@tai-io/codesearch 2026.313.1626 → 2026.313.1653
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/README.md +115 -115
- package/dist/build-info.d.ts +2 -2
- package/dist/build-info.js +2 -2
- package/dist/config.d.ts +5 -5
- package/dist/config.js +2 -2
- package/dist/hooks/cli-router.d.ts +1 -1
- package/dist/hooks/cli-router.js +1 -1
- package/dist/index.js +3 -3
- package/dist/paths.js +2 -2
- package/dist/state/snapshot.js +1 -1
- package/dist/vectordb/sqlite.js +6 -3
- package/messages.yaml +10 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,115 +1,115 @@
|
|
|
1
|
-
# @tai-io/codesearch
|
|
2
|
-
|
|
3
|
-
Semantic code search MCP server for [Claude Code](https://claude.ai/code). Index any codebase and search it by meaning, not just keywords.
|
|
4
|
-
|
|
5
|
-
## How it works
|
|
6
|
-
|
|
7
|
-
1. **Index** a codebase — files are parsed with tree-sitter (AST-aware chunking for 10 languages), embedded via OpenAI, and stored in a local SQLite database
|
|
8
|
-
2. **Search** by natural language — queries are embedded and matched using hybrid search (dense vectors + full-text, RRF fusion)
|
|
9
|
-
3. Results return in a compact table (~20 tokens/result) so Claude can efficiently decide what to read in full
|
|
10
|
-
|
|
11
|
-
All data is stored locally under `~/.
|
|
12
|
-
|
|
13
|
-
## Quick start
|
|
14
|
-
|
|
15
|
-
### Prerequisites
|
|
16
|
-
|
|
17
|
-
- Node.js >= 20
|
|
18
|
-
- An OpenAI API key (for embeddings), or Ollama running locally
|
|
19
|
-
|
|
20
|
-
### Install as a Claude Code MCP server
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
claude mcp add -s user -e OPENAI_API_KEY
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Or add the MCP config directly:
|
|
29
|
-
|
|
30
|
-
```json
|
|
31
|
-
{
|
|
32
|
-
"
|
|
33
|
-
"command": "npx",
|
|
34
|
-
"args": ["@tai-io/codesearch"],
|
|
35
|
-
"env": {
|
|
36
|
-
"OPENAI_API_KEY": "sk-..."
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### Use it
|
|
43
|
-
|
|
44
|
-
Once configured, Claude Code has 8 new tools:
|
|
45
|
-
|
|
46
|
-
| Tool | Example | What it does |
|
|
47
|
-
|------|---------|--------------|
|
|
48
|
-
| `index` | `index(path="/my/project")` | Index a codebase (~30s one-time) |
|
|
49
|
-
| `search` | `search(query="how does auth work")` | Semantic search |
|
|
50
|
-
| `list` | `list()` | See indexed codebases |
|
|
51
|
-
| `browse` | `browse(path="/my/project")` | Structural map of classes/functions |
|
|
52
|
-
| `clear` | `clear(path="/my/project")` | Remove index |
|
|
53
|
-
| `cleanup` | `cleanup(path="/my/project")` | Remove vectors for deleted files |
|
|
54
|
-
| `ingest` | `ingest(content="...", library="react", ...)` | Cache external docs |
|
|
55
|
-
| `lookup` | `lookup(query="react hooks")` | Search cached docs |
|
|
56
|
-
|
|
57
|
-
## Tools
|
|
58
|
-
|
|
59
|
-
| Tool | Description |
|
|
60
|
-
|------|-------------|
|
|
61
|
-
| `index` | Index a codebase for semantic search. Incremental — only re-embeds changed files. |
|
|
62
|
-
| `search` | Search indexed code by natural language. Returns compact results (~20 tokens each). |
|
|
63
|
-
| `list` | List all indexed codebases with status and file/chunk counts. |
|
|
64
|
-
| `browse` | Structural map — classes, functions, methods with signatures, grouped by file. |
|
|
65
|
-
| `clear` | Remove the search index for a codebase. |
|
|
66
|
-
| `cleanup` | Remove orphaned vectors for deleted files. No embedding cost. |
|
|
67
|
-
| `ingest` | Cache external documentation for cheap semantic search later. |
|
|
68
|
-
| `lookup` | Search cached documentation (~20 tokens/result vs ~5K for re-fetching). |
|
|
69
|
-
|
|
70
|
-
## Supported languages
|
|
71
|
-
|
|
72
|
-
AST-aware chunking (via tree-sitter): TypeScript, JavaScript, Python, Go, Java, Rust, C++, C, C#, TSX.
|
|
73
|
-
|
|
74
|
-
Line-based fallback for all other text files.
|
|
75
|
-
|
|
76
|
-
## Configuration
|
|
77
|
-
|
|
78
|
-
All configuration is via environment variables:
|
|
79
|
-
|
|
80
|
-
| Variable | Default | Description |
|
|
81
|
-
|----------|---------|-------------|
|
|
82
|
-
| `OPENAI_API_KEY` | *required* | OpenAI API key for embeddings |
|
|
83
|
-
| `EMBEDDING_PROVIDER` | `openai` | `openai`, `ollama`, or `local` |
|
|
84
|
-
| `EMBEDDING_MODEL` | `text-embedding-3-small` | Embedding model name |
|
|
85
|
-
| `OPENAI_BASE_URL` | — | Override base URL (for proxies or compatible APIs) |
|
|
86
|
-
| `OLLAMA_BASE_URL` | `http://localhost:11434/v1` | Ollama server URL |
|
|
87
|
-
| `EMBEDDING_BATCH_SIZE` | `100` | Vectors per API call (1–2048) |
|
|
88
|
-
| `INDEXING_CONCURRENCY` | `8` | Parallel file processing (1–32) |
|
|
89
|
-
| `
|
|
90
|
-
| `CUSTOM_EXTENSIONS` | `[]` | Additional file extensions as JSON array |
|
|
91
|
-
| `CUSTOM_IGNORE_PATTERNS` | `[]` | Additional glob ignore patterns as JSON array |
|
|
92
|
-
|
|
93
|
-
### Using Ollama (free, local)
|
|
94
|
-
|
|
95
|
-
```bash
|
|
96
|
-
# Install and start Ollama with an embedding model
|
|
97
|
-
ollama pull nomic-embed-text
|
|
98
|
-
|
|
99
|
-
# Configure
|
|
100
|
-
export EMBEDDING_PROVIDER=ollama
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
## Development
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
git clone https://github.com/tai-io/codesearch.git
|
|
107
|
-
cd codesearch
|
|
108
|
-
npm install
|
|
109
|
-
npm run build
|
|
110
|
-
npm test
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
## License
|
|
114
|
-
|
|
115
|
-
MIT
|
|
1
|
+
# @tai-io/codesearch
|
|
2
|
+
|
|
3
|
+
Semantic code search MCP server for [Claude Code](https://claude.ai/code). Index any codebase and search it by meaning, not just keywords.
|
|
4
|
+
|
|
5
|
+
## How it works
|
|
6
|
+
|
|
7
|
+
1. **Index** a codebase — files are parsed with tree-sitter (AST-aware chunking for 10 languages), embedded via OpenAI, and stored in a local SQLite database
|
|
8
|
+
2. **Search** by natural language — queries are embedded and matched using hybrid search (dense vectors + full-text, RRF fusion)
|
|
9
|
+
3. Results return in a compact table (~20 tokens/result) so Claude can efficiently decide what to read in full
|
|
10
|
+
|
|
11
|
+
All data is stored locally under `~/.codesearch/`. No external servers required.
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
### Prerequisites
|
|
16
|
+
|
|
17
|
+
- Node.js >= 20
|
|
18
|
+
- An OpenAI API key (for embeddings), or Ollama running locally
|
|
19
|
+
|
|
20
|
+
### Install as a Claude Code MCP server
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
export OPENAI_API_KEY=sk-...
|
|
24
|
+
npm install -g @tai-io/codesearch
|
|
25
|
+
claude mcp add -s user -e "OPENAI_API_KEY=$OPENAI_API_KEY" codesearch -- npx @tai-io/codesearch
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or add the MCP config directly:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"codesearch": {
|
|
33
|
+
"command": "npx",
|
|
34
|
+
"args": ["@tai-io/codesearch"],
|
|
35
|
+
"env": {
|
|
36
|
+
"OPENAI_API_KEY": "sk-..."
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Use it
|
|
43
|
+
|
|
44
|
+
Once configured, Claude Code has 8 new tools:
|
|
45
|
+
|
|
46
|
+
| Tool | Example | What it does |
|
|
47
|
+
|------|---------|--------------|
|
|
48
|
+
| `index` | `index(path="/my/project")` | Index a codebase (~30s one-time) |
|
|
49
|
+
| `search` | `search(query="how does auth work")` | Semantic search |
|
|
50
|
+
| `list` | `list()` | See indexed codebases |
|
|
51
|
+
| `browse` | `browse(path="/my/project")` | Structural map of classes/functions |
|
|
52
|
+
| `clear` | `clear(path="/my/project")` | Remove index |
|
|
53
|
+
| `cleanup` | `cleanup(path="/my/project")` | Remove vectors for deleted files |
|
|
54
|
+
| `ingest` | `ingest(content="...", library="react", ...)` | Cache external docs |
|
|
55
|
+
| `lookup` | `lookup(query="react hooks")` | Search cached docs |
|
|
56
|
+
|
|
57
|
+
## Tools
|
|
58
|
+
|
|
59
|
+
| Tool | Description |
|
|
60
|
+
|------|-------------|
|
|
61
|
+
| `index` | Index a codebase for semantic search. Incremental — only re-embeds changed files. |
|
|
62
|
+
| `search` | Search indexed code by natural language. Returns compact results (~20 tokens each). |
|
|
63
|
+
| `list` | List all indexed codebases with status and file/chunk counts. |
|
|
64
|
+
| `browse` | Structural map — classes, functions, methods with signatures, grouped by file. |
|
|
65
|
+
| `clear` | Remove the search index for a codebase. |
|
|
66
|
+
| `cleanup` | Remove orphaned vectors for deleted files. No embedding cost. |
|
|
67
|
+
| `ingest` | Cache external documentation for cheap semantic search later. |
|
|
68
|
+
| `lookup` | Search cached documentation (~20 tokens/result vs ~5K for re-fetching). |
|
|
69
|
+
|
|
70
|
+
## Supported languages
|
|
71
|
+
|
|
72
|
+
AST-aware chunking (via tree-sitter): TypeScript, JavaScript, Python, Go, Java, Rust, C++, C, C#, TSX.
|
|
73
|
+
|
|
74
|
+
Line-based fallback for all other text files.
|
|
75
|
+
|
|
76
|
+
## Configuration
|
|
77
|
+
|
|
78
|
+
All configuration is via environment variables:
|
|
79
|
+
|
|
80
|
+
| Variable | Default | Description |
|
|
81
|
+
|----------|---------|-------------|
|
|
82
|
+
| `OPENAI_API_KEY` | *required* | OpenAI API key for embeddings |
|
|
83
|
+
| `EMBEDDING_PROVIDER` | `openai` | `openai`, `ollama`, or `local` |
|
|
84
|
+
| `EMBEDDING_MODEL` | `text-embedding-3-small` | Embedding model name |
|
|
85
|
+
| `OPENAI_BASE_URL` | — | Override base URL (for proxies or compatible APIs) |
|
|
86
|
+
| `OLLAMA_BASE_URL` | `http://localhost:11434/v1` | Ollama server URL |
|
|
87
|
+
| `EMBEDDING_BATCH_SIZE` | `100` | Vectors per API call (1–2048) |
|
|
88
|
+
| `INDEXING_CONCURRENCY` | `8` | Parallel file processing (1–32) |
|
|
89
|
+
| `CODESEARCH_DATA_DIR` | `~/.codesearch` | Data directory for indexes and state |
|
|
90
|
+
| `CUSTOM_EXTENSIONS` | `[]` | Additional file extensions as JSON array |
|
|
91
|
+
| `CUSTOM_IGNORE_PATTERNS` | `[]` | Additional glob ignore patterns as JSON array |
|
|
92
|
+
|
|
93
|
+
### Using Ollama (free, local)
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Install and start Ollama with an embedding model
|
|
97
|
+
ollama pull nomic-embed-text
|
|
98
|
+
|
|
99
|
+
# Configure
|
|
100
|
+
export EMBEDDING_PROVIDER=ollama
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Development
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
git clone https://github.com/tai-io/codesearch.git
|
|
107
|
+
cd codesearch
|
|
108
|
+
npm install
|
|
109
|
+
npm run build
|
|
110
|
+
npm test
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
MIT
|
package/dist/build-info.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare const BUILD_VERSION = "2026.313.
|
|
2
|
-
export declare const BUILD_TIMESTAMP = "2026-03-13T16:
|
|
1
|
+
export declare const BUILD_VERSION = "2026.313.1653";
|
|
2
|
+
export declare const BUILD_TIMESTAMP = "2026-03-13T16:53:39.927Z";
|
|
3
3
|
//# sourceMappingURL=build-info.d.ts.map
|
package/dist/build-info.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// Auto-generated by scripts/generate-build-info.ts — do not edit
|
|
2
|
-
export const BUILD_VERSION = '2026.313.
|
|
3
|
-
export const BUILD_TIMESTAMP = '2026-03-13T16:
|
|
2
|
+
export const BUILD_VERSION = '2026.313.1653';
|
|
3
|
+
export const BUILD_TIMESTAMP = '2026-03-13T16:53:39.927Z';
|
|
4
4
|
//# sourceMappingURL=build-info.js.map
|
package/dist/config.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
|
|
|
7
7
|
embeddingModel: z.ZodOptional<z.ZodString>;
|
|
8
8
|
embeddingBatchSize: z.ZodDefault<z.ZodNumber>;
|
|
9
9
|
indexingConcurrency: z.ZodDefault<z.ZodNumber>;
|
|
10
|
-
|
|
10
|
+
dataDir: z.ZodDefault<z.ZodString>;
|
|
11
11
|
customExtensions: z.ZodEffects<z.ZodDefault<z.ZodArray<z.ZodString, "many">>, string[], unknown>;
|
|
12
12
|
customIgnorePatterns: z.ZodEffects<z.ZodDefault<z.ZodArray<z.ZodString, "many">>, string[], unknown>;
|
|
13
13
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -16,7 +16,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
|
|
|
16
16
|
ollamaBaseUrl: string;
|
|
17
17
|
embeddingBatchSize: number;
|
|
18
18
|
indexingConcurrency: number;
|
|
19
|
-
|
|
19
|
+
dataDir: string;
|
|
20
20
|
customExtensions: string[];
|
|
21
21
|
customIgnorePatterns: string[];
|
|
22
22
|
openaiBaseUrl?: string | undefined;
|
|
@@ -29,7 +29,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
|
|
|
29
29
|
embeddingModel?: string | undefined;
|
|
30
30
|
embeddingBatchSize?: number | undefined;
|
|
31
31
|
indexingConcurrency?: number | undefined;
|
|
32
|
-
|
|
32
|
+
dataDir?: string | undefined;
|
|
33
33
|
customExtensions?: unknown;
|
|
34
34
|
customIgnorePatterns?: unknown;
|
|
35
35
|
}>, {
|
|
@@ -39,7 +39,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
|
|
|
39
39
|
ollamaBaseUrl: string;
|
|
40
40
|
embeddingBatchSize: number;
|
|
41
41
|
indexingConcurrency: number;
|
|
42
|
-
|
|
42
|
+
dataDir: string;
|
|
43
43
|
customExtensions: string[];
|
|
44
44
|
customIgnorePatterns: string[];
|
|
45
45
|
openaiBaseUrl?: string | undefined;
|
|
@@ -51,7 +51,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
|
|
|
51
51
|
embeddingModel?: string | undefined;
|
|
52
52
|
embeddingBatchSize?: number | undefined;
|
|
53
53
|
indexingConcurrency?: number | undefined;
|
|
54
|
-
|
|
54
|
+
dataDir?: string | undefined;
|
|
55
55
|
customExtensions?: unknown;
|
|
56
56
|
customIgnorePatterns?: unknown;
|
|
57
57
|
}>;
|
package/dist/config.js
CHANGED
|
@@ -11,7 +11,7 @@ const configSchema = z
|
|
|
11
11
|
embeddingModel: z.string().optional(),
|
|
12
12
|
embeddingBatchSize: z.coerce.number().int().min(1).max(2048).default(100),
|
|
13
13
|
indexingConcurrency: z.coerce.number().int().min(1).max(32).default(8),
|
|
14
|
-
|
|
14
|
+
dataDir: z.string().default(path.join(os.homedir(), '.codesearch')),
|
|
15
15
|
customExtensions: z.preprocess((val) => (typeof val === 'string' ? JSON.parse(val) : val), z.array(z.string()).default([])),
|
|
16
16
|
customIgnorePatterns: z.preprocess((val) => (typeof val === 'string' ? JSON.parse(val) : val), z.array(z.string()).default([])),
|
|
17
17
|
})
|
|
@@ -30,7 +30,7 @@ export function loadConfig() {
|
|
|
30
30
|
embeddingModel: process.env.EMBEDDING_MODEL?.trim() ?? undefined,
|
|
31
31
|
embeddingBatchSize: process.env.EMBEDDING_BATCH_SIZE,
|
|
32
32
|
indexingConcurrency: process.env.INDEXING_CONCURRENCY,
|
|
33
|
-
|
|
33
|
+
dataDir: process.env.CODESEARCH_DATA_DIR,
|
|
34
34
|
customExtensions: process.env.CUSTOM_EXTENSIONS,
|
|
35
35
|
customIgnorePatterns: process.env.CUSTOM_IGNORE_PATTERNS,
|
|
36
36
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CLI subcommand router for hook events.
|
|
3
3
|
*
|
|
4
|
-
* Plugin bash hooks call `npx
|
|
4
|
+
* Plugin bash hooks call `npx codesearch hook <event>` which routes here.
|
|
5
5
|
*/
|
|
6
6
|
export declare function runHook(event: string | undefined): Promise<void>;
|
|
7
7
|
//# sourceMappingURL=cli-router.d.ts.map
|
package/dist/hooks/cli-router.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CLI subcommand router for hook events.
|
|
3
3
|
*
|
|
4
|
-
* Plugin bash hooks call `npx
|
|
4
|
+
* Plugin bash hooks call `npx codesearch hook <event>` which routes here.
|
|
5
5
|
*/
|
|
6
6
|
export async function runHook(event) {
|
|
7
7
|
switch (event) {
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ import { ToolHandlers } from './tools.js';
|
|
|
20
20
|
import { TOOL_DEFINITIONS } from './tool-schemas.js';
|
|
21
21
|
import { getSetupErrorMessage } from './setup-message.js';
|
|
22
22
|
import { BUILD_VERSION, BUILD_TIMESTAMP } from './build-info.js';
|
|
23
|
-
const SERVER_INSTRUCTIONS = `#
|
|
23
|
+
const SERVER_INSTRUCTIONS = `# Codesearch — Workflow
|
|
24
24
|
|
|
25
25
|
**Before searching:** Ensure the codebase is indexed.
|
|
26
26
|
- \`list\` → see what's already indexed
|
|
@@ -45,7 +45,7 @@ const SERVER_INSTRUCTIONS = `# Eidetic Codesearch — Workflow
|
|
|
45
45
|
- Next time you need the same docs: \`lookup(query="...", library="<name>")\`
|
|
46
46
|
- Stale docs (past TTL) still return results but are flagged \`[STALE]\``;
|
|
47
47
|
async function main() {
|
|
48
|
-
// CLI subcommand routing — hooks call `npx
|
|
48
|
+
// CLI subcommand routing — hooks call `npx codesearch hook <event>`
|
|
49
49
|
if (process.argv[2] === 'hook') {
|
|
50
50
|
const { runHook } = await import('./hooks/cli-router.js');
|
|
51
51
|
await runHook(process.argv[3]);
|
|
@@ -121,7 +121,7 @@ async function main() {
|
|
|
121
121
|
});
|
|
122
122
|
const transport = new StdioServerTransport();
|
|
123
123
|
await server.connect(transport);
|
|
124
|
-
console.log(`
|
|
124
|
+
console.log(`Codesearch MCP server v${BUILD_VERSION} (built ${BUILD_TIMESTAMP}) started on stdio.`);
|
|
125
125
|
}
|
|
126
126
|
process.on('SIGINT', () => {
|
|
127
127
|
console.error('Received SIGINT, shutting down...');
|
package/dist/paths.js
CHANGED
|
@@ -14,7 +14,7 @@ export function normalizePath(inputPath) {
|
|
|
14
14
|
return resolved;
|
|
15
15
|
}
|
|
16
16
|
export function getDataDir() {
|
|
17
|
-
return normalizePath(getConfig().
|
|
17
|
+
return normalizePath(getConfig().dataDir);
|
|
18
18
|
}
|
|
19
19
|
export function getSnapshotDir() {
|
|
20
20
|
return `${getDataDir()}/snapshots`;
|
|
@@ -32,7 +32,7 @@ export function pathToCollectionName(absolutePath) {
|
|
|
32
32
|
.replace(/[^a-z0-9]/g, '_')
|
|
33
33
|
.replace(/_+/g, '_')
|
|
34
34
|
.replace(/^_|_$/g, '');
|
|
35
|
-
return `
|
|
35
|
+
return `cs_${safe}`;
|
|
36
36
|
}
|
|
37
37
|
export function getCodesearchDbPath() {
|
|
38
38
|
return `${getDataDir()}/codesearch.db`;
|
package/dist/state/snapshot.js
CHANGED
|
@@ -73,7 +73,7 @@ export async function cleanupOrphanedSnapshots(vectordb) {
|
|
|
73
73
|
const collections = listSnapshotCollections();
|
|
74
74
|
if (collections.length === 0)
|
|
75
75
|
return 0;
|
|
76
|
-
const probeResult = await vectordb.hasCollection('
|
|
76
|
+
const probeResult = await vectordb.hasCollection('__codesearch_connectivity_probe__');
|
|
77
77
|
if (probeResult) {
|
|
78
78
|
console.warn('Orphan cleanup skipped: connectivity probe returned unexpected result.');
|
|
79
79
|
return 0;
|
package/dist/vectordb/sqlite.js
CHANGED
|
@@ -246,14 +246,16 @@ export class SqliteVectorDB {
|
|
|
246
246
|
symbol_signature, parent_symbol, indexed_at, file_modified_at)
|
|
247
247
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), ?)
|
|
248
248
|
`);
|
|
249
|
+
const deleteVec = this.db.prepare(`DELETE FROM "${safe}_vec" WHERE id = ?`);
|
|
249
250
|
const insertVec = this.db.prepare(`
|
|
250
|
-
INSERT
|
|
251
|
+
INSERT INTO "${safe}_vec" (id, vector) VALUES (?, ?)
|
|
251
252
|
`);
|
|
252
253
|
for (let i = 0; i < documents.length; i += INSERT_BATCH_SIZE) {
|
|
253
254
|
const batch = documents.slice(i, i + INSERT_BATCH_SIZE);
|
|
254
255
|
this.db.transaction(() => {
|
|
255
256
|
for (const doc of batch) {
|
|
256
257
|
insertChunk.run(doc.id, safe, doc.content, doc.relativePath, doc.startLine, doc.endLine, doc.fileExtension, doc.language, doc.fileCategory ?? null, doc.symbolName ?? null, doc.symbolKind ?? null, doc.symbolSignature ?? null, doc.parentSymbol ?? null, doc.fileModifiedAt ?? null);
|
|
258
|
+
deleteVec.run(doc.id);
|
|
257
259
|
insertVec.run(doc.id, vecToBuffer(doc.vector));
|
|
258
260
|
}
|
|
259
261
|
})();
|
|
@@ -308,7 +310,7 @@ export class SqliteVectorDB {
|
|
|
308
310
|
WHERE "${safe}_fts" MATCH ?
|
|
309
311
|
${extClause}
|
|
310
312
|
LIMIT ?`)
|
|
311
|
-
.all(safe, ftsQuery,
|
|
313
|
+
.all(safe, ftsQuery, ...extParams, fetchLimit);
|
|
312
314
|
const pointsForRank = ftsRows.map((r) => ({
|
|
313
315
|
id: r.id,
|
|
314
316
|
payload: { content: r.content },
|
|
@@ -437,8 +439,9 @@ export class SqliteVectorDB {
|
|
|
437
439
|
symbol_signature, parent_symbol, indexed_at, file_modified_at)
|
|
438
440
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), ?)`)
|
|
439
441
|
.run(id, safe, String(payload.content ?? ''), String(payload.relativePath ?? ''), Number(payload.startLine ?? 0), Number(payload.endLine ?? 0), String(payload.fileExtension ?? ''), String(payload.language ?? ''), String(payload.fileCategory ?? ''), String(payload.symbolName ?? ''), String(payload.symbolKind ?? ''), String(payload.symbolSignature ?? ''), String(payload.parentSymbol ?? ''), payload.fileModifiedAt != null ? String(payload.fileModifiedAt) : null);
|
|
442
|
+
this.db.prepare(`DELETE FROM "${safe}_vec" WHERE id = ?`).run(id);
|
|
440
443
|
this.db
|
|
441
|
-
.prepare(`INSERT
|
|
444
|
+
.prepare(`INSERT INTO "${safe}_vec" (id, vector) VALUES (?, ?)`)
|
|
442
445
|
.run(id, vecToBuffer(vector));
|
|
443
446
|
})();
|
|
444
447
|
}
|
package/messages.yaml
CHANGED
|
@@ -1,34 +1,36 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Codesearch user-facing messages — edit here, everything else reads from this file.
|
|
2
2
|
|
|
3
3
|
welcome:
|
|
4
4
|
ascii_art: |
|
|
5
5
|
┌─────────────────────────────────────────────┐
|
|
6
|
-
│
|
|
7
|
-
│
|
|
8
|
-
│
|
|
6
|
+
│ ╔═╗╔═╗╔╦╗╔═╗╔═╗╔═╗╔═╗╦═╗╔═╗╦ ╦ │
|
|
7
|
+
│ ║ ║ ║ ║║║╣ ╚═╗║╣ ╠═╣╠╦╝║ ╠═╣ │
|
|
8
|
+
│ ╚═╝╚═╝═╩╝╚═╝╚═╝╚═╝╩ ╩╩╚═╚═╝╩ ╩ │
|
|
9
|
+
│ semantic code search │
|
|
10
|
+
│ for Claude Code │
|
|
9
11
|
└─────────────────────────────────────────────┘
|
|
10
12
|
first_run: |
|
|
11
|
-
|
|
13
|
+
Codesearch is ready! Quick start:
|
|
12
14
|
1. `/index` — index this codebase
|
|
13
15
|
2. `search("how does X work")` — search by meaning
|
|
14
16
|
3. That's it. Everything else is optional.
|
|
15
17
|
|
|
16
18
|
setup:
|
|
17
19
|
missing:
|
|
18
|
-
header: "
|
|
20
|
+
header: "Codesearch setup required: No API key configured."
|
|
19
21
|
diagnosis: >
|
|
20
22
|
`OPENAI_API_KEY` is not set and no alternative provider is configured.
|
|
21
23
|
step1: "**Get an API key**: https://platform.openai.com/api-keys"
|
|
22
24
|
|
|
23
25
|
invalid:
|
|
24
|
-
header: "
|
|
26
|
+
header: "Codesearch setup failed: {error}"
|
|
25
27
|
diagnosis: >
|
|
26
28
|
Key/provider is configured but initialization failed.
|
|
27
29
|
The key may be invalid, expired, or the provider may be unreachable.
|
|
28
30
|
step1: "**Verify your key** is valid and has embedding permissions"
|
|
29
31
|
|
|
30
32
|
unknown:
|
|
31
|
-
header: "
|
|
33
|
+
header: "Codesearch setup failed: {error}"
|
|
32
34
|
diagnosis: ""
|
|
33
35
|
step1: "**Get an API key**: https://platform.openai.com/api-keys"
|
|
34
36
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tai-io/codesearch",
|
|
3
|
-
"version": "2026.313.
|
|
3
|
+
"version": "2026.313.1653",
|
|
4
4
|
"description": "Semantic code search MCP server for Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"
|
|
8
|
+
"codesearch": "dist/index.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist/**/*.js",
|