Forráskód Böngészése

Add checkpoint initialization timeout settings and fix checkpoint timeout warnings (#8019)

Co-authored-by: daniel-lxs <[email protected]>
Co-authored-by: Matt Rubens <[email protected]>
NaccOll 2 hónapja
szülő
commit
f4121e2568
54 módosított fájl, 519 hozzáadás és 55 törlés
  1. 21 0
      packages/types/src/global-settings.ts
  2. 1 0
      src/__tests__/extension.spec.ts
  3. 160 1
      src/core/checkpoints/__tests__/checkpoint.test.ts
  4. 38 6
      src/core/checkpoints/index.ts
  5. 21 0
      src/core/task/Task.ts
  6. 8 0
      src/core/webview/ClineProvider.ts
  7. 7 1
      src/core/webview/__tests__/ClineProvider.spec.ts
  8. 6 0
      src/core/webview/webviewMessageHandler.ts
  9. 1 1
      src/services/checkpoints/ShadowCheckpointService.ts
  10. 7 0
      src/shared/ExtensionMessage.ts
  11. 1 0
      src/shared/WebviewMessage.ts
  12. 13 21
      webview-ui/src/components/chat/ChatView.tsx
  13. 35 22
      webview-ui/src/components/chat/CheckpointWarning.tsx
  14. 3 0
      webview-ui/src/components/marketplace/__tests__/MarketplaceView.spec.tsx
  15. 41 2
      webview-ui/src/components/settings/CheckpointSettings.tsx
  16. 3 0
      webview-ui/src/components/settings/SettingsView.tsx
  17. 5 0
      webview-ui/src/context/ExtensionStateContext.tsx
  18. 4 1
      webview-ui/src/context/__tests__/ExtensionStateContext.spec.tsx
  19. 4 0
      webview-ui/src/i18n/locales/ca/common.json
  20. 4 0
      webview-ui/src/i18n/locales/ca/settings.json
  21. 4 0
      webview-ui/src/i18n/locales/de/common.json
  22. 4 0
      webview-ui/src/i18n/locales/de/settings.json
  23. 4 0
      webview-ui/src/i18n/locales/en/common.json
  24. 4 0
      webview-ui/src/i18n/locales/en/settings.json
  25. 4 0
      webview-ui/src/i18n/locales/es/common.json
  26. 4 0
      webview-ui/src/i18n/locales/es/settings.json
  27. 4 0
      webview-ui/src/i18n/locales/fr/common.json
  28. 4 0
      webview-ui/src/i18n/locales/fr/settings.json
  29. 4 0
      webview-ui/src/i18n/locales/hi/common.json
  30. 4 0
      webview-ui/src/i18n/locales/hi/settings.json
  31. 4 0
      webview-ui/src/i18n/locales/id/common.json
  32. 4 0
      webview-ui/src/i18n/locales/id/settings.json
  33. 4 0
      webview-ui/src/i18n/locales/it/common.json
  34. 4 0
      webview-ui/src/i18n/locales/it/settings.json
  35. 4 0
      webview-ui/src/i18n/locales/ja/common.json
  36. 4 0
      webview-ui/src/i18n/locales/ja/settings.json
  37. 4 0
      webview-ui/src/i18n/locales/ko/common.json
  38. 4 0
      webview-ui/src/i18n/locales/ko/settings.json
  39. 4 0
      webview-ui/src/i18n/locales/nl/common.json
  40. 4 0
      webview-ui/src/i18n/locales/nl/settings.json
  41. 4 0
      webview-ui/src/i18n/locales/pl/common.json
  42. 4 0
      webview-ui/src/i18n/locales/pl/settings.json
  43. 4 0
      webview-ui/src/i18n/locales/pt-BR/common.json
  44. 4 0
      webview-ui/src/i18n/locales/pt-BR/settings.json
  45. 4 0
      webview-ui/src/i18n/locales/ru/common.json
  46. 4 0
      webview-ui/src/i18n/locales/ru/settings.json
  47. 4 0
      webview-ui/src/i18n/locales/tr/common.json
  48. 4 0
      webview-ui/src/i18n/locales/tr/settings.json
  49. 4 0
      webview-ui/src/i18n/locales/vi/common.json
  50. 4 0
      webview-ui/src/i18n/locales/vi/settings.json
  51. 4 0
      webview-ui/src/i18n/locales/zh-CN/common.json
  52. 4 0
      webview-ui/src/i18n/locales/zh-CN/settings.json
  53. 4 0
      webview-ui/src/i18n/locales/zh-TW/common.json
  54. 4 0
      webview-ui/src/i18n/locales/zh-TW/settings.json

+ 21 - 0
packages/types/src/global-settings.ts

@@ -29,6 +29,21 @@ export const DEFAULT_WRITE_DELAY_MS = 1000
  */
 export const DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT = 50_000
 
+/**
+ * Minimum checkpoint timeout in seconds.
+ */
+export const MIN_CHECKPOINT_TIMEOUT_SECONDS = 10
+
+/**
+ * Maximum checkpoint timeout in seconds.
+ */
+export const MAX_CHECKPOINT_TIMEOUT_SECONDS = 60
+
+/**
+ * Default checkpoint timeout in seconds.
+ */
+export const DEFAULT_CHECKPOINT_TIMEOUT_SECONDS = 15
+
 /**
  * GlobalSettings
  */
@@ -97,6 +112,12 @@ export const globalSettingsSchema = z.object({
 	cachedChromeHostUrl: z.string().optional(),
 
 	enableCheckpoints: z.boolean().optional(),
+	checkpointTimeout: z
+		.number()
+		.int()
+		.min(MIN_CHECKPOINT_TIMEOUT_SECONDS)
+		.max(MAX_CHECKPOINT_TIMEOUT_SECONDS)
+		.optional(),
 
 	ttsEnabled: z.boolean().optional(),
 	ttsSpeed: z.number().optional(),

+ 1 - 0
src/__tests__/extension.spec.ts

@@ -168,6 +168,7 @@ vi.mock("../activate", () => ({
 
 vi.mock("../i18n", () => ({
 	initializeI18n: vi.fn(),
+	t: vi.fn((key) => key),
 }))
 
 describe("extension.ts", () => {

+ 160 - 1
src/core/checkpoints/__tests__/checkpoint.test.ts

@@ -1,4 +1,4 @@
-import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"
+import { describe, it, expect, vi, beforeEach, afterEach, Mock } from "vitest"
 import { Task } from "../../task/Task"
 import { ClineProvider } from "../../webview/ClineProvider"
 import { checkpointSave, checkpointRestore, checkpointDiff, getCheckpointService } from "../index"
@@ -35,6 +35,27 @@ vi.mock("../../../utils/path", () => ({
 	getWorkspacePath: vi.fn(() => "/test/workspace"),
 }))
 
+vi.mock("../../../utils/git", () => ({
+	checkGitInstalled: vi.fn().mockResolvedValue(true),
+}))
+
+vi.mock("../../../i18n", () => ({
+	t: vi.fn((key: string, options?: Record<string, any>) => {
+		if (key === "common:errors.wait_checkpoint_long_time") {
+			return `Checkpoint initialization is taking longer than ${options?.timeout} seconds...`
+		}
+		if (key === "common:errors.init_checkpoint_fail_long_time") {
+			return `Checkpoint initialization failed after ${options?.timeout} seconds`
+		}
+		return key
+	}),
+}))
+
+// Mock p-wait-for to control timeout behavior
+vi.mock("p-wait-for", () => ({
+	default: vi.fn(),
+}))
+
 vi.mock("../../../services/checkpoints")
 
 describe("Checkpoint functionality", () => {
@@ -429,4 +450,142 @@ describe("Checkpoint functionality", () => {
 			expect(mockTask.enableCheckpoints).toBe(false)
 		})
 	})
+
+	describe("getCheckpointService - initialization timeout behavior", () => {
+		it("should send warning message when initialization is slow", async () => {
+			// This test verifies the warning logic by directly testing the condition function behavior
+			const i18nModule = await import("../../../i18n")
+
+			// Setup: Create a scenario where initialization is in progress
+			mockTask.checkpointService = undefined
+			mockTask.checkpointServiceInitializing = true
+			mockTask.checkpointTimeout = 15
+
+			vi.clearAllMocks()
+
+			// Simulate the condition function that runs inside pWaitFor
+			let warningShown = false
+			const simulateConditionCheck = (elapsedMs: number) => {
+				// This simulates what happens inside the pWaitFor condition function (lines 85-100)
+				if (!warningShown && elapsedMs >= 5000) {
+					warningShown = true
+					// This is what the actual code does at line 91-94
+					const provider = mockTask.providerRef.deref()
+					provider?.postMessageToWebview({
+						type: "checkpointInitWarning",
+						checkpointWarning: i18nModule.t("common:errors.wait_checkpoint_long_time", { timeout: 5 }),
+					})
+				}
+
+				return !!mockTask.checkpointService && !!mockTask.checkpointService.isInitialized
+			}
+
+			// Test: At 4 seconds, no warning should be sent
+			expect(simulateConditionCheck(4000)).toBe(false)
+			expect(mockProvider.postMessageToWebview).not.toHaveBeenCalled()
+
+			// Test: At 5 seconds, warning should be sent
+			expect(simulateConditionCheck(5000)).toBe(false)
+			expect(mockProvider.postMessageToWebview).toHaveBeenCalledWith({
+				type: "checkpointInitWarning",
+				checkpointWarning: "Checkpoint initialization is taking longer than 5 seconds...",
+			})
+
+			// Test: At 6 seconds, warning should not be sent again (warningShown is true)
+			vi.clearAllMocks()
+			expect(simulateConditionCheck(6000)).toBe(false)
+			expect(mockProvider.postMessageToWebview).not.toHaveBeenCalled()
+		})
+
+		it("should send timeout error message when initialization fails", async () => {
+			const i18nModule = await import("../../../i18n")
+
+			// Setup
+			mockTask.checkpointService = undefined
+			mockTask.checkpointTimeout = 10
+			mockTask.enableCheckpoints = true
+
+			vi.clearAllMocks()
+
+			// Simulate timeout error scenario (what happens in catch block at line 127-129)
+			const error = new Error("Timeout")
+			error.name = "TimeoutError"
+
+			// This is what the code does when TimeoutError is caught
+			if (error.name === "TimeoutError" && mockTask.enableCheckpoints) {
+				const provider = mockTask.providerRef.deref()
+				provider?.postMessageToWebview({
+					type: "checkpointInitWarning",
+					checkpointWarning: i18nModule.t("common:errors.init_checkpoint_fail_long_time", {
+						timeout: mockTask.checkpointTimeout,
+					}),
+				})
+			}
+
+			mockTask.enableCheckpoints = false
+
+			// Verify
+			expect(mockProvider.postMessageToWebview).toHaveBeenCalledWith({
+				type: "checkpointInitWarning",
+				checkpointWarning: "Checkpoint initialization failed after 10 seconds",
+			})
+			expect(mockTask.enableCheckpoints).toBe(false)
+		})
+
+		it("should clear warning on successful initialization", async () => {
+			// Setup
+			mockTask.checkpointService = mockCheckpointService
+			mockTask.enableCheckpoints = true
+
+			vi.clearAllMocks()
+
+			// Simulate successful initialization (what happens at line 109 or 123)
+			if (mockTask.enableCheckpoints) {
+				const provider = mockTask.providerRef.deref()
+				provider?.postMessageToWebview({
+					type: "checkpointInitWarning",
+					checkpointWarning: "",
+				})
+			}
+
+			// Verify warning was cleared
+			expect(mockProvider.postMessageToWebview).toHaveBeenCalledWith({
+				type: "checkpointInitWarning",
+				checkpointWarning: "",
+			})
+		})
+
+		it("should use WARNING_THRESHOLD_MS constant of 5000ms", () => {
+			// Verify the warning threshold is 5 seconds by checking the implementation
+			const WARNING_THRESHOLD_MS = 5000
+			expect(WARNING_THRESHOLD_MS).toBe(5000)
+			expect(WARNING_THRESHOLD_MS / 1000).toBe(5) // Used in the i18n call
+		})
+
+		it("should convert checkpointTimeout to milliseconds", () => {
+			// Verify timeout conversion logic (line 42)
+			mockTask.checkpointTimeout = 15
+			const checkpointTimeoutMs = mockTask.checkpointTimeout * 1000
+			expect(checkpointTimeoutMs).toBe(15000)
+
+			mockTask.checkpointTimeout = 10
+			expect(mockTask.checkpointTimeout * 1000).toBe(10000)
+
+			mockTask.checkpointTimeout = 60
+			expect(mockTask.checkpointTimeout * 1000).toBe(60000)
+		})
+
+		it("should use correct i18n keys for warning messages", async () => {
+			const i18nModule = await import("../../../i18n")
+			vi.clearAllMocks()
+
+			// Test warning message i18n key
+			const warningMessage = i18nModule.t("common:errors.wait_checkpoint_long_time", { timeout: 5 })
+			expect(warningMessage).toBe("Checkpoint initialization is taking longer than 5 seconds...")
+
+			// Test timeout error message i18n key
+			const errorMessage = i18nModule.t("common:errors.init_checkpoint_fail_long_time", { timeout: 30 })
+			expect(errorMessage).toBe("Checkpoint initialization failed after 30 seconds")
+		})
+	})
 })

+ 38 - 6
src/core/checkpoints/index.ts

@@ -16,10 +16,16 @@ import { DIFF_VIEW_URI_SCHEME } from "../../integrations/editor/DiffViewProvider
 
 import { CheckpointServiceOptions, RepoPerTaskCheckpointService } from "../../services/checkpoints"
 
-export async function getCheckpointService(
-	task: Task,
-	{ interval = 250, timeout = 15_000 }: { interval?: number; timeout?: number } = {},
-) {
+const WARNING_THRESHOLD_MS = 5000
+
+function sendCheckpointInitWarn(task: Task, type?: "WAIT_TIMEOUT" | "INIT_TIMEOUT", timeout?: number) {
+	task.providerRef.deref()?.postMessageToWebview({
+		type: "checkpointInitWarning",
+		checkpointWarning: type && timeout ? { type, timeout } : undefined,
+	})
+}
+
+export async function getCheckpointService(task: Task, { interval = 250 }: { interval?: number } = {}) {
 	if (!task.enableCheckpoints) {
 		return undefined
 	}
@@ -30,6 +36,9 @@ export async function getCheckpointService(
 
 	const provider = task.providerRef.deref()
 
+	// Get checkpoint timeout from task settings (converted to milliseconds)
+	const checkpointTimeoutMs = task.checkpointTimeout * 1000
+
 	const log = (message: string) => {
 		console.log(message)
 
@@ -67,16 +76,32 @@ export async function getCheckpointService(
 		}
 
 		if (task.checkpointServiceInitializing) {
+			const checkpointInitStartTime = Date.now()
+			let warningShown = false
+
 			await pWaitFor(
 				() => {
-					console.log("[Task#getCheckpointService] waiting for service to initialize")
+					const elapsed = Date.now() - checkpointInitStartTime
+
+					// Show warning if we're past the threshold and haven't shown it yet
+					if (!warningShown && elapsed >= WARNING_THRESHOLD_MS) {
+						warningShown = true
+						sendCheckpointInitWarn(task, "WAIT_TIMEOUT", WARNING_THRESHOLD_MS / 1000)
+					}
+
+					console.log(
+						`[Task#getCheckpointService] waiting for service to initialize (${Math.round(elapsed / 1000)}s)`,
+					)
 					return !!task.checkpointService && !!task?.checkpointService?.isInitialized
 				},
-				{ interval, timeout },
+				{ interval, timeout: checkpointTimeoutMs },
 			)
 			if (!task?.checkpointService) {
+				sendCheckpointInitWarn(task, "INIT_TIMEOUT", task.checkpointTimeout)
 				task.enableCheckpoints = false
 				return undefined
+			} else {
+				sendCheckpointInitWarn(task)
 			}
 			return task.checkpointService
 		}
@@ -89,8 +114,14 @@ export async function getCheckpointService(
 		task.checkpointServiceInitializing = true
 		await checkGitInstallation(task, service, log, provider)
 		task.checkpointService = service
+		if (task.enableCheckpoints) {
+			sendCheckpointInitWarn(task)
+		}
 		return service
 	} catch (err) {
+		if (err.name === "TimeoutError" && task.enableCheckpoints) {
+			sendCheckpointInitWarn(task, "INIT_TIMEOUT", task.checkpointTimeout)
+		}
 		log(`[Task#getCheckpointService] ${err.message}`)
 		task.enableCheckpoints = false
 		task.checkpointServiceInitializing = false
@@ -133,6 +164,7 @@ async function checkGitInstallation(
 
 		service.on("checkpoint", ({ fromHash: from, toHash: to, suppressMessage }) => {
 			try {
+				sendCheckpointInitWarn(task)
 				// Always update the current checkpoint hash in the webview, including the suppress flag
 				provider?.postMessageToWebview({
 					type: "currentCheckpointUpdated",

+ 21 - 0
src/core/task/Task.ts

@@ -35,6 +35,9 @@ import {
 	isInteractiveAsk,
 	isResumableAsk,
 	QueuedMessage,
+	DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
+	MAX_CHECKPOINT_TIMEOUT_SECONDS,
+	MIN_CHECKPOINT_TIMEOUT_SECONDS,
 } from "@roo-code/types"
 import { TelemetryService } from "@roo-code/telemetry"
 import { CloudService, BridgeOrchestrator } from "@roo-code/cloud"
@@ -125,6 +128,7 @@ export interface TaskOptions extends CreateTaskOptions {
 	apiConfiguration: ProviderSettings
 	enableDiff?: boolean
 	enableCheckpoints?: boolean
+	checkpointTimeout?: number
 	enableBridge?: boolean
 	fuzzyMatchThreshold?: number
 	consecutiveMistakeLimit?: number
@@ -267,6 +271,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
 
 	// Checkpoints
 	enableCheckpoints: boolean
+	checkpointTimeout: number
 	checkpointService?: RepoPerTaskCheckpointService
 	checkpointServiceInitializing = false
 
@@ -303,6 +308,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
 		apiConfiguration,
 		enableDiff = false,
 		enableCheckpoints = true,
+		checkpointTimeout = DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
 		enableBridge = false,
 		fuzzyMatchThreshold = 1.0,
 		consecutiveMistakeLimit = DEFAULT_CONSECUTIVE_MISTAKE_LIMIT,
@@ -323,6 +329,20 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
 			throw new Error("Either historyItem or task/images must be provided")
 		}
 
+		if (
+			!checkpointTimeout ||
+			checkpointTimeout > MAX_CHECKPOINT_TIMEOUT_SECONDS ||
+			checkpointTimeout < MIN_CHECKPOINT_TIMEOUT_SECONDS
+		) {
+			throw new Error(
+				"checkpointTimeout must be between " +
+					MIN_CHECKPOINT_TIMEOUT_SECONDS +
+					" and " +
+					MAX_CHECKPOINT_TIMEOUT_SECONDS +
+					" seconds",
+			)
+		}
+
 		this.taskId = historyItem ? historyItem.id : crypto.randomUUID()
 		this.rootTaskId = historyItem ? historyItem.rootTaskId : rootTask?.taskId
 		this.parentTaskId = historyItem ? historyItem.parentTaskId : parentTask?.taskId
@@ -362,6 +382,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
 		this.globalStoragePath = provider.context.globalStorageUri.fsPath
 		this.diffViewProvider = new DiffViewProvider(this.cwd, this)
 		this.enableCheckpoints = enableCheckpoints
+		this.checkpointTimeout = checkpointTimeout
 		this.enableBridge = enableBridge
 
 		this.parentTask = parentTask

+ 8 - 0
src/core/webview/ClineProvider.ts

@@ -41,6 +41,7 @@ import {
 	DEFAULT_WRITE_DELAY_MS,
 	ORGANIZATION_ALLOW_ALL,
 	DEFAULT_MODES,
+	DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
 } from "@roo-code/types"
 import { TelemetryService } from "@roo-code/telemetry"
 import { CloudService, BridgeOrchestrator, getRooCodeApiUrl } from "@roo-code/cloud"
@@ -895,6 +896,7 @@ export class ClineProvider
 			apiConfiguration,
 			diffEnabled: enableDiff,
 			enableCheckpoints,
+			checkpointTimeout,
 			fuzzyMatchThreshold,
 			experiments,
 			cloudUserInfo,
@@ -906,6 +908,7 @@ export class ClineProvider
 			apiConfiguration,
 			enableDiff,
 			enableCheckpoints,
+			checkpointTimeout,
 			fuzzyMatchThreshold,
 			consecutiveMistakeLimit: apiConfiguration.consecutiveMistakeLimit,
 			historyItem,
@@ -1748,6 +1751,7 @@ export class ClineProvider
 			ttsSpeed,
 			diffEnabled,
 			enableCheckpoints,
+			checkpointTimeout,
 			taskHistory,
 			soundVolume,
 			browserViewportSize,
@@ -1869,6 +1873,7 @@ export class ClineProvider
 			ttsSpeed: ttsSpeed ?? 1.0,
 			diffEnabled: diffEnabled ?? true,
 			enableCheckpoints: enableCheckpoints ?? true,
+			checkpointTimeout: checkpointTimeout ?? DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
 			shouldShowAnnouncement:
 				telemetrySetting !== "unset" && lastShownAnnouncementId !== this.latestAnnouncementId,
 			allowedCommands: mergedAllowedCommands,
@@ -2091,6 +2096,7 @@ export class ClineProvider
 			ttsSpeed: stateValues.ttsSpeed ?? 1.0,
 			diffEnabled: stateValues.diffEnabled ?? true,
 			enableCheckpoints: stateValues.enableCheckpoints ?? true,
+			checkpointTimeout: stateValues.checkpointTimeout ?? DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
 			soundVolume: stateValues.soundVolume,
 			browserViewportSize: stateValues.browserViewportSize ?? "900x600",
 			screenshotQuality: stateValues.screenshotQuality ?? 75,
@@ -2534,6 +2540,7 @@ export class ClineProvider
 			organizationAllowList,
 			diffEnabled: enableDiff,
 			enableCheckpoints,
+			checkpointTimeout,
 			fuzzyMatchThreshold,
 			experiments,
 			cloudUserInfo,
@@ -2549,6 +2556,7 @@ export class ClineProvider
 			apiConfiguration,
 			enableDiff,
 			enableCheckpoints,
+			checkpointTimeout,
 			fuzzyMatchThreshold,
 			consecutiveMistakeLimit: apiConfiguration.consecutiveMistakeLimit,
 			task: text,

+ 7 - 1
src/core/webview/__tests__/ClineProvider.spec.ts

@@ -4,7 +4,12 @@ import Anthropic from "@anthropic-ai/sdk"
 import * as vscode from "vscode"
 import axios from "axios"
 
-import { type ProviderSettingsEntry, type ClineMessage, ORGANIZATION_ALLOW_ALL } from "@roo-code/types"
+import {
+	type ProviderSettingsEntry,
+	type ClineMessage,
+	ORGANIZATION_ALLOW_ALL,
+	DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
+} from "@roo-code/types"
 import { TelemetryService } from "@roo-code/telemetry"
 
 import { ExtensionMessage, ExtensionState } from "../../../shared/ExtensionMessage"
@@ -556,6 +561,7 @@ describe("ClineProvider", () => {
 			remoteControlEnabled: false,
 			taskSyncEnabled: false,
 			featureRoomoteControlEnabled: false,
+			checkpointTimeout: DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
 		}
 
 		const message: ExtensionMessage = {

+ 6 - 0
src/core/webview/webviewMessageHandler.ts

@@ -12,6 +12,7 @@ import {
 	type TelemetrySetting,
 	TelemetryEventName,
 	UserSettingsConfig,
+	DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
 } from "@roo-code/types"
 import { CloudService } from "@roo-code/cloud"
 import { TelemetryService } from "@roo-code/telemetry"
@@ -1262,6 +1263,11 @@ export const webviewMessageHandler = async (
 			await updateGlobalState("enableCheckpoints", enableCheckpoints)
 			await provider.postStateToWebview()
 			break
+		case "checkpointTimeout":
+			const checkpointTimeout = message.value ?? DEFAULT_CHECKPOINT_TIMEOUT_SECONDS
+			await updateGlobalState("checkpointTimeout", checkpointTimeout)
+			await provider.postStateToWebview()
+			break
 		case "browserViewportSize":
 			const browserViewportSize = message.text ?? "900x600"
 			await updateGlobalState("browserViewportSize", browserViewportSize)

+ 1 - 1
src/services/checkpoints/ShadowCheckpointService.ts

@@ -152,7 +152,7 @@ export abstract class ShadowCheckpointService extends EventEmitter {
 
 	private async stageAll(git: SimpleGit) {
 		try {
-			await git.add(".")
+			await git.add([".", "--ignore-errors"])
 		} catch (error) {
 			this.log(
 				`[${this.constructor.name}#stageAll] failed to add files to git: ${error instanceof Error ? error.message : String(error)}`,

+ 7 - 0
src/shared/ExtensionMessage.ts

@@ -92,6 +92,7 @@ export interface ExtensionMessage {
 		| "checkRulesDirectoryResult"
 		| "deleteCustomModeCheck"
 		| "currentCheckpointUpdated"
+		| "checkpointInitWarning"
 		| "showHumanRelayDialog"
 		| "humanRelayResponse"
 		| "humanRelayCancel"
@@ -128,6 +129,11 @@ export interface ExtensionMessage {
 		| "organizationSwitchResult"
 	text?: string
 	payload?: any // Add a generic payload for now, can refine later
+	// Checkpoint warning message
+	checkpointWarning?: {
+		type: "WAIT_TIMEOUT" | "INIT_TIMEOUT"
+		timeout: number
+	}
 	action?:
 		| "chatButtonClicked"
 		| "mcpButtonClicked"
@@ -303,6 +309,7 @@ export type ExtensionState = Pick<
 	requestDelaySeconds: number
 
 	enableCheckpoints: boolean
+	checkpointTimeout: number // Timeout for checkpoint initialization in seconds (default: 15)
 	maxOpenTabsContext: number // Maximum number of VSCode open tabs to include in context (0-500)
 	maxWorkspaceFiles: number // Maximum number of files to include in current working directory details (0-500)
 	showRooIgnoredFiles: boolean // Whether to show .rooignore'd files in listings

+ 1 - 0
src/shared/WebviewMessage.ts

@@ -99,6 +99,7 @@ export interface WebviewMessage {
 		| "soundVolume"
 		| "diffEnabled"
 		| "enableCheckpoints"
+		| "checkpointTimeout"
 		| "browserViewportSize"
 		| "screenshotQuality"
 		| "remoteBrowserHost"

+ 13 - 21
webview-ui/src/components/chat/ChatView.tsx

@@ -192,7 +192,9 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
 	const [isAtBottom, setIsAtBottom] = useState(false)
 	const lastTtsRef = useRef<string>("")
 	const [wasStreaming, setWasStreaming] = useState<boolean>(false)
-	const [showCheckpointWarning, setShowCheckpointWarning] = useState<boolean>(false)
+	const [checkpointWarning, setCheckpointWarning] = useState<
+		{ type: "WAIT_TIMEOUT" | "INIT_TIMEOUT"; timeout: number } | undefined
+	>(undefined)
 	const [isCondensing, setIsCondensing] = useState<boolean>(false)
 	const [showAnnouncementModal, setShowAnnouncementModal] = useState(false)
 	const everVisibleMessagesTsRef = useRef<LRUCache<number, boolean>>(
@@ -829,6 +831,9 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
 						setIsCondensing(false)
 					}
 					break
+				case "checkpointInitWarning":
+					setCheckpointWarning(message.checkpointWarning)
+					break
 			}
 			// textAreaRef.current is not explicitly required here since React
 			// guarantees that ref will be stable across re-renders, and we're
@@ -845,6 +850,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
 			handleSetChatBoxMessage,
 			handlePrimaryButtonClick,
 			handleSecondaryButtonClick,
+			setCheckpointWarning,
 		],
 	)
 
@@ -1420,26 +1426,12 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
 
 	useEvent("wheel", handleWheel, window, { passive: true }) // passive improves scrolling performance
 
-	// Effect to handle showing the checkpoint warning after a delay
-	useEffect(() => {
-		// Only show the warning when there's a task but no visible messages yet
-		if (task && modifiedMessages.length === 0 && !isStreaming && !isHidden) {
-			const timer = setTimeout(() => {
-				setShowCheckpointWarning(true)
-			}, 5000) // 5 seconds
-
-			return () => clearTimeout(timer)
-		} else {
-			setShowCheckpointWarning(false)
-		}
-	}, [task, modifiedMessages.length, isStreaming, isHidden])
-
-	// Effect to hide the checkpoint warning when messages appear
+	// Effect to clear checkpoint warning when messages appear or task changes
 	useEffect(() => {
-		if (modifiedMessages.length > 0 || isStreaming || isHidden) {
-			setShowCheckpointWarning(false)
+		if (isHidden || !task) {
+			setCheckpointWarning(undefined)
 		}
-	}, [modifiedMessages.length, isStreaming, isHidden])
+	}, [modifiedMessages.length, isStreaming, isHidden, task])
 
 	const placeholderText = task ? t("chat:typeMessage") : t("chat:typeTask")
 
@@ -1810,9 +1802,9 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
 						</div>
 					)}
 
-					{showCheckpointWarning && (
+					{checkpointWarning && (
 						<div className="px-3">
-							<CheckpointWarning />
+							<CheckpointWarning warning={checkpointWarning} />
 						</div>
 					)}
 				</>

+ 35 - 22
webview-ui/src/components/chat/CheckpointWarning.tsx

@@ -1,32 +1,45 @@
-import { Trans } from "react-i18next"
 import { VSCodeLink } from "@vscode/webview-ui-toolkit/react"
+import { Trans } from "react-i18next"
+
+interface CheckpointWarningProps {
+	warning: {
+		type: "WAIT_TIMEOUT" | "INIT_TIMEOUT"
+		timeout: number
+	}
+}
+
+export const CheckpointWarning = ({ warning }: CheckpointWarningProps) => {
+	const settingsLink = (
+		<VSCodeLink
+			href="#"
+			onClick={(e) => {
+				e.preventDefault()
+				window.postMessage(
+					{
+						type: "action",
+						action: "settingsButtonClicked",
+						values: { section: "checkpoints" },
+					},
+					"*",
+				)
+			}}
+			className="inline"
+		/>
+	)
+
+	// Map warning type to i18n key
+	const i18nKey =
+		warning.type === "WAIT_TIMEOUT" ? "errors.wait_checkpoint_long_time" : "errors.init_checkpoint_fail_long_time"
 
-export const CheckpointWarning = () => {
 	return (
 		<div className="flex items-center p-3 my-3 bg-vscode-inputValidation-warningBackground border border-vscode-inputValidation-warningBorder rounded">
 			<span className="codicon codicon-loading codicon-modifier-spin mr-2" />
 			<span className="text-vscode-foreground">
 				<Trans
-					i18nKey="chat:checkpoint.initializingWarning"
-					components={{
-						settingsLink: (
-							<VSCodeLink
-								href="#"
-								onClick={(e) => {
-									e.preventDefault()
-									window.postMessage(
-										{
-											type: "action",
-											action: "settingsButtonClicked",
-											values: { section: "checkpoints" },
-										},
-										"*",
-									)
-								}}
-								className="inline px-0.5"
-							/>
-						),
-					}}
+					i18nKey={i18nKey}
+					ns="common"
+					values={{ timeout: warning.timeout }}
+					components={{ settingsLink }}
 				/>
 			</span>
 		</div>

+ 3 - 0
webview-ui/src/components/marketplace/__tests__/MarketplaceView.spec.tsx

@@ -5,6 +5,7 @@ import { vscode } from "@/utils/vscode"
 
 import { MarketplaceView } from "../MarketplaceView"
 import { MarketplaceViewStateManager } from "../MarketplaceViewStateManager"
+import { DEFAULT_CHECKPOINT_TIMEOUT_SECONDS } from "@roo-code/types"
 
 vi.mock("@/utils/vscode", () => ({
 	vscode: {
@@ -66,6 +67,7 @@ describe("MarketplaceView", () => {
 			setFollowupAutoApproveTimeoutMs: vi.fn(),
 			profileThresholds: {},
 			setProfileThresholds: vi.fn(),
+			checkpointTimeout: DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
 			// ... other required context properties
 		}
 	})
@@ -86,6 +88,7 @@ describe("MarketplaceView", () => {
 		mockExtensionState = {
 			...mockExtensionState,
 			organizationSettingsVersion: 2,
+			checkpointTimeout: DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
 		}
 
 		// Re-render with updated context

+ 41 - 2
webview-ui/src/components/settings/CheckpointSettings.tsx

@@ -4,17 +4,29 @@ import { VSCodeCheckbox, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
 import { GitBranch } from "lucide-react"
 import { Trans } from "react-i18next"
 import { buildDocLink } from "@src/utils/docLinks"
+import { Slider } from "@/components/ui"
 
 import { SetCachedStateField } from "./types"
 import { SectionHeader } from "./SectionHeader"
 import { Section } from "./Section"
+import {
+	DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
+	MAX_CHECKPOINT_TIMEOUT_SECONDS,
+	MIN_CHECKPOINT_TIMEOUT_SECONDS,
+} from "@roo-code/types"
 
 type CheckpointSettingsProps = HTMLAttributes<HTMLDivElement> & {
 	enableCheckpoints?: boolean
-	setCachedStateField: SetCachedStateField<"enableCheckpoints">
+	checkpointTimeout?: number
+	setCachedStateField: SetCachedStateField<"enableCheckpoints" | "checkpointTimeout">
 }
 
-export const CheckpointSettings = ({ enableCheckpoints, setCachedStateField, ...props }: CheckpointSettingsProps) => {
+export const CheckpointSettings = ({
+	enableCheckpoints,
+	checkpointTimeout,
+	setCachedStateField,
+	...props
+}: CheckpointSettingsProps) => {
 	const { t } = useAppTranslation()
 	return (
 		<div {...props}>
@@ -44,6 +56,33 @@ export const CheckpointSettings = ({ enableCheckpoints, setCachedStateField, ...
 						</Trans>
 					</div>
 				</div>
+
+				{enableCheckpoints && (
+					<div className="mt-4">
+						<label className="block text-sm font-medium mb-2">
+							{t("settings:checkpoints.timeout.label")}
+						</label>
+						<div className="flex items-center gap-2">
+							<Slider
+								min={MIN_CHECKPOINT_TIMEOUT_SECONDS}
+								max={MAX_CHECKPOINT_TIMEOUT_SECONDS}
+								step={1}
+								defaultValue={[checkpointTimeout ?? DEFAULT_CHECKPOINT_TIMEOUT_SECONDS]}
+								onValueChange={([value]) => {
+									setCachedStateField("checkpointTimeout", value)
+								}}
+								className="flex-1"
+								data-testid="checkpoint-timeout-slider"
+							/>
+							<span className="w-12 text-center">
+								{checkpointTimeout ?? DEFAULT_CHECKPOINT_TIMEOUT_SECONDS}
+							</span>
+						</div>
+						<div className="text-vscode-descriptionForeground text-sm mt-1">
+							{t("settings:checkpoints.timeout.description")}
+						</div>
+					</div>
+				)}
 			</Section>
 		</div>
 	)

+ 3 - 0
webview-ui/src/components/settings/SettingsView.tsx

@@ -150,6 +150,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
 		browserToolEnabled,
 		browserViewportSize,
 		enableCheckpoints,
+		checkpointTimeout,
 		diffEnabled,
 		experiments,
 		fuzzyMatchThreshold,
@@ -343,6 +344,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
 			vscode.postMessage({ type: "soundVolume", value: soundVolume })
 			vscode.postMessage({ type: "diffEnabled", bool: diffEnabled })
 			vscode.postMessage({ type: "enableCheckpoints", bool: enableCheckpoints })
+			vscode.postMessage({ type: "checkpointTimeout", value: checkpointTimeout })
 			vscode.postMessage({ type: "browserViewportSize", text: browserViewportSize })
 			vscode.postMessage({ type: "remoteBrowserHost", text: remoteBrowserHost })
 			vscode.postMessage({ type: "remoteBrowserEnabled", bool: remoteBrowserEnabled })
@@ -712,6 +714,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
 					{activeTab === "checkpoints" && (
 						<CheckpointSettings
 							enableCheckpoints={enableCheckpoints}
+							checkpointTimeout={checkpointTimeout}
 							setCachedStateField={setCachedStateField}
 						/>
 					)}

+ 5 - 0
webview-ui/src/context/ExtensionStateContext.tsx

@@ -11,6 +11,7 @@ import {
 	type OrganizationAllowList,
 	type CloudOrganizationMembership,
 	ORGANIZATION_ALLOW_ALL,
+	DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
 } from "@roo-code/types"
 
 import { ExtensionMessage, ExtensionState, MarketplaceInstalledMetadata, Command } from "@roo/ExtensionMessage"
@@ -88,6 +89,8 @@ export interface ExtensionStateContextType extends ExtensionState {
 	setTtsSpeed: (value: number) => void
 	setDiffEnabled: (value: boolean) => void
 	setEnableCheckpoints: (value: boolean) => void
+	checkpointTimeout: number
+	setCheckpointTimeout: (value: number) => void
 	setBrowserViewportSize: (value: string) => void
 	setFuzzyMatchThreshold: (value: number) => void
 	setWriteDelayMs: (value: number) => void
@@ -197,6 +200,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
 		ttsSpeed: 1.0,
 		diffEnabled: false,
 		enableCheckpoints: true,
+		checkpointTimeout: DEFAULT_CHECKPOINT_TIMEOUT_SECONDS, // Default to 15 seconds
 		fuzzyMatchThreshold: 1.0,
 		language: "en", // Default language code
 		writeDelayMs: 1000,
@@ -473,6 +477,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
 		setTtsSpeed: (value) => setState((prevState) => ({ ...prevState, ttsSpeed: value })),
 		setDiffEnabled: (value) => setState((prevState) => ({ ...prevState, diffEnabled: value })),
 		setEnableCheckpoints: (value) => setState((prevState) => ({ ...prevState, enableCheckpoints: value })),
+		setCheckpointTimeout: (value) => setState((prevState) => ({ ...prevState, checkpointTimeout: value })),
 		setBrowserViewportSize: (value: string) =>
 			setState((prevState) => ({ ...prevState, browserViewportSize: value })),
 		setFuzzyMatchThreshold: (value) => setState((prevState) => ({ ...prevState, fuzzyMatchThreshold: value })),

+ 4 - 1
webview-ui/src/context/__tests__/ExtensionStateContext.spec.tsx

@@ -1,6 +1,6 @@
 import { render, screen, act } from "@/utils/test-utils"
 
-import { ProviderSettings, ExperimentId } from "@roo-code/types"
+import { ProviderSettings, ExperimentId, DEFAULT_CHECKPOINT_TIMEOUT_SECONDS } from "@roo-code/types"
 
 import { ExtensionState } from "@roo/ExtensionMessage"
 
@@ -214,12 +214,14 @@ describe("mergeExtensionState", () => {
 			remoteControlEnabled: false,
 			taskSyncEnabled: false,
 			featureRoomoteControlEnabled: false,
+			checkpointTimeout: DEFAULT_CHECKPOINT_TIMEOUT_SECONDS, // Add the checkpoint timeout property
 		}
 
 		const prevState: ExtensionState = {
 			...baseState,
 			apiConfiguration: { modelMaxTokens: 1234, modelMaxThinkingTokens: 123 },
 			experiments: {} as Record<ExperimentId, boolean>,
+			checkpointTimeout: DEFAULT_CHECKPOINT_TIMEOUT_SECONDS - 5,
 		}
 
 		const newState: ExtensionState = {
@@ -236,6 +238,7 @@ describe("mergeExtensionState", () => {
 				imageGeneration: false,
 				runSlashCommand: false,
 			} as Record<ExperimentId, boolean>,
+			checkpointTimeout: DEFAULT_CHECKPOINT_TIMEOUT_SECONDS + 5,
 		}
 
 		const result = mergeExtensionState(prevState, newState)

+ 4 - 0
webview-ui/src/i18n/locales/ca/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "fa {{count}} mesos",
 		"year_ago": "fa un any",
 		"years_ago": "fa {{count}} anys"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "Has esperat {{timeout}} segons per inicialitzar el punt de control. Si no necessites aquesta funció, desactiva-la a <settingsLink>la configuració del punt de control</settingsLink>.",
+		"init_checkpoint_fail_long_time": "La inicialització del punt de control ha trigat més de {{timeout}} segons, per això els punts de control estan desactivats per a aquesta tasca. Pots desactivar els punts de control o augmentar el temps d'espera a <settingsLink>la configuració del punt de control</settingsLink>."
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/ca/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "Temps d'espera per inicialitzar el punt de control (segons)",
+			"description": "Temps màxim d'espera per inicialitzar el servei de punts de control. El valor per defecte és 15 segons. Rang: 10-60 segons."
+		},
 		"enable": {
 			"label": "Habilitar punts de control automàtics",
 			"description": "Quan està habilitat, Roo crearà automàticament punts de control durant l'execució de tasques, facilitant la revisió de canvis o la reversió a estats anteriors. <0>Més informació</0>"

+ 4 - 0
webview-ui/src/i18n/locales/de/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "vor {{count}} Monaten",
 		"year_ago": "vor einem Jahr",
 		"years_ago": "vor {{count}} Jahren"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "Du hast {{timeout}} Sekunden auf die Initialisierung des Checkpoints gewartet. Wenn du die Checkpoint-Funktion nicht brauchst, kannst du sie in den <settingsLink>Checkpoint-Einstellungen</settingsLink> ausschalten.",
+		"init_checkpoint_fail_long_time": "Die Initialisierung des Checkpoints dauert länger als {{timeout}} Sekunden, deshalb sind Checkpoints für diese Aufgabe deaktiviert. Du kannst Checkpoints ausschalten oder die Wartezeit in den <settingsLink>Checkpoint-Einstellungen</settingsLink> verlängern."
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/de/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "Timeout für Checkpoint-Initialisierung (Sekunden)",
+			"description": "Maximale Wartezeit für die Initialisierung des Checkpoint-Dienstes. Standard ist 15 Sekunden. Bereich: 10-60 Sekunden."
+		},
 		"enable": {
 			"label": "Automatische Kontrollpunkte aktivieren",
 			"description": "Wenn aktiviert, erstellt Roo automatisch Kontrollpunkte während der Aufgabenausführung, was die Überprüfung von Änderungen oder die Rückkehr zu früheren Zuständen erleichtert. <0>Mehr erfahren</0>"

+ 4 - 0
webview-ui/src/i18n/locales/en/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "{{count}} months ago",
 		"year_ago": "a year ago",
 		"years_ago": "{{count}} years ago"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "Waited {{timeout}} seconds for checkpoint initialization. If you don't need the checkpoint feature, please turn it off in <settingsLink>the checkpoint settings</settingsLink>.",
+		"init_checkpoint_fail_long_time": "Checkpoint initialization has taken more than {{timeout}} seconds, so checkpoints are disabled for this task. You can disable checkpoints or extend the waiting time in <settingsLink>the checkpoint settings</settingsLink>."
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/en/settings.json

@@ -515,6 +515,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "Checkpoint initialization timeout (seconds)",
+			"description": "Maximum time to wait for checkpoint service initialization. Default is 15 seconds. Range: 10-60 seconds."
+		},
 		"enable": {
 			"label": "Enable automatic checkpoints",
 			"description": "When enabled, Roo will automatically create checkpoints during task execution, making it easy to review changes or revert to earlier states. <0>Learn more</0>"

+ 4 - 0
webview-ui/src/i18n/locales/es/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "hace {{count}} meses",
 		"year_ago": "hace un año",
 		"years_ago": "hace {{count}} años"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "Has esperado {{timeout}} segundos para la inicialización del punto de control. Si no necesitas esta función, desactívala en <settingsLink>la configuración del punto de control</settingsLink>.",
+		"init_checkpoint_fail_long_time": "La inicialización del punto de control ha tardado más de {{timeout}} segundos, por lo que los puntos de control están desactivados para esta tarea. Puedes desactivar los puntos de control o aumentar el tiempo de espera en <settingsLink>la configuración del punto de control</settingsLink>."
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/es/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "Tiempo de espera para inicializar el punto de control (segundos)",
+			"description": "Tiempo máximo de espera para inicializar el servicio de puntos de control. El valor por defecto es 15 segundos. Rango: 10-60 segundos."
+		},
 		"enable": {
 			"label": "Habilitar puntos de control automáticos",
 			"description": "Cuando está habilitado, Roo creará automáticamente puntos de control durante la ejecución de tareas, facilitando la revisión de cambios o la reversión a estados anteriores. <0>Más información</0>"

+ 4 - 0
webview-ui/src/i18n/locales/fr/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "il y a {{count}} mois",
 		"year_ago": "il y a un an",
 		"years_ago": "il y a {{count}} ans"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "Tu as attendu {{timeout}} secondes pour l'initialisation du checkpoint. Si tu n'as pas besoin de cette fonction, désactive-la dans <settingsLink>les paramètres du checkpoint</settingsLink>.",
+		"init_checkpoint_fail_long_time": "L'initialisation du checkpoint a pris plus de {{timeout}} secondes, donc les checkpoints sont désactivés pour cette tâche. Tu peux désactiver les checkpoints ou prolonger le délai dans <settingsLink>les paramètres du checkpoint</settingsLink>."
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/fr/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "Délai d'initialisation du point de contrôle (secondes)",
+			"description": "Temps d'attente maximum pour l'initialisation du service de points de contrôle. Par défaut : 15 secondes. Plage : 10-60 secondes."
+		},
 		"enable": {
 			"label": "Activer les points de contrôle automatiques",
 			"description": "Lorsque cette option est activée, Roo créera automatiquement des points de contrôle pendant l'exécution des tâches, facilitant la révision des modifications ou le retour à des états antérieurs. <0>En savoir plus</0>"

+ 4 - 0
webview-ui/src/i18n/locales/hi/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "{{count}} महीने पहले",
 		"year_ago": "एक साल पहले",
 		"years_ago": "{{count}} साल पहले"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "तुमने {{timeout}} सेकंड तक चेकपॉइंट इनिशियलाइज़ेशन का इंतजार किया। अगर तुम्हें यह फ़ीचर नहीं चाहिए, तो <settingsLink>चेकपॉइंट सेटिंग्स</settingsLink> में बंद कर दो।",
+		"init_checkpoint_fail_long_time": "चेकपॉइंट इनिशियलाइज़ेशन {{timeout}} सेकंड से ज़्यादा समय ले रहा है, इसलिए इस कार्य के लिए चेकपॉइंट बंद कर दिए गए हैं। तुम चेकपॉइंट बंद कर सकते हो या <settingsLink>चेकपॉइंट सेटिंग्स</settingsLink> में इंतजार का समय बढ़ा सकते हो।"
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/hi/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "चेकपॉइंट इनिशियलाइज़ेशन टाइमआउट (सेकंड)",
+			"description": "चेकपॉइंट सेवा इनिशियलाइज़ करने के लिए अधिकतम प्रतीक्षा समय। डिफ़ॉल्ट 15 सेकंड है। सीमा: 10-60 सेकंड।"
+		},
 		"enable": {
 			"label": "स्वचालित चेकपॉइंट सक्षम करें",
 			"description": "जब सक्षम होता है, तो Roo कार्य निष्पादन के दौरान स्वचालित रूप से चेकपॉइंट बनाएगा, जिससे परिवर्तनों की समीक्षा करना या पहले की स्थितियों पर वापस जाना आसान हो जाएगा। <0>अधिक जानें</0>"

+ 4 - 0
webview-ui/src/i18n/locales/id/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "{{count}} bulan yang lalu",
 		"year_ago": "satu tahun yang lalu",
 		"years_ago": "{{count}} tahun yang lalu"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "Kamu sudah menunggu {{timeout}} detik untuk inisialisasi checkpoint. Kalau tidak butuh fitur ini, matikan saja di <settingsLink>pengaturan checkpoint</settingsLink>.",
+		"init_checkpoint_fail_long_time": "Inisialisasi checkpoint sudah lebih dari {{timeout}} detik, jadi checkpoint dinonaktifkan untuk tugas ini. Kamu bisa mematikan checkpoint atau menambah waktu tunggu di <settingsLink>pengaturan checkpoint</settingsLink>."
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/id/settings.json

@@ -514,6 +514,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "Batas waktu inisialisasi checkpoint (detik)",
+			"description": "Waktu maksimum menunggu inisialisasi layanan checkpoint. Default 15 detik. Rentang: 10-60 detik."
+		},
 		"enable": {
 			"label": "Aktifkan checkpoint otomatis",
 			"description": "Ketika diaktifkan, Roo akan secara otomatis membuat checkpoint selama eksekusi tugas, memudahkan untuk meninjau perubahan atau kembali ke state sebelumnya. <0>Pelajari lebih lanjut</0>"

+ 4 - 0
webview-ui/src/i18n/locales/it/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "{{count}} mesi fa",
 		"year_ago": "un anno fa",
 		"years_ago": "{{count}} anni fa"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "Hai aspettato {{timeout}} secondi per l'inizializzazione del checkpoint. Se non ti serve questa funzione, disattivala nelle <settingsLink>impostazioni del checkpoint</settingsLink>.",
+		"init_checkpoint_fail_long_time": "L'inizializzazione del checkpoint ha impiegato più di {{timeout}} secondi, quindi i checkpoint sono disabilitati per questa attività. Puoi disattivare i checkpoint o aumentare il tempo di attesa nelle <settingsLink>impostazioni del checkpoint</settingsLink>."
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/it/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "Timeout inizializzazione checkpoint (secondi)",
+			"description": "Tempo massimo di attesa per l'inizializzazione del servizio checkpoint. Predefinito: 15 secondi. Intervallo: 10-60 secondi."
+		},
 		"enable": {
 			"label": "Abilita punti di controllo automatici",
 			"description": "Quando abilitato, Roo creerà automaticamente punti di controllo durante l'esecuzione dei compiti, facilitando la revisione delle modifiche o il ritorno a stati precedenti. <0>Scopri di più</0>"

+ 4 - 0
webview-ui/src/i18n/locales/ja/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "{{count}}ヶ月前",
 		"year_ago": "1年前",
 		"years_ago": "{{count}}年前"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "{{timeout}} 秒間チェックポイントの初期化を待機しました。チェックポイント機能が不要な場合は、<settingsLink>チェックポイント設定</settingsLink>でオフにしてください。",
+		"init_checkpoint_fail_long_time": "チェックポイントの初期化が {{timeout}} 秒以上かかったため、このタスクではチェックポイントが無効化されました。チェックポイントをオフにするか、<settingsLink>チェックポイント設定</settingsLink>で待機時間を延長できます。"
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/ja/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "チェックポイント初期化タイムアウト(秒)",
+			"description": "チェックポイントサービスの初期化を待つ最大時間。デフォルトは15秒。範囲:10~60秒。"
+		},
 		"enable": {
 			"label": "自動チェックポイントを有効化",
 			"description": "有効にすると、Rooはタスク実行中に自動的にチェックポイントを作成し、変更の確認や以前の状態への復帰を容易にします。 <0>詳細情報</0>"

+ 4 - 0
webview-ui/src/i18n/locales/ko/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "{{count}}개월 전",
 		"year_ago": "1년 전",
 		"years_ago": "{{count}}년 전"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "{{timeout}}초 동안 체크포인트 초기화를 기다렸어. 체크포인트 기능이 필요 없다면 <settingsLink>체크포인트 설정</settingsLink>에서 꺼 줘.",
+		"init_checkpoint_fail_long_time": "체크포인트 초기화가 {{timeout}}초 이상 걸려서 이 작업에 대해 체크포인트가 꺼졌어. 체크포인트를 끄거나 <settingsLink>체크포인트 설정</settingsLink>에서 대기 시간을 늘릴 수 있어."
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/ko/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "체크포인트 초기화 타임아웃(초)",
+			"description": "체크포인트 서비스 초기화를 기다리는 최대 시간입니다. 기본값은 15초. 범위: 10~60초."
+		},
 		"enable": {
 			"label": "자동 체크포인트 활성화",
 			"description": "활성화되면 Roo는 작업 실행 중에 자동으로 체크포인트를 생성하여 변경 사항을 검토하거나 이전 상태로 되돌리기 쉽게 합니다. <0>더 알아보기</0>"

+ 4 - 0
webview-ui/src/i18n/locales/nl/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "{{count}} maanden geleden",
 		"year_ago": "een jaar geleden",
 		"years_ago": "{{count}} jaar geleden"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "Je hebt {{timeout}} seconden gewacht op de initialisatie van de checkpoint. Als je deze functie niet nodig hebt, schakel hem dan uit in de <settingsLink>checkpoint-instellingen</settingsLink>.",
+		"init_checkpoint_fail_long_time": "De initialisatie van de checkpoint duurde meer dan {{timeout}} seconden, dus checkpoints zijn uitgeschakeld voor deze taak. Je kunt checkpoints uitschakelen of de wachttijd in de <settingsLink>checkpoint-instellingen</settingsLink> verhogen."
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/nl/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "Timeout voor checkpoint-initialisatie (seconden)",
+			"description": "Maximale wachttijd voor het initialiseren van de checkpointservice. Standaard is 15 seconden. Bereik: 10-60 seconden."
+		},
 		"enable": {
 			"label": "Automatische checkpoints inschakelen",
 			"description": "Indien ingeschakeld, maakt Roo automatisch checkpoints tijdens het uitvoeren van taken, zodat je eenvoudig wijzigingen kunt bekijken of terugzetten. <0>Meer informatie</0>"

+ 4 - 0
webview-ui/src/i18n/locales/pl/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "{{count}} miesięcy temu",
 		"year_ago": "rok temu",
 		"years_ago": "{{count}} lat temu"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "Czekałeś {{timeout}} sekund na inicjalizację punktu kontrolnego. Jeśli nie potrzebujesz tej funkcji, wyłącz ją w <settingsLink>ustawieniach punktu kontrolnego</settingsLink>.",
+		"init_checkpoint_fail_long_time": "Inicjalizacja punktu kontrolnego trwała ponad {{timeout}} sekund, więc punkty kontrolne zostały wyłączone dla tego zadania. Możesz wyłączyć punkty kontrolne lub wydłużyć czas oczekiwania w <settingsLink>ustawieniach punktu kontrolnego</settingsLink>."
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/pl/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "Limit czasu inicjalizacji punktu kontrolnego (sekundy)",
+			"description": "Maksymalny czas oczekiwania na inicjalizację usługi punktów kontrolnych. Domyślnie 15 sekund. Zakres: 10-60 sekund."
+		},
 		"enable": {
 			"label": "Włącz automatyczne punkty kontrolne",
 			"description": "Gdy włączone, Roo automatycznie utworzy punkty kontrolne podczas wykonywania zadań, ułatwiając przeglądanie zmian lub powrót do wcześniejszych stanów. <0>Dowiedz się więcej</0>"

+ 4 - 0
webview-ui/src/i18n/locales/pt-BR/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "há {{count}} meses",
 		"year_ago": "há um ano",
 		"years_ago": "há {{count}} anos"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "Você esperou {{timeout}} segundos para inicializar o checkpoint. Se não precisa dessa função, desative nas <settingsLink>configurações do checkpoint</settingsLink>.",
+		"init_checkpoint_fail_long_time": "A inicialização do checkpoint levou mais de {{timeout}} segundos, então os checkpoints foram desativados para esta tarefa. Você pode desativar os checkpoints ou aumentar o tempo de espera nas <settingsLink>configurações do checkpoint</settingsLink>."
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/pt-BR/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "Tempo limite para inicialização do checkpoint (segundos)",
+			"description": "Tempo máximo de espera para inicializar o serviço de checkpoint. Padrão: 15 segundos. Faixa: 10-60 segundos."
+		},
 		"enable": {
 			"label": "Ativar pontos de verificação automáticos",
 			"description": "Quando ativado, o Roo criará automaticamente pontos de verificação durante a execução de tarefas, facilitando a revisão de alterações ou o retorno a estados anteriores. <0>Saiba mais</0>"

+ 4 - 0
webview-ui/src/i18n/locales/ru/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "{{count}} месяцев назад",
 		"year_ago": "год назад",
 		"years_ago": "{{count}} лет назад"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "Ожидание инициализации контрольной точки заняло {{timeout}} секунд. Если тебе не нужна эта функция, отключи её в <settingsLink>настройках контрольных точек</settingsLink>.",
+		"init_checkpoint_fail_long_time": "Инициализация контрольной точки заняла более {{timeout}} секунд, поэтому контрольные точки отключены для этой задачи. Ты можешь отключить контрольные точки или увеличить время ожидания в <settingsLink>настройках контрольных точек</settingsLink>."
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/ru/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "Таймаут инициализации контрольной точки (секунды)",
+			"description": "Максимальное время ожидания инициализации сервиса контрольных точек. По умолчанию 15 секунд. Диапазон: 10-60 секунд."
+		},
 		"enable": {
 			"label": "Включить автоматические контрольные точки",
 			"description": "Если включено, Roo будет автоматически создавать контрольные точки во время выполнения задач, что упрощает просмотр изменений или возврат к предыдущим состояниям. <0>Подробнее</0>"

+ 4 - 0
webview-ui/src/i18n/locales/tr/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "{{count}} ay önce",
 		"year_ago": "bir yıl önce",
 		"years_ago": "{{count}} yıl önce"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "{{timeout}} saniye boyunca kontrol noktası başlatılması beklendi. Bu özelliğe ihtiyacın yoksa <settingsLink>kontrol noktası ayarlarından</settingsLink> kapatabilirsin.",
+		"init_checkpoint_fail_long_time": "Kontrol noktası başlatılması {{timeout}} saniyeden fazla sürdü, bu yüzden bu görev için kontrol noktaları devre dışı bırakıldı. Kontrol noktalarını kapatabilir veya <settingsLink>kontrol noktası ayarlarından</settingsLink> bekleme süresini artırabilirsin."
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/tr/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "Kontrol noktası başlatma zaman aşımı (saniye)",
+			"description": "Kontrol noktası servisini başlatmak için maksimum bekleme süresi. Varsayılan 15 saniye. Aralık: 10-60 saniye."
+		},
 		"enable": {
 			"label": "Otomatik kontrol noktalarını etkinleştir",
 			"description": "Etkinleştirildiğinde, Roo görev yürütme sırasında otomatik olarak kontrol noktaları oluşturarak değişiklikleri gözden geçirmeyi veya önceki durumlara dönmeyi kolaylaştırır. <0>Daha fazla bilgi</0>"

+ 4 - 0
webview-ui/src/i18n/locales/vi/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "{{count}} tháng trước",
 		"year_ago": "một năm trước",
 		"years_ago": "{{count}} năm trước"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "Bạn đã chờ {{timeout}} giây để khởi tạo điểm kiểm tra. Nếu không cần chức năng này, hãy tắt nó trong <settingsLink>cài đặt điểm kiểm tra</settingsLink>.",
+		"init_checkpoint_fail_long_time": "Khởi tạo điểm kiểm tra mất hơn {{timeout}} giây, vì vậy các điểm kiểm tra đã bị vô hiệu hóa cho tác vụ này. Bạn có thể tắt các điểm kiểm tra hoặc tăng thời gian chờ trong <settingsLink>cài đặt điểm kiểm tra</settingsLink>."
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/vi/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "Thời gian chờ khởi tạo điểm kiểm tra (giây)",
+			"description": "Thời gian tối đa chờ khởi tạo dịch vụ điểm kiểm tra. Mặc định là 15 giây. Khoảng: 10-60 giây."
+		},
 		"enable": {
 			"label": "Bật điểm kiểm tra tự động",
 			"description": "Khi được bật, Roo sẽ tự động tạo các điểm kiểm tra trong quá trình thực hiện nhiệm vụ, giúp dễ dàng xem lại các thay đổi hoặc quay lại trạng thái trước đó. <0>Tìm hiểu thêm</0>"

+ 4 - 0
webview-ui/src/i18n/locales/zh-CN/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "{{count}}个月前",
 		"year_ago": "1年前",
 		"years_ago": "{{count}}年前"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "初始化存档点已等待 {{timeout}} 秒。如果你不需要存档点功能,请在<settingsLink>存档点设置</settingsLink>中关闭。",
+		"init_checkpoint_fail_long_time": "存档点初始化已超过 {{timeout}} 秒,因此本任务已禁用存档点。你可以关闭存档点或在<settingsLink>存档点设置</settingsLink>中延长等待时间。"
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/zh-CN/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "存档点初始化超时时间(秒)",
+			"description": "存档点服务初始化最长等待时间。默认 15 秒。范围:10-60 秒。"
+		},
 		"enable": {
 			"label": "启用自动存档点",
 			"description": "开启后自动创建任务存档点,方便回溯修改。 <0>了解更多</0>"

+ 4 - 0
webview-ui/src/i18n/locales/zh-TW/common.json

@@ -95,5 +95,9 @@
 		"months_ago": "{{count}} 個月前",
 		"year_ago": "1 年前",
 		"years_ago": "{{count}} 年前"
+	},
+	"errors": {
+		"wait_checkpoint_long_time": "初始化存檔點已等待 {{timeout}} 秒。如果你不需要存檔點功能,請在<settingsLink>存檔點設定</settingsLink>中關閉。",
+		"init_checkpoint_fail_long_time": "存檔點初始化已超過 {{timeout}} 秒,因此此工作已停用存檔點。你可以關閉存檔點或在<settingsLink>存檔點設定</settingsLink>中延長等待時間。"
 	}
 }

+ 4 - 0
webview-ui/src/i18n/locales/zh-TW/settings.json

@@ -510,6 +510,10 @@
 		}
 	},
 	"checkpoints": {
+		"timeout": {
+			"label": "檢查點初始化逾時(秒)",
+			"description": "檢查點服務初始化的最長等待時間。預設為 15 秒。範圍:10-60 秒。"
+		},
 		"enable": {
 			"label": "啟用自動檢查點",
 			"description": "啟用後,Roo 將在工作執行期間自動建立檢查點,使審核變更或回到早期狀態變得容易。 <0>了解更多</0>"