@vibgrate/cli 2026.807.1 → 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.
- package/dist/{agent-K3J6EHLI.js → agent-N3CP3SPI.js} +10 -10
- package/dist/{agent-K3J6EHLI.js.map → agent-N3CP3SPI.js.map} +1 -1
- package/dist/baseline-ZMRZRGFI.js +9 -0
- package/dist/{baseline-IAFWF2ET.js.map → baseline-ZMRZRGFI.js.map} +1 -1
- package/dist/{chunk-5ESL76CM.js → chunk-3WUTQYRY.js} +7 -7
- package/dist/{chunk-5ESL76CM.js.map → chunk-3WUTQYRY.js.map} +1 -1
- package/dist/{chunk-NWX4VUFS.js → chunk-5JJBGBP2.js} +8 -8
- package/dist/{chunk-NWX4VUFS.js.map → chunk-5JJBGBP2.js.map} +1 -1
- package/dist/{chunk-Y4JO6LYP.js → chunk-5ROZODMW.js} +302 -11
- package/dist/chunk-5ROZODMW.js.map +1 -0
- package/dist/{chunk-G4KO5W6H.js → chunk-6423BHLN.js} +7 -7
- package/dist/{chunk-G4KO5W6H.js.map → chunk-6423BHLN.js.map} +1 -1
- package/dist/{chunk-GQ2EQXBG.js → chunk-6GQLEDVK.js} +5 -5
- package/dist/{chunk-GQ2EQXBG.js.map → chunk-6GQLEDVK.js.map} +1 -1
- package/dist/{chunk-JFCCJWXD.js → chunk-7ZHSSGUF.js} +3 -3
- package/dist/{chunk-JFCCJWXD.js.map → chunk-7ZHSSGUF.js.map} +1 -1
- package/dist/{chunk-FOKURZL3.js → chunk-CJNWHXQD.js} +12 -10
- package/dist/chunk-CJNWHXQD.js.map +1 -0
- package/dist/{chunk-2M6B5V2U.js → chunk-EWZKOU66.js} +3 -3
- package/dist/{chunk-2M6B5V2U.js.map → chunk-EWZKOU66.js.map} +1 -1
- package/dist/{chunk-EJUMV5HU.js → chunk-FBVKQXBH.js} +3 -3
- package/dist/{chunk-EJUMV5HU.js.map → chunk-FBVKQXBH.js.map} +1 -1
- package/dist/{chunk-EXOYSXH6.js → chunk-GOPANQZT.js} +3 -3
- package/dist/{chunk-EXOYSXH6.js.map → chunk-GOPANQZT.js.map} +1 -1
- package/dist/{chunk-VNAOFA6X.js → chunk-IJQOZ6ZD.js} +8 -8
- package/dist/{chunk-VNAOFA6X.js.map → chunk-IJQOZ6ZD.js.map} +1 -1
- package/dist/{chunk-2HAJCW7Z.js → chunk-JYM4QT6F.js} +4 -4
- package/dist/{chunk-2HAJCW7Z.js.map → chunk-JYM4QT6F.js.map} +1 -1
- package/dist/{chunk-LS7GZBKP.js → chunk-KBP7GJV6.js} +3 -3
- package/dist/{chunk-LS7GZBKP.js.map → chunk-KBP7GJV6.js.map} +1 -1
- package/dist/{chunk-XSHGXGVJ.js → chunk-KF2QT6RY.js} +4 -4
- package/dist/{chunk-XSHGXGVJ.js.map → chunk-KF2QT6RY.js.map} +1 -1
- package/dist/{chunk-INIULQEP.js → chunk-N6ZMZ5AI.js} +11 -2
- package/dist/chunk-N6ZMZ5AI.js.map +1 -0
- package/dist/{chunk-N5EP5ZR2.js → chunk-OYHAF2J2.js} +4 -4
- package/dist/{chunk-N5EP5ZR2.js.map → chunk-OYHAF2J2.js.map} +1 -1
- package/dist/{chunk-VQVLY63G.js → chunk-RHKJPTON.js} +13 -12
- package/dist/chunk-RHKJPTON.js.map +1 -0
- package/dist/chunk-RT7P5AYU.js +6 -0
- package/dist/{chunk-ITY2NPIQ.js.map → chunk-RT7P5AYU.js.map} +1 -1
- package/dist/{chunk-QXIWQ2WG.js → chunk-UZP623Y4.js} +4 -4
- package/dist/{chunk-QXIWQ2WG.js.map → chunk-UZP623Y4.js.map} +1 -1
- package/dist/{chunk-7CYFCSY2.js → chunk-YJU7S7N6.js} +24 -6
- package/dist/chunk-YJU7S7N6.js.map +1 -0
- package/dist/{chunk-PT2XQTSK.js → chunk-Z3AYOZ3C.js} +6 -5
- package/dist/chunk-Z3AYOZ3C.js.map +1 -0
- package/dist/{chunk-KEIMMCS5.js → chunk-Z3MUWXP3.js} +4 -4
- package/dist/{chunk-KEIMMCS5.js.map → chunk-Z3MUWXP3.js.map} +1 -1
- package/dist/cli.js +93 -66
- package/dist/cli.js.map +1 -1
- package/dist/embed-worker-main.js +3 -3
- package/dist/{ensure-map-TYMYYIJE.js → ensure-map-PHAJACFF.js} +13 -13
- package/dist/{ensure-map-TYMYYIJE.js.map → ensure-map-PHAJACFF.js.map} +1 -1
- package/dist/graph-backend-4B3MTVIW.js +13 -0
- package/dist/{graph-backend-5YOWNHHG.js.map → graph-backend-4B3MTVIW.js.map} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +12 -12
- package/dist/{interactive-YEMXHGBO.js → interactive-WUXMXFNM.js} +22 -22
- package/dist/{interactive-YEMXHGBO.js.map → interactive-WUXMXFNM.js.map} +1 -1
- package/dist/load-EUZSV73H.js +9 -0
- package/dist/{load-IIWVYUN7.js.map → load-EUZSV73H.js.map} +1 -1
- package/dist/{run-outcome-2JO55QCC.js → run-outcome-O5PR7ZCK.js} +5 -5
- package/dist/{run-outcome-2JO55QCC.js.map → run-outcome-O5PR7ZCK.js.map} +1 -1
- package/dist/runtime-session-PPQDTFIK.js +20 -0
- package/dist/{runtime-session-HFKGKQV7.js.map → runtime-session-PPQDTFIK.js.map} +1 -1
- package/dist/{session-5LFX4U2E.js → session-WS7SOVJE.js} +8 -8
- package/dist/{session-5LFX4U2E.js.map → session-WS7SOVJE.js.map} +1 -1
- package/dist/{stream-json-DUCFTBUF.js → stream-json-7MK3QQYG.js} +10 -10
- package/dist/{stream-json-DUCFTBUF.js.map → stream-json-7MK3QQYG.js.map} +1 -1
- package/dist/{vg-mcp-bridge-4KPDQUFN.js → vg-mcp-bridge-DQLCHBI6.js} +9 -9
- package/dist/{vg-mcp-bridge-4KPDQUFN.js.map → vg-mcp-bridge-DQLCHBI6.js.map} +1 -1
- package/dist/{vgd-LFHQ4GWC.js → vgd-Y25XSQGZ.js} +8 -8
- package/dist/vgd-Y25XSQGZ.js.map +1 -0
- package/package.json +6 -6
- package/dist/baseline-IAFWF2ET.js +0 -9
- package/dist/chunk-7CYFCSY2.js.map +0 -1
- package/dist/chunk-FOKURZL3.js.map +0 -1
- package/dist/chunk-INIULQEP.js.map +0 -1
- package/dist/chunk-ITY2NPIQ.js +0 -6
- package/dist/chunk-PT2XQTSK.js.map +0 -1
- package/dist/chunk-VQVLY63G.js.map +0 -1
- package/dist/chunk-Y4JO6LYP.js.map +0 -1
- package/dist/graph-backend-5YOWNHHG.js +0 -13
- package/dist/load-IIWVYUN7.js +0 -9
- package/dist/runtime-session-HFKGKQV7.js +0 -20
- package/dist/vgd-LFHQ4GWC.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { probeFreshness, hasDrift, buildGraph, writeSnapshot } from './chunk-
|
|
2
|
-
import { acquireLock, releaseLock } from './chunk-
|
|
3
|
-
import { vibgrateDir, writeArtifacts, cacheDir } from './chunk-
|
|
1
|
+
import { probeFreshness, hasDrift, buildGraph, writeSnapshot } from './chunk-6423BHLN.js';
|
|
2
|
+
import { acquireLock, releaseLock } from './chunk-KBP7GJV6.js';
|
|
3
|
+
import { vibgrateDir, writeArtifacts, cacheDir } from './chunk-EWZKOU66.js';
|
|
4
4
|
import * as fs from 'fs';
|
|
5
5
|
import * as path from 'path';
|
|
6
6
|
|
|
@@ -60,5 +60,5 @@ async function refreshIfStale(root, opts = {}) {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
export { refreshIfStale };
|
|
63
|
-
//# sourceMappingURL=chunk-
|
|
64
|
-
//# sourceMappingURL=chunk-
|
|
63
|
+
//# sourceMappingURL=chunk-6GQLEDVK.js.map
|
|
64
|
+
//# sourceMappingURL=chunk-6GQLEDVK.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/engine/refresh.ts"],"names":[],"mappings":";;;;;;AAsDA,IAAM,qBAAA,GAAwB,KAAK,EAAA,GAAK,GAAA;AAExC,SAAS,gBAAgB,IAAA,EAAsB;AAC7C,EAAA,OAAY,IAAA,CAAA,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG,cAAc,CAAA;AACjD;AAMA,eAAsB,cAAA,CAAe,IAAA,EAAc,IAAA,GAAuB,EAAC,EAA4B;AACrG,EAAA,MAAM,KAAA,GAAQ,eAAe,IAAI,CAAA;AACjC,EAAA,IAAI,CAAC,KAAA,EAAO,OAAO,EAAE,QAAQ,aAAA,EAAc;AAC3C,EAAA,IAAI,CAAC,SAAS,KAAA,CAAM,KAAK,GAAG,OAAO,EAAE,QAAQ,OAAA,EAAQ;AAErD,EAAA,MAAM,IAAA,GAAO,gBAAgB,IAAI,CAAA;AACjC,EAAA,IAAI,CAAC,YAAY,IAAA,EAAM,qBAAqB,GAAG,OAAO,EAAE,QAAQ,QAAA,EAAS;AAEzE,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,MAAA,CAAO,MAAA,EAAO;AACpC,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,OAAM,GAAI,KAAA;AAClB,IAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW;AAAA,MAC9B,IAAA;AAAA,MACA,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,OAAO,KAAA,CAAM,KAAA;AAAA,MACb,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,UAAU,KAAA,CAAM,QAAA;AAAA,MAChB,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,OAAO,KAAA,CAAM,KAAA;AAAA,MACb,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,aAAa,KAAA,CAAM,WAAA;AAAA,MACnB,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,MAAM,IAAA,CAAK;AAAA,KACZ,CAAA;AAED,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,UAAA,CAAW,eAAe,KAAA,CAAM,UAAA;AAC3D,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,MAAM,GAAA,GAAM,YAAY,IAAI,CAAA;AAC5B,MAAA,cAAA,CAAe,OAAO,KAAA,EAAO;AAAA,QAC3B,IAAA;AAAA,QACA,WAAW,IAAA,CAAK,SAAA;AAAA,QAChB,MAAA,EAAW,EAAA,CAAA,UAAA,CAAgB,IAAA,CAAA,IAAA,CAAK,GAAA,EAAK,iBAAiB,CAAC,CAAA;AAAA,QACvD,IAAA,EAAS,EAAA,CAAA,UAAA,CAAgB,IAAA,CAAA,IAAA,CAAK,GAAA,EAAK,YAAY,CAAC;AAAA,OACjD,CAAA;AAAA,IACH;AACA,IAAA,aAAA,CAAc,MAAM,MAAA,CAAO,KAAA,CAAM,WAAW,UAAA,EAAY,MAAA,CAAO,WAAW,KAAK,CAAA;AAE/E,IAAA,MAAM,KAAK,MAAA,CAAA,CAAQ,OAAA,CAAQ,OAAO,MAAA,EAAO,GAAI,SAAS,QAAQ,CAAA;AAC9D,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,WAAA;AAAA,MACR,OAAO,KAAA,CAAM,KAAA;AAAA,MACb,EAAA;AAAA,MACA,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,YAAY,MAAA,CAAO,UAAA;AAAA,MACnB;AAAA,KACF;AAAA,EACF,SAAS,GAAA,EAAK;AACZ,IAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,OAAA,EAAU,IAAc,OAAA,EAAQ;AAAA,EAC5D,CAAA,SAAE;AACA,IAAA,WAAA,CAAY,IAAI,CAAA;AAAA,EAClB;AACF","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/engine/refresh.ts"],"names":[],"mappings":";;;;;;AAsDA,IAAM,qBAAA,GAAwB,KAAK,EAAA,GAAK,GAAA;AAExC,SAAS,gBAAgB,IAAA,EAAsB;AAC7C,EAAA,OAAY,IAAA,CAAA,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG,cAAc,CAAA;AACjD;AAMA,eAAsB,cAAA,CAAe,IAAA,EAAc,IAAA,GAAuB,EAAC,EAA4B;AACrG,EAAA,MAAM,KAAA,GAAQ,eAAe,IAAI,CAAA;AACjC,EAAA,IAAI,CAAC,KAAA,EAAO,OAAO,EAAE,QAAQ,aAAA,EAAc;AAC3C,EAAA,IAAI,CAAC,SAAS,KAAA,CAAM,KAAK,GAAG,OAAO,EAAE,QAAQ,OAAA,EAAQ;AAErD,EAAA,MAAM,IAAA,GAAO,gBAAgB,IAAI,CAAA;AACjC,EAAA,IAAI,CAAC,YAAY,IAAA,EAAM,qBAAqB,GAAG,OAAO,EAAE,QAAQ,QAAA,EAAS;AAEzE,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,MAAA,CAAO,MAAA,EAAO;AACpC,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,OAAM,GAAI,KAAA;AAClB,IAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW;AAAA,MAC9B,IAAA;AAAA,MACA,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,OAAO,KAAA,CAAM,KAAA;AAAA,MACb,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,UAAU,KAAA,CAAM,QAAA;AAAA,MAChB,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,OAAO,KAAA,CAAM,KAAA;AAAA,MACb,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,aAAa,KAAA,CAAM,WAAA;AAAA,MACnB,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,MAAM,IAAA,CAAK;AAAA,KACZ,CAAA;AAED,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,UAAA,CAAW,eAAe,KAAA,CAAM,UAAA;AAC3D,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,MAAM,GAAA,GAAM,YAAY,IAAI,CAAA;AAC5B,MAAA,cAAA,CAAe,OAAO,KAAA,EAAO;AAAA,QAC3B,IAAA;AAAA,QACA,WAAW,IAAA,CAAK,SAAA;AAAA,QAChB,MAAA,EAAW,EAAA,CAAA,UAAA,CAAgB,IAAA,CAAA,IAAA,CAAK,GAAA,EAAK,iBAAiB,CAAC,CAAA;AAAA,QACvD,IAAA,EAAS,EAAA,CAAA,UAAA,CAAgB,IAAA,CAAA,IAAA,CAAK,GAAA,EAAK,YAAY,CAAC;AAAA,OACjD,CAAA;AAAA,IACH;AACA,IAAA,aAAA,CAAc,MAAM,MAAA,CAAO,KAAA,CAAM,WAAW,UAAA,EAAY,MAAA,CAAO,WAAW,KAAK,CAAA;AAE/E,IAAA,MAAM,KAAK,MAAA,CAAA,CAAQ,OAAA,CAAQ,OAAO,MAAA,EAAO,GAAI,SAAS,QAAQ,CAAA;AAC9D,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,WAAA;AAAA,MACR,OAAO,KAAA,CAAM,KAAA;AAAA,MACb,EAAA;AAAA,MACA,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,YAAY,MAAA,CAAO,UAAA;AAAA,MACnB;AAAA,KACF;AAAA,EACF,SAAS,GAAA,EAAK;AACZ,IAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,OAAA,EAAU,IAAc,OAAA,EAAQ;AAAA,EAC5D,CAAA,SAAE;AACA,IAAA,WAAA,CAAY,IAAI,CAAA;AAAA,EAClB;AACF","file":"chunk-6GQLEDVK.js","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { buildGraph } from './build.js';\nimport { probeFreshness, writeSnapshot, hasDrift, type Drift } from './freshness.js';\nimport { writeArtifacts, vibgrateDir } from './artifacts.js';\nimport { acquireLock, releaseLock } from './lock.js';\nimport { cacheDir } from './cache.js';\nimport type { ClusterMode } from './analyze.js';\n\n/**\n * Auto-refresh: bring the code map back in sync with the working tree when the\n * freshness probe says it drifted. The rebuild is the ordinary incremental\n * `buildGraph` (warm parse cache → only changed files re-parse), replaying the\n * scope recorded at the last explicit build, guarded by a cross-process lock\n * so a serving MCP process and a foreground command never write at once.\n *\n * Two properties keep this safe to run implicitly:\n * - **No git churn**: if the rebuilt corpusHash equals the snapshot's (e.g. a\n * drift that reverted itself), `graph.json` is left untouched — the artifact\n * stays byte-identical.\n * - **No surprise artifacts**: `GRAPH_REPORT.md`/`graph.html` are rewritten\n * only if they already exist; a refresh never adds files a user's explicit\n * build chose not to produce.\n */\n\nexport interface RefreshOptions {\n /** Force single-threaded parsing (tests / constrained hosts). */\n inline?: boolean;\n /** Worker count for the parse pool. */\n jobs?: number;\n /**\n * The map path already resolved by the caller (e.g. `vg serve`'s startup\n * resolution). Passed straight through to `writeArtifacts` so a refresh\n * never re-resolves it: `defaultGraphPath` shells out to `git rev-parse`\n * (Fusion §4.1.1 branch keying), and re-running that on every drift-driven\n * refresh put a synchronous git spawn back on the hot tool-call path this\n * function exists to keep off of. Omit only when no caller-known path\n * exists (falls back to a fresh `defaultGraphPath` resolution).\n */\n graphPath?: string;\n}\n\nexport type RefreshOutcome =\n /** Map already matches the working tree. */\n | { status: 'fresh' }\n /** No freshness snapshot — no build ever ran here, so scope is unknown. */\n | { status: 'no-snapshot' }\n /** Another vg process is rebuilding right now; its write will land shortly. */\n | { status: 'locked' }\n /** Rebuilt. `wrote` is false when the corpus turned out unchanged. */\n | { status: 'refreshed'; drift: Drift; ms: number; reparsed: number; totalFiles: number; wrote: boolean }\n | { status: 'error'; message: string };\n\n/** A refresh stuck longer than this is presumed crashed and its lock reclaimed. */\nconst REFRESH_LOCK_STALE_MS = 10 * 60 * 1000;\n\nfunction refreshLockPath(root: string): string {\n return path.join(cacheDir(root), 'refresh.lock');\n}\n\n/**\n * Probe, and rebuild incrementally if the tree drifted from the map.\n * Silent (no output) — callers own the messaging for their surface.\n */\nexport async function refreshIfStale(root: string, opts: RefreshOptions = {}): Promise<RefreshOutcome> {\n const probe = probeFreshness(root);\n if (!probe) return { status: 'no-snapshot' };\n if (!hasDrift(probe.drift)) return { status: 'fresh' };\n\n const lock = refreshLockPath(root);\n if (!acquireLock(lock, REFRESH_LOCK_STALE_MS)) return { status: 'locked' };\n\n const start = process.hrtime.bigint();\n try {\n const { scope } = probe;\n const result = await buildGraph({\n root,\n only: scope.only,\n exclude: scope.exclude,\n paths: scope.paths,\n deep: scope.deep,\n noGround: scope.noGround,\n scip: scope.scip,\n noScip: scope.noScip,\n noTsc: scope.noTsc,\n cluster: scope.cluster as ClusterMode | undefined,\n grammarsDir: scope.grammarsDir,\n inline: opts.inline,\n jobs: opts.jobs,\n });\n\n const wrote = result.graph.provenance.corpusHash !== probe.corpusHash;\n if (wrote) {\n const dir = vibgrateDir(root);\n writeArtifacts(result.graph, {\n root,\n graphPath: opts.graphPath,\n report: fs.existsSync(path.join(dir, 'GRAPH_REPORT.md')),\n html: fs.existsSync(path.join(dir, 'graph.html')),\n });\n }\n writeSnapshot(root, result.graph.provenance.corpusHash, result.fileStats, scope);\n\n const ms = Number((process.hrtime.bigint() - start) / 1000000n);\n return {\n status: 'refreshed',\n drift: probe.drift,\n ms,\n reparsed: result.reparsed,\n totalFiles: result.totalFiles,\n wrote,\n };\n } catch (err) {\n return { status: 'error', message: (err as Error).message };\n } finally {\n releaseLock(lock);\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { loadGraphFileWithSnapshot, resolveGraphPath, cacheDir } from './chunk-
|
|
1
|
+
import { loadGraphFileWithSnapshot, resolveGraphPath, cacheDir } from './chunk-EWZKOU66.js';
|
|
2
2
|
import { __require } from './chunk-Z6ZWNWWR.js';
|
|
3
3
|
import * as fs from 'fs';
|
|
4
4
|
import * as path from 'path';
|
|
@@ -198,5 +198,5 @@ function loadGraph(root, graphPath) {
|
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
export { SCHEMA_VERSION, loadGraph, loadGraphPreferIndex, writeGraphIndex };
|
|
201
|
-
//# sourceMappingURL=chunk-
|
|
202
|
-
//# sourceMappingURL=chunk-
|
|
201
|
+
//# sourceMappingURL=chunk-7ZHSSGUF.js.map
|
|
202
|
+
//# sourceMappingURL=chunk-7ZHSSGUF.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schema.ts","../src/engine/index-db.ts","../src/engine/load.ts"],"names":[],"mappings":"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","file":"chunk-JFCCJWXD.js","sourcesContent":["/**\n * The `vg-graph/1.0` on-disk schema.\n *\n * This is vg's own open schema (VG-PACKAGE-AND-SCHEMA.md §4) — informed by good\n * ideas (content-hashed ids, epistemic typing of facts) but standalone and\n * self-contained. Every collection is deterministically serialized\n * (sorted keys, stable element order). These TypeScript shapes are normative.\n */\n\nexport const SCHEMA_VERSION = 'vg-graph/1.0' as const;\n\nexport type ResolverKind = 'scip' | 'stackgraph' | 'tsc' | 'heuristic';\n\n/** Coarse, honest resolution tier for an edge (see engine/epistemic.ts). */\nexport type EpistemicTier = 'observed' | 'name-matched' | 'declared';\n\n/**\n * The toolchain that produced this graph — the reproducibility fingerprint.\n * Everything here deterministically affects graph *content* (parse trees change\n * between grammar releases; resolvers change which edges resolve), so a CI run\n * and a laptop run that disagree can be caught by comparing `fingerprint`.\n * Deliberately excludes the Node/OS version so the graph stays byte-stable\n * across host runtimes; `fingerprint` pins the parse/resolve toolchain only.\n */\nexport interface Toolchain {\n schema: string; // SCHEMA_VERSION\n tool: string; // vg calendar version\n grammars: string; // tree-sitter grammar set version string\n resolvers: ResolverKind[]; // resolver kinds available, sorted\n fingerprint: string; // shortId over the fields above — the value `vg attest` signs\n}\n\nexport interface Provenance {\n tool: 'vg';\n version: string; // calendar version\n grammars: Record<string, string>; // lang → grammar version (determinism input)\n resolver: ResolverKind[];\n deep: boolean; // did the heavier open passes run\n semanticModel?: string; // embedding model id+version if --deep semantic links\n corpusHash: string; // blake3 over the included file set + hashes\n toolchain?: Toolchain; // reproducibility fingerprint (checked by `vg verify`)\n}\n\n/** Analysis cost tier — auto-selected by node count (or forced). Reported honestly. */\nexport type AnalysisTier = 'full' | 'large' | 'xl';\n\nexport interface GraphMeta {\n root: string; // relative; portable across machines\n languages: string[];\n counts: {\n nodes: number;\n edges: number;\n areas: number;\n tests: number;\n untested: number;\n };\n cluster: 'leiden' | 'louvain' | 'none';\n /** Auto-selected (or forced) analysis tier for large maps. */\n analysisTier?: AnalysisTier;\n edgeKinds: EdgeKind[];\n}\n\nexport type NodeKind =\n | 'file'\n | 'module'\n | 'package'\n | 'class'\n | 'interface'\n | 'function'\n | 'method'\n | 'property'\n | 'test'\n | 'route'\n | 'component'\n /** Documentation / config text ingested for semantic ask (markdown, txt, env examples). */\n | 'document'\n | 'external';\n\nexport interface Span {\n start: number; // 1-based start line\n end: number; // 1-based end line\n}\n\nexport interface Centrality {\n degree: number;\n pagerank: number;\n betweenness: number;\n eigenvector: number;\n}\n\nexport interface GraphNode {\n id: string; // blake3(canonical(kind, qualifiedName, file, signature))\n kind: NodeKind;\n name: string; // short name\n qualifiedName: string;\n file: string; // relative path\n span: Span; // line range (excluded from id hash)\n lang: string;\n visibility?: 'public' | 'private' | 'protected' | 'internal';\n signature?: string;\n doc?: string; // short leading doc-comment / docstring summary (deterministic; not a full body)\n importance: number; // 0..1 blended centrality\n centrality: Centrality;\n area: number; // area id (the node's community); -1 = unassigned (cluster \"none\")\n isHub: boolean; // centrality outlier — surfaced by `vg hubs`\n tested: boolean | null; // null = not analyzable (e.g. external)\n coverage?: number; // 0..1 line coverage if a coverage report was ingested\n changeCoupling?: string[]; // node ids that historically change together\n}\n\nexport type EdgeKind =\n | 'call'\n | 'import'\n | 'contains'\n | 'extends'\n | 'implements'\n | 'references'\n | 'test'\n | 'coverage';\n\nexport interface GraphEdge {\n id: string; // blake3(canonical(kind, src, dst))\n kind: EdgeKind;\n src: string; // node id\n dst: string; // node id\n resolution: ResolverKind; // how the edge was resolved\n confidence: number; // 0..1 (1.0 for scip/declared; lower for heuristic/dynamic)\n epistemic?: EpistemicTier; // coarse honesty tier derived from resolution+kind\n surprise?: number; // 0..1 improbability under the area model (`vg oddities`)\n count?: number; // call-site multiplicity\n}\n\nexport interface Area {\n id: number; // stable across runs (remapped to previous committed map)\n label: string; // most-central member's name (editable via `vg label`)\n size: number;\n members: string[]; // node ids, sorted\n cohesion: number; // 0..1\n externalEdges: number; // cross-area edge count\n}\n\nexport type FactKind = 'contract' | 'invariant' | 'characterization';\nexport type DerivedBy = 'declared' | 'static';\nexport type FactConfidence = 'Observed' | 'Derived';\n\nexport interface Fact {\n id: string; // blake3(canonical(kind, subjectIds, predicate))\n kind: FactKind;\n subjectIds: string[]; // node ids this fact constrains\n predicate: unknown; // the constraint\n derivedBy: DerivedBy;\n confidence: FactConfidence;\n evidence: { file: string; span: Span }[];\n}\n\n/**\n * A reference the graph could not resolve — surfaced by `vg unknowns`. Reporting\n * what it *cannot* connect (ranked by blast radius) is the honest inverse of a\n * scanner that hides its unknowns. Only unknowns the precise rungs (tsc/scip)\n * did not supersede are recorded, so a compiler-resolved file never shows here.\n */\nexport interface Unknown {\n from: string; // node id where the unresolved reference occurs\n name: string; // the callee/type name that could not be resolved\n kind: 'call' | 'extends' | 'implements';\n count: number; // occurrences at this site\n}\n\nexport type GroundingKind = 'should_follow' | 'smells_like' | 'relevant_to';\n\nexport interface GroundingEdge {\n src: string; // node id\n packEntryId: string;\n kind: GroundingKind;\n confidence: number; // 0..1\n rationale: 'recommended' | 'conjectured';\n citation: { title: string; url: string };\n}\n\n/** Precomputed hub blast-radius counts for fast agent answers (optional). */\nexport interface HubBlastSummary {\n id: string;\n name: string;\n kind: string;\n file: string;\n importance: number;\n direct: number;\n depth2: number;\n files: number;\n tested: boolean | null;\n}\n\nexport interface GraphSummaries {\n hubs: HubBlastSummary[];\n}\n\nexport interface VgGraph {\n schemaVersion: typeof SCHEMA_VERSION;\n generatedAt: string; // ISO; the ONLY nondeterministic field (pinned by --generated-at)\n provenance: Provenance;\n meta: GraphMeta;\n nodes: GraphNode[]; // sorted by id\n edges: GraphEdge[]; // sorted by (kind, src, dst)\n areas: Area[]; // sorted by id\n facts?: Fact[]; // open facts (contract/invariant/characterization); sorted by id\n grounding?: GroundingEdge[]; // free-pack grounding (default on; omit with --no-ground)\n unknowns?: Unknown[]; // heuristic references left unresolved; sorted by (from, kind, name)\n /** Build-time hub blast-radius summaries (always on; tiny). */\n summaries?: GraphSummaries;\n}\n","/**\n * SQLite serve index for large maps (scale past flat-JSON-only serve).\n *\n * The canonical artifact remains `graph.json` (determinism / git). The index\n * at `.vibgrate/cache/graph.db` is a derived, gitignored structure built after\n * every successful build:\n * - denormalized name/edge columns for O(log n) lookup\n * - full node/edge/area JSON for reconstructing a `VgGraph` without parsing\n * the pretty-printed graph.json (faster cold serve on XL maps)\n *\n * Uses Node's built-in `node:sqlite` (Node ≥22) — no native npm dependency.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { cacheDir } from './cache.js';\nimport { loadGraphFileWithSnapshot } from './snapshot.js';\nimport type {\n Area,\n EpistemicTier,\n GraphEdge,\n GraphNode,\n ResolverKind,\n VgGraph,\n} from '../schema.js';\nimport { SCHEMA_VERSION } from '../schema.js';\n\nexport interface IndexWriteResult {\n path: string;\n nodes: number;\n edges: number;\n /** False when node:sqlite is unavailable — callers should not fail the build. */\n ok: boolean;\n reason?: string;\n}\n\nexport function indexDbPath(root: string): string {\n return path.join(cacheDir(root), 'graph.db');\n}\n\n/** Write (replace) the SQLite index from a built graph. Never throws to callers. */\nexport function writeGraphIndex(root: string, graph: VgGraph): IndexWriteResult {\n const file = indexDbPath(root);\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n fs.mkdirSync(path.dirname(file), { recursive: true });\n const tmp = `${file}.${process.pid}.tmp`;\n try {\n if (fs.existsSync(tmp)) fs.unlinkSync(tmp);\n } catch {\n /* ignore */\n }\n\n const db = new DatabaseSync(tmp);\n db.exec(`\n PRAGMA journal_mode = OFF;\n PRAGMA synchronous = OFF;\n CREATE TABLE meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n CREATE TABLE nodes (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n qualified_name TEXT NOT NULL,\n kind TEXT NOT NULL,\n file TEXT NOT NULL,\n line INTEGER NOT NULL,\n importance REAL NOT NULL,\n area INTEGER NOT NULL,\n is_hub INTEGER NOT NULL,\n lang TEXT NOT NULL,\n json TEXT NOT NULL\n );\n CREATE TABLE edges (\n id TEXT PRIMARY KEY,\n kind TEXT NOT NULL,\n src TEXT NOT NULL,\n dst TEXT NOT NULL,\n resolution TEXT NOT NULL,\n confidence REAL NOT NULL,\n epistemic TEXT NOT NULL,\n json TEXT NOT NULL\n );\n CREATE TABLE areas (\n id INTEGER PRIMARY KEY,\n json TEXT NOT NULL\n );\n CREATE INDEX idx_nodes_name ON nodes(name);\n CREATE INDEX idx_nodes_qn ON nodes(qualified_name);\n CREATE INDEX idx_nodes_file ON nodes(file);\n CREATE INDEX idx_edges_src ON edges(src);\n CREATE INDEX idx_edges_dst ON edges(dst);\n CREATE INDEX idx_edges_kind ON edges(kind);\n `);\n\n const insMeta = db.prepare('INSERT INTO meta(key, value) VALUES (?, ?)');\n insMeta.run('corpusHash', graph.provenance.corpusHash);\n insMeta.run('schemaVersion', graph.schemaVersion);\n insMeta.run('generatedAt', graph.generatedAt);\n insMeta.run('nodeCount', String(graph.nodes.length));\n insMeta.run('edgeCount', String(graph.edges.length));\n insMeta.run('analysisTier', graph.meta.analysisTier ?? 'full');\n insMeta.run('indexVersion', 'vg-graph-index/2');\n // Full meta + provenance for reconstruct without graph.json parse.\n insMeta.run('graphMeta', JSON.stringify(graph.meta));\n insMeta.run('graphProvenance', JSON.stringify(graph.provenance));\n if (graph.facts) insMeta.run('factsJson', JSON.stringify(graph.facts));\n if (graph.grounding) insMeta.run('groundingJson', JSON.stringify(graph.grounding));\n if (graph.summaries) insMeta.run('summariesJson', JSON.stringify(graph.summaries));\n if (graph.unknowns) insMeta.run('unknownsJson', JSON.stringify(graph.unknowns));\n\n const insNode = db.prepare(\n `INSERT INTO nodes(id, name, qualified_name, kind, file, line, importance, area, is_hub, lang, json)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n );\n for (const n of graph.nodes) {\n insNode.run(\n n.id,\n n.name,\n n.qualifiedName,\n n.kind,\n n.file,\n n.span.start,\n n.importance,\n n.area,\n n.isHub ? 1 : 0,\n n.lang,\n JSON.stringify(n),\n );\n }\n\n const insEdge = db.prepare(\n `INSERT INTO edges(id, kind, src, dst, resolution, confidence, epistemic, json)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n );\n for (const e of graph.edges) {\n insEdge.run(\n e.id,\n e.kind,\n e.src,\n e.dst,\n e.resolution,\n e.confidence,\n e.epistemic ?? 'observed',\n JSON.stringify(e),\n );\n }\n\n const insArea = db.prepare('INSERT INTO areas(id, json) VALUES (?, ?)');\n for (const a of graph.areas) {\n insArea.run(a.id, JSON.stringify(a));\n }\n\n db.close();\n fs.renameSync(tmp, file);\n return { path: file, nodes: graph.nodes.length, edges: graph.edges.length, ok: true };\n } catch (err) {\n return {\n path: file,\n nodes: 0,\n edges: 0,\n ok: false,\n reason: (err as Error).message,\n };\n }\n}\n\nexport interface NameHit {\n id: string;\n name: string;\n qualifiedName: string;\n kind: string;\n file: string;\n line: number;\n importance: number;\n}\n\n/** Fast name / prefix lookup against the index. Empty if index missing. */\nexport function lookupNameIndex(root: string, query: string, limit = 20): NameHit[] {\n const file = indexDbPath(root);\n if (!fs.existsSync(file) || !query.trim()) return [];\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n const db = new DatabaseSync(file, { readOnly: true });\n const q = query.trim();\n const rows = db\n .prepare(\n `SELECT id, name, qualified_name, kind, file, line, importance\n FROM nodes\n WHERE name = ? OR qualified_name = ? OR name LIKE ? OR qualified_name LIKE ?\n ORDER BY\n CASE WHEN name = ? OR qualified_name = ? THEN 0\n WHEN name LIKE ? THEN 1\n ELSE 2 END,\n importance DESC\n LIMIT ?`,\n )\n .all(q, q, `${q}%`, `%${q}%`, q, q, `${q}%`, limit) as Record<string, unknown>[];\n db.close();\n return rows.map((r) => ({\n id: String(r.id),\n name: String(r.name),\n qualifiedName: String(r.qualified_name),\n kind: String(r.kind),\n file: String(r.file),\n line: Number(r.line),\n importance: Number(r.importance),\n }));\n } catch {\n return [];\n }\n}\n\n/** Neighbor edges for a node id (src or dst). Empty if index missing. */\nexport function lookupNeighbors(\n root: string,\n nodeId: string,\n direction: 'out' | 'in' | 'both' = 'both',\n limit = 50,\n): GraphEdge[] {\n const file = indexDbPath(root);\n if (!fs.existsSync(file) || !nodeId) return [];\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n const db = new DatabaseSync(file, { readOnly: true });\n let rows: Record<string, unknown>[] = [];\n if (direction === 'out' || direction === 'both') {\n rows = rows.concat(\n db\n .prepare(`SELECT json FROM edges WHERE src = ? LIMIT ?`)\n .all(nodeId, limit) as Record<string, unknown>[],\n );\n }\n if (direction === 'in' || direction === 'both') {\n rows = rows.concat(\n db\n .prepare(`SELECT json FROM edges WHERE dst = ? LIMIT ?`)\n .all(nodeId, limit) as Record<string, unknown>[],\n );\n }\n db.close();\n const byId = new Map<string, GraphEdge>();\n for (const r of rows) {\n try {\n const e = JSON.parse(String(r.json)) as GraphEdge;\n byId.set(e.id, e);\n } catch {\n /* skip bad row */\n }\n }\n return [...byId.values()];\n } catch {\n return [];\n }\n}\n\n/** Read index meta (corpusHash etc.) or null if missing. */\nexport function readIndexMeta(root: string): Record<string, string> | null {\n const file = indexDbPath(root);\n if (!fs.existsSync(file)) return null;\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n const db = new DatabaseSync(file, { readOnly: true });\n const rows = db.prepare('SELECT key, value FROM meta').all() as { key: string; value: string }[];\n db.close();\n const out: Record<string, string> = {};\n for (const r of rows) out[r.key] = r.value;\n return out;\n } catch {\n return null;\n }\n}\n\n/**\n * Reconstruct a full `VgGraph` from the SQLite index (indexVersion ≥ 2).\n * Returns null if the index is missing, stale schema, or incomplete.\n * Prefer this over JSON.parse of pretty graph.json for cold serve on large maps.\n */\nexport function loadGraphFromIndex(root: string): VgGraph | null {\n const file = indexDbPath(root);\n if (!fs.existsSync(file)) return null;\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n const db = new DatabaseSync(file, { readOnly: true });\n const metaRows = db.prepare('SELECT key, value FROM meta').all() as {\n key: string;\n value: string;\n }[];\n const meta: Record<string, string> = {};\n for (const r of metaRows) meta[r.key] = r.value;\n\n if (meta.indexVersion !== 'vg-graph-index/2' || !meta.graphMeta || !meta.graphProvenance) {\n db.close();\n return null;\n }\n\n const nodeRows = db.prepare('SELECT json FROM nodes ORDER BY id').all() as {\n json: string;\n }[];\n const edgeRows = db.prepare('SELECT json FROM edges ORDER BY id').all() as {\n json: string;\n }[];\n const areaRows = db.prepare('SELECT json FROM areas ORDER BY id').all() as {\n json: string;\n }[];\n db.close();\n\n const nodes = nodeRows.map((r) => JSON.parse(r.json) as GraphNode);\n const edges = edgeRows.map((r) => JSON.parse(r.json) as GraphEdge);\n const areas = areaRows.map((r) => JSON.parse(r.json) as Area);\n\n // Stable sorts match serialize contract (ids already ordered by SQL, re-sort for safety).\n nodes.sort((a, b) => a.id.localeCompare(b.id));\n edges.sort(\n (a, b) =>\n a.kind.localeCompare(b.kind) || a.src.localeCompare(b.src) || a.dst.localeCompare(b.dst),\n );\n areas.sort((a, b) => a.id - b.id);\n\n const graph: VgGraph = {\n schemaVersion: (meta.schemaVersion as typeof SCHEMA_VERSION) || SCHEMA_VERSION,\n generatedAt: meta.generatedAt ?? new Date(0).toISOString(),\n provenance: JSON.parse(meta.graphProvenance),\n meta: JSON.parse(meta.graphMeta),\n nodes,\n edges,\n areas,\n };\n if (meta.factsJson) graph.facts = JSON.parse(meta.factsJson);\n if (meta.groundingJson) graph.grounding = JSON.parse(meta.groundingJson);\n if (meta.summariesJson) graph.summaries = JSON.parse(meta.summariesJson);\n if (meta.unknownsJson) graph.unknowns = JSON.parse(meta.unknownsJson);\n\n // Lightweight integrity: edge resolution types stay valid.\n for (const e of edges) {\n if (!e.resolution) e.resolution = 'heuristic' as ResolverKind;\n if (!e.epistemic) e.epistemic = 'observed' as EpistemicTier;\n }\n return graph;\n } catch {\n return null;\n }\n}\n\n/**\n * Load the graph preferring the SQLite index when its corpusHash matches the\n * committed graph.json provenance (or when only the index exists). Falls back\n * to graph.json. Returns null if neither is usable.\n */\nexport function loadGraphPreferIndex(\n root: string,\n graphJsonPath: string,\n): { graph: VgGraph; source: 'index' | 'json' } | null {\n // Snapshot-first: skips the large-string JSON.parse when a fresh binary\n // snapshot exists (sidecar or store-mode standalone), and self-heals the\n // sidecar when not (see engine/snapshot.ts).\n const jsonGraph: VgGraph | null = loadGraphFileWithSnapshot(graphJsonPath);\n\n const fromIndex = loadGraphFromIndex(root);\n if (fromIndex) {\n if (!jsonGraph || fromIndex.provenance.corpusHash === jsonGraph.provenance.corpusHash) {\n return { graph: fromIndex, source: 'index' };\n }\n // Index stale vs graph.json — prefer canonical JSON and let next build refresh.\n }\n if (jsonGraph) return { graph: jsonGraph, source: 'json' };\n return null;\n}\n","import * as fs from 'node:fs';\nimport { resolveGraphPath } from './artifacts.js';\nimport { loadGraphFileWithSnapshot } from './snapshot.js';\nimport { loadGraphPreferIndex } from './index-db.js';\nimport type { VgGraph } from '../schema.js';\n\n/**\n * Load the code map for a repository.\n *\n * When `graphPath` is omitted, prefers an existing global-store snapshot, then\n * the legacy `.vibgrate/graph.json`, matching {@link resolveGraphPath}.\n * Prefers the SQLite index when its corpusHash matches the committed map\n * (faster cold serve on large repos). Returns null if none exists.\n */\nexport function loadGraph(root: string, graphPath?: string): VgGraph | null {\n const file = resolveGraphPath(root, graphPath);\n // Index is always rooted at the project root; only use it when loading the\n // default map for that root (not an arbitrary --graph path).\n if (!graphPath) {\n const preferred = loadGraphPreferIndex(root, file);\n if (preferred) return preferred.graph;\n }\n return loadGraphFileWithSnapshot(file);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/schema.ts","../src/engine/index-db.ts","../src/engine/load.ts"],"names":[],"mappings":"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","file":"chunk-7ZHSSGUF.js","sourcesContent":["/**\n * The `vg-graph/1.0` on-disk schema.\n *\n * This is vg's own open schema (VG-PACKAGE-AND-SCHEMA.md §4) — informed by good\n * ideas (content-hashed ids, epistemic typing of facts) but standalone and\n * self-contained. Every collection is deterministically serialized\n * (sorted keys, stable element order). These TypeScript shapes are normative.\n */\n\nexport const SCHEMA_VERSION = 'vg-graph/1.0' as const;\n\nexport type ResolverKind = 'scip' | 'stackgraph' | 'tsc' | 'heuristic';\n\n/** Coarse, honest resolution tier for an edge (see engine/epistemic.ts). */\nexport type EpistemicTier = 'observed' | 'name-matched' | 'declared';\n\n/**\n * The toolchain that produced this graph — the reproducibility fingerprint.\n * Everything here deterministically affects graph *content* (parse trees change\n * between grammar releases; resolvers change which edges resolve), so a CI run\n * and a laptop run that disagree can be caught by comparing `fingerprint`.\n * Deliberately excludes the Node/OS version so the graph stays byte-stable\n * across host runtimes; `fingerprint` pins the parse/resolve toolchain only.\n */\nexport interface Toolchain {\n schema: string; // SCHEMA_VERSION\n tool: string; // vg calendar version\n grammars: string; // tree-sitter grammar set version string\n resolvers: ResolverKind[]; // resolver kinds available, sorted\n fingerprint: string; // shortId over the fields above — the value `vg attest` signs\n}\n\nexport interface Provenance {\n tool: 'vg';\n version: string; // calendar version\n grammars: Record<string, string>; // lang → grammar version (determinism input)\n resolver: ResolverKind[];\n deep: boolean; // did the heavier open passes run\n semanticModel?: string; // embedding model id+version if --deep semantic links\n corpusHash: string; // blake3 over the included file set + hashes\n toolchain?: Toolchain; // reproducibility fingerprint (checked by `vg verify`)\n}\n\n/** Analysis cost tier — auto-selected by node count (or forced). Reported honestly. */\nexport type AnalysisTier = 'full' | 'large' | 'xl';\n\nexport interface GraphMeta {\n root: string; // relative; portable across machines\n languages: string[];\n counts: {\n nodes: number;\n edges: number;\n areas: number;\n tests: number;\n untested: number;\n };\n cluster: 'leiden' | 'louvain' | 'none';\n /** Auto-selected (or forced) analysis tier for large maps. */\n analysisTier?: AnalysisTier;\n edgeKinds: EdgeKind[];\n}\n\nexport type NodeKind =\n | 'file'\n | 'module'\n | 'package'\n | 'class'\n | 'interface'\n | 'function'\n | 'method'\n | 'property'\n | 'test'\n | 'route'\n | 'component'\n /** Documentation / config text ingested for semantic ask (markdown, txt, env examples). */\n | 'document'\n | 'external';\n\nexport interface Span {\n start: number; // 1-based start line\n end: number; // 1-based end line\n}\n\nexport interface Centrality {\n degree: number;\n pagerank: number;\n betweenness: number;\n eigenvector: number;\n}\n\nexport interface GraphNode {\n id: string; // blake3(canonical(kind, qualifiedName, file, signature))\n kind: NodeKind;\n name: string; // short name\n qualifiedName: string;\n file: string; // relative path\n span: Span; // line range (excluded from id hash)\n lang: string;\n visibility?: 'public' | 'private' | 'protected' | 'internal';\n signature?: string;\n doc?: string; // short leading doc-comment / docstring summary (deterministic; not a full body)\n importance: number; // 0..1 blended centrality\n centrality: Centrality;\n area: number; // area id (the node's community); -1 = unassigned (cluster \"none\")\n isHub: boolean; // centrality outlier — surfaced by `vg hubs`\n tested: boolean | null; // null = not analyzable (e.g. external)\n coverage?: number; // 0..1 line coverage if a coverage report was ingested\n changeCoupling?: string[]; // node ids that historically change together\n}\n\nexport type EdgeKind =\n | 'call'\n | 'import'\n | 'contains'\n | 'extends'\n | 'implements'\n | 'references'\n | 'test'\n | 'coverage';\n\nexport interface GraphEdge {\n id: string; // blake3(canonical(kind, src, dst))\n kind: EdgeKind;\n src: string; // node id\n dst: string; // node id\n resolution: ResolverKind; // how the edge was resolved\n confidence: number; // 0..1 (1.0 for scip/declared; lower for heuristic/dynamic)\n epistemic?: EpistemicTier; // coarse honesty tier derived from resolution+kind\n surprise?: number; // 0..1 improbability under the area model (`vg oddities`)\n count?: number; // call-site multiplicity\n}\n\nexport interface Area {\n id: number; // stable across runs (remapped to previous committed map)\n label: string; // most-central member's name (editable via `vg label`)\n size: number;\n members: string[]; // node ids, sorted\n cohesion: number; // 0..1\n externalEdges: number; // cross-area edge count\n}\n\nexport type FactKind = 'contract' | 'invariant' | 'characterization';\nexport type DerivedBy = 'declared' | 'static';\nexport type FactConfidence = 'Observed' | 'Derived';\n\nexport interface Fact {\n id: string; // blake3(canonical(kind, subjectIds, predicate))\n kind: FactKind;\n subjectIds: string[]; // node ids this fact constrains\n predicate: unknown; // the constraint\n derivedBy: DerivedBy;\n confidence: FactConfidence;\n evidence: { file: string; span: Span }[];\n}\n\n/**\n * A reference the graph could not resolve — surfaced by `vg unknowns`. Reporting\n * what it *cannot* connect (ranked by blast radius) is the honest inverse of a\n * scanner that hides its unknowns. Only unknowns the precise rungs (tsc/scip)\n * did not supersede are recorded, so a compiler-resolved file never shows here.\n */\nexport interface Unknown {\n from: string; // node id where the unresolved reference occurs\n name: string; // the callee/type name that could not be resolved\n kind: 'call' | 'extends' | 'implements';\n count: number; // occurrences at this site\n}\n\nexport type GroundingKind = 'should_follow' | 'smells_like' | 'relevant_to';\n\nexport interface GroundingEdge {\n src: string; // node id\n packEntryId: string;\n kind: GroundingKind;\n confidence: number; // 0..1\n rationale: 'recommended' | 'conjectured';\n citation: { title: string; url: string };\n}\n\n/** Precomputed hub blast-radius counts for fast agent answers (optional). */\nexport interface HubBlastSummary {\n id: string;\n name: string;\n kind: string;\n file: string;\n importance: number;\n direct: number;\n depth2: number;\n files: number;\n tested: boolean | null;\n}\n\nexport interface GraphSummaries {\n hubs: HubBlastSummary[];\n}\n\nexport interface VgGraph {\n schemaVersion: typeof SCHEMA_VERSION;\n generatedAt: string; // ISO; the ONLY nondeterministic field (pinned by --generated-at)\n provenance: Provenance;\n meta: GraphMeta;\n nodes: GraphNode[]; // sorted by id\n edges: GraphEdge[]; // sorted by (kind, src, dst)\n areas: Area[]; // sorted by id\n facts?: Fact[]; // open facts (contract/invariant/characterization); sorted by id\n grounding?: GroundingEdge[]; // free-pack grounding (default on; omit with --no-ground)\n unknowns?: Unknown[]; // heuristic references left unresolved; sorted by (from, kind, name)\n /** Build-time hub blast-radius summaries (always on; tiny). */\n summaries?: GraphSummaries;\n}\n","/**\n * SQLite serve index for large maps (scale past flat-JSON-only serve).\n *\n * The canonical artifact remains `graph.json` (determinism / git). The index\n * at `.vibgrate/cache/graph.db` is a derived, gitignored structure built after\n * every successful build:\n * - denormalized name/edge columns for O(log n) lookup\n * - full node/edge/area JSON for reconstructing a `VgGraph` without parsing\n * the pretty-printed graph.json (faster cold serve on XL maps)\n *\n * Uses Node's built-in `node:sqlite` (Node ≥22) — no native npm dependency.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { cacheDir } from './cache.js';\nimport { loadGraphFileWithSnapshot } from './snapshot.js';\nimport type {\n Area,\n EpistemicTier,\n GraphEdge,\n GraphNode,\n ResolverKind,\n VgGraph,\n} from '../schema.js';\nimport { SCHEMA_VERSION } from '../schema.js';\n\nexport interface IndexWriteResult {\n path: string;\n nodes: number;\n edges: number;\n /** False when node:sqlite is unavailable — callers should not fail the build. */\n ok: boolean;\n reason?: string;\n}\n\nexport function indexDbPath(root: string): string {\n return path.join(cacheDir(root), 'graph.db');\n}\n\n/** Write (replace) the SQLite index from a built graph. Never throws to callers. */\nexport function writeGraphIndex(root: string, graph: VgGraph): IndexWriteResult {\n const file = indexDbPath(root);\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n fs.mkdirSync(path.dirname(file), { recursive: true });\n const tmp = `${file}.${process.pid}.tmp`;\n try {\n if (fs.existsSync(tmp)) fs.unlinkSync(tmp);\n } catch {\n /* ignore */\n }\n\n const db = new DatabaseSync(tmp);\n db.exec(`\n PRAGMA journal_mode = OFF;\n PRAGMA synchronous = OFF;\n CREATE TABLE meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n CREATE TABLE nodes (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n qualified_name TEXT NOT NULL,\n kind TEXT NOT NULL,\n file TEXT NOT NULL,\n line INTEGER NOT NULL,\n importance REAL NOT NULL,\n area INTEGER NOT NULL,\n is_hub INTEGER NOT NULL,\n lang TEXT NOT NULL,\n json TEXT NOT NULL\n );\n CREATE TABLE edges (\n id TEXT PRIMARY KEY,\n kind TEXT NOT NULL,\n src TEXT NOT NULL,\n dst TEXT NOT NULL,\n resolution TEXT NOT NULL,\n confidence REAL NOT NULL,\n epistemic TEXT NOT NULL,\n json TEXT NOT NULL\n );\n CREATE TABLE areas (\n id INTEGER PRIMARY KEY,\n json TEXT NOT NULL\n );\n CREATE INDEX idx_nodes_name ON nodes(name);\n CREATE INDEX idx_nodes_qn ON nodes(qualified_name);\n CREATE INDEX idx_nodes_file ON nodes(file);\n CREATE INDEX idx_edges_src ON edges(src);\n CREATE INDEX idx_edges_dst ON edges(dst);\n CREATE INDEX idx_edges_kind ON edges(kind);\n `);\n\n const insMeta = db.prepare('INSERT INTO meta(key, value) VALUES (?, ?)');\n insMeta.run('corpusHash', graph.provenance.corpusHash);\n insMeta.run('schemaVersion', graph.schemaVersion);\n insMeta.run('generatedAt', graph.generatedAt);\n insMeta.run('nodeCount', String(graph.nodes.length));\n insMeta.run('edgeCount', String(graph.edges.length));\n insMeta.run('analysisTier', graph.meta.analysisTier ?? 'full');\n insMeta.run('indexVersion', 'vg-graph-index/2');\n // Full meta + provenance for reconstruct without graph.json parse.\n insMeta.run('graphMeta', JSON.stringify(graph.meta));\n insMeta.run('graphProvenance', JSON.stringify(graph.provenance));\n if (graph.facts) insMeta.run('factsJson', JSON.stringify(graph.facts));\n if (graph.grounding) insMeta.run('groundingJson', JSON.stringify(graph.grounding));\n if (graph.summaries) insMeta.run('summariesJson', JSON.stringify(graph.summaries));\n if (graph.unknowns) insMeta.run('unknownsJson', JSON.stringify(graph.unknowns));\n\n const insNode = db.prepare(\n `INSERT INTO nodes(id, name, qualified_name, kind, file, line, importance, area, is_hub, lang, json)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n );\n for (const n of graph.nodes) {\n insNode.run(\n n.id,\n n.name,\n n.qualifiedName,\n n.kind,\n n.file,\n n.span.start,\n n.importance,\n n.area,\n n.isHub ? 1 : 0,\n n.lang,\n JSON.stringify(n),\n );\n }\n\n const insEdge = db.prepare(\n `INSERT INTO edges(id, kind, src, dst, resolution, confidence, epistemic, json)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n );\n for (const e of graph.edges) {\n insEdge.run(\n e.id,\n e.kind,\n e.src,\n e.dst,\n e.resolution,\n e.confidence,\n e.epistemic ?? 'observed',\n JSON.stringify(e),\n );\n }\n\n const insArea = db.prepare('INSERT INTO areas(id, json) VALUES (?, ?)');\n for (const a of graph.areas) {\n insArea.run(a.id, JSON.stringify(a));\n }\n\n db.close();\n fs.renameSync(tmp, file);\n return { path: file, nodes: graph.nodes.length, edges: graph.edges.length, ok: true };\n } catch (err) {\n return {\n path: file,\n nodes: 0,\n edges: 0,\n ok: false,\n reason: (err as Error).message,\n };\n }\n}\n\nexport interface NameHit {\n id: string;\n name: string;\n qualifiedName: string;\n kind: string;\n file: string;\n line: number;\n importance: number;\n}\n\n/** Fast name / prefix lookup against the index. Empty if index missing. */\nexport function lookupNameIndex(root: string, query: string, limit = 20): NameHit[] {\n const file = indexDbPath(root);\n if (!fs.existsSync(file) || !query.trim()) return [];\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n const db = new DatabaseSync(file, { readOnly: true });\n const q = query.trim();\n const rows = db\n .prepare(\n `SELECT id, name, qualified_name, kind, file, line, importance\n FROM nodes\n WHERE name = ? OR qualified_name = ? OR name LIKE ? OR qualified_name LIKE ?\n ORDER BY\n CASE WHEN name = ? OR qualified_name = ? THEN 0\n WHEN name LIKE ? THEN 1\n ELSE 2 END,\n importance DESC\n LIMIT ?`,\n )\n .all(q, q, `${q}%`, `%${q}%`, q, q, `${q}%`, limit) as Record<string, unknown>[];\n db.close();\n return rows.map((r) => ({\n id: String(r.id),\n name: String(r.name),\n qualifiedName: String(r.qualified_name),\n kind: String(r.kind),\n file: String(r.file),\n line: Number(r.line),\n importance: Number(r.importance),\n }));\n } catch {\n return [];\n }\n}\n\n/** Neighbor edges for a node id (src or dst). Empty if index missing. */\nexport function lookupNeighbors(\n root: string,\n nodeId: string,\n direction: 'out' | 'in' | 'both' = 'both',\n limit = 50,\n): GraphEdge[] {\n const file = indexDbPath(root);\n if (!fs.existsSync(file) || !nodeId) return [];\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n const db = new DatabaseSync(file, { readOnly: true });\n let rows: Record<string, unknown>[] = [];\n if (direction === 'out' || direction === 'both') {\n rows = rows.concat(\n db\n .prepare(`SELECT json FROM edges WHERE src = ? LIMIT ?`)\n .all(nodeId, limit) as Record<string, unknown>[],\n );\n }\n if (direction === 'in' || direction === 'both') {\n rows = rows.concat(\n db\n .prepare(`SELECT json FROM edges WHERE dst = ? LIMIT ?`)\n .all(nodeId, limit) as Record<string, unknown>[],\n );\n }\n db.close();\n const byId = new Map<string, GraphEdge>();\n for (const r of rows) {\n try {\n const e = JSON.parse(String(r.json)) as GraphEdge;\n byId.set(e.id, e);\n } catch {\n /* skip bad row */\n }\n }\n return [...byId.values()];\n } catch {\n return [];\n }\n}\n\n/** Read index meta (corpusHash etc.) or null if missing. */\nexport function readIndexMeta(root: string): Record<string, string> | null {\n const file = indexDbPath(root);\n if (!fs.existsSync(file)) return null;\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n const db = new DatabaseSync(file, { readOnly: true });\n const rows = db.prepare('SELECT key, value FROM meta').all() as { key: string; value: string }[];\n db.close();\n const out: Record<string, string> = {};\n for (const r of rows) out[r.key] = r.value;\n return out;\n } catch {\n return null;\n }\n}\n\n/**\n * Reconstruct a full `VgGraph` from the SQLite index (indexVersion ≥ 2).\n * Returns null if the index is missing, stale schema, or incomplete.\n * Prefer this over JSON.parse of pretty graph.json for cold serve on large maps.\n */\nexport function loadGraphFromIndex(root: string): VgGraph | null {\n const file = indexDbPath(root);\n if (!fs.existsSync(file)) return null;\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { DatabaseSync } = require('node:sqlite') as typeof import('node:sqlite');\n const db = new DatabaseSync(file, { readOnly: true });\n const metaRows = db.prepare('SELECT key, value FROM meta').all() as {\n key: string;\n value: string;\n }[];\n const meta: Record<string, string> = {};\n for (const r of metaRows) meta[r.key] = r.value;\n\n if (meta.indexVersion !== 'vg-graph-index/2' || !meta.graphMeta || !meta.graphProvenance) {\n db.close();\n return null;\n }\n\n const nodeRows = db.prepare('SELECT json FROM nodes ORDER BY id').all() as {\n json: string;\n }[];\n const edgeRows = db.prepare('SELECT json FROM edges ORDER BY id').all() as {\n json: string;\n }[];\n const areaRows = db.prepare('SELECT json FROM areas ORDER BY id').all() as {\n json: string;\n }[];\n db.close();\n\n const nodes = nodeRows.map((r) => JSON.parse(r.json) as GraphNode);\n const edges = edgeRows.map((r) => JSON.parse(r.json) as GraphEdge);\n const areas = areaRows.map((r) => JSON.parse(r.json) as Area);\n\n // Stable sorts match serialize contract (ids already ordered by SQL, re-sort for safety).\n nodes.sort((a, b) => a.id.localeCompare(b.id));\n edges.sort(\n (a, b) =>\n a.kind.localeCompare(b.kind) || a.src.localeCompare(b.src) || a.dst.localeCompare(b.dst),\n );\n areas.sort((a, b) => a.id - b.id);\n\n const graph: VgGraph = {\n schemaVersion: (meta.schemaVersion as typeof SCHEMA_VERSION) || SCHEMA_VERSION,\n generatedAt: meta.generatedAt ?? new Date(0).toISOString(),\n provenance: JSON.parse(meta.graphProvenance),\n meta: JSON.parse(meta.graphMeta),\n nodes,\n edges,\n areas,\n };\n if (meta.factsJson) graph.facts = JSON.parse(meta.factsJson);\n if (meta.groundingJson) graph.grounding = JSON.parse(meta.groundingJson);\n if (meta.summariesJson) graph.summaries = JSON.parse(meta.summariesJson);\n if (meta.unknownsJson) graph.unknowns = JSON.parse(meta.unknownsJson);\n\n // Lightweight integrity: edge resolution types stay valid.\n for (const e of edges) {\n if (!e.resolution) e.resolution = 'heuristic' as ResolverKind;\n if (!e.epistemic) e.epistemic = 'observed' as EpistemicTier;\n }\n return graph;\n } catch {\n return null;\n }\n}\n\n/**\n * Load the graph preferring the SQLite index when its corpusHash matches the\n * committed graph.json provenance (or when only the index exists). Falls back\n * to graph.json. Returns null if neither is usable.\n */\nexport function loadGraphPreferIndex(\n root: string,\n graphJsonPath: string,\n): { graph: VgGraph; source: 'index' | 'json' } | null {\n // Snapshot-first: skips the large-string JSON.parse when a fresh binary\n // snapshot exists (sidecar or store-mode standalone), and self-heals the\n // sidecar when not (see engine/snapshot.ts).\n const jsonGraph: VgGraph | null = loadGraphFileWithSnapshot(graphJsonPath);\n\n const fromIndex = loadGraphFromIndex(root);\n if (fromIndex) {\n if (!jsonGraph || fromIndex.provenance.corpusHash === jsonGraph.provenance.corpusHash) {\n return { graph: fromIndex, source: 'index' };\n }\n // Index stale vs graph.json — prefer canonical JSON and let next build refresh.\n }\n if (jsonGraph) return { graph: jsonGraph, source: 'json' };\n return null;\n}\n","import * as fs from 'node:fs';\nimport { resolveGraphPath } from './artifacts.js';\nimport { loadGraphFileWithSnapshot } from './snapshot.js';\nimport { loadGraphPreferIndex } from './index-db.js';\nimport type { VgGraph } from '../schema.js';\n\n/**\n * Load the code map for a repository.\n *\n * When `graphPath` is omitted, prefers an existing global-store snapshot, then\n * the legacy `.vibgrate/graph.json`, matching {@link resolveGraphPath}.\n * Prefers the SQLite index when its corpusHash matches the committed map\n * (faster cold serve on large repos). Returns null if none exists.\n */\nexport function loadGraph(root: string, graphPath?: string): VgGraph | null {\n const file = resolveGraphPath(root, graphPath);\n // Index is always rooted at the project root; only use it when loading the\n // default map for that root (not an arbitrary --graph path).\n if (!graphPath) {\n const preferred = loadGraphPreferIndex(root, file);\n if (preferred) return preferred.graph;\n }\n return loadGraphFileWithSnapshot(file);\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { indexFor, queryGraph, impactOf, conceptMapLines, extractLiteralNeedles } from './chunk-
|
|
2
|
-
import { cacheDir } from './chunk-
|
|
1
|
+
import { indexFor, userAskFromInstruction, queryGraph, impactOf, conceptMapLines, extractLiteralNeedles } from './chunk-YJU7S7N6.js';
|
|
2
|
+
import { cacheDir } from './chunk-EWZKOU66.js';
|
|
3
3
|
import { hashString } from './chunk-JFGYT6BI.js';
|
|
4
4
|
import * as fs from 'fs';
|
|
5
5
|
import * as path from 'path';
|
|
@@ -221,12 +221,14 @@ function buildCodeContext(graph, instruction, options = {}) {
|
|
|
221
221
|
const seedLimit = options.seeds ?? 8;
|
|
222
222
|
const impactDepth = options.impactDepth ?? 2;
|
|
223
223
|
const index = indexFor(graph);
|
|
224
|
-
const
|
|
224
|
+
const ask = userAskFromInstruction(instruction);
|
|
225
|
+
const priorAsk = options.priorInstruction ? userAskFromInstruction(options.priorInstruction) : options.priorInstruction;
|
|
226
|
+
const q = queryGraph(graph, ask, {
|
|
225
227
|
budget: Math.floor(budget * 0.6),
|
|
226
228
|
limit: seedLimit * 2,
|
|
227
229
|
relevance: options.relevance,
|
|
228
230
|
topicTags: options.topicTags,
|
|
229
|
-
priorQuestion:
|
|
231
|
+
priorQuestion: priorAsk
|
|
230
232
|
});
|
|
231
233
|
let seeds = q.matches.map((m) => ({ node: m.node, why: m.why }));
|
|
232
234
|
if (options.files && options.files.length) {
|
|
@@ -246,10 +248,10 @@ function buildCodeContext(graph, instruction, options = {}) {
|
|
|
246
248
|
const targetFiles = options.files?.length ? [...new Set(options.files.map(normalize))].sort() : [...new Set(seeds.map((s) => s.node.file))].sort();
|
|
247
249
|
const seedIds = new Set(seeds.map((s) => s.node.id));
|
|
248
250
|
const pinnedFacts = [
|
|
249
|
-
...literalNeedleFacts(
|
|
251
|
+
...literalNeedleFacts(ask),
|
|
250
252
|
...pinnedFactsFor(graph, seedIds)
|
|
251
253
|
];
|
|
252
|
-
const conceptMap = conceptMapLines(
|
|
254
|
+
const conceptMap = conceptMapLines(ask, options.relevance, priorAsk);
|
|
253
255
|
const rendered = render(instruction, seeds, [...impacted.values()], targetFiles, pinnedFacts, conceptMap, index, budget);
|
|
254
256
|
return {
|
|
255
257
|
instruction,
|
|
@@ -262,8 +264,8 @@ function buildCodeContext(graph, instruction, options = {}) {
|
|
|
262
264
|
tokensEstimate: estimateTokens(rendered)
|
|
263
265
|
};
|
|
264
266
|
}
|
|
265
|
-
function literalNeedleFacts(
|
|
266
|
-
const needles = extractLiteralNeedles(
|
|
267
|
+
function literalNeedleFacts(ask) {
|
|
268
|
+
const needles = extractLiteralNeedles(ask);
|
|
267
269
|
if (!needles.length) return [];
|
|
268
270
|
return needles.map(
|
|
269
271
|
(n) => `literal-locate: search the workspace for the exact string \`${n}\` (use search_code with the quoted needle). This is not a graph symbol name. If there are zero hits, report that honestly and finish \u2014 do not invent an edit.`
|
|
@@ -640,5 +642,5 @@ function estimateTokens2(text) {
|
|
|
640
642
|
}
|
|
641
643
|
|
|
642
644
|
export { CAPSULE_COMPILER_ID, CAPSULE_RANKING_VERSION, CLI_TOOL_ALIASES, PER_FILE_TOKENS, SAVINGS_TOOLS, TASK_CAPSULE_SCHEMA_VERSION, buildCodeContext, buildTaskCapsule, capsuleToCodeContext, clearSavings, readModelSavings, readSavings, readUsage, recordCliCall, recordSaving, sanitizeClient, savingsLedgerPath, savingsRecorded, summarizeCapsule };
|
|
643
|
-
//# sourceMappingURL=chunk-
|
|
644
|
-
//# sourceMappingURL=chunk-
|
|
645
|
+
//# sourceMappingURL=chunk-CJNWHXQD.js.map
|
|
646
|
+
//# sourceMappingURL=chunk-CJNWHXQD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/engine/savings.ts","../src/code/context.ts","../src/code/capsule.ts"],"names":["estimateTokens","normalize"],"mappings":"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","file":"chunk-CJNWHXQD.js","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { cacheDir } from './cache.js';\n\n/**\n * Usage-savings tracking (VG-DEVELOPMENT-PLAN §5) — local, privacy-safe, and\n * **opt-in**. We record *counts only* — never code, never the question text —\n * comparing the context tokens vg returned against a grep/read baseline estimate.\n * `vg savings` reports it with the assumptions shown; figures are labelled\n * estimates, never a hero number.\n *\n * Each entry also carries which path served the call (`source`: an MCP tool call\n * vs a `vg <subcommand>` CLI invocation) and, when known, a coarse `client` label\n * (the AI on the other end). That powers the command-vs-MCP split and the\n * per-client breakdown in `vg savings`, and is the basis for the opt-in\n * `vg serve --share-stats` upload (see ./stats-share.ts). Nothing here leaves the\n * machine unless the operator explicitly enables sharing.\n */\n\nconst LEDGER = 'savings.jsonl';\n// A conservative, documented estimate: tokens an agent reads per file it opens.\nexport const PER_FILE_TOKENS = 400;\n\n/** The tools whose grep/read token baseline the savings summary is computed from.\n * search_symbols belongs here: it is the direct grep replacement (the server\n * instructions steer agents to it INSTEAD of grep), yet it used to contribute\n * zero to the estimate — on search-heavy sessions most of the real saving went\n * uncounted. Its baseline is the same measure as query_graph's: the distinct\n * files its matches point at, at PER_FILE_TOKENS each. */\nexport const SAVINGS_TOOLS = new Set(['query_graph', 'get_node', 'search_symbols']);\n\n/**\n * How a navigation call reached the map:\n * - `mcp` — a tool call over the local `vg serve` MCP server;\n * - `cli` — a `vg <subcommand>` invocation that identified itself with `--client`.\n * Both are recorded into one ledger under a shared tool vocabulary (CLI\n * subcommands are normalised to their MCP tool names via CLI_TOOL_ALIASES), so\n * `(tool, source)` is the command-vs-MCP split and the token math stays unified.\n * Absent on ledger lines written before sources existed → read as `mcp` (the\n * only path that recorded then).\n */\nexport type Source = 'mcp' | 'cli';\n\n/**\n * Canonical tool name a CLI navigation subcommand maps to — the same vocabulary\n * the MCP tools use, so a `vg ask --client=claude` and an MCP `query_graph` call\n * land on one row distinguished only by `source`. A subcommand with no MCP twin\n * (e.g. `tree`) keeps its own name.\n */\nexport const CLI_TOOL_ALIASES: Readonly<Record<string, string>> = {\n ask: 'query_graph',\n show: 'get_node',\n impact: 'impact_of',\n path: 'find_path',\n hubs: 'list_hubs',\n areas: 'list_areas',\n tree: 'tree',\n};\n\n/**\n * Normalise a free-form client name (from `--client` or the MCP `initialize`\n * handshake) to a short, bounded, non-PII token: lowercase, `[a-z0-9._-]` only,\n * ≤ 40 chars. Never carries arbitrary user input into the ledger or an upload —\n * it is a coarse client label (e.g. `claude`, `cursor`, `cline`), not identity.\n * Returns `'unknown'` when nothing usable is provided.\n */\nexport function sanitizeClient(name: string | undefined | null): string {\n if (typeof name !== 'string') return 'unknown';\n const cleaned = name\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 40);\n return cleaned || 'unknown';\n}\n\n/**\n * Outcome of a recorded navigation call:\n * - `complete` — returned results, with nothing capped or paginated;\n * - `partial` — returned results, but more were available/truncated;\n * - `miss` — returned no result (no match, not-found, not-connected).\n */\nexport type Outcome = 'complete' | 'partial' | 'miss';\n\nexport interface SavingEntry {\n ts: number; // epoch ms (runtime ledger state, not part of any artifact)\n tool: string;\n // Optional for back-compat with ledger lines written before outcomes existed;\n // an absent value is read as `complete` (those lines only recorded hits).\n outcome?: Outcome;\n vgTokens: number;\n baselineTokens: number;\n // Optional for back-compat: absent `source` reads as `mcp`. `client` is a\n // sanitized coarse label (see sanitizeClient) or absent when unidentified.\n source?: Source;\n client?: string;\n // The model that made the call, for per-model savings auditing. `provider` is\n // a coarse provider label (e.g. `anthropic`, `ollama`), `model` the sanitized\n // model slug. VG Code sets both so `vg savings` can break usage down per model.\n // Absent on lines from callers that don't identify a model.\n provider?: string;\n model?: string;\n // Wall time of the call, ms. Optional: absent on lines written before timing\n // existed (and on CLI-sourced lines) — absent means \"not measured\", never 0.\n ms?: number;\n}\n\n/**\n * Normalise a model slug to a bounded, non-PII token — like {@link sanitizeClient}\n * but keeping the `/` and `:` that model ids use (`anthropic/claude-3.5-sonnet`,\n * `qwen2.5-coder:7b`). Returns undefined when nothing usable is given.\n */\nexport function sanitizeModelId(name: string | undefined | null): string | undefined {\n if (typeof name !== 'string') return undefined;\n const cleaned = name\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9._:/-]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 60);\n return cleaned || undefined;\n}\n\n/**\n * Record a CLI navigation call (`vg <subcommand> --client=<ai>`) into the same\n * local ledger the MCP path uses. Only ever called when the caller passed\n * `--client` — i.e. an AI host explicitly identified itself — so a human's bare\n * `vg ask` still records nothing. Counts only; never the question or code.\n */\nexport function recordCliCall(\n root: string,\n entry: { tool: string; client?: string; provider?: string; model?: string; outcome: Outcome; vgTokens?: number; baselineFiles?: number },\n now: number,\n): void {\n recordSaving(\n root,\n {\n tool: entry.tool,\n source: 'cli',\n client: sanitizeClient(entry.client),\n provider: entry.provider ? sanitizeClient(entry.provider) : undefined,\n model: sanitizeModelId(entry.model),\n outcome: entry.outcome,\n vgTokens: entry.vgTokens ?? 0,\n baselineTokens: (entry.baselineFiles ?? 0) * PER_FILE_TOKENS,\n },\n now,\n );\n}\n\n/**\n * Absolute path of the local usage ledger for this repo. Exported so the serve\n * status display can tail it live (mcp/ledger-tail.ts) — the file itself stays\n * local-only (GUARDRAILS §3.4; upload is the separate opt-in stats-share path).\n */\nexport function savingsLedgerPath(root: string): string {\n return path.join(cacheDir(root), LEDGER);\n}\n\nfunction ledgerPath(root: string): string {\n return savingsLedgerPath(root);\n}\n\n/** Whether a savings ledger exists for this repo (i.e. `vg serve --savings` has recorded). */\nexport function savingsRecorded(root: string): boolean {\n return fs.existsSync(ledgerPath(root));\n}\n\n/**\n * Delete the recorded usage data for this repo: the ledger itself plus the\n * stats-share state that indexes into it (a byte offset into the ledger and the\n * random per-install id) — a stale offset against a fresh ledger would silently\n * skip new entries, and clearing \"my data\" should also reset the id. Everything\n * removed lives under `.vibgrate/cache/`; nothing else is touched. Returns\n * whether a ledger existed.\n */\nexport function clearSavings(root: string): boolean {\n const file = ledgerPath(root);\n const existed = fs.existsSync(file);\n fs.rmSync(file, { force: true });\n fs.rmSync(path.join(cacheDir(root), 'stats-share.json'), { force: true });\n return existed;\n}\n\nexport function recordSaving(root: string, entry: Omit<SavingEntry, 'ts'>, now: number): void {\n try {\n fs.mkdirSync(cacheDir(root), { recursive: true });\n const line = JSON.stringify({ ts: now, ...entry });\n fs.appendFileSync(ledgerPath(root), line + '\\n');\n } catch {\n /* never let telemetry break a tool call */\n }\n}\n\nexport interface SavingsReport {\n enabled: boolean;\n days: number;\n queries: number;\n vgTokens: number;\n baselineTokens: number;\n ratio: number;\n estCostVg: number;\n estCostBaseline: number;\n saved: number;\n rateLabel: string;\n}\n\n// Published-style input rate ($/1M tokens), shipped with the CLI. Labelled\n// estimate; the user can pass their own model rate.\nconst DEFAULT_RATE_PER_M = 3.0; // e.g. a mid-tier model input rate\nconst DEFAULT_RATE_LABEL = 'input @ $3/1M';\n\nexport function readSavings(root: string, days: number, now: number, ratePerM = DEFAULT_RATE_PER_M): SavingsReport {\n const file = ledgerPath(root);\n const cutoff = now - days * 24 * 60 * 60 * 1000;\n let queries = 0;\n let vgTokens = 0;\n let baselineTokens = 0;\n if (fs.existsSync(file)) {\n for (const line of fs.readFileSync(file, 'utf8').split('\\n')) {\n if (!line.trim()) continue;\n try {\n const e = JSON.parse(line) as SavingEntry;\n if (e.ts < cutoff) continue;\n // The token-savings figures compare only the tools with a meaningful\n // grep/read baseline; the full per-command breakdown lives in readUsage.\n if (!SAVINGS_TOOLS.has(e.tool)) continue;\n queries++;\n vgTokens += e.vgTokens;\n baselineTokens += e.baselineTokens;\n } catch {\n /* skip corrupt line */\n }\n }\n }\n const estCostVg = (vgTokens / 1e6) * ratePerM;\n const estCostBaseline = (baselineTokens / 1e6) * ratePerM;\n return {\n enabled: savingsRecorded(root),\n days,\n queries,\n vgTokens,\n baselineTokens,\n ratio: vgTokens > 0 ? Math.round((baselineTokens / vgTokens) * 100) / 100 : 0,\n estCostVg: round2(estCostVg),\n estCostBaseline: round2(estCostBaseline),\n saved: round2(estCostBaseline - estCostVg),\n rateLabel: DEFAULT_RATE_LABEL,\n };\n}\n\nfunction round2(x: number): number {\n return Math.round(x * 100) / 100;\n}\n\n/** Token + cost savings attributed to one model (VG Code per-model auditing). */\nexport interface ModelSaving {\n /** `provider/model`, the ledger's per-model key. */\n key: string;\n provider: string;\n model: string;\n queries: number;\n vgTokens: number;\n baselineTokens: number;\n saved: number;\n}\n\n/**\n * Per-model breakdown of the token-savings figures — the basis of \"full savings\n * auditing per model\". Only entries that carry a `model` and are savings-baseline\n * tools contribute, so it lines up with the headline `readSavings` totals.\n * Sorted by dollars saved (desc), then key.\n */\nexport function readModelSavings(root: string, days: number, now: number, ratePerM = DEFAULT_RATE_PER_M): ModelSaving[] {\n const file = ledgerPath(root);\n const cutoff = now - days * 24 * 60 * 60 * 1000;\n const byModel = new Map<string, { provider: string; model: string; queries: number; vg: number; base: number }>();\n if (fs.existsSync(file)) {\n for (const line of fs.readFileSync(file, 'utf8').split('\\n')) {\n if (!line.trim()) continue;\n try {\n const e = JSON.parse(line) as SavingEntry;\n if (e.ts < cutoff || !e.model || !SAVINGS_TOOLS.has(e.tool)) continue;\n const provider = e.provider ?? 'unknown';\n const key = `${provider}/${e.model}`;\n const row = byModel.get(key) ?? { provider, model: e.model, queries: 0, vg: 0, base: 0 };\n row.queries++;\n row.vg += e.vgTokens;\n row.base += e.baselineTokens;\n byModel.set(key, row);\n } catch {\n /* skip corrupt line */\n }\n }\n }\n return [...byModel.entries()]\n .map(([key, r]) => ({\n key,\n provider: r.provider,\n model: r.model,\n queries: r.queries,\n vgTokens: r.vg,\n baselineTokens: r.base,\n saved: round2(((r.base - r.vg) / 1e6) * ratePerM),\n }))\n .sort((a, b) => b.saved - a.saved || a.key.localeCompare(b.key));\n}\n\n/** Per-command usage stats over the ledger window (all recorded tools). */\nexport interface CommandStat {\n tool: string;\n calls: number;\n complete: number;\n partial: number;\n miss: number;\n /** (complete + partial) / calls, as a whole-number percentage. */\n successPct: number;\n /** Mean wall time over the calls that recorded one; null when none did. */\n avgMs: number | null;\n}\n\n/** Calls attributed to one dimension value (a source, or a client). */\nexport interface DimensionStat {\n key: string;\n calls: number;\n complete: number;\n partial: number;\n miss: number;\n successPct: number;\n}\n\nexport interface UsageReport {\n enabled: boolean;\n days: number;\n /** One row per tool used, ordered by call count (desc), then name. */\n commands: CommandStat[];\n /** The command-vs-MCP split: calls grouped by `source` (`cli` / `mcp`). */\n sources: DimensionStat[];\n /** Which AI is calling: calls grouped by coarse `client` label. */\n clients: DimensionStat[];\n /** Column sums across all commands. */\n totals: { calls: number; complete: number; partial: number; miss: number };\n /** The mean of the per-command success percentages (each command weighted equally). */\n avgSuccessPct: number;\n}\n\ninterface OutcomeCounts {\n complete: number;\n partial: number;\n miss: number;\n}\n\n/** Turn a name→outcome-count map into sorted DimensionStat rows. */\nfunction toDimensionStats(byKey: Map<string, OutcomeCounts>): DimensionStat[] {\n return [...byKey.entries()]\n .map(([key, r]) => {\n const calls = r.complete + r.partial + r.miss;\n return {\n key,\n calls,\n complete: r.complete,\n partial: r.partial,\n miss: r.miss,\n successPct: calls ? Math.round(((r.complete + r.partial) / calls) * 100) : 0,\n };\n })\n .sort((a, b) => b.calls - a.calls || a.key.localeCompare(b.key));\n}\n\n/**\n * Per-command breakdown of recorded navigation calls: how often each tool was\n * used and how those calls resolved (complete / partial / miss), plus column\n * totals and the average success rate. Complements the token-savings summary —\n * this counts *every* recorded tool, not just the grep-baseline ones.\n */\nexport function readUsage(root: string, days: number, now: number): UsageReport {\n const file = ledgerPath(root);\n const cutoff = now - days * 24 * 60 * 60 * 1000;\n const byTool = new Map<string, OutcomeCounts>();\n const bySource = new Map<string, OutcomeCounts>();\n const byClient = new Map<string, OutcomeCounts>();\n // Per-tool timing over the entries that recorded a duration (older ledger\n // lines and CLI-sourced calls carry none — \"not measured\", never zero).\n const msByTool = new Map<string, { sum: number; n: number }>();\n const bump = (m: Map<string, OutcomeCounts>, key: string, outcome: Outcome): void => {\n const row = m.get(key) ?? { complete: 0, partial: 0, miss: 0 };\n row[outcome]++;\n m.set(key, row);\n };\n if (fs.existsSync(file)) {\n for (const line of fs.readFileSync(file, 'utf8').split('\\n')) {\n if (!line.trim()) continue;\n try {\n const e = JSON.parse(line) as SavingEntry;\n if (e.ts < cutoff) continue;\n const outcome: Outcome = e.outcome ?? 'complete';\n // Back-compat: lines written before these dims existed are MCP calls\n // from an unidentified client.\n bump(byTool, e.tool, outcome);\n bump(bySource, e.source ?? 'mcp', outcome);\n bump(byClient, e.client ?? 'unknown', outcome);\n if (typeof e.ms === 'number' && e.ms >= 0) {\n const timing = msByTool.get(e.tool) ?? { sum: 0, n: 0 };\n timing.sum += e.ms;\n timing.n++;\n msByTool.set(e.tool, timing);\n }\n } catch {\n /* skip corrupt line */\n }\n }\n }\n const commands: CommandStat[] = toDimensionStats(byTool).map((d) => {\n const timing = msByTool.get(d.key);\n return {\n tool: d.key,\n calls: d.calls,\n complete: d.complete,\n partial: d.partial,\n miss: d.miss,\n successPct: d.successPct,\n avgMs: timing && timing.n > 0 ? Math.round(timing.sum / timing.n) : null,\n };\n });\n const totals = commands.reduce(\n (t, c) => ({\n calls: t.calls + c.calls,\n complete: t.complete + c.complete,\n partial: t.partial + c.partial,\n miss: t.miss + c.miss,\n }),\n { calls: 0, complete: 0, partial: 0, miss: 0 },\n );\n const avgSuccessPct = commands.length\n ? Math.round(commands.reduce((s, c) => s + c.successPct, 0) / commands.length)\n : 0;\n return {\n enabled: savingsRecorded(root),\n days,\n commands,\n sources: toDimensionStats(bySource),\n clients: toDimensionStats(byClient),\n totals,\n avgSuccessPct,\n };\n}\n","/**\n * Graph-grounded context assembly for `vg code` (VG-CLI-CODE §3).\n *\n * A generic coding agent starts blind and reconstructs structure by grepping and\n * reading whole files — which is exactly what blows the context window and\n * degrades the model. This module instead uses the deterministic code graph to\n * hand the planner a *small, high-signal, budget-bounded* context: the symbols\n * most relevant to the instruction, their immediate relations, the blast radius\n * of changing them, and any declared facts (hard constraints) that must not be\n * dropped by later compaction. Deterministic given a graph + instruction, so it\n * is fully offline-testable and benchmarkable.\n */\n\nimport { conceptMapLines, extractLiteralNeedles, queryGraph } from '../engine/query.js';\nimport type { RelevanceAnalysis } from '../engine/relevance-provider.js';\nimport { indexFor } from '../engine/relations.js';\nimport { impactOf } from '../engine/impact.js';\nimport type { CodeContext } from './types.js';\nimport type { GraphNode, VgGraph } from '../schema.js';\nimport { userAskFromInstruction } from '../engine/user-ask.js';\n\nexport interface BuildContextOptions {\n /** Approx token budget for the rendered block (default 3000). */\n budget?: number;\n /** How many retrieval seeds to expand (default 8). */\n seeds?: number;\n /** Impact BFS depth for the blast radius (default 2). */\n impactDepth?: number;\n /** Restrict the edit surface to these files (from `--file`), if given. */\n files?: string[];\n /** Optional pre-computed relevance analysis (engine/relevance-provider.ts),\n * loaded by the async caller; widens seed vocabulary deterministically. */\n relevance?: RelevanceAnalysis | null;\n /** Optional per-node topic tags (engine/relevance-enrich.ts). */\n topicTags?: Map<string, readonly string[]> | null;\n /** The previous conversational ask (multi-turn `vg code`). Its content\n * terms join seed ranking at a damped weight so follow-ups (\"do we\n * support direct debits?\" after \"where is stripe used?\") stay anchored to\n * the conversation's topic. Absent → single-turn behaviour, unchanged. */\n priorInstruction?: string | null;\n}\n\n/**\n * Build the context block for a coding instruction. The ordering is\n * cache-stable by design (see router.ts): the invariant, repo-derived material\n * (facts, symbols, relations) comes first and the volatile instruction is\n * echoed last, so a provider's prompt cache can reuse the stable prefix across\n * turns.\n */\nexport function buildCodeContext(graph: VgGraph, instruction: string, options: BuildContextOptions = {}): CodeContext {\n const budget = options.budget ?? 3000;\n const seedLimit = options.seeds ?? 8;\n const impactDepth = options.impactDepth ?? 2;\n const index = indexFor(graph);\n\n // Hosts (VS Code panel) append a \"User attachments\" block with backticked\n // filenames/paths. Ranking and literal-locate pins must use only the user's\n // ask — otherwise `image.png` becomes a hard constraint that aborts the task.\n // The full instruction (with attachments) still goes in the Task section.\n const ask = userAskFromInstruction(instruction);\n const priorAsk = options.priorInstruction\n ? userAskFromInstruction(options.priorInstruction)\n : options.priorInstruction;\n\n // Retrieval seeds: reuse the deterministic lexical/structural retrieval that\n // backs `vg ask`. When `--file` narrows the surface, keep only seeds in those\n // files (but still let impact reach outside them, so the review is honest).\n // URL / quoted-string needles are stripped inside queryGraph so path tokens\n // cannot poison seeds (dash→dashboard, exist→NonExisting, …).\n const q = queryGraph(graph, ask, {\n budget: Math.floor(budget * 0.6),\n limit: seedLimit * 2,\n relevance: options.relevance,\n topicTags: options.topicTags,\n priorQuestion: priorAsk,\n });\n let seeds = q.matches.map((m) => ({ node: m.node, why: m.why }));\n if (options.files && options.files.length) {\n const set = new Set(options.files.map(normalize));\n const inScope = seeds.filter((s) => set.has(normalize(s.node.file)));\n // If nothing matched inside the named files, keep the best global seeds but\n // still steer target files to what the caller asked for.\n if (inScope.length) seeds = inScope;\n }\n seeds = seeds.slice(0, seedLimit);\n\n // Blast radius: who depends on the seeds. This is the impact-aware review\n // signal — an edit to a hub is riskier and the context says so.\n const impacted = new Map<string, { node: GraphNode; via: string }>();\n for (const s of seeds) {\n const impact = impactOf(graph, s.node.id, { depth: impactDepth });\n for (const item of impact.affected.slice(0, 6)) {\n const node = index.node(item.id);\n if (node && !impacted.has(node.id)) impacted.set(node.id, { node, via: s.node.qualifiedName });\n }\n }\n\n // Target files: the seed files (or the explicit --file set), stable order.\n const targetFiles = options.files?.length\n ? [...new Set(options.files.map(normalize))].sort()\n : [...new Set(seeds.map((s) => s.node.file))].sort();\n\n // Pinned facts: declared invariants/contracts that touch the seeds. These are\n // hard constraints; they are surfaced explicitly and never summarized away.\n const seedIds = new Set(seeds.map((s) => s.node.id));\n const pinnedFacts = [\n ...literalNeedleFacts(ask),\n ...pinnedFactsFor(graph, seedIds),\n ];\n\n const conceptMap = conceptMapLines(ask, options.relevance, priorAsk);\n const rendered = render(instruction, seeds, [...impacted.values()], targetFiles, pinnedFacts, conceptMap, index, budget);\n return {\n instruction,\n seeds,\n targetFiles,\n impacted: [...impacted.values()],\n pinnedFacts,\n conceptMap,\n rendered,\n tokensEstimate: estimateTokens(rendered),\n };\n}\n\n/** Pin URL / quoted needles so the agent does not treat path tokens as symbols. */\nfunction literalNeedleFacts(ask: string): string[] {\n const needles = extractLiteralNeedles(ask);\n if (!needles.length) return [];\n return needles.map(\n (n) =>\n `literal-locate: search the workspace for the exact string \\`${n}\\` (use search_code with the quoted needle). This is not a graph symbol name. If there are zero hits, report that honestly and finish — do not invent an edit.`,\n );\n}\n\nfunction pinnedFactsFor(graph: VgGraph, seedIds: Set<string>): string[] {\n if (!graph.facts?.length) return [];\n const out: string[] = [];\n for (const f of graph.facts) {\n if (f.kind === 'characterization') continue; // keep hard constraints only\n if (!f.subjectIds.some((id) => seedIds.has(id))) continue;\n const subjects = f.subjectIds\n .map((id) => graph.nodes.find((n) => n.id === id)?.qualifiedName ?? id)\n .join(', ');\n out.push(`${f.kind}: ${subjects} — ${JSON.stringify(f.predicate)}`);\n }\n return out.sort().slice(0, 12);\n}\n\nfunction render(\n instruction: string,\n seeds: { node: GraphNode; why: string }[],\n impacted: { node: GraphNode; via: string }[],\n targetFiles: string[],\n pinnedFacts: string[],\n conceptMap: string[],\n index: ReturnType<typeof indexFor>,\n budget: number,\n): string {\n const lines: string[] = [];\n lines.push('# Repository context (from the deterministic code graph)');\n lines.push('');\n\n if (pinnedFacts.length) {\n lines.push('## Hard constraints (do not violate)');\n for (const f of pinnedFacts) lines.push(`- ${f}`);\n lines.push('');\n }\n\n if (conceptMap.length) {\n lines.push('## How the ask was interpreted');\n for (const l of conceptMap) lines.push(l);\n lines.push('');\n }\n\n lines.push('## Relevant symbols');\n for (const { node, why } of seeds) {\n const block: string[] = [];\n block.push(`### ${node.qualifiedName} (${node.kind}, ${node.file}:${node.span.start}-${node.span.end})`);\n if (node.signature) block.push('`' + node.signature + '`');\n const callees = uniqueNames(index.callees(node.id).map((x) => x.node.qualifiedName)).slice(0, 6);\n const callers = uniqueNames(index.callers(node.id).map((x) => x.node.qualifiedName)).slice(0, 6);\n if (callees.length) block.push(`calls: ${callees.join(', ')}`);\n if (callers.length) block.push(`called by: ${callers.join(', ')}`);\n block.push(`importance ${node.importance.toFixed(3)}${node.isHub ? ' · hub (high blast radius)' : ''} · ${why}`);\n block.push('');\n const candidate = lines.concat(block).join('\\n');\n if (estimateTokens(candidate) > budget && lines.length > 3) break;\n lines.push(...block);\n }\n\n if (impacted.length) {\n lines.push('## Blast radius (would be affected by a change here)');\n for (const { node, via } of impacted.slice(0, 10)) {\n lines.push(`- ${node.qualifiedName} (${node.file}:${node.span.start}) — depends on ${via}`);\n }\n lines.push('');\n }\n\n lines.push('## Files in scope for this edit');\n for (const f of targetFiles) lines.push(`- ${f}`);\n lines.push('');\n\n lines.push('## Task');\n lines.push(instruction);\n return lines.join('\\n');\n}\n\nfunction uniqueNames(xs: string[]): string[] {\n return [...new Set(xs)];\n}\n\nfunction normalize(file: string): string {\n return file.replace(/\\\\/g, '/').replace(/^\\.\\//, '');\n}\n\nfunction estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n","/**\n * Source-bearing Task Capsule compiler (Fusion Runtime Phase 0).\n *\n * Today's {@link buildCodeContext} pays for graph metadata, then the model still\n * calls `read_file` — double payment. This module compiles a Task Capsule that\n * includes exact source ranges (from Tree-sitter spans already on graph nodes)\n * so the first inference can solve without navigation tool calls (ZNS@1 path).\n *\n * Deterministic given (graph, instruction, file contents, options). Injectable\n * `readFile` keeps unit tests offline and pure.\n *\n * Schema: docs/fusion/task-capsule-v0.schema.json\n */\n\nimport { queryGraph } from '../engine/query.js';\nimport { indexFor } from '../engine/relations.js';\nimport { impactOf } from '../engine/impact.js';\nimport { hashString } from '../engine/hash.js';\nimport type { GraphNode, VgGraph } from '../schema.js';\nimport type { CodeContext } from './types.js';\nimport { buildCodeContext, type BuildContextOptions } from './context.js';\n\nexport const TASK_CAPSULE_SCHEMA_VERSION = 'task-capsule/0' as const;\n/** Frozen ranking policy id — bump when the heuristic changes (benchmark gate). */\n/** Bumped 2026.07.1: strip URL/quoted needles from seed ranking (no path-token false positives). */\n/** Bumped 2026.08.1: term roles (weak process verbs never seed alone), concept/bigram\n * expansion (payments→stripe, \"direct debit\"→sepa/bacs/mandate), multi-term coverage\n * bonus, directory-segment evidence — gated by the ask-quality corpus (bench/ask-corpus.mjs). */\n/** Bumped 2026.08.2: optional relevance-provider seam — sanitized provider expansions\n * join term preparation (own 0..1 weight capped at EXPANSION_WEIGHT; weak-provenance\n * dropped); provider version recorded as `relevanceVersion` provenance. Absent\n * provider = 2026.08.1 behaviour exactly — gated by the same corpus, dual-mode. */\n/** Bumped 2026.08.3: multi-turn field report (\"do we support direct debits?\" after a\n * stripe ask seeded direct* distractors). (a) Tokens consumed by a fired bigram\n * concept are demoted to the weak role — \"direct\" corroborates, never seeds.\n * (b) Conversation carry-over: the previous ask's content terms join ranking at\n * CARRY_WEIGHT when the caller passes `priorInstruction`. (c) A plain-language\n * \"how the ask was interpreted\" concept map is rendered for small local models.\n * No prior instruction + no bigram ask = 2026.08.2 behaviour exactly. */\nexport const CAPSULE_RANKING_VERSION = 'capsule-rank@2026.08.3' as const;\nexport const CAPSULE_COMPILER_ID = 'vg-task-capsule/0' as const;\n\nexport interface BuildCapsuleOptions extends BuildContextOptions {\n /**\n * Read file contents relative to the repository root. Required for source\n * slices; when omitted, the capsule still builds metadata + empty slices\n * (useful for schema/shape tests).\n */\n readFile?: (relativePath: string) => string | null;\n /** Extra lines of context around each symbol span (default 1). */\n padding?: number;\n /** Max source slices after merge (default 12). */\n maxSlices?: number;\n repositoryId?: string | null;\n /** Optional provenance from the Model Execution Profile / security ladder. */\n provenance?: CapsuleProvenanceExtras;\n /**\n * Extra pinned facts (e.g. high-confidence federation bridge edges) appended\n * after graph-derived facts. Secret-free, short strings only.\n */\n extraPinnedFacts?: string[];\n}\n\nexport interface CapsuleSymbolRef {\n id: string;\n qualifiedName: string;\n kind: string;\n file: string;\n span: { start: number; end: number };\n signature?: string | null;\n why: string;\n importance: number;\n}\n\nexport interface SourceSlice {\n file: string;\n start: number;\n end: number;\n content: string;\n contentHash: string;\n symbolIds: string[];\n}\n\nexport interface CapsuleRelationship {\n kind: 'calls' | 'called-by' | 'impacts' | 'contains' | 'other';\n from: string;\n to: string;\n}\n\nexport interface VerificationPlan {\n syntaxFiles: string[];\n suggestedTests: string[];\n notes: string[];\n}\n\nexport interface TaskCapsule {\n schemaVersion: typeof TASK_CAPSULE_SCHEMA_VERSION;\n instruction: string;\n primary: CapsuleSymbolRef[];\n supporting: CapsuleSymbolRef[];\n sourceSlices: SourceSlice[];\n relationships: CapsuleRelationship[];\n pinnedFacts: string[];\n /** Plain-language interpretation of the ask (concept expansions, relevance\n * topics, carried prior-turn terms) — see engine/query.ts conceptMapLines. */\n conceptMap: string[];\n targetFiles: string[];\n verificationPlan: VerificationPlan;\n rendered: string;\n tokensEstimate: number;\n provenance: {\n compiler: string;\n rankingVersion: string;\n graphCorpusHash: string | null;\n repositoryId: string | null;\n /** Model Execution Profile id when resolved (Fusion Phase 4/7). */\n modelProfileId?: string | null;\n /** Security tier for shell during this task. */\n securityTier?: string | null;\n /** Frozen policy / ranking patch id if any. */\n policyVersion?: string | null;\n /** Version of the optional relevance provider that widened seed\n * vocabulary for this capsule, or null when none was active. */\n relevanceVersion?: string | null;\n };\n}\n\nexport interface CapsuleProvenanceExtras {\n modelProfileId?: string | null;\n securityTier?: string | null;\n policyVersion?: string | null;\n}\n\n/** Host-safe capsule summary for VS Code / stream-json capsule transparency. */\nexport interface CapsuleSummary {\n schemaVersion: string;\n instruction: string;\n primary: Array<{ qualifiedName: string; file: string; kind: string }>;\n supporting: Array<{ qualifiedName: string; file: string; kind: string }>;\n sourceSliceCount: number;\n sourceFiles: string[];\n tokensEstimate: number;\n rankingVersion: string;\n /** Truncated rendered capsule for display (not the full prompt dump). */\n preview: string;\n}\n\n/** Host-safe capsule summary (capsule transparency UI / stream-json). */\nexport function summarizeCapsule(capsule: TaskCapsule): CapsuleSummary {\n const sourceFiles = [...new Set(capsule.sourceSlices.map((s) => s.file))].sort();\n const preview = capsule.rendered.length > 4000 ? `${capsule.rendered.slice(0, 4000)}\\n… (truncated)` : capsule.rendered;\n return {\n schemaVersion: capsule.schemaVersion,\n instruction: capsule.instruction,\n primary: capsule.primary.map((p) => ({ qualifiedName: p.qualifiedName, file: p.file, kind: p.kind })),\n supporting: capsule.supporting.map((p) => ({ qualifiedName: p.qualifiedName, file: p.file, kind: p.kind })),\n sourceSliceCount: capsule.sourceSlices.length,\n sourceFiles,\n tokensEstimate: capsule.tokensEstimate,\n rankingVersion: capsule.provenance.rankingVersion,\n preview,\n };\n}\n\n/**\n * Compile a source-bearing Task Capsule. Reuses the same seed / impact /\n * fact-pinning path as {@link buildCodeContext}, then attaches exact source\n * slices and a verification sketch.\n */\nexport function buildTaskCapsule(graph: VgGraph, instruction: string, options: BuildCapsuleOptions = {}): TaskCapsule {\n const base = buildCodeContext(graph, instruction, options);\n const padding = options.padding ?? 1;\n const maxSlices = options.maxSlices ?? 12;\n const budget = options.budget ?? 3000;\n const index = indexFor(graph);\n\n const primary = base.seeds.map((s) => toRef(s.node, s.why));\n const primaryIds = new Set(primary.map((p) => p.id));\n\n const supporting: CapsuleSymbolRef[] = [];\n for (const { node, via } of base.impacted) {\n if (primaryIds.has(node.id)) continue;\n supporting.push(toRef(node, `depends on ${via}`));\n }\n\n const relationships = collectRelationships(base, index);\n const sourceSlices = options.readFile\n ? buildSourceSlices(\n [...base.seeds.map((s) => s.node), ...base.impacted.map((i) => i.node)],\n options.readFile,\n padding,\n maxSlices,\n )\n : [];\n\n const extraFacts = (options.extraPinnedFacts ?? []).filter((f) => typeof f === 'string' && f.trim());\n const pinnedFacts = [...base.pinnedFacts, ...extraFacts];\n const verificationPlan = buildVerificationPlan(graph, base);\n const rendered = renderCapsule(instruction, primary, supporting, sourceSlices, pinnedFacts, base.conceptMap, base.targetFiles, verificationPlan, relationships, budget);\n\n return {\n schemaVersion: TASK_CAPSULE_SCHEMA_VERSION,\n instruction,\n primary,\n supporting,\n sourceSlices,\n relationships,\n pinnedFacts,\n conceptMap: base.conceptMap,\n targetFiles: base.targetFiles,\n verificationPlan,\n rendered,\n tokensEstimate: estimateTokens(rendered),\n provenance: {\n compiler: CAPSULE_COMPILER_ID,\n rankingVersion: CAPSULE_RANKING_VERSION,\n graphCorpusHash: graph.provenance?.corpusHash ?? null,\n repositoryId: options.repositoryId ?? null,\n modelProfileId: options.provenance?.modelProfileId ?? null,\n securityTier: options.provenance?.securityTier ?? null,\n policyVersion: options.provenance?.policyVersion ?? null,\n relevanceVersion: options.relevance?.version ?? null,\n },\n };\n}\n\n/**\n * Project a capsule into the legacy {@link CodeContext} shape so the existing\n * agent prompt path can consume it without a full rewrite (A/B flag).\n */\nexport function capsuleToCodeContext(capsule: TaskCapsule): CodeContext {\n return {\n instruction: capsule.instruction,\n seeds: capsule.primary.map((p) => ({\n node: {\n id: p.id,\n qualifiedName: p.qualifiedName,\n kind: p.kind,\n file: p.file,\n span: p.span,\n signature: p.signature ?? undefined,\n importance: p.importance,\n } as GraphNode,\n why: p.why,\n })),\n targetFiles: capsule.targetFiles,\n conceptMap: capsule.conceptMap,\n impacted: capsule.supporting.map((s) => ({\n node: {\n id: s.id,\n qualifiedName: s.qualifiedName,\n kind: s.kind,\n file: s.file,\n span: s.span,\n signature: s.signature ?? undefined,\n importance: s.importance,\n } as GraphNode,\n via: s.why.replace(/^depends on /, ''),\n })),\n pinnedFacts: capsule.pinnedFacts,\n rendered: capsule.rendered,\n tokensEstimate: capsule.tokensEstimate,\n };\n}\n\nfunction toRef(node: GraphNode, why: string): CapsuleSymbolRef {\n return {\n id: node.id,\n qualifiedName: node.qualifiedName,\n kind: node.kind,\n file: normalize(node.file),\n span: { start: node.span.start, end: node.span.end },\n signature: node.signature ?? null,\n why,\n importance: node.importance,\n };\n}\n\nfunction collectRelationships(\n base: CodeContext,\n index: ReturnType<typeof indexFor>,\n): CapsuleRelationship[] {\n const out: CapsuleRelationship[] = [];\n const seen = new Set<string>();\n const push = (kind: CapsuleRelationship['kind'], from: string, to: string) => {\n const key = `${kind}|${from}|${to}`;\n if (seen.has(key)) return;\n seen.add(key);\n out.push({ kind, from, to });\n };\n\n for (const { node } of base.seeds) {\n for (const c of index.callees(node.id).slice(0, 6)) {\n push('calls', node.qualifiedName, c.node.qualifiedName);\n }\n for (const c of index.callers(node.id).slice(0, 6)) {\n push('called-by', node.qualifiedName, c.node.qualifiedName);\n }\n }\n for (const { node, via } of base.impacted.slice(0, 10)) {\n push('impacts', via, node.qualifiedName);\n }\n\n // Stable order for determinism.\n return out.sort((a, b) => a.kind.localeCompare(b.kind) || a.from.localeCompare(b.from) || a.to.localeCompare(b.to));\n}\n\nfunction buildSourceSlices(\n nodes: GraphNode[],\n readFile: (relativePath: string) => string | null,\n padding: number,\n maxSlices: number,\n): SourceSlice[] {\n // Prefer concrete symbols over file/module containers for source evidence.\n const eligible = nodes.filter((n) => !['file', 'module', 'package'].includes(n.kind));\n const byFile = new Map<string, GraphNode[]>();\n for (const n of eligible) {\n const file = normalize(n.file);\n const list = byFile.get(file) ?? [];\n list.push(n);\n byFile.set(file, list);\n }\n\n type Range = { file: string; start: number; end: number; symbolIds: string[]; score: number };\n const ranges: Range[] = [];\n\n for (const [file, fileNodes] of [...byFile.entries()].sort(([a], [b]) => a.localeCompare(b))) {\n const sorted = [...fileNodes].sort((a, b) => a.span.start - b.span.start || b.importance - a.importance);\n let current: Range | null = null;\n for (const n of sorted) {\n const start = Math.max(1, n.span.start - padding);\n const end = n.span.end + padding;\n const score = n.importance + (n.isHub ? 0.25 : 0);\n if (current && current.file === file && start <= current.end + 2) {\n current.end = Math.max(current.end, end);\n current.symbolIds.push(n.id);\n current.score = Math.max(current.score, score);\n } else {\n if (current) ranges.push(current);\n current = { file, start, end, symbolIds: [n.id], score };\n }\n }\n if (current) ranges.push(current);\n }\n\n ranges.sort((a, b) => b.score - a.score || a.file.localeCompare(b.file) || a.start - b.start);\n\n const slices: SourceSlice[] = [];\n for (const range of ranges) {\n if (slices.length >= maxSlices) break;\n const raw = readFile(range.file);\n if (raw === null) continue;\n const lines = raw.split('\\n');\n const start = Math.min(range.start, lines.length);\n const end = Math.min(range.end, lines.length);\n if (start < 1 || end < start) continue;\n const content = lines.slice(start - 1, end).join('\\n');\n slices.push({\n file: range.file,\n start,\n end,\n content,\n contentHash: hashString(content),\n symbolIds: [...new Set(range.symbolIds)].sort(),\n });\n }\n\n // Stable final order: file then start line (score only used for selection).\n return slices.sort((a, b) => a.file.localeCompare(b.file) || a.start - b.start);\n}\n\nfunction buildVerificationPlan(graph: VgGraph, base: CodeContext): VerificationPlan {\n const syntaxFiles = [...base.targetFiles].sort();\n const seedIds = new Set(base.seeds.map((s) => s.node.id));\n const suggestedTests: string[] = [];\n\n for (const n of graph.nodes) {\n if (n.kind !== 'test') continue;\n // Prefer tests that share a file with seeds or whose name mentions a seed.\n const sameFile = base.seeds.some((s) => normalize(s.node.file) === normalize(n.file));\n const nameHit = base.seeds.some((s) => n.qualifiedName.toLowerCase().includes(s.node.name.toLowerCase()));\n if (sameFile || nameHit || seedIds.has(n.id)) {\n suggestedTests.push(n.qualifiedName);\n }\n }\n suggestedTests.sort();\n\n const notes: string[] = [];\n if (!suggestedTests.length) {\n notes.push('No graph-linked tests found for seed symbols; run the nearest project test command after apply.');\n }\n if (base.impacted.some((i) => i.node.isHub || i.node.importance >= 0.7)) {\n notes.push('High-importance dependents in blast radius — prefer targeted tests before a full build.');\n }\n\n return {\n syntaxFiles,\n suggestedTests: suggestedTests.slice(0, 12),\n notes,\n };\n}\n\nfunction renderCapsule(\n instruction: string,\n primary: CapsuleSymbolRef[],\n supporting: CapsuleSymbolRef[],\n slices: SourceSlice[],\n pinnedFacts: string[],\n conceptMap: string[],\n targetFiles: string[],\n verification: VerificationPlan,\n relationships: CapsuleRelationship[],\n budget: number,\n): string {\n const lines: string[] = [];\n lines.push('# Task capsule (source-bearing, from the deterministic code graph)');\n lines.push('');\n lines.push('Use the exact source evidence below. Search or read outside it only if this capsule is insufficient.');\n lines.push('');\n\n if (pinnedFacts.length) {\n lines.push('## Hard constraints (do not violate)');\n for (const f of pinnedFacts) lines.push(`- ${f}`);\n lines.push('');\n }\n\n // Rendered before the symbol list on purpose: a small local model reads the\n // interpretation first, so the `a→b` provenance slugs on each seed line are\n // decodable instead of noise.\n if (conceptMap.length) {\n lines.push('## How the ask was interpreted');\n for (const l of conceptMap) lines.push(l);\n lines.push('');\n }\n\n lines.push('## Primary symbols');\n for (const s of primary) {\n lines.push(`- ${s.qualifiedName} (${s.kind}, ${s.file}:${s.span.start}-${s.span.end})${s.signature ? ` — \\`${s.signature}\\`` : ''} — ${s.why}`);\n }\n lines.push('');\n\n if (supporting.length) {\n lines.push('## Supporting / blast radius');\n for (const s of supporting.slice(0, 10)) {\n lines.push(`- ${s.qualifiedName} (${s.file}:${s.span.start}) — ${s.why}`);\n }\n lines.push('');\n }\n\n if (relationships.length) {\n lines.push('## Relationships');\n for (const r of relationships.slice(0, 24)) {\n lines.push(`- ${r.kind}: ${r.from} → ${r.to}`);\n }\n lines.push('');\n }\n\n lines.push('## Exact source evidence');\n if (!slices.length) {\n lines.push('_No source slices available (file reader missing or spans unreadable)._');\n lines.push('');\n } else {\n let included = 0;\n for (const slice of slices) {\n const block = [\n `### ${slice.file}:${slice.start}-${slice.end}`,\n `\\`\\`\\`${langFor(slice.file)}`,\n slice.content,\n '```',\n '',\n ];\n const candidate = [...lines, ...block, '## Task', instruction].join('\\n');\n if (estimateTokens(candidate) > budget && included > 0) break;\n lines.push(...block);\n included += 1;\n }\n }\n\n lines.push('## Files in scope');\n for (const f of targetFiles) lines.push(`- ${f}`);\n lines.push('');\n\n lines.push('## Verification plan');\n for (const f of verification.syntaxFiles) lines.push(`- syntax: ${f}`);\n for (const t of verification.suggestedTests) lines.push(`- test: ${t}`);\n for (const n of verification.notes) lines.push(`- note: ${n}`);\n lines.push('');\n\n lines.push('## Task');\n lines.push(instruction);\n return lines.join('\\n');\n}\n\nfunction langFor(file: string): string {\n const ext = file.split('.').pop()?.toLowerCase() ?? '';\n const map: Record<string, string> = {\n ts: 'ts',\n tsx: 'tsx',\n js: 'js',\n jsx: 'jsx',\n mjs: 'js',\n cjs: 'js',\n py: 'python',\n rs: 'rust',\n go: 'go',\n java: 'java',\n cs: 'csharp',\n md: 'md',\n json: 'json',\n };\n return map[ext] ?? '';\n}\n\nfunction normalize(file: string): string {\n return file.replace(/\\\\/g, '/').replace(/^\\.\\//, '');\n}\n\nfunction estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n// Re-export query touch so tree-shaking keeps the dependency explicit for tests.\nexport const __testing = { queryGraph, impactOf };\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { VERSION } from './chunk-
|
|
1
|
+
import { VERSION } from './chunk-RT7P5AYU.js';
|
|
2
2
|
import { globalGraphPathForRef, globalGraphPath, repositoryStoreDir } from './chunk-BWPBB45M.js';
|
|
3
3
|
import { detectGitRef } from './chunk-BPF3YX2U.js';
|
|
4
4
|
import * as fs3 from 'fs';
|
|
@@ -1113,5 +1113,5 @@ function loadCache(root, opts) {
|
|
|
1113
1113
|
}
|
|
1114
1114
|
|
|
1115
1115
|
export { WEAK_TERMS, analyzeQuestion, bigramConsumedTokens, cacheDir, defaultGraphPath, ensureVibgrateGitignore, expandConcepts, legacyGraphPath, loadCache, loadGraphFileWithSnapshot, loadRelevanceProvider, loadTopicTags, mapFileExists, mapFileStat, parseGraph, preferInRepoGraph, relevanceModuleDir, renderHtml, renderReport, resetRelevanceProviderCache, resolveGraphPath, serializeGraph, slimGraphForExport, stableStringify, vibgrateDir, writeArtifacts };
|
|
1116
|
-
//# sourceMappingURL=chunk-
|
|
1117
|
-
//# sourceMappingURL=chunk-
|
|
1116
|
+
//# sourceMappingURL=chunk-EWZKOU66.js.map
|
|
1117
|
+
//# sourceMappingURL=chunk-EWZKOU66.js.map
|