MCPcopy Create free account
hub / github.com/anus-dev/ANUS / RecursiveFileSearch

Class RecursiveFileSearch

packages/core/src/utils/filesearch/fileSearch.ts:91–182  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

89}
90
91class RecursiveFileSearch implements FileSearch {
92 private ignore: Ignore | undefined;
93 private resultCache: ResultCache | undefined;
94 private allFiles: string[] = [];
95 private fzf: AsyncFzf<string[]> | undefined;
96
97 constructor(private readonly options: FileSearchOptions) {}
98
99 async initialize(): Promise<void> {
100 this.ignore = loadIgnoreRules(this.options);
101 this.allFiles = await crawl({
102 crawlDirectory: this.options.projectRoot,
103 cwd: this.options.projectRoot,
104 ignore: this.ignore,
105 cache: this.options.cache,
106 cacheTtl: this.options.cacheTtl,
107 maxDepth: this.options.maxDepth,
108 });
109 this.buildResultCache();
110 }
111
112 async search(
113 pattern: string,
114 options: SearchOptions = {},
115 ): Promise<string[]> {
116 if (!this.resultCache || !this.fzf || !this.ignore) {
117 throw new Error('Engine not initialized. Call initialize() first.');
118 }
119
120 pattern = pattern || '*';
121
122 let filteredCandidates;
123 const { files: candidates, isExactMatch } =
124 await this.resultCache!.get(pattern);
125
126 if (isExactMatch) {
127 // Use the cached result.
128 filteredCandidates = candidates;
129 } else {
130 let shouldCache = true;
131 if (pattern.includes('*')) {
132 filteredCandidates = await filter(candidates, pattern, options.signal);
133 } else {
134 filteredCandidates = await this.fzf
135 .find(pattern)
136 .then((results: Array<FzfResultItem<string>>) =>
137 results.map((entry: FzfResultItem<string>) => entry.item),
138 )
139 .catch(() => {
140 shouldCache = false;
141 return [];
142 });
143 }
144
145 if (shouldCache) {
146 this.resultCache!.set(pattern, filteredCandidates);
147 }
148 }

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected