Rename LLMFileAccessController to ClineIgnoreController

This commit is contained in:
Saoud Rizwan 2025-02-07 00:25:29 -08:00
parent 88a07de5fb
commit 7f292bc995
6 changed files with 43 additions and 43 deletions

View file

@ -46,7 +46,7 @@ import { HistoryItem } from "../shared/HistoryItem"
import { ClineAskResponse, ClineCheckpointRestore } from "../shared/WebviewMessage"
import { calculateApiCost } from "../utils/cost"
import { fileExistsAtPath } from "../utils/fs"
import { LLMFileAccessController } from "../services/llm-access-control/LLMFileAccessController"
import { ClineIgnoreController } from "./ignore/ClineIgnoreController"
import { arePathsEqual, getReadablePath } from "../utils/path"
import { fixModelHtmlEscaping, removeInvalidChars } from "../utils/string"
import { AssistantMessageContent, parseAssistantMessage, ToolParamName, ToolUseName } from "./assistant-message"
@ -81,7 +81,7 @@ export class Cline {
private chatSettings: ChatSettings
apiConversationHistory: Anthropic.MessageParam[] = []
clineMessages: ClineMessage[] = []
private llmFileAccessController: LLMFileAccessController
private clineIgnoreController: ClineIgnoreController
private askResponse?: ClineAskResponse
private askResponseText?: string
private askResponseImages?: string[]
@ -125,9 +125,9 @@ export class Cline {
images?: string[],
historyItem?: HistoryItem,
) {
this.llmFileAccessController = new LLMFileAccessController(cwd)
this.llmFileAccessController.initialize().catch((error) => {
console.error("Failed to initialize LLMFileAccessController:", error)
this.clineIgnoreController = new ClineIgnoreController(cwd)
this.clineIgnoreController.initialize().catch((error) => {
console.error("Failed to initialize ClineIgnoreController:", error)
})
this.providerRef = new WeakRef(provider)
this.api = buildApiHandler(apiConfiguration)
@ -1057,7 +1057,7 @@ export class Cline {
this.terminalManager.disposeAll()
this.urlContentFetcher.closeBrowser()
this.browserSession.closeBrowser()
this.llmFileAccessController.dispose()
this.clineIgnoreController.dispose()
await this.diffViewProvider.revertChanges() // need to await for when we want to make sure directories/files are reverted before re-starting the task from a checkpoint
}
@ -1592,7 +1592,7 @@ export class Cline {
break
}
const accessAllowed = this.llmFileAccessController.validateAccess(relPath)
const accessAllowed = this.clineIgnoreController.validateAccess(relPath)
if (!accessAllowed) {
await this.say("clineignore_error", relPath)
pushToolResult(formatResponse.clineIgnoreError(relPath))
@ -1869,7 +1869,7 @@ export class Cline {
break
}
const accessAllowed = this.llmFileAccessController.validateAccess(relPath)
const accessAllowed = this.clineIgnoreController.validateAccess(relPath)
if (!accessAllowed) {
await this.say("clineignore_error", relPath)
pushToolResult(formatResponse.clineIgnoreError(relPath))
@ -1948,7 +1948,7 @@ export class Cline {
absolutePath,
files,
didHitLimit,
this.llmFileAccessController,
this.clineIgnoreController,
)
const completeMessage = JSON.stringify({
...sharedMessageProps,
@ -2012,7 +2012,7 @@ export class Cline {
const absolutePath = path.resolve(cwd, relDirPath)
const result = await parseSourceCodeForDefinitionsTopLevel(
absolutePath,
this.llmFileAccessController,
this.clineIgnoreController,
)
const completeMessage = JSON.stringify({
@ -2089,7 +2089,7 @@ export class Cline {
absolutePath,
regex,
filePattern,
this.llmFileAccessController,
this.clineIgnoreController,
)
const completeMessage = JSON.stringify({
@ -3236,8 +3236,8 @@ export class Cline {
.filter(Boolean)
.map((absolutePath) => path.relative(cwd, absolutePath))
// Filter paths through LLMFileAccessController
const allowedVisibleFiles = this.llmFileAccessController
// Filter paths through clineIgnoreController
const allowedVisibleFiles = this.clineIgnoreController
.filterPaths(visibleFilePaths)
.map((p) => p.toPosix())
.join("\n")
@ -3255,8 +3255,8 @@ export class Cline {
.filter(Boolean)
.map((absolutePath) => path.relative(cwd, absolutePath))
// Filter paths through LLMFileAccessController
const allowedOpenTabs = this.llmFileAccessController
// Filter paths through clineIgnoreController
const allowedOpenTabs = this.clineIgnoreController
.filterPaths(openTabPaths)
.map((p) => p.toPosix())
.join("\n")
@ -3376,7 +3376,7 @@ export class Cline {
details += "(Desktop files not shown automatically. Use list_files to explore if needed.)"
} else {
const [files, didHitLimit] = await listFiles(cwd, true, 200)
const result = formatResponse.formatFilesList(cwd, files, didHitLimit, this.llmFileAccessController)
const result = formatResponse.formatFilesList(cwd, files, didHitLimit, this.clineIgnoreController)
details += result
}
}

View file

@ -1,13 +1,13 @@
import { LLMFileAccessController } from "./LLMFileAccessController"
import { ClineIgnoreController } from "./ClineIgnoreController"
import fs from "fs/promises"
import path from "path"
import os from "os"
import { after, beforeEach, describe, it } from "mocha"
import "should"
describe("LLMFileAccessController", () => {
describe("ClineIgnoreController", () => {
let tempDir: string
let controller: LLMFileAccessController
let controller: ClineIgnoreController
beforeEach(async () => {
// Create a temp directory for testing
@ -22,7 +22,7 @@ describe("LLMFileAccessController", () => {
),
)
controller = new LLMFileAccessController(tempDir)
controller = new ClineIgnoreController(tempDir)
await controller.initialize()
})
@ -80,7 +80,7 @@ describe("LLMFileAccessController", () => {
["*.secret", "private/", "*.tmp", "data-*.json", "temp/*"].join("\n"),
)
controller = new LLMFileAccessController(tempDir)
controller = new ClineIgnoreController(tempDir)
await controller.initialize()
const results = [
@ -150,7 +150,7 @@ describe("LLMFileAccessController", () => {
["# Comment line", "*.secret", "private/", "temp.*"].join("\n"),
)
controller = new LLMFileAccessController(tempDir)
controller = new ClineIgnoreController(tempDir)
await controller.initialize()
const result = controller.validateAccess("test.secret")
@ -237,7 +237,7 @@ describe("LLMFileAccessController", () => {
await fs.mkdir(emptyDir)
try {
const controller = new LLMFileAccessController(emptyDir)
const controller = new ClineIgnoreController(emptyDir)
await controller.initialize()
const result = controller.validateAccess("file.txt")
result.should.be.true()
@ -249,7 +249,7 @@ describe("LLMFileAccessController", () => {
it("should handle empty .clineignore", async () => {
await fs.writeFile(path.join(tempDir, ".clineignore"), "")
controller = new LLMFileAccessController(tempDir)
controller = new ClineIgnoreController(tempDir)
await controller.initialize()
const result = controller.validateAccess("regular-file.txt")

View file

@ -9,7 +9,7 @@ import * as vscode from "vscode"
* Designed to be instantiated once in Cline.ts and passed to file manipulation services.
* Uses the 'ignore' library to support standard .gitignore syntax in .clineignore files.
*/
export class LLMFileAccessController {
export class ClineIgnoreController {
private cwd: string
private ignoreInstance: Ignore
private fileWatcher: vscode.FileSystemWatcher | null
@ -23,7 +23,7 @@ export class LLMFileAccessController {
constructor(cwd: string) {
this.cwd = cwd
this.ignoreInstance = ignore()
this.ignoreInstance.add(LLMFileAccessController.DEFAULT_PATTERNS)
this.ignoreInstance.add(ClineIgnoreController.DEFAULT_PATTERNS)
this.fileWatcher = null
// Set up file watcher for .clineignore
@ -93,7 +93,7 @@ export class LLMFileAccessController {
*/
private resetToDefaultPatterns(): void {
this.ignoreInstance = ignore()
this.ignoreInstance.add(LLMFileAccessController.DEFAULT_PATTERNS)
this.ignoreInstance.add(ClineIgnoreController.DEFAULT_PATTERNS)
}
/**

View file

@ -1,7 +1,7 @@
import { Anthropic } from "@anthropic-ai/sdk"
import * as path from "path"
import * as diff from "diff"
import { LLMFileAccessController } from "../../services/llm-access-control/LLMFileAccessController"
import * as path from "path"
import { ClineIgnoreController } from "../ignore/ClineIgnoreController"
export const formatResponse = {
toolDenied: () => `The user denied this operation.`,
@ -54,7 +54,7 @@ Otherwise, if you have not completed the task and do not need additional informa
absolutePath: string,
files: string[],
didHitLimit: boolean,
llmFileAccessController: LLMFileAccessController,
clineIgnoreController: ClineIgnoreController,
): string => {
const sorted = files
.map((file) => {
@ -87,13 +87,13 @@ Otherwise, if you have not completed the task and do not need additional informa
return aParts.length - bParts.length
})
const accessControlledSortedFiles = llmFileAccessController
const accessControlledSortedFiles = clineIgnoreController
? sorted.map((filePath) => {
// path is relative to absolute path, not cwd
// validateAccess expects either path relative to cwd or absolute path
// otherwise, for validating against ignore patterns like "assets/icons", we would end up with just "icons", which would result in the path not being ignored.
const absoluteFilePath = path.resolve(absolutePath, filePath)
const isIgnored = !llmFileAccessController.validateAccess(absoluteFilePath)
const isIgnored = !clineIgnoreController.validateAccess(absoluteFilePath)
if (isIgnored) {
return "\u{1F512} " + filePath
}

View file

@ -2,8 +2,8 @@ import * as vscode from "vscode"
import * as childProcess from "child_process"
import * as path from "path"
import * as readline from "readline"
import { LLMFileAccessController } from "../llm-access-control/LLMFileAccessController"
import { fileExistsAtPath } from "../../utils/fs"
import { ClineIgnoreController } from "../../core/ignore/ClineIgnoreController"
/*
This file provides functionality to perform regex searches on files using ripgrep.
@ -120,7 +120,7 @@ export async function regexSearchFiles(
directoryPath: string,
regex: string,
filePattern?: string,
llmFileAccessController?: LLMFileAccessController,
clineIgnoreController?: ClineIgnoreController,
): Promise<string> {
const vscodeAppRoot = vscode.env.appRoot
const rgPath = await getBinPath(vscodeAppRoot)
@ -173,9 +173,9 @@ export async function regexSearchFiles(
results.push(currentResult as SearchResult)
}
// Filter results using LLMFileAccessController if provided
const filteredResults = llmFileAccessController
? results.filter((result) => llmFileAccessController.validateAccess(result.filePath))
// Filter results using ClineIgnoreController if provided
const filteredResults = clineIgnoreController
? results.filter((result) => clineIgnoreController.validateAccess(result.filePath))
: results
return formatResults(filteredResults, cwd)

View file

@ -3,12 +3,12 @@ import * as path from "path"
import { listFiles } from "../glob/list-files"
import { LanguageParser, loadRequiredLanguageParsers } from "./languageParser"
import { fileExistsAtPath } from "../../utils/fs"
import { LLMFileAccessController } from "../llm-access-control/LLMFileAccessController"
import { ClineIgnoreController } from "../../core/ignore/ClineIgnoreController"
// TODO: implement caching behavior to avoid having to keep analyzing project for new tasks.
export async function parseSourceCodeForDefinitionsTopLevel(
dirPath: string,
llmFileAccessController?: LLMFileAccessController,
clineIgnoreController?: ClineIgnoreController,
): Promise<string> {
// check if the path exists
const dirExists = await fileExistsAtPath(path.resolve(dirPath))
@ -30,10 +30,10 @@ export async function parseSourceCodeForDefinitionsTopLevel(
// const filesWithoutDefinitions: string[] = []
// Filter filepaths for access if controller is provided
const allowedFilesToParse = llmFileAccessController ? llmFileAccessController.filterPaths(filesToParse) : filesToParse
const allowedFilesToParse = clineIgnoreController ? clineIgnoreController.filterPaths(filesToParse) : filesToParse
for (const filePath of allowedFilesToParse) {
const definitions = await parseFile(filePath, languageParsers, llmFileAccessController)
const definitions = await parseFile(filePath, languageParsers, clineIgnoreController)
if (definitions) {
result += `${path.relative(dirPath, filePath).toPosix()}\n${definitions}\n`
}
@ -109,9 +109,9 @@ This approach allows us to focus on the most relevant parts of the code (defined
async function parseFile(
filePath: string,
languageParsers: LanguageParser,
llmFileAccessController?: LLMFileAccessController,
clineIgnoreController?: ClineIgnoreController,
): Promise<string | null> {
if (llmFileAccessController && !llmFileAccessController.validateAccess(filePath)) {
if (clineIgnoreController && !clineIgnoreController.validateAccess(filePath)) {
return null
}
const fileContent = await fs.readFile(filePath, "utf8")