@veewo/gitnexus 1.3.8 → 1.3.10

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 (133) hide show
  1. package/README.md +5 -0
  2. package/dist/benchmark/runner.test.js +1 -1
  3. package/dist/benchmark/u2-e2e/analyze-parser.d.ts +22 -0
  4. package/dist/benchmark/u2-e2e/analyze-parser.js +89 -0
  5. package/dist/benchmark/u2-e2e/analyze-parser.test.js +13 -0
  6. package/dist/benchmark/u2-e2e/characterlist-assetref.d.ts +19 -0
  7. package/dist/benchmark/u2-e2e/characterlist-assetref.js +80 -0
  8. package/dist/benchmark/u2-e2e/characterlist-assetref.test.js +108 -0
  9. package/dist/benchmark/u2-e2e/config.d.ts +25 -0
  10. package/dist/benchmark/u2-e2e/config.js +86 -0
  11. package/dist/benchmark/u2-e2e/config.test.js +29 -0
  12. package/dist/benchmark/u2-e2e/metrics.d.ts +20 -0
  13. package/dist/benchmark/u2-e2e/metrics.js +34 -0
  14. package/dist/benchmark/u2-e2e/metrics.test.js +13 -0
  15. package/dist/benchmark/u2-e2e/neonspark-full-e2e.d.ts +33 -0
  16. package/dist/benchmark/u2-e2e/neonspark-full-e2e.js +439 -0
  17. package/dist/benchmark/u2-e2e/neonspark-full-e2e.test.js +40 -0
  18. package/dist/benchmark/u2-e2e/report.d.ts +58 -0
  19. package/dist/benchmark/u2-e2e/report.js +130 -0
  20. package/dist/benchmark/u2-e2e/report.test.js +58 -0
  21. package/dist/benchmark/u2-e2e/retrieval-runner.d.ts +21 -0
  22. package/dist/benchmark/u2-e2e/retrieval-runner.js +166 -0
  23. package/dist/benchmark/u2-e2e/retrieval-runner.test.d.ts +1 -0
  24. package/dist/benchmark/u2-e2e/retrieval-runner.test.js +145 -0
  25. package/dist/benchmark/u2-performance-sampler.d.ts +33 -0
  26. package/dist/benchmark/u2-performance-sampler.js +178 -0
  27. package/dist/benchmark/u2-performance-sampler.test.d.ts +1 -0
  28. package/dist/benchmark/u2-performance-sampler.test.js +34 -0
  29. package/dist/cli/ai-context.js +1 -1
  30. package/dist/cli/analyze-multi-scope-regression.test.js +10 -0
  31. package/dist/cli/analyze-options.d.ts +19 -0
  32. package/dist/cli/analyze-options.js +35 -0
  33. package/dist/cli/analyze-options.test.js +42 -1
  34. package/dist/cli/analyze-summary.d.ts +7 -0
  35. package/dist/cli/analyze-summary.js +37 -0
  36. package/dist/cli/analyze-summary.test.d.ts +1 -0
  37. package/dist/cli/analyze-summary.test.js +58 -0
  38. package/dist/cli/analyze.d.ts +1 -0
  39. package/dist/cli/analyze.js +64 -32
  40. package/dist/cli/benchmark-u2-e2e.d.ts +9 -0
  41. package/dist/cli/benchmark-u2-e2e.js +35 -0
  42. package/dist/cli/benchmark-u2-e2e.test.d.ts +1 -0
  43. package/dist/cli/benchmark-u2-e2e.test.js +7 -0
  44. package/dist/cli/index.js +21 -0
  45. package/dist/cli/repo-manager-alias.test.js +24 -1
  46. package/dist/cli/tool.d.ts +3 -0
  47. package/dist/cli/tool.js +2 -0
  48. package/dist/cli/unity-bindings.d.ts +8 -0
  49. package/dist/cli/unity-bindings.js +33 -0
  50. package/dist/cli/unity-bindings.test.d.ts +1 -0
  51. package/dist/cli/unity-bindings.test.js +24 -0
  52. package/dist/core/graph/types.d.ts +1 -1
  53. package/dist/core/ingestion/pipeline.d.ts +2 -4
  54. package/dist/core/ingestion/pipeline.js +12 -0
  55. package/dist/core/ingestion/unity-resource-processor.d.ts +26 -0
  56. package/dist/core/ingestion/unity-resource-processor.js +363 -0
  57. package/dist/core/ingestion/unity-resource-processor.test.d.ts +1 -0
  58. package/dist/core/ingestion/unity-resource-processor.test.js +599 -0
  59. package/dist/core/kuzu/kuzu-adapter.d.ts +6 -0
  60. package/dist/core/kuzu/kuzu-adapter.js +18 -7
  61. package/dist/core/kuzu/schema.d.ts +2 -2
  62. package/dist/core/kuzu/schema.js +22 -1
  63. package/dist/core/kuzu/schema.test.d.ts +1 -0
  64. package/dist/core/kuzu/schema.test.js +17 -0
  65. package/dist/core/unity/meta-index.d.ts +5 -0
  66. package/dist/core/unity/meta-index.js +113 -0
  67. package/dist/core/unity/meta-index.test.d.ts +1 -0
  68. package/dist/core/unity/meta-index.test.js +11 -0
  69. package/dist/core/unity/options.d.ts +2 -0
  70. package/dist/core/unity/options.js +9 -0
  71. package/dist/core/unity/options.test.d.ts +1 -0
  72. package/dist/core/unity/options.test.js +10 -0
  73. package/dist/core/unity/override-merger.d.ts +27 -0
  74. package/dist/core/unity/override-merger.js +35 -0
  75. package/dist/core/unity/override-merger.test.d.ts +1 -0
  76. package/dist/core/unity/override-merger.test.js +47 -0
  77. package/dist/core/unity/resolver.d.ts +79 -0
  78. package/dist/core/unity/resolver.js +384 -0
  79. package/dist/core/unity/resolver.test.d.ts +1 -0
  80. package/dist/core/unity/resolver.test.js +244 -0
  81. package/dist/core/unity/resource-hit-scanner.d.ts +10 -0
  82. package/dist/core/unity/resource-hit-scanner.js +60 -0
  83. package/dist/core/unity/resource-hit-scanner.test.d.ts +1 -0
  84. package/dist/core/unity/resource-hit-scanner.test.js +20 -0
  85. package/dist/core/unity/scan-context.d.ts +23 -0
  86. package/dist/core/unity/scan-context.js +318 -0
  87. package/dist/core/unity/scan-context.test.d.ts +1 -0
  88. package/dist/core/unity/scan-context.test.js +118 -0
  89. package/dist/core/unity/serialized-type-index.d.ts +10 -0
  90. package/dist/core/unity/serialized-type-index.js +105 -0
  91. package/dist/core/unity/serialized-type-index.test.d.ts +1 -0
  92. package/dist/core/unity/serialized-type-index.test.js +34 -0
  93. package/dist/core/unity/u2-thresholds.test.d.ts +1 -0
  94. package/dist/core/unity/u2-thresholds.test.js +71 -0
  95. package/dist/core/unity/yaml-object-graph.d.ts +9 -0
  96. package/dist/core/unity/yaml-object-graph.js +92 -0
  97. package/dist/core/unity/yaml-object-graph.test.d.ts +1 -0
  98. package/dist/core/unity/yaml-object-graph.test.js +49 -0
  99. package/dist/mcp/local/local-backend.js +12 -1
  100. package/dist/mcp/local/unity-enrichment.d.ts +6 -0
  101. package/dist/mcp/local/unity-enrichment.js +91 -0
  102. package/dist/mcp/local/unity-enrichment.test.d.ts +1 -0
  103. package/dist/mcp/local/unity-enrichment.test.js +130 -0
  104. package/dist/mcp/resources.js +1 -1
  105. package/dist/mcp/staleness.js +1 -1
  106. package/dist/mcp/tools.js +12 -0
  107. package/dist/storage/repo-manager.d.ts +6 -0
  108. package/dist/types/pipeline.d.ts +7 -0
  109. package/dist/types/pipeline.js +2 -0
  110. package/hooks/check-release-path-hygiene.mjs +108 -0
  111. package/package.json +16 -9
  112. package/dist/cli/analyze-custom-modules-regression.test.js +0 -75
  113. package/dist/cli/analyze-modules-diagnostics.test.js +0 -36
  114. package/dist/core/ingestion/modules/assignment-engine.d.ts +0 -33
  115. package/dist/core/ingestion/modules/assignment-engine.js +0 -179
  116. package/dist/core/ingestion/modules/assignment-engine.test.js +0 -111
  117. package/dist/core/ingestion/modules/config-loader.d.ts +0 -2
  118. package/dist/core/ingestion/modules/config-loader.js +0 -186
  119. package/dist/core/ingestion/modules/config-loader.test.js +0 -57
  120. package/dist/core/ingestion/modules/rule-matcher.d.ts +0 -12
  121. package/dist/core/ingestion/modules/rule-matcher.js +0 -63
  122. package/dist/core/ingestion/modules/rule-matcher.test.js +0 -58
  123. package/dist/core/ingestion/modules/types.d.ts +0 -44
  124. package/dist/core/ingestion/modules/types.js +0 -2
  125. package/dist/mcp/local/cluster-aggregation.d.ts +0 -20
  126. package/dist/mcp/local/cluster-aggregation.js +0 -48
  127. package/dist/mcp/local/cluster-aggregation.test.js +0 -22
  128. /package/dist/{cli/analyze-custom-modules-regression.test.d.ts → benchmark/u2-e2e/analyze-parser.test.d.ts} +0 -0
  129. /package/dist/{cli/analyze-modules-diagnostics.test.d.ts → benchmark/u2-e2e/characterlist-assetref.test.d.ts} +0 -0
  130. /package/dist/{core/ingestion/modules/assignment-engine.test.d.ts → benchmark/u2-e2e/config.test.d.ts} +0 -0
  131. /package/dist/{core/ingestion/modules/config-loader.test.d.ts → benchmark/u2-e2e/metrics.test.d.ts} +0 -0
  132. /package/dist/{core/ingestion/modules/rule-matcher.test.d.ts → benchmark/u2-e2e/neonspark-full-e2e.test.d.ts} +0 -0
  133. /package/dist/{mcp/local/cluster-aggregation.test.d.ts → benchmark/u2-e2e/report.test.d.ts} +0 -0
