kiri-mcp-server 0.9.5 → 0.9.9

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 (108) hide show
  1. package/README.md +94 -7
  2. package/dist/package.json +11 -1
  3. package/dist/src/client/proxy.js +2 -1
  4. package/dist/src/client/proxy.js.map +1 -1
  5. package/dist/src/client/start-daemon.d.ts.map +1 -1
  6. package/dist/src/client/start-daemon.js +2 -1
  7. package/dist/src/client/start-daemon.js.map +1 -1
  8. package/dist/src/daemon/daemon.js +6 -4
  9. package/dist/src/daemon/daemon.js.map +1 -1
  10. package/dist/src/daemon/socket.d.ts +6 -4
  11. package/dist/src/daemon/socket.d.ts.map +1 -1
  12. package/dist/src/daemon/socket.js +62 -18
  13. package/dist/src/daemon/socket.js.map +1 -1
  14. package/dist/src/indexer/cli.d.ts +1 -0
  15. package/dist/src/indexer/cli.d.ts.map +1 -1
  16. package/dist/src/indexer/cli.js +503 -257
  17. package/dist/src/indexer/cli.js.map +1 -1
  18. package/dist/src/indexer/codeintel.d.ts +1 -1
  19. package/dist/src/indexer/codeintel.d.ts.map +1 -1
  20. package/dist/src/indexer/codeintel.js +296 -3
  21. package/dist/src/indexer/codeintel.js.map +1 -1
  22. package/dist/src/indexer/dart/analyze.d.ts +29 -0
  23. package/dist/src/indexer/dart/analyze.d.ts.map +1 -0
  24. package/dist/src/indexer/dart/analyze.js +452 -0
  25. package/dist/src/indexer/dart/analyze.js.map +1 -0
  26. package/dist/src/indexer/dart/client.d.ts +113 -0
  27. package/dist/src/indexer/dart/client.d.ts.map +1 -0
  28. package/dist/src/indexer/dart/client.js +444 -0
  29. package/dist/src/indexer/dart/client.js.map +1 -0
  30. package/dist/src/indexer/dart/config.d.ts +36 -0
  31. package/dist/src/indexer/dart/config.d.ts.map +1 -0
  32. package/dist/src/indexer/dart/config.js +62 -0
  33. package/dist/src/indexer/dart/config.js.map +1 -0
  34. package/dist/src/indexer/dart/dependencies.d.ts +17 -0
  35. package/dist/src/indexer/dart/dependencies.d.ts.map +1 -0
  36. package/dist/src/indexer/dart/dependencies.js +102 -0
  37. package/dist/src/indexer/dart/dependencies.js.map +1 -0
  38. package/dist/src/indexer/dart/pathKey.d.ts +40 -0
  39. package/dist/src/indexer/dart/pathKey.d.ts.map +1 -0
  40. package/dist/src/indexer/dart/pathKey.js +72 -0
  41. package/dist/src/indexer/dart/pathKey.js.map +1 -0
  42. package/dist/src/indexer/dart/poolGate.d.ts +57 -0
  43. package/dist/src/indexer/dart/poolGate.d.ts.map +1 -0
  44. package/dist/src/indexer/dart/poolGate.js +87 -0
  45. package/dist/src/indexer/dart/poolGate.js.map +1 -0
  46. package/dist/src/indexer/dart/sdk.d.ts +40 -0
  47. package/dist/src/indexer/dart/sdk.d.ts.map +1 -0
  48. package/dist/src/indexer/dart/sdk.js +167 -0
  49. package/dist/src/indexer/dart/sdk.js.map +1 -0
  50. package/dist/src/indexer/dart/transform.d.ts +17 -0
  51. package/dist/src/indexer/dart/transform.d.ts.map +1 -0
  52. package/dist/src/indexer/dart/transform.js +157 -0
  53. package/dist/src/indexer/dart/transform.js.map +1 -0
  54. package/dist/src/indexer/dart/types.d.ts +137 -0
  55. package/dist/src/indexer/dart/types.d.ts.map +1 -0
  56. package/dist/src/indexer/dart/types.js +5 -0
  57. package/dist/src/indexer/dart/types.js.map +1 -0
  58. package/dist/src/indexer/git.d.ts +1 -0
  59. package/dist/src/indexer/git.d.ts.map +1 -1
  60. package/dist/src/indexer/git.js +8 -0
  61. package/dist/src/indexer/git.js.map +1 -1
  62. package/dist/src/indexer/language.d.ts.map +1 -1
  63. package/dist/src/indexer/language.js +1 -0
  64. package/dist/src/indexer/language.js.map +1 -1
  65. package/dist/src/indexer/queue.d.ts +19 -0
  66. package/dist/src/indexer/queue.d.ts.map +1 -0
  67. package/dist/src/indexer/queue.js +50 -0
  68. package/dist/src/indexer/queue.js.map +1 -0
  69. package/dist/src/indexer/schema.d.ts +61 -1
  70. package/dist/src/indexer/schema.d.ts.map +1 -1
  71. package/dist/src/indexer/schema.js +253 -2
  72. package/dist/src/indexer/schema.js.map +1 -1
  73. package/dist/src/indexer/watch.d.ts +21 -0
  74. package/dist/src/indexer/watch.d.ts.map +1 -1
  75. package/dist/src/indexer/watch.js +189 -28
  76. package/dist/src/indexer/watch.js.map +1 -1
  77. package/dist/src/server/context.d.ts +7 -0
  78. package/dist/src/server/context.d.ts.map +1 -1
  79. package/dist/src/server/handlers.d.ts +7 -3
  80. package/dist/src/server/handlers.d.ts.map +1 -1
  81. package/dist/src/server/handlers.js +252 -24
  82. package/dist/src/server/handlers.js.map +1 -1
  83. package/dist/src/server/indexBootstrap.d.ts.map +1 -1
  84. package/dist/src/server/indexBootstrap.js +4 -1
  85. package/dist/src/server/indexBootstrap.js.map +1 -1
  86. package/dist/src/server/rpc.d.ts +40 -4
  87. package/dist/src/server/rpc.d.ts.map +1 -1
  88. package/dist/src/server/rpc.js +131 -41
  89. package/dist/src/server/rpc.js.map +1 -1
  90. package/dist/src/server/runtime.d.ts.map +1 -1
  91. package/dist/src/server/runtime.js +47 -7
  92. package/dist/src/server/runtime.js.map +1 -1
  93. package/dist/src/shared/duckdb.d.ts.map +1 -1
  94. package/dist/src/shared/duckdb.js +9 -0
  95. package/dist/src/shared/duckdb.js.map +1 -1
  96. package/dist/src/shared/security/masker.d.ts +1 -0
  97. package/dist/src/shared/security/masker.d.ts.map +1 -1
  98. package/dist/src/shared/security/masker.js +59 -13
  99. package/dist/src/shared/security/masker.js.map +1 -1
  100. package/dist/src/shared/utils/path.d.ts +46 -0
  101. package/dist/src/shared/utils/path.d.ts.map +1 -0
  102. package/dist/src/shared/utils/path.js +94 -0
  103. package/dist/src/shared/utils/path.js.map +1 -0
  104. package/dist/src/shared/utils/socket.d.ts +6 -2
  105. package/dist/src/shared/utils/socket.d.ts.map +1 -1
  106. package/dist/src/shared/utils/socket.js +62 -10
  107. package/dist/src/shared/utils/socket.js.map +1 -1
  108. package/package.json +11 -1
