@vibgrate/cli 2026.806.2 → 2026.813.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/{agent-DSC3EQLT.js → agent-N3CP3SPI.js} +11 -11
  2. package/dist/{agent-DSC3EQLT.js.map → agent-N3CP3SPI.js.map} +1 -1
  3. package/dist/baseline-ZMRZRGFI.js +9 -0
  4. package/dist/{baseline-KVCXVZFQ.js.map → baseline-ZMRZRGFI.js.map} +1 -1
  5. package/dist/{chunk-QDKFGLI3.js → chunk-3WUTQYRY.js} +7 -7
  6. package/dist/{chunk-QDKFGLI3.js.map → chunk-3WUTQYRY.js.map} +1 -1
  7. package/dist/{chunk-D2VEJHPC.js → chunk-5JJBGBP2.js} +8 -8
  8. package/dist/{chunk-D2VEJHPC.js.map → chunk-5JJBGBP2.js.map} +1 -1
  9. package/dist/{chunk-Y4JO6LYP.js → chunk-5ROZODMW.js} +302 -11
  10. package/dist/chunk-5ROZODMW.js.map +1 -0
  11. package/dist/{chunk-ZPPDKHGL.js → chunk-6423BHLN.js} +7 -7
  12. package/dist/{chunk-ZPPDKHGL.js.map → chunk-6423BHLN.js.map} +1 -1
  13. package/dist/{chunk-455ZJQQ4.js → chunk-6GQLEDVK.js} +5 -5
  14. package/dist/{chunk-455ZJQQ4.js.map → chunk-6GQLEDVK.js.map} +1 -1
  15. package/dist/{chunk-SBVZGEOB.js → chunk-7ZHSSGUF.js} +3 -3
  16. package/dist/{chunk-SBVZGEOB.js.map → chunk-7ZHSSGUF.js.map} +1 -1
  17. package/dist/{chunk-SI4D7DYF.js → chunk-ADP6ITGF.js} +44 -8
  18. package/dist/chunk-ADP6ITGF.js.map +1 -0
  19. package/dist/{chunk-7C5UKIXD.js → chunk-CJNWHXQD.js} +12 -10
  20. package/dist/chunk-CJNWHXQD.js.map +1 -0
  21. package/dist/{chunk-ZMSTSEGR.js → chunk-EWZKOU66.js} +3 -3
  22. package/dist/{chunk-ZMSTSEGR.js.map → chunk-EWZKOU66.js.map} +1 -1
  23. package/dist/{chunk-TOVVTZTM.js → chunk-FBVKQXBH.js} +3 -3
  24. package/dist/{chunk-TOVVTZTM.js.map → chunk-FBVKQXBH.js.map} +1 -1
  25. package/dist/{chunk-HV4CKBXT.js → chunk-GOPANQZT.js} +3 -3
  26. package/dist/{chunk-HV4CKBXT.js.map → chunk-GOPANQZT.js.map} +1 -1
  27. package/dist/{chunk-6L6V77HW.js → chunk-IJQOZ6ZD.js} +8 -8
  28. package/dist/{chunk-6L6V77HW.js.map → chunk-IJQOZ6ZD.js.map} +1 -1
  29. package/dist/{chunk-VTJAPNJO.js → chunk-JYM4QT6F.js} +4 -4
  30. package/dist/{chunk-VTJAPNJO.js.map → chunk-JYM4QT6F.js.map} +1 -1
  31. package/dist/{chunk-KYRH3567.js → chunk-KBP7GJV6.js} +3 -3
  32. package/dist/{chunk-KYRH3567.js.map → chunk-KBP7GJV6.js.map} +1 -1
  33. package/dist/{chunk-6XKDAYYR.js → chunk-KF2QT6RY.js} +4 -4
  34. package/dist/{chunk-6XKDAYYR.js.map → chunk-KF2QT6RY.js.map} +1 -1
  35. package/dist/{chunk-INIULQEP.js → chunk-N6ZMZ5AI.js} +11 -2
  36. package/dist/chunk-N6ZMZ5AI.js.map +1 -0
  37. package/dist/{chunk-IQJUFRZZ.js → chunk-OYHAF2J2.js} +5 -5
  38. package/dist/{chunk-IQJUFRZZ.js.map → chunk-OYHAF2J2.js.map} +1 -1
  39. package/dist/{chunk-I2JNLAKW.js → chunk-RHKJPTON.js} +47 -15
  40. package/dist/chunk-RHKJPTON.js.map +1 -0
  41. package/dist/chunk-RT7P5AYU.js +6 -0
  42. package/dist/{chunk-K6MLOGU4.js.map → chunk-RT7P5AYU.js.map} +1 -1
  43. package/dist/{chunk-CBPDYYIH.js → chunk-UZP623Y4.js} +4 -4
  44. package/dist/{chunk-CBPDYYIH.js.map → chunk-UZP623Y4.js.map} +1 -1
  45. package/dist/{chunk-EW2ZMFUC.js → chunk-YJU7S7N6.js} +24 -6
  46. package/dist/chunk-YJU7S7N6.js.map +1 -0
  47. package/dist/{chunk-KAOSPAFK.js → chunk-Z3AYOZ3C.js} +7 -6
  48. package/dist/chunk-Z3AYOZ3C.js.map +1 -0
  49. package/dist/{chunk-RL6MHAOK.js → chunk-Z3MUWXP3.js} +4 -4
  50. package/dist/{chunk-RL6MHAOK.js.map → chunk-Z3MUWXP3.js.map} +1 -1
  51. package/dist/{chunk-KUZLILN3.js → chunk-Z7FM3ETS.js} +18 -4
  52. package/dist/chunk-Z7FM3ETS.js.map +1 -0
  53. package/dist/cli.js +96 -69
  54. package/dist/cli.js.map +1 -1
  55. package/dist/embed-worker-main.js +3 -3
  56. package/dist/{ensure-map-5E5TFPXJ.js → ensure-map-PHAJACFF.js} +13 -13
  57. package/dist/{ensure-map-5E5TFPXJ.js.map → ensure-map-PHAJACFF.js.map} +1 -1
  58. package/dist/graph-backend-4B3MTVIW.js +13 -0
  59. package/dist/{graph-backend-GQZXMNRI.js.map → graph-backend-4B3MTVIW.js.map} +1 -1
  60. package/dist/index.d.ts +1 -1
  61. package/dist/index.js +12 -12
  62. package/dist/{interactive-7EZHEBHQ.js → interactive-WUXMXFNM.js} +24 -24
  63. package/dist/{interactive-7EZHEBHQ.js.map → interactive-WUXMXFNM.js.map} +1 -1
  64. package/dist/load-EUZSV73H.js +9 -0
  65. package/dist/{load-QBVKCWZT.js.map → load-EUZSV73H.js.map} +1 -1
  66. package/dist/{run-outcome-NQAU6DOA.js → run-outcome-O5PR7ZCK.js} +5 -5
  67. package/dist/{run-outcome-NQAU6DOA.js.map → run-outcome-O5PR7ZCK.js.map} +1 -1
  68. package/dist/runtime-session-PPQDTFIK.js +20 -0
  69. package/dist/{runtime-session-ZPGU4PGW.js.map → runtime-session-PPQDTFIK.js.map} +1 -1
  70. package/dist/session-WS7SOVJE.js +15 -0
  71. package/dist/{session-QNSYTLLJ.js.map → session-WS7SOVJE.js.map} +1 -1
  72. package/dist/session-store-KGONLWHN.js +4 -0
  73. package/dist/{session-store-F7NX7SZN.js.map → session-store-KGONLWHN.js.map} +1 -1
  74. package/dist/{stream-json-5WFD6HRO.js → stream-json-7MK3QQYG.js} +11 -11
  75. package/dist/{stream-json-5WFD6HRO.js.map → stream-json-7MK3QQYG.js.map} +1 -1
  76. package/dist/{vg-mcp-bridge-VTGXA6CO.js → vg-mcp-bridge-DQLCHBI6.js} +9 -9
  77. package/dist/{vg-mcp-bridge-VTGXA6CO.js.map → vg-mcp-bridge-DQLCHBI6.js.map} +1 -1
  78. package/dist/{vgd-54GEZWBI.js → vgd-Y25XSQGZ.js} +8 -8
  79. package/dist/vgd-Y25XSQGZ.js.map +1 -0
  80. package/package.json +6 -6
  81. package/dist/baseline-KVCXVZFQ.js +0 -9
  82. package/dist/chunk-7C5UKIXD.js.map +0 -1
  83. package/dist/chunk-EW2ZMFUC.js.map +0 -1
  84. package/dist/chunk-I2JNLAKW.js.map +0 -1
  85. package/dist/chunk-INIULQEP.js.map +0 -1
  86. package/dist/chunk-K6MLOGU4.js +0 -6
  87. package/dist/chunk-KAOSPAFK.js.map +0 -1
  88. package/dist/chunk-KUZLILN3.js.map +0 -1
  89. package/dist/chunk-SI4D7DYF.js.map +0 -1
  90. package/dist/chunk-Y4JO6LYP.js.map +0 -1
  91. package/dist/graph-backend-GQZXMNRI.js +0 -13
  92. package/dist/load-QBVKCWZT.js +0 -9
  93. package/dist/runtime-session-ZPGU4PGW.js +0 -20
  94. package/dist/session-QNSYTLLJ.js +0 -15
  95. package/dist/session-store-F7NX7SZN.js +0 -4
  96. package/dist/vgd-54GEZWBI.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { resolveGraphPath, cacheDir } from './chunk-ZMSTSEGR.js';
1
+ import { resolveGraphPath, cacheDir } from './chunk-EWZKOU66.js';
2
2
  import { hashString } from './chunk-JFGYT6BI.js';
3
3
  import * as fs2 from 'fs';
4
4
  import { createRequire } from 'module';
@@ -585,5 +585,5 @@ function safe(id) {
585
585
  }
586
586
 
587
587
  export { acquireLock, clearModelCache, cosine, countPending, embeddingsCached, embeddingsPath, embeddingsPathFor, getNodeEmbeddings, isModelReady, loadEmbedder, modelCacheInfo, nodeEmbedText, releaseLock, resolveEmbedModel, unavailableMessage, withTimeout };
