@vibgrate/cli 2026.806.1 → 2026.807.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/DOCS.md +3 -1
  2. package/dist/{agent-SBVWSP7G.js → agent-K3J6EHLI.js} +11 -11
  3. package/dist/{agent-SBVWSP7G.js.map → agent-K3J6EHLI.js.map} +1 -1
  4. package/dist/{baseline-NM53X2TB.js → baseline-IAFWF2ET.js} +3 -3
  5. package/dist/{baseline-NM53X2TB.js.map → baseline-IAFWF2ET.js.map} +1 -1
  6. package/dist/{chunk-ITGUM42X.js → chunk-2HAJCW7Z.js} +4 -4
  7. package/dist/{chunk-ITGUM42X.js.map → chunk-2HAJCW7Z.js.map} +1 -1
  8. package/dist/{chunk-SMDHK37H.js → chunk-2M6B5V2U.js} +3 -3
  9. package/dist/{chunk-SMDHK37H.js.map → chunk-2M6B5V2U.js.map} +1 -1
  10. package/dist/{chunk-5AUCYYBG.js → chunk-5ESL76CM.js} +6 -6
  11. package/dist/{chunk-5AUCYYBG.js.map → chunk-5ESL76CM.js.map} +1 -1
  12. package/dist/{chunk-Y6AMGI4L.js → chunk-7CYFCSY2.js} +4 -4
  13. package/dist/{chunk-Y6AMGI4L.js.map → chunk-7CYFCSY2.js.map} +1 -1
  14. package/dist/{chunk-BOAUTBTB.js → chunk-ADP6ITGF.js} +53 -8
  15. package/dist/chunk-ADP6ITGF.js.map +1 -0
  16. package/dist/{chunk-6XP2TQS5.js → chunk-EJUMV5HU.js} +3 -3
  17. package/dist/{chunk-6XP2TQS5.js.map → chunk-EJUMV5HU.js.map} +1 -1
  18. package/dist/{chunk-LFHXJHOZ.js → chunk-EXOYSXH6.js} +3 -3
  19. package/dist/{chunk-LFHXJHOZ.js.map → chunk-EXOYSXH6.js.map} +1 -1
  20. package/dist/{chunk-TWZLUOTR.js → chunk-FOKURZL3.js} +4 -4
  21. package/dist/{chunk-TWZLUOTR.js.map → chunk-FOKURZL3.js.map} +1 -1
  22. package/dist/{chunk-H4ZIJSHE.js → chunk-G4KO5W6H.js} +65 -9
  23. package/dist/chunk-G4KO5W6H.js.map +1 -0
  24. package/dist/{chunk-N6LGZBIC.js → chunk-GQ2EQXBG.js} +5 -5
  25. package/dist/{chunk-N6LGZBIC.js.map → chunk-GQ2EQXBG.js.map} +1 -1
  26. package/dist/chunk-ITY2NPIQ.js +6 -0
  27. package/dist/{chunk-3Z6TDWNS.js.map → chunk-ITY2NPIQ.js.map} +1 -1
  28. package/dist/{chunk-A42UDYL2.js → chunk-JFCCJWXD.js} +3 -3
  29. package/dist/{chunk-A42UDYL2.js.map → chunk-JFCCJWXD.js.map} +1 -1
  30. package/dist/{chunk-SAHORNZX.js → chunk-KEIMMCS5.js} +4 -4
  31. package/dist/{chunk-SAHORNZX.js.map → chunk-KEIMMCS5.js.map} +1 -1
  32. package/dist/{chunk-AN7RCXE4.js → chunk-LS7GZBKP.js} +32 -12
  33. package/dist/chunk-LS7GZBKP.js.map +1 -0
  34. package/dist/{chunk-OGJ633I2.js → chunk-N5EP5ZR2.js} +35 -17
  35. package/dist/{chunk-OGJ633I2.js.map → chunk-N5EP5ZR2.js.map} +1 -1
  36. package/dist/{chunk-KACPLPFT.js → chunk-NWX4VUFS.js} +7 -7
  37. package/dist/{chunk-KACPLPFT.js.map → chunk-NWX4VUFS.js.map} +1 -1
  38. package/dist/{chunk-OKJTAHOL.js → chunk-PT2XQTSK.js} +5 -5
  39. package/dist/{chunk-OKJTAHOL.js.map → chunk-PT2XQTSK.js.map} +1 -1
  40. package/dist/{chunk-VJIRJLV2.js → chunk-QXIWQ2WG.js} +4 -4
  41. package/dist/{chunk-VJIRJLV2.js.map → chunk-QXIWQ2WG.js.map} +1 -1
  42. package/dist/{chunk-VP5ECB7T.js → chunk-VNAOFA6X.js} +8 -8
  43. package/dist/{chunk-VP5ECB7T.js.map → chunk-VNAOFA6X.js.map} +1 -1
  44. package/dist/{chunk-VKVGREHC.js → chunk-VQVLY63G.js} +1326 -61
  45. package/dist/chunk-VQVLY63G.js.map +1 -0
  46. package/dist/{chunk-K3KEKY2L.js → chunk-XSHGXGVJ.js} +4 -4
  47. package/dist/{chunk-K3KEKY2L.js.map → chunk-XSHGXGVJ.js.map} +1 -1
  48. package/dist/{chunk-KUZLILN3.js → chunk-Z7FM3ETS.js} +18 -4
  49. package/dist/chunk-Z7FM3ETS.js.map +1 -0
  50. package/dist/cli.js +95 -53
  51. package/dist/cli.js.map +1 -1
  52. package/dist/embed-worker-main.js +3 -3
  53. package/dist/{ensure-map-JICVC2ZJ.js → ensure-map-TYMYYIJE.js} +12 -12
  54. package/dist/{ensure-map-JICVC2ZJ.js.map → ensure-map-TYMYYIJE.js.map} +1 -1
  55. package/dist/graph-backend-5YOWNHHG.js +13 -0
  56. package/dist/{graph-backend-TB35N5MC.js.map → graph-backend-5YOWNHHG.js.map} +1 -1
  57. package/dist/index.d.ts +10 -3
  58. package/dist/index.js +11 -11
  59. package/dist/{interactive-IJS33F4K.js → interactive-YEMXHGBO.js} +25 -23
  60. package/dist/interactive-YEMXHGBO.js.map +1 -0
  61. package/dist/load-IIWVYUN7.js +9 -0
  62. package/dist/{load-OMTSGVDX.js.map → load-IIWVYUN7.js.map} +1 -1
  63. package/dist/{run-outcome-UENLWBWC.js → run-outcome-2JO55QCC.js} +5 -5
  64. package/dist/{run-outcome-UENLWBWC.js.map → run-outcome-2JO55QCC.js.map} +1 -1
  65. package/dist/runtime-session-HFKGKQV7.js +20 -0
  66. package/dist/{runtime-session-AFL7P4TQ.js.map → runtime-session-HFKGKQV7.js.map} +1 -1
  67. package/dist/session-5LFX4U2E.js +15 -0
  68. package/dist/{session-HOS4454T.js.map → session-5LFX4U2E.js.map} +1 -1
  69. package/dist/session-store-KGONLWHN.js +4 -0
  70. package/dist/{session-store-F7NX7SZN.js.map → session-store-KGONLWHN.js.map} +1 -1
  71. package/dist/{stream-json-SVMGVBFB.js → stream-json-DUCFTBUF.js} +11 -11
  72. package/dist/{stream-json-SVMGVBFB.js.map → stream-json-DUCFTBUF.js.map} +1 -1
  73. package/dist/{vg-mcp-bridge-NYCAQEMU.js → vg-mcp-bridge-4KPDQUFN.js} +8 -8
  74. package/dist/{vg-mcp-bridge-NYCAQEMU.js.map → vg-mcp-bridge-4KPDQUFN.js.map} +1 -1
  75. package/dist/{vgd-YFPJHQB5.js → vgd-LFHQ4GWC.js} +8 -8
  76. package/dist/vgd-LFHQ4GWC.js.map +1 -0
  77. package/package.json +3 -3
  78. package/dist/chunk-3Z6TDWNS.js +0 -6
  79. package/dist/chunk-AN7RCXE4.js.map +0 -1
  80. package/dist/chunk-BOAUTBTB.js.map +0 -1
  81. package/dist/chunk-H4ZIJSHE.js.map +0 -1
  82. package/dist/chunk-KUZLILN3.js.map +0 -1
  83. package/dist/chunk-VKVGREHC.js.map +0 -1
  84. package/dist/graph-backend-TB35N5MC.js +0 -13
  85. package/dist/interactive-IJS33F4K.js.map +0 -1
  86. package/dist/load-OMTSGVDX.js +0 -9
  87. package/dist/runtime-session-AFL7P4TQ.js +0 -20
  88. package/dist/session-HOS4454T.js +0 -15
  89. package/dist/session-store-F7NX7SZN.js +0 -4
  90. package/dist/vgd-YFPJHQB5.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { resolveIngestHost } from './chunk-HTLDXEHW.js';
