@vibgrate/cli 2026.708.2 → 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/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, 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-AWEAREOE.js';
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-GHLYQZWT.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-ICBBG6U3.js';
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';
@@ -2367,7 +2367,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
2367
2367
  console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
2368
2368
  }
2369
2369
  if (opts.baseline) {
2370
- const { runBaseline } = await import('./baseline-AMQ7VEB5.js');
2370
+ const { runBaseline } = await import('./baseline-AUC3HAXW.js');
2371
2371
  await runBaseline(rootDir);
2372
2372
  }
2373
2373
  console.log("");
@@ -3193,11 +3193,11 @@ function estimateDriftScore(artifact, upgraded) {
3193
3193
  }
3194
3194
  return computeDriftScore(projects).score;
3195
3195
  }
3196
- function pmCommandFor(ecosystem, pkg, version, pm = "npm") {
3196
+ function pmCommandFor(ecosystem, pkg, version, pm = "npm", opts = {}) {
3197
3197
  switch (ecosystem) {
3198
3198
  case "npm":
3199
- if (pm === "pnpm") return { cmd: "pnpm", args: ["add", `${pkg}@${version}`] };
3200
- 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}`] };
3201
3201
  if (pm === "bun") return { cmd: "bun", args: ["add", `${pkg}@${version}`] };
3202
3202
  return { cmd: "npm", args: ["install", `${pkg}@${version}`] };
3203
3203
  case "pypi":
@@ -3224,19 +3224,37 @@ function pmCommandFor(ecosystem, pkg, version, pm = "npm") {
3224
3224
  }
3225
3225
  function defaultRun(cmd, cwd) {
3226
3226
  const res = spawnSync(cmd.cmd, cmd.args, { cwd, stdio: "inherit", shell: false });
3227
- if (res.error) return { ok: false, detail: res.error.message };
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
+ }
3228
3233
  if (res.status !== 0) return { ok: false, detail: `exit ${res.status ?? "signal"}` };
3229
3234
  return { ok: true };
3230
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
+ }
3231
3248
  function applyPlan(rootDir, upgrades, opts = {}) {
3232
3249
  const run = opts.run ?? defaultRun;
3250
+ const workspaceRoot = isWorkspaceRoot(rootDir);
3233
3251
  const results = [];
3234
3252
  for (const u of upgrades) {
3235
3253
  if (!u.to) {
3236
3254
  results.push({ package: u.package, to: u.to, status: "skipped", detail: "no target version" });
3237
3255
  continue;
3238
3256
  }
3239
- const command = pmCommandFor(u.ecosystem, u.package, u.to, opts.packageManager);
3257
+ const command = pmCommandFor(u.ecosystem, u.package, u.to, opts.packageManager, { workspaceRoot });
3240
3258
  if (!command) {
3241
3259
  results.push({ package: u.package, to: u.to, status: "manual", detail: `${u.ecosystem}: update the manifest to ${u.to} manually` });
3242
3260
  continue;
@@ -3249,8 +3267,8 @@ function applyPlan(rootDir, upgrades, opts = {}) {
3249
3267
  results.push({
3250
3268
  package: u.package,
3251
3269
  to: u.to,
3252
- status: outcome.ok ? "applied" : "failed",
3253
- 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
3254
3272
  });
3255
3273
  }
3256
3274
  return results;
@@ -3490,6 +3508,44 @@ function npmPackageManager(artifact) {
3490
3508
  }
3491
3509
  return "npm";
3492
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
+ }
3493
3549
  function promptPlanSelection(response) {
3494
3550
  const plans = response.plans.filter((p) => p.upgrades.length > 0);
3495
3551
  console.log(chalk7.bold("\nSelect a plan to apply:"));
@@ -3544,8 +3600,7 @@ async function runApplyFlow(rootDir, artifact, response, opts) {
3544
3600
  console.log(chalk7.dim("Selected plan has no upgrades."));
3545
3601
  return;
3546
3602
  }
3547
- const pm = npmPackageManager(artifact);
3548
- const results = applyPlan(rootDir, chosen.upgrades, { dryRun: opts.dryRun, packageManager: pm });
3603
+ const results = applyChosenPlan(rootDir, artifact, chosen.upgrades, { dryRun: opts.dryRun });
3549
3604
  if (opts.dryRun) {
3550
3605
  console.log(chalk7.bold(`
3551
3606
  Dry run \u2014 ${chosen.label} plan (${chosen.upgrades.length} upgrade(s)):`));