@@ -187,6 +187,7 @@ export const loadGraphToKuzu = async (graph, repoPath, storagePath, onProgress)
187
187
  });
188
188
  const insertedRels = totalValidRels;
189
189
  const warnings = [];
190
+ let fallbackStats = { attempted: 0, succeeded: 0, failed: 0 };
190
191
  if (insertedRels > 0) {
191
192
  log(`Loading edges: ${insertedRels.toLocaleString()} across ${relsByPair.size} types`);
192
193
  let pairIdx = 0;
@@ -224,7 +225,7 @@ export const loadGraphToKuzu = async (graph, repoPath, storagePath, onProgress)
224
225
  }
225
226
  if (failedPairLines.length > 0) {
226
227
  log(`Inserting ${failedPairEdges} edges individually (missing schema pairs)`);
227
- await fallbackRelationshipInserts([relHeader, ...failedPairLines], validTables, getNodeLabel);
228
+ fallbackStats = await fallbackRelationshipInserts([relHeader, ...failedPairLines], validTables, getNodeLabel);
228
229
  }
229
230
  }
230
231
  // Cleanup all CSVs
@@ -252,7 +253,7 @@ export const loadGraphToKuzu = async (graph, repoPath, storagePath, onProgress)
252
253
  await fs.rmdir(csvDir);
