@mduenas/codegraph 0.4.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 (192) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +641 -0
  3. package/dist/bin/codegraph.d.ts +20 -0
  4. package/dist/bin/codegraph.d.ts.map +1 -0
  5. package/dist/bin/codegraph.js +704 -0
  6. package/dist/bin/codegraph.js.map +1 -0
  7. package/dist/config.d.ts +51 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +291 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/context/formatter.d.ts +30 -0
  12. package/dist/context/formatter.d.ts.map +1 -0
  13. package/dist/context/formatter.js +244 -0
  14. package/dist/context/formatter.js.map +1 -0
  15. package/dist/context/index.d.ts +86 -0
  16. package/dist/context/index.d.ts.map +1 -0
  17. package/dist/context/index.js +402 -0
  18. package/dist/context/index.js.map +1 -0
  19. package/dist/db/index.d.ts +64 -0
  20. package/dist/db/index.d.ts.map +1 -0
  21. package/dist/db/index.js +170 -0
  22. package/dist/db/index.js.map +1 -0
  23. package/dist/db/migrations.d.ts +44 -0
  24. package/dist/db/migrations.d.ts.map +1 -0
  25. package/dist/db/migrations.js +105 -0
  26. package/dist/db/migrations.js.map +1 -0
  27. package/dist/db/queries.d.ts +148 -0
  28. package/dist/db/queries.d.ts.map +1 -0
  29. package/dist/db/queries.js +669 -0
  30. package/dist/db/queries.js.map +1 -0
  31. package/dist/directory.d.ts +45 -0
  32. package/dist/directory.d.ts.map +1 -0
  33. package/dist/directory.js +191 -0
  34. package/dist/directory.js.map +1 -0
  35. package/dist/errors.d.ts +136 -0
  36. package/dist/errors.d.ts.map +1 -0
  37. package/dist/errors.js +219 -0
  38. package/dist/errors.js.map +1 -0
  39. package/dist/extraction/grammars.d.ts +36 -0
  40. package/dist/extraction/grammars.d.ts.map +1 -0
  41. package/dist/extraction/grammars.js +181 -0
  42. package/dist/extraction/grammars.js.map +1 -0
  43. package/dist/extraction/index.d.ts +91 -0
  44. package/dist/extraction/index.d.ts.map +1 -0
  45. package/dist/extraction/index.js +493 -0
  46. package/dist/extraction/index.js.map +1 -0
  47. package/dist/extraction/tree-sitter.d.ts +176 -0
  48. package/dist/extraction/tree-sitter.d.ts.map +1 -0
  49. package/dist/extraction/tree-sitter.js +1798 -0
  50. package/dist/extraction/tree-sitter.js.map +1 -0
  51. package/dist/graph/index.d.ts +8 -0
  52. package/dist/graph/index.d.ts.map +1 -0
  53. package/dist/graph/index.js +13 -0
  54. package/dist/graph/index.js.map +1 -0
  55. package/dist/graph/queries.d.ts +106 -0
  56. package/dist/graph/queries.d.ts.map +1 -0
  57. package/dist/graph/queries.js +355 -0
  58. package/dist/graph/queries.js.map +1 -0
  59. package/dist/graph/traversal.d.ts +127 -0
  60. package/dist/graph/traversal.d.ts.map +1 -0
  61. package/dist/graph/traversal.js +465 -0
  62. package/dist/graph/traversal.js.map +1 -0
  63. package/dist/index.d.ts +496 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +818 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/installer/banner.d.ts +40 -0
  68. package/dist/installer/banner.d.ts.map +1 -0
  69. package/dist/installer/banner.js +162 -0
  70. package/dist/installer/banner.js.map +1 -0
  71. package/dist/installer/claude-md-template.d.ts +10 -0
  72. package/dist/installer/claude-md-template.d.ts.map +1 -0
  73. package/dist/installer/claude-md-template.js +46 -0
  74. package/dist/installer/claude-md-template.js.map +1 -0
  75. package/dist/installer/config-writer.d.ts +36 -0
  76. package/dist/installer/config-writer.d.ts.map +1 -0
  77. package/dist/installer/config-writer.js +282 -0
  78. package/dist/installer/config-writer.js.map +1 -0
  79. package/dist/installer/index.d.ts +13 -0
  80. package/dist/installer/index.d.ts.map +1 -0
  81. package/dist/installer/index.js +155 -0
  82. package/dist/installer/index.js.map +1 -0
  83. package/dist/installer/prompts.d.ts +18 -0
  84. package/dist/installer/prompts.d.ts.map +1 -0
  85. package/dist/installer/prompts.js +113 -0
  86. package/dist/installer/prompts.js.map +1 -0
  87. package/dist/mcp/index.d.ts +64 -0
  88. package/dist/mcp/index.d.ts.map +1 -0
  89. package/dist/mcp/index.js +207 -0
  90. package/dist/mcp/index.js.map +1 -0
  91. package/dist/mcp/tools.d.ts +93 -0
  92. package/dist/mcp/tools.d.ts.map +1 -0
  93. package/dist/mcp/tools.js +442 -0
  94. package/dist/mcp/tools.js.map +1 -0
  95. package/dist/mcp/transport.d.ts +89 -0
  96. package/dist/mcp/transport.d.ts.map +1 -0
  97. package/dist/mcp/transport.js +170 -0
  98. package/dist/mcp/transport.js.map +1 -0
  99. package/dist/resolution/frameworks/csharp.d.ts +8 -0
  100. package/dist/resolution/frameworks/csharp.d.ts.map +1 -0
  101. package/dist/resolution/frameworks/csharp.js +274 -0
  102. package/dist/resolution/frameworks/csharp.js.map +1 -0
  103. package/dist/resolution/frameworks/express.d.ts +8 -0
  104. package/dist/resolution/frameworks/express.d.ts.map +1 -0
  105. package/dist/resolution/frameworks/express.js +208 -0
  106. package/dist/resolution/frameworks/express.js.map +1 -0
  107. package/dist/resolution/frameworks/go.d.ts +8 -0
  108. package/dist/resolution/frameworks/go.d.ts.map +1 -0
  109. package/dist/resolution/frameworks/go.js +225 -0
  110. package/dist/resolution/frameworks/go.js.map +1 -0
  111. package/dist/resolution/frameworks/index.d.ts +33 -0
  112. package/dist/resolution/frameworks/index.d.ts.map +1 -0
  113. package/dist/resolution/frameworks/index.js +113 -0
  114. package/dist/resolution/frameworks/index.js.map +1 -0
  115. package/dist/resolution/frameworks/java.d.ts +8 -0
  116. package/dist/resolution/frameworks/java.d.ts.map +1 -0
  117. package/dist/resolution/frameworks/java.js +239 -0
  118. package/dist/resolution/frameworks/java.js.map +1 -0
  119. package/dist/resolution/frameworks/laravel.d.ts +13 -0
  120. package/dist/resolution/frameworks/laravel.d.ts.map +1 -0
  121. package/dist/resolution/frameworks/laravel.js +198 -0
  122. package/dist/resolution/frameworks/laravel.js.map +1 -0
  123. package/dist/resolution/frameworks/python.d.ts +10 -0
  124. package/dist/resolution/frameworks/python.d.ts.map +1 -0
  125. package/dist/resolution/frameworks/python.js +331 -0
  126. package/dist/resolution/frameworks/python.js.map +1 -0
  127. package/dist/resolution/frameworks/react.d.ts +8 -0
  128. package/dist/resolution/frameworks/react.d.ts.map +1 -0
  129. package/dist/resolution/frameworks/react.js +294 -0
  130. package/dist/resolution/frameworks/react.js.map +1 -0
  131. package/dist/resolution/frameworks/ruby.d.ts +8 -0
  132. package/dist/resolution/frameworks/ruby.d.ts.map +1 -0
  133. package/dist/resolution/frameworks/ruby.js +262 -0
  134. package/dist/resolution/frameworks/ruby.js.map +1 -0
  135. package/dist/resolution/frameworks/rust.d.ts +8 -0
  136. package/dist/resolution/frameworks/rust.d.ts.map +1 -0
  137. package/dist/resolution/frameworks/rust.js +222 -0
  138. package/dist/resolution/frameworks/rust.js.map +1 -0
  139. package/dist/resolution/frameworks/swift.d.ts +10 -0
  140. package/dist/resolution/frameworks/swift.d.ts.map +1 -0
  141. package/dist/resolution/frameworks/swift.js +486 -0
  142. package/dist/resolution/frameworks/swift.js.map +1 -0
  143. package/dist/resolution/import-resolver.d.ts +20 -0
  144. package/dist/resolution/import-resolver.d.ts.map +1 -0
  145. package/dist/resolution/import-resolver.js +445 -0
  146. package/dist/resolution/import-resolver.js.map +1 -0
  147. package/dist/resolution/index.d.ts +72 -0
  148. package/dist/resolution/index.d.ts.map +1 -0
  149. package/dist/resolution/index.js +301 -0
  150. package/dist/resolution/index.js.map +1 -0
  151. package/dist/resolution/name-matcher.d.ts +27 -0
  152. package/dist/resolution/name-matcher.d.ts.map +1 -0
  153. package/dist/resolution/name-matcher.js +210 -0
  154. package/dist/resolution/name-matcher.js.map +1 -0
  155. package/dist/resolution/types.d.ts +108 -0
  156. package/dist/resolution/types.d.ts.map +1 -0
  157. package/dist/resolution/types.js +8 -0
  158. package/dist/resolution/types.js.map +1 -0
  159. package/dist/sync/git-hooks.d.ts +66 -0
  160. package/dist/sync/git-hooks.d.ts.map +1 -0
  161. package/dist/sync/git-hooks.js +281 -0
  162. package/dist/sync/git-hooks.js.map +1 -0
  163. package/dist/sync/index.d.ts +13 -0
  164. package/dist/sync/index.d.ts.map +1 -0
  165. package/dist/sync/index.js +18 -0
  166. package/dist/sync/index.js.map +1 -0
  167. package/dist/types.d.ts +410 -0
  168. package/dist/types.d.ts.map +1 -0
  169. package/dist/types.js +165 -0
  170. package/dist/types.js.map +1 -0
  171. package/dist/utils.d.ts +116 -0
  172. package/dist/utils.d.ts.map +1 -0
  173. package/dist/utils.js +295 -0
  174. package/dist/utils.js.map +1 -0
  175. package/dist/vectors/embedder.d.ts +140 -0
  176. package/dist/vectors/embedder.d.ts.map +1 -0
  177. package/dist/vectors/embedder.js +336 -0
  178. package/dist/vectors/embedder.js.map +1 -0
  179. package/dist/vectors/index.d.ts +9 -0
  180. package/dist/vectors/index.d.ts.map +1 -0
  181. package/dist/vectors/index.js +20 -0
  182. package/dist/vectors/index.js.map +1 -0
  183. package/dist/vectors/manager.d.ts +119 -0
  184. package/dist/vectors/manager.d.ts.map +1 -0
  185. package/dist/vectors/manager.js +274 -0
  186. package/dist/vectors/manager.js.map +1 -0
  187. package/dist/vectors/search.d.ts +134 -0
  188. package/dist/vectors/search.d.ts.map +1 -0
  189. package/dist/vectors/search.js +409 -0
  190. package/dist/vectors/search.js.map +1 -0
  191. package/package.json +67 -0
  192. package/scripts/postinstall.js +68 -0
