@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.
- package/DOCS.md +5 -1
- package/dist/agent-33BMKWJC.js +22 -0
- package/dist/agent-33BMKWJC.js.map +1 -0
- package/dist/baseline-V6MYDEMS.js +9 -0
- package/dist/{baseline-UOTGTJYT.js.map → baseline-V6MYDEMS.js.map} +1 -1
- package/dist/checkpoint-4WFZMKEO.js +56 -0
- package/dist/checkpoint-4WFZMKEO.js.map +1 -0
- package/dist/chunk-543E6WDJ.js +61 -0
- package/dist/chunk-543E6WDJ.js.map +1 -0
- package/dist/{chunk-P3QIO4ZU.js → chunk-5G7C6H2G.js} +14 -204
- package/dist/chunk-5G7C6H2G.js.map +1 -0
- package/dist/{chunk-JIBOJTGS.js → chunk-5HYCB55P.js} +101 -101
- package/dist/chunk-5HYCB55P.js.map +1 -0
- package/dist/{chunk-67YG3R5F.js → chunk-6D4BCGRQ.js} +6 -62
- package/dist/chunk-6D4BCGRQ.js.map +1 -0
- package/dist/{chunk-F6ZPUKED.js → chunk-6WNJJXFY.js} +4 -4
- package/dist/{chunk-F6ZPUKED.js.map → chunk-6WNJJXFY.js.map} +1 -1
- package/dist/{chunk-PXXVLX7K.js → chunk-CFL3QQQZ.js} +7 -6
- package/dist/chunk-CFL3QQQZ.js.map +1 -0
- package/dist/{chunk-74ZMAOVF.js → chunk-CQDCZQFV.js} +55 -9
- package/dist/chunk-CQDCZQFV.js.map +1 -0
- package/dist/{chunk-VZRQUI54.js → chunk-DBMYWNLC.js} +4 -4
- package/dist/{chunk-VZRQUI54.js.map → chunk-DBMYWNLC.js.map} +1 -1
- package/dist/{chunk-QDZ47G45.js → chunk-EKCNSRNJ.js} +20 -11
- package/dist/chunk-EKCNSRNJ.js.map +1 -0
- package/dist/{chunk-SIPGDJT4.js → chunk-EVLS2M5G.js} +4 -4
- package/dist/{chunk-SIPGDJT4.js.map → chunk-EVLS2M5G.js.map} +1 -1
- package/dist/{chunk-G4HTI4ZM.js → chunk-FHJBGPJZ.js} +3 -2
- package/dist/chunk-FHJBGPJZ.js.map +1 -0
- package/dist/{chunk-CYC3ZI32.js → chunk-GLT3N7T2.js} +9 -6
- package/dist/chunk-GLT3N7T2.js.map +1 -0
- package/dist/chunk-HTLDXEHW.js +60 -0
- package/dist/chunk-HTLDXEHW.js.map +1 -0
- package/dist/{chunk-GI6W53LM.js → chunk-IDAQV3NQ.js} +4 -2
- package/dist/chunk-IDAQV3NQ.js.map +1 -0
- package/dist/{chunk-2ZHWF7C6.js → chunk-KGWEBM2J.js} +43 -68
- package/dist/chunk-KGWEBM2J.js.map +1 -0
- package/dist/{chunk-RZEXHDCF.js → chunk-MYM5VIJ4.js} +14 -3
- package/dist/chunk-MYM5VIJ4.js.map +1 -0
- package/dist/{chunk-HDQG3QYV.js → chunk-ON7PZNYV.js} +42 -26
- package/dist/chunk-ON7PZNYV.js.map +1 -0
- package/dist/chunk-Q4UQ73NA.js +6 -0
- package/dist/{chunk-WQE4OIZS.js.map → chunk-Q4UQ73NA.js.map} +1 -1
- package/dist/{chunk-PMYWZRRS.js → chunk-RBIRXQR6.js} +21 -3
- package/dist/chunk-RBIRXQR6.js.map +1 -0
- package/dist/{chunk-TCJTQGAO.js → chunk-RGEVBSLK.js} +3 -3
- package/dist/{chunk-TCJTQGAO.js.map → chunk-RGEVBSLK.js.map} +1 -1
- package/dist/chunk-TJ3WIJ7H.js +216 -0
- package/dist/chunk-TJ3WIJ7H.js.map +1 -0
- package/dist/chunk-VOEYUAER.js +203 -0
- package/dist/chunk-VOEYUAER.js.map +1 -0
- package/dist/{chunk-PRGCCW7D.js → chunk-WBMMRERH.js} +3 -3
- package/dist/{chunk-PRGCCW7D.js.map → chunk-WBMMRERH.js.map} +1 -1
- package/dist/{chunk-6HX47EBL.js → chunk-X634FZVG.js} +3 -3
- package/dist/{chunk-6HX47EBL.js.map → chunk-X634FZVG.js.map} +1 -1
- package/dist/cli.js +563 -340
- package/dist/cli.js.map +1 -1
- package/dist/{fs-6JKZNQ3U.js → fs-HNR6LAI7.js} +3 -3
- package/dist/fs-HNR6LAI7.js.map +1 -0
- package/dist/{graph-backend-GBL33GMW.js → graph-backend-G5Y6QQV4.js} +4 -4
- package/dist/{graph-backend-GBL33GMW.js.map → graph-backend-G5Y6QQV4.js.map} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +12 -10
- package/dist/index.js.map +1 -1
- package/dist/{interactive-HLGJJFLI.js → interactive-NJG6467J.js} +27 -24
- package/dist/interactive-NJG6467J.js.map +1 -0
- package/dist/{llm-host-5RE34322.js → llm-host-DZBD5D36.js} +5 -5
- package/dist/{llm-host-5RE34322.js.map → llm-host-DZBD5D36.js.map} +1 -1
- package/dist/load-YPSEDYIW.js +10 -0
- package/dist/{load-4MLIHGXF.js.map → load-YPSEDYIW.js.map} +1 -1
- package/dist/rules-ASYEUNB5.js +74 -0
- package/dist/rules-ASYEUNB5.js.map +1 -0
- package/dist/run-outcome-5FQWHWYK.js +253 -0
- package/dist/run-outcome-5FQWHWYK.js.map +1 -0
- package/dist/runtime-session-Y4ZD3QDO.js +20 -0
- package/dist/{runtime-session-5M6QZZOS.js.map → runtime-session-Y4ZD3QDO.js.map} +1 -1
- package/dist/{session-2JT4AUZT.js → session-3OBIQLE4.js} +5 -5
- package/dist/{session-2JT4AUZT.js.map → session-3OBIQLE4.js.map} +1 -1
- package/dist/{stream-json-Y45JBNYP.js → stream-json-3YOPU3LF.js} +82 -10
- package/dist/stream-json-3YOPU3LF.js.map +1 -0
- package/dist/{vg-mcp-bridge-ZCKBYQ2D.js → vg-mcp-bridge-PZFGTZSA.js} +8 -7
- package/dist/vg-mcp-bridge-PZFGTZSA.js.map +1 -0
- package/dist/{vgd-TGGEAGQZ.js → vgd-DH7AHQ23.js} +9 -8
- package/dist/vgd-DH7AHQ23.js.map +1 -0
- package/package.json +1 -1
- package/dist/baseline-UOTGTJYT.js +0 -9
- package/dist/chunk-2ZHWF7C6.js.map +0 -1
- package/dist/chunk-67YG3R5F.js.map +0 -1
- package/dist/chunk-74ZMAOVF.js.map +0 -1
- package/dist/chunk-CYC3ZI32.js.map +0 -1
- package/dist/chunk-G4HTI4ZM.js.map +0 -1
- package/dist/chunk-GI6W53LM.js.map +0 -1
- package/dist/chunk-HDQG3QYV.js.map +0 -1
- package/dist/chunk-JIBOJTGS.js.map +0 -1
- package/dist/chunk-P3QIO4ZU.js.map +0 -1
- package/dist/chunk-PMYWZRRS.js.map +0 -1
- package/dist/chunk-PXXVLX7K.js.map +0 -1
- package/dist/chunk-QDZ47G45.js.map +0 -1
- package/dist/chunk-RZEXHDCF.js.map +0 -1
- package/dist/chunk-WQE4OIZS.js +0 -6
- package/dist/fs-6JKZNQ3U.js.map +0 -1
- package/dist/interactive-HLGJJFLI.js.map +0 -1
- package/dist/load-4MLIHGXF.js +0 -9
- package/dist/runtime-session-5M6QZZOS.js +0 -19
- package/dist/stream-json-Y45JBNYP.js.map +0 -1
- package/dist/vg-mcp-bridge-ZCKBYQ2D.js.map +0 -1
- 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-
|
|
3
|
-
export { runBuild } from './chunk-
|
|
4
|
-
import {
|
|
5
|
-
import { loadAdvancedScanHook, baselineCommand } from './chunk-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
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-
|
|
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-
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import
|
|
20
|
-
import {
|
|
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
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
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-
|
|
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 {
|
|
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 {
|
|
40
|
-
import {
|
|
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-
|
|
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
|
|
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:
|
|
2566
|
-
methodology:
|
|
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
|
-
...
|
|
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-
|
|
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-
|
|
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-
|
|
6305
|
-
const { nodeCodeFs } = await import('./session-
|
|
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-
|
|
6312
|
-
const { resolveGraphBackend } = await import('./graph-backend-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
6416
|
-
|
|
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-
|
|
6444
|
-
const { nodeCodeFs } = await import('./session-
|
|
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-
|
|
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-
|
|
6478
|
-
const { resolveGraphBackend } = await import('./graph-backend-
|
|
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-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
|
7326
|
-
|
|
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
|
-
|
|
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-
|
|
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
|
|
7982
|
+
const stat2 = await fs21.stat(absPath);
|
|
7781
7983
|
if (!stat2.isFile() || stat2.size > MAX_FILE_BYTES) return null;
|
|
7782
|
-
return await
|
|
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
|
|
8637
|
+
const MAX_ENTRIES2 = 2e4;
|
|
8436
8638
|
let scanned = 0;
|
|
8437
8639
|
const walk2 = (dir, depth) => {
|
|
8438
|
-
if (depth > 8 || scanned >
|
|
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 >
|
|
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
|
|
8981
|
-
await
|
|
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 {
|