@codragraph/cli 2.1.5 → 2.1.6

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 (101) hide show
  1. package/README.md +18 -13
  2. package/dist/cli/analyze.d.ts +9 -4
  3. package/dist/cli/analyze.js +37 -13
  4. package/dist/cli/index.js +9 -3
  5. package/dist/cli/status.d.ts +1 -1
  6. package/dist/cli/status.js +8 -0
  7. package/dist/cli/tool.d.ts +10 -2
  8. package/dist/cli/tool.js +27 -6
  9. package/dist/core/adaptive-profile.d.ts +52 -0
  10. package/dist/core/adaptive-profile.js +180 -0
  11. package/dist/core/cgdb/cgdb-adapter.d.ts +34 -5
  12. package/dist/core/cgdb/cgdb-adapter.js +418 -5
  13. package/dist/core/cgdb/pool-adapter.js +1 -1
  14. package/dist/core/ingestion/pipeline-phases/parse-impl.js +3 -1
  15. package/dist/core/ingestion/pipeline-phases/structure.js +19 -3
  16. package/dist/core/ingestion/pipeline.d.ts +10 -0
  17. package/dist/core/run-analyze.d.ts +27 -2
  18. package/dist/core/run-analyze.js +598 -27
  19. package/dist/core/search/bm25-index.d.ts +19 -0
  20. package/dist/core/search/bm25-index.js +68 -29
  21. package/dist/mcp/local/local-backend.js +6 -3
  22. package/dist/storage/repo-manager.d.ts +29 -0
  23. package/dist/web/assets/__vite-browser-external-BIHI7g3E.js +1 -0
  24. package/dist/web/assets/agent-DcdaQnmu.js +1104 -0
  25. package/dist/web/assets/architectureDiagram-UL44E2DR-DFSpa3Hb.js +36 -0
  26. package/dist/web/assets/blockDiagram-7IZFK4PR-DlFaxH1b.js +132 -0
  27. package/dist/web/assets/{c4Diagram-DFAF54RM-C4Hl3J2U.js → c4Diagram-Y2BXMSZH-BjJ_Yrim.js} +1 -1
  28. package/dist/web/assets/{chunk-7RZVMHOQ-BitYcNVR.js → chunk-3SSMPTDK-KGZSzG3Y.js} +1 -1
  29. package/dist/web/assets/{chunk-TBF5ZNIQ-DL5stGM1.js → chunk-6764PJDD-p1sGJgVm.js} +1 -1
  30. package/dist/web/assets/{chunk-KSICW3F5-BYzvDLNI.js → chunk-AZZRMDJM-DIDkQA4V.js} +1 -1
  31. package/dist/web/assets/{chunk-AEOMTBSW-BgTIXPsY.js → chunk-JQRUD6KW-DAwg-yCU.js} +1 -1
  32. package/dist/web/assets/chunk-KRXBNO2N-ChVO_XdS.js +1 -0
  33. package/dist/web/assets/chunk-LCXTWHL2-DGYdb_Eh.js +231 -0
  34. package/dist/web/assets/{chunk-O5ABG6QK-dHwHzA6n.js → chunk-LII3EMHJ-Bzh9SNgD.js} +1 -1
  35. package/dist/web/assets/chunk-RG4AUYOV-Bcl7U_IV.js +206 -0
  36. package/dist/web/assets/{chunk-TU3PZOEN-RLyvLcv-.js → chunk-T5OCTHI4-CZYMg5sc.js} +1 -1
  37. package/dist/web/assets/chunk-W44A43WB-REOI67PN.js +13 -0
  38. package/dist/web/assets/{chunk-RWUO3TPN-BgRTY0_k.js → chunk-ZXARS5L4-BfFdV1tf.js} +1 -1
  39. package/dist/web/assets/classDiagram-KGZ6W3CR-B-qkKMYi.js +1 -0
  40. package/dist/web/assets/classDiagram-v2-72OJOZXJ-B-qkKMYi.js +1 -0
  41. package/dist/web/assets/{cose-bilkent-PNC4W37J-DVhePRYg.js → cose-bilkent-UX7MHV2Q-D6vANJGG.js} +1 -1
  42. package/dist/web/assets/dagre-ND4H6XIP-BiHe5Lal.js +4 -0
  43. package/dist/web/assets/diagram-3NCE3AQN-CEutBCOW.js +43 -0
  44. package/dist/web/assets/diagram-GF46GFSD-CZns6HPQ.js +24 -0
  45. package/dist/web/assets/diagram-HNR7UZ2L-Vz8fE5of.js +3 -0
  46. package/dist/web/assets/diagram-QXG6HAR7-D60HKZ_y.js +24 -0
  47. package/dist/web/assets/diagram-WEQXMOUZ-vGAf1p3E.js +10 -0
  48. package/dist/web/assets/{erDiagram-GCSMX5X6-C3dhDFA8.js → erDiagram-L5TCEMPS-DZaplJA6.js} +5 -5
  49. package/dist/web/assets/{flowDiagram-OTCZ4VVT-CWSFWmhr.js → flowDiagram-H6V6AXG4-BqUqeAsI.js} +9 -9
  50. package/dist/web/assets/ganttDiagram-JCBTUEKG-XEB6H-0G.js +292 -0
  51. package/dist/web/assets/gitGraphDiagram-S2ZK5IYY-7G50u1Cd.js +106 -0
  52. package/dist/web/assets/index-B5WxtMpv.js +1415 -0
  53. package/dist/web/assets/infoDiagram-3YFTVSEB-Cut_rzaf.js +2 -0
  54. package/dist/web/assets/{ishikawaDiagram-YMYX4NHK-DUoJvNP2.js → ishikawaDiagram-BNXS4ZKH-B4DGfGi3.js} +3 -3
  55. package/dist/web/assets/{journeyDiagram-SO5T7YLQ-RMFPNNqz.js → journeyDiagram-M6C3CM3L-BBFhsL3E.js} +1 -1
  56. package/dist/web/assets/{kanban-definition-LJHFXRCJ-BzpDs1K9.js → kanban-definition-75IXJCU3-DarGRyn3.js} +4 -4
  57. package/dist/web/assets/{katex-GD7MH7QM-DBQvrix-.js → katex-K3KEBU37-W5XTYMhr.js} +1 -1
  58. package/dist/web/assets/mindmap-definition-2TDM6QVE-BgeczIJM.js +96 -0
  59. package/dist/web/assets/pieDiagram-CU6KROY3-Kkoo-Noq.js +30 -0
  60. package/dist/web/assets/quadrantDiagram-VICAPDV7-CDQFeRWN.js +7 -0
  61. package/dist/web/assets/{requirementDiagram-M5DCFWZL-DLHOVTSv.js → requirementDiagram-JXO7QTGE-Cz9-XnkA.js} +2 -2
  62. package/dist/web/assets/sankeyDiagram-URQDO5SZ-CU26z0n7.js +40 -0
  63. package/dist/web/assets/sequenceDiagram-VS2MUI6T-OGK1FLOt.js +162 -0
  64. package/dist/web/assets/stateDiagram-7D4R322I-DJ9brq0U.js +1 -0
  65. package/dist/web/assets/stateDiagram-v2-36443NZ5-DhJ4Ky-7.js +1 -0
  66. package/dist/web/assets/{timeline-definition-5SPVSISX-TRSDRgPw.js → timeline-definition-O6YCAMPW-XZvnjqTT.js} +4 -4
  67. package/dist/web/assets/{vennDiagram-IE5QUKF5-DNy7HRBM.js → vennDiagram-MWXL3ELB-CJUssEjA.js} +6 -6
  68. package/dist/web/assets/wardley-L42UT6IY-5TKZOOLJ-DZr11zBG.js +173 -0
  69. package/dist/web/assets/wardleyDiagram-CUQ6CDDI-C276iqrN.js +78 -0
  70. package/dist/web/assets/{xychartDiagram-ZHJ5623Y-Dr9r7a35.js → xychartDiagram-N2JHSOCM-B9-uCZyP.js} +4 -4
  71. package/dist/web/index.html +1 -1
  72. package/package.json +1 -1
  73. package/vendor/node_modules/node-addon-api/node_addon_api_except.stamp +0 -0
  74. package/dist/web/assets/agent-D5lb0zXz.js +0 -1089
  75. package/dist/web/assets/architectureDiagram-EMZXCZ2Q-CZtc99v_.js +0 -36
  76. package/dist/web/assets/blockDiagram-IGV67L2C-BtoUp-6Y.js +0 -132
  77. package/dist/web/assets/chunk-3GS5O3IE-DkUjU0WD.js +0 -231
  78. package/dist/web/assets/chunk-3YCYZ6SJ-CQkVgT_z.js +0 -1
  79. package/dist/web/assets/chunk-H3VCZNTA-Cx5XV_aC.js +0 -13
  80. package/dist/web/assets/chunk-HN6EAY2L-BBnyTNdB.js +0 -1
  81. package/dist/web/assets/chunk-PK6DOVAG-CvsEnugt.js +0 -206
  82. package/dist/web/assets/classDiagram-PPOCWD7C-DTr8QIOf.js +0 -1
  83. package/dist/web/assets/classDiagram-v2-23LJLIIU-DTr8QIOf.js +0 -1
  84. package/dist/web/assets/dagre-E77IOHMT-Dzx0A6ZU.js +0 -4
  85. package/dist/web/assets/diagram-H7BISOXX-CC9pRew1.js +0 -43
  86. package/dist/web/assets/diagram-JC5VWROH-Bau_i9tf.js +0 -24
  87. package/dist/web/assets/diagram-LXUTUG65-D9_FM2Gt.js +0 -10
  88. package/dist/web/assets/diagram-WEHSV5V5-BMlayouL.js +0 -24
  89. package/dist/web/assets/ganttDiagram-MUNLMDZQ-D3a67Yol.js +0 -292
  90. package/dist/web/assets/gitGraphDiagram-3HKGZ4G3-7jmry-vM.js +0 -106
  91. package/dist/web/assets/index-BgeqpYgd.js +0 -1415
  92. package/dist/web/assets/infoDiagram-MN7RKWGX-G7lhP0Ib.js +0 -2
  93. package/dist/web/assets/mindmap-definition-2EUWGEK5-Bk0O4roa.js +0 -96
  94. package/dist/web/assets/pieDiagram-3IATQBI2-DKU7kpgS.js +0 -30
  95. package/dist/web/assets/quadrantDiagram-E256RVCF-BY0TGWCS.js +0 -7
  96. package/dist/web/assets/sankeyDiagram-L3NBLAOT-DVMj5rX2.js +0 -10
  97. package/dist/web/assets/sequenceDiagram-ZOUHS735-CJC73bV-.js +0 -157
  98. package/dist/web/assets/stateDiagram-MLPALWAM-BCFyESls.js +0 -1
  99. package/dist/web/assets/stateDiagram-v2-B5LQ5ZB2-DahzzIca.js +0 -1
  100. package/dist/web/assets/wardley-RL74JXVD-BCRCBASE-B-eZEzf9.js +0 -161
  101. package/dist/web/assets/wardleyDiagram-XU3VSMPF-BP-r1xzR.js +0 -20
