@vibgrate/cli 2026.824.3 → 2026.825.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/{agent-6SJVWFPV.js → agent-DHQYEHVW.js} +13 -12
- package/dist/{agent-6SJVWFPV.js.map → agent-DHQYEHVW.js.map} +1 -1
- package/dist/{approvals-5UBLBNJF.js → approvals-KBM72NU2.js} +5 -5
- package/dist/{approvals-5UBLBNJF.js.map → approvals-KBM72NU2.js.map} +1 -1
- package/dist/{attach-PSGCCJMA.js → attach-O74NL4M5.js} +3 -3
- package/dist/{attach-PSGCCJMA.js.map → attach-O74NL4M5.js.map} +1 -1
- package/dist/{baseline-HPXACNFU.js → baseline-4X6MQBDA.js} +3 -3
- package/dist/{baseline-HPXACNFU.js.map → baseline-4X6MQBDA.js.map} +1 -1
- package/dist/{chunk-B5GOCQFB.js → chunk-27TS2AUJ.js} +8 -8
- package/dist/{chunk-B5GOCQFB.js.map → chunk-27TS2AUJ.js.map} +1 -1
- package/dist/{chunk-2IY24TTR.js → chunk-2NUS5BOR.js} +3 -3
- package/dist/{chunk-2IY24TTR.js.map → chunk-2NUS5BOR.js.map} +1 -1
- package/dist/{chunk-JL66EPZ4.js → chunk-3E7QT4NE.js} +9 -9
- package/dist/{chunk-JL66EPZ4.js.map → chunk-3E7QT4NE.js.map} +1 -1
- package/dist/{chunk-M5QSBXA6.js → chunk-6MIJLO5B.js} +11 -4
- package/dist/chunk-6MIJLO5B.js.map +1 -0
- package/dist/{chunk-SGIFJIII.js → chunk-7M4E7UGX.js} +3 -3
- package/dist/{chunk-SGIFJIII.js.map → chunk-7M4E7UGX.js.map} +1 -1
- package/dist/{chunk-KBLKNR3V.js → chunk-BICZR6UJ.js} +3 -3
- package/dist/{chunk-KBLKNR3V.js.map → chunk-BICZR6UJ.js.map} +1 -1
- package/dist/{chunk-UUNEUEPQ.js → chunk-DIZ5KI5Q.js} +6 -6
- package/dist/{chunk-UUNEUEPQ.js.map → chunk-DIZ5KI5Q.js.map} +1 -1
- package/dist/{chunk-IKB5U3AH.js → chunk-E3XVIFSH.js} +3 -3
- package/dist/{chunk-IKB5U3AH.js.map → chunk-E3XVIFSH.js.map} +1 -1
- package/dist/{chunk-3PNAQUZM.js → chunk-FQHWPOTS.js} +3 -3
- package/dist/{chunk-3PNAQUZM.js.map → chunk-FQHWPOTS.js.map} +1 -1
- package/dist/chunk-G3ACLBMG.js +6 -0
- package/dist/{chunk-AGOKTI77.js.map → chunk-G3ACLBMG.js.map} +1 -1
- package/dist/{chunk-5QO2GFAE.js → chunk-GR7SFCQJ.js} +44 -12
- package/dist/chunk-GR7SFCQJ.js.map +1 -0
- package/dist/{chunk-4PDWV4AE.js → chunk-GWSJYDK7.js} +5 -5
- package/dist/{chunk-4PDWV4AE.js.map → chunk-GWSJYDK7.js.map} +1 -1
- package/dist/{chunk-CJ2R3LVX.js → chunk-HFQIYM6E.js} +4 -4
- package/dist/{chunk-CJ2R3LVX.js.map → chunk-HFQIYM6E.js.map} +1 -1
- package/dist/{chunk-LMHKIQA5.js → chunk-IJVWKZRS.js} +3 -3
- package/dist/{chunk-LMHKIQA5.js.map → chunk-IJVWKZRS.js.map} +1 -1
- package/dist/{chunk-YJ23GGAJ.js → chunk-JAEHLTVX.js} +3 -3
- package/dist/{chunk-YJ23GGAJ.js.map → chunk-JAEHLTVX.js.map} +1 -1
- package/dist/{chunk-USW5WHUG.js → chunk-K3SXWOTT.js} +3 -3
- package/dist/{chunk-USW5WHUG.js.map → chunk-K3SXWOTT.js.map} +1 -1
- package/dist/{chunk-RAEHWCN6.js → chunk-KYM55VZX.js} +6 -6
- package/dist/{chunk-RAEHWCN6.js.map → chunk-KYM55VZX.js.map} +1 -1
- package/dist/chunk-L7GCJNDT.js +90 -0
- package/dist/chunk-L7GCJNDT.js.map +1 -0
- package/dist/{chunk-QP3P4V4I.js → chunk-NS4DL3QR.js} +8 -8
- package/dist/{chunk-QP3P4V4I.js.map → chunk-NS4DL3QR.js.map} +1 -1
- package/dist/{chunk-WATYIYWP.js → chunk-NZES47ST.js} +3 -3
- package/dist/{chunk-WATYIYWP.js.map → chunk-NZES47ST.js.map} +1 -1
- package/dist/{chunk-III7S75O.js → chunk-OIUVWCKM.js} +3 -3
- package/dist/{chunk-III7S75O.js.map → chunk-OIUVWCKM.js.map} +1 -1
- package/dist/{chunk-LA4CETXN.js → chunk-SIXWWQ6S.js} +3 -3
- package/dist/{chunk-LA4CETXN.js.map → chunk-SIXWWQ6S.js.map} +1 -1
- package/dist/{chunk-TWWVTKA7.js → chunk-SYMJSRYF.js} +3 -3
- package/dist/{chunk-TWWVTKA7.js.map → chunk-SYMJSRYF.js.map} +1 -1
- package/dist/{chunk-KRE7SXSA.js → chunk-TT2J2TB6.js} +6 -6
- package/dist/{chunk-KRE7SXSA.js.map → chunk-TT2J2TB6.js.map} +1 -1
- package/dist/{chunk-XHIWQGRE.js → chunk-VMPKOMHG.js} +5 -5
- package/dist/{chunk-XHIWQGRE.js.map → chunk-VMPKOMHG.js.map} +1 -1
- package/dist/cli.js +52 -48
- package/dist/cli.js.map +1 -1
- package/dist/{daemon-AEL5N4SJ.js → daemon-RZS5FPIW.js} +9 -9
- package/dist/{daemon-AEL5N4SJ.js.map → daemon-RZS5FPIW.js.map} +1 -1
- package/dist/embed-worker-main.js +3 -3
- package/dist/{ensure-map-YL5NR6UH.js → ensure-map-DL2S774J.js} +14 -14
- package/dist/{ensure-map-YL5NR6UH.js.map → ensure-map-DL2S774J.js.map} +1 -1
- package/dist/{graph-backend-LEPXFPXQ.js → graph-backend-JXARVT3R.js} +7 -7
- package/dist/{graph-backend-LEPXFPXQ.js.map → graph-backend-JXARVT3R.js.map} +1 -1
- package/dist/index.d.ts +45 -4
- package/dist/index.js +15 -14
- package/dist/index.js.map +1 -1
- package/dist/{interactive-YJ37ZWTA.js → interactive-2XRBRFRB.js} +25 -24
- package/dist/interactive-2XRBRFRB.js.map +1 -0
- package/dist/load-7C5VETRD.js +11 -0
- package/dist/{load-LT6R73IZ.js.map → load-7C5VETRD.js.map} +1 -1
- package/dist/parse-worker.js +2 -2
- package/dist/{run-outcome-YQBPYNEY.js → run-outcome-TMB5TJNA.js} +5 -5
- package/dist/{run-outcome-YQBPYNEY.js.map → run-outcome-TMB5TJNA.js.map} +1 -1
- package/dist/{runtime-session-JSH5UL7Z.js → runtime-session-Y23NVY7R.js} +9 -9
- package/dist/{runtime-session-JSH5UL7Z.js.map → runtime-session-Y23NVY7R.js.map} +1 -1
- package/dist/{session-3FLVZRMM.js → session-KXT2ZTPE.js} +8 -8
- package/dist/{session-3FLVZRMM.js.map → session-KXT2ZTPE.js.map} +1 -1
- package/dist/{stream-json-VJ2O52CR.js → stream-json-NW6AOE47.js} +13 -12
- package/dist/stream-json-NW6AOE47.js.map +1 -0
- package/dist/version-7ABYXWOZ.js +4 -0
- package/dist/{version-VUTM46C5.js.map → version-7ABYXWOZ.js.map} +1 -1
- package/dist/{vg-mcp-bridge-UUMEOJSO.js → vg-mcp-bridge-LXBHKEFR.js} +8 -8
- package/dist/{vg-mcp-bridge-UUMEOJSO.js.map → vg-mcp-bridge-LXBHKEFR.js.map} +1 -1
- package/dist/{vgd-XFT574U6.js → vgd-RW7HCEIP.js} +8 -8
- package/dist/vgd-RW7HCEIP.js.map +1 -0
- package/package.json +2 -5
- package/dist/chunk-5QO2GFAE.js.map +0 -1
- package/dist/chunk-AGOKTI77.js +0 -6
- package/dist/chunk-M5QSBXA6.js.map +0 -1
- package/dist/interactive-YJ37ZWTA.js.map +0 -1
- package/dist/load-LT6R73IZ.js +0 -11
- package/dist/stream-json-VJ2O52CR.js.map +0 -1
- package/dist/version-VUTM46C5.js +0 -4
- package/dist/vgd-XFT574U6.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/engine/grammars.ts","../src/engine/queries.ts","../src/engine/sfc.ts","../src/engine/toolchain/grammars.ts","../src/engine/ast-roles.ts","../src/engine/parse.ts"],"names":["require","ranges","createRequire","languageCache","path2","fs2","Language","Parser","compiledCache","compile","Query"],"mappings":"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","file":"chunk-6MIJLO5B.js","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { createRequire } from 'node:module';\nimport { Parser, Language } from 'web-tree-sitter';\nimport { langById, LANGUAGES, type LanguageDef } from './languages.js';\n\n/**\n * Grammar loader. Resolves the pre-compiled tree-sitter `.wasm` for a language\n * from, in order:\n * 1. the `--grammars <dir>` override (offline / air-gapped)\n * 2. ../grammars next to dist (bundled in the published package)\n * 3. the installed `tree-sitter-wasms` package (dev / fallback)\n *\n * Languages are cached. The grammar set version is recorded in provenance so the\n * determinism contract is explicit about which grammars produced the graph.\n */\n\nconst require = createRequire(import.meta.url);\n\nlet parserInit: Promise<void> | null = null;\nconst languageCache = new Map<string, Language>();\n\n// The `--grammars <dir>` override, set per process (and per parse worker, via the\n// parse payload) before parsing. Configured by a command option, not an env var.\nlet grammarsOverride: string | undefined;\nexport function setGrammarsOverride(dir?: string): void {\n grammarsOverride = dir ? path.resolve(dir) : undefined;\n}\n\nfunction thisDir(): string {\n return path.dirname(fileURLToPath(import.meta.url));\n}\n\nlet cachedTreeSitterWasmsDir: string | null = null;\nfunction treeSitterWasmsOutDir(): string {\n if (cachedTreeSitterWasmsDir) return cachedTreeSitterWasmsDir;\n const pkgJson = require.resolve('tree-sitter-wasms/package.json');\n cachedTreeSitterWasmsDir = path.join(path.dirname(pkgJson), 'out');\n return cachedTreeSitterWasmsDir;\n}\n\n/**\n * The grammar-set version string recorded in provenance (determinism input).\n * The `+swift-vendored` suffix marks the vendored tree-sitter-swift build (see\n * vendor/README.md) that replaces the tree-sitter-wasms prebuilt; bump the\n * suffix if a vendored grammar is regenerated, so caches invalidate.\n */\nexport function grammarSetVersion(): string {\n try {\n const pkgJson = require.resolve('tree-sitter-wasms/package.json');\n const { version } = JSON.parse(fs.readFileSync(pkgJson, 'utf8')) as { version: string };\n return `tree-sitter-wasms@${version}+swift-vendored@0.7.1`;\n } catch {\n return 'tree-sitter-wasms@unknown+swift-vendored@0.7.1';\n }\n}\n\n/**\n * Candidate directories holding grammar .wasm files, highest priority first.\n * The vendor/ dirs are OVERLAYS holding only rebuilt replacements for\n * defective prebuilts (vendor/README.md) — they outrank the tree-sitter-wasms\n * fallback so dev/test runs without a prior `pnpm build` never load a\n * known-bad prebuilt, but they are never a complete grammar set.\n */\nexport function grammarDirs(): string[] {\n const dirs: string[] = [];\n // the `--grammars <dir>` override (offline / air-gapped), if set\n if (grammarsOverride) dirs.push(grammarsOverride);\n // ../grammars relative to dist/ (bundled in the published artifact)\n dirs.push(path.join(thisDir(), '..', 'grammars'));\n dirs.push(path.join(thisDir(), 'grammars'));\n // vendored overlays\n dirs.push(path.join(thisDir(), '..', 'vendor')); // from dist/\n dirs.push(path.join(thisDir(), '..', '..', 'vendor')); // from src/engine/\n // node_modules fallback\n try {\n dirs.push(treeSitterWasmsOutDir());\n } catch {\n /* tree-sitter-wasms not resolvable — rely on the dirs above */\n }\n return dirs;\n}\n\nconst isVendorOverlay = (dir: string): boolean => path.basename(dir) === 'vendor';\n\n/**\n * The first existing directory that holds a grammar .wasm set. Skips the\n * vendor overlays — they hold single replacement files, never a full set.\n * For a complete per-language resolution use resolvedGrammarFiles().\n */\nexport function grammarsSourceDir(): string | null {\n for (const dir of grammarDirs()) {\n if (isVendorOverlay(dir)) continue;\n if (fs.existsSync(dir) && fs.readdirSync(dir).some((f) => f.endsWith('.wasm'))) return dir;\n }\n return null;\n}\n\nfunction resolveGrammarFile(grammarFile: string): string {\n const fileName = `${grammarFile}.wasm`;\n for (const dir of grammarDirs()) {\n const candidate = path.join(dir, fileName);\n if (fs.existsSync(candidate)) return candidate;\n }\n throw new Error(\n `grammar \"${fileName}\" not found. Looked in: ${grammarDirs().join(', ')}. ` +\n `Pass --grammars <dir> pointing at a directory of grammar .wasm files.`,\n );\n}\n\n/**\n * Every registered language's grammar .wasm resolved through the same\n * priority order the parser uses (override > bundled > vendor overlay >\n * tree-sitter-wasms). Used by `vg bundle` so an air-gapped bundle always\n * carries the exact grammar files a scan would load.\n */\nexport function resolvedGrammarFiles(): { fileName: string; absPath: string }[] {\n return LANGUAGES.map((l) => ({\n fileName: `${l.grammarFile}.wasm`,\n absPath: resolveGrammarFile(l.grammarFile),\n }));\n}\n\nexport async function ensureParserInit(): Promise<void> {\n if (!parserInit) parserInit = Parser.init();\n await parserInit;\n}\n\n/** Load (and cache) the tree-sitter Language for a vg language id. */\nexport async function loadLanguage(langId: string): Promise<Language> {\n const cached = languageCache.get(langId);\n if (cached) return cached;\n const def = langById(langId);\n if (!def) throw new Error(`unknown language id \"${langId}\"`);\n await ensureParserInit();\n const wasmPath = resolveGrammarFile(def.grammarFile);\n const language = await Language.load(fs.readFileSync(wasmPath));\n languageCache.set(langId, language);\n return language;\n}\n\n// One reused parser per language: a Parser allocates in the shared wasm heap\n// and is never garbage-collected there, so a parser-per-file leaks the heap\n// until parsing dies with \"memory access out of bounds\" on large builds\n// (observed ~10k files in one process). Parsers are reusable across parse()\n// calls; resetParser() discards one after a failed parse left it mid-state.\nconst parserCache = new Map<string, Parser>();\n\n/** A per-language reused parser bound to the language's grammar. */\nexport async function parserFor(def: LanguageDef): Promise<Parser> {\n const cached = parserCache.get(def.id);\n if (cached) return cached;\n const language = await loadLanguage(def.id);\n const parser = new Parser();\n parser.setLanguage(language);\n parserCache.set(def.id, parser);\n return parser;\n}\n\n/** Drop a language's cached parser (after a parse error left it mid-state). */\nexport function resetParser(langId: string): void {\n const parser = parserCache.get(langId);\n if (!parser) return;\n parserCache.delete(langId);\n try {\n parser.delete();\n } catch {\n // The wasm side may already be unusable; dropping the reference is enough.\n }\n}\n","import type { NodeKind } from '../schema.js';\n\n/**\n * Per-language tree-sitter queries driving extraction. Each query uses a small,\n * fixed capture vocabulary so the generic extractor (parse.ts) stays\n * language-agnostic:\n *\n * @def — a definition node (its kind comes from the rule)\n * @name — the name node of that definition\n * @callee — a called name node (a call edge, resolved later)\n * @source — an import/require source string node (incl. quotes)\n * @extends / @implements — a base type name node (a heritage edge)\n *\n * Queries are best-effort per language: if a pattern fails to compile against a\n * grammar it is skipped (logged once), so one bad rule never disables a whole\n * language. Coverage is deepest for the TS/JS-first audience and a solid\n * baseline elsewhere — honestly recorded as `heuristic` resolution.\n */\n\nexport interface DefRule {\n kind: NodeKind;\n query: string;\n}\n\nexport interface LangQueries {\n defs: DefRule[];\n calls: string[];\n imports: string[];\n heritage: string[];\n /** Assert/guard expressions captured as @guard → invariant facts. */\n guards?: string[];\n /**\n * Constructor-parameter / field declared types captured as @typeref — a\n * structural dependency (e.g. Spring constructor/field injection) that never\n * appears as a `call_expression`/`object_creation_expression`, so it needs its\n * own capture. Resolved to a `references` edge (not `call`) in resolve.ts.\n */\n typeRefs?: string[];\n /**\n * Namespace declarations captured as @namespace — the namespaces a file\n * declares its types in. For languages where a namespace is decoupled from\n * the directory (C#), this lets the resolver connect a cross-directory\n * reference when the caller `using`-imports that namespace. Absent for\n * languages that have no namespace concept or where package == directory.\n */\n namespaces?: string[];\n}\n\n// assert-like call detection, shared by the C-family languages.\nconst ASSERT_CALLS = [\n '(call_expression function: (identifier) @_g (#match? @_g \"^(assert|invariant|require|precondition|invariantViolation)$\")) @guard',\n];\n\nconst TS_JS_CALLS = [\n '(call_expression function: (identifier) @callee)',\n '(call_expression function: (member_expression property: (property_identifier) @callee))',\n '(new_expression constructor: (identifier) @callee)',\n];\n\nconst TS_JS_IMPORTS = [\n '(import_statement source: (string) @source)',\n '(call_expression function: (identifier) @_req (#eq? @_req \"require\") arguments: (arguments (string) @source))',\n];\n\nconst TYPESCRIPT: LangQueries = {\n defs: [\n { kind: 'function', query: '(function_declaration name: (identifier) @name) @def' },\n {\n kind: 'function',\n query: '(generator_function_declaration name: (identifier) @name) @def',\n },\n {\n kind: 'function',\n query:\n '(variable_declarator name: (identifier) @name value: [(arrow_function) (function_expression)]) @def',\n },\n { kind: 'method', query: '(method_definition name: (property_identifier) @name) @def' },\n // Object-literal methods: `{ showToast: function () {} }` / `{ showToast: () => {} }`\n // (common in Vue/NS utilities; class method_definition alone does not cover these).\n {\n kind: 'method',\n query:\n '(pair key: (property_identifier) @name value: [(function_expression) (arrow_function)] @def)',\n },\n { kind: 'class', query: '(class_declaration name: (type_identifier) @name) @def' },\n { kind: 'class', query: '(abstract_class_declaration name: (type_identifier) @name) @def' },\n { kind: 'interface', query: '(interface_declaration name: (type_identifier) @name) @def' },\n ],\n calls: TS_JS_CALLS,\n imports: TS_JS_IMPORTS,\n heritage: [\n '(class_heritage (extends_clause value: (identifier) @extends))',\n '(class_heritage (extends_clause value: (member_expression property: (property_identifier) @extends)))',\n '(class_heritage (implements_clause (type_identifier) @implements))',\n '(extends_type_clause type: (type_identifier) @extends)',\n ],\n guards: ASSERT_CALLS,\n};\n\nconst JAVASCRIPT: LangQueries = {\n defs: [\n { kind: 'function', query: '(function_declaration name: (identifier) @name) @def' },\n {\n kind: 'function',\n query: '(generator_function_declaration name: (identifier) @name) @def',\n },\n {\n kind: 'function',\n query:\n '(variable_declarator name: (identifier) @name value: [(arrow_function) (function_expression)]) @def',\n },\n { kind: 'method', query: '(method_definition name: (property_identifier) @name) @def' },\n // Object-literal methods (see TYPESCRIPT above).\n {\n kind: 'method',\n query:\n '(pair key: (property_identifier) @name value: [(function_expression) (arrow_function)] @def)',\n },\n { kind: 'class', query: '(class_declaration name: (identifier) @name) @def' },\n ],\n calls: TS_JS_CALLS,\n imports: TS_JS_IMPORTS,\n heritage: [\n '(class_heritage (identifier) @extends)',\n '(class_heritage (member_expression property: (property_identifier) @extends))',\n ],\n guards: ASSERT_CALLS,\n};\n\nconst PYTHON: LangQueries = {\n defs: [\n { kind: 'function', query: '(function_definition name: (identifier) @name) @def' },\n { kind: 'class', query: '(class_definition name: (identifier) @name) @def' },\n ],\n calls: [\n '(call function: (identifier) @callee)',\n '(call function: (attribute attribute: (identifier) @callee))',\n ],\n imports: [\n '(import_statement name: (dotted_name) @source)',\n '(import_from_statement module_name: (dotted_name) @source)',\n // Relative imports (`from .models import X`, `from ..core.utils import Y`) —\n // the module is a `relative_import` node, not a `dotted_name`. These are the\n // bulk of intra-package edges and were previously dropped entirely.\n '(import_from_statement module_name: (relative_import) @source)',\n ],\n heritage: ['(class_definition superclasses: (argument_list (identifier) @extends))'],\n guards: ['(assert_statement) @guard'],\n};\n\nconst GO: LangQueries = {\n defs: [\n { kind: 'function', query: '(function_declaration name: (identifier) @name) @def' },\n { kind: 'method', query: '(method_declaration name: (field_identifier) @name) @def' },\n { kind: 'class', query: '(type_declaration (type_spec name: (type_identifier) @name)) @def' },\n ],\n calls: [\n '(call_expression function: (identifier) @callee)',\n '(call_expression function: (selector_expression field: (field_identifier) @callee))',\n ],\n imports: ['(import_spec path: (interpreted_string_literal) @source)'],\n heritage: [],\n};\n\nconst JAVA: LangQueries = {\n defs: [\n { kind: 'method', query: '(method_declaration name: (identifier) @name) @def' },\n { kind: 'method', query: '(constructor_declaration name: (identifier) @name) @def' },\n { kind: 'class', query: '(class_declaration name: (identifier) @name) @def' },\n { kind: 'interface', query: '(interface_declaration name: (identifier) @name) @def' },\n ],\n calls: ['(method_invocation name: (identifier) @callee)', '(object_creation_expression type: (type_identifier) @callee)'],\n imports: ['(import_declaration (scoped_identifier) @source)'],\n heritage: [\n '(superclass (type_identifier) @extends)',\n '(super_interfaces (type_list (type_identifier) @implements))',\n ],\n // Spring-style dependency injection wires a collaborator via a constructor\n // parameter or a field, never a `new`/method call — so without these, an\n // injected repository/service shows zero callers even when it is the sole\n // reason five other classes exist.\n typeRefs: [\n '(constructor_declaration parameters: (formal_parameters (formal_parameter type: (type_identifier) @typeref)))',\n '(field_declaration type: (type_identifier) @typeref)',\n ],\n // A Java package is a directory, so cross-directory (cross-package) DI\n // resolves through `import a.b.Foo`. Capturing the package lets the resolver\n // reach the implementation in another package when the caller imports it.\n namespaces: ['(package_declaration (scoped_identifier) @namespace)', '(package_declaration (identifier) @namespace)'],\n};\n\nconst RUST: LangQueries = {\n defs: [\n { kind: 'function', query: '(function_item name: (identifier) @name) @def' },\n { kind: 'class', query: '(struct_item name: (type_identifier) @name) @def' },\n { kind: 'class', query: '(enum_item name: (type_identifier) @name) @def' },\n { kind: 'interface', query: '(trait_item name: (type_identifier) @name) @def' },\n // Rust colocates tests: `#[cfg(test)] mod tests` sits at the bottom of the\n // file it tests. Without the module capture every `#[test] fn` is indexed\n // as a bare top-level function, so nothing downstream can tell a test from\n // production code (a test name echoing an ask outranked the code it\n // covers). Capturing it also qualifies ordinary `mod` members, matching\n // what Ruby/Scala/C++/OCaml already do.\n { kind: 'module', query: '(mod_item name: (identifier) @name) @def' },\n ],\n calls: [\n '(call_expression function: (identifier) @callee)',\n '(call_expression function: (field_expression field: (field_identifier) @callee))',\n '(call_expression function: (scoped_identifier name: (identifier) @callee))',\n ],\n imports: ['(use_declaration (scoped_identifier) @source)'],\n heritage: [],\n};\n\nconst C_SHARP: LangQueries = {\n defs: [\n { kind: 'method', query: '(method_declaration name: (identifier) @name) @def' },\n { kind: 'class', query: '(class_declaration name: (identifier) @name) @def' },\n { kind: 'interface', query: '(interface_declaration name: (identifier) @name) @def' },\n { kind: 'class', query: '(struct_declaration name: (identifier) @name) @def' },\n // Enums and records are load-bearing lookup targets in real C# codebases\n // (permission enums, DTO records); without these captures a `Privilege`-\n // style lookup only ever resolves via the literal text fallthrough.\n // 'class' is this engine's established kind for enum-like types (see the\n // Rust enum_item and C enum_specifier mappings).\n { kind: 'class', query: '(enum_declaration name: (identifier) @name) @def' },\n { kind: 'class', query: '(record_declaration name: (identifier) @name) @def' },\n ],\n calls: [\n '(invocation_expression function: (member_access_expression name: (identifier) @callee))',\n '(invocation_expression function: (identifier) @callee)',\n // `new Foo(...)` is an instantiation dependency (the caller depends on Foo),\n // and it is how a test most directly links to the class under test — without\n // it a test that only constructs the service showed up as no coverage.\n '(object_creation_expression type: (identifier) @callee)',\n ],\n imports: ['(using_directive (qualified_name) @source)', '(using_directive (identifier) @source)'],\n heritage: ['(base_list (identifier) @extends)'],\n // Dependency-injection wiring: the interface a class depends on appears as a\n // constructor-parameter type or a readonly field type, never as a call — so\n // without these captures a controller/service injected through an interface\n // looks like it references nothing. Simple (identifier) types only; generics/\n // qualified names are left to a precise rung. Mirrors the Java DI captures.\n typeRefs: [\n '(constructor_declaration (parameter_list (parameter type: (identifier) @typeref)))',\n '(field_declaration (variable_declaration type: (identifier) @typeref))',\n ],\n // A namespace is decoupled from the directory in C#, so cross-namespace\n // resolution needs to know which namespace a file declares. Both block-scoped\n // (`namespace N { }`) and file-scoped (`namespace N;`) forms.\n namespaces: [\n '(namespace_declaration name: [(identifier) (qualified_name)] @namespace)',\n '(file_scoped_namespace_declaration name: [(identifier) (qualified_name)] @namespace)',\n ],\n};\n\nconst RUBY: LangQueries = {\n defs: [\n { kind: 'method', query: '(method name: (identifier) @name) @def' },\n { kind: 'class', query: '(class name: (constant) @name) @def' },\n { kind: 'module', query: '(module name: (constant) @name) @def' },\n ],\n calls: ['(call method: (identifier) @callee)', '(command method: (identifier) @callee)'],\n imports: [\n '(call method: (identifier) @_m (#match? @_m \"require\") arguments: (argument_list (string (string_content) @source)))',\n ],\n heritage: ['(class (superclass (constant) @extends))'],\n};\n\n\nconst PHP: LangQueries = {\n defs: [\n { kind: 'function', query: '(function_definition name: (name) @name) @def' },\n {\n kind: 'function',\n query:\n '(assignment_expression left: (variable_name (name) @name) right: [(anonymous_function_creation_expression) (arrow_function)]) @def',\n },\n { kind: 'method', query: '(method_declaration name: (name) @name) @def' },\n { kind: 'class', query: '(class_declaration name: (name) @name) @def' },\n { kind: 'class', query: '(trait_declaration name: (name) @name) @def' },\n { kind: 'interface', query: '(interface_declaration name: (name) @name) @def' },\n ],\n calls: [\n '(function_call_expression function: (name) @callee)',\n '(member_call_expression name: (name) @callee)',\n '(nullsafe_member_call_expression name: (name) @callee)',\n '(scoped_call_expression name: (name) @callee)',\n '(object_creation_expression (name) @callee)',\n ],\n imports: [\n '(namespace_use_clause (qualified_name) @source)',\n '(namespace_use_clause (name) @source)',\n '[(require_expression (string) @source) (require_once_expression (string) @source) (include_expression (string) @source) (include_once_expression (string) @source)]',\n ],\n heritage: ['(base_clause (name) @extends)', '(class_interface_clause (name) @implements)'],\n // PHP namespaces are decoupled from directories (PSR-4 maps them, but the\n // resolver has no composer.json), so cross-namespace DI resolves through\n // `use`. Constructor-parameter and typed-property types are the injection\n // points.\n namespaces: ['(namespace_definition name: (namespace_name) @namespace)'],\n typeRefs: [\n '(simple_parameter type: (named_type (name) @typeref))',\n '(property_declaration type: (named_type (name) @typeref))',\n ],\n guards: ['(function_call_expression function: (name) @_g (#eq? @_g \"assert\")) @guard'],\n};\n\n// fwcd grammar: no field names — captures are positional; each def pattern binds\n// exactly one @name (params live under function_value_parameters). `class` vs\n// `interface` are both class_declaration, split by the anonymous keyword token.\nconst KOTLIN: LangQueries = {\n defs: [\n { kind: 'function', query: '(function_declaration (simple_identifier) @name) @def' },\n { kind: 'class', query: '(class_declaration \"class\" (type_identifier) @name) @def' },\n { kind: 'interface', query: '(class_declaration \"interface\" (type_identifier) @name) @def' },\n { kind: 'class', query: '(object_declaration (type_identifier) @name) @def' },\n ],\n calls: [\n '(call_expression (simple_identifier) @callee)',\n '(call_expression (navigation_expression (navigation_suffix (simple_identifier) @callee)))',\n ],\n imports: ['(import_header (identifier) @source)'],\n // Kotlin: package for cross-package DI reachability; primary-constructor\n // `val` params and property types are the injection points.\n namespaces: ['(package_header (identifier) @namespace)'],\n typeRefs: [\n '(class_parameter (user_type (type_identifier) @typeref))',\n '(property_declaration (variable_declaration (user_type (type_identifier) @typeref)))',\n '(property_declaration (variable_declaration (nullable_type (user_type (type_identifier) @typeref))))',\n ],\n heritage: [\n '(delegation_specifier (constructor_invocation (user_type (type_identifier) @extends)))',\n '(delegation_specifier (user_type (type_identifier) @implements))',\n ],\n guards: ['(call_expression (simple_identifier) @_g (#match? @_g \"^(require|check|assert)$\")) @guard'],\n};\n\n// class/struct/enum/extension are ALL class_declaration; extensions carry\n// name: (user_type …) and so get their own (duplicate-named) class def node.\nconst SWIFT: LangQueries = {\n defs: [\n { kind: 'function', query: '(function_declaration name: (simple_identifier) @name) @def' },\n { kind: 'method', query: '(protocol_function_declaration name: (simple_identifier) @name) @def' },\n { kind: 'class', query: '(class_declaration name: (type_identifier) @name) @def' },\n { kind: 'class', query: '(class_declaration name: (user_type (type_identifier) @name)) @def' },\n { kind: 'interface', query: '(protocol_declaration name: (type_identifier) @name) @def' },\n ],\n calls: [\n '(call_expression (simple_identifier) @callee)',\n '(call_expression (navigation_expression suffix: (navigation_suffix suffix: (simple_identifier) @callee)))',\n ],\n imports: ['(import_declaration (identifier) @source)'],\n heritage: ['(inheritance_specifier inherits_from: (user_type (type_identifier) @extends))'],\n // Swift: init-parameter and stored-property types are the injection points\n // (protocol-typed). Whole-module visibility (handled in resolve.ts) makes the\n // conforming implementation reachable cross-file.\n typeRefs: [\n '(parameter (user_type (type_identifier) @typeref))',\n '(type_annotation (user_type (type_identifier) @typeref))',\n ],\n guards: [\n '(call_expression (simple_identifier) @_g (#match? @_g \"^(assert|precondition|assertionFailure|preconditionFailure)$\")) @guard',\n ],\n};\n\nconst SCALA: LangQueries = {\n defs: [\n { kind: 'function', query: '(function_definition name: (identifier) @name) @def' },\n { kind: 'method', query: '(function_declaration name: (identifier) @name) @def' },\n { kind: 'class', query: '(class_definition name: (identifier) @name) @def' },\n { kind: 'interface', query: '(trait_definition name: (identifier) @name) @def' },\n { kind: 'module', query: '(object_definition name: (identifier) @name) @def' },\n ],\n calls: [\n '(call_expression function: (identifier) @callee)',\n '(call_expression function: (field_expression field: (identifier) @callee))',\n ],\n imports: [\n '(import_declaration path: (stable_identifier) @source)',\n '(import_declaration path: (identifier) @source)',\n ],\n heritage: [\n '(extends_clause type: (type_identifier) @extends)',\n '(extends_clause type: (generic_type type: (type_identifier) @extends))',\n '(extends_clause type: (compound_type base: (type_identifier) @extends))',\n '(extends_clause type: (compound_type extra: (type_identifier) @implements))',\n ],\n // Scala: package for cross-package DI reachability; class-parameter and val\n // types are the injection points.\n namespaces: ['(package_clause name: (package_identifier) @namespace)'],\n typeRefs: [\n '(class_parameter type: (type_identifier) @typeref)',\n '(val_definition type: (type_identifier) @typeref)',\n ],\n guards: ['(call_expression function: (identifier) @_g (#match? @_g \"^(require|assert|assume)$\")) @guard'],\n};\n\n// No call_expression node in this grammar: a call is an identifier followed by a\n// sibling selector(argument_part), hence the anchored sibling patterns.\nconst DART: LangQueries = {\n defs: [\n { kind: 'function', query: '(function_signature name: (identifier) @name) @def' },\n { kind: 'method', query: '(constructor_signature name: (identifier) @name) @def' },\n { kind: 'class', query: '(class_definition name: (identifier) @name) @def' },\n { kind: 'class', query: '(mixin_declaration (identifier) @name) @def' },\n ],\n calls: [\n '(_ (identifier) @callee . (selector (argument_part)))',\n '(_ (selector (unconditional_assignable_selector (identifier) @callee)) . (selector (argument_part)))',\n '(_ (selector (conditional_assignable_selector (identifier) @callee)) . (selector (argument_part)))',\n '(cascade_section (cascade_selector (identifier) @callee) . (argument_part))',\n ],\n imports: ['(import_specification (configurable_uri (uri (string_literal) @source)))'],\n // Dart: constructor/method parameter types and typed field declarations are\n // the injection points (Dart resolves cross-file via `import`, so no\n // namespace query is needed — the import rung already reaches the impl).\n typeRefs: [\n '(formal_parameter (type_identifier) @typeref)',\n '(declaration (type_identifier) @typeref)',\n ],\n heritage: [\n '(superclass (type_identifier) @extends)',\n '(interfaces (type_identifier) @implements)',\n '(mixins (type_identifier) @implements)',\n ],\n guards: ['(assert_statement) @guard'],\n};\n\nconst LUA: LangQueries = {\n defs: [\n { kind: 'function', query: '(function_definition_statement name: (identifier) @name) @def' },\n { kind: 'function', query: '(function_definition_statement name: (variable field: (identifier) @name)) @def' },\n { kind: 'method', query: '(function_definition_statement name: (variable method: (identifier) @name)) @def' },\n { kind: 'function', query: '(local_function_definition_statement name: (identifier) @name) @def' },\n {\n kind: 'function',\n query:\n '(variable_assignment (variable_list (variable field: (identifier) @name)) (expression_list value: (function_definition))) @def',\n },\n {\n kind: 'function',\n query:\n '(local_variable_declaration (variable_list (variable name: (identifier) @name)) (expression_list value: (function_definition))) @def',\n },\n ],\n calls: [\n '(call function: (variable name: (identifier) @callee))',\n '(call function: (variable field: (identifier) @callee))',\n '(call function: (variable method: (identifier) @callee))',\n ],\n imports: [\n '(call function: (variable name: (identifier) @_r (#eq? @_r \"require\")) arguments: (argument_list (expression_list (string) @source)))',\n ],\n heritage: [],\n guards: ['(call function: (variable name: (identifier) @_g (#eq? @_g \"assert\"))) @guard'],\n};\n\n// Expression-based grammar: defmodule/def/defp are ordinary `call` nodes keyed by\n// their target identifier, so every rule is predicate-gated. A parenthesized def\n// head is itself a call and yields one benign same-line self-capture; the\n// resolver's qualified-call/enclosing-def rules keep it from becoming an edge.\nconst ELIXIR: LangQueries = {\n defs: [\n { kind: 'module', query: '(call target: (identifier) @_kw (#eq? @_kw \"defmodule\") (arguments (alias) @name)) @def' },\n {\n kind: 'function',\n query:\n '(call target: (identifier) @_kw (#match? @_kw \"^(def|defp|defmacro|defmacrop|defguard|defguardp)$\") (arguments (call target: (identifier) @name))) @def',\n },\n {\n kind: 'function',\n query:\n '(call target: (identifier) @_kw (#match? @_kw \"^(def|defp|defmacro|defmacrop)$\") (arguments (identifier) @name)) @def',\n },\n {\n kind: 'function',\n query:\n '(call target: (identifier) @_kw (#match? @_kw \"^(def|defp|defmacro|defmacrop|defguard|defguardp)$\") (arguments (binary_operator left: (call target: (identifier) @name)))) @def',\n },\n ],\n calls: [\n '(call target: (dot right: (identifier) @callee))',\n '(call target: (identifier) @callee (#not-match? @callee \"^(def|defp|defmacro|defmacrop|defmodule|defstruct|defprotocol|defimpl|defguard|defguardp|defdelegate|defexception|defoverridable|alias|import|require|use|quote|unquote|moduledoc|doc|spec|type|typep|typedoc|opaque|behaviour|impl|derive|enforce_keys|callback|macrocallback|optional_callbacks|compile|deprecated|dialyzer|external_resource|on_definition|on_load|after_compile|before_compile)$\"))',\n ],\n imports: [\n '(call target: (identifier) @_kw (#match? @_kw \"^(alias|import|require|use)$\") (arguments (alias) @source))',\n '(call target: (identifier) @_kw (#match? @_kw \"^(alias|import|require|use)$\") (arguments (dot left: (alias) @source)))',\n ],\n heritage: [],\n};\n\n// Every shell command is a `command` node, so callees include external binaries\n// (rsync, git, …). Safe: the resolver has no global-name fallback, so only\n// callees matching a reachable function_definition become edges.\nconst BASH: LangQueries = {\n defs: [{ kind: 'function', query: '(function_definition name: (word) @name) @def' }],\n calls: ['(command name: (command_name (word) @callee))'],\n imports: [\n '(command name: (command_name (word) @_c (#match? @_c \"^(source|\\\\.)$\")) argument: [(word) (string) (raw_string) (concatenation)] @source)',\n ],\n heritage: [],\n};\n\nconst ZIG: LangQueries = {\n defs: [\n { kind: 'function', query: '(function_declaration name: (identifier) @name) @def' },\n { kind: 'class', query: '(variable_declaration (identifier) @name (struct_declaration)) @def' },\n { kind: 'class', query: '(variable_declaration (identifier) @name (enum_declaration)) @def' },\n { kind: 'class', query: '(variable_declaration (identifier) @name (union_declaration)) @def' },\n ],\n calls: [\n '(call_expression function: (identifier) @callee)',\n '(call_expression function: (field_expression member: (identifier) @callee))',\n ],\n imports: ['(builtin_function (builtin_identifier) @_i (#eq? @_i \"@import\") (arguments (string) @source))'],\n heritage: [],\n guards: ['(call_expression function: (field_expression member: (identifier) @_g (#eq? @_g \"assert\"))) @guard'],\n};\n\n// Only body-bearing function_definitions match (prototypes are `declaration`s).\nconst C_LANG: LangQueries = {\n defs: [\n {\n kind: 'function',\n query:\n '(function_definition declarator: [(function_declarator declarator: (identifier) @name) (pointer_declarator declarator: (function_declarator declarator: (identifier) @name))]) @def',\n },\n { kind: 'class', query: '(struct_specifier name: (type_identifier) @name body: (field_declaration_list)) @def' },\n { kind: 'class', query: '(enum_specifier name: (type_identifier) @name body: (enumerator_list)) @def' },\n { kind: 'class', query: '(type_definition declarator: (type_identifier) @name) @def' },\n ],\n calls: [\n '(call_expression function: (identifier) @callee)',\n '(call_expression function: (field_expression field: (field_identifier) @callee))',\n ],\n imports: ['(preproc_include path: (string_literal) @source)', '(preproc_include path: (system_lib_string) @source)'],\n heritage: [],\n guards: ['(call_expression function: (identifier) @_g (#match? @_g \"^(assert|static_assert)$\")) @guard'],\n};\n\nconst CPP: LangQueries = {\n defs: [\n {\n kind: 'function',\n query:\n '(function_definition declarator: [(function_declarator declarator: (identifier) @name) (pointer_declarator declarator: (function_declarator declarator: (identifier) @name)) (reference_declarator (function_declarator declarator: (identifier) @name))]) @def',\n },\n { kind: 'method', query: '(function_definition declarator: (function_declarator declarator: (field_identifier) @name)) @def' },\n {\n kind: 'method',\n query:\n '(function_definition declarator: [(function_declarator declarator: (qualified_identifier name: (identifier) @name)) (pointer_declarator declarator: (function_declarator declarator: (qualified_identifier name: (identifier) @name))) (reference_declarator (function_declarator declarator: (qualified_identifier name: (identifier) @name)))]) @def',\n },\n {\n kind: 'method',\n query:\n '(function_definition declarator: (function_declarator declarator: (qualified_identifier name: (qualified_identifier name: (identifier) @name)))) @def',\n },\n { kind: 'class', query: '(class_specifier name: (type_identifier) @name body: (field_declaration_list)) @def' },\n { kind: 'class', query: '(struct_specifier name: (type_identifier) @name body: (field_declaration_list)) @def' },\n { kind: 'module', query: '(namespace_definition name: (namespace_identifier) @name) @def' },\n ],\n calls: [\n '(call_expression function: (identifier) @callee)',\n '(call_expression function: (field_expression field: (field_identifier) @callee))',\n '(call_expression function: (qualified_identifier name: (identifier) @callee))',\n '(call_expression function: (qualified_identifier name: (qualified_identifier name: (identifier) @callee)))',\n '(new_expression type: (type_identifier) @callee)',\n ],\n imports: ['(preproc_include path: (string_literal) @source)', '(preproc_include path: (system_lib_string) @source)'],\n heritage: [\n '(base_class_clause (type_identifier) @extends)',\n '(base_class_clause (qualified_identifier name: (type_identifier) @extends))',\n ],\n guards: ['(call_expression function: (identifier) @_g (#match? @_g \"^(assert|static_assert)$\")) @guard'],\n};\n\nconst OBJC: LangQueries = {\n defs: [\n {\n kind: 'function',\n query: '(function_definition declarator: (function_declarator declarator: (identifier) @name)) @def',\n },\n // The selector segments are the method_definition's direct bare identifiers\n // (param names sit inside method_parameter); the first segment names it.\n { kind: 'method', query: '(method_definition (identifier) @name) @def' },\n { kind: 'class', query: '(class_implementation . (identifier) @name) @def' },\n { kind: 'interface', query: '(class_interface . (identifier) @name) @def' },\n // A @protocol is Objective-C's interface — without this it is not a node, so\n // conformance and protocol-typed DI cannot resolve.\n { kind: 'interface', query: '(protocol_declaration (identifier) @name) @def' },\n ],\n calls: [\n '(call_expression function: (identifier) @callee)',\n '(message_expression method: (identifier) @callee)',\n ],\n imports: [\n '(preproc_include path: (string_literal) @source)',\n '(preproc_include path: (system_lib_string) @source)',\n ],\n // Superclass (`: NSObject`) is `extends`; adopted protocols (`<Servicing>`,\n // captured as parameterized_arguments after the interface name) are the\n // `implements` relationship a DI call disambiguates through.\n heritage: [\n '(class_interface superclass: (identifier) @extends)',\n '(class_interface (parameterized_arguments (type_name (type_identifier) @implements)))',\n ],\n guards: ASSERT_CALLS,\n};\n\nconst OCAML: LangQueries = {\n defs: [\n // Only parameterised bindings — plain `let x = …` values would drown the\n // graph in constants.\n { kind: 'function', query: '(let_binding pattern: (value_name) @name (parameter)) @def' },\n { kind: 'module', query: '(module_binding name: (module_name) @name) @def' },\n ],\n calls: ['(application_expression function: (value_path (value_name) @callee))'],\n imports: ['(open_module (module_path (module_name) @source))'],\n heritage: [],\n};\n\nconst RESCRIPT: LangQueries = {\n defs: [\n { kind: 'function', query: '(let_binding pattern: (value_identifier) @name body: (function)) @def' },\n { kind: 'module', query: '(module_binding name: (module_identifier) @name) @def' },\n ],\n calls: [\n '(call_expression function: (value_identifier) @callee)',\n '(call_expression function: (value_identifier_path (value_identifier) @callee))',\n ],\n imports: ['(open_statement (module_identifier) @source)'],\n heritage: [],\n};\n\nconst SOLIDITY: LangQueries = {\n defs: [\n { kind: 'function', query: '(function_definition name: (identifier) @name) @def' },\n { kind: 'function', query: '(modifier_definition name: (identifier) @name) @def' },\n { kind: 'class', query: '(contract_declaration name: (identifier) @name) @def' },\n { kind: 'class', query: '(library_declaration name: (identifier) @name) @def' },\n { kind: 'interface', query: '(interface_declaration name: (identifier) @name) @def' },\n ],\n calls: [\n '(call_expression function: (identifier) @callee)',\n '(call_expression function: (member_expression property: (identifier) @callee))',\n '(emit_statement name: (identifier) @callee)',\n ],\n imports: ['(import_directive source: (string) @source)'],\n heritage: ['(inheritance_specifier ancestor: (user_defined_type (identifier) @extends))'],\n guards: [\n '(call_expression function: (identifier) @_g (#match? @_g \"^(require|assert)$\")) @guard',\n ],\n};\n\nconst BY_LANG: Record<string, LangQueries> = {\n ts: TYPESCRIPT,\n tsx: TYPESCRIPT,\n js: JAVASCRIPT,\n py: PYTHON,\n go: GO,\n java: JAVA,\n rust: RUST,\n cs: C_SHARP,\n rb: RUBY,\n php: PHP,\n kotlin: KOTLIN,\n swift: SWIFT,\n scala: SCALA,\n dart: DART,\n lua: LUA,\n ex: ELIXIR,\n sh: BASH,\n zig: ZIG,\n c: C_LANG,\n cpp: CPP,\n objc: OBJC,\n ocaml: OCAML,\n rescript: RESCRIPT,\n solidity: SOLIDITY,\n // Container formats (vue/svelte/astro/html/erb/ejs) have no entry here on\n // purpose: parse.ts routes them to their embedded language's queries.\n};\n\nexport function queriesFor(langId: string): LangQueries | undefined {\n return BY_LANG[langId];\n}\n","/**\n * Embedded-script container formats — files whose code lives in script regions\n * inside a non-code host document:\n *\n * - single-file components: Vue (`.vue`), Svelte (`.svelte`), Astro\n * (`.astro`, frontmatter fence + client `<script>`s);\n * - plain HTML with inline `<script>` blocks (`.html`/`.htm`);\n * - `<% … %>` templates: ERB (`.erb`, Ruby) and EJS (`.ejs`, JavaScript).\n *\n * The graph parses these by masking: every character outside the script\n * region(s) is replaced with a space (newlines kept), and the result is parsed\n * with the ordinary grammar of the embedded language. Masking preserves byte\n * offsets and line numbers exactly, so defs/calls/imports land on their true\n * positions in the original file and every downstream stage (resolution,\n * impact, display) works unchanged. Pure and deterministic: identical source →\n * identical mask.\n *\n * Template/markup content is intentionally out of scope — imports, exported\n * bindings, and calls all live in the script regions, which is what call/import\n * edges are built from.\n */\n\nexport interface EmbeddedScript {\n /** Effective grammar to parse the masked source with ('ts' | 'tsx' | 'js' | 'rb'). */\n langId: string;\n /** The original source with all non-script content blanked to spaces. */\n masked: string;\n}\n\ninterface ScriptTagSpec {\n kind: 'script-tags';\n /** Grammar when a block has no `lang` attribute. */\n defaultLang: string;\n /** Also extract a leading `---` frontmatter fence (Astro). */\n frontmatter?: boolean;\n}\n\ninterface DelimitedSpec {\n kind: 'delimited';\n /** The container's fixed embedded language. */\n lang: string;\n}\n\n/** Container language ids (must match the languages.ts registry entries). */\nconst CONTAINERS: Record<string, ScriptTagSpec | DelimitedSpec> = {\n vue: { kind: 'script-tags', defaultLang: 'js' },\n svelte: { kind: 'script-tags', defaultLang: 'js' },\n astro: { kind: 'script-tags', defaultLang: 'ts', frontmatter: true }, // frontmatter is TS\n html: { kind: 'script-tags', defaultLang: 'js' },\n erb: { kind: 'delimited', lang: 'rb' },\n ejs: { kind: 'delimited', lang: 'js' },\n};\n\nexport function isContainerLang(langId: string): boolean {\n return langId in CONTAINERS;\n}\n\ninterface Range {\n start: number;\n end: number;\n}\n\n// `<script …>body</script>` — non-greedy body, so multiple blocks (Vue's\n// `<script>` + `<script setup>`, Svelte's `context=\"module\"`) each match.\n// A void `<script src=… />` has an empty body and contributes nothing.\nconst SCRIPT_RE = /<script\\b([^>]*)>([\\s\\S]*?)<\\/script\\s*>/gi;\n\n// Astro frontmatter: a `---` fence on the first line, closed by a `---` line.\nconst ASTRO_FENCE_RE = /^---\\r?\\n([\\s\\S]*?)(\\r?\\n)---(?:\\r?\\n|$)/;\n\n// `<% code %>` regions (ERB/EJS): `=`/`-` output tags included, `#`/`%%`\n// comment/escape forms excluded, optional `-`/`_` trim markers kept out of the\n// body. Non-greedy to the first closer, the standard template behaviour.\nconst DELIMITED_RE = /<%(?![%#])[=\\-_]?([\\s\\S]*?)[-_]?%>/g;\n\nconst LANG_ATTR_RE = /\\blang\\s*=\\s*[\"']?([A-Za-z]+)/i;\n\n/** Rank grammars so mixed blocks pick the most permissive one (tsx ⊇ ts ⊇ js for our queries). */\nconst GRAMMAR_RANK: Record<string, number> = { js: 0, ts: 1, tsx: 2 };\n\nfunction grammarForAttr(attrs: string, fallback: string): string {\n const m = LANG_ATTR_RE.exec(attrs);\n if (!m) return fallback;\n const lang = m[1].toLowerCase();\n if (lang === 'ts' || lang === 'typescript') return 'ts';\n if (lang === 'tsx') return 'tsx';\n return 'js'; // js / jsx / anything exotic → the JS grammar\n}\n\n/**\n * Extract the script regions of a container-format file. Returns null for\n * non-container language ids (the caller parses the source as-is). A container\n * file with no script region returns a fully-blank mask — the file still gets\n * a graph node, it just defines nothing.\n */\nexport function extractEmbeddedScript(langId: string, source: string): EmbeddedScript | null {\n const spec = CONTAINERS[langId];\n if (!spec) return null;\n\n if (spec.kind === 'delimited') {\n const ranges: Range[] = [];\n for (const m of source.matchAll(DELIMITED_RE)) {\n const body = m[1] ?? '';\n if (!body.trim()) continue;\n const start = m.index + m[0].indexOf(body);\n ranges.push({ start, end: start + body.length });\n }\n // Fragments are expressions/statements cut from one template — terminate\n // each region (on the trim/closing char, still inside the match, so the\n // length is unchanged) so `<%= a %> … <%= b %>` on one line parses as two\n // statements rather than one garbled one.\n return { langId: spec.lang, masked: mask(source, ranges, { terminate: true }) };\n }\n\n const ranges: Range[] = [];\n let grammar = spec.defaultLang;\n\n if (spec.frontmatter) {\n const fence = ASTRO_FENCE_RE.exec(source);\n if (fence) {\n const start = fence[0].indexOf('\\n') + 1;\n ranges.push({ start, end: start + fence[1].length });\n }\n }\n\n for (const m of source.matchAll(SCRIPT_RE)) {\n const attrs = m[1] ?? '';\n const body = m[2] ?? '';\n if (!body) continue;\n const start = m.index + '<script'.length + attrs.length + 1; // past the tag's '>'\n ranges.push({ start, end: start + body.length });\n const g = grammarForAttr(attrs, spec.defaultLang);\n if (GRAMMAR_RANK[g] > GRAMMAR_RANK[grammar]) grammar = g;\n }\n\n return { langId: grammar, masked: mask(source, ranges) };\n}\n\n/**\n * Blank everything outside `ranges` to spaces, preserving newlines (and CR).\n * With `terminate`, the character right after each range (part of the closing\n * delimiter, never a newline) becomes `;` — a statement boundary for the\n * embedded language.\n */\nfunction mask(source: string, ranges: Range[], opts: { terminate?: boolean } = {}): string {\n const out = new Array<string>(source.length);\n for (let i = 0; i < source.length; i++) {\n const ch = source[i];\n out[i] = ch === '\\n' || ch === '\\r' ? ch : ' ';\n }\n for (const r of ranges) {\n for (let i = r.start; i < r.end && i < source.length; i++) out[i] = source[i];\n if (opts.terminate && r.end < source.length && out[r.end] === ' ') out[r.end] = ';';\n }\n return out.join('');\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { createRequire } from 'node:module';\nimport { Parser, Language } from 'web-tree-sitter';\nimport { grammarDirs, ensureParserInit } from '../grammars.js';\n\n/**\n * Grammar loading for the **toolchain** corpus (infrastructure, CI, config).\n *\n * Deliberately separate from `engine/grammars.ts`'s language registry. Adding\n * these grammars to `LANGUAGES` would make `discover.ts` treat every `.tf` /\n * `.yaml` / `.json` in a repository as a *source* file, which silently changes:\n *\n * - `project-classification.ts` source-file counts — and those pick the\n * billing tier, so a config-heavy repo would jump a tier for free;\n * - DriftScore, coverage ratios, file-hotspot and code-quality metrics.\n *\n * So the toolchain corpus is discovered separately (via `docs-ingest`, which\n * already classifies exactly these files) and parsed with its own grammar set.\n * The source corpus is untouched.\n *\n * ## Why only HCL\n *\n * YAML, JSON and TOML are *not* parsed with tree-sitter here. The repository\n * already depends on `yaml` (which yields byte ranges on every node, plus\n * multi-document, anchor and merge-key support that a grammar would force us to\n * reimplement) and `smol-toml`. Reusing audited parsers beats adding grammars.\n * HCL has no such parser in the tree, so it gets a grammar.\n *\n * ## Supply chain\n *\n * `@tree-sitter-grammars/tree-sitter-hcl` carries a native `install` script\n * (`node-gyp-build`) for its Node bindings. It is therefore a **devDependency**\n * only: `scripts/bundle-grammars.mjs` copies its prebuilt `.wasm` into\n * `grammars/` at build time, and that file ships inside the published tarball.\n * End users receive the grammar; they never install the grammar package and\n * never run its install script.\n */\n\nconst require = createRequire(import.meta.url);\n\n/** Toolchain grammar ids → the `.wasm` base name and its owning npm package. */\nexport const TOOLCHAIN_GRAMMARS: Record<string, { wasm: string; pkg: string }> = {\n hcl: { wasm: 'tree-sitter-hcl', pkg: '@tree-sitter-grammars/tree-sitter-hcl' },\n};\n\nconst languageCache = new Map<string, Language>();\n\n/**\n * Directories to search for a toolchain grammar, highest priority first: the\n * same set the source grammars use (so `--grammars <dir>` and the bundled\n * `grammars/` both work), then the owning devDependency's package root as the\n * dev/test fallback before a `pnpm build` has run.\n */\nfunction toolchainGrammarDirs(pkg: string): string[] {\n const dirs = [...grammarDirs()];\n try {\n dirs.push(path.dirname(require.resolve(`${pkg}/package.json`)));\n } catch {\n /* devDependency absent (e.g. a published install) — the bundled dirs cover it */\n }\n return dirs;\n}\n\n/** Absolute path to a toolchain grammar's `.wasm`, or null when unavailable. */\nexport function resolveToolchainGrammar(id: string): string | null {\n const spec = TOOLCHAIN_GRAMMARS[id];\n if (!spec) return null;\n for (const dir of toolchainGrammarDirs(spec.pkg)) {\n const candidate = path.join(dir, `${spec.wasm}.wasm`);\n if (fs.existsSync(candidate)) return candidate;\n }\n return null;\n}\n\n/**\n * Load (and cache) a toolchain grammar.\n *\n * Returns `null` rather than throwing when the grammar is unavailable: a\n * missing toolchain grammar must degrade to \"no structural extraction for that\n * format\", never fail a build. The caller surfaces a warning.\n */\nexport async function loadToolchainLanguage(id: string): Promise<Language | null> {\n const cached = languageCache.get(id);\n if (cached) return cached;\n const wasmPath = resolveToolchainGrammar(id);\n if (!wasmPath) return null;\n try {\n await ensureParserInit();\n const language = await Language.load(fs.readFileSync(wasmPath));\n languageCache.set(id, language);\n return language;\n } catch {\n return null;\n }\n}\n\n/** A parser bound to a toolchain grammar, or null when the grammar is unavailable. */\nexport async function toolchainParser(id: string): Promise<Parser | null> {\n const language = await loadToolchainLanguage(id);\n if (!language) return null;\n const parser = new Parser();\n parser.setLanguage(language);\n return parser;\n}\n\n/**\n * Version string for the toolchain grammar set — a determinism input recorded\n * in provenance alongside `grammarSetVersion()`. Resolved from the owning\n * package when present; `unknown` once the package is absent (published\n * installs), which is stable because the shipped `.wasm` is fixed at publish.\n */\nexport function toolchainGrammarSetVersion(): string {\n const parts: string[] = [];\n for (const id of Object.keys(TOOLCHAIN_GRAMMARS).sort()) {\n const { pkg } = TOOLCHAIN_GRAMMARS[id];\n let version = 'bundled';\n try {\n const json = require.resolve(`${pkg}/package.json`);\n version = (JSON.parse(fs.readFileSync(json, 'utf8')) as { version: string }).version;\n } catch {\n /* published install — the bundled .wasm is fixed, so `bundled` is stable */\n }\n parts.push(`${pkg}@${version}`);\n }\n return parts.join(',');\n}\n\n/** Reset the language cache. Test-only. */\nexport function resetToolchainGrammarCache(): void {\n languageCache.clear();\n}\n","import { Query, type Language, type Node } from 'web-tree-sitter';\nimport {\n catalogForLanguage,\n sourceHasRoleNeedle,\n type AstRoleCatalogEntry,\n} from '../core-open/scanners/architecture/packs/ast-role-catalog.js';\nimport type { AstRoleHit } from '../core-open/scanners/architecture/ast-roles.js';\nimport type { FileParse } from './types.js';\nimport { loadCache } from './cache.js';\nimport { grammarSetVersion } from './grammars.js';\nimport { toolchainGrammarSetVersion } from './toolchain/grammars.js';\nimport { VERSION } from '../version.js';\n\n/**\n * Run pack-scoped role queries against the tree `buildGraph` already paid for.\n * A compile miss falls back to the needle matcher — never a second parse.\n */\n\nconst compiledCache = new Map<string, Query | null>();\n\nfunction compile(lang: Language, langId: string, source: string): Query | null {\n const key = `${langId}::${source}`;\n if (compiledCache.has(key)) return compiledCache.get(key) ?? null;\n let q: Query | null = null;\n try {\n q = new Query(lang, source);\n } catch {\n q = null;\n }\n compiledCache.set(key, q);\n return q;\n}\n\nfunction entryHits(\n lang: Language,\n langId: string,\n root: Node,\n source: string,\n entry: AstRoleCatalogEntry,\n): boolean {\n const compiled = compile(lang, langId, entry.query);\n if (!compiled) return sourceHasRoleNeedle(source, entry.needle);\n try {\n return compiled.captures(root).length > 0;\n } catch {\n return sourceHasRoleNeedle(source, entry.needle);\n }\n}\n\nexport function extractAstRolesFromTree(\n _rel: string,\n langId: string,\n language: Language,\n root: Node,\n source: string,\n): FileParse['roles'] {\n const catalog = catalogForLanguage(langId);\n if (catalog.length === 0) return undefined;\n const hits: NonNullable<FileParse['roles']> = [];\n for (const entry of catalog) {\n if (!entryHits(language, langId, root, source, entry)) continue;\n hits.push({\n role: entry.role,\n layer: entry.layer,\n confidence: entry.confidence,\n signal: entry.signal,\n packId: entry.packId,\n });\n }\n if (hits.length === 0) return undefined;\n hits.sort((a, b) =>\n b.confidence - a.confidence\n || a.packId.localeCompare(b.packId)\n || a.role.localeCompare(b.role),\n );\n return hits;\n}\n\nexport function fileRolesFromParses(parses: readonly FileParse[]): AstRoleHit[] {\n const hits: AstRoleHit[] = [];\n for (const parse of parses) {\n if (!parse.roles?.length) continue;\n const rel = (parse.rel || '.').replace(/\\\\/g, '/');\n for (const role of parse.roles) {\n hits.push({\n filePath: rel,\n role: role.role,\n layer: role.layer,\n confidence: role.confidence,\n signal: role.signal,\n packId: role.packId,\n });\n }\n }\n return hits;\n}\n\n/**\n * Recover architecture role hits from the versioned parse cache.\n * Used by the LSP when the map is loaded from disk (no in-process build).\n */\nexport function fileRolesFromParseCache(root: string): AstRoleHit[] {\n const grammars = `${grammarSetVersion()}+${toolchainGrammarSetVersion()}`;\n const cache = loadCache(root, { toolVersion: VERSION, grammars });\n return fileRolesFromParses(cache.allParses());\n}\n","import { Query, type Node, type Language } from 'web-tree-sitter';\nimport { parserFor, loadLanguage } from './grammars.js';\nimport { langById } from './languages.js';\nimport { queriesFor, type DefRule } from './queries.js';\nimport { extractEmbeddedScript } from './sfc.js';\nimport { hashString } from './hash.js';\nimport { redactSecrets } from '../core-open/utils/redact.js';\nimport { extractAstRolesFromTree } from './ast-roles.js';\nimport type { FileParse, RawCall, RawDef, RawGuard, RawHeritage, RawImport, RawTypeRef } from './types.js';\n\n/**\n * Parse a single file's source into the raw symbol/edge tables. Pure and\n * deterministic: identical (lang, source) → identical FileParse. Cross-file\n * resolution is a later stage (resolve.ts); here we only see one file.\n */\n\n// Compiled queries are cached per (lang, querySource) — compilation is the\n// expensive part and queries are reused across every file of a language.\nconst compiledCache = new Map<string, Query | null>();\n\nfunction compile(lang: Language, langId: string, source: string): Query | null {\n const key = `${langId}::${source}`;\n if (compiledCache.has(key)) return compiledCache.get(key) ?? null;\n let q: Query | null = null;\n try {\n q = new Query(lang, source);\n } catch {\n q = null; // grammar doesn't support this pattern — skip it gracefully\n }\n compiledCache.set(key, q);\n return q;\n}\n\nfunction namedCapture(\n captures: { name: string; node: Node }[],\n name: string,\n): Node | undefined {\n return captures.find((c) => c.name === name)?.node;\n}\n\n/**\n * Wrapper node types that sit between a *qualified* callee identifier and the\n * call node (`obj.foo()` / `pkg::foo()` / `recv.foo()` across the grammars).\n * A bare call's identifier hangs directly off the call node instead.\n */\nconst MEMBER_PARENT_TYPES = new Set([\n 'member_expression', // ts/js: obj.foo()\n 'attribute', // python: obj.foo()\n 'selector_expression', // go: pkg.Foo()\n 'field_expression', // rust/scala/c/cpp/zig: recv.foo()\n 'scoped_identifier', // rust: Type::foo()\n 'member_access_expression', // c#: obj.Foo()\n 'qualified_identifier', // c++: ns::f(), Type::m()\n 'dot', // elixir: Mod.fun()\n 'navigation_suffix', // kotlin/swift: recv.foo()\n 'member_call_expression', // php: $x->m()\n 'nullsafe_member_call_expression', // php: $x?->m()\n 'scoped_call_expression', // php: X::m()\n 'unconditional_assignable_selector', // dart: x.foo()\n 'conditional_assignable_selector', // dart: x?.foo()\n 'cascade_selector', // dart: x..foo()\n 'value_identifier_path', // rescript: Mod.foo() (only exists for qualified calls)\n]);\n\n/**\n * Was this callee identifier part of a qualified call (`x.foo()`) rather than a\n * bare one (`foo()`)? The queries capture only the trailing name, so the\n * resolver needs this bit to know a same-file def with the same short name is\n * NOT evidence — the receiver points elsewhere (see resolve.ts).\n */\nfunction isQualifiedCallee(node: Node): boolean {\n const parent = node.parent;\n if (!parent) return false;\n if (MEMBER_PARENT_TYPES.has(parent.type)) return true;\n // Java `method_invocation` and Ruby `call` keep receiver and name on the call\n // node itself — qualified iff the receiver/object field is present.\n if (parent.type === 'method_invocation') return parent.childForFieldName('object') != null;\n // Ruby `call` carries a `receiver` field when qualified; Python's `call` has\n // no such field (its qualified form is the `attribute` wrapper above), and\n // Elixir's `call` has none either (its qualified form is the `dot` wrapper).\n if (parent.type === 'call') return parent.childForFieldName('receiver') != null;\n // Lua wraps every callee in `variable`; qualified iff a `table` receiver exists\n // (`repo.fetch()` / `repo:method()` carry table:, bare `foo()` has only name:).\n if (parent.type === 'variable') return parent.childForFieldName('table') != null;\n // OCaml wraps every callee in `value_path`; qualified iff a module path is\n // present (`Mod.f x` has two named children, bare `f x` has one).\n if (parent.type === 'value_path') return parent.namedChildCount > 1;\n // ObjC message sends: `[obj doThing]` points elsewhere, but `[self …]` /\n // `[super …]` stay within the class — same-file evidence still counts there.\n if (parent.type === 'message_expression') {\n const recv = parent.childForFieldName('receiver');\n return recv != null && recv.text !== 'self' && recv.text !== 'super';\n }\n return false;\n}\n\nfunction signatureOf(source: string, def: Node, langId: string): string {\n // The text up to the body opening, single-lined, bounded — a deterministic,\n // human-meaningful signature without dragging in the whole body.\n // - Brace languages: cut at the body `{`.\n // - Python: cut at the def-terminating `:` at bracket-depth 0 (so a `:` inside\n // typed params / generics / the `-> Dict[...]` return type doesn't cut it,\n // and the docstring/body is excluded).\n // - Ruby: the header is the first line.\n const full = source.slice(def.startIndex, def.endIndex);\n let head: string;\n if (langId === 'py') head = pythonHeader(full);\n // Ruby/Elixir: `do…end` bodies (and Elixir `%{}` default args would break a\n // brace cut) — the header is the first line.\n else if (langId === 'rb' || langId === 'ex') head = full.split('\\n')[0];\n else {\n const braceIdx = full.indexOf('{');\n head = braceIdx >= 0 ? full.slice(0, braceIdx) : full.split('\\n')[0];\n }\n head = head.replace(/\\s+/g, ' ').trim().replace(/[:{]\\s*$/, '').trim();\n return head.length > 200 ? `${head.slice(0, 197)}...` : head;\n}\n\n/**\n * A short doc summary for a definition — the leading doc-comment (JSDoc/TSDoc,\n * `//`, `///`, `#`) directly above it, or (Python) the body docstring. Gives a\n * tersely-named symbol real prose for semantic search. Deterministic, marker-\n * stripped, whitespace-collapsed, truncated; never the full body. Returns\n * undefined when there is no doc.\n */\nfunction scrubbedDoc(source: string, def: Node, langId: string): string | undefined {\n const doc = docOf(source, def, langId);\n return doc === undefined ? undefined : redactSecrets(doc);\n}\n\nfunction docOf(source: string, def: Node, langId: string): string | undefined {\n const lines = source.split('\\n');\n if (langId === 'py') return pythonDocstring(lines, def.startPosition.row);\n return leadingComment(lines, def.startPosition.row);\n}\n\n/** Contiguous comment lines directly above `row` (0-based), markers stripped. */\nfunction leadingComment(lines: string[], row: number): string | undefined {\n const collected: string[] = [];\n for (let r = row - 1; r >= 0; r--) {\n const line = lines[r].trim();\n if (line === '') break; // a blank line detaches the comment\n if (/^(\\/\\/|\\/\\*\\*?|\\*\\/?|#|;|--)/.test(line)) collected.unshift(line);\n else break;\n }\n if (!collected.length) return undefined;\n const text = collected\n .join('\\n')\n .replace(/\\/\\*\\*?|\\*\\//g, ' ') // /** and */\n .replace(/^\\s*[*]\\s?/gm, ' ') // leading * in block comments\n .replace(/^\\s*(\\/\\/+|#+|;+|--)\\s?/gm, ' ') // line-comment markers\n .replace(/@\\w+/g, ' '); // drop JSDoc tags (@param, @returns…)\n return clip(text);\n}\n\n/** The first string literal in a Python body (the docstring), if present. */\nfunction pythonDocstring(lines: string[], row: number): string | undefined {\n // Find the header's terminating line (ends with ':'), then the first non-blank line.\n let r = row;\n while (r < lines.length && !/:\\s*(#.*)?$/.test(lines[r])) r++;\n let j = r + 1;\n while (j < lines.length && lines[j].trim() === '') j++;\n const first = lines[j]?.trim() ?? '';\n const m = /^[rubfRUBF]{0,2}(\"\"\"|''')/.exec(first);\n if (!m) return undefined;\n const q = m[1];\n let rest = first.slice(first.indexOf(q) + 3);\n if (rest.includes(q)) return clip(rest.slice(0, rest.indexOf(q))); // single-line docstring\n const parts = [rest];\n for (let k = j + 1; k < lines.length; k++) {\n const idx = lines[k].indexOf(q);\n if (idx >= 0) {\n parts.push(lines[k].slice(0, idx));\n break;\n }\n parts.push(lines[k]);\n }\n return clip(parts.join(' '));\n}\n\nfunction clip(s: string): string | undefined {\n const t = s.replace(/\\s+/g, ' ').trim();\n if (!t) return undefined;\n return t.length > 200 ? `${t.slice(0, 197)}...` : t;\n}\n\n/** Python def/class header up to the terminating `:` at bracket-depth 0. */\nfunction pythonHeader(full: string): string {\n let depth = 0;\n for (let i = 0; i < full.length; i++) {\n const c = full[i];\n if (c === '(' || c === '[' || c === '{') depth++;\n else if (c === ')' || c === ']' || c === '}') depth--;\n else if (c === ':' && depth === 0) return full.slice(0, i);\n }\n return full.split('\\n')[0];\n}\n\nexport async function parseSource(\n rel: string,\n langId: string,\n source: string,\n): Promise<FileParse> {\n // Pure extractors (no tree-sitter) — SQL DDL topology.\n if (langId === 'sql') {\n const { parseSqlFile } = await import('./sql-extract.js');\n return parseSqlFile(rel, source);\n }\n\n // Container formats (Vue/Svelte/Astro SFCs): parse the embedded script\n // region with the JS/TS grammar over a position-preserving mask, so every\n // offset/line below refers to the original file. The node keeps the\n // container's own lang id.\n const embedded = extractEmbeddedScript(langId, source);\n const effLangId = embedded?.langId ?? langId;\n const text = embedded?.masked ?? source;\n const def = langById(effLangId);\n const langQueries = queriesFor(effLangId);\n const hash = hashString(source);\n const result: FileParse = {\n rel,\n lang: langId,\n hash,\n bytes: Buffer.byteLength(source, 'utf8'),\n defs: [],\n calls: [],\n imports: [],\n heritage: [],\n typeRefs: [],\n guards: [],\n };\n if (!def || !langQueries) return result;\n\n const language = await loadLanguage(effLangId);\n const parser = await parserFor(def);\n const tree = parser.parse(text);\n if (!tree) return result;\n const root = tree.rootNode;\n\n // --- definitions ---\n const rawDefs: (RawDef & { _start: number; _end: number })[] = [];\n for (const rule of langQueries.defs) {\n collectDefs(language, effLangId, text, root, rule, rawDefs);\n }\n // Dedupe definitions that overlap on the same name+range (multiple rules can\n // match the same node, e.g. abstract vs plain class).\n const seen = new Set<string>();\n const deduped = rawDefs.filter((d) => {\n const key = `${d._start}:${d._end}:${d.name}:${d.kind}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n // Compute dotted qualified names by nesting (smallest enclosing def is parent).\n const byStart = [...deduped].sort((a, b) => a._start - b._start || b._end - a._end);\n for (const d of byStart) {\n const parent = enclosing(byStart, d._start, d._end);\n d.qualifiedName = parent ? `${parent.qualifiedName}.${d.name}` : d.name;\n }\n result.defs = byStart\n .map((d) => {\n const { _start, _end, ...rest } = d;\n void _start;\n void _end;\n return rest;\n })\n .sort(\n (a, b) =>\n a.startLine - b.startLine ||\n a.qualifiedName.localeCompare(b.qualifiedName) ||\n a.name.localeCompare(b.name),\n );\n\n // --- calls ---\n // A definition's own name node must never double as a call site: in\n // expression-based grammars (Elixir) a `def foo(…)` head is itself a `call`\n // node, which would fabricate a recursion edge for every definition.\n const defNameBytes = new Set<number>();\n for (const qsrc of langQueries.defs) {\n const q = compile(language, effLangId, qsrc.query);\n if (!q) continue;\n for (const m of q.matches(root)) {\n const nameNode = namedCapture(m.captures, 'name');\n if (nameNode) defNameBytes.add(nameNode.startIndex);\n }\n }\n const calls: RawCall[] = [];\n for (const qsrc of langQueries.calls) {\n const q = compile(language, effLangId, qsrc);\n if (!q) continue;\n for (const cap of q.captures(root)) {\n if (cap.name !== 'callee') continue;\n if (defNameBytes.has(cap.node.startIndex)) continue;\n calls.push({\n callee: cap.node.text,\n byte: cap.node.startIndex,\n line: cap.node.startPosition.row + 1,\n qualified: isQualifiedCallee(cap.node),\n });\n }\n }\n result.calls = calls.sort((a, b) => a.byte - b.byte || a.callee.localeCompare(b.callee));\n\n // --- imports ---\n const imports: RawImport[] = [];\n for (const qsrc of langQueries.imports) {\n const q = compile(language, effLangId, qsrc);\n if (!q) continue;\n for (const cap of q.captures(root)) {\n if (cap.name !== 'source') continue;\n imports.push({ source: stripQuotes(cap.node.text) });\n }\n }\n result.imports = dedupeImports(imports);\n\n // --- heritage (extends / implements) ---\n const heritage: RawHeritage[] = [];\n for (const qsrc of langQueries.heritage) {\n const q = compile(language, effLangId, qsrc);\n if (!q) continue;\n for (const cap of q.captures(root)) {\n if (cap.name !== 'extends' && cap.name !== 'implements') continue;\n heritage.push({ superName: cap.node.text, byte: cap.node.startIndex, kind: cap.name });\n }\n }\n result.heritage = heritage.sort(\n (a, b) =>\n a.byte - b.byte || a.kind.localeCompare(b.kind) || a.superName.localeCompare(b.superName),\n );\n\n // --- type references (constructor-param / field types → DI dependency edges) ---\n const typeRefs: RawTypeRef[] = [];\n for (const qsrc of langQueries.typeRefs ?? []) {\n const q = compile(language, effLangId, qsrc);\n if (!q) continue;\n for (const cap of q.captures(root)) {\n if (cap.name !== 'typeref') continue;\n typeRefs.push({ name: cap.node.text, byte: cap.node.startIndex });\n }\n }\n result.typeRefs = typeRefs.sort((a, b) => a.byte - b.byte || a.name.localeCompare(b.name));\n\n // --- namespaces declared by this file (C# cross-namespace resolution) ---\n const namespaces = new Set<string>();\n for (const qsrc of langQueries.namespaces ?? []) {\n const q = compile(language, effLangId, qsrc);\n if (!q) continue;\n for (const cap of q.captures(root)) {\n if (cap.name !== 'namespace') continue;\n const name = cap.node.text.trim();\n if (name) namespaces.add(name);\n }\n }\n if (namespaces.size) result.namespaces = [...namespaces].sort();\n\n // --- guards (assert-like expressions → invariant facts) ---\n const guards: RawGuard[] = [];\n for (const qsrc of langQueries.guards ?? []) {\n const q = compile(language, effLangId, qsrc);\n if (!q) continue;\n for (const cap of q.captures(root)) {\n if (cap.name !== 'guard') continue;\n const expr = cap.node.text.replace(/\\s+/g, ' ').trim();\n guards.push({ expr: expr.length > 160 ? `${expr.slice(0, 157)}...` : expr, line: cap.node.startPosition.row + 1 });\n }\n }\n result.guards = guards.sort((a, b) => a.line - b.line || a.expr.localeCompare(b.expr));\n\n const roles = extractAstRolesFromTree(rel, effLangId, language, root, text);\n if (roles) result.roles = roles;\n\n tree.delete();\n return result;\n}\n\n/**\n * Dart splits a function into sibling signature + body nodes (and wraps class\n * methods in a method_signature). Return the trailing function_body so the def\n * span covers it — otherwise calls inside the body attribute to the file and\n * nested defs do not nest.\n */\nfunction dartBodyOf(defNode: Node): Node | null {\n if (!defNode.type.endsWith('_signature')) return null;\n if (defNode.nextNamedSibling?.type === 'function_body') return defNode.nextNamedSibling;\n const wrapper = defNode.parent;\n if (wrapper?.type === 'method_signature' && wrapper.nextNamedSibling?.type === 'function_body') {\n return wrapper.nextNamedSibling;\n }\n return null;\n}\n\nfunction collectDefs(\n language: Language,\n langId: string,\n source: string,\n root: Node,\n rule: DefRule,\n out: (RawDef & { _start: number; _end: number })[],\n): void {\n const q = compile(language, langId, rule.query);\n if (!q) return;\n for (const match of q.matches(root)) {\n const defNode = namedCapture(match.captures, 'def');\n const nameNode = namedCapture(match.captures, 'name');\n if (!defNode || !nameNode) continue;\n // Dart splits a function into sibling signature + body nodes; the def span\n // must cover the body or calls inside it would attribute to the file, and\n // nested defs would not nest.\n const spanEnd = dartBodyOf(defNode) ?? defNode;\n out.push({\n kind: rule.kind,\n name: nameNode.text,\n qualifiedName: nameNode.text, // refined after nesting is computed\n startLine: defNode.startPosition.row + 1,\n endLine: spanEnd.endPosition.row + 1,\n startByte: defNode.startIndex,\n endByte: spanEnd.endIndex,\n signature:\n rule.kind === 'function' || rule.kind === 'method'\n ? redactSecrets(signatureOf(source, defNode, langId))\n : undefined,\n // GUARDRAILS §1: signatures/docs are lifted verbatim from source and are\n // persisted (graph.json, `vg share` commits it) — scrub at ingest.\n doc: scrubbedDoc(source, defNode, langId),\n visibility: undefined,\n _start: defNode.startIndex,\n _end: spanEnd.endIndex,\n });\n }\n}\n\n/** The smallest def strictly containing [start,end) other than itself. */\nfunction enclosing(\n defs: { qualifiedName: string; _start: number; _end: number }[],\n start: number,\n end: number,\n): { qualifiedName: string } | undefined {\n let best: { qualifiedName: string; _start: number; _end: number } | undefined;\n for (const d of defs) {\n if (d._start === start && d._end === end) continue;\n if (d._start <= start && d._end >= end) {\n if (!best || d._end - d._start < best._end - best._start) best = d;\n }\n }\n return best;\n}\n\nfunction stripQuotes(text: string): string {\n return text.replace(/^['\"`]|['\"`]$/g, '');\n}\n\nfunction dedupeImports(imports: RawImport[]): RawImport[] {\n const seen = new Set<string>();\n const out: RawImport[] = [];\n for (const i of imports.sort((a, b) => a.source.localeCompare(b.source))) {\n if (seen.has(i.source)) continue;\n seen.add(i.source);\n out.push(i);\n }\n return out;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { loadGraphFileWithSnapshot, resolveGraphPath } from './chunk-
|
|
1
|
+
import { loadGraphFileWithSnapshot, resolveGraphPath } from './chunk-OIUVWCKM.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-7M4E7UGX.js.map
|
|
204
|
+
//# sourceMappingURL=chunk-7M4E7UGX.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-SGIFJIII.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-7M4E7UGX.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,6 +1,6 @@
|
|
|
1
1
|
import { resolveIngestHost } from './chunk-HTLDXEHW.js';
|
|
2
2
|
import { cacheDir } from './chunk-MVPRPSXU.js';
|
|
3
|
-
import { VERSION } from './chunk-
|
|
3
|
+
import { VERSION } from './chunk-G3ACLBMG.js';
|
|
4
4
|
import * as fs from 'fs';
|
|
5
5
|
import * as os from 'os';
|
|
6
6
|
import * as path from 'path';
|
|
@@ -212,5 +212,5 @@ var StatsSharer = class {
|
|
|
212
212
|
};
|
|
213
213
|
|
|
214
214
|
export { StatsSharer, installId, isCI, statsEndpoint, telemetryOptOut };
|
|
215
|
-
//# sourceMappingURL=chunk-
|
|
216
|
-
//# sourceMappingURL=chunk-
|
|
215
|
+
//# sourceMappingURL=chunk-BICZR6UJ.js.map
|
|
216
|
+
//# sourceMappingURL=chunk-BICZR6UJ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/engine/stats-share.ts"],"names":[],"mappings":"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","file":"chunk-KBLKNR3V.js","sourcesContent":["import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport { cacheDir } from './cache.js';\nimport { VERSION } from '../version.js';\nimport { resolveIngestHost } from '../reporting/regions.js';\nimport type { SavingEntry, Source, Outcome } from './savings.js';\n\n/**\n * Opt-in usage-stats sharing for `vg serve --share-stats`.\n *\n * This is the ONLY path in `vg serve` that sends anything off the machine, and\n * it is off unless the operator explicitly asks for it. What we send is the\n * same counts-only ledger `vg savings` reports locally — per (source, client,\n * tool, outcome): how many calls and the vg-vs-grep token figures — plus the vg\n * version, OS/arch, and a random per-install id. We never send code, file paths,\n * question text, repo identity, or any credential. See GUARDRAILS §3.4.\n *\n * Even when the flag is passed, the universal `DO_NOT_TRACK` opt-out (or\n * `VIBGRATE_TELEMETRY=0`) wins: nothing is uploaded and no install id is ever\n * minted or persisted (see `telemetryOptOut` / `installId`).\n *\n * Design:\n * - The local ledger (savings.jsonl) is the single source of truth; the flusher\n * reads only the tail past a persisted byte offset, so a batch is sent once.\n * - Fire-and-forget with a short timeout. A network problem never blocks a tool\n * call and never throws — the offset only advances on a confirmed 2xx, so a\n * failed batch is retried on the next flush.\n * - Fully offline-safe: under `--local` the sharer is never constructed.\n */\n\n/** Payload schema version — must match the server's `mcpUsageStatsSchema`. */\nconst SCHEMA_VERSION = '1';\n/** Where the offset (and cached install id) live, per repo, beside the ledger. */\nconst OFFSET_FILE = 'stats-share.json';\n/** The machine-global anonymous install id lives here (stable across repos). */\nconst INSTALL_ID_DIR = path.join(os.homedir(), '.vibgrate');\nconst INSTALL_ID_FILE = path.join(INSTALL_ID_DIR, 'install-id');\n/** Give a flush POST a hard ceiling so a hung endpoint never stalls shutdown. */\nconst SEND_TIMEOUT_MS = 4000;\n\n/** One aggregated row of the shared batch — counts only. */\nexport interface StatsRow {\n source: Source;\n client: string;\n tool: string;\n outcome: Outcome;\n calls: number;\n vgTokens: number;\n baselineTokens: number;\n}\n\n/** The counts-only batch POSTed to the ingest endpoint. */\nexport interface StatsBatch {\n schemaVersion: string;\n installId: string;\n vgVersion: string;\n os: string;\n arch: string;\n windowStart: string;\n windowEnd: string;\n totalCalls: number;\n rows: StatsRow[];\n}\n\n/**\n * The universal opt-out (https://consoledonottrack.com) plus a tool-specific\n * alias, honoured even when `--share-stats` is passed explicitly. Pure function\n * of the environment for testability. Returns the name of the variable that\n * opted out (for the disclosure message), or null when sharing may proceed.\n */\nexport function telemetryOptOut(env: NodeJS.ProcessEnv = process.env): string | null {\n const dnt = (env.DO_NOT_TRACK ?? '').trim().toLowerCase();\n if (dnt !== '' && dnt !== '0' && dnt !== 'false') return 'DO_NOT_TRACK';\n const vt = (env.VIBGRATE_TELEMETRY ?? '').trim().toLowerCase();\n if (vt === '0' || vt === 'false' || vt === 'off') return 'VIBGRATE_TELEMETRY';\n return null;\n}\n\n/** Common CI environment markers — a CI runner is never an interactive session. */\nconst CI_ENV_VARS = [\n 'CI',\n 'GITHUB_ACTIONS',\n 'GITLAB_CI',\n 'CIRCLECI',\n 'TRAVIS',\n 'BUILDKITE',\n 'JENKINS_URL',\n 'TF_BUILD',\n] as const;\n\n/** True when running under a recognised CI system. Pure function of the env. */\nexport function isCI(env: NodeJS.ProcessEnv = process.env): boolean {\n return CI_ENV_VARS.some((v) => {\n const val = (env[v] ?? '').trim().toLowerCase();\n return val !== '' && val !== '0' && val !== 'false';\n });\n}\n\n/**\n * Read (or lazily create) the anonymous per-install id — a random UUID stored in\n * `~/.vibgrate/install-id`. It is *not* tied to the user, the repo, or any\n * account; it only lets us de-duplicate batches from the same install when\n * aggregating. If the home dir isn't writable we fall back to an ephemeral id\n * so sharing still works (it just can't be de-duplicated across restarts).\n *\n * Under an env opt-out no id is ever read or persisted (the sharing path isn't\n * reached then either — this is defence in depth), and on CI runners the id is\n * ephemeral: a persisted id on a shared/throwaway runner would be meaningless\n * for de-duplication and would leave state behind on machines we don't own.\n */\nexport function installId(env: NodeJS.ProcessEnv = process.env): string {\n if (telemetryOptOut(env) !== null || isCI(env)) return randomUuid();\n try {\n const existing = fs.readFileSync(INSTALL_ID_FILE, 'utf8').trim();\n if (isUuid(existing)) return existing;\n } catch {\n /* not created yet */\n }\n const id = randomUuid();\n try {\n fs.mkdirSync(INSTALL_ID_DIR, { recursive: true });\n fs.writeFileSync(INSTALL_ID_FILE, id + '\\n', { mode: 0o600 });\n } catch {\n /* home dir read-only — use the ephemeral id for this process */\n }\n return id;\n}\n\nfunction isUuid(s: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s);\n}\n\nfunction randomUuid(): string {\n return randomUUID();\n}\n\n/** Resolve the ingest endpoint: env override wins, else the default region host. */\nexport function statsEndpoint(): string {\n const override = process.env.VIBGRATE_STATS_ENDPOINT;\n if (override && /^https?:\\/\\//.test(override)) return override;\n return `https://${resolveIngestHost()}/v1/ingest/cli-mcp-usage`;\n}\n\nfunction offsetPath(root: string): string {\n return path.join(cacheDir(root), OFFSET_FILE);\n}\n\nfunction ledgerFilePath(root: string): string {\n return path.join(cacheDir(root), 'savings.jsonl');\n}\n\nfunction readOffset(root: string): number {\n try {\n const raw = JSON.parse(fs.readFileSync(offsetPath(root), 'utf8')) as { offset?: number };\n return typeof raw.offset === 'number' && raw.offset >= 0 ? raw.offset : 0;\n } catch {\n return 0;\n }\n}\n\nfunction writeOffset(root: string, offset: number): void {\n try {\n fs.mkdirSync(cacheDir(root), { recursive: true });\n fs.writeFileSync(offsetPath(root), JSON.stringify({ offset }) + '\\n');\n } catch {\n /* best-effort; a lost offset just means one batch may re-send */\n }\n}\n\n/**\n * Aggregate the ledger entries after `fromOffset` into a counts-only batch.\n * Returns the batch (or null if there's nothing new) and the new byte offset to\n * persist once the batch is confirmed sent.\n */\nexport function buildBatch(\n root: string,\n fromOffset: number,\n id = installId(),\n): { batch: StatsBatch | null; newOffset: number } {\n const file = ledgerFilePath(root);\n let size = 0;\n try {\n size = fs.statSync(file).size;\n } catch {\n return { batch: null, newOffset: 0 };\n }\n // The ledger was truncated/recreated under us — re-read from the top.\n const start = fromOffset > size ? 0 : fromOffset;\n if (start >= size) return { batch: null, newOffset: size };\n\n let text = '';\n try {\n const fd = fs.openSync(file, 'r');\n try {\n const buf = Buffer.alloc(size - start);\n fs.readSync(fd, buf, 0, buf.length, start);\n text = buf.toString('utf8');\n } finally {\n fs.closeSync(fd);\n }\n } catch {\n return { batch: null, newOffset: fromOffset };\n }\n\n // Only whole lines are complete; a trailing partial line (mid-append) is left\n // for the next flush by rewinding the offset to the last newline.\n const lastNl = text.lastIndexOf('\\n');\n if (lastNl < 0) return { batch: null, newOffset: start };\n const consumed = start + lastNl + 1;\n const rows = new Map<string, StatsRow>();\n let total = 0;\n let minTs = Infinity;\n let maxTs = -Infinity;\n for (const line of text.slice(0, lastNl).split('\\n')) {\n if (!line.trim()) continue;\n let e: SavingEntry;\n try {\n e = JSON.parse(line) as SavingEntry;\n } catch {\n continue;\n }\n const source: Source = e.source ?? 'mcp';\n const client = e.client ?? 'unknown';\n const outcome: Outcome = e.outcome ?? 'complete';\n const key = `${source}|${client}|${e.tool}|${outcome}`;\n const row = rows.get(key) ?? {\n source,\n client,\n tool: e.tool,\n outcome,\n calls: 0,\n vgTokens: 0,\n baselineTokens: 0,\n };\n row.calls++;\n row.vgTokens += e.vgTokens ?? 0;\n row.baselineTokens += e.baselineTokens ?? 0;\n rows.set(key, row);\n total++;\n if (typeof e.ts === 'number') {\n if (e.ts < minTs) minTs = e.ts;\n if (e.ts > maxTs) maxTs = e.ts;\n }\n }\n if (total === 0 || !Number.isFinite(minTs)) return { batch: null, newOffset: consumed };\n const batch: StatsBatch = {\n schemaVersion: SCHEMA_VERSION,\n installId: id,\n vgVersion: VERSION,\n os: process.platform,\n arch: process.arch,\n windowStart: new Date(minTs).toISOString(),\n windowEnd: new Date(maxTs).toISOString(),\n totalCalls: total,\n rows: [...rows.values()],\n };\n return { batch, newOffset: consumed };\n}\n\n/**\n * POST a batch to the endpoint. Never throws; returns whether it was accepted.\n * A short timeout keeps a hung endpoint from stalling the caller (e.g. shutdown).\n */\nasync function postBatch(batch: StatsBatch): Promise<boolean> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), SEND_TIMEOUT_MS);\n timer.unref?.();\n try {\n const res = await fetch(statsEndpoint(), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Connection: 'close' },\n body: JSON.stringify(batch),\n signal: controller.signal,\n });\n return res.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Periodic + on-shutdown flusher for one serve session. Holds the install id and\n * the persisted offset so each flush reads only new ledger lines and advances the\n * offset only when the batch is confirmed sent.\n */\nexport class StatsSharer {\n private readonly id = installId();\n private offset: number;\n private flushing = false;\n\n constructor(private readonly root: string) {\n this.offset = readOffset(root);\n }\n\n /**\n * Flush any new ledger entries. Single-flight (a slow POST won't overlap the\n * next tick). Best-effort: any failure is swallowed and retried next time.\n */\n async flush(): Promise<void> {\n if (this.flushing) return;\n this.flushing = true;\n try {\n const { batch, newOffset } = buildBatch(this.root, this.offset, this.id);\n if (!batch) {\n // Nothing to send, but still advance past consumed blank/partial space.\n if (newOffset > this.offset) {\n this.offset = newOffset;\n writeOffset(this.root, newOffset);\n }\n return;\n }\n const ok = await postBatch(batch);\n if (ok) {\n this.offset = newOffset;\n writeOffset(this.root, newOffset);\n }\n } catch {\n /* never let sharing break serving */\n } finally {\n this.flushing = false;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/engine/stats-share.ts"],"names":[],"mappings":";;;;;;;;AAiCA,IAAM,cAAA,GAAiB,GAAA;AAEvB,IAAM,WAAA,GAAc,kBAAA;AAEpB,IAAM,cAAA,GAAsB,IAAA,CAAA,IAAA,CAAQ,EAAA,CAAA,OAAA,EAAQ,EAAG,WAAW,CAAA;AAC1D,IAAM,eAAA,GAAuB,IAAA,CAAA,IAAA,CAAK,cAAA,EAAgB,YAAY,CAAA;AAE9D,IAAM,eAAA,GAAkB,GAAA;AAgCjB,SAAS,eAAA,CAAgB,GAAA,GAAyB,OAAA,CAAQ,GAAA,EAAoB;AACnF,EAAA,MAAM,OAAO,GAAA,CAAI,YAAA,IAAgB,EAAA,EAAI,IAAA,GAAO,WAAA,EAAY;AACxD,EAAA,IAAI,QAAQ,EAAA,IAAM,GAAA,KAAQ,GAAA,IAAO,GAAA,KAAQ,SAAS,OAAO,cAAA;AACzD,EAAA,MAAM,MAAM,GAAA,CAAI,kBAAA,IAAsB,EAAA,EAAI,IAAA,GAAO,WAAA,EAAY;AAC7D,EAAA,IAAI,OAAO,GAAA,IAAO,EAAA,KAAO,OAAA,IAAW,EAAA,KAAO,OAAO,OAAO,oBAAA;AACzD,EAAA,OAAO,IAAA;AACT;AAGA,IAAM,WAAA,GAAc;AAAA,EAClB,IAAA;AAAA,EACA,gBAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAA;AAGO,SAAS,IAAA,CAAK,GAAA,GAAyB,OAAA,CAAQ,GAAA,EAAc;AAClE,EAAA,OAAO,WAAA,CAAY,IAAA,CAAK,CAAC,CAAA,KAAM;AAC7B,IAAA,MAAM,OAAO,GAAA,CAAI,CAAC,KAAK,EAAA,EAAI,IAAA,GAAO,WAAA,EAAY;AAC9C,IAAA,OAAO,GAAA,KAAQ,EAAA,IAAM,GAAA,KAAQ,GAAA,IAAO,GAAA,KAAQ,OAAA;AAAA,EAC9C,CAAC,CAAA;AACH;AAcO,SAAS,SAAA,CAAU,GAAA,GAAyB,OAAA,CAAQ,GAAA,EAAa;AACtE,EAAA,IAAI,eAAA,CAAgB,GAAG,CAAA,KAAM,IAAA,IAAQ,KAAK,GAAG,CAAA,SAAU,UAAA,EAAW;AAClE,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAc,EAAA,CAAA,YAAA,CAAa,eAAA,EAAiB,MAAM,EAAE,IAAA,EAAK;AAC/D,IAAA,IAAI,MAAA,CAAO,QAAQ,CAAA,EAAG,OAAO,QAAA;AAAA,EAC/B,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,MAAM,KAAK,UAAA,EAAW;AACtB,EAAA,IAAI;AACF,IAAG,EAAA,CAAA,SAAA,CAAU,cAAA,EAAgB,EAAE,SAAA,EAAW,MAAM,CAAA;AAChD,IAAG,iBAAc,eAAA,EAAiB,EAAA,GAAK,MAAM,EAAE,IAAA,EAAM,KAAO,CAAA;AAAA,EAC9D,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,EAAA;AACT;AAEA,SAAS,OAAO,CAAA,EAAoB;AAClC,EAAA,OAAO,iEAAA,CAAkE,KAAK,CAAC,CAAA;AACjF;AAEA,SAAS,UAAA,GAAqB;AAC5B,EAAA,OAAO,UAAA,EAAW;AACpB;AAGO,SAAS,aAAA,GAAwB;AACtC,EAAA,MAAM,QAAA,GAAW,QAAQ,GAAA,CAAI,uBAAA;AAC7B,EAAA,IAAI,QAAA,IAAY,cAAA,CAAe,IAAA,CAAK,QAAQ,GAAG,OAAO,QAAA;AACtD,EAAA,OAAO,CAAA,QAAA,EAAW,mBAAmB,CAAA,wBAAA,CAAA;AACvC;AAEA,SAAS,WAAW,IAAA,EAAsB;AACxC,EAAA,OAAY,IAAA,CAAA,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG,WAAW,CAAA;AAC9C;AAEA,SAAS,eAAe,IAAA,EAAsB;AAC5C,EAAA,OAAY,IAAA,CAAA,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG,eAAe,CAAA;AAClD;AAEA,SAAS,WAAW,IAAA,EAAsB;AACxC,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,KAAK,KAAA,CAAS,EAAA,CAAA,YAAA,CAAa,WAAW,IAAI,CAAA,EAAG,MAAM,CAAC,CAAA;AAChE,IAAA,OAAO,OAAO,IAAI,MAAA,KAAW,QAAA,IAAY,IAAI,MAAA,IAAU,CAAA,GAAI,IAAI,MAAA,GAAS,CAAA;AAAA,EAC1E,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,CAAA;AAAA,EACT;AACF;AAEA,SAAS,WAAA,CAAY,MAAc,MAAA,EAAsB;AACvD,EAAA,IAAI;AACF,IAAG,aAAU,QAAA,CAAS,IAAI,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAChD,IAAG,EAAA,CAAA,aAAA,CAAc,UAAA,CAAW,IAAI,CAAA,EAAG,IAAA,CAAK,UAAU,EAAE,MAAA,EAAQ,CAAA,GAAI,IAAI,CAAA;AAAA,EACtE,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAOO,SAAS,UAAA,CACd,IAAA,EACA,UAAA,EACA,EAAA,GAAK,WAAU,EACkC;AACjD,EAAA,MAAM,IAAA,GAAO,eAAe,IAAI,CAAA;AAChC,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,IAAI;AACF,IAAA,IAAA,GAAU,EAAA,CAAA,QAAA,CAAS,IAAI,CAAA,CAAE,IAAA;AAAA,EAC3B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,SAAA,EAAW,CAAA,EAAE;AAAA,EACrC;AAEA,EAAA,MAAM,KAAA,GAAQ,UAAA,GAAa,IAAA,GAAO,CAAA,GAAI,UAAA;AACtC,EAAA,IAAI,SAAS,IAAA,EAAM,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,WAAW,IAAA,EAAK;AAEzD,EAAA,IAAI,IAAA,GAAO,EAAA;AACX,EAAA,IAAI;AACF,IAAA,MAAM,EAAA,GAAQ,EAAA,CAAA,QAAA,CAAS,IAAA,EAAM,GAAG,CAAA;AAChC,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAA,CAAO,KAAA,CAAM,IAAA,GAAO,KAAK,CAAA;AACrC,MAAG,YAAS,EAAA,EAAI,GAAA,EAAK,CAAA,EAAG,GAAA,CAAI,QAAQ,KAAK,CAAA;AACzC,MAAA,IAAA,GAAO,GAAA,CAAI,SAAS,MAAM,CAAA;AAAA,IAC5B,CAAA,SAAE;AACA,MAAG,aAAU,EAAE,CAAA;AAAA,IACjB;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,SAAA,EAAW,UAAA,EAAW;AAAA,EAC9C;AAIA,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,WAAA,CAAY,IAAI,CAAA;AACpC,EAAA,IAAI,SAAS,CAAA,EAAG,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,WAAW,KAAA,EAAM;AACvD,EAAA,MAAM,QAAA,GAAW,QAAQ,MAAA,GAAS,CAAA;AAClC,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAsB;AACvC,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,IAAI,KAAA,GAAQ,QAAA;AACZ,EAAA,IAAI,KAAA,GAAQ,CAAA,QAAA;AACZ,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,KAAA,CAAM,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,CAAM,IAAI,CAAA,EAAG;AACpD,IAAA,IAAI,CAAC,IAAA,CAAK,IAAA,EAAK,EAAG;AAClB,IAAA,IAAI,CAAA;AACJ,IAAA,IAAI;AACF,MAAA,CAAA,GAAI,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AACA,IAAA,MAAM,MAAA,GAAiB,EAAE,MAAA,IAAU,KAAA;AACnC,IAAA,MAAM,MAAA,GAAS,EAAE,MAAA,IAAU,SAAA;AAC3B,IAAA,MAAM,OAAA,GAAmB,EAAE,OAAA,IAAW,UAAA;AACtC,IAAA,MAAM,GAAA,GAAM,GAAG,MAAM,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA,EAAI,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;AACpD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,IAAK;AAAA,MAC3B,MAAA;AAAA,MACA,MAAA;AAAA,MACA,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,OAAA;AAAA,MACA,KAAA,EAAO,CAAA;AAAA,MACP,QAAA,EAAU,CAAA;AAAA,MACV,cAAA,EAAgB;AAAA,KAClB;AACA,IAAA,GAAA,CAAI,KAAA,EAAA;AACJ,IAAA,GAAA,CAAI,QAAA,IAAY,EAAE,QAAA,IAAY,CAAA;AAC9B,IAAA,GAAA,CAAI,cAAA,IAAkB,EAAE,cAAA,IAAkB,CAAA;AAC1C,IAAA,IAAA,CAAK,GAAA,CAAI,KAAK,GAAG,CAAA;AACjB,IAAA,KAAA,EAAA;AACA,IAAA,IAAI,OAAO,CAAA,CAAE,EAAA,KAAO,QAAA,EAAU;AAC5B,MAAA,IAAI,CAAA,CAAE,EAAA,GAAK,KAAA,EAAO,KAAA,GAAQ,CAAA,CAAE,EAAA;AAC5B,MAAA,IAAI,CAAA,CAAE,EAAA,GAAK,KAAA,EAAO,KAAA,GAAQ,CAAA,CAAE,EAAA;AAAA,IAC9B;AAAA,EACF;AACA,EAAA,IAAI,KAAA,KAAU,CAAA,IAAK,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,SAAA,EAAW,QAAA,EAAS;AACtF,EAAA,MAAM,KAAA,GAAoB;AAAA,IACxB,aAAA,EAAe,cAAA;AAAA,IACf,SAAA,EAAW,EAAA;AAAA,IACX,SAAA,EAAW,OAAA;AAAA,IACX,IAAI,OAAA,CAAQ,QAAA;AAAA,IACZ,MAAM,OAAA,CAAQ,IAAA;AAAA,IACd,WAAA,EAAa,IAAI,IAAA,CAAK,KAAK,EAAE,WAAA,EAAY;AAAA,IACzC,SAAA,EAAW,IAAI,IAAA,CAAK,KAAK,EAAE,WAAA,EAAY;AAAA,IACvC,UAAA,EAAY,KAAA;AAAA,IACZ,IAAA,EAAM,CAAC,GAAG,IAAA,CAAK,QAAQ;AAAA,GACzB;AACA,EAAA,OAAO,EAAE,KAAA,EAAO,SAAA,EAAW,QAAA,EAAS;AACtC;AAMA,eAAe,UAAU,KAAA,EAAqC;AAC5D,EAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,EAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,eAAe,CAAA;AAClE,EAAA,KAAA,CAAM,KAAA,IAAQ;AACd,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,aAAA,EAAc,EAAG;AAAA,MACvC,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAoB,YAAY,OAAA,EAAQ;AAAA,MACnE,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AAAA,MAC1B,QAAQ,UAAA,CAAW;AAAA,KACpB,CAAA;AACD,IAAA,OAAO,GAAA,CAAI,EAAA;AAAA,EACb,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT,CAAA,SAAE;AACA,IAAA,YAAA,CAAa,KAAK,CAAA;AAAA,EACpB;AACF;AAOO,IAAM,cAAN,MAAkB;AAAA,EAKvB,YAA6B,IAAA,EAAc;AAAd,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAC3B,IAAA,IAAA,CAAK,MAAA,GAAS,WAAW,IAAI,CAAA;AAAA,EAC/B;AAAA,EAF6B,IAAA;AAAA,EAJZ,KAAK,SAAA,EAAU;AAAA,EACxB,MAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUnB,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAI,KAAK,QAAA,EAAU;AACnB,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAU,GAAI,UAAA,CAAW,KAAK,IAAA,EAAM,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,EAAE,CAAA;AACvE,MAAA,IAAI,CAAC,KAAA,EAAO;AAEV,QAAA,IAAI,SAAA,GAAY,KAAK,MAAA,EAAQ;AAC3B,UAAA,IAAA,CAAK,MAAA,GAAS,SAAA;AACd,UAAA,WAAA,CAAY,IAAA,CAAK,MAAM,SAAS,CAAA;AAAA,QAClC;AACA,QAAA;AAAA,MACF;AACA,MAAA,MAAM,EAAA,GAAK,MAAM,SAAA,CAAU,KAAK,CAAA;AAChC,MAAA,IAAI,EAAA,EAAI;AACN,QAAA,IAAA,CAAK,MAAA,GAAS,SAAA;AACd,QAAA,WAAA,CAAY,IAAA,CAAK,MAAM,SAAS,CAAA;AAAA,MAClC;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,QAAA,GAAW,KAAA;AAAA,IAClB;AAAA,EACF;AACF","file":"chunk-BICZR6UJ.js","sourcesContent":["import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport { cacheDir } from './cache.js';\nimport { VERSION } from '../version.js';\nimport { resolveIngestHost } from '../reporting/regions.js';\nimport type { SavingEntry, Source, Outcome } from './savings.js';\n\n/**\n * Opt-in usage-stats sharing for `vg serve --share-stats`.\n *\n * This is the ONLY path in `vg serve` that sends anything off the machine, and\n * it is off unless the operator explicitly asks for it. What we send is the\n * same counts-only ledger `vg savings` reports locally — per (source, client,\n * tool, outcome): how many calls and the vg-vs-grep token figures — plus the vg\n * version, OS/arch, and a random per-install id. We never send code, file paths,\n * question text, repo identity, or any credential. See GUARDRAILS §3.4.\n *\n * Even when the flag is passed, the universal `DO_NOT_TRACK` opt-out (or\n * `VIBGRATE_TELEMETRY=0`) wins: nothing is uploaded and no install id is ever\n * minted or persisted (see `telemetryOptOut` / `installId`).\n *\n * Design:\n * - The local ledger (savings.jsonl) is the single source of truth; the flusher\n * reads only the tail past a persisted byte offset, so a batch is sent once.\n * - Fire-and-forget with a short timeout. A network problem never blocks a tool\n * call and never throws — the offset only advances on a confirmed 2xx, so a\n * failed batch is retried on the next flush.\n * - Fully offline-safe: under `--local` the sharer is never constructed.\n */\n\n/** Payload schema version — must match the server's `mcpUsageStatsSchema`. */\nconst SCHEMA_VERSION = '1';\n/** Where the offset (and cached install id) live, per repo, beside the ledger. */\nconst OFFSET_FILE = 'stats-share.json';\n/** The machine-global anonymous install id lives here (stable across repos). */\nconst INSTALL_ID_DIR = path.join(os.homedir(), '.vibgrate');\nconst INSTALL_ID_FILE = path.join(INSTALL_ID_DIR, 'install-id');\n/** Give a flush POST a hard ceiling so a hung endpoint never stalls shutdown. */\nconst SEND_TIMEOUT_MS = 4000;\n\n/** One aggregated row of the shared batch — counts only. */\nexport interface StatsRow {\n source: Source;\n client: string;\n tool: string;\n outcome: Outcome;\n calls: number;\n vgTokens: number;\n baselineTokens: number;\n}\n\n/** The counts-only batch POSTed to the ingest endpoint. */\nexport interface StatsBatch {\n schemaVersion: string;\n installId: string;\n vgVersion: string;\n os: string;\n arch: string;\n windowStart: string;\n windowEnd: string;\n totalCalls: number;\n rows: StatsRow[];\n}\n\n/**\n * The universal opt-out (https://consoledonottrack.com) plus a tool-specific\n * alias, honoured even when `--share-stats` is passed explicitly. Pure function\n * of the environment for testability. Returns the name of the variable that\n * opted out (for the disclosure message), or null when sharing may proceed.\n */\nexport function telemetryOptOut(env: NodeJS.ProcessEnv = process.env): string | null {\n const dnt = (env.DO_NOT_TRACK ?? '').trim().toLowerCase();\n if (dnt !== '' && dnt !== '0' && dnt !== 'false') return 'DO_NOT_TRACK';\n const vt = (env.VIBGRATE_TELEMETRY ?? '').trim().toLowerCase();\n if (vt === '0' || vt === 'false' || vt === 'off') return 'VIBGRATE_TELEMETRY';\n return null;\n}\n\n/** Common CI environment markers — a CI runner is never an interactive session. */\nconst CI_ENV_VARS = [\n 'CI',\n 'GITHUB_ACTIONS',\n 'GITLAB_CI',\n 'CIRCLECI',\n 'TRAVIS',\n 'BUILDKITE',\n 'JENKINS_URL',\n 'TF_BUILD',\n] as const;\n\n/** True when running under a recognised CI system. Pure function of the env. */\nexport function isCI(env: NodeJS.ProcessEnv = process.env): boolean {\n return CI_ENV_VARS.some((v) => {\n const val = (env[v] ?? '').trim().toLowerCase();\n return val !== '' && val !== '0' && val !== 'false';\n });\n}\n\n/**\n * Read (or lazily create) the anonymous per-install id — a random UUID stored in\n * `~/.vibgrate/install-id`. It is *not* tied to the user, the repo, or any\n * account; it only lets us de-duplicate batches from the same install when\n * aggregating. If the home dir isn't writable we fall back to an ephemeral id\n * so sharing still works (it just can't be de-duplicated across restarts).\n *\n * Under an env opt-out no id is ever read or persisted (the sharing path isn't\n * reached then either — this is defence in depth), and on CI runners the id is\n * ephemeral: a persisted id on a shared/throwaway runner would be meaningless\n * for de-duplication and would leave state behind on machines we don't own.\n */\nexport function installId(env: NodeJS.ProcessEnv = process.env): string {\n if (telemetryOptOut(env) !== null || isCI(env)) return randomUuid();\n try {\n const existing = fs.readFileSync(INSTALL_ID_FILE, 'utf8').trim();\n if (isUuid(existing)) return existing;\n } catch {\n /* not created yet */\n }\n const id = randomUuid();\n try {\n fs.mkdirSync(INSTALL_ID_DIR, { recursive: true });\n fs.writeFileSync(INSTALL_ID_FILE, id + '\\n', { mode: 0o600 });\n } catch {\n /* home dir read-only — use the ephemeral id for this process */\n }\n return id;\n}\n\nfunction isUuid(s: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s);\n}\n\nfunction randomUuid(): string {\n return randomUUID();\n}\n\n/** Resolve the ingest endpoint: env override wins, else the default region host. */\nexport function statsEndpoint(): string {\n const override = process.env.VIBGRATE_STATS_ENDPOINT;\n if (override && /^https?:\\/\\//.test(override)) return override;\n return `https://${resolveIngestHost()}/v1/ingest/cli-mcp-usage`;\n}\n\nfunction offsetPath(root: string): string {\n return path.join(cacheDir(root), OFFSET_FILE);\n}\n\nfunction ledgerFilePath(root: string): string {\n return path.join(cacheDir(root), 'savings.jsonl');\n}\n\nfunction readOffset(root: string): number {\n try {\n const raw = JSON.parse(fs.readFileSync(offsetPath(root), 'utf8')) as { offset?: number };\n return typeof raw.offset === 'number' && raw.offset >= 0 ? raw.offset : 0;\n } catch {\n return 0;\n }\n}\n\nfunction writeOffset(root: string, offset: number): void {\n try {\n fs.mkdirSync(cacheDir(root), { recursive: true });\n fs.writeFileSync(offsetPath(root), JSON.stringify({ offset }) + '\\n');\n } catch {\n /* best-effort; a lost offset just means one batch may re-send */\n }\n}\n\n/**\n * Aggregate the ledger entries after `fromOffset` into a counts-only batch.\n * Returns the batch (or null if there's nothing new) and the new byte offset to\n * persist once the batch is confirmed sent.\n */\nexport function buildBatch(\n root: string,\n fromOffset: number,\n id = installId(),\n): { batch: StatsBatch | null; newOffset: number } {\n const file = ledgerFilePath(root);\n let size = 0;\n try {\n size = fs.statSync(file).size;\n } catch {\n return { batch: null, newOffset: 0 };\n }\n // The ledger was truncated/recreated under us — re-read from the top.\n const start = fromOffset > size ? 0 : fromOffset;\n if (start >= size) return { batch: null, newOffset: size };\n\n let text = '';\n try {\n const fd = fs.openSync(file, 'r');\n try {\n const buf = Buffer.alloc(size - start);\n fs.readSync(fd, buf, 0, buf.length, start);\n text = buf.toString('utf8');\n } finally {\n fs.closeSync(fd);\n }\n } catch {\n return { batch: null, newOffset: fromOffset };\n }\n\n // Only whole lines are complete; a trailing partial line (mid-append) is left\n // for the next flush by rewinding the offset to the last newline.\n const lastNl = text.lastIndexOf('\\n');\n if (lastNl < 0) return { batch: null, newOffset: start };\n const consumed = start + lastNl + 1;\n const rows = new Map<string, StatsRow>();\n let total = 0;\n let minTs = Infinity;\n let maxTs = -Infinity;\n for (const line of text.slice(0, lastNl).split('\\n')) {\n if (!line.trim()) continue;\n let e: SavingEntry;\n try {\n e = JSON.parse(line) as SavingEntry;\n } catch {\n continue;\n }\n const source: Source = e.source ?? 'mcp';\n const client = e.client ?? 'unknown';\n const outcome: Outcome = e.outcome ?? 'complete';\n const key = `${source}|${client}|${e.tool}|${outcome}`;\n const row = rows.get(key) ?? {\n source,\n client,\n tool: e.tool,\n outcome,\n calls: 0,\n vgTokens: 0,\n baselineTokens: 0,\n };\n row.calls++;\n row.vgTokens += e.vgTokens ?? 0;\n row.baselineTokens += e.baselineTokens ?? 0;\n rows.set(key, row);\n total++;\n if (typeof e.ts === 'number') {\n if (e.ts < minTs) minTs = e.ts;\n if (e.ts > maxTs) maxTs = e.ts;\n }\n }\n if (total === 0 || !Number.isFinite(minTs)) return { batch: null, newOffset: consumed };\n const batch: StatsBatch = {\n schemaVersion: SCHEMA_VERSION,\n installId: id,\n vgVersion: VERSION,\n os: process.platform,\n arch: process.arch,\n windowStart: new Date(minTs).toISOString(),\n windowEnd: new Date(maxTs).toISOString(),\n totalCalls: total,\n rows: [...rows.values()],\n };\n return { batch, newOffset: consumed };\n}\n\n/**\n * POST a batch to the endpoint. Never throws; returns whether it was accepted.\n * A short timeout keeps a hung endpoint from stalling the caller (e.g. shutdown).\n */\nasync function postBatch(batch: StatsBatch): Promise<boolean> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), SEND_TIMEOUT_MS);\n timer.unref?.();\n try {\n const res = await fetch(statsEndpoint(), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Connection: 'close' },\n body: JSON.stringify(batch),\n signal: controller.signal,\n });\n return res.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Periodic + on-shutdown flusher for one serve session. Holds the install id and\n * the persisted offset so each flush reads only new ledger lines and advances the\n * offset only when the batch is confirmed sent.\n */\nexport class StatsSharer {\n private readonly id = installId();\n private offset: number;\n private flushing = false;\n\n constructor(private readonly root: string) {\n this.offset = readOffset(root);\n }\n\n /**\n * Flush any new ledger entries. Single-flight (a slow POST won't overlap the\n * next tick). Best-effort: any failure is swallowed and retried next time.\n */\n async flush(): Promise<void> {\n if (this.flushing) return;\n this.flushing = true;\n try {\n const { batch, newOffset } = buildBatch(this.root, this.offset, this.id);\n if (!batch) {\n // Nothing to send, but still advance past consumed blank/partial space.\n if (newOffset > this.offset) {\n this.offset = newOffset;\n writeOffset(this.root, newOffset);\n }\n return;\n }\n const ok = await postBatch(batch);\n if (ok) {\n this.offset = newOffset;\n writeOffset(this.root, newOffset);\n }\n } catch {\n /* never let sharing break serving */\n } finally {\n this.flushing = false;\n }\n }\n}\n"]}
|