codesift-mcp 0.2.6 → 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 (44) hide show
  1. package/dist/cli/commands.d.ts.map +1 -1
  2. package/dist/cli/commands.js +5 -1
  3. package/dist/cli/commands.js.map +1 -1
  4. package/dist/cli/help.d.ts +1 -1
  5. package/dist/cli/help.d.ts.map +1 -1
  6. package/dist/cli/help.js +14 -0
  7. package/dist/cli/help.js.map +1 -1
  8. package/dist/cli/hooks.d.ts +1 -0
  9. package/dist/cli/hooks.d.ts.map +1 -1
  10. package/dist/cli/hooks.js +170 -61
  11. package/dist/cli/hooks.js.map +1 -1
  12. package/dist/cli/platform.d.ts +12 -0
  13. package/dist/cli/platform.d.ts.map +1 -0
  14. package/dist/cli/platform.js +36 -0
  15. package/dist/cli/platform.js.map +1 -0
  16. package/dist/cli/setup.d.ts +6 -0
  17. package/dist/cli/setup.d.ts.map +1 -1
  18. package/dist/cli/setup.js +161 -121
  19. package/dist/cli/setup.js.map +1 -1
  20. package/dist/cli/shell-templates.d.ts +4 -0
  21. package/dist/cli/shell-templates.d.ts.map +1 -0
  22. package/dist/cli/shell-templates.js +86 -0
  23. package/dist/cli/shell-templates.js.map +1 -0
  24. package/dist/instructions.d.ts +1 -1
  25. package/dist/instructions.d.ts.map +1 -1
  26. package/dist/instructions.js +4 -4
  27. package/dist/register-tools.d.ts.map +1 -1
  28. package/dist/register-tools.js +68 -42
  29. package/dist/register-tools.js.map +1 -1
  30. package/dist/server-helpers.d.ts.map +1 -1
  31. package/dist/server-helpers.js +13 -1
  32. package/dist/server-helpers.js.map +1 -1
  33. package/dist/server.d.ts.map +1 -1
  34. package/dist/server.js +17 -0
  35. package/dist/server.js.map +1 -1
  36. package/dist/tools/project-tools.d.ts +107 -0
  37. package/dist/tools/project-tools.d.ts.map +1 -0
  38. package/dist/tools/project-tools.js +535 -0
  39. package/dist/tools/project-tools.js.map +1 -0
  40. package/package.json +1 -1
  41. package/rules/codesift.md +7 -9
  42. package/rules/codesift.mdc +6 -8
  43. package/rules/codex.md +6 -8
  44. package/rules/gemini.md +6 -8
