codebasesearch 0.1.14 → 0.1.17

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/.prd ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "project": "code-search",
3
+ "objective": "Display relative file paths in search results from current working directory",
4
+ "created": "2026-03-05",
5
+ "items": [],
6
+ "completed": [
7
+ {
8
+ "id": "1",
9
+ "subject": "Add relative path computation to search-worker.js result mapping",
10
+ "status": "completed"
11
+ },
12
+ {
13
+ "id": "2",
14
+ "subject": "Update mcp.js output formatting to display relative paths",
15
+ "status": "completed"
16
+ },
17
+ {
18
+ "id": "3",
19
+ "subject": "Test relative path display with real searches from different directories",
20
+ "status": "completed"
21
+ }
22
+ ],
23
+ "notes": "All work complete. Search results now display relative paths computed from repositoryPath to absolute file paths. Paths are easy to locate from the directory where the search command runs."
24
+ }
package/README.md CHANGED
@@ -24,7 +24,7 @@ claude mcp add -s user codebasesearch -- bunx codebasesearch
24
24
  - **Semantic search** across entire repositories using Jina embeddings (512-dim vectors)
25
25
  - **Embedded vector database** (LanceDB) - no external servers or setup required
26
26
  - **Auto-indexing** - automatically scans and indexes repository before each search
27
- - **Comprehensive ignore patterns** - respects .gitignore and ignores build artifacts, node_modules, etc. across all languages
27
+ - **Comprehensive file filtering** - respects .gitignore, ignores build artifacts, node_modules, dependencies across all languages; includes 102 code/markup/styling file types
28
28
  - **Single-shot execution** - no persistent processes, no background daemons
29
29
  - **MCP protocol support** - integrates with Claude Code and other MCP-compatible tools
30
30
  - **Auto-gitignore** - automatically adds `.code-search/` to .gitignore on first run
@@ -71,9 +71,19 @@ search query="middleware validation" repository_path="/path/to/repo"
71
71
  7. **Returns** ranked results with line numbers and code snippets
72
72
  8. **Auto-adds** `.code-search/` to .gitignore
73
73
 
74
- ## Supported Languages
74
+ ## Supported Languages (102 Extensions)
75
75
 
76
- JavaScript, TypeScript, Python, Go, Rust, Java, C/C++, C#, Ruby, PHP, Scala, Swift, Shell, SQL, R, Lua, Perl, Groovy, XML, JSON, YAML, TOML, HTML, CSS, SCSS, Vue, and more.
76
+ **Programming**: JavaScript, TypeScript, Python, Go, Rust, Java, Kotlin, Scala, C/C++, C#, Ruby, PHP, Swift, Shell, PowerShell, Perl, Lua, R, Dart, Elixir, Erlang, Haskell, Clojure, Lisp, Fortran, Assembly, Groovy, Visual Basic, F#, OCaml, Objective-C, Arduino, CoffeeScript, Reason, Julia, MATLAB
77
+
78
+ **Markup & Data**: XML, XSD, HTML, YAML, TOML
79
+
80
+ **Styling**: CSS, SCSS, Sass, Less
81
+
82
+ **Database**: SQL
83
+
84
+ **Frontend**: Vue, Svelte
85
+
86
+ **Text & Docs**: Markdown, Plain Text
77
87
 
78
88
  ## Storage
79
89
 
