@codragraph/cli 1.6.4 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/README.md +34 -0
  2. package/dist/_shared/cgdb/schema-constants.d.ts +16 -0
  3. package/dist/_shared/cgdb/schema-constants.d.ts.map +1 -0
  4. package/dist/_shared/cgdb/schema-constants.js +67 -0
  5. package/dist/_shared/cgdb/schema-constants.js.map +1 -0
  6. package/dist/_shared/index.d.ts +2 -2
  7. package/dist/_shared/index.js +1 -1
  8. package/dist/cli/analyze.d.ts +22 -0
  9. package/dist/cli/analyze.js +109 -6
  10. package/dist/cli/compress-stats.d.ts +29 -0
  11. package/dist/cli/compress-stats.js +97 -0
  12. package/dist/cli/graphstore.d.ts +6 -2
  13. package/dist/cli/graphstore.js +45 -23
  14. package/dist/cli/index-repo.js +3 -3
  15. package/dist/cli/index.js +16 -2
  16. package/dist/cli/profile-heap.d.ts +35 -0
  17. package/dist/cli/profile-heap.js +126 -0
  18. package/dist/cli/setup.d.ts +13 -0
  19. package/dist/cli/setup.js +22 -11
  20. package/dist/cli/skill-gen.d.ts +14 -2
  21. package/dist/cli/skill-gen.js +52 -19
  22. package/dist/cli/tool.js +4 -0
  23. package/dist/cli/wiki.js +3 -3
  24. package/dist/core/augmentation/engine.js +7 -7
  25. package/dist/core/cgdb/cgdb-adapter.d.ts +176 -0
  26. package/dist/core/cgdb/cgdb-adapter.js +1320 -0
  27. package/dist/core/cgdb/content-read.d.ts +46 -0
  28. package/dist/core/cgdb/content-read.js +64 -0
  29. package/dist/core/cgdb/csv-generator.d.ts +29 -0
  30. package/dist/core/cgdb/csv-generator.js +492 -0
  31. package/dist/core/cgdb/pool-adapter.d.ts +93 -0
  32. package/dist/core/cgdb/pool-adapter.js +550 -0
  33. package/dist/core/cgdb/schema.d.ts +62 -0
  34. package/dist/core/cgdb/schema.js +502 -0
  35. package/dist/core/embeddings/embedding-pipeline.js +27 -10
  36. package/dist/core/graphstore/cgdb-row-source.d.ts +19 -0
  37. package/dist/core/graphstore/cgdb-row-source.js +141 -0
  38. package/dist/core/graphstore/index.d.ts +1 -1
  39. package/dist/core/graphstore/index.js +3 -3
  40. package/dist/core/group/bridge-db.d.ts +2 -2
  41. package/dist/core/group/bridge-db.js +123 -36
  42. package/dist/core/group/bridge-schema.d.ts +4 -4
  43. package/dist/core/group/bridge-schema.js +4 -4
  44. package/dist/core/group/cross-impact.js +3 -3
  45. package/dist/core/group/sync.js +4 -4
  46. package/dist/core/lbug/content-read.d.ts +46 -0
  47. package/dist/core/lbug/content-read.js +64 -0
  48. package/dist/core/lbug/csv-generator.d.ts +2 -6
  49. package/dist/core/lbug/csv-generator.js +45 -12
  50. package/dist/core/lbug/lbug-adapter.d.ts +4 -1
  51. package/dist/core/lbug/lbug-adapter.js +153 -21
  52. package/dist/core/lbug/schema.d.ts +7 -7
  53. package/dist/core/lbug/schema.js +18 -0
  54. package/dist/core/run-analyze.d.ts +13 -0
  55. package/dist/core/run-analyze.js +114 -27
  56. package/dist/core/search/bm25-index.d.ts +3 -3
  57. package/dist/core/search/bm25-index.js +75 -23
  58. package/dist/core/search/hybrid-search.js +2 -2
  59. package/dist/core/wiki/generator.d.ts +2 -2
  60. package/dist/core/wiki/generator.js +4 -4
  61. package/dist/core/wiki/graph-queries.d.ts +2 -2
  62. package/dist/core/wiki/graph-queries.js +5 -5
  63. package/dist/mcp/core/cgdb-adapter.d.ts +5 -0
  64. package/dist/mcp/core/cgdb-adapter.js +5 -0
  65. package/dist/mcp/core/embedder.js +1 -1
  66. package/dist/mcp/local/local-backend.d.ts +2 -2
  67. package/dist/mcp/local/local-backend.js +36 -19
  68. package/dist/mcp/server.js +3 -3
  69. package/dist/mcp/tools.js +1 -1
  70. package/dist/server/analyze-worker.js +2 -2
  71. package/dist/server/api.js +34 -33
  72. package/dist/storage/repo-manager.d.ts +42 -3
  73. package/dist/storage/repo-manager.js +23 -4
  74. package/hooks/claude/codragraph-hook.cjs +98 -5
  75. package/package.json +4 -4
  76. package/scripts/build-tree-sitter-proto.cjs +15 -3
  77. package/scripts/build.js +8 -9
  78. package/scripts/patch-tree-sitter-swift.cjs +17 -4
  79. package/skills/codragraph-api-surface.md +110 -0
  80. package/skills/codragraph-config-audit.md +146 -0
  81. package/skills/codragraph-cross-repo-impact.md +135 -0
  82. package/skills/codragraph-data-lineage.md +137 -0
  83. package/skills/codragraph-dead-code.md +119 -0
  84. package/skills/codragraph-gh-actions-debug.md +162 -0
  85. package/skills/codragraph-gh-issue-workflow.md +178 -0
  86. package/skills/codragraph-gh-pr-workflow.md +176 -0
  87. package/skills/codragraph-gh-release-workflow.md +187 -0
  88. package/skills/codragraph-git-bisect.md +176 -0
  89. package/skills/codragraph-git-force-push.md +147 -0
  90. package/skills/codragraph-git-history-rewrite.md +174 -0
  91. package/skills/codragraph-git-rebase-vs-merge.md +138 -0
  92. package/skills/codragraph-git-recovery.md +181 -0
  93. package/skills/codragraph-git-worktree.md +145 -0
  94. package/skills/codragraph-migration-tracking.md +130 -0
  95. package/skills/codragraph-notebook-context.md +136 -0
  96. package/skills/codragraph-observability-coverage.md +125 -0
  97. package/skills/codragraph-onboarding.md +129 -0
  98. package/skills/codragraph-perf-hotspots.md +132 -0
  99. package/skills/codragraph-project-switcher.md +116 -0
  100. package/skills/codragraph-security-audit.md +144 -0
  101. package/skills/codragraph-sql-tracing.md +122 -0
  102. package/skills/codragraph-supply-chain-audit.md +153 -0
  103. package/skills/codragraph-test-coverage.md +97 -0
  104. package/vendor/tree-sitter-proto/bindings/node/index.js +3 -3
  105. package/vendor/tree-sitter-proto/src/node-types.json +1 -1
