@@ -2088,7 +2127,7 @@ export default function Layout(props: ParentProps) {
<>
@@ -2129,9 +2168,9 @@ export default function Layout(props: ParentProps) {
-
Getting started
-
OpenCode includes free models so you can start immediately.
-
Connect any provider to use models, inc. Claude, GPT, Gemini etc.
+
{language.t("sidebar.gettingStarted")}
+
{language.t("sidebar.gettingStartedDesc1")}
+
{language.t("sidebar.gettingStartedDesc2")}
- Connect provider
+ {language.t("provider.connect")}
diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx
index 89d3ec77334..4dd75cdeae0 100644
--- a/packages/app/src/pages/session.tsx
+++ b/packages/app/src/pages/session.tsx
@@ -38,6 +38,7 @@ import { UserMessage } from "@opencode-ai/sdk/v2"
import type { FileDiff } from "@opencode-ai/sdk/v2/client"
import { useSDK } from "@/context/sdk"
import { usePrompt } from "@/context/prompt"
+import { useLanguage } from "@/context/language"
import { extractPromptFromParts } from "@/utils/prompt"
import { ConstrainDragYAxis, getDraggableId } from "@/utils/solid-dnd"
import { usePermission } from "@/context/permission"
@@ -162,6 +163,7 @@ export default function Page() {
const codeComponent = useCodeComponent()
const command = useCommand()
const platform = usePlatform()
+ const language = useLanguage()
const params = useParams()
const navigate = useNavigate()
const sdk = useSDK()
@@ -419,51 +421,51 @@ export default function Page() {
command.register(() => [
{
id: "session.new",
- title: "New session",
- category: "Session",
+ title: language.t("session.new"),
+ category: language.t("command.category.session"),
keybind: "mod+shift+s",
slash: "new",
onSelect: () => navigate(`/${params.dir}/session`),
},
{
id: "file.open",
- title: "Open file",
- description: "Search files and commands",
- category: "File",
+ title: language.t("command.title.openFile"),
+ description: language.t("command.description.openFile"),
+ category: language.t("command.category.file"),
keybind: "mod+p",
slash: "open",
onSelect: () => dialog.show(() =>
),
},
{
id: "terminal.toggle",
- title: "Toggle terminal",
+ title: language.t("terminal.toggle"),
description: "",
- category: "View",
+ category: language.t("command.category.view"),
keybind: "ctrl+`",
slash: "terminal",
onSelect: () => view().terminal.toggle(),
},
{
id: "review.toggle",
- title: "Toggle review",
+ title: language.t("review.toggle"),
description: "",
- category: "View",
+ category: language.t("command.category.view"),
keybind: "mod+shift+r",
onSelect: () => view().reviewPanel.toggle(),
},
{
id: "terminal.new",
- title: "New terminal",
- description: "Create a new terminal tab",
- category: "Terminal",
+ title: language.t("terminal.new"),
+ description: language.t("command.description.newTerminal"),
+ category: language.t("command.category.terminal"),
keybind: "ctrl+shift+`",
onSelect: () => terminal.new(),
},
{
id: "steps.toggle",
- title: "Toggle steps",
- description: "Show or hide steps for the current message",
- category: "View",
+ title: language.t("command.title.toggleSteps"),
+ description: language.t("command.description.toggleSteps"),
+ category: language.t("command.category.view"),
keybind: "mod+e",
slash: "steps",
disabled: !params.id,
@@ -475,62 +477,62 @@ export default function Page() {
},
{
id: "message.previous",
- title: "Previous message",
- description: "Go to the previous user message",
- category: "Session",
+ title: language.t("command.title.previousMessage"),
+ description: language.t("command.description.previousMessage"),
+ category: language.t("command.category.session"),
keybind: "mod+arrowup",
disabled: !params.id,
onSelect: () => navigateMessageByOffset(-1),
},
{
id: "message.next",
- title: "Next message",
- description: "Go to the next user message",
- category: "Session",
+ title: language.t("command.title.nextMessage"),
+ description: language.t("command.description.nextMessage"),
+ category: language.t("command.category.session"),
keybind: "mod+arrowdown",
disabled: !params.id,
onSelect: () => navigateMessageByOffset(1),
},
{
id: "model.choose",
- title: "Choose model",
- description: "Select a different model",
- category: "Model",
+ title: language.t("command.title.chooseModel"),
+ description: language.t("command.description.chooseModel"),
+ category: language.t("command.category.model"),
keybind: "mod+'",
slash: "model",
onSelect: () => dialog.show(() =>
),
},
{
id: "mcp.toggle",
- title: "Toggle MCPs",
- description: "Toggle MCPs",
- category: "MCP",
+ title: language.t("command.title.toggleMcp"),
+ description: language.t("command.description.toggleMcp"),
+ category: language.t("command.category.mcp"),
keybind: "mod+;",
slash: "mcp",
onSelect: () => dialog.show(() =>
),
},
{
id: "agent.cycle",
- title: "Cycle agent",
- description: "Switch to the next agent",
- category: "Agent",
+ title: language.t("command.title.cycleAgent"),
+ description: language.t("command.description.cycleAgent"),
+ category: language.t("command.category.agent"),
keybind: "mod+.",
slash: "agent",
onSelect: () => local.agent.move(1),
},
{
id: "agent.cycle.reverse",
- title: "Cycle agent backwards",
- description: "Switch to the previous agent",
- category: "Agent",
+ title: language.t("command.title.cycleAgentBack"),
+ description: language.t("command.description.cycleAgentBack"),
+ category: language.t("command.category.agent"),
keybind: "shift+mod+.",
onSelect: () => local.agent.move(-1),
},
{
id: "model.variant.cycle",
- title: "Cycle thinking effort",
- description: "Switch to the next effort level",
- category: "Model",
+ title: language.t("command.title.cycleThinking"),
+ description: language.t("command.description.cycleThinking"),
+ category: language.t("command.category.model"),
keybind: "shift+mod+d",
onSelect: () => {
local.model.variant.cycle()
@@ -540,9 +542,9 @@ export default function Page() {
id: "permissions.autoaccept",
title:
params.id && permission.isAutoAccepting(params.id, sdk.directory)
- ? "Stop auto-accepting edits"
- : "Auto-accept edits",
- category: "Permissions",
+ ? language.t("command.title.stopAutoAcceptEdits")
+ : language.t("command.title.autoAcceptEdits"),
+ category: language.t("command.category.permissions"),
keybind: "mod+shift+a",
disabled: !params.id || !permission.permissionsEnabled(),
onSelect: () => {
@@ -551,19 +553,19 @@ export default function Page() {
permission.toggleAutoAccept(sessionID, sdk.directory)
showToast({
title: permission.isAutoAccepting(sessionID, sdk.directory)
- ? "Auto-accepting edits"
- : "Stopped auto-accepting edits",
+ ? language.t("command.toast.autoAcceptOnTitle")
+ : language.t("command.toast.autoAcceptOffTitle"),
description: permission.isAutoAccepting(sessionID, sdk.directory)
- ? "Edit and write permissions will be automatically approved"
- : "Edit and write permissions will require approval",
+ ? language.t("command.toast.autoAcceptOnDescription")
+ : language.t("command.toast.autoAcceptOffDescription"),
})
},
},
{
id: "session.undo",
- title: "Undo",
- description: "Undo the last message",
- category: "Session",
+ title: language.t("command.title.undo"),
+ description: language.t("command.description.undo"),
+ category: language.t("command.category.session"),
slash: "undo",
disabled: !params.id || visibleUserMessages().length === 0,
onSelect: async () => {
@@ -590,9 +592,9 @@ export default function Page() {
},
{
id: "session.redo",
- title: "Redo",
- description: "Redo the last undone message",
- category: "Session",
+ title: language.t("command.title.redo"),
+ description: language.t("command.description.redo"),
+ category: language.t("command.category.session"),
slash: "redo",
disabled: !params.id || !info()?.revert?.messageID,
onSelect: async () => {
@@ -619,9 +621,9 @@ export default function Page() {
},
{
id: "session.compact",
- title: "Compact session",
- description: "Summarize the session to reduce context size",
- category: "Session",
+ title: language.t("command.title.compactSession"),
+ description: language.t("command.description.compactSession"),
+ category: language.t("command.category.session"),
slash: "compact",
disabled: !params.id || visibleUserMessages().length === 0,
onSelect: async () => {
@@ -630,8 +632,8 @@ export default function Page() {
const model = local.model.current()
if (!model) {
showToast({
- title: "No model selected",
- description: "Connect a provider to summarize this session",
+ title: language.t("command.toast.noModelTitle"),
+ description: language.t("command.toast.noModelDescription"),
})
return
}
@@ -644,9 +646,9 @@ export default function Page() {
},
{
id: "session.fork",
- title: "Fork from message",
- description: "Create a new session from a previous message",
- category: "Session",
+ title: language.t("command.title.forkFromMessage"),
+ description: language.t("command.description.forkFromMessage"),
+ category: language.t("command.category.session"),
slash: "fork",
disabled: !params.id || visibleUserMessages().length === 0,
onSelect: () => dialog.show(() =>
),
@@ -655,9 +657,9 @@ export default function Page() {
? [
{
id: "session.share",
- title: "Share session",
- description: "Share this session and copy the URL to clipboard",
- category: "Session",
+ title: language.t("session.shareCommandTitle"),
+ description: language.t("session.shareCommandDescription"),
+ category: language.t("command.category.session"),
slash: "share",
disabled: !params.id || !!info()?.share?.url,
onSelect: async () => {
@@ -667,22 +669,22 @@ export default function Page() {
.then((res) => {
navigator.clipboard.writeText(res.data!.share!.url).catch(() =>
showToast({
- title: "Failed to copy URL to clipboard",
+ title: language.t("session.shareCopyFailedTitle"),
variant: "error",
}),
)
})
.then(() =>
showToast({
- title: "Session shared",
- description: "Share URL copied to clipboard!",
+ title: language.t("session.shareSuccessTitle"),
+ description: language.t("session.shareSuccessDescription"),
variant: "success",
}),
)
.catch(() =>
showToast({
- title: "Failed to share session",
- description: "An error occurred while sharing the session",
+ title: language.t("session.shareFailedTitle"),
+ description: language.t("session.shareFailedDescription"),
variant: "error",
}),
)
@@ -690,9 +692,9 @@ export default function Page() {
},
{
id: "session.unshare",
- title: "Unshare session",
- description: "Stop sharing this session",
- category: "Session",
+ title: language.t("session.unshareCommandTitle"),
+ description: language.t("session.unshareCommandDescription"),
+ category: language.t("command.category.session"),
slash: "unshare",
disabled: !params.id || !info()?.share?.url,
onSelect: async () => {
@@ -701,15 +703,15 @@ export default function Page() {
.unshare({ sessionID: params.id })
.then(() =>
showToast({
- title: "Session unshared",
- description: "Session unshared successfully!",
+ title: language.t("session.unshareSuccessTitle"),
+ description: language.t("session.unshareSuccessDescription"),
variant: "success",
}),
)
.catch(() =>
showToast({
- title: "Failed to unshare session",
- description: "An error occurred while unsharing the session",
+ title: language.t("session.unshareFailedTitle"),
+ description: language.t("session.unshareFailedDescription"),
variant: "error",
}),
)
@@ -1200,7 +1202,7 @@ export default function Page() {
classes={{ button: "w-full" }}
onClick={() => setStore("mobileTab", "session")}
>
- Session
+ {language.t("session.tab")}
setStore("mobileTab", "review")}
>
- {reviewCount()} Files Changed
+ {language.t("session.filesChangedLabel", { count: reviewCount() })}
Review
@@ -1240,7 +1242,7 @@ export default function Page() {
Loading changes...