@@ -7,7 +7,11 @@ export async function ensureBaseSchema(db) {
7
7
  id INTEGER PRIMARY KEY DEFAULT nextval('repo_id_seq'),
8
8
  root TEXT NOT NULL UNIQUE,
9
9
  default_branch TEXT,
10
- indexed_at TIMESTAMP
10
+ indexed_at TIMESTAMP,
11
+ fts_last_indexed_at TIMESTAMP,
12
+ fts_dirty BOOLEAN DEFAULT false,
13
+ fts_status TEXT DEFAULT 'dirty',
14
+ fts_generation INTEGER DEFAULT 0
11
15
  )
12
16
  `);
13
17
  await db.run(`
@@ -98,19 +102,82 @@ export async function ensureBaseSchema(db) {
98
102
  )
99
103
  `);
100
104
  }
105
+ /**
106
+ * repoテーブルにFTSメタデータ列を追加(Phase 3マイグレーション)
107
+ * 既存DBとの互換性のため、列が存在しない場合のみ追加
108
+ * @param db - DuckDBクライアント
109
+ * @throws Error if migration fails (except when repo table doesn't exist yet)
110
+ */
111
+ export async function ensureRepoMetaColumns(db) {
112
+ // Check if repo table exists first
113
+ const tables = await db.all(`SELECT table_name FROM duckdb_tables() WHERE table_name = 'repo'`);
114
+ if (tables.length === 0) {
115
+ // repo table doesn't exist yet - will be created by ensureBaseSchema()
116
+ return;
117
+ }
118
+ // 列の存在確認
119
+ const columns = await db.all(`SELECT column_name FROM duckdb_columns()
120
+ WHERE table_name = 'repo' AND column_name IN ('fts_last_indexed_at', 'fts_dirty', 'fts_status', 'fts_generation')`);
121
+ const hasLastIndexedAt = columns.some((c) => c.column_name === "fts_last_indexed_at");
122
+ const hasDirty = columns.some((c) => c.column_name === "fts_dirty");
123
+ const hasStatus = columns.some((c) => c.column_name === "fts_status");
124
+ const hasGeneration = columns.some((c) => c.column_name === "fts_generation");
125
+ // fts_last_indexed_atの追加
126
+ if (!hasLastIndexedAt) {
127
+ await db.run(`ALTER TABLE repo ADD COLUMN fts_last_indexed_at TIMESTAMP`);
128
+ }
129
+ // fts_dirtyの追加
130
+ if (!hasDirty) {
131
+ await db.run(`ALTER TABLE repo ADD COLUMN fts_dirty BOOLEAN DEFAULT false`);
132
+ }
133
+ // fts_statusの追加 (Fix #2: FTS rebuild status tracking)
134
+ if (!hasStatus) {
135
+ await db.run(`ALTER TABLE repo ADD COLUMN fts_status TEXT DEFAULT 'dirty'`);
136
+ }
137
+ // fts_generationの追加 (Fix #3: Lost dirty flags prevention)
138
+ if (!hasGeneration) {
139
+ await db.run(`ALTER TABLE repo ADD COLUMN fts_generation INTEGER DEFAULT 0`);
140
+ }
141
+ // 既存レコードの初期化:常にdirty=trueで初期化
142
+ // (rebuildFTSIfNeededが実際のFTS状態を確認して処理を決定)
143
+ // 理由: multi-repo環境で新規repoが誤ってclean扱いされるのを防ぐため
144
+ await db.run(`
145
+ UPDATE repo
146
+ SET fts_dirty = true,
147
+ fts_status = 'dirty'
148
+ WHERE fts_last_indexed_at IS NULL
149
+ `);
150
+ }
101
151
  /**
102
152
  * FTS(全文検索)インデックスの作成を試行
103
153
  * @param db - DuckDBクライアント
154
+ * @param forceRebuild - 強制的に再構築する場合true
104
155
  * @returns FTS拡張が利用可能な場合true、それ以外false
105
156
  */
106
- export async function tryCreateFTSIndex(db) {
157
+ export async function tryCreateFTSIndex(db, forceRebuild = false) {
107
158
  try {
108
159
  // FTS拡張の利用可能性を確認
109
160
  await db.run(`
