kiri-mcp-server 0.9.6 → 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.
- package/README.md +94 -7
- package/dist/client/cli.js +68 -0
- package/dist/client/cli.js.map +1 -0
- package/dist/client/index.js +5 -0
- package/dist/client/index.js.map +1 -0
- package/dist/eval/metrics.js +47 -0
- package/dist/eval/metrics.js.map +1 -0
- package/dist/indexer/cli.js +362 -0
- package/dist/indexer/cli.js.map +1 -0
- package/dist/indexer/codeintel.js +182 -0
- package/dist/indexer/codeintel.js.map +1 -0
- package/dist/indexer/git.js +30 -0
- package/dist/indexer/git.js.map +1 -0
- package/dist/indexer/language.js +34 -0
- package/dist/indexer/language.js.map +1 -0
- package/dist/indexer/pipeline/filters/denylist.js +71 -0
- package/dist/indexer/pipeline/filters/denylist.js.map +1 -0
- package/dist/indexer/schema.js +101 -0
- package/dist/indexer/schema.js.map +1 -0
- package/dist/package.json +11 -1
- package/dist/server/bootstrap.js +19 -0
- package/dist/server/bootstrap.js.map +1 -0
- package/dist/server/context.js +1 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/fallbacks/degradeController.js +69 -0
- package/dist/server/fallbacks/degradeController.js.map +1 -0
- package/dist/server/handlers.js +1268 -0
- package/dist/server/handlers.js.map +1 -0
- package/dist/server/main.js +151 -0
- package/dist/server/main.js.map +1 -0
- package/dist/server/observability/metrics.js +56 -0
- package/dist/server/observability/metrics.js.map +1 -0
- package/dist/server/observability/tracing.js +58 -0
- package/dist/server/observability/tracing.js.map +1 -0
- package/dist/server/rpc.js +477 -0
- package/dist/server/rpc.js.map +1 -0
- package/dist/server/runtime.js +47 -0
- package/dist/server/runtime.js.map +1 -0
- package/dist/server/scoring.js +116 -0
- package/dist/server/scoring.js.map +1 -0
- package/dist/server/stdio.js +76 -0
- package/dist/server/stdio.js.map +1 -0
- package/dist/shared/duckdb.js +119 -0
- package/dist/shared/duckdb.js.map +1 -0
- package/dist/shared/embedding.js +98 -0
- package/dist/shared/embedding.js.map +1 -0
- package/dist/shared/index.js +9 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/security/config.js +64 -0
- package/dist/shared/security/config.js.map +1 -0
- package/dist/shared/security/masker.js +56 -0
- package/dist/shared/security/masker.js.map +1 -0
- package/dist/shared/tokenizer.js +4 -0
- package/dist/shared/tokenizer.js.map +1 -0
- package/dist/shared/utils/simpleYaml.js +89 -0
- package/dist/shared/utils/simpleYaml.js.map +1 -0
- package/dist/src/client/proxy.js +2 -1
- package/dist/src/client/proxy.js.map +1 -1
- package/dist/src/client/start-daemon.d.ts.map +1 -1
- package/dist/src/client/start-daemon.js +2 -1
- package/dist/src/client/start-daemon.js.map +1 -1
- package/dist/src/daemon/daemon.js +6 -4
- package/dist/src/daemon/daemon.js.map +1 -1
- package/dist/src/daemon/socket.d.ts +6 -4
- package/dist/src/daemon/socket.d.ts.map +1 -1
- package/dist/src/daemon/socket.js +62 -18
- package/dist/src/daemon/socket.js.map +1 -1
- package/dist/src/indexer/cli.d.ts +1 -0
- package/dist/src/indexer/cli.d.ts.map +1 -1
- package/dist/src/indexer/cli.js +503 -257
- package/dist/src/indexer/cli.js.map +1 -1
- package/dist/src/indexer/codeintel.d.ts +1 -1
- package/dist/src/indexer/codeintel.d.ts.map +1 -1
- package/dist/src/indexer/codeintel.js +296 -3
- package/dist/src/indexer/codeintel.js.map +1 -1
- package/dist/src/indexer/dart/analyze.d.ts +29 -0
- package/dist/src/indexer/dart/analyze.d.ts.map +1 -0
- package/dist/src/indexer/dart/analyze.js +452 -0
- package/dist/src/indexer/dart/analyze.js.map +1 -0
- package/dist/src/indexer/dart/client.d.ts +113 -0
- package/dist/src/indexer/dart/client.d.ts.map +1 -0
- package/dist/src/indexer/dart/client.js +444 -0
- package/dist/src/indexer/dart/client.js.map +1 -0
- package/dist/src/indexer/dart/config.d.ts +36 -0
- package/dist/src/indexer/dart/config.d.ts.map +1 -0
- package/dist/src/indexer/dart/config.js +62 -0
- package/dist/src/indexer/dart/config.js.map +1 -0
- package/dist/src/indexer/dart/dependencies.d.ts +17 -0
- package/dist/src/indexer/dart/dependencies.d.ts.map +1 -0
- package/dist/src/indexer/dart/dependencies.js +102 -0
- package/dist/src/indexer/dart/dependencies.js.map +1 -0
- package/dist/src/indexer/dart/pathKey.d.ts +40 -0
- package/dist/src/indexer/dart/pathKey.d.ts.map +1 -0
- package/dist/src/indexer/dart/pathKey.js +72 -0
- package/dist/src/indexer/dart/pathKey.js.map +1 -0
- package/dist/src/indexer/dart/poolGate.d.ts +57 -0
- package/dist/src/indexer/dart/poolGate.d.ts.map +1 -0
- package/dist/src/indexer/dart/poolGate.js +87 -0
- package/dist/src/indexer/dart/poolGate.js.map +1 -0
- package/dist/src/indexer/dart/sdk.d.ts +40 -0
- package/dist/src/indexer/dart/sdk.d.ts.map +1 -0
- package/dist/src/indexer/dart/sdk.js +167 -0
- package/dist/src/indexer/dart/sdk.js.map +1 -0
- package/dist/src/indexer/dart/transform.d.ts +17 -0
- package/dist/src/indexer/dart/transform.d.ts.map +1 -0
- package/dist/src/indexer/dart/transform.js +157 -0
- package/dist/src/indexer/dart/transform.js.map +1 -0
- package/dist/src/indexer/dart/types.d.ts +137 -0
- package/dist/src/indexer/dart/types.d.ts.map +1 -0
- package/dist/src/indexer/dart/types.js +5 -0
- package/dist/src/indexer/dart/types.js.map +1 -0
- package/dist/src/indexer/git.d.ts +1 -0
- package/dist/src/indexer/git.d.ts.map +1 -1
- package/dist/src/indexer/git.js +8 -0
- package/dist/src/indexer/git.js.map +1 -1
- package/dist/src/indexer/language.d.ts.map +1 -1
- package/dist/src/indexer/language.js +1 -0
- package/dist/src/indexer/language.js.map +1 -1
- package/dist/src/indexer/queue.d.ts +19 -0
- package/dist/src/indexer/queue.d.ts.map +1 -0
- package/dist/src/indexer/queue.js +50 -0
- package/dist/src/indexer/queue.js.map +1 -0
- package/dist/src/indexer/schema.d.ts +61 -1
- package/dist/src/indexer/schema.d.ts.map +1 -1
- package/dist/src/indexer/schema.js +253 -2
- package/dist/src/indexer/schema.js.map +1 -1
- package/dist/src/indexer/watch.d.ts +21 -0
- package/dist/src/indexer/watch.d.ts.map +1 -1
- package/dist/src/indexer/watch.js +189 -28
- package/dist/src/indexer/watch.js.map +1 -1
- package/dist/src/server/context.d.ts +7 -0
- package/dist/src/server/context.d.ts.map +1 -1
- package/dist/src/server/handlers.d.ts.map +1 -1
- package/dist/src/server/handlers.js +87 -4
- package/dist/src/server/handlers.js.map +1 -1
- package/dist/src/server/indexBootstrap.d.ts.map +1 -1
- package/dist/src/server/indexBootstrap.js +4 -1
- package/dist/src/server/indexBootstrap.js.map +1 -1
- package/dist/src/server/main.js +0 -0
- package/dist/src/server/runtime.d.ts.map +1 -1
- package/dist/src/server/runtime.js +45 -6
- package/dist/src/server/runtime.js.map +1 -1
- package/dist/src/shared/duckdb.d.ts.map +1 -1
- package/dist/src/shared/duckdb.js +9 -0
- package/dist/src/shared/duckdb.js.map +1 -1
- package/dist/src/shared/utils/path.d.ts +46 -0
- package/dist/src/shared/utils/path.d.ts.map +1 -0
- package/dist/src/shared/utils/path.js +94 -0
- package/dist/src/shared/utils/path.js.map +1 -0
- package/dist/src/shared/utils/socket.d.ts +61 -0
- package/dist/src/shared/utils/socket.d.ts.map +1 -0
- package/dist/src/shared/utils/socket.js +156 -0
- package/dist/src/shared/utils/socket.js.map +1 -0
- package/package.json +11 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { realpathSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { resolve, relative, sep, dirname, isAbsolute } from "node:path";
|
|
2
3
|
import { performance } from "node:perf_hooks";
|
|
3
4
|
import { watch } from "chokidar";
|
|
4
5
|
import { acquireLock, releaseLock, getLockOwner, LockfileError } from "../shared/utils/lockfile.js";
|
|
6
|
+
import { normalizeDbPath, normalizeRepoPath } from "../shared/utils/path.js";
|
|
5
7
|
import { runIndexer } from "./cli.js";
|
|
6
8
|
import { createDenylistFilter } from "./pipeline/filters/denylist.js";
|
|
7
9
|
/**
|
|
@@ -21,6 +23,7 @@ import { createDenylistFilter } from "./pipeline/filters/denylist.js";
|
|
|
21
23
|
*/
|
|
22
24
|
export class IndexWatcher {
|
|
23
25
|
options;
|
|
26
|
+
rawRepoRoot;
|
|
24
27
|
watcher = null;
|
|
25
28
|
reindexTimer = null;
|
|
26
29
|
isReindexing = false;
|
|
@@ -29,11 +32,28 @@ export class IndexWatcher {
|
|
|
29
32
|
pendingFiles = new Set();
|
|
30
33
|
stats;
|
|
31
34
|
lockfilePath;
|
|
35
|
+
realpathCache = new Map();
|
|
32
36
|
isStopping = false; // Flag to prevent new reindexes during shutdown
|
|
33
37
|
constructor(options) {
|
|
38
|
+
this.rawRepoRoot = resolve(options.repoRoot);
|
|
39
|
+
const repoRoot = normalizeRepoPath(this.rawRepoRoot);
|
|
40
|
+
let databasePath;
|
|
41
|
+
// Fix #2: Ensure parent directory exists BEFORE normalization
|
|
42
|
+
// This guarantees consistent path normalization on first and subsequent runs
|
|
43
|
+
// Using sync version because constructors can't be async
|
|
44
|
+
try {
|
|
45
|
+
const parentDir = dirname(resolve(options.databasePath));
|
|
46
|
+
mkdirSync(parentDir, { recursive: true });
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Ignore if already exists or permission denied
|
|
50
|
+
}
|
|
51
|
+
// Critical: Use normalizeDbPath to ensure consistent path with cli.ts
|
|
52
|
+
// This prevents lock file and queue key mismatch
|
|
53
|
+
databasePath = normalizeDbPath(options.databasePath);
|
|
34
54
|
this.options = {
|
|
35
|
-
repoRoot
|
|
36
|
-
databasePath
|
|
55
|
+
repoRoot,
|
|
56
|
+
databasePath,
|
|
37
57
|
debounceMs: options.debounceMs ?? 500,
|
|
38
58
|
};
|
|
39
59
|
if (options.configPath) {
|
|
@@ -57,6 +77,72 @@ export class IndexWatcher {
|
|
|
57
77
|
});
|
|
58
78
|
}
|
|
59
79
|
}
|
|
80
|
+
getCachedRealPath(absPath) {
|
|
81
|
+
const cached = this.realpathCache.get(absPath);
|
|
82
|
+
if (cached) {
|
|
83
|
+
return cached;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const realPath = realpathSync.native(absPath);
|
|
87
|
+
this.realpathCache.set(absPath, realPath);
|
|
88
|
+
if (this.realpathCache.size > 2048) {
|
|
89
|
+
const key = this.realpathCache.keys().next().value;
|
|
90
|
+
if (key) {
|
|
91
|
+
this.realpathCache.delete(key);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return realPath;
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Normalizes absolute file path to repository-relative path.
|
|
102
|
+
*
|
|
103
|
+
* Fix #3: Proper cross-platform path handling to prevent denylist bypass on Windows.
|
|
104
|
+
*
|
|
105
|
+
* Strategy:
|
|
106
|
+
* - Use path.relative() instead of string replacement
|
|
107
|
+
* - Normalize path separator to forward slash (git-compatible)
|
|
108
|
+
* - Reject paths outside repository (security check)
|
|
109
|
+
* - Reject Windows cross-drive paths and UNC paths
|
|
110
|
+
* - Resolve symlinks to prevent bypass via junctions/symlinks
|
|
111
|
+
*
|
|
112
|
+
* @param absPath - Absolute path from file watcher
|
|
113
|
+
* @returns Git-compatible relative path, or null if outside repo
|
|
114
|
+
*/
|
|
115
|
+
normalizePathForRepo(absPath) {
|
|
116
|
+
const rel = relative(this.options.repoRoot, absPath);
|
|
117
|
+
// Fix #3: Security - Reject paths outside repository
|
|
118
|
+
// - Parent directory traversal: ".."
|
|
119
|
+
// - Absolute paths (Unix): starts with "/"
|
|
120
|
+
// - Absolute paths (Windows): starts with drive letter "C:" or "C:\"
|
|
121
|
+
// - UNC paths (Windows): starts with "\\" or "//"
|
|
122
|
+
// Note: Empty string is ALLOWED (represents repo root for chokidar directory watching)
|
|
123
|
+
if (rel.startsWith("..") ||
|
|
124
|
+
isAbsolute(rel) ||
|
|
125
|
+
/^[A-Za-z]:/.test(rel) ||
|
|
126
|
+
rel.startsWith("\\\\") ||
|
|
127
|
+
rel.startsWith("//")) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
// Fix #3: Additional safety - Resolve symlinks once and cache the result
|
|
131
|
+
// This prevents bypass via junction points or symlinks pointing outside the repo
|
|
132
|
+
const realAbsPath = this.getCachedRealPath(absPath);
|
|
133
|
+
if (realAbsPath) {
|
|
134
|
+
const realRepoRoot = this.options.repoRoot; // Already normalized in constructor
|
|
135
|
+
const realRel = relative(realRepoRoot, realAbsPath);
|
|
136
|
+
// Double-check the real path is still inside repo
|
|
137
|
+
if (realRel.startsWith("..") || isAbsolute(realRel)) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Allow empty string (repo root itself) for chokidar directory watching
|
|
142
|
+
// Normalize to forward slash for cross-platform compatibility
|
|
143
|
+
// Windows uses backslash, but git and denylist rules expect forward slash
|
|
144
|
+
return rel.split(sep).join("/");
|
|
145
|
+
}
|
|
60
146
|
/**
|
|
61
147
|
* Starts the file watcher and begins monitoring for changes.
|
|
62
148
|
*
|
|
@@ -73,7 +159,11 @@ export class IndexWatcher {
|
|
|
73
159
|
persistent: true,
|
|
74
160
|
ignoreInitial: true, // Don't trigger on existing files
|
|
75
161
|
ignored: (path) => {
|
|
76
|
-
const relativePath =
|
|
162
|
+
const relativePath = this.normalizePathForRepo(path);
|
|
163
|
+
// Reject paths outside repo or invalid paths (explicit null check, not falsy check)
|
|
164
|
+
if (relativePath === null) {
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
77
167
|
return denylistFilter.isDenied(relativePath);
|
|
78
168
|
},
|
|
79
169
|
// Editor-specific handling
|
|
@@ -85,17 +175,47 @@ export class IndexWatcher {
|
|
|
85
175
|
usePolling: false, // Use native OS events (faster)
|
|
86
176
|
// depth option omitted for no depth limit
|
|
87
177
|
});
|
|
88
|
-
//
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
178
|
+
// Return promise that resolves when watcher is fully initialized
|
|
179
|
+
return new Promise((resolve, reject) => {
|
|
180
|
+
const watcher = this.watcher;
|
|
181
|
+
let settled = false;
|
|
182
|
+
const settle = (cb) => {
|
|
183
|
+
if (settled) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
settled = true;
|
|
187
|
+
cb();
|
|
188
|
+
};
|
|
189
|
+
const handleError = (error) => {
|
|
190
|
+
process.stderr.write(`❌ File watcher error: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
191
|
+
if (this.watcher) {
|
|
192
|
+
void this.watcher.close().catch(() => {
|
|
193
|
+
/* ignore */
|
|
194
|
+
});
|
|
195
|
+
this.watcher = null;
|
|
196
|
+
}
|
|
197
|
+
settle(() => {
|
|
198
|
+
reject(new Error(`Failed to start watch mode: ${error instanceof Error ? error.message : String(error)}`));
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
// Register event handlers
|
|
202
|
+
watcher
|
|
203
|
+
.on("add", (path) => {
|
|
204
|
+
this.scheduleReindex("add", path);
|
|
205
|
+
})
|
|
206
|
+
.on("change", (path) => {
|
|
207
|
+
this.scheduleReindex("change", path);
|
|
208
|
+
})
|
|
209
|
+
.on("unlink", (path) => {
|
|
210
|
+
this.scheduleReindex("unlink", path);
|
|
211
|
+
})
|
|
212
|
+
.on("error", handleError)
|
|
213
|
+
.once("ready", () => {
|
|
214
|
+
watcher.off("error", handleError);
|
|
215
|
+
process.stderr.write(`👁️ Watch mode started. Monitoring ${this.options.repoRoot} for changes...\n`);
|
|
216
|
+
process.stderr.write(` Debounce: ${this.options.debounceMs}ms\n`);
|
|
217
|
+
settle(resolve);
|
|
218
|
+
});
|
|
99
219
|
});
|
|
100
220
|
}
|
|
101
221
|
/**
|
|
@@ -111,7 +231,11 @@ export class IndexWatcher {
|
|
|
111
231
|
if (this.isStopping) {
|
|
112
232
|
return;
|
|
113
233
|
}
|
|
114
|
-
const relativePath =
|
|
234
|
+
const relativePath = this.normalizePathForRepo(path);
|
|
235
|
+
// Ignore paths outside repository (security check)
|
|
236
|
+
if (!relativePath) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
115
239
|
this.pendingFiles.add(relativePath);
|
|
116
240
|
// Clear existing timer if present
|
|
117
241
|
if (this.reindexTimer !== null) {
|
|
@@ -126,9 +250,11 @@ export class IndexWatcher {
|
|
|
126
250
|
const moreCount = Math.max(0, this.pendingFiles.size - 5);
|
|
127
251
|
const summary = moreCount > 0 ? `${fileList} (+${moreCount} more)` : fileList;
|
|
128
252
|
process.stderr.write(`\n📝 File changes detected: ${summary}\n`);
|
|
129
|
-
//
|
|
253
|
+
// Fix #3 & #4: Capture snapshot BEFORE clearing to prevent data loss and enable incremental indexing
|
|
254
|
+
const changedPaths = Array.from(this.pendingFiles);
|
|
130
255
|
this.pendingFiles.clear();
|
|
131
|
-
|
|
256
|
+
// Pass snapshot to executeReindex
|
|
257
|
+
void this.executeReindex(changedPaths);
|
|
132
258
|
}, this.options.debounceMs);
|
|
133
259
|
// Mark pending flag (used if reindex is already running)
|
|
134
260
|
this.pendingReindex = true;
|
|
@@ -138,8 +264,10 @@ export class IndexWatcher {
|
|
|
138
264
|
*
|
|
139
265
|
* If a reindex is already in progress, marks a pending flag to trigger
|
|
140
266
|
* another reindex after the current one completes.
|
|
267
|
+
*
|
|
268
|
+
* @param changedPaths - Array of file paths that changed (Fix #3 & #4: snapshot from scheduleReindex)
|
|
141
269
|
*/
|
|
142
|
-
async executeReindex() {
|
|
270
|
+
async executeReindex(changedPaths) {
|
|
143
271
|
// Don't start reindex if watcher is stopping
|
|
144
272
|
if (this.isStopping) {
|
|
145
273
|
process.stderr.write(`🛑 Watcher stopping. Skipping reindex.\n`);
|
|
@@ -147,6 +275,10 @@ export class IndexWatcher {
|
|
|
147
275
|
}
|
|
148
276
|
// Check if already reindexing
|
|
149
277
|
if (this.isReindexing) {
|
|
278
|
+
// Fix #6: Restore changedPaths back to pendingFiles to prevent data loss
|
|
279
|
+
for (const path of changedPaths) {
|
|
280
|
+
this.pendingFiles.add(path);
|
|
281
|
+
}
|
|
150
282
|
process.stderr.write(`⏳ Reindex already in progress. Will reindex again after completion.\n`);
|
|
151
283
|
this.pendingReindex = true;
|
|
152
284
|
return;
|
|
@@ -154,10 +286,12 @@ export class IndexWatcher {
|
|
|
154
286
|
this.isReindexing = true;
|
|
155
287
|
this.pendingReindex = false;
|
|
156
288
|
this.stats.lastReindexStart = performance.now();
|
|
157
|
-
//
|
|
158
|
-
|
|
289
|
+
// Fix #3 & #4: Use changedPaths parameter (snapshot from scheduleReindex) instead of reading pendingFiles
|
|
290
|
+
// This prevents data loss on lock contention and enables true incremental indexing
|
|
159
291
|
// Create and store the reindex promise for proper shutdown handling
|
|
160
292
|
this.reindexPromise = (async () => {
|
|
293
|
+
// Fix #1: Track lock ownership to prevent releasing locks we don't own
|
|
294
|
+
let lockAcquired = false;
|
|
161
295
|
try {
|
|
162
296
|
// Double-check stopping flag before acquiring lock
|
|
163
297
|
if (this.isStopping) {
|
|
@@ -167,12 +301,18 @@ export class IndexWatcher {
|
|
|
167
301
|
// Acquire lock to prevent concurrent indexing
|
|
168
302
|
try {
|
|
169
303
|
acquireLock(this.lockfilePath);
|
|
304
|
+
lockAcquired = true; // Fix #1: Only set to true on successful acquisition
|
|
170
305
|
}
|
|
171
306
|
catch (error) {
|
|
172
307
|
if (error instanceof LockfileError) {
|
|
308
|
+
// Fix #3: Restore changedPaths to pendingFiles to prevent data loss
|
|
309
|
+
for (const path of changedPaths) {
|
|
310
|
+
this.pendingFiles.add(path);
|
|
311
|
+
}
|
|
312
|
+
this.pendingReindex = true; // Mark for retry when lock is available
|
|
173
313
|
const ownerPid = error.ownerPid ?? getLockOwner(this.lockfilePath);
|
|
174
314
|
const ownerInfo = ownerPid ? ` (PID: ${ownerPid})` : "";
|
|
175
|
-
process.stderr.write(`⚠️ Another indexing process${ownerInfo} holds the lock.
|
|
315
|
+
process.stderr.write(`⚠️ Another indexing process${ownerInfo} holds the lock. Changes queued for retry.\n`);
|
|
176
316
|
return;
|
|
177
317
|
}
|
|
178
318
|
throw error;
|
|
@@ -181,10 +321,11 @@ export class IndexWatcher {
|
|
|
181
321
|
const start = performance.now();
|
|
182
322
|
process.stderr.write(`🔄 Incrementally reindexing ${changedPaths.length} file(s)...\n`);
|
|
183
323
|
await runIndexer({
|
|
184
|
-
repoRoot: this.
|
|
324
|
+
repoRoot: this.rawRepoRoot,
|
|
185
325
|
databasePath: this.options.databasePath,
|
|
186
326
|
full: false,
|
|
187
327
|
changedPaths,
|
|
328
|
+
skipLocking: true, // Fix #1: Watcher already holds the lock
|
|
188
329
|
});
|
|
189
330
|
const duration = performance.now() - start;
|
|
190
331
|
this.stats.reindexCount++;
|
|
@@ -198,22 +339,42 @@ export class IndexWatcher {
|
|
|
198
339
|
}
|
|
199
340
|
}
|
|
200
341
|
catch (error) {
|
|
342
|
+
// Fix #2: Restore changedPaths for ALL errors, not just LockfileError
|
|
343
|
+
// This prevents permanent data loss when reindex fails due to:
|
|
344
|
+
// - Database I/O errors
|
|
345
|
+
// - Parsing failures
|
|
346
|
+
// - Network timeouts
|
|
347
|
+
// - Any other transient errors
|
|
348
|
+
for (const path of changedPaths) {
|
|
349
|
+
this.pendingFiles.add(path);
|
|
350
|
+
}
|
|
351
|
+
this.pendingReindex = true;
|
|
201
352
|
process.stderr.write(`❌ Reindex failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
202
|
-
process.stderr.write(`
|
|
353
|
+
process.stderr.write(` Changes queued for retry on next file event.\n`);
|
|
203
354
|
}
|
|
204
355
|
finally {
|
|
205
356
|
this.isReindexing = false;
|
|
206
|
-
|
|
357
|
+
// Fix #1: Only release lock if we acquired it (prevents deleting other process's locks)
|
|
358
|
+
if (lockAcquired) {
|
|
359
|
+
releaseLock(this.lockfilePath);
|
|
360
|
+
}
|
|
207
361
|
this.reindexPromise = null;
|
|
208
362
|
// Clear timer to prevent resource leak
|
|
209
363
|
if (this.reindexTimer !== null) {
|
|
210
364
|
clearTimeout(this.reindexTimer);
|
|
211
365
|
this.reindexTimer = null;
|
|
212
366
|
}
|
|
213
|
-
// If more changes occurred during reindex,
|
|
214
|
-
if (this.pendingReindex) {
|
|
367
|
+
// Fix #7: If more changes occurred during reindex, trigger direct retry
|
|
368
|
+
if (this.pendingReindex && this.pendingFiles.size > 0) {
|
|
215
369
|
process.stderr.write(`🔁 New changes detected during reindex. Scheduling another reindex...\n`);
|
|
216
|
-
|
|
370
|
+
// Direct retry without file system event dependency
|
|
371
|
+
// Don't clear pendingFiles here - let the timer callback handle it
|
|
372
|
+
this.reindexTimer = setTimeout(() => {
|
|
373
|
+
this.reindexTimer = null;
|
|
374
|
+
const changedPaths = Array.from(this.pendingFiles);
|
|
375
|
+
this.pendingFiles.clear();
|
|
376
|
+
void this.executeReindex(changedPaths);
|
|
377
|
+
}, this.options.debounceMs);
|
|
217
378
|
}
|
|
218
379
|
}
|
|
219
380
|
})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../../src/indexer/watch.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../../src/indexer/watch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { DuckDBClient } from "../shared/duckdb.js";
|
|
2
2
|
import { WarningManager } from "./rpc.js";
|
|
3
|
+
export interface FtsStatusCache {
|
|
4
|
+
ready: boolean;
|
|
5
|
+
schemaExists: boolean;
|
|
6
|
+
anyDirty: boolean;
|
|
7
|
+
lastChecked: number;
|
|
8
|
+
}
|
|
3
9
|
export interface ServerContext {
|
|
4
10
|
db: DuckDBClient;
|
|
5
11
|
repoId: number;
|
|
6
12
|
features?: {
|
|
7
13
|
fts?: boolean;
|
|
8
14
|
};
|
|
15
|
+
ftsStatusCache?: FtsStatusCache;
|
|
9
16
|
warningManager: WarningManager;
|
|
10
17
|
}
|
|
11
18
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/server/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,YAAY,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE;QACT,GAAG,CAAC,EAAE,OAAO,CAAC;KACf,CAAC;IACF,cAAc,EAAE,cAAc,CAAC;CAChC"}
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/server/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,YAAY,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE;QACT,GAAG,CAAC,EAAE,OAAO,CAAC;KACf,CAAC;IACF,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;CAChC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../src/server/handlers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../src/server/handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { checkFTSSchemaExists } from "../indexer/schema.js";
|
|
2
3
|
import { generateEmbedding, structuralSimilarity } from "../shared/embedding.js";
|
|
3
4
|
import { encode as encodeGPT, tokenizeText } from "../shared/tokenizer.js";
|
|
5
|
+
import { getRepoPathCandidates, normalizeRepoPath } from "../shared/utils/path.js";
|
|
4
6
|
import { coerceProfileName, loadScoringProfile } from "./scoring.js";
|
|
5
7
|
// Configuration file patterns (v0.8.0+: consolidated to avoid duplication)
|
|
6
8
|
// Comprehensive list covering multiple languages and tools
|
|
@@ -127,6 +129,67 @@ const CONFIG_PATTERNS = [
|
|
|
127
129
|
".circleci/config.yml",
|
|
128
130
|
".github/workflows",
|
|
129
131
|
];
|
|
132
|
+
const FTS_STATUS_CACHE_TTL_MS = 10_000;
|
|
133
|
+
async function hasDirtyRepos(db) {
|
|
134
|
+
const statusCheck = await db.all(`SELECT COUNT(*) as count FROM repo
|
|
135
|
+
WHERE fts_dirty = true OR fts_status IN ('dirty', 'rebuilding')`);
|
|
136
|
+
return (statusCheck[0]?.count ?? 0) > 0;
|
|
137
|
+
}
|
|
138
|
+
async function refreshFtsStatus(context) {
|
|
139
|
+
const previousReady = context.features?.fts ?? false;
|
|
140
|
+
const cache = {
|
|
141
|
+
ready: false,
|
|
142
|
+
schemaExists: false,
|
|
143
|
+
anyDirty: false,
|
|
144
|
+
lastChecked: Date.now(),
|
|
145
|
+
};
|
|
146
|
+
try {
|
|
147
|
+
cache.schemaExists = await checkFTSSchemaExists(context.db);
|
|
148
|
+
if (!cache.schemaExists) {
|
|
149
|
+
context.warningManager.warnForRequest("fts-schema-missing", "FTS schema not found, falling back to ILIKE");
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
cache.anyDirty = await hasDirtyRepos(context.db);
|
|
153
|
+
if (cache.anyDirty) {
|
|
154
|
+
context.warningManager.warnForRequest("fts-stale", "FTS index is stale or rebuilding, using ILIKE fallback. Run indexer to update FTS.");
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
await context.db.run("LOAD fts;");
|
|
158
|
+
cache.ready = true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
cache.ready = false;
|
|
164
|
+
cache.schemaExists = false;
|
|
165
|
+
context.warningManager.warnForRequest("fts-check-failed", `FTS availability check failed: ${error}`);
|
|
166
|
+
}
|
|
167
|
+
if (!context.features) {
|
|
168
|
+
context.features = {};
|
|
169
|
+
}
|
|
170
|
+
context.features.fts = cache.ready;
|
|
171
|
+
context.ftsStatusCache = cache;
|
|
172
|
+
if (cache.ready && !previousReady) {
|
|
173
|
+
console.info("✅ FTS recovered and enabled");
|
|
174
|
+
}
|
|
175
|
+
else if (!cache.ready && previousReady) {
|
|
176
|
+
console.warn("⚠️ FTS became unavailable; falling back to ILIKE");
|
|
177
|
+
}
|
|
178
|
+
return cache;
|
|
179
|
+
}
|
|
180
|
+
async function getFreshFtsStatus(context) {
|
|
181
|
+
const cache = context.ftsStatusCache;
|
|
182
|
+
if (cache && Date.now() - cache.lastChecked < FTS_STATUS_CACHE_TTL_MS) {
|
|
183
|
+
if (cache.ready) {
|
|
184
|
+
const dirtyNow = await hasDirtyRepos(context.db);
|
|
185
|
+
if (dirtyNow) {
|
|
186
|
+
return refreshFtsStatus(context);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return cache;
|
|
190
|
+
}
|
|
191
|
+
return refreshFtsStatus(context);
|
|
192
|
+
}
|
|
130
193
|
/**
|
|
131
194
|
* Check if a file path represents a configuration file
|
|
132
195
|
* Supports multiple languages: JS/TS, Python, Ruby, Go, PHP, Java, Rust, C/C++, Docker, CI/CD
|
|
@@ -634,8 +697,14 @@ function applyFileTypeBoost(path, baseScore, profile = "default", weights) {
|
|
|
634
697
|
".git/",
|
|
635
698
|
"node_modules/",
|
|
636
699
|
];
|
|
637
|
-
|
|
638
|
-
|
|
700
|
+
for (const dir of blacklistedDirs) {
|
|
701
|
+
if (path.startsWith(dir)) {
|
|
702
|
+
// FIX: boost_profile="docs" の場合は docs/ ブラックリストをスキップ
|
|
703
|
+
if (profile === "docs" && dir === "docs/") {
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
return -100; // Effectively remove it
|
|
707
|
+
}
|
|
639
708
|
}
|
|
640
709
|
if (profile === "none") {
|
|
641
710
|
return baseScore;
|
|
@@ -913,7 +982,8 @@ export async function filesSearch(context, params) {
|
|
|
913
982
|
throw new Error("files_search requires a non-empty query. Provide a search keyword to continue.");
|
|
914
983
|
}
|
|
915
984
|
const limit = normalizeLimit(params.limit);
|
|
916
|
-
const
|
|
985
|
+
const ftsStatus = await getFreshFtsStatus(context);
|
|
986
|
+
const hasFTS = ftsStatus.ready;
|
|
917
987
|
let sql;
|
|
918
988
|
let values;
|
|
919
989
|
if (hasFTS) {
|
|
@@ -1669,14 +1739,27 @@ export async function depsClosure(context, params) {
|
|
|
1669
1739
|
}
|
|
1670
1740
|
export async function resolveRepoId(db, repoRoot) {
|
|
1671
1741
|
try {
|
|
1672
|
-
const
|
|
1742
|
+
const candidates = getRepoPathCandidates(repoRoot);
|
|
1743
|
+
const normalized = candidates[0];
|
|
1744
|
+
const placeholders = candidates.map(() => "?").join(", ");
|
|
1745
|
+
const rows = await db.all(`SELECT id, root FROM repo WHERE root IN (${placeholders}) LIMIT 1`, candidates);
|
|
1673
1746
|
if (rows.length === 0) {
|
|
1747
|
+
const existingRows = await db.all("SELECT id, root FROM repo");
|
|
1748
|
+
for (const candidate of existingRows) {
|
|
1749
|
+
if (normalizeRepoPath(candidate.root) === normalized) {
|
|
1750
|
+
await db.run("UPDATE repo SET root = ? WHERE id = ?", [normalized, candidate.id]);
|
|
1751
|
+
return candidate.id;
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1674
1754
|
throw new Error("Target repository is missing from DuckDB. Run the indexer before starting the server.");
|
|
1675
1755
|
}
|
|
1676
1756
|
const row = rows[0];
|
|
1677
1757
|
if (!row) {
|
|
1678
1758
|
throw new Error("Failed to retrieve repository record. Database returned empty result.");
|
|
1679
1759
|
}
|
|
1760
|
+
if (row.root !== normalized) {
|
|
1761
|
+
await db.run("UPDATE repo SET root = ? WHERE id = ?", [normalized, row.id]);
|
|
1762
|
+
}
|
|
1680
1763
|
return row.id;
|
|
1681
1764
|
}
|
|
1682
1765
|
catch (error) {
|