2
- import { cacheDir } from './chunk-SMDHK37H.js';
3
- import { VERSION } from './chunk-3Z6TDWNS.js';
2
+ import { cacheDir } from './chunk-2M6B5V2U.js';
3
+ import { VERSION } from './chunk-ITY2NPIQ.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-K3KEKY2L.js.map
216
- //# sourceMappingURL=chunk-K3KEKY2L.js.map
215
+ //# sourceMappingURL=chunk-XSHGXGVJ.js.map
216
+ //# sourceMappingURL=chunk-XSHGXGVJ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/engine/stats-share.ts"],"names":[],"mappings":"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","file":"chunk-K3KEKY2L.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-XSHGXGVJ.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"]}
@@ -75,9 +75,21 @@ function setLatestSession(root, id) {
75
75
  return false;
76
76
  }
77
77
  }
78
+ var MAX_INSTRUCTION_CHARS = 32e3;
79
+ var MAX_SUMMARY_CHARS = 2e5;
80
+ function recapSnippet(text, max) {
81
+ const s = String(text || "").replace(/\s+/g, " ").trim();
82
+ if (s.length <= max) return s;
83
+ return s.slice(0, Math.max(0, max - 1)) + "\u2026";
84
+ }
78
85
  function summarizeSession(session) {
79
86
  if (session.tasks.length === 0) return "";
80
- const lines = session.tasks.slice(-8).map((t, i) => `${i + 1}. ${t.instruction} \u2014 ${t.summary}${t.files.length ? ` (${t.files.join(", ")})` : ""}`);
87
+ const lines = session.tasks.slice(-8).map((t, i) => {
88
+ const instr = recapSnippet(t.instruction, 120);
89
+ const sum = recapSnippet(t.summary, 200);
90
+ const files = t.files.length ? ` (${t.files.join(", ")})` : "";
91
+ return `${i + 1}. ${instr} \u2014 ${sum}${files}`;
92
+ });
81
93
  return `Earlier in this session (${session.provider}/${session.model}) you did:
82
94
  ${lines.join("\n")}`;
83
95
  }
@@ -99,14 +111,16 @@ function condenseSession(session, now) {
99
111
  }
100
112
  function recordTask(session, task, now) {
101
113
  const files = [...new Set(task.changes.map((c) => c.file))];
114
+ const instruction = String(task.instruction ?? "").slice(0, MAX_INSTRUCTION_CHARS);
115
+ const summary = String(task.summary ?? "").slice(0, MAX_SUMMARY_CHARS);
102
116
  return {
103
117
  ...session,
104
118
  updatedAt: now,
105
- tasks: [...session.tasks, { instruction: task.instruction.slice(0, 300), summary: task.summary.slice(0, 300), files, stopped: task.stopped, ts: now }],
119
+ tasks: [...session.tasks, { instruction, summary, files, stopped: task.stopped, ts: now }],
106
120
  lastChanges: task.changes.length ? task.changes : session.lastChanges
107
121
  };
108
122
  }
