@git.zone/tsdoc 1.11.0 → 1.11.2

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 (62) hide show
  1. package/dist_ts/aidocs_classes/commit.js +27 -34
  2. package/dist_ts/aidocs_classes/description.js +68 -29
  3. package/dist_ts/aidocs_classes/projectcontext.d.ts +5 -5
  4. package/dist_ts/aidocs_classes/projectcontext.js +8 -16
  5. package/dist_ts/aidocs_classes/readme.js +156 -88
  6. package/dist_ts/classes.aidoc.d.ts +10 -6
  7. package/dist_ts/classes.aidoc.js +17 -11
  8. package/dist_ts/classes.diffprocessor.js +284 -0
  9. package/dist_ts/cli.js +21 -92
  10. package/dist_ts/plugins.d.ts +1 -2
  11. package/dist_ts/plugins.js +2 -3
  12. package/package.json +11 -13
  13. package/ts/aidocs_classes/commit.ts +26 -41
  14. package/ts/aidocs_classes/description.ts +72 -34
  15. package/ts/aidocs_classes/projectcontext.ts +7 -14
  16. package/ts/aidocs_classes/readme.ts +168 -93
  17. package/ts/classes.aidoc.ts +18 -11
  18. package/ts/cli.ts +20 -100
  19. package/ts/plugins.ts +1 -2
  20. package/dist_ts/context/config-manager.d.ts +0 -83
  21. package/dist_ts/context/config-manager.js +0 -318
  22. package/dist_ts/context/context-analyzer.d.ts +0 -73
  23. package/dist_ts/context/context-analyzer.js +0 -311
  24. package/dist_ts/context/context-cache.d.ts +0 -73
  25. package/dist_ts/context/context-cache.js +0 -239
  26. package/dist_ts/context/context-trimmer.d.ts +0 -60
  27. package/dist_ts/context/context-trimmer.js +0 -258
  28. package/dist_ts/context/diff-processor.js +0 -284
  29. package/dist_ts/context/enhanced-context.d.ts +0 -73
  30. package/dist_ts/context/enhanced-context.js +0 -275
  31. package/dist_ts/context/index.d.ts +0 -11
  32. package/dist_ts/context/index.js +0 -12
  33. package/dist_ts/context/iterative-context-builder.d.ts +0 -62
  34. package/dist_ts/context/iterative-context-builder.js +0 -395
  35. package/dist_ts/context/lazy-file-loader.d.ts +0 -60
  36. package/dist_ts/context/lazy-file-loader.js +0 -182
  37. package/dist_ts/context/task-context-factory.d.ts +0 -48
  38. package/dist_ts/context/task-context-factory.js +0 -86
  39. package/dist_ts/context/types.d.ts +0 -301
  40. package/dist_ts/context/types.js +0 -2
  41. package/dist_ts/tsdoc.classes.typedoc.d.ts +0 -10
  42. package/dist_ts/tsdoc.classes.typedoc.js +0 -48
  43. package/dist_ts/tsdoc.cli.d.ts +0 -1
  44. package/dist_ts/tsdoc.cli.js +0 -32
  45. package/dist_ts/tsdoc.logging.d.ts +0 -2
  46. package/dist_ts/tsdoc.logging.js +0 -14
  47. package/dist_ts/tsdoc.paths.d.ts +0 -8
  48. package/dist_ts/tsdoc.paths.js +0 -12
  49. package/dist_ts/tsdoc.plugins.d.ts +0 -11
  50. package/dist_ts/tsdoc.plugins.js +0 -15
  51. package/ts/context/config-manager.ts +0 -369
  52. package/ts/context/context-analyzer.ts +0 -391
  53. package/ts/context/context-cache.ts +0 -286
  54. package/ts/context/context-trimmer.ts +0 -310
  55. package/ts/context/enhanced-context.ts +0 -332
  56. package/ts/context/index.ts +0 -70
  57. package/ts/context/iterative-context-builder.ts +0 -512
  58. package/ts/context/lazy-file-loader.ts +0 -207
  59. package/ts/context/task-context-factory.ts +0 -120
  60. package/ts/context/types.ts +0 -324
  61. /package/dist_ts/{context/diff-processor.d.ts → classes.diffprocessor.d.ts} +0 -0
  62. /package/ts/{context/diff-processor.ts → classes.diffprocessor.ts} +0 -0
