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.
Files changed (177) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +241 -0
  3. package/dist/cli/args.d.ts +13 -0
  4. package/dist/cli/args.d.ts.map +1 -0
  5. package/dist/cli/args.js +79 -0
  6. package/dist/cli/args.js.map +1 -0
  7. package/dist/cli/commands.d.ts +4 -0
  8. package/dist/cli/commands.d.ts.map +1 -0
  9. package/dist/cli/commands.js +336 -0
  10. package/dist/cli/commands.js.map +1 -0
  11. package/dist/cli/help.d.ts +3 -0
  12. package/dist/cli/help.d.ts.map +1 -0
  13. package/dist/cli/help.js +271 -0
  14. package/dist/cli/help.js.map +1 -0
  15. package/dist/cli.d.ts +3 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js +80 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/config.d.ts +23 -0
  20. package/dist/config.d.ts.map +1 -0
  21. package/dist/config.js +49 -0
  22. package/dist/config.js.map +1 -0
  23. package/dist/parser/extractors/go.d.ts +4 -0
  24. package/dist/parser/extractors/go.d.ts.map +1 -0
  25. package/dist/parser/extractors/go.js +185 -0
  26. package/dist/parser/extractors/go.js.map +1 -0
  27. package/dist/parser/extractors/javascript.d.ts +9 -0
  28. package/dist/parser/extractors/javascript.d.ts.map +1 -0
  29. package/dist/parser/extractors/javascript.js +10 -0
  30. package/dist/parser/extractors/javascript.js.map +1 -0
  31. package/dist/parser/extractors/markdown.d.ts +15 -0
  32. package/dist/parser/extractors/markdown.d.ts.map +1 -0
  33. package/dist/parser/extractors/markdown.js +217 -0
  34. package/dist/parser/extractors/markdown.js.map +1 -0
  35. package/dist/parser/extractors/prisma.d.ts +17 -0
  36. package/dist/parser/extractors/prisma.d.ts.map +1 -0
  37. package/dist/parser/extractors/prisma.js +121 -0
  38. package/dist/parser/extractors/prisma.js.map +1 -0
  39. package/dist/parser/extractors/python.d.ts +4 -0
  40. package/dist/parser/extractors/python.d.ts.map +1 -0
  41. package/dist/parser/extractors/python.js +203 -0
  42. package/dist/parser/extractors/python.js.map +1 -0
  43. package/dist/parser/extractors/rust.d.ts +4 -0
  44. package/dist/parser/extractors/rust.d.ts.map +1 -0
  45. package/dist/parser/extractors/rust.js +178 -0
  46. package/dist/parser/extractors/rust.js.map +1 -0
  47. package/dist/parser/extractors/typescript.d.ts +4 -0
  48. package/dist/parser/extractors/typescript.d.ts.map +1 -0
  49. package/dist/parser/extractors/typescript.js +296 -0
  50. package/dist/parser/extractors/typescript.js.map +1 -0
  51. package/dist/parser/languages/tree-sitter-css.wasm +0 -0
  52. package/dist/parser/languages/tree-sitter-go.wasm +0 -0
  53. package/dist/parser/languages/tree-sitter-java.wasm +0 -0
  54. package/dist/parser/languages/tree-sitter-javascript.wasm +0 -0
  55. package/dist/parser/languages/tree-sitter-json.wasm +0 -0
  56. package/dist/parser/languages/tree-sitter-php.wasm +0 -0
  57. package/dist/parser/languages/tree-sitter-python.wasm +0 -0
  58. package/dist/parser/languages/tree-sitter-ruby.wasm +0 -0
  59. package/dist/parser/languages/tree-sitter-rust.wasm +0 -0
  60. package/dist/parser/languages/tree-sitter-tsx.wasm +0 -0
  61. package/dist/parser/languages/tree-sitter-typescript.wasm +0 -0
  62. package/dist/parser/parser-manager.d.ts +6 -0
  63. package/dist/parser/parser-manager.d.ts.map +1 -0
  64. package/dist/parser/parser-manager.js +60 -0
  65. package/dist/parser/parser-manager.js.map +1 -0
  66. package/dist/parser/symbol-extractor.d.ts +22 -0
  67. package/dist/parser/symbol-extractor.d.ts.map +1 -0
  68. package/dist/parser/symbol-extractor.js +115 -0
  69. package/dist/parser/symbol-extractor.js.map +1 -0
  70. package/dist/retrieval/codebase-retrieval.d.ts +27 -0
  71. package/dist/retrieval/codebase-retrieval.d.ts.map +1 -0
  72. package/dist/retrieval/codebase-retrieval.js +472 -0
  73. package/dist/retrieval/codebase-retrieval.js.map +1 -0
  74. package/dist/search/bm25.d.ts +22 -0
  75. package/dist/search/bm25.d.ts.map +1 -0
  76. package/dist/search/bm25.js +179 -0
  77. package/dist/search/bm25.js.map +1 -0
  78. package/dist/search/chunker.d.ts +9 -0
  79. package/dist/search/chunker.d.ts.map +1 -0
  80. package/dist/search/chunker.js +91 -0
  81. package/dist/search/chunker.js.map +1 -0
  82. package/dist/search/hybrid.d.ts +16 -0
  83. package/dist/search/hybrid.d.ts.map +1 -0
  84. package/dist/search/hybrid.js +51 -0
  85. package/dist/search/hybrid.js.map +1 -0
  86. package/dist/search/semantic.d.ts +44 -0
  87. package/dist/search/semantic.d.ts.map +1 -0
  88. package/dist/search/semantic.js +194 -0
  89. package/dist/search/semantic.js.map +1 -0
  90. package/dist/server.d.ts +2 -0
  91. package/dist/server.d.ts.map +1 -0
  92. package/dist/server.js +285 -0
  93. package/dist/server.js.map +1 -0
  94. package/dist/storage/chunk-store.d.ts +32 -0
  95. package/dist/storage/chunk-store.d.ts.map +1 -0
  96. package/dist/storage/chunk-store.js +144 -0
  97. package/dist/storage/chunk-store.js.map +1 -0
  98. package/dist/storage/embedding-store.d.ts +41 -0
  99. package/dist/storage/embedding-store.d.ts.map +1 -0
  100. package/dist/storage/embedding-store.js +149 -0
  101. package/dist/storage/embedding-store.js.map +1 -0
  102. package/dist/storage/index-store.d.ts +23 -0
  103. package/dist/storage/index-store.d.ts.map +1 -0
  104. package/dist/storage/index-store.js +95 -0
  105. package/dist/storage/index-store.js.map +1 -0
  106. package/dist/storage/registry.d.ts +35 -0
  107. package/dist/storage/registry.d.ts.map +1 -0
  108. package/dist/storage/registry.js +99 -0
  109. package/dist/storage/registry.js.map +1 -0
  110. package/dist/storage/usage-stats.d.ts +32 -0
  111. package/dist/storage/usage-stats.d.ts.map +1 -0
  112. package/dist/storage/usage-stats.js +180 -0
  113. package/dist/storage/usage-stats.js.map +1 -0
  114. package/dist/storage/usage-tracker.d.ts +35 -0
  115. package/dist/storage/usage-tracker.d.ts.map +1 -0
  116. package/dist/storage/usage-tracker.js +245 -0
  117. package/dist/storage/usage-tracker.js.map +1 -0
  118. package/dist/storage/watcher.d.ts +12 -0
  119. package/dist/storage/watcher.d.ts.map +1 -0
  120. package/dist/storage/watcher.js +66 -0
  121. package/dist/storage/watcher.js.map +1 -0
  122. package/dist/tools/context-tools.d.ts +31 -0
  123. package/dist/tools/context-tools.d.ts.map +1 -0
  124. package/dist/tools/context-tools.js +219 -0
  125. package/dist/tools/context-tools.js.map +1 -0
  126. package/dist/tools/diff-tools.d.ts +22 -0
  127. package/dist/tools/diff-tools.d.ts.map +1 -0
  128. package/dist/tools/diff-tools.js +165 -0
  129. package/dist/tools/diff-tools.js.map +1 -0
  130. package/dist/tools/generate-tools.d.ts +11 -0
  131. package/dist/tools/generate-tools.d.ts.map +1 -0
  132. package/dist/tools/generate-tools.js +135 -0
  133. package/dist/tools/generate-tools.js.map +1 -0
  134. package/dist/tools/graph-tools.d.ts +60 -0
  135. package/dist/tools/graph-tools.d.ts.map +1 -0
  136. package/dist/tools/graph-tools.js +313 -0
  137. package/dist/tools/graph-tools.js.map +1 -0
  138. package/dist/tools/index-tools.d.ts +39 -0
  139. package/dist/tools/index-tools.d.ts.map +1 -0
  140. package/dist/tools/index-tools.js +451 -0
  141. package/dist/tools/index-tools.js.map +1 -0
  142. package/dist/tools/outline-tools.d.ts +59 -0
  143. package/dist/tools/outline-tools.d.ts.map +1 -0
  144. package/dist/tools/outline-tools.js +342 -0
  145. package/dist/tools/outline-tools.js.map +1 -0
  146. package/dist/tools/search-tools.d.ts +29 -0
  147. package/dist/tools/search-tools.d.ts.map +1 -0
  148. package/dist/tools/search-tools.js +309 -0
  149. package/dist/tools/search-tools.js.map +1 -0
  150. package/dist/tools/symbol-tools.d.ts +24 -0
  151. package/dist/tools/symbol-tools.d.ts.map +1 -0
  152. package/dist/tools/symbol-tools.js +172 -0
  153. package/dist/tools/symbol-tools.js.map +1 -0
  154. package/dist/types.d.ts +91 -0
  155. package/dist/types.d.ts.map +1 -0
  156. package/dist/types.js +3 -0
  157. package/dist/types.js.map +1 -0
  158. package/dist/utils/git-validation.d.ts +11 -0
  159. package/dist/utils/git-validation.d.ts.map +1 -0
  160. package/dist/utils/git-validation.js +19 -0
  161. package/dist/utils/git-validation.js.map +1 -0
  162. package/dist/utils/test-file.d.ts +11 -0
  163. package/dist/utils/test-file.d.ts.map +1 -0
  164. package/dist/utils/test-file.js +27 -0
  165. package/dist/utils/test-file.js.map +1 -0
  166. package/package.json +62 -0
  167. package/src/parser/languages/tree-sitter-css.wasm +0 -0
  168. package/src/parser/languages/tree-sitter-go.wasm +0 -0
  169. package/src/parser/languages/tree-sitter-java.wasm +0 -0
  170. package/src/parser/languages/tree-sitter-javascript.wasm +0 -0
  171. package/src/parser/languages/tree-sitter-json.wasm +0 -0
  172. package/src/parser/languages/tree-sitter-php.wasm +0 -0
  173. package/src/parser/languages/tree-sitter-python.wasm +0 -0
  174. package/src/parser/languages/tree-sitter-ruby.wasm +0 -0
  175. package/src/parser/languages/tree-sitter-rust.wasm +0 -0
  176. package/src/parser/languages/tree-sitter-tsx.wasm +0 -0
  177. 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"}