109
123
 
110
124
  export { condenseSession, listSessions, loadLatestSession, loadSession, newSession, recordTask, saveSession, sessionsDir, setLatestSession, summarizeSession };
111
- //# sourceMappingURL=chunk-KUZLILN3.js.map
112
- //# sourceMappingURL=chunk-KUZLILN3.js.map
125
+ //# sourceMappingURL=chunk-Z7FM3ETS.js.map
126
+ //# sourceMappingURL=chunk-Z7FM3ETS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/code/session-store.ts"],"names":[],"mappings":"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","file":"chunk-Z7FM3ETS.js","sourcesContent":["/**\n * Session persistence for VG Code (VG-CLI-CODE §16) — `vg code --continue`.\n *\n * A coding session is a series of tasks; this stores each turn's instruction and\n * final answer (plus which files changed) and the last change-set so `/undo`\n * survives a restart. History → pick reloads those turns into the panel so the\n * user can re-read the full thread. `--continue` reloads the most recent session\n * and seeds the model with a *short recap* of prior turns (see\n * {@link summarizeSession}) — never raw file bodies or tool transcripts.\n *\n * Pure over an injected clock; the store is JSON under `.vibgrate/code-sessions/`.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { FileChange } from './types.js';\n\nexport interface SessionTask {\n instruction: string;\n summary: string;\n files: string[];\n stopped: string;\n ts: number;\n}\n\nexport interface StoredSession {\n id: string;\n provider: string;\n model: string;\n startedAt: number;\n updatedAt: number;\n tasks: SessionTask[];\n /** The most recent change-set, so `/undo` works after `--continue`. */\n lastChanges: FileChange[];\n}\n\nexport function sessionsDir(root: string): string {\n return path.join(root, '.vibgrate', 'code-sessions');\n}\nfunction latestPointer(root: string): string {\n return path.join(sessionsDir(root), 'latest.json');\n}\n\n/** Write a session and update the `latest` pointer. Best-effort; never throws. */\nexport function saveSession(root: string, session: StoredSession): void {\n try {\n const dir = sessionsDir(root);\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(path.join(dir, `${session.id}.json`), JSON.stringify(session, null, 2));\n fs.writeFileSync(latestPointer(root), JSON.stringify({ id: session.id }));\n } catch {\n /* persistence is best-effort */\n }\n}\n\n/** Load the most recent session, or undefined if none/there was a read error. */\nexport function loadLatestSession(root: string): StoredSession | undefined {\n try {\n const { id } = JSON.parse(fs.readFileSync(latestPointer(root), 'utf8')) as { id: string };\n return loadSession(root, id);\n } catch {\n /* no session */\n }\n return undefined;\n}\n\n/** Load one session by id, or undefined if missing/invalid. */\nexport function loadSession(root: string, id: string): StoredSession | undefined {\n try {\n const safe = id.replace(/[^a-zA-Z0-9_-]/g, '');\n if (!safe || safe !== id) return undefined;\n const raw = JSON.parse(fs.readFileSync(path.join(sessionsDir(root), `${safe}.json`), 'utf8')) as StoredSession;\n if (Array.isArray(raw.tasks) && raw.id) return raw;\n } catch {\n /* missing */\n }\n return undefined;\n}\n\nexport interface SessionListEntry {\n id: string;\n provider: string;\n model: string;\n startedAt: number;\n updatedAt: number;\n taskCount: number;\n /** First task instruction (truncated) for history UI. */\n title: string;\n}\n\n/** List stored sessions newest-first (multi-chat history). Best-effort. */\nexport function listSessions(root: string, limit = 50): SessionListEntry[] {\n try {\n const dir = sessionsDir(root);\n if (!fs.existsSync(dir)) return [];\n const files = fs.readdirSync(dir).filter((f) => f.endsWith('.json') && f !== 'latest.json');\n const out: SessionListEntry[] = [];\n for (const f of files) {\n try {\n const raw = JSON.parse(fs.readFileSync(path.join(dir, f), 'utf8')) as StoredSession;\n if (!raw?.id || !Array.isArray(raw.tasks)) continue;\n const first = raw.tasks[0]?.instruction?.trim() || 'New chat';\n out.push({\n id: raw.id,\n provider: raw.provider ?? '',\n model: raw.model ?? '',\n startedAt: raw.startedAt ?? 0,\n updatedAt: raw.updatedAt ?? raw.startedAt ?? 0,\n taskCount: raw.tasks.length,\n title: first.slice(0, 80),\n });\n } catch {\n /* skip bad file */\n }\n }\n out.sort((a, b) => b.updatedAt - a.updatedAt);\n return out.slice(0, Math.max(1, limit));\n } catch {\n return [];\n }\n}\n\n/** Point `latest` at an existing session (resume a prior chat). */\nexport function setLatestSession(root: string, id: string): boolean {\n const s = loadSession(root, id);\n if (!s) return false;\n try {\n fs.mkdirSync(sessionsDir(root), { recursive: true });\n fs.writeFileSync(latestPointer(root), JSON.stringify({ id: s.id }));\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Cap stored fields so a runaway answer cannot fill the disk, while still\n * keeping enough of each prompt/answer for History → reload to repaint the\n * full panel transcript (the old 300-char cap cut answers mid-sentence).\n */\nconst MAX_INSTRUCTION_CHARS = 32_000;\nconst MAX_SUMMARY_CHARS = 200_000;\n\n/** Truncate for model recaps only — disk storage keeps the longer form. */\nfunction recapSnippet(text: string, max: number): string {\n const s = String(text || '').replace(/\\s+/g, ' ').trim();\n if (s.length <= max) return s;\n return s.slice(0, Math.max(0, max - 1)) + '…';\n}\n\n/** A short natural-language recap of a session to seed a continued run's context. */\nexport function summarizeSession(session: StoredSession): string {\n if (session.tasks.length === 0) return '';\n const lines = session.tasks.slice(-8).map((t, i) => {\n const instr = recapSnippet(t.instruction, 120);\n const sum = recapSnippet(t.summary, 200);\n const files = t.files.length ? ` (${t.files.join(', ')})` : '';\n return `${i + 1}. ${instr} — ${sum}${files}`;\n });\n return `Earlier in this session (${session.provider}/${session.model}) you did:\\n${lines.join('\\n')}`;\n}\n\n/** A fresh session record. `id` and `now` are injected so this stays deterministic. */\nexport function newSession(id: string, provider: string, model: string, now: number): StoredSession {\n return { id, provider, model, startedAt: now, updatedAt: now, tasks: [], lastChanges: [] };\n}\n\n/**\n * Manually compact a session: collapse all recorded tasks into a single\n * checkpoint entry so the recap seeded into future turns shrinks to one line\n * per prior task, capped. Deterministic (no model call) — the in-turn LLM\n * compaction handles rich summaries; this is the user-invoked `/compact`.\n */\nexport function condenseSession(session: StoredSession, now: number): StoredSession {\n if (session.tasks.length <= 1) return session;\n const files = [...new Set(session.tasks.flatMap((t) => t.files))];\n const lines = session.tasks\n .slice(-12)\n .map((t) => `${t.instruction.slice(0, 80)} — ${t.summary.slice(0, 80)}`);\n const checkpoint: SessionTask = {\n instruction: `(compacted: ${session.tasks.length} earlier task(s))`,\n summary: lines.join(' · ').slice(0, 1500),\n files,\n stopped: 'compacted',\n ts: now,\n };\n return { ...session, updatedAt: now, tasks: [checkpoint] };\n}\n\n/** Append a completed task (immutably updating the record's timestamps). */\nexport function recordTask(\n session: StoredSession,\n task: { instruction: string; summary: string; changes: FileChange[]; stopped: string },\n now: number,\n): StoredSession {\n const files = [...new Set(task.changes.map((c) => c.file))];\n const instruction = String(task.instruction ?? '').slice(0, MAX_INSTRUCTION_CHARS);\n const summary = String(task.summary ?? '').slice(0, MAX_SUMMARY_CHARS);\n return {\n ...session,\n updatedAt: now,\n tasks: [...session.tasks, { instruction, summary, files, stopped: task.stopped, ts: now }],\n lastChanges: task.changes.length ? task.changes : session.lastChanges,\n };\n}\n"]}
package/dist/cli.js CHANGED
@@ -1,37 +1,37 @@
1
1
  #!/usr/bin/env node