110
161
  INSTALL fts;
111
162
  LOAD fts;
112
163
  `);
164
+ // forceRebuildが指定されていない場合は既存インデックスを確認
165
+ if (!forceRebuild) {
166
+ const schemaExists = await checkFTSSchemaExists(db);
167
+ if (schemaExists) {
168
+ // インデックスの整合性を検証
169
+ const isValid = await verifyFTSIntegrity(db);
170
+ if (isValid) {
171
+ // 既存の有効なインデックスがあるのでスキップ
172
+ return true;
173
+ }
174
+ // 整合性検証失敗 - 再作成が必要
175
+ console.warn("FTS index integrity check failed, recreating index...");
176
+ }
177
+ }
113
178
  // blob.content に FTS インデックスを作成
179
+ // Phase 2: インデクサー内での利用を想定し、overwrite=1で常に再構築
180
+ // (dirty flag管理により、実際の呼び出しは必要時のみ)
114
181
  await db.run(`
115
182
  PRAGMA create_fts_index('blob', 'hash', 'content', overwrite=1);
116
183
  `);
@@ -122,4 +189,188 @@ export async function tryCreateFTSIndex(db) {
122
189
  return false;
123
190
  }
124
191
  }
192
+ /**
193
+ * FTSスキーマの存在を確認
194
+ * @param db - DuckDBクライアント
195
+ * @returns スキーマが存在する場合true
196
+ */
197
+ export async function checkFTSSchemaExists(db) {
198
+ try {
199
+ const schemas = await db.all(`SELECT schema_name FROM duckdb_schemas() WHERE schema_name = 'fts_main_blob'`);
200
+ return schemas.length > 0;
201
+ }
202
+ catch {
203
+ // クエリ失敗時は存在しないと判断
204
+ return false;
205
+ }
206
+ }
207
+ /**
208
+ * FTSインデックスの整合性を検証
209
+ * @param db - DuckDBクライアント
210
+ * @returns インデックスが有効な場合true
211
+ */
212
+ async function verifyFTSIntegrity(db) {
213
+ try {
214
+ // 必須テーブル(docs, terms)の存在を確認
215
+ const tables = await db.all(`SELECT table_name FROM duckdb_tables()
216
+ WHERE schema_name = 'fts_main_blob' AND table_name IN ('docs', 'terms')`);
217
+ if (tables.length < 2) {
218
+ return false;
219
+ }
220
+ // 実際にクエリを実行して動作確認(軽量チェック)
221
+ // Note: MATCH構文を使用するため、FTS拡張が正しくロードされている必要がある
222
+ await db.all(`SELECT docid FROM fts_main_blob.docs WHERE docs MATCH 'test' LIMIT 1`);
223
+ return true;
224
+ }
225
+ catch {
226
+ // クエリ失敗 = インデックスが破損または不完全
227
+ return false;
228
+ }
229
+ }
230
+ /**
231
+ * FTS拡張の利用可能性のみをチェック(Phase 2: サーバー起動時用)
232
+ * インデックスの作成は行わず、存在確認のみ
233
+ * @param db - DuckDBクライアント
234
+ * @returns FTS拡張がロード可能でインデックスが存在する場合true
235
+ */
236
+ export async function checkFTSAvailability(db) {
237
+ try {
238
+ // FTS拡張のロードを試行
239
+ await db.run(`LOAD fts;`);
240
+ // FTSスキーマの存在確認
241
+ return await checkFTSSchemaExists(db);
242
+ }
243
+ catch {
244
+ // FTS拡張がロードできない、またはスキーマが存在しない
245
+ return false;
246
+ }
247
+ }
248
+ /**
249
+ * dirty flagに基づいてFTSインデックスを条件付きで再構築(Phase 2+3: インデクサー用)
250
+ *
251
+ * @deprecated The `repoId` parameter is currently ignored due to global FTS architecture.
252
+ * Use `rebuildGlobalFTS()` instead for clearer intent. This signature will be removed in v2.0.
253
+ *
254
+ * NOTE: DuckDB FTS index is GLOBAL (one fts_main_blob schema for entire blob table).
255
+ * We check if ANY repo is dirty to avoid partial corruption in multi-repo environments.
256
+ * Future improvement: migrate to dedicated fts_metadata table (see Codex design proposal).
257
+ *
258
+ * @param db - DuckDBクライアント
259
+ * @param repoId - リポジトリID (⚠️ IGNORED: FTS is global, not per-repo)
260
+ * @param forceFTS - FTS再構築を強制する場合true
261
+ * @returns FTSが利用可能な場合true
262
+ */
263
+ export async function rebuildFTSIfNeeded(db, repoId, forceFTS = false) {
264
+ console.warn("rebuildFTSIfNeeded: repoId parameter is deprecated and ignored (FTS is global). Use rebuildGlobalFTS() instead.");
265
+ return rebuildGlobalFTS(db, { forceFTS });
266
+ }
267
+ /**
268
+ * グローバルFTSインデックスを再構築(Fix #4: New API without misleading repoId parameter)
269
+ *
270
+ * NOTE: DuckDB FTS index is GLOBAL (one fts_main_blob schema for entire blob table).
271
+ * This function rebuilds FTS for all repos in the database, with proper status tracking
272
+ * and generation-based dirty flag management to prevent lost concurrent updates.
273
+ *
274
+ * @param db - DuckDBクライアント
275
+ * @param options - オプション設定
276
+ * @param options.forceFTS - FTS再構築を強制する場合true
277
+ * @returns FTSが利用可能な場合true
278
+ */
279
+ export async function rebuildGlobalFTS(db, options = {}) {
280
+ const forceFTS = options.forceFTS ?? false;
281
+ try {
282
+ // メタデータ列の存在確認と初期化
283
+ await ensureRepoMetaColumns(db);
284
+ // CRITICAL: Check if ANY repo is dirty or rebuilding (FTS is global, not per-repo)
285
+ // This prevents multi-repo corruption where one repo's failure breaks all repos
286
+ const statusCheck = await db.all(`SELECT COUNT(*) as count FROM repo
287
+ WHERE fts_dirty = true OR fts_status IN ('dirty', 'rebuilding')`);
288
+ const needsRebuild = (statusCheck[0]?.count ?? 0) > 0;
289
+ const ftsExists = await checkFTSSchemaExists(db);
290
+ // FTS再構築が必要かチェック
291
+ if (forceFTS || needsRebuild || !ftsExists) {
292
+ // Fix #2: Wrap entire rebuild in transaction with status tracking
293
+ // Fix #3: Capture dirty repos' generations to prevent lost updates
294
+ const dirtyRepos = await db.all(`SELECT id, fts_generation FROM repo WHERE fts_dirty = true`);
295
+ if (dirtyRepos.length === 0 && !forceFTS && ftsExists) {
296
+ // No dirty repos and FTS exists - likely another process is rebuilding
297
+ console.info("FTS rebuild already in progress or completed by another process");
298
+ return true;
299
+ }
300
+ // Fix: Wrap metadata updates in transaction for atomicity
301
+ return await db.transaction(async () => {
302
+ // Fix: Set only dirty/dirty-status repos to 'rebuilding' to avoid permanent rebuilding state
303
+ await db.run(`UPDATE repo SET fts_status = 'rebuilding'
304
+ WHERE fts_dirty = true OR fts_status = 'dirty'`);
305
+ console.info("Rebuilding FTS index...");
306
+ // Note: tryCreateFTSIndex must run inside transaction to ensure metadata consistency
307
+ const success = await tryCreateFTSIndex(db, true);
308
+ if (success) {
309
+ // Fix #3 & #5: Clear dirty flags based on rebuild context using parameterized queries
310
+ const generationTargets = forceFTS
311
+ ? await db.all(`SELECT id, fts_generation FROM repo WHERE fts_status = 'rebuilding'`)
312
+ : dirtyRepos;
313
+ if (generationTargets.length > 0) {
314
+ for (const repo of generationTargets) {
315
+ await db.run(`UPDATE repo
316
+ SET fts_dirty = false,
317
+ fts_status = 'clean',
318
+ fts_last_indexed_at = CURRENT_TIMESTAMP
319
+ WHERE id = ? AND fts_generation = ?`, [repo.id, repo.fts_generation]);
320
+ }
321
+ }
322
+ else {
323
+ // No dirty repos but rebuild was needed (e.g., fts schema was missing)
324
+ // Only clear rows that are still marked as rebuilding to avoid wiping
325
+ // fresh dirty flags raised during the rebuild window.
326
+ await db.run(`UPDATE repo
327
+ SET fts_dirty = false,
328
+ fts_status = 'clean',
329
+ fts_last_indexed_at = CURRENT_TIMESTAMP
330
+ WHERE fts_status = 'rebuilding'`);
331
+ }
332
+ console.info("✅ FTS index rebuilt successfully");
333
+ }
334
+ else {
335
+ // Fix #2: On failure, reset status to 'dirty' so next run will retry
336
+ await db.run(`UPDATE repo SET fts_status = 'dirty' WHERE fts_status = 'rebuilding'`);
337
+ console.warn("⚠️ FTS index rebuild failed, will retry on next indexer run");
338
+ }
339
+ return success;
340
+ });
341
+ }
342
+ // 再構築不要
343
+ console.info("FTS index is up to date, skipping rebuild");
344
+ return true;
345
+ }
346
+ catch (error) {
347
+ // On exception, reset any 'rebuilding' status to 'dirty'
348
+ try {
349
+ await db.run(`UPDATE repo SET fts_status = 'dirty' WHERE fts_status = 'rebuilding'`);
350
+ }
351
+ catch {
352
+ // Ignore cleanup errors
353
+ }
354
+ console.warn("Failed to rebuild FTS index:", error);
355
+ return false;
356
+ }
357
+ }
358
+ /**
359
+ * FTS dirty flagを設定(Phase 3: ウォッチモード用)
360
+ * Note: 現在は rebuildFTSIfNeeded() の使用を推奨。この関数は将来のウォッチモード実装用に保持。
361
+ * @param db - DuckDBクライアント
362
+ * @param repoId - リポジトリID
363
+ * @throws Error if database update fails
364
+ */
365
+ export async function setFTSDirty(db, repoId) {
366
+ // Ensure the fts_dirty column exists before trying to update it
367
+ await ensureRepoMetaColumns(db);
368
+ // Update the dirty flag with generation increment (Fix #3: prevents lost updates)
369
+ // Incrementing generation ensures concurrent setFTSDirty calls aren't lost during rebuild
370
+ await db.run(`UPDATE repo
371
+ SET fts_dirty = true,
372
+ fts_status = 'dirty',
373
+ fts_generation = fts_generation + 1
374
+ WHERE id = ?`, [repoId]);
375
+ }
125
376
  //# sourceMappingURL=schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/indexer/schema.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EAAgB;IACrD,MAAM,EAAE,CAAC,GAAG,CAAC;;GAEZ,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,GAAG,CAAC;;;;;;;GAOZ,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,GAAG,CAAC;;;;;;;GAOZ,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,GAAG,CAAC;;;;;;;;;;;;GAYZ,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,GAAG,CAAC;;;;;;;;;;;GAWZ,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,GAAG,CAAC;;GAEZ,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,GAAG,CAAC;;;;;;;;;;;;;GAaZ,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,GAAG,CAAC;;GAEZ,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,GAAG,CAAC;;;;;;;;;;GAUZ,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,GAAG,CAAC;;;;;;;;;GASZ,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,GAAG,CAAC;;GAEZ,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,GAAG,CAAC;;;;;;;;;GASZ,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,EAAgB;IACtD,IAAI,CAAC;QACH,iBAAiB;QACjB,MAAM,EAAE,CAAC,GAAG,CAAC;;;KAGZ,CAAC,CAAC;QAEH,+BAA+B;QAC/B,MAAM,EAAE,CAAC,GAAG,CAAC;;KAEZ,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,gCAAgC;QAChC,OAAO,CAAC,IAAI,CAAC,kDAAkD,EAAE,KAAK,CAAC,CAAC;QACxE,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/indexer/schema.ts"],"names":[],"mappings":"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"}
@@ -45,6 +45,7 @@ export interface WatcherStatistics {
45
45
  */
46
46
  export declare class IndexWatcher {
47
47
  private readonly options;
48
+ private readonly rawRepoRoot;
48
49
  private watcher;
49
50
  private reindexTimer;
50
51
  private isReindexing;
@@ -53,8 +54,26 @@ export declare class IndexWatcher {
53
54
  private pendingFiles;
54
55
  private readonly stats;
55
56
  private readonly lockfilePath;
57
+ private readonly realpathCache;
56
58
  private isStopping;
57
59
  constructor(options: IndexWatcherOptions);
60
+ private getCachedRealPath;
61
+ /**
62
+ * Normalizes absolute file path to repository-relative path.
63
+ *
64
+ * Fix #3: Proper cross-platform path handling to prevent denylist bypass on Windows.
65
+ *
66
+ * Strategy:
67
+ * - Use path.relative() instead of string replacement
68
+ * - Normalize path separator to forward slash (git-compatible)
69
+ * - Reject paths outside repository (security check)
70
+ * - Reject Windows cross-drive paths and UNC paths
71
+ * - Resolve symlinks to prevent bypass via junctions/symlinks
72
+ *
73
+ * @param absPath - Absolute path from file watcher
74
+ * @returns Git-compatible relative path, or null if outside repo
75
+ */
76
+ private normalizePathForRepo;
58
77
  /**
59
78
  * Starts the file watcher and begins monitoring for changes.
60
79
  *
@@ -75,6 +94,8 @@ export declare class IndexWatcher {
75
94
  *
76
95
  * If a reindex is already in progress, marks a pending flag to trigger
77
96
  * another reindex after the current one completes.
97
+ *
98
+ * @param changedPaths - Array of file paths that changed (Fix #3 & #4: snapshot from scheduleReindex)
78
99
  */
79
100
  private executeReindex;
80
101
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../../src/indexer/watch.ts"],"names":[],"mappings":"AAUA;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,mBAAmB,EAAE,MAAM,CAAC;IAC5B,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iCAAiC;IACjC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAMtB;IACF,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,UAAU,CAAS;gBAEf,OAAO,EAAE,mBAAmB;IAiCxC;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4C5B;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IAmCvB;;;;;OAKG;YACW,cAAc;IAqG5B;;;;;OAKG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkC3B;;;;OAIG;IACH,aAAa,IAAI,QAAQ,CAAC,iBAAiB,CAAC;IAI5C;;OAEG;IACH,SAAS,IAAI,OAAO;CAGrB"}
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../../src/indexer/watch.ts"],"names":[],"mappings":"AAYA;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,mBAAmB,EAAE,MAAM,CAAC;IAC5B,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iCAAiC;IACjC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAMtB;IACF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA6B;IAC3D,OAAO,CAAC,UAAU,CAAS;gBAEf,OAAO,EAAE,mBAAmB;IAmDxC,OAAO,CAAC,iBAAiB;IAqBzB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,oBAAoB;IAsC5B;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoF5B;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IA0CvB;;;;;;;OAOG;YACW,cAAc;IA6I5B;;;;;OAKG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkC3B;;;;OAIG;IACH,aAAa,IAAI,QAAQ,CAAC,iBAAiB,CAAC;IAI5C;;OAEG;IACH,SAAS,IAAI,OAAO;CAGrB"}