@vibgrate/cli 2026.805.1 → 2026.806.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/DOCS.md +8 -4
  2. package/README.md +1 -0
  3. package/dist/{agent-WH2VVIHM.js → agent-SBVWSP7G.js} +11 -11
  4. package/dist/{agent-WH2VVIHM.js.map → agent-SBVWSP7G.js.map} +1 -1
  5. package/dist/{baseline-LMGZURQF.js → baseline-NM53X2TB.js} +3 -3
  6. package/dist/{baseline-LMGZURQF.js.map → baseline-NM53X2TB.js.map} +1 -1
  7. package/dist/chunk-3Z6TDWNS.js +6 -0
  8. package/dist/{chunk-MEKXVHW7.js.map → chunk-3Z6TDWNS.js.map} +1 -1
  9. package/dist/{chunk-55Q56FD7.js → chunk-5AUCYYBG.js} +6 -6
  10. package/dist/{chunk-55Q56FD7.js.map → chunk-5AUCYYBG.js.map} +1 -1
  11. package/dist/{chunk-DG33XQX2.js → chunk-6XP2TQS5.js} +3 -3
  12. package/dist/{chunk-DG33XQX2.js.map → chunk-6XP2TQS5.js.map} +1 -1
  13. package/dist/{chunk-B6CWDTAG.js → chunk-A42UDYL2.js} +3 -3
  14. package/dist/{chunk-B6CWDTAG.js.map → chunk-A42UDYL2.js.map} +1 -1
  15. package/dist/{chunk-QTKGOXSE.js → chunk-AN7RCXE4.js} +3 -3
  16. package/dist/{chunk-QTKGOXSE.js.map → chunk-AN7RCXE4.js.map} +1 -1
  17. package/dist/{chunk-2U4SXS5U.js → chunk-BOAUTBTB.js} +4 -4
  18. package/dist/{chunk-2U4SXS5U.js.map → chunk-BOAUTBTB.js.map} +1 -1
  19. package/dist/{chunk-Q6OQPCYC.js → chunk-H4ZIJSHE.js} +7 -7
  20. package/dist/{chunk-Q6OQPCYC.js.map → chunk-H4ZIJSHE.js.map} +1 -1
  21. package/dist/{chunk-6LDYH3PR.js → chunk-ITGUM42X.js} +4 -4
  22. package/dist/{chunk-6LDYH3PR.js.map → chunk-ITGUM42X.js.map} +1 -1
  23. package/dist/{chunk-AQLP3V5Y.js → chunk-K3KEKY2L.js} +4 -4
  24. package/dist/{chunk-AQLP3V5Y.js.map → chunk-K3KEKY2L.js.map} +1 -1
  25. package/dist/{chunk-IA3WXZLB.js → chunk-KACPLPFT.js} +7 -7
  26. package/dist/{chunk-IA3WXZLB.js.map → chunk-KACPLPFT.js.map} +1 -1
  27. package/dist/{chunk-FTZGQPHB.js → chunk-LFHXJHOZ.js} +3 -3
  28. package/dist/{chunk-FTZGQPHB.js.map → chunk-LFHXJHOZ.js.map} +1 -1
  29. package/dist/{chunk-E72RZJPC.js → chunk-N6LGZBIC.js} +5 -5
  30. package/dist/{chunk-E72RZJPC.js.map → chunk-N6LGZBIC.js.map} +1 -1
  31. package/dist/{chunk-TSEE4YUQ.js → chunk-OGJ633I2.js} +5 -5
  32. package/dist/{chunk-TSEE4YUQ.js.map → chunk-OGJ633I2.js.map} +1 -1
  33. package/dist/{chunk-5HDCARJE.js → chunk-OKJTAHOL.js} +5 -5
  34. package/dist/{chunk-5HDCARJE.js.map → chunk-OKJTAHOL.js.map} +1 -1
  35. package/dist/{chunk-QCEGM4WC.js → chunk-SAHORNZX.js} +4 -4
  36. package/dist/{chunk-QCEGM4WC.js.map → chunk-SAHORNZX.js.map} +1 -1
  37. package/dist/{chunk-6IL3UJTE.js → chunk-SMDHK37H.js} +83 -4
  38. package/dist/chunk-SMDHK37H.js.map +1 -0
  39. package/dist/{chunk-LGYIYZVS.js → chunk-TWZLUOTR.js} +4 -4
  40. package/dist/{chunk-LGYIYZVS.js.map → chunk-TWZLUOTR.js.map} +1 -1
  41. package/dist/{chunk-IFCK26ZD.js → chunk-VJIRJLV2.js} +4 -4
  42. package/dist/{chunk-IFCK26ZD.js.map → chunk-VJIRJLV2.js.map} +1 -1
  43. package/dist/{chunk-3ZNFU2GI.js → chunk-VKVGREHC.js} +8 -8
  44. package/dist/{chunk-3ZNFU2GI.js.map → chunk-VKVGREHC.js.map} +1 -1
  45. package/dist/{chunk-YW45X2XK.js → chunk-VP5ECB7T.js} +119 -56
  46. package/dist/chunk-VP5ECB7T.js.map +1 -0
  47. package/dist/{chunk-4CM33QT2.js → chunk-Y6AMGI4L.js} +84 -6
  48. package/dist/chunk-Y6AMGI4L.js.map +1 -0
  49. package/dist/cli.js +386 -242
  50. package/dist/cli.js.map +1 -1
  51. package/dist/embed-worker-main.js +3 -3
  52. package/dist/{ensure-map-HWHMALI4.js → ensure-map-JICVC2ZJ.js} +12 -12
  53. package/dist/{ensure-map-HWHMALI4.js.map → ensure-map-JICVC2ZJ.js.map} +1 -1
  54. package/dist/graph-backend-TB35N5MC.js +13 -0
  55. package/dist/{graph-backend-H42SHYB5.js.map → graph-backend-TB35N5MC.js.map} +1 -1
  56. package/dist/index.d.ts +75 -9
  57. package/dist/index.js +11 -11
  58. package/dist/{interactive-AAKPP4BJ.js → interactive-IJS33F4K.js} +22 -22
  59. package/dist/{interactive-AAKPP4BJ.js.map → interactive-IJS33F4K.js.map} +1 -1
  60. package/dist/load-OMTSGVDX.js +9 -0
  61. package/dist/{load-BB52WJTD.js.map → load-OMTSGVDX.js.map} +1 -1
  62. package/dist/{run-outcome-TTLHJEDB.js → run-outcome-UENLWBWC.js} +5 -5
  63. package/dist/{run-outcome-TTLHJEDB.js.map → run-outcome-UENLWBWC.js.map} +1 -1
  64. package/dist/runtime-session-AFL7P4TQ.js +20 -0
  65. package/dist/{runtime-session-CKNRMKSK.js.map → runtime-session-AFL7P4TQ.js.map} +1 -1
  66. package/dist/session-HOS4454T.js +15 -0
  67. package/dist/{session-5TNNGP2K.js.map → session-HOS4454T.js.map} +1 -1
  68. package/dist/{stream-json-T6DS3GIO.js → stream-json-SVMGVBFB.js} +11 -11
  69. package/dist/{stream-json-T6DS3GIO.js.map → stream-json-SVMGVBFB.js.map} +1 -1
  70. package/dist/{vg-mcp-bridge-AP3B7BN6.js → vg-mcp-bridge-NYCAQEMU.js} +8 -8
  71. package/dist/{vg-mcp-bridge-AP3B7BN6.js.map → vg-mcp-bridge-NYCAQEMU.js.map} +1 -1
  72. package/dist/{vgd-FXIEZZT2.js → vgd-YFPJHQB5.js} +8 -8
  73. package/dist/vgd-YFPJHQB5.js.map +1 -0
  74. package/package.json +2 -2
  75. package/dist/chunk-4CM33QT2.js.map +0 -1
  76. package/dist/chunk-6IL3UJTE.js.map +0 -1
  77. package/dist/chunk-MEKXVHW7.js +0 -6
  78. package/dist/chunk-YW45X2XK.js.map +0 -1
  79. package/dist/graph-backend-H42SHYB5.js +0 -13
  80. package/dist/load-BB52WJTD.js +0 -9
  81. package/dist/runtime-session-CKNRMKSK.js +0 -20
  82. package/dist/session-5TNNGP2K.js +0 -15
  83. package/dist/vgd-FXIEZZT2.js.map +0 -1
package/dist/cli.js CHANGED
@@ -1,37 +1,37 @@
1
1
  #!/usr/bin/env node
2
2
  import { loadAdvancedScanHook, baselineCommand } from './chunk-Y4JO6LYP.js';
3
- import { fetchCatalog, resolveProviders } from './chunk-TSEE4YUQ.js';
4
- import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-6LDYH3PR.js';
3
+ import { fetchCatalog, resolveProviders } from './chunk-OGJ633I2.js';
4
+ import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-ITGUM42X.js';
5
5
  import './chunk-IS7VTH2Q.js';
6
- import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-AQLP3V5Y.js';
7
- import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-3ZNFU2GI.js';
6
+ import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-K3KEKY2L.js';
7
+ import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-VKVGREHC.js';
8
8
  import './chunk-543E6WDJ.js';
9
9
  import './chunk-7AVYKZEM.js';
10
10
  import { buildModelInstallPlan } from './chunk-WHJMS7XC.js';
11
- import { runCodeSession } from './chunk-5HDCARJE.js';
12
- import { summarizeDiffs, ScriptedProvider } from './chunk-2U4SXS5U.js';
11
+ import { runCodeSession } from './chunk-OKJTAHOL.js';
12
+ import { summarizeDiffs, ScriptedProvider } from './chunk-BOAUTBTB.js';
13
13
  import { ensurePackage, ensureUnavailableMessage } from './chunk-REIGWTTH.js';
14
- import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, runBuild } from './chunk-IA3WXZLB.js';
15
- export { runBuild } from './chunk-IA3WXZLB.js';
14
+ import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, runBuild } from './chunk-KACPLPFT.js';
15
+ export { runBuild } from './chunk-KACPLPFT.js';
16
16
  import { disableColor, info, c, json, out } from './chunk-CT5BS56U.js';
17
17
  import { init_resolve_ollama, gatherSystemMemory, resolveOllamaBinary, hasOllamaBinary, resolve_ollama_exports } from './chunk-OWSFZQOP.js';
18
18
  import { readOrchestratorState, writeOrchestratorState, parseMode, setDefaultMode, recommendMode, activePin, resolveMode, providerForBackend, QUALIFIED_PACKS, pinPack, unpinPack, buildOrchestratorStatus } from './chunk-NZELMYT4.js';
19
19
  import { fmt, estimateModelBytes } from './chunk-7N4Y3E47.js';
20
20
  import './chunk-IZDH67DX.js';
21
- import './chunk-FTZGQPHB.js';
21
+ import './chunk-LFHXJHOZ.js';
22
22
  import { vgdSocketPath, vgdIsRunning, vgdRequest, vgdPidPath } from './chunk-RBIRXQR6.js';
23
23
  import { defaultProcessEndpoint, startProcessHostServer, resolveInferenceIsolation } from './chunk-JFE7XCAE.js';
24
24
  import { clearHostSessionPool, acquireHostSession, generateOnSession, listHostSessions, hostSessionPoolSize } from './chunk-3LOWJSAF.js';
25
25
  import { buildIdentifierTrieFromGraph } from './chunk-5HYCB55P.js';
26
- import { serveStdio, isRelevantChange, exportGraph, GraphSource, createServer, formatForExt } from './chunk-YW45X2XK.js';
27
- import { refreshIfStale } from './chunk-E72RZJPC.js';
28
- import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-LGYIYZVS.js';
29
- import { CliError, ExitCode, driftCount, ASSISTANTS, detectAssistants, isAssistantInstalled, usageError, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, buildGraph, writeSnapshot, probeFreshness, discover, assistantById, SMALL_REPO_FILES, isSkippedDirName, SKIP_FILES, SKIP_DIRS } from './chunk-Q6OQPCYC.js';
30
- import { resolveDsn, createWorkspaceDsn, writeStoredCredentials, credentialsPath, findGitRoot, ensureGitignored, gitignoreEntryForCredentials, clearStoredCredentials, parseDsn as parseDsn$1, uploadScanArtifact, dsnCommand, pushCommand, countTokens, shortestPath, pathDisconnect, testsToRun, detectRunner, coveringTests, FREE_PACK, readScanArtifact, publishPrivateLibrary, assessDocQuality, symbolsFromApi, fetchHostedDocsCached, selectForBudget, hostedBase, readStoredCredentials, projectCredentialsPath, homeCredentialsPath } from './chunk-55Q56FD7.js';
26
+ import { serveStdio, isRelevantChange, exportGraph, GraphSource, createServer, formatForExt, RefreshScheduler } from './chunk-VP5ECB7T.js';
27
+ import { refreshIfStale } from './chunk-N6LGZBIC.js';
28
+ import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-TWZLUOTR.js';
29
+ import { CliError, ExitCode, driftCount, ASSISTANTS, detectAssistants, isAssistantInstalled, usageError, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, buildGraph, writeSnapshot, probeFreshness, discover, assistantById, SMALL_REPO_FILES, isSkippedDirName, SKIP_FILES, SKIP_DIRS } from './chunk-H4ZIJSHE.js';
30
+ import { resolveDsn, createWorkspaceDsn, writeStoredCredentials, credentialsPath, findGitRoot, ensureGitignored, gitignoreEntryForCredentials, clearStoredCredentials, parseDsn as parseDsn$1, uploadScanArtifact, dsnCommand, pushCommand, countTokens, shortestPath, pathDisconnect, testsToRun, detectRunner, coveringTests, FREE_PACK, readScanArtifact, publishPrivateLibrary, assessDocQuality, symbolsFromApi, fetchHostedDocsCached, selectForBudget, hostedBase, readStoredCredentials, projectCredentialsPath, homeCredentialsPath } from './chunk-5AUCYYBG.js';
31
31
  import { writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, loadConfig, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, PROJECT_TYPE_TO_OSV_ECOSYSTEM, fetchRiskySymbols, perDependencyDrift } from './chunk-INIULQEP.js';
32
32
  import { resolveIngestHost, dashHostForIngestHost, availableRegionIds, ingestHostForRegionId } from './chunk-HTLDXEHW.js';
33
33
  import './chunk-VIWZ4QT7.js';
34
- import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-IFCK26ZD.js';
34
+ import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-VJIRJLV2.js';
35
35
  import { discoverModels } from './chunk-CQDUBAQY.js';
