@vibgrate/cli 2026.817.2 → 2026.818.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/activity-MF2GNYAI.js +5 -0
- package/dist/activity-MF2GNYAI.js.map +1 -0
- package/dist/agent-X6VYCE63.js +30 -0
- package/dist/{agent-UQC7QN77.js.map → agent-X6VYCE63.js.map} +1 -1
- package/dist/{approvals-ASPJQUZK.js → approvals-TPQFQSWG.js} +5 -5
- package/dist/{approvals-ASPJQUZK.js.map → approvals-TPQFQSWG.js.map} +1 -1
- package/dist/attach-G5JUIWIT.js +10 -0
- package/dist/attach-G5JUIWIT.js.map +1 -0
- package/dist/baseline-DXI64VLW.js +9 -0
- package/dist/{baseline-FIV6PR2M.js.map → baseline-DXI64VLW.js.map} +1 -1
- package/dist/{chunk-AXZZ5CCG.js → chunk-2C33WR5O.js} +38 -19
- package/dist/chunk-2C33WR5O.js.map +1 -0
- package/dist/chunk-4NTNMT6T.js +6 -0
- package/dist/{chunk-PRG2ULPK.js.map → chunk-4NTNMT6T.js.map} +1 -1
- package/dist/chunk-5IQBIXHS.js +23 -0
- package/dist/chunk-5IQBIXHS.js.map +1 -0
- package/dist/{chunk-6K3XK7C5.js → chunk-6ABMV74F.js} +6 -3
- package/dist/chunk-6ABMV74F.js.map +1 -0
- package/dist/chunk-6BEBJCK4.js +467 -0
- package/dist/chunk-6BEBJCK4.js.map +1 -0
- package/dist/{chunk-E2FAQREZ.js → chunk-6PFHDHOL.js} +174 -401
- package/dist/chunk-6PFHDHOL.js.map +1 -0
- package/dist/chunk-6WRG7VDO.js +118 -0
- package/dist/chunk-6WRG7VDO.js.map +1 -0
- package/dist/{chunk-3NJUOIZQ.js → chunk-AEJYA6HZ.js} +5 -5
- package/dist/{chunk-3NJUOIZQ.js.map → chunk-AEJYA6HZ.js.map} +1 -1
- package/dist/{chunk-O2DL2Q55.js → chunk-B4EXD5LK.js} +5 -5
- package/dist/{chunk-O2DL2Q55.js.map → chunk-B4EXD5LK.js.map} +1 -1
- package/dist/{chunk-EXV4QSAD.js → chunk-BMOFJIMG.js} +3 -3
- package/dist/{chunk-EXV4QSAD.js.map → chunk-BMOFJIMG.js.map} +1 -1
- package/dist/chunk-DBX3DL27.js +26 -0
- package/dist/chunk-DBX3DL27.js.map +1 -0
- package/dist/{chunk-KNGAZDGF.js → chunk-E3O5UKNA.js} +151 -42
- package/dist/chunk-E3O5UKNA.js.map +1 -0
- package/dist/{chunk-RBIRXQR6.js → chunk-E53WBVUQ.js} +7 -14
- package/dist/chunk-E53WBVUQ.js.map +1 -0
- package/dist/{chunk-C3LMWZKF.js → chunk-FFXGWFAE.js} +4 -4
- package/dist/{chunk-C3LMWZKF.js.map → chunk-FFXGWFAE.js.map} +1 -1
- package/dist/chunk-H5Q4JUY4.js +47 -0
- package/dist/chunk-H5Q4JUY4.js.map +1 -0
- package/dist/{chunk-LHKQGVRF.js → chunk-HF6R73UC.js} +100 -11
- package/dist/chunk-HF6R73UC.js.map +1 -0
- package/dist/{chunk-K6DXETMC.js → chunk-JGA63RGF.js} +13 -12
- package/dist/chunk-JGA63RGF.js.map +1 -0
- package/dist/{chunk-3FMRFECC.js → chunk-KU7FI5EV.js} +3 -3
- package/dist/{chunk-3FMRFECC.js.map → chunk-KU7FI5EV.js.map} +1 -1
- package/dist/{chunk-5OL2TSHK.js → chunk-L2OS4WHT.js} +4 -4
- package/dist/{chunk-5OL2TSHK.js.map → chunk-L2OS4WHT.js.map} +1 -1
- package/dist/chunk-LJSJX6U4.js +38 -0
- package/dist/chunk-LJSJX6U4.js.map +1 -0
- package/dist/{chunk-Q4G2BWE3.js → chunk-MRZHNUN7.js} +12 -6
- package/dist/chunk-MRZHNUN7.js.map +1 -0
- package/dist/chunk-NDNNOAS6.js +16 -0
- package/dist/chunk-NDNNOAS6.js.map +1 -0
- package/dist/chunk-NJQZRM55.js +100 -0
- package/dist/chunk-NJQZRM55.js.map +1 -0
- package/dist/{chunk-DVW3SVCW.js → chunk-NKLYDSB7.js} +29 -9
- package/dist/chunk-NKLYDSB7.js.map +1 -0
- package/dist/{chunk-TVDMNIUT.js → chunk-O5IJDMTB.js} +4 -4
- package/dist/{chunk-TVDMNIUT.js.map → chunk-O5IJDMTB.js.map} +1 -1
- package/dist/chunk-POOL355F.js +237 -0
- package/dist/chunk-POOL355F.js.map +1 -0
- package/dist/{chunk-XLXJC7H3.js → chunk-PRHH4DVO.js} +5 -118
- package/dist/chunk-PRHH4DVO.js.map +1 -0
- package/dist/{chunk-3H3SVJUY.js → chunk-RHKOUPWT.js} +107 -542
- package/dist/chunk-RHKOUPWT.js.map +1 -0
- package/dist/{chunk-WAKP7SK7.js → chunk-V2UGRUTL.js} +225 -48
- package/dist/chunk-V2UGRUTL.js.map +1 -0
- package/dist/{chunk-2FEB5KJS.js → chunk-V6WONSIK.js} +5 -4
- package/dist/chunk-V6WONSIK.js.map +1 -0
- package/dist/{chunk-WVMOGIPC.js → chunk-VMAIDM4K.js} +3 -3
- package/dist/{chunk-WVMOGIPC.js.map → chunk-VMAIDM4K.js.map} +1 -1
- package/dist/{chunk-GOGMS3ST.js → chunk-VQ5KMHW6.js} +860 -65
- package/dist/chunk-VQ5KMHW6.js.map +1 -0
- package/dist/{chunk-M7IO3DXH.js → chunk-X2MQ7UFL.js} +250 -30
- package/dist/chunk-X2MQ7UFL.js.map +1 -0
- package/dist/{chunk-OZ3IFXRD.js → chunk-YENM3HT7.js} +5 -4
- package/dist/chunk-YENM3HT7.js.map +1 -0
- package/dist/{chunk-KJT2R6WW.js → chunk-YF54UMOU.js} +3 -3
- package/dist/{chunk-KJT2R6WW.js.map → chunk-YF54UMOU.js.map} +1 -1
- package/dist/{chunk-Q3M6K3HY.js → chunk-ZUOBPKVK.js} +3 -3
- package/dist/{chunk-Q3M6K3HY.js.map → chunk-ZUOBPKVK.js.map} +1 -1
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +711 -463
- package/dist/cli.js.map +1 -1
- package/dist/client-UQIELEEZ.js +8 -0
- package/dist/client-UQIELEEZ.js.map +1 -0
- package/dist/daemon-GUMWMKCA.js +31 -0
- package/dist/{daemon-FPTRHO5N.js.map → daemon-GUMWMKCA.js.map} +1 -1
- package/dist/embed-worker-main.js +3 -3
- package/dist/ensure-map-FHDJTO7Y.js +41 -0
- package/dist/{ensure-map-342G2IV3.js.map → ensure-map-FHDJTO7Y.js.map} +1 -1
- package/dist/graph-backend-W2D3HRRD.js +16 -0
- package/dist/{graph-backend-RNWQBT3P.js.map → graph-backend-W2D3HRRD.js.map} +1 -1
- package/dist/index.d.ts +633 -4
- package/dist/index.js +26 -17
- package/dist/index.js.map +1 -1
- package/dist/{interactive-SR7TMF6M.js → interactive-2MK4TLRD.js} +42 -34
- package/dist/interactive-2MK4TLRD.js.map +1 -0
- package/dist/load-4R4HYMBB.js +11 -0
- package/dist/{load-AYFECIQB.js.map → load-4R4HYMBB.js.map} +1 -1
- package/dist/parse-worker.js +3 -2
- package/dist/parse-worker.js.map +1 -1
- package/dist/publish-7YHRTBRA.js +9 -0
- package/dist/publish-7YHRTBRA.js.map +1 -0
- package/dist/{run-outcome-YQQJG3LW.js → run-outcome-H5GVDDZJ.js} +5 -5
- package/dist/{run-outcome-YQQJG3LW.js.map → run-outcome-H5GVDDZJ.js.map} +1 -1
- package/dist/runtime-session-JBIHHH5N.js +27 -0
- package/dist/{runtime-session-CNJ4DAV5.js.map → runtime-session-JBIHHH5N.js.map} +1 -1
- package/dist/semantic-status-2JFLIQQJ.js +4 -0
- package/dist/semantic-status-2JFLIQQJ.js.map +1 -0
- package/dist/{session-H34HUV2Y.js → session-N5IU4K5Q.js} +8 -8
- package/dist/{session-H34HUV2Y.js.map → session-N5IU4K5Q.js.map} +1 -1
- package/dist/slot-subscription-25GOARW5.js +95 -0
- package/dist/slot-subscription-25GOARW5.js.map +1 -0
- package/dist/{stream-json-55YDNAFX.js → stream-json-4WLSUF6I.js} +18 -15
- package/dist/stream-json-4WLSUF6I.js.map +1 -0
- package/dist/version-DTEU3SQD.js +4 -0
- package/dist/{version-WSE3QOPK.js.map → version-DTEU3SQD.js.map} +1 -1
- package/dist/{vg-mcp-bridge-2CNLHNEL.js → vg-mcp-bridge-KDVYIMFX.js} +12 -11
- package/dist/vg-mcp-bridge-KDVYIMFX.js.map +1 -0
- package/dist/{vgd-URUZQORN.js → vgd-M7UOPWLB.js} +15 -10
- package/dist/vgd-M7UOPWLB.js.map +1 -0
- package/package.json +1 -1
- package/dist/agent-UQC7QN77.js +0 -27
- package/dist/baseline-FIV6PR2M.js +0 -9
- package/dist/chunk-2FEB5KJS.js.map +0 -1
- package/dist/chunk-3H3SVJUY.js.map +0 -1
- package/dist/chunk-6K3XK7C5.js.map +0 -1
- package/dist/chunk-AXZZ5CCG.js.map +0 -1
- package/dist/chunk-DVW3SVCW.js.map +0 -1
- package/dist/chunk-E2FAQREZ.js.map +0 -1
- package/dist/chunk-GOGMS3ST.js.map +0 -1
- package/dist/chunk-K6DXETMC.js.map +0 -1
- package/dist/chunk-KNGAZDGF.js.map +0 -1
- package/dist/chunk-LHKQGVRF.js.map +0 -1
- package/dist/chunk-M7IO3DXH.js.map +0 -1
- package/dist/chunk-OZ3IFXRD.js.map +0 -1
- package/dist/chunk-PRG2ULPK.js +0 -6
- package/dist/chunk-Q4G2BWE3.js.map +0 -1
- package/dist/chunk-RBIRXQR6.js.map +0 -1
- package/dist/chunk-WAKP7SK7.js.map +0 -1
- package/dist/chunk-XLXJC7H3.js.map +0 -1
- package/dist/daemon-FPTRHO5N.js +0 -26
- package/dist/ensure-map-342G2IV3.js +0 -33
- package/dist/graph-backend-RNWQBT3P.js +0 -15
- package/dist/interactive-SR7TMF6M.js.map +0 -1
- package/dist/load-AYFECIQB.js +0 -11
- package/dist/runtime-session-CNJ4DAV5.js +0 -22
- package/dist/stream-json-55YDNAFX.js.map +0 -1
- package/dist/version-WSE3QOPK.js +0 -4
- package/dist/vg-mcp-bridge-2CNLHNEL.js.map +0 -1
- package/dist/vgd-URUZQORN.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { loadGraphFileWithSnapshot, resolveGraphPath } from './chunk-
|
|
1
|
+
import { loadGraphFileWithSnapshot, resolveGraphPath } from './chunk-VMAIDM4K.js';
|
|
2
2
|
import { cacheDir } from './chunk-MVPRPSXU.js';
|
|
3
3
|
import { __require } from './chunk-Z6ZWNWWR.js';
|
|
4
4
|
import * as fs from 'fs';
|
|
@@ -200,5 +200,5 @@ function loadGraph(root, graphPath) {
|
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
export { SCHEMA_VERSION, SUPPORTED_SCHEMA_VERSIONS, loadGraph, loadGraphPreferIndex, writeGraphIndex };
|
|
203
|
-
//# sourceMappingURL=chunk-
|
|
204
|
-
//# sourceMappingURL=chunk-
|
|
203
|
+
//# sourceMappingURL=chunk-KU7FI5EV.js.map
|
|
204
|
+
//# sourceMappingURL=chunk-KU7FI5EV.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-3FMRFECC.js","sourcesContent":["/**\n * The `vg-graph/1.1` 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 * ## Version history\n *\n * - `vg-graph/1.0` — code-only vocabulary.\n * - `vg-graph/1.1` — **additive**: toolchain node kinds (`resource`, `workload`,\n * `job`, `step`, `image`, `chart`) and toolchain edge kinds (`depends_on`,\n * `provisions`, `deploys`, `triggers`, `exposes`, `mounts`, `builds_from`),\n * produced by `engine/toolchain/`. Nothing was removed or renamed, so a 1.0\n * reader that tolerates unknown kinds reads a 1.1 graph correctly; readers\n * that hard-match the version string need widening (see\n * `SUPPORTED_SCHEMA_VERSIONS`).\n */\n\nexport const SCHEMA_VERSION = 'vg-graph/1.1' as const;\n\n/**\n * Schema versions a reader should accept. The toolchain vocabulary added in 1.1\n * is purely additive, so a 1.0 artifact still loads — only the newer kinds are\n * absent from it. Readers must prefer this over an equality check on\n * {@link SCHEMA_VERSION}, which rejects perfectly readable older graphs.\n */\nexport const SUPPORTED_SCHEMA_VERSIONS = ['vg-graph/1.0', 'vg-graph/1.1'] as const;\n\nexport type SupportedSchemaVersion = (typeof SUPPORTED_SCHEMA_VERSIONS)[number];\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 // ── Toolchain kinds (engine/toolchain/) ──────────────────────────────────\n // Structural extraction of the infrastructure/CI corpus. These sit alongside\n // the code kinds above and never replace the `document` node for the same\n // file: the document node stays the semantic-ask surface, these carry the\n // structure. Additive — consumers must tolerate unknown kinds.\n /** A declared infrastructure object: Terraform resource/data, K8s object, Compose service. */\n | 'resource'\n /** A deployable unit that runs containers (Deployment, StatefulSet, DaemonSet, Job, CronJob). */\n | 'workload'\n /** A CI job (GitHub Actions job, GitLab CI job). */\n | 'job'\n /** A single step within a CI job. */\n | 'step'\n /** A container image reference (`ghcr.io/acme/web:1.2.3`) or a Dockerfile build stage. */\n | 'image'\n /** A Helm chart (from `Chart.yaml`). */\n | 'chart';\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 // ── Toolchain edge kinds (engine/toolchain/) ─────────────────────────────\n // Every edge below is produced by structural extraction or by the\n // cross-domain linker. Linker-produced edges are always\n // `resolution: 'heuristic'` with a calibrated confidence — an inferred\n // `deploys` is not a declared `import` and must never claim to be.\n /** Declared ordering/reference dependency (Terraform `depends_on` + interpolation, Compose `depends_on`, CI `needs`). */\n | 'depends_on'\n /** An IaC declaration creates infrastructure (Terraform module → resource, chart → workload). */\n | 'provisions'\n /** A CI job or IaC declaration puts a workload/image into an environment. */\n | 'deploys'\n /** An event or upstream job causes a workflow/job to run. */\n | 'triggers'\n /** A workload/service publishes a port or endpoint. */\n | 'exposes'\n /** A workload/service consumes a volume, config map, or secret *by reference*. */\n | 'mounts'\n /** A build stage or workload is derived from a container image. */\n | 'builds_from';\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 /**\n * The schema this artifact was written against. A freshly built graph always\n * carries {@link SCHEMA_VERSION}; a graph *loaded* from disk may carry any\n * member of {@link SUPPORTED_SCHEMA_VERSIONS}, since older artifacts stay\n * readable (the 1.1 additions are additive).\n */\n schemaVersion: SupportedSchemaVersion;\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 \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 \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 \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 \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 \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 { 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-KU7FI5EV.js","sourcesContent":["/**\n * The `vg-graph/1.1` 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 * ## Version history\n *\n * - `vg-graph/1.0` — code-only vocabulary.\n * - `vg-graph/1.1` — **additive**: toolchain node kinds (`resource`, `workload`,\n * `job`, `step`, `image`, `chart`) and toolchain edge kinds (`depends_on`,\n * `provisions`, `deploys`, `triggers`, `exposes`, `mounts`, `builds_from`),\n * produced by `engine/toolchain/`. Nothing was removed or renamed, so a 1.0\n * reader that tolerates unknown kinds reads a 1.1 graph correctly; readers\n * that hard-match the version string need widening (see\n * `SUPPORTED_SCHEMA_VERSIONS`).\n */\n\nexport const SCHEMA_VERSION = 'vg-graph/1.1' as const;\n\n/**\n * Schema versions a reader should accept. The toolchain vocabulary added in 1.1\n * is purely additive, so a 1.0 artifact still loads — only the newer kinds are\n * absent from it. Readers must prefer this over an equality check on\n * {@link SCHEMA_VERSION}, which rejects perfectly readable older graphs.\n */\nexport const SUPPORTED_SCHEMA_VERSIONS = ['vg-graph/1.0', 'vg-graph/1.1'] as const;\n\nexport type SupportedSchemaVersion = (typeof SUPPORTED_SCHEMA_VERSIONS)[number];\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 // ── Toolchain kinds (engine/toolchain/) ──────────────────────────────────\n // Structural extraction of the infrastructure/CI corpus. These sit alongside\n // the code kinds above and never replace the `document` node for the same\n // file: the document node stays the semantic-ask surface, these carry the\n // structure. Additive — consumers must tolerate unknown kinds.\n /** A declared infrastructure object: Terraform resource/data, K8s object, Compose service. */\n | 'resource'\n /** A deployable unit that runs containers (Deployment, StatefulSet, DaemonSet, Job, CronJob). */\n | 'workload'\n /** A CI job (GitHub Actions job, GitLab CI job). */\n | 'job'\n /** A single step within a CI job. */\n | 'step'\n /** A container image reference (`ghcr.io/acme/web:1.2.3`) or a Dockerfile build stage. */\n | 'image'\n /** A Helm chart (from `Chart.yaml`). */\n | 'chart';\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 // ── Toolchain edge kinds (engine/toolchain/) ─────────────────────────────\n // Every edge below is produced by structural extraction or by the\n // cross-domain linker. Linker-produced edges are always\n // `resolution: 'heuristic'` with a calibrated confidence — an inferred\n // `deploys` is not a declared `import` and must never claim to be.\n /** Declared ordering/reference dependency (Terraform `depends_on` + interpolation, Compose `depends_on`, CI `needs`). */\n | 'depends_on'\n /** An IaC declaration creates infrastructure (Terraform module → resource, chart → workload). */\n | 'provisions'\n /** A CI job or IaC declaration puts a workload/image into an environment. */\n | 'deploys'\n /** An event or upstream job causes a workflow/job to run. */\n | 'triggers'\n /** A workload/service publishes a port or endpoint. */\n | 'exposes'\n /** A workload/service consumes a volume, config map, or secret *by reference*. */\n | 'mounts'\n /** A build stage or workload is derived from a container image. */\n | 'builds_from';\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 /**\n * The schema this artifact was written against. A freshly built graph always\n * carries {@link SCHEMA_VERSION}; a graph *loaded* from disk may carry any\n * member of {@link SUPPORTED_SCHEMA_VERSIONS}, since older artifacts stay\n * readable (the 1.1 additions are additive).\n */\n schemaVersion: SupportedSchemaVersion;\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 \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 \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 \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 \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 \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 { 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 { runBuild } from './chunk-
|
|
2
|
-
import { loadGraph } from './chunk-
|
|
1
|
+
import { runBuild } from './chunk-HF6R73UC.js';
|
|
2
|
+
import { loadGraph } from './chunk-KU7FI5EV.js';
|
|
3
3
|
|
|
4
4
|
// src/code/ensure-map.ts
|
|
5
5
|
async function ensureCodeMap(root, global, hooks) {
|
|
@@ -38,5 +38,5 @@ async function ensureCodeMap(root, global, hooks) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
export { ensureCodeMap };
|
|
41
|
-
//# sourceMappingURL=chunk-
|
|
42
|
-
//# sourceMappingURL=chunk-
|
|
41
|
+
//# sourceMappingURL=chunk-L2OS4WHT.js.map
|
|
42
|
+
//# sourceMappingURL=chunk-L2OS4WHT.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/code/ensure-map.ts"],"names":[],"mappings":";;;;AA4BA,eAAsB,aAAA,CACpB,IAAA,EACA,MAAA,EACA,KAAA,EAC4B;AAC5B,EAAA,IAAI,SAAA,CAAU,IAAA,EAAM,MAAA,CAAO,KAAK,GAAG,OAAO,OAAA;AAE1C,EAAA,KAAA,EAAO,UAAA,GAAa;AAAA,IAClB,KAAA,EAAO,OAAA;AAAA,IACP,OAAA,EAAS,+DAAA;AAAA,IACT,GAAA,EAAK;AAAA,GACN,CAAA;AAED,EAAA,IAAI;AACF,IAAA,MAAM,QAAA;AAAA,MACJ,CAAC,IAAI,CAAA;AAAA,MACL,EAAE,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAM;AAAA,MAC7B,EAAE,GAAG,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAK;AAAA,MACzB;AAAA,QACE,eAAA,EAAiB,CAAC,IAAA,EAAM,KAAA,KAAU;AAChC,UAAA,MAAM,GAAA,GAAM,KAAA,GAAQ,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,IAAA,CAAK,KAAA,CAAO,IAAA,GAAO,KAAA,GAAS,GAAG,CAAC,CAAA,GAAI,KAAA,CAAA;AACzE,UAAA,KAAA,EAAO,UAAA,GAAa;AAAA,YAClB,KAAA,EAAO,UAAA;AAAA,YACP,OAAA,EACE,KAAA,GAAQ,CAAA,GACJ,CAAA,oBAAA,EAAkB,IAAA,CAAK,cAAA,EAAgB,CAAA,CAAA,EAAI,KAAA,CAAM,cAAA,EAAgB,CAAA,CAAA,GACjE,qBAAA;AAAA,YACN;AAAA,WACD,CAAA;AAAA,QACH;AAAA;AACF,KACF;AACA,IAAA,KAAA,EAAO,UAAA,GAAa,EAAE,KAAA,EAAO,MAAA,EAAQ,SAAS,gDAAA,EAAwC,GAAA,EAAK,KAAK,CAAA;AAChG,IAAA,OAAO,OAAA;AAAA,EACT,SAAS,CAAA,EAAG;AACV,IAAA,MAAM,UAAU,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,OAAO,CAAC,CAAA;AACzD,IAAA,KAAA,EAAO,UAAA,GAAa;AAAA,MAClB,KAAA,EAAO,OAAA;AAAA,MACP,OAAA,EAAS,iCAAiC,OAAO,CAAA;AAAA,KAClD,CAAA;AACD,IAAA,MAAM,CAAA;AAAA,EACR;AACF","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/code/ensure-map.ts"],"names":[],"mappings":";;;;AA4BA,eAAsB,aAAA,CACpB,IAAA,EACA,MAAA,EACA,KAAA,EAC4B;AAC5B,EAAA,IAAI,SAAA,CAAU,IAAA,EAAM,MAAA,CAAO,KAAK,GAAG,OAAO,OAAA;AAE1C,EAAA,KAAA,EAAO,UAAA,GAAa;AAAA,IAClB,KAAA,EAAO,OAAA;AAAA,IACP,OAAA,EAAS,+DAAA;AAAA,IACT,GAAA,EAAK;AAAA,GACN,CAAA;AAED,EAAA,IAAI;AACF,IAAA,MAAM,QAAA;AAAA,MACJ,CAAC,IAAI,CAAA;AAAA,MACL,EAAE,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAM;AAAA,MAC7B,EAAE,GAAG,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAK;AAAA,MACzB;AAAA,QACE,eAAA,EAAiB,CAAC,IAAA,EAAM,KAAA,KAAU;AAChC,UAAA,MAAM,GAAA,GAAM,KAAA,GAAQ,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,IAAA,CAAK,KAAA,CAAO,IAAA,GAAO,KAAA,GAAS,GAAG,CAAC,CAAA,GAAI,KAAA,CAAA;AACzE,UAAA,KAAA,EAAO,UAAA,GAAa;AAAA,YAClB,KAAA,EAAO,UAAA;AAAA,YACP,OAAA,EACE,KAAA,GAAQ,CAAA,GACJ,CAAA,oBAAA,EAAkB,IAAA,CAAK,cAAA,EAAgB,CAAA,CAAA,EAAI,KAAA,CAAM,cAAA,EAAgB,CAAA,CAAA,GACjE,qBAAA;AAAA,YACN;AAAA,WACD,CAAA;AAAA,QACH;AAAA;AACF,KACF;AACA,IAAA,KAAA,EAAO,UAAA,GAAa,EAAE,KAAA,EAAO,MAAA,EAAQ,SAAS,gDAAA,EAAwC,GAAA,EAAK,KAAK,CAAA;AAChG,IAAA,OAAO,OAAA;AAAA,EACT,SAAS,CAAA,EAAG;AACV,IAAA,MAAM,UAAU,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,OAAO,CAAC,CAAA;AACzD,IAAA,KAAA,EAAO,UAAA,GAAa;AAAA,MAClB,KAAA,EAAO,OAAA;AAAA,MACP,OAAA,EAAS,iCAAiC,OAAO,CAAA;AAAA,KAClD,CAAA;AACD,IAAA,MAAM,CAAA;AAAA,EACR;AACF","file":"chunk-L2OS4WHT.js","sourcesContent":["/**\n * Ensure a code map exists before VG Code (or any host) starts work.\n *\n * Interactive CLI, `vg code --stream-json`, and VS Code all share this path so\n * the first turn never fails with \"no map found\" — we build once (with progress\n * callbacks for host UIs) and then proceed.\n */\n\nimport { loadGraph } from '../engine/load.js';\nimport { runBuild } from '../commands/build.js';\nimport type { GlobalOpts } from '../cli-options.js';\n\nexport type EnsureMapPhase = 'start' | 'progress' | 'done' | 'error';\n\nexport interface EnsureMapProgress {\n phase: EnsureMapPhase;\n message: string;\n /** 0–100 when known (parse phase); omitted when indeterminate. */\n pct?: number;\n}\n\nexport interface EnsureMapHooks {\n onProgress?: (p: EnsureMapProgress) => void;\n}\n\n/**\n * @returns `ready` when a map already existed; `built` when this call built one.\n */\nexport async function ensureCodeMap(\n root: string,\n global: GlobalOpts,\n hooks?: EnsureMapHooks,\n): Promise<'ready' | 'built'> {\n if (loadGraph(root, global.graph)) return 'ready';\n\n hooks?.onProgress?.({\n phase: 'start',\n message: 'Building the code map for this project… (first run only)',\n pct: 0,\n });\n\n try {\n await runBuild(\n [root],\n { html: false, report: false },\n { ...global, quiet: true },\n {\n onParseProgress: (done, total) => {\n const pct = total > 0 ? Math.min(99, Math.round((done / total) * 100)) : undefined;\n hooks?.onProgress?.({\n phase: 'progress',\n message:\n total > 0\n ? `Parsing files… ${done.toLocaleString()}/${total.toLocaleString()}`\n : 'Parsing files…',\n pct,\n });\n },\n },\n );\n hooks?.onProgress?.({ phase: 'done', message: 'Code map ready — starting your task…', pct: 100 });\n return 'built';\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n hooks?.onProgress?.({\n phase: 'error',\n message: `Could not build the code map: ${message}`,\n });\n throw e;\n }\n}\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { vgdIsRunning, vgdRequest } from './chunk-E53WBVUQ.js';
|
|
2
|
+
|
|
3
|
+
// src/runtime/vgd/publish.ts
|
|
4
|
+
async function publishGraphToVgd(root, options = {}) {
|
|
5
|
+
const { socketPath } = options;
|
|
6
|
+
const isRunning = options.isRunning ?? vgdIsRunning;
|
|
7
|
+
const request = options.request ?? vgdRequest;
|
|
8
|
+
try {
|
|
9
|
+
if (!await isRunning({ socketPath })) return { status: "not-running" };
|
|
10
|
+
const loaded = await request(
|
|
11
|
+
{ op: "load-graph", root, gitRef: options.gitRef, graphPath: options.graphPath },
|
|
12
|
+
{ socketPath }
|
|
13
|
+
);
|
|
14
|
+
if (!loaded.ok) return { status: "failed", error: loaded.error };
|
|
15
|
+
if (!("stored" in loaded)) return { status: "failed", error: "vgd did not store the map" };
|
|
16
|
+
let semantic;
|
|
17
|
+
if (options.warmSemantic) {
|
|
18
|
+
const indexed = await request(
|
|
19
|
+
{ op: "embed-index", repositoryId: loaded.repositoryId, gitRef: loaded.gitRef },
|
|
20
|
+
{ socketPath }
|
|
21
|
+
).catch((e) => ({ ok: false, error: e instanceof Error ? e.message : String(e) }));
|
|
22
|
+
if (indexed.ok && "state" in indexed) semantic = indexed.state;
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
status: "published",
|
|
26
|
+
repositoryId: loaded.repositoryId,
|
|
27
|
+
gitRef: loaded.gitRef,
|
|
28
|
+
nodeCount: loaded.nodeCount,
|
|
29
|
+
semantic
|
|
30
|
+
};
|
|
31
|
+
} catch (e) {
|
|
32
|
+
return { status: "failed", error: e instanceof Error ? e.message : String(e) };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { publishGraphToVgd };
|
|
37
|
+
//# sourceMappingURL=chunk-LJSJX6U4.js.map
|
|
38
|
+
//# sourceMappingURL=chunk-LJSJX6U4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/vgd/publish.ts"],"names":[],"mappings":";;;AA2CA,eAAsB,iBAAA,CAAkB,IAAA,EAAc,OAAA,GAA6B,EAAC,EAA+B;AACjH,EAAA,MAAM,EAAE,YAAW,GAAI,OAAA;AACvB,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,YAAA;AACvC,EAAA,MAAM,OAAA,GAAU,QAAQ,OAAA,IAAW,UAAA;AACnC,EAAA,IAAI;AACF,IAAA,IAAI,CAAE,MAAM,SAAA,CAAU,EAAE,UAAA,EAAY,CAAA,EAAI,OAAO,EAAE,MAAA,EAAQ,aAAA,EAAc;AAEvE,IAAA,MAAM,SAAS,MAAM,OAAA;AAAA,MACnB,EAAE,IAAI,YAAA,EAAc,IAAA,EAAM,QAAQ,OAAA,CAAQ,MAAA,EAAQ,SAAA,EAAW,OAAA,CAAQ,SAAA,EAAU;AAAA,MAC/E,EAAE,UAAA;AAAW,KACf;AACA,IAAA,IAAI,CAAC,OAAO,EAAA,EAAI,OAAO,EAAE,MAAA,EAAQ,QAAA,EAAU,KAAA,EAAO,MAAA,CAAO,KAAA,EAAM;AAC/D,IAAA,IAAI,EAAE,YAAY,MAAA,CAAA,EAAS,OAAO,EAAE,MAAA,EAAQ,QAAA,EAAU,OAAO,2BAAA,EAA4B;AAEzF,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI,QAAQ,YAAA,EAAc;AACxB,MAAA,MAAM,UAAU,MAAM,OAAA;AAAA,QACpB,EAAE,IAAI,aAAA,EAAe,YAAA,EAAc,OAAO,YAAA,EAAc,MAAA,EAAQ,OAAO,MAAA,EAAO;AAAA,QAC9E,EAAE,UAAA;AAAW,OACf,CAAE,KAAA,CAAM,CAAC,CAAA,MAAgB,EAAE,EAAA,EAAI,KAAA,EAAgB,KAAA,EAAO,CAAA,YAAa,QAAQ,CAAA,CAAE,OAAA,GAAU,MAAA,CAAO,CAAC,GAAE,CAAE,CAAA;AACnG,MAAA,IAAI,OAAA,CAAQ,EAAA,IAAM,OAAA,IAAW,OAAA,aAAoB,OAAA,CAAQ,KAAA;AAAA,IAC3D;AACA,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,WAAA;AAAA,MACR,cAAc,MAAA,CAAO,YAAA;AAAA,MACrB,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB;AAAA,KACF;AAAA,EACF,SAAS,CAAA,EAAG;AACV,IAAA,OAAO,EAAE,MAAA,EAAQ,QAAA,EAAU,KAAA,EAAO,CAAA,YAAa,QAAQ,CAAA,CAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAA,EAAE;AAAA,EAC/E;AACF","file":"chunk-LJSJX6U4.js","sourcesContent":["import { vgdIsRunning, vgdRequest } from './client.js';\n\nexport type VgdPublishOutcome =\n | { status: 'not-running' }\n | { status: 'failed'; error: string }\n /** The daemon already holds this exact map — nothing was sent. */\n | { status: 'current'; repositoryId: string; gitRef: string }\n | { status: 'published'; repositoryId: string; gitRef: string; nodeCount: number; semantic?: string };\n\nexport interface VgdPublishOptions {\n /** Override socket path (tests). */\n socketPath?: string;\n /** Branch / detached SHA this map describes; the daemon detects it otherwise. */\n gitRef?: string;\n /** Custom `--graph` artifact, when the map is not at its default location. */\n graphPath?: string;\n /**\n * Also wait for the slot's semantic index. Off by default: publishing already\n * queues a background warm, and a build should not block on embedding.\n */\n warmSemantic?: boolean;\n /** Injected transport (tests). */\n isRunning?: typeof vgdIsRunning;\n request?: typeof vgdRequest;\n}\n\n/**\n * Hand a freshly-built code map to a vgd that is **already** running.\n *\n * Without this the daemon only ever learned about a repo through `vg code`, so\n * an ordinary `vg build` left it reporting `0 graph slot(s)` — and because the\n * semantic index hangs off the graph slot, the index never warmed either. The\n * daemon looked idle on a machine that had just spent ten seconds building the\n * very map it was supposed to be holding.\n *\n * `load-graph` rather than `put-graph`: the daemon reads the snapshot from\n * disk itself (binary sidecar when fresh), so a 40k-node map never crosses the\n * socket as one multi-MB JSON line. Storing it runs the registry's slot funnel,\n * which invalidates and re-warms the semantic index for exactly that slot.\n *\n * Never starts a daemon, never throws, and never changes the command's exit\n * status: a machine with no vgd is a supported configuration, not an error.\n */\nexport async function publishGraphToVgd(root: string, options: VgdPublishOptions = {}): Promise<VgdPublishOutcome> {\n const { socketPath } = options;\n const isRunning = options.isRunning ?? vgdIsRunning;\n const request = options.request ?? vgdRequest;\n try {\n if (!(await isRunning({ socketPath }))) return { status: 'not-running' };\n\n const loaded = await request(\n { op: 'load-graph', root, gitRef: options.gitRef, graphPath: options.graphPath },\n { socketPath },\n );\n if (!loaded.ok) return { status: 'failed', error: loaded.error };\n if (!('stored' in loaded)) return { status: 'failed', error: 'vgd did not store the map' };\n\n let semantic: string | undefined;\n if (options.warmSemantic) {\n const indexed = await request(\n { op: 'embed-index', repositoryId: loaded.repositoryId, gitRef: loaded.gitRef },\n { socketPath },\n ).catch((e: unknown) => ({ ok: false as const, error: e instanceof Error ? e.message : String(e) }));\n if (indexed.ok && 'state' in indexed) semantic = indexed.state;\n }\n return {\n status: 'published',\n repositoryId: loaded.repositoryId,\n gitRef: loaded.gitRef,\n nodeCount: loaded.nodeCount,\n semantic,\n };\n } catch (e) {\n return { status: 'failed', error: e instanceof Error ? e.message : String(e) };\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { cosine } from './chunk-
|
|
2
|
-
import { bigramConsumedTokens, WEAK_TERMS, expandConcepts } from './chunk-
|
|
1
|
+
import { cosine } from './chunk-2C33WR5O.js';
|
|
2
|
+
import { bigramConsumedTokens, WEAK_TERMS, expandConcepts } from './chunk-VMAIDM4K.js';
|
|
3
3
|
|
|
4
4
|
// src/engine/relations.ts
|
|
5
5
|
var GraphIndex = class {
|
|
@@ -274,7 +274,7 @@ async function queryGraphSemantic(graph, question, options) {
|
|
|
274
274
|
const terms = prep.terms.map((t) => t.term);
|
|
275
275
|
const weightOf = termWeights(graph, terms);
|
|
276
276
|
const index = indexFor(graph);
|
|
277
|
-
const queryVec = await options.embedder
|
|
277
|
+
const queryVec = options.semanticRanked ? null : await options.embedder?.embedQuery(forTokens || question);
|
|
278
278
|
const lexRaw = /* @__PURE__ */ new Map();
|
|
279
279
|
const whyById = /* @__PURE__ */ new Map();
|
|
280
280
|
if (prep.hasContent) {
|
|
@@ -292,10 +292,16 @@ async function queryGraphSemantic(graph, question, options) {
|
|
|
292
292
|
for (const node of graph.nodes) {
|
|
293
293
|
if (node.kind === "file" || node.kind === "external") continue;
|
|
294
294
|
nodeById.set(node.id, node);
|
|
295
|
-
|
|
295
|
+
if (options.semanticRanked || !queryVec) continue;
|
|
296
|
+
const vec = options.nodeVectors?.get(node.id);
|
|
296
297
|
const sem = vec && terms.length > 0 ? Math.max(0, cosine(queryVec, vec)) : 0;
|
|
297
298
|
if (sem > 0) semRaw.set(node.id, sem);
|
|
298
299
|
}
|
|
300
|
+
if (options.semanticRanked && terms.length > 0) {
|
|
301
|
+
for (const { id, score } of options.semanticRanked) {
|
|
302
|
+
if (score > 0 && nodeById.has(id)) semRaw.set(id, score);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
299
305
|
const nameOf = (id) => nodeById.get(id)?.qualifiedName ?? id;
|
|
300
306
|
const lexRanks = ranksOf(lexRaw, nameOf);
|
|
301
307
|
const semRanks = ranksOf(semRaw, nameOf);
|
|
@@ -689,5 +695,5 @@ function round2(x) {
|
|
|
689
695
|
}
|
|
690
696
|
|
|
691
697
|
export { GraphIndex, conceptMapLines, extractLiteralNeedles, identifierParts, impactOf, indexFor, isLocateOnlyInstruction, queryGraph, queryGraphSemantic, residualForSymbolSearch, userAskFromInstruction };
|
|
692
|
-
//# sourceMappingURL=chunk-
|
|
693
|
-
//# sourceMappingURL=chunk-
|
|
698
|
+
//# sourceMappingURL=chunk-MRZHNUN7.js.map
|
|
699
|
+
//# sourceMappingURL=chunk-MRZHNUN7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/engine/relations.ts","../src/engine/user-ask.ts","../src/engine/query.ts","../src/engine/impact.ts"],"names":["push","l","v","affinity","text","round"],"mappings":"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","file":"chunk-MRZHNUN7.js","sourcesContent":["import type { EdgeKind, GraphEdge, GraphNode, VgGraph } from '../schema.js';\n\n/** Indexes over a graph for O(1) neighbor lookups (built once per command). */\nexport class GraphIndex {\n readonly nodeById = new Map<string, GraphNode>();\n private outById = new Map<string, GraphEdge[]>();\n private inById = new Map<string, GraphEdge[]>();\n\n constructor(readonly graph: VgGraph) {\n for (const n of graph.nodes) this.nodeById.set(n.id, n);\n for (const e of graph.edges) {\n push(this.outById, e.src, e);\n push(this.inById, e.dst, e);\n }\n }\n\n out(id: string, kind?: EdgeKind): GraphEdge[] {\n const all = this.outById.get(id) ?? [];\n return kind ? all.filter((e) => e.kind === kind) : all;\n }\n\n in(id: string, kind?: EdgeKind): GraphEdge[] {\n const all = this.inById.get(id) ?? [];\n return kind ? all.filter((e) => e.kind === kind) : all;\n }\n\n node(id: string): GraphNode | undefined {\n return this.nodeById.get(id);\n }\n\n /**\n * Resolved nodes called by `id` — invocations (`call`) plus structural\n * dependency references (`references`, e.g. a constructor-injected field's\n * type), since both represent real usage a caller/impact question cares\n * about. `references` is otherwise only emitted by the precise SCIP/tsc\n * rungs and (for Java DI wiring) the heuristic rung — never a guess.\n */\n callees(id: string): { edge: GraphEdge; node: GraphNode }[] {\n return this.resolveTargets(this.out(id).filter(isUsageEdge), 'dst');\n }\n\n /** Resolved nodes that call or structurally reference `id`. */\n callers(id: string): { edge: GraphEdge; node: GraphNode }[] {\n return this.resolveTargets(this.in(id).filter(isUsageEdge), 'src');\n }\n\n private resolveTargets(edges: GraphEdge[], end: 'src' | 'dst') {\n const out: { edge: GraphEdge; node: GraphNode }[] = [];\n for (const e of edges) {\n const node = this.nodeById.get(e[end]);\n if (node) out.push({ edge: e, node });\n }\n return out;\n }\n}\n\nconst USAGE_KINDS: ReadonlySet<EdgeKind> = new Set(['call', 'references']);\nfunction isUsageEdge(e: GraphEdge): boolean {\n return USAGE_KINDS.has(e.kind);\n}\n\nfunction push(map: Map<string, GraphEdge[]>, key: string, value: GraphEdge): void {\n const list = map.get(key);\n if (list) list.push(value);\n else map.set(key, [value]);\n}\n\n/**\n * Memoized `GraphIndex`, keyed on the graph object's identity.\n *\n * The index (node-by-id + in/out adjacency) is a pure function of the graph's\n * content, and every read path rebuilds it from scratch — an O(nodes + edges)\n * pass that, on a large map, costs hundreds of milliseconds *per query*. Under\n * `vg serve` the same parsed graph object is reused across many tool calls\n * (`GraphSource` caches it by file mtime and only replaces the reference when\n * `graph.json` actually changes), so rebuilding the index on every call is pure\n * waste. Keying a `WeakMap` on that object identity builds the index once and\n * reuses it until the file is rebuilt — at which point `GraphSource` hands back a\n * *new* object, this map misses, and the stale index is collected with the old\n * graph. Correct and stale-safe by construction: a different graph is a\n * different object, so there is no cross-graph reuse and nothing to invalidate.\n *\n * `GraphIndex` is read-only (no method mutates its maps), so sharing one\n * instance across callers is safe.\n */\nconst INDEX_CACHE = new WeakMap<VgGraph, GraphIndex>();\n\nexport function indexFor(graph: VgGraph): GraphIndex {\n let idx = INDEX_CACHE.get(graph);\n if (!idx) {\n idx = new GraphIndex(graph);\n INDEX_CACHE.set(graph, idx);\n }\n return idx;\n}\n","/**\n * Split the user's ask from host-injected attachment metadata.\n *\n * The VS Code panel (`codeAttachments.ts`) and other hosts append a markdown\n * block after a `---` fence:\n *\n * ## User attachments (always include in your reasoning for this turn)\n * ### Attached image: `image.png`\n * … saved at: `.vibgrate/code-attachments/…`\n *\n * Those backticks are for the model. If the full instruction is fed into\n * {@link extractLiteralNeedles} / seed ranking, attachment basenames and paths\n * become **literal-locate hard constraints** (\"0 hits → finish, do not invent\n * an edit\") and the agent aborts a real coding task. Field report: version-badge\n * health UI with a screenshot — agent searched for `image.png` and stopped.\n *\n * Retrieval, needle pinning, locate-only detection, and relevance analysis must\n * use {@link userAskFromInstruction}. The full instruction (with attachments)\n * still belongs in the Task / user message so the model can see the appendix.\n */\n\n/** Heading written by hosts when packing panel attachments into the instruction. */\nexport const USER_ATTACHMENTS_HEADING_PREFIX = '## User attachments';\n\n/**\n * Return only the user-authored portion of an instruction, dropping a trailing\n * host \"User attachments\" appendix when present. Unchanged when no appendix.\n */\nexport function userAskFromInstruction(instruction: string): string {\n if (!instruction) return instruction;\n\n // Canonical host shape: blank line, --- fence, then the attachments heading.\n const fenced = /\\n---\\s*\\n## User attachments\\b[^\\n]*\\n?/;\n const m = fenced.exec(instruction);\n if (m && m.index != null) {\n return instruction.slice(0, m.index).trimEnd();\n }\n\n // Defensive: heading without the fence (older hosts / hand-edited prompts).\n const bare = instruction.search(/(?:^|\\n)## User attachments\\b/);\n if (bare > 0) {\n return instruction.slice(0, bare).trimEnd();\n }\n if (bare === 0) {\n // Instruction is only the appendix — no user ask left.\n return '';\n }\n\n return instruction;\n}\n","import { indexFor, type GraphIndex } from './relations.js';\nimport { cosine, type Embedder } from './embeddings.js';\nimport { WEAK_TERMS, expandConcepts, bigramConsumedTokens } from './concepts.js';\nimport type { RelevanceAnalysis } from './relevance-provider.js';\nimport type { GraphNode, VgGraph } from '../schema.js';\nimport { userAskFromInstruction } from './user-ask.js';\n\n/**\n * Deterministic retrieval for `vg ask` (VG-CLI-SPEC §3.2).\n *\n * Builds a structured, fact-annotated, budget-bounded context block for a\n * question — designed to drop straight into an assistant's context. The default\n * is deterministic lexical+structural retrieval: identifier/term matching with\n * morphological prefix-fuzzing, term-role weighting (process verbs like \"add\"\n * only corroborate, never seed — see engine/concepts.ts), static concept\n * expansion (\"payments\" → stripe/billing/…, \"direct debit\" → sepa/bacs/mandate),\n * and a multi-term coverage bonus, ranked with importance as a mild tiebreaker.\n * `--semantic`/`--deep` adds\n * a hybrid local-embedding pass (`queryGraphSemantic`) that surfaces conceptually\n * related code even when no word is shared — still no API key.\n */\n\nexport interface QueryOptions {\n budget?: number; // approx token budget for the context block (default 2000)\n limit?: number; // max seed matches to expand (default 12)\n /** Optional pre-computed relevance analysis (engine/relevance-provider.ts).\n * Injected by async callers so this module stays pure and sync; when\n * absent, ranking is exactly the built-in lexicon path. */\n relevance?: RelevanceAnalysis | null;\n /** Optional per-node topic tags (engine/relevance-enrich.ts). Combined with\n * `relevance.topics` into a bounded affinity bonus: a node structurally\n * tagged with a topic the question is about ranks above an equal textual\n * match outside it. Never seeds alone — it multiplies existing evidence. */\n topicTags?: Map<string, readonly string[]> | null;\n /** Previous conversational ask (multi-turn `vg code`). Its content terms —\n * never its process verbs — join ranking at a damped weight (CARRY_WEIGHT)\n * so a follow-up like \"can we use direct debits?\" keeps the prior turn's\n * topic (\"where is stripe used?\") instead of ranking the repo on the\n * follow-up's words alone. Absent → behaviour is unchanged. */\n priorQuestion?: string | null;\n}\n\nexport interface QueryMatch {\n node: GraphNode;\n score: number;\n why: string;\n}\n\nexport interface QueryResult {\n question: string;\n matches: QueryMatch[];\n context: string;\n tokensEstimate: number;\n}\n\nconst STOPWORDS = new Set([\n 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'to', 'of', 'in', 'on', 'for', 'and', 'or',\n 'where', 'what', 'which', 'how', 'do', 'does', 'did', 'i', 'we', 'it', 'this', 'that', 'with',\n 'when', 'who', 'why', 'can', 'should', 'my', 'our', 'you', 'your', 'from', 'by', 'at', 'as',\n // Discovery-question scaffolding: words a caller uses to FRAME the ask\n // (\"find the code responsible for X\", \"I need to modify X, where do I\n // start?\", \"explain how X works in this codebase\") rather than to name the\n // target. Left in, these compete on equal footing with the real identifier\n // terms and can outrank it outright — e.g. \"find the code responsible for\n // deleteAsync\" let \"find\" alone drag in every FindByIdAsync/FindAll method\n // in the repo, none of them the target (VG-LOCATE-FAILURE-ANALYSIS.md).\n 'find', 'code', 'responsible', 'need', 'modify', 'me',\n 'implementation', 'explain', 'works', 'codebase', 'contains', 'file',\n // String/URL occurrence scaffolding: \"does not exist\", \"find occurrences of …\"\n // must not light up DoesNot*/NonExisting*/commandExists via weak substrings\n // (field report: https://…/signup does not exist find occurrences).\n 'not', 'no', 'exist', 'exists', 'existing', 'occurrence', 'occurrences',\n 'occurence', 'occurences', 'every', 'place', 'places', 'string', 'literal',\n 'text', 'search', 'locate', 'look', 'looking', 'show', 'list', 'all',\n]);\n\n/**\n * Strip sentence punctuation from a URL match without breaking real query\n * strings (`?key=value`). A lone trailing `?` / `!` is English punctuation\n * (\"where is https://…/signup?\") — leaving it in the needle makes the literal\n * sweep miss the bare path in source.\n */\nfunction cleanUrlNeedle(raw: string): string {\n let s = raw.trim();\n // Trailing ) ] } > , ; : ! . from markdown links / sentence ends.\n s = s.replace(/[.,;:!)\\]}>]+$/g, '');\n // Lone trailing `?` → drop. Keep `?key=…` (content after `?`).\n if (s.endsWith('?')) {\n const qi = s.lastIndexOf('?');\n if (qi === s.length - 1) s = s.slice(0, -1);\n }\n return s;\n}\n\n/**\n * Extract string/URL needles a caller is asking to *locate as text*, not as\n * bag-of-words symbol terms. URLs and quoted phrases are exact-match material\n * for the literal sweep (`search_symbols` / `search_code`); feeding their path\n * segments into lexical symbol ranking produces confidently wrong seeds\n * (dash → dashboard package, exist → NonExisting, …).\n */\nexport function extractLiteralNeedles(question: string): string[] {\n const out: string[] = [];\n const seen = new Set<string>();\n const push = (raw: string, kind: 'url' | 'quote') => {\n let s = raw.trim();\n s = kind === 'url' ? cleanUrlNeedle(s) : s.replace(/[.,;:!)\\]}>?]+$/g, '');\n if (s.length < 2 || seen.has(s)) return;\n seen.add(s);\n out.push(s);\n };\n for (const m of question.matchAll(/https?:\\/\\/[^\\s\"'`<>]+/gi)) push(m[0]!, 'url');\n for (const m of question.matchAll(/([\"'`])((?:(?!\\1)[^\\\\]|\\\\.){2,})\\1/g)) {\n push(m[2]!.replace(/\\\\(.)/g, '$1'), 'quote');\n }\n return out;\n}\n\n/** Question text with URL/quoted needles removed so residual tokens can name symbols. */\nexport function stripLiteralNeedles(question: string): string {\n let s = question;\n // Strip raw URL spans first (may still carry a trailing `?` from the ask).\n for (const m of question.matchAll(/https?:\\/\\/[^\\s\"'`<>]+/gi)) {\n s = s.split(m[0]!).join(' ');\n }\n for (const lit of extractLiteralNeedles(question)) {\n s = s.split(lit).join(' ');\n }\n // Also strip bare quote pairs left behind.\n s = s.replace(/([\"'`])\\s*\\1/g, ' ');\n return s.replace(/\\s+/g, ' ').trim();\n}\n\n/**\n * Residual ask used for graph symbol ranking when the question embeds a\n * URL/quote. Empty when only framing words remain (\"where is …?\") so we do\n * not light up unrelated symbols like `applyPlan.where`.\n */\nexport function residualForSymbolSearch(question: string): string {\n const literals = extractLiteralNeedles(question);\n if (literals.length === 0) return question.trim();\n const stripped = stripLiteralNeedles(question);\n return tokenize(stripped).length === 0 ? '' : stripped;\n}\n\n/**\n * True when the instruction is a string/URL occurrence locate (not an edit).\n * Used to skip PatchIR grammar and answer from the literal sweep without\n * dumping constrained-decoding JSON into the VG Code panel.\n */\nexport function isLocateOnlyInstruction(instruction: string): boolean {\n // Drop host-injected \"User attachments\" appendix (backticked image paths)\n // before classify — same rule as buildCodeContext. Avoids treating a screenshot\n // filename as a locate-only occurrence search.\n const q = userAskFromInstruction(instruction).trim();\n if (!q) return false;\n const needles = extractLiteralNeedles(q);\n const hasLocateFrame =\n /\\b(where\\s+is|where\\s+are|find\\s+(all\\s+|every\\s+)?occurrence|find\\s+occurrences|does\\s+not\\s+exist|locate|search\\s+for)\\b/i.test(\n q,\n ) ||\n (needles.length > 0 && /^https?:\\/\\//i.test(q));\n // Strong edit verbs cancel locate-only (ignore \"does not exist\" as non-edit).\n const withoutExist = q.replace(/\\bdoes\\s+not\\s+exist\\b/gi, ' ');\n if (\n /\\b(fix|edit|change|replace|implement|refactor|rename|patch|create\\s+file|delete\\s+file|add\\s+a\\b|remove\\s+the\\b)\\b/i.test(\n withoutExist,\n )\n ) {\n return false;\n }\n if (needles.some((n) => /^https?:\\/\\//i.test(n))) return true;\n return hasLocateFrame && needles.length > 0;\n}\n\nexport function queryGraph(graph: VgGraph, question: string, options: QueryOptions = {}): QueryResult {\n const budget = options.budget ?? 2000;\n const limit = options.limit ?? 12;\n // When the ask embeds a URL or quoted string, score symbols only on the\n // residual framing text. Empty residual → empty matches (honest miss) rather\n // than path-token false positives that poison Task Capsules.\n const literals = extractLiteralNeedles(question);\n const forTokens = literals.length > 0 ? stripLiteralNeedles(question) : question;\n const prep = prepareTerms(forTokens, options.relevance, priorResidual(options.priorQuestion));\n const weightOf = termWeights(graph, prep.terms.map((t) => t.term));\n const index = indexFor(graph);\n\n const scored: QueryMatch[] = [];\n // Two honest-miss paths: literal-only locate (no identifier terms after\n // stripping needles) and weak-only asks (\"add a new feature\") whose every\n // term is a process verb — seeding those from `add*`/`create*` surface\n // matches is exactly the capsule-poisoning failure (field report 2026-07).\n if (prep.hasContent) {\n for (const node of graph.nodes) {\n if (node.kind === 'file' || node.kind === 'external') continue;\n const { score, why } = scoreNode(node, prep.terms, weightOf);\n if (score > 0) {\n const affinity = topicAffinity(node.id, options.relevance, options.topicTags);\n scored.push({\n node,\n score: round(score * affinity.boost * (1 + IMPORTANCE_WEIGHT * node.importance)),\n why: why + affinity.label,\n });\n }\n }\n scored.sort((a, b) => b.score - a.score || a.node.qualifiedName.localeCompare(b.node.qualifiedName));\n }\n\n const seeds = scored.slice(0, limit);\n const { context, tokensEstimate } = buildContext(graph, index, question, seeds, budget, literals);\n\n return { question, matches: seeds, context, tokensEstimate };\n}\n\nexport interface SemanticQueryOptions extends QueryOptions {\n /** Local embedder. Optional only when {@link semanticRanked} supplies the pass. */\n embedder?: Embedder;\n /** Precomputed node vectors (from getNodeEmbeddings); falls back to lexical for nodes without one. */\n nodeVectors?: Map<string, number[]>;\n /**\n * A semantic pass someone else already ran — vgd ranking the question\n * against its resident slot index. Supplied instead of `embedder` +\n * `nodeVectors` so the caller pays neither a model load nor a vector scan,\n * and no vectors cross the socket.\n *\n * Only the ORDER of this list is consumed (RRF fuses rankings, not scores),\n * so a truncated top-K is not an approximation: a candidate ranked past a\n * few hundred cannot reach a 12-row answer.\n */\n semanticRanked?: Array<{ id: string; score: number }>;\n}\n\n/**\n * Reciprocal Rank Fusion constant (the standard k=60). Fusing RANKINGS\n * instead of blending raw scores removes the need to calibrate two\n * incomparable scales (tiered lexical evidence vs cosine similarity): a node's\n * fused score is Σ 1/(k + rankᵢ) over the lists it appears in, so agreement\n * between signals dominates and a single signal's outlier magnitude cannot.\n */\nconst RRF_K = 60;\n\n/** 1-based ranks for a scored id list (desc score, qualifiedName tiebreak). */\nfunction ranksOf(scores: Map<string, number>, nameOf: (id: string) => string): Map<string, number> {\n const ids = [...scores.entries()]\n .filter(([, s]) => s > 0)\n .sort((a, b) => b[1] - a[1] || nameOf(a[0]).localeCompare(nameOf(b[0])))\n .map(([id]) => id);\n return new Map(ids.map((id, i) => [id, i + 1]));\n}\n\n/**\n * Hybrid lexical + local-embedding retrieval, combined with Reciprocal Rank\n * Fusion (Phase 3.2 — replaces the former 50/50 score blend), so a question\n * like \"where do we handle auth failures?\" can surface `verify_token` even\n * with no shared identifier. Topic affinity and importance stay multiplicative\n * tiebreakers on the fused score. Deterministic given the same model + cached\n * vectors; embeddings live in a binary sidecar next to the map, never in `graph.json`.\n */\nexport async function queryGraphSemantic(\n graph: VgGraph,\n question: string,\n options: SemanticQueryOptions,\n): Promise<QueryResult> {\n const budget = options.budget ?? 2000;\n const limit = options.limit ?? 12;\n const literals = extractLiteralNeedles(question);\n const forTokens = literals.length > 0 ? stripLiteralNeedles(question) : question;\n const prep = prepareTerms(forTokens, options.relevance, priorResidual(options.priorQuestion));\n const terms = prep.terms.map((t) => t.term);\n const weightOf = termWeights(graph, terms);\n const index = indexFor(graph);\n // Embed the residual ask (without URL/quote noise) so semantic neighbours\n // aren't dragged toward package names that share host path segments. Skipped\n // entirely when the ranking arrives pre-computed (vgd already embedded it).\n const queryVec = options.semanticRanked\n ? null\n : await options.embedder?.embedQuery(forTokens || question);\n\n // Raw lexical scores (pre-importance) — RRF consumes only their ORDER.\n // Weak-only asks get no lexical evidence (same suppression as queryGraph);\n // the semantic cosine below may still surface conceptual neighbours for them.\n const lexRaw = new Map<string, number>();\n const whyById = new Map<string, string>();\n if (prep.hasContent) {\n for (const node of graph.nodes) {\n if (node.kind === 'file' || node.kind === 'external') continue;\n const { score, why } = scoreNode(node, prep.terms, weightOf);\n lexRaw.set(node.id, score);\n whyById.set(node.id, why);\n }\n }\n\n const scored: QueryMatch[] = [];\n // Literal-only asks: skip the semantic loop entirely — embeddings over\n // \"does not exist find occurrences\" still surface unrelated hubs.\n if (terms.length > 0 || literals.length === 0) {\n // Independent per-signal rankings, then RRF.\n const semRaw = new Map<string, number>();\n const nodeById = new Map<string, GraphNode>();\n for (const node of graph.nodes) {\n if (node.kind === 'file' || node.kind === 'external') continue;\n nodeById.set(node.id, node);\n if (options.semanticRanked || !queryVec) continue;\n const vec = options.nodeVectors?.get(node.id);\n const sem = vec && terms.length > 0 ? Math.max(0, cosine(queryVec, vec)) : 0;\n if (sem > 0) semRaw.set(node.id, sem);\n }\n if (options.semanticRanked && terms.length > 0) {\n // Ignore ids the ranking knows about but this graph no longer has: the\n // daemon's index can be one publish behind a locally refreshed map.\n for (const { id, score } of options.semanticRanked) {\n if (score > 0 && nodeById.has(id)) semRaw.set(id, score);\n }\n }\n const nameOf = (id: string) => nodeById.get(id)?.qualifiedName ?? id;\n const lexRanks = ranksOf(lexRaw, nameOf);\n const semRanks = ranksOf(semRaw, nameOf);\n for (const [id, node] of nodeById) {\n const lr = lexRanks.get(id);\n const sr = semRanks.get(id);\n if (lr === undefined && sr === undefined) continue;\n const fused = (lr !== undefined ? 1 / (RRF_K + lr) : 0) + (sr !== undefined ? 1 / (RRF_K + sr) : 0);\n const sem = semRaw.get(id) ?? 0;\n const lexWhy = whyById.get(id);\n const affinity = topicAffinity(id, options.relevance, options.topicTags);\n const why = (lexWhy || (sem > 0.3 ? `semantic match (${sem.toFixed(2)})` : 'weak match')) + affinity.label;\n scored.push({ node, score: round(fused * affinity.boost * (1 + IMPORTANCE_WEIGHT * node.importance)), why });\n }\n scored.sort((a, b) => b.score - a.score || a.node.qualifiedName.localeCompare(b.node.qualifiedName));\n }\n\n const seeds = scored.slice(0, limit);\n const { context, tokensEstimate } = buildContext(graph, index, question, seeds, budget, literals);\n return { question, matches: seeds, context, tokensEstimate };\n}\n\n/**\n * Split on anything that isn't a Unicode letter/number (`\\p{L}\\p{N}`, not the\n * ASCII-only `[a-z0-9]`) so identifiers in non-Latin scripts (Japanese,\n * Cyrillic, ...) survive tokenization instead of vanishing entirely — the\n * ASCII-only split treated every character of e.g. `名前` as a separator,\n * producing zero terms and a guaranteed empty result for any question about\n * it (VG-LOCATE-FAILURE-ANALYSIS.md). Length floor is 1, not 2: a single\n * non-stopword letter/digit is still the whole identifier when that's genuinely\n * the symbol's name (adversarial fixtures deliberately use bare `f`/`x`/`h`\n * names to stress this) — STOPWORDS already screens out short function words.\n */\nfunction tokenize(q: string): string[] {\n return [\n ...new Set(\n q\n .toLowerCase()\n .split(/[^\\p{L}\\p{N}]+/u)\n .filter((t) => t.length >= 1 && !STOPWORDS.has(t)),\n ),\n ];\n}\n\n/** Ordered, lowercased token stream WITH stopwords — bigram concepts (\"sign in\",\n * \"direct debit\") need adjacency over the raw word order. */\nfunction tokenizeOrdered(q: string): string[] {\n return q\n .toLowerCase()\n .split(/[^\\p{L}\\p{N}]+/u)\n .filter((t) => t.length >= 1);\n}\n\n/**\n * A query term with its role resolved. Roles decide how much evidence a match\n * carries (see scoreNode):\n * - content — names the topic; full weight, counts toward coverage\n * - weak — process verb (\"add\", \"create\", \"via\"); down-weighted, can only\n * corroborate a content match, never carry a seed alone\n * - expansion — concept vocabulary from the lexicon (\"payments\"→\"stripe\");\n * reduced weight, counts as content evidence, provenance in `why`\n */\ninterface QueryTerm {\n term: string;\n weak: boolean;\n /** Source token/bigram when this term came from concept expansion. */\n from?: string;\n /** Provider-supplied confidence (0..1) when this term came from the optional\n * relevance provider; replaces the flat EXPANSION_WEIGHT for that term. */\n providerWeight?: number;\n /** True when this term was carried over from the previous conversational\n * turn (QueryOptions.priorQuestion); scores at CARRY_WEIGHT. */\n carried?: boolean;\n}\n\ninterface PreparedTerms {\n terms: QueryTerm[];\n /** True when at least one content or expansion term exists — the bar a\n * question must clear before ANY node may seed. */\n hasContent: boolean;\n}\n\n/** Weak process verbs corroborate at a fraction of a content term's weight. */\nconst WEAK_TERM_WEIGHT = 0.25;\n/** Concept expansions score below a literal question term of the same rarity. */\nconst EXPANSION_WEIGHT = 0.7;\n/** Per extra distinct content term matched, the multiplicative coverage bonus.\n * Multi-topic evidence (\"direct\" + \"debit\" + \"payments\") must beat any\n * single-term surface hit (\"add\") by construction, not by luck. */\nconst COVERAGE_BONUS = 0.35;\n/** Terms carried from the previous conversational turn score at half weight:\n * enough to keep a follow-up anchored to the conversation's topic (and to\n * rescue weak-only follow-ups like \"can we use it?\"), never enough for stale\n * context to outrank a clearly-named new topic in the current ask. */\nconst CARRY_WEIGHT = 0.5;\n\n/** Resolve term roles + concept expansions for the residual ask text. */\nfunction prepareTerms(forTokens: string, relevance?: RelevanceAnalysis | null, prior?: string | null): PreparedTerms {\n const base = tokenize(forTokens);\n const ordered = tokenizeOrdered(forTokens);\n const baseSet = new Set(base);\n // A token consumed by a fired bigram concept (\"direct\" in \"direct debits\")\n // is demoted to the weak role: the bigram's expansions carry the topic, and\n // the constituent alone is a distractor magnet (directGet, redirectUrl, …).\n const consumed = bigramConsumedTokens(ordered);\n const terms: QueryTerm[] = base.map((t) => ({ term: t, weak: WEAK_TERMS.has(t) || consumed.has(t) }));\n const have = new Set(base);\n for (const e of expandConcepts(ordered)) {\n if (baseSet.has(e.term)) continue;\n terms.push({ term: e.term, weak: false, from: e.from });\n have.add(e.term);\n }\n // Provider expansions (already sanitized by engine/relevance-provider.ts)\n // join as expansion-role terms with their own confidence weight. The\n // built-in lexicon wins ties: a term it already produced is not re-added,\n // so provider presence never changes the score of a lexicon-covered term.\n for (const e of relevance?.expansions ?? []) {\n if (have.has(e.term)) continue;\n terms.push({ term: e.term, weak: false, from: e.from, providerWeight: e.weight });\n have.add(e.term);\n }\n // Conversation carry-over: the previous turn's CONTENT terms (plus their\n // lexicon expansions) join at CARRY_WEIGHT. Weak process verbs from the\n // prior turn are dropped outright — carrying \"add\"/\"use\" forward would\n // re-open the grab-bag failure this module exists to prevent. A term the\n // current ask already produced is never re-added, so the current turn\n // always wins ties and single-turn behaviour is byte-identical.\n if (prior?.trim()) {\n const priorOrdered = tokenizeOrdered(prior);\n const priorConsumed = bigramConsumedTokens(priorOrdered);\n for (const t of tokenize(prior)) {\n if (have.has(t) || WEAK_TERMS.has(t) || priorConsumed.has(t)) continue;\n terms.push({ term: t, weak: false, carried: true });\n have.add(t);\n }\n for (const e of expandConcepts(priorOrdered)) {\n if (have.has(e.term)) continue;\n terms.push({ term: e.term, weak: false, from: e.from, carried: true });\n have.add(e.term);\n }\n }\n const hasContent = terms.some((t) => !t.weak);\n return { terms, hasContent };\n}\n\n/** Residual text of the previous ask, with URL/quoted needles stripped so a\n * pasted link in turn N-1 cannot poison turn N's carried vocabulary. */\nfunction priorResidual(prior: string | null | undefined): string | null {\n const raw = prior?.trim();\n if (!raw) return null;\n return extractLiteralNeedles(raw).length > 0 ? stripLiteralNeedles(raw) : raw;\n}\n\n/**\n * Plain-language concept map for one ask: how its words were interpreted —\n * fired concept/bigram expansions, relevance-kernel topics and vocabulary,\n * and terms carried from the previous conversational turn. Rendered into the\n * Task Capsule so a model (especially a small local one) can read the\n * inference chain (\"direct debits\" → debit/mandate/…; topic payments →\n * stripe/billing/…) as sentences instead of reverse-engineering the `a→b`\n * slugs in per-seed match provenance. Deterministic and bounded; empty when\n * nothing fired (honest-empty asks stay empty).\n */\nexport function conceptMapLines(\n question: string,\n relevance?: RelevanceAnalysis | null,\n priorQuestion?: string | null,\n): string[] {\n const cap = (xs: string[]) => [...new Set(xs)].slice(0, 8).join(', ');\n const literals = extractLiteralNeedles(question);\n const residual = literals.length > 0 ? stripLiteralNeedles(question) : question;\n const lines: string[] = [];\n\n // Lexicon / bigram expansions, grouped by the ask term that fired them.\n const byFrom = new Map<string, string[]>();\n for (const e of expandConcepts(tokenizeOrdered(residual))) {\n const list = byFrom.get(e.from) ?? [];\n list.push(e.term);\n byFrom.set(e.from, list);\n }\n for (const [from, terms] of byFrom) {\n lines.push(`- \"${from}\" in the ask implies these codebase identifiers: ${cap(terms)}.`);\n }\n\n // ---------------------------------------------------------------------\n // What the ask is about, deepest first.\n //\n // Order is the message. A reader (or a model) wants the most specific thing\n // first — \"cname\" — then the product that makes it concrete — \"cloudflare\" —\n // then the containing levels, widening out to \"infrastructure\". Files come\n // after that, because they are where to look once you know what you are\n // looking for. Corrections come last: they explain how the ask was read,\n // which only matters once the reading itself is on the page.\n // ---------------------------------------------------------------------\n const matches = relevance?.taxonomy ?? [];\n if (matches.length) {\n // Every matched level, deduped, deepest first. Ties keep provider order,\n // which is evidence-ranked.\n const seenPath = new Set<string>();\n const levels: Array<{ path: string; id: string; depth: number; terms: string[] }> = [];\n for (const m of matches) {\n for (const l of m.levels) {\n if (seenPath.has(l.path)) continue;\n seenPath.add(l.path);\n levels.push({ path: l.path, id: l.id, depth: l.path.split('/').length, terms: l.terms });\n }\n }\n const deepest = Math.max(...levels.map((l) => l.depth));\n const describe = (l: { id: string; terms: string[] }, lead: string) =>\n l.terms.length\n ? `${lead} ${l.id}; code for it typically uses: ${cap(l.terms)}.`\n : `${lead} ${l.id}.`;\n\n for (const l of levels.filter((l) => l.depth === deepest)) {\n lines.push(describe(l, '- The ask is specifically about'));\n }\n\n // The product named sits directly under the most specific topic — it is\n // what turns that topic into this codebase's version of it. When the\n // product IS the most specific topic, the line above already said so, and\n // only the typed form is worth adding.\n const deepestIds = new Set(levels.filter((l) => l.depth === deepest).map((l) => l.id));\n for (const v of (relevance?.vendors ?? []).filter((v) => v.score > 0).slice(0, 3)) {\n if (deepestIds.has(v.name)) {\n if (v.from !== v.name) lines.push(`- That product was typed \"${v.from}\".`);\n continue;\n }\n lines.push(\n v.from === v.name\n ? `- It names the product \"${v.name}\".`\n : `- It names the product \"${v.name}\" (typed \"${v.from}\").`,\n );\n }\n\n // Then widen, one level at a time — skipping any level the vendor line\n // already named, so a Cloudflare ask does not say \"cloudflare\" twice.\n const named = new Set((relevance?.vendors ?? []).map((v) => v.name));\n for (let d = deepest - 1; d >= 1; d--) {\n for (const l of levels.filter((l) => l.depth === d && !named.has(l.id))) {\n lines.push(describe(l, '- More broadly, this is'));\n }\n }\n } else if (relevance?.topics?.length) {\n // Provider without a taxonomy (or an older one): flat topics, as before.\n const topicVocab = new Map<string, string[]>();\n for (const e of relevance.expansions ?? []) {\n const list = topicVocab.get(e.from) ?? [];\n list.push(e.term);\n topicVocab.set(e.from, list);\n }\n for (const t of relevance.topics.slice(0, 3)) {\n const vocab = topicVocab.get(t.id);\n lines.push(\n vocab?.length\n ? `- The ask is about the \"${t.id}\" domain; code for it typically uses: ${cap(vocab)}.`\n : `- The ask is about the \"${t.id}\" domain.`,\n );\n }\n }\n\n // What governs the work, named at the revision the provider tracks. This is\n // the difference between \"this is accessibility work\" and \"this is\n // accessibility work, and WCAG 2.2 is what it has to satisfy\".\n const standards = relevance?.standards ?? [];\n if (standards.length) {\n const specs = standards.filter((st) => st.kind !== 'regulation');\n const rules = standards.filter((st) => st.kind === 'regulation');\n const render = (list: typeof standards) =>\n list\n .slice(0, 3)\n .map((st) => (st.publisher ? `${st.name} (${st.publisher})` : st.name))\n .join('; ');\n // A spec and a legal duty are not the same obligation, so they are not\n // pooled into one sentence.\n if (specs.length) lines.push(`- Standards that govern this area: ${render(specs)}.`);\n if (rules.length) lines.push(`- Regulations that apply here: ${render(rules)}.`);\n }\n\n // The site's own category slugs for everything above, so a reader (or a\n // lookup) can cross-reference content by the same key.\n const categories = relevance?.categories ?? [];\n if (categories.length) {\n lines.push(`- Related categories: ${cap(categories)}.`);\n }\n\n // Where that work usually lives — the concrete lead, after the abstract one.\n const fileHints = relevance?.files ?? [];\n if (fileHints.length) {\n lines.push(`- Files for this kind of work are usually named or extended: ${cap(fileHints)}.`);\n }\n\n // How the ask was read, if it was read as something other than typed.\n for (const c of (relevance?.corrections ?? []).slice(0, 3)) {\n lines.push(`- Read \"${c.from}\" in the ask as \"${c.to}\".`);\n }\n\n // Conversation carry-over provenance.\n const priorText = priorResidual(priorQuestion);\n if (priorText) {\n const current = new Set(tokenize(residual));\n const consumed = bigramConsumedTokens(tokenizeOrdered(priorText));\n const carried = tokenize(priorText).filter((t) => !current.has(t) && !WEAK_TERMS.has(t) && !consumed.has(t));\n if (carried.length) {\n lines.push(`- This is a follow-up; topic words carried from the previous ask: ${cap(carried)}.`);\n }\n }\n\n if (lines.length) {\n lines.push(\n '- Seed notation below: `a→b` = ask term \"a\" implied identifier \"b\"; `~t` = word-form match; `↩t` = carried from the previous ask.',\n );\n }\n return lines;\n}\n\nfunction scoreNode(node: GraphNode, terms: QueryTerm[], weightOf: (t: string) => number = () => 1): { score: number; why: string } {\n let score = 0;\n let contentHits = 0;\n const hits: string[] = [];\n const name = node.name.toLowerCase();\n const qn = node.qualifiedName.toLowerCase();\n const file = node.file.toLowerCase();\n // Directory segments of the file path: a term naming a whole directory\n // (\"payments\" → src/payments/…) is domain evidence, stronger than an\n // incidental substring somewhere in the path.\n const dirSegments = new Set(file.split('/').slice(0, -1));\n // Split the ORIGINAL name on camelCase / snake_case, then lowercase the parts\n // (splitting must see the capitals, so it happens before lowercasing).\n const nameParts = identifierParts(node.name);\n for (const { term: t, weak, from, providerWeight, carried } of terms) {\n // Each term's contribution is weighted by its specificity (IDF over symbol\n // names): a match on a distinctive term (\"toComparable\", \"layoutFor\") counts\n // for more than a match on a term shared by hundreds of symbols (\"code\",\n // \"get\", \"run\"). Without this, an incidental exact-name hit on a common word\n // in a natural-language question outranked the conceptually-correct symbol,\n // and importance weighting amplified the wrong hit (VG-NAVIGATION trace).\n // Role multipliers stack on top: process verbs corroborate at a fraction,\n // concept expansions score below a literal term of the same rarity.\n // Expansion role multiplier: provider expansions carry their own 0..1\n // confidence (capped at the lexicon's EXPANSION_WEIGHT so an installed\n // provider can widen vocabulary but never outrank the reviewed lexicon's\n // evidence class); lexicon expansions keep the flat EXPANSION_WEIGHT.\n const expansionW = providerWeight !== undefined ? Math.min(providerWeight, EXPANSION_WEIGHT) : from ? EXPANSION_WEIGHT : 1;\n const w = weightOf(t) * (weak ? WEAK_TERM_WEIGHT : 1) * expansionW * (carried ? CARRY_WEIGHT : 1);\n const label = (carried ? '↩' : '') + (from ? `${from}→${t}` : t);\n let contribution = 0;\n if (name === t) {\n contribution = 10 * w;\n hits.push(label);\n } else if (nameParts.has(t)) {\n contribution = 6 * w;\n hits.push(label);\n } else if (name.includes(t)) {\n contribution = 4 * w;\n hits.push(label);\n } else if (qn.includes(t)) {\n contribution = 3 * w;\n hits.push(label);\n } else if (fuzzyPartMatch(t, nameParts)) {\n // Morphological / subword match: \"authentication\" ↔ \"authenticate\"\n // (shared prefix), so lexical ask survives word-form differences without\n // a model. The semantic path handles non-shared-root synonyms.\n contribution = 2 * w;\n hits.push((carried ? '↩' : '') + (from ? `~${from}→${t}` : `~${t}`));\n } else if (dirSegments.has(t)) {\n contribution = 2 * w;\n hits.push(label);\n } else if (file.includes(t)) {\n contribution = 1 * w;\n hits.push(label);\n }\n if (contribution > 0) {\n score += contribution;\n if (!weak) contentHits += 1;\n }\n }\n // A node whose only evidence is weak process verbs is noise by definition —\n // the `add`-grab-bag capsule failure. Suppress it outright: weak terms\n // corroborate content matches, they never carry a seed.\n if (contentHits === 0) return { score: 0, why: '' };\n // Reward multi-term topic coverage multiplicatively so converging evidence\n // (\"direct\" + \"debit\" + payments-expansion) dominates single-term hits.\n score *= 1 + COVERAGE_BONUS * Math.min(contentHits - 1, 4);\n return { score, why: hits.length ? `matched: ${hits.join(', ')}` : '' };\n}\n\n/**\n * Importance is a mild tiebreaker, not a doubling. The old `1 + importance`\n * let a hub (importance→1) double its score and outrank a stronger textual\n * match on the actual target; at 0.4 a top hub adds at most 40%, enough to\n * break genuine ties without overriding term evidence.\n */\nconst IMPORTANCE_WEIGHT = 0.4;\n\n/**\n * Topic-affinity bonus cap: a node whose enrichment tags intersect the\n * question's inferred topics gains at most this fraction on top of its\n * textual evidence. Sized between IMPORTANCE_WEIGHT (0.4) and nothing:\n * strong enough to break domain ties (\"direct debits\" → the payments file\n * over an equal-scoring name hit elsewhere), never strong enough to outrank\n * a clearly better textual match — and it multiplies an existing non-zero\n * score, so it can never conjure a seed by itself.\n */\nconst TOPIC_AFFINITY_WEIGHT = 0.3;\n\n/** Affinity multiplier + provenance for one node under the current analysis. */\n/**\n * Shared root-first path depth between two taxonomy paths.\n * \"infrastructure/networking/dns/cname\" vs \"infrastructure/networking/dns\" → 3.\n */\nfunction sharedDepth(a: string, b: string): number {\n const as = a.split('/');\n const bs = b.split('/');\n let n = 0;\n while (n < as.length && n < bs.length && as[n] === bs[n]) n++;\n return n;\n}\n\n/**\n * How strongly a node's taxonomy tags match what the ask is about.\n *\n * Tags and query matches are both PATHS, so agreement is measured by how far\n * down the tree they agree, not merely whether they share a label. A DNS ask\n * and a file tagged `infrastructure/networking/dns` agree three levels deep\n * and get most of the bonus; the same ask and a file tagged\n * `infrastructure/containers` agree only at the root and get a fraction of it.\n * That is the whole reason tags carry paths.\n *\n * Falls back to flat topic-id matching when the provider predates the\n * taxonomy (or a stale sidecar still holds flat tags), so an older install\n * ranks exactly as it did before.\n */\nfunction topicAffinity(\n nodeId: string,\n relevance: RelevanceAnalysis | null | undefined,\n topicTags: Map<string, readonly string[]> | null | undefined,\n): { boost: number; label: string } {\n if (!topicTags) return { boost: 1, label: '' };\n const tags = topicTags.get(nodeId);\n if (!tags?.length) return { boost: 1, label: '' };\n\n const paths = relevance?.taxonomy ?? [];\n if (paths.length && tags.some((t) => t.includes('/'))) {\n let best = 0;\n let label = '';\n for (const match of paths) {\n const askDepth = match.path.split('/').length;\n for (const tag of tags) {\n const shared = sharedDepth(match.path, tag);\n if (shared === 0) continue;\n // Specificity of agreement × confidence in the match.\n const affinity = (shared / askDepth) * match.score;\n if (affinity > best) {\n best = affinity;\n label = shared === askDepth ? match.path : match.path.split('/').slice(0, shared).join('/');\n }\n }\n }\n if (best <= 0) return { boost: 1, label: '' };\n return { boost: 1 + TOPIC_AFFINITY_WEIGHT * Math.min(best, 1), label: `, topic:${label}` };\n }\n\n if (!relevance?.topics?.length) return { boost: 1, label: '' };\n let affinity = 0;\n const matched: string[] = [];\n for (const t of relevance.topics) {\n if (tags.includes(t.id)) {\n affinity += t.score;\n matched.push(t.id);\n }\n }\n if (affinity <= 0) return { boost: 1, label: '' };\n return { boost: 1 + TOPIC_AFFINITY_WEIGHT * Math.min(affinity, 1), label: `, topic:${matched.sort().join('+')}` };\n}\n\n/**\n * Per-term specificity weights (IDF) for one question, computed over the graph's\n * symbol-name vocabulary: `ln((N+1)/(df+1)) + 1`, clamped to a sane band. A term\n * that appears in one symbol name is highly discriminating; one that appears in\n * hundreds (\"get\", \"code\", \"run\", \"handler\") is near-noise. Clamped so a term\n * matching nothing (huge idf, but it scores 0 anyway) or everything can't\n * distort the scale. Cost is one O(nodes) pass, dwarfed by the scoring loop.\n */\nfunction termWeights(graph: VgGraph, terms: string[]): (t: string) => number {\n if (terms.length === 0) return () => 1;\n const df = new Map<string, number>();\n let n = 0;\n for (const node of graph.nodes) {\n if (node.kind === 'file' || node.kind === 'external') continue;\n n++;\n const name = node.name.toLowerCase();\n const parts = identifierParts(node.name);\n for (const t of terms) {\n if (parts.has(t) || name.includes(t)) df.set(t, (df.get(t) ?? 0) + 1);\n }\n }\n const w = new Map<string, number>();\n for (const t of terms) {\n const idf = Math.log((n + 1) / ((df.get(t) ?? 0) + 1)) + 1;\n // Ceiling of 8 (vs a natural df≈40 idf ≈ 5.4) keeps genuinely rare terms\n // dominant while a term matching nothing/only a file path can't distort.\n w.set(t, Math.max(0.5, Math.min(8, idf)));\n }\n return (t: string) => w.get(t) ?? 1;\n}\n\n/**\n * camelCase / snake_case / kebab split of an identifier → lowercased parts.\n * The separator alternative is Unicode-letter-aware (`\\p{L}\\p{N}`, not\n * ASCII-only `a-zA-Z0-9`) so non-Latin identifiers split on punctuation\n * without losing every character to it; the camelCase boundary lookaround\n * stays ASCII-only since upper/lowercase casing is itself an ASCII-script\n * concept — scripts without case simply never trigger it and fall through to\n * the separator split.\n */\nexport function identifierParts(name: string): Set<string> {\n return new Set(\n name\n .split(/[^\\p{L}\\p{N}]+|(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/u)\n .filter(Boolean)\n .map((s) => s.toLowerCase()),\n );\n}\n\n/** A term fuzzily matches a part if they share a long-enough prefix (same root). */\nfunction fuzzyPartMatch(term: string, parts: Set<string>): boolean {\n for (const part of parts) {\n const shared = sharedPrefixLen(term, part);\n if (shared >= 5 && shared >= 0.6 * Math.min(term.length, part.length)) return true;\n }\n return false;\n}\n\nfunction sharedPrefixLen(a: string, b: string): number {\n const n = Math.min(a.length, b.length);\n let i = 0;\n while (i < n && a[i] === b[i]) i++;\n return i;\n}\n\nfunction buildContext(\n graph: VgGraph,\n index: GraphIndex,\n question: string,\n seeds: QueryMatch[],\n budget: number,\n literals: string[] = [],\n): { context: string; tokensEstimate: number } {\n const lines: string[] = [];\n lines.push(`# Context for: ${question}`);\n lines.push('');\n if (literals.length) {\n lines.push('## Literal string(s) to locate (exact text, not symbol names)');\n for (const lit of literals) lines.push(`- \\`${lit}\\``);\n lines.push(\n '_Use a quoted phrase / URL search (`search_symbols` or `search_code` with the exact needle) for occurrences. Graph symbols below (if any) are residual identifier hints only._',\n );\n lines.push('');\n }\n if (seeds.length === 0) {\n lines.push(\n literals.length\n ? '_No graph symbols matched residual terms — this is expected for a pure string/URL occurrence search. Run a literal sweep on the needle(s) above._'\n : '_No matching symbols found in the map. Try different terms, or `vg hubs` for the most important code._',\n );\n const text = lines.join('\\n');\n return { context: text, tokensEstimate: estimateTokens(text) };\n }\n\n for (const { node, why } of seeds) {\n const block: string[] = [];\n block.push(`## ${node.qualifiedName} (${node.kind}, ${node.file}:${node.span.start})`);\n if (node.signature) block.push('`' + node.signature + '`');\n const callees = index.callees(node.id).map((x) => x.node.qualifiedName);\n const callers = index.callers(node.id).map((x) => x.node.qualifiedName);\n if (callees.length) block.push(`calls: ${unique(callees).slice(0, 8).join(', ')}`);\n if (callers.length) block.push(`called by: ${unique(callers).slice(0, 8).join(', ')}`);\n block.push(`importance ${node.importance.toFixed(3)} · area #${node.area}${node.isHub ? ' · hub' : ''} · ${why}`);\n block.push('');\n\n const candidate = lines.concat(block).join('\\n');\n if (estimateTokens(candidate) > budget && lines.length > 2) break;\n lines.push(...block);\n }\n\n const text = lines.join('\\n');\n return { context: text, tokensEstimate: estimateTokens(text) };\n}\n\nfunction unique(xs: string[]): string[] {\n return [...new Set(xs)];\n}\n\nfunction estimateTokens(text: string): number {\n // ~4 chars per token, the standard rough estimate.\n return Math.ceil(text.length / 4);\n}\n\nfunction round(x: number): number {\n return Math.round(x * 1e6) / 1e6;\n}\n","import { indexFor } from './relations.js';\nimport type { EdgeKind, VgGraph } from '../schema.js';\n\n/**\n * Deterministic reverse-reachability impact analysis (VG-CLI-SPEC §3.5).\n *\n * \"What breaks if `<node>` changes\" = everything that (transitively) depends on\n * it: its callers, importers, and subtypes. We BFS *backwards* along dependency\n * edges, bounded by depth, with a confidence that decays with distance (direct =\n * high; transitive lower; ambiguous/dynamic edges already carry lower edge\n * confidence which we fold in). Test-impact selection (`--tests`) lands in\n * Phase 2; this is the structural blast radius.\n */\n\nconst DEPEND_EDGES = new Set<EdgeKind>(['call', 'import', 'extends', 'implements', 'references']);\n\nexport interface ImpactItem {\n id: string;\n name: string;\n kind: string;\n file: string;\n line: number;\n depth: number;\n confidence: number;\n}\n\nexport interface ImpactResult {\n root: { id: string; name: string };\n depth: number;\n affected: ImpactItem[];\n direct: number;\n transitive: number;\n /** Lowest edge confidence encountered (e.g. a dynamic-dispatch edge). */\n minEdgeConfidence: number;\n}\n\nexport function impactOf(graph: VgGraph, rootId: string, opts: { depth?: number } = {}): ImpactResult {\n const maxDepth = Math.max(1, opts.depth ?? 4);\n const index = indexFor(graph);\n const root = index.node(rootId);\n\n const affected = new Map<string, ImpactItem>();\n let minEdgeConfidence = 1;\n\n // BFS over incoming dependency edges (dependents of the frontier).\n let frontier: { id: string; conf: number }[] = [{ id: rootId, conf: 1 }];\n for (let depth = 1; depth <= maxDepth; depth++) {\n const nextFrontier: { id: string; conf: number }[] = [];\n for (const { id, conf } of frontier) {\n for (const e of index.in(id)) {\n if (!DEPEND_EDGES.has(e.kind)) continue;\n minEdgeConfidence = Math.min(minEdgeConfidence, e.confidence);\n const dependentId = e.src;\n if (dependentId === rootId || affected.has(dependentId)) continue;\n const node = index.node(dependentId);\n if (!node) continue;\n const conf2 = round(conf * e.confidence * 0.9); // decay with distance\n affected.set(dependentId, {\n id: node.id,\n name: node.qualifiedName,\n kind: node.kind,\n file: node.file,\n line: node.span.start,\n depth,\n confidence: conf2,\n });\n nextFrontier.push({ id: dependentId, conf: conf2 });\n }\n }\n frontier = nextFrontier;\n if (frontier.length === 0) break;\n }\n\n const items = [...affected.values()].sort(\n (a, b) => a.depth - b.depth || b.confidence - a.confidence || a.name.localeCompare(b.name),\n );\n\n return {\n root: { id: rootId, name: root?.qualifiedName ?? rootId },\n depth: maxDepth,\n affected: items,\n direct: items.filter((i) => i.depth === 1).length,\n transitive: items.filter((i) => i.depth > 1).length,\n minEdgeConfidence: round(minEdgeConfidence),\n };\n}\n\nfunction round(x: number): number {\n return Math.round(x * 1e6) / 1e6;\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { daemonDir } from './chunk-BWPBB45M.js';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
|
|
4
|
+
function vgdSocketPath(env = process.env, platform = process.platform) {
|
|
5
|
+
if (platform === "win32") {
|
|
6
|
+
return path.join("\\\\.\\pipe", "vibgrate-vgd");
|
|
7
|
+
}
|
|
8
|
+
return path.join(daemonDir(env, platform), "vgd.sock");
|
|
9
|
+
}
|
|
10
|
+
function vgdPidPath(env = process.env, platform = process.platform) {
|
|
11
|
+
return path.join(daemonDir(env, platform), "vgd.pid");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { vgdPidPath, vgdSocketPath };
|
|
15
|
+
//# sourceMappingURL=chunk-NDNNOAS6.js.map
|
|
16
|
+
//# sourceMappingURL=chunk-NDNNOAS6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/vgd/paths.ts"],"names":[],"mappings":";;;AAIO,SAAS,cAAc,GAAA,GAAyB,OAAA,CAAQ,GAAA,EAAK,QAAA,GAA4B,QAAQ,QAAA,EAAkB;AACxH,EAAA,IAAI,aAAa,OAAA,EAAS;AACxB,IAAA,OAAY,IAAA,CAAA,IAAA,CAAK,eAAe,cAAc,CAAA;AAAA,EAChD;AACA,EAAA,OAAY,IAAA,CAAA,IAAA,CAAK,SAAA,CAAU,GAAA,EAAK,QAAQ,GAAG,UAAU,CAAA;AACvD;AAGO,SAAS,WAAW,GAAA,GAAyB,OAAA,CAAQ,GAAA,EAAK,QAAA,GAA4B,QAAQ,QAAA,EAAkB;AACrH,EAAA,OAAY,IAAA,CAAA,IAAA,CAAK,SAAA,CAAU,GAAA,EAAK,QAAQ,GAAG,SAAS,CAAA;AACtD","file":"chunk-NDNNOAS6.js","sourcesContent":["import * as path from 'node:path';\nimport { daemonDir } from '../paths.js';\n\n/** Socket (or named-pipe) path for the local vgd instance. */\nexport function vgdSocketPath(env: NodeJS.ProcessEnv = process.env, platform: NodeJS.Platform = process.platform): string {\n if (platform === 'win32') {\n return path.join('\\\\\\\\.\\\\pipe', 'vibgrate-vgd');\n }\n return path.join(daemonDir(env, platform), 'vgd.sock');\n}\n\n/** PID file for quick status without a round-trip (Unix). */\nexport function vgdPidPath(env: NodeJS.ProcessEnv = process.env, platform: NodeJS.Platform = process.platform): string {\n return path.join(daemonDir(env, platform), 'vgd.pid');\n}\n"]}
|