mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-10-06 02:47:56 +00:00
Co-authored-by: Roo Code <roomote@roocode.com> Co-authored-by: Daniel Riccio <ricciodaniel98@gmail.com> Co-authored-by: Daniel <57051444+daniel-lxs@users.noreply.github.com>
This commit is contained in:
parent
d720d35483
commit
0323256006
37 changed files with 1203 additions and 215 deletions
|
|
@ -72,6 +72,17 @@ export const globalSettingsSchema = z.object({
|
|||
autoCondenseContextPercent: z.number().optional(),
|
||||
maxConcurrentFileReads: z.number().optional(),
|
||||
|
||||
/**
|
||||
* Whether to include diagnostic messages (errors, warnings) in tool outputs
|
||||
* @default true
|
||||
*/
|
||||
includeDiagnosticMessages: z.boolean().optional(),
|
||||
/**
|
||||
* Maximum number of diagnostic messages to include in tool outputs
|
||||
* @default 50
|
||||
*/
|
||||
maxDiagnosticMessages: z.number().optional(),
|
||||
|
||||
browserToolEnabled: z.boolean().optional(),
|
||||
browserViewportSize: z.string().optional(),
|
||||
screenshotQuality: z.number().optional(),
|
||||
|
|
@ -261,6 +272,9 @@ export const EVALS_SETTINGS: RooCodeSettings = {
|
|||
showRooIgnoredFiles: true,
|
||||
maxReadFileLine: -1, // -1 to enable full file reading.
|
||||
|
||||
includeDiagnosticMessages: true,
|
||||
maxDiagnosticMessages: 50,
|
||||
|
||||
language: "en",
|
||||
telemetrySetting: "enabled",
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ export async function parseMentions(
|
|||
fileContextTracker?: FileContextTracker,
|
||||
rooIgnoreController?: RooIgnoreController,
|
||||
showRooIgnoredFiles: boolean = true,
|
||||
includeDiagnosticMessages: boolean = true,
|
||||
maxDiagnosticMessages: number = 50,
|
||||
): Promise<string> {
|
||||
const mentions: Set<string> = new Set()
|
||||
let parsedText = text.replace(mentionRegexGlobal, (match, mention) => {
|
||||
|
|
@ -165,7 +167,7 @@ export async function parseMentions(
|
|||
}
|
||||
} else if (mention === "problems") {
|
||||
try {
|
||||
const problems = await getWorkspaceProblems(cwd)
|
||||
const problems = await getWorkspaceProblems(cwd, includeDiagnosticMessages, maxDiagnosticMessages)
|
||||
parsedText += `\n\n<workspace_diagnostics>\n${problems}\n</workspace_diagnostics>`
|
||||
} catch (error) {
|
||||
parsedText += `\n\n<workspace_diagnostics>\nError fetching diagnostics: ${error.message}\n</workspace_diagnostics>`
|
||||
|
|
@ -286,12 +288,18 @@ async function getFileOrFolderContent(
|
|||
}
|
||||
}
|
||||
|
||||
async function getWorkspaceProblems(cwd: string): Promise<string> {
|
||||
async function getWorkspaceProblems(
|
||||
cwd: string,
|
||||
includeDiagnosticMessages: boolean = true,
|
||||
maxDiagnosticMessages: number = 50,
|
||||
): Promise<string> {
|
||||
const diagnostics = vscode.languages.getDiagnostics()
|
||||
const result = await diagnosticsToProblemsString(
|
||||
diagnostics,
|
||||
[vscode.DiagnosticSeverity.Error, vscode.DiagnosticSeverity.Warning],
|
||||
cwd,
|
||||
includeDiagnosticMessages,
|
||||
maxDiagnosticMessages,
|
||||
)
|
||||
if (!result) {
|
||||
return "No errors or warnings detected."
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ export async function processUserContentMentions({
|
|||
fileContextTracker,
|
||||
rooIgnoreController,
|
||||
showRooIgnoredFiles = true,
|
||||
includeDiagnosticMessages = true,
|
||||
maxDiagnosticMessages = 50,
|
||||
}: {
|
||||
userContent: Anthropic.Messages.ContentBlockParam[]
|
||||
cwd: string
|
||||
|
|
@ -20,6 +22,8 @@ export async function processUserContentMentions({
|
|||
fileContextTracker: FileContextTracker
|
||||
rooIgnoreController?: any
|
||||
showRooIgnoredFiles?: boolean
|
||||
includeDiagnosticMessages?: boolean
|
||||
maxDiagnosticMessages?: number
|
||||
}) {
|
||||
// Process userContent array, which contains various block types:
|
||||
// TextBlockParam, ImageBlockParam, ToolUseBlockParam, and ToolResultBlockParam.
|
||||
|
|
@ -46,6 +50,8 @@ export async function processUserContentMentions({
|
|||
fileContextTracker,
|
||||
rooIgnoreController,
|
||||
showRooIgnoredFiles,
|
||||
includeDiagnosticMessages,
|
||||
maxDiagnosticMessages,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
@ -63,6 +69,8 @@ export async function processUserContentMentions({
|
|||
fileContextTracker,
|
||||
rooIgnoreController,
|
||||
showRooIgnoredFiles,
|
||||
includeDiagnosticMessages,
|
||||
maxDiagnosticMessages,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
@ -81,6 +89,8 @@ export async function processUserContentMentions({
|
|||
fileContextTracker,
|
||||
rooIgnoreController,
|
||||
showRooIgnoredFiles,
|
||||
includeDiagnosticMessages,
|
||||
maxDiagnosticMessages,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ export class Task extends EventEmitter<ClineEvents> {
|
|||
this.consecutiveMistakeLimit = consecutiveMistakeLimit ?? DEFAULT_CONSECUTIVE_MISTAKE_LIMIT
|
||||
this.providerRef = new WeakRef(provider)
|
||||
this.globalStoragePath = provider.context.globalStorageUri.fsPath
|
||||
this.diffViewProvider = new DiffViewProvider(this.cwd)
|
||||
this.diffViewProvider = new DiffViewProvider(this.cwd, this)
|
||||
this.enableCheckpoints = enableCheckpoints
|
||||
|
||||
this.rootTask = rootTask
|
||||
|
|
@ -1225,7 +1225,11 @@ export class Task extends EventEmitter<ClineEvents> {
|
|||
}),
|
||||
)
|
||||
|
||||
const { showRooIgnoredFiles = true } = (await this.providerRef.deref()?.getState()) ?? {}
|
||||
const {
|
||||
showRooIgnoredFiles = true,
|
||||
includeDiagnosticMessages = true,
|
||||
maxDiagnosticMessages = 50,
|
||||
} = (await this.providerRef.deref()?.getState()) ?? {}
|
||||
|
||||
const parsedUserContent = await processUserContentMentions({
|
||||
userContent,
|
||||
|
|
@ -1234,6 +1238,8 @@ export class Task extends EventEmitter<ClineEvents> {
|
|||
fileContextTracker: this.fileContextTracker,
|
||||
rooIgnoreController: this.rooIgnoreController,
|
||||
showRooIgnoredFiles,
|
||||
includeDiagnosticMessages,
|
||||
maxDiagnosticMessages,
|
||||
})
|
||||
|
||||
const environmentDetails = await getEnvironmentDetails(this, includeFileDetails)
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ describe("insertContentTool", () => {
|
|||
finalContent: "final content",
|
||||
}),
|
||||
scrollToFirstDiff: vi.fn(),
|
||||
updateDiagnosticSettings: vi.fn(),
|
||||
pushToolWriteResult: vi.fn().mockImplementation(async function (
|
||||
this: any,
|
||||
task: any,
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ describe("writeToFileTool", () => {
|
|||
finalContent: "final content",
|
||||
}),
|
||||
scrollToFirstDiff: vi.fn(),
|
||||
updateDiagnosticSettings: vi.fn(),
|
||||
pushToolWriteResult: vi.fn().mockImplementation(async function (
|
||||
this: any,
|
||||
task: any,
|
||||
|
|
|
|||
|
|
@ -1439,7 +1439,8 @@ export class ClineProvider
|
|||
profileThresholds,
|
||||
alwaysAllowFollowupQuestions,
|
||||
followupAutoApproveTimeoutMs,
|
||||
diagnosticsEnabled,
|
||||
includeDiagnosticMessages,
|
||||
maxDiagnosticMessages,
|
||||
} = await this.getState()
|
||||
|
||||
const telemetryKey = process.env.POSTHOG_API_KEY
|
||||
|
|
@ -1560,7 +1561,8 @@ export class ClineProvider
|
|||
hasOpenedModeSelector: this.getGlobalState("hasOpenedModeSelector") ?? false,
|
||||
alwaysAllowFollowupQuestions: alwaysAllowFollowupQuestions ?? false,
|
||||
followupAutoApproveTimeoutMs: followupAutoApproveTimeoutMs ?? 60000,
|
||||
diagnosticsEnabled: diagnosticsEnabled ?? true,
|
||||
includeDiagnosticMessages: includeDiagnosticMessages ?? true,
|
||||
maxDiagnosticMessages: maxDiagnosticMessages ?? 50,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1726,6 +1728,9 @@ export class ClineProvider
|
|||
codebaseIndexSearchMinScore: stateValues.codebaseIndexConfig?.codebaseIndexSearchMinScore,
|
||||
},
|
||||
profileThresholds: stateValues.profileThresholds ?? {},
|
||||
// Add diagnostic message settings
|
||||
includeDiagnosticMessages: stateValues.includeDiagnosticMessages ?? true,
|
||||
maxDiagnosticMessages: stateValues.maxDiagnosticMessages ?? 50,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1254,6 +1254,16 @@ export const webviewMessageHandler = async (
|
|||
await updateGlobalState("maxConcurrentFileReads", valueToSave)
|
||||
await provider.postStateToWebview()
|
||||
break
|
||||
case "includeDiagnosticMessages":
|
||||
// Only apply default if the value is truly undefined (not false)
|
||||
const includeValue = message.bool !== undefined ? message.bool : true
|
||||
await updateGlobalState("includeDiagnosticMessages", includeValue)
|
||||
await provider.postStateToWebview()
|
||||
break
|
||||
case "maxDiagnosticMessages":
|
||||
await updateGlobalState("maxDiagnosticMessages", message.value ?? 50)
|
||||
await provider.postStateToWebview()
|
||||
break
|
||||
case "setHistoryPreviewCollapsed": // Add the new case handler
|
||||
await updateGlobalState("historyPreviewCollapsed", message.bool ?? false)
|
||||
// No need to call postStateToWebview here as the UI already updated optimistically
|
||||
|
|
|
|||
|
|
@ -383,4 +383,234 @@ describe("diagnosticsToProblemsString", () => {
|
|||
expect(vscode.workspace.fs.stat).toHaveBeenCalledWith(fileUri)
|
||||
expect(vscode.workspace.openTextDocument).toHaveBeenCalledWith(fileUri)
|
||||
})
|
||||
it("should return empty string when includeDiagnostics is false", async () => {
|
||||
// Mock file URI
|
||||
const fileUri = vscode.Uri.file("/path/to/file.ts")
|
||||
|
||||
// Create diagnostics
|
||||
const diagnostics = [
|
||||
new vscode.Diagnostic(new vscode.Range(0, 0, 0, 10), "Error message", vscode.DiagnosticSeverity.Error),
|
||||
new vscode.Diagnostic(new vscode.Range(1, 0, 1, 10), "Warning message", vscode.DiagnosticSeverity.Warning),
|
||||
]
|
||||
|
||||
// Mock fs.stat to return file type
|
||||
const mockStat = {
|
||||
type: vscode.FileType.File,
|
||||
}
|
||||
vscode.workspace.fs.stat = vitest.fn().mockResolvedValue(mockStat)
|
||||
|
||||
// Mock document content
|
||||
const mockDocument = {
|
||||
lineAt: vitest.fn((line) => ({
|
||||
text: `Line ${line + 1} content`,
|
||||
})),
|
||||
}
|
||||
vscode.workspace.openTextDocument = vitest.fn().mockResolvedValue(mockDocument)
|
||||
|
||||
// Test with includeDiagnostics set to false
|
||||
const result = await diagnosticsToProblemsString(
|
||||
[[fileUri, diagnostics]],
|
||||
[vscode.DiagnosticSeverity.Error, vscode.DiagnosticSeverity.Warning],
|
||||
"/path/to",
|
||||
false, // includeDiagnostics
|
||||
)
|
||||
|
||||
// Verify empty string is returned
|
||||
expect(result).toBe("")
|
||||
|
||||
// Verify no file operations were performed
|
||||
expect(vscode.workspace.fs.stat).not.toHaveBeenCalled()
|
||||
expect(vscode.workspace.openTextDocument).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it("should limit diagnostics based on count when maxDiagnostics is specified", async () => {
|
||||
// Mock file URI
|
||||
const fileUri = vscode.Uri.file("/path/to/file.ts")
|
||||
|
||||
// Create multiple diagnostics with varying message lengths
|
||||
const diagnostics = [
|
||||
new vscode.Diagnostic(new vscode.Range(0, 0, 0, 10), "Error 1", vscode.DiagnosticSeverity.Error),
|
||||
new vscode.Diagnostic(new vscode.Range(1, 0, 1, 10), "Warning 1", vscode.DiagnosticSeverity.Warning),
|
||||
new vscode.Diagnostic(new vscode.Range(2, 0, 2, 10), "Error 2", vscode.DiagnosticSeverity.Error),
|
||||
new vscode.Diagnostic(new vscode.Range(3, 0, 3, 10), "Warning 2", vscode.DiagnosticSeverity.Warning),
|
||||
new vscode.Diagnostic(new vscode.Range(4, 0, 4, 10), "Error 3", vscode.DiagnosticSeverity.Error),
|
||||
]
|
||||
|
||||
// Mock fs.stat to return file type
|
||||
const mockStat = {
|
||||
type: vscode.FileType.File,
|
||||
}
|
||||
vscode.workspace.fs.stat = vitest.fn().mockResolvedValue(mockStat)
|
||||
|
||||
// Mock document content
|
||||
const mockDocument = {
|
||||
lineAt: vitest.fn((line) => ({
|
||||
text: `Line ${line + 1} content`,
|
||||
})),
|
||||
}
|
||||
vscode.workspace.openTextDocument = vitest.fn().mockResolvedValue(mockDocument)
|
||||
|
||||
// Test with maxDiagnostics set to 3 (should include exactly 3 diagnostics)
|
||||
const result = await diagnosticsToProblemsString(
|
||||
[[fileUri, diagnostics]],
|
||||
[vscode.DiagnosticSeverity.Error, vscode.DiagnosticSeverity.Warning],
|
||||
"/path/to",
|
||||
true, // includeDiagnostics
|
||||
3, // maxDiagnostics (count limit)
|
||||
)
|
||||
|
||||
// Verify that exactly 3 diagnostics are included, prioritizing errors
|
||||
expect(result).toContain("Error 1")
|
||||
expect(result).toContain("Error 2")
|
||||
expect(result).toContain("Error 3")
|
||||
// Warnings should not be included since we have 3 errors and limit is 3
|
||||
expect(result).not.toContain("Warning 1")
|
||||
expect(result).not.toContain("Warning 2")
|
||||
|
||||
// Verify the limit message is included
|
||||
expect(result).toContain("2 more problems omitted to prevent context overflow")
|
||||
})
|
||||
|
||||
it("should prioritize errors over warnings when limiting diagnostics by count", async () => {
|
||||
// Mock file URIs
|
||||
const fileUri1 = vscode.Uri.file("/path/to/file1.ts")
|
||||
const fileUri2 = vscode.Uri.file("/path/to/file2.ts")
|
||||
|
||||
// Create diagnostics with mixed severities
|
||||
const diagnostics1 = [
|
||||
new vscode.Diagnostic(new vscode.Range(0, 0, 0, 10), "Warning in file1", vscode.DiagnosticSeverity.Warning),
|
||||
new vscode.Diagnostic(new vscode.Range(1, 0, 1, 10), "Error in file1", vscode.DiagnosticSeverity.Error),
|
||||
]
|
||||
|
||||
const diagnostics2 = [
|
||||
new vscode.Diagnostic(new vscode.Range(0, 0, 0, 10), "Error in file2", vscode.DiagnosticSeverity.Error),
|
||||
new vscode.Diagnostic(new vscode.Range(1, 0, 1, 10), "Warning in file2", vscode.DiagnosticSeverity.Warning),
|
||||
new vscode.Diagnostic(
|
||||
new vscode.Range(2, 0, 2, 10),
|
||||
"Info in file2",
|
||||
vscode.DiagnosticSeverity.Information,
|
||||
),
|
||||
]
|
||||
|
||||
// Mock fs.stat to return file type
|
||||
const mockStat = {
|
||||
type: vscode.FileType.File,
|
||||
}
|
||||
vscode.workspace.fs.stat = vitest.fn().mockResolvedValue(mockStat)
|
||||
|
||||
// Mock document content
|
||||
const mockDocument = {
|
||||
lineAt: vitest.fn((line) => ({
|
||||
text: `Line ${line + 1} content`,
|
||||
})),
|
||||
}
|
||||
vscode.workspace.openTextDocument = vitest.fn().mockResolvedValue(mockDocument)
|
||||
|
||||
// Test with maxDiagnostics set to 2 (should include exactly 2 diagnostics)
|
||||
const result = await diagnosticsToProblemsString(
|
||||
[
|
||||
[fileUri1, diagnostics1],
|
||||
[fileUri2, diagnostics2],
|
||||
],
|
||||
[vscode.DiagnosticSeverity.Error, vscode.DiagnosticSeverity.Warning, vscode.DiagnosticSeverity.Information],
|
||||
"/path/to",
|
||||
true, // includeDiagnostics
|
||||
2, // maxDiagnostics (count limit)
|
||||
)
|
||||
|
||||
// Verify exactly 2 errors are included (prioritized over warnings)
|
||||
expect(result).toContain("Error in file1")
|
||||
expect(result).toContain("Error in file2")
|
||||
// Warnings and info should not be included
|
||||
expect(result).not.toContain("Warning in file1")
|
||||
expect(result).not.toContain("Warning in file2")
|
||||
expect(result).not.toContain("Info in file2")
|
||||
|
||||
// Verify the limit message is included
|
||||
expect(result).toContain("3 more problems omitted to prevent context overflow")
|
||||
})
|
||||
|
||||
it("should handle maxDiagnostics with no limit when undefined", async () => {
|
||||
// Mock file URI
|
||||
const fileUri = vscode.Uri.file("/path/to/file.ts")
|
||||
|
||||
// Create multiple diagnostics
|
||||
const diagnostics = [
|
||||
new vscode.Diagnostic(new vscode.Range(0, 0, 0, 10), "Error 1", vscode.DiagnosticSeverity.Error),
|
||||
new vscode.Diagnostic(new vscode.Range(1, 0, 1, 10), "Warning 1", vscode.DiagnosticSeverity.Warning),
|
||||
new vscode.Diagnostic(new vscode.Range(2, 0, 2, 10), "Error 2", vscode.DiagnosticSeverity.Error),
|
||||
]
|
||||
|
||||
// Mock fs.stat to return file type
|
||||
const mockStat = {
|
||||
type: vscode.FileType.File,
|
||||
}
|
||||
vscode.workspace.fs.stat = vitest.fn().mockResolvedValue(mockStat)
|
||||
|
||||
// Mock document content
|
||||
const mockDocument = {
|
||||
lineAt: vitest.fn((line) => ({
|
||||
text: `Line ${line + 1} content`,
|
||||
})),
|
||||
}
|
||||
vscode.workspace.openTextDocument = vitest.fn().mockResolvedValue(mockDocument)
|
||||
|
||||
// Test with maxDiagnostics undefined
|
||||
const result = await diagnosticsToProblemsString(
|
||||
[[fileUri, diagnostics]],
|
||||
[vscode.DiagnosticSeverity.Error, vscode.DiagnosticSeverity.Warning],
|
||||
"/path/to",
|
||||
true, // includeDiagnostics
|
||||
undefined, // maxDiagnostics
|
||||
)
|
||||
|
||||
// Verify all diagnostics are included
|
||||
expect(result).toContain("Error 1")
|
||||
expect(result).toContain("Warning 1")
|
||||
expect(result).toContain("Error 2")
|
||||
|
||||
// Verify no limit message is included
|
||||
expect(result).not.toContain("(Showing")
|
||||
})
|
||||
|
||||
it("should handle maxDiagnostics of 0 as no limit", async () => {
|
||||
// Mock file URI
|
||||
const fileUri = vscode.Uri.file("/path/to/file.ts")
|
||||
|
||||
// Create multiple diagnostics
|
||||
const diagnostics = [
|
||||
new vscode.Diagnostic(new vscode.Range(0, 0, 0, 10), "Error 1", vscode.DiagnosticSeverity.Error),
|
||||
new vscode.Diagnostic(new vscode.Range(1, 0, 1, 10), "Warning 1", vscode.DiagnosticSeverity.Warning),
|
||||
]
|
||||
|
||||
// Mock fs.stat to return file type
|
||||
const mockStat = {
|
||||
type: vscode.FileType.File,
|
||||
}
|
||||
vscode.workspace.fs.stat = vitest.fn().mockResolvedValue(mockStat)
|
||||
|
||||
// Mock document content
|
||||
const mockDocument = {
|
||||
lineAt: vitest.fn((line) => ({
|
||||
text: `Line ${line + 1} content`,
|
||||
})),
|
||||
}
|
||||
vscode.workspace.openTextDocument = vitest.fn().mockResolvedValue(mockDocument)
|
||||
|
||||
// Test with maxDiagnostics set to 0
|
||||
const result = await diagnosticsToProblemsString(
|
||||
[[fileUri, diagnostics]],
|
||||
[vscode.DiagnosticSeverity.Error, vscode.DiagnosticSeverity.Warning],
|
||||
"/path/to",
|
||||
true, // includeDiagnostics
|
||||
0, // maxDiagnostics (should be treated as no limit)
|
||||
)
|
||||
|
||||
// Verify all diagnostics are included
|
||||
expect(result).toContain("Error 1")
|
||||
expect(result).toContain("Warning 1")
|
||||
|
||||
// Verify no limit message is included
|
||||
expect(result).not.toContain("(Showing")
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -74,55 +74,170 @@ export async function diagnosticsToProblemsString(
|
|||
diagnostics: [vscode.Uri, vscode.Diagnostic[]][],
|
||||
severities: vscode.DiagnosticSeverity[],
|
||||
cwd: string,
|
||||
includeDiagnosticMessages: boolean = true,
|
||||
maxDiagnosticMessages?: number,
|
||||
): Promise<string> {
|
||||
// If diagnostics are disabled, return empty string
|
||||
if (!includeDiagnosticMessages) {
|
||||
return ""
|
||||
}
|
||||
|
||||
const documents = new Map<vscode.Uri, vscode.TextDocument>()
|
||||
const fileStats = new Map<vscode.Uri, vscode.FileStat>()
|
||||
let result = ""
|
||||
for (const [uri, fileDiagnostics] of diagnostics) {
|
||||
const problems = fileDiagnostics
|
||||
.filter((d) => severities.includes(d.severity))
|
||||
.sort((a, b) => a.range.start.line - b.range.start.line)
|
||||
if (problems.length > 0) {
|
||||
result += `\n\n${path.relative(cwd, uri.fsPath).toPosix()}`
|
||||
for (const diagnostic of problems) {
|
||||
let label: string
|
||||
switch (diagnostic.severity) {
|
||||
case vscode.DiagnosticSeverity.Error:
|
||||
label = "Error"
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Warning:
|
||||
label = "Warning"
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Information:
|
||||
label = "Information"
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Hint:
|
||||
label = "Hint"
|
||||
break
|
||||
default:
|
||||
label = "Diagnostic"
|
||||
|
||||
// If we have a limit, use count-based limiting
|
||||
if (maxDiagnosticMessages && maxDiagnosticMessages > 0) {
|
||||
let includedCount = 0
|
||||
let totalCount = 0
|
||||
|
||||
// Flatten all diagnostics with their URIs
|
||||
const allDiagnostics: { uri: vscode.Uri; diagnostic: vscode.Diagnostic; formattedText?: string }[] = []
|
||||
for (const [uri, fileDiagnostics] of diagnostics) {
|
||||
const filtered = fileDiagnostics.filter((d) => severities.includes(d.severity))
|
||||
for (const diagnostic of filtered) {
|
||||
allDiagnostics.push({ uri, diagnostic })
|
||||
totalCount++
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by severity (errors first) and then by line number
|
||||
allDiagnostics.sort((a, b) => {
|
||||
const severityDiff = a.diagnostic.severity - b.diagnostic.severity
|
||||
if (severityDiff !== 0) return severityDiff
|
||||
return a.diagnostic.range.start.line - b.diagnostic.range.start.line
|
||||
})
|
||||
|
||||
// Process diagnostics up to the count limit
|
||||
const includedDiagnostics: typeof allDiagnostics = []
|
||||
for (const item of allDiagnostics) {
|
||||
// Stop if we've reached the count limit
|
||||
if (includedCount >= maxDiagnosticMessages) {
|
||||
break
|
||||
}
|
||||
|
||||
// Format the diagnostic
|
||||
let label: string
|
||||
switch (item.diagnostic.severity) {
|
||||
case vscode.DiagnosticSeverity.Error:
|
||||
label = "Error"
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Warning:
|
||||
label = "Warning"
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Information:
|
||||
label = "Information"
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Hint:
|
||||
label = "Hint"
|
||||
break
|
||||
default:
|
||||
label = "Diagnostic"
|
||||
}
|
||||
const line = item.diagnostic.range.start.line + 1
|
||||
const source = item.diagnostic.source ? `${item.diagnostic.source} ` : ""
|
||||
|
||||
// Pre-format the diagnostic text
|
||||
let diagnosticText = ""
|
||||
try {
|
||||
let fileStat = fileStats.get(item.uri)
|
||||
if (!fileStat) {
|
||||
fileStat = await vscode.workspace.fs.stat(item.uri)
|
||||
fileStats.set(item.uri, fileStat)
|
||||
}
|
||||
const line = diagnostic.range.start.line + 1 // VSCode lines are 0-indexed
|
||||
const source = diagnostic.source ? `${diagnostic.source} ` : ""
|
||||
try {
|
||||
let fileStat = fileStats.get(uri)
|
||||
if (!fileStat) {
|
||||
fileStat = await vscode.workspace.fs.stat(uri)
|
||||
fileStats.set(uri, fileStat)
|
||||
if (fileStat.type === vscode.FileType.File) {
|
||||
const document = documents.get(item.uri) || (await vscode.workspace.openTextDocument(item.uri))
|
||||
documents.set(item.uri, document)
|
||||
const lineContent = document.lineAt(item.diagnostic.range.start.line).text
|
||||
diagnosticText = `\n- [${source}${label}] ${line} | ${lineContent} : ${item.diagnostic.message}`
|
||||
} else {
|
||||
diagnosticText = `\n- [${source}${label}] 1 | (directory) : ${item.diagnostic.message}`
|
||||
}
|
||||
} catch {
|
||||
diagnosticText = `\n- [${source}${label}] ${line} | (unavailable) : ${item.diagnostic.message}`
|
||||
}
|
||||
|
||||
item.formattedText = diagnosticText
|
||||
includedDiagnostics.push(item)
|
||||
includedCount++
|
||||
}
|
||||
|
||||
// Group included diagnostics by URI for output
|
||||
const groupedDiagnostics = new Map<string, { uri: vscode.Uri; diagnostics: typeof allDiagnostics }>()
|
||||
for (const item of includedDiagnostics) {
|
||||
const key = item.uri.toString()
|
||||
if (!groupedDiagnostics.has(key)) {
|
||||
groupedDiagnostics.set(key, { uri: item.uri, diagnostics: [] })
|
||||
}
|
||||
groupedDiagnostics.get(key)!.diagnostics.push(item)
|
||||
}
|
||||
|
||||
// Build the output
|
||||
for (const { uri, diagnostics: fileDiagnostics } of groupedDiagnostics.values()) {
|
||||
const sortedDiagnostics = fileDiagnostics.sort(
|
||||
(a, b) => a.diagnostic.range.start.line - b.diagnostic.range.start.line,
|
||||
)
|
||||
if (sortedDiagnostics.length > 0) {
|
||||
result += `\n\n${path.relative(cwd, uri.fsPath).toPosix()}`
|
||||
for (const item of sortedDiagnostics) {
|
||||
result += item.formattedText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add a note if we hit the limit
|
||||
if (totalCount > includedCount) {
|
||||
result += `\n\n... ${totalCount - includedCount} more problems omitted to prevent context overflow`
|
||||
}
|
||||
} else {
|
||||
// No limit, process all diagnostics as before
|
||||
for (const [uri, fileDiagnostics] of diagnostics) {
|
||||
const problems = fileDiagnostics
|
||||
.filter((d) => severities.includes(d.severity))
|
||||
.sort((a, b) => a.range.start.line - b.range.start.line)
|
||||
if (problems.length > 0) {
|
||||
result += `\n\n${path.relative(cwd, uri.fsPath).toPosix()}`
|
||||
for (const diagnostic of problems) {
|
||||
let label: string
|
||||
switch (diagnostic.severity) {
|
||||
case vscode.DiagnosticSeverity.Error:
|
||||
label = "Error"
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Warning:
|
||||
label = "Warning"
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Information:
|
||||
label = "Information"
|
||||
break
|
||||
case vscode.DiagnosticSeverity.Hint:
|
||||
label = "Hint"
|
||||
break
|
||||
default:
|
||||
label = "Diagnostic"
|
||||
}
|
||||
if (fileStat.type === vscode.FileType.File) {
|
||||
const document = documents.get(uri) || (await vscode.workspace.openTextDocument(uri))
|
||||
documents.set(uri, document)
|
||||
const lineContent = document.lineAt(diagnostic.range.start.line).text
|
||||
result += `\n- [${source}${label}] ${line} | ${lineContent} : ${diagnostic.message}`
|
||||
} else {
|
||||
result += `\n- [${source}${label}] 1 | (directory) : ${diagnostic.message}`
|
||||
const line = diagnostic.range.start.line + 1 // VSCode lines are 0-indexed
|
||||
const source = diagnostic.source ? `${diagnostic.source} ` : ""
|
||||
try {
|
||||
let fileStat = fileStats.get(uri)
|
||||
if (!fileStat) {
|
||||
fileStat = await vscode.workspace.fs.stat(uri)
|
||||
fileStats.set(uri, fileStat)
|
||||
}
|
||||
if (fileStat.type === vscode.FileType.File) {
|
||||
const document = documents.get(uri) || (await vscode.workspace.openTextDocument(uri))
|
||||
documents.set(uri, document)
|
||||
const lineContent = document.lineAt(diagnostic.range.start.line).text
|
||||
result += `\n- [${source}${label}] ${line} | ${lineContent} : ${diagnostic.message}`
|
||||
} else {
|
||||
result += `\n- [${source}${label}] 1 | (directory) : ${diagnostic.message}`
|
||||
}
|
||||
} catch {
|
||||
result += `\n- [${source}${label}] ${line} | (unavailable) : ${diagnostic.message}`
|
||||
}
|
||||
} catch {
|
||||
result += `\n- [${source}${label}] ${line} | (unavailable) : ${diagnostic.message}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.trim()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,14 @@ export class DiffViewProvider {
|
|||
private activeLineController?: DecorationController
|
||||
private streamedLines: string[] = []
|
||||
private preDiagnostics: [vscode.Uri, vscode.Diagnostic[]][] = []
|
||||
private taskRef: WeakRef<Task>
|
||||
|
||||
constructor(private cwd: string) {}
|
||||
constructor(
|
||||
private cwd: string,
|
||||
task: Task,
|
||||
) {
|
||||
this.taskRef = new WeakRef(task)
|
||||
}
|
||||
|
||||
async open(relPath: string): Promise<void> {
|
||||
this.relPath = relPath
|
||||
|
|
@ -234,12 +240,20 @@ export class DiffViewProvider {
|
|||
|
||||
const postDiagnostics = vscode.languages.getDiagnostics()
|
||||
|
||||
// Get diagnostic settings from state
|
||||
const task = this.taskRef.deref()
|
||||
const state = await task?.providerRef.deref()?.getState()
|
||||
const includeDiagnosticMessages = state?.includeDiagnosticMessages ?? true
|
||||
const maxDiagnosticMessages = state?.maxDiagnosticMessages ?? 50
|
||||
|
||||
const newProblems = await diagnosticsToProblemsString(
|
||||
getNewDiagnostics(this.preDiagnostics, postDiagnostics),
|
||||
[
|
||||
vscode.DiagnosticSeverity.Error, // only including errors since warnings can be distracting (if user wants to fix warnings they can use the @problems mention)
|
||||
],
|
||||
this.cwd,
|
||||
includeDiagnosticMessages,
|
||||
maxDiagnosticMessages,
|
||||
) // Will be empty string if no errors.
|
||||
|
||||
newProblemsMessage =
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ describe("DiffViewProvider", () => {
|
|||
let diffViewProvider: DiffViewProvider
|
||||
const mockCwd = "/mock/cwd"
|
||||
let mockWorkspaceEdit: { replace: any; delete: any }
|
||||
let mockTask: any
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
|
|
@ -110,7 +111,19 @@ describe("DiffViewProvider", () => {
|
|||
}
|
||||
vi.mocked(vscode.WorkspaceEdit).mockImplementation(() => mockWorkspaceEdit as any)
|
||||
|
||||
diffViewProvider = new DiffViewProvider(mockCwd)
|
||||
// Create a mock Task instance
|
||||
mockTask = {
|
||||
providerRef: {
|
||||
deref: vi.fn().mockReturnValue({
|
||||
getState: vi.fn().mockResolvedValue({
|
||||
includeDiagnosticMessages: true,
|
||||
maxDiagnosticMessages: 50,
|
||||
}),
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
diffViewProvider = new DiffViewProvider(mockCwd, mockTask)
|
||||
// Mock the necessary properties and methods
|
||||
;(diffViewProvider as any).relPath = "test.txt"
|
||||
;(diffViewProvider as any).activeDiffEditor = {
|
||||
|
|
|
|||
|
|
@ -234,6 +234,8 @@ export type ExtensionState = Pick<
|
|||
| "codebaseIndexConfig"
|
||||
| "codebaseIndexModels"
|
||||
| "profileThresholds"
|
||||
| "includeDiagnosticMessages"
|
||||
| "maxDiagnosticMessages"
|
||||
> & {
|
||||
version: string
|
||||
clineMessages: ClineMessage[]
|
||||
|
|
|
|||
|
|
@ -162,6 +162,8 @@ export interface WebviewMessage {
|
|||
| "language"
|
||||
| "maxReadFileLine"
|
||||
| "maxConcurrentFileReads"
|
||||
| "includeDiagnosticMessages"
|
||||
| "maxDiagnosticMessages"
|
||||
| "searchFiles"
|
||||
| "toggleApiConfigPin"
|
||||
| "setHistoryPreviewCollapsed"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ type AutoApproveSettingsProps = HTMLAttributes<HTMLDivElement> & {
|
|||
alwaysAllowWrite?: boolean
|
||||
alwaysAllowWriteOutsideWorkspace?: boolean
|
||||
alwaysAllowWriteProtected?: boolean
|
||||
writeDelayMs: number
|
||||
alwaysAllowBrowser?: boolean
|
||||
alwaysApproveResubmit?: boolean
|
||||
requestDelaySeconds: number
|
||||
|
|
@ -39,7 +38,6 @@ type AutoApproveSettingsProps = HTMLAttributes<HTMLDivElement> & {
|
|||
| "alwaysAllowWrite"
|
||||
| "alwaysAllowWriteOutsideWorkspace"
|
||||
| "alwaysAllowWriteProtected"
|
||||
| "writeDelayMs"
|
||||
| "alwaysAllowBrowser"
|
||||
| "alwaysApproveResubmit"
|
||||
| "requestDelaySeconds"
|
||||
|
|
@ -61,7 +59,6 @@ export const AutoApproveSettings = ({
|
|||
alwaysAllowWrite,
|
||||
alwaysAllowWriteOutsideWorkspace,
|
||||
alwaysAllowWriteProtected,
|
||||
writeDelayMs,
|
||||
alwaysAllowBrowser,
|
||||
alwaysApproveResubmit,
|
||||
requestDelaySeconds,
|
||||
|
|
@ -216,22 +213,6 @@ export const AutoApproveSettings = ({
|
|||
{t("settings:autoApprove.write.protected.description")}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Slider
|
||||
min={0}
|
||||
max={5000}
|
||||
step={100}
|
||||
value={[writeDelayMs]}
|
||||
onValueChange={([value]) => setCachedStateField("writeDelayMs", value)}
|
||||
data-testid="write-delay-slider"
|
||||
/>
|
||||
<span className="w-20">{writeDelayMs}ms</span>
|
||||
</div>
|
||||
<div className="text-vscode-descriptionForeground text-sm mt-1">
|
||||
{t("settings:autoApprove.write.delayLabel")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
|
|||
import { Database, FoldVertical } from "lucide-react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Slider } from "@/components/ui"
|
||||
import { Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Slider, Button } from "@/components/ui"
|
||||
|
||||
import { SetCachedStateField } from "./types"
|
||||
import { SectionHeader } from "./SectionHeader"
|
||||
|
|
@ -22,6 +22,9 @@ type ContextManagementSettingsProps = HTMLAttributes<HTMLDivElement> & {
|
|||
maxReadFileLine?: number
|
||||
maxConcurrentFileReads?: number
|
||||
profileThresholds?: Record<string, number>
|
||||
includeDiagnosticMessages?: boolean
|
||||
maxDiagnosticMessages?: number
|
||||
writeDelayMs: number
|
||||
setCachedStateField: SetCachedStateField<
|
||||
| "autoCondenseContext"
|
||||
| "autoCondenseContextPercent"
|
||||
|
|
@ -31,6 +34,9 @@ type ContextManagementSettingsProps = HTMLAttributes<HTMLDivElement> & {
|
|||
| "maxReadFileLine"
|
||||
| "maxConcurrentFileReads"
|
||||
| "profileThresholds"
|
||||
| "includeDiagnosticMessages"
|
||||
| "maxDiagnosticMessages"
|
||||
| "writeDelayMs"
|
||||
>
|
||||
}
|
||||
|
||||
|
|
@ -45,6 +51,9 @@ export const ContextManagementSettings = ({
|
|||
maxReadFileLine,
|
||||
maxConcurrentFileReads,
|
||||
profileThresholds = {},
|
||||
includeDiagnosticMessages,
|
||||
maxDiagnosticMessages,
|
||||
writeDelayMs,
|
||||
className,
|
||||
...props
|
||||
}: ContextManagementSettingsProps) => {
|
||||
|
|
@ -196,6 +205,95 @@ export const ContextManagementSettings = ({
|
|||
{t("settings:contextManagement.maxReadFile.description")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<VSCodeCheckbox
|
||||
checked={includeDiagnosticMessages}
|
||||
onChange={(e: any) => setCachedStateField("includeDiagnosticMessages", e.target.checked)}
|
||||
data-testid="include-diagnostic-messages-checkbox">
|
||||
<label className="block font-medium mb-1">
|
||||
{t("settings:contextManagement.diagnostics.includeMessages.label")}
|
||||
</label>
|
||||
</VSCodeCheckbox>
|
||||
<div className="text-vscode-descriptionForeground text-sm mt-1 mb-3">
|
||||
{t("settings:contextManagement.diagnostics.includeMessages.description")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span className="block font-medium mb-1">
|
||||
{t("settings:contextManagement.diagnostics.maxMessages.label")}
|
||||
</span>
|
||||
<div className="flex items-center gap-2">
|
||||
<Slider
|
||||
min={1}
|
||||
max={100}
|
||||
step={1}
|
||||
value={[
|
||||
maxDiagnosticMessages !== undefined && maxDiagnosticMessages <= 0
|
||||
? 100
|
||||
: (maxDiagnosticMessages ?? 50),
|
||||
]}
|
||||
onValueChange={([value]) => {
|
||||
// When slider reaches 100, set to -1 (unlimited)
|
||||
setCachedStateField("maxDiagnosticMessages", value === 100 ? -1 : value)
|
||||
}}
|
||||
data-testid="max-diagnostic-messages-slider"
|
||||
aria-label={t("settings:contextManagement.diagnostics.maxMessages.label")}
|
||||
aria-valuemin={1}
|
||||
aria-valuemax={100}
|
||||
aria-valuenow={
|
||||
maxDiagnosticMessages !== undefined && maxDiagnosticMessages <= 0
|
||||
? 100
|
||||
: (maxDiagnosticMessages ?? 50)
|
||||
}
|
||||
aria-valuetext={
|
||||
(maxDiagnosticMessages !== undefined && maxDiagnosticMessages <= 0) ||
|
||||
maxDiagnosticMessages === 100
|
||||
? t("settings:contextManagement.diagnostics.maxMessages.unlimitedLabel")
|
||||
: `${maxDiagnosticMessages ?? 50} ${t("settings:contextManagement.diagnostics.maxMessages.label")}`
|
||||
}
|
||||
/>
|
||||
<span className="w-20 text-sm font-medium">
|
||||
{(maxDiagnosticMessages !== undefined && maxDiagnosticMessages <= 0) ||
|
||||
maxDiagnosticMessages === 100
|
||||
? t("settings:contextManagement.diagnostics.maxMessages.unlimitedLabel")
|
||||
: (maxDiagnosticMessages ?? 50)}
|
||||
</span>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => setCachedStateField("maxDiagnosticMessages", 50)}
|
||||
title={t("settings:contextManagement.diagnostics.maxMessages.resetTooltip")}
|
||||
className="p-1 h-6 w-6"
|
||||
disabled={maxDiagnosticMessages === 50}>
|
||||
<span className="codicon codicon-discard" />
|
||||
</Button>
|
||||
</div>
|
||||
<div className="text-vscode-descriptionForeground text-sm mt-1">
|
||||
{t("settings:contextManagement.diagnostics.maxMessages.description")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span className="block font-medium mb-1">
|
||||
{t("settings:contextManagement.diagnostics.delayAfterWrite.label")}
|
||||
</span>
|
||||
<div className="flex items-center gap-2">
|
||||
<Slider
|
||||
min={0}
|
||||
max={5000}
|
||||
step={100}
|
||||
value={[writeDelayMs]}
|
||||
onValueChange={([value]) => setCachedStateField("writeDelayMs", value)}
|
||||
data-testid="write-delay-slider"
|
||||
/>
|
||||
<span className="w-20">{writeDelayMs}ms</span>
|
||||
</div>
|
||||
<div className="text-vscode-descriptionForeground text-sm mt-1">
|
||||
{t("settings:contextManagement.diagnostics.delayAfterWrite.description")}
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
<Section className="pt-2">
|
||||
<VSCodeCheckbox
|
||||
|
|
|
|||
|
|
@ -177,6 +177,8 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
|
|||
alwaysAllowFollowupQuestions,
|
||||
alwaysAllowUpdateTodoList,
|
||||
followupAutoApproveTimeoutMs,
|
||||
includeDiagnosticMessages,
|
||||
maxDiagnosticMessages,
|
||||
} = cachedState
|
||||
|
||||
const apiConfiguration = useMemo(() => cachedState.apiConfiguration ?? {}, [cachedState.apiConfiguration])
|
||||
|
|
@ -320,6 +322,8 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
|
|||
vscode.postMessage({ type: "showRooIgnoredFiles", bool: showRooIgnoredFiles })
|
||||
vscode.postMessage({ type: "maxReadFileLine", value: maxReadFileLine ?? -1 })
|
||||
vscode.postMessage({ type: "maxConcurrentFileReads", value: cachedState.maxConcurrentFileReads ?? 5 })
|
||||
vscode.postMessage({ type: "includeDiagnosticMessages", bool: includeDiagnosticMessages })
|
||||
vscode.postMessage({ type: "maxDiagnosticMessages", value: maxDiagnosticMessages ?? 50 })
|
||||
vscode.postMessage({ type: "currentApiConfigName", text: currentApiConfigName })
|
||||
vscode.postMessage({ type: "updateExperimental", values: experiments })
|
||||
vscode.postMessage({ type: "alwaysAllowModeSwitch", bool: alwaysAllowModeSwitch })
|
||||
|
|
@ -606,7 +610,6 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
|
|||
alwaysAllowWrite={alwaysAllowWrite}
|
||||
alwaysAllowWriteOutsideWorkspace={alwaysAllowWriteOutsideWorkspace}
|
||||
alwaysAllowWriteProtected={alwaysAllowWriteProtected}
|
||||
writeDelayMs={writeDelayMs}
|
||||
alwaysAllowBrowser={alwaysAllowBrowser}
|
||||
alwaysApproveResubmit={alwaysApproveResubmit}
|
||||
requestDelaySeconds={requestDelaySeconds}
|
||||
|
|
@ -666,6 +669,9 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
|
|||
maxReadFileLine={maxReadFileLine}
|
||||
maxConcurrentFileReads={maxConcurrentFileReads}
|
||||
profileThresholds={profileThresholds}
|
||||
includeDiagnosticMessages={includeDiagnosticMessages}
|
||||
maxDiagnosticMessages={maxDiagnosticMessages}
|
||||
writeDelayMs={writeDelayMs}
|
||||
setCachedStateField={setCachedStateField}
|
||||
/>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,122 +1,320 @@
|
|||
import { render, screen, fireEvent } from "@/utils/test-utils"
|
||||
// npx vitest src/components/settings/__tests__/ContextManagementSettings.spec.tsx
|
||||
|
||||
import { ContextManagementSettings } from "@src/components/settings/ContextManagementSettings"
|
||||
import { render, screen, fireEvent, waitFor } from "@/utils/test-utils"
|
||||
import { ContextManagementSettings } from "../ContextManagementSettings"
|
||||
|
||||
// Mock translation hook to return the key as the translation
|
||||
vitest.mock("@/i18n/TranslationContext", () => ({
|
||||
// Mock the translation hook
|
||||
vi.mock("@/hooks/useAppTranslation", () => ({
|
||||
useAppTranslation: () => ({
|
||||
t: (key: string) => key,
|
||||
t: (key: string) => {
|
||||
// Return specific translations for our test cases
|
||||
if (key === "settings:contextManagement.diagnostics.maxMessages.unlimitedLabel") {
|
||||
return "Unlimited"
|
||||
}
|
||||
return key
|
||||
},
|
||||
}),
|
||||
}))
|
||||
|
||||
// Mock the UI components
|
||||
vi.mock("@/components/ui", () => ({
|
||||
...vi.importActual("@/components/ui"),
|
||||
Slider: ({ value, onValueChange, "data-testid": dataTestId, disabled }: any) => (
|
||||
<input
|
||||
type="range"
|
||||
value={value?.[0] ?? 0}
|
||||
onChange={(e) => onValueChange([parseFloat(e.target.value)])}
|
||||
onKeyDown={(e) => {
|
||||
const currentValue = value?.[0] ?? 0
|
||||
if (e.key === "ArrowRight") {
|
||||
onValueChange([currentValue + 1])
|
||||
} else if (e.key === "ArrowLeft") {
|
||||
onValueChange([currentValue - 1])
|
||||
}
|
||||
}}
|
||||
data-testid={dataTestId}
|
||||
disabled={disabled}
|
||||
role="slider"
|
||||
/>
|
||||
),
|
||||
Input: ({ value, onChange, "data-testid": dataTestId, ...props }: any) => (
|
||||
<input value={value} onChange={onChange} data-testid={dataTestId} {...props} />
|
||||
),
|
||||
Button: ({ children, onClick, ...props }: any) => (
|
||||
<button onClick={onClick} {...props}>
|
||||
{children}
|
||||
</button>
|
||||
),
|
||||
Select: ({ children, ...props }: any) => (
|
||||
<div role="combobox" {...props}>
|
||||
{children}
|
||||
</div>
|
||||
),
|
||||
SelectTrigger: ({ children, ...props }: any) => <div {...props}>{children}</div>,
|
||||
SelectValue: ({ children, ...props }: any) => <div {...props}>{children}</div>,
|
||||
SelectContent: ({ children, ...props }: any) => <div {...props}>{children}</div>,
|
||||
SelectItem: ({ children, ...props }: any) => <div {...props}>{children}</div>,
|
||||
}))
|
||||
|
||||
// Mock vscode utilities - this is necessary since we're not in a VSCode environment
|
||||
|
||||
vitest.mock("@/utils/vscode", () => ({
|
||||
vi.mock("@/utils/vscode", () => ({
|
||||
vscode: {
|
||||
postMessage: vitest.fn(),
|
||||
postMessage: vi.fn(),
|
||||
},
|
||||
}))
|
||||
|
||||
// Mock VSCode components to behave like standard HTML elements
|
||||
vitest.mock("@vscode/webview-ui-toolkit/react", () => ({
|
||||
vi.mock("@vscode/webview-ui-toolkit/react", () => ({
|
||||
VSCodeCheckbox: ({ checked, onChange, children, "data-testid": dataTestId, ...props }: any) => (
|
||||
<div>
|
||||
<label data-testid={dataTestId} {...props}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={checked}
|
||||
onChange={onChange}
|
||||
data-testid={dataTestId}
|
||||
aria-label={children?.props?.children || children}
|
||||
role="checkbox"
|
||||
aria-checked={checked}
|
||||
{...props}
|
||||
checked={checked || false}
|
||||
aria-checked={checked || false}
|
||||
onChange={(e: any) => onChange?.({ target: { checked: e.target.checked } })}
|
||||
/>
|
||||
{children}
|
||||
</div>
|
||||
),
|
||||
VSCodeTextArea: ({ value, onChange, rows, className, ...props }: any) => (
|
||||
<textarea value={value} onChange={onChange} rows={rows} className={className} role="textbox" {...props} />
|
||||
</label>
|
||||
),
|
||||
VSCodeTextArea: ({ value, onChange, ...props }: any) => <textarea value={value} onChange={onChange} {...props} />,
|
||||
}))
|
||||
|
||||
describe("ContextManagementSettings", () => {
|
||||
const defaultProps = {
|
||||
autoCondenseContext: true,
|
||||
autoCondenseContextPercent: 100,
|
||||
autoCondenseContext: false,
|
||||
autoCondenseContextPercent: 80,
|
||||
condensingApiConfigId: undefined,
|
||||
customCondensingPrompt: undefined,
|
||||
listApiConfigMeta: [],
|
||||
maxOpenTabsContext: 20,
|
||||
maxWorkspaceFiles: 200,
|
||||
showRooIgnoredFiles: false,
|
||||
setCachedStateField: vitest.fn(),
|
||||
maxReadFileLine: -1,
|
||||
maxConcurrentFileReads: 5,
|
||||
profileThresholds: {},
|
||||
includeDiagnosticMessages: true,
|
||||
maxDiagnosticMessages: 50,
|
||||
writeDelayMs: 1000,
|
||||
setCachedStateField: vi.fn(),
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
vitest.clearAllMocks()
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
it("renders all controls", () => {
|
||||
it("renders diagnostic settings", () => {
|
||||
render(<ContextManagementSettings {...defaultProps} />)
|
||||
|
||||
// Open tabs context limit
|
||||
const openTabsSlider = screen.getByTestId("open-tabs-limit-slider")
|
||||
expect(openTabsSlider).toBeInTheDocument()
|
||||
// Check for diagnostic checkbox
|
||||
expect(screen.getByTestId("include-diagnostic-messages-checkbox")).toBeInTheDocument()
|
||||
|
||||
// Workspace files limit
|
||||
const workspaceFilesSlider = screen.getByTestId("workspace-files-limit-slider")
|
||||
expect(workspaceFilesSlider).toBeInTheDocument()
|
||||
|
||||
// Show .rooignore'd files
|
||||
const showRooIgnoredFilesCheckbox = screen.getByTestId("show-rooignored-files-checkbox")
|
||||
expect(showRooIgnoredFilesCheckbox).toBeInTheDocument()
|
||||
expect(screen.getByTestId("show-rooignored-files-checkbox")).not.toBeChecked()
|
||||
// Check for slider
|
||||
expect(screen.getByTestId("max-diagnostic-messages-slider")).toBeInTheDocument()
|
||||
expect(screen.getByText("50")).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it("updates open tabs context limit", () => {
|
||||
const mockSetCachedStateField = vitest.fn()
|
||||
const props = { ...defaultProps, setCachedStateField: mockSetCachedStateField }
|
||||
render(<ContextManagementSettings {...props} />)
|
||||
it("renders with diagnostic messages enabled", () => {
|
||||
render(<ContextManagementSettings {...defaultProps} includeDiagnosticMessages={true} />)
|
||||
|
||||
const slider = screen.getByTestId("open-tabs-limit-slider")
|
||||
const checkbox = screen.getByTestId("include-diagnostic-messages-checkbox")
|
||||
expect(checkbox.querySelector("input")).toBeChecked()
|
||||
|
||||
const slider = screen.getByTestId("max-diagnostic-messages-slider")
|
||||
expect(slider).toBeInTheDocument()
|
||||
|
||||
// Check that the current value is displayed
|
||||
expect(screen.getByText("20")).toBeInTheDocument()
|
||||
|
||||
// Test slider interaction using keyboard events (ArrowRight increases value)
|
||||
slider.focus()
|
||||
fireEvent.keyDown(slider, { key: "ArrowRight" })
|
||||
|
||||
// The callback should have been called with the new value (20 + 1 = 21)
|
||||
expect(mockSetCachedStateField).toHaveBeenCalledWith("maxOpenTabsContext", 21)
|
||||
expect(slider).toHaveValue("50")
|
||||
})
|
||||
|
||||
it("updates workspace files limit", () => {
|
||||
const mockSetCachedStateField = vitest.fn()
|
||||
const props = { ...defaultProps, setCachedStateField: mockSetCachedStateField }
|
||||
render(<ContextManagementSettings {...props} />)
|
||||
it("renders with diagnostic messages disabled", () => {
|
||||
render(<ContextManagementSettings {...defaultProps} includeDiagnosticMessages={false} />)
|
||||
|
||||
const slider = screen.getByTestId("workspace-files-limit-slider")
|
||||
expect(slider).toBeInTheDocument()
|
||||
const checkbox = screen.getByTestId("include-diagnostic-messages-checkbox")
|
||||
expect(checkbox.querySelector("input")).not.toBeChecked()
|
||||
|
||||
// Check that the current value is displayed
|
||||
expect(screen.getByText("200")).toBeInTheDocument()
|
||||
|
||||
// Test slider interaction using keyboard events (ArrowRight increases value)
|
||||
slider.focus()
|
||||
fireEvent.keyDown(slider, { key: "ArrowRight" })
|
||||
|
||||
// The callback should have been called with the new value (200 + 1 = 201)
|
||||
expect(mockSetCachedStateField).toHaveBeenCalledWith("maxWorkspaceFiles", 201)
|
||||
// Slider should still be rendered when diagnostics are disabled
|
||||
expect(screen.getByTestId("max-diagnostic-messages-slider")).toBeInTheDocument()
|
||||
expect(screen.getByText("50")).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it("updates show rooignored files setting", () => {
|
||||
render(<ContextManagementSettings {...defaultProps} />)
|
||||
it("calls setCachedStateField when include diagnostic messages checkbox is toggled", async () => {
|
||||
const setCachedStateField = vi.fn()
|
||||
render(<ContextManagementSettings {...defaultProps} setCachedStateField={setCachedStateField} />)
|
||||
|
||||
const checkbox = screen.getByTestId("show-rooignored-files-checkbox")
|
||||
const checkbox = screen.getByTestId("include-diagnostic-messages-checkbox").querySelector("input")!
|
||||
fireEvent.click(checkbox)
|
||||
|
||||
expect(defaultProps.setCachedStateField).toHaveBeenCalledWith("showRooIgnoredFiles", true)
|
||||
await waitFor(() => {
|
||||
expect(setCachedStateField).toHaveBeenCalledWith("includeDiagnosticMessages", false)
|
||||
})
|
||||
})
|
||||
|
||||
it("calls setCachedStateField when max diagnostic messages slider is changed", async () => {
|
||||
const setCachedStateField = vi.fn()
|
||||
render(<ContextManagementSettings {...defaultProps} setCachedStateField={setCachedStateField} />)
|
||||
|
||||
const slider = screen.getByTestId("max-diagnostic-messages-slider")
|
||||
fireEvent.change(slider, { target: { value: "100" } })
|
||||
|
||||
await waitFor(() => {
|
||||
expect(setCachedStateField).toHaveBeenCalledWith("maxDiagnosticMessages", -1)
|
||||
})
|
||||
})
|
||||
|
||||
it("keeps slider visible when include diagnostic messages is unchecked", () => {
|
||||
const { rerender } = render(<ContextManagementSettings {...defaultProps} includeDiagnosticMessages={true} />)
|
||||
|
||||
const slider = screen.getByTestId("max-diagnostic-messages-slider")
|
||||
expect(slider).toBeInTheDocument()
|
||||
|
||||
// Update to disabled - slider should still be visible
|
||||
rerender(<ContextManagementSettings {...defaultProps} includeDiagnosticMessages={false} />)
|
||||
expect(screen.getByTestId("max-diagnostic-messages-slider")).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it("displays correct max diagnostic messages value", () => {
|
||||
const { rerender } = render(<ContextManagementSettings {...defaultProps} maxDiagnosticMessages={25} />)
|
||||
|
||||
expect(screen.getByText("25")).toBeInTheDocument()
|
||||
|
||||
// Update value - 100 should display as "Unlimited"
|
||||
rerender(<ContextManagementSettings {...defaultProps} maxDiagnosticMessages={100} />)
|
||||
expect(
|
||||
screen.getByText("settings:contextManagement.diagnostics.maxMessages.unlimitedLabel"),
|
||||
).toBeInTheDocument()
|
||||
|
||||
// Test unlimited value (-1) displays as "Unlimited"
|
||||
rerender(<ContextManagementSettings {...defaultProps} maxDiagnosticMessages={-1} />)
|
||||
expect(
|
||||
screen.getByText("settings:contextManagement.diagnostics.maxMessages.unlimitedLabel"),
|
||||
).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it("renders other context management settings", () => {
|
||||
render(<ContextManagementSettings {...defaultProps} />)
|
||||
|
||||
// Check for other sliders
|
||||
expect(screen.getByTestId("open-tabs-limit-slider")).toBeInTheDocument()
|
||||
expect(screen.getByTestId("workspace-files-limit-slider")).toBeInTheDocument()
|
||||
expect(screen.getByTestId("max-concurrent-file-reads-slider")).toBeInTheDocument()
|
||||
|
||||
// Check for checkboxes
|
||||
expect(screen.getByTestId("show-rooignored-files-checkbox")).toBeInTheDocument()
|
||||
expect(screen.getByTestId("auto-condense-context-checkbox")).toBeInTheDocument()
|
||||
})
|
||||
|
||||
describe("Edge cases for maxDiagnosticMessages", () => {
|
||||
it("handles zero value as unlimited", async () => {
|
||||
const setCachedStateField = vi.fn()
|
||||
render(
|
||||
<ContextManagementSettings
|
||||
{...defaultProps}
|
||||
maxDiagnosticMessages={0}
|
||||
setCachedStateField={setCachedStateField}
|
||||
/>,
|
||||
)
|
||||
|
||||
// Zero is now treated as unlimited
|
||||
expect(
|
||||
screen.getByText("settings:contextManagement.diagnostics.maxMessages.unlimitedLabel"),
|
||||
).toBeInTheDocument()
|
||||
|
||||
const slider = screen.getByTestId("max-diagnostic-messages-slider")
|
||||
// Zero should map to slider position 100 (unlimited)
|
||||
expect(slider).toHaveValue("100")
|
||||
})
|
||||
|
||||
it("handles negative values as unlimited", async () => {
|
||||
const setCachedStateField = vi.fn()
|
||||
render(
|
||||
<ContextManagementSettings
|
||||
{...defaultProps}
|
||||
maxDiagnosticMessages={-10}
|
||||
setCachedStateField={setCachedStateField}
|
||||
/>,
|
||||
)
|
||||
|
||||
// Component displays "Unlimited" for any negative value
|
||||
expect(
|
||||
screen.getByText("settings:contextManagement.diagnostics.maxMessages.unlimitedLabel"),
|
||||
).toBeInTheDocument()
|
||||
|
||||
// Slider should be at max position (100) for negative values
|
||||
const slider = screen.getByTestId("max-diagnostic-messages-slider")
|
||||
expect(slider).toHaveValue("100")
|
||||
})
|
||||
|
||||
it("handles very large numbers by capping at maximum", async () => {
|
||||
const setCachedStateField = vi.fn()
|
||||
const largeNumber = 1000
|
||||
render(
|
||||
<ContextManagementSettings
|
||||
{...defaultProps}
|
||||
maxDiagnosticMessages={largeNumber}
|
||||
setCachedStateField={setCachedStateField}
|
||||
/>,
|
||||
)
|
||||
|
||||
// Should display the actual value even if it exceeds slider max
|
||||
expect(screen.getByText(largeNumber.toString())).toBeInTheDocument()
|
||||
|
||||
// Slider value would be capped at max (100)
|
||||
const slider = screen.getByTestId("max-diagnostic-messages-slider")
|
||||
expect(slider).toHaveValue("100")
|
||||
})
|
||||
|
||||
it("enforces maximum value constraint", async () => {
|
||||
const setCachedStateField = vi.fn()
|
||||
render(<ContextManagementSettings {...defaultProps} setCachedStateField={setCachedStateField} />)
|
||||
|
||||
const slider = screen.getByTestId("max-diagnostic-messages-slider")
|
||||
|
||||
// Test that setting value above 100 gets capped
|
||||
fireEvent.change(slider, { target: { value: "150" } })
|
||||
|
||||
await waitFor(() => {
|
||||
// Should be capped at 100, which maps to -1 (unlimited)
|
||||
expect(setCachedStateField).toHaveBeenCalledWith("maxDiagnosticMessages", -1)
|
||||
})
|
||||
})
|
||||
|
||||
it("handles boundary value at minimum (1)", async () => {
|
||||
const setCachedStateField = vi.fn()
|
||||
render(<ContextManagementSettings {...defaultProps} setCachedStateField={setCachedStateField} />)
|
||||
|
||||
const slider = screen.getByTestId("max-diagnostic-messages-slider")
|
||||
fireEvent.change(slider, { target: { value: "1" } })
|
||||
|
||||
await waitFor(() => {
|
||||
expect(setCachedStateField).toHaveBeenCalledWith("maxDiagnosticMessages", 1)
|
||||
})
|
||||
})
|
||||
|
||||
it("handles boundary value at maximum (100) as unlimited (-1)", async () => {
|
||||
const setCachedStateField = vi.fn()
|
||||
render(<ContextManagementSettings {...defaultProps} setCachedStateField={setCachedStateField} />)
|
||||
|
||||
const slider = screen.getByTestId("max-diagnostic-messages-slider")
|
||||
fireEvent.change(slider, { target: { value: "100" } })
|
||||
|
||||
await waitFor(() => {
|
||||
// When slider is at 100, it should set the value to -1 (unlimited)
|
||||
expect(setCachedStateField).toHaveBeenCalledWith("maxDiagnosticMessages", -1)
|
||||
})
|
||||
})
|
||||
|
||||
it("handles decimal values by parsing as float", async () => {
|
||||
const setCachedStateField = vi.fn()
|
||||
render(<ContextManagementSettings {...defaultProps} setCachedStateField={setCachedStateField} />)
|
||||
|
||||
const slider = screen.getByTestId("max-diagnostic-messages-slider")
|
||||
fireEvent.change(slider, { target: { value: "50.7" } })
|
||||
|
||||
await waitFor(() => {
|
||||
// The mock slider component parses as float
|
||||
expect(setCachedStateField).toHaveBeenCalledWith("maxDiagnosticMessages", 50.7)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it("renders max read file line controls", () => {
|
||||
|
|
@ -201,7 +399,8 @@ describe("ContextManagementSettings", () => {
|
|||
render(<ContextManagementSettings {...props} />)
|
||||
|
||||
const checkbox = screen.getByTestId("auto-condense-context-checkbox")
|
||||
expect(checkbox).toBeChecked()
|
||||
const input = checkbox.querySelector('input[type="checkbox"]')
|
||||
expect(input).toBeChecked()
|
||||
|
||||
// Toggle off
|
||||
fireEvent.click(checkbox)
|
||||
|
|
@ -238,89 +437,47 @@ describe("ContextManagementSettings", () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe("Edge cases and validation", () => {
|
||||
it("handles invalid max read file line input", () => {
|
||||
const mockSetCachedStateField = vitest.fn()
|
||||
const propsWithMaxReadFileLine = {
|
||||
...defaultProps,
|
||||
maxReadFileLine: 500,
|
||||
setCachedStateField: mockSetCachedStateField,
|
||||
}
|
||||
render(<ContextManagementSettings {...propsWithMaxReadFileLine} />)
|
||||
it("renders max read file line controls with -1 value", () => {
|
||||
const propsWithMaxReadFileLine = {
|
||||
...defaultProps,
|
||||
maxReadFileLine: -1,
|
||||
}
|
||||
render(<ContextManagementSettings {...propsWithMaxReadFileLine} />)
|
||||
|
||||
const input = screen.getByTestId("max-read-file-line-input")
|
||||
const checkbox = screen.getByTestId("max-read-file-always-full-checkbox")
|
||||
const input = checkbox.querySelector('input[type="checkbox"]')
|
||||
expect(input).toBeChecked()
|
||||
})
|
||||
|
||||
// Test invalid input (non-numeric)
|
||||
fireEvent.change(input, { target: { value: "abc" } })
|
||||
expect(mockSetCachedStateField).not.toHaveBeenCalled()
|
||||
it("handles boundary values for sliders", () => {
|
||||
const mockSetCachedStateField = vitest.fn()
|
||||
const props = {
|
||||
...defaultProps,
|
||||
maxOpenTabsContext: 0,
|
||||
maxWorkspaceFiles: 500,
|
||||
setCachedStateField: mockSetCachedStateField,
|
||||
}
|
||||
render(<ContextManagementSettings {...props} />)
|
||||
|
||||
// Test negative value below -1
|
||||
fireEvent.change(input, { target: { value: "-5" } })
|
||||
expect(mockSetCachedStateField).not.toHaveBeenCalled()
|
||||
// Check boundary values are displayed
|
||||
expect(screen.getByText("0")).toBeInTheDocument() // min open tabs
|
||||
expect(screen.getByText("500")).toBeInTheDocument() // max workspace files
|
||||
})
|
||||
|
||||
// Test valid input
|
||||
fireEvent.change(input, { target: { value: "1000" } })
|
||||
expect(mockSetCachedStateField).toHaveBeenCalledWith("maxReadFileLine", 1000)
|
||||
})
|
||||
it("handles undefined optional props gracefully", () => {
|
||||
const propsWithUndefined = {
|
||||
...defaultProps,
|
||||
showRooIgnoredFiles: undefined,
|
||||
maxReadFileLine: undefined,
|
||||
}
|
||||
|
||||
it("selects input text on click", () => {
|
||||
const propsWithMaxReadFileLine = {
|
||||
...defaultProps,
|
||||
maxReadFileLine: 500,
|
||||
}
|
||||
render(<ContextManagementSettings {...propsWithMaxReadFileLine} />)
|
||||
expect(() => {
|
||||
render(<ContextManagementSettings {...propsWithUndefined} />)
|
||||
}).not.toThrow()
|
||||
|
||||
const input = screen.getByTestId("max-read-file-line-input") as HTMLInputElement
|
||||
const selectSpy = vitest.spyOn(input, "select")
|
||||
|
||||
fireEvent.click(input)
|
||||
expect(selectSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it("disables max read file input when always full read is checked", () => {
|
||||
const propsWithAlwaysFullRead = {
|
||||
...defaultProps,
|
||||
maxReadFileLine: -1,
|
||||
}
|
||||
render(<ContextManagementSettings {...propsWithAlwaysFullRead} />)
|
||||
|
||||
const input = screen.getByTestId("max-read-file-line-input")
|
||||
expect(input).toBeDisabled()
|
||||
|
||||
const checkbox = screen.getByTestId("max-read-file-always-full-checkbox")
|
||||
expect(checkbox).toBeChecked()
|
||||
})
|
||||
|
||||
it("handles boundary values for sliders", () => {
|
||||
const mockSetCachedStateField = vitest.fn()
|
||||
const props = {
|
||||
...defaultProps,
|
||||
maxOpenTabsContext: 0,
|
||||
maxWorkspaceFiles: 500,
|
||||
setCachedStateField: mockSetCachedStateField,
|
||||
}
|
||||
render(<ContextManagementSettings {...props} />)
|
||||
|
||||
// Check boundary values are displayed
|
||||
expect(screen.getByText("0")).toBeInTheDocument() // min open tabs
|
||||
expect(screen.getByText("500")).toBeInTheDocument() // max workspace files
|
||||
})
|
||||
|
||||
it("handles undefined optional props gracefully", () => {
|
||||
const propsWithUndefined = {
|
||||
...defaultProps,
|
||||
showRooIgnoredFiles: undefined,
|
||||
maxReadFileLine: undefined,
|
||||
}
|
||||
|
||||
expect(() => {
|
||||
render(<ContextManagementSettings {...propsWithUndefined} />)
|
||||
}).not.toThrow()
|
||||
|
||||
// Should use default values
|
||||
expect(screen.getByText("20")).toBeInTheDocument() // default maxOpenTabsContext
|
||||
expect(screen.getByText("200")).toBeInTheDocument() // default maxWorkspaceFiles
|
||||
})
|
||||
// Should use default values
|
||||
expect(screen.getByText("20")).toBeInTheDocument() // default maxOpenTabsContext
|
||||
expect(screen.getByText("200")).toBeInTheDocument() // default maxWorkspaceFiles
|
||||
})
|
||||
|
||||
describe("Conditional rendering", () => {
|
||||
|
|
|
|||
|
|
@ -134,6 +134,10 @@ export interface ExtensionStateContextType extends ExtensionState {
|
|||
routerModels?: RouterModels
|
||||
alwaysAllowUpdateTodoList?: boolean
|
||||
setAlwaysAllowUpdateTodoList: (value: boolean) => void
|
||||
includeDiagnosticMessages?: boolean
|
||||
setIncludeDiagnosticMessages: (value: boolean) => void
|
||||
maxDiagnosticMessages?: number
|
||||
setMaxDiagnosticMessages: (value: number) => void
|
||||
}
|
||||
|
||||
export const ExtensionStateContext = createContext<ExtensionStateContextType | undefined>(undefined)
|
||||
|
|
@ -229,6 +233,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
|
|||
},
|
||||
codebaseIndexModels: { ollama: {}, openai: {} },
|
||||
alwaysAllowUpdateTodoList: true,
|
||||
includeDiagnosticMessages: true,
|
||||
maxDiagnosticMessages: 50,
|
||||
})
|
||||
|
||||
const [didHydrateState, setDidHydrateState] = useState(false)
|
||||
|
|
@ -474,6 +480,14 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
|
|||
setAlwaysAllowUpdateTodoList: (value) => {
|
||||
setState((prevState) => ({ ...prevState, alwaysAllowUpdateTodoList: value }))
|
||||
},
|
||||
includeDiagnosticMessages: state.includeDiagnosticMessages,
|
||||
setIncludeDiagnosticMessages: (value) => {
|
||||
setState((prevState) => ({ ...prevState, includeDiagnosticMessages: value }))
|
||||
},
|
||||
maxDiagnosticMessages: state.maxDiagnosticMessages,
|
||||
setMaxDiagnosticMessages: (value) => {
|
||||
setState((prevState) => ({ ...prevState, maxDiagnosticMessages: value }))
|
||||
},
|
||||
}
|
||||
|
||||
return <ExtensionStateContext.Provider value={contextValue}>{children}</ExtensionStateContext.Provider>
|
||||
|
|
|
|||
16
webview-ui/src/i18n/locales/ca/settings.json
generated
16
webview-ui/src/i18n/locales/ca/settings.json
generated
|
|
@ -488,6 +488,22 @@
|
|||
"label": "Límit de lectures simultànies",
|
||||
"description": "Nombre màxim de fitxers que l'eina 'read_file' pot processar simultàniament. Els valors més alts poden accelerar la lectura de múltiples fitxers petits però augmenten l'ús de memòria."
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "Inclou automàticament diagnòstics al context",
|
||||
"description": "Quan està activat, els missatges de diagnòstic (errors) dels fitxers editats s'inclouran automàticament al context. Sempre pots incloure manualment tots els diagnòstics de l'espai de treball utilitzant @problems."
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "Màxim de missatges de diagnòstic",
|
||||
"description": "Nombre màxim de missatges de diagnòstic a incloure per fitxer. Aquest límit s'aplica tant a la inclusió automàtica (quan la casella està activada) com a les mencions manuals de @problems. Valors més alts proporcionen més context però augmenten l'ús de tokens.",
|
||||
"resetTooltip": "Restablir al valor per defecte (50)",
|
||||
"unlimitedLabel": "Il·limitat"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "Retard després d'escriptures per permetre que els diagnòstics detectin possibles problemes",
|
||||
"description": "Temps d'espera després d'escriptures de fitxers abans de continuar, permetent que les eines de diagnòstic processin els canvis i detectin problemes."
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "Llindar d'activació de condensació",
|
||||
"selectProfile": "Configura el llindar per al perfil",
|
||||
|
|
|
|||
16
webview-ui/src/i18n/locales/de/settings.json
generated
16
webview-ui/src/i18n/locales/de/settings.json
generated
|
|
@ -488,6 +488,22 @@
|
|||
"lines": "Zeilen",
|
||||
"always_full_read": "Immer die gesamte Datei lesen"
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "Diagnosen automatisch in den Kontext aufnehmen",
|
||||
"description": "Wenn aktiviert, werden Diagnosenachrichten (Fehler) aus bearbeiteten Dateien automatisch in den Kontext aufgenommen. Sie können jederzeit alle Workspace-Diagnosen manuell mit @problems einbeziehen."
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "Maximale Anzahl von Diagnosenachrichten",
|
||||
"description": "Maximale Anzahl von Diagnosenachrichten, die pro Datei eingeschlossen werden. Dieses Limit gilt sowohl für die automatische Einbeziehung (wenn das Kontrollkästchen aktiviert ist) als auch für manuelle @problems-Erwähnungen. Höhere Werte bieten mehr Kontext, erhöhen aber den Token-Verbrauch.",
|
||||
"resetTooltip": "Auf Standardwert zurücksetzen (50)",
|
||||
"unlimitedLabel": "Unbegrenzt"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "Verzögerung nach Schreibvorgängen, damit Diagnosen potenzielle Probleme erkennen können",
|
||||
"description": "Wartezeit nach Dateischreibvorgängen vor dem Fortfahren, damit Diagnosetools Änderungen verarbeiten und Probleme erkennen können."
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "Schwellenwert für Kontextkomprimierung",
|
||||
"selectProfile": "Profil für Schwellenwert konfigurieren",
|
||||
|
|
|
|||
|
|
@ -488,6 +488,22 @@
|
|||
"lines": "lines",
|
||||
"always_full_read": "Always read entire file"
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "Automatically include diagnostics in context",
|
||||
"description": "When enabled, diagnostic messages (errors) from edited files will be automatically included in the context. You can always manually include all workspace diagnostics using @problems."
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "Maximum diagnostic messages",
|
||||
"description": "Limits the number of diagnostic messages (errors, warnings) included in the context. When set, only this many diagnostics will be shown, prioritizing errors over warnings. Set to 0 for unlimited diagnostics.",
|
||||
"resetTooltip": "Reset to default value (50)",
|
||||
"unlimitedLabel": "Unlimited"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "Delay after writes to allow diagnostics to detect potential problems",
|
||||
"description": "Time to wait after file writes before proceeding, allowing diagnostic tools to process changes and detect issues."
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "Condensing Trigger Threshold",
|
||||
"selectProfile": "Configure threshold for profile",
|
||||
|
|
|
|||
16
webview-ui/src/i18n/locales/es/settings.json
generated
16
webview-ui/src/i18n/locales/es/settings.json
generated
|
|
@ -488,6 +488,22 @@
|
|||
"label": "Límite de lecturas simultáneas",
|
||||
"description": "Número máximo de archivos que la herramienta 'read_file' puede procesar simultáneamente. Valores más altos pueden acelerar la lectura de múltiples archivos pequeños pero aumentan el uso de memoria."
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "Incluir automáticamente diagnósticos en el contexto",
|
||||
"description": "Cuando está habilitado, los mensajes de diagnóstico (errores) de los archivos editados se incluirán automáticamente en el contexto. Siempre puedes incluir manualmente todos los diagnósticos del espacio de trabajo usando @problems."
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "Máximo de mensajes de diagnóstico",
|
||||
"description": "Número máximo de mensajes de diagnóstico a incluir por archivo. Este límite se aplica tanto a la inclusión automática (cuando la casilla está habilitada) como a las menciones manuales de @problems. Valores más altos proporcionan más contexto pero aumentan el uso de tokens.",
|
||||
"resetTooltip": "Restablecer al valor predeterminado (50)",
|
||||
"unlimitedLabel": "Ilimitado"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "Retraso después de escrituras para permitir que los diagnósticos detecten problemas potenciales",
|
||||
"description": "Tiempo de espera después de escrituras de archivos antes de continuar, permitiendo que las herramientas de diagnóstico procesen cambios y detecten problemas."
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "Umbral de condensación de contexto",
|
||||
"selectProfile": "Configurar umbral para perfil",
|
||||
|
|
|
|||
16
webview-ui/src/i18n/locales/fr/settings.json
generated
16
webview-ui/src/i18n/locales/fr/settings.json
generated
|
|
@ -488,6 +488,22 @@
|
|||
"label": "Limite de lectures simultanées",
|
||||
"description": "Nombre maximum de fichiers que l'outil 'read_file' peut traiter simultanément. Des valeurs plus élevées peuvent accélérer la lecture de plusieurs petits fichiers mais augmentent l'utilisation de la mémoire."
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "Inclure automatiquement les diagnostics dans le contexte",
|
||||
"description": "Lorsque cette option est activée, les messages de diagnostic (erreurs) des fichiers modifiés seront automatiquement inclus dans le contexte. Vous pouvez toujours inclure manuellement tous les diagnostics de l'espace de travail en utilisant @problems."
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "Nombre maximum de messages de diagnostic",
|
||||
"description": "Nombre maximum de messages de diagnostic à inclure par fichier. Cette limite s'applique à la fois à l'inclusion automatique (lorsque la case est cochée) et aux mentions manuelles @problems. Des valeurs plus élevées fournissent plus de contexte mais augmentent l'utilisation des jetons.",
|
||||
"resetTooltip": "Réinitialiser à la valeur par défaut (50)",
|
||||
"unlimitedLabel": "Illimité"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "Délai après les écritures pour permettre aux diagnostics de détecter les problèmes potentiels",
|
||||
"description": "Temps d'attente après les écritures de fichiers avant de continuer, permettant aux outils de diagnostic de traiter les modifications et de détecter les problèmes."
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "Seuil de condensation du contexte",
|
||||
"selectProfile": "Configurer le seuil pour le profil",
|
||||
|
|
|
|||
17
webview-ui/src/i18n/locales/hi/settings.json
generated
17
webview-ui/src/i18n/locales/hi/settings.json
generated
|
|
@ -488,6 +488,23 @@
|
|||
"label": "एक साथ फ़ाइल पढ़ने की सीमा",
|
||||
"description": "'read_file' टूल द्वारा एक साथ प्रोसेस की जा सकने वाली अधिकतम फ़ाइलों की संख्या। उच्च मान कई छोटी फ़ाइलों को पढ़ने की गति बढ़ा सकते हैं लेकिन मेमोरी उपयोग बढ़ा देते हैं।"
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "स्वचालित रूप से संदर्भ में डायग्नोस्टिक शामिल करें",
|
||||
"description": "जब सक्षम होता है, तो संपादित फ़ाइलों से डायग्नोस्टिक संदेश (त्रुटियां) स्वचालित रूप से संदर्भ में शामिल किए जाएंगे। आप हमेशा @problems का उपयोग करके सभी कार्यक्षेत्र डायग्नोस्टिक को मैन्युअल रूप से शामिल कर सकते हैं।"
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "अधिकतम डायग्नोस्टिक संदेश",
|
||||
"description": "प्रति फ़ाइल शामिल किए जाने वाले डायग्नोस्टिक संदेशों की अधिकतम संख्या। यह सीमा स्वचालित समावेशन (जब चेकबॉक्स सक्षम है) और मैन्युअल @problems उल्लेख दोनों पर लागू होती है। उच्च मान अधिक संदर्भ प्रदान करते हैं लेकिन टोकन उपयोग बढ़ाते हैं।",
|
||||
"resetTooltip": "डिफ़ॉल्ट मान पर रीसेट करें (50)",
|
||||
"unlimited": "असीमित डायग्नोस्टिक संदेश",
|
||||
"unlimitedLabel": "असीमित"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "संभावित समस्याओं का पता लगाने के लिए डायग्नोस्टिक्स को अनुमति देने के लिए लिखने के बाद देरी",
|
||||
"description": "फ़ाइल लिखने के बाद आगे बढ़ने से पहले प्रतीक्षा करने का समय, डायग्नोस्टिक टूल को परिवर्तनों को संसाधित करने और समस्याओं का पता लगाने की अनुमति देता है।"
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "संघनन ट्रिगर सीमा",
|
||||
"selectProfile": "प्रोफ़ाइल के लिए सीमा कॉन्फ़िगर करें",
|
||||
|
|
|
|||
17
webview-ui/src/i18n/locales/id/settings.json
generated
17
webview-ui/src/i18n/locales/id/settings.json
generated
|
|
@ -470,6 +470,23 @@
|
|||
"name": "Secara otomatis memicu kondensasi konteks cerdas",
|
||||
"description": "Ketika diaktifkan, Roo akan secara otomatis mengondensasi konteks ketika ambang batas tercapai. Ketika dinonaktifkan, kamu masih dapat memicu kondensasi konteks secara manual."
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "Secara otomatis sertakan diagnostik dalam konteks",
|
||||
"description": "Ketika diaktifkan, pesan diagnostik (error) dari file yang diedit akan secara otomatis disertakan dalam konteks. Kamu selalu dapat menyertakan semua diagnostik workspace secara manual menggunakan @problems."
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "Pesan diagnostik maksimum",
|
||||
"description": "Jumlah maksimum pesan diagnostik yang akan disertakan per file. Batas ini berlaku untuk penyertaan otomatis (ketika checkbox diaktifkan) dan penyebutan manual @problems. Nilai yang lebih tinggi memberikan lebih banyak konteks tetapi meningkatkan penggunaan token.",
|
||||
"resetTooltip": "Reset ke nilai default (50)",
|
||||
"unlimited": "Pesan diagnostik tidak terbatas",
|
||||
"unlimitedLabel": "Tak terbatas"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "Tunda setelah penulisan untuk memungkinkan diagnostik mendeteksi potensi masalah",
|
||||
"description": "Waktu tunggu setelah penulisan file sebelum melanjutkan, memungkinkan alat diagnostik untuk memproses perubahan dan mendeteksi masalah."
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "Ambang Batas Pemicu Kondensasi",
|
||||
"selectProfile": "Konfigurasi ambang batas untuk profil",
|
||||
|
|
|
|||
17
webview-ui/src/i18n/locales/it/settings.json
generated
17
webview-ui/src/i18n/locales/it/settings.json
generated
|
|
@ -488,6 +488,23 @@
|
|||
"label": "Limite letture simultanee",
|
||||
"description": "Numero massimo di file che lo strumento 'read_file' può elaborare contemporaneamente. Valori più alti possono velocizzare la lettura di più file piccoli ma aumentano l'utilizzo della memoria."
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "Includi automaticamente la diagnostica nel contesto",
|
||||
"description": "Quando abilitato, i messaggi diagnostici (errori) dai file modificati verranno automaticamente inclusi nel contesto. Puoi sempre includere manualmente tutta la diagnostica del workspace usando @problems."
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "Numero massimo di messaggi diagnostici",
|
||||
"description": "Numero massimo di messaggi diagnostici da includere per file. Questo limite si applica sia all'inclusione automatica (quando la casella è abilitata) che alle menzioni manuali di @problems. Valori più alti forniscono più contesto ma aumentano l'utilizzo dei token.",
|
||||
"resetTooltip": "Ripristina al valore predefinito (50)",
|
||||
"unlimited": "Messaggi diagnostici illimitati",
|
||||
"unlimitedLabel": "Illimitato"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "Ritardo dopo le scritture per consentire alla diagnostica di rilevare potenziali problemi",
|
||||
"description": "Tempo di attesa dopo la scrittura dei file prima di procedere, consentendo agli strumenti di diagnostica di elaborare le modifiche e rilevare i problemi."
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "Soglia di attivazione condensazione",
|
||||
"selectProfile": "Configura soglia per profilo",
|
||||
|
|
|
|||
17
webview-ui/src/i18n/locales/ja/settings.json
generated
17
webview-ui/src/i18n/locales/ja/settings.json
generated
|
|
@ -488,6 +488,23 @@
|
|||
"label": "同時ファイル読み取り制限",
|
||||
"description": "read_file ツールが同時に処理できるファイルの最大数。値を高くすると複数の小さなファイルの読み取りが速くなる可能性がありますが、メモリ使用量が増加します。"
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "診断を自動的にコンテキストに含める",
|
||||
"description": "有効にすると、編集されたファイルからの診断メッセージ(エラー)が自動的にコンテキストに含まれます。@problemsを使用して、いつでも手動ですべてのワークスペース診断を含めることができます。"
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "最大診断メッセージ数",
|
||||
"description": "ファイルごとに含める診断メッセージの最大数。この制限は、自動インクルード(チェックボックスが有効な場合)と手動の@problemsメンションの両方に適用されます。値を高くするとより多くのコンテキストが提供されますが、トークンの使用量が増加します。",
|
||||
"resetTooltip": "デフォルト値(50)にリセット",
|
||||
"unlimited": "無制限の診断メッセージ",
|
||||
"unlimitedLabel": "無制限"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "書き込み後に診断が潜在的な問題を検出できるように遅延させる",
|
||||
"description": "ファイルの書き込み後に処理を続行するまでの待機時間。これにより、診断ツールが変更を処理して問題を検出できます。"
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "圧縮トリガーしきい値",
|
||||
"selectProfile": "プロファイルのしきい値を設定",
|
||||
|
|
|
|||
17
webview-ui/src/i18n/locales/ko/settings.json
generated
17
webview-ui/src/i18n/locales/ko/settings.json
generated
|
|
@ -488,6 +488,23 @@
|
|||
"label": "동시 파일 읽기 제한",
|
||||
"description": "read_file 도구가 동시에 처리할 수 있는 최대 파일 수입니다. 높은 값은 여러 작은 파일을 읽는 속도를 높일 수 있지만 메모리 사용량이 증가합니다."
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "진단을 자동으로 컨텍스트에 포함",
|
||||
"description": "활성화되면 편집된 파일의 진단 메시지(오류)가 자동으로 컨텍스트에 포함됩니다. @problems를 사용하여 언제든지 모든 워크스페이스 진단을 수동으로 포함할 수 있습니다."
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "최대 진단 메시지",
|
||||
"description": "파일당 포함할 최대 진단 메시지 수입니다. 이 제한은 자동 포함(체크박스가 활성화된 경우)과 수동 @problems 언급 모두에 적용됩니다. 값이 높을수록 더 많은 컨텍스트를 제공하지만 토큰 사용량이 증가합니다.",
|
||||
"resetTooltip": "기본값(50)으로 재설정",
|
||||
"unlimited": "무제한 진단 메시지",
|
||||
"unlimitedLabel": "무제한"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "진단이 잠재적인 문제를 감지할 수 있도록 쓰기 후 지연",
|
||||
"description": "파일 쓰기 후 계속 진행하기 전에 대기하는 시간으로, 진단 도구가 변경 사항을 처리하고 문제를 감지할 수 있도록 합니다."
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "압축 트리거 임계값",
|
||||
"selectProfile": "프로필 임계값 구성",
|
||||
|
|
|
|||
17
webview-ui/src/i18n/locales/nl/settings.json
generated
17
webview-ui/src/i18n/locales/nl/settings.json
generated
|
|
@ -488,6 +488,23 @@
|
|||
"label": "Limiet gelijktijdige bestandslezingen",
|
||||
"description": "Maximum aantal bestanden dat de 'read_file' tool tegelijkertijd kan verwerken. Hogere waarden kunnen het lezen van meerdere kleine bestanden versnellen maar verhogen het geheugengebruik."
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "Automatisch diagnostiek opnemen in context",
|
||||
"description": "Indien ingeschakeld, worden diagnostische berichten (fouten) van bewerkte bestanden automatisch opgenomen in de context. Je kunt altijd handmatig alle werkruimte-diagnostiek opnemen met @problems."
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "Maximale diagnostische berichten",
|
||||
"description": "Maximaal aantal diagnostische berichten dat per bestand moet worden opgenomen. Deze limiet geldt voor zowel automatische opname (wanneer checkbox is ingeschakeld) als handmatige @problems vermeldingen. Hogere waarden bieden meer context maar verhogen het tokengebruik.",
|
||||
"resetTooltip": "Reset naar standaardwaarde (50)",
|
||||
"unlimited": "Onbeperkte diagnostische berichten",
|
||||
"unlimitedLabel": "Onbeperkt"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "Vertraging na het schrijven om diagnostiek potentiële problemen te laten detecteren",
|
||||
"description": "Wachttijd na het schrijven van bestanden voordat u doorgaat, zodat diagnostische hulpmiddelen wijzigingen kunnen verwerken en problemen kunnen detecteren."
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "Compressie trigger drempelwaarde",
|
||||
"selectProfile": "Drempelwaarde voor profiel configureren",
|
||||
|
|
|
|||
17
webview-ui/src/i18n/locales/pl/settings.json
generated
17
webview-ui/src/i18n/locales/pl/settings.json
generated
|
|
@ -488,6 +488,23 @@
|
|||
"label": "Limit jednoczesnych odczytów",
|
||||
"description": "Maksymalna liczba plików, które narzędzie 'read_file' może przetwarzać jednocześnie. Wyższe wartości mogą przyspieszyć odczyt wielu małych plików, ale zwiększają zużycie pamięci."
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "Automatycznie dołączaj diagnostykę do kontekstu",
|
||||
"description": "Gdy włączone, komunikaty diagnostyczne (błędy) z edytowanych plików będą automatycznie dołączane do kontekstu. Zawsze możesz ręcznie dołączyć całą diagnostykę obszaru roboczego używając @problems."
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "Maksymalna liczba komunikatów diagnostycznych",
|
||||
"description": "Maksymalna liczba komunikatów diagnostycznych dołączanych na plik. Ten limit dotyczy zarówno automatycznego dołączania (gdy pole wyboru jest włączone) jak i ręcznych wzmianek @problems. Wyższe wartości dostarczają więcej kontekstu, ale zwiększają zużycie tokenów.",
|
||||
"resetTooltip": "Resetuj do wartości domyślnej (50)",
|
||||
"unlimited": "Nieograniczone komunikaty diagnostyczne",
|
||||
"unlimitedLabel": "Nieograniczone"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "Opóźnienie po zapisie, aby umożliwić diagnostyce wykrycie potencjalnych problemów",
|
||||
"description": "Czas oczekiwania po zapisie plików przed kontynuowaniem, aby narzędzia diagnostyczne mogły przetworzyć zmiany i wykryć problemy."
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "Próg wyzwalania kondensacji",
|
||||
"selectProfile": "Skonfiguruj próg dla profilu",
|
||||
|
|
|
|||
17
webview-ui/src/i18n/locales/pt-BR/settings.json
generated
17
webview-ui/src/i18n/locales/pt-BR/settings.json
generated
|
|
@ -488,6 +488,23 @@
|
|||
"label": "Limite de leituras simultâneas",
|
||||
"description": "Número máximo de arquivos que a ferramenta 'read_file' pode processar simultaneamente. Valores mais altos podem acelerar a leitura de vários arquivos pequenos, mas aumentam o uso de memória."
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "Incluir diagnósticos automaticamente no contexto",
|
||||
"description": "Quando ativado, mensagens de diagnóstico (erros) de arquivos editados serão automaticamente incluídas no contexto. Você sempre pode incluir manualmente todos os diagnósticos do espaço de trabalho usando @problems."
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "Máximo de mensagens de diagnóstico",
|
||||
"description": "Número máximo de mensagens de diagnóstico a serem incluídas por arquivo. Este limite se aplica tanto à inclusão automática (quando a caixa de seleção está ativada) quanto às menções manuais de @problems. Valores mais altos fornecem mais contexto, mas aumentam o uso de tokens.",
|
||||
"resetTooltip": "Redefinir para o valor padrão (50)",
|
||||
"unlimited": "Mensagens de diagnóstico ilimitadas",
|
||||
"unlimitedLabel": "Ilimitado"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "Atraso após as gravações para permitir que os diagnósticos detectem possíveis problemas",
|
||||
"description": "Tempo de espera após a gravação de arquivos antes de prosseguir, permitindo que as ferramentas de diagnóstico processem as alterações e detectem problemas."
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "Limite de Ativação de Condensação",
|
||||
"selectProfile": "Configurar limite para perfil",
|
||||
|
|
|
|||
17
webview-ui/src/i18n/locales/ru/settings.json
generated
17
webview-ui/src/i18n/locales/ru/settings.json
generated
|
|
@ -488,6 +488,23 @@
|
|||
"label": "Лимит одновременного чтения",
|
||||
"description": "Максимальное количество файлов, которые инструмент 'read_file' может обрабатывать одновременно. Более высокие значения могут ускорить чтение нескольких небольших файлов, но увеличивают использование памяти."
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "Автоматически включать диагностику в контекст",
|
||||
"description": "Если включено, диагностические сообщения (ошибки) из редактируемых файлов будут автоматически включаться в контекст. Вы всегда можете вручную включить всю диагностику рабочей области, используя @problems."
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "Максимальное количество диагностических сообщений",
|
||||
"description": "Максимальное количество диагностических сообщений для включения в файл. Этот лимит применяется как к автоматическому включению (когда флажок включен), так и к ручным упоминаниям @problems. Более высокие значения предоставляют больше контекста, но увеличивают использование токенов.",
|
||||
"resetTooltip": "Сбросить к значению по умолчанию (50)",
|
||||
"unlimited": "Неограниченные диагностические сообщения",
|
||||
"unlimitedLabel": "Неограниченно"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "Задержка после записи, чтобы диагностика могла обнаружить потенциальные проблемы",
|
||||
"description": "Время ожидания после записи файлов перед продолжением, чтобы средства диагностики могли обработать изменения и выявить проблемы."
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "Порог запуска сжатия",
|
||||
"selectProfile": "Настроить порог для профиля",
|
||||
|
|
|
|||
17
webview-ui/src/i18n/locales/tr/settings.json
generated
17
webview-ui/src/i18n/locales/tr/settings.json
generated
|
|
@ -488,6 +488,23 @@
|
|||
"label": "Eşzamanlı dosya okuma sınırı",
|
||||
"description": "'read_file' aracının aynı anda işleyebileceği maksimum dosya sayısı. Daha yüksek değerler birden çok küçük dosyanın okunmasını hızlandırabilir ancak bellek kullanımını artırır."
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "Tanı mesajlarını otomatik olarak bağlama dahil et",
|
||||
"description": "Etkinleştirildiğinde, düzenlenen dosyalardan tanı mesajları (hatalar) otomatik olarak bağlama dahil edilecektir. @problems kullanarak tüm çalışma alanı tanı mesajlarını her zaman manuel olarak dahil edebilirsiniz."
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "Maksimum tanı mesajı",
|
||||
"description": "Dosya başına dahil edilecek maksimum tanı mesajı sayısı. Bu sınır hem otomatik dahil etme (onay kutusu etkinleştirildiğinde) hem de manuel @problems bahisleri için geçerlidir. Daha yüksek değerler daha fazla bağlam sağlar ancak jeton kullanımını artırır.",
|
||||
"resetTooltip": "Varsayılan değere sıfırla (50)",
|
||||
"unlimited": "Sınırsız tanı mesajları",
|
||||
"unlimitedLabel": "Sınırsız"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "Potansiyel sorunları tespit etmek için tanılamaya izin vermek üzere yazmalardan sonra gecikme",
|
||||
"description": "Devam etmeden önce dosya yazımlarından sonra beklenecek süre, tanılama araçlarının değişiklikleri işlemesine ve sorunları tespit etmesine olanak tanır."
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "Sıkıştırma Tetikleme Eşiği",
|
||||
"selectProfile": "Profil için eşik yapılandır",
|
||||
|
|
|
|||
17
webview-ui/src/i18n/locales/vi/settings.json
generated
17
webview-ui/src/i18n/locales/vi/settings.json
generated
|
|
@ -488,6 +488,23 @@
|
|||
"label": "Giới hạn đọc file đồng thời",
|
||||
"description": "Số lượng file tối đa mà công cụ 'read_file' có thể xử lý cùng lúc. Giá trị cao hơn có thể tăng tốc độ đọc nhiều file nhỏ nhưng sẽ tăng mức sử dụng bộ nhớ."
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "Tự động bao gồm chẩn đoán trong ngữ cảnh",
|
||||
"description": "Khi được bật, thông báo chẩn đoán (lỗi) từ các tệp đã chỉnh sửa sẽ tự động được bao gồm trong ngữ cảnh. Bạn luôn có thể bao gồm thủ công tất cả chẩn đoán của workspace bằng cách sử dụng @problems."
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "Thông báo chẩn đoán tối đa",
|
||||
"description": "Số lượng thông báo chẩn đoán tối đa được bao gồm cho mỗi tệp. Giới hạn này áp dụng cho cả việc bao gồm tự động (khi hộp kiểm được bật) và đề cập thủ công @problems. Giá trị cao hơn cung cấp nhiều ngữ cảnh hơn nhưng tăng mức sử dụng token.",
|
||||
"resetTooltip": "Đặt lại về giá trị mặc định (50)",
|
||||
"unlimited": "Thông báo chẩn đoán không giới hạn",
|
||||
"unlimitedLabel": "Không giới hạn"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "Trì hoãn sau khi ghi để cho phép chẩn đoán phát hiện các sự cố tiềm ẩn",
|
||||
"description": "Thời gian chờ sau khi ghi tệp trước khi tiếp tục, cho phép các công cụ chẩn đoán xử lý các thay đổi và phát hiện sự cố."
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "Ngưỡng kích hoạt nén",
|
||||
"selectProfile": "Cấu hình ngưỡng cho hồ sơ",
|
||||
|
|
|
|||
17
webview-ui/src/i18n/locales/zh-CN/settings.json
generated
17
webview-ui/src/i18n/locales/zh-CN/settings.json
generated
|
|
@ -488,6 +488,23 @@
|
|||
"label": "并发文件读取限制",
|
||||
"description": "read_file 工具可以同时处理的最大文件数。较高的值可能会加快读取多个小文件的速度,但会增加内存使用量。"
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "自动在上下文中包含诊断",
|
||||
"description": "启用后,来自已编辑文件的诊断消息(错误)将自动包含在上下文中。您始终可以使用 @problems 手动包含所有工作区诊断。"
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "最大诊断消息数",
|
||||
"description": "每个文件包含的最大诊断消息数。此限制适用于自动包含(启用复选框时)和手动 @problems 提及。较高的值提供更多上下文,但会增加令牌使用量。",
|
||||
"resetTooltip": "重置为默认值 (50)",
|
||||
"unlimited": "无限制诊断消息",
|
||||
"unlimitedLabel": "无限制"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "写入后延迟以允许诊断程序检测潜在问题",
|
||||
"description": "在继续之前写入文件后等待的时间,允许诊断工具处理更改并检测问题。"
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "压缩触发阈值",
|
||||
"selectProfile": "配置配置文件阈值",
|
||||
|
|
|
|||
17
webview-ui/src/i18n/locales/zh-TW/settings.json
generated
17
webview-ui/src/i18n/locales/zh-TW/settings.json
generated
|
|
@ -488,6 +488,23 @@
|
|||
"label": "並行檔案讀取限制",
|
||||
"description": "read_file 工具可以同時處理的最大檔案數。較高的值可能會加快讀取多個小檔案的速度,但會增加記憶體使用量。"
|
||||
},
|
||||
"diagnostics": {
|
||||
"includeMessages": {
|
||||
"label": "自動在上下文中包含診斷",
|
||||
"description": "啟用後,來自已編輯檔案的診斷訊息(錯誤)將自動包含在上下文中。您隨時可以使用 @problems 手動包含所有工作區診斷。"
|
||||
},
|
||||
"maxMessages": {
|
||||
"label": "最大診斷訊息數",
|
||||
"description": "每個檔案包含的最大診斷訊息數。此限制適用於自動包含(當核取方塊啟用時)和手動 @problems 提及。較高的值提供更多上下文,但會增加權杖使用量。",
|
||||
"resetTooltip": "重設為預設值 (50)",
|
||||
"unlimited": "無限制診斷訊息",
|
||||
"unlimitedLabel": "無限制"
|
||||
},
|
||||
"delayAfterWrite": {
|
||||
"label": "寫入後延遲以允許診斷程式偵測潛在問題",
|
||||
"description": "在繼續之前寫入檔案後等待的時間,允許診斷工具處理變更並偵測問題。"
|
||||
}
|
||||
},
|
||||
"condensingThreshold": {
|
||||
"label": "壓縮觸發閾值",
|
||||
"selectProfile": "設定檔案閾值",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue