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,76 @@
|
|
|
1
|
+
import { Cache } from "../cache.js";
|
|
2
|
+
/** SCIP symbol-role bitfield (from scip.proto). */
|
|
3
|
+
export declare enum SymbolRole {
|
|
4
|
+
Unspecified = 0,
|
|
5
|
+
Definition = 1,
|
|
6
|
+
Import = 2,
|
|
7
|
+
WriteAccess = 4,
|
|
8
|
+
ReadAccess = 8,
|
|
9
|
+
Generated = 16,
|
|
10
|
+
Test = 32,
|
|
11
|
+
ForwardDefinition = 64
|
|
12
|
+
}
|
|
13
|
+
export interface SymbolInfo {
|
|
14
|
+
/** Canonical SCIP id (e.g. ``scip-python python . models.py:User#``). */
|
|
15
|
+
symbolId: string;
|
|
16
|
+
/** Short, human-readable display name (e.g. ``User``). */
|
|
17
|
+
displayName: string;
|
|
18
|
+
/** Function|Class|Variable|... — extracted from SymbolInformation.kind. */
|
|
19
|
+
kind: string;
|
|
20
|
+
/** Optional type signature when present in the index. */
|
|
21
|
+
signature?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface Location {
|
|
24
|
+
file: string;
|
|
25
|
+
startLine: number;
|
|
26
|
+
startChar: number;
|
|
27
|
+
endLine: number;
|
|
28
|
+
endChar: number;
|
|
29
|
+
}
|
|
30
|
+
export interface DefinitionResult {
|
|
31
|
+
symbolId: string;
|
|
32
|
+
displayName: string;
|
|
33
|
+
kind: string;
|
|
34
|
+
signature?: string;
|
|
35
|
+
location: Location;
|
|
36
|
+
/** Source code at the definition range (with a small margin). */
|
|
37
|
+
snippet?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface ReferenceResult {
|
|
40
|
+
symbolId: string;
|
|
41
|
+
location: Location;
|
|
42
|
+
roles: SymbolRole[];
|
|
43
|
+
}
|
|
44
|
+
interface ScipMeta {
|
|
45
|
+
builtAt: number;
|
|
46
|
+
filesIndexed: number;
|
|
47
|
+
documents: number;
|
|
48
|
+
symbols: number;
|
|
49
|
+
/** content-hash of the .scip file we ingested */
|
|
50
|
+
scipSha: string;
|
|
51
|
+
languages: string[];
|
|
52
|
+
}
|
|
53
|
+
export declare class SCIPIndexer {
|
|
54
|
+
private readonly cache;
|
|
55
|
+
constructor(cache: Cache);
|
|
56
|
+
/**
|
|
57
|
+
* Build (or refresh) the SCIP index for this project root. Idempotent.
|
|
58
|
+
* Returns false if no SCIP-compatible language found / no indexer installed.
|
|
59
|
+
*/
|
|
60
|
+
ensureIndexed(root: string): Promise<boolean>;
|
|
61
|
+
/** Force a re-index regardless of cache freshness. */
|
|
62
|
+
reindex(root: string): Promise<boolean>;
|
|
63
|
+
/** Decode + persist one .scip file into LMDB. */
|
|
64
|
+
private ingest;
|
|
65
|
+
meta(root: string): Promise<ScipMeta | undefined>;
|
|
66
|
+
findSymbolsByDisplay(root: string, displayName: string): Promise<SymbolInfo[]>;
|
|
67
|
+
defOf(root: string, symbolId: string): Promise<DefinitionResult | null>;
|
|
68
|
+
refsOf(root: string, symbolId: string): Promise<ReferenceResult[]>;
|
|
69
|
+
/** Callers = references whose role does NOT include Definition. */
|
|
70
|
+
callersOf(root: string, nameOrId: string): Promise<ReferenceResult[]>;
|
|
71
|
+
}
|
|
72
|
+
export declare function getIndexer(cacheRoot?: string): SCIPIndexer;
|
|
73
|
+
/** Utility for callers that want a path relative to the project root. */
|
|
74
|
+
export declare function relPath(root: string, abs: string): string;
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=scip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scip.d.ts","sourceRoot":"","sources":["../../src/index/scip.ts"],"names":[],"mappings":"AA4BA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAkBpC,mDAAmD;AACnD,oBAAY,UAAU;IACpB,WAAW,IAAI;IACf,UAAU,IAAI;IACd,MAAM,IAAI;IACV,WAAW,IAAI;IACf,UAAU,IAAI;IACd,SAAS,KAAK;IACd,IAAI,KAAK;IACT,iBAAiB,KAAK;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAcD,UAAU,QAAQ;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAwQD,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,KAAK;IAEzC;;;OAGG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASnD,sDAAsD;IAChD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAwF7C,iDAAiD;YACnC,MAAM;IA6Fd,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAIjD,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAiB9E,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAqBvE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAexE,mEAAmE;IAC7D,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAiB5E;AA2BD,wBAAgB,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,CAK1D;AAED,yEAAyE;AACzE,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzD"}
|
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SCIP-based project indexer.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the official Sourcegraph indexers (``scip-typescript``,
|
|
5
|
+
* ``scip-python``) — they emit a binary protobuf "Index". We decode the
|
|
6
|
+
* Index with ``@sourcegraph/scip``, then store per-symbol records in LMDB
|
|
7
|
+
* for O(1) lookup at gate time.
|
|
8
|
+
*
|
|
9
|
+
* Public API (used by the context engine):
|
|
10
|
+
* - ``ensureIndexed(root)`` — build (or refresh stale) the index for the
|
|
11
|
+
* project root. Runs the appropriate scip-* binaries.
|
|
12
|
+
* - ``findSymbolsByDisplay(root, name)`` — fuzzy resolve ``User`` →
|
|
13
|
+
* ``scip-python python . models.py::User#``.
|
|
14
|
+
* - ``defOf(root, symId)`` — definition site + code snippet.
|
|
15
|
+
* - ``refsOf(root, symId)`` — every reference + role.
|
|
16
|
+
* - ``callersOf(root, displayName | symId)`` — refs whose role is NOT
|
|
17
|
+
* Definition (i.e. read-uses / call-sites).
|
|
18
|
+
*
|
|
19
|
+
* The index is persisted in ``.aegis/scip/`` (LMDB) + ``.aegis/scip/raw/``
|
|
20
|
+
* for the .scip protobuf snapshots. Stale-check: if any source file's mtime
|
|
21
|
+
* is newer than the index's recorded mtime, re-run before serving queries.
|
|
22
|
+
*/
|
|
23
|
+
import { createHash } from "node:crypto";
|
|
24
|
+
import { existsSync, mkdirSync, readFileSync, statSync } from "node:fs";
|
|
25
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
26
|
+
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
27
|
+
import { fileURLToPath } from "node:url";
|
|
28
|
+
import { Cache } from "../cache.js";
|
|
29
|
+
import { getLogger } from "../util/logger.js";
|
|
30
|
+
import { run, which } from "../util/subprocess.js";
|
|
31
|
+
// Resolve our own package directory so we can find the bundled scip.proto
|
|
32
|
+
// and look up node_modules/.bin/scip-* relative to ourselves.
|
|
33
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
34
|
+
const __dirname = dirname(__filename);
|
|
35
|
+
const PKG_ROOT = resolve(__dirname, "..", "..");
|
|
36
|
+
const log = getLogger("aegis.index.scip");
|
|
37
|
+
const STALE_TTL_MS = Number(process.env.AEGIS_SCIP_TTL_MS ?? 30 * 60 * 1000); // 30 min
|
|
38
|
+
const MAX_SNIPPET_LINES = 80;
|
|
39
|
+
const MAX_INDEX_TIMEOUT_MS = Number(process.env.AEGIS_SCIP_INDEX_TIMEOUT_MS ?? 60_000);
|
|
40
|
+
// --- Public surface types ---------------------------------------------------
|
|
41
|
+
/** SCIP symbol-role bitfield (from scip.proto). */
|
|
42
|
+
export var SymbolRole;
|
|
43
|
+
(function (SymbolRole) {
|
|
44
|
+
SymbolRole[SymbolRole["Unspecified"] = 0] = "Unspecified";
|
|
45
|
+
SymbolRole[SymbolRole["Definition"] = 1] = "Definition";
|
|
46
|
+
SymbolRole[SymbolRole["Import"] = 2] = "Import";
|
|
47
|
+
SymbolRole[SymbolRole["WriteAccess"] = 4] = "WriteAccess";
|
|
48
|
+
SymbolRole[SymbolRole["ReadAccess"] = 8] = "ReadAccess";
|
|
49
|
+
SymbolRole[SymbolRole["Generated"] = 16] = "Generated";
|
|
50
|
+
SymbolRole[SymbolRole["Test"] = 32] = "Test";
|
|
51
|
+
SymbolRole[SymbolRole["ForwardDefinition"] = 64] = "ForwardDefinition";
|
|
52
|
+
})(SymbolRole || (SymbolRole = {}));
|
|
53
|
+
// --- LMDB key namespacing ---------------------------------------------------
|
|
54
|
+
function rootKey(root) {
|
|
55
|
+
return createHash("sha256").update(resolve(root)).digest("hex").slice(0, 16);
|
|
56
|
+
}
|
|
57
|
+
const k = {
|
|
58
|
+
meta: (r) => `scip:meta:${rootKey(r)}`,
|
|
59
|
+
symbol: (r, id) => `scip:sym:${rootKey(r)}:${id}`,
|
|
60
|
+
refs: (r, id) => `scip:refs:${rootKey(r)}:${id}`,
|
|
61
|
+
nameIdx: (r, name) => `scip:byname:${rootKey(r)}:${name}`,
|
|
62
|
+
};
|
|
63
|
+
async function fileWalk(root, acc, visited, maxFiles) {
|
|
64
|
+
if (visited >= maxFiles)
|
|
65
|
+
return visited;
|
|
66
|
+
let entries;
|
|
67
|
+
try {
|
|
68
|
+
entries = await readdir(root, { withFileTypes: true });
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return visited;
|
|
72
|
+
}
|
|
73
|
+
for (const e of entries) {
|
|
74
|
+
if (visited >= maxFiles)
|
|
75
|
+
return visited;
|
|
76
|
+
if (e.name.startsWith("."))
|
|
77
|
+
continue;
|
|
78
|
+
if (e.isDirectory() &&
|
|
79
|
+
["node_modules", "dist", "build", "venv", ".venv", "__pycache__", "target", "vendor"].includes(e.name)) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const full = join(root, e.name);
|
|
83
|
+
if (e.isDirectory()) {
|
|
84
|
+
visited = await fileWalk(full, acc, visited, maxFiles);
|
|
85
|
+
}
|
|
86
|
+
else if (e.isFile()) {
|
|
87
|
+
acc.push(full);
|
|
88
|
+
visited++;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return visited;
|
|
92
|
+
}
|
|
93
|
+
async function hasExt(root, exts) {
|
|
94
|
+
const collected = [];
|
|
95
|
+
await fileWalk(root, collected, 0, 2000);
|
|
96
|
+
for (const f of collected) {
|
|
97
|
+
const ext = f.slice(f.lastIndexOf("."));
|
|
98
|
+
if (exts.includes(ext))
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
async function findScipBin(name) {
|
|
104
|
+
const override = process.env[`AEGIS_${name.toUpperCase().replace(/-/g, "_")}_BIN`];
|
|
105
|
+
if (override && existsSync(override))
|
|
106
|
+
return override;
|
|
107
|
+
// Walk up from this file's location looking for node_modules/.bin/<name>
|
|
108
|
+
// (or .cmd on Windows). This is how npm-installed deps are exposed when
|
|
109
|
+
// we ship as a library — the consumer's project has us under
|
|
110
|
+
// node_modules/@aegis/aegis-v2 and the scip binaries one level up.
|
|
111
|
+
const candidates = [
|
|
112
|
+
join(PKG_ROOT, "node_modules", ".bin", `${name}.cmd`),
|
|
113
|
+
join(PKG_ROOT, "node_modules", ".bin", name),
|
|
114
|
+
join(PKG_ROOT, "..", ".bin", `${name}.cmd`),
|
|
115
|
+
join(PKG_ROOT, "..", ".bin", name),
|
|
116
|
+
join(PKG_ROOT, "..", "..", ".bin", `${name}.cmd`),
|
|
117
|
+
join(PKG_ROOT, "..", "..", ".bin", name),
|
|
118
|
+
];
|
|
119
|
+
for (const c of candidates) {
|
|
120
|
+
if (existsSync(c))
|
|
121
|
+
return c;
|
|
122
|
+
}
|
|
123
|
+
return (await which(name)) ?? (await which(`${name}.cmd`));
|
|
124
|
+
}
|
|
125
|
+
const SPECS_FACTORY = async () => {
|
|
126
|
+
const tsBin = await findScipBin("scip-typescript");
|
|
127
|
+
const pyBin = await findScipBin("scip-python");
|
|
128
|
+
const out = [];
|
|
129
|
+
if (tsBin) {
|
|
130
|
+
out.push({
|
|
131
|
+
bin: tsBin,
|
|
132
|
+
args: (root, outPath) => ["index", "--cwd", root, "--output", outPath],
|
|
133
|
+
applies: (root) => hasExt(root, [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]),
|
|
134
|
+
language: "typescript",
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
if (pyBin) {
|
|
138
|
+
out.push({
|
|
139
|
+
bin: pyBin,
|
|
140
|
+
args: (root, outPath) => ["index", "--project-root", root, "--output", outPath],
|
|
141
|
+
applies: (root) => hasExt(root, [".py"]),
|
|
142
|
+
language: "python",
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return out;
|
|
146
|
+
};
|
|
147
|
+
// SymbolInformation.Kind enum from scip.proto — we map the common ones to a
|
|
148
|
+
// short string. Unknown → "Symbol".
|
|
149
|
+
const KIND_MAP = {
|
|
150
|
+
0: "Symbol", 7: "Class", 8: "Constant", 9: "Constructor", 12: "Enum",
|
|
151
|
+
13: "EnumMember", 14: "Field", 15: "File", 16: "Function", 17: "Interface",
|
|
152
|
+
18: "Key", 19: "Method", 21: "Module", 22: "Namespace", 23: "Null",
|
|
153
|
+
25: "Object", 26: "Operator", 27: "Package", 28: "Parameter", 29: "Property",
|
|
154
|
+
31: "String", 32: "Struct", 33: "Type", 34: "TypeParameter", 35: "Union",
|
|
155
|
+
36: "Variable",
|
|
156
|
+
};
|
|
157
|
+
function normRange(r) {
|
|
158
|
+
// SCIP encodes same-line ranges as [sL, sC, eC] (3 elements).
|
|
159
|
+
if (r.length === 3)
|
|
160
|
+
return [r[0], r[1], r[0], r[2]];
|
|
161
|
+
if (r.length >= 4)
|
|
162
|
+
return [r[0], r[1], r[2], r[3]];
|
|
163
|
+
return [0, 0, 0, 0];
|
|
164
|
+
}
|
|
165
|
+
function rolesFrom(bits) {
|
|
166
|
+
const all = [
|
|
167
|
+
SymbolRole.Definition, SymbolRole.Import, SymbolRole.WriteAccess,
|
|
168
|
+
SymbolRole.ReadAccess, SymbolRole.Generated, SymbolRole.Test,
|
|
169
|
+
SymbolRole.ForwardDefinition,
|
|
170
|
+
];
|
|
171
|
+
return all.filter((r) => (bits & r) !== 0);
|
|
172
|
+
}
|
|
173
|
+
/** Short display name extracted from a SCIP symbol id when explicit field is missing.
|
|
174
|
+
* e.g. ``scip-python python . models.py:User#`` → ``User`` */
|
|
175
|
+
function inferDisplayName(symbolId) {
|
|
176
|
+
// Take the last meaningful segment.
|
|
177
|
+
const tail = symbolId.replace(/[#().]+$/g, "");
|
|
178
|
+
const m = tail.split(/[\s:/\\]/);
|
|
179
|
+
return m[m.length - 1] || symbolId;
|
|
180
|
+
}
|
|
181
|
+
// --- Indexer class ----------------------------------------------------------
|
|
182
|
+
// Load the bundled scip.proto via protobufjs. We ship the official .proto from
|
|
183
|
+
// github.com/sourcegraph/scip; this avoids depending on `@sourcegraph/scip`
|
|
184
|
+
// (which is not published on npm). Cached for the life of the process.
|
|
185
|
+
let _scipMod = null;
|
|
186
|
+
async function scipMod() {
|
|
187
|
+
if (_scipMod)
|
|
188
|
+
return _scipMod;
|
|
189
|
+
let protobuf;
|
|
190
|
+
try {
|
|
191
|
+
const mod = (await import("protobufjs"));
|
|
192
|
+
protobuf = (mod.default && typeof mod.default.loadSync === "function" ? mod.default : mod);
|
|
193
|
+
if (typeof protobuf.loadSync !== "function" || typeof protobuf.Root !== "function") {
|
|
194
|
+
log.warn("protobufjs unexpected shape on import");
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
log.warn("protobufjs not installed", { err: String(err) });
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
// proto lives at <pkg>/src/index/proto/scip.proto (during dev) or
|
|
203
|
+
// <pkg>/dist/index/proto/scip.proto (after build). Check both.
|
|
204
|
+
const protoCandidates = [
|
|
205
|
+
join(PKG_ROOT, "src", "index", "proto", "scip.proto"),
|
|
206
|
+
join(PKG_ROOT, "dist", "index", "proto", "scip.proto"),
|
|
207
|
+
join(__dirname, "proto", "scip.proto"),
|
|
208
|
+
];
|
|
209
|
+
let protoPath = null;
|
|
210
|
+
for (const c of protoCandidates) {
|
|
211
|
+
if (existsSync(c)) {
|
|
212
|
+
protoPath = c;
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (!protoPath) {
|
|
217
|
+
log.warn("scip.proto not found", { candidates: protoCandidates });
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
try {
|
|
221
|
+
const root = new protobuf.Root().loadSync(protoPath, { keepCase: true });
|
|
222
|
+
const IndexType = root.lookupType("scip.Index");
|
|
223
|
+
_scipMod = {
|
|
224
|
+
Index: {
|
|
225
|
+
decode: (buf) => {
|
|
226
|
+
const msg = IndexType.decode(buf);
|
|
227
|
+
// protobufjs returns Message instances; convert to plain JS for
|
|
228
|
+
// downstream code that expects { documents: [...] }.
|
|
229
|
+
// Field names are already snake_case because the Root was loaded
|
|
230
|
+
// with keepCase:true above.
|
|
231
|
+
return IndexType.toObject(msg, {
|
|
232
|
+
longs: Number,
|
|
233
|
+
enums: Number,
|
|
234
|
+
bytes: String,
|
|
235
|
+
defaults: false,
|
|
236
|
+
arrays: true,
|
|
237
|
+
objects: true,
|
|
238
|
+
oneofs: true,
|
|
239
|
+
});
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
return _scipMod;
|
|
244
|
+
}
|
|
245
|
+
catch (err) {
|
|
246
|
+
log.warn("scip proto load/parse failed", { err: String(err) });
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
export class SCIPIndexer {
|
|
251
|
+
cache;
|
|
252
|
+
constructor(cache) {
|
|
253
|
+
this.cache = cache;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Build (or refresh) the SCIP index for this project root. Idempotent.
|
|
257
|
+
* Returns false if no SCIP-compatible language found / no indexer installed.
|
|
258
|
+
*/
|
|
259
|
+
async ensureIndexed(root) {
|
|
260
|
+
const meta = await this.cache.get(k.meta(root));
|
|
261
|
+
if (meta && Date.now() - meta.builtAt < STALE_TTL_MS) {
|
|
262
|
+
log.debug("scip index fresh", { root, ageMs: Date.now() - meta.builtAt });
|
|
263
|
+
return true;
|
|
264
|
+
}
|
|
265
|
+
return this.reindex(root);
|
|
266
|
+
}
|
|
267
|
+
/** Force a re-index regardless of cache freshness. */
|
|
268
|
+
async reindex(root) {
|
|
269
|
+
const specs = await SPECS_FACTORY();
|
|
270
|
+
if (specs.length === 0) {
|
|
271
|
+
log.info("no scip indexers found", {
|
|
272
|
+
hint: "npm i -g @sourcegraph/scip-typescript @sourcegraph/scip-python",
|
|
273
|
+
});
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
const outDir = resolve(root, ".aegis", "scip", "raw");
|
|
277
|
+
mkdirSync(outDir, { recursive: true });
|
|
278
|
+
let totalDocs = 0;
|
|
279
|
+
let totalSymbols = 0;
|
|
280
|
+
let totalFiles = 0;
|
|
281
|
+
const langs = [];
|
|
282
|
+
let combinedSha = "";
|
|
283
|
+
for (const spec of specs) {
|
|
284
|
+
if (!(await spec.applies(root)))
|
|
285
|
+
continue;
|
|
286
|
+
langs.push(spec.language);
|
|
287
|
+
const outPath = join(outDir, `${spec.language}.scip`);
|
|
288
|
+
log.info("running scip indexer", { language: spec.language, bin: spec.bin });
|
|
289
|
+
const t0 = Date.now();
|
|
290
|
+
const r = await run(spec.bin, {
|
|
291
|
+
args: spec.args(root, outPath),
|
|
292
|
+
cwd: root,
|
|
293
|
+
timeoutMs: MAX_INDEX_TIMEOUT_MS,
|
|
294
|
+
});
|
|
295
|
+
if (r.timedOut) {
|
|
296
|
+
log.warn("scip indexer timed out", { language: spec.language });
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (r.exitCode !== 0) {
|
|
300
|
+
// Known issue: @sourcegraph/scip-python on Windows crashes on a
|
|
301
|
+
// RegExp(path.sep) at startup. Surface a clearer warning so the
|
|
302
|
+
// operator can swap indexers (e.g. install scip-python via pipx).
|
|
303
|
+
const isScipPyWindowsBug = spec.language === "python" &&
|
|
304
|
+
process.platform === "win32" &&
|
|
305
|
+
/Invalid regular expression.*pathSepRegex|new RegExp/.test(r.stderr);
|
|
306
|
+
if (isScipPyWindowsBug) {
|
|
307
|
+
log.warn("scip-python npm distribution is broken on Windows (upstream bug). " +
|
|
308
|
+
"Install the python-distributed indexer instead or run on WSL/Linux.");
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
log.warn("scip indexer failed", {
|
|
312
|
+
language: spec.language,
|
|
313
|
+
exit: r.exitCode,
|
|
314
|
+
stderr: r.stderr.slice(0, 300),
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
log.info("scip indexer finished", {
|
|
320
|
+
language: spec.language,
|
|
321
|
+
durationMs: Date.now() - t0,
|
|
322
|
+
});
|
|
323
|
+
// Ingest the .scip file
|
|
324
|
+
const stats = await this.ingest(root, outPath, spec.language);
|
|
325
|
+
totalDocs += stats.documents;
|
|
326
|
+
totalSymbols += stats.symbols;
|
|
327
|
+
totalFiles += stats.files;
|
|
328
|
+
combinedSha = createHash("sha256")
|
|
329
|
+
.update(combinedSha)
|
|
330
|
+
.update(stats.scipSha)
|
|
331
|
+
.digest("hex");
|
|
332
|
+
}
|
|
333
|
+
if (totalDocs === 0) {
|
|
334
|
+
log.warn("scip produced no documents; index empty");
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
const meta = {
|
|
338
|
+
builtAt: Date.now(),
|
|
339
|
+
filesIndexed: totalFiles,
|
|
340
|
+
documents: totalDocs,
|
|
341
|
+
symbols: totalSymbols,
|
|
342
|
+
scipSha: combinedSha,
|
|
343
|
+
languages: langs,
|
|
344
|
+
};
|
|
345
|
+
await this.cache.put(k.meta(root), meta);
|
|
346
|
+
log.info("scip index built", { root, ...meta });
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
/** Decode + persist one .scip file into LMDB. */
|
|
350
|
+
async ingest(root, scipPath, language) {
|
|
351
|
+
const mod = await scipMod();
|
|
352
|
+
if (!mod)
|
|
353
|
+
return { documents: 0, symbols: 0, files: 0, scipSha: "" };
|
|
354
|
+
const buf = await readFile(scipPath);
|
|
355
|
+
const sha = createHash("sha256").update(buf).digest("hex");
|
|
356
|
+
const index = mod.Index.decode(buf);
|
|
357
|
+
const docs = index.documents ?? [];
|
|
358
|
+
let symbolCount = 0;
|
|
359
|
+
// First pass: collect SymbolInformation per doc and external_symbols.
|
|
360
|
+
// We persist a per-symbol StoredSymbol record and a per-symbol refs list.
|
|
361
|
+
const refsAcc = new Map();
|
|
362
|
+
const symbolMeta = new Map();
|
|
363
|
+
const allSymInfo = [...(index.external_symbols ?? [])];
|
|
364
|
+
for (const d of docs) {
|
|
365
|
+
if (d.symbols)
|
|
366
|
+
allSymInfo.push(...d.symbols);
|
|
367
|
+
}
|
|
368
|
+
for (const si of allSymInfo) {
|
|
369
|
+
const display = si.display_name ?? inferDisplayName(si.symbol);
|
|
370
|
+
const kind = KIND_MAP[si.kind ?? 0] ?? "Symbol";
|
|
371
|
+
const signature = si.signature_documentation?.text ??
|
|
372
|
+
(si.documentation && si.documentation[0]) ??
|
|
373
|
+
undefined;
|
|
374
|
+
const prev = symbolMeta.get(si.symbol);
|
|
375
|
+
symbolMeta.set(si.symbol, {
|
|
376
|
+
displayName: display,
|
|
377
|
+
kind,
|
|
378
|
+
...(signature !== undefined ? { signature } : (prev?.signature !== undefined ? { signature: prev.signature } : {})),
|
|
379
|
+
...(prev?.definitionDoc !== undefined ? { definitionDoc: prev.definitionDoc } : {}),
|
|
380
|
+
...(prev?.definitionRange !== undefined ? { definitionRange: prev.definitionRange } : {}),
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
// Second pass: record occurrences. Definition role → mark stored symbol's def location.
|
|
384
|
+
for (const d of docs) {
|
|
385
|
+
const relPath = d.relative_path;
|
|
386
|
+
for (const occ of d.occurrences ?? []) {
|
|
387
|
+
const range = normRange(occ.range);
|
|
388
|
+
const roles = occ.symbol_roles ?? 0;
|
|
389
|
+
const isDef = (roles & SymbolRole.Definition) !== 0;
|
|
390
|
+
if (isDef) {
|
|
391
|
+
const prev = symbolMeta.get(occ.symbol) ?? {
|
|
392
|
+
displayName: inferDisplayName(occ.symbol),
|
|
393
|
+
kind: "Symbol",
|
|
394
|
+
};
|
|
395
|
+
symbolMeta.set(occ.symbol, {
|
|
396
|
+
...prev,
|
|
397
|
+
definitionDoc: relPath,
|
|
398
|
+
definitionRange: range,
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
// every occurrence becomes a ref (incl. defs; consumer filters by role)
|
|
402
|
+
let arr = refsAcc.get(occ.symbol);
|
|
403
|
+
if (!arr) {
|
|
404
|
+
arr = [];
|
|
405
|
+
refsAcc.set(occ.symbol, arr);
|
|
406
|
+
}
|
|
407
|
+
arr.push({ doc: relPath, range, roles });
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
// Persist
|
|
411
|
+
for (const [sym, info] of symbolMeta) {
|
|
412
|
+
await this.cache.put(k.symbol(root, sym), info);
|
|
413
|
+
// also store under the displayName index for fuzzy lookup (multiple ids per name OK)
|
|
414
|
+
const nameKey = k.nameIdx(root, info.displayName.toLowerCase());
|
|
415
|
+
const existing = (await this.cache.get(nameKey)) ?? [];
|
|
416
|
+
if (!existing.includes(sym)) {
|
|
417
|
+
existing.push(sym);
|
|
418
|
+
await this.cache.put(nameKey, existing);
|
|
419
|
+
}
|
|
420
|
+
symbolCount++;
|
|
421
|
+
}
|
|
422
|
+
for (const [sym, refs] of refsAcc) {
|
|
423
|
+
await this.cache.put(k.refs(root, sym), refs);
|
|
424
|
+
}
|
|
425
|
+
return {
|
|
426
|
+
documents: docs.length,
|
|
427
|
+
symbols: symbolCount,
|
|
428
|
+
files: docs.length,
|
|
429
|
+
scipSha: sha,
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
// --- Query API -----------------------------------------------------------
|
|
433
|
+
async meta(root) {
|
|
434
|
+
return this.cache.get(k.meta(root));
|
|
435
|
+
}
|
|
436
|
+
async findSymbolsByDisplay(root, displayName) {
|
|
437
|
+
if (!displayName)
|
|
438
|
+
return [];
|
|
439
|
+
const ids = (await this.cache.get(k.nameIdx(root, displayName.toLowerCase()))) ?? [];
|
|
440
|
+
const out = [];
|
|
441
|
+
for (const id of ids.slice(0, 32)) {
|
|
442
|
+
const s = await this.cache.get(k.symbol(root, id));
|
|
443
|
+
if (!s)
|
|
444
|
+
continue;
|
|
445
|
+
out.push({
|
|
446
|
+
symbolId: id,
|
|
447
|
+
displayName: s.displayName,
|
|
448
|
+
kind: s.kind,
|
|
449
|
+
...(s.signature !== undefined ? { signature: s.signature } : {}),
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
return out;
|
|
453
|
+
}
|
|
454
|
+
async defOf(root, symbolId) {
|
|
455
|
+
const s = await this.cache.get(k.symbol(root, symbolId));
|
|
456
|
+
if (!s || !s.definitionDoc || !s.definitionRange)
|
|
457
|
+
return null;
|
|
458
|
+
const loc = {
|
|
459
|
+
file: s.definitionDoc,
|
|
460
|
+
startLine: s.definitionRange[0] + 1,
|
|
461
|
+
startChar: s.definitionRange[1] + 1,
|
|
462
|
+
endLine: s.definitionRange[2] + 1,
|
|
463
|
+
endChar: s.definitionRange[3] + 1,
|
|
464
|
+
};
|
|
465
|
+
const snippet = readSnippet(root, s.definitionDoc, loc.startLine, loc.endLine);
|
|
466
|
+
return {
|
|
467
|
+
symbolId,
|
|
468
|
+
displayName: s.displayName,
|
|
469
|
+
kind: s.kind,
|
|
470
|
+
...(s.signature !== undefined ? { signature: s.signature } : {}),
|
|
471
|
+
location: loc,
|
|
472
|
+
...(snippet !== undefined ? { snippet } : {}),
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
async refsOf(root, symbolId) {
|
|
476
|
+
const refs = (await this.cache.get(k.refs(root, symbolId))) ?? [];
|
|
477
|
+
return refs.map((r) => ({
|
|
478
|
+
symbolId,
|
|
479
|
+
location: {
|
|
480
|
+
file: r.doc,
|
|
481
|
+
startLine: r.range[0] + 1,
|
|
482
|
+
startChar: r.range[1] + 1,
|
|
483
|
+
endLine: r.range[2] + 1,
|
|
484
|
+
endChar: r.range[3] + 1,
|
|
485
|
+
},
|
|
486
|
+
roles: rolesFrom(r.roles),
|
|
487
|
+
}));
|
|
488
|
+
}
|
|
489
|
+
/** Callers = references whose role does NOT include Definition. */
|
|
490
|
+
async callersOf(root, nameOrId) {
|
|
491
|
+
// accept either a display name or a full symbol id
|
|
492
|
+
let symbolIds = [nameOrId];
|
|
493
|
+
const looksLikeId = /[\s./:]/.test(nameOrId) || nameOrId.endsWith("#");
|
|
494
|
+
if (!looksLikeId) {
|
|
495
|
+
const found = await this.findSymbolsByDisplay(root, nameOrId);
|
|
496
|
+
symbolIds = found.map((s) => s.symbolId);
|
|
497
|
+
}
|
|
498
|
+
const out = [];
|
|
499
|
+
for (const id of symbolIds) {
|
|
500
|
+
const refs = await this.refsOf(root, id);
|
|
501
|
+
for (const r of refs) {
|
|
502
|
+
if (!r.roles.includes(SymbolRole.Definition))
|
|
503
|
+
out.push(r);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return out;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
// --- snippet helper ---------------------------------------------------------
|
|
510
|
+
function readSnippet(root, relPath, startLine, endLine) {
|
|
511
|
+
try {
|
|
512
|
+
const abs = resolve(root, relPath);
|
|
513
|
+
if (!existsSync(abs))
|
|
514
|
+
return undefined;
|
|
515
|
+
const st = statSync(abs);
|
|
516
|
+
if (!st.isFile() || st.size > 2 * 1024 * 1024)
|
|
517
|
+
return undefined;
|
|
518
|
+
const content = readFileSync(abs, "utf8");
|
|
519
|
+
const lines = content.split(/\r?\n/);
|
|
520
|
+
const sl = Math.max(1, startLine);
|
|
521
|
+
const el = Math.min(lines.length, Math.min(endLine + 5, sl + MAX_SNIPPET_LINES));
|
|
522
|
+
return lines.slice(sl - 1, el).join("\n");
|
|
523
|
+
}
|
|
524
|
+
catch {
|
|
525
|
+
return undefined;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
// Singleton accessor — reuses one indexer per process.
|
|
529
|
+
let _singleton = null;
|
|
530
|
+
export function getIndexer(cacheRoot) {
|
|
531
|
+
if (_singleton)
|
|
532
|
+
return _singleton;
|
|
533
|
+
const cache = new Cache(cacheRoot);
|
|
534
|
+
_singleton = new SCIPIndexer(cache);
|
|
535
|
+
return _singleton;
|
|
536
|
+
}
|
|
537
|
+
/** Utility for callers that want a path relative to the project root. */
|
|
538
|
+
export function relPath(root, abs) {
|
|
539
|
+
return relative(resolve(root), resolve(abs)).split(sep).join("/");
|
|
540
|
+
}
|
|
541
|
+
//# sourceMappingURL=scip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scip.js","sourceRoot":"","sources":["../../src/index/scip.ts"],"names":[],"mappings":"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"}
|