diff --git a/apps/cli/src/ui/components/autocomplete/triggers/HistoryTrigger.tsx b/apps/cli/src/ui/components/autocomplete/triggers/HistoryTrigger.tsx index 443fdfa9797..86e2fad9b4b 100644 --- a/apps/cli/src/ui/components/autocomplete/triggers/HistoryTrigger.tsx +++ b/apps/cli/src/ui/components/autocomplete/triggers/HistoryTrigger.tsx @@ -21,7 +21,7 @@ export interface HistoryResult extends AutocompleteItem { /** Mode the task was run in */ mode?: string /** Task status */ - status?: "active" | "completed" | "delegated" + status?: "active" | "completed" | "delegated" | "interrupted" } /** @@ -178,7 +178,7 @@ export function toHistoryResult(item: { totalCost?: number workspace?: string mode?: string - status?: "active" | "completed" | "delegated" + status?: "active" | "completed" | "delegated" | "interrupted" }): HistoryResult { return { key: item.id, // Use task ID as the unique key diff --git a/apps/cli/src/ui/types.ts b/apps/cli/src/ui/types.ts index 3c45377c675..48d59d643dd 100644 --- a/apps/cli/src/ui/types.ts +++ b/apps/cli/src/ui/types.ts @@ -109,7 +109,8 @@ export interface TaskHistoryItem { totalCost?: number workspace?: string mode?: string - status?: "active" | "completed" | "delegated" + status?: "active" | "completed" | "delegated" | "interrupted" + background?: boolean tokensIn?: number tokensOut?: number } diff --git a/packages/types/src/history.ts b/packages/types/src/history.ts index a60d1a75b65..67286692e80 100644 --- a/packages/types/src/history.ts +++ b/packages/types/src/history.ts @@ -20,7 +20,8 @@ export const historyItemSchema = z.object({ workspace: z.string().optional(), mode: z.string().optional(), apiConfigName: z.string().optional(), // Provider profile name for sticky profile feature - status: z.enum(["active", "completed", "delegated"]).optional(), + background: z.boolean().optional(), // true if this was a background task + status: z.enum(["active", "completed", "delegated", "interrupted"]).optional(), delegatedToId: z.string().optional(), // Last child this parent delegated to childIds: z.array(z.string()).optional(), // All children spawned by this task awaitingChildId: z.string().optional(), // Child currently awaited (set when delegated) diff --git a/packages/types/src/task.ts b/packages/types/src/task.ts index 7447dc772e7..572302861b5 100644 --- a/packages/types/src/task.ts +++ b/packages/types/src/task.ts @@ -90,7 +90,7 @@ export interface CreateTaskOptions { experiments?: Record initialTodos?: TodoItem[] /** Initial status for the task's history item (e.g., "active" for child tasks) */ - initialStatus?: "active" | "delegated" | "completed" + initialStatus?: "active" | "delegated" | "completed" | "interrupted" /** Whether to start the task loop immediately (default: true). * When false, the caller must invoke `task.start()` manually. */ startTask?: boolean diff --git a/src/core/task-persistence/TaskHistoryStore.ts b/src/core/task-persistence/TaskHistoryStore.ts index 4157d8b9fbb..b8f70841279 100644 --- a/src/core/task-persistence/TaskHistoryStore.ts +++ b/src/core/task-persistence/TaskHistoryStore.ts @@ -88,6 +88,9 @@ export class TaskHistoryStore { // 2. Reconcile cache against actual task directories on disk await this.reconcile() + // 2b. Mark interrupted background tasks (were active when VS Code closed) + this.markInterruptedBackgroundTasks() + // 3. Start fs.watch for cross-instance reactivity this.startWatcher() @@ -233,6 +236,24 @@ export class TaskHistoryStore { }) } + // ────────────────────────────── Background Task Recovery ────────────────────────────── + + /** + * Mark background tasks that were still active when VS Code closed as "interrupted". + * This runs after cache is loaded and reconciled during initialization. + */ + private markInterruptedBackgroundTasks(): void { + for (const [id, item] of this.cache) { + if (item.background && item.status === "active") { + this.cache.set(id, { ...item, status: "interrupted" }) + // Best-effort write of updated status to disk (fire-and-forget during init) + this.writeTaskFile({ ...item, status: "interrupted" }).catch((err) => { + console.error(`[TaskHistoryStore] Failed to mark background task ${id} as interrupted:`, err) + }) + } + } + } + // ────────────────────────────── Reconciliation ────────────────────────────── /** diff --git a/src/core/task-persistence/__tests__/TaskHistoryStore.spec.ts b/src/core/task-persistence/__tests__/TaskHistoryStore.spec.ts index 8adc486160a..c42a7d88ffd 100644 --- a/src/core/task-persistence/__tests__/TaskHistoryStore.spec.ts +++ b/src/core/task-persistence/__tests__/TaskHistoryStore.spec.ts @@ -439,4 +439,58 @@ describe("TaskHistoryStore", () => { expect(store.get("gone-task")).toBeUndefined() }) }) + + describe("markInterruptedBackgroundTasks()", () => { + it("marks active background tasks as interrupted on initialize", async () => { + // Create a background task with active status before initializing + const taskDir = path.join(tmpDir, "tasks", "bg-active-task") + await fs.mkdir(taskDir, { recursive: true }) + const bgItem = makeHistoryItem({ + id: "bg-active-task", + background: true, + status: "active", + }) + await fs.writeFile(path.join(taskDir, GlobalFileNames.historyItem), JSON.stringify(bgItem)) + + await store.initialize() + + const result = store.get("bg-active-task") + expect(result).toBeDefined() + expect(result!.status).toBe("interrupted") + expect(result!.background).toBe(true) + }) + + it("does not mark completed background tasks as interrupted", async () => { + const taskDir = path.join(tmpDir, "tasks", "bg-completed-task") + await fs.mkdir(taskDir, { recursive: true }) + const bgItem = makeHistoryItem({ + id: "bg-completed-task", + background: true, + status: "completed", + }) + await fs.writeFile(path.join(taskDir, GlobalFileNames.historyItem), JSON.stringify(bgItem)) + + await store.initialize() + + const result = store.get("bg-completed-task") + expect(result).toBeDefined() + expect(result!.status).toBe("completed") + }) + + it("does not mark non-background active tasks as interrupted", async () => { + const taskDir = path.join(tmpDir, "tasks", "fg-active-task") + await fs.mkdir(taskDir, { recursive: true }) + const fgItem = makeHistoryItem({ + id: "fg-active-task", + status: "active", + }) + await fs.writeFile(path.join(taskDir, GlobalFileNames.historyItem), JSON.stringify(fgItem)) + + await store.initialize() + + const result = store.get("fg-active-task") + expect(result).toBeDefined() + expect(result!.status).toBe("active") + }) + }) }) diff --git a/src/core/task-persistence/taskMetadata.ts b/src/core/task-persistence/taskMetadata.ts index 4b771269713..979750c351c 100644 --- a/src/core/task-persistence/taskMetadata.ts +++ b/src/core/task-persistence/taskMetadata.ts @@ -24,7 +24,9 @@ export type TaskMetadataOptions = { /** Provider profile name for the task (sticky profile feature) */ apiConfigName?: string /** Initial status for the task (e.g., "active" for child tasks) */ - initialStatus?: "active" | "delegated" | "completed" + initialStatus?: "active" | "delegated" | "completed" | "interrupted" + /** Whether this is a background task */ + background?: boolean } export async function taskMetadata({ @@ -38,6 +40,7 @@ export async function taskMetadata({ mode, apiConfigName, initialStatus, + background, }: TaskMetadataOptions) { const taskDir = await getTaskDirectoryPath(globalStoragePath, id) @@ -112,6 +115,7 @@ export async function taskMetadata({ mode, ...(typeof apiConfigName === "string" && apiConfigName.length > 0 ? { apiConfigName } : {}), ...(initialStatus && { status: initialStatus }), + ...(background && { background: true }), } return { historyItem, tokenUsage } diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 97f07fcc7aa..65acb76a08b 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -152,7 +152,7 @@ export interface TaskOptions extends CreateTaskOptions { initialTodos?: TodoItem[] workspacePath?: string /** Initial status for the task's history item (e.g., "active" for child tasks) */ - initialStatus?: "active" | "delegated" | "completed" + initialStatus?: "active" | "delegated" | "completed" | "interrupted" } export class Task extends EventEmitter implements TaskLike { @@ -406,7 +406,7 @@ export class Task extends EventEmitter implements TaskLike { // Cloud Sync Tracking // Initial status for the task's history item (set at creation time to avoid race conditions) - private readonly initialStatus?: "active" | "delegated" | "completed" + private readonly initialStatus?: "active" | "delegated" | "completed" | "interrupted" // MessageManager for high-level message operations (lazy initialized) private _messageManager?: MessageManager diff --git a/webview-ui/src/components/history/HistoryView.tsx b/webview-ui/src/components/history/HistoryView.tsx index 1d6de93e64d..3672a4dacb6 100644 --- a/webview-ui/src/components/history/HistoryView.tsx +++ b/webview-ui/src/components/history/HistoryView.tsx @@ -41,6 +41,8 @@ const HistoryView = ({ onDone }: HistoryViewProps) => { setLastNonRelevantSort, showAllWorkspaces, setShowAllWorkspaces, + showBackgroundTasks, + setShowBackgroundTasks, } = useTaskSearch() const { t } = useAppTranslation() @@ -223,6 +225,30 @@ const HistoryView = ({ onDone }: HistoryViewProps) => { + {/* Select all control in selection mode */} diff --git a/webview-ui/src/components/history/TaskItemFooter.tsx b/webview-ui/src/components/history/TaskItemFooter.tsx index d0dc367e646..a1d440781e8 100644 --- a/webview-ui/src/components/history/TaskItemFooter.tsx +++ b/webview-ui/src/components/history/TaskItemFooter.tsx @@ -6,7 +6,7 @@ import { ExportButton } from "./ExportButton" import { DeleteButton } from "./DeleteButton" import { StandardTooltip } from "../ui/standard-tooltip" import { useAppTranslation } from "@/i18n/TranslationContext" -import { Split } from "lucide-react" +import { Split, Layers, AlertTriangle } from "lucide-react" export interface TaskItemFooterProps { item: HistoryItem @@ -28,6 +28,20 @@ const TaskItemFooter: React.FC = ({ return (
+ {/* Background task tag */} + {item.background && ( + <> + {item.status === "interrupted" ? ( + + ) : ( + + )} + + {item.status === "interrupted" ? t("history:interruptedTag") : t("history:backgroundTag")} + + · + + )} {/* Subtask tag */} {isSubtask && ( <> diff --git a/webview-ui/src/components/history/__tests__/TaskItemFooter.spec.tsx b/webview-ui/src/components/history/__tests__/TaskItemFooter.spec.tsx index aa334d94c26..337ec2aecd9 100644 --- a/webview-ui/src/components/history/__tests__/TaskItemFooter.spec.tsx +++ b/webview-ui/src/components/history/__tests__/TaskItemFooter.spec.tsx @@ -94,4 +94,33 @@ describe("TaskItemFooter", () => { expect(screen.queryByText("history:subtaskTag")).not.toBeInTheDocument() }) + + it("shows background tag when item.background is true", () => { + const backgroundItem = { ...mockItem, background: true } + render() + + expect(screen.getByText("history:backgroundTag")).toBeInTheDocument() + }) + + it("does not show background tag when item.background is falsy", () => { + render() + + expect(screen.queryByText("history:backgroundTag")).not.toBeInTheDocument() + }) + + it("shows interrupted tag when item is a background task with interrupted status", () => { + const interruptedItem = { ...mockItem, background: true, status: "interrupted" as const } + render() + + expect(screen.getByText("history:interruptedTag")).toBeInTheDocument() + expect(screen.queryByText("history:backgroundTag")).not.toBeInTheDocument() + }) + + it("shows background tag instead of interrupted for active background tasks", () => { + const activeBackgroundItem = { ...mockItem, background: true, status: "active" as const } + render() + + expect(screen.getByText("history:backgroundTag")).toBeInTheDocument() + expect(screen.queryByText("history:interruptedTag")).not.toBeInTheDocument() + }) }) diff --git a/webview-ui/src/components/history/__tests__/useTaskSearch.spec.tsx b/webview-ui/src/components/history/__tests__/useTaskSearch.spec.tsx index bea79814fa1..b99c9ca598d 100644 --- a/webview-ui/src/components/history/__tests__/useTaskSearch.spec.tsx +++ b/webview-ui/src/components/history/__tests__/useTaskSearch.spec.tsx @@ -284,4 +284,65 @@ describe("useTaskSearch", () => { // When not searching, it should fall back to newest expect(result.current.sortOption).toBe("mostRelevant") }) + + it("shows background tasks by default", () => { + const taskHistoryWithBackground: HistoryItem[] = [ + ...mockTaskHistory, + { + id: "task-bg", + number: 4, + task: "Background task", + ts: new Date("2022-02-18T12:00:00").getTime(), + tokensIn: 50, + tokensOut: 25, + totalCost: 0.005, + workspace: "/workspace/project1", + background: true, + }, + ] + + mockUseExtensionState.mockReturnValue({ + taskHistory: taskHistoryWithBackground, + cwd: "/workspace/project1", + } as any) + + const { result } = renderHook(() => useTaskSearch()) + + // Background tasks should be included by default + expect(result.current.showBackgroundTasks).toBe(true) + expect(result.current.tasks.some((task) => task.id === "task-bg")).toBe(true) + }) + + it("hides background tasks when showBackgroundTasks is false", () => { + const taskHistoryWithBackground: HistoryItem[] = [ + ...mockTaskHistory, + { + id: "task-bg", + number: 4, + task: "Background task", + ts: new Date("2022-02-18T12:00:00").getTime(), + tokensIn: 50, + tokensOut: 25, + totalCost: 0.005, + workspace: "/workspace/project1", + background: true, + }, + ] + + mockUseExtensionState.mockReturnValue({ + taskHistory: taskHistoryWithBackground, + cwd: "/workspace/project1", + } as any) + + const { result } = renderHook(() => useTaskSearch()) + + act(() => { + result.current.setShowBackgroundTasks(false) + }) + + // Background tasks should be hidden + expect(result.current.tasks.some((task) => task.id === "task-bg")).toBe(false) + // Non-background tasks should still be visible + expect(result.current.tasks.some((task) => task.id === "task-1")).toBe(true) + }) }) diff --git a/webview-ui/src/components/history/useTaskSearch.ts b/webview-ui/src/components/history/useTaskSearch.ts index 3969985b98a..e4cd6a98ca7 100644 --- a/webview-ui/src/components/history/useTaskSearch.ts +++ b/webview-ui/src/components/history/useTaskSearch.ts @@ -12,6 +12,7 @@ export const useTaskSearch = () => { const [sortOption, setSortOption] = useState("newest") const [lastNonRelevantSort, setLastNonRelevantSort] = useState("newest") const [showAllWorkspaces, setShowAllWorkspaces] = useState(false) + const [showBackgroundTasks, setShowBackgroundTasks] = useState(true) useEffect(() => { if (searchQuery && sortOption !== "mostRelevant" && !lastNonRelevantSort) { @@ -28,8 +29,11 @@ export const useTaskSearch = () => { if (!showAllWorkspaces) { tasks = tasks.filter((item) => item.workspace === cwd) } + if (!showBackgroundTasks) { + tasks = tasks.filter((item) => !item.background) + } return tasks - }, [taskHistory, showAllWorkspaces, cwd]) + }, [taskHistory, showAllWorkspaces, showBackgroundTasks, cwd]) const fzf = useMemo(() => { return new Fzf(presentableTasks, { @@ -88,5 +92,7 @@ export const useTaskSearch = () => { setLastNonRelevantSort, showAllWorkspaces, setShowAllWorkspaces, + showBackgroundTasks, + setShowBackgroundTasks, } } diff --git a/webview-ui/src/i18n/locales/ca/history.json b/webview-ui/src/i18n/locales/ca/history.json index ab1bba7582e..7c0ced7e5f2 100644 --- a/webview-ui/src/i18n/locales/ca/history.json +++ b/webview-ui/src/i18n/locales/ca/history.json @@ -54,5 +54,14 @@ "subtaskTag": "Subtasca", "deleteWithSubtasks": "Això també eliminarà {{count}} subtasca(s). Estàs segur?", "expandSubtasks": "Expandir subtasques", - "collapseSubtasks": "Contreure subtasques" + "collapseSubtasks": "Contreure subtasques", + "backgroundTag": "Segon pla", + "interruptedTag": "Interrompuda", + "showBackgroundTasks": "Mostrar tasques en segon pla", + "hideBackgroundTasks": "Amagar tasques en segon pla", + "filter": { + "prefix": "Filtre:", + "all": "Totes les tasques", + "foregroundOnly": "Només primer pla" + } } diff --git a/webview-ui/src/i18n/locales/de/history.json b/webview-ui/src/i18n/locales/de/history.json index 46064d6e2ea..2006bf2645d 100644 --- a/webview-ui/src/i18n/locales/de/history.json +++ b/webview-ui/src/i18n/locales/de/history.json @@ -54,5 +54,14 @@ "subtaskTag": "Teilaufgabe", "deleteWithSubtasks": "Dies löscht auch {{count}} Teilaufgabe(n). Bist du sicher?", "expandSubtasks": "Teilaufgaben erweitern", - "collapseSubtasks": "Teilaufgaben einklappen" + "collapseSubtasks": "Teilaufgaben einklappen", + "backgroundTag": "Hintergrund", + "interruptedTag": "Unterbrochen", + "showBackgroundTasks": "Hintergrundaufgaben anzeigen", + "hideBackgroundTasks": "Hintergrundaufgaben ausblenden", + "filter": { + "prefix": "Filter:", + "all": "Alle Aufgaben", + "foregroundOnly": "Nur Vordergrund" + } } diff --git a/webview-ui/src/i18n/locales/en/history.json b/webview-ui/src/i18n/locales/en/history.json index 85174890e14..6d1d54606f1 100644 --- a/webview-ui/src/i18n/locales/en/history.json +++ b/webview-ui/src/i18n/locales/en/history.json @@ -47,5 +47,14 @@ "subtaskTag": "Subtask", "deleteWithSubtasks": "This will also delete {{count}} subtask(s). Are you sure?", "expandSubtasks": "Expand subtasks", - "collapseSubtasks": "Collapse subtasks" + "collapseSubtasks": "Collapse subtasks", + "backgroundTag": "Background", + "interruptedTag": "Interrupted", + "showBackgroundTasks": "Show background tasks", + "hideBackgroundTasks": "Hide background tasks", + "filter": { + "prefix": "Filter:", + "all": "All Tasks", + "foregroundOnly": "Foreground Only" + } } diff --git a/webview-ui/src/i18n/locales/es/history.json b/webview-ui/src/i18n/locales/es/history.json index 820f003d402..f05bf529004 100644 --- a/webview-ui/src/i18n/locales/es/history.json +++ b/webview-ui/src/i18n/locales/es/history.json @@ -54,5 +54,14 @@ "subtaskTag": "Subtarea", "deleteWithSubtasks": "Esto también eliminará {{count}} subtarea(s). ¿Estás seguro?", "expandSubtasks": "Expandir subtareas", - "collapseSubtasks": "Contraer subtareas" + "collapseSubtasks": "Contraer subtareas", + "backgroundTag": "Segundo plano", + "interruptedTag": "Interrumpida", + "showBackgroundTasks": "Mostrar tareas en segundo plano", + "hideBackgroundTasks": "Ocultar tareas en segundo plano", + "filter": { + "prefix": "Filtro:", + "all": "Todas las tareas", + "foregroundOnly": "Solo primer plano" + } } diff --git a/webview-ui/src/i18n/locales/fr/history.json b/webview-ui/src/i18n/locales/fr/history.json index d84cfcb190a..eaf219e626c 100644 --- a/webview-ui/src/i18n/locales/fr/history.json +++ b/webview-ui/src/i18n/locales/fr/history.json @@ -54,5 +54,14 @@ "subtaskTag": "Sous-tâche", "deleteWithSubtasks": "Cela supprimera aussi {{count}} sous-tâche(s). Êtes-vous sûr ?", "expandSubtasks": "Développer les sous-tâches", - "collapseSubtasks": "Réduire les sous-tâches" + "collapseSubtasks": "Réduire les sous-tâches", + "backgroundTag": "Arrière-plan", + "interruptedTag": "Interrompue", + "showBackgroundTasks": "Afficher les tâches en arrière-plan", + "hideBackgroundTasks": "Masquer les tâches en arrière-plan", + "filter": { + "prefix": "Filtre :", + "all": "Toutes les tâches", + "foregroundOnly": "Premier plan uniquement" + } } diff --git a/webview-ui/src/i18n/locales/hi/history.json b/webview-ui/src/i18n/locales/hi/history.json index 0d4cb40dd9e..81eea38e7ce 100644 --- a/webview-ui/src/i18n/locales/hi/history.json +++ b/webview-ui/src/i18n/locales/hi/history.json @@ -47,5 +47,14 @@ "subtaskTag": "उप-कार्य", "deleteWithSubtasks": "यह {{count}} उप-कार्य(कों) को भी हटा देगा। क्या आप निश्चित हैं?", "expandSubtasks": "उप-कार्य विस्तारित करें", - "collapseSubtasks": "उप-कार्य संपीड़ित करें" + "collapseSubtasks": "उप-कार्य संपीड़ित करें", + "backgroundTag": "बैकग्राउंड", + "interruptedTag": "बाधित", + "showBackgroundTasks": "बैकग्राउंड टास्क दिखाएं", + "hideBackgroundTasks": "बैकग्राउंड टास्क छुपाएं", + "filter": { + "prefix": "फ़िल्टर:", + "all": "सभी टास्क", + "foregroundOnly": "केवल फ़ोरग्राउंड" + } } diff --git a/webview-ui/src/i18n/locales/id/history.json b/webview-ui/src/i18n/locales/id/history.json index 7796061107e..5ae44f939f1 100644 --- a/webview-ui/src/i18n/locales/id/history.json +++ b/webview-ui/src/i18n/locales/id/history.json @@ -56,5 +56,14 @@ "subtaskTag": "Subtask", "deleteWithSubtasks": "Ini juga akan menghapus {{count}} subtask. Apakah Anda yakin?", "expandSubtasks": "Perluas subtask", - "collapseSubtasks": "Tutup subtask" + "collapseSubtasks": "Tutup subtask", + "backgroundTag": "Latar belakang", + "interruptedTag": "Terinterupsi", + "showBackgroundTasks": "Tampilkan tugas latar belakang", + "hideBackgroundTasks": "Sembunyikan tugas latar belakang", + "filter": { + "prefix": "Filter:", + "all": "Semua Tugas", + "foregroundOnly": "Hanya Latar Depan" + } } diff --git a/webview-ui/src/i18n/locales/it/history.json b/webview-ui/src/i18n/locales/it/history.json index aa728ef8f60..340e7d59ea8 100644 --- a/webview-ui/src/i18n/locales/it/history.json +++ b/webview-ui/src/i18n/locales/it/history.json @@ -47,5 +47,14 @@ "subtaskTag": "Sottoattività", "deleteWithSubtasks": "Questo eliminerà anche {{count}} sottoattività. Sei sicuro?", "expandSubtasks": "Espandi sottoattività", - "collapseSubtasks": "Comprimi sottoattività" + "collapseSubtasks": "Comprimi sottoattività", + "backgroundTag": "Background", + "interruptedTag": "Interrotto", + "showBackgroundTasks": "Mostra attività in background", + "hideBackgroundTasks": "Nascondi attività in background", + "filter": { + "prefix": "Filtro:", + "all": "Tutte le attività", + "foregroundOnly": "Solo primo piano" + } } diff --git a/webview-ui/src/i18n/locales/ja/history.json b/webview-ui/src/i18n/locales/ja/history.json index b73baa3a763..6d47b2d217a 100644 --- a/webview-ui/src/i18n/locales/ja/history.json +++ b/webview-ui/src/i18n/locales/ja/history.json @@ -47,5 +47,14 @@ "subtaskTag": "サブタスク", "deleteWithSubtasks": "これにより {{count}} サブタスクも削除されます。よろしいですか?", "expandSubtasks": "サブタスクを展開", - "collapseSubtasks": "サブタスクを折りたたむ" + "collapseSubtasks": "サブタスクを折りたたむ", + "backgroundTag": "バックグラウンド", + "interruptedTag": "中断", + "showBackgroundTasks": "バックグラウンドタスクを表示", + "hideBackgroundTasks": "バックグラウンドタスクを非表示", + "filter": { + "prefix": "フィルター:", + "all": "すべてのタスク", + "foregroundOnly": "フォアグラウンドのみ" + } } diff --git a/webview-ui/src/i18n/locales/ko/history.json b/webview-ui/src/i18n/locales/ko/history.json index 0363feaaffb..3b9c3e88f90 100644 --- a/webview-ui/src/i18n/locales/ko/history.json +++ b/webview-ui/src/i18n/locales/ko/history.json @@ -47,5 +47,14 @@ "subtaskTag": "부분작업", "deleteWithSubtasks": "이는 {{count}} 부분작업도 삭제합니다. 확실하십니까?", "expandSubtasks": "부분작업 확장", - "collapseSubtasks": "부분작업 축소" + "collapseSubtasks": "부분작업 축소", + "backgroundTag": "백그라운드", + "interruptedTag": "중단됨", + "showBackgroundTasks": "백그라운드 작업 표시", + "hideBackgroundTasks": "백그라운드 작업 숨기기", + "filter": { + "prefix": "필터:", + "all": "모든 작업", + "foregroundOnly": "포그라운드만" + } } diff --git a/webview-ui/src/i18n/locales/nl/history.json b/webview-ui/src/i18n/locales/nl/history.json index 012059ed047..cd769522e5f 100644 --- a/webview-ui/src/i18n/locales/nl/history.json +++ b/webview-ui/src/i18n/locales/nl/history.json @@ -47,5 +47,14 @@ "subtaskTag": "Subtaak", "deleteWithSubtasks": "Dit zal ook {{count}} subtaak(en) verwijderen. Weet je het zeker?", "expandSubtasks": "Subtaken uitvouwen", - "collapseSubtasks": "Subtaken samenvouwen" + "collapseSubtasks": "Subtaken samenvouwen", + "backgroundTag": "Achtergrond", + "interruptedTag": "Onderbroken", + "showBackgroundTasks": "Achtergrondtaken weergeven", + "hideBackgroundTasks": "Achtergrondtaken verbergen", + "filter": { + "prefix": "Filter:", + "all": "Alle taken", + "foregroundOnly": "Alleen voorgrond" + } } diff --git a/webview-ui/src/i18n/locales/pl/history.json b/webview-ui/src/i18n/locales/pl/history.json index 7ec4b40d8f5..859f3ce9b98 100644 --- a/webview-ui/src/i18n/locales/pl/history.json +++ b/webview-ui/src/i18n/locales/pl/history.json @@ -47,5 +47,14 @@ "subtaskTag": "Podzadanie", "deleteWithSubtasks": "Spowoduje to usunięcie {{count}} podzadania(ń). Jesteś pewny?", "expandSubtasks": "Rozwiń podzadania", - "collapseSubtasks": "Zwiń podzadania" + "collapseSubtasks": "Zwiń podzadania", + "backgroundTag": "W tle", + "interruptedTag": "Przerwane", + "showBackgroundTasks": "Pokaż zadania w tle", + "hideBackgroundTasks": "Ukryj zadania w tle", + "filter": { + "prefix": "Filtr:", + "all": "Wszystkie zadania", + "foregroundOnly": "Tylko na pierwszym planie" + } } diff --git a/webview-ui/src/i18n/locales/pt-BR/history.json b/webview-ui/src/i18n/locales/pt-BR/history.json index 7966df1f463..202df2173c8 100644 --- a/webview-ui/src/i18n/locales/pt-BR/history.json +++ b/webview-ui/src/i18n/locales/pt-BR/history.json @@ -47,5 +47,14 @@ "subtaskTag": "Subtarefa", "deleteWithSubtasks": "Isso também excluirá {{count}} subtarefa(s). Tem certeza?", "expandSubtasks": "Expandir subtarefas", - "collapseSubtasks": "Recolher subtarefas" + "collapseSubtasks": "Recolher subtarefas", + "backgroundTag": "Segundo plano", + "interruptedTag": "Interrompida", + "showBackgroundTasks": "Mostrar tarefas em segundo plano", + "hideBackgroundTasks": "Ocultar tarefas em segundo plano", + "filter": { + "prefix": "Filtro:", + "all": "Todas as tarefas", + "foregroundOnly": "Somente primeiro plano" + } } diff --git a/webview-ui/src/i18n/locales/ru/history.json b/webview-ui/src/i18n/locales/ru/history.json index 7852362348b..25214a17d74 100644 --- a/webview-ui/src/i18n/locales/ru/history.json +++ b/webview-ui/src/i18n/locales/ru/history.json @@ -47,5 +47,14 @@ "subtaskTag": "Подзадача", "deleteWithSubtasks": "Это также удалит {{count}} подзадачу(и). Вы уверены?", "expandSubtasks": "Развернуть подзадачи", - "collapseSubtasks": "Свернуть подзадачи" + "collapseSubtasks": "Свернуть подзадачи", + "backgroundTag": "Фоновая", + "interruptedTag": "Прервана", + "showBackgroundTasks": "Показать фоновые задачи", + "hideBackgroundTasks": "Скрыть фоновые задачи", + "filter": { + "prefix": "Фильтр:", + "all": "Все задачи", + "foregroundOnly": "Только активные" + } } diff --git a/webview-ui/src/i18n/locales/tr/history.json b/webview-ui/src/i18n/locales/tr/history.json index fb7b6c68320..183ccbce310 100644 --- a/webview-ui/src/i18n/locales/tr/history.json +++ b/webview-ui/src/i18n/locales/tr/history.json @@ -47,5 +47,14 @@ "subtaskTag": "Alt görev", "deleteWithSubtasks": "Bu, {{count}} alt görev(i) de silecektir. Emin misiniz?", "expandSubtasks": "Alt görevleri genişlet", - "collapseSubtasks": "Alt görevleri daralt" + "collapseSubtasks": "Alt görevleri daralt", + "backgroundTag": "Arka plan", + "interruptedTag": "Kesintiye uğradı", + "showBackgroundTasks": "Arka plan görevlerini göster", + "hideBackgroundTasks": "Arka plan görevlerini gizle", + "filter": { + "prefix": "Filtre:", + "all": "Tüm Görevler", + "foregroundOnly": "Yalnızca Ön Plan" + } } diff --git a/webview-ui/src/i18n/locales/vi/history.json b/webview-ui/src/i18n/locales/vi/history.json index 779953e5406..22db4c20bc5 100644 --- a/webview-ui/src/i18n/locales/vi/history.json +++ b/webview-ui/src/i18n/locales/vi/history.json @@ -47,5 +47,14 @@ "subtaskTag": "Tác vụ con", "deleteWithSubtasks": "Điều này cũng sẽ xóa {{count}} tác vụ con. Bạn có chắc không?", "expandSubtasks": "Mở rộng tác vụ con", - "collapseSubtasks": "Thu gọn tác vụ con" + "collapseSubtasks": "Thu gọn tác vụ con", + "backgroundTag": "Nền", + "interruptedTag": "Bị gián đoạn", + "showBackgroundTasks": "Hiển thị tác vụ nền", + "hideBackgroundTasks": "Ẩn tác vụ nền", + "filter": { + "prefix": "Bộ lọc:", + "all": "Tất cả tác vụ", + "foregroundOnly": "Chỉ tiền cảnh" + } } diff --git a/webview-ui/src/i18n/locales/zh-CN/history.json b/webview-ui/src/i18n/locales/zh-CN/history.json index 20a73240ea9..32e5a7bb472 100644 --- a/webview-ui/src/i18n/locales/zh-CN/history.json +++ b/webview-ui/src/i18n/locales/zh-CN/history.json @@ -47,5 +47,14 @@ "subtaskTag": "子任务", "deleteWithSubtasks": "这也将删除 {{count}} 个子任务。您确定吗?", "expandSubtasks": "展开子任务", - "collapseSubtasks": "收起子任务" + "collapseSubtasks": "收起子任务", + "backgroundTag": "后台", + "interruptedTag": "已中断", + "showBackgroundTasks": "显示后台任务", + "hideBackgroundTasks": "隐藏后台任务", + "filter": { + "prefix": "筛选:", + "all": "所有任务", + "foregroundOnly": "仅前台" + } } diff --git a/webview-ui/src/i18n/locales/zh-TW/history.json b/webview-ui/src/i18n/locales/zh-TW/history.json index 1e12190a69b..6b5bc577641 100644 --- a/webview-ui/src/i18n/locales/zh-TW/history.json +++ b/webview-ui/src/i18n/locales/zh-TW/history.json @@ -47,5 +47,14 @@ "subtaskTag": "子工作", "deleteWithSubtasks": "這也將刪除 {{count}} 個子工作。您確定嗎?", "expandSubtasks": "展開子工作", - "collapseSubtasks": "收起子工作" + "collapseSubtasks": "收起子工作", + "backgroundTag": "背景", + "interruptedTag": "已中斷", + "showBackgroundTasks": "顯示背景工作", + "hideBackgroundTasks": "隱藏背景工作", + "filter": { + "prefix": "篩選:", + "all": "所有工作", + "foregroundOnly": "僅前景" + } }