genifyai 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 (78) hide show
  1. package/README.md +156 -0
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +229 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/parsers/cache.d.ts +9 -0
  7. package/dist/parsers/cache.d.ts.map +1 -0
  8. package/dist/parsers/cache.js +51 -0
  9. package/dist/parsers/cache.js.map +1 -0
  10. package/dist/parsers/css.d.ts +5 -0
  11. package/dist/parsers/css.d.ts.map +1 -0
  12. package/dist/parsers/css.js +122 -0
  13. package/dist/parsers/css.js.map +1 -0
  14. package/dist/parsers/exportResolver.d.ts +12 -0
  15. package/dist/parsers/exportResolver.d.ts.map +1 -0
  16. package/dist/parsers/exportResolver.js +113 -0
  17. package/dist/parsers/exportResolver.js.map +1 -0
  18. package/dist/parsers/html.d.ts +5 -0
  19. package/dist/parsers/html.d.ts.map +1 -0
  20. package/dist/parsers/html.js +124 -0
  21. package/dist/parsers/html.js.map +1 -0
  22. package/dist/parsers/index.d.ts +10 -0
  23. package/dist/parsers/index.d.ts.map +1 -0
  24. package/dist/parsers/index.js +22 -0
  25. package/dist/parsers/index.js.map +1 -0
  26. package/dist/parsers/registry.d.ts +6 -0
  27. package/dist/parsers/registry.d.ts.map +1 -0
  28. package/dist/parsers/registry.js +18 -0
  29. package/dist/parsers/registry.js.map +1 -0
  30. package/dist/parsers/solidity.d.ts +5 -0
  31. package/dist/parsers/solidity.d.ts.map +1 -0
  32. package/dist/parsers/solidity.js +123 -0
  33. package/dist/parsers/solidity.js.map +1 -0
  34. package/dist/parsers/types.d.ts +37 -0
  35. package/dist/parsers/types.d.ts.map +1 -0
  36. package/dist/parsers/types.js +2 -0
  37. package/dist/parsers/types.js.map +1 -0
  38. package/dist/parsers/typescript.d.ts +5 -0
  39. package/dist/parsers/typescript.d.ts.map +1 -0
  40. package/dist/parsers/typescript.js +264 -0
  41. package/dist/parsers/typescript.js.map +1 -0
  42. package/dist/search/glob.d.ts +2 -0
  43. package/dist/search/glob.d.ts.map +1 -0
  44. package/dist/search/glob.js +49 -0
  45. package/dist/search/glob.js.map +1 -0
  46. package/dist/search/ripgrep.d.ts +15 -0
  47. package/dist/search/ripgrep.d.ts.map +1 -0
  48. package/dist/search/ripgrep.js +66 -0
  49. package/dist/search/ripgrep.js.map +1 -0
  50. package/dist/tools/readRange.d.ts +21 -0
  51. package/dist/tools/readRange.d.ts.map +1 -0
  52. package/dist/tools/readRange.js +37 -0
  53. package/dist/tools/readRange.js.map +1 -0
  54. package/dist/tools/registerAlias.d.ts +27 -0
  55. package/dist/tools/registerAlias.d.ts.map +1 -0
  56. package/dist/tools/registerAlias.js +68 -0
  57. package/dist/tools/registerAlias.js.map +1 -0
  58. package/dist/tools/searchFuzzy.d.ts +25 -0
  59. package/dist/tools/searchFuzzy.d.ts.map +1 -0
  60. package/dist/tools/searchFuzzy.js +178 -0
  61. package/dist/tools/searchFuzzy.js.map +1 -0
  62. package/dist/tools/searchSymbol.d.ts +24 -0
  63. package/dist/tools/searchSymbol.d.ts.map +1 -0
  64. package/dist/tools/searchSymbol.js +95 -0
  65. package/dist/tools/searchSymbol.js.map +1 -0
  66. package/dist/utils/fileReader.d.ts +16 -0
  67. package/dist/utils/fileReader.d.ts.map +1 -0
  68. package/dist/utils/fileReader.js +45 -0
  69. package/dist/utils/fileReader.js.map +1 -0
  70. package/dist/utils/ignore.d.ts +4 -0
  71. package/dist/utils/ignore.d.ts.map +1 -0
  72. package/dist/utils/ignore.js +80 -0
  73. package/dist/utils/ignore.js.map +1 -0
  74. package/dist/utils/pathResolver.d.ts +7 -0
  75. package/dist/utils/pathResolver.d.ts.map +1 -0
  76. package/dist/utils/pathResolver.js +31 -0
  77. package/dist/utils/pathResolver.js.map +1 -0
  78. package/package.json +61 -0
