@vibgrate/cli 2026.729.2 → 2026.730.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 (107) hide show
  1. package/DOCS.md +5 -1
  2. package/dist/agent-33BMKWJC.js +22 -0
  3. package/dist/agent-33BMKWJC.js.map +1 -0
  4. package/dist/baseline-V6MYDEMS.js +9 -0
  5. package/dist/{baseline-UOTGTJYT.js.map → baseline-V6MYDEMS.js.map} +1 -1
  6. package/dist/checkpoint-4WFZMKEO.js +56 -0
  7. package/dist/checkpoint-4WFZMKEO.js.map +1 -0
  8. package/dist/chunk-543E6WDJ.js +61 -0
  9. package/dist/chunk-543E6WDJ.js.map +1 -0
  10. package/dist/{chunk-P3QIO4ZU.js → chunk-5G7C6H2G.js} +14 -204
  11. package/dist/chunk-5G7C6H2G.js.map +1 -0
  12. package/dist/{chunk-JIBOJTGS.js → chunk-5HYCB55P.js} +101 -101
  13. package/dist/chunk-5HYCB55P.js.map +1 -0
  14. package/dist/{chunk-67YG3R5F.js → chunk-6D4BCGRQ.js} +6 -62
  15. package/dist/chunk-6D4BCGRQ.js.map +1 -0
  16. package/dist/{chunk-F6ZPUKED.js → chunk-6WNJJXFY.js} +4 -4
  17. package/dist/{chunk-F6ZPUKED.js.map → chunk-6WNJJXFY.js.map} +1 -1
  18. package/dist/{chunk-PXXVLX7K.js → chunk-CFL3QQQZ.js} +7 -6
  19. package/dist/chunk-CFL3QQQZ.js.map +1 -0
  20. package/dist/{chunk-74ZMAOVF.js → chunk-CQDCZQFV.js} +55 -9
  21. package/dist/chunk-CQDCZQFV.js.map +1 -0
  22. package/dist/{chunk-VZRQUI54.js → chunk-DBMYWNLC.js} +4 -4
  23. package/dist/{chunk-VZRQUI54.js.map → chunk-DBMYWNLC.js.map} +1 -1
  24. package/dist/{chunk-QDZ47G45.js → chunk-EKCNSRNJ.js} +20 -11
  25. package/dist/chunk-EKCNSRNJ.js.map +1 -0
  26. package/dist/{chunk-SIPGDJT4.js → chunk-EVLS2M5G.js} +4 -4
  27. package/dist/{chunk-SIPGDJT4.js.map → chunk-EVLS2M5G.js.map} +1 -1
  28. package/dist/{chunk-G4HTI4ZM.js → chunk-FHJBGPJZ.js} +3 -2
  29. package/dist/chunk-FHJBGPJZ.js.map +1 -0
  30. package/dist/{chunk-CYC3ZI32.js → chunk-GLT3N7T2.js} +9 -6
  31. package/dist/chunk-GLT3N7T2.js.map +1 -0
  32. package/dist/chunk-HTLDXEHW.js +60 -0
  33. package/dist/chunk-HTLDXEHW.js.map +1 -0
  34. package/dist/{chunk-GI6W53LM.js → chunk-IDAQV3NQ.js} +4 -2
  35. package/dist/chunk-IDAQV3NQ.js.map +1 -0
  36. package/dist/{chunk-2ZHWF7C6.js → chunk-KGWEBM2J.js} +43 -68
  37. package/dist/chunk-KGWEBM2J.js.map +1 -0
  38. package/dist/{chunk-RZEXHDCF.js → chunk-MYM5VIJ4.js} +14 -3
  39. package/dist/chunk-MYM5VIJ4.js.map +1 -0
  40. package/dist/{chunk-HDQG3QYV.js → chunk-ON7PZNYV.js} +42 -26
  41. package/dist/chunk-ON7PZNYV.js.map +1 -0
  42. package/dist/chunk-Q4UQ73NA.js +6 -0
  43. package/dist/{chunk-WQE4OIZS.js.map → chunk-Q4UQ73NA.js.map} +1 -1
  44. package/dist/{chunk-PMYWZRRS.js → chunk-RBIRXQR6.js} +21 -3
  45. package/dist/chunk-RBIRXQR6.js.map +1 -0
  46. package/dist/{chunk-TCJTQGAO.js → chunk-RGEVBSLK.js} +3 -3
  47. package/dist/{chunk-TCJTQGAO.js.map → chunk-RGEVBSLK.js.map} +1 -1
  48. package/dist/chunk-TJ3WIJ7H.js +216 -0
  49. package/dist/chunk-TJ3WIJ7H.js.map +1 -0
  50. package/dist/chunk-VOEYUAER.js +203 -0
  51. package/dist/chunk-VOEYUAER.js.map +1 -0
  52. package/dist/{chunk-PRGCCW7D.js → chunk-WBMMRERH.js} +3 -3
  53. package/dist/{chunk-PRGCCW7D.js.map → chunk-WBMMRERH.js.map} +1 -1
  54. package/dist/{chunk-6HX47EBL.js → chunk-X634FZVG.js} +3 -3
  55. package/dist/{chunk-6HX47EBL.js.map → chunk-X634FZVG.js.map} +1 -1
  56. package/dist/cli.js +563 -340
  57. package/dist/cli.js.map +1 -1
  58. package/dist/{fs-6JKZNQ3U.js → fs-HNR6LAI7.js} +3 -3
  59. package/dist/fs-HNR6LAI7.js.map +1 -0
  60. package/dist/{graph-backend-GBL33GMW.js → graph-backend-G5Y6QQV4.js} +4 -4
  61. package/dist/{graph-backend-GBL33GMW.js.map → graph-backend-G5Y6QQV4.js.map} +1 -1
  62. package/dist/index.d.ts +1 -1
  63. package/dist/index.js +12 -10
  64. package/dist/index.js.map +1 -1
  65. package/dist/{interactive-HLGJJFLI.js → interactive-NJG6467J.js} +27 -24
  66. package/dist/interactive-NJG6467J.js.map +1 -0
  67. package/dist/{llm-host-5RE34322.js → llm-host-DZBD5D36.js} +5 -5
  68. package/dist/{llm-host-5RE34322.js.map → llm-host-DZBD5D36.js.map} +1 -1
  69. package/dist/load-YPSEDYIW.js +10 -0
  70. package/dist/{load-4MLIHGXF.js.map → load-YPSEDYIW.js.map} +1 -1
  71. package/dist/rules-ASYEUNB5.js +74 -0
  72. package/dist/rules-ASYEUNB5.js.map +1 -0
  73. package/dist/run-outcome-5FQWHWYK.js +253 -0
  74. package/dist/run-outcome-5FQWHWYK.js.map +1 -0
  75. package/dist/runtime-session-Y4ZD3QDO.js +20 -0
  76. package/dist/{runtime-session-5M6QZZOS.js.map → runtime-session-Y4ZD3QDO.js.map} +1 -1
  77. package/dist/{session-2JT4AUZT.js → session-3OBIQLE4.js} +5 -5
  78. package/dist/{session-2JT4AUZT.js.map → session-3OBIQLE4.js.map} +1 -1
  79. package/dist/{stream-json-Y45JBNYP.js → stream-json-3YOPU3LF.js} +82 -10
  80. package/dist/stream-json-3YOPU3LF.js.map +1 -0
  81. package/dist/{vg-mcp-bridge-ZCKBYQ2D.js → vg-mcp-bridge-PZFGTZSA.js} +8 -7
  82. package/dist/vg-mcp-bridge-PZFGTZSA.js.map +1 -0
  83. package/dist/{vgd-TGGEAGQZ.js → vgd-DH7AHQ23.js} +9 -8
  84. package/dist/vgd-DH7AHQ23.js.map +1 -0
  85. package/package.json +1 -1
  86. package/dist/baseline-UOTGTJYT.js +0 -9
  87. package/dist/chunk-2ZHWF7C6.js.map +0 -1
  88. package/dist/chunk-67YG3R5F.js.map +0 -1
  89. package/dist/chunk-74ZMAOVF.js.map +0 -1
  90. package/dist/chunk-CYC3ZI32.js.map +0 -1
  91. package/dist/chunk-G4HTI4ZM.js.map +0 -1
  92. package/dist/chunk-GI6W53LM.js.map +0 -1
  93. package/dist/chunk-HDQG3QYV.js.map +0 -1
  94. package/dist/chunk-JIBOJTGS.js.map +0 -1
  95. package/dist/chunk-P3QIO4ZU.js.map +0 -1
  96. package/dist/chunk-PMYWZRRS.js.map +0 -1
  97. package/dist/chunk-PXXVLX7K.js.map +0 -1
  98. package/dist/chunk-QDZ47G45.js.map +0 -1
  99. package/dist/chunk-RZEXHDCF.js.map +0 -1
  100. package/dist/chunk-WQE4OIZS.js +0 -6
  101. package/dist/fs-6JKZNQ3U.js.map +0 -1
  102. package/dist/interactive-HLGJJFLI.js.map +0 -1
  103. package/dist/load-4MLIHGXF.js +0 -9
  104. package/dist/runtime-session-5M6QZZOS.js +0 -19
  105. package/dist/stream-json-Y45JBNYP.js.map +0 -1
  106. package/dist/vg-mcp-bridge-ZCKBYQ2D.js.map +0 -1
  107. package/dist/vgd-TGGEAGQZ.js.map +0 -1
package/dist/cli.js CHANGED
@@ -1,48 +1,52 @@
1
1
  #!/usr/bin/env node
