@defai.digital/ax-cli 2.5.2 → 2.6.4
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/config/settings.yaml +28 -0
- package/dist/agent/context-manager.js +8 -6
- package/dist/agent/context-manager.js.map +1 -1
- package/dist/agent/llm-agent.js +19 -10
- package/dist/agent/llm-agent.js.map +1 -1
- package/dist/commands/cache.d.ts +7 -0
- package/dist/commands/cache.js +270 -0
- package/dist/commands/cache.js.map +1 -0
- package/dist/commands/mcp.js +6 -5
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/memory.js.map +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +2 -0
- package/dist/constants.js.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/llm/client.d.ts +1 -1
- package/dist/llm/types.d.ts +9 -0
- package/dist/llm/types.js.map +1 -1
- package/dist/mcp/transports.js +4 -2
- package/dist/mcp/transports.js.map +1 -1
- package/dist/schemas/api-schemas.js +1 -0
- package/dist/schemas/api-schemas.js.map +1 -1
- package/dist/schemas/yaml-schemas.d.ts +10 -0
- package/dist/schemas/yaml-schemas.js +2 -0
- package/dist/schemas/yaml-schemas.js.map +1 -1
- package/dist/tools/bash.js +16 -3
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/text-editor.js +8 -5
- package/dist/tools/text-editor.js.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/ui/components/chat-interface.js +27 -15
- package/dist/ui/components/chat-interface.js.map +1 -1
- package/dist/utils/config-loader.d.ts +2 -0
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/file-cache.d.ts +144 -0
- package/dist/utils/file-cache.js +412 -0
- package/dist/utils/file-cache.js.map +1 -0
- package/dist/utils/incremental-analyzer.d.ts +134 -0
- package/dist/utils/incremental-analyzer.js +361 -0
- package/dist/utils/incremental-analyzer.js.map +1 -0
- package/dist/utils/message-optimizer.d.ts +99 -0
- package/dist/utils/message-optimizer.js +291 -0
- package/dist/utils/message-optimizer.js.map +1 -0
- package/dist/utils/parallel-analyzer.d.ts +123 -0
- package/dist/utils/parallel-analyzer.js +228 -0
- package/dist/utils/parallel-analyzer.js.map +1 -0
- package/dist/utils/streaming-analyzer.d.ts +171 -0
- package/dist/utils/streaming-analyzer.js +248 -0
- package/dist/utils/streaming-analyzer.js.map +1 -0
- package/dist/utils/token-counter.d.ts +2 -5
- package/dist/utils/token-counter.js +12 -3
- package/dist/utils/token-counter.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Cache System for Analysis Results
|
|
3
|
+
*
|
|
4
|
+
* Implements intelligent caching to avoid re-analyzing unchanged files:
|
|
5
|
+
* - Multi-level change detection (mtime, size, hash)
|
|
6
|
+
* - Automatic cache invalidation
|
|
7
|
+
* - Git integration for change detection
|
|
8
|
+
* - Configurable TTL and size limits
|
|
9
|
+
*
|
|
10
|
+
* Best practices:
|
|
11
|
+
* - Uses SHA-256 for content hashing
|
|
12
|
+
* - Stores cache in user directory (~/.ax-cli/cache/)
|
|
13
|
+
* - Includes cache versioning for schema changes
|
|
14
|
+
* - Provides statistics and cache management
|
|
15
|
+
*/
|
|
16
|
+
import { createHash } from 'crypto';
|
|
17
|
+
import { readFile, writeFile, mkdir, stat } from 'fs/promises';
|
|
18
|
+
import { join, relative } from 'path';
|
|
19
|
+
import { existsSync } from 'fs';
|
|
20
|
+
import { execSync } from 'child_process';
|
|
21
|
+
/**
|
|
22
|
+
* File Cache Manager
|
|
23
|
+
*
|
|
24
|
+
* Provides intelligent file caching with multiple change detection strategies
|
|
25
|
+
*/
|
|
26
|
+
export class FileCache {
|
|
27
|
+
config;
|
|
28
|
+
cache = new Map();
|
|
29
|
+
metadata;
|
|
30
|
+
stats = {
|
|
31
|
+
hits: 0,
|
|
32
|
+
misses: 0,
|
|
33
|
+
invalidations: 0,
|
|
34
|
+
totalEntries: 0,
|
|
35
|
+
cacheSize: 0,
|
|
36
|
+
hitRate: 0,
|
|
37
|
+
};
|
|
38
|
+
gitChangedFiles;
|
|
39
|
+
cacheLoaded = false;
|
|
40
|
+
cacheDirty = false;
|
|
41
|
+
constructor(config = {}) {
|
|
42
|
+
// Default configuration
|
|
43
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '/tmp';
|
|
44
|
+
this.config = {
|
|
45
|
+
cacheDir: config.cacheDir || join(homeDir, '.ax-cli', 'cache'),
|
|
46
|
+
namespace: config.namespace || 'default',
|
|
47
|
+
ttl: config.ttl || 7 * 24 * 60 * 60 * 1000, // 7 days
|
|
48
|
+
maxEntries: config.maxEntries || 10000,
|
|
49
|
+
maxSize: config.maxSize || 100 * 1024 * 1024, // 100MB
|
|
50
|
+
useGit: config.useGit !== false,
|
|
51
|
+
toolVersion: config.toolVersion || '1.0.0',
|
|
52
|
+
};
|
|
53
|
+
this.metadata = {
|
|
54
|
+
version: 1,
|
|
55
|
+
createdAt: Date.now(),
|
|
56
|
+
lastAccessedAt: Date.now(),
|
|
57
|
+
toolVersion: this.config.toolVersion,
|
|
58
|
+
totalEntries: 0,
|
|
59
|
+
totalSize: 0,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Initialize cache (load from disk)
|
|
64
|
+
*/
|
|
65
|
+
async init() {
|
|
66
|
+
if (this.cacheLoaded)
|
|
67
|
+
return;
|
|
68
|
+
// Ensure cache directory exists
|
|
69
|
+
await mkdir(this.config.cacheDir, { recursive: true });
|
|
70
|
+
// Load cache from disk
|
|
71
|
+
await this.loadCache();
|
|
72
|
+
// Load git changed files if enabled
|
|
73
|
+
if (this.config.useGit) {
|
|
74
|
+
this.gitChangedFiles = await this.getGitChangedFiles();
|
|
75
|
+
}
|
|
76
|
+
this.cacheLoaded = true;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get cached result for a file, or compute if not cached/invalid
|
|
80
|
+
*/
|
|
81
|
+
async get(filePath, computer) {
|
|
82
|
+
await this.init();
|
|
83
|
+
const relativePath = this.getRelativePath(filePath);
|
|
84
|
+
// Check if file has changed via git (fast check)
|
|
85
|
+
if (this.gitChangedFiles && this.gitChangedFiles.has(relativePath)) {
|
|
86
|
+
this.stats.misses++;
|
|
87
|
+
return this.computeAndCache(filePath, computer);
|
|
88
|
+
}
|
|
89
|
+
// Check cache
|
|
90
|
+
const cached = this.cache.get(relativePath);
|
|
91
|
+
if (!cached) {
|
|
92
|
+
this.stats.misses++;
|
|
93
|
+
return this.computeAndCache(filePath, computer);
|
|
94
|
+
}
|
|
95
|
+
// Validate cache entry
|
|
96
|
+
const isValid = await this.isCacheValid(filePath, cached);
|
|
97
|
+
if (!isValid) {
|
|
98
|
+
this.stats.invalidations++;
|
|
99
|
+
this.stats.misses++;
|
|
100
|
+
return this.computeAndCache(filePath, computer);
|
|
101
|
+
}
|
|
102
|
+
// Cache hit!
|
|
103
|
+
this.stats.hits++;
|
|
104
|
+
this.updateStats();
|
|
105
|
+
return cached.result;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Set cache entry directly
|
|
109
|
+
*/
|
|
110
|
+
async set(filePath, result) {
|
|
111
|
+
await this.init();
|
|
112
|
+
const relativePath = this.getRelativePath(filePath);
|
|
113
|
+
const fileStat = await stat(filePath);
|
|
114
|
+
const hash = await this.hashFile(filePath);
|
|
115
|
+
const entry = {
|
|
116
|
+
path: relativePath,
|
|
117
|
+
mtime: fileStat.mtimeMs,
|
|
118
|
+
size: fileStat.size,
|
|
119
|
+
hash,
|
|
120
|
+
result,
|
|
121
|
+
cachedAt: Date.now(),
|
|
122
|
+
version: this.metadata.version,
|
|
123
|
+
};
|
|
124
|
+
this.cache.set(relativePath, entry);
|
|
125
|
+
this.cacheDirty = true;
|
|
126
|
+
// Enforce limits
|
|
127
|
+
await this.enforceLimits();
|
|
128
|
+
// Update stats
|
|
129
|
+
this.updateStats();
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Check if a file has changed
|
|
133
|
+
*/
|
|
134
|
+
async hasChanged(filePath) {
|
|
135
|
+
await this.init();
|
|
136
|
+
const relativePath = this.getRelativePath(filePath);
|
|
137
|
+
// Git check (fastest)
|
|
138
|
+
if (this.gitChangedFiles && this.gitChangedFiles.has(relativePath)) {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
const cached = this.cache.get(relativePath);
|
|
142
|
+
if (!cached)
|
|
143
|
+
return true;
|
|
144
|
+
return !(await this.isCacheValid(filePath, cached));
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Invalidate cache for a specific file
|
|
148
|
+
*/
|
|
149
|
+
invalidate(filePath) {
|
|
150
|
+
const relativePath = this.getRelativePath(filePath);
|
|
151
|
+
const deleted = this.cache.delete(relativePath);
|
|
152
|
+
if (deleted) {
|
|
153
|
+
this.stats.invalidations++;
|
|
154
|
+
this.cacheDirty = true;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Clear entire cache
|
|
159
|
+
*/
|
|
160
|
+
async clear() {
|
|
161
|
+
this.cache.clear();
|
|
162
|
+
this.stats = {
|
|
163
|
+
hits: 0,
|
|
164
|
+
misses: 0,
|
|
165
|
+
invalidations: 0,
|
|
166
|
+
totalEntries: 0,
|
|
167
|
+
cacheSize: 0,
|
|
168
|
+
hitRate: 0,
|
|
169
|
+
};
|
|
170
|
+
this.cacheDirty = true;
|
|
171
|
+
await this.saveCache();
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Save cache to disk
|
|
175
|
+
*/
|
|
176
|
+
async save() {
|
|
177
|
+
if (!this.cacheDirty)
|
|
178
|
+
return;
|
|
179
|
+
await this.saveCache();
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Get cache statistics
|
|
183
|
+
*/
|
|
184
|
+
getStats() {
|
|
185
|
+
return { ...this.stats };
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Get cache metadata
|
|
189
|
+
*/
|
|
190
|
+
getMetadata() {
|
|
191
|
+
return { ...this.metadata };
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Prune expired entries
|
|
195
|
+
*/
|
|
196
|
+
async prune() {
|
|
197
|
+
const now = Date.now();
|
|
198
|
+
let pruned = 0;
|
|
199
|
+
for (const [path, entry] of this.cache.entries()) {
|
|
200
|
+
if (now - entry.cachedAt > this.config.ttl) {
|
|
201
|
+
this.cache.delete(path);
|
|
202
|
+
pruned++;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (pruned > 0) {
|
|
206
|
+
this.cacheDirty = true;
|
|
207
|
+
this.updateStats();
|
|
208
|
+
await this.saveCache();
|
|
209
|
+
}
|
|
210
|
+
return pruned;
|
|
211
|
+
}
|
|
212
|
+
// Private methods
|
|
213
|
+
async computeAndCache(filePath, computer) {
|
|
214
|
+
const result = await computer(filePath);
|
|
215
|
+
await this.set(filePath, result);
|
|
216
|
+
return result;
|
|
217
|
+
}
|
|
218
|
+
async isCacheValid(filePath, cached) {
|
|
219
|
+
try {
|
|
220
|
+
// Check if file exists
|
|
221
|
+
if (!existsSync(filePath)) {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
// Check version compatibility
|
|
225
|
+
if (cached.version !== this.metadata.version) {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
// Check tool version
|
|
229
|
+
if (cached.version === 1 && this.config.toolVersion !== this.metadata.toolVersion) {
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
// Check TTL
|
|
233
|
+
if (Date.now() - cached.cachedAt > this.config.ttl) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
// Fast checks: mtime and size
|
|
237
|
+
const fileStat = await stat(filePath);
|
|
238
|
+
if (fileStat.mtimeMs !== cached.mtime) {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
if (fileStat.size !== cached.size) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
// Slow but accurate: content hash
|
|
245
|
+
const currentHash = await this.hashFile(filePath);
|
|
246
|
+
return currentHash === cached.hash;
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
async hashFile(filePath) {
|
|
253
|
+
const content = await readFile(filePath);
|
|
254
|
+
return createHash('sha256').update(content).digest('hex');
|
|
255
|
+
}
|
|
256
|
+
getRelativePath(filePath) {
|
|
257
|
+
const cwd = process.cwd();
|
|
258
|
+
return relative(cwd, filePath);
|
|
259
|
+
}
|
|
260
|
+
async getGitChangedFiles() {
|
|
261
|
+
try {
|
|
262
|
+
// Check if we're in a git repo
|
|
263
|
+
execSync('git rev-parse --git-dir', {
|
|
264
|
+
stdio: 'ignore',
|
|
265
|
+
cwd: process.cwd(),
|
|
266
|
+
});
|
|
267
|
+
// Get changed files (modified, added, untracked)
|
|
268
|
+
const output = execSync('git status --porcelain --untracked-files=all', {
|
|
269
|
+
encoding: 'utf-8',
|
|
270
|
+
cwd: process.cwd(),
|
|
271
|
+
});
|
|
272
|
+
const changedFiles = new Set();
|
|
273
|
+
for (const line of output.split('\n')) {
|
|
274
|
+
if (!line.trim())
|
|
275
|
+
continue;
|
|
276
|
+
// Parse git status output
|
|
277
|
+
const status = line.substring(0, 2);
|
|
278
|
+
const filePath = line.substring(3);
|
|
279
|
+
// Include modified, added, deleted, renamed, untracked files
|
|
280
|
+
if (status.trim()) {
|
|
281
|
+
changedFiles.add(filePath);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return changedFiles;
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
// Not a git repo or git not available
|
|
288
|
+
return undefined;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
getCacheFilePath() {
|
|
292
|
+
return join(this.config.cacheDir, `${this.config.namespace}.json`);
|
|
293
|
+
}
|
|
294
|
+
async loadCache() {
|
|
295
|
+
const cacheFile = this.getCacheFilePath();
|
|
296
|
+
if (!existsSync(cacheFile)) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
try {
|
|
300
|
+
const content = await readFile(cacheFile, 'utf-8');
|
|
301
|
+
const data = JSON.parse(content);
|
|
302
|
+
// Load metadata
|
|
303
|
+
if (data.metadata) {
|
|
304
|
+
this.metadata = data.metadata;
|
|
305
|
+
this.metadata.lastAccessedAt = Date.now();
|
|
306
|
+
}
|
|
307
|
+
// Load entries
|
|
308
|
+
if (data.entries && Array.isArray(data.entries)) {
|
|
309
|
+
for (const entry of data.entries) {
|
|
310
|
+
this.cache.set(entry.path, entry);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// Update stats
|
|
314
|
+
this.stats.totalEntries = this.cache.size;
|
|
315
|
+
this.updateStats();
|
|
316
|
+
}
|
|
317
|
+
catch (error) {
|
|
318
|
+
// Cache corrupted, start fresh
|
|
319
|
+
console.warn(`Cache corrupted, starting fresh: ${error}`);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
async saveCache() {
|
|
323
|
+
const cacheFile = this.getCacheFilePath();
|
|
324
|
+
// Update metadata
|
|
325
|
+
this.metadata.totalEntries = this.cache.size;
|
|
326
|
+
this.metadata.lastAccessedAt = Date.now();
|
|
327
|
+
// Calculate total size
|
|
328
|
+
let totalSize = 0;
|
|
329
|
+
for (const entry of this.cache.values()) {
|
|
330
|
+
totalSize += entry.size;
|
|
331
|
+
}
|
|
332
|
+
this.metadata.totalSize = totalSize;
|
|
333
|
+
const data = {
|
|
334
|
+
metadata: this.metadata,
|
|
335
|
+
entries: Array.from(this.cache.values()),
|
|
336
|
+
};
|
|
337
|
+
await writeFile(cacheFile, JSON.stringify(data, null, 2));
|
|
338
|
+
this.cacheDirty = false;
|
|
339
|
+
}
|
|
340
|
+
async enforceLimits() {
|
|
341
|
+
// Enforce max entries
|
|
342
|
+
if (this.cache.size > this.config.maxEntries) {
|
|
343
|
+
// Remove oldest entries
|
|
344
|
+
const entries = Array.from(this.cache.entries());
|
|
345
|
+
entries.sort((a, b) => a[1].cachedAt - b[1].cachedAt);
|
|
346
|
+
const toRemove = entries.slice(0, entries.length - this.config.maxEntries);
|
|
347
|
+
for (const [path] of toRemove) {
|
|
348
|
+
this.cache.delete(path);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
// Enforce max size
|
|
352
|
+
let totalSize = 0;
|
|
353
|
+
for (const entry of this.cache.values()) {
|
|
354
|
+
totalSize += entry.size;
|
|
355
|
+
}
|
|
356
|
+
if (totalSize > this.config.maxSize) {
|
|
357
|
+
// Remove oldest entries until under limit
|
|
358
|
+
const entries = Array.from(this.cache.entries());
|
|
359
|
+
entries.sort((a, b) => a[1].cachedAt - b[1].cachedAt);
|
|
360
|
+
let currentSize = totalSize;
|
|
361
|
+
for (const [path, entry] of entries) {
|
|
362
|
+
if (currentSize <= this.config.maxSize)
|
|
363
|
+
break;
|
|
364
|
+
this.cache.delete(path);
|
|
365
|
+
currentSize -= entry.size;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
updateStats() {
|
|
370
|
+
this.stats.totalEntries = this.cache.size;
|
|
371
|
+
let totalSize = 0;
|
|
372
|
+
for (const entry of this.cache.values()) {
|
|
373
|
+
totalSize += entry.size;
|
|
374
|
+
}
|
|
375
|
+
this.stats.cacheSize = totalSize;
|
|
376
|
+
const total = this.stats.hits + this.stats.misses;
|
|
377
|
+
this.stats.hitRate = total > 0 ? this.stats.hits / total : 0;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Create a file cache instance
|
|
382
|
+
*/
|
|
383
|
+
export function createFileCache(config) {
|
|
384
|
+
return new FileCache(config);
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Global cache instances by namespace
|
|
388
|
+
*/
|
|
389
|
+
const cacheInstances = new Map();
|
|
390
|
+
/**
|
|
391
|
+
* Get or create a cache instance for a namespace
|
|
392
|
+
*/
|
|
393
|
+
export function getFileCache(namespace, config) {
|
|
394
|
+
if (!cacheInstances.has(namespace)) {
|
|
395
|
+
cacheInstances.set(namespace, new FileCache({ ...config, namespace }));
|
|
396
|
+
}
|
|
397
|
+
return cacheInstances.get(namespace);
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Save all cache instances
|
|
401
|
+
*/
|
|
402
|
+
export async function saveAllCaches() {
|
|
403
|
+
await Promise.all(Array.from(cacheInstances.values()).map(cache => cache.save()));
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Clear all cache instances
|
|
407
|
+
*/
|
|
408
|
+
export async function clearAllCaches() {
|
|
409
|
+
await Promise.all(Array.from(cacheInstances.values()).map(cache => cache.clear()));
|
|
410
|
+
cacheInstances.clear();
|
|
411
|
+
}
|
|
412
|
+
//# sourceMappingURL=file-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-cache.js","sourceRoot":"","sources":["../../src/utils/file-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Analyzes only changed files and their dependencies using git integration.
|
|
5
|
+
* Provides 10-50x speedup by avoiding analysis of unchanged files.
|
|
6
|
+
*
|
|
7
|
+
* Quick Win #2: Git-Based Incremental Analysis (Est. time: 1 hour)
|
|
8
|
+
* Impact: 10-50x reduction in files to analyze
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Configuration for incremental analysis
|
|
12
|
+
*/
|
|
13
|
+
export interface IncrementalConfig {
|
|
14
|
+
/** Base directory for git operations (default: cwd) */
|
|
15
|
+
baseDir?: string;
|
|
16
|
+
/** File patterns to include (default: all) */
|
|
17
|
+
include?: string[];
|
|
18
|
+
/** File patterns to exclude (default: none) */
|
|
19
|
+
exclude?: string[];
|
|
20
|
+
/** Compare against specific commit/branch (default: HEAD) */
|
|
21
|
+
compareWith?: string;
|
|
22
|
+
/** Include untracked files (default: true) */
|
|
23
|
+
includeUntracked?: boolean;
|
|
24
|
+
/** Build dependency graph (default: false, for future use) */
|
|
25
|
+
trackDependencies?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Changed file info
|
|
29
|
+
*/
|
|
30
|
+
export interface ChangedFile {
|
|
31
|
+
/** File path relative to base directory */
|
|
32
|
+
path: string;
|
|
33
|
+
/** Type of change */
|
|
34
|
+
status: 'modified' | 'added' | 'deleted' | 'renamed' | 'untracked';
|
|
35
|
+
/** Previous path (for renamed files) */
|
|
36
|
+
oldPath?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Result of incremental analysis
|
|
40
|
+
*/
|
|
41
|
+
export interface IncrementalResult {
|
|
42
|
+
/** Files that need analysis */
|
|
43
|
+
filesToAnalyze: string[];
|
|
44
|
+
/** Files that are cached */
|
|
45
|
+
cachedFiles: string[];
|
|
46
|
+
/** Changed files detected */
|
|
47
|
+
changedFiles: ChangedFile[];
|
|
48
|
+
/** Total files in project */
|
|
49
|
+
totalFiles: number;
|
|
50
|
+
/** Estimated speedup */
|
|
51
|
+
speedup: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Check if directory is a git repository
|
|
55
|
+
*/
|
|
56
|
+
export declare function isGitRepo(dir?: string): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Get changed files from git
|
|
59
|
+
*
|
|
60
|
+
* @param config - Configuration options
|
|
61
|
+
* @returns Array of changed files
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const changed = await getChangedFiles({
|
|
66
|
+
* compareWith: 'main',
|
|
67
|
+
* include: ['*.ts', '*.tsx'],
|
|
68
|
+
* });
|
|
69
|
+
*
|
|
70
|
+
* console.log(`${changed.length} files changed`);
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare function getChangedFiles(config?: IncrementalConfig): Promise<ChangedFile[]>;
|
|
74
|
+
/**
|
|
75
|
+
* Get files to analyze incrementally
|
|
76
|
+
*
|
|
77
|
+
* Returns only files that need analysis based on git changes.
|
|
78
|
+
*
|
|
79
|
+
* @param allFiles - All files in project
|
|
80
|
+
* @param config - Configuration options
|
|
81
|
+
* @returns Incremental analysis result
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* const allFiles = await glob('src/** /*.ts');
|
|
86
|
+
* const result = await getFilesToAnalyze(allFiles);
|
|
87
|
+
*
|
|
88
|
+
* console.log(`Analyzing ${result.filesToAnalyze.length} of ${result.totalFiles} files`);
|
|
89
|
+
* console.log(`Speedup: ${result.speedup.toFixed(1)}x`);
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export declare function getFilesToAnalyze(allFiles: string[], config?: IncrementalConfig): Promise<IncrementalResult>;
|
|
93
|
+
/**
|
|
94
|
+
* Get git repository info
|
|
95
|
+
*
|
|
96
|
+
* @param baseDir - Base directory (default: cwd)
|
|
97
|
+
* @returns Repository information
|
|
98
|
+
*/
|
|
99
|
+
export declare function getGitInfo(baseDir?: string): {
|
|
100
|
+
branch: string;
|
|
101
|
+
commit: string;
|
|
102
|
+
isDirty: boolean;
|
|
103
|
+
ahead: number;
|
|
104
|
+
behind: number;
|
|
105
|
+
} | null;
|
|
106
|
+
/**
|
|
107
|
+
* Simple dependency tracker (for future use)
|
|
108
|
+
*
|
|
109
|
+
* Parses import/require statements to build a dependency graph.
|
|
110
|
+
*/
|
|
111
|
+
export declare class DependencyTracker {
|
|
112
|
+
private graph;
|
|
113
|
+
private reverseGraph;
|
|
114
|
+
/**
|
|
115
|
+
* Add a file and its dependencies
|
|
116
|
+
*/
|
|
117
|
+
addFile(filePath: string): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Get files that depend on the given file
|
|
120
|
+
*/
|
|
121
|
+
getDependents(filePath: string): string[];
|
|
122
|
+
/**
|
|
123
|
+
* Get all affected files (transitive dependencies)
|
|
124
|
+
*/
|
|
125
|
+
getAffectedFiles(changedFiles: string[]): string[];
|
|
126
|
+
/**
|
|
127
|
+
* Parse import statements from file content
|
|
128
|
+
*/
|
|
129
|
+
private parseImports;
|
|
130
|
+
/**
|
|
131
|
+
* Resolve import path to absolute path
|
|
132
|
+
*/
|
|
133
|
+
private resolveImport;
|
|
134
|
+
}
|