codesift-mcp 0.2.5 → 0.2.7

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 (45) hide show
  1. package/README.md +8 -8
  2. package/dist/cli/commands.d.ts.map +1 -1
  3. package/dist/cli/commands.js +5 -1
  4. package/dist/cli/commands.js.map +1 -1
  5. package/dist/cli/help.d.ts +1 -1
  6. package/dist/cli/help.d.ts.map +1 -1
  7. package/dist/cli/help.js +14 -0
  8. package/dist/cli/help.js.map +1 -1
  9. package/dist/cli/hooks.d.ts +1 -0
  10. package/dist/cli/hooks.d.ts.map +1 -1
  11. package/dist/cli/hooks.js +170 -61
  12. package/dist/cli/hooks.js.map +1 -1
  13. package/dist/cli/platform.d.ts +12 -0
  14. package/dist/cli/platform.d.ts.map +1 -0
  15. package/dist/cli/platform.js +36 -0
  16. package/dist/cli/platform.js.map +1 -0
  17. package/dist/cli/setup.d.ts +6 -0
  18. package/dist/cli/setup.d.ts.map +1 -1
  19. package/dist/cli/setup.js +161 -121
  20. package/dist/cli/setup.js.map +1 -1
  21. package/dist/cli/shell-templates.d.ts +4 -0
  22. package/dist/cli/shell-templates.d.ts.map +1 -0
  23. package/dist/cli/shell-templates.js +86 -0
  24. package/dist/cli/shell-templates.js.map +1 -0
  25. package/dist/instructions.d.ts +1 -1
  26. package/dist/instructions.d.ts.map +1 -1
  27. package/dist/instructions.js +4 -4
  28. package/dist/register-tools.d.ts.map +1 -1
  29. package/dist/register-tools.js +68 -42
  30. package/dist/register-tools.js.map +1 -1
  31. package/dist/server-helpers.d.ts.map +1 -1
  32. package/dist/server-helpers.js +13 -1
  33. package/dist/server-helpers.js.map +1 -1
  34. package/dist/server.d.ts.map +1 -1
  35. package/dist/server.js +17 -0
  36. package/dist/server.js.map +1 -1
  37. package/dist/tools/project-tools.d.ts +107 -0
  38. package/dist/tools/project-tools.d.ts.map +1 -0
  39. package/dist/tools/project-tools.js +535 -0
  40. package/dist/tools/project-tools.js.map +1 -0
  41. package/package.json +2 -2
  42. package/rules/codesift.md +24 -13
  43. package/rules/codesift.mdc +10 -12
  44. package/rules/codex.md +10 -12
  45. package/rules/gemini.md +10 -12
