@rpcajr/smart-graph-indexer 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.
Files changed (60) hide show
  1. package/.agents/rules/antigravity-rtk-rules.md +32 -0
  2. package/README.md +116 -0
  3. package/dist/graph.d.ts +32 -0
  4. package/dist/graph.js +86 -0
  5. package/dist/index.d.ts +2 -0
  6. package/dist/index.js +227 -0
  7. package/dist/mcp_server.d.ts +48 -0
  8. package/dist/mcp_server.js +433 -0
  9. package/dist/parser.d.ts +42 -0
  10. package/dist/parser.js +529 -0
  11. package/dist/stats.d.ts +43 -0
  12. package/dist/stats.js +146 -0
  13. package/dist/ui.d.ts +2 -0
  14. package/dist/ui.js +1003 -0
  15. package/dist/vector.d.ts +66 -0
  16. package/dist/vector.js +144 -0
  17. package/dist/wasm/tree-sitter-c.wasm +0 -0
  18. package/dist/wasm/tree-sitter-c_sharp.wasm +0 -0
  19. package/dist/wasm/tree-sitter-cpp.wasm +0 -0
  20. package/dist/wasm/tree-sitter-go.wasm +0 -0
  21. package/dist/wasm/tree-sitter-java.wasm +0 -0
  22. package/dist/wasm/tree-sitter-python.wasm +0 -0
  23. package/dist/wasm/tree-sitter-ruby.wasm +0 -0
  24. package/dist/wasm/tree-sitter-rust.wasm +0 -0
  25. package/dist/wasm/tree-sitter-typescript.wasm +0 -0
  26. package/dist/wasm/tree-sitter.wasm +0 -0
  27. package/dist/watcher.d.ts +36 -0
  28. package/dist/watcher.js +166 -0
  29. package/mcp-config-example.json +12 -0
  30. package/mcp_smart_indexer_implementation_spec.md +366 -0
  31. package/package.json +35 -0
  32. package/src/graph.ts +93 -0
  33. package/src/index.ts +216 -0
  34. package/src/mcp_server.ts +454 -0
  35. package/src/parser.ts +484 -0
  36. package/src/stats.ts +156 -0
  37. package/src/ui.ts +956 -0
  38. package/src/vector.ts +166 -0
  39. package/src/watcher.ts +144 -0
  40. package/test_project/App.java +16 -0
  41. package/test_project/BillingService.cs +31 -0
  42. package/test_project/auth.ts +18 -0
  43. package/test_project/config.ts +11 -0
  44. package/test_project/database.ts +21 -0
  45. package/test_project/index.ts +13 -0
  46. package/test_project/main.go +11 -0
  47. package/test_project/main.py +21 -0
  48. package/test_project/processor.py +12 -0
  49. package/test_project/utils.py +13 -0
  50. package/tsconfig.json +16 -0
  51. package/wasm/tree-sitter-c.wasm +0 -0
  52. package/wasm/tree-sitter-c_sharp.wasm +0 -0
  53. package/wasm/tree-sitter-cpp.wasm +0 -0
  54. package/wasm/tree-sitter-go.wasm +0 -0
  55. package/wasm/tree-sitter-java.wasm +0 -0
  56. package/wasm/tree-sitter-python.wasm +0 -0
  57. package/wasm/tree-sitter-ruby.wasm +0 -0
  58. package/wasm/tree-sitter-rust.wasm +0 -0
  59. package/wasm/tree-sitter-typescript.wasm +0 -0
  60. package/wasm/tree-sitter.wasm +0 -0