253
254
  }
254
255
  catch { }
255
- return { success: true, insertedRels, skippedRels, warnings };
256
+ return { success: true, insertedRels, skippedRels, warnings, fallbackStats };
256
257
  };
257
258
  // KuzuDB default ESCAPE is '\' (backslash), but our CSV uses RFC 4180 escaping ("" for literal quotes).
258
259
  // Source code content is full of backslashes which confuse the auto-detection.
@@ -271,22 +272,30 @@ const escapeTableName = (table) => {
271
272
  };
272
273
  /** Fallback: insert relationships one-by-one if COPY fails */
273
274
  const fallbackRelationshipInserts = async (validRelLines, validTables, getNodeLabel) => {
274
- if (!conn)
275
- return;
275
+ const attempted = Math.max(0, validRelLines.length - 1);
276
+ if (!conn) {
277
+ return { attempted, succeeded: 0, failed: attempted };
278
+ }
276
279
  const escapeLabel = (label) => {
277
280
  return BACKTICK_TABLES.has(label) ? `\`${label}\`` : label;
278
281
  };
282
+ let succeeded = 0;
283
+ let failed = 0;
279
284
  for (let i = 1; i < validRelLines.length; i++) {
280
285
  const line = validRelLines[i];
281
286
  try {
282
287
  const match = line.match(/"([^"]*)","([^"]*)","([^"]*)",([0-9.]+),"([^"]*)",([0-9-]+)/);
283
- if (!match)
288
+ if (!match) {
289
+ failed++;
284
290
  continue;
291
+ }
285
292
  const [, fromId, toId, relType, confidenceStr, reason, stepStr] = match;
286
293
  const fromLabel = getNodeLabel(fromId);
287
294
  const toLabel = getNodeLabel(toId);
288
- if (!validTables.has(fromLabel) || !validTables.has(toLabel))
295
+ if (!validTables.has(fromLabel) || !validTables.has(toLabel)) {
296
+ failed++;
289
297
  continue;
298
+ }
290
299
  const confidence = parseFloat(confidenceStr) || 1.0;
291
300
  const step = parseInt(stepStr) || 0;
292
301
  await conn.query(`
@@ -294,11 +303,13 @@ const fallbackRelationshipInserts = async (validRelLines, validTables, getNodeLa
294
303
  (b:${escapeLabel(toLabel)} {id: '${toId.replace(/'/g, "''")}' })
295
304
  CREATE (a)-[:${REL_TABLE_NAME} {type: '${relType}', confidence: ${confidence}, reason: '${reason.replace(/'/g, "''")}', step: ${step}}]->(b)
296
305
  `);
306
+ succeeded++;
297
307
  }
298
308
  catch {
299
- // skip
309
+ failed++;
300
310
  }
301
311
  }
312
+ return { attempted, succeeded, failed };
302
313
  };
