@vibgrate/cli 2026.805.2 → 2026.806.2

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 (84) hide show
  1. package/DOCS.md +11 -5
  2. package/dist/{agent-PFYXJWWP.js → agent-DSC3EQLT.js} +11 -11
  3. package/dist/{agent-PFYXJWWP.js.map → agent-DSC3EQLT.js.map} +1 -1
  4. package/dist/{baseline-7C4F7PBS.js → baseline-KVCXVZFQ.js} +3 -3
  5. package/dist/{baseline-7C4F7PBS.js.map → baseline-KVCXVZFQ.js.map} +1 -1
  6. package/dist/{chunk-PPXAN2X5.js → chunk-455ZJQQ4.js} +5 -5
  7. package/dist/{chunk-PPXAN2X5.js.map → chunk-455ZJQQ4.js.map} +1 -1
  8. package/dist/{chunk-MDQO4ACI.js → chunk-6L6V77HW.js} +8 -8
  9. package/dist/{chunk-MDQO4ACI.js.map → chunk-6L6V77HW.js.map} +1 -1
  10. package/dist/{chunk-L5O6W5EB.js → chunk-6XKDAYYR.js} +4 -4
  11. package/dist/{chunk-L5O6W5EB.js.map → chunk-6XKDAYYR.js.map} +1 -1
  12. package/dist/{chunk-4IAKFZVG.js → chunk-7C5UKIXD.js} +4 -4
  13. package/dist/{chunk-4IAKFZVG.js.map → chunk-7C5UKIXD.js.map} +1 -1
  14. package/dist/{chunk-EEZ5HCL2.js → chunk-CBPDYYIH.js} +4 -4
  15. package/dist/{chunk-EEZ5HCL2.js.map → chunk-CBPDYYIH.js.map} +1 -1
  16. package/dist/{chunk-OAMAINC6.js → chunk-D2VEJHPC.js} +7 -7
  17. package/dist/{chunk-OAMAINC6.js.map → chunk-D2VEJHPC.js.map} +1 -1
  18. package/dist/{chunk-PZEJ4LHP.js → chunk-EW2ZMFUC.js} +4 -4
  19. package/dist/{chunk-PZEJ4LHP.js.map → chunk-EW2ZMFUC.js.map} +1 -1
  20. package/dist/{chunk-TFGUYBNC.js → chunk-HV4CKBXT.js} +3 -3
  21. package/dist/{chunk-TFGUYBNC.js.map → chunk-HV4CKBXT.js.map} +1 -1
  22. package/dist/{chunk-P64OTAUL.js → chunk-I2JNLAKW.js} +1295 -61
  23. package/dist/chunk-I2JNLAKW.js.map +1 -0
  24. package/dist/{chunk-ABJVJUKB.js → chunk-IQJUFRZZ.js} +35 -17
  25. package/dist/{chunk-ABJVJUKB.js.map → chunk-IQJUFRZZ.js.map} +1 -1
  26. package/dist/chunk-K6MLOGU4.js +6 -0
  27. package/dist/{chunk-54USY7IT.js.map → chunk-K6MLOGU4.js.map} +1 -1
  28. package/dist/{chunk-63QGVU4A.js → chunk-KAOSPAFK.js} +5 -5
  29. package/dist/{chunk-63QGVU4A.js.map → chunk-KAOSPAFK.js.map} +1 -1
  30. package/dist/{chunk-LEESW7CF.js → chunk-KYRH3567.js} +32 -12
  31. package/dist/chunk-KYRH3567.js.map +1 -0
  32. package/dist/{chunk-TPWMFEIA.js → chunk-QDKFGLI3.js} +6 -6
  33. package/dist/{chunk-TPWMFEIA.js.map → chunk-QDKFGLI3.js.map} +1 -1
  34. package/dist/{chunk-ZY6XAHLH.js → chunk-RL6MHAOK.js} +4 -4
  35. package/dist/{chunk-ZY6XAHLH.js.map → chunk-RL6MHAOK.js.map} +1 -1
  36. package/dist/{chunk-VETQRKXJ.js → chunk-SBVZGEOB.js} +3 -3
  37. package/dist/{chunk-VETQRKXJ.js.map → chunk-SBVZGEOB.js.map} +1 -1
  38. package/dist/{chunk-2U4SXS5U.js → chunk-SI4D7DYF.js} +13 -4
  39. package/dist/chunk-SI4D7DYF.js.map +1 -0
  40. package/dist/{chunk-TWSUMNKS.js → chunk-TOVVTZTM.js} +3 -3
  41. package/dist/{chunk-TWSUMNKS.js.map → chunk-TOVVTZTM.js.map} +1 -1
  42. package/dist/{chunk-3LDQD53S.js → chunk-VTJAPNJO.js} +4 -4
  43. package/dist/{chunk-3LDQD53S.js.map → chunk-VTJAPNJO.js.map} +1 -1
  44. package/dist/{chunk-ZXQP2GQE.js → chunk-ZMSTSEGR.js} +3 -3
  45. package/dist/{chunk-ZXQP2GQE.js.map → chunk-ZMSTSEGR.js.map} +1 -1
  46. package/dist/{chunk-TAV6XEFK.js → chunk-ZPPDKHGL.js} +65 -9
  47. package/dist/chunk-ZPPDKHGL.js.map +1 -0
  48. package/dist/cli.js +406 -244
  49. package/dist/cli.js.map +1 -1
  50. package/dist/embed-worker-main.js +3 -3
  51. package/dist/{ensure-map-7L3TPCGA.js → ensure-map-5E5TFPXJ.js} +12 -12
  52. package/dist/{ensure-map-7L3TPCGA.js.map → ensure-map-5E5TFPXJ.js.map} +1 -1
  53. package/dist/graph-backend-GQZXMNRI.js +13 -0
  54. package/dist/{graph-backend-5AMGXUDF.js.map → graph-backend-GQZXMNRI.js.map} +1 -1
  55. package/dist/index.d.ts +10 -3
  56. package/dist/index.js +11 -11
  57. package/dist/{interactive-5NXJTODL.js → interactive-7EZHEBHQ.js} +24 -22
  58. package/dist/interactive-7EZHEBHQ.js.map +1 -0
  59. package/dist/load-QBVKCWZT.js +9 -0
  60. package/dist/{load-B6KY2WPG.js.map → load-QBVKCWZT.js.map} +1 -1
  61. package/dist/{run-outcome-JO4IIEJJ.js → run-outcome-NQAU6DOA.js} +5 -5
  62. package/dist/{run-outcome-JO4IIEJJ.js.map → run-outcome-NQAU6DOA.js.map} +1 -1
  63. package/dist/runtime-session-ZPGU4PGW.js +20 -0
  64. package/dist/{runtime-session-LY3STY7C.js.map → runtime-session-ZPGU4PGW.js.map} +1 -1
  65. package/dist/session-QNSYTLLJ.js +15 -0
  66. package/dist/{session-KRLJTAK6.js.map → session-QNSYTLLJ.js.map} +1 -1
  67. package/dist/{stream-json-VP6TVWKF.js → stream-json-5WFD6HRO.js} +11 -11
  68. package/dist/{stream-json-VP6TVWKF.js.map → stream-json-5WFD6HRO.js.map} +1 -1
  69. package/dist/{vg-mcp-bridge-2CT67CXT.js → vg-mcp-bridge-VTGXA6CO.js} +8 -8
  70. package/dist/{vg-mcp-bridge-2CT67CXT.js.map → vg-mcp-bridge-VTGXA6CO.js.map} +1 -1
  71. package/dist/{vgd-BCBVZ2QA.js → vgd-54GEZWBI.js} +8 -8
  72. package/dist/vgd-54GEZWBI.js.map +1 -0
  73. package/package.json +3 -3
  74. package/dist/chunk-2U4SXS5U.js.map +0 -1
  75. package/dist/chunk-54USY7IT.js +0 -6
  76. package/dist/chunk-LEESW7CF.js.map +0 -1
  77. package/dist/chunk-P64OTAUL.js.map +0 -1
  78. package/dist/chunk-TAV6XEFK.js.map +0 -1
  79. package/dist/graph-backend-5AMGXUDF.js +0 -13
  80. package/dist/interactive-5NXJTODL.js.map +0 -1
  81. package/dist/load-B6KY2WPG.js +0 -9
  82. package/dist/runtime-session-LY3STY7C.js +0 -20
  83. package/dist/session-KRLJTAK6.js +0 -15
  84. package/dist/vgd-BCBVZ2QA.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-ABJVJUKB.js';
4
- import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-3LDQD53S.js';
3
+ import { fetchCatalog, resolveProviders } from './chunk-IQJUFRZZ.js';
4
+ import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-VTJAPNJO.js';
5
5
  import './chunk-IS7VTH2Q.js';
6
- import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-L5O6W5EB.js';
7
- import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-P64OTAUL.js';
6
+ import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-6XKDAYYR.js';
7
+ import { runCodeSession } from './chunk-KAOSPAFK.js';
8
+ import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-I2JNLAKW.js';
8
9
  import './chunk-543E6WDJ.js';
10
+ import { summarizeDiffs, ScriptedProvider } from './chunk-SI4D7DYF.js';
9
11
  import './chunk-7AVYKZEM.js';
10
12
  import { buildModelInstallPlan } from './chunk-WHJMS7XC.js';
11
- import { runCodeSession } from './chunk-63QGVU4A.js';
12
- import { summarizeDiffs, ScriptedProvider } from './chunk-2U4SXS5U.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-OAMAINC6.js';
15
- export { runBuild } from './chunk-OAMAINC6.js';
14
+ import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, runBuild } from './chunk-D2VEJHPC.js';
15
+ export { runBuild } from './chunk-D2VEJHPC.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-TFGUYBNC.js';
21
+ import './chunk-HV4CKBXT.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, RefreshScheduler } from './chunk-MDQO4ACI.js';
27
- import { refreshIfStale } from './chunk-PPXAN2X5.js';
28
- import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-4IAKFZVG.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-TAV6XEFK.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-TPWMFEIA.js';
26
+ import { serveStdio, isRelevantChange, exportGraph, GraphSource, createServer, formatForExt, RefreshScheduler } from './chunk-6L6V77HW.js';
27
+ import { refreshIfStale } from './chunk-455ZJQQ4.js';
28
+ import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-7C5UKIXD.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-ZPPDKHGL.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-QDKFGLI3.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-EEZ5HCL2.js';
34
+ import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-CBPDYYIH.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-PZEJ4LHP.js';
42
+ import { queryGraphSemantic, queryGraph, indexFor, impactOf } from './chunk-EW2ZMFUC.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-LEESW7CF.js';
46
- import { loadGraph, loadGraphPreferIndex, SCHEMA_VERSION } from './chunk-VETQRKXJ.js';
47
- import { cacheDir, resolveGraphPath, analyzeQuestion, loadTopicTags, renderReport, resetRelevanceProviderCache, loadRelevanceProvider, loadGraphFileWithSnapshot, serializeGraph, stableStringify, writeArtifacts, vibgrateDir, mapFileExists, relevanceModuleDir, parseGraph, ensureVibgrateGitignore } from './chunk-ZXQP2GQE.js';
48
- import { VERSION } from './chunk-54USY7IT.js';
45
+ import { embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, unavailableMessage, countPending, modelCacheInfo, embeddingsPath, clearModelCache, withTimeout } from './chunk-KYRH3567.js';
46
+ import { loadGraph, loadGraphPreferIndex, SCHEMA_VERSION } from './chunk-SBVZGEOB.js';
47
+ import { cacheDir, resolveGraphPath, analyzeQuestion, loadTopicTags, renderReport, resetRelevanceProviderCache, loadRelevanceProvider, loadGraphFileWithSnapshot, serializeGraph, stableStringify, writeArtifacts, vibgrateDir, mapFileExists, relevanceModuleDir, parseGraph, ensureVibgrateGitignore } from './chunk-ZMSTSEGR.js';
48
+ import { VERSION } from './chunk-K6MLOGU4.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);
@@ -179,7 +179,14 @@ function registerAsk(program) {
179
179
  info(c.dim(" preparing semantic search (first use embeds the map; cached, resumable & offline after)\u2026"));
180
180
  }
181
181
  let reason;