@@ -0,0 +1,32 @@
1
+ # RTK - Rust Token Killer (Google Antigravity)
2
+
3
+ **Usage**: Token-optimized CLI proxy for shell commands.
4
+
5
+ ## Rule
6
+
7
+ Always prefix shell commands with `rtk` to minimize token consumption.
8
+
9
+ Examples:
10
+
11
+ ```bash
12
+ rtk git status
13
+ rtk cargo test
14
+ rtk ls src/
15
+ rtk grep "pattern" src/
16
+ rtk find "*.rs" .
17
+ rtk docker ps
18
+ rtk gh pr list
19
+ ```
20
+
21
+ ## Meta Commands
22
+
23
+ ```bash
24
+ rtk gain # Show token savings
25
+ rtk gain --history # Command history with savings
26
+ rtk discover # Find missed RTK opportunities
27
+ rtk proxy <cmd> # Run raw (no filtering, for debugging)
28
+ ```
29
+
30
+ ## Why
31
+
32
+ RTK filters and compresses command output before it reaches the LLM context, saving 60-90% tokens on common operations. Always use `rtk <cmd>` instead of raw commands.
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # smart-graph-indexer 🚀
2
+
3
+ A fast, language-agnostic, syntax-aware structural code indexer and **Model Context Protocol (MCP)** server.
4
+
5
+ It indexes project structure, extracts AST signature skeletons, computes file-to-file dependency graphs, and provides local hybrid search (semantic vector embeddings + exact substring search) for **9 major programming languages**:
6
+ *TypeScript/JavaScript, Python, C#, Java, Go, Rust, Ruby, C, and C++.*
7
+
8
+ Additionally, it tracks **Token Savings (RTK Token Killer)** and session logs, giving you a detailed breakdown of how much context (and API cost) you are saving when utilizing AI assistants with this MCP server.
9
+
10
+ ---
11
+
12
+ ## Key Features
13
+
14
+ 1. **Syntax-Aware Structural Parsing (AST Skeletons)**:
15
+ Extracts public class, method, function signatures, and docstrings using Tree-Sitter WASM grammars. Internal logic blocks are discarded, creating a lightweight "skeleton" map of your project.
16
+
17
+ 2. **Dynamic Workspace Discovery**:
18
+ Uses the MCP `roots/list` protocol handshake to dynamically query the IDE for the active project path. Zero configuration needed for CWD path variations across different IDE hosts.
19
+
20
+ 3. **Local Hybrid Search**:
21
+ Performs fast cosine-similarity search using a local ONNX embedding model (`all-MiniLM-L6-v2` via `@xenova/transformers`) running entirely on your CPU, blended with substring lexical fallback.
22
+
23
+ 4. **Interactive Dependency Graph (`graph-indexer view`)**:
24
+ Generates a visually stunning Vis.js network visualization (`.graph-indexer/graph.html`) of your file imports. Use the `--watch` flag to auto-update the visualization as you save code.
25
+
26
+ 5. **Dormant Mode by Default**:
27
+ To prevent overhead when opening arbitrary folders, the server runs in a dormant mode (0% CPU, minimum RAM) unless a `.graph-indexer/` directory exists in the workspace. Toggle it on-demand with `graph-indexer init`.
28
+
29
+ 6. **Console-Style RTK Session Dashboard**:
30
+ A visual dashboard in the HTML interface that mimics the popular `RTK` (Rust Token Killer) console, tracking requests, used tokens, alternative raw tokens, execution times, and efficiency ratios.
31
+
32
+ ---
33
+
34
+ ## Installation
35
+
36
+ Install the package globally using npm:
37
+
38
+ ```bash
39
+ # Install globally from source
40
+ npm install -g .
41
+ ```
42
+
43
+ ---
44
+
45
+ ## CLI Commands
46
+
47
+ ### 1. Initialize a Project (`init`)
48
+ Enables the MCP indexing engine for the current directory by creating the `.graph-indexer` folder:
49
+ ```bash
50
+ graph-indexer init
51
+ ```
52
+
53
+ > [!TIP]
54
+ > **Gitignore Configuration**:
55
+ > It is highly recommended to add the configuration folder to your project's `.gitignore` to avoid committing local stats and generated HTML views:
56
+ > ```gitignore
57
+ > # Exclude local Graph Indexer assets
58
+ > .graph-indexer/
59
+ > ```
60
+
61
+ ### 2. Visualize Graph & Stats (`view`)
62
+ Generates the interactive HTML network graph and opens it in your default browser:
63
+ ```bash
64
+ graph-indexer view
65
+ ```
66
+ To monitor code modifications and regenerate the graph automatically, add the watch flag:
67
+ ```bash
68
+ graph-indexer view --watch
69
+ ```
70
+
71
+ ### 3. Quick Index Export (`index`)
72
+ Indexes the project once and exports the structural skeletons report directly to stdout as JSON:
73
+ ```bash
74
+ graph-indexer index
75
+ ```
76
+
77
+ ---
78
+
79
+ ## IDE MCP Server Integration
80
+
81
+ Add the server to your editor's global Model Context Protocol configuration (e.g., `mcp_config.json` in Antigravity, Claude Desktop, Cursor, or VS Code):
82
+
83
+ ```json
84
+ {
85
+ "mcpServers": {
86
+ "smart-graph-indexer": {
87
+ "command": "graph-indexer",
88
+ "args": [
89
+ "start",
90
+ "--path",
91
+ "."
92
+ ]
93
+ }
94
+ }
95
+ }
96
+ ```
97
+
98
+ *Note: Since the server queries the editor for active workspace roots dynamically, `--path "."` works as a safe fallback.*
99
+
100
+ ---
101
+
102
+ ## Available MCP Tools
103
+
104
+ Once connected, your AI assistant will automatically use the following tools:
105
+
106
+ * `search_symbols(query, limit)`: Performs a hybrid search over indexed structural signatures.
107
+ * `get_file_skeleton(file_path)`: Retrieves the clean AST skeleton (methods, properties, docstrings) of a file without internal logic blocks.
108
+ * `get_dependencies(file_path, direction)`: Retrieves direct imports or dependants of a file.
109
+ * `read_symbol_body(file_path, symbol_name)`: JIT-fetches the actual body of a class/method from disk when requested.
110
+ * `get_token_savings()`: Returns the detailed JSON log of token metrics.
111
+
112
+ ---
113
+
114
+ ## License
115
+
116
+ ISC License. Open Source.
@@ -0,0 +1,32 @@
1
+ export declare class DependencyGraph {
2
+ private adjacencyList;
3
+ private reverseAdjacencyList;
4
+ constructor();
5
+ /**
6
+ * Adds or updates a file and its dependencies in the graph.
7
+ */
8
+ updateFileDependencies(filePath: string, dependencies: string[]): void;
9
+ /**
10
+ * Removes a file and its edges from the graph.
11
+ */
12
+ removeFile(filePath: string): void;
13
+ /**
14
+ * Clears the entire graph.
15
+ */
16
+ clear(): void;
17
+ /**
18
+ * Gets direct dependencies (files/namespaces this file imports).
19
+ */
20
+ getOutgoing(filePath: string): string[];
21
+ /**
22
+ * Gets dependants (files that import this file/namespace).
23
+ */
24
+ getIncoming(filePathOrNamespace: string): string[];
25
+ /**
26
+ * Exports the entire graph for debugging/serialization.
27
+ */
28
+ serialize(): Record<string, {
29
+ imports: string[];
30
+ importedBy: string[];
31
+ }>;
32
+ }
package/dist/graph.js ADDED
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DependencyGraph = void 0;
4
+ class DependencyGraph {
5
+ // Map of file relative path -> set of other files/namespaces this file imports (outgoing)
6
+ adjacencyList = new Map();
7
+ // Map of file/namespace -> set of files that import it (incoming)
8
+ reverseAdjacencyList = new Map();
9
+ constructor() { }
10
+ /**
11
+ * Adds or updates a file and its dependencies in the graph.
12
+ */
13
+ updateFileDependencies(filePath, dependencies) {
14
+ // Clean old dependencies if file already existed
15
+ this.removeFile(filePath);
16
+ // Set outgoing dependencies
17
+ const outgoing = new Set(dependencies);
18
+ this.adjacencyList.set(filePath, outgoing);
19
+ // Set incoming dependencies
20
+ for (const dep of dependencies) {
21
+ if (!this.reverseAdjacencyList.has(dep)) {
22
+ this.reverseAdjacencyList.set(dep, new Set());
23
+ }
24
+ this.reverseAdjacencyList.get(dep).add(filePath);
25
+ }
26
+ }
27
+ /**
28
+ * Removes a file and its edges from the graph.
29
+ */
30
+ removeFile(filePath) {
31
+ const oldDeps = this.adjacencyList.get(filePath);
32
+ if (oldDeps) {
33
+ for (const dep of oldDeps) {
34
+ const incoming = this.reverseAdjacencyList.get(dep);
35
+ if (incoming) {
36
+ incoming.delete(filePath);
37
+ if (incoming.size === 0) {
38
+ this.reverseAdjacencyList.delete(dep);
39
+ }
40
+ }
41
+ }
42
+ this.adjacencyList.delete(filePath);
43
+ }
44
+ // Also remove from reverse list (in case this file was imported by others)
45
+ this.reverseAdjacencyList.delete(filePath);
46
+ for (const [node, deps] of this.adjacencyList.entries()) {
47
+ if (deps.has(filePath)) {
48
+ deps.delete(filePath);
49
+ }
50
+ }
51
+ }
52
+ /**
53
+ * Clears the entire graph.
54
+ */
55
+ clear() {
56
+ this.adjacencyList.clear();
57
+ this.reverseAdjacencyList.clear();
58
+ }
59
+ /**
60
+ * Gets direct dependencies (files/namespaces this file imports).
61
+ */
62
+ getOutgoing(filePath) {
63
+ return Array.from(this.adjacencyList.get(filePath) || []);
64
+ }
65
+ /**
66
+ * Gets dependants (files that import this file/namespace).
67
+ */
68
+ getIncoming(filePathOrNamespace) {
69
+ return Array.from(this.reverseAdjacencyList.get(filePathOrNamespace) || []);
70
+ }
71
+ /**
72
+ * Exports the entire graph for debugging/serialization.
73
+ */
74
+ serialize() {
75
+ const serialized = {};
76
+ const allNodes = new Set([...this.adjacencyList.keys(), ...this.reverseAdjacencyList.keys()]);
77
+ for (const node of allNodes) {
78
+ serialized[node] = {
79
+ imports: this.getOutgoing(node),
80
+ importedBy: this.getIncoming(node),
81
+ };
82
+ }
83
+ return serialized;
84
+ }
85
+ }
86
+ exports.DependencyGraph = DependencyGraph;
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,227 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ const commander_1 = require("commander");
38
+ const mcp_server_js_1 = require("./mcp_server.js");
39
+ const ui_js_1 = require("./ui.js");
40
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
41
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
42
+ const path = __importStar(require("path"));
43
+ const fs = __importStar(require("fs"));
44
+ const child_process_1 = require("child_process");
45
+ const program = new commander_1.Command();
46
+ program
47
+ .name('graph-indexer')
48
+ .description('Smart Graph Code Indexer MCP CLI')
49
+ .version('1.0.0');
50
+ program
51
+ .command('start')
52
+ .description('Starts the MCP server via stdio')
53
+ .option('-p, --path <directory>', 'Target project directory to index', '.')
54
+ .action(async (options) => {
55
+ try {
56
+ const projectPath = path.resolve(options.path);
57
+ console.error(`[Start] Initializing SmartGraphIndexerMCP for: ${projectPath}`);
58
+ const engine = new mcp_server_js_1.IndexerEngine(projectPath);
59
+ const server = (0, mcp_server_js_1.createMCPServer)(engine);
60
+ const transport = new stdio_js_1.StdioServerTransport();
61
+ await server.connect(transport);
62
+ console.error('[Start] MCP Server successfully connected via Stdio.');
63
+ // Dynamic workspace path discovery via client roots list
64
+ let resolvedPath = projectPath;
65
+ let rootsResult = "none";
66
+ let rootsError = "none";
67
+ try {
68
+ const response = await server.request({ method: 'roots/list' }, types_js_1.ListRootsResultSchema);
69
+ rootsResult = JSON.stringify(response);
70
+ if (response && response.roots && response.roots.length > 0) {
71
+ const rootUri = response.roots[0].uri;
72
+ if (rootUri.startsWith('file:///')) {
73
+ // Remove file:/// prefix
74
+ let pathFromUri = rootUri.substring(8);
75
+ pathFromUri = decodeURIComponent(pathFromUri);
76
+ // Normalize Windows/Unix path
77
+ resolvedPath = path.resolve(pathFromUri);
78
+ engine.updateProjectPath(resolvedPath);
79
+ }
80
+ }
81
+ }
82
+ catch (err) {
83
+ rootsError = err?.message || String(err);
84
+ }
85
+ await engine.startIndexing();
86
+ // Handle termination gracefully
87
+ process.on('SIGINT', async () => {
88
+ console.error('[Shutdown] Closing watcher...');
89
+ await engine.shutdown();
90
+ process.exit(0);
91
+ });
92
+ process.on('SIGTERM', async () => {
93
+ console.error('[Shutdown] Closing watcher...');
94
+ await engine.shutdown();
95
+ process.exit(0);
96
+ });
97
+ }
98
+ catch (err) {
99
+ console.error('Critical error starting the MCP server:', err);
100
+ process.exit(1);
101
+ }
102
+ });
103
+ program
104
+ .command('index')
105
+ .description('Performs only the initial indexing of the project and exports a JSON structural report')
106
+ .option('-p, --path <directory>', 'Target project directory to index', '.')
107
+ .action(async (options) => {
108
+ try {
109
+ const projectPath = path.resolve(options.path);
110
+ console.log(`[Index] Indexing project at: ${projectPath}`);
111
+ const engine = new mcp_server_js_1.IndexerEngine(projectPath);
112
+ await engine.initialize();
113
+ await engine.scanDir(projectPath);
114
+ const report = engine.getReport();
115
+ console.log(JSON.stringify(report, null, 2));
116
+ process.exit(0);
117
+ }
118
+ catch (err) {
119
+ console.error('Critical error during indexing:', err);
120
+ process.exit(1);
121
+ }
122
+ });
123
+ program
124
+ .command('view')
125
+ .description('Maps the project and opens an interactive web graph of dependencies')
126
+ .option('-p, --path <directory>', 'Target project directory to map', '.')
127
+ .option('-w, --watch', 'Monitors filesystem changes in real time and regenerates the graph automatically')
128
+ .action(async (options) => {
129
+ try {
130
+ const projectPath = path.resolve(options.path);
131
+ console.log(`[View] Mapping project dependencies at: ${projectPath}`);
132
+ let engine;
133
+ const writeHtml = () => {
134
+ const htmlContent = (0, ui_js_1.generateGraphHtml)(engine);
135
+ const mcpDir = path.join(projectPath, '.graph-indexer');
136
+ if (!fs.existsSync(mcpDir)) {
137
+ fs.mkdirSync(mcpDir, { recursive: true });
138
+ }
139
+ const htmlPath = path.join(mcpDir, 'graph.html');
140
+ fs.writeFileSync(htmlPath, htmlContent, 'utf-8');
141
+ console.log(`[View] Interactive graph updated at: ${htmlPath}`);
142
+ };
143
+ if (options.watch) {
144
+ engine = new mcp_server_js_1.IndexerEngine(projectPath, () => {
145
+ writeHtml();
146
+ });
147
+ }
148
+ else {
149
+ engine = new mcp_server_js_1.IndexerEngine(projectPath);
150
+ }
151
+ await engine.initialize();
152
+ await engine.scanDir(projectPath);
153
+ // Write initial HTML
154
+ writeHtml();
155
+ const mcpDir = path.join(projectPath, '.graph-indexer');
156
+ const htmlPath = path.join(mcpDir, 'graph.html');
157
+ // Open in the default browser based on platform
158
+ console.log('[View] Opening interactive graph in default browser...');
159
+ const platform = process.platform;
160
+ const fileUrl = `file:///${htmlPath.replace(/\\/g, '/')}`;
161
+ if (platform === 'win32') {
162
+ (0, child_process_1.exec)(`start "" "${fileUrl}"`);
163
+ }
164
+ else if (platform === 'darwin') {
165
+ (0, child_process_1.exec)(`open "${fileUrl}"`);
166
+ }
167
+ else {
168
+ (0, child_process_1.exec)(`xdg-open "${fileUrl}"`);
169
+ }
170
+ if (options.watch) {
171
+ console.log('[View] Real-time monitoring (--watch) active. Press Ctrl+C to terminate.');
172
+ engine.startWatcher();
173
+ process.on('SIGINT', async () => {
174
+ console.log('[Shutdown] Closing watcher...');
175
+ await engine.shutdown();
176
+ process.exit(0);
177
+ });
178
+ }
179
+ else {
180
+ process.exit(0);
181
+ }
182
+ }
183
+ catch (err) {
184
+ console.error('Critical error generating graph view:', err);
185
+ process.exit(1);
186
+ }
187
+ });
188
+ program
189
+ .command('init')
190
+ .description('Initializes the current project directory for SmartGraphIndexer by creating the .graph-indexer config folder')
191
+ .option('-p, --path <directory>', 'Target directory to initialize', '.')
192
+ .action(async (options) => {
193
+ try {
194
+ const projectPath = path.resolve(options.path);
195
+ const mcpDir = path.join(projectPath, '.graph-indexer');
196
+ if (fs.existsSync(mcpDir)) {
197
+ console.log(`[Init] Project is already initialized at: ${projectPath} (.graph-indexer directory exists).`);
198
+ process.exit(0);
199
+ }
200
+ fs.mkdirSync(mcpDir, { recursive: true });
201
+ // Create initial empty stats file
202
+ const statsPath = path.join(mcpDir, 'stats.json');
203
+ const initialStats = {
204
+ totalCalls: 0,
205
+ totalTokensSaved: 0,
206
+ totalTokensActual: 0,
207
+ totalTokensAlternative: 0,
208
+ efficiencyPercentage: 0,
209
+ callsByType: {
210
+ search_symbols: { calls: 0, saved: 0, actual: 0, alternative: 0, totalTimeMs: 0 },
211
+ get_file_skeleton: { calls: 0, saved: 0, actual: 0, alternative: 0, totalTimeMs: 0 },
212
+ get_dependencies: { calls: 0, saved: 0, actual: 0, alternative: 0, totalTimeMs: 0 },
213
+ read_symbol_body: { calls: 0, saved: 0, actual: 0, alternative: 0, totalTimeMs: 0 }
214
+ },
215
+ history: []
216
+ };
217
+ fs.writeFileSync(statsPath, JSON.stringify(initialStats, null, 2), 'utf-8');
218
+ console.log(`[Init] Successfully initialized SmartGraphIndexer workspace at: ${projectPath}`);
219
+ console.log('[Init] The MCP server will now index and analyze this project.');
220
+ process.exit(0);
221
+ }
222
+ catch (err) {
223
+ console.error('Critical error during initialization:', err);
224
+ process.exit(1);
225
+ }
226
+ });
227
+ program.parse(process.argv);
@@ -0,0 +1,48 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { FileSkeleton } from './parser.js';
3
+ import { DependencyGraph } from './graph.js';
4
+ import { VectorStore } from './vector.js';
5
+ import { StatsManager } from './stats.js';
6
+ export declare class IndexerEngine {
7
+ projectPath: string;
8
+ private parser;
9
+ private graph;
10
+ private vectorStore;
11
+ private watcher;
12
+ private fileSkeletons;
13
+ private isLoaded;
14
+ private stats;
15
+ constructor(projectPath: string, onUpdate?: () => void);
16
+ updateProjectPath(newPath: string, onUpdate?: () => void): void;
17
+ startWatcher(): void;
18
+ initialize(): Promise<void>;
19
+ /**
20
+ * Scans and indexes the entire directory recursively.
21
+ */
22
+ startIndexing(): Promise<void>;
23
+ private scanDir;
24
+ /**
25
+ * Indexes a single file.
26
+ */
27
+ indexFile(relativeFilePath: string): Promise<void>;
28
+ /**
29
+ * Gracefully updates a file on demand (for JIT read operations).
30
+ */
31
+ ensureFileUpToDate(relativeFilePath: string): Promise<FileSkeleton | undefined>;
32
+ getFileSkeleton(relativeFilePath: string): FileSkeleton | undefined;
33
+ getGraph(): DependencyGraph;
34
+ getVectorStore(): VectorStore;
35
+ getStatsManager(): StatsManager;
36
+ shutdown(): Promise<void>;
37
+ getReport(): {
38
+ totalFiles: number;
39
+ files: string[];
40
+ symbolsCount: number;
41
+ dependencyGraph: Record<string, {
42
+ imports: string[];
43
+ importedBy: string[];
44
+ }>;
45
+ tokenStats: import("./stats.js").TokenStats;
46
+ };
47
+ }
48
+ export declare function createMCPServer(engine: IndexerEngine): Server;