@@ -13,6 +13,7 @@
13
13
  */
14
14
  import { KnowledgeGraph } from '../graph/types.js';
15
15
  import { NodeTableName } from './schema.js';
16
+ import { type ContentEncoding } from '@codragraph/graphstore';
16
17
  export declare const sanitizeUTF8: (str: string) => string;
17
18
  export declare const escapeCSVField: (value: string | number | undefined | null) => string;
18
19
  export declare const escapeCSVNumber: (value: number | undefined | null, defaultValue?: number) => string;
@@ -25,9 +26,4 @@ export interface StreamedCSVResult {
25
26
  relCsvPath: string;
26
27
  relRows: number;
27
28
  }
28
- /**
29
- * Stream all CSV data directly to disk files.
30
- * Iterates graph nodes exactly ONCE — routes each node to the right writer.
31
- * File contents are lazy-read from disk with a generous LRU cache.
32
- */
33
- export declare const streamAllCSVsToDisk: (graph: KnowledgeGraph, repoPath: string, csvDir: string) => Promise<StreamedCSVResult>;
29
+ export declare const streamAllCSVsToDisk: (graph: KnowledgeGraph, repoPath: string, csvDir: string, compress?: ContentEncoding) => Promise<StreamedCSVResult>;
@@ -14,6 +14,7 @@
14
14
  import fs from 'fs/promises';
15
15
  import { createWriteStream } from 'fs';
16
16
  import path from 'path';
17
+ import { encodeContent } from '@codragraph/graphstore';
17
18
  /** Flush buffered rows to disk every N rows */
18
19
  const FLUSH_EVERY = 500;
19
20
  // ============================================================================
