@git.zone/tsdoc 1.8.2 → 1.9.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.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@git.zone/tsdoc',
6
- version: '1.8.0',
6
+ version: '1.9.0',
7
7
  description: 'A comprehensive TypeScript documentation tool that leverages AI to generate and enhance project documentation, including dynamic README creation, API docs via TypeDoc, and smart commit message generation.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxpQkFBaUI7SUFDdkIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLDhNQUE4TTtDQUM1TixDQUFBIn0=
@@ -1,6 +1,7 @@
1
1
  import * as plugins from '../plugins.js';
2
2
  import { AiDoc } from '../classes.aidoc.js';
3
3
  import { ProjectContext } from './projectcontext.js';
4
+ import { DiffProcessor } from '../context/diff-processor.js';
4
5
  export class Commit {
5
6
  constructor(aiDocsRef, projectDirArg) {
6
7
  this.aiDocsRef = aiDocsRef;
@@ -10,23 +11,84 @@ export class Commit {
10
11
  const smartgitInstance = new plugins.smartgit.Smartgit();
11
12
  await smartgitInstance.init();
12
13
  const gitRepo = await plugins.smartgit.GitRepo.fromOpeningRepoDir(smartgitInstance, this.projectDir);
13
- const diffStringArray = await gitRepo.getUncommittedDiff([
14
+ // Define comprehensive exclusion patterns
15
+ // smartgit@3.3.0+ supports glob patterns natively
16
+ const excludePatterns = [
17
+ // Lock files
14
18
  'pnpm-lock.yaml',
15
19
  'package-lock.json',
16
20
  'npm-shrinkwrap.json',
17
21
  'yarn.lock',
18
22
  'deno.lock',
19
23
  'bun.lockb',
20
- '.claude/*',
21
- '.cursor/*',
22
- '.vscode/*',
23
- '.idea/*',
24
- ]);
24
+ // Build artifacts (main culprit for large diffs!)
25
+ 'dist/**',
26
+ 'dist_*/**', // dist_ts, dist_web, etc.
27
+ 'build/**',
28
+ '.next/**',
29
+ 'out/**',
30
+ 'public/dist/**',
31
+ // Compiled/bundled files
32
+ '**/*.js.map',
33
+ '**/*.d.ts.map',
34
+ '**/*.min.js',
35
+ '**/*.bundle.js',
36
+ '**/*.chunk.js',
37
+ // IDE/Editor directories
38
+ '.claude/**',
39
+ '.cursor/**',
40
+ '.vscode/**',
41
+ '.idea/**',
42
+ '**/*.swp',
43
+ '**/*.swo',
44
+ // Logs and caches
45
+ '.nogit/**',
46
+ '**/*.log',
47
+ '.cache/**',
48
+ '.rpt2_cache/**',
49
+ 'coverage/**',
50
+ '.nyc_output/**',
51
+ ];
52
+ // Pass glob patterns directly to smartgit - it handles matching internally
53
+ const diffStringArray = await gitRepo.getUncommittedDiff(excludePatterns);
54
+ // Process diffs intelligently using DiffProcessor
55
+ let processedDiffString;
56
+ if (diffStringArray.length > 0) {
57
+ // Diagnostic logging for raw diff statistics
58
+ const totalChars = diffStringArray.join('\n\n').length;
59
+ const estimatedTokens = Math.ceil(totalChars / 4);
60
+ console.log(`📊 Raw git diff statistics:`);
61
+ console.log(` Files changed: ${diffStringArray.length}`);
62
+ console.log(` Total characters: ${totalChars.toLocaleString()}`);
63
+ console.log(` Estimated tokens: ${estimatedTokens.toLocaleString()}`);
64
+ console.log(` Exclusion patterns: ${excludePatterns.length}`);
65
+ // Use DiffProcessor to intelligently handle large diffs
66
+ const diffProcessor = new DiffProcessor({
67
+ maxDiffTokens: 100000, // Reserve 100k tokens for diffs
68
+ smallFileLines: 50, // Include files <= 50 lines fully
69
+ mediumFileLines: 200, // Summarize files <= 200 lines
70
+ sampleHeadLines: 20, // Show first 20 lines
71
+ sampleTailLines: 20, // Show last 20 lines
72
+ });
73
+ const processedDiff = diffProcessor.processDiffs(diffStringArray);
74
+ processedDiffString = diffProcessor.formatForContext(processedDiff);
75
+ console.log(`📝 Processed diff statistics:`);
76
+ console.log(` Full diffs: ${processedDiff.fullDiffs.length} files`);
77
+ console.log(` Summarized: ${processedDiff.summarizedDiffs.length} files`);
78
+ console.log(` Metadata only: ${processedDiff.metadataOnly.length} files`);
79
+ console.log(` Final tokens: ${processedDiff.totalTokens.toLocaleString()}`);
80
+ if (estimatedTokens > 50000) {
81
+ console.log(`✅ DiffProcessor reduced token usage: ${estimatedTokens.toLocaleString()} → ${processedDiff.totalTokens.toLocaleString()}`);
82
+ }
83
+ }
84
+ else {
85
+ processedDiffString = 'No changes.';
86
+ }
25
87
  // Use the new TaskContextFactory for optimized context
26
88
  const taskContextFactory = new (await import('../context/index.js')).TaskContextFactory(this.projectDir, this.aiDocsRef.openaiInstance);
27
89
  await taskContextFactory.initialize();
28
90
  // Generate context specifically for commit task
29
- const contextResult = await taskContextFactory.createContextForCommit(diffStringArray[0] ? diffStringArray.join('\n\n') : 'No changes.');
91
+ const contextResult = await taskContextFactory.createContextForCommit(processedDiffString);
30
92
  // Get the optimized context string
31
93
  let contextString = contextResult.context;
32
94
  // Log token usage statistics
@@ -116,4 +178,4 @@ ${JSON.stringify(commitMessages, null, 2)}
116
178
  return resultObject;
117
179
  }
118
180
  }
119
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWl0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvYWlkb2NzX2NsYXNzZXMvY29tbWl0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM1QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFXckQsTUFBTSxPQUFPLE1BQU07SUFJakIsWUFBWSxTQUFnQixFQUFFLGFBQXFCO1FBQ2pELElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO1FBQzNCLElBQUksQ0FBQyxVQUFVLEdBQUcsYUFBYSxDQUFDO0lBQ2xDLENBQUM7SUFFTSxLQUFLLENBQUMscUJBQXFCO1FBQ2hDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3pELE1BQU0sZ0JBQWdCLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDOUIsTUFBTSxPQUFPLEdBQUcsTUFBTSxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FDL0QsZ0JBQWdCLEVBQ2hCLElBQUksQ0FBQyxVQUFVLENBQ2hCLENBQUM7UUFDRixNQUFNLGVBQWUsR0FBRyxNQUFNLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztZQUN2RCxnQkFBZ0I7WUFDaEIsbUJBQW1CO1lBQ25CLHFCQUFxQjtZQUNyQixXQUFXO1lBQ1gsV0FBVztZQUNYLFdBQVc7WUFDWCxXQUFXO1lBQ1gsV0FBVztZQUNYLFdBQVc7WUFDWCxTQUFTO1NBQ1YsQ0FBQyxDQUFDO1FBQ0gsdURBQXVEO1FBQ3ZELE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLE1BQU0sTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FDckYsSUFBSSxDQUFDLFVBQVUsRUFDZixJQUFJLENBQUMs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
181
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWl0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvYWlkb2NzX2NsYXNzZXMvY29tbWl0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM1QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDckQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBVzdELE1BQU0sT0FBTyxNQUFNO0lBSWpCLFlBQVksU0FBZ0IsRUFBRSxhQUFxQjtRQUNqRCxJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUMzQixJQUFJLENBQUMsVUFBVSxHQUFHLGFBQWEsQ0FBQztJQUNsQyxDQUFDO0lBRU0sS0FBSyxDQUFDLHFCQUFxQjtRQUNoQyxNQUFNLGdCQUFnQixHQUFHLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN6RCxNQUFNLGdCQUFnQixDQUFDLElBQUksRUFBRSxDQUFDO1FBQzlCLE1BQU0sT0FBTyxHQUFHLE1BQU0sT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQy9ELGdCQUFnQixFQUNoQixJQUFJLENBQUMsVUFBVSxDQUNoQixDQUFDO1FBRUYsMENBQTBDO1FBQzFDLGtEQUFrRDtRQUNsRCxNQUFNLGVBQWUsR0FBRztZQUN0QixhQUFhO1lBQ2IsZ0JBQWdCO1lBQ2hCLG1CQUFtQjtZQUNuQixxQkFBcUI7WUFDckIsV0FBVztZQUNYLFdBQVc7WUFDWCxXQUFXO1lBRVgsa0RBQWtEO1lBQ2xELFNBQVM7WUFDVCxXQUFXLEVBQVksMEJBQTBCO1lBQ2pELFVBQVU7WUFDVixVQUFVO1lBQ1YsUUFBUTtZQUNSLGdCQUFnQjtZQUVoQix5QkFBeUI7WUFDekIsYUFBYTtZQUNiLGVBQWU7WUFDZixh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
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Intelligent git diff processor that handles large diffs by sampling and prioritization
3
+ * instead of blind truncation.
4
+ */
5
+ export interface IDiffFileInfo {
6
+ filepath: string;
7
+ status: 'added' | 'modified' | 'deleted';
8
+ linesAdded: number;
9
+ linesRemoved: number;
10
+ totalLines: number;
11
+ estimatedTokens: number;
12
+ diffContent: string;
13
+ }
14
+ export interface IProcessedDiff {
15
+ summary: string;
16
+ fullDiffs: string[];
17
+ summarizedDiffs: string[];
18
+ metadataOnly: string[];
19
+ totalFiles: number;
20
+ totalTokens: number;
21
+ }
22
+ export interface IDiffProcessorOptions {
23
+ maxDiffTokens?: number;
24
+ smallFileLines?: number;
25
+ mediumFileLines?: number;
26
+ sampleHeadLines?: number;
27
+ sampleTailLines?: number;
28
+ }
29
+ export declare class DiffProcessor {
30
+ private options;
31
+ constructor(options?: IDiffProcessorOptions);
32
+ /**
33
+ * Process an array of git diffs into a structured, token-efficient format
34
+ */
35
+ processDiffs(diffStringArray: string[]): IProcessedDiff;
36
+ /**
37
+ * Format the processed diff for inclusion in context
38
+ */
39
+ formatForContext(processed: IProcessedDiff): string;
40
+ /**
41
+ * Parse a single git diff string into file information
42
+ */
43
+ private parseDiffFile;
44
+ /**
45
+ * Prioritize files by importance (source files before build artifacts)
46
+ */
47
+ private prioritizeFiles;
48
+ /**
49
+ * Calculate importance score for a file path
50
+ */
51
+ private getFileImportanceScore;
52
+ /**
53
+ * Extract head and tail lines from a diff, omitting the middle
54
+ */
55
+ private extractDiffSample;
56
+ /**
57
+ * Get file status prefix with emoji
58
+ */
59
+ private getFileStatusPrefix;
60
+ /**
61
+ * Extract filepath from diff content
62
+ */
63
+ private extractFilepathFromDiff;
64
+ /**
65
+ * Format file info as metadata only
66
+ */
67
+ private formatMetadataOnly;
68
+ /**
69
+ * Generate human-readable summary of processed diff
70
+ */
71
+ private generateSummary;
72
+ }
@@ -0,0 +1,275 @@
1
+ /**
2
+ * Intelligent git diff processor that handles large diffs by sampling and prioritization
3
+ * instead of blind truncation.
4
+ */
5
+ export class DiffProcessor {
6
+ constructor(options = {}) {
7
+ this.options = {
8
+ maxDiffTokens: options.maxDiffTokens ?? 100000,
9
+ smallFileLines: options.smallFileLines ?? 50,
10
+ mediumFileLines: options.mediumFileLines ?? 200,
11
+ sampleHeadLines: options.sampleHeadLines ?? 20,
12
+ sampleTailLines: options.sampleTailLines ?? 20,
13
+ };
14
+ }
15
+ /**
16
+ * Process an array of git diffs into a structured, token-efficient format
17
+ */
18
+ processDiffs(diffStringArray) {
19
+ // Parse all diffs into file info objects
20
+ const fileInfos = diffStringArray
21
+ .map(diffString => this.parseDiffFile(diffString))
22
+ .filter(info => info !== null);
23
+ // Prioritize files (source files first, build artifacts last)
24
+ const prioritized = this.prioritizeFiles(fileInfos);
25
+ const result = {
26
+ summary: '',
27
+ fullDiffs: [],
28
+ summarizedDiffs: [],
29
+ metadataOnly: [],
30
+ totalFiles: prioritized.length,
31
+ totalTokens: 0,
32
+ };
33
+ let tokensUsed = 0;
34
+ const tokenBudget = this.options.maxDiffTokens;
35
+ // Categorize and include files based on size and token budget
36
+ for (const fileInfo of prioritized) {
37
+ const remainingBudget = tokenBudget - tokensUsed;
38
+ if (remainingBudget <= 0) {
39
+ // Budget exhausted - rest are metadata only
40
+ result.metadataOnly.push(this.formatMetadataOnly(fileInfo));
41
+ continue;
42
+ }
43
+ if (fileInfo.totalLines <= this.options.smallFileLines) {
44
+ // Small file - include fully if budget allows
45
+ if (fileInfo.estimatedTokens <= remainingBudget) {
46
+ const statusPrefix = this.getFileStatusPrefix(fileInfo);
47
+ result.fullDiffs.push(`${statusPrefix}${fileInfo.diffContent}`);
48
+ tokensUsed += fileInfo.estimatedTokens;
49
+ }
50
+ else {
51
+ result.metadataOnly.push(this.formatMetadataOnly(fileInfo));
52
+ }
53
+ }
54
+ else if (fileInfo.totalLines <= this.options.mediumFileLines) {
55
+ // Medium file - try to include summary with head/tail
56
+ const summary = this.extractDiffSample(fileInfo, this.options.sampleHeadLines, this.options.sampleTailLines);
57
+ const summaryTokens = Math.ceil(summary.length / 4); // Rough estimate
58
+ if (summaryTokens <= remainingBudget) {
59
+ result.summarizedDiffs.push(summary);
60
+ tokensUsed += summaryTokens;
61
+ }
62
+ else {
63
+ result.metadataOnly.push(this.formatMetadataOnly(fileInfo));
64
+ }
65
+ }
66
+ else {
67
+ // Large file - metadata only
68
+ result.metadataOnly.push(this.formatMetadataOnly(fileInfo));
69
+ }
70
+ }
71
+ result.totalTokens = tokensUsed;
72
+ result.summary = this.generateSummary(result);
73
+ return result;
74
+ }
75
+ /**
76
+ * Format the processed diff for inclusion in context
77
+ */
78
+ formatForContext(processed) {
79
+ const sections = [];
80
+ // Summary section
81
+ sections.push('====== GIT DIFF SUMMARY ======');
82
+ sections.push(processed.summary);
83
+ sections.push('');
84
+ // Full diffs section
85
+ if (processed.fullDiffs.length > 0) {
86
+ sections.push(`====== FULL DIFFS (${processed.fullDiffs.length} files) ======`);
87
+ sections.push(processed.fullDiffs.join('\n\n'));
88
+ sections.push('');
89
+ }
90
+ // Summarized diffs section
91
+ if (processed.summarizedDiffs.length > 0) {
92
+ sections.push(`====== SUMMARIZED DIFFS (${processed.summarizedDiffs.length} files) ======`);
93
+ sections.push(processed.summarizedDiffs.join('\n\n'));
94
+ sections.push('');
95
+ }
96
+ // Metadata only section
97
+ if (processed.metadataOnly.length > 0) {
98
+ sections.push(`====== METADATA ONLY (${processed.metadataOnly.length} files) ======`);
99
+ sections.push(processed.metadataOnly.join('\n'));
100
+ sections.push('');
101
+ }
102
+ sections.push('====== END OF GIT DIFF ======');
103
+ return sections.join('\n');
104
+ }
105
+ /**
106
+ * Parse a single git diff string into file information
107
+ */
108
+ parseDiffFile(diffString) {
109
+ if (!diffString || diffString.trim().length === 0) {
110
+ return null;
111
+ }
112
+ const lines = diffString.split('\n');
113
+ let filepath = '';
114
+ let status = 'modified';
115
+ let linesAdded = 0;
116
+ let linesRemoved = 0;
117
+ // Parse diff header to extract filepath and status
118
+ for (const line of lines) {
119
+ if (line.startsWith('--- a/')) {
120
+ filepath = line.substring(6);
121
+ }
122
+ else if (line.startsWith('+++ b/')) {
123
+ const newPath = line.substring(6);
124
+ if (newPath === '/dev/null') {
125
+ status = 'deleted';
126
+ }
127
+ else if (filepath === '/dev/null') {
128
+ status = 'added';
129
+ filepath = newPath;
130
+ }
131
+ else {
132
+ filepath = newPath;
133
+ }
134
+ }
135
+ else if (line.startsWith('+') && !line.startsWith('+++')) {
136
+ linesAdded++;
137
+ }
138
+ else if (line.startsWith('-') && !line.startsWith('---')) {
139
+ linesRemoved++;
140
+ }
141
+ }
142
+ const totalLines = linesAdded + linesRemoved;
143
+ const estimatedTokens = Math.ceil(diffString.length / 4);
144
+ return {
145
+ filepath,
146
+ status,
147
+ linesAdded,
148
+ linesRemoved,
149
+ totalLines,
150
+ estimatedTokens,
151
+ diffContent: diffString,
152
+ };
153
+ }
154
+ /**
155
+ * Prioritize files by importance (source files before build artifacts)
156
+ */
157
+ prioritizeFiles(files) {
158
+ return files.sort((a, b) => {
159
+ const scoreA = this.getFileImportanceScore(a.filepath);
160
+ const scoreB = this.getFileImportanceScore(b.filepath);
161
+ return scoreB - scoreA; // Higher score first
162
+ });
163
+ }
164
+ /**
165
+ * Calculate importance score for a file path
166
+ */
167
+ getFileImportanceScore(filepath) {
168
+ // Source files - highest priority
169
+ if (filepath.match(/^(src|lib|app|components|pages|api)\//)) {
170
+ return 100;
171
+ }
172
+ // Test files - high priority
173
+ if (filepath.match(/\.(test|spec)\.(ts|js|tsx|jsx)$/) || filepath.startsWith('test/')) {
174
+ return 80;
175
+ }
176
+ // Configuration files - medium-high priority
177
+ if (filepath.match(/\.(json|yaml|yml|toml|config\.(ts|js))$/)) {
178
+ return 60;
179
+ }
180
+ // Documentation - medium priority
181
+ if (filepath.match(/\.(md|txt|rst)$/)) {
182
+ return 40;
183
+ }
184
+ // Build artifacts - low priority
185
+ if (filepath.match(/^(dist|build|out|\.next|public\/dist)\//)) {
186
+ return 10;
187
+ }
188
+ // Everything else - default priority
189
+ return 50;
190
+ }
191
+ /**
192
+ * Extract head and tail lines from a diff, omitting the middle
193
+ */
194
+ extractDiffSample(fileInfo, headLines, tailLines) {
195
+ const lines = fileInfo.diffContent.split('\n');
196
+ const totalLines = lines.length;
197
+ if (totalLines <= headLines + tailLines) {
198
+ // File is small enough to include fully
199
+ return fileInfo.diffContent;
200
+ }
201
+ // Extract file metadata from diff header
202
+ const headerLines = [];
203
+ let bodyStartIndex = 0;
204
+ for (let i = 0; i < lines.length; i++) {
205
+ if (lines[i].startsWith('@@')) {
206
+ headerLines.push(...lines.slice(0, i + 1));
207
+ bodyStartIndex = i + 1;
208
+ break;
209
+ }
210
+ }
211
+ const bodyLines = lines.slice(bodyStartIndex);
212
+ const head = bodyLines.slice(0, headLines);
213
+ const tail = bodyLines.slice(-tailLines);
214
+ const omittedLines = bodyLines.length - headLines - tailLines;
215
+ const statusEmoji = fileInfo.status === 'added' ? '➕' :
216
+ fileInfo.status === 'deleted' ? '➖' : '📝';
217
+ const parts = [];
218
+ parts.push(`${statusEmoji} FILE: ${fileInfo.filepath}`);
219
+ parts.push(`CHANGES: +${fileInfo.linesAdded} lines, -${fileInfo.linesRemoved} lines (${fileInfo.totalLines} total)`);
220
+ parts.push('');
221
+ parts.push(...headerLines);
222
+ parts.push(...head);
223
+ parts.push('');
224
+ parts.push(`[... ${omittedLines} lines omitted - use Read tool to see full file ...]`);
225
+ parts.push('');
226
+ parts.push(...tail);
227
+ return parts.join('\n');
228
+ }
229
+ /**
230
+ * Get file status prefix with emoji
231
+ */
232
+ getFileStatusPrefix(fileInfo) {
233
+ const statusEmoji = fileInfo.status === 'added' ? '➕' :
234
+ fileInfo.status === 'deleted' ? '➖' : '📝';
235
+ return `${statusEmoji} `;
236
+ }
237
+ /**
238
+ * Extract filepath from diff content
239
+ */
240
+ extractFilepathFromDiff(diffContent) {
241
+ const lines = diffContent.split('\n');
242
+ for (const line of lines) {
243
+ if (line.startsWith('+++ b/')) {
244
+ return line.substring(6);
245
+ }
246
+ }
247
+ return 'unknown';
248
+ }
249
+ /**
250
+ * Format file info as metadata only
251
+ */
252
+ formatMetadataOnly(fileInfo) {
253
+ const statusEmoji = fileInfo.status === 'added' ? '➕' :
254
+ fileInfo.status === 'deleted' ? '➖' : '📝';
255
+ return `${statusEmoji} ${fileInfo.filepath} (+${fileInfo.linesAdded}, -${fileInfo.linesRemoved})`;
256
+ }
257
+ /**
258
+ * Generate human-readable summary of processed diff
259
+ */
260
+ generateSummary(result) {
261
+ const parts = [];
262
+ parts.push(`Files changed: ${result.totalFiles} total`);
263
+ parts.push(`- ${result.fullDiffs.length} included in full`);
264
+ parts.push(`- ${result.summarizedDiffs.length} summarized (head/tail shown)`);
265
+ parts.push(`- ${result.metadataOnly.length} metadata only`);
266
+ parts.push(`Estimated tokens: ~${result.totalTokens.toLocaleString()}`);
267
+ if (result.metadataOnly.length > 0) {
268
+ parts.push('');
269
+ parts.push('NOTE: Some files excluded to stay within token budget.');
270
+ parts.push('Use Read tool with specific file paths to see full content.');
271
+ }
272
+ return parts.join('\n');
273
+ }
274
+ }
275
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlmZi1wcm9jZXNzb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9jb250ZXh0L2RpZmYtcHJvY2Vzc29yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQTZCSCxNQUFNLE9BQU8sYUFBYTtJQUd4QixZQUFZLFVBQWlDLEVBQUU7UUFDN0MsSUFBSSxDQUFDLE9BQU8sR0FBRztZQUNiLGFBQWEsRUFBRSxPQUFPLENBQUMsYUFBYSxJQUFJLE1BQU07WUFDOUMsY0FBYyxFQUFFLE9BQU8sQ0FBQyxjQUFjLElBQUksRUFBRTtZQUM1QyxlQUFlLEVBQUUsT0FBTyxDQUFDLGVBQWUsSUFBSSxHQUFHO1lBQy9DLGVBQWUsRUFBRSxPQUFPLENBQUMsZUFBZSxJQUFJLEVBQUU7WUFDOUMsZUFBZSxFQUFFLE9BQU8sQ0FBQyxlQUFlLElBQUksRUFBRTtTQUMvQyxDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0ksWUFBWSxDQUFDLGVBQXlCO1FBQzNDLHlDQUF5QztRQUN6QyxNQUFNLFNBQVMsR0FBb0IsZUFBZTthQUMvQyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQ2pELE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksS0FBSyxJQUFJLENBQW9CLENBQUM7UUFFcEQsOERBQThEO1FBQzlELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFcEQsTUFBTSxNQUFNLEdBQW1CO1lBQzdCLE9BQU8sRUFBRSxFQUFFO1lBQ1gsU0FBUyxFQUFFLEVBQUU7WUFDYixlQUFlLEVBQUUsRUFBRTtZQUNuQixZQUFZLEVBQUUsRUFBRTtZQUNoQixVQUFVLEVBQUUsV0FBVyxDQUFDLE1BQU07WUFDOUIsV0FBVyxFQUFFLENBQUM7U0FDZixDQUFDO1FBRUYsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDO1FBQ25CLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDO1FBRS9DLDhEQUE4RDtRQUM5RCxLQUFLLE1BQU0sUUFBUSxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQ25DLE1BQU0sZUFBZSxHQUFHLFdBQVcsR0FBRyxVQUFVLENBQUM7WUFFakQsSUFBSSxlQUFlLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ3pCLDRDQUE0QztnQkFDNUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7Z0JBQzVELFNBQVM7WUFDWCxDQUFDO1lBRUQsSUFBSSxRQUFRLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQ3ZELDhDQUE4QztnQkFDOUMsSUFBSSxRQUFRLENBQUMsZUFBZSxJQUFJLGVBQWUsRUFBRSxDQUFDO29CQUNoRCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQ3hELE1BQU0sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsWUFBWSxHQUFHLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO29CQUNoRSxVQUFVLElBQUksUUFBUSxDQUFDLGVBQWUsQ0FBQztnQkFDekMsQ0FBQztxQkFBTSxDQUFDO29CQUNOLE1BQU0sQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO2dCQUM5RCxDQUFDO1lBQ0gsQ0FBQztpQkFBTSxJQUFJLFFBQVEsQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDL0Qsc0RBQXNEO2dCQUN0RCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQ3BDLFFBQVEsRUFDUixJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFDNUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQzdCLENBQUM7Z0JBQ0YsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCO2dCQUV0RSxJQUFJLGFBQWEsSUFBSSxlQUFlLEVBQUUsQ0FBQztvQkFDckMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ3JDLFVBQVUsSUFBSSxhQUFhLENBQUM7Z0JBQzlCLENBQUM7cUJBQU0sQ0FBQztvQkFDTixNQUFNLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztnQkFDOUQsQ0FBQztZQUNILENBQUM7aUJBQU0sQ0FBQztnQkFDTiw2QkFBNkI7Z0JBQzdCLE1BQU0sQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQzlELENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxDQUFDLFdBQVcsR0FBRyxVQUFVLENBQUM7UUFDaEMsTUFBTSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTlDLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7T0FFRztJQUNJLGdCQUFnQixDQUFDLFNBQXlCO1FBQy9DLE1BQU0sUUFBUSxHQUFhLEVBQUUsQ0FBQztRQUU5QixrQkFBa0I7UUFDbEIsUUFBUSxDQUFDLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1FBQ2hELFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2pDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFbEIscUJBQXFCO1FBQ3JCLElBQUksU0FBUyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDbkMsUUFBUSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsU0FBUyxDQUFDLFNBQVMsQ0FBQyxNQUFNLGdCQUFnQixDQUFDLENBQUM7WUFDaEYsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ2hELFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDcEIsQ0FBQztRQUVELDJCQUEyQjtRQUMzQixJQUFJLFNBQVMsQ0FBQyxlQUFlLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3pDLFFBQVEsQ0FBQyxJQUFJLENBQUMsNEJBQTRCLFNBQVMsQ0FBQyxlQUFlLENBQUMsTUFBTSxnQkFBZ0IsQ0FBQyxDQUFDO1lBQzVGLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUN0RCxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3BCLENBQUM7UUFFRCx3QkFBd0I7UUFDeEIsSUFBSSxTQUFTLENBQUMsWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN0QyxRQUFRLENBQUMsSUFBSSxDQUFDLHlCQUF5QixTQUFTLENBQUMsWUFBWSxDQUFDLE1BQU0sZ0JBQWdCLENBQUMsQ0FBQztZQUN0RixRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDakQsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNwQixDQUFDO1FBRUQsUUFBUSxDQUFDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1FBRS9DLE9BQU8sUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBRUQ7O09BRUc7SUFDSyxhQUFhLENBQUMsVUFBa0I7UUFDdEMsSUFBSSxDQUFDLFVBQVUsSUFBSSxVQUFVLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ2xELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckMsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ2xCLElBQUksTUFBTSxHQUFxQyxVQUFVLENBQUM7UUFDMUQsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDO1FBQ25CLElBQUksWUFBWSxHQUFHLENBQUMsQ0FBQztRQUVyQixtREFBbUQ7UUFDbkQsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUN6QixJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDOUIsUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDL0IsQ0FBQztpQkFBTSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDckMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbEMsSUFBSSxPQUFPLEtBQUssV0FBVyxFQUFFLENBQUM7b0JBQzVCLE1BQU0sR0FBRyxTQUFTLENBQUM7Z0JBQ3JCLENBQUM7cUJBQU0sSUFBSSxRQUFRLEtBQUssV0FBVyxFQUFFLENBQUM7b0JBQ3BDLE1BQU0sR0FBRyxPQUFPLENBQUM7b0JBQ2pCLFFBQVEsR0FBRyxPQUFPLENBQUM7Z0JBQ3JCLENBQUM7cUJBQU0sQ0FBQztvQkFDTixRQUFRLEdBQUcsT0FBTyxDQUFDO2dCQUNyQixDQUFDO1lBQ0gsQ0FBQztpQkFBTSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQzNELFVBQVUsRUFBRSxDQUFDO1lBQ2YsQ0FBQztpQkFBTSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQzNELFlBQVksRUFBRSxDQUFDO1lBQ2pCLENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxVQUFVLEdBQUcsVUFBVSxHQUFHLFlBQVksQ0FBQztRQUM3QyxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFekQsT0FBTztZQUNMLFFBQVE7WUFDUixNQUFNO1lBQ04sVUFBVTtZQUNWLFlBQVk7WUFDWixVQUFVO1lBQ1YsZUFBZTtZQUNmLFdBQVcsRUFBRSxVQUFVO1NBQ3hCLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSyxlQUFlLENBQUMsS0FBc0I7UUFDNUMsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3pCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDdkQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN2RCxPQUFPLE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQyxxQkFBcUI7UUFDL0MsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxzQkFBc0IsQ0FBQyxRQUFnQjtRQUM3QyxrQ0FBa0M7UUFDbEMsSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLHVDQUF1QyxDQUFDLEVBQUUsQ0FBQztZQUM1RCxPQUFPLEdBQUcsQ0FBQztRQUNiLENBQUM7UUFFRCw2QkFBNkI7UUFDN0IsSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxDQUFDLElBQUksUUFBUSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ3RGLE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUVELDZDQUE2QztRQUM3QyxJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMseUNBQXlDLENBQUMsRUFBRSxDQUFDO1lBQzlELE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUVELGtDQUFrQztRQUNsQyxJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDO1lBQ3RDLE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUVELGlDQUFpQztRQUNqQyxJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMseUNBQXlDLENBQUMsRUFBRSxDQUFDO1lBQzlELE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUVELHFDQUFxQztRQUNyQyxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRDs7T0FFRztJQUNLLGlCQUFpQixDQUFDLFFBQXVCLEVBQUUsU0FBaUIsRUFBRSxTQUFpQjtRQUNyRixNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMvQyxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO1FBRWhDLElBQUksVUFBVSxJQUFJLFNBQVMsR0FBRyxTQUFTLEVBQUUsQ0FBQztZQUN4Qyx3Q0FBd0M7WUFDeEMsT0FBTyxRQUFRLENBQUMsV0FBVyxDQUFDO1FBQzlCLENBQUM7UUFFRCx5Q0FBeUM7UUFDekMsTUFBTSxXQUFXLEdBQWEsRUFBRSxDQUFDO1FBQ2pDLElBQUksY0FBYyxHQUFHLENBQUMsQ0FBQztRQUN2QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3RDLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUM5QixXQUFXLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNDLGNBQWMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUN2QixNQUFNO1lBQ1IsQ0FBQztRQUNILENBQUM7UUFFRCxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sSUFBSSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzNDLE1BQU0sSUFBSSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN6QyxNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsTUFBTSxHQUFHLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFFOUQsTUFBTSxXQUFXLEdBQUcsUUFBUSxDQUFDLE1BQU0sS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3BDLFFBQVEsQ0FBQyxNQUFNLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUU5RCxNQUFNLEtBQUssR0FBYSxFQUFFLENBQUM7UUFDM0IsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLFdBQVcsVUFBVSxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUN4RCxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsUUFBUSxDQUFDLFVBQVUsWUFBWSxRQUFRLENBQUMsWUFBWSxXQUFXLFFBQVEsQ0FBQyxVQUFVLFNBQVMsQ0FBQyxDQUFDO1FBQ3JILEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDZixLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsV0FBVyxDQUFDLENBQUM7UUFDM0IsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQ3BCLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDZixLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsWUFBWSxzREFBc0QsQ0FBQyxDQUFDO1FBQ3ZGLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDZixLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7UUFFcEIsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFCLENBQUM7SUFFRDs7T0FFRztJQUNLLG1CQUFtQixDQUFDLFFBQXVCO1FBQ2pELE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxNQUFNLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNwQyxRQUFRLENBQUMsTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDOUQsT0FBTyxHQUFHLFdBQVcsR0FBRyxDQUFDO0lBQzNCLENBQUM7SUFFRDs7T0FFRztJQUNLLHVCQUF1QixDQUFDLFdBQW1CO1FBQ2pELE1BQU0sS0FBSyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUN6QixJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDOUIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzNCLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVEOztPQUVHO0lBQ0ssa0JBQWtCLENBQUMsUUFBdUI7UUFDaEQsTUFBTSxXQUFXLEdBQUcsUUFBUSxDQUFDLE1BQU0sS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3BDLFFBQVEsQ0FBQyxNQUFNLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUM5RCxPQUFPLEdBQUcsV0FBVyxJQUFJLFFBQVEsQ0FBQyxRQUFRLE1BQU0sUUFBUSxDQUFDLFVBQVUsTUFBTSxRQUFRLENBQUMsWUFBWSxHQUFHLENBQUM7SUFDcEcsQ0FBQztJQUVEOztPQUVHO0lBQ0ssZUFBZSxDQUFDLE1BQXNCO1FBQzVDLE1BQU0sS0FBSyxHQUFhLEVBQUUsQ0FBQztRQUMzQixLQUFLLENBQUMsSUFBSSxDQUFDLGtCQUFrQixNQUFNLENBQUMsVUFBVSxRQUFRLENBQUMsQ0FBQztRQUN4RCxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLG1CQUFtQixDQUFDLENBQUM7UUFDNUQsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLE1BQU0sQ0FBQyxlQUFlLENBQUMsTUFBTSwrQkFBK0IsQ0FBQyxDQUFDO1FBQzlFLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxNQUFNLENBQUMsWUFBWSxDQUFDLE1BQU0sZ0JBQWdCLENBQUMsQ0FBQztRQUM1RCxLQUFLLENBQUMsSUFBSSxDQUFDLHNCQUFzQixNQUFNLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUV4RSxJQUFJLE1BQU0sQ0FBQyxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ25DLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDZixLQUFLLENBQUMsSUFBSSxDQUFDLHdEQUF3RCxDQUFDLENBQUM7WUFDckUsS0FBSyxDQUFDLElBQUksQ0FBQyw2REFBNkQsQ0FBQyxDQUFDO1FBQzVFLENBQUM7UUFFRCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDMUIsQ0FBQztDQUNGIn0=
@@ -5,6 +5,7 @@ import { ContextTrimmer } from './context-trimmer.js';
5
5
  import { LazyFileLoader } from './lazy-file-loader.js';
6
6
  import { ContextCache } from './context-cache.js';
7
7
  import { ContextAnalyzer } from './context-analyzer.js';
8
- import type { ContextMode, IContextConfig, IContextResult, IFileInfo, ITrimConfig, ITaskConfig, TaskType, ICacheConfig, IAnalyzerConfig, IPrioritizationWeights, ITierConfig, ITierSettings, IFileMetadata, ICacheEntry, IFileDependencies, IFileAnalysis, IAnalysisResult, IIterativeConfig, IIterativeContextResult } from './types.js';
9
- export { EnhancedContext, TaskContextFactory, ConfigManager, ContextTrimmer, LazyFileLoader, ContextCache, ContextAnalyzer, };
10
- export type { ContextMode, IContextConfig, IContextResult, IFileInfo, ITrimConfig, ITaskConfig, TaskType, ICacheConfig, IAnalyzerConfig, IPrioritizationWeights, ITierConfig, ITierSettings, IFileMetadata, ICacheEntry, IFileDependencies, IFileAnalysis, IAnalysisResult, IIterativeConfig, IIterativeContextResult };
8
+ import { DiffProcessor } from './diff-processor.js';
9
+ import type { ContextMode, IContextConfig, IContextResult, IFileInfo, ITrimConfig, ITaskConfig, TaskType, ICacheConfig, IAnalyzerConfig, IPrioritizationWeights, ITierConfig, ITierSettings, IFileMetadata, ICacheEntry, IFileDependencies, IFileAnalysis, IAnalysisResult, IIterativeConfig, IIterativeContextResult, IDiffFileInfo, IProcessedDiff, IDiffProcessorOptions } from './types.js';
10
+ export { EnhancedContext, TaskContextFactory, ConfigManager, ContextTrimmer, LazyFileLoader, ContextCache, ContextAnalyzer, DiffProcessor, };
11
+ export type { ContextMode, IContextConfig, IContextResult, IFileInfo, ITrimConfig, ITaskConfig, TaskType, ICacheConfig, IAnalyzerConfig, IPrioritizationWeights, ITierConfig, ITierSettings, IFileMetadata, ICacheEntry, IFileDependencies, IFileAnalysis, IAnalysisResult, IIterativeConfig, IIterativeContextResult, IDiffFileInfo, IProcessedDiff, IDiffProcessorOptions };
@@ -5,7 +5,8 @@ import { ContextTrimmer } from './context-trimmer.js';
5
5
  import { LazyFileLoader } from './lazy-file-loader.js';
6
6
  import { ContextCache } from './context-cache.js';
7
7
  import { ContextAnalyzer } from './context-analyzer.js';
8
+ import { DiffProcessor } from './diff-processor.js';
8
9
  export {
9
10
  // Classes
10
- EnhancedContext, TaskContextFactory, ConfigManager, ContextTrimmer, LazyFileLoader, ContextCache, ContextAnalyzer, };
11
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9jb250ZXh0L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBdUJ4RCxPQUFPO0FBQ0wsVUFBVTtBQUNWLGVBQWUsRUFDZixrQkFBa0IsRUFDbEIsYUFBYSxFQUNiLGNBQWMsRUFDZCxjQUFjLEVBQ2QsWUFBWSxFQUNaLGVBQWUsR0FDaEIsQ0FBQyJ9
11
+ EnhancedContext, TaskContextFactory, ConfigManager, ContextTrimmer, LazyFileLoader, ContextCache, ContextAnalyzer, DiffProcessor, };
12
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9jb250ZXh0L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQTBCcEQsT0FBTztBQUNMLFVBQVU7QUFDVixlQUFlLEVBQ2Ysa0JBQWtCLEVBQ2xCLGFBQWEsRUFDYixjQUFjLEVBQ2QsY0FBYyxFQUNkLFlBQVksRUFDWixlQUFlLEVBQ2YsYUFBYSxHQUNkLENBQUMifQ==
@@ -84,6 +84,19 @@ export class IterativeContextBuilder {
84
84
  const includedFiles = [];
85
85
  // If additional context (e.g., git diff) is provided, prepend it
86
86
  if (additionalContext) {
87
+ // CRITICAL SAFETY: Check raw string size BEFORE tokenization to prevent OOM
88
+ const MAX_DIFF_CHARS = 500000; // ~125k tokens max (conservative 4 chars/token ratio)
89
+ const MAX_DIFF_TOKENS = 150000; // Hard token limit for safety
90
+ // First check: raw character count
91
+ if (additionalContext.length > MAX_DIFF_CHARS) {
92
+ const originalSize = additionalContext.length;
93
+ logger.log('warn', `⚠️ Git diff too large (${originalSize.toLocaleString()} chars > ${MAX_DIFF_CHARS.toLocaleString()} limit)`);
94
+ logger.log('warn', ` This likely includes build artifacts (dist/, *.js.map, bundles, etc.)`);
95
+ logger.log('warn', ` Truncating to first ${MAX_DIFF_CHARS.toLocaleString()} characters.`);
96
+ logger.log('warn', ` Consider: git stash build files, improve .gitignore, or review uncommitted changes.`);
97
+ additionalContext = additionalContext.substring(0, MAX_DIFF_CHARS) +
98
+ '\n\n[... DIFF TRUNCATED - exceeded size limit of ' + MAX_DIFF_CHARS.toLocaleString() + ' chars ...]';
99
+ }
87
100
  const diffSection = `
88
101
  ====== GIT DIFF ======
89
102
 
@@ -91,10 +104,17 @@ ${additionalContext}
91
104
 
92
105
  ====== END OF GIT DIFF ======
93
106
  `;
94
- loadedContent = diffSection;
107
+ // Second check: actual token count after truncation
95
108
  const diffTokens = this.countTokens(diffSection);
109
+ if (diffTokens > MAX_DIFF_TOKENS) {
110
+ logger.log('error', `❌ Git diff still too large after truncation (${diffTokens.toLocaleString()} tokens > ${MAX_DIFF_TOKENS.toLocaleString()} limit)`);
111
+ throw new Error(`Git diff size (${diffTokens.toLocaleString()} tokens) exceeds maximum (${MAX_DIFF_TOKENS.toLocaleString()} tokens). ` +
112
+ `This indicates massive uncommitted changes, likely build artifacts. ` +
113
+ `Please commit or stash dist/, build/, or other generated files.`);
114
+ }
115
+ loadedContent = diffSection;
96
116
  totalTokensUsed += diffTokens;
97
- logger.log('info', `📝 Added git diff to context (${diffTokens} tokens)`);
117
+ logger.log('info', `📝 Added git diff to context (${diffTokens.toLocaleString()} tokens)`);
98
118
  }
99
119
  // Phase 3: Iterative file selection and loading
100
120
  for (let iteration = 1; iteration <= this.config.maxIterations; iteration++) {
@@ -381,4 +401,4 @@ ${file.contents}
381
401
  }
382
402
  }
383
403
  }
384
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXRlcmF0aXZlLWNvbnRleHQtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2NvbnRleHQvaXRlcmF0aXZlLWNvbnRleHQtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQUN6QixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBV3ZDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVwRDs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sdUJBQXVCO0lBVWxDOzs7OztPQUtHO0lBQ0gsWUFDRSxXQUFtQixFQUNuQixNQUFrQyxFQUNsQyxjQUErQztRQWJ6QyxnQkFBVyxHQUFXLE1BQU0sQ0FBQztRQWVuQyxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztRQUMvQixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2xELElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDM0MsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLGVBQWUsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsc0JBQXNCLEdBQUcsY0FBYyxDQUFDO1FBRTdDLHdCQUF3QjtRQUN4QixJQUFJLENBQUMsTUFBTSxHQUFHO1lBQ1osYUFBYSxFQUFFLE1BQU0sRUFBRSxhQUFhLElBQUksQ0FBQztZQUN6QyxrQkFBa0IsRUFBRSxNQUFNLEVBQUUs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
404
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXRlcmF0aXZlLWNvbnRleHQtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2NvbnRleHQvaXRlcmF0aXZlLWNvbnRleHQtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQUN6QixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBV3ZDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVwRDs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sdUJBQXVCO0lBVWxDOzs7OztPQUtHO0lBQ0gsWUFDRSxXQUFtQixFQUNuQixNQUFrQyxFQUNsQyxjQUErQztRQWJ6QyxnQkFBVyxHQUFXLE1BQU0sQ0FBQztRQWVuQyxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztRQUMvQixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2xELElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDM0MsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLGVBQWUsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsc0JBQXNCLEdBQUcsY0FBYyxDQUFDO1FBRTdDLHdCQUF3QjtRQUN4QixJQUFJLENBQUMsTUFBTSxHQUFHO1lBQ1osYUFBYSxFQUFFLE1BQU0sRUFBRSxhQUFhLElBQUksQ0FBQztZQUN6QyxrQkFBa0IsRUFBRSxNQUFNLEVBQUUs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
@@ -298,3 +298,4 @@ export interface IIterativeContextResult extends IContextResult {
298
298
  /** Total duration in ms */
299
299
  totalDuration: number;
300
300
  }
301
+ export type { IDiffFileInfo, IProcessedDiff, IDiffProcessorOptions } from './diff-processor.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@git.zone/tsdoc",
3
- "version": "1.8.2",
3
+ "version": "1.9.0",
4
4
  "private": false,
5
5
  "description": "A comprehensive TypeScript documentation tool that leverages AI to generate and enhance project documentation, including dynamic README creation, API docs via TypeDoc, and smart commit message generation.",
6
6
  "type": "module",
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@git.zone/tsdoc',
6
- version: '1.8.0',
6
+ version: '1.9.0',
7
7
  description: 'A comprehensive TypeScript documentation tool that leverages AI to generate and enhance project documentation, including dynamic README creation, API docs via TypeDoc, and smart commit message generation.'
8
8
  }