2
2
  import { loadAdvancedScanHook, baselineCommand } from './chunk-Y4JO6LYP.js';
3
- import { fetchCatalog, resolveProviders } from './chunk-OGJ633I2.js';
4
- import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-ITGUM42X.js';
3
+ import { fetchCatalog, resolveProviders } from './chunk-N5EP5ZR2.js';
4
+ import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-2HAJCW7Z.js';
5
5
  import './chunk-IS7VTH2Q.js';
6
- import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-K3KEKY2L.js';
7
- import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-VKVGREHC.js';
6
+ import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-XSHGXGVJ.js';
7
+ import { runCodeSession } from './chunk-PT2XQTSK.js';
8
+ import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-VQVLY63G.js';
8
9
  import './chunk-543E6WDJ.js';
10
+ import { summarizeDiffs, ScriptedProvider } from './chunk-ADP6ITGF.js';
9
11
  import './chunk-7AVYKZEM.js';
10
12
  import { buildModelInstallPlan } from './chunk-WHJMS7XC.js';
11
- import { runCodeSession } from './chunk-OKJTAHOL.js';
12
- import { summarizeDiffs, ScriptedProvider } from './chunk-BOAUTBTB.js';
13
13
  import { ensurePackage, ensureUnavailableMessage } from './chunk-REIGWTTH.js';
14
- import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, runBuild } from './chunk-KACPLPFT.js';
15
- export { runBuild } from './chunk-KACPLPFT.js';
14
+ import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, runBuild } from './chunk-NWX4VUFS.js';
15
+ export { runBuild } from './chunk-NWX4VUFS.js';
16
16
  import { disableColor, info, c, json, out } from './chunk-CT5BS56U.js';
17
17
  import { init_resolve_ollama, gatherSystemMemory, resolveOllamaBinary, hasOllamaBinary, resolve_ollama_exports } from './chunk-OWSFZQOP.js';
18
18
  import { readOrchestratorState, writeOrchestratorState, parseMode, setDefaultMode, recommendMode, activePin, resolveMode, providerForBackend, QUALIFIED_PACKS, pinPack, unpinPack, buildOrchestratorStatus } from './chunk-NZELMYT4.js';
19
19
  import { fmt, estimateModelBytes } from './chunk-7N4Y3E47.js';
20
20
  import './chunk-IZDH67DX.js';
21
- import './chunk-LFHXJHOZ.js';
21
+ import './chunk-EXOYSXH6.js';
22
22
  import { vgdSocketPath, vgdIsRunning, vgdRequest, vgdPidPath } from './chunk-RBIRXQR6.js';
23
23
  import { defaultProcessEndpoint, startProcessHostServer, resolveInferenceIsolation } from './chunk-JFE7XCAE.js';
24
24
  import { clearHostSessionPool, acquireHostSession, generateOnSession, listHostSessions, hostSessionPoolSize } from './chunk-3LOWJSAF.js';
25
25
  import { buildIdentifierTrieFromGraph } from './chunk-5HYCB55P.js';
