@fodx/codelens 1.2.0 → 2.0.1

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 (46) hide show
  1. package/README.md +15 -10
  2. package/adapters/pi/codelens.extension.ts +6 -3
  3. package/build/src/cli.js +7 -4
  4. package/build/src/cli.js.map +1 -1
  5. package/build/src/db/migrations.js +8 -0
  6. package/build/src/db/migrations.js.map +1 -1
  7. package/build/src/graph/edges.js +4 -11
  8. package/build/src/graph/edges.js.map +1 -1
  9. package/build/src/graph/grammars.js +12 -0
  10. package/build/src/graph/grammars.js.map +1 -1
  11. package/build/src/graph/symbols.js +4 -11
  12. package/build/src/graph/symbols.js.map +1 -1
  13. package/build/src/index/freshness.js +13 -0
  14. package/build/src/index/freshness.js.map +1 -1
  15. package/build/src/index/fts.js +205 -21
  16. package/build/src/index/fts.js.map +1 -1
  17. package/build/src/index/indexer.js +2 -0
  18. package/build/src/index/indexer.js.map +1 -1
  19. package/build/src/index/reindex.js +6 -2
  20. package/build/src/index/reindex.js.map +1 -1
  21. package/build/src/index/staleness.js +16 -0
  22. package/build/src/index/staleness.js.map +1 -0
  23. package/build/src/search/identifiers.js +52 -0
  24. package/build/src/search/identifiers.js.map +1 -0
  25. package/build/src/search/query.js +13 -0
  26. package/build/src/search/query.js.map +1 -0
  27. package/build/src/search/snippet.js +2 -1
  28. package/build/src/search/snippet.js.map +1 -1
  29. package/build/src/server.js +1 -1
  30. package/build/src/server.js.map +1 -1
  31. package/build/src/tools/explore.js +110 -0
  32. package/build/src/tools/explore.js.map +1 -0
  33. package/build/src/tools/impact.js +159 -0
  34. package/build/src/tools/impact.js.map +1 -0
  35. package/build/src/tools/map.js +12 -2
  36. package/build/src/tools/map.js.map +1 -1
  37. package/build/src/tools/registry.js +48 -3
  38. package/build/src/tools/registry.js.map +1 -1
  39. package/build/src/tools/related.js +30 -10
  40. package/build/src/tools/related.js.map +1 -1
  41. package/build/src/tools/search.js +86 -19
  42. package/build/src/tools/search.js.map +1 -1
  43. package/docs/agent-guide.md +27 -5
  44. package/docs/routing.md +12 -6
  45. package/docs/tools.md +19 -3
  46. package/package.json +3 -2
@@ -3,21 +3,56 @@ import { extractSnippet, headlineSnippet } from "../search/snippet.js";
3
3
  import { rank, normalize } from "../search/rank.js";
4
4
  import { neighbors } from "../graph/query.js";
5
5
  import { ensureFreshIndex } from "../index/reindex.js";
6
+ import { getPendingPaths } from "../index/staleness.js";
7
+ import { splitIdentifiers } from "../search/identifiers.js";
8
+ import { queryTokens, quoteFtsTerm } from "../search/query.js";
6
9
  const DEFAULT_LIMIT = 5;
7
10
  /** Ranks below this (0-indexed) keep a richer preview when no mode is forced. */
8
11
  const RICH_PREVIEW_TOP_N = 3;