303
314
  /** Tables with isExported column (TypeScript/JS-native types) */
304
315
  const TABLES_WITH_EXPORTED = new Set(['Function', 'Class', 'Interface', 'Method', 'CodeElement']);
@@ -11,7 +11,7 @@
11
11
  export declare const NODE_TABLES: readonly ["File", "Folder", "Function", "Class", "Interface", "Method", "CodeElement", "Community", "Process", "Struct", "Enum", "Macro", "Typedef", "Union", "Namespace", "Trait", "Impl", "TypeAlias", "Const", "Static", "Property", "Record", "Delegate", "Annotation", "Constructor", "Template", "Module"];
12
12
  export type NodeTableName = typeof NODE_TABLES[number];
13
13
  export declare const REL_TABLE_NAME = "CodeRelation";
14
- export declare const REL_TYPES: readonly ["CONTAINS", "DEFINES", "IMPORTS", "CALLS", "EXTENDS", "IMPLEMENTS", "MEMBER_OF", "STEP_IN_PROCESS"];
14
+ export declare const REL_TYPES: readonly ["CONTAINS", "DEFINES", "IMPORTS", "CALLS", "EXTENDS", "IMPLEMENTS", "MEMBER_OF", "STEP_IN_PROCESS", "UNITY_COMPONENT_IN", "UNITY_COMPONENT_INSTANCE", "UNITY_SERIALIZED_TYPE_IN"];
15
15
  export type RelType = typeof REL_TYPES[number];
16
16
  export declare const EMBEDDING_TABLE_NAME = "CodeEmbedding";
17
17
  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)";
@@ -41,7 +41,7 @@ export declare const ANNOTATION_SCHEMA: string;
41
41
  export declare const CONSTRUCTOR_SCHEMA: string;
42
42
  export declare const TEMPLATE_SCHEMA: string;
43
43
  export declare const MODULE_SCHEMA: string;