588
- //# sourceMappingURL=chunk-KYRH3567.js.map
589
- //# sourceMappingURL=chunk-KYRH3567.js.map
588
+ //# sourceMappingURL=chunk-KBP7GJV6.js.map
589
+ //# sourceMappingURL=chunk-KBP7GJV6.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/engine/lock.ts","../src/engine/embeddings.ts"],"names":["fs","path"],"mappings":"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","file":"chunk-KYRH3567.js","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * Cross-process single-writer lock (O_EXCL create), shared by the embedding\n * cache writer and the auto-refresh rebuild so two vg processes never write\n * the same repo-local artifact at once. A lock whose owning process is dead,\n * or that is older than `staleMs`, is presumed abandoned and reclaimed.\n */\n\n/** A lock older than this is presumed dead (crashed process). */\nexport const DEFAULT_LOCK_STALE_MS = 15 * 60 * 1000;\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (e) {\n return (e as NodeJS.ErrnoException).code === 'EPERM'; // exists, just not ours to signal\n }\n}\n\nfunction lockIsStale(file: string, staleMs: number): boolean {\n try {\n const { pid, at } = JSON.parse(fs.readFileSync(file, 'utf8')) as { pid?: number; at?: number };\n if (typeof at === 'number' && Date.now() - at > staleMs) return true;\n if (typeof pid === 'number' && !isProcessAlive(pid)) return true;\n return false;\n } catch {\n return true; // unreadable/corrupt → reclaim it\n }\n}\n\n/** Take the lock (O_EXCL), reclaiming a stale/dead one. Returns success. */\nexport function acquireLock(file: string, staleMs = DEFAULT_LOCK_STALE_MS): boolean {\n const write = (): boolean => {\n try {\n fs.mkdirSync(path.dirname(file), { recursive: true });\n const fd = fs.openSync(file, 'wx');\n fs.writeFileSync(fd, JSON.stringify({ pid: process.pid, at: Date.now() }));\n fs.closeSync(fd);\n return true;\n } catch {\n return false;\n }\n };\n if (write()) return true;\n if (lockIsStale(file, staleMs)) {\n try {\n fs.rmSync(file, { force: true });\n } catch {\n /* another process may have reclaimed it */\n }\n return write();\n }\n return false;\n}\n\nexport function releaseLock(file: string): void {\n try {\n fs.rmSync(file, { force: true });\n } catch {\n /* best-effort */\n }\n}\n","import * as fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { hashString } from './hash.js';\nimport { cacheDir } from './cache.js';\nimport { resolveGraphPath } from './artifacts.js';\nimport { acquireLock, releaseLock } from './lock.js';\nimport type { GraphNode, VgGraph } from '../schema.js';\n\n/**\n * Local-embedding semantic search for `vg ask --semantic`/`--deep` (no API key).\n *\n * The embedding backend is an OPTIONAL, lazily-loaded dependency (`fastembed`,\n * Apache-2.0, local ONNX) so the core install stays lean and `ask` never breaks:\n * if the backend or model isn't available it degrades to (prefix-fuzzy) lexical\n * search with a clear note. Per-repo vectors live in a binary `*.embeddings`\n * file **alongside the code map** (global store under Application Support /\n * XDG data, or `.vibgrate/embeddings` in-repo) — never model-named, never under\n * `.vibgrate/cache/`, and NEVER inside the committed `graph.json`, so the map\n * stays byte-deterministic. The model id is recorded inside the file header so\n * a model change still invalidates the cache without putting the name in the\n * path.\n *\n * `--local` disables the model download (semantic is skipped unless already\n * cached via an injected backend), keeping the air-gapped guarantee.\n */\n\nexport interface Embedder {\n /** Stable model id (recorded with cached vectors so a model change invalidates them). */\n id: string;\n /** Embed documents → unit-or-raw vectors (cosine handles normalization). */\n embed(texts: string[]): Promise<number[][]>;\n /** Embed a single query string. */\n embedQuery(text: string): Promise<number[]>;\n}\n\n/** Why semantic fell back to lexical — for calm, specific messaging. */\nexport type EmbedUnavailable = 'not-installed' | 'no-permission' | 'download-failed' | 'init-failed';\n\nexport interface LoadEmbedderOptions {\n local?: boolean; // --local: do not download a model\n model?: string; // override the embedding model id\n noDownload?: boolean; // only load if the model is already cached (never fetch)\n showDownloadProgress?: boolean; // let fastembed print its one-time download progress\n /**\n * Called (not thrown) when the backend can't load. `detail` carries the\n * underlying loader error when there is one, so a host can log something\n * actionable instead of a bare category.\n */\n onUnavailable?: (reason: EmbedUnavailable, detail?: string) => void;\n}\n\n/** The embedding model id in effect (explicit override → default). */\nexport function resolveEmbedModel(model?: string): string {\n return model ?? 'bge-small-en-v1.5';\n}\n\n/**\n * The **central, per-user** model cache — downloaded once per machine and shared\n * across every repo/folder (devs have many repos; the ~tens-of-MB model should\n * not re-download per project). Uses the XDG standard:\n * `$XDG_CACHE_HOME/vibgrate/models` (or `~/.cache/vibgrate/models`); relocate via\n * the standard `XDG_CACHE_HOME`. NB: fastembed's own default is the relative\n * `./local_cache`, i.e. per-CWD — which we override.\n */\nexport function modelCacheDir(): string {\n const base = process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache');\n return path.join(base, 'vibgrate', 'models');\n}\n\n/** A machine-global marker written once the model has loaded successfully. */\nfunction modelReadyMarker(modelId: string): string {\n return path.join(modelCacheDir(), `.ready-${safe(modelId)}`);\n}\n\n/**\n * Whether the embedding model is already present on this machine (loaded at least\n * once), so it can be used with **no network**. Lets the background warm-up\n * trigger only when it won't surprise-download.\n */\nexport function isModelReady(modelId = resolveEmbedModel()): boolean {\n return fs.existsSync(modelReadyMarker(modelId));\n}\n\n/**\n * A calm, specific, actionable one-liner for why semantic isn't available right\n * now — built to reassure (lexical still works) and inform, never to alarm. No\n * stack traces, no scary words; always names the off switch and the fix.\n */\nexport function unavailableMessage(reason: EmbedUnavailable): string {\n switch (reason) {\n case 'no-permission':\n return `semantic search couldn't write its model cache at ${modelCacheDir()} — using fast lexical search instead. Relocate it with the standard XDG_CACHE_HOME, or run with --local to stay lexical quietly. (No admin/sudo is ever needed — the cache lives in your home folder.)`;\n case 'download-failed':\n return `the semantic model isn't downloaded yet and couldn't be fetched (offline?) — using fast lexical search. It'll try again next time; run with --local to keep lexical without retrying.`;\n case 'not-installed':\n return `the optional semantic backend isn't available here — using fast lexical search.`;\n case 'init-failed':\n default:\n return `the semantic model couldn't load — using fast lexical search.`;\n }\n}\n\nexport interface ModelCacheInfo {\n dir: string;\n present: boolean;\n bytes: number;\n}\n\n/** Where the shared model lives, whether it's present, and how big it is. */\nexport function modelCacheInfo(modelId = resolveEmbedModel()): ModelCacheInfo {\n const dir = modelCacheDir();\n return { dir, present: isModelReady(modelId) || fs.existsSync(dir), bytes: dirSize(dir) };\n}\n\n/** Remove the shared, re-downloadable model from the central cache. Returns bytes freed. */\nexport function clearModelCache(): number {\n const dir = modelCacheDir();\n const bytes = dirSize(dir);\n try {\n fs.rmSync(dir, { recursive: true, force: true });\n } catch {\n /* best-effort */\n }\n return bytes;\n}\n\nfunction dirSize(dir: string): number {\n let total = 0;\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return 0;\n }\n for (const e of entries) {\n const p = path.join(dir, e.name);\n if (e.isDirectory()) total += dirSize(p);\n else {\n try {\n total += fs.statSync(p).size;\n } catch {\n /* skip unreadable */\n }\n }\n }\n return total;\n}\n\nfunction isPermissionError(e: unknown): boolean {\n const code = (e as NodeJS.ErrnoException | undefined)?.code;\n return code === 'EACCES' || code === 'EPERM' || code === 'EROFS';\n}\n\n/**\n * Whether this repo already has a cached vector set for `modelId` — i.e. semantic\n * search has run here before, so the next run is fast (no first-use download/embed).\n * Lets `ask` show the one-time setup note only when it's actually warranted.\n * Checks the binary sidecar next to the map (and the legacy JSON path once).\n */\nexport function embeddingsCached(root: string, modelId: string): boolean {\n const file = vectorCachePath(root);\n if (fs.existsSync(file) && readCacheHeader(file)?.model === modelId) return true;\n // One-shot legacy: pre-binary caches lived under `.vibgrate/cache/embeddings-<model>.json`.\n return fs.existsSync(legacyVectorCachePath(root, modelId));\n}\n\n/**\n * Path of the binary embeddings file for this repo's current map — always named\n * `embeddings` (or `<snapshot>.embeddings` next to a branch-keyed graph), never\n * after the model. Exported for `vg embed --where` and tests.\n */\nexport function embeddingsPath(root: string): string {\n return vectorCachePath(root);\n}\n\n/** Sidecar path next to a map file: `…/branch-main.graph.json` → `…/branch-main.embeddings`. */\nexport function embeddingsPathFor(graphPath: string): string {\n // Branch-keyed global maps: `…/graphs/branch-main.graph.json` → `…/graphs/branch-main.embeddings`.\n if (graphPath.endsWith('.graph.json')) return `${graphPath.slice(0, -'.graph.json'.length)}.embeddings`;\n if (graphPath.endsWith('.graph.snap')) return `${graphPath.slice(0, -'.graph.snap'.length)}.embeddings`;\n // In-repo map is exactly `…/graph.json` (or `graph.snap`) → plain `…/embeddings`.\n const base = path.basename(graphPath);\n if (base === 'graph.json' || base === 'graph.snap') {\n return path.join(path.dirname(graphPath), 'embeddings');\n }\n if (graphPath.endsWith('.json')) return `${graphPath.slice(0, -5)}.embeddings`;\n if (graphPath.endsWith('.snap')) return `${graphPath.slice(0, -5)}.embeddings`;\n return `${graphPath}.embeddings`;\n}\n\n/**\n * Try to load the optional local embedding backend. Returns null (→ caller falls\n * back to lexical) when running `--local`, when the dependency isn't installed,\n * or when the model can't initialize.\n */\nexport async function loadEmbedder(options: LoadEmbedderOptions = {}): Promise<Embedder | null> {\n // `--local` forces the deterministic lexical floor with no model load/download\n // (air-gapped guarantee; also how tests stay offline).\n if (options.local) return null;\n const modelId = resolveEmbedModel(options.model);\n // noDownload (used by the background warm-up): never fetch — bail if not cached.\n if (options.noDownload && !isModelReady(modelId)) return null;\n const fail = (reason: EmbedUnavailable, detail?: string): null => {\n options.onUnavailable?.(reason, detail);\n return null;\n };\n\n // Lazy, optional dependency (native ONNX): loaded only for `vg ask`/`embed`,\n // never by build/verify, so the graph artifact stays deterministic.\n const backend = await importEmbedBackend();\n const mod: any = backend.mod;\n if (!mod?.FlagEmbedding) return fail('not-installed', backend.error);\n\n const cache = modelCacheDir(); // central, shared across all repos\n try {\n fs.mkdirSync(cache, { recursive: true });\n } catch (e) {\n return fail(isPermissionError(e) ? 'no-permission' : 'init-failed');\n }\n\n try {\n // First use fetches the model. A refused connection fails fast, but a\n // black-holing proxy (common on corporate networks) would hang the first\n // `vg ask` / MCP query_graph forever — bound the wait and fall back to\n // lexical instead. Cached loads are local disk and get the same generous\n // ceiling without ever hitting it.\n const model: any = await withTimeout(\n mod.FlagEmbedding.init({\n model: mapModel(mod, modelId),\n cacheDir: cache,\n showDownloadProgress: options.showDownloadProgress ?? false,\n }) as Promise<unknown>,\n embedInitTimeoutMs(),\n 'embedding model init timed out',\n );\n // Record machine-global readiness so future builds can warm up offline.\n try {\n fs.writeFileSync(modelReadyMarker(modelId), new Date(0).toISOString());\n } catch {\n /* marker is best-effort */\n }\n return {\n id: modelId,\n async embed(texts) {\n const out: number[][] = [];\n for await (const batch of model.embed(texts, 64)) {\n for (const v of batch) out.push(Array.from(v as ArrayLike<number>));\n }\n return out;\n },\n async embedQuery(text) {\n const v = await model.queryEmbed(text);\n return Array.from(v as ArrayLike<number>);\n },\n };\n } catch (e) {\n return fail(isPermissionError(e) ? 'no-permission' : 'download-failed', errText(e));\n }\n}\n\n/**\n * Import the optional native backend. A host can supply it out-of-tree via\n * `VIBGRATE_EMBEDDER_PATH` — a directory whose `node_modules` contains\n * `fastembed`. Editor integrations use this when their bundled engine ships\n * without the native optional dependency (the VS Code extension installs it\n * into its own storage on consent); the host dir wins over this package's own\n * dependency tree so the copy the user consented to is the one that loads.\n * Any resolution failure falls through — never throws.\n */\nasync function importEmbedBackend(): Promise<{ mod: any | null; error?: string }> {\n const hostDir = process.env.VIBGRATE_EMBEDDER_PATH;\n let error: string | undefined;\n if (hostDir) {\n try {\n const req = createRequire(path.join(hostDir, 'package.json'));\n const mod: any = await import(pathToFileURL(req.resolve('fastembed')).href);\n const resolved = unwrapBackend(mod);\n if (resolved) return { mod: resolved };\n error = `${hostDir}: fastembed loaded but exported no FlagEmbedding`;\n } catch (e) {\n // Keep the reason. A host-supplied backend that resolves but won't load\n // (native binary built for another ABI, a half-extracted tree, a missing\n // transitive dep) is indistinguishable from \"never installed\" once the\n // error is dropped — and that is the one failure a user cannot act on.\n error = `${hostDir}: ${errText(e)}`;\n }\n }\n try {\n const mod: any = await import('fastembed' as string);\n const resolved = unwrapBackend(mod);\n return resolved ? { mod: resolved } : { mod: null, error: error ?? 'fastembed exported no FlagEmbedding' };\n } catch (e) {\n return { mod: null, error: error ?? errText(e) };\n }\n}\n\n/** A CJS entry imported over ESM may nest its exports one or two `default`s deep. */\nfunction unwrapBackend(mod: any): any | null {\n for (const candidate of [mod, mod?.default, mod?.default?.default]) {\n if (candidate?.FlagEmbedding) return candidate;\n }\n return null;\n}\n\nfunction errText(e: unknown): string {\n const msg = e instanceof Error ? e.message : String(e);\n return msg.replace(/\\s+/g, ' ').trim().slice(0, 300);\n}\n\n/** Ceiling for the one-time model fetch/init; override via VG_EMBED_TIMEOUT_MS. */\nfunction embedInitTimeoutMs(): number {\n const n = Number(process.env.VG_EMBED_TIMEOUT_MS);\n return Number.isFinite(n) && n > 0 ? n : 60_000;\n}\n\n/** Reject `promise` if it hasn't settled within `ms` (the work itself is not cancelled). */\nexport async function withTimeout<T>(promise: Promise<T>, ms: number, message: string): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(message)), ms);\n timer.unref?.();\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n}\n\nfunction mapModel(mod: any, id: string): unknown {\n const m = mod.EmbeddingModel ?? {};\n if (/bge-small/i.test(id)) return m.BGESmallENV15 ?? m.BGESmallEN ?? id;\n if (/bge-base/i.test(id)) return m.BGEBaseENV15 ?? id;\n if (/all-minilm/i.test(id)) return m.AllMiniLML6V2 ?? id;\n return id;\n}\n\n/** Path segments that carry no semantic signal — dropped from embed context. */\nconst PATH_NOISE = new Set([\n 'src', 'app', 'apps', 'lib', 'libs', 'dist', 'build', 'out', 'index', 'main',\n 'packages', 'pkg', 'test', 'tests', '__tests__', 'spec', 'node_modules', 'internal',\n 'com', 'example', 'demo', 'java', 'net', 'org', 'www',\n]);\n\n/** Meaningful path context for a node: a couple of parent dirs + the filename stem. */\nfunction pathContext(file: string): string {\n const parts = file.split('/');\n const stem = (parts.pop() ?? '').replace(/\\.[^.]+$/, '');\n const dirs = parts.filter((p) => p && !PATH_NOISE.has(p.toLowerCase()));\n return [...dirs.slice(-2), stem].filter(Boolean).join(' ');\n}\n\n/**\n * The text we embed for a node. Alongside identity + signature we add the\n * strongest available signal — the node's **doc-comment / docstring** summary —\n * plus lightweight context already on the graph (file-path words, area label), so\n * a tersely-named symbol (`Table`, `NotificationJob`) a concept query can reach.\n *\n * `document` nodes (markdown, manifests, Docker, CI, OpenAPI, …) put the\n * scrubbed body in `doc` — that body is the primary embed signal so `vg ask`\n * can answer project-context questions, not only code symbols.\n */\nexport function nodeEmbedText(node: GraphNode, areaLabel?: string): string {\n if (node.kind === 'document') {\n const category = (node.signature ?? 'document').replace(/^document:/, '');\n // Category keywords help ops/config queries land on the right file type.\n const categoryHints: Record<string, string> = {\n manifest: 'package dependencies scripts install dependencies versions',\n docker: 'dockerfile container image build runtime',\n compose: 'docker-compose services containers networking volumes',\n ci: 'continuous integration github actions workflow pipeline test build deploy',\n 'build-config': 'typescript tsconfig bundler vite webpack eslint prettier test',\n 'api-contract': 'openapi swagger graphql protobuf api schema endpoints',\n 'task-runner': 'makefile justfile tasks build test run commands',\n workspace: 'monorepo workspace packages pnpm turbo nx',\n infra: 'deploy infrastructure kubernetes kubernetes terraform helm kubernetes',\n 'env-example': 'environment variables configuration secrets template',\n markdown: 'documentation readme guide',\n };\n const hint = categoryHints[category] ?? category;\n return [\n node.qualifiedName,\n 'document',\n category,\n hint,\n pathContext(node.file),\n (node.doc ?? '').slice(0, 5000),\n ]\n .filter(Boolean)\n .join('\\n');\n }\n return [node.qualifiedName, node.kind, node.signature ?? '', node.doc ?? '', pathContext(node.file), areaLabel ?? '']\n .filter(Boolean)\n .join(' ');\n}\n\nexport function cosine(a: number[], b: number[]): number {\n let dot = 0;\n let na = 0;\n let nb = 0;\n const n = Math.min(a.length, b.length);\n for (let i = 0; i < n; i++) {\n dot += a[i] * b[i];\n na += a[i] * a[i];\n nb += b[i] * b[i];\n }\n if (na === 0 || nb === 0) return 0;\n return dot / (Math.sqrt(na) * Math.sqrt(nb));\n}\n\ninterface EmbedCache {\n model: string;\n entries: Record<string, { hash: string; vec: number[] }>;\n}\n\n/** Reports embedding progress: how many of `total` nodes are done so far. */\nexport type EmbedProgress = (done: number, total: number) => void;\n\n/** Nodes embedded per chunk — bounds memory and gives progress granularity. */\nconst EMBED_CHUNK = 256;\n/** Min gap between incremental cache writes (ms) — caps IO on big repos. */\nconst CACHE_WRITE_INTERVAL_MS = 1500;\n\n/**\n * Binary embeddings format (local cache next to the map, never committed):\n *\n * MAGIC \"VGEMB1\\0\" · u16 version · u16 modelLen · model utf8 ·\n * u32 dims · u32 count ·\n * for each entry: u16 idLen · id · u16 hashLen · hash ·\n * then contiguous Float32LE vectors [count × dims]\n *\n * Why binary: a medium map (~4k nodes × 384 dims) is ~6 MB of floats but was\n * ~30 MB of JSON with full decimal text — slow to parse and noisy in source\n * control if it ever landed under the repo. The filename is always\n * `embeddings` / `<snapshot>.embeddings`; the model id lives only in the header.\n */\n/** 8-byte little-endian-friendly magic (same width as graph `VGSNAP1\\0`). */\nconst EMB_MAGIC = Buffer.from('VGEMB01\\0', 'latin1');\nconst EMB_VERSION = 1;\n\nfunction vectorCachePath(root: string): string {\n return embeddingsPathFor(resolveGraphPath(root));\n}\n\n/** Pre-binary path: `.vibgrate/cache/embeddings-<model>.json` (read once to migrate). */\nfunction legacyVectorCachePath(root: string, modelId: string): string {\n return path.join(cacheDir(root), `embeddings-${safe(modelId)}.json`);\n}\n\n/**\n * How many searchable nodes still need embedding for `modelId` — cheap (hashes\n * the embed-text, reads only the cache; never loads the model). Lets the embed\n * command / background warm-up exit instantly when nothing changed.\n */\nexport function countPending(graph: VgGraph, root: string, modelId: string): number {\n const entries = loadCache(root, modelId).entries;\n const areaLabel = new Map(graph.areas.map((a) => [a.id, a.label] as const));\n let pending = 0;\n for (const n of graph.nodes) {\n // file/external stay out of the index; document (docs/env examples) are in.\n if (n.kind === 'file' || n.kind === 'external') continue;\n const h = hashString(nodeEmbedText(n, areaLabel.get(n.area)));\n const cached = entries[n.id];\n if (!cached || cached.hash !== h) pending++;\n }\n return pending;\n}\n\nfunction loadCache(root: string, modelId: string): EmbedCache {\n const file = vectorCachePath(root);\n const binary = readBinaryCache(file, modelId);\n if (binary) return binary;\n\n // Migrate legacy JSON if present (once) — keep working after upgrade without\n // re-embedding the whole repo.\n const legacy = legacyVectorCachePath(root, modelId);\n if (fs.existsSync(legacy)) {\n try {\n const loaded = JSON.parse(fs.readFileSync(legacy, 'utf8')) as EmbedCache;\n if (loaded.model === modelId && loaded.entries) {\n return { model: modelId, entries: loaded.entries };\n }\n } catch {\n /* treat as empty */\n }\n }\n return { model: modelId, entries: {} };\n}\n\ninterface EmbedHeader {\n model: string;\n dims: number;\n count: number;\n}\n\n/** Cheap header-only peek (no vectors) for `embeddingsCached` / diagnostics. */\nfunction readCacheHeader(file: string): EmbedHeader | null {\n let fd: number | null = null;\n try {\n fd = fs.openSync(file, 'r');\n const prefix = Buffer.alloc(8 + 2 + 2 + 512); // magic + ver + modelLen + model (capped)\n const n = fs.readSync(fd, prefix, 0, prefix.length, 0);\n if (n < EMB_MAGIC.length + 4 || !prefix.subarray(0, EMB_MAGIC.length).equals(EMB_MAGIC)) return null;\n let o = EMB_MAGIC.length;\n const version = prefix.readUInt16LE(o);\n o += 2;\n if (version !== EMB_VERSION) return null;\n const modelLen = prefix.readUInt16LE(o);\n o += 2;\n if (o + modelLen + 8 > n) {\n // model spills past our prefix — re-read exactly\n const full = Buffer.alloc(EMB_MAGIC.length + 2 + 2 + modelLen + 8);\n fs.readSync(fd, full, 0, full.length, 0);\n return parseHeaderPrefix(full);\n }\n return parseHeaderPrefix(prefix);\n } catch {\n return null;\n } finally {\n if (fd !== null) fs.closeSync(fd);\n }\n}\n\nfunction parseHeaderPrefix(buf: Buffer): EmbedHeader | null {\n try {\n if (!buf.subarray(0, EMB_MAGIC.length).equals(EMB_MAGIC)) return null;\n let o = EMB_MAGIC.length;\n if (buf.readUInt16LE(o) !== EMB_VERSION) return null;\n o += 2;\n const modelLen = buf.readUInt16LE(o);\n o += 2;\n if (o + modelLen + 8 > buf.length) return null;\n const model = buf.subarray(o, o + modelLen).toString('utf8');\n o += modelLen;\n const dims = buf.readUInt32LE(o);\n o += 4;\n const count = buf.readUInt32LE(o);\n return { model, dims, count };\n } catch {\n return null;\n }\n}\n\nfunction readBinaryCache(file: string, modelId: string): EmbedCache | null {\n if (!fs.existsSync(file)) return null;\n try {\n const buf = fs.readFileSync(file);\n if (buf.length < EMB_MAGIC.length + 4 || !buf.subarray(0, EMB_MAGIC.length).equals(EMB_MAGIC)) return null;\n let o = EMB_MAGIC.length;\n if (buf.readUInt16LE(o) !== EMB_VERSION) return null;\n o += 2;\n const modelLen = buf.readUInt16LE(o);\n o += 2;\n const model = buf.subarray(o, o + modelLen).toString('utf8');\n o += modelLen;\n if (model !== modelId) return null;\n const dims = buf.readUInt32LE(o);\n o += 4;\n const count = buf.readUInt32LE(o);\n o += 4;\n if (dims === 0 || count === 0) return { model, entries: {} };\n\n const ids: string[] = [];\n const hashes: string[] = [];\n for (let i = 0; i < count; i++) {\n const idLen = buf.readUInt16LE(o);\n o += 2;\n ids.push(buf.subarray(o, o + idLen).toString('utf8'));\n o += idLen;\n const hashLen = buf.readUInt16LE(o);\n o += 2;\n hashes.push(buf.subarray(o, o + hashLen).toString('utf8'));\n o += hashLen;\n }\n const floatsNeeded = count * dims;\n const bytesNeeded = floatsNeeded * 4;\n if (o + bytesNeeded > buf.length) return null;\n // Copy into a standalone ArrayBuffer so Float32Array views are safe after buf is GC'd.\n const floatBuf = Buffer.from(buf.subarray(o, o + bytesNeeded));\n const floats = new Float32Array(floatBuf.buffer, floatBuf.byteOffset, floatsNeeded);\n\n const entries: EmbedCache['entries'] = {};\n for (let i = 0; i < count; i++) {\n const start = i * dims;\n const vec = Array.from(floats.subarray(start, start + dims));\n entries[ids[i]!] = { hash: hashes[i]!, vec };\n }\n return { model, entries };\n } catch {\n return null;\n }\n}\n\nfunction writeBinaryCache(file: string, cache: EmbedCache): void {\n const ids = Object.keys(cache.entries);\n const count = ids.length;\n let dims = 0;\n for (const id of ids) {\n const d = cache.entries[id]!.vec.length;\n if (d > 0) {\n dims = d;\n break;\n }\n }\n // Empty or all-zero-dim cache: still write a valid header so \"cached\" is true.\n const modelBuf = Buffer.from(cache.model, 'utf8');\n if (modelBuf.length > 0xffff) throw new Error('embed model id too long');\n\n // Index size (ids + hashes)\n let indexBytes = 0;\n const idBufs: Buffer[] = [];\n const hashBufs: Buffer[] = [];\n for (const id of ids) {\n const ib = Buffer.from(id, 'utf8');\n const hb = Buffer.from(cache.entries[id]!.hash, 'utf8');\n if (ib.length > 0xffff || hb.length > 0xffff) throw new Error('embed entry key too long');\n idBufs.push(ib);\n hashBufs.push(hb);\n indexBytes += 2 + ib.length + 2 + hb.length;\n }\n\n const headerBytes = EMB_MAGIC.length + 2 + 2 + modelBuf.length + 4 + 4;\n const vecBytes = count * dims * 4;\n const out = Buffer.allocUnsafe(headerBytes + indexBytes + vecBytes);\n let o = 0;\n EMB_MAGIC.copy(out, o);\n o += EMB_MAGIC.length;\n out.writeUInt16LE(EMB_VERSION, o);\n o += 2;\n out.writeUInt16LE(modelBuf.length, o);\n o += 2;\n modelBuf.copy(out, o);\n o += modelBuf.length;\n out.writeUInt32LE(dims, o);\n o += 4;\n out.writeUInt32LE(count, o);\n o += 4;\n\n for (let i = 0; i < count; i++) {\n const ib = idBufs[i]!;\n const hb = hashBufs[i]!;\n out.writeUInt16LE(ib.length, o);\n o += 2;\n ib.copy(out, o);\n o += ib.length;\n out.writeUInt16LE(hb.length, o);\n o += 2;\n hb.copy(out, o);\n o += hb.length;\n }\n\n if (dims > 0 && count > 0) {\n const floats = new Float32Array(count * dims);\n for (let i = 0; i < count; i++) {\n const vec = cache.entries[ids[i]!]!.vec;\n const base = i * dims;\n for (let d = 0; d < dims; d++) floats[base + d] = vec[d] ?? 0;\n }\n Buffer.from(floats.buffer, floats.byteOffset, floats.byteLength).copy(out, o);\n }\n\n fs.mkdirSync(path.dirname(file), { recursive: true });\n const tmp = `${file}.tmp.${process.pid}`;\n fs.writeFileSync(tmp, out);\n fs.renameSync(tmp, file);\n}\n\n/** Best-effort drop of the old model-named JSON caches under `.vibgrate/cache/`. */\nfunction purgeLegacyJsonCaches(root: string): void {\n const dir = cacheDir(root);\n let names: string[];\n try {\n names = fs.readdirSync(dir);\n } catch {\n return;\n }\n for (const name of names) {\n if (/^embeddings-.+\\.json$/.test(name) || /^embeddings-.+\\.json\\.lock$/.test(name)) {\n try {\n fs.rmSync(path.join(dir, name), { force: true });\n } catch {\n /* best-effort */\n }\n }\n }\n}\n\n// Single-writer lock (shared helper — see ./lock.ts) so a foreground `ask`\n// and a background `embed` never both embed the same repo at once (which\n// would race on the cache file).\n\n/**\n * Node embeddings for the searchable (non-file/external) nodes, cache-backed:\n * only nodes whose embed-text changed are re-embedded. The first run embeds in\n * chunks, **persists the cache incrementally** (so an interrupted/timed-out run\n * resumes instead of wasting the work), and reports progress via `onProgress`.\n */\nexport async function getNodeEmbeddings(\n graph: VgGraph,\n embedder: Embedder,\n root: string,\n onProgress?: EmbedProgress,\n): Promise<Map<string, number[]>> {\n const file = vectorCachePath(root);\n const cache = loadCache(root, embedder.id);\n\n const areaLabel = new Map(graph.areas.map((a) => [a.id, a.label] as const));\n // Include document nodes (markdown/txt/env examples) so ask can retrieve docs.\n const targets = graph.nodes.filter((n) => n.kind !== 'file' && n.kind !== 'external');\n const toEmbed: { id: string; text: string; hash: string }[] = [];\n const vectors = new Map<string, number[]>();\n for (const n of targets) {\n const text = nodeEmbedText(n, areaLabel.get(n.area));\n const h = hashString(text);\n const cached = cache.entries[n.id];\n if (cached && cached.hash === h) vectors.set(n.id, cached.vec);\n else toEmbed.push({ id: n.id, text, hash: h });\n }\n\n // Atomic write (temp + rename) so a reader never sees a half-written cache.\n const persist = (): void => {\n try {\n writeBinaryCache(file, cache);\n purgeLegacyJsonCaches(root);\n } catch {\n /* cache write best-effort */\n }\n };\n\n if (toEmbed.length) {\n // Single-writer: if another process (e.g. a background warm-up) is already\n // embedding this repo, don't double-work or race the cache — return what's\n // cached so far (lexical floor still applies). It will be complete next run.\n const lock = `${file}.lock`;\n if (!acquireLock(lock)) return vectors;\n try {\n onProgress?.(0, toEmbed.length);\n let lastWrite = Date.now();\n for (let i = 0; i < toEmbed.length; i += EMBED_CHUNK) {\n const slice = toEmbed.slice(i, i + EMBED_CHUNK);\n const vecs = await embedder.embed(slice.map((t) => t.text));\n slice.forEach((t, j) => {\n const vec = vecs[j] ?? [];\n vectors.set(t.id, vec);\n cache.entries[t.id] = { hash: t.hash, vec };\n });\n onProgress?.(Math.min(i + EMBED_CHUNK, toEmbed.length), toEmbed.length);\n // Persist periodically so a crash/timeout resumes from here next run.\n if (Date.now() - lastWrite >= CACHE_WRITE_INTERVAL_MS) {\n persist();\n lastWrite = Date.now();\n }\n }\n // prune entries for nodes no longer present, then a final authoritative write\n const live = new Set(targets.map((n) => n.id));\n for (const id of Object.keys(cache.entries)) if (!live.has(id)) delete cache.entries[id];\n persist();\n } finally {\n releaseLock(lock);\n }\n } else if (!fs.existsSync(file) && Object.keys(cache.entries).length > 0) {\n // Migrating from legacy JSON with a full hit set — rewrite as binary once\n // so the next run never reads the old path again.\n persist();\n }\n\n return vectors;\n}\n\nfunction safe(id: string): string {\n return id.replace(/[^a-z0-9.-]+/gi, '_');\n}\n"]}
1
+ {"version":3,"sources":["../src/engine/lock.ts","../src/engine/embeddings.ts"],"names":["fs","path"],"mappings":"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","file":"chunk-KBP7GJV6.js","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * Cross-process single-writer lock (O_EXCL create), shared by the embedding\n * cache writer and the auto-refresh rebuild so two vg processes never write\n * the same repo-local artifact at once. A lock whose owning process is dead,\n * or that is older than `staleMs`, is presumed abandoned and reclaimed.\n */\n\n/** A lock older than this is presumed dead (crashed process). */\nexport const DEFAULT_LOCK_STALE_MS = 15 * 60 * 1000;\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (e) {\n return (e as NodeJS.ErrnoException).code === 'EPERM'; // exists, just not ours to signal\n }\n}\n\nfunction lockIsStale(file: string, staleMs: number): boolean {\n try {\n const { pid, at } = JSON.parse(fs.readFileSync(file, 'utf8')) as { pid?: number; at?: number };\n if (typeof at === 'number' && Date.now() - at > staleMs) return true;\n if (typeof pid === 'number' && !isProcessAlive(pid)) return true;\n return false;\n } catch {\n return true; // unreadable/corrupt → reclaim it\n }\n}\n\n/** Take the lock (O_EXCL), reclaiming a stale/dead one. Returns success. */\nexport function acquireLock(file: string, staleMs = DEFAULT_LOCK_STALE_MS): boolean {\n const write = (): boolean => {\n try {\n fs.mkdirSync(path.dirname(file), { recursive: true });\n const fd = fs.openSync(file, 'wx');\n fs.writeFileSync(fd, JSON.stringify({ pid: process.pid, at: Date.now() }));\n fs.closeSync(fd);\n return true;\n } catch {\n return false;\n }\n };\n if (write()) return true;\n if (lockIsStale(file, staleMs)) {\n try {\n fs.rmSync(file, { force: true });\n } catch {\n /* another process may have reclaimed it */\n }\n return write();\n }\n return false;\n}\n\nexport function releaseLock(file: string): void {\n try {\n fs.rmSync(file, { force: true });\n } catch {\n /* best-effort */\n }\n}\n","import * as fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { hashString } from './hash.js';\nimport { cacheDir } from './cache.js';\nimport { resolveGraphPath } from './artifacts.js';\nimport { acquireLock, releaseLock } from './lock.js';\nimport type { GraphNode, VgGraph } from '../schema.js';\n\n/**\n * Local-embedding semantic search for `vg ask --semantic`/`--deep` (no API key).\n *\n * The embedding backend is an OPTIONAL, lazily-loaded dependency (`fastembed`,\n * Apache-2.0, local ONNX) so the core install stays lean and `ask` never breaks:\n * if the backend or model isn't available it degrades to (prefix-fuzzy) lexical\n * search with a clear note. Per-repo vectors live in a binary `*.embeddings`\n * file **alongside the code map** (global store under Application Support /\n * XDG data, or `.vibgrate/embeddings` in-repo) — never model-named, never under\n * `.vibgrate/cache/`, and NEVER inside the committed `graph.json`, so the map\n * stays byte-deterministic. The model id is recorded inside the file header so\n * a model change still invalidates the cache without putting the name in the\n * path.\n *\n * `--local` disables the model download (semantic is skipped unless already\n * cached via an injected backend), keeping the air-gapped guarantee.\n */\n\nexport interface Embedder {\n /** Stable model id (recorded with cached vectors so a model change invalidates them). */\n id: string;\n /** Embed documents → unit-or-raw vectors (cosine handles normalization). */\n embed(texts: string[]): Promise<number[][]>;\n /** Embed a single query string. */\n embedQuery(text: string): Promise<number[]>;\n}\n\n/** Why semantic fell back to lexical — for calm, specific messaging. */\nexport type EmbedUnavailable = 'not-installed' | 'no-permission' | 'download-failed' | 'init-failed';\n\nexport interface LoadEmbedderOptions {\n local?: boolean; // --local: do not download a model\n model?: string; // override the embedding model id\n noDownload?: boolean; // only load if the model is already cached (never fetch)\n showDownloadProgress?: boolean; // let fastembed print its one-time download progress\n /**\n * Called (not thrown) when the backend can't load. `detail` carries the\n * underlying loader error when there is one, so a host can log something\n * actionable instead of a bare category.\n */\n onUnavailable?: (reason: EmbedUnavailable, detail?: string) => void;\n}\n\n/** The embedding model id in effect (explicit override → default). */\nexport function resolveEmbedModel(model?: string): string {\n return model ?? 'bge-small-en-v1.5';\n}\n\n/**\n * The **central, per-user** model cache — downloaded once per machine and shared\n * across every repo/folder (devs have many repos; the ~tens-of-MB model should\n * not re-download per project). Uses the XDG standard:\n * `$XDG_CACHE_HOME/vibgrate/models` (or `~/.cache/vibgrate/models`); relocate via\n * the standard `XDG_CACHE_HOME`. NB: fastembed's own default is the relative\n * `./local_cache`, i.e. per-CWD — which we override.\n */\nexport function modelCacheDir(): string {\n const base = process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache');\n return path.join(base, 'vibgrate', 'models');\n}\n\n/** A machine-global marker written once the model has loaded successfully. */\nfunction modelReadyMarker(modelId: string): string {\n return path.join(modelCacheDir(), `.ready-${safe(modelId)}`);\n}\n\n/**\n * Whether the embedding model is already present on this machine (loaded at least\n * once), so it can be used with **no network**. Lets the background warm-up\n * trigger only when it won't surprise-download.\n */\nexport function isModelReady(modelId = resolveEmbedModel()): boolean {\n return fs.existsSync(modelReadyMarker(modelId));\n}\n\n/**\n * A calm, specific, actionable one-liner for why semantic isn't available right\n * now — built to reassure (lexical still works) and inform, never to alarm. No\n * stack traces, no scary words; always names the off switch and the fix.\n */\nexport function unavailableMessage(reason: EmbedUnavailable): string {\n switch (reason) {\n case 'no-permission':\n return `semantic search couldn't write its model cache at ${modelCacheDir()} — using fast lexical search instead. Relocate it with the standard XDG_CACHE_HOME, or run with --local to stay lexical quietly. (No admin/sudo is ever needed — the cache lives in your home folder.)`;\n case 'download-failed':\n return `the semantic model isn't downloaded yet and couldn't be fetched (offline?) — using fast lexical search. It'll try again next time; run with --local to keep lexical without retrying.`;\n case 'not-installed':\n return `the optional semantic backend isn't available here — using fast lexical search.`;\n case 'init-failed':\n default:\n return `the semantic model couldn't load — using fast lexical search.`;\n }\n}\n\nexport interface ModelCacheInfo {\n dir: string;\n present: boolean;\n bytes: number;\n}\n\n/** Where the shared model lives, whether it's present, and how big it is. */\nexport function modelCacheInfo(modelId = resolveEmbedModel()): ModelCacheInfo {\n const dir = modelCacheDir();\n return { dir, present: isModelReady(modelId) || fs.existsSync(dir), bytes: dirSize(dir) };\n}\n\n/** Remove the shared, re-downloadable model from the central cache. Returns bytes freed. */\nexport function clearModelCache(): number {\n const dir = modelCacheDir();\n const bytes = dirSize(dir);\n try {\n fs.rmSync(dir, { recursive: true, force: true });\n } catch {\n /* best-effort */\n }\n return bytes;\n}\n\nfunction dirSize(dir: string): number {\n let total = 0;\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return 0;\n }\n for (const e of entries) {\n const p = path.join(dir, e.name);\n if (e.isDirectory()) total += dirSize(p);\n else {\n try {\n total += fs.statSync(p).size;\n } catch {\n /* skip unreadable */\n }\n }\n }\n return total;\n}\n\nfunction isPermissionError(e: unknown): boolean {\n const code = (e as NodeJS.ErrnoException | undefined)?.code;\n return code === 'EACCES' || code === 'EPERM' || code === 'EROFS';\n}\n\n/**\n * Whether this repo already has a cached vector set for `modelId` — i.e. semantic\n * search has run here before, so the next run is fast (no first-use download/embed).\n * Lets `ask` show the one-time setup note only when it's actually warranted.\n * Checks the binary sidecar next to the map (and the legacy JSON path once).\n */\nexport function embeddingsCached(root: string, modelId: string): boolean {\n const file = vectorCachePath(root);\n if (fs.existsSync(file) && readCacheHeader(file)?.model === modelId) return true;\n // One-shot legacy: pre-binary caches lived under `.vibgrate/cache/embeddings-<model>.json`.\n return fs.existsSync(legacyVectorCachePath(root, modelId));\n}\n\n/**\n * Path of the binary embeddings file for this repo's current map — always named\n * `embeddings` (or `<snapshot>.embeddings` next to a branch-keyed graph), never\n * after the model. Exported for `vg embed --where` and tests.\n */\nexport function embeddingsPath(root: string): string {\n return vectorCachePath(root);\n}\n\n/** Sidecar path next to a map file: `…/branch-main.graph.json` → `…/branch-main.embeddings`. */\nexport function embeddingsPathFor(graphPath: string): string {\n // Branch-keyed global maps: `…/graphs/branch-main.graph.json` → `…/graphs/branch-main.embeddings`.\n if (graphPath.endsWith('.graph.json')) return `${graphPath.slice(0, -'.graph.json'.length)}.embeddings`;\n if (graphPath.endsWith('.graph.snap')) return `${graphPath.slice(0, -'.graph.snap'.length)}.embeddings`;\n // In-repo map is exactly `…/graph.json` (or `graph.snap`) → plain `…/embeddings`.\n const base = path.basename(graphPath);\n if (base === 'graph.json' || base === 'graph.snap') {\n return path.join(path.dirname(graphPath), 'embeddings');\n }\n if (graphPath.endsWith('.json')) return `${graphPath.slice(0, -5)}.embeddings`;\n if (graphPath.endsWith('.snap')) return `${graphPath.slice(0, -5)}.embeddings`;\n return `${graphPath}.embeddings`;\n}\n\n/**\n * Try to load the optional local embedding backend. Returns null (→ caller falls\n * back to lexical) when running `--local`, when the dependency isn't installed,\n * or when the model can't initialize.\n */\nexport async function loadEmbedder(options: LoadEmbedderOptions = {}): Promise<Embedder | null> {\n // `--local` forces the deterministic lexical floor with no model load/download\n // (air-gapped guarantee; also how tests stay offline).\n if (options.local) return null;\n const modelId = resolveEmbedModel(options.model);\n // noDownload (used by the background warm-up): never fetch — bail if not cached.\n if (options.noDownload && !isModelReady(modelId)) return null;\n const fail = (reason: EmbedUnavailable, detail?: string): null => {\n options.onUnavailable?.(reason, detail);\n return null;\n };\n\n // Lazy, optional dependency (native ONNX): loaded only for `vg ask`/`embed`,\n // never by build/verify, so the graph artifact stays deterministic.\n const backend = await importEmbedBackend();\n const mod: any = backend.mod;\n if (!mod?.FlagEmbedding) return fail('not-installed', backend.error);\n\n const cache = modelCacheDir(); // central, shared across all repos\n try {\n fs.mkdirSync(cache, { recursive: true });\n } catch (e) {\n return fail(isPermissionError(e) ? 'no-permission' : 'init-failed');\n }\n\n try {\n // First use fetches the model. A refused connection fails fast, but a\n // black-holing proxy (common on corporate networks) would hang the first\n // `vg ask` / MCP query_graph forever — bound the wait and fall back to\n // lexical instead. Cached loads are local disk and get the same generous\n // ceiling without ever hitting it.\n const model: any = await withTimeout(\n mod.FlagEmbedding.init({\n model: mapModel(mod, modelId),\n cacheDir: cache,\n showDownloadProgress: options.showDownloadProgress ?? false,\n }) as Promise<unknown>,\n embedInitTimeoutMs(),\n 'embedding model init timed out',\n );\n // Record machine-global readiness so future builds can warm up offline.\n try {\n fs.writeFileSync(modelReadyMarker(modelId), new Date(0).toISOString());\n } catch {\n /* marker is best-effort */\n }\n return {\n id: modelId,\n async embed(texts) {\n const out: number[][] = [];\n for await (const batch of model.embed(texts, 64)) {\n for (const v of batch) out.push(Array.from(v as ArrayLike<number>));\n }\n return out;\n },\n async embedQuery(text) {\n const v = await model.queryEmbed(text);\n return Array.from(v as ArrayLike<number>);\n },\n };\n } catch (e) {\n return fail(isPermissionError(e) ? 'no-permission' : 'download-failed', errText(e));\n }\n}\n\n/**\n * Import the optional native backend. A host can supply it out-of-tree via\n * `VIBGRATE_EMBEDDER_PATH` — a directory whose `node_modules` contains\n * `fastembed`. Editor integrations use this when their bundled engine ships\n * without the native optional dependency (the VS Code extension installs it\n * into its own storage on consent); the host dir wins over this package's own\n * dependency tree so the copy the user consented to is the one that loads.\n * Any resolution failure falls through — never throws.\n */\nasync function importEmbedBackend(): Promise<{ mod: any | null; error?: string }> {\n const hostDir = process.env.VIBGRATE_EMBEDDER_PATH;\n let error: string | undefined;\n if (hostDir) {\n try {\n const req = createRequire(path.join(hostDir, 'package.json'));\n const mod: any = await import(pathToFileURL(req.resolve('fastembed')).href);\n const resolved = unwrapBackend(mod);\n if (resolved) return { mod: resolved };\n error = `${hostDir}: fastembed loaded but exported no FlagEmbedding`;\n } catch (e) {\n // Keep the reason. A host-supplied backend that resolves but won't load\n // (native binary built for another ABI, a half-extracted tree, a missing\n // transitive dep) is indistinguishable from \"never installed\" once the\n // error is dropped — and that is the one failure a user cannot act on.\n error = `${hostDir}: ${errText(e)}`;\n }\n }\n try {\n const mod: any = await import('fastembed' as string);\n const resolved = unwrapBackend(mod);\n return resolved ? { mod: resolved } : { mod: null, error: error ?? 'fastembed exported no FlagEmbedding' };\n } catch (e) {\n return { mod: null, error: error ?? errText(e) };\n }\n}\n\n/** A CJS entry imported over ESM may nest its exports one or two `default`s deep. */\nfunction unwrapBackend(mod: any): any | null {\n for (const candidate of [mod, mod?.default, mod?.default?.default]) {\n if (candidate?.FlagEmbedding) return candidate;\n }\n return null;\n}\n\nfunction errText(e: unknown): string {\n const msg = e instanceof Error ? e.message : String(e);\n return msg.replace(/\\s+/g, ' ').trim().slice(0, 300);\n}\n\n/** Ceiling for the one-time model fetch/init; override via VG_EMBED_TIMEOUT_MS. */\nfunction embedInitTimeoutMs(): number {\n const n = Number(process.env.VG_EMBED_TIMEOUT_MS);\n return Number.isFinite(n) && n > 0 ? n : 60_000;\n}\n\n/** Reject `promise` if it hasn't settled within `ms` (the work itself is not cancelled). */\nexport async function withTimeout<T>(promise: Promise<T>, ms: number, message: string): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(message)), ms);\n timer.unref?.();\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n}\n\nfunction mapModel(mod: any, id: string): unknown {\n const m = mod.EmbeddingModel ?? {};\n if (/bge-small/i.test(id)) return m.BGESmallENV15 ?? m.BGESmallEN ?? id;\n if (/bge-base/i.test(id)) return m.BGEBaseENV15 ?? id;\n if (/all-minilm/i.test(id)) return m.AllMiniLML6V2 ?? id;\n return id;\n}\n\n/** Path segments that carry no semantic signal — dropped from embed context. */\nconst PATH_NOISE = new Set([\n 'src', 'app', 'apps', 'lib', 'libs', 'dist', 'build', 'out', 'index', 'main',\n 'packages', 'pkg', 'test', 'tests', '__tests__', 'spec', 'node_modules', 'internal',\n 'com', 'example', 'demo', 'java', 'net', 'org', 'www',\n]);\n\n/** Meaningful path context for a node: a couple of parent dirs + the filename stem. */\nfunction pathContext(file: string): string {\n const parts = file.split('/');\n const stem = (parts.pop() ?? '').replace(/\\.[^.]+$/, '');\n const dirs = parts.filter((p) => p && !PATH_NOISE.has(p.toLowerCase()));\n return [...dirs.slice(-2), stem].filter(Boolean).join(' ');\n}\n\n/**\n * The text we embed for a node. Alongside identity + signature we add the\n * strongest available signal — the node's **doc-comment / docstring** summary —\n * plus lightweight context already on the graph (file-path words, area label), so\n * a tersely-named symbol (`Table`, `NotificationJob`) a concept query can reach.\n *\n * `document` nodes (markdown, manifests, Docker, CI, OpenAPI, …) put the\n * scrubbed body in `doc` — that body is the primary embed signal so `vg ask`\n * can answer project-context questions, not only code symbols.\n */\nexport function nodeEmbedText(node: GraphNode, areaLabel?: string): string {\n if (node.kind === 'document') {\n const category = (node.signature ?? 'document').replace(/^document:/, '');\n // Category keywords help ops/config queries land on the right file type.\n const categoryHints: Record<string, string> = {\n manifest: 'package dependencies scripts install dependencies versions',\n docker: 'dockerfile container image build runtime',\n compose: 'docker-compose services containers networking volumes',\n ci: 'continuous integration github actions workflow pipeline test build deploy',\n 'build-config': 'typescript tsconfig bundler vite webpack eslint prettier test',\n 'api-contract': 'openapi swagger graphql protobuf api schema endpoints',\n 'task-runner': 'makefile justfile tasks build test run commands',\n workspace: 'monorepo workspace packages pnpm turbo nx',\n infra: 'deploy infrastructure kubernetes kubernetes terraform helm kubernetes',\n 'env-example': 'environment variables configuration secrets template',\n markdown: 'documentation readme guide',\n };\n const hint = categoryHints[category] ?? category;\n return [\n node.qualifiedName,\n 'document',\n category,\n hint,\n pathContext(node.file),\n (node.doc ?? '').slice(0, 5000),\n ]\n .filter(Boolean)\n .join('\\n');\n }\n return [node.qualifiedName, node.kind, node.signature ?? '', node.doc ?? '', pathContext(node.file), areaLabel ?? '']\n .filter(Boolean)\n .join(' ');\n}\n\nexport function cosine(a: number[], b: number[]): number {\n let dot = 0;\n let na = 0;\n let nb = 0;\n const n = Math.min(a.length, b.length);\n for (let i = 0; i < n; i++) {\n dot += a[i] * b[i];\n na += a[i] * a[i];\n nb += b[i] * b[i];\n }\n if (na === 0 || nb === 0) return 0;\n return dot / (Math.sqrt(na) * Math.sqrt(nb));\n}\n\ninterface EmbedCache {\n model: string;\n entries: Record<string, { hash: string; vec: number[] }>;\n}\n\n/** Reports embedding progress: how many of `total` nodes are done so far. */\nexport type EmbedProgress = (done: number, total: number) => void;\n\n/** Nodes embedded per chunk — bounds memory and gives progress granularity. */\nconst EMBED_CHUNK = 256;\n/** Min gap between incremental cache writes (ms) — caps IO on big repos. */\nconst CACHE_WRITE_INTERVAL_MS = 1500;\n\n/**\n * Binary embeddings format (local cache next to the map, never committed):\n *\n * MAGIC \"VGEMB1\\0\" · u16 version · u16 modelLen · model utf8 ·\n * u32 dims · u32 count ·\n * for each entry: u16 idLen · id · u16 hashLen · hash ·\n * then contiguous Float32LE vectors [count × dims]\n *\n * Why binary: a medium map (~4k nodes × 384 dims) is ~6 MB of floats but was\n * ~30 MB of JSON with full decimal text — slow to parse and noisy in source\n * control if it ever landed under the repo. The filename is always\n * `embeddings` / `<snapshot>.embeddings`; the model id lives only in the header.\n */\n/** 8-byte little-endian-friendly magic (same width as graph `VGSNAP1\\0`). */\nconst EMB_MAGIC = Buffer.from('VGEMB01\\0', 'latin1');\nconst EMB_VERSION = 1;\n\nfunction vectorCachePath(root: string): string {\n return embeddingsPathFor(resolveGraphPath(root));\n}\n\n/** Pre-binary path: `.vibgrate/cache/embeddings-<model>.json` (read once to migrate). */\nfunction legacyVectorCachePath(root: string, modelId: string): string {\n return path.join(cacheDir(root), `embeddings-${safe(modelId)}.json`);\n}\n\n/**\n * How many searchable nodes still need embedding for `modelId` — cheap (hashes\n * the embed-text, reads only the cache; never loads the model). Lets the embed\n * command / background warm-up exit instantly when nothing changed.\n */\nexport function countPending(graph: VgGraph, root: string, modelId: string): number {\n const entries = loadCache(root, modelId).entries;\n const areaLabel = new Map(graph.areas.map((a) => [a.id, a.label] as const));\n let pending = 0;\n for (const n of graph.nodes) {\n // file/external stay out of the index; document (docs/env examples) are in.\n if (n.kind === 'file' || n.kind === 'external') continue;\n const h = hashString(nodeEmbedText(n, areaLabel.get(n.area)));\n const cached = entries[n.id];\n if (!cached || cached.hash !== h) pending++;\n }\n return pending;\n}\n\nfunction loadCache(root: string, modelId: string): EmbedCache {\n const file = vectorCachePath(root);\n const binary = readBinaryCache(file, modelId);\n if (binary) return binary;\n\n // Migrate legacy JSON if present (once) — keep working after upgrade without\n // re-embedding the whole repo.\n const legacy = legacyVectorCachePath(root, modelId);\n if (fs.existsSync(legacy)) {\n try {\n const loaded = JSON.parse(fs.readFileSync(legacy, 'utf8')) as EmbedCache;\n if (loaded.model === modelId && loaded.entries) {\n return { model: modelId, entries: loaded.entries };\n }\n } catch {\n /* treat as empty */\n }\n }\n return { model: modelId, entries: {} };\n}\n\ninterface EmbedHeader {\n model: string;\n dims: number;\n count: number;\n}\n\n/** Cheap header-only peek (no vectors) for `embeddingsCached` / diagnostics. */\nfunction readCacheHeader(file: string): EmbedHeader | null {\n let fd: number | null = null;\n try {\n fd = fs.openSync(file, 'r');\n const prefix = Buffer.alloc(8 + 2 + 2 + 512); // magic + ver + modelLen + model (capped)\n const n = fs.readSync(fd, prefix, 0, prefix.length, 0);\n if (n < EMB_MAGIC.length + 4 || !prefix.subarray(0, EMB_MAGIC.length).equals(EMB_MAGIC)) return null;\n let o = EMB_MAGIC.length;\n const version = prefix.readUInt16LE(o);\n o += 2;\n if (version !== EMB_VERSION) return null;\n const modelLen = prefix.readUInt16LE(o);\n o += 2;\n if (o + modelLen + 8 > n) {\n // model spills past our prefix — re-read exactly\n const full = Buffer.alloc(EMB_MAGIC.length + 2 + 2 + modelLen + 8);\n fs.readSync(fd, full, 0, full.length, 0);\n return parseHeaderPrefix(full);\n }\n return parseHeaderPrefix(prefix);\n } catch {\n return null;\n } finally {\n if (fd !== null) fs.closeSync(fd);\n }\n}\n\nfunction parseHeaderPrefix(buf: Buffer): EmbedHeader | null {\n try {\n if (!buf.subarray(0, EMB_MAGIC.length).equals(EMB_MAGIC)) return null;\n let o = EMB_MAGIC.length;\n if (buf.readUInt16LE(o) !== EMB_VERSION) return null;\n o += 2;\n const modelLen = buf.readUInt16LE(o);\n o += 2;\n if (o + modelLen + 8 > buf.length) return null;\n const model = buf.subarray(o, o + modelLen).toString('utf8');\n o += modelLen;\n const dims = buf.readUInt32LE(o);\n o += 4;\n const count = buf.readUInt32LE(o);\n return { model, dims, count };\n } catch {\n return null;\n }\n}\n\nfunction readBinaryCache(file: string, modelId: string): EmbedCache | null {\n if (!fs.existsSync(file)) return null;\n try {\n const buf = fs.readFileSync(file);\n if (buf.length < EMB_MAGIC.length + 4 || !buf.subarray(0, EMB_MAGIC.length).equals(EMB_MAGIC)) return null;\n let o = EMB_MAGIC.length;\n if (buf.readUInt16LE(o) !== EMB_VERSION) return null;\n o += 2;\n const modelLen = buf.readUInt16LE(o);\n o += 2;\n const model = buf.subarray(o, o + modelLen).toString('utf8');\n o += modelLen;\n if (model !== modelId) return null;\n const dims = buf.readUInt32LE(o);\n o += 4;\n const count = buf.readUInt32LE(o);\n o += 4;\n if (dims === 0 || count === 0) return { model, entries: {} };\n\n const ids: string[] = [];\n const hashes: string[] = [];\n for (let i = 0; i < count; i++) {\n const idLen = buf.readUInt16LE(o);\n o += 2;\n ids.push(buf.subarray(o, o + idLen).toString('utf8'));\n o += idLen;\n const hashLen = buf.readUInt16LE(o);\n o += 2;\n hashes.push(buf.subarray(o, o + hashLen).toString('utf8'));\n o += hashLen;\n }\n const floatsNeeded = count * dims;\n const bytesNeeded = floatsNeeded * 4;\n if (o + bytesNeeded > buf.length) return null;\n // Copy into a standalone ArrayBuffer so Float32Array views are safe after buf is GC'd.\n const floatBuf = Buffer.from(buf.subarray(o, o + bytesNeeded));\n const floats = new Float32Array(floatBuf.buffer, floatBuf.byteOffset, floatsNeeded);\n\n const entries: EmbedCache['entries'] = {};\n for (let i = 0; i < count; i++) {\n const start = i * dims;\n const vec = Array.from(floats.subarray(start, start + dims));\n entries[ids[i]!] = { hash: hashes[i]!, vec };\n }\n return { model, entries };\n } catch {\n return null;\n }\n}\n\nfunction writeBinaryCache(file: string, cache: EmbedCache): void {\n const ids = Object.keys(cache.entries);\n const count = ids.length;\n let dims = 0;\n for (const id of ids) {\n const d = cache.entries[id]!.vec.length;\n if (d > 0) {\n dims = d;\n break;\n }\n }\n // Empty or all-zero-dim cache: still write a valid header so \"cached\" is true.\n const modelBuf = Buffer.from(cache.model, 'utf8');\n if (modelBuf.length > 0xffff) throw new Error('embed model id too long');\n\n // Index size (ids + hashes)\n let indexBytes = 0;\n const idBufs: Buffer[] = [];\n const hashBufs: Buffer[] = [];\n for (const id of ids) {\n const ib = Buffer.from(id, 'utf8');\n const hb = Buffer.from(cache.entries[id]!.hash, 'utf8');\n if (ib.length > 0xffff || hb.length > 0xffff) throw new Error('embed entry key too long');\n idBufs.push(ib);\n hashBufs.push(hb);\n indexBytes += 2 + ib.length + 2 + hb.length;\n }\n\n const headerBytes = EMB_MAGIC.length + 2 + 2 + modelBuf.length + 4 + 4;\n const vecBytes = count * dims * 4;\n const out = Buffer.allocUnsafe(headerBytes + indexBytes + vecBytes);\n let o = 0;\n EMB_MAGIC.copy(out, o);\n o += EMB_MAGIC.length;\n out.writeUInt16LE(EMB_VERSION, o);\n o += 2;\n out.writeUInt16LE(modelBuf.length, o);\n o += 2;\n modelBuf.copy(out, o);\n o += modelBuf.length;\n out.writeUInt32LE(dims, o);\n o += 4;\n out.writeUInt32LE(count, o);\n o += 4;\n\n for (let i = 0; i < count; i++) {\n const ib = idBufs[i]!;\n const hb = hashBufs[i]!;\n out.writeUInt16LE(ib.length, o);\n o += 2;\n ib.copy(out, o);\n o += ib.length;\n out.writeUInt16LE(hb.length, o);\n o += 2;\n hb.copy(out, o);\n o += hb.length;\n }\n\n if (dims > 0 && count > 0) {\n const floats = new Float32Array(count * dims);\n for (let i = 0; i < count; i++) {\n const vec = cache.entries[ids[i]!]!.vec;\n const base = i * dims;\n for (let d = 0; d < dims; d++) floats[base + d] = vec[d] ?? 0;\n }\n Buffer.from(floats.buffer, floats.byteOffset, floats.byteLength).copy(out, o);\n }\n\n fs.mkdirSync(path.dirname(file), { recursive: true });\n const tmp = `${file}.tmp.${process.pid}`;\n fs.writeFileSync(tmp, out);\n fs.renameSync(tmp, file);\n}\n\n/** Best-effort drop of the old model-named JSON caches under `.vibgrate/cache/`. */\nfunction purgeLegacyJsonCaches(root: string): void {\n const dir = cacheDir(root);\n let names: string[];\n try {\n names = fs.readdirSync(dir);\n } catch {\n return;\n }\n for (const name of names) {\n if (/^embeddings-.+\\.json$/.test(name) || /^embeddings-.+\\.json\\.lock$/.test(name)) {\n try {\n fs.rmSync(path.join(dir, name), { force: true });\n } catch {\n /* best-effort */\n }\n }\n }\n}\n\n// Single-writer lock (shared helper — see ./lock.ts) so a foreground `ask`\n// and a background `embed` never both embed the same repo at once (which\n// would race on the cache file).\n\n/**\n * Node embeddings for the searchable (non-file/external) nodes, cache-backed:\n * only nodes whose embed-text changed are re-embedded. The first run embeds in\n * chunks, **persists the cache incrementally** (so an interrupted/timed-out run\n * resumes instead of wasting the work), and reports progress via `onProgress`.\n */\nexport async function getNodeEmbeddings(\n graph: VgGraph,\n embedder: Embedder,\n root: string,\n onProgress?: EmbedProgress,\n): Promise<Map<string, number[]>> {\n const file = vectorCachePath(root);\n const cache = loadCache(root, embedder.id);\n\n const areaLabel = new Map(graph.areas.map((a) => [a.id, a.label] as const));\n // Include document nodes (markdown/txt/env examples) so ask can retrieve docs.\n const targets = graph.nodes.filter((n) => n.kind !== 'file' && n.kind !== 'external');\n const toEmbed: { id: string; text: string; hash: string }[] = [];\n const vectors = new Map<string, number[]>();\n for (const n of targets) {\n const text = nodeEmbedText(n, areaLabel.get(n.area));\n const h = hashString(text);\n const cached = cache.entries[n.id];\n if (cached && cached.hash === h) vectors.set(n.id, cached.vec);\n else toEmbed.push({ id: n.id, text, hash: h });\n }\n\n // Atomic write (temp + rename) so a reader never sees a half-written cache.\n const persist = (): void => {\n try {\n writeBinaryCache(file, cache);\n purgeLegacyJsonCaches(root);\n } catch {\n /* cache write best-effort */\n }\n };\n\n if (toEmbed.length) {\n // Single-writer: if another process (e.g. a background warm-up) is already\n // embedding this repo, don't double-work or race the cache — return what's\n // cached so far (lexical floor still applies). It will be complete next run.\n const lock = `${file}.lock`;\n if (!acquireLock(lock)) return vectors;\n try {\n onProgress?.(0, toEmbed.length);\n let lastWrite = Date.now();\n for (let i = 0; i < toEmbed.length; i += EMBED_CHUNK) {\n const slice = toEmbed.slice(i, i + EMBED_CHUNK);\n const vecs = await embedder.embed(slice.map((t) => t.text));\n slice.forEach((t, j) => {\n const vec = vecs[j] ?? [];\n vectors.set(t.id, vec);\n cache.entries[t.id] = { hash: t.hash, vec };\n });\n onProgress?.(Math.min(i + EMBED_CHUNK, toEmbed.length), toEmbed.length);\n // Persist periodically so a crash/timeout resumes from here next run.\n if (Date.now() - lastWrite >= CACHE_WRITE_INTERVAL_MS) {\n persist();\n lastWrite = Date.now();\n }\n }\n // prune entries for nodes no longer present, then a final authoritative write\n const live = new Set(targets.map((n) => n.id));\n for (const id of Object.keys(cache.entries)) if (!live.has(id)) delete cache.entries[id];\n persist();\n } finally {\n releaseLock(lock);\n }\n } else if (!fs.existsSync(file) && Object.keys(cache.entries).length > 0) {\n // Migrating from legacy JSON with a full hit set — rewrite as binary once\n // so the next run never reads the old path again.\n persist();\n }\n\n return vectors;\n}\n\nfunction safe(id: string): string {\n return id.replace(/[^a-z0-9.-]+/gi, '_');\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { resolveIngestHost } from './chunk-HTLDXEHW.js';
2
- import { cacheDir } from './chunk-ZMSTSEGR.js';
3
- import { VERSION } from './chunk-K6MLOGU4.js';
2
+ import { cacheDir } from './chunk-EWZKOU66.js';
3
+ import { VERSION } from './chunk-RT7P5AYU.js';
4
4
  import * as fs from 'fs';
5
5
  import * as os from 'os';
6
6
  import * as path from 'path';
@@ -212,5 +212,5 @@ var StatsSharer = class {
212
212
  };
213
213
 
214
214
  export { StatsSharer, installId, isCI, statsEndpoint, telemetryOptOut };
215
- //# sourceMappingURL=chunk-6XKDAYYR.js.map
216
- //# sourceMappingURL=chunk-6XKDAYYR.js.map
215
+ //# sourceMappingURL=chunk-KF2QT6RY.js.map
216
+ //# sourceMappingURL=chunk-KF2QT6RY.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/engine/stats-share.ts"],"names":[],"mappings":"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","file":"chunk-6XKDAYYR.js","sourcesContent":["import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport { cacheDir } from './cache.js';\nimport { VERSION } from '../version.js';\nimport { resolveIngestHost } from '../reporting/regions.js';\nimport type { SavingEntry, Source, Outcome } from './savings.js';\n\n/**\n * Opt-in usage-stats sharing for `vg serve --share-stats`.\n *\n * This is the ONLY path in `vg serve` that sends anything off the machine, and\n * it is off unless the operator explicitly asks for it. What we send is the\n * same counts-only ledger `vg savings` reports locally — per (source, client,\n * tool, outcome): how many calls and the vg-vs-grep token figures — plus the vg\n * version, OS/arch, and a random per-install id. We never send code, file paths,\n * question text, repo identity, or any credential. See GUARDRAILS §3.4.\n *\n * Even when the flag is passed, the universal `DO_NOT_TRACK` opt-out (or\n * `VIBGRATE_TELEMETRY=0`) wins: nothing is uploaded and no install id is ever\n * minted or persisted (see `telemetryOptOut` / `installId`).\n *\n * Design:\n * - The local ledger (savings.jsonl) is the single source of truth; the flusher\n * reads only the tail past a persisted byte offset, so a batch is sent once.\n * - Fire-and-forget with a short timeout. A network problem never blocks a tool\n * call and never throws — the offset only advances on a confirmed 2xx, so a\n * failed batch is retried on the next flush.\n * - Fully offline-safe: under `--local` the sharer is never constructed.\n */\n\n/** Payload schema version — must match the server's `mcpUsageStatsSchema`. */\nconst SCHEMA_VERSION = '1';\n/** Where the offset (and cached install id) live, per repo, beside the ledger. */\nconst OFFSET_FILE = 'stats-share.json';\n/** The machine-global anonymous install id lives here (stable across repos). */\nconst INSTALL_ID_DIR = path.join(os.homedir(), '.vibgrate');\nconst INSTALL_ID_FILE = path.join(INSTALL_ID_DIR, 'install-id');\n/** Give a flush POST a hard ceiling so a hung endpoint never stalls shutdown. */\nconst SEND_TIMEOUT_MS = 4000;\n\n/** One aggregated row of the shared batch — counts only. */\nexport interface StatsRow {\n source: Source;\n client: string;\n tool: string;\n outcome: Outcome;\n calls: number;\n vgTokens: number;\n baselineTokens: number;\n}\n\n/** The counts-only batch POSTed to the ingest endpoint. */\nexport interface StatsBatch {\n schemaVersion: string;\n installId: string;\n vgVersion: string;\n os: string;\n arch: string;\n windowStart: string;\n windowEnd: string;\n totalCalls: number;\n rows: StatsRow[];\n}\n\n/**\n * The universal opt-out (https://consoledonottrack.com) plus a tool-specific\n * alias, honoured even when `--share-stats` is passed explicitly. Pure function\n * of the environment for testability. Returns the name of the variable that\n * opted out (for the disclosure message), or null when sharing may proceed.\n */\nexport function telemetryOptOut(env: NodeJS.ProcessEnv = process.env): string | null {\n const dnt = (env.DO_NOT_TRACK ?? '').trim().toLowerCase();\n if (dnt !== '' && dnt !== '0' && dnt !== 'false') return 'DO_NOT_TRACK';\n const vt = (env.VIBGRATE_TELEMETRY ?? '').trim().toLowerCase();\n if (vt === '0' || vt === 'false' || vt === 'off') return 'VIBGRATE_TELEMETRY';\n return null;\n}\n\n/** Common CI environment markers — a CI runner is never an interactive session. */\nconst CI_ENV_VARS = [\n 'CI',\n 'GITHUB_ACTIONS',\n 'GITLAB_CI',\n 'CIRCLECI',\n 'TRAVIS',\n 'BUILDKITE',\n 'JENKINS_URL',\n 'TF_BUILD',\n] as const;\n\n/** True when running under a recognised CI system. Pure function of the env. */\nexport function isCI(env: NodeJS.ProcessEnv = process.env): boolean {\n return CI_ENV_VARS.some((v) => {\n const val = (env[v] ?? '').trim().toLowerCase();\n return val !== '' && val !== '0' && val !== 'false';\n });\n}\n\n/**\n * Read (or lazily create) the anonymous per-install id — a random UUID stored in\n * `~/.vibgrate/install-id`. It is *not* tied to the user, the repo, or any\n * account; it only lets us de-duplicate batches from the same install when\n * aggregating. If the home dir isn't writable we fall back to an ephemeral id\n * so sharing still works (it just can't be de-duplicated across restarts).\n *\n * Under an env opt-out no id is ever read or persisted (the sharing path isn't\n * reached then either — this is defence in depth), and on CI runners the id is\n * ephemeral: a persisted id on a shared/throwaway runner would be meaningless\n * for de-duplication and would leave state behind on machines we don't own.\n */\nexport function installId(env: NodeJS.ProcessEnv = process.env): string {\n if (telemetryOptOut(env) !== null || isCI(env)) return randomUuid();\n try {\n const existing = fs.readFileSync(INSTALL_ID_FILE, 'utf8').trim();\n if (isUuid(existing)) return existing;\n } catch {\n /* not created yet */\n }\n const id = randomUuid();\n try {\n fs.mkdirSync(INSTALL_ID_DIR, { recursive: true });\n fs.writeFileSync(INSTALL_ID_FILE, id + '\\n', { mode: 0o600 });\n } catch {\n /* home dir read-only — use the ephemeral id for this process */\n }\n return id;\n}\n\nfunction isUuid(s: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s);\n}\n\nfunction randomUuid(): string {\n return randomUUID();\n}\n\n/** Resolve the ingest endpoint: env override wins, else the default region host. */\nexport function statsEndpoint(): string {\n const override = process.env.VIBGRATE_STATS_ENDPOINT;\n if (override && /^https?:\\/\\//.test(override)) return override;\n return `https://${resolveIngestHost()}/v1/ingest/cli-mcp-usage`;\n}\n\nfunction offsetPath(root: string): string {\n return path.join(cacheDir(root), OFFSET_FILE);\n}\n\nfunction ledgerFilePath(root: string): string {\n return path.join(cacheDir(root), 'savings.jsonl');\n}\n\nfunction readOffset(root: string): number {\n try {\n const raw = JSON.parse(fs.readFileSync(offsetPath(root), 'utf8')) as { offset?: number };\n return typeof raw.offset === 'number' && raw.offset >= 0 ? raw.offset : 0;\n } catch {\n return 0;\n }\n}\n\nfunction writeOffset(root: string, offset: number): void {\n try {\n fs.mkdirSync(cacheDir(root), { recursive: true });\n fs.writeFileSync(offsetPath(root), JSON.stringify({ offset }) + '\\n');\n } catch {\n /* best-effort; a lost offset just means one batch may re-send */\n }\n}\n\n/**\n * Aggregate the ledger entries after `fromOffset` into a counts-only batch.\n * Returns the batch (or null if there's nothing new) and the new byte offset to\n * persist once the batch is confirmed sent.\n */\nexport function buildBatch(\n root: string,\n fromOffset: number,\n id = installId(),\n): { batch: StatsBatch | null; newOffset: number } {\n const file = ledgerFilePath(root);\n let size = 0;\n try {\n size = fs.statSync(file).size;\n } catch {\n return { batch: null, newOffset: 0 };\n }\n // The ledger was truncated/recreated under us — re-read from the top.\n const start = fromOffset > size ? 0 : fromOffset;\n if (start >= size) return { batch: null, newOffset: size };\n\n let text = '';\n try {\n const fd = fs.openSync(file, 'r');\n try {\n const buf = Buffer.alloc(size - start);\n fs.readSync(fd, buf, 0, buf.length, start);\n text = buf.toString('utf8');\n } finally {\n fs.closeSync(fd);\n }\n } catch {\n return { batch: null, newOffset: fromOffset };\n }\n\n // Only whole lines are complete; a trailing partial line (mid-append) is left\n // for the next flush by rewinding the offset to the last newline.\n const lastNl = text.lastIndexOf('\\n');\n if (lastNl < 0) return { batch: null, newOffset: start };\n const consumed = start + lastNl + 1;\n const rows = new Map<string, StatsRow>();\n let total = 0;\n let minTs = Infinity;\n let maxTs = -Infinity;\n for (const line of text.slice(0, lastNl).split('\\n')) {\n if (!line.trim()) continue;\n let e: SavingEntry;\n try {\n e = JSON.parse(line) as SavingEntry;\n } catch {\n continue;\n }\n const source: Source = e.source ?? 'mcp';\n const client = e.client ?? 'unknown';\n const outcome: Outcome = e.outcome ?? 'complete';\n const key = `${source}|${client}|${e.tool}|${outcome}`;\n const row = rows.get(key) ?? {\n source,\n client,\n tool: e.tool,\n outcome,\n calls: 0,\n vgTokens: 0,\n baselineTokens: 0,\n };\n row.calls++;\n row.vgTokens += e.vgTokens ?? 0;\n row.baselineTokens += e.baselineTokens ?? 0;\n rows.set(key, row);\n total++;\n if (typeof e.ts === 'number') {\n if (e.ts < minTs) minTs = e.ts;\n if (e.ts > maxTs) maxTs = e.ts;\n }\n }\n if (total === 0 || !Number.isFinite(minTs)) return { batch: null, newOffset: consumed };\n const batch: StatsBatch = {\n schemaVersion: SCHEMA_VERSION,\n installId: id,\n vgVersion: VERSION,\n os: process.platform,\n arch: process.arch,\n windowStart: new Date(minTs).toISOString(),\n windowEnd: new Date(maxTs).toISOString(),\n totalCalls: total,\n rows: [...rows.values()],\n };\n return { batch, newOffset: consumed };\n}\n\n/**\n * POST a batch to the endpoint. Never throws; returns whether it was accepted.\n * A short timeout keeps a hung endpoint from stalling the caller (e.g. shutdown).\n */\nasync function postBatch(batch: StatsBatch): Promise<boolean> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), SEND_TIMEOUT_MS);\n timer.unref?.();\n try {\n const res = await fetch(statsEndpoint(), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Connection: 'close' },\n body: JSON.stringify(batch),\n signal: controller.signal,\n });\n return res.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Periodic + on-shutdown flusher for one serve session. Holds the install id and\n * the persisted offset so each flush reads only new ledger lines and advances the\n * offset only when the batch is confirmed sent.\n */\nexport class StatsSharer {\n private readonly id = installId();\n private offset: number;\n private flushing = false;\n\n constructor(private readonly root: string) {\n this.offset = readOffset(root);\n }\n\n /**\n * Flush any new ledger entries. Single-flight (a slow POST won't overlap the\n * next tick). Best-effort: any failure is swallowed and retried next time.\n */\n async flush(): Promise<void> {\n if (this.flushing) return;\n this.flushing = true;\n try {\n const { batch, newOffset } = buildBatch(this.root, this.offset, this.id);\n if (!batch) {\n // Nothing to send, but still advance past consumed blank/partial space.\n if (newOffset > this.offset) {\n this.offset = newOffset;\n writeOffset(this.root, newOffset);\n }\n return;\n }\n const ok = await postBatch(batch);\n if (ok) {\n this.offset = newOffset;\n writeOffset(this.root, newOffset);\n }\n } catch {\n /* never let sharing break serving */\n } finally {\n this.flushing = false;\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/engine/stats-share.ts"],"names":[],"mappings":";;;;;;;;AAiCA,IAAM,cAAA,GAAiB,GAAA;AAEvB,IAAM,WAAA,GAAc,kBAAA;AAEpB,IAAM,cAAA,GAAsB,IAAA,CAAA,IAAA,CAAQ,EAAA,CAAA,OAAA,EAAQ,EAAG,WAAW,CAAA;AAC1D,IAAM,eAAA,GAAuB,IAAA,CAAA,IAAA,CAAK,cAAA,EAAgB,YAAY,CAAA;AAE9D,IAAM,eAAA,GAAkB,GAAA;AAgCjB,SAAS,eAAA,CAAgB,GAAA,GAAyB,OAAA,CAAQ,GAAA,EAAoB;AACnF,EAAA,MAAM,OAAO,GAAA,CAAI,YAAA,IAAgB,EAAA,EAAI,IAAA,GAAO,WAAA,EAAY;AACxD,EAAA,IAAI,QAAQ,EAAA,IAAM,GAAA,KAAQ,GAAA,IAAO,GAAA,KAAQ,SAAS,OAAO,cAAA;AACzD,EAAA,MAAM,MAAM,GAAA,CAAI,kBAAA,IAAsB,EAAA,EAAI,IAAA,GAAO,WAAA,EAAY;AAC7D,EAAA,IAAI,OAAO,GAAA,IAAO,EAAA,KAAO,OAAA,IAAW,EAAA,KAAO,OAAO,OAAO,oBAAA;AACzD,EAAA,OAAO,IAAA;AACT;AAGA,IAAM,WAAA,GAAc;AAAA,EAClB,IAAA;AAAA,EACA,gBAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAA;AAGO,SAAS,IAAA,CAAK,GAAA,GAAyB,OAAA,CAAQ,GAAA,EAAc;AAClE,EAAA,OAAO,WAAA,CAAY,IAAA,CAAK,CAAC,CAAA,KAAM;AAC7B,IAAA,MAAM,OAAO,GAAA,CAAI,CAAC,KAAK,EAAA,EAAI,IAAA,GAAO,WAAA,EAAY;AAC9C,IAAA,OAAO,GAAA,KAAQ,EAAA,IAAM,GAAA,KAAQ,GAAA,IAAO,GAAA,KAAQ,OAAA;AAAA,EAC9C,CAAC,CAAA;AACH;AAcO,SAAS,SAAA,CAAU,GAAA,GAAyB,OAAA,CAAQ,GAAA,EAAa;AACtE,EAAA,IAAI,eAAA,CAAgB,GAAG,CAAA,KAAM,IAAA,IAAQ,KAAK,GAAG,CAAA,SAAU,UAAA,EAAW;AAClE,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAc,EAAA,CAAA,YAAA,CAAa,eAAA,EAAiB,MAAM,EAAE,IAAA,EAAK;AAC/D,IAAA,IAAI,MAAA,CAAO,QAAQ,CAAA,EAAG,OAAO,QAAA;AAAA,EAC/B,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,MAAM,KAAK,UAAA,EAAW;AACtB,EAAA,IAAI;AACF,IAAG,EAAA,CAAA,SAAA,CAAU,cAAA,EAAgB,EAAE,SAAA,EAAW,MAAM,CAAA;AAChD,IAAG,iBAAc,eAAA,EAAiB,EAAA,GAAK,MAAM,EAAE,IAAA,EAAM,KAAO,CAAA;AAAA,EAC9D,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,EAAA;AACT;AAEA,SAAS,OAAO,CAAA,EAAoB;AAClC,EAAA,OAAO,iEAAA,CAAkE,KAAK,CAAC,CAAA;AACjF;AAEA,SAAS,UAAA,GAAqB;AAC5B,EAAA,OAAO,UAAA,EAAW;AACpB;AAGO,SAAS,aAAA,GAAwB;AACtC,EAAA,MAAM,QAAA,GAAW,QAAQ,GAAA,CAAI,uBAAA;AAC7B,EAAA,IAAI,QAAA,IAAY,cAAA,CAAe,IAAA,CAAK,QAAQ,GAAG,OAAO,QAAA;AACtD,EAAA,OAAO,CAAA,QAAA,EAAW,mBAAmB,CAAA,wBAAA,CAAA;AACvC;AAEA,SAAS,WAAW,IAAA,EAAsB;AACxC,EAAA,OAAY,IAAA,CAAA,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG,WAAW,CAAA;AAC9C;AAEA,SAAS,eAAe,IAAA,EAAsB;AAC5C,EAAA,OAAY,IAAA,CAAA,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG,eAAe,CAAA;AAClD;AAEA,SAAS,WAAW,IAAA,EAAsB;AACxC,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,KAAK,KAAA,CAAS,EAAA,CAAA,YAAA,CAAa,WAAW,IAAI,CAAA,EAAG,MAAM,CAAC,CAAA;AAChE,IAAA,OAAO,OAAO,IAAI,MAAA,KAAW,QAAA,IAAY,IAAI,MAAA,IAAU,CAAA,GAAI,IAAI,MAAA,GAAS,CAAA;AAAA,EAC1E,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,CAAA;AAAA,EACT;AACF;AAEA,SAAS,WAAA,CAAY,MAAc,MAAA,EAAsB;AACvD,EAAA,IAAI;AACF,IAAG,aAAU,QAAA,CAAS,IAAI,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAChD,IAAG,EAAA,CAAA,aAAA,CAAc,UAAA,CAAW,IAAI,CAAA,EAAG,IAAA,CAAK,UAAU,EAAE,MAAA,EAAQ,CAAA,GAAI,IAAI,CAAA;AAAA,EACtE,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAOO,SAAS,UAAA,CACd,IAAA,EACA,UAAA,EACA,EAAA,GAAK,WAAU,EACkC;AACjD,EAAA,MAAM,IAAA,GAAO,eAAe,IAAI,CAAA;AAChC,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,IAAI;AACF,IAAA,IAAA,GAAU,EAAA,CAAA,QAAA,CAAS,IAAI,CAAA,CAAE,IAAA;AAAA,EAC3B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,SAAA,EAAW,CAAA,EAAE;AAAA,EACrC;AAEA,EAAA,MAAM,KAAA,GAAQ,UAAA,GAAa,IAAA,GAAO,CAAA,GAAI,UAAA;AACtC,EAAA,IAAI,SAAS,IAAA,EAAM,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,WAAW,IAAA,EAAK;AAEzD,EAAA,IAAI,IAAA,GAAO,EAAA;AACX,EAAA,IAAI;AACF,IAAA,MAAM,EAAA,GAAQ,EAAA,CAAA,QAAA,CAAS,IAAA,EAAM,GAAG,CAAA;AAChC,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAA,CAAO,KAAA,CAAM,IAAA,GAAO,KAAK,CAAA;AACrC,MAAG,YAAS,EAAA,EAAI,GAAA,EAAK,CAAA,EAAG,GAAA,CAAI,QAAQ,KAAK,CAAA;AACzC,MAAA,IAAA,GAAO,GAAA,CAAI,SAAS,MAAM,CAAA;AAAA,IAC5B,CAAA,SAAE;AACA,MAAG,aAAU,EAAE,CAAA;AAAA,IACjB;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,SAAA,EAAW,UAAA,EAAW;AAAA,EAC9C;AAIA,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,WAAA,CAAY,IAAI,CAAA;AACpC,EAAA,IAAI,SAAS,CAAA,EAAG,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,WAAW,KAAA,EAAM;AACvD,EAAA,MAAM,QAAA,GAAW,QAAQ,MAAA,GAAS,CAAA;AAClC,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAsB;AACvC,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,IAAI,KAAA,GAAQ,QAAA;AACZ,EAAA,IAAI,KAAA,GAAQ,CAAA,QAAA;AACZ,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,KAAA,CAAM,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,CAAM,IAAI,CAAA,EAAG;AACpD,IAAA,IAAI,CAAC,IAAA,CAAK,IAAA,EAAK,EAAG;AAClB,IAAA,IAAI,CAAA;AACJ,IAAA,IAAI;AACF,MAAA,CAAA,GAAI,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AACA,IAAA,MAAM,MAAA,GAAiB,EAAE,MAAA,IAAU,KAAA;AACnC,IAAA,MAAM,MAAA,GAAS,EAAE,MAAA,IAAU,SAAA;AAC3B,IAAA,MAAM,OAAA,GAAmB,EAAE,OAAA,IAAW,UAAA;AACtC,IAAA,MAAM,GAAA,GAAM,GAAG,MAAM,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA,EAAI,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;AACpD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,IAAK;AAAA,MAC3B,MAAA;AAAA,MACA,MAAA;AAAA,MACA,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,OAAA;AAAA,MACA,KAAA,EAAO,CAAA;AAAA,MACP,QAAA,EAAU,CAAA;AAAA,MACV,cAAA,EAAgB;AAAA,KAClB;AACA,IAAA,GAAA,CAAI,KAAA,EAAA;AACJ,IAAA,GAAA,CAAI,QAAA,IAAY,EAAE,QAAA,IAAY,CAAA;AAC9B,IAAA,GAAA,CAAI,cAAA,IAAkB,EAAE,cAAA,IAAkB,CAAA;AAC1C,IAAA,IAAA,CAAK,GAAA,CAAI,KAAK,GAAG,CAAA;AACjB,IAAA,KAAA,EAAA;AACA,IAAA,IAAI,OAAO,CAAA,CAAE,EAAA,KAAO,QAAA,EAAU;AAC5B,MAAA,IAAI,CAAA,CAAE,EAAA,GAAK,KAAA,EAAO,KAAA,GAAQ,CAAA,CAAE,EAAA;AAC5B,MAAA,IAAI,CAAA,CAAE,EAAA,GAAK,KAAA,EAAO,KAAA,GAAQ,CAAA,CAAE,EAAA;AAAA,IAC9B;AAAA,EACF;AACA,EAAA,IAAI,KAAA,KAAU,CAAA,IAAK,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,SAAA,EAAW,QAAA,EAAS;AACtF,EAAA,MAAM,KAAA,GAAoB;AAAA,IACxB,aAAA,EAAe,cAAA;AAAA,IACf,SAAA,EAAW,EAAA;AAAA,IACX,SAAA,EAAW,OAAA;AAAA,IACX,IAAI,OAAA,CAAQ,QAAA;AAAA,IACZ,MAAM,OAAA,CAAQ,IAAA;AAAA,IACd,WAAA,EAAa,IAAI,IAAA,CAAK,KAAK,EAAE,WAAA,EAAY;AAAA,IACzC,SAAA,EAAW,IAAI,IAAA,CAAK,KAAK,EAAE,WAAA,EAAY;AAAA,IACvC,UAAA,EAAY,KAAA;AAAA,IACZ,IAAA,EAAM,CAAC,GAAG,IAAA,CAAK,QAAQ;AAAA,GACzB;AACA,EAAA,OAAO,EAAE,KAAA,EAAO,SAAA,EAAW,QAAA,EAAS;AACtC;AAMA,eAAe,UAAU,KAAA,EAAqC;AAC5D,EAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,EAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,eAAe,CAAA;AAClE,EAAA,KAAA,CAAM,KAAA,IAAQ;AACd,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,aAAA,EAAc,EAAG;AAAA,MACvC,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAoB,YAAY,OAAA,EAAQ;AAAA,MACnE,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AAAA,MAC1B,QAAQ,UAAA,CAAW;AAAA,KACpB,CAAA;AACD,IAAA,OAAO,GAAA,CAAI,EAAA;AAAA,EACb,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT,CAAA,SAAE;AACA,IAAA,YAAA,CAAa,KAAK,CAAA;AAAA,EACpB;AACF;AAOO,IAAM,cAAN,MAAkB;AAAA,EAKvB,YAA6B,IAAA,EAAc;AAAd,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAC3B,IAAA,IAAA,CAAK,MAAA,GAAS,WAAW,IAAI,CAAA;AAAA,EAC/B;AAAA,EAF6B,IAAA;AAAA,EAJZ,KAAK,SAAA,EAAU;AAAA,EACxB,MAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUnB,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAI,KAAK,QAAA,EAAU;AACnB,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAU,GAAI,UAAA,CAAW,KAAK,IAAA,EAAM,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,EAAE,CAAA;AACvE,MAAA,IAAI,CAAC,KAAA,EAAO;AAEV,QAAA,IAAI,SAAA,GAAY,KAAK,MAAA,EAAQ;AAC3B,UAAA,IAAA,CAAK,MAAA,GAAS,SAAA;AACd,UAAA,WAAA,CAAY,IAAA,CAAK,MAAM,SAAS,CAAA;AAAA,QAClC;AACA,QAAA;AAAA,MACF;AACA,MAAA,MAAM,EAAA,GAAK,MAAM,SAAA,CAAU,KAAK,CAAA;AAChC,MAAA,IAAI,EAAA,EAAI;AACN,QAAA,IAAA,CAAK,MAAA,GAAS,SAAA;AACd,QAAA,WAAA,CAAY,IAAA,CAAK,MAAM,SAAS,CAAA;AAAA,MAClC;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,QAAA,GAAW,KAAA;AAAA,IAClB;AAAA,EACF;AACF","file":"chunk-KF2QT6RY.js","sourcesContent":["import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport { cacheDir } from './cache.js';\nimport { VERSION } from '../version.js';\nimport { resolveIngestHost } from '../reporting/regions.js';\nimport type { SavingEntry, Source, Outcome } from './savings.js';\n\n/**\n * Opt-in usage-stats sharing for `vg serve --share-stats`.\n *\n * This is the ONLY path in `vg serve` that sends anything off the machine, and\n * it is off unless the operator explicitly asks for it. What we send is the\n * same counts-only ledger `vg savings` reports locally — per (source, client,\n * tool, outcome): how many calls and the vg-vs-grep token figures — plus the vg\n * version, OS/arch, and a random per-install id. We never send code, file paths,\n * question text, repo identity, or any credential. See GUARDRAILS §3.4.\n *\n * Even when the flag is passed, the universal `DO_NOT_TRACK` opt-out (or\n * `VIBGRATE_TELEMETRY=0`) wins: nothing is uploaded and no install id is ever\n * minted or persisted (see `telemetryOptOut` / `installId`).\n *\n * Design:\n * - The local ledger (savings.jsonl) is the single source of truth; the flusher\n * reads only the tail past a persisted byte offset, so a batch is sent once.\n * - Fire-and-forget with a short timeout. A network problem never blocks a tool\n * call and never throws — the offset only advances on a confirmed 2xx, so a\n * failed batch is retried on the next flush.\n * - Fully offline-safe: under `--local` the sharer is never constructed.\n */\n\n/** Payload schema version — must match the server's `mcpUsageStatsSchema`. */\nconst SCHEMA_VERSION = '1';\n/** Where the offset (and cached install id) live, per repo, beside the ledger. */\nconst OFFSET_FILE = 'stats-share.json';\n/** The machine-global anonymous install id lives here (stable across repos). */\nconst INSTALL_ID_DIR = path.join(os.homedir(), '.vibgrate');\nconst INSTALL_ID_FILE = path.join(INSTALL_ID_DIR, 'install-id');\n/** Give a flush POST a hard ceiling so a hung endpoint never stalls shutdown. */\nconst SEND_TIMEOUT_MS = 4000;\n\n/** One aggregated row of the shared batch — counts only. */\nexport interface StatsRow {\n source: Source;\n client: string;\n tool: string;\n outcome: Outcome;\n calls: number;\n vgTokens: number;\n baselineTokens: number;\n}\n\n/** The counts-only batch POSTed to the ingest endpoint. */\nexport interface StatsBatch {\n schemaVersion: string;\n installId: string;\n vgVersion: string;\n os: string;\n arch: string;\n windowStart: string;\n windowEnd: string;\n totalCalls: number;\n rows: StatsRow[];\n}\n\n/**\n * The universal opt-out (https://consoledonottrack.com) plus a tool-specific\n * alias, honoured even when `--share-stats` is passed explicitly. Pure function\n * of the environment for testability. Returns the name of the variable that\n * opted out (for the disclosure message), or null when sharing may proceed.\n */\nexport function telemetryOptOut(env: NodeJS.ProcessEnv = process.env): string | null {\n const dnt = (env.DO_NOT_TRACK ?? '').trim().toLowerCase();\n if (dnt !== '' && dnt !== '0' && dnt !== 'false') return 'DO_NOT_TRACK';\n const vt = (env.VIBGRATE_TELEMETRY ?? '').trim().toLowerCase();\n if (vt === '0' || vt === 'false' || vt === 'off') return 'VIBGRATE_TELEMETRY';\n return null;\n}\n\n/** Common CI environment markers — a CI runner is never an interactive session. */\nconst CI_ENV_VARS = [\n 'CI',\n 'GITHUB_ACTIONS',\n 'GITLAB_CI',\n 'CIRCLECI',\n 'TRAVIS',\n 'BUILDKITE',\n 'JENKINS_URL',\n 'TF_BUILD',\n] as const;\n\n/** True when running under a recognised CI system. Pure function of the env. */\nexport function isCI(env: NodeJS.ProcessEnv = process.env): boolean {\n return CI_ENV_VARS.some((v) => {\n const val = (env[v] ?? '').trim().toLowerCase();\n return val !== '' && val !== '0' && val !== 'false';\n });\n}\n\n/**\n * Read (or lazily create) the anonymous per-install id — a random UUID stored in\n * `~/.vibgrate/install-id`. It is *not* tied to the user, the repo, or any\n * account; it only lets us de-duplicate batches from the same install when\n * aggregating. If the home dir isn't writable we fall back to an ephemeral id\n * so sharing still works (it just can't be de-duplicated across restarts).\n *\n * Under an env opt-out no id is ever read or persisted (the sharing path isn't\n * reached then either — this is defence in depth), and on CI runners the id is\n * ephemeral: a persisted id on a shared/throwaway runner would be meaningless\n * for de-duplication and would leave state behind on machines we don't own.\n */\nexport function installId(env: NodeJS.ProcessEnv = process.env): string {\n if (telemetryOptOut(env) !== null || isCI(env)) return randomUuid();\n try {\n const existing = fs.readFileSync(INSTALL_ID_FILE, 'utf8').trim();\n if (isUuid(existing)) return existing;\n } catch {\n /* not created yet */\n }\n const id = randomUuid();\n try {\n fs.mkdirSync(INSTALL_ID_DIR, { recursive: true });\n fs.writeFileSync(INSTALL_ID_FILE, id + '\\n', { mode: 0o600 });\n } catch {\n /* home dir read-only — use the ephemeral id for this process */\n }\n return id;\n}\n\nfunction isUuid(s: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s);\n}\n\nfunction randomUuid(): string {\n return randomUUID();\n}\n\n/** Resolve the ingest endpoint: env override wins, else the default region host. */\nexport function statsEndpoint(): string {\n const override = process.env.VIBGRATE_STATS_ENDPOINT;\n if (override && /^https?:\\/\\//.test(override)) return override;\n return `https://${resolveIngestHost()}/v1/ingest/cli-mcp-usage`;\n}\n\nfunction offsetPath(root: string): string {\n return path.join(cacheDir(root), OFFSET_FILE);\n}\n\nfunction ledgerFilePath(root: string): string {\n return path.join(cacheDir(root), 'savings.jsonl');\n}\n\nfunction readOffset(root: string): number {\n try {\n const raw = JSON.parse(fs.readFileSync(offsetPath(root), 'utf8')) as { offset?: number };\n return typeof raw.offset === 'number' && raw.offset >= 0 ? raw.offset : 0;\n } catch {\n return 0;\n }\n}\n\nfunction writeOffset(root: string, offset: number): void {\n try {\n fs.mkdirSync(cacheDir(root), { recursive: true });\n fs.writeFileSync(offsetPath(root), JSON.stringify({ offset }) + '\\n');\n } catch {\n /* best-effort; a lost offset just means one batch may re-send */\n }\n}\n\n/**\n * Aggregate the ledger entries after `fromOffset` into a counts-only batch.\n * Returns the batch (or null if there's nothing new) and the new byte offset to\n * persist once the batch is confirmed sent.\n */\nexport function buildBatch(\n root: string,\n fromOffset: number,\n id = installId(),\n): { batch: StatsBatch | null; newOffset: number } {\n const file = ledgerFilePath(root);\n let size = 0;\n try {\n size = fs.statSync(file).size;\n } catch {\n return { batch: null, newOffset: 0 };\n }\n // The ledger was truncated/recreated under us — re-read from the top.\n const start = fromOffset > size ? 0 : fromOffset;\n if (start >= size) return { batch: null, newOffset: size };\n\n let text = '';\n try {\n const fd = fs.openSync(file, 'r');\n try {\n const buf = Buffer.alloc(size - start);\n fs.readSync(fd, buf, 0, buf.length, start);\n text = buf.toString('utf8');\n } finally {\n fs.closeSync(fd);\n }\n } catch {\n return { batch: null, newOffset: fromOffset };\n }\n\n // Only whole lines are complete; a trailing partial line (mid-append) is left\n // for the next flush by rewinding the offset to the last newline.\n const lastNl = text.lastIndexOf('\\n');\n if (lastNl < 0) return { batch: null, newOffset: start };\n const consumed = start + lastNl + 1;\n const rows = new Map<string, StatsRow>();\n let total = 0;\n let minTs = Infinity;\n let maxTs = -Infinity;\n for (const line of text.slice(0, lastNl).split('\\n')) {\n if (!line.trim()) continue;\n let e: SavingEntry;\n try {\n e = JSON.parse(line) as SavingEntry;\n } catch {\n continue;\n }\n const source: Source = e.source ?? 'mcp';\n const client = e.client ?? 'unknown';\n const outcome: Outcome = e.outcome ?? 'complete';\n const key = `${source}|${client}|${e.tool}|${outcome}`;\n const row = rows.get(key) ?? {\n source,\n client,\n tool: e.tool,\n outcome,\n calls: 0,\n vgTokens: 0,\n baselineTokens: 0,\n };\n row.calls++;\n row.vgTokens += e.vgTokens ?? 0;\n row.baselineTokens += e.baselineTokens ?? 0;\n rows.set(key, row);\n total++;\n if (typeof e.ts === 'number') {\n if (e.ts < minTs) minTs = e.ts;\n if (e.ts > maxTs) maxTs = e.ts;\n }\n }\n if (total === 0 || !Number.isFinite(minTs)) return { batch: null, newOffset: consumed };\n const batch: StatsBatch = {\n schemaVersion: SCHEMA_VERSION,\n installId: id,\n vgVersion: VERSION,\n os: process.platform,\n arch: process.arch,\n windowStart: new Date(minTs).toISOString(),\n windowEnd: new Date(maxTs).toISOString(),\n totalCalls: total,\n rows: [...rows.values()],\n };\n return { batch, newOffset: consumed };\n}\n\n/**\n * POST a batch to the endpoint. Never throws; returns whether it was accepted.\n * A short timeout keeps a hung endpoint from stalling the caller (e.g. shutdown).\n */\nasync function postBatch(batch: StatsBatch): Promise<boolean> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), SEND_TIMEOUT_MS);\n timer.unref?.();\n try {\n const res = await fetch(statsEndpoint(), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Connection: 'close' },\n body: JSON.stringify(batch),\n signal: controller.signal,\n });\n return res.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Periodic + on-shutdown flusher for one serve session. Holds the install id and\n * the persisted offset so each flush reads only new ledger lines and advances the\n * offset only when the batch is confirmed sent.\n */\nexport class StatsSharer {\n private readonly id = installId();\n private offset: number;\n private flushing = false;\n\n constructor(private readonly root: string) {\n this.offset = readOffset(root);\n }\n\n /**\n * Flush any new ledger entries. Single-flight (a slow POST won't overlap the\n * next tick). Best-effort: any failure is swallowed and retried next time.\n */\n async flush(): Promise<void> {\n if (this.flushing) return;\n this.flushing = true;\n try {\n const { batch, newOffset } = buildBatch(this.root, this.offset, this.id);\n if (!batch) {\n // Nothing to send, but still advance past consumed blank/partial space.\n if (newOffset > this.offset) {\n this.offset = newOffset;\n writeOffset(this.root, newOffset);\n }\n return;\n }\n const ok = await postBatch(batch);\n if (ok) {\n this.offset = newOffset;\n writeOffset(this.root, newOffset);\n }\n } catch {\n /* never let sharing break serving */\n } finally {\n this.flushing = false;\n }\n }\n}\n"]}
@@ -10603,6 +10603,12 @@ async function runCoreScan(rootDir, opts, advanced) {
10603
10603
  const OVERLAY_PROJECT_TYPES = /* @__PURE__ */ new Set(["docker", "helm", "terraform"]);
10604
10604
  const dedupeKey = (p) => OVERLAY_PROJECT_TYPES.has(p.type) ? `${p.type}:${p.path}` : p.path;
10605
10605
  const rawProjects = [...nodeProjects, ...dotnetProjects, ...pythonProjects, ...javaProjects, ...rubyProjects, ...swiftProjects, ...goProjects, ...rustProjects, ...phpProjects, ...dartProjects, ...elixirProjects, ...dockerProjects, ...helmProjects, ...terraformProjects, ...polyglotProjects];
10606
+ for (const project of rawProjects) {
10607
+ project.path = project.path.replace(/\\/g, "/");
10608
+ for (const ref of project.projectReferences ?? []) {
10609
+ ref.path = ref.path.replace(/\\/g, "/");
10610
+ }
10611
+ }
10606
10612
  const deduplicatedMap = /* @__PURE__ */ new Map();
10607
10613
  for (const project of rawProjects) {
10608
10614
  const existing = deduplicatedMap.get(dedupeKey(project));
@@ -11556,6 +11562,9 @@ async function fetchScanPreflight(parsed, ingestHost, options) {
11556
11562
  if (options?.vcsSha) {
11557
11563
  url.searchParams.set("vcsSha", options.vcsSha);
11558
11564
  }
11565
+ if (options?.remoteUrl) {
11566
+ url.searchParams.set("remoteUrl", options.remoteUrl);
11567
+ }
11559
11568
  const timestamp = String(Date.now());
11560
11569
  const response = await fetch(url.toString(), {
11561
11570
  method: "GET",
@@ -11688,5 +11697,5 @@ async function computeTreeMetadataHash(rootDir, options) {
11688
11697
  }
11689
11698
 
11690
11699
  export { PROJECT_TYPE_TO_OSV_ECOSYSTEM, brandProgressBar, buildVersionTimelines, compactUiPurpose, computeDriftScore, computeRepoFingerprint, computeUpgradeImpact, detectVcs, driftBar, fetchRiskySymbols, fetchScanPreflight, findPackageAnyEcosystem, findPackageTimeline, findVersionCrossings, getChangelogSignals, gitHistoryAvailable, loadConfig, normalizeConstraint, parseDsn, perDependencyDrift, prepareCompressedUpload, projectTypeToVulnEcosystem, resolveHead, resolveRepositoryName, runCoreScan, severityRank, titleBox, versionSatisfies, workingTreeDirty, writeDefaultConfig };
11691
- //# sourceMappingURL=chunk-INIULQEP.js.map
11692
- //# sourceMappingURL=chunk-INIULQEP.js.map
11700
+ //# sourceMappingURL=chunk-N6ZMZ5AI.js.map
11701
+ //# sourceMappingURL=chunk-N6ZMZ5AI.js.map