@@ -0,0 +1,535 @@
1
+ /**
2
+ * Project Profile Analysis Tools
3
+ *
4
+ * Deterministic extraction of project stack, file classifications, and
5
+ * framework-specific conventions. Produces a JSON profile conforming to
6
+ * the zuvo project-profile schema v1.0.
7
+ */
8
+ import { readFile, access } from "node:fs/promises";
9
+ import { join, basename } from "node:path";
10
+ import { getCodeIndex } from "./index-tools.js";
11
+ // ---------------------------------------------------------------------------
12
+ // Versioning — used by get_extractor_versions
13
+ // ---------------------------------------------------------------------------
14
+ export const EXTRACTOR_VERSIONS = {
15
+ stack_detector: "1.0.0",
16
+ file_classifier: "1.0.0",
17
+ hono: "1.0.0",
18
+ };
19
+ // ---------------------------------------------------------------------------
20
+ // Stack Detector
21
+ // ---------------------------------------------------------------------------
22
+ async function fileExists(path) {
23
+ try {
24
+ await access(path);
25
+ return true;
26
+ }
27
+ catch {
28
+ return false;
29
+ }
30
+ }
31
+ async function readJson(path) {
32
+ try {
33
+ return JSON.parse(await readFile(path, "utf-8"));
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ export async function detectStack(projectRoot) {
40
+ const detected_from = [];
41
+ const pkg = await readJson(join(projectRoot, "package.json"));
42
+ // Framework detection
43
+ let framework = null;
44
+ let framework_version = null;
45
+ if (pkg) {
46
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
47
+ const frameworkMap = [
48
+ ["hono", "hono"],
49
+ ["@nestjs/core", "nestjs"],
50
+ ["next", "nextjs"],
51
+ ["nuxt", "nuxt"],
52
+ ["@remix-run/node", "remix"],
53
+ ["astro", "astro"],
54
+ ["express", "express"],
55
+ ["fastify", "fastify"],
56
+ ["@angular/core", "angular"],
57
+ ["vue", "vue"],
58
+ ["svelte", "svelte"],
59
+ ];
60
+ for (const [dep, name] of frameworkMap) {
61
+ if (allDeps?.[dep]) {
62
+ framework = name;
63
+ framework_version = allDeps[dep]?.replace(/^[\^~>=<]/, "") ?? null;
64
+ detected_from.push(`package.json:dependencies.${dep}`);
65
+ break;
66
+ }
67
+ }
68
+ // React detection (only if no framework found — React is often a sub-dep)
69
+ if (!framework && allDeps?.["react"]) {
70
+ framework = "react";
71
+ framework_version = allDeps["react"]?.replace(/^[\^~>=<]/, "") ?? null;
72
+ detected_from.push("package.json:dependencies.react");
73
+ }
74
+ }
75
+ // Language detection
76
+ let language = "javascript";
77
+ let language_version = null;
78
+ const tsconfig = await readJson(join(projectRoot, "tsconfig.json"));
79
+ if (tsconfig) {
80
+ language = "typescript";
81
+ language_version = tsconfig?.compilerOptions?.target ?? null;
82
+ detected_from.push("tsconfig.json");
83
+ }
84
+ // Test runner detection
85
+ let test_runner = null;
86
+ if (pkg) {
87
+ const devDeps = pkg.devDependencies ?? {};
88
+ if (devDeps["vitest"]) {
89
+ test_runner = "vitest";
90
+ detected_from.push("package.json:devDependencies.vitest");
91
+ }
92
+ else if (devDeps["jest"]) {
93
+ test_runner = "jest";
94
+ detected_from.push("package.json:devDependencies.jest");
95
+ }
96
+ else if (devDeps["mocha"]) {
97
+ test_runner = "mocha";
98
+ detected_from.push("package.json:devDependencies.mocha");
99
+ }
100
+ }
101
+ // Package manager detection
102
+ let package_manager = null;
103
+ if (await fileExists(join(projectRoot, "pnpm-lock.yaml"))) {
104
+ package_manager = "pnpm";
105
+ detected_from.push("pnpm-lock.yaml");
106
+ }
107
+ else if (await fileExists(join(projectRoot, "yarn.lock"))) {
108
+ package_manager = "yarn";
109
+ detected_from.push("yarn.lock");
110
+ }
111
+ else if (await fileExists(join(projectRoot, "package-lock.json"))) {
112
+ package_manager = "npm";
113
+ detected_from.push("package-lock.json");
114
+ }
115
+ else if (await fileExists(join(projectRoot, "bun.lockb"))) {
116
+ package_manager = "bun";
117
+ detected_from.push("bun.lockb");
118
+ }
119
+ // Monorepo detection
120
+ let monorepo = null;
121
+ if (pkg?.workspaces) {
122
+ const workspaces = Array.isArray(pkg.workspaces)
123
+ ? pkg.workspaces
124
+ : pkg.workspaces.packages ?? [];
125
+ const turboExists = await fileExists(join(projectRoot, "turbo.json"));
126
+ const nxExists = await fileExists(join(projectRoot, "nx.json"));
127
+ monorepo = {
128
+ tool: turboExists ? "turborepo" : nxExists ? "nx" : "workspaces",
129
+ workspaces,
130
+ };
131
+ detected_from.push("package.json:workspaces");
132
+ }
133
+ else if (await fileExists(join(projectRoot, "pnpm-workspace.yaml"))) {
134
+ try {
135
+ const content = await readFile(join(projectRoot, "pnpm-workspace.yaml"), "utf-8");
136
+ const workspaces = content.match(/- ['"]?([^'"]+)['"]?/g)?.map(m => m.replace(/- ['"]?/, "").replace(/['"]$/, "")) ?? [];
137
+ const turboExists = await fileExists(join(projectRoot, "turbo.json"));
138
+ monorepo = { tool: turboExists ? "turborepo" : "pnpm-workspaces", workspaces };
139
+ detected_from.push("pnpm-workspace.yaml");
140
+ }
141
+ catch { /* ignore parse errors */ }
142
+ }
143
+ return {
144
+ framework,
145
+ framework_version,
146
+ language,
147
+ language_version,
148
+ test_runner,
149
+ package_manager,
150
+ monorepo,
151
+ detected_from,
152
+ };
153
+ }
154
+ // ---------------------------------------------------------------------------
155
+ // File Classifier
156
+ // ---------------------------------------------------------------------------
157
+ const CRITICAL_PATH_PATTERNS = [
158
+ /\/(app|main|server|index)\.(ts|js|tsx|jsx)$/,
159
+ /\/middleware\//,
160
+ /\/security\//,
161
+ /\/auth\//,
162
+ /\/crypto\//,
163
+ ];
164
+ const IMPORTANT_PATH_PATTERNS = [
165
+ /\/services?\//,
166
+ /\/controllers?\//,
167
+ /\/routes?\//,
168
+ /\/handlers?\//,
169
+ /\/resolvers?\//,
170
+ ];
171
+ const ROUTINE_PATH_PATTERNS = [
172
+ /\/utils?\//,
173
+ /\/helpers?\//,
174
+ /\/constants?\//,
175
+ /\/types?\//,
176
+ /\/interfaces?\//,
177
+ /\/config\//,
178
+ /\/dto\//,
179
+ /\/schemas?\//,
180
+ ];
181
+ function isTestFile(path) {
182
+ return /\.(test|spec)\.(ts|js|tsx|jsx)$/.test(path);
183
+ }
184
+ function classifyCodeType(path, symbol_count) {
185
+ const base = basename(path);
186
+ if (/\/(app|main|server)\.(ts|js)$/.test(path))
187
+ return "ORCHESTRATOR";
188
+ if (/\/middleware\//.test(path))
189
+ return "GUARD";
190
+ if (/\/auth\//.test(path))
191
+ return "GUARD";
192
+ if (/\.(service|repository)\.(ts|js)$/.test(path))
193
+ return "SERVICE";
194
+ if (/\.(controller|handler)\.(ts|js)$/.test(path))
195
+ return "CONTROLLER";
196
+ if (/\.(component|page)\.(tsx|jsx)$/.test(path))
197
+ return "COMPONENT";
198
+ if (/\/hooks?\//.test(path) || /\.hook\.(ts|js)$/.test(path))
199
+ return "HOOK";
200
+ if (/\/utils?\//.test(path) || /\/helpers?\//.test(path))
201
+ return "PURE";
202
+ if (/\/types?\//.test(path) || /\.d\.ts$/.test(path))
203
+ return "TYPE_DEF";
204
+ if (/\/constants?\//.test(path))
205
+ return "CONSTANT";
206
+ return "PURE";
207
+ }
208
+ export function classifyFiles(index) {
209
+ const critical = [];
210
+ const important = [];
211
+ const routineCounts = {};
212
+ let routineCount = 0;
213
+ // Build importer count map
214
+ const importerCount = new Map();
215
+ for (const sym of index.symbols) {
216
+ // Count how many unique files import each file
217
+ if (sym.source?.includes("import ") || sym.source?.includes("require(")) {
218
+ // Simplified — in production this would use the actual import graph
219
+ }
220
+ }
221
+ // Build test file set for has_tests detection
222
+ const testFiles = new Set(index.files
223
+ .filter((f) => isTestFile(f.path))
224
+ .map((f) => f.path));
225
+ function hasTests(filePath) {
226
+ const base = filePath.replace(/\.(ts|js|tsx|jsx)$/, "");
227
+ return (testFiles.has(`${base}.test.ts`) ||
228
+ testFiles.has(`${base}.test.tsx`) ||
229
+ testFiles.has(`${base}.spec.ts`) ||
230
+ testFiles.has(`${base}.spec.tsx`) ||
231
+ testFiles.has(`${base}.test.js`) ||
232
+ testFiles.has(`${base}.spec.js`));
233
+ }
234
+ for (const file of index.files) {
235
+ if (isTestFile(file.path))
236
+ continue; // skip test files
237
+ if (/node_modules|\.d\.ts$|\.json$|\.md$|\.css$|\.scss$/.test(file.path))
238
+ continue;
239
+ const code_type = classifyCodeType(file.path, file.symbol_count);
240
+ const dependents = importerCount.get(file.path) ?? 0;
241
+ // Tier assignment
242
+ const isCritical = CRITICAL_PATH_PATTERNS.some((p) => p.test(file.path)) || dependents > 5;
243
+ const isImportant = IMPORTANT_PATH_PATTERNS.some((p) => p.test(file.path)) || file.symbol_count > 3;
244
+ const isRoutine = ROUTINE_PATH_PATTERNS.some((p) => p.test(file.path));
245
+ if (isCritical) {
246
+ const reason = dependents > 5
247
+ ? `Hub module (${dependents} importers)`
248
+ : CRITICAL_PATH_PATTERNS.find((p) => p.test(file.path))?.source.replace(/\\\//g, "/") ?? "entry point";
249
+ critical.push({
250
+ path: file.path,
251
+ code_type,
252
+ reason,
253
+ dependents_count: dependents,
254
+ has_tests: hasTests(file.path),
255
+ });
256
+ }
257
+ else if (isImportant && !isRoutine) {
258
+ important.push({
259
+ path: file.path,
260
+ code_type,
261
+ dependents_count: dependents,
262
+ has_tests: hasTests(file.path),
263
+ });
264
+ }
265
+ else {
266
+ routineCount++;
267
+ routineCounts[code_type] = (routineCounts[code_type] ?? 0) + 1;
268
+ }
269
+ }
270
+ return {
271
+ critical,
272
+ important,
273
+ routine: { count: routineCount, by_type: routineCounts },
274
+ };
275
+ }
276
+ function parseHonoCalls(source) {
277
+ const calls = [];
278
+ const lines = source.split("\n");
279
+ for (let i = 0; i < lines.length; i++) {
280
+ const line = lines[i];
281
+ const lineNum = i + 1;
282
+ // Match app.use("path", handler) or app.route("path", router)
283
+ const useMatch = line.match(/app\.(use|route|get|post|put|delete|all)\s*\(\s*["']([^"']+)["']\s*,\s*(.+)/);
284
+ if (useMatch) {
285
+ // Clean trailing ); but preserve function call parens like rateLimit(3, 3600)
286
+ let args = useMatch[3].trim().replace(/\);?\s*$/, "").trim();
287
+ calls.push({
288
+ type: useMatch[1],
289
+ path: useMatch[2],
290
+ args,
291
+ line: lineNum,
292
+ });
293
+ continue;
294
+ }
295
+ // Match app.use("*", handler) — global middleware
296
+ const globalUseMatch = line.match(/app\.use\s*\(\s*["']\*["']\s*,\s*(.+)/);
297
+ if (globalUseMatch) {
298
+ let args = globalUseMatch[1].trim().replace(/\);?\s*$/, "").trim();
299
+ calls.push({
300
+ type: "use",
301
+ path: "*",
302
+ args,
303
+ line: lineNum,
304
+ });
305
+ continue;
306
+ }
307
+ // Match app.get("/path", (c) => ...) — inline handler
308
+ const inlineMatch = line.match(/app\.(get|post|put|delete)\s*\(\s*["']([^"']+)["']\s*,/);
309
+ if (inlineMatch) {
310
+ calls.push({
311
+ type: inlineMatch[1],
312
+ path: inlineMatch[2],
313
+ args: "(inline handler)",
314
+ line: lineNum,
315
+ });
316
+ }
317
+ }
318
+ return calls;
319
+ }
320
+ function extractMiddlewareName(args) {
321
+ // Handle rateLimit(3, 3600) → "rateLimit"
322
+ const funcCall = args.match(/^(\w+)\s*\(/);
323
+ if (funcCall)
324
+ return funcCall[1];
325
+ // Handle simple identifier: clerkAuth
326
+ const simple = args.match(/^(\w+)$/);
327
+ if (simple)
328
+ return simple[1];
329
+ return null;
330
+ }
331
+ function extractRateLimit(args) {
332
+ const match = args.match(/rateLimit\s*\(\s*(\d+)\s*,\s*(\d+)\s*\)/);
333
+ if (match)
334
+ return { max: parseInt(match[1]), window: parseInt(match[2]) };
335
+ return null;
336
+ }
337
+ export function extractHonoConventions(source, filePath) {
338
+ const calls = parseHonoCalls(source);
339
+ const middleware_chains = [];
340
+ const rate_limits = [];
341
+ const route_mounts = [];
342
+ const authGroups = {};
343
+ let auth_middleware = null;
344
+ // Group middleware by scope
345
+ const scopeChains = new Map();
346
+ let globalOrder = 0;
347
+ const scopeOrders = new Map();
348
+ for (const call of calls) {
349
+ if (call.type === "use") {
350
+ const mwName = extractMiddlewareName(call.args);
351
+ const rl = extractRateLimit(call.args);
352
+ if (rl) {
353
+ rate_limits.push({
354
+ file: filePath,
355
+ line: call.line,
356
+ max: rl.max,
357
+ window: rl.window,
358
+ applied_to_path: call.path !== "*" ? call.path : null,
359
+ method: null, // .use() doesn't bind to a specific method
360
+ });
361
+ }
362
+ else if (mwName) {
363
+ const scope = call.path === "*" ? "global" : inferScope(call.path ?? "");
364
+ const currentOrder = scope === "global"
365
+ ? ++globalOrder
366
+ : (scopeOrders.set(scope, (scopeOrders.get(scope) ?? 0) + 1), scopeOrders.get(scope));
367
+ if (!scopeChains.has(scope))
368
+ scopeChains.set(scope, []);
369
+ scopeChains.get(scope).push({ name: mwName, line: call.line, order: currentOrder });
370
+ // Detect auth middleware
371
+ if (/auth|clerk|jwt|session|passport/i.test(mwName)) {
372
+ auth_middleware = mwName;
373
+ const group = inferScope(call.path ?? "");
374
+ if (!authGroups[group])
375
+ authGroups[group] = { requires_auth: false, middleware: [] };
376
+ authGroups[group].requires_auth = true;
377
+ authGroups[group].middleware.push(mwName);
378
+ }
379
+ else if (scope !== "global") {
380
+ const group = scope;
381
+ if (!authGroups[group])
382
+ authGroups[group] = { requires_auth: false, middleware: [] };
383
+ authGroups[group].middleware.push(mwName);
384
+ }
385
+ }
386
+ }
387
+ else if (call.type === "route") {
388
+ route_mounts.push({
389
+ file: filePath,
390
+ line: call.line,
391
+ mount_path: call.path ?? "",
392
+ imported_from: call.args.includes("/") ? call.args : null,
393
+ exported_as: call.args.includes("/") ? null : call.args,
394
+ });
395
+ // Infer route group for auth detection
396
+ const group = inferScope(call.path ?? "");
397
+ if (!authGroups[group])
398
+ authGroups[group] = { requires_auth: false, middleware: [] };
399
+ }
400
+ else if (call.type === "get" || call.type === "post" || call.type === "put" || call.type === "delete") {
401
+ // Inline route — nothing to extract for conventions, but note for route groups
402
+ }
403
+ }
404
+ // Build middleware chain array
405
+ for (const [scope, chain] of scopeChains) {
406
+ middleware_chains.push({ scope, file: filePath, chain });
407
+ }
408
+ // Build auth pattern groups — ensure all route groups are represented
409
+ const routeGroups = new Set();
410
+ for (const mount of route_mounts) {
411
+ routeGroups.add(inferScope(mount.mount_path));
412
+ }
413
+ // Add health and other direct routes
414
+ for (const call of calls) {
415
+ if (call.type !== "use" && call.type !== "route" && call.path) {
416
+ routeGroups.add(inferScope(call.path));
417
+ }
418
+ }
419
+ for (const group of routeGroups) {
420
+ if (!authGroups[group]) {
421
+ authGroups[group] = { requires_auth: false, middleware: [] };
422
+ }
423
+ }
424
+ return {
425
+ middleware_chains,
426
+ rate_limits,
427
+ route_mounts,
428
+ auth_patterns: { auth_middleware, groups: authGroups },
429
+ };
430
+ }
431
+ function inferScope(path) {
432
+ if (path === "*")
433
+ return "global";
434
+ if (path.includes("/admin"))
435
+ return "admin";
436
+ if (path.includes("/webhook"))
437
+ return "webhook";
438
+ if (path.includes("/health"))
439
+ return "health";
440
+ if (path.includes("/public") || path.includes("/contests") || path.includes("/translations") || path.includes("/r/"))
441
+ return "public";
442
+ // Default: extract first meaningful segment
443
+ const segments = path.split("/").filter(Boolean);
444
+ if (segments.length >= 2)
445
+ return segments[1];
446
+ return "root";
447
+ }
448
+ // ---------------------------------------------------------------------------
449
+ // Main orchestrator: analyze_project
450
+ // ---------------------------------------------------------------------------
451
+ export async function analyzeProject(repoName, options = {}) {
452
+ const startTime = Date.now();
453
+ let files_analyzed = 0;
454
+ let files_skipped = 0;
455
+ const skip_reasons = {};
456
+ const index = await getCodeIndex(repoName);
457
+ if (!index) {
458
+ return {
459
+ version: "1.0",
460
+ generated_at: new Date().toISOString(),
461
+ generated_by: {
462
+ tool: "codesift",
463
+ tool_version: "1.0.0",
464
+ extractor_versions: { ...EXTRACTOR_VERSIONS },
465
+ },
466
+ compatible_with: ">=1.0, <2.0",
467
+ status: "failed",
468
+ generation_metadata: {
469
+ files_analyzed: 0,
470
+ files_skipped: 0,
471
+ skip_reasons: { no_index: 1 },
472
+ duration_ms: Date.now() - startTime,
473
+ },
474
+ };
475
+ }
476
+ const projectRoot = index.root;
477
+ files_analyzed = index.file_count;
478
+ // Step 1: Stack detection
479
+ const stack = await detectStack(projectRoot);
480
+ // Step 2: File classification
481
+ const file_classifications = classifyFiles(index);
482
+ // Step 3: Framework-specific convention extraction
483
+ let conventions;
484
+ let status = "complete";
485
+ if (stack.framework === "hono") {
486
+ // Find the ORCHESTRATOR file from critical tier
487
+ const orchestratorFile = file_classifications.critical.find((f) => f.code_type === "ORCHESTRATOR");
488
+ if (orchestratorFile) {
489
+ try {
490
+ const appSource = await readFile(join(projectRoot, orchestratorFile.path), "utf-8");
491
+ conventions = extractHonoConventions(appSource, orchestratorFile.path);
492
+ }
493
+ catch (err) {
494
+ status = "partial";
495
+ skip_reasons["hono_extractor_error"] = 1;
496
+ }
497
+ }
498
+ else {
499
+ status = "partial";
500
+ skip_reasons["no_orchestrator_file"] = 1;
501
+ }
502
+ }
503
+ else {
504
+ // No framework-specific extractor available
505
+ status = "partial";
506
+ }
507
+ const profile = {
508
+ version: "1.0",
509
+ generated_at: new Date().toISOString(),
510
+ generated_by: {
511
+ tool: "codesift",
512
+ tool_version: "1.0.0",
513
+ extractor_versions: { ...EXTRACTOR_VERSIONS },
514
+ },
515
+ compatible_with: ">=1.0, <2.0",
516
+ status,
517
+ stack,
518
+ file_classifications,
519
+ ...(conventions ? { conventions } : {}),
520
+ generation_metadata: {
521
+ files_analyzed,
522
+ files_skipped,
523
+ skip_reasons,
524
+ duration_ms: Date.now() - startTime,
525
+ },
526
+ };
527
+ return profile;
528
+ }
529
+ // ---------------------------------------------------------------------------
530
+ // get_extractor_versions — fast metadata call
531
+ // ---------------------------------------------------------------------------
532
+ export function getExtractorVersions() {
533
+ return { ...EXTRACTOR_VERSIONS };
534
+ }
535
+ //# sourceMappingURL=project-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-tools.js","sourceRoot":"","sources":["../../src/tools/project-tools.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "codesift-mcp",
3
- "version": "0.2.5",
4
- "description": "MCP server for code intelligence — 63 tools for symbol search, call graph, semantic search, route tracing, community detection, LSP bridge, secret detection, and conversation search",
3
+ "version": "0.2.7",
4
+ "description": "MCP server for code intelligence — 66 tools for symbol search, call graph, semantic search, route tracing, community detection, LSP bridge, secret detection, and conversation search",
5
5
  "license": "BSL-1.1",
6
6
  "author": "Greg Laskowski",
7
7
  "type": "module",
package/rules/codesift.md CHANGED
@@ -4,23 +4,32 @@
4
4
 
5
5
  ## Setup
6
6
 
7
- Run once per session:
7
+ The `repo` parameter auto-resolves from the current working directory — no need to call `list_repos`.
8
+ If the repo is not yet indexed, run `index_folder(path=<root>)` once.
9
+ For multi-repo sessions, call `list_repos()` to discover available repos.
8
10
 
9
- 1. `list_repos()` get the repo identifier (e.g. `local/codesift-mcp`). **Never call again** — cache the result.
10
- 2. If the repo is missing: `index_folder(path=<root>)` once to index it.
11
- 3. Use `"local/<folder-name>"` as the `repo` parameter for all tool calls.
11
+ ## PREFER CodeSift over Bash/Glob/Grep
12
+
13
+ When CodeSift MCP tools are available, ALWAYS prefer them over shell commands:
14
+ - `Bash(find ... -name)` → use `get_file_tree(repo, compact=true, name_pattern="*.ts")`
15
+ - `Bash(grep -r ...)` or `Bash(rg ...)` → use `search_text(repo, query, file_pattern=)`
16
+ - `Glob(pattern)` for code discovery → use `get_file_tree(repo, name_pattern=)`
17
+ - `Grep(pattern)` for code search → use `search_text(repo, query)`
18
+
19
+ This applies to ALL agents including sub-agents spawned via the Agent tool.
20
+ The `repo` param is optional — it auto-resolves from CWD. Just call CodeSift tools directly.
12
21
 
13
22
  ## Tool Discovery
14
23
 
15
- **63 MCP tools total** (13 core visible + 50 deferred/hidden).
24
+ **66 MCP tools total** (14 core + 52 discoverable).
16
25
 
17
- Only ~13 core tools appear in ListTools. Hidden tools are discovered on demand:
26
+ Only 14 core tools appear in ListTools. Hidden tools are discovered on demand:
18
27
 
19
- - `discover_tools(query="dead code")` — keyword search across all 63 tools
28
+ - `discover_tools(query="dead code")` — keyword search across all 66 tools
20
29
  - `describe_tools(names=["find_dead_code"])` — get full parameter schema
21
30
  - `describe_tools(names=["find_dead_code"], reveal=true)` — also reveal in ListTools
22
31
 
23
- Core tools always visible: `search_text`, `search_symbols`, `get_file_outline`, `get_file_tree`, `get_symbol`, `get_symbols`, `find_references`, `find_and_show`, `codebase_retrieval`, `semantic_search`, `list_repos`, `index_file`, `discover_tools`, `describe_tools`.
32
+ Core tools always visible: `search_text`, `codebase_retrieval`, `get_file_outline`, `search_symbols`, `list_repos`, `get_file_tree`, `index_file`, `get_symbol`, `index_conversations`, `search_patterns`, `index_folder`, `discover_tools`, `get_session_snapshot`, `describe_tools`.
24
33
 
25
34
  ## Tool Mapping
26
35
 
@@ -131,7 +140,7 @@ The server appends hint codes to responses to guide tool usage. Act on them imme
131
140
  |------|---------|--------|
132
141
  | `H1(n)` | n matches returned | Add `group_by_file=true` |
133
142
  | `H2(n,tool)` | n consecutive identical calls | Batch into one `tool` call |
134
- | `H3(n)` | `list_repos` called n times | Reuse cached value |
143
+ | `H3(n)` | `list_repos` called n times | Repo auto-resolves from CWD, no need to call |
135
144
  | `H4` | `include_source` without `file_pattern` | Add `file_pattern` |
136
145
  | `H5(path)` | Duplicate `get_file_tree` | Use cached result |
137
146
  | `H6(n)` | n results without `detail_level` | Add `detail_level='compact'` |
@@ -153,8 +162,8 @@ The server appends hint codes to responses to guide tool usage. Act on them imme
153
162
 
154
163
  ## NEVER
155
164
 
156
- - Call `index_folder` if repo already in `list_repos` — file watcher auto-updates
157
- - Call `list_repos` more than once per session
165
+ - Call `index_folder` if repo is already indexed — file watcher auto-updates
166
+ - Call `list_repos` in single-repo sessions repo auto-resolves from CWD
158
167
  - Use manual Edit on multiple files for rename — use `rename_symbol`
159
168
  - Read entire file just to get a return type — use `get_type_info`
160
169
  - Index worktrees — use the main repo index
@@ -180,9 +189,11 @@ Setup auto-indexing and read-redirect hooks for Claude Code:
180
189
  codesift setup claude --hooks
181
190
  ```
182
191
 
183
- Installs two hooks in `.claude/settings.local.json`:
192
+ Installs hooks in `.claude/settings.local.json` and rules in `~/.claude/rules/codesift.md`:
184
193
 
185
194
  - **PreToolUse** (`precheck-read`) — redirects `Read` on large code files to CodeSift tools
195
+ - **PreToolUse** (`precheck-bash`) — redirects `find`/`grep`/`rg` in Bash to CodeSift tools
186
196
  - **PostToolUse** (`postindex-file`) — auto-runs `index_file` after `Edit` or `Write`
197
+ - **PreCompact** (`precompact-snapshot`) — injects session snapshot before context compaction
187
198
 
188
- This ensures the index stays current without manual `index_file` calls after every edit.
199
+ This ensures the index stays current and sub-agents use CodeSift tools automatically.