36
36
  import { freeBytesOnVolume, weightStoreDir, listCachedWeights, ensureWeightCached, catalogIntegrityReport } from './chunk-OV4KGXPD.js';
37
37
  import './chunk-5I4VSBWQ.js';
@@ -39,21 +39,21 @@ import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-DT4KIV
39
39
  import { ensureDir, pathExists, readJsonFile, writeTextFile, writeJsonFile } from './chunk-CRAMOEBE.js';
40
40
  import { init_cli_invocation, resolveCliInvocation, NPX_INVOCATION } from './chunk-3LSG7Z4I.js';
41
41
  import { resolveOne } from './chunk-J7LKEB2R.js';
42
- import { queryGraphSemantic, queryGraph, indexFor, impactOf } from './chunk-4CM33QT2.js';
42
+ import { queryGraphSemantic, queryGraph, indexFor, impactOf } from './chunk-Y6AMGI4L.js';
43
43
  import { resolvedGrammarFiles, grammarSetVersion } from './chunk-UTNNGKKX.js';
44
44
  import './chunk-RXP66R2E.js';
45
- import { embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, unavailableMessage, countPending, modelCacheInfo, embeddingsPath, clearModelCache, withTimeout } from './chunk-QTKGOXSE.js';
46
- import { loadGraph, loadGraphPreferIndex, SCHEMA_VERSION } from './chunk-B6CWDTAG.js';
47
- import { cacheDir, resolveGraphPath, analyzeQuestion, loadTopicTags, renderReport, resetRelevanceProviderCache, loadRelevanceProvider, loadGraphFileWithSnapshot, serializeGraph, stableStringify, writeArtifacts, vibgrateDir, mapFileExists, relevanceModuleDir, parseGraph, ensureVibgrateGitignore } from './chunk-6IL3UJTE.js';
48
- import { VERSION } from './chunk-MEKXVHW7.js';
45
+ import { embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, unavailableMessage, countPending, modelCacheInfo, embeddingsPath, clearModelCache, withTimeout } from './chunk-AN7RCXE4.js';
46
+ import { loadGraph, loadGraphPreferIndex, SCHEMA_VERSION } from './chunk-A42UDYL2.js';
47
+ import { cacheDir, resolveGraphPath, analyzeQuestion, loadTopicTags, renderReport, resetRelevanceProviderCache, loadRelevanceProvider, loadGraphFileWithSnapshot, serializeGraph, stableStringify, writeArtifacts, vibgrateDir, mapFileExists, relevanceModuleDir, parseGraph, ensureVibgrateGitignore } from './chunk-SMDHK37H.js';
48
+ import { VERSION } from './chunk-3Z6TDWNS.js';
49
49
  import './chunk-BWPBB45M.js';
50
50
  import { canonicalize, hashString, hashBytes } from './chunk-JFGYT6BI.js';
51
51
  import './chunk-BPF3YX2U.js';
52
52
  import { __toCommonJS } from './chunk-Z6ZWNWWR.js';
53
53
  import * as fs11 from 'fs';
54
54
  import fs11__default, { realpathSync } from 'fs';
55
- import * as path40 from 'path';
56
- import path40__default from 'path';
55
+ import * as path41 from 'path';
56
+ import path41__default from 'path';
57
57
  import { fileURLToPath, pathToFileURL } from 'url';
58
58
  import { Command, CommanderError, Option } from 'commander';
59
59
  import { execSync, spawn, spawnSync, execFileSync } from 'child_process';
@@ -75,10 +75,10 @@ function registerStatus(program) {
75
75
  applyGlobalOptions(cmd);
76
76
  }