44
- 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 `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 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 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 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 `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 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 `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 `Enum` TO Community,\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 Community,\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 `Const` TO Community,\n FROM `Static` TO Community,\n FROM `Property` TO Community,\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 `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 `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 type STRING,\n confidence DOUBLE,\n reason STRING,\n step INT32\n)";
44
+ 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 `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 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 `Property`,\n FROM Function TO `Const`,\n FROM Function TO `Typedef`,\n FROM Function TO `Union`,\n FROM Class TO Method,\n FROM Class TO Function,\n FROM Class TO Class,\n FROM Class TO File,\n FROM Class TO CodeElement,\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 Class TO `Delegate`,\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 `Delegate`,\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 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 `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 `Enum` TO Community,\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 Community,\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 `Const` TO Community,\n FROM `Static` TO Community,\n FROM `Property` TO Community,\n FROM `Property` TO Class,\n FROM `Property` TO Interface,\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 `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 `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 type STRING,\n confidence DOUBLE,\n reason STRING,\n step INT32\n)";
45
45
  export declare const EMBEDDING_SCHEMA = "\nCREATE NODE TABLE CodeEmbedding (\n nodeId STRING,\n embedding FLOAT[384],\n PRIMARY KEY (nodeId)\n)";
46
46
  /**
47
47
  * Create vector index for semantic search
@@ -22,7 +22,19 @@ export const NODE_TABLES = [
22
22
  // ============================================================================
23
23
  export const REL_TABLE_NAME = 'CodeRelation';
24
24
  // Valid relation types
25
- export const REL_TYPES = ['CONTAINS', 'DEFINES', 'IMPORTS', 'CALLS', 'EXTENDS', 'IMPLEMENTS', 'MEMBER_OF', 'STEP_IN_PROCESS'];
25
+ export const REL_TYPES = [
26
+ 'CONTAINS',
27
+ 'DEFINES',
28
+ 'IMPORTS',
29
+ 'CALLS',
30
+ 'EXTENDS',
31
+ 'IMPLEMENTS',
32
+ 'MEMBER_OF',
33
+ 'STEP_IN_PROCESS',
34
+ 'UNITY_COMPONENT_IN',
35
+ 'UNITY_COMPONENT_INSTANCE',
36
+ 'UNITY_SERIALIZED_TYPE_IN',
37
+ ];
26
38
  // ============================================================================
27
39
  // EMBEDDING TABLE
28
40
  // ============================================================================
@@ -216,12 +228,15 @@ CREATE REL TABLE ${REL_TABLE_NAME} (
216
228
  FROM Function TO \`Impl\`,
217
229
  FROM Function TO Interface,
218
230
  FROM Function TO \`Constructor\`,
231
+ FROM Function TO \`Property\`,
219
232
  FROM Function TO \`Const\`,
220
233
  FROM Function TO \`Typedef\`,
221
234
  FROM Function TO \`Union\`,
222
235
  FROM Class TO Method,
223
236
  FROM Class TO Function,
224
237
  FROM Class TO Class,
238
+ FROM Class TO File,
239
+ FROM Class TO CodeElement,
225
240
  FROM Class TO Interface,
226
241
  FROM Class TO Community,
227
242
  FROM Class TO \`Template\`,
@@ -236,6 +251,8 @@ CREATE REL TABLE ${REL_TABLE_NAME} (
236
251
  FROM Class TO \`Union\`,
237
252
  FROM Class TO \`Namespace\`,
238
253
  FROM Class TO \`Typedef\`,
254
+ FROM Class TO \`Property\`,
255
+ FROM Class TO \`Delegate\`,
239
256
  FROM Method TO Function,
240
257
  FROM Method TO Method,
241
258
  FROM Method TO Class,
@@ -251,6 +268,7 @@ CREATE REL TABLE ${REL_TABLE_NAME} (
251
268
  FROM Method TO Interface,
252
269
  FROM Method TO \`Constructor\`,
253
270
  FROM Method TO \`Property\`,
271
+ FROM Method TO \`Delegate\`,
254
272
  FROM \`Template\` TO \`Template\`,
255
273
  FROM \`Template\` TO Function,
256
274
  FROM \`Template\` TO Method,
@@ -298,6 +316,8 @@ CREATE REL TABLE ${REL_TABLE_NAME} (
298
316
  FROM \`Const\` TO Community,
299
317
  FROM \`Static\` TO Community,
300
318
  FROM \`Property\` TO Community,
319
+ FROM \`Property\` TO Class,
320
+ FROM \`Property\` TO Interface,
301
321
  FROM \`Record\` TO Community,
302
322
  FROM \`Delegate\` TO Community,
303
323
  FROM \`Annotation\` TO Community,
@@ -316,6 +336,7 @@ CREATE REL TABLE ${REL_TABLE_NAME} (
316
336
  FROM \`Constructor\` TO \`Impl\`,
317
337
  FROM \`Constructor\` TO \`Namespace\`,
318
338
  FROM \`Constructor\` TO \`Module\`,
339
+ FROM \`Constructor\` TO \`Property\`,
319
340
  FROM \`Template\` TO Community,
320
341
  FROM \`Module\` TO Community,
321
342
  FROM Function TO Process,
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { RELATION_SCHEMA } from './schema.js';
4
+ test('RELATION_SCHEMA includes audited fallback pairs for Property/Delegate links', () => {
5
+ const requiredPairs = [
6
+ 'FROM Method TO `Delegate`',
7
+ 'FROM Class TO `Property`',
8
+ 'FROM `Constructor` TO `Property`',
9
+ 'FROM Function TO `Property`',
10
+ 'FROM `Property` TO Class',
11
+ 'FROM `Property` TO Interface',
12
+ 'FROM Class TO `Delegate`',
13
+ ];
14
+ for (const pair of requiredPairs) {
15
+ assert.match(RELATION_SCHEMA, new RegExp(pair.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')), `Missing relationship pair in schema: ${pair}`);
16
+ }
17
+ });
@@ -0,0 +1,5 @@
1
+ export interface BuildMetaIndexOptions {
2
+ metaFiles?: string[];
3
+ }
4
+ export declare function buildMetaIndex(repoRoot: string, options?: BuildMetaIndexOptions): Promise<Map<string, string>>;
5
+ export declare function buildAssetMetaIndex(repoRoot: string, options?: BuildMetaIndexOptions): Promise<Map<string, string>>;
@@ -0,0 +1,113 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { glob } from 'glob';
4
+ const GUID_PATTERN = /^guid:\s*([0-9a-f]{32})\s*$/im;
5
+ const META_INDEX_READ_CONCURRENCY = 64;
6
+ export async function buildMetaIndex(repoRoot, options = {}) {
7
+ const metaFiles = await resolveMetaFiles(repoRoot, options.metaFiles);
8
+ const entries = await mapWithConcurrency(metaFiles, META_INDEX_READ_CONCURRENCY, async (metaPath) => {
9
+ const absolutePath = path.join(repoRoot, metaPath);
10
+ let content = '';
11
+ try {
12
+ content = await fs.readFile(absolutePath, 'utf-8');
13
+ }
14
+ catch (error) {
15
+ if (error.code === 'ENOENT')
16
+ return null;
17
+ throw error;
18
+ }
19
+ const match = content.match(GUID_PATTERN);
20
+ if (!match)
21
+ return null;
22
+ const scriptPath = metaPath.slice(0, -'.meta'.length).replace(/\\/g, '/');
23
+ return [match[1], scriptPath];
24
+ });
25
+ const index = new Map();
26
+ for (const entry of entries) {
27
+ if (!entry)
28
+ continue;
29
+ index.set(entry[0], entry[1]);
30
+ }
31
+ return index;
32
+ }
33
+ export async function buildAssetMetaIndex(repoRoot, options = {}) {
34
+ const metaFiles = await resolveAssetMetaFiles(repoRoot, options.metaFiles);
35
+ const entries = await mapWithConcurrency(metaFiles, META_INDEX_READ_CONCURRENCY, async (metaPath) => {
36
+ const absolutePath = path.join(repoRoot, metaPath);
37
+ let content = '';
38
+ try {
39
+ content = await fs.readFile(absolutePath, 'utf-8');
40
+ }
41
+ catch (error) {
42
+ if (error.code === 'ENOENT')
43
+ return null;
44
+ throw error;
45
+ }
46
+ const match = content.match(GUID_PATTERN);
47
+ if (!match)
48
+ return null;
49
+ const assetPath = metaPath.slice(0, -'.meta'.length).replace(/\\/g, '/');
50
+ return [match[1], assetPath];
51
+ });
52
+ const index = new Map();
53
+ for (const entry of entries) {
54
+ if (!entry)
55
+ continue;
56
+ index.set(entry[0], entry[1]);
57
+ index.set(entry[0].toLowerCase(), entry[1]);
58
+ }
59
+ return index;
60
+ }
61
+ async function resolveMetaFiles(repoRoot, scopedMetaFiles) {
62
+ if (!scopedMetaFiles || scopedMetaFiles.length === 0) {
63
+ return (await glob('**/*.cs.meta', {
64
+ cwd: repoRoot,
65
+ nodir: true,
66
+ dot: false,
67
+ })).sort((left, right) => left.localeCompare(right));
68
+ }
69
+ const normalized = scopedMetaFiles
70
+ .filter((value) => value.endsWith('.cs.meta'))
71
+ .map((value) => normalizeRelativePath(repoRoot, value))
72
+ .filter((value) => value !== null)
73
+ .sort((left, right) => left.localeCompare(right));
74
+ return [...new Set(normalized)];
75
+ }
76
+ async function resolveAssetMetaFiles(repoRoot, scopedMetaFiles) {
77
+ if (!scopedMetaFiles || scopedMetaFiles.length === 0) {
78
+ return (await glob('**/*.meta', {
79
+ cwd: repoRoot,
80
+ nodir: true,
81
+ dot: false,
82
+ })).sort((left, right) => left.localeCompare(right));
83
+ }
84
+ const normalized = scopedMetaFiles
85
+ .filter((value) => value.endsWith('.meta'))
86
+ .map((value) => normalizeRelativePath(repoRoot, value))
87
+ .filter((value) => value !== null)
88
+ .sort((left, right) => left.localeCompare(right));
89
+ return [...new Set(normalized)];
90
+ }
91
+ function normalizeRelativePath(repoRoot, filePath) {
92
+ const relativePath = path.isAbsolute(filePath) ? path.relative(repoRoot, filePath) : filePath;
93
+ const normalized = relativePath.replace(/\\/g, '/');
94
+ if (normalized.startsWith('../'))
95
+ return null;
96
+ return normalized;
97
+ }
98
+ async function mapWithConcurrency(items, concurrency, mapper) {
99
+ const safeConcurrency = Math.max(1, Math.min(concurrency, items.length || 1));
100
+ const results = new Array(items.length);
101
+ let cursor = 0;
102
+ const workers = Array.from({ length: safeConcurrency }, async () => {
103
+ while (true) {
104
+ const index = cursor;
105
+ cursor += 1;
106
+ if (index >= items.length)
107
+ break;
108
+ results[index] = await mapper(items[index], index);
109
+ }
110
+ });
111
+ await Promise.all(workers);
112
+ return results;
113
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { buildMetaIndex } from './meta-index.js';
6
+ const here = path.dirname(fileURLToPath(import.meta.url));
7
+ const fixtureRoot = path.resolve(here, '../../../src/core/unity/__fixtures__/mini-unity');
8
+ test('buildMetaIndex maps script guid to script path', async () => {
9
+ const index = await buildMetaIndex(fixtureRoot);
10
+ assert.equal(index.get('a6d481d58c0b4f646b7106ceaf633d6e')?.endsWith('Global.cs'), true);
11
+ });
@@ -0,0 +1,2 @@
1
+ export type UnityResourcesMode = 'off' | 'on' | 'auto';
2
+ export declare function parseUnityResourcesMode(raw?: string): UnityResourcesMode;
@@ -0,0 +1,9 @@
1
+ export function parseUnityResourcesMode(raw) {
2
+ if (!raw)
3
+ return 'off';
4
+ const normalized = raw.trim().toLowerCase();
5
+ if (normalized === 'off' || normalized === 'on' || normalized === 'auto') {
6
+ return normalized;
7
+ }
8
+ throw new Error('Invalid unity resources mode. Use off|on|auto.');
9
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { parseUnityResourcesMode } from './options.js';
4
+ test('parseUnityResourcesMode defaults to off', () => {
5
+ assert.equal(parseUnityResourcesMode(undefined), 'off');
6
+ });
7
+ test('parseUnityResourcesMode validates mode', () => {
8
+ assert.equal(parseUnityResourcesMode('on'), 'on');
9
+ assert.throws(() => parseUnityResourcesMode('bad'), /unity resources mode/i);
10
+ });
@@ -0,0 +1,27 @@
1
+ export interface UnityScalarFieldInput {
2
+ value: string;
3
+ valueType?: string;
4
+ }
5
+ export interface UnityReferenceFieldInput {
6
+ fileId?: string;
7
+ guid?: string;
8
+ resolvedAssetPath?: string;
9
+ }
10
+ export interface UnityObjectLayer {
11
+ sourceLayer: string;
12
+ scalarFields?: Record<string, UnityScalarFieldInput>;
13
+ referenceFields?: Record<string, UnityReferenceFieldInput>;
14
+ }
15
+ export interface MergedUnityScalarField extends UnityScalarFieldInput {
16
+ name: string;
17
+ sourceLayer: string;
18
+ }
19
+ export interface MergedUnityReferenceField extends UnityReferenceFieldInput {
20
+ name: string;
21
+ sourceLayer: string;
22
+ }
23
+ export interface MergedUnityComponent {
24
+ scalarFields: Record<string, MergedUnityScalarField>;
25
+ referenceFields: Record<string, MergedUnityReferenceField>;
26
+ }
27
+ export declare function mergeOverrideChain(...layersOrArray: Array<UnityObjectLayer | UnityObjectLayer[]>): MergedUnityComponent;
@@ -0,0 +1,35 @@
1
+ export function mergeOverrideChain(...layersOrArray) {
2
+ const layers = normalizeLayers(layersOrArray);
3
+ const merged = {
4
+ scalarFields: {},
5
+ referenceFields: {},
6
+ };
7
+ for (const layer of layers) {
8
+ if (!layer)
9
+ continue;
10
+ for (const [name, field] of Object.entries(layer.scalarFields || {})) {
11
+ merged.scalarFields[name] = {
12
+ name,
13
+ sourceLayer: layer.sourceLayer,
14
+ value: field.value,
15
+ valueType: field.valueType,
16
+ };
17
+ }
18
+ for (const [name, field] of Object.entries(layer.referenceFields || {})) {
19
+ merged.referenceFields[name] = {
20
+ name,
21
+ sourceLayer: layer.sourceLayer,
22
+ fileId: field.fileId,
23
+ guid: field.guid,
24
+ resolvedAssetPath: field.resolvedAssetPath,
25
+ };
26
+ }
27
+ }
28
+ return merged;
29
+ }
30
+ function normalizeLayers(layersOrArray) {
31
+ if (layersOrArray.length === 1 && Array.isArray(layersOrArray[0])) {
32
+ return layersOrArray[0];
33
+ }
34
+ return layersOrArray;
35
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,47 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { mergeOverrideChain } from './override-merger.js';
4
+ test('mergeOverrideChain applies base -> variant -> nested -> scene order', () => {
5
+ const baseComponent = {
6
+ sourceLayer: 'base',
7
+ scalarFields: {
8
+ needPause: { value: '0' },
9
+ title: { value: 'Base' },
10
+ },
11
+ referenceFields: {
12
+ mainUIDocument: { fileId: '1000', guid: 'base-guid' },
13
+ },
14
+ };
15
+ const variantComponent = {
16
+ sourceLayer: 'variant',
17
+ scalarFields: {
18
+ title: { value: 'Variant' },
19
+ },
20
+ referenceFields: {
21
+ mainUIDocument: { fileId: '2000', guid: 'variant-guid' },
22
+ },
23
+ };
24
+ const nestedComponent = {
25
+ sourceLayer: 'nested',
26
+ scalarFields: {
27
+ subtitle: { value: 'Nested' },
28
+ },
29
+ };
30
+ const sceneOverride = {
31
+ sourceLayer: 'scene',
32
+ scalarFields: {
33
+ needPause: { value: '1' },
34
+ },
35
+ referenceFields: {
36
+ mainUIDocument: { fileId: '11400000', guid: 'scene-guid' },
37
+ },
38
+ };
39
+ const merged = mergeOverrideChain(baseComponent, variantComponent, nestedComponent, sceneOverride);
40
+ assert.equal(merged.scalarFields.needPause.value, '1');
41
+ assert.equal(merged.scalarFields.needPause.sourceLayer, 'scene');
42
+ assert.equal(merged.scalarFields.title.value, 'Variant');
43
+ assert.equal(merged.scalarFields.title.sourceLayer, 'variant');
44
+ assert.equal(merged.scalarFields.subtitle.value, 'Nested');
45
+ assert.equal(merged.referenceFields.mainUIDocument.fileId, '11400000');
46
+ assert.equal(merged.referenceFields.mainUIDocument.sourceLayer, 'scene');
47
+ });
@@ -0,0 +1,79 @@
1
+ import type { UnityScanContext } from './scan-context.js';
2
+ import { type UnityObjectType } from './yaml-object-graph.js';
3
+ export type UnityBindingKind = 'direct' | 'prefab-instance' | 'nested' | 'variant' | 'scene-override';
4
+ export interface ResolveInput {
5
+ repoRoot: string;
6
+ symbol: string;
7
+ scanContext?: UnityScanContext;
8
+ }
9
+ export interface UnityScalarField {
10
+ name: string;
11
+ value: string;
12
+ valueType?: string;
13
+ sourceLayer: string;
14
+ }
15
+ export interface UnityReferenceField {
16
+ name: string;
17
+ fileId?: string;
18
+ guid?: string;
19
+ resolvedAssetPath?: string;
20
+ sourceLayer: string;
21
+ }
22
+ export interface UnitySerializedFields {
23
+ scalarFields: UnityScalarField[];
24
+ referenceFields: UnityReferenceField[];
25
+ }
26
+ export type UnityReferenceResolution = 'null' | 'local-object' | 'external-asset' | 'unresolved';
27
+ export interface UnityResolvedReferenceTarget {
28
+ resourcePath?: string;
29
+ objectId?: string;
30
+ objectType?: UnityObjectType | string;
31
+ gameObjectName?: string;
32
+ assetPath?: string;
33
+ }
34
+ export interface UnityResolvedReference {
35
+ fieldName: string;
36
+ sourceLayer: string;
37
+ fileId?: string;
38
+ guid?: string;
39
+ fromList: boolean;
40
+ listIndex?: number;
41
+ resolution: UnityReferenceResolution;
42
+ target?: UnityResolvedReferenceTarget;
43
+ }
44
+ export interface UnityBindingEvidence {
45
+ line: number;
46
+ lineText: string;
47
+ }
48
+ export interface UnityAssetRefPathReference {
49
+ parentFieldName: string;
50
+ fieldName: string;
51
+ relativePath: string;
52
+ sourceLayer: string;
53
+ isEmpty: boolean;
54
+ isSprite: boolean;
55
+ }
56
+ export interface ResolvedUnityBinding {
57
+ resourcePath: string;
58
+ resourceType: 'prefab' | 'scene' | 'asset';
59
+ bindingKind: UnityBindingKind;
60
+ componentObjectId: string;
61
+ evidence: UnityBindingEvidence;
62
+ serializedFields: UnitySerializedFields;
63
+ resolvedReferences: UnityResolvedReference[];
64
+ assetRefPaths?: UnityAssetRefPathReference[];
65
+ }
66
+ export interface ResolveOutput {
67
+ symbol: string;
68
+ scriptPath: string;
69
+ scriptGuid: string;
70
+ resourceBindings: ResolvedUnityBinding[];
71
+ serializedFields: UnitySerializedFields;
72
+ unityDiagnostics: string[];
73
+ }
74
+ export declare function resolveUnityBindings(input: ResolveInput): Promise<ResolveOutput>;
75
+ export declare function hasCoverage(resultSet: ResolveOutput[]): {
76
+ hasScalar: boolean;
77
+ hasReference: boolean;
78
+ };
79
+ export declare function extractAssetRefPathReferences(serializedFields: UnitySerializedFields): UnityAssetRefPathReference[];