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,24 @@
1
+ import TreeSitter from 'web-tree-sitter';
2
+ import type { ClastDatabase } from '../db/index.js';
3
+ import type { ClastConfig } from '../config/index.js';
4
+ export declare class ParserManager {
5
+ private parser;
6
+ private languages;
7
+ private config;
8
+ private initialized;
9
+ constructor(config: ClastConfig);
10
+ init(): Promise<void>;
11
+ private getLanguage;
12
+ parseSource(source: string, langName: string): Promise<TreeSitter.Tree | null>;
13
+ parseAndStore(filePath: string, projectRoot: string, db: ClastDatabase): Promise<boolean>;
14
+ fullIndex(projectRoot: string, db: ClastDatabase, onProgress?: (file: string, current: number, total: number) => void): Promise<{
15
+ filesProcessed: number;
16
+ nodesFound: number;
17
+ edgesResolved: number;
18
+ durationMs: number;
19
+ }>;
20
+ incrementalUpdate(filePath: string, projectRoot: string, db: ClastDatabase): Promise<boolean>;
21
+ removeFile(filePath: string, projectRoot: string, db: ClastDatabase): void;
22
+ private collectFiles;
23
+ }
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,iBAAiB,CAAC;AAOzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,EAAE,WAAW;IAIzB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAOb,WAAW;IAqBnB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC;IAW9E,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IAgFzF,SAAS,CACb,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,aAAa,EACjB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAClE,OAAO,CAAC;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IA8B/F,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IASnG,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,GAAG,IAAI;IAM1E,OAAO,CAAC,YAAY;CAoCrB"}
@@ -0,0 +1,190 @@
1
+ import TreeSitter from 'web-tree-sitter';
2
+ import { createHash } from 'node:crypto';
3
+ import { readFileSync, readdirSync, statSync } from 'node:fs';
4
+ import { join, extname, relative } from 'node:path';
5
+ import { getLanguageForExtension, getGrammarWasmPath, getSupportedExtensions } from './languages.js';
6
+ import { extractFromTree } from './extractor.js';
7
+ import { resolveCallEdges } from './call-resolver.js';
8
+ export class ParserManager {
9
+ parser = null;
10
+ languages = new Map();
11
+ config;
12
+ initialized = false;
13
+ constructor(config) {
14
+ this.config = config;
15
+ }
16
+ async init() {
17
+ if (this.initialized)
18
+ return;
19
+ await TreeSitter.init();
20
+ this.parser = new TreeSitter();
21
+ this.initialized = true;
22
+ }
23
+ async getLanguage(langName) {
24
+ if (this.languages.has(langName)) {
25
+ return this.languages.get(langName);
26
+ }
27
+ const wasmPath = getGrammarWasmPath(langName);
28
+ if (!wasmPath) {
29
+ console.error(`[clast] No WASM grammar found for ${langName}`);
30
+ return null;
31
+ }
32
+ try {
33
+ const language = await TreeSitter.Language.load(wasmPath);
34
+ this.languages.set(langName, language);
35
+ return language;
36
+ }
37
+ catch (err) {
38
+ console.error(`[clast] Failed to load grammar for ${langName}:`, err);
39
+ return null;
40
+ }
41
+ }
42
+ async parseSource(source, langName) {
43
+ await this.init();
44
+ if (!this.parser)
45
+ return null;
46
+ const language = await this.getLanguage(langName);
47
+ if (!language)
48
+ return null;
49
+ this.parser.setLanguage(language);
50
+ return this.parser.parse(source);
51
+ }
52
+ async parseAndStore(filePath, projectRoot, db) {
53
+ const ext = extname(filePath);
54
+ const langEntry = getLanguageForExtension(ext);
55
+ if (!langEntry)
56
+ return false;
57
+ const relPath = relative(projectRoot, filePath).replace(/\\/g, '/');
58
+ let source;
59
+ try {
60
+ source = readFileSync(filePath, 'utf-8');
61
+ }
62
+ catch {
63
+ return false;
64
+ }
65
+ const hash = createHash('sha256').update(source).digest('hex');
66
+ const existingHash = db.queries.getFileHash(relPath);
67
+ if (existingHash === hash)
68
+ return false;
69
+ const tree = await this.parseSource(source, langEntry.name);
70
+ if (!tree)
71
+ return false;
72
+ const result = extractFromTree(tree, relPath, langEntry.name, source, this.config.maxBodySize);
73
+ // Delete old data for this file and upsert file record BEFORE inserting nodes
74
+ // (nodes have a FK to files.file_path)
75
+ db.queries.deleteNodesForFile(relPath);
76
+ db.queries.upsertFile(relPath, hash, langEntry.name, result.nodes.length);
77
+ // Insert nodes
78
+ const nodeRows = result.nodes.map(n => ({
79
+ file_path: n.filePath,
80
+ name: n.name,
81
+ type: n.type,
82
+ signature: n.signature,
83
+ start_line: n.startLine,
84
+ end_line: n.endLine,
85
+ start_col: n.startCol,
86
+ end_col: n.endCol,
87
+ parent_id: n.parentId,
88
+ language: n.language,
89
+ body_text: n.bodyText,
90
+ }));
91
+ const nodeIds = db.queries.insertNodes(nodeRows);
92
+ // Insert edges
93
+ const edgeRows = result.edges
94
+ .filter(e => nodeIds[e.callerNodeIndex] !== undefined)
95
+ .map(e => ({
96
+ caller_id: nodeIds[e.callerNodeIndex],
97
+ callee_id: null,
98
+ callee_name: e.calleeName,
99
+ file_path: relPath,
100
+ line: e.line,
101
+ }));
102
+ if (edgeRows.length > 0) {
103
+ db.queries.insertEdges(edgeRows);
104
+ }
105
+ // Insert comments
106
+ for (const c of result.comments) {
107
+ const dbId = nodeIds[c.nodeIndex];
108
+ if (dbId !== undefined) {
109
+ db.queries.insertComment(dbId, c.text, c.source);
110
+ }
111
+ }
112
+ // Save DB periodically
113
+ db.save();
114
+ return true;
115
+ }
116
+ async fullIndex(projectRoot, db, onProgress) {
117
+ await this.init();
118
+ const start = Date.now();
119
+ const supportedExts = new Set(getSupportedExtensions(this.config.languages));
120
+ const files = this.collectFiles(projectRoot, supportedExts);
121
+ let filesProcessed = 0;
122
+ for (let i = 0; i < files.length; i++) {
123
+ const file = files[i];
124
+ onProgress?.(file, i + 1, files.length);
125
+ if (await this.parseAndStore(file, projectRoot, db)) {
126
+ filesProcessed++;
127
+ }
128
+ }
129
+ const edgesResolved = resolveCallEdges(db.queries);
130
+ // Final save
131
+ db.save();
132
+ const status = db.queries.getStatus();
133
+ return {
134
+ filesProcessed,
135
+ nodesFound: status.total_nodes,
136
+ edgesResolved,
137
+ durationMs: Date.now() - start,
138
+ };
139
+ }
140
+ async incrementalUpdate(filePath, projectRoot, db) {
141
+ const parsed = await this.parseAndStore(filePath, projectRoot, db);
142
+ if (parsed) {
143
+ resolveCallEdges(db.queries);
144
+ db.save();
145
+ }
146
+ return parsed;
147
+ }
148
+ removeFile(filePath, projectRoot, db) {
149
+ const relPath = relative(projectRoot, filePath).replace(/\\/g, '/');
150
+ db.queries.deleteFile(relPath);
151
+ db.save();
152
+ }
153
+ collectFiles(dir, supportedExts, depth = 0) {
154
+ if (depth > 20)
155
+ return [];
156
+ const files = [];
157
+ let entries;
158
+ try {
159
+ entries = readdirSync(dir);
160
+ }
161
+ catch {
162
+ return files;
163
+ }
164
+ for (const entry of entries) {
165
+ if (this.config.ignoredPaths.includes(entry))
166
+ continue;
167
+ if (entry.startsWith('.'))
168
+ continue;
169
+ const fullPath = join(dir, entry);
170
+ let stat;
171
+ try {
172
+ stat = statSync(fullPath);
173
+ }
174
+ catch {
175
+ continue;
176
+ }
177
+ if (stat.isDirectory()) {
178
+ files.push(...this.collectFiles(fullPath, supportedExts, depth + 1));
179
+ }
180
+ else if (stat.isFile()) {
181
+ const ext = extname(entry);
182
+ if (supportedExts.has(ext)) {
183
+ files.push(fullPath);
184
+ }
185
+ }
186
+ }
187
+ return files;
188
+ }
189
+ }
190
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ interface LanguageEntry {
2
+ name: string;
3
+ extensions: string[];
4
+ wasmFile: string;
5
+ }
6
+ export declare function getLanguageForExtension(ext: string): LanguageEntry | undefined;
7
+ export declare function getGrammarWasmPath(langName: string): string | null;
8
+ export declare function getSupportedExtensions(enabledLanguages?: string[]): string[];
9
+ export declare function getAllLanguageNames(): string[];
10
+ export {};
11
+ //# sourceMappingURL=languages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"languages.d.ts","sourceRoot":"","sources":["../../src/parser/languages.ts"],"names":[],"mappings":"AAKA,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAyBD,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAE9E;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiClE;AAED,wBAAgB,sBAAsB,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAQ5E;AAED,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAE9C"}
@@ -0,0 +1,74 @@
1
+ import { join, dirname } from 'node:path';
2
+ import { existsSync } from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { createRequire } from 'node:module';
5
+ const LANGUAGES = [
6
+ { name: 'typescript', extensions: ['.ts'], wasmFile: 'tree-sitter-typescript.wasm' },
7
+ { name: 'tsx', extensions: ['.tsx'], wasmFile: 'tree-sitter-tsx.wasm' },
8
+ { name: 'javascript', extensions: ['.js', '.jsx', '.mjs', '.cjs'], wasmFile: 'tree-sitter-javascript.wasm' },
9
+ { name: 'python', extensions: ['.py', '.pyw'], wasmFile: 'tree-sitter-python.wasm' },
10
+ { name: 'java', extensions: ['.java'], wasmFile: 'tree-sitter-java.wasm' },
11
+ { name: 'csharp', extensions: ['.cs'], wasmFile: 'tree-sitter-c_sharp.wasm' },
12
+ { name: 'go', extensions: ['.go'], wasmFile: 'tree-sitter-go.wasm' },
13
+ { name: 'rust', extensions: ['.rs'], wasmFile: 'tree-sitter-rust.wasm' },
14
+ { name: 'c', extensions: ['.c', '.h'], wasmFile: 'tree-sitter-c.wasm' },
15
+ { name: 'cpp', extensions: ['.cpp', '.hpp', '.cc', '.hh', '.cxx', '.hxx'], wasmFile: 'tree-sitter-cpp.wasm' },
16
+ { name: 'ruby', extensions: ['.rb'], wasmFile: 'tree-sitter-ruby.wasm' },
17
+ { name: 'php', extensions: ['.php'], wasmFile: 'tree-sitter-php.wasm' },
18
+ ];
19
+ // Extension → language entry mapping
20
+ const EXT_MAP = new Map();
21
+ for (const lang of LANGUAGES) {
22
+ for (const ext of lang.extensions) {
23
+ EXT_MAP.set(ext, lang);
24
+ }
25
+ }
26
+ export function getLanguageForExtension(ext) {
27
+ return EXT_MAP.get(ext.toLowerCase());
28
+ }
29
+ export function getGrammarWasmPath(langName) {
30
+ const entry = LANGUAGES.find(l => l.name === langName);
31
+ if (!entry)
32
+ return null;
33
+ // Try to resolve from tree-sitter-wasms npm package first
34
+ const require = createRequire(import.meta.url);
35
+ try {
36
+ const wasmsDir = dirname(require.resolve('tree-sitter-wasms/package.json'));
37
+ const npmPath = join(wasmsDir, 'out', entry.wasmFile);
38
+ if (existsSync(npmPath))
39
+ return npmPath;
40
+ }
41
+ catch {
42
+ // tree-sitter-wasms not installed, try fallbacks
43
+ }
44
+ const __dirname = dirname(fileURLToPath(import.meta.url));
45
+ // Check grammars/ directory relative to project
46
+ const candidates = [
47
+ // Custom grammars dir (env override)
48
+ process.env.CLAST_GRAMMARS_DIR ? join(process.env.CLAST_GRAMMARS_DIR, entry.wasmFile) : null,
49
+ // Plugin root
50
+ process.env.CLAUDE_PLUGIN_ROOT ? join(process.env.CLAUDE_PLUGIN_ROOT, 'grammars', entry.wasmFile) : null,
51
+ // Relative to dist/
52
+ join(__dirname, '..', '..', 'grammars', entry.wasmFile),
53
+ // CWD
54
+ join(process.cwd(), 'grammars', entry.wasmFile),
55
+ ].filter(Boolean);
56
+ for (const candidate of candidates) {
57
+ if (existsSync(candidate))
58
+ return candidate;
59
+ }
60
+ return null;
61
+ }
62
+ export function getSupportedExtensions(enabledLanguages) {
63
+ const result = [];
64
+ for (const lang of LANGUAGES) {
65
+ if (!enabledLanguages || enabledLanguages.includes(lang.name)) {
66
+ result.push(...lang.extensions);
67
+ }
68
+ }
69
+ return result;
70
+ }
71
+ export function getAllLanguageNames() {
72
+ return LANGUAGES.map(l => l.name);
73
+ }
74
+ //# sourceMappingURL=languages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"languages.js","sourceRoot":"","sources":["../../src/parser/languages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { resolve } from 'node:path';
5
+ import { loadConfig, resolveDbPath } from '../config/index.js';
6
+ import { ClastDatabase } from '../db/index.js';
7
+ import { ParserManager } from '../parser/index.js';
8
+ import { FileWatcher } from '../watcher/index.js';
9
+ import { LlmClient } from '../llm/index.js';
10
+ import { CommentGenerator } from '../llm/comment-generator.js';
11
+ import { registerAllTools } from './register-tools.js';
12
+ async function main() {
13
+ // Determine project root
14
+ const projectRoot = resolve(process.env.CLAST_PROJECT_DIR ??
15
+ process.env.CLAUDE_PROJECT_DIR ??
16
+ process.cwd());
17
+ console.error(`[clast] Project root: ${projectRoot}`);
18
+ // Load configuration
19
+ const config = loadConfig(projectRoot);
20
+ console.error(`[clast] Config loaded. Languages: ${config.languages.join(', ')}`);
21
+ // Open database (async — sql.js uses WASM)
22
+ const dbPath = resolveDbPath(projectRoot, config);
23
+ console.error(`[clast] Database: ${dbPath}`);
24
+ const db = await ClastDatabase.open(dbPath);
25
+ // Create parser (async — web-tree-sitter uses WASM)
26
+ const parser = new ParserManager(config);
27
+ await parser.init();
28
+ // Create watcher
29
+ const watcher = new FileWatcher(projectRoot, config, db, parser);
30
+ // Create LLM client + comment generator
31
+ const llmClient = new LlmClient(config.llm.endpoint, config.llm.model, config.llm.apiKey);
32
+ const commentGen = new CommentGenerator(llmClient, db.queries, config);
33
+ if (llmClient.isConfigured) {
34
+ console.error(`[clast] LLM configured: ${config.llm.model} @ ${config.llm.endpoint}`);
35
+ }
36
+ else {
37
+ console.error('[clast] LLM not configured (comment generation disabled)');
38
+ }
39
+ // Create MCP server
40
+ const server = new McpServer({
41
+ name: 'clast',
42
+ version: '0.1.0',
43
+ });
44
+ // Register all tools
45
+ registerAllTools(server, db, parser, watcher, commentGen, projectRoot);
46
+ // Perform initial index
47
+ console.error('[clast] Starting initial index...');
48
+ const indexResult = await parser.fullIndex(projectRoot, db, (file, current, total) => {
49
+ if (current % 50 === 0 || current === total) {
50
+ console.error(`[clast] Indexing: ${current}/${total} files`);
51
+ }
52
+ });
53
+ console.error(`[clast] Index complete: ${indexResult.filesProcessed} files, ` +
54
+ `${indexResult.nodesFound} nodes, ${indexResult.edgesResolved} edges resolved ` +
55
+ `(${indexResult.durationMs}ms)`);
56
+ // Start file watcher
57
+ watcher.start();
58
+ watcher.on('indexed', ({ filePath, nodesFound }) => {
59
+ console.error(`[clast] Updated: ${filePath} (${nodesFound} nodes)`);
60
+ });
61
+ watcher.on('deleted', ({ filePath }) => {
62
+ console.error(`[clast] Removed: ${filePath}`);
63
+ });
64
+ watcher.on('error', ({ filePath, error }) => {
65
+ console.error(`[clast] Error processing ${filePath}:`, error.message);
66
+ });
67
+ if (watcher.isActive) {
68
+ console.error('[clast] File watcher active');
69
+ }
70
+ // Connect to stdio transport
71
+ const transport = new StdioServerTransport();
72
+ await server.connect(transport);
73
+ console.error('[clast] MCP server running on stdio');
74
+ // Graceful shutdown
75
+ const shutdown = () => {
76
+ console.error('[clast] Shutting down...');
77
+ watcher.stop();
78
+ db.close();
79
+ process.exit(0);
80
+ };
81
+ process.on('SIGINT', shutdown);
82
+ process.on('SIGTERM', shutdown);
83
+ }
84
+ main().catch((err) => {
85
+ console.error('[clast] Fatal error:', err);
86
+ process.exit(1);
87
+ });
88
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ClastDatabase } from '../db/index.js';
3
+ import type { ParserManager } from '../parser/index.js';
4
+ import type { FileWatcher } from '../watcher/index.js';
5
+ import type { CommentGenerator } from '../llm/comment-generator.js';
6
+ export declare function registerAllTools(server: McpServer, db: ClastDatabase, parser: ParserManager, watcher: FileWatcher, commentGen: CommentGenerator, projectRoot: string): void;
7
+ //# sourceMappingURL=register-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-tools.d.ts","sourceRoot":"","sources":["../../src/server/register-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAUpE,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,EAAE,EAAE,aAAa,EACjB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,gBAAgB,EAC5B,WAAW,EAAE,MAAM,GAClB,IAAI,CAQN"}
@@ -0,0 +1,17 @@
1
+ import { registerSearchTool } from './tools/clast-search.js';
2
+ import { registerCallGraphTool } from './tools/clast-call-graph.js';
3
+ import { registerFileSummaryTool } from './tools/clast-file-summary.js';
4
+ import { registerGetContextTool } from './tools/clast-get-context.js';
5
+ import { registerStatusTool } from './tools/clast-status.js';
6
+ import { registerReindexTool } from './tools/clast-reindex.js';
7
+ import { registerCommentTool } from './tools/clast-comment.js';
8
+ export function registerAllTools(server, db, parser, watcher, commentGen, projectRoot) {
9
+ registerSearchTool(server, db);
10
+ registerCallGraphTool(server, db);
11
+ registerFileSummaryTool(server, db);
12
+ registerGetContextTool(server, db);
13
+ registerStatusTool(server, db, watcher);
14
+ registerReindexTool(server, db, parser, projectRoot);
15
+ registerCommentTool(server, db, commentGen);
16
+ }
17
+ //# sourceMappingURL=register-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-tools.js","sourceRoot":"","sources":["../../src/server/register-tools.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,MAAM,UAAU,gBAAgB,CAC9B,MAAiB,EACjB,EAAiB,EACjB,MAAqB,EACrB,OAAoB,EACpB,UAA4B,EAC5B,WAAmB;IAEnB,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/B,qBAAqB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAClC,uBAAuB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACpC,sBAAsB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACnC,kBAAkB,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IACxC,mBAAmB,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IACrD,mBAAmB,CAAC,MAAM,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ClastDatabase } from '../../db/index.js';
3
+ export declare function registerCallGraphTool(server: McpServer, db: ClastDatabase): void;
4
+ //# sourceMappingURL=clast-call-graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clast-call-graph.d.ts","sourceRoot":"","sources":["../../../src/server/tools/clast-call-graph.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,aAAa,GAAG,IAAI,CA6EhF"}
@@ -0,0 +1,70 @@
1
+ import { z } from 'zod';
2
+ export function registerCallGraphTool(server, db) {
3
+ server.tool('clast_call_graph', 'Get the call graph for a function or method: what it calls (callees) and what calls it (callers). Supports configurable traversal depth.', {
4
+ name: z.string().describe('Function or method name to trace'),
5
+ depth: z.number().int().min(1).max(5).default(2).describe('How many levels deep to traverse'),
6
+ direction: z.enum(['callers', 'callees', 'both']).default('both').describe('Direction to traverse'),
7
+ }, async ({ name, depth, direction }) => {
8
+ const node = db.queries.getNodeByName(name);
9
+ if (node.length === 0) {
10
+ return {
11
+ content: [{
12
+ type: 'text',
13
+ text: JSON.stringify({ error: `No symbol found with name "${name}"` }),
14
+ }],
15
+ };
16
+ }
17
+ const result = {
18
+ symbol: {
19
+ name: node[0].name,
20
+ type: node[0].type,
21
+ filePath: node[0].file_path,
22
+ startLine: node[0].start_line,
23
+ endLine: node[0].end_line,
24
+ signature: node[0].signature,
25
+ },
26
+ };
27
+ if (direction === 'callers' || direction === 'both') {
28
+ const callers = db.queries.getCallersOf(name, depth);
29
+ result.callers = callers.map(n => ({
30
+ name: n.name,
31
+ type: n.type,
32
+ filePath: n.file_path,
33
+ startLine: n.start_line,
34
+ signature: n.signature,
35
+ }));
36
+ }
37
+ if (direction === 'callees' || direction === 'both') {
38
+ const callees = db.queries.getCalleesOf(name, depth);
39
+ result.callees = callees.map(n => ({
40
+ name: n.name,
41
+ type: n.type,
42
+ filePath: n.file_path,
43
+ startLine: n.start_line,
44
+ signature: n.signature,
45
+ }));
46
+ }
47
+ // Also include direct call edge details for the primary node
48
+ if (node[0]) {
49
+ const edges = db.queries.getCallEdgesForNode(node[0].id);
50
+ result.directCalls = {
51
+ outgoing: edges.outgoing.map(e => ({
52
+ calleeName: e.callee_name,
53
+ line: e.line,
54
+ resolved: e.callee_id !== null,
55
+ })),
56
+ incoming: edges.incoming.map(e => ({
57
+ callerId: e.caller_id,
58
+ line: e.line,
59
+ })),
60
+ };
61
+ }
62
+ return {
63
+ content: [{
64
+ type: 'text',
65
+ text: JSON.stringify(result, null, 2),
66
+ }],
67
+ };
68
+ });
69
+ }
70
+ //# sourceMappingURL=clast-call-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clast-call-graph.js","sourceRoot":"","sources":["../../../src/server/tools/clast-call-graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ClastDatabase } from '../../db/index.js';
3
+ import type { CommentGenerator } from '../../llm/comment-generator.js';
4
+ export declare function registerCommentTool(server: McpServer, db: ClastDatabase, commentGen: CommentGenerator): void;
5
+ //# sourceMappingURL=clast-comment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clast-comment.d.ts","sourceRoot":"","sources":["../../../src/server/tools/clast-comment.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,EAAE,EAAE,aAAa,EACjB,UAAU,EAAE,gBAAgB,GAC3B,IAAI,CAkEN"}
@@ -0,0 +1,64 @@
1
+ import { z } from 'zod';
2
+ export function registerCommentTool(server, db, commentGen) {
3
+ server.tool('clast_comment', 'Get or generate documentation comments for a symbol. By default returns existing comments. Set generate=true to create a new comment via LLM if none exists.', {
4
+ name: z.string().describe('Symbol name to get/generate comment for'),
5
+ generate: z.boolean().default(false).describe('If true and no comment exists, generate one via LLM'),
6
+ }, async ({ name, generate }) => {
7
+ const nodes = db.queries.getNodeByName(name);
8
+ if (nodes.length === 0) {
9
+ return {
10
+ content: [{
11
+ type: 'text',
12
+ text: JSON.stringify({ error: `No symbol found with name "${name}"` }),
13
+ }],
14
+ };
15
+ }
16
+ const results = [];
17
+ for (const node of nodes) {
18
+ const comments = db.queries.getCommentsForNode(node.id);
19
+ const original = comments.find(c => c.source === 'original');
20
+ const generated = comments.find(c => c.source === 'generated');
21
+ const entry = {
22
+ name: node.name,
23
+ type: node.type,
24
+ filePath: node.file_path,
25
+ startLine: node.start_line,
26
+ };
27
+ if (original) {
28
+ entry.comment = original.text;
29
+ entry.source = 'original';
30
+ }
31
+ else if (generated) {
32
+ entry.comment = generated.text;
33
+ entry.source = 'generated';
34
+ }
35
+ else if (generate) {
36
+ if (!commentGen.isAvailable) {
37
+ entry.error = 'LLM not configured. Set llm.model in clast.config.json.';
38
+ }
39
+ else {
40
+ const result = await commentGen.generateForNode(node.id);
41
+ if (result) {
42
+ entry.comment = result;
43
+ entry.source = 'generated';
44
+ }
45
+ else {
46
+ entry.error = 'Failed to generate comment';
47
+ }
48
+ }
49
+ }
50
+ else {
51
+ entry.comment = null;
52
+ entry.source = null;
53
+ }
54
+ results.push(entry);
55
+ }
56
+ return {
57
+ content: [{
58
+ type: 'text',
59
+ text: JSON.stringify(results, null, 2),
60
+ }],
61
+ };
62
+ });
63
+ }
64
+ //# sourceMappingURL=clast-comment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clast-comment.js","sourceRoot":"","sources":["../../../src/server/tools/clast-comment.ts"],"names":[],"mappings":"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"}