@vibgrate/cli 2026.814.2 → 2026.817.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 (134) hide show
  1. package/dist/agent-CUYQKC6S.js +26 -0
  2. package/dist/{agent-5ANHRYEI.js.map → agent-CUYQKC6S.js.map} +1 -1
  3. package/dist/{approvals-T2KXPJLV.js → approvals-IPMUDEDV.js} +5 -5
  4. package/dist/{approvals-T2KXPJLV.js.map → approvals-IPMUDEDV.js.map} +1 -1
  5. package/dist/baseline-NZFGLMER.js +9 -0
  6. package/dist/{baseline-WVD6P5IO.js.map → baseline-NZFGLMER.js.map} +1 -1
  7. package/dist/{chunk-TFAXW7VM.js → chunk-2BURPMYA.js} +3 -3
  8. package/dist/{chunk-TFAXW7VM.js.map → chunk-2BURPMYA.js.map} +1 -1
  9. package/dist/{chunk-X76VPOYH.js → chunk-2GSMCOIC.js} +4 -4
  10. package/dist/{chunk-X76VPOYH.js.map → chunk-2GSMCOIC.js.map} +1 -1
  11. package/dist/{chunk-KGPX4EUN.js → chunk-2TJ5EY4I.js} +4 -4
  12. package/dist/{chunk-KGPX4EUN.js.map → chunk-2TJ5EY4I.js.map} +1 -1
  13. package/dist/{chunk-BH54SLGZ.js → chunk-3GZSDY35.js} +4 -4
  14. package/dist/{chunk-BH54SLGZ.js.map → chunk-3GZSDY35.js.map} +1 -1
  15. package/dist/{chunk-REIGWTTH.js → chunk-3HNPVXUK.js} +3 -3
  16. package/dist/{chunk-REIGWTTH.js.map → chunk-3HNPVXUK.js.map} +1 -1
  17. package/dist/{chunk-7NMXE6KG.js → chunk-45AKSS4A.js} +4 -4
  18. package/dist/{chunk-7NMXE6KG.js.map → chunk-45AKSS4A.js.map} +1 -1
  19. package/dist/{chunk-FOW5IF73.js → chunk-4W5SYK2M.js} +11 -34
  20. package/dist/chunk-4W5SYK2M.js.map +1 -0
  21. package/dist/{chunk-UTNNGKKX.js → chunk-6NOGNOE4.js} +4 -4
  22. package/dist/chunk-6NOGNOE4.js.map +1 -0
  23. package/dist/{chunk-N3XFY3PX.js → chunk-74UBGF4P.js} +3 -3
  24. package/dist/{chunk-N3XFY3PX.js.map → chunk-74UBGF4P.js.map} +1 -1
  25. package/dist/{chunk-YNV5M3JW.js → chunk-A7EKFLAN.js} +8 -8
  26. package/dist/{chunk-YNV5M3JW.js.map → chunk-A7EKFLAN.js.map} +1 -1
  27. package/dist/{chunk-N6ZMZ5AI.js → chunk-ANYL7SUI.js} +349 -46
  28. package/dist/chunk-ANYL7SUI.js.map +1 -0
  29. package/dist/{chunk-75LJM5XD.js → chunk-ENFSSUNK.js} +7 -3
  30. package/dist/chunk-ENFSSUNK.js.map +1 -0
  31. package/dist/{chunk-3LSG7Z4I.js → chunk-EZ7UC5Y5.js} +25 -4
  32. package/dist/chunk-EZ7UC5Y5.js.map +1 -0
  33. package/dist/{chunk-WWGLVF7D.js → chunk-FD2HPGX2.js} +8 -8
  34. package/dist/{chunk-WWGLVF7D.js.map → chunk-FD2HPGX2.js.map} +1 -1
  35. package/dist/{chunk-OWSFZQOP.js → chunk-FJG5AXKZ.js} +3 -3
  36. package/dist/{chunk-OWSFZQOP.js.map → chunk-FJG5AXKZ.js.map} +1 -1
  37. package/dist/chunk-FMS6G67U.js +467 -0
  38. package/dist/chunk-FMS6G67U.js.map +1 -0
  39. package/dist/{chunk-WHJMS7XC.js → chunk-I5LP55B6.js} +3 -3
  40. package/dist/{chunk-WHJMS7XC.js.map → chunk-I5LP55B6.js.map} +1 -1
  41. package/dist/{chunk-JCN6MSXQ.js → chunk-JHLCKMKF.js} +16 -29
  42. package/dist/chunk-JHLCKMKF.js.map +1 -0
  43. package/dist/{chunk-IHLLWBZU.js → chunk-K267DHCF.js} +6 -6
  44. package/dist/{chunk-IHLLWBZU.js.map → chunk-K267DHCF.js.map} +1 -1
  45. package/dist/{chunk-WQLZSVNF.js → chunk-MIYXVY57.js} +7 -6
  46. package/dist/chunk-MIYXVY57.js.map +1 -0
  47. package/dist/chunk-MS6V5XKB.js +33 -0
  48. package/dist/chunk-MS6V5XKB.js.map +1 -0
  49. package/dist/{chunk-5GLQNMTI.js → chunk-NHB53JTV.js} +6 -6
  50. package/dist/{chunk-5GLQNMTI.js.map → chunk-NHB53JTV.js.map} +1 -1
  51. package/dist/{chunk-DSUGC7F5.js → chunk-NKRWKCME.js} +4 -4
  52. package/dist/{chunk-DSUGC7F5.js.map → chunk-NKRWKCME.js.map} +1 -1
  53. package/dist/{chunk-7QDHQLUS.js → chunk-NQUWC2IA.js} +13 -11
  54. package/dist/chunk-NQUWC2IA.js.map +1 -0
  55. package/dist/{chunk-NKFXXP6W.js → chunk-OWSXI3PJ.js} +8 -6
  56. package/dist/chunk-OWSXI3PJ.js.map +1 -0
  57. package/dist/chunk-OZ3IFXRD.js +22 -0
  58. package/dist/chunk-OZ3IFXRD.js.map +1 -0
  59. package/dist/chunk-PV76EO4G.js +6 -0
  60. package/dist/{chunk-2H2U3DC7.js.map → chunk-PV76EO4G.js.map} +1 -1
  61. package/dist/{chunk-2U37PFB2.js → chunk-QPXVTQ7O.js} +3 -3
  62. package/dist/{chunk-2U37PFB2.js.map → chunk-QPXVTQ7O.js.map} +1 -1
  63. package/dist/{chunk-TNROG5CO.js → chunk-RJCRWQNS.js} +1855 -175
  64. package/dist/chunk-RJCRWQNS.js.map +1 -0
  65. package/dist/{chunk-54RGT2T5.js → chunk-RQAKBRAV.js} +3 -3
  66. package/dist/{chunk-54RGT2T5.js.map → chunk-RQAKBRAV.js.map} +1 -1
  67. package/dist/{chunk-YQNTIBKS.js → chunk-UBEVY5UT.js} +6 -6
  68. package/dist/{chunk-YQNTIBKS.js.map → chunk-UBEVY5UT.js.map} +1 -1
  69. package/dist/{chunk-IHXNOY3R.js → chunk-YL4OIUA5.js} +12 -12
  70. package/dist/{chunk-IHXNOY3R.js.map → chunk-YL4OIUA5.js.map} +1 -1
  71. package/dist/{chunk-TVDYEHIM.js → chunk-ZSECAGSU.js} +3 -3
  72. package/dist/{chunk-TVDYEHIM.js.map → chunk-ZSECAGSU.js.map} +1 -1
  73. package/dist/cli.js +416 -717
  74. package/dist/cli.js.map +1 -1
  75. package/dist/daemon-J2HX4GY3.js +25 -0
  76. package/dist/daemon-J2HX4GY3.js.map +1 -0
  77. package/dist/embed-worker-main.js +4 -4
  78. package/dist/ensure-map-5C6KG66X.js +32 -0
  79. package/dist/{ensure-map-HQ7A5NDL.js.map → ensure-map-5C6KG66X.js.map} +1 -1
  80. package/dist/graph-backend-HH5IIQ55.js +14 -0
  81. package/dist/{graph-backend-W2TNTMY7.js.map → graph-backend-HH5IIQ55.js.map} +1 -1
  82. package/dist/index.d.ts +9 -6
  83. package/dist/index.js +18 -16
  84. package/dist/index.js.map +1 -1
  85. package/dist/{interactive-EW2VJ3BZ.js → interactive-FXPAZAUJ.js} +33 -31
  86. package/dist/interactive-FXPAZAUJ.js.map +1 -0
  87. package/dist/load-OR2XVGAV.js +10 -0
  88. package/dist/{load-64RK5O6C.js.map → load-OR2XVGAV.js.map} +1 -1
  89. package/dist/local-runtime-6SNWKSA7.js +6 -0
  90. package/dist/{local-runtime-2ED33KK6.js.map → local-runtime-6SNWKSA7.js.map} +1 -1
  91. package/dist/model-manager-SXHZ5VD4.js +10 -0
  92. package/dist/{model-manager-GJ2YSTSK.js.map → model-manager-SXHZ5VD4.js.map} +1 -1
  93. package/dist/parse-worker.d.ts +1 -1
  94. package/dist/parse-worker.js +1 -1
  95. package/dist/{run-outcome-6QNQIHPV.js → run-outcome-M4546HLJ.js} +6 -6
  96. package/dist/{run-outcome-6QNQIHPV.js.map → run-outcome-M4546HLJ.js.map} +1 -1
  97. package/dist/runtime-session-6KKMFS6Q.js +21 -0
  98. package/dist/{runtime-session-RJHH3KMF.js.map → runtime-session-6KKMFS6Q.js.map} +1 -1
  99. package/dist/session-HCFJUSKN.js +16 -0
  100. package/dist/{session-4BGYASOH.js.map → session-HCFJUSKN.js.map} +1 -1
  101. package/dist/{stream-json-GY5N7WZT.js → stream-json-4DL65D6U.js} +16 -16
  102. package/dist/{stream-json-GY5N7WZT.js.map → stream-json-4DL65D6U.js.map} +1 -1
  103. package/dist/{types-DLH-Ritr.d.ts → types-8SYlXhzm.d.ts} +57 -6
  104. package/dist/version-UPIC3F4P.js +4 -0
  105. package/dist/{version-DPAMQW6M.js.map → version-UPIC3F4P.js.map} +1 -1
  106. package/dist/{vg-mcp-bridge-IGHJKKSL.js → vg-mcp-bridge-FZGX6DYO.js} +10 -10
  107. package/dist/{vg-mcp-bridge-IGHJKKSL.js.map → vg-mcp-bridge-FZGX6DYO.js.map} +1 -1
  108. package/dist/{vgd-ORPA5C2K.js → vgd-QR26FAZD.js} +9 -9
  109. package/dist/vgd-QR26FAZD.js.map +1 -0
  110. package/grammars/tree-sitter-hcl.wasm +0 -0
  111. package/package.json +3 -2
  112. package/dist/agent-5ANHRYEI.js +0 -26
  113. package/dist/baseline-WVD6P5IO.js +0 -9
  114. package/dist/chunk-2H2U3DC7.js +0 -6
  115. package/dist/chunk-3LSG7Z4I.js.map +0 -1
  116. package/dist/chunk-75LJM5XD.js.map +0 -1
  117. package/dist/chunk-7QDHQLUS.js.map +0 -1
  118. package/dist/chunk-FOW5IF73.js.map +0 -1
  119. package/dist/chunk-JCN6MSXQ.js.map +0 -1
  120. package/dist/chunk-N6ZMZ5AI.js.map +0 -1
  121. package/dist/chunk-NKFXXP6W.js.map +0 -1
  122. package/dist/chunk-TNROG5CO.js.map +0 -1
  123. package/dist/chunk-UTNNGKKX.js.map +0 -1
  124. package/dist/chunk-WQLZSVNF.js.map +0 -1
  125. package/dist/ensure-map-HQ7A5NDL.js +0 -30
  126. package/dist/graph-backend-W2TNTMY7.js +0 -14
  127. package/dist/interactive-EW2VJ3BZ.js.map +0 -1
  128. package/dist/load-64RK5O6C.js +0 -10
  129. package/dist/local-runtime-2ED33KK6.js +0 -6
  130. package/dist/model-manager-GJ2YSTSK.js +0 -10
  131. package/dist/runtime-session-RJHH3KMF.js +0 -21
  132. package/dist/session-4BGYASOH.js +0 -16
  133. package/dist/version-DPAMQW6M.js +0 -4
  134. package/dist/vgd-ORPA5C2K.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { parseOllamaPs, parseNvidiaSmi } from './chunk-7N4Y3E47.js';
