@vibgrate/cli 2026.708.1 → 2026.708.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/dist/baseline-AUC3HAXW.js +6 -0
- package/dist/{baseline-RRO4NNNF.js.map → baseline-AUC3HAXW.js.map} +1 -1
- package/dist/{chunk-2J7DPIAL.js → chunk-2DJ3UXG7.js} +186 -48
- package/dist/chunk-2DJ3UXG7.js.map +1 -0
- package/dist/{chunk-FMCI3MXH.js → chunk-JXGVMXYE.js} +3 -3
- package/dist/{chunk-FMCI3MXH.js.map → chunk-JXGVMXYE.js.map} +1 -1
- package/dist/{chunk-SRWMZBLG.js → chunk-QUELGOCR.js} +4 -4
- package/dist/{chunk-SRWMZBLG.js.map → chunk-QUELGOCR.js.map} +1 -1
- package/dist/cli.js +185 -67
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/dist/baseline-RRO4NNNF.js +0 -6
- package/dist/chunk-2J7DPIAL.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
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, countPending, resolveOne, GraphIndex, shortestPath, renderReport, impactOf, testsToRun, detectRunner, defaultGraphPath, serveStdio, ASSISTANTS, usageError, loadGraph, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, coveringTests, FREE_PACK, readScanArtifact, enrichOnline, ECOSYSTEMS, discoverModels, readSavings, 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, fetchHostedDocs, selectForBudget, formatForExt, verifyDeterminism, renderHtml, isModelReady } 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, countPending, resolveOne, GraphIndex, shortestPath, renderReport, impactOf, testsToRun, detectRunner, defaultGraphPath, serveStdio, ASSISTANTS, 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, fetchHostedDocs, selectForBudget, formatForExt, verifyDeterminism, renderHtml, isModelReady } from './chunk-2DJ3UXG7.js';
|
|
3
3
|
import { resolvedGrammarFiles, grammarSetVersion, canonicalize } from './chunk-X5YT263H.js';
|
|
4
|
-
import { loadAdvancedScanHook, baselineCommand } from './chunk-
|
|
5
|
-
import { ensureDir, pathExists, writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, VERSION, readJsonFile, writeTextFile, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, brandProgressBar, resolveHead, workingTreeDirty } from './chunk-
|
|
4
|
+
import { loadAdvancedScanHook, baselineCommand } from './chunk-JXGVMXYE.js';
|
|
5
|
+
import { ensureDir, pathExists, writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, VERSION, readJsonFile, writeTextFile, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, brandProgressBar, resolveHead, workingTreeDirty } from './chunk-QUELGOCR.js';
|
|
6
6
|
import './chunk-RXP66R2E.js';
|
|
7
7
|
import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-GI6W53LM.js';
|
|
8
8
|
import * as fs5 from 'fs';
|
|
9
|
-
import fs5__default, { realpathSync } from 'fs';
|
|
9
|
+
import fs5__default, { realpathSync, existsSync, readFileSync } from 'fs';
|
|
10
10
|
import * as path from 'path';
|
|
11
|
-
import path__default from 'path';
|
|
11
|
+
import path__default, { join } from 'path';
|
|
12
12
|
import { fileURLToPath } from 'url';
|
|
13
13
|
import { Command, CommanderError, Option } from 'commander';
|
|
14
14
|
import { execSync, spawn, spawnSync, execFileSync, execFile } from 'child_process';
|
|
@@ -295,7 +295,7 @@ function logoLines(root) {
|
|
|
295
295
|
` ${ROBOT[1]}`,
|
|
296
296
|
` ${ROBOT[2]}`,
|
|
297
297
|
` ${ROBOT[3]}`,
|
|
298
|
-
` ${c.bold.white("
|
|
298
|
+
` ${c.bold.white("Vibgrate")} ${teal("Graph")} ${c.dim(`\xB7 Code Intelligence Engine \xB7 v${VERSION}`)}`,
|
|
299
299
|
...root ? [` ${c.dim(root)}`] : [],
|
|
300
300
|
""
|
|
301
301
|
];
|
|
@@ -2034,23 +2034,29 @@ function registerSavings(program) {
|
|
|
2034
2034
|
const cmd = program.command("savings").description("local, privacy-safe report of tokens/$ saved vs a grep baseline (estimates)").option("--days <n>", "window in days", "30").action(function() {
|
|
2035
2035
|
const global = readGlobal(this);
|
|
2036
2036
|
const days = Number(this.opts().days) || 30;
|
|
2037
|
-
const
|
|
2037
|
+
const root = rootOf(global);
|
|
2038
|
+
const now2 = Date.now();
|
|
2039
|
+
const report = readSavings(root, days, now2);
|
|
2040
|
+
const usage = readUsage(root, days, now2);
|
|
2038
2041
|
if (global.json) {
|
|
2039
|
-
json(report);
|
|
2042
|
+
json({ ...report, usage });
|
|
2040
2043
|
return;
|
|
2041
2044
|
}
|
|
2042
2045
|
info(`${c.cyan("vg savings")} \xB7 last ${days} days ${c.dim("(local, nothing left your machine)")}`);
|
|
2043
|
-
if (
|
|
2044
|
-
info(
|
|
2046
|
+
if (usage.totals.calls === 0) {
|
|
2047
|
+
info(
|
|
2048
|
+
c.dim(
|
|
2049
|
+
report.enabled ? " no calls recorded yet in this window" : " recording is off. Enable with `vg serve --savings`, then query via MCP."
|
|
2050
|
+
)
|
|
2051
|
+
);
|
|
2045
2052
|
return;
|
|
2046
2053
|
}
|
|
2047
|
-
if (report.queries
|
|
2048
|
-
info(
|
|
2049
|
-
|
|
2054
|
+
if (report.queries > 0) {
|
|
2055
|
+
info(` queries ${report.queries} \xB7 context tokens ${fmt(report.vgTokens)} (grep/read baseline \u2248 ${fmt(report.baselineTokens)}) \u2192 ${report.ratio}\xD7 fewer`);
|
|
2056
|
+
info(` est. cost (${report.rateLabel}): $${report.estCostVg} vs $${report.estCostBaseline} \u2192 saved \u2248 $${report.saved}`);
|
|
2057
|
+
info(c.dim(" estimates with stated assumptions (~4 chars/token; ~400 tokens/file baseline); scales with repo size."));
|
|
2050
2058
|
}
|
|
2051
|
-
|
|
2052
|
-
info(` est. cost (${report.rateLabel}): $${report.estCostVg} vs $${report.estCostBaseline} \u2192 saved \u2248 $${report.saved}`);
|
|
2053
|
-
info(c.dim(" estimates with stated assumptions (~4 chars/token; ~400 tokens/file baseline); scales with repo size."));
|
|
2059
|
+
printBreakdown(usage);
|
|
2054
2060
|
});
|
|
2055
2061
|
applyGlobalOptions(cmd);
|
|
2056
2062
|
}
|
|
@@ -2059,6 +2065,24 @@ function fmt(n) {
|
|
|
2059
2065
|
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}k`;
|
|
2060
2066
|
return String(n);
|
|
2061
2067
|
}
|
|
2068
|
+
function printBreakdown(usage) {
|
|
2069
|
+
info("");
|
|
2070
|
+
info(c.bold(" by command") + c.dim(" (complete = full result \xB7 partial = capped/paginated \xB7 miss = no result)"));
|
|
2071
|
+
const nameW = Math.max(7, ...usage.commands.map((cmd) => cmd.tool.length));
|
|
2072
|
+
const header = " " + "command".padEnd(nameW) + ["calls", "complete", "partial", "miss", "success%"].map((h) => h.padStart(9)).join("");
|
|
2073
|
+
info(c.dim(header));
|
|
2074
|
+
for (const cmd of usage.commands) {
|
|
2075
|
+
info(
|
|
2076
|
+
" " + cmd.tool.padEnd(nameW) + String(cmd.calls).padStart(9) + String(cmd.complete).padStart(9) + String(cmd.partial).padStart(9) + String(cmd.miss).padStart(9) + `${cmd.successPct}%`.padStart(9)
|
|
2077
|
+
);
|
|
2078
|
+
}
|
|
2079
|
+
const t = usage.totals;
|
|
2080
|
+
info(c.dim(" " + "\u2500".repeat(nameW + 45)));
|
|
2081
|
+
info(
|
|
2082
|
+
" " + c.bold("total".padEnd(nameW)) + String(t.calls).padStart(9) + String(t.complete).padStart(9) + String(t.partial).padStart(9) + String(t.miss).padStart(9) + "".padStart(9)
|
|
2083
|
+
);
|
|
2084
|
+
info(c.dim(` avg success across commands: ${usage.avgSuccessPct}%`));
|
|
2085
|
+
}
|
|
2062
2086
|
function registerLib(program) {
|
|
2063
2087
|
const cmd = program.command("lib").description("library currency: version-correct, drift-annotated usage docs").argument("[args...]", "a library name, or: add <source> | publish <name> | resolve <name> | refresh").option("--name <name>", "library name for `add`").option("--version <v>", "pin the doc version for `add`/`publish`").option("--online", "(deprecated; network is on by default) allow network for add/refresh URL sources").option("-b, --budget <n>", "trim docs to ~N tokens").option("--readme <path>", "README path for `publish` (default ./README.md)").option("--dts <path>", "TypeScript declaration (.d.ts) path for `publish`").option("--language <lang>", "primary language for `publish`").option("--region <region>", "data-residency region for the hosted catalog (same as scans; default us)").option("--ingest <url>", "hosted catalog/ingest URL override (host extracted; wins over --region)").action(async function(args, opts) {
|
|
2064
2088
|
const global = readGlobal(this);
|
|
@@ -2343,7 +2367,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
|
|
|
2343
2367
|
console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
|
|
2344
2368
|
}
|
|
2345
2369
|
if (opts.baseline) {
|
|
2346
|
-
const { runBaseline } = await import('./baseline-
|
|
2370
|
+
const { runBaseline } = await import('./baseline-AUC3HAXW.js');
|
|
2347
2371
|
await runBaseline(rootDir);
|
|
2348
2372
|
}
|
|
2349
2373
|
console.log("");
|
|
@@ -3169,11 +3193,11 @@ function estimateDriftScore(artifact, upgraded) {
|
|
|
3169
3193
|
}
|
|
3170
3194
|
return computeDriftScore(projects).score;
|
|
3171
3195
|
}
|
|
3172
|
-
function pmCommandFor(ecosystem, pkg, version, pm = "npm") {
|
|
3196
|
+
function pmCommandFor(ecosystem, pkg, version, pm = "npm", opts = {}) {
|
|
3173
3197
|
switch (ecosystem) {
|
|
3174
3198
|
case "npm":
|
|
3175
|
-
if (pm === "pnpm") return { cmd: "pnpm", args: ["add", `${pkg}@${version}`] };
|
|
3176
|
-
if (pm === "yarn") return { cmd: "yarn", args: ["add", `${pkg}@${version}`] };
|
|
3199
|
+
if (pm === "pnpm") return { cmd: "pnpm", args: opts.workspaceRoot ? ["add", "-w", `${pkg}@${version}`] : ["add", `${pkg}@${version}`] };
|
|
3200
|
+
if (pm === "yarn") return { cmd: "yarn", args: opts.workspaceRoot ? ["add", "-W", `${pkg}@${version}`] : ["add", `${pkg}@${version}`] };
|
|
3177
3201
|
if (pm === "bun") return { cmd: "bun", args: ["add", `${pkg}@${version}`] };
|
|
3178
3202
|
return { cmd: "npm", args: ["install", `${pkg}@${version}`] };
|
|
3179
3203
|
case "pypi":
|
|
@@ -3200,19 +3224,37 @@ function pmCommandFor(ecosystem, pkg, version, pm = "npm") {
|
|
|
3200
3224
|
}
|
|
3201
3225
|
function defaultRun(cmd, cwd) {
|
|
3202
3226
|
const res = spawnSync(cmd.cmd, cmd.args, { cwd, stdio: "inherit", shell: false });
|
|
3203
|
-
if (res.error)
|
|
3227
|
+
if (res.error) {
|
|
3228
|
+
if (res.error.code === "ENOENT") {
|
|
3229
|
+
return { ok: false, toolMissing: true, detail: `${cmd.cmd} is not installed or not on PATH` };
|
|
3230
|
+
}
|
|
3231
|
+
return { ok: false, detail: res.error.message };
|
|
3232
|
+
}
|
|
3204
3233
|
if (res.status !== 0) return { ok: false, detail: `exit ${res.status ?? "signal"}` };
|
|
3205
3234
|
return { ok: true };
|
|
3206
3235
|
}
|
|
3236
|
+
function isWorkspaceRoot(dir) {
|
|
3237
|
+
try {
|
|
3238
|
+
if (existsSync(join(dir, "pnpm-workspace.yaml"))) return true;
|
|
3239
|
+
const pkgPath = join(dir, "package.json");
|
|
3240
|
+
if (existsSync(pkgPath)) {
|
|
3241
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
3242
|
+
if (pkg?.workspaces) return true;
|
|
3243
|
+
}
|
|
3244
|
+
} catch {
|
|
3245
|
+
}
|
|
3246
|
+
return false;
|
|
3247
|
+
}
|
|
3207
3248
|
function applyPlan(rootDir, upgrades, opts = {}) {
|
|
3208
3249
|
const run = opts.run ?? defaultRun;
|
|
3250
|
+
const workspaceRoot = isWorkspaceRoot(rootDir);
|
|
3209
3251
|
const results = [];
|
|
3210
3252
|
for (const u of upgrades) {
|
|
3211
3253
|
if (!u.to) {
|
|
3212
3254
|
results.push({ package: u.package, to: u.to, status: "skipped", detail: "no target version" });
|
|
3213
3255
|
continue;
|
|
3214
3256
|
}
|
|
3215
|
-
const command = pmCommandFor(u.ecosystem, u.package, u.to, opts.packageManager);
|
|
3257
|
+
const command = pmCommandFor(u.ecosystem, u.package, u.to, opts.packageManager, { workspaceRoot });
|
|
3216
3258
|
if (!command) {
|
|
3217
3259
|
results.push({ package: u.package, to: u.to, status: "manual", detail: `${u.ecosystem}: update the manifest to ${u.to} manually` });
|
|
3218
3260
|
continue;
|
|
@@ -3225,8 +3267,8 @@ function applyPlan(rootDir, upgrades, opts = {}) {
|
|
|
3225
3267
|
results.push({
|
|
3226
3268
|
package: u.package,
|
|
3227
3269
|
to: u.to,
|
|
3228
|
-
status: outcome.ok ? "applied" : "failed",
|
|
3229
|
-
detail: outcome.detail
|
|
3270
|
+
status: outcome.ok ? "applied" : outcome.toolMissing ? "manual" : "failed",
|
|
3271
|
+
detail: outcome.toolMissing && outcome.detail ? `${outcome.detail} \u2014 upgrade manually` : outcome.detail
|
|
3230
3272
|
});
|
|
3231
3273
|
}
|
|
3232
3274
|
return results;
|
|
@@ -3466,6 +3508,44 @@ function npmPackageManager(artifact) {
|
|
|
3466
3508
|
}
|
|
3467
3509
|
return "npm";
|
|
3468
3510
|
}
|
|
3511
|
+
function toNpmPackageManager(pm) {
|
|
3512
|
+
return pm === "pnpm" || pm === "yarn" || pm === "bun" ? pm : "npm";
|
|
3513
|
+
}
|
|
3514
|
+
function projectsDeclaring(rootDir, artifact, pkg, ecosystem) {
|
|
3515
|
+
const out2 = [];
|
|
3516
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3517
|
+
for (const project of artifact.projects ?? []) {
|
|
3518
|
+
if (ecosystemId(project.type) !== ecosystem) continue;
|
|
3519
|
+
if (!(project.dependencies ?? []).some((d) => d.package === pkg)) continue;
|
|
3520
|
+
const dir = path.resolve(rootDir, project.path && project.path !== "." ? project.path : ".");
|
|
3521
|
+
if (seen.has(dir)) continue;
|
|
3522
|
+
seen.add(dir);
|
|
3523
|
+
out2.push({ dir, pm: toNpmPackageManager(project.packageManager) });
|
|
3524
|
+
}
|
|
3525
|
+
return out2;
|
|
3526
|
+
}
|
|
3527
|
+
function applyChosenPlan(rootDir, artifact, upgrades, opts) {
|
|
3528
|
+
const fallbackPm = npmPackageManager(artifact);
|
|
3529
|
+
const groups = /* @__PURE__ */ new Map();
|
|
3530
|
+
for (const u of upgrades) {
|
|
3531
|
+
let targets = projectsDeclaring(rootDir, artifact, u.package, u.ecosystem);
|
|
3532
|
+
if (targets.length === 0) targets = [{ dir: rootDir, pm: fallbackPm }];
|
|
3533
|
+
for (const t of targets) {
|
|
3534
|
+
const group = groups.get(t.dir) ?? { dir: t.dir, pm: t.pm, upgrades: [] };
|
|
3535
|
+
group.upgrades.push(u);
|
|
3536
|
+
groups.set(t.dir, group);
|
|
3537
|
+
}
|
|
3538
|
+
}
|
|
3539
|
+
const results = [];
|
|
3540
|
+
for (const group of groups.values()) {
|
|
3541
|
+
const applied = applyPlan(group.dir, group.upgrades, { dryRun: opts.dryRun, packageManager: group.pm });
|
|
3542
|
+
const rel3 = path.relative(rootDir, group.dir) || ".";
|
|
3543
|
+
for (const r of applied) {
|
|
3544
|
+
results.push(rel3 === "." ? r : { ...r, detail: [r.detail, `in ${rel3}`].filter(Boolean).join(" \xB7 ") });
|
|
3545
|
+
}
|
|
3546
|
+
}
|
|
3547
|
+
return results;
|
|
3548
|
+
}
|
|
3469
3549
|
function promptPlanSelection(response) {
|
|
3470
3550
|
const plans = response.plans.filter((p) => p.upgrades.length > 0);
|
|
3471
3551
|
console.log(chalk7.bold("\nSelect a plan to apply:"));
|
|
@@ -3520,8 +3600,7 @@ async function runApplyFlow(rootDir, artifact, response, opts) {
|
|
|
3520
3600
|
console.log(chalk7.dim("Selected plan has no upgrades."));
|
|
3521
3601
|
return;
|
|
3522
3602
|
}
|
|
3523
|
-
const
|
|
3524
|
-
const results = applyPlan(rootDir, chosen.upgrades, { dryRun: opts.dryRun, packageManager: pm });
|
|
3603
|
+
const results = applyChosenPlan(rootDir, artifact, chosen.upgrades, { dryRun: opts.dryRun });
|
|
3525
3604
|
if (opts.dryRun) {
|
|
3526
3605
|
console.log(chalk7.bold(`
|
|
3527
3606
|
Dry run \u2014 ${chosen.label} plan (${chosen.upgrades.length} upgrade(s)):`));
|
|
@@ -3559,7 +3638,7 @@ function formatText(artifact) {
|
|
|
3559
3638
|
lines.push("");
|
|
3560
3639
|
lines.push(" " + teal2("\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u256E") + mint2("\u279C"));
|
|
3561
3640
|
lines.push(" " + chalk7.dim("\u2524") + teal2("\u2502") + " " + mint2("\u25FC") + " " + mint2("\u25FC") + " " + teal2("\u2502") + chalk7.dim("\u251C") + " " + chalk7.bold.white("vibgrate"));
|
|
3562
|
-
lines.push(" " + chalk7.dim("\u2524") + teal2("\u2502") + " " + chalk7.dim("\u2581\u2581") + " " + teal2("\u2502") + chalk7.dim("\u251C") + " " + chalk7.dim(`
|
|
3641
|
+
lines.push(" " + chalk7.dim("\u2524") + teal2("\u2502") + " " + chalk7.dim("\u2581\u2581") + " " + teal2("\u2502") + chalk7.dim("\u251C") + " " + chalk7.dim(`Code Intelligence Engine v${VERSION}`));
|
|
3563
3642
|
lines.push(" " + teal2("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u256F"));
|
|
3564
3643
|
lines.push("");
|
|
3565
3644
|
lines.push(...titleBox("Vibgrate Drift Report", teal2));
|
|
@@ -4532,11 +4611,23 @@ async function detectPackageManager(cwd) {
|
|
|
4532
4611
|
if (await pathExists(path.join(cwd, "yarn.lock"))) return "yarn";
|
|
4533
4612
|
return "npm";
|
|
4534
4613
|
}
|
|
4535
|
-
function
|
|
4614
|
+
async function detectWorkspaceRoot(cwd) {
|
|
4615
|
+
if (await pathExists(path.join(cwd, "pnpm-workspace.yaml"))) return true;
|
|
4616
|
+
try {
|
|
4617
|
+
const pkgPath = path.join(cwd, "package.json");
|
|
4618
|
+
const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
|
|
4619
|
+
const pkg = JSON.parse(raw);
|
|
4620
|
+
return pkg.workspaces != null;
|
|
4621
|
+
} catch {
|
|
4622
|
+
return false;
|
|
4623
|
+
}
|
|
4624
|
+
}
|
|
4625
|
+
function getInstallCommand(pm, pkg, version, isDev, opts = {}) {
|
|
4536
4626
|
const spec = `${pkg}@${version}`;
|
|
4627
|
+
const ws = opts.workspaceRoot && pm === "pnpm" ? " -w" : "";
|
|
4537
4628
|
switch (pm) {
|
|
4538
4629
|
case "pnpm":
|
|
4539
|
-
return isDev ? `pnpm add -D ${spec}` : `pnpm add ${spec}`;
|
|
4630
|
+
return isDev ? `pnpm add${ws} -D ${spec}` : `pnpm add${ws} ${spec}`;
|
|
4540
4631
|
case "yarn":
|
|
4541
4632
|
return isDev ? `yarn add --dev ${spec}` : `yarn add ${spec}`;
|
|
4542
4633
|
case "bun":
|
|
@@ -4556,45 +4647,72 @@ async function isDevDependency(cwd) {
|
|
|
4556
4647
|
return true;
|
|
4557
4648
|
}
|
|
4558
4649
|
}
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
console.log(chalk7.
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4650
|
+
async function confirmWorkspaceRoot(pm) {
|
|
4651
|
+
if (!(process.stdin.isTTY && process.stdout.isTTY)) return false;
|
|
4652
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
4653
|
+
return new Promise((resolve16) => {
|
|
4654
|
+
rl.question(chalk7.yellow(`Update the ${pm} workspace root with -w? [y/N]: `), (ans) => {
|
|
4655
|
+
rl.close();
|
|
4656
|
+
const t = ans.trim().toLowerCase();
|
|
4657
|
+
resolve16(t === "y" || t === "yes");
|
|
4658
|
+
});
|
|
4659
|
+
});
|
|
4660
|
+
}
|
|
4661
|
+
var updateCommand = new Command("update").description("Update vibgrate to the latest version").option("--check", "Only check for updates, do not install").option("--pm <manager>", "Package manager to use (npm, pnpm, yarn, bun)").option("--global", "Update global installation").option("-y, --yes", "Skip confirmation prompts (e.g. installing at a workspace root)").option("-w, --workspace-root", "Allow updating the pnpm workspace root (implies --yes for that prompt)").action(
|
|
4662
|
+
async (opts) => {
|
|
4663
|
+
console.log(chalk7.dim(`Current version: ${VERSION}`));
|
|
4664
|
+
console.log(chalk7.dim("Checking npm registry..."));
|
|
4665
|
+
const latest = await fetchLatestVersion();
|
|
4666
|
+
if (!latest) {
|
|
4667
|
+
console.error(chalk7.red("Could not reach the npm registry. Check your network connection."));
|
|
4668
|
+
process.exit(1);
|
|
4669
|
+
}
|
|
4670
|
+
const semver2 = await import('semver');
|
|
4671
|
+
if (!semver2.gt(latest, VERSION)) {
|
|
4672
|
+
console.log(chalk7.green("\u2714") + ` You are on the latest version (${VERSION}).`);
|
|
4673
|
+
return;
|
|
4674
|
+
}
|
|
4675
|
+
console.log(chalk7.yellow(`Update available: ${VERSION} \u2192 ${latest}`));
|
|
4676
|
+
if (opts.check) {
|
|
4677
|
+
console.log(chalk7.dim('Run "vg update" to install.'));
|
|
4678
|
+
return;
|
|
4679
|
+
}
|
|
4680
|
+
const cwd = process.cwd();
|
|
4681
|
+
const globalPm = detectGlobalInstall();
|
|
4682
|
+
const isGlobal = opts.global || globalPm !== null;
|
|
4683
|
+
const pm = opts.pm || (globalPm ?? await detectPackageManager(cwd));
|
|
4684
|
+
let cmd;
|
|
4685
|
+
if (isGlobal) {
|
|
4686
|
+
cmd = getGlobalUpdateCommand(pm, "@vibgrate/cli", latest);
|
|
4687
|
+
console.log(chalk7.dim(`Updating global installation with ${pm}: ${cmd}`));
|
|
4688
|
+
} else {
|
|
4689
|
+
const isDev = await isDevDependency(cwd);
|
|
4690
|
+
let workspaceRoot = false;
|
|
4691
|
+
if (pm === "pnpm" && await detectWorkspaceRoot(cwd)) {
|
|
4692
|
+
console.log(
|
|
4693
|
+
chalk7.yellow("Detected a pnpm workspace root.") + chalk7.dim(" Installing here needs the -w flag and updates the root package.json.")
|
|
4694
|
+
);
|
|
4695
|
+
const proceed = opts.yes || opts.workspaceRoot || await confirmWorkspaceRoot(pm);
|
|
4696
|
+
if (!proceed) {
|
|
4697
|
+
const rootCmd = getInstallCommand(pm, "@vibgrate/cli", latest, isDev, { workspaceRoot: true });
|
|
4698
|
+
console.log(chalk7.dim(`Skipped. To update the workspace root, run: ${rootCmd}`));
|
|
4699
|
+
console.log(chalk7.dim('or re-run "vg update --yes" (or --workspace-root) to let vg do it.'));
|
|
4700
|
+
return;
|
|
4701
|
+
}
|
|
4702
|
+
workspaceRoot = true;
|
|
4703
|
+
}
|
|
4704
|
+
cmd = getInstallCommand(pm, "@vibgrate/cli", latest, isDev, { workspaceRoot });
|
|
4705
|
+
console.log(chalk7.dim(`Using ${pm}: ${cmd}`));
|
|
4706
|
+
}
|
|
4707
|
+
try {
|
|
4708
|
+
execSync(cmd, { cwd, stdio: "inherit" });
|
|
4709
|
+
console.log(chalk7.green("\u2714") + ` Updated to @vibgrate/cli@${latest}`);
|
|
4710
|
+
} catch {
|
|
4711
|
+
console.error(chalk7.red(`Update failed. Run manually: ${cmd}`));
|
|
4712
|
+
process.exit(1);
|
|
4713
|
+
}
|
|
4596
4714
|
}
|
|
4597
|
-
|
|
4715
|
+
);
|
|
4598
4716
|
var OPENVEX_CONTEXT = "https://openvex.dev/ns/v0.2.0";
|
|
4599
4717
|
var VEX_STATUSES = ["not_affected", "affected", "fixed", "under_investigation"];
|
|
4600
4718
|
var VEX_JUSTIFICATIONS = [
|