@@ -1 +1 @@
1
- {"version":3,"file":"register-tools.d.ts","sourceRoot":"","sources":["../src/register-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAuCxB,iFAAiF;AACjF,eAAO,MAAM,IAAI,yIAQF,CAAC;AAQhB,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,OAEzC;AAMD,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;IACrC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7D,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,YAAY,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC;CAC7B;AAMD,eAAO,MAAM,aAAa;IACxB,wCAAwC;;IAGxC,oBAAoB;;IAGpB,uBAAuB;;IAGvB,iBAAiB;;IAGjB,sBAAsB;;IAGtB,uBAAuB;;IAGvB,sBAAsB;;IAGtB,yBAAyB;;IAGzB,qBAAqB;;;;;;;;;;;;IAarB,yBAAyB;;IAGzB,yBAAyB;;IAGzB,qBAAqB;;IAGrB,kBAAkB;;IAGlB,mBAAmB;;IAGnB,uBAAuB;;IAGvB,oBAAoB;;;;;;;;;IAMpB,oBAAoB;;;;;;;;IAMpB,kBAAkB;;;;IAGlB,iBAAiB;;;;CAET,CAAC;AAEX,MAAM,MAAM,YAAY,GACpB,UAAU,GACV,QAAQ,GACR,SAAS,GACT,SAAS,GACT,OAAO,GACP,KAAK,GACL,cAAc,GACd,SAAS,GACT,MAAM,GACN,UAAU,GACV,UAAU,GACV,eAAe,GACf,UAAU,GACV,WAAW,GACX,YAAY,GACZ,MAAM,CAAC;AAmBX,sDAAsD;AACtD,wBAAgB,kBAAkB,IAAI,SAAS,cAAc,EAAE,CAE9D;AA6xCD,UAAU,mBAAmB;IAC3B,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,OAAO,CAAC;YAAC,WAAW,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACzE,CAAC,CAAC;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,mBAAmB,CAqBlE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC1F,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAmDA;AAMD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAiF3F"}
1
+ {"version":3,"file":"register-tools.d.ts","sourceRoot":"","sources":["../src/register-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAwCxB,iFAAiF;AACjF,eAAO,MAAM,IAAI,yIAQF,CAAC;AAQhB,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,OAEzC;AAMD,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;IACrC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7D,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,YAAY,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC;CAC7B;AAMD,eAAO,MAAM,aAAa;IACxB,wCAAwC;;IAGxC,oBAAoB;;IAGpB,uBAAuB;;IAGvB,iBAAiB;;IAGjB,sBAAsB;;IAGtB,uBAAuB;;IAGvB,sBAAsB;;IAGtB,yBAAyB;;IAGzB,qBAAqB;;;;;;;;;;;;IAarB,yBAAyB;;IAGzB,yBAAyB;;IAGzB,qBAAqB;;IAGrB,kBAAkB;;IAGlB,mBAAmB;;IAGnB,uBAAuB;;IAGvB,oBAAoB;;;;;;;;;IAMpB,oBAAoB;;;;;;;;IAMpB,kBAAkB;;;;IAGlB,iBAAiB;;;;CAET,CAAC;AAEX,MAAM,MAAM,YAAY,GACpB,UAAU,GACV,QAAQ,GACR,SAAS,GACT,SAAS,GACT,OAAO,GACP,KAAK,GACL,cAAc,GACd,SAAS,GACT,MAAM,GACN,UAAU,GACV,UAAU,GACV,eAAe,GACf,UAAU,GACV,WAAW,GACX,YAAY,GACZ,MAAM,CAAC;AAmBX,sDAAsD;AACtD,wBAAgB,kBAAkB,IAAI,SAAS,cAAc,EAAE,CAE9D;AAuzCD,UAAU,mBAAmB;IAC3B,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,OAAO,CAAC;YAAC,WAAW,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACzE,CAAC,CAAC;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,mBAAmB,CAqBlE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC1F,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAmDA;AAMD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAiF3F"}
@@ -27,6 +27,7 @@ import { scanSecrets } from "./tools/secret-tools.js";
27
27
  import { consolidateMemories, readMemory } from "./tools/memory-tools.js";
28
28
  import { createAnalysisPlan, writeScratchpad, readScratchpad, listScratchpad, updateStepStatus, getPlan, listPlans } from "./tools/coordinator-tools.js";
29
29
  import { frequencyAnalysis } from "./tools/frequency-tools.js";
30
+ import { analyzeProject, getExtractorVersions } from "./tools/project-tools.js";
30
31
  import { reviewDiff } from "./tools/review-diff-tools.js";
31
32
  import { formatSnapshot, getContext, getSessionState } from "./storage/session-state.js";
32
33
  import { formatComplexityCompact, formatComplexityCounts, formatClonesCompact, formatClonesCounts, formatHotspotsCompact, formatHotspotsCounts, formatTraceRouteCompact, formatTraceRouteCounts } from "./formatters-shortening.js";
@@ -168,7 +169,7 @@ const TOOL_DEFINITIONS = [
168
169
  category: "indexing",
169
170
  searchHint: "list indexed repositories repos available",
170
171
  outputSchema: OutputSchemas.repoList,
171
- description: "List indexed repos. Set compact=false for full metadata. Cached per session.",
172
+ description: "List indexed repos. Only needed for multi-repo discovery — single-repo tools auto-resolve from CWD. Set compact=false for full metadata.",
172
173
  schema: {
173
174
  compact: zBool().describe("true=names only (default), false=full metadata"),
174
175
  },
@@ -180,7 +181,7 @@ const TOOL_DEFINITIONS = [
180
181
  searchHint: "clear cache invalidate re-index refresh",
181
182
  description: "Clear the index cache for a repository, forcing full re-index on next use",
182
183
  schema: {
183
- repo: z.string().describe("Repository identifier (e.g. local/my-project)"),
184
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
184
185
  },
185
186
  handler: (args) => invalidateCache(args.repo),
186
187
  },
@@ -202,7 +203,7 @@ const TOOL_DEFINITIONS = [
202
203
  outputSchema: OutputSchemas.searchResults,
203
204
  description: "Search symbols by name/signature. detail_level: compact (~15 tok), standard (default), full.",
204
205
  schema: {
205
- repo: z.string().describe("Repository identifier"),
206
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
206
207
  query: z.string().describe("Search query string"),
207
208
  kind: z.string().optional().describe("Filter by symbol kind (function, class, etc.)"),
208
209
  file_pattern: z.string().optional().describe("Glob pattern to filter files"),
@@ -233,7 +234,7 @@ const TOOL_DEFINITIONS = [
233
234
  searchHint: "AST tree-sitter query structural pattern matching code shape",
234
235
  description: "Search AST patterns via tree-sitter S-expressions. Finds code by structural shape.",
235
236
  schema: {
236
- repo: z.string().describe("Repository identifier"),
237
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
237
238
  query: z.string().describe("Tree-sitter query in S-expression syntax"),
238
239
  language: z.string().describe("Tree-sitter grammar: typescript, javascript, python, go, rust, java, ruby, php"),
239
240
  file_pattern: z.string().optional().describe("Filter to files matching this path substring"),
@@ -254,7 +255,7 @@ const TOOL_DEFINITIONS = [
254
255
  searchHint: "semantic meaning intent concept embedding vector natural language",
255
256
  description: "Search code by meaning using embeddings. For intent-based queries: 'error handling', 'auth flow'. Requires indexed embeddings.",
256
257
  schema: {
257
- repo: z.string().describe("Repository identifier"),
258
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
258
259
  query: z.string().describe("Natural language query describing what you're looking for"),
259
260
  top_k: zNum().describe("Number of results (default: 10)"),
260
261
  file_pattern: z.string().optional().describe("Filter to files matching this path substring"),
@@ -280,7 +281,7 @@ const TOOL_DEFINITIONS = [
280
281
  searchHint: "full-text search grep regex keyword content files",
281
282
  description: "Full-text search across all files. For conceptual queries use semantic_search.",
282
283
  schema: {
283
- repo: z.string().describe("Repository identifier"),
284
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
284
285
  query: z.string().describe("Search query or regex pattern"),
285
286
  regex: zBool().describe("Treat query as a regex pattern"),
286
287
  context_lines: zNum().describe("Number of context lines around each match"),
@@ -308,7 +309,7 @@ const TOOL_DEFINITIONS = [
308
309
  outputSchema: OutputSchemas.fileTree,
309
310
  description: "File tree with symbol counts. compact=true for flat list (10-50x less output). Cached 5min.",
310
311
  schema: {
311
- repo: z.string().describe("Repository identifier"),
312
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
312
313
  path_prefix: z.string().optional().describe("Filter to a subtree by path prefix"),
313
314
  name_pattern: z.string().optional().describe("Glob pattern to filter file names"),
314
315
  depth: zNum().describe("Maximum directory depth to traverse"),
@@ -333,7 +334,7 @@ const TOOL_DEFINITIONS = [
333
334
  outputSchema: OutputSchemas.fileOutline,
334
335
  description: "Get the symbol outline of a single file (functions, classes, exports)",
335
336
  schema: {
336
- repo: z.string().describe("Repository identifier"),
337
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
337
338
  file_path: z.string().describe("Relative file path within the repository"),
338
339
  },
339
340
  handler: async (args) => {
@@ -347,7 +348,7 @@ const TOOL_DEFINITIONS = [
347
348
  searchHint: "repository outline overview directory structure high-level",
348
349
  description: "Get a high-level outline of the entire repository grouped by directory",
349
350
  schema: {
350
- repo: z.string().describe("Repository identifier"),
351
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
351
352
  },
352
353
  handler: async (args) => {
353
354
  const result = await getRepoOutline(args.repo);
@@ -360,7 +361,7 @@ const TOOL_DEFINITIONS = [
360
361
  searchHint: "suggest queries explore unfamiliar repo onboarding first call",
361
362
  description: "Suggest queries for exploring a new repo. Returns top files, kind distribution, examples.",
362
363
  schema: {
363
- repo: z.string().describe("Repository identifier"),
364
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
364
365
  },
365
366
  handler: async (args) => {
366
367
  const result = await suggestQueries(args.repo);
@@ -375,7 +376,7 @@ const TOOL_DEFINITIONS = [
375
376
  outputSchema: OutputSchemas.symbol,
376
377
  description: "Get symbol by ID with source. Auto-prefetches children for classes. For batch: get_symbols. For context: get_context_bundle.",
377
378
  schema: {
378
- repo: z.string().describe("Repository identifier"),
379
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
379
380
  symbol_id: z.string().describe("Unique symbol identifier"),
380
381
  include_related: zBool().describe("Include children/related symbols (default: true)"),
381
382
  },
@@ -399,7 +400,7 @@ const TOOL_DEFINITIONS = [
399
400
  searchHint: "batch get multiple symbols by IDs",
400
401
  description: "Retrieve multiple symbols by ID in a single batch call",
401
402
  schema: {
402
- repo: z.string().describe("Repository identifier"),
403
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
403
404
  symbol_ids: z.union([
404
405
  z.array(z.string()),
405
406
  z.string().transform((s) => JSON.parse(s)),
@@ -416,7 +417,7 @@ const TOOL_DEFINITIONS = [
416
417
  searchHint: "find symbol by name show source code references",
417
418
  description: "Find a symbol by name and show its source, optionally including references",
418
419
  schema: {
419
- repo: z.string().describe("Repository identifier"),
420
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
420
421
  query: z.string().describe("Symbol name or query to search for"),
421
422
  include_refs: zBool().describe("Include locations that reference this symbol"),
422
423
  },
@@ -437,7 +438,7 @@ const TOOL_DEFINITIONS = [
437
438
  searchHint: "context bundle symbol imports siblings callers one call",
438
439
  description: "Symbol + imports + siblings in one call. Saves 2-3 round-trips.",
439
440
  schema: {
440
- repo: z.string().describe("Repository identifier"),
441
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
441
442
  symbol_name: z.string().describe("Symbol name to find"),
442
443
  },
443
444
  handler: async (args) => {
@@ -455,7 +456,7 @@ const TOOL_DEFINITIONS = [
455
456
  outputSchema: OutputSchemas.references,
456
457
  description: "Find all references to a symbol. Pass symbol_names array for batch search.",
457
458
  schema: {
458
- repo: z.string().describe("Repository identifier"),
459
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
459
460
  symbol_name: z.string().optional().describe("Name of the symbol to find references for"),
460
461
  symbol_names: z.union([z.array(z.string()), z.string().transform((s) => JSON.parse(s))]).optional()
461
462
  .describe("Array of symbol names for batch search (reads each file once). Can be JSON string."),
@@ -478,7 +479,7 @@ const TOOL_DEFINITIONS = [
478
479
  outputSchema: OutputSchemas.callTree,
479
480
  description: "Trace call chain: callers or callees. output_format='mermaid' for diagram.",
480
481
  schema: {
481
- repo: z.string().describe("Repository identifier"),
482
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
482
483
  symbol_name: z.string().describe("Name of the symbol to trace"),
483
484
  direction: z.enum(["callers", "callees"]).describe("Trace direction"),
484
485
  depth: zNum().describe("Maximum depth to traverse the call graph (default: 1)"),
@@ -503,7 +504,7 @@ const TOOL_DEFINITIONS = [
503
504
  outputSchema: OutputSchemas.impactAnalysis,
504
505
  description: "Blast radius of git changes — affected symbols and files.",
505
506
  schema: {
506
- repo: z.string().describe("Repository identifier"),
507
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
507
508
  since: z.string().describe("Git ref to compare from (e.g. HEAD~3, commit SHA, branch)"),
508
509
  depth: zNum().describe("Depth of dependency traversal"),
509
510
  until: z.string().optional().describe("Git ref to compare to (defaults to HEAD)"),
@@ -524,7 +525,7 @@ const TOOL_DEFINITIONS = [
524
525
  searchHint: "trace HTTP route handler API endpoint service database NestJS Express Next.js",
525
526
  description: "Trace HTTP route → handler → service → DB. NestJS, Next.js, Express.",
526
527
  schema: {
527
- repo: z.string().describe("Repository identifier"),
528
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
528
529
  path: z.string().describe("URL path to trace (e.g. '/api/users', '/api/projects/:id')"),
529
530
  output_format: z.enum(["json", "mermaid"]).optional().describe("Output format: 'json' (default) or 'mermaid' (sequence diagram)"),
530
531
  },
@@ -540,7 +541,7 @@ const TOOL_DEFINITIONS = [
540
541
  outputSchema: OutputSchemas.definition,
541
542
  description: "Go to the definition of a symbol. Uses LSP when available for type-safe precision, falls back to index search.",
542
543
  schema: {
543
- repo: z.string().describe("Repository identifier"),
544
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
544
545
  symbol_name: z.string().describe("Symbol name to find definition of"),
545
546
  file_path: z.string().optional().describe("File containing the symbol reference (for LSP precision)"),
546
547
  line: zNum().describe("0-based line number of the reference"),
@@ -561,7 +562,7 @@ const TOOL_DEFINITIONS = [
561
562
  outputSchema: OutputSchemas.typeInfo,
562
563
  description: "Get type info via LSP hover (return type, params, docs). Hint if LSP unavailable.",
563
564
  schema: {
564
- repo: z.string().describe("Repository identifier"),
565
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
565
566
  symbol_name: z.string().describe("Symbol name to get type info for"),
566
567
  file_path: z.string().optional().describe("File containing the symbol"),
567
568
  line: zNum().describe("0-based line number"),
@@ -576,7 +577,7 @@ const TOOL_DEFINITIONS = [
576
577
  outputSchema: OutputSchemas.renameResult,
577
578
  description: "Rename symbol across all files via LSP. Type-safe, updates imports/refs.",
578
579
  schema: {
579
- repo: z.string().describe("Repository identifier"),
580
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
580
581
  symbol_name: z.string().describe("Current name of the symbol to rename"),
581
582
  new_name: z.string().describe("New name for the symbol"),
582
583
  file_path: z.string().optional().describe("File containing the symbol"),
@@ -592,7 +593,7 @@ const TOOL_DEFINITIONS = [
592
593
  outputSchema: OutputSchemas.callHierarchy,
593
594
  description: "LSP call hierarchy: incoming + outgoing calls. Complements trace_call_chain.",
594
595
  schema: {
595
- repo: z.string().describe("Repository identifier"),
596
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
596
597
  symbol_name: z.string().describe("Symbol name to get call hierarchy for"),
597
598
  file_path: z.string().optional().describe("File containing the symbol (for LSP precision)"),
598
599
  line: zNum().describe("0-based line number"),
@@ -630,7 +631,7 @@ const TOOL_DEFINITIONS = [
630
631
  searchHint: "community detection clusters modules Louvain import graph boundaries",
631
632
  description: "Louvain community detection on import graph. Discovers module boundaries.",
632
633
  schema: {
633
- repo: z.string().describe("Repository identifier"),
634
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
634
635
  focus: z.string().optional().describe("Path substring to filter files (e.g. 'src/lib')"),
635
636
  resolution: zNum().describe("Louvain resolution: higher = more smaller communities, lower = fewer larger (default: 1.0)"),
636
637
  output_format: z.enum(["json", "mermaid"]).optional().describe("Output format: 'json' (default) or 'mermaid' (graph diagram)"),
@@ -646,7 +647,7 @@ const TOOL_DEFINITIONS = [
646
647
  searchHint: "circular dependency cycle import loop detection",
647
648
  description: "Detect circular dependencies in the import graph via DFS. Returns file-level cycles.",
648
649
  schema: {
649
- repo: z.string().describe("Repository identifier"),
650
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
650
651
  file_pattern: z.string().optional().describe("Filter to files matching this path substring"),
651
652
  max_cycles: zNum().describe("Maximum cycles to report (default: 50)"),
652
653
  },
@@ -674,7 +675,7 @@ const TOOL_DEFINITIONS = [
674
675
  searchHint: "boundary rules architecture enforcement imports CI gate hexagonal onion",
675
676
  description: "Check architecture boundary rules against imports. Path substring matching.",
676
677
  schema: {
677
- repo: z.string().describe("Repository identifier"),
678
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
678
679
  rules: z.union([
679
680
  z.array(z.object({
680
681
  from: z.string().describe("Path substring matching source files (e.g. 'src/domain')"),
@@ -696,7 +697,7 @@ const TOOL_DEFINITIONS = [
696
697
  searchHint: "classify roles entry core utility dead leaf symbol architecture",
697
698
  description: "Classify symbol roles (entry/core/utility/dead/leaf) by call graph connectivity.",
698
699
  schema: {
699
- repo: z.string().describe("Repository identifier"),
700
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
700
701
  file_pattern: z.string().optional().describe("Filter to files matching this path substring"),
701
702
  include_tests: zBool().describe("Include test files (default: false)"),
702
703
  top_n: zNum().describe("Maximum number of symbols to return (default: 100)"),
@@ -718,7 +719,7 @@ const TOOL_DEFINITIONS = [
718
719
  searchHint: "assemble context token budget L0 L1 L2 L3 source signatures summaries",
719
720
  description: "Assemble code context within token budget. L0=source, L1=signatures, L2=files, L3=dirs.",
720
721
  schema: {
721
- repo: z.string().describe("Repository identifier"),
722
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
722
723
  query: z.string().describe("Natural language query describing what context is needed"),
723
724
  token_budget: zNum().describe("Maximum tokens for the assembled context"),
724
725
  level: z.enum(["L0", "L1", "L2", "L3"]).optional().describe("L0=source (default), L1=signatures, L2=files, L3=dirs"),
@@ -735,7 +736,7 @@ const TOOL_DEFINITIONS = [
735
736
  searchHint: "knowledge map module dependency graph architecture overview mermaid",
736
737
  description: "Get the module dependency map showing how files and directories relate",
737
738
  schema: {
738
- repo: z.string().describe("Repository identifier"),
739
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
739
740
  focus: z.string().optional().describe("Focus on a specific module or directory"),
740
741
  depth: zNum().describe("Maximum depth of the dependency graph"),
741
742
  output_format: z.enum(["json", "mermaid"]).optional().describe("Output format: 'json' (default) or 'mermaid' (dependency diagram)"),
@@ -752,7 +753,7 @@ const TOOL_DEFINITIONS = [
752
753
  searchHint: "diff outline structural changes git refs compare",
753
754
  description: "Get a structural outline of what changed between two git refs",
754
755
  schema: {
755
- repo: z.string().describe("Repository identifier"),
756
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
756
757
  since: z.string().describe("Git ref to compare from"),
757
758
  until: z.string().optional().describe("Git ref to compare to (defaults to HEAD)"),
758
759
  },
@@ -767,7 +768,7 @@ const TOOL_DEFINITIONS = [
767
768
  searchHint: "changed symbols added modified removed git diff",
768
769
  description: "List symbols that were added, modified, or removed between two git refs",
769
770
  schema: {
770
- repo: z.string().describe("Repository identifier"),
771
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
771
772
  since: z.string().describe("Git ref to compare from"),
772
773
  until: z.string().optional().describe("Git ref to compare to (defaults to HEAD)"),
773
774
  include_diff: zBool().describe("Include unified diff per changed file (truncated to 500 chars)"),
@@ -787,7 +788,7 @@ const TOOL_DEFINITIONS = [
787
788
  searchHint: "generate CLAUDE.md project summary documentation",
788
789
  description: "Generate a CLAUDE.md project summary file from the repository index",
789
790
  schema: {
790
- repo: z.string().describe("Repository identifier"),
791
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
791
792
  output_path: z.string().optional().describe("Custom output file path"),
792
793
  },
793
794
  handler: (args) => generateClaudeMd(args.repo, args.output_path),
@@ -800,7 +801,7 @@ const TOOL_DEFINITIONS = [
800
801
  outputSchema: OutputSchemas.batchResults,
801
802
  description: "Batch multi-query retrieval with shared token budget. Supports symbols/text/semantic/hybrid.",
802
803
  schema: {
803
- repo: z.string().describe("Repository identifier"),
804
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
804
805
  queries: z
805
806
  .union([
806
807
  z.array(z.object({ type: z.string() }).passthrough()),
@@ -830,7 +831,7 @@ const TOOL_DEFINITIONS = [
830
831
  outputSchema: OutputSchemas.deadCode,
831
832
  description: "Find dead code: exported symbols with zero external references.",
832
833
  schema: {
833
- repo: z.string().describe("Repository identifier"),
834
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
834
835
  file_pattern: z.string().optional().describe("Filter to files matching this path substring"),
835
836
  include_tests: zBool().describe("Include test files in scan (default: false)"),
836
837
  },
@@ -848,7 +849,7 @@ const TOOL_DEFINITIONS = [
848
849
  searchHint: "unused imports dead cleanup lint",
849
850
  description: "Find imported names never referenced in the file body. Complements find_dead_code.",
850
851
  schema: {
851
- repo: z.string().describe("Repository identifier"),
852
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
852
853
  file_pattern: z.string().optional().describe("Filter to files matching this path substring"),
853
854
  include_tests: zBool().describe("Include test files in scan (default: false)"),
854
855
  },
@@ -877,7 +878,7 @@ const TOOL_DEFINITIONS = [
877
878
  outputSchema: OutputSchemas.complexity,
878
879
  description: "Top N most complex functions by cyclomatic complexity, nesting, lines.",
879
880
  schema: {
880
- repo: z.string().describe("Repository identifier"),
881
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
881
882
  file_pattern: z.string().optional().describe("Filter to files matching this path substring"),
882
883
  top_n: zNum().describe("Return top N most complex functions (default: 30)"),
883
884
  min_complexity: zNum().describe("Minimum cyclomatic complexity to include (default: 1)"),
@@ -900,7 +901,7 @@ const TOOL_DEFINITIONS = [
900
901
  outputSchema: OutputSchemas.clones,
901
902
  description: "Find code clones: similar function pairs via hash bucketing + line-similarity.",
902
903
  schema: {
903
- repo: z.string().describe("Repository identifier"),
904
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
904
905
  file_pattern: z.string().optional().describe("Filter to files matching this path substring"),
905
906
  min_similarity: zNum().describe("Minimum similarity threshold 0-1 (default: 0.7)"),
906
907
  min_lines: zNum().describe("Minimum normalized lines to consider (default: 10)"),
@@ -922,7 +923,7 @@ const TOOL_DEFINITIONS = [
922
923
  searchHint: "frequency analysis common patterns AST shape clusters",
923
924
  description: "Group functions by normalized AST shape. Finds emergent patterns invisible to regex.",
924
925
  schema: {
925
- repo: z.string().describe("Repository identifier"),
926
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
926
927
  top_n: zNum().optional().describe("Number of clusters to return (default: 30)"),
927
928
  min_nodes: zNum().optional().describe("Minimum AST nodes in a subtree to include (default: 5)"),
928
929
  file_pattern: z.string().optional().describe("Filter to files matching this path substring"),
@@ -945,7 +946,7 @@ const TOOL_DEFINITIONS = [
945
946
  searchHint: "hotspots git churn bug-prone change frequency complexity",
946
947
  description: "Git churn hotspots: change frequency × complexity. Higher score = more bug-prone.",
947
948
  schema: {
948
- repo: z.string().describe("Repository identifier"),
949
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
949
950
  since_days: zNum().describe("Look back N days (default: 90)"),
950
951
  top_n: zNum().describe("Return top N hotspots (default: 30)"),
951
952
  file_pattern: z.string().optional().describe("Filter to files matching this path substring"),
@@ -1001,7 +1002,7 @@ const TOOL_DEFINITIONS = [
1001
1002
  searchHint: "search patterns anti-patterns CQ violations useEffect empty-catch console-log",
1002
1003
  description: "Search structural patterns/anti-patterns. Built-in or custom regex.",
1003
1004
  schema: {
1004
- repo: z.string().describe("Repository identifier"),
1005
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
1005
1006
  pattern: z.string().describe("Built-in pattern name or custom regex"),
1006
1007
  file_pattern: z.string().optional().describe("Filter to files matching this path substring"),
1007
1008
  include_tests: zBool().describe("Include test files (default: false)"),
@@ -1031,7 +1032,7 @@ const TOOL_DEFINITIONS = [
1031
1032
  searchHint: "generate HTML report complexity dead code hotspots architecture browser",
1032
1033
  description: "Generate a standalone HTML report with complexity, dead code, hotspots, and architecture. Opens in any browser.",
1033
1034
  schema: {
1034
- repo: z.string().describe("Repository identifier"),
1035
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
1035
1036
  },
1036
1037
  handler: (args) => generateReport(args.repo),
1037
1038
  },
@@ -1099,7 +1100,7 @@ const TOOL_DEFINITIONS = [
1099
1100
  outputSchema: OutputSchemas.secrets,
1100
1101
  description: "Scan for hardcoded secrets (API keys, tokens, passwords). ~1,100 rules.",
1101
1102
  schema: {
1102
- repo: z.string().describe("Repository identifier"),
1103
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
1103
1104
  file_pattern: z.string().optional().describe("Glob pattern to filter scanned files"),
1104
1105
  min_confidence: z.enum(["high", "medium", "low"]).optional().describe("Minimum confidence level (default: medium)"),
1105
1106
  exclude_tests: zBool().describe("Exclude test file findings (default: true)"),
@@ -1255,7 +1256,7 @@ const TOOL_DEFINITIONS = [
1255
1256
  searchHint: "review diff static analysis git changes secrets breaking-changes complexity dead-code blast-radius",
1256
1257
  description: "Run 9 parallel static analysis checks on a git diff: secrets, breaking changes, coupling gaps, complexity, dead-code, blast-radius, bug-patterns, test-gaps, hotspots. Returns a scored verdict (pass/warn/fail) with tiered findings.",
1257
1258
  schema: {
1258
- repo: z.string().describe("Repository identifier"),
1259
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
1259
1260
  since: z.string().optional().describe("Base git ref (default: HEAD~1)"),
1260
1261
  until: z.string().optional().describe("Target ref. Default: HEAD. Special: WORKING, STAGED"),
1261
1262
  checks: z.string().optional().describe("Comma-separated check names (default: all)"),
@@ -1332,6 +1333,31 @@ const TOOL_DEFINITIONS = [
1332
1333
  return getContext(args.repo, includeStale);
1333
1334
  },
1334
1335
  },
1336
+ // --- Project Analysis ---
1337
+ {
1338
+ name: "analyze_project",
1339
+ category: "analysis",
1340
+ searchHint: "project profile stack conventions middleware routes rate-limits auth detection",
1341
+ description: "Analyze a repository to extract stack, file classifications, and framework-specific conventions. Returns a structured project profile (schema v1.0) with file:line evidence for convention-level facts.",
1342
+ schema: {
1343
+ repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
1344
+ force: zBool().describe("Ignore cached results and re-analyze"),
1345
+ },
1346
+ handler: async (args) => {
1347
+ const result = await analyzeProject(args.repo, {
1348
+ force: args.force,
1349
+ });
1350
+ return result;
1351
+ },
1352
+ },
1353
+ {
1354
+ name: "get_extractor_versions",
1355
+ category: "meta",
1356
+ searchHint: "extractor version cache invalidation profile",
1357
+ description: "Return current extractor versions without triggering analysis. Used for cache invalidation.",
1358
+ schema: {},
1359
+ handler: async () => getExtractorVersions(),
1360
+ },
1335
1361
  ];
1336
1362
  function buildToolSummaries() {
1337
1363
  return TOOL_DEFINITIONS.map((t) => ({