clast-ai 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 (133) hide show
  1. package/.claude-plugin/plugin.json +22 -0
  2. package/.mcp.json +8 -0
  3. package/LICENSE +21 -0
  4. package/README.md +419 -0
  5. package/commands/clast-status.md +9 -0
  6. package/dist/config/defaults.d.ts +19 -0
  7. package/dist/config/defaults.d.ts.map +1 -0
  8. package/dist/config/defaults.js +44 -0
  9. package/dist/config/defaults.js.map +1 -0
  10. package/dist/config/index.d.ts +5 -0
  11. package/dist/config/index.d.ts.map +1 -0
  12. package/dist/config/index.js +48 -0
  13. package/dist/config/index.js.map +1 -0
  14. package/dist/db/index.d.ts +16 -0
  15. package/dist/db/index.d.ts.map +1 -0
  16. package/dist/db/index.js +54 -0
  17. package/dist/db/index.js.map +1 -0
  18. package/dist/db/queries.d.ts +44 -0
  19. package/dist/db/queries.d.ts.map +1 -0
  20. package/dist/db/queries.js +251 -0
  21. package/dist/db/queries.js.map +1 -0
  22. package/dist/db/schema.d.ts +3 -0
  23. package/dist/db/schema.d.ts.map +1 -0
  24. package/dist/db/schema.js +94 -0
  25. package/dist/db/schema.js.map +1 -0
  26. package/dist/db/types.d.ts +44 -0
  27. package/dist/db/types.d.ts.map +1 -0
  28. package/dist/db/types.js +2 -0
  29. package/dist/db/types.js.map +1 -0
  30. package/dist/llm/comment-generator.d.ts +26 -0
  31. package/dist/llm/comment-generator.d.ts.map +1 -0
  32. package/dist/llm/comment-generator.js +106 -0
  33. package/dist/llm/comment-generator.js.map +1 -0
  34. package/dist/llm/index.d.ts +24 -0
  35. package/dist/llm/index.d.ts.map +1 -0
  36. package/dist/llm/index.js +54 -0
  37. package/dist/llm/index.js.map +1 -0
  38. package/dist/llm/prompts.d.ts +9 -0
  39. package/dist/llm/prompts.d.ts.map +1 -0
  40. package/dist/llm/prompts.js +79 -0
  41. package/dist/llm/prompts.js.map +1 -0
  42. package/dist/parser/call-resolver.d.ts +15 -0
  43. package/dist/parser/call-resolver.d.ts.map +1 -0
  44. package/dist/parser/call-resolver.js +16 -0
  45. package/dist/parser/call-resolver.js.map +1 -0
  46. package/dist/parser/extractor.d.ts +17 -0
  47. package/dist/parser/extractor.d.ts.map +1 -0
  48. package/dist/parser/extractor.js +254 -0
  49. package/dist/parser/extractor.js.map +1 -0
  50. package/dist/parser/index.d.ts +24 -0
  51. package/dist/parser/index.d.ts.map +1 -0
  52. package/dist/parser/index.js +190 -0
  53. package/dist/parser/index.js.map +1 -0
  54. package/dist/parser/languages.d.ts +11 -0
  55. package/dist/parser/languages.d.ts.map +1 -0
  56. package/dist/parser/languages.js +74 -0
  57. package/dist/parser/languages.js.map +1 -0
  58. package/dist/server/index.d.ts +3 -0
  59. package/dist/server/index.d.ts.map +1 -0
  60. package/dist/server/index.js +88 -0
  61. package/dist/server/index.js.map +1 -0
  62. package/dist/server/register-tools.d.ts +7 -0
  63. package/dist/server/register-tools.d.ts.map +1 -0
  64. package/dist/server/register-tools.js +17 -0
  65. package/dist/server/register-tools.js.map +1 -0
  66. package/dist/server/tools/clast-call-graph.d.ts +4 -0
  67. package/dist/server/tools/clast-call-graph.d.ts.map +1 -0
  68. package/dist/server/tools/clast-call-graph.js +70 -0
  69. package/dist/server/tools/clast-call-graph.js.map +1 -0
  70. package/dist/server/tools/clast-comment.d.ts +5 -0
  71. package/dist/server/tools/clast-comment.d.ts.map +1 -0
  72. package/dist/server/tools/clast-comment.js +64 -0
  73. package/dist/server/tools/clast-comment.js.map +1 -0
  74. package/dist/server/tools/clast-file-summary.d.ts +4 -0
  75. package/dist/server/tools/clast-file-summary.d.ts.map +1 -0
  76. package/dist/server/tools/clast-file-summary.js +42 -0
  77. package/dist/server/tools/clast-file-summary.js.map +1 -0
  78. package/dist/server/tools/clast-get-context.d.ts +4 -0
  79. package/dist/server/tools/clast-get-context.d.ts.map +1 -0
  80. package/dist/server/tools/clast-get-context.js +80 -0
  81. package/dist/server/tools/clast-get-context.js.map +1 -0
  82. package/dist/server/tools/clast-reindex.d.ts +5 -0
  83. package/dist/server/tools/clast-reindex.d.ts.map +1 -0
  84. package/dist/server/tools/clast-reindex.js +36 -0
  85. package/dist/server/tools/clast-reindex.js.map +1 -0
  86. package/dist/server/tools/clast-search.d.ts +4 -0
  87. package/dist/server/tools/clast-search.d.ts.map +1 -0
  88. package/dist/server/tools/clast-search.js +29 -0
  89. package/dist/server/tools/clast-search.js.map +1 -0
  90. package/dist/server/tools/clast-status.d.ts +5 -0
  91. package/dist/server/tools/clast-status.d.ts.map +1 -0
  92. package/dist/server/tools/clast-status.js +23 -0
  93. package/dist/server/tools/clast-status.js.map +1 -0
  94. package/dist/types.d.ts +52 -0
  95. package/dist/types.d.ts.map +1 -0
  96. package/dist/types.js +2 -0
  97. package/dist/types.js.map +1 -0
  98. package/dist/watcher/gitignore.d.ts +9 -0
  99. package/dist/watcher/gitignore.d.ts.map +1 -0
  100. package/dist/watcher/gitignore.js +38 -0
  101. package/dist/watcher/gitignore.js.map +1 -0
  102. package/dist/watcher/index.d.ts +23 -0
  103. package/dist/watcher/index.d.ts.map +1 -0
  104. package/dist/watcher/index.js +111 -0
  105. package/dist/watcher/index.js.map +1 -0
  106. package/package.json +65 -0
  107. package/skills/clast-explore/SKILL.md +41 -0
  108. package/src/config/defaults.ts +61 -0
  109. package/src/config/index.ts +55 -0
  110. package/src/db/index.ts +63 -0
  111. package/src/db/queries.ts +332 -0
  112. package/src/db/schema.ts +106 -0
  113. package/src/db/types.ts +47 -0
  114. package/src/llm/comment-generator.ts +131 -0
  115. package/src/llm/index.ts +80 -0
  116. package/src/llm/prompts.ts +95 -0
  117. package/src/parser/call-resolver.ts +17 -0
  118. package/src/parser/extractor.ts +303 -0
  119. package/src/parser/index.ts +226 -0
  120. package/src/parser/languages.ts +86 -0
  121. package/src/server/index.ts +109 -0
  122. package/src/server/register-tools.ts +30 -0
  123. package/src/server/tools/clast-call-graph.ts +82 -0
  124. package/src/server/tools/clast-comment.ts +76 -0
  125. package/src/server/tools/clast-file-summary.ts +59 -0
  126. package/src/server/tools/clast-get-context.ts +97 -0
  127. package/src/server/tools/clast-reindex.ts +52 -0
  128. package/src/server/tools/clast-search.ts +38 -0
  129. package/src/server/tools/clast-status.ts +37 -0
  130. package/src/types.ts +69 -0
  131. package/src/watcher/gitignore.ts +42 -0
  132. package/src/watcher/index.ts +131 -0
  133. package/tsconfig.json +20 -0
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "clast",
3
+ "version": "0.1.0",
4
+ "description": "AST-based code intelligence for Claude Code: search symbols, trace call graphs, generate documentation, and provide structured context for any repository. Supports TypeScript, JavaScript, Python, Java, C#, Go, Rust, C/C++, Ruby, and PHP.",
5
+ "author": {
6
+ "name": "Thomas"
7
+ },
8
+ "keywords": [
9
+ "ast",
10
+ "code-intelligence",
11
+ "call-graph",
12
+ "tree-sitter",
13
+ "mcp",
14
+ "documentation",
15
+ "code-navigation"
16
+ ],
17
+ "repository": "https://github.com/thomas/clast",
18
+ "license": "MIT",
19
+ "engines": {
20
+ "node": ">=18.0.0"
21
+ }
22
+ }
package/.mcp.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "clast": {
4
+ "command": "node",
5
+ "args": ["${CLAUDE_PLUGIN_ROOT}/dist/server/index.js"]
6
+ }
7
+ }
8
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Thomas
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,419 @@
1
+ # Clast
2
+
3
+ AST-based code intelligence plugin for Claude Code. Indexes your repository using [tree-sitter](https://tree-sitter.github.io/), maintains a live AST database, and exposes MCP tools for fast symbol search, call graph traversal, and context retrieval.
4
+
5
+ ## Features
6
+
7
+ - **Multi-language AST parsing** — TypeScript, JavaScript, Python, Java, C#, Go, Rust, C/C++, Ruby, PHP
8
+ - **Call graph tracking** — Trace callers and callees with configurable depth
9
+ - **Live file watching** — Automatic incremental re-indexing on file changes
10
+ - **Comment extraction** — Reads existing docstrings/comments; optionally generates missing ones via local LLM
11
+ - **Per-project database** — Each repo gets its own `.clast/` SQLite database with file hashes for change detection
12
+ - **Cross-platform** — Pure WASM (no native compilation), works on Windows, macOS, Linux
13
+ - **Zero config** — Automatically indexes the current working directory on startup
14
+
15
+ ---
16
+
17
+ ## Quick Start
18
+
19
+ ### Option 1: Install from npm (once published)
20
+
21
+ ```bash
22
+ npm install -g clast-ai
23
+ ```
24
+
25
+ ### Option 2: Install from GitHub (no cloning needed)
26
+
27
+ ```bash
28
+ npm install -g github:xls/clast
29
+ ```
30
+
31
+ npm fetches the repo, installs dependencies, and builds automatically via the `prepare` script. The `clast` command will be available globally.
32
+
33
+ ### Option 3: Clone and Build
34
+
35
+ ```bash
36
+ git clone https://github.com/xls/clast.git
37
+ cd clast
38
+ npm install
39
+ npm run build
40
+ ```
41
+
42
+ ### Option 4: As a Claude Code Plugin
43
+
44
+ ```bash
45
+ git clone https://github.com/xls/clast.git
46
+ cd clast
47
+ npm install && npm run build
48
+ claude plugin add /path/to/clast
49
+ ```
50
+
51
+ The plugin bundles a model-invoked skill that automatically suggests Clast tools when Claude is exploring code.
52
+
53
+ ### Publishing to npm
54
+
55
+ If you want to publish your own fork:
56
+
57
+ ```bash
58
+ npm login
59
+ npm publish
60
+ ```
61
+
62
+ Then anyone can `npm install -g clast-ai`.
63
+
64
+ ---
65
+
66
+ ## Setup for CLI
67
+
68
+ Add to `~/.claude/settings.local.json`:
69
+
70
+ ```json
71
+ {
72
+ "mcpServers": {
73
+ "clast": {
74
+ "command": "clast-ai"
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ Or using the CLI:
81
+
82
+ ```bash
83
+ claude mcp add clast -- clast-ai
84
+ ```
85
+
86
+ Restart Claude Code. Clast will automatically index whichever project directory you open.
87
+
88
+ ## Setup for VS Code (Claude Code Extension)
89
+
90
+ The Claude Code extension for VS Code uses the **same MCP configuration files** as the CLI. There is no separate VS Code-specific config.
91
+
92
+ **Step 1:** Open VS Code's integrated terminal and run:
93
+
94
+ ```bash
95
+ claude mcp add clast -- clast-ai
96
+ ```
97
+
98
+ Or manually add to `~/.claude/settings.local.json`:
99
+
100
+ ```json
101
+ {
102
+ "mcpServers": {
103
+ "clast": {
104
+ "command": "clast-ai"
105
+ }
106
+ }
107
+ }
108
+ ```
109
+
110
+ **Step 2:** Restart the Claude Code extension (Cmd/Ctrl+Shift+P → "Claude Code: Restart")
111
+
112
+ **Step 3:** Verify by typing `/mcp` in the Claude Code chat panel — you should see `clast` listed with 7 tools.
113
+
114
+ > **Note:** When VS Code spawns the MCP server, the working directory is your open workspace folder. Clast automatically indexes that directory — no path configuration needed.
115
+
116
+ If you built from source instead of installing globally:
117
+
118
+ ```json
119
+ {
120
+ "mcpServers": {
121
+ "clast": {
122
+ "command": "node",
123
+ "args": ["/path/to/clast/dist/server/index.js"]
124
+ }
125
+ }
126
+ }
127
+ ```
128
+
129
+ ## Per-Project Config (Optional)
130
+
131
+ To only enable Clast for a specific project instead of globally, create `.mcp.json` in the project root:
132
+
133
+ ```json
134
+ {
135
+ "mcpServers": {
136
+ "clast": {
137
+ "command": "clast-ai"
138
+ }
139
+ }
140
+ }
141
+ ```
142
+
143
+ This way Clast only activates when you open that project.
144
+
145
+ ---
146
+
147
+ ## Testing with MCP Inspector
148
+
149
+ To interactively test the tools without Claude Code:
150
+
151
+ ```bash
152
+ npx @modelcontextprotocol/inspector node /path/to/clast/dist/server/index.js
153
+ ```
154
+
155
+ Opens a web UI where you can call each tool and see responses.
156
+
157
+ ---
158
+
159
+ ## How It Detects Your Project
160
+
161
+ Clast resolves the project root in this order:
162
+
163
+ 1. `CLAST_PROJECT_DIR` environment variable (explicit override)
164
+ 2. `CLAUDE_PROJECT_DIR` (set automatically by Claude Code for plugins)
165
+ 3. `process.cwd()` — the current working directory
166
+
167
+ **In most cases you don't need to set anything.** Claude Code (both CLI and VS Code) sets the working directory to your project folder when spawning MCP servers.
168
+
169
+ Override example (for indexing a different directory):
170
+
171
+ ```json
172
+ {
173
+ "mcpServers": {
174
+ "clast": {
175
+ "command": "clast-ai",
176
+ "env": {
177
+ "CLAST_PROJECT_DIR": "/path/to/other/project"
178
+ }
179
+ }
180
+ }
181
+ }
182
+ ```
183
+
184
+ ---
185
+
186
+ ## MCP Tools
187
+
188
+ | Tool | Description | Read-only |
189
+ |------|-------------|-----------|
190
+ | `clast_search` | Search symbols by name, type, or pattern | Yes |
191
+ | `clast_call_graph` | Trace callers/callees with configurable depth (1-5 levels) | Yes |
192
+ | `clast_file_summary` | All symbols in a file, grouped by type (imports, classes, functions, etc.) | Yes |
193
+ | `clast_get_context` | Full symbol context: definition, comments, callers, callees, parent class | Yes |
194
+ | `clast_status` | Index statistics: files, nodes, edges, watcher state | Yes |
195
+ | `clast_reindex` | Force re-index a specific file or the entire repo | No |
196
+ | `clast_comment` | Get existing or generate new documentation comments via LLM | No |
197
+
198
+ ### Example Usage in Claude Code
199
+
200
+ - *"Search for the ParserManager class"* → Claude uses `clast_search`
201
+ - *"What calls the `parseAndStore` function?"* → Claude uses `clast_call_graph`
202
+ - *"Show me the structure of `src/db/queries.ts`"* → Claude uses `clast_file_summary`
203
+ - *"I need to refactor `extractFromTree` — what's the blast radius?"* → Claude uses `clast_get_context` + `clast_call_graph`
204
+
205
+ ---
206
+
207
+ ## Configuration
208
+
209
+ Configuration is optional. Clast works with sensible defaults out of the box.
210
+
211
+ To customize, create `clast.config.json` in your project root (or `.claude/clast.config.json`):
212
+
213
+ ```json
214
+ {
215
+ "languages": ["typescript", "javascript", "python", "java", "go", "rust"],
216
+ "ignoredPaths": ["node_modules", ".git", "dist", "build"],
217
+ "dbPath": ".clast/clast.db",
218
+ "maxBodySize": 2000,
219
+ "llm": {
220
+ "endpoint": "http://localhost:11434/v1",
221
+ "model": "qwen2.5-coder:7b",
222
+ "apiKey": "",
223
+ "alwaysGenerate": false,
224
+ "maxConcurrent": 3
225
+ },
226
+ "watch": {
227
+ "debounceMs": 300,
228
+ "enabled": true
229
+ }
230
+ }
231
+ ```
232
+
233
+ | Setting | Default | Description |
234
+ |---------|---------|-------------|
235
+ | `languages` | All supported (see below) | Which languages to parse |
236
+ | `ignoredPaths` | `node_modules`, `.git`, `dist`, etc. | Directories to skip |
237
+ | `dbPath` | `.clast/clast.db` | SQLite database location (relative to project root) |
238
+ | `maxBodySize` | `2000` | Max characters of function body stored per node |
239
+ | `llm.endpoint` | `http://localhost:11434/v1` | OpenAI-compatible API endpoint |
240
+ | `llm.model` | `""` (disabled) | LLM model name — empty string disables comment generation |
241
+ | `llm.apiKey` | `""` | API key if the endpoint requires one |
242
+ | `llm.alwaysGenerate` | `false` | Generate LLM comments even when original comments exist |
243
+ | `llm.maxConcurrent` | `3` | Max parallel LLM requests during batch generation |
244
+ | `watch.enabled` | `true` | Watch filesystem for changes |
245
+ | `watch.debounceMs` | `300` | Debounce delay for file change events |
246
+
247
+ ### Supported Languages
248
+
249
+ | Language | Config name | File extensions |
250
+ |----------|-------------|-----------------|
251
+ | TypeScript | `typescript` | `.ts` |
252
+ | TSX | `tsx` | `.tsx` |
253
+ | JavaScript | `javascript` | `.js`, `.jsx`, `.mjs`, `.cjs` |
254
+ | Python | `python` | `.py`, `.pyw` |
255
+ | Java | `java` | `.java` |
256
+ | C# | `csharp` | `.cs` |
257
+ | Go | `go` | `.go` |
258
+ | Rust | `rust` | `.rs` |
259
+ | C | `c` | `.c`, `.h` |
260
+ | C++ | `cpp` | `.cpp`, `.hpp`, `.cc`, `.hh`, `.cxx`, `.hxx` |
261
+ | Ruby | `ruby` | `.rb` |
262
+ | PHP | `php` | `.php` |
263
+
264
+ Use the **Config name** values in the `languages` array to enable/disable specific languages:
265
+
266
+ ```json
267
+ {
268
+ "languages": ["typescript", "javascript", "python", "go"]
269
+ }
270
+ ```
271
+
272
+ ---
273
+
274
+ ## LLM Comment Generation
275
+
276
+ Clast can generate documentation comments for functions and classes that lack them. This is **optional and disabled by default** — you need to configure an OpenAI-compatible API endpoint.
277
+
278
+ ### Comment Priority Logic
279
+
280
+ 1. If a function has an existing comment/docstring → use it (no LLM call)
281
+ 2. If no comment exists and LLM is configured → generate on demand via `clast_comment`
282
+ 3. Set `llm.alwaysGenerate: true` to generate LLM descriptions even when original comments exist
283
+
284
+ ### Setup with Ollama (Free, Local)
285
+
286
+ [Ollama](https://ollama.com/) runs models locally on your machine. No API key needed.
287
+
288
+ ```bash
289
+ # Install Ollama (https://ollama.com/download)
290
+ # Then pull a code model:
291
+ ollama pull qwen2.5-coder:7b
292
+ ```
293
+
294
+ Add to your `clast.config.json`:
295
+
296
+ ```json
297
+ {
298
+ "llm": {
299
+ "endpoint": "http://localhost:11434/v1",
300
+ "model": "qwen2.5-coder:7b"
301
+ }
302
+ }
303
+ ```
304
+
305
+ Ollama's default port (11434) and Clast's default endpoint already match — so you only need to set the model name.
306
+
307
+ **Recommended Ollama models for code:**
308
+
309
+ | Model | Size | VRAM | Quality |
310
+ |-------|------|------|---------|
311
+ | `qwen2.5-coder:7b` | 4.7 GB | ~6 GB | Good |
312
+ | `qwen2.5-coder:14b` | 9 GB | ~12 GB | Better |
313
+ | `qwen2.5-coder:32b` | 18 GB | ~24 GB | Best |
314
+ | `codellama:7b` | 3.8 GB | ~6 GB | Good |
315
+ | `deepseek-coder-v2:16b` | 8.9 GB | ~12 GB | Very good |
316
+
317
+ ### Setup with LM Studio (Free, Local)
318
+
319
+ [LM Studio](https://lmstudio.ai/) provides a GUI for running local models.
320
+
321
+ 1. Download and install LM Studio
322
+ 2. Download a code model (search for "Qwen 2.5 Coder" or "DeepSeek Coder")
323
+ 3. Start the local server (LM Studio → Local Server → Start)
324
+ 4. LM Studio serves on `http://localhost:1234/v1` by default
325
+
326
+ ```json
327
+ {
328
+ "llm": {
329
+ "endpoint": "http://localhost:1234/v1",
330
+ "model": "qwen2.5-coder-7b-instruct"
331
+ }
332
+ }
333
+ ```
334
+
335
+ > **Note:** The model name in `clast.config.json` must match exactly what LM Studio shows in its server panel.
336
+
337
+ ### Setup with OpenAI / OpenRouter / Any Cloud API
338
+
339
+ Any service that exposes an OpenAI-compatible `/v1/chat/completions` endpoint works:
340
+
341
+ ```json
342
+ {
343
+ "llm": {
344
+ "endpoint": "https://api.openai.com/v1",
345
+ "model": "gpt-4o-mini",
346
+ "apiKey": "sk-..."
347
+ }
348
+ }
349
+ ```
350
+
351
+ **OpenRouter** (access many models via one API):
352
+
353
+ ```json
354
+ {
355
+ "llm": {
356
+ "endpoint": "https://openrouter.ai/api/v1",
357
+ "model": "qwen/qwen-2.5-coder-32b-instruct",
358
+ "apiKey": "sk-or-..."
359
+ }
360
+ }
361
+ ```
362
+
363
+ ### Setup with vLLM (Self-Hosted)
364
+
365
+ If you run [vLLM](https://docs.vllm.ai/) on a server or cloud GPU:
366
+
367
+ ```json
368
+ {
369
+ "llm": {
370
+ "endpoint": "http://your-server:8000/v1",
371
+ "model": "Qwen/Qwen2.5-Coder-7B-Instruct"
372
+ }
373
+ }
374
+ ```
375
+
376
+ ---
377
+
378
+ ## How It Works
379
+
380
+ 1. **Startup** — Clast scans your project and parses all supported files using tree-sitter (WASM)
381
+ 2. **Storage** — Extracted symbols (functions, classes, methods, imports, etc.) are stored in a SQLite database at `.clast/clast.db`, along with SHA-256 file hashes
382
+ 3. **Call graph** — Call relationships are extracted from function bodies and resolved across files using name matching
383
+ 4. **Watching** — A file watcher detects changes and incrementally re-indexes only modified files (hash comparison skips unchanged files)
384
+ 5. **Querying** — Claude Code queries the AST database through MCP tools instead of reading raw files, getting structured context with file paths and line numbers
385
+
386
+ ### What Gets Indexed
387
+
388
+ For each supported file, Clast extracts:
389
+ - **Functions and methods** — name, signature, body, line numbers
390
+ - **Classes, interfaces, structs, traits** — with their methods as children
391
+ - **Imports and exports** — module relationships
392
+ - **Enums and type aliases**
393
+ - **Call edges** — which function calls which (resolved across files)
394
+ - **Comments and docstrings** — linked to their parent symbol
395
+
396
+ ### Database Location
397
+
398
+ Each project gets its own database at `{project_root}/.clast/clast.db`. Add `.clast/` to your `.gitignore` — the database is regenerated on startup from source files.
399
+
400
+ ---
401
+
402
+ ## VS Code Extension (Optional)
403
+
404
+ The `vscode/` directory contains a VS Code extension scaffold that:
405
+ - Auto-detects workspace folders
406
+ - Configures Claude Code's MCP settings automatically
407
+ - Provides commands: `Clast: Reindex`, `Clast: Status`, `Clast: Configure`
408
+
409
+ This is optional — most users just need the MCP server config described in [Setup for VS Code](#setup-for-vs-code).
410
+
411
+ ## Requirements
412
+
413
+ - Node.js >= 18
414
+ - For LLM comment generation: an OpenAI-compatible API endpoint (optional)
415
+ - No native compilation required — all dependencies are pure JS/WASM
416
+
417
+ ## License
418
+
419
+ MIT
@@ -0,0 +1,9 @@
1
+ ---
2
+ name: clast-status
3
+ description: Show Clast AST indexing status for the current repository
4
+ allowed-tools: [clast_status]
5
+ ---
6
+
7
+ Call the `clast_status` tool and present the results to the user in a clear, readable format.
8
+ Include: files indexed, total symbols, total call edges, total comments, last indexed time,
9
+ watcher status, and any pending files.
@@ -0,0 +1,19 @@
1
+ export interface ClastConfig {
2
+ languages: string[];
3
+ ignoredPaths: string[];
4
+ dbPath: string;
5
+ llm: {
6
+ endpoint: string;
7
+ model: string;
8
+ apiKey: string;
9
+ maxConcurrent: number;
10
+ alwaysGenerate: boolean;
11
+ };
12
+ watch: {
13
+ debounceMs: number;
14
+ enabled: boolean;
15
+ };
16
+ maxBodySize: number;
17
+ }
18
+ export declare const DEFAULT_CONFIG: ClastConfig;
19
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE;QACH,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,KAAK,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,cAAc,EAAE,WA0C5B,CAAC"}
@@ -0,0 +1,44 @@
1
+ export const DEFAULT_CONFIG = {
2
+ languages: [
3
+ 'typescript',
4
+ 'javascript',
5
+ 'python',
6
+ 'java',
7
+ 'csharp',
8
+ 'go',
9
+ 'rust',
10
+ 'c',
11
+ 'cpp',
12
+ 'ruby',
13
+ 'php',
14
+ ],
15
+ ignoredPaths: [
16
+ 'node_modules',
17
+ '.git',
18
+ 'dist',
19
+ 'build',
20
+ 'out',
21
+ '__pycache__',
22
+ '.venv',
23
+ 'venv',
24
+ '.clast',
25
+ 'vendor',
26
+ 'target',
27
+ '.next',
28
+ 'coverage',
29
+ ],
30
+ dbPath: '.clast/clast.db',
31
+ llm: {
32
+ endpoint: 'http://localhost:11434/v1',
33
+ model: '',
34
+ apiKey: '',
35
+ maxConcurrent: 3,
36
+ alwaysGenerate: false,
37
+ },
38
+ watch: {
39
+ debounceMs: 300,
40
+ enabled: true,
41
+ },
42
+ maxBodySize: 2000,
43
+ };
44
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAkBA,MAAM,CAAC,MAAM,cAAc,GAAgB;IACzC,SAAS,EAAE;QACT,YAAY;QACZ,YAAY;QACZ,QAAQ;QACR,MAAM;QACN,QAAQ;QACR,IAAI;QACJ,MAAM;QACN,GAAG;QACH,KAAK;QACL,MAAM;QACN,KAAK;KACN;IACD,YAAY,EAAE;QACZ,cAAc;QACd,MAAM;QACN,MAAM;QACN,OAAO;QACP,KAAK;QACL,aAAa;QACb,OAAO;QACP,MAAM;QACN,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,OAAO;QACP,UAAU;KACX;IACD,MAAM,EAAE,iBAAiB;IACzB,GAAG,EAAE;QACH,QAAQ,EAAE,2BAA2B;QACrC,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,EAAE;QACV,aAAa,EAAE,CAAC;QAChB,cAAc,EAAE,KAAK;KACtB;IACD,KAAK,EAAE;QACL,UAAU,EAAE,GAAG;QACf,OAAO,EAAE,IAAI;KACd;IACD,WAAW,EAAE,IAAI;CAClB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { type ClastConfig } from './defaults.js';
2
+ export type { ClastConfig } from './defaults.js';
3
+ export declare function loadConfig(projectRoot: string): ClastConfig;
4
+ export declare function resolveDbPath(projectRoot: string, config: ClastConfig): string;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAwBjE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAkB3D;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CAK9E"}
@@ -0,0 +1,48 @@
1
+ import { z } from 'zod';
2
+ import { readFileSync, existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { DEFAULT_CONFIG } from './defaults.js';
5
+ const LlmConfigSchema = z.object({
6
+ endpoint: z.string().default(DEFAULT_CONFIG.llm.endpoint),
7
+ model: z.string().default(DEFAULT_CONFIG.llm.model),
8
+ apiKey: z.string().default(DEFAULT_CONFIG.llm.apiKey),
9
+ maxConcurrent: z.number().int().min(1).max(10).default(DEFAULT_CONFIG.llm.maxConcurrent),
10
+ alwaysGenerate: z.boolean().default(DEFAULT_CONFIG.llm.alwaysGenerate),
11
+ });
12
+ const WatchConfigSchema = z.object({
13
+ debounceMs: z.number().int().min(50).max(5000).default(DEFAULT_CONFIG.watch.debounceMs),
14
+ enabled: z.boolean().default(DEFAULT_CONFIG.watch.enabled),
15
+ });
16
+ const ClastConfigSchema = z.object({
17
+ languages: z.array(z.string()).default(DEFAULT_CONFIG.languages),
18
+ ignoredPaths: z.array(z.string()).default(DEFAULT_CONFIG.ignoredPaths),
19
+ dbPath: z.string().default(DEFAULT_CONFIG.dbPath),
20
+ llm: LlmConfigSchema.default(DEFAULT_CONFIG.llm),
21
+ watch: WatchConfigSchema.default(DEFAULT_CONFIG.watch),
22
+ maxBodySize: z.number().int().min(100).max(50000).default(DEFAULT_CONFIG.maxBodySize),
23
+ });
24
+ export function loadConfig(projectRoot) {
25
+ const candidates = [
26
+ join(projectRoot, 'clast.config.json'),
27
+ join(projectRoot, '.claude', 'clast.config.json'),
28
+ ];
29
+ for (const candidate of candidates) {
30
+ if (existsSync(candidate)) {
31
+ try {
32
+ const raw = JSON.parse(readFileSync(candidate, 'utf-8'));
33
+ return ClastConfigSchema.parse(raw);
34
+ }
35
+ catch (err) {
36
+ console.error(`[clast] Failed to parse config at ${candidate}:`, err);
37
+ }
38
+ }
39
+ }
40
+ return ClastConfigSchema.parse({});
41
+ }
42
+ export function resolveDbPath(projectRoot, config) {
43
+ if (config.dbPath.startsWith('/') || config.dbPath.match(/^[a-zA-Z]:\\/)) {
44
+ return config.dbPath;
45
+ }
46
+ return join(projectRoot, config.dbPath);
47
+ }
48
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAoB,MAAM,eAAe,CAAC;AAEjE,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC;IACzD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC;IACnD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC;IACrD,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,aAAa,CAAC;IACxF,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC;CACvE,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC;IACvF,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC;CAC3D,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC;IAChE,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,YAAY,CAAC;IACtE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC;IACjD,GAAG,EAAE,eAAe,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC;IAChD,KAAK,EAAE,iBAAiB,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC;IACtD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC;CACtF,CAAC,CAAC;AAIH,MAAM,UAAU,UAAU,CAAC,WAAmB;IAC5C,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,WAAW,EAAE,mBAAmB,CAAC;QACtC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,mBAAmB,CAAC;KAClD,CAAC;IAEF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;gBACzD,OAAO,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAgB,CAAC;YACrD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,qCAAqC,SAAS,GAAG,EAAE,GAAG,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAgB,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,WAAmB,EAAE,MAAmB;IACpE,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;QACzE,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;IACD,OAAO,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type Database } from 'sql.js';
2
+ import { Queries } from './queries.js';
3
+ export declare class ClastDatabase {
4
+ private db;
5
+ private dbPath;
6
+ private saveTimer;
7
+ queries: Queries;
8
+ private constructor();
9
+ static open(dbPath: string): Promise<ClastDatabase>;
10
+ save(): void;
11
+ close(): void;
12
+ get raw(): Database;
13
+ }
14
+ export { Queries } from './queries.js';
15
+ export type { FileRow, AstNodeRow, CallEdgeRow, CommentRow, StatusRow } from './types.js';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAkB,EAAE,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAIlD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAAW;IACrB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAA+C;IACzD,OAAO,EAAE,OAAO,CAAC;IAExB,OAAO;WAUM,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAgBzD,IAAI,IAAI,IAAI;IASZ,KAAK,IAAI,IAAI;IASb,IAAI,GAAG,IAAI,QAAQ,CAElB;CACF;AAED,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}