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
@@ -0,0 +1,178 @@
1
+ import { z } from 'zod';
2
+ import * as path from 'node:path';
3
+ import { searchSymbol } from './searchSymbol.js';
4
+ import { lookupAlias } from './registerAlias.js';
5
+ import { searchPattern } from '../search/ripgrep.js';
6
+ import { parseFile } from '../parsers/index.js';
7
+ import { formatRange } from '../utils/fileReader.js';
8
+ import { glob } from '../search/glob.js';
9
+ export const searchFuzzySchema = z.object({
10
+ query: z.string().describe('Natural language query, alias, or fuzzy keyword'),
11
+ scope: z.string().optional().describe('Search scope (directory path)'),
12
+ limit: z.number().optional().default(20).describe('Maximum number of results'),
13
+ });
14
+ function normalizeQuery(query) {
15
+ const variants = [query];
16
+ // 小写
17
+ variants.push(query.toLowerCase());
18
+ // 去空格
19
+ variants.push(query.replace(/\s+/g, ''));
20
+ // kebab-case -> camelCase
21
+ const kebabToCamel = query.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
22
+ variants.push(kebabToCamel);
23
+ // camelCase -> kebab-case
24
+ const camelToKebab = query.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
25
+ variants.push(camelToKebab);
26
+ // PascalCase
27
+ const pascal = query.charAt(0).toUpperCase() + query.slice(1);
28
+ variants.push(pascal);
29
+ return [...new Set(variants)];
30
+ }
31
+ function parseTarget(target) {
32
+ const hashIdx = target.indexOf('#');
33
+ if (hashIdx !== -1) {
34
+ return {
35
+ file: target.slice(0, hashIdx),
36
+ symbol: target.slice(hashIdx + 1),
37
+ };
38
+ }
39
+ return { file: target };
40
+ }
41
+ async function aliasRecall(query) {
42
+ const targets = lookupAlias(query);
43
+ const results = [];
44
+ for (const target of targets) {
45
+ const { file, symbol } = parseTarget(target);
46
+ const parseResult = parseFile(file);
47
+ if (symbol) {
48
+ const matched = parseResult.symbols.find((s) => s.name === symbol);
49
+ if (matched) {
50
+ results.push({
51
+ file: matched.file,
52
+ range: matched.range,
53
+ symbol: matched.name,
54
+ kind: matched.kind,
55
+ score: 1.0,
56
+ reasons: ['alias_hit'],
57
+ });
58
+ }
59
+ }
60
+ else if (parseResult.symbols.length > 0) {
61
+ const first = parseResult.symbols[0];
62
+ results.push({
63
+ file,
64
+ range: formatRange(1, 100),
65
+ symbol: first.name,
66
+ kind: first.kind,
67
+ score: 0.95,
68
+ reasons: ['alias_hit'],
69
+ });
70
+ }
71
+ }
72
+ return results;
73
+ }
74
+ async function symbolRecall(query, scope, limit) {
75
+ const variants = normalizeQuery(query);
76
+ const allResults = [];
77
+ const seen = new Set();
78
+ for (const variant of variants) {
79
+ const symbols = await searchSymbol({ query: variant, scope, limit: limit ?? 20, followExports: true });
80
+ for (const sym of symbols) {
81
+ const key = `${sym.file}:${sym.name}`;
82
+ if (seen.has(key))
83
+ continue;
84
+ seen.add(key);
85
+ const isExact = sym.name === query || sym.name.toLowerCase() === query.toLowerCase();
86
+ allResults.push({
87
+ file: sym.file,
88
+ range: sym.range,
89
+ symbol: sym.name,
90
+ kind: sym.kind,
91
+ score: isExact ? 0.9 : 0.7,
92
+ reasons: isExact ? ['definition_exact'] : ['definition_match'],
93
+ });
94
+ }
95
+ }
96
+ return allResults;
97
+ }
98
+ async function fileNameRecall(query, scope) {
99
+ const variants = normalizeQuery(query);
100
+ const results = [];
101
+ const seen = new Set();
102
+ for (const variant of variants) {
103
+ const files = await glob(`**/*${variant}*`, scope);
104
+ for (const file of files) {
105
+ if (seen.has(file))
106
+ continue;
107
+ seen.add(file);
108
+ const basename = path.basename(file, path.extname(file));
109
+ const isExact = basename.toLowerCase() === variant.toLowerCase() ||
110
+ basename.toLowerCase().includes(variant.toLowerCase());
111
+ results.push({
112
+ file,
113
+ range: '[1:50]',
114
+ score: isExact ? 0.6 : 0.4,
115
+ reasons: ['filename_match'],
116
+ });
117
+ }
118
+ }
119
+ return results;
120
+ }
121
+ async function textRecall(query, scope) {
122
+ const matches = await searchPattern(query, { scope, maxResults: 50 });
123
+ const results = [];
124
+ const seen = new Set();
125
+ for (const match of matches) {
126
+ const key = `${match.file}:${match.line}`;
127
+ if (seen.has(key))
128
+ continue;
129
+ seen.add(key);
130
+ const startLine = Math.max(1, match.line - 5);
131
+ const endLine = match.line + 10;
132
+ results.push({
133
+ file: match.file,
134
+ range: formatRange(startLine, endLine),
135
+ score: 0.3,
136
+ reasons: ['text_hit'],
137
+ });
138
+ }
139
+ return results;
140
+ }
141
+ function mergeAndSort(results, limit) {
142
+ // 按 file+range 去重,保留最高分
143
+ const map = new Map();
144
+ for (const r of results) {
145
+ const key = `${r.file}:${r.range}`;
146
+ const existing = map.get(key);
147
+ if (!existing || r.score > existing.score) {
148
+ if (existing) {
149
+ r.reasons = [...new Set([...r.reasons, ...existing.reasons])];
150
+ }
151
+ map.set(key, r);
152
+ }
153
+ else {
154
+ existing.reasons = [...new Set([...existing.reasons, ...r.reasons])];
155
+ }
156
+ }
157
+ const merged = Array.from(map.values());
158
+ merged.sort((a, b) => b.score - a.score);
159
+ return merged.slice(0, limit);
160
+ }
161
+ export async function searchFuzzy(input) {
162
+ const { query, scope, limit = 20 } = input;
163
+ // 并行执行多路召回
164
+ const [aliasResults, symbolResults, fileResults, textResults] = await Promise.all([
165
+ aliasRecall(query),
166
+ symbolRecall(query, scope, limit),
167
+ fileNameRecall(query, scope),
168
+ textRecall(query, scope),
169
+ ]);
170
+ const allResults = [
171
+ ...aliasResults,
172
+ ...symbolResults,
173
+ ...fileResults,
174
+ ...textResults,
175
+ ];
176
+ return mergeAndSort(allResults, limit);
177
+ }
178
+ //# sourceMappingURL=searchFuzzy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchFuzzy.js","sourceRoot":"","sources":["../../src/tools/searchFuzzy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { z } from 'zod';
2
+ import type { SymbolInfo } from '../parsers/types.js';
3
+ export declare const searchSymbolSchema: z.ZodObject<{
4
+ query: z.ZodString;
5
+ type: z.ZodOptional<z.ZodEnum<["function", "class", "interface", "type", "enum", "const", "let", "var", "function_component", "method", "getter", "setter", "contract", "library", "sol_interface", "struct", "event", "modifier", "error", "mapping", "element", "component", "selector", "variable", "mixin", "keyframes"]>>;
6
+ scope: z.ZodOptional<z.ZodString>;
7
+ limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
8
+ followExports: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
9
+ }, "strip", z.ZodTypeAny, {
10
+ query: string;
11
+ limit: number;
12
+ followExports: boolean;
13
+ scope?: string | undefined;
14
+ type?: "function" | "error" | "class" | "interface" | "type" | "enum" | "const" | "let" | "var" | "function_component" | "method" | "getter" | "setter" | "contract" | "library" | "sol_interface" | "struct" | "event" | "modifier" | "mapping" | "element" | "component" | "selector" | "variable" | "mixin" | "keyframes" | undefined;
15
+ }, {
16
+ query: string;
17
+ scope?: string | undefined;
18
+ type?: "function" | "error" | "class" | "interface" | "type" | "enum" | "const" | "let" | "var" | "function_component" | "method" | "getter" | "setter" | "contract" | "library" | "sol_interface" | "struct" | "event" | "modifier" | "mapping" | "element" | "component" | "selector" | "variable" | "mixin" | "keyframes" | undefined;
19
+ limit?: number | undefined;
20
+ followExports?: boolean | undefined;
21
+ }>;
22
+ export type SearchSymbolInput = z.infer<typeof searchSymbolSchema>;
23
+ export declare function searchSymbol(input: SearchSymbolInput): Promise<SymbolInfo[]>;
24
+ //# sourceMappingURL=searchSymbol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchSymbol.d.ts","sourceRoot":"","sources":["../../src/tools/searchSymbol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,qBAAqB,CAAC;AAElE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;EAwC7B,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEnE,wBAAsB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAwDlF"}
@@ -0,0 +1,95 @@
1
+ import { z } from 'zod';
2
+ import { searchFiles } from '../search/ripgrep.js';
3
+ import { parseFileForSymbol } from '../parsers/index.js';
4
+ import { resolveSymbolThroughExports } from '../parsers/exportResolver.js';
5
+ export const searchSymbolSchema = z.object({
6
+ query: z.string().describe('Symbol name to search for'),
7
+ type: z
8
+ .enum([
9
+ // TypeScript/JavaScript
10
+ 'function',
11
+ 'class',
12
+ 'interface',
13
+ 'type',
14
+ 'enum',
15
+ 'const',
16
+ 'let',
17
+ 'var',
18
+ 'function_component',
19
+ 'method',
20
+ 'getter',
21
+ 'setter',
22
+ // Solidity
23
+ 'contract',
24
+ 'library',
25
+ 'sol_interface',
26
+ 'struct',
27
+ 'event',
28
+ 'modifier',
29
+ 'error',
30
+ 'mapping',
31
+ // HTML
32
+ 'element',
33
+ 'component',
34
+ // CSS/Less/Sass
35
+ 'selector',
36
+ 'variable',
37
+ 'mixin',
38
+ 'keyframes',
39
+ ])
40
+ .optional()
41
+ .describe('Optional filter by symbol type'),
42
+ scope: z.string().optional().describe('Search scope (directory path)'),
43
+ limit: z.number().optional().default(20).describe('Maximum number of results'),
44
+ followExports: z.boolean().optional().default(true).describe('Follow export chains to find original definitions'),
45
+ });
46
+ export async function searchSymbol(input) {
47
+ const { query, type, scope, limit = 20, followExports = true } = input;
48
+ // 1. ripgrep 粗筛:找到包含 query 的文件
49
+ const candidateFiles = await searchFiles(query, { scope });
50
+ if (candidateFiles.length === 0) {
51
+ return [];
52
+ }
53
+ // 2. Tree-sitter 精筛:解析每个文件,提取匹配的符号定义
54
+ const allSymbols = [];
55
+ const seen = new Set();
56
+ for (const file of candidateFiles) {
57
+ const symbols = parseFileForSymbol(file, query, type);
58
+ for (const symbol of symbols) {
59
+ const key = `${symbol.file}:${symbol.name}:${symbol.location.startLine}`;
60
+ if (seen.has(key))
61
+ continue;
62
+ seen.add(key);
63
+ allSymbols.push(symbol);
64
+ }
65
+ // 3. 如果启用导出跟随,尝试解析重导出
66
+ if (followExports) {
67
+ const resolved = resolveSymbolThroughExports(file, query);
68
+ if (resolved) {
69
+ const key = `${resolved.file}:${resolved.name}:${resolved.location.startLine}`;
70
+ if (!seen.has(key)) {
71
+ seen.add(key);
72
+ allSymbols.push(resolved);
73
+ }
74
+ }
75
+ }
76
+ // 提前终止
77
+ if (allSymbols.length >= limit * 2) {
78
+ break;
79
+ }
80
+ }
81
+ // 4. 排序:优先完全匹配,然后按文件路径深度
82
+ const sorted = allSymbols.sort((a, b) => {
83
+ // 完全匹配优先
84
+ const aExact = a.name === query ? 0 : 1;
85
+ const bExact = b.name === query ? 0 : 1;
86
+ if (aExact !== bExact)
87
+ return aExact - bExact;
88
+ // 文件路径深度浅的优先
89
+ const aDepth = a.file.split('/').length;
90
+ const bDepth = b.file.split('/').length;
91
+ return aDepth - bDepth;
92
+ });
93
+ return sorted.slice(0, limit);
94
+ }
95
+ //# sourceMappingURL=searchSymbol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchSymbol.js","sourceRoot":"","sources":["../../src/tools/searchSymbol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export interface RangeReadResult {
2
+ file: string;
3
+ range: string;
4
+ startLine: number;
5
+ endLine: number;
6
+ code: string;
7
+ }
8
+ export declare function parseRange(rangeStr: string): {
9
+ startLine: number;
10
+ endLine: number;
11
+ } | null;
12
+ export declare function formatRange(startLine: number, endLine: number): string;
13
+ export declare function readFileContent(filePath: string): string | null;
14
+ export declare function readFileLines(filePath: string): string[] | null;
15
+ export declare function readRange(filePath: string, startLine: number, endLine: number, surround?: number): RangeReadResult | null;
16
+ //# sourceMappingURL=fileReader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileReader.d.ts","sourceRoot":"","sources":["../../src/utils/fileReader.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAO1F;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM/D;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAI/D;AAED,wBAAgB,SAAS,CACvB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAU,GACnB,eAAe,GAAG,IAAI,CAiBxB"}
@@ -0,0 +1,45 @@
1
+ import * as fs from 'node:fs';
2
+ import { toAbsolute } from './pathResolver.js';
3
+ export function parseRange(rangeStr) {
4
+ const match = rangeStr.match(/^\[(\d+):(\d+)\]$/);
5
+ if (!match)
6
+ return null;
7
+ return {
8
+ startLine: parseInt(match[1], 10),
9
+ endLine: parseInt(match[2], 10),
10
+ };
11
+ }
12
+ export function formatRange(startLine, endLine) {
13
+ return `[${startLine}:${endLine}]`;
14
+ }
15
+ export function readFileContent(filePath) {
16
+ try {
17
+ return fs.readFileSync(toAbsolute(filePath), 'utf-8');
18
+ }
19
+ catch {
20
+ return null;
21
+ }
22
+ }
23
+ export function readFileLines(filePath) {
24
+ const content = readFileContent(filePath);
25
+ if (content === null)
26
+ return null;
27
+ return content.split('\n');
28
+ }
29
+ export function readRange(filePath, startLine, endLine, surround = 0) {
30
+ const lines = readFileLines(filePath);
31
+ if (!lines)
32
+ return null;
33
+ const totalLines = lines.length;
34
+ const actualStart = Math.max(1, startLine - surround);
35
+ const actualEnd = Math.min(totalLines, endLine + surround);
36
+ const selectedLines = lines.slice(actualStart - 1, actualEnd);
37
+ return {
38
+ file: filePath,
39
+ range: formatRange(actualStart, actualEnd),
40
+ startLine: actualStart,
41
+ endLine: actualEnd,
42
+ code: selectedLines.join('\n'),
43
+ };
44
+ }
45
+ //# sourceMappingURL=fileReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileReader.js","sourceRoot":"","sources":["../../src/utils/fileReader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAU/C,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAClD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO;QACL,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACjC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;KAChC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,SAAiB,EAAE,OAAe;IAC5D,OAAO,IAAI,SAAS,IAAI,OAAO,GAAG,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,QAAgB,EAChB,SAAiB,EACjB,OAAe,EACf,WAAmB,CAAC;IAEpB,MAAM,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;IAChC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,OAAO,GAAG,QAAQ,CAAC,CAAC;IAE3D,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;IAE9D,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,WAAW,CAAC,WAAW,EAAE,SAAS,CAAC;QAC1C,SAAS,EAAE,WAAW;QACtB,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;KAC/B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function getIgnorePatterns(): string[];
2
+ export declare function shouldIgnorePath(relativePath: string): boolean;
3
+ export declare function resetIgnoreCache(): void;
4
+ //# sourceMappingURL=ignore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ignore.d.ts","sourceRoot":"","sources":["../../src/utils/ignore.ts"],"names":[],"mappings":"AA8CA,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAG5C;AAED,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAiC9D;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC"}
@@ -0,0 +1,80 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { getWorkspaceRoot } from './pathResolver.js';
4
+ const DEFAULT_IGNORE = [
5
+ 'node_modules',
6
+ 'dist',
7
+ 'build',
8
+ '.git',
9
+ '.next',
10
+ '.nuxt',
11
+ 'coverage',
12
+ '.cache',
13
+ '*.min.js',
14
+ '*.bundle.js',
15
+ ];
16
+ let customIgnorePatterns = null;
17
+ let ignoreFileWatchTime = 0;
18
+ function loadIgnoreFile() {
19
+ const ignoreFilePath = path.join(getWorkspaceRoot(), '.gitignore');
20
+ try {
21
+ const stat = fs.statSync(ignoreFilePath);
22
+ // 检查文件是否变更
23
+ if (customIgnorePatterns !== null && stat.mtimeMs === ignoreFileWatchTime) {
24
+ return customIgnorePatterns;
25
+ }
26
+ const content = fs.readFileSync(ignoreFilePath, 'utf-8');
27
+ const patterns = content
28
+ .split('\n')
29
+ .map((line) => line.trim())
30
+ .filter((line) => line && !line.startsWith('#'));
31
+ customIgnorePatterns = patterns;
32
+ ignoreFileWatchTime = stat.mtimeMs;
33
+ return patterns;
34
+ }
35
+ catch {
36
+ customIgnorePatterns = [];
37
+ return [];
38
+ }
39
+ }
40
+ export function getIgnorePatterns() {
41
+ const custom = loadIgnoreFile();
42
+ return [...DEFAULT_IGNORE, ...custom];
43
+ }
44
+ export function shouldIgnorePath(relativePath) {
45
+ const patterns = getIgnorePatterns();
46
+ const parts = relativePath.split(path.sep);
47
+ for (const pattern of patterns) {
48
+ // 简单的 glob 匹配
49
+ if (pattern.startsWith('*.')) {
50
+ // 扩展名匹配
51
+ const ext = pattern.slice(1);
52
+ if (relativePath.endsWith(ext)) {
53
+ return true;
54
+ }
55
+ }
56
+ else if (pattern.includes('*')) {
57
+ // 通配符匹配
58
+ const regex = new RegExp('^' + pattern.replace(/\*/g, '.*').replace(/\?/g, '.') + '$');
59
+ if (regex.test(relativePath) || parts.some((p) => regex.test(p))) {
60
+ return true;
61
+ }
62
+ }
63
+ else {
64
+ // 目录/文件名精确匹配
65
+ if (parts.includes(pattern)) {
66
+ return true;
67
+ }
68
+ // 路径前缀匹配
69
+ if (relativePath.startsWith(pattern + '/') || relativePath === pattern) {
70
+ return true;
71
+ }
72
+ }
73
+ }
74
+ return false;
75
+ }
76
+ export function resetIgnoreCache() {
77
+ customIgnorePatterns = null;
78
+ ignoreFileWatchTime = 0;
79
+ }
80
+ //# sourceMappingURL=ignore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ignore.js","sourceRoot":"","sources":["../../src/utils/ignore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare function setWorkspaceRoot(root: string): void;
2
+ export declare function getWorkspaceRoot(): string;
3
+ export declare function toAbsolute(relativePath: string): string;
4
+ export declare function toRelative(absolutePath: string): string;
5
+ export declare function isWithinWorkspace(filePath: string): boolean;
6
+ export declare function fileExists(filePath: string): boolean;
7
+ //# sourceMappingURL=pathResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathResolver.d.ts","sourceRoot":"","sources":["../../src/utils/pathResolver.ts"],"names":[],"mappings":"AAKA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEnD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAG3D;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAMpD"}
@@ -0,0 +1,31 @@
1
+ import * as path from 'node:path';
2
+ import * as fs from 'node:fs';
3
+ let workspaceRoot = process.cwd();
4
+ export function setWorkspaceRoot(root) {
5
+ workspaceRoot = path.resolve(root);
6
+ }
7
+ export function getWorkspaceRoot() {
8
+ return workspaceRoot;
9
+ }
10
+ export function toAbsolute(relativePath) {
11
+ if (path.isAbsolute(relativePath)) {
12
+ return relativePath;
13
+ }
14
+ return path.join(workspaceRoot, relativePath);
15
+ }
16
+ export function toRelative(absolutePath) {
17
+ return path.relative(workspaceRoot, absolutePath);
18
+ }
19
+ export function isWithinWorkspace(filePath) {
20
+ const absolute = toAbsolute(filePath);
21
+ return absolute.startsWith(workspaceRoot);
22
+ }
23
+ export function fileExists(filePath) {
24
+ try {
25
+ return fs.statSync(toAbsolute(filePath)).isFile();
26
+ }
27
+ catch {
28
+ return false;
29
+ }
30
+ }
31
+ //# sourceMappingURL=pathResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathResolver.js","sourceRoot":"","sources":["../../src/utils/pathResolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,IAAI,aAAa,GAAW,OAAO,CAAC,GAAG,EAAE,CAAC;AAE1C,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,YAAoB;IAC7C,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAClC,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,YAAoB;IAC7C,OAAO,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IACtC,OAAO,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "genifyai",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Intelligent coding assistant MCP tool with AST-based code indexing",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "genifyai": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "dev": "tsc --watch",
16
+ "start": "node dist/index.js",
17
+ "prepublishOnly": "pnpm build"
18
+ },
19
+ "keywords": [
20
+ "mcp",
21
+ "code-assistant",
22
+ "tree-sitter",
23
+ "ast",
24
+ "code-search"
25
+ ],
26
+ "author": "",
27
+ "license": "MIT",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/xiaozuoyou/Genify"
31
+ },
32
+ "packageManager": "pnpm@10.26.1",
33
+ "engines": {
34
+ "node": ">=18.0.0"
35
+ },
36
+ "dependencies": {
37
+ "@modelcontextprotocol/sdk": "^1.0.0",
38
+ "@vscode/ripgrep": "^1.15.0",
39
+ "tree-sitter": "^0.21.1",
40
+ "tree-sitter-css": "0.20.0",
41
+ "tree-sitter-html": "0.20.1",
42
+ "tree-sitter-solidity": "1.2.9",
43
+ "tree-sitter-typescript": "^0.23.2",
44
+ "zod": "^3.24.0"
45
+ },
46
+ "devDependencies": {
47
+ "@types/node": "^22.0.0",
48
+ "typescript": "^5.7.0"
49
+ },
50
+ "pnpm": {
51
+ "onlyBuiltDependencies": [
52
+ "@vscode/ripgrep",
53
+ "tree-sitter",
54
+ "tree-sitter-javascript",
55
+ "tree-sitter-typescript",
56
+ "tree-sitter-solidity",
57
+ "tree-sitter-html",
58
+ "tree-sitter-css"
59
+ ]
60
+ }
61
+ }