@vibgrate/cli 2026.727.1 → 2026.727.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/DOCS.md +21 -18
  2. package/README.md +2 -2
  3. package/dist/baseline-ATM5MXBZ.js +8 -0
  4. package/dist/{baseline-K7YBFKZI.js.map → baseline-ATM5MXBZ.js.map} +1 -1
  5. package/dist/{chunk-OXQNQW5J.js → chunk-2VFWXNS5.js} +4 -4
  6. package/dist/{chunk-OXQNQW5J.js.map → chunk-2VFWXNS5.js.map} +1 -1
  7. package/dist/{chunk-VXGV6NTD.js → chunk-3V24O47U.js} +11 -9
  8. package/dist/chunk-3V24O47U.js.map +1 -0
  9. package/dist/{chunk-C4CKTAZP.js → chunk-6JIKUDWM.js} +4 -4
  10. package/dist/chunk-6JIKUDWM.js.map +1 -0
  11. package/dist/{chunk-6IOQJGFT.js → chunk-6UK6QPTR.js} +96 -140
  12. package/dist/chunk-6UK6QPTR.js.map +1 -0
  13. package/dist/chunk-6UQMXIAG.js +122 -0
  14. package/dist/chunk-6UQMXIAG.js.map +1 -0
  15. package/dist/{chunk-SZLF66FJ.js → chunk-77LYGXBI.js} +5 -5
  16. package/dist/{chunk-SZLF66FJ.js.map → chunk-77LYGXBI.js.map} +1 -1
  17. package/dist/{chunk-KHJO4D5N.js → chunk-7N4Y3E47.js} +2 -2
  18. package/dist/{chunk-KHJO4D5N.js.map → chunk-7N4Y3E47.js.map} +1 -1
  19. package/dist/{chunk-65MEOA4E.js → chunk-AVQSHIJ5.js} +22 -18
  20. package/dist/chunk-AVQSHIJ5.js.map +1 -0
  21. package/dist/chunk-B3YUO3NW.js +469 -0
  22. package/dist/chunk-B3YUO3NW.js.map +1 -0
  23. package/dist/{chunk-YDAT7LD2.js → chunk-C66GOHYB.js} +18 -10
  24. package/dist/chunk-C66GOHYB.js.map +1 -0
  25. package/dist/chunk-DGUM43GV.js +10 -0
  26. package/dist/chunk-DGUM43GV.js.map +1 -0
  27. package/dist/{chunk-HYZVHJ3Q.js → chunk-FFWGT55D.js} +4 -4
  28. package/dist/{chunk-HYZVHJ3Q.js.map → chunk-FFWGT55D.js.map} +1 -1
  29. package/dist/{chunk-4CQ3MGNN.js → chunk-HK3AWUXH.js} +3 -3
  30. package/dist/{chunk-4CQ3MGNN.js.map → chunk-HK3AWUXH.js.map} +1 -1
  31. package/dist/{chunk-S6CYDZEW.js → chunk-MAY5HLDH.js} +772 -200
  32. package/dist/chunk-MAY5HLDH.js.map +1 -0
  33. package/dist/{chunk-7JHPQ6WF.js → chunk-OFUC6RYN.js} +3 -3
  34. package/dist/{chunk-7JHPQ6WF.js.map → chunk-OFUC6RYN.js.map} +1 -1
  35. package/dist/{chunk-3Q7QBWFW.js → chunk-ON25BX6T.js} +9 -3
  36. package/dist/chunk-ON25BX6T.js.map +1 -0
  37. package/dist/{chunk-JZYGEZTU.js → chunk-XPJZTSY7.js} +3 -3
  38. package/dist/{chunk-JZYGEZTU.js.map → chunk-XPJZTSY7.js.map} +1 -1
  39. package/dist/{chunk-WLETRGAC.js → chunk-Y23HMSWU.js} +11 -11
  40. package/dist/{chunk-WLETRGAC.js.map → chunk-Y23HMSWU.js.map} +1 -1
  41. package/dist/{chunk-3BVSDMHV.js → chunk-Z7GP7XTJ.js} +8 -8
  42. package/dist/{chunk-3BVSDMHV.js.map → chunk-Z7GP7XTJ.js.map} +1 -1
  43. package/dist/{chunk-EDAAG7BL.js → chunk-ZBTY6VV4.js} +4 -3
  44. package/dist/chunk-ZBTY6VV4.js.map +1 -0
  45. package/dist/chunk-ZKNB4YH4.js +102 -0
  46. package/dist/chunk-ZKNB4YH4.js.map +1 -0
  47. package/dist/cli.d.ts +3 -0
  48. package/dist/cli.js +475 -404
  49. package/dist/cli.js.map +1 -1
  50. package/dist/{execution-env-3BN7Z737.js → execution-env-ZU45JZ4G.js} +3 -2
  51. package/dist/{execution-env-3BN7Z737.js.map → execution-env-ZU45JZ4G.js.map} +1 -1
  52. package/dist/{federation-EPZDUWCK.js → federation-SZWZIFZ7.js} +3 -2
  53. package/dist/{federation-EPZDUWCK.js.map → federation-SZWZIFZ7.js.map} +1 -1
  54. package/dist/{fs-IPY4FJKH.js → fs-B5HZ2MIU.js} +3 -2
  55. package/dist/fs-B5HZ2MIU.js.map +1 -0
  56. package/dist/{fs-KCABDURV.js → fs-O5IQYXHO.js} +3 -2
  57. package/dist/fs-O5IQYXHO.js.map +1 -0
  58. package/dist/{git-ref-HPRLUFFW.js → git-ref-XDXB6JP5.js} +3 -2
  59. package/dist/{git-ref-HPRLUFFW.js.map → git-ref-XDXB6JP5.js.map} +1 -1
  60. package/dist/graph-backend-UTOL3SHE.js +11 -0
  61. package/dist/{graph-backend-ZMSYOZMW.js.map → graph-backend-UTOL3SHE.js.map} +1 -1
  62. package/dist/index.d.ts +53 -17
  63. package/dist/index.js +11 -10
  64. package/dist/index.js.map +1 -1
  65. package/dist/{interactive-ICL7D7LO.js → interactive-INGJNSON.js} +23 -22
  66. package/dist/interactive-INGJNSON.js.map +1 -0
  67. package/dist/{llm-host-2RAYQSDQ.js → llm-host-7GWDO6IX.js} +3 -2
  68. package/dist/{llm-host-2RAYQSDQ.js.map → llm-host-7GWDO6IX.js.map} +1 -1
  69. package/dist/load-QPOWQD7C.js +8 -0
  70. package/dist/{load-OHVKDX4R.js.map → load-QPOWQD7C.js.map} +1 -1
  71. package/dist/local-runtime-5O2NN3GA.js +5 -0
  72. package/dist/{local-runtime-OJFLX2HI.js.map → local-runtime-5O2NN3GA.js.map} +1 -1
  73. package/dist/mcp-tools-I7JK3S2M.js +4 -0
  74. package/dist/{mcp-tools-I6PME3AV.js.map → mcp-tools-I7JK3S2M.js.map} +1 -1
  75. package/dist/{model-execution-profile-MQ2QCP24.js → model-execution-profile-TFBKCNJG.js} +3 -2
  76. package/dist/{model-execution-profile-MQ2QCP24.js.map → model-execution-profile-TFBKCNJG.js.map} +1 -1
  77. package/dist/{model-orchestrator-FFTZI3U2.js → model-orchestrator-TVONAUPS.js} +5 -4
  78. package/dist/{model-orchestrator-FFTZI3U2.js.map → model-orchestrator-TVONAUPS.js.map} +1 -1
  79. package/dist/parse-worker.d.ts +1 -1
  80. package/dist/parse-worker.js +2 -1
  81. package/dist/parse-worker.js.map +1 -1
  82. package/dist/{paths-MCH75O3G.js → paths-2RAH3GME.js} +3 -2
  83. package/dist/{paths-MCH75O3G.js.map → paths-2RAH3GME.js.map} +1 -1
  84. package/dist/{resolve-gguf-4UPIGPEE.js → resolve-gguf-VPL4YQ6J.js} +3 -2
  85. package/dist/{resolve-gguf-4UPIGPEE.js.map → resolve-gguf-VPL4YQ6J.js.map} +1 -1
  86. package/dist/runtime-session-4AMZIAAG.js +18 -0
  87. package/dist/{runtime-session-IDU5BDUJ.js.map → runtime-session-4AMZIAAG.js.map} +1 -1
  88. package/dist/session-M72522AP.js +11 -0
  89. package/dist/{session-L2OSDRPI.js.map → session-M72522AP.js.map} +1 -1
  90. package/dist/session-store-WFBX7HXL.js +4 -0
  91. package/dist/{session-store-W5RZZHA3.js.map → session-store-WFBX7HXL.js.map} +1 -1
  92. package/dist/sql-extract-JELDZA6W.js +81 -0
  93. package/dist/sql-extract-JELDZA6W.js.map +1 -0
  94. package/dist/{stream-json-F74W5FCK.js → stream-json-6ZBUA2L3.js} +11 -10
  95. package/dist/stream-json-6ZBUA2L3.js.map +1 -0
  96. package/dist/{types-ZMg1mSuu.d.ts → types-DLH-Ritr.d.ts} +22 -1
  97. package/dist/ui-Q6DJ3GCU.js +5 -0
  98. package/dist/ui-Q6DJ3GCU.js.map +1 -0
  99. package/dist/{vgd-EGBQD7BW.js → vgd-CVLKBS7K.js} +7 -6
  100. package/dist/vgd-CVLKBS7K.js.map +1 -0
  101. package/package.json +1 -1
  102. package/dist/baseline-K7YBFKZI.js +0 -7
  103. package/dist/chunk-3Q7QBWFW.js.map +0 -1
  104. package/dist/chunk-5Q54GEHM.js +0 -29
  105. package/dist/chunk-5Q54GEHM.js.map +0 -1
  106. package/dist/chunk-65MEOA4E.js.map +0 -1
  107. package/dist/chunk-6IOQJGFT.js.map +0 -1
  108. package/dist/chunk-C4CKTAZP.js.map +0 -1
  109. package/dist/chunk-EDAAG7BL.js.map +0 -1
  110. package/dist/chunk-EDBV33B7.js +0 -57
  111. package/dist/chunk-EDBV33B7.js.map +0 -1
  112. package/dist/chunk-HABUT7HW.js +0 -233
  113. package/dist/chunk-HABUT7HW.js.map +0 -1
  114. package/dist/chunk-S6CYDZEW.js.map +0 -1
  115. package/dist/chunk-VXGV6NTD.js.map +0 -1
  116. package/dist/chunk-YDAT7LD2.js.map +0 -1
  117. package/dist/fs-IPY4FJKH.js.map +0 -1
  118. package/dist/fs-KCABDURV.js.map +0 -1
  119. package/dist/graph-backend-ZMSYOZMW.js +0 -10
  120. package/dist/interactive-ICL7D7LO.js.map +0 -1
  121. package/dist/load-OHVKDX4R.js +0 -7
  122. package/dist/local-runtime-OJFLX2HI.js +0 -4
  123. package/dist/mcp-tools-I6PME3AV.js +0 -3
  124. package/dist/runtime-session-IDU5BDUJ.js +0 -17
  125. package/dist/session-L2OSDRPI.js +0 -10
  126. package/dist/session-store-W5RZZHA3.js +0 -3
  127. package/dist/stream-json-F74W5FCK.js.map +0 -1
  128. package/dist/ui-HOVOPWMX.js +0 -4
  129. package/dist/ui-HOVOPWMX.js.map +0 -1
  130. package/dist/vgd-EGBQD7BW.js.map +0 -1
package/dist/cli.js CHANGED
@@ -1,45 +1,46 @@
1
1
  #!/usr/bin/env node
2
- import { loadAdvancedScanHook, baselineCommand } from './chunk-HYZVHJ3Q.js';
3
- import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, fetchCatalog, resolveProviders, runBuild } from './chunk-YDAT7LD2.js';
4
- export { runBuild } from './chunk-YDAT7LD2.js';
5
- import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-SZLF66FJ.js';
2
+ import { loadAdvancedScanHook, baselineCommand } from './chunk-FFWGT55D.js';
3
+ import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, fetchCatalog, resolveProviders, runBuild } from './chunk-C66GOHYB.js';
4
+ export { runBuild } from './chunk-C66GOHYB.js';
5
+ import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-Z7GP7XTJ.js';
6
+ import { disableColor, info, c, json, out } from './chunk-CT5BS56U.js';
7
+ import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-77LYGXBI.js';
6
8
  import './chunk-5I4VSBWQ.js';
7
9
  import './chunk-IS7VTH2Q.js';
8
- import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-3BVSDMHV.js';
9
- import { gatherSystemMemory } from './chunk-EDBV33B7.js';
10
- import { readOrchestratorState, writeOrchestratorState, parseMode, setDefaultMode, recommendMode, activePin, resolveMode, providerForBackend, QUALIFIED_PACKS, pinPack, unpinPack, buildOrchestratorStatus } from './chunk-VXGV6NTD.js';
11
- import { fmt, estimateModelBytes } from './chunk-KHJO4D5N.js';
10
+ import { gatherSystemMemory } from './chunk-6UQMXIAG.js';
11
+ import { readOrchestratorState, writeOrchestratorState, parseMode, setDefaultMode, recommendMode, activePin, resolveMode, providerForBackend, QUALIFIED_PACKS, pinPack, unpinPack, buildOrchestratorStatus } from './chunk-3V24O47U.js';
12
+ import { fmt, estimateModelBytes } from './chunk-7N4Y3E47.js';
12
13
  import './chunk-IZDH67DX.js';
13
- import './chunk-4CQ3MGNN.js';
14
+ import './chunk-HK3AWUXH.js';
14
15
  import { vgdIsRunning, vgdRequest, vgdSocketPath } from './chunk-PMYWZRRS.js';
15
16
  import { defaultProcessEndpoint, startProcessHostServer, resolveInferenceIsolation } from './chunk-PXHNTC6D.js';
16
17
  import { clearHostSessionPool, acquireHostSession, generateOnSession, listHostSessions, hostSessionPoolSize } from './chunk-K7REHDQS.js';
17
18
  import { buildIdentifierTrieFromGraph } from './chunk-JIBOJTGS.js';
18
19
  import './chunk-NDMDSPFX.js';
19
- import { runCodeSession } from './chunk-OXQNQW5J.js';
20
- import { ensurePackage, ensureUnavailableMessage, isPackageInstalled, summarizeDiffs, ScriptedProvider } from './chunk-7JHPQ6WF.js';
21
- import { disableColor, info, c, json, out } from './chunk-CT5BS56U.js';
22
- import { serveStdio, exportGraph, GraphSource, createServer, formatForExt } from './chunk-65MEOA4E.js';
23
- import { resolveDsn, resolveIngestHost, dashHostForIngestHost, resolveCliInvocation, availableRegionIds, createWorkspaceDsn, writeStoredCredentials, credentialsPath, findGitRoot, ensureGitignored, gitignoreEntryForCredentials, clearStoredCredentials, CliError, ExitCode, parseDsn as parseDsn$1, uploadScanArtifact, ingestHostForRegionId, dsnCommand, pushCommand, NPX_INVOCATION, refreshIfStale, driftCount, countTokens, shortestPath, testsToRun, detectRunner, ASSISTANTS, detectAssistants, usageError, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, coveringTests, FREE_PACK, readScanArtifact, buildGraph, writeSnapshot, probeFreshness, discover, assistantById, SMALL_REPO_FILES, resolveLimits, publishPrivateLibrary, assessDocQuality, symbolsFromApi, fetchHostedDocsCached, selectForBudget, hostedBase, readStoredCredentials, projectCredentialsPath, homeCredentialsPath, SKIP_DIRS, SKIP_FILES, SCHEMA_VERSION } from './chunk-S6CYDZEW.js';
24
- import { writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, VERSION, loadConfig, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, PROJECT_TYPE_TO_OSV_ECOSYSTEM, fetchRiskySymbols } from './chunk-WLETRGAC.js';
25
- import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-C4CKTAZP.js';
20
+ import { runCodeSession } from './chunk-2VFWXNS5.js';
21
+ import { ensurePackage, ensureUnavailableMessage, isPackageInstalled, summarizeDiffs, ScriptedProvider } from './chunk-OFUC6RYN.js';
22
+ import { serveStdio, exportGraph, GraphSource, createServer, formatForExt } from './chunk-AVQSHIJ5.js';
23
+ import { resolveDsn, resolveIngestHost, dashHostForIngestHost, resolveCliInvocation, availableRegionIds, createWorkspaceDsn, writeStoredCredentials, credentialsPath, findGitRoot, ensureGitignored, gitignoreEntryForCredentials, clearStoredCredentials, CliError, ExitCode, parseDsn as parseDsn$1, uploadScanArtifact, ingestHostForRegionId, dsnCommand, pushCommand, NPX_INVOCATION, refreshIfStale, driftCount, countTokens, shortestPath, pathDisconnect, testsToRun, detectRunner, ASSISTANTS, detectAssistants, usageError, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, coveringTests, FREE_PACK, readScanArtifact, buildGraph, writeSnapshot, probeFreshness, discover, assistantById, SMALL_REPO_FILES, publishPrivateLibrary, assessDocQuality, symbolsFromApi, fetchHostedDocsCached, selectForBudget, hostedBase, readStoredCredentials, projectCredentialsPath, homeCredentialsPath, SKIP_DIRS, SKIP_FILES } from './chunk-MAY5HLDH.js';
24
+ import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-6JIKUDWM.js';
25
+ import { writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, VERSION, loadConfig, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, PROJECT_TYPE_TO_OSV_ECOSYSTEM, fetchRiskySymbols } from './chunk-Y23HMSWU.js';
26
+ import { ensureDir, pathExists, readJsonFile, writeTextFile, writeJsonFile } from './chunk-CRAMOEBE.js';
26
27
  import { resolveOne } from './chunk-J7LKEB2R.js';
