@vibgrate/cli 2026.817.2 → 2026.818.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/dist/activity-MF2GNYAI.js +5 -0
- package/dist/activity-MF2GNYAI.js.map +1 -0
- package/dist/agent-CUK24AWF.js +30 -0
- package/dist/{agent-UQC7QN77.js.map → agent-CUK24AWF.js.map} +1 -1
- package/dist/{approvals-ASPJQUZK.js → approvals-YFOU6GVB.js} +5 -5
- package/dist/{approvals-ASPJQUZK.js.map → approvals-YFOU6GVB.js.map} +1 -1
- package/dist/attach-6S3XS7VO.js +9 -0
- package/dist/attach-6S3XS7VO.js.map +1 -0
- package/dist/baseline-OBZJRCCP.js +9 -0
- package/dist/{baseline-FIV6PR2M.js.map → baseline-OBZJRCCP.js.map} +1 -1
- package/dist/{chunk-E2FAQREZ.js → chunk-43ESHUM5.js} +174 -401
- package/dist/chunk-43ESHUM5.js.map +1 -0
- package/dist/{chunk-K6DXETMC.js → chunk-4QAMUBAC.js} +13 -12
- package/dist/chunk-4QAMUBAC.js.map +1 -0
- package/dist/{chunk-6K3XK7C5.js → chunk-6ABMV74F.js} +6 -3
- package/dist/chunk-6ABMV74F.js.map +1 -0
- package/dist/chunk-6BEBJCK4.js +467 -0
- package/dist/chunk-6BEBJCK4.js.map +1 -0
- package/dist/{chunk-KJT2R6WW.js → chunk-6LY3JH6S.js} +3 -3
- package/dist/{chunk-KJT2R6WW.js.map → chunk-6LY3JH6S.js.map} +1 -1
- package/dist/chunk-6WRG7VDO.js +118 -0
- package/dist/chunk-6WRG7VDO.js.map +1 -0
- package/dist/chunk-DBX3DL27.js +26 -0
- package/dist/chunk-DBX3DL27.js.map +1 -0
- package/dist/{chunk-Q3M6K3HY.js → chunk-DH6EDSQP.js} +3 -3
- package/dist/{chunk-Q3M6K3HY.js.map → chunk-DH6EDSQP.js.map} +1 -1
- package/dist/{chunk-5OL2TSHK.js → chunk-DM6MJ7IF.js} +4 -4
- package/dist/{chunk-5OL2TSHK.js.map → chunk-DM6MJ7IF.js.map} +1 -1
- package/dist/{chunk-Q4G2BWE3.js → chunk-DUCEKH7Q.js} +12 -6
- package/dist/chunk-DUCEKH7Q.js.map +1 -0
- package/dist/{chunk-EXV4QSAD.js → chunk-E7RVA2ZI.js} +3 -3
- package/dist/{chunk-EXV4QSAD.js.map → chunk-E7RVA2ZI.js.map} +1 -1
- package/dist/{chunk-C3LMWZKF.js → chunk-FFYO7G3T.js} +4 -4
- package/dist/{chunk-C3LMWZKF.js.map → chunk-FFYO7G3T.js.map} +1 -1
- package/dist/chunk-G7ZFSH5J.js +132 -0
- package/dist/chunk-G7ZFSH5J.js.map +1 -0
- package/dist/{chunk-M7IO3DXH.js → chunk-GKZU6MII.js} +165 -31
- package/dist/chunk-GKZU6MII.js.map +1 -0
- package/dist/chunk-H5Q4JUY4.js +47 -0
- package/dist/chunk-H5Q4JUY4.js.map +1 -0
- package/dist/{chunk-LHKQGVRF.js → chunk-H6RV2OAX.js} +31 -10
- package/dist/chunk-H6RV2OAX.js.map +1 -0
- package/dist/{chunk-2FEB5KJS.js → chunk-I3PKYYRP.js} +5 -4
- package/dist/chunk-I3PKYYRP.js.map +1 -0
- package/dist/{chunk-XLXJC7H3.js → chunk-J3A3O4IA.js} +5 -118
- package/dist/chunk-J3A3O4IA.js.map +1 -0
- package/dist/{chunk-O2DL2Q55.js → chunk-J7CVFTLG.js} +5 -5
- package/dist/{chunk-O2DL2Q55.js.map → chunk-J7CVFTLG.js.map} +1 -1
- package/dist/{chunk-3NJUOIZQ.js → chunk-LHQYYBCH.js} +5 -5
- package/dist/{chunk-3NJUOIZQ.js.map → chunk-LHQYYBCH.js.map} +1 -1
- package/dist/{chunk-GOGMS3ST.js → chunk-MHJBIGWV.js} +752 -51
- package/dist/chunk-MHJBIGWV.js.map +1 -0
- package/dist/chunk-NDNNOAS6.js +16 -0
- package/dist/chunk-NDNNOAS6.js.map +1 -0
- package/dist/{chunk-RBIRXQR6.js → chunk-NO4BMW7M.js} +4 -14
- package/dist/chunk-NO4BMW7M.js.map +1 -0
- package/dist/{chunk-DVW3SVCW.js → chunk-OS4YFOFJ.js} +29 -9
- package/dist/chunk-OS4YFOFJ.js.map +1 -0
- package/dist/{chunk-3H3SVJUY.js → chunk-OVUZWR67.js} +107 -542
- package/dist/chunk-OVUZWR67.js.map +1 -0
- package/dist/chunk-POOL355F.js +237 -0
- package/dist/chunk-POOL355F.js.map +1 -0
- package/dist/{chunk-WVMOGIPC.js → chunk-Q7TWHJJ6.js} +3 -3
- package/dist/{chunk-WVMOGIPC.js.map → chunk-Q7TWHJJ6.js.map} +1 -1
- package/dist/{chunk-3FMRFECC.js → chunk-SBHK4ECM.js} +3 -3
- package/dist/{chunk-3FMRFECC.js.map → chunk-SBHK4ECM.js.map} +1 -1
- package/dist/chunk-SUD54UGN.js +6 -0
- package/dist/{chunk-PRG2ULPK.js.map → chunk-SUD54UGN.js.map} +1 -1
- package/dist/{chunk-WAKP7SK7.js → chunk-V2UGRUTL.js} +225 -48
- package/dist/chunk-V2UGRUTL.js.map +1 -0
- package/dist/{chunk-AXZZ5CCG.js → chunk-WVTGF2MP.js} +38 -19
- package/dist/chunk-WVTGF2MP.js.map +1 -0
- package/dist/{chunk-TVDMNIUT.js → chunk-X4DECFUG.js} +4 -4
- package/dist/{chunk-TVDMNIUT.js.map → chunk-X4DECFUG.js.map} +1 -1
- package/dist/{chunk-OZ3IFXRD.js → chunk-YENM3HT7.js} +5 -4
- package/dist/chunk-YENM3HT7.js.map +1 -0
- package/dist/{chunk-KNGAZDGF.js → chunk-ZWFMJUXC.js} +151 -42
- package/dist/chunk-ZWFMJUXC.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +576 -454
- package/dist/cli.js.map +1 -1
- package/dist/daemon-4Q5QBBAF.js +31 -0
- package/dist/{daemon-FPTRHO5N.js.map → daemon-4Q5QBBAF.js.map} +1 -1
- package/dist/embed-worker-main.js +3 -3
- package/dist/ensure-map-B2PS5ALS.js +40 -0
- package/dist/{ensure-map-342G2IV3.js.map → ensure-map-B2PS5ALS.js.map} +1 -1
- package/dist/graph-backend-EEXMD6XY.js +16 -0
- package/dist/{graph-backend-RNWQBT3P.js.map → graph-backend-EEXMD6XY.js.map} +1 -1
- package/dist/index.d.ts +606 -4
- package/dist/index.js +24 -17
- package/dist/index.js.map +1 -1
- package/dist/{interactive-SR7TMF6M.js → interactive-KEPGE5HD.js} +40 -33
- package/dist/interactive-KEPGE5HD.js.map +1 -0
- package/dist/load-H5HAME25.js +11 -0
- package/dist/{load-AYFECIQB.js.map → load-H5HAME25.js.map} +1 -1
- package/dist/parse-worker.js +3 -2
- package/dist/parse-worker.js.map +1 -1
- package/dist/{run-outcome-YQQJG3LW.js → run-outcome-V3L4GAN4.js} +5 -5
- package/dist/{run-outcome-YQQJG3LW.js.map → run-outcome-V3L4GAN4.js.map} +1 -1
- package/dist/runtime-session-M2FRGTDS.js +27 -0
- package/dist/{runtime-session-CNJ4DAV5.js.map → runtime-session-M2FRGTDS.js.map} +1 -1
- package/dist/{session-H34HUV2Y.js → session-77YXFUC7.js} +8 -8
- package/dist/{session-H34HUV2Y.js.map → session-77YXFUC7.js.map} +1 -1
- package/dist/slot-subscription-25GOARW5.js +95 -0
- package/dist/slot-subscription-25GOARW5.js.map +1 -0
- package/dist/{stream-json-55YDNAFX.js → stream-json-S6E3W2US.js} +18 -15
- package/dist/stream-json-S6E3W2US.js.map +1 -0
- package/dist/version-VRZT5G4T.js +4 -0
- package/dist/{version-WSE3QOPK.js.map → version-VRZT5G4T.js.map} +1 -1
- package/dist/{vg-mcp-bridge-2CNLHNEL.js → vg-mcp-bridge-HCPJWJKJ.js} +12 -11
- package/dist/vg-mcp-bridge-HCPJWJKJ.js.map +1 -0
- package/dist/{vgd-URUZQORN.js → vgd-R2PNIDEP.js} +15 -10
- package/dist/vgd-R2PNIDEP.js.map +1 -0
- package/package.json +1 -1
- package/dist/agent-UQC7QN77.js +0 -27
- package/dist/baseline-FIV6PR2M.js +0 -9
- package/dist/chunk-2FEB5KJS.js.map +0 -1
- package/dist/chunk-3H3SVJUY.js.map +0 -1
- package/dist/chunk-6K3XK7C5.js.map +0 -1
- package/dist/chunk-AXZZ5CCG.js.map +0 -1
- package/dist/chunk-DVW3SVCW.js.map +0 -1
- package/dist/chunk-E2FAQREZ.js.map +0 -1
- package/dist/chunk-GOGMS3ST.js.map +0 -1
- package/dist/chunk-K6DXETMC.js.map +0 -1
- package/dist/chunk-KNGAZDGF.js.map +0 -1
- package/dist/chunk-LHKQGVRF.js.map +0 -1
- package/dist/chunk-M7IO3DXH.js.map +0 -1
- package/dist/chunk-OZ3IFXRD.js.map +0 -1
- package/dist/chunk-PRG2ULPK.js +0 -6
- package/dist/chunk-Q4G2BWE3.js.map +0 -1
- package/dist/chunk-RBIRXQR6.js.map +0 -1
- package/dist/chunk-WAKP7SK7.js.map +0 -1
- package/dist/chunk-XLXJC7H3.js.map +0 -1
- package/dist/daemon-FPTRHO5N.js +0 -26
- package/dist/ensure-map-342G2IV3.js +0 -33
- package/dist/graph-backend-RNWQBT3P.js +0 -15
- package/dist/interactive-SR7TMF6M.js.map +0 -1
- package/dist/load-AYFECIQB.js +0 -11
- package/dist/runtime-session-CNJ4DAV5.js +0 -22
- package/dist/stream-json-55YDNAFX.js.map +0 -1
- package/dist/version-WSE3QOPK.js +0 -4
- package/dist/vg-mcp-bridge-2CNLHNEL.js.map +0 -1
- package/dist/vgd-URUZQORN.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,63 +1,70 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import { restartVgdIfRunning, stopVgd, registerDaemon, rootOf, requireGraph } from './chunk-KNGAZDGF.js';
|
|
8
|
-
import { readGlobal, applyGlobalOptions } from './chunk-OZ3IFXRD.js';
|
|
9
|
-
import { disableColor, info, c, json, out } from './chunk-CT5BS56U.js';
|
|
10
|
-
import './chunk-GOGMS3ST.js';
|
|
11
|
-
import './chunk-IS7VTH2Q.js';
|
|
2
|
+
import { loadAdvancedScanHook, baselineCommand } from './chunk-6ABMV74F.js';
|
|
3
|
+
import { fetchCatalog, resolveProviders } from './chunk-FFYO7G3T.js';
|
|
4
|
+
import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, ProgressBar, printLogo, runBuild } from './chunk-H6RV2OAX.js';
|
|
5
|
+
export { runBuild } from './chunk-H6RV2OAX.js';
|
|
6
|
+
import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-E7RVA2ZI.js';
|
|
12
7
|
import { defaultProcessEndpoint, startProcessHostServer, resolveInferenceIsolation } from './chunk-JFE7XCAE.js';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-K6DXETMC.js';
|
|
8
|
+
import { runCodeSession } from './chunk-LHQYYBCH.js';
|
|
9
|
+
import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-4QAMUBAC.js';
|
|
16
10
|
import './chunk-543E6WDJ.js';
|
|
17
|
-
import './chunk-Q3M6K3HY.js';
|
|
18
|
-
import './chunk-TVDMNIUT.js';
|
|
19
|
-
import './chunk-RBIRXQR6.js';
|
|
20
|
-
import { buildIdentifierTrieFromGraph } from './chunk-5HYCB55P.js';
|
|
21
11
|
import { parseReasoningEffort, summarizeDiffs, ScriptedProvider } from './chunk-74UBGF4P.js';
|
|
22
12
|
import './chunk-7AVYKZEM.js';
|
|
23
13
|
import { buildModelInstallPlan } from './chunk-I5LP55B6.js';
|
|
24
14
|
import { ensurePackage, ensureUnavailableMessage } from './chunk-3HNPVXUK.js';
|
|
15
|
+
import { ActivityLog } from './chunk-H5Q4JUY4.js';
|
|
25
16
|
import { init_resolve_ollama, gatherSystemMemory, resolveOllamaBinary, hasOllamaBinary, resolve_ollama_exports } from './chunk-FJG5AXKZ.js';
|
|
26
17
|
import { readOrchestratorState, writeOrchestratorState, parseMode, setDefaultMode, recommendMode, activePin, resolveMode, providerForBackend, QUALIFIED_PACKS, pinPack, unpinPack, buildOrchestratorStatus } from './chunk-NZELMYT4.js';
|
|
27
18
|
import { fmt, estimateModelBytes } from './chunk-7N4Y3E47.js';
|
|
19
|
+
import './chunk-DH6EDSQP.js';
|
|
20
|
+
import './chunk-X4DECFUG.js';
|
|
21
|
+
import { vgdVersionSkew, restartVgdIfRunning, stopVgd, registerDaemon, rootOf, requireGraph } from './chunk-ZWFMJUXC.js';
|
|
22
|
+
import { readGlobal, applyGlobalOptions } from './chunk-YENM3HT7.js';
|
|
23
|
+
import { disableColor, info, c, json, out } from './chunk-CT5BS56U.js';
|
|
24
|
+
import { isManifest, isDependencyFile, manifestHash, loadScanCache, writeScanCache, manifestKind, findPackageLine, endOfLine, findRuntimeLine } from './chunk-MHJBIGWV.js';
|
|
25
|
+
import { clearHostSessionPool, acquireHostSession, generateOnSession, listHostSessions, hostSessionPoolSize } from './chunk-3LOWJSAF.js';
|
|
26
|
+
import { buildIdentifierTrieFromGraph } from './chunk-5HYCB55P.js';
|
|
27
|
+
import './chunk-IS7VTH2Q.js';
|
|
28
28
|
import './chunk-IZDH67DX.js';
|
|
29
|
-
import {
|
|
30
|
-
import { refreshIfStale } from './chunk-
|
|
31
|
-
import { driftCount, ASSISTANTS, detectAssistants, isAssistantInstalled, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, buildGraph, writeSnapshot, probeFreshness,
|
|
32
|
-
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-
|
|
29
|
+
import { DaemonSemanticSession, serveStdio, exportGraph, GraphSource, createServer, formatForExt, RefreshScheduler } from './chunk-GKZU6MII.js';
|
|
30
|
+
import { refreshIfStale } from './chunk-J7CVFTLG.js';
|
|
31
|
+
import { driftCount, ASSISTANTS, detectAssistants, isAssistantInstalled, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, buildGraph, writeSnapshot, probeFreshness, assistantById, SMALL_REPO_FILES } from './chunk-43ESHUM5.js';
|
|
32
|
+
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-OS4YFOFJ.js';
|
|
33
|
+
import { writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, loadConfig, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, refineArchitectureWithAstRoles, refineArchitectureWithGraph, PROJECT_TYPE_TO_OSV_ECOSYSTEM, fetchRiskySymbols, perDependencyDrift, boundaryProfileRules } from './chunk-V2UGRUTL.js';
|
|
33
34
|
import { resolveIngestHost, dashHostForIngestHost, availableRegionIds, ingestHostForRegionId } from './chunk-HTLDXEHW.js';
|
|
34
|
-
import { writeDefaultConfig, parseDsn, detectVcs, computeRepoFingerprint, resolveRepositoryName, fetchScanPreflight, runCoreScan, loadConfig, prepareCompressedUpload, computeDriftScore, titleBox, projectTypeToVulnEcosystem, driftBar, gitHistoryAvailable, buildVersionTimelines, findPackageAnyEcosystem, normalizeConstraint, findVersionCrossings, versionSatisfies, refineArchitectureWithGraph, refineArchitectureWithAstRoles, PROJECT_TYPE_TO_OSV_ECOSYSTEM, fetchRiskySymbols, perDependencyDrift } from './chunk-WAKP7SK7.js';
|
|
35
|
-
import { CliError, ExitCode, usageError, engineUnavailable } from './chunk-MS6V5XKB.js';
|
|
36
35
|
import './chunk-VIWZ4QT7.js';
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-KJT2R6WW.js';
|
|
40
|
-
import { queryGraphSemantic, queryGraph, indexFor, impactOf } from './chunk-Q4G2BWE3.js';
|
|
36
|
+
import { catalogPath, libDir, loadCatalog, driftFor, addLibrary, resolveLib, libId, resolveVersion, readDoc, localPackageDocs, localApiSurface } from './chunk-OVUZWR67.js';
|
|
37
|
+
import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-6LY3JH6S.js';
|
|
41
38
|
import { discoverModels } from './chunk-CQDUBAQY.js';
|
|
42
39
|
import { freeBytesOnVolume, weightStoreDir, listCachedWeights, ensureWeightCached, catalogIntegrityReport } from './chunk-OV4KGXPD.js';
|
|
43
|
-
import { loadGraph, loadGraphPreferIndex, SCHEMA_VERSION } from './chunk-3FMRFECC.js';
|
|
44
|
-
import './chunk-5I4VSBWQ.js';
|
|
45
40
|
import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-NG4KIJW6.js';
|
|
46
41
|
import { ensureDir, pathExists, readJsonFile, writeTextFile, writeJsonFile } from './chunk-CRAMOEBE.js';
|
|
42
|
+
import { CliError, ExitCode, usageError, engineUnavailable } from './chunk-MS6V5XKB.js';
|
|
47
43
|
import { init_cli_invocation, resolveCliInvocation, NPX_INVOCATION } from './chunk-EZ7UC5Y5.js';
|
|
48
|
-
import {
|
|
44
|
+
import { isRelevantChange } from './chunk-DBX3DL27.js';
|
|
45
|
+
import { discover, SKIP_DIRS } from './chunk-POOL355F.js';
|
|
46
|
+
import { inventory, enrichOnline, ECOSYSTEMS } from './chunk-6BEBJCK4.js';
|
|
47
|
+
import { resolveOne } from './chunk-J7LKEB2R.js';
|
|
48
|
+
import { queryGraphSemantic, queryGraph, indexFor, impactOf } from './chunk-DUCEKH7Q.js';
|
|
49
|
+
import { loadGraph, loadGraphPreferIndex, SCHEMA_VERSION } from './chunk-SBHK4ECM.js';
|
|
50
|
+
import './chunk-5I4VSBWQ.js';
|
|
51
|
+
import { attachVgd, publishGraphToVgd } from './chunk-G7ZFSH5J.js';
|
|
52
|
+
import './chunk-NO4BMW7M.js';
|
|
53
|
+
import './chunk-NDNNOAS6.js';
|
|
54
|
+
import { resolvedGrammarFiles, TOOLCHAIN_GRAMMARS, resolveToolchainGrammar, grammarSetVersion, fileRolesFromParseCache } from './chunk-J3A3O4IA.js';
|
|
49
55
|
import './chunk-T7RSQ5WD.js';
|
|
50
|
-
import
|
|
51
|
-
import {
|
|
56
|
+
import './chunk-6WRG7VDO.js';
|
|
57
|
+
import { embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, unavailableMessage, countPending, modelCacheInfo, embeddingsPath, clearModelCache, withTimeout } from './chunk-WVTGF2MP.js';
|
|
58
|
+
import { resetRelevanceProviderCache, loadRelevanceProvider, relevanceModuleDir, resolveGraphPath, analyzeQuestion, loadTopicTags, renderReport, loadGraphFileWithSnapshot, writeArtifacts, vibgrateDir, mapFileExists, ensureVibgrateGitignore } from './chunk-Q7TWHJJ6.js';
|
|
52
59
|
import { cacheDir } from './chunk-MVPRPSXU.js';
|
|
53
60
|
import { serializeGraph, stableStringify, parseGraph } from './chunk-O3LABX6I.js';
|
|
54
|
-
import { VERSION } from './chunk-
|
|
61
|
+
import { VERSION } from './chunk-SUD54UGN.js';
|
|
55
62
|
import './chunk-BWPBB45M.js';
|
|
56
|
-
import { canonicalize, hashString
|
|
63
|
+
import { canonicalize, hashString } from './chunk-JFGYT6BI.js';
|
|
57
64
|
import './chunk-BPF3YX2U.js';
|
|
58
65
|
import { __toCommonJS } from './chunk-Z6ZWNWWR.js';
|
|
59
|
-
import * as
|
|
60
|
-
import
|
|
66
|
+
import * as fs13 from 'fs';
|
|
67
|
+
import fs13__default, { realpathSync } from 'fs';
|
|
61
68
|
import * as path46 from 'path';
|
|
62
69
|
import path46__default from 'path';
|
|
63
70
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
@@ -71,7 +78,7 @@ import * as zlib from 'zlib';
|
|
|
71
78
|
import * as crypto3 from 'crypto';
|
|
72
79
|
import { randomUUID, createHash } from 'crypto';
|
|
73
80
|
import chalk7 from 'chalk';
|
|
74
|
-
import * as
|
|
81
|
+
import * as fs27 from 'fs/promises';
|
|
75
82
|
import { parse, stringify } from 'yaml';
|
|
76
83
|
|
|
77
84
|
init_cli_invocation();
|
|
@@ -85,7 +92,7 @@ async function runStatus(global) {
|
|
|
85
92
|
const root3 = path46.resolve(global.cwd ?? ".");
|
|
86
93
|
const graphPath = resolveGraphPath(root3, global.graph);
|
|
87
94
|
const graph = loadGraph(root3, graphPath);
|
|
88
|
-
const hasCache =
|
|
95
|
+
const hasCache = fs13.existsSync(path46.join(cacheDir(root3), "parse-cache.json"));
|
|
89
96
|
let stale = null;
|
|
90
97
|
let staleExact = false;
|
|
91
98
|
if (graph) {
|
|
@@ -158,6 +165,19 @@ function registerAsk(program) {
|
|
|
158
165
|
}
|
|
159
166
|
}
|
|
160
167
|
const { graph } = requireGraph(global);
|
|
168
|
+
const activity = new ActivityLog();
|
|
169
|
+
const attached = await activity.time(
|
|
170
|
+
"attach",
|
|
171
|
+
() => attachVgd(root3, {
|
|
172
|
+
graphPath: global.graph,
|
|
173
|
+
disabled: global.daemon === false,
|
|
174
|
+
// Skip the republish when the daemon already holds this exact map:
|
|
175
|
+
// a publish drops the slot's vectors, so doing it on every ask
|
|
176
|
+
// churned the index for nothing.
|
|
177
|
+
corpusHash: graph.provenance?.corpusHash
|
|
178
|
+
}),
|
|
179
|
+
(a) => describeAttach(a)
|
|
180
|
+
);
|
|
161
181
|
const budget = Number(opts.budget) || 2e3;
|
|
162
182
|
const q = question.join(" ");
|
|
163
183
|
const wantSemantic = opts.semantic !== false && !global.local;
|
|
@@ -167,33 +187,54 @@ function registerAsk(program) {
|
|
|
167
187
|
const relevance = await analyzeQuestion(q);
|
|
168
188
|
const topicTags = relevance ? await loadTopicTags(graph, root3, resolveGraphPath(root3, global.graph)) : null;
|
|
169
189
|
if (wantSemantic) {
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
bar?.done();
|
|
187
|
-
result = await queryGraphSemantic(graph, q, { budget, embedder, nodeVectors: vectors, relevance, topicTags });
|
|
188
|
-
mode = `semantic (${embedder.id})`;
|
|
190
|
+
const ranked = attached.status === "attached" && attached.repositoryId ? await activity.time(
|
|
191
|
+
"semantic",
|
|
192
|
+
// The attach above already resolved (and, if needed, published)
|
|
193
|
+
// the slot — this session only sends the question.
|
|
194
|
+
() => new DaemonSemanticSession(root3, { socketPath: attached.socketPath, publish: false }).rank(q),
|
|
195
|
+
(r) => r ? { outcome: "ok", detail: `ranked in the daemon \xB7 ${r.ranked.length} of ${r.vectors} vector(s)${r.model ? ` \xB7 ${r.model}` : ""}` } : { outcome: "skip", detail: "daemon has no usable index \u2014 embedding in this process" }
|
|
196
|
+
) : null;
|
|
197
|
+
if (ranked) {
|
|
198
|
+
result = await queryGraphSemantic(graph, q, {
|
|
199
|
+
budget,
|
|
200
|
+
semanticRanked: ranked.ranked,
|
|
201
|
+
relevance,
|
|
202
|
+
topicTags
|
|
203
|
+
});
|
|
204
|
+
mode = `semantic (vgd${ranked.model ? `, ${ranked.model}` : ""})`;
|
|
205
|
+
activity.add("answer", "ok", "answered from the daemon index \u2014 no local model load");
|
|
189
206
|
} else {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
207
|
+
const firstRun = !embeddingsCached(root3, resolveEmbedModel());
|
|
208
|
+
if (!global.json && firstRun) {
|
|
209
|
+
info(c.dim(" preparing semantic search (first use embeds the map; cached, resumable & offline after)\u2026"));
|
|
210
|
+
}
|
|
211
|
+
let reason;
|
|
212
|
+
let detail;
|
|
213
|
+
const embedder = await loadEmbedder({
|
|
214
|
+
local: global.local,
|
|
215
|
+
onUnavailable: (r, d) => {
|
|
216
|
+
reason = r;
|
|
217
|
+
detail = d;
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
if (embedder) {
|
|
221
|
+
const bar = !global.json && firstRun ? new ProgressBar(c.dim("embedding")) : void 0;
|
|
222
|
+
const vectors = await getNodeEmbeddings(graph, embedder, root3, bar ? (d, t) => bar.update(d, t) : void 0);
|
|
223
|
+
bar?.done();
|
|
224
|
+
result = await queryGraphSemantic(graph, q, { budget, embedder, nodeVectors: vectors, relevance, topicTags });
|
|
225
|
+
mode = `semantic (${embedder.id})`;
|
|
226
|
+
activity.add("answer", "ok", `answered in this process \xB7 ${embedder.id} \xB7 ${vectors.size} vector(s)`);
|
|
227
|
+
} else {
|
|
228
|
+
result = queryGraph(graph, q, { budget, relevance, topicTags });
|
|
229
|
+
note = reason ? unavailableMessage(reason) : "semantic unavailable; used lexical";
|
|
230
|
+
if (detail) note += ` (${detail})`;
|
|
231
|
+
activity.add("answer", "warn", `lexical only \u2014 ${note}`);
|
|
232
|
+
}
|
|
193
233
|
}
|
|
194
234
|
} else {
|
|
195
235
|
result = queryGraph(graph, q, { budget, relevance, topicTags });
|
|
196
236
|
if (global.local) note = "semantic skipped under --local; used lexical";
|
|
237
|
+
activity.add("answer", "skip", global.local ? "lexical only (--local)" : "lexical only (--no-semantic)");
|
|
197
238
|
}
|
|
198
239
|
if (global.client) {
|
|
199
240
|
const files = new Set(result.matches.map((m) => m.node.file).filter(Boolean));
|
|
@@ -214,6 +255,7 @@ function registerAsk(program) {
|
|
|
214
255
|
question: result.question,
|
|
215
256
|
mode,
|
|
216
257
|
note: note || void 0,
|
|
258
|
+
activity: activity.toJSON(),
|
|
217
259
|
tokensEstimate: result.tokensEstimate,
|
|
218
260
|
matches: result.matches.map((m) => ({
|
|
219
261
|
name: m.node.qualifiedName,
|
|
@@ -231,9 +273,25 @@ function registerAsk(program) {
|
|
|
231
273
|
info("");
|
|
232
274
|
info(c.dim(`vg \xB7 ${result.matches.length} match(es) \xB7 ~${result.tokensEstimate} tokens (budget ${budget}) \xB7 ${mode}`));
|
|
233
275
|
if (note) info(c.yellow(` ${note}`));
|
|
276
|
+
for (const line of activity.render()) info(line);
|
|
234
277
|
});
|
|
235
278
|
applyGlobalOptions(cmd);
|
|
236
279
|
}
|
|
280
|
+
function describeAttach(a) {
|
|
281
|
+
if (a.status === "disabled") return { outcome: "skip", detail: `${a.reason} \u2014 running in this process` };
|
|
282
|
+
if (a.status === "unavailable") return { outcome: "skip", detail: `${a.reason} \u2014 running in this process` };
|
|
283
|
+
const started = a.started ? "started vgd" : "attached to vgd";
|
|
284
|
+
if (a.published?.status === "current") {
|
|
285
|
+
return { outcome: "ok", detail: `${started} \xB7 already holds this map (${a.published.gitRef})` };
|
|
286
|
+
}
|
|
287
|
+
if (a.published?.status === "published") {
|
|
288
|
+
return { outcome: "ok", detail: `${started} \xB7 map published ${a.published.gitRef} \xB7 ${a.published.nodeCount} nodes` };
|
|
289
|
+
}
|
|
290
|
+
if (a.published?.status === "failed") {
|
|
291
|
+
return { outcome: "warn", detail: `${started} \xB7 map not published (${a.published.error})` };
|
|
292
|
+
}
|
|
293
|
+
return { outcome: "ok", detail: started };
|
|
294
|
+
}
|
|
237
295
|
function crashedMessage(signal) {
|
|
238
296
|
const envPrefix = process.platform === "linux" ? "ONNXRUNTIME_NODE_INSTALL=skip " : "";
|
|
239
297
|
return `semantic search is disabled: its native backend (onnxruntime-node, via the vendored fastembed path) crashed with ${signal} \u2014 using fast lexical search instead. This usually means the installed native binaries are broken (an interrupted install, or a platform without prebuilt CPU binaries). Reinstall to repair \u2014 ${envPrefix}npm install -g --allow-scripts=@vibgrate/cli,onnxruntime-node,msgpackr-extract @vibgrate/cli \u2014 or run with --local to stay lexical quietly.`;
|
|
@@ -247,7 +305,7 @@ function verdictPath(dir) {
|
|
|
247
305
|
}
|
|
248
306
|
function readVerdict(dir) {
|
|
249
307
|
try {
|
|
250
|
-
const raw = JSON.parse(
|
|
308
|
+
const raw = JSON.parse(fs13.readFileSync(verdictPath(dir), "utf8"));
|
|
251
309
|
if (raw?.status !== "ok" && raw?.status !== "crashed") return null;
|
|
252
310
|
if (raw.version !== VERSION) return null;
|
|
253
311
|
return raw;
|
|
@@ -257,8 +315,8 @@ function readVerdict(dir) {
|
|
|
257
315
|
}
|
|
258
316
|
function writeVerdict(dir, verdict) {
|
|
259
317
|
try {
|
|
260
|
-
|
|
261
|
-
|
|
318
|
+
fs13.mkdirSync(dir, { recursive: true });
|
|
319
|
+
fs13.writeFileSync(verdictPath(dir), JSON.stringify(verdict, null, 2) + "\n", "utf8");
|
|
262
320
|
} catch {
|
|
263
321
|
}
|
|
264
322
|
}
|
|
@@ -266,7 +324,7 @@ function probeModuleUrl(from = import.meta.url) {
|
|
|
266
324
|
const dir = path46.dirname(fileURLToPath(from));
|
|
267
325
|
for (const name of ["embeddings.js", "index.js"]) {
|
|
268
326
|
const candidate = path46.join(dir, name);
|
|
269
|
-
if (
|
|
327
|
+
if (fs13.existsSync(candidate)) return pathToFileURL(candidate).href;
|
|
270
328
|
}
|
|
271
329
|
return pathToFileURL(path46.join(dir, "index.js")).href;
|
|
272
330
|
}
|
|
@@ -343,7 +401,7 @@ async function embedderHealth(options = {}) {
|
|
|
343
401
|
}
|
|
344
402
|
function clearEmbedderHealth(cacheDir2) {
|
|
345
403
|
try {
|
|
346
|
-
|
|
404
|
+
fs13.unlinkSync(verdictPath(cacheDir2 ?? defaultCacheDir()));
|
|
347
405
|
} catch {
|
|
348
406
|
}
|
|
349
407
|
}
|
|
@@ -370,6 +428,7 @@ function registerEmbed(program) {
|
|
|
370
428
|
return;
|
|
371
429
|
}
|
|
372
430
|
if (countPending(graph, root3, modelId) === 0) {
|
|
431
|
+
await warmDaemonIndex(root3, global.graph);
|
|
373
432
|
if (global.json) json({ embedded: 0, pending: 0, upToDate: true, model: modelId, semantic: true });
|
|
374
433
|
else if (speak) info(`${c.cyan("vg embed")} \xB7 semantic index already up to date`);
|
|
375
434
|
return;
|
|
@@ -406,11 +465,15 @@ function registerEmbed(program) {
|
|
|
406
465
|
const bar = speak ? new ProgressBar(c.dim("embedding")) : void 0;
|
|
407
466
|
await getNodeEmbeddings(graph, embedder, root3, bar ? (d, t) => bar.update(d, t) : void 0);
|
|
408
467
|
bar?.done();
|
|
468
|
+
await warmDaemonIndex(root3, global.graph);
|
|
409
469
|
if (global.json) json({ embedded: pending, model: modelId, semantic: true });
|
|
410
470
|
else if (speak) info(`${c.green("\u2714")} vg embed \xB7 semantic index ready (~${pending} node(s) \xB7 model ${modelId})`);
|
|
411
471
|
});
|
|
412
472
|
applyGlobalOptions(cmd);
|
|
413
473
|
}
|
|
474
|
+
async function warmDaemonIndex(root3, graphPath) {
|
|
475
|
+
await publishGraphToVgd(root3, { graphPath, warmSemantic: true });
|
|
476
|
+
}
|
|
414
477
|
function showWhere(root3, modelId, asJson) {
|
|
415
478
|
const m = modelCacheInfo(modelId);
|
|
416
479
|
const repoCached = embeddingsCached(root3, modelId);
|
|
@@ -1018,7 +1081,7 @@ function liveStatsDir(root3) {
|
|
|
1018
1081
|
function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid, signal) => process.kill(pid, signal), selfPid = process.pid) {
|
|
1019
1082
|
let entries;
|
|
1020
1083
|
try {
|
|
1021
|
-
entries =
|
|
1084
|
+
entries = fs13.readdirSync(dir);
|
|
1022
1085
|
} catch {
|
|
1023
1086
|
return [];
|
|
1024
1087
|
}
|
|
@@ -1027,7 +1090,7 @@ function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid
|
|
|
1027
1090
|
if (!/^serve-\d+\.json$/.test(name)) continue;
|
|
1028
1091
|
let parsed;
|
|
1029
1092
|
try {
|
|
1030
|
-
parsed = JSON.parse(
|
|
1093
|
+
parsed = JSON.parse(fs13.readFileSync(path46.join(dir, name), "utf8"));
|
|
1031
1094
|
} catch {
|
|
1032
1095
|
continue;
|
|
1033
1096
|
}
|
|
@@ -1081,10 +1144,10 @@ var LiveStatsBus = class {
|
|
|
1081
1144
|
this.lastWriteAt = now;
|
|
1082
1145
|
const body = { pid: this.pid, updatedAt: now, version: VERSION, snapshot: snap };
|
|
1083
1146
|
try {
|
|
1084
|
-
|
|
1147
|
+
fs13.mkdirSync(this.dir, { recursive: true });
|
|
1085
1148
|
const tmp = `${this.file}.tmp`;
|
|
1086
|
-
|
|
1087
|
-
|
|
1149
|
+
fs13.writeFileSync(tmp, JSON.stringify(body));
|
|
1150
|
+
fs13.renameSync(tmp, this.file);
|
|
1088
1151
|
} catch {
|
|
1089
1152
|
}
|
|
1090
1153
|
}
|
|
@@ -1095,7 +1158,7 @@ var LiveStatsBus = class {
|
|
|
1095
1158
|
siblings(now = Date.now()) {
|
|
1096
1159
|
let entries;
|
|
1097
1160
|
try {
|
|
1098
|
-
entries =
|
|
1161
|
+
entries = fs13.readdirSync(this.dir);
|
|
1099
1162
|
} catch {
|
|
1100
1163
|
return [];
|
|
1101
1164
|
}
|
|
@@ -1105,14 +1168,14 @@ var LiveStatsBus = class {
|
|
|
1105
1168
|
const file = path46.join(this.dir, name);
|
|
1106
1169
|
let parsed;
|
|
1107
1170
|
try {
|
|
1108
|
-
parsed = JSON.parse(
|
|
1171
|
+
parsed = JSON.parse(fs13.readFileSync(file, "utf8"));
|
|
1109
1172
|
} catch {
|
|
1110
1173
|
continue;
|
|
1111
1174
|
}
|
|
1112
1175
|
if (typeof parsed?.pid !== "number" || typeof parsed.updatedAt !== "number" || !parsed.snapshot?.totals) continue;
|
|
1113
1176
|
if (now - parsed.updatedAt > STALE_MS) {
|
|
1114
1177
|
try {
|
|
1115
|
-
|
|
1178
|
+
fs13.unlinkSync(file);
|
|
1116
1179
|
} catch {
|
|
1117
1180
|
}
|
|
1118
1181
|
continue;
|
|
@@ -1124,7 +1187,7 @@ var LiveStatsBus = class {
|
|
|
1124
1187
|
}
|
|
1125
1188
|
unlinkOwn = () => {
|
|
1126
1189
|
try {
|
|
1127
|
-
|
|
1190
|
+
fs13.unlinkSync(this.file);
|
|
1128
1191
|
} catch {
|
|
1129
1192
|
}
|
|
1130
1193
|
};
|
|
@@ -1437,12 +1500,12 @@ var LedgerTail = class {
|
|
|
1437
1500
|
if (size === this.offset) return;
|
|
1438
1501
|
let chunk;
|
|
1439
1502
|
try {
|
|
1440
|
-
const fd =
|
|
1503
|
+
const fd = fs13.openSync(this.file, "r");
|
|
1441
1504
|
try {
|
|
1442
1505
|
chunk = Buffer.alloc(size - this.offset);
|
|
1443
|
-
|
|
1506
|
+
fs13.readSync(fd, chunk, 0, chunk.length, this.offset);
|
|
1444
1507
|
} finally {
|
|
1445
|
-
|
|
1508
|
+
fs13.closeSync(fd);
|
|
1446
1509
|
}
|
|
1447
1510
|
} catch {
|
|
1448
1511
|
return;
|
|
@@ -1455,7 +1518,7 @@ var LedgerTail = class {
|
|
|
1455
1518
|
}
|
|
1456
1519
|
sizeOf() {
|
|
1457
1520
|
try {
|
|
1458
|
-
return
|
|
1521
|
+
return fs13.statSync(this.file).size;
|
|
1459
1522
|
} catch {
|
|
1460
1523
|
return 0;
|
|
1461
1524
|
}
|
|
@@ -1511,6 +1574,7 @@ function registerServe(program) {
|
|
|
1511
1574
|
dedup: opts.dedup === true,
|
|
1512
1575
|
refresh,
|
|
1513
1576
|
watch: opts.watch !== false,
|
|
1577
|
+
daemon: global.daemon,
|
|
1514
1578
|
root: root3,
|
|
1515
1579
|
stats,
|
|
1516
1580
|
// Listing surface: flags win over env; unknown values fall back to the
|
|
@@ -1745,171 +1809,26 @@ var Connection = class {
|
|
|
1745
1809
|
}
|
|
1746
1810
|
}
|
|
1747
1811
|
};
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
const base = (filePath.split(/[\\/]/).pop() ?? "").toLowerCase();
|
|
1752
|
-
if (base === "package.json") return "package.json";
|
|
1753
|
-
if (base === "go.mod") return "go.mod";
|
|
1754
|
-
if (base === "requirements.txt" || /^requirements.*\.txt$/.test(base)) return "requirements.txt";
|
|
1755
|
-
if (base === "pyproject.toml") return "pyproject.toml";
|
|
1756
|
-
if (base === "cargo.toml") return "Cargo.toml";
|
|
1757
|
-
if (base === "pom.xml") return "pom.xml";
|
|
1758
|
-
if (base === "build.gradle" || base === "build.gradle.kts") return "build.gradle";
|
|
1759
|
-
if (base === "gemfile") return "Gemfile";
|
|
1760
|
-
if (base === "composer.json") return "composer.json";
|
|
1761
|
-
if (base === "pubspec.yaml") return "pubspec.yaml";
|
|
1762
|
-
if (base === "mix.exs") return "mix.exs";
|
|
1763
|
-
if (base.endsWith(".csproj") || base.endsWith(".fsproj") || base.endsWith(".vbproj")) return "csproj";
|
|
1764
|
-
if (base === "dockerfile" || base.startsWith("dockerfile.")) return "Dockerfile";
|
|
1765
|
-
return "unknown";
|
|
1766
|
-
}
|
|
1767
|
-
function isManifest(filePath) {
|
|
1768
|
-
return manifestKind(filePath) !== "unknown";
|
|
1769
|
-
}
|
|
1770
|
-
function esc(s) {
|
|
1771
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1772
|
-
}
|
|
1773
|
-
function findPackageLine(text, pkg, kind) {
|
|
1774
|
-
const lines = text.split(/\r?\n/);
|
|
1775
|
-
const p = esc(pkg);
|
|
1776
|
-
const patterns = (() => {
|
|
1777
|
-
switch (kind) {
|
|
1778
|
-
case "package.json":
|
|
1779
|
-
case "composer.json":
|
|
1780
|
-
return [new RegExp(`^\\s*"${p}"\\s*:`)];
|
|
1781
|
-
case "go.mod":
|
|
1782
|
-
return [new RegExp(`^\\s*(?:require\\s+)?${p}\\s+v?\\d`)];
|
|
1783
|
-
case "requirements.txt":
|
|
1784
|
-
return [new RegExp(`^\\s*${p}\\s*(?:\\[[^\\]]*\\])?\\s*(?:[=<>!~]|$)`, "i")];
|
|
1785
|
-
case "pyproject.toml":
|
|
1786
|
-
case "Cargo.toml":
|
|
1787
|
-
return [
|
|
1788
|
-
new RegExp(`^\\s*${p}\\s*=`),
|
|
1789
|
-
new RegExp(`^\\s*"${p}\\s*(?:[=<>!~\\[]|")`)
|
|
1790
|
-
];
|
|
1791
|
-
case "pom.xml":
|
|
1792
|
-
return [new RegExp(`<artifactId>\\s*${p}\\s*</artifactId>`)];
|
|
1793
|
-
case "build.gradle":
|
|
1794
|
-
return [new RegExp(`["']${p}(?:["':])`)];
|
|
1795
|
-
case "Gemfile":
|
|
1796
|
-
return [new RegExp(`^\\s*gem\\s+["']${p}["']`)];
|
|
1797
|
-
case "pubspec.yaml":
|
|
1798
|
-
return [new RegExp(`^\\s*${p}\\s*:`)];
|
|
1799
|
-
case "mix.exs":
|
|
1800
|
-
return [new RegExp(`\\{\\s*:${p}\\s*,`)];
|
|
1801
|
-
case "csproj":
|
|
1802
|
-
return [new RegExp(`Include\\s*=\\s*"${p}"`, "i")];
|
|
1803
|
-
case "Dockerfile":
|
|
1804
|
-
return [new RegExp(`^\\s*FROM\\s+.*${p}`, "i")];
|
|
1805
|
-
default:
|
|
1806
|
-
return [];
|
|
1807
|
-
}
|
|
1808
|
-
})();
|
|
1809
|
-
for (const re of patterns) {
|
|
1810
|
-
for (let i = 0; i < lines.length; i++) {
|
|
1811
|
-
if (re.test(lines[i])) return i;
|
|
1812
|
-
}
|
|
1813
|
-
}
|
|
1814
|
-
return -1;
|
|
1812
|
+
function projectDir(root3, projectPath) {
|
|
1813
|
+
const rel = projectPath === "" || projectPath === "." ? "" : projectPath;
|
|
1814
|
+
return rel ? path46.resolve(root3, rel) : path46.resolve(root3);
|
|
1815
1815
|
}
|
|
1816
|
-
function
|
|
1817
|
-
const
|
|
1818
|
-
const
|
|
1819
|
-
|
|
1820
|
-
case "package.json":
|
|
1821
|
-
return [/^\s*"node"\s*:/, /^\s*"engines"\s*:/];
|
|
1822
|
-
case "go.mod":
|
|
1823
|
-
return [/^\s*go\s+\d/];
|
|
1824
|
-
case "pyproject.toml":
|
|
1825
|
-
return [/^\s*(?:requires-python|python)\s*=/];
|
|
1826
|
-
case "pom.xml":
|
|
1827
|
-
return [/<(?:java\.version|maven\.compiler\.(?:source|target|release))>/];
|
|
1828
|
-
case "build.gradle":
|
|
1829
|
-
return [/(?:sourceCompatibility|targetCompatibility|JavaVersion)/];
|
|
1830
|
-
case "csproj":
|
|
1831
|
-
return [/<TargetFrameworks?>/i];
|
|
1832
|
-
case "Dockerfile":
|
|
1833
|
-
return [/^\s*FROM\s+/i];
|
|
1834
|
-
default:
|
|
1835
|
-
return [];
|
|
1836
|
-
}
|
|
1837
|
-
})();
|
|
1838
|
-
for (const re of patterns) {
|
|
1839
|
-
for (let i = 0; i < lines.length; i++) {
|
|
1840
|
-
if (re.test(lines[i])) return i;
|
|
1841
|
-
}
|
|
1816
|
+
function projectForFile(root3, projects, filePath) {
|
|
1817
|
+
const dir = path46.dirname(path46.resolve(filePath));
|
|
1818
|
+
for (const proj of projects) {
|
|
1819
|
+
if (projectDir(root3, proj.path) === dir) return proj;
|
|
1842
1820
|
}
|
|
1843
|
-
return
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
const
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
return path46.join(cacheDir(root3), "lsp-scan.json");
|
|
1852
|
-
}
|
|
1853
|
-
function manifestHash(root3) {
|
|
1854
|
-
const files = [];
|
|
1855
|
-
const walk2 = (dir) => {
|
|
1856
|
-
let entries;
|
|
1857
|
-
try {
|
|
1858
|
-
entries = fs14.readdirSync(dir, { withFileTypes: true });
|
|
1859
|
-
} catch {
|
|
1860
|
-
return;
|
|
1861
|
-
}
|
|
1862
|
-
for (const entry of entries) {
|
|
1863
|
-
const abs = path46.join(dir, entry.name);
|
|
1864
|
-
if (entry.isDirectory()) {
|
|
1865
|
-
if (isSkippedDirName(entry.name)) continue;
|
|
1866
|
-
walk2(abs);
|
|
1867
|
-
continue;
|
|
1868
|
-
}
|
|
1869
|
-
if (!entry.isFile()) continue;
|
|
1870
|
-
const base = entry.name.toLowerCase();
|
|
1871
|
-
if (!isManifest(abs) && !SKIP_FILES.has(base)) continue;
|
|
1872
|
-
try {
|
|
1873
|
-
const rel = path46.relative(root3, abs).split(path46.sep).join("/");
|
|
1874
|
-
files.push({ rel, hash: hashBytes(fs14.readFileSync(abs)) });
|
|
1875
|
-
} catch {
|
|
1876
|
-
}
|
|
1877
|
-
}
|
|
1878
|
-
};
|
|
1879
|
-
walk2(root3);
|
|
1880
|
-
files.sort((a, b) => a.rel < b.rel ? -1 : a.rel > b.rel ? 1 : 0);
|
|
1881
|
-
return hashString(canonicalize(files));
|
|
1882
|
-
}
|
|
1883
|
-
function isDependencyFile(root3, filePath) {
|
|
1884
|
-
const rel = path46.relative(path46.resolve(root3), path46.resolve(filePath));
|
|
1885
|
-
if (rel === "" || rel.startsWith("..") || path46.isAbsolute(rel)) return false;
|
|
1886
|
-
const parts = rel.split(path46.sep);
|
|
1887
|
-
if (parts.slice(0, -1).some((dir) => isSkippedDirName(dir))) return false;
|
|
1888
|
-
const base = parts[parts.length - 1].toLowerCase();
|
|
1889
|
-
return isManifest(filePath) || SKIP_FILES.has(base);
|
|
1890
|
-
}
|
|
1891
|
-
function loadScanCache(root3, key2) {
|
|
1892
|
-
try {
|
|
1893
|
-
const raw = JSON.parse(fs14.readFileSync(cachePath(root3), "utf8"));
|
|
1894
|
-
if (raw.version === CACHE_VERSION && raw.manifestHash === key2.manifestHash && raw.toolVersion === key2.toolVersion && raw.offline === key2.offline && raw.artifact) {
|
|
1895
|
-
return { manifestHash: raw.manifestHash, artifact: raw.artifact };
|
|
1821
|
+
if (isManifest(filePath)) return void 0;
|
|
1822
|
+
let best;
|
|
1823
|
+
let bestLen = -1;
|
|
1824
|
+
for (const proj of projects) {
|
|
1825
|
+
const projDir = projectDir(root3, proj.path);
|
|
1826
|
+
if ((dir === projDir || dir.startsWith(projDir + path46.sep)) && projDir.length > bestLen) {
|
|
1827
|
+
best = proj;
|
|
1828
|
+
bestLen = projDir.length;
|
|
1896
1829
|
}
|
|
1897
|
-
} catch {
|
|
1898
|
-
}
|
|
1899
|
-
return null;
|
|
1900
|
-
}
|
|
1901
|
-
function writeScanCache(root3, key2, artifact) {
|
|
1902
|
-
try {
|
|
1903
|
-
fs14.mkdirSync(cacheDir(root3), { recursive: true });
|
|
1904
|
-
fs14.writeFileSync(
|
|
1905
|
-
cachePath(root3),
|
|
1906
|
-
stableStringify(
|
|
1907
|
-
{ version: CACHE_VERSION, manifestHash: key2.manifestHash, toolVersion: key2.toolVersion, offline: key2.offline, artifact },
|
|
1908
|
-
0
|
|
1909
|
-
)
|
|
1910
|
-
);
|
|
1911
|
-
} catch {
|
|
1912
1830
|
}
|
|
1831
|
+
return best;
|
|
1913
1832
|
}
|
|
1914
1833
|
var MAX_ENTRIES = 1e3;
|
|
1915
1834
|
var KEEP_ENTRIES = 500;
|
|
@@ -1928,7 +1847,7 @@ function parseLine(line) {
|
|
|
1928
1847
|
}
|
|
1929
1848
|
function readHistory(root3) {
|
|
1930
1849
|
try {
|
|
1931
|
-
return
|
|
1850
|
+
return fs13.readFileSync(historyPath(root3), "utf8").split("\n").filter((l) => l.trim()).map(parseLine).filter((e) => e !== null);
|
|
1932
1851
|
} catch {
|
|
1933
1852
|
return [];
|
|
1934
1853
|
}
|
|
@@ -1955,14 +1874,14 @@ function recordScore(root3, entry) {
|
|
|
1955
1874
|
}
|
|
1956
1875
|
}
|
|
1957
1876
|
const file = historyPath(root3);
|
|
1958
|
-
|
|
1877
|
+
fs13.mkdirSync(path46.dirname(file), { recursive: true });
|
|
1959
1878
|
ensureVibgrateGitignore(root3);
|
|
1960
|
-
|
|
1879
|
+
fs13.appendFileSync(file, `${JSON.stringify(entry)}
|
|
1961
1880
|
`);
|
|
1962
1881
|
const all = readHistory(root3);
|
|
1963
1882
|
if (all.length > MAX_ENTRIES) {
|
|
1964
1883
|
const kept = all.slice(-KEEP_ENTRIES);
|
|
1965
|
-
|
|
1884
|
+
fs13.writeFileSync(file, kept.map((e) => JSON.stringify(e)).join("\n") + "\n");
|
|
1966
1885
|
}
|
|
1967
1886
|
} catch {
|
|
1968
1887
|
}
|
|
@@ -1985,7 +1904,7 @@ function readIgnores(root3, now = Date.now()) {
|
|
|
1985
1904
|
const out2 = /* @__PURE__ */ new Map();
|
|
1986
1905
|
let raw;
|
|
1987
1906
|
try {
|
|
1988
|
-
raw =
|
|
1907
|
+
raw = fs13.readFileSync(ignoreFilePath(root3), "utf8");
|
|
1989
1908
|
} catch {
|
|
1990
1909
|
return out2;
|
|
1991
1910
|
}
|
|
@@ -2012,7 +1931,7 @@ function inventoryKey(projectPath, pkg) {
|
|
|
2012
1931
|
}
|
|
2013
1932
|
function readInventory(root3) {
|
|
2014
1933
|
try {
|
|
2015
|
-
const parsed = JSON.parse(
|
|
1934
|
+
const parsed = JSON.parse(fs13.readFileSync(inventoryPath(root3), "utf8"));
|
|
2016
1935
|
if (typeof parsed.ts === "string" && typeof parsed.methodology === "string" && Array.isArray(parsed.drifted) && parsed.drifted.every((d) => typeof d === "string")) {
|
|
2017
1936
|
return parsed;
|
|
2018
1937
|
}
|
|
@@ -2023,7 +1942,7 @@ function readInventory(root3) {
|
|
|
2023
1942
|
function recordInventory(root3, snap) {
|
|
2024
1943
|
try {
|
|
2025
1944
|
ensureVibgrateGitignore(root3);
|
|
2026
|
-
|
|
1945
|
+
fs13.writeFileSync(inventoryPath(root3), `${JSON.stringify(snap)}
|
|
2027
1946
|
`);
|
|
2028
1947
|
} catch {
|
|
2029
1948
|
}
|
|
@@ -2075,7 +1994,23 @@ async function runAsk(graph, params, ctx) {
|
|
|
2075
1994
|
let result = null;
|
|
2076
1995
|
let mode = "lexical";
|
|
2077
1996
|
let note;
|
|
2078
|
-
if (wantSemantic) {
|
|
1997
|
+
if (wantSemantic && ctx.semanticSession) {
|
|
1998
|
+
try {
|
|
1999
|
+
const ranked = await withTimeout(
|
|
2000
|
+
ctx.semanticSession.rank(question, graph.provenance?.corpusHash),
|
|
2001
|
+
semanticBudgetMs(),
|
|
2002
|
+
"daemon ranking over budget"
|
|
2003
|
+
);
|
|
2004
|
+
if (ranked) {
|
|
2005
|
+
log(`ask: ranked by vgd against ${ranked.vectors} vector(s) \u2014 no local model load`);
|
|
2006
|
+
result = await queryGraphSemantic(graph, question, { budget, semanticRanked: ranked.ranked });
|
|
2007
|
+
mode = `semantic (vgd${ranked.model ? `, ${ranked.model}` : ""})`;
|
|
2008
|
+
}
|
|
2009
|
+
} catch {
|
|
2010
|
+
log("ask: vgd ranking unavailable \u2014 trying the in-process semantic path");
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
if (wantSemantic && !result) {
|
|
2079
2014
|
const budgetMs = semanticBudgetMs();
|
|
2080
2015
|
log(`ask: trying the semantic path (budget ${Math.round(budgetMs / 1e3)}s)`);
|
|
2081
2016
|
let reason;
|
|
@@ -2556,7 +2491,11 @@ function architectureWire(arch) {
|
|
|
2556
2491
|
if (arch.workspaceEdgesCapped) out2.workspaceEdgesCapped = true;
|
|
2557
2492
|
if (arch.violations) out2.violations = arch.violations;
|
|
2558
2493
|
if (arch.violationsCapped) out2.violationsCapped = true;
|
|
2559
|
-
if (arch.boundaryProfile)
|
|
2494
|
+
if (arch.boundaryProfile) {
|
|
2495
|
+
out2.boundaryProfile = arch.boundaryProfile;
|
|
2496
|
+
const rules = boundaryProfileRules(arch.boundaryProfile);
|
|
2497
|
+
if (rules.length > 0) out2.boundaryRules = rules;
|
|
2498
|
+
}
|
|
2560
2499
|
if (arch.structure) out2.structure = arch.structure;
|
|
2561
2500
|
if (arch.generated) out2.generated = true;
|
|
2562
2501
|
if (arch.generatedBy) out2.generatedBy = arch.generatedBy;
|
|
@@ -2586,6 +2525,7 @@ var VibgrateLanguageServer = class {
|
|
|
2586
2525
|
constructor(opts, output = process.stdout) {
|
|
2587
2526
|
this.opts = opts;
|
|
2588
2527
|
this.conn = new Connection(process.stdin, output);
|
|
2528
|
+
this.semanticSession = new DaemonSemanticSession(opts.root, { disabled: opts.daemon === false });
|
|
2589
2529
|
this.refresher = new RefreshScheduler({
|
|
2590
2530
|
root: opts.root,
|
|
2591
2531
|
graphPath: () => resolveGraphPath(opts.root),
|
|
@@ -2623,6 +2563,17 @@ var VibgrateLanguageServer = class {
|
|
|
2623
2563
|
* single Ask block for over a minute. See engine/refresh-scheduler.ts.
|
|
2624
2564
|
*/
|
|
2625
2565
|
refresher;
|
|
2566
|
+
/**
|
|
2567
|
+
* The local runtime's semantic index, held for the life of the server.
|
|
2568
|
+
* Ranking there means the native embedding backend is never loaded into this
|
|
2569
|
+
* process — the failure this server has the least tolerance for, since a
|
|
2570
|
+
* SIGTRAP from the addon kills it outright mid-request.
|
|
2571
|
+
*/
|
|
2572
|
+
semanticSession;
|
|
2573
|
+
/** In-flight on-demand scans of open manifests the workspace scan skipped. */
|
|
2574
|
+
openManifestScans = /* @__PURE__ */ new Set();
|
|
2575
|
+
/** Failed on-demand scans — retry only after the next workspace scan. */
|
|
2576
|
+
openManifestFailed = /* @__PURE__ */ new Set();
|
|
2626
2577
|
register() {
|
|
2627
2578
|
this.conn.onRequest("initialize", () => ({
|
|
2628
2579
|
capabilities: {
|
|
@@ -2680,6 +2631,7 @@ var VibgrateLanguageServer = class {
|
|
|
2680
2631
|
this.conn.onRequest("vibgrate/score/forFile", (_m, params) => this.onScoreForFile(params));
|
|
2681
2632
|
this.conn.onRequest("vibgrate/score/forProject", (_m, params) => this.onScoreForProject(params));
|
|
2682
2633
|
this.conn.onRequest("vibgrate/architecture", (_m, params) => this.onArchitecture(params));
|
|
2634
|
+
this.conn.onRequest("vibgrate/architecture/projects", () => this.onArchitectureProjects());
|
|
2683
2635
|
this.conn.onRequest("vibgrate/score/history", (_m, params) => {
|
|
2684
2636
|
const p = params;
|
|
2685
2637
|
const days = typeof p?.days === "number" && p.days > 0 && p.days <= 365 ? p.days : 90;
|
|
@@ -2718,8 +2670,13 @@ var VibgrateLanguageServer = class {
|
|
|
2718
2670
|
this.scanning = true;
|
|
2719
2671
|
const force = this.forceNextScan;
|
|
2720
2672
|
this.forceNextScan = false;
|
|
2673
|
+
this.openManifestFailed.clear();
|
|
2721
2674
|
try {
|
|
2722
|
-
const cacheKey = {
|
|
2675
|
+
const cacheKey = {
|
|
2676
|
+
manifestHash: await this.sharedManifestHash() ?? manifestHash(this.opts.root),
|
|
2677
|
+
toolVersion: VERSION,
|
|
2678
|
+
offline: this.opts.offline
|
|
2679
|
+
};
|
|
2723
2680
|
const cached2 = force ? null : loadScanCache(this.opts.root, cacheKey);
|
|
2724
2681
|
let fromCache = false;
|
|
2725
2682
|
if (cached2) {
|
|
@@ -2845,7 +2802,10 @@ var VibgrateLanguageServer = class {
|
|
|
2845
2802
|
if (!a || text === void 0) return;
|
|
2846
2803
|
const filePath = uriToPath(uri);
|
|
2847
2804
|
const kind = manifestKind(filePath);
|
|
2848
|
-
const project =
|
|
2805
|
+
const project = projectForFile2(this.opts.root, a, filePath);
|
|
2806
|
+
if (!project && isManifest(filePath)) {
|
|
2807
|
+
void this.scanOpenManifest(uri, filePath);
|
|
2808
|
+
}
|
|
2849
2809
|
const items = [];
|
|
2850
2810
|
for (const dep of project?.dependencies ?? []) {
|
|
2851
2811
|
if (dep.drift === "current" || dep.drift === "unknown") continue;
|
|
@@ -2890,6 +2850,58 @@ var VibgrateLanguageServer = class {
|
|
|
2890
2850
|
});
|
|
2891
2851
|
this.conn.notify("textDocument/publishDiagnostics", { uri, diagnostics });
|
|
2892
2852
|
}
|
|
2853
|
+
/**
|
|
2854
|
+
* Workspace scan skipped this package (auto-exclude / timeout). Score it
|
|
2855
|
+
* alone so the open editor can show overlays; do not write the result into
|
|
2856
|
+
* the workspace scan cache (billing / repo score stay on the official scan).
|
|
2857
|
+
*/
|
|
2858
|
+
async scanOpenManifest(uri, filePath) {
|
|
2859
|
+
const relDir = path46.relative(this.opts.root, path46.dirname(path46.resolve(filePath)));
|
|
2860
|
+
const key2 = relDir === "" ? "." : relDir;
|
|
2861
|
+
if (this.openManifestScans.has(key2) || this.openManifestFailed.has(key2)) return;
|
|
2862
|
+
if (key2 === "." || key2.startsWith("..")) return;
|
|
2863
|
+
this.openManifestScans.add(key2);
|
|
2864
|
+
try {
|
|
2865
|
+
this.conn.notify("window/logMessage", {
|
|
2866
|
+
type: 3,
|
|
2867
|
+
message: `Vibgrate: scoring open package ${key2} (not in the workspace scan) so editor overlays can render.`
|
|
2868
|
+
});
|
|
2869
|
+
const advanced = await loadAdvancedScanHook();
|
|
2870
|
+
const scanOpts = {
|
|
2871
|
+
format: "json",
|
|
2872
|
+
concurrency: 8,
|
|
2873
|
+
offline: this.opts.offline,
|
|
2874
|
+
noLocalArtifacts: true,
|
|
2875
|
+
noGraph: true,
|
|
2876
|
+
quiet: true,
|
|
2877
|
+
vibgrateVersion: VERSION
|
|
2878
|
+
};
|
|
2879
|
+
const sub = await runCoreScanSilently(path46.dirname(filePath), scanOpts, advanced);
|
|
2880
|
+
const proj = (sub.projects ?? []).find((p) => p.path === "." || p.path === "") ?? sub.projects?.[0];
|
|
2881
|
+
if (!proj || !this.artifact) {
|
|
2882
|
+
this.openManifestFailed.add(key2);
|
|
2883
|
+
return;
|
|
2884
|
+
}
|
|
2885
|
+
proj.path = key2;
|
|
2886
|
+
this.artifact.projects = [...(this.artifact.projects ?? []).filter((p) => p.path !== key2), proj];
|
|
2887
|
+
for (const f of sub.findings ?? []) {
|
|
2888
|
+
if (f.location === "." || f.location === "" || f.location === key2) {
|
|
2889
|
+
this.artifact.findings = [...(this.artifact.findings ?? []).filter((x) => !(x.ruleId === f.ruleId && x.location === key2)), { ...f, location: key2 }];
|
|
2890
|
+
}
|
|
2891
|
+
}
|
|
2892
|
+
this.publishScore();
|
|
2893
|
+
this.publishForDoc(uri);
|
|
2894
|
+
} catch (err) {
|
|
2895
|
+
this.openManifestFailed.add(key2);
|
|
2896
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2897
|
+
this.conn.notify("window/logMessage", {
|
|
2898
|
+
type: 3,
|
|
2899
|
+
message: `Vibgrate: could not score open package ${key2}: ${message}`
|
|
2900
|
+
});
|
|
2901
|
+
} finally {
|
|
2902
|
+
this.openManifestScans.delete(key2);
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2893
2905
|
// ── Requests ─────────────────────────────────────────────────────────────
|
|
2894
2906
|
onHover(params) {
|
|
2895
2907
|
const p = params;
|
|
@@ -2900,7 +2912,7 @@ var VibgrateLanguageServer = class {
|
|
|
2900
2912
|
if (!uri || line === void 0 || !a || text === void 0) return null;
|
|
2901
2913
|
const filePath = uriToPath(uri);
|
|
2902
2914
|
const kind = manifestKind(filePath);
|
|
2903
|
-
const project =
|
|
2915
|
+
const project = projectForFile2(this.opts.root, a, filePath);
|
|
2904
2916
|
const dep = (project?.dependencies ?? []).find(
|
|
2905
2917
|
(d) => findPackageLine(text, d.package, kind) === line
|
|
2906
2918
|
);
|
|
@@ -2923,18 +2935,31 @@ var VibgrateLanguageServer = class {
|
|
|
2923
2935
|
const uri = p.textDocument?.uri;
|
|
2924
2936
|
const a = this.artifact;
|
|
2925
2937
|
if (!uri || !a || !this.docs.has(uri)) return [];
|
|
2926
|
-
const
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2938
|
+
const filePath = uriToPath(uri);
|
|
2939
|
+
const project = projectForFile2(this.opts.root, a, filePath);
|
|
2940
|
+
if (!project) {
|
|
2941
|
+
return [
|
|
2942
|
+
{
|
|
2943
|
+
range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } },
|
|
2944
|
+
command: {
|
|
2945
|
+
title: "Vibgrate \xB7 this package is not in the workspace scan",
|
|
2946
|
+
command: "vibgrate.openPanel",
|
|
2947
|
+
arguments: []
|
|
2948
|
+
}
|
|
2949
|
+
}
|
|
2950
|
+
];
|
|
2951
|
+
}
|
|
2952
|
+
const behind = (project.dependencies ?? []).filter(
|
|
2953
|
+
(d) => d.drift === "major-behind" || d.drift === "minor-behind"
|
|
2954
|
+
).length;
|
|
2932
2955
|
const eol = (a.findings ?? []).filter(
|
|
2933
|
-
(f) => f.ruleId === "vibgrate/runtime-eol" || f.ruleId === "vibgrate/eol"
|
|
2956
|
+
(f) => sameProject(f.location, project.path) && (f.ruleId === "vibgrate/runtime-eol" || f.ruleId === "vibgrate/eol")
|
|
2934
2957
|
).length;
|
|
2935
|
-
const estimated = (a.drift.mode ?? (hasReleaseDates(a) ? "verified" : "estimated")) === "estimated";
|
|
2958
|
+
const estimated = (project.drift?.mode ?? a.drift.mode ?? (hasReleaseDates(a) ? "verified" : "estimated")) === "estimated";
|
|
2936
2959
|
const mode = estimated ? "~" : "";
|
|
2937
|
-
const
|
|
2960
|
+
const score = project.drift?.score ?? a.drift.score;
|
|
2961
|
+
const band = project.drift?.riskLevel ?? a.drift.riskLevel;
|
|
2962
|
+
const title = `Vibgrate \xB7 drift ${mode}${score} (${band}) \xB7 ${behind} behind \xB7 ${eol} EOL`;
|
|
2938
2963
|
return [
|
|
2939
2964
|
{
|
|
2940
2965
|
range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } },
|
|
@@ -3040,9 +3065,23 @@ var VibgrateLanguageServer = class {
|
|
|
3040
3065
|
root: this.opts.root,
|
|
3041
3066
|
offline: this.opts.offline,
|
|
3042
3067
|
semantic: this.opts.semantic,
|
|
3068
|
+
semanticSession: this.semanticSession,
|
|
3043
3069
|
log: trace
|
|
3044
3070
|
});
|
|
3045
3071
|
}
|
|
3072
|
+
/**
|
|
3073
|
+
* The daemon's manifest digest for this workspace, or null when there is no
|
|
3074
|
+
* daemon (or it has not been told about this repo yet) — in which case the
|
|
3075
|
+
* caller computes it locally, exactly as before.
|
|
3076
|
+
*/
|
|
3077
|
+
async sharedManifestHash() {
|
|
3078
|
+
try {
|
|
3079
|
+
const deps = await this.semanticSession.depContext();
|
|
3080
|
+
return deps?.manifestHash ?? null;
|
|
3081
|
+
} catch {
|
|
3082
|
+
return null;
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3046
3085
|
/**
|
|
3047
3086
|
* `vibgrate/enrich` — lazy vulnerability enrichment for one expanded package,
|
|
3048
3087
|
* straight from OSV.dev (never our API). Honours the server's offline flag.
|
|
@@ -3090,7 +3129,7 @@ var VibgrateLanguageServer = class {
|
|
|
3090
3129
|
const absManifest = path46.resolve(this.opts.root, relManifest);
|
|
3091
3130
|
let text = null;
|
|
3092
3131
|
try {
|
|
3093
|
-
if (
|
|
3132
|
+
if (fs13.existsSync(absManifest)) text = fs13.readFileSync(absManifest, "utf8");
|
|
3094
3133
|
} catch {
|
|
3095
3134
|
text = null;
|
|
3096
3135
|
}
|
|
@@ -3140,7 +3179,7 @@ var VibgrateLanguageServer = class {
|
|
|
3140
3179
|
const p = params;
|
|
3141
3180
|
const a = this.artifact;
|
|
3142
3181
|
if (!a || !p.uri) return null;
|
|
3143
|
-
const project =
|
|
3182
|
+
const project = projectForFile2(this.opts.root, a, uriToPath(p.uri));
|
|
3144
3183
|
return project ? scoreForProject(this.opts.root, a, project) : null;
|
|
3145
3184
|
}
|
|
3146
3185
|
/**
|
|
@@ -3181,6 +3220,37 @@ var VibgrateLanguageServer = class {
|
|
|
3181
3220
|
lockfilePath: lockfileRelativePath(this.opts.root, project)
|
|
3182
3221
|
};
|
|
3183
3222
|
}
|
|
3223
|
+
/**
|
|
3224
|
+
* `vibgrate/architecture/projects` — the workspace-scope Projects view.
|
|
3225
|
+
* One row per scanned project that produced architecture data, so a client
|
|
3226
|
+
* can render the whole portfolio without N round trips. Projects the
|
|
3227
|
+
* scanner never classified are omitted rather than shown as empty rows.
|
|
3228
|
+
*/
|
|
3229
|
+
onArchitectureProjects() {
|
|
3230
|
+
const a = this.artifact;
|
|
3231
|
+
if (!a) return null;
|
|
3232
|
+
const rows = [];
|
|
3233
|
+
for (const project of a.projects ?? []) {
|
|
3234
|
+
const arch = project.architecture;
|
|
3235
|
+
if (!arch) continue;
|
|
3236
|
+
const row = {
|
|
3237
|
+
path: project.path,
|
|
3238
|
+
name: project.name,
|
|
3239
|
+
// `violations` absent means "no graph was available to check against",
|
|
3240
|
+
// which is not the same as "checked and clean" — keep them distinct.
|
|
3241
|
+
violations: arch.violations ? arch.violations.length : null,
|
|
3242
|
+
layerCount: arch.layers.filter((l) => l.fileCount > 0).length,
|
|
3243
|
+
fileCount: arch.totalClassified
|
|
3244
|
+
};
|
|
3245
|
+
if (arch.projectKind) row.projectKind = arch.projectKind;
|
|
3246
|
+
if (arch.artifactKind) row.artifactKind = arch.artifactKind;
|
|
3247
|
+
if (arch.structure) row.structure = arch.structure.primary;
|
|
3248
|
+
if (arch.supportLevel !== void 0) row.supportLevel = arch.supportLevel;
|
|
3249
|
+
if (arch.packIds && arch.packIds.length > 0) row.packIds = arch.packIds;
|
|
3250
|
+
rows.push(row);
|
|
3251
|
+
}
|
|
3252
|
+
return rows;
|
|
3253
|
+
}
|
|
3184
3254
|
};
|
|
3185
3255
|
function uriToPath(uri) {
|
|
3186
3256
|
try {
|
|
@@ -3292,18 +3362,8 @@ function buildProjectRefs(rootDir, projects) {
|
|
|
3292
3362
|
refs.sort((a, b) => a.path.localeCompare(b.path));
|
|
3293
3363
|
return refs.length > 0 ? refs : void 0;
|
|
3294
3364
|
}
|
|
3295
|
-
function
|
|
3296
|
-
|
|
3297
|
-
let best;
|
|
3298
|
-
let bestLen = -1;
|
|
3299
|
-
for (const proj of a.projects ?? []) {
|
|
3300
|
-
const projDir = path46.resolve(root3, proj.path);
|
|
3301
|
-
if ((dir === projDir || dir.startsWith(projDir + path46.sep)) && projDir.length > bestLen) {
|
|
3302
|
-
best = proj;
|
|
3303
|
-
bestLen = projDir.length;
|
|
3304
|
-
}
|
|
3305
|
-
}
|
|
3306
|
-
return best;
|
|
3365
|
+
function projectForFile2(root3, a, filePath) {
|
|
3366
|
+
return projectForFile(root3, a.projects ?? [], filePath);
|
|
3307
3367
|
}
|
|
3308
3368
|
function sameProject(location, projectPath) {
|
|
3309
3369
|
return path46.normalize(location) === path46.normalize(projectPath);
|
|
@@ -3379,7 +3439,7 @@ function buildBreakdown(rootDir, projects) {
|
|
|
3379
3439
|
const absManifest = path46.resolve(rootDir, relManifest);
|
|
3380
3440
|
let text = null;
|
|
3381
3441
|
try {
|
|
3382
|
-
if (
|
|
3442
|
+
if (fs13.existsSync(absManifest)) text = fs13.readFileSync(absManifest, "utf8");
|
|
3383
3443
|
} catch {
|
|
3384
3444
|
text = null;
|
|
3385
3445
|
}
|
|
@@ -3444,34 +3504,34 @@ function buildBreakdown(rootDir, projects) {
|
|
|
3444
3504
|
}
|
|
3445
3505
|
function manifestRelativePath(proj) {
|
|
3446
3506
|
const base = proj.path === "." || proj.path === "" ? "" : proj.path;
|
|
3447
|
-
const
|
|
3507
|
+
const join35 = (name) => base ? path46.join(base, name) : name;
|
|
3448
3508
|
switch (proj.type) {
|
|
3449
3509
|
case "node":
|
|
3450
3510
|
case "typescript":
|
|
3451
|
-
return
|
|
3511
|
+
return join35("package.json");
|
|
3452
3512
|
case "python":
|
|
3453
|
-
return
|
|
3513
|
+
return join35("pyproject.toml");
|
|
3454
3514
|
case "go":
|
|
3455
|
-
return
|
|
3515
|
+
return join35("go.mod");
|
|
3456
3516
|
case "rust":
|
|
3457
|
-
return
|
|
3517
|
+
return join35("Cargo.toml");
|
|
3458
3518
|
case "ruby":
|
|
3459
|
-
return
|
|
3519
|
+
return join35("Gemfile");
|
|
3460
3520
|
case "php":
|
|
3461
|
-
return
|
|
3521
|
+
return join35("composer.json");
|
|
3462
3522
|
case "java":
|
|
3463
3523
|
case "kotlin":
|
|
3464
3524
|
case "scala":
|
|
3465
3525
|
case "groovy":
|
|
3466
|
-
return
|
|
3526
|
+
return join35("pom.xml");
|
|
3467
3527
|
case "dotnet":
|
|
3468
|
-
return
|
|
3528
|
+
return join35(proj.name ? `${proj.name}.csproj` : "Directory.Build.props");
|
|
3469
3529
|
case "dart":
|
|
3470
|
-
return
|
|
3530
|
+
return join35("pubspec.yaml");
|
|
3471
3531
|
case "elixir":
|
|
3472
|
-
return
|
|
3532
|
+
return join35("mix.exs");
|
|
3473
3533
|
default:
|
|
3474
|
-
return
|
|
3534
|
+
return join35("package.json");
|
|
3475
3535
|
}
|
|
3476
3536
|
}
|
|
3477
3537
|
function lockfileRelativePath(rootDir, proj) {
|
|
@@ -3504,7 +3564,7 @@ function lockfileRelativePath(rootDir, proj) {
|
|
|
3504
3564
|
for (const name of candidateNames) {
|
|
3505
3565
|
const rel = dir ? path46.join(dir, name) : name;
|
|
3506
3566
|
try {
|
|
3507
|
-
if (
|
|
3567
|
+
if (fs13.existsSync(path46.join(rootDir, rel))) return rel;
|
|
3508
3568
|
} catch {
|
|
3509
3569
|
}
|
|
3510
3570
|
}
|
|
@@ -3576,9 +3636,9 @@ function lookupImportFiles(map, pkg) {
|
|
|
3576
3636
|
function firstPackageMentionLine(root3, relFile, pkg) {
|
|
3577
3637
|
try {
|
|
3578
3638
|
const abs = path46.resolve(root3, relFile);
|
|
3579
|
-
const stat2 =
|
|
3639
|
+
const stat2 = fs13.statSync(abs);
|
|
3580
3640
|
if (!stat2.isFile() || stat2.size > 256 * 1024) return null;
|
|
3581
|
-
const text =
|
|
3641
|
+
const text = fs13.readFileSync(abs, "utf8");
|
|
3582
3642
|
const tokens = [pkg];
|
|
3583
3643
|
if (pkg.startsWith("@")) {
|
|
3584
3644
|
const parts = pkg.split("/");
|
|
@@ -3774,7 +3834,7 @@ function hoverMarkdown(dep, contribution, state) {
|
|
|
3774
3834
|
return lines.join("\n");
|
|
3775
3835
|
}
|
|
3776
3836
|
function startLanguageServer(opts) {
|
|
3777
|
-
if (!
|
|
3837
|
+
if (!fs13.existsSync(opts.root)) {
|
|
3778
3838
|
process.stderr.write(`vg lsp: root does not exist: ${opts.root}
|
|
3779
3839
|
`);
|
|
3780
3840
|
process.exit(1);
|
|
@@ -3809,7 +3869,8 @@ function registerLsp(program) {
|
|
|
3809
3869
|
offline: global.local === true,
|
|
3810
3870
|
diagnostics: opts.diagnostics === true,
|
|
3811
3871
|
graph: opts.graph !== false,
|
|
3812
|
-
semantic: opts.semantic !== false
|
|
3872
|
+
semantic: opts.semantic !== false,
|
|
3873
|
+
daemon: global.daemon
|
|
3813
3874
|
});
|
|
3814
3875
|
await new Promise(() => {
|
|
3815
3876
|
});
|
|
@@ -3826,9 +3887,9 @@ function installClaudeHooks(root3, vgBin = "vg") {
|
|
|
3826
3887
|
const file = path46.join(root3, ".claude", "settings.json");
|
|
3827
3888
|
const rel = path46.join(".claude", "settings.json");
|
|
3828
3889
|
let settings = {};
|
|
3829
|
-
if (
|
|
3890
|
+
if (fs13.existsSync(file)) {
|
|
3830
3891
|
try {
|
|
3831
|
-
const parsed = JSON.parse(
|
|
3892
|
+
const parsed = JSON.parse(fs13.readFileSync(file, "utf8"));
|
|
3832
3893
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
3833
3894
|
return { file: rel, status: "skipped", note: "settings.json is not a JSON object \u2014 left untouched" };
|
|
3834
3895
|
}
|
|
@@ -3867,10 +3928,10 @@ function installClaudeHooks(root3, vgBin = "vg") {
|
|
|
3867
3928
|
function uninstallClaudeHooks(root3) {
|
|
3868
3929
|
const file = path46.join(root3, ".claude", "settings.json");
|
|
3869
3930
|
const rel = path46.join(".claude", "settings.json");
|
|
3870
|
-
if (!
|
|
3931
|
+
if (!fs13.existsSync(file)) return { file: rel, status: "unchanged" };
|
|
3871
3932
|
let settings;
|
|
3872
3933
|
try {
|
|
3873
|
-
settings = JSON.parse(
|
|
3934
|
+
settings = JSON.parse(fs13.readFileSync(file, "utf8"));
|
|
3874
3935
|
} catch {
|
|
3875
3936
|
return { file: rel, status: "skipped", note: "settings.json is not parseable JSON \u2014 left untouched" };
|
|
3876
3937
|
}
|
|
@@ -3892,8 +3953,8 @@ function uninstallClaudeHooks(root3) {
|
|
|
3892
3953
|
return { file: rel, status: "written" };
|
|
3893
3954
|
}
|
|
3894
3955
|
function writeSettings(file, settings) {
|
|
3895
|
-
|
|
3896
|
-
|
|
3956
|
+
fs13.mkdirSync(path46.dirname(file), { recursive: true });
|
|
3957
|
+
fs13.writeFileSync(file, `${JSON.stringify(settings, null, 2)}
|
|
3897
3958
|
`);
|
|
3898
3959
|
}
|
|
3899
3960
|
|
|
@@ -4020,15 +4081,15 @@ function stateFile() {
|
|
|
4020
4081
|
}
|
|
4021
4082
|
function readConsent() {
|
|
4022
4083
|
try {
|
|
4023
|
-
return JSON.parse(
|
|
4084
|
+
return JSON.parse(fs13.readFileSync(stateFile(), "utf8"));
|
|
4024
4085
|
} catch {
|
|
4025
4086
|
return {};
|
|
4026
4087
|
}
|
|
4027
4088
|
}
|
|
4028
4089
|
function writeConsent(state) {
|
|
4029
4090
|
try {
|
|
4030
|
-
|
|
4031
|
-
|
|
4091
|
+
fs13.mkdirSync(path46.dirname(stateFile()), { recursive: true });
|
|
4092
|
+
fs13.writeFileSync(stateFile(), JSON.stringify(state));
|
|
4032
4093
|
} catch {
|
|
4033
4094
|
}
|
|
4034
4095
|
}
|
|
@@ -4038,8 +4099,8 @@ function kernelDisabled() {
|
|
|
4038
4099
|
}
|
|
4039
4100
|
function moduleInstalledAt(dir) {
|
|
4040
4101
|
try {
|
|
4041
|
-
const meta = JSON.parse(
|
|
4042
|
-
if (
|
|
4102
|
+
const meta = JSON.parse(fs13.readFileSync(path46.join(dir, ".module.json"), "utf8"));
|
|
4103
|
+
if (fs13.existsSync(path46.join(dir, "index.js"))) {
|
|
4043
4104
|
return { installed: true, version: meta.version };
|
|
4044
4105
|
}
|
|
4045
4106
|
} catch {
|
|
@@ -4113,8 +4174,8 @@ async function installModule(mod, opts = {}) {
|
|
|
4113
4174
|
verifyIntegrity(gz, dist.integrity, dist.shasum);
|
|
4114
4175
|
const entries = untar(zlib.gunzipSync(gz));
|
|
4115
4176
|
const dir = mod.dir();
|
|
4116
|
-
|
|
4117
|
-
|
|
4177
|
+
fs13.rmSync(dir, { recursive: true, force: true });
|
|
4178
|
+
fs13.mkdirSync(dir, { recursive: true });
|
|
4118
4179
|
let wrote = 0;
|
|
4119
4180
|
for (const e of entries) {
|
|
4120
4181
|
let rel = null;
|
|
@@ -4123,15 +4184,15 @@ async function installModule(mod, opts = {}) {
|
|
|
4123
4184
|
if (!rel) continue;
|
|
4124
4185
|
const target = path46.join(dir, rel);
|
|
4125
4186
|
if (!target.startsWith(dir + path46.sep) && target !== dir) throw new Error(`unsafe extract path: ${rel}`);
|
|
4126
|
-
|
|
4127
|
-
|
|
4187
|
+
fs13.mkdirSync(path46.dirname(target), { recursive: true });
|
|
4188
|
+
fs13.writeFileSync(target, e.body);
|
|
4128
4189
|
wrote += 1;
|
|
4129
4190
|
}
|
|
4130
|
-
if (!wrote || !
|
|
4131
|
-
|
|
4191
|
+
if (!wrote || !fs13.existsSync(path46.join(dir, "index.js"))) {
|
|
4192
|
+
fs13.rmSync(dir, { recursive: true, force: true });
|
|
4132
4193
|
return { status: "unavailable", detail: "package layout not recognized (no dist/index.js)" };
|
|
4133
4194
|
}
|
|
4134
|
-
|
|
4195
|
+
fs13.writeFileSync(path46.join(dir, ".module.json"), JSON.stringify({ name: mod.npmName, version }));
|
|
4135
4196
|
mod.onChanged?.();
|
|
4136
4197
|
return { status: "installed", version };
|
|
4137
4198
|
} catch (e) {
|
|
@@ -4139,7 +4200,7 @@ async function installModule(mod, opts = {}) {
|
|
|
4139
4200
|
}
|
|
4140
4201
|
}
|
|
4141
4202
|
function removeModule(mod) {
|
|
4142
|
-
|
|
4203
|
+
fs13.rmSync(mod.dir(), { recursive: true, force: true });
|
|
4143
4204
|
mod.onChanged?.();
|
|
4144
4205
|
}
|
|
4145
4206
|
|
|
@@ -4184,7 +4245,7 @@ function candidatePaths() {
|
|
|
4184
4245
|
if (custom) {
|
|
4185
4246
|
const p = path46.resolve(custom);
|
|
4186
4247
|
try {
|
|
4187
|
-
if (
|
|
4248
|
+
if (fs13.statSync(p).isDirectory()) return [path46.join(p, "index.js")];
|
|
4188
4249
|
} catch {
|
|
4189
4250
|
}
|
|
4190
4251
|
return [p];
|
|
@@ -4200,7 +4261,7 @@ async function loadHcsEngine() {
|
|
|
4200
4261
|
cached = null;
|
|
4201
4262
|
if (disabled()) return cached;
|
|
4202
4263
|
for (const p of candidatePaths()) {
|
|
4203
|
-
if (!
|
|
4264
|
+
if (!fs13.existsSync(p)) continue;
|
|
4204
4265
|
try {
|
|
4205
4266
|
const mod = await import(pathToFileURL(p).href);
|
|
4206
4267
|
const engine = await mod.createHcsEngine?.();
|
|
@@ -4367,7 +4428,7 @@ function hookContext(payloadText, root3, graphOverride) {
|
|
|
4367
4428
|
let graph;
|
|
4368
4429
|
try {
|
|
4369
4430
|
const preferred = loadGraphPreferIndex(root3, graphPath);
|
|
4370
|
-
graph = preferred ? preferred.graph : parseGraph(
|
|
4431
|
+
graph = preferred ? preferred.graph : parseGraph(fs13.readFileSync(graphPath, "utf8"));
|
|
4371
4432
|
} catch {
|
|
4372
4433
|
return null;
|
|
4373
4434
|
}
|
|
@@ -4389,7 +4450,7 @@ function registerHook(program) {
|
|
|
4389
4450
|
const global = readGlobal(this);
|
|
4390
4451
|
const root3 = rootOf(global);
|
|
4391
4452
|
try {
|
|
4392
|
-
const stdin =
|
|
4453
|
+
const stdin = fs13.readFileSync(0, "utf8");
|
|
4393
4454
|
const context = hookContext(stdin, root3, global.graph);
|
|
4394
4455
|
if (context) {
|
|
4395
4456
|
process.stdout.write(
|
|
@@ -4410,7 +4471,7 @@ function registerShare(program) {
|
|
|
4410
4471
|
const global = readGlobal(this);
|
|
4411
4472
|
const root3 = rootOf(global);
|
|
4412
4473
|
const gitDir = path46.join(root3, ".git");
|
|
4413
|
-
if (!
|
|
4474
|
+
if (!fs13.existsSync(gitDir)) {
|
|
4414
4475
|
throw new CliError("not a git repository \u2014 run `vg share` inside a git repo", ExitCode.USAGE_ERROR);
|
|
4415
4476
|
}
|
|
4416
4477
|
if (opts.undo) {
|
|
@@ -4432,22 +4493,22 @@ function registerShare(program) {
|
|
|
4432
4493
|
}
|
|
4433
4494
|
function writeVibgrateGitignore(root3, reports) {
|
|
4434
4495
|
const dir = path46.join(root3, ".vibgrate");
|
|
4435
|
-
|
|
4496
|
+
fs13.mkdirSync(dir, { recursive: true });
|
|
4436
4497
|
const lines = ["# Managed by `vg share` \u2014 keep graph.json committed, ignore the rest", "cache/", "facts.jsonl", "graph.snap"];
|
|
4437
4498
|
if (!reports) lines.push("graph.html", "GRAPH_REPORT.md");
|
|
4438
|
-
|
|
4499
|
+
fs13.writeFileSync(path46.join(dir, ".gitignore"), `${lines.join("\n")}
|
|
4439
4500
|
`);
|
|
4440
4501
|
}
|
|
4441
4502
|
function writeGitAttributes(root3) {
|
|
4442
4503
|
const file = path46.join(root3, ".gitattributes");
|
|
4443
4504
|
const line = ".vibgrate/graph.json merge=vg";
|
|
4444
|
-
let content =
|
|
4505
|
+
let content = fs13.existsSync(file) ? fs13.readFileSync(file, "utf8") : "";
|
|
4445
4506
|
if (!content.split("\n").some((l) => l.trim() === line)) {
|
|
4446
4507
|
content = content.length ? `${content.replace(/\s*$/, "")}
|
|
4447
4508
|
${line}
|
|
4448
4509
|
` : `${line}
|
|
4449
4510
|
`;
|
|
4450
|
-
|
|
4511
|
+
fs13.writeFileSync(file, content);
|
|
4451
4512
|
}
|
|
4452
4513
|
}
|
|
4453
4514
|
function configureMergeDriver(root3) {
|
|
@@ -4456,7 +4517,7 @@ function configureMergeDriver(root3) {
|
|
|
4456
4517
|
}
|
|
4457
4518
|
function installPreCommitHook(root3) {
|
|
4458
4519
|
const hooksDir = hookDir(root3);
|
|
4459
|
-
|
|
4520
|
+
fs13.mkdirSync(hooksDir, { recursive: true });
|
|
4460
4521
|
const file = path46.join(hooksDir, "pre-commit");
|
|
4461
4522
|
const block = [
|
|
4462
4523
|
HOOK_BEGIN,
|
|
@@ -4466,7 +4527,7 @@ function installPreCommitHook(root3) {
|
|
|
4466
4527
|
"fi",
|
|
4467
4528
|
HOOK_END
|
|
4468
4529
|
].join("\n");
|
|
4469
|
-
let content =
|
|
4530
|
+
let content = fs13.existsSync(file) ? fs13.readFileSync(file, "utf8") : "#!/bin/sh\n";
|
|
4470
4531
|
const re = new RegExp(`${escapeRe(HOOK_BEGIN)}[\\s\\S]*?${escapeRe(HOOK_END)}`);
|
|
4471
4532
|
if (re.test(content)) content = content.replace(re, block);
|
|
4472
4533
|
else content = `${content.replace(/\s*$/, "")}
|
|
@@ -4475,21 +4536,21 @@ ${block}
|
|
|
4475
4536
|
`;
|
|
4476
4537
|
if (!content.startsWith("#!")) content = `#!/bin/sh
|
|
4477
4538
|
${content}`;
|
|
4478
|
-
|
|
4479
|
-
|
|
4539
|
+
fs13.writeFileSync(file, content);
|
|
4540
|
+
fs13.chmodSync(file, 493);
|
|
4480
4541
|
}
|
|
4481
4542
|
function undo(root3) {
|
|
4482
4543
|
const hookFile = path46.join(hookDir(root3), "pre-commit");
|
|
4483
|
-
if (
|
|
4544
|
+
if (fs13.existsSync(hookFile)) {
|
|
4484
4545
|
const re = new RegExp(`\\n*${escapeRe(HOOK_BEGIN)}[\\s\\S]*?${escapeRe(HOOK_END)}\\n*`);
|
|
4485
|
-
const next2 =
|
|
4486
|
-
if (next2.trim() === "#!/bin/sh")
|
|
4487
|
-
else
|
|
4546
|
+
const next2 = fs13.readFileSync(hookFile, "utf8").replace(re, "\n");
|
|
4547
|
+
if (next2.trim() === "#!/bin/sh") fs13.rmSync(hookFile);
|
|
4548
|
+
else fs13.writeFileSync(hookFile, next2);
|
|
4488
4549
|
}
|
|
4489
4550
|
const attr = path46.join(root3, ".gitattributes");
|
|
4490
|
-
if (
|
|
4491
|
-
const next2 =
|
|
4492
|
-
|
|
4551
|
+
if (fs13.existsSync(attr)) {
|
|
4552
|
+
const next2 = fs13.readFileSync(attr, "utf8").split("\n").filter((l) => l.trim() !== ".vibgrate/graph.json merge=vg").join("\n");
|
|
4553
|
+
fs13.writeFileSync(attr, next2);
|
|
4493
4554
|
}
|
|
4494
4555
|
try {
|
|
4495
4556
|
git(root3, ["config", "--remove-section", "merge.vg"]);
|
|
@@ -4518,7 +4579,7 @@ function registerWatch(program) {
|
|
|
4518
4579
|
const debounceMs = Math.max(50, Number(opts.debounce) || DEFAULT_DEBOUNCE_MS);
|
|
4519
4580
|
const watchRoots = (paths.length ? paths : ["."]).map((p) => path46.resolve(root3, p));
|
|
4520
4581
|
for (const w of watchRoots) {
|
|
4521
|
-
if (!
|
|
4582
|
+
if (!fs13.existsSync(w)) {
|
|
4522
4583
|
throw new CliError(`watch path not found: ${w}`, ExitCode.USAGE_ERROR);
|
|
4523
4584
|
}
|
|
4524
4585
|
}
|
|
@@ -4571,7 +4632,7 @@ function registerWatch(program) {
|
|
|
4571
4632
|
const watchers = [];
|
|
4572
4633
|
for (const w of watchRoots) {
|
|
4573
4634
|
try {
|
|
4574
|
-
const watcher =
|
|
4635
|
+
const watcher = fs13.watch(w, { recursive: true }, (_event, filename) => {
|
|
4575
4636
|
if (!filename) {
|
|
4576
4637
|
schedule("change");
|
|
4577
4638
|
return;
|
|
@@ -4920,7 +4981,7 @@ function loadStandards(root3) {
|
|
|
4920
4981
|
const p = path46__default.join(root3, rel);
|
|
4921
4982
|
let text;
|
|
4922
4983
|
try {
|
|
4923
|
-
text =
|
|
4984
|
+
text = fs13__default.readFileSync(p, "utf8");
|
|
4924
4985
|
} catch {
|
|
4925
4986
|
continue;
|
|
4926
4987
|
}
|
|
@@ -6851,7 +6912,7 @@ function registerModels(program) {
|
|
|
6851
6912
|
);
|
|
6852
6913
|
}
|
|
6853
6914
|
} else {
|
|
6854
|
-
if (!target.path || !
|
|
6915
|
+
if (!target.path || !fs13.existsSync(target.path)) {
|
|
6855
6916
|
throw new CliError(
|
|
6856
6917
|
`model file not found at ${target.path || "(unknown path)"} \u2014 it may already be removed.`,
|
|
6857
6918
|
ExitCode.NOT_FOUND
|
|
@@ -6865,7 +6926,7 @@ function registerModels(program) {
|
|
|
6865
6926
|
}
|
|
6866
6927
|
if (!global.json) info(c.dim(` $ rm ${target.path}`));
|
|
6867
6928
|
try {
|
|
6868
|
-
|
|
6929
|
+
fs13.unlinkSync(target.path);
|
|
6869
6930
|
} catch (e) {
|
|
6870
6931
|
const msg = e instanceof Error ? e.message : String(e);
|
|
6871
6932
|
throw new CliError(`could not delete ${target.path}: ${msg}`, ExitCode.ERROR);
|
|
@@ -7004,8 +7065,8 @@ function registerModels(program) {
|
|
|
7004
7065
|
});
|
|
7005
7066
|
if (opts.out) {
|
|
7006
7067
|
const outPath = path46.resolve(opts.out);
|
|
7007
|
-
|
|
7008
|
-
|
|
7068
|
+
fs13.mkdirSync(path46.dirname(outPath), { recursive: true });
|
|
7069
|
+
fs13.writeFileSync(outPath, `${JSON.stringify(report, null, 2)}
|
|
7009
7070
|
`);
|
|
7010
7071
|
if (!global.json) info(c.dim(` wrote ${outPath}`));
|
|
7011
7072
|
}
|
|
@@ -7203,7 +7264,7 @@ function codeConfigPath(root3) {
|
|
|
7203
7264
|
}
|
|
7204
7265
|
function loadCodeConfig(root3) {
|
|
7205
7266
|
try {
|
|
7206
|
-
const raw = JSON.parse(
|
|
7267
|
+
const raw = JSON.parse(fs13.readFileSync(codeConfigPath(root3), "utf8"));
|
|
7207
7268
|
return sanitize(raw);
|
|
7208
7269
|
} catch {
|
|
7209
7270
|
return {};
|
|
@@ -7270,7 +7331,7 @@ function contextBudgetFor(config, modelContextWindow) {
|
|
|
7270
7331
|
var MCP_CONFIG_FILES = [".cursor/mcp.json", ".vscode/mcp.json", ".mcp.json"];
|
|
7271
7332
|
function readMcpServersFile(file) {
|
|
7272
7333
|
try {
|
|
7273
|
-
const raw = JSON.parse(
|
|
7334
|
+
const raw = JSON.parse(fs13.readFileSync(file, "utf8"));
|
|
7274
7335
|
const map = raw.mcpServers ?? raw.servers;
|
|
7275
7336
|
return map && typeof map === "object" ? parseMcpServers(map) : {};
|
|
7276
7337
|
} catch {
|
|
@@ -7395,10 +7456,10 @@ function registerCode(program) {
|
|
|
7395
7456
|
return;
|
|
7396
7457
|
}
|
|
7397
7458
|
const patchFile = pathMod.join(
|
|
7398
|
-
|
|
7459
|
+
fs13.mkdtempSync(pathMod.join(os7.tmpdir(), "vg-wt-")),
|
|
7399
7460
|
"delta.patch"
|
|
7400
7461
|
);
|
|
7401
|
-
|
|
7462
|
+
fs13.writeFileSync(patchFile, diff2.patch);
|
|
7402
7463
|
const outcome = wt.applyWorktreePatch(gitRunner, root4, patchFile, diff2.files);
|
|
7403
7464
|
emitLine({ event: "worktree-applied", id: target.id, ...outcome });
|
|
7404
7465
|
if (!opts.streamJson && !global.json) {
|
|
@@ -7464,7 +7525,7 @@ function registerCode(program) {
|
|
|
7464
7525
|
try {
|
|
7465
7526
|
const { parseMode: parseMode2, resolveMode: resolveMode2, readOrchestratorState: readOrchestratorState2, activePin: activePin2 } = await import('./model-orchestrator-LHYPJBFH.js');
|
|
7466
7527
|
const { gatherSystemMemory: gatherSystemMemory2 } = await import('./local-runtime-6SNWKSA7.js');
|
|
7467
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
7528
|
+
const { loadGraph: loadGraph2 } = await import('./load-H5HAME25.js');
|
|
7468
7529
|
const state = readOrchestratorState2();
|
|
7469
7530
|
const mode = parseMode2(modeFlag) ?? state.defaultMode ?? void 0;
|
|
7470
7531
|
const pin = mode ? activePin2(mode, state) : null;
|
|
@@ -7549,7 +7610,7 @@ function registerCode(program) {
|
|
|
7549
7610
|
if (!(process.stdin.isTTY && process.stdout.isTTY)) {
|
|
7550
7611
|
throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"` (guided mode needs an interactive terminal)');
|
|
7551
7612
|
}
|
|
7552
|
-
const { runInteractive } = await import('./interactive-
|
|
7613
|
+
const { runInteractive } = await import('./interactive-KEPGE5HD.js');
|
|
7553
7614
|
await runInteractive(
|
|
7554
7615
|
rootOf(global),
|
|
7555
7616
|
global,
|
|
@@ -7579,7 +7640,7 @@ function registerCode(program) {
|
|
|
7579
7640
|
}
|
|
7580
7641
|
if (!instruction && !stdinFirstTurn) throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"`');
|
|
7581
7642
|
{
|
|
7582
|
-
const { ensureCodeMap } = await import('./ensure-map-
|
|
7643
|
+
const { ensureCodeMap } = await import('./ensure-map-B2PS5ALS.js');
|
|
7583
7644
|
const mapRoot = rootOf(global);
|
|
7584
7645
|
try {
|
|
7585
7646
|
await ensureCodeMap(mapRoot, global, {
|
|
@@ -7616,7 +7677,7 @@ function registerCode(program) {
|
|
|
7616
7677
|
let mockReply;
|
|
7617
7678
|
if (opts.mock) {
|
|
7618
7679
|
try {
|
|
7619
|
-
mockReply =
|
|
7680
|
+
mockReply = fs13.readFileSync(opts.mock, "utf8");
|
|
7620
7681
|
} catch {
|
|
7621
7682
|
throw new CliError(`couldn't read the --mock file: ${opts.mock}`, ExitCode.USAGE_ERROR);
|
|
7622
7683
|
}
|
|
@@ -7664,20 +7725,20 @@ function registerCode(program) {
|
|
|
7664
7725
|
process.stdout.write(JSON.stringify(line) + "\n");
|
|
7665
7726
|
};
|
|
7666
7727
|
try {
|
|
7667
|
-
const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-
|
|
7728
|
+
const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-V3L4GAN4.js');
|
|
7668
7729
|
const primarySlug = route.providers[0]?.model.includes("/") ? route.providers[0].model.split("/")[0] : route.providers[0]?.id;
|
|
7669
|
-
const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-
|
|
7670
|
-
const { nodeCodeFs } = await import('./session-
|
|
7730
|
+
const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-S6E3W2US.js');
|
|
7731
|
+
const { nodeCodeFs } = await import('./session-77YXFUC7.js');
|
|
7671
7732
|
const readline6 = await import('readline');
|
|
7672
7733
|
const child = await import('child_process');
|
|
7673
7734
|
const { loadOrDiscoverFederation } = await import('./federation-MDQPO3PW.js');
|
|
7674
7735
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
7675
7736
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
7676
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
7677
|
-
const { resolveGraphBackend } = await import('./graph-backend-
|
|
7737
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-M2FRGTDS.js');
|
|
7738
|
+
const { resolveGraphBackend } = await import('./graph-backend-EEXMD6XY.js');
|
|
7678
7739
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
7679
7740
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
7680
|
-
const { vgdRequest } = await import('./vgd-
|
|
7741
|
+
const { vgdRequest } = await import('./vgd-R2PNIDEP.js');
|
|
7681
7742
|
const federation = loadOrDiscoverFederation(root3);
|
|
7682
7743
|
const modelProfile = mergeModelExecutionProfile(
|
|
7683
7744
|
resolveModelExecutionProfile({
|
|
@@ -7735,7 +7796,7 @@ ${res.stderr}` : ""),
|
|
|
7735
7796
|
exitCode: res.status ?? 1
|
|
7736
7797
|
};
|
|
7737
7798
|
};
|
|
7738
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
7799
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-HCPJWJKJ.js');
|
|
7739
7800
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
7740
7801
|
getGraph: () => graph,
|
|
7741
7802
|
root: root3,
|
|
@@ -7759,7 +7820,7 @@ ${res.stderr}` : ""),
|
|
|
7759
7820
|
const os7 = await import('os');
|
|
7760
7821
|
const pathMod = await import('path');
|
|
7761
7822
|
const checkpointIndex = pathMod.join(
|
|
7762
|
-
|
|
7823
|
+
fs13.mkdtempSync(pathMod.join(os7.tmpdir(), "vg-code-cp-")),
|
|
7763
7824
|
"index"
|
|
7764
7825
|
);
|
|
7765
7826
|
const gitRunner = (gitArgs, gitEnv) => {
|
|
@@ -7780,7 +7841,7 @@ ${res.stderr}` : ""),
|
|
|
7780
7841
|
files,
|
|
7781
7842
|
indexFile: checkpointIndex
|
|
7782
7843
|
});
|
|
7783
|
-
const { loadApprovalRules, addApprovalRule, ruleForAction, ruleLabel } = await import('./approvals-
|
|
7844
|
+
const { loadApprovalRules, addApprovalRule, ruleForAction, ruleLabel } = await import('./approvals-YFOU6GVB.js');
|
|
7784
7845
|
const { loadProjectRules, nodeRulesReader } = await import('./rules-ASYEUNB5.js');
|
|
7785
7846
|
const projectRules = loadProjectRules(nodeRulesReader(root3));
|
|
7786
7847
|
if (projectRules.sources.length && !global.quiet) {
|
|
@@ -7838,8 +7899,8 @@ ${res.stderr}` : ""),
|
|
|
7838
7899
|
};
|
|
7839
7900
|
try {
|
|
7840
7901
|
if (opts.session) {
|
|
7841
|
-
const { runCodeStreamJsonSession, STREAM_JSON_PROTOCOL_VERSION } = await import('./stream-json-
|
|
7842
|
-
const { runAgent: runAgent2 } = await import('./agent-
|
|
7902
|
+
const { runCodeStreamJsonSession, STREAM_JSON_PROTOCOL_VERSION } = await import('./stream-json-S6E3W2US.js');
|
|
7903
|
+
const { runAgent: runAgent2 } = await import('./agent-CUK24AWF.js');
|
|
7843
7904
|
const {
|
|
7844
7905
|
condenseSession,
|
|
7845
7906
|
loadLatestSession,
|
|
@@ -7850,7 +7911,7 @@ ${res.stderr}` : ""),
|
|
|
7850
7911
|
sessionsDir,
|
|
7851
7912
|
summarizeSession
|
|
7852
7913
|
} = await import('./session-store-AQUORKWB.js');
|
|
7853
|
-
const { VERSION: VERSION2 } = await import('./version-
|
|
7914
|
+
const { VERSION: VERSION2 } = await import('./version-VRZT5G4T.js');
|
|
7854
7915
|
const resumedRecord = typeof opts.continue === "string" ? loadSession(mainRoot, opts.continue) : opts.continue ? loadLatestSession(mainRoot) : void 0;
|
|
7855
7916
|
if (typeof opts.continue === "string" && !resumedRecord) {
|
|
7856
7917
|
emitStream({
|
|
@@ -8062,8 +8123,8 @@ ${res.stderr}` : ""),
|
|
|
8062
8123
|
if (!autonomous && !tty) {
|
|
8063
8124
|
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).");
|
|
8064
8125
|
}
|
|
8065
|
-
const { agentTask } = await import('./interactive-
|
|
8066
|
-
const { nodeCodeFs } = await import('./session-
|
|
8126
|
+
const { agentTask } = await import('./interactive-KEPGE5HD.js');
|
|
8127
|
+
const { nodeCodeFs } = await import('./session-77YXFUC7.js');
|
|
8067
8128
|
const { TtyPrompter } = await import('./ui-K7D3BCHD.js');
|
|
8068
8129
|
let priorSummary;
|
|
8069
8130
|
let priorInstruction;
|
|
@@ -8078,7 +8139,7 @@ ${res.stderr}` : ""),
|
|
|
8078
8139
|
}
|
|
8079
8140
|
}
|
|
8080
8141
|
const prompter = tty ? new TtyPrompter() : void 0;
|
|
8081
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
8142
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-HCPJWJKJ.js');
|
|
8082
8143
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
8083
8144
|
getGraph: () => graph,
|
|
8084
8145
|
root: root3,
|
|
@@ -8102,11 +8163,11 @@ ${res.stderr}` : ""),
|
|
|
8102
8163
|
const { loadFederation } = await import('./federation-MDQPO3PW.js');
|
|
8103
8164
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
8104
8165
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
8105
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
8106
|
-
const { resolveGraphBackend } = await import('./graph-backend-
|
|
8166
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-M2FRGTDS.js');
|
|
8167
|
+
const { resolveGraphBackend } = await import('./graph-backend-EEXMD6XY.js');
|
|
8107
8168
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
8108
8169
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
8109
|
-
const { vgdRequest } = await import('./vgd-
|
|
8170
|
+
const { vgdRequest } = await import('./vgd-R2PNIDEP.js');
|
|
8110
8171
|
const federation = loadFederation(root3);
|
|
8111
8172
|
const modelProfile = mergeModelExecutionProfile(
|
|
8112
8173
|
resolveModelExecutionProfile({
|
|
@@ -8200,7 +8261,7 @@ ${res.stderr}` : ""),
|
|
|
8200
8261
|
attribution: { client: "vg-code", provider: providerSlug, model: primary?.model }
|
|
8201
8262
|
});
|
|
8202
8263
|
if (opts.out) {
|
|
8203
|
-
|
|
8264
|
+
fs13.writeFileSync(opts.out, JSON.stringify(result, null, 2) + "\n");
|
|
8204
8265
|
}
|
|
8205
8266
|
if (global.json) {
|
|
8206
8267
|
json(result);
|
|
@@ -8389,8 +8450,9 @@ function listCatalog(root3, asJson) {
|
|
|
8389
8450
|
return;
|
|
8390
8451
|
}
|
|
8391
8452
|
info(`${c.cyan("vg lib")} \xB7 ${libs.length} library(ies) in the catalog`);
|
|
8453
|
+
const inv = inventory(root3);
|
|
8392
8454
|
for (const l of libs) {
|
|
8393
|
-
const d = driftFor(root3, l);
|
|
8455
|
+
const d = driftFor(root3, l, inv);
|
|
8394
8456
|
const tag = d.drift === "behind" ? c.yellow(" (docs behind your version)") : d.drift === "ahead" ? c.dim(" (docs ahead)") : "";
|
|
8395
8457
|
info(` ${c.bold(l.name)} ${c.dim(`@${l.version}`)} ${c.dim(`[${l.source.type}]`)}${tag}`);
|
|
8396
8458
|
}
|
|
@@ -8413,7 +8475,7 @@ async function addCmd(root3, rest, opts, asJson) {
|
|
|
8413
8475
|
}
|
|
8414
8476
|
function readPackageVersion(root3) {
|
|
8415
8477
|
try {
|
|
8416
|
-
const pkg = JSON.parse(
|
|
8478
|
+
const pkg = JSON.parse(fs13__default.readFileSync(path46__default.join(root3, "package.json"), "utf8"));
|
|
8417
8479
|
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
8418
8480
|
} catch {
|
|
8419
8481
|
return void 0;
|
|
@@ -8421,7 +8483,7 @@ function readPackageVersion(root3) {
|
|
|
8421
8483
|
}
|
|
8422
8484
|
function readOptionalFile(p) {
|
|
8423
8485
|
try {
|
|
8424
|
-
const t =
|
|
8486
|
+
const t = fs13__default.readFileSync(p, "utf8");
|
|
8425
8487
|
return t.trim() ? t : void 0;
|
|
8426
8488
|
} catch {
|
|
8427
8489
|
return void 0;
|
|
@@ -8569,8 +8631,8 @@ function registerExport(program) {
|
|
|
8569
8631
|
out(content.trimEnd());
|
|
8570
8632
|
return;
|
|
8571
8633
|
}
|
|
8572
|
-
|
|
8573
|
-
|
|
8634
|
+
fs13.mkdirSync(path46.dirname(path46.resolve(file)), { recursive: true });
|
|
8635
|
+
fs13.writeFileSync(file, content);
|
|
8574
8636
|
info(`${c.green("\u2714")} wrote ${file} ${c.dim(`(${format})`)}`);
|
|
8575
8637
|
});
|
|
8576
8638
|
applyGlobalOptions(cmd);
|
|
@@ -8593,36 +8655,36 @@ function registerBundle(program) {
|
|
|
8593
8655
|
} catch {
|
|
8594
8656
|
throw new CliError("no grammars found to bundle (run a build first)", ExitCode.ERROR);
|
|
8595
8657
|
}
|
|
8596
|
-
|
|
8658
|
+
fs13.mkdirSync(path46.join(outDir, "grammars"), { recursive: true });
|
|
8597
8659
|
let grammarCount = 0;
|
|
8598
8660
|
for (const { fileName, absPath } of grammarFiles) {
|
|
8599
|
-
|
|
8661
|
+
fs13.copyFileSync(absPath, path46.join(outDir, "grammars", fileName));
|
|
8600
8662
|
grammarCount++;
|
|
8601
8663
|
}
|
|
8602
8664
|
for (const id of Object.keys(TOOLCHAIN_GRAMMARS).sort()) {
|
|
8603
8665
|
const absPath = resolveToolchainGrammar(id);
|
|
8604
8666
|
if (!absPath) continue;
|
|
8605
|
-
|
|
8667
|
+
fs13.copyFileSync(absPath, path46.join(outDir, "grammars", path46.basename(absPath)));
|
|
8606
8668
|
grammarCount++;
|
|
8607
8669
|
}
|
|
8608
8670
|
const included = [`grammars/ (${grammarCount} .wasm)`];
|
|
8609
8671
|
const graphSrc = resolveGraphPath(root3, global.graph);
|
|
8610
|
-
if (
|
|
8611
|
-
|
|
8672
|
+
if (fs13.existsSync(graphSrc)) {
|
|
8673
|
+
fs13.copyFileSync(graphSrc, path46.join(outDir, "graph.json"));
|
|
8612
8674
|
included.push("graph.json");
|
|
8613
8675
|
} else {
|
|
8614
8676
|
const graph = loadGraphFileWithSnapshot(graphSrc);
|
|
8615
8677
|
if (graph) {
|
|
8616
|
-
|
|
8678
|
+
fs13.writeFileSync(path46.join(outDir, "graph.json"), serializeGraph(graph));
|
|
8617
8679
|
included.push("graph.json");
|
|
8618
8680
|
}
|
|
8619
8681
|
}
|
|
8620
8682
|
const cat = catalogPath(root3);
|
|
8621
|
-
if (
|
|
8622
|
-
|
|
8683
|
+
if (fs13.existsSync(cat)) {
|
|
8684
|
+
fs13.copyFileSync(cat, path46.join(outDir, "vibgrate.lib.json"));
|
|
8623
8685
|
included.push("vibgrate.lib.json");
|
|
8624
|
-
if (
|
|
8625
|
-
|
|
8686
|
+
if (fs13.existsSync(libDir(root3))) {
|
|
8687
|
+
fs13.cpSync(libDir(root3), path46.join(outDir, "lib"), { recursive: true });
|
|
8626
8688
|
included.push("lib/");
|
|
8627
8689
|
}
|
|
8628
8690
|
}
|
|
@@ -8634,7 +8696,7 @@ function registerBundle(program) {
|
|
|
8634
8696
|
included,
|
|
8635
8697
|
usage: "Run `vg build --grammars <this dir>/grammars` to build fully offline."
|
|
8636
8698
|
};
|
|
8637
|
-
|
|
8699
|
+
fs13.writeFileSync(path46.join(outDir, "MANIFEST.json"), `${stableStringify(manifest, 2)}
|
|
8638
8700
|
`);
|
|
8639
8701
|
if (global.json) {
|
|
8640
8702
|
json({ out: path46.relative(root3, outDir), ...manifest });
|
|
@@ -8660,7 +8722,7 @@ async function runDoctor(global) {
|
|
|
8660
8722
|
const root3 = rootOf(global);
|
|
8661
8723
|
const local = global.local === true;
|
|
8662
8724
|
const graphPath = resolveGraphPath(root3, global.graph);
|
|
8663
|
-
const configFile = CONFIG_BASENAMES.find((f) =>
|
|
8725
|
+
const configFile = CONFIG_BASENAMES.find((f) => fs13.existsSync(path46.join(root3, f))) ?? null;
|
|
8664
8726
|
const graph = loadGraph(root3, graphPath);
|
|
8665
8727
|
let staleFiles = null;
|
|
8666
8728
|
if (graph) {
|
|
@@ -8693,7 +8755,7 @@ async function runDoctor(global) {
|
|
|
8693
8755
|
},
|
|
8694
8756
|
libCatalog: {
|
|
8695
8757
|
path: path46.relative(root3, catalogPath(root3)),
|
|
8696
|
-
present:
|
|
8758
|
+
present: fs13.existsSync(catalogPath(root3)),
|
|
8697
8759
|
libraries: libCount
|
|
8698
8760
|
},
|
|
8699
8761
|
credentials: creds,
|
|
@@ -8870,7 +8932,7 @@ function registerPolicy(program) {
|
|
|
8870
8932
|
const global = readGlobal(this);
|
|
8871
8933
|
let raw;
|
|
8872
8934
|
try {
|
|
8873
|
-
raw =
|
|
8935
|
+
raw = fs13.readFileSync(file, "utf8");
|
|
8874
8936
|
} catch {
|
|
8875
8937
|
throw new CliError(`cannot read ${file}`, ExitCode.NOT_FOUND);
|
|
8876
8938
|
}
|
|
@@ -9058,8 +9120,8 @@ async function readStdin() {
|
|
|
9058
9120
|
}
|
|
9059
9121
|
function readFileOrThrow(file, label) {
|
|
9060
9122
|
const p = path46.resolve(file);
|
|
9061
|
-
if (!
|
|
9062
|
-
return
|
|
9123
|
+
if (!fs13.existsSync(p)) throw usageError(`${label} file not found: ${p}`);
|
|
9124
|
+
return fs13.readFileSync(p, "utf-8");
|
|
9063
9125
|
}
|
|
9064
9126
|
async function readInput(file, label) {
|
|
9065
9127
|
return file ? readFileOrThrow(file, label) : readStdin();
|
|
@@ -9071,8 +9133,8 @@ function writeOutput(outFile, content) {
|
|
|
9071
9133
|
}
|
|
9072
9134
|
const outPath = path46.resolve(outFile);
|
|
9073
9135
|
const dir = path46.dirname(outPath);
|
|
9074
|
-
if (!
|
|
9075
|
-
|
|
9136
|
+
if (!fs13.existsSync(dir)) throw usageError(`output directory does not exist: ${dir}`);
|
|
9137
|
+
fs13.writeFileSync(outPath, content.endsWith("\n") ? content : content + "\n", "utf-8");
|
|
9076
9138
|
info(c.dim(`wrote ${outPath}`));
|
|
9077
9139
|
}
|
|
9078
9140
|
function requireChoice(value, valid2, flag) {
|
|
@@ -9106,7 +9168,7 @@ function registerHcs(program) {
|
|
|
9106
9168
|
const statePath = opts.previous ?? opts.out;
|
|
9107
9169
|
const useIncremental = canIncremental && statePath !== void 0;
|
|
9108
9170
|
const root3 = path46.resolve(dir);
|
|
9109
|
-
if (!
|
|
9171
|
+
if (!fs13.existsSync(root3) || !fs13.statSync(root3).isDirectory()) {
|
|
9110
9172
|
throw usageError(`not a directory: ${root3}`);
|
|
9111
9173
|
}
|
|
9112
9174
|
const supported = new Set(
|
|
@@ -9124,7 +9186,7 @@ function registerHcs(program) {
|
|
|
9124
9186
|
const walk2 = (abs, rel) => {
|
|
9125
9187
|
let entries;
|
|
9126
9188
|
try {
|
|
9127
|
-
entries =
|
|
9189
|
+
entries = fs13.readdirSync(abs, { withFileTypes: true });
|
|
9128
9190
|
} catch {
|
|
9129
9191
|
return;
|
|
9130
9192
|
}
|
|
@@ -9141,8 +9203,8 @@ function registerHcs(program) {
|
|
|
9141
9203
|
const lang = extToLang.get(path46.extname(entry.name).toLowerCase());
|
|
9142
9204
|
if (!lang) continue;
|
|
9143
9205
|
try {
|
|
9144
|
-
if (
|
|
9145
|
-
const content =
|
|
9206
|
+
if (fs13.statSync(absChild).size > MAX_EXTRACT_FILE_BYTES) continue;
|
|
9207
|
+
const content = fs13.readFileSync(absChild, "utf-8");
|
|
9146
9208
|
let bucket = byLanguage.get(lang);
|
|
9147
9209
|
if (!bucket) byLanguage.set(lang, bucket = []);
|
|
9148
9210
|
bucket.push({ path: relChild, content });
|
|
@@ -9173,7 +9235,7 @@ function registerHcs(program) {
|
|
|
9173
9235
|
return;
|
|
9174
9236
|
}
|
|
9175
9237
|
const previousPath = path46.resolve(statePath);
|
|
9176
|
-
const previousNdjson = !opts.full &&
|
|
9238
|
+
const previousNdjson = !opts.full && fs13.existsSync(previousPath) ? fs13.readFileSync(previousPath, "utf-8") : "";
|
|
9177
9239
|
if (opts.full) info(c.dim("running a full re-extraction (--full)"));
|
|
9178
9240
|
else if (!previousNdjson) info(c.dim(`previous stream not found at ${previousPath} \u2014 running a full extraction`));
|
|
9179
9241
|
const currentFilesJson = JSON.stringify(
|
|
@@ -9289,7 +9351,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
|
|
|
9289
9351
|
console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
|
|
9290
9352
|
}
|
|
9291
9353
|
if (opts.baseline) {
|
|
9292
|
-
const { runBaseline } = await import('./baseline-
|
|
9354
|
+
const { runBaseline } = await import('./baseline-OBZJRCCP.js');
|
|
9293
9355
|
await runBaseline(rootDir);
|
|
9294
9356
|
}
|
|
9295
9357
|
console.log("");
|
|
@@ -9430,9 +9492,9 @@ function sitesFromImportFiles(files, limit = 10) {
|
|
|
9430
9492
|
}
|
|
9431
9493
|
async function defaultReadFile(absPath) {
|
|
9432
9494
|
try {
|
|
9433
|
-
const stat2 = await
|
|
9495
|
+
const stat2 = await fs27.stat(absPath);
|
|
9434
9496
|
if (!stat2.isFile() || stat2.size > MAX_FILE_BYTES) return null;
|
|
9435
|
-
return await
|
|
9497
|
+
return await fs27.readFile(absPath, "utf8");
|
|
9436
9498
|
} catch {
|
|
9437
9499
|
return null;
|
|
9438
9500
|
}
|
|
@@ -9833,7 +9895,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
|
|
|
9833
9895
|
'Exclude paths matching a glob pattern. Repeatable, and a single value may list several patterns separated by commas or semicolons (e.g. --exclude "legacy/**,vendor/**"). Merged with excludes from the config file.',
|
|
9834
9896
|
collectExcludes,
|
|
9835
9897
|
[]
|
|
9836
|
-
).option("--concurrency <n>", "Max concurrent registry lookups", "8").option("--push", "Auto-push results to Vibgrate API after scan").option("--dsn <dsn>", "DSN token for push (or use VIBGRATE_DSN env)").option("--region <region>", "Override data residency region for push (us, eu)").option("--strict", "Fail on push errors").option("--ui-purpose", "Enable optional UI purpose evidence extraction (slower)").option("--no-local-artifacts", "Do not write .vibgrate JSON artifacts to disk").option("--max-privacy", "Enable strongest privacy mode (minimal scanners, no local artifacts)").option("--offline", "Run without network calls; do not upload results").option("--full", "Comprehensive scan: turns on known-vulnerability detection (= --vulns) and, when a standards policy exists, a banned-dependency report \u2014 on top of drift scoring and the code map").option("--vulns", "Also scan installed dependencies for known vulnerabilities (OSV online, or advisories from --package-manifest when offline)").option("--package-manifest <file>", "Use local package-version manifest JSON/ZIP (for offline mode)").option("--project-scan-timeout <seconds>", "Per-project scan timeout in seconds (default: 180)").option("--drift-budget <score>", "Fail if DriftScore is above budget (0-100)").option("--drift-worsening <percent>", "Fail if drift worsens by more than % since baseline").option("--repository-name <name>", "Override the repository name recorded for this scan (defaults to the directory or package.json name)").option("--force", "Always create a fresh scan ingest, even if the repository is unchanged since the last scan (skips the unchanged/reuse optimization). Used by scheduled and dashboard-triggered scans.").option("--no-graph", "Skip building the local code map (the AI/docs index) that scan produces after scoring drift").option("--quiet", "Suppress promotional output (the free-plan tracking panel and the AI Context install prompt); scan results are unaffected").action(async (targetPath, opts) => {
|
|
9898
|
+
).option("--concurrency <n>", "Max concurrent registry lookups", "8").option("--push", "Auto-push results to Vibgrate API after scan").option("--dsn <dsn>", "DSN token for push (or use VIBGRATE_DSN env)").option("--region <region>", "Override data residency region for push (us, eu)").option("--strict", "Fail on push errors").option("--ui-purpose", "Enable optional UI purpose evidence extraction (slower)").option("--no-local-artifacts", "Do not write .vibgrate JSON artifacts to disk").option("--max-privacy", "Enable strongest privacy mode (minimal scanners, no local artifacts)").option("--offline", "Run without network calls; do not upload results").option("--full", "Comprehensive scan: turns on known-vulnerability detection (= --vulns) and, when a standards policy exists, a banned-dependency report \u2014 on top of drift scoring and the code map").option("--vulns", "Also scan installed dependencies for known vulnerabilities (OSV online, or advisories from --package-manifest when offline)").option("--package-manifest <file>", "Use local package-version manifest JSON/ZIP (for offline mode)").option("--project-scan-timeout <seconds>", "Per-project scan timeout in seconds (default: 180)").option("--drift-budget <score>", "Fail if DriftScore is above budget (0-100)").option("--drift-worsening <percent>", "Fail if drift worsens by more than % since baseline").option("--repository-name <name>", "Override the repository name recorded for this scan (defaults to the directory or package.json name)").option("--force", "Always create a fresh scan ingest, even if the repository is unchanged since the last scan (skips the unchanged/reuse optimization). Used by scheduled and dashboard-triggered scans.").option("--no-graph", "Skip building the local code map (the AI/docs index) that scan produces after scoring drift").option("--no-daemon", "Never auto-start or use the local runtime (vgd) \u2014 run everything in this process").option("--quiet", "Suppress promotional output (the free-plan tracking panel and the AI Context install prompt); scan results are unaffected").action(async (targetPath, opts) => {
|
|
9837
9899
|
const rootDir = path46.resolve(targetPath);
|
|
9838
9900
|
if (!await pathExists$1(rootDir)) {
|
|
9839
9901
|
console.error(chalk7.red(`Path does not exist: ${rootDir}`));
|
|
@@ -9985,20 +10047,43 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
|
|
|
9985
10047
|
writeSnapshot(rootDir, result.graph.provenance.corpusHash, result.fileStats, {
|
|
9986
10048
|
exclude: opts.exclude
|
|
9987
10049
|
});
|
|
9988
|
-
refineArchitectureWithGraph(
|
|
9989
|
-
{ projects: ctx.projects, solutions: ctx.solutions, extended: ctx.extended },
|
|
9990
|
-
architectureGraphView2(result.graph)
|
|
9991
|
-
);
|
|
9992
10050
|
refineArchitectureWithAstRoles(
|
|
9993
10051
|
{ projects: ctx.projects, solutions: ctx.solutions, extended: ctx.extended },
|
|
9994
10052
|
result.fileRoles
|
|
9995
10053
|
);
|
|
10054
|
+
refineArchitectureWithGraph(
|
|
10055
|
+
{ projects: ctx.projects, solutions: ctx.solutions, extended: ctx.extended },
|
|
10056
|
+
architectureGraphView2(result.graph)
|
|
10057
|
+
);
|
|
9996
10058
|
const { counts } = result.graph.meta;
|
|
9997
10059
|
return `${counts.nodes.toLocaleString()} nodes \xB7 ${counts.edges.toLocaleString()} edges`;
|
|
9998
10060
|
};
|
|
9999
10061
|
}
|
|
10000
10062
|
const advanced = await loadAdvancedScanHook();
|
|
10001
10063
|
const artifact = await runCoreScan(rootDir, scanOpts, advanced);
|
|
10064
|
+
if (wantGraph && builtGraph) {
|
|
10065
|
+
const { attachVgd: attachVgd2 } = await import('./attach-6S3XS7VO.js');
|
|
10066
|
+
const { ActivityLog: ActivityLog2 } = await import('./activity-MF2GNYAI.js');
|
|
10067
|
+
const activity = new ActivityLog2();
|
|
10068
|
+
await activity.time(
|
|
10069
|
+
"attach",
|
|
10070
|
+
() => attachVgd2(rootDir, { disabled: opts.daemon === false }),
|
|
10071
|
+
(a) => {
|
|
10072
|
+
if (a.status !== "attached") return { outcome: "skip", detail: `${a.reason} \u2014 the map stays on disk only` };
|
|
10073
|
+
const started = a.started ? "started vgd" : "attached to vgd";
|
|
10074
|
+
if (a.published?.status === "published") {
|
|
10075
|
+
return {
|
|
10076
|
+
outcome: "ok",
|
|
10077
|
+
detail: `${started} \xB7 map published ${a.published.gitRef} \xB7 ${a.published.nodeCount} nodes \xB7 semantic index warming`
|
|
10078
|
+
};
|
|
10079
|
+
}
|
|
10080
|
+
return { outcome: "ok", detail: started };
|
|
10081
|
+
}
|
|
10082
|
+
);
|
|
10083
|
+
if (!opts.quiet && opts.format !== "json") {
|
|
10084
|
+
for (const line of activity.render()) console.error(line);
|
|
10085
|
+
}
|
|
10086
|
+
}
|
|
10002
10087
|
emitDriftScoreLine(artifact.drift.score);
|
|
10003
10088
|
if (opts.full) {
|
|
10004
10089
|
reportStandards(rootDir);
|
|
@@ -10119,7 +10204,7 @@ var SKIP_DIRS3 = /* @__PURE__ */ new Set([
|
|
|
10119
10204
|
function scanStaleness(rootDir, artifactPath) {
|
|
10120
10205
|
let ref;
|
|
10121
10206
|
try {
|
|
10122
|
-
ref =
|
|
10207
|
+
ref = fs13.statSync(artifactPath).mtimeMs;
|
|
10123
10208
|
} catch {
|
|
10124
10209
|
return { stale: false };
|
|
10125
10210
|
}
|
|
@@ -10131,7 +10216,7 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
10131
10216
|
if (depth > 8 || scanned > MAX_ENTRIES2) return;
|
|
10132
10217
|
let entries;
|
|
10133
10218
|
try {
|
|
10134
|
-
entries =
|
|
10219
|
+
entries = fs13.readdirSync(dir, { withFileTypes: true });
|
|
10135
10220
|
} catch {
|
|
10136
10221
|
return;
|
|
10137
10222
|
}
|
|
@@ -10146,7 +10231,7 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
10146
10231
|
const abs = path46.join(dir, e.name);
|
|
10147
10232
|
let mtimeMs;
|
|
10148
10233
|
try {
|
|
10149
|
-
mtimeMs =
|
|
10234
|
+
mtimeMs = fs13.statSync(abs).mtimeMs;
|
|
10150
10235
|
} catch {
|
|
10151
10236
|
continue;
|
|
10152
10237
|
}
|
|
@@ -10283,7 +10368,7 @@ function analyzeTree(root3, packages) {
|
|
|
10283
10368
|
if (depth > MAX_DEPTH || filesSeen >= MAX_FILES) return;
|
|
10284
10369
|
let entries;
|
|
10285
10370
|
try {
|
|
10286
|
-
entries =
|
|
10371
|
+
entries = fs13.readdirSync(dir, { withFileTypes: true });
|
|
10287
10372
|
} catch {
|
|
10288
10373
|
return;
|
|
10289
10374
|
}
|
|
@@ -10301,8 +10386,8 @@ function analyzeTree(root3, packages) {
|
|
|
10301
10386
|
const full = path46.join(dir, entry.name);
|
|
10302
10387
|
let content;
|
|
10303
10388
|
try {
|
|
10304
|
-
if (
|
|
10305
|
-
content =
|
|
10389
|
+
if (fs13.statSync(full).size > MAX_FILE_BYTES2) continue;
|
|
10390
|
+
content = fs13.readFileSync(full, "utf8");
|
|
10306
10391
|
} catch {
|
|
10307
10392
|
continue;
|
|
10308
10393
|
}
|
|
@@ -10670,8 +10755,8 @@ async function fetchLatestVersion() {
|
|
|
10670
10755
|
}
|
|
10671
10756
|
async function writeCache(data) {
|
|
10672
10757
|
try {
|
|
10673
|
-
await
|
|
10674
|
-
await
|
|
10758
|
+
await fs27.mkdir(CACHE_DIR, { recursive: true });
|
|
10759
|
+
await fs27.writeFile(CACHE_FILE, JSON.stringify(data), "utf-8");
|
|
10675
10760
|
} catch {
|
|
10676
10761
|
}
|
|
10677
10762
|
}
|
|
@@ -10709,7 +10794,7 @@ function scheduleDeferredUpdate(command, pid = process.pid, dir = os.tmpdir()) {
|
|
|
10709
10794
|
const scriptPath = path46.join(dir, `vg-update-${stamp}.cmd`);
|
|
10710
10795
|
const logPath = path46.join(dir, `vg-update-${stamp}.log`);
|
|
10711
10796
|
try {
|
|
10712
|
-
|
|
10797
|
+
fs13.writeFileSync(scriptPath, buildDeferredUpdateScript({ pid, command, logPath }), "utf8");
|
|
10713
10798
|
const child = spawn(process.env.ComSpec || "cmd.exe", ["/d", "/s", "/c", scriptPath], {
|
|
10714
10799
|
detached: true,
|
|
10715
10800
|
stdio: "ignore",
|
|
@@ -10733,7 +10818,7 @@ function detectGlobalInstall(execPath = process.argv[1] || "", cwd = process.cwd
|
|
|
10733
10818
|
if (!execPath) return null;
|
|
10734
10819
|
let resolved = execPath;
|
|
10735
10820
|
try {
|
|
10736
|
-
resolved =
|
|
10821
|
+
resolved = fs13.realpathSync(execPath);
|
|
10737
10822
|
} catch {
|
|
10738
10823
|
}
|
|
10739
10824
|
const p = resolved.replace(/\\/g, "/");
|
|
@@ -10877,7 +10962,7 @@ ${String(err)}` }));
|
|
|
10877
10962
|
async function releaseWindowsFileLocks(cwd, keepVersion) {
|
|
10878
10963
|
reapAndReport(cwd, keepVersion);
|
|
10879
10964
|
try {
|
|
10880
|
-
const { vgdSocketPath } = await import('./vgd-
|
|
10965
|
+
const { vgdSocketPath } = await import('./vgd-R2PNIDEP.js');
|
|
10881
10966
|
const result = await stopVgd(vgdSocketPath());
|
|
10882
10967
|
if (result === "stopped") {
|
|
10883
10968
|
console.log(chalk7.dim("Stopped the vgd daemon so its files can be replaced \u2014 it restarts on the next command."));
|
|
@@ -10930,6 +11015,7 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
|
|
|
10930
11015
|
if (!semver4.gt(latest, VERSION)) {
|
|
10931
11016
|
console.log(chalk7.green("\u2714") + ` You are on the latest version (${VERSION}).`);
|
|
10932
11017
|
if (opts.reap !== false) reapAndReport(process.cwd(), VERSION);
|
|
11018
|
+
if (opts.reap !== false) await reconcileVgdAndReport(process.cwd());
|
|
10933
11019
|
return;
|
|
10934
11020
|
}
|
|
10935
11021
|
console.log(chalk7.yellow(`Update available: ${VERSION} \u2192 ${latest}`));
|
|
@@ -10992,7 +11078,7 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
|
|
|
10992
11078
|
process.exit(1);
|
|
10993
11079
|
}
|
|
10994
11080
|
if (opts.reap !== false) reapAndReport(cwd, latest);
|
|
10995
|
-
if (opts.reap !== false) await restartVgdAndReport();
|
|
11081
|
+
if (opts.reap !== false) await restartVgdAndReport({ force: true });
|
|
10996
11082
|
try {
|
|
10997
11083
|
clearEmbedderHealth();
|
|
10998
11084
|
} catch {
|
|
@@ -11002,10 +11088,10 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
|
|
|
11002
11088
|
);
|
|
11003
11089
|
async function rewarmVgdAndReport(cwd) {
|
|
11004
11090
|
try {
|
|
11005
|
-
const { vgdIsRunning, vgdRequest } = await import('./vgd-
|
|
11091
|
+
const { vgdIsRunning, vgdRequest } = await import('./vgd-R2PNIDEP.js');
|
|
11006
11092
|
if (!await vgdIsRunning()) return;
|
|
11007
11093
|
const loaded = await vgdRequest({ op: "load-graph", root: cwd });
|
|
11008
|
-
if (!loaded.ok || !("
|
|
11094
|
+
if (!loaded.ok || !("stored" in loaded)) return;
|
|
11009
11095
|
console.log(chalk7.dim("Re-published the code map into the restarted daemon."));
|
|
11010
11096
|
const indexed = await vgdRequest({ op: "embed-index", repositoryId: loaded.repositoryId });
|
|
11011
11097
|
if (indexed.ok && "vectors" in indexed && indexed.state === "ready") {
|
|
@@ -11014,10 +11100,30 @@ async function rewarmVgdAndReport(cwd) {
|
|
|
11014
11100
|
} catch {
|
|
11015
11101
|
}
|
|
11016
11102
|
}
|
|
11017
|
-
async function
|
|
11103
|
+
async function reconcileVgdAndReport(cwd) {
|
|
11104
|
+
let skew;
|
|
11105
|
+
try {
|
|
11106
|
+
skew = await vgdVersionSkew();
|
|
11107
|
+
} catch {
|
|
11108
|
+
return;
|
|
11109
|
+
}
|
|
11110
|
+
if (!skew.running || skew.state === "match") return;
|
|
11111
|
+
if (skew.state === "newer") {
|
|
11112
|
+
console.log(chalk7.dim(`A newer vgd (${skew.version}) is running \u2014 left alone.`));
|
|
11113
|
+
return;
|
|
11114
|
+
}
|
|
11115
|
+
console.log(
|
|
11116
|
+
chalk7.yellow("Stale daemon: ") + chalk7.dim(
|
|
11117
|
+
`vgd is running ${skew.version ?? "a build older than 2026.817"}, not ${VERSION} \u2014 restarting it on this build.`
|
|
11118
|
+
)
|
|
11119
|
+
);
|
|
11120
|
+
await restartVgdAndReport({ force: true });
|
|
11121
|
+
await rewarmVgdAndReport(cwd);
|
|
11122
|
+
}
|
|
11123
|
+
async function restartVgdAndReport(opts = {}) {
|
|
11018
11124
|
let result;
|
|
11019
11125
|
try {
|
|
11020
|
-
result = await restartVgdIfRunning();
|
|
11126
|
+
result = await restartVgdIfRunning(void 0, opts);
|
|
11021
11127
|
} catch {
|
|
11022
11128
|
return;
|
|
11023
11129
|
}
|
|
@@ -11771,6 +11877,7 @@ function formatArchitectureDiagram(arch) {
|
|
|
11771
11877
|
lines.push("");
|
|
11772
11878
|
if (arch.layers.length > 0) {
|
|
11773
11879
|
for (const layer of arch.layers) {
|
|
11880
|
+
if (layer.fileCount === 0) continue;
|
|
11774
11881
|
const risk = layer.riskLevel === "none" ? chalk7.dim("none") : layer.riskLevel === "low" ? chalk7.green("low") : layer.riskLevel === "moderate" ? chalk7.yellow("moderate") : chalk7.red("high");
|
|
11775
11882
|
lines.push(` ${chalk7.bold(layer.layer)} ${layer.fileCount} file${layer.fileCount !== 1 ? "s" : ""} drift ${scoreBar(layer.driftScore)} risk ${risk}`);
|
|
11776
11883
|
}
|
|
@@ -11778,12 +11885,27 @@ function formatArchitectureDiagram(arch) {
|
|
|
11778
11885
|
}
|
|
11779
11886
|
if (arch.violations && arch.violations.length > 0) {
|
|
11780
11887
|
const extra = arch.violationsCapped ? "+" : "";
|
|
11781
|
-
|
|
11782
|
-
|
|
11783
|
-
|
|
11888
|
+
const boundary = arch.violations.filter((v) => !v.rule.startsWith("graph-conflict:"));
|
|
11889
|
+
const conflicts = arch.violations.filter((v) => v.rule.startsWith("graph-conflict:"));
|
|
11890
|
+
if (boundary.length > 0) {
|
|
11891
|
+
const cap = extra && conflicts.length === 0 ? extra : "";
|
|
11892
|
+
lines.push(` Boundary violations (${boundary.length}${cap})`);
|
|
11893
|
+
for (const v of boundary.slice(0, 8)) {
|
|
11894
|
+
lines.push(` ${v.fromFile} \u2192 ${v.toFile} ${v.rule}`);
|
|
11895
|
+
}
|
|
11896
|
+
if (boundary.length > 8) {
|
|
11897
|
+
lines.push(chalk7.dim(` + ${boundary.length - 8} more`));
|
|
11898
|
+
}
|
|
11784
11899
|
}
|
|
11785
|
-
if (
|
|
11786
|
-
|
|
11900
|
+
if (conflicts.length > 0) {
|
|
11901
|
+
const cap = extra ? extra : "";
|
|
11902
|
+
lines.push(` Layer conflicts (${conflicts.length}${cap})`);
|
|
11903
|
+
for (const v of conflicts.slice(0, 8)) {
|
|
11904
|
+
lines.push(` ${v.fromFile} \u2192 ${v.toFile} ${v.rule}`);
|
|
11905
|
+
}
|
|
11906
|
+
if (conflicts.length > 8) {
|
|
11907
|
+
lines.push(chalk7.dim(` + ${conflicts.length - 8} more`));
|
|
11908
|
+
}
|
|
11787
11909
|
}
|
|
11788
11910
|
lines.push("");
|
|
11789
11911
|
}
|
|
@@ -12446,7 +12568,7 @@ var LOCALE_CONFIG_FILENAMES = ["vibgrate.locale.yaml", ".vibgrate/locale.yaml"];
|
|
|
12446
12568
|
function findLocaleConfig(cwd) {
|
|
12447
12569
|
for (const name of LOCALE_CONFIG_FILENAMES) {
|
|
12448
12570
|
const candidate = path46.join(cwd, name);
|
|
12449
|
-
if (
|
|
12571
|
+
if (fs13.existsSync(candidate)) return candidate;
|
|
12450
12572
|
}
|
|
12451
12573
|
return null;
|
|
12452
12574
|
}
|
|
@@ -12474,7 +12596,7 @@ function loadLocaleConfig(cwd) {
|
|
|
12474
12596
|
const file = findLocaleConfig(cwd);
|
|
12475
12597
|
if (!file) return { config: {}, file: null };
|
|
12476
12598
|
try {
|
|
12477
|
-
return { config: parseLocaleConfig(
|
|
12599
|
+
return { config: parseLocaleConfig(fs13.readFileSync(file, "utf8")), file };
|
|
12478
12600
|
} catch (error) {
|
|
12479
12601
|
throw new Error(
|
|
12480
12602
|
`Could not parse ${path46.relative(cwd, file)}: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -12493,8 +12615,8 @@ function serializeLocaleConfig(config) {
|
|
|
12493
12615
|
}
|
|
12494
12616
|
function writeLocaleConfig(cwd, config, filename) {
|
|
12495
12617
|
const target = filename ?? path46.join(cwd, LOCALE_CONFIG_FILENAMES[0]);
|
|
12496
|
-
|
|
12497
|
-
|
|
12618
|
+
fs13.mkdirSync(path46.dirname(target), { recursive: true });
|
|
12619
|
+
fs13.writeFileSync(target, serializeLocaleConfig(config), "utf8");
|
|
12498
12620
|
return target;
|
|
12499
12621
|
}
|
|
12500
12622
|
function resolveLocaleSettings(config, flags) {
|
|
@@ -12652,14 +12774,14 @@ function resolveLocaleFiles(cwd, template, languages, namespaces) {
|
|
|
12652
12774
|
for (const namespace of namespaces) {
|
|
12653
12775
|
const relative13 = renderPath(template, language, namespace);
|
|
12654
12776
|
const file = path46.resolve(cwd, relative13);
|
|
12655
|
-
out2.push({ language, namespace, file, relative: relative13, exists:
|
|
12777
|
+
out2.push({ language, namespace, file, relative: relative13, exists: fs13.existsSync(file) });
|
|
12656
12778
|
}
|
|
12657
12779
|
}
|
|
12658
12780
|
return out2;
|
|
12659
12781
|
}
|
|
12660
12782
|
function readCatalog(file, format) {
|
|
12661
|
-
if (!
|
|
12662
|
-
const text =
|
|
12783
|
+
if (!fs13.existsSync(file)) return {};
|
|
12784
|
+
const text = fs13.readFileSync(file, "utf8");
|
|
12663
12785
|
try {
|
|
12664
12786
|
return codecFor(format).decode(text);
|
|
12665
12787
|
} catch (error) {
|
|
@@ -12670,11 +12792,11 @@ function readCatalog(file, format) {
|
|
|
12670
12792
|
}
|
|
12671
12793
|
function writeCatalog(file, format, catalog, opts = {}) {
|
|
12672
12794
|
const encoded = codecFor(format).encode(sortKeys(catalog));
|
|
12673
|
-
const existing =
|
|
12795
|
+
const existing = fs13.existsSync(file) ? fs13.readFileSync(file, "utf8") : null;
|
|
12674
12796
|
const changed = existing !== encoded;
|
|
12675
12797
|
if (changed && !opts.dryRun) {
|
|
12676
|
-
|
|
12677
|
-
|
|
12798
|
+
fs13.mkdirSync(path46.dirname(file), { recursive: true });
|
|
12799
|
+
fs13.writeFileSync(file, encoded, "utf8");
|
|
12678
12800
|
}
|
|
12679
12801
|
return { file, changed, bytes: Buffer.byteLength(encoded, "utf8") };
|
|
12680
12802
|
}
|
|
@@ -14357,17 +14479,17 @@ function resolveSigningKey(root3, explicit) {
|
|
|
14357
14479
|
const chosen = process.env.VG_ATTEST_KEY;
|
|
14358
14480
|
const keyPath = chosen ? path46.resolve(chosen) : path46.join(root3, ".vibgrate", DEFAULT_KEY);
|
|
14359
14481
|
let minted = false;
|
|
14360
|
-
if (!
|
|
14482
|
+
if (!fs13.existsSync(keyPath)) {
|
|
14361
14483
|
if (chosen) throw new CliError(`signing key not found: ${chosen}`, ExitCode.USAGE_ERROR);
|
|
14362
14484
|
const kp = generateKeypair();
|
|
14363
|
-
|
|
14364
|
-
|
|
14365
|
-
|
|
14485
|
+
fs13.mkdirSync(path46.dirname(keyPath), { recursive: true });
|
|
14486
|
+
fs13.writeFileSync(keyPath, kp.privatePem, { mode: 384 });
|
|
14487
|
+
fs13.writeFileSync(`${keyPath}.pub`, kp.publicPem);
|
|
14366
14488
|
minted = true;
|
|
14367
14489
|
}
|
|
14368
14490
|
let key2;
|
|
14369
14491
|
try {
|
|
14370
|
-
key2 = crypto3.createPrivateKey(
|
|
14492
|
+
key2 = crypto3.createPrivateKey(fs13.readFileSync(keyPath, "utf8"));
|
|
14371
14493
|
} catch {
|
|
14372
14494
|
throw new CliError(`could not read an Ed25519 private key from ${keyPath}`, ExitCode.USAGE_ERROR);
|
|
14373
14495
|
}
|
|
@@ -14378,8 +14500,8 @@ function resolveSigningKey(root3, explicit) {
|
|
|
14378
14500
|
}
|
|
14379
14501
|
function writeBundle(input) {
|
|
14380
14502
|
const dir = input.outDir;
|
|
14381
|
-
|
|
14382
|
-
const write = (rel, data) =>
|
|
14503
|
+
fs13.mkdirSync(path46.join(dir, "inputs", "releases"), { recursive: true });
|
|
14504
|
+
const write = (rel, data) => fs13.writeFileSync(path46.join(dir, rel), `${JSON.stringify(data, null, 2)}
|
|
14383
14505
|
`);
|
|
14384
14506
|
write("result.json", input.result);
|
|
14385
14507
|
write(path46.join("inputs", "advisory.json"), input.advisory);
|
|
@@ -14403,13 +14525,13 @@ function writeBundle(input) {
|
|
|
14403
14525
|
disclaimer: input.regime.disclaimer
|
|
14404
14526
|
});
|
|
14405
14527
|
if (input.envelope) {
|
|
14406
|
-
|
|
14528
|
+
fs13.writeFileSync(path46.join(dir, "evidence.intoto.jsonl"), `${JSON.stringify(input.envelope)}
|
|
14407
14529
|
`);
|
|
14408
14530
|
}
|
|
14409
14531
|
if (input.timestampToken) {
|
|
14410
|
-
|
|
14532
|
+
fs13.writeFileSync(path46.join(dir, "timestamp.tsr"), input.timestampToken);
|
|
14411
14533
|
}
|
|
14412
|
-
|
|
14534
|
+
fs13.writeFileSync(path46.join(dir, "VERIFY.md"), verifyDoc(input));
|
|
14413
14535
|
return dir;
|
|
14414
14536
|
}
|
|
14415
14537
|
function verifyDoc(input) {
|
|
@@ -14752,7 +14874,7 @@ var packCmd = new Command("pack").description("Build the submission pack a human
|
|
|
14752
14874
|
const stage = opts.stage ?? regime.clocks[0]?.stage ?? "early-warning";
|
|
14753
14875
|
const md = buildPack(result, regime, org, stage);
|
|
14754
14876
|
if (opts.out) {
|
|
14755
|
-
|
|
14877
|
+
fs13.writeFileSync(path46.resolve(rootDir, opts.out), md);
|
|
14756
14878
|
console.error(chalk7.green("\u2714") + ` pack written to ${opts.out}`);
|
|
14757
14879
|
} else {
|
|
14758
14880
|
console.log(md);
|
|
@@ -14795,19 +14917,19 @@ var drillCmd = new Command("drill").description("Timed dry-run of the determinat
|
|
|
14795
14917
|
});
|
|
14796
14918
|
var verifyCmd = new Command("verify").description("Verify an evidence bundle offline (no Vibgrate needed)").argument("<bundle>", "Path to an evidence bundle directory or evidence.intoto.jsonl").option("--pub <file>", "Public key PEM to pin the signer (establish trust)").action((bundlePath, opts) => {
|
|
14797
14919
|
const abs = path46.resolve(bundlePath);
|
|
14798
|
-
const envPath =
|
|
14799
|
-
if (!
|
|
14800
|
-
const envelope = JSON.parse(
|
|
14920
|
+
const envPath = fs13.statSync(abs).isDirectory() ? path46.join(abs, "evidence.intoto.jsonl") : abs;
|
|
14921
|
+
if (!fs13.existsSync(envPath)) throw new CliError(`no evidence.intoto.jsonl at ${bundlePath}`, ExitCode.NOT_FOUND);
|
|
14922
|
+
const envelope = JSON.parse(fs13.readFileSync(envPath, "utf8").trim().split("\n")[0]);
|
|
14801
14923
|
const resultPath = path46.join(path46.dirname(envPath), "result.json");
|
|
14802
|
-
const result =
|
|
14803
|
-
const publicKeyPem = opts.pub ?
|
|
14924
|
+
const result = fs13.existsSync(resultPath) ? JSON.parse(fs13.readFileSync(resultPath, "utf8")) : void 0;
|
|
14925
|
+
const publicKeyPem = opts.pub ? fs13.readFileSync(path46.resolve(opts.pub), "utf8") : void 0;
|
|
14804
14926
|
const v = verifyEvidenceEnvelope(envelope, { publicKeyPem, result });
|
|
14805
14927
|
const color = v.status === "verified" ? chalk7.green : v.status === "failed" ? chalk7.red : chalk7.yellow;
|
|
14806
14928
|
console.log(" " + color(v.status.toUpperCase()) + ` ${v.reason}`);
|
|
14807
14929
|
if (v.evidenceId) console.log(" " + chalk7.dim(`evidence ${v.evidenceId} \xB7 regime ${v.regime} \xB7 advisory ${v.advisoryId} \xB7 ${v.overallStatus}`));
|
|
14808
14930
|
const tsrPath = path46.join(path46.dirname(envPath), "timestamp.tsr");
|
|
14809
|
-
if (
|
|
14810
|
-
const t = verifyTimestamp(
|
|
14931
|
+
if (fs13.existsSync(tsrPath) && result) {
|
|
14932
|
+
const t = verifyTimestamp(fs13.readFileSync(tsrPath), exposureSubjectDigest(result));
|
|
14811
14933
|
const tcolor = t.imprintMatches ? chalk7.green : chalk7.red;
|
|
14812
14934
|
console.log(" " + tcolor("TIMESTAMP") + ` ${t.reason}`);
|
|
14813
14935
|
}
|
|
@@ -14906,9 +15028,9 @@ var pushCmd = new Command("push").description("Push the product registry (and an
|
|
|
14906
15028
|
let exposure;
|
|
14907
15029
|
if (opts.result) {
|
|
14908
15030
|
const raw = path46.resolve(rootDir, opts.result);
|
|
14909
|
-
const resultPath =
|
|
14910
|
-
if (!
|
|
14911
|
-
exposure = JSON.parse(
|
|
15031
|
+
const resultPath = fs13.existsSync(raw) && fs13.statSync(raw).isDirectory() ? path46.join(raw, "result.json") : raw;
|
|
15032
|
+
if (!fs13.existsSync(resultPath)) throw new CliError(`no result.json at ${opts.result}`, ExitCode.NOT_FOUND);
|
|
15033
|
+
exposure = JSON.parse(fs13.readFileSync(resultPath, "utf8"));
|
|
14912
15034
|
}
|
|
14913
15035
|
const payload = { schemaVersion: "evidence-push-1", regime: regime.id, generatedAt: nowIso(), signed: Boolean(opts.signed), products: productPayload, exposure };
|
|
14914
15036
|
const body = JSON.stringify(payload);
|
|
@@ -15107,7 +15229,7 @@ function dispatch(argv, cwd) {
|
|
|
15107
15229
|
}
|
|
15108
15230
|
const looksLikeQuestion = /\s/.test(first) || first.endsWith("?");
|
|
15109
15231
|
if (looksLikeQuestion) return ["ask", ...args];
|
|
15110
|
-
if (
|
|
15232
|
+
if (fs13.existsSync(path46.resolve(cwd, first))) {
|
|
15111
15233
|
return [hasBuildOnlyFlag(args) ? "build" : "scan", ...args];
|
|
15112
15234
|
}
|
|
15113
15235
|
const moved = MOVED_COMMANDS[first];
|