package/README.md ADDED
@@ -0,0 +1,156 @@
1
+ # Genify
2
+
3
+ 一个基于 MCP(Model Context Protocol)的本地代码检索/定位服务:用 ripgrep 做粗筛,用 Tree-sitter(AST)做定义级精筛,向 MCP 客户端提供可调用的工具,从而让"找代码位置/读上下文"更稳定、更可复用。
4
+
5
+ ## 能做什么
6
+
7
+ - `search_symbol`:按符号定义搜索(function/class/interface/type/enum/const/let/var/组件/方法等),返回精确位置与签名,支持自动跟随导出链路。
8
+ - `read_range`:按行号范围读取文件片段(1-based,包含 endLine)。
9
+ - `search_fuzzy`:自然语言/关键词/别名的多路召回(别名命中、定义召回、文件名召回、文本命中),返回候选与打分原因。
10
+ - `register_alias`:把自然语言称呼映射到代码位置,便于长期稳定命中。
11
+
12
+ ## 支持的语言
13
+
14
+ | 语言 | 扩展名 | 符号类型 |
15
+ |------|--------|----------|
16
+ | TypeScript/JavaScript | `.ts` `.tsx` `.js` `.jsx` | function, class, interface, type, enum, const, let, var, function_component, method, getter, setter |
17
+ | Solidity | `.sol` | contract, library, sol_interface, struct, event, modifier, error, function, enum |
18
+ | HTML | `.html` `.htm` | element (#id), component (web components) |
19
+ | CSS/Less/Sass | `.css` `.less` `.sass` `.scss` | selector (.class/#id), variable (--custom-prop), keyframes |
20
+
21
+ 默认忽略 `node_modules/dist/build/.git` 等目录。
22
+
23
+ ## 特性
24
+
25
+ - **多语言支持**:TypeScript/JavaScript、Solidity、HTML、CSS/Less/Sass
26
+ - **导出链路跟随**:自动解析 `export { } from`、`export * from`、`export default`,找到原始定义位置(仅 TS/JS)
27
+ - **AST 解析缓存**:基于文件 mtime 的智能缓存,避免重复解析
28
+ - **智能忽略规则**:自动读取 `.gitignore`,无需额外配置
29
+
30
+ ## 依赖
31
+
32
+ - Node.js `>= 18`
33
+ - 包管理器:`pnpm`
34
+
35
+ ## 快速开始(本地运行)
36
+
37
+ ```bash
38
+ pnpm install
39
+ pnpm build
40
+ node dist/index.js
41
+ ```
42
+
43
+ 该服务使用 MCP stdio 传输;通常不需要你手动运行,而是由 MCP 客户端按配置拉起。
44
+
45
+ ## 作为 MCP Server 接入
46
+
47
+ Genify 的工作区根目录使用启动进程的 `cwd`(`process.cwd()`)。因此建议把 `cwd` 设置为你的项目根目录(或在客户端里把命令的工作目录指向项目根)。
48
+
49
+ 通用配置(支持 `command + args` 的 MCP 客户端都适用):
50
+
51
+ ```json
52
+ {
53
+ "mcpServers": {
54
+ "genify": {
55
+ "command": "node",
56
+ "args": ["<绝对路径>/Genify/dist/index.js"],
57
+ "env": {}
58
+ }
59
+ }
60
+ }
61
+ ```
62
+
63
+ 如果你把它发布/安装成可执行命令,也可以用:
64
+
65
+ ```json
66
+ {
67
+ "mcpServers": {
68
+ "genify": {
69
+ "command": "npx",
70
+ "args": ["-y", "genify"],
71
+ "env": {}
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ ## 工具说明
78
+
79
+ ### `search_symbol`
80
+
81
+ 按符号定义搜索(AST 精筛),自动跟随导出链路找到原始定义。
82
+
83
+ 输入:
84
+
85
+ ```json
86
+ { "query": "Header", "type": "function_component", "scope": "src", "limit": 20, "followExports": true }
87
+ ```
88
+
89
+ - `query`:符号名称
90
+ - `type`:可选,过滤符号类型
91
+ - `scope`:可选,搜索范围(相对路径)
92
+ - `limit`:可选,返回数量(默认 20)
93
+ - `followExports`:可选,是否跟随导出链路(默认 true)
94
+
95
+ 输出(示例):
96
+
97
+ ```json
98
+ [
99
+ {
100
+ "name": "Header",
101
+ "kind": "function_component",
102
+ "file": "src/components/Header.tsx",
103
+ "location": { "startLine": 10, "endLine": 85, "startCol": 0, "endCol": 1 },
104
+ "range": "[10:85]",
105
+ "signature": "export const Header = (...) =>",
106
+ "language": "tsx"
107
+ }
108
+ ]
109
+ ```
110
+
111
+ ### `read_range`
112
+
113
+ 按行号范围读取片段(`"[start:end]"`,1-based,包含 end)。
114
+
115
+ 输入:
116
+
117
+ ```json
118
+ { "filePath": "src/index.ts", "range": "[1:80]", "surround": 0 }
119
+ ```
120
+
121
+ ### `register_alias`
122
+
123
+ 把"自然语言称呼"绑定到代码目标上(目标格式:`relativePath#SymbolName` 或 `relativePath`)。
124
+
125
+ 输入:
126
+
127
+ ```json
128
+ { "term": "反转卡片", "target": "src/components/FlipCard.tsx#FlipCard" }
129
+ ```
130
+
131
+ 别名存储位置(项目内本地状态):`.genify/aliases.json`
132
+
133
+ ### `search_fuzzy`
134
+
135
+ 面向自然语言/别名/关键词的多路召回,返回候选、分数与原因。
136
+
137
+ 输入:
138
+
139
+ ```json
140
+ { "query": "反转卡片", "scope": "src", "limit": 20 }
141
+ ```
142
+
143
+ 输出字段:
144
+
145
+ - `file`:相对工作区路径
146
+ - `range`:建议读取范围
147
+ - `symbol/kind`:可选,命中定义时给出
148
+ - `score`:0~1
149
+ - `reasons`:召回/排序原因(如 `alias_hit`、`definition_match`、`filename_match`、`text_hit`)
150
+
151
+ ## 开发
152
+
153
+ ```bash
154
+ pnpm dev # watch 模式编译
155
+ pnpm build # 编译
156
+ ```
@@ -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/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,229 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
+ import { searchSymbol, searchSymbolSchema } from './tools/searchSymbol.js';
6
+ import { readRange, readRangeSchema } from './tools/readRange.js';
7
+ import { registerAlias, registerAliasSchema } from './tools/registerAlias.js';
8
+ import { searchFuzzy, searchFuzzySchema } from './tools/searchFuzzy.js';
9
+ import { setWorkspaceRoot } from './utils/pathResolver.js';
10
+ const server = new Server({
11
+ name: 'genify',
12
+ version: '0.1.0',
13
+ }, {
14
+ capabilities: {
15
+ tools: {},
16
+ },
17
+ });
18
+ // 列出可用工具
19
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
20
+ return {
21
+ tools: [
22
+ {
23
+ name: 'search_symbol',
24
+ description: 'Search for symbol definitions (function, class, interface, type, enum, const, etc.) in the codebase. Returns precise locations using AST parsing.',
25
+ inputSchema: {
26
+ type: 'object',
27
+ properties: {
28
+ query: {
29
+ type: 'string',
30
+ description: 'Symbol name to search for',
31
+ },
32
+ type: {
33
+ type: 'string',
34
+ enum: [
35
+ 'function',
36
+ 'class',
37
+ 'interface',
38
+ 'type',
39
+ 'enum',
40
+ 'const',
41
+ 'let',
42
+ 'var',
43
+ 'function_component',
44
+ 'method',
45
+ 'getter',
46
+ 'setter',
47
+ ],
48
+ description: 'Optional filter by symbol type',
49
+ },
50
+ scope: {
51
+ type: 'string',
52
+ description: 'Search scope (directory path relative to workspace)',
53
+ },
54
+ limit: {
55
+ type: 'number',
56
+ description: 'Maximum number of results (default: 20)',
57
+ },
58
+ },
59
+ required: ['query'],
60
+ },
61
+ },
62
+ {
63
+ name: 'read_range',
64
+ description: 'Read a specific line range from a file. Use this to examine code at locations returned by search_symbol.',
65
+ inputSchema: {
66
+ type: 'object',
67
+ properties: {
68
+ filePath: {
69
+ type: 'string',
70
+ description: 'File path relative to workspace root',
71
+ },
72
+ range: {
73
+ type: 'string',
74
+ description: 'Line range in format "[startLine:endLine]" (1-based, inclusive)',
75
+ pattern: '^\\[\\d+:\\d+\\]$',
76
+ },
77
+ surround: {
78
+ type: 'number',
79
+ description: 'Number of surrounding context lines (default: 0)',
80
+ },
81
+ },
82
+ required: ['filePath', 'range'],
83
+ },
84
+ },
85
+ {
86
+ name: 'register_alias',
87
+ description: 'Register an alias/nickname for a code location. Use this when natural language terms do not appear in code.',
88
+ inputSchema: {
89
+ type: 'object',
90
+ properties: {
91
+ term: {
92
+ type: 'string',
93
+ description: 'Alias or nickname (e.g., "flip card", "反转卡片")',
94
+ },
95
+ target: {
96
+ type: 'string',
97
+ description: 'Target in format "relativePath#SymbolName" or "relativePath"',
98
+ },
99
+ },
100
+ required: ['term', 'target'],
101
+ },
102
+ },
103
+ {
104
+ name: 'search_fuzzy',
105
+ description: 'Fuzzy search using natural language, aliases, or keywords. Returns ranked candidates with scores and reasons.',
106
+ inputSchema: {
107
+ type: 'object',
108
+ properties: {
109
+ query: {
110
+ type: 'string',
111
+ description: 'Natural language query, alias, or fuzzy keyword',
112
+ },
113
+ scope: {
114
+ type: 'string',
115
+ description: 'Search scope (directory path relative to workspace)',
116
+ },
117
+ limit: {
118
+ type: 'number',
119
+ description: 'Maximum number of results (default: 20)',
120
+ },
121
+ },
122
+ required: ['query'],
123
+ },
124
+ },
125
+ ],
126
+ };
127
+ });
128
+ // 处理工具调用
129
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
130
+ const { name, arguments: args } = request.params;
131
+ try {
132
+ switch (name) {
133
+ case 'search_symbol': {
134
+ const input = searchSymbolSchema.parse(args);
135
+ const results = await searchSymbol(input);
136
+ return {
137
+ content: [
138
+ {
139
+ type: 'text',
140
+ text: JSON.stringify(results, null, 2),
141
+ },
142
+ ],
143
+ };
144
+ }
145
+ case 'read_range': {
146
+ const input = readRangeSchema.parse(args);
147
+ const result = readRange(input);
148
+ if (!result) {
149
+ return {
150
+ content: [
151
+ {
152
+ type: 'text',
153
+ text: JSON.stringify({ error: 'Failed to read file or invalid range' }),
154
+ },
155
+ ],
156
+ isError: true,
157
+ };
158
+ }
159
+ return {
160
+ content: [
161
+ {
162
+ type: 'text',
163
+ text: JSON.stringify(result, null, 2),
164
+ },
165
+ ],
166
+ };
167
+ }
168
+ case 'register_alias': {
169
+ const input = registerAliasSchema.parse(args);
170
+ const result = registerAlias(input);
171
+ return {
172
+ content: [
173
+ {
174
+ type: 'text',
175
+ text: JSON.stringify(result, null, 2),
176
+ },
177
+ ],
178
+ };
179
+ }
180
+ case 'search_fuzzy': {
181
+ const input = searchFuzzySchema.parse(args);
182
+ const results = await searchFuzzy(input);
183
+ return {
184
+ content: [
185
+ {
186
+ type: 'text',
187
+ text: JSON.stringify(results, null, 2),
188
+ },
189
+ ],
190
+ };
191
+ }
192
+ default:
193
+ return {
194
+ content: [
195
+ {
196
+ type: 'text',
197
+ text: JSON.stringify({ error: `Unknown tool: ${name}` }),
198
+ },
199
+ ],
200
+ isError: true,
201
+ };
202
+ }
203
+ }
204
+ catch (err) {
205
+ const errorMessage = err instanceof Error ? err.message : String(err);
206
+ console.error(`[genify] Error in tool ${name}:`, errorMessage);
207
+ return {
208
+ content: [
209
+ {
210
+ type: 'text',
211
+ text: JSON.stringify({ error: errorMessage }),
212
+ },
213
+ ],
214
+ isError: true,
215
+ };
216
+ }
217
+ });
218
+ async function main() {
219
+ // 设置工作区根目录
220
+ setWorkspaceRoot(process.cwd());
221
+ const transport = new StdioServerTransport();
222
+ await server.connect(transport);
223
+ console.error('[genify] Server started');
224
+ }
225
+ main().catch((err) => {
226
+ console.error('[genify] Fatal error:', err);
227
+ process.exit(1);
228
+ });
229
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { ParseResult } from './types.js';
2
+ export declare function getCachedResult(filePath: string): ParseResult | null;
3
+ export declare function setCachedResult(filePath: string, result: ParseResult): void;
4
+ export declare function invalidateCache(filePath?: string): void;
5
+ export declare function getCacheStats(): {
6
+ size: number;
7
+ files: string[];
8
+ };
9
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/parsers/cache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAU9C,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAoBpE;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAW3E;AAED,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAMvD;AAED,wBAAgB,aAAa,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAKjE"}
@@ -0,0 +1,51 @@
1
+ import * as fs from 'node:fs';
2
+ import { toAbsolute } from '../utils/pathResolver.js';
3
+ const cache = new Map();
4
+ export function getCachedResult(filePath) {
5
+ const entry = cache.get(filePath);
6
+ if (!entry)
7
+ return null;
8
+ const absolutePath = toAbsolute(filePath);
9
+ try {
10
+ const stat = fs.statSync(absolutePath);
11
+ const currentMtime = stat.mtimeMs;
12
+ if (currentMtime === entry.mtime) {
13
+ return entry.result;
14
+ }
15
+ // mtime 变化,缓存失效
16
+ cache.delete(filePath);
17
+ return null;
18
+ }
19
+ catch {
20
+ cache.delete(filePath);
21
+ return null;
22
+ }
23
+ }
24
+ export function setCachedResult(filePath, result) {
25
+ const absolutePath = toAbsolute(filePath);
26
+ try {
27
+ const stat = fs.statSync(absolutePath);
28
+ cache.set(filePath, {
29
+ mtime: stat.mtimeMs,
30
+ result,
31
+ });
32
+ }
33
+ catch {
34
+ // 文件不存在,不缓存
35
+ }
36
+ }
37
+ export function invalidateCache(filePath) {
38
+ if (filePath) {
39
+ cache.delete(filePath);
40
+ }
41
+ else {
42
+ cache.clear();
43
+ }
44
+ }
45
+ export function getCacheStats() {
46
+ return {
47
+ size: cache.size,
48
+ files: Array.from(cache.keys()),
49
+ };
50
+ }
51
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/parsers/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAOtD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;AAE5C,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,YAAY,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QACvC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC;QAElC,IAAI,YAAY,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;YACjC,OAAO,KAAK,CAAC,MAAM,CAAC;QACtB,CAAC;QAED,gBAAgB;QAChB,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,MAAmB;IACnE,MAAM,YAAY,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QACvC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE;YAClB,KAAK,EAAE,IAAI,CAAC,OAAO;YACnB,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAiB;IAC/C,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;KAChC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { SymbolInfo, SymbolKind, ParseResult, LanguageParser } from './types.js';
2
+ export declare function parseFile(filePath: string): ParseResult;
3
+ export declare function parseFileForSymbol(filePath: string, query: string, type?: SymbolKind): SymbolInfo[];
4
+ export declare const cssParserInstance: LanguageParser;
5
+ //# sourceMappingURL=css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../../src/parsers/css.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAc,cAAc,EAAE,MAAM,YAAY,CAAC;AA2FlG,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CA4BvD;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,UAAU,GAChB,UAAU,EAAE,CAOd;AAED,eAAO,MAAM,iBAAiB,EAAE,cAK/B,CAAC"}
@@ -0,0 +1,122 @@
1
+ import Parser from 'tree-sitter';
2
+ import CSS from 'tree-sitter-css';
3
+ import { readFileContent, formatRange } from '../utils/fileReader.js';
4
+ import { getCachedResult, setCachedResult } from './cache.js';
5
+ import { registerParser } from './registry.js';
6
+ const cssParser = new Parser();
7
+ cssParser.setLanguage(CSS);
8
+ function extractSelectorName(node) {
9
+ // 提取选择器文本,清理空白
10
+ return node.text.replace(/\s+/g, ' ').trim();
11
+ }
12
+ function collectSymbols(node, filePath, sourceCode, symbols) {
13
+ // 规则集(选择器)
14
+ if (node.type === 'rule_set') {
15
+ const selectorsNode = node.childForFieldName('selectors') || node.namedChildren[0];
16
+ if (selectorsNode) {
17
+ const selectorText = extractSelectorName(selectorsNode);
18
+ // 只记录 class 和 id 选择器
19
+ if (selectorText.startsWith('.') || selectorText.startsWith('#')) {
20
+ symbols.push({
21
+ name: selectorText.split(/[,\s]/)[0], // 取第一个选择器
22
+ kind: 'selector',
23
+ file: filePath,
24
+ location: {
25
+ startLine: node.startPosition.row + 1,
26
+ endLine: node.endPosition.row + 1,
27
+ startCol: node.startPosition.column,
28
+ endCol: node.endPosition.column,
29
+ },
30
+ range: formatRange(node.startPosition.row + 1, node.endPosition.row + 1),
31
+ signature: selectorText.length > 60 ? selectorText.substring(0, 60) + '...' : selectorText,
32
+ language: 'css',
33
+ });
34
+ }
35
+ }
36
+ }
37
+ // @keyframes
38
+ if (node.type === 'keyframes_statement') {
39
+ const nameNode = node.childForFieldName('name') || node.namedChildren.find(c => c.type === 'keyframes_name');
40
+ if (nameNode) {
41
+ symbols.push({
42
+ name: nameNode.text,
43
+ kind: 'keyframes',
44
+ file: filePath,
45
+ location: {
46
+ startLine: node.startPosition.row + 1,
47
+ endLine: node.endPosition.row + 1,
48
+ startCol: node.startPosition.column,
49
+ endCol: node.endPosition.column,
50
+ },
51
+ range: formatRange(node.startPosition.row + 1, node.endPosition.row + 1),
52
+ signature: `@keyframes ${nameNode.text}`,
53
+ language: 'css',
54
+ });
55
+ }
56
+ }
57
+ // CSS 自定义属性(变量)在 :root 或其他地方声明
58
+ if (node.type === 'declaration') {
59
+ const propertyNode = node.childForFieldName('property') || node.namedChildren[0];
60
+ if (propertyNode && propertyNode.text.startsWith('--')) {
61
+ symbols.push({
62
+ name: propertyNode.text,
63
+ kind: 'variable',
64
+ file: filePath,
65
+ location: {
66
+ startLine: node.startPosition.row + 1,
67
+ endLine: node.endPosition.row + 1,
68
+ startCol: node.startPosition.column,
69
+ endCol: node.endPosition.column,
70
+ },
71
+ range: formatRange(node.startPosition.row + 1, node.endPosition.row + 1),
72
+ signature: node.text.length > 60 ? node.text.substring(0, 60) + '...' : node.text,
73
+ language: 'css',
74
+ });
75
+ }
76
+ }
77
+ for (const child of node.namedChildren) {
78
+ collectSymbols(child, filePath, sourceCode, symbols);
79
+ }
80
+ }
81
+ export function parseFile(filePath) {
82
+ const cached = getCachedResult(filePath);
83
+ if (cached) {
84
+ return cached;
85
+ }
86
+ const sourceCode = readFileContent(filePath);
87
+ if (!sourceCode) {
88
+ return { symbols: [], exports: [], errors: [`Failed to read file: ${filePath}`] };
89
+ }
90
+ try {
91
+ const tree = cssParser.parse(sourceCode);
92
+ const symbols = [];
93
+ const exports = [];
94
+ collectSymbols(tree.rootNode, filePath, sourceCode, symbols);
95
+ const result = { symbols, exports, errors: [] };
96
+ setCachedResult(filePath, result);
97
+ return result;
98
+ }
99
+ catch (err) {
100
+ return {
101
+ symbols: [],
102
+ exports: [],
103
+ errors: [`Failed to parse file: ${filePath} - ${err}`],
104
+ };
105
+ }
106
+ }
107
+ export function parseFileForSymbol(filePath, query, type) {
108
+ const { symbols } = parseFile(filePath);
109
+ return symbols.filter((s) => {
110
+ const nameMatch = s.name.toLowerCase().includes(query.toLowerCase());
111
+ const typeMatch = !type || s.kind === type;
112
+ return nameMatch && typeMatch;
113
+ });
114
+ }
115
+ export const cssParserInstance = {
116
+ language: 'css',
117
+ extensions: ['.css', '.less', '.sass', '.scss'],
118
+ parseFile,
119
+ parseFileForSymbol,
120
+ };
121
+ registerParser(cssParserInstance);
122
+ //# sourceMappingURL=css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css.js","sourceRoot":"","sources":["../../src/parsers/css.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,GAAG,MAAM,iBAAiB,CAAC;AAElC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,MAAM,SAAS,GAAG,IAAI,MAAM,EAAE,CAAC;AAC/B,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;AAE3B,SAAS,mBAAmB,CAAC,IAAuB;IAClD,eAAe;IACf,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAC/C,CAAC;AAED,SAAS,cAAc,CACrB,IAAuB,EACvB,QAAgB,EAChB,UAAkB,EAClB,OAAqB;IAErB,WAAW;IACX,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC7B,MAAM,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACnF,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,YAAY,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;YACxD,qBAAqB;YACrB,IAAI,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjE,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU;oBAChD,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,QAAQ;oBACd,QAAQ,EAAE;wBACR,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC;wBACrC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC;wBACjC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM;wBACnC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM;qBAChC;oBACD,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC;oBACxE,SAAS,EAAE,YAAY,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,YAAY;oBAC1F,QAAQ,EAAE,KAAK;iBAChB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,aAAa;IACb,IAAI,IAAI,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAAC;QAC7G,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE;oBACR,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC;oBACrC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC;oBACjC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM;oBACnC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM;iBAChC;gBACD,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC;gBACxE,SAAS,EAAE,cAAc,QAAQ,CAAC,IAAI,EAAE;gBACxC,QAAQ,EAAE,KAAK;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,+BAA+B;IAC/B,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QAChC,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACjF,IAAI,YAAY,IAAI,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACvD,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,YAAY,CAAC,IAAI;gBACvB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE;oBACR,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC;oBACrC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC;oBACjC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM;oBACnC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM;iBAChC;gBACD,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC;gBACxE,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI;gBACjF,QAAQ,EAAE,KAAK;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvC,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,UAAU,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC7C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,wBAAwB,QAAQ,EAAE,CAAC,EAAE,CAAC;IACpF,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACzC,MAAM,OAAO,GAAiB,EAAE,CAAC;QACjC,MAAM,OAAO,GAAiB,EAAE,CAAC;QAEjC,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QAE7D,MAAM,MAAM,GAAgB,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAC7D,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAClC,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,EAAE;YACX,MAAM,EAAE,CAAC,yBAAyB,QAAQ,MAAM,GAAG,EAAE,CAAC;SACvD,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,QAAgB,EAChB,KAAa,EACb,IAAiB;IAEjB,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACxC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC1B,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QACrE,MAAM,SAAS,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;QAC3C,OAAO,SAAS,IAAI,SAAS,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAmB;IAC/C,QAAQ,EAAE,KAAK;IACf,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;IAC/C,SAAS;IACT,kBAAkB;CACnB,CAAC;AAEF,cAAc,CAAC,iBAAiB,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { SymbolInfo } from './types.js';
2
+ export interface ResolvedExport {
3
+ originalFile: string;
4
+ originalName: string;
5
+ resolvedFile: string;
6
+ resolvedSymbol?: SymbolInfo;
7
+ exportChain: string[];
8
+ }
9
+ export declare function followExport(filePath: string, exportedName: string, visited?: Set<string>, depth?: number): ResolvedExport | null;
10
+ export declare function resolveSymbolThroughExports(filePath: string, symbolName: string): SymbolInfo | null;
11
+ export declare function getAllReexportedSymbols(filePath: string, visited?: Set<string>, depth?: number): SymbolInfo[];
12
+ //# sourceMappingURL=exportResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exportResolver.d.ts","sourceRoot":"","sources":["../../src/parsers/exportResolver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,YAAY,CAAC;AA2BzD,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,GAAG,CAAC,MAAM,CAAa,EAChC,KAAK,GAAE,MAAU,GAChB,cAAc,GAAG,IAAI,CAkEvB;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,UAAU,GAAG,IAAI,CAGnB;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,GAAG,CAAC,MAAM,CAAa,EAChC,KAAK,GAAE,MAAU,GAChB,UAAU,EAAE,CAuBd"}