77
77
  async function runStatus(global) {
78
- const root2 = path40.resolve(global.cwd ?? ".");
78
+ const root2 = path41.resolve(global.cwd ?? ".");
79
79
  const graphPath = resolveGraphPath(root2, global.graph);
80
80
  const graph = loadGraph(root2, graphPath);
81
- const hasCache = fs11.existsSync(path40.join(cacheDir(root2), "parse-cache.json"));
81
+ const hasCache = fs11.existsSync(path41.join(cacheDir(root2), "parse-cache.json"));
82
82
  let stale = null;
83
83
  let staleExact = false;
84
84
  if (graph) {
@@ -98,8 +98,8 @@ async function runStatus(global) {
98
98
  }
99
99
  if (global.json) {
100
100
  json({
101
- root: path40.relative(process.cwd(), root2) || ".",
102
- graphPath: path40.relative(root2, graphPath),
101
+ root: path41.relative(process.cwd(), root2) || ".",
102
+ graphPath: path41.relative(root2, graphPath),
103
103
  built: graph !== null,
104
104
  generatedAt: graph?.generatedAt ?? null,
105
105
  counts: graph?.meta.counts ?? null,
@@ -114,11 +114,11 @@ async function runStatus(global) {
114
114
  return;
115
115
  }
116
116
  if (!graph) {
117
- info(`${c.cyan("vg")} \xB7 no map yet at ${c.dim(path40.relative(root2, graphPath))}`);
117
+ info(`${c.cyan("vg")} \xB7 no map yet at ${c.dim(path41.relative(root2, graphPath))}`);
118
118
  info(` run ${c.bold("vg")} to build one`);
119
119
  return;
120
120
  }
121
- info(`${c.cyan("vg")} \xB7 ${path40.relative(root2, graphPath)}`);
121
+ info(`${c.cyan("vg")} \xB7 ${path41.relative(root2, graphPath)}`);
122
122
  info(` generated ${graph.generatedAt}`);
123
123
  info(
124
124
  ` nodes ${c.bold(String(graph.meta.counts.nodes))} edges ${c.bold(
@@ -135,7 +135,7 @@ async function runStatus(global) {
135
135
  if (vibgrateDir(root2)) ;
136
136
  }
137
137
  function rootOf(global) {
138
- return path40.resolve(global.cwd ?? ".");
138
+ return path41.resolve(global.cwd ?? ".");
139
139
  }
140
140
  function requireGraph(global) {
141
141
  const root2 = rootOf(global);
@@ -237,11 +237,11 @@ function crashedMessage(signal) {
237
237
  return `semantic search is disabled: its native backend (onnxruntime-node, via fastembed) crashed with ${signal} \u2014 using fast lexical search instead. This is almost always an install-script block: npm skips onnxruntime-node's postinstall under allow-scripts/ignore-scripts, so the platform binaries were never downloaded. Reinstall allowing them \u2014 npm install -g --allow-scripts=@vibgrate/cli,onnxruntime-node,msgpackr-extract @vibgrate/cli \u2014 or run with --local to stay lexical quietly.`;
238
238
  }
239
239
  function defaultCacheDir() {
240
- const base = process.env.XDG_CACHE_HOME || path40.join(os.homedir(), ".cache");
241
- return path40.join(base, "vibgrate", "models");
240
+ const base = process.env.XDG_CACHE_HOME || path41.join(os.homedir(), ".cache");
241
+ return path41.join(base, "vibgrate", "models");
242
242
  }
243
243
  function verdictPath(dir) {
244
- return path40.join(dir, `embed-health-${process.platform}-${process.arch}.json`);
244
+ return path41.join(dir, `embed-health-${process.platform}-${process.arch}.json`);
245
245
  }
246
246
  function readVerdict(dir) {
247
247
  try {
@@ -989,7 +989,7 @@ var PUBLISH_INTERVAL_MS = 2e3;
989
989
  var KEEPALIVE_MS = 1e4;
990
990
  var STALE_MS = 6e4;
991
991
  function liveStatsDir(root2) {
992
- return path40.join(cacheDir(root2), "serve-live");
992
+ return path41.join(cacheDir(root2), "serve-live");
993
993
  }
994
994
  function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid, signal) => process.kill(pid, signal), selfPid = process.pid) {
995
995
  let entries;
@@ -1003,7 +1003,7 @@ function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid
1003
1003
  if (!/^serve-\d+\.json$/.test(name)) continue;
1004
1004
  let parsed;
1005
1005
  try {
1006
- parsed = JSON.parse(fs11.readFileSync(path40.join(dir, name), "utf8"));
1006
+ parsed = JSON.parse(fs11.readFileSync(path41.join(dir, name), "utf8"));
1007
1007
  } catch {
1008
1008
  continue;
1009
1009
  }
@@ -1025,7 +1025,7 @@ var LiveStatsBus = class {
1025
1025
  this.dir = dir;
1026
1026
  this.stats = stats;
1027
1027
  this.pid = pid;
1028
- this.file = path40.join(dir, `serve-${this.pid}.json`);
1028
+ this.file = path41.join(dir, `serve-${this.pid}.json`);
1029
1029
  }
1030
1030
  dir;
1031
1031
  stats;
@@ -1078,7 +1078,7 @@ var LiveStatsBus = class {
1078
1078
  const out2 = [];
1079
1079
  for (const name of entries.sort()) {
1080
1080
  if (!/^serve-\d+\.json$/.test(name)) continue;
1081
- const file = path40.join(this.dir, name);
1081
+ const file = path41.join(this.dir, name);
1082
1082
  let parsed;
1083
1083
  try {
1084
1084
  parsed = JSON.parse(fs11.readFileSync(file, "utf8"));
@@ -1824,7 +1824,7 @@ function endOfLine(text, line) {
1824
1824
  }
1825
1825
  var CACHE_VERSION = "vg-lsp-scan-cache/2";
1826
1826
  function cachePath(root2) {
1827
- return path40.join(cacheDir(root2), "lsp-scan.json");
1827
+ return path41.join(cacheDir(root2), "lsp-scan.json");
1828
1828
  }
1829
1829
  function manifestHash(root2) {
1830
1830
  const files = [];
@@ -1836,7 +1836,7 @@ function manifestHash(root2) {
1836
1836
  return;
1837
1837
  }
1838
1838
  for (const entry of entries) {
1839
- const abs = path40.join(dir, entry.name);
1839
+ const abs = path41.join(dir, entry.name);
1840
1840
  if (entry.isDirectory()) {
1841
1841
  if (isSkippedDirName(entry.name)) continue;
1842
1842
  walk2(abs);
@@ -1846,7 +1846,7 @@ function manifestHash(root2) {
1846
1846
  const base = entry.name.toLowerCase();
1847
1847
  if (!isManifest(abs) && !SKIP_FILES.has(base)) continue;
1848
1848
  try {
1849
- const rel = path40.relative(root2, abs).split(path40.sep).join("/");
1849
+ const rel = path41.relative(root2, abs).split(path41.sep).join("/");
1850
1850
  files.push({ rel, hash: hashBytes(fs11.readFileSync(abs)) });
1851
1851
  } catch {
1852
1852
  }
@@ -1857,9 +1857,9 @@ function manifestHash(root2) {
1857
1857
  return hashString(canonicalize(files));
1858
1858
  }
1859
1859
  function isDependencyFile(root2, filePath) {
1860
- const rel = path40.relative(path40.resolve(root2), path40.resolve(filePath));
1861
- if (rel === "" || rel.startsWith("..") || path40.isAbsolute(rel)) return false;
1862
- const parts = rel.split(path40.sep);
1860
+ const rel = path41.relative(path41.resolve(root2), path41.resolve(filePath));
1861
+ if (rel === "" || rel.startsWith("..") || path41.isAbsolute(rel)) return false;
1862
+ const parts = rel.split(path41.sep);
1863
1863
  if (parts.slice(0, -1).some((dir) => isSkippedDirName(dir))) return false;
1864
1864
  const base = parts[parts.length - 1].toLowerCase();
1865
1865
  return isManifest(filePath) || SKIP_FILES.has(base);
@@ -1890,7 +1890,7 @@ function writeScanCache(root2, key2, artifact) {
1890
1890
  var MAX_ENTRIES = 1e3;
1891
1891
  var KEEP_ENTRIES = 500;
1892
1892
  function historyPath(root2) {
1893
- return path40.join(root2, ".vibgrate", "score-history.jsonl");
1893
+ return path41.join(root2, ".vibgrate", "score-history.jsonl");
1894
1894
  }
1895
1895
  function parseLine(line) {
1896
1896
  try {
@@ -1931,7 +1931,7 @@ function recordScore(root2, entry) {
1931
1931
  }
1932
1932
  }
1933
1933
  const file = historyPath(root2);
1934
- fs11.mkdirSync(path40.dirname(file), { recursive: true });
1934
+ fs11.mkdirSync(path41.dirname(file), { recursive: true });
1935
1935
  ensureVibgrateGitignore(root2);
1936
1936
  fs11.appendFileSync(file, `${JSON.stringify(entry)}
1937
1937
  `);
@@ -2458,6 +2458,11 @@ var VibgrateLanguageServer = class {
2458
2458
  constructor(opts, output = process.stdout) {
2459
2459
  this.opts = opts;
2460
2460
  this.conn = new Connection(process.stdin, output);
2461
+ this.refresher = new RefreshScheduler({
2462
+ root: opts.root,
2463
+ graphPath: () => resolveGraphPath(opts.root),
2464
+ onSettled: (outcome) => this.onRefreshSettled(outcome)
2465
+ });
2461
2466
  this.register();
2462
2467
  }
2463
2468
  opts;
@@ -2477,6 +2482,13 @@ var VibgrateLanguageServer = class {
2477
2482
  shuttingDown = false;
2478
2483
  graph = null;
2479
2484
  graphBuilding = false;
2485
+ /**
2486
+ * Keeps the freshness probe / incremental rebuild OFF the query path. The
2487
+ * probe alone stat-walks the whole corpus synchronously (seconds on a 20k-file
2488
+ * workspace) and a real drift rebuilds the map; awaiting either inline made a
2489
+ * single Ask block for over a minute. See engine/refresh-scheduler.ts.
2490
+ */
2491
+ refresher;
2480
2492
  register() {
2481
2493
  this.conn.onRequest("initialize", () => ({
2482
2494
  capabilities: {
@@ -2799,18 +2811,30 @@ var VibgrateLanguageServer = class {
2799
2811
  this.graphBuilding = false;
2800
2812
  }
2801
2813
  }
2802
- /** The graph, refreshed if the working tree drifted since the last build (same probe `vg ask` uses). */
2814
+ /**
2815
+ * The graph for a query. The first call still builds the map (there is
2816
+ * nothing to answer from otherwise), but a *refresh* is only ever kicked off
2817
+ * here — never awaited to completion. The scheduler waits a micro-budget so a
2818
+ * warm probe can land, then we answer from the map we have; a rebuild that
2819
+ * outruns the budget is picked up by `onRefreshSettled` for the next query.
2820
+ */
2803
2821
  async graphForQuery() {
2804
2822
  await this.ensureGraph();
2805
2823
  if (!this.graph) return null;
2806
- const graphPath = resolveGraphPath(this.opts.root);
2807
- const refreshed = await refreshIfStale(this.opts.root, { graphPath });
2808
- if (refreshed.status === "refreshed" && refreshed.wrote) {
2809
- const reloaded = loadGraph(this.opts.root);
2810
- if (reloaded) this.graph = reloaded;
2811
- }
2824
+ await this.refresher.maybeRefresh();
2812
2825
  return this.graph;
2813
2826
  }
2827
+ /**
2828
+ * A refresh finished. Reload only when it actually rewrote the map — and
2829
+ * prefer the SQLite index, because re-parsing a six-figure-node `graph.json`
2830
+ * is itself multi-second work we must not do more often than the map changes.
2831
+ */
2832
+ onRefreshSettled(outcome) {
2833
+ if (outcome?.status !== "refreshed" || !outcome.wrote) return;
2834
+ const graphPath = resolveGraphPath(this.opts.root);
2835
+ const reloaded = loadGraphPreferIndex(this.opts.root, graphPath)?.graph ?? loadGraph(this.opts.root);
2836
+ if (reloaded) this.graph = reloaded;
2837
+ }
2814
2838
  async onGraphQuery(params) {
2815
2839
  const p = params;
2816
2840
  const trace = (message) => this.conn.notify("window/logMessage", { type: 3, message: `Vibgrate graph: ${message}` });
@@ -2878,7 +2902,7 @@ var VibgrateLanguageServer = class {
2878
2902
  const ecosystem = osvEcosystem(proj.type);
2879
2903
  if (!ecosystem) continue;
2880
2904
  const relManifest = manifestRelativePath(proj);
2881
- const absManifest = path40.resolve(this.opts.root, relManifest);
2905
+ const absManifest = path41.resolve(this.opts.root, relManifest);
2882
2906
  let text = null;
2883
2907
  try {
2884
2908
  if (fs11.existsSync(absManifest)) text = fs11.readFileSync(absManifest, "utf8");
@@ -3030,9 +3054,9 @@ function pruneArtifactProjects(a) {
3030
3054
  return { ...a, projects, findings };
3031
3055
  }
3032
3056
  function projectByPath(a, projectPath) {
3033
- const want = path40.normalize(projectPath === "" ? "." : projectPath);
3057
+ const want = path41.normalize(projectPath === "" ? "." : projectPath);
3034
3058
  for (const proj of a.projects ?? []) {
3035
- const got = path40.normalize(proj.path === "" ? "." : proj.path);
3059
+ const got = path41.normalize(proj.path === "" ? "." : proj.path);
3036
3060
  if (got === want) return proj;
3037
3061
  }
3038
3062
  return void 0;
@@ -3069,12 +3093,12 @@ function buildProjectRefs(rootDir, projects) {
3069
3093
  return refs.length > 0 ? refs : void 0;
3070
3094
  }
3071
3095
  function projectForFile(root2, a, filePath) {
3072
- const dir = path40.dirname(path40.resolve(filePath));
3096
+ const dir = path41.dirname(path41.resolve(filePath));
3073
3097
  let best;
3074
3098
  let bestLen = -1;
3075
3099
  for (const proj of a.projects ?? []) {
3076
- const projDir = path40.resolve(root2, proj.path);
3077
- if ((dir === projDir || dir.startsWith(projDir + path40.sep)) && projDir.length > bestLen) {
3100
+ const projDir = path41.resolve(root2, proj.path);
3101
+ if ((dir === projDir || dir.startsWith(projDir + path41.sep)) && projDir.length > bestLen) {
3078
3102
  best = proj;
3079
3103
  bestLen = projDir.length;
3080
3104
  }
@@ -3082,7 +3106,7 @@ function projectForFile(root2, a, filePath) {
3082
3106
  return best;
3083
3107
  }
3084
3108
  function sameProject(location, projectPath) {
3085
- return path40.normalize(location) === path40.normalize(projectPath);
3109
+ return path41.normalize(location) === path41.normalize(projectPath);
3086
3110
  }
3087
3111
  function hasReleaseDates(a) {
3088
3112
  for (const proj of a.projects ?? []) {
@@ -3152,7 +3176,7 @@ function buildBreakdown(rootDir, projects) {
3152
3176
  const relManifest = manifestRelativePath(p);
3153
3177
  if (isPrunedWorkspacePath(p.path) || isPrunedWorkspacePath(relManifest)) continue;
3154
3178
  const ecosystem = osvEcosystem(p.type);
3155
- const absManifest = path40.resolve(rootDir, relManifest);
3179
+ const absManifest = path41.resolve(rootDir, relManifest);
3156
3180
  let text = null;
3157
3181
  try {
3158
3182
  if (fs11.existsSync(absManifest)) text = fs11.readFileSync(absManifest, "utf8");
@@ -3220,34 +3244,34 @@ function buildBreakdown(rootDir, projects) {
3220
3244
  }
3221
3245
  function manifestRelativePath(proj) {
3222
3246
  const base = proj.path === "." || proj.path === "" ? "" : proj.path;
3223
- const join30 = (name) => base ? path40.join(base, name) : name;
3247
+ const join31 = (name) => base ? path41.join(base, name) : name;
3224
3248
  switch (proj.type) {
3225
3249
  case "node":
3226
3250
  case "typescript":
3227
- return join30("package.json");
3251
+ return join31("package.json");
3228
3252
  case "python":
3229
- return join30("pyproject.toml");
3253
+ return join31("pyproject.toml");
3230
3254
  case "go":
3231
- return join30("go.mod");
3255
+ return join31("go.mod");
3232
3256
  case "rust":
3233
- return join30("Cargo.toml");
3257
+ return join31("Cargo.toml");
3234
3258
  case "ruby":
3235
- return join30("Gemfile");
3259
+ return join31("Gemfile");
3236
3260
  case "php":
3237
- return join30("composer.json");
3261
+ return join31("composer.json");
3238
3262
  case "java":
3239
3263
  case "kotlin":
3240
3264
  case "scala":
3241
3265
  case "groovy":
3242
- return join30("pom.xml");
3266
+ return join31("pom.xml");
3243
3267
  case "dotnet":
3244
- return join30(proj.name ? `${proj.name}.csproj` : "Directory.Build.props");
3268
+ return join31(proj.name ? `${proj.name}.csproj` : "Directory.Build.props");
3245
3269
  case "dart":
3246
- return join30("pubspec.yaml");
3270
+ return join31("pubspec.yaml");
3247
3271
  case "elixir":
3248
- return join30("mix.exs");
3272
+ return join31("mix.exs");
3249
3273
  default:
3250
- return join30("package.json");
3274
+ return join31("package.json");
3251
3275
  }
3252
3276
  }
3253
3277
  function lockfileRelativePath(rootDir, proj) {
@@ -3278,9 +3302,9 @@ function lockfileRelativePath(rootDir, proj) {
3278
3302
  const dirsToTry = base ? [base, ""] : [""];
3279
3303
  for (const dir of dirsToTry) {
3280
3304
  for (const name of candidateNames) {
3281
- const rel = dir ? path40.join(dir, name) : name;
3305
+ const rel = dir ? path41.join(dir, name) : name;
3282
3306
  try {
3283
- if (fs11.existsSync(path40.join(rootDir, rel))) return rel;
3307
+ if (fs11.existsSync(path41.join(rootDir, rel))) return rel;
3284
3308
  } catch {
3285
3309
  }
3286
3310
  }
@@ -3351,7 +3375,7 @@ function lookupImportFiles(map, pkg) {
3351
3375
  }
3352
3376
  function firstPackageMentionLine(root2, relFile, pkg) {
3353
3377
  try {
3354
- const abs = path40.resolve(root2, relFile);
3378
+ const abs = path41.resolve(root2, relFile);
3355
3379
  const stat2 = fs11.statSync(abs);
3356
3380
  if (!stat2.isFile() || stat2.size > 256 * 1024) return null;
3357
3381
  const text = fs11.readFileSync(abs, "utf8");
@@ -3555,8 +3579,8 @@ function hookCommand(vgBin) {
3555
3579
  return `${vgBin} hook pre-tool-use`;
3556
3580
  }
3557
3581
  function installClaudeHooks(root2, vgBin = "vg") {
3558
- const file = path40.join(root2, ".claude", "settings.json");
3559
- const rel = path40.join(".claude", "settings.json");
3582
+ const file = path41.join(root2, ".claude", "settings.json");
3583
+ const rel = path41.join(".claude", "settings.json");
3560
3584
  let settings = {};
3561
3585
  if (fs11.existsSync(file)) {
3562
3586
  try {
@@ -3597,8 +3621,8 @@ function installClaudeHooks(root2, vgBin = "vg") {
3597
3621
  return { file: rel, status: "written" };
3598
3622
  }
3599
3623
  function uninstallClaudeHooks(root2) {
3600
- const file = path40.join(root2, ".claude", "settings.json");
3601
- const rel = path40.join(".claude", "settings.json");
3624
+ const file = path41.join(root2, ".claude", "settings.json");
3625
+ const rel = path41.join(".claude", "settings.json");
3602
3626
  if (!fs11.existsSync(file)) return { file: rel, status: "unchanged" };
3603
3627
  let settings;
3604
3628
  try {
@@ -3624,7 +3648,7 @@ function uninstallClaudeHooks(root2) {
3624
3648
  return { file: rel, status: "written" };
3625
3649
  }
3626
3650
  function writeSettings(file, settings) {
3627
- fs11.mkdirSync(path40.dirname(file), { recursive: true });
3651
+ fs11.mkdirSync(path41.dirname(file), { recursive: true });
3628
3652
  fs11.writeFileSync(file, `${JSON.stringify(settings, null, 2)}
3629
3653
  `);
3630
3654
  }
@@ -3745,7 +3769,7 @@ function registryBase(opts) {
3745
3769
  return (process.env.VIBGRATE_MODULE_REGISTRY || opts.registry || DEFAULT_REGISTRY).replace(/\/+$/, "");
3746
3770
  }
3747
3771
  function stateFile() {
3748
- return path40.join(path40.dirname(relevanceModuleDir()), "consent.json");
3772
+ return path41.join(path41.dirname(relevanceModuleDir()), "consent.json");
3749
3773
  }
3750
3774
  function readConsent() {
3751
3775
  try {
@@ -3756,7 +3780,7 @@ function readConsent() {
3756
3780
  }
3757
3781
  function writeConsent(state) {
3758
3782
  try {
3759
- fs11.mkdirSync(path40.dirname(stateFile()), { recursive: true });
3783
+ fs11.mkdirSync(path41.dirname(stateFile()), { recursive: true });
3760
3784
  fs11.writeFileSync(stateFile(), JSON.stringify(state));
3761
3785
  } catch {
3762
3786
  }
@@ -3767,8 +3791,8 @@ function kernelDisabled() {
3767
3791
  }
3768
3792
  function moduleInstalled() {
3769
3793
  try {
3770
- const meta = JSON.parse(fs11.readFileSync(path40.join(relevanceModuleDir(), ".module.json"), "utf8"));
3771
- if (fs11.existsSync(path40.join(relevanceModuleDir(), "index.js"))) {
3794
+ const meta = JSON.parse(fs11.readFileSync(path41.join(relevanceModuleDir(), ".module.json"), "utf8"));
3795
+ if (fs11.existsSync(path41.join(relevanceModuleDir(), "index.js"))) {
3772
3796
  return { installed: true, version: meta.version };
3773
3797
  }
3774
3798
  } catch {
@@ -3817,7 +3841,7 @@ function untar(data) {
3817
3841
  if (type !== "0" && type !== "\0") continue;
3818
3842
  const name = pendingName ?? (prefix ? `${prefix}/${rawName}` : rawName);
3819
3843
  pendingName = null;
3820
- if (name.split("/").includes("..") || path40.isAbsolute(name)) {
3844
+ if (name.split("/").includes("..") || path41.isAbsolute(name)) {
3821
3845
  throw new Error(`unsafe path in tarball: ${name}`);
3822
3846
  }
3823
3847
  out2.push({ name, body: Buffer.from(body) });
@@ -3851,17 +3875,17 @@ async function installRelevanceModule(opts = {}) {
3851
3875
  if (e.name.startsWith("package/dist/")) rel = e.name.slice("package/dist/".length);
3852
3876
  else if (e.name === "package/LICENSE" || e.name === "package/README.md") rel = e.name.slice("package/".length);
3853
3877
  if (!rel) continue;
3854
- const target = path40.join(dir, rel);
3855
- if (!target.startsWith(dir + path40.sep) && target !== dir) throw new Error(`unsafe extract path: ${rel}`);
3856
- fs11.mkdirSync(path40.dirname(target), { recursive: true });
3878
+ const target = path41.join(dir, rel);
3879
+ if (!target.startsWith(dir + path41.sep) && target !== dir) throw new Error(`unsafe extract path: ${rel}`);
3880
+ fs11.mkdirSync(path41.dirname(target), { recursive: true });
3857
3881
  fs11.writeFileSync(target, e.body);
3858
3882
  wrote += 1;
3859
3883
  }
3860
- if (!wrote || !fs11.existsSync(path40.join(dir, "index.js"))) {
3884
+ if (!wrote || !fs11.existsSync(path41.join(dir, "index.js"))) {
3861
3885
  fs11.rmSync(dir, { recursive: true, force: true });
3862
3886
  return { status: "unavailable", detail: "package layout not recognized (no dist/index.js)" };
3863
3887
  }
3864
- fs11.writeFileSync(path40.join(dir, ".module.json"), JSON.stringify({ name: RELEVANCE_MODULE_NAME, version }));
3888
+ fs11.writeFileSync(path41.join(dir, ".module.json"), JSON.stringify({ name: RELEVANCE_MODULE_NAME, version }));
3865
3889
  resetRelevanceProviderCache();
3866
3890
  return { status: "installed", version };
3867
3891
  } catch (e) {
@@ -4020,7 +4044,7 @@ function registerShare(program) {
4020
4044
  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) {
4021
4045
  const global = readGlobal(this);
4022
4046
  const root2 = rootOf(global);
4023
- const gitDir = path40.join(root2, ".git");
4047
+ const gitDir = path41.join(root2, ".git");
4024
4048
  if (!fs11.existsSync(gitDir)) {
4025
4049
  throw new CliError("not a git repository \u2014 run `vg share` inside a git repo", ExitCode.USAGE_ERROR);
4026
4050
  }
@@ -4042,15 +4066,15 @@ function registerShare(program) {
4042
4066
  applyGlobalOptions(cmd);
4043
4067
  }
4044
4068
  function writeVibgrateGitignore(root2, reports) {
4045
- const dir = path40.join(root2, ".vibgrate");
4069
+ const dir = path41.join(root2, ".vibgrate");
4046
4070
  fs11.mkdirSync(dir, { recursive: true });
4047
4071
  const lines = ["# Managed by `vg share` \u2014 keep graph.json committed, ignore the rest", "cache/", "facts.jsonl", "graph.snap"];
4048
4072
  if (!reports) lines.push("graph.html", "GRAPH_REPORT.md");
4049
- fs11.writeFileSync(path40.join(dir, ".gitignore"), `${lines.join("\n")}
4073
+ fs11.writeFileSync(path41.join(dir, ".gitignore"), `${lines.join("\n")}
4050
4074
  `);
4051
4075
  }
4052
4076
  function writeGitAttributes(root2) {
4053
- const file = path40.join(root2, ".gitattributes");
4077
+ const file = path41.join(root2, ".gitattributes");
4054
4078
  const line = ".vibgrate/graph.json merge=vg";
4055
4079
  let content = fs11.existsSync(file) ? fs11.readFileSync(file, "utf8") : "";
4056
4080
  if (!content.split("\n").some((l) => l.trim() === line)) {
@@ -4068,7 +4092,7 @@ function configureMergeDriver(root2) {
4068
4092
  function installPreCommitHook(root2) {
4069
4093
  const hooksDir = hookDir(root2);
4070
4094
  fs11.mkdirSync(hooksDir, { recursive: true });
4071
- const file = path40.join(hooksDir, "pre-commit");
4095
+ const file = path41.join(hooksDir, "pre-commit");
4072
4096
  const block = [
4073
4097
  HOOK_BEGIN,
4074
4098
  "if command -v vg >/dev/null 2>&1; then",
@@ -4090,14 +4114,14 @@ ${content}`;
4090
4114
  fs11.chmodSync(file, 493);
4091
4115
  }
4092
4116
  function undo(root2) {
4093
- const hookFile = path40.join(hookDir(root2), "pre-commit");
4117
+ const hookFile = path41.join(hookDir(root2), "pre-commit");
4094
4118
  if (fs11.existsSync(hookFile)) {
4095
4119
  const re = new RegExp(`\\n*${escapeRe(HOOK_BEGIN)}[\\s\\S]*?${escapeRe(HOOK_END)}\\n*`);
4096
4120
  const next2 = fs11.readFileSync(hookFile, "utf8").replace(re, "\n");
4097
4121
  if (next2.trim() === "#!/bin/sh") fs11.rmSync(hookFile);
4098
4122
  else fs11.writeFileSync(hookFile, next2);
4099
4123
  }
4100
- const attr = path40.join(root2, ".gitattributes");
4124
+ const attr = path41.join(root2, ".gitattributes");
4101
4125
  if (fs11.existsSync(attr)) {
4102
4126
  const next2 = fs11.readFileSync(attr, "utf8").split("\n").filter((l) => l.trim() !== ".vibgrate/graph.json merge=vg").join("\n");
4103
4127
  fs11.writeFileSync(attr, next2);
@@ -4110,10 +4134,10 @@ function undo(root2) {
4110
4134
  function hookDir(root2) {
4111
4135
  try {
4112
4136
  const configured = git(root2, ["config", "--get", "core.hooksPath"]).trim();
4113
- if (configured) return path40.resolve(root2, configured);
4137
+ if (configured) return path41.resolve(root2, configured);
4114
4138
  } catch {
4115
4139
  }
4116
- return path40.join(root2, ".git", "hooks");
4140
+ return path41.join(root2, ".git", "hooks");
4117
4141
  }
4118
4142
  function git(root2, args) {
4119
4143
  return execFileSync("git", args, { cwd: root2, encoding: "utf8" });
@@ -4127,7 +4151,7 @@ function registerWatch(program) {
4127
4151
  const global = readGlobal(this);
4128
4152
  const root2 = rootOf(global);
4129
4153
  const debounceMs = Math.max(50, Number(opts.debounce) || DEFAULT_DEBOUNCE_MS);
4130
- const watchRoots = (paths.length ? paths : ["."]).map((p) => path40.resolve(root2, p));
4154
+ const watchRoots = (paths.length ? paths : ["."]).map((p) => path41.resolve(root2, p));
4131
4155
  for (const w of watchRoots) {
4132
4156
  if (!fs11.existsSync(w)) {
4133
4157
  throw new CliError(`watch path not found: ${w}`, ExitCode.USAGE_ERROR);
@@ -4195,7 +4219,7 @@ function registerWatch(program) {
4195
4219
  throw new CliError(`cannot watch ${w}: ${err.message}`, ExitCode.ERROR);
4196
4220
  }
4197
4221
  }
4198
- info(c.dim(`vg watch \xB7 watching ${watchRoots.map((p) => path40.relative(root2, p) || ".").join(", ")} (debounce ${debounceMs}ms) \xB7 Ctrl+C to stop`));
4222
+ info(c.dim(`vg watch \xB7 watching ${watchRoots.map((p) => path41.relative(root2, p) || ".").join(", ")} (debounce ${debounceMs}ms) \xB7 Ctrl+C to stop`));
4199
4223
  await new Promise((resolve21) => {
4200
4224
  const stop = () => {
4201
4225
  for (const w of watchers) w.close();
@@ -4528,7 +4552,7 @@ function normalizeStandards(raw) {
4528
4552
  }
4529
4553
  function loadStandards(root2) {
4530
4554
  for (const rel of STANDARDS_FILES) {
4531
- const p = path40__default.join(root2, rel);
4555
+ const p = path41__default.join(root2, rel);
4532
4556
  let text;
4533
4557
  try {
4534
4558
  text = fs11__default.readFileSync(p, "utf8");
@@ -5249,8 +5273,8 @@ async function runHostBench(options = {}) {
5249
5273
  }
5250
5274
  async function runArmSimulate(input) {
5251
5275
  const { arm, lib, modelPath, turns, trie, env, live } = input;
5252
- const path42 = `${modelPath}#${arm.id}`;
5253
- const session = await acquireHostSession(lib, path42);
5276
+ const path43 = `${modelPath}#${arm.id}`;
5277
+ const session = await acquireHostSession(lib, path43);
5254
5278
  const system = "You are a coding agent with a Task Capsule.";
5255
5279
  const capsule = "function readConfig(): Config { return load(); }";
5256
5280
  let last = null;
@@ -6614,8 +6638,8 @@ function registerModels(program) {
6614
6638
  }
6615
6639
  });
6616
6640
  if (opts.out) {
6617
- const outPath = path40.resolve(opts.out);
6618
- fs11.mkdirSync(path40.dirname(outPath), { recursive: true });
6641
+ const outPath = path41.resolve(opts.out);
6642
+ fs11.mkdirSync(path41.dirname(outPath), { recursive: true });
6619
6643
  fs11.writeFileSync(outPath, `${JSON.stringify(report, null, 2)}
6620
6644
  `);
6621
6645
  if (!global.json) info(c.dim(` wrote ${outPath}`));
@@ -6765,14 +6789,14 @@ function resolveUninstallTarget(name, runtimeOpt) {
6765
6789
  }
6766
6790
  return exact[0];
6767
6791
  }
6768
- const base = path40.basename(wantLc);
6792
+ const base = path41.basename(wantLc);
6769
6793
  const soft = fleet.filter((m) => {
6770
6794
  const n = m.name.toLowerCase();
6771
- return n === base || n.endsWith("/" + base) || n.endsWith(wantLc) || path40.basename(n) === base;
6795
+ return n === base || n.endsWith("/" + base) || n.endsWith(wantLc) || path41.basename(n) === base;
6772
6796
  });
6773
6797
  if (soft.length === 1) return soft[0];
6774
6798
  if (soft.length > 1) {
6775
- const baseHits = soft.filter((m) => path40.basename(m.name).toLowerCase() === base);
6799
+ const baseHits = soft.filter((m) => path41.basename(m.name).toLowerCase() === base);
6776
6800
  const pool = baseHits.length ? baseHits : soft;
6777
6801
  const order = ["ollama", "gguf", "lm-studio"];
6778
6802
  for (const rt of order) {
@@ -6810,7 +6834,7 @@ function printBackends(backends) {
6810
6834
  }
6811
6835
  }
6812
6836
  function codeConfigPath(root2) {
6813
- return path40.join(root2, ".vibgrate", "code.json");
6837
+ return path41.join(root2, ".vibgrate", "code.json");
6814
6838
  }
6815
6839
  function loadCodeConfig(root2) {
6816
6840
  try {
@@ -6892,7 +6916,7 @@ function discoverMcpServers(root2, ownServers) {
6892
6916
  const servers = {};
6893
6917
  const sources = [];
6894
6918
  for (const rel of MCP_CONFIG_FILES) {
6895
- const found = readMcpServersFile(path40.join(root2, rel));
6919
+ const found = readMcpServersFile(path41.join(root2, rel));
6896
6920
  const names = Object.keys(found);
6897
6921
  if (names.length) {
6898
6922
  sources.push(rel);
@@ -6924,7 +6948,7 @@ function registerCode(program) {
6924
6948
  try {
6925
6949
  const { parseMode: parseMode2, resolveMode: resolveMode2, readOrchestratorState: readOrchestratorState2, activePin: activePin2 } = await import('./model-orchestrator-LHYPJBFH.js');
6926
6950
  const { gatherSystemMemory: gatherSystemMemory2 } = await import('./local-runtime-2ED33KK6.js');
6927
- const { loadGraph: loadGraph2 } = await import('./load-BB52WJTD.js');
6951
+ const { loadGraph: loadGraph2 } = await import('./load-OMTSGVDX.js');
6928
6952
  const state = readOrchestratorState2();
6929
6953
  const mode = parseMode2(modeFlag) ?? state.defaultMode ?? void 0;
6930
6954
  const pin = mode ? activePin2(mode, state) : null;
@@ -7009,7 +7033,7 @@ function registerCode(program) {
7009
7033
  if (!(process.stdin.isTTY && process.stdout.isTTY)) {
7010
7034
  throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"` (guided mode needs an interactive terminal)');
7011
7035
  }
7012
- const { runInteractive } = await import('./interactive-AAKPP4BJ.js');
7036
+ const { runInteractive } = await import('./interactive-IJS33F4K.js');
7013
7037
  await runInteractive(
7014
7038
  rootOf(global),
7015
7039
  global,
@@ -7039,7 +7063,7 @@ function registerCode(program) {
7039
7063
  }
7040
7064
  if (!instruction && !stdinFirstTurn) throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"`');
7041
7065
  {
7042
- const { ensureCodeMap } = await import('./ensure-map-HWHMALI4.js');
7066
+ const { ensureCodeMap } = await import('./ensure-map-JICVC2ZJ.js');
7043
7067
  const mapRoot = rootOf(global);
7044
7068
  try {
7045
7069
  await ensureCodeMap(mapRoot, global, {
@@ -7124,20 +7148,20 @@ function registerCode(program) {
7124
7148
  process.stdout.write(JSON.stringify(line) + "\n");
7125
7149
  };
7126
7150
  try {
7127
- const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-TTLHJEDB.js');
7151
+ const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-UENLWBWC.js');
7128
7152
  const primarySlug = route.providers[0]?.model.includes("/") ? route.providers[0].model.split("/")[0] : route.providers[0]?.id;
7129
- const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-T6DS3GIO.js');
7130
- const { nodeCodeFs } = await import('./session-5TNNGP2K.js');
7153
+ const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-SVMGVBFB.js');
7154
+ const { nodeCodeFs } = await import('./session-HOS4454T.js');
7131
7155
  const readline6 = await import('readline');
7132
7156
  const child = await import('child_process');
7133
7157
  const { loadOrDiscoverFederation } = await import('./federation-MDQPO3PW.js');
7134
7158
  const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
7135
7159
  const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
7136
- const { startCodeRuntimeSession } = await import('./runtime-session-CKNRMKSK.js');
7137
- const { resolveGraphBackend } = await import('./graph-backend-H42SHYB5.js');
7160
+ const { startCodeRuntimeSession } = await import('./runtime-session-AFL7P4TQ.js');
7161
+ const { resolveGraphBackend } = await import('./graph-backend-TB35N5MC.js');
7138
7162
  const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
7139
7163
  const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
7140
- const { vgdRequest: vgdRequest2 } = await import('./vgd-FXIEZZT2.js');
7164
+ const { vgdRequest: vgdRequest2 } = await import('./vgd-YFPJHQB5.js');
7141
7165
  const federation = loadOrDiscoverFederation(root2);
7142
7166
  const modelProfile = mergeModelExecutionProfile(
7143
7167
  resolveModelExecutionProfile({
@@ -7195,7 +7219,7 @@ ${res.stderr}` : ""),
7195
7219
  exitCode: res.status ?? 1
7196
7220
  };
7197
7221
  };
7198
- const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-AP3B7BN6.js');
7222
+ const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-NYCAQEMU.js');
7199
7223
  const vgBuiltin = createVgBuiltinMcpTools({
7200
7224
  getGraph: () => graph,
7201
7225
  root: root2,
@@ -7216,10 +7240,10 @@ ${res.stderr}` : ""),
7216
7240
  }
7217
7241
  const externalTools = mergeExternalToolsets(vgBuiltin, projectMcp);
7218
7242
  const { createCheckpoint } = await import('./checkpoint-4WFZMKEO.js');
7219
- const os5 = await import('os');
7243
+ const os6 = await import('os');
7220
7244
  const pathMod = await import('path');
7221
7245
  const checkpointIndex = pathMod.join(
7222
- fs11.mkdtempSync(pathMod.join(os5.tmpdir(), "vg-code-cp-")),
7246
+ fs11.mkdtempSync(pathMod.join(os6.tmpdir(), "vg-code-cp-")),
7223
7247
  "index"
7224
7248
  );
7225
7249
  const gitRunner = (gitArgs, gitEnv) => {
@@ -7285,8 +7309,8 @@ ${res.stderr}` : ""),
7285
7309
  };
7286
7310
  try {
7287
7311
  if (opts.session) {
7288
- const { runCodeStreamJsonSession } = await import('./stream-json-T6DS3GIO.js');
7289
- const { runAgent: runAgent2 } = await import('./agent-WH2VVIHM.js');
7312
+ const { runCodeStreamJsonSession } = await import('./stream-json-SVMGVBFB.js');
7313
+ const { runAgent: runAgent2 } = await import('./agent-SBVWSP7G.js');
7290
7314
  const {
7291
7315
  condenseSession,
7292
7316
  loadLatestSession,
@@ -7454,8 +7478,8 @@ ${res.stderr}` : ""),
7454
7478
  if (!autonomous && !tty) {
7455
7479
  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).");
7456
7480
  }
7457
- const { agentTask } = await import('./interactive-AAKPP4BJ.js');
7458
- const { nodeCodeFs } = await import('./session-5TNNGP2K.js');
7481
+ const { agentTask } = await import('./interactive-IJS33F4K.js');
7482
+ const { nodeCodeFs } = await import('./session-HOS4454T.js');
7459
7483
  const { TtyPrompter } = await import('./ui-K7D3BCHD.js');
7460
7484
  let priorSummary;
7461
7485
  let priorInstruction;
@@ -7468,7 +7492,7 @@ ${res.stderr}` : ""),
7468
7492
  }
7469
7493
  }
7470
7494
  const prompter = tty ? new TtyPrompter() : void 0;
7471
- const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-AP3B7BN6.js');
7495
+ const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-NYCAQEMU.js');
7472
7496
  const vgBuiltin = createVgBuiltinMcpTools({
7473
7497
  getGraph: () => graph,
7474
7498
  root: root2,
@@ -7492,11 +7516,11 @@ ${res.stderr}` : ""),
7492
7516
  const { loadFederation } = await import('./federation-MDQPO3PW.js');
7493
7517
  const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
7494
7518
  const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
7495
- const { startCodeRuntimeSession } = await import('./runtime-session-CKNRMKSK.js');
7496
- const { resolveGraphBackend } = await import('./graph-backend-H42SHYB5.js');
7519
+ const { startCodeRuntimeSession } = await import('./runtime-session-AFL7P4TQ.js');
7520
+ const { resolveGraphBackend } = await import('./graph-backend-TB35N5MC.js');
7497
7521
  const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
7498
7522
  const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
7499
- const { vgdRequest: vgdRequest2 } = await import('./vgd-FXIEZZT2.js');
7523
+ const { vgdRequest: vgdRequest2 } = await import('./vgd-YFPJHQB5.js');
7500
7524
  const federation = loadFederation(root2);
7501
7525
  const modelProfile = mergeModelExecutionProfile(
7502
7526
  resolveModelExecutionProfile({
@@ -7803,7 +7827,7 @@ async function addCmd(root2, rest, opts, asJson) {
7803
7827
  }
7804
7828
  function readPackageVersion(root2) {
7805
7829
  try {
7806
- const pkg = JSON.parse(fs11__default.readFileSync(path40__default.join(root2, "package.json"), "utf8"));
7830
+ const pkg = JSON.parse(fs11__default.readFileSync(path41__default.join(root2, "package.json"), "utf8"));
7807
7831
  return typeof pkg.version === "string" ? pkg.version : void 0;
7808
7832
  } catch {
7809
7833
  return void 0;
@@ -7826,8 +7850,8 @@ async function publishCmd(root2, rest, opts, global, asJson) {
7826
7850
  if (!parsed) throw new CliError("publishing a private library requires a DSN \u2014 run `vibgrate login` or set VIBGRATE_DSN", ExitCode.USAGE_ERROR);
7827
7851
  const version = (opts.version || readPackageVersion(root2) || "").trim();
7828
7852
  if (!version) throw usageError("a --version is required (or run from a package whose package.json has a version)");
7829
- const readme = readOptionalFile(opts.readme ? path40__default.resolve(opts.readme) : path40__default.join(root2, "README.md"));
7830
- const dts = opts.dts ? readOptionalFile(path40__default.resolve(opts.dts)) : void 0;
7853
+ const readme = readOptionalFile(opts.readme ? path41__default.resolve(opts.readme) : path41__default.join(root2, "README.md"));
7854
+ const dts = opts.dts ? readOptionalFile(path41__default.resolve(opts.dts)) : void 0;
7831
7855
  if (!readme && !dts) throw usageError("nothing to publish \u2014 no README.md found and no --dts given");
7832
7856
  const result = await publishPrivateLibrary(
7833
7857
  { name, version, readme, dts, language: opts.language },
@@ -7959,7 +7983,7 @@ function registerExport(program) {
7959
7983
  out(content.trimEnd());
7960
7984
  return;
7961
7985
  }
7962
- fs11.mkdirSync(path40.dirname(path40.resolve(file)), { recursive: true });
7986
+ fs11.mkdirSync(path41.dirname(path41.resolve(file)), { recursive: true });
7963
7987
  fs11.writeFileSync(file, content);
7964
7988
  info(`${c.green("\u2714")} wrote ${file} ${c.dim(`(${format})`)}`);
7965
7989
  });
@@ -7970,43 +7994,43 @@ function detectFormat(file) {
7970
7994
  if (lower.endsWith(".cdx.json")) return "cyclonedx";
7971
7995
  if (lower.endsWith(".spdx.json")) return "spdx";
7972
7996
  if (file === "-") return "json";
7973
- return formatForExt(path40.extname(file));
7997
+ return formatForExt(path41.extname(file));
7974
7998
  }
7975
7999
  function registerBundle(program) {
7976
8000
  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) {
7977
8001
  const global = readGlobal(this);
7978
8002
  const root2 = rootOf(global);
7979
- const outDir = path40.resolve(root2, opts.out ?? "vg-bundle");
8003
+ const outDir = path41.resolve(root2, opts.out ?? "vg-bundle");
7980
8004
  let grammarFiles;
7981
8005
  try {
7982
8006
  grammarFiles = resolvedGrammarFiles();
7983
8007
  } catch {
7984
8008
  throw new CliError("no grammars found to bundle (run a build first)", ExitCode.ERROR);
7985
8009
  }
7986
- fs11.mkdirSync(path40.join(outDir, "grammars"), { recursive: true });
8010
+ fs11.mkdirSync(path41.join(outDir, "grammars"), { recursive: true });
7987
8011
  let grammarCount = 0;
7988
8012
  for (const { fileName, absPath } of grammarFiles) {
7989
- fs11.copyFileSync(absPath, path40.join(outDir, "grammars", fileName));
8013
+ fs11.copyFileSync(absPath, path41.join(outDir, "grammars", fileName));
7990
8014
  grammarCount++;
7991
8015
  }
7992
8016
  const included = [`grammars/ (${grammarCount} .wasm)`];
7993
8017
  const graphSrc = resolveGraphPath(root2, global.graph);
7994
8018
  if (fs11.existsSync(graphSrc)) {
7995
- fs11.copyFileSync(graphSrc, path40.join(outDir, "graph.json"));
8019
+ fs11.copyFileSync(graphSrc, path41.join(outDir, "graph.json"));
7996
8020
  included.push("graph.json");
7997
8021
  } else {
7998
8022
  const graph = loadGraphFileWithSnapshot(graphSrc);
7999
8023
  if (graph) {
8000
- fs11.writeFileSync(path40.join(outDir, "graph.json"), serializeGraph(graph));
8024
+ fs11.writeFileSync(path41.join(outDir, "graph.json"), serializeGraph(graph));
8001
8025
  included.push("graph.json");
8002
8026
  }
8003
8027
  }
8004
8028
  const cat = catalogPath(root2);
8005
8029
  if (fs11.existsSync(cat)) {
8006
- fs11.copyFileSync(cat, path40.join(outDir, "vibgrate.lib.json"));
8030
+ fs11.copyFileSync(cat, path41.join(outDir, "vibgrate.lib.json"));
8007
8031
  included.push("vibgrate.lib.json");
8008
8032
  if (fs11.existsSync(libDir(root2))) {
8009
- fs11.cpSync(libDir(root2), path40.join(outDir, "lib"), { recursive: true });
8033
+ fs11.cpSync(libDir(root2), path41.join(outDir, "lib"), { recursive: true });
8010
8034
  included.push("lib/");
8011
8035
  }
8012
8036
  }
@@ -8018,15 +8042,15 @@ function registerBundle(program) {
8018
8042
  included,
8019
8043
  usage: "Run `vg build --grammars <this dir>/grammars` to build fully offline."
8020
8044
  };
8021
- fs11.writeFileSync(path40.join(outDir, "MANIFEST.json"), `${stableStringify(manifest, 2)}
8045
+ fs11.writeFileSync(path41.join(outDir, "MANIFEST.json"), `${stableStringify(manifest, 2)}
8022
8046
  `);
8023
8047
  if (global.json) {
8024
- json({ out: path40.relative(root2, outDir), ...manifest });
8048
+ json({ out: path41.relative(root2, outDir), ...manifest });
8025
8049
  return;
8026
8050
  }
8027
- info(`${c.cyan("vg bundle")} \xB7 wrote ${path40.relative(root2, outDir)}/`);
8051
+ info(`${c.cyan("vg bundle")} \xB7 wrote ${path41.relative(root2, outDir)}/`);
8028
8052
  for (const i of included) info(` ${c.green("\u2714")} ${i}`);
8029
- info(c.dim(` offline: vg build --grammars "${path40.relative(root2, outDir)}/grammars"`));
8053
+ info(c.dim(` offline: vg build --grammars "${path41.relative(root2, outDir)}/grammars"`));
8030
8054
  });
8031
8055
  applyGlobalOptions(cmd);
8032
8056
  }
@@ -8044,7 +8068,7 @@ async function runDoctor(global) {
8044
8068
  const root2 = rootOf(global);
8045
8069
  const local = global.local === true;
8046
8070
  const graphPath = resolveGraphPath(root2, global.graph);
8047
- const configFile = CONFIG_BASENAMES.find((f) => fs11.existsSync(path40.join(root2, f))) ?? null;
8071
+ const configFile = CONFIG_BASENAMES.find((f) => fs11.existsSync(path41.join(root2, f))) ?? null;
8048
8072
  const graph = loadGraph(root2, graphPath);
8049
8073
  let staleFiles = null;
8050
8074
  if (graph) {
@@ -8070,13 +8094,13 @@ async function runDoctor(global) {
8070
8094
  root: root2,
8071
8095
  configFile,
8072
8096
  map: {
8073
- path: path40.relative(root2, graphPath),
8097
+ path: path41.relative(root2, graphPath),
8074
8098
  built: graph !== null,
8075
8099
  generatedAt: graph?.generatedAt ?? null,
8076
8100
  staleFiles
8077
8101
  },
8078
8102
  libCatalog: {
8079
- path: path40.relative(root2, catalogPath(root2)),
8103
+ path: path41.relative(root2, catalogPath(root2)),
8080
8104
  present: fs11.existsSync(catalogPath(root2)),
8081
8105
  libraries: libCount
8082
8106
  },
@@ -8134,7 +8158,7 @@ async function runDoctor(global) {
8134
8158
  );
8135
8159
  info(
8136
8160
  ` host pool ${li.hostPool.size} warm session(s)` + (li.hostPool.sessions[0] ? c.dim(
8137
- ` \xB7 last ${path40.basename(li.hostPool.sessions[0].modelPath)} kv=${li.hostPool.sessions[0].kvBlocks}`
8161
+ ` \xB7 last ${path41.basename(li.hostPool.sessions[0].modelPath)} kv=${li.hostPool.sessions[0].kvBlocks}`
8138
8162
  ) : c.dim(" \xB7 none (load via vg code / vgd host-load)"))
8139
8163
  );
8140
8164
  if (li.dynamicOnToken || li.dynamicCustomSampler) {
@@ -8328,7 +8352,7 @@ function registerDaemon(program) {
8328
8352
  const register = cmd.command("register").description("register the current repository with a running vgd").argument("[root]", "repository root (default: cwd)").action(async function(rootArg) {
8329
8353
  const global = readGlobal(this);
8330
8354
  const socketPath = socketOf(this);
8331
- const root2 = path40.resolve(rootArg ?? rootOf(global));
8355
+ const root2 = path41.resolve(rootArg ?? rootOf(global));
8332
8356
  if (!await vgdIsRunning({ socketPath })) {
8333
8357
  throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
8334
8358
  }
@@ -8364,7 +8388,7 @@ function registerDaemon(program) {
8364
8388
  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) {
8365
8389
  const global = readGlobal(this);
8366
8390
  const socketPath = socketOf(this);
8367
- const primary = path40.resolve(rootArg ?? rootOf(global));
8391
+ const primary = path41.resolve(rootArg ?? rootOf(global));
8368
8392
  if (!await vgdIsRunning({ socketPath })) {
8369
8393
  throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
8370
8394
  }
@@ -8392,7 +8416,7 @@ function registerDaemon(program) {
8392
8416
  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) {
8393
8417
  const global = readGlobal(this);
8394
8418
  const socketPath = socketOf(this);
8395
- const root2 = path40.resolve(rootArg ?? rootOf(global));
8419
+ const root2 = path41.resolve(rootArg ?? rootOf(global));
8396
8420
  if (!await vgdIsRunning({ socketPath })) {
8397
8421
  throw new CliError(`vgd is not running \u2014 start it with \`vg daemon ensure\` (${socketPath})`, ExitCode.NOT_FOUND);
8398
8422
  }
@@ -8406,7 +8430,7 @@ function registerDaemon(program) {
8406
8430
  throw new CliError(loaded.error, ExitCode.NOT_FOUND);
8407
8431
  }
8408
8432
  if (!loaded.ok) {
8409
- const { loadGraph: loadGraph2 } = await import('./load-BB52WJTD.js');
8433
+ const { loadGraph: loadGraph2 } = await import('./load-OMTSGVDX.js');
8410
8434
  const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
8411
8435
  const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
8412
8436
  const graph = loadGraph2(root2, global.graph);
@@ -8522,7 +8546,7 @@ function socketOf(cmd) {
8522
8546
  let c2 = cmd;
8523
8547
  while (c2) {
8524
8548
  const opts = c2.opts();
8525
- if (opts.socket) return path40.resolve(opts.socket);
8549
+ if (opts.socket) return path41.resolve(opts.socket);
8526
8550
  c2 = c2.parent;
8527
8551
  }
8528
8552
  return vgdSocketPath();
@@ -8799,11 +8823,11 @@ function registerLlmHost(program) {
8799
8823
  applyGlobalOptions(cmd);
8800
8824
  }
8801
8825
  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) => {
8802
- const rootDir = path40.resolve(targetPath);
8803
- const vibgrateDir2 = path40.join(rootDir, ".vibgrate");
8826
+ const rootDir = path41.resolve(targetPath);
8827
+ const vibgrateDir2 = path41.join(rootDir, ".vibgrate");
8804
8828
  await ensureDir(vibgrateDir2);
8805
8829
  console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold(".vibgrate/")} directory`);
8806
- const configPath = path40.join(rootDir, "vibgrate.config.ts");
8830
+ const configPath = path41.join(rootDir, "vibgrate.config.ts");
8807
8831
  if (await pathExists(configPath)) {
8808
8832
  console.log(chalk7.dim(" vibgrate.config.ts already exists, skipping"));
8809
8833
  } else {
@@ -8811,7 +8835,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
8811
8835
  console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
8812
8836
  }
8813
8837
  if (opts.baseline) {
8814
- const { runBaseline } = await import('./baseline-LMGZURQF.js');
8838
+ const { runBaseline } = await import('./baseline-NM53X2TB.js');
8815
8839
  await runBaseline(rootDir);
8816
8840
  }
8817
8841
  console.log("");
@@ -8914,7 +8938,7 @@ function collectPackageImports(graph, ecosystem, pkg) {
8914
8938
  };
8915
8939
  }
8916
8940
  async function firstReferenceLine(rootDir, relFile, identifier, readFile3) {
8917
- const content = await readFile3(path40.join(rootDir, relFile));
8941
+ const content = await readFile3(path41.join(rootDir, relFile));
8918
8942
  if (!content) return null;
8919
8943
  const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8920
8944
  const re = new RegExp(`\\b${escaped}\\b`);
@@ -9150,7 +9174,7 @@ var AI_ASSISTANT_DETECTORS = [
9150
9174
  async function detectAiAssistant(rootDir) {
9151
9175
  for (const detector of AI_ASSISTANT_DETECTORS) {
9152
9176
  for (const file of detector.files) {
9153
- if (await pathExists$1(path40.join(rootDir, file))) {
9177
+ if (await pathExists$1(path41.join(rootDir, file))) {
9154
9178
  return detector.name;
9155
9179
  }
9156
9180
  }
@@ -9344,7 +9368,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
9344
9368
  collectExcludes,
9345
9369
  []
9346
9370
  ).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) => {
9347
- const rootDir = path40.resolve(targetPath);
9371
+ const rootDir = path41.resolve(targetPath);
9348
9372
  if (!await pathExists$1(rootDir)) {
9349
9373
  console.error(chalk7.red(`Path does not exist: ${rootDir}`));
9350
9374
  process.exit(1);
@@ -9352,7 +9376,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
9352
9376
  const hasDsn = !!resolveDsn(opts.dsn);
9353
9377
  const willPush = !opts.offline && (opts.push || hasDsn);
9354
9378
  const noLocalArtifacts = opts.localArtifacts === false;
9355
- const isFirstRun = !await pathExists$1(path40.join(rootDir, ".vibgrate", "scan_result.json"));
9379
+ const isFirstRun = !await pathExists$1(path41.join(rootDir, ".vibgrate", "scan_result.json"));
9356
9380
  let pinnedRegion;
9357
9381
  let planTier;
9358
9382
  let upgradeUrl;
@@ -9631,11 +9655,11 @@ function scanStaleness(rootDir, artifactPath) {
9631
9655
  scanned++;
9632
9656
  if (scanned > MAX_ENTRIES2) break;
9633
9657
  if (e.isDirectory()) {
9634
- if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(path40.join(dir, e.name), depth + 1);
9658
+ if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(path41.join(dir, e.name), depth + 1);
9635
9659
  continue;
9636
9660
  }
9637
9661
  if (!WATCHED_FILES.has(e.name) && !WATCHED_EXT.test(e.name)) continue;
9638
- const abs = path40.join(dir, e.name);
9662
+ const abs = path41.join(dir, e.name);
9639
9663
  let mtimeMs;
9640
9664
  try {
9641
9665
  mtimeMs = fs11.statSync(abs).mtimeMs;
@@ -9644,7 +9668,7 @@ function scanStaleness(rootDir, artifactPath) {
9644
9668
  }
9645
9669
  if (mtimeMs > newest) {
9646
9670
  newest = mtimeMs;
9647
- newestChanged = path40.relative(rootDir, abs) || e.name;
9671
+ newestChanged = path41.relative(rootDir, abs) || e.name;
9648
9672
  }
9649
9673
  }
9650
9674
  };
@@ -9784,13 +9808,13 @@ function analyzeTree(root2, packages) {
9784
9808
  if (filesSeen >= MAX_FILES) return;
9785
9809
  if (entry.isDirectory()) {
9786
9810
  if (SKIP_DIRS3.has(entry.name) || entry.name.startsWith(".")) continue;
9787
- walk2(path40.join(dir, entry.name), depth + 1);
9811
+ walk2(path41.join(dir, entry.name), depth + 1);
9788
9812
  continue;
9789
9813
  }
9790
- const fileEco = EXT_ECOSYSTEM[path40.extname(entry.name)];
9814
+ const fileEco = EXT_ECOSYSTEM[path41.extname(entry.name)];
9791
9815
  if (!fileEco || fileEco === "unknown") continue;
9792
9816
  filesSeen++;
9793
- const full = path40.join(dir, entry.name);
9817
+ const full = path41.join(dir, entry.name);
9794
9818
  let content;
9795
9819
  try {
9796
9820
  if (fs11.statSync(full).size > MAX_FILE_BYTES2) continue;
@@ -10105,7 +10129,7 @@ function applyPlan(rootDir, upgrades, opts = {}) {
10105
10129
  }
10106
10130
  const outcomes = effective.map((t) => {
10107
10131
  const c2 = pmCommandFor(u.ecosystem, u.package, u.to, opts.packageManager, { workspaceRoot: t.isWorkspaceRoot });
10108
- return { t, res: run(c2, path40.join(rootDir, t.dir)) };
10132
+ return { t, res: run(c2, path41.join(rootDir, t.dir)) };
10109
10133
  });
10110
10134
  const failures = outcomes.filter((o) => !o.res.ok);
10111
10135
  if (failures.length === 0) {
@@ -10134,8 +10158,8 @@ function applyPlan(rootDir, upgrades, opts = {}) {
10134
10158
  return results;
10135
10159
  }
10136
10160
  var REGISTRY_URL = "https://registry.npmjs.org/@vibgrate%2fcli/latest";
10137
- var CACHE_DIR = path40.join(os.homedir(), ".vibgrate");
10138
- var CACHE_FILE = path40.join(CACHE_DIR, "update-check.json");
10161
+ var CACHE_DIR = path41.join(os.homedir(), ".vibgrate");
10162
+ var CACHE_FILE = path41.join(CACHE_DIR, "update-check.json");
10139
10163
  async function fetchLatestVersion() {
10140
10164
  try {
10141
10165
  const controller = new AbortController();
@@ -10167,6 +10191,52 @@ async function writeCache(data) {
10167
10191
  } catch {
10168
10192
  }
10169
10193
  }
10194
+ var LOCK_ERROR_RE = /\b(EBUSY|EPERM|ETXTBSY|EACCES)\b|resource busy or locked|being used by another process|access is denied/i;
10195
+ function isFileLockError(output) {
10196
+ return LOCK_ERROR_RE.test(output);
10197
+ }
10198
+ function buildDeferredUpdateScript(opts) {
10199
+ const waitSeconds = opts.waitSeconds ?? 120;
10200
+ return [
10201
+ "@echo off",
10202
+ "setlocal",
10203
+ `set "VG_PID=${opts.pid}"`,
10204
+ `set "VG_LOG=${opts.logPath}"`,
10205
+ 'echo Waiting for vg (pid %VG_PID%) to exit so its locked files can be replaced...> "%VG_LOG%"',
10206
+ `for /l %%i in (1,1,${waitSeconds}) do (`,
10207
+ ' tasklist /FI "PID eq %VG_PID%" /NH 2>nul | find "%VG_PID%" >nul || goto :run',
10208
+ " ping -n 2 127.0.0.1 >nul",
10209
+ ")",
10210
+ ":run",
10211
+ `echo Running: ${opts.command}>> "%VG_LOG%"`,
10212
+ `call ${opts.command} >> "%VG_LOG%" 2>&1`,
10213
+ "if errorlevel 1 (",
10214
+ ' echo.>> "%VG_LOG%"',
10215
+ ' echo Update FAILED. See the npm output above.>> "%VG_LOG%"',
10216
+ ") else (",
10217
+ ' echo.>> "%VG_LOG%"',
10218
+ ' echo Update complete.>> "%VG_LOG%"',
10219
+ ")",
10220
+ ""
10221
+ ].join("\r\n");
10222
+ }
10223
+ function scheduleDeferredUpdate(command, pid = process.pid, dir = os.tmpdir()) {
10224
+ const stamp = `${pid}-${process.hrtime.bigint().toString(36)}`;
10225
+ const scriptPath = path41.join(dir, `vg-update-${stamp}.cmd`);
10226
+ const logPath = path41.join(dir, `vg-update-${stamp}.log`);
10227
+ try {
10228
+ fs11.writeFileSync(scriptPath, buildDeferredUpdateScript({ pid, command, logPath }), "utf8");
10229
+ const child = spawn(process.env.ComSpec || "cmd.exe", ["/d", "/s", "/c", scriptPath], {
10230
+ detached: true,
10231
+ stdio: "ignore",
10232
+ windowsHide: true
10233
+ });
10234
+ child.unref();
10235
+ return { scriptPath, logPath };
10236
+ } catch {
10237
+ return null;
10238
+ }
10239
+ }
10170
10240
 
10171
10241
  // src/reporting/commands/update.ts
10172
10242
  var PACKAGE_NAME = "@vibgrate/cli";
@@ -10208,14 +10278,14 @@ async function findGlobalInstall(pkg = PACKAGE_NAME, run = defaultRunner) {
10208
10278
  pm: "yarn",
10209
10279
  root: () => {
10210
10280
  const dir = tryRun("yarn global dir");
10211
- return dir ? path40.join(dir, "node_modules") : null;
10281
+ return dir ? path41.join(dir, "node_modules") : null;
10212
10282
  }
10213
10283
  },
10214
- { pm: "bun", root: () => path40.join(os.homedir(), ".bun", "install", "global", "node_modules") }
10284
+ { pm: "bun", root: () => path41.join(os.homedir(), ".bun", "install", "global", "node_modules") }
10215
10285
  ];
10216
10286
  for (const probe of probes) {
10217
10287
  const root2 = probe.root();
10218
- if (root2 && await pathExists(path40.join(root2, pkg))) return probe.pm;
10288
+ if (root2 && await pathExists(path41.join(root2, pkg))) return probe.pm;
10219
10289
  }
10220
10290
  return null;
10221
10291
  }
@@ -10234,15 +10304,15 @@ function getGlobalUpdateCommand(pm, pkg, version) {
10234
10304
  }
10235
10305
  }
10236
10306
  async function detectPackageManager(cwd) {
10237
- if (await pathExists(path40.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
10238
- if (await pathExists(path40.join(cwd, "bun.lockb"))) return "bun";
10239
- if (await pathExists(path40.join(cwd, "yarn.lock"))) return "yarn";
10307
+ if (await pathExists(path41.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
10308
+ if (await pathExists(path41.join(cwd, "bun.lockb"))) return "bun";
10309
+ if (await pathExists(path41.join(cwd, "yarn.lock"))) return "yarn";
10240
10310
  return "npm";
10241
10311
  }
10242
10312
  async function detectWorkspaceRoot(cwd) {
10243
- if (await pathExists(path40.join(cwd, "pnpm-workspace.yaml"))) return true;
10313
+ if (await pathExists(path41.join(cwd, "pnpm-workspace.yaml"))) return true;
10244
10314
  try {
10245
- const pkgPath = path40.join(cwd, "package.json");
10315
+ const pkgPath = path41.join(cwd, "package.json");
10246
10316
  const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
10247
10317
  const pkg = JSON.parse(raw);
10248
10318
  return pkg.workspaces != null;
@@ -10269,7 +10339,7 @@ function getInstallCommand(pm, pkg, version, isDev, opts = {}) {
10269
10339
  }
10270
10340
  async function getLocalDependencyState(cwd, pkg = PACKAGE_NAME) {
10271
10341
  try {
10272
- const pkgPath = path40.join(cwd, "package.json");
10342
+ const pkgPath = path41.join(cwd, "package.json");
10273
10343
  const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
10274
10344
  const parsed = JSON.parse(raw);
10275
10345
  if (parsed.devDependencies?.[pkg]) return "dev";
@@ -10279,16 +10349,84 @@ async function getLocalDependencyState(cwd, pkg = PACKAGE_NAME) {
10279
10349
  return null;
10280
10350
  }
10281
10351
  async function confirmWorkspaceRoot(pm) {
10352
+ return confirm3(`Update the ${pm} workspace root with -w? [y/N]: `);
10353
+ }
10354
+ async function confirm3(question) {
10282
10355
  if (!(process.stdin.isTTY && process.stdout.isTTY)) return false;
10283
10356
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
10284
10357
  return new Promise((resolve21) => {
10285
- rl.question(chalk7.yellow(`Update the ${pm} workspace root with -w? [y/N]: `), (ans) => {
10358
+ rl.question(chalk7.yellow(question), (ans) => {
10286
10359
  rl.close();
10287
10360
  const t = ans.trim().toLowerCase();
10288
10361
  resolve21(t === "y" || t === "yes");
10289
10362
  });
10290
10363
  });
10291
10364
  }
10365
+ var CAPTURED_OUTPUT_LIMIT = 64e3;
10366
+ async function runInstall(cmd, cwd) {
10367
+ const { spawn: spawn5 } = await import('child_process');
10368
+ return new Promise((resolve21) => {
10369
+ const child = spawn5(cmd, { cwd, shell: true, stdio: ["inherit", "pipe", "pipe"] });
10370
+ let output = "";
10371
+ const tee = (src, dest) => {
10372
+ if (!src) return;
10373
+ src.setEncoding("utf8");
10374
+ src.on("data", (chunk) => {
10375
+ dest.write(chunk);
10376
+ output += chunk;
10377
+ if (output.length > CAPTURED_OUTPUT_LIMIT) output = output.slice(-CAPTURED_OUTPUT_LIMIT);
10378
+ });
10379
+ };
10380
+ tee(child.stdout, process.stdout);
10381
+ tee(child.stderr, process.stderr);
10382
+ child.on("error", (err) => resolve21({ ok: false, output: `${output}
10383
+ ${String(err)}` }));
10384
+ child.on("close", (code) => resolve21({ ok: code === 0, output }));
10385
+ });
10386
+ }
10387
+ async function releaseWindowsFileLocks(cwd, keepVersion) {
10388
+ reapAndReport(cwd, keepVersion);
10389
+ try {
10390
+ const { vgdSocketPath: vgdSocketPath2 } = await import('./vgd-YFPJHQB5.js');
10391
+ const result = await stopVgd(vgdSocketPath2());
10392
+ if (result === "stopped") {
10393
+ console.log(chalk7.dim("Stopped the vgd daemon so its files can be replaced \u2014 it restarts on the next command."));
10394
+ } else if (result === "refused") {
10395
+ console.log(
10396
+ chalk7.dim(
10397
+ "A vgd embedded in another process (e.g. vg code) is running \u2014 close that session if the update reports a locked file."
10398
+ )
10399
+ );
10400
+ }
10401
+ } catch {
10402
+ }
10403
+ }
10404
+ async function offerDeferredWindowsUpdate(cmd, assumeYes) {
10405
+ console.error(
10406
+ chalk7.yellow("\nWindows could not replace a file that is still in use.") + chalk7.dim(
10407
+ "\nThis is the self-update case: vg loads native modules (.node), and Windows locks them\nfor as long as a process has them open \u2014 including this one. Re-running the same\ncommand by hand hits the identical lock."
10408
+ )
10409
+ );
10410
+ const proceed = assumeYes || await confirm3("Finish the update automatically after vg exits? [y/N]: ");
10411
+ if (!proceed) {
10412
+ console.error(
10413
+ chalk7.dim(
10414
+ "Skipped. To update manually, close every terminal and editor running vg (including\nMCP servers started by your AI client), then run:\n " + cmd
10415
+ )
10416
+ );
10417
+ return false;
10418
+ }
10419
+ const scheduled = scheduleDeferredUpdate(cmd);
10420
+ if (!scheduled) {
10421
+ console.error(chalk7.red(`Could not schedule the deferred update. Run manually once vg is closed: ${cmd}`));
10422
+ return false;
10423
+ }
10424
+ console.log(
10425
+ chalk7.green("\u2714") + " Update scheduled \u2014 it runs as soon as this process exits.\n" + chalk7.dim(` Transcript: ${scheduled.logPath}
10426
+ `) + chalk7.dim(' Check the new version with "vg --version" in a few seconds.')
10427
+ );
10428
+ return true;
10429
+ }
10292
10430
  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)").option("--no-reap", "Do not signal running vg serve processes on an older version to restart").action(
10293
10431
  async (opts) => {
10294
10432
  console.log(chalk7.dim(`Current version: ${VERSION}`));
@@ -10350,10 +10488,16 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
10350
10488
  cmd = getInstallCommand(pm, PACKAGE_NAME, latest, isDev, { workspaceRoot });
10351
10489
  console.log(chalk7.dim(`Using ${pm}: ${cmd}`));
10352
10490
  }
10353
- try {
10354
- execSync(cmd, { cwd, stdio: "inherit" });
10491
+ if (process.platform === "win32" && isGlobal && opts.reap !== false) {
10492
+ await releaseWindowsFileLocks(cwd, latest);
10493
+ }
10494
+ const install = await runInstall(cmd, cwd);
10495
+ if (install.ok) {
10355
10496
  console.log(chalk7.green("\u2714") + ` Updated to ${PACKAGE_NAME}@${latest}`);
10356
- } catch {
10497
+ } else if (process.platform === "win32" && isFileLockError(install.output)) {
10498
+ const scheduled = await offerDeferredWindowsUpdate(cmd, Boolean(opts.yes));
10499
+ process.exit(scheduled ? 0 : 1);
10500
+ } else {
10357
10501
  console.error(chalk7.red(`Update failed. Run manually: ${cmd}`));
10358
10502
  process.exit(1);
10359
10503
  }
@@ -10368,7 +10512,7 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
10368
10512
  );
10369
10513
  async function rewarmVgdAndReport(cwd) {
10370
10514
  try {
10371
- const { vgdIsRunning: vgdIsRunning2, vgdRequest: vgdRequest2 } = await import('./vgd-FXIEZZT2.js');
10515
+ const { vgdIsRunning: vgdIsRunning2, vgdRequest: vgdRequest2 } = await import('./vgd-YFPJHQB5.js');
10372
10516
  if (!await vgdIsRunning2()) return;
10373
10517
  const loaded = await vgdRequest2({ op: "load-graph", root: cwd });
10374
10518
  if (!loaded.ok || !("repositoryId" in loaded)) return;
@@ -10457,13 +10601,13 @@ function collectCandidates(artifact) {
10457
10601
  return out2;
10458
10602
  }
10459
10603
  var defaultFixScanner = async (rootDir) => {
10460
- const scratch = path40.join(os.tmpdir(), `vg-fix-scan-${process.pid}.json`);
10604
+ const scratch = path41.join(os.tmpdir(), `vg-fix-scan-${process.pid}.json`);
10461
10605
  const scanOpts = { vibgrateVersion: VERSION, format: "json", out: scratch, quiet: true, concurrency: 8 };
10462
10606
  const advanced = await loadAdvancedScanHook();
10463
10607
  return runCoreScan(rootDir, scanOpts, advanced);
10464
10608
  };
10465
10609
  async function loadArtifact(rootDir, inFile, scan = defaultFixScanner) {
10466
- const artifactPath = path40.isAbsolute(inFile) ? inFile : path40.join(rootDir, inFile);
10610
+ const artifactPath = path41.isAbsolute(inFile) ? inFile : path41.join(rootDir, inFile);
10467
10611
  if (await pathExists(artifactPath)) {
10468
10612
  const staleness = scanStaleness(rootDir, artifactPath);
10469
10613
  if (!staleness.stale) {
@@ -10490,7 +10634,7 @@ async function repositoryIdentity(rootDir, override) {
10490
10634
  }
10491
10635
  }
10492
10636
  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) => {
10493
- const rootDir = path40.resolve(targetPath);
10637
+ const rootDir = path41.resolve(targetPath);
10494
10638
  if (!await pathExists(rootDir)) {
10495
10639
  console.error(chalk7.red(`Path does not exist: ${rootDir}`));
10496
10640
  process.exit(1);
@@ -10651,7 +10795,7 @@ function emit(report, format) {
10651
10795
  }
10652
10796
  }
10653
10797
  function relProjectDir(rootDir, projectPath) {
10654
- const rel = path40.isAbsolute(projectPath) ? path40.relative(rootDir, projectPath) : projectPath;
10798
+ const rel = path41.isAbsolute(projectPath) ? path41.relative(rootDir, projectPath) : projectPath;
10655
10799
  return rel === "" ? "." : rel;
10656
10800
  }
10657
10801
  async function buildTargetResolver(rootDir, artifact) {
@@ -11486,7 +11630,7 @@ function formatMarkdown(artifact) {
11486
11630
 
11487
11631
  // src/reporting/commands/report.ts
11488
11632
  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) => {
11489
- const artifactPath = path40.resolve(opts.in);
11633
+ const artifactPath = path41.resolve(opts.in);
11490
11634
  if (!await pathExists(artifactPath)) {
11491
11635
  console.error(chalk7.red(`Artifact not found: ${artifactPath}`));
11492
11636
  console.error(chalk7.dim('Run "vibgrate scan" first to generate a scan artifact.'));
@@ -11535,8 +11679,8 @@ function openUrl(url) {
11535
11679
  // src/reporting/commands/login.ts
11536
11680
  var delay = (ms) => new Promise((resolve21) => setTimeout(resolve21, ms));
11537
11681
  function isInside(dir, file) {
11538
- const rel = path40.relative(dir, file);
11539
- return !!rel && !rel.startsWith("..") && !path40.isAbsolute(rel);
11682
+ const rel = path41.relative(dir, file);
11683
+ return !!rel && !rel.startsWith("..") && !path41.isAbsolute(rel);
11540
11684
  }
11541
11685
  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(
11542
11686
  "--local",
@@ -11791,7 +11935,7 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
11791
11935
  try {
11792
11936
  const statements = [];
11793
11937
  if (opts.from) {
11794
- const fromPath = path40.resolve(opts.from);
11938
+ const fromPath = path41.resolve(opts.from);
11795
11939
  if (!await pathExists(fromPath)) {
11796
11940
  process.stderr.write(chalk7.red(`Statements file not found: ${fromPath}
11797
11941
  `));
@@ -11809,9 +11953,9 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
11809
11953
  });
11810
11954
  const json2 = JSON.stringify(doc, null, 2);
11811
11955
  if (opts.out) {
11812
- await writeTextFile(path40.resolve(opts.out), json2 + "\n");
11956
+ await writeTextFile(path41.resolve(opts.out), json2 + "\n");
11813
11957
  process.stderr.write(
11814
- chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${path40.resolve(opts.out)}
11958
+ chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${path41.resolve(opts.out)}
11815
11959
  `
11816
11960
  );
11817
11961
  } else {
@@ -11994,7 +12138,7 @@ function formatDeltaText(base, current) {
11994
12138
  return lines.join("\n");
11995
12139
  }
11996
12140
  async function readArtifactOrExit(filePath) {
11997
- const absolutePath = path40.resolve(filePath);
12141
+ const absolutePath = path41.resolve(filePath);
11998
12142
  if (!await pathExists(absolutePath)) {
11999
12143
  console.error(chalk7.red(`Artifact not found: ${absolutePath}`));
12000
12144
  process.exit(1);
@@ -12011,7 +12155,7 @@ var exportCommand = new Command("export").description("Export scan artifact as S
12011
12155
  const sbom = format === "cyclonedx" ? toCycloneDx(artifact) : toSpdx(artifact);
12012
12156
  const body = JSON.stringify(sbom, null, 2);
12013
12157
  if (opts.out) {
12014
- await writeTextFile(path40.resolve(opts.out), body);
12158
+ await writeTextFile(path41.resolve(opts.out), body);
12015
12159
  console.log(chalk7.green("\u2714") + ` SBOM written to ${opts.out}`);
12016
12160
  } else {
12017
12161
  console.log(body);
@@ -12022,7 +12166,7 @@ var deltaCommand = new Command("delta").description("Show SBOM delta between two
12022
12166
  const current = await readArtifactOrExit(opts.to);
12023
12167
  const report = formatDeltaText(base, current);
12024
12168
  if (opts.out) {
12025
- await writeTextFile(path40.resolve(opts.out), report);
12169
+ await writeTextFile(path41.resolve(opts.out), report);
12026
12170
  console.log(chalk7.green("\u2714") + ` SBOM delta report written to ${opts.out}`);
12027
12171
  } else {
12028
12172
  console.log(report);
@@ -12153,20 +12297,20 @@ function resolveRegime(id) {
12153
12297
  return regime;
12154
12298
  }
12155
12299
  function evidenceDir(root2) {
12156
- return path40.join(root2, ".vibgrate", "evidence");
12300
+ return path41.join(root2, ".vibgrate", "evidence");
12157
12301
  }
12158
12302
  function orgPath(root2) {
12159
- return path40.join(evidenceDir(root2), "org.json");
12303
+ return path41.join(evidenceDir(root2), "org.json");
12160
12304
  }
12161
12305
  function productsPath(root2) {
12162
- return path40.join(evidenceDir(root2), "products.json");
12306
+ return path41.join(evidenceDir(root2), "products.json");
12163
12307
  }
12164
12308
  function releasesDir(root2) {
12165
- return path40.join(evidenceDir(root2), "releases");
12309
+ return path41.join(evidenceDir(root2), "releases");
12166
12310
  }
12167
12311
  function releasePath(root2, productId, version) {
12168
12312
  const safe = `${productId}@${version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
12169
- return path40.join(releasesDir(root2), `${safe}.json`);
12313
+ return path41.join(releasesDir(root2), `${safe}.json`);
12170
12314
  }
12171
12315
  var DEFAULT_ORG = {
12172
12316
  responsiblePersons: [],
@@ -12197,7 +12341,7 @@ async function freezeRelease(root2, release) {
12197
12341
  const p = releasePath(root2, release.productId, release.version);
12198
12342
  if (await pathExists(p)) {
12199
12343
  throw new CliError(
12200
- `release ${release.productId}@${release.version} is already frozen and manifests are immutable \u2014 delete ${path40.relative(root2, p)} only if it was frozen in error`,
12344
+ `release ${release.productId}@${release.version} is already frozen and manifests are immutable \u2014 delete ${path41.relative(root2, p)} only if it was frozen in error`,
12201
12345
  ExitCode.USAGE_ERROR
12202
12346
  );
12203
12347
  }
@@ -12211,7 +12355,7 @@ async function loadReleases(root2, productId) {
12211
12355
  const files = (await readdir(dir)).filter((f) => f.endsWith(".json")).sort();
12212
12356
  const releases = [];
12213
12357
  for (const f of files) {
12214
- const rel = await readJsonFile(path40.join(dir, f));
12358
+ const rel = await readJsonFile(path41.join(dir, f));
12215
12359
  if (!productId || rel.productId === productId) releases.push(rel);
12216
12360
  }
12217
12361
  return releases;
@@ -12906,12 +13050,12 @@ function verifyEvidenceEnvelope(env, opts = {}) {
12906
13050
  var DEFAULT_KEY = "attest-key.pem";
12907
13051
  function resolveSigningKey(root2, explicit) {
12908
13052
  const chosen = process.env.VG_ATTEST_KEY;
12909
- const keyPath = chosen ? path40.resolve(chosen) : path40.join(root2, ".vibgrate", DEFAULT_KEY);
13053
+ const keyPath = chosen ? path41.resolve(chosen) : path41.join(root2, ".vibgrate", DEFAULT_KEY);
12910
13054
  let minted = false;
12911
13055
  if (!fs11.existsSync(keyPath)) {
12912
13056
  if (chosen) throw new CliError(`signing key not found: ${chosen}`, ExitCode.USAGE_ERROR);
12913
13057
  const kp = generateKeypair();
12914
- fs11.mkdirSync(path40.dirname(keyPath), { recursive: true });
13058
+ fs11.mkdirSync(path41.dirname(keyPath), { recursive: true });
12915
13059
  fs11.writeFileSync(keyPath, kp.privatePem, { mode: 384 });
12916
13060
  fs11.writeFileSync(`${keyPath}.pub`, kp.publicPem);
12917
13061
  minted = true;
@@ -12929,16 +13073,16 @@ function resolveSigningKey(root2, explicit) {
12929
13073
  }
12930
13074
  function writeBundle(input) {
12931
13075
  const dir = input.outDir;
12932
- fs11.mkdirSync(path40.join(dir, "inputs", "releases"), { recursive: true });
12933
- const write = (rel, data) => fs11.writeFileSync(path40.join(dir, rel), `${JSON.stringify(data, null, 2)}
13076
+ fs11.mkdirSync(path41.join(dir, "inputs", "releases"), { recursive: true });
13077
+ const write = (rel, data) => fs11.writeFileSync(path41.join(dir, rel), `${JSON.stringify(data, null, 2)}
12934
13078
  `);
12935
13079
  write("result.json", input.result);
12936
- write(path40.join("inputs", "advisory.json"), input.advisory);
13080
+ write(path41.join("inputs", "advisory.json"), input.advisory);
12937
13081
  for (const rel of input.releases) {
12938
13082
  const safe = `${rel.productId}@${rel.version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
12939
- write(path40.join("inputs", "releases", `${safe}.json`), rel);
13083
+ write(path41.join("inputs", "releases", `${safe}.json`), rel);
12940
13084
  }
12941
- write(path40.join("inputs", "datapack.lock"), { dataPackVersion: input.result.meta.dataPackVersion, kernelVersion: input.result.meta.kernelVersion });
13085
+ write(path41.join("inputs", "datapack.lock"), { dataPackVersion: input.result.meta.dataPackVersion, kernelVersion: input.result.meta.kernelVersion });
12942
13086
  write("provenance.json", {
12943
13087
  method: "deterministic",
12944
13088
  modelDrafted: [],
@@ -12954,13 +13098,13 @@ function writeBundle(input) {
12954
13098
  disclaimer: input.regime.disclaimer
12955
13099
  });
12956
13100
  if (input.envelope) {
12957
- fs11.writeFileSync(path40.join(dir, "evidence.intoto.jsonl"), `${JSON.stringify(input.envelope)}
13101
+ fs11.writeFileSync(path41.join(dir, "evidence.intoto.jsonl"), `${JSON.stringify(input.envelope)}
12958
13102
  `);
12959
13103
  }
12960
13104
  if (input.timestampToken) {
12961
- fs11.writeFileSync(path40.join(dir, "timestamp.tsr"), input.timestampToken);
13105
+ fs11.writeFileSync(path41.join(dir, "timestamp.tsr"), input.timestampToken);
12962
13106
  }
12963
- fs11.writeFileSync(path40.join(dir, "VERIFY.md"), verifyDoc(input));
13107
+ fs11.writeFileSync(path41.join(dir, "VERIFY.md"), verifyDoc(input));
12964
13108
  return dir;
12965
13109
  }
12966
13110
  function verifyDoc(input) {
@@ -13021,13 +13165,13 @@ function undeterminedFields(result, regime) {
13021
13165
  return gaps.filter((g) => regime.submission.requires.some((r) => g.startsWith(r)) || g.startsWith("exposure") || g.startsWith("member"));
13022
13166
  }
13023
13167
  async function recordDrill(root2, record) {
13024
- const dir = path40.join(evidenceDir(root2), "drills");
13025
- const p = path40.join(dir, `${record.drillId}.json`);
13168
+ const dir = path41.join(evidenceDir(root2), "drills");
13169
+ const p = path41.join(dir, `${record.drillId}.json`);
13026
13170
  await writeJsonFile(p, record);
13027
13171
  return p;
13028
13172
  }
13029
13173
  async function hasRecentDrill(root2, asOf) {
13030
- const dir = path40.join(evidenceDir(root2), "drills");
13174
+ const dir = path41.join(evidenceDir(root2), "drills");
13031
13175
  if (!await pathExists(dir)) return void 0;
13032
13176
  const { readdir } = await import('fs/promises');
13033
13177
  const { readJsonFile: readJsonFile2 } = await import('./fs-4G5A65KS.js');
@@ -13035,7 +13179,7 @@ async function hasRecentDrill(root2, asOf) {
13035
13179
  if (files.length === 0) return void 0;
13036
13180
  const cutoff = new Date(new Date(asOf).getTime() - 90 * 24 * 3600 * 1e3).toISOString();
13037
13181
  for (const f of files) {
13038
- const rec = await readJsonFile2(path40.join(dir, f));
13182
+ const rec = await readJsonFile2(path41.join(dir, f));
13039
13183
  if (rec.ranAt >= cutoff) return true;
13040
13184
  }
13041
13185
  return false;
@@ -13115,7 +13259,7 @@ function formatRegimeList() {
13115
13259
 
13116
13260
  // src/reporting/commands/evidence/index.ts
13117
13261
  function root(opts) {
13118
- return path40.resolve(opts.cwd ?? process.cwd());
13262
+ return path41.resolve(opts.cwd ?? process.cwd());
13119
13263
  }
13120
13264
  function slug(name) {
13121
13265
  return name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "product";
@@ -13203,7 +13347,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
13203
13347
  const release = await buildRelease({
13204
13348
  productId: product.id,
13205
13349
  version,
13206
- from: path40.resolve(rootDir, opts.from),
13350
+ from: path41.resolve(rootDir, opts.from),
13207
13351
  shipDate: opts.shipDate,
13208
13352
  buildId: opts.buildId,
13209
13353
  artefactDigest: opts.digest,
@@ -13211,7 +13355,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
13211
13355
  frozenAt: nowIso()
13212
13356
  });
13213
13357
  const p = await freezeRelease(rootDir, release);
13214
- console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${path40.relative(rootDir, p)}`);
13358
+ console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${path41.relative(rootDir, p)}`);
13215
13359
  });
13216
13360
  async function runExposure(rootDir, vuln, opts) {
13217
13361
  const org = await loadOrg(rootDir);
@@ -13263,7 +13407,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
13263
13407
  console.log("\n" + buildPack(result, regime, org, stage));
13264
13408
  }
13265
13409
  if (opts.bundle) {
13266
- const dir = path40.resolve(rootDir, opts.bundle, `evidence-${result.meta.evidenceId}`);
13410
+ const dir = path41.resolve(rootDir, opts.bundle, `evidence-${result.meta.evidenceId}`);
13267
13411
  let envelope;
13268
13412
  if (opts.sign !== false) {
13269
13413
  const { key: key2, minted } = resolveSigningKey(rootDir);
@@ -13271,7 +13415,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
13271
13415
  envelope = signEvidenceStatement(buildEvidenceStatement(result, VERSION), key2);
13272
13416
  }
13273
13417
  writeBundle({ outDir: dir, result, advisory, releases, regime, envelope, timestampToken, cliVersion: VERSION });
13274
- console.error(chalk7.green("\u2714") + ` evidence bundle written to ${path40.relative(rootDir, dir)}${envelope ? " (signed)" : " (unsigned)"}${timestampToken ? " \xB7 RFC 3161" : ""}`);
13418
+ console.error(chalk7.green("\u2714") + ` evidence bundle written to ${path41.relative(rootDir, dir)}${envelope ? " (signed)" : " (unsigned)"}${timestampToken ? " \xB7 RFC 3161" : ""}`);
13275
13419
  }
13276
13420
  process.exitCode = exposureExit(result.overallStatus);
13277
13421
  });
@@ -13303,7 +13447,7 @@ var packCmd = new Command("pack").description("Build the submission pack a human
13303
13447
  const stage = opts.stage ?? regime.clocks[0]?.stage ?? "early-warning";
13304
13448
  const md = buildPack(result, regime, org, stage);
13305
13449
  if (opts.out) {
13306
- fs11.writeFileSync(path40.resolve(rootDir, opts.out), md);
13450
+ fs11.writeFileSync(path41.resolve(rootDir, opts.out), md);
13307
13451
  console.error(chalk7.green("\u2714") + ` pack written to ${opts.out}`);
13308
13452
  } else {
13309
13453
  console.log(md);
@@ -13345,18 +13489,18 @@ var drillCmd = new Command("drill").description("Timed dry-run of the determinat
13345
13489
  }
13346
13490
  });
13347
13491
  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) => {
13348
- const abs = path40.resolve(bundlePath);
13349
- const envPath = fs11.statSync(abs).isDirectory() ? path40.join(abs, "evidence.intoto.jsonl") : abs;
13492
+ const abs = path41.resolve(bundlePath);
13493
+ const envPath = fs11.statSync(abs).isDirectory() ? path41.join(abs, "evidence.intoto.jsonl") : abs;
13350
13494
  if (!fs11.existsSync(envPath)) throw new CliError(`no evidence.intoto.jsonl at ${bundlePath}`, ExitCode.NOT_FOUND);
13351
13495
  const envelope = JSON.parse(fs11.readFileSync(envPath, "utf8").trim().split("\n")[0]);
13352
- const resultPath = path40.join(path40.dirname(envPath), "result.json");
13496
+ const resultPath = path41.join(path41.dirname(envPath), "result.json");
13353
13497
  const result = fs11.existsSync(resultPath) ? JSON.parse(fs11.readFileSync(resultPath, "utf8")) : void 0;
13354
- const publicKeyPem = opts.pub ? fs11.readFileSync(path40.resolve(opts.pub), "utf8") : void 0;
13498
+ const publicKeyPem = opts.pub ? fs11.readFileSync(path41.resolve(opts.pub), "utf8") : void 0;
13355
13499
  const v = verifyEvidenceEnvelope(envelope, { publicKeyPem, result });
13356
13500
  const color = v.status === "verified" ? chalk7.green : v.status === "failed" ? chalk7.red : chalk7.yellow;
13357
13501
  console.log(" " + color(v.status.toUpperCase()) + ` ${v.reason}`);
13358
13502
  if (v.evidenceId) console.log(" " + chalk7.dim(`evidence ${v.evidenceId} \xB7 regime ${v.regime} \xB7 advisory ${v.advisoryId} \xB7 ${v.overallStatus}`));
13359
- const tsrPath = path40.join(path40.dirname(envPath), "timestamp.tsr");
13503
+ const tsrPath = path41.join(path41.dirname(envPath), "timestamp.tsr");
13360
13504
  if (fs11.existsSync(tsrPath) && result) {
13361
13505
  const t = verifyTimestamp(fs11.readFileSync(tsrPath), exposureSubjectDigest(result));
13362
13506
  const tcolor = t.imprintMatches ? chalk7.green : chalk7.red;
@@ -13425,12 +13569,12 @@ var exportCmd = new Command("export").description("Air-gap bundle of all evidenc
13425
13569
  const releases = [];
13426
13570
  for (const list of releasesByProduct.values()) releases.push(...list);
13427
13571
  const report = computeReadiness({ regime, org, products, releasesByProduct, recentDrill: await hasRecentDrill(rootDir, today()) });
13428
- const dir = path40.resolve(rootDir, opts.out);
13429
- await writeJsonFile(path40.join(dir, "org.json"), org);
13430
- await writeJsonFile(path40.join(dir, "products.json"), products);
13431
- for (const r of releases) await writeJsonFile(path40.join(dir, "releases", `${r.productId}@${r.version}.json`.replace(/[^A-Za-z0-9._@-]/g, "_")), r);
13432
- await writeJsonFile(path40.join(dir, "readiness.json"), report);
13433
- console.error(chalk7.green("\u2714") + ` exported evidence state to ${path40.relative(rootDir, dir)} (${products.length} products, ${releases.length} frozen releases)`);
13572
+ const dir = path41.resolve(rootDir, opts.out);
13573
+ await writeJsonFile(path41.join(dir, "org.json"), org);
13574
+ await writeJsonFile(path41.join(dir, "products.json"), products);
13575
+ for (const r of releases) await writeJsonFile(path41.join(dir, "releases", `${r.productId}@${r.version}.json`.replace(/[^A-Za-z0-9._@-]/g, "_")), r);
13576
+ await writeJsonFile(path41.join(dir, "readiness.json"), report);
13577
+ console.error(chalk7.green("\u2714") + ` exported evidence state to ${path41.relative(rootDir, dir)} (${products.length} products, ${releases.length} frozen releases)`);
13434
13578
  });
13435
13579
  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) => {
13436
13580
  const rootDir = root(opts);
@@ -13456,8 +13600,8 @@ var pushCmd = new Command("push").description("Push the product registry (and an
13456
13600
  }));
13457
13601
  let exposure;
13458
13602
  if (opts.result) {
13459
- const raw = path40.resolve(rootDir, opts.result);
13460
- const resultPath = fs11.existsSync(raw) && fs11.statSync(raw).isDirectory() ? path40.join(raw, "result.json") : raw;
13603
+ const raw = path41.resolve(rootDir, opts.result);
13604
+ const resultPath = fs11.existsSync(raw) && fs11.statSync(raw).isDirectory() ? path41.join(raw, "result.json") : raw;
13461
13605
  if (!fs11.existsSync(resultPath)) throw new CliError(`no result.json at ${opts.result}`, ExitCode.NOT_FOUND);
13462
13606
  exposure = JSON.parse(fs11.readFileSync(resultPath, "utf8"));
13463
13607
  }
@@ -13653,7 +13797,7 @@ function dispatch(argv, cwd) {
13653
13797
  }
13654
13798
  const looksLikeQuestion = /\s/.test(first) || first.endsWith("?");
13655
13799
  if (looksLikeQuestion) return ["ask", ...args];
13656
- if (fs11.existsSync(path40.resolve(cwd, first))) {
13800
+ if (fs11.existsSync(path41.resolve(cwd, first))) {
13657
13801
  return [hasBuildOnlyFlag(args) ? "build" : "scan", ...args];
13658
13802
  }
13659
13803
  const moved = MOVED_COMMANDS[first];
@@ -13698,9 +13842,9 @@ async function main(argv = process.argv) {
13698
13842
  }
13699
13843
  function readCwd(raw) {
13700
13844
  const i = raw.findIndex((a) => a === "-C" || a === "--cwd");
13701
- if (i >= 0 && raw[i + 1]) return path40.resolve(raw[i + 1]);
13845
+ if (i >= 0 && raw[i + 1]) return path41.resolve(raw[i + 1]);
13702
13846
  const eq = raw.find((a) => a.startsWith("--cwd="));
13703
- if (eq) return path40.resolve(eq.slice("--cwd=".length));
13847
+ if (eq) return path41.resolve(eq.slice("--cwd=".length));
13704
13848
  return process.cwd();
13705
13849
  }
13706
13850
  function handleError(err) {