@@ -15,7 +15,26 @@ export interface BM25SearchResult {
15
15
  score: number;
16
16
  rank: number;
17
17
  nodeIds?: string[];
18
+ /** False when results came from the bounded fallback scan instead of FTS. */
19
+ ftsUsed?: boolean;
18
20
  }
21
+ /**
22
+ * FTS table set served by `searchFTSFromCgdb`. Centralised so that both
23
+ * the CLI/pipeline path and the MCP pool path stay in lockstep.
24
+ *
25
+ * The properties list is computed at FTS-create time via `ftsPropertiesFor`
26
+ * — for repos that were analysed with `--compress brotli|zstd`, the
27
+ * `content` column holds base64-of-encoded-bytes and would tokenise to
28
+ * useless tokens. Those repos get name-only FTS so search at least
29
+ * matches function/class names instead of returning random hits on
30
+ * base64 alphabet. Plain (compress='none' / unset) repos get the full
31
+ * `name + content` index for body-text matches. RFC 0001 Phase 2.5.
32
+ */
33
+ export declare const FTS_TABLES: ReadonlyArray<{
34
+ table: string;
35
+ indexName: string;
36
+ }>;
37
+ export declare const ftsPropertiesFor: (compress: "none" | "brotli" | "zstd" | undefined) => readonly string[];
19
38
  /**
20
39
  * Search using LadybugDB's built-in FTS (always fresh, reads from disk)
21
40
  *
@@ -23,22 +23,21 @@ import { queryFTS, ensureFTSIndex, executeQuery as executeCoreQuery, } from '../
23
23
  * base64 alphabet. Plain (compress='none' / unset) repos get the full
24
24
  * `name + content` index for body-text matches. RFC 0001 Phase 2.5.
25
25
  */