26
- import { serveStdio, isRelevantChange, exportGraph, GraphSource, createServer, formatForExt, RefreshScheduler } from './chunk-VP5ECB7T.js';
27
- import { refreshIfStale } from './chunk-N6LGZBIC.js';
28
- import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-TWZLUOTR.js';
29
- import { CliError, ExitCode, driftCount, ASSISTANTS, detectAssistants, isAssistantInstalled, usageError, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, buildGraph, writeSnapshot, probeFreshness, discover, assistantById, SMALL_REPO_FILES, isSkippedDirName, SKIP_FILES, SKIP_DIRS } from './chunk-H4ZIJSHE.js';
30
- import { resolveDsn, createWorkspaceDsn, writeStoredCredentials, credentialsPath, findGitRoot, ensureGitignored, gitignoreEntryForCredentials, clearStoredCredentials, parseDsn as parseDsn$1, uploadScanArtifact, dsnCommand, pushCommand, countTokens, shortestPath, pathDisconnect, testsToRun, detectRunner, coveringTests, FREE_PACK, readScanArtifact, publishPrivateLibrary, assessDocQuality, symbolsFromApi, fetchHostedDocsCached, selectForBudget, hostedBase, readStoredCredentials, projectCredentialsPath, homeCredentialsPath } from './chunk-5AUCYYBG.js';
26
+ import { serveStdio, isRelevantChange, exportGraph, GraphSource, createServer, formatForExt, RefreshScheduler } from './chunk-VNAOFA6X.js';
27
+ import { refreshIfStale } from './chunk-GQ2EQXBG.js';
28
+ import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-FOKURZL3.js';
29
+ import { CliError, ExitCode, driftCount, ASSISTANTS, detectAssistants, isAssistantInstalled, usageError, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, buildGraph, writeSnapshot, probeFreshness, discover, assistantById, SMALL_REPO_FILES, isSkippedDirName, SKIP_FILES, SKIP_DIRS } from './chunk-G4KO5W6H.js';
30
+ import { resolveDsn, createWorkspaceDsn, writeStoredCredentials, credentialsPath, findGitRoot, ensureGitignored, gitignoreEntryForCredentials, clearStoredCredentials, parseDsn as parseDsn$1, uploadScanArtifact, dsnCommand, pushCommand, countTokens, shortestPath, pathDisconnect, testsToRun, detectRunner, coveringTests, FREE_PACK, readScanArtifact, publishPrivateLibrary, assessDocQuality, symbolsFromApi, fetchHostedDocsCached, selectForBudget, hostedBase, readStoredCredentials, projectCredentialsPath, homeCredentialsPath } from './chunk-5ESL76CM.js';
31
31
  import { writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, loadConfig, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, PROJECT_TYPE_TO_OSV_ECOSYSTEM, fetchRiskySymbols, perDependencyDrift } from './chunk-INIULQEP.js';
32
32
  import { resolveIngestHost, dashHostForIngestHost, availableRegionIds, ingestHostForRegionId } from './chunk-HTLDXEHW.js';
33
33
  import './chunk-VIWZ4QT7.js';
34
- import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-VJIRJLV2.js';
34
+ import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-QXIWQ2WG.js';
35
35
  import { discoverModels } from './chunk-CQDUBAQY.js';
36
36
  import { freeBytesOnVolume, weightStoreDir, listCachedWeights, ensureWeightCached, catalogIntegrityReport } from './chunk-OV4KGXPD.js';
37
37
  import './chunk-5I4VSBWQ.js';
@@ -39,13 +39,13 @@ import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-DT4KIV
39
39
  import { ensureDir, pathExists, readJsonFile, writeTextFile, writeJsonFile } from './chunk-CRAMOEBE.js';
40
40
  import { init_cli_invocation, resolveCliInvocation, NPX_INVOCATION } from './chunk-3LSG7Z4I.js';
41
41
  import { resolveOne } from './chunk-J7LKEB2R.js';
42
- import { queryGraphSemantic, queryGraph, indexFor, impactOf } from './chunk-Y6AMGI4L.js';
42
+ import { queryGraphSemantic, queryGraph, indexFor, impactOf } from './chunk-7CYFCSY2.js';
43
43
  import { resolvedGrammarFiles, grammarSetVersion } from './chunk-UTNNGKKX.js';
44
44
  import './chunk-RXP66R2E.js';
45
- import { embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, unavailableMessage, countPending, modelCacheInfo, embeddingsPath, clearModelCache, withTimeout } from './chunk-AN7RCXE4.js';
46
- import { loadGraph, loadGraphPreferIndex, SCHEMA_VERSION } from './chunk-A42UDYL2.js';
47
- import { cacheDir, resolveGraphPath, analyzeQuestion, loadTopicTags, renderReport, resetRelevanceProviderCache, loadRelevanceProvider, loadGraphFileWithSnapshot, serializeGraph, stableStringify, writeArtifacts, vibgrateDir, mapFileExists, relevanceModuleDir, parseGraph, ensureVibgrateGitignore } from './chunk-SMDHK37H.js';
48
- import { VERSION } from './chunk-3Z6TDWNS.js';
45
+ import { embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, unavailableMessage, countPending, modelCacheInfo, embeddingsPath, clearModelCache, withTimeout } from './chunk-LS7GZBKP.js';
46
+ import { loadGraph, loadGraphPreferIndex, SCHEMA_VERSION } from './chunk-JFCCJWXD.js';
47
+ import { cacheDir, resolveGraphPath, analyzeQuestion, loadTopicTags, renderReport, resetRelevanceProviderCache, loadRelevanceProvider, loadGraphFileWithSnapshot, serializeGraph, stableStringify, writeArtifacts, vibgrateDir, mapFileExists, relevanceModuleDir, parseGraph, ensureVibgrateGitignore } from './chunk-2M6B5V2U.js';
48
+ import { VERSION } from './chunk-ITY2NPIQ.js';
49
49
  import './chunk-BWPBB45M.js';
50
50
  import { canonicalize, hashString, hashBytes } from './chunk-JFGYT6BI.js';
51
51
  import './chunk-BPF3YX2U.js';
@@ -179,7 +179,14 @@ function registerAsk(program) {
179
179
  info(c.dim(" preparing semantic search (first use embeds the map; cached, resumable & offline after)\u2026"));
180
180
  }
181
181
  let reason;
