codesift-mcp 0.1.0
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/LICENSE +21 -0
- package/README.md +241 -0
- package/dist/cli/args.d.ts +13 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +79 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/commands.d.ts +4 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +336 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/help.d.ts +3 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +271 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +80 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +23 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +49 -0
- package/dist/config.js.map +1 -0
- package/dist/parser/extractors/go.d.ts +4 -0
- package/dist/parser/extractors/go.d.ts.map +1 -0
- package/dist/parser/extractors/go.js +185 -0
- package/dist/parser/extractors/go.js.map +1 -0
- package/dist/parser/extractors/javascript.d.ts +9 -0
- package/dist/parser/extractors/javascript.d.ts.map +1 -0
- package/dist/parser/extractors/javascript.js +10 -0
- package/dist/parser/extractors/javascript.js.map +1 -0
- package/dist/parser/extractors/markdown.d.ts +15 -0
- package/dist/parser/extractors/markdown.d.ts.map +1 -0
- package/dist/parser/extractors/markdown.js +217 -0
- package/dist/parser/extractors/markdown.js.map +1 -0
- package/dist/parser/extractors/prisma.d.ts +17 -0
- package/dist/parser/extractors/prisma.d.ts.map +1 -0
- package/dist/parser/extractors/prisma.js +121 -0
- package/dist/parser/extractors/prisma.js.map +1 -0
- package/dist/parser/extractors/python.d.ts +4 -0
- package/dist/parser/extractors/python.d.ts.map +1 -0
- package/dist/parser/extractors/python.js +203 -0
- package/dist/parser/extractors/python.js.map +1 -0
- package/dist/parser/extractors/rust.d.ts +4 -0
- package/dist/parser/extractors/rust.d.ts.map +1 -0
- package/dist/parser/extractors/rust.js +178 -0
- package/dist/parser/extractors/rust.js.map +1 -0
- package/dist/parser/extractors/typescript.d.ts +4 -0
- package/dist/parser/extractors/typescript.d.ts.map +1 -0
- package/dist/parser/extractors/typescript.js +296 -0
- package/dist/parser/extractors/typescript.js.map +1 -0
- package/dist/parser/languages/tree-sitter-css.wasm +0 -0
- package/dist/parser/languages/tree-sitter-go.wasm +0 -0
- package/dist/parser/languages/tree-sitter-java.wasm +0 -0
- package/dist/parser/languages/tree-sitter-javascript.wasm +0 -0
- package/dist/parser/languages/tree-sitter-json.wasm +0 -0
- package/dist/parser/languages/tree-sitter-php.wasm +0 -0
- package/dist/parser/languages/tree-sitter-python.wasm +0 -0
- package/dist/parser/languages/tree-sitter-ruby.wasm +0 -0
- package/dist/parser/languages/tree-sitter-rust.wasm +0 -0
- package/dist/parser/languages/tree-sitter-tsx.wasm +0 -0
- package/dist/parser/languages/tree-sitter-typescript.wasm +0 -0
- package/dist/parser/parser-manager.d.ts +6 -0
- package/dist/parser/parser-manager.d.ts.map +1 -0
- package/dist/parser/parser-manager.js +60 -0
- package/dist/parser/parser-manager.js.map +1 -0
- package/dist/parser/symbol-extractor.d.ts +22 -0
- package/dist/parser/symbol-extractor.d.ts.map +1 -0
- package/dist/parser/symbol-extractor.js +115 -0
- package/dist/parser/symbol-extractor.js.map +1 -0
- package/dist/retrieval/codebase-retrieval.d.ts +27 -0
- package/dist/retrieval/codebase-retrieval.d.ts.map +1 -0
- package/dist/retrieval/codebase-retrieval.js +472 -0
- package/dist/retrieval/codebase-retrieval.js.map +1 -0
- package/dist/search/bm25.d.ts +22 -0
- package/dist/search/bm25.d.ts.map +1 -0
- package/dist/search/bm25.js +179 -0
- package/dist/search/bm25.js.map +1 -0
- package/dist/search/chunker.d.ts +9 -0
- package/dist/search/chunker.d.ts.map +1 -0
- package/dist/search/chunker.js +91 -0
- package/dist/search/chunker.js.map +1 -0
- package/dist/search/hybrid.d.ts +16 -0
- package/dist/search/hybrid.d.ts.map +1 -0
- package/dist/search/hybrid.js +51 -0
- package/dist/search/hybrid.js.map +1 -0
- package/dist/search/semantic.d.ts +44 -0
- package/dist/search/semantic.d.ts.map +1 -0
- package/dist/search/semantic.js +194 -0
- package/dist/search/semantic.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +285 -0
- package/dist/server.js.map +1 -0
- package/dist/storage/chunk-store.d.ts +32 -0
- package/dist/storage/chunk-store.d.ts.map +1 -0
- package/dist/storage/chunk-store.js +144 -0
- package/dist/storage/chunk-store.js.map +1 -0
- package/dist/storage/embedding-store.d.ts +41 -0
- package/dist/storage/embedding-store.d.ts.map +1 -0
- package/dist/storage/embedding-store.js +149 -0
- package/dist/storage/embedding-store.js.map +1 -0
- package/dist/storage/index-store.d.ts +23 -0
- package/dist/storage/index-store.d.ts.map +1 -0
- package/dist/storage/index-store.js +95 -0
- package/dist/storage/index-store.js.map +1 -0
- package/dist/storage/registry.d.ts +35 -0
- package/dist/storage/registry.d.ts.map +1 -0
- package/dist/storage/registry.js +99 -0
- package/dist/storage/registry.js.map +1 -0
- package/dist/storage/usage-stats.d.ts +32 -0
- package/dist/storage/usage-stats.d.ts.map +1 -0
- package/dist/storage/usage-stats.js +180 -0
- package/dist/storage/usage-stats.js.map +1 -0
- package/dist/storage/usage-tracker.d.ts +35 -0
- package/dist/storage/usage-tracker.d.ts.map +1 -0
- package/dist/storage/usage-tracker.js +245 -0
- package/dist/storage/usage-tracker.js.map +1 -0
- package/dist/storage/watcher.d.ts +12 -0
- package/dist/storage/watcher.d.ts.map +1 -0
- package/dist/storage/watcher.js +66 -0
- package/dist/storage/watcher.js.map +1 -0
- package/dist/tools/context-tools.d.ts +31 -0
- package/dist/tools/context-tools.d.ts.map +1 -0
- package/dist/tools/context-tools.js +219 -0
- package/dist/tools/context-tools.js.map +1 -0
- package/dist/tools/diff-tools.d.ts +22 -0
- package/dist/tools/diff-tools.d.ts.map +1 -0
- package/dist/tools/diff-tools.js +165 -0
- package/dist/tools/diff-tools.js.map +1 -0
- package/dist/tools/generate-tools.d.ts +11 -0
- package/dist/tools/generate-tools.d.ts.map +1 -0
- package/dist/tools/generate-tools.js +135 -0
- package/dist/tools/generate-tools.js.map +1 -0
- package/dist/tools/graph-tools.d.ts +60 -0
- package/dist/tools/graph-tools.d.ts.map +1 -0
- package/dist/tools/graph-tools.js +313 -0
- package/dist/tools/graph-tools.js.map +1 -0
- package/dist/tools/index-tools.d.ts +39 -0
- package/dist/tools/index-tools.d.ts.map +1 -0
- package/dist/tools/index-tools.js +451 -0
- package/dist/tools/index-tools.js.map +1 -0
- package/dist/tools/outline-tools.d.ts +59 -0
- package/dist/tools/outline-tools.d.ts.map +1 -0
- package/dist/tools/outline-tools.js +342 -0
- package/dist/tools/outline-tools.js.map +1 -0
- package/dist/tools/search-tools.d.ts +29 -0
- package/dist/tools/search-tools.d.ts.map +1 -0
- package/dist/tools/search-tools.js +309 -0
- package/dist/tools/search-tools.js.map +1 -0
- package/dist/tools/symbol-tools.d.ts +24 -0
- package/dist/tools/symbol-tools.d.ts.map +1 -0
- package/dist/tools/symbol-tools.js +172 -0
- package/dist/tools/symbol-tools.js.map +1 -0
- package/dist/types.d.ts +91 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/git-validation.d.ts +11 -0
- package/dist/utils/git-validation.d.ts.map +1 -0
- package/dist/utils/git-validation.js +19 -0
- package/dist/utils/git-validation.js.map +1 -0
- package/dist/utils/test-file.d.ts +11 -0
- package/dist/utils/test-file.d.ts.map +1 -0
- package/dist/utils/test-file.js +27 -0
- package/dist/utils/test-file.js.map +1 -0
- package/package.json +62 -0
- package/src/parser/languages/tree-sitter-css.wasm +0 -0
- package/src/parser/languages/tree-sitter-go.wasm +0 -0
- package/src/parser/languages/tree-sitter-java.wasm +0 -0
- package/src/parser/languages/tree-sitter-javascript.wasm +0 -0
- package/src/parser/languages/tree-sitter-json.wasm +0 -0
- package/src/parser/languages/tree-sitter-php.wasm +0 -0
- package/src/parser/languages/tree-sitter-python.wasm +0 -0
- package/src/parser/languages/tree-sitter-ruby.wasm +0 -0
- package/src/parser/languages/tree-sitter-rust.wasm +0 -0
- package/src/parser/languages/tree-sitter-tsx.wasm +0 -0
- package/src/parser/languages/tree-sitter-typescript.wasm +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Greg Laskowski
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# CodeSift -- Token-efficient code intelligence for AI agents
|
|
2
|
+
|
|
3
|
+
CodeSift indexes your codebase with tree-sitter AST parsing and gives AI agents 22 search/retrieval tools via CLI or MCP server. It uses 20-33% fewer tokens than raw grep/Read workflows on typical code navigation tasks.
|
|
4
|
+
|
|
5
|
+
## Quick install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g codesift-mcp
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Index a project
|
|
15
|
+
codesift index /path/to/project
|
|
16
|
+
|
|
17
|
+
# Search for a function
|
|
18
|
+
codesift symbols local/my-project "createUser" --kind function --include-source
|
|
19
|
+
|
|
20
|
+
# Semantic search (requires embedding provider)
|
|
21
|
+
codesift retrieve local/my-project \
|
|
22
|
+
--queries '[{"type":"semantic","query":"how does caching work?"}]'
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Benchmark results
|
|
26
|
+
|
|
27
|
+
Measured on a real 4,127-file TypeScript codebase (70 tasks, CodeSift CLI vs Bash grep/Read).
|
|
28
|
+
|
|
29
|
+
| Category | CodeSift | Bash grep | Delta |
|
|
30
|
+
|----------|----------|-----------|-------|
|
|
31
|
+
| Text Search | 48,930 tok | 72,993 tok | **-33%** |
|
|
32
|
+
| Symbol Search | 63,829 tok | 60,282 tok | +6% |
|
|
33
|
+
| File Structure | 36,580 tok | 45,489 tok | **-20%** |
|
|
34
|
+
| Code Retrieval | 57,703 tok | 60,482 tok | **-5%** |
|
|
35
|
+
| Relationships | 52,312 tok | 60,810 tok | **-14%** |
|
|
36
|
+
| Semantic Search | 7.8/10 quality | 6.5/10 | **+20% quality** |
|
|
37
|
+
|
|
38
|
+
CodeSift wins 4 of 6 categories. Symbol search is at parity (verbose output, being optimized). Relationship tracing is being rewritten for AST-level accuracy.
|
|
39
|
+
|
|
40
|
+
## CLI commands
|
|
41
|
+
|
|
42
|
+
### Indexing
|
|
43
|
+
|
|
44
|
+
| Command | Description |
|
|
45
|
+
|---------|-------------|
|
|
46
|
+
| `codesift index <path>` | Index a local folder |
|
|
47
|
+
| `codesift index-repo <url>` | Clone and index a remote git repository |
|
|
48
|
+
| `codesift repos` | List all indexed repositories |
|
|
49
|
+
| `codesift invalidate <repo>` | Clear index cache for a repository |
|
|
50
|
+
|
|
51
|
+
### Search
|
|
52
|
+
|
|
53
|
+
| Command | Description |
|
|
54
|
+
|---------|-------------|
|
|
55
|
+
| `codesift search <repo> <query>` | Full-text search across all files |
|
|
56
|
+
| `codesift symbols <repo> <query>` | Search symbols by name/signature |
|
|
57
|
+
|
|
58
|
+
### Outline
|
|
59
|
+
|
|
60
|
+
| Command | Description |
|
|
61
|
+
|---------|-------------|
|
|
62
|
+
| `codesift tree <repo>` | File tree with symbol counts |
|
|
63
|
+
| `codesift outline <repo> <file>` | Symbol outline of a single file |
|
|
64
|
+
| `codesift repo-outline <repo>` | High-level repository outline |
|
|
65
|
+
|
|
66
|
+
### Symbol retrieval
|
|
67
|
+
|
|
68
|
+
| Command | Description |
|
|
69
|
+
|---------|-------------|
|
|
70
|
+
| `codesift symbol <repo> <id>` | Get a single symbol by ID |
|
|
71
|
+
| `codesift symbols-batch <repo> <ids...>` | Get multiple symbols by ID |
|
|
72
|
+
| `codesift find <repo> <query>` | Find symbol and show source |
|
|
73
|
+
| `codesift refs <repo> <name>` | Find all references to a symbol |
|
|
74
|
+
|
|
75
|
+
### Graph & analysis
|
|
76
|
+
|
|
77
|
+
| Command | Description |
|
|
78
|
+
|---------|-------------|
|
|
79
|
+
| `codesift trace <repo> <name>` | Trace call chain (callers/callees) |
|
|
80
|
+
| `codesift impact <repo> --since <ref>` | Blast radius of git changes |
|
|
81
|
+
| `codesift context <repo> <query>` | Assemble relevant code context |
|
|
82
|
+
| `codesift knowledge-map <repo>` | Module dependency map |
|
|
83
|
+
|
|
84
|
+
### Diff
|
|
85
|
+
|
|
86
|
+
| Command | Description |
|
|
87
|
+
|---------|-------------|
|
|
88
|
+
| `codesift diff <repo> --since <ref>` | Structural diff between git refs |
|
|
89
|
+
| `codesift changed <repo> --since <ref>` | List changed symbols between refs |
|
|
90
|
+
|
|
91
|
+
### Batch & utility
|
|
92
|
+
|
|
93
|
+
| Command | Description |
|
|
94
|
+
|---------|-------------|
|
|
95
|
+
| `codesift retrieve <repo> --queries <json>` | Batch multiple queries in one call |
|
|
96
|
+
| `codesift stats` | Show usage statistics |
|
|
97
|
+
| `codesift generate-claude-md <repo>` | Generate CLAUDE.md project summary |
|
|
98
|
+
|
|
99
|
+
## When to use CodeSift vs grep
|
|
100
|
+
|
|
101
|
+
| Task | Best tool | Why |
|
|
102
|
+
|------|-----------|-----|
|
|
103
|
+
| Find text in files | `codesift search` | 33% fewer tokens, BM25 ranking |
|
|
104
|
+
| Find function by name | `codesift symbols` | Returns signature + body in 1 call |
|
|
105
|
+
| File structure | `codesift tree` | 20% fewer tokens, symbol counts |
|
|
106
|
+
| "How does X work?" | `codesift retrieve` (semantic) | 20% better quality on concept queries |
|
|
107
|
+
| Find ALL occurrences | `grep -rn` | Exhaustive, no top_k cap |
|
|
108
|
+
| Count matches | `grep -c` | Simple exact count |
|
|
109
|
+
| Call chain tracing | `grep -rn "fn("` | CodeSift trace is being rewritten |
|
|
110
|
+
|
|
111
|
+
## MCP server
|
|
112
|
+
|
|
113
|
+
CodeSift runs as an [MCP](https://modelcontextprotocol.io) server, exposing all 22 tools to AI agents like Claude.
|
|
114
|
+
|
|
115
|
+
### Claude Code (CLI)
|
|
116
|
+
|
|
117
|
+
Add to `~/.claude.json`:
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"mcpServers": {
|
|
122
|
+
"codesift": {
|
|
123
|
+
"command": "codesift-mcp"
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Or from source:
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"mcpServers": {
|
|
134
|
+
"codesift": {
|
|
135
|
+
"command": "node",
|
|
136
|
+
"args": ["/path/to/codesift-mcp/dist/server.js"]
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Claude Desktop
|
|
143
|
+
|
|
144
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
{
|
|
148
|
+
"mcpServers": {
|
|
149
|
+
"codesift": {
|
|
150
|
+
"command": "node",
|
|
151
|
+
"args": ["/path/to/codesift-mcp/dist/server.js"]
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Semantic search
|
|
158
|
+
|
|
159
|
+
Semantic search uses embeddings to answer concept queries like "how does authentication work?" that keyword search misses.
|
|
160
|
+
|
|
161
|
+
### Setup
|
|
162
|
+
|
|
163
|
+
Set **one** of these environment variables:
|
|
164
|
+
|
|
165
|
+
| Variable | Provider | Model |
|
|
166
|
+
|----------|----------|-------|
|
|
167
|
+
| `CODESIFT_VOYAGE_API_KEY` | [Voyage AI](https://voyageai.com/) | `voyage-code-3` |
|
|
168
|
+
| `CODESIFT_OPENAI_API_KEY` | [OpenAI](https://openai.com/) | `text-embedding-3-small` |
|
|
169
|
+
| `CODESIFT_OLLAMA_URL` | [Ollama](https://ollama.com/) (local) | `nomic-embed-text` |
|
|
170
|
+
|
|
171
|
+
### Usage
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Pure semantic search
|
|
175
|
+
codesift retrieve local/my-project \
|
|
176
|
+
--queries '[{"type":"semantic","query":"error handling and retry logic","top_k":10}]'
|
|
177
|
+
|
|
178
|
+
# Hybrid search (semantic + BM25 text, RRF-merged)
|
|
179
|
+
codesift retrieve local/my-project \
|
|
180
|
+
--queries '[{"type":"hybrid","query":"caching strategy","top_k":10}]'
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Semantic and hybrid queries exclude test files by default to maximize token efficiency. To include test files, set `"exclude_tests": false` in the sub-query or pass `--exclude-tests=false` on the CLI.
|
|
184
|
+
|
|
185
|
+
### MCP example
|
|
186
|
+
|
|
187
|
+
```json
|
|
188
|
+
{
|
|
189
|
+
"mcpServers": {
|
|
190
|
+
"codesift": {
|
|
191
|
+
"command": "codesift-mcp",
|
|
192
|
+
"env": {
|
|
193
|
+
"CODESIFT_OPENAI_API_KEY": "sk-..."
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Configuration
|
|
201
|
+
|
|
202
|
+
All configuration is via environment variables.
|
|
203
|
+
|
|
204
|
+
| Variable | Description | Default |
|
|
205
|
+
|----------|-------------|---------|
|
|
206
|
+
| `CODESIFT_DATA_DIR` | Storage directory for indexes | `~/.codesift` |
|
|
207
|
+
| `CODESIFT_WATCH_DEBOUNCE_MS` | File watcher debounce interval | `500` |
|
|
208
|
+
| `CODESIFT_DEFAULT_TOKEN_BUDGET` | Default token budget for retrieval | `8000` |
|
|
209
|
+
| `CODESIFT_DEFAULT_TOP_K` | Default max results for search | `20` |
|
|
210
|
+
|
|
211
|
+
## How it works
|
|
212
|
+
|
|
213
|
+
1. **Indexing** -- Tree-sitter WASM grammars parse source files into ASTs. Symbol extraction produces functions, classes, methods, types, constants, etc. with signatures, docstrings, and source code.
|
|
214
|
+
|
|
215
|
+
2. **BM25F search** -- Symbols are tokenized (camelCase/snake_case splitting) and indexed with field-weighted BM25 scoring. Name matches rank 3x higher than body matches.
|
|
216
|
+
|
|
217
|
+
3. **Semantic search** (optional) -- Source code is chunked and embedded via the configured provider. Queries are embedded at search time and ranked by cosine similarity. Multi-sub-query decomposition with Reciprocal Rank Fusion (RRF, k=60).
|
|
218
|
+
|
|
219
|
+
4. **Hybrid search** -- Combines semantic embedding similarity with BM25 text matches via RRF, getting the best of both keyword and concept search.
|
|
220
|
+
|
|
221
|
+
5. **File watcher** -- chokidar watches indexed folders for changes. Modified files are re-parsed and the index is updated incrementally.
|
|
222
|
+
|
|
223
|
+
## Supported languages
|
|
224
|
+
|
|
225
|
+
TypeScript, JavaScript (JSX/TSX), Python, Go, Rust, Java, Ruby, PHP, Markdown, CSS, Prisma.
|
|
226
|
+
|
|
227
|
+
## Development
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
git clone https://github.com/greglas/codesift-mcp.git
|
|
231
|
+
cd codesift-mcp
|
|
232
|
+
npm install
|
|
233
|
+
npm run download-wasm # Download tree-sitter WASM grammars
|
|
234
|
+
npm run build # TypeScript compilation
|
|
235
|
+
npm test # Run tests (Vitest)
|
|
236
|
+
npm run test:coverage # Coverage report
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## License
|
|
240
|
+
|
|
241
|
+
MIT
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface ParsedArgs {
|
|
2
|
+
positional: string[];
|
|
3
|
+
flags: Record<string, string | boolean>;
|
|
4
|
+
}
|
|
5
|
+
export type Flags = Record<string, string | boolean>;
|
|
6
|
+
export declare function parseArgs(args: string[]): ParsedArgs;
|
|
7
|
+
export declare function getFlag(flags: Flags, name: string): string | undefined;
|
|
8
|
+
export declare function getBoolFlag(flags: Flags, name: string): boolean | undefined;
|
|
9
|
+
export declare function getNumFlag(flags: Flags, name: string): number | undefined;
|
|
10
|
+
export declare function output(data: unknown, flags: Flags): void;
|
|
11
|
+
export declare function die(message: string): never;
|
|
12
|
+
export declare function requireArg(args: string[], index: number, name: string): string;
|
|
13
|
+
//# sourceMappingURL=args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;AAErD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CA4BpD;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAItE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAM3E;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQzE;AAMD,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAIxD;AAED,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAG1C;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAM9E"}
|
package/dist/cli/args.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// CLI argument parsing and output helpers
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
export function parseArgs(args) {
|
|
5
|
+
const positional = [];
|
|
6
|
+
const flags = {};
|
|
7
|
+
for (let i = 0; i < args.length; i++) {
|
|
8
|
+
const arg = args[i];
|
|
9
|
+
if (arg.startsWith("--")) {
|
|
10
|
+
const key = arg.slice(2);
|
|
11
|
+
// Handle --key=value syntax
|
|
12
|
+
if (key.includes("=")) {
|
|
13
|
+
const eqIdx = key.indexOf("=");
|
|
14
|
+
flags[key.slice(0, eqIdx)] = key.slice(eqIdx + 1);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
const next = args[i + 1];
|
|
18
|
+
// Boolean flags: no next value, or next value is also a flag
|
|
19
|
+
if (next === undefined || next.startsWith("--")) {
|
|
20
|
+
flags[key] = true;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
flags[key] = next;
|
|
24
|
+
i++;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
positional.push(arg);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return { positional, flags };
|
|
33
|
+
}
|
|
34
|
+
export function getFlag(flags, name) {
|
|
35
|
+
const val = flags[name];
|
|
36
|
+
if (val === undefined || typeof val === "boolean")
|
|
37
|
+
return undefined;
|
|
38
|
+
return val;
|
|
39
|
+
}
|
|
40
|
+
export function getBoolFlag(flags, name) {
|
|
41
|
+
const val = flags[name];
|
|
42
|
+
if (val === undefined)
|
|
43
|
+
return undefined;
|
|
44
|
+
if (val === true || val === "true")
|
|
45
|
+
return true;
|
|
46
|
+
if (val === "false")
|
|
47
|
+
return false;
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
export function getNumFlag(flags, name) {
|
|
51
|
+
const raw = getFlag(flags, name);
|
|
52
|
+
if (raw === undefined)
|
|
53
|
+
return undefined;
|
|
54
|
+
const num = Number(raw);
|
|
55
|
+
if (isNaN(num)) {
|
|
56
|
+
die(`Invalid number for --${name}: ${raw}`);
|
|
57
|
+
}
|
|
58
|
+
return num;
|
|
59
|
+
}
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
// Output helpers
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
export function output(data, flags) {
|
|
64
|
+
const compact = getBoolFlag(flags, "compact");
|
|
65
|
+
const indent = compact ? undefined : 2;
|
|
66
|
+
process.stdout.write(JSON.stringify(data, null, indent) + "\n");
|
|
67
|
+
}
|
|
68
|
+
export function die(message) {
|
|
69
|
+
process.stderr.write(`Error: ${message}\n`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
export function requireArg(args, index, name) {
|
|
73
|
+
const val = args[index];
|
|
74
|
+
if (val === undefined) {
|
|
75
|
+
die(`Missing required argument: <${name}>`);
|
|
76
|
+
}
|
|
77
|
+
return val;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAGvC,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAgX7E,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAuBtD,CAAC"}
|