codebasesearch 0.1.14 → 0.1.16

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,31 @@
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
+ {
7
+ "id": "3",
8
+ "subject": "Test relative path display with real searches from different directories",
9
+ "status": "pending",
10
+ "description": "Execute real searches from root, nested directory, and different locations. Verify relative paths are displayed correctly in each case. Test with files at various depths.",
11
+ "category": "feature",
12
+ "effort": "medium",
13
+ "blocking": [],
14
+ "blockedBy": ["2"],
15
+ "acceptance": [
16
+ "Search from /config/code-search shows relative paths",
17
+ "Search from /config shows paths like code-search/src/file.js",
18
+ "Search from nested dir shows correct relative paths",
19
+ "All file paths are correct and usable"
20
+ ],
21
+ "scenarios": [
22
+ "Search from repository root",
23
+ "Search from parent directory",
24
+ "Search from nested directory within repo",
25
+ "Files at root level vs deep nesting"
26
+ ]
27
+ }
28
+ ],
29
+ "completed": [],
30
+ "notes": "Results constructed in search-worker.js, formatted in mcp.js. Path.relative() available via path module already imported in search-worker.js."
31
+ }
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.16",
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: [] };