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,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ClastDatabase } from '../../db/index.js';
3
+ export declare function registerFileSummaryTool(server: McpServer, db: ClastDatabase): void;
4
+ //# sourceMappingURL=clast-file-summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clast-file-summary.d.ts","sourceRoot":"","sources":["../../../src/server/tools/clast-file-summary.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,aAAa,GAAG,IAAI,CAsDlF"}
@@ -0,0 +1,42 @@
1
+ import { z } from 'zod';
2
+ export function registerFileSummaryTool(server, db) {
3
+ server.tool('clast_file_summary', 'Get a structured summary of all symbols in a file, grouped by type (imports, classes, functions, exports, etc.). Use instead of reading the whole file to understand its structure.', {
4
+ filePath: z.string().describe('Relative file path (forward slashes, e.g. "src/parser/index.ts")'),
5
+ }, async ({ filePath }) => {
6
+ // Normalize path
7
+ const normalized = filePath.replace(/\\/g, '/');
8
+ const nodes = db.queries.getNodesByFile(normalized);
9
+ if (nodes.length === 0) {
10
+ return {
11
+ content: [{
12
+ type: 'text',
13
+ text: JSON.stringify({ error: `No indexed data for file "${normalized}". Try clast_reindex first.` }),
14
+ }],
15
+ };
16
+ }
17
+ // Group by type
18
+ const grouped = {};
19
+ for (const node of nodes) {
20
+ const group = grouped[node.type] ??= [];
21
+ group.push({
22
+ name: node.name,
23
+ signature: node.signature,
24
+ startLine: node.start_line,
25
+ endLine: node.end_line,
26
+ });
27
+ }
28
+ const summary = {
29
+ filePath: normalized,
30
+ language: nodes[0]?.language,
31
+ totalSymbols: nodes.length,
32
+ symbols: grouped,
33
+ };
34
+ return {
35
+ content: [{
36
+ type: 'text',
37
+ text: JSON.stringify(summary, null, 2),
38
+ }],
39
+ };
40
+ });
41
+ }
42
+ //# sourceMappingURL=clast-file-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clast-file-summary.js","sourceRoot":"","sources":["../../../src/server/tools/clast-file-summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,uBAAuB,CAAC,MAAiB,EAAE,EAAiB;IAC1E,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,qLAAqL,EACrL;QACE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kEAAkE,CAAC;KAClG,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QACrB,iBAAiB;QACjB,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QAEpD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,6BAA6B,UAAU,6BAA6B,EAAE,CAAC;qBACtG,CAAC;aACH,CAAC;QACJ,CAAC;QAED,gBAAgB;QAChB,MAAM,OAAO,GAKP,EAAE,CAAC;QAET,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,SAAS,EAAE,IAAI,CAAC,UAAU;gBAC1B,OAAO,EAAE,IAAI,CAAC,QAAQ;aACvB,CAAC,CAAC;QACL,CAAC;QAED,MAAM,OAAO,GAAG;YACd,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ;YAC5B,YAAY,EAAE,KAAK,CAAC,MAAM;YAC1B,OAAO,EAAE,OAAO;SACjB,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;iBACvC,CAAC;SACH,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,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 registerGetContextTool(server: McpServer, db: ClastDatabase): void;
4
+ //# sourceMappingURL=clast-get-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clast-get-context.d.ts","sourceRoot":"","sources":["../../../src/server/tools/clast-get-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,aAAa,GAAG,IAAI,CA4FjF"}
@@ -0,0 +1,80 @@
1
+ import { z } from 'zod';
2
+ export function registerGetContextTool(server, db) {
3
+ server.tool('clast_get_context', 'Get full context for a symbol: its definition, comments/documentation, callers, callees, and parent class (if method). This is the primary tool for understanding a symbol before editing — use instead of reading the whole file.', {
4
+ name: z.string().describe('Symbol name to look up'),
5
+ includeBody: z.boolean().default(false).describe('Include the full function/class body text'),
6
+ }, async ({ name, includeBody }) => {
7
+ const ctx = db.queries.getNodeWithContext(name);
8
+ if (ctx.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 result = ctx.nodes.map(node => {
17
+ const nodeComments = ctx.comments.filter(c => c.node_id === node.id);
18
+ const entry = {
19
+ name: node.name,
20
+ type: node.type,
21
+ filePath: node.file_path,
22
+ location: `${node.file_path}:${node.start_line}-${node.end_line}`,
23
+ signature: node.signature,
24
+ language: node.language,
25
+ };
26
+ if (includeBody) {
27
+ entry.body = node.body_text;
28
+ }
29
+ // Comments: prioritize original, also show generated
30
+ const originalComment = nodeComments.find(c => c.source === 'original');
31
+ const generatedComment = nodeComments.find(c => c.source === 'generated');
32
+ if (originalComment) {
33
+ entry.comment = originalComment.text;
34
+ entry.commentSource = 'original';
35
+ }
36
+ if (generatedComment) {
37
+ entry.generatedDescription = generatedComment.text;
38
+ }
39
+ // Parent (for methods inside classes)
40
+ if (node.parent_id) {
41
+ const parent = db.queries.getNodeById(node.parent_id);
42
+ if (parent) {
43
+ entry.parentClass = {
44
+ name: parent.name,
45
+ type: parent.type,
46
+ filePath: parent.file_path,
47
+ startLine: parent.start_line,
48
+ };
49
+ }
50
+ }
51
+ return entry;
52
+ });
53
+ // Callers and callees (deduplicated across all matching nodes)
54
+ const callers = ctx.callers.map(n => ({
55
+ name: n.name,
56
+ type: n.type,
57
+ filePath: n.file_path,
58
+ startLine: n.start_line,
59
+ signature: n.signature,
60
+ }));
61
+ const callees = ctx.callees.map(n => ({
62
+ name: n.name,
63
+ type: n.type,
64
+ filePath: n.file_path,
65
+ startLine: n.start_line,
66
+ signature: n.signature,
67
+ }));
68
+ return {
69
+ content: [{
70
+ type: 'text',
71
+ text: JSON.stringify({
72
+ definitions: result,
73
+ callers,
74
+ callees,
75
+ }, null, 2),
76
+ }],
77
+ };
78
+ });
79
+ }
80
+ //# sourceMappingURL=clast-get-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clast-get-context.js","sourceRoot":"","sources":["../../../src/server/tools/clast-get-context.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 { ParserManager } from '../../parser/index.js';
4
+ export declare function registerReindexTool(server: McpServer, db: ClastDatabase, parser: ParserManager, projectRoot: string): void;
5
+ //# sourceMappingURL=clast-reindex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clast-reindex.d.ts","sourceRoot":"","sources":["../../../src/server/tools/clast-reindex.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,EAAE,EAAE,aAAa,EACjB,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,MAAM,GAClB,IAAI,CAwCN"}
@@ -0,0 +1,36 @@
1
+ import { z } from 'zod';
2
+ import { join } from 'node:path';
3
+ export function registerReindexTool(server, db, parser, projectRoot) {
4
+ server.tool('clast_reindex', 'Force re-index a specific file or the entire repository. Use when the index seems stale or after large changes.', {
5
+ filePath: z.string().optional().describe('Specific file to reindex (relative path). Omit to reindex the entire repo.'),
6
+ }, async ({ filePath }) => {
7
+ if (filePath) {
8
+ const absPath = join(projectRoot, filePath);
9
+ const parsed = await parser.incrementalUpdate(absPath, projectRoot, db);
10
+ return {
11
+ content: [{
12
+ type: 'text',
13
+ text: JSON.stringify({
14
+ file: filePath,
15
+ reindexed: parsed,
16
+ message: parsed ? 'File reindexed successfully' : 'File unchanged or unsupported',
17
+ }),
18
+ }],
19
+ };
20
+ }
21
+ const result = await parser.fullIndex(projectRoot, db);
22
+ return {
23
+ content: [{
24
+ type: 'text',
25
+ text: JSON.stringify({
26
+ filesProcessed: result.filesProcessed,
27
+ nodesFound: result.nodesFound,
28
+ edgesResolved: result.edgesResolved,
29
+ durationMs: result.durationMs,
30
+ message: `Full reindex completed in ${result.durationMs}ms`,
31
+ }),
32
+ }],
33
+ };
34
+ });
35
+ }
36
+ //# sourceMappingURL=clast-reindex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clast-reindex.js","sourceRoot":"","sources":["../../../src/server/tools/clast-reindex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAKjC,MAAM,UAAU,mBAAmB,CACjC,MAAiB,EACjB,EAAiB,EACjB,MAAqB,EACrB,WAAmB;IAEnB,MAAM,CAAC,IAAI,CACT,eAAe,EACf,iHAAiH,EACjH;QACE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4EAA4E,CAAC;KACvH,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QACrB,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;YAExE,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;4BACnB,IAAI,EAAE,QAAQ;4BACd,SAAS,EAAE,MAAM;4BACjB,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,+BAA+B;yBAClF,CAAC;qBACH,CAAC;aACH,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAEvD,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,cAAc,EAAE,MAAM,CAAC,cAAc;wBACrC,UAAU,EAAE,MAAM,CAAC,UAAU;wBAC7B,aAAa,EAAE,MAAM,CAAC,aAAa;wBACnC,UAAU,EAAE,MAAM,CAAC,UAAU;wBAC7B,OAAO,EAAE,6BAA6B,MAAM,CAAC,UAAU,IAAI;qBAC5D,CAAC;iBACH,CAAC;SACH,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,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 registerSearchTool(server: McpServer, db: ClastDatabase): void;
4
+ //# sourceMappingURL=clast-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clast-search.d.ts","sourceRoot":"","sources":["../../../src/server/tools/clast-search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,aAAa,GAAG,IAAI,CAiC7E"}
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod';
2
+ export function registerSearchTool(server, db) {
3
+ server.tool('clast_search', 'Search AST nodes (functions, classes, methods, etc.) by name pattern and optional type filter. Returns matching symbols with file locations and signatures.', {
4
+ query: z.string().describe('Search pattern (matches against symbol names, supports partial matches)'),
5
+ type: z.enum([
6
+ 'function', 'method', 'class', 'interface', 'enum',
7
+ 'import', 'export', 'variable', 'type_alias', 'struct', 'trait', 'module',
8
+ ]).optional().describe('Filter by symbol type'),
9
+ limit: z.number().int().min(1).max(100).default(20).describe('Maximum results to return'),
10
+ }, async ({ query, type, limit }) => {
11
+ const results = db.queries.searchNodes(query, type, limit);
12
+ const formatted = results.map(n => ({
13
+ name: n.name,
14
+ type: n.type,
15
+ filePath: n.file_path,
16
+ startLine: n.start_line,
17
+ endLine: n.end_line,
18
+ signature: n.signature,
19
+ language: n.language,
20
+ }));
21
+ return {
22
+ content: [{
23
+ type: 'text',
24
+ text: JSON.stringify(formatted, null, 2),
25
+ }],
26
+ };
27
+ });
28
+ }
29
+ //# sourceMappingURL=clast-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clast-search.js","sourceRoot":"","sources":["../../../src/server/tools/clast-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,EAAiB;IACrE,MAAM,CAAC,IAAI,CACT,cAAc,EACd,6JAA6J,EAC7J;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yEAAyE,CAAC;QACrG,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;YACX,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM;YAClD,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ;SAC1E,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QAC/C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,2BAA2B,CAAC;KAC1F,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;QAC/B,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAE3D,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,QAAQ,EAAE,CAAC,CAAC,SAAS;YACrB,SAAS,EAAE,CAAC,CAAC,UAAU;YACvB,OAAO,EAAE,CAAC,CAAC,QAAQ;YACnB,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,QAAQ,EAAE,CAAC,CAAC,QAAQ;SACrB,CAAC,CAAC,CAAC;QAEJ,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;iBACzC,CAAC;SACH,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -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 { FileWatcher } from '../../watcher/index.js';
4
+ export declare function registerStatusTool(server: McpServer, db: ClastDatabase, watcher: FileWatcher): void;
5
+ //# sourceMappingURL=clast-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clast-status.d.ts","sourceRoot":"","sources":["../../../src/server/tools/clast-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,EACjB,EAAE,EAAE,aAAa,EACjB,OAAO,EAAE,WAAW,GACnB,IAAI,CA4BN"}
@@ -0,0 +1,23 @@
1
+ export function registerStatusTool(server, db, watcher) {
2
+ server.tool('clast_status', 'Show the current indexing status: files indexed, total symbols, total call edges, watcher state, and pending updates.', {}, async () => {
3
+ const status = db.queries.getStatus();
4
+ const result = {
5
+ filesIndexed: status.files_indexed,
6
+ totalNodes: status.total_nodes,
7
+ totalEdges: status.total_edges,
8
+ totalComments: status.total_comments,
9
+ lastIndexed: status.last_indexed
10
+ ? new Date(status.last_indexed).toISOString()
11
+ : null,
12
+ watcherActive: watcher.isActive,
13
+ pendingFiles: watcher.pendingCount,
14
+ };
15
+ return {
16
+ content: [{
17
+ type: 'text',
18
+ text: JSON.stringify(result, null, 2),
19
+ }],
20
+ };
21
+ });
22
+ }
23
+ //# sourceMappingURL=clast-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clast-status.js","sourceRoot":"","sources":["../../../src/server/tools/clast-status.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,kBAAkB,CAChC,MAAiB,EACjB,EAAiB,EACjB,OAAoB;IAEpB,MAAM,CAAC,IAAI,CACT,cAAc,EACd,uHAAuH,EACvH,EAAE,EACF,KAAK,IAAI,EAAE;QACT,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QAEtC,MAAM,MAAM,GAAG;YACb,YAAY,EAAE,MAAM,CAAC,aAAa;YAClC,UAAU,EAAE,MAAM,CAAC,WAAW;YAC9B,UAAU,EAAE,MAAM,CAAC,WAAW;YAC9B,aAAa,EAAE,MAAM,CAAC,cAAc;YACpC,WAAW,EAAE,MAAM,CAAC,YAAY;gBAC9B,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE;gBAC7C,CAAC,CAAC,IAAI;YACR,aAAa,EAAE,OAAO,CAAC,QAAQ;YAC/B,YAAY,EAAE,OAAO,CAAC,YAAY;SACnC,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;iBACtC,CAAC;SACH,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,52 @@
1
+ export type AstNodeType = 'function' | 'method' | 'class' | 'interface' | 'enum' | 'import' | 'export' | 'variable' | 'type_alias' | 'struct' | 'trait' | 'module';
2
+ export interface AstNode {
3
+ id?: number;
4
+ filePath: string;
5
+ name: string;
6
+ type: AstNodeType;
7
+ signature: string;
8
+ startLine: number;
9
+ endLine: number;
10
+ startCol: number;
11
+ endCol: number;
12
+ parentId: number | null;
13
+ language: string;
14
+ bodyText: string;
15
+ }
16
+ export interface CallEdge {
17
+ id?: number;
18
+ callerId: number;
19
+ calleeId: number | null;
20
+ calleeName: string;
21
+ filePath: string;
22
+ line: number;
23
+ }
24
+ export interface FileInfo {
25
+ filePath: string;
26
+ hash: string;
27
+ language: string;
28
+ lastIndexed: number;
29
+ nodeCount: number;
30
+ }
31
+ export interface CommentInfo {
32
+ id?: number;
33
+ nodeId: number;
34
+ text: string;
35
+ source: 'original' | 'generated';
36
+ generatedAt: number | null;
37
+ }
38
+ export interface ParseResult {
39
+ nodes: AstNode[];
40
+ edges: CallEdge[];
41
+ comments: CommentInfo[];
42
+ }
43
+ export interface IndexStatus {
44
+ filesIndexed: number;
45
+ totalNodes: number;
46
+ totalEdges: number;
47
+ totalComments: number;
48
+ lastIndexed: number | null;
49
+ watcherActive: boolean;
50
+ pendingFiles: number;
51
+ }
52
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GACnB,UAAU,GACV,QAAQ,GACR,OAAO,GACP,WAAW,GACX,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,YAAY,GACZ,QAAQ,GACR,OAAO,GACP,QAAQ,CAAC;AAEb,MAAM,WAAW,OAAO;IACtB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,GAAG,WAAW,CAAC;IACjC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Parse .gitignore files into glob patterns suitable for chokidar's `ignored` option.
3
+ */
4
+ export declare function loadGitignorePatterns(projectRoot: string): string[];
5
+ /**
6
+ * Build the full ignored patterns list combining .gitignore and config.
7
+ */
8
+ export declare function buildIgnorePatterns(projectRoot: string, configIgnored: string[]): string[];
9
+ //# sourceMappingURL=gitignore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitignore.d.ts","sourceRoot":"","sources":["../../src/watcher/gitignore.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAsBnE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EAAE,GACtB,MAAM,EAAE,CAKV"}
@@ -0,0 +1,38 @@
1
+ import { readFileSync, existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ /**
4
+ * Parse .gitignore files into glob patterns suitable for chokidar's `ignored` option.
5
+ */
6
+ export function loadGitignorePatterns(projectRoot) {
7
+ const patterns = [];
8
+ const gitignorePath = join(projectRoot, '.gitignore');
9
+ if (!existsSync(gitignorePath))
10
+ return patterns;
11
+ try {
12
+ const content = readFileSync(gitignorePath, 'utf-8');
13
+ for (const line of content.split('\n')) {
14
+ const trimmed = line.trim();
15
+ // Skip comments and empty lines
16
+ if (!trimmed || trimmed.startsWith('#'))
17
+ continue;
18
+ // Negation patterns are not supported by chokidar's simple ignored
19
+ if (trimmed.startsWith('!'))
20
+ continue;
21
+ patterns.push(trimmed);
22
+ }
23
+ }
24
+ catch {
25
+ // Silently ignore read errors
26
+ }
27
+ return patterns;
28
+ }
29
+ /**
30
+ * Build the full ignored patterns list combining .gitignore and config.
31
+ */
32
+ export function buildIgnorePatterns(projectRoot, configIgnored) {
33
+ const gitignorePatterns = loadGitignorePatterns(projectRoot);
34
+ // Deduplicate
35
+ const all = new Set([...configIgnored, ...gitignorePatterns]);
36
+ return Array.from(all);
37
+ }
38
+ //# sourceMappingURL=gitignore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitignore.js","sourceRoot":"","sources":["../../src/watcher/gitignore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,WAAmB;IACvD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAEtD,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;QAAE,OAAO,QAAQ,CAAC;IAEhD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QACrD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,gCAAgC;YAChC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YAClD,mEAAmE;YACnE,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YAEtC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;IAChC,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,WAAmB,EACnB,aAAuB;IAEvB,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAAC;IAC7D,cAAc;IACd,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,aAAa,EAAE,GAAG,iBAAiB,CAAC,CAAC,CAAC;IAC9D,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { ParserManager } from '../parser/index.js';
3
+ import type { ClastDatabase } from '../db/index.js';
4
+ import type { ClastConfig } from '../config/index.js';
5
+ export declare class FileWatcher extends EventEmitter {
6
+ private watcher;
7
+ private projectRoot;
8
+ private config;
9
+ private db;
10
+ private parser;
11
+ private debounceTimers;
12
+ private _pendingCount;
13
+ private supportedExts;
14
+ constructor(projectRoot: string, config: ClastConfig, db: ClastDatabase, parser: ParserManager);
15
+ get isActive(): boolean;
16
+ get pendingCount(): number;
17
+ start(): void;
18
+ stop(): void;
19
+ private handleFileChange;
20
+ private handleFileDelete;
21
+ private processFile;
22
+ }
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,EAAE,CAAgB;IAC1B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,cAAc,CAAoD;IAC1E,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,aAAa,CAAc;gBAGjC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,EACnB,EAAE,EAAE,aAAa,EACjB,MAAM,EAAE,aAAa;IAUvB,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,KAAK,IAAI,IAAI;IA4Bb,IAAI,IAAI,IAAI;IAYZ,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,gBAAgB;YAmBV,WAAW;CAY1B"}
@@ -0,0 +1,111 @@
1
+ import { watch } from 'chokidar';
2
+ import { extname } from 'node:path';
3
+ import { EventEmitter } from 'node:events';
4
+ import { getSupportedExtensions } from '../parser/languages.js';
5
+ import { buildIgnorePatterns } from './gitignore.js';
6
+ export class FileWatcher extends EventEmitter {
7
+ watcher = null;
8
+ projectRoot;
9
+ config;
10
+ db;
11
+ parser;
12
+ debounceTimers = new Map();
13
+ _pendingCount = 0;
14
+ supportedExts;
15
+ constructor(projectRoot, config, db, parser) {
16
+ super();
17
+ this.projectRoot = projectRoot;
18
+ this.config = config;
19
+ this.db = db;
20
+ this.parser = parser;
21
+ this.supportedExts = new Set(getSupportedExtensions(config.languages));
22
+ }
23
+ get isActive() {
24
+ return this.watcher !== null;
25
+ }
26
+ get pendingCount() {
27
+ return this._pendingCount;
28
+ }
29
+ start() {
30
+ if (this.watcher)
31
+ return;
32
+ if (!this.config.watch.enabled)
33
+ return;
34
+ const ignoredPatterns = buildIgnorePatterns(this.projectRoot, this.config.ignoredPaths);
35
+ this.watcher = watch(this.projectRoot, {
36
+ ignored: [
37
+ /(^|[/\\])\./,
38
+ ...ignoredPatterns.map(p => {
39
+ if (!p.includes('*') && !p.includes('/')) {
40
+ return `**/${p}/**`;
41
+ }
42
+ return p;
43
+ }),
44
+ ],
45
+ persistent: true,
46
+ ignoreInitial: true,
47
+ });
48
+ this.watcher.on('add', path => this.handleFileChange(path));
49
+ this.watcher.on('change', path => this.handleFileChange(path));
50
+ this.watcher.on('unlink', path => this.handleFileDelete(path));
51
+ this.watcher.on('error', err => {
52
+ console.error('[clast] Watcher error:', err);
53
+ });
54
+ }
55
+ stop() {
56
+ if (!this.watcher)
57
+ return;
58
+ for (const timer of this.debounceTimers.values()) {
59
+ clearTimeout(timer);
60
+ }
61
+ this.debounceTimers.clear();
62
+ this.watcher.close();
63
+ this.watcher = null;
64
+ }
65
+ handleFileChange(filePath) {
66
+ const ext = extname(filePath);
67
+ if (!this.supportedExts.has(ext))
68
+ return;
69
+ const existing = this.debounceTimers.get(filePath);
70
+ if (existing)
71
+ clearTimeout(existing);
72
+ this._pendingCount++;
73
+ this.debounceTimers.set(filePath, setTimeout(() => {
74
+ this.debounceTimers.delete(filePath);
75
+ this._pendingCount--;
76
+ this.processFile(filePath);
77
+ }, this.config.watch.debounceMs));
78
+ }
79
+ handleFileDelete(filePath) {
80
+ const ext = extname(filePath);
81
+ if (!this.supportedExts.has(ext))
82
+ return;
83
+ const existing = this.debounceTimers.get(filePath);
84
+ if (existing) {
85
+ clearTimeout(existing);
86
+ this.debounceTimers.delete(filePath);
87
+ this._pendingCount--;
88
+ }
89
+ try {
90
+ this.parser.removeFile(filePath, this.projectRoot, this.db);
91
+ this.emit('deleted', { filePath });
92
+ }
93
+ catch (err) {
94
+ this.emit('error', { filePath, error: err });
95
+ }
96
+ }
97
+ async processFile(filePath) {
98
+ try {
99
+ const parsed = await this.parser.incrementalUpdate(filePath, this.projectRoot, this.db);
100
+ if (parsed) {
101
+ const relPath = filePath.replace(/\\/g, '/');
102
+ const nodes = this.db.queries.getNodesByFile(relPath);
103
+ this.emit('indexed', { filePath, nodesFound: nodes.length });
104
+ }
105
+ }
106
+ catch (err) {
107
+ this.emit('error', { filePath, error: err });
108
+ }
109
+ }
110
+ }
111
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "clast-ai",
3
+ "version": "0.1.0",
4
+ "description": "AST-based code intelligence plugin for Claude Code: search symbols, trace call graphs, generate comments, and provide structured context for any repository",
5
+ "main": "dist/server/index.js",
6
+ "bin": {
7
+ "clast-ai": "dist/server/index.js"
8
+ },
9
+ "type": "module",
10
+ "scripts": {
11
+ "build": "tsc -p tsconfig.json",
12
+ "start": "node dist/server/index.js",
13
+ "dev": "tsx src/server/index.ts",
14
+ "test": "vitest run",
15
+ "test:watch": "vitest",
16
+ "clean": "rm -rf dist",
17
+ "prepare": "npm run build",
18
+ "prepublishOnly": "npm run build"
19
+ },
20
+ "keywords": [
21
+ "ast",
22
+ "code-intelligence",
23
+ "call-graph",
24
+ "tree-sitter",
25
+ "mcp",
26
+ "claude-code",
27
+ "plugin"
28
+ ],
29
+ "author": "trizos",
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/xls/clast.git"
34
+ },
35
+ "files": [
36
+ "dist",
37
+ "src",
38
+ "skills",
39
+ "commands",
40
+ ".claude-plugin",
41
+ ".mcp.json",
42
+ "tsconfig.json",
43
+ "README.md",
44
+ "LICENSE"
45
+ ],
46
+ "engines": {
47
+ "node": ">=18.0.0"
48
+ },
49
+ "dependencies": {
50
+ "@anthropic-ai/sdk": "^0.39.0",
51
+ "@modelcontextprotocol/sdk": "^1.12.0",
52
+ "chokidar": "^4.0.0",
53
+ "sql.js": "^1.12.0",
54
+ "tree-sitter-wasms": "^0.1.13",
55
+ "web-tree-sitter": "^0.24.7",
56
+ "zod": "^3.24.0"
57
+ },
58
+ "devDependencies": {
59
+ "@types/node": "^22.0.0",
60
+ "@types/sql.js": "^1.4.11",
61
+ "tsx": "^4.19.0",
62
+ "typescript": "^5.7.0",
63
+ "vitest": "^3.0.0"
64
+ }
65
+ }