2
- import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, fetchCatalog, resolveProviders, runBuild } from './chunk-QDZ47G45.js';
3
- export { runBuild } from './chunk-QDZ47G45.js';
4
- import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-2ZHWF7C6.js';
5
- import { loadAdvancedScanHook, baselineCommand } from './chunk-F6ZPUKED.js';
6
- import { runCodeSession } from './chunk-PRGCCW7D.js';
7
- import { summarizeDiffs, ScriptedProvider } from './chunk-RZEXHDCF.js';
2
+ import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, readGlobal, applyGlobalOptions, ProgressBar, printLogo, fetchCatalog, resolveProviders, runBuild } from './chunk-EKCNSRNJ.js';
3
+ export { runBuild } from './chunk-EKCNSRNJ.js';
4
+ import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-TJ3WIJ7H.js';
5
+ import { loadAdvancedScanHook, baselineCommand } from './chunk-6WNJJXFY.js';
6
+ import { buildModelInstallPlan } from './chunk-WHJMS7XC.js';
7
+ import { runCodeSession } from './chunk-WBMMRERH.js';
8
8
  import { disableColor, info, c, json, out } from './chunk-CT5BS56U.js';
9
- import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-74ZMAOVF.js';
9
+ import { VGD_PROTOCOL_VERSION, startVgdServer } from './chunk-CQDCZQFV.js';
10
10
  import './chunk-5I4VSBWQ.js';
11
11
  import './chunk-IS7VTH2Q.js';
12
12
  import { init_resolve_ollama, gatherSystemMemory, resolveOllamaBinary, hasOllamaBinary, resolve_ollama_exports } from './chunk-OWSFZQOP.js';
13
13
  import { readOrchestratorState, writeOrchestratorState, parseMode, setDefaultMode, recommendMode, activePin, resolveMode, providerForBackend, QUALIFIED_PACKS, pinPack, unpinPack, buildOrchestratorStatus } from './chunk-NZELMYT4.js';
14
14
  import { fmt, estimateModelBytes } from './chunk-7N4Y3E47.js';
15
15
  import './chunk-IZDH67DX.js';
16
- import './chunk-TCJTQGAO.js';
17
- import { vgdIsRunning, vgdRequest, vgdSocketPath } from './chunk-PMYWZRRS.js';
18
- import { defaultProcessEndpoint, startProcessHostServer, resolveInferenceIsolation } from './chunk-SIPGDJT4.js';
19
- import { clearHostSessionPool, acquireHostSession, generateOnSession, listHostSessions, hostSessionPoolSize } from './chunk-6HX47EBL.js';
20
- import { buildIdentifierTrieFromGraph } from './chunk-JIBOJTGS.js';
21
- import './chunk-7AVYKZEM.js';
22
- import { buildModelInstallPlan } from './chunk-WHJMS7XC.js';
16
+ import { defaultProcessEndpoint, startProcessHostServer, resolveInferenceIsolation } from './chunk-EVLS2M5G.js';
17
+ import { clearHostSessionPool, acquireHostSession, generateOnSession, listHostSessions, hostSessionPoolSize } from './chunk-X634FZVG.js';
18
+ import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-KGWEBM2J.js';
19
+ import './chunk-543E6WDJ.js';
20
+ import { summarizeDiffs, ScriptedProvider } from './chunk-MYM5VIJ4.js';
23
21
  import { ensurePackage, ensureUnavailableMessage } from './chunk-REIGWTTH.js';
24
- import { serveStdio, exportGraph, GraphSource, createServer, formatForExt } from './chunk-PXXVLX7K.js';
25
- import { CliError, ExitCode, refreshIfStale, driftCount, ASSISTANTS, detectAssistants, usageError, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, buildGraph, writeSnapshot, probeFreshness, discover, assistantById, SMALL_REPO_FILES, SKIP_DIRS, SKIP_FILES } from './chunk-CYC3ZI32.js';
26
- import { resolveDsn, resolveIngestHost, dashHostForIngestHost, availableRegionIds, createWorkspaceDsn, writeStoredCredentials, credentialsPath, findGitRoot, ensureGitignored, gitignoreEntryForCredentials, clearStoredCredentials, parseDsn as parseDsn$1, uploadScanArtifact, ingestHostForRegionId, dsnCommand, pushCommand, countTokens, shortestPath, pathDisconnect, testsToRun, detectRunner, coveringTests, FREE_PACK, readScanArtifact, publishPrivateLibrary, assessDocQuality, symbolsFromApi, fetchHostedDocsCached, selectForBudget, hostedBase, readStoredCredentials, projectCredentialsPath, homeCredentialsPath } from './chunk-67YG3R5F.js';
22
+ import './chunk-RGEVBSLK.js';
23
+ import { vgdSocketPath, vgdIsRunning, vgdRequest, vgdPidPath } from './chunk-RBIRXQR6.js';
24
+ import { buildIdentifierTrieFromGraph } from './chunk-5HYCB55P.js';
25
+ import './chunk-7AVYKZEM.js';
26
+ import { serveStdio, exportGraph, GraphSource, createServer, formatForExt } from './chunk-CFL3QQQZ.js';
27
+ import { CliError, ExitCode, refreshIfStale, driftCount, ASSISTANTS, detectAssistants, usageError, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, buildGraph, writeSnapshot, probeFreshness, discover, assistantById, SMALL_REPO_FILES, SKIP_DIRS, SKIP_FILES } from './chunk-GLT3N7T2.js';
28
+ 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-6D4BCGRQ.js';
29
+ import { resolveIngestHost, dashHostForIngestHost, availableRegionIds, ingestHostForRegionId } from './chunk-HTLDXEHW.js';
30
+ 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 } from './chunk-ON7PZNYV.js';
31
+ import { ensureDir, pathExists, readJsonFile, writeTextFile, writeJsonFile } from './chunk-CRAMOEBE.js';
27
32
  import './chunk-IPICO2RV.js';
28
- import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-G4HTI4ZM.js';
29
- 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 } from './chunk-HDQG3QYV.js';
33
+ import { inventory, enrichOnline, ECOSYSTEMS, catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-FHJBGPJZ.js';
30
34
  import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-US2DAKCM.js';
31
- import { ensureDir, pathExists, readJsonFile, writeTextFile, writeJsonFile } from './chunk-CRAMOEBE.js';
35
+ import { init_cli_invocation, resolveCliInvocation, NPX_INVOCATION } from './chunk-3LSG7Z4I.js';
32
36
  import { resolveOne } from './chunk-J7LKEB2R.js';
33
37
  import { embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, queryGraphSemantic, queryGraph, unavailableMessage, countPending, indexFor, impactOf, modelCacheInfo, clearModelCache } from './chunk-EETK7S43.js';
34
38
  import { discoverModels } from './chunk-CQDUBAQY.js';
35
- import { init_cli_invocation, resolveCliInvocation, NPX_INVOCATION } from './chunk-3LSG7Z4I.js';
36
39
  import { freeBytesOnVolume, weightStoreDir, listCachedWeights, ensureWeightCached, catalogIntegrityReport } from './chunk-OV4KGXPD.js';
37
40
  import { resolvedGrammarFiles, grammarSetVersion } from './chunk-UTNNGKKX.js';
38
41
  import './chunk-RXP66R2E.js';
39
- import { resolveGraphPath, renderReport, loadGraph, loadGraphFileWithSnapshot, writeArtifacts, vibgrateDir, mapFileExists, SCHEMA_VERSION } from './chunk-P3QIO4ZU.js';
40
- import { VERSION } from './chunk-WQE4OIZS.js';
42
+ import { loadGraph, SCHEMA_VERSION } from './chunk-VOEYUAER.js';
43
+ import { resolveGraphPath, renderReport, loadGraphFileWithSnapshot, writeArtifacts, vibgrateDir, mapFileExists, ensureVibgrateGitignore } from './chunk-5G7C6H2G.js';
44
+ import { VERSION } from './chunk-Q4UQ73NA.js';
41
45
  import { cacheDir, serializeGraph, stableStringify } from './chunk-ZKNB4YH4.js';
42
46
  import './chunk-BWPBB45M.js';
43
47
  import { canonicalize, hashString, hashBytes } from './chunk-JFGYT6BI.js';
44
48
  import './chunk-BPF3YX2U.js';
45
- import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-GI6W53LM.js';
49
+ import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-IDAQV3NQ.js';
46
50
  import { __toCommonJS } from './chunk-Z6ZWNWWR.js';
47
51
  import * as fs7 from 'fs';
48
52
  import fs7__default, { realpathSync } from 'fs';
@@ -50,15 +54,15 @@ import * as path37 from 'path';
50
54
  import path37__default from 'path';
51
55
  import { fileURLToPath, pathToFileURL } from 'url';
52
56
  import { Command, CommanderError, Option } from 'commander';
53
- import * as os from 'os';
54
- import * as crypto3 from 'crypto';
55
- import { randomUUID } from 'crypto';
56
57
  import * as semver3 from 'semver';
57
58
  import semver3__default from 'semver';
58
59
  import { execSync, spawn, spawnSync, execFileSync } from 'child_process';
59
60
  import * as readline from 'readline';
61
+ import * as crypto3 from 'crypto';
62
+ import { randomUUID } from 'crypto';
60
63
  import chalk7 from 'chalk';
61
- import * as fs20 from 'fs/promises';
64
+ import * as fs21 from 'fs/promises';
65
+ import * as os from 'os';
62
66
 
63
67
  init_cli_invocation();
64
68
  function registerStatus(program) {
@@ -837,210 +841,6 @@ function fmtRef(r) {
837
841
  function pad2(s, n) {
838
842
  return s.padStart(n, " ");
839
843
  }
840
- var SCHEMA_VERSION2 = "1";
841
- var OFFSET_FILE = "stats-share.json";
842
- var INSTALL_ID_DIR = path37.join(os.homedir(), ".vibgrate");
843
- var INSTALL_ID_FILE = path37.join(INSTALL_ID_DIR, "install-id");
844
- var SEND_TIMEOUT_MS = 4e3;
845
- function telemetryOptOut(env = process.env) {
846
- const dnt = (env.DO_NOT_TRACK ?? "").trim().toLowerCase();
847
- if (dnt !== "" && dnt !== "0" && dnt !== "false") return "DO_NOT_TRACK";
848
- const vt = (env.VIBGRATE_TELEMETRY ?? "").trim().toLowerCase();
849
- if (vt === "0" || vt === "false" || vt === "off") return "VIBGRATE_TELEMETRY";
850
- return null;
851
- }
852
- var CI_ENV_VARS = [
853
- "CI",
854
- "GITHUB_ACTIONS",
855
- "GITLAB_CI",
856
- "CIRCLECI",
857
- "TRAVIS",
858
- "BUILDKITE",
859
- "JENKINS_URL",
860
- "TF_BUILD"
861
- ];
862
- function isCI(env = process.env) {
863
- return CI_ENV_VARS.some((v) => {
864
- const val = (env[v] ?? "").trim().toLowerCase();
865
- return val !== "" && val !== "0" && val !== "false";
866
- });
867
- }
868
- function installId(env = process.env) {
869
- if (telemetryOptOut(env) !== null || isCI(env)) return randomUuid();
870
- try {
871
- const existing = fs7.readFileSync(INSTALL_ID_FILE, "utf8").trim();
872
- if (isUuid(existing)) return existing;
873
- } catch {
874
- }
875
- const id = randomUuid();
876
- try {
877
- fs7.mkdirSync(INSTALL_ID_DIR, { recursive: true });
878
- fs7.writeFileSync(INSTALL_ID_FILE, id + "\n", { mode: 384 });
879
- } catch {
880
- }
881
- return id;
882
- }
883
- function isUuid(s) {
884
- return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s);
885
- }
886
- function randomUuid() {
887
- return randomUUID();
888
- }
889
- function statsEndpoint() {
890
- const override = process.env.VIBGRATE_STATS_ENDPOINT;
891
- if (override && /^https?:\/\//.test(override)) return override;
892
- return `https://${resolveIngestHost()}/v1/ingest/cli-mcp-usage`;
893
- }
894
- function offsetPath(root2) {
895
- return path37.join(cacheDir(root2), OFFSET_FILE);
896
- }
897
- function ledgerFilePath(root2) {
898
- return path37.join(cacheDir(root2), "savings.jsonl");
899
- }
900
- function readOffset(root2) {
901
- try {
902
- const raw = JSON.parse(fs7.readFileSync(offsetPath(root2), "utf8"));
903
- return typeof raw.offset === "number" && raw.offset >= 0 ? raw.offset : 0;
904
- } catch {
905
- return 0;
906
- }
907
- }
908
- function writeOffset(root2, offset) {
909
- try {
910
- fs7.mkdirSync(cacheDir(root2), { recursive: true });
911
- fs7.writeFileSync(offsetPath(root2), JSON.stringify({ offset }) + "\n");
912
- } catch {
913
- }
914
- }
915
- function buildBatch(root2, fromOffset, id = installId()) {
916
- const file = ledgerFilePath(root2);
917
- let size = 0;
918
- try {
919
- size = fs7.statSync(file).size;
920
- } catch {
921
- return { batch: null, newOffset: 0 };
922
- }
923
- const start = fromOffset > size ? 0 : fromOffset;
924
- if (start >= size) return { batch: null, newOffset: size };
925
- let text = "";
926
- try {
927
- const fd = fs7.openSync(file, "r");
928
- try {
929
- const buf = Buffer.alloc(size - start);
930
- fs7.readSync(fd, buf, 0, buf.length, start);
931
- text = buf.toString("utf8");
932
- } finally {
933
- fs7.closeSync(fd);
934
- }
935
- } catch {
936
- return { batch: null, newOffset: fromOffset };
937
- }
938
- const lastNl = text.lastIndexOf("\n");
939
- if (lastNl < 0) return { batch: null, newOffset: start };
940
- const consumed = start + lastNl + 1;
941
- const rows = /* @__PURE__ */ new Map();
942
- let total = 0;
943
- let minTs = Infinity;
944
- let maxTs = -Infinity;
945
- for (const line of text.slice(0, lastNl).split("\n")) {
946
- if (!line.trim()) continue;
947
- let e;
948
- try {
949
- e = JSON.parse(line);
950
- } catch {
951
- continue;
952
- }
953
- const source = e.source ?? "mcp";
954
- const client = e.client ?? "unknown";
955
- const outcome = e.outcome ?? "complete";
956
- const key2 = `${source}|${client}|${e.tool}|${outcome}`;
957
- const row = rows.get(key2) ?? {
958
- source,
959
- client,
960
- tool: e.tool,
961
- outcome,
962
- calls: 0,
963
- vgTokens: 0,
964
- baselineTokens: 0
965
- };
966
- row.calls++;
967
- row.vgTokens += e.vgTokens ?? 0;
968
- row.baselineTokens += e.baselineTokens ?? 0;
969
- rows.set(key2, row);
970
- total++;
971
- if (typeof e.ts === "number") {
972
- if (e.ts < minTs) minTs = e.ts;
973
- if (e.ts > maxTs) maxTs = e.ts;
974
- }
975
- }
976
- if (total === 0 || !Number.isFinite(minTs)) return { batch: null, newOffset: consumed };
977
- const batch = {
978
- schemaVersion: SCHEMA_VERSION2,
979
- installId: id,
980
- vgVersion: VERSION,
981
- os: process.platform,
982
- arch: process.arch,
983
- windowStart: new Date(minTs).toISOString(),
984
- windowEnd: new Date(maxTs).toISOString(),
985
- totalCalls: total,
986
- rows: [...rows.values()]
987
- };
988
- return { batch, newOffset: consumed };
989
- }
990
- async function postBatch(batch) {
991
- const controller = new AbortController();
992
- const timer = setTimeout(() => controller.abort(), SEND_TIMEOUT_MS);
993
- timer.unref?.();
994
- try {
995
- const res = await fetch(statsEndpoint(), {
996
- method: "POST",
997
- headers: { "Content-Type": "application/json", Connection: "close" },
998
- body: JSON.stringify(batch),
999
- signal: controller.signal
1000
- });
1001
- return res.ok;
1002
- } catch {
1003
- return false;
1004
- } finally {
1005
- clearTimeout(timer);
1006
- }
1007
- }
1008
- var StatsSharer = class {
1009
- constructor(root2) {
1010
- this.root = root2;
1011
- this.offset = readOffset(root2);
1012
- }
1013
- root;
1014
- id = installId();
1015
- offset;
1016
- flushing = false;
1017
- /**
1018
- * Flush any new ledger entries. Single-flight (a slow POST won't overlap the
1019
- * next tick). Best-effort: any failure is swallowed and retried next time.
1020
- */
1021
- async flush() {
1022
- if (this.flushing) return;
1023
- this.flushing = true;
1024
- try {
1025
- const { batch, newOffset } = buildBatch(this.root, this.offset, this.id);
1026
- if (!batch) {
1027
- if (newOffset > this.offset) {
1028
- this.offset = newOffset;
1029
- writeOffset(this.root, newOffset);
1030
- }
1031
- return;
1032
- }
1033
- const ok = await postBatch(batch);
1034
- if (ok) {
1035
- this.offset = newOffset;
1036
- writeOffset(this.root, newOffset);
1037
- }
1038
- } catch {
1039
- } finally {
1040
- this.flushing = false;
1041
- }
1042
- }
1043
- };
1044
844
 
1045
845
  // src/util/origin.ts
1046
846
  function originAllowed(origin, allowlist) {
@@ -1956,6 +1756,67 @@ function writeScanCache(root2, key2, artifact) {
1956
1756
  } catch {
1957
1757
  }
1958
1758
  }
1759
+ var MAX_ENTRIES = 1e3;
1760
+ var KEEP_ENTRIES = 500;
1761
+ function historyPath(root2) {
1762
+ return path37.join(root2, ".vibgrate", "score-history.jsonl");
1763
+ }
1764
+ function parseLine(line) {
1765
+ try {
1766
+ const e = JSON.parse(line);
1767
+ if (typeof e.ts === "string" && typeof e.score === "number" && typeof e.band === "string" && (e.mode === "verified" || e.mode === "estimated") && typeof e.methodology === "string") {
1768
+ return e;
1769
+ }
1770
+ } catch {
1771
+ }
1772
+ return null;
1773
+ }
1774
+ function readHistory(root2) {
1775
+ try {
1776
+ return fs7.readFileSync(historyPath(root2), "utf8").split("\n").filter((l) => l.trim()).map(parseLine).filter((e) => e !== null);
1777
+ } catch {
1778
+ return [];
1779
+ }
1780
+ }
1781
+ function lastEntry(root2) {
1782
+ const all = readHistory(root2);
1783
+ return all.length ? all[all.length - 1] : null;
1784
+ }
1785
+ function recentHistory(root2, days, now = Date.now()) {
1786
+ const cutoff = now - days * 24 * 60 * 60 * 1e3;
1787
+ return readHistory(root2).filter((e) => {
1788
+ const t = Date.parse(e.ts);
1789
+ return Number.isFinite(t) && t >= cutoff;
1790
+ });
1791
+ }
1792
+ function recordScore(root2, entry) {
1793
+ try {
1794
+ const prev = lastEntry(root2);
1795
+ if (prev && prev.score === entry.score && prev.band === entry.band && prev.mode === entry.mode && prev.methodology === entry.methodology) {
1796
+ const prevT = Date.parse(prev.ts);
1797
+ const nextT = Date.parse(entry.ts);
1798
+ if (Number.isFinite(prevT) && Number.isFinite(nextT) && nextT - prevT < 24 * 60 * 60 * 1e3) {
1799
+ return;
1800
+ }
1801
+ }
1802
+ const file = historyPath(root2);
1803
+ fs7.mkdirSync(path37.dirname(file), { recursive: true });
1804
+ ensureVibgrateGitignore(root2);
1805
+ fs7.appendFileSync(file, `${JSON.stringify(entry)}
1806
+ `);
1807
+ const all = readHistory(root2);
1808
+ if (all.length > MAX_ENTRIES) {
1809
+ const kept = all.slice(-KEEP_ENTRIES);
1810
+ fs7.writeFileSync(file, kept.map((e) => JSON.stringify(e)).join("\n") + "\n");
1811
+ }
1812
+ } catch {
1813
+ }
1814
+ }
1815
+ function deltaFrom(prev, current) {
1816
+ if (!prev) return void 0;
1817
+ if (prev.methodology !== current.methodology) return void 0;
1818
+ return current.score - prev.score;
1819
+ }
1959
1820
 
1960
1821
  // src/lsp/graph-query.ts
1961
1822
  async function runGraphQuery(graph, params, ctx) {
@@ -2408,6 +2269,12 @@ var VibgrateLanguageServer = class {
2408
2269
  artifact = null;
2409
2270
  scanning = false;
2410
2271
  queued = false;
2272
+ /**
2273
+ * Sticky until the next `scan()` runs: set by explicit "Rescan Workspace"
2274
+ * (and preserved if a non-force schedule races the debounce). Bypasses the
2275
+ * LSP scan cache so config/SKIP_DIRS changes actually re-score.
2276
+ */
2277
+ forceNextScan = false;
2411
2278
  debounce = null;
2412
2279
  shuttingDown = false;
2413
2280
  graph = null;
@@ -2467,12 +2334,17 @@ var VibgrateLanguageServer = class {
2467
2334
  this.conn.onRequest("textDocument/codeLens", (_m, params) => this.onCodeLens(params));
2468
2335
  this.conn.onRequest("vibgrate/graph/query", (_m, params) => this.onGraphQuery(params));
2469
2336
  this.conn.onRequest("vibgrate/score/forFile", (_m, params) => this.onScoreForFile(params));
2337
+ this.conn.onRequest("vibgrate/score/history", (_m, params) => {
2338
+ const p = params;
2339
+ const days = typeof p?.days === "number" && p.days > 0 && p.days <= 365 ? p.days : 90;
2340
+ return { days, entries: recentHistory(this.opts.root, days) };
2341
+ });
2470
2342
  this.conn.onRequest("vibgrate/enrich", (_m, params) => this.onEnrich(params));
2471
2343
  this.conn.onRequest("vibgrate/vulns", (_m, _params) => this.onVulns());
2472
2344
  this.conn.onRequest("workspace/executeCommand", (_m, params) => {
2473
2345
  const p = params;
2474
2346
  if (p.command === "vibgrate.rescan") {
2475
- this.scheduleScan(0);
2347
+ this.scheduleScan(0, { force: true });
2476
2348
  return { ok: true };
2477
2349
  }
2478
2350
  return null;
@@ -2487,7 +2359,8 @@ var VibgrateLanguageServer = class {
2487
2359
  });
2488
2360
  }
2489
2361
  // ── Scanning ─────────────────────────────────────────────────────────────
2490
- scheduleScan(delayMs) {
2362
+ scheduleScan(delayMs, opts) {
2363
+ if (opts?.force) this.forceNextScan = true;
2491
2364
  if (this.debounce) clearTimeout(this.debounce);
2492
2365
  this.debounce = setTimeout(() => void this.scan(), delayMs);
2493
2366
  }
@@ -2497,11 +2370,13 @@ var VibgrateLanguageServer = class {
2497
2370
  return;
2498
2371
  }
2499
2372
  this.scanning = true;
2373
+ const force = this.forceNextScan;
2374
+ this.forceNextScan = false;
2500
2375
  try {
2501
2376
  const cacheKey = { manifestHash: manifestHash(this.opts.root), toolVersion: VERSION, offline: this.opts.offline };
2502
- const cached = loadScanCache(this.opts.root, cacheKey);
2377
+ const cached = force ? null : loadScanCache(this.opts.root, cacheKey);
2503
2378
  if (cached) {
2504
- this.artifact = cached.artifact;
2379
+ this.artifact = pruneArtifactProjects(cached.artifact);
2505
2380
  } else {
2506
2381
  const scanOpts = {
2507
2382
  format: "json",
@@ -2516,7 +2391,7 @@ var VibgrateLanguageServer = class {
2516
2391
  vibgrateVersion: VERSION
2517
2392
  };
2518
2393
  const advanced = await loadAdvancedScanHook();
2519
- this.artifact = await runCoreScan(this.opts.root, scanOpts, advanced);
2394
+ this.artifact = pruneArtifactProjects(await runCoreScan(this.opts.root, scanOpts, advanced));
2520
2395
  writeScanCache(this.opts.root, cacheKey, this.artifact);
2521
2396
  }
2522
2397
  this.publishScore();
@@ -2555,6 +2430,15 @@ var VibgrateLanguageServer = class {
2555
2430
  (f) => f.ruleId === "vibgrate/unmaintained" || f.ruleId === "vibgrate/abandoned"
2556
2431
  ).length;
2557
2432
  const band = a.drift.riskLevel ?? "low";
2433
+ const historyEntry = {
2434
+ ts: a.timestamp,
2435
+ score: a.drift.score,
2436
+ band,
2437
+ mode: a.drift.mode ?? (hasReleaseDates(a) ? "verified" : "estimated"),
2438
+ methodology: a.drift.methodologyVersion ?? "unknown"
2439
+ };
2440
+ const delta = deltaFrom(lastEntry(this.opts.root), historyEntry);
2441
+ recordScore(this.opts.root, historyEntry);
2558
2442
  const payload = {
2559
2443
  score: a.drift.score,
2560
2444
  band,
@@ -2562,13 +2446,15 @@ var VibgrateLanguageServer = class {
2562
2446
  // offline marker. An air-gapped scan against a dated snapshot is Verified.
2563
2447
  // The score now carries the authoritative provenance (driftscore-3.0
2564
2448
  // envelope); fall back to the artifact heuristic for pre-v3 engines.
2565
- mode: a.drift.mode ?? (hasReleaseDates(a) ? "verified" : "estimated"),
2566
- methodology: a.drift.methodologyVersion ?? "unknown",
2449
+ mode: historyEntry.mode,
2450
+ methodology: historyEntry.methodology,
2567
2451
  scale: "0 best, 100 worst",
2568
2452
  counts: { behind, eol, unmaintained, total },
2569
2453
  rootPath: a.rootPath,
2570
2454
  scannedAt: a.timestamp,
2571
- ...buildBreakdown(a.drift, a.projects ?? []) ? { breakdown: buildBreakdown(a.drift, a.projects ?? []) } : {}
2455
+ ...delta !== void 0 ? { delta } : {},
2456
+ ...buildBreakdown(a.drift, a.projects ?? []) ? { breakdown: buildBreakdown(a.drift, a.projects ?? []) } : {},
2457
+ ...buildEolHorizon(a.projects ?? []) ? { eolHorizon: buildEolHorizon(a.projects ?? []) } : {}
2572
2458
  };
2573
2459
  this.conn.notify("vibgrate/score", payload);
2574
2460
  }
@@ -2754,6 +2640,9 @@ var VibgrateLanguageServer = class {
2754
2640
  const reachedPkgs = packageReachSet(this.graph);
2755
2641
  const targets = [];
2756
2642
  for (const proj of a.projects ?? []) {
2643
+ if (isPrunedWorkspacePath(proj.path) || isPrunedWorkspacePath(manifestRelativePath(proj))) {
2644
+ continue;
2645
+ }
2757
2646
  const ecosystem = osvEcosystem(proj.type);
2758
2647
  if (!ecosystem) continue;
2759
2648
  const relManifest = manifestRelativePath(proj);
@@ -2805,6 +2694,24 @@ function uriToPath(uri) {
2805
2694
  return uri;
2806
2695
  }
2807
2696
  }
2697
+ function isPrunedWorkspacePath(relPath) {
2698
+ if (!relPath || relPath === "." || relPath === "") return false;
2699
+ const parts = relPath.split(/[/\\]/).filter(Boolean);
2700
+ if (parts.includes(".claude")) return true;
2701
+ return parts.some((p) => SKIP_DIRS.has(p));
2702
+ }
2703
+ function pruneArtifactProjects(a) {
2704
+ const projects = (a.projects ?? []).filter(
2705
+ (p) => !isPrunedWorkspacePath(p.path) && !isPrunedWorkspacePath(manifestRelativePath(p))
2706
+ );
2707
+ if (projects.length === (a.projects ?? []).length) {
2708
+ const findings2 = (a.findings ?? []).filter((f) => !isPrunedWorkspacePath(f.location));
2709
+ if (findings2.length === (a.findings ?? []).length) return a;
2710
+ return { ...a, findings: findings2 };
2711
+ }
2712
+ const findings = (a.findings ?? []).filter((f) => !isPrunedWorkspacePath(f.location));
2713
+ return { ...a, projects, findings };
2714
+ }
2808
2715
  function projectForFile(root2, a, filePath) {
2809
2716
  const dir = path37.dirname(path37.resolve(filePath));
2810
2717
  let best;
@@ -2852,9 +2759,31 @@ function scoreForProject(a, proj) {
2852
2759
  counts: { behind, eol, unmaintained, total },
2853
2760
  rootPath: proj.path,
2854
2761
  scannedAt: a.timestamp,
2855
- ...buildBreakdown(proj.drift, [proj]) ? { breakdown: buildBreakdown(proj.drift, [proj]) } : {}
2762
+ ...buildBreakdown(proj.drift, [proj]) ? { breakdown: buildBreakdown(proj.drift, [proj]) } : {},
2763
+ ...buildEolHorizon([proj]) ? { eolHorizon: buildEolHorizon([proj]) } : {}
2856
2764
  };
2857
2765
  }
2766
+ function runtimeHorizonLabel(project) {
2767
+ const kind = project.type === "node" ? "Node.js" : project.type === "dotnet" ? ".NET" : project.type === "python" ? "Python" : project.type === "java" ? "Java" : project.type;
2768
+ return project.runtime ? `${kind} ${project.runtime}` : kind;
2769
+ }
2770
+ function buildEolHorizon(projects, now = Date.now()) {
2771
+ const byLabel = /* @__PURE__ */ new Map();
2772
+ for (const p of projects) {
2773
+ if (!p.runtimeEolDate) continue;
2774
+ const t = Date.parse(p.runtimeEolDate);
2775
+ if (!Number.isFinite(t)) continue;
2776
+ const label = runtimeHorizonLabel(p);
2777
+ if (byLabel.has(label)) continue;
2778
+ byLabel.set(label, {
2779
+ runtime: label,
2780
+ eolDate: p.runtimeEolDate,
2781
+ daysUntil: Math.round((t - now) / (24 * 60 * 60 * 1e3))
2782
+ });
2783
+ }
2784
+ if (byLabel.size === 0) return void 0;
2785
+ return [...byLabel.values()].sort((a, b) => a.daysUntil - b.daysUntil).slice(0, 5);
2786
+ }
2858
2787
  function bandForScore(n) {
2859
2788
  if (n <= 30) return "low";
2860
2789
  if (n <= 60) return "moderate";
@@ -6122,7 +6051,7 @@ function discoverMcpServers(root2, ownServers) {
6122
6051
 
6123
6052
  // src/commands/code.ts
6124
6053
  function registerCode(program) {
6125
- const cmd = program.command("code").description("propose a graph-grounded code edit (guided mode with no instruction; dry-run by default)").argument("[instruction...]", "what to change, in plain language (omit for guided interactive mode)").option("--provider <id>", "backend: ollama, lmstudio, foundry-local, openrouter, litellm, openai, together, llama-cpp").option("--model <id>", "model id (or set VG_CODE_MODEL). No model is hard-coded \u2014 pick the current best.").option("--mode <mode>", "Code Mode: spark | flow | forge (preferred over raw model names; auto-fits when omitted and no --model)").option("--model-path <gguf>", "gguf path for --provider llama-cpp (weights are never auto-downloaded)").option("-f, --file <path>", "restrict the edit surface to this file (repeatable)", collect, []).option("-b, --budget <n>", "approx context token budget", "3000").option("--apply", "write the change (still requires --yes or an interactive confirm)").option("--yes", "consent to write / to a first-use package install, non-interactively").option("--auto", "autonomous agent: auto-approve every edit and command (use with care)").option("--max-steps <n>", "cap the number of agent steps", "24").option("--single", "one-shot planner (single edit) instead of the multi-step agent").option("--stream", "stream the model output live").option("--stream-json", "machine protocol: NDJSON agent events on stdout, approval decisions on stdin (for host UIs like the VS Code panel)").option("--verify [command]", "after the agent finishes, run tests and make it fix failures (uses the config testCommand if no command is given)").option("--continue", "resume the most recent session (recap + restore /undo)").option("--capsule", "use a source-bearing Task Capsule for first context (Fusion A/B; exact source ranges from the graph)").option("--no-capsule", "disable Task Capsule context even if enabled in .vibgrate/code.json").option("--security-tier <tier>", "shell isolation: L0 (host), L1 (Seatbelt/bubblewrap when available), L2/L3 reserved").option("--mock <file>", "use a scripted reply from <file> instead of a model (offline; for tests/CI)").option("-o, --out <file>", "write the JSON result to <file> (implies --json shape; for CI/benchmarks)").action(async function(instructionParts, opts) {
6054
+ const cmd = program.command("code").description("propose a graph-grounded code edit (guided mode with no instruction; dry-run by default)").argument("[instruction...]", "what to change, in plain language (omit for guided interactive mode)").option("--provider <id>", "backend: vibgrate-relay (Vibgrate Relay), ollama, lmstudio, foundry-local, openrouter, litellm, openai, together, llama-cpp").option("--model <id>", "model id (or set VG_CODE_MODEL). No model is hard-coded \u2014 pick the current best.").option("--mode <mode>", "Code Mode: spark | flow | forge (preferred over raw model names; auto-fits when omitted and no --model)").option("--model-path <gguf>", "gguf path for --provider llama-cpp (weights are never auto-downloaded)").option("-f, --file <path>", "restrict the edit surface to this file (repeatable)", collect, []).option("-b, --budget <n>", "approx context token budget", "3000").option("--apply", "write the change (still requires --yes or an interactive confirm)").option("--yes", "consent to write / to a first-use package install, non-interactively").option("--auto", "autonomous agent: auto-approve every edit and command (use with care)").option("--max-steps <n>", "cap the number of agent steps", "24").option("--single", "one-shot planner (single edit) instead of the multi-step agent").option("--stream", "stream the model output live").option("--stream-json", "machine protocol: NDJSON agent events on stdout, approval decisions on stdin (for host UIs like the VS Code panel)").option("--session", "with --stream-json: stay open for further turns (warm graph and tools) instead of exiting after one").option("--verify [command]", "after the agent finishes, run tests and make it fix failures (uses the config testCommand if no command is given)").option("--continue", "resume the most recent session (recap + restore /undo)").option("--capsule", "use a source-bearing Task Capsule for first context (Fusion A/B; exact source ranges from the graph)").option("--no-capsule", "disable Task Capsule context even if enabled in .vibgrate/code.json").option("--security-tier <tier>", "shell isolation: L0 (host), L1 (Seatbelt/bubblewrap when available), L2/L3 reserved").option("--mock <file>", "use a scripted reply from <file> instead of a model (offline; for tests/CI)").option("-o, --out <file>", "write the JSON result to <file> (implies --json shape; for CI/benchmarks)").action(async function(instructionParts, opts) {
6126
6055
  const global = readGlobal(this);
6127
6056
  const instruction = (instructionParts ?? []).join(" ").trim();
6128
6057
  const config = loadCodeConfig(rootOf(global));
@@ -6135,7 +6064,7 @@ function registerCode(program) {
6135
6064
  try {
6136
6065
  const { parseMode: parseMode2, resolveMode: resolveMode2, readOrchestratorState: readOrchestratorState2, activePin: activePin2 } = await import('./model-orchestrator-LHYPJBFH.js');
6137
6066
  const { gatherSystemMemory: gatherSystemMemory2 } = await import('./local-runtime-2ED33KK6.js');
6138
- const { loadGraph: loadGraph2 } = await import('./load-4MLIHGXF.js');
6067
+ const { loadGraph: loadGraph2 } = await import('./load-YPSEDYIW.js');
6139
6068
  const state = readOrchestratorState2();
6140
6069
  const mode = parseMode2(modeFlag) ?? state.defaultMode ?? void 0;
6141
6070
  const pin = mode ? activePin2(mode, state) : null;
@@ -6219,7 +6148,7 @@ function registerCode(program) {
6219
6148
  if (!(process.stdin.isTTY && process.stdout.isTTY)) {
6220
6149
  throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"` (guided mode needs an interactive terminal)');
6221
6150
  }
6222
- const { runInteractive } = await import('./interactive-HLGJJFLI.js');
6151
+ const { runInteractive } = await import('./interactive-NJG6467J.js');
6223
6152
  await runInteractive(
6224
6153
  rootOf(global),
6225
6154
  global,
@@ -6300,19 +6229,20 @@ function registerCode(program) {
6300
6229
  process.stdout.write(JSON.stringify(line) + "\n");
6301
6230
  };
6302
6231
  try {
6232
+ const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-5FQWHWYK.js');
6303
6233
  const primarySlug = route.providers[0]?.model.includes("/") ? route.providers[0].model.split("/")[0] : route.providers[0]?.id;
6304
- const { runCodeStreamJson } = await import('./stream-json-Y45JBNYP.js');
6305
- const { nodeCodeFs } = await import('./session-2JT4AUZT.js');
6234
+ const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-3YOPU3LF.js');
6235
+ const { nodeCodeFs } = await import('./session-3OBIQLE4.js');
6306
6236
  const readline5 = await import('readline');
6307
6237
  const child = await import('child_process');
6308
6238
  const { loadOrDiscoverFederation } = await import('./federation-MDQPO3PW.js');
6309
6239
  const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
6310
6240
  const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
6311
- const { startCodeRuntimeSession } = await import('./runtime-session-5M6QZZOS.js');
6312
- const { resolveGraphBackend } = await import('./graph-backend-GBL33GMW.js');
6241
+ const { startCodeRuntimeSession } = await import('./runtime-session-Y4ZD3QDO.js');
6242
+ const { resolveGraphBackend } = await import('./graph-backend-G5Y6QQV4.js');
6313
6243
  const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
6314
6244
  const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
6315
- const { vgdRequest: vgdRequest2 } = await import('./vgd-TGGEAGQZ.js');
6245
+ const { vgdRequest: vgdRequest2 } = await import('./vgd-DH7AHQ23.js');
6316
6246
  const federation = loadOrDiscoverFederation(root2);
6317
6247
  const modelProfile = mergeModelExecutionProfile(
6318
6248
  resolveModelExecutionProfile({
@@ -6329,6 +6259,18 @@ function registerCode(program) {
6329
6259
  const runtime = await startCodeRuntimeSession({ root: root2 });
6330
6260
  const git2 = detectGitRef(root2);
6331
6261
  const repositoryId = repositoryIdFromRoot(root2);
6262
+ const runOutcome = new RunOutcomeRecorder(
6263
+ root2,
6264
+ repositoryId,
6265
+ git2.ref || null,
6266
+ { mode: codeModeActive ? modeFlag : void 0, provider: primarySlug, model: route.providers[0]?.model },
6267
+ tier,
6268
+ !!auto
6269
+ );
6270
+ const emitAndRecord = (line) => {
6271
+ runOutcome.observe(line);
6272
+ emitStream(line);
6273
+ };
6332
6274
  if (runtime.socketPath && git2.ref) {
6333
6275
  try {
6334
6276
  await vgdRequest2(
@@ -6358,7 +6300,7 @@ ${res.stderr}` : ""),
6358
6300
  exitCode: res.status ?? 1
6359
6301
  };
6360
6302
  };
6361
- const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-ZCKBYQ2D.js');
6303
+ const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-PZFGTZSA.js');
6362
6304
  const vgBuiltin = createVgBuiltinMcpTools({
6363
6305
  getGraph: () => graph,
6364
6306
  root: root2,
@@ -6378,50 +6320,204 @@ ${res.stderr}` : ""),
6378
6320
  };
6379
6321
  }
6380
6322
  const externalTools = mergeExternalToolsets(vgBuiltin, projectMcp);
6323
+ const { createCheckpoint } = await import('./checkpoint-4WFZMKEO.js');
6324
+ const os4 = await import('os');
6325
+ const pathMod = await import('path');
6326
+ const checkpointIndex = pathMod.join(
6327
+ fs7.mkdtempSync(pathMod.join(os4.tmpdir(), "vg-code-cp-")),
6328
+ "index"
6329
+ );
6330
+ const gitRunner = (gitArgs, gitEnv) => {
6331
+ const res = child.spawnSync("git", gitArgs, {
6332
+ cwd: root2,
6333
+ encoding: "utf8",
6334
+ env: { ...process.env, ...gitEnv ?? {} },
6335
+ timeout: 3e4,
6336
+ maxBuffer: 32 * 1024 * 1024
6337
+ });
6338
+ return { stdout: res.stdout ?? "", exitCode: res.status ?? 1 };
6339
+ };
6340
+ const checkpointSessionId = `r${Date.now().toString(36)}`;
6341
+ let checkpointSeq = 0;
6342
+ const takeCheckpoint = (files) => createCheckpoint(gitRunner, {
6343
+ sessionId: checkpointSessionId,
6344
+ seq: ++checkpointSeq,
6345
+ files,
6346
+ indexFile: checkpointIndex
6347
+ });
6348
+ const { loadProjectRules, nodeRulesReader } = await import('./rules-ASYEUNB5.js');
6349
+ const projectRules = loadProjectRules(nodeRulesReader(root2));
6350
+ if (projectRules.sources.length && !global.quiet) {
6351
+ emitStream({
6352
+ event: "event",
6353
+ type: "notice",
6354
+ text: `project instructions: ${projectRules.sources.join(", ")}`
6355
+ });
6356
+ }
6357
+ const baseAgentOptions = {
6358
+ graph,
6359
+ root: root2,
6360
+ providers: route.providers,
6361
+ fsImpl: nodeCodeFs(root2),
6362
+ run,
6363
+ executionEnv,
6364
+ graphBackend,
6365
+ modelProfile,
6366
+ auto: !!auto,
6367
+ maxSteps,
6368
+ budget: modelProfile.capsuleBudgetTokens,
6369
+ contextBudget,
6370
+ denyCommands: config.denyCommands,
6371
+ testCommand: config.testCommand,
6372
+ stream: true,
6373
+ verify: verify3 ? { command: verify3.command, maxRounds: modelProfile.maxRepairRounds } : void 0,
6374
+ capsule,
6375
+ files: opts.file.length ? opts.file : void 0,
6376
+ worktreeOverlay: true,
6377
+ advancedMode: !capsule,
6378
+ externalTools,
6379
+ attribution: {
6380
+ client: "vg-code",
6381
+ provider: primarySlug,
6382
+ model: route.providers[0]?.model
6383
+ },
6384
+ now: () => Date.now(),
6385
+ projectRules: projectRules.rendered || void 0,
6386
+ checkpoint: takeCheckpoint
6387
+ };
6381
6388
  try {
6382
- await runCodeStreamJson({
6383
- graph,
6384
- root: root2,
6385
- instruction,
6386
- providers: route.providers,
6387
- fsImpl: nodeCodeFs(root2),
6388
- run,
6389
- executionEnv,
6390
- graphBackend,
6391
- modelProfile,
6392
- auto: !!auto,
6393
- maxSteps,
6394
- budget: modelProfile.capsuleBudgetTokens,
6395
- contextBudget,
6396
- denyCommands: config.denyCommands,
6397
- testCommand: config.testCommand,
6398
- stream: true,
6399
- verify: verify3 ? { command: verify3.command, maxRounds: modelProfile.maxRepairRounds } : void 0,
6400
- capsule,
6401
- files: opts.file.length ? opts.file : void 0,
6402
- worktreeOverlay: true,
6403
- advancedMode: !capsule,
6404
- externalTools,
6405
- attribution: {
6406
- client: "vg-code",
6407
- provider: primarySlug,
6408
- model: route.providers[0]?.model
6409
- },
6410
- now: () => Date.now(),
6411
- emit: emitStream,
6412
- bindDecisions: (session) => {
6413
- streamApprove = (action) => session.approve(action);
6414
- const rl = readline5.createInterface({ input: process.stdin });
6415
- rl.on("line", (raw) => {
6416
- try {
6417
- const msg = JSON.parse(raw);
6418
- if (typeof msg.approveId === "number") session.submitDecision(msg.approveId, !!msg.approve);
6419
- if (typeof msg.answerId === "number") session.submitAnswer(msg.answerId, String(msg.answer ?? ""));
6420
- } catch {
6421
- }
6389
+ if (opts.session) {
6390
+ const { runCodeStreamJsonSession } = await import('./stream-json-3YOPU3LF.js');
6391
+ const { runAgent: runAgent2 } = await import('./agent-33BMKWJC.js');
6392
+ const {
6393
+ loadLatestSession,
6394
+ newSession,
6395
+ recordTask,
6396
+ saveSession,
6397
+ summarizeSession
6398
+ } = await import('./session-store-O4XPXKOV.js');
6399
+ const resumedRecord = opts.continue ? loadLatestSession(root2) : void 0;
6400
+ let record = resumedRecord ?? newSession(
6401
+ `s${Date.now().toString(36)}`,
6402
+ primarySlug ?? route.providers[0]?.id ?? "unknown",
6403
+ route.providers[0]?.model ?? "unknown",
6404
+ Date.now()
6405
+ );
6406
+ const pendingTurns = [];
6407
+ let wakeTurn;
6408
+ let ended = false;
6409
+ const pushTurn = (instruction2) => {
6410
+ if (wakeTurn) {
6411
+ const wake = wakeTurn;
6412
+ wakeTurn = void 0;
6413
+ wake(instruction2);
6414
+ } else if (instruction2 !== null) {
6415
+ pendingTurns.push(instruction2);
6416
+ }
6417
+ };
6418
+ const nextTurn = () => {
6419
+ if (ended) return Promise.resolve(null);
6420
+ const queued = pendingTurns.shift();
6421
+ if (queued !== void 0) return Promise.resolve(queued);
6422
+ return new Promise((resolve21) => {
6423
+ wakeTurn = resolve21;
6422
6424
  });
6423
- }
6424
- });
6425
+ };
6426
+ let turnIndex = 0;
6427
+ await runCodeStreamJsonSession({
6428
+ emit: emitAndRecord,
6429
+ auto: !!auto,
6430
+ sessionId: record.id,
6431
+ resumed: !!resumedRecord,
6432
+ instruction,
6433
+ nextTurn,
6434
+ bindDecisions: (session) => {
6435
+ streamApprove = (action) => session.approve(action);
6436
+ const rl = readline5.createInterface({ input: process.stdin });
6437
+ rl.on("line", (raw) => {
6438
+ const msg = parseHostMessage(raw);
6439
+ if (!msg) return;
6440
+ if (msg.kind === "approve") {
6441
+ session.submitDecision(msg.id, msg.approve);
6442
+ runOutcome.noteDecision(msg.id, msg.approve);
6443
+ } else if (msg.kind === "answer") session.submitAnswer(msg.id, msg.answer);
6444
+ else if (msg.kind === "submit") pushTurn(msg.instruction);
6445
+ else if (msg.kind === "restore") {
6446
+ void import('./checkpoint-4WFZMKEO.js').then(({ restoreCheckpoint }) => {
6447
+ const outcome = restoreCheckpoint(gitRunner, {
6448
+ commit: msg.commit,
6449
+ files: msg.files
6450
+ });
6451
+ emitStream({ event: "checkpoint-restored", commit: msg.commit, ...outcome });
6452
+ });
6453
+ } else if (msg.kind === "cancel") {
6454
+ session.cancelTurn();
6455
+ runOutcome.cancelPending();
6456
+ } else if (msg.kind === "end") {
6457
+ ended = true;
6458
+ pushTurn(null);
6459
+ }
6460
+ });
6461
+ rl.on("close", () => {
6462
+ ended = true;
6463
+ session.cancelTurn();
6464
+ runOutcome.cancelPending();
6465
+ pushTurn(null);
6466
+ });
6467
+ },
6468
+ runTurn: ({ instruction: turnInstruction, priorSummary, signal, session }) => {
6469
+ turnIndex++;
6470
+ runOutcome.beginRun(turnRunId(record.id, turnIndex), turnInstruction);
6471
+ return runAgent2({
6472
+ ...baseAgentOptions,
6473
+ instruction: turnInstruction,
6474
+ priorSummary,
6475
+ signal,
6476
+ approve: session.approve,
6477
+ askUser: session.askUser,
6478
+ onEvent: session.onEvent
6479
+ });
6480
+ },
6481
+ onTurnEnd: (turn) => {
6482
+ record = recordTask(
6483
+ record,
6484
+ {
6485
+ instruction: turn.instruction,
6486
+ summary: turn.result?.finalText ?? "turn failed",
6487
+ changes: turn.result?.changes ?? [],
6488
+ stopped: turn.result?.stopped ?? "error"
6489
+ },
6490
+ Date.now()
6491
+ );
6492
+ saveSession(root2, record);
6493
+ return summarizeSession(record);
6494
+ }
6495
+ });
6496
+ } else {
6497
+ runOutcome.beginRun(newOneShotRunId(), instruction);
6498
+ await runCodeStreamJson({
6499
+ ...baseAgentOptions,
6500
+ instruction,
6501
+ emit: emitAndRecord,
6502
+ bindDecisions: (session) => {
6503
+ streamApprove = (action) => session.approve(action);
6504
+ const rl = readline5.createInterface({ input: process.stdin });
6505
+ rl.on("line", (raw) => {
6506
+ const msg = parseHostMessage(raw);
6507
+ if (!msg) return;
6508
+ if (msg.kind === "approve") {
6509
+ session.submitDecision(msg.id, msg.approve);
6510
+ runOutcome.noteDecision(msg.id, msg.approve);
6511
+ } else if (msg.kind === "answer") session.submitAnswer(msg.id, msg.answer);
6512
+ else if (msg.kind === "cancel") {
6513
+ session.cancelTurn();
6514
+ runOutcome.cancelPending();
6515
+ }
6516
+ });
6517
+ rl.on("close", () => runOutcome.cancelPending());
6518
+ }
6519
+ });
6520
+ }
6425
6521
  } finally {
6426
6522
  await disposeMcpStream?.();
6427
6523
  await runtime.dispose();
@@ -6440,8 +6536,8 @@ ${res.stderr}` : ""),
6440
6536
  if (!autonomous && !tty) {
6441
6537
  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).");
6442
6538
  }
6443
- const { agentTask } = await import('./interactive-HLGJJFLI.js');
6444
- const { nodeCodeFs } = await import('./session-2JT4AUZT.js');
6539
+ const { agentTask } = await import('./interactive-NJG6467J.js');
6540
+ const { nodeCodeFs } = await import('./session-3OBIQLE4.js');
6445
6541
  const { TtyPrompter } = await import('./ui-K7D3BCHD.js');
6446
6542
  let priorSummary;
6447
6543
  if (opts.continue) {
@@ -6450,7 +6546,7 @@ ${res.stderr}` : ""),
6450
6546
  if (prev) priorSummary = summarizeSession(prev);
6451
6547
  }
6452
6548
  const prompter = tty ? new TtyPrompter() : void 0;
6453
- const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-ZCKBYQ2D.js');
6549
+ const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-PZFGTZSA.js');
6454
6550
  const vgBuiltin = createVgBuiltinMcpTools({
6455
6551
  getGraph: () => graph,
6456
6552
  root: root2,
@@ -6474,11 +6570,11 @@ ${res.stderr}` : ""),
6474
6570
  const { loadFederation } = await import('./federation-MDQPO3PW.js');
6475
6571
  const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
6476
6572
  const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
6477
- const { startCodeRuntimeSession } = await import('./runtime-session-5M6QZZOS.js');
6478
- const { resolveGraphBackend } = await import('./graph-backend-GBL33GMW.js');
6573
+ const { startCodeRuntimeSession } = await import('./runtime-session-Y4ZD3QDO.js');
6574
+ const { resolveGraphBackend } = await import('./graph-backend-G5Y6QQV4.js');
6479
6575
  const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
6480
6576
  const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
6481
- const { vgdRequest: vgdRequest2 } = await import('./vgd-TGGEAGQZ.js');
6577
+ const { vgdRequest: vgdRequest2 } = await import('./vgd-DH7AHQ23.js');
6482
6578
  const federation = loadFederation(root2);
6483
6579
  const modelProfile = mergeModelExecutionProfile(
6484
6580
  resolveModelExecutionProfile({
@@ -7194,7 +7290,9 @@ function registerDaemon(program) {
7194
7290
  if (await vgdIsRunning({ socketPath })) {
7195
7291
  throw new CliError(`vgd is already running at ${socketPath}`, ExitCode.ERROR);
7196
7292
  }
7197
- const server = await startVgdServer({ socketPath });
7293
+ let requestShutdown = () => {
7294
+ };
7295
+ const server = await startVgdServer({ socketPath, onShutdownRequest: () => requestShutdown() });
7198
7296
  if (!global.quiet) {
7199
7297
  info(`vgd \xB7 listening on ${c.dim(server.socketPath)} (${VGD_PROTOCOL_VERSION})`);
7200
7298
  info(c.dim(" register a workspace: vg daemon register"));
@@ -7205,6 +7303,7 @@ function registerDaemon(program) {
7205
7303
  if (!global.quiet) info(c.dim("vgd \xB7 stopped"));
7206
7304
  process.exit(0);
7207
7305
  };
7306
+ requestShutdown = () => void shutdown();
7208
7307
  process.on("SIGINT", () => void shutdown());
7209
7308
  process.on("SIGTERM", () => void shutdown());
7210
7309
  await new Promise(() => {
@@ -7224,29 +7323,66 @@ function registerDaemon(program) {
7224
7323
  }
7225
7324
  return;
7226
7325
  }
7227
- const child = spawnDetachedDaemonStart(socketPath);
7228
- child.unref();
7229
- const deadline = Date.now() + 8e3;
7230
- let ready = false;
7231
- while (Date.now() < deadline) {
7232
- await sleep(100);
7233
- if (await vgdIsRunning({ socketPath })) {
7234
- ready = true;
7235
- break;
7236
- }
7237
- }
7238
- if (!ready) {
7239
- throw new CliError(`vgd failed to become ready at ${socketPath}`, ExitCode.ERROR);
7240
- }
7326
+ const child = await startDetachedVgd(socketPath);
7241
7327
  const res = await vgdRequest({ op: "status" }, { socketPath });
7242
7328
  if (global.json) {
7243
7329
  json({ running: true, ensured: true, ...res.ok ? res : { socketPath } });
7244
7330
  } else if (!global.quiet) {
7245
- const pid = res.ok && "pid" in res ? res.pid : child.pid;
7331
+ const pid = res.ok && "pid" in res ? res.pid : child;
7246
7332
  info(`vgd \xB7 started in background pid ${pid} \xB7 ${c.dim(socketPath)}`);
7247
7333
  }
7248
7334
  });
7249
7335
  applyGlobalOptions(ensure);
7336
+ const stop = cmd.command("stop").description("stop the running vgd (idempotent \u2014 succeeds if none is running)").action(async function() {
7337
+ const global = readGlobal(this);
7338
+ const socketPath = socketOf(this);
7339
+ const result = await stopVgd(socketPath);
7340
+ if (global.json) {
7341
+ json({ stopped: result === "stopped", result, socketPath });
7342
+ } else if (!global.quiet) {
7343
+ if (result === "stopped") info(`vgd \xB7 stopped ${c.dim(socketPath)}`);
7344
+ else if (result === "not-running") info(c.dim(`vgd \xB7 not running (${socketPath})`));
7345
+ }
7346
+ if (result === "refused") {
7347
+ throw new CliError(
7348
+ "this vgd is embedded in another process (e.g. vg code) \u2014 stop that process instead",
7349
+ ExitCode.ERROR
7350
+ );
7351
+ }
7352
+ if (result === "failed") {
7353
+ throw new CliError(
7354
+ `vgd did not stop within 5s (${socketPath}) \u2014 check \`vg daemon status\` and stop the process manually`,
7355
+ ExitCode.ERROR
7356
+ );
7357
+ }
7358
+ });
7359
+ applyGlobalOptions(stop);
7360
+ const restart = cmd.command("restart").description("restart vgd (stop if running, then start in the background)").action(async function() {
7361
+ const global = readGlobal(this);
7362
+ const socketPath = socketOf(this);
7363
+ const stopResult = await stopVgd(socketPath);
7364
+ if (stopResult === "refused") {
7365
+ throw new CliError(
7366
+ "this vgd is embedded in another process (e.g. vg code) \u2014 stop that process instead",
7367
+ ExitCode.ERROR
7368
+ );
7369
+ }
7370
+ if (stopResult === "failed") {
7371
+ throw new CliError(
7372
+ `vgd did not stop within 5s (${socketPath}) \u2014 check \`vg daemon status\` and stop the process manually`,
7373
+ ExitCode.ERROR
7374
+ );
7375
+ }
7376
+ await startDetachedVgd(socketPath);
7377
+ const res = await vgdRequest({ op: "status" }, { socketPath });
7378
+ if (global.json) {
7379
+ json({ running: true, restarted: true, ...res.ok ? res : { socketPath } });
7380
+ } else if (!global.quiet) {
7381
+ const pid = res.ok && "pid" in res ? res.pid : "?";
7382
+ info(`vgd \xB7 restarted pid ${pid} \xB7 ${c.dim(socketPath)}`);
7383
+ }
7384
+ });
7385
+ applyGlobalOptions(restart);
7250
7386
  const register = cmd.command("register").description("register the current repository with a running vgd").argument("[root]", "repository root (default: cwd)").action(async function(rootArg) {
7251
7387
  const global = readGlobal(this);
7252
7388
  const socketPath = socketOf(this);
@@ -7318,28 +7454,38 @@ function registerDaemon(program) {
7318
7454
  if (!await vgdIsRunning({ socketPath })) {
7319
7455
  throw new CliError(`vgd is not running \u2014 start it with \`vg daemon ensure\` (${socketPath})`, ExitCode.NOT_FOUND);
7320
7456
  }
7321
- const { loadGraph: loadGraph2 } = await import('./load-4MLIHGXF.js');
7322
- const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
7323
- const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
7324
7457
  const opts = this.opts();
7325
- const graph = loadGraph2(root2, global.graph);
7326
- if (!graph) {
7327
- throw new CliError(
7328
- `no code map found for ${root2} \u2014 run \`vg build\` (or bare \`vg\`) first`,
7329
- ExitCode.NOT_FOUND
7330
- );
7331
- }
7332
- const reg = await vgdRequest({ op: "register", root: root2 }, { socketPath });
7333
- if (!reg.ok) throw new CliError(reg.error, ExitCode.ERROR);
7334
- const git2 = opts.gitRef?.trim() || detectGitRef(root2).ref || "HEAD";
7335
- const repositoryId = reg.ok && "workspace" in reg ? reg.workspace.id : repositoryIdFromRoot(root2);
7336
- const put = await vgdRequest(
7337
- { op: "put-graph", repositoryId, gitRef: git2, graph },
7458
+ const loaded = await vgdRequest(
7459
+ { op: "load-graph", root: root2, gitRef: opts.gitRef?.trim() || void 0, graphPath: global.graph },
7338
7460
  { socketPath }
7339
7461
  );
7340
- if (!put.ok) throw new CliError(put.error, ExitCode.ERROR);
7462
+ let put = loaded;
7463
+ if (!loaded.ok && loaded.code === "no_map") {
7464
+ throw new CliError(loaded.error, ExitCode.NOT_FOUND);
7465
+ }
7466
+ if (!loaded.ok) {
7467
+ const { loadGraph: loadGraph2 } = await import('./load-YPSEDYIW.js');
7468
+ const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
7469
+ const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
7470
+ const graph = loadGraph2(root2, global.graph);
7471
+ if (!graph) {
7472
+ throw new CliError(
7473
+ `no code map found for ${root2} \u2014 run \`vg build\` (or bare \`vg\`) first`,
7474
+ ExitCode.NOT_FOUND
7475
+ );
7476
+ }
7477
+ const reg = await vgdRequest({ op: "register", root: root2 }, { socketPath });
7478
+ if (!reg.ok) throw new CliError(reg.error, ExitCode.ERROR);
7479
+ const git2 = opts.gitRef?.trim() || detectGitRef(root2).ref || "HEAD";
7480
+ const repositoryId = reg.ok && "workspace" in reg ? reg.workspace.id : repositoryIdFromRoot(root2);
7481
+ put = await vgdRequest(
7482
+ { op: "put-graph", repositoryId, gitRef: git2, graph },
7483
+ { socketPath }
7484
+ );
7485
+ if (!put.ok) throw new CliError(put.error, ExitCode.ERROR);
7486
+ }
7341
7487
  if (global.json) json(put);
7342
- else if ("stored" in put) {
7488
+ else if (put.ok && "stored" in put) {
7343
7489
  info(`vgd \xB7 published graph \xB7 ${put.nodeCount} node(s) \xB7 ref ${put.gitRef}`);
7344
7490
  info(c.dim(` repositoryId ${put.repositoryId}`));
7345
7491
  }
@@ -7457,6 +7603,62 @@ function spawnDetachedDaemonStart(socketPath) {
7457
7603
  function sleep(ms) {
7458
7604
  return new Promise((r) => setTimeout(r, ms));
7459
7605
  }
7606
+ async function startDetachedVgd(socketPath) {
7607
+ const child = spawnDetachedDaemonStart(socketPath);
7608
+ child.unref();
7609
+ const deadline = Date.now() + 8e3;
7610
+ while (Date.now() < deadline) {
7611
+ await sleep(100);
7612
+ if (await vgdIsRunning({ socketPath })) return child.pid;
7613
+ }
7614
+ throw new CliError(`vgd failed to become ready at ${socketPath}`, ExitCode.ERROR);
7615
+ }
7616
+ async function stopVgd(socketPath) {
7617
+ if (!await vgdIsRunning({ socketPath })) return "not-running";
7618
+ let acknowledged = false;
7619
+ try {
7620
+ const res = await vgdRequest({ op: "shutdown" }, { socketPath });
7621
+ if (res.ok) acknowledged = true;
7622
+ else if (res.code === "shutdown_unsupported") return "refused";
7623
+ } catch {
7624
+ }
7625
+ if (!acknowledged) {
7626
+ const pid = readVgdPid();
7627
+ if (pid == null) return "failed";
7628
+ try {
7629
+ process.kill(pid, "SIGTERM");
7630
+ } catch {
7631
+ return "failed";
7632
+ }
7633
+ }
7634
+ const deadline = Date.now() + 5e3;
7635
+ while (Date.now() < deadline) {
7636
+ await sleep(100);
7637
+ if (!await vgdIsRunning({ socketPath })) return "stopped";
7638
+ }
7639
+ return "failed";
7640
+ }
7641
+ async function restartVgdIfRunning(socketPath = vgdSocketPath()) {
7642
+ try {
7643
+ const stopResult = await stopVgd(socketPath);
7644
+ if (stopResult === "not-running") return "not-running";
7645
+ if (stopResult === "refused") return "refused";
7646
+ if (stopResult === "failed") return "failed";
7647
+ await startDetachedVgd(socketPath);
7648
+ return "restarted";
7649
+ } catch {
7650
+ return "failed";
7651
+ }
7652
+ }
7653
+ function readVgdPid() {
7654
+ try {
7655
+ const raw = fs7.readFileSync(vgdPidPath(), "utf8").trim();
7656
+ const pid = Number.parseInt(raw, 10);
7657
+ return Number.isInteger(pid) && pid > 0 ? pid : null;
7658
+ } catch {
7659
+ return null;
7660
+ }
7661
+ }
7460
7662
  async function repositoryIdForCwd(socketPath, root2) {
7461
7663
  const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
7462
7664
  const reg = await vgdRequest({ op: "register", root: root2 }, { socketPath });
@@ -7667,7 +7869,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
7667
7869
  console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
7668
7870
  }
7669
7871
  if (opts.baseline) {
7670
- const { runBaseline } = await import('./baseline-UOTGTJYT.js');
7872
+ const { runBaseline } = await import('./baseline-V6MYDEMS.js');
7671
7873
  await runBaseline(rootDir);
7672
7874
  }
7673
7875
  console.log("");
@@ -7777,9 +7979,9 @@ async function fileReferencesIdentifier(rootDir, relFile, identifier, readFile3)
7777
7979
  }
7778
7980
  async function defaultReadFile(absPath) {
7779
7981
  try {
7780
- const stat2 = await fs20.stat(absPath);
7982
+ const stat2 = await fs21.stat(absPath);
7781
7983
  if (!stat2.isFile() || stat2.size > MAX_FILE_BYTES) return null;
7782
- return await fs20.readFile(absPath, "utf8");
7984
+ return await fs21.readFile(absPath, "utf8");
7783
7985
  } catch {
7784
7986
  return null;
7785
7987
  }
@@ -8432,10 +8634,10 @@ function scanStaleness(rootDir, artifactPath) {
8432
8634
  }
8433
8635
  let newest = -Infinity;
8434
8636
  let newestChanged;
8435
- const MAX_ENTRIES = 2e4;
8637
+ const MAX_ENTRIES2 = 2e4;
8436
8638
  let scanned = 0;
8437
8639
  const walk2 = (dir, depth) => {
8438
- if (depth > 8 || scanned > MAX_ENTRIES) return;
8640
+ if (depth > 8 || scanned > MAX_ENTRIES2) return;
8439
8641
  let entries;
8440
8642
  try {
8441
8643
  entries = fs7.readdirSync(dir, { withFileTypes: true });
@@ -8444,7 +8646,7 @@ function scanStaleness(rootDir, artifactPath) {
8444
8646
  }
8445
8647
  for (const e of entries) {
8446
8648
  scanned++;
8447
- if (scanned > MAX_ENTRIES) break;
8649
+ if (scanned > MAX_ENTRIES2) break;
8448
8650
  if (e.isDirectory()) {
8449
8651
  if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(path37.join(dir, e.name), depth + 1);
8450
8652
  continue;
@@ -8977,8 +9179,8 @@ async function fetchLatestVersion() {
8977
9179
  }
8978
9180
  async function writeCache(data) {
8979
9181
  try {
8980
- await fs20.mkdir(CACHE_DIR, { recursive: true });
8981
- await fs20.writeFile(CACHE_FILE, JSON.stringify(data), "utf-8");
9182
+ await fs21.mkdir(CACHE_DIR, { recursive: true });
9183
+ await fs21.writeFile(CACHE_FILE, JSON.stringify(data), "utf-8");
8982
9184
  } catch {
8983
9185
  }
8984
9186
  }
@@ -9167,8 +9369,29 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
9167
9369
  process.exit(1);
9168
9370
  }
9169
9371
  if (opts.reap !== false) reapAndReport(cwd, latest);
9372
+ if (opts.reap !== false) await restartVgdAndReport();
9170
9373
  }
9171
9374
  );
9375
+ async function restartVgdAndReport() {
9376
+ let result;
9377
+ try {
9378
+ result = await restartVgdIfRunning();
9379
+ } catch {
9380
+ return;
9381
+ }
9382
+ if (result === "not-running") return;
9383
+ if (result === "restarted") {
9384
+ console.log(chalk7.dim("Restarted the vgd daemon on the new version."));
9385
+ } else if (result === "refused") {
9386
+ console.log(
9387
+ chalk7.dim("A vgd embedded in another process (e.g. vg code) is running \u2014 restart that session to pick up the update.")
9388
+ );
9389
+ } else {
9390
+ console.log(
9391
+ chalk7.dim('Could not restart the vgd daemon automatically \u2014 run "vg daemon restart" to pick up the update.')
9392
+ );
9393
+ }
9394
+ }
9172
9395
  function reapAndReport(cwd, keepVersion) {
9173
9396
  let reaped = [];
9174
9397
  try {