@oddessentials/odd-repo-mapper 1.0.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.
Potentially problematic release.
This version of @oddessentials/odd-repo-mapper might be problematic. Click here for more details.
- package/LICENSE +21 -0
- package/README.md +45 -0
- package/dist/cli/commands/mcp.d.ts +6 -0
- package/dist/cli/commands/mcp.d.ts.map +1 -0
- package/dist/cli/commands/mcp.js +11 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/report.d.ts +6 -0
- package/dist/cli/commands/report.d.ts.map +1 -0
- package/dist/cli/commands/report.js +96 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/cli/commands/scan.d.ts +6 -0
- package/dist/cli/commands/scan.d.ts.map +1 -0
- package/dist/cli/commands/scan.js +118 -0
- package/dist/cli/commands/scan.js.map +1 -0
- package/dist/cli/commands/verify.d.ts +6 -0
- package/dist/cli/commands/verify.d.ts.map +1 -0
- package/dist/cli/commands/verify.js +47 -0
- package/dist/cli/commands/verify.js.map +1 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +20 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/config.d.ts +53 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +106 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/constants.d.ts +31 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +31 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/graph.d.ts +61 -0
- package/dist/core/graph.d.ts.map +1 -0
- package/dist/core/graph.js +163 -0
- package/dist/core/graph.js.map +1 -0
- package/dist/core/hashing.d.ts +37 -0
- package/dist/core/hashing.d.ts.map +1 -0
- package/dist/core/hashing.js +66 -0
- package/dist/core/hashing.js.map +1 -0
- package/dist/core/indexers/go.d.ts +14 -0
- package/dist/core/indexers/go.d.ts.map +1 -0
- package/dist/core/indexers/go.js +175 -0
- package/dist/core/indexers/go.js.map +1 -0
- package/dist/core/indexers/index.d.ts +39 -0
- package/dist/core/indexers/index.d.ts.map +1 -0
- package/dist/core/indexers/index.js +76 -0
- package/dist/core/indexers/index.js.map +1 -0
- package/dist/core/indexers/python.d.ts +14 -0
- package/dist/core/indexers/python.d.ts.map +1 -0
- package/dist/core/indexers/python.js +186 -0
- package/dist/core/indexers/python.js.map +1 -0
- package/dist/core/indexers/rust.d.ts +14 -0
- package/dist/core/indexers/rust.d.ts.map +1 -0
- package/dist/core/indexers/rust.js +156 -0
- package/dist/core/indexers/rust.js.map +1 -0
- package/dist/core/indexers/typescript.d.ts +19 -0
- package/dist/core/indexers/typescript.d.ts.map +1 -0
- package/dist/core/indexers/typescript.js +223 -0
- package/dist/core/indexers/typescript.js.map +1 -0
- package/dist/core/reports/coverage.d.ts +38 -0
- package/dist/core/reports/coverage.d.ts.map +1 -0
- package/dist/core/reports/coverage.js +175 -0
- package/dist/core/reports/coverage.js.map +1 -0
- package/dist/core/reports/index.d.ts +10 -0
- package/dist/core/reports/index.d.ts.map +1 -0
- package/dist/core/reports/index.js +7 -0
- package/dist/core/reports/index.js.map +1 -0
- package/dist/core/reports/mermaid.d.ts +41 -0
- package/dist/core/reports/mermaid.d.ts.map +1 -0
- package/dist/core/reports/mermaid.js +171 -0
- package/dist/core/reports/mermaid.js.map +1 -0
- package/dist/core/reports/traceability.d.ts +45 -0
- package/dist/core/reports/traceability.d.ts.map +1 -0
- package/dist/core/reports/traceability.js +190 -0
- package/dist/core/reports/traceability.js.map +1 -0
- package/dist/core/scanner.d.ts +48 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +191 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/core/toolchain.d.ts +28 -0
- package/dist/core/toolchain.d.ts.map +1 -0
- package/dist/core/toolchain.js +68 -0
- package/dist/core/toolchain.js.map +1 -0
- package/dist/core/verify.d.ts +15 -0
- package/dist/core/verify.d.ts.map +1 -0
- package/dist/core/verify.js +182 -0
- package/dist/core/verify.js.map +1 -0
- package/dist/mcp/server.d.ts +46 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +421 -0
- package/dist/mcp/server.js.map +1 -0
- package/package.json +86 -0
- package/schemas/config.schema.json +140 -0
- package/schemas/graph.schema.json +132 -0
- package/schemas/repo-profile.schema.json +118 -0
- package/schemas/toolchain.schema.json +37 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determinism constants and cross-platform normalization rules.
|
|
3
|
+
* Per D10: All paths use forward slash, UTF-8, LC_ALL=C sorting.
|
|
4
|
+
*/
|
|
5
|
+
/** Canonical path separator for all artifacts */
|
|
6
|
+
export declare const PATH_SEPARATOR = "/";
|
|
7
|
+
/** Maximum path length before truncation warning (Windows limit) */
|
|
8
|
+
export declare const MAX_PATH_LENGTH = 260;
|
|
9
|
+
/** Chunk size for MCP artifact transport (fixed per D2) */
|
|
10
|
+
export declare const MCP_CHUNK_SIZE_BYTES: number;
|
|
11
|
+
/** Hard limits per implementation plan */
|
|
12
|
+
export declare const LIMITS: {
|
|
13
|
+
readonly maxFiles: 50000;
|
|
14
|
+
readonly maxEdges: 500000;
|
|
15
|
+
readonly maxSymbols: 1000000;
|
|
16
|
+
readonly maxNodesPerDiagram: 250;
|
|
17
|
+
};
|
|
18
|
+
/** Test linking confidence scores per D7 */
|
|
19
|
+
export declare const LINK_CONFIDENCE: {
|
|
20
|
+
readonly coverage: 100;
|
|
21
|
+
readonly directImport: 90;
|
|
22
|
+
readonly symbolReference: 70;
|
|
23
|
+
readonly pathHeuristic: 50;
|
|
24
|
+
};
|
|
25
|
+
/** Minimum confidence threshold (configurable) */
|
|
26
|
+
export declare const DEFAULT_MIN_CONFIDENCE = 50;
|
|
27
|
+
/** Schema version for all artifacts */
|
|
28
|
+
export declare const SCHEMA_VERSION = "0.1.0";
|
|
29
|
+
/** Package version */
|
|
30
|
+
export declare const REPO_MAPPER_VERSION = "0.1.0";
|
|
31
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/core/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,iDAAiD;AACjD,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC,oEAAoE;AACpE,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,2DAA2D;AAC3D,eAAO,MAAM,oBAAoB,QAAY,CAAC;AAE9C,0CAA0C;AAC1C,eAAO,MAAM,MAAM;;;;;CAKT,CAAC;AAEX,4CAA4C;AAC5C,eAAO,MAAM,eAAe;;;;;CAKlB,CAAC;AAEX,kDAAkD;AAClD,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC,uCAAuC;AACvC,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC,sBAAsB;AACtB,eAAO,MAAM,mBAAmB,UAAU,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determinism constants and cross-platform normalization rules.
|
|
3
|
+
* Per D10: All paths use forward slash, UTF-8, LC_ALL=C sorting.
|
|
4
|
+
*/
|
|
5
|
+
/** Canonical path separator for all artifacts */
|
|
6
|
+
export const PATH_SEPARATOR = '/';
|
|
7
|
+
/** Maximum path length before truncation warning (Windows limit) */
|
|
8
|
+
export const MAX_PATH_LENGTH = 260;
|
|
9
|
+
/** Chunk size for MCP artifact transport (fixed per D2) */
|
|
10
|
+
export const MCP_CHUNK_SIZE_BYTES = 64 * 1024;
|
|
11
|
+
/** Hard limits per implementation plan */
|
|
12
|
+
export const LIMITS = {
|
|
13
|
+
maxFiles: 50_000,
|
|
14
|
+
maxEdges: 500_000,
|
|
15
|
+
maxSymbols: 1_000_000,
|
|
16
|
+
maxNodesPerDiagram: 250,
|
|
17
|
+
};
|
|
18
|
+
/** Test linking confidence scores per D7 */
|
|
19
|
+
export const LINK_CONFIDENCE = {
|
|
20
|
+
coverage: 100,
|
|
21
|
+
directImport: 90,
|
|
22
|
+
symbolReference: 70,
|
|
23
|
+
pathHeuristic: 50,
|
|
24
|
+
};
|
|
25
|
+
/** Minimum confidence threshold (configurable) */
|
|
26
|
+
export const DEFAULT_MIN_CONFIDENCE = 50;
|
|
27
|
+
/** Schema version for all artifacts */
|
|
28
|
+
export const SCHEMA_VERSION = '0.1.0';
|
|
29
|
+
/** Package version */
|
|
30
|
+
export const REPO_MAPPER_VERSION = '0.1.0';
|
|
31
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/core/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,iDAAiD;AACjD,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC;AAElC,oEAAoE;AACpE,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAC;AAEnC,2DAA2D;AAC3D,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,GAAG,IAAI,CAAC;AAE9C,0CAA0C;AAC1C,MAAM,CAAC,MAAM,MAAM,GAAG;IAClB,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,OAAO;IACjB,UAAU,EAAE,SAAS;IACrB,kBAAkB,EAAE,GAAG;CACjB,CAAC;AAEX,4CAA4C;AAC5C,MAAM,CAAC,MAAM,eAAe,GAAG;IAC3B,QAAQ,EAAE,GAAG;IACb,YAAY,EAAE,EAAE;IAChB,eAAe,EAAE,EAAE;IACnB,aAAa,EAAE,EAAE;CACX,CAAC;AAEX,kDAAkD;AAClD,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAEzC,uCAAuC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC,sBAAsB;AACtB,MAAM,CAAC,MAAM,mBAAmB,GAAG,OAAO,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite-backed knowledge graph with canonical JSON export.
|
|
3
|
+
* Per D3: SQLite is canonical, graph.json must match via contentHash.
|
|
4
|
+
*/
|
|
5
|
+
import Database from 'better-sqlite3';
|
|
6
|
+
export interface GraphNode {
|
|
7
|
+
id: string;
|
|
8
|
+
type: 'file' | 'module' | 'symbol' | 'test' | 'entrypoint';
|
|
9
|
+
path: string;
|
|
10
|
+
language?: string;
|
|
11
|
+
tier?: 1 | 2 | 3;
|
|
12
|
+
name?: string;
|
|
13
|
+
fqn?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface EdgeProof {
|
|
16
|
+
type: 'ast_import' | 'ast_reference' | 'go_list' | 'cargo_metadata' | 'coverage' | 'path_heuristic';
|
|
17
|
+
location?: {
|
|
18
|
+
file: string;
|
|
19
|
+
line?: number;
|
|
20
|
+
column?: number;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export interface GraphEdge {
|
|
24
|
+
source: string;
|
|
25
|
+
target: string;
|
|
26
|
+
kind: 'import' | 'reference' | 'contains' | 'tests' | 'entrypoint';
|
|
27
|
+
proof: EdgeProof;
|
|
28
|
+
}
|
|
29
|
+
export interface GraphExport {
|
|
30
|
+
schemaVersion: string;
|
|
31
|
+
meta: {
|
|
32
|
+
contentHash: string;
|
|
33
|
+
nodeCount: number;
|
|
34
|
+
edgeCount: number;
|
|
35
|
+
exportedAt: string;
|
|
36
|
+
};
|
|
37
|
+
nodes: GraphNode[];
|
|
38
|
+
edges: GraphEdge[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Initialize the SQLite graph database.
|
|
42
|
+
*/
|
|
43
|
+
export declare function initGraphDatabase(dbPath: string): Database.Database;
|
|
44
|
+
/**
|
|
45
|
+
* Insert a node into the graph.
|
|
46
|
+
*/
|
|
47
|
+
export declare function insertNode(db: Database.Database, node: GraphNode): void;
|
|
48
|
+
/**
|
|
49
|
+
* Insert an edge into the graph.
|
|
50
|
+
*/
|
|
51
|
+
export declare function insertEdge(db: Database.Database, edge: GraphEdge): void;
|
|
52
|
+
/**
|
|
53
|
+
* Export graph to canonical JSON.
|
|
54
|
+
* Per D3: Ordering is deterministic, contentHash must match.
|
|
55
|
+
*/
|
|
56
|
+
export declare function exportGraph(db: Database.Database): Promise<GraphExport>;
|
|
57
|
+
/**
|
|
58
|
+
* Write graph.json to disk.
|
|
59
|
+
*/
|
|
60
|
+
export declare function writeGraphJson(db: Database.Database, outPath: string): Promise<GraphExport>;
|
|
61
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/core/graph.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAYtC,MAAM,WAAW,SAAS;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,CAAC;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACtB,IAAI,EACE,YAAY,GACZ,eAAe,GACf,SAAS,GACT,gBAAgB,GAChB,UAAU,GACV,gBAAgB,CAAC;IACvB,QAAQ,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACL;AAED,MAAM,WAAW,SAAS;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,YAAY,CAAC;IACnE,KAAK,EAAE,SAAS,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE;QACF,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAoCnE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAcvE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAcvE;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CA+F7E;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAajG"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite-backed knowledge graph with canonical JSON export.
|
|
3
|
+
* Per D3: SQLite is canonical, graph.json must match via contentHash.
|
|
4
|
+
*/
|
|
5
|
+
import Database from 'better-sqlite3';
|
|
6
|
+
import { writeFileSync, mkdirSync } from 'node:fs';
|
|
7
|
+
import { dirname } from 'node:path';
|
|
8
|
+
import { sha256 } from './hashing.js';
|
|
9
|
+
import { SCHEMA_VERSION } from './constants.js';
|
|
10
|
+
// Use dynamic import for json-canonicalize (ESM)
|
|
11
|
+
async function canonicalize(obj) {
|
|
12
|
+
const { canonicalize: canon } = await import('json-canonicalize');
|
|
13
|
+
return canon(obj);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Initialize the SQLite graph database.
|
|
17
|
+
*/
|
|
18
|
+
export function initGraphDatabase(dbPath) {
|
|
19
|
+
mkdirSync(dirname(dbPath), { recursive: true });
|
|
20
|
+
const db = new Database(dbPath);
|
|
21
|
+
db.exec(`
|
|
22
|
+
CREATE TABLE IF NOT EXISTS nodes (
|
|
23
|
+
id TEXT PRIMARY KEY,
|
|
24
|
+
type TEXT NOT NULL,
|
|
25
|
+
path TEXT NOT NULL,
|
|
26
|
+
language TEXT,
|
|
27
|
+
tier INTEGER,
|
|
28
|
+
name TEXT,
|
|
29
|
+
fqn TEXT
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
CREATE TABLE IF NOT EXISTS edges (
|
|
33
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
34
|
+
source TEXT NOT NULL,
|
|
35
|
+
target TEXT NOT NULL,
|
|
36
|
+
kind TEXT NOT NULL,
|
|
37
|
+
proof_type TEXT NOT NULL,
|
|
38
|
+
proof_file TEXT,
|
|
39
|
+
proof_line INTEGER,
|
|
40
|
+
proof_column INTEGER,
|
|
41
|
+
FOREIGN KEY (source) REFERENCES nodes(id),
|
|
42
|
+
FOREIGN KEY (target) REFERENCES nodes(id)
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_type ON nodes(type);
|
|
46
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_path ON nodes(path);
|
|
47
|
+
CREATE INDEX IF NOT EXISTS idx_edges_source ON edges(source);
|
|
48
|
+
CREATE INDEX IF NOT EXISTS idx_edges_target ON edges(target);
|
|
49
|
+
`);
|
|
50
|
+
return db;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Insert a node into the graph.
|
|
54
|
+
*/
|
|
55
|
+
export function insertNode(db, node) {
|
|
56
|
+
const stmt = db.prepare(`
|
|
57
|
+
INSERT OR REPLACE INTO nodes (id, type, path, language, tier, name, fqn)
|
|
58
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
59
|
+
`);
|
|
60
|
+
stmt.run(node.id, node.type, node.path, node.language ?? null, node.tier ?? null, node.name ?? null, node.fqn ?? null);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Insert an edge into the graph.
|
|
64
|
+
*/
|
|
65
|
+
export function insertEdge(db, edge) {
|
|
66
|
+
const stmt = db.prepare(`
|
|
67
|
+
INSERT INTO edges (source, target, kind, proof_type, proof_file, proof_line, proof_column)
|
|
68
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
69
|
+
`);
|
|
70
|
+
stmt.run(edge.source, edge.target, edge.kind, edge.proof.type, edge.proof.location?.file ?? null, edge.proof.location?.line ?? null, edge.proof.location?.column ?? null);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Export graph to canonical JSON.
|
|
74
|
+
* Per D3: Ordering is deterministic, contentHash must match.
|
|
75
|
+
*/
|
|
76
|
+
export async function exportGraph(db) {
|
|
77
|
+
// SELECT all nodes ORDER BY type ASC, id ASC
|
|
78
|
+
const rawNodes = db
|
|
79
|
+
.prepare(`
|
|
80
|
+
SELECT id, type, path, language, tier, name, fqn
|
|
81
|
+
FROM nodes
|
|
82
|
+
ORDER BY type ASC, id ASC
|
|
83
|
+
`)
|
|
84
|
+
.all();
|
|
85
|
+
// Transform to clean nodes (remove null values)
|
|
86
|
+
const nodes = rawNodes.map((n) => {
|
|
87
|
+
const node = {
|
|
88
|
+
id: n.id,
|
|
89
|
+
type: n.type,
|
|
90
|
+
path: n.path,
|
|
91
|
+
};
|
|
92
|
+
if (n.language)
|
|
93
|
+
node.language = n.language;
|
|
94
|
+
if (n.tier)
|
|
95
|
+
node.tier = n.tier;
|
|
96
|
+
if (n.name)
|
|
97
|
+
node.name = n.name;
|
|
98
|
+
if (n.fqn)
|
|
99
|
+
node.fqn = n.fqn;
|
|
100
|
+
return node;
|
|
101
|
+
});
|
|
102
|
+
// SELECT all edges ORDER BY source ASC, target ASC, kind ASC
|
|
103
|
+
const rawEdges = db
|
|
104
|
+
.prepare(`
|
|
105
|
+
SELECT source, target, kind, proof_type, proof_file, proof_line, proof_column
|
|
106
|
+
FROM edges
|
|
107
|
+
ORDER BY source ASC, target ASC, kind ASC
|
|
108
|
+
`)
|
|
109
|
+
.all();
|
|
110
|
+
const edges = rawEdges.map((e) => {
|
|
111
|
+
const edge = {
|
|
112
|
+
source: e.source,
|
|
113
|
+
target: e.target,
|
|
114
|
+
kind: e.kind,
|
|
115
|
+
proof: {
|
|
116
|
+
type: e.proof_type,
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
if (e.proof_file) {
|
|
120
|
+
edge.proof.location = {
|
|
121
|
+
file: e.proof_file,
|
|
122
|
+
line: e.proof_line ?? undefined,
|
|
123
|
+
column: e.proof_column ?? undefined,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
return edge;
|
|
127
|
+
});
|
|
128
|
+
// Build export without hash first
|
|
129
|
+
const exportData = {
|
|
130
|
+
schemaVersion: SCHEMA_VERSION,
|
|
131
|
+
meta: {
|
|
132
|
+
contentHash: '', // Placeholder
|
|
133
|
+
nodeCount: nodes.length,
|
|
134
|
+
edgeCount: edges.length,
|
|
135
|
+
exportedAt: new Date().toISOString(),
|
|
136
|
+
},
|
|
137
|
+
nodes,
|
|
138
|
+
edges,
|
|
139
|
+
};
|
|
140
|
+
// Compute hash of canonical form (excluding contentHash and exportedAt)
|
|
141
|
+
const hashableData = {
|
|
142
|
+
schemaVersion: exportData.schemaVersion,
|
|
143
|
+
nodes: exportData.nodes,
|
|
144
|
+
edges: exportData.edges,
|
|
145
|
+
};
|
|
146
|
+
const canonicalJson = await canonicalize(hashableData);
|
|
147
|
+
exportData.meta.contentHash = sha256(canonicalJson);
|
|
148
|
+
return exportData;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Write graph.json to disk.
|
|
152
|
+
*/
|
|
153
|
+
export async function writeGraphJson(db, outPath) {
|
|
154
|
+
const exportData = await exportGraph(db);
|
|
155
|
+
// Write with 2-space indent for readability, but lines will be deterministic
|
|
156
|
+
const json = JSON.stringify(exportData, null, 2);
|
|
157
|
+
// Normalize newlines to \n
|
|
158
|
+
const normalized = json.replace(/\r\n/g, '\n');
|
|
159
|
+
mkdirSync(dirname(outPath), { recursive: true });
|
|
160
|
+
writeFileSync(outPath, normalized, 'utf8');
|
|
161
|
+
return exportData;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/core/graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable ID generation and content hashing.
|
|
3
|
+
* Per D10: Windows paths normalized to lowercase for ID generation.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Normalize a path for cross-platform determinism.
|
|
7
|
+
* - Forward slashes only
|
|
8
|
+
* - NFC unicode normalization
|
|
9
|
+
* - Lowercase for ID generation (Windows case-insensitivity)
|
|
10
|
+
*/
|
|
11
|
+
export declare function normalizePath(rawPath: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Generate a stable ID from a normalized path.
|
|
14
|
+
* Uses SHA256 and lowercase normalization for Windows compatibility.
|
|
15
|
+
*/
|
|
16
|
+
export declare function pathToId(path: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Generate a content-based ID from file contents.
|
|
19
|
+
*/
|
|
20
|
+
export declare function contentToId(content: Buffer | string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Compute SHA256 hash with standard prefix.
|
|
23
|
+
*/
|
|
24
|
+
export declare function sha256(data: Buffer | string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Check if path exceeds Windows limit and return truncation warning.
|
|
27
|
+
*/
|
|
28
|
+
export declare function checkPathLength(path: string): {
|
|
29
|
+
valid: boolean;
|
|
30
|
+
warning?: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Detect case collision in a list of paths.
|
|
34
|
+
* Per D10: Case collision → FAIL
|
|
35
|
+
*/
|
|
36
|
+
export declare function detectCaseCollisions(paths: string[]): string[];
|
|
37
|
+
//# sourceMappingURL=hashing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hashing.d.ts","sourceRoot":"","sources":["../../src/core/hashing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAGpD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAQlF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAc9D"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable ID generation and content hashing.
|
|
3
|
+
* Per D10: Windows paths normalized to lowercase for ID generation.
|
|
4
|
+
*/
|
|
5
|
+
import { createHash } from 'node:crypto';
|
|
6
|
+
import { PATH_SEPARATOR, MAX_PATH_LENGTH } from './constants.js';
|
|
7
|
+
/**
|
|
8
|
+
* Normalize a path for cross-platform determinism.
|
|
9
|
+
* - Forward slashes only
|
|
10
|
+
* - NFC unicode normalization
|
|
11
|
+
* - Lowercase for ID generation (Windows case-insensitivity)
|
|
12
|
+
*/
|
|
13
|
+
export function normalizePath(rawPath) {
|
|
14
|
+
return rawPath.normalize('NFC').replace(/\\/g, PATH_SEPARATOR).replace(/\/+/g, PATH_SEPARATOR);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Generate a stable ID from a normalized path.
|
|
18
|
+
* Uses SHA256 and lowercase normalization for Windows compatibility.
|
|
19
|
+
*/
|
|
20
|
+
export function pathToId(path) {
|
|
21
|
+
const normalized = normalizePath(path).toLowerCase();
|
|
22
|
+
return createHash('sha256').update(normalized, 'utf8').digest('hex').slice(0, 16);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Generate a content-based ID from file contents.
|
|
26
|
+
*/
|
|
27
|
+
export function contentToId(content) {
|
|
28
|
+
return createHash('sha256').update(content).digest('hex').slice(0, 16);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Compute SHA256 hash with standard prefix.
|
|
32
|
+
*/
|
|
33
|
+
export function sha256(data) {
|
|
34
|
+
const hash = createHash('sha256').update(data).digest('hex');
|
|
35
|
+
return `sha256:${hash}`;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Check if path exceeds Windows limit and return truncation warning.
|
|
39
|
+
*/
|
|
40
|
+
export function checkPathLength(path) {
|
|
41
|
+
if (path.length > MAX_PATH_LENGTH) {
|
|
42
|
+
return {
|
|
43
|
+
valid: true, // Still process, but warn
|
|
44
|
+
warning: `Path exceeds ${MAX_PATH_LENGTH} chars, may cause issues on Windows: ${path.slice(0, 50)}...`,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return { valid: true };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Detect case collision in a list of paths.
|
|
51
|
+
* Per D10: Case collision → FAIL
|
|
52
|
+
*/
|
|
53
|
+
export function detectCaseCollisions(paths) {
|
|
54
|
+
const normalized = new Map();
|
|
55
|
+
const collisions = [];
|
|
56
|
+
for (const p of paths) {
|
|
57
|
+
const lower = normalizePath(p).toLowerCase();
|
|
58
|
+
const existing = normalized.get(lower);
|
|
59
|
+
if (existing !== undefined && existing !== normalizePath(p)) {
|
|
60
|
+
collisions.push(`Case collision: "${existing}" vs "${normalizePath(p)}"`);
|
|
61
|
+
}
|
|
62
|
+
normalized.set(lower, normalizePath(p));
|
|
63
|
+
}
|
|
64
|
+
return collisions;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=hashing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hashing.js","sourceRoot":"","sources":["../../src/core/hashing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IACzC,OAAO,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AACnG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY;IACjC,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IACrD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACtF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,OAAwB;IAChD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC3E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,IAAqB;IACxC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7D,OAAO,UAAU,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IACxC,IAAI,IAAI,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;QAChC,OAAO;YACH,KAAK,EAAE,IAAI,EAAE,0BAA0B;YACvC,OAAO,EAAE,gBAAgB,eAAe,wCAAwC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK;SACzG,CAAC;IACN,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAe;IAChD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC7C,MAAM,UAAU,GAAa,EAAE,CAAC;IAEhC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1D,UAAU,CAAC,IAAI,CAAC,oBAAoB,QAAQ,SAAS,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC9E,CAAC;QACD,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,UAAU,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Go indexer using go list command.
|
|
3
|
+
* Per D5: Import edges require go_list proof.
|
|
4
|
+
*/
|
|
5
|
+
import type { IndexResult } from './typescript.js';
|
|
6
|
+
export interface GoIndexerOptions {
|
|
7
|
+
rootDir: string;
|
|
8
|
+
files: string[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Index Go files using go list.
|
|
12
|
+
*/
|
|
13
|
+
export declare function indexGo(options: GoIndexerOptions): IndexResult;
|
|
14
|
+
//# sourceMappingURL=go.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go.d.ts","sourceRoot":"","sources":["../../../src/core/indexers/go.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;CACnB;AAYD;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,WAAW,CAkI9D"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Go indexer using go list command.
|
|
3
|
+
* Per D5: Import edges require go_list proof.
|
|
4
|
+
*/
|
|
5
|
+
import { execSync } from 'node:child_process';
|
|
6
|
+
import { dirname, relative } from 'node:path';
|
|
7
|
+
import { existsSync } from 'node:fs';
|
|
8
|
+
import { normalizePath, pathToId } from '../hashing.js';
|
|
9
|
+
/**
|
|
10
|
+
* Index Go files using go list.
|
|
11
|
+
*/
|
|
12
|
+
export function indexGo(options) {
|
|
13
|
+
const { rootDir } = options;
|
|
14
|
+
const nodes = [];
|
|
15
|
+
const edges = [];
|
|
16
|
+
// Find go.mod to determine module root
|
|
17
|
+
const goModPath = findGoMod(rootDir);
|
|
18
|
+
if (!goModPath) {
|
|
19
|
+
// No go.mod, skip Go indexing
|
|
20
|
+
return { nodes, edges };
|
|
21
|
+
}
|
|
22
|
+
const moduleRoot = dirname(goModPath);
|
|
23
|
+
try {
|
|
24
|
+
// Run go list to get package information
|
|
25
|
+
const output = execSync('go list -json ./...', {
|
|
26
|
+
cwd: moduleRoot,
|
|
27
|
+
encoding: 'utf8',
|
|
28
|
+
timeout: 60000,
|
|
29
|
+
windowsHide: true,
|
|
30
|
+
});
|
|
31
|
+
// Parse JSON output (one object per line, but may be multiple objects)
|
|
32
|
+
const packages = parseGoListOutput(output);
|
|
33
|
+
for (const pkg of packages) {
|
|
34
|
+
// Skip external packages
|
|
35
|
+
if (!pkg.Dir.startsWith(moduleRoot))
|
|
36
|
+
continue;
|
|
37
|
+
const pkgRelPath = normalizePath(relative(rootDir, pkg.Dir));
|
|
38
|
+
const pkgId = pathToId(pkgRelPath);
|
|
39
|
+
// Add package node
|
|
40
|
+
nodes.push({
|
|
41
|
+
id: pkgId,
|
|
42
|
+
type: 'module',
|
|
43
|
+
path: pkgRelPath,
|
|
44
|
+
name: pkg.Name,
|
|
45
|
+
fqn: pkg.ImportPath,
|
|
46
|
+
language: 'go',
|
|
47
|
+
tier: 1,
|
|
48
|
+
});
|
|
49
|
+
// Add file nodes
|
|
50
|
+
for (const goFile of pkg.GoFiles || []) {
|
|
51
|
+
const filePath = normalizePath(`${pkgRelPath}/${goFile}`);
|
|
52
|
+
const fileId = pathToId(filePath);
|
|
53
|
+
nodes.push({
|
|
54
|
+
id: fileId,
|
|
55
|
+
type: 'file',
|
|
56
|
+
path: filePath,
|
|
57
|
+
language: 'go',
|
|
58
|
+
tier: 1,
|
|
59
|
+
});
|
|
60
|
+
// File contains edge
|
|
61
|
+
edges.push({
|
|
62
|
+
source: pkgId,
|
|
63
|
+
target: fileId,
|
|
64
|
+
kind: 'contains',
|
|
65
|
+
proof: {
|
|
66
|
+
type: 'go_list',
|
|
67
|
+
location: { file: filePath },
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
// Add test file nodes
|
|
72
|
+
for (const testFile of pkg.TestGoFiles || []) {
|
|
73
|
+
const filePath = normalizePath(`${pkgRelPath}/${testFile}`);
|
|
74
|
+
const fileId = pathToId(filePath);
|
|
75
|
+
nodes.push({
|
|
76
|
+
id: fileId,
|
|
77
|
+
type: 'test',
|
|
78
|
+
path: filePath,
|
|
79
|
+
language: 'go',
|
|
80
|
+
tier: 1,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
// Add import edges
|
|
84
|
+
for (const importPath of pkg.Imports || []) {
|
|
85
|
+
// Only track internal imports
|
|
86
|
+
if (importPath.startsWith(getModulePath(goModPath))) {
|
|
87
|
+
const targetId = pathToId(importPath);
|
|
88
|
+
edges.push({
|
|
89
|
+
source: pkgId,
|
|
90
|
+
target: targetId,
|
|
91
|
+
kind: 'import',
|
|
92
|
+
proof: {
|
|
93
|
+
type: 'go_list',
|
|
94
|
+
location: { file: pkgRelPath },
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Check for main package (entrypoint)
|
|
100
|
+
if (pkg.Name === 'main') {
|
|
101
|
+
const epId = pathToId(`${pkgRelPath}#main`);
|
|
102
|
+
nodes.push({
|
|
103
|
+
id: epId,
|
|
104
|
+
type: 'entrypoint',
|
|
105
|
+
path: pkgRelPath,
|
|
106
|
+
name: 'main',
|
|
107
|
+
fqn: `${pkg.ImportPath}#main`,
|
|
108
|
+
language: 'go',
|
|
109
|
+
tier: 1,
|
|
110
|
+
});
|
|
111
|
+
edges.push({
|
|
112
|
+
source: epId,
|
|
113
|
+
target: pkgId,
|
|
114
|
+
kind: 'entrypoint',
|
|
115
|
+
proof: {
|
|
116
|
+
type: 'go_list',
|
|
117
|
+
location: { file: pkgRelPath },
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// go list failed (Go not installed, invalid module, etc.)
|
|
125
|
+
}
|
|
126
|
+
return { nodes, edges };
|
|
127
|
+
}
|
|
128
|
+
function findGoMod(startDir) {
|
|
129
|
+
let dir = startDir;
|
|
130
|
+
while (dir !== dirname(dir)) {
|
|
131
|
+
const goModPath = `${dir}/go.mod`;
|
|
132
|
+
if (existsSync(goModPath)) {
|
|
133
|
+
return goModPath;
|
|
134
|
+
}
|
|
135
|
+
dir = dirname(dir);
|
|
136
|
+
}
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
function getModulePath(goModPath) {
|
|
140
|
+
try {
|
|
141
|
+
const content = require('node:fs').readFileSync(goModPath, 'utf8');
|
|
142
|
+
const match = content.match(/^module\s+(\S+)/m);
|
|
143
|
+
return match ? match[1] : '';
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return '';
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function parseGoListOutput(output) {
|
|
150
|
+
const packages = [];
|
|
151
|
+
// go list -json outputs concatenated JSON objects
|
|
152
|
+
let depth = 0;
|
|
153
|
+
let start = 0;
|
|
154
|
+
for (let i = 0; i < output.length; i++) {
|
|
155
|
+
if (output[i] === '{') {
|
|
156
|
+
if (depth === 0)
|
|
157
|
+
start = i;
|
|
158
|
+
depth++;
|
|
159
|
+
}
|
|
160
|
+
else if (output[i] === '}') {
|
|
161
|
+
depth--;
|
|
162
|
+
if (depth === 0) {
|
|
163
|
+
try {
|
|
164
|
+
const obj = JSON.parse(output.slice(start, i + 1));
|
|
165
|
+
packages.push(obj);
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
// Skip malformed JSON
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return packages;
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=go.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go.js","sourceRoot":"","sources":["../../../src/core/indexers/go.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Index orchestrator - runs all language indexers and populates graph.
|
|
3
|
+
*/
|
|
4
|
+
import { type IndexResult } from './typescript.js';
|
|
5
|
+
export interface IndexOptions {
|
|
6
|
+
rootDir: string;
|
|
7
|
+
files: Map<string, string[]>;
|
|
8
|
+
tsConfigPath?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface AggregatedIndexResult extends IndexResult {
|
|
11
|
+
stats: {
|
|
12
|
+
typescript: {
|
|
13
|
+
files: number;
|
|
14
|
+
nodes: number;
|
|
15
|
+
edges: number;
|
|
16
|
+
};
|
|
17
|
+
python: {
|
|
18
|
+
files: number;
|
|
19
|
+
nodes: number;
|
|
20
|
+
edges: number;
|
|
21
|
+
};
|
|
22
|
+
go: {
|
|
23
|
+
files: number;
|
|
24
|
+
nodes: number;
|
|
25
|
+
edges: number;
|
|
26
|
+
};
|
|
27
|
+
rust: {
|
|
28
|
+
files: number;
|
|
29
|
+
nodes: number;
|
|
30
|
+
edges: number;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Run all indexers and aggregate results.
|
|
36
|
+
*/
|
|
37
|
+
export declare function indexAll(options: IndexOptions): AggregatedIndexResult;
|
|
38
|
+
export type { IndexResult } from './typescript.js';
|
|
39
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/indexers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAKpE,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,qBAAsB,SAAQ,WAAW;IACtD,KAAK,EAAE;QACH,UAAU,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;QAC5D,MAAM,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;QACxD,EAAE,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;QACpD,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KACzD,CAAC;CACL;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,qBAAqB,CAuErE;AAGD,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC"}
|