12
+ const QUERY_EXPANSION_MAX_TERMS = 16;
13
+ function queryTerms(query) {
14
+ const original = queryTokens(query);
15
+ const seen = new Set(original.map((t) => t.toLowerCase()));
16
+ const expanded = splitIdentifiers(query, { maxTokens: QUERY_EXPANSION_MAX_TERMS });
17
+ const terms = [...original];
18
+ for (const term of expanded) {
19
+ const lower = term.toLowerCase();
20
+ if (seen.has(lower))
21
+ continue;
22
+ seen.add(lower);
23
+ terms.push(term);
24
+ }
25
+ return terms;
26
+ }
9
27
  function ftsQuery(query) {
10
- const terms = query.split(/[^A-Za-z0-9_]+/i).filter((t) => t.length > 0);
11
- if (terms.length === 0)
28
+ const original = queryTokens(query);
29
+ if (original.length === 0)
12
30
  return "";
13
- return terms.map((t) => `"${t}"`).join(" OR ");
31
+ const expressions = [];
32
+ const seen = new Set();
33
+ for (const term of original) {
34
+ const quoted = quoteFtsTerm(term);
35
+ if (!seen.has(quoted)) {
36
+ seen.add(quoted);
37
+ expressions.push(quoted);
38
+ }
39
+ const parts = splitIdentifiers(term, { maxTokens: QUERY_EXPANSION_MAX_TERMS });
40
+ if (parts.length > 1) {
41
+ const group = `(${parts.map(quoteFtsTerm).join(" AND ")})`;
42
+ if (!seen.has(group)) {
43
+ seen.add(group);
44
+ expressions.push(group);
45
+ }
46
+ }
47
+ }
48
+ return expressions.join(" OR ");
14
49
  }