package/dist/index.js ADDED
@@ -0,0 +1,818 @@
1
+ "use strict";
2
+ /**
3
+ * CodeGraph
4
+ *
5
+ * A local-first code intelligence system that builds a semantic
6
+ * knowledge graph from any codebase.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
42
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.CodeGraph = exports.MCPServer = exports.MemoryMonitor = exports.throttle = exports.debounce = exports.processInBatches = exports.Mutex = exports.defaultLogger = exports.silentLogger = exports.getLogger = exports.setLogger = exports.ConfigError = exports.VectorError = exports.SearchError = exports.DatabaseError = exports.ParseError = exports.FileError = exports.CodeGraphError = exports.getSupportedLanguages = exports.isLanguageSupported = exports.detectLanguage = exports.isInitialized = exports.getCodeGraphDir = exports.getConfigPath = exports.getDatabasePath = void 0;
46
+ const path = __importStar(require("path"));
47
+ const db_1 = require("./db");
48
+ const queries_1 = require("./db/queries");
49
+ const config_1 = require("./config");
50
+ const directory_1 = require("./directory");
51
+ const extraction_1 = require("./extraction");
52
+ const resolution_1 = require("./resolution");
53
+ const graph_1 = require("./graph");
54
+ const vectors_1 = require("./vectors");
55
+ const context_1 = require("./context");
56
+ const sync_1 = require("./sync");
57
+ const utils_1 = require("./utils");
58
+ // Re-export types for consumers
59
+ __exportStar(require("./types"), exports);
60
+ var db_2 = require("./db");
61
+ Object.defineProperty(exports, "getDatabasePath", { enumerable: true, get: function () { return db_2.getDatabasePath; } });
62
+ var config_2 = require("./config");
63
+ Object.defineProperty(exports, "getConfigPath", { enumerable: true, get: function () { return config_2.getConfigPath; } });
64
+ var directory_2 = require("./directory");
65
+ Object.defineProperty(exports, "getCodeGraphDir", { enumerable: true, get: function () { return directory_2.getCodeGraphDir; } });
66
+ Object.defineProperty(exports, "isInitialized", { enumerable: true, get: function () { return directory_2.isInitialized; } });
67
+ var extraction_2 = require("./extraction");
68
+ Object.defineProperty(exports, "detectLanguage", { enumerable: true, get: function () { return extraction_2.detectLanguage; } });
69
+ Object.defineProperty(exports, "isLanguageSupported", { enumerable: true, get: function () { return extraction_2.isLanguageSupported; } });
70
+ Object.defineProperty(exports, "getSupportedLanguages", { enumerable: true, get: function () { return extraction_2.getSupportedLanguages; } });
71
+ var errors_1 = require("./errors");
72
+ Object.defineProperty(exports, "CodeGraphError", { enumerable: true, get: function () { return errors_1.CodeGraphError; } });
73
+ Object.defineProperty(exports, "FileError", { enumerable: true, get: function () { return errors_1.FileError; } });
74
+ Object.defineProperty(exports, "ParseError", { enumerable: true, get: function () { return errors_1.ParseError; } });
75
+ Object.defineProperty(exports, "DatabaseError", { enumerable: true, get: function () { return errors_1.DatabaseError; } });
76
+ Object.defineProperty(exports, "SearchError", { enumerable: true, get: function () { return errors_1.SearchError; } });
77
+ Object.defineProperty(exports, "VectorError", { enumerable: true, get: function () { return errors_1.VectorError; } });
78
+ Object.defineProperty(exports, "ConfigError", { enumerable: true, get: function () { return errors_1.ConfigError; } });
79
+ Object.defineProperty(exports, "setLogger", { enumerable: true, get: function () { return errors_1.setLogger; } });
80
+ Object.defineProperty(exports, "getLogger", { enumerable: true, get: function () { return errors_1.getLogger; } });
81
+ Object.defineProperty(exports, "silentLogger", { enumerable: true, get: function () { return errors_1.silentLogger; } });
82
+ Object.defineProperty(exports, "defaultLogger", { enumerable: true, get: function () { return errors_1.defaultLogger; } });
83
+ var utils_2 = require("./utils");
84
+ Object.defineProperty(exports, "Mutex", { enumerable: true, get: function () { return utils_2.Mutex; } });
85
+ Object.defineProperty(exports, "processInBatches", { enumerable: true, get: function () { return utils_2.processInBatches; } });
86
+ Object.defineProperty(exports, "debounce", { enumerable: true, get: function () { return utils_2.debounce; } });
87
+ Object.defineProperty(exports, "throttle", { enumerable: true, get: function () { return utils_2.throttle; } });
88
+ Object.defineProperty(exports, "MemoryMonitor", { enumerable: true, get: function () { return utils_2.MemoryMonitor; } });
89
+ var mcp_1 = require("./mcp");
90
+ Object.defineProperty(exports, "MCPServer", { enumerable: true, get: function () { return mcp_1.MCPServer; } });
91
+ /**
92
+ * Main CodeGraph class
93
+ *
94
+ * Provides the primary interface for interacting with the code knowledge graph.
95
+ */
96
+ class CodeGraph {
97
+ db;
98
+ queries;
99
+ config;
100
+ projectRoot;
101
+ orchestrator;
102
+ resolver;
103
+ graphManager;
104
+ traverser;
105
+ vectorManager = null;
106
+ contextBuilder;
107
+ gitHooksManager;
108
+ // Mutex for preventing concurrent indexing operations
109
+ indexMutex = new utils_1.Mutex();
110
+ constructor(db, queries, config, projectRoot) {
111
+ this.db = db;
112
+ this.queries = queries;
113
+ this.config = config;
114
+ this.projectRoot = projectRoot;
115
+ this.orchestrator = new extraction_1.ExtractionOrchestrator(projectRoot, config, queries);
116
+ this.resolver = (0, resolution_1.createResolver)(projectRoot, queries);
117
+ this.graphManager = new graph_1.GraphQueryManager(queries);
118
+ this.traverser = new graph_1.GraphTraverser(queries);
119
+ // Vector manager is created lazily when embeddings are enabled
120
+ if (config.enableEmbeddings) {
121
+ this.vectorManager = (0, vectors_1.createVectorManager)(db.getDb(), queries, {
122
+ embedder: {
123
+ cacheDir: path.join(projectRoot, '.codegraph', 'models'),
124
+ },
125
+ });
126
+ }
127
+ // Context builder (uses vector manager if available)
128
+ this.contextBuilder = (0, context_1.createContextBuilder)(projectRoot, queries, this.traverser, this.vectorManager);
129
+ // Git hooks manager
130
+ this.gitHooksManager = (0, sync_1.createGitHooksManager)(projectRoot);
131
+ }
132
+ // ===========================================================================
133
+ // Lifecycle Methods
134
+ // ===========================================================================
135
+ /**
136
+ * Initialize a new CodeGraph project
137
+ *
138
+ * Creates the .codegraph directory, database, and configuration.
139
+ *
140
+ * @param projectRoot - Path to the project root directory
141
+ * @param options - Initialization options
142
+ * @returns A new CodeGraph instance
143
+ */
144
+ static async init(projectRoot, options = {}) {
145
+ const resolvedRoot = path.resolve(projectRoot);
146
+ // Check if already initialized
147
+ if ((0, directory_1.isInitialized)(resolvedRoot)) {
148
+ throw new Error(`CodeGraph already initialized in ${resolvedRoot}`);
149
+ }
150
+ // Create directory structure
151
+ (0, directory_1.createDirectory)(resolvedRoot);
152
+ // Create and save configuration
153
+ const config = (0, config_1.createDefaultConfig)(resolvedRoot);
154
+ if (options.config) {
155
+ Object.assign(config, options.config);
156
+ }
157
+ (0, config_1.saveConfig)(resolvedRoot, config);
158
+ // Initialize database
159
+ const dbPath = (0, db_1.getDatabasePath)(resolvedRoot);
160
+ const db = db_1.DatabaseConnection.initialize(dbPath);
161
+ const queries = new queries_1.QueryBuilder(db.getDb());
162
+ const instance = new CodeGraph(db, queries, config, resolvedRoot);
163
+ // Run initial indexing if requested
164
+ if (options.index) {
165
+ await instance.indexAll({ onProgress: options.onProgress });
166
+ }
167
+ return instance;
168
+ }
169
+ /**
170
+ * Initialize synchronously (without indexing)
171
+ */
172
+ static initSync(projectRoot, options = {}) {
173
+ const resolvedRoot = path.resolve(projectRoot);
174
+ // Check if already initialized
175
+ if ((0, directory_1.isInitialized)(resolvedRoot)) {
176
+ throw new Error(`CodeGraph already initialized in ${resolvedRoot}`);
177
+ }
178
+ // Create directory structure
179
+ (0, directory_1.createDirectory)(resolvedRoot);
180
+ // Create and save configuration
181
+ const config = (0, config_1.createDefaultConfig)(resolvedRoot);
182
+ if (options.config) {
183
+ Object.assign(config, options.config);
184
+ }
185
+ (0, config_1.saveConfig)(resolvedRoot, config);
186
+ // Initialize database
187
+ const dbPath = (0, db_1.getDatabasePath)(resolvedRoot);
188
+ const db = db_1.DatabaseConnection.initialize(dbPath);
189
+ const queries = new queries_1.QueryBuilder(db.getDb());
190
+ return new CodeGraph(db, queries, config, resolvedRoot);
191
+ }
192
+ /**
193
+ * Open an existing CodeGraph project
194
+ *
195
+ * @param projectRoot - Path to the project root directory
196
+ * @param options - Open options
197
+ * @returns A CodeGraph instance
198
+ */
199
+ static async open(projectRoot, options = {}) {
200
+ const resolvedRoot = path.resolve(projectRoot);
201
+ // Check if initialized
202
+ if (!(0, directory_1.isInitialized)(resolvedRoot)) {
203
+ throw new Error(`CodeGraph not initialized in ${resolvedRoot}. Run init() first.`);
204
+ }
205
+ // Validate directory structure
206
+ const validation = (0, directory_1.validateDirectory)(resolvedRoot);
207
+ if (!validation.valid) {
208
+ throw new Error(`Invalid CodeGraph directory: ${validation.errors.join(', ')}`);
209
+ }
210
+ // Load configuration
211
+ const config = (0, config_1.loadConfig)(resolvedRoot);
212
+ // Open database
213
+ const dbPath = (0, db_1.getDatabasePath)(resolvedRoot);
214
+ const db = db_1.DatabaseConnection.open(dbPath);
215
+ const queries = new queries_1.QueryBuilder(db.getDb());
216
+ const instance = new CodeGraph(db, queries, config, resolvedRoot);
217
+ // Sync if requested
218
+ if (options.sync) {
219
+ await instance.sync();
220
+ }
221
+ return instance;
222
+ }
223
+ /**
224
+ * Open synchronously (without sync)
225
+ */
226
+ static openSync(projectRoot) {
227
+ const resolvedRoot = path.resolve(projectRoot);
228
+ // Check if initialized
229
+ if (!(0, directory_1.isInitialized)(resolvedRoot)) {
230
+ throw new Error(`CodeGraph not initialized in ${resolvedRoot}. Run init() first.`);
231
+ }
232
+ // Validate directory structure
233
+ const validation = (0, directory_1.validateDirectory)(resolvedRoot);
234
+ if (!validation.valid) {
235
+ throw new Error(`Invalid CodeGraph directory: ${validation.errors.join(', ')}`);
236
+ }
237
+ // Load configuration
238
+ const config = (0, config_1.loadConfig)(resolvedRoot);
239
+ // Open database
240
+ const dbPath = (0, db_1.getDatabasePath)(resolvedRoot);
241
+ const db = db_1.DatabaseConnection.open(dbPath);
242
+ const queries = new queries_1.QueryBuilder(db.getDb());
243
+ return new CodeGraph(db, queries, config, resolvedRoot);
244
+ }
245
+ /**
246
+ * Check if a directory has been initialized as a CodeGraph project
247
+ */
248
+ static isInitialized(projectRoot) {
249
+ return (0, directory_1.isInitialized)(path.resolve(projectRoot));
250
+ }
251
+ /**
252
+ * Close the CodeGraph instance and release resources
253
+ */
254
+ close() {
255
+ this.db.close();
256
+ }
257
+ // ===========================================================================
258
+ // Configuration
259
+ // ===========================================================================
260
+ /**
261
+ * Get the current configuration
262
+ */
263
+ getConfig() {
264
+ return { ...this.config };
265
+ }
266
+ /**
267
+ * Update configuration
268
+ */
269
+ updateConfig(updates) {
270
+ Object.assign(this.config, updates);
271
+ (0, config_1.saveConfig)(this.projectRoot, this.config);
272
+ // Recreate orchestrator and resolver with new config
273
+ this.orchestrator = new extraction_1.ExtractionOrchestrator(this.projectRoot, this.config, this.queries);
274
+ this.resolver = (0, resolution_1.createResolver)(this.projectRoot, this.queries);
275
+ }
276
+ /**
277
+ * Get the project root directory
278
+ */
279
+ getProjectRoot() {
280
+ return this.projectRoot;
281
+ }
282
+ // ===========================================================================
283
+ // Indexing
284
+ // ===========================================================================
285
+ /**
286
+ * Index all files in the project
287
+ *
288
+ * Uses a mutex to prevent concurrent indexing operations.
289
+ */
290
+ async indexAll(options = {}) {
291
+ return this.indexMutex.withLock(async () => {
292
+ const result = await this.orchestrator.indexAll(options.onProgress, options.signal);
293
+ // Resolve references to create call/import/extends edges
294
+ if (result.success && result.filesIndexed > 0) {
295
+ options.onProgress?.({
296
+ phase: 'resolving',
297
+ current: 0,
298
+ total: 1,
299
+ });
300
+ this.resolveReferences();
301
+ }
302
+ return result;
303
+ });
304
+ }
305
+ /**
306
+ * Index specific files
307
+ *
308
+ * Uses a mutex to prevent concurrent indexing operations.
309
+ */
310
+ async indexFiles(filePaths) {
311
+ return this.indexMutex.withLock(async () => {
312
+ return this.orchestrator.indexFiles(filePaths);
313
+ });
314
+ }
315
+ /**
316
+ * Sync with current file state (incremental update)
317
+ *
318
+ * Uses a mutex to prevent concurrent indexing operations.
319
+ */
320
+ async sync(options = {}) {
321
+ return this.indexMutex.withLock(async () => {
322
+ const result = await this.orchestrator.sync(options.onProgress);
323
+ // Resolve references if files were updated
324
+ if (result.filesAdded > 0 || result.filesModified > 0) {
325
+ this.resolveReferences();
326
+ }
327
+ return result;
328
+ });
329
+ }
330
+ /**
331
+ * Check if an indexing operation is currently in progress
332
+ */
333
+ isIndexing() {
334
+ return this.indexMutex.isLocked();
335
+ }
336
+ /**
337
+ * Get files that have changed since last index
338
+ */
339
+ getChangedFiles() {
340
+ return this.orchestrator.getChangedFiles();
341
+ }
342
+ /**
343
+ * Extract nodes and edges from source code (without storing)
344
+ */
345
+ extractFromSource(filePath, source) {
346
+ return (0, extraction_1.extractFromSource)(filePath, source);
347
+ }
348
+ // ===========================================================================
349
+ // Reference Resolution
350
+ // ===========================================================================
351
+ /**
352
+ * Resolve unresolved references and create edges
353
+ *
354
+ * This method takes unresolved references from extraction and attempts
355
+ * to resolve them using multiple strategies:
356
+ * - Framework-specific patterns (React, Express, Laravel)
357
+ * - Import-based resolution
358
+ * - Name-based symbol matching
359
+ */
360
+ resolveReferences() {
361
+ // Get all unresolved references from the database
362
+ const unresolvedRefs = this.queries.getUnresolvedReferences();
363
+ return this.resolver.resolveAndPersist(unresolvedRefs);
364
+ }
365
+ /**
366
+ * Get detected frameworks in the project
367
+ */
368
+ getDetectedFrameworks() {
369
+ return this.resolver.getDetectedFrameworks();
370
+ }
371
+ /**
372
+ * Re-initialize the resolver (useful after adding new files)
373
+ */
374
+ reinitializeResolver() {
375
+ this.resolver.initialize();
376
+ }
377
+ // ===========================================================================
378
+ // Graph Statistics
379
+ // ===========================================================================
380
+ /**
381
+ * Get statistics about the knowledge graph
382
+ */
383
+ getStats() {
384
+ const stats = this.queries.getStats();
385
+ stats.dbSizeBytes = this.db.getSize();
386
+ return stats;
387
+ }
388
+ // ===========================================================================
389
+ // Node Operations
390
+ // ===========================================================================
391
+ /**
392
+ * Get a node by ID
393
+ */
394
+ getNode(id) {
395
+ return this.queries.getNodeById(id);
396
+ }
397
+ /**
398
+ * Get all nodes in a file
399
+ */
400
+ getNodesInFile(filePath) {
401
+ return this.queries.getNodesByFile(filePath);
402
+ }
403
+ /**
404
+ * Get all nodes of a specific kind
405
+ */
406
+ getNodesByKind(kind) {
407
+ return this.queries.getNodesByKind(kind);
408
+ }
409
+ /**
410
+ * Search nodes by text
411
+ */
412
+ searchNodes(query, options) {
413
+ return this.queries.searchNodes(query, options);
414
+ }
415
+ // ===========================================================================
416
+ // Edge Operations
417
+ // ===========================================================================
418
+ /**
419
+ * Get outgoing edges from a node
420
+ */
421
+ getOutgoingEdges(nodeId) {
422
+ return this.queries.getOutgoingEdges(nodeId);
423
+ }
424
+ /**
425
+ * Get incoming edges to a node
426
+ */
427
+ getIncomingEdges(nodeId) {
428
+ return this.queries.getIncomingEdges(nodeId);
429
+ }
430
+ // ===========================================================================
431
+ // File Operations
432
+ // ===========================================================================
433
+ /**
434
+ * Get a file record by path
435
+ */
436
+ getFile(filePath) {
437
+ return this.queries.getFileByPath(filePath);
438
+ }
439
+ /**
440
+ * Get all tracked files
441
+ */
442
+ getFiles() {
443
+ return this.queries.getAllFiles();
444
+ }
445
+ // ===========================================================================
446
+ // Graph Query Methods
447
+ // ===========================================================================
448
+ /**
449
+ * Get the context for a node (ancestors, children, references)
450
+ *
451
+ * Returns comprehensive context about a node including its containment
452
+ * hierarchy, children, incoming/outgoing references, type information,
453
+ * and relevant imports.
454
+ *
455
+ * @param nodeId - ID of the focal node
456
+ * @returns Context object with all related information
457
+ */
458
+ getContext(nodeId) {
459
+ return this.graphManager.getContext(nodeId);
460
+ }
461
+ /**
462
+ * Traverse the graph from a starting node
463
+ *
464
+ * Uses breadth-first search by default. Supports filtering by edge types,
465
+ * node types, and traversal direction.
466
+ *
467
+ * @param startId - Starting node ID
468
+ * @param options - Traversal options
469
+ * @returns Subgraph containing traversed nodes and edges
470
+ */
471
+ traverse(startId, options) {
472
+ return this.traverser.traverseBFS(startId, options);
473
+ }
474
+ /**
475
+ * Get the call graph for a function
476
+ *
477
+ * Returns both callers (functions that call this function) and
478
+ * callees (functions called by this function) up to the specified depth.
479
+ *
480
+ * @param nodeId - ID of the function/method node
481
+ * @param depth - Maximum depth in each direction (default: 2)
482
+ * @returns Subgraph containing the call graph
483
+ */
484
+ getCallGraph(nodeId, depth = 2) {
485
+ return this.traverser.getCallGraph(nodeId, depth);
486
+ }
487
+ /**
488
+ * Get the type hierarchy for a class/interface
489
+ *
490
+ * Returns both ancestors (types this extends/implements) and
491
+ * descendants (types that extend/implement this).
492
+ *
493
+ * @param nodeId - ID of the class/interface node
494
+ * @returns Subgraph containing the type hierarchy
495
+ */
496
+ getTypeHierarchy(nodeId) {
497
+ return this.traverser.getTypeHierarchy(nodeId);
498
+ }
499
+ /**
500
+ * Find all usages of a symbol
501
+ *
502
+ * Returns all nodes that reference the specified symbol through
503
+ * any edge type (calls, references, type_of, etc.).
504
+ *
505
+ * @param nodeId - ID of the symbol node
506
+ * @returns Array of nodes and edges that reference this symbol
507
+ */
508
+ findUsages(nodeId) {
509
+ return this.traverser.findUsages(nodeId);
510
+ }
511
+ /**
512
+ * Get callers of a function/method
513
+ *
514
+ * @param nodeId - ID of the function/method node
515
+ * @param maxDepth - Maximum depth to traverse (default: 1)
516
+ * @returns Array of nodes that call this function
517
+ */
518
+ getCallers(nodeId, maxDepth = 1) {
519
+ return this.traverser.getCallers(nodeId, maxDepth);
520
+ }
521
+ /**
522
+ * Get callees of a function/method
523
+ *
524
+ * @param nodeId - ID of the function/method node
525
+ * @param maxDepth - Maximum depth to traverse (default: 1)
526
+ * @returns Array of nodes called by this function
527
+ */
528
+ getCallees(nodeId, maxDepth = 1) {
529
+ return this.traverser.getCallees(nodeId, maxDepth);
530
+ }
531
+ /**
532
+ * Calculate the impact radius of a node
533
+ *
534
+ * Returns all nodes that could be affected by changes to this node.
535
+ *
536
+ * @param nodeId - ID of the node
537
+ * @param maxDepth - Maximum depth to traverse (default: 3)
538
+ * @returns Subgraph containing potentially impacted nodes
539
+ */
540
+ getImpactRadius(nodeId, maxDepth = 3) {
541
+ return this.traverser.getImpactRadius(nodeId, maxDepth);
542
+ }
543
+ /**
544
+ * Find the shortest path between two nodes
545
+ *
546
+ * @param fromId - Starting node ID
547
+ * @param toId - Target node ID
548
+ * @param edgeKinds - Edge types to consider (all if empty)
549
+ * @returns Array of nodes and edges forming the path, or null if no path exists
550
+ */
551
+ findPath(fromId, toId, edgeKinds) {
552
+ return this.traverser.findPath(fromId, toId, edgeKinds);
553
+ }
554
+ /**
555
+ * Get ancestors of a node in the containment hierarchy
556
+ *
557
+ * @param nodeId - ID of the node
558
+ * @returns Array of ancestor nodes from immediate parent to root
559
+ */
560
+ getAncestors(nodeId) {
561
+ return this.traverser.getAncestors(nodeId);
562
+ }
563
+ /**
564
+ * Get immediate children of a node
565
+ *
566
+ * @param nodeId - ID of the node
567
+ * @returns Array of child nodes
568
+ */
569
+ getChildren(nodeId) {
570
+ return this.traverser.getChildren(nodeId);
571
+ }
572
+ /**
573
+ * Get dependencies of a file
574
+ *
575
+ * @param filePath - Path to the file
576
+ * @returns Array of file paths this file depends on
577
+ */
578
+ getFileDependencies(filePath) {
579
+ return this.graphManager.getFileDependencies(filePath);
580
+ }
581
+ /**
582
+ * Get dependents of a file
583
+ *
584
+ * @param filePath - Path to the file
585
+ * @returns Array of file paths that depend on this file
586
+ */
587
+ getFileDependents(filePath) {
588
+ return this.graphManager.getFileDependents(filePath);
589
+ }
590
+ /**
591
+ * Find circular dependencies in the codebase
592
+ *
593
+ * @returns Array of cycles, each cycle is an array of file paths
594
+ */
595
+ findCircularDependencies() {
596
+ return this.graphManager.findCircularDependencies();
597
+ }
598
+ /**
599
+ * Find dead code (unreferenced symbols)
600
+ *
601
+ * @param kinds - Node kinds to check (default: functions, methods, classes)
602
+ * @returns Array of unreferenced nodes
603
+ */
604
+ findDeadCode(kinds) {
605
+ return this.graphManager.findDeadCode(kinds);
606
+ }
607
+ /**
608
+ * Get complexity metrics for a node
609
+ *
610
+ * @param nodeId - ID of the node
611
+ * @returns Object containing various complexity metrics
612
+ */
613
+ getNodeMetrics(nodeId) {
614
+ return this.graphManager.getNodeMetrics(nodeId);
615
+ }
616
+ // ===========================================================================
617
+ // Semantic Search (Vector Embeddings)
618
+ // ===========================================================================
619
+ /**
620
+ * Initialize the embedding system
621
+ *
622
+ * This downloads the embedding model on first use and initializes
623
+ * the vector search system. Must be called before using semantic search.
624
+ */
625
+ async initializeEmbeddings() {
626
+ if (!this.vectorManager) {
627
+ this.vectorManager = (0, vectors_1.createVectorManager)(this.db.getDb(), this.queries, {
628
+ embedder: {
629
+ showProgress: true,
630
+ },
631
+ });
632
+ }
633
+ await this.vectorManager.initialize();
634
+ }
635
+ /**
636
+ * Check if embeddings are initialized
637
+ */
638
+ isEmbeddingsInitialized() {
639
+ return this.vectorManager?.isInitialized() ?? false;
640
+ }
641
+ /**
642
+ * Generate embeddings for all eligible nodes
643
+ *
644
+ * @param onProgress - Optional progress callback
645
+ * @returns Number of nodes embedded
646
+ */
647
+ async generateEmbeddings(onProgress) {
648
+ if (!this.vectorManager) {
649
+ await this.initializeEmbeddings();
650
+ }
651
+ return this.vectorManager.embedAllNodes(onProgress);
652
+ }
653
+ /**
654
+ * Semantic search using embeddings
655
+ *
656
+ * Searches for code nodes semantically similar to the query.
657
+ * Requires embeddings to be initialized first.
658
+ *
659
+ * @param query - Natural language search query
660
+ * @param limit - Maximum number of results (default: 10)
661
+ * @returns Array of search results with similarity scores
662
+ */
663
+ async semanticSearch(query, limit = 10) {
664
+ if (!this.vectorManager || !this.vectorManager.isInitialized()) {
665
+ throw new Error('Embeddings not initialized. Call initializeEmbeddings() first.');
666
+ }
667
+ return this.vectorManager.search(query, { limit });
668
+ }
669
+ /**
670
+ * Find similar code blocks
671
+ *
672
+ * Finds nodes semantically similar to a given node.
673
+ * Requires embeddings to be initialized first.
674
+ *
675
+ * @param nodeId - ID of the node to find similar nodes for
676
+ * @param limit - Maximum number of results (default: 10)
677
+ * @returns Array of similar nodes with similarity scores
678
+ */
679
+ async findSimilar(nodeId, limit = 10) {
680
+ if (!this.vectorManager || !this.vectorManager.isInitialized()) {
681
+ throw new Error('Embeddings not initialized. Call initializeEmbeddings() first.');
682
+ }
683
+ return this.vectorManager.findSimilar(nodeId, { limit });
684
+ }
685
+ /**
686
+ * Get vector embedding statistics
687
+ */
688
+ getEmbeddingStats() {
689
+ if (!this.vectorManager) {
690
+ return null;
691
+ }
692
+ return this.vectorManager.getStats();
693
+ }
694
+ // ===========================================================================
695
+ // Context Building
696
+ // ===========================================================================
697
+ /**
698
+ * Get the source code for a node
699
+ *
700
+ * Reads the file and extracts the code between startLine and endLine.
701
+ *
702
+ * @param nodeId - ID of the node
703
+ * @returns Code string or null if not found
704
+ */
705
+ async getCode(nodeId) {
706
+ return this.contextBuilder.getCode(nodeId);
707
+ }
708
+ /**
709
+ * Find relevant subgraph for a query
710
+ *
711
+ * Combines semantic search with graph traversal to find the most
712
+ * relevant nodes and their relationships for a given query.
713
+ *
714
+ * @param query - Natural language query describing the task
715
+ * @param options - Search and traversal options
716
+ * @returns Subgraph of relevant nodes and edges
717
+ */
718
+ async findRelevantContext(query, options) {
719
+ // Update context builder with current vector manager
720
+ this.contextBuilder = (0, context_1.createContextBuilder)(this.projectRoot, this.queries, this.traverser, this.vectorManager);
721
+ return this.contextBuilder.findRelevantContext(query, options);
722
+ }
723
+ /**
724
+ * Build context for a task
725
+ *
726
+ * Creates comprehensive context by:
727
+ * 1. Running semantic search to find entry points
728
+ * 2. Expanding the graph around entry points
729
+ * 3. Extracting code blocks for key nodes
730
+ * 4. Formatting output for Claude
731
+ *
732
+ * @param input - Task description (string or {title, description})
733
+ * @param options - Build options (maxNodes, includeCode, format, etc.)
734
+ * @returns TaskContext object or formatted string (markdown/JSON)
735
+ */
736
+ async buildContext(input, options) {
737
+ // Update context builder with current vector manager
738
+ this.contextBuilder = (0, context_1.createContextBuilder)(this.projectRoot, this.queries, this.traverser, this.vectorManager);
739
+ return this.contextBuilder.buildContext(input, options);
740
+ }
741
+ // ===========================================================================
742
+ // Git Integration
743
+ // ===========================================================================
744
+ /**
745
+ * Check if the project is a git repository
746
+ */
747
+ isGitRepository() {
748
+ return this.gitHooksManager.isGitRepository();
749
+ }
750
+ /**
751
+ * Check if the CodeGraph git hook is installed
752
+ */
753
+ isGitHookInstalled() {
754
+ return this.gitHooksManager.isHookInstalled();
755
+ }
756
+ /**
757
+ * Install git hooks for automatic incremental indexing
758
+ *
759
+ * Installs a post-commit hook that automatically runs `codegraph sync`
760
+ * after each commit to keep the graph up-to-date.
761
+ *
762
+ * If a post-commit hook already exists:
763
+ * - If it's a CodeGraph hook, it will be updated
764
+ * - If it's a user hook, it will be backed up before installing
765
+ *
766
+ * @returns Result indicating success/failure and any messages
767
+ */
768
+ installGitHooks() {
769
+ return this.gitHooksManager.installHook();
770
+ }
771
+ /**
772
+ * Remove CodeGraph git hooks
773
+ *
774
+ * Removes the CodeGraph post-commit hook. If a backup of a previous
775
+ * user hook exists, it will be restored.
776
+ *
777
+ * @returns Result indicating success/failure and any messages
778
+ */
779
+ removeGitHooks() {
780
+ return this.gitHooksManager.removeHook();
781
+ }
782
+ // ===========================================================================
783
+ // Database Management
784
+ // ===========================================================================
785
+ /**
786
+ * Optimize the database (vacuum and analyze)
787
+ */
788
+ optimize() {
789
+ this.db.optimize();
790
+ }
791
+ /**
792
+ * Clear all data from the graph
793
+ */
794
+ clear() {
795
+ this.queries.clear();
796
+ }
797
+ /**
798
+ * Alias for close() for backwards compatibility.
799
+ * @deprecated Use close() instead
800
+ */
801
+ destroy() {
802
+ this.close();
803
+ }
804
+ /**
805
+ * Completely remove CodeGraph from the project.
806
+ * This closes the database and deletes the .codegraph directory.
807
+ *
808
+ * WARNING: This permanently deletes all CodeGraph data for the project.
809
+ */
810
+ uninitialize() {
811
+ this.db.close();
812
+ (0, directory_1.removeDirectory)(this.projectRoot);
813
+ }
814
+ }
815
+ exports.CodeGraph = CodeGraph;
816
+ // Default export
817
+ exports.default = CodeGraph;
818
+ //# sourceMappingURL=index.js.map