package/mcp.js CHANGED
@@ -140,7 +140,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
140
140
  : `Found ${result.resultsCount} result${result.resultsCount !== 1 ? 's' : ''} for query: "${query}"\nRepository: ${result.repository}\n\n${result.results
141
141
  .map(
142
142
  (r) =>
143
- `${r.rank}. ${r.file}:${r.lines} (score: ${r.score}%)\n${r.snippet
143
+ `${r.rank}. ${r.relativePath}:${r.lines} (score: ${r.score}%)\n${r.snippet
144
144
  .split('\n')
145
145
  .map((line) => ` ${line}`)
146
146
  .join('\n')}`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codebasesearch",
3
- "version": "0.1.14",
3
+ "version": "0.1.17",
4
4
  "description": "Ultra-simple code search tool with Jina embeddings, LanceDB, and MCP protocol support",
5
5
  "type": "module",
6
6
  "bin": {
@@ -4,7 +4,7 @@ import { fileURLToPath } from 'url';
4
4
 
5
5
  const __dirname = dirname(fileURLToPath(import.meta.url));
6
6
 
7
- // Whitelist of code file extensions to include
7
+ // Unified whitelist of code file extensions to include (102 supported)
8
8
  const CODE_EXTENSIONS = new Set([
9
9
  // JavaScript/TypeScript
10
10
  '.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs', '.mts', '.cts',
@@ -15,13 +15,13 @@ const CODE_EXTENSIONS = new Set([
15
15
  // C/C++
16
16
  '.c', '.cpp', '.cc', '.cxx', '.h', '.hpp', '.hh', '.hxx',
17
17
  // C#
18
- '.cs',
18
+ '.cs', '.csx',
19
19
  // Go
20
20
  '.go',
21
21
  // Rust
22
22
  '.rs',
23
23
  // Ruby
24
- '.rb',
24
+ '.rb', '.erb',
25
25
  // PHP
26
26
  '.php', '.phtml',
27
27
  // Swift
@@ -54,7 +54,7 @@ const CODE_EXTENSIONS = new Set([
54
54
  '.hs', '.lhs',
55
55
  // Clojure
56
56
  '.clj', '.cljs', '.cljc',
57
- // Lisp
57
+ // Lisp/Scheme
58
58
  '.lisp', '.lsp', '.scm', '.ss', '.rkt',
59
59
  // Fortran
60
60
  '.f', '.for', '.f90', '.f95', '.f03',
@@ -79,7 +79,15 @@ const CODE_EXTENSIONS = new Set([
79
79
  // CoffeeScript
80
80
  '.coffee',
81
81
  // Reason
82
- '.re', '.rei'
82
+ '.re', '.rei',
83
+ // Markup/Data
84
+ '.xml', '.xsd', '.html', '.htm', '.yml', '.yaml', '.toml',
85
+ // Styling
86
+ '.css', '.scss', '.sass', '.less',
87
+ // SQL
88
+ '.sql',
89
+ // Markdown/Text
90
+ '.md', '.markdown', '.txt'
83
91
  ]);
84
92
 
85
93
  function loadDefaultIgnores() {
package/src/scanner.js CHANGED
@@ -1,36 +1,6 @@
1
1
  import { readdirSync, statSync, readFileSync } from 'fs';
2
2
  import { join, relative } from 'path';
3
- import { shouldIgnore } from './ignore-parser.js';
4
-
5
- const SUPPORTED_EXTENSIONS = new Set([
6
- '.js', '.ts', '.tsx', '.jsx', '.mjs', '.cjs',
7
- '.py', '.pyw', '.pyi',
8
- '.go',
9
- '.rs',
10
- '.java', '.kt', '.scala',
11
- '.cpp', '.cc', '.cxx', '.h', '.hpp', '.hxx',
12
- '.c', '.h',
13
- '.rb', '.erb',
14
- '.php',
15
- '.cs', '.csx',
16
- '.swift',
17
- '.m', '.mm',
18
- '.sh', '.bash', '.zsh',
19
- '.sql',
20
- '.r', '.R',
21
- '.lua',
22
- '.pl', '.pm',
23
- '.groovy',
24
- '.gradle',
25
- '.xml', '.xsd',
26
- '.yaml', '.yml',
27
- '.toml',
28
- '.html', '.htm',
29
- '.css', '.scss', '.sass', '.less',
30
- '.vue', '.svelte',
31
- '.md', '.markdown',
32
- '.txt'
33
- ]);
3
+ import { shouldIgnore, isCodeFile } from './ignore-parser.js';
34
4
 
35
5
  function getFileExtension(filePath) {
36
6
  const lastDot = filePath.lastIndexOf('.');
@@ -71,8 +41,7 @@ function walkDirectory(dirPath, ignorePatterns, relativePath = '') {
71
41
  if (entry.isDirectory()) {
72
42
  files.push(...walkDirectory(fullPath, ignorePatterns, relPath));
73
43
  } else if (entry.isFile()) {
74
- const ext = getFileExtension(entry.name);
75
- if (SUPPORTED_EXTENSIONS.has(ext) && !isBinaryFile(entry.name)) {
44
+ if (isCodeFile(normalizedRelPath) && !isBinaryFile(entry.name)) {
76
45
  try {
77
46
  const stat = entry.isSymbolicLink ? null : statSync(fullPath);
78
47
  const maxSize = 5 * 1024 * 1024;
@@ -1,5 +1,5 @@
1
1
  import { parentPort } from 'worker_threads';
2
- import { resolve } from 'path';
2
+ import { resolve, relative } from 'path';
3
3
  import { existsSync } from 'fs';
4
4
  import { loadIgnorePatterns } from './ignore-parser.js';
5
5
  import { scanRepository } from './scanner.js';
@@ -53,13 +53,17 @@ async function performSearch(repositoryPath, query) {
53
53
  query,
54
54
  repository: absolutePath,
55
55
  resultsCount: results.length,
56
- results: results.slice(0, 10).map((result, idx) => ({
57
- rank: idx + 1,
58
- file: result.file_path,
59
- lines: `${result.line_start}-${result.line_end}`,
60
- score: (result.score * 100).toFixed(1),
61
- snippet: result.content.split('\n').slice(0, 3).join('\n'),
62
- })),
56
+ results: results.slice(0, 10).map((result, idx) => {
57
+ const absoluteFilePath = resolve(absolutePath, result.file_path);
58
+ return {
59
+ rank: idx + 1,
60
+ file: result.file_path,
61
+ relativePath: relative(repositoryPath, absoluteFilePath),
62
+ lines: `${result.line_start}-${result.line_end}`,
63
+ score: (result.score * 100).toFixed(1),
64
+ snippet: result.content.split('\n').slice(0, 3).join('\n'),
65
+ };
66
+ }),
63
67
  };
64
68
  } catch (error) {
65
69
  return { error: error.message, results: [] };