15
50
  function gatherFts(db, indexId, fts, limit, contentType) {
16
51
  const typeClause = contentType ? " AND c.content_type = ?" : "";
17
52
  const params = contentType ? [fts, indexId, contentType, limit] : [fts, indexId, limit];
18
53
  return db
19
54
  .prepare(`SELECT c.path AS path, c.start_line AS startLine, c.end_line AS endLine,
20
- c.content AS content, c.id AS chunkId, c.content_type AS contentType,
55
+ c.content AS content, c.id AS chunkId, c.symbol_id AS symbolId, c.content_type AS contentType,
21
56
  bm25(chunks_fts) AS rank
22
57
  FROM chunks_fts
23
58
  JOIN chunks c ON c.id = chunks_fts.chunk_id
@@ -28,9 +63,11 @@ function gatherFts(db, indexId, fts, limit, contentType) {
28
63
  /** Build hybrid signals (FTS + symbol + graph). */
29
64
  function buildSignals(db, indexId, query, ftsRows) {
30
65
  const ftsNorm = normalize(ftsRows.map((r) => -r.rank));
31
- const terms = query.toLowerCase().split(/[^a-z0-9_]+/i).filter((t) => t.length > 1);
66
+ const terms = queryTerms(query).map((t) => t.toLowerCase()).filter((t) => t.length > 1);
32
67
  const symbolStmt = db.prepare(`SELECT 1 FROM symbols WHERE index_id = ? AND path = ? AND lower(name) LIKE ? LIMIT 1`);
33
68
  const exactStmt = db.prepare(`SELECT 1 FROM symbols WHERE index_id = ? AND path = ? AND lower(name) = ? LIMIT 1`);
69
+ const chunkSymbolStmt = db.prepare(`SELECT lower(name) AS name FROM symbols WHERE index_id = ? AND id = ? LIMIT 1`);
70
+ const symbolNameById = new Map();
34
71
  const topPaths = new Set(ftsRows.slice(0, 8).map((r) => r.path));
35
72
  const graphPaths = new Set();
36
73
  for (const p of topPaths) {
@@ -43,8 +80,20 @@ function buildSignals(db, indexId, query, ftsRows) {
43
80
  catch { /* ignore */ }
44
81
  }
45
82
  return ftsRows.map((r, i) => {
46
- const symMatch = terms.some((t) => !!symbolStmt.get(indexId, r.path, "%" + t + "%"));
47
- const exactMatch = terms.some((t) => !!exactStmt.get(indexId, r.path, t));
83
+ let chunkSymbolName = null;
84
+ if (r.symbolId) {
85
+ if (!symbolNameById.has(r.symbolId)) {
86
+ const row = chunkSymbolStmt.get(indexId, r.symbolId);
87
+ symbolNameById.set(r.symbolId, row?.name ?? null);
88
+ }
89
+ chunkSymbolName = symbolNameById.get(r.symbolId) ?? null;
90
+ }
91
+ const chunkSymMatch = !!chunkSymbolName && terms.some((t) => chunkSymbolName.includes(t));
92
+ const chunkExactMatch = !!chunkSymbolName && terms.some((t) => chunkSymbolName === t);
93
+ const fileSymMatch = terms.some((t) => !!symbolStmt.get(indexId, r.path, "%" + t + "%"));
94
+ const fileExactMatch = terms.some((t) => !!exactStmt.get(indexId, r.path, t));
95
+ const symMatch = chunkSymMatch ? 1 : (fileSymMatch ? 0.5 : 0);
96
+ const exactMatch = chunkExactMatch ? 1 : (fileExactMatch ? 0.5 : 0);
48
97
  const pathLower = r.path.toLowerCase();
49
98
  const pathMatch = terms.some((t) => pathLower.includes(t));
50
99
  return {
@@ -53,8 +102,8 @@ function buildSignals(db, indexId, query, ftsRows) {
53
102
  endLine: r.endLine,
54
103
  chunkId: r.chunkId,
55
104
  fts: ftsNorm[i],
56
- symbol: symMatch ? 1 : 0,
57
- exact: exactMatch ? 1 : 0,
105
+ symbol: symMatch,
106
+ exact: exactMatch,
58
107
  graph: graphPaths.has(r.path) ? 1 : 0,
59
108
  pathHit: pathMatch ? 1 : 0,
60
109
  code: r.contentType === "code" ? 1 : 0,
@@ -71,6 +120,14 @@ function prelude(db, opts) {
71
120
  pendingFiles = r.pending;
72
121
  }
73
122
  }
123
+ const indexId = getActiveIndexId();
124
+ if (indexId) {
125
+ const pending = getPendingPaths(indexId).size;
126
+ if (pending > 0) {
127
+ freshness = "partial";
128
+ pendingFiles = pending;
129
+ }
130
+ }
74
131
  return { freshness, pendingFiles };
75
132
  }
76
133
  export function ctxSearch(db, query, opts) {
@@ -82,8 +139,12 @@ export function ctxSearch(db, query, opts) {
82
139
  const limit = opts?.limit ?? DEFAULT_LIMIT;
83
140
  const offset = decodeCursor(opts?.cursor);
84
141
  const fts = ftsQuery(query);
85
- if (fts.length === 0)
86
- return { indexId, results: [], nextCursor: null, freshness: "fresh" };
142
+ if (fts.length === 0) {
143
+ const out = { indexId, query, count: 0, results: [], freshness };
144
+ if (pendingFiles !== undefined)
145
+ out.pendingFiles = pendingFiles;
146
+ return out;
147
+ }
87
148
  const ftsRows = gatherFts(db, indexId, fts, limit * 4, opts?.contentType);
88
149
  const signals = buildSignals(db, indexId, query, ftsRows);
89
150
  const ranked = rank(signals);
@@ -117,22 +178,28 @@ export function ctxSearch(db, query, opts) {
117
178
  case "full": return extractSnippet(src.content, query, 1500);
118
179
  }
119
180
  };
181
+ const pendingPaths = getPendingPaths(indexId);
120
182
  const results = page.map((r, i) => {
121
183
  const src = r.chunkId ? byChunk.get(r.chunkId) : undefined;
122
184
  const rankOffset = offset + i;
123
- return {
185
+ const item = {
124
186
  handle: r.chunkId ?? "",
125
187
  path: r.path,
126
- startLine: r.startLine,
127
- endLine: r.endLine,
128
- score: r.score,
129
- snippet: src ? renderPreview(src, rankOffset) : r.path,
130
- cursor: encodeCursor(rankOffset, r.chunkId ?? `${rankOffset}`),
131
- why: r.why,
188
+ lines: `${r.startLine}-${r.endLine}`,
189
+ score: Math.round(r.score * 1000) / 1000,
190
+ why: r.why.join(","),
191
+ preview: src ? renderPreview(src, rankOffset) : "",
132
192
  };
193
+ if (pendingPaths.has(r.path))
194
+ item.stale = true;
195
+ return item;
133
196
  });
134
197
  const nextCursor = hasMore && results.length > 0 ? encodeCursor(offset + results.length, results[results.length - 1].handle || `${offset}`) : null;
135
- const out = { indexId, results, nextCursor, freshness, pendingFiles };
198
+ const out = { indexId, query, count: results.length, results, freshness };
199
+ if (pendingFiles !== undefined)
200
+ out.pendingFiles = pendingFiles;
201
+ if (nextCursor)
202
+ out.nextCursor = nextCursor;
136
203
  if (opts?.related && results[0]) {
137
204
  try {
138
205
  out.related = neighbors(db, indexId, results[0].path, { types: ["imports", "imported_by", "tests"], depth: 1 });
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/tools/search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/tools/search.ts"],"names":[],"mappings":"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"}
@@ -11,11 +11,17 @@ End-to-end workflow for a coding agent using codelens.
11
11
  2. cl_refresh
12
12
  → { indexedFiles: 812, totalChunks: 2400, status: "ready" }
13
13
 
14
- 3. cl_search(query: "session validation")
15
- results: [
16
- { handle: "chk_…", path: "src/auth/session.ts", symbol: "validateSession",
17
- startLine: 12, endLine: 58, score: 0.92, why: ["fts","symbol","graph"] }
18
- ]
14
+ 3. cl_explore(query: "session validation flow")
15
+ { query: "session validation flow", count: 3,
16
+ files: [{ path: "src/auth/session.ts", results: [{ handle: "chk_…", lines: "12-58", preview: "export function validateSession" }] }],
17
+ related: [{ sourcePath: "src/auth/session.ts", path: "src/routes/login.ts", edgeType: "imported_by", hops: 1 }] }
18
+
19
+ # If you only need to locate a handle, use the leaner search tool:
20
+ cl_search(query: "session validation")
21
+ → { query: "session validation", count: 1, results: [
22
+ { handle: "chk_…", path: "src/auth/session.ts", lines: "12-58",
23
+ score: 0.92, why: "fts,symbol,graph", preview: "export function validateSession(token: string): boolean" }
24
+ ] }
19
25
 
20
26
  4. cl_related(path: "src/auth/session.ts", types: ["tests","imported_by"])
21
27
  → results: [
@@ -24,6 +30,10 @@ End-to-end workflow for a coding agent using codelens.
24
30
  ]
25
31
  # TS/JS also populate `calls`/`references` and resolve dynamic import().
26
32
 
33
+ # Before changing shared code, ask for the blast radius.
34
+ cl_impact(symbol: "validateSession", path: "src/auth/session.ts")
35
+ → { callers: [...], callees: [...], affectedFiles: [...], affectedTests: [...], confidenceNote: "…" }
36
+
27
37
  # Orientation (optional): outline a file or directory without reading it.
28
38
  cl_map(path: "src/auth")
29
39
  → files: [{ path: "src/auth/session.ts", symbols: [{ name: "validateSession", kind: "function", signature: "export function validateSession(token: string): boolean" }] }]
@@ -37,6 +47,14 @@ End-to-end workflow for a coding agent using codelens.
37
47
  8. cl_load(name: "auth-investigation") # after compaction
38
48
  ```
39
49
 
50
+ ## Tool choice
51
+
52
+ - Use `cl_explore` for broad questions: "how does X work?", "show the flow around Y", or surveying an unfamiliar area. It combines search, compact source previews, and relationships in one call.
53
+ - Use `cl_search` when you only need ranked handles/locations.
54
+ - Use `cl_related` to expand from a known file.
55
+ - Use `cl_impact` before editing shared code to see callers/callees/affected tests.
56
+ - Use `cl_expand` (or raw read) for exact current file content before editing.
57
+
40
58
  ## Branch switch
41
59
 
42
60
  ```
@@ -46,6 +64,10 @@ cl_refresh → builds feature-b index; main's results no longer leak in
46
64
  ```
47
65
 
48
66
 
67
+ ## Freshness and stale results
68
+
69
+ Query tools reconcile changed files before answering. If a response includes `freshness: "partial"`, `pendingFiles`, or per-result `stale:true`, read those stale files directly (`cl_expand` or raw read) before relying on indexed previews/edges.
70
+
49
71
  ## Saving context across compaction
50
72
 
51
73
  `cl_save` / `cl_load` persist named handle sets in a **separate** DB that
package/docs/routing.md CHANGED
@@ -14,14 +14,16 @@ right tool for the job.
14
14
 
15
15
  Prefer codelens when:
16
16
  - you don't know the exact name/string (semantic or conceptual search via `cl_search`)
17
- - you need relationships importers, tests, callers (`cl_related`) — or a
18
- per-file outline / repo map (`cl_map`)
17
+ - you need broad orientation in one call (`cl_explore`) — "how does X work?", flows, or unfamiliar areas
18
+ - you need relationships importers, tests, callers (`cl_related`) — or blast radius before edits (`cl_impact`)
19
+ - you need a per-file outline / repo map (`cl_map`)
19
20
  - the repo is large or unfamiliar, or you'd otherwise grep + read many files
20
21
  - branch-scoped correctness matters (results won't leak across branches)
21
22
 
22
23
  Then use `cl_expand` to read the exact current content of a chosen target (it
23
24
  reads from disk — never stale), and `cl_save`/`cl_load` to persist working
24
- context across compaction.
25
+ context across compaction. If a query result has `stale:true`, read that file
26
+ from disk before relying on indexed snippets/edges.
25
27
 
26
28
  ## When raw grep/find/read is fine (or better)
27
29
 
@@ -44,9 +46,11 @@ branch's index automatically.
44
46
 
45
47
  ## Freshness
46
48
 
47
- `cl_search` auto-refreshes changed files before returning (budget-bounded). If
48
- the response carries `freshness: "partial"` and `pendingFiles > 0`, some very
49
- recent edits may not yet be reflected call `cl_refresh` or re-query.
49
+ Query tools auto-refresh changed files before returning (budget-bounded). If
50
+ the response carries `freshness: "partial"`, `pendingFiles > 0`, or per-result
51
+ `stale:true`, some recent edits were not reindexed within the budget. Read those
52
+ files directly with `cl_expand`/raw read, then call `cl_refresh` or re-query when
53
+ you need indexed relationships to catch up.
50
54
 
51
55
  ## Tool quick reference
52
56
 
@@ -55,7 +59,9 @@ recent edits may not yet be reflected — call `cl_refresh` or re-query.
55
59
  | `cl_current` | repo/branch/index status + freshness |
56
60
  | `cl_refresh` | build/update the current branch index |
57
61
  | `cl_search` | hybrid ranked search → compact handles |
62
+ | `cl_explore` | one-call grouped search + previews + relationship map |
58
63
  | `cl_related` | graph neighbors (imports/tests/callers) |
64
+ | `cl_impact` | callers/callees/affected files/tests before edits |
59
65
  | `cl_map` | per-file symbol outline (repo map) |
60
66
  | `cl_expand` | exact current file content by path/range |
61
67
  | `cl_save` / `cl_load` | persist + reload working context |
package/docs/tools.md CHANGED
@@ -15,21 +15,37 @@ JSON-serialized text content.
15
15
 
16
16
  ## cl_search
17
17
  - **Input**: `{ query: string, limit?: number=5, cursor?: string, contentType?: "code"|"prose", related?: boolean, snippet?: "none"|"headline"|"compact"|"full" }`
18
- - **Returns**: `{ indexId, results:[{handle,path,startLine,endLine,score,snippet,why}], nextCursor, freshness, pendingFiles, related? }`
18
+ - **Returns**: `{ indexId, query, count, results:[{handle,path,lines,score,why,preview,stale?}], freshness, nextCursor?, pendingFiles?, related? }`
19
+ - `lines` is `"start-end"`; `why` is a comma-joined signal string; `preview` is a short highlighted snippet (empty when `snippet:"none"`). Use `handle` with `cl_expand`/`cl_save`. Pagination uses the top-level `nextCursor` (no per-result cursor). If `stale:true`, read that file from disk (`cl_expand`/raw read) before relying on indexed content.
19
20
  - **Use**: intent-level code discovery.
21
+ - **Identifier matching**: code identifiers are indexed with bounded subtokens (`validateSession` also matches `session`) in the match-only FTS text. Query expansion uses the same bounded splitter and preserves snippets/handles from stored chunk content.
20
22
  - **`snippet` (preview verbosity)**: default is signature-first `headline` (richer `compact` for the top ~3 results), which keeps payloads small. `none` returns path+lines only (fetch with `cl_expand`); `compact`/`full` return larger code windows. Explicitly setting `snippet` applies that mode to all results.
21
23
  - **`why` signals**: `fts|symbol|exact|graph|path|code` (exact = exact symbol-name match; path = query term in the file path). Ranking is deterministic with a stable tie-break.
24
+ - **Line-range format**: `cl_search` reports `lines` as a `"start-end"` string for compact display; `cl_map` and `cl_expand` use numeric `startLine`/`endLine` for programmatic use. This difference is intentional.
25
+
26
+ ## cl_explore
27
+ - **Input**: `{ query: string, limit?: number=8, cursor?: string, contentType?: "code"|"prose", snippet?: "none"|"headline"|"compact"|"full", relatedDepth?: number=1 }`
28
+ - **Returns**: `{ indexId, query, count, files:[{path, stale?, results:[{handle,lines,score,why,preview,signature?,collapsed?,stale?}]}], related:[{sourcePath,path,edgeType,hops,confidence,stale?}], freshness, pendingFiles?, nextCursor? }`
29
+ - **Use**: broad orientation in one call — "how does X work?", "show the flow around Y", or surveying an unfamiliar area. It fuses `cl_search` + grouped previews + graph relationships; use `cl_search` when you only need to locate handles.
22
30
 
23
31
  ## cl_related
24
32
  - **Input**: `{ path: string, types?: string[], depth?: number=2, direction?: "out"|"in"|"both" }`
25
- - **Returns**: `{ indexId, results:[{handle,path,edgeType,hops,confidence}] }`
33
+ - **Returns**: `{ indexId, results:[{handle,path,edgeType,hops,confidence,stale?}], freshness?, pendingFiles? }`
26
34
  - **Edge types**: `imports|imported_by|tests|calls|references|defines|exports|belongs_to` (TS/JS populate `calls`/`references` and resolve dynamic `import()`).
27
35
 
36
+ ## cl_impact
37
+ - **Input**: `{ symbol?: string, path?: string, depth?: number=2, includeTests?: boolean=true }`
38
+ - **Returns**: `{ indexId, target?, candidates?, callers, callees, affectedFiles, affectedTests, depth, confidenceNote, freshness?, pendingFiles? }`
39
+ - **Use**: before changing shared code. Pass `symbol` plus `path` when possible; if a symbol is ambiguous, CodeLens returns `candidates` instead of guessing. Impact is edge-derived and includes confidence/hop counts; use `cl_expand` to inspect exact current code before editing.
40
+
28
41
  ## cl_map
29
42
  - **Input**: `{ path?: string, limit?: number=50, all?: boolean }`
30
- - **Returns**: `{ indexId, files:[{path, symbols:[{name,kind,signature,startLine,endLine,exported}]}], fileCount, truncated }`
43
+ - **Returns**: `{ indexId, files:[{path, stale?, symbols:[{name,kind,signature,startLine,endLine,exported}]}], fileCount, truncated, freshness?, pendingFiles? }`
31
44
  - **Use**: outline / repo-map for orientation — per-file symbol signatures from the index (no file re-read). Defaults to exported symbols; pass `all:true` for everything. File-capped (default 50, max 200) with a `truncated` flag.
32
45
 
46
+ ## Freshness and stale flags
47
+ Query tools perform a budget-bounded reconciliation before answering. If the response has `freshness:"partial"` and `pendingFiles > 0`, some changed files were not reindexed within the budget. Results/files with `stale:true` point at those known-stale paths; read them directly with `cl_expand` or a raw read before depending on indexed previews/edges.
48
+
33
49
  ## cl_expand
34
50
  - **Input**: `{ path?: string, handle?: string, startLine?: number, endLine?: number, budget?: number=4000 }`
35
51
  - **Returns**: `{ path, startLine, endLine, content, truncated, chars }`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fodx/codelens",
3
- "version": "1.2.0",
3
+ "version": "2.0.1",
4
4
  "description": "Local, branch-aware code search & relation graph. SQLite FTS5 + tree-sitter symbols + source-graph edges, exposed as an MCP server and CLI. No chat LLM required.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -57,7 +57,8 @@
57
57
  "prepublishOnly": "npm run build",
58
58
  "mcp:smoke": "node build/src/server.js --smoke",
59
59
  "start": "node build/src/server.js",
60
- "benchmark": "npx tsx bench/run.ts"
60
+ "benchmark": "npx tsx bench/run.ts",
61
+ "quality": "npx tsx bench/quality.ts"
61
62
  },
62
63
  "dependencies": {
63
64
  "@modelcontextprotocol/sdk": "^1.26.0",