@@ -1,395 +0,0 @@
1
- import * as plugins from '../plugins.js';
2
- import * as fs from 'fs';
3
- import { logger } from '../logging.js';
4
- import { LazyFileLoader } from './lazy-file-loader.js';
5
- import { ContextCache } from './context-cache.js';
6
- import { ContextAnalyzer } from './context-analyzer.js';
7
- import { ConfigManager } from './config-manager.js';
8
- /**
9
- * Iterative context builder that uses AI to intelligently select files
10
- * across multiple iterations until sufficient context is gathered
11
- */
12
- export class IterativeContextBuilder {
13
- /**
14
- * Creates a new IterativeContextBuilder
15
- * @param projectRoot - Root directory of the project
16
- * @param config - Iterative configuration
17
- * @param openaiInstance - Optional pre-configured OpenAI provider instance
18
- */
19
- constructor(projectRoot, config, openaiInstance) {
20
- this.tokenBudget = 190000;
21
- this.projectRoot = projectRoot;
22
- this.lazyLoader = new LazyFileLoader(projectRoot);
23
- this.cache = new ContextCache(projectRoot);
24
- this.analyzer = new ContextAnalyzer(projectRoot);
25
- this.externalOpenaiInstance = openaiInstance;
26
- // Default configuration
27
- this.config = {
28
- maxIterations: config?.maxIterations ?? 5,
29
- firstPassFileLimit: config?.firstPassFileLimit ?? 10,
30
- subsequentPassFileLimit: config?.subsequentPassFileLimit ?? 5,
31
- temperature: config?.temperature ?? 0.3,
32
- model: config?.model ?? 'gpt-4-turbo-preview',
33
- };
34
- }
35
- /**
36
- * Initialize the builder
37
- */
38
- async initialize() {
39
- await this.cache.init();
40
- const configManager = ConfigManager.getInstance();
41
- await configManager.initialize(this.projectRoot);
42
- this.tokenBudget = configManager.getMaxTokens();
43
- // Use external OpenAI instance if provided, otherwise create a new one
44
- if (this.externalOpenaiInstance) {
45
- this.openaiInstance = this.externalOpenaiInstance;
46
- }
47
- else {
48
- // Initialize OpenAI instance from environment
49
- const qenvInstance = new plugins.qenv.Qenv();
50
- const openaiToken = await qenvInstance.getEnvVarOnDemand('OPENAI_TOKEN');
51
- if (!openaiToken) {
52
- throw new Error('OPENAI_TOKEN environment variable is required for iterative context building');
53
- }
54
- this.openaiInstance = new plugins.smartai.OpenAiProvider({
55
- openaiToken,
56
- });
57
- await this.openaiInstance.start();
58
- }
59
- }
60
- /**
61
- * Build context iteratively using AI decision making
62
- * @param taskType - Type of task being performed
63
- * @param additionalContext - Optional additional context (e.g., git diff for commit tasks)
64
- * @returns Complete iterative context result
65
- */
66
- async buildContextIteratively(taskType, additionalContext) {
67
- const startTime = Date.now();
68
- logger.log('info', '🤖 Starting iterative context building...');
69
- logger.log('info', ` Task: ${taskType}, Budget: ${this.tokenBudget} tokens, Max iterations: ${this.config.maxIterations}`);
70
- // Phase 1: Scan project files for metadata
71
- logger.log('info', '📋 Scanning project files...');
72
- const metadata = await this.scanProjectFiles(taskType);
73
- const totalEstimatedTokens = metadata.reduce((sum, m) => sum + m.estimatedTokens, 0);
74
- logger.log('info', ` Found ${metadata.length} files (~${totalEstimatedTokens} estimated tokens)`);
75
- // Phase 2: Analyze files for initial prioritization
76
- logger.log('info', '🔍 Analyzing file dependencies and importance...');
77
- const analysis = await this.analyzer.analyze(metadata, taskType, []);
78
- logger.log('info', ` Analysis complete in ${analysis.analysisDuration}ms`);
79
- // Track state across iterations
80
- const iterations = [];
81
- let totalTokensUsed = 0;
82
- let apiCallCount = 0;
83
- let loadedContent = '';
84
- const includedFiles = [];
85
- // If additional context (e.g., git diff) is provided, prepend it
86
- if (additionalContext) {
87
- // NOTE: additionalContext is expected to be pre-processed by DiffProcessor
88
- // which intelligently samples large diffs to stay within token budget (100k default)
89
- const MAX_DIFF_TOKENS = 200000; // Safety net for edge cases (DiffProcessor uses 100k budget)
90
- const diffSection = `
91
- ====== GIT DIFF ======
92
-
93
- ${additionalContext}
94
-
95
- ====== END OF GIT DIFF ======
96
- `;
97
- // Validate token count (should already be under budget from DiffProcessor)
98
- const diffTokens = this.countTokens(diffSection);
99
- if (diffTokens > MAX_DIFF_TOKENS) {
100
- logger.log('error', `❌ Pre-processed git diff exceeds safety limit (${diffTokens.toLocaleString()} tokens > ${MAX_DIFF_TOKENS.toLocaleString()} limit)`);
101
- logger.log('error', ` This should not happen - DiffProcessor should have limited to ~100k tokens.`);
102
- logger.log('error', ` Please check DiffProcessor configuration and output.`);
103
- throw new Error(`Pre-processed git diff size (${diffTokens.toLocaleString()} tokens) exceeds safety limit (${MAX_DIFF_TOKENS.toLocaleString()} tokens). ` +
104
- `This indicates a bug in DiffProcessor or misconfiguration.`);
105
- }
106
- loadedContent = diffSection;
107
- totalTokensUsed += diffTokens;
108
- logger.log('info', `📝 Added pre-processed git diff to context (${diffTokens.toLocaleString()} tokens)`);
109
- }
110
- // Phase 3: Iterative file selection and loading
111
- for (let iteration = 1; iteration <= this.config.maxIterations; iteration++) {
112
- const iterationStart = Date.now();
113
- logger.log('info', `\n🤔 Iteration ${iteration}/${this.config.maxIterations}: Asking AI which files to examine...`);
114
- const remainingBudget = this.tokenBudget - totalTokensUsed;
115
- logger.log('info', ` Token budget remaining: ${remainingBudget}/${this.tokenBudget} (${Math.round((remainingBudget / this.tokenBudget) * 100)}%)`);
116
- // Get AI decision on which files to load
117
- const decision = await this.getFileSelectionDecision(metadata, analysis.files.slice(0, 30), // Top 30 files by importance
118
- taskType, iteration, totalTokensUsed, remainingBudget, loadedContent);
119
- apiCallCount++;
120
- logger.log('info', ` AI reasoning: ${decision.reasoning}`);
121
- logger.log('info', ` AI requested ${decision.filesToLoad.length} files`);
122
- // Load requested files
123
- const iterationFiles = [];
124
- let iterationTokens = 0;
125
- if (decision.filesToLoad.length > 0) {
126
- logger.log('info', '📥 Loading requested files...');
127
- for (const filePath of decision.filesToLoad) {
128
- try {
129
- const fileInfo = await this.loadFile(filePath);
130
- if (totalTokensUsed + fileInfo.tokenCount <= this.tokenBudget) {
131
- const formattedFile = this.formatFileForContext(fileInfo);
132
- loadedContent += formattedFile;
133
- includedFiles.push(fileInfo);
134
- iterationFiles.push(fileInfo);
135
- iterationTokens += fileInfo.tokenCount;
136
- totalTokensUsed += fileInfo.tokenCount;
137
- logger.log('info', ` ✓ ${fileInfo.relativePath} (${fileInfo.tokenCount} tokens)`);
138
- }
139
- else {
140
- logger.log('warn', ` ✗ ${fileInfo.relativePath} - would exceed budget, skipping`);
141
- }
142
- }
143
- catch (error) {
144
- logger.log('warn', ` ✗ Failed to load ${filePath}: ${error.message}`);
145
- }
146
- }
147
- }
148
- // Record iteration state
149
- const iterationDuration = Date.now() - iterationStart;
150
- iterations.push({
151
- iteration,
152
- filesLoaded: iterationFiles,
153
- tokensUsed: iterationTokens,
154
- totalTokensUsed,
155
- decision,
156
- duration: iterationDuration,
157
- });
158
- logger.log('info', ` Iteration ${iteration} complete: ${iterationFiles.length} files loaded, ${iterationTokens} tokens used`);
159
- // Check if we should continue
160
- if (totalTokensUsed >= this.tokenBudget * 0.95) {
161
- logger.log('warn', '⚠️ Approaching token budget limit, stopping iterations');
162
- break;
163
- }
164
- // Ask AI if context is sufficient
165
- if (iteration < this.config.maxIterations) {
166
- logger.log('info', '🤔 Asking AI if context is sufficient...');
167
- const sufficiencyDecision = await this.evaluateContextSufficiency(loadedContent, taskType, iteration, totalTokensUsed, remainingBudget - iterationTokens);
168
- apiCallCount++;
169
- logger.log('info', ` AI decision: ${sufficiencyDecision.sufficient ? '✅ SUFFICIENT' : '⏭️ NEEDS MORE'}`);
170
- logger.log('info', ` Reasoning: ${sufficiencyDecision.reasoning}`);
171
- if (sufficiencyDecision.sufficient) {
172
- logger.log('ok', '✅ Context building complete - AI determined context is sufficient');
173
- break;
174
- }
175
- }
176
- }
177
- const totalDuration = Date.now() - startTime;
178
- logger.log('ok', `\n✅ Iterative context building complete!`);
179
- logger.log('info', ` Files included: ${includedFiles.length}`);
180
- logger.log('info', ` Token usage: ${totalTokensUsed}/${this.tokenBudget} (${Math.round((totalTokensUsed / this.tokenBudget) * 100)}%)`);
181
- logger.log('info', ` Iterations: ${iterations.length}, API calls: ${apiCallCount}`);
182
- logger.log('info', ` Total duration: ${(totalDuration / 1000).toFixed(2)}s`);
183
- return {
184
- context: loadedContent,
185
- tokenCount: totalTokensUsed,
186
- includedFiles,
187
- trimmedFiles: [],
188
- excludedFiles: [],
189
- tokenSavings: 0,
190
- iterationCount: iterations.length,
191
- iterations,
192
- apiCallCount,
193
- totalDuration,
194
- };
195
- }
196
- /**
197
- * Scan project files based on task type
198
- */
199
- async scanProjectFiles(taskType) {
200
- const configManager = ConfigManager.getInstance();
201
- const taskConfig = configManager.getTaskConfig(taskType);
202
- const includeGlobs = taskConfig?.includePaths?.map(p => `${p}/**/*.ts`) || [
203
- 'ts/**/*.ts',
204
- 'ts*/**/*.ts'
205
- ];
206
- const configGlobs = [
207
- 'package.json',
208
- 'readme.md',
209
- 'readme.hints.md',
210
- 'npmextra.json'
211
- ];
212
- return await this.lazyLoader.scanFiles([...configGlobs, ...includeGlobs]);
213
- }
214
- /**
215
- * Get AI decision on which files to load
216
- */
217
- async getFileSelectionDecision(allMetadata, analyzedFiles, taskType, iteration, tokensUsed, remainingBudget, loadedContent) {
218
- const isFirstIteration = iteration === 1;
219
- const fileLimit = isFirstIteration
220
- ? this.config.firstPassFileLimit
221
- : this.config.subsequentPassFileLimit;
222
- const systemPrompt = this.buildFileSelectionPrompt(allMetadata, analyzedFiles, taskType, iteration, tokensUsed, remainingBudget, loadedContent, fileLimit);
223
- const response = await this.openaiInstance.chat({
224
- systemMessage: `You are an AI assistant that helps select the most relevant files for code analysis.
225
- You must respond ONLY with valid JSON that can be parsed with JSON.parse().
226
- Do not wrap the JSON in markdown code blocks or add any other text.`,
227
- userMessage: systemPrompt,
228
- messageHistory: [],
229
- });
230
- // Parse JSON response, handling potential markdown formatting
231
- const content = response.message.replace('```json', '').replace('```', '').trim();
232
- const parsed = JSON.parse(content);
233
- return {
234
- reasoning: parsed.reasoning || 'No reasoning provided',
235
- filesToLoad: parsed.files_to_load || [],
236
- estimatedTokensNeeded: parsed.estimated_tokens_needed,
237
- };
238
- }
239
- /**
240
- * Build prompt for file selection
241
- */
242
- buildFileSelectionPrompt(metadata, analyzedFiles, taskType, iteration, tokensUsed, remainingBudget, loadedContent, fileLimit) {
243
- const taskDescriptions = {
244
- readme: 'generating a comprehensive README that explains the project\'s purpose, features, and API',
245
- commit: 'analyzing code changes to generate an intelligent commit message',
246
- description: 'generating a concise project description for package.json',
247
- };
248
- const alreadyLoadedFiles = loadedContent
249
- ? loadedContent.split('\n======').slice(1).map(section => {
250
- const match = section.match(/START OF FILE (.+?) ======/);
251
- return match ? match[1] : '';
252
- }).filter(Boolean)
253
- : [];
254
- const availableFiles = metadata
255
- .filter(m => !alreadyLoadedFiles.includes(m.relativePath))
256
- .map(m => {
257
- const analysis = analyzedFiles.find(a => a.path === m.path);
258
- return `- ${m.relativePath} (${m.size} bytes, ~${m.estimatedTokens} tokens${analysis ? `, importance: ${analysis.importanceScore.toFixed(2)}` : ''})`;
259
- })
260
- .join('\n');
261
- return `You are building context for ${taskDescriptions[taskType]} in a TypeScript project.
262
-
263
- ITERATION: ${iteration}
264
- TOKENS USED: ${tokensUsed}/${tokensUsed + remainingBudget} (${Math.round((tokensUsed / (tokensUsed + remainingBudget)) * 100)}%)
265
- REMAINING BUDGET: ${remainingBudget} tokens
266
-
267
- ${alreadyLoadedFiles.length > 0 ? `FILES ALREADY LOADED:\n${alreadyLoadedFiles.map(f => `- ${f}`).join('\n')}\n\n` : ''}AVAILABLE FILES (not yet loaded):
268
- ${availableFiles}
269
-
270
- Your task: Select up to ${fileLimit} files that will give you the MOST understanding for this ${taskType} task.
271
-
272
- ${iteration === 1 ? `This is the FIRST iteration. Focus on:
273
- - Main entry points (index.ts, main exports)
274
- - Core classes and interfaces
275
- - Package configuration
276
- ` : `This is iteration ${iteration}. You've already seen some files. Now focus on:
277
- - Files that complement what you've already loaded
278
- - Dependencies of already-loaded files
279
- - Missing pieces for complete understanding
280
- `}
281
-
282
- Consider:
283
- 1. File importance scores (if provided)
284
- 2. File paths (ts/index.ts is likely more important than ts/internal/utils.ts)
285
- 3. Token efficiency (prefer smaller files if they provide good information)
286
- 4. Remaining budget (${remainingBudget} tokens)
287
-
288
- Respond in JSON format:
289
- {
290
- "reasoning": "Brief explanation of why you're selecting these files",
291
- "files_to_load": ["path/to/file1.ts", "path/to/file2.ts"],
292
- "estimated_tokens_needed": 15000
293
- }`;
294
- }
295
- /**
296
- * Evaluate if current context is sufficient
297
- */
298
- async evaluateContextSufficiency(loadedContent, taskType, iteration, tokensUsed, remainingBudget) {
299
- const prompt = `You have been building context for a ${taskType} task across ${iteration} iterations.
300
-
301
- CURRENT STATE:
302
- - Tokens used: ${tokensUsed}
303
- - Remaining budget: ${remainingBudget}
304
- - Files loaded: ${loadedContent.split('\n======').length - 1}
305
-
306
- CONTEXT SO FAR:
307
- ${loadedContent.substring(0, 3000)}... (truncated for brevity)
308
-
309
- Question: Do you have SUFFICIENT context to successfully complete the ${taskType} task?
310
-
311
- Consider:
312
- - For README: Do you understand the project's purpose, main features, API surface, and usage patterns?
313
- - For commit: Do you understand what changed and why?
314
- - For description: Do you understand the project's core value proposition?
315
-
316
- Respond in JSON format:
317
- {
318
- "sufficient": true or false,
319
- "reasoning": "Detailed explanation of your decision"
320
- }`;
321
- const response = await this.openaiInstance.chat({
322
- systemMessage: `You are an AI assistant that evaluates whether gathered context is sufficient for a task.
323
- You must respond ONLY with valid JSON that can be parsed with JSON.parse().
324
- Do not wrap the JSON in markdown code blocks or add any other text.`,
325
- userMessage: prompt,
326
- messageHistory: [],
327
- });
328
- // Parse JSON response, handling potential markdown formatting
329
- const content = response.message.replace('```json', '').replace('```', '').trim();
330
- const parsed = JSON.parse(content);
331
- return {
332
- sufficient: parsed.sufficient || false,
333
- reasoning: parsed.reasoning || 'No reasoning provided',
334
- };
335
- }
336
- /**
337
- * Load a single file with caching
338
- */
339
- async loadFile(filePath) {
340
- // Try cache first
341
- const cached = await this.cache.get(filePath);
342
- if (cached) {
343
- return {
344
- path: filePath,
345
- relativePath: plugins.path.relative(this.projectRoot, filePath),
346
- contents: cached.contents,
347
- tokenCount: cached.tokenCount,
348
- };
349
- }
350
- // Load from disk
351
- const contents = await plugins.fsInstance.file(filePath).encoding('utf8').read();
352
- const tokenCount = this.countTokens(contents);
353
- const relativePath = plugins.path.relative(this.projectRoot, filePath);
354
- // Cache it
355
- const stats = await fs.promises.stat(filePath);
356
- await this.cache.set({
357
- path: filePath,
358
- contents,
359
- tokenCount,
360
- mtime: Math.floor(stats.mtimeMs),
361
- cachedAt: Date.now(),
362
- });
363
- return {
364
- path: filePath,
365
- relativePath,
366
- contents,
367
- tokenCount,
368
- };
369
- }
370
- /**
371
- * Format a file for inclusion in context
372
- */
373
- formatFileForContext(file) {
374
- return `
375
- ====== START OF FILE ${file.relativePath} ======
376
-
377
- ${file.contents}
378
-
379
- ====== END OF FILE ${file.relativePath} ======
380
- `;
381
- }
382
- /**
383
- * Count tokens in text
384
- */
385
- countTokens(text) {
386
- try {
387
- const tokens = plugins.gptTokenizer.encode(text);
388
- return tokens.length;
389
- }
390
- catch (error) {
391
- return Math.ceil(text.length / 4);
392
- }
393
- }
394
- }
395
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXRlcmF0aXZlLWNvbnRleHQtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2NvbnRleHQvaXRlcmF0aXZlLWNvbnRleHQtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQUN6QixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBV3ZDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVwRDs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sdUJBQXVCO0lBVWxDOzs7OztPQUtHO0lBQ0gsWUFDRSxXQUFtQixFQUNuQixNQUFrQyxFQUNsQyxjQUErQztRQWJ6QyxnQkFBVyxHQUFXLE1BQU0sQ0FBQztRQWVuQyxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztRQUMvQixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2xELElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDM0MsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLGVBQWUsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsc0JBQXNCLEdBQUcsY0FBYyxDQUFDO1FBRTdDLHdCQUF3QjtRQUN4QixJQUFJLENBQUMsTUFBTSxHQUFHO1lBQ1osYUFBYSxFQUFFLE1BQU0sRUFBRSxhQUFhLElBQUksQ0FBQztZQUN6QyxrQkFBa0IsRUFBRSxNQUFNLEVBQUUs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
@@ -1,60 +0,0 @@
1
- import type { IFileMetadata, IFileInfo } from './types.js';
2
- /**
3
- * LazyFileLoader handles efficient file loading by:
4
- * - Scanning files for metadata without loading contents
5
- * - Providing fast file size and token estimates
6
- * - Loading contents only when requested
7
- * - Parallel loading of selected files
8
- */
9
- export declare class LazyFileLoader {
10
- private projectRoot;
11
- private metadataCache;
12
- /**
13
- * Creates a new LazyFileLoader
14
- * @param projectRoot - Root directory of the project
15
- */
16
- constructor(projectRoot: string);
17
- /**
18
- * Scans files in given globs and creates metadata without loading contents
19
- * @param globs - File patterns to scan (e.g., ['ts/**\/*.ts', 'test/**\/*.ts'])
20
- * @returns Array of file metadata
21
- */
22
- scanFiles(globs: string[]): Promise<IFileMetadata[]>;
23
- /**
24
- * Gets metadata for a single file without loading contents
25
- * @param filePath - Absolute path to the file
26
- * @returns File metadata
27
- */
28
- getMetadata(filePath: string): Promise<IFileMetadata>;
29
- /**
30
- * Loads file contents for selected files in parallel
31
- * @param metadata - Array of file metadata to load
32
- * @param tokenizer - Function to calculate accurate token count
33
- * @returns Array of complete file info with contents
34
- */
35
- loadFiles(metadata: IFileMetadata[], tokenizer: (content: string) => number): Promise<IFileInfo[]>;
36
- /**
37
- * Loads a single file with contents
38
- * @param filePath - Absolute path to the file
39
- * @param tokenizer - Function to calculate accurate token count
40
- * @returns Complete file info with contents
41
- */
42
- loadFile(filePath: string, tokenizer: (content: string) => number): Promise<IFileInfo>;
43
- /**
44
- * Updates importance scores for metadata entries
45
- * @param scores - Map of file paths to importance scores
46
- */
47
- updateImportanceScores(scores: Map<string, number>): void;
48
- /**
49
- * Clears the metadata cache
50
- */
51
- clearCache(): void;
52
- /**
53
- * Gets total estimated tokens for all cached metadata
54
- */
55
- getTotalEstimatedTokens(): number;
56
- /**
57
- * Gets cached metadata entries
58
- */
59
- getCachedMetadata(): IFileMetadata[];
60
- }