@@ -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":"AAAA,8EAA8E;AAC9E,0CAA0C;AAC1C,8EAA8E;AAS9E,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,KAAK,GAAU,EAAE,CAAC;IAExB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;QACrB,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,4BAA4B;YAC5B,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBAC/B,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBACzB,6DAA6D;gBAC7D,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;oBAChD,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;gBACpB,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;oBAClB,CAAC,EAAE,CAAC;gBACN,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAAY,EAAE,IAAY;IAChD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IACxB,IAAI,GAAG,KAAK,SAAS,IAAI,OAAO,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACpE,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAY,EAAE,IAAY;IACpD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IACxB,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAChD,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAClC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAY,EAAE,IAAY;IACnD,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjC,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACxB,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACf,GAAG,CAAC,wBAAwB,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,MAAM,UAAU,MAAM,CAAC,IAAa,EAAE,KAAY;IAChD,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,OAAe;IACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,OAAO,IAAI,CAAC,CAAC;IAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAc,EAAE,KAAa,EAAE,IAAY;IACpE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IACxB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,GAAG,CAAC,+BAA+B,IAAI,GAAG,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Flags } from "./args.js";
2
+ export type CommandHandler = (args: string[], flags: Flags) => Promise<void>;
3
+ export declare const COMMAND_MAP: Record<string, CommandHandler>;
4
+ //# sourceMappingURL=commands.d.ts.map
@@ -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"}