dravix-agent 0.1.0
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/.claude/settings.example.json +30 -0
- package/ARCHITECTURE.md +410 -0
- package/LICENSE +21 -0
- package/README.md +153 -0
- package/ROADMAP.md +117 -0
- package/data/vulnkb.json +666 -0
- package/dist/bin/aegis.d.ts +3 -0
- package/dist/bin/aegis.d.ts.map +1 -0
- package/dist/bin/aegis.js +489 -0
- package/dist/bin/aegis.js.map +1 -0
- package/dist/cache.d.ts +9 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +146 -0
- package/dist/cache.js.map +1 -0
- package/dist/engines/ai-sinks.d.ts +52 -0
- package/dist/engines/ai-sinks.d.ts.map +1 -0
- package/dist/engines/ai-sinks.js +204 -0
- package/dist/engines/ai-sinks.js.map +1 -0
- package/dist/engines/eslint.d.ts +9 -0
- package/dist/engines/eslint.d.ts.map +1 -0
- package/dist/engines/eslint.js +245 -0
- package/dist/engines/eslint.js.map +1 -0
- package/dist/engines/joern.d.ts +3 -0
- package/dist/engines/joern.d.ts.map +1 -0
- package/dist/engines/joern.js +98 -0
- package/dist/engines/joern.js.map +1 -0
- package/dist/engines/js-sinks.d.ts +70 -0
- package/dist/engines/js-sinks.d.ts.map +1 -0
- package/dist/engines/js-sinks.js +370 -0
- package/dist/engines/js-sinks.js.map +1 -0
- package/dist/engines/llm-critic.d.ts +130 -0
- package/dist/engines/llm-critic.d.ts.map +1 -0
- package/dist/engines/llm-critic.js +551 -0
- package/dist/engines/llm-critic.js.map +1 -0
- package/dist/engines/pragma.d.ts +20 -0
- package/dist/engines/pragma.d.ts.map +1 -0
- package/dist/engines/pragma.js +83 -0
- package/dist/engines/pragma.js.map +1 -0
- package/dist/engines/property-test.d.ts +3 -0
- package/dist/engines/property-test.d.ts.map +1 -0
- package/dist/engines/property-test.js +134 -0
- package/dist/engines/property-test.js.map +1 -0
- package/dist/engines/pyright.d.ts +10 -0
- package/dist/engines/pyright.d.ts.map +1 -0
- package/dist/engines/pyright.js +143 -0
- package/dist/engines/pyright.js.map +1 -0
- package/dist/engines/pysa.d.ts +3 -0
- package/dist/engines/pysa.d.ts.map +1 -0
- package/dist/engines/pysa.js +83 -0
- package/dist/engines/pysa.js.map +1 -0
- package/dist/engines/python-sinks.d.ts +82 -0
- package/dist/engines/python-sinks.d.ts.map +1 -0
- package/dist/engines/python-sinks.js +459 -0
- package/dist/engines/python-sinks.js.map +1 -0
- package/dist/engines/registry.d.ts +26 -0
- package/dist/engines/registry.d.ts.map +1 -0
- package/dist/engines/registry.js +70 -0
- package/dist/engines/registry.js.map +1 -0
- package/dist/engines/secret-scan.d.ts +22 -0
- package/dist/engines/secret-scan.d.ts.map +1 -0
- package/dist/engines/secret-scan.js +179 -0
- package/dist/engines/secret-scan.js.map +1 -0
- package/dist/engines/semgrep.d.ts +10 -0
- package/dist/engines/semgrep.d.ts.map +1 -0
- package/dist/engines/semgrep.js +200 -0
- package/dist/engines/semgrep.js.map +1 -0
- package/dist/engines/treesitter.d.ts +18 -0
- package/dist/engines/treesitter.d.ts.map +1 -0
- package/dist/engines/treesitter.js +135 -0
- package/dist/engines/treesitter.js.map +1 -0
- package/dist/engines/tsc.d.ts +10 -0
- package/dist/engines/tsc.d.ts.map +1 -0
- package/dist/engines/tsc.js +142 -0
- package/dist/engines/tsc.js.map +1 -0
- package/dist/engines/types.d.ts +47 -0
- package/dist/engines/types.d.ts.map +1 -0
- package/dist/engines/types.js +27 -0
- package/dist/engines/types.js.map +1 -0
- package/dist/findings.d.ts +121 -0
- package/dist/findings.d.ts.map +1 -0
- package/dist/findings.js +98 -0
- package/dist/findings.js.map +1 -0
- package/dist/hooks/claude-code.d.ts +3 -0
- package/dist/hooks/claude-code.d.ts.map +1 -0
- package/dist/hooks/claude-code.js +187 -0
- package/dist/hooks/claude-code.js.map +1 -0
- package/dist/index/context.d.ts +127 -0
- package/dist/index/context.d.ts.map +1 -0
- package/dist/index/context.js +267 -0
- package/dist/index/context.js.map +1 -0
- package/dist/index/embeddings.d.ts +68 -0
- package/dist/index/embeddings.d.ts.map +1 -0
- package/dist/index/embeddings.js +570 -0
- package/dist/index/embeddings.js.map +1 -0
- package/dist/index/graph_routing.d.ts +36 -0
- package/dist/index/graph_routing.d.ts.map +1 -0
- package/dist/index/graph_routing.js +170 -0
- package/dist/index/graph_routing.js.map +1 -0
- package/dist/index/joern.d.ts +76 -0
- package/dist/index/joern.d.ts.map +1 -0
- package/dist/index/joern.js +782 -0
- package/dist/index/joern.js.map +1 -0
- package/dist/index/property-test.d.ts +88 -0
- package/dist/index/property-test.d.ts.map +1 -0
- package/dist/index/property-test.js +466 -0
- package/dist/index/property-test.js.map +1 -0
- package/dist/index/proto/scip.proto +897 -0
- package/dist/index/pysa.d.ts +91 -0
- package/dist/index/pysa.d.ts.map +1 -0
- package/dist/index/pysa.js +617 -0
- package/dist/index/pysa.js.map +1 -0
- package/dist/index/scip.d.ts +76 -0
- package/dist/index/scip.d.ts.map +1 -0
- package/dist/index/scip.js +541 -0
- package/dist/index/scip.js.map +1 -0
- package/dist/index/vulrag.d.ts +86 -0
- package/dist/index/vulrag.d.ts.map +1 -0
- package/dist/index/vulrag.js +242 -0
- package/dist/index/vulrag.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/install/claude-code.d.ts +31 -0
- package/dist/install/claude-code.d.ts.map +1 -0
- package/dist/install/claude-code.js +447 -0
- package/dist/install/claude-code.js.map +1 -0
- package/dist/lang.d.ts +5 -0
- package/dist/lang.d.ts.map +1 -0
- package/dist/lang.js +52 -0
- package/dist/lang.js.map +1 -0
- package/dist/learning/suppressions.d.ts +70 -0
- package/dist/learning/suppressions.d.ts.map +1 -0
- package/dist/learning/suppressions.js +179 -0
- package/dist/learning/suppressions.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +187 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/explain.d.ts +58 -0
- package/dist/mcp/tools/explain.d.ts.map +1 -0
- package/dist/mcp/tools/explain.js +60 -0
- package/dist/mcp/tools/explain.js.map +1 -0
- package/dist/mcp/tools/precheck.d.ts +29 -0
- package/dist/mcp/tools/precheck.d.ts.map +1 -0
- package/dist/mcp/tools/precheck.js +42 -0
- package/dist/mcp/tools/precheck.js.map +1 -0
- package/dist/mcp/tools/validate.d.ts +73 -0
- package/dist/mcp/tools/validate.d.ts.map +1 -0
- package/dist/mcp/tools/validate.js +66 -0
- package/dist/mcp/tools/validate.js.map +1 -0
- package/dist/mcp/warm.d.ts +88 -0
- package/dist/mcp/warm.d.ts.map +1 -0
- package/dist/mcp/warm.js +331 -0
- package/dist/mcp/warm.js.map +1 -0
- package/dist/orchestrator.d.ts +46 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +596 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/policy.d.ts +51 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +201 -0
- package/dist/policy.js.map +1 -0
- package/dist/risk.d.ts +31 -0
- package/dist/risk.d.ts.map +1 -0
- package/dist/risk.js +92 -0
- package/dist/risk.js.map +1 -0
- package/dist/stats.d.ts +72 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +217 -0
- package/dist/stats.js.map +1 -0
- package/dist/telemetry/collector.d.ts +10 -0
- package/dist/telemetry/collector.d.ts.map +1 -0
- package/dist/telemetry/collector.js +75 -0
- package/dist/telemetry/collector.js.map +1 -0
- package/dist/telemetry/consent.d.ts +9 -0
- package/dist/telemetry/consent.d.ts.map +1 -0
- package/dist/telemetry/consent.js +42 -0
- package/dist/telemetry/consent.js.map +1 -0
- package/dist/telemetry/installation.d.ts +2 -0
- package/dist/telemetry/installation.d.ts.map +1 -0
- package/dist/telemetry/installation.js +32 -0
- package/dist/telemetry/installation.js.map +1 -0
- package/dist/telemetry/sanitizer.d.ts +5 -0
- package/dist/telemetry/sanitizer.d.ts.map +1 -0
- package/dist/telemetry/sanitizer.js +60 -0
- package/dist/telemetry/sanitizer.js.map +1 -0
- package/dist/telemetry/types.d.ts +39 -0
- package/dist/telemetry/types.d.ts.map +1 -0
- package/dist/telemetry/types.js +4 -0
- package/dist/telemetry/types.js.map +1 -0
- package/dist/telemetry/uploader.d.ts +12 -0
- package/dist/telemetry/uploader.d.ts.map +1 -0
- package/dist/telemetry/uploader.js +92 -0
- package/dist/telemetry/uploader.js.map +1 -0
- package/dist/util/logger.d.ts +19 -0
- package/dist/util/logger.d.ts.map +1 -0
- package/dist/util/logger.js +58 -0
- package/dist/util/logger.js.map +1 -0
- package/dist/util/safe-paths.d.ts +8 -0
- package/dist/util/safe-paths.d.ts.map +1 -0
- package/dist/util/safe-paths.js +102 -0
- package/dist/util/safe-paths.js.map +1 -0
- package/dist/util/subprocess.d.ts +32 -0
- package/dist/util/subprocess.d.ts.map +1 -0
- package/dist/util/subprocess.js +137 -0
- package/dist/util/subprocess.js.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local CPU embeddings + HNSW semantic search.
|
|
3
|
+
*
|
|
4
|
+
* Stack (OSS-only, no API):
|
|
5
|
+
* - ``@huggingface/transformers`` (transformers.js) loads an ONNX-quantised
|
|
6
|
+
* sentence/code embedding model and runs inference on CPU. Default:
|
|
7
|
+
* ``Xenova/all-MiniLM-L6-v2`` (384-d, ~80 MB, MIT). Override with
|
|
8
|
+
* ``AEGIS_EMBED_MODEL``.
|
|
9
|
+
* - ``hnswlib-node`` builds a Hierarchical NSW graph for sub-millisecond
|
|
10
|
+
* top-K queries at projects up to ~1M points.
|
|
11
|
+
*
|
|
12
|
+
* Stored per project under ``$AEGIS_HOME/embeddings/<sha256(root)[:16]>/``:
|
|
13
|
+
* - ``index.hnsw`` — serialized HNSW
|
|
14
|
+
* - ``meta.jsonl`` — one JSON per row mapping HNSW label → {file, symbol, kind, snippet}
|
|
15
|
+
* - ``info.json`` — {model, dim, rows, built_at, scip_sha}
|
|
16
|
+
*
|
|
17
|
+
* Lazy-load + singleton per process. Cold cost (~10-15 s for model warm-up +
|
|
18
|
+
* a few minutes for first index build); subsequent queries are sub-ms.
|
|
19
|
+
*/
|
|
20
|
+
import { createHash } from "node:crypto";
|
|
21
|
+
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
22
|
+
import { join, resolve } from "node:path";
|
|
23
|
+
import { getLogger } from "../util/logger.js";
|
|
24
|
+
const log = getLogger("aegis.embeddings");
|
|
25
|
+
const DEFAULT_MODEL = process.env.AEGIS_EMBED_MODEL ?? "Xenova/all-MiniLM-L6-v2";
|
|
26
|
+
const DEFAULT_DIM = 384;
|
|
27
|
+
const DEFAULT_MAX_ELEMENTS = 1_000_000;
|
|
28
|
+
const SNIPPET_MAX_CHARS = 2_000;
|
|
29
|
+
const QUERY_MAX_CHARS = 8_000;
|
|
30
|
+
function aegisHome() {
|
|
31
|
+
return (process.env.AEGIS_HOME ??
|
|
32
|
+
resolve(process.env.HOME ?? process.env.USERPROFILE ?? ".", ".aegis"));
|
|
33
|
+
}
|
|
34
|
+
function embedDirFor(projectRoot) {
|
|
35
|
+
const h = createHash("sha256").update(resolve(projectRoot)).digest("hex").slice(0, 16);
|
|
36
|
+
return join(aegisHome(), "embeddings", h);
|
|
37
|
+
}
|
|
38
|
+
let _hfMod = null;
|
|
39
|
+
async function loadHf() {
|
|
40
|
+
if (_hfMod)
|
|
41
|
+
return _hfMod;
|
|
42
|
+
try {
|
|
43
|
+
const mod = (await import("@huggingface/transformers"));
|
|
44
|
+
// Cache models under AEGIS_HOME so users can see/clean them
|
|
45
|
+
mod.env.cacheDir = join(aegisHome(), "models");
|
|
46
|
+
mkdirSync(mod.env.cacheDir, { recursive: true });
|
|
47
|
+
// Allow remote model downloads (default) so first-run "just works"
|
|
48
|
+
mod.env.allowRemoteModels = true;
|
|
49
|
+
// Use a sensible thread count for CPU inference
|
|
50
|
+
if (mod.env.backends?.onnx) {
|
|
51
|
+
const n = Number(process.env.AEGIS_EMBED_THREADS ?? "0");
|
|
52
|
+
if (n > 0)
|
|
53
|
+
mod.env.backends.onnx.numThreads = n;
|
|
54
|
+
}
|
|
55
|
+
_hfMod = mod;
|
|
56
|
+
return _hfMod;
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
log.warn("@huggingface/transformers not installed", { err: String(err) });
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export class Embedder {
|
|
64
|
+
modelName;
|
|
65
|
+
_pipeline = null;
|
|
66
|
+
_dim = DEFAULT_DIM;
|
|
67
|
+
constructor(modelName = DEFAULT_MODEL) {
|
|
68
|
+
this.modelName = modelName;
|
|
69
|
+
}
|
|
70
|
+
/** Lazily load the model (cold cost). Returns false if unavailable. */
|
|
71
|
+
async ensureLoaded() {
|
|
72
|
+
if (this._pipeline)
|
|
73
|
+
return true;
|
|
74
|
+
const hf = await loadHf();
|
|
75
|
+
if (!hf)
|
|
76
|
+
return false;
|
|
77
|
+
try {
|
|
78
|
+
log.info("loading embedding model", { model: this.modelName });
|
|
79
|
+
this._pipeline = await hf.pipeline("feature-extraction", this.modelName);
|
|
80
|
+
// Probe dim with a tiny embed
|
|
81
|
+
const probe = await this._pipeline("x", { pooling: "mean", normalize: true });
|
|
82
|
+
this._dim = probe.dims?.[probe.dims.length - 1] ?? probe.data.length ?? DEFAULT_DIM;
|
|
83
|
+
log.info("embedding model ready", { model: this.modelName, dim: this._dim });
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
log.warn("embedding model load failed", { model: this.modelName, err: String(err) });
|
|
88
|
+
this._pipeline = null;
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
get dim() {
|
|
93
|
+
return this._dim;
|
|
94
|
+
}
|
|
95
|
+
get model() {
|
|
96
|
+
return this.modelName;
|
|
97
|
+
}
|
|
98
|
+
/** Returns the L2-normalised embedding (use cosine via dot product). */
|
|
99
|
+
async embed(text) {
|
|
100
|
+
if (!(await this.ensureLoaded()) || !this._pipeline)
|
|
101
|
+
return null;
|
|
102
|
+
const t = (text ?? "").slice(0, QUERY_MAX_CHARS);
|
|
103
|
+
if (!t.trim())
|
|
104
|
+
return new Float32Array(this._dim); // zero vector for empty
|
|
105
|
+
try {
|
|
106
|
+
const out = await this._pipeline(t, { pooling: "mean", normalize: true });
|
|
107
|
+
const arr = out.data instanceof Float32Array ? out.data : Float32Array.from(out.data);
|
|
108
|
+
// Trim if the model returns a different size than the probed dim
|
|
109
|
+
if (arr.length !== this._dim) {
|
|
110
|
+
const fixed = new Float32Array(this._dim);
|
|
111
|
+
fixed.set(arr.slice(0, this._dim));
|
|
112
|
+
return fixed;
|
|
113
|
+
}
|
|
114
|
+
return arr;
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
log.debug("embed failed", { err: String(err) });
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/** Batch embed; sequential on CPU to keep peak memory bounded. */
|
|
122
|
+
async embedBatch(texts) {
|
|
123
|
+
const out = [];
|
|
124
|
+
for (const t of texts) {
|
|
125
|
+
out.push(await this.embed(t));
|
|
126
|
+
}
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
let _hnswMod = null;
|
|
131
|
+
async function loadHnsw() {
|
|
132
|
+
if (_hnswMod)
|
|
133
|
+
return _hnswMod;
|
|
134
|
+
try {
|
|
135
|
+
const mod = (await import("hnswlib-node"));
|
|
136
|
+
_hnswMod = (mod.default ?? mod);
|
|
137
|
+
if (typeof _hnswMod.HierarchicalNSW !== "function") {
|
|
138
|
+
log.warn("hnswlib-node unexpected shape");
|
|
139
|
+
_hnswMod = null;
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
return _hnswMod;
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
log.warn("hnswlib-node not installed", { err: String(err) });
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// --- the project-wide embedding index --------------------------------------
|
|
150
|
+
export class EmbeddingIndex {
|
|
151
|
+
projectRoot;
|
|
152
|
+
embedder;
|
|
153
|
+
hnsw = null;
|
|
154
|
+
meta = [];
|
|
155
|
+
info = null;
|
|
156
|
+
constructor(projectRoot, embedder = new Embedder()) {
|
|
157
|
+
this.projectRoot = projectRoot;
|
|
158
|
+
this.embedder = embedder;
|
|
159
|
+
}
|
|
160
|
+
dir() {
|
|
161
|
+
return embedDirFor(this.projectRoot);
|
|
162
|
+
}
|
|
163
|
+
indexPath() {
|
|
164
|
+
return join(this.dir(), "index.hnsw");
|
|
165
|
+
}
|
|
166
|
+
metaPath() {
|
|
167
|
+
return join(this.dir(), "meta.jsonl");
|
|
168
|
+
}
|
|
169
|
+
infoPath() {
|
|
170
|
+
return join(this.dir(), "info.json");
|
|
171
|
+
}
|
|
172
|
+
/** True iff an index file exists on disk for this project. */
|
|
173
|
+
hasPersisted() {
|
|
174
|
+
return existsSync(this.indexPath()) && existsSync(this.metaPath()) && existsSync(this.infoPath());
|
|
175
|
+
}
|
|
176
|
+
/** Load an existing index from disk; returns false if any required file missing. */
|
|
177
|
+
async load() {
|
|
178
|
+
if (!this.hasPersisted())
|
|
179
|
+
return false;
|
|
180
|
+
try {
|
|
181
|
+
const info = JSON.parse(readFileSync(this.infoPath(), "utf8"));
|
|
182
|
+
const hnswMod = await loadHnsw();
|
|
183
|
+
if (!hnswMod)
|
|
184
|
+
return false;
|
|
185
|
+
const idx = new hnswMod.HierarchicalNSW("cosine", info.dim);
|
|
186
|
+
// ``hnswlib-node`` exposes both sync and async readIndex depending on
|
|
187
|
+
// version; prefer sync if present (we're inside an async fn anyway).
|
|
188
|
+
// Second arg is NOT maxElements — it's ``allowReplaceDeleted`` (bool).
|
|
189
|
+
// The on-disk file already stores maxElements; passing a number here
|
|
190
|
+
// raises "Invalid the second argument type, must be a boolean".
|
|
191
|
+
if (typeof idx.readIndexSync === "function") {
|
|
192
|
+
idx.readIndexSync(this.indexPath());
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
await idx.readIndex(this.indexPath());
|
|
196
|
+
}
|
|
197
|
+
idx.setEf(Math.max(50, Math.min(200, info.rows)));
|
|
198
|
+
this.hnsw = idx;
|
|
199
|
+
this.info = info;
|
|
200
|
+
this.meta = readFileSync(this.metaPath(), "utf8")
|
|
201
|
+
.split(/\r?\n/)
|
|
202
|
+
.filter(Boolean)
|
|
203
|
+
.map((l) => JSON.parse(l));
|
|
204
|
+
log.info("embedding index loaded", { ...info, rows: this.meta.length });
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
catch (err) {
|
|
208
|
+
log.warn("embedding index load failed", { err: String(err) });
|
|
209
|
+
this.hnsw = null;
|
|
210
|
+
this.meta = [];
|
|
211
|
+
this.info = null;
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Build the index from scratch by walking every SymbolInformation entry the
|
|
217
|
+
* SCIP indexer has stored for this project. We embed each symbol's snippet
|
|
218
|
+
* (from defOf). Slow (~5-50 ms per symbol on CPU); meant to be invoked from
|
|
219
|
+
* ``aegis index --embed`` and persisted.
|
|
220
|
+
*/
|
|
221
|
+
async build(scip, opts) {
|
|
222
|
+
const meta = await scip.meta(this.projectRoot);
|
|
223
|
+
if (!meta) {
|
|
224
|
+
log.warn("cannot build embeddings — SCIP not indexed for this project");
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
const hfReady = await this.embedder.ensureLoaded();
|
|
228
|
+
if (!hfReady) {
|
|
229
|
+
log.warn("embedder unavailable; embedding index not built");
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
const hnswMod = await loadHnsw();
|
|
233
|
+
if (!hnswMod)
|
|
234
|
+
return false;
|
|
235
|
+
// Collect candidates: every symbol that has a definition site
|
|
236
|
+
const cap = opts?.maxSymbols ?? 20_000;
|
|
237
|
+
const candidates = [];
|
|
238
|
+
// Walk every symbol id we know about. The SCIPIndexer stores symbols
|
|
239
|
+
// keyed individually; we don't expose a "list all" method yet, so use
|
|
240
|
+
// the meta.documents + per-doc enumeration via SCIP's stored docs would
|
|
241
|
+
// require new code. For the v1 path we iterate by display-name across
|
|
242
|
+
// a reasonable hard-coded set of "exported" kinds via direct access.
|
|
243
|
+
//
|
|
244
|
+
// Pragmatic shortcut: re-read each .scip raw file we wrote during index
|
|
245
|
+
// build and re-emit definitions. This avoids adding a new API to
|
|
246
|
+
// SCIPIndexer and keeps the contract narrow.
|
|
247
|
+
const rawDir = join(this.projectRoot, ".aegis", "scip", "raw");
|
|
248
|
+
if (!existsSync(rawDir)) {
|
|
249
|
+
// The user may have built the index from a different cwd; surface a clear hint.
|
|
250
|
+
log.warn("no .scip raw files at <project>/.aegis/scip/raw/ — re-run `aegis index --force <project>` from anywhere to regenerate raw artefacts", { rawDir });
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
// Read raw .scip and extract definitions directly.
|
|
254
|
+
const protoFiles = (await import("node:fs/promises")).readdir;
|
|
255
|
+
const entries = await protoFiles(rawDir);
|
|
256
|
+
const decodeMod = await import("./scip.js"); // re-use the proto decoder via SCIPIndexer's private path — instead just call defOf per known display name
|
|
257
|
+
void decodeMod;
|
|
258
|
+
const protobufMod = (await import("protobufjs"));
|
|
259
|
+
const proto = (protobufMod.default && typeof protobufMod.default.Root === "function"
|
|
260
|
+
? protobufMod.default
|
|
261
|
+
: protobufMod);
|
|
262
|
+
// Better: derive proto path from a known anchor — use the bundled one we shipped at <pkg>/dist/index/proto/scip.proto
|
|
263
|
+
const altProtoPaths = [
|
|
264
|
+
resolve(process.cwd(), "src", "index", "proto", "scip.proto"),
|
|
265
|
+
resolve(process.cwd(), "dist", "index", "proto", "scip.proto"),
|
|
266
|
+
resolve(process.cwd(), "..", "src", "index", "proto", "scip.proto"),
|
|
267
|
+
resolve(process.cwd(), "..", "dist", "index", "proto", "scip.proto"),
|
|
268
|
+
// also walk near this module's URL
|
|
269
|
+
resolve(new URL(".", import.meta.url).pathname.replace(/^\/([A-Za-z]:)/, "$1"), "proto", "scip.proto"),
|
|
270
|
+
];
|
|
271
|
+
let usedProto = null;
|
|
272
|
+
for (const p of altProtoPaths) {
|
|
273
|
+
if (existsSync(p)) {
|
|
274
|
+
usedProto = p;
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (!usedProto) {
|
|
279
|
+
log.warn("scip.proto not found for embedding ingest");
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
const root = new proto.Root().loadSync(usedProto, { keepCase: true });
|
|
283
|
+
const IndexType = root.lookupType("scip.Index");
|
|
284
|
+
// Symbol-kind enum copied DIRECTLY from scip.proto SymbolInformation.Kind.
|
|
285
|
+
// The previous version of this map mistakenly used LSP SymbolKind numbers
|
|
286
|
+
// (Function=12, Method=6, etc.) — SCIP's values are completely different
|
|
287
|
+
// (Function=17, Method=26, Interface=21) and the mismatch caused every
|
|
288
|
+
// definition to be filtered out as "Symbol" (unknown), producing
|
|
289
|
+
// "no embeddable code-bearing definitions found" on every project.
|
|
290
|
+
const KIND_MAP = {
|
|
291
|
+
0: "UnspecifiedKind",
|
|
292
|
+
// — Types & containers —
|
|
293
|
+
7: "Class", 21: "Interface", 49: "Struct", 53: "Trait", 42: "Protocol",
|
|
294
|
+
54: "Type", 55: "TypeAlias", 56: "TypeClass", 11: "Enum", 75: "SingletonClass",
|
|
295
|
+
// — Methods & functions (every callable variant) —
|
|
296
|
+
17: "Function", 26: "Method", 9: "Constructor", 66: "AbstractMethod",
|
|
297
|
+
67: "MethodSpecification", 68: "ProtocolMethod", 69: "PureVirtualMethod",
|
|
298
|
+
70: "TraitMethod", 71: "TypeClassMethod", 76: "SingletonMethod",
|
|
299
|
+
80: "StaticMethod", 18: "Getter", 45: "Setter",
|
|
300
|
+
// — Things we skip but want logged correctly —
|
|
301
|
+
8: "Constant", 12: "EnumMember", 13: "Event", 15: "Field", 16: "File",
|
|
302
|
+
22: "Key", 25: "Macro", 28: "Message", 29: "Module", 30: "Namespace",
|
|
303
|
+
33: "Object", 34: "Operator", 35: "Package", 37: "Parameter", 41: "Property",
|
|
304
|
+
48: "String", 50: "Tactic", 51: "Theorem", 58: "TypeParameter", 59: "Union",
|
|
305
|
+
};
|
|
306
|
+
for (const ent of entries) {
|
|
307
|
+
if (!ent.endsWith(".scip"))
|
|
308
|
+
continue;
|
|
309
|
+
const buf = readFileSync(join(rawDir, ent));
|
|
310
|
+
const msg = IndexType.decode(buf);
|
|
311
|
+
const obj = IndexType.toObject(msg, {
|
|
312
|
+
longs: Number, enums: Number, bytes: String,
|
|
313
|
+
defaults: false, arrays: true, objects: true, oneofs: true,
|
|
314
|
+
});
|
|
315
|
+
const docs = obj.documents ?? [];
|
|
316
|
+
const symInfo = new Map();
|
|
317
|
+
for (const si of [...(obj.external_symbols ?? []), ...docs.flatMap((d) => d.symbols ?? [])]) {
|
|
318
|
+
if (!si.symbol)
|
|
319
|
+
continue;
|
|
320
|
+
symInfo.set(si.symbol, {
|
|
321
|
+
display: si.display_name ?? deriveDisplayName(si.symbol),
|
|
322
|
+
kind: KIND_MAP[si.kind ?? 0] ?? "UnspecifiedKind",
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
// Walk occurrences with Definition role; read the source snippet
|
|
326
|
+
for (const d of docs) {
|
|
327
|
+
const rel = d.relative_path ?? "";
|
|
328
|
+
if (!rel)
|
|
329
|
+
continue;
|
|
330
|
+
for (const occ of d.occurrences ?? []) {
|
|
331
|
+
const roles = occ.symbol_roles ?? 0;
|
|
332
|
+
if ((roles & 1) === 0)
|
|
333
|
+
continue; // not a Definition
|
|
334
|
+
const info = symInfo.get(occ.symbol);
|
|
335
|
+
let name = info?.display ?? deriveDisplayName(occ.symbol);
|
|
336
|
+
let kind = info?.kind ?? "UnspecifiedKind";
|
|
337
|
+
// scip-typescript emits SymbolInformation.kind=0 (UnspecifiedKind)
|
|
338
|
+
// for 100% of symbols and no display_name — it leaves classification
|
|
339
|
+
// to the SCIP descriptor suffix (`).` method, `#` type, `.` term,
|
|
340
|
+
// `/` namespace). Fall back to that here, otherwise every TS
|
|
341
|
+
// project would silently produce 0 embedding candidates.
|
|
342
|
+
if (kind === "UnspecifiedKind" || kind === "Symbol") {
|
|
343
|
+
kind = inferKindFromDescriptor(occ.symbol);
|
|
344
|
+
}
|
|
345
|
+
if (!name || name === "?")
|
|
346
|
+
name = deriveDisplayName(occ.symbol);
|
|
347
|
+
// Code-bearing kinds — what's actually useful for semantic retrieval.
|
|
348
|
+
// Variables/params/namespaces are skipped (they add noise and the
|
|
349
|
+
// snippet would just be a name).
|
|
350
|
+
if (!CODE_BEARING_KINDS.has(kind))
|
|
351
|
+
continue;
|
|
352
|
+
const range = occ.range;
|
|
353
|
+
const sLine = (range?.[0] ?? 0) + 1;
|
|
354
|
+
const eLine = (range && range.length >= 4 ? range[2] : sLine) + 1;
|
|
355
|
+
const snippet = readSnippet(this.projectRoot, rel, sLine, eLine, SNIPPET_MAX_CHARS);
|
|
356
|
+
if (!snippet || snippet.length < 30)
|
|
357
|
+
continue;
|
|
358
|
+
candidates.push({
|
|
359
|
+
id: occ.symbol,
|
|
360
|
+
file: rel,
|
|
361
|
+
line: sLine,
|
|
362
|
+
name,
|
|
363
|
+
kind,
|
|
364
|
+
snippet,
|
|
365
|
+
});
|
|
366
|
+
if (candidates.length >= cap)
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
if (candidates.length >= cap)
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
if (candidates.length >= cap)
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
if (candidates.length === 0) {
|
|
376
|
+
log.warn("no embeddable code-bearing definitions found");
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
log.info("embedding candidates collected", { count: candidates.length });
|
|
380
|
+
// Init HNSW
|
|
381
|
+
const dim = this.embedder.dim;
|
|
382
|
+
const idx = new hnswMod.HierarchicalNSW("cosine", dim);
|
|
383
|
+
idx.initIndex(Math.max(1024, Math.min(DEFAULT_MAX_ELEMENTS, candidates.length * 2)), 16, 200);
|
|
384
|
+
idx.setEf(100);
|
|
385
|
+
const metaOut = [];
|
|
386
|
+
const t0 = Date.now();
|
|
387
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
388
|
+
const c = candidates[i];
|
|
389
|
+
const vec = await this.embedder.embed(c.snippet);
|
|
390
|
+
if (!vec)
|
|
391
|
+
continue;
|
|
392
|
+
// hnswlib-node's addPoint refuses Float32Array — it explicitly
|
|
393
|
+
// type-checks for `Array` (plain JS array). Convert before passing.
|
|
394
|
+
idx.addPoint(Array.from(vec), i);
|
|
395
|
+
metaOut.push({
|
|
396
|
+
id: i,
|
|
397
|
+
file: c.file,
|
|
398
|
+
symbolId: c.id,
|
|
399
|
+
displayName: c.name,
|
|
400
|
+
kind: c.kind,
|
|
401
|
+
snippet: c.snippet.slice(0, SNIPPET_MAX_CHARS),
|
|
402
|
+
});
|
|
403
|
+
if ((i + 1) % 100 === 0) {
|
|
404
|
+
const rate = ((i + 1) / Math.max(1, (Date.now() - t0) / 1000)).toFixed(1);
|
|
405
|
+
log.info("embedding progress", { done: i + 1, total: candidates.length, rate_per_sec: rate });
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
// Persist
|
|
409
|
+
mkdirSync(this.dir(), { recursive: true });
|
|
410
|
+
if (typeof idx.writeIndexSync === "function") {
|
|
411
|
+
idx.writeIndexSync(this.indexPath());
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
await idx.writeIndex(this.indexPath());
|
|
415
|
+
}
|
|
416
|
+
writeFileSync(this.metaPath(), metaOut.map((m) => JSON.stringify(m)).join("\n") + "\n", "utf8");
|
|
417
|
+
const info = {
|
|
418
|
+
model: this.embedder.model,
|
|
419
|
+
dim,
|
|
420
|
+
rows: metaOut.length,
|
|
421
|
+
built_at: Date.now(),
|
|
422
|
+
...(meta.scipSha ? { scip_sha: meta.scipSha } : {}),
|
|
423
|
+
};
|
|
424
|
+
writeFileSync(this.infoPath(), JSON.stringify(info, null, 2), "utf8");
|
|
425
|
+
this.hnsw = idx;
|
|
426
|
+
this.meta = metaOut;
|
|
427
|
+
this.info = info;
|
|
428
|
+
log.info("embedding index built", {
|
|
429
|
+
rows: metaOut.length,
|
|
430
|
+
durationMs: Date.now() - t0,
|
|
431
|
+
dir: this.dir(),
|
|
432
|
+
});
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
/** Top-K semantically similar embedded items for a query snippet. */
|
|
436
|
+
async topK(query, k) {
|
|
437
|
+
if (!this.hnsw && !(await this.load()))
|
|
438
|
+
return [];
|
|
439
|
+
if (!this.hnsw || this.meta.length === 0)
|
|
440
|
+
return [];
|
|
441
|
+
const vec = await this.embedder.embed(query);
|
|
442
|
+
if (!vec)
|
|
443
|
+
return [];
|
|
444
|
+
const kEff = Math.min(k, this.meta.length);
|
|
445
|
+
// Same Float32Array→Array conversion as addPoint — hnswlib-node's
|
|
446
|
+
// searchKnn is also type-strict.
|
|
447
|
+
const { neighbors, distances } = this.hnsw.searchKnn(Array.from(vec), kEff);
|
|
448
|
+
const out = [];
|
|
449
|
+
for (let i = 0; i < neighbors.length; i++) {
|
|
450
|
+
const m = this.meta[neighbors[i]];
|
|
451
|
+
if (!m)
|
|
452
|
+
continue;
|
|
453
|
+
// hnswlib cosine "distance" = 1 - cosine_similarity (in [0, 2]) → flip
|
|
454
|
+
const sim = 1 - (distances[i] ?? 1);
|
|
455
|
+
out.push({ item: m, similarity: sim });
|
|
456
|
+
}
|
|
457
|
+
return out;
|
|
458
|
+
}
|
|
459
|
+
/** Quick info accessor for `aegis index --embed` / `aegis doctor`. */
|
|
460
|
+
getInfo() {
|
|
461
|
+
return this.info;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
// --- helpers ---------------------------------------------------------------
|
|
465
|
+
/** Allowed symbol-kind names. Methods include constructors / accessors / all
|
|
466
|
+
* the language-specific method variants from scip.proto. Types include classes,
|
|
467
|
+
* interfaces, structs, traits, type aliases, enums.
|
|
468
|
+
*/
|
|
469
|
+
const CODE_BEARING_KINDS = new Set([
|
|
470
|
+
// Callables
|
|
471
|
+
"Function", "Method", "Constructor", "AbstractMethod", "StaticMethod",
|
|
472
|
+
"ProtocolMethod", "PureVirtualMethod", "TraitMethod", "TypeClassMethod",
|
|
473
|
+
"SingletonMethod", "MethodSpecification", "Getter", "Setter",
|
|
474
|
+
// Types
|
|
475
|
+
"Class", "Interface", "Struct", "Trait", "Protocol", "Type",
|
|
476
|
+
"TypeAlias", "TypeClass", "Enum",
|
|
477
|
+
]);
|
|
478
|
+
/** Infer a symbol kind from the SCIP descriptor suffix.
|
|
479
|
+
*
|
|
480
|
+
* SCIP encodes the descriptor chain at the end of the symbol string after the
|
|
481
|
+
* last whitespace. The terminal descriptor's punctuation tells us what it is:
|
|
482
|
+
* `Foo).` → Method / Function (the `(...)` is the param disambiguator)
|
|
483
|
+
* `Foo#` → Type (class / interface / struct / type alias / enum)
|
|
484
|
+
* `Foo/` → Namespace / package / file
|
|
485
|
+
* `Foo.` → Term (variable / property / getter target — no parens before)
|
|
486
|
+
* `Foo[T]` → TypeParameter
|
|
487
|
+
* `(p1)` → Parameter
|
|
488
|
+
*
|
|
489
|
+
* We map the punctuation we care about to one of our `CODE_BEARING_KINDS`
|
|
490
|
+
* names so the downstream filter works uniformly across languages that DO
|
|
491
|
+
* populate `SymbolInformation.kind` (scip-java) and ones that DON'T
|
|
492
|
+
* (scip-typescript leaves it at 0 for every symbol).
|
|
493
|
+
*/
|
|
494
|
+
function inferKindFromDescriptor(symbolStr) {
|
|
495
|
+
const lastSpace = symbolStr.lastIndexOf(" ");
|
|
496
|
+
const chain = lastSpace >= 0 ? symbolStr.slice(lastSpace + 1) : symbolStr;
|
|
497
|
+
if (!chain)
|
|
498
|
+
return "Symbol";
|
|
499
|
+
if (chain.endsWith(")."))
|
|
500
|
+
return "Method"; // function or method
|
|
501
|
+
if (chain.endsWith("#"))
|
|
502
|
+
return "Type"; // class / interface / struct
|
|
503
|
+
if (chain.endsWith("/"))
|
|
504
|
+
return "Namespace";
|
|
505
|
+
if (chain.endsWith(":"))
|
|
506
|
+
return "Meta";
|
|
507
|
+
if (chain.endsWith("."))
|
|
508
|
+
return "Term"; // variable / property
|
|
509
|
+
return "Symbol";
|
|
510
|
+
}
|
|
511
|
+
/** Pull a human-friendly display name out of a SCIP symbol string.
|
|
512
|
+
*
|
|
513
|
+
* Examples:
|
|
514
|
+
* "scip-typescript npm @aegis/aegis-v2 0.1.0 src/util/`logger.ts`/getLogger()."
|
|
515
|
+
* → "getLogger"
|
|
516
|
+
* "scip-typescript npm @aegis/aegis-v2 0.1.0 src/util/`logger.ts`/LogLevel#"
|
|
517
|
+
* → "LogLevel"
|
|
518
|
+
* "scip-typescript npm @aegis/aegis-v2 0.1.0 src/index.ts/Foo#bar()."
|
|
519
|
+
* → "bar"
|
|
520
|
+
*/
|
|
521
|
+
function deriveDisplayName(symbolStr) {
|
|
522
|
+
const lastSpace = symbolStr.lastIndexOf(" ");
|
|
523
|
+
let chain = lastSpace >= 0 ? symbolStr.slice(lastSpace + 1) : symbolStr;
|
|
524
|
+
// Strip backticks (used to quote path segments containing dots, e.g. `logger.ts`)
|
|
525
|
+
chain = chain.replace(/`/g, "");
|
|
526
|
+
// Split on the descriptor separator '/' and take the rightmost non-empty
|
|
527
|
+
// segment. That's the symbol's local name (possibly with disambiguator suffix).
|
|
528
|
+
const segments = chain.split("/").filter(Boolean);
|
|
529
|
+
let tail = segments[segments.length - 1] ?? chain;
|
|
530
|
+
// For methods, the form is "name(disambig).". Strip the "(...)." suffix.
|
|
531
|
+
// For types it's "Name#" — strip the '#'. For terms it's "Name." — strip the '.'.
|
|
532
|
+
tail = tail.replace(/\([^)]*\)\.$/, "");
|
|
533
|
+
tail = tail.replace(/[#.]+$/, "");
|
|
534
|
+
// Sometimes the segment itself contains '#' (e.g. "Foo#bar()") — take last token.
|
|
535
|
+
const hashIdx = tail.lastIndexOf("#");
|
|
536
|
+
if (hashIdx >= 0 && hashIdx < tail.length - 1) {
|
|
537
|
+
tail = tail.slice(hashIdx + 1);
|
|
538
|
+
}
|
|
539
|
+
return tail || "?";
|
|
540
|
+
}
|
|
541
|
+
function readSnippet(root, rel, sLine, eLine, maxChars) {
|
|
542
|
+
try {
|
|
543
|
+
const abs = resolve(root, rel);
|
|
544
|
+
if (!existsSync(abs))
|
|
545
|
+
return undefined;
|
|
546
|
+
const st = statSync(abs);
|
|
547
|
+
if (!st.isFile() || st.size > 2 * 1024 * 1024)
|
|
548
|
+
return undefined;
|
|
549
|
+
const lines = readFileSync(abs, "utf8").split(/\r?\n/);
|
|
550
|
+
const sl = Math.max(1, sLine);
|
|
551
|
+
const el = Math.min(lines.length, Math.max(sl, eLine) + 5);
|
|
552
|
+
const snippet = lines.slice(sl - 1, el).join("\n");
|
|
553
|
+
return snippet.slice(0, maxChars);
|
|
554
|
+
}
|
|
555
|
+
catch {
|
|
556
|
+
return undefined;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
// --- singleton accessor ----------------------------------------------------
|
|
560
|
+
const _indices = new Map();
|
|
561
|
+
export function getEmbeddingIndex(projectRoot) {
|
|
562
|
+
const key = resolve(projectRoot);
|
|
563
|
+
let ix = _indices.get(key);
|
|
564
|
+
if (!ix) {
|
|
565
|
+
ix = new EmbeddingIndex(key);
|
|
566
|
+
_indices.set(key, ix);
|
|
567
|
+
}
|
|
568
|
+
return ix;
|
|
569
|
+
}
|
|
570
|
+
//# sourceMappingURL=embeddings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../../src/index/embeddings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEvF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9C,MAAM,GAAG,GAAG,SAAS,CAAC,kBAAkB,CAAC,CAAC;AAE1C,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,yBAAyB,CAAC;AACjF,MAAM,WAAW,GAAG,GAAG,CAAC;AACxB,MAAM,oBAAoB,GAAG,SAAS,CAAC;AACvC,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAChC,MAAM,eAAe,GAAG,KAAK,CAAC;AAE9B,SAAS,SAAS;IAChB,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,UAAU;QACtB,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,GAAG,EAAE,QAAQ,CAAC,CACtE,CAAC;AACJ,CAAC;AACD,SAAS,WAAW,CAAC,WAAmB;IACtC,MAAM,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvF,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;AAC5C,CAAC;AAwCD,IAAI,MAAM,GAAiB,IAAI,CAAC;AAChC,KAAK,UAAU,MAAM;IACnB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAqB,CAAC;QAC5E,4DAA4D;QAC5D,GAAG,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC/C,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,mEAAmE;QACnE,GAAG,CAAC,GAAG,CAAC,iBAAiB,GAAG,IAAI,CAAC;QACjC,gDAAgD;QAChD,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,GAAG,CAAC,CAAC;YACzD,IAAI,CAAC,GAAG,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QAClD,CAAC;QACD,MAAM,GAAG,GAAG,CAAC;QACb,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,yCAAyC,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC1E,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,OAAO,QAAQ;IAIU;IAHrB,SAAS,GAAsB,IAAI,CAAC;IACpC,IAAI,GAAW,WAAW,CAAC;IAEnC,YAA6B,YAAoB,aAAa;QAAjC,cAAS,GAAT,SAAS,CAAwB;IAAG,CAAC;IAElE,uEAAuE;IACvE,KAAK,CAAC,YAAY;QAChB,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAChC,MAAM,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC;QAC1B,IAAI,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC;QACtB,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YAC/D,IAAI,CAAC,SAAS,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACzE,8BAA8B;YAC9B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9E,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,WAAW,CAAC;YACpF,GAAG,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAC7E,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,6BAA6B,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACrF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,wEAAwE;IACxE,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QACjE,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;QACjD,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;YAAE,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,wBAAwB;QAC3E,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1E,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,YAAY,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,IAAgB,CAAC,CAAC;YAClG,iEAAiE;YACjE,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC7B,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC1C,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;gBACnC,OAAO,KAAK,CAAC;YACf,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,kEAAkE;IAClE,KAAK,CAAC,UAAU,CAAC,KAA4B;QAC3C,MAAM,GAAG,GAA+B,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF;AAuBD,IAAI,QAAQ,GAAmB,IAAI,CAAC;AACpC,KAAK,UAAU,QAAQ;IACrB,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,cAAc,CAAC,CAA+C,CAAC;QACzF,QAAQ,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAY,CAAC;QAC3C,IAAI,OAAO,QAAQ,CAAC,eAAe,KAAK,UAAU,EAAE,CAAC;YACnD,GAAG,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;YAC1C,QAAQ,GAAG,IAAI,CAAC;YAChB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,4BAA4B,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,8EAA8E;AAE9E,MAAM,OAAO,cAAc;IAMN;IACA;IANX,IAAI,GAAwB,IAAI,CAAC;IACjC,IAAI,GAAmB,EAAE,CAAC;IAC1B,IAAI,GAA0B,IAAI,CAAC;IAE3C,YACmB,WAAmB,EACnB,WAAqB,IAAI,QAAQ,EAAE;QADnC,gBAAW,GAAX,WAAW,CAAQ;QACnB,aAAQ,GAAR,QAAQ,CAA2B;IACnD,CAAC;IAEI,GAAG;QACT,OAAO,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC;IACO,SAAS;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;IACxC,CAAC;IACO,QAAQ;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;IACxC,CAAC;IACO,QAAQ;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;IACvC,CAAC;IAED,8DAA8D;IAC9D,YAAY;QACV,OAAO,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACpG,CAAC;IAED,oFAAoF;IACpF,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YAAE,OAAO,KAAK,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAmB,CAAC;YACjF,MAAM,OAAO,GAAG,MAAM,QAAQ,EAAE,CAAC;YACjC,IAAI,CAAC,OAAO;gBAAE,OAAO,KAAK,CAAC;YAC3B,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5D,sEAAsE;YACtE,qEAAqE;YACrE,uEAAuE;YACvE,qEAAqE;YACrE,gEAAgE;YAChE,IAAI,OAAO,GAAG,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;gBAC5C,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YACtC,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YACxC,CAAC;YACD,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClD,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;YAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC;iBAC9C,KAAK,CAAC,OAAO,CAAC;iBACd,MAAM,CAAC,OAAO,CAAC;iBACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAiB,CAAC,CAAC;YAC7C,GAAG,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACxE,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,6BAA6B,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK,CAAC,IAAiB,EAAE,IAA8B;QAC3D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,GAAG,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;YACxE,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;QACnD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;YAC5D,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,QAAQ,EAAE,CAAC;QACjC,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QAE3B,8DAA8D;QAC9D,MAAM,GAAG,GAAG,IAAI,EAAE,UAAU,IAAI,MAAM,CAAC;QACvC,MAAM,UAAU,GAAmG,EAAE,CAAC;QAEtH,qEAAqE;QACrE,sEAAsE;QACtE,wEAAwE;QACxE,sEAAsE;QACtE,qEAAqE;QACrE,EAAE;QACF,wEAAwE;QACxE,iEAAiE;QACjE,6CAA6C;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QAC/D,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,gFAAgF;YAChF,GAAG,CAAC,IAAI,CACN,qIAAqI,EACrI,EAAE,MAAM,EAAE,CACX,CAAC;YACF,OAAO,KAAK,CAAC;QACf,CAAC;QACD,mDAAmD;QACnD,MAAM,UAAU,GAAG,CAAC,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC;QAC9D,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,2GAA2G;QACxJ,KAAK,SAAS,CAAC;QAgBf,MAAM,WAAW,GAAG,CAAC,MAAM,MAAM,CAAC,YAAY,CAAC,CAA+C,CAAC;QAC/F,MAAM,KAAK,GACT,CAAC,WAAW,CAAC,OAAO,IAAI,OAAO,WAAW,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU;YACpE,CAAC,CAAC,WAAW,CAAC,OAAO;YACrB,CAAC,CAAC,WAAW,CAAY,CAAC;QAC9B,sHAAsH;QACtH,MAAM,aAAa,GAAG;YACpB,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC;YAC7D,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC;YAC9D,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC;YACnE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC;YACpE,mCAAmC;YACnC,OAAO,CACL,IAAI,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,EACtE,OAAO,EACP,YAAY,CACb;SACF,CAAC;QACF,IAAI,SAAS,GAAkB,IAAI,CAAC;QACpC,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;YAC9B,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;gBAAC,SAAS,GAAG,CAAC,CAAC;gBAAC,MAAM;YAAC,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,GAAG,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;YACtD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACtE,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QAEhD,2EAA2E;QAC3E,0EAA0E;QAC1E,yEAAyE;QACzE,uEAAuE;QACvE,iEAAiE;QACjE,mEAAmE;QACnE,MAAM,QAAQ,GAAqC;YACjD,CAAC,EAAE,iBAAiB;YACpB,yBAAyB;YACzB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU;YACtE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,gBAAgB;YAC9E,mDAAmD;YACnD,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,gBAAgB;YACpE,EAAE,EAAE,qBAAqB,EAAE,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE,mBAAmB;YACxE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,iBAAiB;YAC/D,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ;YAC9C,+CAA+C;YAC/C,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM;YACrE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW;YACpE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU;YAC5E,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,OAAO;SAC5E,CAAC;QAEF,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,SAAS;YACrC,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;YAC5C,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAClC,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE;gBAClC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;gBAC3C,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI;aAC3D,CAAsS,CAAC;YACxS,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,IAAI,GAAG,EAA6C,CAAC;YACrE,KAAK,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;gBAC5F,IAAI,CAAC,EAAE,CAAC,MAAM;oBAAE,SAAS;gBACzB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE;oBACrB,OAAO,EAAE,EAAE,CAAC,YAAY,IAAI,iBAAiB,CAAC,EAAE,CAAC,MAAM,CAAC;oBACxD,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,iBAAiB;iBAClD,CAAC,CAAC;YACL,CAAC;YACD,iEAAiE;YACjE,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBACrB,MAAM,GAAG,GAAG,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC;gBAClC,IAAI,CAAC,GAAG;oBAAE,SAAS;gBACnB,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;oBACtC,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,IAAI,CAAC,CAAC;oBACpC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;wBAAE,SAAS,CAAC,mBAAmB;oBACpD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;oBACrC,IAAI,IAAI,GAAG,IAAI,EAAE,OAAO,IAAI,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;oBAC1D,IAAI,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,iBAAiB,CAAC;oBAC3C,mEAAmE;oBACnE,qEAAqE;oBACrE,kEAAkE;oBAClE,6DAA6D;oBAC7D,yDAAyD;oBACzD,IAAI,IAAI,KAAK,iBAAiB,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;wBACpD,IAAI,GAAG,uBAAuB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;oBAC7C,CAAC;oBACD,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG;wBAAE,IAAI,GAAG,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;oBAChE,sEAAsE;oBACtE,kEAAkE;oBAClE,iCAAiC;oBACjC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC;wBAAE,SAAS;oBAC5C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;oBACxB,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;oBACpC,MAAM,KAAK,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBACnE,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;oBACpF,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE;wBAAE,SAAS;oBAC9C,UAAU,CAAC,IAAI,CAAC;wBACd,EAAE,EAAE,GAAG,CAAC,MAAM;wBACd,IAAI,EAAE,GAAG;wBACT,IAAI,EAAE,KAAK;wBACX,IAAI;wBACJ,IAAI;wBACJ,OAAO;qBACR,CAAC,CAAC;oBACH,IAAI,UAAU,CAAC,MAAM,IAAI,GAAG;wBAAE,MAAM;gBACtC,CAAC;gBACD,IAAI,UAAU,CAAC,MAAM,IAAI,GAAG;oBAAE,MAAM;YACtC,CAAC;YACD,IAAI,UAAU,CAAC,MAAM,IAAI,GAAG;gBAAE,MAAM;QACtC,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,GAAG,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;YACzD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,gCAAgC,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;QAEzE,YAAY;QACZ,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACvD,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;QAC9F,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEf,MAAM,OAAO,GAAmB,EAAE,CAAC;QACnC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC;YACzB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YACjD,IAAI,CAAC,GAAG;gBAAE,SAAS;YACnB,+DAA+D;YAC/D,oEAAoE;YACpE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,CAAC;gBACL,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,QAAQ,EAAE,CAAC,CAAC,EAAE;gBACd,WAAW,EAAE,CAAC,CAAC,IAAI;gBACnB,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC;aAC/C,CAAC,CAAC;YACH,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBAC1E,GAAG,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;YAChG,CAAC;QACH,CAAC;QAED,UAAU;QACV,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,IAAI,OAAO,GAAG,CAAC,cAAc,KAAK,UAAU,EAAE,CAAC;YAC7C,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QACzC,CAAC;QACD,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;QAChG,MAAM,IAAI,GAAmB;YAC3B,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK;YAC1B,GAAG;YACH,IAAI,EAAE,OAAO,CAAC,MAAM;YACpB,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;YACpB,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpD,CAAC;QACF,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAEtE,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;QAChB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,GAAG,CAAC,IAAI,CAAC,uBAAuB,EAAE;YAChC,IAAI,EAAE,OAAO,CAAC,MAAM;YACpB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE;YAC3B,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE;SAChB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qEAAqE;IACrE,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,CAAS;QACjC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YAAE,OAAO,EAAE,CAAC;QAClD,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACpD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3C,kEAAkE;QAClE,iCAAiC;QACjC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;QAC5E,MAAM,GAAG,GAAkB,EAAE,CAAC;QAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC,CAAC;YACnC,IAAI,CAAC,CAAC;gBAAE,SAAS;YACjB,uEAAuE;YACvE,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACpC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,sEAAsE;IACtE,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;CACF;AAED,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,kBAAkB,GAAwB,IAAI,GAAG,CAAC;IACtD,YAAY;IACZ,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc;IACrE,gBAAgB,EAAE,mBAAmB,EAAE,aAAa,EAAE,iBAAiB;IACvE,iBAAiB,EAAE,qBAAqB,EAAE,QAAQ,EAAE,QAAQ;IAC5D,QAAQ;IACR,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM;IAC3D,WAAW,EAAE,WAAW,EAAE,MAAM;CACjC,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;GAeG;AACH,SAAS,uBAAuB,CAAC,SAAiB;IAChD,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1E,IAAI,CAAC,KAAK;QAAE,OAAO,QAAQ,CAAC;IAC5B,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC,CAAG,qBAAqB;IAClE,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC,CAAO,6BAA6B;IAC3E,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,WAAW,CAAC;IAC5C,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC;IACvC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC,CAAO,sBAAsB;IACpE,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,iBAAiB,CAAC,SAAiB;IAC1C,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,KAAK,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,kFAAkF;IAClF,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAChC,yEAAyE;IACzE,gFAAgF;IAChF,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClD,IAAI,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC;IAClD,yEAAyE;IACzE,kFAAkF;IAClF,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IACxC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAClC,kFAAkF;IAClF,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,OAAO,IAAI,CAAC,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,IAAI,GAAG,CAAC;AACrB,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,GAAW,EAAE,KAAa,EAAE,KAAa,EAAE,QAAgB;IAC5F,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QACvC,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI;YAAE,OAAO,SAAS,CAAC;QAChE,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACvD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAC9B,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,8EAA8E;AAE9E,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;AACnD,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACjC,IAAI,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,EAAE,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7B,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Finding } from "../findings.js";
|
|
2
|
+
export interface CallerSideRiskHit {
|
|
3
|
+
/** The raw import string as it appeared in source (``"db"`` or
|
|
4
|
+
* ``"services.pricing"``). */
|
|
5
|
+
importedModule: string;
|
|
6
|
+
/** Project-relative POSIX path of the resolved file. */
|
|
7
|
+
resolvedFile: string;
|
|
8
|
+
/** The finding (from Joern or Pysa) that lives in the imported module. */
|
|
9
|
+
finding: Finding;
|
|
10
|
+
/** Which engine produced the finding (handy for routing logs / critic
|
|
11
|
+
* context — ``joern`` is structural, ``pysa`` is taint reachability). */
|
|
12
|
+
sourceEngine: "joern" | "pysa";
|
|
13
|
+
}
|
|
14
|
+
/** Top-level Python imports — both ``from X import Y`` and ``import X``
|
|
15
|
+
* (and dotted forms like ``import services.pricing``). Aliases via ``as``
|
|
16
|
+
* are intentionally ignored — we care about the SOURCE module, not the
|
|
17
|
+
* local binding. */
|
|
18
|
+
export declare function parsePythonImports(content: string): string[];
|
|
19
|
+
/** Top-level JS/TS imports — `import … from "…"` and `require("…")`.
|
|
20
|
+
* Currently parsed for future use; ``resolveImportToFile`` returns null
|
|
21
|
+
* for JS so these don't yet contribute to routing. */
|
|
22
|
+
export declare function parseJsImports(content: string): string[];
|
|
23
|
+
/** Resolve a Python module name to a file inside ``projectRoot``. Returns
|
|
24
|
+
* the absolute path or null when not found. */
|
|
25
|
+
export declare function resolveImportToFile(importStr: string, projectRoot: string, lang: string): string | null;
|
|
26
|
+
/** Inspect ``content``'s imports + the project's cached findings; return
|
|
27
|
+
* one hit per (import, finding) pair when the imported module already has
|
|
28
|
+
* a cached finding. */
|
|
29
|
+
export declare function findCallerSideRiskSignals(content: string, projectRoot: string, lang: string): CallerSideRiskHit[];
|
|
30
|
+
export declare const _testing: {
|
|
31
|
+
parsePythonImports: typeof parsePythonImports;
|
|
32
|
+
parseJsImports: typeof parseJsImports;
|
|
33
|
+
resolveImportToFile: typeof resolveImportToFile;
|
|
34
|
+
findCallerSideRiskSignals: typeof findCallerSideRiskSignals;
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=graph_routing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph_routing.d.ts","sourceRoot":"","sources":["../../src/index/graph_routing.ts"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAM9C,MAAM,WAAW,iBAAiB;IAChC;kCAC8B;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAC;IACjB;6EACyE;IACzE,YAAY,EAAE,OAAO,GAAG,MAAM,CAAC;CAChC;AAID;;;oBAGoB;AACpB,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CA2B5D;AAED;;sDAEsD;AACtD,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAMxD;AAID;+CAC+C;AAC/C,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,IAAI,CAiBf;AAID;;uBAEuB;AACvB,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GACX,iBAAiB,EAAE,CAiDrB;AAGD,eAAO,MAAM,QAAQ;;;;;CAKpB,CAAC"}
|