2
- import { whichOnPath, init_cli_invocation } from './chunk-3LSG7Z4I.js';
2
+ import { whichOnPath, init_cli_invocation } from './chunk-EZ7UC5Y5.js';
3
3
  import { __export, __esm } from './chunk-Z6ZWNWWR.js';
4
4
  import * as fs2 from 'fs';
5
5
  import * as os2 from 'os';
@@ -168,5 +168,5 @@ function safeRun(bin, args) {
168
168
  }
169
169
 
170
170
  export { gatherSystemMemory, hasOllama, hasOllamaBinary, init_resolve_ollama, pullModelClean, resolveOllamaBinary, resolve_ollama_exports, stopModel };
171
- //# sourceMappingURL=chunk-OWSFZQOP.js.map
172
- //# sourceMappingURL=chunk-OWSFZQOP.js.map
171
+ //# sourceMappingURL=chunk-FJG5AXKZ.js.map
172
+ //# sourceMappingURL=chunk-FJG5AXKZ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/util/resolve-ollama.ts","../src/code/available-memory.ts","../src/code/local-runtime.ts"],"names":["freemem","os","fs","os3","spawnSync"],"mappings":"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","file":"chunk-OWSFZQOP.js","sourcesContent":["/**\n * Locate the Ollama CLI for install/uninstall/pull.\n *\n * Dock-launched GUI apps (VS Code, Cursor) often inherit a stripped PATH that\n * omits Homebrew (`/opt/homebrew/bin`) and the official installer locations.\n * Discovery of models still works (on-disk manifests under ~/.ollama), so the\n * UI lists models that then fail to uninstall with \"ollama not on PATH\".\n * Resolve the binary via PATH first, then well-known install prefixes.\n */\n\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { whichOnPath } from './cli-invocation.js';\n\n/** Absolute path to the ollama binary, or null if not found. */\nexport function resolveOllamaBinary(): string | null {\n const names = process.platform === 'win32' ? ['ollama.exe', 'ollama'] : ['ollama'];\n for (const name of names) {\n const hit = whichOnPath(name);\n if (hit) return hit;\n }\n\n const candidates =\n process.platform === 'win32'\n ? [\n path.join(process.env.LOCALAPPDATA || '', 'Programs', 'Ollama', 'ollama.exe'),\n path.join(process.env.ProgramFiles || 'C:\\\\Program Files', 'Ollama', 'ollama.exe'),\n ]\n : [\n '/opt/homebrew/bin/ollama',\n '/usr/local/bin/ollama',\n '/usr/bin/ollama',\n path.join(os.homedir(), '.local', 'bin', 'ollama'),\n ];\n\n for (const c of candidates) {\n if (!c) continue;\n try {\n if (fs.existsSync(c)) return c;\n } catch {\n /* ignore */\n }\n }\n return null;\n}\n\n/** True when the Ollama CLI is on PATH or at a known install location. */\nexport function hasOllamaBinary(): boolean {\n return resolveOllamaBinary() !== null;\n}\n","/**\n * Platform-accurate *available* RAM for model fit decisions.\n *\n * Node's `os.freemem()` is wrong for this use case on several OSes:\n * - **macOS**: returns only completely unused pages. The kernel fills the rest\n * with file cache that is reclaimable under pressure — Activity Monitor's\n * \"Available\" (and what a model can actually use). Under normal load\n * `os.freemem()` often reports ~0 while many GiB are available.\n * - **Linux**: prefers `/proc/meminfo` `MemAvailable` (reclaim-aware) over\n * `MemFree`.\n * - **Windows**: `os.freemem()` already maps to available physical memory\n * (`GlobalMemoryStatusEx.ullAvailPhys`) and is fine.\n *\n * Fit/install gates must use *available* memory, not bare free pages, or\n * Spark/Flow falsely report \"0.0 GiB free after reserves\" on machines with\n * tens of GiB of reclaimable RAM.\n */\n\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport { spawnSync } from 'node:child_process';\n\n/**\n * Parse `vm_stat` output into reclaimable/available bytes.\n * Available ≈ free + inactive + speculative + purgeable (file cache that the\n * kernel can reclaim). Returns null when the output is unparseable.\n */\nexport function parseVmStatAvailableBytes(stdout: string): number | null {\n if (!stdout || !/Pages free:/i.test(stdout)) return null;\n const pageMatch = stdout.match(/page size of (\\d+) bytes/i);\n // Apple Silicon is typically 16 KiB; Intel macOS 4 KiB. Default conservatively.\n const pageSize = pageMatch ? Number(pageMatch[1]) : 4096;\n if (!Number.isFinite(pageSize) || pageSize <= 0) return null;\n\n const pages = (label: string): number => {\n // Lines look like: \"Pages free: 4085.\"\n const m = stdout.match(new RegExp(`${label}:\\\\s+(\\\\d+)\\\\.?`, 'i'));\n return m ? Number(m[1]) : 0;\n };\n\n const free = pages('Pages free');\n const inactive = pages('Pages inactive');\n const speculative = pages('Pages speculative');\n const purgeable = pages('Pages purgeable');\n const totalPages = free + inactive + speculative + purgeable;\n if (!Number.isFinite(totalPages) || totalPages < 0) return null;\n return totalPages * pageSize;\n}\n\n/**\n * Parse `/proc/meminfo` for MemAvailable (kB). Falls back to MemFree when\n * MemAvailable is missing (very old kernels).\n */\nexport function parseMeminfoAvailableBytes(content: string): number | null {\n if (!content) return null;\n const avail = content.match(/^MemAvailable:\\s+(\\d+)\\s*kB/im);\n if (avail) {\n const n = Number(avail[1]) * 1024;\n return Number.isFinite(n) && n >= 0 ? n : null;\n }\n const free = content.match(/^MemFree:\\s+(\\d+)\\s*kB/im);\n if (free) {\n const n = Number(free[1]) * 1024;\n return Number.isFinite(n) && n >= 0 ? n : null;\n }\n return null;\n}\n\n/** Best-effort available RAM in bytes. Never throws; falls back to os.freemem(). */\nexport function availableRamBytes(\n platform: NodeJS.Platform = process.platform,\n freemem: () => number = () => os.freemem(),\n): number {\n const nodeFree = safeNonNeg(freemem());\n let platformAvail: number | null = null;\n\n if (platform === 'darwin') {\n platformAvail = readMacAvailableBytes();\n } else if (platform === 'linux') {\n platformAvail = readLinuxAvailableBytes();\n }\n // win32 and others: Node freemem is already \"available\".\n\n // Prefer the larger of the two when both exist — never under-report\n // availability because of a stale/partial platform probe.\n if (platformAvail != null && platformAvail > nodeFree) return platformAvail;\n return nodeFree;\n}\n\nfunction readMacAvailableBytes(): number | null {\n try {\n const res = spawnSync('vm_stat', [], { encoding: 'utf8', timeout: 3000 });\n if (res.status !== 0 || typeof res.stdout !== 'string') return null;\n return parseVmStatAvailableBytes(res.stdout);\n } catch {\n return null;\n }\n}\n\nfunction readLinuxAvailableBytes(): number | null {\n try {\n const content = fs.readFileSync('/proc/meminfo', 'utf8');\n return parseMeminfoAvailableBytes(content);\n } catch {\n return null;\n }\n}\n\nfunction safeNonNeg(n: number): number {\n return Number.isFinite(n) && n > 0 ? n : 0;\n}\n","/**\n * Thin I/O wrappers around the local model runtime (Ollama / GPU) for the\n * `vg code` guided flow (VG-CLI-CODE §10). The pure parsing/estimation these\n * feed lives in capability.ts and is unit-tested; this file just gathers real\n * system state and wraps the noisy `ollama pull` behind a single clean status\n * line (no raw progress spam), per the \"clean UI for devs\" requirement.\n */\n\nimport * as os from 'node:os';\nimport { spawn, spawnSync } from 'node:child_process';\nimport { availableRamBytes } from './available-memory.js';\nimport { parseOllamaPs, parseNvidiaSmi, type SystemMemory } from './capability.js';\nimport { hasOllamaBinary, resolveOllamaBinary } from '../util/resolve-ollama.js';\nimport type { Spinner } from './ui.js';\n\n/**\n * Gather current system memory, loaded models, and (best-effort) GPU VRAM.\n *\n * `freeRamBytes` is *available* RAM (reclaim-aware on macOS/Linux), not bare\n * free pages from `os.freemem()` — see `available-memory.ts`.\n */\nexport function gatherSystemMemory(): SystemMemory {\n const ollama = resolveOllamaBinary();\n const loaded = ollama ? safeRun(ollama, ['ps']).map(parseOllamaPs).flat() : [];\n const smi = safeRun('nvidia-smi', ['--query-gpu=memory.total,memory.used', '--format=csv,noheader,nounits'])\n .map(parseNvidiaSmi)\n .find(Boolean);\n const sys: SystemMemory = {\n totalRamBytes: os.totalmem(),\n freeRamBytes: availableRamBytes(),\n loaded,\n };\n if (smi) {\n sys.vramTotalBytes = smi.totalBytes;\n sys.vramFreeBytes = Math.max(0, smi.totalBytes - smi.usedBytes);\n }\n return sys;\n}\n\n/** True if the `ollama` binary is on PATH or a known install location. */\nexport function hasOllama(): boolean {\n return hasOllamaBinary();\n}\n\n/** Unload a running model to free memory. Returns true on success. */\nexport function stopModel(name: string): boolean {\n const ollama = resolveOllamaBinary();\n if (!ollama) return false;\n return spawnSync(ollama, ['stop', name], { stdio: 'ignore' }).status === 0;\n}\n\n/**\n * Pull a model, wrapping Ollama's chatty progress in one clean spinner line.\n * We read its stderr, keep only the latest human-meaningful status (e.g.\n * \"pulling manifest\", \"downloading … 42%\"), and never echo the raw stream.\n */\nexport function pullModelClean(name: string, spinner: Spinner): Promise<boolean> {\n return new Promise((resolve) => {\n const ollama = resolveOllamaBinary();\n if (!ollama) {\n resolve(false);\n return;\n }\n const child = spawn(ollama, ['pull', name]);\n const onData = (buf: Buffer): void => {\n const line = lastMeaningfulLine(buf.toString());\n if (line) spinner.update(`pulling ${name} — ${line}`);\n };\n child.stdout?.on('data', onData);\n child.stderr?.on('data', onData);\n child.on('error', () => resolve(false));\n child.on('close', (code) => resolve(code === 0));\n });\n}\n\n/** The last non-empty, de-noised status token from an ollama progress chunk. */\nfunction lastMeaningfulLine(chunk: string): string {\n const lines = chunk\n .split(/[\\r\\n]+/)\n .map((l) => l.trim())\n // ollama redraws a progress bar with escape codes; strip them and bar glyphs.\n .map((l) => l.replace(/\\x1b\\[[0-9;]*[A-Za-z]/g, '').replace(/[▏▎▍▌▋▊▉█░▒▓⣀-⣿]/g, '').trim())\n .filter(Boolean);\n const last = lines[lines.length - 1] ?? '';\n // Keep a short, meaningful summary (status + any percentage).\n const pct = last.match(/(\\d+)\\s*%/);\n const status = last.replace(/\\s{2,}.*$/, '').slice(0, 48);\n return pct ? `${status} ${pct[1]}%`.trim() : status;\n}\n\n/** Run a command and return its stdout lines (or [] if the binary is missing/fails). */\nfunction safeRun(bin: string, args: string[]): string[] {\n try {\n const res = spawnSync(bin, args, { encoding: 'utf8', timeout: 5000 });\n if (res.status !== 0 || typeof res.stdout !== 'string') return [];\n return [res.stdout];\n } catch {\n return [];\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/util/resolve-ollama.ts","../src/code/available-memory.ts","../src/code/local-runtime.ts"],"names":["freemem","os","fs","os3","spawnSync"],"mappings":"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","file":"chunk-FJG5AXKZ.js","sourcesContent":["/**\n * Locate the Ollama CLI for install/uninstall/pull.\n *\n * Dock-launched GUI apps (VS Code, Cursor) often inherit a stripped PATH that\n * omits Homebrew (`/opt/homebrew/bin`) and the official installer locations.\n * Discovery of models still works (on-disk manifests under ~/.ollama), so the\n * UI lists models that then fail to uninstall with \"ollama not on PATH\".\n * Resolve the binary via PATH first, then well-known install prefixes.\n */\n\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { whichOnPath } from './cli-invocation.js';\n\n/** Absolute path to the ollama binary, or null if not found. */\nexport function resolveOllamaBinary(): string | null {\n const names = process.platform === 'win32' ? ['ollama.exe', 'ollama'] : ['ollama'];\n for (const name of names) {\n const hit = whichOnPath(name);\n if (hit) return hit;\n }\n\n const candidates =\n process.platform === 'win32'\n ? [\n path.join(process.env.LOCALAPPDATA || '', 'Programs', 'Ollama', 'ollama.exe'),\n path.join(process.env.ProgramFiles || 'C:\\\\Program Files', 'Ollama', 'ollama.exe'),\n ]\n : [\n '/opt/homebrew/bin/ollama',\n '/usr/local/bin/ollama',\n '/usr/bin/ollama',\n path.join(os.homedir(), '.local', 'bin', 'ollama'),\n ];\n\n for (const c of candidates) {\n if (!c) continue;\n try {\n if (fs.existsSync(c)) return c;\n } catch {\n /* ignore */\n }\n }\n return null;\n}\n\n/** True when the Ollama CLI is on PATH or at a known install location. */\nexport function hasOllamaBinary(): boolean {\n return resolveOllamaBinary() !== null;\n}\n","/**\n * Platform-accurate *available* RAM for model fit decisions.\n *\n * Node's `os.freemem()` is wrong for this use case on several OSes:\n * - **macOS**: returns only completely unused pages. The kernel fills the rest\n * with file cache that is reclaimable under pressure — Activity Monitor's\n * \"Available\" (and what a model can actually use). Under normal load\n * `os.freemem()` often reports ~0 while many GiB are available.\n * - **Linux**: prefers `/proc/meminfo` `MemAvailable` (reclaim-aware) over\n * `MemFree`.\n * - **Windows**: `os.freemem()` already maps to available physical memory\n * (`GlobalMemoryStatusEx.ullAvailPhys`) and is fine.\n *\n * Fit/install gates must use *available* memory, not bare free pages, or\n * Spark/Flow falsely report \"0.0 GiB free after reserves\" on machines with\n * tens of GiB of reclaimable RAM.\n */\n\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport { spawnSync } from 'node:child_process';\n\n/**\n * Parse `vm_stat` output into reclaimable/available bytes.\n * Available ≈ free + inactive + speculative + purgeable (file cache that the\n * kernel can reclaim). Returns null when the output is unparseable.\n */\nexport function parseVmStatAvailableBytes(stdout: string): number | null {\n if (!stdout || !/Pages free:/i.test(stdout)) return null;\n const pageMatch = stdout.match(/page size of (\\d+) bytes/i);\n // Apple Silicon is typically 16 KiB; Intel macOS 4 KiB. Default conservatively.\n const pageSize = pageMatch ? Number(pageMatch[1]) : 4096;\n if (!Number.isFinite(pageSize) || pageSize <= 0) return null;\n\n const pages = (label: string): number => {\n // Lines look like: \"Pages free: 4085.\"\n const m = stdout.match(new RegExp(`${label}:\\\\s+(\\\\d+)\\\\.?`, 'i'));\n return m ? Number(m[1]) : 0;\n };\n\n const free = pages('Pages free');\n const inactive = pages('Pages inactive');\n const speculative = pages('Pages speculative');\n const purgeable = pages('Pages purgeable');\n const totalPages = free + inactive + speculative + purgeable;\n if (!Number.isFinite(totalPages) || totalPages < 0) return null;\n return totalPages * pageSize;\n}\n\n/**\n * Parse `/proc/meminfo` for MemAvailable (kB). Falls back to MemFree when\n * MemAvailable is missing (very old kernels).\n */\nexport function parseMeminfoAvailableBytes(content: string): number | null {\n if (!content) return null;\n const avail = content.match(/^MemAvailable:\\s+(\\d+)\\s*kB/im);\n if (avail) {\n const n = Number(avail[1]) * 1024;\n return Number.isFinite(n) && n >= 0 ? n : null;\n }\n const free = content.match(/^MemFree:\\s+(\\d+)\\s*kB/im);\n if (free) {\n const n = Number(free[1]) * 1024;\n return Number.isFinite(n) && n >= 0 ? n : null;\n }\n return null;\n}\n\n/** Best-effort available RAM in bytes. Never throws; falls back to os.freemem(). */\nexport function availableRamBytes(\n platform: NodeJS.Platform = process.platform,\n freemem: () => number = () => os.freemem(),\n): number {\n const nodeFree = safeNonNeg(freemem());\n let platformAvail: number | null = null;\n\n if (platform === 'darwin') {\n platformAvail = readMacAvailableBytes();\n } else if (platform === 'linux') {\n platformAvail = readLinuxAvailableBytes();\n }\n // win32 and others: Node freemem is already \"available\".\n\n // Prefer the larger of the two when both exist — never under-report\n // availability because of a stale/partial platform probe.\n if (platformAvail != null && platformAvail > nodeFree) return platformAvail;\n return nodeFree;\n}\n\nfunction readMacAvailableBytes(): number | null {\n try {\n const res = spawnSync('vm_stat', [], { encoding: 'utf8', timeout: 3000 });\n if (res.status !== 0 || typeof res.stdout !== 'string') return null;\n return parseVmStatAvailableBytes(res.stdout);\n } catch {\n return null;\n }\n}\n\nfunction readLinuxAvailableBytes(): number | null {\n try {\n const content = fs.readFileSync('/proc/meminfo', 'utf8');\n return parseMeminfoAvailableBytes(content);\n } catch {\n return null;\n }\n}\n\nfunction safeNonNeg(n: number): number {\n return Number.isFinite(n) && n > 0 ? n : 0;\n}\n","/**\n * Thin I/O wrappers around the local model runtime (Ollama / GPU) for the\n * `vg code` guided flow (VG-CLI-CODE §10). The pure parsing/estimation these\n * feed lives in capability.ts and is unit-tested; this file just gathers real\n * system state and wraps the noisy `ollama pull` behind a single clean status\n * line (no raw progress spam), per the \"clean UI for devs\" requirement.\n */\n\nimport * as os from 'node:os';\nimport { spawn, spawnSync } from 'node:child_process';\nimport { availableRamBytes } from './available-memory.js';\nimport { parseOllamaPs, parseNvidiaSmi, type SystemMemory } from './capability.js';\nimport { hasOllamaBinary, resolveOllamaBinary } from '../util/resolve-ollama.js';\nimport type { Spinner } from './ui.js';\n\n/**\n * Gather current system memory, loaded models, and (best-effort) GPU VRAM.\n *\n * `freeRamBytes` is *available* RAM (reclaim-aware on macOS/Linux), not bare\n * free pages from `os.freemem()` — see `available-memory.ts`.\n */\nexport function gatherSystemMemory(): SystemMemory {\n const ollama = resolveOllamaBinary();\n const loaded = ollama ? safeRun(ollama, ['ps']).map(parseOllamaPs).flat() : [];\n const smi = safeRun('nvidia-smi', ['--query-gpu=memory.total,memory.used', '--format=csv,noheader,nounits'])\n .map(parseNvidiaSmi)\n .find(Boolean);\n const sys: SystemMemory = {\n totalRamBytes: os.totalmem(),\n freeRamBytes: availableRamBytes(),\n loaded,\n };\n if (smi) {\n sys.vramTotalBytes = smi.totalBytes;\n sys.vramFreeBytes = Math.max(0, smi.totalBytes - smi.usedBytes);\n }\n return sys;\n}\n\n/** True if the `ollama` binary is on PATH or a known install location. */\nexport function hasOllama(): boolean {\n return hasOllamaBinary();\n}\n\n/** Unload a running model to free memory. Returns true on success. */\nexport function stopModel(name: string): boolean {\n const ollama = resolveOllamaBinary();\n if (!ollama) return false;\n return spawnSync(ollama, ['stop', name], { stdio: 'ignore' }).status === 0;\n}\n\n/**\n * Pull a model, wrapping Ollama's chatty progress in one clean spinner line.\n * We read its stderr, keep only the latest human-meaningful status (e.g.\n * \"pulling manifest\", \"downloading … 42%\"), and never echo the raw stream.\n */\nexport function pullModelClean(name: string, spinner: Spinner): Promise<boolean> {\n return new Promise((resolve) => {\n const ollama = resolveOllamaBinary();\n if (!ollama) {\n resolve(false);\n return;\n }\n const child = spawn(ollama, ['pull', name]);\n const onData = (buf: Buffer): void => {\n const line = lastMeaningfulLine(buf.toString());\n if (line) spinner.update(`pulling ${name} — ${line}`);\n };\n child.stdout?.on('data', onData);\n child.stderr?.on('data', onData);\n child.on('error', () => resolve(false));\n child.on('close', (code) => resolve(code === 0));\n });\n}\n\n/** The last non-empty, de-noised status token from an ollama progress chunk. */\nfunction lastMeaningfulLine(chunk: string): string {\n const lines = chunk\n .split(/[\\r\\n]+/)\n .map((l) => l.trim())\n // ollama redraws a progress bar with escape codes; strip them and bar glyphs.\n .map((l) => l.replace(/\\x1b\\[[0-9;]*[A-Za-z]/g, '').replace(/[▏▎▍▌▋▊▉█░▒▓⣀-⣿]/g, '').trim())\n .filter(Boolean);\n const last = lines[lines.length - 1] ?? '';\n // Keep a short, meaningful summary (status + any percentage).\n const pct = last.match(/(\\d+)\\s*%/);\n const status = last.replace(/\\s{2,}.*$/, '').slice(0, 48);\n return pct ? `${status} ${pct[1]}%`.trim() : status;\n}\n\n/** Run a command and return its stdout lines (or [] if the binary is missing/fails). */\nfunction safeRun(bin: string, args: string[]): string[] {\n try {\n const res = spawnSync(bin, args, { encoding: 'utf8', timeout: 5000 });\n if (res.status !== 0 || typeof res.stdout !== 'string') return [];\n return [res.stdout];\n } catch {\n return [];\n }\n}\n"]}
@@ -0,0 +1,467 @@
1
+ import { readGlobal, applyGlobalOptions } from './chunk-OZ3IFXRD.js';
2
+ import { json, info, c } from './chunk-CT5BS56U.js';
3
+ import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-OWSXI3PJ.js';
4
+ import { vgdIsRunning, vgdRequest, vgdSocketPath, vgdPidPath } from './chunk-RBIRXQR6.js';
5
+ import { CliError, ExitCode } from './chunk-MS6V5XKB.js';
6
+ import { loadGraph } from './chunk-MIYXVY57.js';
7
+ import { init_cli_invocation, reinvokeCli } from './chunk-EZ7UC5Y5.js';
8
+ import * as fs from 'fs';
9
+ import * as path2 from 'path';
10
+ import { spawn } from 'child_process';
11
+
12
+ function rootOf(global) {
13
+ return path2.resolve(global.cwd ?? ".");
14
+ }
15
+ function requireGraph(global) {
16
+ const root = rootOf(global);
17
+ const graph = loadGraph(root, global.graph);
18
+ if (!graph) {
19
+ throw new CliError(
20
+ `no map found \u2014 run \`vg\` to build one first` + (global.graph ? ` (looked at ${global.graph})` : ""),
21
+ ExitCode.NOT_FOUND
22
+ );
23
+ }
24
+ return { root, graph };
25
+ }
26
+
27
+ // src/commands/daemon.ts
28
+ init_cli_invocation();
29
+ function registerDaemon(program) {
30
+ const cmd = program.command("daemon").description("local Fusion Runtime daemon (vgd) \u2014 workspace registry prototype").option("--socket <path>", "override the daemon socket path");
31
+ const status = cmd.command("status").description("show whether vgd is running and how many workspaces it tracks").action(async function() {
32
+ const global = readGlobal(this);
33
+ const socketPath = socketOf(this);
34
+ const running = await vgdIsRunning({ socketPath });
35
+ if (!running) {
36
+ if (global.json) {
37
+ json({ running: false, socketPath, version: VGD_PROTOCOL_VERSION });
38
+ } else {
39
+ info(c.dim(`vgd \xB7 not running (${socketPath})`));
40
+ }
41
+ process.exitCode = ExitCode.NOT_FOUND;
42
+ return;
43
+ }
44
+ const res = await vgdRequest({ op: "status" }, { socketPath });
45
+ if (!res.ok) throw new CliError(res.error, ExitCode.ERROR);
46
+ const semantic = await vgdRequest({ op: "embed-status" }, { socketPath }).catch(() => null);
47
+ const semanticPayload = semantic && semantic.ok && "semantic" in semantic ? semantic.semantic : void 0;
48
+ if (global.json) json({ running: true, ...res, semantic: semanticPayload });
49
+ else if ("pid" in res) {
50
+ const slots = typeof res.graphSlots === "number" ? ` \xB7 ${res.graphSlots} graph slot(s)` : "";
51
+ const cli = res.cliVersion ? ` \xB7 cli ${res.cliVersion}` : "";
52
+ info(
53
+ `vgd \xB7 running pid ${res.pid}${cli} \xB7 ${res.workspaces} workspace(s)${slots} \xB7 ${res.uptimeMs}ms up \xB7 ${c.dim(res.socketPath)}`
54
+ );
55
+ if (semanticPayload) {
56
+ const ready = semanticPayload.slots.filter((sl) => sl.state === "ready");
57
+ const vectors = ready.reduce((n, sl) => n + sl.vectors, 0);
58
+ const detail = semanticPayload.worker === "unavailable" ? c.dim(semanticPayload.reason ?? "semantic off \u2014 lexical only") : `${ready.length}/${semanticPayload.slots.length} index(es) ready \xB7 ${vectors} vector(s)` + (semanticPayload.model ? ` \xB7 ${semanticPayload.model}` : "");
59
+ info(` semantic \xB7 worker ${semanticPayload.worker} \xB7 ${detail}`);
60
+ for (const sl of semanticPayload.slots) {
61
+ if (sl.state === "ready") continue;
62
+ info(c.dim(` ${sl.repositoryId}@${sl.gitRef} \xB7 ${sl.state}${sl.error ? ` \u2014 ${sl.error}` : ""}`));
63
+ }
64
+ }
65
+ }
66
+ });
67
+ applyGlobalOptions(status);
68
+ const start = cmd.command("start").description("run vgd in the foreground (Ctrl-C to stop)").action(async function() {
69
+ const global = readGlobal(this);
70
+ const socketPath = socketOf(this);
71
+ if (await vgdIsRunning({ socketPath })) {
72
+ throw new CliError(`vgd is already running at ${socketPath}`, ExitCode.ERROR);
73
+ }
74
+ let requestShutdown = () => {
75
+ };
76
+ const server = await startVgdServer({
77
+ socketPath,
78
+ onShutdownRequest: () => requestShutdown(),
79
+ // Show the daemon working: graph publishes, branch switches, new repos,
80
+ // and every semantic index build. Silent under --quiet/--json.
81
+ log: global.quiet || global.json ? void 0 : (message) => info(c.dim(`vgd \xB7 ${message}`))
82
+ });
83
+ if (!global.quiet) {
84
+ info(`vgd \xB7 listening on ${c.dim(server.socketPath)} (${VGD_PROTOCOL_VERSION})`);
85
+ info(c.dim(" register a workspace: vg daemon register"));
86
+ info(c.dim(" status: vg daemon status"));
87
+ }
88
+ const shutdown = async () => {
89
+ await server.close();
90
+ if (!global.quiet) info(c.dim("vgd \xB7 stopped"));
91
+ process.exit(0);
92
+ };
93
+ requestShutdown = () => void shutdown();
94
+ process.on("SIGINT", () => void shutdown());
95
+ process.on("SIGTERM", () => void shutdown());
96
+ await new Promise(() => {
97
+ });
98
+ });
99
+ applyGlobalOptions(start);
100
+ const ensure = cmd.command("ensure").description("ensure vgd is running (start in background if needed)").action(async function() {
101
+ const global = readGlobal(this);
102
+ const socketPath = socketOf(this);
103
+ const ensured = await ensureVgd(socketPath);
104
+ const res = await vgdRequest({ op: "status" }, { socketPath });
105
+ if (!res.ok) {
106
+ throw new CliError(
107
+ ensured.started ? `vgd started (pid ${ensured.pid ?? "?"}) but status failed: ${res.error} (${socketPath})` : `vgd is running but status failed: ${res.error} (${socketPath})`,
108
+ ExitCode.ERROR
109
+ );
110
+ }
111
+ if (global.json) {
112
+ json({ running: true, ensured: ensured.started, ...res });
113
+ } else if (!global.quiet) {
114
+ const pid = "pid" in res ? res.pid : ensured.pid;
115
+ info(
116
+ ensured.started ? `vgd \xB7 started in background pid ${pid} \xB7 ${c.dim(socketPath)}` : `vgd \xB7 already running pid ${pid} \xB7 ${c.dim(socketPath)}`
117
+ );
118
+ }
119
+ });
120
+ applyGlobalOptions(ensure);
121
+ const stop = cmd.command("stop").description("stop the running vgd (idempotent \u2014 succeeds if none is running)").action(async function() {
122
+ const global = readGlobal(this);
123
+ const socketPath = socketOf(this);
124
+ const result = await stopVgd(socketPath);
125
+ if (global.json) {
126
+ json({ stopped: result === "stopped", result, socketPath });
127
+ } else if (!global.quiet) {
128
+ if (result === "stopped") info(`vgd \xB7 stopped ${c.dim(socketPath)}`);
129
+ else if (result === "not-running") info(c.dim(`vgd \xB7 not running (${socketPath})`));
130
+ }
131
+ if (result === "refused") {
132
+ throw new CliError(
133
+ "this vgd cannot be stopped remotely \u2014 it is running inside another process; stop that process instead",
134
+ ExitCode.ERROR
135
+ );
136
+ }
137
+ if (result === "failed") {
138
+ throw new CliError(
139
+ `vgd did not stop within 5s (${socketPath}) \u2014 check \`vg daemon status\` and stop the process manually`,
140
+ ExitCode.ERROR
141
+ );
142
+ }
143
+ });
144
+ applyGlobalOptions(stop);
145
+ const restart = cmd.command("restart").description("restart vgd (stop if running, then start in the background)").action(async function() {
146
+ const global = readGlobal(this);
147
+ const socketPath = socketOf(this);
148
+ const stopResult = await stopVgd(socketPath);
149
+ if (stopResult === "refused") {
150
+ throw new CliError(
151
+ "this vgd cannot be stopped remotely \u2014 it is running inside another process; stop that process instead",
152
+ ExitCode.ERROR
153
+ );
154
+ }
155
+ if (stopResult === "failed") {
156
+ throw new CliError(
157
+ `vgd did not stop within 5s (${socketPath}) \u2014 check \`vg daemon status\` and stop the process manually`,
158
+ ExitCode.ERROR
159
+ );
160
+ }
161
+ await startDetachedVgd(socketPath);
162
+ const res = await vgdRequest({ op: "status" }, { socketPath });
163
+ if (global.json) {
164
+ json({ running: true, restarted: true, ...res.ok ? res : { socketPath } });
165
+ } else if (!global.quiet) {
166
+ const pid = res.ok && "pid" in res ? res.pid : "?";
167
+ info(`vgd \xB7 restarted pid ${pid} \xB7 ${c.dim(socketPath)}`);
168
+ }
169
+ });
170
+ applyGlobalOptions(restart);
171
+ const register = cmd.command("register").description("register the current repository with a running vgd").argument("[root]", "repository root (default: cwd)").action(async function(rootArg) {
172
+ const global = readGlobal(this);
173
+ const socketPath = socketOf(this);
174
+ const root = path2.resolve(rootArg ?? rootOf(global));
175
+ if (!await vgdIsRunning({ socketPath })) {
176
+ throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
177
+ }
178
+ const res = await vgdRequest({ op: "register", root }, { socketPath });
179
+ if (!res.ok) throw new CliError(res.error, ExitCode.ERROR);
180
+ if (global.json) json(res);
181
+ else if ("workspace" in res) {
182
+ info(`vgd \xB7 registered ${res.workspace.root}`);
183
+ info(c.dim(` id ${res.workspace.id}`));
184
+ info(c.dim(` graph ${res.workspace.graphPath}`));
185
+ }
186
+ });
187
+ applyGlobalOptions(register);
188
+ const list = cmd.command("list").description("list workspaces registered with the running vgd").action(async function() {
189
+ const global = readGlobal(this);
190
+ const socketPath = socketOf(this);
191
+ if (!await vgdIsRunning({ socketPath })) {
192
+ throw new CliError(`vgd is not running (${socketPath})`, ExitCode.NOT_FOUND);
193
+ }
194
+ const res = await vgdRequest({ op: "list" }, { socketPath });
195
+ if (!res.ok) throw new CliError(res.error, ExitCode.ERROR);
196
+ if (global.json) json(res);
197
+ else if ("workspaces" in res && Array.isArray(res.workspaces)) {
198
+ if (res.workspaces.length === 0) info(c.dim("vgd \xB7 no workspaces registered"));
199
+ for (const w of res.workspaces) {
200
+ const tag = w.label ? ` (${w.label}${w.role ? `/${w.role}` : ""})` : "";
201
+ info(`${w.root}${tag}`);
202
+ info(c.dim(` id ${w.id} \xB7 graph ${w.graphPath}`));
203
+ }
204
+ }
205
+ });
206
+ applyGlobalOptions(list);
207
+ const federation = cmd.command("federation").description("register a multi-root federation from .vibgrate/federation.json (or primary cwd)").argument("[root]", "primary repository root (default: cwd)").action(async function(rootArg) {
208
+ const global = readGlobal(this);
209
+ const socketPath = socketOf(this);
210
+ const primary = path2.resolve(rootArg ?? rootOf(global));
211
+ if (!await vgdIsRunning({ socketPath })) {
212
+ throw new CliError(`vgd is not running \u2014 start it with \`vg daemon start\` (${socketPath})`, ExitCode.NOT_FOUND);
213
+ }
214
+ const { loadFederation } = await import('./federation-MDQPO3PW.js');
215
+ const fed = loadFederation(primary);
216
+ if (!fed) throw new CliError(`could not load federation for ${primary}`, ExitCode.ERROR);
217
+ const res = await vgdRequest(
218
+ {
219
+ op: "register-federation",
220
+ primaryRoot: fed.primaryRoot,
221
+ members: fed.members.map((m) => ({ root: m.root, label: m.label, role: m.role }))
222
+ },
223
+ { socketPath }
224
+ );
225
+ if (!res.ok) throw new CliError(res.error, ExitCode.ERROR);
226
+ if (global.json) json(res);
227
+ else if ("workspaces" in res && Array.isArray(res.workspaces)) {
228
+ info(`vgd \xB7 federation registered (${res.workspaces.length} workspace(s))`);
229
+ for (const w of res.workspaces) {
230
+ info(c.dim(` ${w.label ?? w.root}${w.role ? ` [${w.role}]` : ""}`));
231
+ }
232
+ }
233
+ });
234
+ applyGlobalOptions(federation);
235
+ const publish = cmd.command("publish").description("load the workspace code map into vgd ActiveGraph (from global/legacy store)").argument("[root]", "repository root (default: cwd)").option("--git-ref <ref>", "branch or SHA (default: detect HEAD)").action(async function(rootArg) {
236
+ const global = readGlobal(this);
237
+ const socketPath = socketOf(this);
238
+ const root = path2.resolve(rootArg ?? rootOf(global));
239
+ if (!await vgdIsRunning({ socketPath })) {
240
+ throw new CliError(`vgd is not running \u2014 start it with \`vg daemon ensure\` (${socketPath})`, ExitCode.NOT_FOUND);
241
+ }
242
+ const opts = this.opts();
243
+ const loaded = await vgdRequest(
244
+ { op: "load-graph", root, gitRef: opts.gitRef?.trim() || void 0, graphPath: global.graph },
245
+ { socketPath }
246
+ );
247
+ let put = loaded;
248
+ if (!loaded.ok && loaded.code === "no_map") {
249
+ throw new CliError(loaded.error, ExitCode.NOT_FOUND);
250
+ }
251
+ if (!loaded.ok) {
252
+ const { loadGraph: loadGraph2 } = await import('./load-OR2XVGAV.js');
253
+ const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
254
+ const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
255
+ const graph = loadGraph2(root, global.graph);
256
+ if (!graph) {
257
+ throw new CliError(
258
+ `no code map found for ${root} \u2014 run \`vg build\` (or bare \`vg\`) first`,
259
+ ExitCode.NOT_FOUND
260
+ );
261
+ }
262
+ const reg = await vgdRequest({ op: "register", root }, { socketPath });
263
+ if (!reg.ok) throw new CliError(reg.error, ExitCode.ERROR);
264
+ const git = opts.gitRef?.trim() || detectGitRef(root).ref || "HEAD";
265
+ const repositoryId = reg.ok && "workspace" in reg ? reg.workspace.id : repositoryIdFromRoot(root);
266
+ put = await vgdRequest(
267
+ { op: "put-graph", repositoryId, gitRef: git, graph },
268
+ { socketPath }
269
+ );
270
+ if (!put.ok) throw new CliError(put.error, ExitCode.ERROR);
271
+ }
272
+ if (global.json) json(put);
273
+ else if (put.ok && "stored" in put) {
274
+ info(`vgd \xB7 published graph \xB7 ${put.nodeCount} node(s) \xB7 ref ${put.gitRef}`);
275
+ info(c.dim(` repositoryId ${put.repositoryId}`));
276
+ }
277
+ });
278
+ applyGlobalOptions(publish);
279
+ const query = cmd.command("query").description("query the ActiveGraph held by vgd (lexical/structural)").option("--repository-id <id>", "repository id from `vg daemon list` (default: cwd workspace)").argument("<query...>", "what to find").option("--limit <n>", "max matches", "12").option("--git-ref <ref>", "branch or SHA (default: current slot)").action(async function(queryParts) {
280
+ const global = readGlobal(this);
281
+ const socketPath = socketOf(this);
282
+ const opts = this.opts();
283
+ const q = (queryParts ?? []).join(" ").trim();
284
+ if (!q) throw new CliError("say what to find", ExitCode.USAGE_ERROR);
285
+ if (!await vgdIsRunning({ socketPath })) {
286
+ throw new CliError(`vgd is not running (${socketPath})`, ExitCode.NOT_FOUND);
287
+ }
288
+ const repositoryId = opts.repositoryId?.trim() || await repositoryIdForCwd(socketPath, rootOf(global));
289
+ const res = await vgdRequest(
290
+ {
291
+ op: "query-graph",
292
+ repositoryId,
293
+ query: q,
294
+ limit: opts.limit ? Number(opts.limit) : 12,
295
+ gitRef: opts.gitRef
296
+ },
297
+ { socketPath }
298
+ );
299
+ if (!res.ok) throw new CliError(res.error, ExitCode.ERROR);
300
+ if (global.json) json(res);
301
+ else if ("matches" in res) {
302
+ info(`vgd query \xB7 ${res.matches.length} match(es) \xB7 ref ${res.gitRef}`);
303
+ for (const m of res.matches) {
304
+ info(`${m.qualifiedName} (${m.kind}) ${m.file}:${m.line}`);
305
+ info(c.dim(` score ${m.score} \xB7 ${m.why}`));
306
+ }
307
+ }
308
+ });
309
+ applyGlobalOptions(query);
310
+ const impact = cmd.command("impact").description("blast radius for a symbol in the vgd ActiveGraph").option("--repository-id <id>", "repository id (default: cwd workspace)").argument("<symbol>", "symbol id or qualified name").option("--depth <n>", "max dependency depth", "4").option("--git-ref <ref>", "branch or SHA").action(async function(symbol) {
311
+ const global = readGlobal(this);
312
+ const socketPath = socketOf(this);
313
+ const opts = this.opts();
314
+ if (!await vgdIsRunning({ socketPath })) {
315
+ throw new CliError(`vgd is not running (${socketPath})`, ExitCode.NOT_FOUND);
316
+ }
317
+ const repositoryId = opts.repositoryId?.trim() || await repositoryIdForCwd(socketPath, rootOf(global));
318
+ const res = await vgdRequest(
319
+ {
320
+ op: "impact-of",
321
+ repositoryId,
322
+ symbol: symbol.trim(),
323
+ depth: opts.depth ? Number(opts.depth) : 4,
324
+ gitRef: opts.gitRef
325
+ },
326
+ { socketPath }
327
+ );
328
+ if (!res.ok) throw new CliError(res.error, ExitCode.ERROR);
329
+ if (global.json) json(res);
330
+ else if ("affected" in res) {
331
+ info(`vgd impact \xB7 ${res.root.name} \xB7 depth ${res.depth} \xB7 ${res.affected.length} affected`);
332
+ for (const a of res.affected.slice(0, 30)) {
333
+ info(`- ${a.name} (${a.file}:${a.line}) d=${a.depth}`);
334
+ }
335
+ }
336
+ });
337
+ applyGlobalOptions(impact);
338
+ const graphs = cmd.command("graphs").description("list multi-branch ActiveGraph slots resident in the running vgd (Fusion \xA74.1.1)").option("--repository-id <id>", "filter slots to one repository id").action(async function() {
339
+ const global = readGlobal(this);
340
+ const socketPath = socketOf(this);
341
+ const opts = this.opts();
342
+ if (!await vgdIsRunning({ socketPath })) {
343
+ throw new CliError(`vgd is not running (${socketPath})`, ExitCode.NOT_FOUND);
344
+ }
345
+ const res = await vgdRequest(
346
+ { op: "list-graph-slots", repositoryId: opts.repositoryId },
347
+ { socketPath }
348
+ );
349
+ if (!res.ok) throw new CliError(res.error, ExitCode.ERROR);
350
+ if (global.json) json(res);
351
+ else if ("slots" in res) {
352
+ if (!res.slots.length) info(c.dim("vgd \xB7 no graph slots resident"));
353
+ for (const s of res.slots) {
354
+ const cur = s.current ? c.green(" current") : "";
355
+ const idle = s.evictable ? c.yellow(" idle") : "";
356
+ info(`${s.repositoryId.slice(0, 8)}\u2026 ${s.gitRef}${cur}${idle}`);
357
+ info(c.dim(` nodes ${s.nodeCount} \xB7 idle ${Math.round(s.idleMs / 1e3)}s \xB7 loaded ${new Date(s.loadedAt).toISOString()}`));
358
+ }
359
+ }
360
+ });
361
+ applyGlobalOptions(graphs);
362
+ applyGlobalOptions(cmd);
363
+ }
364
+ function socketOf(cmd) {
365
+ let c2 = cmd;
366
+ while (c2) {
367
+ const opts = c2.opts();
368
+ if (opts.socket) return path2.resolve(opts.socket);
369
+ c2 = c2.parent;
370
+ }
371
+ return vgdSocketPath();
372
+ }
373
+ function spawnDetachedDaemonStart(socketPath) {
374
+ const opts = {
375
+ detached: true,
376
+ stdio: "ignore",
377
+ env: process.env,
378
+ windowsHide: true
379
+ };
380
+ const { command, argv } = reinvokeCli(["daemon", "start", "--socket", socketPath]);
381
+ return spawn(command, argv, opts);
382
+ }
383
+ function sleep(ms) {
384
+ return new Promise((r) => setTimeout(r, ms));
385
+ }
386
+ async function startDetachedVgd(socketPath) {
387
+ const child = spawnDetachedDaemonStart(socketPath);
388
+ child.unref();
389
+ const readyMs = 3e4;
390
+ const deadline = Date.now() + readyMs;
391
+ while (Date.now() < deadline) {
392
+ await sleep(150);
393
+ if (await vgdIsRunning({ socketPath })) return child.pid;
394
+ if (child.exitCode != null && child.exitCode !== 0) {
395
+ if (await vgdIsRunning({ socketPath })) return child.pid;
396
+ throw new CliError(
397
+ `vgd child exited ${child.exitCode} before becoming ready at ${socketPath} \u2014 run "vg daemon start" in the foreground to see the error`,
398
+ ExitCode.ERROR
399
+ );
400
+ }
401
+ }
402
+ throw new CliError(
403
+ `vgd failed to become ready within ${Math.round(readyMs / 1e3)}s at ${socketPath}`,
404
+ ExitCode.ERROR
405
+ );
406
+ }
407
+ async function ensureVgd(socketPath = vgdSocketPath()) {
408
+ if (await vgdIsRunning({ socketPath })) return { started: false };
409
+ const pid = await startDetachedVgd(socketPath);
410
+ return { started: true, pid };
411
+ }
412
+ async function stopVgd(socketPath) {
413
+ if (!await vgdIsRunning({ socketPath })) return "not-running";
414
+ let acknowledged = false;
415
+ try {
416
+ const res = await vgdRequest({ op: "shutdown" }, { socketPath });
417
+ if (res.ok) acknowledged = true;
418
+ else if (res.code === "shutdown_unsupported") return "refused";
419
+ } catch {
420
+ }
421
+ if (!acknowledged) {
422
+ const pid = readVgdPid();
423
+ if (pid == null) return "failed";
424
+ try {
425
+ process.kill(pid, "SIGTERM");
426
+ } catch {
427
+ return "failed";
428
+ }
429
+ }
430
+ const deadline = Date.now() + 5e3;
431
+ while (Date.now() < deadline) {
432
+ await sleep(100);
433
+ if (!await vgdIsRunning({ socketPath })) return "stopped";
434
+ }
435
+ return "failed";
436
+ }
437
+ async function restartVgdIfRunning(socketPath = vgdSocketPath()) {
438
+ try {
439
+ const stopResult = await stopVgd(socketPath);
440
+ if (stopResult === "not-running") return "not-running";
441
+ if (stopResult === "refused") return "refused";
442
+ if (stopResult === "failed") return "failed";
443
+ await startDetachedVgd(socketPath);
444
+ return "restarted";
445
+ } catch {
446
+ return "failed";
447
+ }
448
+ }
449
+ function readVgdPid() {
450
+ try {
451
+ const raw = fs.readFileSync(vgdPidPath(), "utf8").trim();
452
+ const pid = Number.parseInt(raw, 10);
453
+ return Number.isInteger(pid) && pid > 0 ? pid : null;
454
+ } catch {
455
+ return null;
456
+ }
457
+ }
458
+ async function repositoryIdForCwd(socketPath, root) {
459
+ const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
460
+ const reg = await vgdRequest({ op: "register", root }, { socketPath });
461
+ if (reg.ok && "workspace" in reg) return reg.workspace.id;
462
+ return repositoryIdFromRoot(root);
463
+ }
464
+
465
+ export { ensureVgd, registerDaemon, requireGraph, restartVgdIfRunning, rootOf, stopVgd };
466
+ //# sourceMappingURL=chunk-FMS6G67U.js.map
467
+ //# sourceMappingURL=chunk-FMS6G67U.js.map