From ade036e215b506476cd1f128ccb95f9761876fbb Mon Sep 17 00:00:00 2001
From: johnnyshields <27655+johnnyshields@users.noreply.github.com>
Date: Fri, 10 Apr 2026 14:11:14 +0900
Subject: [PATCH 1/5] Cleanup usage of I18n function
---
.../app-settings/authorized-folders-panel.tsx | 4 +-
apps/app/src/app/app.tsx | 26 +-
.../app/bundles/skill-destination-modal.tsx | 53 ++--
apps/app/src/app/bundles/store.ts | 2 +-
apps/app/src/app/components/add-mcp-modal.tsx | 44 ++-
.../components/control-chrome-setup-modal.tsx | 37 ++-
.../src/app/components/den-settings-panel.tsx | 273 +++++++++---------
.../app/src/app/components/mcp-auth-modal.tsx | 173 ++++++-----
.../src/app/components/model-picker-modal.tsx | 23 +-
.../app/src/app/components/question-modal.tsx | 2 +-
.../app/components/rename-session-modal.tsx | 15 +-
.../app/components/rename-workspace-modal.tsx | 15 +-
apps/app/src/app/components/reset-modal.tsx | 21 +-
.../src/app/components/session/composer.tsx | 2 +-
.../app/components/session/message-list.tsx | 22 +-
.../session/workspace-session-list.tsx | 2 +-
apps/app/src/app/components/status-bar.tsx | 6 +-
.../app/connections/openwork-server-store.ts | 8 +-
apps/app/src/app/connections/store.ts | 33 +--
apps/app/src/app/context/extensions.ts | 145 +++++-----
apps/app/src/app/context/global-sync.tsx | 4 +-
apps/app/src/app/context/model-config.ts | 18 +-
apps/app/src/app/context/providers/store.ts | 6 +-
apps/app/src/app/context/session.ts | 16 +-
apps/app/src/app/context/workspace.ts | 56 ++--
apps/app/src/app/lib/model-behavior.ts | 2 +-
apps/app/src/app/pages/automations.tsx | 24 +-
apps/app/src/app/pages/extensions.tsx | 4 +-
apps/app/src/app/pages/identities.tsx | 18 +-
apps/app/src/app/pages/mcp.tsx | 103 ++++---
apps/app/src/app/pages/session.tsx | 26 +-
apps/app/src/app/pages/settings.tsx | 118 ++++----
apps/app/src/app/pages/skills.tsx | 241 ++++++++--------
apps/app/src/app/session/actions-store.ts | 26 +-
apps/app/src/app/session/share-workspace.ts | 2 +-
apps/app/src/app/shell/deep-links.ts | 12 +-
apps/app/src/app/shell/settings-shell.tsx | 10 +-
apps/app/src/app/utils/index.ts | 6 +-
.../create-remote-workspace-modal.tsx | 13 +-
.../app/workspace/create-workspace-modal.tsx | 89 +++---
apps/app/src/i18n/index.ts | 7 +-
.../react/session/session-surface.react.tsx | 2 +-
apps/app/src/react/session/session-sync.ts | 2 +-
apps/app/src/react/session/usechat-adapter.ts | 2 +-
44 files changed, 845 insertions(+), 868 deletions(-)
diff --git a/apps/app/src/app/app-settings/authorized-folders-panel.tsx b/apps/app/src/app/app-settings/authorized-folders-panel.tsx
index 66b1554fa..6c840d9d5 100644
--- a/apps/app/src/app/app-settings/authorized-folders-panel.tsx
+++ b/apps/app/src/app/app-settings/authorized-folders-panel.tsx
@@ -89,7 +89,7 @@ const buildAuthorizedFoldersStatus = (preservedCount: number, action?: string) =
preservedCount > 0
? preservedCount === 1
? t("context_panel.preserving_entry")
- : t("context_panel.preserving_entries", undefined, { count: preservedCount })
+ : t("context_panel.preserving_entries", { count: preservedCount })
: null;
if (action && preservedLabel) return `${action} ${preservedLabel}`;
return action ?? preservedLabel;
@@ -406,7 +406,7 @@ export default function AuthorizedFoldersPanel(props: AuthorizedFoldersPanelProp
authorizedFoldersSaving() ||
!canWriteConfig()
}
- aria-label={t("context_panel.remove_folder", undefined, { name: folderName })}
+ aria-label={t("context_panel.remove_folder", { name: folderName })}
>
diff --git a/apps/app/src/app/app.tsx b/apps/app/src/app/app.tsx
index 7a8a459a9..ded567c79 100644
--- a/apps/app/src/app/app.tsx
+++ b/apps/app/src/app/app.tsx
@@ -1985,16 +1985,16 @@ export default function App() {
});
const headerStatus = createMemo(() => {
- if (!client() || !headerConnectedVersion()) return t("status.disconnected", currentLocale());
- const bits = [`${t("status.connected", currentLocale())} · ${headerConnectedVersion()}`];
- if (sseConnected()) bits.push(t("status.live", currentLocale()));
+ if (!client() || !headerConnectedVersion()) return t("status.disconnected");
+ const bits = [`${t("status.connected")} · ${headerConnectedVersion()}`];
+ if (sseConnected()) bits.push(t("status.live"));
return bits.join(" · ");
});
const busyHint = createMemo(() => {
if (!busy() || !busyLabel()) return null;
const seconds = busySeconds();
- const label = t(busyLabel()!, currentLocale());
+ const label = t(busyLabel()!);
return seconds > 0 ? `${label} · ${seconds}s` : label;
});
@@ -2572,17 +2572,17 @@ export default function App() {
return !doctor?.ready;
})()}
workerDisabledReason={(() => {
- if (!isTauriRuntime()) return t("app.error.tauri_required", currentLocale());
+ if (!isTauriRuntime()) return t("app.error.tauri_required");
if (workspaceStore.sandboxDoctorBusy?.()) {
- return t("dashboard.sandbox_checking_docker", currentLocale());
+ return t("dashboard.sandbox_checking_docker");
}
const doctor = workspaceStore.sandboxDoctorResult?.();
if (!doctor || doctor.ready) return null;
const message = doctor?.error?.trim();
- return message || t("dashboard.sandbox_get_ready_desc", currentLocale());
+ return message || t("dashboard.sandbox_get_ready_desc");
})()}
- workerCtaLabel={t("dashboard.sandbox_get_ready_action", currentLocale())}
- workerCtaDescription={t("dashboard.sandbox_get_ready_desc", currentLocale())}
+ workerCtaLabel={t("dashboard.sandbox_get_ready_action")}
+ workerCtaDescription={t("dashboard.sandbox_get_ready_desc")}
onWorkerCta={async () => {
const url = "https://www.docker.com/products/docker-desktop/";
if (isTauriRuntime()) {
@@ -2592,7 +2592,7 @@ export default function App() {
window.open(url, "_blank", "noopener,noreferrer");
}
}}
- workerRetryLabel={t("common.retry", currentLocale())}
+ workerRetryLabel={t("common.retry")}
workerDebugLines={(() => {
const doctor = workspaceStore.sandboxDoctorResult?.();
const lines: string[] = [];
@@ -2718,9 +2718,9 @@ export default function App() {
initialValues={workspaceStore.editRemoteWorkspaceDefaults() ?? undefined}
submitting={busy() && busyLabel() === "status.connecting"}
error={workspaceStore.editRemoteWorkspaceError()}
- title={t("dashboard.edit_remote_workspace_title", currentLocale())}
- subtitle={t("dashboard.edit_remote_workspace_subtitle", currentLocale())}
- confirmLabel={t("dashboard.edit_remote_workspace_confirm", currentLocale())}
+ title={t("dashboard.edit_remote_workspace_title")}
+ subtitle={t("dashboard.edit_remote_workspace_subtitle")}
+ confirmLabel={t("dashboard.edit_remote_workspace_confirm")}
/>
diff --git a/apps/app/src/app/bundles/skill-destination-modal.tsx b/apps/app/src/app/bundles/skill-destination-modal.tsx
index b68526f12..1600bbefa 100644
--- a/apps/app/src/app/bundles/skill-destination-modal.tsx
+++ b/apps/app/src/app/bundles/skill-destination-modal.tsx
@@ -2,7 +2,7 @@ import { For, Show, createEffect, createMemo, createSignal } from "solid-js";
import { CheckCircle2, Folder, FolderPlus, Globe, Loader2, Sparkles, X } from "lucide-solid";
import type { WorkspaceInfo } from "../lib/tauri";
-import { t, currentLocale } from "../../i18n";
+import { t } from "../../i18n";
import Button from "../components/button";
@@ -23,7 +23,6 @@ export default function SkillDestinationModal(props: {
onCreateWorker?: () => void;
onConnectRemote?: () => void;
}) {
- const translate = (key: string) => t(key, currentLocale());
const [selectedWorkspaceId, setSelectedWorkspaceId] = createSignal(null);
const displayName = (workspace: WorkspaceInfo) =>
@@ -37,14 +36,14 @@ export default function SkillDestinationModal(props: {
const subtitle = (workspace: WorkspaceInfo) => {
if (workspace.workspaceType === "local") {
- return workspace.path?.trim() || translate("share_skill_destination.local_badge");
+ return workspace.path?.trim() || t("share_skill_destination.local_badge");
}
return (
workspace.directory?.trim() ||
workspace.openworkHostUrl?.trim() ||
workspace.baseUrl?.trim() ||
workspace.path?.trim() ||
- translate("share_skill_destination.remote_badge")
+ t("share_skill_destination.remote_badge")
);
};
@@ -55,12 +54,12 @@ export default function SkillDestinationModal(props: {
Boolean(workspace.sandboxRunId?.trim()) ||
Boolean(workspace.sandboxContainerName?.trim()))
) {
- return translate("share_skill_destination.sandbox_badge");
+ return t("share_skill_destination.sandbox_badge");
}
if (workspace.workspaceType === "remote") {
- return translate("share_skill_destination.remote_badge");
+ return t("share_skill_destination.remote_badge");
}
- return translate("share_skill_destination.local_badge");
+ return t("share_skill_destination.local_badge");
};
const footerBusy = () => Boolean(props.busyWorkspaceId?.trim());
@@ -106,7 +105,7 @@ export default function SkillDestinationModal(props: {
- {translate("share_skill_destination.skill_label")}
+ {t("share_skill_destination.skill_label")}
@@ -115,17 +114,17 @@ export default function SkillDestinationModal(props: {
- {translate("share_skill_destination.skill_label")}
+ {t("share_skill_destination.skill_label")}
- {props.skill?.name ?? translate("share_skill_destination.fallback_skill_name")}
+ {props.skill?.name ?? t("share_skill_destination.fallback_skill_name")}
{props.skill?.description?.trim()}
- {translate("share_skill_destination.trigger_label")}
+ {t("share_skill_destination.trigger_label")}
{props.skill?.trigger?.trim()}
@@ -133,8 +132,8 @@ export default function SkillDestinationModal(props: {
-
{translate("share_skill_destination.title")}
-
{translate("share_skill_destination.subtitle")}
+
{t("share_skill_destination.title")}
+
{t("share_skill_destination.subtitle")}
@@ -142,7 +141,7 @@ export default function SkillDestinationModal(props: {
onClick={props.onClose}
disabled={footerBusy()}
class={`rounded-full p-2 text-gray-9 transition hover:bg-gray-2 hover:text-gray-12 ${footerBusy() ? "cursor-not-allowed opacity-50" : ""}`.trim()}
- aria-label={translate("common.close")}
+ aria-label={t("common.close")}
>
@@ -152,7 +151,7 @@ export default function SkillDestinationModal(props: {
-
{translate("share_skill_destination.existing_workers")}
+
{t("share_skill_destination.existing_workers")}
0}>
{props.workspaces.length}
@@ -162,7 +161,7 @@ export default function SkillDestinationModal(props: {
when={props.workspaces.length > 0}
fallback={
- {translate("share_skill_destination.no_workers")}
+ {t("share_skill_destination.no_workers")}
}
>
@@ -196,7 +195,7 @@ export default function SkillDestinationModal(props: {
{displayName(workspace)}
- {translate("share_skill_destination.current_badge")}
+ {t("share_skill_destination.current_badge")}
@@ -204,14 +203,14 @@ export default function SkillDestinationModal(props: {
- {translate("share_skill_destination.selected_badge")}
+ {t("share_skill_destination.selected_badge")}
{subtitle(workspace)}
- {translate("share_skill_destination.selected_hint")}
+ {t("share_skill_destination.selected_hint")}
@@ -231,7 +230,7 @@ export default function SkillDestinationModal(props: {
-
{translate("share_skill_destination.more_options")}
+
{t("share_skill_destination.more_options")}
-
{translate("share_skill_destination.create_worker")}
-
{translate("share_skill_destination.create_worker_hint")}
+
{t("share_skill_destination.create_worker")}
+
{t("share_skill_destination.create_worker_hint")}
@@ -264,8 +263,8 @@ export default function SkillDestinationModal(props: {
-
{translate("share_skill_destination.connect_remote")}
-
{translate("share_skill_destination.connect_remote_hint")}
+
{t("share_skill_destination.connect_remote")}
+
{t("share_skill_destination.connect_remote_hint")}
@@ -289,13 +288,13 @@ export default function SkillDestinationModal(props: {
diff --git a/apps/app/src/app/bundles/store.ts b/apps/app/src/app/bundles/store.ts
index 0d8a451fa..77afba2c8 100644
--- a/apps/app/src/app/bundles/store.ts
+++ b/apps/app/src/app/bundles/store.ts
@@ -639,7 +639,7 @@ export function createBundlesStore(options: {
b.path?.trim() ||
b.baseUrl?.trim() ||
"";
- return aLabel.localeCompare(bLabel, undefined, { sensitivity: "base" });
+ return aLabel.localeCompare(bLabel, { sensitivity: "base" });
});
});
diff --git a/apps/app/src/app/components/add-mcp-modal.tsx b/apps/app/src/app/components/add-mcp-modal.tsx
index 9301c0e8e..318c37f8e 100644
--- a/apps/app/src/app/components/add-mcp-modal.tsx
+++ b/apps/app/src/app/components/add-mcp-modal.tsx
@@ -15,8 +15,6 @@ export type AddMcpModalProps = {
};
export default function AddMcpModal(props: AddMcpModalProps) {
- const tr = (key: string) => t(key, props.language);
-
const [name, setName] = createSignal("");
const [serverType, setServerType] = createSignal<"remote" | "local">("remote");
const [url, setUrl] = createSignal("");
@@ -46,7 +44,7 @@ export default function AddMcpModal(props: AddMcpModalProps) {
const trimmedName = name().trim();
if (!trimmedName) {
- setError(tr("mcp.name_required"));
+ setError(t("mcp.name_required"));
return;
}
@@ -55,7 +53,7 @@ export default function AddMcpModal(props: AddMcpModalProps) {
if (serverType() === "remote") {
const trimmedUrl = url().trim();
if (!trimmedUrl) {
- setError(tr("mcp.url_or_command_required"));
+ setError(t("mcp.url_or_command_required"));
setSubmitting(false);
return;
}
@@ -74,7 +72,7 @@ export default function AddMcpModal(props: AddMcpModalProps) {
} else {
const trimmedCommand = command().trim();
if (!trimmedCommand) {
- setError(tr("mcp.url_or_command_required"));
+ setError(t("mcp.url_or_command_required"));
setSubmitting(false);
return;
}
@@ -111,9 +109,9 @@ export default function AddMcpModal(props: AddMcpModalProps) {
- {tr("mcp.add_modal_title")}
+ {t("mcp.add_modal_title")}
-
{tr("mcp.add_modal_subtitle")}
+
{t("mcp.add_modal_subtitle")}
- {tr("mcp.control_chrome_setup_title")}
+ {t("mcp.control_chrome_setup_title")}
- {tr("mcp.control_chrome_setup_subtitle")}
+ {t("mcp.control_chrome_setup_subtitle")}
@@ -48,7 +47,7 @@ export default function ControlChromeSetupModal(props: ControlChromeSetupModalPr
type="button"
class="rounded-xl p-2 text-gray-11 transition-colors hover:bg-gray-4 hover:text-gray-12"
onClick={props.onClose}
- aria-label={tr("common.cancel")}
+ aria-label={t("common.cancel")}
>
@@ -63,15 +62,15 @@ export default function ControlChromeSetupModal(props: ControlChromeSetupModalPr
- {tr("mcp.control_chrome_browser_title")}
+ {t("mcp.control_chrome_browser_title")}
- {tr("mcp.control_chrome_browser_hint")}
+ {t("mcp.control_chrome_browser_hint")}
- - 1. {tr("mcp.control_chrome_browser_step_one")}
- - 2. {tr("mcp.control_chrome_browser_step_two")}
- - 3. {tr("mcp.control_chrome_browser_step_three")}
+ - 1. {t("mcp.control_chrome_browser_step_one")}
+ - 2. {t("mcp.control_chrome_browser_step_two")}
+ - 3. {t("mcp.control_chrome_browser_step_three")}
- {tr("mcp.control_chrome_docs")}
+ {t("mcp.control_chrome_docs")}
@@ -93,10 +92,10 @@ export default function ControlChromeSetupModal(props: ControlChromeSetupModalPr
- {tr("mcp.control_chrome_profile_title")}
+ {t("mcp.control_chrome_profile_title")}
- {tr("mcp.control_chrome_profile_hint")}
+ {t("mcp.control_chrome_profile_hint")}
- {tr("mcp.control_chrome_toggle_label")}
+ {t("mcp.control_chrome_toggle_label")}
- {tr("mcp.control_chrome_toggle_hint")}
+ {t("mcp.control_chrome_toggle_hint")}
@@ -122,8 +121,8 @@ export default function ControlChromeSetupModal(props: ControlChromeSetupModalPr
{useExistingProfile()
- ? tr("mcp.control_chrome_toggle_on")
- : tr("mcp.control_chrome_toggle_off")}
+ ? t("mcp.control_chrome_toggle_on")
+ : t("mcp.control_chrome_toggle_off")}
@@ -132,13 +131,13 @@ export default function ControlChromeSetupModal(props: ControlChromeSetupModalPr
- {tr("mcp.auth.cancel")}
+ {t("mcp.auth.cancel")}
props.onSave(useExistingProfile())} disabled={props.busy}>
-
+
<>
- {props.mode === "edit" ? tr("mcp.control_chrome_save") : tr("mcp.control_chrome_connect")}
+ {props.mode === "edit" ? t("mcp.control_chrome_save") : t("mcp.control_chrome_connect")}
>
diff --git a/apps/app/src/app/components/den-settings-panel.tsx b/apps/app/src/app/components/den-settings-panel.tsx
index 5527443a3..29087e629 100644
--- a/apps/app/src/app/components/den-settings-panel.tsx
+++ b/apps/app/src/app/components/den-settings-panel.tsx
@@ -3,7 +3,7 @@ import { ArrowUpRight, Boxes, Brain, Cloud, KeyRound, LogOut, RefreshCcw, Server
import Button from "./button";
import TextInput from "./text-input";
-import { currentLocale, t } from "../../i18n";
+import { t } from "../../i18n";
import {
buildDenAuthUrl,
clearDenSession,
@@ -95,18 +95,18 @@ function workerStatusMeta(status: string, tr: (key: string) => string) {
const normalized = status.trim().toLowerCase();
switch (normalized) {
case "healthy":
- return { label: tr("dashboard.worker_status_ready"), tone: "ready" as const, canOpen: true };
+ return { label: t("dashboard.worker_status_ready"), tone: "ready" as const, canOpen: true };
case "provisioning":
- return { label: tr("dashboard.worker_status_starting"), tone: "warning" as const, canOpen: false };
+ return { label: t("dashboard.worker_status_starting"), tone: "warning" as const, canOpen: false };
case "failed":
- return { label: tr("dashboard.worker_status_attention"), tone: "error" as const, canOpen: false };
+ return { label: t("dashboard.worker_status_attention"), tone: "error" as const, canOpen: false };
case "stopped":
- return { label: tr("dashboard.worker_status_stopped"), tone: "neutral" as const, canOpen: false };
+ return { label: t("dashboard.worker_status_stopped"), tone: "neutral" as const, canOpen: false };
default:
return {
label: normalized
? `${normalized.slice(0, 1).toUpperCase()}${normalized.slice(1)}`
- : tr("dashboard.worker_status_unknown"),
+ : t("dashboard.worker_status_unknown"),
tone: "neutral" as const,
canOpen: normalized === "ready",
};
@@ -116,7 +116,6 @@ function workerStatusMeta(status: string, tr: (key: string) => string) {
export default function DenSettingsPanel(props: DenSettingsPanelProps) {
const platform = usePlatform();
const extensions = useExtensions();
- const tr = (key: string) => t(key, currentLocale());
const initial = readDenSettings();
const initialBaseUrl = initial.baseUrl || DEFAULT_DEN_BASE_URL;
@@ -171,7 +170,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
createDenClient({ baseUrl: baseUrl(), token: authToken() }),
);
const isSignedIn = createMemo(() => Boolean(user() && authToken().trim()));
- const activeOrgName = createMemo(() => activeOrg()?.name || tr("den.no_org_selected"));
+ const activeOrgName = createMemo(() => activeOrg()?.name || t("den.no_org_selected"));
const templateCacheSnapshot = createMemo(() =>
readDenTemplateCacheSnapshot({
baseUrl: baseUrl(),
@@ -270,10 +269,10 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
});
const summaryLabel = createMemo(() => {
- if (authError()) return tr("den.needs_attention");
- if (sessionBusy()) return tr("den.checking_session");
- if (isSignedIn()) return t("dashboard.connected", currentLocale());
- return tr("den.signed_out");
+ if (authError()) return t("den.needs_attention");
+ if (sessionBusy()) return t("den.checking_session");
+ if (isSignedIn()) return t("dashboard.connected");
+ return t("den.signed_out");
});
createEffect(() => {
@@ -294,8 +293,8 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
platform.openLink(buildDenAuthUrl(baseUrl(), mode));
setStatusMessage(
mode === "sign-up"
- ? tr("den.status_browser_signup")
- : tr("den.status_browser_signin"),
+ ? t("den.status_browser_signup")
+ : t("den.status_browser_signin"),
);
setAuthError(null);
};
@@ -331,7 +330,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
const parsed = parseManualAuthInput(manualAuthInput());
if (!parsed || authBusy()) {
if (!parsed) {
- setAuthError(tr("den.error_paste_valid_code"));
+ setAuthError(t("den.error_paste_valid_code"));
}
return;
}
@@ -340,12 +339,12 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
setAuthBusy(true);
setAuthError(null);
- setStatusMessage(tr("den.signing_in"));
+ setStatusMessage(t("den.signing_in"));
try {
const result = await createDenClient({ baseUrl: nextBaseUrl }).exchangeDesktopHandoff(parsed.grant);
if (!result.token) {
- throw new Error(tr("den.error_no_token"));
+ throw new Error(t("den.error_no_token"));
}
if (props.developerMode) {
@@ -376,7 +375,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
message:
error instanceof Error
? error.message
- : tr("den.error_signin_failed"),
+ : t("den.error_signin_failed"),
});
} finally {
setAuthBusy(false);
@@ -420,7 +419,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
const applyBaseUrl = () => {
const normalized = normalizeDenBaseUrl(baseUrlDraft());
if (!normalized) {
- setBaseUrlError(tr("den.error_base_url"));
+ setBaseUrlError(t("den.error_base_url"));
return;
}
@@ -433,7 +432,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
setBaseUrl(resolved.baseUrl);
setBaseUrlDraft(resolved.baseUrl);
- clearSignedInState(tr("den.status_base_url_updated"));
+ clearSignedInState(t("den.status_base_url_updated"));
};
const refreshOrgs = async (quiet = false) => {
@@ -463,11 +462,11 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
});
if (!quiet && response.orgs.length > 0) {
setStatusMessage(
- t("den.status_loaded_orgs", currentLocale(), { count: response.orgs.length, plural: response.orgs.length === 1 ? "" : "s" }),
+ t("den.status_loaded_orgs", { count: response.orgs.length, plural: response.orgs.length === 1 ? "" : "s" }),
);
}
} catch (error) {
- setOrgsError(error instanceof Error ? error.message : tr("den.error_load_orgs"));
+ setOrgsError(error instanceof Error ? error.message : t("den.error_load_orgs"));
} finally {
setOrgsBusy(false);
}
@@ -489,12 +488,12 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
if (!quiet) {
setStatusMessage(
nextWorkers.length > 0
- ? t("den.status_loaded_workers", currentLocale(), { count: nextWorkers.length, plural: nextWorkers.length === 1 ? "" : "s", name: activeOrg()?.name ?? tr("den.active_org_title") })
- : t("den.status_no_workers", currentLocale(), { name: activeOrg()?.name ?? tr("den.active_org_title") }),
+ ? t("den.status_loaded_workers", { count: nextWorkers.length, plural: nextWorkers.length === 1 ? "" : "s", name: activeOrg()?.name ?? t("den.active_org_title") })
+ : t("den.status_no_workers", { name: activeOrg()?.name ?? t("den.active_org_title") }),
);
}
} catch (error) {
- setWorkersError(error instanceof Error ? error.message : tr("den.error_load_workers"));
+ setWorkersError(error instanceof Error ? error.message : t("den.error_load_workers"));
} finally {
setWorkersBusy(false);
}
@@ -520,13 +519,13 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
if (!quiet) {
setStatusMessage(
nextTemplates.length > 0
- ? t("den.status_loaded_templates", currentLocale(), { count: nextTemplates.length, plural: nextTemplates.length === 1 ? "" : "s", name: activeOrg()?.name ?? tr("den.active_org_title") })
- : t("den.status_no_templates", currentLocale(), { name: activeOrg()?.name ?? tr("den.active_org_title") }),
+ ? t("den.status_loaded_templates", { count: nextTemplates.length, plural: nextTemplates.length === 1 ? "" : "s", name: activeOrg()?.name ?? t("den.active_org_title") })
+ : t("den.status_no_templates", { name: activeOrg()?.name ?? t("den.active_org_title") }),
);
}
} catch (error) {
if (!quiet) {
- setTemplateActionError(error instanceof Error ? error.message : tr("den.error_load_templates"));
+ setTemplateActionError(error instanceof Error ? error.message : t("den.error_load_templates"));
}
}
};
@@ -546,8 +545,8 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
const count = extensions.cloudOrgSkillHubs().length;
setStatusMessage(
count > 0
- ? `Loaded ${count} cloud skill hub${count === 1 ? "" : "s"} for ${activeOrg()?.name ?? tr("den.active_org_title")}.`
- : `No cloud skill hubs are available for ${activeOrg()?.name ?? tr("den.active_org_title")}.`,
+ ? `Loaded ${count} cloud skill hub${count === 1 ? "" : "s"} for ${activeOrg()?.name ?? t("den.active_org_title")}.`
+ : `No cloud skill hubs are available for ${activeOrg()?.name ?? t("den.active_org_title")}.`,
);
}
} catch (error) {
@@ -575,8 +574,8 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
if (!quiet) {
setStatusMessage(
items.length > 0
- ? `Loaded ${items.length} cloud provider${items.length === 1 ? "" : "s"} for ${activeOrg()?.name ?? tr("den.active_org_title")}.`
- : `No cloud providers are available for ${activeOrg()?.name ?? tr("den.active_org_title")}.`,
+ ? `Loaded ${items.length} cloud provider${items.length === 1 ? "" : "s"} for ${activeOrg()?.name ?? t("den.active_org_title")}.`
+ : `No cloud providers are available for ${activeOrg()?.name ?? t("den.active_org_title")}.`,
);
}
} catch (error) {
@@ -610,7 +609,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
.then((nextUser) => {
if (cancelled) return;
setUser(nextUser);
- setStatusMessage(t("den.status_signed_in_as", currentLocale(), { email: nextUser.email }));
+ setStatusMessage(t("den.status_signed_in_as", { email: nextUser.email }));
})
.catch((error) => {
if (cancelled) return;
@@ -620,7 +619,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
clearSessionState();
}
setAuthError(
- error instanceof Error ? error.message : tr("den.error_no_session"),
+ error instanceof Error ? error.message : t("den.error_no_session"),
);
})
.finally(() => {
@@ -682,13 +681,13 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
setSessionBusy(false);
setStatusMessage(
customEvent.detail.email?.trim()
- ? t("den.status_cloud_signed_in_as", currentLocale(), { email: customEvent.detail.email.trim() })
- : tr("den.status_cloud_signin_done"),
+ ? t("den.status_cloud_signed_in_as", { email: customEvent.detail.email.trim() })
+ : t("den.status_cloud_signin_done"),
);
} else if (customEvent.detail?.status === "error") {
setAuthError(
customEvent.detail.message?.trim() ||
- tr("den.error_signin_failed"),
+ t("den.error_signin_failed"),
);
}
};
@@ -718,13 +717,13 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
setAuthBusy(false);
}
- clearSignedInState(tr("den.status_signed_out"));
+ clearSignedInState(t("den.status_signed_out"));
};
const handleOpenWorker = async (workerId: string, workerName: string) => {
const orgId = activeOrgId().trim();
if (!orgId) {
- setWorkersError(tr("den.error_choose_org"));
+ setWorkersError(t("den.error_choose_org"));
return;
}
@@ -737,7 +736,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
const accessToken =
tokens.ownerToken?.trim() || tokens.clientToken?.trim() || "";
if (!openworkUrl || !accessToken) {
- throw new Error(tr("den.error_worker_not_ready"));
+ throw new Error(t("den.error_worker_not_ready"));
}
const ok = await props.connectRemoteWorkspace({
@@ -747,13 +746,13 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
displayName: workerName,
});
if (!ok) {
- throw new Error(t("den.error_open_worker", currentLocale(), { name: workerName }));
+ throw new Error(t("den.error_open_worker", { name: workerName }));
}
- setStatusMessage(t("den.status_opened_worker", currentLocale(), { name: workerName }));
+ setStatusMessage(t("den.status_opened_worker", { name: workerName }));
} catch (error) {
setWorkersError(
- error instanceof Error ? error.message : t("den.error_open_worker_fallback", currentLocale(), { name: workerName }),
+ error instanceof Error ? error.message : t("den.error_open_worker_fallback", { name: workerName }),
);
} finally {
setOpeningWorkerId(null);
@@ -776,11 +775,11 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
const orgName = activeOrg()?.name;
setStatusMessage(
orgName
- ? t("den.status_opened_template", currentLocale(), { name: template.name, org: orgName })
- : t("den.status_opened_template_fallback", currentLocale(), { name: template.name }),
+ ? t("den.status_opened_template", { name: template.name, org: orgName })
+ : t("den.status_opened_template_fallback", { name: template.name }),
);
} catch (error) {
- setTemplateActionError(error instanceof Error ? error.message : t("den.error_open_template", currentLocale(), { name: template.name }));
+ setTemplateActionError(error instanceof Error ? error.message : t("den.error_open_template", { name: template.name }));
} finally {
setOpeningTemplateId(null);
}
@@ -861,9 +860,9 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
try {
const message = await props.connectCloudProvider(cloudProviderId);
- setStatusMessage(`${message || t("den.imported_provider", undefined, { name: providerName })} ${t("den.reload_workspace")}`);
+ setStatusMessage(`${message || t("den.imported_provider", { name: providerName })} ${t("den.reload_workspace")}`);
} catch (error) {
- setProviderActionError(error instanceof Error ? error.message : t("den.import_provider_failed", undefined, { name: providerName }));
+ setProviderActionError(error instanceof Error ? error.message : t("den.import_provider_failed", { name: providerName }));
} finally {
setProviderActionId(null);
setProviderActionKind(null);
@@ -879,9 +878,9 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
try {
const message = await props.removeCloudProvider(cloudProviderId);
- setStatusMessage(`${message || t("den.removed_provider", undefined, { name: providerName })} ${t("den.reload_workspace")}`);
+ setStatusMessage(`${message || t("den.removed_provider", { name: providerName })} ${t("den.reload_workspace")}`);
} catch (error) {
- setProviderActionError(error instanceof Error ? error.message : t("den.remove_provider_failed", undefined, { name: providerName }));
+ setProviderActionError(error instanceof Error ? error.message : t("den.remove_provider_failed", { name: providerName }));
} finally {
setProviderActionId(null);
setProviderActionKind(null);
@@ -897,9 +896,9 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
try {
await props.connectCloudProvider(cloudProviderId);
- setStatusMessage(`${t("den.synced_provider", undefined, { name: providerName })} ${t("den.reload_workspace")}`);
+ setStatusMessage(`${t("den.synced_provider", { name: providerName })} ${t("den.reload_workspace")}`);
} catch (error) {
- setProviderActionError(error instanceof Error ? error.message : t("den.sync_provider_failed", undefined, { name: providerName }));
+ setProviderActionError(error instanceof Error ? error.message : t("den.sync_provider_failed", { name: providerName }));
} finally {
setProviderActionId(null);
setProviderActionKind(null);
@@ -907,9 +906,9 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
};
const formatTemplateTimestamp = (value: string | null) => {
- if (!value) return tr("dashboard.recently_updated");
+ if (!value) return t("dashboard.recently_updated");
const date = new Date(value);
- if (Number.isNaN(date.getTime())) return tr("dashboard.recently_updated");
+ if (Number.isNaN(date.getTime())) return t("dashboard.recently_updated");
return new Intl.DateTimeFormat(undefined, {
month: "short",
day: "numeric",
@@ -919,8 +918,8 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
const templateCreatorLabel = (template: DenTemplate) => {
const creator = template.creator;
- if (!creator) return tr("dashboard.unknown_creator");
- return creator.name?.trim() || creator.email?.trim() || tr("dashboard.unknown_creator");
+ if (!creator) return t("dashboard.unknown_creator");
+ return creator.name?.trim() || creator.email?.trim() || t("dashboard.unknown_creator");
};
const settingsPanelClass =
@@ -945,14 +944,14 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
- {tr("den.cloud_section_desc")}
+ {t("den.cloud_section_desc")}
- {tr("den.cloud_sleep_hint")}
+ {t("den.cloud_sleep_hint")}
@@ -967,11 +966,11 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
setBaseUrlDraft(event.currentTarget.value)}
placeholder={DEFAULT_DEN_BASE_URL}
- hint={tr("den.cloud_control_plane_url_hint")}
+ hint={t("den.cloud_control_plane_url_hint")}
disabled={authBusy() || sessionBusy()}
/>
@@ -981,7 +980,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
onClick={() => setBaseUrlDraft(baseUrl())}
disabled={authBusy() || sessionBusy()}
>
- {tr("den.cloud_control_plane_reset")}
+ {t("den.cloud_control_plane_reset")}
- {tr("den.cloud_control_plane_save")}
+ {t("den.cloud_control_plane_save")}
- {tr("den.cloud_control_plane_open")}
+ {t("den.cloud_control_plane_open")}
@@ -1024,16 +1023,16 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
- {tr("den.signin_title")}
+ {t("den.signin_title")}
- {tr("den.cloud_sleep_hint")}
+ {t("den.cloud_sleep_hint")}
openBrowserAuth("sign-in")}>
- {tr("den.signin_button")}
+ {t("den.signin_button")}
openBrowserAuth("sign-up")}
>
- {tr("den.create_account")}
+ {t("den.create_account")}
- {manualAuthOpen() ? tr("den.hide_signin_code") : tr("den.paste_signin_code")}
+ {manualAuthOpen() ? t("den.hide_signin_code") : t("den.paste_signin_code")}
setManualAuthInput(event.currentTarget.value)}
- placeholder={tr("den.signin_link_placeholder")}
+ placeholder={t("den.signin_link_placeholder")}
disabled={authBusy() || sessionBusy()}
- hint={tr("den.signin_link_hint")}
+ hint={t("den.signin_link_hint")}
/>
void submitManualAuth()}
disabled={authBusy() || sessionBusy() || !manualAuthInput().trim()}
>
- {authBusy() ? tr("den.finishing") : tr("den.finish_signin")}
+ {authBusy() ? t("den.finishing") : t("den.finish_signin")}
- {tr("den.signin_code_note")}
+ {t("den.signin_code_note")}
@@ -1092,7 +1091,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
- {tr("den.auto_reconnect_hint")}
+ {t("den.auto_reconnect_hint")}
@@ -1101,9 +1100,9 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
-
{tr("den.cloud_account_title")}
+
{t("den.cloud_account_title")}
- {tr("den.cloud_account_hint")}
+ {t("den.cloud_account_hint")}
@@ -1124,15 +1123,15 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
disabled={authBusy() || sessionBusy()}
>
- {authBusy() ? tr("den.signing_out") : tr("den.sign_out")}
+ {authBusy() ? t("den.signing_out") : t("den.sign_out")}
-
{tr("den.active_org_title")}
+
{t("den.active_org_title")}
- {tr("den.active_org_hint")}
+ {t("den.active_org_hint")}
@@ -1151,7 +1150,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
activeOrgName: nextOrg?.name ?? null,
});
setStatusMessage(
- t("den.org_switched", currentLocale(), { name: nextOrg?.name ?? tr("den.active_org_title") }),
+ t("den.org_switched", { name: nextOrg?.name ?? t("den.active_org_title") }),
);
}}
disabled={orgsBusy() || orgs().length === 0}
@@ -1159,7 +1158,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
{(org) => (
)}
@@ -1190,10 +1189,10 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
- {tr("den.cloud_workers_title")}
+ {t("den.cloud_workers_title")}
- {tr("den.cloud_workers_hint")}
+ {t("den.cloud_workers_hint")}
@@ -1208,7 +1207,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
disabled={workersBusy() || !activeOrgId().trim()}
>
- {tr("den.refresh")}
+ {t("den.refresh")}
@@ -1223,7 +1222,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
- {tr("den.no_cloud_workers")}
+ {t("den.no_cloud_workers")}
@@ -1245,12 +1244,12 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
- {tr("den.worker_mine_badge")}
+ {t("den.worker_mine_badge")}
- {worker.provider ? t("den.worker_provider_label", currentLocale(), { provider: worker.provider }) : tr("den.worker_secondary_cloud")}
+ {worker.provider ? t("den.worker_provider_label", { provider: worker.provider }) : t("den.worker_secondary_cloud")}
{(value) => · {value()}}
@@ -1263,9 +1262,9 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
void handleOpenWorker(worker.workerId, worker.workerName)
}
disabled={openingWorkerId() !== null || !status().canOpen}
- title={!status().canOpen ? tr("den.worker_not_ready_title") : undefined}
+ title={!status().canOpen ? t("den.worker_not_ready_title") : undefined}
>
- {openingWorkerId() === worker.workerId ? tr("den.opening") : tr("den.open")}
+ {openingWorkerId() === worker.workerId ? t("den.opening") : t("den.open")}
);
@@ -1279,10 +1278,10 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
- {tr("den.team_templates_title")}
+ {t("den.team_templates_title")}
- {tr("den.team_templates_hint")}
+ {t("den.team_templates_hint")}
@@ -1297,7 +1296,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
disabled={templatesBusy() || !activeOrg()?.slug?.trim()}
>
- {tr("den.refresh")}
+ {t("den.refresh")}
@@ -1314,9 +1313,9 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
- {tr("den.no_team_templates")}
+ {t("den.no_team_templates")}
@@ -1334,11 +1333,11 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
{template.name}
- {tr("den.team_template_badge")}
+ {t("den.team_template_badge")}
- {tr("den.worker_mine_badge")}
+ {t("den.worker_mine_badge")}
@@ -1352,7 +1351,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
onClick={() => void handleOpenTemplate(template)}
disabled={openingTemplateId() !== null}
>
- {opening() ? tr("den.opening") : tr("den.open")}
+ {opening() ? t("den.opening") : t("den.open")}
);
@@ -1366,10 +1365,10 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
- {tr("den.skill_hubs_title")}
+ {t("den.skill_hubs_title")}
- {tr("den.skill_hubs_hint")}
+ {t("den.skill_hubs_hint")}
@@ -1384,7 +1383,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
disabled={skillHubsBusy() || !activeOrgId().trim()}
>
- {tr("den.refresh")}
+ {t("den.refresh")}
@@ -1399,8 +1398,8 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
-
- {tr("den.no_skill_hubs")}
+
+ {t("den.no_skill_hubs")}
@@ -1413,11 +1412,11 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
if (!actionBusy()) return null;
switch (skillHubActionKind()) {
case "import":
- return tr("den.importing");
+ return t("den.importing");
case "sync":
- return tr("den.syncing");
+ return t("den.syncing");
default:
- return tr("den.removing");
+ return t("den.removing");
}
});
return (
@@ -1426,33 +1425,33 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
{row.name}
- {t("den.skill_hub_skills_badge", currentLocale(), {
+ {t("den.skill_hub_skills_badge", {
count: row.hub?.skills.length ?? row.importedSkillCount,
})}
{row.status === "imported"
- ? tr("den.imported_badge")
+ ? t("den.imported_badge")
: row.status === "out_of_sync"
- ? tr("den.out_of_sync_badge")
- : tr("den.removed_from_cloud_badge")}
+ ? t("den.out_of_sync_badge")
+ : t("den.removed_from_cloud_badge")}
{row.status === "available"
- ? t("den.skill_hub_detail", currentLocale(), { count: row.liveSkillCount })
+ ? t("den.skill_hub_detail", { count: row.liveSkillCount })
: row.status === "imported"
- ? t("den.skill_hub_imported_detail", currentLocale(), {
+ ? t("den.skill_hub_imported_detail", {
count: row.importedSkillCount,
})
: row.status === "out_of_sync"
- ? t("den.skill_hub_sync_detail", currentLocale(), {
+ ? t("den.skill_hub_sync_detail", {
liveCount: row.liveSkillCount,
importedCount: row.importedSkillCount,
})
- : t("den.skill_hub_removed_detail", currentLocale(), {
+ : t("den.skill_hub_removed_detail", {
importedCount: row.importedSkillCount,
})}
@@ -1465,7 +1464,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
onClick={() => void handleSyncSkillHub(row.hubId)}
disabled={skillHubActionId() !== null}
>
- {actionBusy() && skillHubActionKind() === "sync" ? tr("den.syncing") : tr("den.sync")}
+ {actionBusy() && skillHubActionKind() === "sync" ? t("den.syncing") : t("den.sync")}
@@ -1498,10 +1497,10 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
- {tr("den.cloud_providers_title")}
+ {t("den.cloud_providers_title")}
- {tr("den.cloud_providers_hint")}
+ {t("den.cloud_providers_hint")}
@@ -1516,7 +1515,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
disabled={providersBusy() || !activeOrgId().trim()}
>
- {tr("den.refresh")}
+ {t("den.refresh")}
@@ -1531,8 +1530,8 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
-
- {tr("den.no_cloud_providers")}
+
+ {t("den.no_cloud_providers")}
@@ -1545,11 +1544,11 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
if (!actionBusy()) return null;
switch (providerActionKind()) {
case "import":
- return tr("den.importing");
+ return t("den.importing");
case "sync":
- return tr("den.syncing");
+ return t("den.syncing");
default:
- return tr("den.removing");
+ return t("den.removing");
}
});
return (
@@ -1562,29 +1561,29 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
{row.provider?.providerId ?? row.imported?.providerId}
- {tr("den.credentials_ready_badge")}
+ {t("den.credentials_ready_badge")}
{row.status === "imported"
- ? tr("den.imported_badge")
+ ? t("den.imported_badge")
: row.status === "out_of_sync"
- ? tr("den.out_of_sync_badge")
- : tr("den.removed_from_cloud_badge")}
+ ? t("den.out_of_sync_badge")
+ : t("den.removed_from_cloud_badge")}
{row.status === "removed_from_cloud"
- ? t("den.cloud_provider_removed_detail", currentLocale(), {
+ ? t("den.cloud_provider_removed_detail", {
providerId: row.imported?.providerId ?? row.name,
})
: row.status === "out_of_sync"
- ? t("den.cloud_provider_sync_detail", currentLocale(), {
+ ? t("den.cloud_provider_sync_detail", {
count: row.provider?.models.length ?? 0,
source: row.provider?.source === "custom" ? "custom" : "managed",
})
- : t("den.cloud_provider_detail", currentLocale(), {
+ : t("den.cloud_provider_detail", {
count: row.provider?.models.length ?? 0,
source: row.provider?.source === "custom" ? "custom" : "managed",
})}
@@ -1598,7 +1597,7 @@ export default function DenSettingsPanel(props: DenSettingsPanelProps) {
onClick={() => void handleSyncProvider(row.cloudProviderId, row.name)}
disabled={providerActionId() !== null}
>
- {actionBusy() && providerActionKind() === "sync" ? tr("den.syncing") : tr("den.sync")}
+ {actionBusy() && providerActionKind() === "sync" ? t("den.syncing") : t("den.sync")}
diff --git a/apps/app/src/app/components/mcp-auth-modal.tsx b/apps/app/src/app/components/mcp-auth-modal.tsx
index 8d0b04a1b..7f103fda6 100644
--- a/apps/app/src/app/components/mcp-auth-modal.tsx
+++ b/apps/app/src/app/components/mcp-auth-modal.tsx
@@ -31,15 +31,6 @@ export type McpAuthModalProps = {
};
export default function McpAuthModal(props: McpAuthModalProps) {
- const translate = (key: string, replacements?: Record) => {
- let result = t(key, props.language);
- if (replacements) {
- Object.entries(replacements).forEach(([placeholder, value]) => {
- result = result.replace(`{${placeholder}}`, value);
- });
- }
- return result;
- };
const [loading, setLoading] = createSignal(false);
const [error, setError] = createSignal(null);
@@ -168,7 +159,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
statusPoll = window.setInterval(async () => {
if (Date.now() - startedAt >= MCP_AUTH_TIMEOUT_MS) {
stopStatusPolling();
- setError(translate("mcp.auth.request_timed_out"));
+ setError(t("mcp.auth.request_timed_out"));
return;
}
@@ -193,7 +184,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
try {
slug = resolveSlug(entry.name);
} catch (err) {
- const message = err instanceof Error ? err.message : translate("mcp.auth.failed_to_start_oauth");
+ const message = err instanceof Error ? err.message : t("mcp.auth.failed_to_start_oauth");
setError(message);
setLoading(false);
setAuthInProgress(false);
@@ -217,7 +208,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
try {
const directory = await resolveDirectory();
if (!directory) {
- setError(translate("mcp.pick_workspace_first"));
+ setError(t("mcp.pick_workspace_first"));
return;
}
@@ -226,8 +217,8 @@ export default function McpAuthModal(props: McpAuthModalProps) {
setNeedsReload(true);
setReloadNotice(
props.reloadBlocked
- ? translate("mcp.auth.reload_blocked")
- : translate("mcp.auth.reload_notice")
+ ? t("mcp.auth.reload_blocked")
+ : t("mcp.auth.reload_notice")
);
return;
}
@@ -251,13 +242,13 @@ export default function McpAuthModal(props: McpAuthModalProps) {
}
if (status.status === "needs_client_registration") {
- setError(status.error ?? translate("mcp.auth.client_registration_required"));
+ setError(status.error ?? t("mcp.auth.client_registration_required"));
} else if (status.status === "disabled") {
- setError(translate("mcp.auth.server_disabled"));
+ setError(t("mcp.auth.server_disabled"));
} else if (status.status === "failed") {
- setError(status.error ?? translate("mcp.auth.oauth_failed"));
+ setError(status.error ?? t("mcp.auth.oauth_failed"));
} else {
- setError(translate("mcp.auth.authorization_still_required"));
+ setError(t("mcp.auth.authorization_still_required"));
}
return;
}
@@ -277,7 +268,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
await openAuthorizationUrl(auth.authorizationUrl);
startStatusPolling(slug);
} catch (err) {
- const message = err instanceof Error ? err.message : translate("mcp.auth.failed_to_start_oauth");
+ const message = err instanceof Error ? err.message : t("mcp.auth.failed_to_start_oauth");
if (message.toLowerCase().includes("does not support oauth")) {
const serverSlug = props.entry?.name.toLowerCase().replace(/[^a-z0-9]+/g, "-") ?? "server";
@@ -293,18 +284,18 @@ export default function McpAuthModal(props: McpAuthModalProps) {
if (props.reloadRequired && !reloadSatisfied()) {
setReloadNotice(
props.reloadBlocked
- ? translate("mcp.auth.reload_blocked")
- : translate("mcp.auth.reload_notice")
+ ? t("mcp.auth.reload_blocked")
+ : t("mcp.auth.reload_notice")
);
} else {
setError(
- `${message}\n\n` + translate("mcp.auth.oauth_not_supported_hint", { server: serverSlug })
+ `${message}\n\n` + t("mcp.auth.oauth_not_supported_hint", { server: serverSlug })
);
}
setNeedsReload(true);
} else if (message.toLowerCase().includes("not found") || message.toLowerCase().includes("unknown")) {
setNeedsReload(true);
- setError(translate("mcp.auth.try_reload_engine", { message }));
+ setError(t("mcp.auth.try_reload_engine", { message }));
} else {
setError(message);
}
@@ -339,12 +330,12 @@ export default function McpAuthModal(props: McpAuthModalProps) {
if (result.ok) {
setError(null);
setNeedsReload(true);
- setReloadNotice(translate("mcp.auth.oauth_completed_reload"));
+ setReloadNotice(t("mcp.auth.oauth_completed_reload"));
} else {
- setCliAuthResult(result.stderr || result.stdout || translate("mcp.auth.reauth_failed"));
+ setCliAuthResult(result.stderr || result.stdout || t("mcp.auth.reauth_failed"));
}
} catch (err) {
- const message = err instanceof Error ? err.message : translate("mcp.auth.reauth_failed");
+ const message = err instanceof Error ? err.message : t("mcp.auth.reauth_failed");
setCliAuthResult(message);
} finally {
setCliAuthBusy(false);
@@ -396,8 +387,8 @@ export default function McpAuthModal(props: McpAuthModalProps) {
setNeedsReload(true);
setReloadNotice(
props.reloadBlocked
- ? translate("mcp.auth.reload_blocked")
- : translate("mcp.auth.reload_notice")
+ ? t("mcp.auth.reload_blocked")
+ : t("mcp.auth.reload_notice")
);
return;
}
@@ -405,7 +396,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
setAwaitingReload(false);
startAuth(false, false);
} catch (err) {
- const message = err instanceof Error ? err.message : translate("mcp.auth.reload_failed");
+ const message = err instanceof Error ? err.message : t("mcp.auth.reload_failed");
setAwaitingReload(false);
setNeedsReload(true);
setError(message);
@@ -426,7 +417,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
const handleReloadAndRetry = async () => {
if (!props.onReloadEngine) return;
if (props.isRemoteWorkspace && typeof window !== "undefined") {
- const proceed = window.confirm(translate("mcp.auth.reload_remote_confirm"));
+ const proceed = window.confirm(t("mcp.auth.reload_remote_confirm"));
if (!proceed) return;
}
await props.onReloadEngine();
@@ -497,14 +488,14 @@ export default function McpAuthModal(props: McpAuthModalProps) {
const safeName = validateMcpServerName(entry.name);
slug = safeName.toLowerCase().replace(/[^a-z0-9]+/g, "-");
} catch (err) {
- const message = err instanceof Error ? err.message : translate("mcp.auth.failed_to_start_oauth");
+ const message = err instanceof Error ? err.message : t("mcp.auth.failed_to_start_oauth");
setError(message);
return;
}
const code = parseAuthCode(callbackInput());
if (!code) {
- setError(translate("mcp.auth.callback_invalid"));
+ setError(t("mcp.auth.callback_invalid"));
return;
}
@@ -515,7 +506,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
try {
const directory = await resolveDirectory();
if (!directory) {
- setError(translate("mcp.pick_workspace_first"));
+ setError(t("mcp.pick_workspace_first"));
return;
}
@@ -533,16 +524,16 @@ export default function McpAuthModal(props: McpAuthModalProps) {
}
if (status.status === "needs_client_registration") {
- setError(status.error ?? translate("mcp.auth.client_registration_required"));
+ setError(status.error ?? t("mcp.auth.client_registration_required"));
} else if (status.status === "disabled") {
- setError(translate("mcp.auth.server_disabled"));
+ setError(t("mcp.auth.server_disabled"));
} else if (status.status === "failed") {
- setError(status.error ?? translate("mcp.auth.oauth_failed"));
+ setError(status.error ?? t("mcp.auth.oauth_failed"));
} else {
- setError(translate("mcp.auth.authorization_still_required"));
+ setError(t("mcp.auth.authorization_still_required"));
}
} catch (err) {
- const message = err instanceof Error ? err.message : translate("mcp.auth.oauth_failed");
+ const message = err instanceof Error ? err.message : t("mcp.auth.oauth_failed");
setError(message);
} finally {
setManualAuthBusy(false);
@@ -562,7 +553,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
const safeName = validateMcpServerName(entry.name);
slug = safeName.toLowerCase().replace(/[^a-z0-9]+/g, "-");
} catch (err) {
- const message = err instanceof Error ? err.message : translate("mcp.auth.failed_to_start_oauth");
+ const message = err instanceof Error ? err.message : t("mcp.auth.failed_to_start_oauth");
setError(message);
setStatusChecking(false);
return;
@@ -577,13 +568,13 @@ export default function McpAuthModal(props: McpAuthModalProps) {
}
if (statusEntry?.status === "needs_client_registration") {
- setError(statusEntry.error ?? translate("mcp.auth.client_registration_required"));
+ setError(statusEntry.error ?? t("mcp.auth.client_registration_required"));
} else if (statusEntry?.status === "disabled") {
- setError(translate("mcp.auth.server_disabled"));
+ setError(t("mcp.auth.server_disabled"));
} else if (statusEntry?.status === "failed") {
- setError(statusEntry.error ?? translate("mcp.auth.oauth_failed"));
+ setError(statusEntry.error ?? t("mcp.auth.oauth_failed"));
} else {
- setError(translate("mcp.auth.authorization_still_required"));
+ setError(t("mcp.auth.authorization_still_required"));
}
setStatusChecking(false);
@@ -606,9 +597,9 @@ export default function McpAuthModal(props: McpAuthModalProps) {
- {translate("mcp.auth.connect_server", { server: serverName() })}
+ {t("mcp.auth.connect_server", { server: serverName() })}
-
{translate("mcp.auth.open_browser_signin")}
+
{t("mcp.auth.open_browser_signin")}
- {translate("mcp.auth.waiting_authorization")}
+ {t("mcp.auth.waiting_authorization")}
- {translate("mcp.auth.follow_browser_steps")}
+ {t("mcp.auth.follow_browser_steps")}
- {translate("mcp.auth.reopen_browser_link")}
+ {t("mcp.auth.reopen_browser_link")}
@@ -652,13 +643,13 @@ export default function McpAuthModal(props: McpAuthModalProps) {
{props.reloadBlocked
- ? translate("mcp.auth.waiting_for_conversation_title")
- : translate("mcp.auth.applying_changes_title")}
+ ? t("mcp.auth.waiting_for_conversation_title")
+ : t("mcp.auth.applying_changes_title")}
{props.reloadBlocked
- ? translate("mcp.auth.waiting_for_conversation_body")
- : translate("mcp.auth.applying_changes_body")}
+ ? t("mcp.auth.waiting_for_conversation_body")
+ : t("mcp.auth.applying_changes_body")}
0}>
@@ -667,7 +658,7 @@ export default function McpAuthModal(props: McpAuthModalProps) {
{(session) => (
- {translate("mcp.auth.waiting_for_session", { session: session.title })}
+ {t("mcp.auth.waiting_for_session", { session: session.title })}
{forceStopBusySessionID() === session.id
- ? translate("mcp.auth.force_stopping")
- : translate("mcp.auth.force_stop")}
+ ? t("mcp.auth.force_stopping")
+ : t("mcp.auth.force_stop")}
)}
@@ -694,14 +685,14 @@ export default function McpAuthModal(props: McpAuthModalProps) {
-
{translate("mcp.auth.already_connected")}
+
{t("mcp.auth.already_connected")}
- {translate("mcp.auth.already_connected_description", { server: serverName() })}
+ {t("mcp.auth.already_connected_description", { server: serverName() })}
- {translate("mcp.auth.configured_previously")}
+ {t("mcp.auth.configured_previously")}
@@ -716,14 +707,14 @@ export default function McpAuthModal(props: McpAuthModalProps) {
variant="secondary"
onClick={handleReloadAndRetry}
disabled={props.reloadBlocked}
- title={props.reloadBlocked ? translate("mcp.reload_banner_blocked_hint") : undefined}
+ title={props.reloadBlocked ? t("mcp.reload_banner_blocked_hint") : undefined}
>
- {translate("mcp.auth.reload_engine_retry")}
+ {t("mcp.auth.reload_engine_retry")}
- {translate("mcp.auth.retry_now")}
+ {t("mcp.auth.retry_now")}
@@ -740,14 +731,14 @@ export default function McpAuthModal(props: McpAuthModalProps) {
variant="secondary"
onClick={handleReloadAndRetry}
disabled={props.reloadBlocked}
- title={props.reloadBlocked ? translate("mcp.reload_banner_blocked_hint") : undefined}
+ title={props.reloadBlocked ? t("mcp.reload_banner_blocked_hint") : undefined}
>
- {translate("mcp.auth.reload_engine_retry")}
+ {t("mcp.auth.reload_engine_retry")}
- {translate("mcp.auth.retry_now")}
+ {t("mcp.auth.retry_now")}
@@ -755,35 +746,35 @@ export default function McpAuthModal(props: McpAuthModalProps) {
- {translate("mcp.auth.retry")}
+ {t("mcp.auth.retry")}
-
{translate("mcp.auth.invalid_refresh_token")}
+
{t("mcp.auth.invalid_refresh_token")}
- {translate("mcp.auth.reauth_running")}
+ {t("mcp.auth.reauth_running")}
- {translate("mcp.auth.reauth_cli_hint", { server: serverName() })}
+ {t("mcp.auth.reauth_cli_hint", { server: serverName() })}
- {translate("mcp.auth.reauth_remote_hint")}
+ {t("mcp.auth.reauth_remote_hint")}
@@ -797,14 +788,14 @@ export default function McpAuthModal(props: McpAuthModalProps) {
- {translate("mcp.auth.manual_finish_title")}
+ {t("mcp.auth.manual_finish_title")}
- {translate("mcp.auth.manual_finish_hint")}
+ {t("mcp.auth.manual_finish_hint")}
-
{translate("mcp.auth.authorization_link")}
+
{t("mcp.auth.authorization_link")}
{authorizationUrl()}
@@ -814,17 +805,17 @@ export default function McpAuthModal(props: McpAuthModalProps) {
class="text-xs"
onClick={handleCopyAuthorizationUrl}
>
- {authUrlCopied() ? translate("mcp.auth.copied") : translate("mcp.auth.copy_link")}
+ {authUrlCopied() ? t("mcp.auth.copied") : t("mcp.auth.copy_link")}
setCallbackInput(event.currentTarget.value)}
/>
- {translate("mcp.auth.port_forward_hint")}
+ {t("mcp.auth.port_forward_hint")}
- {translate("mcp.auth.complete_connection")}
+ {t("mcp.auth.complete_connection")}
@@ -851,9 +842,9 @@ export default function McpAuthModal(props: McpAuthModalProps) {
1
-
{translate("mcp.auth.step1_title")}
+
{t("mcp.auth.step1_title")}
- {translate("mcp.auth.step1_description", { server: serverName() })}
+ {t("mcp.auth.step1_description", { server: serverName() })}
@@ -863,9 +854,9 @@ export default function McpAuthModal(props: McpAuthModalProps) {
2
-
{translate("mcp.auth.step2_title")}
+
{t("mcp.auth.step2_title")}
- {translate("mcp.auth.step2_description")}
+ {t("mcp.auth.step2_description")}
@@ -875,9 +866,9 @@ export default function McpAuthModal(props: McpAuthModalProps) {
3
-
{translate("mcp.auth.step3_title")}
+
{t("mcp.auth.step3_title")}
- {translate("mcp.auth.step3_description")}
+ {t("mcp.auth.step3_description")}
@@ -885,16 +876,16 @@ export default function McpAuthModal(props: McpAuthModalProps) {
-
{translate("mcp.auth.waiting_authorization")}
+
{t("mcp.auth.waiting_authorization")}
- {translate("mcp.auth.follow_browser_steps")}
+ {t("mcp.auth.follow_browser_steps")}
- {translate("mcp.auth.reopen_browser_link")}
+ {t("mcp.auth.reopen_browser_link")}
@@ -906,16 +897,16 @@ export default function McpAuthModal(props: McpAuthModalProps) {
- {translate("mcp.auth.done")}
+ {t("mcp.auth.done")}
- {translate("mcp.auth.cancel")}
+ {t("mcp.auth.cancel")}
- {translate("mcp.auth.im_done")}
+ {t("mcp.auth.im_done")}
diff --git a/apps/app/src/app/components/model-picker-modal.tsx b/apps/app/src/app/components/model-picker-modal.tsx
index f63caa9b7..8f0be71b7 100644
--- a/apps/app/src/app/components/model-picker-modal.tsx
+++ b/apps/app/src/app/components/model-picker-modal.tsx
@@ -24,7 +24,6 @@ export type ModelPickerModalProps = {
export default function ModelPickerModal(props: ModelPickerModalProps) {
let searchInputRef: HTMLInputElement | undefined;
- const translate = (key: string, params?: Record) => t(key, undefined, params);
type RenderedItem =
| { kind: "model"; opt: ModelOption }
@@ -306,9 +305,9 @@ export default function ModelPickerModal(props: ModelPickerModalProps) {
{provider.title}
- {translate("model_picker.connect_provider_hint")}
+ {t("model_picker.connect_provider_hint")}
- {translate(provider.matchCount === 1 ? "model_picker.model_count_one" : "model_picker.model_count", { count: provider.matchCount })}
+ {t(provider.matchCount === 1 ? "model_picker.model_count_one" : "model_picker.model_count", { count: provider.matchCount })}
@@ -324,10 +323,10 @@ export default function ModelPickerModal(props: ModelPickerModalProps) {
- {translate(props.target === "default" ? "model_picker.default_model_title" : "model_picker.chat_model_title")}
+ {t(props.target === "default" ? "model_picker.default_model_title" : "model_picker.chat_model_title")}
- {translate(props.target === "default"
+ {t(props.target === "default"
? "model_picker.default_model_desc"
: "model_picker.chat_model_desc")}
@@ -349,13 +348,13 @@ export default function ModelPickerModal(props: ModelPickerModalProps) {
type="text"
value={props.query}
onInput={(e) => props.setQuery(e.currentTarget.value)}
- placeholder={translate("settings.search_models")}
+ placeholder={t("settings.search_models")}
class="w-full bg-dls-surface border border-dls-border rounded-xl py-2.5 pl-9 pr-3 text-sm text-dls-text placeholder:text-dls-secondary focus:outline-none focus:ring-1 focus:ring-[rgba(var(--dls-accent-rgb),0.2)] focus:border-dls-accent"
/>
- {translate("settings.showing_models", { count: props.filteredOptions.length, total: props.options.length })}
+ {t("settings.showing_models", { count: props.filteredOptions.length, total: props.options.length })}
@@ -364,7 +363,7 @@ export default function ModelPickerModal(props: ModelPickerModalProps) {
0}>
- {translate("model_picker.recommended")}
+ {t("model_picker.recommended")}
{({ opt, index }) => renderOption(opt, index)}
@@ -373,7 +372,7 @@ export default function ModelPickerModal(props: ModelPickerModalProps) {
0}>
- {translate("model_picker.other_connected_models")}
+ {t("model_picker.other_connected_models")}
{({ opt, index }) => renderOption(opt, index)}
@@ -382,7 +381,7 @@ export default function ModelPickerModal(props: ModelPickerModalProps) {
0}>
- {translate("model_picker.more_providers")}
+ {t("model_picker.more_providers")}
{(provider) => renderProviderLink(provider, provider.index)}
@@ -392,14 +391,14 @@ export default function ModelPickerModal(props: ModelPickerModalProps) {
- {translate("model_picker.no_results")}
+ {t("model_picker.no_results")}
props.onClose()}>
- {translate("settings.done")}
+ {t("settings.done")}
diff --git a/apps/app/src/app/components/question-modal.tsx b/apps/app/src/app/components/question-modal.tsx
index e77b06420..bdb16c22f 100644
--- a/apps/app/src/app/components/question-modal.tsx
+++ b/apps/app/src/app/components/question-modal.tsx
@@ -141,7 +141,7 @@ export default function QuestionModal(props: QuestionModalProps) {
{currentQuestion()!.header || t("common.question")}
- {t("question_modal.question_counter", undefined, { current: currentIndex() + 1, total: props.questions.length })}
+ {t("question_modal.question_counter", { current: currentIndex() + 1, total: props.questions.length })}
diff --git a/apps/app/src/app/components/rename-session-modal.tsx b/apps/app/src/app/components/rename-session-modal.tsx
index 9bdcde386..d8c3a4c34 100644
--- a/apps/app/src/app/components/rename-session-modal.tsx
+++ b/apps/app/src/app/components/rename-session-modal.tsx
@@ -1,6 +1,6 @@
import { Show, createEffect } from "solid-js";
import { X } from "lucide-solid";
-import { t, currentLocale } from "../../i18n";
+import { t } from "../../i18n";
import Button from "./button";
import TextInput from "./text-input";
@@ -17,7 +17,6 @@ export type RenameSessionModalProps = {
export default function RenameSessionModal(props: RenameSessionModalProps) {
let inputRef: HTMLInputElement | undefined;
- const translate = (key: string) => t(key, currentLocale());
createEffect(() => {
if (props.open) {
@@ -37,8 +36,8 @@ export default function RenameSessionModal(props: RenameSessionModalProps) {
-
{translate("session.rename_title")}
-
{translate("session.rename_description")}
+
{t("session.rename_title")}
+
{t("session.rename_description")}
@@ -48,10 +47,10 @@ export default function RenameSessionModal(props: RenameSessionModalProps) {
props.onTitleChange(e.currentTarget.value)}
- placeholder={translate("session.rename_placeholder")}
+ placeholder={t("session.rename_placeholder")}
class="bg-gray-3"
onKeyDown={(event) => {
if (event.key !== "Enter" || event.isComposing || event.keyCode === 229) return;
@@ -63,10 +62,10 @@ export default function RenameSessionModal(props: RenameSessionModalProps) {
- {translate("common.cancel")}
+ {t("common.cancel")}
- {translate("common.save")}
+ {t("common.save")}
diff --git a/apps/app/src/app/components/rename-workspace-modal.tsx b/apps/app/src/app/components/rename-workspace-modal.tsx
index 3e44e846d..0f37d3f17 100644
--- a/apps/app/src/app/components/rename-workspace-modal.tsx
+++ b/apps/app/src/app/components/rename-workspace-modal.tsx
@@ -1,6 +1,6 @@
import { Show, createEffect } from "solid-js";
import { X } from "lucide-solid";
-import { t, currentLocale } from "../../i18n";
+import { t } from "../../i18n";
import Button from "./button";
import TextInput from "./text-input";
@@ -17,7 +17,6 @@ export type RenameWorkspaceModalProps = {
export default function RenameWorkspaceModal(props: RenameWorkspaceModalProps) {
let inputRef: HTMLInputElement | undefined;
- const translate = (key: string) => t(key, currentLocale());
createEffect(() => {
if (props.open) {
@@ -37,8 +36,8 @@ export default function RenameWorkspaceModal(props: RenameWorkspaceModalProps) {
-
{translate("workspace.rename_title")}
-
{translate("workspace.rename_description")}
+
{t("workspace.rename_title")}
+
{t("workspace.rename_description")}
@@ -48,10 +47,10 @@ export default function RenameWorkspaceModal(props: RenameWorkspaceModalProps) {
props.onTitleChange(e.currentTarget.value)}
- placeholder={translate("workspace.rename_placeholder")}
+ placeholder={t("workspace.rename_placeholder")}
class="bg-gray-3"
onKeyDown={(event) => {
if (event.key !== "Enter" || event.isComposing || event.keyCode === 229) return;
@@ -63,10 +62,10 @@ export default function RenameWorkspaceModal(props: RenameWorkspaceModalProps) {
- {translate("common.cancel")}
+ {t("common.cancel")}
- {translate("common.save")}
+ {t("common.save")}
diff --git a/apps/app/src/app/components/reset-modal.tsx b/apps/app/src/app/components/reset-modal.tsx
index 8dbf05f03..e3533a21f 100644
--- a/apps/app/src/app/components/reset-modal.tsx
+++ b/apps/app/src/app/components/reset-modal.tsx
@@ -23,9 +23,8 @@ export type ResetModalProps = {
};
export default function ResetModal(props: ResetModalProps) {
- const translate = (key: string) => t(key, props.language);
const resetConfirmationHint = () => {
- const template = translate("settings.reset_confirmation_hint");
+ const template = t("settings.reset_confirmation_hint");
const parts = template.split(RESET_CONFIRM_PLACEHOLDER);
if (parts.length === 1) return template;
@@ -46,8 +45,8 @@ export default function ResetModal(props: ResetModalProps) {
- {translate("settings.reset_onboarding_title")}
- {translate("settings.reset_app_data_title")}
+ {t("settings.reset_onboarding_title")}
+ {t("settings.reset_app_data_title")}
{resetConfirmationHint()}
@@ -66,19 +65,19 @@ export default function ResetModal(props: ResetModalProps) {
- {translate("settings.reset_onboarding_warning")}
+ {t("settings.reset_onboarding_warning")}
- {translate("settings.reset_app_data_warning")}
+ {t("settings.reset_app_data_warning")}
- {translate("settings.reset_stop_active_runs")}
+ {t("settings.reset_stop_active_runs")}
props.onTextChange(e.currentTarget.value)}
disabled={props.busy}
@@ -87,10 +86,10 @@ export default function ResetModal(props: ResetModalProps) {
- {translate("settings.reset_cancel")}
+ {t("settings.reset_cancel")}
- {translate("settings.reset_confirm_button")}
+ {t("settings.reset_confirm_button")}
diff --git a/apps/app/src/app/components/session/composer.tsx b/apps/app/src/app/components/session/composer.tsx
index 4381dae2d..158f49c5b 100644
--- a/apps/app/src/app/components/session/composer.tsx
+++ b/apps/app/src/app/components/session/composer.tsx
@@ -1309,7 +1309,7 @@ export default function Composer(props: ComposerProps) {
for (const file of supportedFiles) {
if (file.size > MAX_ATTACHMENT_BYTES) {
props.onNotice({
- title: t("composer.file_exceeds_limit", undefined, {
+ title: t("composer.file_exceeds_limit", {
name: file.name,
}),
tone: "warning",
diff --git a/apps/app/src/app/components/session/message-list.tsx b/apps/app/src/app/components/session/message-list.tsx
index 0644c97cd..1073ea762 100644
--- a/apps/app/src/app/components/session/message-list.tsx
+++ b/apps/app/src/app/components/session/message-list.tsx
@@ -229,39 +229,39 @@ function toolHeadline(part: Part) {
const description = pick("description");
if (description) return compactText(description);
const command = pick("command", "cmd");
- return command ? compactText(t("message_list.tool_run_command", undefined, { command }), 48) : t("message_list.tool_run_command_fallback");
+ return command ? compactText(t("message_list.tool_run_command", { command }), 48) : t("message_list.tool_run_command_fallback");
}
if (tool === "read") {
const file = target("filePath", "path", "file");
- return file ? t("message_list.tool_reviewed_file", undefined, { file }) : t("message_list.tool_reviewed_file_fallback");
+ return file ? t("message_list.tool_reviewed_file", { file }) : t("message_list.tool_reviewed_file_fallback");
}
if (tool === "edit") {
const file = target("filePath", "path", "file");
- return file ? t("message_list.tool_updated_file", undefined, { file }) : t("message_list.tool_updated_file_fallback");
+ return file ? t("message_list.tool_updated_file", { file }) : t("message_list.tool_updated_file_fallback");
}
if (tool === "write" || tool === "apply_patch") {
const file = target("filePath", "path", "file");
- return file ? t("message_list.tool_update_file", undefined, { file }) : t("message_list.tool_update_file_fallback");
+ return file ? t("message_list.tool_update_file", { file }) : t("message_list.tool_update_file_fallback");
}
if (tool === "grep" || tool === "glob" || tool === "search") {
const pattern = pick("pattern", "query");
- return pattern ? t("message_list.tool_searched_pattern", undefined, { pattern: compactText(pattern, 36) }) : t("message_list.tool_searched_code_fallback");
+ return pattern ? t("message_list.tool_searched_pattern", { pattern: compactText(pattern, 36) }) : t("message_list.tool_searched_code_fallback");
}
if (tool === "list" || tool === "list_files") {
const path = target("path");
- return path ? t("message_list.tool_reviewed_path", undefined, { path }) : t("message_list.tool_reviewed_files_fallback");
+ return path ? t("message_list.tool_reviewed_path", { path }) : t("message_list.tool_reviewed_files_fallback");
}
if (tool === "task") {
const description = pick("description");
if (description) return compactText(description);
const agent = pick("subagent_type");
- return agent ? t("message_list.tool_delegate_agent", undefined, { agent }) : t("message_list.tool_delegate_task_fallback");
+ return agent ? t("message_list.tool_delegate_agent", { agent }) : t("message_list.tool_delegate_task_fallback");
}
if (tool === "todowrite") {
@@ -274,12 +274,12 @@ function toolHeadline(part: Part) {
if (tool === "webfetch") {
const url = pick("url");
- return url ? t("message_list.tool_checked_url", undefined, { url: compactText(url, 36) }) : t("message_list.tool_checked_web_fallback");
+ return url ? t("message_list.tool_checked_url", { url: compactText(url, 36) }) : t("message_list.tool_checked_web_fallback");
}
if (tool === "skill") {
const name = pick("name");
- return name ? t("message_list.tool_load_skill_named", undefined, { name }) : t("message_list.tool_load_skill_fallback");
+ return name ? t("message_list.tool_load_skill_named", { name }) : t("message_list.tool_load_skill_fallback");
}
const fallback = tool
@@ -696,7 +696,7 @@ export default function MessageList(props: MessageListProps) {
const title = session()?.title?.trim();
if (title) return title;
if (task().description) return task().description!;
- if (task().agentType) return t("message_list.subagent_type_task", undefined, { agentType: task().agentType! });
+ if (task().agentType) return t("message_list.subagent_type_task", { agentType: task().agentType! });
return t("message_list.subagent_session_fallback");
});
const statusLabel = createMemo(() => {
@@ -704,7 +704,7 @@ export default function MessageList(props: MessageListProps) {
if (streaming()) return t("message_list.subagent_running");
if (childMessages().length > 0) {
const count = childMessages().length;
- return t("message_list.subagent_message_count", undefined, { count, plural: count === 1 ? "" : "s" });
+ return t("message_list.subagent_message_count", { count, plural: count === 1 ? "" : "s" });
}
return t("message_list.subagent_waiting_transcript");
});
diff --git a/apps/app/src/app/components/session/workspace-session-list.tsx b/apps/app/src/app/components/session/workspace-session-list.tsx
index f79e7576c..6c2e35c87 100644
--- a/apps/app/src/app/components/session/workspace-session-list.tsx
+++ b/apps/app/src/app/components/session/workspace-session-list.tsx
@@ -283,7 +283,7 @@ export default function WorkspaceSessionList(props: Props) {
const showMoreLabel = (workspaceId: string, totalRoots: number) => {
const remaining = Math.max(0, totalRoots - previewCount(workspaceId));
const nextCount = Math.min(MAX_SESSIONS_PREVIEW, remaining);
- return nextCount > 0 ? t("workspace_list.show_more", undefined, { count: nextCount }) : t("workspace_list.show_more_fallback");
+ return nextCount > 0 ? t("workspace_list.show_more", { count: nextCount }) : t("workspace_list.show_more_fallback");
};
createEffect(() => {
diff --git a/apps/app/src/app/components/status-bar.tsx b/apps/app/src/app/components/status-bar.tsx
index bc556cf86..d4234ed61 100644
--- a/apps/app/src/app/components/status-bar.tsx
+++ b/apps/app/src/app/components/status-bar.tsx
@@ -45,10 +45,10 @@ export default function StatusBar(props: StatusBarProps) {
if (props.clientConnected) {
const detailBits: string[] = [];
if (providers > 0) {
- detailBits.push(t("status.providers_connected", undefined, { count: providers, plural: providers === 1 ? "" : "s" }));
+ detailBits.push(t("status.providers_connected", { count: providers, plural: providers === 1 ? "" : "s" }));
}
if (mcp > 0) {
- detailBits.push(t("status.mcp_connected", undefined, { count: mcp }));
+ detailBits.push(t("status.mcp_connected", { count: mcp }));
}
if (!detailBits.length) {
detailBits.push(t("status.ready_for_tasks"));
@@ -70,7 +70,7 @@ export default function StatusBar(props: StatusBarProps) {
label: t("status.limited_mode"),
detail:
mcp > 0
- ? t("status.limited_mcp_hint", undefined, { count: mcp })
+ ? t("status.limited_mcp_hint", { count: mcp })
: t("status.limited_hint"),
dotClass: "bg-amber-9",
pingClass: "bg-amber-9/35",
diff --git a/apps/app/src/app/connections/openwork-server-store.ts b/apps/app/src/app/connections/openwork-server-store.ts
index 539d113fd..83bbb7c18 100644
--- a/apps/app/src/app/connections/openwork-server-store.ts
+++ b/apps/app/src/app/connections/openwork-server-store.ts
@@ -1,6 +1,6 @@
import { createEffect, createMemo, createSignal, onCleanup, type Accessor } from "solid-js";
-import { t, currentLocale } from "../../i18n";
+import { t } from "../../i18n";
import type { StartupPreference, WorkspaceDisplay } from "../types";
import { isTauriRuntime } from "../utils";
import {
@@ -470,7 +470,7 @@ export function createOpenworkServerStore(options: {
if (!active) return;
setOpenworkAuditEntries([]);
setOpenworkAuditStatus("error");
- setOpenworkAuditError(error instanceof Error ? error.message : t("app.error_audit_load", currentLocale()));
+ setOpenworkAuditError(error instanceof Error ? error.message : t("app.error_audit_load"));
} finally {
busy = false;
}
@@ -620,7 +620,7 @@ export function createOpenworkServerStore(options: {
if (isTauriRuntime() && options.selectedWorkspaceDisplay().workspaceType === "local") {
const restarted = await options.restartLocalServer();
if (!restarted) {
- throw new Error(t("app.error_restart_local_worker", currentLocale()));
+ throw new Error(t("app.error_restart_local_worker"));
}
await reconnectOpenworkServer();
}
@@ -629,7 +629,7 @@ export function createOpenworkServerStore(options: {
setShareRemoteAccessError(
error instanceof Error
? error.message
- : t("app.error_remote_access", currentLocale()),
+ : t("app.error_remote_access"),
);
return;
} finally {
diff --git a/apps/app/src/app/connections/store.ts b/apps/app/src/app/connections/store.ts
index de49b3386..009bceba2 100644
--- a/apps/app/src/app/connections/store.ts
+++ b/apps/app/src/app/connections/store.ts
@@ -3,7 +3,7 @@ import { createEffect, createSignal } from "solid-js";
import { homeDir } from "@tauri-apps/api/path";
import { parse } from "jsonc-parser";
-import { currentLocale, t } from "../../i18n";
+import { t } from "../../i18n";
import { CHROME_DEVTOOLS_MCP_ID, MCP_QUICK_CONNECT, type McpDirectoryInfo } from "../constants";
import { createClient, unwrap } from "../lib/opencode";
import { finishPerf, perfNow, recordPerfLog } from "../lib/perf-log";
@@ -36,7 +36,6 @@ export function createConnectionsStore(options: {
developerMode: () => boolean;
markReloadRequired?: (reason: ReloadReason, trigger?: ReloadTrigger) => void;
}) {
- const translate = (key: string) => t(key, currentLocale());
const [mcpServers, setMcpServers] = createSignal([]);
const [mcpStatus, setMcpStatus] = createSignal(null);
@@ -94,7 +93,7 @@ export function createConnectionsStore(options: {
return null;
}
- activeClient = createClient(`${openworkBaseUrl.replace(/\/+$/, "")}/opencode`, undefined, {
+ activeClient = createClient(`${openworkBaseUrl.replace(/\/+$/, "")}/opencode`, {
token,
mode: "openwork",
});
@@ -303,7 +302,7 @@ export function createConnectionsStore(options: {
}
if (!canUseOpenworkServer && !isTauriRuntime()) {
- setMcpStatus(translate("mcp.desktop_required"));
+ setMcpStatus(t("mcp.desktop_required"));
finishPerf(options.developerMode(), "mcp.connect", "blocked", startedAt, {
reason: "desktop-required",
});
@@ -311,7 +310,7 @@ export function createConnectionsStore(options: {
}
if (!isRemoteWorkspace && !projectDir) {
- setMcpStatus(translate("mcp.pick_workspace_first"));
+ setMcpStatus(t("mcp.pick_workspace_first"));
finishPerf(options.developerMode(), "mcp.connect", "blocked", startedAt, {
reason: "missing-workspace",
});
@@ -320,7 +319,7 @@ export function createConnectionsStore(options: {
const activeClient = await ensureActiveClient();
if (!activeClient) {
- setMcpStatus(translate("mcp.connect_server_first"));
+ setMcpStatus(t("mcp.connect_server_first"));
finishPerf(options.developerMode(), "mcp.connect", "blocked", startedAt, {
reason: "no-active-client",
});
@@ -329,7 +328,7 @@ export function createConnectionsStore(options: {
const resolvedProjectDir = await resolveProjectDir(activeClient, projectDir);
if (!resolvedProjectDir) {
- setMcpStatus(translate("mcp.pick_workspace_first"));
+ setMcpStatus(t("mcp.pick_workspace_first"));
finishPerf(options.developerMode(), "mcp.connect", "blocked", startedAt, {
reason: "missing-workspace-after-discovery",
});
@@ -449,7 +448,7 @@ export function createConnectionsStore(options: {
setMcpAuthNeedsReload(true);
setMcpAuthModalOpen(true);
} else {
- setMcpStatus(translate("mcp.connected"));
+ setMcpStatus(t("mcp.connected"));
}
await refreshMcpServers();
@@ -459,7 +458,7 @@ export function createConnectionsStore(options: {
slug,
});
} catch (e) {
- setMcpStatus(e instanceof Error ? e.message : translate("mcp.connect_failed"));
+ setMcpStatus(e instanceof Error ? e.message : t("mcp.connect_failed"));
finishPerf(options.developerMode(), "mcp.connect", "error", startedAt, {
name: entry.name,
type: entryType,
@@ -472,7 +471,7 @@ export function createConnectionsStore(options: {
function authorizeMcp(entry: McpServerEntry) {
if (entry.config.type !== "remote" || entry.config.oauth === false) {
- setMcpStatus(translate("mcp.login_unavailable"));
+ setMcpStatus(t("mcp.login_unavailable"));
return;
}
@@ -508,19 +507,19 @@ export function createConnectionsStore(options: {
}
if (!canUseOpenworkServer && !isTauriRuntime()) {
- setMcpStatus(translate("mcp.desktop_required"));
+ setMcpStatus(t("mcp.desktop_required"));
return;
}
const activeClient = await ensureActiveClient();
if (!activeClient) {
- setMcpStatus(translate("mcp.connect_server_first"));
+ setMcpStatus(t("mcp.connect_server_first"));
return;
}
const resolvedProjectDir = await resolveProjectDir(activeClient, projectDir);
if (!resolvedProjectDir) {
- setMcpStatus(translate("mcp.pick_workspace_first"));
+ setMcpStatus(t("mcp.pick_workspace_first"));
return;
}
@@ -547,9 +546,9 @@ export function createConnectionsStore(options: {
}
await refreshMcpServers();
- setMcpStatus(translate("mcp.logout_success").replace("{server}", safeName));
+ setMcpStatus(t("mcp.logout_success").replace("{server}", safeName));
} catch (e) {
- setMcpStatus(e instanceof Error ? e.message : translate("mcp.logout_failed"));
+ setMcpStatus(e instanceof Error ? e.message : t("mcp.logout_failed"));
}
}
@@ -570,7 +569,7 @@ export function createConnectionsStore(options: {
} else {
const projectDir = options.projectDir().trim();
if (!projectDir) {
- setMcpStatus(translate("mcp.pick_workspace_first"));
+ setMcpStatus(t("mcp.pick_workspace_first"));
return;
}
await removeMcpFromConfig(projectDir, name);
@@ -583,7 +582,7 @@ export function createConnectionsStore(options: {
}
setMcpStatus(null);
} catch (e) {
- setMcpStatus(e instanceof Error ? e.message : translate("mcp.remove_failed"));
+ setMcpStatus(e instanceof Error ? e.message : t("mcp.remove_failed"));
}
}
diff --git a/apps/app/src/app/context/extensions.ts b/apps/app/src/app/context/extensions.ts
index de69ad8e9..6b06f7a91 100644
--- a/apps/app/src/app/context/extensions.ts
+++ b/apps/app/src/app/context/extensions.ts
@@ -2,7 +2,7 @@ import { createEffect, createMemo, createSignal } from "solid-js";
import { applyEdits, modify } from "jsonc-parser";
import { join } from "@tauri-apps/api/path";
-import { currentLocale, t } from "../../i18n";
+import { t } from "../../i18n";
import type { Client, DenOrgSkillCard, HubSkillCard, HubSkillRepo, PluginScope, ReloadReason, ReloadTrigger, SkillCard } from "../types";
import { addOpencodeCacheHint, isTauriRuntime } from "../utils";
@@ -96,7 +96,6 @@ export function createExtensionsStore(options: {
markReloadRequired?: (reason: ReloadReason, trigger?: ReloadTrigger) => void;
}) {
// Translation helper that uses current language from i18n
- const translate = (key: string) => t(key, currentLocale());
// ── Workspace context tracking ──────────────────────
const workspaceContextKey = createWorkspaceContextKey({
@@ -335,18 +334,18 @@ export function createExtensionsStore(options: {
}
if (!isTauriRuntime()) {
- throw new Error(translate("skills.desktop_required"));
+ throw new Error(t("skills.desktop_required"));
}
if (!isLocalWorkspace || !root) {
- throw new Error(translate("skills.pick_workspace_first"));
+ throw new Error(t("skills.pick_workspace_first"));
}
const result = await installSkillTemplate(root, name, content, {
overwrite: optionsOverride?.overwrite ?? false,
});
if (!result.ok) {
- throw new Error(result.stderr || result.stdout || translate("skills.install_failed"));
+ throw new Error(result.stderr || result.stdout || t("skills.install_failed"));
}
};
@@ -428,16 +427,16 @@ export function createExtensionsStore(options: {
}
if (!isTauriRuntime()) {
- throw new Error(translate("skills.desktop_required"));
+ throw new Error(t("skills.desktop_required"));
}
if (!isLocalWorkspace || !root) {
- throw new Error(translate("skills.pick_workspace_first"));
+ throw new Error(t("skills.pick_workspace_first"));
}
const result = await uninstallSkillCommand(root, name);
if (!result.ok) {
- throw new Error(result.stderr || result.stdout || translate("skills.uninstall_failed"));
+ throw new Error(result.stderr || result.stdout || t("skills.uninstall_failed"));
}
};
@@ -666,7 +665,7 @@ export function createExtensionsStore(options: {
if (refreshCloudOrgSkillsAborted) return;
setCloudOrgSkills(catalog);
if (!catalog.length) {
- setCloudOrgSkillsStatus(translate("skills.cloud_org_empty"));
+ setCloudOrgSkillsStatus(t("skills.cloud_org_empty"));
}
cloudOrgSkillsLoaded = true;
cloudOrgSkillsLoadKey = loadKey;
@@ -674,7 +673,7 @@ export function createExtensionsStore(options: {
} catch (e) {
if (refreshCloudOrgSkillsAborted) return;
setCloudOrgSkills([]);
- setCloudOrgSkillsStatus(e instanceof Error ? e.message : translate("skills.cloud_org_load_failed"));
+ setCloudOrgSkillsStatus(e instanceof Error ? e.message : t("skills.cloud_org_load_failed"));
} finally {
refreshCloudOrgSkillsInFlight = false;
}
@@ -771,7 +770,7 @@ export function createExtensionsStore(options: {
importedNames,
};
} catch (e) {
- const message = e instanceof Error ? e.message : translate("skills.unknown_error");
+ const message = e instanceof Error ? e.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
return { ok: false, message, importedNames };
} finally {
@@ -818,7 +817,7 @@ export function createExtensionsStore(options: {
importedNames: applied.nextSkillNames,
};
} catch (e) {
- const message = e instanceof Error ? e.message : translate("skills.unknown_error");
+ const message = e instanceof Error ? e.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
return { ok: false, message, importedNames: [] };
} finally {
@@ -860,7 +859,7 @@ export function createExtensionsStore(options: {
removedNames: imported.skillNames,
};
} catch (e) {
- const message = e instanceof Error ? e.message : translate("skills.unknown_error");
+ const message = e instanceof Error ? e.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
return { ok: false, message, removedNames: [] };
} finally {
@@ -914,7 +913,7 @@ export function createExtensionsStore(options: {
}
return { ok: true, message: `Installed ${trimmed}.` };
} catch (e) {
- const message = e instanceof Error ? e.message : translate("skills.unknown_error");
+ const message = e instanceof Error ? e.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
return { ok: false, message };
} finally {
@@ -944,9 +943,9 @@ export function createExtensionsStore(options: {
});
await refreshSkills({ force: true });
await refreshCloudOrgSkills({ force: true });
- return { ok: true, message: t("skills.cloud_installed", currentLocale(), { name: installName }) };
+ return { ok: true, message: t("skills.cloud_installed", { name: installName }) };
} catch (e) {
- const message = e instanceof Error ? e.message : translate("skills.unknown_error");
+ const message = e instanceof Error ? e.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
return { ok: false, message };
} finally {
@@ -976,7 +975,7 @@ export function createExtensionsStore(options: {
if (!root) {
setSkills([]);
- setSkillsStatus(translate("skills.pick_workspace_first"));
+ setSkillsStatus(t("skills.pick_workspace_first"));
return;
}
@@ -1013,7 +1012,7 @@ export function createExtensionsStore(options: {
: [];
setSkills(next);
if (!next.length) {
- setSkillsStatus(translate("skills.no_skills_found"));
+ setSkillsStatus(t("skills.no_skills_found"));
}
skillsLoaded = true;
skillsRoot = root;
@@ -1021,7 +1020,7 @@ export function createExtensionsStore(options: {
} catch (e) {
if (refreshSkillsAborted) return;
setSkills([]);
- setSkillsStatus(e instanceof Error ? e.message : translate("skills.failed_to_load"));
+ setSkillsStatus(e instanceof Error ? e.message : t("skills.failed_to_load"));
} finally {
refreshSkillsInFlight = false;
}
@@ -1063,7 +1062,7 @@ export function createExtensionsStore(options: {
setSkills(next);
if (!next.length) {
- setSkillsStatus(translate("skills.no_skills_found"));
+ setSkillsStatus(t("skills.no_skills_found"));
}
skillsLoaded = true;
skillsRoot = root;
@@ -1071,7 +1070,7 @@ export function createExtensionsStore(options: {
} catch (e) {
if (refreshSkillsAborted) return;
setSkills([]);
- setSkillsStatus(e instanceof Error ? e.message : translate("skills.failed_to_load"));
+ setSkillsStatus(e instanceof Error ? e.message : t("skills.failed_to_load"));
} finally {
refreshSkillsInFlight = false;
}
@@ -1115,7 +1114,7 @@ export function createExtensionsStore(options: {
if (result?.data === undefined) {
const err = result?.error;
const message =
- err instanceof Error ? err.message : typeof err === "string" ? err : translate("skills.failed_to_load");
+ err instanceof Error ? err.message : typeof err === "string" ? err : t("skills.failed_to_load");
throw new Error(message);
}
const data = result.data as Array<{
@@ -1136,7 +1135,7 @@ export function createExtensionsStore(options: {
setSkills(next);
if (!next.length) {
- setSkillsStatus(translate("skills.no_skills_found"));
+ setSkillsStatus(t("skills.no_skills_found"));
}
skillsLoaded = true;
skillsRoot = root;
@@ -1144,7 +1143,7 @@ export function createExtensionsStore(options: {
} catch (e) {
if (refreshSkillsAborted) return;
setSkills([]);
- setSkillsStatus(e instanceof Error ? e.message : translate("skills.failed_to_load"));
+ setSkillsStatus(e instanceof Error ? e.message : t("skills.failed_to_load"));
} finally {
refreshSkillsInFlight = false;
}
@@ -1218,9 +1217,9 @@ export function createExtensionsStore(options: {
}
if (!isTauriRuntime()) {
- setPluginStatus(translate("skills.plugin_management_host_only"));
+ setPluginStatus(t("skills.plugin_management_host_only"));
setPluginList([]);
- setSidebarPluginStatus(translate("skills.plugins_host_only"));
+ setSidebarPluginStatus(t("skills.plugins_host_only"));
setSidebarPluginList([]);
refreshPluginsInFlight = false;
return;
@@ -1236,9 +1235,9 @@ export function createExtensionsStore(options: {
}
if (scope === "project" && !targetDir) {
- setPluginStatus(translate("skills.pick_project_for_plugins"));
+ setPluginStatus(t("skills.pick_project_for_plugins"));
setPluginList([]);
- setSidebarPluginStatus(translate("skills.pick_project_for_active"));
+ setSidebarPluginStatus(t("skills.pick_project_for_active"));
setSidebarPluginList([]);
refreshPluginsInFlight = false;
return;
@@ -1259,9 +1258,9 @@ export function createExtensionsStore(options: {
if (!config.exists) {
setPluginList([]);
- setPluginStatus(translate("skills.no_opencode_found"));
+ setPluginStatus(t("skills.no_opencode_found"));
setSidebarPluginList([]);
- setSidebarPluginStatus(translate("skills.no_opencode_workspace"));
+ setSidebarPluginStatus(t("skills.no_opencode_workspace"));
return;
}
@@ -1270,7 +1269,7 @@ export function createExtensionsStore(options: {
setSidebarPluginList(next);
} catch {
setSidebarPluginList([]);
- setSidebarPluginStatus(translate("skills.failed_parse_opencode"));
+ setSidebarPluginStatus(t("skills.failed_parse_opencode"));
}
loadPluginsFromConfig(config);
@@ -1280,8 +1279,8 @@ export function createExtensionsStore(options: {
setPluginConfig(null);
setPluginConfigPath(null);
setPluginList([]);
- setPluginStatus(e instanceof Error ? e.message : translate("skills.failed_load_opencode"));
- setSidebarPluginStatus(translate("skills.failed_load_active"));
+ setPluginStatus(e instanceof Error ? e.message : t("skills.failed_load_opencode"));
+ setSidebarPluginStatus(t("skills.failed_load_active"));
setSidebarPluginList([]);
} finally {
refreshPluginsInFlight = false;
@@ -1306,7 +1305,7 @@ export function createExtensionsStore(options: {
if (!pluginName) {
if (isManualInput) {
- setPluginStatus(translate("skills.enter_plugin_name"));
+ setPluginStatus(t("skills.enter_plugin_name"));
}
return;
}
@@ -1332,7 +1331,7 @@ export function createExtensionsStore(options: {
}
if (!isTauriRuntime()) {
- setPluginStatus(translate("skills.plugin_management_host_only"));
+ setPluginStatus(t("skills.plugin_management_host_only"));
return;
}
@@ -1345,7 +1344,7 @@ export function createExtensionsStore(options: {
const targetDir = options.projectDir().trim();
if (scope === "project" && !targetDir) {
- setPluginStatus(translate("skills.pick_project_for_plugins"));
+ setPluginStatus(t("skills.pick_project_for_plugins"));
return;
}
@@ -1372,7 +1371,7 @@ export function createExtensionsStore(options: {
const desired = stripPluginVersion(pluginName).toLowerCase();
if (plugins.some((entry) => stripPluginVersion(entry).toLowerCase() === desired)) {
- setPluginStatus(translate("skills.plugin_already_listed"));
+ setPluginStatus(t("skills.plugin_already_listed"));
return;
}
@@ -1389,7 +1388,7 @@ export function createExtensionsStore(options: {
}
await refreshPlugins(scope);
} catch (e) {
- setPluginStatus(e instanceof Error ? e.message : translate("skills.failed_update_opencode"));
+ setPluginStatus(e instanceof Error ? e.message : t("skills.failed_update_opencode"));
}
}
@@ -1427,7 +1426,7 @@ export function createExtensionsStore(options: {
}
if (!isTauriRuntime()) {
- setPluginStatus(translate("skills.plugin_management_host_only"));
+ setPluginStatus(t("skills.plugin_management_host_only"));
return;
}
@@ -1440,7 +1439,7 @@ export function createExtensionsStore(options: {
const targetDir = options.projectDir().trim();
if (scope === "project" && !targetDir) {
- setPluginStatus(translate("skills.pick_project_for_plugins"));
+ setPluginStatus(t("skills.pick_project_for_plugins"));
return;
}
@@ -1469,7 +1468,7 @@ export function createExtensionsStore(options: {
options.markReloadRequired?.("plugins", { type: "plugin", name: triggerName, action: "removed" });
await refreshPlugins(scope);
} catch (e) {
- setPluginStatus(e instanceof Error ? e.message : translate("skills.failed_update_opencode"));
+ setPluginStatus(e instanceof Error ? e.message : t("skills.failed_update_opencode"));
}
}
@@ -1477,7 +1476,7 @@ export function createExtensionsStore(options: {
const isLocalWorkspace = options.workspaceType() === "local";
if (!isTauriRuntime()) {
- options.setError(translate("skills.desktop_required"));
+ options.setError(t("skills.desktop_required"));
return;
}
@@ -1488,7 +1487,7 @@ export function createExtensionsStore(options: {
const targetDir = options.projectDir().trim();
if (!targetDir) {
- options.setError(translate("skills.pick_project_first"));
+ options.setError(t("skills.pick_project_first"));
return;
}
@@ -1497,7 +1496,7 @@ export function createExtensionsStore(options: {
setSkillsStatus(null);
try {
- const selection = await pickDirectory({ title: translate("skills.select_skill_folder") });
+ const selection = await pickDirectory({ title: t("skills.select_skill_folder") });
const sourceDir = typeof selection === "string" ? selection : Array.isArray(selection) ? selection[0] : null;
if (!sourceDir) {
@@ -1507,9 +1506,9 @@ export function createExtensionsStore(options: {
const inferredName = sourceDir.split(/[\\/]/).filter(Boolean).pop();
const result = await importSkill(targetDir, sourceDir, { overwrite: false });
if (!result.ok) {
- setSkillsStatus(result.stderr || result.stdout || translate("skills.import_failed").replace("{status}", String(result.status)));
+ setSkillsStatus(result.stderr || result.stdout || t("skills.import_failed").replace("{status}", String(result.status)));
} else {
- setSkillsStatus(result.stdout || translate("skills.imported"));
+ setSkillsStatus(result.stdout || t("skills.imported"));
options.markReloadRequired?.("skills", {
type: "skill",
name: inferredName,
@@ -1519,7 +1518,7 @@ export function createExtensionsStore(options: {
await refreshSkills({ force: true });
} catch (e) {
- const message = e instanceof Error ? e.message : translate("skills.unknown_error");
+ const message = e instanceof Error ? e.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
} finally {
options.setBusy(false);
@@ -1542,20 +1541,20 @@ export function createExtensionsStore(options: {
if (canUseOpenworkServer) {
options.setBusy(true);
options.setError(null);
- setSkillsStatus(translate("skills.installing_skill_creator"));
+ setSkillsStatus(t("skills.installing_skill_creator"));
try {
await openworkClient.upsertSkill(openworkWorkspaceId, {
name: "skill-creator",
content: skillCreatorTemplate,
});
- const message = translate("skills.skill_creator_installed");
+ const message = t("skills.skill_creator_installed");
setSkillsStatus(message);
options.markReloadRequired?.("skills", { type: "skill", name: "skill-creator", action: "added" });
await refreshSkills({ force: true });
return { ok: true, message };
} catch (e) {
- const raw = e instanceof Error ? e.message : translate("skills.unknown_error");
+ const raw = e instanceof Error ? e.message : t("skills.unknown_error");
const message = addOpencodeCacheHint(raw);
// Ensure we show feedback on the Skills page (not just the global error banner).
setSkillsStatus(message);
@@ -1574,7 +1573,7 @@ export function createExtensionsStore(options: {
}
if (!isTauriRuntime()) {
- const message = translate("skills.desktop_required");
+ const message = t("skills.desktop_required");
setSkillsStatus(message);
return { ok: false, message };
}
@@ -1588,37 +1587,37 @@ export function createExtensionsStore(options: {
const targetDir = options.selectedWorkspaceRoot().trim();
if (!targetDir) {
- const message = translate("skills.pick_workspace_first");
+ const message = t("skills.pick_workspace_first");
setSkillsStatus(message);
return { ok: false, message };
}
options.setBusy(true);
options.setError(null);
- setSkillsStatus(translate("skills.installing_skill_creator"));
+ setSkillsStatus(t("skills.installing_skill_creator"));
try {
const result = await installSkillTemplate(targetDir, "skill-creator", skillCreatorTemplate, { overwrite: false });
if (!result.ok && /already exists/i.test(result.stderr)) {
- const message = translate("skills.skill_creator_already_installed");
+ const message = t("skills.skill_creator_already_installed");
setSkillsStatus(message);
await refreshSkills({ force: true });
return { ok: true, message };
} else if (!result.ok) {
- const message = result.stderr || result.stdout || translate("skills.install_failed");
+ const message = result.stderr || result.stdout || t("skills.install_failed");
setSkillsStatus(message);
await refreshSkills({ force: true });
return { ok: false, message };
} else {
- const message = result.stdout || translate("skills.skill_creator_installed");
+ const message = result.stdout || t("skills.skill_creator_installed");
setSkillsStatus(message);
options.markReloadRequired?.("skills", { type: "skill", name: "skill-creator", action: "added" });
await refreshSkills({ force: true });
return { ok: true, message };
}
} catch (e) {
- const raw = e instanceof Error ? e.message : translate("skills.unknown_error");
+ const raw = e instanceof Error ? e.message : t("skills.unknown_error");
const message = addOpencodeCacheHint(raw);
setSkillsStatus(message);
options.setError(message);
@@ -1628,18 +1627,18 @@ export function createExtensionsStore(options: {
}
// Should be unreachable, but keep TS happy.
- return { ok: false, message: translate("skills.install_failed") };
+ return { ok: false, message: t("skills.install_failed") };
}
async function revealSkillsFolder() {
if (!isTauriRuntime()) {
- setSkillsStatus(translate("skills.desktop_required"));
+ setSkillsStatus(t("skills.desktop_required"));
return;
}
const root = options.selectedWorkspaceRoot().trim();
if (!root) {
- setSkillsStatus(translate("skills.pick_workspace_first"));
+ setSkillsStatus(t("skills.pick_workspace_first"));
return;
}
@@ -1664,14 +1663,14 @@ export function createExtensionsStore(options: {
if (await tryOpen(legacySkills)) return;
await revealItemInDir(opencodeSkills);
} catch (e) {
- setSkillsStatus(e instanceof Error ? e.message : translate("skills.reveal_failed"));
+ setSkillsStatus(e instanceof Error ? e.message : t("skills.reveal_failed"));
}
}
async function uninstallSkill(name: string) {
const root = options.selectedWorkspaceRoot().trim();
if (!root) {
- setSkillsStatus(translate("skills.pick_workspace_first"));
+ setSkillsStatus(t("skills.pick_workspace_first"));
return;
}
@@ -1686,11 +1685,11 @@ export function createExtensionsStore(options: {
try {
await deleteWorkspaceSkill(trimmed);
- setSkillsStatus(translate("skills.uninstalled"));
+ setSkillsStatus(t("skills.uninstalled"));
options.markReloadRequired?.("skills", { type: "skill", name: trimmed, action: "removed" });
await refreshSkills({ force: true });
} catch (e) {
- const message = e instanceof Error ? e.message : translate("skills.unknown_error");
+ const message = e instanceof Error ? e.message : t("skills.unknown_error");
setSkillsStatus(message);
options.setError(addOpencodeCacheHint(message));
} finally {
@@ -1704,7 +1703,7 @@ export function createExtensionsStore(options: {
const root = options.selectedWorkspaceRoot().trim();
if (!root) {
- setSkillsStatus(translate("skills.pick_workspace_first"));
+ setSkillsStatus(t("skills.pick_workspace_first"));
return null;
}
@@ -1734,7 +1733,7 @@ export function createExtensionsStore(options: {
content: result.content,
};
} catch (e) {
- setSkillsStatus(e instanceof Error ? e.message : translate("skills.failed_to_load"));
+ setSkillsStatus(e instanceof Error ? e.message : t("skills.failed_to_load"));
return null;
}
}
@@ -1745,7 +1744,7 @@ export function createExtensionsStore(options: {
}
if (!isTauriRuntime()) {
- setSkillsStatus(translate("skills.desktop_required"));
+ setSkillsStatus(t("skills.desktop_required"));
return null;
}
@@ -1759,7 +1758,7 @@ export function createExtensionsStore(options: {
const result = await readLocalSkill(root, trimmed);
return { name: trimmed, path: result.path, content: result.content };
} catch (e) {
- setSkillsStatus(e instanceof Error ? e.message : translate("skills.failed_to_load"));
+ setSkillsStatus(e instanceof Error ? e.message : t("skills.failed_to_load"));
return null;
}
}
@@ -1770,7 +1769,7 @@ export function createExtensionsStore(options: {
const root = options.selectedWorkspaceRoot().trim();
if (!root) {
- setSkillsStatus(translate("skills.pick_workspace_first"));
+ setSkillsStatus(t("skills.pick_workspace_first"));
return;
}
@@ -1799,7 +1798,7 @@ export function createExtensionsStore(options: {
await refreshSkills({ force: true });
setSkillsStatus("Saved.");
} catch (e) {
- const message = e instanceof Error ? e.message : translate("skills.unknown_error");
+ const message = e instanceof Error ? e.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
} finally {
options.setBusy(false);
@@ -1813,7 +1812,7 @@ export function createExtensionsStore(options: {
}
if (!isTauriRuntime()) {
- setSkillsStatus(translate("skills.desktop_required"));
+ setSkillsStatus(t("skills.desktop_required"));
return;
}
@@ -1828,14 +1827,14 @@ export function createExtensionsStore(options: {
try {
const result = await writeLocalSkill(root, trimmed, input.content);
if (!result.ok) {
- setSkillsStatus(result.stderr || result.stdout || translate("skills.unknown_error"));
+ setSkillsStatus(result.stderr || result.stdout || t("skills.unknown_error"));
} else {
setSkillsStatus(result.stdout || "Saved.");
options.markReloadRequired?.("skills", { type: "skill", name: trimmed, action: "updated" });
}
await refreshSkills({ force: true });
} catch (e) {
- const message = e instanceof Error ? e.message : translate("skills.unknown_error");
+ const message = e instanceof Error ? e.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
} finally {
options.setBusy(false);
diff --git a/apps/app/src/app/context/global-sync.tsx b/apps/app/src/app/context/global-sync.tsx
index 4b73134bb..17638a2b7 100644
--- a/apps/app/src/app/context/global-sync.tsx
+++ b/apps/app/src/app/context/global-sync.tsx
@@ -1,6 +1,6 @@
import { createContext, createEffect, useContext, type ParentProps } from "solid-js";
-import { t, currentLocale } from "../../i18n";
+import { t } from "../../i18n";
import { createStore, type SetStoreFunction, type Store } from "solid-js/store";
import type {
@@ -96,7 +96,7 @@ export function GlobalSyncProvider(props: ParentProps) {
const setError = (error: unknown) => {
const message = error instanceof Error ? error.message : safeStringify(error);
- setGlobalStore("error", message || t("app.unknown_error", currentLocale()));
+ setGlobalStore("error", message || t("app.unknown_error"));
};
const setProjectMeta = (projects: Project[]) => {
diff --git a/apps/app/src/app/context/model-config.ts b/apps/app/src/app/context/model-config.ts
index 4e1d73ed5..26e0729f0 100644
--- a/apps/app/src/app/context/model-config.ts
+++ b/apps/app/src/app/context/model-config.ts
@@ -2,7 +2,7 @@ import { createEffect, createMemo, createSignal, onCleanup, type Accessor } from
import { parse } from "jsonc-parser";
-import { currentLocale, t } from "../../i18n";
+import { t } from "../../i18n";
import { DEFAULT_MODEL, MODEL_PREF_KEY, SESSION_MODEL_PREF_KEY, VARIANT_PREF_KEY } from "../constants";
import { readOpencodeConfig, writeOpencodeConfig } from "../lib/tauri";
import {
@@ -551,9 +551,9 @@ export function createModelConfigStore(options: {
const modelInfo = findProviderModel(ref);
if (!modelInfo) {
return {
- title: t("app.model_behavior_title", currentLocale()),
+ title: t("app.model_behavior_title"),
label: formatGenericBehaviorLabel(value),
- description: t("app.model_behavior_desc", currentLocale()),
+ description: t("app.model_behavior_desc"),
options: [],
};
}
@@ -597,7 +597,7 @@ export function createModelConfigStore(options: {
modelID: DEFAULT_MODEL.modelID,
title: DEFAULT_MODEL.modelID,
description: DEFAULT_MODEL.providerID,
- footer: t("settings.model_fallback", currentLocale()),
+ footer: t("settings.model_fallback"),
behaviorTitle: behavior.title,
behaviorLabel: behavior.label,
behaviorDescription: behavior.description,
@@ -637,9 +637,9 @@ export function createModelConfigStore(options: {
const behaviorValue = sanitizeModelBehaviorValue(provider.id, model, activeVariant);
const footerBits: string[] = [];
if (defaultModelID === model.id || isDefault) {
- footerBits.push(t("settings.model_default", currentLocale()));
+ footerBits.push(t("settings.model_default"));
}
- if (model.reasoning) footerBits.push(t("settings.model_reasoning", currentLocale()));
+ if (model.reasoning) footerBits.push(t("settings.model_reasoning"));
next.push({
providerID: provider.id,
@@ -1070,7 +1070,7 @@ export function createModelConfigStore(options: {
const content = formatConfigWithDefaultModel(configFile.content, nextModel);
const result = await writeOpencodeConfig("project", root, content);
if (!result.ok) {
- throw new Error(result.stderr || result.stdout || t("app.error_update_opencode_json", currentLocale()));
+ throw new Error(result.stderr || result.stdout || t("app.error_update_opencode_json"));
}
options.setLastKnownConfigSnapshot(getConfigSnapshot(content));
if (workspaceId) {
@@ -1201,7 +1201,7 @@ export function createModelConfigStore(options: {
if (workspace.workspaceType !== "local" || !root || !isTauriRuntime()) {
throw new Error(
- t("app.error_auto_compact_scope", currentLocale()),
+ t("app.error_auto_compact_scope"),
);
}
@@ -1211,7 +1211,7 @@ export function createModelConfigStore(options: {
const content = formatConfigWithAutoCompactContext(configFile.content, nextValue);
const result = await writeOpencodeConfig("project", root, content);
if (!result.ok) {
- throw new Error(result.stderr || result.stdout || t("app.error_update_opencode_json", currentLocale()));
+ throw new Error(result.stderr || result.stdout || t("app.error_update_opencode_json"));
}
options.setLastKnownConfigSnapshot(getConfigSnapshot(content));
options.markOpencodeConfigReloadRequired();
diff --git a/apps/app/src/app/context/providers/store.ts b/apps/app/src/app/context/providers/store.ts
index a6dab2fc7..a44891fc5 100644
--- a/apps/app/src/app/context/providers/store.ts
+++ b/apps/app/src/app/context/providers/store.ts
@@ -368,7 +368,7 @@ export function createProvidersStore(options: CreateProvidersStoreOptions) {
if (previousProviderId && previousProviderId !== provider.providerId) {
updated = removeCloudProviderComment(updated, previousProviderId);
- const previousEdits = modify(updated, ["provider", previousProviderId], undefined, {
+ const previousEdits = modify(updated, ["provider", previousProviderId], {
formattingOptions: { insertSpaces: true, tabSize: 2 },
});
updated = applyEdits(updated, previousEdits);
@@ -396,7 +396,7 @@ export function createProvidersStore(options: CreateProvidersStoreOptions) {
const formatConfigWithoutCloudProvider = (raw: string, providerId: string) => {
let updated = raw.trim() ? raw : '{\n "$schema": "https://opencode.ai/config.json"\n}\n';
updated = removeCloudProviderComment(updated, providerId);
- const providerEdits = modify(updated, ["provider", providerId], undefined, {
+ const providerEdits = modify(updated, ["provider", providerId], {
formattingOptions: { insertSpaces: true, tabSize: 2 },
});
updated = applyEdits(updated, providerEdits);
@@ -670,7 +670,7 @@ export function createProvidersStore(options: CreateProvidersStoreOptions) {
const heading = (() => {
if (status === 401 || status === 403) return t("providers.auth_failed");
if (status === 429) return t("providers.rate_limit_exceeded");
- if (provider) return t("providers.provider_error", undefined, { provider });
+ if (provider) return t("providers.provider_error", { provider });
return fallback;
})();
diff --git a/apps/app/src/app/context/session.ts b/apps/app/src/app/context/session.ts
index 120ab6f9a..607b9cc96 100644
--- a/apps/app/src/app/context/session.ts
+++ b/apps/app/src/app/context/session.ts
@@ -1,6 +1,6 @@
import { batch, createEffect, createMemo, createSignal, onCleanup } from "solid-js";
-import { t, currentLocale } from "../../i18n";
+import { t } from "../../i18n";
import { createStore, produce, reconcile } from "solid-js/store";
import type { Message, Part, Session } from "@opencode-ai/sdk/v2/client";
@@ -532,7 +532,7 @@ export function createSessionStore(options: {
});
};
- const addError = (error: unknown, fallback = t("app.unknown_error", currentLocale())) => {
+ const addError = (error: unknown, fallback = t("app.unknown_error")) => {
const message = error instanceof Error ? error.message : fallback;
if (!message) return;
options.setError(addOpencodeCacheHint(message));
@@ -701,14 +701,14 @@ export function createSessionStore(options: {
const heading = (() => {
if (errorName === "ProviderAuthError") return `Provider auth error${providerID ? ` (${providerID})` : ""}`;
if (errorName === "APIError") {
- if (effectiveStatus === 401 || effectiveStatus === 403) return t("app.error_auth_failed", currentLocale());
+ if (effectiveStatus === 401 || effectiveStatus === 403) return t("app.error_auth_failed");
if (effectiveStatus === 413) return "Context too large";
- if (effectiveStatus === 429) return t("app.error_rate_limit", currentLocale());
+ if (effectiveStatus === 429) return t("app.error_rate_limit");
return `API error${effectiveStatus ? ` (${effectiveStatus})` : ""}`;
}
- if (effectiveStatus === 401 || effectiveStatus === 403) return t("app.error_auth_failed", currentLocale());
+ if (effectiveStatus === 401 || effectiveStatus === 403) return t("app.error_auth_failed");
if (effectiveStatus === 413) return "Context too large";
- if (effectiveStatus === 429) return t("app.error_rate_limit", currentLocale());
+ if (effectiveStatus === 429) return t("app.error_rate_limit");
if (errorName === "MessageOutputLengthError") return "Output length limit exceeded";
return errorName.replace(/([a-z])([A-Z])/g, "$1 $2");
})();
@@ -1047,7 +1047,7 @@ export function createSessionStore(options: {
if (!c) return;
const trimmed = title.trim();
if (!trimmed) {
- throw new Error(t("app.error_session_name_required", currentLocale()));
+ throw new Error(t("app.error_session_name_required"));
}
const next = unwrap(await c.session.update({ sessionID, title: trimmed }));
rememberSession(next);
@@ -1225,7 +1225,7 @@ export function createSessionStore(options: {
mark("health FAILED", {
error: error instanceof Error ? error.message : safeStringify(error),
});
- throw new Error(t("app.connection_lost", currentLocale()));
+ throw new Error(t("app.connection_lost"));
}
}
if (abortIfStale("selection changed after health")) return;
diff --git a/apps/app/src/app/context/workspace.ts b/apps/app/src/app/context/workspace.ts
index a3806fee2..1066b072c 100644
--- a/apps/app/src/app/context/workspace.ts
+++ b/apps/app/src/app/context/workspace.ts
@@ -69,7 +69,7 @@ import {
import type { BootPhase, StartupBranch } from "../lib/startup-boot";
import { waitForHealthy, createClient, type OpencodeAuth } from "../lib/opencode";
import type { OpencodeConnectStatus, ProviderListItem } from "../types";
-import { t, currentLocale } from "../../i18n";
+import { t } from "../../i18n";
import { filterProviderList, mapConfigProvidersToList } from "../utils/providers";
import { buildDefaultWorkspaceBlueprint, normalizeWorkspaceOpenworkConfig } from "../lib/workspace-blueprints";
import type { OpenworkServerStore } from "../connections/openwork-server-store";
@@ -1551,7 +1551,7 @@ export function createWorkspaceStore(options: {
}
if (!resolvedBaseUrl) {
- options.setError(t("app.error.remote_base_url_required", currentLocale()));
+ options.setError(t("app.error.remote_base_url_required"));
updateWorkspaceConnectionState(id, {
status: "error",
message: "Remote base URL is required.",
@@ -1583,7 +1583,7 @@ export function createWorkspaceStore(options: {
}
if (!baseUrl) {
- options.setError(t("app.error.remote_base_url_required", currentLocale()));
+ options.setError(t("app.error.remote_base_url_required"));
updateWorkspaceConnectionState(id, {
status: "error",
message: "Remote base URL is required.",
@@ -2171,12 +2171,12 @@ export function createWorkspaceStore(options: {
async function createWorkspaceFlow(preset: WorkspacePreset, folder: string | null): Promise {
if (!isTauriRuntime()) {
- options.setError(t("app.error.tauri_required", currentLocale()));
+ options.setError(t("app.error.tauri_required"));
return false;
}
if (!folder) {
- options.setError(t("app.error.choose_folder", currentLocale()));
+ options.setError(t("app.error.choose_folder"));
return false;
}
@@ -2190,7 +2190,7 @@ export function createWorkspaceStore(options: {
try {
const resolvedFolder = await resolveWorkspacePath(folder);
if (!resolvedFolder) {
- options.setError(t("app.error.choose_folder", currentLocale()));
+ options.setError(t("app.error.choose_folder"));
return false;
}
@@ -2275,12 +2275,12 @@ export function createWorkspaceStore(options: {
input?: { onReady?: () => Promise | void },
): Promise {
if (!isTauriRuntime()) {
- options.setError(t("app.error.tauri_required", currentLocale()));
+ options.setError(t("app.error.tauri_required"));
return false;
}
if (!folder) {
- options.setError(t("app.error.choose_folder", currentLocale()));
+ options.setError(t("app.error.choose_folder"));
return false;
}
@@ -2346,7 +2346,7 @@ export function createWorkspaceStore(options: {
try {
const resolvedFolder = await resolveWorkspacePath(folder);
if (!resolvedFolder) {
- options.setError(t("app.error.choose_folder", currentLocale()));
+ options.setError(t("app.error.choose_folder"));
setSandboxStep("workspace", { status: "error", detail: "No folder selected" });
setSandboxError("No folder selected");
return false;
@@ -2559,7 +2559,7 @@ export function createWorkspaceStore(options: {
const displayName = input.displayName?.trim() || null;
if (!hostUrl) {
- options.setError(t("app.error.remote_base_url_required", currentLocale()));
+ options.setError(t("app.error.remote_base_url_required"));
return false;
}
@@ -2632,7 +2632,7 @@ export function createWorkspaceStore(options: {
}
if (!resolvedBaseUrl) {
- options.setError(t("app.error.remote_base_url_required", currentLocale()));
+ options.setError(t("app.error.remote_base_url_required"));
return false;
}
@@ -2798,7 +2798,7 @@ export function createWorkspaceStore(options: {
const displayName = input.displayName?.trim() || null;
if (!hostUrl) {
- options.setError(t("app.error.remote_base_url_required", currentLocale()));
+ options.setError(t("app.error.remote_base_url_required"));
return false;
}
@@ -2840,7 +2840,7 @@ export function createWorkspaceStore(options: {
}
if (!resolvedBaseUrl) {
- options.setError(t("app.error.remote_base_url_required", currentLocale()));
+ options.setError(t("app.error.remote_base_url_required"));
return false;
}
@@ -2928,7 +2928,7 @@ export function createWorkspaceStore(options: {
async function forgetWorkspace(workspaceId: string) {
if (!isTauriRuntime()) {
- options.setError(t("app.error.tauri_required", currentLocale()));
+ options.setError(t("app.error.tauri_required"));
return;
}
@@ -3018,10 +3018,10 @@ export function createWorkspaceStore(options: {
}
if (!isTauriRuntime()) {
- options.setError(t("app.error.tauri_required", currentLocale()));
+ options.setError(t("app.error.tauri_required"));
updateWorkspaceConnectionState(id, {
status: "error",
- message: t("app.error.tauri_required", currentLocale()),
+ message: t("app.error.tauri_required"),
});
return false;
}
@@ -3106,12 +3106,12 @@ export function createWorkspaceStore(options: {
async function pickWorkspaceFolder() {
if (!isTauriRuntime()) {
- options.setError(t("app.error.tauri_required", currentLocale()));
+ options.setError(t("app.error.tauri_required"));
return null;
}
try {
- const selection = await pickDirectory({ title: t("onboarding.choose_workspace_folder", currentLocale()) });
+ const selection = await pickDirectory({ title: t("onboarding.choose_workspace_folder") });
const folder =
typeof selection === "string" ? selection : Array.isArray(selection) ? selection[0] : null;
@@ -3142,7 +3142,7 @@ export function createWorkspaceStore(options: {
async function exportWorkspaceConfig(workspaceId?: string) {
if (exportingWorkspaceConfig()) return;
if (!isTauriRuntime()) {
- options.setError(t("app.error.tauri_required", currentLocale()));
+ options.setError(t("app.error.tauri_required"));
return;
}
@@ -3200,7 +3200,7 @@ export function createWorkspaceStore(options: {
async function importWorkspaceConfig() {
if (importingWorkspaceConfig()) return;
if (!isTauriRuntime()) {
- options.setError(t("app.error.tauri_required", currentLocale()));
+ options.setError(t("app.error.tauri_required"));
return;
}
@@ -3225,7 +3225,7 @@ export function createWorkspaceStore(options: {
const resolvedFolder = await resolveWorkspacePath(folder);
if (!resolvedFolder) {
- options.setError(t("app.error.choose_folder", currentLocale()));
+ options.setError(t("app.error.choose_folder"));
return;
}
@@ -3254,19 +3254,19 @@ export function createWorkspaceStore(options: {
async function startHost(optionsOverride?: { workspacePath?: string; navigate?: boolean }) {
if (!isTauriRuntime()) {
- options.setError(t("app.error.tauri_required", currentLocale()));
+ options.setError(t("app.error.tauri_required"));
return false;
}
const overrideWorkspacePath = optionsOverride?.workspacePath?.trim() ?? "";
if (selectedWorkspaceInfo()?.workspaceType === "remote" && !overrideWorkspacePath) {
- options.setError(t("app.error.host_requires_local", currentLocale()));
+ options.setError(t("app.error.host_requires_local"));
return false;
}
const dir = (overrideWorkspacePath || selectedWorkspacePath() || projectDir()).trim();
if (!dir) {
- options.setError(t("app.error.pick_workspace_folder", currentLocale()));
+ options.setError(t("app.error.pick_workspace_folder"));
return false;
}
@@ -3477,10 +3477,10 @@ export function createWorkspaceStore(options: {
closeWorkspaceConnectionSettings();
return;
}
- setEditRemoteWorkspaceError(t("app.error_connection_failed_url", currentLocale()));
+ setEditRemoteWorkspaceError(t("app.error_connection_failed_url"));
options.setError(null);
} catch (e) {
- const message = e instanceof Error ? e.message : t("app.error_connection_failed", currentLocale());
+ const message = e instanceof Error ? e.message : t("app.error_connection_failed");
setEditRemoteWorkspaceError(message);
options.setError(null);
}
@@ -3657,7 +3657,7 @@ export function createWorkspaceStore(options: {
setEngineInstallLogs(combined || null);
if (!result.ok) {
- options.setError(result.stderr.trim() || t("app.error.install_failed", currentLocale()));
+ options.setError(result.stderr.trim() || t("app.error.install_failed"));
}
await refreshEngineDoctor();
@@ -3750,7 +3750,7 @@ export function createWorkspaceStore(options: {
if (selectedWorkspaceInfo()?.workspaceType === "remote") return;
try {
- const selection = await pickDirectory({ title: t("onboarding.authorize_folder", currentLocale()) });
+ const selection = await pickDirectory({ title: t("onboarding.authorize_folder") });
const folder =
typeof selection === "string" ? selection : Array.isArray(selection) ? selection[0] : null;
if (!folder) return;
diff --git a/apps/app/src/app/lib/model-behavior.ts b/apps/app/src/app/lib/model-behavior.ts
index 287deb3c8..1bceea053 100644
--- a/apps/app/src/app/lib/model-behavior.ts
+++ b/apps/app/src/app/lib/model-behavior.ts
@@ -116,7 +116,7 @@ const getVariantDescription = (providerID: string, key: string, label: string) =
if (key === "xhigh" || key === "max") return providerID === "anthropic"
? t("model_behavior.desc_max_anthropic")
: t("model_behavior.desc_max");
- return t("model_behavior.desc_generic", undefined, { label: label.toLowerCase() });
+ return t("model_behavior.desc_generic", { label: label.toLowerCase() });
};
export const getModelBehaviorOptions = (
diff --git a/apps/app/src/app/pages/automations.tsx b/apps/app/src/app/pages/automations.tsx
index 4ceb54393..7e220525a 100644
--- a/apps/app/src/app/pages/automations.tsx
+++ b/apps/app/src/app/pages/automations.tsx
@@ -193,7 +193,7 @@ const humanizeCron = (cron: string) => {
) {
const interval = Number.parseInt(hourRaw.slice(2), 10);
if (Number.isFinite(interval) && interval > 0) {
- return interval === 1 ? t("scheduled.every_hour") : t("scheduled.every_n_hours", undefined, { interval });
+ return interval === 1 ? t("scheduled.every_hour") : t("scheduled.every_n_hours", { interval });
}
}
@@ -205,7 +205,7 @@ const humanizeCron = (cron: string) => {
const timeLabel = `${pad2(hour)}:${pad2(minute)}`;
if (dowRaw === "*") {
- return t("scheduled.every_day_at", undefined, { time: timeLabel });
+ return t("scheduled.every_day_at", { time: timeLabel });
}
const days = parseCronNumbers(dowRaw);
@@ -214,18 +214,18 @@ const humanizeCron = (cron: string) => {
const weekdayDays = [1, 2, 3, 4, 5];
const weekendDays = [0, 6];
- if (allDays.every((d) => normalized.has(d))) return t("scheduled.every_day_at", undefined, { time: timeLabel });
+ if (allDays.every((d) => normalized.has(d))) return t("scheduled.every_day_at", { time: timeLabel });
if (
weekdayDays.every((d) => normalized.has(d)) &&
!weekendDays.some((d) => normalized.has(d))
) {
- return t("scheduled.weekdays_at", undefined, { time: timeLabel });
+ return t("scheduled.weekdays_at", { time: timeLabel });
}
if (
weekendDays.every((d) => normalized.has(d)) &&
!weekdayDays.some((d) => normalized.has(d))
) {
- return t("scheduled.weekends_at", undefined, { time: timeLabel });
+ return t("scheduled.weekends_at", { time: timeLabel });
}
const labels: Record = {
@@ -244,7 +244,7 @@ const humanizeCron = (cron: string) => {
.map((d) => labels[d] ?? String(d))
.join(", ");
- return list ? t("scheduled.days_at", undefined, { days: list, time: timeLabel }) : t("scheduled.at_time", undefined, { time: timeLabel });
+ return list ? t("scheduled.days_at", { days: list, time: timeLabel }) : t("scheduled.at_time", { time: timeLabel });
};
const buildCronFromDaily = (timeValue: string, days: string[]) => {
@@ -290,7 +290,7 @@ const toRelative = (value?: string | null) => {
const templateScheduleLabel = (template: AutomationTemplate) => {
if (template.scheduleMode === "interval") {
const interval = template.intervalHours ?? DEFAULT_INTERVAL_HOURS;
- return interval === 1 ? t("scheduled.every_hour") : t("scheduled.every_n_hours", undefined, { interval });
+ return interval === 1 ? t("scheduled.every_hour") : t("scheduled.every_n_hours", { interval });
}
return humanizeCron(
buildCronFromDaily(
@@ -610,7 +610,7 @@ export default function AutomationsView(props: AutomationsViewProps) {
return;
}
await Promise.resolve(props.createSessionAndOpen(plan.prompt));
- showToast(t("scheduled.prepared_job_in_chat", undefined, { name: job.name }), "success");
+ showToast(t("scheduled.prepared_job_in_chat", { name: job.name }), "success");
};
const confirmDelete = async () => {
@@ -621,7 +621,7 @@ export default function AutomationsView(props: AutomationsViewProps) {
try {
await automations.remove(target.slug);
setDeleteTarget(null);
- showToast(t("scheduled.removed_job", undefined, { name: target.name }), "success");
+ showToast(t("scheduled.removed_job", { name: target.name }), "success");
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
setDeleteError(message || t("scheduled.delete_error_fallback"));
@@ -648,7 +648,7 @@ export default function AutomationsView(props: AutomationsViewProps) {
const jobsEmptyMessage = createMemo(() => {
const query = searchQuery().trim();
- if (query) return t("scheduled.no_automations_match", undefined, { query });
+ if (query) return t("scheduled.no_automations_match", { query });
if (schedulerGateActive()) return t("scheduled.install_scheduler_hint");
return t("scheduled.empty_hint");
});
@@ -829,7 +829,7 @@ export default function AutomationsView(props: AutomationsViewProps) {
{t("scheduled.quick_start_templates_desc")}
-
{t("scheduled.template_count", undefined, { count: filteredTemplates().length })}
+
{t("scheduled.template_count", { count: filteredTemplates().length })}
{t("scheduled.delete_confirm_title")}
- {t("scheduled.delete_confirm_desc", undefined, { source: sourceLabel().toLowerCase() })}
+ {t("scheduled.delete_confirm_desc", { source: sourceLabel().toLowerCase() })}
diff --git a/apps/app/src/app/pages/extensions.tsx b/apps/app/src/app/pages/extensions.tsx
index cc61c3306..4b4da367b 100644
--- a/apps/app/src/app/pages/extensions.tsx
+++ b/apps/app/src/app/pages/extensions.tsx
@@ -75,7 +75,7 @@ export default function ExtensionsView(props: ExtensionsViewProps) {
- {t(connectedAppsCount() === 1 ? "extensions.app_count_one" : "extensions.app_count_many", undefined, { count: connectedAppsCount() })}
+ {t(connectedAppsCount() === 1 ? "extensions.app_count_one" : "extensions.app_count_many", { count: connectedAppsCount() })}
@@ -83,7 +83,7 @@ export default function ExtensionsView(props: ExtensionsViewProps) {
- {t(pluginCount() === 1 ? "extensions.plugin_count_one" : "extensions.plugin_count_many", undefined, { count: pluginCount() })}
+ {t(pluginCount() === 1 ? "extensions.plugin_count_one" : "extensions.plugin_count_many", { count: pluginCount() })}
diff --git a/apps/app/src/app/pages/identities.tsx b/apps/app/src/app/pages/identities.tsx
index f4ae04872..9e19a26d0 100644
--- a/apps/app/src/app/pages/identities.tsx
+++ b/apps/app/src/app/pages/identities.tsx
@@ -270,11 +270,11 @@ export default function IdentitiesView(props: IdentitiesViewProps) {
const elapsedMs = Math.max(0, Date.now() - ts);
if (elapsedMs < 60_000) return t("identities.just_now");
const minutes = Math.floor(elapsedMs / 60_000);
- if (minutes < 60) return t("identities.minutes_ago", undefined, { minutes });
+ if (minutes < 60) return t("identities.minutes_ago", { minutes });
const hours = Math.floor(minutes / 60);
- if (hours < 24) return t("identities.hours_ago", undefined, { hours });
+ if (hours < 24) return t("identities.hours_ago", { hours });
const days = Math.floor(hours / 24);
- return t("identities.days_ago", undefined, { days });
+ return t("identities.days_ago", { days });
});
const workspaceAgentStatus = createMemo(() => {
@@ -416,7 +416,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) {
...(sendAutoBind() ? { autoBind: true } : {}),
});
setSendResult(result);
- const base = t("identities.dispatched_messages", undefined, { sent: result.sent, attempted: result.attempted });
+ const base = t("identities.dispatched_messages", { sent: result.sent, attempted: result.attempted });
setSendStatus(result.reason?.trim() ? `${base} ${result.reason.trim()}` : base);
} catch (error) {
setSendError(formatRequestError(error));
@@ -493,7 +493,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) {
const message =
(healthRes.json && typeof (healthRes.json as any).message === "string")
? String((healthRes.json as any).message)
- : t("identities.health_unavailable_status", undefined, { status: healthRes.status });
+ : t("identities.health_unavailable_status", { status: healthRes.status });
setHealthError(message);
}
setMessagingRestartRequired(true);
@@ -666,7 +666,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) {
const pairingCode = typeof result.telegram?.pairingCode === "string" ? result.telegram.pairingCode.trim() : "";
if (access === "private" && pairingCode) {
setTelegramPairingCode(pairingCode);
- setTelegramStatus(t("identities.telegram_private_saved_pair", undefined, { code: pairingCode }));
+ setTelegramStatus(t("identities.telegram_private_saved_pair", { code: pairingCode }));
} else {
setTelegramPairingCode(null);
}
@@ -675,7 +675,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) {
const normalized = String(username).trim().replace(/^@+/, "");
setTelegramBotUsername(normalized || null);
if (access !== "private" || !pairingCode) {
- setTelegramStatus(t("identities.telegram_saved_username", undefined, { username: normalized || String(username) }));
+ setTelegramStatus(t("identities.telegram_saved_username", { username: normalized || String(username) }));
}
} else {
if (access !== "private" || !pairingCode) {
@@ -1290,7 +1290,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) {
class="inline-flex items-center gap-2 rounded-lg border border-gray-4 bg-gray-2/50 px-3 py-2 text-[12px] font-medium text-gray-11 hover:bg-gray-2"
>
- {t("identities.open_bot_link", undefined, { username: telegramBotUsername() ?? "" })}
+ {t("identities.open_bot_link", { username: telegramBotUsername() ?? "" })}
)}
@@ -1546,7 +1546,7 @@ export default function IdentitiesView(props: IdentitiesViewProps) {
{(value) => (
- {t("identities.agent_scope_status", undefined, { status: value().loaded ? t("identities.agent_status_loaded") : t("identities.agent_status_missing"), agent: value().selected || t("identities.agent_none") })}
+ {t("identities.agent_scope_status", { status: value().loaded ? t("identities.agent_status_loaded") : t("identities.agent_status_missing"), agent: value().selected || t("identities.agent_none") })}
)}
diff --git a/apps/app/src/app/pages/mcp.tsx b/apps/app/src/app/pages/mcp.tsx
index 02e5b53d9..cbcb5c195 100644
--- a/apps/app/src/app/pages/mcp.tsx
+++ b/apps/app/src/app/pages/mcp.tsx
@@ -133,7 +133,6 @@ const serviceIconBg = (name: string) => {
export default function McpView(props: McpViewProps) {
const locale = () => currentLocale();
- const tr = (key: string) => t(key, locale());
const showHeader = () => props.showHeader !== false;
const [logoutOpen, setLogoutOpen] = createSignal(false);
@@ -189,7 +188,7 @@ export default function McpView(props: McpViewProps) {
if (nextId !== configRequestId) return;
setProjectConfig(null);
setGlobalConfig(null);
- setConfigError(e instanceof Error ? e.message : tr("mcp.config_load_failed"));
+ setConfigError(e instanceof Error ? e.message : t("mcp.config_load_failed"));
}
})();
});
@@ -199,7 +198,7 @@ export default function McpView(props: McpViewProps) {
);
const revealLabel = () =>
- isWindowsPlatform() ? tr("mcp.open_file") : tr("mcp.reveal_in_finder");
+ isWindowsPlatform() ? t("mcp.open_file") : t("mcp.reveal_in_finder");
const canRevealConfig = () => {
if (!isTauriRuntime() || revealBusy()) return false;
@@ -212,7 +211,7 @@ export default function McpView(props: McpViewProps) {
const root = props.selectedWorkspaceRoot.trim();
if (configScope() === "project" && !root) {
- setConfigError(tr("mcp.pick_workspace_error"));
+ setConfigError(t("mcp.pick_workspace_error"));
return;
}
@@ -223,7 +222,7 @@ export default function McpView(props: McpViewProps) {
? await props.readConfigFile(configScope())
: await readOpencodeConfig(configScope(), root);
if (!resolved) {
- throw new Error(tr("mcp.config_load_failed"));
+ throw new Error(t("mcp.config_load_failed"));
}
const { openPath, revealItemInDir } = await import("@tauri-apps/plugin-opener");
if (isWindowsPlatform()) {
@@ -232,7 +231,7 @@ export default function McpView(props: McpViewProps) {
await revealItemInDir(resolved.path);
}
} catch (e) {
- setConfigError(e instanceof Error ? e.message : tr("mcp.reveal_config_failed"));
+ setConfigError(e instanceof Error ? e.message : t("mcp.reveal_config_failed"));
} finally {
setRevealBusy(false);
}
@@ -308,15 +307,15 @@ export default function McpView(props: McpViewProps) {
{/* ── Header ───────────────────────────────────── */}
-
{tr("mcp.apps_title")}
+
{t("mcp.apps_title")}
- {tr("mcp.apps_subtitle")}
+ {t("mcp.apps_subtitle")}
0}>
- {connectedCount()} {connectedCount() === 1 ? tr("mcp.app_connected") : tr("mcp.apps_connected")}
+ {connectedCount()} {connectedCount() === 1 ? t("mcp.app_connected") : t("mcp.apps_connected")}
@@ -333,12 +332,12 @@ export default function McpView(props: McpViewProps) {
-
{tr("mcp.add_modal_title")}
-
{tr("mcp.custom_app_cta_hint")}
+
{t("mcp.add_modal_title")}
+
{t("mcp.custom_app_cta_hint")}
setAddMcpModalOpen(true)}>
- {tr("mcp.add_modal_title")}
+ {t("mcp.add_modal_title")}
@@ -347,9 +346,9 @@ export default function McpView(props: McpViewProps) {
- {tr("mcp.available_apps")}
+ {t("mcp.available_apps")}
- {tr("mcp.one_click_connect")}
+ {t("mcp.one_click_connect")}
@@ -366,7 +365,7 @@ export default function McpView(props: McpViewProps) {
{
event.stopPropagation();
const existingEntry = props.mcpServers.find((server) => server.name === getMcpIdentityKey(entry));
@@ -416,7 +415,7 @@ export default function McpView(props: McpViewProps) {
{entry.name}
- {tr("mcp.connected_badge")}
+ {t("mcp.connected_badge")}
@@ -432,7 +431,7 @@ export default function McpView(props: McpViewProps) {
- {tr("mcp.tap_to_connect")}
+ {t("mcp.tap_to_connect")}
@@ -449,11 +448,11 @@ export default function McpView(props: McpViewProps) {
- {tr("mcp.your_apps")}
+ {t("mcp.your_apps")}
- {tr("mcp.last_synced")} {formatRelativeTime(props.mcpLastUpdatedAt ?? Date.now())}
+ {t("mcp.last_synced")} {formatRelativeTime(props.mcpLastUpdatedAt ?? Date.now())}
@@ -463,8 +462,8 @@ export default function McpView(props: McpViewProps) {
fallback={
-
{tr("mcp.no_apps_yet")}
-
{tr("mcp.no_apps_hint")}
+
{t("mcp.no_apps_yet")}
+
{t("mcp.no_apps_hint")}
}
>
@@ -477,7 +476,7 @@ export default function McpView(props: McpViewProps) {
const errorInfo = () => {
const resolved = props.mcpStatuses[entry.name];
if (!resolved || resolved.status !== "failed") return null;
- return "error" in resolved ? resolved.error : tr("mcp.connection_failed");
+ return "error" in resolved ? resolved.error : t("mcp.connection_failed");
};
return (
@@ -518,20 +517,20 @@ export default function McpView(props: McpViewProps) {
{/* Connection type */}
- {tr("mcp.connection_type")}
+ {t("mcp.connection_type")}
- {entry.config.type === "remote" ? tr("mcp.type_cloud") : tr("mcp.type_local")}
+ {entry.config.type === "remote" ? t("mcp.type_cloud") : t("mcp.type_local")}
{/* Capabilities */}
- {tr("mcp.cap_tools")}
+ {t("mcp.cap_tools")}
- {tr("mcp.cap_signin")}
+ {t("mcp.cap_signin")}
@@ -549,7 +548,7 @@ export default function McpView(props: McpViewProps) {
- {tr("mcp.technical_details")}
+ {t("mcp.technical_details")}
@@ -562,7 +561,7 @@ export default function McpView(props: McpViewProps) {
- {tr("mcp.logout_label")}
+ {t("mcp.logout_label")}
props.authorizeMcp(entry)}
>
- {tr("mcp.login_action")}
+ {t("mcp.login_action")}
- {tr("mcp.login_hint")}
+ {t("mcp.login_hint")}
- {tr("mcp.logout_label")}
+ {t("mcp.logout_label")}
requestLogout(entry.name)}
>
- {logoutBusy() && logoutTarget() === entry.name ? tr("mcp.logout_working") : tr("mcp.logout_action")}
+ {logoutBusy() && logoutTarget() === entry.name ? t("mcp.logout_working") : t("mcp.logout_action")}
- {tr("mcp.logout_hint")}
+ {t("mcp.logout_hint")}
@@ -605,7 +604,7 @@ export default function McpView(props: McpViewProps) {
onClick={() => openControlChromeModal("edit", entry)}
>
- {tr("mcp.control_chrome_edit")}
+ {t("mcp.control_chrome_edit")}
- {tr("mcp.remove_app")}
+ {t("mcp.remove_app")}
@@ -632,10 +631,10 @@ export default function McpView(props: McpViewProps) {
{
if (logoutBusy()) return;
@@ -649,10 +648,10 @@ export default function McpView(props: McpViewProps) {
{
setRemoveOpen(false);
@@ -676,8 +675,8 @@ export default function McpView(props: McpViewProps) {
-
{tr("mcp.advanced_settings")}
-
{tr("mcp.advanced_settings_hint")}
+
{t("mcp.advanced_settings")}
+
{t("mcp.advanced_settings_hint")}
@@ -697,7 +696,7 @@ export default function McpView(props: McpViewProps) {
}`}
onClick={() => setConfigScope("project")}
>
- {tr("mcp.scope_project")}
+ {t("mcp.scope_project")}
setConfigScope("global")}
>
- {tr("mcp.scope_global")}
+ {t("mcp.scope_global")}
{/* Config path */}
-
{tr("mcp.config_file")}
+
{t("mcp.config_file")}
- {activeConfig()?.path ?? tr("mcp.config_not_loaded")}
+ {activeConfig()?.path ?? t("mcp.config_not_loaded")}
@@ -728,7 +727,7 @@ export default function McpView(props: McpViewProps) {
fallback={<> {revealLabel()}>}
>
- {tr("mcp.opening_label")}
+ {t("mcp.opening_label")}
- {tr("mcp.docs_link")}
+ {t("mcp.docs_link")}
- {tr("mcp.file_not_found")}
+ {t("mcp.file_not_found")}
diff --git a/apps/app/src/app/pages/session.tsx b/apps/app/src/app/pages/session.tsx
index 2fd8251ec..231794535 100644
--- a/apps/app/src/app/pages/session.tsx
+++ b/apps/app/src/app/pages/session.tsx
@@ -627,7 +627,7 @@ export default function SessionView(props: SessionViewProps) {
const size = hits.length;
const raw = activeSearchHitIndex();
const index = ((raw % size) + size) % size;
- return t("session.search_position", undefined, { current: index + 1, total: size });
+ return t("session.search_position", { current: index + 1, total: size });
});
const searchActive = createMemo(
@@ -1057,7 +1057,7 @@ export default function SessionView(props: SessionViewProps) {
const todoLabel = createMemo(() => {
const total = todoCount();
if (!total) return "";
- return t("session.todo_progress", undefined, { completed: todoCompletedCount(), total });
+ return t("session.todo_progress", { completed: todoCompletedCount(), total });
});
const shareWorkspaceState = createShareWorkspaceState({
workspaces: () => props.workspaces,
@@ -2509,7 +2509,7 @@ export default function SessionView(props: SessionViewProps) {
files.length === 1 ? (files[0]?.name ?? "file") : `${files.length} files`;
if (notify) {
showComposerNotice({
- title: t("session.uploading_to_shared_folder", undefined, { label }),
+ title: t("session.uploading_to_shared_folder", { label }),
tone: "info",
});
}
@@ -2528,7 +2528,7 @@ export default function SessionView(props: SessionViewProps) {
.join(", ");
showComposerNotice({
title: summary
- ? t("session.uploaded_with_summary", undefined, { summary })
+ ? t("session.uploaded_with_summary", { summary })
: t("session.uploaded_to_shared_folder"),
tone: "success",
});
@@ -2636,7 +2636,7 @@ export default function SessionView(props: SessionViewProps) {
{
id: "sessions",
title: t("session.cmd_sessions_title"),
- detail: t("session.cmd_sessions_detail", undefined, { count: totalSessionCount().toLocaleString() }),
+ detail: t("session.cmd_sessions_detail", { count: totalSessionCount().toLocaleString() }),
meta: t("session.cmd_sessions_meta"),
action: () => {
setCommandPaletteMode("sessions");
@@ -2648,7 +2648,7 @@ export default function SessionView(props: SessionViewProps) {
{
id: "model",
title: t("session.cmd_model_title"),
- detail: t("session.cmd_model_detail", undefined, { model: modelControls.selectedSessionModelLabel() || t("session.cmd_model_fallback"), variant: modelControls.sessionModelVariantLabel() }),
+ detail: t("session.cmd_model_detail", { model: modelControls.selectedSessionModelLabel() || t("session.cmd_model_fallback"), variant: modelControls.sessionModelVariantLabel() }),
meta: t("session.cmd_model_meta"),
action: () => {
closeCommandPalette();
@@ -2770,7 +2770,7 @@ export default function SessionView(props: SessionViewProps) {
}
if (state === "downloading") {
const percent = updateDownloadPercent();
- return percent == null ? t("session.downloading") : t("session.downloading_percent", undefined, { percent });
+ return percent == null ? t("session.downloading") : t("session.downloading_percent", { percent });
}
return t("session.update_available");
});
@@ -2830,11 +2830,11 @@ export default function SessionView(props: SessionViewProps) {
const state = props.updateStatus?.state;
if (state === "ready") {
return props.anyActiveRuns
- ? t("session.update_ready_stop_runs_title", undefined, { version })
- : t("session.restart_update_title", undefined, { version });
+ ? t("session.update_ready_stop_runs_title", { version })
+ : t("session.restart_update_title", { version });
}
- if (state === "downloading") return t("session.downloading_update_title", undefined, { version });
- return t("session.update_available_title", undefined, { version });
+ if (state === "downloading") return t("session.downloading_update_title", { version });
+ return t("session.update_available_title", { version });
});
const handleUpdatePillClick = () => {
@@ -3400,7 +3400,7 @@ export default function SessionView(props: SessionViewProps) {
{props.loadingEarlierMessages
? t("session.loading_earlier")
: hiddenMessageCount() > 0
- ? t("session.show_earlier", undefined, { count: nextRevealCount().toLocaleString(), plural: nextRevealCount() === 1 ? "" : "s" })
+ ? t("session.show_earlier", { count: nextRevealCount().toLocaleString(), plural: nextRevealCount() === 1 ? "" : "s" })
: t("session.load_earlier")}
@@ -3780,7 +3780,7 @@ export default function SessionView(props: SessionViewProps) {
title={t("session.delete_session_title")}
message={
sessionTitleForId(deleteSessionId()).trim()
- ? t("session.delete_named_session_message", undefined, { title: sessionTitleForId(deleteSessionId()).trim() })
+ ? t("session.delete_named_session_message", { title: sessionTitleForId(deleteSessionId()).trim() })
: t("session.delete_session_generic")
}
confirmLabel={deleteSessionBusy() ? t("session.deleting") : t("session.delete")}
diff --git a/apps/app/src/app/pages/settings.tsx b/apps/app/src/app/pages/settings.tsx
index ea68b5f77..6ca58d4e6 100644
--- a/apps/app/src/app/pages/settings.tsx
+++ b/apps/app/src/app/pages/settings.tsx
@@ -344,10 +344,10 @@ export default function SettingsView(props: SettingsViewProps) {
const percent = updateDownloadPercent();
if (total != null && percent != null) {
- return t("settings.downloading_progress", undefined, { downloaded: formatBytes(downloaded), total: formatBytes(total), percent: String(percent) }) + (version ? ` · v${version}` : "");
+ return t("settings.downloading_progress", { downloaded: formatBytes(downloaded), total: formatBytes(total), percent: String(percent) }) + (version ? ` · v${version}` : "");
}
- return t("settings.downloading_bytes", undefined, { downloaded: formatBytes(downloaded) }) + (version ? ` · v${version}` : "");
+ return t("settings.downloading_bytes", { downloaded: formatBytes(downloaded) }) + (version ? ` · v${version}` : "");
});
const updateToolbarActionLabel = createMemo(() => {
@@ -439,7 +439,7 @@ export default function SettingsView(props: SettingsViewProps) {
const providerStatusLabel = createMemo(() => {
if (!providerAvailableCount()) return t("config.unavailable");
if (!providerConnectedCount()) return t("config.status_not_connected");
- return t("settings.connected_count", undefined, { count: providerConnectedCount() });
+ return t("settings.connected_count", { count: providerConnectedCount() });
});
const providerStatusStyle = createMemo(() => {
if (!providerAvailableCount())
@@ -453,8 +453,8 @@ export default function SettingsView(props: SettingsViewProps) {
return t("settings.connect_opencode_hint");
const connected = providerConnectedCount();
const available = providerAvailableCount();
- if (!connected) return t("settings.available_count", undefined, { count: available });
- return `${t("settings.connected_count", undefined, { count: connected })} · ${t("settings.available_count", undefined, { count: available })}`;
+ if (!connected) return t("settings.available_count", { count: available });
+ return `${t("settings.connected_count", { count: connected })} · ${t("settings.available_count", { count: available })}`;
});
const handleOpenProviderAuth = async () => {
@@ -2284,13 +2284,13 @@ export default function SettingsView(props: SettingsViewProps) {
{t("settings.update_checking")}
- {t("settings.update_available_version", undefined, { version: updateVersion() ?? "" })}
+ {t("settings.update_available_version", { version: updateVersion() ?? "" })}
{t("settings.update_downloading")}
- {t("settings.update_ready_version", undefined, { version: updateVersion() ?? "" })}
+ {t("settings.update_ready_version", { version: updateVersion() ?? "" })}
{t("settings.update_check_failed")}
@@ -2305,7 +2305,7 @@ export default function SettingsView(props: SettingsViewProps) {
}
>
- {t("settings.update_last_checked", undefined, { time: formatRelativeTime(updateLastCheckedAt() as number) })}
+ {t("settings.update_last_checked", { time: formatRelativeTime(updateLastCheckedAt() as number) })}
- {t("settings.update_published", undefined, { date: updateDate() ?? "" })}
+ {t("settings.update_published", { date: updateDate() ?? "" })}
@@ -2563,12 +2563,12 @@ export default function SettingsView(props: SettingsViewProps) {
-
{t("settings.debug_desktop_app", undefined, { version: appVersionLabel() })}
-
{t("settings.debug_commit", undefined, { commit: appCommitLabel() })}
-
{t("settings.debug_orchestrator_version", undefined, { version: orchestratorVersionLabel() })}
-
{t("settings.debug_opencode_version", undefined, { version: opencodeVersionLabel() })}
-
{t("settings.debug_openwork_server_version", undefined, { version: openworkServerVersionLabel() })}
-
{t("settings.debug_opencode_router_version", undefined, { version: opencodeRouterVersionLabel() })}
+
{t("settings.debug_desktop_app", { version: appVersionLabel() })}
+
{t("settings.debug_commit", { commit: appCommitLabel() })}
+
{t("settings.debug_orchestrator_version", { version: orchestratorVersionLabel() })}
+
{t("settings.debug_opencode_version", { version: opencodeVersionLabel() })}
+
{t("settings.debug_openwork_server_version", { version: openworkServerVersionLabel() })}
+
{t("settings.debug_opencode_router_version", { version: opencodeRouterVersionLabel() })}
{runtimeDebugReportJson()}
@@ -2665,9 +2665,9 @@ export default function SettingsView(props: SettingsViewProps) {
{(result) => (
- {t("settings.sandbox_run_id", undefined, { id: result().runId ?? "—" })}
+ {t("settings.sandbox_run_id", { id: result().runId ?? "—" })}
-
{t("settings.sandbox_result", undefined, { status: result().ready ? t("settings.sandbox_ready") : t("settings.sandbox_error") })}
+
{t("settings.sandbox_result", { status: result().ready ? t("settings.sandbox_ready") : t("settings.sandbox_error") })}
{(err) => {err()}
}
@@ -3066,22 +3066,22 @@ export default function SettingsView(props: SettingsViewProps) {
- {t("settings.debug_desktop_app", undefined, { version: appVersionLabel() })}
+ {t("settings.debug_desktop_app", { version: appVersionLabel() })}
- {t("settings.debug_commit", undefined, { commit: appCommitLabel() })}
+ {t("settings.debug_commit", { commit: appCommitLabel() })}
- {t("settings.debug_orchestrator_version", undefined, { version: orchestratorVersionLabel() })}
+ {t("settings.debug_orchestrator_version", { version: orchestratorVersionLabel() })}
- {t("settings.debug_opencode_version", undefined, { version: opencodeVersionLabel() })}
+ {t("settings.debug_opencode_version", { version: opencodeVersionLabel() })}
- {t("settings.debug_openwork_server_version", undefined, { version: openworkServerVersionLabel() })}
+ {t("settings.debug_openwork_server_version", { version: openworkServerVersionLabel() })}
- {t("settings.debug_opencode_router_version", undefined, { version: opencodeRouterVersionLabel() })}
+ {t("settings.debug_opencode_router_version", { version: opencodeRouterVersionLabel() })}
@@ -3111,7 +3111,7 @@ export default function SettingsView(props: SettingsViewProps) {
t("settings.no_project_directory")}
- {t("settings.diag_pid", undefined, { pid: String(props.engineInfo?.pid ?? "—") })}
+ {t("settings.diag_pid", { pid: String(props.engineInfo?.pid ?? "—") })}
@@ -3156,25 +3156,25 @@ export default function SettingsView(props: SettingsViewProps) {
t("settings.data_dir_unavailable")}
- {t("settings.diag_daemon_url", undefined, { url: props.orchestratorStatus?.daemon?.baseUrl ?? "—" })}
+ {t("settings.diag_daemon_url", { url: props.orchestratorStatus?.daemon?.baseUrl ?? "—" })}
- {t("settings.diag_opencode_url", undefined, { url: props.orchestratorStatus?.opencode?.baseUrl ?? "—" })}
+ {t("settings.diag_opencode_url", { url: props.orchestratorStatus?.opencode?.baseUrl ?? "—" })}
- {t("settings.diag_version", undefined, { version: props.orchestratorStatus?.cliVersion ?? "—" })}
+ {t("settings.diag_version", { version: props.orchestratorStatus?.cliVersion ?? "—" })}
- {t("settings.diag_sidecar", undefined, { info: orchestratorSidecarSummary() })}
+ {t("settings.diag_sidecar", { info: orchestratorSidecarSummary() })}
- {t("settings.diag_opencode_binary", undefined, { binary: formatOrchestratorBinary(props.orchestratorStatus?.binaries?.opencode ?? null) })}
+ {t("settings.diag_opencode_binary", { binary: formatOrchestratorBinary(props.orchestratorStatus?.binaries?.opencode ?? null) })}
- {t("settings.diag_runtime_workspace", undefined, { id: props.orchestratorStatus?.activeId ?? "—" })}
+ {t("settings.diag_runtime_workspace", { id: props.orchestratorStatus?.activeId ?? "—" })}
@@ -3215,11 +3215,11 @@ export default function SettingsView(props: SettingsViewProps) {
t("settings.no_worker_directory")}
- {t("settings.diag_last_attempt", undefined, { time: opencodeConnectTimestamp() ?? "—" })}
+ {t("settings.diag_last_attempt", { time: opencodeConnectTimestamp() ?? "—" })}
- {t("settings.diag_reason", undefined, { reason: props.opencodeConnectStatus?.reason ?? "" })}
+ {t("settings.diag_reason", { reason: props.opencodeConnectStatus?.reason ?? "" })}
@@ -3227,29 +3227,29 @@ export default function SettingsView(props: SettingsViewProps) {
- {t("settings.diag_healthy_ms", undefined, { ms: String(Math.round(metrics().healthyMs as number)) })}
+ {t("settings.diag_healthy_ms", { ms: String(Math.round(metrics().healthyMs as number)) })}
- {t("settings.diag_load_sessions_ms", undefined, { ms: String(Math.round(metrics().loadSessionsMs as number)) })}
+ {t("settings.diag_load_sessions_ms", { ms: String(Math.round(metrics().loadSessionsMs as number)) })}
- {t("settings.diag_pending_permissions_ms", undefined, { ms: String(Math.round(metrics().pendingPermissionsMs as number)) })}
+ {t("settings.diag_pending_permissions_ms", { ms: String(Math.round(metrics().pendingPermissionsMs as number)) })}
- {t("settings.diag_providers_ms", undefined, { ms: String(Math.round(metrics().providersMs as number)) })}
+ {t("settings.diag_providers_ms", { ms: String(Math.round(metrics().providersMs as number)) })}
- {t("settings.diag_total_ms", undefined, { ms: String(Math.round(metrics().totalMs as number)) })}
+ {t("settings.diag_total_ms", { ms: String(Math.round(metrics().totalMs as number)) })}
@@ -3291,7 +3291,7 @@ export default function SettingsView(props: SettingsViewProps) {
t("settings.base_url_unavailable")}
- {t("settings.diag_pid", undefined, { pid: String(props.openworkServerHostInfo?.pid ?? "—") })}
+ {t("settings.diag_pid", { pid: String(props.openworkServerHostInfo?.pid ?? "—") })}
@@ -3340,10 +3340,10 @@ export default function SettingsView(props: SettingsViewProps) {
t("settings.no_worker_directory")}
- {t("settings.diag_health_port", undefined, { port: String(props.opencodeRouterInfo?.healthPort ?? "—") })}
+ {t("settings.diag_health_port", { port: String(props.opencodeRouterInfo?.healthPort ?? "—") })}
- {t("settings.diag_pid", undefined, { pid: String(props.opencodeRouterInfo?.pid ?? "—") })}
+ {t("settings.diag_pid", { pid: String(props.opencodeRouterInfo?.pid ?? "—") })}
@@ -3418,26 +3418,26 @@ export default function SettingsView(props: SettingsViewProps) {
>
{(diag) => (
-
{t("settings.diag_started", undefined, { time: formatUptime(diag().uptimeMs) })}
+
{t("settings.diag_started", { time: formatUptime(diag().uptimeMs) })}
- {t("settings.diag_read_only", undefined, { value: diag().readOnly ? "true" : "false" })}
+ {t("settings.diag_read_only", { value: diag().readOnly ? "true" : "false" })}
- {t("settings.diag_approval", undefined, { mode: diag().approval.mode, ms: String(diag().approval.timeoutMs) })}
+ {t("settings.diag_approval", { mode: diag().approval.mode, ms: String(diag().approval.timeoutMs) })}
-
{t("settings.diag_workspaces", undefined, { count: String(diag().workspaceCount) })}
+
{t("settings.diag_workspaces", { count: String(diag().workspaceCount) })}
- {t("settings.diag_selected_workspace", undefined, { id: diag().selectedWorkspaceId ?? "—" })}
+ {t("settings.diag_selected_workspace", { id: diag().selectedWorkspaceId ?? "—" })}
- {t("settings.diag_runtime_workspace", undefined, { id: diag().activeWorkspaceId ?? "—" })}
+ {t("settings.diag_runtime_workspace", { id: diag().activeWorkspaceId ?? "—" })}
- {t("settings.diag_config_path", undefined, { path: diag().server.configPath ?? t("settings.diag_default") })}
+ {t("settings.diag_config_path", { path: diag().server.configPath ?? t("settings.diag_default") })}
-
{t("settings.diag_token_source", undefined, { source: diag().tokenSource.client })}
+
{t("settings.diag_token_source", { source: diag().tokenSource.client })}
- {t("settings.diag_host_token_source", undefined, { source: diag().tokenSource.host })}
+ {t("settings.diag_host_token_source", { source: diag().tokenSource.host })}
)}
@@ -3451,7 +3451,7 @@ export default function SettingsView(props: SettingsViewProps) {
{props.runtimeWorkspaceId
- ? t("settings.worker_id_label", undefined, { id: props.runtimeWorkspaceId })
+ ? t("settings.worker_id_label", { id: props.runtimeWorkspaceId })
: t("settings.worker_unresolved")}
@@ -3465,20 +3465,20 @@ export default function SettingsView(props: SettingsViewProps) {
>
{(caps) => (
-
{t("settings.cap_skills", undefined, { value: formatCapability(caps().skills) })}
-
{t("settings.cap_plugins", undefined, { value: formatCapability(caps().plugins) })}
-
{t("settings.cap_mcp", undefined, { value: formatCapability(caps().mcp) })}
-
{t("settings.cap_commands", undefined, { value: formatCapability(caps().commands) })}
-
{t("settings.cap_config", undefined, { value: formatCapability(caps().config) })}
+
{t("settings.cap_skills", { value: formatCapability(caps().skills) })}
+
{t("settings.cap_plugins", { value: formatCapability(caps().plugins) })}
+
{t("settings.cap_mcp", { value: formatCapability(caps().mcp) })}
+
{t("settings.cap_commands", { value: formatCapability(caps().commands) })}
+
{t("settings.cap_config", { value: formatCapability(caps().config) })}
- {t("settings.cap_proxy", undefined, {
+ {t("settings.cap_proxy", {
value: caps().proxy?.opencodeRouter
? t("settings.enabled")
: t("settings.disabled")
})}
- {t("settings.cap_browser_tools", undefined, {
+ {t("settings.cap_browser_tools", {
value: (() => {
const browser = caps().toolProviders?.browser;
if (!browser?.enabled) return t("settings.disabled");
@@ -3487,7 +3487,7 @@ export default function SettingsView(props: SettingsViewProps) {
})}
- {t("settings.cap_file_tools", undefined, {
+ {t("settings.cap_file_tools", {
value: (() => {
const files = caps().toolProviders?.files;
if (!files) return t("config.unavailable");
@@ -3500,7 +3500,7 @@ export default function SettingsView(props: SettingsViewProps) {
})}
- {t("settings.cap_sandbox", undefined, {
+ {t("settings.cap_sandbox", {
value: (() => {
const sandbox = caps().sandbox;
return sandbox
diff --git a/apps/app/src/app/pages/skills.tsx b/apps/app/src/app/pages/skills.tsx
index 9c2b68aa4..ffef12598 100644
--- a/apps/app/src/app/pages/skills.tsx
+++ b/apps/app/src/app/pages/skills.tsx
@@ -27,7 +27,7 @@ import {
Users,
X,
} from "lucide-solid";
-import { currentLocale, t } from "../../i18n";
+import { t } from "../../i18n";
import { DEFAULT_OPENWORK_PUBLISHER_BASE_URL, publishOpenworkBundleJson } from "../lib/publisher";
import { buildDenAuthUrl, createDenClient, DEFAULT_DEN_BASE_URL, readDenSettings, type DenOrgSkillHubSummary } from "../lib/den";
import { useStatusToasts, type AppStatusToastTone } from "../shell/status-toasts";
@@ -88,7 +88,6 @@ export default function SkillsView(props: SkillsViewProps) {
const platform = usePlatform();
const statusToasts = useStatusToasts();
// Translation helper that uses current language from i18n
- const translate = (key: string) => t(key, currentLocale());
const skillCreatorInstalled = createMemo(() =>
extensions.skills().some((skill) => skill.name === "skill-creator")
@@ -150,14 +149,14 @@ export default function SkillsView(props: SkillsViewProps) {
const shareTeamOrgLabel = createMemo(() => {
cloudSessionNonce();
const name = readDenSettings().activeOrgName?.trim();
- return name || translate("skills.share_team_org_fallback");
+ return name || t("skills.share_team_org_fallback");
});
const shareTeamDisabledReason = createMemo(() => {
if (!shareCloudSignedIn()) return null;
const settings = readDenSettings();
if (!settings.activeOrgId?.trim() && !settings.activeOrgSlug?.trim()) {
- return translate("skills.share_team_choose_org");
+ return t("skills.share_team_choose_org");
}
return null;
});
@@ -165,17 +164,17 @@ export default function SkillsView(props: SkillsViewProps) {
const shareModalSubtitle = createMemo(() => {
switch (shareSubView()) {
case "public":
- return translate("skills.share_subtitle_public");
+ return t("skills.share_subtitle_public");
case "team":
- return translate("skills.share_subtitle_team");
+ return t("skills.share_subtitle_team");
default:
- return translate("skills.share_chooser_subtitle");
+ return t("skills.share_chooser_subtitle");
}
});
const shareHubSelectOptions = createMemo(
(): SelectMenuOption[] => [
- { value: "", label: translate("skills.share_team_hub_none") },
+ { value: "", label: t("skills.share_team_hub_none") },
...shareManageableHubs().map((h) => ({ value: h.id, label: h.name })),
],
);
@@ -216,7 +215,7 @@ export default function SkillsView(props: SkillsViewProps) {
orgId = res.orgs[0]?.id ?? "";
}
if (!orgId) {
- throw new Error(translate("skills.share_team_choose_org"));
+ throw new Error(t("skills.share_team_choose_org"));
}
const hubs = await client.listOrgSkillHubSummaries(orgId);
@@ -237,7 +236,7 @@ export default function SkillsView(props: SkillsViewProps) {
});
});
- const maskError = (value: unknown) => (value instanceof Error ? value.message : translate("common.something_went_wrong"));
+ const maskError = (value: unknown) => (value instanceof Error ? value.message : t("common.something_went_wrong"));
const showToast = (title: string, tone: AppStatusToastTone = "info") => {
statusToasts.showToast({ title, tone });
};
@@ -245,7 +244,7 @@ export default function SkillsView(props: SkillsViewProps) {
const hubRepoKey = (repo: HubSkillRepo) => `${repo.owner}/${repo.repo}@${repo.ref}`;
const defaultHubRepoKey = "different-ai/openwork-hub@main";
- const activeHubRepoLabel = createMemo(() => (extensions.hubRepo() ? hubRepoKey(extensions.hubRepo()!) : translate("skills.no_hub_repo_label")));
+ const activeHubRepoLabel = createMemo(() => (extensions.hubRepo() ? hubRepoKey(extensions.hubRepo()!) : t("skills.no_hub_repo_label")));
const hasDefaultHubRepo = createMemo(() => extensions.hubRepos().some((repo) => hubRepoKey(repo) === defaultHubRepoKey));
@@ -273,7 +272,7 @@ export default function SkillsView(props: SkillsViewProps) {
const repo = customRepoName().trim();
const ref = customRepoRef().trim() || "main";
if (!owner || !repo) {
- setCustomRepoError(translate("skills.owner_repo_required"));
+ setCustomRepoError(t("skills.owner_repo_required"));
return;
}
extensions.addHubRepo({ owner, repo, ref });
@@ -333,7 +332,7 @@ export default function SkillsView(props: SkillsViewProps) {
denUiTick();
const name = readDenSettings().activeOrgName?.trim();
if (name) return name;
- return translate("skills.cloud_org_fallback");
+ return t("skills.cloud_org_fallback");
});
const cloudSessionReady = createMemo(() => {
@@ -350,16 +349,16 @@ export default function SkillsView(props: SkillsViewProps) {
const installSkillCreator = async () => {
if (props.busy || installingSkillCreator()) return;
if (!props.canInstallSkillCreator) {
- showToast(props.accessHint ?? translate("skills.host_only_error"), "warning");
+ showToast(props.accessHint ?? t("skills.host_only_error"), "warning");
return;
}
setInstallingSkillCreator(true);
- showToast(translate("skills.installing_skill_creator"));
+ showToast(t("skills.installing_skill_creator"));
try {
const result = await extensions.installSkillCreator();
showToast(result.message, "success");
} catch (e) {
- showToast(e instanceof Error ? e.message : translate("skills.install_failed"), "error");
+ showToast(e instanceof Error ? e.message : t("skills.install_failed"), "error");
} finally {
setInstallingSkillCreator(false);
}
@@ -368,12 +367,12 @@ export default function SkillsView(props: SkillsViewProps) {
const installFromCloud = async (skill: DenOrgSkillCard) => {
if (props.busy || installingCloudSkillId()) return;
setInstallingCloudSkillId(skill.id);
- showToast(t("skills.cloud_installing", currentLocale(), { title: skill.title }));
+ showToast(t("skills.cloud_installing", { title: skill.title }));
try {
const result = await extensions.installCloudOrgSkill(skill);
showToast(result.message, result.ok ? "success" : "error");
} catch (e) {
- showToast(e instanceof Error ? e.message : translate("skills.install_failed"), "error");
+ showToast(e instanceof Error ? e.message : t("skills.install_failed"), "error");
} finally {
setInstallingCloudSkillId(null);
}
@@ -387,12 +386,12 @@ export default function SkillsView(props: SkillsViewProps) {
const installFromHub = async (skill: HubSkillCard) => {
if (props.busy || installingHubSkill()) return;
setInstallingHubSkill(skill.name);
- showToast(`${translate("skills.installing_prefix")} ${skill.name}…`);
+ showToast(`${t("skills.installing_prefix")} ${skill.name}…`);
try {
const result = await extensions.installHubSkill(skill.name);
showToast(result.message, "success");
} catch (e) {
- showToast(e instanceof Error ? e.message : translate("skills.install_failed"), "error");
+ showToast(e instanceof Error ? e.message : t("skills.install_failed"), "error");
} finally {
setInstallingHubSkill(null);
}
@@ -466,7 +465,7 @@ export default function SkillsView(props: SkillsViewProps) {
skillText: skill.content,
skillHubId: hubId || null,
});
- setShareTeamSuccess(t("skills.share_team_success", currentLocale(), { org: orgName }));
+ setShareTeamSuccess(t("skills.share_team_success", { org: orgName }));
window.dispatchEvent(
new CustomEvent<{ orgId: string }>("openwork-den-org-skills-changed", { detail: { orgId } }),
);
@@ -488,7 +487,7 @@ export default function SkillsView(props: SkillsViewProps) {
try {
const skill = await extensions.readSkill(target.name);
- if (!skill) throw new Error(translate("skills.skill_load_failed"));
+ if (!skill) throw new Error(t("skills.skill_load_failed"));
const payload: SkillBundleV1 = {
schemaVersion: 1,
@@ -508,7 +507,7 @@ export default function SkillsView(props: SkillsViewProps) {
setShareUrl(result.url);
try {
await navigator.clipboard.writeText(result.url);
- showToast(translate("skills.link_copied"), "success");
+ showToast(t("skills.link_copied"), "success");
} catch {
// ignore
}
@@ -524,9 +523,9 @@ export default function SkillsView(props: SkillsViewProps) {
if (!url) return;
try {
await navigator.clipboard.writeText(url);
- showToast(translate("skills.link_copied"), "success");
+ showToast(t("skills.link_copied"), "success");
} catch {
- setShareError(translate("skills.copy_link_failed"));
+ setShareError(t("skills.copy_link_failed"));
}
};
@@ -540,12 +539,12 @@ export default function SkillsView(props: SkillsViewProps) {
try {
const result = await extensions.readSkill(skill.name);
if (!result) {
- setSelectedError(translate("skills.skill_load_failed"));
+ setSelectedError(t("skills.skill_load_failed"));
return;
}
setSelectedContent(result.content);
} catch (e) {
- setSelectedError(e instanceof Error ? e.message : translate("skills.skill_load_failed"));
+ setSelectedError(e instanceof Error ? e.message : t("skills.skill_load_failed"));
} finally {
setSelectedLoading(false);
}
@@ -574,7 +573,7 @@ export default function SkillsView(props: SkillsViewProps) {
);
setSelectedDirty(false);
} catch (e) {
- setSelectedError(e instanceof Error ? e.message : translate("skills.save_failed"));
+ setSelectedError(e instanceof Error ? e.message : t("skills.save_failed"));
}
};
@@ -597,7 +596,7 @@ export default function SkillsView(props: SkillsViewProps) {
const runDesktopAction = (action: () => void | Promise
) => {
if (props.busy) return;
if (!props.canUseDesktopTools) {
- showToast(translate("skills.desktop_required"), "warning");
+ showToast(t("skills.desktop_required"), "warning");
return;
}
void Promise.resolve(action());
@@ -616,10 +615,10 @@ export default function SkillsView(props: SkillsViewProps) {
- {translate("skills.title")}
+ {t("skills.title")}
- {translate("skills.worker_profile_desc")}
+ {t("skills.worker_profile_desc")}
@@ -631,7 +630,7 @@ export default function SkillsView(props: SkillsViewProps) {
class={pillSecondaryClass}
>
- {translate("skills.import_local_skill")}
+ {t("skills.import_local_skill")}
- {translate("skills.reveal_folder")}
+ {t("skills.reveal_folder")}
- {translate("skills.create_in_chat")}
+ {t("skills.create_in_chat")}
@@ -661,7 +660,7 @@ export default function SkillsView(props: SkillsViewProps) {
type="text"
value={searchQuery()}
onInput={(event) => setSearchQuery(event.currentTarget.value)}
- placeholder={translate("skills.catalog_search_placeholder")}
+ placeholder={t("skills.catalog_search_placeholder")}
class="w-full rounded-xl border border-dls-border bg-dls-surface py-3 pl-11 pr-4 text-[14px] text-dls-text focus:outline-none focus:ring-2 focus:ring-[rgba(var(--dls-accent-rgb),0.12)]"
/>
@@ -675,12 +674,12 @@ export default function SkillsView(props: SkillsViewProps) {
class={activeFilter() === filter ? pillPrimaryClass : pillGhostClass}
>
{filter === "all"
- ? translate("skills.filter_all")
+ ? t("skills.filter_all")
: filter === "installed"
- ? translate("skills.filter_installed")
+ ? t("skills.filter_installed")
: filter === "cloud"
- ? translate("skills.filter_cloud")
- : translate("skills.filter_hub")}
+ ? t("skills.filter_cloud")
+ : t("skills.filter_hub")}
)}
@@ -691,7 +690,7 @@ export default function SkillsView(props: SkillsViewProps) {
class={pillSecondaryClass}
>
- {translate("common.refresh")}
+ {t("common.refresh")}
@@ -706,7 +705,7 @@ export default function SkillsView(props: SkillsViewProps) {
when={!props.accessHint && !props.canInstallSkillCreator && !props.canUseDesktopTools}
>
- {translate("skills.host_mode_only")}
+ {t("skills.host_mode_only")}
@@ -720,19 +719,19 @@ export default function SkillsView(props: SkillsViewProps) {
-
{translate("skills.installed")}
+
{t("skills.installed")}
- {translate("skills.installed_desc")}
+ {t("skills.installed_desc")}
-
{t("skills.shown_count", currentLocale(), { count: filteredSkills().length })}
+
{t("skills.shown_count", { count: filteredSkills().length })}
- {translate("skills.no_skills")}
+ {t("skills.no_skills")}
}
>
@@ -764,7 +763,7 @@ export default function SkillsView(props: SkillsViewProps) {
OpenWork
- {translate("skills.no_description")}
}>
+ {t("skills.no_description")}}>
{skill.description}
@@ -773,7 +772,7 @@ export default function SkillsView(props: SkillsViewProps) {
-
{translate("skills.installed_status")}
+
{t("skills.installed_status")}
- {translate("skills.share_title")}
+ {t("skills.share_title")}
- {translate("common.edit")}
+ {t("common.edit")}
- {translate("common.remove")}
+ {t("common.remove")}
@@ -837,9 +836,9 @@ export default function SkillsView(props: SkillsViewProps) {
{cloudOrgLabel()}
-
{translate("skills.cloud_section_title")}
+
{t("skills.cloud_section_title")}
- {translate("skills.cloud_section_subtitle")}
+ {t("skills.cloud_section_subtitle")}
@@ -850,7 +849,7 @@ export default function SkillsView(props: SkillsViewProps) {
class={pillSecondaryClass}
>
- {translate("skills.cloud_refresh")}
+ {t("skills.cloud_refresh")}
@@ -861,15 +860,15 @@ export default function SkillsView(props: SkillsViewProps) {
when={cloudNeedsSignIn()}
fallback={
-
{translate("skills.cloud_choose_org_hint")}
-
{translate("skills.cloud_choose_org_detail")}
+
{t("skills.cloud_choose_org_hint")}
+
{t("skills.cloud_choose_org_detail")}
}
>
-
{translate("skills.cloud_sign_in_hint")}
+
{t("skills.cloud_sign_in_hint")}
openCloudSignIn()}>
- {translate("skills.cloud_sign_in")}
+ {t("skills.cloud_sign_in")}
@@ -888,8 +887,8 @@ export default function SkillsView(props: SkillsViewProps) {
fallback={
{extensions.cloudOrgSkills().length === 0
- ? translate("skills.cloud_org_empty")
- : translate("skills.cloud_no_search_matches")}
+ ? t("skills.cloud_org_empty")
+ : t("skills.cloud_no_search_matches")}
}
>
@@ -912,21 +911,21 @@ export default function SkillsView(props: SkillsViewProps) {
- {t("skills.cloud_hub_label", currentLocale(), { name: skill.hubName ?? "" })}
+ {t("skills.cloud_hub_label", { name: skill.hubName ?? "" })}
- {translate("skills.cloud_shared_org")}
+ {t("skills.cloud_shared_org")}
- {translate("skills.cloud_shared_public")}
+ {t("skills.cloud_shared_public")}
- {translate("skills.cloud_footer_label")}
+ {t("skills.cloud_footer_label")}
{installingCloudSkillId() === skill.id
- ? translate("skills.cloud_installing_short")
- : translate("skills.cloud_add_skill")}
+ ? t("skills.cloud_installing_short")
+ : t("skills.cloud_add_skill")}
@@ -961,9 +960,9 @@ export default function SkillsView(props: SkillsViewProps) {
-
{translate("skills.available_from_hub")}
+
{t("skills.available_from_hub")}
- {translate("skills.hub_desc")}
+ {t("skills.hub_desc")}
@@ -977,34 +976,34 @@ export default function SkillsView(props: SkillsViewProps) {
disabled={props.busy || hasDefaultHubRepo()}
>
- {translate("skills.add_openwork_hub")}
+ {t("skills.add_openwork_hub")}
- {translate("skills.add_git_repo")}
+ {t("skills.add_git_repo")}
void extensions.refreshHubSkills({ force: true })}
disabled={props.busy}
class={pillSecondaryClass}
- title={translate("skills.refresh_hub_title")}
+ title={t("skills.refresh_hub_title")}
>
- {translate("skills.refresh_hub")}
+ {t("skills.refresh_hub")}
- {translate("skills.source_label")}: {activeHubRepoLabel()}
+ {t("skills.source_label")}: {activeHubRepoLabel()}
@@ -1031,7 +1030,7 @@ export default function SkillsView(props: SkillsViewProps) {
void extensions.refreshHubSkills({ force: true });
}}
disabled={props.busy}
- title={translate("skills.remove_saved_repo")}
+ title={t("skills.remove_saved_repo")}
>
×
@@ -1052,7 +1051,7 @@ export default function SkillsView(props: SkillsViewProps) {
when={filteredHubSkills().length}
fallback={
- {extensions.hubRepo() ? translate("skills.no_hub_skills") : translate("skills.no_hub_repo_selected")}
+ {extensions.hubRepo() ? t("skills.no_hub_skills") : t("skills.no_hub_repo_selected")}
}
>
@@ -1069,7 +1068,7 @@ export default function SkillsView(props: SkillsViewProps) {
{skill.name}
{t("skills.from_repo", currentLocale(), { owner: skill.source.owner, repo: skill.source.repo })}}
+ fallback={{t("skills.from_repo", { owner: skill.source.owner, repo: skill.source.repo })}
}
>
{skill.description}
@@ -1078,8 +1077,8 @@ export default function SkillsView(props: SkillsViewProps) {
{skill.source.owner}/{skill.source.repo}
-
- {t("skills.trigger_label", currentLocale(), { trigger: skill.trigger ?? "" })}
+
+ {t("skills.trigger_label", { trigger: skill.trigger ?? "" })}
@@ -1087,7 +1086,7 @@ export default function SkillsView(props: SkillsViewProps) {
- {translate("skills.hub_label")}
+ {t("skills.hub_label")}
- {installingHubSkill() === skill.name ? translate("skills.installing") : translate("common.add")}
+ {installingHubSkill() === skill.name ? t("skills.installing") : t("common.add")}
@@ -1135,14 +1134,14 @@ export default function SkillsView(props: SkillsViewProps) {
disabled={!selectedDirty() || props.busy}
onClick={() => void saveSelectedSkill()}
>
- {translate("common.save")}
+ {t("common.save")}
- {translate("common.close")}
+ {t("common.close")}
@@ -1155,7 +1154,7 @@ export default function SkillsView(props: SkillsViewProps) {
{translate("skills.loading")}}
+ fallback={{t("skills.loading")}
}
>
-
{translate("skills.share_title")}
+
{t("skills.share_title")}
{shareTarget()?.name}
@@ -1236,8 +1235,8 @@ export default function SkillsView(props: SkillsViewProps) {
type="button"
onClick={closeShareLink}
class={modalHeaderButtonClass}
- aria-label={translate("skills.share_close")}
- title={translate("skills.share_close")}
+ aria-label={t("skills.share_close")}
+ title={t("skills.share_close")}
>
@@ -1247,14 +1246,14 @@ export default function SkillsView(props: SkillsViewProps) {
setShareSubView("team")}
/>
setShareSubView("public")}
/>
@@ -1263,11 +1262,11 @@ export default function SkillsView(props: SkillsViewProps) {
-
{translate("skills.share_public_intro")}
+
{t("skills.share_public_intro")}
- {shareBusy() ? translate("skills.share_public_creating") : translate("skills.share_public_regenerate")}
+ {shareBusy() ? t("skills.share_public_creating") : t("skills.share_public_regenerate")}
- {translate("skills.share_done")}
+ {t("skills.share_done")}
@@ -1315,7 +1314,7 @@ export default function SkillsView(props: SkillsViewProps) {
-
{translate("skills.share_team_intro")}
+
{t("skills.share_team_intro")}
@@ -1344,7 +1343,7 @@ export default function SkillsView(props: SkillsViewProps) {
id="skills-share-hub-label"
class="mb-1.5 block text-[13px] font-medium text-dls-text"
>
- {translate("skills.share_team_hub_label")}
+ {t("skills.share_team_hub_label")}
- {translate("skills.share_team_hubs_loading")}
+ {t("skills.share_team_hubs_loading")}
@@ -1380,20 +1379,20 @@ export default function SkillsView(props: SkillsViewProps) {
class={`${sharePillPrimaryClass} mt-4 w-full`}
>
{!shareCloudSignedIn()
- ? translate("skills.share_team_sign_in")
+ ? t("skills.share_team_sign_in")
: shareTeamBusy()
- ? translate("skills.share_team_saving")
- : translate("skills.share_team_save")}
+ ? t("skills.share_team_saving")
+ : t("skills.share_team_save")}
- {translate("skills.share_team_sign_in_hint")}
+ {t("skills.share_team_sign_in_hint")}
- {translate("skills.share_done")}
+ {t("skills.share_done")}
@@ -1408,15 +1407,15 @@ export default function SkillsView(props: SkillsViewProps) {
-
{translate("skills.add_custom_repo")}
+
{t("skills.add_custom_repo")}
- {translate("skills.github_repo_hint")}
+ {t("skills.github_repo_hint")}
diff --git a/apps/app/src/app/session/actions-store.ts b/apps/app/src/app/session/actions-store.ts
index 5ba8fd6ca..22e0bd1e4 100644
--- a/apps/app/src/app/session/actions-store.ts
+++ b/apps/app/src/app/session/actions-store.ts
@@ -9,7 +9,7 @@ import type {
TextPartInput,
} from "@opencode-ai/sdk/v2/client";
-import { t, currentLocale } from "../../i18n";
+import { t } from "../../i18n";
import { unwrap } from "../lib/opencode";
import {
abortSession as abortSessionTyped,
@@ -232,8 +232,8 @@ export function createSessionActionsStore(options: {
const generic = raw && /^unknown\s+error$/i.test(raw);
const heading = (() => {
- if (status === 401 || status === 403) return t("app.error_auth_failed", currentLocale());
- if (status === 429) return t("app.error_rate_limit", currentLocale());
+ if (status === 401 || status === 403) return t("app.error_auth_failed");
+ if (status === 429) return t("app.error_rate_limit");
if (provider) return `Provider error (${provider})`;
return fallback;
})();
@@ -257,7 +257,7 @@ export function createSessionActionsStore(options: {
const assertNoClientError = (result: unknown) => {
const maybe = result as { error?: unknown } | null | undefined;
if (!maybe || maybe.error === undefined) return;
- throw new Error(describeProviderError(maybe.error, t("app.error_request_failed", currentLocale())));
+ throw new Error(describeProviderError(maybe.error, t("app.error_request_failed")));
};
const selectedSessionAgent = createMemo(() => {
@@ -388,7 +388,7 @@ export function createSessionActionsStore(options: {
error: e instanceof Error ? e.message : safeStringify(e),
workspaceId: id,
});
- const message = e instanceof Error ? e.message : t("app.unknown_error", currentLocale());
+ const message = e instanceof Error ? e.message : t("app.unknown_error");
options.setError(addOpencodeCacheHint(message));
return undefined;
} finally {
@@ -449,7 +449,7 @@ export function createSessionActionsStore(options: {
const compactCommand = resolvedDraft.command?.name === "compact" || compactShortcut;
const commandName = compactCommand ? "compact" : (resolvedDraft.command?.name ?? null);
if (compactCommand && !options.selectedSessionId()) {
- options.setError(t("app.error_compact_no_session", currentLocale()));
+ options.setError(t("app.error_compact_no_session"));
return;
}
@@ -511,7 +511,7 @@ export function createSessionActionsStore(options: {
const command = resolvedDraft.command;
if (!command) {
- throw new Error(t("app.error_command_not_resolved", currentLocale()));
+ throw new Error(t("app.error_command_not_resolved"));
}
const modelString = `${model.providerID}/${model.modelID}`;
@@ -591,17 +591,17 @@ export function createSessionActionsStore(options: {
async function compactCurrentSession(sessionIdOverride?: string) {
const c = options.client();
if (!c) {
- throw new Error(t("app.error_not_connected", currentLocale()));
+ throw new Error(t("app.error_not_connected"));
}
const sessionID = (sessionIdOverride ?? options.selectedSessionId() ?? "").trim();
if (!sessionID) {
- throw new Error(t("app.error_compact_no_session_id", currentLocale()));
+ throw new Error(t("app.error_compact_no_session_id"));
}
const visible = options.messages();
if (!visible.length) {
- throw new Error(t("app.error_compact_empty", currentLocale()));
+ throw new Error(t("app.error_compact_empty"));
}
const model = options.selectedSessionModel();
@@ -716,7 +716,7 @@ export function createSessionActionsStore(options: {
async function renameSessionTitle(sessionID: string, title: string) {
const trimmed = title.trim();
if (!trimmed) {
- throw new Error(t("app.error_session_name_required", currentLocale()));
+ throw new Error(t("app.error_session_name_required"));
}
await options.renameSession(sessionID, trimmed);
@@ -728,7 +728,7 @@ export function createSessionActionsStore(options: {
if (!trimmed) return;
const c = options.client();
if (!c) {
- throw new Error(t("app.error_not_connected", currentLocale()));
+ throw new Error(t("app.error_not_connected"));
}
const root = options.selectedWorkspaceRoot().trim();
@@ -780,7 +780,7 @@ export function createSessionActionsStore(options: {
const BUILTIN_COMPACT_COMMAND = {
id: "builtin:compact",
name: "compact",
- description: t("app.compact_command_desc", currentLocale()),
+ description: t("app.compact_command_desc"),
source: "command" as const,
};
diff --git a/apps/app/src/app/session/share-workspace.ts b/apps/app/src/app/session/share-workspace.ts
index c8ac73f70..73ea22c4b 100644
--- a/apps/app/src/app/session/share-workspace.ts
+++ b/apps/app/src/app/session/share-workspace.ts
@@ -499,7 +499,7 @@ export function createShareWorkspaceState(options: ShareWorkspaceStateOptions) {
});
setShareWorkspaceProfileTeamSuccess(
- t("session.share_saved_to_org", undefined, { name: created.name, org: orgName || t("session.share_team_fallback_name") }),
+ t("session.share_saved_to_org", { name: created.name, org: orgName || t("session.share_team_fallback_name") }),
);
} catch (error) {
const warnings = readWorkspaceExportWarnings(error);
diff --git a/apps/app/src/app/shell/deep-links.ts b/apps/app/src/app/shell/deep-links.ts
index 70c1cbc78..e59013d12 100644
--- a/apps/app/src/app/shell/deep-links.ts
+++ b/apps/app/src/app/shell/deep-links.ts
@@ -1,6 +1,6 @@
import { createEffect, createSignal, type Accessor } from "solid-js";
-import { t, currentLocale } from "../../i18n";
+import { t } from "../../i18n";
import { createDenClient, writeDenSettings } from "../lib/den";
import { dispatchDenSessionUpdated } from "../lib/den-session-events";
@@ -169,7 +169,7 @@ export function createDeepLinksController(options: {
const openDebugDeepLink = async (rawUrl: string): Promise<{ ok: boolean; message: string }> => {
const parsed = parseDebugDeepLinkInput(rawUrl);
if (!parsed) {
- return { ok: false, message: t("app.error_deep_link_unrecognized", currentLocale()) };
+ return { ok: false, message: t("app.error_deep_link_unrecognized") };
}
options.setError(null);
@@ -179,12 +179,12 @@ export function createDeepLinksController(options: {
}
if (parsed.kind === "auth") {
setPendingDenAuthDeepLink(parsed.link);
- return { ok: true, message: t("app.deep_link_auth_queued", currentLocale()) };
+ return { ok: true, message: t("app.deep_link_auth_queued") };
}
setPendingRemoteConnectDeepLink(parsed.kind === "remote" ? parsed.link : null);
options.setSettingsTab("automations");
- return { ok: true, message: t("app.deep_link_remote_queued", currentLocale()) };
+ return { ok: true, message: t("app.deep_link_remote_queued") };
};
createEffect(() => {
@@ -204,7 +204,7 @@ export function createDeepLinksController(options: {
.exchangeDesktopHandoff(pending.grant)
.then((result) => {
if (!result.token) {
- throw new Error(t("app.error_desktop_signin", currentLocale()));
+ throw new Error(t("app.error_desktop_signin"));
}
writeDenSettings({
@@ -227,7 +227,7 @@ export function createDeepLinksController(options: {
recentHandledDenGrants.delete(pending.grant);
dispatchDenSessionUpdated({
status: "error",
- message: error instanceof Error ? error.message : t("app.error_cloud_signin", currentLocale()),
+ message: error instanceof Error ? error.message : t("app.error_cloud_signin"),
});
})
.finally(() => {
diff --git a/apps/app/src/app/shell/settings-shell.tsx b/apps/app/src/app/shell/settings-shell.tsx
index bf2e1616d..afb67e458 100644
--- a/apps/app/src/app/shell/settings-shell.tsx
+++ b/apps/app/src/app/shell/settings-shell.tsx
@@ -943,7 +943,7 @@ export default function SettingsShell(props: SettingsShellProps) {
}
if (state === "downloading") {
const percent = updateDownloadPercent();
- return percent == null ? t("session.downloading") : t("session.downloading_percent", undefined, { percent });
+ return percent == null ? t("session.downloading") : t("session.downloading_percent", { percent });
}
return t("session.update_available");
});
@@ -999,11 +999,11 @@ export default function SettingsShell(props: SettingsShellProps) {
const state = props.updateStatus?.state;
if (state === "ready") {
return props.anyActiveRuns
- ? t("session.update_ready_stop_runs_title", undefined, { version })
- : t("session.restart_update_title", undefined, { version });
+ ? t("session.update_ready_stop_runs_title", { version })
+ : t("session.restart_update_title", { version });
}
- if (state === "downloading") return t("session.downloading_update_title", undefined, { version });
- return t("session.update_available_title", undefined, { version });
+ if (state === "downloading") return t("session.downloading_update_title", { version });
+ return t("session.update_available_title", { version });
});
const handleUpdatePillClick = () => {
diff --git a/apps/app/src/app/utils/index.ts b/apps/app/src/app/utils/index.ts
index 39d24c186..bc1378708 100644
--- a/apps/app/src/app/utils/index.ts
+++ b/apps/app/src/app/utils/index.ts
@@ -261,15 +261,15 @@ export function formatRelativeTime(timestampMs: number) {
}
if (delta < 60_000) {
- return t("time.seconds_ago", undefined, { count: Math.max(1, Math.round(delta / 1000)) });
+ return t("time.seconds_ago", { count: Math.max(1, Math.round(delta / 1000)) });
}
if (delta < 60 * 60_000) {
- return t("time.minutes_ago", undefined, { count: Math.max(1, Math.round(delta / 60_000)) });
+ return t("time.minutes_ago", { count: Math.max(1, Math.round(delta / 60_000)) });
}
if (delta < 24 * 60 * 60_000) {
- return t("time.hours_ago", undefined, { count: Math.max(1, Math.round(delta / (60 * 60_000))) });
+ return t("time.hours_ago", { count: Math.max(1, Math.round(delta / (60 * 60_000))) });
}
return new Date(timestampMs).toLocaleDateString();
diff --git a/apps/app/src/app/workspace/create-remote-workspace-modal.tsx b/apps/app/src/app/workspace/create-remote-workspace-modal.tsx
index 96d008182..d5841ee6b 100644
--- a/apps/app/src/app/workspace/create-remote-workspace-modal.tsx
+++ b/apps/app/src/app/workspace/create-remote-workspace-modal.tsx
@@ -2,7 +2,7 @@ import { Show, createEffect, createMemo, createSignal } from "solid-js";
import { X } from "lucide-solid";
-import { currentLocale, t } from "../../i18n";
+import { t } from "../../i18n";
import {
modalHeaderButtonClass,
modalHeaderClass,
@@ -20,7 +20,6 @@ import type { CreateRemoteWorkspaceModalProps } from "./types";
export default function CreateRemoteWorkspaceModal(props: CreateRemoteWorkspaceModalProps) {
let inputRef: HTMLInputElement | undefined;
- const translate = (key: string) => t(key, currentLocale());
const [openworkHostUrl, setOpenworkHostUrl] = createSignal("");
const [openworkToken, setOpenworkToken] = createSignal("");
@@ -29,9 +28,9 @@ export default function CreateRemoteWorkspaceModal(props: CreateRemoteWorkspaceM
const [displayName, setDisplayName] = createSignal("");
const showClose = () => props.showClose ?? true;
- const title = () => props.title ?? translate("dashboard.create_remote_workspace_title");
- const subtitle = () => props.subtitle ?? translate("dashboard.create_remote_workspace_subtitle");
- const confirmLabel = () => props.confirmLabel ?? translate("dashboard.create_remote_workspace_confirm");
+ const title = () => props.title ?? t("dashboard.create_remote_workspace_title");
+ const subtitle = () => props.subtitle ?? t("dashboard.create_remote_workspace_subtitle");
+ const confirmLabel = () => props.confirmLabel ?? t("dashboard.create_remote_workspace_confirm");
const isInline = () => props.inline ?? false;
const submitting = () => props.submitting ?? false;
@@ -106,7 +105,7 @@ export default function CreateRemoteWorkspaceModal(props: CreateRemoteWorkspaceM
disabled={submitting()}
class={pillGhostClass}
>
- {translate("common.cancel")}
+ {t("common.cancel")}
{confirmLabel()}
diff --git a/apps/app/src/app/workspace/create-workspace-modal.tsx b/apps/app/src/app/workspace/create-workspace-modal.tsx
index 9cbf5b7a0..0db069390 100644
--- a/apps/app/src/app/workspace/create-workspace-modal.tsx
+++ b/apps/app/src/app/workspace/create-workspace-modal.tsx
@@ -2,7 +2,7 @@ import { Show, createEffect, createMemo, createSignal, onCleanup } from "solid-j
import { ArrowLeft, Cloud, FolderPlus, Globe, Loader2, X } from "lucide-solid";
-import { currentLocale, t } from "../../i18n";
+import { t } from "../../i18n";
import { usePlatform } from "../context/platform";
import {
buildDenAuthUrl,
@@ -45,20 +45,20 @@ function workerStatusMeta(status: string, translate: (key: string) => string) {
const normalized = status.trim().toLowerCase();
switch (normalized) {
case "healthy":
- return { label: translate("dashboard.worker_status_ready"), tone: "ready" as const, canOpen: true };
+ return { label: t("dashboard.worker_status_ready"), tone: "ready" as const, canOpen: true };
case "provisioning":
case "starting":
- return { label: translate("dashboard.worker_status_starting"), tone: "warning" as const, canOpen: false };
+ return { label: t("dashboard.worker_status_starting"), tone: "warning" as const, canOpen: false };
case "failed":
case "error":
- return { label: translate("dashboard.worker_status_attention"), tone: "error" as const, canOpen: false };
+ return { label: t("dashboard.worker_status_attention"), tone: "error" as const, canOpen: false };
case "stopped":
- return { label: translate("dashboard.worker_status_stopped"), tone: "neutral" as const, canOpen: false };
+ return { label: t("dashboard.worker_status_stopped"), tone: "neutral" as const, canOpen: false };
default:
return {
label: normalized
? `${normalized.slice(0, 1).toUpperCase()}${normalized.slice(1)}`
- : translate("common.unknown"),
+ : t("common.unknown"),
tone: "neutral" as const,
canOpen: normalized === "ready",
};
@@ -66,9 +66,9 @@ function workerStatusMeta(status: string, translate: (key: string) => string) {
}
function formatTemplateTimestamp(value: string | null, translate: (key: string) => string) {
- if (!value) return translate("dashboard.recently_updated");
+ if (!value) return t("dashboard.recently_updated");
const date = new Date(value);
- if (Number.isNaN(date.getTime())) return translate("dashboard.recently_updated");
+ if (Number.isNaN(date.getTime())) return t("dashboard.recently_updated");
return new Intl.DateTimeFormat(undefined, {
month: "short",
day: "numeric",
@@ -78,19 +78,18 @@ function formatTemplateTimestamp(value: string | null, translate: (key: string)
function templateCreatorLabel(template: DenTemplate, translate: (key: string) => string) {
const creator = template.creator;
- if (!creator) return translate("dashboard.unknown_creator");
- return creator.name?.trim() || creator.email?.trim() || translate("dashboard.unknown_creator");
+ if (!creator) return t("dashboard.unknown_creator");
+ return creator.name?.trim() || creator.email?.trim() || t("dashboard.unknown_creator");
}
function workerSecondaryLine(worker: DenWorkerSummary, translate: (key: string) => string) {
- const parts = [worker.provider?.trim() || translate("dashboard.cloud_worker")];
+ const parts = [worker.provider?.trim() || t("dashboard.cloud_worker")];
if (worker.instanceUrl?.trim()) parts.push(worker.instanceUrl.trim());
return parts.join(" · ");
}
export default function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
let remoteUrlRef: HTMLInputElement | undefined;
- const translate = (key: string, params?: Record) => t(key, currentLocale(), params);
const platform = usePlatform();
const [screen, setScreen] = createSignal("chooser");
@@ -186,28 +185,28 @@ export default function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
const headerTitle = createMemo(() => {
switch (screen()) {
case "local":
- return translate("dashboard.create_local_workspace_title");
+ return t("dashboard.create_local_workspace_title");
case "remote":
- return translate("dashboard.create_remote_custom_title");
+ return t("dashboard.create_remote_custom_title");
case "shared":
- return translate("dashboard.create_shared_title");
+ return t("dashboard.create_shared_title");
default:
- return props.title ?? translate("dashboard.create_workspace_title");
+ return props.title ?? t("dashboard.create_workspace_title");
}
});
const headerSubtitle = createMemo(() => {
switch (screen()) {
case "local":
- return translate("dashboard.create_local_workspace_subtitle");
+ return t("dashboard.create_local_workspace_subtitle");
case "remote":
- return translate("dashboard.create_remote_custom_subtitle");
+ return t("dashboard.create_remote_custom_subtitle");
case "shared":
return isSignedIn()
- ? translate("dashboard.create_shared_subtitle_signed_in")
- : translate("dashboard.create_shared_subtitle_signed_out");
+ ? t("dashboard.create_shared_subtitle_signed_in")
+ : t("dashboard.create_shared_subtitle_signed_out");
default:
- return props.subtitle ?? translate("dashboard.create_workspace_subtitle");
+ return props.subtitle ?? t("dashboard.create_workspace_subtitle");
}
});
@@ -324,7 +323,7 @@ export default function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
applyActiveOrg(nextActive);
} catch (error) {
setOrgsError(
- error instanceof Error ? error.message : translate("dashboard.error_load_orgs"),
+ error instanceof Error ? error.message : t("dashboard.error_load_orgs"),
);
} finally {
setOrgsBusy(false);
@@ -340,7 +339,7 @@ export default function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
setWorkers(nextWorkers);
} catch (error) {
setWorkersError(
- error instanceof Error ? error.message : translate("dashboard.error_load_shared_workspaces"),
+ error instanceof Error ? error.message : t("dashboard.error_load_shared_workspaces"),
);
} finally {
setWorkersBusy(false);
@@ -372,7 +371,7 @@ export default function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
if (!props.onConfirmRemote) return;
const orgId = activeOrgId().trim();
if (!orgId) {
- setWorkersError(translate("dashboard.error_choose_org"));
+ setWorkersError(t("dashboard.error_choose_org"));
return;
}
setOpeningWorkerId(worker.workerId);
@@ -383,7 +382,7 @@ export default function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
const accessToken =
tokens.ownerToken?.trim() || tokens.clientToken?.trim() || "";
if (!openworkUrl || !accessToken) {
- throw new Error(translate("dashboard.error_workspace_not_ready"));
+ throw new Error(t("dashboard.error_workspace_not_ready"));
}
const ok = await Promise.resolve(
props.onConfirmRemote({
@@ -397,13 +396,13 @@ export default function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
}),
);
if (ok === false) {
- throw new Error(translate("dashboard.error_connect_worker", { name: worker.workerName }));
+ throw new Error(t("dashboard.error_connect_worker", { name: worker.workerName }));
}
} catch (error) {
setWorkersError(
error instanceof Error
? error.message
- : translate("dashboard.error_connect_worker", { name: worker.workerName }),
+ : t("dashboard.error_connect_worker", { name: worker.workerName }),
);
} finally {
setOpeningWorkerId(null);
@@ -420,7 +419,7 @@ export default function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
setTemplateError(
error instanceof Error
? error.message
- : translate("dashboard.error_create_template", { name: template.name }),
+ : t("dashboard.error_create_template", { name: template.name }),
);
}
return;
@@ -438,7 +437,7 @@ export default function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
onClick={() => setScreen("chooser")}
disabled={submitting() || remoteSubmitting()}
class={modalHeaderButtonClass}
- aria-label={translate("dashboard.modal_back")}
+ aria-label={t("dashboard.modal_back")}
>
@@ -454,7 +453,7 @@ export default function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
onClick={props.onClose}
disabled={submitting() || remoteSubmitting()}
class={modalHeaderButtonClass}
- aria-label={translate("dashboard.modal_close")}
+ aria-label={t("dashboard.modal_close")}
>
@@ -465,26 +464,26 @@ export default function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
setScreen("local")}
disabled={props.localDisabled}
- endAdornment={props.localDisabled ? {translate("dashboard.desktop_badge")} : undefined}
+ endAdornment={props.localDisabled ? {t("dashboard.desktop_badge")} : undefined}
/>
setScreen("remote")}
/>
setScreen("shared")}
/>
@@ -497,10 +496,10 @@ export default function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
disabled={props.importingConfig}
class={pillGhostClass}
>
-
+
- {translate("dashboard.importing")}
+ {t("dashboard.importing")}
@@ -563,15 +562,15 @@ export default function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
onDisplayNameInput={setRemoteDisplayName}
submitting={remoteSubmitting()}
hostInputRef={remoteUrlRef}
- title={translate("dashboard.remote_server_details_title")}
- description={translate("dashboard.remote_server_details_hint")}
+ title={t("dashboard.remote_server_details_title")}
+ description={t("dashboard.remote_server_details_hint")}
/>
{(value) => {value()}
}
- {translate("common.cancel")}
+ {t("common.cancel")}
void handleRemoteSubmit()}
>
-
+
- {translate("dashboard.connecting")}
+ {t("dashboard.connecting")}
diff --git a/apps/app/src/i18n/index.ts b/apps/app/src/i18n/index.ts
index 38553c37c..30ed43ca1 100644
--- a/apps/app/src/i18n/index.ts
+++ b/apps/app/src/i18n/index.ts
@@ -93,8 +93,8 @@ export const setLocale = (newLocale: Language) => {
* @param localeOverride - Optional locale override (defaults to current locale)
* @returns Translated string or fallback
*/
-export const t = (key: string, localeOverride?: Language, params?: Record
): string => {
- const loc = localeOverride ?? locale();
+export const t = (key: string, params?: Record & { lng?: Language }): string => {
+ const loc = params?.lng ?? locale();
// Try target language first
let result: string;
@@ -108,9 +108,10 @@ export const t = (key: string, localeOverride?: Language, params?: Record(null);
const hydratedKeyRef = useRef(null);
const opencodeClient = useMemo(
- () => createClient(props.opencodeBaseUrl, undefined, { token: props.openworkToken, mode: "openwork" }),
+ () => createClient(props.opencodeBaseUrl, { token: props.openworkToken, mode: "openwork" }),
[props.opencodeBaseUrl, props.openworkToken],
);
diff --git a/apps/app/src/react/session/session-sync.ts b/apps/app/src/react/session/session-sync.ts
index 09e444cad..494c285d2 100644
--- a/apps/app/src/react/session/session-sync.ts
+++ b/apps/app/src/react/session/session-sync.ts
@@ -260,7 +260,7 @@ function applyEvent(entry: SyncEntry, workspaceId: string, event: OpencodeEvent)
}
function startSync(input: SyncOptions) {
- const client = createClient(input.baseUrl, undefined, { token: input.openworkToken, mode: "openwork" });
+ const client = createClient(input.baseUrl, { token: input.openworkToken, mode: "openwork" });
const controller = new AbortController();
const entry = syncs.get(syncKey(input));
diff --git a/apps/app/src/react/session/usechat-adapter.ts b/apps/app/src/react/session/usechat-adapter.ts
index 77b828ba4..90677197b 100644
--- a/apps/app/src/react/session/usechat-adapter.ts
+++ b/apps/app/src/react/session/usechat-adapter.ts
@@ -360,7 +360,7 @@ function handleEventChunk(
export function createOpenworkChatTransport(options: TransportOptions): ChatTransport {
return {
async sendMessages({ messages, abortSignal }) {
- const client = createClient(options.baseUrl, undefined, {
+ const client = createClient(options.baseUrl, {
token: options.openworkToken,
mode: "openwork",
});
From ea31582ed93cb4bd025224909bff109cf5512814 Mon Sep 17 00:00:00 2001
From: johnnyshields <27655+johnnyshields@users.noreply.github.com>
Date: Mon, 4 May 2026 21:38:29 +0900
Subject: [PATCH 2/5] Add skip pattern
---
scripts/i18n-audit.mjs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/scripts/i18n-audit.mjs b/scripts/i18n-audit.mjs
index 2909b2b06..37a331640 100644
--- a/scripts/i18n-audit.mjs
+++ b/scripts/i18n-audit.mjs
@@ -329,14 +329,15 @@ if (shouldRun("--aliases")) {
const aliasSourceFiles = collectSourceFiles(APP_SRC, (dir) => dir.includes("locales"));
const aliasPattern = /\b(?:translate|tr)\s*\(/g;
const aliasDefPattern = /(?:const|function)\s+(?:translate|tr)\s*[=(]/;
+ const aliasSkipPattern = /translate\s*\(\s*[-\d]|translate\s*\(\s*0|props\.translate|:\s*\(key:\s*string\)|`translate\(/;
const hits = [];
for (const file of aliasSourceFiles) {
const content = readFileSync(file, "utf-8");
const lines = content.split("\n");
for (let i = 0; i < lines.length; i++) {
- // Skip alias definitions themselves
if (aliasDefPattern.test(lines[i])) continue;
+ if (aliasSkipPattern.test(lines[i])) continue;
if (aliasPattern.test(lines[i])) {
hits.push({ file: file.replace(REPO_ROOT + "/", ""), line: i + 1, text: lines[i].trim() });
}
From e0271b20c2040c88d22a0144d16b08f337e4fc87 Mon Sep 17 00:00:00 2001
From: johnnyshields <27655+johnnyshields@users.noreply.github.com>
Date: Mon, 4 May 2026 22:23:11 +0900
Subject: [PATCH 3/5] Cleanup I18n function usage across react-app
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Drop translate/tr alias wrappers that just forwarded to t() with an explicit
locale arg, and migrate direct t(key, locale, ...) calls to the new
t(key, params?) signature. Also drop the now-unused language prop drilled
through McpAuthModal, AddMcpModal, ControlChromeSetupModal, and the
translate prop drilled through CreateWorkspaceLocalPanel — components
read the global locale via t() directly.
Default the i18n-audit script to include --aliases.
---
.../restriction-notice-modal.tsx | 6 +-
.../bundles/skill-destination-modal.tsx | 53 ++-
.../domains/cloud/den-signin-surface.tsx | 37 +-
.../domains/cloud/forced-signin-page.tsx | 35 +-
.../domains/connections/mcp-auth-modal.tsx | 175 ++++----
.../react-app/domains/connections/modals.tsx | 3 -
.../connections/modals/add-mcp-modal.tsx | 47 +--
.../modals/control-chrome-setup-modal.tsx | 40 +-
.../connections/openwork-server-store.ts | 8 +-
.../react-app/domains/connections/store.ts | 39 +-
.../session/modals/model-picker-modal.tsx | 28 +-
.../session/modals/rename-session-modal.tsx | 15 +-
.../session/surface/composer/composer.tsx | 89 ++--
.../domains/settings/modals/reset-modal.tsx | 25 +-
.../domains/settings/pages/mcp-view.tsx | 134 +++---
.../settings/panels/den-settings-panel.tsx | 385 +++++++++---------
.../settings/state/extensions-store.ts | 149 ++++---
.../create-remote-workspace-modal.tsx | 13 +-
.../create-workspace-local-panel.tsx | 30 +-
.../workspace/create-workspace-modal.tsx | 101 ++---
.../workspace/rename-workspace-modal.tsx | 15 +-
.../react-app/kernel/global-sync-provider.tsx | 4 +-
.../src/react-app/shell/settings-route.tsx | 1 -
scripts/i18n-audit.mjs | 4 +-
24 files changed, 687 insertions(+), 749 deletions(-)
diff --git a/apps/app/src/react-app/design-system/restriction-notice-modal.tsx b/apps/app/src/react-app/design-system/restriction-notice-modal.tsx
index 5081d3772..66a441cd8 100644
--- a/apps/app/src/react-app/design-system/restriction-notice-modal.tsx
+++ b/apps/app/src/react-app/design-system/restriction-notice-modal.tsx
@@ -1,7 +1,7 @@
/** @jsxImportSource react */
import { X } from "lucide-react";
-import { currentLocale, t } from "../../i18n";
+import { t } from "../../i18n";
import { Button } from "./button";
export type RestrictionNoticeModalProps = {
@@ -35,7 +35,7 @@ export function RestrictionNoticeModal(props: RestrictionNoticeModalProps) {
@@ -48,7 +48,7 @@ export function RestrictionNoticeModal(props: RestrictionNoticeModalProps) {
- {t("common.close", currentLocale())}
+ {t("common.close")}
diff --git a/apps/app/src/react-app/domains/bundles/skill-destination-modal.tsx b/apps/app/src/react-app/domains/bundles/skill-destination-modal.tsx
index bbd830f25..869c0d488 100644
--- a/apps/app/src/react-app/domains/bundles/skill-destination-modal.tsx
+++ b/apps/app/src/react-app/domains/bundles/skill-destination-modal.tsx
@@ -11,7 +11,7 @@ import {
} from "lucide-react";
import type { WorkspaceInfo } from "../../../app/lib/desktop";
-import { currentLocale, t } from "../../../i18n";
+import { t } from "../../../i18n";
import { isSandboxWorkspace } from "../../../app/utils";
import { Button } from "../../design-system/button";
@@ -43,7 +43,6 @@ const displayName = (workspace: WorkspaceInfo, fallback: string): string =>
fallback;
export function SkillDestinationModal(props: SkillDestinationModalProps) {
- const translate = (key: string) => t(key, currentLocale());
const [selectedWorkspaceId, setSelectedWorkspaceId] = useState<
string | null
>(null);
@@ -72,7 +71,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
if (workspace.workspaceType === "local") {
return (
workspace.path?.trim() ||
- translate("share_skill_destination.local_badge")
+ t("share_skill_destination.local_badge")
);
}
return (
@@ -80,18 +79,18 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
workspace.openworkHostUrl?.trim() ||
workspace.baseUrl?.trim() ||
workspace.path?.trim() ||
- translate("share_skill_destination.remote_badge")
+ t("share_skill_destination.remote_badge")
);
};
const workspaceBadge = (workspace: WorkspaceInfo): string => {
if (isSandboxWorkspace(workspace)) {
- return translate("share_skill_destination.sandbox_badge");
+ return t("share_skill_destination.sandbox_badge");
}
if (workspace.workspaceType === "remote") {
- return translate("share_skill_destination.remote_badge");
+ return t("share_skill_destination.remote_badge");
}
- return translate("share_skill_destination.local_badge");
+ return t("share_skill_destination.local_badge");
};
const workspaceCircleClass = (
@@ -126,7 +125,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
- {translate("share_skill_destination.skill_label")}
+ {t("share_skill_destination.skill_label")}
@@ -135,11 +134,11 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
- {translate("share_skill_destination.skill_label")}
+ {t("share_skill_destination.skill_label")}
{props.skill?.name ??
- translate("share_skill_destination.fallback_skill_name")}
+ t("share_skill_destination.fallback_skill_name")}
{props.skill?.description?.trim() ? (
@@ -149,7 +148,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
{props.skill?.trigger?.trim() ? (
- {translate("share_skill_destination.trigger_label")}
+ {t("share_skill_destination.trigger_label")}
{props.skill.trigger.trim()}
@@ -161,10 +160,10 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
- {translate("share_skill_destination.title")}
+ {t("share_skill_destination.title")}
- {translate("share_skill_destination.subtitle")}
+ {t("share_skill_destination.subtitle")}
@@ -175,7 +174,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
className={`rounded-full p-2 text-gray-9 transition hover:bg-gray-2 hover:text-gray-12 ${
footerBusy ? "cursor-not-allowed opacity-50" : ""
}`.trim()}
- aria-label={translate("common.close")}
+ aria-label={t("common.close")}
>
@@ -186,7 +185,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
- {translate("share_skill_destination.existing_workers")}
+ {t("share_skill_destination.existing_workers")}
{props.workspaces.length > 0 ? (
@@ -197,7 +196,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
{props.workspaces.length === 0 ? (
- {translate("share_skill_destination.no_workers")}
+ {t("share_skill_destination.no_workers")}
) : (
@@ -240,7 +239,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
{isActive ? (
- {translate("share_skill_destination.current_badge")}
+ {t("share_skill_destination.current_badge")}
) : null}
@@ -248,7 +247,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
{isSelected ? (
- {translate(
+ {t(
"share_skill_destination.selected_badge",
)}
@@ -260,7 +259,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
{isSelected ? (
- {translate(
+ {t(
"share_skill_destination.selected_hint",
)}
@@ -290,7 +289,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
{props.onCreateWorker || props.onConnectRemote ? (
- {translate("share_skill_destination.more_options")}
+ {t("share_skill_destination.more_options")}
{props.onCreateWorker ? (
@@ -308,10 +307,10 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
- {translate("share_skill_destination.create_worker")}
+ {t("share_skill_destination.create_worker")}
- {translate(
+ {t(
"share_skill_destination.create_worker_hint",
)}
@@ -335,10 +334,10 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
- {translate("share_skill_destination.connect_remote")}
+ {t("share_skill_destination.connect_remote")}
- {translate(
+ {t(
"share_skill_destination.connect_remote_hint",
)}
@@ -371,7 +370,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
onClick={props.onClose}
disabled={footerBusy}
>
- {translate("common.cancel")}
+ {t("common.cancel")}
- {translate("share_skill_destination.adding")}
+ {t("share_skill_destination.adding")}
) : (
- translate("share_skill_destination.add_to_workspace")
+ t("share_skill_destination.add_to_workspace")
)}
diff --git a/apps/app/src/react-app/domains/cloud/den-signin-surface.tsx b/apps/app/src/react-app/domains/cloud/den-signin-surface.tsx
index a44d313e7..f65267259 100644
--- a/apps/app/src/react-app/domains/cloud/den-signin-surface.tsx
+++ b/apps/app/src/react-app/domains/cloud/den-signin-surface.tsx
@@ -1,7 +1,7 @@
/** @jsxImportSource react */
import { ArrowUpRight, Cloud } from "lucide-react";
-import { currentLocale, t } from "../../../i18n";
+import { t } from "../../../i18n";
import { DEFAULT_DEN_BASE_URL } from "../../../app/lib/den";
import { Button } from "../../design-system/button";
import { TextInput } from "../../design-system/text-input";
@@ -50,7 +50,6 @@ const errorBannerClass =
* feature parity is obvious.
*/
export function DenSignInSurface(props: DenSignInSurfaceProps) {
- const tr = (key: string) => t(key, currentLocale());
const variant: DenSignInSurfaceVariant = props.variant ?? "panel";
const content = (
@@ -59,11 +58,11 @@ export function DenSignInSurface(props: DenSignInSurfaceProps) {
- {tr("den.cloud_section_title")}
+ {t("den.cloud_section_title")}
- {tr("den.signin_title")}
+ {t("den.signin_title")}
@@ -72,13 +71,13 @@ export function DenSignInSurface(props: DenSignInSurfaceProps) {
{props.developerMode ? (
props.onBaseUrlDraftInput(event.currentTarget.value)
}
placeholder={DEFAULT_DEN_BASE_URL}
- hint={tr("den.cloud_control_plane_url_hint")}
+ hint={t("den.cloud_control_plane_url_hint")}
disabled={props.authBusy || props.baseUrlBusy || props.sessionBusy}
/>
@@ -88,7 +87,7 @@ export function DenSignInSurface(props: DenSignInSurfaceProps) {
onClick={props.onResetBaseUrl}
disabled={props.authBusy || props.baseUrlBusy || props.sessionBusy}
>
- {tr("den.cloud_control_plane_reset")}
+ {t("den.cloud_control_plane_reset")}
- {tr("den.cloud_control_plane_save")}
+ {t("den.cloud_control_plane_save")}
- {tr("den.cloud_control_plane_open")}
+ {t("den.cloud_control_plane_open")}
@@ -120,7 +119,7 @@ export function DenSignInSurface(props: DenSignInSurfaceProps) {
- {tr("den.auto_reconnect_hint")}
+ {t("den.auto_reconnect_hint")}
@@ -129,7 +128,7 @@ export function DenSignInSurface(props: DenSignInSurfaceProps) {
variant="secondary"
onClick={() => props.onOpenBrowserAuth("sign-in")}
>
- {tr("den.signin_button")}
+ {t("den.signin_button")}
props.onOpenBrowserAuth("sign-up")}
>
- {tr("den.create_account")}
+ {t("den.create_account")}
{props.manualAuthOpen
- ? tr("den.hide_signin_code")
- : tr("den.paste_signin_code")}
+ ? t("den.hide_signin_code")
+ : t("den.paste_signin_code")}
{props.manualAuthOpen ? (
props.onManualAuthInput(event.currentTarget.value)
}
- placeholder={tr("den.signin_link_placeholder")}
+ placeholder={t("den.signin_link_placeholder")}
disabled={props.authBusy || props.sessionBusy}
- hint={tr("den.signin_link_hint")}
+ hint={t("den.signin_link_hint")}
/>
- {props.authBusy ? tr("den.finishing") : tr("den.finish_signin")}
+ {props.authBusy ? t("den.finishing") : t("den.finish_signin")}
- {tr("den.signin_code_note")}
+ {t("den.signin_code_note")}
diff --git a/apps/app/src/react-app/domains/cloud/forced-signin-page.tsx b/apps/app/src/react-app/domains/cloud/forced-signin-page.tsx
index 0457895a8..9e673b55d 100644
--- a/apps/app/src/react-app/domains/cloud/forced-signin-page.tsx
+++ b/apps/app/src/react-app/domains/cloud/forced-signin-page.tsx
@@ -1,7 +1,7 @@
/** @jsxImportSource react */
import { useCallback, useEffect, useState } from "react";
-import { currentLocale, t } from "../../../i18n";
+import { t } from "../../../i18n";
import {
buildDenAuthUrl,
clearDenSession,
@@ -78,7 +78,6 @@ export function ForcedSigninPage({ developerMode }: ForcedSigninPageProps) {
const denAuth = useDenAuth();
const desktopConfig = useDesktopConfig();
const { markRouteReady } = useBootState();
- const tr = useCallback((key: string) => t(key, currentLocale()), []);
const initial = readDenSettings();
const initialBaseUrl = initial.baseUrl || DEFAULT_DEN_BASE_URL;
@@ -102,19 +101,19 @@ export function ForcedSigninPage({ developerMode }: ForcedSigninPageProps) {
platform.openLink(buildDenAuthUrl(baseUrl, mode));
setStatusMessage(
mode === "sign-up"
- ? tr("den.status_browser_signup")
- : tr("den.status_browser_signin"),
+ ? t("den.status_browser_signup")
+ : t("den.status_browser_signin"),
);
setAuthError(null);
},
- [baseUrl, platform, tr],
+ [baseUrl, platform],
);
const submitManualAuth = useCallback(async () => {
const parsed = parseManualAuthInput(manualAuthInput);
if (!parsed || authBusy) {
if (!parsed) {
- setAuthError(tr("den.error_paste_valid_code"));
+ setAuthError(t("den.error_paste_valid_code"));
}
return;
}
@@ -123,14 +122,14 @@ export function ForcedSigninPage({ developerMode }: ForcedSigninPageProps) {
setAuthBusy(true);
setAuthError(null);
- setStatusMessage(tr("den.signing_in"));
+ setStatusMessage(t("den.signing_in"));
try {
const result = await createDenClient({
baseUrl: nextBaseUrl,
}).exchangeDesktopHandoff(parsed.grant);
if (!result.token) {
- throw new Error(tr("den.error_no_token"));
+ throw new Error(t("den.error_no_token"));
}
if (developerMode) {
@@ -161,17 +160,17 @@ export function ForcedSigninPage({ developerMode }: ForcedSigninPageProps) {
message:
error instanceof Error
? error.message
- : tr("den.error_signin_failed"),
+ : t("den.error_signin_failed"),
});
} finally {
setAuthBusy(false);
}
- }, [authBusy, baseUrl, developerMode, manualAuthInput, tr]);
+ }, [authBusy, baseUrl, developerMode, manualAuthInput]);
const applyBaseUrl = useCallback(async () => {
const normalized = normalizeDenBaseUrl(baseUrlDraft);
if (!normalized) {
- setBaseUrlError(tr("den.error_base_url"));
+ setBaseUrlError(t("den.error_base_url"));
return;
}
@@ -200,19 +199,19 @@ export function ForcedSigninPage({ developerMode }: ForcedSigninPageProps) {
{ persistBootstrap: false },
);
setAuthError(null);
- setStatusMessage(tr("den.status_base_url_updated"));
+ setStatusMessage(t("den.status_base_url_updated"));
void desktopConfig.refresh();
void denAuth.refresh();
} catch (error) {
setBaseUrlError(
error instanceof Error
? error.message
- : tr("den.error_base_url"),
+ : t("den.error_base_url"),
);
} finally {
setBaseUrlBusy(false);
}
- }, [baseUrlDraft, denAuth, desktopConfig, developerMode, tr]);
+ }, [baseUrlDraft, denAuth, desktopConfig, developerMode]);
// Listen for Den session events broadcast from the Tauri deep-link handler,
// a successful browser auth, or an org switch, and reflect the result in
@@ -239,12 +238,12 @@ export function ForcedSigninPage({ developerMode }: ForcedSigninPageProps) {
const email = customEvent.detail.email?.trim();
setStatusMessage(
email
- ? t("den.status_cloud_signed_in_as", currentLocale(), { email })
- : tr("den.status_cloud_signin_done"),
+ ? t("den.status_cloud_signed_in_as", { email })
+ : t("den.status_cloud_signin_done"),
);
} else if (customEvent.detail?.status === "error") {
setAuthError(
- customEvent.detail.message?.trim() || tr("den.error_signin_failed"),
+ customEvent.detail.message?.trim() || t("den.error_signin_failed"),
);
}
};
@@ -256,7 +255,7 @@ export function ForcedSigninPage({ developerMode }: ForcedSigninPageProps) {
handler as EventListener,
);
};
- }, [tr]);
+ }, []);
return (
void | Promise;
};
export function McpAuthModal(props: McpAuthModalProps) {
- const translate = (key: string, replacements?: Record) => {
- let result = t(key, props.language);
- if (replacements) {
- for (const [placeholder, value] of Object.entries(replacements)) {
- result = result.replace(`{${placeholder}}`, value);
- }
- }
- return result;
- };
-
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [needsReload, setNeedsReload] = useState(false);
@@ -177,7 +166,7 @@ export function McpAuthModal(props: McpAuthModalProps) {
statusPollRef.current = window.setInterval(async () => {
if (Date.now() - startedAt >= MCP_AUTH_TIMEOUT_MS) {
stopStatusPolling();
- setError(translate("mcp.auth.request_timed_out"));
+ setError(t("mcp.auth.request_timed_out"));
return;
}
@@ -197,7 +186,7 @@ export function McpAuthModal(props: McpAuthModalProps) {
try {
slug = resolveSlug(props.entry.name);
} catch (err) {
- const message = err instanceof Error ? err.message : translate("mcp.auth.failed_to_start_oauth");
+ const message = err instanceof Error ? err.message : t("mcp.auth.failed_to_start_oauth");
setError(message);
setLoading(false);
setAuthInProgress(false);
@@ -221,7 +210,7 @@ export function McpAuthModal(props: McpAuthModalProps) {
try {
const directory = await resolveDirectory();
if (!directory) {
- setError(translate("mcp.pick_workspace_first"));
+ setError(t("mcp.pick_workspace_first"));
return;
}
@@ -230,8 +219,8 @@ export function McpAuthModal(props: McpAuthModalProps) {
setNeedsReload(true);
setReloadNotice(
props.reloadBlocked
- ? translate("mcp.auth.reload_blocked")
- : translate("mcp.auth.reload_notice"),
+ ? t("mcp.auth.reload_blocked")
+ : t("mcp.auth.reload_notice"),
);
return;
}
@@ -255,13 +244,13 @@ export function McpAuthModal(props: McpAuthModalProps) {
}
if (status.status === "needs_client_registration") {
- setError(status.error ?? translate("mcp.auth.client_registration_required"));
+ setError(status.error ?? t("mcp.auth.client_registration_required"));
} else if (status.status === "disabled") {
- setError(translate("mcp.auth.server_disabled"));
+ setError(t("mcp.auth.server_disabled"));
} else if (status.status === "failed") {
- setError(status.error ?? translate("mcp.auth.oauth_failed"));
+ setError(status.error ?? t("mcp.auth.oauth_failed"));
} else {
- setError(translate("mcp.auth.authorization_still_required"));
+ setError(t("mcp.auth.authorization_still_required"));
}
return;
}
@@ -281,7 +270,7 @@ export function McpAuthModal(props: McpAuthModalProps) {
await openAuthorizationUrl(auth.authorizationUrl);
startStatusPolling(slug);
} catch (err) {
- const message = err instanceof Error ? err.message : translate("mcp.auth.failed_to_start_oauth");
+ const message = err instanceof Error ? err.message : t("mcp.auth.failed_to_start_oauth");
if (message.toLowerCase().includes("does not support oauth")) {
const serverSlug = props.entry.name.toLowerCase().replace(/[^a-z0-9]+/g, "-") || "server";
@@ -297,18 +286,18 @@ export function McpAuthModal(props: McpAuthModalProps) {
if (props.reloadRequired && !reloadSatisfied) {
setReloadNotice(
props.reloadBlocked
- ? translate("mcp.auth.reload_blocked")
- : translate("mcp.auth.reload_notice"),
+ ? t("mcp.auth.reload_blocked")
+ : t("mcp.auth.reload_notice"),
);
} else {
setError(
- `${message}\n\n${translate("mcp.auth.oauth_not_supported_hint", { server: serverSlug })}`,
+ `${message}\n\n${t("mcp.auth.oauth_not_supported_hint", { server: serverSlug })}`,
);
}
setNeedsReload(true);
} else if (message.toLowerCase().includes("not found") || message.toLowerCase().includes("unknown")) {
setNeedsReload(true);
- setError(translate("mcp.auth.try_reload_engine", { message }));
+ setError(t("mcp.auth.try_reload_engine", { message }));
} else {
setError(message);
}
@@ -339,12 +328,12 @@ export function McpAuthModal(props: McpAuthModalProps) {
if (result.ok) {
setError(null);
setNeedsReload(true);
- setReloadNotice(translate("mcp.auth.oauth_completed_reload"));
+ setReloadNotice(t("mcp.auth.oauth_completed_reload"));
} else {
- setCliAuthResult(result.stderr || result.stdout || translate("mcp.auth.reauth_failed"));
+ setCliAuthResult(result.stderr || result.stdout || t("mcp.auth.reauth_failed"));
}
} catch (err) {
- const message = err instanceof Error ? err.message : translate("mcp.auth.reauth_failed");
+ const message = err instanceof Error ? err.message : t("mcp.auth.reauth_failed");
setCliAuthResult(message);
} finally {
setCliAuthBusy(false);
@@ -403,8 +392,8 @@ export function McpAuthModal(props: McpAuthModalProps) {
setNeedsReload(true);
setReloadNotice(
props.reloadBlocked
- ? translate("mcp.auth.reload_blocked")
- : translate("mcp.auth.reload_notice"),
+ ? t("mcp.auth.reload_blocked")
+ : t("mcp.auth.reload_notice"),
);
return;
}
@@ -413,7 +402,7 @@ export function McpAuthModal(props: McpAuthModalProps) {
setAwaitingReload(false);
await startAuth(false, false);
} catch (err) {
- const message = err instanceof Error ? err.message : translate("mcp.auth.reload_failed");
+ const message = err instanceof Error ? err.message : t("mcp.auth.reload_failed");
if (cancelled) return;
setAwaitingReload(false);
setNeedsReload(true);
@@ -437,7 +426,7 @@ export function McpAuthModal(props: McpAuthModalProps) {
const handleReloadAndRetry = async () => {
if (!props.onReloadEngine) return;
if (props.isRemoteWorkspace && typeof window !== "undefined") {
- const proceed = window.confirm(translate("mcp.auth.reload_remote_confirm"));
+ const proceed = window.confirm(t("mcp.auth.reload_remote_confirm"));
if (!proceed) return;
}
await props.onReloadEngine();
@@ -502,14 +491,14 @@ export function McpAuthModal(props: McpAuthModalProps) {
try {
slug = resolveSlug(props.entry.name);
} catch (err) {
- const message = err instanceof Error ? err.message : translate("mcp.auth.failed_to_start_oauth");
+ const message = err instanceof Error ? err.message : t("mcp.auth.failed_to_start_oauth");
setError(message);
return;
}
const code = parseAuthCode(callbackInput);
if (!code) {
- setError(translate("mcp.auth.callback_invalid"));
+ setError(t("mcp.auth.callback_invalid"));
return;
}
@@ -520,7 +509,7 @@ export function McpAuthModal(props: McpAuthModalProps) {
try {
const directory = await resolveDirectory();
if (!directory) {
- setError(translate("mcp.pick_workspace_first"));
+ setError(t("mcp.pick_workspace_first"));
return;
}
@@ -538,16 +527,16 @@ export function McpAuthModal(props: McpAuthModalProps) {
}
if (status.status === "needs_client_registration") {
- setError(status.error ?? translate("mcp.auth.client_registration_required"));
+ setError(status.error ?? t("mcp.auth.client_registration_required"));
} else if (status.status === "disabled") {
- setError(translate("mcp.auth.server_disabled"));
+ setError(t("mcp.auth.server_disabled"));
} else if (status.status === "failed") {
- setError(status.error ?? translate("mcp.auth.oauth_failed"));
+ setError(status.error ?? t("mcp.auth.oauth_failed"));
} else {
- setError(translate("mcp.auth.authorization_still_required"));
+ setError(t("mcp.auth.authorization_still_required"));
}
} catch (err) {
- const message = err instanceof Error ? err.message : translate("mcp.auth.oauth_failed");
+ const message = err instanceof Error ? err.message : t("mcp.auth.oauth_failed");
setError(message);
} finally {
setManualAuthBusy(false);
@@ -564,7 +553,7 @@ export function McpAuthModal(props: McpAuthModalProps) {
try {
slug = resolveSlug(props.entry.name);
} catch (err) {
- const message = err instanceof Error ? err.message : translate("mcp.auth.failed_to_start_oauth");
+ const message = err instanceof Error ? err.message : t("mcp.auth.failed_to_start_oauth");
setError(message);
setStatusChecking(false);
return;
@@ -579,13 +568,13 @@ export function McpAuthModal(props: McpAuthModalProps) {
}
if (statusEntry?.status === "needs_client_registration") {
- setError(statusEntry.error ?? translate("mcp.auth.client_registration_required"));
+ setError(statusEntry.error ?? t("mcp.auth.client_registration_required"));
} else if (statusEntry?.status === "disabled") {
- setError(translate("mcp.auth.server_disabled"));
+ setError(t("mcp.auth.server_disabled"));
} else if (statusEntry?.status === "failed") {
- setError(statusEntry.error ?? translate("mcp.auth.oauth_failed"));
+ setError(statusEntry.error ?? t("mcp.auth.oauth_failed"));
} else {
- setError(translate("mcp.auth.authorization_still_required"));
+ setError(t("mcp.auth.authorization_still_required"));
}
setStatusChecking(false);
@@ -608,9 +597,9 @@ export function McpAuthModal(props: McpAuthModalProps) {
- {translate("mcp.auth.connect_server", { server: serverName })}
+ {t("mcp.auth.connect_server", { server: serverName })}
-
{translate("mcp.auth.open_browser_signin")}
+
{t("mcp.auth.open_browser_signin")}
-
{translate("mcp.auth.waiting_authorization")}
-
{translate("mcp.auth.follow_browser_steps")}
+
{t("mcp.auth.waiting_authorization")}
+
{t("mcp.auth.follow_browser_steps")}
- {translate("mcp.auth.reopen_browser_link")}
+ {t("mcp.auth.reopen_browser_link")}
@@ -649,13 +638,13 @@ export function McpAuthModal(props: McpAuthModalProps) {
{props.reloadBlocked
- ? translate("mcp.auth.waiting_for_conversation_title")
- : translate("mcp.auth.applying_changes_title")}
+ ? t("mcp.auth.waiting_for_conversation_title")
+ : t("mcp.auth.applying_changes_title")}
{props.reloadBlocked
- ? translate("mcp.auth.waiting_for_conversation_body")
- : translate("mcp.auth.applying_changes_body")}
+ ? t("mcp.auth.waiting_for_conversation_body")
+ : t("mcp.auth.applying_changes_body")}
{props.reloadBlocked && (props.activeSessions?.length ?? 0) > 0 ? (
@@ -666,7 +655,7 @@ export function McpAuthModal(props: McpAuthModalProps) {
className="flex items-center justify-between gap-3 rounded-lg border border-amber-6/50 bg-amber-1/40 px-3 py-2"
>
- {translate("mcp.auth.waiting_for_session", { session: session.title })}
+ {t("mcp.auth.waiting_for_session", { session: session.title })}
{forceStopBusySessionID === session.id
- ? translate("mcp.auth.force_stopping")
- : translate("mcp.auth.force_stop")}
+ ? t("mcp.auth.force_stopping")
+ : t("mcp.auth.force_stop")}
))}
@@ -692,13 +681,13 @@ export function McpAuthModal(props: McpAuthModalProps) {
-
{translate("mcp.auth.already_connected")}
+
{t("mcp.auth.already_connected")}
- {translate("mcp.auth.already_connected_description", { server: serverName })}
+ {t("mcp.auth.already_connected_description", { server: serverName })}
-
{translate("mcp.auth.configured_previously")}
+
{t("mcp.auth.configured_previously")}
) : null}
@@ -712,14 +701,14 @@ export function McpAuthModal(props: McpAuthModalProps) {
variant="secondary"
onClick={() => void handleReloadAndRetry()}
disabled={props.reloadBlocked}
- title={props.reloadBlocked ? translate("mcp.reload_banner_blocked_hint") : undefined}
+ title={props.reloadBlocked ? t("mcp.reload_banner_blocked_hint") : undefined}
>
- {translate("mcp.auth.reload_engine_retry")}
+ {t("mcp.auth.reload_engine_retry")}
) : null}
- {translate("mcp.auth.retry_now")}
+ {t("mcp.auth.retry_now")}
@@ -736,42 +725,42 @@ export function McpAuthModal(props: McpAuthModalProps) {
variant="secondary"
onClick={() => void handleReloadAndRetry()}
disabled={props.reloadBlocked}
- title={props.reloadBlocked ? translate("mcp.reload_banner_blocked_hint") : undefined}
+ title={props.reloadBlocked ? t("mcp.reload_banner_blocked_hint") : undefined}
>
- {translate("mcp.auth.reload_engine_retry")}
+ {t("mcp.auth.reload_engine_retry")}
) : null}
- {translate("mcp.auth.retry_now")}
+ {t("mcp.auth.retry_now")}
) : (
- {translate("mcp.auth.retry")}
+ {t("mcp.auth.retry")}
)}
{isInvalidRefreshToken() ? (
-
{translate("mcp.auth.invalid_refresh_token")}
+
{t("mcp.auth.invalid_refresh_token")}
{!props.isRemoteWorkspace ? (
isDesktopRuntime() ? (
void handleCliReauth()} disabled={cliAuthBusy}>
{cliAuthBusy ? : null}
{cliAuthBusy
- ? translate("mcp.auth.reauth_running")
- : translate("mcp.auth.reauth_action")}
+ ? t("mcp.auth.reauth_running")
+ : t("mcp.auth.reauth_action")}
) : (
- {translate("mcp.auth.reauth_cli_hint", { server: serverName })}
+ {t("mcp.auth.reauth_cli_hint", { server: serverName })}
)
) : (
-
{translate("mcp.auth.reauth_remote_hint")}
+
{t("mcp.auth.reauth_remote_hint")}
)}
{cliAuthResult ?
{cliAuthResult}
: null}
@@ -781,26 +770,26 @@ export function McpAuthModal(props: McpAuthModalProps) {
{!isBusy && authorizationUrl && props.isRemoteWorkspace && !alreadyConnected ? (
-
{translate("mcp.auth.manual_finish_title")}
-
{translate("mcp.auth.manual_finish_hint")}
+
{t("mcp.auth.manual_finish_title")}
+
{t("mcp.auth.manual_finish_hint")}
- {translate("mcp.auth.authorization_link")}
+ {t("mcp.auth.authorization_link")}
{authorizationUrl}
void handleCopyAuthorizationUrl()}>
- {authUrlCopied ? translate("mcp.auth.copied") : translate("mcp.auth.copy_link")}
+ {authUrlCopied ? t("mcp.auth.copied") : t("mcp.auth.copy_link")}
setCallbackInput(event.currentTarget.value)}
/>
- {translate("mcp.auth.port_forward_hint")}
+ {t("mcp.auth.port_forward_hint")}
{manualAuthBusy ? : null}
- {translate("mcp.auth.complete_connection")}
+ {t("mcp.auth.complete_connection")}
@@ -822,9 +811,9 @@ export function McpAuthModal(props: McpAuthModalProps) {
1
-
{translate("mcp.auth.step1_title")}
+
{t("mcp.auth.step1_title")}
- {translate("mcp.auth.step1_description", { server: serverName })}
+ {t("mcp.auth.step1_description", { server: serverName })}
@@ -834,8 +823,8 @@ export function McpAuthModal(props: McpAuthModalProps) {
2
-
{translate("mcp.auth.step2_title")}
-
{translate("mcp.auth.step2_description")}
+
{t("mcp.auth.step2_title")}
+
{t("mcp.auth.step2_description")}
@@ -844,22 +833,22 @@ export function McpAuthModal(props: McpAuthModalProps) {
3
-
{translate("mcp.auth.step3_title")}
-
{translate("mcp.auth.step3_description")}
+
{t("mcp.auth.step3_title")}
+
{t("mcp.auth.step3_description")}
-
{translate("mcp.auth.waiting_authorization")}
-
{translate("mcp.auth.follow_browser_steps")}
+
{t("mcp.auth.waiting_authorization")}
+
{t("mcp.auth.follow_browser_steps")}
- {translate("mcp.auth.reopen_browser_link")}
+ {t("mcp.auth.reopen_browser_link")}
@@ -871,16 +860,16 @@ export function McpAuthModal(props: McpAuthModalProps) {
{alreadyConnected ? (
void handleComplete()}>
- {translate("mcp.auth.done")}
+ {t("mcp.auth.done")}
) : (
<>
- {translate("mcp.auth.cancel")}
+ {t("mcp.auth.cancel")}
void handleComplete()}>
- {translate("mcp.auth.im_done")}
+ {t("mcp.auth.im_done")}
>
)}
diff --git a/apps/app/src/react-app/domains/connections/modals.tsx b/apps/app/src/react-app/domains/connections/modals.tsx
index 3ac2ad8a4..1367cb257 100644
--- a/apps/app/src/react-app/domains/connections/modals.tsx
+++ b/apps/app/src/react-app/domains/connections/modals.tsx
@@ -1,6 +1,5 @@
/** @jsxImportSource react */
import type { Client } from "../../../app/types";
-import type { Language } from "../../../i18n";
import type { McpDirectoryInfo } from "../../../app/constants";
import { McpAuthModal } from "./mcp-auth-modal";
@@ -14,7 +13,6 @@ export type ConnectionsModalsState = {
export type ConnectionsModalsProps = {
client: Client | null;
projectDir: string;
- language: Language;
reloadBlocked: boolean;
activeSessions: Array<{ id: string; title: string }>;
isRemoteWorkspace: boolean;
@@ -32,7 +30,6 @@ export default function ConnectionsModals(props: ConnectionsModalsProps) {
client={props.client}
entry={props.modalState.mcpAuthEntry}
projectDir={props.projectDir}
- language={props.language}
reloadRequired={props.modalState.mcpAuthNeedsReload}
reloadBlocked={props.reloadBlocked}
activeSessions={props.activeSessions}
diff --git a/apps/app/src/react-app/domains/connections/modals/add-mcp-modal.tsx b/apps/app/src/react-app/domains/connections/modals/add-mcp-modal.tsx
index 29480d5d7..d6c7d8adb 100644
--- a/apps/app/src/react-app/domains/connections/modals/add-mcp-modal.tsx
+++ b/apps/app/src/react-app/domains/connections/modals/add-mcp-modal.tsx
@@ -5,7 +5,7 @@ import { Loader2, Plus, X } from "lucide-react";
import { Button } from "../../../design-system/button";
import { TextInput } from "../../../design-system/text-input";
import type { McpDirectoryInfo } from "../../../../app/constants";
-import { t, type Language } from "../../../../i18n";
+import { t } from "../../../../i18n";
export type AddMcpModalProps = {
open: boolean;
@@ -13,12 +13,9 @@ export type AddMcpModalProps = {
onAdd: (entry: McpDirectoryInfo) => void;
busy: boolean;
isRemoteWorkspace: boolean;
- language: Language;
};
export function AddMcpModal(props: AddMcpModalProps) {
- const tr = (key: string) => t(key, props.language);
-
const [name, setName] = useState("");
const [serverType, setServerType] = useState<"remote" | "local">("remote");
const [url, setUrl] = useState("");
@@ -48,7 +45,7 @@ export function AddMcpModal(props: AddMcpModalProps) {
const trimmedName = name.trim();
if (!trimmedName) {
- setError(tr("mcp.name_required"));
+ setError(t("mcp.name_required"));
return;
}
@@ -57,7 +54,7 @@ export function AddMcpModal(props: AddMcpModalProps) {
if (serverType === "remote") {
const trimmedUrl = url.trim();
if (!trimmedUrl) {
- setError(tr("mcp.url_or_command_required"));
+ setError(t("mcp.url_or_command_required"));
setSubmitting(false);
return;
}
@@ -78,7 +75,7 @@ export function AddMcpModal(props: AddMcpModalProps) {
} else {
const trimmedCommand = command.trim();
if (!trimmedCommand) {
- setError(tr("mcp.url_or_command_required"));
+ setError(t("mcp.url_or_command_required"));
setSubmitting(false);
return;
}
@@ -116,10 +113,10 @@ export function AddMcpModal(props: AddMcpModalProps) {
- {tr("mcp.add_modal_title")}
+ {t("mcp.add_modal_title")}
- {tr("mcp.add_modal_subtitle")}
+ {t("mcp.add_modal_subtitle")}
setName(event.currentTarget.value)}
autoFocus
@@ -142,7 +139,7 @@ export function AddMcpModal(props: AddMcpModalProps) {
- {tr("mcp.server_type")}
+ {t("mcp.server_type")}
setServerType("remote")}
>
- {tr("mcp.type_remote")}
+ {t("mcp.type_remote")}
- {tr("mcp.type_local_cmd")}
+ {t("mcp.type_local_cmd")}
{props.isRemoteWorkspace ? (
- {tr("mcp.remote_workspace_url_hint")}
+ {t("mcp.remote_workspace_url_hint")}
) : null}
@@ -182,14 +179,14 @@ export function AddMcpModal(props: AddMcpModalProps) {
{serverType === "remote" ? (
setUrl(event.currentTarget.value)}
/>
diff --git a/apps/app/src/react-app/domains/connections/modals/control-chrome-setup-modal.tsx b/apps/app/src/react-app/domains/connections/modals/control-chrome-setup-modal.tsx
index 4426b4e17..4b2201442 100644
--- a/apps/app/src/react-app/domains/connections/modals/control-chrome-setup-modal.tsx
+++ b/apps/app/src/react-app/domains/connections/modals/control-chrome-setup-modal.tsx
@@ -9,13 +9,12 @@ import {
X,
} from "lucide-react";
-import { t, type Language } from "../../../../i18n";
+import { t } from "../../../../i18n";
import { Button } from "../../../design-system/button";
export type ControlChromeSetupModalProps = {
open: boolean;
busy: boolean;
- language: Language;
mode: "connect" | "edit";
initialUseExistingProfile: boolean;
onClose: () => void;
@@ -23,7 +22,6 @@ export type ControlChromeSetupModalProps = {
};
export function ControlChromeSetupModal(props: ControlChromeSetupModalProps) {
- const tr = (key: string) => t(key, props.language);
const [useExistingProfile, setUseExistingProfile] = useState(
props.initialUseExistingProfile,
);
@@ -37,8 +35,8 @@ export function ControlChromeSetupModal(props: ControlChromeSetupModalProps) {
const ctaLabel =
props.mode === "edit"
- ? tr("mcp.control_chrome_save")
- : tr("mcp.control_chrome_connect");
+ ? t("mcp.control_chrome_save")
+ : t("mcp.control_chrome_connect");
return (
@@ -57,10 +55,10 @@ export function ControlChromeSetupModal(props: ControlChromeSetupModalProps) {
- {tr("mcp.control_chrome_setup_title")}
+ {t("mcp.control_chrome_setup_title")}
- {tr("mcp.control_chrome_setup_subtitle")}
+ {t("mcp.control_chrome_setup_subtitle")}
@@ -68,7 +66,7 @@ export function ControlChromeSetupModal(props: ControlChromeSetupModalProps) {
type="button"
className="rounded-xl p-2 text-gray-11 transition-colors hover:bg-gray-4 hover:text-gray-12"
onClick={props.onClose}
- aria-label={tr("common.cancel")}
+ aria-label={t("common.cancel")}
>
@@ -83,15 +81,15 @@ export function ControlChromeSetupModal(props: ControlChromeSetupModalProps) {
- {tr("mcp.control_chrome_browser_title")}
+ {t("mcp.control_chrome_browser_title")}
- {tr("mcp.control_chrome_browser_hint")}
+ {t("mcp.control_chrome_browser_hint")}
- - 1. {tr("mcp.control_chrome_browser_step_one")}
- - 2. {tr("mcp.control_chrome_browser_step_two")}
- - 3. {tr("mcp.control_chrome_browser_step_three")}
+ - 1. {t("mcp.control_chrome_browser_step_one")}
+ - 2. {t("mcp.control_chrome_browser_step_two")}
+ - 3. {t("mcp.control_chrome_browser_step_three")}
- {tr("mcp.control_chrome_docs")}
+ {t("mcp.control_chrome_docs")}
@@ -113,10 +111,10 @@ export function ControlChromeSetupModal(props: ControlChromeSetupModalProps) {
- {tr("mcp.control_chrome_profile_title")}
+ {t("mcp.control_chrome_profile_title")}
- {tr("mcp.control_chrome_profile_hint")}
+ {t("mcp.control_chrome_profile_hint")}
- {tr("mcp.control_chrome_toggle_label")}
+ {t("mcp.control_chrome_toggle_label")}
- {tr("mcp.control_chrome_toggle_hint")}
+ {t("mcp.control_chrome_toggle_hint")}
@@ -150,8 +148,8 @@ export function ControlChromeSetupModal(props: ControlChromeSetupModalProps) {
{useExistingProfile
- ? tr("mcp.control_chrome_toggle_on")
- : tr("mcp.control_chrome_toggle_off")}
+ ? t("mcp.control_chrome_toggle_on")
+ : t("mcp.control_chrome_toggle_off")}
@@ -160,7 +158,7 @@ export function ControlChromeSetupModal(props: ControlChromeSetupModalProps) {
- {tr("mcp.auth.cancel")}
+ {t("mcp.auth.cancel")}
void;
}) {
const listeners = new Set<() => void>();
- const translate = (key: string) => t(key, currentLocale());
let started = false;
let disposed = false;
@@ -418,7 +417,7 @@ export function createConnectionsStore(options: {
}
if (!canUseOpenworkServer && !isDesktopRuntime()) {
- setStateField("mcpStatus", translate("mcp.desktop_required"));
+ setStateField("mcpStatus", t("mcp.desktop_required"));
finishPerf(options.developerMode(), "mcp.connect", "blocked", startedAt, {
reason: "desktop-required",
});
@@ -426,7 +425,7 @@ export function createConnectionsStore(options: {
}
if (!isRemoteWorkspace && !projectDir) {
- setStateField("mcpStatus", translate("mcp.pick_workspace_first"));
+ setStateField("mcpStatus", t("mcp.pick_workspace_first"));
finishPerf(options.developerMode(), "mcp.connect", "blocked", startedAt, {
reason: "missing-workspace",
});
@@ -435,7 +434,7 @@ export function createConnectionsStore(options: {
const activeClient = await ensureActiveClient();
if (!activeClient) {
- setStateField("mcpStatus", translate("mcp.connect_server_first"));
+ setStateField("mcpStatus", t("mcp.connect_server_first"));
finishPerf(options.developerMode(), "mcp.connect", "blocked", startedAt, {
reason: "no-active-client",
});
@@ -444,7 +443,7 @@ export function createConnectionsStore(options: {
const resolvedProjectDir = await resolveProjectDir(activeClient, projectDir);
if (!resolvedProjectDir) {
- setStateField("mcpStatus", translate("mcp.pick_workspace_first"));
+ setStateField("mcpStatus", t("mcp.pick_workspace_first"));
finishPerf(options.developerMode(), "mcp.connect", "blocked", startedAt, {
reason: "missing-workspace-after-discovery",
});
@@ -580,7 +579,7 @@ export function createConnectionsStore(options: {
mcpAuthModalOpen: true,
}));
} else {
- setStateField("mcpStatus", translate("mcp.connected"));
+ setStateField("mcpStatus", t("mcp.connected"));
}
await refreshMcpServers();
@@ -592,7 +591,7 @@ export function createConnectionsStore(options: {
} catch (error) {
setStateField(
"mcpStatus",
- error instanceof Error ? error.message : translate("mcp.connect_failed"),
+ error instanceof Error ? error.message : t("mcp.connect_failed"),
);
finishPerf(options.developerMode(), "mcp.connect", "error", startedAt, {
name: entry.name,
@@ -606,7 +605,7 @@ export function createConnectionsStore(options: {
function authorizeMcp(entry: McpServerEntry) {
if (entry.config.type !== "remote" || entry.config.oauth === false) {
- setStateField("mcpStatus", translate("mcp.login_unavailable"));
+ setStateField("mcpStatus", t("mcp.login_unavailable"));
return;
}
@@ -646,19 +645,19 @@ export function createConnectionsStore(options: {
}
if (!canUseOpenworkServer && !isDesktopRuntime()) {
- setStateField("mcpStatus", translate("mcp.desktop_required"));
+ setStateField("mcpStatus", t("mcp.desktop_required"));
return;
}
const activeClient = await ensureActiveClient();
if (!activeClient) {
- setStateField("mcpStatus", translate("mcp.connect_server_first"));
+ setStateField("mcpStatus", t("mcp.connect_server_first"));
return;
}
const resolvedProjectDir = await resolveProjectDir(activeClient, projectDir);
if (!resolvedProjectDir) {
- setStateField("mcpStatus", translate("mcp.pick_workspace_first"));
+ setStateField("mcpStatus", t("mcp.pick_workspace_first"));
return;
}
@@ -685,11 +684,11 @@ export function createConnectionsStore(options: {
}
await refreshMcpServers();
- setStateField("mcpStatus", translate("mcp.logout_success").replace("{server}", safeName));
+ setStateField("mcpStatus", t("mcp.logout_success").replace("{server}", safeName));
} catch (error) {
setStateField(
"mcpStatus",
- error instanceof Error ? error.message : translate("mcp.logout_failed"),
+ error instanceof Error ? error.message : t("mcp.logout_failed"),
);
}
}
@@ -712,7 +711,7 @@ export function createConnectionsStore(options: {
} else {
const projectDir = options.projectDir().trim();
if (!projectDir) {
- setStateField("mcpStatus", translate("mcp.pick_workspace_first"));
+ setStateField("mcpStatus", t("mcp.pick_workspace_first"));
return;
}
await removeMcpFromConfig(projectDir, name);
@@ -727,13 +726,13 @@ export function createConnectionsStore(options: {
} catch (error) {
setStateField(
"mcpStatus",
- error instanceof Error ? error.message : translate("mcp.remove_failed"),
+ error instanceof Error ? error.message : t("mcp.remove_failed"),
);
}
}
function notifyMcpReloading() {
- setStateField("mcpStatus", translate("mcp.reloading_status"));
+ setStateField("mcpStatus", t("mcp.reloading_status"));
}
// OpenCode reconnects MCP servers asynchronously after /instance/dispose,
@@ -765,7 +764,7 @@ export function createConnectionsStore(options: {
if (disposed) return;
// Only clear the reloading banner if it's still ours. refreshMcpServers
// may have already replaced it with a real message (e.g. "No MCP servers").
- if (snapshot.mcpStatus === translate("mcp.reloading_status")) {
+ if (snapshot.mcpStatus === t("mcp.reloading_status")) {
setStateField("mcpStatus", null);
}
}
@@ -786,7 +785,7 @@ export function createConnectionsStore(options: {
openworkSnapshot.openworkServerCapabilities?.mcp?.write;
if (!canUseOpenworkServer || !openworkClient || !openworkWorkspaceId) {
- setStateField("mcpStatus", translate("mcp.toggle_requires_server"));
+ setStateField("mcpStatus", t("mcp.toggle_requires_server"));
return;
}
@@ -796,7 +795,7 @@ export function createConnectionsStore(options: {
} catch (error) {
setStateField(
"mcpStatus",
- error instanceof Error ? error.message : translate("mcp.toggle_failed"),
+ error instanceof Error ? error.message : t("mcp.toggle_failed"),
);
}
}
diff --git a/apps/app/src/react-app/domains/session/modals/model-picker-modal.tsx b/apps/app/src/react-app/domains/session/modals/model-picker-modal.tsx
index 2ab49e2b2..6f2867ca2 100644
--- a/apps/app/src/react-app/domains/session/modals/model-picker-modal.tsx
+++ b/apps/app/src/react-app/domains/session/modals/model-picker-modal.tsx
@@ -72,12 +72,6 @@ export function ModelPickerModal(props: ModelPickerModalProps) {
const optionRefs = useRef([]);
const [activeIndex, setActiveIndex] = useState(0);
- const translate = useCallback(
- (key: string, params?: Record) =>
- t(key, undefined, params),
- [],
- );
-
const otherProviderLinks = useMemo(() => {
const seen = new Set();
const items: { providerID: string; title: string; matchCount: number }[] =
@@ -457,10 +451,10 @@ export function ModelPickerModal(props: ModelPickerModalProps) {
].join(" ")}
>
- {translate("model_picker.connect_provider_hint")}
+ {t("model_picker.connect_provider_hint")}
- {translate(
+ {t(
provider.matchCount === 1
? "model_picker.model_count_one"
: "model_picker.model_count",
@@ -481,14 +475,14 @@ export function ModelPickerModal(props: ModelPickerModalProps) {
- {translate(
+ {t(
props.target === "default"
? "model_picker.default_model_title"
: "model_picker.chat_model_title",
)}
- {translate(
+ {t(
props.target === "default"
? "model_picker.default_model_desc"
: "model_picker.chat_model_desc",
@@ -515,13 +509,13 @@ export function ModelPickerModal(props: ModelPickerModalProps) {
type="text"
value={props.query}
onChange={(event) => props.setQuery(event.currentTarget.value)}
- placeholder={translate("settings.search_models")}
+ placeholder={t("settings.search_models")}
className="w-full bg-dls-surface border border-dls-border rounded-xl py-2.5 pl-9 pr-3 text-sm text-dls-text placeholder:text-dls-secondary focus:outline-none focus:ring-1 focus:ring-[rgba(var(--dls-accent-rgb),0.2)] focus:border-dls-accent"
/>
{props.query.trim() ? (
- {translate("settings.showing_models", {
+ {t("settings.showing_models", {
count: props.filteredOptions.length,
total: props.options.length,
})}
@@ -533,7 +527,7 @@ export function ModelPickerModal(props: ModelPickerModalProps) {
{recommendedOptions.length > 0 ? (
- {translate("model_picker.recommended")}
+ {t("model_picker.recommended")}
{recommendedOptions.map(({ opt, index }) =>
renderOption(opt, index),
@@ -544,7 +538,7 @@ export function ModelPickerModal(props: ModelPickerModalProps) {
{otherEnabledOptions.length > 0 ? (
- {translate("model_picker.other_connected_models")}
+ {t("model_picker.other_connected_models")}
{otherEnabledOptions.map(({ opt, index }) =>
renderOption(opt, index),
@@ -555,7 +549,7 @@ export function ModelPickerModal(props: ModelPickerModalProps) {
{otherOptions.length > 0 ? (
- {translate("model_picker.more_providers")}
+ {t("model_picker.more_providers")}
{otherOptions.map(renderProviderLink)}
@@ -563,7 +557,7 @@ export function ModelPickerModal(props: ModelPickerModalProps) {
{renderedItems.length === 0 ? (
- {translate("model_picker.no_results")}
+ {t("model_picker.no_results")}
) : null}
@@ -574,7 +568,7 @@ export function ModelPickerModal(props: ModelPickerModalProps) {
className="inline-flex items-center justify-center rounded-full border border-dls-border px-4 py-2 text-[13px] font-medium text-dls-text transition-colors hover:bg-[var(--dls-hover)]"
onClick={() => props.onClose()}
>
- {translate("settings.done")}
+ {t("settings.done")}
diff --git a/apps/app/src/react-app/domains/session/modals/rename-session-modal.tsx b/apps/app/src/react-app/domains/session/modals/rename-session-modal.tsx
index 6b1a779c5..05787702b 100644
--- a/apps/app/src/react-app/domains/session/modals/rename-session-modal.tsx
+++ b/apps/app/src/react-app/domains/session/modals/rename-session-modal.tsx
@@ -2,7 +2,7 @@
import { useEffect, useRef } from "react";
import { X } from "lucide-react";
-import { currentLocale, t } from "../../../../i18n";
+import { t } from "../../../../i18n";
import {
inputClass,
pillGhostClass,
@@ -22,7 +22,6 @@ export type RenameSessionModalProps = {
export function RenameSessionModal(props: RenameSessionModalProps) {
const inputRef = useRef(null);
- const translate = (key: string) => t(key, currentLocale());
useEffect(() => {
if (!props.open) return;
@@ -42,10 +41,10 @@ export function RenameSessionModal(props: RenameSessionModalProps) {
@@ -88,7 +87,7 @@ export function RenameSessionModal(props: RenameSessionModalProps) {
onClick={props.onClose}
disabled={props.busy}
>
- {translate("common.cancel")}
+ {t("common.cancel")}
- {translate("common.save")}
+ {t("common.save")}
diff --git a/apps/app/src/react-app/domains/session/surface/composer/composer.tsx b/apps/app/src/react-app/domains/session/surface/composer/composer.tsx
index 0ddcbee61..e666aeba3 100644
--- a/apps/app/src/react-app/domains/session/surface/composer/composer.tsx
+++ b/apps/app/src/react-app/domains/session/surface/composer/composer.tsx
@@ -5,7 +5,7 @@ import { ArrowUp, Check, ChevronDown, ChevronRight, FileText, Paperclip, Plug, S
import fuzzysort from "fuzzysort";
import type { CloudImportedPlugin, CloudImportedPluginFile } from "../../../../../app/cloud/import-state";
import type { ComposerAttachment, McpServerEntry, McpStatusMap, SkillCard, SlashCommandOption } from "../../../../../app/types";
-import { currentLocale, t, type Language } from "../../../../../i18n";
+import { t } from "../../../../../i18n";
import { LexicalPromptEditor } from "./editor";
import {
ReactComposerNotice,
@@ -177,20 +177,20 @@ async function compressImageFile(file: File): Promise {
return new File([blob], `${stem}.jpg`, { type: "image/jpeg" });
}
-function formatMcpStatusLabel(status: McpServerStatus | undefined, locale: Language) {
+function formatMcpStatusLabel(status: McpServerStatus | undefined) {
switch (status) {
case "connected":
- return t("mcp.friendly_status_ready", locale);
+ return t("mcp.friendly_status_ready");
case "needs_auth":
case "needs_client_registration":
- return t("mcp.friendly_status_needs_signin", locale);
+ return t("mcp.friendly_status_needs_signin");
case "disabled":
- return t("mcp.friendly_status_paused", locale);
+ return t("mcp.friendly_status_paused");
case "disconnected":
- return t("mcp.friendly_status_offline", locale);
+ return t("mcp.friendly_status_offline");
case "failed":
default:
- return t("mcp.friendly_status_issue", locale);
+ return t("mcp.friendly_status_issue");
}
}
@@ -280,7 +280,6 @@ export function ReactSessionComposer(props: ComposerProps) {
// compositionstart/compositionend events below.
const imeComposingRef = useRef(false);
const rootRef = useRef(null);
- const locale = currentLocale();
const draftRef = useRef(props.draft);
useEffect(() => {
draftRef.current = props.draft;
@@ -707,7 +706,7 @@ export function ReactSessionComposer(props: ComposerProps) {
if (!inputFiles.length) return;
if (!props.attachmentsEnabled) {
props.onNotice({
- title: props.attachmentsDisabledReason ?? t("composer.attachments_unavailable", locale),
+ title: props.attachmentsDisabledReason ?? t("composer.attachments_unavailable"),
tone: "warning",
});
return;
@@ -719,7 +718,7 @@ export function ReactSessionComposer(props: ComposerProps) {
for (const original of inputFiles) {
if (!isSupportedAttachmentType(original.type)) {
- unsupported.push(original.name || t("composer.file_kind", locale));
+ unsupported.push(original.name || t("composer.file_kind"));
continue;
}
const processed = original.type.startsWith("image/") ? await compressImageFile(original) : original;
@@ -735,8 +734,8 @@ export function ReactSessionComposer(props: ComposerProps) {
props.onNotice({
title:
accepted.length === 1
- ? t("composer.uploaded_single_file", locale, { name: accepted[0]?.name ?? t("composer.file_kind", locale) })
- : t("composer.uploaded_multiple_files", locale, { count: accepted.length }),
+ ? t("composer.uploaded_single_file", { name: accepted[0]?.name ?? t("composer.file_kind") })
+ : t("composer.uploaded_multiple_files", { count: accepted.length }),
tone: "success",
});
}
@@ -745,7 +744,7 @@ export function ReactSessionComposer(props: ComposerProps) {
props.onNotice({
title:
oversize.length === 1
- ? t("composer.file_exceeds_limit", locale, { name: oversize[0] })
+ ? t("composer.file_exceeds_limit", { name: oversize[0] })
: `${oversize.length} files exceed the 8MB limit.`,
tone: "warning",
});
@@ -755,8 +754,8 @@ export function ReactSessionComposer(props: ComposerProps) {
props.onNotice({
title:
unsupported.length === 1
- ? `${unsupported[0]} · ${t("composer.unsupported_attachment_type", locale)}`
- : `${unsupported.length} ${t("composer.unsupported_attachment_type", locale).toLowerCase()}`,
+ ? `${unsupported[0]} · ${t("composer.unsupported_attachment_type")}`
+ : `${unsupported.length} ${t("composer.unsupported_attachment_type").toLowerCase()}`,
tone: "warning",
});
}
@@ -807,7 +806,7 @@ export function ReactSessionComposer(props: ComposerProps) {
/{command.name}
{command.source && command.source !== "command" ? (
- {command.source === "skill" ? t("composer.skill_source", locale) : t("composer.mcps_label", locale)}
+ {command.source === "skill" ? t("composer.skill_source") : t("composer.mcps_label")}
) : null}
@@ -818,7 +817,7 @@ export function ReactSessionComposer(props: ComposerProps) {
) : (
- {commandsLoading ? t("composer.loading_commands", locale) : t("composer.no_commands", locale)}
+ {commandsLoading ? t("composer.loading_commands") : t("composer.no_commands")}
)}
@@ -860,8 +859,8 @@ export function ReactSessionComposer(props: ComposerProps) {
@{item.label}
{item.kind === "agent"
- ? t("composer.agent_label", locale)
- : t("composer.file_kind", locale)}
+ ? t("composer.agent_label")
+ : t("composer.file_kind")}
@@ -910,7 +909,7 @@ export function ReactSessionComposer(props: ComposerProps) {
{attachment.name}
- {isImageAttachment(attachment) ? t("composer.image_kind", locale) : t("composer.file_kind", locale)}
+ {isImageAttachment(attachment) ? t("composer.image_kind") : t("composer.file_kind")}
·
{formatBytes(attachment.size)}
@@ -919,7 +918,7 @@ export function ReactSessionComposer(props: ComposerProps) {
type="button"
className="ml-1 inline-flex h-5 w-5 items-center justify-center rounded-full text-gray-10 transition-colors hover:bg-gray-3 hover:text-gray-12"
onClick={() => props.onRemoveAttachment(attachment.id)}
- title={t("action.remove", locale)}
+ title={t("action.remove")}
>
@@ -939,7 +938,7 @@ export function ReactSessionComposer(props: ComposerProps) {
{dropzoneActive ? (
-
{t("composer.attach_files", locale)}
+
{t("composer.attach_files")}
Images and PDFs are supported.
@@ -952,7 +951,7 @@ export function ReactSessionComposer(props: ComposerProps) {
mentions={props.mentions}
pastedText={pastedTextTokens}
disabled={props.disabled}
- placeholder={t("composer.placeholder", locale)}
+ placeholder={t("composer.placeholder")}
onChange={props.onDraftChange}
onSubmit={props.onSend}
onPasteText={props.onPasteText}
@@ -980,7 +979,7 @@ export function ReactSessionComposer(props: ComposerProps) {
event.preventDefault();
props.onUnsupportedFileLinks(uriList);
props.onNotice({
- title: t("composer.inserted_links_unsupported", locale),
+ title: t("composer.inserted_links_unsupported"),
tone: "info",
});
return;
@@ -1007,11 +1006,11 @@ export function ReactSessionComposer(props: ComposerProps) {
) {
const attachedFiles = props.attachments.map((attachment) => attachment.file);
props.onNotice({
- title: t("composer.remote_worker_paste_warning", locale),
+ title: t("composer.remote_worker_paste_warning"),
tone: "warning",
actionLabel:
props.onUploadInboxFiles && attachedFiles.length > 0
- ? t("composer.upload_to_shared_folder", locale)
+ ? t("composer.upload_to_shared_folder")
: undefined,
onAction:
props.onUploadInboxFiles && attachedFiles.length > 0
@@ -1068,7 +1067,7 @@ export function ReactSessionComposer(props: ComposerProps) {
fileInput?.click();
}}
disabled={!props.attachmentsEnabled}
- title={props.attachmentsDisabledReason ?? t("composer.attach_files", locale)}
+ title={props.attachmentsDisabledReason ?? t("composer.attach_files")}
>
@@ -1084,7 +1083,7 @@ export function ReactSessionComposer(props: ComposerProps) {
}}
aria-expanded={toolMenuOpen}
aria-haspopup="dialog"
- title={t("composer.tools_label", locale)}
+ title={t("composer.tools_label")}
>
@@ -1093,9 +1092,9 @@ export function ReactSessionComposer(props: ComposerProps) {
{([
- ["commands", t("dashboard.commands", locale)],
- ["skills", t("dashboard.skills", locale)],
- ["mcps", t("composer.mcps_label", locale)],
+ ["commands", t("dashboard.commands")],
+ ["skills", t("dashboard.skills")],
+ ["mcps", t("composer.mcps_label")],
] as const).map(([section, label]) => (
- {t("composer.configure", locale)}
+ {t("composer.configure")}
{toolMenuSection === "commands" ? (
@@ -1154,7 +1153,7 @@ export function ReactSessionComposer(props: ComposerProps) {
) : (
- {commandsLoading ? t("composer.loading_commands", locale) : t("composer.no_commands", locale)}
+ {commandsLoading ? t("composer.loading_commands") : t("composer.no_commands")}
)
) : null}
@@ -1178,7 +1177,7 @@ export function ReactSessionComposer(props: ComposerProps) {
) : (
- {skillsLoading || commandsLoading ? t("composer.loading_commands", locale) : t("context_panel.no_skills", locale)}
+ {skillsLoading || commandsLoading ? t("composer.loading_commands") : t("context_panel.no_skills")}
)
) : null}
@@ -1192,7 +1191,7 @@ export function ReactSessionComposer(props: ComposerProps) {
{entry.name}
- {formatMcpStatusLabel(status, locale)}
+ {formatMcpStatusLabel(status)}
{entry.config.type === "remote" ? entry.config.url ?? entry.config.command?.join(" ") ?? "Remote MCP" : entry.config.command?.join(" ") ?? "Local MCP"}
@@ -1202,7 +1201,7 @@ export function ReactSessionComposer(props: ComposerProps) {
) : (
- {mcpLoading ? t("composer.loading_commands", locale) : (mcpStatus ?? t("context_panel.no_mcp", locale))}
+ {mcpLoading ? t("composer.loading_commands") : (mcpStatus ?? t("context_panel.no_mcp"))}
)
) : null}
@@ -1233,7 +1232,7 @@ export function ReactSessionComposer(props: ComposerProps) {
)
) : toolMenuSection.startsWith("plugin:") ? (
- {pluginsLoading ? t("composer.loading_commands", locale) : "Plugin files are unavailable."}
+ {pluginsLoading ? t("composer.loading_commands") : "Plugin files are unavailable."}
) : null}
@@ -1255,10 +1254,10 @@ export function ReactSessionComposer(props: ComposerProps) {
type="button"
onClick={props.onStop}
className="inline-flex h-9 max-h-9 items-center gap-2 rounded-full bg-gray-12 px-4 text-[13px] font-medium text-gray-1 transition-colors hover:bg-gray-11"
- title={t("composer.stop", locale)}
+ title={t("composer.stop")}
>
- {t("composer.stop", locale)}
+ {t("composer.stop")}
) : (
- {t("composer.run_task", locale)}
+ {t("composer.run_task")}
)}
@@ -1291,7 +1290,7 @@ export function ReactSessionComposer(props: ComposerProps) {
onClick={() => setAgentMenuOpen((value) => !value)}
disabled={props.busy}
aria-expanded={agentMenuOpen}
- title={t("composer.agent_label", locale)}
+ title={t("composer.agent_label")}
>
{props.agentLabel}
@@ -1299,7 +1298,7 @@ export function ReactSessionComposer(props: ComposerProps) {
{agentMenuOpen ? (
- {t("composer.agent_label", locale)}
+ {t("composer.agent_label")}
-
{t("composer.default_agent", locale)}
+
{t("composer.default_agent")}
{!props.selectedAgent ?
: null}
{agents.map((agent, index) => {
@@ -1384,7 +1383,7 @@ export function ReactSessionComposer(props: ComposerProps) {
{variantMenuOpen ? (
- {t("composer.behavior_label", locale)}
+ {t("composer.behavior_label")}
{props.modelBehaviorOptions.map((option) => {
diff --git a/apps/app/src/react-app/domains/settings/modals/reset-modal.tsx b/apps/app/src/react-app/domains/settings/modals/reset-modal.tsx
index 84aa3a939..1b939105c 100644
--- a/apps/app/src/react-app/domains/settings/modals/reset-modal.tsx
+++ b/apps/app/src/react-app/domains/settings/modals/reset-modal.tsx
@@ -2,7 +2,7 @@
import type { ReactNode } from "react";
import { X } from "lucide-react";
-import { t, type Language } from "../../../../i18n";
+import { t } from "../../../../i18n";
const RESET_CONFIRM_PLACEHOLDER = "{resetWord}";
const RESET_CONFIRM_WORD = "RESET";
@@ -21,17 +21,14 @@ export type ResetModalProps = {
busy: boolean;
canReset: boolean;
hasActiveRuns: boolean;
- language: Language;
onClose: () => void;
onConfirm: () => void;
onTextChange: (value: string) => void;
};
export function ResetModal(props: ResetModalProps) {
- const translate = (key: string) => t(key, props.language);
-
const resetConfirmationHint = (): ReactNode => {
- const template = translate("settings.reset_confirmation_hint");
+ const template = t("settings.reset_confirmation_hint");
const parts = template.split(RESET_CONFIRM_PLACEHOLDER);
if (parts.length === 1) return template;
const nodes: ReactNode[] = [];
@@ -58,8 +55,8 @@ export function ResetModal(props: ResetModalProps) {
{props.mode === "onboarding"
- ? translate("settings.reset_onboarding_title")
- : translate("settings.reset_app_data_title")}
+ ? t("settings.reset_onboarding_title")
+ : t("settings.reset_app_data_title")}
{resetConfirmationHint()}
@@ -78,23 +75,23 @@ export function ResetModal(props: ResetModalProps) {
{props.mode === "onboarding"
- ? translate("settings.reset_onboarding_warning")
- : translate("settings.reset_app_data_warning")}
+ ? t("settings.reset_onboarding_warning")
+ : t("settings.reset_app_data_warning")}
{props.hasActiveRuns ? (
- {translate("settings.reset_stop_active_runs")}
+ {t("settings.reset_stop_active_runs")}
) : null}
diff --git a/apps/app/src/react-app/domains/settings/pages/mcp-view.tsx b/apps/app/src/react-app/domains/settings/pages/mcp-view.tsx
index df357832d..33f492d54 100644
--- a/apps/app/src/react-app/domains/settings/pages/mcp-view.tsx
+++ b/apps/app/src/react-app/domains/settings/pages/mcp-view.tsx
@@ -37,7 +37,7 @@ import {
} from "../../../../app/mcp";
import type { McpServerEntry, McpStatusMap } from "../../../../app/types";
import { formatRelativeTime, isDesktopRuntime, isWindowsPlatform } from "../../../../app/utils";
-import { currentLocale, t, type Language } from "../../../../i18n";
+import { t } from "../../../../i18n";
import { Button } from "../../../design-system/button";
import { ConfirmModal } from "../../../design-system/modals/confirm-modal";
import { AddMcpModal } from "../../connections/modals/add-mcp-modal";
@@ -88,19 +88,19 @@ const statusDot = (status: ReactMcpStatus) => {
}
};
-const friendlyStatus = (status: ReactMcpStatus, locale: Language) => {
+const friendlyStatus = (status: ReactMcpStatus) => {
switch (status) {
case "connected":
- return t("mcp.friendly_status_ready", locale);
+ return t("mcp.friendly_status_ready");
case "needs_auth":
case "needs_client_registration":
- return t("mcp.friendly_status_needs_signin", locale);
+ return t("mcp.friendly_status_needs_signin");
case "disabled":
- return t("mcp.friendly_status_paused", locale);
+ return t("mcp.friendly_status_paused");
case "disconnected":
- return t("mcp.friendly_status_offline", locale);
+ return t("mcp.friendly_status_offline");
default:
- return t("mcp.friendly_status_issue", locale);
+ return t("mcp.friendly_status_issue");
}
};
@@ -159,8 +159,6 @@ const serviceIconBg = (name: string) => {
};
export function McpView(props: McpViewProps) {
- const locale = currentLocale();
- const tr = (key: string) => t(key, locale);
const showHeader = props.showHeader !== false;
const [logoutOpen, setLogoutOpen] = useState(false);
@@ -215,17 +213,17 @@ export function McpView(props: McpViewProps) {
setProjectConfig(null);
setGlobalConfig(null);
setConfigError(
- error instanceof Error ? error.message : tr("mcp.config_load_failed"),
+ error instanceof Error ? error.message : t("mcp.config_load_failed"),
);
}
})();
- }, [locale, props.readConfigFile, props.selectedWorkspaceRoot]);
+ }, [props.readConfigFile, props.selectedWorkspaceRoot]);
const activeConfig = configScope === "project" ? projectConfig : globalConfig;
const revealLabel = isWindowsPlatform()
- ? tr("mcp.open_file")
- : tr("mcp.reveal_in_finder");
+ ? t("mcp.open_file")
+ : t("mcp.reveal_in_finder");
const canRevealConfig =
isDesktopRuntime() &&
@@ -314,7 +312,7 @@ export function McpView(props: McpViewProps) {
const root = props.selectedWorkspaceRoot.trim();
if (configScope === "project" && !root) {
- setConfigError(tr("mcp.pick_workspace_error"));
+ setConfigError(t("mcp.pick_workspace_error"));
return;
}
@@ -325,7 +323,7 @@ export function McpView(props: McpViewProps) {
? await props.readConfigFile(configScope)
: await readOpencodeConfig(configScope, root);
if (!resolved) {
- throw new Error(tr("mcp.config_load_failed"));
+ throw new Error(t("mcp.config_load_failed"));
}
if (isWindowsPlatform()) {
await openDesktopPath(resolved.path);
@@ -334,7 +332,7 @@ export function McpView(props: McpViewProps) {
}
} catch (error) {
setConfigError(
- error instanceof Error ? error.message : tr("mcp.reveal_config_failed"),
+ error instanceof Error ? error.message : t("mcp.reveal_config_failed"),
);
} finally {
setRevealBusy(false);
@@ -345,13 +343,13 @@ export function McpView(props: McpViewProps) {
{showHeader ? (
-
{tr("mcp.apps_title")}
-
{tr("mcp.apps_subtitle")}
+
{t("mcp.apps_title")}
+
{t("mcp.apps_subtitle")}
{connectedCount > 0 ? (
- {connectedCount} {connectedCount === 1 ? tr("mcp.app_connected") : tr("mcp.apps_connected")}
+ {connectedCount} {connectedCount === 1 ? t("mcp.app_connected") : t("mcp.apps_connected")}
) : null}
@@ -367,12 +365,12 @@ export function McpView(props: McpViewProps) {
-
{tr("mcp.add_modal_title")}
-
{tr("mcp.custom_app_cta_hint")}
+
{t("mcp.add_modal_title")}
+
{t("mcp.custom_app_cta_hint")}
setAddMcpModalOpen(true)}>
- {tr("mcp.add_modal_title")}
+ {t("mcp.add_modal_title")}
@@ -380,9 +378,9 @@ export function McpView(props: McpViewProps) {
- {tr("mcp.available_apps")}
+ {t("mcp.available_apps")}
- {tr("mcp.one_click_connect")}
+ {t("mcp.one_click_connect")}
@@ -399,7 +397,7 @@ export function McpView(props: McpViewProps) {
{
event.stopPropagation();
const existingEntry = props.mcpServers.find(
@@ -449,7 +447,7 @@ export function McpView(props: McpViewProps) {
{entry.name}
{configured ? (
- {tr("mcp.connected_badge")}
+ {t("mcp.connected_badge")}
) : null}
{!configured && quickStatus ? (
@@ -458,7 +456,7 @@ export function McpView(props: McpViewProps) {
quickStatus.status,
)}`}
>
- {friendlyStatus(quickStatus.status, locale)}
+ {friendlyStatus(quickStatus.status)}
) : null}
@@ -467,7 +465,7 @@ export function McpView(props: McpViewProps) {
{!configured && !connecting ? (
- {tr("mcp.tap_to_connect")}
+ {t("mcp.tap_to_connect")}
) : null}
@@ -482,11 +480,11 @@ export function McpView(props: McpViewProps) {
- {tr("mcp.your_apps")}
+ {t("mcp.your_apps")}
{props.mcpLastUpdatedAt ? (
- {tr("mcp.last_synced")} {formatRelativeTime(props.mcpLastUpdatedAt ?? Date.now())}
+ {t("mcp.last_synced")} {formatRelativeTime(props.mcpLastUpdatedAt ?? Date.now())}
) : null}
@@ -502,7 +500,7 @@ export function McpView(props: McpViewProps) {
resolvedStatus && resolvedStatus.status === "failed"
? "error" in resolvedStatus
? resolvedStatus.error
- : tr("mcp.connection_failed")
+ : t("mcp.connection_failed")
: null;
return (
@@ -542,7 +540,7 @@ export function McpView(props: McpViewProps) {
- {friendlyStatus(status, locale)}
+ {friendlyStatus(status)}
@@ -554,19 +552,19 @@ export function McpView(props: McpViewProps) {
{isSelected ? (
- {tr("mcp.connection_type")}
+ {t("mcp.connection_type")}
- {entry.config.type === "remote" ? tr("mcp.type_cloud") : tr("mcp.type_local")}
+ {entry.config.type === "remote" ? t("mcp.type_cloud") : t("mcp.type_local")}
- {tr("mcp.cap_tools")}
+ {t("mcp.cap_tools")}
{entry.config.type === "remote" ? (
- {tr("mcp.cap_signin")}
+ {t("mcp.cap_signin")}
) : null}
@@ -580,7 +578,7 @@ export function McpView(props: McpViewProps) {
- {tr("mcp.technical_details")}
+ {t("mcp.technical_details")}
@@ -593,24 +591,24 @@ export function McpView(props: McpViewProps) {
{supportsOauth(entry) && status !== "connected" ? (
<>
-
{tr("mcp.logout_label")}
+
{t("mcp.logout_label")}
props.authorizeMcp(entry)}
>
- {tr("mcp.login_action")}
+ {t("mcp.login_action")}
-
{tr("mcp.login_hint")}
+
{t("mcp.login_hint")}
>
) : null}
{supportsOauth(entry) && status === "connected" ? (
<>
-
{tr("mcp.logout_label")}
+
{t("mcp.logout_label")}
requestLogout(entry.name)}
>
{logoutBusy && logoutTarget === entry.name
- ? tr("mcp.logout_working")
- : tr("mcp.logout_action")}
+ ? t("mcp.logout_working")
+ : t("mcp.logout_action")}
-
{tr("mcp.logout_hint")}
+
{t("mcp.logout_hint")}
>
) : null}
@@ -634,7 +632,7 @@ export function McpView(props: McpViewProps) {
onClick={() => openControlChromeModal("edit", entry)}
>
- {tr("mcp.control_chrome_edit")}
+ {t("mcp.control_chrome_edit")}
) : null}
{props.setMcpEnabled && entry.source !== "config.global" ? (
@@ -654,8 +652,8 @@ export function McpView(props: McpViewProps) {
>
{entry.config.enabled === false
- ? tr("mcp.enable_app")
- : tr("mcp.disable_app")}
+ ? t("mcp.enable_app")
+ : t("mcp.disable_app")}
) : null}
- {tr("mcp.remove_app")}
+ {t("mcp.remove_app")}
@@ -679,18 +677,18 @@ export function McpView(props: McpViewProps) {
) : (
-
{tr("mcp.no_apps_yet")}
-
{tr("mcp.no_apps_hint")}
+
{t("mcp.no_apps_yet")}
+
{t("mcp.no_apps_hint")}
)}
{
if (logoutBusy) return;
@@ -704,10 +702,10 @@ export function McpView(props: McpViewProps) {
{
setRemoveOpen(false);
@@ -729,8 +727,8 @@ export function McpView(props: McpViewProps) {
-
{tr("mcp.advanced_settings")}
-
{tr("mcp.advanced_settings_hint")}
+
{t("mcp.advanced_settings")}
+
{t("mcp.advanced_settings_hint")}
@@ -750,7 +748,7 @@ export function McpView(props: McpViewProps) {
}`}
onClick={() => setConfigScope("project")}
>
- {tr("mcp.scope_project")}
+ {t("mcp.scope_project")}
setConfigScope("global")}
>
- {tr("mcp.scope_global")}
+ {t("mcp.scope_global")}
-
{tr("mcp.config_file")}
+
{t("mcp.config_file")}
- {activeConfig?.path ?? tr("mcp.config_not_loaded")}
+ {activeConfig?.path ?? t("mcp.config_not_loaded")}
@@ -778,7 +776,7 @@ export function McpView(props: McpViewProps) {
{revealBusy ? (
<>
- {tr("mcp.opening_label")}
+ {t("mcp.opening_label")}
>
) : (
<>
@@ -793,12 +791,12 @@ export function McpView(props: McpViewProps) {
rel="noopener noreferrer"
className="inline-flex items-center gap-1 text-xs text-dls-secondary transition-colors hover:text-dls-text"
>
- {tr("mcp.docs_link")}
+ {t("mcp.docs_link")}
{activeConfig && activeConfig.exists === false ? (
-
{tr("mcp.file_not_found")}
+
{t("mcp.file_not_found")}
) : null}
@@ -813,13 +811,11 @@ export function McpView(props: McpViewProps) {
onAdd={(entry) => props.connectMcp(entry)}
busy={props.busy}
isRemoteWorkspace={props.isRemoteWorkspace}
- language={locale}
/>
setControlChromeModalOpen(false)}
diff --git a/apps/app/src/react-app/domains/settings/panels/den-settings-panel.tsx b/apps/app/src/react-app/domains/settings/panels/den-settings-panel.tsx
index 9bd9222c4..c67039c0e 100644
--- a/apps/app/src/react-app/domains/settings/panels/den-settings-panel.tsx
+++ b/apps/app/src/react-app/domains/settings/panels/den-settings-panel.tsx
@@ -13,7 +13,7 @@ import {
Users,
} from "lucide-react";
-import { currentLocale, t } from "../../../../i18n";
+import { t } from "../../../../i18n";
import {
buildDenAuthUrl,
clearDenSession,
@@ -154,22 +154,22 @@ function statusBadgeClass(kind: "ready" | "warning" | "neutral" | "error") {
}
}
-function workerStatusMeta(status: string, tr: (key: string) => string) {
+function workerStatusMeta(status: string) {
const normalized = status.trim().toLowerCase();
switch (normalized) {
case "healthy":
- return { label: tr("dashboard.worker_status_ready"), tone: "ready" as const, canOpen: true };
+ return { label: t("dashboard.worker_status_ready"), tone: "ready" as const, canOpen: true };
case "provisioning":
- return { label: tr("dashboard.worker_status_starting"), tone: "warning" as const, canOpen: false };
+ return { label: t("dashboard.worker_status_starting"), tone: "warning" as const, canOpen: false };
case "failed":
- return { label: tr("dashboard.worker_status_attention"), tone: "error" as const, canOpen: false };
+ return { label: t("dashboard.worker_status_attention"), tone: "error" as const, canOpen: false };
case "stopped":
- return { label: tr("dashboard.worker_status_stopped"), tone: "neutral" as const, canOpen: false };
+ return { label: t("dashboard.worker_status_stopped"), tone: "neutral" as const, canOpen: false };
default:
return {
label: normalized
? `${normalized.slice(0, 1).toUpperCase()}${normalized.slice(1)}`
- : tr("dashboard.worker_status_unknown"),
+ : t("dashboard.worker_status_unknown"),
tone: "neutral" as const,
canOpen: normalized === "ready",
};
@@ -204,13 +204,6 @@ function parseManualAuthInput(value: string) {
}
export function DenSettingsPanel(props: DenSettingsPanelProps) {
- const tr = useCallback((key: string) => t(key, currentLocale()), []);
- const tx = useCallback(
- (key: string, params?: Record) =>
- t(key, currentLocale(), params),
- [],
- );
-
const initial = useMemo(() => readDenSettings(), []);
const initialBaseUrl = initial.baseUrl || DEFAULT_DEN_BASE_URL;
@@ -267,14 +260,14 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
[activeOrgId, orgs],
);
const isSignedIn = Boolean(user && authToken.trim());
- const activeOrgName = activeOrg?.name || tr("den.no_org_selected");
+ const activeOrgName = activeOrg?.name || t("den.no_org_selected");
const activeOrgOptions = useMemo(
() =>
orgs.map((org) => ({
value: org.id,
- label: `${org.name} ${org.role === "owner" ? tr("den.org_owner_suffix") : tr("den.org_member_suffix")}`,
+ label: `${org.name} ${org.role === "owner" ? t("den.org_owner_suffix") : t("den.org_member_suffix")}`,
})),
- [orgs, tr],
+ [orgs],
);
const syncCurrentDenSettings = useCallback(() => {
@@ -489,11 +482,11 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
]);
const summaryLabel = useMemo(() => {
- if (authError) return tr("den.needs_attention");
- if (sessionBusy) return tr("den.checking_session");
- if (isSignedIn) return tr("dashboard.connected");
- return tr("den.signed_out");
- }, [authError, isSignedIn, sessionBusy, tr]);
+ if (authError) return t("den.needs_attention");
+ if (sessionBusy) return t("den.checking_session");
+ if (isSignedIn) return t("dashboard.connected");
+ return t("den.signed_out");
+ }, [authError, isSignedIn, sessionBusy]);
const clearSessionState = useCallback(() => {
setUser(null);
@@ -544,18 +537,18 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
props.openLink(buildDenAuthUrl(baseUrl, mode));
setStatusMessage(
mode === "sign-up"
- ? tr("den.status_browser_signup")
- : tr("den.status_browser_signin"),
+ ? t("den.status_browser_signup")
+ : t("den.status_browser_signin"),
);
setAuthError(null);
},
- [baseUrl, props, tr],
+ [baseUrl, props],
);
const applyBaseUrl = useCallback(() => {
const normalized = normalizeDenBaseUrl(baseUrlDraft);
if (!normalized) {
- setBaseUrlError(tr("den.error_base_url"));
+ setBaseUrlError(t("den.error_base_url"));
return;
}
@@ -568,8 +561,8 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
setBaseUrl(resolved.baseUrl);
setBaseUrlDraft(resolved.baseUrl);
- clearSignedInState(tr("den.status_base_url_updated"));
- }, [baseUrl, baseUrlDraft, clearSignedInState, tr]);
+ clearSignedInState(t("den.status_base_url_updated"));
+ }, [baseUrl, baseUrlDraft, clearSignedInState]);
const refreshOrgs = useCallback(
async (quiet = false) => {
@@ -608,19 +601,19 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
}
if (!quiet && response.orgs.length > 0) {
setStatusMessage(
- tx("den.status_loaded_orgs", {
+ t("den.status_loaded_orgs", {
count: response.orgs.length,
plural: response.orgs.length === 1 ? "" : "s",
}),
);
}
} catch (error) {
- setOrgsError(error instanceof Error ? error.message : tr("den.error_load_orgs"));
+ setOrgsError(error instanceof Error ? error.message : t("den.error_load_orgs"));
} finally {
setOrgsBusy(false);
}
},
- [activeOrgId, authToken, baseUrl, client, tr, tx],
+ [activeOrgId, authToken, baseUrl, client],
);
const refreshWorkers = useCallback(
@@ -640,23 +633,23 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
if (!quiet) {
setStatusMessage(
nextWorkers.length > 0
- ? tx("den.status_loaded_workers", {
+ ? t("den.status_loaded_workers", {
count: nextWorkers.length,
plural: nextWorkers.length === 1 ? "" : "s",
- name: activeOrg?.name ?? tr("den.active_org_title"),
+ name: activeOrg?.name ?? t("den.active_org_title"),
})
- : tx("den.status_no_workers", {
- name: activeOrg?.name ?? tr("den.active_org_title"),
+ : t("den.status_no_workers", {
+ name: activeOrg?.name ?? t("den.active_org_title"),
}),
);
}
} catch (error) {
- setWorkersError(error instanceof Error ? error.message : tr("den.error_load_workers"));
+ setWorkersError(error instanceof Error ? error.message : t("den.error_load_workers"));
} finally {
setWorkersBusy(false);
}
},
- [activeOrg, activeOrgId, authToken, client, tr, tx],
+ [activeOrg, activeOrgId, authToken, client],
);
const refreshSkillHubs = useCallback(
@@ -674,8 +667,8 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
const count = props.extensions.cloudOrgSkillHubs().length;
setStatusMessage(
count > 0
- ? `Loaded ${count} cloud skill hub${count === 1 ? "" : "s"} for ${activeOrg?.name ?? tr("den.active_org_title")}.`
- : `No cloud skill hubs are available for ${activeOrg?.name ?? tr("den.active_org_title")}.`,
+ ? `Loaded ${count} cloud skill hub${count === 1 ? "" : "s"} for ${activeOrg?.name ?? t("den.active_org_title")}.`
+ : `No cloud skill hubs are available for ${activeOrg?.name ?? t("den.active_org_title")}.`,
);
}
} catch (error) {
@@ -688,7 +681,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
setSkillHubsBusy(false);
}
},
- [activeOrg, activeOrgId, authToken, props.extensions, syncCurrentDenSettings, tr],
+ [activeOrg, activeOrgId, authToken, props.extensions, syncCurrentDenSettings],
);
const refreshSkills = useCallback(
@@ -706,25 +699,25 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
const count = props.extensions.cloudOrgSkills().length;
setStatusMessage(
count > 0
- ? tx("den.status_loaded_skills", {
+ ? t("den.status_loaded_skills", {
count,
plural: count === 1 ? "" : "s",
- name: activeOrg?.name ?? tr("den.active_org_title"),
+ name: activeOrg?.name ?? t("den.active_org_title"),
})
- : tx("den.status_no_skills", {
- name: activeOrg?.name ?? tr("den.active_org_title"),
+ : t("den.status_no_skills", {
+ name: activeOrg?.name ?? t("den.active_org_title"),
}),
);
}
} catch (error) {
if (!quiet) {
- setSkillActionError(error instanceof Error ? error.message : tr("den.error_load_skills"));
+ setSkillActionError(error instanceof Error ? error.message : t("den.error_load_skills"));
}
} finally {
setSkillsBusy(false);
}
},
- [activeOrg, activeOrgId, authToken, props.extensions, syncCurrentDenSettings, tr, tx],
+ [activeOrg, activeOrgId, authToken, props.extensions, syncCurrentDenSettings],
);
const refreshProviders = useCallback(
@@ -741,8 +734,8 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
if (!quiet) {
setStatusMessage(
items.length > 0
- ? `Loaded ${items.length} cloud provider${items.length === 1 ? "" : "s"} for ${activeOrg?.name ?? tr("den.active_org_title")}.`
- : `No cloud providers are available for ${activeOrg?.name ?? tr("den.active_org_title")}.`,
+ ? `Loaded ${items.length} cloud provider${items.length === 1 ? "" : "s"} for ${activeOrg?.name ?? t("den.active_org_title")}.`
+ : `No cloud providers are available for ${activeOrg?.name ?? t("den.active_org_title")}.`,
);
}
} catch (error) {
@@ -755,7 +748,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
setProvidersBusy(false);
}
},
- [activeOrg, activeOrgId, authToken, props, syncCurrentDenSettings, tr],
+ [activeOrg, activeOrgId, authToken, props, syncCurrentDenSettings],
);
const refreshMarketplaces = useCallback(
@@ -773,8 +766,8 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
const count = props.extensions.cloudOrgMarketplaces().length;
setStatusMessage(
count > 0
- ? `Loaded ${count} marketplace${count === 1 ? "" : "s"} for ${activeOrg?.name ?? tr("den.active_org_title")}.`
- : `No marketplaces are available for ${activeOrg?.name ?? tr("den.active_org_title")}.`,
+ ? `Loaded ${count} marketplace${count === 1 ? "" : "s"} for ${activeOrg?.name ?? t("den.active_org_title")}.`
+ : `No marketplaces are available for ${activeOrg?.name ?? t("den.active_org_title")}.`,
);
}
} catch (error) {
@@ -785,7 +778,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
setMarketplacesBusy(false);
}
},
- [activeOrg, activeOrgId, authToken, props.extensions, syncCurrentDenSettings, tr],
+ [activeOrg, activeOrgId, authToken, props.extensions, syncCurrentDenSettings],
);
useEffect(() => {
@@ -806,7 +799,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
.then((nextUser) => {
if (cancelled) return;
setUser(nextUser);
- setStatusMessage(tx("den.status_signed_in_as", { email: nextUser.email }));
+ setStatusMessage(t("den.status_signed_in_as", { email: nextUser.email }));
})
.catch((error) => {
if (cancelled) return;
@@ -815,7 +808,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
} else {
clearSessionState();
}
- setAuthError(error instanceof Error ? error.message : tr("den.error_no_session"));
+ setAuthError(error instanceof Error ? error.message : t("den.error_no_session"));
})
.finally(() => {
if (!cancelled) setSessionBusy(false);
@@ -824,7 +817,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
return () => {
cancelled = true;
};
- }, [authToken, baseUrl, clearSessionState, clearSignedInState, tr, tx]);
+ }, [authToken, baseUrl, clearSessionState, clearSignedInState]);
useEffect(() => {
if (!user) return;
@@ -877,34 +870,34 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
setSessionBusy(false);
setStatusMessage(
customEvent.detail.email?.trim()
- ? tx("den.status_cloud_signed_in_as", { email: customEvent.detail.email.trim() })
- : tr("den.status_cloud_signin_done"),
+ ? t("den.status_cloud_signed_in_as", { email: customEvent.detail.email.trim() })
+ : t("den.status_cloud_signin_done"),
);
} else if (customEvent.detail?.status === "error") {
- setAuthError(customEvent.detail.message?.trim() || tr("den.error_signin_failed"));
+ setAuthError(customEvent.detail.message?.trim() || t("den.error_signin_failed"));
}
};
window.addEventListener(denSessionUpdatedEvent, handler as EventListener);
return () => window.removeEventListener(denSessionUpdatedEvent, handler as EventListener);
- }, [clearSessionState, tr, tx]);
+ }, [clearSessionState]);
const submitManualAuth = useCallback(async () => {
const parsed = parseManualAuthInput(manualAuthInput);
if (!parsed || authBusy) {
- if (!parsed) setAuthError(tr("den.error_paste_valid_code"));
+ if (!parsed) setAuthError(t("den.error_paste_valid_code"));
return;
}
const nextBaseUrl = parsed.baseUrl ?? baseUrl;
setAuthBusy(true);
setAuthError(null);
- setStatusMessage(tr("den.signing_in"));
+ setStatusMessage(t("den.signing_in"));
try {
const result = await createDenClient({ baseUrl: nextBaseUrl }).exchangeDesktopHandoff(parsed.grant);
if (!result.token) {
- throw new Error(tr("den.error_no_token"));
+ throw new Error(t("den.error_no_token"));
}
if (props.developerMode) {
@@ -932,12 +925,12 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
} catch (error) {
dispatchDenSessionUpdated({
status: "error",
- message: error instanceof Error ? error.message : tr("den.error_signin_failed"),
+ message: error instanceof Error ? error.message : t("den.error_signin_failed"),
});
} finally {
setAuthBusy(false);
}
- }, [authBusy, baseUrl, manualAuthInput, props.developerMode, tr]);
+ }, [authBusy, baseUrl, manualAuthInput, props.developerMode]);
const signOut = useCallback(async () => {
if (authBusy) return;
@@ -953,14 +946,14 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
setAuthBusy(false);
}
- clearSignedInState(tr("den.status_signed_out"));
- }, [authBusy, authToken, clearSignedInState, client, tr]);
+ clearSignedInState(t("den.status_signed_out"));
+ }, [authBusy, authToken, clearSignedInState, client]);
const handleOpenWorker = useCallback(
async (workerId: string, workerName: string) => {
const orgId = activeOrgId.trim();
if (!orgId) {
- setWorkersError(tr("den.error_choose_org"));
+ setWorkersError(t("den.error_choose_org"));
return;
}
@@ -972,7 +965,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
const openworkUrl = tokens.openworkUrl?.trim() ?? "";
const accessToken = tokens.ownerToken?.trim() || tokens.clientToken?.trim() || "";
if (!openworkUrl || !accessToken) {
- throw new Error(tr("den.error_worker_not_ready"));
+ throw new Error(t("den.error_worker_not_ready"));
}
const ok = await props.connectRemoteWorkspace({
@@ -982,21 +975,21 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
displayName: workerName,
});
if (!ok) {
- throw new Error(tx("den.error_open_worker", { name: workerName }));
+ throw new Error(t("den.error_open_worker", { name: workerName }));
}
- setStatusMessage(tx("den.status_opened_worker", { name: workerName }));
+ setStatusMessage(t("den.status_opened_worker", { name: workerName }));
} catch (error) {
setWorkersError(
error instanceof Error
? error.message
- : tx("den.error_open_worker_fallback", { name: workerName }),
+ : t("den.error_open_worker_fallback", { name: workerName }),
);
} finally {
setOpeningWorkerId(null);
}
},
- [activeOrgId, client, props, tr, tx],
+ [activeOrgId, client, props],
);
const handleActiveOrgChange = useCallback(
@@ -1014,9 +1007,9 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
if (nextId) {
void ensureDenActiveOrganization({ forceServerSync: true }).catch(() => null);
}
- setStatusMessage(tx("den.org_switched", { name: nextOrg?.name ?? tr("den.active_org_title") }));
+ setStatusMessage(t("den.org_switched", { name: nextOrg?.name ?? t("den.active_org_title") }));
},
- [authToken, baseUrl, orgs, tr, tx],
+ [authToken, baseUrl, orgs],
);
const handleImportSkillHub = useCallback(
@@ -1031,7 +1024,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
try {
const result = await props.extensions.importCloudOrgSkillHub(hub);
if (!result.ok) throw new Error(result.message);
- setStatusMessage(`${result.message} ${tr("den.reload_workspace")}`);
+ setStatusMessage(`${result.message} ${t("den.reload_workspace")}`);
} catch (error) {
setSkillHubActionError(error instanceof Error ? error.message : `Failed to import ${hub.name}.`);
} finally {
@@ -1039,7 +1032,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
setSkillHubActionKind(null);
}
},
- [props.extensions, skillHubActionId, tr],
+ [props.extensions, skillHubActionId],
);
const handleRemoveSkillHub = useCallback(
@@ -1054,7 +1047,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
try {
const result = await props.extensions.removeCloudOrgSkillHub(hubId);
if (!result.ok) throw new Error(result.message);
- setStatusMessage(`${result.message} ${tr("den.reload_workspace")}`);
+ setStatusMessage(`${result.message} ${t("den.reload_workspace")}`);
} catch (error) {
setSkillHubActionError(error instanceof Error ? error.message : `Failed to remove ${imported.name}.`);
} finally {
@@ -1062,7 +1055,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
setSkillHubActionKind(null);
}
},
- [props.extensions, skillHubActionId, tr],
+ [props.extensions, skillHubActionId],
);
const handleSyncSkillHub = useCallback(
@@ -1077,7 +1070,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
try {
const result = await props.extensions.syncCloudOrgSkillHub(hub);
if (!result.ok) throw new Error(result.message);
- setStatusMessage(`${result.message} ${tr("den.reload_workspace")}`);
+ setStatusMessage(`${result.message} ${t("den.reload_workspace")}`);
} catch (error) {
setSkillHubActionError(error instanceof Error ? error.message : `Failed to sync ${hub.name}.`);
} finally {
@@ -1085,7 +1078,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
setSkillHubActionKind(null);
}
},
- [props.extensions, skillHubActionId, tr],
+ [props.extensions, skillHubActionId],
);
const handleImportSkill = useCallback(
@@ -1100,17 +1093,17 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
try {
const result = await props.extensions.installCloudOrgSkill(skill);
if (!result.ok) throw new Error(result.message);
- setStatusMessage(`${result.message} ${tr("den.reload_workspace")}`);
+ setStatusMessage(`${result.message} ${t("den.reload_workspace")}`);
} catch (error) {
setSkillActionError(
- error instanceof Error ? error.message : tx("den.import_skill_failed", { name: title }),
+ error instanceof Error ? error.message : t("den.import_skill_failed", { name: title }),
);
} finally {
setSkillActionId(null);
setSkillActionKind(null);
}
},
- [props.extensions, skillActionId, tr, tx],
+ [props.extensions, skillActionId],
);
const handleRemoveSkill = useCallback(
@@ -1124,17 +1117,17 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
try {
const result = await props.extensions.removeCloudOrgSkill(cloudSkillId);
if (!result.ok) throw new Error(result.message);
- setStatusMessage(`${result.message} ${tr("den.reload_workspace")}`);
+ setStatusMessage(`${result.message} ${t("den.reload_workspace")}`);
} catch (error) {
setSkillActionError(
- error instanceof Error ? error.message : tx("den.remove_skill_failed", { name: title }),
+ error instanceof Error ? error.message : t("den.remove_skill_failed", { name: title }),
);
} finally {
setSkillActionId(null);
setSkillActionKind(null);
}
},
- [props.extensions, skillActionId, tr, tx],
+ [props.extensions, skillActionId],
);
const handleSyncSkill = useCallback(
@@ -1149,17 +1142,17 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
try {
const result = await props.extensions.syncCloudOrgSkill(skill);
if (!result.ok) throw new Error(result.message);
- setStatusMessage(`${result.message} ${tr("den.reload_workspace")}`);
+ setStatusMessage(`${result.message} ${t("den.reload_workspace")}`);
} catch (error) {
setSkillActionError(
- error instanceof Error ? error.message : tx("den.sync_skill_failed", { name: title }),
+ error instanceof Error ? error.message : t("den.sync_skill_failed", { name: title }),
);
} finally {
setSkillActionId(null);
setSkillActionKind(null);
}
},
- [props.extensions, skillActionId, tr, tx],
+ [props.extensions, skillActionId],
);
const handleImportPlugin = useCallback(
@@ -1172,14 +1165,14 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
try {
const result = await props.extensions.importCloudOrgPlugin(marketplaceId, plugin);
if (!result.ok) throw new Error(result.message);
- setStatusMessage(`${result.message} ${tr("den.reload_workspace")}`);
+ setStatusMessage(`${result.message} ${t("den.reload_workspace")}`);
} catch (error) {
setPluginActionError(error instanceof Error ? error.message : `Failed to import ${plugin.name}.`);
} finally {
setPluginActionId(null);
}
},
- [pluginActionId, props.extensions, tr],
+ [pluginActionId, props.extensions],
);
const handleImportProvider = useCallback(
@@ -1192,17 +1185,17 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
try {
const message = await props.connectCloudProvider(cloudProviderId);
- setStatusMessage(`${message || tx("den.imported_provider", { name: providerName })} ${tr("den.reload_workspace")}`);
+ setStatusMessage(`${message || t("den.imported_provider", { name: providerName })} ${t("den.reload_workspace")}`);
} catch (error) {
setProviderActionError(
- error instanceof Error ? error.message : tx("den.import_provider_failed", { name: providerName }),
+ error instanceof Error ? error.message : t("den.import_provider_failed", { name: providerName }),
);
} finally {
setProviderActionId(null);
setProviderActionKind(null);
}
},
- [props, providerActionId, tr, tx],
+ [props, providerActionId],
);
const handleRemoveProvider = useCallback(
@@ -1215,17 +1208,17 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
try {
const message = await props.removeCloudProvider(cloudProviderId);
- setStatusMessage(`${message || tx("den.removed_provider", { name: providerName })} ${tr("den.reload_workspace")}`);
+ setStatusMessage(`${message || t("den.removed_provider", { name: providerName })} ${t("den.reload_workspace")}`);
} catch (error) {
setProviderActionError(
- error instanceof Error ? error.message : tx("den.remove_provider_failed", { name: providerName }),
+ error instanceof Error ? error.message : t("den.remove_provider_failed", { name: providerName }),
);
} finally {
setProviderActionId(null);
setProviderActionKind(null);
}
},
- [props, providerActionId, tr, tx],
+ [props, providerActionId],
);
const handleSyncProvider = useCallback(
@@ -1238,17 +1231,17 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
try {
await props.connectCloudProvider(cloudProviderId);
- setStatusMessage(`${tx("den.synced_provider", { name: providerName })} ${tr("den.reload_workspace")}`);
+ setStatusMessage(`${t("den.synced_provider", { name: providerName })} ${t("den.reload_workspace")}`);
} catch (error) {
setProviderActionError(
- error instanceof Error ? error.message : tx("den.sync_provider_failed", { name: providerName }),
+ error instanceof Error ? error.message : t("den.sync_provider_failed", { name: providerName }),
);
} finally {
setProviderActionId(null);
setProviderActionKind(null);
}
},
- [props, providerActionId, tr, tx],
+ [props, providerActionId],
);
return (
@@ -1258,14 +1251,14 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
- {tr("den.cloud_section_title")}
+ {t("den.cloud_section_title")}
- {tr("den.cloud_section_desc")}
+ {t("den.cloud_section_desc")}
- {tr("den.cloud_sleep_hint")}
+ {t("den.cloud_sleep_hint")}
@@ -1288,11 +1281,11 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
{props.developerMode ? (
setBaseUrlDraft(event.currentTarget.value)}
placeholder={DEFAULT_DEN_BASE_URL}
- hint={tr("den.cloud_control_plane_url_hint")}
+ hint={t("den.cloud_control_plane_url_hint")}
disabled={authBusy || sessionBusy}
/>
@@ -1302,7 +1295,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
onClick={() => setBaseUrlDraft(baseUrl)}
disabled={authBusy || sessionBusy}
>
- {tr("den.cloud_control_plane_reset")}
+ {t("den.cloud_control_plane_reset")}
- {tr("den.cloud_control_plane_save")}
+ {t("den.cloud_control_plane_save")}
- {tr("den.cloud_control_plane_open")}
+ {t("den.cloud_control_plane_open")}
@@ -1330,15 +1323,15 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
{!isSignedIn ? (
-
{tr("den.signin_title")}
+
{t("den.signin_title")}
- {tr("den.cloud_sleep_hint")}
+ {t("den.cloud_sleep_hint")}
openBrowserAuth("sign-in")}>
- {tr("den.signin_button")}
+ {t("den.signin_button")}
openBrowserAuth("sign-up")}
>
- {tr("den.create_account")}
+ {t("den.create_account")}
- {manualAuthOpen ? tr("den.hide_signin_code") : tr("den.paste_signin_code")}
+ {manualAuthOpen ? t("den.hide_signin_code") : t("den.paste_signin_code")}
{manualAuthOpen ? (
setManualAuthInput(event.currentTarget.value)}
- placeholder={tr("den.signin_link_placeholder")}
+ placeholder={t("den.signin_link_placeholder")}
disabled={authBusy || sessionBusy}
- hint={tr("den.signin_link_hint")}
+ hint={t("den.signin_link_hint")}
/>
void submitManualAuth()}
disabled={authBusy || sessionBusy || !manualAuthInput.trim()}
>
- {authBusy ? tr("den.finishing") : tr("den.finish_signin")}
+ {authBusy ? t("den.finishing") : t("den.finish_signin")}
-
{tr("den.signin_code_note")}
+
{t("den.signin_code_note")}
) : null}
@@ -1389,15 +1382,15 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
{authError ?
{authError}
: null}
- {tr("den.auto_reconnect_hint")}
+ {t("den.auto_reconnect_hint")}
) : (
-
{tr("den.cloud_account_title")}
-
{tr("den.cloud_account_hint")}
+
{t("den.cloud_account_title")}
+
{t("den.cloud_account_hint")}
@@ -1413,14 +1406,14 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
disabled={authBusy || sessionBusy}
>
- {authBusy ? tr("den.signing_out") : tr("den.sign_out")}
+ {authBusy ? t("den.signing_out") : t("den.sign_out")}
-
{tr("den.active_org_title")}
-
{tr("den.active_org_hint")}
+
{t("den.active_org_title")}
+
{t("den.active_org_hint")}
@@ -1429,8 +1422,8 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
options={activeOrgOptions}
onChange={handleActiveOrgChange}
disabled={orgsBusy || orgs.length === 0}
- placeholder={tr("den.no_org_selected")}
- ariaLabel={tr("den.active_org_title")}
+ placeholder={t("den.no_org_selected")}
+ ariaLabel={t("den.active_org_title")}
/>
- {tr("den.refresh")}
+ {t("den.refresh")}
@@ -1525,7 +1518,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
{row.plugin.name}
{row.status !== "available" ? (
- {row.status === "imported" ? tr("den.imported_badge") : tr("den.out_of_sync_badge")}
+ {row.status === "imported" ? t("den.imported_badge") : t("den.out_of_sync_badge")}
) : null}
{counts.length > 0 ? counts.map((label) =>
{label}) : null}
@@ -1545,7 +1538,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
onClick={() => void handleImportPlugin(row.marketplaceId, row.plugin)}
disabled={pluginActionId !== null}
>
- {actionBusy ? tr("den.importing") : row.status === "available" ? "Import plugin" : "Sync plugin"}
+ {actionBusy ? t("den.importing") : row.status === "available" ? "Import plugin" : "Sync plugin"}
);
@@ -1566,9 +1559,9 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
- {tr("den.cloud_skills_title")}
+ {t("den.cloud_skills_title")}
-
{tr("den.cloud_skills_hint")}
+
{t("den.cloud_skills_hint")}
@@ -1582,7 +1575,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
disabled={skillsBusy || !activeOrgId.trim()}
>
- {tr("den.refresh")}
+ {t("den.refresh")}
@@ -1593,7 +1586,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
{!skillsBusy && skillRows.length === 0 ? (
- {activeOrgId.trim() ? tr("den.no_cloud_skills") : tr("den.choose_org_for_skills")}
+ {activeOrgId.trim() ? t("den.no_cloud_skills") : t("den.choose_org_for_skills")}
) : null}
@@ -1603,10 +1596,10 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
const actionLabel = !actionBusy
? null
: skillActionKind === "import"
- ? tr("den.importing")
+ ? t("den.importing")
: skillActionKind === "sync"
- ? tr("den.syncing")
- : tr("den.removing");
+ ? t("den.syncing")
+ : t("den.removing");
return (
{row.title}
{row.skill?.hubName ? (
- {tx("skills.cloud_hub_label", { name: row.skill.hubName })}
+ {t("skills.cloud_hub_label", { name: row.skill.hubName })}
) : null}
- {row.skill?.shared === "org" ? {tr("skills.cloud_shared_org")} : null}
- {row.skill?.shared === "public" ? {tr("skills.cloud_shared_public")} : null}
- {row.skill?.shared === null && !row.skill?.hubName ? {tr("den.private_badge")} : null}
+ {row.skill?.shared === "org" ? {t("skills.cloud_shared_org")} : null}
+ {row.skill?.shared === "public" ? {t("skills.cloud_shared_public")} : null}
+ {row.skill?.shared === null && !row.skill?.hubName ? {t("den.private_badge")} : null}
{row.installedName ? (
- {tx("den.installed_name_badge", { name: row.installedName })}
+ {t("den.installed_name_badge", { name: row.installedName })}
) : null}
{row.status !== "available" ? (
{row.status === "installed"
- ? tr("den.imported_badge")
+ ? t("den.imported_badge")
: row.status === "out_of_sync"
- ? tr("den.out_of_sync_badge")
- : tr("den.removed_from_cloud_badge")}
+ ? t("den.out_of_sync_badge")
+ : t("den.removed_from_cloud_badge")}
) : null}
{row.status === "available"
- ? tx("den.cloud_skill_detail", { title: row.title })
+ ? t("den.cloud_skill_detail", { title: row.title })
: row.status === "installed"
- ? tx("den.cloud_skill_imported_detail", { name: row.installedName ?? row.title })
+ ? t("den.cloud_skill_imported_detail", { name: row.installedName ?? row.title })
: row.status === "out_of_sync"
- ? tx("den.cloud_skill_sync_detail", { name: row.installedName ?? row.title })
- : tx("den.cloud_skill_removed_detail", { name: row.installedName ?? row.title })}
+ ? t("den.cloud_skill_sync_detail", { name: row.installedName ?? row.title })
+ : t("den.cloud_skill_removed_detail", { name: row.installedName ?? row.title })}
@@ -1653,7 +1646,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
onClick={() => void handleSyncSkill(row.cloudSkillId, row.title)}
disabled={skillActionId !== null}
>
- {actionBusy && skillActionKind === "sync" ? tr("den.syncing") : tr("den.sync")}
+ {actionBusy && skillActionKind === "sync" ? t("den.syncing") : t("den.sync")}
) : null}
- {actionBusy ? actionLabel : row.status === "available" ? tr("den.import_skill") : tr("den.uninstall")}
+ {actionBusy ? actionLabel : row.status === "available" ? t("den.import_skill") : t("den.uninstall")}
@@ -1681,9 +1674,9 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
- {tr("den.cloud_workers_title")}
+ {t("den.cloud_workers_title")}
-
{tr("den.cloud_workers_hint")}
+
{t("den.cloud_workers_hint")}
@@ -1697,7 +1690,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
disabled={workersBusy || !activeOrgId.trim()}
>
- {tr("den.refresh")}
+ {t("den.refresh")}
@@ -1706,13 +1699,13 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
{!workersBusy && workers.length === 0 ? (
- {tr("den.no_cloud_workers")}
+ {t("den.no_cloud_workers")}
) : null}
{workers.map((worker) => {
- const status = workerStatusMeta(worker.status, tr);
+ const status = workerStatusMeta(worker.status);
return (
{status.label}
- {worker.isMine ? {tr("den.worker_mine_badge")} : null}
+ {worker.isMine ? {t("den.worker_mine_badge")} : null}
- {worker.provider ? tx("den.worker_provider_label", { provider: worker.provider }) : tr("den.worker_secondary_cloud")}
+ {worker.provider ? t("den.worker_provider_label", { provider: worker.provider }) : t("den.worker_secondary_cloud")}
{worker.instanceUrl ? · {worker.instanceUrl} : null}
@@ -1738,9 +1731,9 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
className="h-8 shrink-0 px-4 text-xs"
onClick={() => void handleOpenWorker(worker.workerId, worker.workerName)}
disabled={openingWorkerId !== null || !status.canOpen}
- title={!status.canOpen ? tr("den.worker_not_ready_title") : undefined}
+ title={!status.canOpen ? t("den.worker_not_ready_title") : undefined}
>
- {openingWorkerId === worker.workerId ? tr("den.opening") : tr("den.open")}
+ {openingWorkerId === worker.workerId ? t("den.opening") : t("den.open")}
);
@@ -1753,9 +1746,9 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
- {tr("den.skill_hubs_title")}
+ {t("den.skill_hubs_title")}
-
{tr("den.skill_hubs_hint")}
+
{t("den.skill_hubs_hint")}
@@ -1769,7 +1762,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
disabled={skillHubsBusy || !activeOrgId.trim()}
>
- {tr("den.refresh")}
+ {t("den.refresh")}
@@ -1780,7 +1773,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
{!skillHubsBusy && skillHubRows.length === 0 ? (
- {activeOrgId.trim() ? tr("den.no_skill_hubs") : tr("den.choose_org_for_skill_hubs")}
+ {activeOrgId.trim() ? t("den.no_skill_hubs") : t("den.choose_org_for_skill_hubs")}
) : null}
@@ -1790,10 +1783,10 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
const actionLabel = !actionBusy
? null
: skillHubActionKind === "import"
- ? tr("den.importing")
+ ? t("den.importing")
: skillHubActionKind === "sync"
- ? tr("den.syncing")
- : tr("den.removing");
+ ? t("den.syncing")
+ : t("den.removing");
return (
{row.name}
- {tx("den.skill_hub_skills_badge", { count: row.hub?.skills.length ?? row.importedSkillCount })}
+ {t("den.skill_hub_skills_badge", { count: row.hub?.skills.length ?? row.importedSkillCount })}
{row.status !== "available" ? (
{row.status === "imported"
- ? tr("den.imported_badge")
+ ? t("den.imported_badge")
: row.status === "out_of_sync"
- ? tr("den.out_of_sync_badge")
- : tr("den.removed_from_cloud_badge")}
+ ? t("den.out_of_sync_badge")
+ : t("den.removed_from_cloud_badge")}
) : null}
{row.status === "available"
- ? tx("den.skill_hub_detail", { count: row.liveSkillCount })
+ ? t("den.skill_hub_detail", { count: row.liveSkillCount })
: row.status === "imported"
- ? tx("den.skill_hub_imported_detail", { count: row.importedSkillCount })
+ ? t("den.skill_hub_imported_detail", { count: row.importedSkillCount })
: row.status === "out_of_sync"
- ? tx("den.skill_hub_sync_detail", {
+ ? t("den.skill_hub_sync_detail", {
liveCount: row.liveSkillCount,
importedCount: row.importedSkillCount,
})
- : tx("den.skill_hub_removed_detail", { importedCount: row.importedSkillCount })}
+ : t("den.skill_hub_removed_detail", { importedCount: row.importedSkillCount })}
@@ -1837,7 +1830,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
onClick={() => void handleSyncSkillHub(row.hubId)}
disabled={skillHubActionId !== null}
>
- {actionBusy && skillHubActionKind === "sync" ? tr("den.syncing") : tr("den.sync")}
+ {actionBusy && skillHubActionKind === "sync" ? t("den.syncing") : t("den.sync")}
) : null}
@@ -1869,9 +1862,9 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
- {tr("den.cloud_providers_title")}
+ {t("den.cloud_providers_title")}
-
{tr("den.cloud_providers_hint")}
+
{t("den.cloud_providers_hint")}
@@ -1885,7 +1878,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
disabled={providersBusy || !activeOrgId.trim()}
>
- {tr("den.refresh")}
+ {t("den.refresh")}
@@ -1894,7 +1887,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
{!providersBusy && providerRows.length === 0 ? (
- {activeOrgId.trim() ? tr("den.no_cloud_providers") : tr("den.choose_org_for_providers")}
+ {activeOrgId.trim() ? t("den.no_cloud_providers") : t("den.choose_org_for_providers")}
) : null}
@@ -1904,10 +1897,10 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
const actionLabel = !actionBusy
? null
: providerActionKind === "import"
- ? tr("den.importing")
+ ? t("den.importing")
: providerActionKind === "sync"
- ? tr("den.syncing")
- : tr("den.removing");
+ ? t("den.syncing")
+ : t("den.removing");
return (
{row.provider?.providerId ?? row.imported?.providerId}
- {row.provider?.hasApiKey ?
{tr("den.credentials_ready_badge")} : null}
+ {row.provider?.hasApiKey ?
{t("den.credentials_ready_badge")} : null}
{row.status !== "available" ? (
{row.status === "imported"
- ? tr("den.imported_badge")
+ ? t("den.imported_badge")
: row.status === "out_of_sync"
- ? tr("den.out_of_sync_badge")
- : tr("den.removed_from_cloud_badge")}
+ ? t("den.out_of_sync_badge")
+ : t("den.removed_from_cloud_badge")}
) : null}
{row.status === "removed_from_cloud"
- ? tx("den.cloud_provider_removed_detail", { providerId: row.imported?.providerId ?? row.name })
+ ? t("den.cloud_provider_removed_detail", { providerId: row.imported?.providerId ?? row.name })
: row.status === "out_of_sync"
- ? tx("den.cloud_provider_sync_detail", {
+ ? t("den.cloud_provider_sync_detail", {
count: row.provider?.models.length ?? 0,
source: row.provider?.source === "custom" ? "custom" : "managed",
})
- : tx("den.cloud_provider_detail", {
+ : t("den.cloud_provider_detail", {
count: row.provider?.models.length ?? 0,
source: row.provider?.source === "custom" ? "custom" : "managed",
})}
@@ -1954,7 +1947,7 @@ export function DenSettingsPanel(props: DenSettingsPanelProps) {
onClick={() => void handleSyncProvider(row.cloudProviderId, row.name)}
disabled={providerActionId !== null}
>
- {actionBusy && providerActionKind === "sync" ? tr("den.syncing") : tr("den.sync")}
+ {actionBusy && providerActionKind === "sync" ? t("den.syncing") : t("den.sync")}
) : null}
diff --git a/apps/app/src/react-app/domains/settings/state/extensions-store.ts b/apps/app/src/react-app/domains/settings/state/extensions-store.ts
index df9c3db18..5ea3bbb70 100644
--- a/apps/app/src/react-app/domains/settings/state/extensions-store.ts
+++ b/apps/app/src/react-app/domains/settings/state/extensions-store.ts
@@ -2,7 +2,7 @@ import { useSyncExternalStore } from "react";
import { applyEdits, modify } from "jsonc-parser";
-import { currentLocale, t } from "../../../../i18n";
+import { t } from "../../../../i18n";
import type {
Client,
DenOrgSkillCard,
@@ -192,7 +192,6 @@ export function createExtensionsStore(options: {
markReloadRequired?: (reason: ReloadReason, trigger?: ReloadTrigger) => void;
}) {
const listeners = new Set<() => void>();
- const translate = (key: string) => t(key, currentLocale());
let disposed = false;
let started = false;
@@ -539,18 +538,18 @@ export function createExtensionsStore(options: {
}
if (!isDesktopRuntime()) {
- throw new Error(translate("skills.desktop_required"));
+ throw new Error(t("skills.desktop_required"));
}
if (!isLocalWorkspace || !root) {
- throw new Error(translate("skills.pick_workspace_first"));
+ throw new Error(t("skills.pick_workspace_first"));
}
const result = await installSkillTemplate(root, name, content, {
overwrite: optionsOverride?.overwrite ?? false,
});
if (!result.ok) {
- throw new Error(result.stderr || result.stdout || translate("skills.install_failed"));
+ throw new Error(result.stderr || result.stdout || t("skills.install_failed"));
}
};
@@ -609,16 +608,16 @@ export function createExtensionsStore(options: {
}
if (!isDesktopRuntime()) {
- throw new Error(translate("skills.desktop_required"));
+ throw new Error(t("skills.desktop_required"));
}
if (!isLocalWorkspace || !root) {
- throw new Error(translate("skills.pick_workspace_first"));
+ throw new Error(t("skills.pick_workspace_first"));
}
const result = await uninstallSkillCommand(root, name);
if (!result.ok) {
- throw new Error(result.stderr || result.stdout || translate("skills.uninstall_failed"));
+ throw new Error(result.stderr || result.stdout || t("skills.uninstall_failed"));
}
};
@@ -1004,7 +1003,7 @@ export function createExtensionsStore(options: {
mutateState((current) => ({
...current,
cloudOrgSkills: catalog,
- cloudOrgSkillsStatus: catalog.length ? null : translate("skills.cloud_org_empty"),
+ cloudOrgSkillsStatus: catalog.length ? null : t("skills.cloud_org_empty"),
cloudOrgSkillsContextKey: loadKey,
}));
cloudOrgSkillsLoaded = true;
@@ -1016,7 +1015,7 @@ export function createExtensionsStore(options: {
...current,
cloudOrgSkills: [],
cloudOrgSkillsStatus:
- error instanceof Error ? error.message : translate("skills.cloud_org_load_failed"),
+ error instanceof Error ? error.message : t("skills.cloud_org_load_failed"),
}));
} finally {
refreshCloudOrgSkillsInFlight = false;
@@ -1168,7 +1167,7 @@ export function createExtensionsStore(options: {
files,
};
} catch (error) {
- const message = error instanceof Error ? error.message : translate("skills.unknown_error");
+ const message = error instanceof Error ? error.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
return { ok: false, message, files: [] };
} finally {
@@ -1206,7 +1205,7 @@ export function createExtensionsStore(options: {
importedNames,
};
} catch (error) {
- const message = error instanceof Error ? error.message : translate("skills.unknown_error");
+ const message = error instanceof Error ? error.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
return { ok: false, message, importedNames };
} finally {
@@ -1241,7 +1240,7 @@ export function createExtensionsStore(options: {
await refreshCloudOrgSkillHubs({ force: true });
return { ok: true, message: `Synced ${hub.name} from cloud.`, importedNames: applied.nextSkillNames };
} catch (error) {
- const message = error instanceof Error ? error.message : translate("skills.unknown_error");
+ const message = error instanceof Error ? error.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
return { ok: false, message, importedNames: [] };
} finally {
@@ -1277,7 +1276,7 @@ export function createExtensionsStore(options: {
removedNames: imported.skillNames,
};
} catch (error) {
- const message = error instanceof Error ? error.message : translate("skills.unknown_error");
+ const message = error instanceof Error ? error.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
return { ok: false, message, removedNames: [] };
} finally {
@@ -1318,7 +1317,7 @@ export function createExtensionsStore(options: {
if (!result?.ok) return { ok: false, message: "Install failed." };
return { ok: true, message: `Installed ${trimmed}.` };
} catch (error) {
- const message = error instanceof Error ? error.message : translate("skills.unknown_error");
+ const message = error instanceof Error ? error.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
return { ok: false, message };
} finally {
@@ -1350,10 +1349,10 @@ export function createExtensionsStore(options: {
await refreshCloudOrgSkills({ force: true });
return {
ok: true,
- message: t(existingImport ? "skills.cloud_updated" : "skills.cloud_installed", currentLocale(), { name: installName }),
+ message: t(existingImport ? "skills.cloud_updated" : "skills.cloud_installed", { name: installName }),
};
} catch (error) {
- const message = error instanceof Error ? error.message : translate("skills.unknown_error");
+ const message = error instanceof Error ? error.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
return { ok: false, message };
} finally {
@@ -1387,11 +1386,11 @@ export function createExtensionsStore(options: {
await refreshCloudOrgSkills({ force: true });
return {
ok: true,
- message: t("skills.cloud_removed", currentLocale(), { name: imported.installedName }),
+ message: t("skills.cloud_removed", { name: imported.installedName }),
removedName: imported.installedName,
};
} catch (error) {
- const message = error instanceof Error ? error.message : translate("skills.unknown_error");
+ const message = error instanceof Error ? error.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
return { ok: false, message, removedName: null };
} finally {
@@ -1438,7 +1437,7 @@ export function createExtensionsStore(options: {
mutateState((current) => ({
...current,
skills: [],
- skillsStatus: translate("skills.pick_workspace_first"),
+ skillsStatus: t("skills.pick_workspace_first"),
}));
return;
}
@@ -1465,7 +1464,7 @@ export function createExtensionsStore(options: {
mutateState((current) => ({
...current,
skills: next,
- skillsStatus: next.length ? null : translate("skills.no_skills_found"),
+ skillsStatus: next.length ? null : t("skills.no_skills_found"),
skillsContextKey: getWorkspaceContextKey(),
}));
skillsLoaded = true;
@@ -1475,7 +1474,7 @@ export function createExtensionsStore(options: {
mutateState((current) => ({
...current,
skills: [],
- skillsStatus: error instanceof Error ? error.message : translate("skills.failed_to_load"),
+ skillsStatus: error instanceof Error ? error.message : t("skills.failed_to_load"),
}));
} finally {
refreshSkillsInFlight = false;
@@ -1505,7 +1504,7 @@ export function createExtensionsStore(options: {
mutateState((current) => ({
...current,
skills: next,
- skillsStatus: next.length ? null : translate("skills.no_skills_found"),
+ skillsStatus: next.length ? null : t("skills.no_skills_found"),
skillsContextKey: getWorkspaceContextKey(),
}));
skillsLoaded = true;
@@ -1515,7 +1514,7 @@ export function createExtensionsStore(options: {
mutateState((current) => ({
...current,
skills: [],
- skillsStatus: error instanceof Error ? error.message : translate("skills.failed_to_load"),
+ skillsStatus: error instanceof Error ? error.message : t("skills.failed_to_load"),
}));
} finally {
refreshSkillsInFlight = false;
@@ -1549,7 +1548,7 @@ export function createExtensionsStore(options: {
};
if (result?.data === undefined) {
const err = result?.error;
- const message = err instanceof Error ? err.message : typeof err === "string" ? err : translate("skills.failed_to_load");
+ const message = err instanceof Error ? err.message : typeof err === "string" ? err : t("skills.failed_to_load");
throw new Error(message);
}
if (refreshSkillsAborted) return;
@@ -1563,7 +1562,7 @@ export function createExtensionsStore(options: {
mutateState((current) => ({
...current,
skills: next,
- skillsStatus: next.length ? null : translate("skills.no_skills_found"),
+ skillsStatus: next.length ? null : t("skills.no_skills_found"),
skillsContextKey: getWorkspaceContextKey(),
}));
skillsLoaded = true;
@@ -1573,7 +1572,7 @@ export function createExtensionsStore(options: {
mutateState((current) => ({
...current,
skills: [],
- skillsStatus: error instanceof Error ? error.message : translate("skills.failed_to_load"),
+ skillsStatus: error instanceof Error ? error.message : t("skills.failed_to_load"),
}));
} finally {
refreshSkillsInFlight = false;
@@ -1651,9 +1650,9 @@ export function createExtensionsStore(options: {
if (!isDesktopRuntime()) {
mutateState((current) => ({
...current,
- pluginStatus: translate("skills.plugin_management_host_only"),
+ pluginStatus: t("skills.plugin_management_host_only"),
pluginList: [],
- sidebarPluginStatus: translate("skills.plugins_host_only"),
+ sidebarPluginStatus: t("skills.plugins_host_only"),
sidebarPluginList: [],
}));
refreshPluginsInFlight = false;
@@ -1675,9 +1674,9 @@ export function createExtensionsStore(options: {
if (scope === "project" && !targetDir) {
mutateState((current) => ({
...current,
- pluginStatus: translate("skills.pick_project_for_plugins"),
+ pluginStatus: t("skills.pick_project_for_plugins"),
pluginList: [],
- sidebarPluginStatus: translate("skills.pick_project_for_active"),
+ sidebarPluginStatus: t("skills.pick_project_for_active"),
sidebarPluginList: [],
}));
refreshPluginsInFlight = false;
@@ -1695,9 +1694,9 @@ export function createExtensionsStore(options: {
mutateState((current) => ({
...current,
pluginList: [],
- pluginStatus: translate("skills.no_opencode_found"),
+ pluginStatus: t("skills.no_opencode_found"),
sidebarPluginList: [],
- sidebarPluginStatus: translate("skills.no_opencode_workspace"),
+ sidebarPluginStatus: t("skills.no_opencode_workspace"),
}));
return;
}
@@ -1708,7 +1707,7 @@ export function createExtensionsStore(options: {
nextSidebarPluginList = parsePluginListFromContent(config.content ?? "");
} catch {
nextSidebarPluginList = [];
- nextSidebarPluginStatus = translate("skills.failed_parse_opencode");
+ nextSidebarPluginStatus = t("skills.failed_parse_opencode");
}
const nextPluginList: string[] = [];
@@ -1738,8 +1737,8 @@ export function createExtensionsStore(options: {
pluginConfig: null,
pluginConfigPath: null,
pluginList: [],
- pluginStatus: error instanceof Error ? error.message : translate("skills.failed_load_opencode"),
- sidebarPluginStatus: translate("skills.failed_load_active"),
+ pluginStatus: error instanceof Error ? error.message : t("skills.failed_load_opencode"),
+ sidebarPluginStatus: t("skills.failed_load_active"),
sidebarPluginList: [],
}));
} finally {
@@ -1764,7 +1763,7 @@ export function createExtensionsStore(options: {
openworkSnapshot.openworkServerCapabilities?.plugins?.write;
if (!pluginName) {
- if (isManualInput) setStateField("pluginStatus", translate("skills.enter_plugin_name"));
+ if (isManualInput) setStateField("pluginStatus", t("skills.enter_plugin_name"));
return;
}
@@ -1787,7 +1786,7 @@ export function createExtensionsStore(options: {
}
if (!isDesktopRuntime()) {
- setStateField("pluginStatus", translate("skills.plugin_management_host_only"));
+ setStateField("pluginStatus", t("skills.plugin_management_host_only"));
return;
}
@@ -1800,7 +1799,7 @@ export function createExtensionsStore(options: {
const targetDir = options.projectDir().trim();
if (scope === "project" && !targetDir) {
- setStateField("pluginStatus", translate("skills.pick_project_for_plugins"));
+ setStateField("pluginStatus", t("skills.pick_project_for_plugins"));
return;
}
@@ -1821,7 +1820,7 @@ export function createExtensionsStore(options: {
const plugins = parsePluginListFromContent(raw);
const desired = stripPluginVersion(pluginName).toLowerCase();
if (plugins.some((entry) => stripPluginVersion(entry).toLowerCase() === desired)) {
- setStateField("pluginStatus", translate("skills.plugin_already_listed"));
+ setStateField("pluginStatus", t("skills.plugin_already_listed"));
return;
}
@@ -1833,7 +1832,7 @@ export function createExtensionsStore(options: {
if (isManualInput) setStateField("pluginInput", "");
await refreshPlugins(scope);
} catch (error) {
- setStateField("pluginStatus", error instanceof Error ? error.message : translate("skills.failed_update_opencode"));
+ setStateField("pluginStatus", error instanceof Error ? error.message : t("skills.failed_update_opencode"));
}
}
@@ -1870,7 +1869,7 @@ export function createExtensionsStore(options: {
}
if (!isDesktopRuntime()) {
- setStateField("pluginStatus", translate("skills.plugin_management_host_only"));
+ setStateField("pluginStatus", t("skills.plugin_management_host_only"));
return;
}
@@ -1882,7 +1881,7 @@ export function createExtensionsStore(options: {
const scope = snapshot.pluginScope;
const targetDir = options.projectDir().trim();
if (scope === "project" && !targetDir) {
- setStateField("pluginStatus", translate("skills.pick_project_for_plugins"));
+ setStateField("pluginStatus", t("skills.pick_project_for_plugins"));
return;
}
@@ -1909,14 +1908,14 @@ export function createExtensionsStore(options: {
options.markReloadRequired?.("plugins", { type: "plugin", name: triggerName, action: "removed" });
await refreshPlugins(scope);
} catch (error) {
- setStateField("pluginStatus", error instanceof Error ? error.message : translate("skills.failed_update_opencode"));
+ setStateField("pluginStatus", error instanceof Error ? error.message : t("skills.failed_update_opencode"));
}
}
async function importLocalSkill() {
const isLocalWorkspace = options.workspaceType() === "local";
if (!isDesktopRuntime()) {
- options.setError(translate("skills.desktop_required"));
+ options.setError(t("skills.desktop_required"));
return;
}
if (!isLocalWorkspace) {
@@ -1925,7 +1924,7 @@ export function createExtensionsStore(options: {
}
const targetDir = options.projectDir().trim();
if (!targetDir) {
- options.setError(translate("skills.pick_project_first"));
+ options.setError(t("skills.pick_project_first"));
return;
}
@@ -1933,20 +1932,20 @@ export function createExtensionsStore(options: {
options.setError(null);
setStateField("skillsStatus", null);
try {
- const selection = await pickDirectory({ title: translate("skills.select_skill_folder") });
+ const selection = await pickDirectory({ title: t("skills.select_skill_folder") });
const sourceDir = typeof selection === "string" ? selection : Array.isArray(selection) ? selection[0] : null;
if (!sourceDir) return;
const inferredName = sourceDir.split(/[\\/]/).filter(Boolean).pop();
const result = await importSkill(targetDir, sourceDir, { overwrite: false });
if (!result.ok) {
- setStateField("skillsStatus", result.stderr || result.stdout || translate("skills.import_failed").replace("{status}", String(result.status)));
+ setStateField("skillsStatus", result.stderr || result.stdout || t("skills.import_failed").replace("{status}", String(result.status)));
} else {
- setStateField("skillsStatus", result.stdout || translate("skills.imported"));
+ setStateField("skillsStatus", result.stdout || t("skills.imported"));
options.markReloadRequired?.("skills", { type: "skill", name: inferredName, action: "added" });
}
await refreshSkills({ force: true });
} catch (error) {
- const message = error instanceof Error ? error.message : translate("skills.unknown_error");
+ const message = error instanceof Error ? error.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
} finally {
options.setBusy(false);
@@ -1968,16 +1967,16 @@ export function createExtensionsStore(options: {
if (canUseOpenworkServer) {
options.setBusy(true);
options.setError(null);
- setStateField("skillsStatus", translate("skills.installing_skill_creator"));
+ setStateField("skillsStatus", t("skills.installing_skill_creator"));
try {
await openworkClient.upsertSkill(openworkWorkspaceId, { name: "skill-creator", content: skillCreatorTemplate });
- const message = translate("skills.skill_creator_installed");
+ const message = t("skills.skill_creator_installed");
setStateField("skillsStatus", message);
options.markReloadRequired?.("skills", { type: "skill", name: "skill-creator", action: "added" });
await refreshSkills({ force: true });
return { ok: true, message };
} catch (error) {
- const raw = error instanceof Error ? error.message : translate("skills.unknown_error");
+ const raw = error instanceof Error ? error.message : t("skills.unknown_error");
const message = addOpencodeCacheHint(raw);
setStateField("skillsStatus", message);
options.setError(message);
@@ -1993,7 +1992,7 @@ export function createExtensionsStore(options: {
return { ok: false, message };
}
if (!isDesktopRuntime()) {
- const message = translate("skills.desktop_required");
+ const message = t("skills.desktop_required");
setStateField("skillsStatus", message);
return { ok: false, message };
}
@@ -2006,35 +2005,35 @@ export function createExtensionsStore(options: {
const targetDir = options.selectedWorkspaceRoot().trim();
if (!targetDir) {
- const message = translate("skills.pick_workspace_first");
+ const message = t("skills.pick_workspace_first");
setStateField("skillsStatus", message);
return { ok: false, message };
}
options.setBusy(true);
options.setError(null);
- setStateField("skillsStatus", translate("skills.installing_skill_creator"));
+ setStateField("skillsStatus", t("skills.installing_skill_creator"));
try {
const result = await installSkillTemplate(targetDir, "skill-creator", skillCreatorTemplate, { overwrite: false });
if (!result.ok && /already exists/i.test(result.stderr)) {
- const message = translate("skills.skill_creator_already_installed");
+ const message = t("skills.skill_creator_already_installed");
setStateField("skillsStatus", message);
await refreshSkills({ force: true });
return { ok: true, message };
}
if (!result.ok) {
- const message = result.stderr || result.stdout || translate("skills.install_failed");
+ const message = result.stderr || result.stdout || t("skills.install_failed");
setStateField("skillsStatus", message);
await refreshSkills({ force: true });
return { ok: false, message };
}
- const message = result.stdout || translate("skills.skill_creator_installed");
+ const message = result.stdout || t("skills.skill_creator_installed");
setStateField("skillsStatus", message);
options.markReloadRequired?.("skills", { type: "skill", name: "skill-creator", action: "added" });
await refreshSkills({ force: true });
return { ok: true, message };
} catch (error) {
- const raw = error instanceof Error ? error.message : translate("skills.unknown_error");
+ const raw = error instanceof Error ? error.message : t("skills.unknown_error");
const message = addOpencodeCacheHint(raw);
setStateField("skillsStatus", message);
options.setError(message);
@@ -2046,12 +2045,12 @@ export function createExtensionsStore(options: {
async function revealSkillsFolder() {
if (!isDesktopRuntime()) {
- setStateField("skillsStatus", translate("skills.desktop_required"));
+ setStateField("skillsStatus", t("skills.desktop_required"));
return;
}
const root = options.selectedWorkspaceRoot().trim();
if (!root) {
- setStateField("skillsStatus", translate("skills.pick_workspace_first"));
+ setStateField("skillsStatus", t("skills.pick_workspace_first"));
return;
}
@@ -2072,14 +2071,14 @@ export function createExtensionsStore(options: {
if (await tryOpen(legacySkills)) return;
await revealDesktopItemInDir(opencodeSkills);
} catch (error) {
- setStateField("skillsStatus", error instanceof Error ? error.message : translate("skills.reveal_failed"));
+ setStateField("skillsStatus", error instanceof Error ? error.message : t("skills.reveal_failed"));
}
}
async function uninstallSkill(name: string) {
const root = options.selectedWorkspaceRoot().trim();
if (!root) {
- setStateField("skillsStatus", translate("skills.pick_workspace_first"));
+ setStateField("skillsStatus", t("skills.pick_workspace_first"));
return;
}
const trimmed = name.trim();
@@ -2090,11 +2089,11 @@ export function createExtensionsStore(options: {
setStateField("skillsStatus", null);
try {
await deleteWorkspaceSkill(trimmed);
- setStateField("skillsStatus", translate("skills.uninstalled"));
+ setStateField("skillsStatus", t("skills.uninstalled"));
options.markReloadRequired?.("skills", { type: "skill", name: trimmed, action: "removed" });
await refreshSkills({ force: true });
} catch (error) {
- const message = error instanceof Error ? error.message : translate("skills.unknown_error");
+ const message = error instanceof Error ? error.message : t("skills.unknown_error");
setStateField("skillsStatus", message);
options.setError(addOpencodeCacheHint(message));
} finally {
@@ -2107,7 +2106,7 @@ export function createExtensionsStore(options: {
if (!trimmed) return null;
const root = options.selectedWorkspaceRoot().trim();
if (!root) {
- setStateField("skillsStatus", translate("skills.pick_workspace_first"));
+ setStateField("skillsStatus", t("skills.pick_workspace_first"));
return null;
}
@@ -2128,7 +2127,7 @@ export function createExtensionsStore(options: {
const result = await openworkClient.getSkill(openworkWorkspaceId, trimmed, { includeGlobal: isLocalWorkspace });
return { name: result.item.name, path: result.item.path, content: result.content };
} catch (error) {
- setStateField("skillsStatus", error instanceof Error ? error.message : translate("skills.failed_to_load"));
+ setStateField("skillsStatus", error instanceof Error ? error.message : t("skills.failed_to_load"));
return null;
}
}
@@ -2138,7 +2137,7 @@ export function createExtensionsStore(options: {
return null;
}
if (!isDesktopRuntime()) {
- setStateField("skillsStatus", translate("skills.desktop_required"));
+ setStateField("skillsStatus", t("skills.desktop_required"));
return null;
}
if (!isLocalWorkspace) {
@@ -2151,7 +2150,7 @@ export function createExtensionsStore(options: {
const result = await readLocalSkill(root, trimmed);
return { name: trimmed, path: result.path, content: result.content };
} catch (error) {
- setStateField("skillsStatus", error instanceof Error ? error.message : translate("skills.failed_to_load"));
+ setStateField("skillsStatus", error instanceof Error ? error.message : t("skills.failed_to_load"));
return null;
}
}
@@ -2161,7 +2160,7 @@ export function createExtensionsStore(options: {
if (!trimmed) return;
const root = options.selectedWorkspaceRoot().trim();
if (!root) {
- setStateField("skillsStatus", translate("skills.pick_workspace_first"));
+ setStateField("skillsStatus", t("skills.pick_workspace_first"));
return;
}
@@ -2190,7 +2189,7 @@ export function createExtensionsStore(options: {
await refreshSkills({ force: true });
setStateField("skillsStatus", "Saved.");
} catch (error) {
- const message = error instanceof Error ? error.message : translate("skills.unknown_error");
+ const message = error instanceof Error ? error.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
} finally {
options.setBusy(false);
@@ -2203,7 +2202,7 @@ export function createExtensionsStore(options: {
return;
}
if (!isDesktopRuntime()) {
- setStateField("skillsStatus", translate("skills.desktop_required"));
+ setStateField("skillsStatus", t("skills.desktop_required"));
return;
}
if (!isLocalWorkspace) {
@@ -2217,14 +2216,14 @@ export function createExtensionsStore(options: {
try {
const result = await writeLocalSkill(root, trimmed, input.content);
if (!result.ok) {
- setStateField("skillsStatus", result.stderr || result.stdout || translate("skills.unknown_error"));
+ setStateField("skillsStatus", result.stderr || result.stdout || t("skills.unknown_error"));
} else {
setStateField("skillsStatus", result.stdout || "Saved.");
options.markReloadRequired?.("skills", { type: "skill", name: trimmed, action: "updated" });
}
await refreshSkills({ force: true });
} catch (error) {
- const message = error instanceof Error ? error.message : translate("skills.unknown_error");
+ const message = error instanceof Error ? error.message : t("skills.unknown_error");
options.setError(addOpencodeCacheHint(message));
} finally {
options.setBusy(false);
diff --git a/apps/app/src/react-app/domains/workspace/create-remote-workspace-modal.tsx b/apps/app/src/react-app/domains/workspace/create-remote-workspace-modal.tsx
index ff09f5c0b..5220e1ba9 100644
--- a/apps/app/src/react-app/domains/workspace/create-remote-workspace-modal.tsx
+++ b/apps/app/src/react-app/domains/workspace/create-remote-workspace-modal.tsx
@@ -2,7 +2,7 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { X } from "lucide-react";
-import { currentLocale, t } from "../../../i18n";
+import { t } from "../../../i18n";
import {
errorBannerClass,
modalBodyClass,
@@ -22,7 +22,6 @@ export function CreateRemoteWorkspaceModal(
props: CreateRemoteWorkspaceModalProps,
) {
const inputRef = useRef(null);
- const translate = (key: string) => t(key, currentLocale());
const [openworkHostUrl, setOpenworkHostUrl] = useState("");
const [openworkToken, setOpenworkToken] = useState("");
@@ -31,11 +30,11 @@ export function CreateRemoteWorkspaceModal(
const [displayName, setDisplayName] = useState("");
const showClose = props.showClose ?? true;
- const title = props.title ?? translate("dashboard.create_remote_workspace_title");
+ const title = props.title ?? t("dashboard.create_remote_workspace_title");
const subtitle =
- props.subtitle ?? translate("dashboard.create_remote_workspace_subtitle");
+ props.subtitle ?? t("dashboard.create_remote_workspace_subtitle");
const confirmLabel =
- props.confirmLabel ?? translate("dashboard.create_remote_workspace_confirm");
+ props.confirmLabel ?? t("dashboard.create_remote_workspace_confirm");
const isInline = props.inline ?? false;
const submitting = props.submitting ?? false;
@@ -116,7 +115,7 @@ export function CreateRemoteWorkspaceModal(
disabled={submitting}
className={pillGhostClass}
>
- {translate("common.cancel")}
+ {t("common.cancel")}
) : null}
string;
selectedFolder: string | null;
hasSelectedFolder: boolean;
pickingFolder: boolean;
@@ -91,27 +91,27 @@ export function CreateWorkspaceLocalPanel(
- {props.translate("welcome.folder_title")}
+ {t("welcome.folder_title")}
- {props.translate("welcome.folder_explanation")}
+ {t("welcome.folder_explanation")}
-
- {props.translate("welcome.folder_read")}
+ {t("welcome.folder_read")}
-
- {props.translate("welcome.folder_write")}
+ {t("welcome.folder_write")}
-
- {props.translate("welcome.folder_anything")}
+ {t("welcome.folder_anything")}
- {props.translate("welcome.folder_drop_hint")}
+ {t("welcome.folder_drop_hint")}
@@ -138,7 +138,7 @@ export function CreateWorkspaceLocalPanel(
)}
{props.hasSelectedFolder
- ? props.translate("dashboard.change")
+ ? t("dashboard.change")
: "Select folder"}
@@ -229,7 +229,7 @@ export function CreateWorkspaceLocalPanel(
props.workerDisabledReason ? (
- {props.translate("dashboard.sandbox_get_ready_title")}
+ {t("dashboard.sandbox_get_ready_title")}
{props.workerDisabledReason || props.workerCtaDescription}
@@ -286,7 +286,7 @@ export function CreateWorkspaceLocalPanel(
disabled={props.submitting}
className={pillGhostClass}
>
- {props.translate("common.cancel")}
+ {t("common.cancel")}
{props.onConfirmWorker ? (
- {props.translate("dashboard.sandbox_checking_docker")}
+ {t("dashboard.sandbox_checking_docker")}
) : (
(props.workerLabel ??
- props.translate("dashboard.create_sandbox_confirm"))
+ t("dashboard.create_sandbox_confirm"))
)}
) : null}
@@ -324,7 +324,7 @@ export function CreateWorkspaceLocalPanel(
disabled={!props.selectedFolder || props.submitting}
title={
!props.selectedFolder
- ? props.translate("dashboard.choose_folder_continue")
+ ? t("dashboard.choose_folder_continue")
: undefined
}
className={pillPrimaryClass}
@@ -336,7 +336,7 @@ export function CreateWorkspaceLocalPanel(
) : (
(props.confirmLabel ??
- props.translate("dashboard.create_workspace_confirm"))
+ t("dashboard.create_workspace_confirm"))
)}
diff --git a/apps/app/src/react-app/domains/workspace/create-workspace-modal.tsx b/apps/app/src/react-app/domains/workspace/create-workspace-modal.tsx
index 3ce8f2cdf..527e607b1 100644
--- a/apps/app/src/react-app/domains/workspace/create-workspace-modal.tsx
+++ b/apps/app/src/react-app/domains/workspace/create-workspace-modal.tsx
@@ -8,7 +8,7 @@ import {
} from "react";
import { ArrowLeft, Cloud, FolderPlus, Globe, Loader2, X } from "lucide-react";
-import { currentLocale, t } from "../../../i18n";
+import { t } from "../../../i18n";
import {
buildDenAuthUrl,
createDenClient,
@@ -42,35 +42,32 @@ import type {
RemoteWorkspaceInput,
} from "./types";
-function workerStatusMeta(
- status: string,
- translate: (key: string) => string,
-) {
+function workerStatusMeta(status: string) {
const normalized = status.trim().toLowerCase();
switch (normalized) {
case "healthy":
return {
- label: translate("dashboard.worker_status_ready"),
+ label: t("dashboard.worker_status_ready"),
tone: "ready" as const,
canOpen: true,
};
case "provisioning":
case "starting":
return {
- label: translate("dashboard.worker_status_starting"),
+ label: t("dashboard.worker_status_starting"),
tone: "warning" as const,
canOpen: false,
};
case "failed":
case "error":
return {
- label: translate("dashboard.worker_status_attention"),
+ label: t("dashboard.worker_status_attention"),
tone: "error" as const,
canOpen: false,
};
case "stopped":
return {
- label: translate("dashboard.worker_status_stopped"),
+ label: t("dashboard.worker_status_stopped"),
tone: "neutral" as const,
canOpen: false,
};
@@ -78,29 +75,21 @@ function workerStatusMeta(
return {
label: normalized
? `${normalized.slice(0, 1).toUpperCase()}${normalized.slice(1)}`
- : translate("common.unknown"),
+ : t("common.unknown"),
tone: "neutral" as const,
canOpen: normalized === "ready",
};
}
}
-function workerSecondaryLine(
- worker: DenWorkerSummary,
- translate: (key: string) => string,
-) {
- const parts = [worker.provider?.trim() || translate("dashboard.cloud_worker")];
+function workerSecondaryLine(worker: DenWorkerSummary) {
+ const parts = [worker.provider?.trim() || t("dashboard.cloud_worker")];
if (worker.instanceUrl?.trim()) parts.push(worker.instanceUrl.trim());
return parts.join(" · ");
}
export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
const remoteUrlRef = useRef
(null);
- const translate = useCallback(
- (key: string, params?: Record) =>
- t(key, currentLocale(), params),
- [],
- );
const platform = usePlatform();
const [screen, setScreen] = useState("chooser");
@@ -175,28 +164,28 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
const headerTitle = (() => {
switch (screen) {
case "local":
- return translate("dashboard.create_local_workspace_title");
+ return t("dashboard.create_local_workspace_title");
case "remote":
- return translate("dashboard.create_remote_custom_title");
+ return t("dashboard.create_remote_custom_title");
case "shared":
- return translate("dashboard.create_shared_title");
+ return t("dashboard.create_shared_title");
default:
- return props.title ?? translate("dashboard.create_workspace_title");
+ return props.title ?? t("dashboard.create_workspace_title");
}
})();
const headerSubtitle = (() => {
switch (screen) {
case "local":
- return translate("dashboard.create_local_workspace_subtitle");
+ return t("dashboard.create_local_workspace_subtitle");
case "remote":
- return translate("dashboard.create_remote_custom_subtitle");
+ return t("dashboard.create_remote_custom_subtitle");
case "shared":
return isSignedIn
- ? translate("dashboard.create_shared_subtitle_signed_in")
- : translate("dashboard.create_shared_subtitle_signed_out");
+ ? t("dashboard.create_shared_subtitle_signed_in")
+ : t("dashboard.create_shared_subtitle_signed_out");
default:
- return props.subtitle ?? translate("dashboard.create_workspace_subtitle");
+ return props.subtitle ?? t("dashboard.create_workspace_subtitle");
}
})();
@@ -288,7 +277,7 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
setOrgsError(
error instanceof Error
? error.message
- : translate("dashboard.error_load_orgs"),
+ : t("dashboard.error_load_orgs"),
);
} finally {
setOrgsBusy(false);
@@ -298,7 +287,6 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
cloudSettings.activeOrgId,
denClient,
isSignedIn,
- translate,
]);
const refreshWorkers = useCallback(
@@ -313,13 +301,13 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
setWorkersError(
error instanceof Error
? error.message
- : translate("dashboard.error_load_shared_workspaces"),
+ : t("dashboard.error_load_shared_workspaces"),
);
} finally {
setWorkersBusy(false);
}
},
- [activeOrgId, denClient, isSignedIn, translate],
+ [activeOrgId, denClient, isSignedIn],
);
// Load orgs/workers when the shared tab is active and signed in.
@@ -374,7 +362,7 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
if (!props.onConfirmRemote) return;
const orgId = activeOrgId.trim();
if (!orgId) {
- setWorkersError(translate("dashboard.error_choose_org"));
+ setWorkersError(t("dashboard.error_choose_org"));
return;
}
setOpeningWorkerId(worker.workerId);
@@ -385,7 +373,7 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
const accessToken =
tokens.ownerToken?.trim() || tokens.clientToken?.trim() || "";
if (!openworkUrl || !accessToken) {
- throw new Error(translate("dashboard.error_workspace_not_ready"));
+ throw new Error(t("dashboard.error_workspace_not_ready"));
}
const ok = await Promise.resolve(
props.onConfirmRemote({
@@ -400,7 +388,7 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
);
if (ok === false) {
throw new Error(
- translate("dashboard.error_connect_worker", {
+ t("dashboard.error_connect_worker", {
name: worker.workerName,
}),
);
@@ -409,7 +397,7 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
setWorkersError(
error instanceof Error
? error.message
- : translate("dashboard.error_connect_worker", {
+ : t("dashboard.error_connect_worker", {
name: worker.workerName,
}),
);
@@ -436,7 +424,7 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
onClick={() => setScreen("chooser")}
disabled={submitting || remoteSubmitting}
className={modalHeaderButtonClass}
- aria-label={translate("dashboard.modal_back")}
+ aria-label={t("dashboard.modal_back")}
>
@@ -452,7 +440,7 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
onClick={props.onClose}
disabled={submitting || remoteSubmitting}
className={modalHeaderButtonClass}
- aria-label={translate("dashboard.modal_close")}
+ aria-label={t("dashboard.modal_close")}
>
@@ -463,12 +451,12 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
setScreen("local")}
@@ -476,20 +464,20 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
endAdornment={
props.localDisabled ? (
- {translate("dashboard.desktop_badge")}
+ {t("dashboard.desktop_badge")}
) : undefined
}
/>
setScreen("remote")}
/>
setScreen("shared")}
/>
@@ -505,10 +493,10 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
{props.importingConfig ? (
- {translate("dashboard.importing")}
+ {t("dashboard.importing")}
) : (
- translate("dashboard.import_config")
+ t("dashboard.import_config")
)}
@@ -519,7 +507,6 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
{screen === "local" ? (
@@ -583,7 +570,7 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
onClick={props.onClose}
disabled={remoteSubmitting}
>
- {translate("common.cancel")}
+ {t("common.cancel")}
- {translate("dashboard.connecting")}
+ {t("dashboard.connecting")}
) : (
- translate("dashboard.connect_remote_button")
+ t("dashboard.connect_remote_button")
)}
@@ -623,8 +610,8 @@ export function CreateWorkspaceModal(props: CreateWorkspaceModalProps) {
onWorkerSearchInput={setWorkerSearch}
filteredWorkers={filteredWorkers}
openingWorkerId={openingWorkerId}
- workerStatusMeta={(status) => workerStatusMeta(status, translate)}
- workerSecondaryLine={(worker) => workerSecondaryLine(worker, translate)}
+ workerStatusMeta={(status) => workerStatusMeta(status)}
+ workerSecondaryLine={(worker) => workerSecondaryLine(worker)}
onOpenWorker={(worker) => void handleOpenWorker(worker)}
onOpenCloudSignIn={openCloudSignIn}
onRefreshWorkers={() => void refreshWorkers()}
diff --git a/apps/app/src/react-app/domains/workspace/rename-workspace-modal.tsx b/apps/app/src/react-app/domains/workspace/rename-workspace-modal.tsx
index 672b088dc..d7178aa47 100644
--- a/apps/app/src/react-app/domains/workspace/rename-workspace-modal.tsx
+++ b/apps/app/src/react-app/domains/workspace/rename-workspace-modal.tsx
@@ -2,7 +2,7 @@
import { useEffect, useRef } from "react";
import { X } from "lucide-react";
-import { currentLocale, t } from "../../../i18n";
+import { t } from "../../../i18n";
import { inputClass, pillGhostClass, pillPrimaryClass, pillSecondaryClass } from "./modal-styles";
export type RenameWorkspaceModalProps = {
@@ -17,7 +17,6 @@ export type RenameWorkspaceModalProps = {
export function RenameWorkspaceModal(props: RenameWorkspaceModalProps) {
const inputRef = useRef(null);
- const translate = (key: string) => t(key, currentLocale());
useEffect(() => {
if (!props.open) return;
@@ -37,10 +36,10 @@ export function RenameWorkspaceModal(props: RenameWorkspaceModalProps) {
@@ -83,7 +82,7 @@ export function RenameWorkspaceModal(props: RenameWorkspaceModalProps) {
onClick={props.onClose}
disabled={props.busy}
>
- {translate("common.cancel")}
+ {t("common.cancel")}
- {translate("common.save")}
+ {t("common.save")}
diff --git a/apps/app/src/react-app/kernel/global-sync-provider.tsx b/apps/app/src/react-app/kernel/global-sync-provider.tsx
index 8f2516e43..c6dff22ed 100644
--- a/apps/app/src/react-app/kernel/global-sync-provider.tsx
+++ b/apps/app/src/react-app/kernel/global-sync-provider.tsx
@@ -24,7 +24,7 @@ import type {
VcsInfo,
} from "@opencode-ai/sdk/v2/client";
-import { currentLocale, t } from "../../i18n";
+import { t } from "../../i18n";
import { unwrap } from "../../app/lib/opencode";
import type { McpStatusMap, TodoItem } from "../../app/types";
import { safeStringify } from "../../app/utils";
@@ -134,7 +134,7 @@ export function GlobalSyncProvider({ children }: GlobalSyncProviderProps) {
error instanceof Error ? error.message : safeStringify(error);
setState((previous) => ({
...previous,
- error: message || t("app.unknown_error", currentLocale()),
+ error: message || t("app.unknown_error"),
}));
}, []);
diff --git a/apps/app/src/react-app/shell/settings-route.tsx b/apps/app/src/react-app/shell/settings-route.tsx
index 122a36aec..418a2683a 100644
--- a/apps/app/src/react-app/shell/settings-route.tsx
+++ b/apps/app/src/react-app/shell/settings-route.tsx
@@ -1410,7 +1410,6 @@ export function SettingsRoute() {
0}
activeSessions={activeReloadBlockingSessions}
isRemoteWorkspace={selectedWorkspace?.workspaceType === "remote"}
diff --git a/scripts/i18n-audit.mjs b/scripts/i18n-audit.mjs
index 2d7ec2859..f73fddc39 100644
--- a/scripts/i18n-audit.mjs
+++ b/scripts/i18n-audit.mjs
@@ -3,7 +3,7 @@
* i18n-audit.mjs — Find missing translations and improperly used translation keys.
*
* Usage:
- * node scripts/i18n-audit.mjs # full audit (default, excludes --hardcoded, --aliases, --prune, --sort)
+ * node scripts/i18n-audit.mjs # full audit (default, excludes --hardcoded, --prune, --sort)
* node scripts/i18n-audit.mjs --missing # missing keys (in EN but not in locale)
* node scripts/i18n-audit.mjs --orphan # orphan keys (in locale but not in EN)
* node scripts/i18n-audit.mjs --duplicates # duplicate keys in any locale
@@ -29,7 +29,7 @@ const LOCALES = ["ja", "zh", "vi", "pt-BR", "th", "fr", "ca", "es"];
const EN_FILE = join(LOCALES_DIR, "en.ts");
const mode = process.argv[2] ?? "--all";
-const EXCLUDED_FROM_ALL = new Set(["--hardcoded", "--aliases"]);
+const EXCLUDED_FROM_ALL = new Set(["--hardcoded"]);
const shouldRun = (...modes) => (mode === "--all" && !modes.some((m) => EXCLUDED_FROM_ALL.has(m))) || modes.includes(mode);
// ---------------------------------------------------------------------------
From 116ddc8c0ed5615e1650f168688e6dcbdf07cd9a Mon Sep 17 00:00:00 2001
From: johnnyshields <27655+johnnyshields@users.noreply.github.com>
Date: Mon, 4 May 2026 22:26:41 +0900
Subject: [PATCH 4/5] Collapse single-key t() calls onto one line
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The translate() → t() rename left multi-line wrappers around short string
literals. Re-flow them since the longer translate() name is gone.
---
.../domains/bundles/skill-destination-modal.tsx | 16 ++++------------
1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/apps/app/src/react-app/domains/bundles/skill-destination-modal.tsx b/apps/app/src/react-app/domains/bundles/skill-destination-modal.tsx
index 869c0d488..9a721314e 100644
--- a/apps/app/src/react-app/domains/bundles/skill-destination-modal.tsx
+++ b/apps/app/src/react-app/domains/bundles/skill-destination-modal.tsx
@@ -247,9 +247,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
{isSelected ? (
- {t(
- "share_skill_destination.selected_badge",
- )}
+ {t("share_skill_destination.selected_badge")}
) : null}
@@ -259,9 +257,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
{isSelected ? (
- {t(
- "share_skill_destination.selected_hint",
- )}
+ {t("share_skill_destination.selected_hint")}
) : null}
@@ -310,9 +306,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
{t("share_skill_destination.create_worker")}
- {t(
- "share_skill_destination.create_worker_hint",
- )}
+ {t("share_skill_destination.create_worker_hint")}
@@ -337,9 +331,7 @@ export function SkillDestinationModal(props: SkillDestinationModalProps) {
{t("share_skill_destination.connect_remote")}
- {t(
- "share_skill_destination.connect_remote_hint",
- )}
+ {t("share_skill_destination.connect_remote_hint")}
From f8f7a05ab930c67042c63b5a0ef629e342c9974c Mon Sep 17 00:00:00 2001
From: johnnyshields <27655+johnnyshields@users.noreply.github.com>
Date: Tue, 5 May 2026 04:58:07 +0900
Subject: [PATCH 5/5] Fix useTranslate hook for new t() signature
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Dev's redesign reintroduced tr/tx wrappers via a centralized useTranslate
hook, but the hook calls t(key, currentLocale(), params) — the old
3-argument signature. The current 2-argument t(key, params) silently
drops the third arg, so every tx() call would lose its substitutions
(e.g. {name}/{count} placeholders never get replaced).
Drop currentLocale() — t() uses the current locale by default — and pass
params straight through.
---
apps/app/src/hooks/use-translate.ts | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/apps/app/src/hooks/use-translate.ts b/apps/app/src/hooks/use-translate.ts
index 311872ab4..502ba7ffb 100644
--- a/apps/app/src/hooks/use-translate.ts
+++ b/apps/app/src/hooks/use-translate.ts
@@ -1,11 +1,10 @@
import * as React from "react";
-import { currentLocale, t } from "@/i18n";
+import { t } from "@/i18n";
export function useTranslate() {
- const tr = React.useCallback((key: string) => t(key, currentLocale()), []);
+ const tr = React.useCallback((key: string) => t(key), []);
const tx = React.useCallback(
- (key: string, params?: Record) =>
- t(key, currentLocale(), params),
+ (key: string, params?: Record) => t(key, params),
[],
);