codesift-mcp 0.2.3 → 0.2.5
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/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +4 -0
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/hooks.d.ts +1 -0
- package/dist/cli/hooks.d.ts.map +1 -1
- package/dist/cli/hooks.js +68 -1
- package/dist/cli/hooks.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +11 -0
- package/dist/cli/setup.js.map +1 -1
- package/dist/formatters-shortening.d.ts +2 -0
- package/dist/formatters-shortening.d.ts.map +1 -1
- package/dist/formatters-shortening.js +33 -0
- package/dist/formatters-shortening.js.map +1 -1
- package/dist/instructions.d.ts +1 -1
- package/dist/instructions.d.ts.map +1 -1
- package/dist/instructions.js +7 -7
- package/dist/register-tools.d.ts.map +1 -1
- package/dist/register-tools.js +60 -7
- package/dist/register-tools.js.map +1 -1
- package/dist/server-helpers.d.ts.map +1 -1
- package/dist/server-helpers.js +18 -2
- package/dist/server-helpers.js.map +1 -1
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +13 -0
- package/dist/server.js.map +1 -1
- package/dist/storage/session-state.d.ts +71 -0
- package/dist/storage/session-state.d.ts.map +1 -0
- package/dist/storage/session-state.js +413 -0
- package/dist/storage/session-state.js.map +1 -0
- package/dist/tools/index-tools.d.ts +5 -0
- package/dist/tools/index-tools.d.ts.map +1 -1
- package/dist/tools/index-tools.js +44 -1
- package/dist/tools/index-tools.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
import { getSessionId } from "./usage-tracker.js";
|
|
2
|
+
import { writeFileSync, renameSync, unlinkSync, readdirSync, statSync, mkdirSync } from "node:fs";
|
|
3
|
+
import { join, dirname } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Module-level singleton
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
function createInitialState() {
|
|
9
|
+
return {
|
|
10
|
+
sessionId: getSessionId(),
|
|
11
|
+
startedAt: Date.now(),
|
|
12
|
+
callCount: 0,
|
|
13
|
+
exploredSymbols: new Map(),
|
|
14
|
+
exploredFiles: new Map(),
|
|
15
|
+
queries: [],
|
|
16
|
+
negativeEvidence: [],
|
|
17
|
+
h10Emitted: false,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
let state = createInitialState();
|
|
21
|
+
let debounceTimer = null;
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Public API — read access
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
export function getSessionState() {
|
|
26
|
+
return state;
|
|
27
|
+
}
|
|
28
|
+
export function getCallCount() {
|
|
29
|
+
return state.callCount;
|
|
30
|
+
}
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Reset — for test isolation and server-helpers delegation
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
export function resetSession() {
|
|
35
|
+
state = createInitialState();
|
|
36
|
+
// Clear any pending sidecar flush timer (CQ22)
|
|
37
|
+
if (debounceTimer) {
|
|
38
|
+
clearTimeout(debounceTimer);
|
|
39
|
+
debounceTimer = null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// Recording — called from wrapTool() on every tool call
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Caps
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
const MAX_SYMBOLS = 500;
|
|
49
|
+
const MAX_FILES = 300;
|
|
50
|
+
const MAX_QUERIES = 200;
|
|
51
|
+
const MAX_NEGATIVE_EVIDENCE = 300;
|
|
52
|
+
function evictLRU(map, maxSize) {
|
|
53
|
+
while (map.size > maxSize) {
|
|
54
|
+
let oldestKey;
|
|
55
|
+
let oldestTime = Infinity;
|
|
56
|
+
for (const [key, entry] of map) {
|
|
57
|
+
if (entry.lastSeen < oldestTime) {
|
|
58
|
+
oldestTime = entry.lastSeen;
|
|
59
|
+
oldestKey = key;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (oldestKey)
|
|
63
|
+
map.delete(oldestKey);
|
|
64
|
+
else
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function enforceQueryCap() {
|
|
69
|
+
while (state.queries.length > MAX_QUERIES) {
|
|
70
|
+
state.queries.shift();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function enforceNegativeEvidenceCap() {
|
|
74
|
+
while (state.negativeEvidence.length > MAX_NEGATIVE_EVIDENCE) {
|
|
75
|
+
// Evict stale entries first, then oldest
|
|
76
|
+
const staleIdx = state.negativeEvidence.findIndex(e => e.stale);
|
|
77
|
+
if (staleIdx !== -1) {
|
|
78
|
+
state.negativeEvidence.splice(staleIdx, 1);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
state.negativeEvidence.shift();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/** Search tools that produce negative evidence on zero results */
|
|
86
|
+
export const SEARCH_TOOL_SET = new Set([
|
|
87
|
+
"search_text", "search_symbols", "codebase_retrieval",
|
|
88
|
+
"semantic_search", "find_references",
|
|
89
|
+
]);
|
|
90
|
+
function addSymbol(symbolId, name, file) {
|
|
91
|
+
const now = Date.now();
|
|
92
|
+
const existing = state.exploredSymbols.get(symbolId);
|
|
93
|
+
if (existing) {
|
|
94
|
+
existing.lastSeen = now;
|
|
95
|
+
existing.accessCount++;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
state.exploredSymbols.set(symbolId, {
|
|
99
|
+
symbolId, name, file, firstSeen: now, lastSeen: now, accessCount: 1,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function addFile(path) {
|
|
104
|
+
const now = Date.now();
|
|
105
|
+
const existing = state.exploredFiles.get(path);
|
|
106
|
+
if (existing) {
|
|
107
|
+
existing.lastSeen = now;
|
|
108
|
+
existing.accessCount++;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
state.exploredFiles.set(path, {
|
|
112
|
+
path, firstSeen: now, lastSeen: now, accessCount: 1,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function extractSymbolsFromResult(resultData) {
|
|
117
|
+
if (!resultData || typeof resultData !== "object")
|
|
118
|
+
return;
|
|
119
|
+
const obj = resultData;
|
|
120
|
+
// search_symbols, get_symbols → symbols array
|
|
121
|
+
if (Array.isArray(obj["symbols"])) {
|
|
122
|
+
for (const sym of obj["symbols"]) {
|
|
123
|
+
if (sym && typeof sym === "object") {
|
|
124
|
+
const s = sym;
|
|
125
|
+
const id = (s["id"] ?? s["symbolId"] ?? s["symbol_id"]);
|
|
126
|
+
if (id && typeof id === "string") {
|
|
127
|
+
addSymbol(id, String(s["name"] ?? ""), String(s["file"] ?? ""));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// get_symbol → single symbol with id field
|
|
133
|
+
if (typeof obj["id"] === "string" && typeof obj["name"] === "string") {
|
|
134
|
+
addSymbol(obj["id"], obj["name"], String(obj["file"] ?? ""));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function extractFilesFromResult(resultData) {
|
|
138
|
+
if (!resultData || typeof resultData !== "object")
|
|
139
|
+
return;
|
|
140
|
+
const obj = resultData;
|
|
141
|
+
// get_file_outline → file field
|
|
142
|
+
if (typeof obj["file"] === "string") {
|
|
143
|
+
addFile(obj["file"]);
|
|
144
|
+
}
|
|
145
|
+
// search_text, get_file_tree → files array
|
|
146
|
+
if (Array.isArray(obj["files"])) {
|
|
147
|
+
for (const f of obj["files"]) {
|
|
148
|
+
if (typeof f === "string")
|
|
149
|
+
addFile(f);
|
|
150
|
+
else if (f && typeof f === "object" && typeof f["path"] === "string") {
|
|
151
|
+
addFile(f["path"]);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
export function recordToolCall(tool, args, resultChunks, resultData) {
|
|
157
|
+
state.callCount++;
|
|
158
|
+
const now = Date.now();
|
|
159
|
+
// Extract symbols from result
|
|
160
|
+
extractSymbolsFromResult(resultData);
|
|
161
|
+
// Extract files from result
|
|
162
|
+
extractFilesFromResult(resultData);
|
|
163
|
+
// Extract file_path / path from args for single-file tools
|
|
164
|
+
const filePath = (args["file_path"] ?? args["path"]);
|
|
165
|
+
if (filePath && typeof filePath === "string") {
|
|
166
|
+
addFile(filePath);
|
|
167
|
+
}
|
|
168
|
+
// Append to queries if args.query exists
|
|
169
|
+
const query = args["query"];
|
|
170
|
+
const repo = (args["repo"] ?? "");
|
|
171
|
+
if (query && typeof query === "string") {
|
|
172
|
+
state.queries.push({ tool, query, repo, ts: now, resultCount: resultChunks });
|
|
173
|
+
}
|
|
174
|
+
// Negative evidence: search tool with zero results (skip error results)
|
|
175
|
+
const isError = resultData !== null && typeof resultData === "object" && "error" in resultData;
|
|
176
|
+
if (SEARCH_TOOL_SET.has(tool) && resultChunks === 0 && !isError) {
|
|
177
|
+
const filePattern = args["file_pattern"];
|
|
178
|
+
state.negativeEvidence.push({
|
|
179
|
+
tool,
|
|
180
|
+
query: (query ?? ""),
|
|
181
|
+
repo,
|
|
182
|
+
ts: now,
|
|
183
|
+
stale: false,
|
|
184
|
+
filePattern,
|
|
185
|
+
});
|
|
186
|
+
enforceNegativeEvidenceCap();
|
|
187
|
+
}
|
|
188
|
+
// Enforce caps
|
|
189
|
+
evictLRU(state.exploredSymbols, MAX_SYMBOLS);
|
|
190
|
+
evictLRU(state.exploredFiles, MAX_FILES);
|
|
191
|
+
enforceQueryCap();
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Track a cache-hit tool call.
|
|
195
|
+
* Increments callCount but does NOT evaluate negative evidence
|
|
196
|
+
* (no result data available to inspect).
|
|
197
|
+
*/
|
|
198
|
+
export function recordCacheHit(tool, _args) {
|
|
199
|
+
state.callCount++;
|
|
200
|
+
}
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
202
|
+
// Negative evidence invalidation — called from watcher
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
// ---------------------------------------------------------------------------
|
|
205
|
+
// Constants
|
|
206
|
+
// ---------------------------------------------------------------------------
|
|
207
|
+
const SNAPSHOT_CHAR_BUDGET = 700;
|
|
208
|
+
const STALENESS_TTL_MS = 120_000;
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
// Staleness check
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
export function isStale(entry) {
|
|
213
|
+
return entry.stale || (Date.now() - entry.ts > STALENESS_TTL_MS);
|
|
214
|
+
}
|
|
215
|
+
// ---------------------------------------------------------------------------
|
|
216
|
+
// Snapshot — pure function, can be called from CLI hook too
|
|
217
|
+
// ---------------------------------------------------------------------------
|
|
218
|
+
function truncateList(items, max, label) {
|
|
219
|
+
if (items.length === 0)
|
|
220
|
+
return "";
|
|
221
|
+
const shown = items.slice(0, max);
|
|
222
|
+
const rest = items.length - max;
|
|
223
|
+
const suffix = rest > 0 ? ` +${rest} more` : "";
|
|
224
|
+
return `${label}: ${shown.join(", ")}${suffix}`;
|
|
225
|
+
}
|
|
226
|
+
export function formatSnapshot(sessionState, repo) {
|
|
227
|
+
const lines = [];
|
|
228
|
+
const effectiveRepo = repo ?? sessionState.queries[sessionState.queries.length - 1]?.repo ?? "";
|
|
229
|
+
// Tier 1: Header (~15 tokens)
|
|
230
|
+
lines.push(`session:${sessionState.sessionId.slice(0, 8)} calls:${sessionState.callCount} started:${new Date(sessionState.startedAt).toISOString().slice(0, 16)}`);
|
|
231
|
+
// Tier 2: Top 5 files by accessCount
|
|
232
|
+
const files = [...sessionState.exploredFiles.values()]
|
|
233
|
+
.sort((a, b) => b.accessCount - a.accessCount || b.lastSeen - a.lastSeen);
|
|
234
|
+
const fileNames = files.map(f => f.path.split("/").pop() ?? f.path);
|
|
235
|
+
const tier2 = truncateList(fileNames, 5, "FILES");
|
|
236
|
+
// Tier 3: Top 10 symbols by lastSeen
|
|
237
|
+
const symbols = [...sessionState.exploredSymbols.values()]
|
|
238
|
+
.sort((a, b) => b.lastSeen - a.lastSeen);
|
|
239
|
+
const symNames = symbols.map(s => s.name);
|
|
240
|
+
const tier3 = truncateList(symNames, 10, "SYMBOLS");
|
|
241
|
+
// Tier 4: Top 5 non-stale negative evidence
|
|
242
|
+
const negEntries = sessionState.negativeEvidence
|
|
243
|
+
.filter(e => !isStale(e))
|
|
244
|
+
.sort((a, b) => b.ts - a.ts);
|
|
245
|
+
const negQueries = negEntries.map(e => `${e.tool}:"${e.query}"`);
|
|
246
|
+
const tier4 = truncateList(negQueries, 5, "NOT_FOUND");
|
|
247
|
+
// Tier 5: Last 3 queries (filtered by repo)
|
|
248
|
+
const recentQueries = sessionState.queries
|
|
249
|
+
.filter(q => !repo ? (!effectiveRepo || q.repo === effectiveRepo) : q.repo === repo)
|
|
250
|
+
.slice(-3)
|
|
251
|
+
.reverse();
|
|
252
|
+
const qStrings = recentQueries.map(q => `${q.tool}:"${q.query}"`);
|
|
253
|
+
const tier5 = truncateList(qStrings, 3, "QUERIES");
|
|
254
|
+
// Build with budget dropping
|
|
255
|
+
const tiers = [tier2, tier3, tier4, tier5].filter(t => t.length > 0);
|
|
256
|
+
for (const tier of tiers) {
|
|
257
|
+
lines.push(tier);
|
|
258
|
+
}
|
|
259
|
+
let result = lines.join("\n");
|
|
260
|
+
// Drop tiers from the bottom if over budget
|
|
261
|
+
while (result.length > SNAPSHOT_CHAR_BUDGET && lines.length > 1) {
|
|
262
|
+
lines.pop();
|
|
263
|
+
result = lines.join("\n");
|
|
264
|
+
}
|
|
265
|
+
// Final hard cap (shouldn't be needed, but safety net)
|
|
266
|
+
if (result.length > SNAPSHOT_CHAR_BUDGET) {
|
|
267
|
+
result = result.slice(0, SNAPSHOT_CHAR_BUDGET - 3) + "...";
|
|
268
|
+
}
|
|
269
|
+
return result;
|
|
270
|
+
}
|
|
271
|
+
// ---------------------------------------------------------------------------
|
|
272
|
+
// getContext — full session state as structured JSON
|
|
273
|
+
// ---------------------------------------------------------------------------
|
|
274
|
+
export function getContext(repo, includeStale = false) {
|
|
275
|
+
const symbols = [...state.exploredSymbols.values()];
|
|
276
|
+
const files = [...state.exploredFiles.values()];
|
|
277
|
+
const queries = repo
|
|
278
|
+
? state.queries.filter(q => q.repo === repo)
|
|
279
|
+
: [...state.queries];
|
|
280
|
+
const negativeEvidence = state.negativeEvidence.filter(e => {
|
|
281
|
+
if (!includeStale && isStale(e))
|
|
282
|
+
return false;
|
|
283
|
+
if (repo && e.repo !== repo)
|
|
284
|
+
return false;
|
|
285
|
+
return true;
|
|
286
|
+
});
|
|
287
|
+
return {
|
|
288
|
+
session_id: state.sessionId,
|
|
289
|
+
started_at: new Date(state.startedAt).toISOString(),
|
|
290
|
+
call_count: state.callCount,
|
|
291
|
+
explored_files: { count: files.length, items: files },
|
|
292
|
+
explored_symbols: { count: symbols.length, items: symbols },
|
|
293
|
+
queries: { count: queries.length, items: queries },
|
|
294
|
+
negative_evidence: { count: negativeEvidence.length, items: negativeEvidence },
|
|
295
|
+
caps: {
|
|
296
|
+
symbols_capped: state.exploredSymbols.size >= MAX_SYMBOLS,
|
|
297
|
+
files_capped: state.exploredFiles.size >= MAX_FILES,
|
|
298
|
+
queries_capped: state.queries.length >= MAX_QUERIES,
|
|
299
|
+
negative_evidence_capped: state.negativeEvidence.length >= MAX_NEGATIVE_EVIDENCE,
|
|
300
|
+
},
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Mark negative evidence entries as stale when a file changes.
|
|
305
|
+
* Scoped to the changed file's subtree — entries with a filePattern
|
|
306
|
+
* in a different subtree are not affected.
|
|
307
|
+
*/
|
|
308
|
+
export function invalidateNegativeEvidence(repo, changedFile) {
|
|
309
|
+
const changedDir = dirname(changedFile);
|
|
310
|
+
for (const entry of state.negativeEvidence) {
|
|
311
|
+
if (entry.repo !== repo)
|
|
312
|
+
continue;
|
|
313
|
+
if (entry.stale)
|
|
314
|
+
continue;
|
|
315
|
+
if (!entry.filePattern) {
|
|
316
|
+
// No filePattern specified — any file change in the same repo invalidates
|
|
317
|
+
entry.stale = true;
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
// Check if changed file is in the same subtree as the filePattern
|
|
321
|
+
const patternDir = dirname(entry.filePattern);
|
|
322
|
+
if (changedDir.startsWith(patternDir) || patternDir.startsWith(changedDir)) {
|
|
323
|
+
entry.stale = true;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// ---------------------------------------------------------------------------
|
|
329
|
+
// Sidecar file management
|
|
330
|
+
// ---------------------------------------------------------------------------
|
|
331
|
+
function getDataDir() {
|
|
332
|
+
return process.env["CODESIFT_DATA_DIR"] ?? join(homedir(), ".codesift");
|
|
333
|
+
}
|
|
334
|
+
function getSidecarPath() {
|
|
335
|
+
return join(getDataDir(), `session-${state.sessionId}.json`);
|
|
336
|
+
}
|
|
337
|
+
/** Serialize state for JSON — converts Maps to plain objects */
|
|
338
|
+
function serializeState() {
|
|
339
|
+
return {
|
|
340
|
+
sessionId: state.sessionId,
|
|
341
|
+
startedAt: state.startedAt,
|
|
342
|
+
callCount: state.callCount,
|
|
343
|
+
exploredSymbols: Object.fromEntries(state.exploredSymbols),
|
|
344
|
+
exploredFiles: Object.fromEntries(state.exploredFiles),
|
|
345
|
+
queries: state.queries,
|
|
346
|
+
negativeEvidence: state.negativeEvidence,
|
|
347
|
+
h10Emitted: state.h10Emitted,
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
/** Deserialize sidecar JSON back to SessionState shape (reconstructs Maps) */
|
|
351
|
+
export function deserializeState(raw) {
|
|
352
|
+
return {
|
|
353
|
+
sessionId: String(raw["sessionId"] ?? ""),
|
|
354
|
+
startedAt: Number(raw["startedAt"] ?? 0),
|
|
355
|
+
callCount: Number(raw["callCount"] ?? 0),
|
|
356
|
+
exploredSymbols: new Map(Object.entries((raw["exploredSymbols"] ?? {}))),
|
|
357
|
+
exploredFiles: new Map(Object.entries((raw["exploredFiles"] ?? {}))),
|
|
358
|
+
queries: (raw["queries"] ?? []),
|
|
359
|
+
negativeEvidence: (raw["negativeEvidence"] ?? []),
|
|
360
|
+
h10Emitted: Boolean(raw["h10Emitted"] ?? false),
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
/** Write current state to sidecar file atomically (tmp + rename) */
|
|
364
|
+
export async function flushSidecar() {
|
|
365
|
+
try {
|
|
366
|
+
const dataDir = getDataDir();
|
|
367
|
+
mkdirSync(dataDir, { recursive: true });
|
|
368
|
+
const finalPath = getSidecarPath();
|
|
369
|
+
const tmpPath = finalPath + ".tmp";
|
|
370
|
+
writeFileSync(tmpPath, JSON.stringify(serializeState()), "utf-8");
|
|
371
|
+
renameSync(tmpPath, finalPath);
|
|
372
|
+
}
|
|
373
|
+
catch {
|
|
374
|
+
// Best-effort — never block
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
/** Remove sidecar file (sync, called on process exit) */
|
|
378
|
+
export function cleanupSidecar() {
|
|
379
|
+
try {
|
|
380
|
+
unlinkSync(getSidecarPath());
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
// Ignore — file may not exist
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
/** Remove orphan sidecar files older than 24h */
|
|
387
|
+
export function cleanupOrphanSidecars() {
|
|
388
|
+
try {
|
|
389
|
+
const dataDir = getDataDir();
|
|
390
|
+
const files = readdirSync(dataDir).filter(f => f.startsWith("session-") && f.endsWith(".json"));
|
|
391
|
+
const cutoff = Date.now() - 24 * 3600 * 1000;
|
|
392
|
+
for (const file of files) {
|
|
393
|
+
const fullPath = join(dataDir, file);
|
|
394
|
+
const stats = statSync(fullPath);
|
|
395
|
+
if (stats.mtimeMs < cutoff) {
|
|
396
|
+
unlinkSync(fullPath);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
catch {
|
|
401
|
+
// Best-effort
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
/** Debounced sidecar flush */
|
|
405
|
+
export function scheduleSidecarFlush() {
|
|
406
|
+
if (debounceTimer)
|
|
407
|
+
clearTimeout(debounceTimer);
|
|
408
|
+
debounceTimer = setTimeout(() => {
|
|
409
|
+
flushSidecar().catch(() => { });
|
|
410
|
+
debounceTimer = null;
|
|
411
|
+
}, 1000);
|
|
412
|
+
}
|
|
413
|
+
//# sourceMappingURL=session-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-state.js","sourceRoot":"","sources":["../../src/storage/session-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -72,6 +72,11 @@ export declare function getBM25Index(repoName: string): Promise<BM25Index | null
|
|
|
72
72
|
* Get the code index for a repo from disk. Auto-refreshes if git HEAD moved.
|
|
73
73
|
*/
|
|
74
74
|
export declare function getCodeIndex(repoName: string): Promise<CodeIndex | null>;
|
|
75
|
+
/**
|
|
76
|
+
* Called at server startup. If the CWD is inside a git repo that isn't indexed yet,
|
|
77
|
+
* index it automatically in the background so tools work without manual setup.
|
|
78
|
+
*/
|
|
79
|
+
export declare function autoIndexCurrentRepo(cwd: string): Promise<void>;
|
|
75
80
|
/**
|
|
76
81
|
* Get the in-memory embedding cache for a repo.
|
|
77
82
|
* Loads from disk if not cached. Returns null if no embeddings file exists.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-tools.d.ts","sourceRoot":"","sources":["../../src/tools/index-tools.ts"],"names":[],"mappings":"AAUA,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAKnE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAa,QAAQ,EAAa,MAAM,aAAa,CAAC;AAsKzF;;;GAGG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,UAAU,EAAE,EACrB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,GACpC,OAAO,CAAC,IAAI,CAAC,CAuBf;AAmFD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,WAAW,CAC/B,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IACR,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACrC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7B,GACA,OAAO,CAAC,iBAAiB,CAAC,CAyJ5B;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;IACR,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CACtC,GACA,OAAO,CAAC,iBAAiB,CAAC,CAgE5B;
|
|
1
|
+
{"version":3,"file":"index-tools.d.ts","sourceRoot":"","sources":["../../src/tools/index-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFile, stat, unlink, rm, mkdir as mkdirAsync } from "node:fs/promises";
|
|
2
|
-
import { join, relative, extname, resolve, basename } from "node:path";
|
|
2
|
+
import { join, relative, extname, resolve, basename, dirname } from "node:path";
|
|
3
3
|
import { execFileSync } from "node:child_process";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
import { parseFile } from "../parser/parser-manager.js";
|
|
@@ -479,6 +479,14 @@ async function handleFileChange(repoRoot, repoName, indexPath, relativeFile) {
|
|
|
479
479
|
const fullPath = join(repoRoot, relativeFile);
|
|
480
480
|
// Invalidate cached findings so the next scan sees the updated file contents.
|
|
481
481
|
scanOnChanged(repoName, relativeFile);
|
|
482
|
+
// Invalidate negative evidence for this file's subtree
|
|
483
|
+
try {
|
|
484
|
+
const { invalidateNegativeEvidence } = await import("../storage/session-state.js");
|
|
485
|
+
invalidateNegativeEvidence(repoName, relativeFile);
|
|
486
|
+
}
|
|
487
|
+
catch {
|
|
488
|
+
// Best-effort — session-state may not be loaded
|
|
489
|
+
}
|
|
482
490
|
const result = await parseOneFile(fullPath, repoRoot, repoName);
|
|
483
491
|
if (!result)
|
|
484
492
|
return;
|
|
@@ -737,6 +745,41 @@ export async function getCodeIndex(repoName) {
|
|
|
737
745
|
codeIndexes.set(repoName, index);
|
|
738
746
|
return index;
|
|
739
747
|
}
|
|
748
|
+
/**
|
|
749
|
+
* Walk up from dir until a .git directory is found. Returns the git root or null.
|
|
750
|
+
*/
|
|
751
|
+
async function findGitRoot(dir) {
|
|
752
|
+
let current = resolve(dir);
|
|
753
|
+
while (true) {
|
|
754
|
+
try {
|
|
755
|
+
await stat(join(current, ".git"));
|
|
756
|
+
return current;
|
|
757
|
+
}
|
|
758
|
+
catch {
|
|
759
|
+
const parent = dirname(current);
|
|
760
|
+
if (parent === current)
|
|
761
|
+
return null;
|
|
762
|
+
current = parent;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Called at server startup. If the CWD is inside a git repo that isn't indexed yet,
|
|
768
|
+
* index it automatically in the background so tools work without manual setup.
|
|
769
|
+
*/
|
|
770
|
+
export async function autoIndexCurrentRepo(cwd) {
|
|
771
|
+
const gitRoot = await findGitRoot(cwd);
|
|
772
|
+
if (!gitRoot)
|
|
773
|
+
return;
|
|
774
|
+
const repoName = getRepoName(gitRoot);
|
|
775
|
+
const config = loadConfig();
|
|
776
|
+
const existing = await getRepo(config.registryPath, repoName);
|
|
777
|
+
if (existing)
|
|
778
|
+
return;
|
|
779
|
+
console.error(`[codesift] Auto-indexing ${repoName} (first use)...`);
|
|
780
|
+
await indexFolder(gitRoot);
|
|
781
|
+
console.error(`[codesift] Auto-index complete: ${repoName}`);
|
|
782
|
+
}
|
|
740
783
|
/**
|
|
741
784
|
* Get the in-memory embedding cache for a repo.
|
|
742
785
|
* Loads from disk if not cached. Returns null if no embeddings file exists.
|