@@ -184,7 +185,26 @@ class BufferedCSVWriter {
184
185
  * Iterates graph nodes exactly ONCE — routes each node to the right writer.
185
186
  * File contents are lazy-read from disk with a generous LRU cache.
186
187
  */
187
- export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
188
+ /**
189
+ * Apply RFC 0001 Phase 2 content encoding. Returns the on-the-wire string
190
+ * + the encoding tag to write into the per-row `contentEncoding` column.
191
+ *
192
+ * `compress: undefined | 'none'` is the default — content goes through
193
+ * unchanged and the tag is `'none'` (matches the schema DEFAULT, so older
194
+ * readers and the schema-default behavior stay in agreement).
195
+ *
196
+ * Always writing the tag column (even as 'none') keeps the CSV / COPY /
197
+ * schema layouts uniform regardless of compression mode. The wasted bytes
198
+ * are negligible — a few characters per row vs the kilobytes of content
199
+ * the column is alongside.
200
+ */
201
+ const applyEncoding = (content, compress) => {
202
+ if (!compress || compress === 'none') {
203
+ return { wireContent: content, tag: 'none' };
204
+ }
205
+ return { wireContent: encodeContent(content, compress), tag: compress };
206
+ };
207
+ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir, compress) => {
188
208
  // Remove stale CSVs from previous crashed runs, then recreate
189
209
  try {
190
210
  await fs.rm(csvDir, { recursive: true, force: true });
@@ -196,26 +216,29 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
196
216
  const prevMax = process.getMaxListeners();
197
217
  process.setMaxListeners(prevMax + 40);
198
218
  const contentCache = new FileContentCache(repoPath);
199
- // Create writers for every node type up-front
200
- const fileWriter = new BufferedCSVWriter(path.join(csvDir, 'file.csv'), 'id,name,filePath,content');
219
+ // Create writers for every node type up-front. Content-bearing tables
220
+ // carry an extra `contentEncoding` column right after `content` to
221
+ // match the Phase 2 schema layout. Tables without `content` (Folder,
222
+ // Community, Process, Route, Tool) are unchanged.
223
+ const fileWriter = new BufferedCSVWriter(path.join(csvDir, 'file.csv'), 'id,name,filePath,content,contentEncoding');
201
224
  const folderWriter = new BufferedCSVWriter(path.join(csvDir, 'folder.csv'), 'id,name,filePath');
202
- const codeElementHeader = 'id,name,filePath,startLine,endLine,isExported,content,description';
225
+ const codeElementHeader = 'id,name,filePath,startLine,endLine,isExported,content,contentEncoding,description';
203
226
  const functionWriter = new BufferedCSVWriter(path.join(csvDir, 'function.csv'), codeElementHeader);
204
227
  const classWriter = new BufferedCSVWriter(path.join(csvDir, 'class.csv'), codeElementHeader);
205
228
  const interfaceWriter = new BufferedCSVWriter(path.join(csvDir, 'interface.csv'), codeElementHeader);
206
- const methodHeader = 'id,name,filePath,startLine,endLine,isExported,content,description,parameterCount,returnType';
229
+ const methodHeader = 'id,name,filePath,startLine,endLine,isExported,content,contentEncoding,description,parameterCount,returnType';
207
230
  const methodWriter = new BufferedCSVWriter(path.join(csvDir, 'method.csv'), methodHeader);
208
231
  const codeElemWriter = new BufferedCSVWriter(path.join(csvDir, 'codeelement.csv'), codeElementHeader);
209
232
  const communityWriter = new BufferedCSVWriter(path.join(csvDir, 'community.csv'), 'id,label,heuristicLabel,keywords,description,enrichedBy,cohesion,symbolCount');
210
233
  const processWriter = new BufferedCSVWriter(path.join(csvDir, 'process.csv'), 'id,label,heuristicLabel,processType,stepCount,communities,entryPointId,terminalId');
211
234
  // Section nodes have an extra 'level' column
212
- const sectionWriter = new BufferedCSVWriter(path.join(csvDir, 'section.csv'), 'id,name,filePath,startLine,endLine,level,content,description');
235
+ const sectionWriter = new BufferedCSVWriter(path.join(csvDir, 'section.csv'), 'id,name,filePath,startLine,endLine,level,content,contentEncoding,description');
213
236
  // Route nodes for API endpoint mapping
214
237
  const routeWriter = new BufferedCSVWriter(path.join(csvDir, 'route.csv'), 'id,name,filePath,responseKeys,errorKeys,middleware');
215
238
  // Tool nodes for MCP tool definitions
216
239
  const toolWriter = new BufferedCSVWriter(path.join(csvDir, 'tool.csv'), 'id,name,filePath,description');
217
240
  // Multi-language node types share the same CSV shape (no isExported column)
218
- const multiLangHeader = 'id,name,filePath,startLine,endLine,content,description';
241
+ const multiLangHeader = 'id,name,filePath,startLine,endLine,content,contentEncoding,description';
219
242
  const MULTI_LANG_TYPES = [
220
243
  'Struct',
221
244
  'Enum',
@@ -259,11 +282,13 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
259
282
  switch (node.label) {
260
283
  case 'File': {
261
284
  const content = await extractContent(node, contentCache);
285
+ const { wireContent, tag } = applyEncoding(content, compress);
262
286
  await fileWriter.addRow([
263
287
  escapeCSVField(node.id),
264
288
  escapeCSVField(node.properties.name || ''),
265
289
  escapeCSVField(node.properties.filePath || ''),
266
- escapeCSVField(content),
290
+ escapeCSVField(wireContent),
291
+ escapeCSVField(tag),
267
292
  ].join(','));
268
293
  break;
269
294
  }
@@ -306,6 +331,7 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
306
331
  }
307
332
  case 'Method': {
308
333
  const content = await extractContent(node, contentCache);
334
+ const { wireContent, tag } = applyEncoding(content, compress);
309
335
  await methodWriter.addRow([
310
336
  escapeCSVField(node.id),
311
337
  escapeCSVField(node.properties.name || ''),
@@ -313,7 +339,8 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
313
339
  escapeCSVNumber(node.properties.startLine, -1),
314
340
  escapeCSVNumber(node.properties.endLine, -1),
315
341
  node.properties.isExported ? 'true' : 'false',
316
- escapeCSVField(content),
342
+ escapeCSVField(wireContent),
343
+ escapeCSVField(tag),
317
344
  escapeCSVField(node.properties.description || ''),
318
345
  escapeCSVNumber(node.properties.parameterCount, 0),
319
346
  escapeCSVField(node.properties.returnType || ''),
@@ -322,6 +349,7 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
322
349
  }
323
350
  case 'Section': {
324
351
  const content = await extractContent(node, contentCache);
352
+ const { wireContent, tag } = applyEncoding(content, compress);
325
353
  await sectionWriter.addRow([
326
354
  escapeCSVField(node.id),
327
355
  escapeCSVField(node.properties.name || ''),
@@ -329,7 +357,8 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
329
357
  escapeCSVNumber(node.properties.startLine, -1),
330
358
  escapeCSVNumber(node.properties.endLine, -1),
331
359
  escapeCSVNumber(node.properties.level, 1),
332
- escapeCSVField(content),
360
+ escapeCSVField(wireContent),
361
+ escapeCSVField(tag),
333
362
  escapeCSVField(node.properties.description || ''),
334
363
  ].join(','));
335
364
  break;
@@ -366,6 +395,7 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
366
395
  const writer = codeWriterMap[node.label];
367
396
  if (writer) {
368
397
  const content = await extractContent(node, contentCache);
398
+ const { wireContent, tag } = applyEncoding(content, compress);
369
399
  await writer.addRow([
370
400
  escapeCSVField(node.id),
371
401
  escapeCSVField(node.properties.name || ''),
@@ -373,7 +403,8 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
373
403
  escapeCSVNumber(node.properties.startLine, -1),
374
404
  escapeCSVNumber(node.properties.endLine, -1),
375
405
  node.properties.isExported ? 'true' : 'false',
376
- escapeCSVField(content),
406
+ escapeCSVField(wireContent),
407
+ escapeCSVField(tag),
377
408
  escapeCSVField(node.properties.description || ''),
378
409
  ].join(','));
379
410
  }
@@ -382,13 +413,15 @@ export const streamAllCSVsToDisk = async (graph, repoPath, csvDir) => {
382
413
  const mlWriter = multiLangWriters.get(node.label);
383
414
  if (mlWriter) {
384
415
  const content = await extractContent(node, contentCache);
416
+ const { wireContent, tag } = applyEncoding(content, compress);
385
417
  await mlWriter.addRow([
386
418
  escapeCSVField(node.id),
387
419
  escapeCSVField(node.properties.name || ''),
388
420
  escapeCSVField(node.properties.filePath || ''),
389
421
  escapeCSVNumber(node.properties.startLine, -1),
390
422
  escapeCSVNumber(node.properties.endLine, -1),
391
- escapeCSVField(content),
423
+ escapeCSVField(wireContent),
424
+ escapeCSVField(tag),
392
425
  escapeCSVField(node.properties.description || ''),
393
426
  ].join(','));
394
427
  }
@@ -1,6 +1,7 @@
1
1
  import lbug from '@ladybugdb/core';
2
2
  import { KnowledgeGraph } from '../graph/types.js';
3
3
  import type { CachedEmbedding } from '../embeddings/types.js';
4
+ import type { ContentEncoding } from '@codragraph/graphstore';
4
5
  /** Factory for creating WriteStreams — injectable for testing. */
5
6
  export type WriteStreamFactory = (filePath: string) => import('fs').WriteStream;
6
7
  /** Result of splitting the relationship CSV into per-label-pair files. */
@@ -51,7 +52,9 @@ export declare const initLbug: (dbPath: string) => Promise<{
51
52
  */
52
53
  export declare const withLbugDb: <T>(dbPath: string, operation: () => Promise<T>) => Promise<T>;
53
54
  export type LbugProgressCallback = (message: string) => void;
54
- export declare const loadGraphToLbug: (graph: KnowledgeGraph, repoPath: string, storagePath: string, onProgress?: LbugProgressCallback) => Promise<{
55
+ export declare const loadGraphToLbug: (graph: KnowledgeGraph, repoPath: string, storagePath: string, onProgress?: LbugProgressCallback, options?: {
56
+ compress?: ContentEncoding;
57
+ }) => Promise<{
55
58
  success: boolean;
56
59
  insertedRels: number;
57
60
  skippedRels: number;
@@ -276,7 +276,7 @@ const doInitLbug = async (dbPath) => {
276
276
  const parentDir = path.dirname(dbPath);
277
277
  await fs.mkdir(parentDir, { recursive: true });
278
278
  db = new lbug.Database(dbPath);
279
- conn = new lbug.Connection(db);
279
+ conn = trackConnection(new lbug.Connection(db));
280
280
  for (const schemaQuery of SCHEMA_QUERIES) {
281
281
  try {
282
282
  await conn.query(schemaQuery);
@@ -294,14 +294,14 @@ const doInitLbug = async (dbPath) => {
294
294
  currentDbPath = dbPath;
295
295
  return { db, conn };
296
296
  };
297
- export const loadGraphToLbug = async (graph, repoPath, storagePath, onProgress) => {
297
+ export const loadGraphToLbug = async (graph, repoPath, storagePath, onProgress, options) => {
298
298
  if (!conn) {
299
299
  throw new Error('LadybugDB not initialized. Call initLbug first.');
300
300
  }
301
301
  const log = onProgress || (() => { });
302
302
  const csvDir = path.join(storagePath, 'csv');
303
303
  log('Streaming CSVs to disk...');
304
- const csvResult = await streamAllCSVsToDisk(graph, repoPath, csvDir);
304
+ const csvResult = await streamAllCSVsToDisk(graph, repoPath, csvDir, options?.compress);
305
305
  const validTables = new Set(NODE_TABLES);
306
306
  const getNodeLabel = (nodeId) => {
307
307
  if (nodeId.startsWith('comm_'))
@@ -504,8 +504,12 @@ const TABLES_WITH_EXPORTED = new Set([
504
504
  ]);
505
505
  const getCopyQuery = (table, filePath) => {
506
506
  const t = escapeTableName(table);
507
+ // RFC 0001 Phase 2: every content-bearing table also lists
508
+ // `contentEncoding` immediately after `content` to match the schema +
509
+ // CSV layout. Tables without a content column (Folder, Community,
510
+ // Process, Route, Tool) are unchanged.
507
511
  if (table === 'File') {
508
- return `COPY ${t}(id, name, filePath, content) FROM "${filePath}" ${COPY_CSV_OPTS}`;
512
+ return `COPY ${t}(id, name, filePath, content, contentEncoding) FROM "${filePath}" ${COPY_CSV_OPTS}`;
509
513
  }
510
514
  if (table === 'Folder') {
511
515
  return `COPY ${t}(id, name, filePath) FROM "${filePath}" ${COPY_CSV_OPTS}`;
@@ -517,7 +521,7 @@ const getCopyQuery = (table, filePath) => {
517
521
  return `COPY ${t}(id, label, heuristicLabel, processType, stepCount, communities, entryPointId, terminalId) FROM "${filePath}" ${COPY_CSV_OPTS}`;
518
522
  }
519
523
  if (table === 'Section') {
520
- return `COPY ${t}(id, name, filePath, startLine, endLine, level, content, description) FROM "${filePath}" ${COPY_CSV_OPTS}`;
524
+ return `COPY ${t}(id, name, filePath, startLine, endLine, level, content, contentEncoding, description) FROM "${filePath}" ${COPY_CSV_OPTS}`;
521
525
  }
522
526
  if (table === 'Route') {
523
527
  return `COPY ${t}(id, name, filePath, responseKeys, errorKeys, middleware) FROM "${filePath}" ${COPY_CSV_OPTS}`;
@@ -526,14 +530,14 @@ const getCopyQuery = (table, filePath) => {
526
530
  return `COPY ${t}(id, name, filePath, description) FROM "${filePath}" ${COPY_CSV_OPTS}`;
527
531
  }
528
532
  if (table === 'Method') {
529
- return `COPY ${t}(id, name, filePath, startLine, endLine, isExported, content, description, parameterCount, returnType) FROM "${filePath}" ${COPY_CSV_OPTS}`;
533
+ return `COPY ${t}(id, name, filePath, startLine, endLine, isExported, content, contentEncoding, description, parameterCount, returnType) FROM "${filePath}" ${COPY_CSV_OPTS}`;
530
534
  }
531
535
  // TypeScript/JS code element tables have isExported; multi-language tables do not
532
536
  if (TABLES_WITH_EXPORTED.has(table)) {
533
- return `COPY ${t}(id, name, filePath, startLine, endLine, isExported, content, description) FROM "${filePath}" ${COPY_CSV_OPTS}`;
537
+ return `COPY ${t}(id, name, filePath, startLine, endLine, isExported, content, contentEncoding, description) FROM "${filePath}" ${COPY_CSV_OPTS}`;
534
538
  }
535
539
  // Multi-language tables (Struct, Impl, Trait, Macro, etc.)
536
- return `COPY ${t}(id, name, filePath, startLine, endLine, content, description) FROM "${filePath}" ${COPY_CSV_OPTS}`;
540
+ return `COPY ${t}(id, name, filePath, startLine, endLine, content, contentEncoding, description) FROM "${filePath}" ${COPY_CSV_OPTS}`;
537
541
  };
538
542
  /**
539
543
  * Insert a single node to LadybugDB
@@ -587,9 +591,10 @@ export const insertNodeToLbug = async (label, properties, dbPath) => {
587
591
  // Use per-query connection if dbPath provided (avoids lock conflicts)
588
592
  if (targetDbPath) {
589
593
  const tempDb = new lbug.Database(targetDbPath);
590
- const tempConn = new lbug.Connection(tempDb);
594
+ const tempConn = trackConnection(new lbug.Connection(tempDb));
591
595
  try {
592
- await tempConn.query(query);
596
+ const qr = await tempConn.query(query);
597
+ await closeQueryResult(qr);
593
598
  return true;
594
599
  }
595
600
  finally {
@@ -635,7 +640,7 @@ export const batchInsertNodesToLbug = async (nodes, dbPath) => {
635
640
  };
636
641
  // Open a single connection for all inserts
637
642
  const tempDb = new lbug.Database(dbPath);
638
- const tempConn = new lbug.Connection(tempDb);
643
+ const tempConn = trackConnection(new lbug.Connection(tempDb));
639
644
  let inserted = 0;
640
645
  let failed = 0;
641
646
  try {
@@ -689,6 +694,83 @@ export const batchInsertNodesToLbug = async (nodes, dbPath) => {
689
694
  }
690
695
  return { inserted, failed };
691
696
  };
697
+ /**
698
+ * Track every live QueryResult / PreparedStatement returned by the
699
+ * connection, and force-close them in `closeLbug()` BEFORE `conn.close()`
700
+ * runs.
701
+ *
702
+ * Why this exists: per upstream Kuzu issue #5316 the close-order is
703
+ * QueryResult & PreparedStatement → Connection → Database
704
+ * Leaking any of these to GC means V8 finalizes the native handles AFTER
705
+ * `db.close()` has run, which corrupts memory and segfaults the process
706
+ * at exit (Windows: 0xC0000005, Linux: SIGSEGV). Kuzu was archived
707
+ * 2025-10-10 and LadybugDB inherits the same C++ core, so the
708
+ * close-discipline is on us — neither upstream is going to ship a fix.
709
+ *
710
+ * Per-call-site close (the `try/finally { closeQueryResult }` blocks
711
+ * below) handles the happy path. The tracking Set is a backstop for any
712
+ * call site that forgets, AND for the fire-and-forget DDL / COPY /
713
+ * extension-load queries that drop the QueryResult on the floor.
714
+ */
715
+ const liveLbugHandles = new Set();
716
+ const closeQueryResult = async (qr) => {
717
+ if (!qr)
718
+ return;
719
+ const candidates = Array.isArray(qr) ? qr : [qr];
720
+ for (const r of candidates) {
721
+ liveLbugHandles.delete(r);
722
+ try {
723
+ const close = r?.close;
724
+ if (typeof close === 'function')
725
+ await Promise.resolve(close.call(r));
726
+ }
727
+ catch {
728
+ /* best-effort */
729
+ }
730
+ }
731
+ };
732
+ const closeStmt = async (stmt) => {
733
+ if (!stmt)
734
+ return;
735
+ liveLbugHandles.delete(stmt);
736
+ try {
737
+ const close = stmt?.close;
738
+ if (typeof close === 'function')
739
+ await Promise.resolve(close.call(stmt));
740
+ }
741
+ catch {
742
+ /* best-effort */
743
+ }
744
+ };
745
+ /**
746
+ * Wrap `conn.query` and `conn.execute` to register every returned
747
+ * QueryResult in the live-handle tracker. PreparedStatements from
748
+ * `conn.prepare` are tracked the same way. Idempotent — safe to call
749
+ * twice on the same Connection.
750
+ */
751
+ const trackConnection = (rawConn) => {
752
+ const c = rawConn;
753
+ if (c.__lbugTracked)
754
+ return rawConn;
755
+ c.__lbugTracked = true;
756
+ const wrap = (orig) => async function (...args) {
757
+ const qr = await orig.apply(this, args);
758
+ if (qr && typeof qr === 'object') {
759
+ if (Array.isArray(qr))
760
+ qr.forEach((r) => r && liveLbugHandles.add(r));
761
+ else
762
+ liveLbugHandles.add(qr);
763
+ }
764
+ return qr;
765
+ };
766
+ if (typeof c.query === 'function')
767
+ c.query = wrap(c.query);
768
+ if (typeof c.execute === 'function')
769
+ c.execute = wrap(c.execute);
770
+ if (typeof c.prepare === 'function')
771
+ c.prepare = wrap(c.prepare);
772
+ return rawConn;
773
+ };
692
774
  export const executeQuery = async (cypher) => {
693
775
  if (!conn) {
694
776
  throw new Error('LadybugDB not initialized. Call initLbug first.');
@@ -697,8 +779,12 @@ export const executeQuery = async (cypher) => {
697
779
  // LadybugDB uses getAll() instead of hasNext()/getNext()
698
780
  // Query returns QueryResult for single queries, QueryResult[] for multi-statement
699
781
  const result = Array.isArray(queryResult) ? queryResult[0] : queryResult;
700
- const rows = await result.getAll();
701
- return rows;
782
+ try {
783
+ return await result.getAll();
784
+ }
785
+ finally {
786
+ await closeQueryResult(queryResult);
787
+ }
702
788
  };
703
789
  export const streamQuery = async (cypher, onRow) => {
704
790
  if (!conn) {
@@ -735,11 +821,18 @@ export const executePrepared = async (cypher, params) => {
735
821
  const stmt = await conn.prepare(cypher);
736
822
  if (!stmt.isSuccess()) {
737
823
  const errMsg = await stmt.getErrorMessage();
824
+ await closeStmt(stmt);
738
825
  throw new Error(`Prepare failed: ${errMsg}`);
739
826
  }
740
827
  const queryResult = await conn.execute(stmt, params);
741
828
  const result = Array.isArray(queryResult) ? queryResult[0] : queryResult;
742
- return await result.getAll();
829
+ try {
830
+ return await result.getAll();
831
+ }
832
+ finally {
833
+ await closeQueryResult(queryResult);
834
+ await closeStmt(stmt);
835
+ }
743
836
  };
744
837
  export const executeWithReusedStatement = async (cypher, paramsList) => {
745
838
  if (!conn) {
@@ -753,18 +846,27 @@ export const executeWithReusedStatement = async (cypher, paramsList) => {
753
846
  const stmt = await conn.prepare(cypher);
754
847
  if (!stmt.isSuccess()) {
755
848
  const errMsg = await stmt.getErrorMessage();
849
+ await closeStmt(stmt);
756
850
  throw new Error(`Prepare failed: ${errMsg}`);
757
851
  }
758
852
  try {
759
853
  for (const params of subBatch) {
760
- await conn.execute(stmt, params);
854
+ // `conn.execute` returns a QueryResult — close it as soon as
855
+ // we don't need its rows. Old code dropped the reference to GC,
856
+ // which is what segfaulted the process at exit on Windows
857
+ // (Kuzu issue #5316: QueryResult & PreparedStatement → Connection
858
+ // → Database close-order is required for native-binding safety).
859
+ const qr = await conn.execute(stmt, params);
860
+ await closeQueryResult(qr);
761
861
  }
762
862
  }
763
863
  catch (e) {
764
864
  // Log the error and continue with next batch
765
865
  console.warn('Batch execution error:', e);
766
866
  }
767
- // Note: LadybugDB PreparedStatement doesn't require explicit close()
867
+ finally {
868
+ await closeStmt(stmt);
869
+ }
768
870
  }
769
871
  };
770
872
  export const getLbugStats = async () => {
@@ -772,8 +874,9 @@ export const getLbugStats = async () => {
772
874
  return { nodes: 0, edges: 0 };
773
875
  let totalNodes = 0;
774
876
  for (const tableName of NODE_TABLES) {
877
+ let queryResult;
775
878
  try {
776
- const queryResult = await conn.query(`MATCH (n:${escapeTableName(tableName)}) RETURN count(n) AS cnt`);
879
+ queryResult = await conn.query(`MATCH (n:${escapeTableName(tableName)}) RETURN count(n) AS cnt`);
777
880
  const nodeResult = Array.isArray(queryResult) ? queryResult[0] : queryResult;
778
881
  const nodeRows = await nodeResult.getAll();
779
882
  if (nodeRows.length > 0) {
@@ -783,11 +886,15 @@ export const getLbugStats = async () => {
783
886
  catch {
784
887
  // ignore
785
888
  }
889
+ finally {
890
+ await closeQueryResult(queryResult);
891
+ }
786
892
  }
787
893
  let totalEdges = 0;
894
+ let edgeQueryResult;
788
895
  try {
789
- const queryResult = await conn.query(`MATCH ()-[r:${REL_TABLE_NAME}]->() RETURN count(r) AS cnt`);
790
- const edgeResult = Array.isArray(queryResult) ? queryResult[0] : queryResult;
896
+ edgeQueryResult = await conn.query(`MATCH ()-[r:${REL_TABLE_NAME}]->() RETURN count(r) AS cnt`);
897
+ const edgeResult = Array.isArray(edgeQueryResult) ? edgeQueryResult[0] : edgeQueryResult;
791
898
  const edgeRows = await edgeResult.getAll();
792
899
  if (edgeRows.length > 0) {
793
900
  totalEdges = Number(edgeRows[0]?.cnt ?? edgeRows[0]?.[0] ?? 0);
@@ -796,6 +903,9 @@ export const getLbugStats = async () => {
796
903
  catch {
797
904
  // ignore
798
905
  }
906
+ finally {
907
+ await closeQueryResult(edgeQueryResult);
908
+ }
799
909
  return { nodes: totalNodes, edges: totalEdges };
800
910
  };
801
911
  /**
@@ -929,6 +1039,24 @@ export const fetchExistingEmbeddingHashes = async (execQuery) => {
929
1039
  }
930
1040
  };
931
1041
  export const closeLbug = async () => {
1042
+ // Drain every live QueryResult / PreparedStatement BEFORE closing the
1043
+ // Connection or the Database. Required by upstream Kuzu (#5316) — the
1044
+ // close-order is `QueryResult/PreparedStatement → Connection → Database`,
1045
+ // and any outstanding handle held when `db.close()` runs corrupts memory
1046
+ // and crashes the process at exit (Windows: 0xC0000005, POSIX: SIGSEGV).
1047
+ // Snapshot the Set so concurrent close() calls don't deadlock the iteration.
1048
+ const handles = Array.from(liveLbugHandles);
1049
+ liveLbugHandles.clear();
1050
+ for (const h of handles) {
1051
+ try {
1052
+ const close = h?.close;
1053
+ if (typeof close === 'function')
1054
+ await Promise.resolve(close.call(h));
1055
+ }
1056
+ catch {
1057
+ /* best-effort */
1058
+ }
1059
+ }
932
1060
  if (conn) {
933
1061
  try {
934
1062
  await conn.close();
@@ -963,7 +1091,7 @@ export const deleteNodesForFile = async (filePath, dbPath) => {
963
1091
  let targetConn = conn;
964
1092
  if (usePerQuery) {
965
1093
  tempDb = new lbug.Database(dbPath);
966
- tempConn = new lbug.Connection(tempDb);
1094
+ tempConn = trackConnection(new lbug.Connection(tempDb));
967
1095
  targetConn = tempConn;
968
1096
  }
969
1097
  else if (!conn) {
@@ -1148,8 +1276,9 @@ export const queryFTS = async (tableName, indexName, query, limit = 20, conjunct
1148
1276
  ORDER BY score DESC
1149
1277
  LIMIT ${limit}
1150
1278
  `;
1279
+ let queryResult;
1151
1280
  try {
1152
- const queryResult = await conn.query(cypher);
1281
+ queryResult = await conn.query(cypher);
1153
1282
  const result = Array.isArray(queryResult) ? queryResult[0] : queryResult;
1154
1283
  const rows = await result.getAll();
1155
1284
  return rows.map((row) => {
@@ -1171,6 +1300,9 @@ export const queryFTS = async (tableName, indexName, query, limit = 20, conjunct
1171
1300
  }
1172
1301
  throw e;
1173
1302
  }
1303
+ finally {
1304
+ await closeQueryResult(queryResult);
1305
+ }
1174
1306
  };
1175
1307
  /**
1176
1308
  * Drop an FTS index
@@ -11,13 +11,13 @@
11
11
  import { NODE_TABLES, REL_TABLE_NAME, REL_TYPES, EMBEDDING_TABLE_NAME } from '../../_shared/index.js';
12
12
  export { NODE_TABLES, REL_TABLE_NAME, REL_TYPES, EMBEDDING_TABLE_NAME };
13
13
  export type { NodeTableName, RelType } from '../../_shared/index.js';
14
- export declare const FILE_SCHEMA = "\nCREATE NODE TABLE File (\n id STRING,\n name STRING,\n filePath STRING,\n content STRING,\n PRIMARY KEY (id)\n)";
14
+ export declare const FILE_SCHEMA = "\nCREATE NODE TABLE File (\n id STRING,\n name STRING,\n filePath STRING,\n content STRING,\n contentEncoding STRING DEFAULT 'none',\n PRIMARY KEY (id)\n)";
15
15
  export declare const FOLDER_SCHEMA = "\nCREATE NODE TABLE Folder (\n id STRING,\n name STRING,\n filePath STRING,\n PRIMARY KEY (id)\n)";
16
- export declare const FUNCTION_SCHEMA = "\nCREATE NODE TABLE Function (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n description STRING,\n PRIMARY KEY (id)\n)";
17
- export declare const CLASS_SCHEMA = "\nCREATE NODE TABLE Class (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n description STRING,\n PRIMARY KEY (id)\n)";
18
- export declare const INTERFACE_SCHEMA = "\nCREATE NODE TABLE Interface (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n description STRING,\n PRIMARY KEY (id)\n)";
19
- export declare const METHOD_SCHEMA = "\nCREATE NODE TABLE Method (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n description STRING,\n parameterCount INT32,\n returnType STRING,\n PRIMARY KEY (id)\n)";
20
- export declare const CODE_ELEMENT_SCHEMA = "\nCREATE NODE TABLE CodeElement (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n description STRING,\n PRIMARY KEY (id)\n)";
16
+ export declare const FUNCTION_SCHEMA = "\nCREATE NODE TABLE Function (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n contentEncoding STRING DEFAULT 'none',\n description STRING,\n PRIMARY KEY (id)\n)";
17
+ export declare const CLASS_SCHEMA = "\nCREATE NODE TABLE Class (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n contentEncoding STRING DEFAULT 'none',\n description STRING,\n PRIMARY KEY (id)\n)";
18
+ export declare const INTERFACE_SCHEMA = "\nCREATE NODE TABLE Interface (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n contentEncoding STRING DEFAULT 'none',\n description STRING,\n PRIMARY KEY (id)\n)";
19
+ export declare const METHOD_SCHEMA = "\nCREATE NODE TABLE Method (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n contentEncoding STRING DEFAULT 'none',\n description STRING,\n parameterCount INT32,\n returnType STRING,\n PRIMARY KEY (id)\n)";
20
+ export declare const CODE_ELEMENT_SCHEMA = "\nCREATE NODE TABLE CodeElement (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n isExported BOOLEAN,\n content STRING,\n contentEncoding STRING DEFAULT 'none',\n description STRING,\n PRIMARY KEY (id)\n)";
21
21
  export declare const COMMUNITY_SCHEMA = "\nCREATE NODE TABLE Community (\n id STRING,\n label STRING,\n heuristicLabel STRING,\n keywords STRING[],\n description STRING,\n enrichedBy STRING,\n cohesion DOUBLE,\n symbolCount INT32,\n PRIMARY KEY (id)\n)";
22
22
  export declare const PROCESS_SCHEMA = "\nCREATE NODE TABLE Process (\n id STRING,\n label STRING,\n heuristicLabel STRING,\n processType STRING,\n stepCount INT32,\n communities STRING[],\n entryPointId STRING,\n terminalId STRING,\n PRIMARY KEY (id)\n)";
23
23
  export declare const STRUCT_SCHEMA: string;
@@ -41,7 +41,7 @@ export declare const TEMPLATE_SCHEMA: string;
41
41
  export declare const MODULE_SCHEMA: string;
42
42
  export declare const ROUTE_SCHEMA = "\nCREATE NODE TABLE Route (\n id STRING,\n name STRING,\n filePath STRING,\n responseKeys STRING[],\n errorKeys STRING[],\n middleware STRING[],\n PRIMARY KEY (id)\n)";
43
43
  export declare const TOOL_SCHEMA = "\nCREATE NODE TABLE Tool (\n id STRING,\n name STRING,\n filePath STRING,\n description STRING,\n PRIMARY KEY (id)\n)";
44
- export declare const SECTION_SCHEMA = "\nCREATE NODE TABLE Section (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n level INT64,\n content STRING,\n description STRING,\n PRIMARY KEY (id)\n)";
44
+ export declare const SECTION_SCHEMA = "\nCREATE NODE TABLE Section (\n id STRING,\n name STRING,\n filePath STRING,\n startLine INT64,\n endLine INT64,\n level INT64,\n content STRING,\n contentEncoding STRING DEFAULT 'none',\n description STRING,\n PRIMARY KEY (id)\n)";
45
45
  export declare const RELATION_SCHEMA = "\nCREATE REL TABLE CodeRelation (\n FROM File TO File,\n FROM File TO Folder,\n FROM File TO Function,\n FROM File TO Class,\n FROM File TO Interface,\n FROM File TO Method,\n FROM File TO CodeElement,\n FROM File TO `Struct`,\n FROM File TO `Enum`,\n FROM File TO `Macro`,\n FROM File TO `Typedef`,\n FROM File TO `Union`,\n FROM File TO `Namespace`,\n FROM File TO `Trait`,\n FROM File TO `Impl`,\n FROM File TO `TypeAlias`,\n FROM File TO `Const`,\n FROM File TO `Static`,\n FROM File TO `Variable`,\n FROM File TO `Property`,\n FROM File TO `Record`,\n FROM File TO `Delegate`,\n FROM File TO `Annotation`,\n FROM File TO `Constructor`,\n FROM File TO `Template`,\n FROM File TO `Module`,\n FROM File TO Section,\n FROM Folder TO Folder,\n FROM Folder TO File,\n FROM Function TO Function,\n FROM Function TO Method,\n FROM Function TO Class,\n FROM Function TO Community,\n FROM Function TO `Macro`,\n FROM Function TO `Struct`,\n FROM Function TO `Template`,\n FROM Function TO `Enum`,\n FROM Function TO `Namespace`,\n FROM Function TO `TypeAlias`,\n FROM Function TO `Module`,\n FROM Function TO `Impl`,\n FROM Function TO Interface,\n FROM Function TO `Constructor`,\n FROM Function TO `Const`,\n FROM Function TO `Typedef`,\n FROM Function TO `Union`,\n FROM Function TO `Property`,\n FROM Function TO CodeElement,\n FROM Class TO Method,\n FROM Class TO Function,\n FROM Class TO Class,\n FROM Class TO Interface,\n FROM Class TO Community,\n FROM Class TO `Template`,\n FROM Class TO `TypeAlias`,\n FROM Class TO `Struct`,\n FROM Class TO `Enum`,\n FROM Class TO `Annotation`,\n FROM Class TO `Constructor`,\n FROM Class TO `Trait`,\n FROM Class TO `Macro`,\n FROM Class TO `Impl`,\n FROM Class TO `Union`,\n FROM Class TO `Namespace`,\n FROM Class TO `Typedef`,\n FROM Class TO `Property`,\n FROM Method TO Function,\n FROM Method TO Method,\n FROM Method TO Class,\n FROM Method TO Community,\n FROM Method TO `Template`,\n FROM Method TO `Struct`,\n FROM Method TO `TypeAlias`,\n FROM Method TO `Enum`,\n FROM Method TO `Macro`,\n FROM Method TO `Namespace`,\n FROM Method TO `Module`,\n FROM Method TO `Impl`,\n FROM Method TO Interface,\n FROM Method TO `Constructor`,\n FROM Method TO `Property`,\n FROM Method TO CodeElement,\n FROM `Template` TO `Template`,\n FROM `Template` TO Function,\n FROM `Template` TO Method,\n FROM `Template` TO Class,\n FROM `Template` TO `Struct`,\n FROM `Template` TO `TypeAlias`,\n FROM `Template` TO `Enum`,\n FROM `Template` TO `Macro`,\n FROM `Template` TO Interface,\n FROM `Template` TO `Constructor`,\n FROM `Module` TO `Module`,\n FROM Section TO Section,\n FROM Section TO File,\n FROM File TO Route,\n FROM Function TO Route,\n FROM Method TO Route,\n FROM File TO Tool,\n FROM Function TO Tool,\n FROM Method TO Tool,\n FROM CodeElement TO Community,\n FROM Interface TO Community,\n FROM Interface TO Function,\n FROM Interface TO Method,\n FROM Interface TO Class,\n FROM Interface TO Interface,\n FROM Interface TO `TypeAlias`,\n FROM Interface TO `Struct`,\n FROM Interface TO `Constructor`,\n FROM Interface TO `Property`,\n FROM `Struct` TO Community,\n FROM `Struct` TO `Trait`,\n FROM `Struct` TO `Struct`,\n FROM `Struct` TO Class,\n FROM `Struct` TO `Enum`,\n FROM `Struct` TO Function,\n FROM `Struct` TO Method,\n FROM `Struct` TO Interface,\n FROM `Struct` TO `Constructor`,\n FROM `Struct` TO `Property`,\n FROM `Enum` TO `Enum`,\n FROM `Enum` TO Community,\n FROM `Enum` TO Class,\n FROM `Enum` TO Interface,\n FROM `Macro` TO Community,\n FROM `Macro` TO Function,\n FROM `Macro` TO Method,\n FROM `Module` TO Function,\n FROM `Module` TO Method,\n FROM `Typedef` TO Community,\n FROM `Union` TO Community,\n FROM `Namespace` TO Community,\n FROM `Namespace` TO `Struct`,\n FROM `Trait` TO Method,\n FROM `Trait` TO `Constructor`,\n FROM `Trait` TO `Property`,\n FROM `Trait` TO Community,\n FROM `Impl` TO Method,\n FROM `Impl` TO `Constructor`,\n FROM `Impl` TO `Property`,\n FROM `Impl` TO Community,\n FROM `Impl` TO `Trait`,\n FROM `Impl` TO `Struct`,\n FROM `Impl` TO `Impl`,\n FROM `TypeAlias` TO Community,\n FROM `TypeAlias` TO `Trait`,\n FROM `TypeAlias` TO Class,\n FROM `Const` TO Community,\n FROM `Static` TO Community,\n FROM `Variable` TO Community,\n FROM `Property` TO Community,\n FROM `Record` TO Method,\n FROM `Record` TO `Constructor`,\n FROM `Record` TO `Property`,\n FROM `Record` TO Community,\n FROM `Delegate` TO Community,\n FROM `Annotation` TO Community,\n FROM `Constructor` TO Community,\n FROM `Constructor` TO Interface,\n FROM `Constructor` TO Class,\n FROM `Constructor` TO Method,\n FROM `Constructor` TO Function,\n FROM `Constructor` TO `Constructor`,\n FROM `Constructor` TO `Struct`,\n FROM `Constructor` TO `Macro`,\n FROM `Constructor` TO `Template`,\n FROM `Constructor` TO `TypeAlias`,\n FROM `Constructor` TO `Enum`,\n FROM `Constructor` TO `Annotation`,\n FROM `Constructor` TO `Impl`,\n FROM `Constructor` TO `Namespace`,\n FROM `Constructor` TO `Module`,\n FROM `Constructor` TO `Property`,\n FROM `Constructor` TO `Typedef`,\n FROM `Template` TO Community,\n FROM `Module` TO Community,\n FROM Function TO Process,\n FROM Method TO Process,\n FROM Class TO Process,\n FROM Interface TO Process,\n FROM `Struct` TO Process,\n FROM `Constructor` TO Process,\n FROM `Module` TO Process,\n FROM `Macro` TO Process,\n FROM `Impl` TO Process,\n FROM `Typedef` TO Process,\n FROM `TypeAlias` TO Process,\n FROM `Enum` TO Process,\n FROM `Union` TO Process,\n FROM `Namespace` TO Process,\n FROM `Trait` TO Process,\n FROM `Const` TO Process,\n FROM `Static` TO Process,\n FROM `Variable` TO Process,\n FROM `Property` TO Process,\n FROM `Record` TO Process,\n FROM `Delegate` TO Process,\n FROM `Annotation` TO Process,\n FROM `Template` TO Process,\n FROM CodeElement TO Process,\n FROM Route TO Process,\n FROM Tool TO Process,\n type STRING,\n confidence DOUBLE,\n reason STRING,\n step INT32\n)";
46
46
  export declare const EMBEDDING_DIMS: number;
47
47
  /** HNSW vector index name for the CodeEmbedding table. */
@@ -15,12 +15,23 @@ export { NODE_TABLES, REL_TABLE_NAME, REL_TYPES, EMBEDDING_TABLE_NAME };
15
15
  // ============================================================================
16
16
  // NODE TABLE SCHEMAS
17
17
  // ============================================================================
18
+ // RFC 0001 Phase 2 — every node table that has `content STRING` also carries
19
+ // `contentEncoding STRING DEFAULT 'none'`. Default keeps existing
20
+ // uncompressed reads working (an empty/missing tag means "no decode
21
+ // needed"); writers opt into compression by setting it to 'brotli' or
22
+ // 'zstd' alongside the encoded bytes.
23
+ //
24
+ // Adding the column to every relevant table at once keeps the read path
25
+ // simple — every `RETURN n.content` site can also `RETURN n.contentEncoding`
26
+ // without per-table feature detection. Tables WITHOUT a content column
27
+ // (Folder, Community, Process, Route, Tool) are intentionally not touched.
18
28
  export const FILE_SCHEMA = `
19
29
  CREATE NODE TABLE File (
20
30
  id STRING,
21
31
  name STRING,
22
32
  filePath STRING,
23
33
  content STRING,
34
+ contentEncoding STRING DEFAULT 'none',
24
35
  PRIMARY KEY (id)
25
36
  )`;
26
37
  export const FOLDER_SCHEMA = `
@@ -39,6 +50,7 @@ CREATE NODE TABLE Function (
39
50
  endLine INT64,
40
51
  isExported BOOLEAN,
41
52
  content STRING,
53
+ contentEncoding STRING DEFAULT 'none',
42
54
  description STRING,
43
55
  PRIMARY KEY (id)
44
56
  )`;
@@ -51,6 +63,7 @@ CREATE NODE TABLE Class (
51
63
  endLine INT64,
52
64
  isExported BOOLEAN,
53
65
  content STRING,
66
+ contentEncoding STRING DEFAULT 'none',
54
67
  description STRING,
55
68
  PRIMARY KEY (id)
56
69
  )`;
@@ -63,6 +76,7 @@ CREATE NODE TABLE Interface (
63
76
  endLine INT64,
64
77
  isExported BOOLEAN,
65
78
  content STRING,
79
+ contentEncoding STRING DEFAULT 'none',
66
80
  description STRING,
67
81
  PRIMARY KEY (id)
68
82
  )`;
@@ -75,6 +89,7 @@ CREATE NODE TABLE Method (
75
89
  endLine INT64,
76
90
  isExported BOOLEAN,
77
91
  content STRING,
92
+ contentEncoding STRING DEFAULT 'none',
78
93
  description STRING,
79
94
  parameterCount INT32,
80
95
  returnType STRING,
@@ -89,6 +104,7 @@ CREATE NODE TABLE CodeElement (
89
104
  endLine INT64,
90
105
  isExported BOOLEAN,
91
106
  content STRING,
107
+ contentEncoding STRING DEFAULT 'none',
92
108
  description STRING,
93
109
  PRIMARY KEY (id)
94
110
  )`;
@@ -135,6 +151,7 @@ CREATE NODE TABLE \`${name}\` (
135
151
  startLine INT64,
136
152
  endLine INT64,
137
153
  content STRING,
154
+ contentEncoding STRING DEFAULT 'none',
138
155
  description STRING,
139
156
  PRIMARY KEY (id)
140
157
  )`;
@@ -187,6 +204,7 @@ CREATE NODE TABLE Section (
187
204
  endLine INT64,
188
205
  level INT64,
189
206
  content STRING,
207
+ contentEncoding STRING DEFAULT 'none',
190
208
  description STRING,
191
209
  PRIMARY KEY (id)
192
210
  )`;