@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.
- package/dist_ts/aidocs_classes/commit.js +27 -34
- package/dist_ts/aidocs_classes/description.js +68 -29
- package/dist_ts/aidocs_classes/projectcontext.d.ts +5 -5
- package/dist_ts/aidocs_classes/projectcontext.js +8 -16
- package/dist_ts/aidocs_classes/readme.js +156 -88
- package/dist_ts/classes.aidoc.d.ts +10 -6
- package/dist_ts/classes.aidoc.js +17 -11
- package/dist_ts/classes.diffprocessor.js +284 -0
- package/dist_ts/cli.js +21 -92
- package/dist_ts/plugins.d.ts +1 -2
- package/dist_ts/plugins.js +2 -3
- package/package.json +11 -13
- package/ts/aidocs_classes/commit.ts +26 -41
- package/ts/aidocs_classes/description.ts +72 -34
- package/ts/aidocs_classes/projectcontext.ts +7 -14
- package/ts/aidocs_classes/readme.ts +168 -93
- package/ts/classes.aidoc.ts +18 -11
- package/ts/cli.ts +20 -100
- package/ts/plugins.ts +1 -2
- package/dist_ts/context/config-manager.d.ts +0 -83
- package/dist_ts/context/config-manager.js +0 -318
- package/dist_ts/context/context-analyzer.d.ts +0 -73
- package/dist_ts/context/context-analyzer.js +0 -311
- package/dist_ts/context/context-cache.d.ts +0 -73
- package/dist_ts/context/context-cache.js +0 -239
- package/dist_ts/context/context-trimmer.d.ts +0 -60
- package/dist_ts/context/context-trimmer.js +0 -258
- package/dist_ts/context/diff-processor.js +0 -284
- package/dist_ts/context/enhanced-context.d.ts +0 -73
- package/dist_ts/context/enhanced-context.js +0 -275
- package/dist_ts/context/index.d.ts +0 -11
- package/dist_ts/context/index.js +0 -12
- package/dist_ts/context/iterative-context-builder.d.ts +0 -62
- package/dist_ts/context/iterative-context-builder.js +0 -395
- package/dist_ts/context/lazy-file-loader.d.ts +0 -60
- package/dist_ts/context/lazy-file-loader.js +0 -182
- package/dist_ts/context/task-context-factory.d.ts +0 -48
- package/dist_ts/context/task-context-factory.js +0 -86
- package/dist_ts/context/types.d.ts +0 -301
- package/dist_ts/context/types.js +0 -2
- package/dist_ts/tsdoc.classes.typedoc.d.ts +0 -10
- package/dist_ts/tsdoc.classes.typedoc.js +0 -48
- package/dist_ts/tsdoc.cli.d.ts +0 -1
- package/dist_ts/tsdoc.cli.js +0 -32
- package/dist_ts/tsdoc.logging.d.ts +0 -2
- package/dist_ts/tsdoc.logging.js +0 -14
- package/dist_ts/tsdoc.paths.d.ts +0 -8
- package/dist_ts/tsdoc.paths.js +0 -12
- package/dist_ts/tsdoc.plugins.d.ts +0 -11
- package/dist_ts/tsdoc.plugins.js +0 -15
- package/ts/context/config-manager.ts +0 -369
- package/ts/context/context-analyzer.ts +0 -391
- package/ts/context/context-cache.ts +0 -286
- package/ts/context/context-trimmer.ts +0 -310
- package/ts/context/enhanced-context.ts +0 -332
- package/ts/context/index.ts +0 -70
- package/ts/context/iterative-context-builder.ts +0 -512
- package/ts/context/lazy-file-loader.ts +0 -207
- package/ts/context/task-context-factory.ts +0 -120
- package/ts/context/types.ts +0 -324
- /package/dist_ts/{context/diff-processor.d.ts → classes.diffprocessor.d.ts} +0 -0
- /package/ts/{context/diff-processor.ts → classes.diffprocessor.ts} +0 -0
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../plugins.js';
|
|
2
|
-
import type { ITrimConfig, ContextMode } from './types.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Class responsible for trimming file contents to reduce token usage
|
|
6
|
-
* while preserving important information for context
|
|
7
|
-
*/
|
|
8
|
-
export class ContextTrimmer {
|
|
9
|
-
private config: ITrimConfig;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Create a new ContextTrimmer with the given configuration
|
|
13
|
-
* @param config The trimming configuration
|
|
14
|
-
*/
|
|
15
|
-
constructor(config?: ITrimConfig) {
|
|
16
|
-
this.config = {
|
|
17
|
-
removeImplementations: true,
|
|
18
|
-
preserveInterfaces: true,
|
|
19
|
-
preserveTypeDefs: true,
|
|
20
|
-
preserveJSDoc: true,
|
|
21
|
-
maxFunctionLines: 5,
|
|
22
|
-
removeComments: true,
|
|
23
|
-
removeBlankLines: true,
|
|
24
|
-
...config
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Trim a file's contents based on the configuration
|
|
30
|
-
* @param filePath The path to the file
|
|
31
|
-
* @param content The file's contents
|
|
32
|
-
* @param mode The context mode to use
|
|
33
|
-
* @returns The trimmed file contents
|
|
34
|
-
*/
|
|
35
|
-
public trimFile(filePath: string, content: string, mode: ContextMode = 'trimmed'): string {
|
|
36
|
-
// If mode is 'full', return the original content
|
|
37
|
-
if (mode === 'full') {
|
|
38
|
-
return content;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Process based on file type
|
|
42
|
-
if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {
|
|
43
|
-
return this.trimTypeScriptFile(content);
|
|
44
|
-
} else if (filePath.endsWith('.md')) {
|
|
45
|
-
return this.trimMarkdownFile(content);
|
|
46
|
-
} else if (filePath.endsWith('.json')) {
|
|
47
|
-
return this.trimJsonFile(content);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Default to returning the original content for unknown file types
|
|
51
|
-
return content;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Trim a TypeScript file to reduce token usage
|
|
56
|
-
* @param content The TypeScript file contents
|
|
57
|
-
* @returns The trimmed file contents
|
|
58
|
-
*/
|
|
59
|
-
private trimTypeScriptFile(content: string): string {
|
|
60
|
-
let result = content;
|
|
61
|
-
|
|
62
|
-
// Step 1: Preserve JSDoc comments if configured
|
|
63
|
-
const jsDocComments: string[] = [];
|
|
64
|
-
if (this.config.preserveJSDoc) {
|
|
65
|
-
const jsDocRegex = /\/\*\*[\s\S]*?\*\//g;
|
|
66
|
-
const matches = result.match(jsDocRegex) || [];
|
|
67
|
-
jsDocComments.push(...matches);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Step 2: Remove comments if configured
|
|
71
|
-
if (this.config.removeComments) {
|
|
72
|
-
// Remove single-line comments
|
|
73
|
-
result = result.replace(/\/\/.*$/gm, '');
|
|
74
|
-
// Remove multi-line comments (except JSDoc if preserveJSDoc is true)
|
|
75
|
-
if (!this.config.preserveJSDoc) {
|
|
76
|
-
result = result.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
77
|
-
} else {
|
|
78
|
-
// Only remove non-JSDoc comments
|
|
79
|
-
result = result.replace(/\/\*(?!\*)[\s\S]*?\*\//g, '');
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Step 3: Remove function implementations if configured
|
|
84
|
-
if (this.config.removeImplementations) {
|
|
85
|
-
// Match function and method bodies
|
|
86
|
-
result = result.replace(
|
|
87
|
-
/(\b(function|constructor|async function)\s+[\w$]*\s*\([^)]*\)\s*{)([\s\S]*?)(})/g,
|
|
88
|
-
(match, start, funcType, body, end) => {
|
|
89
|
-
// Keep function signature and opening brace, replace body with comment
|
|
90
|
-
return `${start} /* implementation removed */ ${end}`;
|
|
91
|
-
}
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
// Match arrow function bodies
|
|
95
|
-
result = result.replace(
|
|
96
|
-
/(\([^)]*\)\s*=>\s*{)([\s\S]*?)(})/g,
|
|
97
|
-
(match, start, body, end) => {
|
|
98
|
-
return `${start} /* implementation removed */ ${end}`;
|
|
99
|
-
}
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
// Match method declarations
|
|
103
|
-
result = result.replace(
|
|
104
|
-
/(^\s*[\w$]*\s*\([^)]*\)\s*{)([\s\S]*?)(})/gm,
|
|
105
|
-
(match, start, body, end) => {
|
|
106
|
-
return `${start} /* implementation removed */ ${end}`;
|
|
107
|
-
}
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
// Match class methods
|
|
111
|
-
result = result.replace(
|
|
112
|
-
/(\b(public|private|protected|static|async)?\s+[\w$]+\s*\([^)]*\)\s*{)([\s\S]*?)(})/g,
|
|
113
|
-
(match, start, modifier, body, end) => {
|
|
114
|
-
return `${start} /* implementation removed */ ${end}`;
|
|
115
|
-
}
|
|
116
|
-
);
|
|
117
|
-
} else if (this.config.maxFunctionLines && this.config.maxFunctionLines > 0) {
|
|
118
|
-
// If not removing implementations completely, limit the number of lines
|
|
119
|
-
// Match function and method bodies
|
|
120
|
-
result = result.replace(
|
|
121
|
-
/(\b(function|constructor|async function)\s+[\w$]*\s*\([^)]*\)\s*{)([\s\S]*?)(})/g,
|
|
122
|
-
(match, start, funcType, body, end) => {
|
|
123
|
-
return this.limitFunctionBody(start, body, end);
|
|
124
|
-
}
|
|
125
|
-
);
|
|
126
|
-
|
|
127
|
-
// Match arrow function bodies
|
|
128
|
-
result = result.replace(
|
|
129
|
-
/(\([^)]*\)\s*=>\s*{)([\s\S]*?)(})/g,
|
|
130
|
-
(match, start, body, end) => {
|
|
131
|
-
return this.limitFunctionBody(start, body, end);
|
|
132
|
-
}
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
// Match method declarations
|
|
136
|
-
result = result.replace(
|
|
137
|
-
/(^\s*[\w$]*\s*\([^)]*\)\s*{)([\s\S]*?)(})/gm,
|
|
138
|
-
(match, start, body, end) => {
|
|
139
|
-
return this.limitFunctionBody(start, body, end);
|
|
140
|
-
}
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
// Match class methods
|
|
144
|
-
result = result.replace(
|
|
145
|
-
/(\b(public|private|protected|static|async)?\s+[\w$]+\s*\([^)]*\)\s*{)([\s\S]*?)(})/g,
|
|
146
|
-
(match, start, modifier, body, end) => {
|
|
147
|
-
return this.limitFunctionBody(start, body, end);
|
|
148
|
-
}
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Step 4: Remove blank lines if configured
|
|
153
|
-
if (this.config.removeBlankLines) {
|
|
154
|
-
result = result.replace(/^\s*[\r\n]/gm, '');
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Step 5: Restore preserved JSDoc comments
|
|
158
|
-
if (this.config.preserveJSDoc && jsDocComments.length > 0) {
|
|
159
|
-
// This is a placeholder; we already preserved JSDoc comments in the regex steps
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return result;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Limit a function body to a maximum number of lines
|
|
167
|
-
* @param start The function signature and opening brace
|
|
168
|
-
* @param body The function body
|
|
169
|
-
* @param end The closing brace
|
|
170
|
-
* @returns The limited function body
|
|
171
|
-
*/
|
|
172
|
-
private limitFunctionBody(start: string, body: string, end: string): string {
|
|
173
|
-
const lines = body.split('\n');
|
|
174
|
-
if (lines.length > this.config.maxFunctionLines!) {
|
|
175
|
-
const limitedBody = lines.slice(0, this.config.maxFunctionLines!).join('\n');
|
|
176
|
-
return `${start}${limitedBody}\n // ... (${lines.length - this.config.maxFunctionLines!} lines trimmed)\n${end}`;
|
|
177
|
-
}
|
|
178
|
-
return `${start}${body}${end}`;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Trim a Markdown file to reduce token usage
|
|
183
|
-
* @param content The Markdown file contents
|
|
184
|
-
* @returns The trimmed file contents
|
|
185
|
-
*/
|
|
186
|
-
private trimMarkdownFile(content: string): string {
|
|
187
|
-
// For markdown files, we generally want to keep most content
|
|
188
|
-
// but we can remove lengthy code blocks if needed
|
|
189
|
-
return content;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Trim a JSON file to reduce token usage
|
|
194
|
-
* @param content The JSON file contents
|
|
195
|
-
* @returns The trimmed file contents
|
|
196
|
-
*/
|
|
197
|
-
private trimJsonFile(content: string): string {
|
|
198
|
-
try {
|
|
199
|
-
// Parse the JSON
|
|
200
|
-
const json = JSON.parse(content);
|
|
201
|
-
|
|
202
|
-
// For package.json, keep only essential information
|
|
203
|
-
if ('name' in json && 'version' in json && 'dependencies' in json) {
|
|
204
|
-
const essentialKeys = [
|
|
205
|
-
'name', 'version', 'description', 'author', 'license',
|
|
206
|
-
'main', 'types', 'exports', 'type'
|
|
207
|
-
];
|
|
208
|
-
|
|
209
|
-
const trimmedJson: any = {};
|
|
210
|
-
essentialKeys.forEach(key => {
|
|
211
|
-
if (key in json) {
|
|
212
|
-
trimmedJson[key] = json[key];
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
// Add dependency information without versions
|
|
217
|
-
if ('dependencies' in json) {
|
|
218
|
-
trimmedJson.dependencies = Object.keys(json.dependencies).reduce((acc, dep) => {
|
|
219
|
-
acc[dep] = '*'; // Replace version with wildcard
|
|
220
|
-
return acc;
|
|
221
|
-
}, {} as Record<string, string>);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Return the trimmed JSON
|
|
225
|
-
return JSON.stringify(trimmedJson, null, 2);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// For other JSON files, leave as is
|
|
229
|
-
return content;
|
|
230
|
-
} catch (error) {
|
|
231
|
-
// If there's an error parsing the JSON, return the original content
|
|
232
|
-
return content;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Update the trimmer configuration
|
|
238
|
-
* @param config The new configuration to apply
|
|
239
|
-
*/
|
|
240
|
-
public updateConfig(config: ITrimConfig): void {
|
|
241
|
-
this.config = {
|
|
242
|
-
...this.config,
|
|
243
|
-
...config
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Trim a file based on its importance tier
|
|
249
|
-
* @param filePath The path to the file
|
|
250
|
-
* @param content The file's contents
|
|
251
|
-
* @param level The trimming level to apply ('none', 'light', 'aggressive')
|
|
252
|
-
* @returns The trimmed file contents
|
|
253
|
-
*/
|
|
254
|
-
public trimFileWithLevel(
|
|
255
|
-
filePath: string,
|
|
256
|
-
content: string,
|
|
257
|
-
level: 'none' | 'light' | 'aggressive'
|
|
258
|
-
): string {
|
|
259
|
-
// No trimming for essential files
|
|
260
|
-
if (level === 'none') {
|
|
261
|
-
return content;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Create a temporary config based on level
|
|
265
|
-
const originalConfig = { ...this.config };
|
|
266
|
-
|
|
267
|
-
try {
|
|
268
|
-
if (level === 'light') {
|
|
269
|
-
// Light trimming: preserve signatures, remove only complex implementations
|
|
270
|
-
this.config = {
|
|
271
|
-
...this.config,
|
|
272
|
-
removeImplementations: false,
|
|
273
|
-
preserveInterfaces: true,
|
|
274
|
-
preserveTypeDefs: true,
|
|
275
|
-
preserveJSDoc: true,
|
|
276
|
-
maxFunctionLines: 10,
|
|
277
|
-
removeComments: false,
|
|
278
|
-
removeBlankLines: true
|
|
279
|
-
};
|
|
280
|
-
} else if (level === 'aggressive') {
|
|
281
|
-
// Aggressive trimming: remove all implementations, keep only signatures
|
|
282
|
-
this.config = {
|
|
283
|
-
...this.config,
|
|
284
|
-
removeImplementations: true,
|
|
285
|
-
preserveInterfaces: true,
|
|
286
|
-
preserveTypeDefs: true,
|
|
287
|
-
preserveJSDoc: true,
|
|
288
|
-
maxFunctionLines: 3,
|
|
289
|
-
removeComments: true,
|
|
290
|
-
removeBlankLines: true
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// Process based on file type
|
|
295
|
-
let result = content;
|
|
296
|
-
if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {
|
|
297
|
-
result = this.trimTypeScriptFile(content);
|
|
298
|
-
} else if (filePath.endsWith('.md')) {
|
|
299
|
-
result = this.trimMarkdownFile(content);
|
|
300
|
-
} else if (filePath.endsWith('.json')) {
|
|
301
|
-
result = this.trimJsonFile(content);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
return result;
|
|
305
|
-
} finally {
|
|
306
|
-
// Restore original config
|
|
307
|
-
this.config = originalConfig;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
@@ -1,332 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../plugins.js';
|
|
2
|
-
import type { ContextMode, IContextResult, IFileInfo, TaskType, IFileMetadata } from './types.js';
|
|
3
|
-
import { ContextTrimmer } from './context-trimmer.js';
|
|
4
|
-
import { ConfigManager } from './config-manager.js';
|
|
5
|
-
import { LazyFileLoader } from './lazy-file-loader.js';
|
|
6
|
-
import { ContextCache } from './context-cache.js';
|
|
7
|
-
import { ContextAnalyzer } from './context-analyzer.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Enhanced ProjectContext that supports context optimization strategies
|
|
11
|
-
*/
|
|
12
|
-
export class EnhancedContext {
|
|
13
|
-
private projectDir: string;
|
|
14
|
-
private trimmer: ContextTrimmer;
|
|
15
|
-
private configManager: ConfigManager;
|
|
16
|
-
private lazyLoader: LazyFileLoader;
|
|
17
|
-
private cache: ContextCache;
|
|
18
|
-
private analyzer: ContextAnalyzer;
|
|
19
|
-
private contextMode: ContextMode = 'trimmed';
|
|
20
|
-
private tokenBudget: number = 190000; // Default for o4-mini
|
|
21
|
-
private contextResult: IContextResult = {
|
|
22
|
-
context: '',
|
|
23
|
-
tokenCount: 0,
|
|
24
|
-
includedFiles: [],
|
|
25
|
-
trimmedFiles: [],
|
|
26
|
-
excludedFiles: [],
|
|
27
|
-
tokenSavings: 0
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Create a new EnhancedContext
|
|
32
|
-
* @param projectDirArg The project directory
|
|
33
|
-
*/
|
|
34
|
-
constructor(projectDirArg: string) {
|
|
35
|
-
this.projectDir = projectDirArg;
|
|
36
|
-
this.configManager = ConfigManager.getInstance();
|
|
37
|
-
this.trimmer = new ContextTrimmer(this.configManager.getTrimConfig());
|
|
38
|
-
this.lazyLoader = new LazyFileLoader(projectDirArg);
|
|
39
|
-
this.cache = new ContextCache(projectDirArg, this.configManager.getCacheConfig());
|
|
40
|
-
this.analyzer = new ContextAnalyzer(
|
|
41
|
-
projectDirArg,
|
|
42
|
-
this.configManager.getPrioritizationWeights(),
|
|
43
|
-
this.configManager.getTierConfig()
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Initialize the context builder
|
|
49
|
-
*/
|
|
50
|
-
public async initialize(): Promise<void> {
|
|
51
|
-
await this.configManager.initialize(this.projectDir);
|
|
52
|
-
this.tokenBudget = this.configManager.getMaxTokens();
|
|
53
|
-
this.trimmer.updateConfig(this.configManager.getTrimConfig());
|
|
54
|
-
await this.cache.init();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Set the context mode
|
|
59
|
-
* @param mode The context mode to use
|
|
60
|
-
*/
|
|
61
|
-
public setContextMode(mode: ContextMode): void {
|
|
62
|
-
this.contextMode = mode;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Set the token budget
|
|
67
|
-
* @param maxTokens The maximum tokens to use
|
|
68
|
-
*/
|
|
69
|
-
public setTokenBudget(maxTokens: number): void {
|
|
70
|
-
this.tokenBudget = maxTokens;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Convert files to context with smart analysis and prioritization
|
|
75
|
-
* @param metadata - File metadata to analyze
|
|
76
|
-
* @param taskType - Task type for context-aware prioritization
|
|
77
|
-
* @param mode - Context mode to use
|
|
78
|
-
* @returns Context string
|
|
79
|
-
*/
|
|
80
|
-
public async convertFilesToContextWithAnalysis(
|
|
81
|
-
metadata: IFileMetadata[],
|
|
82
|
-
taskType: TaskType,
|
|
83
|
-
mode: ContextMode = this.contextMode
|
|
84
|
-
): Promise<string> {
|
|
85
|
-
// Reset context result
|
|
86
|
-
this.contextResult = {
|
|
87
|
-
context: '',
|
|
88
|
-
tokenCount: 0,
|
|
89
|
-
includedFiles: [],
|
|
90
|
-
trimmedFiles: [],
|
|
91
|
-
excludedFiles: [],
|
|
92
|
-
tokenSavings: 0
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
// Analyze files for smart prioritization
|
|
96
|
-
const analysis = await this.analyzer.analyze(metadata, taskType, []);
|
|
97
|
-
|
|
98
|
-
// Sort files by importance score (highest first)
|
|
99
|
-
const sortedAnalysis = [...analysis.files].sort(
|
|
100
|
-
(a, b) => b.importanceScore - a.importanceScore
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
// Filter out excluded tier
|
|
104
|
-
const relevantFiles = sortedAnalysis.filter(f => f.tier !== 'excluded');
|
|
105
|
-
|
|
106
|
-
let totalTokenCount = 0;
|
|
107
|
-
let totalOriginalTokens = 0;
|
|
108
|
-
const processedFiles: string[] = [];
|
|
109
|
-
|
|
110
|
-
// Load files with cache support
|
|
111
|
-
for (const fileAnalysis of relevantFiles) {
|
|
112
|
-
try {
|
|
113
|
-
// Check cache first
|
|
114
|
-
let contents: string;
|
|
115
|
-
let originalTokenCount: number;
|
|
116
|
-
|
|
117
|
-
const cached = await this.cache.get(fileAnalysis.path);
|
|
118
|
-
if (cached) {
|
|
119
|
-
contents = cached.contents;
|
|
120
|
-
originalTokenCount = cached.tokenCount;
|
|
121
|
-
} else {
|
|
122
|
-
// Load file
|
|
123
|
-
const fileData = await plugins.fsInstance.file(fileAnalysis.path).encoding('utf8').read() as string;
|
|
124
|
-
contents = fileData;
|
|
125
|
-
originalTokenCount = this.countTokens(contents);
|
|
126
|
-
|
|
127
|
-
// Cache it
|
|
128
|
-
await this.cache.set({
|
|
129
|
-
path: fileAnalysis.path,
|
|
130
|
-
contents,
|
|
131
|
-
tokenCount: originalTokenCount,
|
|
132
|
-
mtime: Date.now(),
|
|
133
|
-
cachedAt: Date.now()
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
totalOriginalTokens += originalTokenCount;
|
|
138
|
-
|
|
139
|
-
// Apply tier-based trimming
|
|
140
|
-
let processedContent = contents;
|
|
141
|
-
let trimLevel: 'none' | 'light' | 'aggressive' = 'light';
|
|
142
|
-
|
|
143
|
-
if (fileAnalysis.tier === 'essential') {
|
|
144
|
-
trimLevel = 'none';
|
|
145
|
-
} else if (fileAnalysis.tier === 'important') {
|
|
146
|
-
trimLevel = 'light';
|
|
147
|
-
} else if (fileAnalysis.tier === 'optional') {
|
|
148
|
-
trimLevel = 'aggressive';
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Apply trimming based on mode and tier
|
|
152
|
-
if (mode !== 'full' && trimLevel !== 'none') {
|
|
153
|
-
const relativePath = plugins.path.relative(this.projectDir, fileAnalysis.path);
|
|
154
|
-
processedContent = this.trimmer.trimFileWithLevel(
|
|
155
|
-
relativePath,
|
|
156
|
-
contents,
|
|
157
|
-
trimLevel
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Calculate token count
|
|
162
|
-
const processedTokenCount = this.countTokens(processedContent);
|
|
163
|
-
|
|
164
|
-
// Check token budget
|
|
165
|
-
if (totalTokenCount + processedTokenCount > this.tokenBudget) {
|
|
166
|
-
// We don't have budget for this file
|
|
167
|
-
const relativePath = plugins.path.relative(this.projectDir, fileAnalysis.path);
|
|
168
|
-
this.contextResult.excludedFiles.push({
|
|
169
|
-
path: fileAnalysis.path,
|
|
170
|
-
contents,
|
|
171
|
-
relativePath,
|
|
172
|
-
tokenCount: originalTokenCount,
|
|
173
|
-
importanceScore: fileAnalysis.importanceScore
|
|
174
|
-
});
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Format the file for context
|
|
179
|
-
const relativePath = plugins.path.relative(this.projectDir, fileAnalysis.path);
|
|
180
|
-
const formattedContent = `
|
|
181
|
-
====== START OF FILE ${relativePath} ======
|
|
182
|
-
|
|
183
|
-
${processedContent}
|
|
184
|
-
|
|
185
|
-
====== END OF FILE ${relativePath} ======
|
|
186
|
-
`;
|
|
187
|
-
|
|
188
|
-
processedFiles.push(formattedContent);
|
|
189
|
-
totalTokenCount += processedTokenCount;
|
|
190
|
-
|
|
191
|
-
// Track file in appropriate list
|
|
192
|
-
const fileInfo: IFileInfo = {
|
|
193
|
-
path: fileAnalysis.path,
|
|
194
|
-
contents: processedContent,
|
|
195
|
-
relativePath,
|
|
196
|
-
tokenCount: processedTokenCount,
|
|
197
|
-
importanceScore: fileAnalysis.importanceScore
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
if (trimLevel === 'none' || processedContent === contents) {
|
|
201
|
-
this.contextResult.includedFiles.push(fileInfo);
|
|
202
|
-
} else {
|
|
203
|
-
this.contextResult.trimmedFiles.push(fileInfo);
|
|
204
|
-
this.contextResult.tokenSavings += (originalTokenCount - processedTokenCount);
|
|
205
|
-
}
|
|
206
|
-
} catch (error) {
|
|
207
|
-
console.warn(`Failed to process file ${fileAnalysis.path}:`, error.message);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// Join all processed files
|
|
212
|
-
const context = processedFiles.join('\n');
|
|
213
|
-
|
|
214
|
-
// Update context result
|
|
215
|
-
this.contextResult.context = context;
|
|
216
|
-
this.contextResult.tokenCount = totalTokenCount;
|
|
217
|
-
|
|
218
|
-
return context;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Build context for the project using smart analysis
|
|
223
|
-
* @param taskType Task type for context-aware prioritization (defaults to 'description')
|
|
224
|
-
*/
|
|
225
|
-
public async buildContext(taskType?: TaskType): Promise<IContextResult> {
|
|
226
|
-
// Initialize if needed
|
|
227
|
-
if (this.tokenBudget === 0) {
|
|
228
|
-
await this.initialize();
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Smart context building always requires a task type for optimal prioritization
|
|
232
|
-
// Default to 'description' if not provided
|
|
233
|
-
const effectiveTaskType = taskType || 'description';
|
|
234
|
-
|
|
235
|
-
// Get task-specific configuration
|
|
236
|
-
const taskConfig = this.configManager.getTaskConfig(effectiveTaskType);
|
|
237
|
-
if (taskConfig.mode) {
|
|
238
|
-
this.setContextMode(taskConfig.mode);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// Build globs for scanning
|
|
242
|
-
const includeGlobs = taskConfig?.includePaths?.map(p => `${p}/**/*.ts`) || [
|
|
243
|
-
'ts/**/*.ts',
|
|
244
|
-
'ts*/**/*.ts'
|
|
245
|
-
];
|
|
246
|
-
|
|
247
|
-
// Add config files
|
|
248
|
-
const configGlobs = [
|
|
249
|
-
'package.json',
|
|
250
|
-
'readme.md',
|
|
251
|
-
'readme.hints.md',
|
|
252
|
-
'npmextra.json'
|
|
253
|
-
];
|
|
254
|
-
|
|
255
|
-
// Scan files for metadata (fast, doesn't load contents)
|
|
256
|
-
const metadata = await this.lazyLoader.scanFiles([...configGlobs, ...includeGlobs]);
|
|
257
|
-
|
|
258
|
-
// Use smart analyzer to build context with intelligent prioritization
|
|
259
|
-
await this.convertFilesToContextWithAnalysis(metadata, effectiveTaskType, this.contextMode);
|
|
260
|
-
|
|
261
|
-
return this.contextResult;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* Update the context with git diff information for commit tasks
|
|
266
|
-
* @param gitDiff The git diff to include
|
|
267
|
-
*/
|
|
268
|
-
public updateWithGitDiff(gitDiff: string): IContextResult {
|
|
269
|
-
// If we don't have a context yet, return empty result
|
|
270
|
-
if (!this.contextResult.context) {
|
|
271
|
-
return this.contextResult;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// Add git diff to context
|
|
275
|
-
const diffSection = `
|
|
276
|
-
====== GIT DIFF ======
|
|
277
|
-
|
|
278
|
-
${gitDiff}
|
|
279
|
-
|
|
280
|
-
====== END GIT DIFF ======
|
|
281
|
-
`;
|
|
282
|
-
|
|
283
|
-
const diffTokenCount = this.countTokens(diffSection);
|
|
284
|
-
|
|
285
|
-
// Update context and token count
|
|
286
|
-
this.contextResult.context += diffSection;
|
|
287
|
-
this.contextResult.tokenCount += diffTokenCount;
|
|
288
|
-
|
|
289
|
-
return this.contextResult;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Count tokens in a string
|
|
294
|
-
* @param text The text to count tokens for
|
|
295
|
-
* @param model The model to use for token counting
|
|
296
|
-
*/
|
|
297
|
-
public countTokens(text: string, model: string = 'gpt-3.5-turbo'): number {
|
|
298
|
-
try {
|
|
299
|
-
// Use the gpt-tokenizer library to count tokens
|
|
300
|
-
const tokens = plugins.gptTokenizer.encode(text);
|
|
301
|
-
return tokens.length;
|
|
302
|
-
} catch (error) {
|
|
303
|
-
console.error('Error counting tokens:', error);
|
|
304
|
-
// Provide a rough estimate if tokenization fails
|
|
305
|
-
return Math.ceil(text.length / 4);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Get the context result
|
|
311
|
-
*/
|
|
312
|
-
public getContextResult(): IContextResult {
|
|
313
|
-
return this.contextResult;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* Get the token count for the current context
|
|
318
|
-
*/
|
|
319
|
-
public getTokenCount(): number {
|
|
320
|
-
return this.contextResult.tokenCount;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Get both the context string and its token count
|
|
325
|
-
*/
|
|
326
|
-
public getContextWithTokenCount(): { context: string; tokenCount: number } {
|
|
327
|
-
return {
|
|
328
|
-
context: this.contextResult.context,
|
|
329
|
-
tokenCount: this.contextResult.tokenCount
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
}
|
package/ts/context/index.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { EnhancedContext } from './enhanced-context.js';
|
|
2
|
-
import { TaskContextFactory } from './task-context-factory.js';
|
|
3
|
-
import { ConfigManager } from './config-manager.js';
|
|
4
|
-
import { ContextTrimmer } from './context-trimmer.js';
|
|
5
|
-
import { LazyFileLoader } from './lazy-file-loader.js';
|
|
6
|
-
import { ContextCache } from './context-cache.js';
|
|
7
|
-
import { ContextAnalyzer } from './context-analyzer.js';
|
|
8
|
-
import { DiffProcessor } from './diff-processor.js';
|
|
9
|
-
import type {
|
|
10
|
-
ContextMode,
|
|
11
|
-
IContextConfig,
|
|
12
|
-
IContextResult,
|
|
13
|
-
IFileInfo,
|
|
14
|
-
ITrimConfig,
|
|
15
|
-
ITaskConfig,
|
|
16
|
-
TaskType,
|
|
17
|
-
ICacheConfig,
|
|
18
|
-
IAnalyzerConfig,
|
|
19
|
-
IPrioritizationWeights,
|
|
20
|
-
ITierConfig,
|
|
21
|
-
ITierSettings,
|
|
22
|
-
IFileMetadata,
|
|
23
|
-
ICacheEntry,
|
|
24
|
-
IFileDependencies,
|
|
25
|
-
IFileAnalysis,
|
|
26
|
-
IAnalysisResult,
|
|
27
|
-
IIterativeConfig,
|
|
28
|
-
IIterativeContextResult,
|
|
29
|
-
IDiffFileInfo,
|
|
30
|
-
IProcessedDiff,
|
|
31
|
-
IDiffProcessorOptions
|
|
32
|
-
} from './types.js';
|
|
33
|
-
|
|
34
|
-
export {
|
|
35
|
-
// Classes
|
|
36
|
-
EnhancedContext,
|
|
37
|
-
TaskContextFactory,
|
|
38
|
-
ConfigManager,
|
|
39
|
-
ContextTrimmer,
|
|
40
|
-
LazyFileLoader,
|
|
41
|
-
ContextCache,
|
|
42
|
-
ContextAnalyzer,
|
|
43
|
-
DiffProcessor,
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
// Types
|
|
47
|
-
export type {
|
|
48
|
-
ContextMode,
|
|
49
|
-
IContextConfig,
|
|
50
|
-
IContextResult,
|
|
51
|
-
IFileInfo,
|
|
52
|
-
ITrimConfig,
|
|
53
|
-
ITaskConfig,
|
|
54
|
-
TaskType,
|
|
55
|
-
ICacheConfig,
|
|
56
|
-
IAnalyzerConfig,
|
|
57
|
-
IPrioritizationWeights,
|
|
58
|
-
ITierConfig,
|
|
59
|
-
ITierSettings,
|
|
60
|
-
IFileMetadata,
|
|
61
|
-
ICacheEntry,
|
|
62
|
-
IFileDependencies,
|
|
63
|
-
IFileAnalysis,
|
|
64
|
-
IAnalysisResult,
|
|
65
|
-
IIterativeConfig,
|
|
66
|
-
IIterativeContextResult,
|
|
67
|
-
IDiffFileInfo,
|
|
68
|
-
IProcessedDiff,
|
|
69
|
-
IDiffProcessorOptions
|
|
70
|
-
};
|