@@ -1,6 +1,7 @@
1
1
  import * as plugins from '../plugins.js';
2
2
  import { AiDoc } from '../classes.aidoc.js';
3
3
  import { ProjectContext } from './projectcontext.js';
4
+ import { DiffProcessor } from '../context/diff-processor.js';
4
5
 
5
6
  export interface INextCommitObject {
6
7
  recommendedNextVersionLevel: 'fix' | 'feat' | 'BREAKING CHANGE'; // the recommended next version level of the project
@@ -27,29 +28,101 @@ export class Commit {
27
28
  smartgitInstance,
28
29
  this.projectDir
29
30
  );
30
- const diffStringArray = await gitRepo.getUncommittedDiff([
31
+
32
+ // Define comprehensive exclusion patterns
33
+ // smartgit@3.3.0+ supports glob patterns natively
34
+ const excludePatterns = [
35
+ // Lock files
31
36
  'pnpm-lock.yaml',
32
37
  'package-lock.json',
33
38
  'npm-shrinkwrap.json',
34
39
  'yarn.lock',
35
40
  'deno.lock',
36
41
  'bun.lockb',
37
- '.claude/*',
38
- '.cursor/*',
39
- '.vscode/*',
40
- '.idea/*',
41
- ]);
42
+
43
+ // Build artifacts (main culprit for large diffs!)
44
+ 'dist/**',
45
+ 'dist_*/**', // dist_ts, dist_web, etc.
46
+ 'build/**',
47
+ '.next/**',
48
+ 'out/**',
49
+ 'public/dist/**',
50
+
51
+ // Compiled/bundled files
52
+ '**/*.js.map',
53
+ '**/*.d.ts.map',
54
+ '**/*.min.js',
55
+ '**/*.bundle.js',
56
+ '**/*.chunk.js',
57
+
58
+ // IDE/Editor directories
59
+ '.claude/**',
60
+ '.cursor/**',
61
+ '.vscode/**',
62
+ '.idea/**',
63
+ '**/*.swp',
64
+ '**/*.swo',
65
+
66
+ // Logs and caches
67
+ '.nogit/**',
68
+ '**/*.log',
69
+ '.cache/**',
70
+ '.rpt2_cache/**',
71
+ 'coverage/**',
72
+ '.nyc_output/**',
73
+ ];
74
+
75
+ // Pass glob patterns directly to smartgit - it handles matching internally
76
+ const diffStringArray = await gitRepo.getUncommittedDiff(excludePatterns);
77
+
78
+ // Process diffs intelligently using DiffProcessor
79
+ let processedDiffString: string;
80
+
81
+ if (diffStringArray.length > 0) {
82
+ // Diagnostic logging for raw diff statistics
83
+ const totalChars = diffStringArray.join('\n\n').length;
84
+ const estimatedTokens = Math.ceil(totalChars / 4);
85
+
86
+ console.log(`📊 Raw git diff statistics:`);
87
+ console.log(` Files changed: ${diffStringArray.length}`);
88
+ console.log(` Total characters: ${totalChars.toLocaleString()}`);
89
+ console.log(` Estimated tokens: ${estimatedTokens.toLocaleString()}`);
90
+ console.log(` Exclusion patterns: ${excludePatterns.length}`);
91
+
92
+ // Use DiffProcessor to intelligently handle large diffs
93
+ const diffProcessor = new DiffProcessor({
94
+ maxDiffTokens: 100000, // Reserve 100k tokens for diffs
95
+ smallFileLines: 50, // Include files <= 50 lines fully
96
+ mediumFileLines: 200, // Summarize files <= 200 lines
97
+ sampleHeadLines: 20, // Show first 20 lines
98
+ sampleTailLines: 20, // Show last 20 lines
99
+ });
100
+
101
+ const processedDiff = diffProcessor.processDiffs(diffStringArray);
102
+ processedDiffString = diffProcessor.formatForContext(processedDiff);
103
+
104
+ console.log(`📝 Processed diff statistics:`);
105
+ console.log(` Full diffs: ${processedDiff.fullDiffs.length} files`);
106
+ console.log(` Summarized: ${processedDiff.summarizedDiffs.length} files`);
107
+ console.log(` Metadata only: ${processedDiff.metadataOnly.length} files`);
108
+ console.log(` Final tokens: ${processedDiff.totalTokens.toLocaleString()}`);
109
+
110
+ if (estimatedTokens > 50000) {
111
+ console.log(`✅ DiffProcessor reduced token usage: ${estimatedTokens.toLocaleString()} → ${processedDiff.totalTokens.toLocaleString()}`);
112
+ }
113
+ } else {
114
+ processedDiffString = 'No changes.';
115
+ }
116
+
42
117
  // Use the new TaskContextFactory for optimized context
43
118
  const taskContextFactory = new (await import('../context/index.js')).TaskContextFactory(
44
119
  this.projectDir,
45
120
  this.aiDocsRef.openaiInstance
46
121
  );
47
122
  await taskContextFactory.initialize();
48
-
123
+
49
124
  // Generate context specifically for commit task
50
- const contextResult = await taskContextFactory.createContextForCommit(
51
- diffStringArray[0] ? diffStringArray.join('\n\n') : 'No changes.'
52
- );
125
+ const contextResult = await taskContextFactory.createContextForCommit(processedDiffString);
53
126
 
54
127
  // Get the optimized context string
55
128
  let contextString = contextResult.context;
@@ -0,0 +1,341 @@
1
+ /**
2
+ * Intelligent git diff processor that handles large diffs by sampling and prioritization
3
+ * instead of blind truncation.
4
+ */
5
+
6
+ export interface IDiffFileInfo {
7
+ filepath: string;
8
+ status: 'added' | 'modified' | 'deleted';
9
+ linesAdded: number;
10
+ linesRemoved: number;
11
+ totalLines: number;
12
+ estimatedTokens: number;
13
+ diffContent: string;
14
+ }
15
+
16
+ export interface IProcessedDiff {
17
+ summary: string; // Human-readable overview
18
+ fullDiffs: string[]; // Small files included fully
19
+ summarizedDiffs: string[]; // Medium files with head/tail
20
+ metadataOnly: string[]; // Large files, just stats
21
+ totalFiles: number;
22
+ totalTokens: number;
23
+ }
24
+
25
+ export interface IDiffProcessorOptions {
26
+ maxDiffTokens?: number; // Maximum tokens for entire diff section (default: 100000)
27
+ smallFileLines?: number; // Files <= this are included fully (default: 50)
28
+ mediumFileLines?: number; // Files <= this are summarized (default: 200)
29
+ sampleHeadLines?: number; // Lines to show at start of medium files (default: 20)
30
+ sampleTailLines?: number; // Lines to show at end of medium files (default: 20)
31
+ }
32
+
33
+ export class DiffProcessor {
34
+ private options: Required<IDiffProcessorOptions>;
35
+
36
+ constructor(options: IDiffProcessorOptions = {}) {
37
+ this.options = {
38
+ maxDiffTokens: options.maxDiffTokens ?? 100000,
39
+ smallFileLines: options.smallFileLines ?? 50,
40
+ mediumFileLines: options.mediumFileLines ?? 200,
41
+ sampleHeadLines: options.sampleHeadLines ?? 20,
42
+ sampleTailLines: options.sampleTailLines ?? 20,
43
+ };
44
+ }
45
+
46
+ /**
47
+ * Process an array of git diffs into a structured, token-efficient format
48
+ */
49
+ public processDiffs(diffStringArray: string[]): IProcessedDiff {
50
+ // Parse all diffs into file info objects
51
+ const fileInfos: IDiffFileInfo[] = diffStringArray
52
+ .map(diffString => this.parseDiffFile(diffString))
53
+ .filter(info => info !== null) as IDiffFileInfo[];
54
+
55
+ // Prioritize files (source files first, build artifacts last)
56
+ const prioritized = this.prioritizeFiles(fileInfos);
57
+
58
+ const result: IProcessedDiff = {
59
+ summary: '',
60
+ fullDiffs: [],
61
+ summarizedDiffs: [],
62
+ metadataOnly: [],
63
+ totalFiles: prioritized.length,
64
+ totalTokens: 0,
65
+ };
66
+
67
+ let tokensUsed = 0;
68
+ const tokenBudget = this.options.maxDiffTokens;
69
+
70
+ // Categorize and include files based on size and token budget
71
+ for (const fileInfo of prioritized) {
72
+ const remainingBudget = tokenBudget - tokensUsed;
73
+
74
+ if (remainingBudget <= 0) {
75
+ // Budget exhausted - rest are metadata only
76
+ result.metadataOnly.push(this.formatMetadataOnly(fileInfo));
77
+ continue;
78
+ }
79
+
80
+ if (fileInfo.totalLines <= this.options.smallFileLines) {
81
+ // Small file - include fully if budget allows
82
+ if (fileInfo.estimatedTokens <= remainingBudget) {
83
+ const statusPrefix = this.getFileStatusPrefix(fileInfo);
84
+ result.fullDiffs.push(`${statusPrefix}${fileInfo.diffContent}`);
85
+ tokensUsed += fileInfo.estimatedTokens;
86
+ } else {
87
+ result.metadataOnly.push(this.formatMetadataOnly(fileInfo));
88
+ }
89
+ } else if (fileInfo.totalLines <= this.options.mediumFileLines) {
90
+ // Medium file - try to include summary with head/tail
91
+ const summary = this.extractDiffSample(
92
+ fileInfo,
93
+ this.options.sampleHeadLines,
94
+ this.options.sampleTailLines
95
+ );
96
+ const summaryTokens = Math.ceil(summary.length / 4); // Rough estimate
97
+
98
+ if (summaryTokens <= remainingBudget) {
99
+ result.summarizedDiffs.push(summary);
100
+ tokensUsed += summaryTokens;
101
+ } else {
102
+ result.metadataOnly.push(this.formatMetadataOnly(fileInfo));
103
+ }
104
+ } else {
105
+ // Large file - metadata only
106
+ result.metadataOnly.push(this.formatMetadataOnly(fileInfo));
107
+ }
108
+ }
109
+
110
+ result.totalTokens = tokensUsed;
111
+ result.summary = this.generateSummary(result);
112
+
113
+ return result;
114
+ }
115
+
116
+ /**
117
+ * Format the processed diff for inclusion in context
118
+ */
119
+ public formatForContext(processed: IProcessedDiff): string {
120
+ const sections: string[] = [];
121
+
122
+ // Summary section
123
+ sections.push('====== GIT DIFF SUMMARY ======');
124
+ sections.push(processed.summary);
125
+ sections.push('');
126
+
127
+ // Full diffs section
128
+ if (processed.fullDiffs.length > 0) {
129
+ sections.push(`====== FULL DIFFS (${processed.fullDiffs.length} files) ======`);
130
+ sections.push(processed.fullDiffs.join('\n\n'));
131
+ sections.push('');
132
+ }
133
+
134
+ // Summarized diffs section
135
+ if (processed.summarizedDiffs.length > 0) {
136
+ sections.push(`====== SUMMARIZED DIFFS (${processed.summarizedDiffs.length} files) ======`);
137
+ sections.push(processed.summarizedDiffs.join('\n\n'));
138
+ sections.push('');
139
+ }
140
+
141
+ // Metadata only section
142
+ if (processed.metadataOnly.length > 0) {
143
+ sections.push(`====== METADATA ONLY (${processed.metadataOnly.length} files) ======`);
144
+ sections.push(processed.metadataOnly.join('\n'));
145
+ sections.push('');
146
+ }
147
+
148
+ sections.push('====== END OF GIT DIFF ======');
149
+
150
+ return sections.join('\n');
151
+ }
152
+
153
+ /**
154
+ * Parse a single git diff string into file information
155
+ */
156
+ private parseDiffFile(diffString: string): IDiffFileInfo | null {
157
+ if (!diffString || diffString.trim().length === 0) {
158
+ return null;
159
+ }
160
+
161
+ const lines = diffString.split('\n');
162
+ let filepath = '';
163
+ let status: 'added' | 'modified' | 'deleted' = 'modified';
164
+ let linesAdded = 0;
165
+ let linesRemoved = 0;
166
+
167
+ // Parse diff header to extract filepath and status
168
+ for (const line of lines) {
169
+ if (line.startsWith('--- a/')) {
170
+ filepath = line.substring(6);
171
+ } else if (line.startsWith('+++ b/')) {
172
+ const newPath = line.substring(6);
173
+ if (newPath === '/dev/null') {
174
+ status = 'deleted';
175
+ } else if (filepath === '/dev/null') {
176
+ status = 'added';
177
+ filepath = newPath;
178
+ } else {
179
+ filepath = newPath;
180
+ }
181
+ } else if (line.startsWith('+') && !line.startsWith('+++')) {
182
+ linesAdded++;
183
+ } else if (line.startsWith('-') && !line.startsWith('---')) {
184
+ linesRemoved++;
185
+ }
186
+ }
187
+
188
+ const totalLines = linesAdded + linesRemoved;
189
+ const estimatedTokens = Math.ceil(diffString.length / 4);
190
+
191
+ return {
192
+ filepath,
193
+ status,
194
+ linesAdded,
195
+ linesRemoved,
196
+ totalLines,
197
+ estimatedTokens,
198
+ diffContent: diffString,
199
+ };
200
+ }
201
+
202
+ /**
203
+ * Prioritize files by importance (source files before build artifacts)
204
+ */
205
+ private prioritizeFiles(files: IDiffFileInfo[]): IDiffFileInfo[] {
206
+ return files.sort((a, b) => {
207
+ const scoreA = this.getFileImportanceScore(a.filepath);
208
+ const scoreB = this.getFileImportanceScore(b.filepath);
209
+ return scoreB - scoreA; // Higher score first
210
+ });
211
+ }
212
+
213
+ /**
214
+ * Calculate importance score for a file path
215
+ */
216
+ private getFileImportanceScore(filepath: string): number {
217
+ // Source files - highest priority
218
+ if (filepath.match(/^(src|lib|app|components|pages|api)\//)) {
219
+ return 100;
220
+ }
221
+
222
+ // Test files - high priority
223
+ if (filepath.match(/\.(test|spec)\.(ts|js|tsx|jsx)$/) || filepath.startsWith('test/')) {
224
+ return 80;
225
+ }
226
+
227
+ // Configuration files - medium-high priority
228
+ if (filepath.match(/\.(json|yaml|yml|toml|config\.(ts|js))$/)) {
229
+ return 60;
230
+ }
231
+
232
+ // Documentation - medium priority
233
+ if (filepath.match(/\.(md|txt|rst)$/)) {
234
+ return 40;
235
+ }
236
+
237
+ // Build artifacts - low priority
238
+ if (filepath.match(/^(dist|build|out|\.next|public\/dist)\//)) {
239
+ return 10;
240
+ }
241
+
242
+ // Everything else - default priority
243
+ return 50;
244
+ }
245
+
246
+ /**
247
+ * Extract head and tail lines from a diff, omitting the middle
248
+ */
249
+ private extractDiffSample(fileInfo: IDiffFileInfo, headLines: number, tailLines: number): string {
250
+ const lines = fileInfo.diffContent.split('\n');
251
+ const totalLines = lines.length;
252
+
253
+ if (totalLines <= headLines + tailLines) {
254
+ // File is small enough to include fully
255
+ return fileInfo.diffContent;
256
+ }
257
+
258
+ // Extract file metadata from diff header
259
+ const headerLines: string[] = [];
260
+ let bodyStartIndex = 0;
261
+ for (let i = 0; i < lines.length; i++) {
262
+ if (lines[i].startsWith('@@')) {
263
+ headerLines.push(...lines.slice(0, i + 1));
264
+ bodyStartIndex = i + 1;
265
+ break;
266
+ }
267
+ }
268
+
269
+ const bodyLines = lines.slice(bodyStartIndex);
270
+ const head = bodyLines.slice(0, headLines);
271
+ const tail = bodyLines.slice(-tailLines);
272
+ const omittedLines = bodyLines.length - headLines - tailLines;
273
+
274
+ const statusEmoji = fileInfo.status === 'added' ? '➕' :
275
+ fileInfo.status === 'deleted' ? '➖' : '📝';
276
+
277
+ const parts: string[] = [];
278
+ parts.push(`${statusEmoji} FILE: ${fileInfo.filepath}`);
279
+ parts.push(`CHANGES: +${fileInfo.linesAdded} lines, -${fileInfo.linesRemoved} lines (${fileInfo.totalLines} total)`);
280
+ parts.push('');
281
+ parts.push(...headerLines);
282
+ parts.push(...head);
283
+ parts.push('');
284
+ parts.push(`[... ${omittedLines} lines omitted - use Read tool to see full file ...]`);
285
+ parts.push('');
286
+ parts.push(...tail);
287
+
288
+ return parts.join('\n');
289
+ }
290
+
291
+ /**
292
+ * Get file status prefix with emoji
293
+ */
294
+ private getFileStatusPrefix(fileInfo: IDiffFileInfo): string {
295
+ const statusEmoji = fileInfo.status === 'added' ? '➕' :
296
+ fileInfo.status === 'deleted' ? '➖' : '📝';
297
+ return `${statusEmoji} `;
298
+ }
299
+
300
+ /**
301
+ * Extract filepath from diff content
302
+ */
303
+ private extractFilepathFromDiff(diffContent: string): string {
304
+ const lines = diffContent.split('\n');
305
+ for (const line of lines) {
306
+ if (line.startsWith('+++ b/')) {
307
+ return line.substring(6);
308
+ }
309
+ }
310
+ return 'unknown';
311
+ }
312
+
313
+ /**
314
+ * Format file info as metadata only
315
+ */
316
+ private formatMetadataOnly(fileInfo: IDiffFileInfo): string {
317
+ const statusEmoji = fileInfo.status === 'added' ? '➕' :
318
+ fileInfo.status === 'deleted' ? '➖' : '📝';
319
+ return `${statusEmoji} ${fileInfo.filepath} (+${fileInfo.linesAdded}, -${fileInfo.linesRemoved})`;
320
+ }
321
+
322
+ /**
323
+ * Generate human-readable summary of processed diff
324
+ */
325
+ private generateSummary(result: IProcessedDiff): string {
326
+ const parts: string[] = [];
327
+ parts.push(`Files changed: ${result.totalFiles} total`);
328
+ parts.push(`- ${result.fullDiffs.length} included in full`);
329
+ parts.push(`- ${result.summarizedDiffs.length} summarized (head/tail shown)`);
330
+ parts.push(`- ${result.metadataOnly.length} metadata only`);
331
+ parts.push(`Estimated tokens: ~${result.totalTokens.toLocaleString()}`);
332
+
333
+ if (result.metadataOnly.length > 0) {
334
+ parts.push('');
335
+ parts.push('NOTE: Some files excluded to stay within token budget.');
336
+ parts.push('Use Read tool with specific file paths to see full content.');
337
+ }
338
+
339
+ return parts.join('\n');
340
+ }
341
+ }
@@ -5,6 +5,7 @@ import { ContextTrimmer } from './context-trimmer.js';
5
5
  import { LazyFileLoader } from './lazy-file-loader.js';
6
6
  import { ContextCache } from './context-cache.js';
7
7
  import { ContextAnalyzer } from './context-analyzer.js';
8
+ import { DiffProcessor } from './diff-processor.js';
8
9
  import type {
9
10
  ContextMode,
10
11
  IContextConfig,
@@ -24,7 +25,10 @@ import type {
24
25
  IFileAnalysis,
25
26
  IAnalysisResult,
26
27
  IIterativeConfig,
27
- IIterativeContextResult
28
+ IIterativeContextResult,
29
+ IDiffFileInfo,
30
+ IProcessedDiff,
31
+ IDiffProcessorOptions
28
32
  } from './types.js';
29
33
 
30
34
  export {
@@ -36,6 +40,7 @@ export {
36
40
  LazyFileLoader,
37
41
  ContextCache,
38
42
  ContextAnalyzer,
43
+ DiffProcessor,
39
44
  };
40
45
 
41
46
  // Types
@@ -58,5 +63,8 @@ export type {
58
63
  IFileAnalysis,
59
64
  IAnalysisResult,
60
65
  IIterativeConfig,
61
- IIterativeContextResult
66
+ IIterativeContextResult,
67
+ IDiffFileInfo,
68
+ IProcessedDiff,
69
+ IDiffProcessorOptions
62
70
  };
@@ -115,6 +115,22 @@ export class IterativeContextBuilder {
115
115
 
116
116
  // If additional context (e.g., git diff) is provided, prepend it
117
117
  if (additionalContext) {
118
+ // CRITICAL SAFETY: Check raw string size BEFORE tokenization to prevent OOM
119
+ const MAX_DIFF_CHARS = 500000; // ~125k tokens max (conservative 4 chars/token ratio)
120
+ const MAX_DIFF_TOKENS = 150000; // Hard token limit for safety
121
+
122
+ // First check: raw character count
123
+ if (additionalContext.length > MAX_DIFF_CHARS) {
124
+ const originalSize = additionalContext.length;
125
+ logger.log('warn', `⚠️ Git diff too large (${originalSize.toLocaleString()} chars > ${MAX_DIFF_CHARS.toLocaleString()} limit)`);
126
+ logger.log('warn', ` This likely includes build artifacts (dist/, *.js.map, bundles, etc.)`);
127
+ logger.log('warn', ` Truncating to first ${MAX_DIFF_CHARS.toLocaleString()} characters.`);
128
+ logger.log('warn', ` Consider: git stash build files, improve .gitignore, or review uncommitted changes.`);
129
+
130
+ additionalContext = additionalContext.substring(0, MAX_DIFF_CHARS) +
131
+ '\n\n[... DIFF TRUNCATED - exceeded size limit of ' + MAX_DIFF_CHARS.toLocaleString() + ' chars ...]';
132
+ }
133
+
118
134
  const diffSection = `
119
135
  ====== GIT DIFF ======
120
136
 
@@ -122,10 +138,22 @@ ${additionalContext}
122
138
 
123
139
  ====== END OF GIT DIFF ======
124
140
  `;
125
- loadedContent = diffSection;
141
+
142
+ // Second check: actual token count after truncation
126
143
  const diffTokens = this.countTokens(diffSection);
144
+
145
+ if (diffTokens > MAX_DIFF_TOKENS) {
146
+ logger.log('error', `❌ Git diff still too large after truncation (${diffTokens.toLocaleString()} tokens > ${MAX_DIFF_TOKENS.toLocaleString()} limit)`);
147
+ throw new Error(
148
+ `Git diff size (${diffTokens.toLocaleString()} tokens) exceeds maximum (${MAX_DIFF_TOKENS.toLocaleString()} tokens). ` +
149
+ `This indicates massive uncommitted changes, likely build artifacts. ` +
150
+ `Please commit or stash dist/, build/, or other generated files.`
151
+ );
152
+ }
153
+
154
+ loadedContent = diffSection;
127
155
  totalTokensUsed += diffTokens;
128
- logger.log('info', `📝 Added git diff to context (${diffTokens} tokens)`);
156
+ logger.log('info', `📝 Added git diff to context (${diffTokens.toLocaleString()} tokens)`);
129
157
  }
130
158
 
131
159
  // Phase 3: Iterative file selection and loading
@@ -318,4 +318,7 @@ export interface IIterativeContextResult extends IContextResult {
318
318
  apiCallCount: number;
319
319
  /** Total duration in ms */
320
320
  totalDuration: number;
321
- }
321
+ }
322
+
323
+ // Export DiffProcessor types
324
+ export type { IDiffFileInfo, IProcessedDiff, IDiffProcessorOptions } from './diff-processor.js';