182
- const embedder = await loadEmbedder({ local: global.local, onUnavailable: (r) => reason = r });
182
+ let detail;
183
+ const embedder = await loadEmbedder({
184
+ local: global.local,
185
+ onUnavailable: (r, d) => {
186
+ reason = r;
187
+ detail = d;
188
+ }
189
+ });
183
190
  if (embedder) {
184
191
  const bar = !global.json && firstRun ? new ProgressBar(c.dim("embedding")) : void 0;
185
192
  const vectors = await getNodeEmbeddings(graph, embedder, root2, bar ? (d, t) => bar.update(d, t) : void 0);
@@ -189,6 +196,7 @@ function registerAsk(program) {
189
196
  } else {
190
197
  result = queryGraph(graph, q, { budget, relevance, topicTags });
191
198
  note = reason ? unavailableMessage(reason) : "semantic unavailable; used lexical";
199
+ if (detail) note += ` (${detail})`;
192
200
  }
193
201
  } else {
194
202
  result = queryGraph(graph, q, { budget, relevance, topicTags });
@@ -237,11 +245,11 @@ function crashedMessage(signal) {
237
245
  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
246
  }
239
247
  function defaultCacheDir() {
240
- const base = process.env.XDG_CACHE_HOME || path40.join(os.homedir(), ".cache");
241
- return path40.join(base, "vibgrate", "models");
248
+ const base = process.env.XDG_CACHE_HOME || path41.join(os.homedir(), ".cache");
249
+ return path41.join(base, "vibgrate", "models");
242
250
  }
243
251
  function verdictPath(dir) {
244
- return path40.join(dir, `embed-health-${process.platform}-${process.arch}.json`);
252
+ return path41.join(dir, `embed-health-${process.platform}-${process.arch}.json`);
245
253
  }
246
254
  function readVerdict(dir) {
247
255
  try {
@@ -260,14 +268,27 @@ function writeVerdict(dir, verdict) {
260
268
  } catch {
261
269
  }
262
270
  }
271
+ function probeModuleUrl(from = import.meta.url) {
272
+ const dir = path41.dirname(fileURLToPath(from));
273
+ for (const name of ["embeddings.js", "index.js"]) {
274
+ const candidate = path41.join(dir, name);
275
+ if (fs11.existsSync(candidate)) return pathToFileURL(candidate).href;
276
+ }
277
+ return pathToFileURL(path41.join(dir, "index.js")).href;
278
+ }
263
279
  function defaultRunProbe(timeoutMs) {
264
- const moduleUrl = new URL("./embeddings.js", import.meta.url).href;
280
+ const moduleUrl = probeModuleUrl();
265
281
  const script = `
266
282
  import(${JSON.stringify(moduleUrl)})
267
283
  .then(async (m) => {
284
+ if (typeof m.loadEmbedder !== 'function') {
285
+ process.stdout.write('{"ok":false}');
286
+ return;
287
+ }
268
288
  const e = await m.loadEmbedder({ noDownload: true });
269
289
  if (!e) { process.stdout.write('{"ok":false}'); return; }
270
290
  await e.embedQuery('probe');
291
+ await e.embed(['probe document']);
271
292
  process.stdout.write('{"ok":true}');
272
293
  })
273
294
  .catch(() => process.stdout.write('{"ok":false}'));
@@ -350,11 +371,12 @@ function registerEmbed(program) {
350
371
  const bg = opts.bg === true;
351
372
  const speak = !bg && !global.json;
352
373
  if (global.local) {
353
- if (speak) info(c.dim("vg embed \xB7 semantic is off (--local) \u2014 lexical search only"));
374
+ if (global.json) json({ embedded: 0, model: modelId, semantic: false, reason: "local" });
375
+ else if (speak) info(c.dim("vg embed \xB7 semantic is off (--local) \u2014 lexical search only"));
354
376
  return;
355
377
  }
356
378
  if (countPending(graph, root2, modelId) === 0) {
357
- if (global.json) json({ embedded: 0, pending: 0, upToDate: true, model: modelId });
379
+ if (global.json) json({ embedded: 0, pending: 0, upToDate: true, model: modelId, semantic: true });
358
380
  else if (speak) info(`${c.cyan("vg embed")} \xB7 semantic index already up to date`);
359
381
  return;
360
382
  }
@@ -365,6 +387,7 @@ function registerEmbed(program) {
365
387
  return;
366
388
  }
367
389
  let reason;
390
+ let detail;
368
391
  const embedder = await loadEmbedder({
369
392
  local: global.local,
370
393
  // Background warm-ups skip the download unless explicitly asked to fetch
@@ -372,17 +395,24 @@ function registerEmbed(program) {
372
395
  // time `vg serve`/`vg ask` needs it).
373
396
  noDownload: bg && opts.download !== true,
374
397
  showDownloadProgress: !bg,
375
- onUnavailable: (r) => reason = r
398
+ onUnavailable: (r, d) => {
399
+ reason = r;
400
+ detail = d;
401
+ }
376
402
  });
377
403
  if (!embedder) {
378
- if (speak && reason) info(c.dim(`vg embed \xB7 ${unavailableMessage(reason)}`));
404
+ if (global.json) {
405
+ json({ embedded: 0, model: modelId, semantic: false, reason: reason ?? "init-failed", detail: detail ?? null });
406
+ } else if (reason) {
407
+ info(c.dim(`vg embed \xB7 ${unavailableMessage(reason)}${detail ? ` (${detail})` : ""}`));
408
+ }
379
409
  return;
380
410
  }
381
411
  const pending = countPending(graph, root2, modelId);
382
412
  const bar = speak ? new ProgressBar(c.dim("embedding")) : void 0;
383
413
  await getNodeEmbeddings(graph, embedder, root2, bar ? (d, t) => bar.update(d, t) : void 0);
384
414
  bar?.done();
385
- if (global.json) json({ embedded: pending, model: modelId });
415
+ if (global.json) json({ embedded: pending, model: modelId, semantic: true });
386
416
  else if (speak) info(`${c.green("\u2714")} vg embed \xB7 semantic index ready (~${pending} node(s) \xB7 model ${modelId})`);
387
417
  });
388
418
  applyGlobalOptions(cmd);
@@ -989,7 +1019,7 @@ var PUBLISH_INTERVAL_MS = 2e3;
989
1019
  var KEEPALIVE_MS = 1e4;
990
1020
  var STALE_MS = 6e4;
991
1021
  function liveStatsDir(root2) {
992
- return path40.join(cacheDir(root2), "serve-live");
1022
+ return path41.join(cacheDir(root2), "serve-live");
993
1023
  }
994
1024
  function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid, signal) => process.kill(pid, signal), selfPid = process.pid) {
995
1025
  let entries;
@@ -1003,7 +1033,7 @@ function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid
1003
1033
  if (!/^serve-\d+\.json$/.test(name)) continue;
1004
1034
  let parsed;
1005
1035
  try {
1006
- parsed = JSON.parse(fs11.readFileSync(path40.join(dir, name), "utf8"));
1036
+ parsed = JSON.parse(fs11.readFileSync(path41.join(dir, name), "utf8"));
1007
1037
  } catch {
1008
1038
  continue;
1009
1039
  }
@@ -1025,7 +1055,7 @@ var LiveStatsBus = class {
1025
1055
  this.dir = dir;
1026
1056
  this.stats = stats;
1027
1057
  this.pid = pid;
1028
- this.file = path40.join(dir, `serve-${this.pid}.json`);
1058
+ this.file = path41.join(dir, `serve-${this.pid}.json`);
1029
1059
  }
1030
1060
  dir;
1031
1061
  stats;
@@ -1078,7 +1108,7 @@ var LiveStatsBus = class {
1078
1108
  const out2 = [];
1079
1109
  for (const name of entries.sort()) {
1080
1110
  if (!/^serve-\d+\.json$/.test(name)) continue;
1081
- const file = path40.join(this.dir, name);
1111
+ const file = path41.join(this.dir, name);
1082
1112
  let parsed;
1083
1113
  try {
1084
1114
  parsed = JSON.parse(fs11.readFileSync(file, "utf8"));
@@ -1824,7 +1854,7 @@ function endOfLine(text, line) {
1824
1854
  }
1825
1855
  var CACHE_VERSION = "vg-lsp-scan-cache/2";
1826
1856
  function cachePath(root2) {
1827
- return path40.join(cacheDir(root2), "lsp-scan.json");
1857
+ return path41.join(cacheDir(root2), "lsp-scan.json");
1828
1858
  }
1829
1859
  function manifestHash(root2) {
1830
1860
  const files = [];
@@ -1836,7 +1866,7 @@ function manifestHash(root2) {
1836
1866
  return;
1837
1867
  }
1838
1868
  for (const entry of entries) {
1839
- const abs = path40.join(dir, entry.name);
1869
+ const abs = path41.join(dir, entry.name);
1840
1870
  if (entry.isDirectory()) {
1841
1871
  if (isSkippedDirName(entry.name)) continue;
1842
1872
  walk2(abs);
@@ -1846,7 +1876,7 @@ function manifestHash(root2) {
1846
1876
  const base = entry.name.toLowerCase();
1847
1877
  if (!isManifest(abs) && !SKIP_FILES.has(base)) continue;
1848
1878
  try {
1849
- const rel = path40.relative(root2, abs).split(path40.sep).join("/");
1879
+ const rel = path41.relative(root2, abs).split(path41.sep).join("/");
1850
1880
  files.push({ rel, hash: hashBytes(fs11.readFileSync(abs)) });
1851
1881
  } catch {
1852
1882
  }
@@ -1857,9 +1887,9 @@ function manifestHash(root2) {
1857
1887
  return hashString(canonicalize(files));
1858
1888
  }
1859
1889
  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);
1890
+ const rel = path41.relative(path41.resolve(root2), path41.resolve(filePath));
1891
+ if (rel === "" || rel.startsWith("..") || path41.isAbsolute(rel)) return false;
1892
+ const parts = rel.split(path41.sep);
1863
1893
  if (parts.slice(0, -1).some((dir) => isSkippedDirName(dir))) return false;
1864
1894
  const base = parts[parts.length - 1].toLowerCase();
1865
1895
  return isManifest(filePath) || SKIP_FILES.has(base);
@@ -1890,7 +1920,7 @@ function writeScanCache(root2, key2, artifact) {
1890
1920
  var MAX_ENTRIES = 1e3;
1891
1921
  var KEEP_ENTRIES = 500;
1892
1922
  function historyPath(root2) {
1893
- return path40.join(root2, ".vibgrate", "score-history.jsonl");
1923
+ return path41.join(root2, ".vibgrate", "score-history.jsonl");
1894
1924
  }
1895
1925
  function parseLine(line) {
1896
1926
  try {
@@ -1931,7 +1961,7 @@ function recordScore(root2, entry) {
1931
1961
  }
1932
1962
  }
1933
1963
  const file = historyPath(root2);
1934
- fs11.mkdirSync(path40.dirname(file), { recursive: true });
1964
+ fs11.mkdirSync(path41.dirname(file), { recursive: true });
1935
1965
  ensureVibgrateGitignore(root2);
1936
1966
  fs11.appendFileSync(file, `${JSON.stringify(entry)}
1937
1967
  `);
@@ -1990,11 +2020,17 @@ async function runAsk(graph, params, ctx) {
1990
2020
  const budgetMs = semanticBudgetMs();
1991
2021
  log(`ask: trying the semantic path (budget ${Math.round(budgetMs / 1e3)}s)`);
1992
2022
  let reason;
2023
+ let detail;
1993
2024
  const started = Date.now();
1994
2025
  try {
1995
2026
  result = await withTimeout(
1996
2027
  (async () => {
1997
- const embedder = await loadEmbedder({ onUnavailable: (r2) => reason = r2 });
2028
+ const embedder = await loadEmbedder({
2029
+ onUnavailable: (r2, d) => {
2030
+ reason = r2;
2031
+ detail = d;
2032
+ }
2033
+ });
1998
2034
  if (!embedder) return null;
1999
2035
  log(`ask: embedder "${embedder.id}" loaded in ${Date.now() - started}ms; embedding nodes\u2026`);
2000
2036
  const vectors = await getNodeEmbeddings(graph, embedder, ctx.root);
@@ -2008,7 +2044,9 @@ async function runAsk(graph, params, ctx) {
2008
2044
  );
2009
2045
  if (!result) {
2010
2046
  note = reason ? unavailableMessage(reason) : "semantic unavailable; used lexical";
2011
- log(`ask: semantic unavailable (${reason ?? "no backend"}) \u2014 falling back to lexical`);
2047
+ log(
2048
+ `ask: semantic unavailable (${reason ?? "no backend"}) \u2014 falling back to lexical` + (detail ? ` \xB7 ${detail}` : "")
2049
+ );
2012
2050
  }
2013
2051
  } catch (err) {
2014
2052
  mode = "lexical";
@@ -2902,7 +2940,7 @@ var VibgrateLanguageServer = class {
2902
2940
  const ecosystem = osvEcosystem(proj.type);
2903
2941
  if (!ecosystem) continue;
2904
2942
  const relManifest = manifestRelativePath(proj);
2905
- const absManifest = path40.resolve(this.opts.root, relManifest);
2943
+ const absManifest = path41.resolve(this.opts.root, relManifest);
2906
2944
  let text = null;
2907
2945
  try {
2908
2946
  if (fs11.existsSync(absManifest)) text = fs11.readFileSync(absManifest, "utf8");
@@ -3054,9 +3092,9 @@ function pruneArtifactProjects(a) {
3054
3092
  return { ...a, projects, findings };
3055
3093
  }
3056
3094
  function projectByPath(a, projectPath) {
3057
- const want = path40.normalize(projectPath === "" ? "." : projectPath);
3095
+ const want = path41.normalize(projectPath === "" ? "." : projectPath);
3058
3096
  for (const proj of a.projects ?? []) {
3059
- const got = path40.normalize(proj.path === "" ? "." : proj.path);
3097
+ const got = path41.normalize(proj.path === "" ? "." : proj.path);
3060
3098
  if (got === want) return proj;
3061
3099
  }
3062
3100
  return void 0;
@@ -3093,12 +3131,12 @@ function buildProjectRefs(rootDir, projects) {
3093
3131
  return refs.length > 0 ? refs : void 0;
3094
3132
  }
3095
3133
  function projectForFile(root2, a, filePath) {
3096
- const dir = path40.dirname(path40.resolve(filePath));
3134
+ const dir = path41.dirname(path41.resolve(filePath));
3097
3135
  let best;
3098
3136
  let bestLen = -1;
3099
3137
  for (const proj of a.projects ?? []) {
3100
- const projDir = path40.resolve(root2, proj.path);
3101
- if ((dir === projDir || dir.startsWith(projDir + path40.sep)) && projDir.length > bestLen) {
3138
+ const projDir = path41.resolve(root2, proj.path);
3139
+ if ((dir === projDir || dir.startsWith(projDir + path41.sep)) && projDir.length > bestLen) {
3102
3140
  best = proj;
3103
3141
  bestLen = projDir.length;
3104
3142
  }
@@ -3106,7 +3144,7 @@ function projectForFile(root2, a, filePath) {
3106
3144
  return best;
3107
3145
  }
3108
3146
  function sameProject(location, projectPath) {
3109
- return path40.normalize(location) === path40.normalize(projectPath);
3147
+ return path41.normalize(location) === path41.normalize(projectPath);
3110
3148
  }
3111
3149
  function hasReleaseDates(a) {
3112
3150
  for (const proj of a.projects ?? []) {
@@ -3176,7 +3214,7 @@ function buildBreakdown(rootDir, projects) {
3176
3214
  const relManifest = manifestRelativePath(p);
3177
3215
  if (isPrunedWorkspacePath(p.path) || isPrunedWorkspacePath(relManifest)) continue;
3178
3216
  const ecosystem = osvEcosystem(p.type);
3179
- const absManifest = path40.resolve(rootDir, relManifest);
3217
+ const absManifest = path41.resolve(rootDir, relManifest);
3180
3218
  let text = null;
3181
3219
  try {
3182
3220
  if (fs11.existsSync(absManifest)) text = fs11.readFileSync(absManifest, "utf8");
@@ -3244,34 +3282,34 @@ function buildBreakdown(rootDir, projects) {
3244
3282
  }
3245
3283
  function manifestRelativePath(proj) {
3246
3284
  const base = proj.path === "." || proj.path === "" ? "" : proj.path;
3247
- const join30 = (name) => base ? path40.join(base, name) : name;
3285
+ const join31 = (name) => base ? path41.join(base, name) : name;
3248
3286
  switch (proj.type) {
3249
3287
  case "node":
3250
3288
  case "typescript":
3251
- return join30("package.json");
3289
+ return join31("package.json");
3252
3290
  case "python":
3253
- return join30("pyproject.toml");
3291
+ return join31("pyproject.toml");
3254
3292
  case "go":
3255
- return join30("go.mod");
3293
+ return join31("go.mod");
3256
3294
  case "rust":
3257
- return join30("Cargo.toml");
3295
+ return join31("Cargo.toml");
3258
3296
  case "ruby":
3259
- return join30("Gemfile");
3297
+ return join31("Gemfile");
3260
3298
  case "php":
3261
- return join30("composer.json");
3299
+ return join31("composer.json");
3262
3300
  case "java":
3263
3301
  case "kotlin":
3264
3302
  case "scala":
3265
3303
  case "groovy":
3266
- return join30("pom.xml");
3304
+ return join31("pom.xml");
3267
3305
  case "dotnet":
3268
- return join30(proj.name ? `${proj.name}.csproj` : "Directory.Build.props");
3306
+ return join31(proj.name ? `${proj.name}.csproj` : "Directory.Build.props");
3269
3307
  case "dart":
3270
- return join30("pubspec.yaml");
3308
+ return join31("pubspec.yaml");
3271
3309
  case "elixir":
3272
- return join30("mix.exs");
3310
+ return join31("mix.exs");
3273
3311
  default:
3274
- return join30("package.json");
3312
+ return join31("package.json");
3275
3313
  }
3276
3314
  }
3277
3315
  function lockfileRelativePath(rootDir, proj) {
@@ -3302,9 +3340,9 @@ function lockfileRelativePath(rootDir, proj) {
3302
3340
  const dirsToTry = base ? [base, ""] : [""];
3303
3341
  for (const dir of dirsToTry) {
3304
3342
  for (const name of candidateNames) {
3305
- const rel = dir ? path40.join(dir, name) : name;
3343
+ const rel = dir ? path41.join(dir, name) : name;
3306
3344
  try {
3307
- if (fs11.existsSync(path40.join(rootDir, rel))) return rel;
3345
+ if (fs11.existsSync(path41.join(rootDir, rel))) return rel;
3308
3346
  } catch {
3309
3347
  }
3310
3348
  }
@@ -3375,7 +3413,7 @@ function lookupImportFiles(map, pkg) {
3375
3413
  }
3376
3414
  function firstPackageMentionLine(root2, relFile, pkg) {
3377
3415
  try {
3378
- const abs = path40.resolve(root2, relFile);
3416
+ const abs = path41.resolve(root2, relFile);
3379
3417
  const stat2 = fs11.statSync(abs);
3380
3418
  if (!stat2.isFile() || stat2.size > 256 * 1024) return null;
3381
3419
  const text = fs11.readFileSync(abs, "utf8");
@@ -3579,8 +3617,8 @@ function hookCommand(vgBin) {
3579
3617
  return `${vgBin} hook pre-tool-use`;
3580
3618
  }
3581
3619
  function installClaudeHooks(root2, vgBin = "vg") {
3582
- const file = path40.join(root2, ".claude", "settings.json");
3583
- const rel = path40.join(".claude", "settings.json");
3620
+ const file = path41.join(root2, ".claude", "settings.json");
3621
+ const rel = path41.join(".claude", "settings.json");
3584
3622
  let settings = {};
3585
3623
  if (fs11.existsSync(file)) {
3586
3624
  try {
@@ -3621,8 +3659,8 @@ function installClaudeHooks(root2, vgBin = "vg") {
3621
3659
  return { file: rel, status: "written" };
3622
3660
  }
3623
3661
  function uninstallClaudeHooks(root2) {
3624
- const file = path40.join(root2, ".claude", "settings.json");
3625
- const rel = path40.join(".claude", "settings.json");
3662
+ const file = path41.join(root2, ".claude", "settings.json");
3663
+ const rel = path41.join(".claude", "settings.json");
3626
3664
  if (!fs11.existsSync(file)) return { file: rel, status: "unchanged" };
3627
3665
  let settings;
3628
3666
  try {
@@ -3648,7 +3686,7 @@ function uninstallClaudeHooks(root2) {
3648
3686
  return { file: rel, status: "written" };
3649
3687
  }
3650
3688
  function writeSettings(file, settings) {
3651
- fs11.mkdirSync(path40.dirname(file), { recursive: true });
3689
+ fs11.mkdirSync(path41.dirname(file), { recursive: true });
3652
3690
  fs11.writeFileSync(file, `${JSON.stringify(settings, null, 2)}
3653
3691
  `);
3654
3692
  }
@@ -3769,7 +3807,7 @@ function registryBase(opts) {
3769
3807
  return (process.env.VIBGRATE_MODULE_REGISTRY || opts.registry || DEFAULT_REGISTRY).replace(/\/+$/, "");
3770
3808
  }
3771
3809
  function stateFile() {
3772
- return path40.join(path40.dirname(relevanceModuleDir()), "consent.json");
3810
+ return path41.join(path41.dirname(relevanceModuleDir()), "consent.json");
3773
3811
  }
3774
3812
  function readConsent() {
3775
3813
  try {
@@ -3780,7 +3818,7 @@ function readConsent() {
3780
3818
  }
3781
3819
  function writeConsent(state) {
3782
3820
  try {
3783
- fs11.mkdirSync(path40.dirname(stateFile()), { recursive: true });
3821
+ fs11.mkdirSync(path41.dirname(stateFile()), { recursive: true });
3784
3822
  fs11.writeFileSync(stateFile(), JSON.stringify(state));
3785
3823
  } catch {
3786
3824
  }
@@ -3791,8 +3829,8 @@ function kernelDisabled() {
3791
3829
  }
3792
3830
  function moduleInstalled() {
3793
3831
  try {
3794
- const meta = JSON.parse(fs11.readFileSync(path40.join(relevanceModuleDir(), ".module.json"), "utf8"));
3795
- if (fs11.existsSync(path40.join(relevanceModuleDir(), "index.js"))) {
3832
+ const meta = JSON.parse(fs11.readFileSync(path41.join(relevanceModuleDir(), ".module.json"), "utf8"));
3833
+ if (fs11.existsSync(path41.join(relevanceModuleDir(), "index.js"))) {
3796
3834
  return { installed: true, version: meta.version };
3797
3835
  }
3798
3836
  } catch {
@@ -3841,7 +3879,7 @@ function untar(data) {
3841
3879
  if (type !== "0" && type !== "\0") continue;
3842
3880
  const name = pendingName ?? (prefix ? `${prefix}/${rawName}` : rawName);
3843
3881
  pendingName = null;
3844
- if (name.split("/").includes("..") || path40.isAbsolute(name)) {
3882
+ if (name.split("/").includes("..") || path41.isAbsolute(name)) {
3845
3883
  throw new Error(`unsafe path in tarball: ${name}`);
3846
3884
  }
3847
3885
  out2.push({ name, body: Buffer.from(body) });
@@ -3875,17 +3913,17 @@ async function installRelevanceModule(opts = {}) {
3875
3913
  if (e.name.startsWith("package/dist/")) rel = e.name.slice("package/dist/".length);
3876
3914
  else if (e.name === "package/LICENSE" || e.name === "package/README.md") rel = e.name.slice("package/".length);
3877
3915
  if (!rel) continue;
3878
- const target = path40.join(dir, rel);
3879
- if (!target.startsWith(dir + path40.sep) && target !== dir) throw new Error(`unsafe extract path: ${rel}`);
3880
- fs11.mkdirSync(path40.dirname(target), { recursive: true });
3916
+ const target = path41.join(dir, rel);
3917
+ if (!target.startsWith(dir + path41.sep) && target !== dir) throw new Error(`unsafe extract path: ${rel}`);
3918
+ fs11.mkdirSync(path41.dirname(target), { recursive: true });
3881
3919
  fs11.writeFileSync(target, e.body);
3882
3920
  wrote += 1;
3883
3921
  }
3884
- if (!wrote || !fs11.existsSync(path40.join(dir, "index.js"))) {
3922
+ if (!wrote || !fs11.existsSync(path41.join(dir, "index.js"))) {
3885
3923
  fs11.rmSync(dir, { recursive: true, force: true });
3886
3924
  return { status: "unavailable", detail: "package layout not recognized (no dist/index.js)" };
3887
3925
  }
3888
- fs11.writeFileSync(path40.join(dir, ".module.json"), JSON.stringify({ name: RELEVANCE_MODULE_NAME, version }));
3926
+ fs11.writeFileSync(path41.join(dir, ".module.json"), JSON.stringify({ name: RELEVANCE_MODULE_NAME, version }));
3889
3927
  resetRelevanceProviderCache();
3890
3928
  return { status: "installed", version };
3891
3929
  } catch (e) {
@@ -4044,7 +4082,7 @@ function registerShare(program) {
4044
4082
  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) {
4045
4083
  const global = readGlobal(this);
4046
4084
  const root2 = rootOf(global);
4047
- const gitDir = path40.join(root2, ".git");
4085
+ const gitDir = path41.join(root2, ".git");
4048
4086
  if (!fs11.existsSync(gitDir)) {
4049
4087
  throw new CliError("not a git repository \u2014 run `vg share` inside a git repo", ExitCode.USAGE_ERROR);
4050
4088
  }
@@ -4066,15 +4104,15 @@ function registerShare(program) {
4066
4104
  applyGlobalOptions(cmd);
4067
4105
  }
4068
4106
  function writeVibgrateGitignore(root2, reports) {
4069
- const dir = path40.join(root2, ".vibgrate");
4107
+ const dir = path41.join(root2, ".vibgrate");
4070
4108
  fs11.mkdirSync(dir, { recursive: true });
4071
4109
  const lines = ["# Managed by `vg share` \u2014 keep graph.json committed, ignore the rest", "cache/", "facts.jsonl", "graph.snap"];
4072
4110
  if (!reports) lines.push("graph.html", "GRAPH_REPORT.md");
4073
- fs11.writeFileSync(path40.join(dir, ".gitignore"), `${lines.join("\n")}
4111
+ fs11.writeFileSync(path41.join(dir, ".gitignore"), `${lines.join("\n")}
4074
4112
  `);
4075
4113
  }
4076
4114
  function writeGitAttributes(root2) {
4077
- const file = path40.join(root2, ".gitattributes");
4115
+ const file = path41.join(root2, ".gitattributes");
4078
4116
  const line = ".vibgrate/graph.json merge=vg";
4079
4117
  let content = fs11.existsSync(file) ? fs11.readFileSync(file, "utf8") : "";
4080
4118
  if (!content.split("\n").some((l) => l.trim() === line)) {
@@ -4092,7 +4130,7 @@ function configureMergeDriver(root2) {
4092
4130
  function installPreCommitHook(root2) {
4093
4131
  const hooksDir = hookDir(root2);
4094
4132
  fs11.mkdirSync(hooksDir, { recursive: true });
4095
- const file = path40.join(hooksDir, "pre-commit");
4133
+ const file = path41.join(hooksDir, "pre-commit");
4096
4134
  const block = [
4097
4135
  HOOK_BEGIN,
4098
4136
  "if command -v vg >/dev/null 2>&1; then",
@@ -4114,14 +4152,14 @@ ${content}`;
4114
4152
  fs11.chmodSync(file, 493);
4115
4153
  }
4116
4154
  function undo(root2) {
4117
- const hookFile = path40.join(hookDir(root2), "pre-commit");
4155
+ const hookFile = path41.join(hookDir(root2), "pre-commit");
4118
4156
  if (fs11.existsSync(hookFile)) {
4119
4157
  const re = new RegExp(`\\n*${escapeRe(HOOK_BEGIN)}[\\s\\S]*?${escapeRe(HOOK_END)}\\n*`);
4120
4158
  const next2 = fs11.readFileSync(hookFile, "utf8").replace(re, "\n");
4121
4159
  if (next2.trim() === "#!/bin/sh") fs11.rmSync(hookFile);
4122
4160
  else fs11.writeFileSync(hookFile, next2);
4123
4161
  }
4124
- const attr = path40.join(root2, ".gitattributes");
4162
+ const attr = path41.join(root2, ".gitattributes");
4125
4163
  if (fs11.existsSync(attr)) {
4126
4164
  const next2 = fs11.readFileSync(attr, "utf8").split("\n").filter((l) => l.trim() !== ".vibgrate/graph.json merge=vg").join("\n");
4127
4165
  fs11.writeFileSync(attr, next2);
@@ -4134,10 +4172,10 @@ function undo(root2) {
4134
4172
  function hookDir(root2) {
4135
4173
  try {
4136
4174
  const configured = git(root2, ["config", "--get", "core.hooksPath"]).trim();
4137
- if (configured) return path40.resolve(root2, configured);
4175
+ if (configured) return path41.resolve(root2, configured);
4138
4176
  } catch {
4139
4177
  }
4140
- return path40.join(root2, ".git", "hooks");
4178
+ return path41.join(root2, ".git", "hooks");
4141
4179
  }
4142
4180
  function git(root2, args) {
4143
4181
  return execFileSync("git", args, { cwd: root2, encoding: "utf8" });
@@ -4151,7 +4189,7 @@ function registerWatch(program) {
4151
4189
  const global = readGlobal(this);
4152
4190
  const root2 = rootOf(global);
4153
4191
  const debounceMs = Math.max(50, Number(opts.debounce) || DEFAULT_DEBOUNCE_MS);
4154
- const watchRoots = (paths.length ? paths : ["."]).map((p) => path40.resolve(root2, p));
4192
+ const watchRoots = (paths.length ? paths : ["."]).map((p) => path41.resolve(root2, p));
4155
4193
  for (const w of watchRoots) {
4156
4194
  if (!fs11.existsSync(w)) {
4157
4195
  throw new CliError(`watch path not found: ${w}`, ExitCode.USAGE_ERROR);
@@ -4219,7 +4257,7 @@ function registerWatch(program) {
4219
4257
  throw new CliError(`cannot watch ${w}: ${err.message}`, ExitCode.ERROR);
4220
4258
  }
4221
4259
  }
4222
- info(c.dim(`vg watch \xB7 watching ${watchRoots.map((p) => path40.relative(root2, p) || ".").join(", ")} (debounce ${debounceMs}ms) \xB7 Ctrl+C to stop`));
4260
+ info(c.dim(`vg watch \xB7 watching ${watchRoots.map((p) => path41.relative(root2, p) || ".").join(", ")} (debounce ${debounceMs}ms) \xB7 Ctrl+C to stop`));
4223
4261
  await new Promise((resolve21) => {
4224
4262
  const stop = () => {
4225
4263
  for (const w of watchers) w.close();
@@ -4552,7 +4590,7 @@ function normalizeStandards(raw) {
4552
4590
  }
4553
4591
  function loadStandards(root2) {
4554
4592
  for (const rel of STANDARDS_FILES) {
4555
- const p = path40__default.join(root2, rel);
4593
+ const p = path41__default.join(root2, rel);
4556
4594
  let text;
4557
4595
  try {
4558
4596
  text = fs11__default.readFileSync(p, "utf8");
@@ -5273,8 +5311,8 @@ async function runHostBench(options = {}) {
5273
5311
  }
5274
5312
  async function runArmSimulate(input) {
5275
5313
  const { arm, lib, modelPath, turns, trie, env, live } = input;
5276
- const path42 = `${modelPath}#${arm.id}`;
5277
- const session = await acquireHostSession(lib, path42);
5314
+ const path43 = `${modelPath}#${arm.id}`;
5315
+ const session = await acquireHostSession(lib, path43);
5278
5316
  const system = "You are a coding agent with a Task Capsule.";
5279
5317
  const capsule = "function readConfig(): Config { return load(); }";
5280
5318
  let last = null;
@@ -6638,8 +6676,8 @@ function registerModels(program) {
6638
6676
  }
6639
6677
  });
6640
6678
  if (opts.out) {
6641
- const outPath = path40.resolve(opts.out);
6642
- fs11.mkdirSync(path40.dirname(outPath), { recursive: true });
6679
+ const outPath = path41.resolve(opts.out);
6680
+ fs11.mkdirSync(path41.dirname(outPath), { recursive: true });
6643
6681
  fs11.writeFileSync(outPath, `${JSON.stringify(report, null, 2)}
6644
6682
  `);
6645
6683
  if (!global.json) info(c.dim(` wrote ${outPath}`));
@@ -6789,14 +6827,14 @@ function resolveUninstallTarget(name, runtimeOpt) {
6789
6827
  }
6790
6828
  return exact[0];
6791
6829
  }
6792
- const base = path40.basename(wantLc);
6830
+ const base = path41.basename(wantLc);
6793
6831
  const soft = fleet.filter((m) => {
6794
6832
  const n = m.name.toLowerCase();
6795
- return n === base || n.endsWith("/" + base) || n.endsWith(wantLc) || path40.basename(n) === base;
6833
+ return n === base || n.endsWith("/" + base) || n.endsWith(wantLc) || path41.basename(n) === base;
6796
6834
  });
6797
6835
  if (soft.length === 1) return soft[0];
6798
6836
  if (soft.length > 1) {
6799
- const baseHits = soft.filter((m) => path40.basename(m.name).toLowerCase() === base);
6837
+ const baseHits = soft.filter((m) => path41.basename(m.name).toLowerCase() === base);
6800
6838
  const pool = baseHits.length ? baseHits : soft;
6801
6839
  const order = ["ollama", "gguf", "lm-studio"];
6802
6840
  for (const rt of order) {
@@ -6834,7 +6872,7 @@ function printBackends(backends) {
6834
6872
  }
6835
6873
  }
6836
6874
  function codeConfigPath(root2) {
6837
- return path40.join(root2, ".vibgrate", "code.json");
6875
+ return path41.join(root2, ".vibgrate", "code.json");
6838
6876
  }
6839
6877
  function loadCodeConfig(root2) {
6840
6878
  try {
@@ -6916,7 +6954,7 @@ function discoverMcpServers(root2, ownServers) {
6916
6954
  const servers = {};
6917
6955
  const sources = [];
6918
6956
  for (const rel of MCP_CONFIG_FILES) {
6919
- const found = readMcpServersFile(path40.join(root2, rel));
6957
+ const found = readMcpServersFile(path41.join(root2, rel));
6920
6958
  const names = Object.keys(found);
6921
6959
  if (names.length) {
6922
6960
  sources.push(rel);
@@ -6948,7 +6986,7 @@ function registerCode(program) {
6948
6986
  try {
6949
6987
  const { parseMode: parseMode2, resolveMode: resolveMode2, readOrchestratorState: readOrchestratorState2, activePin: activePin2 } = await import('./model-orchestrator-LHYPJBFH.js');
6950
6988
  const { gatherSystemMemory: gatherSystemMemory2 } = await import('./local-runtime-2ED33KK6.js');
6951
- const { loadGraph: loadGraph2 } = await import('./load-B6KY2WPG.js');
6989
+ const { loadGraph: loadGraph2 } = await import('./load-QBVKCWZT.js');
6952
6990
  const state = readOrchestratorState2();
6953
6991
  const mode = parseMode2(modeFlag) ?? state.defaultMode ?? void 0;
6954
6992
  const pin = mode ? activePin2(mode, state) : null;
@@ -7033,7 +7071,7 @@ function registerCode(program) {
7033
7071
  if (!(process.stdin.isTTY && process.stdout.isTTY)) {
7034
7072
  throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"` (guided mode needs an interactive terminal)');
7035
7073
  }
7036
- const { runInteractive } = await import('./interactive-5NXJTODL.js');
7074
+ const { runInteractive } = await import('./interactive-7EZHEBHQ.js');
7037
7075
  await runInteractive(
7038
7076
  rootOf(global),
7039
7077
  global,
@@ -7063,7 +7101,7 @@ function registerCode(program) {
7063
7101
  }
7064
7102
  if (!instruction && !stdinFirstTurn) throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"`');
7065
7103
  {
7066
- const { ensureCodeMap } = await import('./ensure-map-7L3TPCGA.js');
7104
+ const { ensureCodeMap } = await import('./ensure-map-5E5TFPXJ.js');
7067
7105
  const mapRoot = rootOf(global);
7068
7106
  try {
7069
7107
  await ensureCodeMap(mapRoot, global, {
@@ -7148,20 +7186,20 @@ function registerCode(program) {
7148
7186
  process.stdout.write(JSON.stringify(line) + "\n");
7149
7187
  };
7150
7188
  try {
7151
- const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-JO4IIEJJ.js');
7189
+ const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-NQAU6DOA.js');
7152
7190
  const primarySlug = route.providers[0]?.model.includes("/") ? route.providers[0].model.split("/")[0] : route.providers[0]?.id;
7153
- const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-VP6TVWKF.js');
7154
- const { nodeCodeFs } = await import('./session-KRLJTAK6.js');
7191
+ const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-5WFD6HRO.js');
7192
+ const { nodeCodeFs } = await import('./session-QNSYTLLJ.js');
7155
7193
  const readline6 = await import('readline');
7156
7194
  const child = await import('child_process');
7157
7195
  const { loadOrDiscoverFederation } = await import('./federation-MDQPO3PW.js');
7158
7196
  const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
7159
7197
  const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
7160
- const { startCodeRuntimeSession } = await import('./runtime-session-LY3STY7C.js');
7161
- const { resolveGraphBackend } = await import('./graph-backend-5AMGXUDF.js');
7198
+ const { startCodeRuntimeSession } = await import('./runtime-session-ZPGU4PGW.js');
7199
+ const { resolveGraphBackend } = await import('./graph-backend-GQZXMNRI.js');
7162
7200
  const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
7163
7201
  const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
7164
- const { vgdRequest: vgdRequest2 } = await import('./vgd-BCBVZ2QA.js');
7202
+ const { vgdRequest: vgdRequest2 } = await import('./vgd-54GEZWBI.js');
7165
7203
  const federation = loadOrDiscoverFederation(root2);
7166
7204
  const modelProfile = mergeModelExecutionProfile(
7167
7205
  resolveModelExecutionProfile({
@@ -7219,7 +7257,7 @@ ${res.stderr}` : ""),
7219
7257
  exitCode: res.status ?? 1
7220
7258
  };
7221
7259
  };
7222
- const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-2CT67CXT.js');
7260
+ const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-VTGXA6CO.js');
7223
7261
  const vgBuiltin = createVgBuiltinMcpTools({
7224
7262
  getGraph: () => graph,
7225
7263
  root: root2,
@@ -7240,10 +7278,10 @@ ${res.stderr}` : ""),
7240
7278
  }
7241
7279
  const externalTools = mergeExternalToolsets(vgBuiltin, projectMcp);
7242
7280
  const { createCheckpoint } = await import('./checkpoint-4WFZMKEO.js');
7243
- const os5 = await import('os');
7281
+ const os6 = await import('os');
7244
7282
  const pathMod = await import('path');
7245
7283
  const checkpointIndex = pathMod.join(
7246
- fs11.mkdtempSync(pathMod.join(os5.tmpdir(), "vg-code-cp-")),
7284
+ fs11.mkdtempSync(pathMod.join(os6.tmpdir(), "vg-code-cp-")),
7247
7285
  "index"
7248
7286
  );
7249
7287
  const gitRunner = (gitArgs, gitEnv) => {
@@ -7279,6 +7317,10 @@ ${res.stderr}` : ""),
7279
7317
  providers: route.providers,
7280
7318
  fsImpl: nodeCodeFs(root2),
7281
7319
  run,
7320
+ // Live command-output events for the VG Code panel (async shell).
7321
+ // Sandboxed executionEnv still uses its own runner when set.
7322
+ streamShell: !executionEnv,
7323
+ allowSubagents: true,
7282
7324
  executionEnv,
7283
7325
  graphBackend,
7284
7326
  modelProfile,
@@ -7309,8 +7351,8 @@ ${res.stderr}` : ""),
7309
7351
  };
7310
7352
  try {
7311
7353
  if (opts.session) {
7312
- const { runCodeStreamJsonSession } = await import('./stream-json-VP6TVWKF.js');
7313
- const { runAgent: runAgent2 } = await import('./agent-PFYXJWWP.js');
7354
+ const { runCodeStreamJsonSession } = await import('./stream-json-5WFD6HRO.js');
7355
+ const { runAgent: runAgent2 } = await import('./agent-DSC3EQLT.js');
7314
7356
  const {
7315
7357
  condenseSession,
7316
7358
  loadLatestSession,
@@ -7478,8 +7520,8 @@ ${res.stderr}` : ""),
7478
7520
  if (!autonomous && !tty) {
7479
7521
  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).");
7480
7522
  }
7481
- const { agentTask } = await import('./interactive-5NXJTODL.js');
7482
- const { nodeCodeFs } = await import('./session-KRLJTAK6.js');
7523
+ const { agentTask } = await import('./interactive-7EZHEBHQ.js');
7524
+ const { nodeCodeFs } = await import('./session-QNSYTLLJ.js');
7483
7525
  const { TtyPrompter } = await import('./ui-K7D3BCHD.js');
7484
7526
  let priorSummary;
7485
7527
  let priorInstruction;
@@ -7492,7 +7534,7 @@ ${res.stderr}` : ""),
7492
7534
  }
7493
7535
  }
7494
7536
  const prompter = tty ? new TtyPrompter() : void 0;
7495
- const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-2CT67CXT.js');
7537
+ const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-VTGXA6CO.js');
7496
7538
  const vgBuiltin = createVgBuiltinMcpTools({
7497
7539
  getGraph: () => graph,
7498
7540
  root: root2,
@@ -7516,11 +7558,11 @@ ${res.stderr}` : ""),
7516
7558
  const { loadFederation } = await import('./federation-MDQPO3PW.js');
7517
7559
  const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
7518
7560
  const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
7519
- const { startCodeRuntimeSession } = await import('./runtime-session-LY3STY7C.js');
7520
- const { resolveGraphBackend } = await import('./graph-backend-5AMGXUDF.js');
7561
+ const { startCodeRuntimeSession } = await import('./runtime-session-ZPGU4PGW.js');
7562
+ const { resolveGraphBackend } = await import('./graph-backend-GQZXMNRI.js');
7521
7563
  const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
7522
7564
  const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
7523
- const { vgdRequest: vgdRequest2 } = await import('./vgd-BCBVZ2QA.js');
7565
+ const { vgdRequest: vgdRequest2 } = await import('./vgd-54GEZWBI.js');
7524
7566
  const federation = loadFederation(root2);
7525
7567
  const modelProfile = mergeModelExecutionProfile(
7526
7568
  resolveModelExecutionProfile({
@@ -7827,7 +7869,7 @@ async function addCmd(root2, rest, opts, asJson) {
7827
7869
  }
7828
7870
  function readPackageVersion(root2) {
7829
7871
  try {
7830
- const pkg = JSON.parse(fs11__default.readFileSync(path40__default.join(root2, "package.json"), "utf8"));
7872
+ const pkg = JSON.parse(fs11__default.readFileSync(path41__default.join(root2, "package.json"), "utf8"));
7831
7873
  return typeof pkg.version === "string" ? pkg.version : void 0;
7832
7874
  } catch {
7833
7875
  return void 0;
@@ -7850,8 +7892,8 @@ async function publishCmd(root2, rest, opts, global, asJson) {
7850
7892
  if (!parsed) throw new CliError("publishing a private library requires a DSN \u2014 run `vibgrate login` or set VIBGRATE_DSN", ExitCode.USAGE_ERROR);
7851
7893
  const version = (opts.version || readPackageVersion(root2) || "").trim();
7852
7894
  if (!version) throw usageError("a --version is required (or run from a package whose package.json has a version)");
7853
- const readme = readOptionalFile(opts.readme ? path40__default.resolve(opts.readme) : path40__default.join(root2, "README.md"));
7854
- const dts = opts.dts ? readOptionalFile(path40__default.resolve(opts.dts)) : void 0;
7895
+ const readme = readOptionalFile(opts.readme ? path41__default.resolve(opts.readme) : path41__default.join(root2, "README.md"));
7896
+ const dts = opts.dts ? readOptionalFile(path41__default.resolve(opts.dts)) : void 0;
7855
7897
  if (!readme && !dts) throw usageError("nothing to publish \u2014 no README.md found and no --dts given");
7856
7898
  const result = await publishPrivateLibrary(
7857
7899
  { name, version, readme, dts, language: opts.language },
@@ -7983,7 +8025,7 @@ function registerExport(program) {
7983
8025
  out(content.trimEnd());
7984
8026
  return;
7985
8027
  }
7986
- fs11.mkdirSync(path40.dirname(path40.resolve(file)), { recursive: true });
8028
+ fs11.mkdirSync(path41.dirname(path41.resolve(file)), { recursive: true });
7987
8029
  fs11.writeFileSync(file, content);
7988
8030
  info(`${c.green("\u2714")} wrote ${file} ${c.dim(`(${format})`)}`);
7989
8031
  });
@@ -7994,43 +8036,43 @@ function detectFormat(file) {
7994
8036
  if (lower.endsWith(".cdx.json")) return "cyclonedx";
7995
8037
  if (lower.endsWith(".spdx.json")) return "spdx";
7996
8038
  if (file === "-") return "json";
7997
- return formatForExt(path40.extname(file));
8039
+ return formatForExt(path41.extname(file));
7998
8040
  }
7999
8041
  function registerBundle(program) {
8000
8042
  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) {
8001
8043
  const global = readGlobal(this);
8002
8044
  const root2 = rootOf(global);
8003
- const outDir = path40.resolve(root2, opts.out ?? "vg-bundle");
8045
+ const outDir = path41.resolve(root2, opts.out ?? "vg-bundle");
8004
8046
  let grammarFiles;
8005
8047
  try {
8006
8048
  grammarFiles = resolvedGrammarFiles();
8007
8049
  } catch {
8008
8050
  throw new CliError("no grammars found to bundle (run a build first)", ExitCode.ERROR);
8009
8051
  }
8010
- fs11.mkdirSync(path40.join(outDir, "grammars"), { recursive: true });
8052
+ fs11.mkdirSync(path41.join(outDir, "grammars"), { recursive: true });
8011
8053
  let grammarCount = 0;
8012
8054
  for (const { fileName, absPath } of grammarFiles) {
8013
- fs11.copyFileSync(absPath, path40.join(outDir, "grammars", fileName));
8055
+ fs11.copyFileSync(absPath, path41.join(outDir, "grammars", fileName));
8014
8056
  grammarCount++;
8015
8057
  }
8016
8058
  const included = [`grammars/ (${grammarCount} .wasm)`];
8017
8059
  const graphSrc = resolveGraphPath(root2, global.graph);
8018
8060
  if (fs11.existsSync(graphSrc)) {
8019
- fs11.copyFileSync(graphSrc, path40.join(outDir, "graph.json"));
8061
+ fs11.copyFileSync(graphSrc, path41.join(outDir, "graph.json"));
8020
8062
  included.push("graph.json");
8021
8063
  } else {
8022
8064
  const graph = loadGraphFileWithSnapshot(graphSrc);
8023
8065
  if (graph) {
8024
- fs11.writeFileSync(path40.join(outDir, "graph.json"), serializeGraph(graph));
8066
+ fs11.writeFileSync(path41.join(outDir, "graph.json"), serializeGraph(graph));
8025
8067
  included.push("graph.json");
8026
8068
  }
8027
8069
  }
8028
8070
  const cat = catalogPath(root2);
8029
8071
  if (fs11.existsSync(cat)) {
8030
- fs11.copyFileSync(cat, path40.join(outDir, "vibgrate.lib.json"));
8072
+ fs11.copyFileSync(cat, path41.join(outDir, "vibgrate.lib.json"));
8031
8073
  included.push("vibgrate.lib.json");
8032
8074
  if (fs11.existsSync(libDir(root2))) {
8033
- fs11.cpSync(libDir(root2), path40.join(outDir, "lib"), { recursive: true });
8075
+ fs11.cpSync(libDir(root2), path41.join(outDir, "lib"), { recursive: true });
8034
8076
  included.push("lib/");
8035
8077
  }
8036
8078
  }
@@ -8042,15 +8084,15 @@ function registerBundle(program) {
8042
8084
  included,
8043
8085
  usage: "Run `vg build --grammars <this dir>/grammars` to build fully offline."
8044
8086
  };
8045
- fs11.writeFileSync(path40.join(outDir, "MANIFEST.json"), `${stableStringify(manifest, 2)}
8087
+ fs11.writeFileSync(path41.join(outDir, "MANIFEST.json"), `${stableStringify(manifest, 2)}
8046
8088
  `);
8047
8089
  if (global.json) {
8048
- json({ out: path40.relative(root2, outDir), ...manifest });
8090
+ json({ out: path41.relative(root2, outDir), ...manifest });
8049
8091
  return;
8050
8092
  }
8051
- info(`${c.cyan("vg bundle")} \xB7 wrote ${path40.relative(root2, outDir)}/`);
8093
+ info(`${c.cyan("vg bundle")} \xB7 wrote ${path41.relative(root2, outDir)}/`);
8052
8094
  for (const i of included) info(` ${c.green("\u2714")} ${i}`);
8053
- info(c.dim(` offline: vg build --grammars "${path40.relative(root2, outDir)}/grammars"`));
8095
+ info(c.dim(` offline: vg build --grammars "${path41.relative(root2, outDir)}/grammars"`));
8054
8096
  });
8055
8097
  applyGlobalOptions(cmd);
8056
8098
  }
@@ -8068,7 +8110,7 @@ async function runDoctor(global) {
8068
8110
  const root2 = rootOf(global);
8069
8111
  const local = global.local === true;
8070
8112
  const graphPath = resolveGraphPath(root2, global.graph);
8071
- const configFile = CONFIG_BASENAMES.find((f) => fs11.existsSync(path40.join(root2, f))) ?? null;
8113
+ const configFile = CONFIG_BASENAMES.find((f) => fs11.existsSync(path41.join(root2, f))) ?? null;
8072
8114
  const graph = loadGraph(root2, graphPath);
8073
8115
  let staleFiles = null;
8074
8116
  if (graph) {
@@ -8094,13 +8136,13 @@ async function runDoctor(global) {
8094
8136
  root: root2,
8095
8137
  configFile,
8096
8138
  map: {
8097
- path: path40.relative(root2, graphPath),
8139
+ path: path41.relative(root2, graphPath),
8098
8140
  built: graph !== null,
8099
8141
  generatedAt: graph?.generatedAt ?? null,
8100
8142
  staleFiles
8101
8143
  },
8102
8144
  libCatalog: {
8103
- path: path40.relative(root2, catalogPath(root2)),
8145
+ path: path41.relative(root2, catalogPath(root2)),
8104
8146
  present: fs11.existsSync(catalogPath(root2)),
8105
8147
  libraries: libCount
8106
8148
  },
@@ -8158,7 +8200,7 @@ async function runDoctor(global) {
8158
8200
  );
8159
8201
  info(
8160
8202
  ` host pool ${li.hostPool.size} warm session(s)` + (li.hostPool.sessions[0] ? c.dim(
8161
- ` \xB7 last ${path40.basename(li.hostPool.sessions[0].modelPath)} kv=${li.hostPool.sessions[0].kvBlocks}`
8203
+ ` \xB7 last ${path41.basename(li.hostPool.sessions[0].modelPath)} kv=${li.hostPool.sessions[0].kvBlocks}`
8162
8204
  ) : c.dim(" \xB7 none (load via vg code / vgd host-load)"))
8163
8205
  );
8164
8206
  if (li.dynamicOnToken || li.dynamicCustomSampler) {
@@ -8352,7 +8394,7 @@ function registerDaemon(program) {
8352
8394
  const register = cmd.command("register").description("register the current repository with a running vgd").argument("[root]", "repository root (default: cwd)").action(async function(rootArg) {
8353
8395
  const global = readGlobal(this);
8354
8396
  const socketPath = socketOf(this);
8355
- const root2 = path40.resolve(rootArg ?? rootOf(global));
8397
+ const root2 = path41.resolve(rootArg ?? rootOf(global));
8356
8398
  if (!await vgdIsRunning({ socketPath })) {
8357
8399
  throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
8358
8400
  }
@@ -8388,7 +8430,7 @@ function registerDaemon(program) {
8388
8430
  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) {
8389
8431
  const global = readGlobal(this);
8390
8432
  const socketPath = socketOf(this);
8391
- const primary = path40.resolve(rootArg ?? rootOf(global));
8433
+ const primary = path41.resolve(rootArg ?? rootOf(global));
8392
8434
  if (!await vgdIsRunning({ socketPath })) {
8393
8435
  throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
8394
8436
  }
@@ -8416,7 +8458,7 @@ function registerDaemon(program) {
8416
8458
  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) {
8417
8459
  const global = readGlobal(this);
8418
8460
  const socketPath = socketOf(this);
8419
- const root2 = path40.resolve(rootArg ?? rootOf(global));
8461
+ const root2 = path41.resolve(rootArg ?? rootOf(global));
8420
8462
  if (!await vgdIsRunning({ socketPath })) {
8421
8463
  throw new CliError(`vgd is not running \u2014 start it with \`vg daemon ensure\` (${socketPath})`, ExitCode.NOT_FOUND);
8422
8464
  }
@@ -8430,7 +8472,7 @@ function registerDaemon(program) {
8430
8472
  throw new CliError(loaded.error, ExitCode.NOT_FOUND);
8431
8473
  }
8432
8474
  if (!loaded.ok) {
8433
- const { loadGraph: loadGraph2 } = await import('./load-B6KY2WPG.js');
8475
+ const { loadGraph: loadGraph2 } = await import('./load-QBVKCWZT.js');
8434
8476
  const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
8435
8477
  const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
8436
8478
  const graph = loadGraph2(root2, global.graph);
@@ -8546,7 +8588,7 @@ function socketOf(cmd) {
8546
8588
  let c2 = cmd;
8547
8589
  while (c2) {
8548
8590
  const opts = c2.opts();
8549
- if (opts.socket) return path40.resolve(opts.socket);
8591
+ if (opts.socket) return path41.resolve(opts.socket);
8550
8592
  c2 = c2.parent;
8551
8593
  }
8552
8594
  return vgdSocketPath();
@@ -8823,11 +8865,11 @@ function registerLlmHost(program) {
8823
8865
  applyGlobalOptions(cmd);
8824
8866
  }
8825
8867
  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) => {
8826
- const rootDir = path40.resolve(targetPath);
8827
- const vibgrateDir2 = path40.join(rootDir, ".vibgrate");
8868
+ const rootDir = path41.resolve(targetPath);
8869
+ const vibgrateDir2 = path41.join(rootDir, ".vibgrate");
8828
8870
  await ensureDir(vibgrateDir2);
8829
8871
  console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold(".vibgrate/")} directory`);
8830
- const configPath = path40.join(rootDir, "vibgrate.config.ts");
8872
+ const configPath = path41.join(rootDir, "vibgrate.config.ts");
8831
8873
  if (await pathExists(configPath)) {
8832
8874
  console.log(chalk7.dim(" vibgrate.config.ts already exists, skipping"));
8833
8875
  } else {
@@ -8835,7 +8877,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
8835
8877
  console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
8836
8878
  }
8837
8879
  if (opts.baseline) {
8838
- const { runBaseline } = await import('./baseline-7C4F7PBS.js');
8880
+ const { runBaseline } = await import('./baseline-KVCXVZFQ.js');
8839
8881
  await runBaseline(rootDir);
8840
8882
  }
8841
8883
  console.log("");
@@ -8938,7 +8980,7 @@ function collectPackageImports(graph, ecosystem, pkg) {
8938
8980
  };
8939
8981
  }
8940
8982
  async function firstReferenceLine(rootDir, relFile, identifier, readFile3) {
8941
- const content = await readFile3(path40.join(rootDir, relFile));
8983
+ const content = await readFile3(path41.join(rootDir, relFile));
8942
8984
  if (!content) return null;
8943
8985
  const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8944
8986
  const re = new RegExp(`\\b${escaped}\\b`);
@@ -9174,7 +9216,7 @@ var AI_ASSISTANT_DETECTORS = [
9174
9216
  async function detectAiAssistant(rootDir) {
9175
9217
  for (const detector of AI_ASSISTANT_DETECTORS) {
9176
9218
  for (const file of detector.files) {
9177
- if (await pathExists$1(path40.join(rootDir, file))) {
9219
+ if (await pathExists$1(path41.join(rootDir, file))) {
9178
9220
  return detector.name;
9179
9221
  }
9180
9222
  }
@@ -9368,7 +9410,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
9368
9410
  collectExcludes,
9369
9411
  []
9370
9412
  ).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) => {
9371
- const rootDir = path40.resolve(targetPath);
9413
+ const rootDir = path41.resolve(targetPath);
9372
9414
  if (!await pathExists$1(rootDir)) {
9373
9415
  console.error(chalk7.red(`Path does not exist: ${rootDir}`));
9374
9416
  process.exit(1);
@@ -9376,7 +9418,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
9376
9418
  const hasDsn = !!resolveDsn(opts.dsn);
9377
9419
  const willPush = !opts.offline && (opts.push || hasDsn);
9378
9420
  const noLocalArtifacts = opts.localArtifacts === false;
9379
- const isFirstRun = !await pathExists$1(path40.join(rootDir, ".vibgrate", "scan_result.json"));
9421
+ const isFirstRun = !await pathExists$1(path41.join(rootDir, ".vibgrate", "scan_result.json"));
9380
9422
  let pinnedRegion;
9381
9423
  let planTier;
9382
9424
  let upgradeUrl;
@@ -9655,11 +9697,11 @@ function scanStaleness(rootDir, artifactPath) {
9655
9697
  scanned++;
9656
9698
  if (scanned > MAX_ENTRIES2) break;
9657
9699
  if (e.isDirectory()) {
9658
- if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(path40.join(dir, e.name), depth + 1);
9700
+ if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(path41.join(dir, e.name), depth + 1);
9659
9701
  continue;
9660
9702
  }
9661
9703
  if (!WATCHED_FILES.has(e.name) && !WATCHED_EXT.test(e.name)) continue;
9662
- const abs = path40.join(dir, e.name);
9704
+ const abs = path41.join(dir, e.name);
9663
9705
  let mtimeMs;
9664
9706
  try {
9665
9707
  mtimeMs = fs11.statSync(abs).mtimeMs;
@@ -9668,7 +9710,7 @@ function scanStaleness(rootDir, artifactPath) {
9668
9710
  }
9669
9711
  if (mtimeMs > newest) {
9670
9712
  newest = mtimeMs;
9671
- newestChanged = path40.relative(rootDir, abs) || e.name;
9713
+ newestChanged = path41.relative(rootDir, abs) || e.name;
9672
9714
  }
9673
9715
  }
9674
9716
  };
@@ -9808,13 +9850,13 @@ function analyzeTree(root2, packages) {
9808
9850
  if (filesSeen >= MAX_FILES) return;
9809
9851
  if (entry.isDirectory()) {
9810
9852
  if (SKIP_DIRS3.has(entry.name) || entry.name.startsWith(".")) continue;
9811
- walk2(path40.join(dir, entry.name), depth + 1);
9853
+ walk2(path41.join(dir, entry.name), depth + 1);
9812
9854
  continue;
9813
9855
  }
9814
- const fileEco = EXT_ECOSYSTEM[path40.extname(entry.name)];
9856
+ const fileEco = EXT_ECOSYSTEM[path41.extname(entry.name)];
9815
9857
  if (!fileEco || fileEco === "unknown") continue;
9816
9858
  filesSeen++;
9817
- const full = path40.join(dir, entry.name);
9859
+ const full = path41.join(dir, entry.name);
9818
9860
  let content;
9819
9861
  try {
9820
9862
  if (fs11.statSync(full).size > MAX_FILE_BYTES2) continue;
@@ -10129,7 +10171,7 @@ function applyPlan(rootDir, upgrades, opts = {}) {
10129
10171
  }
10130
10172
  const outcomes = effective.map((t) => {
10131
10173
  const c2 = pmCommandFor(u.ecosystem, u.package, u.to, opts.packageManager, { workspaceRoot: t.isWorkspaceRoot });
10132
- return { t, res: run(c2, path40.join(rootDir, t.dir)) };
10174
+ return { t, res: run(c2, path41.join(rootDir, t.dir)) };
10133
10175
  });
10134
10176
  const failures = outcomes.filter((o) => !o.res.ok);
10135
10177
  if (failures.length === 0) {
@@ -10158,8 +10200,8 @@ function applyPlan(rootDir, upgrades, opts = {}) {
10158
10200
  return results;
10159
10201
  }
10160
10202
  var REGISTRY_URL = "https://registry.npmjs.org/@vibgrate%2fcli/latest";
10161
- var CACHE_DIR = path40.join(os.homedir(), ".vibgrate");
10162
- var CACHE_FILE = path40.join(CACHE_DIR, "update-check.json");
10203
+ var CACHE_DIR = path41.join(os.homedir(), ".vibgrate");
10204
+ var CACHE_FILE = path41.join(CACHE_DIR, "update-check.json");
10163
10205
  async function fetchLatestVersion() {
10164
10206
  try {
10165
10207
  const controller = new AbortController();
@@ -10191,6 +10233,52 @@ async function writeCache(data) {
10191
10233
  } catch {
10192
10234
  }
10193
10235
  }
10236
+ var LOCK_ERROR_RE = /\b(EBUSY|EPERM|ETXTBSY|EACCES)\b|resource busy or locked|being used by another process|access is denied/i;
10237
+ function isFileLockError(output) {
10238
+ return LOCK_ERROR_RE.test(output);
10239
+ }
10240
+ function buildDeferredUpdateScript(opts) {
10241
+ const waitSeconds = opts.waitSeconds ?? 120;
10242
+ return [
10243
+ "@echo off",
10244
+ "setlocal",
10245
+ `set "VG_PID=${opts.pid}"`,
10246
+ `set "VG_LOG=${opts.logPath}"`,
10247
+ 'echo Waiting for vg (pid %VG_PID%) to exit so its locked files can be replaced...> "%VG_LOG%"',
10248
+ `for /l %%i in (1,1,${waitSeconds}) do (`,
10249
+ ' tasklist /FI "PID eq %VG_PID%" /NH 2>nul | find "%VG_PID%" >nul || goto :run',
10250
+ " ping -n 2 127.0.0.1 >nul",
10251
+ ")",
10252
+ ":run",
10253
+ `echo Running: ${opts.command}>> "%VG_LOG%"`,
10254
+ `call ${opts.command} >> "%VG_LOG%" 2>&1`,
10255
+ "if errorlevel 1 (",
10256
+ ' echo.>> "%VG_LOG%"',
10257
+ ' echo Update FAILED. See the npm output above.>> "%VG_LOG%"',
10258
+ ") else (",
10259
+ ' echo.>> "%VG_LOG%"',
10260
+ ' echo Update complete.>> "%VG_LOG%"',
10261
+ ")",
10262
+ ""
10263
+ ].join("\r\n");
10264
+ }
10265
+ function scheduleDeferredUpdate(command, pid = process.pid, dir = os.tmpdir()) {
10266
+ const stamp = `${pid}-${process.hrtime.bigint().toString(36)}`;
10267
+ const scriptPath = path41.join(dir, `vg-update-${stamp}.cmd`);
10268
+ const logPath = path41.join(dir, `vg-update-${stamp}.log`);
10269
+ try {
10270
+ fs11.writeFileSync(scriptPath, buildDeferredUpdateScript({ pid, command, logPath }), "utf8");
10271
+ const child = spawn(process.env.ComSpec || "cmd.exe", ["/d", "/s", "/c", scriptPath], {
10272
+ detached: true,
10273
+ stdio: "ignore",
10274
+ windowsHide: true
10275
+ });
10276
+ child.unref();
10277
+ return { scriptPath, logPath };
10278
+ } catch {
10279
+ return null;
10280
+ }
10281
+ }
10194
10282
 
10195
10283
  // src/reporting/commands/update.ts
10196
10284
  var PACKAGE_NAME = "@vibgrate/cli";
@@ -10232,14 +10320,14 @@ async function findGlobalInstall(pkg = PACKAGE_NAME, run = defaultRunner) {
10232
10320
  pm: "yarn",
10233
10321
  root: () => {
10234
10322
  const dir = tryRun("yarn global dir");
10235
- return dir ? path40.join(dir, "node_modules") : null;
10323
+ return dir ? path41.join(dir, "node_modules") : null;
10236
10324
  }
10237
10325
  },
10238
- { pm: "bun", root: () => path40.join(os.homedir(), ".bun", "install", "global", "node_modules") }
10326
+ { pm: "bun", root: () => path41.join(os.homedir(), ".bun", "install", "global", "node_modules") }
10239
10327
  ];
10240
10328
  for (const probe of probes) {
10241
10329
  const root2 = probe.root();
10242
- if (root2 && await pathExists(path40.join(root2, pkg))) return probe.pm;
10330
+ if (root2 && await pathExists(path41.join(root2, pkg))) return probe.pm;
10243
10331
  }
10244
10332
  return null;
10245
10333
  }
@@ -10258,15 +10346,15 @@ function getGlobalUpdateCommand(pm, pkg, version) {
10258
10346
  }
10259
10347
  }
10260
10348
  async function detectPackageManager(cwd) {
10261
- if (await pathExists(path40.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
10262
- if (await pathExists(path40.join(cwd, "bun.lockb"))) return "bun";
10263
- if (await pathExists(path40.join(cwd, "yarn.lock"))) return "yarn";
10349
+ if (await pathExists(path41.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
10350
+ if (await pathExists(path41.join(cwd, "bun.lockb"))) return "bun";
10351
+ if (await pathExists(path41.join(cwd, "yarn.lock"))) return "yarn";
10264
10352
  return "npm";
10265
10353
  }
10266
10354
  async function detectWorkspaceRoot(cwd) {
10267
- if (await pathExists(path40.join(cwd, "pnpm-workspace.yaml"))) return true;
10355
+ if (await pathExists(path41.join(cwd, "pnpm-workspace.yaml"))) return true;
10268
10356
  try {
10269
- const pkgPath = path40.join(cwd, "package.json");
10357
+ const pkgPath = path41.join(cwd, "package.json");
10270
10358
  const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
10271
10359
  const pkg = JSON.parse(raw);
10272
10360
  return pkg.workspaces != null;
@@ -10293,7 +10381,7 @@ function getInstallCommand(pm, pkg, version, isDev, opts = {}) {
10293
10381
  }
10294
10382
  async function getLocalDependencyState(cwd, pkg = PACKAGE_NAME) {
10295
10383
  try {
10296
- const pkgPath = path40.join(cwd, "package.json");
10384
+ const pkgPath = path41.join(cwd, "package.json");
10297
10385
  const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
10298
10386
  const parsed = JSON.parse(raw);
10299
10387
  if (parsed.devDependencies?.[pkg]) return "dev";
@@ -10303,16 +10391,84 @@ async function getLocalDependencyState(cwd, pkg = PACKAGE_NAME) {
10303
10391
  return null;
10304
10392
  }
10305
10393
  async function confirmWorkspaceRoot(pm) {
10394
+ return confirm3(`Update the ${pm} workspace root with -w? [y/N]: `);
10395
+ }
10396
+ async function confirm3(question) {
10306
10397
  if (!(process.stdin.isTTY && process.stdout.isTTY)) return false;
10307
10398
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
10308
10399
  return new Promise((resolve21) => {
10309
- rl.question(chalk7.yellow(`Update the ${pm} workspace root with -w? [y/N]: `), (ans) => {
10400
+ rl.question(chalk7.yellow(question), (ans) => {
10310
10401
  rl.close();
10311
10402
  const t = ans.trim().toLowerCase();
10312
10403
  resolve21(t === "y" || t === "yes");
10313
10404
  });
10314
10405
  });
10315
10406
  }
10407
+ var CAPTURED_OUTPUT_LIMIT = 64e3;
10408
+ async function runInstall(cmd, cwd) {
10409
+ const { spawn: spawn5 } = await import('child_process');
10410
+ return new Promise((resolve21) => {
10411
+ const child = spawn5(cmd, { cwd, shell: true, stdio: ["inherit", "pipe", "pipe"] });
10412
+ let output = "";
10413
+ const tee = (src, dest) => {
10414
+ if (!src) return;
10415
+ src.setEncoding("utf8");
10416
+ src.on("data", (chunk) => {
10417
+ dest.write(chunk);
10418
+ output += chunk;
10419
+ if (output.length > CAPTURED_OUTPUT_LIMIT) output = output.slice(-CAPTURED_OUTPUT_LIMIT);
10420
+ });
10421
+ };
10422
+ tee(child.stdout, process.stdout);
10423
+ tee(child.stderr, process.stderr);
10424
+ child.on("error", (err) => resolve21({ ok: false, output: `${output}
10425
+ ${String(err)}` }));
10426
+ child.on("close", (code) => resolve21({ ok: code === 0, output }));
10427
+ });
10428
+ }
10429
+ async function releaseWindowsFileLocks(cwd, keepVersion) {
10430
+ reapAndReport(cwd, keepVersion);
10431
+ try {
10432
+ const { vgdSocketPath: vgdSocketPath2 } = await import('./vgd-54GEZWBI.js');
10433
+ const result = await stopVgd(vgdSocketPath2());
10434
+ if (result === "stopped") {
10435
+ console.log(chalk7.dim("Stopped the vgd daemon so its files can be replaced \u2014 it restarts on the next command."));
10436
+ } else if (result === "refused") {
10437
+ console.log(
10438
+ chalk7.dim(
10439
+ "A vgd embedded in another process (e.g. vg code) is running \u2014 close that session if the update reports a locked file."
10440
+ )
10441
+ );
10442
+ }
10443
+ } catch {
10444
+ }
10445
+ }
10446
+ async function offerDeferredWindowsUpdate(cmd, assumeYes) {
10447
+ console.error(
10448
+ chalk7.yellow("\nWindows could not replace a file that is still in use.") + chalk7.dim(
10449
+ "\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."
10450
+ )
10451
+ );
10452
+ const proceed = assumeYes || await confirm3("Finish the update automatically after vg exits? [y/N]: ");
10453
+ if (!proceed) {
10454
+ console.error(
10455
+ chalk7.dim(
10456
+ "Skipped. To update manually, close every terminal and editor running vg (including\nMCP servers started by your AI client), then run:\n " + cmd
10457
+ )
10458
+ );
10459
+ return false;
10460
+ }
10461
+ const scheduled = scheduleDeferredUpdate(cmd);
10462
+ if (!scheduled) {
10463
+ console.error(chalk7.red(`Could not schedule the deferred update. Run manually once vg is closed: ${cmd}`));
10464
+ return false;
10465
+ }
10466
+ console.log(
10467
+ chalk7.green("\u2714") + " Update scheduled \u2014 it runs as soon as this process exits.\n" + chalk7.dim(` Transcript: ${scheduled.logPath}
10468
+ `) + chalk7.dim(' Check the new version with "vg --version" in a few seconds.')
10469
+ );
10470
+ return true;
10471
+ }
10316
10472
  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(
10317
10473
  async (opts) => {
10318
10474
  console.log(chalk7.dim(`Current version: ${VERSION}`));
@@ -10374,10 +10530,16 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
10374
10530
  cmd = getInstallCommand(pm, PACKAGE_NAME, latest, isDev, { workspaceRoot });
10375
10531
  console.log(chalk7.dim(`Using ${pm}: ${cmd}`));
10376
10532
  }
10377
- try {
10378
- execSync(cmd, { cwd, stdio: "inherit" });
10533
+ if (process.platform === "win32" && isGlobal && opts.reap !== false) {
10534
+ await releaseWindowsFileLocks(cwd, latest);
10535
+ }
10536
+ const install = await runInstall(cmd, cwd);
10537
+ if (install.ok) {
10379
10538
  console.log(chalk7.green("\u2714") + ` Updated to ${PACKAGE_NAME}@${latest}`);
10380
- } catch {
10539
+ } else if (process.platform === "win32" && isFileLockError(install.output)) {
10540
+ const scheduled = await offerDeferredWindowsUpdate(cmd, Boolean(opts.yes));
10541
+ process.exit(scheduled ? 0 : 1);
10542
+ } else {
10381
10543
  console.error(chalk7.red(`Update failed. Run manually: ${cmd}`));
10382
10544
  process.exit(1);
10383
10545
  }
@@ -10392,7 +10554,7 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
10392
10554
  );
10393
10555
  async function rewarmVgdAndReport(cwd) {
10394
10556
  try {
10395
- const { vgdIsRunning: vgdIsRunning2, vgdRequest: vgdRequest2 } = await import('./vgd-BCBVZ2QA.js');
10557
+ const { vgdIsRunning: vgdIsRunning2, vgdRequest: vgdRequest2 } = await import('./vgd-54GEZWBI.js');
10396
10558
  if (!await vgdIsRunning2()) return;
10397
10559
  const loaded = await vgdRequest2({ op: "load-graph", root: cwd });
10398
10560
  if (!loaded.ok || !("repositoryId" in loaded)) return;
@@ -10481,13 +10643,13 @@ function collectCandidates(artifact) {
10481
10643
  return out2;
10482
10644
  }
10483
10645
  var defaultFixScanner = async (rootDir) => {
10484
- const scratch = path40.join(os.tmpdir(), `vg-fix-scan-${process.pid}.json`);
10646
+ const scratch = path41.join(os.tmpdir(), `vg-fix-scan-${process.pid}.json`);
10485
10647
  const scanOpts = { vibgrateVersion: VERSION, format: "json", out: scratch, quiet: true, concurrency: 8 };
10486
10648
  const advanced = await loadAdvancedScanHook();
10487
10649
  return runCoreScan(rootDir, scanOpts, advanced);
10488
10650
  };
10489
10651
  async function loadArtifact(rootDir, inFile, scan = defaultFixScanner) {
10490
- const artifactPath = path40.isAbsolute(inFile) ? inFile : path40.join(rootDir, inFile);
10652
+ const artifactPath = path41.isAbsolute(inFile) ? inFile : path41.join(rootDir, inFile);
10491
10653
  if (await pathExists(artifactPath)) {
10492
10654
  const staleness = scanStaleness(rootDir, artifactPath);
10493
10655
  if (!staleness.stale) {
@@ -10514,7 +10676,7 @@ async function repositoryIdentity(rootDir, override) {
10514
10676
  }
10515
10677
  }
10516
10678
  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) => {
10517
- const rootDir = path40.resolve(targetPath);
10679
+ const rootDir = path41.resolve(targetPath);
10518
10680
  if (!await pathExists(rootDir)) {
10519
10681
  console.error(chalk7.red(`Path does not exist: ${rootDir}`));
10520
10682
  process.exit(1);
@@ -10675,7 +10837,7 @@ function emit(report, format) {
10675
10837
  }
10676
10838
  }
10677
10839
  function relProjectDir(rootDir, projectPath) {
10678
- const rel = path40.isAbsolute(projectPath) ? path40.relative(rootDir, projectPath) : projectPath;
10840
+ const rel = path41.isAbsolute(projectPath) ? path41.relative(rootDir, projectPath) : projectPath;
10679
10841
  return rel === "" ? "." : rel;
10680
10842
  }
10681
10843
  async function buildTargetResolver(rootDir, artifact) {
@@ -11510,7 +11672,7 @@ function formatMarkdown(artifact) {
11510
11672
 
11511
11673
  // src/reporting/commands/report.ts
11512
11674
  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) => {
11513
- const artifactPath = path40.resolve(opts.in);
11675
+ const artifactPath = path41.resolve(opts.in);
11514
11676
  if (!await pathExists(artifactPath)) {
11515
11677
  console.error(chalk7.red(`Artifact not found: ${artifactPath}`));
11516
11678
  console.error(chalk7.dim('Run "vibgrate scan" first to generate a scan artifact.'));
@@ -11559,8 +11721,8 @@ function openUrl(url) {
11559
11721
  // src/reporting/commands/login.ts
11560
11722
  var delay = (ms) => new Promise((resolve21) => setTimeout(resolve21, ms));
11561
11723
  function isInside(dir, file) {
11562
- const rel = path40.relative(dir, file);
11563
- return !!rel && !rel.startsWith("..") && !path40.isAbsolute(rel);
11724
+ const rel = path41.relative(dir, file);
11725
+ return !!rel && !rel.startsWith("..") && !path41.isAbsolute(rel);
11564
11726
  }
11565
11727
  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(
11566
11728
  "--local",
@@ -11815,7 +11977,7 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
11815
11977
  try {
11816
11978
  const statements = [];
11817
11979
  if (opts.from) {
11818
- const fromPath = path40.resolve(opts.from);
11980
+ const fromPath = path41.resolve(opts.from);
11819
11981
  if (!await pathExists(fromPath)) {
11820
11982
  process.stderr.write(chalk7.red(`Statements file not found: ${fromPath}
11821
11983
  `));
@@ -11833,9 +11995,9 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
11833
11995
  });
11834
11996
  const json2 = JSON.stringify(doc, null, 2);
11835
11997
  if (opts.out) {
11836
- await writeTextFile(path40.resolve(opts.out), json2 + "\n");
11998
+ await writeTextFile(path41.resolve(opts.out), json2 + "\n");
11837
11999
  process.stderr.write(
11838
- chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${path40.resolve(opts.out)}
12000
+ chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${path41.resolve(opts.out)}
11839
12001
  `
11840
12002
  );
11841
12003
  } else {
@@ -12018,7 +12180,7 @@ function formatDeltaText(base, current) {
12018
12180
  return lines.join("\n");
12019
12181
  }
12020
12182
  async function readArtifactOrExit(filePath) {
12021
- const absolutePath = path40.resolve(filePath);
12183
+ const absolutePath = path41.resolve(filePath);
12022
12184
  if (!await pathExists(absolutePath)) {
12023
12185
  console.error(chalk7.red(`Artifact not found: ${absolutePath}`));
12024
12186
  process.exit(1);
@@ -12035,7 +12197,7 @@ var exportCommand = new Command("export").description("Export scan artifact as S
12035
12197
  const sbom = format === "cyclonedx" ? toCycloneDx(artifact) : toSpdx(artifact);
12036
12198
  const body = JSON.stringify(sbom, null, 2);
12037
12199
  if (opts.out) {
12038
- await writeTextFile(path40.resolve(opts.out), body);
12200
+ await writeTextFile(path41.resolve(opts.out), body);
12039
12201
  console.log(chalk7.green("\u2714") + ` SBOM written to ${opts.out}`);
12040
12202
  } else {
12041
12203
  console.log(body);
@@ -12046,7 +12208,7 @@ var deltaCommand = new Command("delta").description("Show SBOM delta between two
12046
12208
  const current = await readArtifactOrExit(opts.to);
12047
12209
  const report = formatDeltaText(base, current);
12048
12210
  if (opts.out) {
12049
- await writeTextFile(path40.resolve(opts.out), report);
12211
+ await writeTextFile(path41.resolve(opts.out), report);
12050
12212
  console.log(chalk7.green("\u2714") + ` SBOM delta report written to ${opts.out}`);
12051
12213
  } else {
12052
12214
  console.log(report);
@@ -12177,20 +12339,20 @@ function resolveRegime(id) {
12177
12339
  return regime;
12178
12340
  }
12179
12341
  function evidenceDir(root2) {
12180
- return path40.join(root2, ".vibgrate", "evidence");
12342
+ return path41.join(root2, ".vibgrate", "evidence");
12181
12343
  }
12182
12344
  function orgPath(root2) {
12183
- return path40.join(evidenceDir(root2), "org.json");
12345
+ return path41.join(evidenceDir(root2), "org.json");
12184
12346
  }
12185
12347
  function productsPath(root2) {
12186
- return path40.join(evidenceDir(root2), "products.json");
12348
+ return path41.join(evidenceDir(root2), "products.json");
12187
12349
  }
12188
12350
  function releasesDir(root2) {
12189
- return path40.join(evidenceDir(root2), "releases");
12351
+ return path41.join(evidenceDir(root2), "releases");
12190
12352
  }
12191
12353
  function releasePath(root2, productId, version) {
12192
12354
  const safe = `${productId}@${version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
12193
- return path40.join(releasesDir(root2), `${safe}.json`);
12355
+ return path41.join(releasesDir(root2), `${safe}.json`);
12194
12356
  }
12195
12357
  var DEFAULT_ORG = {
12196
12358
  responsiblePersons: [],
@@ -12221,7 +12383,7 @@ async function freezeRelease(root2, release) {
12221
12383
  const p = releasePath(root2, release.productId, release.version);
12222
12384
  if (await pathExists(p)) {
12223
12385
  throw new CliError(
12224
- `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`,
12386
+ `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`,
12225
12387
  ExitCode.USAGE_ERROR
12226
12388
  );
12227
12389
  }
@@ -12235,7 +12397,7 @@ async function loadReleases(root2, productId) {
12235
12397
  const files = (await readdir(dir)).filter((f) => f.endsWith(".json")).sort();
12236
12398
  const releases = [];
12237
12399
  for (const f of files) {
12238
- const rel = await readJsonFile(path40.join(dir, f));
12400
+ const rel = await readJsonFile(path41.join(dir, f));
12239
12401
  if (!productId || rel.productId === productId) releases.push(rel);
12240
12402
  }
12241
12403
  return releases;
@@ -12930,12 +13092,12 @@ function verifyEvidenceEnvelope(env, opts = {}) {
12930
13092
  var DEFAULT_KEY = "attest-key.pem";
12931
13093
  function resolveSigningKey(root2, explicit) {
12932
13094
  const chosen = process.env.VG_ATTEST_KEY;
12933
- const keyPath = chosen ? path40.resolve(chosen) : path40.join(root2, ".vibgrate", DEFAULT_KEY);
13095
+ const keyPath = chosen ? path41.resolve(chosen) : path41.join(root2, ".vibgrate", DEFAULT_KEY);
12934
13096
  let minted = false;
12935
13097
  if (!fs11.existsSync(keyPath)) {
12936
13098
  if (chosen) throw new CliError(`signing key not found: ${chosen}`, ExitCode.USAGE_ERROR);
12937
13099
  const kp = generateKeypair();
12938
- fs11.mkdirSync(path40.dirname(keyPath), { recursive: true });
13100
+ fs11.mkdirSync(path41.dirname(keyPath), { recursive: true });
12939
13101
  fs11.writeFileSync(keyPath, kp.privatePem, { mode: 384 });
12940
13102
  fs11.writeFileSync(`${keyPath}.pub`, kp.publicPem);
12941
13103
  minted = true;
@@ -12953,16 +13115,16 @@ function resolveSigningKey(root2, explicit) {
12953
13115
  }
12954
13116
  function writeBundle(input) {
12955
13117
  const dir = input.outDir;
12956
- fs11.mkdirSync(path40.join(dir, "inputs", "releases"), { recursive: true });
12957
- const write = (rel, data) => fs11.writeFileSync(path40.join(dir, rel), `${JSON.stringify(data, null, 2)}
13118
+ fs11.mkdirSync(path41.join(dir, "inputs", "releases"), { recursive: true });
13119
+ const write = (rel, data) => fs11.writeFileSync(path41.join(dir, rel), `${JSON.stringify(data, null, 2)}
12958
13120
  `);
12959
13121
  write("result.json", input.result);
12960
- write(path40.join("inputs", "advisory.json"), input.advisory);
13122
+ write(path41.join("inputs", "advisory.json"), input.advisory);
12961
13123
  for (const rel of input.releases) {
12962
13124
  const safe = `${rel.productId}@${rel.version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
12963
- write(path40.join("inputs", "releases", `${safe}.json`), rel);
13125
+ write(path41.join("inputs", "releases", `${safe}.json`), rel);
12964
13126
  }
12965
- write(path40.join("inputs", "datapack.lock"), { dataPackVersion: input.result.meta.dataPackVersion, kernelVersion: input.result.meta.kernelVersion });
13127
+ write(path41.join("inputs", "datapack.lock"), { dataPackVersion: input.result.meta.dataPackVersion, kernelVersion: input.result.meta.kernelVersion });
12966
13128
  write("provenance.json", {
12967
13129
  method: "deterministic",
12968
13130
  modelDrafted: [],
@@ -12978,13 +13140,13 @@ function writeBundle(input) {
12978
13140
  disclaimer: input.regime.disclaimer
12979
13141
  });
12980
13142
  if (input.envelope) {
12981
- fs11.writeFileSync(path40.join(dir, "evidence.intoto.jsonl"), `${JSON.stringify(input.envelope)}
13143
+ fs11.writeFileSync(path41.join(dir, "evidence.intoto.jsonl"), `${JSON.stringify(input.envelope)}
12982
13144
  `);
12983
13145
  }
12984
13146
  if (input.timestampToken) {
12985
- fs11.writeFileSync(path40.join(dir, "timestamp.tsr"), input.timestampToken);
13147
+ fs11.writeFileSync(path41.join(dir, "timestamp.tsr"), input.timestampToken);
12986
13148
  }
12987
- fs11.writeFileSync(path40.join(dir, "VERIFY.md"), verifyDoc(input));
13149
+ fs11.writeFileSync(path41.join(dir, "VERIFY.md"), verifyDoc(input));
12988
13150
  return dir;
12989
13151
  }
12990
13152
  function verifyDoc(input) {
@@ -13045,13 +13207,13 @@ function undeterminedFields(result, regime) {
13045
13207
  return gaps.filter((g) => regime.submission.requires.some((r) => g.startsWith(r)) || g.startsWith("exposure") || g.startsWith("member"));
13046
13208
  }
13047
13209
  async function recordDrill(root2, record) {
13048
- const dir = path40.join(evidenceDir(root2), "drills");
13049
- const p = path40.join(dir, `${record.drillId}.json`);
13210
+ const dir = path41.join(evidenceDir(root2), "drills");
13211
+ const p = path41.join(dir, `${record.drillId}.json`);
13050
13212
  await writeJsonFile(p, record);
13051
13213
  return p;
13052
13214
  }
13053
13215
  async function hasRecentDrill(root2, asOf) {
13054
- const dir = path40.join(evidenceDir(root2), "drills");
13216
+ const dir = path41.join(evidenceDir(root2), "drills");
13055
13217
  if (!await pathExists(dir)) return void 0;
13056
13218
  const { readdir } = await import('fs/promises');
13057
13219
  const { readJsonFile: readJsonFile2 } = await import('./fs-4G5A65KS.js');
@@ -13059,7 +13221,7 @@ async function hasRecentDrill(root2, asOf) {
13059
13221
  if (files.length === 0) return void 0;
13060
13222
  const cutoff = new Date(new Date(asOf).getTime() - 90 * 24 * 3600 * 1e3).toISOString();
13061
13223
  for (const f of files) {
13062
- const rec = await readJsonFile2(path40.join(dir, f));
13224
+ const rec = await readJsonFile2(path41.join(dir, f));
13063
13225
  if (rec.ranAt >= cutoff) return true;
13064
13226
  }
13065
13227
  return false;
@@ -13139,7 +13301,7 @@ function formatRegimeList() {
13139
13301
 
13140
13302
  // src/reporting/commands/evidence/index.ts
13141
13303
  function root(opts) {
13142
- return path40.resolve(opts.cwd ?? process.cwd());
13304
+ return path41.resolve(opts.cwd ?? process.cwd());
13143
13305
  }
13144
13306
  function slug(name) {
13145
13307
  return name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "product";
@@ -13227,7 +13389,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
13227
13389
  const release = await buildRelease({
13228
13390
  productId: product.id,
13229
13391
  version,
13230
- from: path40.resolve(rootDir, opts.from),
13392
+ from: path41.resolve(rootDir, opts.from),
13231
13393
  shipDate: opts.shipDate,
13232
13394
  buildId: opts.buildId,
13233
13395
  artefactDigest: opts.digest,
@@ -13235,7 +13397,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
13235
13397
  frozenAt: nowIso()
13236
13398
  });
13237
13399
  const p = await freezeRelease(rootDir, release);
13238
- console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${path40.relative(rootDir, p)}`);
13400
+ console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${path41.relative(rootDir, p)}`);
13239
13401
  });
13240
13402
  async function runExposure(rootDir, vuln, opts) {
13241
13403
  const org = await loadOrg(rootDir);
@@ -13287,7 +13449,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
13287
13449
  console.log("\n" + buildPack(result, regime, org, stage));
13288
13450
  }
13289
13451
  if (opts.bundle) {
13290
- const dir = path40.resolve(rootDir, opts.bundle, `evidence-${result.meta.evidenceId}`);
13452
+ const dir = path41.resolve(rootDir, opts.bundle, `evidence-${result.meta.evidenceId}`);
13291
13453
  let envelope;
13292
13454
  if (opts.sign !== false) {
13293
13455
  const { key: key2, minted } = resolveSigningKey(rootDir);
@@ -13295,7 +13457,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
13295
13457
  envelope = signEvidenceStatement(buildEvidenceStatement(result, VERSION), key2);
13296
13458
  }
13297
13459
  writeBundle({ outDir: dir, result, advisory, releases, regime, envelope, timestampToken, cliVersion: VERSION });
13298
- console.error(chalk7.green("\u2714") + ` evidence bundle written to ${path40.relative(rootDir, dir)}${envelope ? " (signed)" : " (unsigned)"}${timestampToken ? " \xB7 RFC 3161" : ""}`);
13460
+ console.error(chalk7.green("\u2714") + ` evidence bundle written to ${path41.relative(rootDir, dir)}${envelope ? " (signed)" : " (unsigned)"}${timestampToken ? " \xB7 RFC 3161" : ""}`);
13299
13461
  }
13300
13462
  process.exitCode = exposureExit(result.overallStatus);
13301
13463
  });
@@ -13327,7 +13489,7 @@ var packCmd = new Command("pack").description("Build the submission pack a human
13327
13489
  const stage = opts.stage ?? regime.clocks[0]?.stage ?? "early-warning";
13328
13490
  const md = buildPack(result, regime, org, stage);
13329
13491
  if (opts.out) {
13330
- fs11.writeFileSync(path40.resolve(rootDir, opts.out), md);
13492
+ fs11.writeFileSync(path41.resolve(rootDir, opts.out), md);
13331
13493
  console.error(chalk7.green("\u2714") + ` pack written to ${opts.out}`);
13332
13494
  } else {
13333
13495
  console.log(md);
@@ -13369,18 +13531,18 @@ var drillCmd = new Command("drill").description("Timed dry-run of the determinat
13369
13531
  }
13370
13532
  });
13371
13533
  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) => {
13372
- const abs = path40.resolve(bundlePath);
13373
- const envPath = fs11.statSync(abs).isDirectory() ? path40.join(abs, "evidence.intoto.jsonl") : abs;
13534
+ const abs = path41.resolve(bundlePath);
13535
+ const envPath = fs11.statSync(abs).isDirectory() ? path41.join(abs, "evidence.intoto.jsonl") : abs;
13374
13536
  if (!fs11.existsSync(envPath)) throw new CliError(`no evidence.intoto.jsonl at ${bundlePath}`, ExitCode.NOT_FOUND);
13375
13537
  const envelope = JSON.parse(fs11.readFileSync(envPath, "utf8").trim().split("\n")[0]);
13376
- const resultPath = path40.join(path40.dirname(envPath), "result.json");
13538
+ const resultPath = path41.join(path41.dirname(envPath), "result.json");
13377
13539
  const result = fs11.existsSync(resultPath) ? JSON.parse(fs11.readFileSync(resultPath, "utf8")) : void 0;
13378
- const publicKeyPem = opts.pub ? fs11.readFileSync(path40.resolve(opts.pub), "utf8") : void 0;
13540
+ const publicKeyPem = opts.pub ? fs11.readFileSync(path41.resolve(opts.pub), "utf8") : void 0;
13379
13541
  const v = verifyEvidenceEnvelope(envelope, { publicKeyPem, result });
13380
13542
  const color = v.status === "verified" ? chalk7.green : v.status === "failed" ? chalk7.red : chalk7.yellow;
13381
13543
  console.log(" " + color(v.status.toUpperCase()) + ` ${v.reason}`);
13382
13544
  if (v.evidenceId) console.log(" " + chalk7.dim(`evidence ${v.evidenceId} \xB7 regime ${v.regime} \xB7 advisory ${v.advisoryId} \xB7 ${v.overallStatus}`));
13383
- const tsrPath = path40.join(path40.dirname(envPath), "timestamp.tsr");
13545
+ const tsrPath = path41.join(path41.dirname(envPath), "timestamp.tsr");
13384
13546
  if (fs11.existsSync(tsrPath) && result) {
13385
13547
  const t = verifyTimestamp(fs11.readFileSync(tsrPath), exposureSubjectDigest(result));
13386
13548
  const tcolor = t.imprintMatches ? chalk7.green : chalk7.red;
@@ -13449,12 +13611,12 @@ var exportCmd = new Command("export").description("Air-gap bundle of all evidenc
13449
13611
  const releases = [];
13450
13612
  for (const list of releasesByProduct.values()) releases.push(...list);
13451
13613
  const report = computeReadiness({ regime, org, products, releasesByProduct, recentDrill: await hasRecentDrill(rootDir, today()) });
13452
- const dir = path40.resolve(rootDir, opts.out);
13453
- await writeJsonFile(path40.join(dir, "org.json"), org);
13454
- await writeJsonFile(path40.join(dir, "products.json"), products);
13455
- for (const r of releases) await writeJsonFile(path40.join(dir, "releases", `${r.productId}@${r.version}.json`.replace(/[^A-Za-z0-9._@-]/g, "_")), r);
13456
- await writeJsonFile(path40.join(dir, "readiness.json"), report);
13457
- console.error(chalk7.green("\u2714") + ` exported evidence state to ${path40.relative(rootDir, dir)} (${products.length} products, ${releases.length} frozen releases)`);
13614
+ const dir = path41.resolve(rootDir, opts.out);
13615
+ await writeJsonFile(path41.join(dir, "org.json"), org);
13616
+ await writeJsonFile(path41.join(dir, "products.json"), products);
13617
+ for (const r of releases) await writeJsonFile(path41.join(dir, "releases", `${r.productId}@${r.version}.json`.replace(/[^A-Za-z0-9._@-]/g, "_")), r);
13618
+ await writeJsonFile(path41.join(dir, "readiness.json"), report);
13619
+ console.error(chalk7.green("\u2714") + ` exported evidence state to ${path41.relative(rootDir, dir)} (${products.length} products, ${releases.length} frozen releases)`);
13458
13620
  });
13459
13621
  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) => {
13460
13622
  const rootDir = root(opts);
@@ -13480,8 +13642,8 @@ var pushCmd = new Command("push").description("Push the product registry (and an
13480
13642
  }));
13481
13643
  let exposure;
13482
13644
  if (opts.result) {
13483
- const raw = path40.resolve(rootDir, opts.result);
13484
- const resultPath = fs11.existsSync(raw) && fs11.statSync(raw).isDirectory() ? path40.join(raw, "result.json") : raw;
13645
+ const raw = path41.resolve(rootDir, opts.result);
13646
+ const resultPath = fs11.existsSync(raw) && fs11.statSync(raw).isDirectory() ? path41.join(raw, "result.json") : raw;
13485
13647
  if (!fs11.existsSync(resultPath)) throw new CliError(`no result.json at ${opts.result}`, ExitCode.NOT_FOUND);
13486
13648
  exposure = JSON.parse(fs11.readFileSync(resultPath, "utf8"));
13487
13649
  }
@@ -13677,7 +13839,7 @@ function dispatch(argv, cwd) {
13677
13839
  }
13678
13840
  const looksLikeQuestion = /\s/.test(first) || first.endsWith("?");
13679
13841
  if (looksLikeQuestion) return ["ask", ...args];
13680
- if (fs11.existsSync(path40.resolve(cwd, first))) {
13842
+ if (fs11.existsSync(path41.resolve(cwd, first))) {
13681
13843
  return [hasBuildOnlyFlag(args) ? "build" : "scan", ...args];
13682
13844
  }
13683
13845
  const moved = MOVED_COMMANDS[first];
@@ -13722,9 +13884,9 @@ async function main(argv = process.argv) {
13722
13884
  }
13723
13885
  function readCwd(raw) {
13724
13886
  const i = raw.findIndex((a) => a === "-C" || a === "--cwd");
13725
- if (i >= 0 && raw[i + 1]) return path40.resolve(raw[i + 1]);
13887
+ if (i >= 0 && raw[i + 1]) return path41.resolve(raw[i + 1]);
13726
13888
  const eq = raw.find((a) => a.startsWith("--cwd="));
13727
- if (eq) return path40.resolve(eq.slice("--cwd=".length));
13889
+ if (eq) return path41.resolve(eq.slice("--cwd=".length));
13728
13890
  return process.cwd();
13729
13891
  }
13730
13892
  function handleError(err) {