Use more efficient clineIgnoreExists

This commit is contained in:
Saoud Rizwan 2025-02-07 10:33:47 -08:00
parent 88c75a06f2
commit 8ae39e24be
2 changed files with 28 additions and 43 deletions

View file

@ -12,20 +12,13 @@ import * as vscode from "vscode"
export class ClineIgnoreController {
private cwd: string
private ignoreInstance: Ignore
private fileWatcher: vscode.FileSystemWatcher | null
private disposables: vscode.Disposable[] = []
/**
* Default patterns that are always ignored
*/
private static readonly DEFAULT_PATTERNS = [".clineignore"]
clineIgnoreExists: boolean
constructor(cwd: string) {
this.cwd = cwd
this.ignoreInstance = ignore()
this.ignoreInstance.add(ClineIgnoreController.DEFAULT_PATTERNS)
this.fileWatcher = null
this.clineIgnoreExists = false
// Set up file watcher for .clineignore
this.setupFileWatcher()
}
@ -35,7 +28,7 @@ export class ClineIgnoreController {
* Must be called after construction and before using the controller
*/
async initialize(): Promise<void> {
await this.loadCustomPatterns()
await this.loadClineIgnore()
}
/**
@ -43,60 +36,56 @@ export class ClineIgnoreController {
*/
private setupFileWatcher(): void {
const clineignorePattern = new vscode.RelativePattern(this.cwd, ".clineignore")
this.fileWatcher = vscode.workspace.createFileSystemWatcher(clineignorePattern)
const fileWatcher = vscode.workspace.createFileSystemWatcher(clineignorePattern)
// Watch for changes and updates
this.disposables.push(
this.fileWatcher.onDidChange(() => {
this.loadCustomPatterns().catch((error) => {
console.error("Failed to load updated .clineignore patterns:", error)
})
fileWatcher.onDidChange(() => {
this.loadClineIgnore()
}),
this.fileWatcher.onDidCreate(() => {
this.loadCustomPatterns().catch((error) => {
console.error("Failed to load new .clineignore patterns:", error)
})
fileWatcher.onDidCreate(() => {
this.loadClineIgnore()
}),
this.fileWatcher.onDidDelete(() => {
this.resetToDefaultPatterns()
fileWatcher.onDidDelete(() => {
this.loadClineIgnore()
}),
)
// Add fileWatcher itself to disposables
this.disposables.push(this.fileWatcher)
this.disposables.push(fileWatcher)
}
/**
* Load custom patterns from .clineignore if it exists
*/
private async loadCustomPatterns(): Promise<void> {
private async loadClineIgnore(): Promise<void> {
try {
// Reset ignore instance to prevent duplicate patterns
this.ignoreInstance = ignore()
const ignorePath = path.join(this.cwd, ".clineignore")
if (await fileExistsAtPath(ignorePath)) {
// Reset ignore instance to prevent duplicate patterns
this.resetToDefaultPatterns()
this.clineIgnoreExists = true
const content = await fs.readFile(ignorePath, "utf8")
this.ignoreInstance.add(content)
} else {
this.clineIgnoreExists = false
}
} catch (error) {
// Continue with default patterns
// Should never happen: reading file failed even though it exists
console.error("Unexpected error loading .clineignore:", error)
}
}
/**
* Reset ignore patterns to defaults
*/
private resetToDefaultPatterns(): void {
this.ignoreInstance = ignore()
this.ignoreInstance.add(ClineIgnoreController.DEFAULT_PATTERNS)
}
/**
* Check if a file should be accessible to the LLM
* @param filePath - Path to check (relative to cwd)
* @returns true if file is accessible, false if ignored
*/
validateAccess(filePath: string): boolean {
// Always allow access if .clineignore does not exist
if (!this.clineIgnoreExists) {
return true
}
try {
// Normalize path to be relative to cwd and use forward slashes
const absolutePath = path.resolve(this.cwd, filePath)
@ -137,6 +126,5 @@ export class ClineIgnoreController {
dispose(): void {
this.disposables.forEach((d) => d.dispose())
this.disposables = []
this.fileWatcher = null
}
}

View file

@ -54,7 +54,7 @@ Otherwise, if you have not completed the task and do not need additional informa
absolutePath: string,
files: string[],
didHitLimit: boolean,
clineIgnoreController: ClineIgnoreController,
clineIgnoreController?: ClineIgnoreController,
): string => {
const sorted = files
.map((file) => {
@ -87,7 +87,7 @@ Otherwise, if you have not completed the task and do not need additional informa
return aParts.length - bParts.length
})
const accessControlledSortedFiles = clineIgnoreController
const clineIgnoreParsed = clineIgnoreController
? sorted.map((filePath) => {
// path is relative to absolute path, not cwd
// validateAccess expects either path relative to cwd or absolute path
@ -103,16 +103,13 @@ Otherwise, if you have not completed the task and do not need additional informa
: sorted
if (didHitLimit) {
return `${accessControlledSortedFiles.join(
return `${clineIgnoreParsed.join(
"\n",
)}\n\n(File list truncated. Use list_files on specific subdirectories if you need to explore further.)`
} else if (
accessControlledSortedFiles.length === 0 ||
(accessControlledSortedFiles.length === 1 && accessControlledSortedFiles[0] === "")
) {
} else if (clineIgnoreParsed.length === 0 || (clineIgnoreParsed.length === 1 && clineIgnoreParsed[0] === "")) {
return "No files found."
} else {
return accessControlledSortedFiles.join("\n")
return clineIgnoreParsed.join("\n")
}
},