182
- const embedder = await loadEmbedder({ local: global.local, onUnavailable: (r) => reason = r });
182
+ let detail;
183
+ const embedder = await loadEmbedder({
184
+ local: global.local,
185
+ onUnavailable: (r, d) => {
186
+ reason = r;
187
+ detail = d;
188
+ }
189
+ });
183
190
  if (embedder) {
184
191
  const bar = !global.json && firstRun ? new ProgressBar(c.dim("embedding")) : void 0;
185
192
  const vectors = await getNodeEmbeddings(graph, embedder, root2, bar ? (d, t) => bar.update(d, t) : void 0);
@@ -189,6 +196,7 @@ function registerAsk(program) {
189
196
  } else {
190
197
  result = queryGraph(graph, q, { budget, relevance, topicTags });
191
198
  note = reason ? unavailableMessage(reason) : "semantic unavailable; used lexical";
199
+ if (detail) note += ` (${detail})`;
192
200
  }
193
201
  } else {
194
202
  result = queryGraph(graph, q, { budget, relevance, topicTags });
@@ -260,14 +268,27 @@ function writeVerdict(dir, verdict) {
260
268
  } catch {
261
269
  }
262
270
  }
271
+ function probeModuleUrl(from = import.meta.url) {
272
+ const dir = path41.dirname(fileURLToPath(from));
273
+ for (const name of ["embeddings.js", "index.js"]) {
274
+ const candidate = path41.join(dir, name);
275
+ if (fs11.existsSync(candidate)) return pathToFileURL(candidate).href;
276
+ }
277
+ return pathToFileURL(path41.join(dir, "index.js")).href;
278
+ }
263
279
  function defaultRunProbe(timeoutMs) {
264
- const moduleUrl = new URL("./embeddings.js", import.meta.url).href;
280
+ const moduleUrl = probeModuleUrl();
265
281
  const script = `
266
282
  import(${JSON.stringify(moduleUrl)})
267
283
  .then(async (m) => {
284
+ if (typeof m.loadEmbedder !== 'function') {
285
+ process.stdout.write('{"ok":false}');
286
+ return;
287
+ }
268
288
  const e = await m.loadEmbedder({ noDownload: true });
269
289
  if (!e) { process.stdout.write('{"ok":false}'); return; }
270
290
  await e.embedQuery('probe');
291
+ await e.embed(['probe document']);
271
292
  process.stdout.write('{"ok":true}');
272
293
  })
273
294
  .catch(() => process.stdout.write('{"ok":false}'));
@@ -350,11 +371,12 @@ function registerEmbed(program) {
350
371
  const bg = opts.bg === true;
351
372
  const speak = !bg && !global.json;
352
373
  if (global.local) {
353
- if (speak) info(c.dim("vg embed \xB7 semantic is off (--local) \u2014 lexical search only"));
374
+ if (global.json) json({ embedded: 0, model: modelId, semantic: false, reason: "local" });
375
+ else if (speak) info(c.dim("vg embed \xB7 semantic is off (--local) \u2014 lexical search only"));
354
376
  return;
355
377
  }
356
378
  if (countPending(graph, root2, modelId) === 0) {
357
- if (global.json) json({ embedded: 0, pending: 0, upToDate: true, model: modelId });
379
+ if (global.json) json({ embedded: 0, pending: 0, upToDate: true, model: modelId, semantic: true });
358
380
  else if (speak) info(`${c.cyan("vg embed")} \xB7 semantic index already up to date`);
359
381
  return;
360
382
  }
@@ -365,6 +387,7 @@ function registerEmbed(program) {
365
387
  return;
366
388
  }
367
389
  let reason;
390
+ let detail;
368
391
  const embedder = await loadEmbedder({
369
392
  local: global.local,
370
393
  // Background warm-ups skip the download unless explicitly asked to fetch
@@ -372,17 +395,24 @@ function registerEmbed(program) {
372
395
  // time `vg serve`/`vg ask` needs it).
373
396
  noDownload: bg && opts.download !== true,
374
397
  showDownloadProgress: !bg,
375
- onUnavailable: (r) => reason = r
398
+ onUnavailable: (r, d) => {
399
+ reason = r;
400
+ detail = d;
401
+ }
376
402
  });
377
403
  if (!embedder) {
378
- if (speak && reason) info(c.dim(`vg embed \xB7 ${unavailableMessage(reason)}`));
404
+ if (global.json) {
405
+ json({ embedded: 0, model: modelId, semantic: false, reason: reason ?? "init-failed", detail: detail ?? null });
406
+ } else if (reason) {
407
+ info(c.dim(`vg embed \xB7 ${unavailableMessage(reason)}${detail ? ` (${detail})` : ""}`));
408
+ }
379
409
  return;
380
410
  }
381
411
  const pending = countPending(graph, root2, modelId);
382
412
  const bar = speak ? new ProgressBar(c.dim("embedding")) : void 0;
383
413
  await getNodeEmbeddings(graph, embedder, root2, bar ? (d, t) => bar.update(d, t) : void 0);
384
414
  bar?.done();
385
- if (global.json) json({ embedded: pending, model: modelId });
415
+ if (global.json) json({ embedded: pending, model: modelId, semantic: true });
386
416
  else if (speak) info(`${c.green("\u2714")} vg embed \xB7 semantic index ready (~${pending} node(s) \xB7 model ${modelId})`);
387
417
  });
388
418
  applyGlobalOptions(cmd);
@@ -1990,11 +2020,17 @@ async function runAsk(graph, params, ctx) {
1990
2020
  const budgetMs = semanticBudgetMs();
1991
2021
  log(`ask: trying the semantic path (budget ${Math.round(budgetMs / 1e3)}s)`);
1992
2022
  let reason;
2023
+ let detail;
1993
2024
  const started = Date.now();
1994
2025
  try {
1995
2026
  result = await withTimeout(
1996
2027
  (async () => {
1997
- const embedder = await loadEmbedder({ onUnavailable: (r2) => reason = r2 });
2028
+ const embedder = await loadEmbedder({
2029
+ onUnavailable: (r2, d) => {
2030
+ reason = r2;
2031
+ detail = d;
2032
+ }
2033
+ });
1998
2034
  if (!embedder) return null;
1999
2035
  log(`ask: embedder "${embedder.id}" loaded in ${Date.now() - started}ms; embedding nodes\u2026`);
2000
2036
  const vectors = await getNodeEmbeddings(graph, embedder, ctx.root);
@@ -2008,7 +2044,9 @@ async function runAsk(graph, params, ctx) {
2008
2044
  );
2009
2045
  if (!result) {
2010
2046
  note = reason ? unavailableMessage(reason) : "semantic unavailable; used lexical";
2011
- log(`ask: semantic unavailable (${reason ?? "no backend"}) \u2014 falling back to lexical`);
2047
+ log(
2048
+ `ask: semantic unavailable (${reason ?? "no backend"}) \u2014 falling back to lexical` + (detail ? ` \xB7 ${detail}` : "")
2049
+ );
2012
2050
  }
2013
2051
  } catch (err) {
2014
2052
  mode = "lexical";
@@ -6948,7 +6986,7 @@ function registerCode(program) {
6948
6986
  try {
6949
6987
  const { parseMode: parseMode2, resolveMode: resolveMode2, readOrchestratorState: readOrchestratorState2, activePin: activePin2 } = await import('./model-orchestrator-LHYPJBFH.js');
6950
6988
  const { gatherSystemMemory: gatherSystemMemory2 } = await import('./local-runtime-2ED33KK6.js');
6951
- const { loadGraph: loadGraph2 } = await import('./load-OMTSGVDX.js');
6989
+ const { loadGraph: loadGraph2 } = await import('./load-IIWVYUN7.js');
6952
6990
  const state = readOrchestratorState2();
6953
6991
  const mode = parseMode2(modeFlag) ?? state.defaultMode ?? void 0;
6954
6992
  const pin = mode ? activePin2(mode, state) : null;
@@ -7033,7 +7071,7 @@ function registerCode(program) {
7033
7071
  if (!(process.stdin.isTTY && process.stdout.isTTY)) {
7034
7072
  throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"` (guided mode needs an interactive terminal)');
7035
7073
  }