27
28
  import { discoverModels, listCachedWeights, isWeightCached, lookupCatalog, ensureWeightCached, catalogIntegrityReport, weightStoreDir } from './chunk-OOIG3RUM.js';
28
- import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-EDAAG7BL.js';
29
- import { cacheDir, embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, queryGraphSemantic, queryGraph, unavailableMessage, countPending, indexFor, impactOf, modelCacheInfo, clearModelCache } from './chunk-6IOQJGFT.js';
30
- import { resolvedGrammarFiles, grammarSetVersion } from './chunk-3Q7QBWFW.js';
29
+ import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-ZBTY6VV4.js';
30
+ import { embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, queryGraphSemantic, queryGraph, unavailableMessage, countPending, indexFor, impactOf, modelCacheInfo, clearModelCache } from './chunk-6UK6QPTR.js';
31
+ import { resolvedGrammarFiles, grammarSetVersion } from './chunk-ON25BX6T.js';
31
32
  import './chunk-RXP66R2E.js';
32
- import { resolveGraphPath, renderReport, loadGraph, writeArtifacts, vibgrateDir } from './chunk-HABUT7HW.js';
33
- import { stableStringify, serializeGraph } from './chunk-5Q54GEHM.js';
33
+ import { resolveGraphPath, renderReport, loadGraph, writeArtifacts, vibgrateDir, SCHEMA_VERSION } from './chunk-B3YUO3NW.js';
34
+ import { cacheDir, stableStringify } from './chunk-ZKNB4YH4.js';
34
35
  import './chunk-BWPBB45M.js';
35
36
  import { canonicalize, hashString, hashBytes } from './chunk-JFGYT6BI.js';
36
37
  import './chunk-BPF3YX2U.js';
37
38
  import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-GI6W53LM.js';
38
- import { ensureDir, pathExists, readJsonFile, writeTextFile, writeJsonFile } from './chunk-CRAMOEBE.js';
39
+ import './chunk-DGUM43GV.js';
39
40
  import * as fs8 from 'fs';
40
41
  import fs8__default, { realpathSync } from 'fs';
41
- import * as path36 from 'path';
42
- import path36__default from 'path';
42
+ import * as path37 from 'path';
43
+ import path37__default from 'path';
43
44
  import { fileURLToPath, pathToFileURL } from 'url';
44
45
  import { Command, CommanderError, Option } from 'commander';
45
46
  import * as os from 'os';
@@ -58,10 +59,10 @@ function registerStatus(program) {
58
59
  applyGlobalOptions(cmd);
59
60
  }
