@vibgrate/cli 2026.711.1 → 2026.715.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DOCS.md +77 -11
- package/README.md +16 -12
- package/dist/baseline-BTLZWSNS.js +6 -0
- package/dist/{baseline-V5XGS76K.js.map → baseline-BTLZWSNS.js.map} +1 -1
- package/dist/{chunk-3BWPEPWH.js → chunk-6DKWB2OI.js} +628 -4
- package/dist/chunk-6DKWB2OI.js.map +1 -0
- package/dist/{chunk-2PCL4ZME.js → chunk-C5AVF7PT.js} +306 -70
- package/dist/chunk-C5AVF7PT.js.map +1 -0
- package/dist/{chunk-MIJ3ZSSF.js → chunk-D4BPWARI.js} +260 -92
- package/dist/chunk-D4BPWARI.js.map +1 -0
- package/dist/{chunk-X5YT263H.js → chunk-VFO5UDAT.js} +21 -2
- package/dist/chunk-VFO5UDAT.js.map +1 -0
- package/dist/cli.js +1016 -97
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +20 -6
- package/dist/index.js +3 -3
- package/dist/parse-worker.d.ts +1 -1
- package/dist/parse-worker.js +2 -1
- package/dist/parse-worker.js.map +1 -1
- package/dist/{types-CXnp1uGj.d.ts → types-BgNa-FZQ.d.ts} +8 -0
- package/package.json +2 -2
- package/skills/README.md +2 -2
- package/dist/baseline-V5XGS76K.js +0 -6
- package/dist/chunk-2PCL4ZME.js.map +0 -1
- package/dist/chunk-3BWPEPWH.js.map +0 -1
- package/dist/chunk-MIJ3ZSSF.js.map +0 -1
- package/dist/chunk-X5YT263H.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { hashString, langById, shortId, canonicalize, grammarSetVersion, hashBytes, langForExtension, setGrammarsOverride, parseSource } from './chunk-
|
|
2
|
-
import { writeTextFile, pathExists, readJsonFile, computeUpgradeImpact, getChangelogSignals, gitHistoryAvailable, buildVersionTimelines, findPackageTimeline, severityRank, projectTypeToVulnEcosystem, VERSION } from './chunk-
|
|
1
|
+
import { hashString, langById, shortId, canonicalize, grammarSetVersion, hashBytes, langForExtension, setGrammarsOverride, parseSource } from './chunk-VFO5UDAT.js';
|
|
2
|
+
import { writeTextFile, pathExists, readJsonFile, loadConfig, computeUpgradeImpact, getChangelogSignals, gitHistoryAvailable, buildVersionTimelines, findPackageTimeline, severityRank, projectTypeToVulnEcosystem, VERSION } from './chunk-C5AVF7PT.js';
|
|
3
3
|
import * as fs19 from 'fs';
|
|
4
4
|
import { spawnSync, execFileSync } from 'child_process';
|
|
5
5
|
import * as path19 from 'path';
|
|
@@ -15,6 +15,7 @@ import { fileURLToPath } from 'url';
|
|
|
15
15
|
import ts from 'typescript';
|
|
16
16
|
import { bidirectional } from 'graphology-shortest-path/unweighted.js';
|
|
17
17
|
import * as crypto from 'crypto';
|
|
18
|
+
import { createHash } from 'crypto';
|
|
18
19
|
import { Command } from 'commander';
|
|
19
20
|
import chalk from 'chalk';
|
|
20
21
|
import * as zlib from 'zlib';
|
|
@@ -702,6 +703,73 @@ function edgeId(kind, src, dst) {
|
|
|
702
703
|
return shortId(canonicalize({ t: "edge", kind, src, dst }));
|
|
703
704
|
}
|
|
704
705
|
|
|
706
|
+
// src/engine/tests.ts
|
|
707
|
+
function isTestFile(rel2) {
|
|
708
|
+
const lower = rel2.toLowerCase();
|
|
709
|
+
const base = rel2.split("/").pop() ?? rel2;
|
|
710
|
+
const lbase = base.toLowerCase();
|
|
711
|
+
if (/(^|\/)(__tests__|__test__)\//.test(lower)) return true;
|
|
712
|
+
if (/(^|\/)(tests?|spec|specs)\//.test(lower)) return true;
|
|
713
|
+
if (/(^|\/)src\/test\//.test(lower)) return true;
|
|
714
|
+
if (/\.(test|spec)\.[cm]?[jt]sx?$/.test(lbase)) return true;
|
|
715
|
+
if (/^test_.*\.py$/.test(lbase) || /_test\.py$/.test(lbase)) return true;
|
|
716
|
+
if (/_test\.go$/.test(lbase)) return true;
|
|
717
|
+
if (/[A-Za-z0-9](Test|Tests|IT)\.java$/.test(base)) return true;
|
|
718
|
+
if (/_spec\.rb$/.test(lbase) || /_test\.rb$/.test(lbase)) return true;
|
|
719
|
+
if (/[A-Za-z0-9](Test|Tests)\.cs$/.test(base)) return true;
|
|
720
|
+
if (/[A-Za-z0-9](Test|Tests)\.swift$/.test(base)) return true;
|
|
721
|
+
return false;
|
|
722
|
+
}
|
|
723
|
+
function applyStaticTestLinkage(nodes, edges) {
|
|
724
|
+
const byId = new Map(nodes.map((n) => [n.id, n]));
|
|
725
|
+
const testFiles = /* @__PURE__ */ new Set();
|
|
726
|
+
for (const n of nodes) if (n.kind === "file" && isTestFile(n.file)) testFiles.add(n.file);
|
|
727
|
+
const fileNodeIdByRel = /* @__PURE__ */ new Map();
|
|
728
|
+
for (const n of nodes) if (n.kind === "file") fileNodeIdByRel.set(n.file, n.id);
|
|
729
|
+
const covered = /* @__PURE__ */ new Set();
|
|
730
|
+
const newEdges = /* @__PURE__ */ new Map();
|
|
731
|
+
for (const e of edges) {
|
|
732
|
+
if (e.kind !== "call") continue;
|
|
733
|
+
const src = byId.get(e.src);
|
|
734
|
+
const dst = byId.get(e.dst);
|
|
735
|
+
if (!src || !dst) continue;
|
|
736
|
+
if (testFiles.has(src.file) && !testFiles.has(dst.file) && dst.kind !== "external") {
|
|
737
|
+
const testFileId = fileNodeIdByRel.get(src.file);
|
|
738
|
+
if (!testFileId) continue;
|
|
739
|
+
const id = edgeId("test", testFileId, dst.id);
|
|
740
|
+
if (!newEdges.has(id)) {
|
|
741
|
+
newEdges.set(id, {
|
|
742
|
+
id,
|
|
743
|
+
kind: "test",
|
|
744
|
+
src: testFileId,
|
|
745
|
+
dst: dst.id,
|
|
746
|
+
resolution: e.resolution,
|
|
747
|
+
confidence: e.confidence
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
covered.add(dst.id);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
const outNodes = nodes.map((n) => ({ ...n, tested: testedFlag(n, covered.has(n.id), testFiles) }));
|
|
754
|
+
const outEdges = [...edges, ...newEdges.values()].sort(
|
|
755
|
+
(a, b) => a.kind.localeCompare(b.kind) || a.src.localeCompare(b.src) || a.dst.localeCompare(b.dst)
|
|
756
|
+
);
|
|
757
|
+
return {
|
|
758
|
+
nodes: outNodes,
|
|
759
|
+
edges: outEdges,
|
|
760
|
+
testFiles: [...testFiles].sort(),
|
|
761
|
+
testEdgeCount: newEdges.size
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
function testedFlag(node, covered, testFiles) {
|
|
765
|
+
if (node.kind === "external" || node.kind === "file" || node.kind === "package" || node.kind === "module") {
|
|
766
|
+
return null;
|
|
767
|
+
}
|
|
768
|
+
if (testFiles.has(node.file)) return null;
|
|
769
|
+
if (node.kind === "function" || node.kind === "method") return covered;
|
|
770
|
+
return covered ? true : node.tested ?? null;
|
|
771
|
+
}
|
|
772
|
+
|
|
705
773
|
// src/engine/scip.ts
|
|
706
774
|
var ROLE_DEFINITION = 1;
|
|
707
775
|
var Reader = class {
|
|
@@ -1064,72 +1132,6 @@ function round(x) {
|
|
|
1064
1132
|
function pairKey(a, b) {
|
|
1065
1133
|
return a < b ? `${a}|${b}` : `${b}|${a}`;
|
|
1066
1134
|
}
|
|
1067
|
-
|
|
1068
|
-
// src/engine/tests.ts
|
|
1069
|
-
function isTestFile(rel2) {
|
|
1070
|
-
const lower = rel2.toLowerCase();
|
|
1071
|
-
const base = rel2.split("/").pop() ?? rel2;
|
|
1072
|
-
const lbase = base.toLowerCase();
|
|
1073
|
-
if (/(^|\/)(__tests__|__test__)\//.test(lower)) return true;
|
|
1074
|
-
if (/(^|\/)(tests?|spec|specs)\//.test(lower)) return true;
|
|
1075
|
-
if (/(^|\/)src\/test\//.test(lower)) return true;
|
|
1076
|
-
if (/\.(test|spec)\.[cm]?[jt]sx?$/.test(lbase)) return true;
|
|
1077
|
-
if (/^test_.*\.py$/.test(lbase) || /_test\.py$/.test(lbase)) return true;
|
|
1078
|
-
if (/_test\.go$/.test(lbase)) return true;
|
|
1079
|
-
if (/[A-Za-z0-9](Test|Tests|IT)\.java$/.test(base)) return true;
|
|
1080
|
-
if (/_spec\.rb$/.test(lbase) || /_test\.rb$/.test(lbase)) return true;
|
|
1081
|
-
if (/[A-Za-z0-9](Test|Tests)\.cs$/.test(base)) return true;
|
|
1082
|
-
return false;
|
|
1083
|
-
}
|
|
1084
|
-
function applyStaticTestLinkage(nodes, edges) {
|
|
1085
|
-
const byId = new Map(nodes.map((n) => [n.id, n]));
|
|
1086
|
-
const testFiles = /* @__PURE__ */ new Set();
|
|
1087
|
-
for (const n of nodes) if (n.kind === "file" && isTestFile(n.file)) testFiles.add(n.file);
|
|
1088
|
-
const fileNodeIdByRel = /* @__PURE__ */ new Map();
|
|
1089
|
-
for (const n of nodes) if (n.kind === "file") fileNodeIdByRel.set(n.file, n.id);
|
|
1090
|
-
const covered = /* @__PURE__ */ new Set();
|
|
1091
|
-
const newEdges = /* @__PURE__ */ new Map();
|
|
1092
|
-
for (const e of edges) {
|
|
1093
|
-
if (e.kind !== "call") continue;
|
|
1094
|
-
const src = byId.get(e.src);
|
|
1095
|
-
const dst = byId.get(e.dst);
|
|
1096
|
-
if (!src || !dst) continue;
|
|
1097
|
-
if (testFiles.has(src.file) && !testFiles.has(dst.file) && dst.kind !== "external") {
|
|
1098
|
-
const testFileId = fileNodeIdByRel.get(src.file);
|
|
1099
|
-
if (!testFileId) continue;
|
|
1100
|
-
const id = edgeId("test", testFileId, dst.id);
|
|
1101
|
-
if (!newEdges.has(id)) {
|
|
1102
|
-
newEdges.set(id, {
|
|
1103
|
-
id,
|
|
1104
|
-
kind: "test",
|
|
1105
|
-
src: testFileId,
|
|
1106
|
-
dst: dst.id,
|
|
1107
|
-
resolution: e.resolution,
|
|
1108
|
-
confidence: e.confidence
|
|
1109
|
-
});
|
|
1110
|
-
}
|
|
1111
|
-
covered.add(dst.id);
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
const outNodes = nodes.map((n) => ({ ...n, tested: testedFlag(n, covered.has(n.id), testFiles) }));
|
|
1115
|
-
const outEdges = [...edges, ...newEdges.values()].sort(
|
|
1116
|
-
(a, b) => a.kind.localeCompare(b.kind) || a.src.localeCompare(b.src) || a.dst.localeCompare(b.dst)
|
|
1117
|
-
);
|
|
1118
|
-
return {
|
|
1119
|
-
nodes: outNodes,
|
|
1120
|
-
edges: outEdges,
|
|
1121
|
-
testFiles: [...testFiles].sort(),
|
|
1122
|
-
testEdgeCount: newEdges.size
|
|
1123
|
-
};
|
|
1124
|
-
}
|
|
1125
|
-
function testedFlag(node, covered, testFiles) {
|
|
1126
|
-
if (node.kind === "external" || node.kind === "file" || node.kind === "package" || node.kind === "module") {
|
|
1127
|
-
return null;
|
|
1128
|
-
}
|
|
1129
|
-
if (testFiles.has(node.file)) return null;
|
|
1130
|
-
if (node.kind === "function" || node.kind === "method") return covered;
|
|
1131
|
-
return covered ? true : node.tested ?? null;
|
|
1132
|
-
}
|
|
1133
1135
|
var DEFAULT_PATHS = [
|
|
1134
1136
|
"coverage/lcov.info",
|
|
1135
1137
|
"lcov.info",
|
|
@@ -1569,6 +1571,7 @@ function emptyParse(file, warning) {
|
|
|
1569
1571
|
calls: [],
|
|
1570
1572
|
imports: [],
|
|
1571
1573
|
heritage: [],
|
|
1574
|
+
typeRefs: [],
|
|
1572
1575
|
guards: [],
|
|
1573
1576
|
warnings: [warning]
|
|
1574
1577
|
};
|
|
@@ -1666,9 +1669,10 @@ function resolve4(parses, resolver) {
|
|
|
1666
1669
|
const fileId = fileNodeIdByRel.get(p.rel);
|
|
1667
1670
|
const localDefs = defsByFile.get(p.rel) ?? [];
|
|
1668
1671
|
const imported = importedFilesByRel.get(p.rel) ?? /* @__PURE__ */ new Set();
|
|
1672
|
+
const testCaller = isTestFile(p.rel);
|
|
1669
1673
|
for (const call of p.calls) {
|
|
1670
1674
|
const srcId = enclosingDefId(localDefs, call.byte) ?? fileId;
|
|
1671
|
-
const resolved = resolveCall(call, p.rel, p.lang, imported, defsByName, srcId);
|
|
1675
|
+
const resolved = resolveCall(call, p.rel, p.lang, imported, defsByName, srcId, testCaller);
|
|
1672
1676
|
if (resolved) {
|
|
1673
1677
|
edges.add("call", srcId, resolved.id, "heuristic", resolved.confidence);
|
|
1674
1678
|
stats.callsResolved++;
|
|
@@ -1678,13 +1682,25 @@ function resolve4(parses, resolver) {
|
|
|
1678
1682
|
}
|
|
1679
1683
|
}
|
|
1680
1684
|
}
|
|
1685
|
+
for (const p of parses) {
|
|
1686
|
+
const fileId = fileNodeIdByRel.get(p.rel);
|
|
1687
|
+
const localDefs = defsByFile.get(p.rel) ?? [];
|
|
1688
|
+
const imported = importedFilesByRel.get(p.rel) ?? /* @__PURE__ */ new Set();
|
|
1689
|
+
const testCaller = isTestFile(p.rel);
|
|
1690
|
+
for (const ref of p.typeRefs) {
|
|
1691
|
+
const srcId = enclosingDefId(localDefs, ref.byte) ?? fileId;
|
|
1692
|
+
const target = resolveType(ref.name, p.rel, p.lang, imported, defsByName, testCaller);
|
|
1693
|
+
if (target) edges.add("references", srcId, target.id, "heuristic", 0.7);
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1681
1696
|
for (const p of parses) {
|
|
1682
1697
|
const localDefs = defsByFile.get(p.rel) ?? [];
|
|
1683
1698
|
const imported = importedFilesByRel.get(p.rel) ?? /* @__PURE__ */ new Set();
|
|
1699
|
+
const testCaller = isTestFile(p.rel);
|
|
1684
1700
|
for (const h of p.heritage) {
|
|
1685
1701
|
const srcId = enclosingDefId(localDefs, h.byte);
|
|
1686
1702
|
if (!srcId) continue;
|
|
1687
|
-
const target = resolveType(h.superName, p.rel, p.lang, imported, defsByName);
|
|
1703
|
+
const target = resolveType(h.superName, p.rel, p.lang, imported, defsByName, testCaller);
|
|
1688
1704
|
if (target) edges.add(h.kind, srcId, target.id, "heuristic", 0.85);
|
|
1689
1705
|
else bumpUnresolved(unresolved2, srcId, h.superName, h.kind, p.rel);
|
|
1690
1706
|
}
|
|
@@ -1749,7 +1765,7 @@ function dirOf(rel2) {
|
|
|
1749
1765
|
const i = rel2.lastIndexOf("/");
|
|
1750
1766
|
return i >= 0 ? rel2.slice(0, i) : "";
|
|
1751
1767
|
}
|
|
1752
|
-
function resolveCall(call, fromRel, fromLang, importedRels, defsByName, enclosingId) {
|
|
1768
|
+
function resolveCall(call, fromRel, fromLang, importedRels, defsByName, enclosingId, fromIsTestFile = false) {
|
|
1753
1769
|
const candidates = defsByName.get(call.callee);
|
|
1754
1770
|
if (!candidates || candidates.length === 0) return null;
|
|
1755
1771
|
const callable = candidates.filter((c) => c.kind === "function" || c.kind === "method");
|
|
@@ -1770,9 +1786,12 @@ function resolveCall(call, fromRel, fromLang, importedRels, defsByName, enclosin
|
|
|
1770
1786
|
if (call.qualified && enclosingId) samePkg = samePkg.filter((c) => c.id !== enclosingId);
|
|
1771
1787
|
if (samePkg.length === 1) return { id: samePkg[0].id, confidence: 0.7 };
|
|
1772
1788
|
}
|
|
1789
|
+
if (fromLang === "swift" && fromIsTestFile && pool.length === 1) {
|
|
1790
|
+
return { id: pool[0].id, confidence: 0.5 };
|
|
1791
|
+
}
|
|
1773
1792
|
return null;
|
|
1774
1793
|
}
|
|
1775
|
-
function resolveType(name, fromRel, fromLang, importedRels, defsByName) {
|
|
1794
|
+
function resolveType(name, fromRel, fromLang, importedRels, defsByName, fromIsTestFile = false) {
|
|
1776
1795
|
const candidates = (defsByName.get(name) ?? []).filter(
|
|
1777
1796
|
(c) => c.kind === "class" || c.kind === "interface"
|
|
1778
1797
|
);
|
|
@@ -1787,6 +1806,9 @@ function resolveType(name, fromRel, fromLang, importedRels, defsByName) {
|
|
|
1787
1806
|
const samePkg = candidates.filter((c) => c.lang === fromLang && dirOf(c.rel) === dir);
|
|
1788
1807
|
if (samePkg.length === 1) return { id: samePkg[0].id };
|
|
1789
1808
|
}
|
|
1809
|
+
if (fromLang === "swift" && fromIsTestFile && candidates.length === 1) {
|
|
1810
|
+
return { id: candidates[0].id };
|
|
1811
|
+
}
|
|
1790
1812
|
return null;
|
|
1791
1813
|
}
|
|
1792
1814
|
var EdgeSet = class {
|
|
@@ -2984,13 +3006,19 @@ var GraphIndex = class {
|
|
|
2984
3006
|
node(id) {
|
|
2985
3007
|
return this.nodeById.get(id);
|
|
2986
3008
|
}
|
|
2987
|
-
/**
|
|
3009
|
+
/**
|
|
3010
|
+
* Resolved nodes called by `id` — invocations (`call`) plus structural
|
|
3011
|
+
* dependency references (`references`, e.g. a constructor-injected field's
|
|
3012
|
+
* type), since both represent real usage a caller/impact question cares
|
|
3013
|
+
* about. `references` is otherwise only emitted by the precise SCIP/tsc
|
|
3014
|
+
* rungs and (for Java DI wiring) the heuristic rung — never a guess.
|
|
3015
|
+
*/
|
|
2988
3016
|
callees(id) {
|
|
2989
|
-
return this.resolveTargets(this.out(id
|
|
3017
|
+
return this.resolveTargets(this.out(id).filter(isUsageEdge), "dst");
|
|
2990
3018
|
}
|
|
2991
|
-
/** Resolved nodes that call `id`. */
|
|
3019
|
+
/** Resolved nodes that call or structurally reference `id`. */
|
|
2992
3020
|
callers(id) {
|
|
2993
|
-
return this.resolveTargets(this.in(id
|
|
3021
|
+
return this.resolveTargets(this.in(id).filter(isUsageEdge), "src");
|
|
2994
3022
|
}
|
|
2995
3023
|
resolveTargets(edges, end) {
|
|
2996
3024
|
const out = [];
|
|
@@ -3001,6 +3029,10 @@ var GraphIndex = class {
|
|
|
3001
3029
|
return out;
|
|
3002
3030
|
}
|
|
3003
3031
|
};
|
|
3032
|
+
var USAGE_KINDS = /* @__PURE__ */ new Set(["call", "references"]);
|
|
3033
|
+
function isUsageEdge(e) {
|
|
3034
|
+
return USAGE_KINDS.has(e.kind);
|
|
3035
|
+
}
|
|
3004
3036
|
function push2(map, key, value) {
|
|
3005
3037
|
const list = map.get(key);
|
|
3006
3038
|
if (list) list.push(value);
|
|
@@ -3058,7 +3090,26 @@ var STOPWORDS = /* @__PURE__ */ new Set([
|
|
|
3058
3090
|
"from",
|
|
3059
3091
|
"by",
|
|
3060
3092
|
"at",
|
|
3061
|
-
"as"
|
|
3093
|
+
"as",
|
|
3094
|
+
// Discovery-question scaffolding: words a caller uses to FRAME the ask
|
|
3095
|
+
// ("find the code responsible for X", "I need to modify X, where do I
|
|
3096
|
+
// start?", "explain how X works in this codebase") rather than to name the
|
|
3097
|
+
// target. Left in, these compete on equal footing with the real identifier
|
|
3098
|
+
// terms and can outrank it outright — e.g. "find the code responsible for
|
|
3099
|
+
// deleteAsync" let "find" alone drag in every FindByIdAsync/FindAll method
|
|
3100
|
+
// in the repo, none of them the target (VG-LOCATE-FAILURE-ANALYSIS.md).
|
|
3101
|
+
"find",
|
|
3102
|
+
"code",
|
|
3103
|
+
"responsible",
|
|
3104
|
+
"need",
|
|
3105
|
+
"modify",
|
|
3106
|
+
"me",
|
|
3107
|
+
"implementation",
|
|
3108
|
+
"explain",
|
|
3109
|
+
"works",
|
|
3110
|
+
"codebase",
|
|
3111
|
+
"contains",
|
|
3112
|
+
"file"
|
|
3062
3113
|
]);
|
|
3063
3114
|
function queryGraph(graph, question, options = {}) {
|
|
3064
3115
|
const budget = options.budget ?? 2e3;
|
|
@@ -3114,7 +3165,7 @@ async function queryGraphSemantic(graph, question, options) {
|
|
|
3114
3165
|
function tokenize(q2) {
|
|
3115
3166
|
return [
|
|
3116
3167
|
...new Set(
|
|
3117
|
-
q2.toLowerCase().split(/[
|
|
3168
|
+
q2.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((t) => t.length >= 1 && !STOPWORDS.has(t))
|
|
3118
3169
|
)
|
|
3119
3170
|
];
|
|
3120
3171
|
}
|
|
@@ -3172,7 +3223,7 @@ function termWeights(graph, terms) {
|
|
|
3172
3223
|
}
|
|
3173
3224
|
function identifierParts(name) {
|
|
3174
3225
|
return new Set(
|
|
3175
|
-
name.split(/[
|
|
3226
|
+
name.split(/[^\p{L}\p{N}]+|(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/u).filter(Boolean).map((s) => s.toLowerCase())
|
|
3176
3227
|
);
|
|
3177
3228
|
}
|
|
3178
3229
|
function fuzzyPartMatch(term, parts) {
|
|
@@ -3675,10 +3726,10 @@ var MANIFEST_BY_FILE = {
|
|
|
3675
3726
|
};
|
|
3676
3727
|
function findManifests(root) {
|
|
3677
3728
|
const set = Object.fromEntries(ECOSYSTEMS.map((e) => [e, []]));
|
|
3678
|
-
const
|
|
3729
|
+
const MAX_ENTRIES2 = 2e4;
|
|
3679
3730
|
let scanned = 0;
|
|
3680
3731
|
const walk2 = (dir, depth) => {
|
|
3681
|
-
if (depth > 8 || scanned >
|
|
3732
|
+
if (depth > 8 || scanned > MAX_ENTRIES2) return;
|
|
3682
3733
|
let entries;
|
|
3683
3734
|
try {
|
|
3684
3735
|
entries = fs19.readdirSync(dir, { withFileTypes: true });
|
|
@@ -3687,7 +3738,7 @@ function findManifests(root) {
|
|
|
3687
3738
|
}
|
|
3688
3739
|
for (const e of entries) {
|
|
3689
3740
|
scanned++;
|
|
3690
|
-
if (scanned >
|
|
3741
|
+
if (scanned > MAX_ENTRIES2) break;
|
|
3691
3742
|
if (e.isDirectory()) {
|
|
3692
3743
|
if (!SKIP_DIRS2.has(e.name) && !e.name.startsWith(".")) walk2(path19.join(dir, e.name), depth + 1);
|
|
3693
3744
|
continue;
|
|
@@ -4937,6 +4988,20 @@ function dedupeRoutes(routes) {
|
|
|
4937
4988
|
// src/reporting/utils/compact-artifact.ts
|
|
4938
4989
|
var gzip2 = promisify(zlib.gzip);
|
|
4939
4990
|
var MAX_ITEMS = 50;
|
|
4991
|
+
var MAX_DB_MODELS = 300;
|
|
4992
|
+
var MAX_DB_FIELDS_PER_MODEL = 100;
|
|
4993
|
+
var MAX_DB_MODEL_FILES = 5;
|
|
4994
|
+
var MAX_DB_FILES_SCANNED = 500;
|
|
4995
|
+
var DB_UPLOAD_HARD_CEILING = {
|
|
4996
|
+
maxModels: 2e3,
|
|
4997
|
+
maxFieldsPerModel: 500,
|
|
4998
|
+
maxFilesPerModel: 20,
|
|
4999
|
+
maxFilesScanned: 5e3
|
|
5000
|
+
};
|
|
5001
|
+
function clampCap(configured, fallback, ceiling) {
|
|
5002
|
+
if (typeof configured !== "number" || !Number.isFinite(configured) || configured <= 0) return fallback;
|
|
5003
|
+
return Math.min(Math.floor(configured), ceiling);
|
|
5004
|
+
}
|
|
4940
5005
|
function extractName(entry) {
|
|
4941
5006
|
const match = entry.match(/^(.+?)\s*\(/);
|
|
4942
5007
|
return match ? match[1].trim() : entry.trim();
|
|
@@ -5002,7 +5067,29 @@ function compactAssetBranding(result) {
|
|
|
5002
5067
|
// Don't include logos
|
|
5003
5068
|
};
|
|
5004
5069
|
}
|
|
5005
|
-
function
|
|
5070
|
+
function compactDatabaseSchema(result, caps) {
|
|
5071
|
+
const maxModels = clampCap(caps?.maxModels, MAX_DB_MODELS, DB_UPLOAD_HARD_CEILING.maxModels);
|
|
5072
|
+
const maxFieldsPerModel = clampCap(caps?.maxFieldsPerModel, MAX_DB_FIELDS_PER_MODEL, DB_UPLOAD_HARD_CEILING.maxFieldsPerModel);
|
|
5073
|
+
const maxFilesPerModel = clampCap(caps?.maxFilesPerModel, MAX_DB_MODEL_FILES, DB_UPLOAD_HARD_CEILING.maxFilesPerModel);
|
|
5074
|
+
const maxFilesScanned = clampCap(caps?.maxFilesScanned, MAX_DB_FILES_SCANNED, DB_UPLOAD_HARD_CEILING.maxFilesScanned);
|
|
5075
|
+
return {
|
|
5076
|
+
providers: result.providers.slice(0, MAX_ITEMS),
|
|
5077
|
+
models: result.models.slice(0, maxModels).map((model) => ({
|
|
5078
|
+
...model,
|
|
5079
|
+
fields: model.fields.slice(0, maxFieldsPerModel),
|
|
5080
|
+
files: model.files.slice(0, maxFilesPerModel)
|
|
5081
|
+
})),
|
|
5082
|
+
enums: result.enums.slice(0, MAX_ITEMS),
|
|
5083
|
+
filesScanned: result.filesScanned.slice(0, maxFilesScanned),
|
|
5084
|
+
projects: result.projects.slice(0, MAX_ITEMS).map((project) => ({
|
|
5085
|
+
project: project.project,
|
|
5086
|
+
filesScanned: project.filesScanned.slice(0, MAX_ITEMS),
|
|
5087
|
+
models: project.models.slice(0, MAX_ITEMS),
|
|
5088
|
+
enums: project.enums.slice(0, MAX_ITEMS)
|
|
5089
|
+
}))
|
|
5090
|
+
};
|
|
5091
|
+
}
|
|
5092
|
+
function prepareArtifactForUpload(artifact, opts) {
|
|
5006
5093
|
const compacted = { ...artifact };
|
|
5007
5094
|
if (compacted.extended) {
|
|
5008
5095
|
const ext = { ...compacted.extended };
|
|
@@ -5078,6 +5165,9 @@ function prepareArtifactForUpload(artifact) {
|
|
|
5078
5165
|
duplicatedPackages: ext.dependencyGraph.duplicatedPackages.slice(0, MAX_ITEMS)
|
|
5079
5166
|
};
|
|
5080
5167
|
}
|
|
5168
|
+
if (ext.databaseSchema) {
|
|
5169
|
+
ext.databaseSchema = compactDatabaseSchema(ext.databaseSchema, opts?.databaseSchemaCaps);
|
|
5170
|
+
}
|
|
5081
5171
|
compacted.extended = ext;
|
|
5082
5172
|
}
|
|
5083
5173
|
return compacted;
|
|
@@ -5086,8 +5176,8 @@ async function compressArtifact(artifact) {
|
|
|
5086
5176
|
const json = JSON.stringify(artifact);
|
|
5087
5177
|
return gzip2(json, { level: 9 });
|
|
5088
5178
|
}
|
|
5089
|
-
async function prepareCompressedUpload(artifact) {
|
|
5090
|
-
const compacted = prepareArtifactForUpload(artifact);
|
|
5179
|
+
async function prepareCompressedUpload(artifact, opts) {
|
|
5180
|
+
const compacted = prepareArtifactForUpload(artifact, opts);
|
|
5091
5181
|
const compressed = await compressArtifact(compacted);
|
|
5092
5182
|
return { body: compressed, contentEncoding: "gzip" };
|
|
5093
5183
|
}
|
|
@@ -5100,8 +5190,9 @@ function postOnce(input, host) {
|
|
|
5100
5190
|
"Content-Encoding": input.contentEncoding,
|
|
5101
5191
|
"X-Vibgrate-Timestamp": input.timestamp,
|
|
5102
5192
|
"Authorization": `VibgrateDSN ${input.keyId}:${input.secret}`,
|
|
5103
|
-
"Connection": "close"
|
|
5193
|
+
"Connection": "close",
|
|
5104
5194
|
// Prevent keep-alive delays on exit
|
|
5195
|
+
...input.runId && input.runToken ? { "X-Vibgrate-Run-Id": input.runId, "X-Vibgrate-Run-Token": input.runToken } : {}
|
|
5105
5196
|
},
|
|
5106
5197
|
body: input.body
|
|
5107
5198
|
});
|
|
@@ -5169,7 +5260,9 @@ var pushCommand = new Command("push").description("Push scan results to Vibgrate
|
|
|
5169
5260
|
return;
|
|
5170
5261
|
}
|
|
5171
5262
|
const artifact = await readJsonFile(filePath);
|
|
5172
|
-
const
|
|
5263
|
+
const config = await loadConfig(process.cwd());
|
|
5264
|
+
const databaseSchemaCaps = config.scanners !== false ? config.scanners?.databaseSchema : void 0;
|
|
5265
|
+
const { body, contentEncoding } = await prepareCompressedUpload(artifact, { databaseSchemaCaps });
|
|
5173
5266
|
const timestamp = String(Date.now());
|
|
5174
5267
|
let host = parsed.host;
|
|
5175
5268
|
if (opts.region) {
|
|
@@ -5193,7 +5286,11 @@ var pushCommand = new Command("push").description("Push scan results to Vibgrate
|
|
|
5193
5286
|
secret: parsed.secret,
|
|
5194
5287
|
body,
|
|
5195
5288
|
contentEncoding,
|
|
5196
|
-
timestamp
|
|
5289
|
+
timestamp,
|
|
5290
|
+
// Set only by an automated caller running the scan on the workspace's
|
|
5291
|
+
// behalf (e.g. a Vibgrate-hosted remediation run) — never a customer flag.
|
|
5292
|
+
runId: process.env.VIBGRATE_SCAN_RUN_ID,
|
|
5293
|
+
runToken: process.env.VIBGRATE_SCAN_RUN_TOKEN
|
|
5197
5294
|
});
|
|
5198
5295
|
host = uploadedHost;
|
|
5199
5296
|
if (!response.ok) {
|
|
@@ -5604,6 +5701,65 @@ async function publishPrivateLibrary(req, opts = {}) {
|
|
|
5604
5701
|
}
|
|
5605
5702
|
}
|
|
5606
5703
|
|
|
5704
|
+
// src/engine/hosted-cache.ts
|
|
5705
|
+
var CACHE_VERSION2 = "vg-hosted-docs/1";
|
|
5706
|
+
var HOSTED_DOCS_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
5707
|
+
var MAX_ENTRIES = 64;
|
|
5708
|
+
function cachePath2(root) {
|
|
5709
|
+
return path19.join(cacheDir(root), "hosted-docs.json");
|
|
5710
|
+
}
|
|
5711
|
+
function hostedDocsCacheKey(req, opts = {}) {
|
|
5712
|
+
const material = JSON.stringify([
|
|
5713
|
+
req.name ?? "",
|
|
5714
|
+
req.targetId ?? "",
|
|
5715
|
+
req.query ?? "",
|
|
5716
|
+
req.verbosity ?? "",
|
|
5717
|
+
req.maxTokens ?? 0,
|
|
5718
|
+
hostedBase(opts),
|
|
5719
|
+
opts.auth?.keyId ?? "anon"
|
|
5720
|
+
]);
|
|
5721
|
+
return createHash("sha256").update(material).digest("hex");
|
|
5722
|
+
}
|
|
5723
|
+
function loadFile(root) {
|
|
5724
|
+
try {
|
|
5725
|
+
const parsed = JSON.parse(fs19.readFileSync(cachePath2(root), "utf8"));
|
|
5726
|
+
if (parsed && parsed.version === CACHE_VERSION2 && parsed.entries && typeof parsed.entries === "object") return parsed;
|
|
5727
|
+
} catch {
|
|
5728
|
+
}
|
|
5729
|
+
return { version: CACHE_VERSION2, entries: {} };
|
|
5730
|
+
}
|
|
5731
|
+
function saveFile(root, file) {
|
|
5732
|
+
try {
|
|
5733
|
+
const keys = Object.keys(file.entries);
|
|
5734
|
+
if (keys.length > MAX_ENTRIES) {
|
|
5735
|
+
for (const k of keys.sort((a, b) => file.entries[a].at - file.entries[b].at).slice(0, keys.length - MAX_ENTRIES)) {
|
|
5736
|
+
delete file.entries[k];
|
|
5737
|
+
}
|
|
5738
|
+
}
|
|
5739
|
+
fs19.mkdirSync(cacheDir(root), { recursive: true });
|
|
5740
|
+
fs19.writeFileSync(cachePath2(root), JSON.stringify(file));
|
|
5741
|
+
} catch {
|
|
5742
|
+
}
|
|
5743
|
+
}
|
|
5744
|
+
async function fetchHostedDocsCached(root, req, opts = {}) {
|
|
5745
|
+
const now = opts.now ?? Date.now;
|
|
5746
|
+
const ttl = opts.ttlMs ?? HOSTED_DOCS_TTL_MS;
|
|
5747
|
+
const key = hostedDocsCacheKey(req, opts);
|
|
5748
|
+
const file = loadFile(root);
|
|
5749
|
+
if (!opts.bypass) {
|
|
5750
|
+
const hit = file.entries[key];
|
|
5751
|
+
if (hit && now() - hit.at < ttl && hit.result?.content) {
|
|
5752
|
+
return { ...hit.result, metadata: { ...hit.result.metadata ?? {}, cached: true } };
|
|
5753
|
+
}
|
|
5754
|
+
}
|
|
5755
|
+
const result = await fetchHostedDocs(req, opts);
|
|
5756
|
+
if (result) {
|
|
5757
|
+
file.entries[key] = { at: now(), result };
|
|
5758
|
+
saveFile(root, file);
|
|
5759
|
+
}
|
|
5760
|
+
return result;
|
|
5761
|
+
}
|
|
5762
|
+
|
|
5607
5763
|
// src/mcp/response.ts
|
|
5608
5764
|
var MAX_RESULT_TOKENS = 25e3;
|
|
5609
5765
|
function renderToolResult(result, maxTokens = MAX_RESULT_TOKENS) {
|
|
@@ -5825,6 +5981,9 @@ async function searchSymbols(graph, root, query, limit) {
|
|
|
5825
5981
|
if (!q2) return { matches: [], moreAvailable: false, hint: "query is required" };
|
|
5826
5982
|
const isPhrase = /\s/.test(q2);
|
|
5827
5983
|
let nodes = findNodes(graph, q2).filter((n) => n.kind !== "file");
|
|
5984
|
+
if (nodes.length === 0 && isPhrase) {
|
|
5985
|
+
nodes = reconstructedIdentifierNodes(graph, q2);
|
|
5986
|
+
}
|
|
5828
5987
|
if (nodes.length === 0) {
|
|
5829
5988
|
const tokens = queryTokens(q2);
|
|
5830
5989
|
if (tokens.length >= 2) nodes = multiTokenNodes(graph, tokens);
|
|
@@ -5867,6 +6026,14 @@ async function searchSymbols(graph, root, query, limit) {
|
|
|
5867
6026
|
function queryTokens(q2) {
|
|
5868
6027
|
return [...new Set(q2.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length >= 2))];
|
|
5869
6028
|
}
|
|
6029
|
+
function reconstructedIdentifierNodes(graph, q2) {
|
|
6030
|
+
const words = q2.trim().split(/\s+/).filter(Boolean);
|
|
6031
|
+
if (words.length < 2) return [];
|
|
6032
|
+
const concat = findNodes(graph, words.join(""));
|
|
6033
|
+
if (concat.length) return concat.filter((n) => n.kind !== "file");
|
|
6034
|
+
const snake = findNodes(graph, words.join("_"));
|
|
6035
|
+
return snake.filter((n) => n.kind !== "file");
|
|
6036
|
+
}
|
|
5870
6037
|
function multiTokenNodes(graph, tokens) {
|
|
5871
6038
|
const cov = /* @__PURE__ */ new Map();
|
|
5872
6039
|
for (const t of tokens) {
|
|
@@ -6546,7 +6713,8 @@ var TOOLS = [
|
|
|
6546
6713
|
return (async () => {
|
|
6547
6714
|
const dsn = resolveDsn();
|
|
6548
6715
|
const parsed = dsn ? parseDsn(dsn) : null;
|
|
6549
|
-
const hosted = await
|
|
6716
|
+
const hosted = await fetchHostedDocsCached(
|
|
6717
|
+
ctx.root,
|
|
6550
6718
|
{ name: entry?.name ?? id, targetId: entry?.id, query: query || void 0, maxTokens: budget },
|
|
6551
6719
|
{ auth: parsed ? { keyId: parsed.keyId, secret: parsed.secret } : void 0 }
|
|
6552
6720
|
);
|
|
@@ -7323,6 +7491,6 @@ function spdx(ctx) {
|
|
|
7323
7491
|
return JSON.stringify(doc, null, 2) + "\n";
|
|
7324
7492
|
}
|
|
7325
7493
|
|
|
7326
|
-
export { ASSISTANTS, CLI_TOOL_ALIASES, CliError, ECOSYSTEMS, ExitCode, FREE_PACK, GraphIndex, GraphSource, NPX_INVOCATION, ResourceLimitError, SCHEMA_VERSION, SKIP_DIRS, SKIP_FILES, TOOLS, UsageError, addLibrary, analyze, applyCoverage, applyStaticTestLinkage, assessDocQuality, assistantById, availableRegionIds, buildFacts, buildGraph, buildModuleResolver, cacheDir, catalogPath, clearModelCache, clearStoredCredentials, cosine, countPending, countTokens, coveringTests, createServer, createWorkspaceDsn, credentialsPath, dashHostForIngestHost, decodeScipIndex, defaultGraphPath, detectRunner, detectServeLaunch, discover, discoverModels, driftCount, driftFor, dsnCommand, embeddingsCached, enrichOnline, ensureGitignored, epistemicBreakdown, exportGraph,
|
|
7327
|
-
//# sourceMappingURL=chunk-
|
|
7328
|
-
//# sourceMappingURL=chunk-
|
|
7494
|
+
export { ASSISTANTS, CLI_TOOL_ALIASES, CliError, ECOSYSTEMS, ExitCode, FREE_PACK, GraphIndex, GraphSource, NPX_INVOCATION, ResourceLimitError, SCHEMA_VERSION, SKIP_DIRS, SKIP_FILES, TOOLS, UsageError, addLibrary, analyze, applyCoverage, applyStaticTestLinkage, assessDocQuality, assistantById, availableRegionIds, buildFacts, buildGraph, buildModuleResolver, cacheDir, catalogPath, clearModelCache, clearStoredCredentials, cosine, countPending, countTokens, coveringTests, createServer, createWorkspaceDsn, credentialsPath, dashHostForIngestHost, decodeScipIndex, defaultGraphPath, detectRunner, detectServeLaunch, discover, discoverModels, driftCount, driftFor, dsnCommand, embeddingsCached, enrichOnline, ensureGitignored, epistemicBreakdown, exportGraph, fetchHostedDocsCached, findGitRoot, findNodes, formatForExt, getNodeEmbeddings, gitignoreEntryForCredentials, groundGraph, hasDrift, identifierParts, impactOf, indexFor, ingestHostForRegionId, installAssistant, inventory, isModelReady, isTestFile, libDir, libId, loadCatalog, loadCoverage, loadEmbedder, loadGraph, loadSnapshot, localApiSurface, localPackageDocs, modelCacheInfo, nodeById, nodeEmbedText, parseDsn, parseGraph, parseJsonc, probeFreshness, publishPrivateLibrary, pushCommand, queryGraph, queryGraphSemantic, readDoc, readSavings, readScanArtifact, readUsage, recordCliCall, recordSaving, refreshIfStale, relativeResolver, renderHtml, renderReport, resolveCliInvocation, resolveDsn, resolveEmbedModel, resolveIngestHost, resolveLib, resolveLimits, resolveOne, resolveVersion, saveCatalog, savingsRecorded, scipEdges, selectForBudget, serializeGraph, serveStdio, shortestPath, stableStringify, symbolsFromApi, testsToRun, unavailableMessage, uninstallAssistant, uploadScanArtifact, usageError, verifyDeterminism, vibgrateDir, writeArtifacts, writeNavigationConfig, writeSnapshot, writeStoredCredentials };
|
|
7495
|
+
//# sourceMappingURL=chunk-D4BPWARI.js.map
|
|
7496
|
+
//# sourceMappingURL=chunk-D4BPWARI.js.map
|