@vibgrate/cli 2026.803.1 → 2026.803.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/{agent-HNV2VUCO.js → agent-JTA4YWMQ.js} +10 -10
  2. package/dist/{agent-HNV2VUCO.js.map → agent-JTA4YWMQ.js.map} +1 -1
  3. package/dist/{baseline-6WTULHM5.js → baseline-2V7PKA7Q.js} +3 -3
  4. package/dist/{baseline-6WTULHM5.js.map → baseline-2V7PKA7Q.js.map} +1 -1
  5. package/dist/{chunk-N4IDP2M2.js → chunk-3Q3ZXJZP.js} +4 -4
  6. package/dist/{chunk-N4IDP2M2.js.map → chunk-3Q3ZXJZP.js.map} +1 -1
  7. package/dist/{chunk-CE45STY5.js → chunk-4ACXDVON.js} +4 -4
  8. package/dist/{chunk-CE45STY5.js.map → chunk-4ACXDVON.js.map} +1 -1
  9. package/dist/{chunk-6I4TXAI6.js → chunk-6DFV4WCQ.js} +3 -3
  10. package/dist/{chunk-6I4TXAI6.js.map → chunk-6DFV4WCQ.js.map} +1 -1
  11. package/dist/chunk-7KNFG44U.js +6 -0
  12. package/dist/{chunk-QT2PMGN3.js.map → chunk-7KNFG44U.js.map} +1 -1
  13. package/dist/{chunk-DIU3MXB3.js → chunk-CPLG4GFB.js} +4 -4
  14. package/dist/{chunk-DIU3MXB3.js.map → chunk-CPLG4GFB.js.map} +1 -1
  15. package/dist/{chunk-5VH3Y4QC.js → chunk-HC44772H.js} +77 -12
  16. package/dist/chunk-HC44772H.js.map +1 -0
  17. package/dist/{chunk-Y7YKUZ3T.js → chunk-K6Q6HTFD.js} +30 -10
  18. package/dist/chunk-K6Q6HTFD.js.map +1 -0
  19. package/dist/{chunk-O7MTBC52.js → chunk-KYX2YCXT.js} +8 -8
  20. package/dist/{chunk-O7MTBC52.js.map → chunk-KYX2YCXT.js.map} +1 -1
  21. package/dist/{chunk-B2KLJPFY.js → chunk-L5PUNO3T.js} +4 -4
  22. package/dist/{chunk-B2KLJPFY.js.map → chunk-L5PUNO3T.js.map} +1 -1
  23. package/dist/{chunk-SNKTD23L.js → chunk-M452MRWI.js} +6 -6
  24. package/dist/{chunk-SNKTD23L.js.map → chunk-M452MRWI.js.map} +1 -1
  25. package/dist/{chunk-CC6F75GI.js → chunk-M7773OUN.js} +4 -4
  26. package/dist/{chunk-CC6F75GI.js.map → chunk-M7773OUN.js.map} +1 -1
  27. package/dist/{chunk-2TLQDF6C.js → chunk-NSWEJPLV.js} +9 -9
  28. package/dist/{chunk-2TLQDF6C.js.map → chunk-NSWEJPLV.js.map} +1 -1
  29. package/dist/{chunk-4HFSUIIN.js → chunk-NUZM7UOR.js} +4 -4
  30. package/dist/{chunk-4HFSUIIN.js.map → chunk-NUZM7UOR.js.map} +1 -1
  31. package/dist/{chunk-BBFQZ7CA.js → chunk-PXM3VZYR.js} +4 -4
  32. package/dist/{chunk-BBFQZ7CA.js.map → chunk-PXM3VZYR.js.map} +1 -1
  33. package/dist/{chunk-AJ2KE3NT.js → chunk-QMME6TB4.js} +14 -3
  34. package/dist/chunk-QMME6TB4.js.map +1 -0
  35. package/dist/{chunk-JUSXLCSE.js → chunk-TM5XQY3L.js} +3 -3
  36. package/dist/{chunk-JUSXLCSE.js.map → chunk-TM5XQY3L.js.map} +1 -1
  37. package/dist/{chunk-FKFRASAB.js → chunk-TNADGCOX.js} +8 -8
  38. package/dist/{chunk-FKFRASAB.js.map → chunk-TNADGCOX.js.map} +1 -1
  39. package/dist/{chunk-S4NSF5AZ.js → chunk-UXR7FBE3.js} +6 -6
  40. package/dist/{chunk-S4NSF5AZ.js.map → chunk-UXR7FBE3.js.map} +1 -1
  41. package/dist/{chunk-536J6HUR.js → chunk-WGPS3NZQ.js} +13 -8
  42. package/dist/chunk-WGPS3NZQ.js.map +1 -0
  43. package/dist/{chunk-BWMMR5XA.js → chunk-XK5LKOBF.js} +4 -4
  44. package/dist/{chunk-BWMMR5XA.js.map → chunk-XK5LKOBF.js.map} +1 -1
  45. package/dist/cli.js +105 -53
  46. package/dist/cli.js.map +1 -1
  47. package/dist/{ensure-map-5YEI7R7V.js → ensure-map-TAVYMPEG.js} +12 -12
  48. package/dist/{ensure-map-5YEI7R7V.js.map → ensure-map-TAVYMPEG.js.map} +1 -1
  49. package/dist/{graph-backend-CPHLUKUC.js → graph-backend-WF4LGBGD.js} +5 -5
  50. package/dist/{graph-backend-CPHLUKUC.js.map → graph-backend-WF4LGBGD.js.map} +1 -1
  51. package/dist/index.d.ts +27 -2
  52. package/dist/index.js +11 -11
  53. package/dist/{interactive-TNRE4OEK.js → interactive-6PN237LX.js} +25 -21
  54. package/dist/interactive-6PN237LX.js.map +1 -0
  55. package/dist/load-T2FOJUPI.js +10 -0
  56. package/dist/{load-MWG6WZTK.js.map → load-T2FOJUPI.js.map} +1 -1
  57. package/dist/{run-outcome-375HMSQG.js → run-outcome-AMIKAASL.js} +6 -6
  58. package/dist/{run-outcome-375HMSQG.js.map → run-outcome-AMIKAASL.js.map} +1 -1
  59. package/dist/runtime-session-QAVOPSSH.js +20 -0
  60. package/dist/{runtime-session-3MPWXNRL.js.map → runtime-session-QAVOPSSH.js.map} +1 -1
  61. package/dist/{session-2NGJLI5Y.js → session-SCHQQTHN.js} +8 -8
  62. package/dist/{session-2NGJLI5Y.js.map → session-SCHQQTHN.js.map} +1 -1
  63. package/dist/{stream-json-AUMU3NLV.js → stream-json-A6K2MONY.js} +10 -10
  64. package/dist/{stream-json-AUMU3NLV.js.map → stream-json-A6K2MONY.js.map} +1 -1
  65. package/dist/{vg-mcp-bridge-D463EHQI.js → vg-mcp-bridge-3TSFOL4V.js} +8 -8
  66. package/dist/{vg-mcp-bridge-D463EHQI.js.map → vg-mcp-bridge-3TSFOL4V.js.map} +1 -1
  67. package/dist/{vgd-Z23PXSP4.js → vgd-B67JCNJP.js} +8 -8
  68. package/dist/vgd-B67JCNJP.js.map +1 -0
  69. package/package.json +1 -1
  70. package/dist/chunk-536J6HUR.js.map +0 -1
  71. package/dist/chunk-5VH3Y4QC.js.map +0 -1
  72. package/dist/chunk-AJ2KE3NT.js.map +0 -1
  73. package/dist/chunk-QT2PMGN3.js +0 -6
  74. package/dist/chunk-Y7YKUZ3T.js.map +0 -1
  75. package/dist/interactive-TNRE4OEK.js.map +0 -1
  76. package/dist/load-MWG6WZTK.js +0 -10
  77. package/dist/runtime-session-3MPWXNRL.js +0 -20
  78. package/dist/vgd-Z23PXSP4.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/code/catalog.ts","../src/code/text-tool-protocol.ts","../src/code/router.ts"],"names":["result","locals"],"mappings":"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","file":"chunk-4HFSUIIN.js","sourcesContent":["/**\n * Live model catalog for the `vg code` guided picker (VG-CLI-CODE §8).\n *\n * The guided flow offers the developer the current top providers and models\n * without us hard-coding a list that goes stale. OpenRouter publishes a public,\n * key-free catalog at `/api/v1/models`; we fetch it, group by provider, rank\n * coding-friendly models first, and cache it per-user with a TTL so repeat runs\n * are instant and offline runs still work. If the network and cache both fail we\n * fall back to a tiny curated provider list plus the always-available\n * \"enter a model slug yourself\" escape hatch — the picker is never empty.\n *\n * Pure over its injected `fetch`, `now`, and cache, so the parse/group/rank\n * logic is unit-testable with no network.\n */\n\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\nexport interface CatalogModel {\n /** Full slug, e.g. `anthropic/claude-3.5-sonnet`. */\n id: string;\n name: string;\n /** Provider segment, e.g. `anthropic`. */\n provider: string;\n contextLength?: number;\n /** USD per 1M prompt tokens (derived from OpenRouter's per-token price). */\n promptPricePerM?: number;\n completionPricePerM?: number;\n}\n\nexport interface ProviderGroup {\n /** Provider id, e.g. `anthropic`. */\n id: string;\n /** Friendly label, e.g. `Anthropic (Claude)`. */\n label: string;\n models: CatalogModel[];\n}\n\nexport interface Catalog {\n providers: ProviderGroup[];\n /** true when served from network, false when from cache or the curated fallback. */\n fresh: boolean;\n source: 'network' | 'cache' | 'fallback';\n}\n\n/** Provider display names + the order we surface them (the \"top providers\" list). */\nconst PROVIDER_LABELS: Record<string, string> = {\n anthropic: 'Anthropic (Claude)',\n openai: 'OpenAI (GPT)',\n 'x-ai': 'xAI (Grok)',\n google: 'Google (Gemini)',\n 'meta-llama': 'Meta (Llama)',\n deepseek: 'DeepSeek',\n mistralai: 'Mistral',\n qwen: 'Qwen',\n};\nconst FEATURED_ORDER = Object.keys(PROVIDER_LABELS);\n\nconst OPENROUTER_MODELS_URL = 'https://openrouter.ai/api/v1/models';\n/** Cache freshness window: a day is plenty; model lists move slowly. */\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000;\n\nexport interface FetchCatalogOptions {\n fetchImpl?: typeof fetch;\n now?: () => number;\n /** Bypass and refresh from network. */\n noCache?: boolean;\n /** Never touch the network (offline / --local): cache or curated only. */\n offline?: boolean;\n timeoutMs?: number;\n}\n\n/** The per-user catalog cache file (shared across repos, like the model cache). */\nexport function catalogCachePath(): string {\n const base = process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache');\n return path.join(base, 'vibgrate', 'catalog', 'openrouter-models.json');\n}\n\nexport async function fetchCatalog(options: FetchCatalogOptions = {}): Promise<Catalog> {\n const now = options.now ?? (() => 0);\n const fetchImpl = options.fetchImpl ?? fetch;\n\n // Serve from a warm cache when allowed.\n if (!options.noCache) {\n const cached = readCache();\n if (cached && (options.offline || now() - cached.ts < CACHE_TTL_MS)) {\n return { providers: groupModels(cached.models), fresh: false, source: 'cache' };\n }\n }\n if (options.offline) {\n const cached = readCache();\n if (cached) return { providers: groupModels(cached.models), fresh: false, source: 'cache' };\n return { providers: curatedFallback(), fresh: false, source: 'fallback' };\n }\n\n // Fetch fresh.\n try {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? 8000);\n let raw: unknown;\n try {\n const res = await fetchImpl(OPENROUTER_MODELS_URL, { signal: controller.signal });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n raw = await res.json();\n } finally {\n clearTimeout(timer);\n }\n const models = parseModels(raw);\n if (models.length === 0) throw new Error('empty catalog');\n writeCache(models, now());\n return { providers: groupModels(models), fresh: true, source: 'network' };\n } catch {\n // Network failed → cache → curated.\n const cached = readCache();\n if (cached) return { providers: groupModels(cached.models), fresh: false, source: 'cache' };\n return { providers: curatedFallback(), fresh: false, source: 'fallback' };\n }\n}\n\n/** Parse OpenRouter's `/models` payload into our shape (defensive about fields). */\nexport function parseModels(raw: unknown): CatalogModel[] {\n const data = (raw as { data?: unknown[] })?.data;\n if (!Array.isArray(data)) return [];\n const out: CatalogModel[] = [];\n for (const entry of data) {\n const e = entry as {\n id?: unknown;\n name?: unknown;\n context_length?: unknown;\n pricing?: { prompt?: unknown; completion?: unknown };\n };\n if (typeof e.id !== 'string' || !e.id.includes('/')) continue;\n const provider = e.id.split('/')[0];\n out.push({\n id: e.id,\n name: typeof e.name === 'string' ? e.name : e.id,\n provider,\n contextLength: numeric(e.context_length),\n promptPricePerM: perMillion(e.pricing?.prompt),\n completionPricePerM: perMillion(e.pricing?.completion),\n });\n }\n return out;\n}\n\n/** Group models by provider, featured providers first, coding models first within each. */\nexport function groupModels(models: CatalogModel[]): ProviderGroup[] {\n const byProvider = new Map<string, CatalogModel[]>();\n for (const m of models) {\n const list = byProvider.get(m.provider) ?? [];\n list.push(m);\n byProvider.set(m.provider, list);\n }\n const groups: ProviderGroup[] = [];\n for (const [id, list] of byProvider) {\n groups.push({ id, label: PROVIDER_LABELS[id] ?? titleCase(id), models: list.sort(rankModels) });\n }\n // Featured providers in our order first, then the rest alphabetically.\n groups.sort((a, b) => {\n const ia = FEATURED_ORDER.indexOf(a.id);\n const ib = FEATURED_ORDER.indexOf(b.id);\n if (ia !== -1 || ib !== -1) return (ia === -1 ? 1e9 : ia) - (ib === -1 ? 1e9 : ib);\n return a.label.localeCompare(b.label);\n });\n return groups;\n}\n\n/** Coding-oriented models first, then larger context, then name — a helpful default order. */\nfunction rankModels(a: CatalogModel, b: CatalogModel): number {\n const ca = isCoding(a) ? 0 : 1;\n const cb = isCoding(b) ? 0 : 1;\n if (ca !== cb) return ca - cb;\n const la = a.contextLength ?? 0;\n const lb = b.contextLength ?? 0;\n if (la !== lb) return lb - la;\n return a.id.localeCompare(b.id);\n}\n\nfunction isCoding(m: CatalogModel): boolean {\n return /cod(e|er|ing)/i.test(m.id) || /cod(e|er|ing)/i.test(m.name);\n}\n\n/** Top N providers (the guided picker's first screen). */\nexport function topProviders(catalog: Catalog, n = 6): ProviderGroup[] {\n return catalog.providers.slice(0, n);\n}\n\ninterface CacheShape {\n ts: number;\n models: CatalogModel[];\n}\n\nfunction readCache(): CacheShape | null {\n try {\n const parsed = JSON.parse(fs.readFileSync(catalogCachePath(), 'utf8')) as CacheShape;\n if (Array.isArray(parsed.models) && typeof parsed.ts === 'number') return parsed;\n } catch {\n /* no cache */\n }\n return null;\n}\n\nfunction writeCache(models: CatalogModel[], ts: number): void {\n try {\n const file = catalogCachePath();\n fs.mkdirSync(path.dirname(file), { recursive: true });\n fs.writeFileSync(file, JSON.stringify({ ts, models }));\n } catch {\n /* cache is best-effort */\n }\n}\n\n/**\n * A minimal, honestly-labelled offline fallback: just the provider names, so the\n * picker still works with no network and no cache. Model ids are intentionally\n * NOT hard-coded (they go stale) — the flow always offers \"enter a model slug\".\n */\nfunction curatedFallback(): ProviderGroup[] {\n return FEATURED_ORDER.map((id) => ({ id, label: PROVIDER_LABELS[id], models: [] }));\n}\n\nfunction numeric(v: unknown): number | undefined {\n const n = typeof v === 'string' ? Number(v) : typeof v === 'number' ? v : NaN;\n return Number.isFinite(n) ? n : undefined;\n}\n\n/** OpenRouter prices are USD *per token* as strings; convert to per-million. */\nfunction perMillion(v: unknown): number | undefined {\n const n = numeric(v);\n if (n === undefined) return undefined;\n return Math.round(n * 1_000_000 * 1000) / 1000;\n}\n\nfunction titleCase(id: string): string {\n return id.replace(/[-_]/g, ' ').replace(/\\b\\w/g, (ch) => ch.toUpperCase());\n}\n","/**\n * Text-based tool-call protocol fallback (model-agnostic agent robustness).\n *\n * The agent loop speaks native (OpenAI-shaped) function calling, but many\n * backends can't: the embedded llama.cpp host has no tool API at all, and a\n * large share of local models served by Ollama / LM Studio either ignore the\n * native `tools` field or emit their chat-template tool markup — Hermes/Qwen\n * `<tool_call>{…}</tool_call>` tags — as plain assistant text. Leading OSS\n * agents (Cline, Roo Code, Aider) solve this with a *prompt-described* tool\n * protocol parsed from text; this module gives `vg code` the same floor, so the\n * core agent works with whatever model is picked underneath.\n *\n * Two layers, both provider-neutral and unit-tested:\n * - {@link parseTextToolCalls} — recover tool calls a model wrote as text\n * (`<tool_call>` tags, fenced ```tool_call blocks, or a bare JSON object\n * with `name` + `arguments`). Used as a *rescue* on every provider, so a\n * model that ignores native function calling still drives the loop.\n * - {@link withToolCallFallback} — a Provider decorator. For backends that\n * declare `supportsTools: false` it renders the tool list into the system\n * prompt, serializes prior tool rounds as text the model can read, and\n * parses the reply. For native backends it passes through and only rescues.\n */\n\nimport type { ChatMessage, ChatOptions, Provider, ProviderResult, ToolCall, ToolSpec } from './types.js';\n\n/** Formats we can recover a tool call from, in order of specificity. */\nconst TAG_RE = /<tool_call>\\s*([\\s\\S]*?)\\s*<\\/tool_call>/g;\nconst FENCE_RE = /```(?:tool_call|tool|json)?\\s*\\n?([\\s\\S]*?)```/g;\n\ninterface RawCall {\n name?: unknown;\n arguments?: unknown;\n parameters?: unknown;\n input?: unknown;\n}\n\n/** Parse one candidate JSON blob into a ToolCall, or null when it isn't one. */\nfunction toToolCall(blob: string, index: number): ToolCall | null {\n let parsed: RawCall;\n try {\n parsed = JSON.parse(blob) as RawCall;\n } catch {\n return null;\n }\n if (!parsed || typeof parsed !== 'object' || typeof parsed.name !== 'string' || !parsed.name) return null;\n const args = parsed.arguments ?? parsed.parameters ?? parsed.input ?? {};\n return {\n id: `text_${index}`,\n name: parsed.name,\n arguments: args && typeof args === 'object' && !Array.isArray(args) ? (args as Record<string, unknown>) : {},\n };\n}\n\n/**\n * Extract tool calls a model emitted as plain text, returning the calls plus\n * the text with the call markup removed (what remains is the user-facing\n * prose, if any). Order of attempts: `<tool_call>` tags, then fenced blocks,\n * then one bare top-level JSON object. Anything that doesn't parse into a\n * `{name, arguments}` shape is left in the text untouched.\n */\nexport function parseTextToolCalls(text: string): { calls: ToolCall[]; text: string } {\n const calls: ToolCall[] = [];\n let cleaned = text ?? '';\n\n cleaned = cleaned.replace(TAG_RE, (whole, body: string) => {\n const call = toToolCall(body, calls.length);\n if (!call) return whole;\n calls.push(call);\n return '';\n });\n\n if (calls.length === 0) {\n cleaned = cleaned.replace(FENCE_RE, (whole, body: string) => {\n const call = toToolCall(body.trim(), calls.length);\n if (!call) return whole;\n calls.push(call);\n return '';\n });\n }\n\n if (calls.length === 0) {\n const t = cleaned.trim();\n if (t.startsWith('{') && t.endsWith('}')) {\n const call = toToolCall(t, 0);\n if (call) {\n calls.push(call);\n cleaned = '';\n }\n }\n }\n\n return { calls, text: cleaned.trim() };\n}\n\n/** The prompt block that teaches a non-tool-calling model the call format. */\nexport function textToolProtocolInstruction(tools: ToolSpec[]): string {\n const lines = tools.map((t) => {\n const params = JSON.stringify(t.parameters?.properties ?? {});\n return `- ${t.name}: ${t.description.split('\\n')[0]} · arguments schema: ${params}`;\n });\n return [\n '',\n '## Tool calling (text protocol)',\n 'This runtime has no native function-calling. To use a tool, reply with ONLY:',\n '<tool_call>{\"name\": \"<tool name>\", \"arguments\": { … }}</tool_call>',\n 'One tool call per reply. Wait for the tool result before the next call.',\n 'When the task is complete, call the `finish` tool with your Markdown summary.',\n 'Available tools:',\n ...lines,\n ].join('\\n');\n}\n\n/** Serialize a tool round into text for backends that lack tool roles. */\nfunction flattenToolRounds(messages: ChatMessage[]): ChatMessage[] {\n return messages.map((m): ChatMessage => {\n if (m.role === 'assistant' && m.toolCalls?.length) {\n const rendered = m.toolCalls\n .map((c) => `<tool_call>${JSON.stringify({ name: c.name, arguments: c.arguments })}</tool_call>`)\n .join('\\n');\n return { role: 'assistant', content: [m.content, rendered].filter(Boolean).join('\\n') };\n }\n if (m.role === 'tool') {\n return { role: 'user', content: `Tool result for ${m.name}:\\n${m.content}` };\n }\n return m;\n });\n}\n\n/**\n * Wrap a provider so the agent loop's tool calling works regardless of the\n * backend's native capability:\n * - `supportsTools === false` (embedded llama.cpp), or a model the\n * capability registry knows cannot tool-call natively: inject the text\n * protocol into the system prompt, flatten tool rounds to text, parse the\n * reply.\n * - native backends: call through unchanged; when the model returned no\n * native tool calls but its text contains parseable tool markup, rescue it.\n * Idempotent-safe: wrapping a wrapped provider changes nothing observable.\n */\nexport function withToolCallFallback(\n provider: Provider,\n caps?: { nativeTools: boolean | null },\n): Provider {\n return {\n id: provider.id,\n label: provider.label,\n local: provider.local,\n model: provider.model,\n supportsTools: provider.supportsTools,\n async chat(messages: ChatMessage[], opts: ChatOptions = {}): Promise<ProviderResult> {\n const native = provider.supportsTools !== false && caps?.nativeTools !== false;\n if (native || !opts.tools?.length) {\n const result = await provider.chat(messages, opts);\n if ((!result.toolCalls || result.toolCalls.length === 0) && result.text) {\n const rescued = parseTextToolCalls(result.text);\n if (rescued.calls.length) return { ...result, text: rescued.text, toolCalls: rescued.calls };\n }\n return result;\n }\n\n // Text-protocol path: teach the format, flatten history, parse the reply.\n const instruction = textToolProtocolInstruction(opts.tools);\n const flattened = flattenToolRounds(messages);\n const withProtocol: ChatMessage[] = flattened.map((m, i) =>\n i === 0 && m.role === 'system' ? { role: 'system', content: m.content + '\\n' + instruction } : m,\n );\n if (withProtocol[0]?.role !== 'system') {\n withProtocol.unshift({ role: 'system', content: instruction });\n }\n const result = await provider.chat(withProtocol, { ...opts, tools: undefined });\n const parsed = parseTextToolCalls(result.text ?? '');\n if (parsed.calls.length) return { ...result, text: parsed.text, toolCalls: parsed.calls };\n return result;\n },\n };\n}\n","/**\n * Model routing for `vg code` (VG-CLI-CODE §5.2).\n *\n * The \"best in breed\" story is an ordered set of backends with automatic\n * fallback — the OpenRouter/LiteLLM model — expressed as a *scheduling* decision\n * the session can execute: try the preferred provider, and on a transport\n * failure fall through to the next available one. This resolver is pure over its\n * injected inputs (flags, environment, the discovered local fleet), so it is\n * fully testable, and it holds two hard rules from the guardrails:\n *\n * - **No surprise egress or install.** With no explicit selection it picks a\n * backend only from signals already present (a configured hosted key, or a\n * model already pulled locally). It never dials a default cloud endpoint you\n * didn't configure, and never triggers an install to pick a default.\n * - **`--local` stays local.** Under `--local` only on-device backends are\n * eligible; if none are available it fails with an actionable message rather\n * than silently reaching the network.\n * - **Code Modes stay on the Vibgrate manager.** When {@link RouteOptions.codeMode}\n * is set, routing is fail-closed to embedded llama.cpp (first-party GGUF).\n * Ollama / LM Studio are never auto-selected for Code Modes.\n */\n\nimport { CliError, ExitCode } from '../util/exit.js';\nimport { discoverModels, type LocalModel } from '../engine/models.js';\nimport { resolveGgufPath } from '../runtime/resolve-gguf.js';\nimport {\n formatManagerBadgeLine,\n managerFromProviderId,\n type ModelManagerId,\n} from '../runtime/model-manager.js';\nimport {\n LocalLlamaProvider,\n MockProvider,\n OllamaProvider,\n OpenAiCompatibleProvider,\n OPENAI_COMPATIBLE,\n type OpenAiCompatibleConfig,\n} from './providers.js';\nimport { withToolCallFallback } from './text-tool-protocol.js';\nimport { lookupModelCapabilities } from './model-capabilities.js';\nimport type { Provider } from './types.js';\n\nexport interface RouteOptions {\n /** Explicit `--provider` (vibgrate-relay, ollama, lmstudio, foundry-local, openrouter, litellm, openai, together, llama-cpp). */\n provider?: string;\n /** Explicit `--model`. */\n model?: string;\n /** `--local`: on-device backends only. */\n local?: boolean;\n /** `--yes`: consent to a first-use install (only relevant to llama-cpp). */\n consent?: boolean;\n /** Path to a gguf for the llama-cpp backend. */\n modelPath?: string;\n /**\n * Prefer embedded llama.cpp when a GGUF is resolvable (Code Mode preferredInference).\n * When false, Ollama may be tried first (VG_PREFER_OLLAMA).\n */\n preferEmbedded?: boolean;\n /**\n * Code Mode path (spark|flow|forge): fail-closed to the Vibgrate model manager.\n * Never auto-routes to Ollama / LM Studio / hosted.\n */\n codeMode?: boolean;\n /** A scripted reply → force the deterministic MockProvider (tests/`--mock`). */\n mockReply?: string;\n}\n\nexport interface RouteDeps {\n env?: NodeJS.ProcessEnv;\n discover?: () => LocalModel[];\n}\n\nexport interface RouteResult {\n /** Providers to try in order; the session falls through on transport failure. */\n providers: Provider[];\n /** A short, human explanation of the choice (for the run header / --json). */\n reason: string;\n /** Manager identity for the primary provider (badge / UX). */\n manager: ModelManagerId;\n /** e.g. \"[Vibgrate] Code Mode · first-party model manager …\" */\n managerLine: string;\n}\n\nconst HOSTED_IDS = new Set(['vibgrate-relay', 'openrouter', 'litellm', 'openai', 'together']);\n\n/** Resolve the ordered provider list for a run. Throws an actionable CliError when nothing is eligible. */\nexport function resolveProviders(opts: RouteOptions, deps: RouteDeps = {}): RouteResult {\n const env = deps.env ?? process.env;\n const discover = deps.discover ?? discoverModels;\n\n // Deterministic offline floor — used by tests, the benchmark, and `--mock`.\n if (opts.mockReply !== undefined) {\n const providers = [new MockProvider(opts.model ?? 'mock-1', opts.mockReply)];\n return finish(providers, 'mock provider (scripted, offline)');\n }\n\n // Code Modes: Vibgrate manager only (embedded GGUF). No third-party auto-route.\n // Even when code.ts pins provider=llama-cpp, never chain Ollama/LM Studio — a\n // grammar or load failure must surface the real error, not \"couldn't reach Ollama\".\n if (opts.codeMode && (!opts.provider || opts.provider === 'llama-cpp' || opts.provider === 'vibgrate')) {\n const gguf = resolveGgufPath({\n modelPath: opts.modelPath || env.VG_CODE_MODEL_PATH,\n modelRef: opts.model,\n env,\n discover,\n });\n if (!gguf) {\n throw new CliError(\n 'Code Mode needs the Vibgrate model manager weights on disk. Run `vg models install spark|flow|forge` (or pass --model-path to a GGUF). Custom Ollama/LM Studio backends are only used when you set --provider explicitly.',\n ExitCode.NOT_FOUND,\n );\n }\n const providers = [\n new LocalLlamaProvider(opts.model ?? basename(gguf.path), gguf.path, undefined, !!opts.consent),\n ];\n return finish(providers, `Code Mode → Vibgrate model manager (embedded llama.cpp · ${gguf.path})`);\n }\n\n // Explicit provider wins.\n if (opts.provider) {\n const provider = buildExplicit(opts.provider, opts, env, discover);\n // Code Mode + explicit custom backend (ollama, lmstudio, …): still no surprise chain.\n if (opts.codeMode) {\n return finish([provider], `Code Mode → explicit --provider ${opts.provider} (no auto-fallback)`);\n }\n // Custom path: only fall through to other *local* adapters when --local, never LM Studio unless chosen.\n const fallbacks =\n opts.local || provider.local\n ? localFallbacks(opts, env, discover, provider.id, { allowLmStudio: opts.provider === 'lmstudio' })\n : [];\n return finish([provider, ...fallbacks], `explicit --provider ${opts.provider}`);\n }\n\n // --local: on-device only, in preference order (embedded → ollama; no surprise LM Studio).\n if (opts.local) {\n const locals = localFallbacks(opts, env, discover, '', { allowLmStudio: false });\n if (locals.length === 0) {\n throw new CliError(\n 'no local model backend available for --local. Install a Code Mode (`vg models install spark`), start Ollama (`ollama serve` + pull), or point --provider llama-cpp at a gguf. See `vg models`.',\n ExitCode.NOT_FOUND,\n );\n }\n return finish(locals, '--local (on-device backends only)');\n }\n\n // No explicit selection: choose from signals already present, best first.\n // 1) Vibgrate Relay — the first-party hosted router, preferred when the user\n // has signed in. Nothing is dialled without their token, so this stays inside\n // the no-surprise-egress rule above.\n if (env.VIBGRATE_RELAY_TOKEN) {\n const model = resolveHostedModel(opts, env, 'vibgrate-relay');\n const primary = buildHosted('vibgrate-relay', model);\n return finish(\n [primary, ...localFallbacks(opts, env, discover, 'vibgrate-relay', { allowLmStudio: false })],\n 'VIBGRATE_RELAY_TOKEN is set → Vibgrate Relay (with local fallback)',\n );\n }\n // 2) Another configured hosted router key.\n if (env.OPENROUTER_API_KEY) {\n const model = resolveHostedModel(opts, env, 'openrouter');\n const primary = buildHosted('openrouter', model);\n return finish(\n [primary, ...localFallbacks(opts, env, discover, 'openrouter', { allowLmStudio: false })],\n 'OPENROUTER_API_KEY is set → OpenRouter (with local fallback)',\n );\n }\n // 3) A locally-pulled model (embedded first; never auto LM Studio).\n const locals = localFallbacks(opts, env, discover, '', { allowLmStudio: false });\n if (locals.length) return finish(locals, 'a local model is available → on-device (no key needed)');\n // 4) Any other configured hosted key.\n for (const id of ['litellm', 'openai', 'together'] as const) {\n const keyEnv = OPENAI_COMPATIBLE[id].apiKeyEnv;\n if (keyEnv && env[keyEnv]) {\n const model = resolveHostedModel(opts, env, id);\n return finish([buildHosted(id, model)], `${keyEnv} is set → ${OPENAI_COMPATIBLE[id].label}`);\n }\n }\n\n throw new CliError(\n 'no model backend configured. Do one of: sign in to Vibgrate Relay (VIBGRATE_RELAY_TOKEN), set OPENROUTER_API_KEY for the hosted router, run `vg models install spark` for the Vibgrate manager, run Ollama locally, or use --local with a local model. Set the model with --model or VG_CODE_MODEL.',\n ExitCode.NOT_FOUND,\n );\n}\n\nfunction finish(rawProviders: Provider[], reason: string): RouteResult {\n // Every backend gets the tool-call fallback: native providers are passed\n // through (with a text-markup rescue), backends without native function\n // calling (embedded llama.cpp) — and models the capability registry knows\n // cannot tool-call natively — get the prompt-described text protocol. This\n // is what makes the agent work with whatever model is picked underneath.\n const providers = rawProviders.map((p) => withToolCallFallback(p, lookupModelCapabilities(p.model)));\n const primary = providers[0];\n const manager = managerFromProviderId(primary?.id);\n return {\n providers,\n reason,\n manager,\n managerLine: formatManagerBadgeLine(manager, primary?.model),\n };\n}\n\nfunction buildExplicit(id: string, opts: RouteOptions, env: NodeJS.ProcessEnv, discover: () => LocalModel[]): Provider {\n if (id === 'ollama') return new OllamaProvider(resolveLocalModel(opts, discover, 'ollama'), env.OLLAMA_HOST);\n if (id === 'llama-cpp' || id === 'vibgrate') {\n const resolved = resolveGgufPath({\n modelPath: opts.modelPath || env.VG_CODE_MODEL_PATH,\n modelRef: opts.model,\n env,\n discover,\n });\n if (!resolved) {\n throw new CliError(\n '--provider llama-cpp needs a GGUF: pass --model-path, set VG_CODE_MODEL_PATH, or run `vg models install` so the weight store has a catalogued gguf. See `vg models`.',\n ExitCode.USAGE_ERROR,\n );\n }\n return new LocalLlamaProvider(opts.model ?? basename(resolved.path), resolved.path, undefined, !!opts.consent);\n }\n if (id === 'lmstudio') return buildHosted('lmstudio', resolveHostedModel(opts, env, 'lmstudio'));\n if (id === 'foundry-local' || id === 'foundry') {\n return buildHosted('foundry-local', resolveHostedModel(opts, env, 'foundry-local'));\n }\n if (HOSTED_IDS.has(id)) return buildHosted(id, resolveHostedModel(opts, env, id));\n throw new CliError(\n `unknown --provider \"${id}\". Known: vibgrate-relay, ollama, lmstudio, foundry-local, openrouter, litellm, openai, together, llama-cpp.`,\n ExitCode.USAGE_ERROR,\n );\n}\n\nfunction buildHosted(id: string, model: string): OpenAiCompatibleProvider {\n const base = OPENAI_COMPATIBLE[id];\n const config: OpenAiCompatibleConfig = { ...base, id };\n return new OpenAiCompatibleProvider(model, config);\n}\n\ninterface LocalFallbackOpts {\n /** Only include LM Studio when the user explicitly asked for it. */\n allowLmStudio: boolean;\n}\n\n/** On-device backends in preference order, skipping the one already chosen as primary. */\nfunction localFallbacks(\n opts: RouteOptions,\n env: NodeJS.ProcessEnv,\n discover: () => LocalModel[],\n exclude: string,\n fb: LocalFallbackOpts,\n): Provider[] {\n const out: Provider[] = [];\n const models = safeDiscover(discover);\n\n // Approach B default: when a GGUF is already on disk, embedded is primary local.\n // Opt out with VG_PREFER_OLLAMA=1 if the user wants Ollama first.\n const preferOllama =\n env.VG_PREFER_OLLAMA === '1' ||\n env.VIBGRATE_PREFER_OLLAMA === '1' ||\n opts.preferEmbedded === false;\n const gguf =\n exclude === 'llama-cpp' || exclude === 'vibgrate'\n ? null\n : resolveGgufPath({\n modelPath: opts.modelPath || env.VG_CODE_MODEL_PATH,\n modelRef: opts.model,\n env,\n discover: () => models,\n });\n\n if (gguf && !preferOllama) {\n out.push(new LocalLlamaProvider(opts.model ?? basename(gguf.path), gguf.path, undefined, !!opts.consent));\n }\n\n const ollamaModel = opts.model ?? firstOfRuntime(models, 'ollama');\n if (exclude !== 'ollama' && ollamaModel) out.push(new OllamaProvider(ollamaModel, env.OLLAMA_HOST));\n\n // LM Studio only when explicitly allowed (user chose --provider lmstudio).\n if (fb.allowLmStudio && exclude !== 'lmstudio') {\n const lmModel = opts.model ?? firstOfRuntime(models, 'lm-studio');\n if (lmModel) out.push(buildHosted('lmstudio', lmModel));\n }\n\n // Foundry Local when server/env is configured.\n if (exclude !== 'foundry-local' && exclude !== 'foundry' && (env.FOUNDRY_LOCAL_BASE_URL || env.VG_CODE_PROVIDER === 'foundry-local')) {\n try {\n const m = opts.model || env.VG_CODE_MODEL;\n if (m) out.push(buildHosted('foundry-local', m));\n } catch {\n /* skip if no model */\n }\n }\n\n // Embedded last if user forced Ollama-first but GGUF still available.\n if (gguf && !out.some((p) => p.id === 'llama-cpp')) {\n out.push(new LocalLlamaProvider(opts.model ?? basename(gguf.path), gguf.path, undefined, !!opts.consent));\n }\n return out;\n}\n\nfunction resolveLocalModel(opts: RouteOptions, discover: () => LocalModel[], runtime: LocalModel['runtime']): string {\n if (opts.model) return opts.model;\n const found = firstOfRuntime(safeDiscover(discover), runtime);\n if (found) return found;\n throw new CliError(`--provider ${runtime} needs a model. Pull one (\\`ollama pull <model>\\`) then re-run, or pass --model. See \\`vg models\\`.`, ExitCode.NOT_FOUND);\n}\n\nfunction resolveHostedModel(opts: RouteOptions, env: NodeJS.ProcessEnv, id: string): string {\n const model = opts.model || env.VG_CODE_MODEL;\n if (model) return model;\n throw new CliError(\n `${OPENAI_COMPATIBLE[id].label} needs a model id — pass --model (e.g. a current best-in-breed coding model) or set VG_CODE_MODEL. We don't hard-code a model so you always pick the current best one.`,\n ExitCode.USAGE_ERROR,\n );\n}\n\nfunction firstOfRuntime(models: LocalModel[], runtime: LocalModel['runtime']): string | undefined {\n // Deterministic: discoverModels() already returns a sorted list.\n const m = models.find((x) => x.runtime === runtime);\n return m?.name;\n}\n\nfunction safeDiscover(discover: () => LocalModel[]): LocalModel[] {\n try {\n return discover();\n } catch {\n return [];\n }\n}\n\nfunction basename(p: string): string {\n return p.replace(/\\\\/g, '/').split('/').pop() ?? p;\n}\n"]}
1
+ {"version":3,"sources":["../src/code/catalog.ts","../src/code/text-tool-protocol.ts","../src/code/router.ts"],"names":["result","locals"],"mappings":"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","file":"chunk-NUZM7UOR.js","sourcesContent":["/**\n * Live model catalog for the `vg code` guided picker (VG-CLI-CODE §8).\n *\n * The guided flow offers the developer the current top providers and models\n * without us hard-coding a list that goes stale. OpenRouter publishes a public,\n * key-free catalog at `/api/v1/models`; we fetch it, group by provider, rank\n * coding-friendly models first, and cache it per-user with a TTL so repeat runs\n * are instant and offline runs still work. If the network and cache both fail we\n * fall back to a tiny curated provider list plus the always-available\n * \"enter a model slug yourself\" escape hatch — the picker is never empty.\n *\n * Pure over its injected `fetch`, `now`, and cache, so the parse/group/rank\n * logic is unit-testable with no network.\n */\n\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\nexport interface CatalogModel {\n /** Full slug, e.g. `anthropic/claude-3.5-sonnet`. */\n id: string;\n name: string;\n /** Provider segment, e.g. `anthropic`. */\n provider: string;\n contextLength?: number;\n /** USD per 1M prompt tokens (derived from OpenRouter's per-token price). */\n promptPricePerM?: number;\n completionPricePerM?: number;\n}\n\nexport interface ProviderGroup {\n /** Provider id, e.g. `anthropic`. */\n id: string;\n /** Friendly label, e.g. `Anthropic (Claude)`. */\n label: string;\n models: CatalogModel[];\n}\n\nexport interface Catalog {\n providers: ProviderGroup[];\n /** true when served from network, false when from cache or the curated fallback. */\n fresh: boolean;\n source: 'network' | 'cache' | 'fallback';\n}\n\n/** Provider display names + the order we surface them (the \"top providers\" list). */\nconst PROVIDER_LABELS: Record<string, string> = {\n anthropic: 'Anthropic (Claude)',\n openai: 'OpenAI (GPT)',\n 'x-ai': 'xAI (Grok)',\n google: 'Google (Gemini)',\n 'meta-llama': 'Meta (Llama)',\n deepseek: 'DeepSeek',\n mistralai: 'Mistral',\n qwen: 'Qwen',\n};\nconst FEATURED_ORDER = Object.keys(PROVIDER_LABELS);\n\nconst OPENROUTER_MODELS_URL = 'https://openrouter.ai/api/v1/models';\n/** Cache freshness window: a day is plenty; model lists move slowly. */\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000;\n\nexport interface FetchCatalogOptions {\n fetchImpl?: typeof fetch;\n now?: () => number;\n /** Bypass and refresh from network. */\n noCache?: boolean;\n /** Never touch the network (offline / --local): cache or curated only. */\n offline?: boolean;\n timeoutMs?: number;\n}\n\n/** The per-user catalog cache file (shared across repos, like the model cache). */\nexport function catalogCachePath(): string {\n const base = process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache');\n return path.join(base, 'vibgrate', 'catalog', 'openrouter-models.json');\n}\n\nexport async function fetchCatalog(options: FetchCatalogOptions = {}): Promise<Catalog> {\n const now = options.now ?? (() => 0);\n const fetchImpl = options.fetchImpl ?? fetch;\n\n // Serve from a warm cache when allowed.\n if (!options.noCache) {\n const cached = readCache();\n if (cached && (options.offline || now() - cached.ts < CACHE_TTL_MS)) {\n return { providers: groupModels(cached.models), fresh: false, source: 'cache' };\n }\n }\n if (options.offline) {\n const cached = readCache();\n if (cached) return { providers: groupModels(cached.models), fresh: false, source: 'cache' };\n return { providers: curatedFallback(), fresh: false, source: 'fallback' };\n }\n\n // Fetch fresh.\n try {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? 8000);\n let raw: unknown;\n try {\n const res = await fetchImpl(OPENROUTER_MODELS_URL, { signal: controller.signal });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n raw = await res.json();\n } finally {\n clearTimeout(timer);\n }\n const models = parseModels(raw);\n if (models.length === 0) throw new Error('empty catalog');\n writeCache(models, now());\n return { providers: groupModels(models), fresh: true, source: 'network' };\n } catch {\n // Network failed → cache → curated.\n const cached = readCache();\n if (cached) return { providers: groupModels(cached.models), fresh: false, source: 'cache' };\n return { providers: curatedFallback(), fresh: false, source: 'fallback' };\n }\n}\n\n/** Parse OpenRouter's `/models` payload into our shape (defensive about fields). */\nexport function parseModels(raw: unknown): CatalogModel[] {\n const data = (raw as { data?: unknown[] })?.data;\n if (!Array.isArray(data)) return [];\n const out: CatalogModel[] = [];\n for (const entry of data) {\n const e = entry as {\n id?: unknown;\n name?: unknown;\n context_length?: unknown;\n pricing?: { prompt?: unknown; completion?: unknown };\n };\n if (typeof e.id !== 'string' || !e.id.includes('/')) continue;\n const provider = e.id.split('/')[0];\n out.push({\n id: e.id,\n name: typeof e.name === 'string' ? e.name : e.id,\n provider,\n contextLength: numeric(e.context_length),\n promptPricePerM: perMillion(e.pricing?.prompt),\n completionPricePerM: perMillion(e.pricing?.completion),\n });\n }\n return out;\n}\n\n/** Group models by provider, featured providers first, coding models first within each. */\nexport function groupModels(models: CatalogModel[]): ProviderGroup[] {\n const byProvider = new Map<string, CatalogModel[]>();\n for (const m of models) {\n const list = byProvider.get(m.provider) ?? [];\n list.push(m);\n byProvider.set(m.provider, list);\n }\n const groups: ProviderGroup[] = [];\n for (const [id, list] of byProvider) {\n groups.push({ id, label: PROVIDER_LABELS[id] ?? titleCase(id), models: list.sort(rankModels) });\n }\n // Featured providers in our order first, then the rest alphabetically.\n groups.sort((a, b) => {\n const ia = FEATURED_ORDER.indexOf(a.id);\n const ib = FEATURED_ORDER.indexOf(b.id);\n if (ia !== -1 || ib !== -1) return (ia === -1 ? 1e9 : ia) - (ib === -1 ? 1e9 : ib);\n return a.label.localeCompare(b.label);\n });\n return groups;\n}\n\n/** Coding-oriented models first, then larger context, then name — a helpful default order. */\nfunction rankModels(a: CatalogModel, b: CatalogModel): number {\n const ca = isCoding(a) ? 0 : 1;\n const cb = isCoding(b) ? 0 : 1;\n if (ca !== cb) return ca - cb;\n const la = a.contextLength ?? 0;\n const lb = b.contextLength ?? 0;\n if (la !== lb) return lb - la;\n return a.id.localeCompare(b.id);\n}\n\nfunction isCoding(m: CatalogModel): boolean {\n return /cod(e|er|ing)/i.test(m.id) || /cod(e|er|ing)/i.test(m.name);\n}\n\n/** Top N providers (the guided picker's first screen). */\nexport function topProviders(catalog: Catalog, n = 6): ProviderGroup[] {\n return catalog.providers.slice(0, n);\n}\n\ninterface CacheShape {\n ts: number;\n models: CatalogModel[];\n}\n\nfunction readCache(): CacheShape | null {\n try {\n const parsed = JSON.parse(fs.readFileSync(catalogCachePath(), 'utf8')) as CacheShape;\n if (Array.isArray(parsed.models) && typeof parsed.ts === 'number') return parsed;\n } catch {\n /* no cache */\n }\n return null;\n}\n\nfunction writeCache(models: CatalogModel[], ts: number): void {\n try {\n const file = catalogCachePath();\n fs.mkdirSync(path.dirname(file), { recursive: true });\n fs.writeFileSync(file, JSON.stringify({ ts, models }));\n } catch {\n /* cache is best-effort */\n }\n}\n\n/**\n * A minimal, honestly-labelled offline fallback: just the provider names, so the\n * picker still works with no network and no cache. Model ids are intentionally\n * NOT hard-coded (they go stale) — the flow always offers \"enter a model slug\".\n */\nfunction curatedFallback(): ProviderGroup[] {\n return FEATURED_ORDER.map((id) => ({ id, label: PROVIDER_LABELS[id], models: [] }));\n}\n\nfunction numeric(v: unknown): number | undefined {\n const n = typeof v === 'string' ? Number(v) : typeof v === 'number' ? v : NaN;\n return Number.isFinite(n) ? n : undefined;\n}\n\n/** OpenRouter prices are USD *per token* as strings; convert to per-million. */\nfunction perMillion(v: unknown): number | undefined {\n const n = numeric(v);\n if (n === undefined) return undefined;\n return Math.round(n * 1_000_000 * 1000) / 1000;\n}\n\nfunction titleCase(id: string): string {\n return id.replace(/[-_]/g, ' ').replace(/\\b\\w/g, (ch) => ch.toUpperCase());\n}\n","/**\n * Text-based tool-call protocol fallback (model-agnostic agent robustness).\n *\n * The agent loop speaks native (OpenAI-shaped) function calling, but many\n * backends can't: the embedded llama.cpp host has no tool API at all, and a\n * large share of local models served by Ollama / LM Studio either ignore the\n * native `tools` field or emit their chat-template tool markup — Hermes/Qwen\n * `<tool_call>{…}</tool_call>` tags — as plain assistant text. Leading OSS\n * agents (Cline, Roo Code, Aider) solve this with a *prompt-described* tool\n * protocol parsed from text; this module gives `vg code` the same floor, so the\n * core agent works with whatever model is picked underneath.\n *\n * Two layers, both provider-neutral and unit-tested:\n * - {@link parseTextToolCalls} — recover tool calls a model wrote as text\n * (`<tool_call>` tags, fenced ```tool_call blocks, or a bare JSON object\n * with `name` + `arguments`). Used as a *rescue* on every provider, so a\n * model that ignores native function calling still drives the loop.\n * - {@link withToolCallFallback} — a Provider decorator. For backends that\n * declare `supportsTools: false` it renders the tool list into the system\n * prompt, serializes prior tool rounds as text the model can read, and\n * parses the reply. For native backends it passes through and only rescues.\n */\n\nimport type { ChatMessage, ChatOptions, Provider, ProviderResult, ToolCall, ToolSpec } from './types.js';\n\n/** Formats we can recover a tool call from, in order of specificity. */\nconst TAG_RE = /<tool_call>\\s*([\\s\\S]*?)\\s*<\\/tool_call>/g;\nconst FENCE_RE = /```(?:tool_call|tool|json)?\\s*\\n?([\\s\\S]*?)```/g;\n\ninterface RawCall {\n name?: unknown;\n arguments?: unknown;\n parameters?: unknown;\n input?: unknown;\n}\n\n/** Parse one candidate JSON blob into a ToolCall, or null when it isn't one. */\nfunction toToolCall(blob: string, index: number): ToolCall | null {\n let parsed: RawCall;\n try {\n parsed = JSON.parse(blob) as RawCall;\n } catch {\n return null;\n }\n if (!parsed || typeof parsed !== 'object' || typeof parsed.name !== 'string' || !parsed.name) return null;\n const args = parsed.arguments ?? parsed.parameters ?? parsed.input ?? {};\n return {\n id: `text_${index}`,\n name: parsed.name,\n arguments: args && typeof args === 'object' && !Array.isArray(args) ? (args as Record<string, unknown>) : {},\n };\n}\n\n/**\n * Extract tool calls a model emitted as plain text, returning the calls plus\n * the text with the call markup removed (what remains is the user-facing\n * prose, if any). Order of attempts: `<tool_call>` tags, then fenced blocks,\n * then one bare top-level JSON object. Anything that doesn't parse into a\n * `{name, arguments}` shape is left in the text untouched.\n */\nexport function parseTextToolCalls(text: string): { calls: ToolCall[]; text: string } {\n const calls: ToolCall[] = [];\n let cleaned = text ?? '';\n\n cleaned = cleaned.replace(TAG_RE, (whole, body: string) => {\n const call = toToolCall(body, calls.length);\n if (!call) return whole;\n calls.push(call);\n return '';\n });\n\n if (calls.length === 0) {\n cleaned = cleaned.replace(FENCE_RE, (whole, body: string) => {\n const call = toToolCall(body.trim(), calls.length);\n if (!call) return whole;\n calls.push(call);\n return '';\n });\n }\n\n if (calls.length === 0) {\n const t = cleaned.trim();\n if (t.startsWith('{') && t.endsWith('}')) {\n const call = toToolCall(t, 0);\n if (call) {\n calls.push(call);\n cleaned = '';\n }\n }\n }\n\n return { calls, text: cleaned.trim() };\n}\n\n/** The prompt block that teaches a non-tool-calling model the call format. */\nexport function textToolProtocolInstruction(tools: ToolSpec[]): string {\n const lines = tools.map((t) => {\n const params = JSON.stringify(t.parameters?.properties ?? {});\n return `- ${t.name}: ${t.description.split('\\n')[0]} · arguments schema: ${params}`;\n });\n return [\n '',\n '## Tool calling (text protocol)',\n 'This runtime has no native function-calling. To use a tool, reply with ONLY:',\n '<tool_call>{\"name\": \"<tool name>\", \"arguments\": { … }}</tool_call>',\n 'One tool call per reply. Wait for the tool result before the next call.',\n 'When the task is complete, call the `finish` tool with your Markdown summary.',\n 'Available tools:',\n ...lines,\n ].join('\\n');\n}\n\n/** Serialize a tool round into text for backends that lack tool roles. */\nfunction flattenToolRounds(messages: ChatMessage[]): ChatMessage[] {\n return messages.map((m): ChatMessage => {\n if (m.role === 'assistant' && m.toolCalls?.length) {\n const rendered = m.toolCalls\n .map((c) => `<tool_call>${JSON.stringify({ name: c.name, arguments: c.arguments })}</tool_call>`)\n .join('\\n');\n return { role: 'assistant', content: [m.content, rendered].filter(Boolean).join('\\n') };\n }\n if (m.role === 'tool') {\n return { role: 'user', content: `Tool result for ${m.name}:\\n${m.content}` };\n }\n return m;\n });\n}\n\n/**\n * Wrap a provider so the agent loop's tool calling works regardless of the\n * backend's native capability:\n * - `supportsTools === false` (embedded llama.cpp), or a model the\n * capability registry knows cannot tool-call natively: inject the text\n * protocol into the system prompt, flatten tool rounds to text, parse the\n * reply.\n * - native backends: call through unchanged; when the model returned no\n * native tool calls but its text contains parseable tool markup, rescue it.\n * Idempotent-safe: wrapping a wrapped provider changes nothing observable.\n */\nexport function withToolCallFallback(\n provider: Provider,\n caps?: { nativeTools: boolean | null },\n): Provider {\n return {\n id: provider.id,\n label: provider.label,\n local: provider.local,\n model: provider.model,\n supportsTools: provider.supportsTools,\n async chat(messages: ChatMessage[], opts: ChatOptions = {}): Promise<ProviderResult> {\n const native = provider.supportsTools !== false && caps?.nativeTools !== false;\n if (native || !opts.tools?.length) {\n const result = await provider.chat(messages, opts);\n if ((!result.toolCalls || result.toolCalls.length === 0) && result.text) {\n const rescued = parseTextToolCalls(result.text);\n if (rescued.calls.length) return { ...result, text: rescued.text, toolCalls: rescued.calls };\n }\n return result;\n }\n\n // Text-protocol path: teach the format, flatten history, parse the reply.\n const instruction = textToolProtocolInstruction(opts.tools);\n const flattened = flattenToolRounds(messages);\n const withProtocol: ChatMessage[] = flattened.map((m, i) =>\n i === 0 && m.role === 'system' ? { role: 'system', content: m.content + '\\n' + instruction } : m,\n );\n if (withProtocol[0]?.role !== 'system') {\n withProtocol.unshift({ role: 'system', content: instruction });\n }\n const result = await provider.chat(withProtocol, { ...opts, tools: undefined });\n const parsed = parseTextToolCalls(result.text ?? '');\n if (parsed.calls.length) return { ...result, text: parsed.text, toolCalls: parsed.calls };\n return result;\n },\n };\n}\n","/**\n * Model routing for `vg code` (VG-CLI-CODE §5.2).\n *\n * The \"best in breed\" story is an ordered set of backends with automatic\n * fallback — the OpenRouter/LiteLLM model — expressed as a *scheduling* decision\n * the session can execute: try the preferred provider, and on a transport\n * failure fall through to the next available one. This resolver is pure over its\n * injected inputs (flags, environment, the discovered local fleet), so it is\n * fully testable, and it holds two hard rules from the guardrails:\n *\n * - **No surprise egress or install.** With no explicit selection it picks a\n * backend only from signals already present (a configured hosted key, or a\n * model already pulled locally). It never dials a default cloud endpoint you\n * didn't configure, and never triggers an install to pick a default.\n * - **`--local` stays local.** Under `--local` only on-device backends are\n * eligible; if none are available it fails with an actionable message rather\n * than silently reaching the network.\n * - **Code Modes stay on the Vibgrate manager.** When {@link RouteOptions.codeMode}\n * is set, routing is fail-closed to embedded llama.cpp (first-party GGUF).\n * Ollama / LM Studio are never auto-selected for Code Modes.\n */\n\nimport { CliError, ExitCode } from '../util/exit.js';\nimport { discoverModels, type LocalModel } from '../engine/models.js';\nimport { resolveGgufPath } from '../runtime/resolve-gguf.js';\nimport {\n formatManagerBadgeLine,\n managerFromProviderId,\n type ModelManagerId,\n} from '../runtime/model-manager.js';\nimport {\n LocalLlamaProvider,\n MockProvider,\n OllamaProvider,\n OpenAiCompatibleProvider,\n OPENAI_COMPATIBLE,\n type OpenAiCompatibleConfig,\n} from './providers.js';\nimport { withToolCallFallback } from './text-tool-protocol.js';\nimport { lookupModelCapabilities } from './model-capabilities.js';\nimport type { Provider } from './types.js';\n\nexport interface RouteOptions {\n /** Explicit `--provider` (vibgrate-relay, ollama, lmstudio, foundry-local, openrouter, litellm, openai, together, llama-cpp). */\n provider?: string;\n /** Explicit `--model`. */\n model?: string;\n /** `--local`: on-device backends only. */\n local?: boolean;\n /** `--yes`: consent to a first-use install (only relevant to llama-cpp). */\n consent?: boolean;\n /** Path to a gguf for the llama-cpp backend. */\n modelPath?: string;\n /**\n * Prefer embedded llama.cpp when a GGUF is resolvable (Code Mode preferredInference).\n * When false, Ollama may be tried first (VG_PREFER_OLLAMA).\n */\n preferEmbedded?: boolean;\n /**\n * Code Mode path (spark|flow|forge): fail-closed to the Vibgrate model manager.\n * Never auto-routes to Ollama / LM Studio / hosted.\n */\n codeMode?: boolean;\n /** A scripted reply → force the deterministic MockProvider (tests/`--mock`). */\n mockReply?: string;\n}\n\nexport interface RouteDeps {\n env?: NodeJS.ProcessEnv;\n discover?: () => LocalModel[];\n}\n\nexport interface RouteResult {\n /** Providers to try in order; the session falls through on transport failure. */\n providers: Provider[];\n /** A short, human explanation of the choice (for the run header / --json). */\n reason: string;\n /** Manager identity for the primary provider (badge / UX). */\n manager: ModelManagerId;\n /** e.g. \"[Vibgrate] Code Mode · first-party model manager …\" */\n managerLine: string;\n}\n\nconst HOSTED_IDS = new Set(['vibgrate-relay', 'openrouter', 'litellm', 'openai', 'together']);\n\n/** Resolve the ordered provider list for a run. Throws an actionable CliError when nothing is eligible. */\nexport function resolveProviders(opts: RouteOptions, deps: RouteDeps = {}): RouteResult {\n const env = deps.env ?? process.env;\n const discover = deps.discover ?? discoverModels;\n\n // Deterministic offline floor — used by tests, the benchmark, and `--mock`.\n if (opts.mockReply !== undefined) {\n const providers = [new MockProvider(opts.model ?? 'mock-1', opts.mockReply)];\n return finish(providers, 'mock provider (scripted, offline)');\n }\n\n // Code Modes: Vibgrate manager only (embedded GGUF). No third-party auto-route.\n // Even when code.ts pins provider=llama-cpp, never chain Ollama/LM Studio — a\n // grammar or load failure must surface the real error, not \"couldn't reach Ollama\".\n if (opts.codeMode && (!opts.provider || opts.provider === 'llama-cpp' || opts.provider === 'vibgrate')) {\n const gguf = resolveGgufPath({\n modelPath: opts.modelPath || env.VG_CODE_MODEL_PATH,\n modelRef: opts.model,\n env,\n discover,\n });\n if (!gguf) {\n throw new CliError(\n 'Code Mode needs the Vibgrate model manager weights on disk. Run `vg models install spark|flow|forge` (or pass --model-path to a GGUF). Custom Ollama/LM Studio backends are only used when you set --provider explicitly.',\n ExitCode.NOT_FOUND,\n );\n }\n const providers = [\n new LocalLlamaProvider(opts.model ?? basename(gguf.path), gguf.path, undefined, !!opts.consent),\n ];\n return finish(providers, `Code Mode → Vibgrate model manager (embedded llama.cpp · ${gguf.path})`);\n }\n\n // Explicit provider wins.\n if (opts.provider) {\n const provider = buildExplicit(opts.provider, opts, env, discover);\n // Code Mode + explicit custom backend (ollama, lmstudio, …): still no surprise chain.\n if (opts.codeMode) {\n return finish([provider], `Code Mode → explicit --provider ${opts.provider} (no auto-fallback)`);\n }\n // Custom path: only fall through to other *local* adapters when --local, never LM Studio unless chosen.\n const fallbacks =\n opts.local || provider.local\n ? localFallbacks(opts, env, discover, provider.id, { allowLmStudio: opts.provider === 'lmstudio' })\n : [];\n return finish([provider, ...fallbacks], `explicit --provider ${opts.provider}`);\n }\n\n // --local: on-device only, in preference order (embedded → ollama; no surprise LM Studio).\n if (opts.local) {\n const locals = localFallbacks(opts, env, discover, '', { allowLmStudio: false });\n if (locals.length === 0) {\n throw new CliError(\n 'no local model backend available for --local. Install a Code Mode (`vg models install spark`), start Ollama (`ollama serve` + pull), or point --provider llama-cpp at a gguf. See `vg models`.',\n ExitCode.NOT_FOUND,\n );\n }\n return finish(locals, '--local (on-device backends only)');\n }\n\n // No explicit selection: choose from signals already present, best first.\n // 1) Vibgrate Relay — the first-party hosted router, preferred when the user\n // has signed in. Nothing is dialled without their token, so this stays inside\n // the no-surprise-egress rule above.\n if (env.VIBGRATE_RELAY_TOKEN) {\n const model = resolveHostedModel(opts, env, 'vibgrate-relay');\n const primary = buildHosted('vibgrate-relay', model);\n return finish(\n [primary, ...localFallbacks(opts, env, discover, 'vibgrate-relay', { allowLmStudio: false })],\n 'VIBGRATE_RELAY_TOKEN is set → Vibgrate Relay (with local fallback)',\n );\n }\n // 2) Another configured hosted router key.\n if (env.OPENROUTER_API_KEY) {\n const model = resolveHostedModel(opts, env, 'openrouter');\n const primary = buildHosted('openrouter', model);\n return finish(\n [primary, ...localFallbacks(opts, env, discover, 'openrouter', { allowLmStudio: false })],\n 'OPENROUTER_API_KEY is set → OpenRouter (with local fallback)',\n );\n }\n // 3) A locally-pulled model (embedded first; never auto LM Studio).\n const locals = localFallbacks(opts, env, discover, '', { allowLmStudio: false });\n if (locals.length) return finish(locals, 'a local model is available → on-device (no key needed)');\n // 4) Any other configured hosted key.\n for (const id of ['litellm', 'openai', 'together'] as const) {\n const keyEnv = OPENAI_COMPATIBLE[id].apiKeyEnv;\n if (keyEnv && env[keyEnv]) {\n const model = resolveHostedModel(opts, env, id);\n return finish([buildHosted(id, model)], `${keyEnv} is set → ${OPENAI_COMPATIBLE[id].label}`);\n }\n }\n\n throw new CliError(\n 'no model backend configured. Do one of: sign in to Vibgrate Relay (VIBGRATE_RELAY_TOKEN), set OPENROUTER_API_KEY for the hosted router, run `vg models install spark` for the Vibgrate manager, run Ollama locally, or use --local with a local model. Set the model with --model or VG_CODE_MODEL.',\n ExitCode.NOT_FOUND,\n );\n}\n\nfunction finish(rawProviders: Provider[], reason: string): RouteResult {\n // Every backend gets the tool-call fallback: native providers are passed\n // through (with a text-markup rescue), backends without native function\n // calling (embedded llama.cpp) — and models the capability registry knows\n // cannot tool-call natively — get the prompt-described text protocol. This\n // is what makes the agent work with whatever model is picked underneath.\n const providers = rawProviders.map((p) => withToolCallFallback(p, lookupModelCapabilities(p.model)));\n const primary = providers[0];\n const manager = managerFromProviderId(primary?.id);\n return {\n providers,\n reason,\n manager,\n managerLine: formatManagerBadgeLine(manager, primary?.model),\n };\n}\n\nfunction buildExplicit(id: string, opts: RouteOptions, env: NodeJS.ProcessEnv, discover: () => LocalModel[]): Provider {\n if (id === 'ollama') return new OllamaProvider(resolveLocalModel(opts, discover, 'ollama'), env.OLLAMA_HOST);\n if (id === 'llama-cpp' || id === 'vibgrate') {\n const resolved = resolveGgufPath({\n modelPath: opts.modelPath || env.VG_CODE_MODEL_PATH,\n modelRef: opts.model,\n env,\n discover,\n });\n if (!resolved) {\n throw new CliError(\n '--provider llama-cpp needs a GGUF: pass --model-path, set VG_CODE_MODEL_PATH, or run `vg models install` so the weight store has a catalogued gguf. See `vg models`.',\n ExitCode.USAGE_ERROR,\n );\n }\n return new LocalLlamaProvider(opts.model ?? basename(resolved.path), resolved.path, undefined, !!opts.consent);\n }\n if (id === 'lmstudio') return buildHosted('lmstudio', resolveHostedModel(opts, env, 'lmstudio'));\n if (id === 'foundry-local' || id === 'foundry') {\n return buildHosted('foundry-local', resolveHostedModel(opts, env, 'foundry-local'));\n }\n if (HOSTED_IDS.has(id)) return buildHosted(id, resolveHostedModel(opts, env, id));\n throw new CliError(\n `unknown --provider \"${id}\". Known: vibgrate-relay, ollama, lmstudio, foundry-local, openrouter, litellm, openai, together, llama-cpp.`,\n ExitCode.USAGE_ERROR,\n );\n}\n\nfunction buildHosted(id: string, model: string): OpenAiCompatibleProvider {\n const base = OPENAI_COMPATIBLE[id];\n const config: OpenAiCompatibleConfig = { ...base, id };\n return new OpenAiCompatibleProvider(model, config);\n}\n\ninterface LocalFallbackOpts {\n /** Only include LM Studio when the user explicitly asked for it. */\n allowLmStudio: boolean;\n}\n\n/** On-device backends in preference order, skipping the one already chosen as primary. */\nfunction localFallbacks(\n opts: RouteOptions,\n env: NodeJS.ProcessEnv,\n discover: () => LocalModel[],\n exclude: string,\n fb: LocalFallbackOpts,\n): Provider[] {\n const out: Provider[] = [];\n const models = safeDiscover(discover);\n\n // Approach B default: when a GGUF is already on disk, embedded is primary local.\n // Opt out with VG_PREFER_OLLAMA=1 if the user wants Ollama first.\n const preferOllama =\n env.VG_PREFER_OLLAMA === '1' ||\n env.VIBGRATE_PREFER_OLLAMA === '1' ||\n opts.preferEmbedded === false;\n const gguf =\n exclude === 'llama-cpp' || exclude === 'vibgrate'\n ? null\n : resolveGgufPath({\n modelPath: opts.modelPath || env.VG_CODE_MODEL_PATH,\n modelRef: opts.model,\n env,\n discover: () => models,\n });\n\n if (gguf && !preferOllama) {\n out.push(new LocalLlamaProvider(opts.model ?? basename(gguf.path), gguf.path, undefined, !!opts.consent));\n }\n\n const ollamaModel = opts.model ?? firstOfRuntime(models, 'ollama');\n if (exclude !== 'ollama' && ollamaModel) out.push(new OllamaProvider(ollamaModel, env.OLLAMA_HOST));\n\n // LM Studio only when explicitly allowed (user chose --provider lmstudio).\n if (fb.allowLmStudio && exclude !== 'lmstudio') {\n const lmModel = opts.model ?? firstOfRuntime(models, 'lm-studio');\n if (lmModel) out.push(buildHosted('lmstudio', lmModel));\n }\n\n // Foundry Local when server/env is configured.\n if (exclude !== 'foundry-local' && exclude !== 'foundry' && (env.FOUNDRY_LOCAL_BASE_URL || env.VG_CODE_PROVIDER === 'foundry-local')) {\n try {\n const m = opts.model || env.VG_CODE_MODEL;\n if (m) out.push(buildHosted('foundry-local', m));\n } catch {\n /* skip if no model */\n }\n }\n\n // Embedded last if user forced Ollama-first but GGUF still available.\n if (gguf && !out.some((p) => p.id === 'llama-cpp')) {\n out.push(new LocalLlamaProvider(opts.model ?? basename(gguf.path), gguf.path, undefined, !!opts.consent));\n }\n return out;\n}\n\nfunction resolveLocalModel(opts: RouteOptions, discover: () => LocalModel[], runtime: LocalModel['runtime']): string {\n if (opts.model) return opts.model;\n const found = firstOfRuntime(safeDiscover(discover), runtime);\n if (found) return found;\n throw new CliError(`--provider ${runtime} needs a model. Pull one (\\`ollama pull <model>\\`) then re-run, or pass --model. See \\`vg models\\`.`, ExitCode.NOT_FOUND);\n}\n\nfunction resolveHostedModel(opts: RouteOptions, env: NodeJS.ProcessEnv, id: string): string {\n const model = opts.model || env.VG_CODE_MODEL;\n if (model) return model;\n throw new CliError(\n `${OPENAI_COMPATIBLE[id].label} needs a model id — pass --model (e.g. a current best-in-breed coding model) or set VG_CODE_MODEL. We don't hard-code a model so you always pick the current best one.`,\n ExitCode.USAGE_ERROR,\n );\n}\n\nfunction firstOfRuntime(models: LocalModel[], runtime: LocalModel['runtime']): string | undefined {\n // Deterministic: discoverModels() already returns a sorted list.\n const m = models.find((x) => x.runtime === runtime);\n return m?.name;\n}\n\nfunction safeDiscover(discover: () => LocalModel[]): LocalModel[] {\n try {\n return discover();\n } catch {\n return [];\n }\n}\n\nfunction basename(p: string): string {\n return p.replace(/\\\\/g, '/').split('/').pop() ?? p;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { resolveIngestHost } from './chunk-HTLDXEHW.js';
2
- import { VERSION } from './chunk-QT2PMGN3.js';
3
- import { cacheDir } from './chunk-AJ2KE3NT.js';
2
+ import { VERSION } from './chunk-7KNFG44U.js';
3
+ import { cacheDir } from './chunk-QMME6TB4.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-BBFQZ7CA.js.map
216
- //# sourceMappingURL=chunk-BBFQZ7CA.js.map
215
+ //# sourceMappingURL=chunk-PXM3VZYR.js.map
216
+ //# sourceMappingURL=chunk-PXM3VZYR.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/engine/stats-share.ts"],"names":[],"mappings":"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","file":"chunk-BBFQZ7CA.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":"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","file":"chunk-PXM3VZYR.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"]}
@@ -440,7 +440,18 @@ function expandConcepts(orderedTokens) {
440
440
  }
441
441
  return out;
442
442
  }
443
+ function bigramConsumedTokens(orderedTokens) {
444
+ const consumed = /* @__PURE__ */ new Set();
445
+ for (let i = 0; i + 1 < orderedTokens.length; i++) {
446
+ const bigram = `${orderedTokens[i]} ${orderedTokens[i + 1]}`;
447
+ if (!BIGRAM_CONCEPTS[bigram]) continue;
448
+ for (const tok of [orderedTokens[i], orderedTokens[i + 1]]) {
449
+ if (!lexiconKey(tok)) consumed.add(tok);
450
+ }
451
+ }
452
+ return consumed;
453
+ }
443
454
 
444
- export { WEAK_TERMS, cacheDir, expandConcepts, loadCache, parseGraph, serializeGraph, slimGraphForExport, stableStringify };
445
- //# sourceMappingURL=chunk-AJ2KE3NT.js.map
446
- //# sourceMappingURL=chunk-AJ2KE3NT.js.map
455
+ export { WEAK_TERMS, bigramConsumedTokens, cacheDir, expandConcepts, loadCache, parseGraph, serializeGraph, slimGraphForExport, stableStringify };
456
+ //# sourceMappingURL=chunk-QMME6TB4.js.map
457
+ //# sourceMappingURL=chunk-QMME6TB4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/engine/serialize.ts","../src/engine/cache.ts","../src/engine/concepts.ts"],"names":[],"mappings":"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","file":"chunk-QMME6TB4.js","sourcesContent":["import type { VgGraph } from '../schema.js';\n\n/**\n * Deterministic serialization of `graph.json`.\n *\n * Object keys are sorted recursively and arrays are emitted in the (already\n * stable) order the engine produced them, so two runs over identical content\n * yield byte-identical output — the determinism contract (VG-CLI-SPEC §1.3).\n * Pretty-printed (2-space) and newline-terminated so the committed artifact is\n * human-diffable and plays well with the union merge driver.\n */\nexport function serializeGraph(graph: VgGraph, opts?: { compact?: boolean }): string {\n // Compact (no pretty-print) for large maps / CI artifacts — still deterministic.\n const indent = opts?.compact ? 0 : 2;\n return `${stableStringify(graph, indent)}\\n`;\n}\n\n/**\n * Drop heavy optional fields for export/sharing when size matters.\n * Does not mutate the input graph.\n */\nexport function slimGraphForExport(graph: VgGraph): VgGraph {\n return {\n ...graph,\n areas: graph.areas.map((a) => ({\n ...a,\n members: [], // member id lists dominate XL exports; area id still on nodes\n })),\n grounding: undefined,\n facts: graph.facts,\n // Keep summaries/unknowns — small and useful to agents.\n };\n}\n\nexport function stableStringify(value: unknown, indent = 2): string {\n return JSON.stringify(sortKeys(value), null, indent);\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortKeys);\n if (value && typeof value === 'object') {\n const input = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(input).sort()) {\n const v = input[key];\n if (v === undefined) continue; // omit undefined for stable output\n out[key] = sortKeys(v);\n }\n return out;\n }\n return value;\n}\n\nexport function parseGraph(json: string): VgGraph {\n return JSON.parse(json) as VgGraph;\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { stableStringify } from './serialize.js';\nimport type { FileParse } from './types.js';\n\n/**\n * Incremental parse cache. Maps a file's content hash to its parsed\n * symbol/edge tables, so a rebuild re-parses only files whose content actually\n * changed (VG-DEVELOPMENT-PLAN Phase 0.4). Lives under `.vibgrate/cache/` and is\n * gitignored — never part of the committed artifact.\n *\n * The cache is a pure performance optimisation: a reused FileParse is identical\n * to a freshly-parsed one (parsing is pure over content), so the graph is\n * byte-identical whether or not the cache was warm. CI-enforced by the\n * mutation-corpus identity gate (incremental-identity.test.ts): warm\n * incremental rebuild ≡ cold full rebuild, byte for byte, across\n * edit/add/delete/rename/touch mutations and the production refresh path.\n */\n\n// Bumped to /4: optional mtime+size fingerprint for stat-skip fast path.\nconst CACHE_VERSION = 'vg-parse-cache/4';\n\ninterface CacheEntry {\n hash: string;\n mtimeMs?: number;\n size?: number;\n parse: FileParse;\n}\n\ninterface CacheFile {\n version: string;\n toolVersion: string;\n grammars: string;\n entries: Record<string, CacheEntry>;\n}\n\nexport interface ParseCache {\n get(rel: string, hash: string): FileParse | undefined;\n /** Fast path: mtime+size match → reuse parse without re-reading bytes. */\n getByStat(rel: string, mtimeMs: number, size: number): { parse: FileParse; hash: string } | undefined;\n set(rel: string, parse: FileParse, stat?: { mtimeMs: number; size: number }): void;\n /** Drop entries for files no longer present. */\n prune(currentRels: Set<string>): void;\n save(): void;\n}\n\nexport function cacheDir(root: string): string {\n return path.join(root, '.vibgrate', 'cache');\n}\n\nfunction cachePath(root: string): string {\n return path.join(cacheDir(root), 'parse-cache.json');\n}\n\nexport function loadCache(\n root: string,\n opts: { toolVersion: string; grammars: string; disabled?: boolean },\n): ParseCache {\n const file = cachePath(root);\n let data: CacheFile = {\n version: CACHE_VERSION,\n toolVersion: opts.toolVersion,\n grammars: opts.grammars,\n entries: {},\n };\n\n if (!opts.disabled && fs.existsSync(file)) {\n try {\n const loaded = JSON.parse(fs.readFileSync(file, 'utf8')) as CacheFile;\n // Accept v3 → v4 (stat fields optional).\n if (\n (loaded.version === CACHE_VERSION || loaded.version === 'vg-parse-cache/3') &&\n loaded.toolVersion === opts.toolVersion &&\n loaded.grammars === opts.grammars &&\n loaded.entries\n ) {\n data = { ...loaded, version: CACHE_VERSION };\n }\n } catch {\n /* corrupt cache — start fresh */\n }\n }\n\n return {\n get(rel, hash) {\n const entry = data.entries[rel];\n return entry && entry.hash === hash ? entry.parse : undefined;\n },\n getByStat(rel, mtimeMs, size) {\n const entry = data.entries[rel];\n if (!entry) return undefined;\n if (entry.mtimeMs === mtimeMs && entry.size === size && entry.parse) {\n return { parse: entry.parse, hash: entry.hash };\n }\n return undefined;\n },\n set(rel, parse, stat) {\n data.entries[rel] = {\n hash: parse.hash,\n parse,\n mtimeMs: stat?.mtimeMs,\n size: stat?.size,\n };\n },\n prune(currentRels) {\n for (const rel of Object.keys(data.entries)) {\n if (!currentRels.has(rel)) delete data.entries[rel];\n }\n },\n save() {\n fs.mkdirSync(cacheDir(root), { recursive: true });\n fs.writeFileSync(file, stableStringify(data, 0));\n },\n };\n}\n","/**\n * Term roles and deterministic concept expansion for `vg ask` / Task Capsule\n * seed ranking (engine/query.ts).\n *\n * Two failure modes motivated this module (field report, 2026-07):\n *\n * 1. Weak process verbs dominated intent asks. \"what do i need to do to add\n * payments via direct debit?\" seeded every `add*` symbol in the repo\n * (`addTeamMember`, `AddBlogForm`, `submitAdd`, …) because \"add\" scored on\n * equal footing with \"debit\". Verbs that describe the ACTION the caller\n * wants (\"add\", \"create\", \"via\") are not the TOPIC being asked about — they\n * may corroborate a topic match but must never be a seed's sole evidence.\n *\n * 2. No conceptual pull. \"payments\" never reached `StripeGateway` /\n * `InvoiceService` unless a symbol literally contained \"payment\". A small,\n * static, product-domain lexicon (payments → stripe/billing/invoice/…,\n * \"direct debit\" → sepa/bacs/mandate) closes the gap deterministically —\n * no embeddings, no network, stable across runs.\n *\n * Everything here is pure data + pure functions: same question in, same\n * expansion out, so capsule ranking stays benchmarkable and pinnable.\n */\n\n/**\n * Process verbs and feature-request scaffolding: words that describe what the\n * caller wants DONE, not what the code is ABOUT. They still contribute score\n * (down-weighted) to nodes that independently match a content term, but a node\n * matching only weak terms is suppressed — that is exactly the `add*` grab-bag\n * failure. Distinct from STOPWORDS (which are dropped outright): a weak term\n * still corroborates (\"add … to scanDir\" boosts an `addEntry` sibling of a\n * scanDir hit), it just cannot carry a seed alone.\n */\nexport const WEAK_TERMS = new Set([\n 'add', 'adds', 'added', 'adding',\n 'create', 'creates', 'created', 'creating',\n 'make', 'makes', 'making', 'made',\n 'new', 'newly',\n 'remove', 'removes', 'removed', 'removing',\n 'delete', 'deletes', 'deleted', 'deleting',\n 'update', 'updates', 'updated', 'updating',\n 'change', 'changes', 'changed', 'changing',\n 'set', 'sets', 'setting', 'setup',\n 'get', 'gets', 'getting',\n 'use', 'uses', 'used', 'using',\n 'want', 'wants', 'wanted',\n 'do', 'does', 'doing', 'done',\n 'support', 'supports', 'supported', 'supporting',\n 'enable', 'enables', 'enabled', 'enabling',\n 'disable', 'disables', 'disabled', 'disabling',\n 'allow', 'allows', 'allowed',\n 'implement', 'implements', 'implemented', 'implementing',\n 'build', 'builds', 'building', 'built',\n 'via', 'through', 'into', 'onto',\n 'way', 'ways', 'thing', 'things', 'stuff',\n 'feature', 'features', 'functionality',\n 'method', 'methods', 'option', 'options', 'ability',\n 'help', 'start', 'begin', 'work', 'works', 'working',\n 'also', 'currently', 'properly', 'correctly', 'please',\n 'happens', 'happen', 'something', 'somewhere',\n 'step', 'steps', 'flow', 'process',\n 'you', 'can',\n]);\n\n/**\n * Product-domain concept lexicon: question token → identifier vocabulary that\n * OWNS the concept in real codebases. Expansion terms score at a reduced tier\n * (EXPANSION_WEIGHT in query.ts) and count as content evidence, with the\n * provenance kept in the seed's `why` (`payments→stripe`).\n *\n * Keep entries conservative: every value should be a word a maintainer would\n * plausibly put in an identifier or directory name for that concept. Do not\n * add framing words (\"code\", \"logic\") — they are stopwords, not concepts.\n */\nconst CONCEPTS: Record<string, readonly string[]> = {\n // ---- payments / billing ----\n payment: ['stripe', 'billing', 'invoice', 'checkout', 'charge', 'subscription', 'refund', 'payout', 'card', 'debit', 'mandate'],\n pay: ['payment', 'stripe', 'charge', 'billing', 'invoice'],\n paid: ['payment', 'invoice', 'charge'],\n billing: ['invoice', 'payment', 'subscription', 'stripe', 'charge', 'renewal'],\n checkout: ['stripe', 'payment', 'cart', 'session'],\n debit: ['mandate', 'sepa', 'bacs', 'ach', 'bank', 'payment'],\n mandate: ['sepa', 'bacs', 'debit'],\n sepa: ['mandate', 'debit', 'iban', 'bank'],\n bacs: ['mandate', 'debit', 'bank'],\n ach: ['mandate', 'debit', 'bank'],\n stripe: ['payment', 'billing', 'checkout', 'webhook', 'charge', 'card'],\n refund: ['payment', 'invoice', 'stripe', 'charge'],\n invoice: ['billing', 'payment', 'refund', 'subscription'],\n subscription: ['billing', 'renewal', 'invoice', 'plan', 'recurring'],\n recurring: ['subscription', 'renewal', 'mandate', 'debit'],\n renewal: ['subscription', 'billing', 'renew'],\n card: ['payment', 'charge', 'stripe'],\n credit: ['card', 'payment', 'charge'],\n bank: ['debit', 'mandate', 'sepa', 'iban', 'account'],\n charge: ['payment', 'card', 'stripe'],\n webhook: ['event', 'handler', 'callback'],\n price: ['payment', 'billing', 'plan'],\n customer: ['billing', 'account', 'user'],\n // ---- auth ----\n auth: ['login', 'session', 'token', 'oauth', 'password', 'credential'],\n authentication: ['auth', 'login', 'session', 'token', 'password'],\n authenticated: ['auth', 'login', 'session'],\n login: ['auth', 'session', 'password', 'signin', 'oauth'],\n signin: ['login', 'auth', 'session'],\n signup: ['register', 'onboard', 'account'],\n logout: ['session', 'auth', 'signout'],\n password: ['auth', 'login', 'credential', 'hash'],\n session: ['auth', 'login', 'token'],\n token: ['session', 'auth', 'jwt'],\n oauth: ['auth', 'login', 'callback', 'provider'],\n google: ['oauth', 'login', 'auth'],\n github: ['oauth', 'login', 'auth'],\n sso: ['oauth', 'auth', 'saml', 'login'],\n credential: ['auth', 'password', 'token', 'secret'],\n // ---- dependencies / supply chain ----\n dependency: ['package', 'audit', 'vulnerability', 'advisory', 'lockfile', 'version'],\n package: ['dependency', 'audit', 'vulnerability', 'advisory', 'lockfile'],\n vulnerability: ['advisory', 'cve', 'osv', 'audit', 'vulnerable'],\n vulnerable: ['vulnerability', 'advisory', 'audit', 'cve'],\n advisory: ['vulnerability', 'cve', 'osv', 'audit'],\n cve: ['vulnerability', 'advisory', 'osv'],\n risk: ['vulnerability', 'audit', 'advisory'],\n security: ['vulnerability', 'audit', 'advisory'],\n audit: ['dependency', 'vulnerability', 'advisory'],\n scan: ['audit', 'vulnerability', 'scanner'],\n // ---- notifications / messaging ----\n email: ['mail', 'smtp', 'sender', 'template', 'message'],\n mail: ['email', 'smtp', 'sender'],\n notification: ['notify', 'email', 'sms', 'push', 'alert'],\n notify: ['notification', 'email', 'alert'],\n sms: ['notification', 'message', 'twilio'],\n // ---- e-commerce ----\n cart: ['checkout', 'order', 'shop', 'basket', 'discount'],\n basket: ['cart', 'checkout', 'order'],\n order: ['cart', 'shipment', 'fulfillment', 'shop', 'checkout'],\n ship: ['order', 'fulfillment', 'delivery', 'shipment'],\n shipment: ['order', 'fulfillment', 'delivery', 'track'],\n shipping: ['order', 'fulfillment', 'delivery', 'shipment'],\n shipped: ['order', 'fulfillment', 'shipment'],\n inventory: ['stock', 'product', 'catalog', 'restock'],\n stock: ['inventory', 'product', 'restock'],\n product: ['catalog', 'inventory', 'shop'],\n discount: ['coupon', 'promo', 'cart', 'price'],\n coupon: ['discount', 'promo', 'code'],\n // ---- chat / social ----\n chat: ['message', 'room', 'conversation', 'presence'],\n message: ['chat', 'sms', 'notification', 'thread'],\n conversation: ['chat', 'message', 'thread'],\n presence: ['online', 'typing', 'status'],\n online: ['presence', 'status'],\n typing: ['presence', 'indicator', 'broadcast'],\n // ---- media / streaming ----\n video: ['media', 'transcode', 'playback', 'stream', 'thumbnail'],\n stream: ['video', 'playback', 'manifest', 'media'],\n streaming: ['video', 'playback', 'manifest', 'media'],\n playback: ['video', 'stream', 'media', 'watch'],\n transcode: ['video', 'media', 'encode'],\n thumbnail: ['video', 'image', 'media'],\n media: ['video', 'stream', 'playback', 'asset'],\n // ---- analytics ----\n analytics: ['event', 'track', 'metric', 'funnel', 'report'],\n event: ['track', 'analytics', 'webhook'],\n track: ['event', 'analytics'],\n funnel: ['conversion', 'analytics', 'event'],\n conversion: ['funnel', 'analytics'],\n report: ['metrics', 'export', 'analytics'],\n // ---- content / CMS ----\n article: ['publish', 'content', 'post', 'cms'],\n publish: ['article', 'release', 'post', 'content'],\n post: ['article', 'publish', 'message'],\n blog: ['article', 'publish', 'post', 'cms'],\n content: ['cms', 'article', 'markdown'],\n markdown: ['render', 'article', 'content'],\n cms: ['article', 'content', 'publish'],\n // ---- CI / deployment ----\n deploy: ['release', 'rollback', 'pipeline', 'deployment'],\n deployment: ['deploy', 'release', 'rollback', 'pipeline'],\n release: ['deploy', 'version', 'rollback'],\n rollback: ['deploy', 'release', 'deployment'],\n pipeline: ['stage', 'deploy', 'runner', 'ci'],\n canary: ['deploy', 'rollout', 'release'],\n // ---- mobile ----\n push: ['notification', 'device', 'token', 'mobile'],\n device: ['push', 'token', 'mobile', 'register'],\n deeplink: ['link', 'route', 'universal'],\n mobile: ['push', 'device', 'deeplink', 'app'],\n ios: ['mobile', 'universal', 'link', 'app'],\n android: ['mobile', 'push', 'device', 'app'],\n // ---- batch / ETL / mainframe ----\n batch: ['settlement', 'job', 'etl', 'reconcile'],\n settlement: ['batch', 'reconcile', 'ledger', 'clearing'],\n reconcile: ['ledger', 'settlement', 'batch'],\n ledger: ['settlement', 'reconcile', 'balance', 'journal'],\n mainframe: ['batch', 'settlement', 'ebcdic', 'cobol', 'fixed'],\n ebcdic: ['mainframe', 'record', 'convert', 'legacy'],\n cobol: ['mainframe', 'batch', 'ebcdic'],\n etl: ['batch', 'pipeline', 'extract', 'load', 'transform'],\n nightly: ['batch', 'cron', 'schedule', 'job'],\n // ---- geo / maps ----\n geocode: ['address', 'location', 'map', 'geo'],\n address: ['geocode', 'location'],\n map: ['geo', 'route', 'location'],\n route: ['distance', 'path', 'planner', 'geo'],\n distance: ['route', 'haversine', 'geo'],\n location: ['geo', 'geocode', 'map'],\n arrival: ['route', 'eta', 'estimate'],\n // ---- i18n ----\n translation: ['locale', 'i18n', 'language', 'translate'],\n translate: ['translation', 'locale', 'language'],\n locale: ['translation', 'i18n', 'language', 'format'],\n i18n: ['translation', 'locale', 'language'],\n language: ['locale', 'translation', 'i18n'],\n localized: ['locale', 'translation', 'format'],\n // ---- observability ----\n metric: ['counter', 'prometheus', 'telemetry', 'export'],\n prometheus: ['metric', 'exporter', 'monitoring'],\n trace: ['span', 'telemetry', 'observability'],\n span: ['trace', 'telemetry'],\n monitoring: ['metric', 'trace', 'alert', 'observability'],\n telemetry: ['metric', 'trace', 'span'],\n counter: ['metric', 'increment'],\n // ---- feature flags / experimentation ----\n flag: ['feature', 'rollout', 'toggle', 'experiment'],\n rollout: ['flag', 'percentage', 'release', 'experiment'],\n toggle: ['flag', 'feature', 'switch'],\n experiment: ['variant', 'assign', 'flag', 'exposure'],\n variant: ['experiment', 'assign'],\n // ---- generic infrastructure ----\n database: ['schema', 'migration', 'sql', 'query', 'orm'],\n db: ['database', 'schema', 'migration', 'sql'],\n migration: ['database', 'schema', 'migrate', 'sql'],\n cache: ['redis', 'ttl', 'store'],\n queue: ['job', 'worker', 'task', 'batch'],\n job: ['queue', 'worker', 'cron'],\n upload: ['file', 'storage', 'blob', 'asset'],\n storage: ['file', 'upload', 'bucket', 'blob'],\n permission: ['role', 'rbac', 'acl', 'access', 'grant'],\n role: ['permission', 'rbac', 'access'],\n error: ['exception', 'failure', 'handler'],\n config: ['settings', 'env', 'configuration'],\n};\n\n/**\n * Adjacent-word concepts: phrases whose meaning is NOT the sum of their\n * tokens. \"direct debit\" is a payments concept; \"direct\" alone is a URL /\n * filesystem word (`validDirectUrl`, `directoryListing` — real distractors\n * from the field report). Detected over the RAW ordered token stream, before\n * stopword filtering, so \"sign in\" / \"log in\" survive.\n */\nconst BIGRAM_CONCEPTS: Record<string, readonly string[]> = {\n 'direct debit': ['debit', 'mandate', 'sepa', 'bacs', 'bank'],\n 'direct debits': ['debit', 'mandate', 'sepa', 'bacs', 'bank'],\n 'sign in': ['login', 'signin', 'auth', 'session'],\n 'signs in': ['login', 'signin', 'auth', 'session'],\n 'log in': ['login', 'auth', 'session'],\n 'logs in': ['login', 'auth', 'session'],\n 'logged in': ['login', 'auth', 'session'],\n 'sign up': ['signup', 'register', 'account'],\n 'credit card': ['card', 'payment', 'charge', 'stripe'],\n 'credit cards': ['card', 'payment', 'charge', 'stripe'],\n 'bank transfer': ['bank', 'payment', 'sepa', 'transfer'],\n 'rate limit': ['ratelimit', 'throttle', 'quota'],\n 'two factor': ['totp', 'mfa', 'otp', 'auth'],\n 'payment method': ['payment', 'stripe', 'card', 'debit'],\n 'payment methods': ['payment', 'stripe', 'card', 'debit'],\n 'push notification': ['push', 'device', 'token', 'notification'],\n 'push notifications': ['push', 'device', 'token', 'notification'],\n 'deep link': ['deeplink', 'link', 'route'],\n 'deep links': ['deeplink', 'link', 'route'],\n 'universal link': ['deeplink', 'link', 'universal'],\n 'universal links': ['deeplink', 'link', 'universal'],\n 'feature flag': ['flag', 'rollout', 'toggle', 'experiment'],\n 'feature flags': ['flag', 'rollout', 'toggle', 'experiment'],\n 'shopping cart': ['cart', 'checkout', 'order'],\n 'roll back': ['rollback', 'deploy', 'release'],\n 'rolled back': ['rollback', 'deploy', 'release'],\n 'ab test': ['experiment', 'variant'],\n 'sign out': ['logout', 'session', 'auth'],\n 'fixed width': ['record', 'export', 'mainframe', 'batch'],\n};\n\nexport interface ConceptExpansion {\n /** The expansion vocabulary term to score against symbol names. */\n term: string;\n /** The question token (or bigram) that produced it — kept for `why`. */\n from: string;\n}\n\n/** Singularize the trivial English plurals that show up in questions. */\nfunction lexiconKey(token: string): string | null {\n if (token in CONCEPTS) return token;\n if (token.endsWith('ies')) {\n const singular = token.slice(0, -3) + 'y';\n if (singular in CONCEPTS) return singular;\n }\n if (token.endsWith('s')) {\n const singular = token.slice(0, -1);\n if (singular in CONCEPTS) return singular;\n }\n return null;\n}\n\n/**\n * Expand a question's ordered, lowercased token stream (stopwords INCLUDED —\n * bigrams like \"sign in\" need them) into concept vocabulary. Deterministic:\n * output order follows first appearance in the question, then lexicon order.\n * Tokens already present in the question are not re-emitted as expansions.\n */\nexport function expandConcepts(orderedTokens: string[]): ConceptExpansion[] {\n const present = new Set(orderedTokens);\n const out: ConceptExpansion[] = [];\n const emitted = new Set<string>();\n const emit = (term: string, from: string) => {\n if (present.has(term) || emitted.has(term)) return;\n emitted.add(term);\n out.push({ term, from });\n };\n\n for (let i = 0; i + 1 < orderedTokens.length; i++) {\n const bigram = `${orderedTokens[i]} ${orderedTokens[i + 1]}`;\n const terms = BIGRAM_CONCEPTS[bigram];\n if (terms) for (const t of terms) emit(t, bigram);\n }\n for (const token of orderedTokens) {\n const key = lexiconKey(token);\n if (key) for (const t of CONCEPTS[key]!) emit(t, token);\n }\n return out;\n}\n\n/**\n * Tokens CONSUMED by a fired bigram concept that carry no standalone domain\n * meaning of their own — \"direct\" in \"direct debit\", \"sign\" in \"sign in\".\n * The bigram's expansion vocabulary re-supplies the topical words (debit,\n * mandate, login, …), so the consumed token must stop acting as independent\n * content evidence: left at full weight it seeds every `directGet`/\n * `redirectUrl`/`directoryListing` in the repo — the exact distractor set the\n * BIGRAM_CONCEPTS comment above documents. A constituent that is itself a\n * lexicon concept (\"debit\", \"card\") keeps its content role.\n */\nexport function bigramConsumedTokens(orderedTokens: string[]): Set<string> {\n const consumed = new Set<string>();\n for (let i = 0; i + 1 < orderedTokens.length; i++) {\n const bigram = `${orderedTokens[i]} ${orderedTokens[i + 1]}`;\n if (!BIGRAM_CONCEPTS[bigram]) continue;\n for (const tok of [orderedTokens[i], orderedTokens[i + 1]]) {\n if (!lexiconKey(tok)) consumed.add(tok);\n }\n }\n return consumed;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { vgdRequest } from './chunk-RBIRXQR6.js';
2
2
  import { resolveOne } from './chunk-J7LKEB2R.js';
3
- import { impactOf, queryGraph } from './chunk-5VH3Y4QC.js';
3
+ import { impactOf, queryGraph } from './chunk-HC44772H.js';
4
4
 
5
5
  // src/code/graph-backend.ts
6
6
  function localGraphBackend(graph) {
@@ -132,5 +132,5 @@ function resolveSymbolId(graph, symbol) {
132
132
  }
133
133
 
134
134
  export { localGraphBackend, resolveGraphBackend, vgdGraphBackend };
135
- //# sourceMappingURL=chunk-JUSXLCSE.js.map
136
- //# sourceMappingURL=chunk-JUSXLCSE.js.map
135
+ //# sourceMappingURL=chunk-TM5XQY3L.js.map
136
+ //# sourceMappingURL=chunk-TM5XQY3L.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/code/graph-backend.ts"],"names":[],"mappings":"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","file":"chunk-JUSXLCSE.js","sourcesContent":["/**\n * Graph query backend for the agent tool layer (Fusion Runtime).\n *\n * Tools prefer a warm ActiveGraph in vgd when a daemon session is attached;\n * otherwise they fall back to the in-process {@link VgGraph}. Failures never\n * surface to the model as transport errors — they degrade to local query.\n */\n\nimport { queryGraph } from '../engine/query.js';\nimport { impactOf } from '../engine/impact.js';\nimport { resolveOne } from '../engine/lookup.js';\nimport { vgdRequest, type VgdClientOptions } from '../runtime/vgd/client.js';\nimport type { VgdRequest } from '../runtime/vgd/protocol.js';\nimport type { VgGraph } from '../schema.js';\n\nexport type GraphBackendSource = 'local' | 'vgd';\n\nexport interface GraphSearchHit {\n id: string;\n qualifiedName: string;\n kind: string;\n file: string;\n line: number;\n score: number;\n why: string;\n signature?: string | null;\n}\n\nexport interface GraphImpactHit {\n id: string;\n name: string;\n kind: string;\n file: string;\n line: number;\n depth: number;\n confidence: number;\n}\n\nexport interface GraphImpactResult {\n root: { id: string; name: string };\n depth: number;\n affected: GraphImpactHit[];\n direct: number;\n transitive: number;\n source: GraphBackendSource;\n}\n\nexport interface GraphSearchResult {\n matches: GraphSearchHit[];\n source: GraphBackendSource;\n}\n\nexport interface GraphBackend {\n readonly source: GraphBackendSource;\n search(query: string, opts?: { limit?: number }): Promise<GraphSearchResult>;\n impact(symbol: string, opts?: { depth?: number }): Promise<GraphImpactResult | null>;\n}\n\n/** Pure in-process backend over a loaded graph. */\nexport function localGraphBackend(graph: VgGraph): GraphBackend {\n return {\n source: 'local',\n async search(query, opts) {\n const res = queryGraph(graph, query, { budget: 1500, limit: opts?.limit ?? 10 });\n return {\n source: 'local',\n matches: res.matches.map((m) => ({\n id: m.node.id,\n qualifiedName: m.node.qualifiedName,\n kind: m.node.kind,\n file: m.node.file,\n line: m.node.span?.start ?? 0,\n score: m.score,\n why: m.why,\n signature: m.node.signature ?? null,\n })),\n };\n },\n async impact(symbol, opts) {\n const node = resolveSymbolId(graph, symbol);\n if (!node) return null;\n const imp = impactOf(graph, node, { depth: opts?.depth ?? 4 });\n return {\n source: 'local',\n root: imp.root,\n depth: imp.depth,\n affected: imp.affected.map((a) => ({\n id: a.id,\n name: a.name,\n kind: a.kind,\n file: a.file,\n line: a.line,\n depth: a.depth,\n confidence: a.confidence,\n })),\n direct: imp.direct,\n transitive: imp.transitive,\n };\n },\n };\n}\n\nexport interface VgdGraphBackendOptions {\n repositoryId: string;\n gitRef?: string;\n socketPath?: string;\n /** Always required for fall back when vgd has no slot or is down. */\n fallback: VgGraph;\n request?: (req: VgdRequest, opts?: VgdClientOptions) => Promise<unknown>;\n}\n\n/**\n * Prefer vgd query/impact; on any failure or empty daemon state, use local.\n * The returned `source` reflects which path answered.\n */\nexport function vgdGraphBackend(options: VgdGraphBackendOptions): GraphBackend {\n const local = localGraphBackend(options.fallback);\n const request = options.request ?? ((req, opts) => vgdRequest(req, opts));\n const clientOpts: VgdClientOptions = { socketPath: options.socketPath };\n\n return {\n source: 'vgd',\n async search(query, opts) {\n try {\n const res = (await request(\n {\n op: 'query-graph',\n repositoryId: options.repositoryId,\n query,\n limit: opts?.limit ?? 10,\n gitRef: options.gitRef,\n },\n clientOpts,\n )) as {\n ok?: boolean;\n matches?: Array<{\n id: string;\n qualifiedName: string;\n kind: string;\n file: string;\n line: number;\n score: number;\n why: string;\n }>;\n };\n if (res?.ok && Array.isArray(res.matches)) {\n return {\n source: 'vgd',\n matches: res.matches.map((m) => ({\n id: m.id,\n qualifiedName: m.qualifiedName,\n kind: m.kind,\n file: m.file,\n line: m.line,\n score: m.score,\n why: m.why,\n signature: null,\n })),\n };\n }\n } catch {\n /* fall through */\n }\n return local.search(query, opts);\n },\n async impact(symbol, opts) {\n try {\n const res = (await request(\n {\n op: 'impact-of',\n repositoryId: options.repositoryId,\n symbol,\n depth: opts?.depth ?? 4,\n gitRef: options.gitRef,\n },\n clientOpts,\n )) as {\n ok?: boolean;\n root?: { id: string; name: string };\n depth?: number;\n affected?: GraphImpactHit[];\n direct?: number;\n transitive?: number;\n };\n if (res?.ok && res.root && Array.isArray(res.affected)) {\n return {\n source: 'vgd',\n root: res.root,\n depth: res.depth ?? opts?.depth ?? 4,\n affected: res.affected,\n direct: res.direct ?? 0,\n transitive: res.transitive ?? 0,\n };\n }\n } catch {\n /* fall through */\n }\n return local.impact(symbol, opts);\n },\n };\n}\n\n/**\n * Pick a backend: vgd when repositoryId + socket are known, else local.\n */\nexport function resolveGraphBackend(input: {\n graph: VgGraph;\n repositoryId?: string | null;\n gitRef?: string | null;\n socketPath?: string | null;\n}): GraphBackend {\n if (input.repositoryId && input.socketPath) {\n return vgdGraphBackend({\n repositoryId: input.repositoryId,\n gitRef: input.gitRef ?? undefined,\n socketPath: input.socketPath,\n fallback: input.graph,\n });\n }\n return localGraphBackend(input.graph);\n}\n\nfunction resolveSymbolId(graph: VgGraph, symbol: string): string | null {\n if (graph.nodes.some((n) => n.id === symbol)) return symbol;\n const hit = resolveOne(graph, symbol);\n if (hit.node?.id) return hit.node.id;\n if (hit.candidates.length === 1 && hit.candidates[0]?.id) return hit.candidates[0].id;\n const q = symbol.toLowerCase();\n const byQn = graph.nodes.find((n) => n.qualifiedName?.toLowerCase() === q || n.name?.toLowerCase() === q);\n return byQn?.id ?? null;\n}\n"]}
1
+ {"version":3,"sources":["../src/code/graph-backend.ts"],"names":[],"mappings":"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","file":"chunk-TM5XQY3L.js","sourcesContent":["/**\n * Graph query backend for the agent tool layer (Fusion Runtime).\n *\n * Tools prefer a warm ActiveGraph in vgd when a daemon session is attached;\n * otherwise they fall back to the in-process {@link VgGraph}. Failures never\n * surface to the model as transport errors — they degrade to local query.\n */\n\nimport { queryGraph } from '../engine/query.js';\nimport { impactOf } from '../engine/impact.js';\nimport { resolveOne } from '../engine/lookup.js';\nimport { vgdRequest, type VgdClientOptions } from '../runtime/vgd/client.js';\nimport type { VgdRequest } from '../runtime/vgd/protocol.js';\nimport type { VgGraph } from '../schema.js';\n\nexport type GraphBackendSource = 'local' | 'vgd';\n\nexport interface GraphSearchHit {\n id: string;\n qualifiedName: string;\n kind: string;\n file: string;\n line: number;\n score: number;\n why: string;\n signature?: string | null;\n}\n\nexport interface GraphImpactHit {\n id: string;\n name: string;\n kind: string;\n file: string;\n line: number;\n depth: number;\n confidence: number;\n}\n\nexport interface GraphImpactResult {\n root: { id: string; name: string };\n depth: number;\n affected: GraphImpactHit[];\n direct: number;\n transitive: number;\n source: GraphBackendSource;\n}\n\nexport interface GraphSearchResult {\n matches: GraphSearchHit[];\n source: GraphBackendSource;\n}\n\nexport interface GraphBackend {\n readonly source: GraphBackendSource;\n search(query: string, opts?: { limit?: number }): Promise<GraphSearchResult>;\n impact(symbol: string, opts?: { depth?: number }): Promise<GraphImpactResult | null>;\n}\n\n/** Pure in-process backend over a loaded graph. */\nexport function localGraphBackend(graph: VgGraph): GraphBackend {\n return {\n source: 'local',\n async search(query, opts) {\n const res = queryGraph(graph, query, { budget: 1500, limit: opts?.limit ?? 10 });\n return {\n source: 'local',\n matches: res.matches.map((m) => ({\n id: m.node.id,\n qualifiedName: m.node.qualifiedName,\n kind: m.node.kind,\n file: m.node.file,\n line: m.node.span?.start ?? 0,\n score: m.score,\n why: m.why,\n signature: m.node.signature ?? null,\n })),\n };\n },\n async impact(symbol, opts) {\n const node = resolveSymbolId(graph, symbol);\n if (!node) return null;\n const imp = impactOf(graph, node, { depth: opts?.depth ?? 4 });\n return {\n source: 'local',\n root: imp.root,\n depth: imp.depth,\n affected: imp.affected.map((a) => ({\n id: a.id,\n name: a.name,\n kind: a.kind,\n file: a.file,\n line: a.line,\n depth: a.depth,\n confidence: a.confidence,\n })),\n direct: imp.direct,\n transitive: imp.transitive,\n };\n },\n };\n}\n\nexport interface VgdGraphBackendOptions {\n repositoryId: string;\n gitRef?: string;\n socketPath?: string;\n /** Always required for fall back when vgd has no slot or is down. */\n fallback: VgGraph;\n request?: (req: VgdRequest, opts?: VgdClientOptions) => Promise<unknown>;\n}\n\n/**\n * Prefer vgd query/impact; on any failure or empty daemon state, use local.\n * The returned `source` reflects which path answered.\n */\nexport function vgdGraphBackend(options: VgdGraphBackendOptions): GraphBackend {\n const local = localGraphBackend(options.fallback);\n const request = options.request ?? ((req, opts) => vgdRequest(req, opts));\n const clientOpts: VgdClientOptions = { socketPath: options.socketPath };\n\n return {\n source: 'vgd',\n async search(query, opts) {\n try {\n const res = (await request(\n {\n op: 'query-graph',\n repositoryId: options.repositoryId,\n query,\n limit: opts?.limit ?? 10,\n gitRef: options.gitRef,\n },\n clientOpts,\n )) as {\n ok?: boolean;\n matches?: Array<{\n id: string;\n qualifiedName: string;\n kind: string;\n file: string;\n line: number;\n score: number;\n why: string;\n }>;\n };\n if (res?.ok && Array.isArray(res.matches)) {\n return {\n source: 'vgd',\n matches: res.matches.map((m) => ({\n id: m.id,\n qualifiedName: m.qualifiedName,\n kind: m.kind,\n file: m.file,\n line: m.line,\n score: m.score,\n why: m.why,\n signature: null,\n })),\n };\n }\n } catch {\n /* fall through */\n }\n return local.search(query, opts);\n },\n async impact(symbol, opts) {\n try {\n const res = (await request(\n {\n op: 'impact-of',\n repositoryId: options.repositoryId,\n symbol,\n depth: opts?.depth ?? 4,\n gitRef: options.gitRef,\n },\n clientOpts,\n )) as {\n ok?: boolean;\n root?: { id: string; name: string };\n depth?: number;\n affected?: GraphImpactHit[];\n direct?: number;\n transitive?: number;\n };\n if (res?.ok && res.root && Array.isArray(res.affected)) {\n return {\n source: 'vgd',\n root: res.root,\n depth: res.depth ?? opts?.depth ?? 4,\n affected: res.affected,\n direct: res.direct ?? 0,\n transitive: res.transitive ?? 0,\n };\n }\n } catch {\n /* fall through */\n }\n return local.impact(symbol, opts);\n },\n };\n}\n\n/**\n * Pick a backend: vgd when repositoryId + socket are known, else local.\n */\nexport function resolveGraphBackend(input: {\n graph: VgGraph;\n repositoryId?: string | null;\n gitRef?: string | null;\n socketPath?: string | null;\n}): GraphBackend {\n if (input.repositoryId && input.socketPath) {\n return vgdGraphBackend({\n repositoryId: input.repositoryId,\n gitRef: input.gitRef ?? undefined,\n socketPath: input.socketPath,\n fallback: input.graph,\n });\n }\n return localGraphBackend(input.graph);\n}\n\nfunction resolveSymbolId(graph: VgGraph, symbol: string): string | null {\n if (graph.nodes.some((n) => n.id === symbol)) return symbol;\n const hit = resolveOne(graph, symbol);\n if (hit.node?.id) return hit.node.id;\n if (hit.candidates.length === 1 && hit.candidates[0]?.id) return hit.candidates[0].id;\n const q = symbol.toLowerCase();\n const byQn = graph.nodes.find((n) => n.qualifiedName?.toLowerCase() === q || n.name?.toLowerCase() === q);\n return byQn?.id ?? null;\n}\n"]}
@@ -1,13 +1,13 @@
1
- import { FREE_PACK, navigationToolsetConfig, deferredToolNames, HOT_TOOLS } from './chunk-SNKTD23L.js';
1
+ import { FREE_PACK, navigationToolsetConfig, deferredToolNames, HOT_TOOLS } from './chunk-M452MRWI.js';
2
2
  import { edgeId, buildModuleResolver, resolve, applyStaticTestLinkage, nodeId } from './chunk-VIWZ4QT7.js';
3
3
  import { init_cli_invocation, whichOnPath, isInstalledOwnBinary } from './chunk-3LSG7Z4I.js';
4
- import { indexFor } from './chunk-5VH3Y4QC.js';
4
+ import { indexFor } from './chunk-HC44772H.js';
5
5
  import { langById, grammarSetVersion, langForExtension, setGrammarsOverride, parseSource } from './chunk-UTNNGKKX.js';
6
6
  import { redactSecrets } from './chunk-RXP66R2E.js';
7
- import { writeGraphIndex, SCHEMA_VERSION, loadGraph } from './chunk-DIU3MXB3.js';
8
- import { ensureVibgrateGitignore } from './chunk-N4IDP2M2.js';
9
- import { VERSION } from './chunk-QT2PMGN3.js';
10
- import { loadCache, serializeGraph, cacheDir, stableStringify } from './chunk-AJ2KE3NT.js';
7
+ import { writeGraphIndex, SCHEMA_VERSION, loadGraph } from './chunk-CPLG4GFB.js';
8
+ import { ensureVibgrateGitignore } from './chunk-3Q3ZXJZP.js';
9
+ import { VERSION } from './chunk-7KNFG44U.js';
10
+ import { loadCache, serializeGraph, cacheDir, stableStringify } from './chunk-QMME6TB4.js';
11
11
  import { shortId, canonicalize, hashString, hashBytes } from './chunk-JFGYT6BI.js';
12
12
  import * as fs11 from 'fs';
13
13
  import * as path11 from 'path';
@@ -3205,5 +3205,5 @@ function escapeRe(s) {
3205
3205
  }
3206
3206
 
3207
3207
  export { ASSISTANTS, CliError, ExitCode, ResourceLimitError, SKIP_DIRS, SKIP_FILES, SMALL_REPO_FILES, UsageError, analyze, applyCoverage, assistantById, buildFacts, buildGraph, decodeScipIndex, detectAssistants, detectServeLaunch, discover, driftCount, epistemicBreakdown, groundGraph, hasDrift, installAssistant, isAssistantInstalled, isSkippedDirName, loadCoverage, loadSnapshot, probeFreshness, refreshInstalledInstructions, resolveLimits, scipEdges, uninstallAssistant, usageError, verifyDeterminism, versionMarker, writeNavigationConfig, writeSnapshot };
3208
- //# sourceMappingURL=chunk-FKFRASAB.js.map
3209
- //# sourceMappingURL=chunk-FKFRASAB.js.map
3208
+ //# sourceMappingURL=chunk-TNADGCOX.js.map
3209
+ //# sourceMappingURL=chunk-TNADGCOX.js.map