7036
- const { runInteractive } = await import('./interactive-IJS33F4K.js');
7074
+ const { runInteractive } = await import('./interactive-YEMXHGBO.js');
7037
7075
  await runInteractive(
7038
7076
  rootOf(global),
7039
7077
  global,
@@ -7063,7 +7101,7 @@ function registerCode(program) {
7063
7101
  }
7064
7102
  if (!instruction && !stdinFirstTurn) throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"`');
7065
7103
  {
7066
- const { ensureCodeMap } = await import('./ensure-map-JICVC2ZJ.js');
7104
+ const { ensureCodeMap } = await import('./ensure-map-TYMYYIJE.js');
7067
7105
  const mapRoot = rootOf(global);
7068
7106
  try {
7069
7107
  await ensureCodeMap(mapRoot, global, {
@@ -7148,20 +7186,20 @@ function registerCode(program) {
7148
7186
  process.stdout.write(JSON.stringify(line) + "\n");
7149
7187
  };
7150
7188
  try {
7151
- const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-UENLWBWC.js');
7189
+ const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-2JO55QCC.js');
7152
7190
  const primarySlug = route.providers[0]?.model.includes("/") ? route.providers[0].model.split("/")[0] : route.providers[0]?.id;
7153
- const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-SVMGVBFB.js');
7154
- const { nodeCodeFs } = await import('./session-HOS4454T.js');
7191
+ const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-DUCFTBUF.js');
7192
+ const { nodeCodeFs } = await import('./session-5LFX4U2E.js');
7155
7193
  const readline6 = await import('readline');
7156
7194
  const child = await import('child_process');
7157
7195
  const { loadOrDiscoverFederation } = await import('./federation-MDQPO3PW.js');
7158
7196
  const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
7159
7197
  const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
7160
- const { startCodeRuntimeSession } = await import('./runtime-session-AFL7P4TQ.js');
7161
- const { resolveGraphBackend } = await import('./graph-backend-TB35N5MC.js');
7198
+ const { startCodeRuntimeSession } = await import('./runtime-session-HFKGKQV7.js');
7199
+ const { resolveGraphBackend } = await import('./graph-backend-5YOWNHHG.js');
7162
7200
  const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
7163
7201
  const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
7164
- const { vgdRequest: vgdRequest2 } = await import('./vgd-YFPJHQB5.js');
7202
+ const { vgdRequest: vgdRequest2 } = await import('./vgd-LFHQ4GWC.js');
7165
7203
  const federation = loadOrDiscoverFederation(root2);
7166
7204
  const modelProfile = mergeModelExecutionProfile(
7167
7205
  resolveModelExecutionProfile({
@@ -7219,7 +7257,7 @@ ${res.stderr}` : ""),
7219
7257
  exitCode: res.status ?? 1
7220
7258
  };
7221
7259
  };
7222
- const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-NYCAQEMU.js');
7260
+ const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-4KPDQUFN.js');
7223
7261
  const vgBuiltin = createVgBuiltinMcpTools({
7224
7262
  getGraph: () => graph,
7225
7263
  root: root2,
@@ -7279,6 +7317,10 @@ ${res.stderr}` : ""),
7279
7317
  providers: route.providers,
7280
7318
  fsImpl: nodeCodeFs(root2),
7281
7319
  run,
7320
+ // Live command-output events for the VG Code panel (async shell).
7321
+ // Sandboxed executionEnv still uses its own runner when set.
7322
+ streamShell: !executionEnv,
7323
+ allowSubagents: true,
7282
7324
  executionEnv,
7283
7325
  graphBackend,
7284
7326
  modelProfile,
@@ -7309,8 +7351,8 @@ ${res.stderr}` : ""),
7309
7351
  };
7310
7352
  try {
7311
7353
  if (opts.session) {
7312
- const { runCodeStreamJsonSession } = await import('./stream-json-SVMGVBFB.js');
7313
- const { runAgent: runAgent2 } = await import('./agent-SBVWSP7G.js');
7354
+ const { runCodeStreamJsonSession } = await import('./stream-json-DUCFTBUF.js');
7355
+ const { runAgent: runAgent2 } = await import('./agent-K3J6EHLI.js');
7314
7356
  const {
7315
7357
  condenseSession,
7316
7358
  loadLatestSession,
@@ -7318,7 +7360,7 @@ ${res.stderr}` : ""),
7318
7360
  recordTask,
7319
7361
  saveSession,
7320
7362
  summarizeSession
7321
- } = await import('./session-store-F7NX7SZN.js');
7363
+ } = await import('./session-store-KGONLWHN.js');
7322
7364
  const resumedRecord = opts.continue ? loadLatestSession(root2) : void 0;
7323
7365
  let record = resumedRecord ?? newSession(
7324
7366
  `s${Date.now().toString(36)}`,
@@ -7478,13 +7520,13 @@ ${res.stderr}` : ""),
7478
7520
  if (!autonomous && !tty) {
7479
7521
  throw usageError("the agent approves each edit/command \u2014 run in a terminal to approve interactively, or pass --auto to run autonomously (or --single for a one-shot diff).");
7480
7522
  }
7481
- const { agentTask } = await import('./interactive-IJS33F4K.js');
7482
- const { nodeCodeFs } = await import('./session-HOS4454T.js');
7523
+ const { agentTask } = await import('./interactive-YEMXHGBO.js');
7524
+ const { nodeCodeFs } = await import('./session-5LFX4U2E.js');
7483
7525
  const { TtyPrompter } = await import('./ui-K7D3BCHD.js');
7484
7526
  let priorSummary;
7485
7527
  let priorInstruction;
7486
7528
  if (opts.continue) {
7487
- const { loadLatestSession, summarizeSession } = await import('./session-store-F7NX7SZN.js');
7529
+ const { loadLatestSession, summarizeSession } = await import('./session-store-KGONLWHN.js');
7488
7530
  const prev = loadLatestSession(root2);
7489
7531
  if (prev) {
7490
7532
  priorSummary = summarizeSession(prev);
@@ -7492,7 +7534,7 @@ ${res.stderr}` : ""),
7492
7534
  }
7493
7535
  }
7494
7536
  const prompter = tty ? new TtyPrompter() : void 0;
7495
- const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-NYCAQEMU.js');
7537
+ const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-4KPDQUFN.js');
7496
7538
  const vgBuiltin = createVgBuiltinMcpTools({
7497
7539
  getGraph: () => graph,
7498
7540
  root: root2,
@@ -7516,11 +7558,11 @@ ${res.stderr}` : ""),
7516
7558
  const { loadFederation } = await import('./federation-MDQPO3PW.js');
7517
7559
  const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
7518
7560
  const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
7519
- const { startCodeRuntimeSession } = await import('./runtime-session-AFL7P4TQ.js');
7520
- const { resolveGraphBackend } = await import('./graph-backend-TB35N5MC.js');
7561
+ const { startCodeRuntimeSession } = await import('./runtime-session-HFKGKQV7.js');
7562
+ const { resolveGraphBackend } = await import('./graph-backend-5YOWNHHG.js');
7521
7563
  const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
7522
7564
  const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
7523
- const { vgdRequest: vgdRequest2 } = await import('./vgd-YFPJHQB5.js');
7565
+ const { vgdRequest: vgdRequest2 } = await import('./vgd-LFHQ4GWC.js');
7524
7566
  const federation = loadFederation(root2);
7525
7567
  const modelProfile = mergeModelExecutionProfile(
7526
7568
  resolveModelExecutionProfile({
@@ -8430,7 +8472,7 @@ function registerDaemon(program) {
8430
8472
  throw new CliError(loaded.error, ExitCode.NOT_FOUND);
8431
8473
  }
8432
8474
  if (!loaded.ok) {
8433
- const { loadGraph: loadGraph2 } = await import('./load-OMTSGVDX.js');
8475
+ const { loadGraph: loadGraph2 } = await import('./load-IIWVYUN7.js');
8434
8476
  const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
8435
8477
  const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
8436
8478
  const graph = loadGraph2(root2, global.graph);
@@ -8835,7 +8877,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
8835
8877
  console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
8836
8878
  }
8837
8879
  if (opts.baseline) {
8838
- const { runBaseline } = await import('./baseline-NM53X2TB.js');
8880
+ const { runBaseline } = await import('./baseline-IAFWF2ET.js');
8839
8881
  await runBaseline(rootDir);
8840
8882
  }
8841
8883
  console.log("");
@@ -10387,7 +10429,7 @@ ${String(err)}` }));
10387
10429
  async function releaseWindowsFileLocks(cwd, keepVersion) {
10388
10430
  reapAndReport(cwd, keepVersion);
10389
10431
  try {
10390
- const { vgdSocketPath: vgdSocketPath2 } = await import('./vgd-YFPJHQB5.js');
10432
+ const { vgdSocketPath: vgdSocketPath2 } = await import('./vgd-LFHQ4GWC.js');
10391
10433
  const result = await stopVgd(vgdSocketPath2());
10392
10434
  if (result === "stopped") {
10393
10435
  console.log(chalk7.dim("Stopped the vgd daemon so its files can be replaced \u2014 it restarts on the next command."));
@@ -10512,7 +10554,7 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
10512
10554
  );
10513
10555
  async function rewarmVgdAndReport(cwd) {
10514
10556
  try {
10515
- const { vgdIsRunning: vgdIsRunning2, vgdRequest: vgdRequest2 } = await import('./vgd-YFPJHQB5.js');
10557
+ const { vgdIsRunning: vgdIsRunning2, vgdRequest: vgdRequest2 } = await import('./vgd-LFHQ4GWC.js');
10516
10558
  if (!await vgdIsRunning2()) return;
10517
10559
  const loaded = await vgdRequest2({ op: "load-graph", root: cwd });
10518
10560
  if (!loaded.ok || !("repositoryId" in loaded)) return;