diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 67ed1ebd7c..0291b01f8f 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "agent-orchestrator",
- "version": "0.0.0",
+ "version": "0.10.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "agent-orchestrator",
- "version": "0.0.0",
+ "version": "0.10.0",
"license": "MIT",
"dependencies": {
"@radix-ui/react-dialog": "^1.1.16",
@@ -25,12 +25,14 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"electron-updater": "^6.8.9",
+ "i18next": "^26.3.4",
"lucide-react": "^1.17.0",
"openapi-fetch": "^0.17.0",
"posthog-js": "^1.390.2",
"radix-ui": "^1.5.0",
"react": "^19.2.7",
"react-dom": "^19.2.7",
+ "react-i18next": "^17.0.8",
"react-resizable-panels": "^4.11.2",
"tailwind-merge": "^3.6.0",
"zustand": "^5.0.14"
@@ -338,7 +340,6 @@
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
"integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -10629,6 +10630,15 @@
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
}
},
+ "node_modules/html-parse-stringify": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
+ "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
+ "license": "MIT",
+ "dependencies": {
+ "void-elements": "3.1.0"
+ }
+ },
"node_modules/http-cache-semantics": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz",
@@ -10688,6 +10698,34 @@
"ms": "^2.0.0"
}
},
+ "node_modules/i18next": {
+ "version": "26.3.4",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-26.3.4.tgz",
+ "integrity": "sha512-pa7m0d7pBDqGHZxljT+WPFeyFgQ7P7SciPPo1tTqYuO0z4sqADYhwnBESmmGp/wEof1inwdls/k8ZgTg8rxFHA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://www.locize.com/i18next"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.locize.com"
+ }
+ ],
+ "license": "MIT",
+ "peerDependencies": {
+ "typescript": "^5 || ^6"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -13538,6 +13576,33 @@
"react": "^19.2.7"
}
},
+ "node_modules/react-i18next": {
+ "version": "17.0.8",
+ "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-17.0.8.tgz",
+ "integrity": "sha512-0ooKbGLU8JXhe1zwpQUWIeXSgLPOfwJmgheWRIUpcoA0CpyabpGhayjdG+/eA5esC1AQ8h2jWpXjJfzQzeDOCw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.29.2",
+ "html-parse-stringify": "^3.0.1",
+ "use-sync-external-store": "^1.6.0"
+ },
+ "peerDependencies": {
+ "i18next": ">= 26.2.0",
+ "react": ">= 16.8.0",
+ "typescript": "^5 || ^6"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
@@ -14953,7 +15018,7 @@
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
- "dev": true,
+ "devOptional": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
@@ -15402,6 +15467,15 @@
}
}
},
+ "node_modules/void-elements": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
+ "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/w3c-xmlserializer": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index a70a05a573..3e39fd1e10 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -70,12 +70,14 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"electron-updater": "^6.8.9",
+ "i18next": "^26.3.4",
"lucide-react": "^1.17.0",
"openapi-fetch": "^0.17.0",
"posthog-js": "^1.390.2",
"radix-ui": "^1.5.0",
"react": "^19.2.7",
"react-dom": "^19.2.7",
+ "react-i18next": "^17.0.8",
"react-resizable-panels": "^4.11.2",
"tailwind-merge": "^3.6.0",
"zustand": "^5.0.14"
diff --git a/frontend/src/renderer/components/SessionsBoard.tsx b/frontend/src/renderer/components/SessionsBoard.tsx
index 0f0d20b14b..64a101edae 100644
--- a/frontend/src/renderer/components/SessionsBoard.tsx
+++ b/frontend/src/renderer/components/SessionsBoard.tsx
@@ -22,6 +22,7 @@ import { restartProjectOrchestrator } from "../lib/restart-orchestrator";
import { prBrowserUrl, sessionPRDisplaySummaries } from "../lib/pr-display";
import { cn } from "../lib/utils";
import { useUiStore } from "../stores/ui-store";
+import { useTranslation } from "react-i18next";
type SessionsBoardProps = {
/** When set, the board shows only this project's sessions. */
@@ -75,6 +76,7 @@ const COLUMNS: Column[] = [
];
export function SessionsBoard({ projectId }: SessionsBoardProps) {
+ const { t } = useTranslation();
const navigate = useNavigate();
const queryClient = useQueryClient();
const workspaceQuery = useWorkspaceQuery();
@@ -160,7 +162,7 @@ export function SessionsBoard({ projectId }: SessionsBoardProps) {
// Never fail silently: the daemon's message (e.g. a worktree/branch
// conflict) is the only actionable signal the user gets.
console.error("Failed to spawn orchestrator:", err);
- setSpawnError(err instanceof Error ? err.message : "Could not spawn orchestrator");
+ setSpawnError(err instanceof Error ? err.message : t("board.errors.spawnFailed"));
} finally {
setIsSpawning(false);
}
@@ -194,17 +196,17 @@ export function SessionsBoard({ projectId }: SessionsBoardProps) {
)}
>
) : undefined;
@@ -229,8 +231,8 @@ export function SessionsBoard({ projectId }: SessionsBoardProps) {
(review feedback on #2432). */}
{!showWelcome && (
Could not load sessions.
+{t("board.errors.loadSessions")}
) : showWelcome ? (