@vibgrate/cli 2026.817.2 → 2026.818.2
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-X6VYCE63.js +30 -0
- package/dist/{agent-UQC7QN77.js.map → agent-X6VYCE63.js.map} +1 -1
- package/dist/{approvals-ASPJQUZK.js → approvals-TPQFQSWG.js} +5 -5
- package/dist/{approvals-ASPJQUZK.js.map → approvals-TPQFQSWG.js.map} +1 -1
- package/dist/attach-G5JUIWIT.js +10 -0
- package/dist/attach-G5JUIWIT.js.map +1 -0
- package/dist/baseline-DXI64VLW.js +9 -0
- package/dist/{baseline-FIV6PR2M.js.map → baseline-DXI64VLW.js.map} +1 -1
- package/dist/{chunk-AXZZ5CCG.js → chunk-2C33WR5O.js} +38 -19
- package/dist/chunk-2C33WR5O.js.map +1 -0
- package/dist/chunk-4NTNMT6T.js +6 -0
- package/dist/{chunk-PRG2ULPK.js.map → chunk-4NTNMT6T.js.map} +1 -1
- package/dist/chunk-5IQBIXHS.js +23 -0
- package/dist/chunk-5IQBIXHS.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-E2FAQREZ.js → chunk-6PFHDHOL.js} +174 -401
- package/dist/chunk-6PFHDHOL.js.map +1 -0
- package/dist/chunk-6WRG7VDO.js +118 -0
- package/dist/chunk-6WRG7VDO.js.map +1 -0
- package/dist/{chunk-3NJUOIZQ.js → chunk-AEJYA6HZ.js} +5 -5
- package/dist/{chunk-3NJUOIZQ.js.map → chunk-AEJYA6HZ.js.map} +1 -1
- package/dist/{chunk-O2DL2Q55.js → chunk-B4EXD5LK.js} +5 -5
- package/dist/{chunk-O2DL2Q55.js.map → chunk-B4EXD5LK.js.map} +1 -1
- package/dist/{chunk-EXV4QSAD.js → chunk-BMOFJIMG.js} +3 -3
- package/dist/{chunk-EXV4QSAD.js.map → chunk-BMOFJIMG.js.map} +1 -1
- package/dist/chunk-DBX3DL27.js +26 -0
- package/dist/chunk-DBX3DL27.js.map +1 -0
- package/dist/{chunk-KNGAZDGF.js → chunk-E3O5UKNA.js} +151 -42
- package/dist/chunk-E3O5UKNA.js.map +1 -0
- package/dist/{chunk-RBIRXQR6.js → chunk-E53WBVUQ.js} +7 -14
- package/dist/chunk-E53WBVUQ.js.map +1 -0
- package/dist/{chunk-C3LMWZKF.js → chunk-FFXGWFAE.js} +4 -4
- package/dist/{chunk-C3LMWZKF.js.map → chunk-FFXGWFAE.js.map} +1 -1
- package/dist/chunk-H5Q4JUY4.js +47 -0
- package/dist/chunk-H5Q4JUY4.js.map +1 -0
- package/dist/{chunk-LHKQGVRF.js → chunk-HF6R73UC.js} +100 -11
- package/dist/chunk-HF6R73UC.js.map +1 -0
- package/dist/{chunk-K6DXETMC.js → chunk-JGA63RGF.js} +13 -12
- package/dist/chunk-JGA63RGF.js.map +1 -0
- package/dist/{chunk-3FMRFECC.js → chunk-KU7FI5EV.js} +3 -3
- package/dist/{chunk-3FMRFECC.js.map → chunk-KU7FI5EV.js.map} +1 -1
- package/dist/{chunk-5OL2TSHK.js → chunk-L2OS4WHT.js} +4 -4
- package/dist/{chunk-5OL2TSHK.js.map → chunk-L2OS4WHT.js.map} +1 -1
- package/dist/chunk-LJSJX6U4.js +38 -0
- package/dist/chunk-LJSJX6U4.js.map +1 -0
- package/dist/{chunk-Q4G2BWE3.js → chunk-MRZHNUN7.js} +12 -6
- package/dist/chunk-MRZHNUN7.js.map +1 -0
- package/dist/chunk-NDNNOAS6.js +16 -0
- package/dist/chunk-NDNNOAS6.js.map +1 -0
- package/dist/chunk-NJQZRM55.js +100 -0
- package/dist/chunk-NJQZRM55.js.map +1 -0
- package/dist/{chunk-DVW3SVCW.js → chunk-NKLYDSB7.js} +29 -9
- package/dist/chunk-NKLYDSB7.js.map +1 -0
- package/dist/{chunk-TVDMNIUT.js → chunk-O5IJDMTB.js} +4 -4
- package/dist/{chunk-TVDMNIUT.js.map → chunk-O5IJDMTB.js.map} +1 -1
- package/dist/chunk-POOL355F.js +237 -0
- package/dist/chunk-POOL355F.js.map +1 -0
- package/dist/{chunk-XLXJC7H3.js → chunk-PRHH4DVO.js} +5 -118
- package/dist/chunk-PRHH4DVO.js.map +1 -0
- package/dist/{chunk-3H3SVJUY.js → chunk-RHKOUPWT.js} +107 -542
- package/dist/chunk-RHKOUPWT.js.map +1 -0
- package/dist/{chunk-WAKP7SK7.js → chunk-V2UGRUTL.js} +225 -48
- package/dist/chunk-V2UGRUTL.js.map +1 -0
- package/dist/{chunk-2FEB5KJS.js → chunk-V6WONSIK.js} +5 -4
- package/dist/chunk-V6WONSIK.js.map +1 -0
- package/dist/{chunk-WVMOGIPC.js → chunk-VMAIDM4K.js} +3 -3
- package/dist/{chunk-WVMOGIPC.js.map → chunk-VMAIDM4K.js.map} +1 -1
- package/dist/{chunk-GOGMS3ST.js → chunk-VQ5KMHW6.js} +860 -65
- package/dist/chunk-VQ5KMHW6.js.map +1 -0
- package/dist/{chunk-M7IO3DXH.js → chunk-X2MQ7UFL.js} +250 -30
- package/dist/chunk-X2MQ7UFL.js.map +1 -0
- package/dist/{chunk-OZ3IFXRD.js → chunk-YENM3HT7.js} +5 -4
- package/dist/chunk-YENM3HT7.js.map +1 -0
- package/dist/{chunk-KJT2R6WW.js → chunk-YF54UMOU.js} +3 -3
- package/dist/{chunk-KJT2R6WW.js.map → chunk-YF54UMOU.js.map} +1 -1
- package/dist/{chunk-Q3M6K3HY.js → chunk-ZUOBPKVK.js} +3 -3
- package/dist/{chunk-Q3M6K3HY.js.map → chunk-ZUOBPKVK.js.map} +1 -1
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +711 -463
- package/dist/cli.js.map +1 -1
- package/dist/client-UQIELEEZ.js +8 -0
- package/dist/client-UQIELEEZ.js.map +1 -0
- package/dist/daemon-GUMWMKCA.js +31 -0
- package/dist/{daemon-FPTRHO5N.js.map → daemon-GUMWMKCA.js.map} +1 -1
- package/dist/embed-worker-main.js +3 -3
- package/dist/ensure-map-FHDJTO7Y.js +41 -0
- package/dist/{ensure-map-342G2IV3.js.map → ensure-map-FHDJTO7Y.js.map} +1 -1
- package/dist/graph-backend-W2D3HRRD.js +16 -0
- package/dist/{graph-backend-RNWQBT3P.js.map → graph-backend-W2D3HRRD.js.map} +1 -1
- package/dist/index.d.ts +633 -4
- package/dist/index.js +26 -17
- package/dist/index.js.map +1 -1
- package/dist/{interactive-SR7TMF6M.js → interactive-2MK4TLRD.js} +42 -34
- package/dist/interactive-2MK4TLRD.js.map +1 -0
- package/dist/load-4R4HYMBB.js +11 -0
- package/dist/{load-AYFECIQB.js.map → load-4R4HYMBB.js.map} +1 -1
- package/dist/parse-worker.js +3 -2
- package/dist/parse-worker.js.map +1 -1
- package/dist/publish-7YHRTBRA.js +9 -0
- package/dist/publish-7YHRTBRA.js.map +1 -0
- package/dist/{run-outcome-YQQJG3LW.js → run-outcome-H5GVDDZJ.js} +5 -5
- package/dist/{run-outcome-YQQJG3LW.js.map → run-outcome-H5GVDDZJ.js.map} +1 -1
- package/dist/runtime-session-JBIHHH5N.js +27 -0
- package/dist/{runtime-session-CNJ4DAV5.js.map → runtime-session-JBIHHH5N.js.map} +1 -1
- package/dist/semantic-status-2JFLIQQJ.js +4 -0
- package/dist/semantic-status-2JFLIQQJ.js.map +1 -0
- package/dist/{session-H34HUV2Y.js → session-N5IU4K5Q.js} +8 -8
- package/dist/{session-H34HUV2Y.js.map → session-N5IU4K5Q.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-4WLSUF6I.js} +18 -15
- package/dist/stream-json-4WLSUF6I.js.map +1 -0
- package/dist/version-DTEU3SQD.js +4 -0
- package/dist/{version-WSE3QOPK.js.map → version-DTEU3SQD.js.map} +1 -1
- package/dist/{vg-mcp-bridge-2CNLHNEL.js → vg-mcp-bridge-KDVYIMFX.js} +12 -11
- package/dist/vg-mcp-bridge-KDVYIMFX.js.map +1 -0
- package/dist/{vgd-URUZQORN.js → vgd-M7UOPWLB.js} +15 -10
- package/dist/vgd-M7UOPWLB.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,72 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { fetchCatalog, resolveProviders } from './chunk-
|
|
3
|
-
import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-
|
|
4
|
-
import { loadAdvancedScanHook, baselineCommand } from './chunk-
|
|
5
|
-
import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, ProgressBar, printLogo, runBuild } from './chunk-
|
|
6
|
-
export { runBuild } from './chunk-
|
|
7
|
-
import {
|
|
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 { fetchCatalog, resolveProviders } from './chunk-FFXGWFAE.js';
|
|
3
|
+
import { telemetryOptOut, StatsSharer, statsEndpoint, isCI } from './chunk-BMOFJIMG.js';
|
|
4
|
+
import { loadAdvancedScanHook, baselineCommand } from './chunk-6ABMV74F.js';
|
|
5
|
+
import { sha256Hex, generateKeypair, dssePae, DSSE_PAYLOAD_TYPE, keyId, registerBuild, LiveStatus, ProgressBar, printLogo, runBuild } from './chunk-HF6R73UC.js';
|
|
6
|
+
export { runBuild } from './chunk-HF6R73UC.js';
|
|
7
|
+
import { readOrchestratorState, writeOrchestratorState, parseMode, setDefaultMode, recommendMode, activePin, resolveMode, providerForBackend, QUALIFIED_PACKS, pinPack, unpinPack, buildOrchestratorStatus } from './chunk-NZELMYT4.js';
|
|
12
8
|
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';
|
|
9
|
+
import { runCodeSession } from './chunk-AEJYA6HZ.js';
|
|
10
|
+
import { CONTEXT_POLICY_VERSION, computeFcsReport, renderFcsReportMarkdown, createTrajectoryCollector, runAgent } from './chunk-JGA63RGF.js';
|
|
16
11
|
import './chunk-543E6WDJ.js';
|
|
17
|
-
import './chunk-
|
|
18
|
-
import './chunk-
|
|
19
|
-
import './chunk-RBIRXQR6.js';
|
|
20
|
-
import { buildIdentifierTrieFromGraph } from './chunk-5HYCB55P.js';
|
|
12
|
+
import './chunk-ZUOBPKVK.js';
|
|
13
|
+
import './chunk-O5IJDMTB.js';
|
|
21
14
|
import { parseReasoningEffort, summarizeDiffs, ScriptedProvider } from './chunk-74UBGF4P.js';
|
|
22
15
|
import './chunk-7AVYKZEM.js';
|
|
23
16
|
import { buildModelInstallPlan } from './chunk-I5LP55B6.js';
|
|
24
17
|
import { ensurePackage, ensureUnavailableMessage } from './chunk-3HNPVXUK.js';
|
|
18
|
+
import { vgdVersionSkew, restartVgdIfRunning, stopVgd, registerDaemon, rootOf, requireGraph } from './chunk-E3O5UKNA.js';
|
|
19
|
+
import { readGlobal, applyGlobalOptions } from './chunk-YENM3HT7.js';
|
|
20
|
+
import { ActivityLog } from './chunk-H5Q4JUY4.js';
|
|
21
|
+
import { disableColor, info, c, json, out } from './chunk-CT5BS56U.js';
|
|
25
22
|
import { init_resolve_ollama, gatherSystemMemory, resolveOllamaBinary, hasOllamaBinary, resolve_ollama_exports } from './chunk-FJG5AXKZ.js';
|
|
26
|
-
import { readOrchestratorState, writeOrchestratorState, parseMode, setDefaultMode, recommendMode, activePin, resolveMode, providerForBackend, QUALIFIED_PACKS, pinPack, unpinPack, buildOrchestratorStatus } from './chunk-NZELMYT4.js';
|
|
27
23
|
import { fmt, estimateModelBytes } from './chunk-7N4Y3E47.js';
|
|
24
|
+
import { isManifest, isDependencyFile, manifestHash, loadScanCache, writeScanCache, manifestKind, findPackageLine, endOfLine, findRuntimeLine } from './chunk-VQ5KMHW6.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-X2MQ7UFL.js';
|
|
30
|
+
import { refreshIfStale } from './chunk-B4EXD5LK.js';
|
|
31
|
+
import { driftCount, ASSISTANTS, detectAssistants, isAssistantInstalled, detectServeLaunch, installAssistant, writeNavigationConfig, uninstallAssistant, buildGraph, writeSnapshot, probeFreshness, assistantById, SMALL_REPO_FILES } from './chunk-6PFHDHOL.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-NKLYDSB7.js';
|
|
33
33
|
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,
|
|
35
|
-
import { CliError, ExitCode, usageError, engineUnavailable } from './chunk-MS6V5XKB.js';
|
|
34
|
+
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';
|
|
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-RHKOUPWT.js';
|
|
37
|
+
import { recordCliCall, CLI_TOOL_ALIASES, savingsLedgerPath, clearSavings, readSavings, readUsage, readModelSavings, CAPSULE_RANKING_VERSION, SAVINGS_TOOLS, sanitizeClient } from './chunk-YF54UMOU.js';
|
|
41
38
|
import { discoverModels } from './chunk-CQDUBAQY.js';
|
|
42
39
|
import { freeBytesOnVolume, weightStoreDir, listCachedWeights, ensureWeightCached, catalogIntegrityReport } from './chunk-OV4KGXPD.js';
|
|
43
|
-
import {
|
|
44
|
-
import './chunk-
|
|
40
|
+
import { CliError, ExitCode, usageError, engineUnavailable } from './chunk-MS6V5XKB.js';
|
|
41
|
+
import { attachVgd } from './chunk-NJQZRM55.js';
|
|
45
42
|
import { pathExists as pathExists$1, parseExcludePatterns } from './chunk-NG4KIJW6.js';
|
|
46
43
|
import { ensureDir, pathExists, readJsonFile, writeTextFile, writeJsonFile } from './chunk-CRAMOEBE.js';
|
|
44
|
+
import './chunk-5IQBIXHS.js';
|
|
47
45
|
import { init_cli_invocation, resolveCliInvocation, NPX_INVOCATION } from './chunk-EZ7UC5Y5.js';
|
|
48
|
-
import {
|
|
46
|
+
import { publishGraphToVgd } from './chunk-LJSJX6U4.js';
|
|
47
|
+
import { isRelevantChange } from './chunk-DBX3DL27.js';
|
|
48
|
+
import { discover, SKIP_DIRS } from './chunk-POOL355F.js';
|
|
49
|
+
import { inventory, enrichOnline, ECOSYSTEMS } from './chunk-6BEBJCK4.js';
|
|
50
|
+
import { resolveOne } from './chunk-J7LKEB2R.js';
|
|
51
|
+
import { queryGraphSemantic, queryGraph, indexFor, impactOf } from './chunk-MRZHNUN7.js';
|
|
52
|
+
import { loadGraph, loadGraphPreferIndex, SCHEMA_VERSION } from './chunk-KU7FI5EV.js';
|
|
53
|
+
import './chunk-E53WBVUQ.js';
|
|
54
|
+
import './chunk-NDNNOAS6.js';
|
|
55
|
+
import './chunk-5I4VSBWQ.js';
|
|
56
|
+
import { resolvedGrammarFiles, TOOLCHAIN_GRAMMARS, resolveToolchainGrammar, grammarSetVersion, fileRolesFromParseCache } from './chunk-PRHH4DVO.js';
|
|
49
57
|
import './chunk-T7RSQ5WD.js';
|
|
50
|
-
import
|
|
51
|
-
import {
|
|
58
|
+
import './chunk-6WRG7VDO.js';
|
|
59
|
+
import { embeddingsCached, resolveEmbedModel, loadEmbedder, getNodeEmbeddings, unavailableMessage, countPending, modelCacheInfo, embeddingsPath, clearModelCache, withTimeout } from './chunk-2C33WR5O.js';
|
|
60
|
+
import { resetRelevanceProviderCache, loadRelevanceProvider, relevanceModuleDir, resolveGraphPath, analyzeQuestion, loadTopicTags, renderReport, loadGraphFileWithSnapshot, writeArtifacts, vibgrateDir, mapFileExists, ensureVibgrateGitignore } from './chunk-VMAIDM4K.js';
|
|
52
61
|
import { cacheDir } from './chunk-MVPRPSXU.js';
|
|
53
62
|
import { serializeGraph, stableStringify, parseGraph } from './chunk-O3LABX6I.js';
|
|
54
|
-
import { VERSION } from './chunk-
|
|
63
|
+
import { VERSION } from './chunk-4NTNMT6T.js';
|
|
55
64
|
import './chunk-BWPBB45M.js';
|
|
56
|
-
import { canonicalize, hashString
|
|
65
|
+
import { canonicalize, hashString } from './chunk-JFGYT6BI.js';
|
|
57
66
|
import './chunk-BPF3YX2U.js';
|
|
58
67
|
import { __toCommonJS } from './chunk-Z6ZWNWWR.js';
|
|
59
|
-
import * as
|
|
60
|
-
import
|
|
68
|
+
import * as fs13 from 'fs';
|
|
69
|
+
import fs13__default, { realpathSync } from 'fs';
|
|
61
70
|
import * as path46 from 'path';
|
|
62
71
|
import path46__default from 'path';
|
|
63
72
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
@@ -71,7 +80,7 @@ import * as zlib from 'zlib';
|
|
|
71
80
|
import * as crypto3 from 'crypto';
|
|
72
81
|
import { randomUUID, createHash } from 'crypto';
|
|
73
82
|
import chalk7 from 'chalk';
|
|
74
|
-
import * as
|
|
83
|
+
import * as fs27 from 'fs/promises';
|
|
75
84
|
import { parse, stringify } from 'yaml';
|
|
76
85
|
|
|
77
86
|
init_cli_invocation();
|
|
@@ -85,7 +94,7 @@ async function runStatus(global) {
|
|
|
85
94
|
const root3 = path46.resolve(global.cwd ?? ".");
|
|
86
95
|
const graphPath = resolveGraphPath(root3, global.graph);
|
|
87
96
|
const graph = loadGraph(root3, graphPath);
|
|
88
|
-
const hasCache =
|
|
97
|
+
const hasCache = fs13.existsSync(path46.join(cacheDir(root3), "parse-cache.json"));
|
|
89
98
|
let stale = null;
|
|
90
99
|
let staleExact = false;
|
|
91
100
|
if (graph) {
|
|
@@ -158,6 +167,21 @@ function registerAsk(program) {
|
|
|
158
167
|
}
|
|
159
168
|
}
|
|
160
169
|
const { graph } = requireGraph(global);
|
|
170
|
+
const activity = new ActivityLog();
|
|
171
|
+
const live = !global.json ? new LiveStatus() : null;
|
|
172
|
+
live?.start("attaching to vgd\u2026");
|
|
173
|
+
const attached = await activity.time(
|
|
174
|
+
"attach",
|
|
175
|
+
() => attachVgd(root3, {
|
|
176
|
+
graphPath: global.graph,
|
|
177
|
+
disabled: global.daemon === false,
|
|
178
|
+
// Skip the republish when the daemon already holds this exact map:
|
|
179
|
+
// a publish drops the slot's vectors, so doing it on every ask
|
|
180
|
+
// churned the index for nothing.
|
|
181
|
+
corpusHash: graph.provenance?.corpusHash
|
|
182
|
+
}),
|
|
183
|
+
(a) => describeAttach(a)
|
|
184
|
+
);
|
|
161
185
|
const budget = Number(opts.budget) || 2e3;
|
|
162
186
|
const q = question.join(" ");
|
|
163
187
|
const wantSemantic = opts.semantic !== false && !global.local;
|
|
@@ -166,34 +190,64 @@ function registerAsk(program) {
|
|
|
166
190
|
let note = "";
|
|
167
191
|
const relevance = await analyzeQuestion(q);
|
|
168
192
|
const topicTags = relevance ? await loadTopicTags(graph, root3, resolveGraphPath(root3, global.graph)) : null;
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
193
|
+
try {
|
|
194
|
+
if (wantSemantic) {
|
|
195
|
+
live?.set("asking the daemon\u2026");
|
|
196
|
+
const ranked = attached.status === "attached" && attached.repositoryId ? await activity.time(
|
|
197
|
+
"semantic",
|
|
198
|
+
// The attach above already resolved (and, if needed, published)
|
|
199
|
+
// the slot — this session only sends the question.
|
|
200
|
+
() => new DaemonSemanticSession(root3, { socketPath: attached.socketPath, publish: false }).rank(q, void 0, {
|
|
201
|
+
onProgress: (p) => live?.set(p.detail)
|
|
202
|
+
}),
|
|
203
|
+
(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 index unavailable \u2014 embedding in this process" }
|
|
204
|
+
) : null;
|
|
205
|
+
if (ranked) {
|
|
206
|
+
live?.set("answering from the daemon index\u2026");
|
|
207
|
+
result = await queryGraphSemantic(graph, q, {
|
|
208
|
+
budget,
|
|
209
|
+
semanticRanked: ranked.ranked,
|
|
210
|
+
relevance,
|
|
211
|
+
topicTags
|
|
212
|
+
});
|
|
213
|
+
mode = `semantic (vgd${ranked.model ? `, ${ranked.model}` : ""})`;
|
|
214
|
+
activity.add("answer", "ok", "answered from the daemon index \u2014 no local model load");
|
|
215
|
+
} else {
|
|
216
|
+
const firstRun = !embeddingsCached(root3, resolveEmbedModel());
|
|
217
|
+
live?.set(
|
|
218
|
+
firstRun ? "loading the embedding model (first use; then cached and offline)\u2026" : "embedding the map in this process\u2026"
|
|
219
|
+
);
|
|
220
|
+
let reason;
|
|
221
|
+
let detail;
|
|
222
|
+
const embedder = await loadEmbedder({
|
|
223
|
+
local: global.local,
|
|
224
|
+
onUnavailable: (r, d) => {
|
|
225
|
+
reason = r;
|
|
226
|
+
detail = d;
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
if (embedder) {
|
|
230
|
+
live?.stop();
|
|
231
|
+
const bar = !global.json ? new ProgressBar(c.dim("embedding")) : void 0;
|
|
232
|
+
const vectors = await getNodeEmbeddings(graph, embedder, root3, bar ? (d, t) => bar.update(d, t) : void 0);
|
|
233
|
+
bar?.done();
|
|
234
|
+
result = await queryGraphSemantic(graph, q, { budget, embedder, nodeVectors: vectors, relevance, topicTags });
|
|
235
|
+
mode = `semantic (${embedder.id})`;
|
|
236
|
+
activity.add("answer", "ok", `answered in this process \xB7 ${embedder.id} \xB7 ${vectors.size} vector(s)`);
|
|
237
|
+
} else {
|
|
238
|
+
result = queryGraph(graph, q, { budget, relevance, topicTags });
|
|
239
|
+
note = reason ? unavailableMessage(reason) : "semantic unavailable; used lexical";
|
|
240
|
+
if (detail) note += ` (${detail})`;
|
|
241
|
+
activity.add("answer", "warn", `lexical only \u2014 ${note}`);
|
|
242
|
+
}
|
|
181
243
|
}
|
|
182
|
-
});
|
|
183
|
-
if (embedder) {
|
|
184
|
-
const bar = !global.json && firstRun ? new ProgressBar(c.dim("embedding")) : void 0;
|
|
185
|
-
const vectors = await getNodeEmbeddings(graph, embedder, root3, bar ? (d, t) => bar.update(d, t) : void 0);
|
|
186
|
-
bar?.done();
|
|
187
|
-
result = await queryGraphSemantic(graph, q, { budget, embedder, nodeVectors: vectors, relevance, topicTags });
|
|
188
|
-
mode = `semantic (${embedder.id})`;
|
|
189
244
|
} else {
|
|
190
245
|
result = queryGraph(graph, q, { budget, relevance, topicTags });
|
|
191
|
-
|
|
192
|
-
|
|
246
|
+
if (global.local) note = "semantic skipped under --local; used lexical";
|
|
247
|
+
activity.add("answer", "skip", global.local ? "lexical only (--local)" : "lexical only (--no-semantic)");
|
|
193
248
|
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if (global.local) note = "semantic skipped under --local; used lexical";
|
|
249
|
+
} finally {
|
|
250
|
+
live?.stop();
|
|
197
251
|
}
|
|
198
252
|
if (global.client) {
|
|
199
253
|
const files = new Set(result.matches.map((m) => m.node.file).filter(Boolean));
|
|
@@ -214,6 +268,7 @@ function registerAsk(program) {
|
|
|
214
268
|
question: result.question,
|
|
215
269
|
mode,
|
|
216
270
|
note: note || void 0,
|
|
271
|
+
activity: activity.toJSON(),
|
|
217
272
|
tokensEstimate: result.tokensEstimate,
|
|
218
273
|
matches: result.matches.map((m) => ({
|
|
219
274
|
name: m.node.qualifiedName,
|
|
@@ -231,9 +286,25 @@ function registerAsk(program) {
|
|
|
231
286
|
info("");
|
|
232
287
|
info(c.dim(`vg \xB7 ${result.matches.length} match(es) \xB7 ~${result.tokensEstimate} tokens (budget ${budget}) \xB7 ${mode}`));
|
|
233
288
|
if (note) info(c.yellow(` ${note}`));
|
|
289
|
+
for (const line of activity.render()) info(line);
|
|
234
290
|
});
|
|
235
291
|
applyGlobalOptions(cmd);
|
|
236
292
|
}
|
|
293
|
+
function describeAttach(a) {
|
|
294
|
+
if (a.status === "disabled") return { outcome: "skip", detail: `${a.reason} \u2014 running in this process` };
|
|
295
|
+
if (a.status === "unavailable") return { outcome: "skip", detail: `${a.reason} \u2014 running in this process` };
|
|
296
|
+
const started = a.started ? "started vgd" : "attached to vgd";
|
|
297
|
+
if (a.published?.status === "current") {
|
|
298
|
+
return { outcome: "ok", detail: `${started} \xB7 already holds this map (${a.published.gitRef})` };
|
|
299
|
+
}
|
|
300
|
+
if (a.published?.status === "published") {
|
|
301
|
+
return { outcome: "ok", detail: `${started} \xB7 map published ${a.published.gitRef} \xB7 ${a.published.nodeCount} nodes` };
|
|
302
|
+
}
|
|
303
|
+
if (a.published?.status === "failed") {
|
|
304
|
+
return { outcome: "warn", detail: `${started} \xB7 map not published (${a.published.error})` };
|
|
305
|
+
}
|
|
306
|
+
return { outcome: "ok", detail: started };
|
|
307
|
+
}
|
|
237
308
|
function crashedMessage(signal) {
|
|
238
309
|
const envPrefix = process.platform === "linux" ? "ONNXRUNTIME_NODE_INSTALL=skip " : "";
|
|
239
310
|
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 +318,7 @@ function verdictPath(dir) {
|
|
|
247
318
|
}
|
|
248
319
|
function readVerdict(dir) {
|
|
249
320
|
try {
|
|
250
|
-
const raw = JSON.parse(
|
|
321
|
+
const raw = JSON.parse(fs13.readFileSync(verdictPath(dir), "utf8"));
|
|
251
322
|
if (raw?.status !== "ok" && raw?.status !== "crashed") return null;
|
|
252
323
|
if (raw.version !== VERSION) return null;
|
|
253
324
|
return raw;
|
|
@@ -257,8 +328,8 @@ function readVerdict(dir) {
|
|
|
257
328
|
}
|
|
258
329
|
function writeVerdict(dir, verdict) {
|
|
259
330
|
try {
|
|
260
|
-
|
|
261
|
-
|
|
331
|
+
fs13.mkdirSync(dir, { recursive: true });
|
|
332
|
+
fs13.writeFileSync(verdictPath(dir), JSON.stringify(verdict, null, 2) + "\n", "utf8");
|
|
262
333
|
} catch {
|
|
263
334
|
}
|
|
264
335
|
}
|
|
@@ -266,7 +337,7 @@ function probeModuleUrl(from = import.meta.url) {
|
|
|
266
337
|
const dir = path46.dirname(fileURLToPath(from));
|
|
267
338
|
for (const name of ["embeddings.js", "index.js"]) {
|
|
268
339
|
const candidate = path46.join(dir, name);
|
|
269
|
-
if (
|
|
340
|
+
if (fs13.existsSync(candidate)) return pathToFileURL(candidate).href;
|
|
270
341
|
}
|
|
271
342
|
return pathToFileURL(path46.join(dir, "index.js")).href;
|
|
272
343
|
}
|
|
@@ -343,7 +414,7 @@ async function embedderHealth(options = {}) {
|
|
|
343
414
|
}
|
|
344
415
|
function clearEmbedderHealth(cacheDir2) {
|
|
345
416
|
try {
|
|
346
|
-
|
|
417
|
+
fs13.unlinkSync(verdictPath(cacheDir2 ?? defaultCacheDir()));
|
|
347
418
|
} catch {
|
|
348
419
|
}
|
|
349
420
|
}
|
|
@@ -370,6 +441,7 @@ function registerEmbed(program) {
|
|
|
370
441
|
return;
|
|
371
442
|
}
|
|
372
443
|
if (countPending(graph, root3, modelId) === 0) {
|
|
444
|
+
await warmDaemonIndex(root3, global.graph);
|
|
373
445
|
if (global.json) json({ embedded: 0, pending: 0, upToDate: true, model: modelId, semantic: true });
|
|
374
446
|
else if (speak) info(`${c.cyan("vg embed")} \xB7 semantic index already up to date`);
|
|
375
447
|
return;
|
|
@@ -406,11 +478,15 @@ function registerEmbed(program) {
|
|
|
406
478
|
const bar = speak ? new ProgressBar(c.dim("embedding")) : void 0;
|
|
407
479
|
await getNodeEmbeddings(graph, embedder, root3, bar ? (d, t) => bar.update(d, t) : void 0);
|
|
408
480
|
bar?.done();
|
|
481
|
+
await warmDaemonIndex(root3, global.graph);
|
|
409
482
|
if (global.json) json({ embedded: pending, model: modelId, semantic: true });
|
|
410
483
|
else if (speak) info(`${c.green("\u2714")} vg embed \xB7 semantic index ready (~${pending} node(s) \xB7 model ${modelId})`);
|
|
411
484
|
});
|
|
412
485
|
applyGlobalOptions(cmd);
|
|
413
486
|
}
|
|
487
|
+
async function warmDaemonIndex(root3, graphPath) {
|
|
488
|
+
await publishGraphToVgd(root3, { graphPath, warmSemantic: true });
|
|
489
|
+
}
|
|
414
490
|
function showWhere(root3, modelId, asJson) {
|
|
415
491
|
const m = modelCacheInfo(modelId);
|
|
416
492
|
const repoCached = embeddingsCached(root3, modelId);
|
|
@@ -1018,7 +1094,7 @@ function liveStatsDir(root3) {
|
|
|
1018
1094
|
function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid, signal) => process.kill(pid, signal), selfPid = process.pid) {
|
|
1019
1095
|
let entries;
|
|
1020
1096
|
try {
|
|
1021
|
-
entries =
|
|
1097
|
+
entries = fs13.readdirSync(dir);
|
|
1022
1098
|
} catch {
|
|
1023
1099
|
return [];
|
|
1024
1100
|
}
|
|
@@ -1027,7 +1103,7 @@ function reapOtherVersionServers(dir, keepVersion, now = Date.now(), kill = (pid
|
|
|
1027
1103
|
if (!/^serve-\d+\.json$/.test(name)) continue;
|
|
1028
1104
|
let parsed;
|
|
1029
1105
|
try {
|
|
1030
|
-
parsed = JSON.parse(
|
|
1106
|
+
parsed = JSON.parse(fs13.readFileSync(path46.join(dir, name), "utf8"));
|
|
1031
1107
|
} catch {
|
|
1032
1108
|
continue;
|
|
1033
1109
|
}
|
|
@@ -1081,10 +1157,10 @@ var LiveStatsBus = class {
|
|
|
1081
1157
|
this.lastWriteAt = now;
|
|
1082
1158
|
const body = { pid: this.pid, updatedAt: now, version: VERSION, snapshot: snap };
|
|
1083
1159
|
try {
|
|
1084
|
-
|
|
1160
|
+
fs13.mkdirSync(this.dir, { recursive: true });
|
|
1085
1161
|
const tmp = `${this.file}.tmp`;
|
|
1086
|
-
|
|
1087
|
-
|
|
1162
|
+
fs13.writeFileSync(tmp, JSON.stringify(body));
|
|
1163
|
+
fs13.renameSync(tmp, this.file);
|
|
1088
1164
|
} catch {
|
|
1089
1165
|
}
|
|
1090
1166
|
}
|
|
@@ -1095,7 +1171,7 @@ var LiveStatsBus = class {
|
|
|
1095
1171
|
siblings(now = Date.now()) {
|
|
1096
1172
|
let entries;
|
|
1097
1173
|
try {
|
|
1098
|
-
entries =
|
|
1174
|
+
entries = fs13.readdirSync(this.dir);
|
|
1099
1175
|
} catch {
|
|
1100
1176
|
return [];
|
|
1101
1177
|
}
|
|
@@ -1105,14 +1181,14 @@ var LiveStatsBus = class {
|
|
|
1105
1181
|
const file = path46.join(this.dir, name);
|
|
1106
1182
|
let parsed;
|
|
1107
1183
|
try {
|
|
1108
|
-
parsed = JSON.parse(
|
|
1184
|
+
parsed = JSON.parse(fs13.readFileSync(file, "utf8"));
|
|
1109
1185
|
} catch {
|
|
1110
1186
|
continue;
|
|
1111
1187
|
}
|
|
1112
1188
|
if (typeof parsed?.pid !== "number" || typeof parsed.updatedAt !== "number" || !parsed.snapshot?.totals) continue;
|
|
1113
1189
|
if (now - parsed.updatedAt > STALE_MS) {
|
|
1114
1190
|
try {
|
|
1115
|
-
|
|
1191
|
+
fs13.unlinkSync(file);
|
|
1116
1192
|
} catch {
|
|
1117
1193
|
}
|
|
1118
1194
|
continue;
|
|
@@ -1124,7 +1200,7 @@ var LiveStatsBus = class {
|
|
|
1124
1200
|
}
|
|
1125
1201
|
unlinkOwn = () => {
|
|
1126
1202
|
try {
|
|
1127
|
-
|
|
1203
|
+
fs13.unlinkSync(this.file);
|
|
1128
1204
|
} catch {
|
|
1129
1205
|
}
|
|
1130
1206
|
};
|
|
@@ -1437,12 +1513,12 @@ var LedgerTail = class {
|
|
|
1437
1513
|
if (size === this.offset) return;
|
|
1438
1514
|
let chunk;
|
|
1439
1515
|
try {
|
|
1440
|
-
const fd =
|
|
1516
|
+
const fd = fs13.openSync(this.file, "r");
|
|
1441
1517
|
try {
|
|
1442
1518
|
chunk = Buffer.alloc(size - this.offset);
|
|
1443
|
-
|
|
1519
|
+
fs13.readSync(fd, chunk, 0, chunk.length, this.offset);
|
|
1444
1520
|
} finally {
|
|
1445
|
-
|
|
1521
|
+
fs13.closeSync(fd);
|
|
1446
1522
|
}
|
|
1447
1523
|
} catch {
|
|
1448
1524
|
return;
|
|
@@ -1455,7 +1531,7 @@ var LedgerTail = class {
|
|
|
1455
1531
|
}
|
|
1456
1532
|
sizeOf() {
|
|
1457
1533
|
try {
|
|
1458
|
-
return
|
|
1534
|
+
return fs13.statSync(this.file).size;
|
|
1459
1535
|
} catch {
|
|
1460
1536
|
return 0;
|
|
1461
1537
|
}
|
|
@@ -1511,6 +1587,7 @@ function registerServe(program) {
|
|
|
1511
1587
|
dedup: opts.dedup === true,
|
|
1512
1588
|
refresh,
|
|
1513
1589
|
watch: opts.watch !== false,
|
|
1590
|
+
daemon: global.daemon,
|
|
1514
1591
|
root: root3,
|
|
1515
1592
|
stats,
|
|
1516
1593
|
// Listing surface: flags win over env; unknown values fall back to the
|
|
@@ -1745,171 +1822,26 @@ var Connection = class {
|
|
|
1745
1822
|
}
|
|
1746
1823
|
}
|
|
1747
1824
|
};
|
|
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";
|
|
1825
|
+
function projectDir(root3, projectPath) {
|
|
1826
|
+
const rel = projectPath === "" || projectPath === "." ? "" : projectPath;
|
|
1827
|
+
return rel ? path46.resolve(root3, rel) : path46.resolve(root3);
|
|
1766
1828
|
}
|
|
1767
|
-
function
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
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;
|
|
1815
|
-
}
|
|
1816
|
-
function findRuntimeLine(text, kind) {
|
|
1817
|
-
const lines = text.split(/\r?\n/);
|
|
1818
|
-
const patterns = (() => {
|
|
1819
|
-
switch (kind) {
|
|
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
|
-
}
|
|
1829
|
+
function projectForFile(root3, projects, filePath) {
|
|
1830
|
+
const dir = path46.dirname(path46.resolve(filePath));
|
|
1831
|
+
for (const proj of projects) {
|
|
1832
|
+
if (projectDir(root3, proj.path) === dir) return proj;
|
|
1842
1833
|
}
|
|
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 };
|
|
1834
|
+
if (isManifest(filePath)) return void 0;
|
|
1835
|
+
let best;
|
|
1836
|
+
let bestLen = -1;
|
|
1837
|
+
for (const proj of projects) {
|
|
1838
|
+
const projDir = projectDir(root3, proj.path);
|
|
1839
|
+
if ((dir === projDir || dir.startsWith(projDir + path46.sep)) && projDir.length > bestLen) {
|
|
1840
|
+
best = proj;
|
|
1841
|
+
bestLen = projDir.length;
|
|
1896
1842
|
}
|
|
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
1843
|
}
|
|
1844
|
+
return best;
|
|
1913
1845
|
}
|
|
1914
1846
|
var MAX_ENTRIES = 1e3;
|
|
1915
1847
|
var KEEP_ENTRIES = 500;
|
|
@@ -1928,7 +1860,7 @@ function parseLine(line) {
|
|
|
1928
1860
|
}
|
|
1929
1861
|
function readHistory(root3) {
|
|
1930
1862
|
try {
|
|
1931
|
-
return
|
|
1863
|
+
return fs13.readFileSync(historyPath(root3), "utf8").split("\n").filter((l) => l.trim()).map(parseLine).filter((e) => e !== null);
|
|
1932
1864
|
} catch {
|
|
1933
1865
|
return [];
|
|
1934
1866
|
}
|
|
@@ -1955,14 +1887,14 @@ function recordScore(root3, entry) {
|
|
|
1955
1887
|
}
|
|
1956
1888
|
}
|
|
1957
1889
|
const file = historyPath(root3);
|
|
1958
|
-
|
|
1890
|
+
fs13.mkdirSync(path46.dirname(file), { recursive: true });
|
|
1959
1891
|
ensureVibgrateGitignore(root3);
|
|
1960
|
-
|
|
1892
|
+
fs13.appendFileSync(file, `${JSON.stringify(entry)}
|
|
1961
1893
|
`);
|
|
1962
1894
|
const all = readHistory(root3);
|
|
1963
1895
|
if (all.length > MAX_ENTRIES) {
|
|
1964
1896
|
const kept = all.slice(-KEEP_ENTRIES);
|
|
1965
|
-
|
|
1897
|
+
fs13.writeFileSync(file, kept.map((e) => JSON.stringify(e)).join("\n") + "\n");
|
|
1966
1898
|
}
|
|
1967
1899
|
} catch {
|
|
1968
1900
|
}
|
|
@@ -1985,7 +1917,7 @@ function readIgnores(root3, now = Date.now()) {
|
|
|
1985
1917
|
const out2 = /* @__PURE__ */ new Map();
|
|
1986
1918
|
let raw;
|
|
1987
1919
|
try {
|
|
1988
|
-
raw =
|
|
1920
|
+
raw = fs13.readFileSync(ignoreFilePath(root3), "utf8");
|
|
1989
1921
|
} catch {
|
|
1990
1922
|
return out2;
|
|
1991
1923
|
}
|
|
@@ -2012,7 +1944,7 @@ function inventoryKey(projectPath, pkg) {
|
|
|
2012
1944
|
}
|
|
2013
1945
|
function readInventory(root3) {
|
|
2014
1946
|
try {
|
|
2015
|
-
const parsed = JSON.parse(
|
|
1947
|
+
const parsed = JSON.parse(fs13.readFileSync(inventoryPath(root3), "utf8"));
|
|
2016
1948
|
if (typeof parsed.ts === "string" && typeof parsed.methodology === "string" && Array.isArray(parsed.drifted) && parsed.drifted.every((d) => typeof d === "string")) {
|
|
2017
1949
|
return parsed;
|
|
2018
1950
|
}
|
|
@@ -2023,7 +1955,7 @@ function readInventory(root3) {
|
|
|
2023
1955
|
function recordInventory(root3, snap) {
|
|
2024
1956
|
try {
|
|
2025
1957
|
ensureVibgrateGitignore(root3);
|
|
2026
|
-
|
|
1958
|
+
fs13.writeFileSync(inventoryPath(root3), `${JSON.stringify(snap)}
|
|
2027
1959
|
`);
|
|
2028
1960
|
} catch {
|
|
2029
1961
|
}
|
|
@@ -2075,7 +2007,23 @@ async function runAsk(graph, params, ctx) {
|
|
|
2075
2007
|
let result = null;
|
|
2076
2008
|
let mode = "lexical";
|
|
2077
2009
|
let note;
|
|
2078
|
-
if (wantSemantic) {
|
|
2010
|
+
if (wantSemantic && ctx.semanticSession) {
|
|
2011
|
+
try {
|
|
2012
|
+
const ranked = await withTimeout(
|
|
2013
|
+
ctx.semanticSession.rank(question, graph.provenance?.corpusHash),
|
|
2014
|
+
semanticBudgetMs(),
|
|
2015
|
+
"daemon ranking over budget"
|
|
2016
|
+
);
|
|
2017
|
+
if (ranked) {
|
|
2018
|
+
log(`ask: ranked by vgd against ${ranked.vectors} vector(s) \u2014 no local model load`);
|
|
2019
|
+
result = await queryGraphSemantic(graph, question, { budget, semanticRanked: ranked.ranked });
|
|
2020
|
+
mode = `semantic (vgd${ranked.model ? `, ${ranked.model}` : ""})`;
|
|
2021
|
+
}
|
|
2022
|
+
} catch {
|
|
2023
|
+
log("ask: vgd ranking unavailable \u2014 trying the in-process semantic path");
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
if (wantSemantic && !result) {
|
|
2079
2027
|
const budgetMs = semanticBudgetMs();
|
|
2080
2028
|
log(`ask: trying the semantic path (budget ${Math.round(budgetMs / 1e3)}s)`);
|
|
2081
2029
|
let reason;
|
|
@@ -2556,7 +2504,11 @@ function architectureWire(arch) {
|
|
|
2556
2504
|
if (arch.workspaceEdgesCapped) out2.workspaceEdgesCapped = true;
|
|
2557
2505
|
if (arch.violations) out2.violations = arch.violations;
|
|
2558
2506
|
if (arch.violationsCapped) out2.violationsCapped = true;
|
|
2559
|
-
if (arch.boundaryProfile)
|
|
2507
|
+
if (arch.boundaryProfile) {
|
|
2508
|
+
out2.boundaryProfile = arch.boundaryProfile;
|
|
2509
|
+
const rules = boundaryProfileRules(arch.boundaryProfile);
|
|
2510
|
+
if (rules.length > 0) out2.boundaryRules = rules;
|
|
2511
|
+
}
|
|
2560
2512
|
if (arch.structure) out2.structure = arch.structure;
|
|
2561
2513
|
if (arch.generated) out2.generated = true;
|
|
2562
2514
|
if (arch.generatedBy) out2.generatedBy = arch.generatedBy;
|
|
@@ -2586,6 +2538,7 @@ var VibgrateLanguageServer = class {
|
|
|
2586
2538
|
constructor(opts, output = process.stdout) {
|
|
2587
2539
|
this.opts = opts;
|
|
2588
2540
|
this.conn = new Connection(process.stdin, output);
|
|
2541
|
+
this.semanticSession = new DaemonSemanticSession(opts.root, { disabled: opts.daemon === false });
|
|
2589
2542
|
this.refresher = new RefreshScheduler({
|
|
2590
2543
|
root: opts.root,
|
|
2591
2544
|
graphPath: () => resolveGraphPath(opts.root),
|
|
@@ -2623,6 +2576,32 @@ var VibgrateLanguageServer = class {
|
|
|
2623
2576
|
* single Ask block for over a minute. See engine/refresh-scheduler.ts.
|
|
2624
2577
|
*/
|
|
2625
2578
|
refresher;
|
|
2579
|
+
/**
|
|
2580
|
+
* Open while the daemon is pushing map changes for this workspace. Closing
|
|
2581
|
+
* it (or losing it) puts this server back in charge of its own freshness.
|
|
2582
|
+
*/
|
|
2583
|
+
slotSubscription = null;
|
|
2584
|
+
/**
|
|
2585
|
+
* True only while the daemon is confirmed to hold *this* map and to be
|
|
2586
|
+
* pushing changes for it. While set, `graphForQuery` stops probing: the
|
|
2587
|
+
* daemon already watches the tree and rebuilds, and two processes doing it
|
|
2588
|
+
* means two stat-walks over one corpus and two rebuilds racing for one lock.
|
|
2589
|
+
*
|
|
2590
|
+
* Never assumed — see `deferFreshnessToDaemon`. A daemon that dies degrades
|
|
2591
|
+
* this server to watching for itself, never to nothing watching.
|
|
2592
|
+
*/
|
|
2593
|
+
daemonOwnsFreshness = false;
|
|
2594
|
+
/**
|
|
2595
|
+
* The local runtime's semantic index, held for the life of the server.
|
|
2596
|
+
* Ranking there means the native embedding backend is never loaded into this
|
|
2597
|
+
* process — the failure this server has the least tolerance for, since a
|
|
2598
|
+
* SIGTRAP from the addon kills it outright mid-request.
|
|
2599
|
+
*/
|
|
2600
|
+
semanticSession;
|
|
2601
|
+
/** In-flight on-demand scans of open manifests the workspace scan skipped. */
|
|
2602
|
+
openManifestScans = /* @__PURE__ */ new Set();
|
|
2603
|
+
/** Failed on-demand scans — retry only after the next workspace scan. */
|
|
2604
|
+
openManifestFailed = /* @__PURE__ */ new Set();
|
|
2626
2605
|
register() {
|
|
2627
2606
|
this.conn.onRequest("initialize", () => ({
|
|
2628
2607
|
capabilities: {
|
|
@@ -2680,6 +2659,7 @@ var VibgrateLanguageServer = class {
|
|
|
2680
2659
|
this.conn.onRequest("vibgrate/score/forFile", (_m, params) => this.onScoreForFile(params));
|
|
2681
2660
|
this.conn.onRequest("vibgrate/score/forProject", (_m, params) => this.onScoreForProject(params));
|
|
2682
2661
|
this.conn.onRequest("vibgrate/architecture", (_m, params) => this.onArchitecture(params));
|
|
2662
|
+
this.conn.onRequest("vibgrate/architecture/projects", () => this.onArchitectureProjects());
|
|
2683
2663
|
this.conn.onRequest("vibgrate/score/history", (_m, params) => {
|
|
2684
2664
|
const p = params;
|
|
2685
2665
|
const days = typeof p?.days === "number" && p.days > 0 && p.days <= 365 ? p.days : 90;
|
|
@@ -2698,6 +2678,9 @@ var VibgrateLanguageServer = class {
|
|
|
2698
2678
|
this.conn.onRequest("shutdown", () => {
|
|
2699
2679
|
this.shuttingDown = true;
|
|
2700
2680
|
if (this.debounce) clearTimeout(this.debounce);
|
|
2681
|
+
this.slotSubscription?.close();
|
|
2682
|
+
this.slotSubscription = null;
|
|
2683
|
+
this.daemonOwnsFreshness = false;
|
|
2701
2684
|
return null;
|
|
2702
2685
|
});
|
|
2703
2686
|
this.conn.onNotification("exit", () => {
|
|
@@ -2718,8 +2701,13 @@ var VibgrateLanguageServer = class {
|
|
|
2718
2701
|
this.scanning = true;
|
|
2719
2702
|
const force = this.forceNextScan;
|
|
2720
2703
|
this.forceNextScan = false;
|
|
2704
|
+
this.openManifestFailed.clear();
|
|
2721
2705
|
try {
|
|
2722
|
-
const cacheKey = {
|
|
2706
|
+
const cacheKey = {
|
|
2707
|
+
manifestHash: await this.sharedManifestHash() ?? manifestHash(this.opts.root),
|
|
2708
|
+
toolVersion: VERSION,
|
|
2709
|
+
offline: this.opts.offline
|
|
2710
|
+
};
|
|
2723
2711
|
const cached2 = force ? null : loadScanCache(this.opts.root, cacheKey);
|
|
2724
2712
|
let fromCache = false;
|
|
2725
2713
|
if (cached2) {
|
|
@@ -2845,7 +2833,10 @@ var VibgrateLanguageServer = class {
|
|
|
2845
2833
|
if (!a || text === void 0) return;
|
|
2846
2834
|
const filePath = uriToPath(uri);
|
|
2847
2835
|
const kind = manifestKind(filePath);
|
|
2848
|
-
const project =
|
|
2836
|
+
const project = projectForFile2(this.opts.root, a, filePath);
|
|
2837
|
+
if (!project && isManifest(filePath)) {
|
|
2838
|
+
void this.scanOpenManifest(uri, filePath);
|
|
2839
|
+
}
|
|
2849
2840
|
const items = [];
|
|
2850
2841
|
for (const dep of project?.dependencies ?? []) {
|
|
2851
2842
|
if (dep.drift === "current" || dep.drift === "unknown") continue;
|
|
@@ -2890,6 +2881,58 @@ var VibgrateLanguageServer = class {
|
|
|
2890
2881
|
});
|
|
2891
2882
|
this.conn.notify("textDocument/publishDiagnostics", { uri, diagnostics });
|
|
2892
2883
|
}
|
|
2884
|
+
/**
|
|
2885
|
+
* Workspace scan skipped this package (auto-exclude / timeout). Score it
|
|
2886
|
+
* alone so the open editor can show overlays; do not write the result into
|
|
2887
|
+
* the workspace scan cache (billing / repo score stay on the official scan).
|
|
2888
|
+
*/
|
|
2889
|
+
async scanOpenManifest(uri, filePath) {
|
|
2890
|
+
const relDir = path46.relative(this.opts.root, path46.dirname(path46.resolve(filePath)));
|
|
2891
|
+
const key2 = relDir === "" ? "." : relDir;
|
|
2892
|
+
if (this.openManifestScans.has(key2) || this.openManifestFailed.has(key2)) return;
|
|
2893
|
+
if (key2 === "." || key2.startsWith("..")) return;
|
|
2894
|
+
this.openManifestScans.add(key2);
|
|
2895
|
+
try {
|
|
2896
|
+
this.conn.notify("window/logMessage", {
|
|
2897
|
+
type: 3,
|
|
2898
|
+
message: `Vibgrate: scoring open package ${key2} (not in the workspace scan) so editor overlays can render.`
|
|
2899
|
+
});
|
|
2900
|
+
const advanced = await loadAdvancedScanHook();
|
|
2901
|
+
const scanOpts = {
|
|
2902
|
+
format: "json",
|
|
2903
|
+
concurrency: 8,
|
|
2904
|
+
offline: this.opts.offline,
|
|
2905
|
+
noLocalArtifacts: true,
|
|
2906
|
+
noGraph: true,
|
|
2907
|
+
quiet: true,
|
|
2908
|
+
vibgrateVersion: VERSION
|
|
2909
|
+
};
|
|
2910
|
+
const sub = await runCoreScanSilently(path46.dirname(filePath), scanOpts, advanced);
|
|
2911
|
+
const proj = (sub.projects ?? []).find((p) => p.path === "." || p.path === "") ?? sub.projects?.[0];
|
|
2912
|
+
if (!proj || !this.artifact) {
|
|
2913
|
+
this.openManifestFailed.add(key2);
|
|
2914
|
+
return;
|
|
2915
|
+
}
|
|
2916
|
+
proj.path = key2;
|
|
2917
|
+
this.artifact.projects = [...(this.artifact.projects ?? []).filter((p) => p.path !== key2), proj];
|
|
2918
|
+
for (const f of sub.findings ?? []) {
|
|
2919
|
+
if (f.location === "." || f.location === "" || f.location === key2) {
|
|
2920
|
+
this.artifact.findings = [...(this.artifact.findings ?? []).filter((x) => !(x.ruleId === f.ruleId && x.location === key2)), { ...f, location: key2 }];
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
this.publishScore();
|
|
2924
|
+
this.publishForDoc(uri);
|
|
2925
|
+
} catch (err) {
|
|
2926
|
+
this.openManifestFailed.add(key2);
|
|
2927
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2928
|
+
this.conn.notify("window/logMessage", {
|
|
2929
|
+
type: 3,
|
|
2930
|
+
message: `Vibgrate: could not score open package ${key2}: ${message}`
|
|
2931
|
+
});
|
|
2932
|
+
} finally {
|
|
2933
|
+
this.openManifestScans.delete(key2);
|
|
2934
|
+
}
|
|
2935
|
+
}
|
|
2893
2936
|
// ── Requests ─────────────────────────────────────────────────────────────
|
|
2894
2937
|
onHover(params) {
|
|
2895
2938
|
const p = params;
|
|
@@ -2900,7 +2943,7 @@ var VibgrateLanguageServer = class {
|
|
|
2900
2943
|
if (!uri || line === void 0 || !a || text === void 0) return null;
|
|
2901
2944
|
const filePath = uriToPath(uri);
|
|
2902
2945
|
const kind = manifestKind(filePath);
|
|
2903
|
-
const project =
|
|
2946
|
+
const project = projectForFile2(this.opts.root, a, filePath);
|
|
2904
2947
|
const dep = (project?.dependencies ?? []).find(
|
|
2905
2948
|
(d) => findPackageLine(text, d.package, kind) === line
|
|
2906
2949
|
);
|
|
@@ -2923,18 +2966,31 @@ var VibgrateLanguageServer = class {
|
|
|
2923
2966
|
const uri = p.textDocument?.uri;
|
|
2924
2967
|
const a = this.artifact;
|
|
2925
2968
|
if (!uri || !a || !this.docs.has(uri)) return [];
|
|
2926
|
-
const
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2969
|
+
const filePath = uriToPath(uri);
|
|
2970
|
+
const project = projectForFile2(this.opts.root, a, filePath);
|
|
2971
|
+
if (!project) {
|
|
2972
|
+
return [
|
|
2973
|
+
{
|
|
2974
|
+
range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } },
|
|
2975
|
+
command: {
|
|
2976
|
+
title: "Vibgrate \xB7 this package is not in the workspace scan",
|
|
2977
|
+
command: "vibgrate.openPanel",
|
|
2978
|
+
arguments: []
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
];
|
|
2982
|
+
}
|
|
2983
|
+
const behind = (project.dependencies ?? []).filter(
|
|
2984
|
+
(d) => d.drift === "major-behind" || d.drift === "minor-behind"
|
|
2985
|
+
).length;
|
|
2932
2986
|
const eol = (a.findings ?? []).filter(
|
|
2933
|
-
(f) => f.ruleId === "vibgrate/runtime-eol" || f.ruleId === "vibgrate/eol"
|
|
2987
|
+
(f) => sameProject(f.location, project.path) && (f.ruleId === "vibgrate/runtime-eol" || f.ruleId === "vibgrate/eol")
|
|
2934
2988
|
).length;
|
|
2935
|
-
const estimated = (a.drift.mode ?? (hasReleaseDates(a) ? "verified" : "estimated")) === "estimated";
|
|
2989
|
+
const estimated = (project.drift?.mode ?? a.drift.mode ?? (hasReleaseDates(a) ? "verified" : "estimated")) === "estimated";
|
|
2936
2990
|
const mode = estimated ? "~" : "";
|
|
2937
|
-
const
|
|
2991
|
+
const score = project.drift?.score ?? a.drift.score;
|
|
2992
|
+
const band = project.drift?.riskLevel ?? a.drift.riskLevel;
|
|
2993
|
+
const title = `Vibgrate \xB7 drift ${mode}${score} (${band}) \xB7 ${behind} behind \xB7 ${eol} EOL`;
|
|
2938
2994
|
return [
|
|
2939
2995
|
{
|
|
2940
2996
|
range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } },
|
|
@@ -2963,6 +3019,7 @@ var VibgrateLanguageServer = class {
|
|
|
2963
3019
|
this.fileRoles = fileRolesFromParseCache(this.opts.root);
|
|
2964
3020
|
this.refineAndPublishArchitecture();
|
|
2965
3021
|
this.conn.notify("vibgrate/graph/status", { state: "ready" });
|
|
3022
|
+
void this.deferFreshnessToDaemon();
|
|
2966
3023
|
return;
|
|
2967
3024
|
}
|
|
2968
3025
|
this.conn.notify("vibgrate/graph/status", { state: "building" });
|
|
@@ -2973,6 +3030,7 @@ var VibgrateLanguageServer = class {
|
|
|
2973
3030
|
this.fileRoles = result.fileRoles;
|
|
2974
3031
|
this.refineAndPublishArchitecture();
|
|
2975
3032
|
this.conn.notify("vibgrate/graph/status", { state: "ready" });
|
|
3033
|
+
void this.deferFreshnessToDaemon();
|
|
2976
3034
|
} catch (err) {
|
|
2977
3035
|
const message = err instanceof Error ? err.message : String(err);
|
|
2978
3036
|
this.conn.notify("window/logMessage", { type: 3, message: `Vibgrate graph build failed: ${message}` });
|
|
@@ -2981,6 +3039,55 @@ var VibgrateLanguageServer = class {
|
|
|
2981
3039
|
this.graphBuilding = false;
|
|
2982
3040
|
}
|
|
2983
3041
|
}
|
|
3042
|
+
/**
|
|
3043
|
+
* Hand freshness to the daemon, but only once it is actually holding this
|
|
3044
|
+
* map and pushing changes for it.
|
|
3045
|
+
*
|
|
3046
|
+
* The daemon watches a repository the moment it holds its slot — and not
|
|
3047
|
+
* before. Registration is not enough; this server has historically been one
|
|
3048
|
+
* of the roots vgd knew about but never had a map for. So the order matters:
|
|
3049
|
+
* publish the map we just loaded or built, take the repository id the daemon
|
|
3050
|
+
* answers with, and subscribe to *that* repository. Only a confirmed
|
|
3051
|
+
* subscription retires the local probe.
|
|
3052
|
+
*
|
|
3053
|
+
* Every failure mode lands on "keep watching for ourselves": no daemon, a
|
|
3054
|
+
* daemon that will not take the map, a subscription it does not confirm, or
|
|
3055
|
+
* a connection that later drops. None of them are errors — a machine with no
|
|
3056
|
+
* vgd is a supported configuration.
|
|
3057
|
+
*/
|
|
3058
|
+
async deferFreshnessToDaemon() {
|
|
3059
|
+
if (this.opts.daemon === false || !this.opts.graph) return;
|
|
3060
|
+
if (this.daemonOwnsFreshness || this.slotSubscription || this.shuttingDown) return;
|
|
3061
|
+
try {
|
|
3062
|
+
const [{ publishGraphToVgd: publishGraphToVgd2 }, { subscribeToSlots }] = await Promise.all([
|
|
3063
|
+
import('./publish-7YHRTBRA.js'),
|
|
3064
|
+
import('./slot-subscription-25GOARW5.js')
|
|
3065
|
+
]);
|
|
3066
|
+
const published = await publishGraphToVgd2(this.opts.root);
|
|
3067
|
+
if (published.status !== "published" && published.status !== "current") return;
|
|
3068
|
+
const { repositoryId } = published;
|
|
3069
|
+
const subscription = await subscribeToSlots({
|
|
3070
|
+
repositoryId,
|
|
3071
|
+
onChange: () => this.reloadGraphFromDisk(),
|
|
3072
|
+
onDetach: () => {
|
|
3073
|
+
this.daemonOwnsFreshness = false;
|
|
3074
|
+
this.slotSubscription = null;
|
|
3075
|
+
}
|
|
3076
|
+
});
|
|
3077
|
+
if (!subscription.active) return;
|
|
3078
|
+
if (this.shuttingDown) {
|
|
3079
|
+
subscription.close();
|
|
3080
|
+
return;
|
|
3081
|
+
}
|
|
3082
|
+
this.slotSubscription = subscription;
|
|
3083
|
+
this.daemonOwnsFreshness = true;
|
|
3084
|
+
this.conn.notify("window/logMessage", {
|
|
3085
|
+
type: 3,
|
|
3086
|
+
message: `Vibgrate graph: freshness deferred to the local runtime (${repositoryId}).`
|
|
3087
|
+
});
|
|
3088
|
+
} catch {
|
|
3089
|
+
}
|
|
3090
|
+
}
|
|
2984
3091
|
/**
|
|
2985
3092
|
* The graph for a query. The first call still builds the map (there is
|
|
2986
3093
|
* nothing to answer from otherwise), but a *refresh* is only ever kicked off
|
|
@@ -2991,7 +3098,7 @@ var VibgrateLanguageServer = class {
|
|
|
2991
3098
|
async graphForQuery() {
|
|
2992
3099
|
await this.ensureGraph();
|
|
2993
3100
|
if (!this.graph) return null;
|
|
2994
|
-
await this.refresher.maybeRefresh();
|
|
3101
|
+
if (!this.daemonOwnsFreshness) await this.refresher.maybeRefresh();
|
|
2995
3102
|
return this.graph;
|
|
2996
3103
|
}
|
|
2997
3104
|
/**
|
|
@@ -3001,13 +3108,20 @@ var VibgrateLanguageServer = class {
|
|
|
3001
3108
|
*/
|
|
3002
3109
|
onRefreshSettled(outcome) {
|
|
3003
3110
|
if (outcome?.status !== "refreshed" || !outcome.wrote) return;
|
|
3111
|
+
this.reloadGraphFromDisk();
|
|
3112
|
+
}
|
|
3113
|
+
/**
|
|
3114
|
+
* Re-read the map we already have on disk. Shared by the local refresher and
|
|
3115
|
+
* by the daemon's `slot-changed` push, which are the only two things that
|
|
3116
|
+
* ever rewrite it — and never both at once.
|
|
3117
|
+
*/
|
|
3118
|
+
reloadGraphFromDisk() {
|
|
3004
3119
|
const graphPath = resolveGraphPath(this.opts.root);
|
|
3005
3120
|
const reloaded = loadGraphPreferIndex(this.opts.root, graphPath)?.graph ?? loadGraph(this.opts.root);
|
|
3006
|
-
if (reloaded)
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
}
|
|
3121
|
+
if (!reloaded) return;
|
|
3122
|
+
this.graph = reloaded;
|
|
3123
|
+
this.fileRoles = fileRolesFromParseCache(this.opts.root);
|
|
3124
|
+
this.refineAndPublishArchitecture();
|
|
3011
3125
|
}
|
|
3012
3126
|
/**
|
|
3013
3127
|
* Graph / AST-role refine can land after the first `publishScore()`. The
|
|
@@ -3040,9 +3154,23 @@ var VibgrateLanguageServer = class {
|
|
|
3040
3154
|
root: this.opts.root,
|
|
3041
3155
|
offline: this.opts.offline,
|
|
3042
3156
|
semantic: this.opts.semantic,
|
|
3157
|
+
semanticSession: this.semanticSession,
|
|
3043
3158
|
log: trace
|
|
3044
3159
|
});
|
|
3045
3160
|
}
|
|
3161
|
+
/**
|
|
3162
|
+
* The daemon's manifest digest for this workspace, or null when there is no
|
|
3163
|
+
* daemon (or it has not been told about this repo yet) — in which case the
|
|
3164
|
+
* caller computes it locally, exactly as before.
|
|
3165
|
+
*/
|
|
3166
|
+
async sharedManifestHash() {
|
|
3167
|
+
try {
|
|
3168
|
+
const deps = await this.semanticSession.depContext();
|
|
3169
|
+
return deps?.manifestHash ?? null;
|
|
3170
|
+
} catch {
|
|
3171
|
+
return null;
|
|
3172
|
+
}
|
|
3173
|
+
}
|
|
3046
3174
|
/**
|
|
3047
3175
|
* `vibgrate/enrich` — lazy vulnerability enrichment for one expanded package,
|
|
3048
3176
|
* straight from OSV.dev (never our API). Honours the server's offline flag.
|
|
@@ -3090,7 +3218,7 @@ var VibgrateLanguageServer = class {
|
|
|
3090
3218
|
const absManifest = path46.resolve(this.opts.root, relManifest);
|
|
3091
3219
|
let text = null;
|
|
3092
3220
|
try {
|
|
3093
|
-
if (
|
|
3221
|
+
if (fs13.existsSync(absManifest)) text = fs13.readFileSync(absManifest, "utf8");
|
|
3094
3222
|
} catch {
|
|
3095
3223
|
text = null;
|
|
3096
3224
|
}
|
|
@@ -3140,7 +3268,7 @@ var VibgrateLanguageServer = class {
|
|
|
3140
3268
|
const p = params;
|
|
3141
3269
|
const a = this.artifact;
|
|
3142
3270
|
if (!a || !p.uri) return null;
|
|
3143
|
-
const project =
|
|
3271
|
+
const project = projectForFile2(this.opts.root, a, uriToPath(p.uri));
|
|
3144
3272
|
return project ? scoreForProject(this.opts.root, a, project) : null;
|
|
3145
3273
|
}
|
|
3146
3274
|
/**
|
|
@@ -3181,6 +3309,37 @@ var VibgrateLanguageServer = class {
|
|
|
3181
3309
|
lockfilePath: lockfileRelativePath(this.opts.root, project)
|
|
3182
3310
|
};
|
|
3183
3311
|
}
|
|
3312
|
+
/**
|
|
3313
|
+
* `vibgrate/architecture/projects` — the workspace-scope Projects view.
|
|
3314
|
+
* One row per scanned project that produced architecture data, so a client
|
|
3315
|
+
* can render the whole portfolio without N round trips. Projects the
|
|
3316
|
+
* scanner never classified are omitted rather than shown as empty rows.
|
|
3317
|
+
*/
|
|
3318
|
+
onArchitectureProjects() {
|
|
3319
|
+
const a = this.artifact;
|
|
3320
|
+
if (!a) return null;
|
|
3321
|
+
const rows = [];
|
|
3322
|
+
for (const project of a.projects ?? []) {
|
|
3323
|
+
const arch = project.architecture;
|
|
3324
|
+
if (!arch) continue;
|
|
3325
|
+
const row = {
|
|
3326
|
+
path: project.path,
|
|
3327
|
+
name: project.name,
|
|
3328
|
+
// `violations` absent means "no graph was available to check against",
|
|
3329
|
+
// which is not the same as "checked and clean" — keep them distinct.
|
|
3330
|
+
violations: arch.violations ? arch.violations.length : null,
|
|
3331
|
+
layerCount: arch.layers.filter((l) => l.fileCount > 0).length,
|
|
3332
|
+
fileCount: arch.totalClassified
|
|
3333
|
+
};
|
|
3334
|
+
if (arch.projectKind) row.projectKind = arch.projectKind;
|
|
3335
|
+
if (arch.artifactKind) row.artifactKind = arch.artifactKind;
|
|
3336
|
+
if (arch.structure) row.structure = arch.structure.primary;
|
|
3337
|
+
if (arch.supportLevel !== void 0) row.supportLevel = arch.supportLevel;
|
|
3338
|
+
if (arch.packIds && arch.packIds.length > 0) row.packIds = arch.packIds;
|
|
3339
|
+
rows.push(row);
|
|
3340
|
+
}
|
|
3341
|
+
return rows;
|
|
3342
|
+
}
|
|
3184
3343
|
};
|
|
3185
3344
|
function uriToPath(uri) {
|
|
3186
3345
|
try {
|
|
@@ -3292,18 +3451,8 @@ function buildProjectRefs(rootDir, projects) {
|
|
|
3292
3451
|
refs.sort((a, b) => a.path.localeCompare(b.path));
|
|
3293
3452
|
return refs.length > 0 ? refs : void 0;
|
|
3294
3453
|
}
|
|
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;
|
|
3454
|
+
function projectForFile2(root3, a, filePath) {
|
|
3455
|
+
return projectForFile(root3, a.projects ?? [], filePath);
|
|
3307
3456
|
}
|
|
3308
3457
|
function sameProject(location, projectPath) {
|
|
3309
3458
|
return path46.normalize(location) === path46.normalize(projectPath);
|
|
@@ -3379,7 +3528,7 @@ function buildBreakdown(rootDir, projects) {
|
|
|
3379
3528
|
const absManifest = path46.resolve(rootDir, relManifest);
|
|
3380
3529
|
let text = null;
|
|
3381
3530
|
try {
|
|
3382
|
-
if (
|
|
3531
|
+
if (fs13.existsSync(absManifest)) text = fs13.readFileSync(absManifest, "utf8");
|
|
3383
3532
|
} catch {
|
|
3384
3533
|
text = null;
|
|
3385
3534
|
}
|
|
@@ -3444,34 +3593,34 @@ function buildBreakdown(rootDir, projects) {
|
|
|
3444
3593
|
}
|
|
3445
3594
|
function manifestRelativePath(proj) {
|
|
3446
3595
|
const base = proj.path === "." || proj.path === "" ? "" : proj.path;
|
|
3447
|
-
const
|
|
3596
|
+
const join35 = (name) => base ? path46.join(base, name) : name;
|
|
3448
3597
|
switch (proj.type) {
|
|
3449
3598
|
case "node":
|
|
3450
3599
|
case "typescript":
|
|
3451
|
-
return
|
|
3600
|
+
return join35("package.json");
|
|
3452
3601
|
case "python":
|
|
3453
|
-
return
|
|
3602
|
+
return join35("pyproject.toml");
|
|
3454
3603
|
case "go":
|
|
3455
|
-
return
|
|
3604
|
+
return join35("go.mod");
|
|
3456
3605
|
case "rust":
|
|
3457
|
-
return
|
|
3606
|
+
return join35("Cargo.toml");
|
|
3458
3607
|
case "ruby":
|
|
3459
|
-
return
|
|
3608
|
+
return join35("Gemfile");
|
|
3460
3609
|
case "php":
|
|
3461
|
-
return
|
|
3610
|
+
return join35("composer.json");
|
|
3462
3611
|
case "java":
|
|
3463
3612
|
case "kotlin":
|
|
3464
3613
|
case "scala":
|
|
3465
3614
|
case "groovy":
|
|
3466
|
-
return
|
|
3615
|
+
return join35("pom.xml");
|
|
3467
3616
|
case "dotnet":
|
|
3468
|
-
return
|
|
3617
|
+
return join35(proj.name ? `${proj.name}.csproj` : "Directory.Build.props");
|
|
3469
3618
|
case "dart":
|
|
3470
|
-
return
|
|
3619
|
+
return join35("pubspec.yaml");
|
|
3471
3620
|
case "elixir":
|
|
3472
|
-
return
|
|
3621
|
+
return join35("mix.exs");
|
|
3473
3622
|
default:
|
|
3474
|
-
return
|
|
3623
|
+
return join35("package.json");
|
|
3475
3624
|
}
|
|
3476
3625
|
}
|
|
3477
3626
|
function lockfileRelativePath(rootDir, proj) {
|
|
@@ -3504,7 +3653,7 @@ function lockfileRelativePath(rootDir, proj) {
|
|
|
3504
3653
|
for (const name of candidateNames) {
|
|
3505
3654
|
const rel = dir ? path46.join(dir, name) : name;
|
|
3506
3655
|
try {
|
|
3507
|
-
if (
|
|
3656
|
+
if (fs13.existsSync(path46.join(rootDir, rel))) return rel;
|
|
3508
3657
|
} catch {
|
|
3509
3658
|
}
|
|
3510
3659
|
}
|
|
@@ -3576,9 +3725,9 @@ function lookupImportFiles(map, pkg) {
|
|
|
3576
3725
|
function firstPackageMentionLine(root3, relFile, pkg) {
|
|
3577
3726
|
try {
|
|
3578
3727
|
const abs = path46.resolve(root3, relFile);
|
|
3579
|
-
const stat2 =
|
|
3728
|
+
const stat2 = fs13.statSync(abs);
|
|
3580
3729
|
if (!stat2.isFile() || stat2.size > 256 * 1024) return null;
|
|
3581
|
-
const text =
|
|
3730
|
+
const text = fs13.readFileSync(abs, "utf8");
|
|
3582
3731
|
const tokens = [pkg];
|
|
3583
3732
|
if (pkg.startsWith("@")) {
|
|
3584
3733
|
const parts = pkg.split("/");
|
|
@@ -3774,7 +3923,7 @@ function hoverMarkdown(dep, contribution, state) {
|
|
|
3774
3923
|
return lines.join("\n");
|
|
3775
3924
|
}
|
|
3776
3925
|
function startLanguageServer(opts) {
|
|
3777
|
-
if (!
|
|
3926
|
+
if (!fs13.existsSync(opts.root)) {
|
|
3778
3927
|
process.stderr.write(`vg lsp: root does not exist: ${opts.root}
|
|
3779
3928
|
`);
|
|
3780
3929
|
process.exit(1);
|
|
@@ -3809,7 +3958,8 @@ function registerLsp(program) {
|
|
|
3809
3958
|
offline: global.local === true,
|
|
3810
3959
|
diagnostics: opts.diagnostics === true,
|
|
3811
3960
|
graph: opts.graph !== false,
|
|
3812
|
-
semantic: opts.semantic !== false
|
|
3961
|
+
semantic: opts.semantic !== false,
|
|
3962
|
+
daemon: global.daemon
|
|
3813
3963
|
});
|
|
3814
3964
|
await new Promise(() => {
|
|
3815
3965
|
});
|
|
@@ -3826,9 +3976,9 @@ function installClaudeHooks(root3, vgBin = "vg") {
|
|
|
3826
3976
|
const file = path46.join(root3, ".claude", "settings.json");
|
|
3827
3977
|
const rel = path46.join(".claude", "settings.json");
|
|
3828
3978
|
let settings = {};
|
|
3829
|
-
if (
|
|
3979
|
+
if (fs13.existsSync(file)) {
|
|
3830
3980
|
try {
|
|
3831
|
-
const parsed = JSON.parse(
|
|
3981
|
+
const parsed = JSON.parse(fs13.readFileSync(file, "utf8"));
|
|
3832
3982
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
3833
3983
|
return { file: rel, status: "skipped", note: "settings.json is not a JSON object \u2014 left untouched" };
|
|
3834
3984
|
}
|
|
@@ -3867,10 +4017,10 @@ function installClaudeHooks(root3, vgBin = "vg") {
|
|
|
3867
4017
|
function uninstallClaudeHooks(root3) {
|
|
3868
4018
|
const file = path46.join(root3, ".claude", "settings.json");
|
|
3869
4019
|
const rel = path46.join(".claude", "settings.json");
|
|
3870
|
-
if (!
|
|
4020
|
+
if (!fs13.existsSync(file)) return { file: rel, status: "unchanged" };
|
|
3871
4021
|
let settings;
|
|
3872
4022
|
try {
|
|
3873
|
-
settings = JSON.parse(
|
|
4023
|
+
settings = JSON.parse(fs13.readFileSync(file, "utf8"));
|
|
3874
4024
|
} catch {
|
|
3875
4025
|
return { file: rel, status: "skipped", note: "settings.json is not parseable JSON \u2014 left untouched" };
|
|
3876
4026
|
}
|
|
@@ -3892,8 +4042,8 @@ function uninstallClaudeHooks(root3) {
|
|
|
3892
4042
|
return { file: rel, status: "written" };
|
|
3893
4043
|
}
|
|
3894
4044
|
function writeSettings(file, settings) {
|
|
3895
|
-
|
|
3896
|
-
|
|
4045
|
+
fs13.mkdirSync(path46.dirname(file), { recursive: true });
|
|
4046
|
+
fs13.writeFileSync(file, `${JSON.stringify(settings, null, 2)}
|
|
3897
4047
|
`);
|
|
3898
4048
|
}
|
|
3899
4049
|
|
|
@@ -4020,15 +4170,15 @@ function stateFile() {
|
|
|
4020
4170
|
}
|
|
4021
4171
|
function readConsent() {
|
|
4022
4172
|
try {
|
|
4023
|
-
return JSON.parse(
|
|
4173
|
+
return JSON.parse(fs13.readFileSync(stateFile(), "utf8"));
|
|
4024
4174
|
} catch {
|
|
4025
4175
|
return {};
|
|
4026
4176
|
}
|
|
4027
4177
|
}
|
|
4028
4178
|
function writeConsent(state) {
|
|
4029
4179
|
try {
|
|
4030
|
-
|
|
4031
|
-
|
|
4180
|
+
fs13.mkdirSync(path46.dirname(stateFile()), { recursive: true });
|
|
4181
|
+
fs13.writeFileSync(stateFile(), JSON.stringify(state));
|
|
4032
4182
|
} catch {
|
|
4033
4183
|
}
|
|
4034
4184
|
}
|
|
@@ -4038,8 +4188,8 @@ function kernelDisabled() {
|
|
|
4038
4188
|
}
|
|
4039
4189
|
function moduleInstalledAt(dir) {
|
|
4040
4190
|
try {
|
|
4041
|
-
const meta = JSON.parse(
|
|
4042
|
-
if (
|
|
4191
|
+
const meta = JSON.parse(fs13.readFileSync(path46.join(dir, ".module.json"), "utf8"));
|
|
4192
|
+
if (fs13.existsSync(path46.join(dir, "index.js"))) {
|
|
4043
4193
|
return { installed: true, version: meta.version };
|
|
4044
4194
|
}
|
|
4045
4195
|
} catch {
|
|
@@ -4113,8 +4263,8 @@ async function installModule(mod, opts = {}) {
|
|
|
4113
4263
|
verifyIntegrity(gz, dist.integrity, dist.shasum);
|
|
4114
4264
|
const entries = untar(zlib.gunzipSync(gz));
|
|
4115
4265
|
const dir = mod.dir();
|
|
4116
|
-
|
|
4117
|
-
|
|
4266
|
+
fs13.rmSync(dir, { recursive: true, force: true });
|
|
4267
|
+
fs13.mkdirSync(dir, { recursive: true });
|
|
4118
4268
|
let wrote = 0;
|
|
4119
4269
|
for (const e of entries) {
|
|
4120
4270
|
let rel = null;
|
|
@@ -4123,15 +4273,15 @@ async function installModule(mod, opts = {}) {
|
|
|
4123
4273
|
if (!rel) continue;
|
|
4124
4274
|
const target = path46.join(dir, rel);
|
|
4125
4275
|
if (!target.startsWith(dir + path46.sep) && target !== dir) throw new Error(`unsafe extract path: ${rel}`);
|
|
4126
|
-
|
|
4127
|
-
|
|
4276
|
+
fs13.mkdirSync(path46.dirname(target), { recursive: true });
|
|
4277
|
+
fs13.writeFileSync(target, e.body);
|
|
4128
4278
|
wrote += 1;
|
|
4129
4279
|
}
|
|
4130
|
-
if (!wrote || !
|
|
4131
|
-
|
|
4280
|
+
if (!wrote || !fs13.existsSync(path46.join(dir, "index.js"))) {
|
|
4281
|
+
fs13.rmSync(dir, { recursive: true, force: true });
|
|
4132
4282
|
return { status: "unavailable", detail: "package layout not recognized (no dist/index.js)" };
|
|
4133
4283
|
}
|
|
4134
|
-
|
|
4284
|
+
fs13.writeFileSync(path46.join(dir, ".module.json"), JSON.stringify({ name: mod.npmName, version }));
|
|
4135
4285
|
mod.onChanged?.();
|
|
4136
4286
|
return { status: "installed", version };
|
|
4137
4287
|
} catch (e) {
|
|
@@ -4139,7 +4289,7 @@ async function installModule(mod, opts = {}) {
|
|
|
4139
4289
|
}
|
|
4140
4290
|
}
|
|
4141
4291
|
function removeModule(mod) {
|
|
4142
|
-
|
|
4292
|
+
fs13.rmSync(mod.dir(), { recursive: true, force: true });
|
|
4143
4293
|
mod.onChanged?.();
|
|
4144
4294
|
}
|
|
4145
4295
|
|
|
@@ -4184,7 +4334,7 @@ function candidatePaths() {
|
|
|
4184
4334
|
if (custom) {
|
|
4185
4335
|
const p = path46.resolve(custom);
|
|
4186
4336
|
try {
|
|
4187
|
-
if (
|
|
4337
|
+
if (fs13.statSync(p).isDirectory()) return [path46.join(p, "index.js")];
|
|
4188
4338
|
} catch {
|
|
4189
4339
|
}
|
|
4190
4340
|
return [p];
|
|
@@ -4200,7 +4350,7 @@ async function loadHcsEngine() {
|
|
|
4200
4350
|
cached = null;
|
|
4201
4351
|
if (disabled()) return cached;
|
|
4202
4352
|
for (const p of candidatePaths()) {
|
|
4203
|
-
if (!
|
|
4353
|
+
if (!fs13.existsSync(p)) continue;
|
|
4204
4354
|
try {
|
|
4205
4355
|
const mod = await import(pathToFileURL(p).href);
|
|
4206
4356
|
const engine = await mod.createHcsEngine?.();
|
|
@@ -4367,7 +4517,7 @@ function hookContext(payloadText, root3, graphOverride) {
|
|
|
4367
4517
|
let graph;
|
|
4368
4518
|
try {
|
|
4369
4519
|
const preferred = loadGraphPreferIndex(root3, graphPath);
|
|
4370
|
-
graph = preferred ? preferred.graph : parseGraph(
|
|
4520
|
+
graph = preferred ? preferred.graph : parseGraph(fs13.readFileSync(graphPath, "utf8"));
|
|
4371
4521
|
} catch {
|
|
4372
4522
|
return null;
|
|
4373
4523
|
}
|
|
@@ -4389,7 +4539,7 @@ function registerHook(program) {
|
|
|
4389
4539
|
const global = readGlobal(this);
|
|
4390
4540
|
const root3 = rootOf(global);
|
|
4391
4541
|
try {
|
|
4392
|
-
const stdin =
|
|
4542
|
+
const stdin = fs13.readFileSync(0, "utf8");
|
|
4393
4543
|
const context = hookContext(stdin, root3, global.graph);
|
|
4394
4544
|
if (context) {
|
|
4395
4545
|
process.stdout.write(
|
|
@@ -4410,7 +4560,7 @@ function registerShare(program) {
|
|
|
4410
4560
|
const global = readGlobal(this);
|
|
4411
4561
|
const root3 = rootOf(global);
|
|
4412
4562
|
const gitDir = path46.join(root3, ".git");
|
|
4413
|
-
if (!
|
|
4563
|
+
if (!fs13.existsSync(gitDir)) {
|
|
4414
4564
|
throw new CliError("not a git repository \u2014 run `vg share` inside a git repo", ExitCode.USAGE_ERROR);
|
|
4415
4565
|
}
|
|
4416
4566
|
if (opts.undo) {
|
|
@@ -4432,22 +4582,22 @@ function registerShare(program) {
|
|
|
4432
4582
|
}
|
|
4433
4583
|
function writeVibgrateGitignore(root3, reports) {
|
|
4434
4584
|
const dir = path46.join(root3, ".vibgrate");
|
|
4435
|
-
|
|
4585
|
+
fs13.mkdirSync(dir, { recursive: true });
|
|
4436
4586
|
const lines = ["# Managed by `vg share` \u2014 keep graph.json committed, ignore the rest", "cache/", "facts.jsonl", "graph.snap"];
|
|
4437
4587
|
if (!reports) lines.push("graph.html", "GRAPH_REPORT.md");
|
|
4438
|
-
|
|
4588
|
+
fs13.writeFileSync(path46.join(dir, ".gitignore"), `${lines.join("\n")}
|
|
4439
4589
|
`);
|
|
4440
4590
|
}
|
|
4441
4591
|
function writeGitAttributes(root3) {
|
|
4442
4592
|
const file = path46.join(root3, ".gitattributes");
|
|
4443
4593
|
const line = ".vibgrate/graph.json merge=vg";
|
|
4444
|
-
let content =
|
|
4594
|
+
let content = fs13.existsSync(file) ? fs13.readFileSync(file, "utf8") : "";
|
|
4445
4595
|
if (!content.split("\n").some((l) => l.trim() === line)) {
|
|
4446
4596
|
content = content.length ? `${content.replace(/\s*$/, "")}
|
|
4447
4597
|
${line}
|
|
4448
4598
|
` : `${line}
|
|
4449
4599
|
`;
|
|
4450
|
-
|
|
4600
|
+
fs13.writeFileSync(file, content);
|
|
4451
4601
|
}
|
|
4452
4602
|
}
|
|
4453
4603
|
function configureMergeDriver(root3) {
|
|
@@ -4456,7 +4606,7 @@ function configureMergeDriver(root3) {
|
|
|
4456
4606
|
}
|
|
4457
4607
|
function installPreCommitHook(root3) {
|
|
4458
4608
|
const hooksDir = hookDir(root3);
|
|
4459
|
-
|
|
4609
|
+
fs13.mkdirSync(hooksDir, { recursive: true });
|
|
4460
4610
|
const file = path46.join(hooksDir, "pre-commit");
|
|
4461
4611
|
const block = [
|
|
4462
4612
|
HOOK_BEGIN,
|
|
@@ -4466,7 +4616,7 @@ function installPreCommitHook(root3) {
|
|
|
4466
4616
|
"fi",
|
|
4467
4617
|
HOOK_END
|
|
4468
4618
|
].join("\n");
|
|
4469
|
-
let content =
|
|
4619
|
+
let content = fs13.existsSync(file) ? fs13.readFileSync(file, "utf8") : "#!/bin/sh\n";
|
|
4470
4620
|
const re = new RegExp(`${escapeRe(HOOK_BEGIN)}[\\s\\S]*?${escapeRe(HOOK_END)}`);
|
|
4471
4621
|
if (re.test(content)) content = content.replace(re, block);
|
|
4472
4622
|
else content = `${content.replace(/\s*$/, "")}
|
|
@@ -4475,21 +4625,21 @@ ${block}
|
|
|
4475
4625
|
`;
|
|
4476
4626
|
if (!content.startsWith("#!")) content = `#!/bin/sh
|
|
4477
4627
|
${content}`;
|
|
4478
|
-
|
|
4479
|
-
|
|
4628
|
+
fs13.writeFileSync(file, content);
|
|
4629
|
+
fs13.chmodSync(file, 493);
|
|
4480
4630
|
}
|
|
4481
4631
|
function undo(root3) {
|
|
4482
4632
|
const hookFile = path46.join(hookDir(root3), "pre-commit");
|
|
4483
|
-
if (
|
|
4633
|
+
if (fs13.existsSync(hookFile)) {
|
|
4484
4634
|
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
|
|
4635
|
+
const next2 = fs13.readFileSync(hookFile, "utf8").replace(re, "\n");
|
|
4636
|
+
if (next2.trim() === "#!/bin/sh") fs13.rmSync(hookFile);
|
|
4637
|
+
else fs13.writeFileSync(hookFile, next2);
|
|
4488
4638
|
}
|
|
4489
4639
|
const attr = path46.join(root3, ".gitattributes");
|
|
4490
|
-
if (
|
|
4491
|
-
const next2 =
|
|
4492
|
-
|
|
4640
|
+
if (fs13.existsSync(attr)) {
|
|
4641
|
+
const next2 = fs13.readFileSync(attr, "utf8").split("\n").filter((l) => l.trim() !== ".vibgrate/graph.json merge=vg").join("\n");
|
|
4642
|
+
fs13.writeFileSync(attr, next2);
|
|
4493
4643
|
}
|
|
4494
4644
|
try {
|
|
4495
4645
|
git(root3, ["config", "--remove-section", "merge.vg"]);
|
|
@@ -4518,7 +4668,7 @@ function registerWatch(program) {
|
|
|
4518
4668
|
const debounceMs = Math.max(50, Number(opts.debounce) || DEFAULT_DEBOUNCE_MS);
|
|
4519
4669
|
const watchRoots = (paths.length ? paths : ["."]).map((p) => path46.resolve(root3, p));
|
|
4520
4670
|
for (const w of watchRoots) {
|
|
4521
|
-
if (!
|
|
4671
|
+
if (!fs13.existsSync(w)) {
|
|
4522
4672
|
throw new CliError(`watch path not found: ${w}`, ExitCode.USAGE_ERROR);
|
|
4523
4673
|
}
|
|
4524
4674
|
}
|
|
@@ -4571,7 +4721,7 @@ function registerWatch(program) {
|
|
|
4571
4721
|
const watchers = [];
|
|
4572
4722
|
for (const w of watchRoots) {
|
|
4573
4723
|
try {
|
|
4574
|
-
const watcher =
|
|
4724
|
+
const watcher = fs13.watch(w, { recursive: true }, (_event, filename) => {
|
|
4575
4725
|
if (!filename) {
|
|
4576
4726
|
schedule("change");
|
|
4577
4727
|
return;
|
|
@@ -4920,7 +5070,7 @@ function loadStandards(root3) {
|
|
|
4920
5070
|
const p = path46__default.join(root3, rel);
|
|
4921
5071
|
let text;
|
|
4922
5072
|
try {
|
|
4923
|
-
text =
|
|
5073
|
+
text = fs13__default.readFileSync(p, "utf8");
|
|
4924
5074
|
} catch {
|
|
4925
5075
|
continue;
|
|
4926
5076
|
}
|
|
@@ -6851,7 +7001,7 @@ function registerModels(program) {
|
|
|
6851
7001
|
);
|
|
6852
7002
|
}
|
|
6853
7003
|
} else {
|
|
6854
|
-
if (!target.path || !
|
|
7004
|
+
if (!target.path || !fs13.existsSync(target.path)) {
|
|
6855
7005
|
throw new CliError(
|
|
6856
7006
|
`model file not found at ${target.path || "(unknown path)"} \u2014 it may already be removed.`,
|
|
6857
7007
|
ExitCode.NOT_FOUND
|
|
@@ -6865,7 +7015,7 @@ function registerModels(program) {
|
|
|
6865
7015
|
}
|
|
6866
7016
|
if (!global.json) info(c.dim(` $ rm ${target.path}`));
|
|
6867
7017
|
try {
|
|
6868
|
-
|
|
7018
|
+
fs13.unlinkSync(target.path);
|
|
6869
7019
|
} catch (e) {
|
|
6870
7020
|
const msg = e instanceof Error ? e.message : String(e);
|
|
6871
7021
|
throw new CliError(`could not delete ${target.path}: ${msg}`, ExitCode.ERROR);
|
|
@@ -7004,8 +7154,8 @@ function registerModels(program) {
|
|
|
7004
7154
|
});
|
|
7005
7155
|
if (opts.out) {
|
|
7006
7156
|
const outPath = path46.resolve(opts.out);
|
|
7007
|
-
|
|
7008
|
-
|
|
7157
|
+
fs13.mkdirSync(path46.dirname(outPath), { recursive: true });
|
|
7158
|
+
fs13.writeFileSync(outPath, `${JSON.stringify(report, null, 2)}
|
|
7009
7159
|
`);
|
|
7010
7160
|
if (!global.json) info(c.dim(` wrote ${outPath}`));
|
|
7011
7161
|
}
|
|
@@ -7203,7 +7353,7 @@ function codeConfigPath(root3) {
|
|
|
7203
7353
|
}
|
|
7204
7354
|
function loadCodeConfig(root3) {
|
|
7205
7355
|
try {
|
|
7206
|
-
const raw = JSON.parse(
|
|
7356
|
+
const raw = JSON.parse(fs13.readFileSync(codeConfigPath(root3), "utf8"));
|
|
7207
7357
|
return sanitize(raw);
|
|
7208
7358
|
} catch {
|
|
7209
7359
|
return {};
|
|
@@ -7270,7 +7420,7 @@ function contextBudgetFor(config, modelContextWindow) {
|
|
|
7270
7420
|
var MCP_CONFIG_FILES = [".cursor/mcp.json", ".vscode/mcp.json", ".mcp.json"];
|
|
7271
7421
|
function readMcpServersFile(file) {
|
|
7272
7422
|
try {
|
|
7273
|
-
const raw = JSON.parse(
|
|
7423
|
+
const raw = JSON.parse(fs13.readFileSync(file, "utf8"));
|
|
7274
7424
|
const map = raw.mcpServers ?? raw.servers;
|
|
7275
7425
|
return map && typeof map === "object" ? parseMcpServers(map) : {};
|
|
7276
7426
|
} catch {
|
|
@@ -7395,10 +7545,10 @@ function registerCode(program) {
|
|
|
7395
7545
|
return;
|
|
7396
7546
|
}
|
|
7397
7547
|
const patchFile = pathMod.join(
|
|
7398
|
-
|
|
7548
|
+
fs13.mkdtempSync(pathMod.join(os7.tmpdir(), "vg-wt-")),
|
|
7399
7549
|
"delta.patch"
|
|
7400
7550
|
);
|
|
7401
|
-
|
|
7551
|
+
fs13.writeFileSync(patchFile, diff2.patch);
|
|
7402
7552
|
const outcome = wt.applyWorktreePatch(gitRunner, root4, patchFile, diff2.files);
|
|
7403
7553
|
emitLine({ event: "worktree-applied", id: target.id, ...outcome });
|
|
7404
7554
|
if (!opts.streamJson && !global.json) {
|
|
@@ -7464,7 +7614,7 @@ function registerCode(program) {
|
|
|
7464
7614
|
try {
|
|
7465
7615
|
const { parseMode: parseMode2, resolveMode: resolveMode2, readOrchestratorState: readOrchestratorState2, activePin: activePin2 } = await import('./model-orchestrator-LHYPJBFH.js');
|
|
7466
7616
|
const { gatherSystemMemory: gatherSystemMemory2 } = await import('./local-runtime-6SNWKSA7.js');
|
|
7467
|
-
const { loadGraph: loadGraph2 } = await import('./load-
|
|
7617
|
+
const { loadGraph: loadGraph2 } = await import('./load-4R4HYMBB.js');
|
|
7468
7618
|
const state = readOrchestratorState2();
|
|
7469
7619
|
const mode = parseMode2(modeFlag) ?? state.defaultMode ?? void 0;
|
|
7470
7620
|
const pin = mode ? activePin2(mode, state) : null;
|
|
@@ -7549,7 +7699,7 @@ function registerCode(program) {
|
|
|
7549
7699
|
if (!(process.stdin.isTTY && process.stdout.isTTY)) {
|
|
7550
7700
|
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
7701
|
}
|
|
7552
|
-
const { runInteractive } = await import('./interactive-
|
|
7702
|
+
const { runInteractive } = await import('./interactive-2MK4TLRD.js');
|
|
7553
7703
|
await runInteractive(
|
|
7554
7704
|
rootOf(global),
|
|
7555
7705
|
global,
|
|
@@ -7579,7 +7729,7 @@ function registerCode(program) {
|
|
|
7579
7729
|
}
|
|
7580
7730
|
if (!instruction && !stdinFirstTurn) throw usageError('say what to change, e.g. `vg code "add a --timeout flag to the scan command"`');
|
|
7581
7731
|
{
|
|
7582
|
-
const { ensureCodeMap } = await import('./ensure-map-
|
|
7732
|
+
const { ensureCodeMap } = await import('./ensure-map-FHDJTO7Y.js');
|
|
7583
7733
|
const mapRoot = rootOf(global);
|
|
7584
7734
|
try {
|
|
7585
7735
|
await ensureCodeMap(mapRoot, global, {
|
|
@@ -7616,7 +7766,7 @@ function registerCode(program) {
|
|
|
7616
7766
|
let mockReply;
|
|
7617
7767
|
if (opts.mock) {
|
|
7618
7768
|
try {
|
|
7619
|
-
mockReply =
|
|
7769
|
+
mockReply = fs13.readFileSync(opts.mock, "utf8");
|
|
7620
7770
|
} catch {
|
|
7621
7771
|
throw new CliError(`couldn't read the --mock file: ${opts.mock}`, ExitCode.USAGE_ERROR);
|
|
7622
7772
|
}
|
|
@@ -7664,20 +7814,20 @@ function registerCode(program) {
|
|
|
7664
7814
|
process.stdout.write(JSON.stringify(line) + "\n");
|
|
7665
7815
|
};
|
|
7666
7816
|
try {
|
|
7667
|
-
const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-
|
|
7817
|
+
const { RunOutcomeRecorder, newOneShotRunId, turnRunId } = await import('./run-outcome-H5GVDDZJ.js');
|
|
7668
7818
|
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-
|
|
7819
|
+
const { runCodeStreamJson, parseHostMessage } = await import('./stream-json-4WLSUF6I.js');
|
|
7820
|
+
const { nodeCodeFs } = await import('./session-N5IU4K5Q.js');
|
|
7671
7821
|
const readline6 = await import('readline');
|
|
7672
7822
|
const child = await import('child_process');
|
|
7673
7823
|
const { loadOrDiscoverFederation } = await import('./federation-MDQPO3PW.js');
|
|
7674
7824
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
7675
7825
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
7676
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
7677
|
-
const { resolveGraphBackend } = await import('./graph-backend-
|
|
7826
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-JBIHHH5N.js');
|
|
7827
|
+
const { resolveGraphBackend } = await import('./graph-backend-W2D3HRRD.js');
|
|
7678
7828
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
7679
7829
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
7680
|
-
const { vgdRequest } = await import('./vgd-
|
|
7830
|
+
const { vgdRequest } = await import('./vgd-M7UOPWLB.js');
|
|
7681
7831
|
const federation = loadOrDiscoverFederation(root3);
|
|
7682
7832
|
const modelProfile = mergeModelExecutionProfile(
|
|
7683
7833
|
resolveModelExecutionProfile({
|
|
@@ -7735,7 +7885,7 @@ ${res.stderr}` : ""),
|
|
|
7735
7885
|
exitCode: res.status ?? 1
|
|
7736
7886
|
};
|
|
7737
7887
|
};
|
|
7738
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
7888
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-KDVYIMFX.js');
|
|
7739
7889
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
7740
7890
|
getGraph: () => graph,
|
|
7741
7891
|
root: root3,
|
|
@@ -7759,7 +7909,7 @@ ${res.stderr}` : ""),
|
|
|
7759
7909
|
const os7 = await import('os');
|
|
7760
7910
|
const pathMod = await import('path');
|
|
7761
7911
|
const checkpointIndex = pathMod.join(
|
|
7762
|
-
|
|
7912
|
+
fs13.mkdtempSync(pathMod.join(os7.tmpdir(), "vg-code-cp-")),
|
|
7763
7913
|
"index"
|
|
7764
7914
|
);
|
|
7765
7915
|
const gitRunner = (gitArgs, gitEnv) => {
|
|
@@ -7780,7 +7930,7 @@ ${res.stderr}` : ""),
|
|
|
7780
7930
|
files,
|
|
7781
7931
|
indexFile: checkpointIndex
|
|
7782
7932
|
});
|
|
7783
|
-
const { loadApprovalRules, addApprovalRule, ruleForAction, ruleLabel } = await import('./approvals-
|
|
7933
|
+
const { loadApprovalRules, addApprovalRule, ruleForAction, ruleLabel } = await import('./approvals-TPQFQSWG.js');
|
|
7784
7934
|
const { loadProjectRules, nodeRulesReader } = await import('./rules-ASYEUNB5.js');
|
|
7785
7935
|
const projectRules = loadProjectRules(nodeRulesReader(root3));
|
|
7786
7936
|
if (projectRules.sources.length && !global.quiet) {
|
|
@@ -7838,8 +7988,8 @@ ${res.stderr}` : ""),
|
|
|
7838
7988
|
};
|
|
7839
7989
|
try {
|
|
7840
7990
|
if (opts.session) {
|
|
7841
|
-
const { runCodeStreamJsonSession, STREAM_JSON_PROTOCOL_VERSION } = await import('./stream-json-
|
|
7842
|
-
const { runAgent: runAgent2 } = await import('./agent-
|
|
7991
|
+
const { runCodeStreamJsonSession, STREAM_JSON_PROTOCOL_VERSION } = await import('./stream-json-4WLSUF6I.js');
|
|
7992
|
+
const { runAgent: runAgent2 } = await import('./agent-X6VYCE63.js');
|
|
7843
7993
|
const {
|
|
7844
7994
|
condenseSession,
|
|
7845
7995
|
loadLatestSession,
|
|
@@ -7850,7 +8000,7 @@ ${res.stderr}` : ""),
|
|
|
7850
8000
|
sessionsDir,
|
|
7851
8001
|
summarizeSession
|
|
7852
8002
|
} = await import('./session-store-AQUORKWB.js');
|
|
7853
|
-
const { VERSION: VERSION2 } = await import('./version-
|
|
8003
|
+
const { VERSION: VERSION2 } = await import('./version-DTEU3SQD.js');
|
|
7854
8004
|
const resumedRecord = typeof opts.continue === "string" ? loadSession(mainRoot, opts.continue) : opts.continue ? loadLatestSession(mainRoot) : void 0;
|
|
7855
8005
|
if (typeof opts.continue === "string" && !resumedRecord) {
|
|
7856
8006
|
emitStream({
|
|
@@ -8062,8 +8212,8 @@ ${res.stderr}` : ""),
|
|
|
8062
8212
|
if (!autonomous && !tty) {
|
|
8063
8213
|
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
8214
|
}
|
|
8065
|
-
const { agentTask } = await import('./interactive-
|
|
8066
|
-
const { nodeCodeFs } = await import('./session-
|
|
8215
|
+
const { agentTask } = await import('./interactive-2MK4TLRD.js');
|
|
8216
|
+
const { nodeCodeFs } = await import('./session-N5IU4K5Q.js');
|
|
8067
8217
|
const { TtyPrompter } = await import('./ui-K7D3BCHD.js');
|
|
8068
8218
|
let priorSummary;
|
|
8069
8219
|
let priorInstruction;
|
|
@@ -8078,7 +8228,7 @@ ${res.stderr}` : ""),
|
|
|
8078
8228
|
}
|
|
8079
8229
|
}
|
|
8080
8230
|
const prompter = tty ? new TtyPrompter() : void 0;
|
|
8081
|
-
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-
|
|
8231
|
+
const { createVgBuiltinMcpTools, mergeExternalToolsets } = await import('./vg-mcp-bridge-KDVYIMFX.js');
|
|
8082
8232
|
const vgBuiltin = createVgBuiltinMcpTools({
|
|
8083
8233
|
getGraph: () => graph,
|
|
8084
8234
|
root: root3,
|
|
@@ -8102,11 +8252,11 @@ ${res.stderr}` : ""),
|
|
|
8102
8252
|
const { loadFederation } = await import('./federation-MDQPO3PW.js');
|
|
8103
8253
|
const { resolveExecutionEnv } = await import('./execution-env-4MS5AYAN.js');
|
|
8104
8254
|
const { resolveModelExecutionProfile, mergeModelExecutionProfile } = await import('./model-execution-profile-ELWF3Z6H.js');
|
|
8105
|
-
const { startCodeRuntimeSession } = await import('./runtime-session-
|
|
8106
|
-
const { resolveGraphBackend } = await import('./graph-backend-
|
|
8255
|
+
const { startCodeRuntimeSession } = await import('./runtime-session-JBIHHH5N.js');
|
|
8256
|
+
const { resolveGraphBackend } = await import('./graph-backend-W2D3HRRD.js');
|
|
8107
8257
|
const { detectGitRef } = await import('./git-ref-RSRAN4OH.js');
|
|
8108
8258
|
const { repositoryIdFromRoot } = await import('./paths-62AKTFSR.js');
|
|
8109
|
-
const { vgdRequest } = await import('./vgd-
|
|
8259
|
+
const { vgdRequest } = await import('./vgd-M7UOPWLB.js');
|
|
8110
8260
|
const federation = loadFederation(root3);
|
|
8111
8261
|
const modelProfile = mergeModelExecutionProfile(
|
|
8112
8262
|
resolveModelExecutionProfile({
|
|
@@ -8200,7 +8350,7 @@ ${res.stderr}` : ""),
|
|
|
8200
8350
|
attribution: { client: "vg-code", provider: providerSlug, model: primary?.model }
|
|
8201
8351
|
});
|
|
8202
8352
|
if (opts.out) {
|
|
8203
|
-
|
|
8353
|
+
fs13.writeFileSync(opts.out, JSON.stringify(result, null, 2) + "\n");
|
|
8204
8354
|
}
|
|
8205
8355
|
if (global.json) {
|
|
8206
8356
|
json(result);
|
|
@@ -8389,8 +8539,9 @@ function listCatalog(root3, asJson) {
|
|
|
8389
8539
|
return;
|
|
8390
8540
|
}
|
|
8391
8541
|
info(`${c.cyan("vg lib")} \xB7 ${libs.length} library(ies) in the catalog`);
|
|
8542
|
+
const inv = inventory(root3);
|
|
8392
8543
|
for (const l of libs) {
|
|
8393
|
-
const d = driftFor(root3, l);
|
|
8544
|
+
const d = driftFor(root3, l, inv);
|
|
8394
8545
|
const tag = d.drift === "behind" ? c.yellow(" (docs behind your version)") : d.drift === "ahead" ? c.dim(" (docs ahead)") : "";
|
|
8395
8546
|
info(` ${c.bold(l.name)} ${c.dim(`@${l.version}`)} ${c.dim(`[${l.source.type}]`)}${tag}`);
|
|
8396
8547
|
}
|
|
@@ -8413,7 +8564,7 @@ async function addCmd(root3, rest, opts, asJson) {
|
|
|
8413
8564
|
}
|
|
8414
8565
|
function readPackageVersion(root3) {
|
|
8415
8566
|
try {
|
|
8416
|
-
const pkg = JSON.parse(
|
|
8567
|
+
const pkg = JSON.parse(fs13__default.readFileSync(path46__default.join(root3, "package.json"), "utf8"));
|
|
8417
8568
|
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
8418
8569
|
} catch {
|
|
8419
8570
|
return void 0;
|
|
@@ -8421,7 +8572,7 @@ function readPackageVersion(root3) {
|
|
|
8421
8572
|
}
|
|
8422
8573
|
function readOptionalFile(p) {
|
|
8423
8574
|
try {
|
|
8424
|
-
const t =
|
|
8575
|
+
const t = fs13__default.readFileSync(p, "utf8");
|
|
8425
8576
|
return t.trim() ? t : void 0;
|
|
8426
8577
|
} catch {
|
|
8427
8578
|
return void 0;
|
|
@@ -8569,8 +8720,8 @@ function registerExport(program) {
|
|
|
8569
8720
|
out(content.trimEnd());
|
|
8570
8721
|
return;
|
|
8571
8722
|
}
|
|
8572
|
-
|
|
8573
|
-
|
|
8723
|
+
fs13.mkdirSync(path46.dirname(path46.resolve(file)), { recursive: true });
|
|
8724
|
+
fs13.writeFileSync(file, content);
|
|
8574
8725
|
info(`${c.green("\u2714")} wrote ${file} ${c.dim(`(${format})`)}`);
|
|
8575
8726
|
});
|
|
8576
8727
|
applyGlobalOptions(cmd);
|
|
@@ -8593,36 +8744,36 @@ function registerBundle(program) {
|
|
|
8593
8744
|
} catch {
|
|
8594
8745
|
throw new CliError("no grammars found to bundle (run a build first)", ExitCode.ERROR);
|
|
8595
8746
|
}
|
|
8596
|
-
|
|
8747
|
+
fs13.mkdirSync(path46.join(outDir, "grammars"), { recursive: true });
|
|
8597
8748
|
let grammarCount = 0;
|
|
8598
8749
|
for (const { fileName, absPath } of grammarFiles) {
|
|
8599
|
-
|
|
8750
|
+
fs13.copyFileSync(absPath, path46.join(outDir, "grammars", fileName));
|
|
8600
8751
|
grammarCount++;
|
|
8601
8752
|
}
|
|
8602
8753
|
for (const id of Object.keys(TOOLCHAIN_GRAMMARS).sort()) {
|
|
8603
8754
|
const absPath = resolveToolchainGrammar(id);
|
|
8604
8755
|
if (!absPath) continue;
|
|
8605
|
-
|
|
8756
|
+
fs13.copyFileSync(absPath, path46.join(outDir, "grammars", path46.basename(absPath)));
|
|
8606
8757
|
grammarCount++;
|
|
8607
8758
|
}
|
|
8608
8759
|
const included = [`grammars/ (${grammarCount} .wasm)`];
|
|
8609
8760
|
const graphSrc = resolveGraphPath(root3, global.graph);
|
|
8610
|
-
if (
|
|
8611
|
-
|
|
8761
|
+
if (fs13.existsSync(graphSrc)) {
|
|
8762
|
+
fs13.copyFileSync(graphSrc, path46.join(outDir, "graph.json"));
|
|
8612
8763
|
included.push("graph.json");
|
|
8613
8764
|
} else {
|
|
8614
8765
|
const graph = loadGraphFileWithSnapshot(graphSrc);
|
|
8615
8766
|
if (graph) {
|
|
8616
|
-
|
|
8767
|
+
fs13.writeFileSync(path46.join(outDir, "graph.json"), serializeGraph(graph));
|
|
8617
8768
|
included.push("graph.json");
|
|
8618
8769
|
}
|
|
8619
8770
|
}
|
|
8620
8771
|
const cat = catalogPath(root3);
|
|
8621
|
-
if (
|
|
8622
|
-
|
|
8772
|
+
if (fs13.existsSync(cat)) {
|
|
8773
|
+
fs13.copyFileSync(cat, path46.join(outDir, "vibgrate.lib.json"));
|
|
8623
8774
|
included.push("vibgrate.lib.json");
|
|
8624
|
-
if (
|
|
8625
|
-
|
|
8775
|
+
if (fs13.existsSync(libDir(root3))) {
|
|
8776
|
+
fs13.cpSync(libDir(root3), path46.join(outDir, "lib"), { recursive: true });
|
|
8626
8777
|
included.push("lib/");
|
|
8627
8778
|
}
|
|
8628
8779
|
}
|
|
@@ -8634,7 +8785,7 @@ function registerBundle(program) {
|
|
|
8634
8785
|
included,
|
|
8635
8786
|
usage: "Run `vg build --grammars <this dir>/grammars` to build fully offline."
|
|
8636
8787
|
};
|
|
8637
|
-
|
|
8788
|
+
fs13.writeFileSync(path46.join(outDir, "MANIFEST.json"), `${stableStringify(manifest, 2)}
|
|
8638
8789
|
`);
|
|
8639
8790
|
if (global.json) {
|
|
8640
8791
|
json({ out: path46.relative(root3, outDir), ...manifest });
|
|
@@ -8660,7 +8811,7 @@ async function runDoctor(global) {
|
|
|
8660
8811
|
const root3 = rootOf(global);
|
|
8661
8812
|
const local = global.local === true;
|
|
8662
8813
|
const graphPath = resolveGraphPath(root3, global.graph);
|
|
8663
|
-
const configFile = CONFIG_BASENAMES.find((f) =>
|
|
8814
|
+
const configFile = CONFIG_BASENAMES.find((f) => fs13.existsSync(path46.join(root3, f))) ?? null;
|
|
8664
8815
|
const graph = loadGraph(root3, graphPath);
|
|
8665
8816
|
let staleFiles = null;
|
|
8666
8817
|
if (graph) {
|
|
@@ -8693,7 +8844,7 @@ async function runDoctor(global) {
|
|
|
8693
8844
|
},
|
|
8694
8845
|
libCatalog: {
|
|
8695
8846
|
path: path46.relative(root3, catalogPath(root3)),
|
|
8696
|
-
present:
|
|
8847
|
+
present: fs13.existsSync(catalogPath(root3)),
|
|
8697
8848
|
libraries: libCount
|
|
8698
8849
|
},
|
|
8699
8850
|
credentials: creds,
|
|
@@ -8870,7 +9021,7 @@ function registerPolicy(program) {
|
|
|
8870
9021
|
const global = readGlobal(this);
|
|
8871
9022
|
let raw;
|
|
8872
9023
|
try {
|
|
8873
|
-
raw =
|
|
9024
|
+
raw = fs13.readFileSync(file, "utf8");
|
|
8874
9025
|
} catch {
|
|
8875
9026
|
throw new CliError(`cannot read ${file}`, ExitCode.NOT_FOUND);
|
|
8876
9027
|
}
|
|
@@ -9058,8 +9209,8 @@ async function readStdin() {
|
|
|
9058
9209
|
}
|
|
9059
9210
|
function readFileOrThrow(file, label) {
|
|
9060
9211
|
const p = path46.resolve(file);
|
|
9061
|
-
if (!
|
|
9062
|
-
return
|
|
9212
|
+
if (!fs13.existsSync(p)) throw usageError(`${label} file not found: ${p}`);
|
|
9213
|
+
return fs13.readFileSync(p, "utf-8");
|
|
9063
9214
|
}
|
|
9064
9215
|
async function readInput(file, label) {
|
|
9065
9216
|
return file ? readFileOrThrow(file, label) : readStdin();
|
|
@@ -9071,8 +9222,8 @@ function writeOutput(outFile, content) {
|
|
|
9071
9222
|
}
|
|
9072
9223
|
const outPath = path46.resolve(outFile);
|
|
9073
9224
|
const dir = path46.dirname(outPath);
|
|
9074
|
-
if (!
|
|
9075
|
-
|
|
9225
|
+
if (!fs13.existsSync(dir)) throw usageError(`output directory does not exist: ${dir}`);
|
|
9226
|
+
fs13.writeFileSync(outPath, content.endsWith("\n") ? content : content + "\n", "utf-8");
|
|
9076
9227
|
info(c.dim(`wrote ${outPath}`));
|
|
9077
9228
|
}
|
|
9078
9229
|
function requireChoice(value, valid2, flag) {
|
|
@@ -9106,7 +9257,7 @@ function registerHcs(program) {
|
|
|
9106
9257
|
const statePath = opts.previous ?? opts.out;
|
|
9107
9258
|
const useIncremental = canIncremental && statePath !== void 0;
|
|
9108
9259
|
const root3 = path46.resolve(dir);
|
|
9109
|
-
if (!
|
|
9260
|
+
if (!fs13.existsSync(root3) || !fs13.statSync(root3).isDirectory()) {
|
|
9110
9261
|
throw usageError(`not a directory: ${root3}`);
|
|
9111
9262
|
}
|
|
9112
9263
|
const supported = new Set(
|
|
@@ -9124,7 +9275,7 @@ function registerHcs(program) {
|
|
|
9124
9275
|
const walk2 = (abs, rel) => {
|
|
9125
9276
|
let entries;
|
|
9126
9277
|
try {
|
|
9127
|
-
entries =
|
|
9278
|
+
entries = fs13.readdirSync(abs, { withFileTypes: true });
|
|
9128
9279
|
} catch {
|
|
9129
9280
|
return;
|
|
9130
9281
|
}
|
|
@@ -9141,8 +9292,8 @@ function registerHcs(program) {
|
|
|
9141
9292
|
const lang = extToLang.get(path46.extname(entry.name).toLowerCase());
|
|
9142
9293
|
if (!lang) continue;
|
|
9143
9294
|
try {
|
|
9144
|
-
if (
|
|
9145
|
-
const content =
|
|
9295
|
+
if (fs13.statSync(absChild).size > MAX_EXTRACT_FILE_BYTES) continue;
|
|
9296
|
+
const content = fs13.readFileSync(absChild, "utf-8");
|
|
9146
9297
|
let bucket = byLanguage.get(lang);
|
|
9147
9298
|
if (!bucket) byLanguage.set(lang, bucket = []);
|
|
9148
9299
|
bucket.push({ path: relChild, content });
|
|
@@ -9173,7 +9324,7 @@ function registerHcs(program) {
|
|
|
9173
9324
|
return;
|
|
9174
9325
|
}
|
|
9175
9326
|
const previousPath = path46.resolve(statePath);
|
|
9176
|
-
const previousNdjson = !opts.full &&
|
|
9327
|
+
const previousNdjson = !opts.full && fs13.existsSync(previousPath) ? fs13.readFileSync(previousPath, "utf-8") : "";
|
|
9177
9328
|
if (opts.full) info(c.dim("running a full re-extraction (--full)"));
|
|
9178
9329
|
else if (!previousNdjson) info(c.dim(`previous stream not found at ${previousPath} \u2014 running a full extraction`));
|
|
9179
9330
|
const currentFilesJson = JSON.stringify(
|
|
@@ -9289,7 +9440,7 @@ var initCommand = new Command("init").description("Initialize vibgrate in a proj
|
|
|
9289
9440
|
console.log(chalk7.green("\u2714") + ` Created ${chalk7.bold("vibgrate.config.ts")}`);
|
|
9290
9441
|
}
|
|
9291
9442
|
if (opts.baseline) {
|
|
9292
|
-
const { runBaseline } = await import('./baseline-
|
|
9443
|
+
const { runBaseline } = await import('./baseline-DXI64VLW.js');
|
|
9293
9444
|
await runBaseline(rootDir);
|
|
9294
9445
|
}
|
|
9295
9446
|
console.log("");
|
|
@@ -9430,9 +9581,9 @@ function sitesFromImportFiles(files, limit = 10) {
|
|
|
9430
9581
|
}
|
|
9431
9582
|
async function defaultReadFile(absPath) {
|
|
9432
9583
|
try {
|
|
9433
|
-
const stat2 = await
|
|
9584
|
+
const stat2 = await fs27.stat(absPath);
|
|
9434
9585
|
if (!stat2.isFile() || stat2.size > MAX_FILE_BYTES) return null;
|
|
9435
|
-
return await
|
|
9586
|
+
return await fs27.readFile(absPath, "utf8");
|
|
9436
9587
|
} catch {
|
|
9437
9588
|
return null;
|
|
9438
9589
|
}
|
|
@@ -9820,6 +9971,36 @@ function reportStandards(rootDir) {
|
|
|
9820
9971
|
console.log(` ${chalk7.red("banned")} ${v.ecosystem}:${v.name}${v.installed ? chalk7.dim(` ${v.installed}`) : ""}${fix}${why}`);
|
|
9821
9972
|
}
|
|
9822
9973
|
}
|
|
9974
|
+
async function printRuntimeSnapshot(rootDir, opts, already) {
|
|
9975
|
+
try {
|
|
9976
|
+
const { attachVgd: attachVgd2 } = await import('./attach-G5JUIWIT.js');
|
|
9977
|
+
const { vgdRequest } = await import('./client-UQIELEEZ.js');
|
|
9978
|
+
const { formatSemanticProgress } = await import('./semantic-status-2JFLIQQJ.js');
|
|
9979
|
+
let repositoryId = already?.repositoryId;
|
|
9980
|
+
let socketPath = already?.socketPath;
|
|
9981
|
+
if (!repositoryId || !socketPath) {
|
|
9982
|
+
const attached = await attachVgd2(rootDir, {
|
|
9983
|
+
disabled: opts.daemon === false,
|
|
9984
|
+
autoStart: false,
|
|
9985
|
+
publish: false
|
|
9986
|
+
});
|
|
9987
|
+
if (attached.status !== "attached" || !attached.repositoryId || !attached.socketPath) return;
|
|
9988
|
+
repositoryId = attached.repositoryId;
|
|
9989
|
+
socketPath = attached.socketPath;
|
|
9990
|
+
}
|
|
9991
|
+
const semantic = await vgdRequest({ op: "embed-status", repositoryId }, { socketPath });
|
|
9992
|
+
if (!semantic.ok || !("semantic" in semantic)) return;
|
|
9993
|
+
const slot = semantic.semantic.slots.find((s) => s.repositoryId === repositoryId) ?? semantic.semantic.slots[0];
|
|
9994
|
+
if (!slot) {
|
|
9995
|
+
if (semantic.semantic.worker === "unavailable" && semantic.semantic.reason) {
|
|
9996
|
+
console.error(chalk7.dim(` \xB7 semantic \xB7 ${semantic.semantic.reason}`));
|
|
9997
|
+
}
|
|
9998
|
+
return;
|
|
9999
|
+
}
|
|
10000
|
+
console.error(chalk7.dim(` \xB7 ${formatSemanticProgress(slot)}`));
|
|
10001
|
+
} catch {
|
|
10002
|
+
}
|
|
10003
|
+
}
|
|
9823
10004
|
function parseNonNegativeNumber(value, label) {
|
|
9824
10005
|
if (value === void 0) return void 0;
|
|
9825
10006
|
const parsed = Number(value);
|
|
@@ -9833,7 +10014,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
|
|
|
9833
10014
|
'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
10015
|
collectExcludes,
|
|
9835
10016
|
[]
|
|
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) => {
|
|
10017
|
+
).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
10018
|
const rootDir = path46.resolve(targetPath);
|
|
9838
10019
|
if (!await pathExists$1(rootDir)) {
|
|
9839
10020
|
console.error(chalk7.red(`Path does not exist: ${rootDir}`));
|
|
@@ -9918,6 +10099,7 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
|
|
|
9918
10099
|
console.error(chalk7.red("Repository unchanged but no previous ingest id available."));
|
|
9919
10100
|
process.exit(1);
|
|
9920
10101
|
}
|
|
10102
|
+
await printRuntimeSnapshot(rootDir, opts);
|
|
9921
10103
|
return;
|
|
9922
10104
|
}
|
|
9923
10105
|
}
|
|
@@ -9985,20 +10167,49 @@ var scanCommand = new Command("scan").description("Scan a project for upgrade dr
|
|
|
9985
10167
|
writeSnapshot(rootDir, result.graph.provenance.corpusHash, result.fileStats, {
|
|
9986
10168
|
exclude: opts.exclude
|
|
9987
10169
|
});
|
|
9988
|
-
refineArchitectureWithGraph(
|
|
9989
|
-
{ projects: ctx.projects, solutions: ctx.solutions, extended: ctx.extended },
|
|
9990
|
-
architectureGraphView2(result.graph)
|
|
9991
|
-
);
|
|
9992
10170
|
refineArchitectureWithAstRoles(
|
|
9993
10171
|
{ projects: ctx.projects, solutions: ctx.solutions, extended: ctx.extended },
|
|
9994
10172
|
result.fileRoles
|
|
9995
10173
|
);
|
|
10174
|
+
refineArchitectureWithGraph(
|
|
10175
|
+
{ projects: ctx.projects, solutions: ctx.solutions, extended: ctx.extended },
|
|
10176
|
+
architectureGraphView2(result.graph)
|
|
10177
|
+
);
|
|
9996
10178
|
const { counts } = result.graph.meta;
|
|
9997
10179
|
return `${counts.nodes.toLocaleString()} nodes \xB7 ${counts.edges.toLocaleString()} edges`;
|
|
9998
10180
|
};
|
|
9999
10181
|
}
|
|
10000
10182
|
const advanced = await loadAdvancedScanHook();
|
|
10001
10183
|
const artifact = await runCoreScan(rootDir, scanOpts, advanced);
|
|
10184
|
+
if (wantGraph && builtGraph) {
|
|
10185
|
+
const { attachVgd: attachVgd2 } = await import('./attach-G5JUIWIT.js');
|
|
10186
|
+
const { ActivityLog: ActivityLog2 } = await import('./activity-MF2GNYAI.js');
|
|
10187
|
+
const activity = new ActivityLog2();
|
|
10188
|
+
const attached = await activity.time(
|
|
10189
|
+
"attach",
|
|
10190
|
+
() => attachVgd2(rootDir, { disabled: opts.daemon === false }),
|
|
10191
|
+
(a) => {
|
|
10192
|
+
if (a.status !== "attached") return { outcome: "skip", detail: `${a.reason} \u2014 the map stays on disk only` };
|
|
10193
|
+
const started = a.started ? "started vgd" : "attached to vgd";
|
|
10194
|
+
if (a.published?.status === "published") {
|
|
10195
|
+
return {
|
|
10196
|
+
outcome: "ok",
|
|
10197
|
+
detail: `${started} \xB7 map published ${a.published.gitRef} \xB7 ${a.published.nodeCount} nodes`
|
|
10198
|
+
};
|
|
10199
|
+
}
|
|
10200
|
+
return { outcome: "ok", detail: started };
|
|
10201
|
+
}
|
|
10202
|
+
);
|
|
10203
|
+
if (!opts.quiet && opts.format !== "json") {
|
|
10204
|
+
for (const line of activity.render()) console.error(line);
|
|
10205
|
+
if (attached.status === "attached") {
|
|
10206
|
+
await printRuntimeSnapshot(rootDir, opts, {
|
|
10207
|
+
repositoryId: attached.repositoryId,
|
|
10208
|
+
socketPath: attached.socketPath
|
|
10209
|
+
});
|
|
10210
|
+
}
|
|
10211
|
+
}
|
|
10212
|
+
}
|
|
10002
10213
|
emitDriftScoreLine(artifact.drift.score);
|
|
10003
10214
|
if (opts.full) {
|
|
10004
10215
|
reportStandards(rootDir);
|
|
@@ -10119,7 +10330,7 @@ var SKIP_DIRS3 = /* @__PURE__ */ new Set([
|
|
|
10119
10330
|
function scanStaleness(rootDir, artifactPath) {
|
|
10120
10331
|
let ref;
|
|
10121
10332
|
try {
|
|
10122
|
-
ref =
|
|
10333
|
+
ref = fs13.statSync(artifactPath).mtimeMs;
|
|
10123
10334
|
} catch {
|
|
10124
10335
|
return { stale: false };
|
|
10125
10336
|
}
|
|
@@ -10131,7 +10342,7 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
10131
10342
|
if (depth > 8 || scanned > MAX_ENTRIES2) return;
|
|
10132
10343
|
let entries;
|
|
10133
10344
|
try {
|
|
10134
|
-
entries =
|
|
10345
|
+
entries = fs13.readdirSync(dir, { withFileTypes: true });
|
|
10135
10346
|
} catch {
|
|
10136
10347
|
return;
|
|
10137
10348
|
}
|
|
@@ -10146,7 +10357,7 @@ function scanStaleness(rootDir, artifactPath) {
|
|
|
10146
10357
|
const abs = path46.join(dir, e.name);
|
|
10147
10358
|
let mtimeMs;
|
|
10148
10359
|
try {
|
|
10149
|
-
mtimeMs =
|
|
10360
|
+
mtimeMs = fs13.statSync(abs).mtimeMs;
|
|
10150
10361
|
} catch {
|
|
10151
10362
|
continue;
|
|
10152
10363
|
}
|
|
@@ -10283,7 +10494,7 @@ function analyzeTree(root3, packages) {
|
|
|
10283
10494
|
if (depth > MAX_DEPTH || filesSeen >= MAX_FILES) return;
|
|
10284
10495
|
let entries;
|
|
10285
10496
|
try {
|
|
10286
|
-
entries =
|
|
10497
|
+
entries = fs13.readdirSync(dir, { withFileTypes: true });
|
|
10287
10498
|
} catch {
|
|
10288
10499
|
return;
|
|
10289
10500
|
}
|
|
@@ -10301,8 +10512,8 @@ function analyzeTree(root3, packages) {
|
|
|
10301
10512
|
const full = path46.join(dir, entry.name);
|
|
10302
10513
|
let content;
|
|
10303
10514
|
try {
|
|
10304
|
-
if (
|
|
10305
|
-
content =
|
|
10515
|
+
if (fs13.statSync(full).size > MAX_FILE_BYTES2) continue;
|
|
10516
|
+
content = fs13.readFileSync(full, "utf8");
|
|
10306
10517
|
} catch {
|
|
10307
10518
|
continue;
|
|
10308
10519
|
}
|
|
@@ -10670,8 +10881,8 @@ async function fetchLatestVersion() {
|
|
|
10670
10881
|
}
|
|
10671
10882
|
async function writeCache(data) {
|
|
10672
10883
|
try {
|
|
10673
|
-
await
|
|
10674
|
-
await
|
|
10884
|
+
await fs27.mkdir(CACHE_DIR, { recursive: true });
|
|
10885
|
+
await fs27.writeFile(CACHE_FILE, JSON.stringify(data), "utf-8");
|
|
10675
10886
|
} catch {
|
|
10676
10887
|
}
|
|
10677
10888
|
}
|
|
@@ -10709,7 +10920,7 @@ function scheduleDeferredUpdate(command, pid = process.pid, dir = os.tmpdir()) {
|
|
|
10709
10920
|
const scriptPath = path46.join(dir, `vg-update-${stamp}.cmd`);
|
|
10710
10921
|
const logPath = path46.join(dir, `vg-update-${stamp}.log`);
|
|
10711
10922
|
try {
|
|
10712
|
-
|
|
10923
|
+
fs13.writeFileSync(scriptPath, buildDeferredUpdateScript({ pid, command, logPath }), "utf8");
|
|
10713
10924
|
const child = spawn(process.env.ComSpec || "cmd.exe", ["/d", "/s", "/c", scriptPath], {
|
|
10714
10925
|
detached: true,
|
|
10715
10926
|
stdio: "ignore",
|
|
@@ -10733,7 +10944,7 @@ function detectGlobalInstall(execPath = process.argv[1] || "", cwd = process.cwd
|
|
|
10733
10944
|
if (!execPath) return null;
|
|
10734
10945
|
let resolved = execPath;
|
|
10735
10946
|
try {
|
|
10736
|
-
resolved =
|
|
10947
|
+
resolved = fs13.realpathSync(execPath);
|
|
10737
10948
|
} catch {
|
|
10738
10949
|
}
|
|
10739
10950
|
const p = resolved.replace(/\\/g, "/");
|
|
@@ -10877,7 +11088,7 @@ ${String(err)}` }));
|
|
|
10877
11088
|
async function releaseWindowsFileLocks(cwd, keepVersion) {
|
|
10878
11089
|
reapAndReport(cwd, keepVersion);
|
|
10879
11090
|
try {
|
|
10880
|
-
const { vgdSocketPath } = await import('./vgd-
|
|
11091
|
+
const { vgdSocketPath } = await import('./vgd-M7UOPWLB.js');
|
|
10881
11092
|
const result = await stopVgd(vgdSocketPath());
|
|
10882
11093
|
if (result === "stopped") {
|
|
10883
11094
|
console.log(chalk7.dim("Stopped the vgd daemon so its files can be replaced \u2014 it restarts on the next command."));
|
|
@@ -10930,6 +11141,7 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
|
|
|
10930
11141
|
if (!semver4.gt(latest, VERSION)) {
|
|
10931
11142
|
console.log(chalk7.green("\u2714") + ` You are on the latest version (${VERSION}).`);
|
|
10932
11143
|
if (opts.reap !== false) reapAndReport(process.cwd(), VERSION);
|
|
11144
|
+
if (opts.reap !== false) await reconcileVgdAndReport(process.cwd());
|
|
10933
11145
|
return;
|
|
10934
11146
|
}
|
|
10935
11147
|
console.log(chalk7.yellow(`Update available: ${VERSION} \u2192 ${latest}`));
|
|
@@ -10992,7 +11204,7 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
|
|
|
10992
11204
|
process.exit(1);
|
|
10993
11205
|
}
|
|
10994
11206
|
if (opts.reap !== false) reapAndReport(cwd, latest);
|
|
10995
|
-
if (opts.reap !== false) await restartVgdAndReport();
|
|
11207
|
+
if (opts.reap !== false) await restartVgdAndReport({ force: true });
|
|
10996
11208
|
try {
|
|
10997
11209
|
clearEmbedderHealth();
|
|
10998
11210
|
} catch {
|
|
@@ -11002,10 +11214,10 @@ var updateCommand = new Command("update").description("Update vibgrate to the la
|
|
|
11002
11214
|
);
|
|
11003
11215
|
async function rewarmVgdAndReport(cwd) {
|
|
11004
11216
|
try {
|
|
11005
|
-
const { vgdIsRunning, vgdRequest } = await import('./vgd-
|
|
11217
|
+
const { vgdIsRunning, vgdRequest } = await import('./vgd-M7UOPWLB.js');
|
|
11006
11218
|
if (!await vgdIsRunning()) return;
|
|
11007
11219
|
const loaded = await vgdRequest({ op: "load-graph", root: cwd });
|
|
11008
|
-
if (!loaded.ok || !("
|
|
11220
|
+
if (!loaded.ok || !("stored" in loaded)) return;
|
|
11009
11221
|
console.log(chalk7.dim("Re-published the code map into the restarted daemon."));
|
|
11010
11222
|
const indexed = await vgdRequest({ op: "embed-index", repositoryId: loaded.repositoryId });
|
|
11011
11223
|
if (indexed.ok && "vectors" in indexed && indexed.state === "ready") {
|
|
@@ -11014,10 +11226,30 @@ async function rewarmVgdAndReport(cwd) {
|
|
|
11014
11226
|
} catch {
|
|
11015
11227
|
}
|
|
11016
11228
|
}
|
|
11017
|
-
async function
|
|
11229
|
+
async function reconcileVgdAndReport(cwd) {
|
|
11230
|
+
let skew;
|
|
11231
|
+
try {
|
|
11232
|
+
skew = await vgdVersionSkew();
|
|
11233
|
+
} catch {
|
|
11234
|
+
return;
|
|
11235
|
+
}
|
|
11236
|
+
if (!skew.running || skew.state === "match") return;
|
|
11237
|
+
if (skew.state === "newer") {
|
|
11238
|
+
console.log(chalk7.dim(`A newer vgd (${skew.version}) is running \u2014 left alone.`));
|
|
11239
|
+
return;
|
|
11240
|
+
}
|
|
11241
|
+
console.log(
|
|
11242
|
+
chalk7.yellow("Stale daemon: ") + chalk7.dim(
|
|
11243
|
+
`vgd is running ${skew.version ?? "a build older than 2026.817"}, not ${VERSION} \u2014 restarting it on this build.`
|
|
11244
|
+
)
|
|
11245
|
+
);
|
|
11246
|
+
await restartVgdAndReport({ force: true });
|
|
11247
|
+
await rewarmVgdAndReport(cwd);
|
|
11248
|
+
}
|
|
11249
|
+
async function restartVgdAndReport(opts = {}) {
|
|
11018
11250
|
let result;
|
|
11019
11251
|
try {
|
|
11020
|
-
result = await restartVgdIfRunning();
|
|
11252
|
+
result = await restartVgdIfRunning(void 0, opts);
|
|
11021
11253
|
} catch {
|
|
11022
11254
|
return;
|
|
11023
11255
|
}
|
|
@@ -11771,6 +12003,7 @@ function formatArchitectureDiagram(arch) {
|
|
|
11771
12003
|
lines.push("");
|
|
11772
12004
|
if (arch.layers.length > 0) {
|
|
11773
12005
|
for (const layer of arch.layers) {
|
|
12006
|
+
if (layer.fileCount === 0) continue;
|
|
11774
12007
|
const risk = layer.riskLevel === "none" ? chalk7.dim("none") : layer.riskLevel === "low" ? chalk7.green("low") : layer.riskLevel === "moderate" ? chalk7.yellow("moderate") : chalk7.red("high");
|
|
11775
12008
|
lines.push(` ${chalk7.bold(layer.layer)} ${layer.fileCount} file${layer.fileCount !== 1 ? "s" : ""} drift ${scoreBar(layer.driftScore)} risk ${risk}`);
|
|
11776
12009
|
}
|
|
@@ -11778,12 +12011,27 @@ function formatArchitectureDiagram(arch) {
|
|
|
11778
12011
|
}
|
|
11779
12012
|
if (arch.violations && arch.violations.length > 0) {
|
|
11780
12013
|
const extra = arch.violationsCapped ? "+" : "";
|
|
11781
|
-
|
|
11782
|
-
|
|
11783
|
-
|
|
12014
|
+
const boundary = arch.violations.filter((v) => !v.rule.startsWith("graph-conflict:"));
|
|
12015
|
+
const conflicts = arch.violations.filter((v) => v.rule.startsWith("graph-conflict:"));
|
|
12016
|
+
if (boundary.length > 0) {
|
|
12017
|
+
const cap = extra && conflicts.length === 0 ? extra : "";
|
|
12018
|
+
lines.push(` Boundary violations (${boundary.length}${cap})`);
|
|
12019
|
+
for (const v of boundary.slice(0, 8)) {
|
|
12020
|
+
lines.push(` ${v.fromFile} \u2192 ${v.toFile} ${v.rule}`);
|
|
12021
|
+
}
|
|
12022
|
+
if (boundary.length > 8) {
|
|
12023
|
+
lines.push(chalk7.dim(` + ${boundary.length - 8} more`));
|
|
12024
|
+
}
|
|
11784
12025
|
}
|
|
11785
|
-
if (
|
|
11786
|
-
|
|
12026
|
+
if (conflicts.length > 0) {
|
|
12027
|
+
const cap = extra ? extra : "";
|
|
12028
|
+
lines.push(` Layer conflicts (${conflicts.length}${cap})`);
|
|
12029
|
+
for (const v of conflicts.slice(0, 8)) {
|
|
12030
|
+
lines.push(` ${v.fromFile} \u2192 ${v.toFile} ${v.rule}`);
|
|
12031
|
+
}
|
|
12032
|
+
if (conflicts.length > 8) {
|
|
12033
|
+
lines.push(chalk7.dim(` + ${conflicts.length - 8} more`));
|
|
12034
|
+
}
|
|
11787
12035
|
}
|
|
11788
12036
|
lines.push("");
|
|
11789
12037
|
}
|
|
@@ -12446,7 +12694,7 @@ var LOCALE_CONFIG_FILENAMES = ["vibgrate.locale.yaml", ".vibgrate/locale.yaml"];
|
|
|
12446
12694
|
function findLocaleConfig(cwd) {
|
|
12447
12695
|
for (const name of LOCALE_CONFIG_FILENAMES) {
|
|
12448
12696
|
const candidate = path46.join(cwd, name);
|
|
12449
|
-
if (
|
|
12697
|
+
if (fs13.existsSync(candidate)) return candidate;
|
|
12450
12698
|
}
|
|
12451
12699
|
return null;
|
|
12452
12700
|
}
|
|
@@ -12474,7 +12722,7 @@ function loadLocaleConfig(cwd) {
|
|
|
12474
12722
|
const file = findLocaleConfig(cwd);
|
|
12475
12723
|
if (!file) return { config: {}, file: null };
|
|
12476
12724
|
try {
|
|
12477
|
-
return { config: parseLocaleConfig(
|
|
12725
|
+
return { config: parseLocaleConfig(fs13.readFileSync(file, "utf8")), file };
|
|
12478
12726
|
} catch (error) {
|
|
12479
12727
|
throw new Error(
|
|
12480
12728
|
`Could not parse ${path46.relative(cwd, file)}: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -12493,8 +12741,8 @@ function serializeLocaleConfig(config) {
|
|
|
12493
12741
|
}
|
|
12494
12742
|
function writeLocaleConfig(cwd, config, filename) {
|
|
12495
12743
|
const target = filename ?? path46.join(cwd, LOCALE_CONFIG_FILENAMES[0]);
|
|
12496
|
-
|
|
12497
|
-
|
|
12744
|
+
fs13.mkdirSync(path46.dirname(target), { recursive: true });
|
|
12745
|
+
fs13.writeFileSync(target, serializeLocaleConfig(config), "utf8");
|
|
12498
12746
|
return target;
|
|
12499
12747
|
}
|
|
12500
12748
|
function resolveLocaleSettings(config, flags) {
|
|
@@ -12652,14 +12900,14 @@ function resolveLocaleFiles(cwd, template, languages, namespaces) {
|
|
|
12652
12900
|
for (const namespace of namespaces) {
|
|
12653
12901
|
const relative13 = renderPath(template, language, namespace);
|
|
12654
12902
|
const file = path46.resolve(cwd, relative13);
|
|
12655
|
-
out2.push({ language, namespace, file, relative: relative13, exists:
|
|
12903
|
+
out2.push({ language, namespace, file, relative: relative13, exists: fs13.existsSync(file) });
|
|
12656
12904
|
}
|
|
12657
12905
|
}
|
|
12658
12906
|
return out2;
|
|
12659
12907
|
}
|
|
12660
12908
|
function readCatalog(file, format) {
|
|
12661
|
-
if (!
|
|
12662
|
-
const text =
|
|
12909
|
+
if (!fs13.existsSync(file)) return {};
|
|
12910
|
+
const text = fs13.readFileSync(file, "utf8");
|
|
12663
12911
|
try {
|
|
12664
12912
|
return codecFor(format).decode(text);
|
|
12665
12913
|
} catch (error) {
|
|
@@ -12670,11 +12918,11 @@ function readCatalog(file, format) {
|
|
|
12670
12918
|
}
|
|
12671
12919
|
function writeCatalog(file, format, catalog, opts = {}) {
|
|
12672
12920
|
const encoded = codecFor(format).encode(sortKeys(catalog));
|
|
12673
|
-
const existing =
|
|
12921
|
+
const existing = fs13.existsSync(file) ? fs13.readFileSync(file, "utf8") : null;
|
|
12674
12922
|
const changed = existing !== encoded;
|
|
12675
12923
|
if (changed && !opts.dryRun) {
|
|
12676
|
-
|
|
12677
|
-
|
|
12924
|
+
fs13.mkdirSync(path46.dirname(file), { recursive: true });
|
|
12925
|
+
fs13.writeFileSync(file, encoded, "utf8");
|
|
12678
12926
|
}
|
|
12679
12927
|
return { file, changed, bytes: Buffer.byteLength(encoded, "utf8") };
|
|
12680
12928
|
}
|
|
@@ -14357,17 +14605,17 @@ function resolveSigningKey(root3, explicit) {
|
|
|
14357
14605
|
const chosen = process.env.VG_ATTEST_KEY;
|
|
14358
14606
|
const keyPath = chosen ? path46.resolve(chosen) : path46.join(root3, ".vibgrate", DEFAULT_KEY);
|
|
14359
14607
|
let minted = false;
|
|
14360
|
-
if (!
|
|
14608
|
+
if (!fs13.existsSync(keyPath)) {
|
|
14361
14609
|
if (chosen) throw new CliError(`signing key not found: ${chosen}`, ExitCode.USAGE_ERROR);
|
|
14362
14610
|
const kp = generateKeypair();
|
|
14363
|
-
|
|
14364
|
-
|
|
14365
|
-
|
|
14611
|
+
fs13.mkdirSync(path46.dirname(keyPath), { recursive: true });
|
|
14612
|
+
fs13.writeFileSync(keyPath, kp.privatePem, { mode: 384 });
|
|
14613
|
+
fs13.writeFileSync(`${keyPath}.pub`, kp.publicPem);
|
|
14366
14614
|
minted = true;
|
|
14367
14615
|
}
|
|
14368
14616
|
let key2;
|
|
14369
14617
|
try {
|
|
14370
|
-
key2 = crypto3.createPrivateKey(
|
|
14618
|
+
key2 = crypto3.createPrivateKey(fs13.readFileSync(keyPath, "utf8"));
|
|
14371
14619
|
} catch {
|
|
14372
14620
|
throw new CliError(`could not read an Ed25519 private key from ${keyPath}`, ExitCode.USAGE_ERROR);
|
|
14373
14621
|
}
|
|
@@ -14378,8 +14626,8 @@ function resolveSigningKey(root3, explicit) {
|
|
|
14378
14626
|
}
|
|
14379
14627
|
function writeBundle(input) {
|
|
14380
14628
|
const dir = input.outDir;
|
|
14381
|
-
|
|
14382
|
-
const write = (rel, data) =>
|
|
14629
|
+
fs13.mkdirSync(path46.join(dir, "inputs", "releases"), { recursive: true });
|
|
14630
|
+
const write = (rel, data) => fs13.writeFileSync(path46.join(dir, rel), `${JSON.stringify(data, null, 2)}
|
|
14383
14631
|
`);
|
|
14384
14632
|
write("result.json", input.result);
|
|
14385
14633
|
write(path46.join("inputs", "advisory.json"), input.advisory);
|
|
@@ -14403,13 +14651,13 @@ function writeBundle(input) {
|
|
|
14403
14651
|
disclaimer: input.regime.disclaimer
|
|
14404
14652
|
});
|
|
14405
14653
|
if (input.envelope) {
|
|
14406
|
-
|
|
14654
|
+
fs13.writeFileSync(path46.join(dir, "evidence.intoto.jsonl"), `${JSON.stringify(input.envelope)}
|
|
14407
14655
|
`);
|
|
14408
14656
|
}
|
|
14409
14657
|
if (input.timestampToken) {
|
|
14410
|
-
|
|
14658
|
+
fs13.writeFileSync(path46.join(dir, "timestamp.tsr"), input.timestampToken);
|
|
14411
14659
|
}
|
|
14412
|
-
|
|
14660
|
+
fs13.writeFileSync(path46.join(dir, "VERIFY.md"), verifyDoc(input));
|
|
14413
14661
|
return dir;
|
|
14414
14662
|
}
|
|
14415
14663
|
function verifyDoc(input) {
|
|
@@ -14752,7 +15000,7 @@ var packCmd = new Command("pack").description("Build the submission pack a human
|
|
|
14752
15000
|
const stage = opts.stage ?? regime.clocks[0]?.stage ?? "early-warning";
|
|
14753
15001
|
const md = buildPack(result, regime, org, stage);
|
|
14754
15002
|
if (opts.out) {
|
|
14755
|
-
|
|
15003
|
+
fs13.writeFileSync(path46.resolve(rootDir, opts.out), md);
|
|
14756
15004
|
console.error(chalk7.green("\u2714") + ` pack written to ${opts.out}`);
|
|
14757
15005
|
} else {
|
|
14758
15006
|
console.log(md);
|
|
@@ -14795,19 +15043,19 @@ var drillCmd = new Command("drill").description("Timed dry-run of the determinat
|
|
|
14795
15043
|
});
|
|
14796
15044
|
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
15045
|
const abs = path46.resolve(bundlePath);
|
|
14798
|
-
const envPath =
|
|
14799
|
-
if (!
|
|
14800
|
-
const envelope = JSON.parse(
|
|
15046
|
+
const envPath = fs13.statSync(abs).isDirectory() ? path46.join(abs, "evidence.intoto.jsonl") : abs;
|
|
15047
|
+
if (!fs13.existsSync(envPath)) throw new CliError(`no evidence.intoto.jsonl at ${bundlePath}`, ExitCode.NOT_FOUND);
|
|
15048
|
+
const envelope = JSON.parse(fs13.readFileSync(envPath, "utf8").trim().split("\n")[0]);
|
|
14801
15049
|
const resultPath = path46.join(path46.dirname(envPath), "result.json");
|
|
14802
|
-
const result =
|
|
14803
|
-
const publicKeyPem = opts.pub ?
|
|
15050
|
+
const result = fs13.existsSync(resultPath) ? JSON.parse(fs13.readFileSync(resultPath, "utf8")) : void 0;
|
|
15051
|
+
const publicKeyPem = opts.pub ? fs13.readFileSync(path46.resolve(opts.pub), "utf8") : void 0;
|
|
14804
15052
|
const v = verifyEvidenceEnvelope(envelope, { publicKeyPem, result });
|
|
14805
15053
|
const color = v.status === "verified" ? chalk7.green : v.status === "failed" ? chalk7.red : chalk7.yellow;
|
|
14806
15054
|
console.log(" " + color(v.status.toUpperCase()) + ` ${v.reason}`);
|
|
14807
15055
|
if (v.evidenceId) console.log(" " + chalk7.dim(`evidence ${v.evidenceId} \xB7 regime ${v.regime} \xB7 advisory ${v.advisoryId} \xB7 ${v.overallStatus}`));
|
|
14808
15056
|
const tsrPath = path46.join(path46.dirname(envPath), "timestamp.tsr");
|
|
14809
|
-
if (
|
|
14810
|
-
const t = verifyTimestamp(
|
|
15057
|
+
if (fs13.existsSync(tsrPath) && result) {
|
|
15058
|
+
const t = verifyTimestamp(fs13.readFileSync(tsrPath), exposureSubjectDigest(result));
|
|
14811
15059
|
const tcolor = t.imprintMatches ? chalk7.green : chalk7.red;
|
|
14812
15060
|
console.log(" " + tcolor("TIMESTAMP") + ` ${t.reason}`);
|
|
14813
15061
|
}
|
|
@@ -14906,9 +15154,9 @@ var pushCmd = new Command("push").description("Push the product registry (and an
|
|
|
14906
15154
|
let exposure;
|
|
14907
15155
|
if (opts.result) {
|
|
14908
15156
|
const raw = path46.resolve(rootDir, opts.result);
|
|
14909
|
-
const resultPath =
|
|
14910
|
-
if (!
|
|
14911
|
-
exposure = JSON.parse(
|
|
15157
|
+
const resultPath = fs13.existsSync(raw) && fs13.statSync(raw).isDirectory() ? path46.join(raw, "result.json") : raw;
|
|
15158
|
+
if (!fs13.existsSync(resultPath)) throw new CliError(`no result.json at ${opts.result}`, ExitCode.NOT_FOUND);
|
|
15159
|
+
exposure = JSON.parse(fs13.readFileSync(resultPath, "utf8"));
|
|
14912
15160
|
}
|
|
14913
15161
|
const payload = { schemaVersion: "evidence-push-1", regime: regime.id, generatedAt: nowIso(), signed: Boolean(opts.signed), products: productPayload, exposure };
|
|
14914
15162
|
const body = JSON.stringify(payload);
|
|
@@ -15107,7 +15355,7 @@ function dispatch(argv, cwd) {
|
|
|
15107
15355
|
}
|
|
15108
15356
|
const looksLikeQuestion = /\s/.test(first) || first.endsWith("?");
|
|
15109
15357
|
if (looksLikeQuestion) return ["ask", ...args];
|
|
15110
|
-
if (
|
|
15358
|
+
if (fs13.existsSync(path46.resolve(cwd, first))) {
|
|
15111
15359
|
return [hasBuildOnlyFlag(args) ? "build" : "scan", ...args];
|
|
15112
15360
|
}
|
|
15113
15361
|
const moved = MOVED_COMMANDS[first];
|