26
- const FTS_TABLES = [
26
+ export const FTS_TABLES = [
27
27
  { table: 'File', indexName: 'file_fts' },
28
28
  { table: 'Function', indexName: 'function_fts' },
29
29
  { table: 'Class', indexName: 'class_fts' },
30
30
  { table: 'Method', indexName: 'method_fts' },
31
31
  { table: 'Interface', indexName: 'interface_fts' },
32
32
  ];
33
- const ftsPropertiesFor = (compress) => !compress || compress === 'none' ? ['name', 'content'] : ['name'];
33
+ export const ftsPropertiesFor = (compress) => (!compress || compress === 'none' ? ['name', 'content'] : ['name']);
34
34
  /**
35
- * Look up `meta.compress` for a repo. The MCP path passes `repoId`
36
- * (registry-derived); the CLI path passes nothing and we walk up from
37
- * cwd. Returns `'none'` whenever the lookup fails so the safe default
38
- * (full FTS index) is used the failure mode is reduced search
39
- * quality, never wrong results.
35
+ * Look up query-related index metadata for a repo. The MCP path passes `repoId`
36
+ * (registry-derived); the CLI/core path passes nothing and we walk up from
37
+ * cwd. Read-only callers use `ftsReady` to avoid expensive probes for
38
+ * FTS indexes that older analyses never wrote.
40
39
  */
41
- async function getCompressMode(repoId) {
40
+ async function getSearchMeta(repoId) {
42
41
  try {
43
42
  const repoMod = await import('../../storage/repo-manager.js');
44
43
  if (repoId) {
@@ -50,16 +49,22 @@ async function getCompressMode(repoId) {
50
49
  const base = entry.name.toLowerCase();
51
50
  if (base === repoId || repoId.startsWith(`${base}-`)) {
52
51
  const meta = await repoMod.loadMeta(entry.storagePath);
53
- return meta?.compress ?? 'none';
52
+ return {
53
+ compress: meta?.compress ?? 'none',
54
+ ftsReady: meta?.searchIndexes?.fts === true,
55
+ };
54
56
  }
55
57
  }
56
- return 'none';
58
+ return { compress: 'none', ftsReady: false };
57
59
  }
58
60
  const repo = await repoMod.findRepo(process.cwd());
59
- return repo?.meta?.compress ?? 'none';
61
+ return {
62
+ compress: repo?.meta?.compress ?? 'none',
63
+ ftsReady: repo?.meta?.searchIndexes?.fts,
64
+ };
60
65
  }
61
66
  catch {
62
- return 'none';
67
+ return { compress: 'none', ftsReady: repoId ? false : undefined };
63
68
  }
64
69
  }
65
70
  const FALLBACK_SCAN_LIMIT = 50_000;
@@ -105,6 +110,22 @@ function searchTerms(query) {
105
110
  ?.filter((term) => term.length > 1 && !BOOLEAN_QUERY_TOKENS.has(term));
106
111
  return [...new Set(terms ?? [])];
107
112
  }
113
+ function searchTermVariants(query) {
114
+ const rawTerms = query.match(/[\p{L}\p{N}_]+/gu) ?? [];
115
+ const variants = new Set();
116
+ for (const raw of rawTerms) {
117
+ const lower = raw.toLowerCase();
118
+ if (raw.length <= 1 || BOOLEAN_QUERY_TOKENS.has(lower))
119
+ continue;
120
+ variants.add(raw);
121
+ variants.add(lower);
122
+ variants.add(raw.charAt(0).toUpperCase() + raw.slice(1).toLowerCase());
123
+ }
124
+ return [...variants];
125
+ }
126
+ function cypherString(value) {
127
+ return `'${value.replace(/\\/g, '\\\\').replace(/'/g, "''")}'`;
128
+ }
108
129
  function scoreFallbackNode(node, query, properties) {
109
130
  const terms = searchTerms(query);
110
131
  if (terms.length === 0)
@@ -131,10 +152,15 @@ function scoreFallbackNode(node, query, properties) {
131
152
  }
132
153
  async function queryFallbackViaExecutor(executor, tableName, properties, query, limit) {
133
154
  try {
155
+ const variants = searchTermVariants(query);
156
+ const conditions = variants.flatMap((term) => properties.map((property) => `node.${property} CONTAINS ${cypherString(term)}`));
157
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' OR ')}` : '';
158
+ const candidateLimit = Math.min(FALLBACK_SCAN_LIMIT, Math.max(limit * 25, 200));
134
159
  const rows = await executor(`
135
160
  MATCH (node:${tableName})
161
+ ${whereClause}
136
162
  RETURN node
137
- LIMIT ${FALLBACK_SCAN_LIMIT}
163
+ LIMIT ${candidateLimit}
138
164
  `);
139
165
  return rows
140
166
  .map((row) => {
@@ -158,10 +184,7 @@ async function fallbackSearchAllTables(executor, query, limit,
158
184
  // pre-Phase-2 behaviour (`['name', 'content']`) for callers that don't
159
185
  // pass a value.
160
186
  properties = ['name', 'content']) {
161
- const results = [];
162
- for (const { table } of FTS_TABLES) {
163
- results.push(await queryFallbackViaExecutor(executor, table, properties, query, limit));
164
- }
187
+ const results = await Promise.all(FTS_TABLES.map(({ table }) => queryFallbackViaExecutor(executor, table, properties, query, limit)));
165
188
  return results;
166
189
  }
167
190
  /**
@@ -179,6 +202,7 @@ export const searchFTSFromCgdb = async (query, limit = 20, repoId) => {
179
202
  if (!query.trim() || limit <= 0)
180
203
  return [];
181
204
  let fileResults, functionResults, classResults, methodResults, interfaceResults;
205
+ let usedFallback = false;
182
206
  if (repoId) {
183
207
  // Use MCP connection pool via dynamic import
184
208
  // IMPORTANT: FTS queries run sequentially to avoid connection contention.
@@ -188,34 +212,46 @@ export const searchFTSFromCgdb = async (query, limit = 20, repoId) => {
188
212
  const executor = (cypher) => executeQuery(repoId, cypher);
189
213
  // The MCP/LocalBackend pool is opened read-only so it can safely coexist
190
214
  // with `codragraph analyze`. Do not issue CREATE_FTS_INDEX here: when
191
- // persisted FTS indexes are missing, QUERY_FTS_INDEX falls through to the
192
- // bounded BM25 fallback below without noisy write-failure retries.
215
+ // persisted FTS indexes are missing, meta.searchIndexes lets us skip
216
+ // QUERY_FTS_INDEX and go straight to the bounded fallback below.
193
217
  // RFC 0001 Phase 2.5: drop `content` from fallback scoring for repos
194
218
  // analysed with --compress brotli|zstd — the column holds encoded bytes.
195
- const compress = await getCompressMode(repoId);
196
- const properties = ftsPropertiesFor(compress);
197
- fileResults = await queryFTSViaExecutor(executor, 'File', 'file_fts', query, limit);
198
- functionResults = await queryFTSViaExecutor(executor, 'Function', 'function_fts', query, limit);
199
- classResults = await queryFTSViaExecutor(executor, 'Class', 'class_fts', query, limit);
200
- methodResults = await queryFTSViaExecutor(executor, 'Method', 'method_fts', query, limit);
201
- interfaceResults = await queryFTSViaExecutor(executor, 'Interface', 'interface_fts', query, limit);
219
+ const meta = await getSearchMeta(repoId);
220
+ const properties = ftsPropertiesFor(meta.compress);
221
+ if (meta.ftsReady) {
222
+ fileResults = await queryFTSViaExecutor(executor, 'File', 'file_fts', query, limit);
223
+ functionResults = await queryFTSViaExecutor(executor, 'Function', 'function_fts', query, limit);
224
+ classResults = await queryFTSViaExecutor(executor, 'Class', 'class_fts', query, limit);
225
+ methodResults = await queryFTSViaExecutor(executor, 'Method', 'method_fts', query, limit);
226
+ interfaceResults = await queryFTSViaExecutor(executor, 'Interface', 'interface_fts', query, limit);
227
+ }
228
+ else {
229
+ usedFallback = true;
230
+ fileResults = [];
231
+ functionResults = [];
232
+ classResults = [];
233
+ methodResults = [];
234
+ interfaceResults = [];
235
+ }
202
236
  if (fileResults.length +
203
237
  functionResults.length +
204
238
  classResults.length +
205
239
  methodResults.length +
206
240
  interfaceResults.length ===
207
241
  0) {
242
+ usedFallback = true;
208
243
  [fileResults, functionResults, classResults, methodResults, interfaceResults] =
209
244
  await fallbackSearchAllTables(executor, query, limit, properties);
210
245
  }
211
246
  }
212
247
  else {
213
248
  // Use core cgdb adapter (CLI / pipeline context) — also sequential for safety.
214
- // Lazy-create FTS indexes on first query (analyze no longer does it).
249
+ // Defensive fallback for older indexes or direct core callers: create FTS
250
+ // indexes on first query when this process owns a writable connection.
215
251
  // RFC 0001 Phase 2.5 — same `compress`-aware property selection as the MCP
216
252
  // path; the CLI walks up from cwd to find the repo's meta.json.
217
- const compress = await getCompressMode();
218
- const properties = ftsPropertiesFor(compress);
253
+ const meta = await getSearchMeta();
254
+ const properties = ftsPropertiesFor(meta.compress);
219
255
  for (const { table, indexName } of FTS_TABLES) {
220
256
  await ensureFTSIndex(table, indexName, [...properties]).catch(() => { });
221
257
  }
@@ -230,6 +266,7 @@ export const searchFTSFromCgdb = async (query, limit = 20, repoId) => {
230
266
  methodResults.length +
231
267
  interfaceResults.length ===
232
268
  0) {
269
+ usedFallback = true;
233
270
  [fileResults, functionResults, classResults, methodResults, interfaceResults] =
234
271
  await fallbackSearchAllTables(executeCoreQuery, query, limit, properties);
235
272
  }
@@ -258,6 +295,7 @@ export const searchFTSFromCgdb = async (query, limit = 20, repoId) => {
258
295
  filePath,
259
296
  score: top3.reduce((acc, e) => acc + e.score, 0),
260
297
  nodeIds: top3.map((e) => e.nodeId).filter((id) => id),
298
+ ftsUsed: !usedFallback,
261
299
  });
262
300
  }
263
301
  // Sort by score descending and add rank
@@ -269,5 +307,6 @@ export const searchFTSFromCgdb = async (query, limit = 20, repoId) => {
269
307
  score: r.score,
270
308
  rank: index + 1,
271
309
  nodeIds: r.nodeIds,
310
+ ftsUsed: r.ftsUsed,
272
311
  }));
273
312
  };
@@ -2107,10 +2107,12 @@ export class LocalBackend {
2107
2107
  queryParams[`hunkEnd${i}`] = hunk.endLine;
2108
2108
  });
2109
2109
  const symbolQuery = `
2110
- MATCH (n) WHERE n.filePath ENDS WITH $filePath
2110
+ MATCH (f:File)-[r:CodeRelation]->(n)
2111
+ WHERE r.type IN ['DEFINES', 'CONTAINS']
2112
+ AND f.filePath ENDS WITH $filePath
2111
2113
  AND n.startLine IS NOT NULL AND n.endLine IS NOT NULL
2112
2114
  AND (${overlapConditions})
2113
- RETURN n.id AS id, n.name AS name, labels(n)[0] AS type,
2115
+ RETURN n.id AS id, n.name AS name, '' AS type,
2114
2116
  n.filePath AS filePath, n.startLine AS startLine, n.endLine AS endLine
2115
2117
  `;
2116
2118
  try {
@@ -2119,7 +2121,8 @@ export class LocalBackend {
2119
2121
  changedSymbols.push({
2120
2122
  id: sym.id || sym[0],
2121
2123
  name: sym.name || sym[1],
2122
- type: sym.type || sym[2],
2124
+ type: safeNodeLabelForCypher(sym.type, sym.id || sym[0]) ??
2125
+ firstNonEmptyString(sym.type, sym.__cgLabel, sym[2]),
2123
2126
  filePath: sym.filePath || sym[3],
2124
2127
  change_type: 'touched',
2125
2128
  });
@@ -83,6 +83,35 @@ export interface RepoMeta {
83
83
  * — they decode at the read boundary.
84
84
  */
85
85
  compress?: 'none' | 'brotli' | 'zstd';
86
+ /**
87
+ * Query-time index capabilities written by analyze after optional search
88
+ * indexes are successfully created. Read-only MCP/CLI query paths use this
89
+ * to avoid expensive probes for indexes that older analyses never wrote.
90
+ */
91
+ searchIndexes?: {
92
+ fts?: boolean;
93
+ };
94
+ /**
95
+ * Runtime policy chosen by `analyze --profile auto|lean|balanced|power`.
96
+ * This is diagnostic metadata only; readers must not require it because
97
+ * older indexes do not have a policy record.
98
+ */
99
+ adaptiveProfile?: {
100
+ requested?: 'auto' | 'lean' | 'balanced' | 'power';
101
+ resolved?: 'lean' | 'balanced' | 'power';
102
+ platform?: NodeJS.Platform;
103
+ arch?: NodeJS.Architecture;
104
+ cpuCount?: number;
105
+ totalMemoryBytes?: number;
106
+ heapLimitBytes?: number;
107
+ compression?: 'none' | 'brotli' | 'zstd';
108
+ embeddingMode?: 'auto' | 'off' | 'on';
109
+ embeddingNodeLimit?: number;
110
+ embeddingDecision?: 'enabled' | 'skipped';
111
+ embeddingReason?: string;
112
+ workerPoolSize?: number;
113
+ workerSubBatchSize?: number;
114
+ };
86
115
  /**
87
116
  * Canonical `origin` remote URL captured at index time. Used to
88
117
  * fingerprint the same logical repo across multiple on-disk clones
@@ -0,0 +1 @@
1
+ const e={};export{e as default};