60
61
  async function runStatus(global) {
61
- const root2 = path36.resolve(global.cwd ?? ".");
62
+ const root2 = path37.resolve(global.cwd ?? ".");
62
63
  const graphPath = resolveGraphPath(root2, global.graph);
63
64
  const graph = loadGraph(root2, graphPath);
64
- const hasCache = fs8.existsSync(path36.join(cacheDir(root2), "parse-cache.json"));
65
+ const hasCache = fs8.existsSync(path37.join(cacheDir(root2), "parse-cache.json"));
65
66
  let stale = null;
66
67
  let staleExact = false;
67
68
  if (graph) {
@@ -81,8 +82,8 @@ async function runStatus(global) {
81
82
  }
82
83
  if (global.json) {
83
84
  json({
84
- root: path36.relative(process.cwd(), root2) || ".",
85
- graphPath: path36.relative(root2, graphPath),
85
+ root: path37.relative(process.cwd(), root2) || ".",
86
+ graphPath: path37.relative(root2, graphPath),
86
87
  built: graph !== null,
87
88
  generatedAt: graph?.generatedAt ?? null,
88
89
  counts: graph?.meta.counts ?? null,
@@ -97,11 +98,11 @@ async function runStatus(global) {
97
98
  return;
98
99
  }
99
100
  if (!graph) {
100
- info(`${c.cyan("vg")} \xB7 no map yet at ${c.dim(path36.relative(root2, graphPath))}`);
101
+ info(`${c.cyan("vg")} \xB7 no map yet at ${c.dim(path37.relative(root2, graphPath))}`);
101
102
  info(` run ${c.bold("vg")} to build one`);
102
103
  return;
103
104
  }
104
- info(`${c.cyan("vg")} \xB7 ${path36.relative(root2, graphPath)}`);
105
+ info(`${c.cyan("vg")} \xB7 ${path37.relative(root2, graphPath)}`);
105
106
  info(` generated ${graph.generatedAt}`);
106
107
  info(
107
108
  ` nodes ${c.bold(String(graph.meta.counts.nodes))} edges ${c.bold(
@@ -118,7 +119,7 @@ async function runStatus(global) {
118
119
  if (vibgrateDir(root2)) ;
119
120
  }
120
121
  function rootOf(global) {
121
- return path36.resolve(global.cwd ?? ".");
122
+ return path37.resolve(global.cwd ?? ".");
122
123
  }
123
124
  function requireGraph(global) {
124
125
  const root2 = rootOf(global);
@@ -401,6 +402,19 @@ function registerPath(program) {
401
402
  );
402
403
  }
403
404
  if (!result) {
405
+ const disc = pathDisconnect(graph, ra.node.id, rb.node.id);
406
+ if (global.json) {
407
+ json(disc);
408
+ throw new CliError(
409
+ `no path between ${ra.node.qualifiedName} and ${rb.node.qualifiedName}`,
410
+ ExitCode.NOT_FOUND
411
+ );
412
+ }
413
+ info(`${c.cyan("vg path")} \xB7 no path between ${c.bold(disc.from.name)} and ${c.bold(disc.to.name)}`);
414
+ printNeighborhood("from", disc.from);
415
+ printNeighborhood("to", disc.to);
416
+ info(c.dim(` ${disc.hint}`));
417
+ info(c.dim(` try: vg show ${disc.from.name} \xB7 vg impact ${disc.from.name} \xB7 vg show ${disc.to.name}`));
404
418
  throw new CliError(
405
419
  `no path between ${ra.node.qualifiedName} and ${rb.node.qualifiedName}`,
406
420
  ExitCode.NOT_FOUND
@@ -417,6 +431,14 @@ function registerPath(program) {
417
431
  });
418
432
  applyGlobalOptions(cmd);
419
433
  }
434
+ function printNeighborhood(label, n) {
435
+ const parts = [];
436
+ if (n.calls.length) parts.push(`calls ${n.calls.join(", ")}`);
437
+ if (n.calledBy.length) parts.push(`called by ${n.calledBy.join(", ")}`);
438
+ if (n.imports.length) parts.push(`imports ${n.imports.join(", ")}`);
439
+ if (n.importedBy.length) parts.push(`imported by ${n.importedBy.join(", ")}`);
440
+ info(` ${c.dim(label)} ${c.bold(n.name)}${parts.length ? c.dim(` \xB7 ${parts.join(" \xB7 ")}`) : c.dim(" \xB7 (no call/import neighbors)")}`);
441
+ }
420
442
 
421
443
  // src/commands/tree.ts
422
444
  function registerTree(program) {
@@ -530,12 +552,12 @@ function registerInsights(program) {
530
552
  }
531
553
  });
532
554
  applyGlobalOptions(areas);
533
- const oddities = program.command("oddities").description("surprising cross-area links (architectural smells)").option("-n, --limit <n>", "how many to show", "20").action(function(opts) {
555
+ const oddities = program.command("oddities").description("surprising cross-area links (architectural smells)").option("-n, --limit <n>", "how many to show", "20").option("--all", "include framework/runtime externals (default: filter them out)").action(function(opts) {
534
556
  const global = readGlobal(this);
535
557
  const { graph } = requireGraph(global);
536
558
  const limit = Number(opts.limit) || 20;
537
559
  const byId = new Map(graph.nodes.map((n) => [n.id, n]));
538
- const list = graph.edges.filter((e) => typeof e.surprise === "number" && e.surprise > 0).sort((a, b) => (b.surprise ?? 0) - (a.surprise ?? 0) || a.id.localeCompare(b.id)).slice(0, limit);
560
+ const list = graph.edges.filter((e) => typeof e.surprise === "number" && e.surprise > 0).filter((e) => opts.all || !isFrameworkOddity(byId.get(e.src), byId.get(e.dst), e.kind)).sort((a, b) => (b.surprise ?? 0) - (a.surprise ?? 0) || a.id.localeCompare(b.id)).slice(0, limit);
539
561
  if (global.json) {
540
562
  json(
541
563
  list.map((e) => ({
@@ -548,7 +570,9 @@ function registerInsights(program) {
548
570
  return;
549
571
  }
550
572
  if (!list.length) {
551
- info(`${c.cyan("vg oddities")} \xB7 none found (no cross-area links, or only one area)`);
573
+ info(
574
+ `${c.cyan("vg oddities")} \xB7 none found` + (opts.all ? " (no cross-area links, or only one area)" : " (no app-level surprises; try --all for framework links)")
575
+ );
552
576
  return;
553
577
  }
554
578
  info(`${c.cyan("vg oddities")} \xB7 top ${list.length} surprising links`);
@@ -560,6 +584,70 @@ function registerInsights(program) {
560
584
  });
561
585
  applyGlobalOptions(oddities);
562
586
  }
587
+ var FRAMEWORK_EXTERNALS = /* @__PURE__ */ new Set([
588
+ "react",
589
+ "react-dom",
590
+ "react-native",
591
+ "vue",
592
+ "vue-router",
593
+ "svelte",
594
+ "svelte/store",
595
+ "next",
596
+ "next/link",
597
+ "next/router",
598
+ "next/navigation",
599
+ "nuxt",
600
+ "angular",
601
+ "@angular/core",
602
+ "@angular/common",
603
+ "preact",
604
+ "solid-js",
605
+ "express",
606
+ "fastify",
607
+ "koa",
608
+ "hono",
609
+ "rxjs",
610
+ "lodash",
611
+ "lodash-es",
612
+ "underscore",
613
+ "jquery",
614
+ "axios",
615
+ "node:fs",
616
+ "node:path",
617
+ "node:url",
618
+ "node:http",
619
+ "node:https",
620
+ "fs",
621
+ "path",
622
+ "url",
623
+ "http",
624
+ "https",
625
+ "crypto",
626
+ "util",
627
+ "stream",
628
+ "events",
629
+ "assert",
630
+ "os",
631
+ "child_process"
632
+ ]);
633
+ function isFrameworkOddity(from, to, kind) {
634
+ if (kind !== "import") return false;
635
+ for (const n of [from, to]) {
636
+ if (n?.kind === "external" && isFrameworkName(n.qualifiedName || n.name)) return true;
637
+ }
638
+ return false;
639
+ }
640
+ function isFrameworkName(name) {
641
+ if (!name) return false;
642
+ if (FRAMEWORK_EXTERNALS.has(name)) return true;
643
+ const base = name.startsWith("@") ? name.split("/").slice(0, 2).join("/") : name.split("/")[0];
644
+ if (FRAMEWORK_EXTERNALS.has(base)) return true;
645
+ if (base.startsWith("react-") || base.startsWith("@types/react")) return true;
646
+ if (base.startsWith("@vue/") || base.startsWith("@angular/") || base.startsWith("@sveltejs/")) {
647
+ return true;
648
+ }
649
+ return false;
650
+ }
563
651
  function nodeSummary(n) {
564
652
  return {
565
653
  id: n.id,
@@ -742,8 +830,8 @@ function pad2(s, n) {
742
830
  }
743
831
  var SCHEMA_VERSION2 = "1";
744
832
  var OFFSET_FILE = "stats-share.json";
745
- var INSTALL_ID_DIR = path36.join(os.homedir(), ".vibgrate");
746
- var INSTALL_ID_FILE = path36.join(INSTALL_ID_DIR, "install-id");
833
+ var INSTALL_ID_DIR = path37.join(os.homedir(), ".vibgrate");
834
+ var INSTALL_ID_FILE = path37.join(INSTALL_ID_DIR, "install-id");
747
835
  var SEND_TIMEOUT_MS = 4e3;
748
836
  function telemetryOptOut(env = process.env) {
749
837
  const dnt = (env.DO_NOT_TRACK ?? "").trim().toLowerCase();
@@ -795,10 +883,10 @@ function statsEndpoint() {
795
883
  return `https://${resolveIngestHost()}/v1/ingest/cli-mcp-usage`;
796
884
  }
797
885
  function offsetPath(root2) {
798
- return path36.join(cacheDir(root2), OFFSET_FILE);
886
+ return path37.join(cacheDir(root2), OFFSET_FILE);
799
887
  }
800
888
  function ledgerFilePath(root2) {
801
- return path36.join(cacheDir(root2), "savings.jsonl");
889
+ return path37.join(cacheDir(root2), "savings.jsonl");
802
890
  }
803
891
  function readOffset(root2) {
804
892
  try {
@@ -969,9 +1057,9 @@ var PUBLISH_INTERVAL_MS = 2e3;
969
1057
  var KEEPALIVE_MS = 1e4;
970
1058
  var STALE_MS = 6e4;
971
1059
  function liveStatsDir(root2) {
972
- return path36.join(cacheDir(root2), "serve-live");
1060
+ return path37.join(cacheDir(root2), "serve-live");
973
1061
  }
974
- function reapOtherVersionServers(dir, keepVersion, now2 = Date.now(), kill = (pid, signal) => process.kill(pid, signal), selfPid = process.pid) {
1062
+ function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid, signal) => process.kill(pid, signal), selfPid = process.pid) {
975
1063
  let entries;
976
1064
  try {
977
1065
  entries = fs8.readdirSync(dir);
@@ -983,13 +1071,13 @@ function reapOtherVersionServers(dir, keepVersion, now2 = Date.now(), kill = (pi
983
1071
  if (!/^serve-\d+\.json$/.test(name)) continue;
984
1072
  let parsed;
985
1073
  try {
986
- parsed = JSON.parse(fs8.readFileSync(path36.join(dir, name), "utf8"));
1074
+ parsed = JSON.parse(fs8.readFileSync(path37.join(dir, name), "utf8"));
987
1075
  } catch {
988
1076
  continue;
989
1077
  }
990
1078
  if (typeof parsed?.pid !== "number" || typeof parsed.updatedAt !== "number") continue;
991
1079
  if (parsed.pid === selfPid) continue;
992
- if (now2 - parsed.updatedAt > STALE_MS) continue;
1080
+ if (now - parsed.updatedAt > STALE_MS) continue;
993
1081
  const version = typeof parsed.version === "string" ? parsed.version : "unknown";
994
1082
  if (version === keepVersion) continue;
995
1083
  try {
@@ -1005,7 +1093,7 @@ var LiveStatsBus = class {
1005
1093
  this.dir = dir;
1006
1094
  this.stats = stats;
1007
1095
  this.pid = pid;
1008
- this.file = path36.join(dir, `serve-${this.pid}.json`);
1096
+ this.file = path37.join(dir, `serve-${this.pid}.json`);
1009
1097
  }
1010
1098
  dir;
1011
1099
  stats;
@@ -1030,12 +1118,12 @@ var LiveStatsBus = class {
1030
1118
  this.unlinkOwn();
1031
1119
  }
1032
1120
  /** Write the current snapshot when it changed (or as a keepalive). Never throws. */
1033
- publish(now2 = Date.now()) {
1121
+ publish(now = Date.now()) {
1034
1122
  const snap = this.stats.snapshot();
1035
- if (snap.revision === this.lastRevision && now2 - this.lastWriteAt < KEEPALIVE_MS) return;
1123
+ if (snap.revision === this.lastRevision && now - this.lastWriteAt < KEEPALIVE_MS) return;
1036
1124
  this.lastRevision = snap.revision;
1037
- this.lastWriteAt = now2;
1038
- const body = { pid: this.pid, updatedAt: now2, version: VERSION, snapshot: snap };
1125
+ this.lastWriteAt = now;
1126
+ const body = { pid: this.pid, updatedAt: now, version: VERSION, snapshot: snap };
1039
1127
  try {
1040
1128
  fs8.mkdirSync(this.dir, { recursive: true });
1041
1129
  const tmp = `${this.file}.tmp`;
@@ -1048,7 +1136,7 @@ var LiveStatsBus = class {
1048
1136
  * Fresh snapshots of the OTHER serve processes in this repo. Stale files
1049
1137
  * (crashed processes) are swept best-effort while reading.
1050
1138
  */
1051
- siblings(now2 = Date.now()) {
1139
+ siblings(now = Date.now()) {
1052
1140
  let entries;
1053
1141
  try {
1054
1142
  entries = fs8.readdirSync(this.dir);
@@ -1058,7 +1146,7 @@ var LiveStatsBus = class {
1058
1146
  const out2 = [];
1059
1147
  for (const name of entries.sort()) {
1060
1148
  if (!/^serve-\d+\.json$/.test(name)) continue;
1061
- const file = path36.join(this.dir, name);
1149
+ const file = path37.join(this.dir, name);
1062
1150
  let parsed;
1063
1151
  try {
1064
1152
  parsed = JSON.parse(fs8.readFileSync(file, "utf8"));
@@ -1066,7 +1154,7 @@ var LiveStatsBus = class {
1066
1154
  continue;
1067
1155
  }
1068
1156
  if (typeof parsed?.pid !== "number" || typeof parsed.updatedAt !== "number" || !parsed.snapshot?.totals) continue;
1069
- if (now2 - parsed.updatedAt > STALE_MS) {
1157
+ if (now - parsed.updatedAt > STALE_MS) {
1070
1158
  try {
1071
1159
  fs8.unlinkSync(file);
1072
1160
  } catch {
@@ -1140,12 +1228,12 @@ var SessionStats = class {
1140
1228
  byClient = /* @__PURE__ */ new Map();
1141
1229
  byTool = /* @__PURE__ */ new Map();
1142
1230
  bySource = /* @__PURE__ */ new Map();
1143
- constructor(now2 = Date.now()) {
1144
- this.startedAt = now2;
1231
+ constructor(now = Date.now()) {
1232
+ this.startedAt = now;
1145
1233
  }
1146
- record(sample, now2 = Date.now()) {
1234
+ record(sample, now = Date.now()) {
1147
1235
  this.revision++;
1148
- this.lastCallAt = now2;
1236
+ this.lastCallAt = now;
1149
1237
  const rows = [
1150
1238
  this.totals,
1151
1239
  this.rowFor(this.byClient, sample.client),
@@ -1208,9 +1296,9 @@ var teal = (s) => c.hex("#3FB0A4")(s);
1208
1296
  var mint = (s) => c.hex("#4FE3C1")(s);
1209
1297
  var SPINNER = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
1210
1298
  var MAX_TOOL_ROWS = 8;
1211
- function serveStatusLines(snap, now2, tick = 0, siblingServers = 0) {
1299
+ function serveStatusLines(snap, now, tick = 0, siblingServers = 0) {
1212
1300
  const spinner = mint(SPINNER[tick % SPINNER.length]);
1213
- const up = fmtUptime(now2 - snap.startedAt);
1301
+ const up = fmtUptime(now - snap.startedAt);
1214
1302
  const lines = [];
1215
1303
  const siblingNote = siblingServers > 0 ? ` ${c.dim(`incl. ${siblingServers} assistant-spawned server${siblingServers === 1 ? "" : "s"} in this repo`)}` : null;
1216
1304
  if (snap.totals.calls === 0) {
@@ -1224,7 +1312,7 @@ function serveStatusLines(snap, now2, tick = 0, siblingServers = 0) {
1224
1312
  const answered = Math.round((t.complete + t.partial) / t.calls * 100);
1225
1313
  const cli = snap.sources.find((s) => s.key === "cli");
1226
1314
  const via = cli ? c.dim(" \xB7 via ") + snap.sources.map((s) => `${c.white(s.key)} ${teal(String(s.calls))}`).join(c.dim(" \xB7 ")) : "";
1227
- const ago = snap.lastCallAt === null ? "" : c.dim(` \xB7 last call ${fmtUptime(now2 - snap.lastCallAt)} ago`);
1315
+ const ago = snap.lastCallAt === null ? "" : c.dim(` \xB7 last call ${fmtUptime(now - snap.lastCallAt)} ago`);
1228
1316
  lines.push(
1229
1317
  ` ${spinner} ${c.bold.white("vg serve")} ${c.dim("\xB7")} up ${teal(up)} ${c.dim("\xB7")} ${c.bold.white(String(t.calls))} call${t.calls === 1 ? "" : "s"} ${c.dim("\xB7")} ${mint(`${answered}%`)} answered${via}${ago}`
1230
1318
  );
@@ -1257,8 +1345,8 @@ function serveStatusLines(snap, now2, tick = 0, siblingServers = 0) {
1257
1345
  if (siblingNote) lines.push(siblingNote);
1258
1346
  return lines;
1259
1347
  }
1260
- function serveHeartbeatLine(snap, now2) {
1261
- const up = fmtUptime(now2 - snap.startedAt);
1348
+ function serveHeartbeatLine(snap, now) {
1349
+ const up = fmtUptime(now - snap.startedAt);
1262
1350
  const t = snap.totals;
1263
1351
  if (t.calls === 0) return c.dim(`vg \xB7 serving for ${up} \u2014 no tool calls yet`);
1264
1352
  const clients = snap.clients.map((cl) => `${cl.key} ${cl.calls}`).join(", ");
@@ -1382,7 +1470,7 @@ var LedgerTail = class {
1382
1470
  }
1383
1471
  }
1384
1472
  /** One poll cycle — exposed for tests (deterministic, no timers needed). */
1385
- poll(now2 = Date.now()) {
1473
+ poll(now = Date.now()) {
1386
1474
  let size;
1387
1475
  try {
1388
1476
  size = this.sizeOf();
@@ -1407,7 +1495,7 @@ var LedgerTail = class {
1407
1495
  if (lastNewline < 0) return;
1408
1496
  const text = chunk.subarray(0, lastNewline).toString("utf8");
1409
1497
  this.offset += lastNewline + 1;
1410
- for (const line of text.split("\n")) ingestLedgerLine(this.stats, line, now2);
1498
+ for (const line of text.split("\n")) ingestLedgerLine(this.stats, line, now);
1411
1499
  }
1412
1500
  sizeOf() {
1413
1501
  try {
@@ -1417,7 +1505,7 @@ var LedgerTail = class {
1417
1505
  }
1418
1506
  }
1419
1507
  };
1420
- function ingestLedgerLine(stats, line, now2) {
1508
+ function ingestLedgerLine(stats, line, now) {
1421
1509
  if (!line.trim()) return;
1422
1510
  let e;
1423
1511
  try {
@@ -1436,7 +1524,7 @@ function ingestLedgerLine(stats, line, now2) {
1436
1524
  vgTokens: e.vgTokens ?? 0,
1437
1525
  baselineTokens: e.baselineTokens ?? 0
1438
1526
  },
1439
- now2
1527
+ now
1440
1528
  );
1441
1529
  }
1442
1530
 
@@ -1486,8 +1574,8 @@ function registerServe(program) {
1486
1574
  await serveHttp(graphPath, opts.host ?? "127.0.0.1", Number(opts.port) || 7437, serveOpts, freshness, () => display?.start());
1487
1575
  } else {
1488
1576
  info(c.dim(`vg \xB7 MCP server on stdio (read-only, ${freshness}). Connect your assistant to this process.`));
1489
- await serveStdio(graphPath, serveOpts);
1490
1577
  display?.start();
1578
+ await serveStdio(graphPath, serveOpts);
1491
1579
  }
1492
1580
  });
1493
1581
  applyGlobalOptions(cmd);
@@ -1502,13 +1590,22 @@ async function ensureServableGraph(root2, graphPath, global, refresh, opts = {})
1502
1590
  { ...global, json: false }
1503
1591
  );
1504
1592
  } else {
1505
- const refreshed = await refreshIfStale(root2, { inline: opts.inline, graphPath });
1506
- if (refreshed.status === "refreshed") {
1507
- const n = driftCount(refreshed.drift);
1508
- info(c.dim(`vg \xB7 map refreshed before serving \u2014 ${n} file(s) drifted (${(refreshed.ms / 1e3).toFixed(2)}s)`));
1509
- } else if (refreshed.status === "error") {
1510
- info(c.yellow(`vg \xB7 map refresh failed (${refreshed.message}) \u2014 serving the last built map`));
1511
- }
1593
+ const kick = refreshIfStale(root2, { inline: opts.inline, graphPath }).then((refreshed) => {
1594
+ if (refreshed.status === "refreshed") {
1595
+ const n = driftCount(refreshed.drift);
1596
+ info(
1597
+ c.dim(
1598
+ `vg \xB7 map refreshed in background \u2014 ${n} file(s) drifted (${(refreshed.ms / 1e3).toFixed(2)}s)`
1599
+ )
1600
+ );
1601
+ } else if (refreshed.status === "error") {
1602
+ info(c.yellow(`vg \xB7 map refresh failed (${refreshed.message}) \u2014 serving the last built map`));
1603
+ }
1604
+ }).catch((err) => {
1605
+ const msg = err instanceof Error ? err.message : String(err);
1606
+ info(c.yellow(`vg \xB7 map refresh failed (${msg}) \u2014 serving the last built map`));
1607
+ });
1608
+ if (opts.awaitStaleRefresh) await kick;
1512
1609
  }
1513
1610
  }
1514
1611
  if (!fs8.existsSync(graphPath)) {
@@ -1573,7 +1670,7 @@ async function serveHttp(graphPath, host, port, opts, freshness, onReady) {
1573
1670
  info(c.red(`vg serve: request error: ${err.message}`));
1574
1671
  }
1575
1672
  });
1576
- await new Promise((resolve19) => httpServer.listen(port, host, resolve19));
1673
+ await new Promise((resolve20) => httpServer.listen(port, host, resolve20));
1577
1674
  info(c.dim(`vg \xB7 MCP server on http://${host}:${port}/mcp (read-only, local, ${freshness})`));
1578
1675
  onReady?.();
1579
1676
  await new Promise(() => {
@@ -1787,7 +1884,7 @@ function endOfLine(text, line) {
1787
1884
  }
1788
1885
  var CACHE_VERSION = "vg-lsp-scan-cache/2";
1789
1886
  function cachePath(root2) {
1790
- return path36.join(cacheDir(root2), "lsp-scan.json");
1887
+ return path37.join(cacheDir(root2), "lsp-scan.json");
1791
1888
  }
1792
1889
  function manifestHash(root2) {
1793
1890
  const files = [];
@@ -1799,7 +1896,7 @@ function manifestHash(root2) {
1799
1896
  return;
1800
1897
  }
1801
1898
  for (const entry of entries) {
1802
- const abs = path36.join(dir, entry.name);
1899
+ const abs = path37.join(dir, entry.name);
1803
1900
  if (entry.isDirectory()) {
1804
1901
  if (SKIP_DIRS.has(entry.name)) continue;
1805
1902
  walk2(abs);
@@ -1809,7 +1906,7 @@ function manifestHash(root2) {
1809
1906
  const base = entry.name.toLowerCase();
1810
1907
  if (!isManifest(abs) && !SKIP_FILES.has(base)) continue;
1811
1908
  try {
1812
- const rel = path36.relative(root2, abs).split(path36.sep).join("/");
1909
+ const rel = path37.relative(root2, abs).split(path37.sep).join("/");
1813
1910
  files.push({ rel, hash: hashBytes(fs8.readFileSync(abs)) });
1814
1911
  } catch {
1815
1912
  }
@@ -2455,12 +2552,12 @@ function uriToPath(uri) {
2455
2552
  }
2456
2553
  }
2457
2554
  function projectForFile(root2, a, filePath) {
2458
- const dir = path36.dirname(path36.resolve(filePath));
2555
+ const dir = path37.dirname(path37.resolve(filePath));
2459
2556
  let best;
2460
2557
  let bestLen = -1;
2461
2558
  for (const proj of a.projects ?? []) {
2462
- const projDir = path36.resolve(root2, proj.path);
2463
- if ((dir === projDir || dir.startsWith(projDir + path36.sep)) && projDir.length > bestLen) {
2559
+ const projDir = path37.resolve(root2, proj.path);
2560
+ if ((dir === projDir || dir.startsWith(projDir + path37.sep)) && projDir.length > bestLen) {
2464
2561
  best = proj;
2465
2562
  bestLen = projDir.length;
2466
2563
  }
@@ -2468,7 +2565,7 @@ function projectForFile(root2, a, filePath) {
2468
2565
  return best;
2469
2566
  }
2470
2567
  function sameProject(location, projectPath) {
2471
- return path36.normalize(location) === path36.normalize(projectPath);
2568
+ return path37.normalize(location) === path37.normalize(projectPath);
2472
2569
  }
2473
2570
  function hasReleaseDates(a) {
2474
2571
  for (const proj of a.projects ?? []) {
@@ -2714,9 +2811,9 @@ function registerInstall(program) {
2714
2811
  info(`${c.cyan("vg install")} \xB7 no AI assistants detected here`);
2715
2812
  } else {
2716
2813
  info(`${c.cyan("vg install")} \xB7 detected assistants`);
2717
- const pad5 = Math.max(...detected.map((d) => d.assistant.id.length)) + 2;
2814
+ const pad4 = Math.max(...detected.map((d) => d.assistant.id.length)) + 2;
2718
2815
  for (const d of detected) {
2719
- info(` ${c.bold(d.assistant.id.padEnd(pad5))} ${d.assistant.label} ${c.dim(`via ${d.via}: ${d.marker}`)}`);
2816
+ info(` ${c.bold(d.assistant.id.padEnd(pad4))} ${d.assistant.label} ${c.dim(`via ${d.via}: ${d.marker}`)}`);
2720
2817
  }
2721
2818
  }
2722
2819
  return;
@@ -2725,9 +2822,9 @@ function registerInstall(program) {
2725
2822
  json(ASSISTANTS.map((a) => ({ id: a.id, label: a.label, mcp: !!a.mcp, skill: !!a.skill, nudge: !!a.nudge })));
2726
2823
  } else {
2727
2824
  info(`${c.cyan("vg install")} \xB7 supported assistants`);
2728
- const pad5 = Math.max(...ASSISTANTS.map((a) => a.id.length)) + 2;
2825
+ const pad4 = Math.max(...ASSISTANTS.map((a) => a.id.length)) + 2;
2729
2826
  for (const a of ASSISTANTS) {
2730
- info(` ${c.bold(a.id.padEnd(pad5))} ${a.label} ${c.dim(`mcp:${a.mcp ? "\u2713" : "\u2014"} skill:${a.skill ? "\u2713" : "\u2014"} nudge:${a.nudge ? "\u2713" : "\u2014"}`)}`);
2827
+ info(` ${c.bold(a.id.padEnd(pad4))} ${a.label} ${c.dim(`mcp:${a.mcp ? "\u2713" : "\u2014"} skill:${a.skill ? "\u2713" : "\u2014"} nudge:${a.nudge ? "\u2713" : "\u2014"}`)}`);
2731
2828
  }
2732
2829
  }
2733
2830
  return;
@@ -2794,7 +2891,7 @@ function registerShare(program) {
2794
2891
  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) {
2795
2892
  const global = readGlobal(this);
2796
2893
  const root2 = rootOf(global);
2797
- const gitDir = path36.join(root2, ".git");
2894
+ const gitDir = path37.join(root2, ".git");
2798
2895
  if (!fs8.existsSync(gitDir)) {
2799
2896
  throw new CliError("not a git repository \u2014 run `vg share` inside a git repo", ExitCode.USAGE_ERROR);
2800
2897
  }
@@ -2816,15 +2913,15 @@ function registerShare(program) {
2816
2913
  applyGlobalOptions(cmd);
2817
2914
  }
2818
2915
  function writeVibgrateGitignore(root2, reports) {
2819
- const dir = path36.join(root2, ".vibgrate");
2916
+ const dir = path37.join(root2, ".vibgrate");
2820
2917
  fs8.mkdirSync(dir, { recursive: true });
2821
2918
  const lines = ["# Managed by `vg share` \u2014 keep graph.json committed, ignore the rest", "cache/", "facts.jsonl"];
2822
2919
  if (!reports) lines.push("graph.html", "GRAPH_REPORT.md");
2823
- fs8.writeFileSync(path36.join(dir, ".gitignore"), `${lines.join("\n")}
2920
+ fs8.writeFileSync(path37.join(dir, ".gitignore"), `${lines.join("\n")}
2824
2921
  `);
2825
2922
  }
2826
2923
  function writeGitAttributes(root2) {
2827
- const file = path36.join(root2, ".gitattributes");
2924
+ const file = path37.join(root2, ".gitattributes");
2828
2925
  const line = ".vibgrate/graph.json merge=vg";
2829
2926
  let content = fs8.existsSync(file) ? fs8.readFileSync(file, "utf8") : "";
2830
2927
  if (!content.split("\n").some((l) => l.trim() === line)) {
@@ -2842,7 +2939,7 @@ function configureMergeDriver(root2) {
2842
2939
  function installPreCommitHook(root2) {
2843
2940
  const hooksDir = hookDir(root2);
2844
2941
  fs8.mkdirSync(hooksDir, { recursive: true });
2845
- const file = path36.join(hooksDir, "pre-commit");
2942
+ const file = path37.join(hooksDir, "pre-commit");
2846
2943
  const block = [
2847
2944
  HOOK_BEGIN,
2848
2945
  "if command -v vg >/dev/null 2>&1; then",
@@ -2864,14 +2961,14 @@ ${content}`;
2864
2961
  fs8.chmodSync(file, 493);
2865
2962
  }
2866
2963
  function undo(root2) {
2867
- const hookFile = path36.join(hookDir(root2), "pre-commit");
2964
+ const hookFile = path37.join(hookDir(root2), "pre-commit");
2868
2965
  if (fs8.existsSync(hookFile)) {
2869
2966
  const re = new RegExp(`\\n*${escapeRe(HOOK_BEGIN)}[\\s\\S]*?${escapeRe(HOOK_END)}\\n*`);
2870
2967
  const next2 = fs8.readFileSync(hookFile, "utf8").replace(re, "\n");
2871
2968
  if (next2.trim() === "#!/bin/sh") fs8.rmSync(hookFile);
2872
2969
  else fs8.writeFileSync(hookFile, next2);
2873
2970
  }
2874
- const attr = path36.join(root2, ".gitattributes");
2971
+ const attr = path37.join(root2, ".gitattributes");
2875
2972
  if (fs8.existsSync(attr)) {
2876
2973
  const next2 = fs8.readFileSync(attr, "utf8").split("\n").filter((l) => l.trim() !== ".vibgrate/graph.json merge=vg").join("\n");
2877
2974
  fs8.writeFileSync(attr, next2);
@@ -2884,10 +2981,10 @@ function undo(root2) {
2884
2981
  function hookDir(root2) {
2885
2982
  try {
2886
2983
  const configured = git(root2, ["config", "--get", "core.hooksPath"]).trim();
2887
- if (configured) return path36.resolve(root2, configured);
2984
+ if (configured) return path37.resolve(root2, configured);
2888
2985
  } catch {
2889
2986
  }
2890
- return path36.join(root2, ".git", "hooks");
2987
+ return path37.join(root2, ".git", "hooks");
2891
2988
  }
2892
2989
  function git(root2, args) {
2893
2990
  return execFileSync("git", args, { cwd: root2, encoding: "utf8" });
@@ -2895,148 +2992,111 @@ function git(root2, args) {
2895
2992
  function escapeRe(s) {
2896
2993
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2897
2994
  }
2898
- var PIN = "2020-01-01T00:00:00.000Z";
2899
- function registerBenchmark(program) {
2900
- const cmd = program.command("benchmark").description("reproducible build + memory + token-reduction benchmark (honest estimates)").option("--budget <n>", "token budget for vg answers", "2000").action(async function(opts) {
2995
+ var DEFAULT_DEBOUNCE_MS = 400;
2996
+ var SKIP_NAME = /* @__PURE__ */ new Set([
2997
+ ".git",
2998
+ "node_modules",
2999
+ ".vibgrate",
3000
+ "dist",
3001
+ "build",
3002
+ "out",
3003
+ "coverage",
3004
+ ".next",
3005
+ "target",
3006
+ "__pycache__",
3007
+ ".venv",
3008
+ "venv"
3009
+ ]);
3010
+ function registerWatch(program) {
3011
+ const cmd = program.command("watch").description("rebuild the code map when files change (debounced)").argument("[paths...]", "folders to watch (default: current folder)").option("--debounce <ms>", "settle time after a change before rebuild", String(DEFAULT_DEBOUNCE_MS)).option("--no-html", "do not write graph.html on each rebuild").option("--no-report", "do not write GRAPH_REPORT.md on each rebuild").option("--fast", "skip precise tsc resolve on rebuilds (heuristic only)").action(async function(paths, opts) {
2901
3012
  const global = readGlobal(this);
2902
3013
  const root2 = rootOf(global);
2903
- const budget = Number(opts.budget) || 2e3;
2904
- const result = await runBenchmarkSuite(root2, budget);
2905
- if (global.json) {
2906
- json(result);
2907
- return;
2908
- }
2909
- const { repo, build, throughput, memory, determinism, tokenReduction } = result;
2910
- info(`${c.cyan("vg benchmark")} \xB7 ${repo.files} files \xB7 ${repo.nodes} nodes`);
2911
- info(` build cold ${build.coldMs.toFixed(0)}ms \xB7 incremental ${build.incrementalMs.toFixed(0)}ms (reused ${build.reusedOnWarm})`);
2912
- info(` speed ${throughput.filesPerSec.toFixed(0)} files/s \xB7 ${throughput.mbPerSec.toFixed(1)} MB/s (cold, ${mb2(throughput.corpusBytes).toFixed(1)} MB corpus)`);
2913
- info(
2914
- ` memory peak rss ${memory.peakRssMb.toFixed(0)} MB (baseline ${memory.baselineRssMb.toFixed(0)} MB) \xB7 peak heap ${memory.peakHeapMb.toFixed(0)} MB \xB7 graph retains ~${memory.retainedHeapMb.toFixed(0)} MB ${c.dim("(approximate)")}`
2915
- );
2916
- info(` graph ${mb2(memory.graphJsonBytes).toFixed(1)} MB serialized \xB7 ${memory.bytesPerNode.toFixed(0)} B/node`);
2917
- info(` determinism ${determinism.byteIdentical ? c.green("byte-identical \u2713") : c.red("NON-DETERMINISTIC \u2717")}`);
2918
- if (tokenReduction.questions.length) {
2919
- info(` token reduction vs grep/read baseline (${c.dim("estimates")}):`);
2920
- for (const q of tokenReduction.questions) {
2921
- info(` ${pad3(`${q.ratio.toFixed(1)}\xD7`, 6)} ${c.dim(`vg ${q.vgTokens} vs ~${q.baselineTokens}`)} "${q.question}"`);
3014
+ const debounceMs = Math.max(50, Number(opts.debounce) || DEFAULT_DEBOUNCE_MS);
3015
+ const watchRoots = (paths.length ? paths : ["."]).map((p) => path37.resolve(root2, p));
3016
+ for (const w of watchRoots) {
3017
+ if (!fs8.existsSync(w)) {
3018
+ throw new CliError(`watch path not found: ${w}`, ExitCode.USAGE_ERROR);
3019
+ }
3020
+ }
3021
+ let building = false;
3022
+ let pending = false;
3023
+ let timer = null;
3024
+ const rebuild = async (reason) => {
3025
+ if (building) {
3026
+ pending = true;
3027
+ return;
3028
+ }
3029
+ building = true;
3030
+ try {
3031
+ info(c.dim(`vg watch \xB7 rebuild (${reason})`));
3032
+ const result = await buildGraph({
3033
+ root: root2,
3034
+ paths: paths.length ? paths : void 0,
3035
+ fast: opts.fast === true,
3036
+ noGround: false
3037
+ });
3038
+ writeArtifacts(result.graph, {
3039
+ root: root2,
3040
+ html: opts.html !== false,
3041
+ report: opts.report !== false,
3042
+ graphPath: global.graph
3043
+ });
3044
+ writeSnapshot(root2, result.graph.provenance.corpusHash, result.fileStats);
3045
+ const { counts } = result.graph.meta;
3046
+ info(
3047
+ `${c.cyan("vg watch")} \xB7 ${counts.nodes} nodes \xB7 ${counts.edges} edges \xB7 ${(result.timing.totalMs / 1e3).toFixed(2)}s` + (result.statHits ? c.dim(` \xB7 ${result.statHits} mtime hits`) : "")
3048
+ );
3049
+ } catch (err) {
3050
+ info(c.yellow(`vg watch \xB7 rebuild failed: ${err.message}`));
3051
+ } finally {
3052
+ building = false;
3053
+ if (pending) {
3054
+ pending = false;
3055
+ void rebuild("queued changes");
3056
+ }
3057
+ }
3058
+ };
3059
+ const schedule = (label) => {
3060
+ if (timer) clearTimeout(timer);
3061
+ timer = setTimeout(() => {
3062
+ timer = null;
3063
+ void rebuild(label);
3064
+ }, debounceMs);
3065
+ };
3066
+ await rebuild("initial");
3067
+ const watchers = [];
3068
+ for (const w of watchRoots) {
3069
+ try {
3070
+ const watcher = fs8.watch(w, { recursive: true }, (_event, filename) => {
3071
+ if (!filename) {
3072
+ schedule("change");
3073
+ return;
3074
+ }
3075
+ const parts = filename.split(path37.sep);
3076
+ if (parts.some((p) => SKIP_NAME.has(p))) return;
3077
+ if (filename.includes(`${path37.sep}.vibgrate${path37.sep}`) || filename.startsWith(".vibgrate")) {
3078
+ return;
3079
+ }
3080
+ schedule(filename);
3081
+ });
3082
+ watchers.push(watcher);
3083
+ } catch (err) {
3084
+ throw new CliError(`cannot watch ${w}: ${err.message}`, ExitCode.ERROR);
2922
3085
  }
2923
- info(` ${c.bold(`aggregate \u2248 ${tokenReduction.aggregateRatio.toFixed(1)}\xD7 fewer tokens`)} ${c.dim("(honest estimate, scales with repo size)")}`);
2924
3086
  }
3087
+ info(c.dim(`vg watch \xB7 watching ${watchRoots.map((p) => path37.relative(root2, p) || ".").join(", ")} (debounce ${debounceMs}ms) \xB7 Ctrl+C to stop`));
3088
+ await new Promise((resolve20) => {
3089
+ const stop = () => {
3090
+ for (const w of watchers) w.close();
3091
+ if (timer) clearTimeout(timer);
3092
+ resolve20();
3093
+ };
3094
+ process.once("SIGINT", stop);
3095
+ process.once("SIGTERM", stop);
3096
+ });
2925
3097
  });
2926
3098
  applyGlobalOptions(cmd);
2927
3099
  }
2928
- async function runBenchmarkSuite(root2, budget) {
2929
- const baseline = process.memoryUsage();
2930
- const sampler = startMemorySampler();
2931
- const t0 = now();
2932
- const cold = await buildGraph({ root: root2, generatedAt: PIN, noCache: true });
2933
- const coldMs = now() - t0;
2934
- const t1 = now();
2935
- const warm = await buildGraph({ root: root2, generatedAt: PIN });
2936
- const warmMs = now() - t1;
2937
- const a = serializeGraph(cold.graph);
2938
- const b = serializeGraph((await buildGraph({ root: root2, generatedAt: PIN, noCache: true })).graph);
2939
- const peak = sampler.stop();
2940
- const deterministic = a === b;
2941
- const after = process.memoryUsage();
2942
- const corpusBytes = cold.fileStats.reduce((s, f) => s + f.size, 0);
2943
- const graphJsonBytes = Buffer.byteLength(a, "utf8");
2944
- const nodes = cold.graph.meta.counts.nodes;
2945
- const questions = deriveQuestions(cold.graph);
2946
- const fileSizes = fileSizeIndex(root2);
2947
- const perQuestion = questions.map((q) => {
2948
- const vgTokens = queryGraph(cold.graph, q, { budget }).tokensEstimate;
2949
- const baseTokens = grepBaselineTokens(q, fileSizes);
2950
- return { question: q, vgTokens, baselineTokens: baseTokens, ratio: baseTokens > 0 ? round(baseTokens / Math.max(vgTokens, 1)) : 1 };
2951
- });
2952
- const totalVg = perQuestion.reduce((s, x) => s + x.vgTokens, 0);
2953
- const totalBase = perQuestion.reduce((s, x) => s + x.baselineTokens, 0);
2954
- const aggregateRatio = totalVg > 0 ? round(totalBase / totalVg) : 0;
2955
- return {
2956
- repo: { files: cold.totalFiles, nodes, edges: cold.graph.meta.counts.edges },
2957
- build: { coldMs: round(coldMs), incrementalMs: round(warmMs), reusedOnWarm: warm.reused },
2958
- throughput: {
2959
- corpusBytes,
2960
- filesPerSec: coldMs > 0 ? round(cold.totalFiles / coldMs * 1e3) : 0,
2961
- // 6-decimal precision: a small corpus at 3 decimals would round to 0.
2962
- mbPerSec: coldMs > 0 ? round6(mb2(corpusBytes) / coldMs * 1e3) : 0
2963
- },
2964
- memory: {
2965
- baselineRssMb: round(mb2(baseline.rss)),
2966
- peakRssMb: round(mb2(Math.max(peak.rss, baseline.rss))),
2967
- peakHeapMb: round(mb2(Math.max(peak.heapUsed, baseline.heapUsed))),
2968
- // Heap growth across the run ≈ what the loaded graphs + caches retain.
2969
- retainedHeapMb: round(Math.max(0, mb2(after.heapUsed - baseline.heapUsed))),
2970
- graphJsonBytes,
2971
- bytesPerNode: nodes > 0 ? round(graphJsonBytes / nodes) : 0,
2972
- note: "sampled at 25ms + phase boundaries; GC timing makes these approximate"
2973
- },
2974
- limits: resolveLimits(),
2975
- determinism: { byteIdentical: deterministic },
2976
- tokenReduction: { questions: perQuestion, aggregateRatio, note: "estimates (~4 chars/token); scales with repo size" }
2977
- };
2978
- }
2979
- function startMemorySampler() {
2980
- let rss = 0;
2981
- let heapUsed = 0;
2982
- const sample = () => {
2983
- const m = process.memoryUsage();
2984
- if (m.rss > rss) rss = m.rss;
2985
- if (m.heapUsed > heapUsed) heapUsed = m.heapUsed;
2986
- };
2987
- const timer = setInterval(sample, 25);
2988
- timer.unref?.();
2989
- return {
2990
- stop: () => {
2991
- clearInterval(timer);
2992
- sample();
2993
- return { rss, heapUsed };
2994
- }
2995
- };
2996
- }
2997
- function deriveQuestions(graph) {
2998
- return graph.nodes.filter((n) => n.kind !== "file" && n.kind !== "external").sort((a, b) => b.importance - a.importance || a.qualifiedName.localeCompare(b.qualifiedName)).slice(0, 5).map((n) => n.name);
2999
- }
3000
- function fileSizeIndex(root2) {
3001
- return discover({ root: root2 }).map((f) => ({ rel: f.rel, abs: f.abs, size: safeSize(f.abs) }));
3002
- }
3003
- function grepBaselineTokens(term, files) {
3004
- const lower = term.toLowerCase();
3005
- let bytes = 0;
3006
- for (const f of files) {
3007
- if (f.size > 512 * 1024) continue;
3008
- let content = "";
3009
- try {
3010
- content = fs8.readFileSync(f.abs, "utf8");
3011
- } catch {
3012
- continue;
3013
- }
3014
- if (content.toLowerCase().includes(lower)) bytes += content.length;
3015
- }
3016
- return Math.ceil(bytes / 4);
3017
- }
3018
- function safeSize(abs) {
3019
- try {
3020
- return fs8.statSync(abs).size;
3021
- } catch {
3022
- return 0;
3023
- }
3024
- }
3025
- function mb2(bytes) {
3026
- return bytes / (1024 * 1024);
3027
- }
3028
- function now() {
3029
- return Number(process.hrtime.bigint() / 1000n) / 1e3;
3030
- }
3031
- function round(x) {
3032
- return Math.round(x * 1e3) / 1e3;
3033
- }
3034
- function round6(x) {
3035
- return Math.round(x * 1e6) / 1e6;
3036
- }
3037
- function pad3(s, n) {
3038
- return s.padStart(n, " ");
3039
- }
3040
3100
  function registerTests(program) {
3041
3101
  const cmd = program.command("tests").description("which tests cover a node (call/coverage linkage)").argument("<name>", "node to inspect").option("--missing", "show untested nodes nearby instead").option("--run", "print the command to run exactly these tests").option("--exec", "run that command").option("--pick <n>", "pick the nth candidate when ambiguous").action(function(name, opts) {
3042
3102
  const global = readGlobal(this);
@@ -3092,8 +3152,17 @@ function registerFacts(program) {
3092
3152
  const { node: node2, candidates } = resolveOne(graph, name, opts.pick ? Number(opts.pick) : void 0);
3093
3153
  if (!node2) throw ambiguityError(`"${name}" ${candidates.length ? "is ambiguous" : "not found"}`, candidates);
3094
3154
  if (!graph.facts) {
3095
- if (global.json) json({ node: node2.qualifiedName, facts: [], note: "facts require a --deep build" });
3096
- else info(`${c.cyan("vg facts")} \xB7 run ${c.bold("vg --deep")} to derive facts (none in this map)`);
3155
+ if (global.json) {
3156
+ json({
3157
+ node: node2.qualifiedName,
3158
+ facts: [],
3159
+ note: "map has no facts \u2014 rebuild with a current vg (facts ship on every build)"
3160
+ });
3161
+ } else {
3162
+ info(
3163
+ `${c.cyan("vg facts")} \xB7 none in this map \u2014 rebuild with ${c.bold("vg")} (facts ship on every build)`
3164
+ );
3165
+ }
3097
3166
  return;
3098
3167
  }
3099
3168
  const facts = graph.facts.filter((f) => f.subjectIds.includes(node2.id));
@@ -3348,7 +3417,7 @@ function normalizeStandards(raw) {
3348
3417
  }
3349
3418
  function loadStandards(root2) {
3350
3419
  for (const rel of STANDARDS_FILES) {
3351
- const p = path36__default.join(root2, rel);
3420
+ const p = path37__default.join(root2, rel);
3352
3421
  let text;
3353
3422
  try {
3354
3423
  text = fs8__default.readFileSync(p, "utf8");
@@ -4224,8 +4293,8 @@ async function runHostBench(options = {}) {
4224
4293
  }
4225
4294
  async function runArmSimulate(input) {
4226
4295
  const { arm, lib, modelPath, turns, trie, env, live } = input;
4227
- const path38 = `${modelPath}#${arm.id}`;
4228
- const session = await acquireHostSession(lib, path38);
4296
+ const path39 = `${modelPath}#${arm.id}`;
4297
+ const session = await acquireHostSession(lib, path39);
4229
4298
  const system = "You are a coding agent with a Task Capsule.";
4230
4299
  const capsule = "function readConfig(): Config { return load(); }";
4231
4300
  let last = null;
@@ -5167,7 +5236,7 @@ function registerModels(program) {
5167
5236
  );
5168
5237
  });
5169
5238
  applyGlobalOptions(modeCmd);
5170
- const resolve19 = cmd.command("resolve").description("resolve a Code Mode to pack + underlying model + fit (no download)").argument("[mode]", "spark | flow | forge (default: auto-fit or configured default)").action(function(modeArg) {
5239
+ const resolve20 = cmd.command("resolve").description("resolve a Code Mode to pack + underlying model + fit (no download)").argument("[mode]", "spark | flow | forge (default: auto-fit or configured default)").action(function(modeArg) {
5171
5240
  const global = readGlobal(this);
5172
5241
  const root2 = rootOf(global);
5173
5242
  const sys = gatherSystemMemory();
@@ -5199,7 +5268,7 @@ function registerModels(program) {
5199
5268
  info(c.yellow(" will not fit \u2014 choose a lower mode or free memory before loading"));
5200
5269
  }
5201
5270
  });
5202
- applyGlobalOptions(resolve19);
5271
+ applyGlobalOptions(resolve20);
5203
5272
  const installCmd = cmd.command("install").description("resolve the best Code Mode for this machine and install the pack").argument("[mode]", "spark | flow | forge (default: auto-fit)").option("--dry-run", "print the install plan only \u2014 do not download").option("--yes", "skip prompts (install already runs by default)").action(async function(modeArg, opts) {
5204
5273
  const global = readGlobal(this);
5205
5274
  const root2 = rootOf(global);
@@ -5537,8 +5606,8 @@ function registerModels(program) {
5537
5606
  }
5538
5607
  });
5539
5608
  if (opts.out) {
5540
- const outPath = path36.resolve(opts.out);
5541
- fs8.mkdirSync(path36.dirname(outPath), { recursive: true });
5609
+ const outPath = path37.resolve(opts.out);
5610
+ fs8.mkdirSync(path37.dirname(outPath), { recursive: true });
5542
5611
  fs8.writeFileSync(outPath, `${JSON.stringify(report, null, 2)}
5543
5612
  `);
5544
5613
  if (!global.json) info(c.dim(` wrote ${outPath}`));
@@ -5649,11 +5718,11 @@ function fitColor(label) {
5649
5718
  return label;
5650
5719
  }
5651
5720
  function confirmYesNo(question) {
5652
- return new Promise((resolve19) => {
5721
+ return new Promise((resolve20) => {
5653
5722
  const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
5654
5723
  rl.question(`${question} [y/N] `, (answer) => {
5655
5724
  rl.close();
5656
- resolve19(/^y(es)?$/i.test(answer.trim()));
5725
+ resolve20(/^y(es)?$/i.test(answer.trim()));
5657
5726
  });
5658
5727
  });
5659
5728
  }
@@ -5679,7 +5748,7 @@ function printBackends(backends) {
5679
5748
  }
5680
5749
  }
5681
5750
  function codeConfigPath(root2) {
5682
- return path36.join(root2, ".vibgrate", "code.json");
5751
+ return path37.join(root2, ".vibgrate", "code.json");
5683
5752
  }
5684
5753
  function loadCodeConfig(root2) {
5685
5754
  try {
@@ -5761,7 +5830,7 @@ function discoverMcpServers(root2, ownServers) {
5761
5830
  const servers = {};
5762
5831
  const sources = [];
5763
5832
  for (const rel of MCP_CONFIG_FILES) {
5764
- const found = readMcpServersFile(path36.join(root2, rel));
5833
+ const found = readMcpServersFile(path37.join(root2, rel));
5765
5834
  const names = Object.keys(found);
5766
5835
  if (names.length) {
5767
5836
  sources.push(rel);
@@ -5786,9 +5855,9 @@ function registerCode(program) {
5786
5855
  const modeFlag = opts.mode ?? config.modelProfile?.mode;
5787
5856
  if (!opts.model && !opts.modelPath && (modeFlag || !provider && !model)) {
5788
5857
  try {
5789
- const { parseMode: parseMode2, resolveMode: resolveMode2, readOrchestratorState: readOrchestratorState2, activePin: activePin2, providerForBackend: providerForBackend2 } = await import('./model-orchestrator-FFTZI3U2.js');
5790
- const { gatherSystemMemory: gatherSystemMemory2 } = await import('./local-runtime-OJFLX2HI.js');
5791
- const { loadGraph: loadGraph2 } = await import('./load-OHVKDX4R.js');
5858
+ const { parseMode: parseMode2, resolveMode: resolveMode2, readOrchestratorState: readOrchestratorState2, activePin: activePin2, providerForBackend: providerForBackend2 } = await import('./model-orchestrator-TVONAUPS.js');
5859
+ const { gatherSystemMemory: gatherSystemMemory2 } = await import('./local-runtime-5O2NN3GA.js');
5860
+ const { loadGraph: loadGraph2 } = await import('./load-QPOWQD7C.js');
5792
5861
  const state = readOrchestratorState2();
5793
5862
  const mode = parseMode2(modeFlag) ?? state.defaultMode ?? void 0;
5794
5863
  const pin = mode ? activePin2(mode, state) : null;
@@ -5817,7 +5886,7 @@ function registerCode(program) {
5817
5886
  ExitCode.ERROR
5818
5887
  );
5819
5888
  }
5820
- const { resolveGgufPath } = await import('./resolve-gguf-4UPIGPEE.js');
5889
+ const { resolveGgufPath } = await import('./resolve-gguf-VPL4YQ6J.js');
5821
5890
  const gguf = resolveGgufPath({
5822
5891
  modelRef: resolved.underlying.weightsRef,
5823
5892
  modelPath: opts.modelPath
@@ -5872,7 +5941,7 @@ function registerCode(program) {
5872
5941
  if (!(process.stdin.isTTY && process.stdout.isTTY)) {
5873
5942
  throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"` (guided mode needs an interactive terminal)');
5874
5943
  }
5875
- const { runInteractive } = await import('./interactive-ICL7D7LO.js');
5944
+ const { runInteractive } = await import('./interactive-INGJNSON.js');
5876
5945
  await runInteractive(
5877
5946
  rootOf(global),
5878
5947
  global,
@@ -5926,18 +5995,18 @@ function registerCode(program) {
5926
5995
  }
5927
5996
  if (opts.streamJson && !opts.mock) {
5928
5997
  const primarySlug = route.providers[0]?.model.includes("/") ? route.providers[0].model.split("/")[0] : route.providers[0]?.id;
5929
- const { runCodeStreamJson } = await import('./stream-json-F74W5FCK.js');
5930
- const { nodeCodeFs } = await import('./session-L2OSDRPI.js');
5998
+ const { runCodeStreamJson } = await import('./stream-json-6ZBUA2L3.js');
5999
+ const { nodeCodeFs } = await import('./session-M72522AP.js');
5931
6000
  const readline5 = await import('readline');
5932
6001
  const child = await import('child_process');
5933
- const { loadOrDiscoverFederation } = await import('./federation-EPZDUWCK.js');
5934
- const { resolveExecutionEnv } = await import('./execution-env-3BN7Z737.js');
5935
- const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-MQ2QCP24.js');
5936
- const { startCodeRuntimeSession } = await import('./runtime-session-IDU5BDUJ.js');
5937
- const { resolveGraphBackend } = await import('./graph-backend-ZMSYOZMW.js');
5938
- const { detectGitRef } = await import('./git-ref-HPRLUFFW.js');
5939
- const { repositoryIdFromRoot } = await import('./paths-MCH75O3G.js');
5940
- const { vgdRequest: vgdRequest2 } = await import('./vgd-EGBQD7BW.js');
6002
+ const { loadOrDiscoverFederation } = await import('./federation-SZWZIFZ7.js');
6003
+ const { resolveExecutionEnv } = await import('./execution-env-ZU45JZ4G.js');
6004
+ const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-TFBKCNJG.js');
6005
+ const { startCodeRuntimeSession } = await import('./runtime-session-4AMZIAAG.js');
6006
+ const { resolveGraphBackend } = await import('./graph-backend-UTOL3SHE.js');
6007
+ const { detectGitRef } = await import('./git-ref-XDXB6JP5.js');
6008
+ const { repositoryIdFromRoot } = await import('./paths-2RAH3GME.js');
6009
+ const { vgdRequest: vgdRequest2 } = await import('./vgd-CVLKBS7K.js');
5941
6010
  const federation = loadOrDiscoverFederation(root2);
5942
6011
  const modelProfile = mergeModelExecutionProfile(
5943
6012
  resolveModelExecutionProfile({
@@ -6026,12 +6095,12 @@ ${res.stderr}` : ""), exitCode: res.status ?? 1 };
6026
6095
  if (!autonomous && !tty) {
6027
6096
  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).");
6028
6097
  }
6029
- const { agentTask } = await import('./interactive-ICL7D7LO.js');
6030
- const { nodeCodeFs } = await import('./session-L2OSDRPI.js');
6031
- const { TtyPrompter } = await import('./ui-HOVOPWMX.js');
6098
+ const { agentTask } = await import('./interactive-INGJNSON.js');
6099
+ const { nodeCodeFs } = await import('./session-M72522AP.js');
6100
+ const { TtyPrompter } = await import('./ui-Q6DJ3GCU.js');
6032
6101
  let priorSummary;
6033
6102
  if (opts.continue) {
6034
- const { loadLatestSession, summarizeSession } = await import('./session-store-W5RZZHA3.js');
6103
+ const { loadLatestSession, summarizeSession } = await import('./session-store-WFBX7HXL.js');
6035
6104
  const prev = loadLatestSession(root2);
6036
6105
  if (prev) priorSummary = summarizeSession(prev);
6037
6106
  }
@@ -6039,21 +6108,21 @@ ${res.stderr}` : ""), exitCode: res.status ?? 1 };
6039
6108
  let mcpTools;
6040
6109
  let disposeMcp;
6041
6110
  if (Object.keys(mcp.servers).length) {
6042
- const { McpToolset, defaultMcpConnect } = await import('./mcp-tools-I6PME3AV.js');
6111
+ const { McpToolset, defaultMcpConnect } = await import('./mcp-tools-I7JK3S2M.js');
6043
6112
  const { toolset } = await McpToolset.connect(mcp.servers, defaultMcpConnect);
6044
6113
  disposeMcp = () => toolset.dispose();
6045
6114
  const approve = async (a) => autonomous || !!(prompter && a.kind === "tool" && await prompter.confirm("Call an external tool?", false));
6046
6115
  mcpTools = { specs: toolset.specs(), owns: (n) => toolset.owns(n), execute: (call) => toolset.execute(call, approve) };
6047
6116
  }
6048
6117
  try {
6049
- const { loadFederation } = await import('./federation-EPZDUWCK.js');
6050
- const { resolveExecutionEnv } = await import('./execution-env-3BN7Z737.js');
6051
- const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-MQ2QCP24.js');
6052
- const { startCodeRuntimeSession } = await import('./runtime-session-IDU5BDUJ.js');
6053
- const { resolveGraphBackend } = await import('./graph-backend-ZMSYOZMW.js');
6054
- const { detectGitRef } = await import('./git-ref-HPRLUFFW.js');
6055
- const { repositoryIdFromRoot } = await import('./paths-MCH75O3G.js');
6056
- const { vgdRequest: vgdRequest2 } = await import('./vgd-EGBQD7BW.js');
6118
+ const { loadFederation } = await import('./federation-SZWZIFZ7.js');
6119
+ const { resolveExecutionEnv } = await import('./execution-env-ZU45JZ4G.js');
6120
+ const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-TFBKCNJG.js');
6121
+ const { startCodeRuntimeSession } = await import('./runtime-session-4AMZIAAG.js');
6122
+ const { resolveGraphBackend } = await import('./graph-backend-UTOL3SHE.js');
6123
+ const { detectGitRef } = await import('./git-ref-XDXB6JP5.js');
6124
+ const { repositoryIdFromRoot } = await import('./paths-2RAH3GME.js');
6125
+ const { vgdRequest: vgdRequest2 } = await import('./vgd-CVLKBS7K.js');
6057
6126
  const federation = loadFederation(root2);
6058
6127
  const modelProfile = mergeModelExecutionProfile(
6059
6128
  resolveModelExecutionProfile({
@@ -6197,11 +6266,11 @@ function resolveSecurityTierFlag(flag, fromConfig, auto) {
6197
6266
  return auto ? "L1" : "L0";
6198
6267
  }
6199
6268
  function confirm(question) {
6200
- return new Promise((resolve19) => {
6269
+ return new Promise((resolve20) => {
6201
6270
  const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
6202
6271
  rl.question(`${question} [y/N] `, (answer) => {
6203
6272
  rl.close();
6204
- resolve19(/^y(es)?$/i.test(answer.trim()));
6273
+ resolve20(/^y(es)?$/i.test(answer.trim()));
6205
6274
  });
6206
6275
  });
6207
6276
  }
@@ -6223,10 +6292,10 @@ function registerSavings(program) {
6223
6292
  );
6224
6293
  return;
6225
6294
  }
6226
- const now2 = Date.now();
6227
- const report = readSavings(root2, days, now2);
6228
- const usage = readUsage(root2, days, now2);
6229
- const models = readModelSavings(root2, days, now2);
6295
+ const now = Date.now();
6296
+ const report = readSavings(root2, days, now);
6297
+ const usage = readUsage(root2, days, now);
6298
+ const models = readModelSavings(root2, days, now);
6230
6299
  if (global.json) {
6231
6300
  json({ ...report, usage, models });
6232
6301
  return;
@@ -6358,7 +6427,7 @@ async function addCmd(root2, rest, opts, asJson) {
6358
6427
  }
6359
6428
  function readPackageVersion(root2) {
6360
6429
  try {
6361
- const pkg = JSON.parse(fs8__default.readFileSync(path36__default.join(root2, "package.json"), "utf8"));
6430
+ const pkg = JSON.parse(fs8__default.readFileSync(path37__default.join(root2, "package.json"), "utf8"));
6362
6431
  return typeof pkg.version === "string" ? pkg.version : void 0;
6363
6432
  } catch {
6364
6433
  return void 0;
@@ -6381,8 +6450,8 @@ async function publishCmd(root2, rest, opts, global, asJson) {
6381
6450
  if (!parsed) throw new CliError("publishing a private library requires a DSN \u2014 run `vibgrate login` or set VIBGRATE_DSN", ExitCode.USAGE_ERROR);
6382
6451
  const version = (opts.version || readPackageVersion(root2) || "").trim();
6383
6452
  if (!version) throw usageError("a --version is required (or run from a package whose package.json has a version)");
6384
- const readme = readOptionalFile(opts.readme ? path36__default.resolve(opts.readme) : path36__default.join(root2, "README.md"));
6385
- const dts = opts.dts ? readOptionalFile(path36__default.resolve(opts.dts)) : void 0;
6453
+ const readme = readOptionalFile(opts.readme ? path37__default.resolve(opts.readme) : path37__default.join(root2, "README.md"));
6454
+ const dts = opts.dts ? readOptionalFile(path37__default.resolve(opts.dts)) : void 0;
6386
6455
  if (!readme && !dts) throw usageError("nothing to publish \u2014 no README.md found and no --dts given");
6387
6456
  const result = await publishPrivateLibrary(
6388
6457
  { name, version, readme, dts, language: opts.language },
@@ -6495,7 +6564,7 @@ async function showCmd(root2, name, budget, asJson, opts = {}) {
6495
6564
  out(doc);
6496
6565
  }
6497
6566
  function registerExport(program) {
6498
- const cmd = program.command("export").description("export the map (format inferred: json|ndjson|graphml|dot|cypher|sql|md|html|cdx.json|spdx.json)").argument("[file]", "target file (or - for stdout)", "map.json").action(function(file) {
6567
+ const cmd = program.command("export").description("export the map (format inferred: json|ndjson|graphml|dot|cypher|sql|md|html|cdx.json|spdx.json)").argument("[file]", "target file (or - for stdout)", "map.json").option("--compact", "compact JSON (no pretty-print; auto for large maps)").option("--slim", "drop heavy fields (area member lists, grounding) for smaller exports").action(function(file, opts) {
6499
6568
  const global = readGlobal(this);
6500
6569
  const { graph } = requireGraph(global);
6501
6570
  const root2 = rootOf(global);
@@ -6506,13 +6575,15 @@ function registerExport(program) {
6506
6575
  graph,
6507
6576
  deps: needsDeps ? inventory(root2).records : void 0,
6508
6577
  models: needsDeps && !global.local ? discoverModels() : void 0,
6509
- generatedAt: graph.generatedAt
6578
+ generatedAt: graph.generatedAt,
6579
+ compact: opts.compact === true ? true : opts.compact === false ? false : void 0,
6580
+ slim: opts.slim === true
6510
6581
  });
6511
6582
  if (file === "-") {
6512
6583
  out(content.trimEnd());
6513
6584
  return;
6514
6585
  }
6515
- fs8.mkdirSync(path36.dirname(path36.resolve(file)), { recursive: true });
6586
+ fs8.mkdirSync(path37.dirname(path37.resolve(file)), { recursive: true });
6516
6587
  fs8.writeFileSync(file, content);
6517
6588
  info(`${c.green("\u2714")} wrote ${file} ${c.dim(`(${format})`)}`);
6518
6589
  });
@@ -6523,37 +6594,37 @@ function detectFormat(file) {
6523
6594
  if (lower.endsWith(".cdx.json")) return "cyclonedx";
6524
6595
  if (lower.endsWith(".spdx.json")) return "spdx";
6525
6596
  if (file === "-") return "json";
6526
- return formatForExt(path36.extname(file));
6597
+ return formatForExt(path37.extname(file));
6527
6598
  }
6528
6599
  function registerBundle(program) {
6529
6600
  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) {
6530
6601
  const global = readGlobal(this);
6531
6602
  const root2 = rootOf(global);
6532
- const outDir = path36.resolve(root2, opts.out ?? "vg-bundle");
6603
+ const outDir = path37.resolve(root2, opts.out ?? "vg-bundle");
6533
6604
  let grammarFiles;
6534
6605
  try {
6535
6606
  grammarFiles = resolvedGrammarFiles();
6536
6607
  } catch {
6537
6608
  throw new CliError("no grammars found to bundle (run a build first)", ExitCode.ERROR);
6538
6609
  }
6539
- fs8.mkdirSync(path36.join(outDir, "grammars"), { recursive: true });
6610
+ fs8.mkdirSync(path37.join(outDir, "grammars"), { recursive: true });
6540
6611
  let grammarCount = 0;
6541
6612
  for (const { fileName, absPath } of grammarFiles) {
6542
- fs8.copyFileSync(absPath, path36.join(outDir, "grammars", fileName));
6613
+ fs8.copyFileSync(absPath, path37.join(outDir, "grammars", fileName));
6543
6614
  grammarCount++;
6544
6615
  }
6545
6616
  const included = [`grammars/ (${grammarCount} .wasm)`];
6546
6617
  const graphSrc = resolveGraphPath(root2, global.graph);
6547
6618
  if (fs8.existsSync(graphSrc)) {
6548
- fs8.copyFileSync(graphSrc, path36.join(outDir, "graph.json"));
6619
+ fs8.copyFileSync(graphSrc, path37.join(outDir, "graph.json"));
6549
6620
  included.push("graph.json");
6550
6621
  }
6551
6622
  const cat = catalogPath(root2);
6552
6623
  if (fs8.existsSync(cat)) {
6553
- fs8.copyFileSync(cat, path36.join(outDir, "vibgrate.lib.json"));
6624
+ fs8.copyFileSync(cat, path37.join(outDir, "vibgrate.lib.json"));
6554
6625
  included.push("vibgrate.lib.json");
6555
6626
  if (fs8.existsSync(libDir(root2))) {
6556
- fs8.cpSync(libDir(root2), path36.join(outDir, "lib"), { recursive: true });
6627
+ fs8.cpSync(libDir(root2), path37.join(outDir, "lib"), { recursive: true });
6557
6628
  included.push("lib/");
6558
6629
  }
6559
6630
  }
@@ -6565,15 +6636,15 @@ function registerBundle(program) {
6565
6636
  included,
6566
6637
  usage: "Run `vg build --grammars <this dir>/grammars` to build fully offline."
6567
6638
  };
6568
- fs8.writeFileSync(path36.join(outDir, "MANIFEST.json"), `${stableStringify(manifest, 2)}
6639
+ fs8.writeFileSync(path37.join(outDir, "MANIFEST.json"), `${stableStringify(manifest, 2)}
6569
6640
  `);
6570
6641
  if (global.json) {
6571
- json({ out: path36.relative(root2, outDir), ...manifest });
6642
+ json({ out: path37.relative(root2, outDir), ...manifest });
6572
6643
  return;
6573
6644
  }
6574
- info(`${c.cyan("vg bundle")} \xB7 wrote ${path36.relative(root2, outDir)}/`);
6645
+ info(`${c.cyan("vg bundle")} \xB7 wrote ${path37.relative(root2, outDir)}/`);
6575
6646
  for (const i of included) info(` ${c.green("\u2714")} ${i}`);
6576
- info(c.dim(` offline: vg build --grammars "${path36.relative(root2, outDir)}/grammars"`));
6647
+ info(c.dim(` offline: vg build --grammars "${path37.relative(root2, outDir)}/grammars"`));
6577
6648
  });
6578
6649
  applyGlobalOptions(cmd);
6579
6650
  }
@@ -6591,7 +6662,7 @@ async function runDoctor(global) {
6591
6662
  const root2 = rootOf(global);
6592
6663
  const local = global.local === true;
6593
6664
  const graphPath = resolveGraphPath(root2, global.graph);
6594
- const configFile = CONFIG_BASENAMES.find((f) => fs8.existsSync(path36.join(root2, f))) ?? null;
6665
+ const configFile = CONFIG_BASENAMES.find((f) => fs8.existsSync(path37.join(root2, f))) ?? null;
6595
6666
  const graph = loadGraph(root2, graphPath);
6596
6667
  let staleFiles = null;
6597
6668
  if (graph) {
@@ -6617,13 +6688,13 @@ async function runDoctor(global) {
6617
6688
  root: root2,
6618
6689
  configFile,
6619
6690
  map: {
6620
- path: path36.relative(root2, graphPath),
6691
+ path: path37.relative(root2, graphPath),
6621
6692
  built: graph !== null,
6622
6693
  generatedAt: graph?.generatedAt ?? null,
6623
6694
  staleFiles
6624
6695
  },
6625
6696
  libCatalog: {
6626
- path: path36.relative(root2, catalogPath(root2)),
6697
+ path: path37.relative(root2, catalogPath(root2)),
6627
6698
  present: fs8.existsSync(catalogPath(root2)),
6628
6699
  libraries: libCount
6629
6700
  },
@@ -6681,7 +6752,7 @@ async function runDoctor(global) {
6681
6752
  );
6682
6753
  info(
6683
6754
  ` host pool ${li.hostPool.size} warm session(s)` + (li.hostPool.sessions[0] ? c.dim(
6684
- ` \xB7 last ${path36.basename(li.hostPool.sessions[0].modelPath)} kv=${li.hostPool.sessions[0].kvBlocks}`
6755
+ ` \xB7 last ${path37.basename(li.hostPool.sessions[0].modelPath)} kv=${li.hostPool.sessions[0].kvBlocks}`
6685
6756
  ) : c.dim(" \xB7 none (load via vg code / vgd host-load)"))
6686
6757
  );
6687
6758
  if (li.dynamicOnToken || li.dynamicCustomSampler) {
@@ -6817,7 +6888,7 @@ function registerDaemon(program) {
6817
6888
  const register = cmd.command("register").description("register the current repository with a running vgd").argument("[root]", "repository root (default: cwd)").action(async function(rootArg) {
6818
6889
  const global = readGlobal(this);
6819
6890
  const socketPath = socketOf(this);
6820
- const root2 = path36.resolve(rootArg ?? rootOf(global));
6891
+ const root2 = path37.resolve(rootArg ?? rootOf(global));
6821
6892
  if (!await vgdIsRunning({ socketPath })) {
6822
6893
  throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
6823
6894
  }
@@ -6853,11 +6924,11 @@ function registerDaemon(program) {
6853
6924
  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) {
6854
6925
  const global = readGlobal(this);
6855
6926
  const socketPath = socketOf(this);
6856
- const primary = path36.resolve(rootArg ?? rootOf(global));
6927
+ const primary = path37.resolve(rootArg ?? rootOf(global));
6857
6928
  if (!await vgdIsRunning({ socketPath })) {
6858
6929
  throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
6859
6930
  }
6860
- const { loadFederation } = await import('./federation-EPZDUWCK.js');
6931
+ const { loadFederation } = await import('./federation-SZWZIFZ7.js');
6861
6932
  const fed = loadFederation(primary);
6862
6933
  if (!fed) throw new CliError(`could not load federation for ${primary}`, ExitCode.ERROR);
6863
6934
  const res = await vgdRequest(
@@ -6881,13 +6952,13 @@ function registerDaemon(program) {
6881
6952
  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) {
6882
6953
  const global = readGlobal(this);
6883
6954
  const socketPath = socketOf(this);
6884
- const root2 = path36.resolve(rootArg ?? rootOf(global));
6955
+ const root2 = path37.resolve(rootArg ?? rootOf(global));
6885
6956
  if (!await vgdIsRunning({ socketPath })) {
6886
6957
  throw new CliError(`vgd is not running \u2014 start it with \`vg daemon ensure\` (${socketPath})`, ExitCode.NOT_FOUND);
6887
6958
  }
6888
- const { loadGraph: loadGraph2 } = await import('./load-OHVKDX4R.js');
6889
- const { detectGitRef } = await import('./git-ref-HPRLUFFW.js');
6890
- const { repositoryIdFromRoot } = await import('./paths-MCH75O3G.js');
6959
+ const { loadGraph: loadGraph2 } = await import('./load-QPOWQD7C.js');
6960
+ const { detectGitRef } = await import('./git-ref-XDXB6JP5.js');
6961
+ const { repositoryIdFromRoot } = await import('./paths-2RAH3GME.js');
6891
6962
  const opts = this.opts();
6892
6963
  const graph = loadGraph2(root2, global.graph);
6893
6964
  if (!graph) {
@@ -7001,7 +7072,7 @@ function socketOf(cmd) {
7001
7072
  let c2 = cmd;
7002
7073
  while (c2) {
7003
7074
  const opts = c2.opts();
7004
- if (opts.socket) return path36.resolve(opts.socket);
7075
+ if (opts.socket) return path37.resolve(opts.socket);
7005
7076
  c2 = c2.parent;
7006
7077
  }
7007
7078
  return vgdSocketPath();
@@ -7025,7 +7096,7 @@ function sleep(ms) {
7025
7096
  return new Promise((r) => setTimeout(r, ms));
7026
7097
  }
7027
7098
  async function repositoryIdForCwd(socketPath, root2) {
7028
- const { repositoryIdFromRoot } = await import('./paths-MCH75O3G.js');
7099
+ const { repositoryIdFromRoot } = await import('./paths-2RAH3GME.js');
7029
7100
  const reg = await vgdRequest({ op: "register", root: root2 }, { socketPath });
7030
7101
  if (reg.ok && "workspace" in reg) return reg.workspace.id;
7031
7102
  return repositoryIdFromRoot(root2);
@@ -7218,11 +7289,11 @@ function registerLlmHost(program) {
7218
7289
  applyGlobalOptions(cmd);
7219
7290
  }
7220
7291
  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) => {
7221
- const rootDir = path36.resolve(targetPath);
7222
- const vibgrateDir2 = path36.join(rootDir, ".vibgrate");
7292
+ const rootDir = path37.resolve(targetPath);
7293
+ const vibgrateDir2 = path37.join(rootDir, ".vibgrate");
7223
7294
  await ensureDir(vibgrateDir2);
7224
7295
  console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold(".vibgrate/")} directory`);
7225
- const configPath = path36.join(rootDir, "vibgrate.config.ts");
7296
+ const configPath = path37.join(rootDir, "vibgrate.config.ts");
7226
7297
  if (await pathExists(configPath)) {
7227
7298
  console.log(chalk7.dim(" vibgrate.config.ts already exists, skipping"));
7228
7299
  } else {
@@ -7230,7 +7301,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
7230
7301
  console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
7231
7302
  }
7232
7303
  if (opts.baseline) {
7233
- const { runBaseline } = await import('./baseline-K7YBFKZI.js');
7304
+ const { runBaseline } = await import('./baseline-ATM5MXBZ.js');
7234
7305
  await runBaseline(rootDir);
7235
7306
  }
7236
7307
  console.log("");
@@ -7333,7 +7404,7 @@ function collectPackageImports(graph, ecosystem, pkg) {
7333
7404
  };
7334
7405
  }
7335
7406
  async function fileReferencesIdentifier(rootDir, relFile, identifier, readFile3) {
7336
- const content = await readFile3(path36.join(rootDir, relFile));
7407
+ const content = await readFile3(path37.join(rootDir, relFile));
7337
7408
  if (!content) return false;
7338
7409
  const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
7339
7410
  return new RegExp(`\\b${escaped}\\b`).test(content);
@@ -7527,7 +7598,7 @@ var AI_ASSISTANT_DETECTORS = [
7527
7598
  async function detectAiAssistant(rootDir) {
7528
7599
  for (const detector of AI_ASSISTANT_DETECTORS) {
7529
7600
  for (const file of detector.files) {
7530
- if (await pathExists$1(path36.join(rootDir, file))) {
7601
+ if (await pathExists$1(path37.join(rootDir, file))) {
7531
7602
  return detector.name;
7532
7603
  }
7533
7604
  }
@@ -7720,7 +7791,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
7720
7791
  collectExcludes,
7721
7792
  []
7722
7793
  ).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) => {
7723
- const rootDir = path36.resolve(targetPath);
7794
+ const rootDir = path37.resolve(targetPath);
7724
7795
  if (!await pathExists$1(rootDir)) {
7725
7796
  console.error(chalk7.red(`Path does not exist: ${rootDir}`));
7726
7797
  process.exit(1);
@@ -7728,7 +7799,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
7728
7799
  const hasDsn = !!resolveDsn(opts.dsn);
7729
7800
  const willPush = !opts.offline && (opts.push || hasDsn);
7730
7801
  const noLocalArtifacts = opts.localArtifacts === false;
7731
- const isFirstRun = !await pathExists$1(path36.join(rootDir, ".vibgrate", "scan_result.json"));
7802
+ const isFirstRun = !await pathExists$1(path37.join(rootDir, ".vibgrate", "scan_result.json"));
7732
7803
  let pinnedRegion;
7733
7804
  let planTier;
7734
7805
  let upgradeUrl;
@@ -8007,11 +8078,11 @@ function scanStaleness(rootDir, artifactPath) {
8007
8078
  scanned++;
8008
8079
  if (scanned > MAX_ENTRIES) break;
8009
8080
  if (e.isDirectory()) {
8010
- if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(path36.join(dir, e.name), depth + 1);
8081
+ if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(path37.join(dir, e.name), depth + 1);
8011
8082
  continue;
8012
8083
  }
8013
8084
  if (!WATCHED_FILES.has(e.name) && !WATCHED_EXT.test(e.name)) continue;
8014
- const abs = path36.join(dir, e.name);
8085
+ const abs = path37.join(dir, e.name);
8015
8086
  let mtimeMs;
8016
8087
  try {
8017
8088
  mtimeMs = fs8.statSync(abs).mtimeMs;
@@ -8020,7 +8091,7 @@ function scanStaleness(rootDir, artifactPath) {
8020
8091
  }
8021
8092
  if (mtimeMs > newest) {
8022
8093
  newest = mtimeMs;
8023
- newestChanged = path36.relative(rootDir, abs) || e.name;
8094
+ newestChanged = path37.relative(rootDir, abs) || e.name;
8024
8095
  }
8025
8096
  }
8026
8097
  };
@@ -8157,13 +8228,13 @@ function analyzeTree(root2, packages) {
8157
8228
  if (filesSeen >= MAX_FILES) return;
8158
8229
  if (entry.isDirectory()) {
8159
8230
  if (SKIP_DIRS3.has(entry.name) || entry.name.startsWith(".")) continue;
8160
- walk2(path36.join(dir, entry.name), depth + 1);
8231
+ walk2(path37.join(dir, entry.name), depth + 1);
8161
8232
  continue;
8162
8233
  }
8163
- const fileEco = EXT_ECOSYSTEM[path36.extname(entry.name)];
8234
+ const fileEco = EXT_ECOSYSTEM[path37.extname(entry.name)];
8164
8235
  if (!fileEco || fileEco === "unknown") continue;
8165
8236
  filesSeen++;
8166
- const full = path36.join(dir, entry.name);
8237
+ const full = path37.join(dir, entry.name);
8167
8238
  let content;
8168
8239
  try {
8169
8240
  if (fs8.statSync(full).size > MAX_FILE_BYTES2) continue;
@@ -8386,16 +8457,16 @@ function estimateDriftScore(artifact, upgraded) {
8386
8457
  const buckets = p.dependencyAgeBuckets;
8387
8458
  for (const dep of p.dependencies ?? []) {
8388
8459
  if (!upgraded.has(dep.package)) continue;
8389
- const mb3 = dep.majorsBehind ?? 0;
8460
+ const mb2 = dep.majorsBehind ?? 0;
8390
8461
  dep.majorsBehind = 0;
8391
8462
  dep.drift = "current";
8392
8463
  if (dep.libyears != null) dep.libyears = 0;
8393
8464
  if (dep.ageDays != null) dep.ageDays = 0;
8394
8465
  if (dep.latestStable) dep.resolvedVersion = dep.latestStable;
8395
- if (mb3 >= 2 && buckets.twoPlusBehind > 0) {
8466
+ if (mb2 >= 2 && buckets.twoPlusBehind > 0) {
8396
8467
  buckets.twoPlusBehind--;
8397
8468
  buckets.current++;
8398
- } else if (mb3 === 1 && buckets.oneBehind > 0) {
8469
+ } else if (mb2 === 1 && buckets.oneBehind > 0) {
8399
8470
  buckets.oneBehind--;
8400
8471
  buckets.current++;
8401
8472
  }
@@ -8478,7 +8549,7 @@ function applyPlan(rootDir, upgrades, opts = {}) {
8478
8549
  }
8479
8550
  const outcomes = effective.map((t) => {
8480
8551
  const c2 = pmCommandFor(u.ecosystem, u.package, u.to, opts.packageManager, { workspaceRoot: t.isWorkspaceRoot });
8481
- return { t, res: run(c2, path36.join(rootDir, t.dir)) };
8552
+ return { t, res: run(c2, path37.join(rootDir, t.dir)) };
8482
8553
  });
8483
8554
  const failures = outcomes.filter((o) => !o.res.ok);
8484
8555
  if (failures.length === 0) {
@@ -8507,8 +8578,8 @@ function applyPlan(rootDir, upgrades, opts = {}) {
8507
8578
  return results;
8508
8579
  }
8509
8580
  var REGISTRY_URL = "https://registry.npmjs.org/@vibgrate%2fcli/latest";
8510
- var CACHE_DIR = path36.join(os.homedir(), ".vibgrate");
8511
- var CACHE_FILE = path36.join(CACHE_DIR, "update-check.json");
8581
+ var CACHE_DIR = path37.join(os.homedir(), ".vibgrate");
8582
+ var CACHE_FILE = path37.join(CACHE_DIR, "update-check.json");
8512
8583
  async function fetchLatestVersion() {
8513
8584
  try {
8514
8585
  const controller = new AbortController();
@@ -8577,14 +8648,14 @@ async function findGlobalInstall(pkg = PACKAGE_NAME, run = defaultRunner) {
8577
8648
  pm: "yarn",
8578
8649
  root: () => {
8579
8650
  const dir = tryRun("yarn global dir");
8580
- return dir ? path36.join(dir, "node_modules") : null;
8651
+ return dir ? path37.join(dir, "node_modules") : null;
8581
8652
  }
8582
8653
  },
8583
- { pm: "bun", root: () => path36.join(os.homedir(), ".bun", "install", "global", "node_modules") }
8654
+ { pm: "bun", root: () => path37.join(os.homedir(), ".bun", "install", "global", "node_modules") }
8584
8655
  ];
8585
8656
  for (const probe of probes) {
8586
8657
  const root2 = probe.root();
8587
- if (root2 && await pathExists(path36.join(root2, pkg))) return probe.pm;
8658
+ if (root2 && await pathExists(path37.join(root2, pkg))) return probe.pm;
8588
8659
  }
8589
8660
  return null;
8590
8661
  }
@@ -8603,15 +8674,15 @@ function getGlobalUpdateCommand(pm, pkg, version) {
8603
8674
  }
8604
8675
  }
8605
8676
  async function detectPackageManager(cwd) {
8606
- if (await pathExists(path36.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
8607
- if (await pathExists(path36.join(cwd, "bun.lockb"))) return "bun";
8608
- if (await pathExists(path36.join(cwd, "yarn.lock"))) return "yarn";
8677
+ if (await pathExists(path37.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
8678
+ if (await pathExists(path37.join(cwd, "bun.lockb"))) return "bun";
8679
+ if (await pathExists(path37.join(cwd, "yarn.lock"))) return "yarn";
8609
8680
  return "npm";
8610
8681
  }
8611
8682
  async function detectWorkspaceRoot(cwd) {
8612
- if (await pathExists(path36.join(cwd, "pnpm-workspace.yaml"))) return true;
8683
+ if (await pathExists(path37.join(cwd, "pnpm-workspace.yaml"))) return true;
8613
8684
  try {
8614
- const pkgPath = path36.join(cwd, "package.json");
8685
+ const pkgPath = path37.join(cwd, "package.json");
8615
8686
  const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
8616
8687
  const pkg = JSON.parse(raw);
8617
8688
  return pkg.workspaces != null;
@@ -8636,7 +8707,7 @@ function getInstallCommand(pm, pkg, version, isDev, opts = {}) {
8636
8707
  }
8637
8708
  async function getLocalDependencyState(cwd, pkg = PACKAGE_NAME) {
8638
8709
  try {
8639
- const pkgPath = path36.join(cwd, "package.json");
8710
+ const pkgPath = path37.join(cwd, "package.json");
8640
8711
  const raw = await (await import('fs/promises')).readFile(pkgPath, "utf-8");
8641
8712
  const parsed = JSON.parse(raw);
8642
8713
  if (parsed.devDependencies?.[pkg]) return "dev";
@@ -8648,11 +8719,11 @@ async function getLocalDependencyState(cwd, pkg = PACKAGE_NAME) {
8648
8719
  async function confirmWorkspaceRoot(pm) {
8649
8720
  if (!(process.stdin.isTTY && process.stdout.isTTY)) return false;
8650
8721
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
8651
- return new Promise((resolve19) => {
8722
+ return new Promise((resolve20) => {
8652
8723
  rl.question(chalk7.yellow(`Update the ${pm} workspace root with -w? [y/N]: `), (ans) => {
8653
8724
  rl.close();
8654
8725
  const t = ans.trim().toLowerCase();
8655
- resolve19(t === "y" || t === "yes");
8726
+ resolve20(t === "y" || t === "yes");
8656
8727
  });
8657
8728
  });
8658
8729
  }
@@ -8784,13 +8855,13 @@ function collectCandidates(artifact) {
8784
8855
  return out2;
8785
8856
  }
8786
8857
  var defaultFixScanner = async (rootDir) => {
8787
- const scratch = path36.join(os.tmpdir(), `vg-fix-scan-${process.pid}.json`);
8858
+ const scratch = path37.join(os.tmpdir(), `vg-fix-scan-${process.pid}.json`);
8788
8859
  const scanOpts = { vibgrateVersion: VERSION, format: "json", out: scratch, quiet: true, concurrency: 8 };
8789
8860
  const advanced = await loadAdvancedScanHook();
8790
8861
  return runCoreScan(rootDir, scanOpts, advanced);
8791
8862
  };
8792
8863
  async function loadArtifact(rootDir, inFile, scan = defaultFixScanner) {
8793
- const artifactPath = path36.isAbsolute(inFile) ? inFile : path36.join(rootDir, inFile);
8864
+ const artifactPath = path37.isAbsolute(inFile) ? inFile : path37.join(rootDir, inFile);
8794
8865
  if (await pathExists(artifactPath)) {
8795
8866
  const staleness = scanStaleness(rootDir, artifactPath);
8796
8867
  if (!staleness.stale) {
@@ -8817,7 +8888,7 @@ async function repositoryIdentity(rootDir, override) {
8817
8888
  }
8818
8889
  }
8819
8890
  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) => {
8820
- const rootDir = path36.resolve(targetPath);
8891
+ const rootDir = path37.resolve(targetPath);
8821
8892
  if (!await pathExists(rootDir)) {
8822
8893
  console.error(chalk7.red(`Path does not exist: ${rootDir}`));
8823
8894
  process.exit(1);
@@ -8978,7 +9049,7 @@ function emit(report, format) {
8978
9049
  }
8979
9050
  }
8980
9051
  function relProjectDir(rootDir, projectPath) {
8981
- const rel = path36.isAbsolute(projectPath) ? path36.relative(rootDir, projectPath) : projectPath;
9052
+ const rel = path37.isAbsolute(projectPath) ? path37.relative(rootDir, projectPath) : projectPath;
8982
9053
  return rel === "" ? "." : rel;
8983
9054
  }
8984
9055
  async function buildTargetResolver(rootDir, artifact) {
@@ -9019,14 +9090,14 @@ function promptPlanSelection(response) {
9019
9090
  const defaultIdx = plans.findIndex((p) => p.tier === response.recommended);
9020
9091
  const def = defaultIdx >= 0 ? defaultIdx + 1 : 1;
9021
9092
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
9022
- return new Promise((resolve19) => {
9093
+ return new Promise((resolve20) => {
9023
9094
  rl.question(`Plan [1-${plans.length}, default ${def}, q to cancel]: `, (ans) => {
9024
9095
  rl.close();
9025
9096
  const t = ans.trim().toLowerCase();
9026
- if (t === "q" || t === "quit") return resolve19(null);
9097
+ if (t === "q" || t === "quit") return resolve20(null);
9027
9098
  const n = t === "" ? def : Number.parseInt(t, 10);
9028
- if (!Number.isInteger(n) || n < 1 || n > plans.length) return resolve19(null);
9029
- resolve19(plans[n - 1].tier);
9099
+ if (!Number.isInteger(n) || n < 1 || n > plans.length) return resolve20(null);
9100
+ resolve20(plans[n - 1].tier);
9030
9101
  });
9031
9102
  });
9032
9103
  }
@@ -9813,7 +9884,7 @@ function formatMarkdown(artifact) {
9813
9884
 
9814
9885
  // src/reporting/commands/report.ts
9815
9886
  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) => {
9816
- const artifactPath = path36.resolve(opts.in);
9887
+ const artifactPath = path37.resolve(opts.in);
9817
9888
  if (!await pathExists(artifactPath)) {
9818
9889
  console.error(chalk7.red(`Artifact not found: ${artifactPath}`));
9819
9890
  console.error(chalk7.dim('Run "vibgrate scan" first to generate a scan artifact.'));
@@ -9859,10 +9930,10 @@ function openUrl(url) {
9859
9930
  }
9860
9931
 
9861
9932
  // src/reporting/commands/login.ts
9862
- var delay = (ms) => new Promise((resolve19) => setTimeout(resolve19, ms));
9933
+ var delay = (ms) => new Promise((resolve20) => setTimeout(resolve20, ms));
9863
9934
  function isInside(dir, file) {
9864
- const rel = path36.relative(dir, file);
9865
- return !!rel && !rel.startsWith("..") && !path36.isAbsolute(rel);
9935
+ const rel = path37.relative(dir, file);
9936
+ return !!rel && !rel.startsWith("..") && !path37.isAbsolute(rel);
9866
9937
  }
9867
9938
  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(
9868
9939
  "--local",
@@ -10117,7 +10188,7 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
10117
10188
  try {
10118
10189
  const statements = [];
10119
10190
  if (opts.from) {
10120
- const fromPath = path36.resolve(opts.from);
10191
+ const fromPath = path37.resolve(opts.from);
10121
10192
  if (!await pathExists(fromPath)) {
10122
10193
  process.stderr.write(chalk7.red(`Statements file not found: ${fromPath}
10123
10194
  `));
@@ -10135,9 +10206,9 @@ var vexCommand = new Command("vex").description("Generate an OpenVEX document (e
10135
10206
  });
10136
10207
  const json2 = JSON.stringify(doc, null, 2);
10137
10208
  if (opts.out) {
10138
- await writeTextFile(path36.resolve(opts.out), json2 + "\n");
10209
+ await writeTextFile(path37.resolve(opts.out), json2 + "\n");
10139
10210
  process.stderr.write(
10140
- chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${path36.resolve(opts.out)}
10211
+ chalk7.green("\u2714") + ` Wrote OpenVEX document (${doc.statements.length} statement(s)) to ${path37.resolve(opts.out)}
10141
10212
  `
10142
10213
  );
10143
10214
  } else {
@@ -10320,7 +10391,7 @@ function formatDeltaText(base, current) {
10320
10391
  return lines.join("\n");
10321
10392
  }
10322
10393
  async function readArtifactOrExit(filePath) {
10323
- const absolutePath = path36.resolve(filePath);
10394
+ const absolutePath = path37.resolve(filePath);
10324
10395
  if (!await pathExists(absolutePath)) {
10325
10396
  console.error(chalk7.red(`Artifact not found: ${absolutePath}`));
10326
10397
  process.exit(1);
@@ -10337,7 +10408,7 @@ var exportCommand = new Command("export").description("Export scan artifact as S
10337
10408
  const sbom = format === "cyclonedx" ? toCycloneDx(artifact) : toSpdx(artifact);
10338
10409
  const body = JSON.stringify(sbom, null, 2);
10339
10410
  if (opts.out) {
10340
- await writeTextFile(path36.resolve(opts.out), body);
10411
+ await writeTextFile(path37.resolve(opts.out), body);
10341
10412
  console.log(chalk7.green("\u2714") + ` SBOM written to ${opts.out}`);
10342
10413
  } else {
10343
10414
  console.log(body);
@@ -10348,7 +10419,7 @@ var deltaCommand = new Command("delta").description("Show SBOM delta between two
10348
10419
  const current = await readArtifactOrExit(opts.to);
10349
10420
  const report = formatDeltaText(base, current);
10350
10421
  if (opts.out) {
10351
- await writeTextFile(path36.resolve(opts.out), report);
10422
+ await writeTextFile(path37.resolve(opts.out), report);
10352
10423
  console.log(chalk7.green("\u2714") + ` SBOM delta report written to ${opts.out}`);
10353
10424
  } else {
10354
10425
  console.log(report);
@@ -10479,20 +10550,20 @@ function resolveRegime(id) {
10479
10550
  return regime;
10480
10551
  }
10481
10552
  function evidenceDir(root2) {
10482
- return path36.join(root2, ".vibgrate", "evidence");
10553
+ return path37.join(root2, ".vibgrate", "evidence");
10483
10554
  }
10484
10555
  function orgPath(root2) {
10485
- return path36.join(evidenceDir(root2), "org.json");
10556
+ return path37.join(evidenceDir(root2), "org.json");
10486
10557
  }
10487
10558
  function productsPath(root2) {
10488
- return path36.join(evidenceDir(root2), "products.json");
10559
+ return path37.join(evidenceDir(root2), "products.json");
10489
10560
  }
10490
10561
  function releasesDir(root2) {
10491
- return path36.join(evidenceDir(root2), "releases");
10562
+ return path37.join(evidenceDir(root2), "releases");
10492
10563
  }
10493
10564
  function releasePath(root2, productId, version) {
10494
10565
  const safe = `${productId}@${version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
10495
- return path36.join(releasesDir(root2), `${safe}.json`);
10566
+ return path37.join(releasesDir(root2), `${safe}.json`);
10496
10567
  }
10497
10568
  var DEFAULT_ORG = {
10498
10569
  responsiblePersons: [],
@@ -10523,7 +10594,7 @@ async function freezeRelease(root2, release) {
10523
10594
  const p = releasePath(root2, release.productId, release.version);
10524
10595
  if (await pathExists(p)) {
10525
10596
  throw new CliError(
10526
- `release ${release.productId}@${release.version} is already frozen and manifests are immutable \u2014 delete ${path36.relative(root2, p)} only if it was frozen in error`,
10597
+ `release ${release.productId}@${release.version} is already frozen and manifests are immutable \u2014 delete ${path37.relative(root2, p)} only if it was frozen in error`,
10527
10598
  ExitCode.USAGE_ERROR
10528
10599
  );
10529
10600
  }
@@ -10537,7 +10608,7 @@ async function loadReleases(root2, productId) {
10537
10608
  const files = (await readdir(dir)).filter((f) => f.endsWith(".json")).sort();
10538
10609
  const releases = [];
10539
10610
  for (const f of files) {
10540
- const rel = await readJsonFile(path36.join(dir, f));
10611
+ const rel = await readJsonFile(path37.join(dir, f));
10541
10612
  if (!productId || rel.productId === productId) releases.push(rel);
10542
10613
  }
10543
10614
  return releases;
@@ -11232,12 +11303,12 @@ function verifyEvidenceEnvelope(env, opts = {}) {
11232
11303
  var DEFAULT_KEY = "attest-key.pem";
11233
11304
  function resolveSigningKey(root2, explicit) {
11234
11305
  const chosen = process.env.VG_ATTEST_KEY;
11235
- const keyPath = chosen ? path36.resolve(chosen) : path36.join(root2, ".vibgrate", DEFAULT_KEY);
11306
+ const keyPath = chosen ? path37.resolve(chosen) : path37.join(root2, ".vibgrate", DEFAULT_KEY);
11236
11307
  let minted = false;
11237
11308
  if (!fs8.existsSync(keyPath)) {
11238
11309
  if (chosen) throw new CliError(`signing key not found: ${chosen}`, ExitCode.USAGE_ERROR);
11239
11310
  const kp = generateKeypair();
11240
- fs8.mkdirSync(path36.dirname(keyPath), { recursive: true });
11311
+ fs8.mkdirSync(path37.dirname(keyPath), { recursive: true });
11241
11312
  fs8.writeFileSync(keyPath, kp.privatePem, { mode: 384 });
11242
11313
  fs8.writeFileSync(`${keyPath}.pub`, kp.publicPem);
11243
11314
  minted = true;
@@ -11255,16 +11326,16 @@ function resolveSigningKey(root2, explicit) {
11255
11326
  }
11256
11327
  function writeBundle(input) {
11257
11328
  const dir = input.outDir;
11258
- fs8.mkdirSync(path36.join(dir, "inputs", "releases"), { recursive: true });
11259
- const write = (rel, data) => fs8.writeFileSync(path36.join(dir, rel), `${JSON.stringify(data, null, 2)}
11329
+ fs8.mkdirSync(path37.join(dir, "inputs", "releases"), { recursive: true });
11330
+ const write = (rel, data) => fs8.writeFileSync(path37.join(dir, rel), `${JSON.stringify(data, null, 2)}
11260
11331
  `);
11261
11332
  write("result.json", input.result);
11262
- write(path36.join("inputs", "advisory.json"), input.advisory);
11333
+ write(path37.join("inputs", "advisory.json"), input.advisory);
11263
11334
  for (const rel of input.releases) {
11264
11335
  const safe = `${rel.productId}@${rel.version}`.replace(/[^A-Za-z0-9._@-]/g, "_");
11265
- write(path36.join("inputs", "releases", `${safe}.json`), rel);
11336
+ write(path37.join("inputs", "releases", `${safe}.json`), rel);
11266
11337
  }
11267
- write(path36.join("inputs", "datapack.lock"), { dataPackVersion: input.result.meta.dataPackVersion, kernelVersion: input.result.meta.kernelVersion });
11338
+ write(path37.join("inputs", "datapack.lock"), { dataPackVersion: input.result.meta.dataPackVersion, kernelVersion: input.result.meta.kernelVersion });
11268
11339
  write("provenance.json", {
11269
11340
  method: "deterministic",
11270
11341
  modelDrafted: [],
@@ -11280,13 +11351,13 @@ function writeBundle(input) {
11280
11351
  disclaimer: input.regime.disclaimer
11281
11352
  });
11282
11353
  if (input.envelope) {
11283
- fs8.writeFileSync(path36.join(dir, "evidence.intoto.jsonl"), `${JSON.stringify(input.envelope)}
11354
+ fs8.writeFileSync(path37.join(dir, "evidence.intoto.jsonl"), `${JSON.stringify(input.envelope)}
11284
11355
  `);
11285
11356
  }
11286
11357
  if (input.timestampToken) {
11287
- fs8.writeFileSync(path36.join(dir, "timestamp.tsr"), input.timestampToken);
11358
+ fs8.writeFileSync(path37.join(dir, "timestamp.tsr"), input.timestampToken);
11288
11359
  }
11289
- fs8.writeFileSync(path36.join(dir, "VERIFY.md"), verifyDoc(input));
11360
+ fs8.writeFileSync(path37.join(dir, "VERIFY.md"), verifyDoc(input));
11290
11361
  return dir;
11291
11362
  }
11292
11363
  function verifyDoc(input) {
@@ -11347,26 +11418,26 @@ function undeterminedFields(result, regime) {
11347
11418
  return gaps.filter((g) => regime.submission.requires.some((r) => g.startsWith(r)) || g.startsWith("exposure") || g.startsWith("member"));
11348
11419
  }
11349
11420
  async function recordDrill(root2, record) {
11350
- const dir = path36.join(evidenceDir(root2), "drills");
11351
- const p = path36.join(dir, `${record.drillId}.json`);
11421
+ const dir = path37.join(evidenceDir(root2), "drills");
11422
+ const p = path37.join(dir, `${record.drillId}.json`);
11352
11423
  await writeJsonFile(p, record);
11353
11424
  return p;
11354
11425
  }
11355
11426
  async function hasRecentDrill(root2, asOf) {
11356
- const dir = path36.join(evidenceDir(root2), "drills");
11427
+ const dir = path37.join(evidenceDir(root2), "drills");
11357
11428
  if (!await pathExists(dir)) return void 0;
11358
11429
  const { readdir } = await import('fs/promises');
11359
- const { readJsonFile: readJsonFile2 } = await import('./fs-KCABDURV.js');
11430
+ const { readJsonFile: readJsonFile2 } = await import('./fs-O5IQYXHO.js');
11360
11431
  const files = (await readdir(dir)).filter((f) => f.endsWith(".json"));
11361
11432
  if (files.length === 0) return void 0;
11362
11433
  const cutoff = new Date(new Date(asOf).getTime() - 90 * 24 * 3600 * 1e3).toISOString();
11363
11434
  for (const f of files) {
11364
- const rec = await readJsonFile2(path36.join(dir, f));
11435
+ const rec = await readJsonFile2(path37.join(dir, f));
11365
11436
  if (rec.ranAt >= cutoff) return true;
11366
11437
  }
11367
11438
  return false;
11368
11439
  }
11369
- function pad4(s, n) {
11440
+ function pad3(s, n) {
11370
11441
  return s.length >= n ? s : s + " ".repeat(n - s.length);
11371
11442
  }
11372
11443
  function formatExposure(result, regime) {
@@ -11383,13 +11454,13 @@ function formatExposure(result, regime) {
11383
11454
  }
11384
11455
  lines.push("");
11385
11456
  if (affected.length) {
11386
- lines.push(" " + chalk7.dim(pad4("Product", 22) + pad4("Shipped versions", 24) + pad4("Markets", 16) + "Support"));
11457
+ lines.push(" " + chalk7.dim(pad3("Product", 22) + pad3("Shipped versions", 24) + pad3("Markets", 16) + "Support"));
11387
11458
  lines.push(" " + chalk7.dim("\u2500".repeat(74)));
11388
11459
  for (const p of affected) {
11389
11460
  const versions = p.affectedVersions.join(", ") || "\u2014";
11390
11461
  const markets = p.memberStates.join(" ") || "\u2014";
11391
11462
  const support = p.supportStatus === "in_support" ? chalk7.green("in support") : p.supportStatus === "expired" ? chalk7.yellow(p.supportDetail ?? "expired") : chalk7.dim("not declared");
11392
- lines.push(" " + pad4(p.productName, 22) + pad4(versions, 24) + pad4(markets, 16) + support);
11463
+ lines.push(" " + pad3(p.productName, 22) + pad3(versions, 24) + pad3(markets, 16) + support);
11393
11464
  }
11394
11465
  lines.push("");
11395
11466
  }
@@ -11420,7 +11491,7 @@ function formatReadiness(report, regime) {
11420
11491
  lines.push(" " + chalk7.bold(`Readiness \u2014 ${regime.name}`) + ` ${chalk7.bold(String(report.score))}% (${report.ready}/${report.assessable} ready)`);
11421
11492
  lines.push("");
11422
11493
  for (const item of report.items) {
11423
- lines.push(" " + mark(item) + " " + pad4(item.label, 52) + " " + chalk7.dim(item.detail));
11494
+ lines.push(" " + mark(item) + " " + pad3(item.label, 52) + " " + chalk7.dim(item.detail));
11424
11495
  if (item.status === "gap" && item.fix) lines.push(" " + chalk7.dim("fix: ") + chalk7.cyan(item.fix));
11425
11496
  }
11426
11497
  lines.push("");
@@ -11431,7 +11502,7 @@ function formatRegimeList() {
11431
11502
  const lines = [" " + chalk7.bold("Available regimes")];
11432
11503
  lines.push("");
11433
11504
  for (const r of listRegimes()) {
11434
- lines.push(" " + chalk7.cyan(pad4(r.id, 16)) + r.name + chalk7.dim(` (${r.jurisdiction})`));
11505
+ lines.push(" " + chalk7.cyan(pad3(r.id, 16)) + r.name + chalk7.dim(` (${r.jurisdiction})`));
11435
11506
  const clocks = r.clocks.map((c2) => `${c2.stage} ${c2.within}`).join(" \xB7 ");
11436
11507
  lines.push(" " + chalk7.dim(clocks));
11437
11508
  lines.push(" " + chalk7.dim(`submission: ${r.submission.target}${r.submission.api ? "" : " \u2014 manual (no API)"}`));
@@ -11441,7 +11512,7 @@ function formatRegimeList() {
11441
11512
 
11442
11513
  // src/reporting/commands/evidence/index.ts
11443
11514
  function root(opts) {
11444
- return path36.resolve(opts.cwd ?? process.cwd());
11515
+ return path37.resolve(opts.cwd ?? process.cwd());
11445
11516
  }
11446
11517
  function slug(name) {
11447
11518
  return name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "product";
@@ -11529,7 +11600,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
11529
11600
  const release = await buildRelease({
11530
11601
  productId: product.id,
11531
11602
  version,
11532
- from: path36.resolve(rootDir, opts.from),
11603
+ from: path37.resolve(rootDir, opts.from),
11533
11604
  shipDate: opts.shipDate,
11534
11605
  buildId: opts.buildId,
11535
11606
  artefactDigest: opts.digest,
@@ -11537,7 +11608,7 @@ var releaseCmd = new Command("release").description("Freeze a shipped release in
11537
11608
  frozenAt: nowIso()
11538
11609
  });
11539
11610
  const p = await freezeRelease(rootDir, release);
11540
- console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${path36.relative(rootDir, p)}`);
11611
+ console.log(chalk7.green("\u2714") + ` froze ${chalk7.bold(`${product.id}@${version}`)} \u2014 ${release.components.length} components, immutable at ${path37.relative(rootDir, p)}`);
11541
11612
  });
11542
11613
  async function runExposure(rootDir, vuln, opts) {
11543
11614
  const org = await loadOrg(rootDir);
@@ -11589,7 +11660,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
11589
11660
  console.log("\n" + buildPack(result, regime, org, stage));
11590
11661
  }
11591
11662
  if (opts.bundle) {
11592
- const dir = path36.resolve(rootDir, opts.bundle, `evidence-${result.meta.evidenceId}`);
11663
+ const dir = path37.resolve(rootDir, opts.bundle, `evidence-${result.meta.evidenceId}`);
11593
11664
  let envelope;
11594
11665
  if (opts.sign !== false) {
11595
11666
  const { key: key2, minted } = resolveSigningKey(rootDir);
@@ -11597,7 +11668,7 @@ var exposureCmd = new Command("exposure").description("Which shipped products co
11597
11668
  envelope = signEvidenceStatement(buildEvidenceStatement(result, VERSION), key2);
11598
11669
  }
11599
11670
  writeBundle({ outDir: dir, result, advisory, releases, regime, envelope, timestampToken, cliVersion: VERSION });
11600
- console.error(chalk7.green("\u2714") + ` evidence bundle written to ${path36.relative(rootDir, dir)}${envelope ? " (signed)" : " (unsigned)"}${timestampToken ? " \xB7 RFC 3161" : ""}`);
11671
+ console.error(chalk7.green("\u2714") + ` evidence bundle written to ${path37.relative(rootDir, dir)}${envelope ? " (signed)" : " (unsigned)"}${timestampToken ? " \xB7 RFC 3161" : ""}`);
11601
11672
  }
11602
11673
  process.exitCode = exposureExit(result.overallStatus);
11603
11674
  });
@@ -11629,7 +11700,7 @@ var packCmd = new Command("pack").description("Build the submission pack a human
11629
11700
  const stage = opts.stage ?? regime.clocks[0]?.stage ?? "early-warning";
11630
11701
  const md = buildPack(result, regime, org, stage);
11631
11702
  if (opts.out) {
11632
- fs8.writeFileSync(path36.resolve(rootDir, opts.out), md);
11703
+ fs8.writeFileSync(path37.resolve(rootDir, opts.out), md);
11633
11704
  console.error(chalk7.green("\u2714") + ` pack written to ${opts.out}`);
11634
11705
  } else {
11635
11706
  console.log(md);
@@ -11671,18 +11742,18 @@ var drillCmd = new Command("drill").description("Timed dry-run of the determinat
11671
11742
  }
11672
11743
  });
11673
11744
  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) => {
11674
- const abs = path36.resolve(bundlePath);
11675
- const envPath = fs8.statSync(abs).isDirectory() ? path36.join(abs, "evidence.intoto.jsonl") : abs;
11745
+ const abs = path37.resolve(bundlePath);
11746
+ const envPath = fs8.statSync(abs).isDirectory() ? path37.join(abs, "evidence.intoto.jsonl") : abs;
11676
11747
  if (!fs8.existsSync(envPath)) throw new CliError(`no evidence.intoto.jsonl at ${bundlePath}`, ExitCode.NOT_FOUND);
11677
11748
  const envelope = JSON.parse(fs8.readFileSync(envPath, "utf8").trim().split("\n")[0]);
11678
- const resultPath = path36.join(path36.dirname(envPath), "result.json");
11749
+ const resultPath = path37.join(path37.dirname(envPath), "result.json");
11679
11750
  const result = fs8.existsSync(resultPath) ? JSON.parse(fs8.readFileSync(resultPath, "utf8")) : void 0;
11680
- const publicKeyPem = opts.pub ? fs8.readFileSync(path36.resolve(opts.pub), "utf8") : void 0;
11751
+ const publicKeyPem = opts.pub ? fs8.readFileSync(path37.resolve(opts.pub), "utf8") : void 0;
11681
11752
  const v = verifyEvidenceEnvelope(envelope, { publicKeyPem, result });
11682
11753
  const color = v.status === "verified" ? chalk7.green : v.status === "failed" ? chalk7.red : chalk7.yellow;
11683
11754
  console.log(" " + color(v.status.toUpperCase()) + ` ${v.reason}`);
11684
11755
  if (v.evidenceId) console.log(" " + chalk7.dim(`evidence ${v.evidenceId} \xB7 regime ${v.regime} \xB7 advisory ${v.advisoryId} \xB7 ${v.overallStatus}`));
11685
- const tsrPath = path36.join(path36.dirname(envPath), "timestamp.tsr");
11756
+ const tsrPath = path37.join(path37.dirname(envPath), "timestamp.tsr");
11686
11757
  if (fs8.existsSync(tsrPath) && result) {
11687
11758
  const t = verifyTimestamp(fs8.readFileSync(tsrPath), exposureSubjectDigest(result));
11688
11759
  const tcolor = t.imprintMatches ? chalk7.green : chalk7.red;
@@ -11751,12 +11822,12 @@ var exportCmd = new Command("export").description("Air-gap bundle of all evidenc
11751
11822
  const releases = [];
11752
11823
  for (const list of releasesByProduct.values()) releases.push(...list);
11753
11824
  const report = computeReadiness({ regime, org, products, releasesByProduct, recentDrill: await hasRecentDrill(rootDir, today()) });
11754
- const dir = path36.resolve(rootDir, opts.out);
11755
- await writeJsonFile(path36.join(dir, "org.json"), org);
11756
- await writeJsonFile(path36.join(dir, "products.json"), products);
11757
- for (const r of releases) await writeJsonFile(path36.join(dir, "releases", `${r.productId}@${r.version}.json`.replace(/[^A-Za-z0-9._@-]/g, "_")), r);
11758
- await writeJsonFile(path36.join(dir, "readiness.json"), report);
11759
- console.error(chalk7.green("\u2714") + ` exported evidence state to ${path36.relative(rootDir, dir)} (${products.length} products, ${releases.length} frozen releases)`);
11825
+ const dir = path37.resolve(rootDir, opts.out);
11826
+ await writeJsonFile(path37.join(dir, "org.json"), org);
11827
+ await writeJsonFile(path37.join(dir, "products.json"), products);
11828
+ for (const r of releases) await writeJsonFile(path37.join(dir, "releases", `${r.productId}@${r.version}.json`.replace(/[^A-Za-z0-9._@-]/g, "_")), r);
11829
+ await writeJsonFile(path37.join(dir, "readiness.json"), report);
11830
+ console.error(chalk7.green("\u2714") + ` exported evidence state to ${path37.relative(rootDir, dir)} (${products.length} products, ${releases.length} frozen releases)`);
11760
11831
  });
11761
11832
  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) => {
11762
11833
  const rootDir = root(opts);
@@ -11782,8 +11853,8 @@ var pushCmd = new Command("push").description("Push the product registry (and an
11782
11853
  }));
11783
11854
  let exposure;
11784
11855
  if (opts.result) {
11785
- const raw = path36.resolve(rootDir, opts.result);
11786
- const resultPath = fs8.existsSync(raw) && fs8.statSync(raw).isDirectory() ? path36.join(raw, "result.json") : raw;
11856
+ const raw = path37.resolve(rootDir, opts.result);
11857
+ const resultPath = fs8.existsSync(raw) && fs8.statSync(raw).isDirectory() ? path37.join(raw, "result.json") : raw;
11787
11858
  if (!fs8.existsSync(resultPath)) throw new CliError(`no result.json at ${opts.result}`, ExitCode.NOT_FOUND);
11788
11859
  exposure = JSON.parse(fs8.readFileSync(resultPath, "utf8"));
11789
11860
  }
@@ -11849,7 +11920,7 @@ var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
11849
11920
  "install",
11850
11921
  "uninstall",
11851
11922
  "share",
11852
- "benchmark",
11923
+ "watch",
11853
11924
  "help",
11854
11925
  // Drift-reporting verbs (merged from the Vibgrate CLI).
11855
11926
  "init",
@@ -11890,7 +11961,7 @@ ${aliasNote}Docs: https://vibgrate.com/help`;
11890
11961
  registerLsp(program);
11891
11962
  registerInstall(program);
11892
11963
  registerShare(program);
11893
- registerBenchmark(program);
11964
+ registerWatch(program);
11894
11965
  registerTests(program);
11895
11966
  registerFacts(program);
11896
11967
  registerGuide(program);
@@ -11975,7 +12046,7 @@ function dispatch(argv, cwd) {
11975
12046
  }
11976
12047
  const looksLikeQuestion = /\s/.test(first) || first.endsWith("?");
11977
12048
  if (looksLikeQuestion) return ["ask", ...args];
11978
- if (fs8.existsSync(path36.resolve(cwd, first))) {
12049
+ if (fs8.existsSync(path37.resolve(cwd, first))) {
11979
12050
  return [hasBuildOnlyFlag(args) ? "build" : "scan", ...args];
11980
12051
  }
11981
12052
  const moved = MOVED_COMMANDS[first];
@@ -12020,9 +12091,9 @@ async function main(argv = process.argv) {
12020
12091
  }
12021
12092
  function readCwd(raw) {
12022
12093
  const i = raw.findIndex((a) => a === "-C" || a === "--cwd");
12023
- if (i >= 0 && raw[i + 1]) return path36.resolve(raw[i + 1]);
12094
+ if (i >= 0 && raw[i + 1]) return path37.resolve(raw[i + 1]);
12024
12095
  const eq = raw.find((a) => a.startsWith("--cwd="));
12025
- if (eq) return path36.resolve(eq.slice("--cwd=".length));
12096
+ if (eq) return path37.resolve(eq.slice("--cwd=".length));
12026
12097
  return process.cwd();
12027
12098
  }
12028
12099
  function handleError(err) {