Compare commits

...
19 Commits
Author SHA1 Message Date
f0afb6750e fix(server): log upstream 5xx bodies from proxied workspace requests (#40135)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-04 09:43:59 -04:00
703d09f306 fix(server): don't forward host directory to remote workspace (#40136)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-04 09:43:45 -04:00
opencode aefaf140c1 sync release versions for v1.18.13 2026-08-04 12:12:30 +00:00
Shoubhit DashandGitHub 44614c79c4 fix(acp): drain updates before end turn (#40422) 2026-08-04 17:26:33 +05:30
Amy DuquetteandGitHub dc67b7a3be docs: add Poolside provider setup (#39187) 2026-08-04 06:43:54 -05:00
Luke ParkerandGitHub de1bd36a47 fix(app): correct RTL layout interactions (#40410) 2026-08-04 11:39:32 +00:00
opencode-agent[bot]andGitHub 6c97a46dae fix(stats): hide zero-usage countries (#40400) 2026-08-04 06:26:48 -05:00
Luke ParkerandGitHub c387fe190b feat(app): add debug layout direction toggle (#40393) 2026-08-04 08:52:37 +00:00
8721a2710b fix(app): complete shared RTL primitives (#40388)
Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com>
2026-08-04 07:38:56 +00:00
Brendan AllanandGitHub c75e3b5bae fix(app): supply fallback session titles (#40385) 2026-08-04 15:09:29 +08:00
opencode-agent[bot] edc8d1d91e chore: generate 2026-08-04 06:57:27 +00:00
e85735028c feat(i18n): localize hardcoded application copy (#40377)
Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com>
2026-08-04 16:56:03 +10:00
6c3299103c feat(app): add minimal RTL support (#40372)
Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com>
2026-08-04 05:08:51 +00:00
opencode-agent[bot] 60e23fee16 chore: generate 2026-08-04 04:38:17 +00:00
0c380f31ac feat(app): support locale plural rules (#40370)
Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com>
2026-08-04 04:36:57 +00:00
opencode-agent[bot] 26aefa68f5 chore: update nix node_modules hashes 2026-08-04 04:30:14 +00:00
Luke ParkerandGitHub 638788f8d0 fix(app): move markdown parsing to worker (#40356) 2026-08-04 04:13:34 +00:00
opencode-agent[bot] b005a15a4a chore: generate 2026-08-04 03:58:49 +00:00
0efa33cf33 feat(desktop): expand and audit locale translations (#40362)
Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com>
2026-08-04 03:57:33 +00:00
253 changed files with 21122 additions and 2815 deletions
+30 -37
View File
@@ -29,7 +29,7 @@
},
"packages/app": {
"name": "@opencode-ai/app",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@corvu/drawer": "catalog:",
"@dnd-kit/abstract": "0.5.0",
@@ -96,7 +96,7 @@
},
"packages/cli": {
"name": "@opencode-ai/cli",
"version": "1.18.12",
"version": "1.18.13",
"bin": {
"lildax": "./bin/lildax.cjs",
},
@@ -144,7 +144,7 @@
},
"packages/codemode": {
"name": "@opencode-ai/codemode",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"acorn": "8.15.0",
"effect": "catalog:",
@@ -158,7 +158,7 @@
},
"packages/console/app": {
"name": "@opencode-ai/console-app",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@cloudflare/vite-plugin": "1.15.2",
"@ibm/plex": "6.4.1",
@@ -194,7 +194,7 @@
},
"packages/console/core": {
"name": "@opencode-ai/console-core",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@aws-sdk/client-sts": "3.782.0",
"@jsx-email/render": "1.1.1",
@@ -221,7 +221,7 @@
},
"packages/console/function": {
"name": "@opencode-ai/console-function",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@ai-sdk/anthropic": "3.0.82",
"@ai-sdk/openai": "3.0.48",
@@ -243,7 +243,7 @@
},
"packages/console/mail": {
"name": "@opencode-ai/console-mail",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@jsx-email/all": "2.2.3",
"@jsx-email/cli": "1.4.3",
@@ -267,7 +267,7 @@
},
"packages/console/support": {
"name": "@opencode-ai/console-support",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@cloudflare/vite-plugin": "1.15.2",
"@opencode-ai/console-core": "workspace:*",
@@ -287,7 +287,7 @@
},
"packages/core": {
"name": "@opencode-ai/core",
"version": "1.18.12",
"version": "1.18.13",
"bin": {
"opencode": "./bin/opencode",
},
@@ -381,7 +381,7 @@
},
"packages/desktop": {
"name": "@opencode-ai/desktop",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@zip.js/zip.js": "2.7.62",
"drizzle-orm": "catalog:",
@@ -435,7 +435,7 @@
},
"packages/effect-drizzle-sqlite": {
"name": "@opencode-ai/effect-drizzle-sqlite",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"drizzle-orm": "catalog:",
"effect": "catalog:",
@@ -449,7 +449,7 @@
},
"packages/effect-sqlite-node": {
"name": "@opencode-ai/effect-sqlite-node",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"effect": "catalog:",
},
@@ -461,7 +461,7 @@
},
"packages/enterprise": {
"name": "@opencode-ai/enterprise",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@hono/standard-validator": "catalog:",
"@opencode-ai/core": "workspace:*",
@@ -493,7 +493,7 @@
},
"packages/function": {
"name": "@opencode-ai/function",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@octokit/auth-app": "8.0.1",
"@octokit/rest": "catalog:",
@@ -509,7 +509,7 @@
},
"packages/http-recorder": {
"name": "@opencode-ai/http-recorder",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@effect/platform-node": "4.0.0-beta.83",
"@effect/platform-node-shared": "4.0.0-beta.83",
@@ -540,7 +540,7 @@
},
"packages/llm": {
"name": "@opencode-ai/llm",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@opencode-ai/schema": "workspace:*",
"@smithy/eventstream-codec": "4.2.14",
@@ -559,7 +559,7 @@
},
"packages/opencode": {
"name": "opencode",
"version": "1.18.12",
"version": "1.18.13",
"bin": {
"opencode": "./bin/opencode",
},
@@ -690,7 +690,7 @@
},
"packages/plugin": {
"name": "@opencode-ai/plugin",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@ai-sdk/provider": "3.0.8",
"@opencode-ai/sdk": "workspace:*",
@@ -766,7 +766,7 @@
},
"packages/sdk/js": {
"name": "@opencode-ai/sdk",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"cross-spawn": "catalog:",
},
@@ -781,7 +781,7 @@
},
"packages/server": {
"name": "@opencode-ai/server",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@opencode-ai/core": "workspace:*",
"@opencode-ai/protocol": "workspace:*",
@@ -796,7 +796,7 @@
},
"packages/session-ui": {
"name": "@opencode-ai/session-ui",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@kobalte/core": "catalog:",
"@opencode-ai/client": "file:../app/vendor/opencode-ai-client-1.17.13-v2.tgz",
@@ -814,11 +814,8 @@
"diff": "catalog:",
"dompurify": "3.3.1",
"fuzzysort": "catalog:",
"katex": "0.16.27",
"luxon": "catalog:",
"marked": "catalog:",
"marked-katex-extension": "5.1.6",
"marked-shiki": "catalog:",
"morphdom": "2.7.8",
"motion": "12.34.5",
"remeda": "catalog:",
@@ -831,7 +828,6 @@
"devDependencies": {
"@tsconfig/node22": "catalog:",
"@types/bun": "catalog:",
"@types/katex": "0.16.7",
"@types/luxon": "catalog:",
"@typescript/native-preview": "catalog:",
"typescript": "catalog:",
@@ -840,7 +836,7 @@
},
"packages/slack": {
"name": "@opencode-ai/slack",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@opencode-ai/sdk": "workspace:*",
"@slack/bolt": "^3.17.1",
@@ -853,7 +849,7 @@
},
"packages/stats/app": {
"name": "@opencode-ai/stats-app",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@ibm/plex": "6.4.1",
"@kobalte/core": "catalog:",
@@ -887,7 +883,7 @@
},
"packages/stats/core": {
"name": "@opencode-ai/stats-core",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@aws-sdk/client-athena": "3.933.0",
"@planetscale/database": "1.19.0",
@@ -906,7 +902,7 @@
},
"packages/stats/server": {
"name": "@opencode-ai/stats-server",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@aws-sdk/client-firehose": "3.933.0",
"@effect/platform-node": "catalog:",
@@ -948,7 +944,7 @@
},
"packages/tui": {
"name": "@opencode-ai/tui",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@opencode-ai/core": "workspace:*",
"@opencode-ai/plugin": "workspace:*",
@@ -975,7 +971,7 @@
},
"packages/ui": {
"name": "@opencode-ai/ui",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@kobalte/core": "catalog:",
"@pierre/diffs": "catalog:",
@@ -991,7 +987,6 @@
"katex": "0.16.27",
"luxon": "catalog:",
"marked": "catalog:",
"marked-katex-extension": "5.1.6",
"marked-shiki": "catalog:",
"morphdom": "2.7.8",
"motion": "12.34.5",
@@ -1027,7 +1022,7 @@
},
"packages/web": {
"name": "@opencode-ai/web",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@astrojs/cloudflare": "12.6.3",
"@astrojs/markdown-remark": "6.3.1",
@@ -1137,7 +1132,7 @@
"hono": "4.10.7",
"hono-openapi": "1.1.2",
"luxon": "3.6.1",
"marked": "17.0.6",
"marked": "18.0.7",
"marked-shiki": "1.2.1",
"opentui-spinner": "0.0.7",
"remeda": "2.26.0",
@@ -4318,9 +4313,7 @@
"markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="],
"marked": ["marked@17.0.6", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-gB0gkNafnonOw0obSTEGZTT86IuhILt2Wfx0mWH/1Au83kybTayroZ/V6nS25mN7u8ASy+5fMhgB3XPNrOZdmA=="],
"marked-katex-extension": ["marked-katex-extension@5.1.6", "", { "peerDependencies": { "katex": ">=0.16 <0.17", "marked": ">=4 <18" } }, "sha512-vYpLXwmlIDKILIhJtiRTgdyZRn5sEYdFBuTmbpjD7lbCIzg0/DWyK3HXIntN3Tp8zV6hvOUgpZNLWRCgWVc24A=="],
"marked": ["marked@18.0.7", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-iDVQ5ldaiKXn6b2JroX5kgRfmwgqolW7NpaEzTl1k/2Zh1njIEN9yniyLV/mOvWwtsE8OGgkjsCYvijuPk1dtA=="],
"marked-shiki": ["marked-shiki@1.2.1", "", { "peerDependencies": { "marked": ">=7.0.0", "shiki": ">=1.0.0" } }, "sha512-yHxYQhPY5oYaIRnROn98foKhuClark7M373/VpLxiy5TrDu9Jd/LsMwo8w+U91Up4oDb9IXFrP0N1MFRz8W/DQ=="],
+4 -4
View File
@@ -1,8 +1,8 @@
{
"nodeModules": {
"x86_64-linux": "sha256-a7NyYa9vRUEqDfZNDPXXmFO58RDEgioyuGSl5CPBvxo=",
"aarch64-linux": "sha256-l4OJtSEllHvRhktjcaJYwkXBSaJvsIoyoLusbZfYMcM=",
"aarch64-darwin": "sha256-IIl0BQGs1/HLFh0auiQjiwfSQ2nfHcK2G2BAphYW59c=",
"x86_64-darwin": "sha256-vVeuPyd4ZIRYrHouphTuEb4rkRZLKKTAHe840jNh9rU="
"x86_64-linux": "sha256-GRjnvvyj37H36RqiCB7dz5ALAEwvw16izwuk1wsHEpU=",
"aarch64-linux": "sha256-0OIn1o6dpqIQ5XgIMzpenMCMqsYzraaYVJk+te5eINU=",
"aarch64-darwin": "sha256-sQSQcuox78d8wT1lsKYHqVBl11NusiszQ+gu2XYXZi8=",
"x86_64-darwin": "sha256-SINkhMRd4oM1zABSs1Uf3OAzxJ1lgcycl1U4fmi+baY="
}
}
+1 -1
View File
@@ -70,7 +70,7 @@
"hono-openapi": "1.1.2",
"fuzzysort": "3.1.0",
"luxon": "3.6.1",
"marked": "17.0.6",
"marked": "18.0.7",
"marked-shiki": "1.2.1",
"remend": "1.3.0",
"@playwright/test": "1.59.1",
+8
View File
@@ -19,6 +19,14 @@
- Always prefer `createStore` over multiple `createSignal` calls
## Localization
- NEVER hardcode user-visible English strings in production code. ALWAYS use an i18n key for visible copy, placeholders, accessible labels, tooltips, menus, dialogs, toasts, empty states, and displayed errors.
- When migrating existing copy to i18n, preserve the English text byte-for-byte unless the task explicitly requests a copy change.
- NEVER change existing English text or English keys to facilitate translation. English is intentional, designer-written source copy; adapt locale-specific translations and i18n mechanics around it.
- Do not translate from model knowledge alone. Verify terminology and grammar with Unicode CLDR locale/plural data, Microsoft Localization Style Guides and terminology, Apple localization/style guidance and localized platform UI, Mozilla localization style guides, Mozilla Pontoon, and the Firefox localization corpus at `github.com/mozilla-l10n/firefox-l10n`.
- Also use the relevant language authority or official dictionary for the locale (for example RAE/Fundéu, FranceTerme, Duden, TDK, Kotus/Kielitoimiston sanakirja, Språkrådet/Bokmålsordboka, Rada Języka Polskiego/PWN, the Russian and Arabic language academies, the Ukrainian Orthography, Taiwan MOE dictionaries, or the Royal Society of Thailand). Treat the English dictionary as the semantic source of truth and preserve placeholders, code identifiers, product names, and keyboard labels.
## Tool Calling
- ALWAYS USE PARALLEL TOOLS WHEN APPLICABLE.
@@ -2,7 +2,7 @@ import { expect, test } from "@playwright/test"
import { assistantMessage, setupTimeline, toolPart, userMessage } from "../performance/timeline-stability/fixture"
for (const profile of [
{ locale: "de", label: "Erkundet" },
{ locale: "de", label: "Erkundung abgeschlossen" },
{ locale: "ar", label: "تم الاستكشاف" },
] as const) {
test(`projects translated context status in ${profile.locale}`, async ({ page }) => {
+2 -1
View File
@@ -1,11 +1,12 @@
{
"name": "@opencode-ai/app",
"version": "1.18.12",
"version": "1.18.13",
"description": "",
"type": "module",
"exports": {
".": "./src/index.ts",
"./desktop-menu": "./src/desktop-menu.ts",
"./i18n/desktop-native": "./src/i18n/desktop-native.ts",
"./updater": "./src/updater.ts",
"./wsl/types": "./src/wsl/types.ts",
"./vite": "./vite.js",
+16 -8
View File
@@ -3,7 +3,6 @@ import * as Sentry from "@sentry/solid"
import { I18nProvider } from "@opencode-ai/ui/context"
import { DialogProvider } from "@opencode-ai/ui/context/dialog"
import { FileComponentProvider } from "@opencode-ai/ui/context/file"
import { MarkedProvider } from "@opencode-ai/ui/context/marked"
import { File } from "@opencode-ai/session-ui/file"
import { Font } from "@opencode-ai/ui/font"
import { Splash } from "@opencode-ai/ui/logo"
@@ -234,7 +233,13 @@ function ResolvedDraftRoute(props: { draft: DraftTab }) {
function UiI18nBridge(props: ParentProps) {
const language = useLanguage()
return <I18nProvider value={{ locale: language.intl, t: language.t }}>{props.children}</I18nProvider>
return (
<I18nProvider
value={{ locale: language.intl, layoutLocale: language.layoutLocale, t: language.t, plural: language.plural }}
>
{props.children}
</I18nProvider>
)
}
function LayoutCompatibility(props: ParentProps) {
@@ -327,7 +332,7 @@ function DesktopCommands() {
if (platform.platform === "desktop" && platform.exportDebugLogs) {
commands.push({
id: "logs.export",
title: "Export logs",
title: language.t("command.logs.export"),
category: language.t("command.category.settings"),
onSelect: () => {
void platform.exportDebugLogs?.()
@@ -385,7 +390,12 @@ function DraftProviders(props: ParentProps) {
)
}
export function AppBaseProviders(props: ParentProps<{ locale?: Locale }>) {
export function AppBaseProviders(
props: ParentProps<{
locale?: Locale
onNativeTranslations?: Parameters<typeof LanguageProvider>[0]["onNativeTranslations"]
}>,
) {
return (
<MetaProvider>
<Font />
@@ -394,7 +404,7 @@ export function AppBaseProviders(props: ParentProps<{ locale?: Locale }>) {
void window.api?.setTitlebar?.({ mode, scheme })
}}
>
<LanguageProvider locale={props.locale}>
<LanguageProvider locale={props.locale} onNativeTranslations={props.onNativeTranslations}>
<UiI18nBridge>
<ErrorBoundary
fallback={(error) => {
@@ -405,9 +415,7 @@ export function AppBaseProviders(props: ParentProps<{ locale?: Locale }>) {
<QueryProvider>
<WslServersProvider>
<DialogProvider>
<MarkedProvider>
<FileComponentProvider component={File}>{props.children}</FileComponentProvider>
</MarkedProvider>
<FileComponentProvider component={File}>{props.children}</FileComponentProvider>
</DialogProvider>
</WslServersProvider>
</QueryProvider>
+34 -15
View File
@@ -60,7 +60,7 @@ function Cell(props: {
label: string
tip: string
value: string
wide?: boolean
span?: 2 | 3
}) {
const content = () => (
<div
@@ -69,7 +69,8 @@ function Cell(props: {
"min-h-[20px] w-fit justify-start px-1.5 py-0.5 text-left": !!props.inline,
"justify-center text-center": !props.inline,
"min-h-[42px] w-full flex-col rounded-[8px] px-0.5 py-1": !props.inline,
"col-span-2": !!props.wide && !props.inline,
"col-span-2": props.span === 2 && !props.inline,
"col-span-3": props.span === 3 && !props.inline,
}}
>
<div
@@ -116,11 +117,18 @@ function Cell(props: {
)
}
function FocusCell(props: { active: boolean; inline?: boolean; onClick: () => void }) {
function ToggleCell(props: {
active: boolean
inline?: boolean
label: string
onClick: () => void
tip: string
value: string
}) {
const content = () => (
<button
type="button"
aria-label="Force focus styles on all interactive elements"
aria-label={`${props.label}: ${props.value}`}
aria-pressed={props.active}
classList={{
"flex min-w-0 items-center font-mono uppercase hover:bg-surface-raised-base focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-border-focus": true,
@@ -137,26 +145,22 @@ function FocusCell(props: { active: boolean; inline?: boolean; onClick: () => vo
"flex-col items-center": !props.inline,
}}
>
<span class="text-[10px] leading-none font-black tracking-[0.04em] opacity-70">FOCUS</span>
<span
classList={{ "leading-none font-bold": true, "text-[11px]": !!props.inline, "text-[13px]": !props.inline }}
>
{props.active ? "ON" : "OFF"}
</span>
<span class="text-[10px] leading-none font-black tracking-[0.04em] opacity-70">{props.label}</span>
<span class="text-[11px] leading-none font-bold">{props.value}</span>
</span>
</button>
)
if (props.inline) {
return (
<TooltipV2 value="Force focus styles on all interactive elements" placement="top">
<TooltipV2 value={props.tip} placement="top">
{content()}
</TooltipV2>
)
}
return (
<Tooltip value="Force focus styles on all interactive elements" placement="top">
<Tooltip value={props.tip} placement="top">
{content()}
</Tooltip>
)
@@ -475,7 +479,7 @@ export function DebugBar(props: { inline?: boolean } = {}) {
"gap-[9px]": !!props.inline,
"gap-px": !props.inline,
"flex w-full flex-nowrap items-center justify-start": !!props.inline,
"grid-cols-5": !props.inline,
"grid-cols-4": !props.inline,
grid: !props.inline,
}}
>
@@ -557,10 +561,25 @@ export function DebugBar(props: { inline?: boolean } = {}) {
bad={bad(heap(), 0.8)}
dim={state.heap.used === undefined}
inline={props.inline}
wide={!platform.setForceFocus}
span={platform.setForceFocus ? 2 : 3}
/>
<ToggleCell
active={language.direction() === "rtl"}
inline={props.inline}
label={language.t("debugBar.direction.label")}
tip={language.t("debugBar.direction.tip")}
value={language.t(`debugBar.direction.${language.direction()}`)}
onClick={() => language.setDirection(language.direction() === "rtl" ? "ltr" : "rtl")}
/>
{platform.setForceFocus && (
<FocusCell active={state.focus} inline={props.inline} onClick={() => void toggleFocus()} />
<ToggleCell
active={state.focus}
inline={props.inline}
label={language.t("debugBar.focus.label")}
tip={language.t("debugBar.focus.tip")}
value={language.t(state.focus ? "debugBar.focus.on" : "debugBar.focus.off")}
onClick={() => void toggleFocus()}
/>
)}
</div>
</aside>
@@ -509,7 +509,12 @@ function ProviderConnection(props: {
const hint = suffix?.[1]
return {
label: suffix ? label.slice(0, -suffix[0].length) : label,
hint: hint ? hint[0].toUpperCase() + hint.slice(1) : value?.type === "key" ? "Browser" : undefined,
hint:
hint?.toLowerCase() === "headless"
? language.t("provider.connect.method.headless")
: hint?.toLowerCase() === "browser" || (!hint && value?.type === "key")
? language.t("provider.connect.method.browser")
: undefined,
}
}
@@ -131,7 +131,7 @@ export function CustomProviderForm(props: { autofocus?: boolean } = {}) {
const saveMutation = useMutation(() => ({
mutationFn: async (result: NonNullable<ReturnType<typeof validate>>) => {
if ((await serverSDK().protocol) !== "v1") throw new Error("Custom providers are unavailable on this server")
if ((await serverSDK().protocol) !== "v1") throw new Error(language.t("provider.custom.unavailable"))
const disabledProviders = serverSync().data.config.disabled_providers ?? []
const nextDisabled = disabledProviders.filter((id) => id !== result.providerID)
+9 -7
View File
@@ -29,14 +29,14 @@ export type { Kind } from "@/components/file-tree"
const INDENT_STEP = 16
function rowPaddingLeft(level: number, type: FileNode["type"]) {
function rowPaddingStart(level: number, type: FileNode["type"]) {
if (type === "directory") return 8 + level * INDENT_STEP
if (level === 0) return 8
return 8 + level * INDENT_STEP - INDENT_STEP
}
function guideLineLeft(level: number) {
return rowPaddingLeft(level, "directory") + 8
function guideLineStart(level: number) {
return rowPaddingStart(level, "directory") + 8
}
export const kindLabel = (kind: Kind) => {
@@ -87,7 +87,7 @@ const FileTreeNodeV2 = (
...local.classList,
[local.class ?? ""]: !!local.class,
}}
style={`padding-left: ${rowPaddingLeft(local.level, local.node.type)}px`}
style={`padding-inline-start: ${rowPaddingStart(local.level, local.node.type)}px`}
draggable={local.draggable}
onDragStart={(event: DragEvent) => {
if (!local.draggable) return
@@ -99,7 +99,9 @@ const FileTreeNodeV2 = (
{...rest}
>
{local.children}
<span class="flex-1 min-w-0 text-12-medium whitespace-nowrap truncate">{local.node.name}</span>
<span class="flex-1 min-w-0 text-start text-12-medium whitespace-nowrap truncate">
<bdi dir="auto">{local.node.name}</bdi>
</span>
{(() => {
const value = kind()
if (!value || local.node.type !== "file") return null
@@ -116,7 +118,7 @@ const FileTreeNodeV2 = (
function GuideLines(props: { level: number }) {
return (
<For each={Array.from({ length: props.level })}>
{(_, index) => <div data-slot="file-tree-v2-guide" style={`left: ${guideLineLeft(index())}px`} />}
{(_, index) => <div data-slot="file-tree-v2-guide" style={`inset-inline-start: ${guideLineStart(index())}px`} />}
</For>
)
}
@@ -227,7 +229,7 @@ export default function FileTreeV2(props: {
style={{
position: "absolute",
top: "0",
left: "0",
"inset-inline-start": "0",
width: "100%",
height: `${item().size}px`,
transform: `translateY(${item().start}px)`,
+2 -2
View File
@@ -146,13 +146,13 @@ const FileTreeNode = (
<Dynamic
component={local.as ?? "div"}
classList={{
"w-full min-w-0 h-6 flex items-center justify-start gap-x-1.5 rounded-md px-1.5 py-0 text-left hover:bg-surface-raised-base-hover active:bg-surface-base-active transition-colors cursor-pointer": true,
"w-full min-w-0 h-6 flex items-center justify-start gap-x-1.5 rounded-md px-1.5 py-0 text-start hover:bg-surface-raised-base-hover active:bg-surface-base-active transition-colors cursor-pointer": true,
"bg-surface-base-active": local.node.path === local.active,
...local.classList,
[local.class ?? ""]: !!local.class,
[local.nodeClass ?? ""]: !!local.nodeClass,
}}
style={`padding-left: ${Math.max(0, 8 + local.level * 12 - (local.node.type === "file" ? 24 : 4))}px`}
style={`padding-inline-start: ${Math.max(0, 8 + local.level * 12 - (local.node.type === "file" ? 24 : 4))}px`}
draggable={local.draggable}
onDragStart={(event: DragEvent) => {
if (!local.draggable) return
+27 -32
View File
@@ -1,9 +1,11 @@
import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon"
import { IconButtonV2 } from "@opencode-ai/ui/v2/icon-button-v2"
import { isRTL } from "@kobalte/core/i18n"
import { createSignal, Show } from "solid-js"
import { Drawer, DrawerClose, DrawerContent } from "@/components/ui/drawer"
import { usePlatform } from "@/context/platform"
import { useSettings } from "@/context/settings"
import { useLanguage } from "@/context/language"
import introducingTabsVideo from "@/assets/help/introducing-tabs.mp4"
import homeImage from "@/assets/help/home.png"
import tabsImage from "@/assets/help/tabs.png"
@@ -15,20 +17,22 @@ const showPopover = () => true
export function TabsInfoPopup() {
const settings = useSettings()
const platform = usePlatform()
const language = useLanguage()
const [drawerOpen, setDrawerOpen] = createSignal(false)
const windows = () => platform.platform === "desktop" && platform.os === "windows"
const rtl = () => isRTL(language.intl())
return (
<Drawer open={drawerOpen()} onOpenChange={setDrawerOpen} side="right">
<Drawer open={drawerOpen()} onOpenChange={setDrawerOpen} side={rtl() ? "left" : "right"}>
<Show when={settings.general.shouldDisplayTabsToast()}>
<div
class="fixed bottom-5 right-5 z-50 h-[240px] w-[192px] rounded-[8px] bg-v2-background-bg-base p-1 shadow-[var(--v2-elevation-floating)]"
aria-label="Introducing Tabs. Organize your work and active sessions with tabs"
class="fixed bottom-5 end-5 z-50 h-[240px] w-[192px] rounded-[8px] bg-v2-background-bg-base p-1 shadow-[var(--v2-elevation-floating)]"
aria-label={language.t("help.tabs.toast.ariaLabel")}
>
<button
type="button"
aria-label="Dismiss Tabs information"
class="absolute top-3 right-3 z-10 size-5 flex items-center justify-center rounded-[4px] bg-[rgba(0,0,0,0.4)]"
aria-label={language.t("help.tabs.toast.dismiss")}
class="absolute top-3 end-3 z-10 size-5 flex items-center justify-center rounded-[4px] bg-[rgba(0,0,0,0.4)]"
onClick={settings.general.dismissTabsToast}
>
<svg
@@ -44,7 +48,7 @@ export function TabsInfoPopup() {
</button>
<button
type="button"
class="relative block h-[232px] w-[184px] cursor-pointer overflow-hidden rounded-[4px] text-left"
class="relative block h-[232px] w-[184px] cursor-pointer overflow-hidden rounded-[4px] text-start"
onClick={() => {
settings.general.dismissTabsToast()
setDrawerOpen(true)
@@ -62,10 +66,10 @@ export function TabsInfoPopup() {
/>
<div class="absolute inset-x-0 bottom-0 flex w-full flex-col items-start gap-1.5 bg-[linear-gradient(180deg,rgba(0,0,0,0)_0%,#000000_100%)] px-3 py-5">
<p class="w-full select-none text-[13px] font-[530] leading-none tracking-[-0.04px] text-[#FFFFFF]">
Introducing Tabs
{language.t("help.tabs.title")}
</p>
<p class="w-full select-none text-[13px] font-[440] leading-[140%] tracking-[-0.04px] text-[#808080]">
Organize your work and active sessions with tabs
{language.t("help.tabs.description")}
</p>
</div>
</button>
@@ -75,7 +79,10 @@ export function TabsInfoPopup() {
style={
windows()
? {
inset: "0 0 0 auto",
top: "0",
bottom: "0",
"inset-inline-end": "0",
"inset-inline-start": "auto",
"max-height": "100vh",
"max-width": "100vw",
"border-radius": "0",
@@ -89,9 +96,9 @@ export function TabsInfoPopup() {
type="button"
size="small"
variant="neutral"
aria-label="Close"
aria-label={language.t("common.close")}
icon={<IconV2 name="xmark-small" />}
class="absolute top-[10px] left-[-36px]"
class="absolute top-[10px] start-[-36px]"
/>
</Show>
<div
@@ -102,7 +109,7 @@ export function TabsInfoPopup() {
}}
>
<p class="min-h-0 min-w-0 flex-1 text-[13px] font-[530] leading-5 tracking-[-0.04px] tabular-nums text-v2-text-text-muted">
July 14
{language.t("help.tabs.date")}
</p>
<Show when={!windows()}>
<DrawerClose
@@ -110,36 +117,24 @@ export function TabsInfoPopup() {
type="button"
size="small"
variant="ghost-muted"
aria-label="Close"
aria-label={language.t("common.close")}
icon={<IconV2 name="xmark-small" />}
/>
</Show>
</div>
<div class="relative flex min-h-0 w-full flex-1 flex-col items-start gap-6 overflow-y-auto p-8">
<p class="w-full shrink-0 self-stretch text-[21px] font-[610] leading-6 tracking-[-0.37px] tabular-nums text-v2-text-text-base">
Introducing Tabs
{language.t("help.tabs.title")}
</p>
<div class="flex w-full flex-1 flex-col gap-4 text-[13px] font-[440] leading-5 tracking-[-0.04px] text-v2-text-text-base">
<p>OpenCode Desktop is now built around tabs.</p>
<p>{language.t("help.tabs.introduction")}</p>
<img src={tabsImage} alt="" class="aspect-video w-full rounded-[6px] object-cover" />
<p>
Start a new session in a tab, or open an existing session from any of your projects. Open a new tab when
you're starting something new, and close it when you're done.
</p>
<p>
Keeping a few tabs open makes it easier to organize your active sessions. Rename tabs to something
memorable if you plan to keep them around.
</p>
<p>
You'll find all your sessions and projects on the new Home screen. Selecting a session opens it in a tab.
</p>
<p>{language.t("help.tabs.sessions")}</p>
<p>{language.t("help.tabs.organize")}</p>
<p>{language.t("help.tabs.home")}</p>
<img src={homeImage} alt="" class="aspect-video w-full rounded-[6px] object-cover" />
<p>When you reopen the app, your tabs are still open.</p>
<p>
The new design does not support Git Worktrees yet, it's coming soon. So if you'd prefer to continue using
the previous layout, you can switch between layouts in Settings. Just keep in mind that the new layout
will become permanent in a few weeks.
</p>
<p>{language.t("help.tabs.persistence")}</p>
<p>{language.t("help.tabs.worktrees")}</p>
</div>
</div>
</DrawerContent>
@@ -137,7 +137,10 @@ export function usePromptInputV2Controller(props: PromptInputV2ControllerProps):
t: (key, params) => language.t(key as Parameters<typeof language.t>[0], params as never),
}),
)
const designPlaceholder = () => promptDesignPlaceholder(mode(), placeholder())
const designPlaceholder = () =>
promptDesignPlaceholder(mode(), placeholder(), (key, params) =>
language.t(key as Parameters<typeof language.t>[0], params as never),
)
const historyComments = () => {
const byID = new Map(comments.all().map((item) => [`${item.file}\n${item.id}`, item] as const))
+2 -1
View File
@@ -77,7 +77,7 @@ import { PromptPopover, type AtOption, type SlashCommand } from "./prompt-input/
import { PromptContextItems } from "./prompt-input/context-items"
import { PromptImageAttachments } from "./prompt-input/image-attachments"
import { PromptDragOverlay } from "./prompt-input/drag-overlay"
import { promptDesignPlaceholder, promptPlaceholder } from "./prompt-input/placeholder"
import { promptPlaceholder } from "./prompt-input/placeholder"
import { createPromptInputTransientState } from "./prompt-input/transient-state"
import { showToast } from "@/utils/toast"
import { ImagePreview } from "@opencode-ai/ui/image-preview"
@@ -1493,6 +1493,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
}
onRemove={removeAttachment}
removeLabel={language.t("prompt.attachment.remove")}
fileLabel={language.t("ui.common.file")}
newLayoutDesigns={false}
/>
<div
@@ -16,6 +16,7 @@ type PromptImageAttachmentsProps = {
onOpen: (attachment: ImageAttachmentPart) => void
onRemove: (id: string) => void
removeLabel: string
fileLabel: string
newLayoutDesigns: boolean
comments?: PromptCommentItem[]
commentActive?: (item: PromptCommentItem) => boolean
@@ -94,7 +95,7 @@ export const PromptImageAttachments: Component<PromptImageAttachmentsProps> = (p
}
>
<AttachmentCardV2 title={attachment.filename}>
{typeLabel(attachment.filename, attachment.mime)}
{typeLabel(attachment.filename, attachment.mime, props.fileLabel)}
</AttachmentCardV2>
</Show>
}
@@ -1,5 +1,5 @@
import { describe, expect, test } from "bun:test"
import { promptPlaceholder } from "./placeholder"
import { promptDesignPlaceholder, promptPlaceholder } from "./placeholder"
describe("promptPlaceholder", () => {
const t = (key: string, params?: Record<string, string>) => `${key}${params?.example ? `:${params.example}` : ""}`
@@ -46,3 +46,18 @@ describe("promptPlaceholder", () => {
expect(value).toBe("prompt.placeholder.simple")
})
})
describe("promptDesignPlaceholder", () => {
const t = (key: string, params?: Record<string, string>) => {
if (key !== "ui.promptInput.placeholder.normal") return key
return `Ask anything, ${params?.slash} for commands, ${params?.at} for context...`
}
test("composes the design placeholder from localized fragments", () => {
expect(promptDesignPlaceholder("normal", "fallback", t)).toBe("Ask anything, / for commands, @ for context...")
})
test("preserves the shell placeholder", () => {
expect(promptDesignPlaceholder("shell", "Enter shell command...", t)).toBe("Enter shell command...")
})
})
@@ -14,7 +14,11 @@ export function promptPlaceholder(input: PromptPlaceholderInput) {
return input.t("prompt.placeholder.normal", { example: input.example })
}
export function promptDesignPlaceholder(mode: PromptPlaceholderInput["mode"], placeholder: string) {
export function promptDesignPlaceholder(
mode: PromptPlaceholderInput["mode"],
placeholder: string,
t: PromptPlaceholderInput["t"],
) {
if (mode === "shell") return placeholder
return "Ask anything, / for commands, @ for context..."
return t("ui.promptInput.placeholder.normal", { slash: "/", at: "@" })
}
@@ -287,7 +287,7 @@
}
.settings-v2-provider-env-hint {
padding-right: 12px;
padding-inline-end: 12px;
font-size: 13px;
font-weight: 440;
line-height: 1;
@@ -311,7 +311,7 @@
line-height: 1;
color: var(--v2-text-text-accent);
cursor: pointer;
text-align: left;
text-align: start;
}
.settings-v2-providers-view-all:hover {
@@ -361,13 +361,13 @@
}
.settings-v2-tab-search [data-slot="text-input-v2-input"] {
padding-right: 28px;
padding-inline-end: 28px;
}
.settings-v2-tab-search-clear {
position: absolute;
top: 50%;
right: 6px;
inset-inline-end: 6px;
z-index: 1;
transform: translateY(-50%);
}
+3 -3
View File
@@ -573,9 +573,8 @@ export const Terminal = (props: TerminalProps) => {
if (!result) return
if (result.response.status === 200 && result.data?.ticket) return result.data.ticket
if (result.response.status === 404 || result.response.status === 405) return
if (result.response.status === 403)
throw new Error("PTY connect ticket rejected by origin or CSRF checks. Check the server CORS config.")
throw new Error(`PTY connect ticket failed with ${result.response.status}`)
if (result.response.status === 403) throw new Error(language.t("terminal.connectTicket.csrfError"))
throw new Error(language.t("terminal.connectTicket.statusError", { status: result.response.status }))
}
// return sdk()
// .api.pty.connectToken({
@@ -742,6 +741,7 @@ export const Terminal = (props: TerminalProps) => {
<div
ref={container}
data-component="terminal"
dir="ltr"
data-prevent-autofocus
tabIndex={-1}
style={{ "background-color": terminalColors().background }}
@@ -1,7 +1,7 @@
[data-titlebar-tab] [data-slot="tab-close"] {
position: absolute;
top: 4px;
right: 4px;
inset-inline-end: 4px;
display: flex;
height: 20px;
width: 20px;
@@ -52,7 +52,7 @@
content: "";
position: absolute;
top: 8px;
left: -3.75px;
inset-inline-start: -3.75px;
width: 1.5px;
height: 12px;
border-radius: 9999px;
@@ -86,6 +86,23 @@
);
}
[data-titlebar-tab][data-title-overflow="true"]:not([data-editing="true"]):dir(rtl) [data-slot="tab-link"] {
-webkit-mask-image: linear-gradient(
to left,
black 0,
black calc(100% - var(--tab-title-fade-offset) - 16px),
transparent calc(100% - var(--tab-title-fade-offset)),
transparent 100%
);
mask-image: linear-gradient(
to left,
black 0,
black calc(100% - var(--tab-title-fade-offset) - 16px),
transparent calc(100% - var(--tab-title-fade-offset)),
transparent 100%
);
}
[data-titlebar-tab][data-title-overflow="true"]:is(:hover, [data-active="true"]):not([data-editing="true"])
[data-slot="tab-link"] {
--tab-title-fade-offset: 24px;
@@ -93,7 +110,7 @@
[data-titlebar-tab][data-title-overflow="true"]:not(:hover):not([data-active="true"]):not([data-editing="true"])
[data-slot="tab-link"] {
padding-right: 0;
padding-inline-end: 0;
}
[data-titlebar-tab] [data-slot="tab-title"] {
@@ -5,6 +5,7 @@ import { createMutation } from "@tanstack/solid-query"
import { IconButtonV2 } from "@opencode-ai/ui/v2/icon-button-v2"
import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon"
import { useGlobal } from "@/context/global"
import { useLanguage } from "@/context/language"
import { ServerConnection, serverName } from "@/context/server"
import { displayName, projectForSession } from "@/pages/layout/helpers"
import { SessionTabAvatar } from "@/pages/layout/session-tab-avatar"
@@ -323,6 +324,7 @@ export function DraftTabItem(props: {
pressed?: boolean
hidden?: boolean
}) {
const language = useLanguage()
const closeTab = (event: MouseEvent) => {
event.preventDefault()
event.stopPropagation()
@@ -397,7 +399,7 @@ export function DraftTabItem(props: {
class="hover-reveal relative z-10 group-hover:opacity-100 group-data-[active=true]:opacity-100 group-data-[editing=true]:opacity-100"
onClick={closeTab}
icon={<IconV2 name="xmark-small" />}
aria-label="Close tab"
aria-label={language.t("common.closeTab")}
/>
</div>
</div>
+21 -6
View File
@@ -1,4 +1,15 @@
import { createEffect, createMemo, createResource, createSignal, Match, onMount, Show, Switch, untrack } from "solid-js"
import {
createEffect,
createMemo,
createResource,
createSignal,
Match,
on,
onMount,
Show,
Switch,
untrack,
} from "solid-js"
import { createStore } from "solid-js/store"
import { useLocation, useNavigate, useParams } from "@solidjs/router"
import { IconButton } from "@opencode-ai/ui/icon-button"
@@ -42,8 +53,11 @@ export type TitlebarUpdate = {
}
export function useTitlebarRightMount() {
const language = useLanguage()
const [mount, setMount] = createSignal<HTMLElement | null>(null)
onMount(() => setMount(document.getElementById("opencode-titlebar-right")))
const sync = () => setMount(document.getElementById("opencode-titlebar-right"))
onMount(sync)
createEffect(on(language.direction, sync, { defer: true }))
return mount
}
@@ -113,9 +127,9 @@ export function Titlebar(props: { update?: TitlebarUpdate; debugTools?: { visibl
return {
visible: version !== undefined || installing,
installing,
label: "Update",
label: language.t("titlebar.update"),
ariaLabel: language.t("toast.update.action.installRestart"),
title: version ? `Update ${version}` : undefined,
title: version ? language.t("titlebar.updateVersion", { version }) : undefined,
onInstall: () => props.update?.install(),
}
})
@@ -169,7 +183,8 @@ export function Titlebar(props: { update?: TitlebarUpdate; debugTools?: { visibl
"padding-left": macTrafficLights() ? `${macTrafficLightsBaseWidth / zoom()}px` : 0,
width: windows() ? `env(titlebar-area-width, calc(100vw - ${windowsControlsWidth()}))` : undefined,
"max-width": windows() ? `env(titlebar-area-width, calc(100vw - ${windowsControlsWidth()}))` : undefined,
"align-self": windows() ? "flex-start" : undefined,
// Native Windows caption controls remain on the physical right in both writing directions.
"margin-right": windows() ? "auto" : undefined,
}}
data-tauri-drag-region
>
@@ -515,7 +530,7 @@ export function Titlebar(props: { update?: TitlebarUpdate; debugTools?: { visibl
<div
class="flex items-center shrink-0"
classList={{
"-translate-x-[36px]": layout.sidebar.opened() && !!params.dir,
"ltr:-translate-x-[36px] rtl:translate-x-[36px]": layout.sidebar.opened() && !!params.dir,
"duration-180 ease-out": !layout.sidebar.opened(),
"duration-180 ease-in": layout.sidebar.opened(),
}}
+1 -1
View File
@@ -55,7 +55,7 @@ const DrawerContent = <T extends ValidComponent = "div">(props: DynamicProps<T,
<DrawerPrimitive.Content
class={props.class}
classList={{
"group/drawer-content fixed inset-y-[6px] right-[6px] left-auto z-[100] flex h-auto max-h-[calc(100vh-12px)] w-[560px] max-w-[calc(100vw-12px)] flex-col items-start rounded-[8px] bg-v2-background-bg-base p-0 shadow-[var(--v2-elevation-overlay)] data-[transitioning]:transition-transform data-[transitioning]:duration-300 md:select-none": true,
"group/drawer-content fixed inset-y-[6px] end-[6px] start-auto z-[100] flex h-auto max-h-[calc(100vh-12px)] w-[560px] max-w-[calc(100vw-12px)] flex-col items-start rounded-[8px] bg-v2-background-bg-base p-0 shadow-[var(--v2-elevation-overlay)] data-[transitioning]:transition-transform data-[transitioning]:duration-300 md:select-none": true,
}}
{...rest}
>
@@ -8,6 +8,7 @@ import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon"
import { useCommand } from "@/context/command"
import { DESKTOP_MENU, desktopMenuVisible, type DesktopMenuAction, type DesktopMenuEntry } from "@/desktop-menu"
import { usePlatform } from "@/context/platform"
import { useLanguage } from "@/context/language"
export function WindowsAppMenu(props: {
command: ReturnType<typeof useCommand>
@@ -15,6 +16,7 @@ export function WindowsAppMenu(props: {
variant?: "legacy" | "v2"
}) {
let lastFocused: HTMLElement | undefined
const language = useLanguage()
const rememberFocus = () => {
const active = document.activeElement
@@ -58,7 +60,7 @@ export function WindowsAppMenu(props: {
variant="ghost-muted"
size="large"
icon={<IconV2 name="menu" />}
aria-label="OpenCode menu"
aria-label={language.t("desktop.menu.ariaLabel")}
onPointerDown={rememberFocus}
onKeyDown={rememberFocus}
/>
@@ -69,7 +71,7 @@ export function WindowsAppMenu(props: {
icon="menu"
variant="ghost"
class="titlebar-icon rounded-md shrink-0"
aria-label="OpenCode menu"
aria-label={language.t("desktop.menu.ariaLabel")}
onPointerDown={rememberFocus}
onKeyDown={rememberFocus}
/>
@@ -79,7 +81,7 @@ export function WindowsAppMenu(props: {
<DropdownMenu.Group>
<DropdownMenu.GroupLabel class="desktop-app-menu-heading">OpenCode</DropdownMenu.GroupLabel>
{DESKTOP_MENU.filter((menu) => desktopMenuVisible(menu, "windows")).map((menu) => (
<DesktopMenuSubmenu label={menu.label}>
<DesktopMenuSubmenu label={language.t(menu.labelKey)}>
{menu.items
?.filter((entry) => desktopMenuVisible(entry, "windows"))
.map((entry) =>
@@ -87,7 +89,7 @@ export function WindowsAppMenu(props: {
<DropdownMenu.Separator />
) : (
<DesktopMenuItem
label={entry.label ?? ""}
label={entry.labelKey ? language.t(entry.labelKey) : ""}
keybind={entry.command ? props.command.keybind(entry.command) : entry.accelerator?.windows}
disabled={entry.command ? commandDisabled(entry.command) : false}
onSelect={() => runEntry(entry)}
+2 -2
View File
@@ -83,7 +83,7 @@ export const ACCEPTED_FILE_EXTENSIONS = Array.from(
),
).sort()
export function filePickerFilters(ext?: string[]) {
export function filePickerFilters(name: string, ext?: string[]) {
if (!ext || ext.length === 0) return undefined
return [{ name: "Files", extensions: ext }]
return [{ name, extensions: ext }]
}
+118 -45
View File
@@ -2,58 +2,41 @@ import * as i18n from "@solid-primitives/i18n"
import { createEffect, createMemo, createResource } from "solid-js"
import { createStore } from "solid-js/store"
import { createSimpleContext } from "@opencode-ai/ui/context"
import { pluralCategory, type UiI18nPluralKey } from "@opencode-ai/ui/context/i18n"
import { Persist, persisted } from "@/utils/persist"
import { dict as en } from "@/i18n/en"
import { dict as uiEn } from "@opencode-ai/ui/i18n/en"
import {
createDesktopNativeBundle,
DESKTOP_NATIVE_ENGLISH,
DESKTOP_NATIVE_LOCALES,
type DesktopNativeBundle,
type DesktopNativeLocale,
} from "@/i18n/desktop-native"
export type Locale =
| "en"
| "zh"
| "zht"
| "ko"
| "de"
| "es"
| "fr"
| "da"
| "ja"
| "pl"
| "ru"
| "uk"
| "ar"
| "no"
| "br"
| "th"
| "bs"
| "tr"
export type Locale = DesktopNativeLocale
export type Direction = "ltr" | "rtl"
const RTL_LOCALES: ReadonlySet<Locale> = new Set(["ar", "ur", "pa"])
function localeDirection(locale: Locale): Direction {
return RTL_LOCALES.has(locale) ? "rtl" : "ltr"
}
type RawDictionary = typeof en & typeof uiEn
type Dictionary = i18n.Flatten<RawDictionary>
type PluralKey =
| UiI18nPluralKey
| "session.question.pending"
| "session.followupDock.summary"
| "session.revertDock.summary"
type Source = { dict: Record<string, string> }
function cookie(locale: Locale) {
return `oc_locale=${encodeURIComponent(locale)}; Path=/; Max-Age=31536000; SameSite=Lax`
}
const LOCALES: readonly Locale[] = [
"en",
"zh",
"zht",
"ko",
"de",
"es",
"fr",
"da",
"ja",
"pl",
"ru",
"uk",
"bs",
"ar",
"no",
"br",
"th",
"tr",
]
const LOCALES: readonly Locale[] = DESKTOP_NATIVE_LOCALES
const INTL: Record<Locale, string> = {
en: "en",
@@ -74,9 +57,19 @@ const INTL: Record<Locale, string> = {
th: "th",
bs: "bs",
tr: "tr",
hi: "hi-IN",
nl: "nl-NL",
id: "id-ID",
vi: "vi-VN",
it: "it-IT",
ur: "ur-PK",
pa: "pa-Arab-PK",
az: "az-Latn-AZ",
fi: "fi-FI",
sv: "sv-SE",
}
const LABEL_KEY: Record<Locale, keyof Dictionary> = {
const LABEL_KEY: Partial<Record<Locale, keyof Dictionary>> = {
en: "language.en",
zh: "language.zh",
zht: "language.zht",
@@ -97,6 +90,19 @@ const LABEL_KEY: Record<Locale, keyof Dictionary> = {
tr: "language.tr",
}
const LABEL: Partial<Record<Locale, string>> = {
hi: "हिन्दी",
nl: "Nederlands",
id: "Bahasa Indonesia",
vi: "Tiếng Việt",
it: "Italiano",
ur: "اردو",
pa: "پنجابی",
az: "Azərbaycanca",
fi: "Suomi",
sv: "Svenska",
}
const base = i18n.flatten({ ...en, ...uiEn })
const dicts = new Map<Locale, Dictionary>([["en", base]])
@@ -121,6 +127,16 @@ const loaders: Record<Exclude<Locale, "en">, () => Promise<Dictionary>> = {
th: () => merge(import("@/i18n/th"), import("@opencode-ai/ui/i18n/th")),
bs: () => merge(import("@/i18n/bs"), import("@opencode-ai/ui/i18n/bs")),
tr: () => merge(import("@/i18n/tr"), import("@opencode-ai/ui/i18n/tr")),
hi: () => merge(import("@/i18n/hi"), import("@opencode-ai/ui/i18n/hi")),
nl: () => merge(import("@/i18n/nl"), import("@opencode-ai/ui/i18n/nl")),
id: () => merge(import("@/i18n/id"), import("@opencode-ai/ui/i18n/id")),
vi: () => merge(import("@/i18n/vi"), import("@opencode-ai/ui/i18n/vi")),
it: () => merge(import("@/i18n/it"), import("@opencode-ai/ui/i18n/it")),
ur: () => merge(import("@/i18n/ur"), import("@opencode-ai/ui/i18n/ur")),
pa: () => merge(import("@/i18n/pa"), import("@opencode-ai/ui/i18n/pa")),
az: () => merge(import("@/i18n/az"), import("@opencode-ai/ui/i18n/az")),
fi: () => merge(import("@/i18n/fi"), import("@opencode-ai/ui/i18n/fi")),
sv: () => merge(import("@/i18n/sv"), import("@opencode-ai/ui/i18n/sv")),
}
function loadDict(locale: Locale) {
@@ -140,7 +156,12 @@ export function loadLocaleDict(locale: Locale) {
const localeMatchers: Array<{ locale: Locale; match: (language: string) => boolean }> = [
{ locale: "en", match: (language) => language.startsWith("en") },
{ locale: "zht", match: (language) => language.startsWith("zh") && language.includes("hant") },
{
locale: "zht",
match: (language) =>
language.startsWith("zh") &&
(language.includes("hant") || language.includes("-tw") || language.includes("-hk") || language.includes("-mo")),
},
{ locale: "zh", match: (language) => language.startsWith("zh") },
{ locale: "ko", match: (language) => language.startsWith("ko") },
{ locale: "de", match: (language) => language.startsWith("de") },
@@ -160,6 +181,22 @@ const localeMatchers: Array<{ locale: Locale; match: (language: string) => boole
{ locale: "th", match: (language) => language.startsWith("th") },
{ locale: "bs", match: (language) => language.startsWith("bs") },
{ locale: "tr", match: (language) => language.startsWith("tr") },
{ locale: "hi", match: (language) => language.startsWith("hi") },
{ locale: "nl", match: (language) => language.startsWith("nl") },
{ locale: "id", match: (language) => language.startsWith("id") },
{ locale: "vi", match: (language) => language.startsWith("vi") },
{ locale: "it", match: (language) => language.startsWith("it") },
{ locale: "ur", match: (language) => language.startsWith("ur") },
{
locale: "pa",
match: (language) => language.startsWith("pa") && (language.includes("arab") || language.includes("-pk")),
},
{
locale: "az",
match: (language) => language.startsWith("az") && !language.includes("arab") && !language.includes("cyrl"),
},
{ locale: "fi", match: (language) => language.startsWith("fi") },
{ locale: "sv", match: (language) => language.startsWith("sv") },
]
function detectLocale(): Locale {
@@ -199,7 +236,7 @@ if (warm !== "en") void loadDict(warm)
export const { use: useLanguage, provider: LanguageProvider } = createSimpleContext({
name: "Language",
gate: false,
init: (props: { locale?: Locale }) => {
init: (props: { locale?: Locale; onNativeTranslations?: (bundle: DesktopNativeBundle) => void }) => {
const initial = props.locale ?? readStoredLocale() ?? detectLocale()
const [store, setStore, _, ready] = persisted(
Persist.global("language", ["language.v1"]),
@@ -210,6 +247,13 @@ export const { use: useLanguage, provider: LanguageProvider } = createSimpleCont
const locale = createMemo<Locale>(() => normalizeLocale(store.locale))
const intl = createMemo(() => INTL[locale()])
const [layout, setLayout] = createStore({ direction: undefined as Direction | undefined })
const direction = createMemo(() => layout.direction ?? localeDirection(locale()))
const layoutLocale = createMemo(() => {
if (!layout.direction) return intl()
// Kobalte derives menu direction from locale rather than accepting a direction override.
return layout.direction === "rtl" ? "ar" : "en"
})
const [dict] = createResource(locale, loadDict, {
initialValue: dicts.get(initial) ?? base,
@@ -220,24 +264,53 @@ export const { use: useLanguage, provider: LanguageProvider } = createSimpleCont
params?: Record<string, string | number | boolean>,
) => string
const label = (value: Locale) => t(LABEL_KEY[value])
const plural = (key: PluralKey, count: number, params?: Record<string, string | number | boolean>) => {
const category = pluralCategory(intl(), count)
const current = (dict.loading ? base : (dict() ?? base)) as Record<string, string>
const candidate = `${key}.${category}`
const fallback = `${key}.other`
return i18n.resolveTemplate(current[candidate] ?? current[fallback] ?? fallback, { ...params, count })
}
const label = (value: Locale) => {
const key = LABEL_KEY[value]
if (key) return t(key)
return LABEL[value] ?? value
}
createEffect(() => {
if (typeof document !== "object") return
document.documentElement.lang = locale()
document.cookie = cookie(locale())
const value = locale()
document.documentElement.lang = value
document.documentElement.dir = direction()
document.cookie = cookie(value)
})
createEffect(() => {
if (!props.onNativeTranslations || dict.loading) return
const current = dict()
if (!current) return
props.onNativeTranslations(
createDesktopNativeBundle(locale(), (key) => current[key] ?? DESKTOP_NATIVE_ENGLISH[key]),
)
})
return {
ready,
locale,
intl,
direction,
layoutLocale,
locales: LOCALES,
label,
t,
plural,
setLocale(next: Locale) {
setStore("locale", normalizeLocale(next))
},
setDirection(next: Direction) {
setLayout("direction", next === localeDirection(locale()) ? undefined : next)
},
}
},
})
+10 -4
View File
@@ -6,6 +6,7 @@ import type { FileSelection } from "@/context/file"
import { Persist, persisted } from "@/utils/persist"
import type { ServerScope } from "@/utils/server-scope"
import type { BlobReference } from "@/utils/draft-store"
import type { Platform } from "@/context/platform"
interface PartBase {
content: string
@@ -236,13 +237,18 @@ function createPromptStateValue(store: PromptStore, setStore: SetStoreFunction<P
return value
}
function createPersistedPrompt(target: ReturnType<typeof promptTarget>, initial?: InitialPrompt) {
const [store, setStore, _, ready] = persisted(target, createStore<PromptStore>(promptStore(initial)))
function createPersistedPrompt(target: ReturnType<typeof promptTarget>, initial?: InitialPrompt, platform?: Platform) {
const [store, setStore, _, ready] = persisted(target, createStore<PromptStore>(promptStore(initial)), platform)
return { ready, ...createPromptStateValue(store, setStore) }
}
export function createPromptSession(serverScope: ServerScope, scope: PromptScope, initial?: InitialPrompt) {
return createPersistedPrompt(promptTarget(serverScope, scope), initial)
export function createPromptSession(
serverScope: ServerScope,
scope: PromptScope,
initial?: InitialPrompt,
platform?: Platform,
) {
return createPersistedPrompt(promptTarget(serverScope, scope), initial, platform)
}
export function createDraftPromptSession(draftID: string, initial?: InitialPrompt) {
+11 -1
View File
@@ -4,10 +4,20 @@ import { DESKTOP_MENU } from "./desktop-menu"
describe("desktop menu", () => {
test("exports logs through the desktop command registry", () => {
const items = DESKTOP_MENU.flatMap((menu) => menu.items ?? []).filter(
(item) => item.type === "item" && item.label === "Export Logs...",
(item) => item.type === "item" && item.labelKey === "desktop.menu.exportLogs",
)
expect(items).toHaveLength(2)
expect(items.every((item) => item.type === "item" && item.command === "logs.export" && !item.action)).toBe(true)
})
test("provides translated labels for role-backed entries", () => {
const windowMenu = DESKTOP_MENU.find((menu) => menu.role === "windowMenu")
const roleItems = DESKTOP_MENU.flatMap((menu) => menu.items ?? []).filter(
(item) => item.type === "item" && item.role && item.labelKey,
)
expect(windowMenu?.labelKey).toBe("desktop.menu.window")
expect(roleItems.length).toBeGreaterThan(0)
})
})
+130 -51
View File
@@ -1,3 +1,5 @@
import type { DesktopNativeKey } from "./i18n/desktop-native"
export type DesktopMenuPlatform = "macos" | "windows"
export type DesktopMenuAction =
@@ -44,7 +46,7 @@ export type DesktopMenuRole =
export type DesktopMenuItem = {
type: "item"
label?: string
labelKey?: DesktopNativeKey
command?: string
action?: DesktopMenuAction
role?: DesktopMenuRole
@@ -63,7 +65,7 @@ export type DesktopMenuEntry = DesktopMenuItem | DesktopMenuSeparator
export type DesktopMenu = {
id: string
label: string
labelKey: DesktopNativeKey
role?: DesktopMenuRole
items?: DesktopMenuEntry[]
platforms?: DesktopMenuPlatform[]
@@ -72,15 +74,20 @@ export type DesktopMenu = {
export const DESKTOP_MENU: DesktopMenu[] = [
{
id: "app",
label: "OpenCode",
labelKey: "desktop.menu.app",
platforms: ["macos"],
items: [
{ type: "item", role: "about" },
{ type: "item", label: "Check for Updates...", action: "app.checkForUpdates", enabled: "updater" },
{ type: "item", label: "Settings", command: "settings.open", accelerator: { macos: "Cmd+," } },
{ type: "item", label: "Reload Webview", action: "view.reload" },
{ type: "item", label: "Restart", action: "app.relaunch" },
{ type: "item", label: "Export Logs...", command: "logs.export" },
{
type: "item",
labelKey: "desktop.menu.checkForUpdates",
action: "app.checkForUpdates",
enabled: "updater",
},
{ type: "item", labelKey: "desktop.menu.settings", command: "settings.open", accelerator: { macos: "Cmd+," } },
{ type: "item", labelKey: "desktop.menu.reloadWebview", action: "view.reload" },
{ type: "item", labelKey: "desktop.menu.restart", action: "app.relaunch" },
{ type: "item", labelKey: "desktop.menu.exportLogs", command: "logs.export" },
{ type: "separator" },
{ type: "item", role: "hide" },
{ type: "item", role: "hideOthers" },
@@ -91,46 +98,81 @@ export const DESKTOP_MENU: DesktopMenu[] = [
},
{
id: "file",
label: "File",
labelKey: "desktop.menu.file",
items: [
{
type: "item",
label: "New Session",
labelKey: "desktop.menu.newSession",
command: "session.new",
accelerator: { macos: "Shift+Cmd+S" },
},
{ type: "item", label: "Open Project...", command: "project.open", accelerator: { macos: "Cmd+O" } },
{
type: "item",
label: "Settings",
labelKey: "desktop.menu.openProject",
command: "project.open",
accelerator: { macos: "Cmd+O" },
},
{
type: "item",
labelKey: "desktop.menu.settings",
command: "settings.open",
accelerator: { windows: "Ctrl+," },
platforms: ["windows"],
},
{
type: "item",
label: "New Window",
labelKey: "desktop.menu.newWindow",
action: "window.new",
accelerator: { macos: "Cmd+Shift+N", windows: "Ctrl+Shift+N" },
},
{ type: "separator" },
{ type: "item", label: "Close Window", action: "window.close", role: "close" },
{ type: "item", labelKey: "desktop.menu.closeWindow", action: "window.close", role: "close" },
],
},
{
id: "edit",
label: "Edit",
labelKey: "desktop.menu.edit",
items: [
{ type: "item", label: "Undo", action: "edit.undo", role: "undo", accelerator: { windows: "Ctrl+Z" } },
{ type: "item", label: "Redo", action: "edit.redo", role: "redo", accelerator: { windows: "Ctrl+Y" } },
{ type: "separator" },
{ type: "item", label: "Cut", action: "edit.cut", role: "cut", accelerator: { windows: "Ctrl+X" } },
{ type: "item", label: "Copy", action: "edit.copy", role: "copy", accelerator: { windows: "Ctrl+C" } },
{ type: "item", label: "Paste", action: "edit.paste", role: "paste", accelerator: { windows: "Ctrl+V" } },
{ type: "item", label: "Delete", action: "edit.delete" },
{
type: "item",
label: "Select All",
labelKey: "desktop.menu.undo",
action: "edit.undo",
role: "undo",
accelerator: { windows: "Ctrl+Z" },
},
{
type: "item",
labelKey: "desktop.menu.redo",
action: "edit.redo",
role: "redo",
accelerator: { windows: "Ctrl+Y" },
},
{ type: "separator" },
{
type: "item",
labelKey: "desktop.menu.cut",
action: "edit.cut",
role: "cut",
accelerator: { windows: "Ctrl+X" },
},
{
type: "item",
labelKey: "desktop.menu.copy",
action: "edit.copy",
role: "copy",
accelerator: { windows: "Ctrl+C" },
},
{
type: "item",
labelKey: "desktop.menu.paste",
action: "edit.paste",
role: "paste",
accelerator: { windows: "Ctrl+V" },
},
{ type: "item", labelKey: "desktop.menu.delete", action: "edit.delete" },
{
type: "item",
labelKey: "desktop.menu.selectAll",
action: "edit.selectAll",
role: "selectAll",
accelerator: { windows: "Ctrl+A" },
@@ -139,47 +181,84 @@ export const DESKTOP_MENU: DesktopMenu[] = [
},
{
id: "view",
label: "View",
labelKey: "desktop.menu.view",
items: [
{ type: "item", label: "Toggle Sidebar", command: "sidebar.toggle" },
{ type: "item", label: "Toggle Terminal", command: "terminal.toggle", accelerator: { macos: "Ctrl+`" } },
{ type: "item", label: "Toggle File Tree", command: "fileTree.toggle" },
{ type: "item", labelKey: "desktop.menu.toggleSidebar", command: "sidebar.toggle" },
{
type: "item",
labelKey: "desktop.menu.toggleTerminal",
command: "terminal.toggle",
accelerator: { macos: "Ctrl+`" },
},
{ type: "item", labelKey: "desktop.menu.toggleFileTree", command: "fileTree.toggle" },
{ type: "separator" },
{ type: "item", label: "Reload", action: "view.reload", role: "reload" },
{ type: "item", label: "Toggle Developer Tools", action: "view.toggleDevTools", role: "toggleDevTools" },
{ type: "item", labelKey: "desktop.menu.reload", action: "view.reload", role: "reload" },
{
type: "item",
labelKey: "desktop.menu.toggleDeveloperTools",
action: "view.toggleDevTools",
role: "toggleDevTools",
},
{ type: "separator" },
{
type: "item",
label: "Actual Size",
labelKey: "desktop.menu.actualSize",
action: "view.resetZoom",
role: "resetZoom",
accelerator: { windows: "Ctrl+0" },
},
{ type: "item", label: "Zoom In", action: "view.zoomIn", role: "zoomIn", accelerator: { windows: "Ctrl++" } },
{ type: "item", label: "Zoom Out", action: "view.zoomOut", role: "zoomOut", accelerator: { windows: "Ctrl+-" } },
{
type: "item",
labelKey: "desktop.menu.zoomIn",
action: "view.zoomIn",
role: "zoomIn",
accelerator: { windows: "Ctrl++" },
},
{
type: "item",
labelKey: "desktop.menu.zoomOut",
action: "view.zoomOut",
role: "zoomOut",
accelerator: { windows: "Ctrl+-" },
},
{ type: "separator" },
{ type: "item", label: "Toggle Full Screen", action: "view.toggleFullscreen", role: "togglefullscreen" },
{
type: "item",
labelKey: "desktop.menu.toggleFullScreen",
action: "view.toggleFullscreen",
role: "togglefullscreen",
},
],
},
{
id: "go",
label: "Go",
labelKey: "desktop.menu.go",
items: [
{ type: "item", label: "Back", command: "common.goBack", accelerator: { macos: "Cmd+[" } },
{ type: "item", label: "Forward", command: "common.goForward", accelerator: { macos: "Cmd+]" } },
{ type: "separator" },
{ type: "item", label: "Previous Session", command: "session.previous", accelerator: { macos: "Option+Up" } },
{ type: "item", label: "Next Session", command: "session.next", accelerator: { macos: "Option+Down" } },
{ type: "item", labelKey: "desktop.menu.back", command: "common.goBack", accelerator: { macos: "Cmd+[" } },
{ type: "item", labelKey: "desktop.menu.forward", command: "common.goForward", accelerator: { macos: "Cmd+]" } },
{ type: "separator" },
{
type: "item",
label: "Previous Project",
labelKey: "desktop.menu.previousSession",
command: "session.previous",
accelerator: { macos: "Option+Up" },
},
{
type: "item",
labelKey: "desktop.menu.nextSession",
command: "session.next",
accelerator: { macos: "Option+Down" },
},
{ type: "separator" },
{
type: "item",
labelKey: "desktop.menu.previousProject",
command: "project.previous",
accelerator: { macos: "Cmd+Option+Up" },
},
{
type: "item",
label: "Next Project",
labelKey: "desktop.menu.nextProject",
command: "project.next",
accelerator: { macos: "Cmd+Option+Down" },
},
@@ -187,31 +266,31 @@ export const DESKTOP_MENU: DesktopMenu[] = [
},
{
id: "window",
label: "Window",
labelKey: "desktop.menu.window",
role: "windowMenu",
items: [
{ type: "item", label: "Minimize", action: "window.minimize" },
{ type: "item", label: "Maximize", action: "window.toggleMaximize" },
{ type: "item", labelKey: "desktop.menu.minimize", action: "window.minimize" },
{ type: "item", labelKey: "desktop.menu.maximize", action: "window.toggleMaximize" },
{ type: "separator" },
{ type: "item", label: "Close Window", action: "window.close" },
{ type: "item", labelKey: "desktop.menu.closeWindow", action: "window.close" },
],
},
{
id: "help",
label: "Help",
labelKey: "desktop.menu.help",
items: [
{ type: "item", label: "OpenCode Documentation", href: "https://opencode.ai/docs" },
{ type: "item", label: "Support Forum", href: "https://discord.com/invite/opencode" },
{ type: "item", label: "Export Logs...", command: "logs.export" },
{ type: "item", labelKey: "desktop.menu.documentation", href: "https://opencode.ai/docs" },
{ type: "item", labelKey: "desktop.menu.supportForum", href: "https://discord.com/invite/opencode" },
{ type: "item", labelKey: "desktop.menu.exportLogs", command: "logs.export" },
{ type: "separator" },
{
type: "item",
label: "Share Feedback",
labelKey: "desktop.menu.shareFeedback",
href: "https://github.com/anomalyco/opencode/issues/new?template=feature_request.yml",
},
{
type: "item",
label: "Report a Bug",
labelKey: "desktop.menu.reportBug",
href: "https://github.com/anomalyco/opencode/issues/new?template=bug_report.yml",
},
],
+231 -82
View File
@@ -1,4 +1,102 @@
export const dict = {
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "ملف",
"desktop.menu.edit": "تحرير",
"desktop.menu.view": "عرض",
"desktop.menu.go": "انتقال",
"desktop.menu.window": "نافذة",
"desktop.menu.help": "مساعدة",
"desktop.menu.checkForUpdates": "التحقق من وجود تحديثات...",
"desktop.menu.settings": "الإعدادات",
"desktop.menu.reloadWebview": "إعادة تحميل Webview",
"desktop.menu.restart": "إعادة التشغيل",
"desktop.menu.exportLogs": "تصدير السجلات...",
"desktop.menu.newSession": "جلسة جديدة",
"desktop.menu.openProject": "فتح مشروع...",
"desktop.menu.newWindow": "نافذة جديدة",
"desktop.menu.closeWindow": "إغلاق النافذة",
"desktop.menu.undo": "تراجع",
"desktop.menu.redo": "إعادة",
"desktop.menu.cut": "قص",
"desktop.menu.copy": "نسخ",
"desktop.menu.paste": "لصق",
"desktop.menu.delete": "حذف",
"desktop.menu.selectAll": "تحديد الكل",
"desktop.menu.toggleSidebar": "إظهار الشريط الجانبي أو إخفاؤه",
"desktop.menu.toggleTerminal": "إظهار المحطة الطرفية أو إخفاؤها",
"desktop.menu.toggleFileTree": "إظهار شجرة الملفات أو إخفاؤها",
"desktop.menu.reload": "إعادة التحميل",
"desktop.menu.toggleDeveloperTools": "إظهار أدوات المطور أو إخفاؤها",
"desktop.menu.actualSize": "الحجم الفعلي",
"desktop.menu.zoomIn": "تكبير",
"desktop.menu.zoomOut": "تصغير",
"desktop.menu.toggleFullScreen": "الدخول إلى ملء الشاشة أو الخروج منه",
"desktop.menu.back": "رجوع",
"desktop.menu.forward": "تقدم",
"desktop.menu.previousSession": "الجلسة السابقة",
"desktop.menu.nextSession": "الجلسة التالية",
"desktop.menu.previousProject": "المشروع السابق",
"desktop.menu.nextProject": "المشروع التالي",
"desktop.menu.minimize": "تصغير النافذة",
"desktop.menu.maximize": "تكبير النافذة",
"desktop.menu.documentation": "وثائق OpenCode",
"desktop.menu.supportForum": "منتدى الدعم",
"desktop.menu.shareFeedback": "إرسال الملاحظات",
"desktop.menu.reportBug": "الإبلاغ عن خلل",
"desktop.menu.ariaLabel": "قائمة OpenCode",
"desktop.updater.dialog.checkFailed.message": "فشل التحقق من وجود تحديثات.",
"desktop.updater.dialog.checkFailed.title": "خطأ في التحديث",
"desktop.updater.dialog.upToDate.message": "لديك أحدث إصدار.",
"desktop.updater.dialog.upToDate.title": "لا توجد تحديثات",
"desktop.updater.dialog.ready.message": "تم تنزيل التحديث {{version}}. هل تريد إعادة التشغيل الآن؟",
"desktop.updater.dialog.ready.title": "التحديث جاهز",
"desktop.updater.dialog.restart": "إعادة التشغيل",
"desktop.updater.dialog.later": "لاحقًا",
"desktop.recovery.action.relaunch": "إعادة تشغيل التطبيق",
"desktop.recovery.action.exportLogs": "تصدير السجلات",
"desktop.recovery.action.keepWaiting": "متابعة الانتظار",
"desktop.recovery.action.quit": "إنهاء",
"desktop.recovery.loadFailed": "فشل تحميل OpenCode",
"desktop.recovery.terminated": "توقفت نافذة OpenCode بشكل غير متوقع",
"desktop.recovery.unresponsive": "OpenCode لا يستجيب",
"desktop.recovery.unresponsive.detail": "يمكنك إعادة تشغيل التطبيق أو فتح السجلات أو متابعة الانتظار.",
"desktop.recovery.loadFailed.detail": "النافذة: {{window}}\nعنوان URL: {{url}}\nالخطأ: {{code}} {{description}}",
"desktop.recovery.terminated.detail": "النافذة: {{window}}\nالسبب: {{reason}}\nالرمز: {{code}}",
"desktop.recovery.unknown": "<غير معروف>",
"desktop.dialog.chooseFolder": "اختيار مجلد",
"desktop.dialog.chooseFile": "اختيار ملف",
"desktop.dialog.saveFile": "حفظ الملف",
"desktop.dialog.files": "الملفات",
"desktop.server.local": "الخادم المحلي",
"desktop.wsl.error.windowsOnly": "لا يتوفر WSL إلا على Windows",
"desktop.wsl.error.unavailable": "WSL غير متاح",
"desktop.wsl.error.listInstalled": "فشل سرد توزيعات WSL المثبتة",
"desktop.wsl.error.listOnline": "فشل سرد توزيعات WSL المتاحة عبر الإنترنت",
"desktop.wsl.error.executeDistro": "تعذر تنفيذ الأوامر في التوزيعة",
"desktop.wsl.error.installWsl": "فشل تثبيت WSL",
"desktop.wsl.error.installDistro": "فشل تثبيت التوزيعة: {{distro}}",
"desktop.wsl.error.installOpencode": "فشل تثبيت OpenCode",
"desktop.wsl.error.alreadyAdded": "تمت إضافة {{distro}} بالفعل",
"desktop.wsl.error.opencodeMissing": "opencode غير مثبت في هذه التوزيعة",
"desktop.wsl.error.opencodeCannotRun": "opencode مثبت، لكن تعذر تشغيله",
"desktop.wsl.error.opencodeNotInstalled": "OpenCode غير مثبت في {{distro}}",
"desktop.wsl.error.updateVersion":
"اكتمل تحديث OpenCode، لكن {{distro}} ما زالت تعرض الإصدار {{installed}}؛ الإصدار المتوقع هو {{expected}}",
"desktop.wsl.error.noVersion": "لا يوجد إصدار",
"desktop.wsl.error.serverExited": "خرج خادم WSL بعد بدء التشغيل (code={{code}} signal={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"خرج خادم WSL قبل أن يصبح سليمًا (code={{code}} signal={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout": "انتهت مهلة فحص سلامة العملية المصاحبة للتوزيعة {{distro}} بعد {{timeout}}ms",
"desktop.wsl.error.commandTimeout": "انتهت مهلة {{command}} {{args}} بعد {{timeout}}ms",
"desktop.wsl.error.failedPort": "فشل الحصول على المنفذ",
"desktop.picker.error.notSelected": "لم يحدد منتقي الملفات ملفًا",
"desktop.picker.error.sizeLimit": "تتجاوز المرفقات المحددة الحد البالغ {{limit}} MB",
"command.category.suggested": "مقترح",
"command.category.view": "عرض",
"command.category.project": "مشروع",
@@ -16,6 +114,7 @@ export const dict = {
"command.category.permissions": "أذونات",
"command.category.workspace": "مساحة عمل",
"command.category.settings": "إعدادات",
"command.logs.export": "تصدير السجلات",
"theme.scheme.system": "نظام",
"theme.scheme.light": "فاتح",
"theme.scheme.dark": "داكن",
@@ -59,16 +158,16 @@ export const dict = {
"command.message.next.description": "انتقل إلى رسالة المستخدم التالية",
"command.model.choose": "اختيار نموذج",
"command.model.choose.description": "حدد نموذجًا مختلفًا",
"command.mcp.toggle": "تبديل MCPs",
"command.mcp.toggle.description": "تبديل MCPs",
"command.mcp.toggle": "تبديل خوادم MCP",
"command.mcp.toggle.description": "تبديل خوادم MCP",
"command.agent.cycle": "تغيير الوكيل",
"command.agent.cycle.description": "التبديل إلى الوكيل التالي",
"command.agent.cycle.reverse": "تغيير الوكيل للخلف",
"command.agent.cycle.reverse.description": "التبديل إلى الوكيل السابق",
"command.model.variant.cycle": "تغيير جهد التفكير",
"command.model.variant.cycle": "تغيير جهد الاستدلال",
"command.model.variant.cycle.description": "التبديل إلى مستوى الجهد التالي",
"command.prompt.mode.shell": "Shell",
"command.prompt.mode.normal": "Prompt",
"command.prompt.mode.normal": "موجّه",
"command.permissions.autoaccept.enable": "قبول الأذونات تلقائيًا",
"command.permissions.autoaccept.disable": "إيقاف قبول الأذونات تلقائيًا",
"command.workspace.toggle": "تبديل مساحات العمل",
@@ -94,13 +193,14 @@ export const dict = {
"dialog.provider.empty": "لم يتم العثور على موفرين",
"dialog.provider.group.popular": "شائع",
"dialog.provider.group.other": "آخر",
"dialog.provider.custom.label": "موفر مخصص متوافق مع OpenAI",
"dialog.provider.tag.recommended": "موصى به",
"dialog.provider.opencode.note": "نماذج مختارة تتضمن Claude و GPT و Gemini والمزيد",
"dialog.provider.opencode.tagline": "نماذج موثوقة ومحسنة",
"dialog.provider.opencodeGo.tagline": "اشتراك منخفض التكلفة للجميع",
"dialog.provider.anthropic.note": "اتصل باستخدام Claude Pro/Max أو مفتاح API",
"dialog.provider.copilot.note": "اتصل باستخدام Copilot أو مفتاح API",
"dialog.provider.openai.note": "اتصل باستخدام ChatGPT Pro/Plus أو مفتاح API",
"dialog.provider.anthropic.note": "وصول مباشر إلى نماذج Claude، بما فيها Pro و Max",
"dialog.provider.copilot.note": "نماذج ذكاء اصطناعي للمساعدة في البرمجة عبر GitHub Copilot",
"dialog.provider.openai.note": "نماذج GPT لمهام الذكاء الاصطناعي العامة السريعة والمتقدمة",
"dialog.provider.google.note": "نماذج Gemini لاستجابات سريعة ومنظمة",
"dialog.provider.openrouter.note": "الوصول إلى جميع النماذج المدعومة من موفر واحد",
"dialog.provider.vercel.note": "وصول موحد إلى نماذج الذكاء الاصطناعي مع توجيه ذكي",
@@ -112,17 +212,20 @@ export const dict = {
"dialog.model.manage.provider.toggle": "تبديل جميع نماذج {{provider}}",
"dialog.model.unpaid.freeModels.title": "نماذج مجانية مقدمة من OpenCode",
"dialog.model.unpaid.addMore.title": "إضافة المزيد من النماذج من موفرين مشهورين",
"dialog.model.unpaid.viewMoreProviders": "عرض أكثر من 70 موفرًا إضافيًا",
"dialog.provider.viewAll": "عرض المزيد من الموفرين",
"provider.connect.title": "اتصال {{provider}}",
"provider.connect.title": "الاتصال بـ {{provider}}",
"provider.connect.title.anthropicProMax": "تسجيل الدخول باستخدام Claude Pro/Max",
"provider.connect.selectMethod": "حدد طريقة تسجيل الدخول لـ {{provider}}.",
"provider.connect.method.apiKey": "مفتاح API",
"provider.connect.method.browser": "المتصفح",
"provider.connect.method.headless": "بدون واجهة رسومية",
"provider.connect.status.inProgress": "جارٍ التفويض...",
"provider.connect.status.waiting": "في انتظار التفويض...",
"provider.connect.status.failed": "فشل التفويض: {{error}}",
"provider.connect.apiKey.description":
"أدخل مفتاح واجهة برمجة تطبيقات {{provider}} الخاص بك لتوصيل حسابك واستخدام نماذج {{provider}} في OpenCode.",
"provider.connect.apiKey.label": "مفتاح واجهة برمجة تطبيقات {{provider}}",
"أدخل مفتاح API الخاص بـ {{provider}} لتوصيل حسابك واستخدام نماذج {{provider}} في OpenCode.",
"provider.connect.apiKey.label": "مفتاح API لـ {{provider}}",
"provider.connect.apiKey.placeholder": "مفتاح API",
"provider.connect.apiKey.required": "مفتاح API مطلوب",
"provider.connect.opencodeZen.line1":
@@ -148,6 +251,7 @@ export const dict = {
"provider.connect.toast.connected.title": "تم توصيل {{provider}}",
"provider.connect.toast.connected.description": "نماذج {{provider}} متاحة الآن للاستخدام.",
"provider.custom.title": "موفر مخصص",
"provider.custom.unavailable": "الموفرون المخصصون غير متاحين على هذا الخادم",
"provider.custom.description.prefix": "تكوين موفر متوافق مع OpenAI. راجع ",
"provider.custom.description.link": "وثائق تكوين الموفر",
"provider.custom.description.suffix": ".",
@@ -196,26 +300,26 @@ export const dict = {
"model.input.image": "صورة",
"model.input.audio": "صوت",
"model.input.video": "فيديو",
"model.input.pdf": "pdf",
"model.input.pdf": "PDF",
"model.tooltip.allows": "يسمح: {{inputs}}",
"model.tooltip.context.label": "السياق",
"model.tooltip.inputs": "المدخلات",
"model.tooltip.model": "النموذج",
"model.tooltip.provider": "الموفر",
"model.tooltip.reasoning": "الاستنتاج",
"model.tooltip.reasoning.allowed": سمح بالاستنتاج",
"model.tooltip.reasoning.none": "بدون استنتاج",
"model.tooltip.reasoning": "الاستدلال",
"model.tooltip.reasoning.allowed": دعم الاستدلال",
"model.tooltip.reasoning.none": "بدون استدلال",
"model.tooltip.context": "حد السياق {{limit}}",
"common.search.placeholder": "بحث",
"common.goBack": "رجوع",
"common.goForward": "انتقل للأمام",
"common.goForward": "التقدم",
"common.loading": "جارٍ التحميل",
"common.loading.ellipsis": "...",
"common.cancel": "إلغاء",
"common.clear": "مسح",
"common.connect": "اتصال",
"common.disconnect": "قطع الاتصال",
"common.continue": "إرسال",
"common.continue": "متابعة",
"common.submit": "إرسال",
"common.save": "حفظ",
"common.saving": "جارٍ الحفظ...",
@@ -227,7 +331,7 @@ export const dict = {
"prompt.placeholder.summarizeComments": "لخّص التعليقات…",
"prompt.placeholder.summarizeComment": "لخّص التعليق…",
"prompt.mode.shell": "Shell",
"prompt.mode.normal": "Prompt",
"prompt.mode.normal": "موجّه",
"prompt.mode.shell.exit": "esc للخروج",
"session.child.promptDisabled": "لا يمكن إرسال موجّهات إلى جلسات الوكلاء الفرعيين.",
"session.child.backToParent": "العودة إلى الجلسة الرئيسية.",
@@ -249,17 +353,17 @@ export const dict = {
"prompt.example.16": "إضافة معالجة الأخطاء لهذه الدالة",
"prompt.example.17": "اشرح نمط regex هذا",
"prompt.example.18": "تحويل هذا إلى TypeScript",
"prompt.example.19": "إضافة تسجيل الدخول (logging) في جميع أنحاء قاعدة التعليمات البرمجية",
"prompt.example.19": "إضافة التسجيل في جميع أنحاء قاعدة التعليمات البرمجية",
"prompt.example.20": "ما هي التبعيات القديمة؟",
"prompt.example.21": "ساعدني في كتابة برنامج نصي للهجرة",
"prompt.example.22": "تنفيذ التخزين المؤقت لهذه النقطة النهائية",
"prompt.example.21": "ساعدني في كتابة برنامج نصي للترحيل",
"prompt.example.22": "تنفيذ التخزين المؤقت لنقطة النهاية هذه",
"prompt.example.23": "إضافة ترقيم الصفحات إلى هذه القائمة",
"prompt.example.24": "إنشاء أمر CLI لـ...",
"prompt.example.25": "كيف تعمل متغيرات البيئة هنا؟",
"prompt.popover.emptyResults": "لا توجد نتائج مطابقة",
"prompt.popover.emptyCommands": "لا توجد أوامر مطابقة",
"prompt.dropzone.label": "أفلت الصور أو ملفات PDF أو الملفات النصية هنا",
"prompt.dropzone.file.label": "أفلت لإشارة @ للملف",
"prompt.dropzone.file.label": "أفلت الملف للإشارة إليه باستخدام @",
"prompt.slash.badge.custom": "مخصص",
"prompt.slash.badge.skill": "مهارة",
"prompt.slash.badge.mcp": "mcp",
@@ -267,7 +371,7 @@ export const dict = {
"prompt.context.includeActiveFile": "تضمين الملف النشط",
"prompt.context.removeActiveFile": "إزالة الملف النشط من السياق",
"prompt.context.removeFile": "إزالة الملف من السياق",
"prompt.action.attachFile": رفاق ملف",
"prompt.action.attachFile": ضافة ملفات",
"prompt.menu.addImagesAndFiles": "إضافة ملفات والمزيد",
"prompt.menu.imagesAndFiles": "الصور والملفات",
"prompt.menu.commands": "الأوامر",
@@ -275,7 +379,7 @@ export const dict = {
"prompt.menu.shellCommand": "أمر shell",
"prompt.attachment.remove": "إزالة المرفق",
"prompt.action.send": "إرسال",
"prompt.action.stop": "توقف",
"prompt.action.stop": "إيقاف",
"prompt.toast.pasteUnsupported.title": "مرفق غير مدعوم",
"prompt.toast.attachmentDuplicate.title": "تم تحميل هذا الملف بالفعل",
"prompt.toast.pasteUnsupported.description": "يمكن إرفاق الصور أو ملفات PDF أو الملفات النصية فقط هنا.",
@@ -287,10 +391,10 @@ export const dict = {
"prompt.toast.commandSendFailed.title": "فشل إرسال الأمر",
"prompt.toast.promptSendFailed.title": "فشل إرسال الموجه",
"prompt.toast.promptSendFailed.description": "تعذر استرداد الجلسة",
"dialog.mcp.title": "MCPs",
"dialog.mcp.description": "{{enabled}} من {{total}} مفعل",
"dialog.mcp.empty": "لم يتم تكوين MCPs",
"dialog.lsp.empty": م الكشف تلقائيًا عن LSPs من أنواع الملفات",
"dialog.mcp.title": "خوادم MCP",
"dialog.mcp.description": "تم تفعيل {{enabled}} من أصل {{total}}",
"dialog.mcp.empty": "لم يتم تكوين أي خوادم MCP",
"dialog.lsp.empty": ُكتشف خوادم LSP تلقائيًا من أنواع الملفات",
"dialog.plugins.empty": "الإضافات المكونة في opencode.json",
"mcp.status.connected": "متصل",
"mcp.status.failed": "فشل",
@@ -401,6 +505,21 @@ export const dict = {
"wsl.onboarding.desktopVersion": "سطح المكتب {{version}}",
"wsl.onboarding.versionMismatch": "لا يتطابق الإصدار المثبت مع إصدار تطبيق سطح المكتب.",
"wsl.onboarding.adding": "جارٍ الإضافة...",
"help.tabs.toast.ariaLabel": "نقدّم علامات التبويب. نظّم عملك وجلساتك النشطة باستخدام علامات التبويب",
"help.tabs.toast.dismiss": "إغلاق معلومات علامات التبويب",
"help.tabs.title": "نقدّم علامات التبويب",
"help.tabs.description": "نظّم عملك وجلساتك النشطة باستخدام علامات التبويب",
"help.tabs.date": "14 يوليو",
"help.tabs.introduction": "أصبح OpenCode Desktop الآن قائمًا على علامات التبويب.",
"help.tabs.sessions":
"ابدأ جلسة جديدة في علامة تبويب، أو افتح جلسة حالية من أي من مشاريعك. افتح علامة تبويب جديدة عندما تبدأ عملاً جديدًا، وأغلقها عند الانتهاء.",
"help.tabs.organize":
"يسهّل إبقاء بضع علامات تبويب مفتوحة تنظيم جلساتك النشطة. أعد تسمية علامات التبويب بأسماء يسهل تذكرها إذا كنت تنوي إبقاءها مفتوحة.",
"help.tabs.home":
"ستجد جميع جلساتك ومشاريعك في شاشة الصفحة الرئيسية الجديدة. يؤدي تحديد جلسة إلى فتحها في علامة تبويب.",
"help.tabs.persistence": "عندما تعيد فتح التطبيق، تظل علامات تبويبك مفتوحة.",
"help.tabs.worktrees":
"لا يدعم التصميم الجديد أشجار عمل Git حتى الآن، وستتوفر قريبًا. لذلك، إذا كنت تفضل مواصلة استخدام التخطيط السابق، فيمكنك التبديل بين التخطيطات في الإعدادات. ضع في اعتبارك أن التخطيط الجديد سيصبح دائمًا خلال بضعة أسابيع.",
"dialog.project.edit.title": "تحرير المشروع",
"dialog.project.edit.name": "الاسم",
"dialog.project.edit.icon": "أيقونة",
@@ -409,35 +528,35 @@ export const dict = {
"dialog.project.edit.icon.recommended": "موصى به: 128x128px",
"dialog.project.edit.color": "لون",
"dialog.project.edit.color.select": "اختر لون {{color}}",
"dialog.project.edit.worktree.startup": "سكريبت بدء تشغيل مساحة العمل",
"dialog.project.edit.worktree.startup": "برنامج نصي لبدء تشغيل مساحة العمل",
"dialog.project.edit.worktree.startup.description": "يتم تشغيله بعد إنشاء مساحة عمل جديدة (شجرة عمل).",
"dialog.project.edit.worktree.startup.placeholder": "مثال: bun install",
"context.breakdown.title": "تفصيل السياق",
"context.breakdown.note": 'تفصيل تقريبي لرموز الإدخال. يشمل "أخرى" تعريفات الأدوات والنفقات العامة.',
"context.breakdown.note": 'تفصيل تقريبي لرموز الإدخال المميزة. يشمل "أخرى" تعريفات الأدوات والأعباء الإضافية.',
"context.breakdown.system": "النظام",
"context.breakdown.user": "المستخدم",
"context.breakdown.assistant": "المساعد",
"context.breakdown.tool": "استدعاءات الأداة",
"context.breakdown.tool": "استدعاءات الأدوات",
"context.breakdown.other": "أخرى",
"context.systemPrompt.title": "موجه النظام",
"context.systemPrompt.title": "موجّه النظام",
"context.rawMessages.title": "الرسائل الخام",
"context.stats.session": "جلسة",
"context.stats.messages": "رسائل",
"context.stats.provider": "موفر",
"context.stats.model": "نموذج",
"context.stats.limit": "حد السياق",
"context.stats.totalTokens": "إجمالي الرموز",
"context.stats.totalTokens": "إجمالي الرموز المميزة",
"context.stats.usage": "استخدام",
"context.stats.inputTokens": "رموز الإدخال",
"context.stats.outputTokens": "رموز الإخراج",
"context.stats.reasoningTokens": "رموز الاستنتاج",
"context.stats.cacheTokens": "رموز التخزين المؤقت (قراءة/كتابة)",
"context.stats.inputTokens": "رموز الإدخال المميزة",
"context.stats.outputTokens": "رموز الإخراج المميزة",
"context.stats.reasoningTokens": "رموز الاستدلال المميزة",
"context.stats.cacheTokens": "رموز التخزين المؤقت المميزة (قراءة/كتابة)",
"context.stats.userMessages": "رسائل المستخدم",
"context.stats.assistantMessages": "رسائل المساعد",
"context.stats.totalCost": "التكلفة الإجمالية",
"context.stats.sessionCreated": "تم إنشاء الجلسة",
"context.stats.lastActivity": "آخر نشاط",
"context.usage.tokens": "رموز",
"context.usage.tokens": "الرموز المميزة",
"context.usage.usage": "استخدام",
"context.usage.cost": "تكلفة",
"context.usage.clickToView": "انقر لعرض السياق",
@@ -465,9 +584,9 @@ export const dict = {
"toast.theme.title": "تم تبديل السمة",
"toast.scheme.title": "مخطط الألوان",
"toast.workspace.enabled.title": "تم تمكين مساحات العمل",
"toast.workspace.enabled.description": "الآن يتم عرض عدة worktrees في الشريط الجانبي",
"toast.workspace.enabled.description": "تُعرض الآن عدة أشجار عمل في الشريط الجانبي",
"toast.workspace.disabled.title": "تم تعطيل مساحات العمل",
"toast.workspace.disabled.description": "يتم عرض worktree الرئيسي فقط في الشريط الجانبي",
"toast.workspace.disabled.description": "تُعرض شجرة العمل الرئيسية فقط في الشريط الجانبي",
"toast.permissions.autoaccept.on.title": "يتم قبول الأذونات تلقائيًا",
"toast.permissions.autoaccept.on.description": "ستتم الموافقة على طلبات الأذونات تلقائيًا",
"toast.permissions.autoaccept.off.title": "تم إيقاف قبول الأذونات تلقائيًا",
@@ -489,7 +608,7 @@ export const dict = {
"toast.session.unshare.failed.description": "حدث خطأ أثناء إلغاء مشاركة الجلسة",
"toast.session.listFailed.title": "فشل تحميل الجلسات لـ {{project}}",
"toast.update.title": "تحديث متاح",
"toast.update.description": "نسخة جديدة من OpenCode ({{version}}) متاحة الآن للتثبيت.",
"toast.update.description": "يتوفر الآن إصدار جديد من OpenCode ({{version}}) للتثبيت.",
"toast.update.action.installRestart": "تثبيت وإعادة تشغيل",
"toast.update.action.notYet": "ليس الآن",
"error.page.title": "حدث خطأ ما",
@@ -509,7 +628,7 @@ export const dict = {
"error.dev.rootNotFound":
"لم يتم العثور على العنصر الجذري. هل نسيت إضافته إلى index.html؟ أو ربما تمت كتابة سمة id بشكل خاطئ؟",
"error.serverSync.connectFailed": "تعذر الاتصال بالخادم. هل هناك خادم يعمل في `{{url}}`؟",
"directory.error.invalidUrl": ليل غير صالح في عنوان URL.",
"directory.error.invalidUrl": "مجلد غير صالح في عنوان URL.",
"error.chain.unknown": "خطأ غير معروف",
"error.chain.causedBy": "بسبب:",
"error.chain.apiError": "خطأ API",
@@ -537,7 +656,7 @@ export const dict = {
"notification.session.responseReady.title": "الاستجابة جاهزة",
"notification.session.error.title": "خطأ في الجلسة",
"notification.session.error.fallbackDescription": "حدث خطأ",
"home.recentProjects": "المشاريع الحديثة",
"home.recentProjects": "المشاريع الأخيرة",
"home.empty.title": "لا توجد مشاريع حديثة",
"home.empty.description": "ابدأ بفتح مشروع محلي",
"home.title": "الرئيسية",
@@ -555,7 +674,7 @@ export const dict = {
"home.sessions.group.today": "اليوم",
"home.sessions.group.yesterday": "أمس",
"home.sessions.group.older": "الأقدم",
"home.providerTip": "اتصل بأكثر من 75 مزودًا لاستخدام نماذج أخرى، بما فيها Claude وGPT وGemini وغيرها",
"home.providerTip": "اتصل بأكثر من 75 موفرًا لاستخدام نماذج أخرى، بما فيها Claude وGPT وGemini وغيرها",
"session.tab.session": "جلسة",
"session.tab.review": "مراجعة",
"session.tab.context": "سياق",
@@ -565,7 +684,7 @@ export const dict = {
"session.error.notFound.description": "يشير هذا التبويب إلى جلسة لم تعد موجودة على هذا الخادم.",
"session.error.notFound.closeTab": "إغلاق علامة التبويب",
"session.error.serverConnection": "تعذر الاتصال بهذا الخادم",
"session.review.filesChanged": "تم تغيير {{count}} ملفات",
"session.review.filesChanged": "الملفات المتغيرة: {{count}}",
"session.review.change.one": "تغيير",
"session.review.change.other": "تغييرات",
"session.review.loadingChanges": "جارٍ تحميل التغييرات...",
@@ -573,7 +692,7 @@ export const dict = {
"session.review.noChanges": "لا توجد تغييرات",
"session.review.noUncommittedChanges": "لا توجد تغييرات غير مُودَعة بعد",
"session.review.noBranchChanges": "لا توجد تغييرات في الفرع بعد",
"session.review.noVcs": "لم يتم اكتشاف نظام التحكم في الإصدار Git، لن يتم عرض التغييرات",
"session.review.noVcs": "لم يُكتشف نظام Git للتحكم في الإصدارات، لذا لن تُعرض التغييرات",
"session.review.noSnapshot": "تم تعطيل تتبع اللقطات في التكوين، لذا فإن تغييرات الجلسة غير متوفرة",
"session.files.selectToOpen": "اختر ملفًا لفتحه",
"session.files.all": "كل الملفات",
@@ -591,14 +710,26 @@ export const dict = {
"session.question.minimize": "تصغير السؤال",
"session.question.restore": "استعادة السؤال",
"session.question.pending.one": "{{count}} سؤال معلق",
"session.question.pending.zero": "عدد الأسئلة المعلقة: {{count}}",
"session.question.pending.two": "عدد الأسئلة المعلقة: {{count}}",
"session.question.pending.few": "{{count}} أسئلة معلقة",
"session.question.pending.many": "{{count}} سؤالًا معلقًا",
"session.question.pending.other": "الأسئلة المعلقة: {{count}}",
"session.followupDock.summary.one": "{{count}} رسالة في الانتظار",
"session.followupDock.summary.other": "{{count}} رسائل في الانتظار",
"session.followupDock.summary.one": "{{count}} رسالة في قائمة الانتظار",
"session.followupDock.summary.zero": "عدد الرسائل في قائمة الانتظار: {{count}}",
"session.followupDock.summary.two": "عدد الرسائل في قائمة الانتظار: {{count}}",
"session.followupDock.summary.few": "{{count}} رسائل في قائمة الانتظار",
"session.followupDock.summary.many": "{{count}} رسالةً في قائمة الانتظار",
"session.followupDock.summary.other": "{{count}} رسائل في قائمة الانتظار",
"session.followupDock.sendNow": "إرسال الآن",
"session.followupDock.edit": "تحرير",
"session.followupDock.collapse": "طي الرسائل المنتظرة",
"session.followupDock.expand": "توسيع الرسائل المنتظرة",
"session.revertDock.summary.one": "{{count}} رسالة تم التراجع عنها",
"session.revertDock.summary.zero": "عدد الرسائل التي تم التراجع عنها: {{count}}",
"session.revertDock.summary.two": "عدد الرسائل التي تم التراجع عنها: {{count}}",
"session.revertDock.summary.few": "{{count}} رسائل تم التراجع عنها",
"session.revertDock.summary.many": "{{count}} رسالةً تم التراجع عنها",
"session.revertDock.summary.other": "{{count}} رسائل تم التراجع عنها",
"session.revertDock.collapse": "طي الرسائل التي تم التراجع عنها",
"session.revertDock.expand": "توسيع الرسائل التي تم التراجع عنها",
@@ -650,11 +781,17 @@ export const dict = {
"terminal.close": "إغلاق المحطة الطرفية",
"terminal.connectionLost.title": "فقد الاتصال",
"terminal.connectionLost.description": "انقطع اتصال المحطة الطرفية. يمكن أن يحدث هذا عند إعادة تشغيل الخادم.",
"terminal.connectTicket.csrfError": "رُفضت تذكرة اتصال PTY بسبب فحوصات الأصل أو CSRF. تحقق من إعداد CORS للخادم.",
"terminal.connectTicket.statusError": "فشلت تذكرة اتصال PTY بالحالة {{status}}",
"titlebar.update": "تحديث",
"titlebar.updateVersion": "تحديث {{version}}",
"common.closeTab": "إغلاق علامة التبويب",
"common.dismiss": "رفض",
"common.dismiss": "إهمال",
"common.requestFailed": "فشل الطلب",
"common.moreOptions": "مزيد من الخيارات",
"common.learnMore": "اعرف المزيد",
"common.learnMore": "اطّلع على المزيد",
"common.rename": "إعادة تسمية",
"common.reset": "إعادة تعيين",
"common.archive": "أرشفة",
@@ -672,7 +809,7 @@ export const dict = {
"sidebar.gettingStarted.title": "البدء",
"sidebar.gettingStarted.line1": "يتضمن OpenCode نماذج مجانية حتى تتمكن من البدء فورًا.",
"sidebar.gettingStarted.line2": "قم بتوصيل أي موفر لاستخدام النماذج، بما في ذلك Claude و GPT و Gemini وما إلى ذلك.",
"sidebar.project.recentSessions": "الجلسات الحديثة",
"sidebar.project.recentSessions": "الجلسات الأخيرة",
"sidebar.project.viewAllSessions": "عرض جميع الجلسات",
"sidebar.project.clearNotifications": "مسح الإشعارات",
"sidebar.empty.title": "لا توجد مشاريع مفتوحة",
@@ -691,7 +828,7 @@ export const dict = {
"settings.general.section.updates": "التحديثات",
"settings.general.section.sounds": "المؤثرات الصوتية",
"settings.general.section.feed": "الخلاصة",
"settings.general.section.display": "شاشة العرض",
"settings.general.section.display": "العرض",
"settings.general.row.language.title": "اللغة",
"settings.general.row.language.description": "تغيير لغة العرض لـ OpenCode",
"settings.general.row.shell.title": "Shell المحطة الطرفية",
@@ -728,10 +865,11 @@ export const dict = {
"settings.general.row.mobileTitlebarBottom.title": "التنقل السفلي",
"settings.general.row.mobileTitlebarBottom.description":
"وضع شريط العنوان وعلامات تبويب الجلسات أسفل الشاشة على الأجهزة المحمولة",
"settings.general.row.showCustomAgents.title": "الوكلاء المخصصون",
"settings.general.row.showCustomAgents.description": "إظهار محدد الوكلاء في محرر الرسائل",
"settings.general.row.reasoningSummaries.title": "إظهار ملخصات الاستنتاج",
"settings.general.row.reasoningSummaries.description": "عرض ملخصات استنتاج النموذج في الشريط الزمني",
"settings.general.row.showCustomAgents.title": "إظهار الوكيل",
"settings.general.row.showCustomAgents.description":
"التبديل بين الوكلاء في محرر الرسائل. عند إخفائه، يُستخدم وكيل Build افتراضيًا.",
"settings.general.row.reasoningSummaries.title": "إظهار ملخصات الاستدلال",
"settings.general.row.reasoningSummaries.description": "عرض ملخصات استدلال النموذج في الشريط الزمني",
"settings.general.row.shellToolPartsExpanded.title": "توسيع أجزاء أداة shell",
"settings.general.row.shellToolPartsExpanded.description":
"إظهار أجزاء أداة shell موسعة بشكل افتراضي في الشريط الزمني",
@@ -744,11 +882,12 @@ export const dict = {
"استخدم علامات التبويب الجديدة وتخطيط الصفحة الرئيسية. يمكنك التبديل بين التخطيطات لفترة محدودة.",
"settings.general.row.newInterfaceNotice.title": "أنت تستخدم الآن التخطيط الجديد",
"settings.general.row.newInterfaceNotice.description": "التخطيط السابق لم يعد متاحًا",
"settings.general.row.newInterfaceNotice.dismiss": "رفض",
"settings.general.row.pinchZoom.title": "التكبير بإيماءة القرص",
"settings.general.row.pinchZoom.description": "السماح بإيماءة القرص على لوحة اللمس وإيماءة Ctrl-scroll للتكبير",
"settings.general.row.newInterfaceNotice.dismiss": "إهمال",
"settings.general.row.pinchZoom.title": "التكبير بالمقاربة والمباعدة",
"settings.general.row.pinchZoom.description":
"السماح بإيماءات مقاربة الأصابع ومباعدتها على لوحة التعقب والتمرير مع الضغط على Ctrl للتكبير",
"settings.general.row.wayland.title": "استخدام Wayland الأصلي",
"settings.general.row.wayland.description": "تعطيل التراجع إلى X11 على Wayland. يتطلب إعادة التشغيل.",
"settings.general.row.wayland.description": "تعطيل الرجوع إلى X11 على Wayland. يتطلب إعادة التشغيل.",
"settings.general.row.wayland.tooltip":
"على Linux مع شاشات بمعدلات تحديث مختلطة، يمكن أن يكون Wayland الأصلي أكثر استقرارًا.",
"settings.general.row.releaseNotes.title": "ملاحظات الإصدار",
@@ -761,7 +900,7 @@ export const dict = {
"settings.updates.action.checking": "جارٍ التحقق...",
"settings.updates.action.downloading": "جارٍ التنزيل...",
"settings.updates.action.installing": "جارٍ التثبيت...",
"settings.updates.toast.latest.title": "أنت على آخر إصدار",
"settings.updates.toast.latest.title": "لديك أحدث إصدار",
"settings.updates.toast.latest.description": "أنت تستخدم أحدث إصدار من OpenCode.",
"sound.option.none": "بلا",
"sound.option.alert01": "تنبيه 01",
@@ -823,17 +962,17 @@ export const dict = {
"settings.general.sounds.errors.description": "تشغيل صوت عند حدوث خطأ",
"settings.shortcuts.title": "اختصارات لوحة المفاتيح",
"settings.shortcuts.reset.button": "إعادة التعيين إلى الافتراضيات",
"settings.shortcuts.reset.toast.title": "تم إعادة تعيين الاختصارات",
"settings.shortcuts.reset.toast.description": "تم إعادة تعيين اختصارات لوحة المفاتيح إلى الافتراضيات.",
"settings.shortcuts.reset.toast.title": "أُعيد تعيين الاختصارات",
"settings.shortcuts.reset.toast.description": "أُعيد تعيين اختصارات لوحة المفاتيح إلى الإعدادات الافتراضية.",
"settings.shortcuts.conflict.title": "الاختصار قيد الاستخدام بالفعل",
"settings.shortcuts.conflict.description": "{{keybind}} معين بالفعل لـ {{titles}}.",
"settings.shortcuts.unassigned": "غير معين",
"settings.shortcuts.conflict.description": "الاختصار {{keybind}} مخصص بالفعل لـ {{titles}}.",
"settings.shortcuts.unassigned": "غير مخصص",
"settings.shortcuts.pressKeys": "اضغط على المفاتيح",
"settings.shortcuts.search.placeholder": "البحث في الاختصارات",
"settings.shortcuts.search.empty": "لم يتم العثور على اختصارات",
"settings.shortcuts.group.general": "عام",
"settings.shortcuts.group.session": "جلسة",
"settings.shortcuts.group.navigation": "تصفح",
"settings.shortcuts.group.navigation": "التنقل",
"settings.shortcuts.group.modelAndAgent": "النموذج والوكيل",
"settings.shortcuts.group.terminal": "المحطة الطرفية",
"settings.shortcuts.group.prompt": "موجه",
@@ -858,19 +997,18 @@ export const dict = {
"settings.permissions.description": "تحكم في الأدوات التي يمكن للخادم استخدامها بشكل افتراضي.",
"settings.permissions.section.tools": "الأدوات",
"settings.permissions.toast.updateFailed.title": "فشل تحديث الأذونات",
"settings.permissions.action.allow": "سماح",
"settings.permissions.action.ask": "سؤال",
"settings.permissions.action.deny": "رفض",
"settings.permissions.action.allow": "السماح",
"settings.permissions.action.ask": "طلب الإذن",
"settings.permissions.action.deny": "الرفض",
"settings.permissions.tool.read.title": "قراءة",
"settings.permissions.tool.read.description": "قراءة ملف (يطابق مسار الملف)",
"settings.permissions.tool.edit.title": "تحرير",
"settings.permissions.tool.edit.description":
"تعديل الملفات، بما في ذلك التحرير والكتابة والتصحيحات والتحرير المتعدد",
"settings.permissions.tool.edit.description": "تعديل الملفات، بما في ذلك عمليات التحرير والكتابة وتطبيق الرقع",
"settings.permissions.tool.glob.title": "Glob",
"settings.permissions.tool.glob.description": "مطابقة الملفات باستخدام أنماط glob",
"settings.permissions.tool.grep.title": "Grep",
"settings.permissions.tool.grep.description": "البحث في محتويات الملف باستخدام التعبيرات العادية",
"settings.permissions.tool.list.title": "قائمة",
"settings.permissions.tool.list.title": "سرد",
"settings.permissions.tool.list.description": "سرد الملفات داخل دليل",
"settings.permissions.tool.bash.title": "Bash",
"settings.permissions.tool.bash.description": "تشغيل أوامر shell",
@@ -888,7 +1026,7 @@ export const dict = {
"settings.permissions.tool.websearch.description": "البحث في الويب",
"settings.permissions.tool.external_directory.title": "دليل خارجي",
"settings.permissions.tool.external_directory.description": "الوصول إلى الملفات خارج دليل المشروع",
"settings.permissions.tool.doom_loop.title": "حلقة الموت",
"settings.permissions.tool.doom_loop.title": "حلقة مفرغة",
"settings.permissions.tool.doom_loop.description": "اكتشاف استدعاءات الأدوات المتكررة بمدخلات متطابقة",
"session.delete.failed.title": "فشل حذف الجلسة",
"session.delete.title": "حذف الجلسة",
@@ -896,7 +1034,7 @@ export const dict = {
"session.delete.button": "حذف الجلسة",
"workspace.new": "مساحة عمل جديدة",
"workspace.type.local": "محلي",
"workspace.type.sandbox": "صندوق رمل",
"workspace.type.sandbox": "بيئة معزولة",
"workspace.create.failed.title": "فشل إنشاء مساحة العمل",
"workspace.delete.failed.title": "فشل حذف مساحة العمل",
"workspace.resetting.title": "إعادة تعيين مساحة العمل",
@@ -906,7 +1044,7 @@ export const dict = {
"workspace.reset.success.description": "مساحة العمل تطابق الآن الفرع الافتراضي.",
"workspace.error.stillPreparing": "مساحة العمل لا تزال قيد الإعداد",
"workspace.status.checking": "التحقق من التغييرات غير المدمجة...",
"workspace.status.error": "تعذر التحقق من حالة git.",
"workspace.status.error": "تعذر التحقق من حالة Git.",
"workspace.status.clean": "لم يتم اكتشاف تغييرات غير مدمجة.",
"workspace.status.dirty": "تم اكتشاف تغييرات غير مدمجة في مساحة العمل هذه.",
"workspace.delete.title": "حذف مساحة العمل",
@@ -922,7 +1060,7 @@ export const dict = {
"common.open": "فتح",
"dialog.releaseNotes.action.getStarted": "البدء",
"dialog.releaseNotes.action.next": "التالي",
"dialog.releaseNotes.action.hideFuture": "عدم إظهار هذا في المستقبل",
"dialog.releaseNotes.action.hideFuture": "عدم إظهارها مستقبلاً",
"dialog.releaseNotes.media.alt": "معاينة الإصدار",
"toast.project.reloadFailed.title": "فشل في إعادة تحميل {{project}}",
"error.server.invalidConfiguration": "تكوين غير صالح",
@@ -932,22 +1070,25 @@ export const dict = {
"common.time.hoursAgo.short": "قبل {{count}} س",
"common.time.daysAgo.short": "قبل {{count}} ي",
"settings.providers.connected.environmentDescription": "متصل من متغيرات البيئة الخاصة بك",
"settings.providers.custom.description": "أضف مزود متوافق مع OpenAI بواسطة عنوان URL الأساسي.",
"settings.providers.custom.description": "أضف موفرًا متوافقًا مع OpenAI باستخدام عنوان URL الأساسي.",
"app.server.unreachable": "تعذر الوصول إلى {{server}}",
"app.server.retrying": "جاري إعادة المحاولة تلقائيًا...",
"app.server.retrying": "جارٍ إعادة المحاولة تلقائيًا...",
"app.server.otherServers": "خوادم أخرى",
"dialog.server.add.usernamePlaceholder": "اسم المستخدم",
"dialog.server.add.passwordPlaceholder": "كلمة المرور",
"server.row.noUsername": "لا يوجد اسم مستخدم",
"session.review.noVcs.createGit.title": "إنشاء مستودع Git",
"session.review.noVcs.createGit.description": "تتبع ومراجعة والتراجع عن التغييرات في هذا المشروع",
"session.review.noVcs.createGit.actionLoading": "جاري إنشاء مستودع Git...",
"session.review.noVcs.createGit.actionLoading": "جارٍ إنشاء مستودع Git...",
"session.review.noVcs.createGit.action": "إنشاء مستودع Git",
"session.todo.progress": "تم إكمال {{done}} من {{total}} مهام",
"session.question.progress": "{{current}} من {{total}} أسئلة",
"session.header.open.finder": "Finder",
"session.header.open.fileExplorer": "مستكشف الملفات",
"session.header.reveal.finder": "إظهار في Finder",
"session.header.reveal.fileExplorer": "إظهار في مستكشف الملفات",
"session.header.reveal.containingFolder": "فتح المجلد الحاوي",
"session.header.open.fileManager": "مدير الملفات",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -965,9 +1106,9 @@ export const dict = {
"debugBar.ariaLabel": "تشخيص أداء التطوير",
"debugBar.na": "غير متاح",
"debugBar.nav.label": "NAV",
"debugBar.nav.tip": "آخر انتقال مكتمل للمسار يمس صفحة جلسة، مُقاسًا من بدء التوجيه حتى أول رسم بعد استقراره.",
"debugBar.nav.tip": "آخر انتقال مكتمل للمسار يتضمن صفحة جلسة، مُقاسًا من بدء التوجيه حتى أول رسم بعد استقراره.",
"debugBar.fps.label": "FPS",
"debugBar.fps.tip": "الإطارات المتجددة في الثانية خلال آخر 5 ثوانٍ.",
"debugBar.fps.tip": "متوسط متحرك لمعدل الإطارات في الثانية خلال آخر 5 ثوانٍ.",
"debugBar.frame.label": "FRAME",
"debugBar.frame.tip": "أسوأ وقت للإطار خلال آخر 5 ثوانٍ.",
"debugBar.jank.label": "JANK",
@@ -979,10 +1120,18 @@ export const dict = {
"debugBar.inp.label": "INP",
"debugBar.inp.tip": "مدة التفاعل التقريبية خلال آخر 5 ثوانٍ. هذا يشبه INP، وليس Web Vitals INP الرسمي.",
"debugBar.cls.label": "CLS",
"debugBar.cls.tip": "التحول التخطيطي التراكمي لعمر التطبيق الحالي.",
"debugBar.cls.tip": "التحول التخطيطي التراكمي منذ تشغيل التطبيق الحالي.",
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "كومة JS المستخدمة مقابل حد الكومة. Chromium فقط.",
"debugBar.mem.tip": "كومة JS المستخدمة مقابل حد الكومة. {{used}} من {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "فرض أنماط التركيز على جميع العناصر التفاعلية",
"debugBar.focus.on": "تشغيل",
"debugBar.focus.off": "إيقاف",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "فرض اتجاه التخطيط على التطبيق بالكامل دون تغيير اللغة المحددة",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
@@ -998,7 +1147,7 @@ export const dict = {
"common.key.pageDown": "Page Down",
"common.key.insert": "Insert",
"common.unknown": "غير معروف",
"error.page.circular": "[دائري]",
"error.page.circular": "[مرجع دائري]",
"error.serverSDK.noServerAvailable": "لا يوجد خادم متاح",
"error.serverSDK.serverNotAvailable": "الخادم غير متاح",
"error.childStore.persistedCacheCreateFailed": "فشل إنشاء ذاكرة التخزين المؤقت الدائمة",
File diff suppressed because it is too large Load Diff
+187 -44
View File
@@ -1,4 +1,104 @@
export const dict = {
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Arquivo",
"desktop.menu.edit": "Editar",
"desktop.menu.view": "Visualizar",
"desktop.menu.go": "Ir",
"desktop.menu.window": "Janela",
"desktop.menu.help": "Ajuda",
"desktop.menu.checkForUpdates": "Verificar atualizações...",
"desktop.menu.settings": "Configurações",
"desktop.menu.reloadWebview": "Recarregar WebView",
"desktop.menu.restart": "Reiniciar",
"desktop.menu.exportLogs": "Exportar logs...",
"desktop.menu.newSession": "Nova sessão",
"desktop.menu.openProject": "Abrir projeto...",
"desktop.menu.newWindow": "Nova janela",
"desktop.menu.closeWindow": "Fechar janela",
"desktop.menu.undo": "Desfazer",
"desktop.menu.redo": "Refazer",
"desktop.menu.cut": "Recortar",
"desktop.menu.copy": "Copiar",
"desktop.menu.paste": "Colar",
"desktop.menu.delete": "Excluir",
"desktop.menu.selectAll": "Selecionar tudo",
"desktop.menu.toggleSidebar": "Alternar barra lateral",
"desktop.menu.toggleTerminal": "Alternar terminal",
"desktop.menu.toggleFileTree": "Alternar árvore de arquivos",
"desktop.menu.reload": "Recarregar",
"desktop.menu.toggleDeveloperTools": "Alternar ferramentas de desenvolvedor",
"desktop.menu.actualSize": "Tamanho real",
"desktop.menu.zoomIn": "Ampliar",
"desktop.menu.zoomOut": "Reduzir",
"desktop.menu.toggleFullScreen": "Alternar tela inteira",
"desktop.menu.back": "Voltar",
"desktop.menu.forward": "Avançar",
"desktop.menu.previousSession": "Sessão anterior",
"desktop.menu.nextSession": "Próxima sessão",
"desktop.menu.previousProject": "Projeto anterior",
"desktop.menu.nextProject": "Próximo projeto",
"desktop.menu.minimize": "Minimizar",
"desktop.menu.maximize": "Maximizar",
"desktop.menu.documentation": "Documentação do OpenCode",
"desktop.menu.supportForum": "Fórum de suporte",
"desktop.menu.shareFeedback": "Enviar comentários",
"desktop.menu.reportBug": "Relatar um bug",
"desktop.menu.ariaLabel": "Menu do OpenCode",
"desktop.updater.dialog.checkFailed.message": "Falha ao verificar atualizações.",
"desktop.updater.dialog.checkFailed.title": "Erro de atualização",
"desktop.updater.dialog.upToDate.message": "Você está em dia.",
"desktop.updater.dialog.upToDate.title": "Nenhuma atualização",
"desktop.updater.dialog.ready.message": "A atualização {{version}} foi baixada. Deseja reiniciar agora?",
"desktop.updater.dialog.ready.title": "Atualização pronta",
"desktop.updater.dialog.restart": "Reiniciar",
"desktop.updater.dialog.later": "Mais tarde",
"desktop.recovery.action.relaunch": "Reabrir",
"desktop.recovery.action.exportLogs": "Exportar logs",
"desktop.recovery.action.keepWaiting": "Continuar aguardando",
"desktop.recovery.action.quit": "Encerrar",
"desktop.recovery.loadFailed": "Falha ao carregar o OpenCode",
"desktop.recovery.terminated": "A janela do OpenCode foi encerrada inesperadamente",
"desktop.recovery.unresponsive": "O OpenCode não está respondendo",
"desktop.recovery.unresponsive.detail": "Você pode reabrir o aplicativo, abrir os logs ou continuar aguardando.",
"desktop.recovery.loadFailed.detail": "Janela: {{window}}\nURL: {{url}}\nErro: {{code}} {{description}}",
"desktop.recovery.terminated.detail": "Janela: {{window}}\nMotivo: {{reason}}\nCódigo: {{code}}",
"desktop.recovery.unknown": "<desconhecido>",
"desktop.dialog.chooseFolder": "Escolher uma pasta",
"desktop.dialog.chooseFile": "Escolher um arquivo",
"desktop.dialog.saveFile": "Salvar arquivo",
"desktop.dialog.files": "Arquivos",
"desktop.server.local": "Servidor local",
"desktop.wsl.error.windowsOnly": "O WSL está disponível somente no Windows",
"desktop.wsl.error.unavailable": "O WSL está indisponível",
"desktop.wsl.error.listInstalled": "Falha ao listar as distribuições WSL instaladas",
"desktop.wsl.error.listOnline": "Falha ao listar as distribuições WSL disponíveis online",
"desktop.wsl.error.executeDistro": "Não é possível executar comandos na distribuição",
"desktop.wsl.error.installWsl": "Falha na instalação do WSL",
"desktop.wsl.error.installDistro": "Falha ao instalar a distribuição: {{distro}}",
"desktop.wsl.error.installOpencode": "Falha na instalação do OpenCode",
"desktop.wsl.error.alreadyAdded": "{{distro}} já foi adicionada",
"desktop.wsl.error.opencodeMissing": "O opencode não está instalado nesta distribuição",
"desktop.wsl.error.opencodeCannotRun": "O opencode está instalado, mas não pôde ser executado",
"desktop.wsl.error.opencodeNotInstalled": "O OpenCode não está instalado em {{distro}}",
"desktop.wsl.error.updateVersion":
"A atualização do OpenCode foi concluída, mas {{distro}} ainda informa a versão {{installed}}; a versão esperada é {{expected}}",
"desktop.wsl.error.noVersion": "sem versão",
"desktop.wsl.error.serverExited":
"O servidor WSL foi encerrado após a inicialização (código={{code}} sinal={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"O servidor WSL foi encerrado antes de ficar íntegro (código={{code}} sinal={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout":
"O tempo limite da verificação de integridade do sidecar de {{distro}} foi excedido após {{timeout}}ms",
"desktop.wsl.error.commandTimeout": "O tempo limite de {{command}} {{args}} foi excedido após {{timeout}}ms",
"desktop.wsl.error.failedPort": "Falha ao obter a porta",
"desktop.picker.error.notSelected": "O arquivo não foi selecionado pelo seletor",
"desktop.picker.error.sizeLimit": "Os anexos selecionados excedem o limite de {{limit}} MB",
"command.category.suggested": "Sugerido",
"command.category.view": "Visualizar",
"command.category.project": "Projeto",
@@ -16,6 +116,7 @@ export const dict = {
"command.category.permissions": "Permissões",
"command.category.workspace": "Espaço de trabalho",
"command.category.settings": "Configurações",
"command.logs.export": "Exportar logs",
"theme.scheme.system": "Sistema",
"theme.scheme.light": "Claro",
"theme.scheme.dark": "Escuro",
@@ -94,13 +195,14 @@ export const dict = {
"dialog.provider.empty": "Nenhum provedor encontrado",
"dialog.provider.group.popular": "Popular",
"dialog.provider.group.other": "Outro",
"dialog.provider.custom.label": "Provedor personalizado compatível com OpenAI",
"dialog.provider.tag.recommended": "Recomendado",
"dialog.provider.opencode.note": "Modelos selecionados incluindo Claude, GPT, Gemini e mais",
"dialog.provider.opencode.tagline": "Modelos otimizados e confiáveis",
"dialog.provider.opencodeGo.tagline": "Assinatura de baixo custo para todos",
"dialog.provider.anthropic.note": "Conectar com Claude Pro/Max ou chave de API",
"dialog.provider.copilot.note": "Conectar com Copilot ou chave de API",
"dialog.provider.openai.note": "Conectar com ChatGPT Pro/Plus ou chave de API",
"dialog.provider.anthropic.note": "Acesso direto aos modelos Claude, incluindo Pro e Max",
"dialog.provider.copilot.note": "Modelos de IA para auxílio à programação pelo GitHub Copilot",
"dialog.provider.openai.note": "Modelos GPT rápidos e avançados para tarefas gerais de IA",
"dialog.provider.google.note": "Modelos Gemini para respostas rápidas e estruturadas",
"dialog.provider.openrouter.note": "Acesse todos os modelos suportados de um único provedor",
"dialog.provider.vercel.note": "Acesso unificado a modelos de IA com roteamento inteligente",
@@ -112,11 +214,14 @@ export const dict = {
"dialog.model.manage.provider.toggle": "Alternar todos os modelos {{provider}}",
"dialog.model.unpaid.freeModels.title": "Modelos gratuitos fornecidos pelo OpenCode",
"dialog.model.unpaid.addMore.title": "Adicionar mais modelos de provedores populares",
"dialog.model.unpaid.viewMoreProviders": "Ver mais de 70 provedores",
"dialog.provider.viewAll": "Ver mais provedores",
"provider.connect.title": "Conectar {{provider}}",
"provider.connect.title.anthropicProMax": "Entrar com Claude Pro/Max",
"provider.connect.selectMethod": "Selecionar método de login para {{provider}}.",
"provider.connect.method.apiKey": "Chave de API",
"provider.connect.method.browser": "Navegador",
"provider.connect.method.headless": "Sem interface gráfica",
"provider.connect.status.inProgress": "Autorização em andamento...",
"provider.connect.status.waiting": "Aguardando autorização...",
"provider.connect.status.failed": "Autorização falhou: {{error}}",
@@ -148,15 +253,16 @@ export const dict = {
"provider.connect.toast.connected.title": "{{provider}} conectado",
"provider.connect.toast.connected.description": "Modelos do {{provider}} agora estão disponíveis para uso.",
"provider.custom.title": "Provedor personalizado",
"provider.custom.unavailable": "Provedores personalizados não estão disponíveis neste servidor",
"provider.custom.description.prefix": "Configure um provedor compatível com OpenAI. Veja a ",
"provider.custom.description.link": "documentação de configuração do provedor",
"provider.custom.description.suffix": ".",
"provider.custom.field.providerID.label": "ID do Provedor",
"provider.custom.field.providerID.label": "ID do provedor",
"provider.custom.field.providerID.placeholder": "meuprovedor",
"provider.custom.field.providerID.description": "Letras minúsculas, números, hifens ou sublinhados",
"provider.custom.field.name.label": "Nome de exibição",
"provider.custom.field.name.placeholder": "Meu Provedor de IA",
"provider.custom.field.baseURL.label": "URL Base",
"provider.custom.field.name.placeholder": "Meu provedor de IA",
"provider.custom.field.baseURL.label": "URL base",
"provider.custom.field.baseURL.placeholder": "https://api.meuprovedor.com/v1",
"provider.custom.field.apiKey.label": "Chave de API",
"provider.custom.field.apiKey.placeholder": "Chave de API",
@@ -165,7 +271,7 @@ export const dict = {
"provider.custom.models.id.label": "ID",
"provider.custom.models.id.placeholder": "id-do-modelo",
"provider.custom.models.name.label": "Nome",
"provider.custom.models.name.placeholder": "Nome de Exibição",
"provider.custom.models.name.placeholder": "Nome de exibição",
"provider.custom.models.remove": "Remover modelo",
"provider.custom.models.add": "Adicionar modelo",
"provider.custom.headers.label": "Cabeçalhos (opcional)",
@@ -175,11 +281,11 @@ export const dict = {
"provider.custom.headers.value.placeholder": "valor",
"provider.custom.headers.remove": "Remover cabeçalho",
"provider.custom.headers.add": "Adicionar cabeçalho",
"provider.custom.error.providerID.required": "ID do Provedor é obrigatório",
"provider.custom.error.providerID.required": "O ID do provedor é obrigatório",
"provider.custom.error.providerID.format": "Use letras minúsculas, números, hifens ou sublinhados",
"provider.custom.error.providerID.exists": "Esse ID de provedor já existe",
"provider.custom.error.name.required": "Nome de exibição é obrigatório",
"provider.custom.error.baseURL.required": "URL Base é obrigatória",
"provider.custom.error.name.required": "O nome de exibição é obrigatório",
"provider.custom.error.baseURL.required": "A URL base é obrigatória",
"provider.custom.error.baseURL.format": "Deve começar com http:// ou https://",
"provider.custom.error.required": "Obrigatório",
"provider.custom.error.duplicate": "Duplicado",
@@ -215,7 +321,7 @@ export const dict = {
"common.clear": "Limpar",
"common.connect": "Conectar",
"common.disconnect": "Desconectar",
"common.continue": "Enviar",
"common.continue": "Continuar",
"common.submit": "Enviar",
"common.save": "Salvar",
"common.saving": "Salvando...",
@@ -267,7 +373,7 @@ export const dict = {
"prompt.context.includeActiveFile": "Incluir arquivo ativo",
"prompt.context.removeActiveFile": "Remover arquivo ativo do contexto",
"prompt.context.removeFile": "Remover arquivo do contexto",
"prompt.action.attachFile": "Anexar arquivo",
"prompt.action.attachFile": "Adicionar arquivos",
"prompt.menu.addImagesAndFiles": "Adicionar arquivos e mais",
"prompt.menu.imagesAndFiles": "Imagens e arquivos",
"prompt.menu.commands": "Comandos",
@@ -288,7 +394,7 @@ export const dict = {
"prompt.toast.promptSendFailed.title": "Falha ao enviar prompt",
"prompt.toast.promptSendFailed.description": "Não foi possível recuperar a sessão",
"dialog.mcp.title": "MCPs",
"dialog.mcp.description": "{{enabled}} of {{total}} habilitados",
"dialog.mcp.description": "{{enabled}} de {{total}} ativados",
"dialog.mcp.empty": "Nenhum MCP configurado",
"dialog.lsp.empty": "LSPs detectados automaticamente pelos tipos de arquivo",
"dialog.plugins.empty": "Plugins configurados em opencode.json",
@@ -310,11 +416,11 @@ export const dict = {
"dialog.server.search.placeholder": "Buscar servidores",
"dialog.server.empty": "Nenhum servidor ainda",
"dialog.server.add.title": "Adicionar um servidor",
"dialog.server.add.url": "URL do servidor",
"dialog.server.add.url": "Endereço do servidor",
"dialog.server.add.placeholder": "http://localhost:4096",
"dialog.server.add.error": "Não foi possível conectar ao servidor",
"dialog.server.add.checking": "Verificando...",
"dialog.server.add.button": "Adicionar",
"dialog.server.add.button": "Adicionar servidor",
"dialog.server.add.name": "Nome do servidor (opcional)",
"dialog.server.add.namePlaceholder": "Localhost",
"dialog.server.add.username": "Nome de usuário (opcional)",
@@ -322,7 +428,7 @@ export const dict = {
"dialog.server.edit.title": "Editar servidor",
"dialog.server.default.title": "Servidor padrão",
"dialog.server.default.description":
"Conectar a este servidor na inicialização do aplicativo ao invés de iniciar um servidor local. Requer reinicialização.",
"Conectar a este servidor na inicialização do aplicativo em vez de iniciar um servidor local. Requer reinicialização.",
"dialog.server.default.none": "Nenhum servidor selecionado",
"dialog.server.default.set": "Definir servidor atual como padrão",
"dialog.server.default.clear": "Limpar",
@@ -402,6 +508,21 @@ export const dict = {
"wsl.onboarding.desktopVersion": "desktop {{version}}",
"wsl.onboarding.versionMismatch": "A versão instalada não corresponde à versão do aplicativo para desktop.",
"wsl.onboarding.adding": "Adicionando...",
"help.tabs.toast.ariaLabel": "Apresentamos as abas. Organize seu trabalho e suas sessões ativas com abas",
"help.tabs.toast.dismiss": "Dispensar informações sobre as abas",
"help.tabs.title": "Apresentamos as abas",
"help.tabs.description": "Organize seu trabalho e suas sessões ativas com abas",
"help.tabs.date": "14 de julho",
"help.tabs.introduction": "Agora, o OpenCode Desktop é organizado em abas.",
"help.tabs.sessions":
"Inicie uma nova sessão em uma aba ou abra uma sessão existente de qualquer um dos seus projetos. Abra uma nova aba quando começar algo novo e feche-a quando terminar.",
"help.tabs.organize":
"Manter algumas abas abertas facilita a organização das sessões ativas. Renomeie as abas com nomes fáceis de lembrar se pretende mantê-las abertas.",
"help.tabs.home":
"Você encontrará todas as suas sessões e projetos na nova tela Início. Ao selecionar uma sessão, ela será aberta em uma aba.",
"help.tabs.persistence": "Quando você reabrir o aplicativo, suas abas ainda estarão abertas.",
"help.tabs.worktrees":
"O novo design ainda não oferece suporte a Git Worktrees, mas esse recurso estará disponível em breve. Se preferir continuar usando o layout anterior, você poderá alternar entre os layouts nas Configurações. Lembre-se apenas de que o novo layout se tornará permanente em algumas semanas.",
"dialog.project.edit.title": "Editar projeto",
"dialog.project.edit.name": "Nome",
"dialog.project.edit.icon": "Ícone",
@@ -412,33 +533,33 @@ export const dict = {
"dialog.project.edit.color.select": "Selecionar cor {{color}}",
"dialog.project.edit.worktree.startup": "Script de inicialização do espaço de trabalho",
"dialog.project.edit.worktree.startup.description": "Executa após criar um novo espaço de trabalho (worktree).",
"dialog.project.edit.worktree.startup.placeholder": "ex: bun install",
"context.breakdown.title": "Detalhamento do Contexto",
"dialog.project.edit.worktree.startup.placeholder": "Ex.: bun install",
"context.breakdown.title": "Detalhamento do contexto",
"context.breakdown.note":
'Detalhamento aproximado dos tokens de entrada. "Outros" inclui definições de ferramentas e overhead.',
'Detalhamento aproximado dos tokens de entrada. "Outros" inclui definições de ferramentas e sobrecarga.',
"context.breakdown.system": "Sistema",
"context.breakdown.user": "Usuário",
"context.breakdown.assistant": "Assistente",
"context.breakdown.tool": "Chamadas de Ferramentas",
"context.breakdown.tool": "Chamadas de ferramentas",
"context.breakdown.other": "Outros",
"context.systemPrompt.title": "Prompt do Sistema",
"context.systemPrompt.title": "Prompt do sistema",
"context.rawMessages.title": "Mensagens brutas",
"context.stats.session": "Sessão",
"context.stats.messages": "Mensagens",
"context.stats.provider": "Provedor",
"context.stats.model": "Modelo",
"context.stats.limit": "Limite de Contexto",
"context.stats.totalTokens": "Total de Tokens",
"context.stats.limit": "Limite de contexto",
"context.stats.totalTokens": "Total de tokens",
"context.stats.usage": "Uso",
"context.stats.inputTokens": "Tokens de Entrada",
"context.stats.outputTokens": "Tokens de Saída",
"context.stats.reasoningTokens": "Tokens de Raciocínio",
"context.stats.cacheTokens": "Tokens de Cache (leitura/escrita)",
"context.stats.userMessages": "Mensagens de Usuário",
"context.stats.assistantMessages": "Mensagens do Assistente",
"context.stats.totalCost": "Custo Total",
"context.stats.sessionCreated": "Sessão Criada",
"context.stats.lastActivity": "Última Atividade",
"context.stats.inputTokens": "Tokens de entrada",
"context.stats.outputTokens": "Tokens de saída",
"context.stats.reasoningTokens": "Tokens de raciocínio",
"context.stats.cacheTokens": "Tokens de cache (leitura/escrita)",
"context.stats.userMessages": "Mensagens do usuário",
"context.stats.assistantMessages": "Mensagens do assistente",
"context.stats.totalCost": "Custo total",
"context.stats.sessionCreated": "Sessão criada",
"context.stats.lastActivity": "Última atividade",
"context.usage.tokens": "Tokens",
"context.usage.usage": "Uso",
"context.usage.cost": "Custo",
@@ -497,7 +618,7 @@ export const dict = {
"error.page.title": "Algo deu errado",
"error.page.description": "Ocorreu um erro ao carregar a aplicação.",
"error.page.description.localServerStartup": "Ocorreu um erro ao iniciar o servidor local.",
"error.page.details.label": "Detalhes do Erro",
"error.page.details.label": "Detalhes do erro",
"error.page.action.restart": "Reiniciar",
"error.page.action.report": "Reportar erro",
"error.page.action.reported": "Erro reportado",
@@ -570,7 +691,7 @@ export const dict = {
"session.error.notFound.description": "Esta aba aponta para uma sessão que não existe mais neste servidor.",
"session.error.notFound.closeTab": "Fechar aba",
"session.error.serverConnection": "Não é possível conectar a este servidor",
"session.review.filesChanged": "{{count}} Arquivos Alterados",
"session.review.filesChanged": "{{count}} arquivos alterados",
"session.review.change.one": "Alteração",
"session.review.change.other": "Alterações",
"session.review.loadingChanges": "Carregando alterações...",
@@ -597,14 +718,17 @@ export const dict = {
"session.question.minimize": "Minimizar pergunta",
"session.question.restore": "Restaurar pergunta",
"session.question.pending.one": "{{count}} pergunta pendente",
"session.question.pending.many": "{{count}} de perguntas pendentes",
"session.question.pending.other": "{{count}} perguntas pendentes",
"session.followupDock.summary.one": "{{count}} mensagem na fila",
"session.followupDock.summary.many": "{{count}} de mensagens na fila",
"session.followupDock.summary.other": "{{count}} mensagens na fila",
"session.followupDock.sendNow": "Enviar agora",
"session.followupDock.edit": "Editar",
"session.followupDock.collapse": "Recolher mensagens na fila",
"session.followupDock.expand": "Expandir mensagens na fila",
"session.revertDock.summary.one": "{{count}} mensagem revertida",
"session.revertDock.summary.many": "{{count}} de mensagens revertidas",
"session.revertDock.summary.other": "{{count}} mensagens revertidas",
"session.revertDock.collapse": "Recolher mensagens revertidas",
"session.revertDock.expand": "Expandir mensagens revertidas",
@@ -656,9 +780,16 @@ export const dict = {
"terminal.title": "Terminal",
"terminal.title.numbered": "Terminal {{number}}",
"terminal.close": "Fechar terminal",
"terminal.connectionLost.title": "Conexão Perdida",
"terminal.connectionLost.title": "Conexão perdida",
"terminal.connectionLost.description":
"A conexão do terminal foi interrompida. Isso pode acontecer quando o servidor reinicia.",
"terminal.connectTicket.csrfError":
"O tíquete de conexão PTY foi rejeitado pelas verificações de origem ou CSRF. Verifique a configuração de CORS do servidor.",
"terminal.connectTicket.statusError": "O tíquete de conexão PTY falhou com o status {{status}}",
"titlebar.update": "Atualizar",
"titlebar.updateVersion": "Atualizar {{version}}",
"common.closeTab": "Fechar aba",
"common.dismiss": "Descartar",
"common.requestFailed": "Requisição falhou",
@@ -706,7 +837,7 @@ export const dict = {
"settings.general.row.shell.title": "Shell do terminal",
"settings.general.row.shell.description":
"Escolha o shell usado no terminal. Os shells compatíveis também são usados nas chamadas de ferramentas do agente.",
"settings.general.row.shell.autoDefault": "Automático (Padrão)",
"settings.general.row.shell.autoDefault": "Automático (padrão)",
"settings.general.row.shell.terminalOnly": "somente no terminal",
"settings.general.row.appearance.title": "Aparência",
"settings.general.row.appearance.description": "Personalize como o OpenCode aparece no seu dispositivo",
@@ -739,8 +870,9 @@ export const dict = {
"settings.general.row.mobileTitlebarBottom.title": "Navegação inferior",
"settings.general.row.mobileTitlebarBottom.description":
"Posicionar a barra de título e as abas da sessão na parte inferior da tela em dispositivos móveis",
"settings.general.row.showCustomAgents.title": "Agentes personalizados",
"settings.general.row.showCustomAgents.description": "Mostrar o seletor de agentes na área de composição",
"settings.general.row.showCustomAgents.title": "Mostrar agente",
"settings.general.row.showCustomAgents.description":
"Alternar entre agentes na área de composição. Quando oculto, usa o agente Build como padrão.",
"settings.general.row.reasoningSummaries.title": "Mostrar resumos de raciocínio",
"settings.general.row.reasoningSummaries.description": "Exibir resumos de raciocínio do modelo na linha do tempo",
"settings.general.row.shellToolPartsExpanded.title": "Expandir partes da ferramenta shell",
@@ -823,14 +955,15 @@ export const dict = {
"sound.option.yup06": "Sim 06",
"settings.general.notifications.agent.title": "Agente",
"settings.general.notifications.agent.description":
"Mostrar notificação do sistema quando o agente estiver completo ou precisar de atenção",
"Mostrar notificação do sistema quando o agente concluir o trabalho ou precisar de atenção",
"settings.general.notifications.permissions.title": "Permissões",
"settings.general.notifications.permissions.description":
"Mostrar notificação do sistema quando uma permissão for necessária",
"settings.general.notifications.errors.title": "Erros",
"settings.general.notifications.errors.description": "Mostrar notificação do sistema quando ocorrer um erro",
"settings.general.sounds.agent.title": "Agente",
"settings.general.sounds.agent.description": "Reproduzir som quando o agente estiver completo ou precisar de atenção",
"settings.general.sounds.agent.description":
"Reproduzir som quando o agente concluir o trabalho ou precisar de atenção",
"settings.general.sounds.permissions.title": "Permissões",
"settings.general.sounds.permissions.description": "Reproduzir som quando uma permissão for necessária",
"settings.general.sounds.errors.title": "Erros",
@@ -878,8 +1011,7 @@ export const dict = {
"settings.permissions.tool.read.title": "Ler",
"settings.permissions.tool.read.description": "Ler um arquivo (corresponde ao caminho do arquivo)",
"settings.permissions.tool.edit.title": "Editar",
"settings.permissions.tool.edit.description":
"Modificar arquivos, incluindo edições, escritas, patches e multi-edições",
"settings.permissions.tool.edit.description": "Modificar arquivos, incluindo edições, escritas e patches",
"settings.permissions.tool.glob.title": "Glob",
"settings.permissions.tool.glob.description": "Corresponder arquivos usando padrões glob",
"settings.permissions.tool.grep.title": "Grep",
@@ -889,7 +1021,7 @@ export const dict = {
"settings.permissions.tool.bash.title": "Bash",
"settings.permissions.tool.bash.description": "Executar comandos shell",
"settings.permissions.tool.task.title": "Tarefa",
"settings.permissions.tool.task.description": "Lançar sub-agentes",
"settings.permissions.tool.task.description": "Iniciar subagentes",
"settings.permissions.tool.skill.title": "Habilidade",
"settings.permissions.tool.skill.description": "Carregar uma habilidade por nome",
"settings.permissions.tool.lsp.title": "LSP",
@@ -946,7 +1078,7 @@ export const dict = {
"common.time.hoursAgo.short": "{{count}}h atrás",
"common.time.daysAgo.short": "{{count}}d atrás",
"settings.providers.connected.environmentDescription": "Conectado a partir de suas variáveis de ambiente",
"settings.providers.custom.description": "Adicionar um provedor compatível com a OpenAI através do URL base.",
"settings.providers.custom.description": "Adicionar um provedor compatível com OpenAI por meio da URL base.",
"app.server.unreachable": "Não foi possível conectar a {{server}}",
"app.server.retrying": "Tentando novamente automaticamente...",
@@ -962,6 +1094,9 @@ export const dict = {
"session.question.progress": "{{current}} de {{total}} perguntas",
"session.header.open.finder": "Finder",
"session.header.open.fileExplorer": "Explorador de Arquivos",
"session.header.reveal.finder": "Revelar no Finder",
"session.header.reveal.fileExplorer": "Revelar no Explorador de Arquivos",
"session.header.reveal.containingFolder": "Abrir pasta que contém este item",
"session.header.open.fileManager": "Gerenciador de Arquivos",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -999,6 +1134,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Heap JS usado vs limite de heap. Apenas Chromium.",
"debugBar.mem.tip": "Heap JS usado vs limite de heap. {{used}} de {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Forçar estilos de foco em todos os elementos interativos",
"debugBar.focus.on": "LIGADO",
"debugBar.focus.off": "DESLIGADO",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Forçar a direção do layout de todo o aplicativo sem alterar o idioma selecionado",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
+185 -42
View File
@@ -1,4 +1,104 @@
export const dict = {
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Datoteka",
"desktop.menu.edit": "Uredi",
"desktop.menu.view": "Prikaz",
"desktop.menu.go": "Idi",
"desktop.menu.window": "Prozor",
"desktop.menu.help": "Pomoć",
"desktop.menu.checkForUpdates": "Provjeri ima li ažuriranja...",
"desktop.menu.settings": "Postavke",
"desktop.menu.reloadWebview": "Ponovo učitaj Webview",
"desktop.menu.restart": "Ponovo pokreni",
"desktop.menu.exportLogs": "Izvezi zapisnike...",
"desktop.menu.newSession": "Nova sesija",
"desktop.menu.openProject": "Otvori projekat...",
"desktop.menu.newWindow": "Novi prozor",
"desktop.menu.closeWindow": "Zatvori prozor",
"desktop.menu.undo": "Poništi",
"desktop.menu.redo": "Vrati",
"desktop.menu.cut": "Izreži",
"desktop.menu.copy": "Kopiraj",
"desktop.menu.paste": "Zalijepi",
"desktop.menu.delete": "Izbriši",
"desktop.menu.selectAll": "Odaberi sve",
"desktop.menu.toggleSidebar": "Prikaži ili sakrij bočnu traku",
"desktop.menu.toggleTerminal": "Prikaži ili sakrij terminal",
"desktop.menu.toggleFileTree": "Prikaži ili sakrij stablo datoteka",
"desktop.menu.reload": "Ponovo učitaj",
"desktop.menu.toggleDeveloperTools": "Prikaži ili sakrij alate za programere",
"desktop.menu.actualSize": "Stvarna veličina",
"desktop.menu.zoomIn": "Uvećaj",
"desktop.menu.zoomOut": "Umanji",
"desktop.menu.toggleFullScreen": "Prikaži ili sakrij prikaz preko cijelog ekrana",
"desktop.menu.back": "Nazad",
"desktop.menu.forward": "Naprijed",
"desktop.menu.previousSession": "Prethodna sesija",
"desktop.menu.nextSession": "Sljedeća sesija",
"desktop.menu.previousProject": "Prethodni projekat",
"desktop.menu.nextProject": "Sljedeći projekat",
"desktop.menu.minimize": "Minimiziraj",
"desktop.menu.maximize": "Maksimiziraj",
"desktop.menu.documentation": "Dokumentacija za OpenCode",
"desktop.menu.supportForum": "Forum za podršku",
"desktop.menu.shareFeedback": "Pošalji povratne informacije",
"desktop.menu.reportBug": "Prijavi grešku",
"desktop.menu.ariaLabel": "OpenCode meni",
"desktop.updater.dialog.checkFailed.message": "Provjera ažuriranja nije uspjela.",
"desktop.updater.dialog.checkFailed.title": "Greška pri ažuriranju",
"desktop.updater.dialog.upToDate.message": "Sve je ažurno.",
"desktop.updater.dialog.upToDate.title": "Nema ažuriranja",
"desktop.updater.dialog.ready.message":
"Ažuriranje {{version}} je preuzeto. Želiš li sada ponovo pokrenuti aplikaciju?",
"desktop.updater.dialog.ready.title": "Ažuriranje je spremno",
"desktop.updater.dialog.restart": "Ponovo pokreni",
"desktop.updater.dialog.later": "Kasnije",
"desktop.recovery.action.relaunch": "Ponovo pokreni",
"desktop.recovery.action.exportLogs": "Izvezi zapisnike",
"desktop.recovery.action.keepWaiting": "Nastavi čekati",
"desktop.recovery.action.quit": "Izađi",
"desktop.recovery.loadFailed": "OpenCode se nije uspio učitati",
"desktop.recovery.terminated": "Prozor OpenCode-a neočekivano je zatvoren",
"desktop.recovery.unresponsive": "OpenCode ne reaguje",
"desktop.recovery.unresponsive.detail": "Možeš ponovo pokrenuti aplikaciju, otvoriti zapisnike ili nastaviti čekati.",
"desktop.recovery.loadFailed.detail": "Prozor: {{window}}\nURL: {{url}}\nGreška: {{code}} {{description}}",
"desktop.recovery.terminated.detail": "Prozor: {{window}}\nRazlog: {{reason}}\nKod: {{code}}",
"desktop.recovery.unknown": "<nepoznato>",
"desktop.dialog.chooseFolder": "Odaberi fasciklu",
"desktop.dialog.chooseFile": "Odaberi datoteku",
"desktop.dialog.saveFile": "Sačuvaj datoteku",
"desktop.dialog.files": "Datoteke",
"desktop.server.local": "Lokalni server",
"desktop.wsl.error.windowsOnly": "WSL je dostupan samo u Windowsu",
"desktop.wsl.error.unavailable": "WSL nije dostupan",
"desktop.wsl.error.listInstalled": "Nije uspjelo prikazivanje instaliranih WSL distribucija",
"desktop.wsl.error.listOnline": "Nije uspjelo prikazivanje dostupnih WSL distribucija",
"desktop.wsl.error.executeDistro": "Nije moguće izvršiti komande u distribuciji",
"desktop.wsl.error.installWsl": "Instalacija WSL-a nije uspjela",
"desktop.wsl.error.installDistro": "Instalacija distribucije nije uspjela: {{distro}}",
"desktop.wsl.error.installOpencode": "Instalacija OpenCode-a nije uspjela",
"desktop.wsl.error.alreadyAdded": "Distribucija {{distro}} je već dodana",
"desktop.wsl.error.opencodeMissing": "opencode nije instaliran u ovoj distribuciji",
"desktop.wsl.error.opencodeCannotRun": "opencode je instaliran, ali se ne može pokrenuti",
"desktop.wsl.error.opencodeNotInstalled": "OpenCode nije instaliran u distribuciji {{distro}}",
"desktop.wsl.error.updateVersion":
"Ažuriranje OpenCode-a je završeno, ali {{distro}} i dalje prijavljuje {{installed}}; očekivano je {{expected}}",
"desktop.wsl.error.noVersion": "nema verzije",
"desktop.wsl.error.serverExited": "WSL server se zatvorio nakon pokretanja (code={{code}} signal={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"WSL server se zatvorio prije nego što je postao dostupan (code={{code}} signal={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout":
"Isteklo je vrijeme provjere dostupnosti komponente Sidecar za {{distro}} nakon {{timeout}} ms",
"desktop.wsl.error.commandTimeout": "Isteklo je vrijeme za {{command}} {{args}} nakon {{timeout}} ms",
"desktop.wsl.error.failedPort": "Nije uspjelo dohvaćanje porta",
"desktop.picker.error.notSelected": "Datoteka nije odabrana u izborniku",
"desktop.picker.error.sizeLimit": "Odabrani prilozi premašuju ograničenje od {{limit}} MB",
"command.category.suggested": "Predloženo",
"command.category.view": "Prikaz",
"command.category.project": "Projekat",
@@ -16,6 +116,7 @@ export const dict = {
"command.category.permissions": "Dozvole",
"command.category.workspace": "Radni prostor",
"command.category.settings": "Postavke",
"command.logs.export": "Izvezi zapisnike",
"theme.scheme.system": "Sistem",
"theme.scheme.light": "Svijetlo",
@@ -102,6 +203,7 @@ export const dict = {
"dialog.provider.empty": "Nema pronađenih provajdera",
"dialog.provider.group.popular": "Popularno",
"dialog.provider.group.other": "Ostalo",
"dialog.provider.custom.label": "Prilagođeni provajder kompatibilan s OpenAI-jem",
"dialog.provider.tag.recommended": "Preporučeno",
"dialog.provider.opencode.note": "Kurirani modeli uključujući Claude, GPT, Gemini i druge",
"dialog.provider.opencode.tagline": "Pouzdani optimizovani modeli",
@@ -122,6 +224,7 @@ export const dict = {
"dialog.model.unpaid.freeModels.title": "Besplatni modeli koje obezbjeđuje OpenCode",
"dialog.model.unpaid.addMore.title": "Dodaj još modela od popularnih provajdera",
"dialog.model.unpaid.viewMoreProviders": "Pogledaj još više od 70 provajdera",
"dialog.provider.viewAll": "Prikaži više provajdera",
@@ -129,6 +232,8 @@ export const dict = {
"provider.connect.title.anthropicProMax": "Prijavi se putem Claude Pro/Max",
"provider.connect.selectMethod": "Odaberi način prijave za {{provider}}.",
"provider.connect.method.apiKey": "API ključ",
"provider.connect.method.browser": "Preglednik",
"provider.connect.method.headless": "Bez grafičkog interfejsa",
"provider.connect.status.inProgress": "Autorizacija je u toku...",
"provider.connect.status.waiting": "Čekanje na autorizaciju...",
"provider.connect.status.failed": "Autorizacija nije uspjela: {{error}}",
@@ -161,6 +266,7 @@ export const dict = {
"provider.connect.toast.connected.description": "{{provider}} modeli su sada dostupni za korištenje.",
"provider.custom.title": "Prilagođeni provajder",
"provider.custom.unavailable": "Prilagođeni provajderi nisu dostupni na ovom serveru",
"provider.custom.description.prefix": "Konfiguriši OpenAI-kompatibilnog provajdera. Pogledaj ",
"provider.custom.description.link": "dokumentaciju za konfiguraciju provajdera",
"provider.custom.description.suffix": ".",
@@ -232,7 +338,7 @@ export const dict = {
"common.clear": "Očisti",
"common.connect": "Poveži",
"common.disconnect": "Prekini vezu",
"common.continue": "Pošalji",
"common.continue": "Nastavi",
"common.submit": "Pošalji",
"common.save": "Sačuvaj",
"common.saving": "Čuvanje...",
@@ -263,7 +369,7 @@ export const dict = {
"prompt.example.11": "Optimizuj upite prema bazi podataka",
"prompt.example.12": "Dodaj validaciju ulaza",
"prompt.example.13": "Napravi novu komponentu za...",
"prompt.example.14": "Kako da deployam ovaj projekat?",
"prompt.example.14": "Kako da postavim ovaj projekat?",
"prompt.example.15": "Pregledaj moj kod prema najboljim praksama",
"prompt.example.16": "Dodaj obradu grešaka u ovu funkciju",
"prompt.example.17": "Objasni ovaj regex obrazac",
@@ -271,14 +377,14 @@ export const dict = {
"prompt.example.19": "Dodaj logovanje kroz cijelu bazu koda",
"prompt.example.20": "Koje su zavisnosti zastarjele?",
"prompt.example.21": "Pomozi mi da napišem migracijsku skriptu",
"prompt.example.22": "Implementiraj keširanje za ovaj endpoint",
"prompt.example.22": "Implementiraj keširanje za ovu krajnju tačku",
"prompt.example.23": "Dodaj paginaciju u ovu listu",
"prompt.example.24": "Napravi CLI komandu za...",
"prompt.example.25": "Kako ovdje rade varijable okruženja?",
"prompt.popover.emptyResults": "Nema rezultata",
"prompt.popover.emptyCommands": "Nema komandi",
"prompt.dropzone.label": "Ovdje prevucite slike, PDF-ove ili tekstualne datoteke",
"prompt.dropzone.label": "Ovdje prevuci slike, PDF-ove ili tekstualne datoteke",
"prompt.dropzone.file.label": "Spusti za @spominjanje datoteke",
"prompt.slash.badge.custom": "prilagođeno",
"prompt.slash.badge.skill": "skill",
@@ -287,7 +393,7 @@ export const dict = {
"prompt.context.includeActiveFile": "Uključi aktivnu datoteku",
"prompt.context.removeActiveFile": "Ukloni aktivnu datoteku iz konteksta",
"prompt.context.removeFile": "Ukloni datoteku iz konteksta",
"prompt.action.attachFile": "Priloži datoteku",
"prompt.action.attachFile": "Dodaj datoteke",
"prompt.menu.addImagesAndFiles": "Dodaj datoteke i više",
"prompt.menu.imagesAndFiles": "Slike i datoteke",
"prompt.menu.commands": "Komande",
@@ -311,7 +417,7 @@ export const dict = {
"dialog.mcp.title": "MCP-ovi",
"dialog.mcp.description": "{{enabled}} od {{total}} omogućeno",
"dialog.mcp.empty": "Nema konfigurisnih MCP-ova",
"dialog.mcp.empty": "Nema konfigurisanih MCP-ova",
"dialog.lsp.empty": "LSP-ovi se automatski otkrivaju prema tipu datoteke",
"dialog.plugins.empty": "Plugini su konfigurisani u opencode.json",
@@ -319,18 +425,18 @@ export const dict = {
"mcp.status.connected": "povezano",
"mcp.status.failed": "neuspjelo",
"mcp.status.needs_auth": "potrebna autentifikacija",
"mcp.auth.clickToAuthenticate": "Kliknite za autentifikaciju",
"mcp.auth.clickToAuthenticate": "Klikni za autentifikaciju",
"mcp.status.disabled": "onemogućeno",
"dialog.fork.empty": "Nema poruka za fork",
"dialog.directory.search.placeholder": "Pretraži foldere",
"dialog.directory.empty": "Nema pronađenih foldera",
"dialog.directory.search.placeholder": "Pretraži fascikle",
"dialog.directory.empty": "Nema pronađenih fascikli",
"dialog.directory.action.selectFile": "Odaberi datoteku",
"dialog.directory.action.selectFolder": "Odaberi folder",
"dialog.directory.action.selectFolder": "Odaberi fasciklu",
"dialog.directory.root": "Korijen",
"dialog.directory.parent": "Nadređeni folder",
"dialog.directory.readError": "Nije moguće pročitati ovaj folder",
"dialog.directory.parent": "Nadređena fascikla",
"dialog.directory.readError": "Nije moguće pročitati ovu fasciklu",
"dialog.server.title": "Serveri",
"dialog.server.description": "Promijeni na koji se OpenCode server ova aplikacija povezuje.",
@@ -349,7 +455,7 @@ export const dict = {
"dialog.server.edit.title": "Uredi server",
"dialog.server.default.title": "Podrazumijevani server",
"dialog.server.default.description":
"Poveži se na ovaj server pri pokretanju aplikacije umjesto pokretanja lokalnog servera. Potreban je restart.",
"Poveži se na ovaj server pri pokretanju aplikacije umjesto pokretanja lokalnog servera. Potrebno je ponovo pokrenuti aplikaciju.",
"dialog.server.default.none": "Nije odabran server",
"dialog.server.default.set": "Postavi trenutni server kao podrazumijevani",
"dialog.server.default.clear": "Očisti",
@@ -431,6 +537,22 @@ export const dict = {
"wsl.onboarding.versionMismatch": "Instalirana verzija ne odgovara verziji desktop aplikacije.",
"wsl.onboarding.adding": "Dodavanje...",
"help.tabs.toast.ariaLabel": "Predstavljamo kartice. Organizuj svoj rad i aktivne sesije pomoću kartica",
"help.tabs.toast.dismiss": "Odbaci informacije o karticama",
"help.tabs.title": "Predstavljamo kartice",
"help.tabs.description": "Organizuj svoj rad i aktivne sesije pomoću kartica",
"help.tabs.date": "14. juli",
"help.tabs.introduction": "OpenCode Desktop sada je organizovan oko kartica.",
"help.tabs.sessions":
"Započni novu sesiju u kartici ili otvori postojeću sesiju iz bilo kojeg projekta. Otvori novu karticu kada započinješ nešto novo, a zatvori je kada završiš.",
"help.tabs.organize":
"Nekoliko otvorenih kartica olakšava organizovanje aktivnih sesija. Preimenuj kartice tako da ih možeš lako prepoznati ako ih namjeravaš zadržati.",
"help.tabs.home":
"Sve svoje sesije i projekte pronaći ćeš na novom početnom ekranu. Odabirom sesije ona se otvara u kartici.",
"help.tabs.persistence": "Kada ponovo otvoriš aplikaciju, tvoje kartice ostaju otvorene.",
"help.tabs.worktrees":
"Novi dizajn još ne podržava Git Worktrees, ali podrška stiže uskoro. Ako želiš nastaviti koristiti prethodni raspored, možeš mijenjati rasporede u Postavkama. Imaj na umu da će novi raspored za nekoliko sedmica postati trajan.",
"dialog.project.edit.title": "Uredi projekat",
"dialog.project.edit.name": "Naziv",
"dialog.project.edit.icon": "Ikonica",
@@ -445,7 +567,7 @@ export const dict = {
"context.breakdown.title": "Razlaganje konteksta",
"context.breakdown.note":
'Približna raspodjela ulaznih tokena. "Ostalo" uključuje definicije alata i dodatni overhead.',
'Približna raspodjela ulaznih tokena. "Ostalo" uključuje definicije alata i dodatno opterećenje.',
"context.breakdown.system": "Sistem",
"context.breakdown.user": "Korisnik",
"context.breakdown.assistant": "Asistent",
@@ -465,7 +587,7 @@ export const dict = {
"context.stats.inputTokens": "Ulazni tokeni",
"context.stats.outputTokens": "Izlazni tokeni",
"context.stats.reasoningTokens": "Tokeni za rasuđivanje",
"context.stats.cacheTokens": "Cache tokeni (čitanje/pisanje)",
"context.stats.cacheTokens": "Keširani tokeni (čitanje/pisanje)",
"context.stats.userMessages": "Korisničke poruke",
"context.stats.assistantMessages": "Poruke asistenta",
"context.stats.totalCost": "Ukupni trošak",
@@ -537,14 +659,14 @@ export const dict = {
"toast.update.title": "Dostupno ažuriranje",
"toast.update.description": "Nova verzija OpenCode-a ({{version}}) je dostupna za instalaciju.",
"toast.update.action.installRestart": "Instaliraj i restartuj",
"toast.update.action.installRestart": "Instaliraj i ponovo pokreni",
"toast.update.action.notYet": "Ne još",
"error.page.title": "Nešto je pošlo po zlu",
"error.page.description": "Došlo je do greške prilikom učitavanja aplikacije.",
"error.page.description.localServerStartup": "Došlo je do greške pri pokretanju lokalnog servera.",
"error.page.details.label": "Detalji greške",
"error.page.action.restart": "Restartuj",
"error.page.action.restart": "Ponovo pokreni",
"error.page.action.report": "Prijavi grešku",
"error.page.action.reported": "Greška prijavljena",
"error.page.action.exportLogs": "Izvezi logove",
@@ -569,7 +691,7 @@ export const dict = {
"error.chain.responseBody": "Tijelo odgovora:\n{{body}}",
"error.chain.didYouMean": "Da li si mislio: {{suggestions}}",
"error.chain.modelNotFound": "Model nije pronađen: {{provider}}/{{model}}",
"error.chain.checkConfig": "Provjeri konfiguraciju (opencode.json) provider/model names",
"error.chain.checkConfig": "Provjeri nazive provajdera/modela u konfiguraciji (opencode.json)",
"error.chain.mcpFailed": 'MCP server "{{name}}" nije uspio. Napomena: OpenCode još ne podržava MCP autentifikaciju.',
"error.chain.providerAuthFailed": "Autentifikacija provajdera nije uspjela ({{provider}}): {{message}}",
"error.chain.providerInitFailed":
@@ -611,7 +733,7 @@ export const dict = {
"home.sessions.group.yesterday": "Jučer",
"home.sessions.group.older": "Starije",
"home.providerTip":
"Povežite se s više od 75 pružalaca usluga kako biste koristili druge modele, uključujući Claude, GPT, Gemini i druge",
"Poveži se s više od 75 provajdera da koristiš druge modele, uključujući Claude, GPT, Gemini i druge",
"session.tab.session": "Sesija",
"session.tab.review": "Pregled",
@@ -627,11 +749,11 @@ export const dict = {
"session.review.change.other": "Izmjene",
"session.review.loadingChanges": "Učitavanje izmjena...",
"session.review.empty": "Još nema izmjena u ovoj sesiji",
"session.review.noVcs": "Nije detektovan Git sistem kontrole verzija, promjene se ne prikazuju",
"session.review.noVcs": "Nije otkriven Git sistem za kontrolu verzija, pa se promjene ne prikazuju",
"session.review.noSnapshot":
"Praćenje snimaka (snapshot) je onemogućeno u konfiguraciji, pa promjene sesije nisu dostupne",
"session.review.noChanges": "Nema izmjena",
"session.review.noUncommittedChanges": "Još nema nepotvrđenih promjena",
"session.review.noUncommittedChanges": "Još nema promjena koje nisu commitovane",
"session.review.noBranchChanges": "Još nema promjena na grani",
"session.files.selectToOpen": "Odaberi datoteku za otvaranje",
@@ -652,14 +774,17 @@ export const dict = {
"session.question.minimize": "Minimiziraj pitanje",
"session.question.restore": "Vrati pitanje",
"session.question.pending.one": "{{count}} pitanje na čekanju",
"session.question.pending.few": "{{count}} pitanja na čekanju",
"session.question.pending.other": "{{count}} pitanja na čekanju",
"session.followupDock.summary.one": "{{count}} poruka na čekanju",
"session.followupDock.summary.few": "{{count}} poruke na čekanju",
"session.followupDock.summary.other": "{{count}} poruka na čekanju",
"session.followupDock.sendNow": "Pošalji sada",
"session.followupDock.edit": "Uredi",
"session.followupDock.collapse": "Sažmi poruke na čekanju",
"session.followupDock.expand": "Proširi poruke na čekanju",
"session.revertDock.summary.one": "{{count}} vraćena poruka",
"session.revertDock.summary.few": "{{count}} vraćene poruke",
"session.revertDock.summary.other": "{{count}} vraćenih poruka",
"session.revertDock.collapse": "Sažmi vraćene poruke",
"session.revertDock.expand": "Proširi vraćene poruke",
@@ -717,7 +842,13 @@ export const dict = {
"terminal.close": "Zatvori terminal",
"terminal.connectionLost.title": "Veza prekinuta",
"terminal.connectionLost.description":
"Veza s terminalom je prekinuta. Ovo se može desiti kada se server restartuje.",
"Veza s terminalom je prekinuta. Ovo se može desiti kada se server ponovo pokrene.",
"terminal.connectTicket.csrfError":
"PTY tiket za povezivanje odbijen je zbog provjera porijekla ili CSRF-a. Provjeri CORS konfiguraciju servera.",
"terminal.connectTicket.statusError": "PTY tiket za povezivanje nije uspio sa statusom {{status}}",
"titlebar.update": "Ažuriraj",
"titlebar.updateVersion": "Ažuriraj {{version}}",
"common.closeTab": "Zatvori karticu",
"common.dismiss": "Odbaci",
@@ -725,7 +856,7 @@ export const dict = {
"common.moreOptions": "Više opcija",
"common.learnMore": "Saznaj više",
"common.rename": "Preimenuj",
"common.reset": "Resetuj",
"common.reset": "Vrati na početno stanje",
"common.archive": "Arhiviraj",
"common.delete": "Izbriši",
"common.close": "Zatvori",
@@ -782,7 +913,7 @@ export const dict = {
"settings.general.row.font.title": "Font za kod",
"settings.general.row.font.description": "Prilagodi font koji se koristi u blokovima koda",
"settings.general.row.terminalFont.title": "Font terminala",
"settings.general.row.terminalFont.description": "Prilagodite font koji se koristi u terminalu",
"settings.general.row.terminalFont.description": "Prilagodi font koji se koristi u terminalu",
"settings.general.row.uiFont.title": "UI font",
"settings.general.row.uiFont.description": "Prilagodi font koji se koristi u cijelom interfejsu",
"settings.general.row.followup.title": "Ponašanje nadovezivanja",
@@ -817,15 +948,16 @@ export const dict = {
"settings.general.row.newInterface.title": "Novi raspored",
"settings.general.row.newInterface.badge": "Novo",
"settings.general.row.newInterface.description":
"Koristite nove kartice i raspored početne stranice. Ograničeno vrijeme možete se prebacivati između rasporeda.",
"settings.general.row.newInterfaceNotice.title": "Sada koristite novi raspored",
"Koristi nove kartice i raspored početne stranice. Ograničeno vrijeme možeš se prebacivati između rasporeda.",
"settings.general.row.newInterfaceNotice.title": "Sada koristiš novi raspored",
"settings.general.row.newInterfaceNotice.description": "Prethodni raspored više nije dostupan",
"settings.general.row.newInterfaceNotice.dismiss": "Odbaci",
"settings.general.row.pinchZoom.title": "Zumiranje štipanjem",
"settings.general.row.pinchZoom.description":
"Dozvoli zumiranje gestom štipanja na dodirnoj ploči i pomoću Ctrl-pomjeranja",
"settings.general.row.wayland.title": "Koristi nativni Wayland",
"settings.general.row.wayland.description": "Onemogući X11 fallback na Waylandu. Zahtijeva restart.",
"settings.general.row.wayland.description":
"Onemogući rezervni X11 način rada na Waylandu. Zahtijeva ponovno pokretanje.",
"settings.general.row.wayland.tooltip":
"Na Linuxu sa monitorima miješanih stopa osvježavanja, nativni Wayland može biti stabilniji.",
@@ -941,7 +1073,7 @@ export const dict = {
"settings.mcp.description": "MCP postavke će se ovdje moći podešavati.",
"settings.permissions.title": "Dozvole",
"settings.permissions.description": "Kontroliši koje alate server smije koristiti po defaultu.",
"settings.permissions.description": "Kontroliši koje alate server smije koristiti zadano.",
"settings.permissions.section.tools": "Alati",
"settings.permissions.toast.updateFailed.title": "Neuspjelo ažuriranje dozvola",
@@ -953,7 +1085,7 @@ export const dict = {
"settings.permissions.tool.read.description": "Čitanje datoteke (podudara se s putanjom datoteke)",
"settings.permissions.tool.edit.title": "Uređivanje",
"settings.permissions.tool.edit.description":
"Mijenjanje datoteka, uključujući izmjene, pisanja, patch-eve i multi-izmjene",
"Mijenjanje datoteka, uključujući uređivanje, pisanje, zakrpe i višestruke izmjene",
"settings.permissions.tool.glob.title": "Glob",
"settings.permissions.tool.glob.description": "Podudaranje datoteka pomoću glob šablona",
"settings.permissions.tool.grep.title": "Grep",
@@ -989,26 +1121,26 @@ export const dict = {
"workspace.type.sandbox": "sandbox",
"workspace.create.failed.title": "Neuspješno kreiranje radnog prostora",
"workspace.delete.failed.title": "Neuspješno brisanje radnog prostora",
"workspace.resetting.title": "Resetovanje radnog prostora",
"workspace.resetting.title": "Vraćanje radnog prostora na početno stanje",
"workspace.resetting.description": "Ovo može potrajati minut.",
"workspace.reset.failed.title": "Neuspješno resetovanje radnog prostora",
"workspace.reset.success.title": "Radni prostor resetovan",
"workspace.reset.failed.title": "Neuspješno vraćanje radnog prostora na početno stanje",
"workspace.reset.success.title": "Radni prostor vraćen na početno stanje",
"workspace.reset.success.description": "Radni prostor sada odgovara podrazumijevanoj grani.",
"workspace.error.stillPreparing": "Radni prostor se još priprema",
"workspace.status.checking": "Provjera neobjedinjenih promjena...",
"workspace.status.checking": "Provjera promjena koje nisu commitovane...",
"workspace.status.error": "Nije moguće provjeriti git status.",
"workspace.status.clean": "Nisu pronađene neobjedinjene promjene.",
"workspace.status.dirty": "Pronađene su neobjedinjene promjene u ovom radnom prostoru.",
"workspace.status.clean": "Nisu pronađene promjene koje nisu commitovane.",
"workspace.status.dirty": "Pronađene su promjene koje nisu commitovane u ovom radnom prostoru.",
"workspace.delete.title": "Izbriši radni prostor",
"workspace.delete.confirm": 'Izbriši radni prostor "{{name}}"?',
"workspace.delete.button": "Izbriši radni prostor",
"workspace.reset.title": "Resetuj radni prostor",
"workspace.reset.confirm": 'Resetuj radni prostor "{{name}}"?',
"workspace.reset.button": "Resetuj radni prostor",
"workspace.reset.title": "Vrati radni prostor na početno stanje",
"workspace.reset.confirm": 'Vrati radni prostor "{{name}}" na početno stanje?',
"workspace.reset.button": "Vrati radni prostor na početno stanje",
"workspace.reset.archived.none": "Nijedna aktivna sesija neće biti arhivirana.",
"workspace.reset.archived.one": "1 sesija će biti arhivirana.",
"workspace.reset.archived.many": "Biće arhivirano {{count}} sesija.",
"workspace.reset.note": "Ovo će resetovati radni prostor da odgovara podrazumijevanoj grani.",
"workspace.reset.note": "Ovo će vratiti radni prostor na stanje podrazumijevane grane.",
"common.open": "Otvori",
"dialog.releaseNotes.action.getStarted": "Započni",
"dialog.releaseNotes.action.next": "Sljedeće",
@@ -1021,8 +1153,8 @@ export const dict = {
"common.time.minutesAgo.short": "prije {{count}} min",
"common.time.hoursAgo.short": "prije {{count}} h",
"common.time.daysAgo.short": "prije {{count}} d",
"settings.providers.connected.environmentDescription": "Povezano sa vašim varijablama okruženja",
"settings.providers.custom.description": "Dodajte provajdera kompatibilnog s OpenAI putem osnovnog URL-a.",
"settings.providers.connected.environmentDescription": "Povezano s tvojim varijablama okruženja",
"settings.providers.custom.description": "Dodaj provajdera kompatibilnog s OpenAI putem baznog URL-a.",
"app.server.unreachable": "Nije moguće pristupiti {{server}}",
"app.server.retrying": "Automatski ponovni pokušaj...",
@@ -1031,13 +1163,16 @@ export const dict = {
"dialog.server.add.passwordPlaceholder": "lozinka",
"server.row.noUsername": "nema korisničkog imena",
"session.review.noVcs.createGit.title": "Kreiraj Git repozitorij",
"session.review.noVcs.createGit.description": "Pratite, pregledajte i poništite promjene u ovom projektu",
"session.review.noVcs.createGit.description": "Prati, pregledaj i poništi promjene u ovom projektu",
"session.review.noVcs.createGit.actionLoading": "Kreiranje Git repozitorija...",
"session.review.noVcs.createGit.action": "Kreiraj Git repozitorij",
"session.todo.progress": "{{done}} od {{total}} zadataka završeno",
"session.question.progress": "{{current}} od {{total}} pitanja",
"session.header.open.finder": "Finder",
"session.header.open.fileExplorer": "File Explorer",
"session.header.reveal.finder": "Prikaži u Finderu",
"session.header.reveal.fileExplorer": "Prikaži u File Exploreru",
"session.header.reveal.containingFolder": "Otvori fasciklu koja sadrži ovu stavku",
"session.header.open.fileManager": "File Manager",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -1075,6 +1210,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Korišteni JS heap naspram limita heapa. Samo Chromium.",
"debugBar.mem.tip": "Korišteni JS heap naspram limita heapa. {{used}} od {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Prisilno primijeni stilove fokusa na sve interaktivne elemente",
"debugBar.focus.on": "UKLJUČENO",
"debugBar.focus.off": "ISKLJUČENO",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Prisilno postavi smjer rasporeda cijele aplikacije bez promjene odabranog jezika",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
+180 -38
View File
@@ -102,6 +102,7 @@ export const dict = {
"dialog.provider.empty": "Ingen udbydere fundet",
"dialog.provider.group.popular": "Populære",
"dialog.provider.group.other": "Andre",
"dialog.provider.custom.label": "Brugerdefineret OpenAI-kompatibel udbyder",
"dialog.provider.tag.recommended": "Anbefalet",
"dialog.provider.opencode.note": "Udvalgte modeller inklusive Claude, GPT, Gemini og flere",
"dialog.provider.opencode.tagline": "Pålidelige optimerede modeller",
@@ -122,6 +123,7 @@ export const dict = {
"dialog.model.unpaid.freeModels.title": "Gratis modeller leveret af OpenCode",
"dialog.model.unpaid.addMore.title": "Tilføj flere modeller fra populære udbydere",
"dialog.model.unpaid.viewMoreProviders": "Se mere end 70 yderligere udbydere",
"dialog.provider.viewAll": "Vis flere udbydere",
@@ -129,12 +131,14 @@ export const dict = {
"provider.connect.title.anthropicProMax": "Log ind med Claude Pro/Max",
"provider.connect.selectMethod": "Vælg loginmetode for {{provider}}.",
"provider.connect.method.apiKey": "API-nøgle",
"provider.connect.method.browser": "Browser",
"provider.connect.method.headless": "Browserløs",
"provider.connect.status.inProgress": "Godkendelse i gang...",
"provider.connect.status.waiting": "Venter på godkendelse...",
"provider.connect.status.failed": "Godkendelse mislykkedes: {{error}}",
"provider.connect.apiKey.description":
"Indtast din {{provider}} API-nøgle for at forbinde din konto og bruge {{provider}} modeller i OpenCode.",
"provider.connect.apiKey.label": "{{provider}} API-nøgle",
"Indtast din API-nøgle til {{provider}} for at forbinde din konto og bruge modeller fra {{provider}} i OpenCode.",
"provider.connect.apiKey.label": "API-nøgle til {{provider}}",
"provider.connect.apiKey.placeholder": "API-nøgle",
"provider.connect.apiKey.required": "API-nøgle er påkrævet",
"provider.connect.opencodeZen.line1":
@@ -147,7 +151,7 @@ export const dict = {
"provider.connect.oauth.code.visit.prefix": "Besøg ",
"provider.connect.oauth.code.visit.link": "dette link",
"provider.connect.oauth.code.visit.suffix":
" for at hente din godkendelseskode for at forbinde din konto og bruge {{provider}} modeller i OpenCode.",
" for at hente din godkendelseskode, forbinde din konto og bruge modeller fra {{provider}} i OpenCode.",
"provider.connect.oauth.code.label": "{{method}} godkendelseskode",
"provider.connect.oauth.code.placeholder": "Godkendelseskode",
"provider.connect.oauth.code.required": "Godkendelseskode er påkrævet",
@@ -155,12 +159,13 @@ export const dict = {
"provider.connect.oauth.auto.visit.prefix": "Besøg ",
"provider.connect.oauth.auto.visit.link": "dette link",
"provider.connect.oauth.auto.visit.suffix":
" og indtast koden nedenfor for at forbinde din konto og bruge {{provider}} modeller i OpenCode.",
" og indtast koden nedenfor for at forbinde din konto og bruge modeller fra {{provider}} i OpenCode.",
"provider.connect.oauth.auto.confirmationCode": "Bekræftelseskode",
"provider.connect.toast.connected.title": "{{provider}} forbundet",
"provider.connect.toast.connected.description": "{{provider}} modeller er nu tilgængelige.",
"provider.connect.toast.connected.description": "Modeller fra {{provider}} er nu tilgængelige.",
"provider.custom.title": "Brugerdefineret udbyder",
"provider.custom.unavailable": "Brugerdefinerede udbydere er ikke tilgængelige på denne server",
"provider.custom.description.prefix": "Konfigurer en OpenAI-kompatibel udbyder. Se ",
"provider.custom.description.link": "dokumentation for udbyderkonfiguration",
"provider.custom.description.suffix": ".",
@@ -217,9 +222,9 @@ export const dict = {
"model.tooltip.inputs": "Input",
"model.tooltip.model": "Model",
"model.tooltip.provider": "Udbyder",
"model.tooltip.reasoning": "Tænkning",
"model.tooltip.reasoning.allowed": "Tillader tænkning",
"model.tooltip.reasoning.none": "Ingen tænkning",
"model.tooltip.reasoning": "Ræsonnering",
"model.tooltip.reasoning.allowed": "Tillader ræsonnering",
"model.tooltip.reasoning.none": "Ingen ræsonnering",
"model.tooltip.context": "Kontekstgrænse {{limit}}",
"common.search.placeholder": "Søg",
"common.goBack": "Gå tilbage",
@@ -230,7 +235,7 @@ export const dict = {
"common.clear": "Ryd",
"common.connect": "Forbind",
"common.disconnect": "Frakobl",
"common.continue": "Indsend",
"common.continue": "Fortsæt",
"common.submit": "Indsend",
"common.save": "Gem",
"common.saving": "Gemmer...",
@@ -253,7 +258,7 @@ export const dict = {
"prompt.example.3": "Ret ødelagte tests",
"prompt.example.4": "Forklar hvordan godkendelse fungerer",
"prompt.example.5": "Find og ret sikkerhedshuller",
"prompt.example.6": "Tilføj enhedstests for brugerservice",
"prompt.example.6": "Tilføj enhedstests for brugertjenesten",
"prompt.example.7": "Refaktorer denne funktion så den er mere læsbar",
"prompt.example.8": "Hvad betyder denne fejl?",
"prompt.example.9": "Hjælp mig med at debugge dette problem",
@@ -335,7 +340,7 @@ export const dict = {
"dialog.server.search.placeholder": "Søg servere",
"dialog.server.empty": "Ingen servere endnu",
"dialog.server.add.title": "Tilføj en server",
"dialog.server.add.url": "Server URL",
"dialog.server.add.url": "Serveradresse",
"dialog.server.add.placeholder": "http://localhost:4096",
"dialog.server.add.error": "Kunne ikke forbinde til server",
"dialog.server.add.checking": "Tjekker...",
@@ -347,7 +352,7 @@ export const dict = {
"dialog.server.edit.title": "Rediger server",
"dialog.server.default.title": "Standardserver",
"dialog.server.default.description":
"Forbind til denne server ved start af app i stedet for at starte en lokal server. Kræver genstart.",
"Opret forbindelse til denne server, når appen starter, i stedet for at starte en lokal server. Kræver genstart.",
"dialog.server.default.none": "Ingen server valgt",
"dialog.server.default.set": "Sæt nuværende server som standard",
"dialog.server.default.clear": "Ryd",
@@ -462,8 +467,8 @@ export const dict = {
"context.stats.usage": "Forbrug",
"context.stats.inputTokens": "Input-tokens",
"context.stats.outputTokens": "Output-tokens",
"context.stats.reasoningTokens": "Tænke Tokens",
"context.stats.cacheTokens": "Cache Tokens (læs/skriv)",
"context.stats.reasoningTokens": "Ræsonneringstokens",
"context.stats.cacheTokens": "Cachetokens (læsning/skrivning)",
"context.stats.userMessages": "Brugerbeskeder",
"context.stats.assistantMessages": "Assistentbeskeder",
"context.stats.totalCost": "Samlede omkostninger",
@@ -566,7 +571,7 @@ export const dict = {
"error.chain.responseBody": "Svarindhold:\n{{body}}",
"error.chain.didYouMean": "Mente du: {{suggestions}}",
"error.chain.modelNotFound": "Model ikke fundet: {{provider}}/{{model}}",
"error.chain.checkConfig": "Tjek dine konfigurations (opencode.json) udbyder/modelnavne",
"error.chain.checkConfig": "Kontrollér udbyder- og modelnavnene i din konfiguration (opencode.json)",
"error.chain.mcpFailed": 'MCP-server "{{name}}" fejlede. Bemærk, OpenCode understøtter ikke MCP-godkendelse endnu.',
"error.chain.providerAuthFailed": "Udbydergodkendelse mislykkedes ({{provider}}): {{message}}",
"error.chain.providerInitFailed":
@@ -619,12 +624,12 @@ export const dict = {
"session.error.notFound.description": "Denne fane henviser til en session, der ikke længere findes på denne server.",
"session.error.notFound.closeTab": "Luk fane",
"session.error.serverConnection": "Kan ikke oprette forbindelse til denne server",
"session.review.filesChanged": "{{count}} Filer ændret",
"session.review.filesChanged": "{{count}} ændrede filer",
"session.review.change.one": "Ændring",
"session.review.change.other": "Ændringer",
"session.review.loadingChanges": "Indlæser ændringer...",
"session.review.empty": "Ingen ændringer i denne session endnu",
"session.review.noVcs": "Intet Git versionsstyringssystem fundet, ændringer vises ikke",
"session.review.noVcs": "Intet Git-versionsstyringssystem fundet, ændringer vises ikke",
"session.review.noSnapshot":
"Snapshot-sporing er deaktiveret i konfigurationen, så sessionsændringer er ikke tilgængelige",
"session.review.noChanges": "Ingen ændringer",
@@ -715,6 +720,13 @@ export const dict = {
"terminal.connectionLost.title": "Forbindelse mistet",
"terminal.connectionLost.description": "Terminalforbindelsen blev afbrudt. Dette kan ske, når serveren genstarter.",
"terminal.connectTicket.csrfError":
"PTY-forbindelsesticket blev afvist ved kontrollen af oprindelse eller CSRF. Kontrollér serverens CORS-konfiguration.",
"terminal.connectTicket.statusError": "PTY-forbindelsesticket mislykkedes med {{status}}",
"titlebar.update": "Opdater",
"titlebar.updateVersion": "Opdater {{version}}",
"common.closeTab": "Luk fane",
"common.dismiss": "Afvis",
"common.requestFailed": "Forespørgsel mislykkedes",
@@ -750,7 +762,7 @@ export const dict = {
"settings.tab.general": "Generelt",
"settings.tab.shortcuts": "Genveje",
"settings.desktop.section.wsl": "WSL",
"settings.desktop.wsl.title": "WSL integration",
"settings.desktop.wsl.title": "WSL-integration",
"settings.desktop.wsl.description": "Kør OpenCode-serveren inde i WSL på Windows.",
"settings.general.section.appearance": "Udseende",
@@ -771,15 +783,16 @@ export const dict = {
"settings.general.row.appearance.title": "Udseende",
"settings.general.row.appearance.description": "Tilpas hvordan OpenCode ser ud på din enhed",
"settings.general.row.colorScheme.title": "Farveskema",
"settings.general.row.colorScheme.description": "Vælg om OpenCode følger systemets, lyst eller mørkt tema",
"settings.general.row.colorScheme.description":
"Vælg, om OpenCode skal følge systemtemaet eller bruge et lyst eller mørkt tema",
"settings.general.row.theme.title": "Tema",
"settings.general.row.theme.description": "Tilpas hvordan OpenCode er temabestemt.",
"settings.general.row.theme.description": "Tilpas OpenCodes tema.",
"settings.general.row.font.title": "Kode-skrifttype",
"settings.general.row.font.description": "Tilpas skrifttypen, der bruges i kodeblokke",
"settings.general.row.terminalFont.title": "Terminalskrifttype",
"settings.general.row.terminalFont.description": "Tilpas den skrifttype, der bruges i terminalen",
"settings.general.row.uiFont.title": "UI-skrifttype",
"settings.general.row.uiFont.description": "Tilpas skrifttypen, der bruges i hele brugerfladen",
"settings.general.row.uiFont.description": "Tilpas skrifttypen, der bruges i hele brugergrænsefladen",
"settings.general.row.followup.title": "Opfølgningsadfærd",
"settings.general.row.followup.description": "Vælg om opfølgende forespørgsler skal styre straks eller vente i kø",
"settings.general.row.followup.option.queue": "Kø",
@@ -797,10 +810,11 @@ export const dict = {
"settings.general.row.mobileTitlebarBottom.title": "Navigation nederst",
"settings.general.row.mobileTitlebarBottom.description":
"Placer titellinjen og sessionsfanerne nederst på skærmen på mobilenheder",
"settings.general.row.showCustomAgents.title": "Brugerdefinerede agenter",
"settings.general.row.showCustomAgents.description": "Vis agentvælgeren i promptfeltet",
"settings.general.row.reasoningSummaries.title": "Vis tænkeoversigter",
"settings.general.row.reasoningSummaries.description": "Vis model tænkeoversigter i tidslinjen",
"settings.general.row.showCustomAgents.title": "Vis agent",
"settings.general.row.showCustomAgents.description":
"Skift mellem agenter i promptfeltet. Når vælgeren er skjult, bruges Build-agenten som standard.",
"settings.general.row.reasoningSummaries.title": "Vis ræsonneringsoversigter",
"settings.general.row.reasoningSummaries.description": "Vis oversigter over modellens ræsonnering på tidslinjen",
"settings.general.row.shellToolPartsExpanded.title": "Udvid shell-værktøjsdele",
"settings.general.row.shellToolPartsExpanded.description": "Vis shell-værktøjsdele udvidet som standard i tidslinjen",
@@ -816,13 +830,13 @@ export const dict = {
"settings.general.row.newInterfaceNotice.dismiss": "Afvis",
"settings.general.row.pinchZoom.title": "Knib for at zoome",
"settings.general.row.pinchZoom.description": "Tillad knibebevægelser på pegefeltet og Ctrl-rulning for at zoome",
"settings.general.row.wayland.title": "Brug native Wayland",
"settings.general.row.wayland.title": "Brug indbygget Wayland",
"settings.general.row.wayland.description": "Deaktiver X11-fallback på Wayland. Kræver genstart.",
"settings.general.row.wayland.tooltip":
"På Linux med skærme med blandet opdateringshastighed kan native Wayland være mere stabilt.",
"På Linux med skærme med forskellige opdateringshastigheder kan indbygget Wayland være mere stabilt.",
"settings.general.row.releaseNotes.title": "Udgivelsesnoter",
"settings.general.row.releaseNotes.description": 'Vis "Hvad er nyt"-popups efter opdateringer',
"settings.general.row.releaseNotes.description": 'Vis pop op-vinduer med "Hvad er nyt" efter opdateringer',
"settings.updates.row.startup.title": "Tjek for opdateringer ved opstart",
"settings.updates.row.startup.description": "Tjek automatisk for opdateringer, når OpenCode starter",
@@ -945,9 +959,9 @@ export const dict = {
"settings.permissions.tool.read.description": "Læsning af en fil (matcher filstien)",
"settings.permissions.tool.edit.title": "Rediger",
"settings.permissions.tool.edit.description":
"Ændre filer, herunder redigeringer, skrivninger, patches og multi-redigeringer",
"Rediger filer, herunder med redigeringer, skrivning, patches og multiredigeringer",
"settings.permissions.tool.glob.title": "Glob",
"settings.permissions.tool.glob.description": "Match filer ved hjælp af glob-mønstre",
"settings.permissions.tool.glob.description": "Find filer ved hjælp af globmønstre",
"settings.permissions.tool.grep.title": "Grep",
"settings.permissions.tool.grep.description": "Søg i filindhold ved hjælp af regulære udtryk",
"settings.permissions.tool.list.title": "Liste",
@@ -960,8 +974,8 @@ export const dict = {
"settings.permissions.tool.skill.description": "Indlæs en færdighed efter navn",
"settings.permissions.tool.lsp.title": "LSP",
"settings.permissions.tool.lsp.description": "Kør sprogserverforespørgsler",
"settings.permissions.tool.todowrite.title": "Skriv To-do",
"settings.permissions.tool.todowrite.description": "Opdater to-do listen",
"settings.permissions.tool.todowrite.title": "Skriv to-do",
"settings.permissions.tool.todowrite.description": "Opdater to-do-listen",
"settings.permissions.tool.webfetch.title": "Webhentning",
"settings.permissions.tool.webfetch.description": "Hent indhold fra en URL",
"settings.permissions.tool.websearch.title": "Websøgning",
@@ -988,7 +1002,7 @@ export const dict = {
"workspace.reset.success.description": "Arbejdsområdet matcher nu hovedgrenen.",
"workspace.error.stillPreparing": "Arbejdsområdet er stadig ved at blive klargjort",
"workspace.status.checking": "Tjekker for uflettede ændringer...",
"workspace.status.error": "Kunne ikke bekræfte git-status.",
"workspace.status.error": "Kunne ikke bekræfte Git-status.",
"workspace.status.clean": "Ingen uflettede ændringer fundet.",
"workspace.status.dirty": "Uflettede ændringer fundet i dette arbejdsområde.",
"workspace.delete.title": "Slet arbejdsområde",
@@ -1030,6 +1044,9 @@ export const dict = {
"session.question.progress": "{{current}} af {{total}} spørgsmål",
"session.header.open.finder": "Finder",
"session.header.open.fileExplorer": "Stifinder",
"session.header.reveal.finder": "Vis i Finder",
"session.header.reveal.fileExplorer": "Vis i Stifinder",
"session.header.reveal.containingFolder": "Åbn den overordnede mappe",
"session.header.open.fileManager": "Filhåndtering",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -1050,11 +1067,11 @@ export const dict = {
"debugBar.nav.tip":
"Sidste gennemførte ruteovergang, der berører en sessionsside, målt fra routerstart til den første optegning efter den falder til ro.",
"debugBar.fps.label": "FPS",
"debugBar.fps.tip": "Rullende billeder pr. sekund over de sidste 5 sekunder.",
"debugBar.fps.tip": "Rullende antal billedrammer pr. sekund over de sidste 5 sekunder.",
"debugBar.frame.label": "FRAME",
"debugBar.frame.tip": "Værste billedtid over de sidste 5 sekunder.",
"debugBar.frame.tip": "Længste billedrammetid over de sidste 5 sekunder.",
"debugBar.jank.label": "JANK",
"debugBar.jank.tip": "Billeder over 32ms i de sidste 5 sekunder.",
"debugBar.jank.tip": "Billedrammer over 32 ms i de sidste 5 sekunder.",
"debugBar.long.label": "LONG",
"debugBar.long.tip": "Blokeret tid og antal lange opgaver i de sidste 5 sekunder. Maks opgave: {{max}}.",
"debugBar.delay.label": "DELAY",
@@ -1065,8 +1082,16 @@ export const dict = {
"debugBar.cls.label": "CLS",
"debugBar.cls.tip": "Kumulativt layoutskift for den nuværende app-levetid.",
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Brugt JS-heap vs heap-grænse. Kun Chromium.",
"debugBar.mem.tip": "Brugt JS-heap vs heap-grænse. {{used}} af {{limit}}.",
"debugBar.mem.tipUnavailable": "Brugt JS-heap sammenholdt med heapgrænsen. Kun Chromium.",
"debugBar.mem.tip": "Brugt JS-heap sammenholdt med heapgrænsen. {{used}} af {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Gennemtving fokusstile for alle interaktive elementer",
"debugBar.focus.on": "TIL",
"debugBar.focus.off": "FRA",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Gennemtving layoutretningen for hele appen uden at ændre det valgte sprog",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
@@ -1090,4 +1115,121 @@ export const dict = {
"error.childStore.persistedProjectIconCreateFailed": "Kunne ikke oprette vedvarende projektikon",
"error.childStore.storeCreateFailed": "Kunne ikke oprette lager",
"terminal.connectionLost.abnormalClose": "WebSocket lukkede unormalt: {{code}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Arkiv",
"desktop.menu.edit": "Rediger",
"desktop.menu.view": "Oversigt",
"desktop.menu.go": "Gå",
"desktop.menu.window": "Vindue",
"desktop.menu.help": "Hjælp",
"desktop.menu.checkForUpdates": "Søg efter opdateringer...",
"desktop.menu.settings": "Indstillinger",
"desktop.menu.reloadWebview": "Genindlæs webvisning",
"desktop.menu.restart": "Genstart",
"desktop.menu.exportLogs": "Eksportér logfiler...",
"desktop.menu.newSession": "Ny session",
"desktop.menu.openProject": "Åbn projekt...",
"desktop.menu.newWindow": "Nyt vindue",
"desktop.menu.closeWindow": "Luk vindue",
"desktop.menu.undo": "Fortryd",
"desktop.menu.redo": "Gentag",
"desktop.menu.cut": "Klip",
"desktop.menu.copy": "Kopier",
"desktop.menu.paste": "Sæt ind",
"desktop.menu.delete": "Slet",
"desktop.menu.selectAll": "Vælg alt",
"desktop.menu.toggleSidebar": "Vis eller skjul indholdsoversigt",
"desktop.menu.toggleTerminal": "Vis eller skjul terminal",
"desktop.menu.toggleFileTree": "Vis eller skjul filtræ",
"desktop.menu.reload": "Genindlæs",
"desktop.menu.toggleDeveloperTools": "Vis eller skjul udviklerværktøjer",
"desktop.menu.actualSize": "Faktisk størrelse",
"desktop.menu.zoomIn": "Zoom ind",
"desktop.menu.zoomOut": "Zoom ud",
"desktop.menu.toggleFullScreen": "Slå fuldskærmsvisning til eller fra",
"desktop.menu.back": "Tilbage",
"desktop.menu.forward": "Frem",
"desktop.menu.previousSession": "Forrige session",
"desktop.menu.nextSession": "Næste session",
"desktop.menu.previousProject": "Forrige projekt",
"desktop.menu.nextProject": "Næste projekt",
"desktop.menu.minimize": "Minimer",
"desktop.menu.maximize": "Maksimer",
"desktop.menu.documentation": "OpenCode-dokumentation",
"desktop.menu.supportForum": "Supportforum",
"desktop.menu.shareFeedback": "Giv feedback",
"desktop.menu.reportBug": "Rapportér en fejl",
"desktop.menu.ariaLabel": "OpenCode-menu",
"desktop.updater.dialog.checkFailed.message": "Søgningen efter opdateringer mislykkedes.",
"desktop.updater.dialog.checkFailed.title": "Opdateringsfejl",
"desktop.updater.dialog.upToDate.message": "Du er opdateret.",
"desktop.updater.dialog.upToDate.title": "Ingen opdateringer",
"desktop.updater.dialog.ready.message": "Opdatering {{version}} er downloadet. Vil du genstarte nu?",
"desktop.updater.dialog.ready.title": "Opdateringen er klar",
"desktop.updater.dialog.restart": "Genstart",
"desktop.updater.dialog.later": "Senere",
"desktop.recovery.action.relaunch": "Start igen",
"desktop.recovery.action.exportLogs": "Eksportér logfiler",
"desktop.recovery.action.keepWaiting": "Vent fortsat",
"desktop.recovery.action.quit": "Afslut",
"desktop.recovery.loadFailed": "OpenCode kunne ikke indlæses",
"desktop.recovery.terminated": "OpenCode-vinduet blev uventet afsluttet",
"desktop.recovery.unresponsive": "OpenCode svarer ikke",
"desktop.recovery.unresponsive.detail": "Du kan starte appen igen, åbne logfilerne eller fortsætte med at vente.",
"desktop.recovery.loadFailed.detail": "Vindue: {{window}}\nURL: {{url}}\nFejl: {{code}} {{description}}",
"desktop.recovery.terminated.detail": "Vindue: {{window}}\nÅrsag: {{reason}}\nKode: {{code}}",
"desktop.recovery.unknown": "<ukendt>",
"desktop.dialog.chooseFolder": "Vælg en mappe",
"desktop.dialog.chooseFile": "Vælg en fil",
"desktop.dialog.saveFile": "Gem fil",
"desktop.dialog.files": "Filer",
"desktop.server.local": "Lokal server",
"desktop.wsl.error.windowsOnly": "WSL er kun tilgængelig i Windows",
"desktop.wsl.error.unavailable": "WSL er ikke tilgængelig",
"desktop.wsl.error.listInstalled": "Kunne ikke vise installerede WSL-distributioner",
"desktop.wsl.error.listOnline": "Kunne ikke vise WSL-distributioner på nettet",
"desktop.wsl.error.executeDistro": "Kan ikke udføre kommandoer i distributionen",
"desktop.wsl.error.installWsl": "Installationen af WSL mislykkedes",
"desktop.wsl.error.installDistro": "Kunne ikke installere distributionen: {{distro}}",
"desktop.wsl.error.installOpencode": "Installationen af OpenCode mislykkedes",
"desktop.wsl.error.alreadyAdded": "{{distro}} er allerede tilføjet",
"desktop.wsl.error.opencodeMissing": "opencode er ikke installeret i denne distribution",
"desktop.wsl.error.opencodeCannotRun": "opencode er installeret, men kunne ikke køre",
"desktop.wsl.error.opencodeNotInstalled": "OpenCode er ikke installeret i {{distro}}",
"desktop.wsl.error.updateVersion":
"Opdateringen af OpenCode er fuldført, men {{distro}} rapporterer stadig {{installed}}. Forventet: {{expected}}",
"desktop.wsl.error.noVersion": "ingen version",
"desktop.wsl.error.serverExited": "WSL-serveren blev afsluttet efter opstart (code={{code}} signal={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"WSL-serveren blev afsluttet, før den var klar (code={{code}} signal={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout":
"Tilstandskontrollen af sidecar-processen for {{distro}} fik timeout efter {{timeout}} ms",
"desktop.wsl.error.commandTimeout": "{{command}} {{args}} fik timeout efter {{timeout}} ms",
"desktop.wsl.error.failedPort": "Kunne ikke hente porten",
"desktop.picker.error.notSelected": "Filen blev ikke valgt i filvælgeren",
"desktop.picker.error.sizeLimit": "De valgte vedhæftede filer overskrider grænsen på {{limit}} MB",
"command.logs.export": "Eksportér logfiler",
"help.tabs.toast.ariaLabel": "Introduktion til faner. Organiser dit arbejde og dine aktive sessioner med faner",
"help.tabs.toast.dismiss": "Luk oplysninger om faner",
"help.tabs.title": "Introduktion til faner",
"help.tabs.description": "Organiser dit arbejde og dine aktive sessioner med faner",
"help.tabs.date": "14. juli",
"help.tabs.introduction": "OpenCode Desktop er nu bygget op omkring faner.",
"help.tabs.sessions":
"Start en ny session i en fane, eller åbn en eksisterende session fra et af dine projekter. Åbn en ny fane, når du går i gang med noget nyt, og luk den, når du er færdig.",
"help.tabs.organize":
"Når du holder nogle få faner åbne, er det nemmere at organisere dine aktive sessioner. Giv fanerne navne, der er nemme at huske, hvis du vil beholde dem.",
"help.tabs.home":
"Du finder alle dine sessioner og projekter på den nye startskærm. Når du vælger en session, åbnes den i en fane.",
"help.tabs.persistence": "Dine faner er stadig åbne, når du åbner appen igen.",
"help.tabs.worktrees":
"Det nye design understøtter endnu ikke Git Worktrees, men understøttelsen kommer snart. Hvis du foretrækker at fortsætte med det tidligere layout, kan du skifte mellem layoutene under Indstillinger. Bemærk, at det nye layout bliver permanent om nogle få uger.",
}
+228 -94
View File
@@ -98,13 +98,14 @@ export const dict = {
"dialog.provider.empty": "Keine Anbieter gefunden",
"dialog.provider.group.popular": "Beliebt",
"dialog.provider.group.other": "Andere",
"dialog.provider.custom.label": "Benutzerdefinierter OpenAI-kompatibler Anbieter",
"dialog.provider.tag.recommended": "Empfohlen",
"dialog.provider.opencode.note": "Kuratierte Modelle inklusive Claude, GPT, Gemini und mehr",
"dialog.provider.opencode.tagline": "Zuverlässige, optimierte Modelle",
"dialog.provider.opencodeGo.tagline": "Kostengünstiges Abo für alle",
"dialog.provider.anthropic.note": "Mit Claude Pro/Max oder API-Schlüssel verbinden",
"dialog.provider.copilot.note": "Mit Copilot oder API-Schlüssel verbinden",
"dialog.provider.openai.note": "Mit ChatGPT Pro/Plus oder API-Schlüssel verbinden",
"dialog.provider.anthropic.note": "Direkter Zugriff auf Claude-Modelle, einschließlich Pro und Max",
"dialog.provider.copilot.note": "KI-Modelle zur Programmierunterstützung über GitHub Copilot",
"dialog.provider.openai.note": "GPT-Modelle für schnelle, leistungsfähige allgemeine KI-Aufgaben",
"dialog.provider.google.note": "Gemini-Modelle für schnelle, strukturierte Antworten",
"dialog.provider.openrouter.note": "Zugriff auf alle unterstützten Modelle über einen Anbieter",
"dialog.provider.vercel.note": "Einheitlicher Zugriff auf KI-Modelle mit intelligentem Routing",
@@ -116,17 +117,20 @@ export const dict = {
"dialog.model.manage.provider.toggle": "Alle {{provider}}-Modelle umschalten",
"dialog.model.unpaid.freeModels.title": "Kostenlose Modelle von OpenCode",
"dialog.model.unpaid.addMore.title": "Weitere Modelle von beliebten Anbietern hinzufügen",
"dialog.model.unpaid.viewMoreProviders": "Über 70 weitere Anbieter anzeigen",
"dialog.provider.viewAll": "Mehr Anbieter anzeigen",
"provider.connect.title": "{{provider}} verbinden",
"provider.connect.title.anthropicProMax": "Mit Claude Pro/Max anmelden",
"provider.connect.selectMethod": "Anmeldemethode für {{provider}} auswählen.",
"provider.connect.method.apiKey": "API-Schlüssel",
"provider.connect.status.inProgress": "Autorisierung läuft...",
"provider.connect.status.waiting": "Warten auf Autorisierung...",
"provider.connect.method.browser": "Browser",
"provider.connect.method.headless": "Browserlos",
"provider.connect.status.inProgress": "Autorisierung läuft…",
"provider.connect.status.waiting": "Warten auf Autorisierung…",
"provider.connect.status.failed": "Autorisierung fehlgeschlagen: {{error}}",
"provider.connect.apiKey.description":
"Geben Sie Ihren {{provider}} API-Schlüssel ein, um Ihr Konto zu verbinden und {{provider}} Modelle in OpenCode zu nutzen.",
"provider.connect.apiKey.label": "{{provider}} API-Schlüssel",
"Geben Sie Ihren API-Schlüssel für {{provider}} ein, um Ihr Konto zu verbinden und {{provider}}-Modelle in OpenCode zu nutzen.",
"provider.connect.apiKey.label": "API-Schlüssel für {{provider}}",
"provider.connect.apiKey.placeholder": "API-Schlüssel",
"provider.connect.apiKey.required": "API-Schlüssel ist erforderlich",
"provider.connect.opencodeZen.line1":
@@ -139,21 +143,22 @@ export const dict = {
"provider.connect.oauth.code.visit.prefix": "Besuchen Sie ",
"provider.connect.oauth.code.visit.link": "diesen Link",
"provider.connect.oauth.code.visit.suffix":
", um Ihren Autorisierungscode zu erhalten, Ihr Konto zu verbinden und {{provider}} Modelle in OpenCode zu nutzen.",
"provider.connect.oauth.code.label": "{{method}} Autorisierungscode",
", um Ihren Autorisierungscode zu erhalten, Ihr Konto zu verbinden und {{provider}}-Modelle in OpenCode zu nutzen.",
"provider.connect.oauth.code.label": "{{method}}-Autorisierungscode",
"provider.connect.oauth.code.placeholder": "Autorisierungscode",
"provider.connect.oauth.code.required": "Autorisierungscode ist erforderlich",
"provider.connect.oauth.code.invalid": "Ungültiger Autorisierungscode",
"provider.connect.oauth.auto.visit.prefix": "Besuchen Sie ",
"provider.connect.oauth.auto.visit.link": "diesen Link",
"provider.connect.oauth.auto.visit.suffix":
" und geben Sie den untenstehenden Code ein, um Ihr Konto zu verbinden und {{provider}} Modelle in OpenCode zu nutzen.",
" und geben Sie den untenstehenden Code ein, um Ihr Konto zu verbinden und {{provider}}-Modelle in OpenCode zu nutzen.",
"provider.connect.oauth.auto.confirmationCode": "Bestätigungscode",
"provider.connect.toast.connected.title": "{{provider}} verbunden",
"provider.connect.toast.connected.description": "{{provider}} Modelle sind jetzt verfügbar.",
"provider.connect.toast.connected.description": "{{provider}}-Modelle sind jetzt verfügbar.",
"provider.custom.title": "Benutzerdefinierter Anbieter",
"provider.custom.unavailable": "Benutzerdefinierte Anbieter sind auf diesem Server nicht verfügbar",
"provider.custom.description.prefix": "Konfigurieren Sie einen OpenAI-kompatiblen Anbieter. Siehe die ",
"provider.custom.description.link": "Anbieter-Konfigurationsdokumente",
"provider.custom.description.link": "Dokumentation zur Anbieterkonfiguration",
"provider.custom.description.suffix": ".",
"provider.custom.field.providerID.label": "Anbieter-ID",
"provider.custom.field.providerID.placeholder": "myprovider",
@@ -208,32 +213,32 @@ export const dict = {
"model.tooltip.model": "Modell",
"model.tooltip.provider": "Anbieter",
"model.tooltip.reasoning": "Reasoning",
"model.tooltip.reasoning.allowed": "Erlaubt Reasoning",
"model.tooltip.reasoning.allowed": "Reasoning möglich",
"model.tooltip.reasoning.none": "Kein Reasoning",
"model.tooltip.context": "Kontextlimit {{limit}}",
"common.search.placeholder": "Suchen",
"common.goBack": "Zurück",
"common.goForward": "Vorwärts navigieren",
"common.loading": "Laden",
"common.loading.ellipsis": "...",
"common.loading": "Wird geladen",
"common.loading.ellipsis": "",
"common.cancel": "Abbrechen",
"common.clear": "Leeren",
"common.connect": "Verbinden",
"common.disconnect": "Trennen",
"common.continue": "Absenden",
"common.continue": "Weiter",
"common.submit": "Absenden",
"common.save": "Speichern",
"common.saving": "Speichert...",
"common.saving": "Wird gespeichert",
"common.default": "Standard",
"common.attachment": "Anhang",
"prompt.placeholder.shell": "Shell-Befehl eingeben... {{example}}",
"prompt.placeholder.normal": 'Fragen Sie alles... "{{example}}"',
"prompt.placeholder.simple": "Fragen Sie alles...",
"prompt.placeholder.shell": "Shell-Befehl eingeben {{example}}",
"prompt.placeholder.normal": 'Beliebige Frage stellen… "{{example}}"',
"prompt.placeholder.simple": "Beliebige Frage stellen…",
"prompt.placeholder.summarizeComments": "Kommentare zusammenfassen…",
"prompt.placeholder.summarizeComment": "Kommentar zusammenfassen…",
"prompt.mode.shell": "Shell",
"prompt.mode.normal": "Prompt",
"prompt.mode.shell.exit": "esc zum Verlassen",
"prompt.mode.shell.exit": "Esc zum Verlassen",
"session.child.promptDisabled": "Unteragenten-Sitzungen können keine Prompts erhalten.",
"session.child.backToParent": "Zurück zur Hauptsitzung.",
"prompt.example.1": "Ein TODO in der Codebasis beheben",
@@ -248,8 +253,8 @@ export const dict = {
"prompt.example.10": "API-Dokumentation generieren",
"prompt.example.11": "Datenbankabfragen optimieren",
"prompt.example.12": "Eingabevalidierung hinzufügen",
"prompt.example.13": "Neue Komponente erstellen für...",
"prompt.example.14": "Wie deploye ich dieses Projekt?",
"prompt.example.13": "Neue Komponente erstellen für",
"prompt.example.14": "Wie stelle ich dieses Projekt bereit?",
"prompt.example.15": "Meinen Code auf Best Practices überprüfen",
"prompt.example.16": "Fehlerbehandlung zu dieser Funktion hinzufügen",
"prompt.example.17": "Erkläre dieses Regex-Muster",
@@ -259,12 +264,12 @@ export const dict = {
"prompt.example.21": "Hilf mir, ein Migrationsskript zu schreiben",
"prompt.example.22": "Caching für diesen Endpunkt implementieren",
"prompt.example.23": "Paginierung zu dieser Liste hinzufügen",
"prompt.example.24": "CLI-Befehl erstellen für...",
"prompt.example.24": "CLI-Befehl erstellen für",
"prompt.example.25": "Wie funktionieren Umgebungsvariablen hier?",
"prompt.popover.emptyResults": "Keine passenden Ergebnisse",
"prompt.popover.emptyCommands": "Keine passenden Befehle",
"prompt.dropzone.label": "Bilder, PDFs oder Textdateien hier ablegen",
"prompt.dropzone.file.label": "Ablegen zum @Erwähnen der Datei",
"prompt.dropzone.file.label": "Ablegen, um die Datei mit @ zu erwähnen",
"prompt.slash.badge.custom": "benutzerdefiniert",
"prompt.slash.badge.skill": "Skill",
"prompt.slash.badge.mcp": "MCP",
@@ -280,14 +285,14 @@ export const dict = {
"prompt.menu.shellCommand": "Shell-Befehl",
"prompt.attachment.remove": "Anhang entfernen",
"prompt.action.send": "Senden",
"prompt.action.stop": "Stopp",
"prompt.action.stop": "Stoppen",
"prompt.toast.pasteUnsupported.title": "Nicht unterstützter Anhang",
"prompt.toast.attachmentDuplicate.title": "Diese Datei wurde bereits hochgeladen",
"prompt.toast.pasteUnsupported.description": "Hier können nur Bilder, PDFs oder Textdateien angehängt werden.",
"prompt.toast.modelAgentRequired.title": "Wählen Sie einen Agenten und ein Modell",
"prompt.toast.modelAgentRequired.description":
"Wählen Sie einen Agenten und ein Modell, bevor Sie eine Eingabe senden.",
"prompt.toast.worktreeCreateFailed.title": "Worktree konnte nicht erstellt werden",
"prompt.toast.worktreeCreateFailed.title": "Der Worktree konnte nicht erstellt werden",
"prompt.toast.sessionCreateFailed.title": "Sitzung konnte nicht erstellt werden",
"prompt.toast.shellSendFailed.title": "Shell-Befehl konnte nicht gesendet werden",
"prompt.toast.commandSendFailed.title": "Befehl konnte nicht gesendet werden",
@@ -300,7 +305,7 @@ export const dict = {
"dialog.plugins.empty": "In opencode.json konfigurierte Plugins",
"mcp.status.connected": "verbunden",
"mcp.status.failed": "fehlgeschlagen",
"mcp.status.needs_auth": "benötigt Authentifizierung",
"mcp.status.needs_auth": "Authentifizierung erforderlich",
"mcp.auth.clickToAuthenticate": "Zum Authentifizieren klicken",
"mcp.status.disabled": "deaktiviert",
"dialog.fork.empty": "Keine Nachrichten zum Abzweigen vorhanden",
@@ -316,10 +321,10 @@ export const dict = {
"dialog.server.search.placeholder": "Server durchsuchen",
"dialog.server.empty": "Noch keine Server",
"dialog.server.add.title": "Server hinzufügen",
"dialog.server.add.url": "Server-URL",
"dialog.server.add.url": "Serveradresse",
"dialog.server.add.placeholder": "http://localhost:4096",
"dialog.server.add.error": "Verbindung zum Server fehlgeschlagen",
"dialog.server.add.checking": "Prüfen...",
"dialog.server.add.checking": "Prüfen",
"dialog.server.add.button": "Server hinzufügen",
"dialog.server.add.name": "Servername (optional)",
"dialog.server.add.namePlaceholder": "Localhost",
@@ -328,7 +333,7 @@ export const dict = {
"dialog.server.edit.title": "Server bearbeiten",
"dialog.server.default.title": "Standardserver",
"dialog.server.default.description":
"Beim App-Start mit diesem Server verbinden, anstatt einen lokalen Server zu starten. Erfordert Neustart.",
"Beim App-Start mit diesem Server verbinden, anstatt einen lokalen Server zu starten. Ein Neustart ist erforderlich.",
"dialog.server.default.none": "Kein Server ausgewählt",
"dialog.server.default.set": "Aktuellen Server als Standard setzen",
"dialog.server.default.clear": "Löschen",
@@ -344,26 +349,26 @@ export const dict = {
"wsl.server.label": "WSL",
"wsl.server.menu.label": "WSL-Server",
"wsl.server.retryStart": "Start erneut versuchen",
"wsl.server.updating": "Wird aktualisiert...",
"wsl.server.updating": "Wird aktualisiert",
"wsl.onboarding.step.distro": "Distribution auswählen",
"wsl.onboarding.step.opencode": "OpenCode",
"wsl.onboarding.checkingRuntime": "WSL wird geprüft...",
"wsl.onboarding.checkingRuntime": "WSL wird geprüft",
"wsl.onboarding.restartRequired": "Windows muss neu gestartet werden, um die WSL-Installation abzuschließen.",
"wsl.onboarding.ready": "WSL ist bereit.",
"wsl.onboarding.required": "WSL ist erforderlich, um fortzufahren.",
"wsl.onboarding.checkingDistros": "Distributionen werden geprüft...",
"wsl.onboarding.installingDistro": "{{distro}} wird installiert...",
"wsl.onboarding.checkingDistro": "{{distro}} wird geprüft...",
"wsl.onboarding.listingDistros": "Distributionen werden aufgelistet...",
"wsl.onboarding.checkingDistros": "Distributionen werden geprüft",
"wsl.onboarding.installingDistro": "{{distro}} wird installiert",
"wsl.onboarding.checkingDistro": "{{distro}} wird geprüft",
"wsl.onboarding.listingDistros": "Distributionen werden aufgelistet",
"wsl.onboarding.distroReady": "{{distro}} ist bereit.",
"wsl.onboarding.distroNotInstalled": "{{distro}} ist noch nicht installiert.",
"wsl.onboarding.openDistroOnce": "Öffnen Sie {{distro}} einmal, um die Einrichtung abzuschließen.",
"wsl.onboarding.finishingDistro": "Einrichtung von {{distro}} wird abgeschlossen.",
"wsl.onboarding.pickDistro": "Wählen Sie eine Distribution aus oder installieren Sie unten eine.",
"wsl.onboarding.checkingOpencode": "OpenCode wird geprüft...",
"wsl.onboarding.checkingOpencodeIn": "OpenCode in {{distro}} wird geprüft...",
"wsl.onboarding.updatingOpencode": "OpenCode wird aktualisiert...",
"wsl.onboarding.updatingOpencodeIn": "OpenCode in {{distro}} wird aktualisiert...",
"wsl.onboarding.checkingOpencode": "OpenCode wird geprüft",
"wsl.onboarding.checkingOpencodeIn": "OpenCode in {{distro}} wird geprüft",
"wsl.onboarding.updatingOpencode": "OpenCode wird aktualisiert",
"wsl.onboarding.updatingOpencodeIn": "OpenCode in {{distro}} wird aktualisiert",
"wsl.onboarding.updateOpencodeIn": "Aktualisieren Sie OpenCode in {{distro}}.",
"wsl.onboarding.updateOpencode": "OpenCode aktualisieren",
"wsl.onboarding.opencodeReadyIn": "OpenCode ist in {{distro}} bereit.",
@@ -372,11 +377,11 @@ export const dict = {
"wsl.onboarding.installOpencode": "OpenCode installieren",
"wsl.onboarding.chooseDistroFirst": "Wählen Sie zuerst eine Distribution aus.",
"wsl.onboarding.loadFailed": "WSL-Status konnte nicht geladen werden.",
"wsl.onboarding.loading": "Wird geladen...",
"wsl.onboarding.loading": "Wird geladen",
"wsl.onboarding.installedDistros": "Installierte Distributionen",
"wsl.onboarding.checkAgain": "Erneut prüfen",
"wsl.onboarding.distroStatus.ready": "Bereit",
"wsl.onboarding.distroStatus.checking": "Wird geprüft...",
"wsl.onboarding.distroStatus.checking": "Wird geprüft",
"wsl.onboarding.distroStatus.opencodeMissing": "OpenCode nicht installiert",
"wsl.onboarding.distroStatus.missingTools": "Fehlend: bash, curl",
"wsl.onboarding.distroStatus.unsupported": "Nicht unterstützt · WSL 2 verwenden",
@@ -395,7 +400,7 @@ export const dict = {
"wsl.onboarding.allDistrosAdded": "Alle installierten Distributionen wurden bereits hinzugefügt.",
"wsl.onboarding.noDistros": "Noch keine Distributionen erkannt.",
"wsl.onboarding.install": "Installieren",
"wsl.onboarding.installing": "Wird installiert...",
"wsl.onboarding.installing": "Wird installiert",
"wsl.onboarding.installDistro": "Distribution installieren",
"wsl.onboarding.searchDistros": "Distributionen durchsuchen",
"wsl.onboarding.wsl2Required": "WSL 2 ist erforderlich.",
@@ -407,13 +412,13 @@ export const dict = {
"wsl.onboarding.unknown": "unbekannt",
"wsl.onboarding.desktopVersion": "Desktop {{version}}",
"wsl.onboarding.versionMismatch": "Die installierte Version entspricht nicht der Version der Desktop-App.",
"wsl.onboarding.adding": "Wird hinzugefügt...",
"wsl.onboarding.adding": "Wird hinzugefügt",
"dialog.project.edit.title": "Projekt bearbeiten",
"dialog.project.edit.name": "Name",
"dialog.project.edit.icon": "Icon",
"dialog.project.edit.icon.alt": "Projekt-Icon",
"dialog.project.edit.icon": "Symbol",
"dialog.project.edit.icon.alt": "Projektsymbol",
"dialog.project.edit.icon.hint": "Klicken oder Bild ziehen",
"dialog.project.edit.icon.recommended": "Empfohlen: 128x128px",
"dialog.project.edit.icon.recommended": "Empfohlen: 128 × 128 px",
"dialog.project.edit.color": "Farbe",
"dialog.project.edit.color.select": "{{color}}-Farbe auswählen",
"dialog.project.edit.worktree.startup": "Startup-Skript für Arbeitsbereich",
@@ -489,7 +494,7 @@ export const dict = {
"toast.context.noLineSelection.description": "Wählen Sie zuerst einen Zeilenbereich in einem Datei-Tab aus.",
"toast.session.share.copyFailed.title": "URL konnte nicht in die Zwischenablage kopiert werden",
"toast.session.share.success.title": "Sitzung geteilt",
"toast.session.share.success.description": "Teilen-URL in die Zwischenablage kopiert!",
"toast.session.share.success.description": "URL zum Teilen in die Zwischenablage kopiert!",
"toast.session.share.failed.title": "Sitzung konnte nicht geteilt werden",
"toast.session.share.failed.description": "Beim Teilen der Sitzung ist ein Fehler aufgetreten",
"toast.session.unshare.success.title": "Teilen der Sitzung aufgehoben",
@@ -509,14 +514,14 @@ export const dict = {
"error.page.action.report": "Fehler melden",
"error.page.action.reported": "Fehler gemeldet",
"error.page.action.exportLogs": "Protokolle exportieren",
"error.page.action.checking": "Prüfen...",
"error.page.action.checking": "Prüfen",
"error.page.action.checkUpdates": "Nach Updates suchen",
"error.page.action.updateTo": "Auf {{version}} aktualisieren",
"error.page.report.prefix": "Bitte melden Sie diesen Fehler dem OpenCode-Team",
"error.page.report.discord": "auf Discord",
"error.page.version": "Version: {{version}}",
"error.dev.rootNotFound":
"Wurzelelement nicht gefunden. Haben Sie vergessen, es in Ihre index.html aufzunehmen? Oder wurde das id-Attribut falsch geschrieben?",
"Wurzelelement nicht gefunden. Haben Sie vergessen, es in Ihre index.html aufzunehmen? Oder wurde das ID-Attribut falsch geschrieben?",
"error.serverSync.connectFailed": "Verbindung zum Server fehlgeschlagen. Läuft ein Server unter `{{url}}`?",
"directory.error.invalidUrl": "Ungültiges Verzeichnis in der URL.",
"error.chain.unknown": "Unbekannter Fehler",
@@ -524,10 +529,10 @@ export const dict = {
"error.chain.apiError": "API-Fehler",
"error.chain.status": "Status: {{status}}",
"error.chain.retryable": "Wiederholbar: {{retryable}}",
"error.chain.responseBody": "Antwort-Body:\n{{body}}",
"error.chain.responseBody": "Antwortinhalt:\n{{body}}",
"error.chain.didYouMean": "Meinten Sie: {{suggestions}}",
"error.chain.modelNotFound": "Modell nicht gefunden: {{provider}}/{{model}}",
"error.chain.checkConfig": "Überprüfen Sie Ihre Konfiguration (opencode.json) auf Anbieter-/Modellnamen",
"error.chain.checkConfig": "Überprüfen Sie die Anbieter- und Modellnamen in Ihrer Konfiguration (opencode.json)",
"error.chain.mcpFailed":
'MCP-Server "{{name}}" fehlgeschlagen. Hinweis: OpenCode unterstützt noch keine MCP-Authentifizierung.',
"error.chain.providerAuthFailed": "Anbieter-Authentifizierung fehlgeschlagen ({{provider}}): {{message}}",
@@ -568,7 +573,7 @@ export const dict = {
"home.sessions.group.yesterday": "Gestern",
"home.sessions.group.older": "Älter",
"home.providerTip":
"Verbinde dich mit über 75 Anbietern, um weitere Modelle wie Claude, GPT, Gemini und andere zu nutzen",
"OpenCode mit über 75 Anbietern verbinden, um weitere Modelle wie Claude, GPT, Gemini und andere zu nutzen",
"session.tab.session": "Sitzung",
"session.tab.review": "Überprüfung",
"session.tab.context": "Kontext",
@@ -579,12 +584,12 @@ export const dict = {
"Dieser Tab verweist auf eine Sitzung, die auf diesem Server nicht mehr existiert.",
"session.error.notFound.closeTab": "Tab schließen",
"session.error.serverConnection": "Verbindung zu diesem Server nicht möglich",
"session.review.filesChanged": "{{count}} Dateien geändert",
"session.review.filesChanged": "Geänderte Dateien: {{count}}",
"session.review.change.one": "Änderung",
"session.review.change.other": "Änderungen",
"session.review.loadingChanges": "Lade Änderungen...",
"session.review.loadingChanges": "Änderungen werden geladen…",
"session.review.empty": "Noch keine Änderungen in dieser Sitzung",
"session.review.noVcs": "Kein Git-Versionskontrollsystem erkannt, Änderungen werden nicht angezeigt",
"session.review.noVcs": "Kein Git-Versionskontrollsystem erkannt. Änderungen werden nicht angezeigt",
"session.review.noSnapshot":
"Snapshot-Tracking ist in der Konfiguration deaktiviert, daher sind Sitzungsänderungen nicht verfügbar",
"session.review.noChanges": "Keine Änderungen",
@@ -595,10 +600,10 @@ export const dict = {
"session.files.empty": "Keine Dateien",
"session.files.binaryContent": "Binärdatei (Inhalt kann nicht angezeigt werden)",
"session.messages.renderEarlier": "Frühere Nachrichten rendern",
"session.messages.loadingEarlier": "Lade frühere Nachrichten...",
"session.messages.loadingEarlier": "Frühere Nachrichten werden geladen…",
"session.messages.loadEarlier": "Frühere Nachrichten laden",
"session.messages.loading": "Lade Nachrichten...",
"session.messages.jumpToLatest": "Zum neuesten springen",
"session.messages.loading": "Nachrichten werden geladen…",
"session.messages.jumpToLatest": "Zur neuesten Nachricht springen",
"session.context.addToContext": "{{selection}} zum Kontext hinzufügen",
"session.todo.title": "Aufgaben",
"session.todo.collapse": "Einklappen",
@@ -618,7 +623,7 @@ export const dict = {
"session.revertDock.collapse": "Zurückgesetzte Nachrichten einklappen",
"session.revertDock.expand": "Zurückgesetzte Nachrichten ausklappen",
"session.revertDock.restore": "Nachricht wiederherstellen",
"session.new.title": "Baue, was du willst",
"session.new.title": "Alles entwickeln",
"session.new.project.new": "Neues Projekt",
"session.new.project.search": "Projekte durchsuchen",
"session.new.project.add": "Projekt hinzufügen",
@@ -652,22 +657,29 @@ export const dict = {
"Sitzung öffentlich im Web teilen. Sie wird für jeden mit dem Link zugänglich sein.",
"session.share.action.share": "Teilen",
"session.share.action.publish": "Veröffentlichen",
"session.share.action.publishing": "Veröffentliche...",
"session.share.action.publishing": "Wird veröffentlicht…",
"session.share.action.unpublish": "Veröffentlichung aufheben",
"session.share.action.unpublishing": "Hebe Veröffentlichung auf...",
"session.share.action.unpublishing": "Veröffentlichung wird aufgehoben…",
"session.share.action.view": "Ansehen",
"session.share.copy.copied": "Kopiert",
"session.share.copy.copyLink": "Link kopieren",
"lsp.tooltip.none": "Keine LSP-Server",
"lsp.label.connected": "{{count}} LSP",
"prompt.loading": "Lade Prompt...",
"terminal.loading": "Lade Terminal...",
"prompt.loading": "Prompt wird geladen…",
"terminal.loading": "Terminal wird geladen…",
"terminal.title": "Terminal",
"terminal.title.numbered": "Terminal {{number}}",
"terminal.close": "Terminal schließen",
"terminal.connectionLost.title": "Verbindung verloren",
"terminal.connectionLost.description":
"Die Terminalverbindung wurde unterbrochen. Das kann passieren, wenn der Server neu startet.",
"terminal.connectTicket.csrfError":
"Das PTY-Verbindungsticket wurde bei der Ursprungs- oder CSRF-Prüfung abgelehnt. Überprüfen Sie die CORS-Konfiguration des Servers.",
"terminal.connectTicket.statusError": "Das PTY-Verbindungsticket ist mit {{status}} fehlgeschlagen",
"titlebar.update": "Aktualisieren",
"titlebar.updateVersion": "Aktualisieren {{version}}",
"common.closeTab": "Tab schließen",
"common.dismiss": "Verwerfen",
"common.requestFailed": "Anfrage fehlgeschlagen",
@@ -728,12 +740,12 @@ export const dict = {
"settings.general.row.font.title": "Code-Schriftart",
"settings.general.row.font.description": "Die in Codeblöcken verwendete Schriftart anpassen",
"settings.general.row.terminalFont.title": "Terminalschriftart",
"settings.general.row.terminalFont.description": "Passe die im Terminal verwendete Schriftart an",
"settings.general.row.terminalFont.description": "Die im Terminal verwendete Schriftart anpassen",
"settings.general.row.uiFont.title": "UI-Schriftart",
"settings.general.row.uiFont.description": "Die im gesamten Interface verwendete Schriftart anpassen",
"settings.general.row.followup.title": "Verhalten bei Folgefragen",
"settings.general.row.uiFont.description": "Die in der gesamten Benutzeroberfläche verwendete Schriftart anpassen",
"settings.general.row.followup.title": "Verhalten bei Folgeeingaben",
"settings.general.row.followup.description":
"Wählen Sie, ob Folgefragen sofort steuern oder in einer Warteschlange warten",
"Wählen Sie, ob Folgeeingaben die laufende Sitzung sofort steuern oder in einer Warteschlange warten",
"settings.general.row.followup.option.queue": "Warteschlange",
"settings.general.row.followup.option.steer": "Steuern",
"settings.general.row.showFileTree.title": "Dateibaum",
@@ -751,8 +763,9 @@ export const dict = {
"settings.general.row.mobileTitlebarBottom.title": "Navigation unten",
"settings.general.row.mobileTitlebarBottom.description":
"Titelleiste und Sitzungs-Tabs auf Mobilgeräten am unteren Bildschirmrand platzieren",
"settings.general.row.showCustomAgents.title": "Benutzerdefinierte Agenten",
"settings.general.row.showCustomAgents.description": "Agentenauswahl im Eingabebereich anzeigen",
"settings.general.row.showCustomAgents.title": "Agent anzeigen",
"settings.general.row.showCustomAgents.description":
"Im Eingabebereich zwischen Agenten wechseln. Ist die Auswahl ausgeblendet, wird standardmäßig der Build-Agent verwendet.",
"settings.general.row.reasoningSummaries.title": "Reasoning-Zusammenfassungen anzeigen",
"settings.general.row.reasoningSummaries.description":
"Zusammenfassungen des Modell-Reasonings in der Timeline anzeigen",
@@ -772,7 +785,7 @@ export const dict = {
"settings.general.row.pinchZoom.title": "Zoom per Fingergeste",
"settings.general.row.pinchZoom.description": "Zoomen per Zwei-Finger- und Ctrl-Scroll-Geste erlauben",
"settings.general.row.wayland.title": "Natives Wayland verwenden",
"settings.general.row.wayland.description": "X11-Fallback unter Wayland deaktivieren. Erfordert Neustart.",
"settings.general.row.wayland.description": "X11-Fallback unter Wayland deaktivieren. Ein Neustart ist erforderlich.",
"settings.general.row.wayland.tooltip":
"Unter Linux mit Monitoren unterschiedlicher Bildwiederholraten kann natives Wayland stabiler sein.",
"settings.general.row.releaseNotes.title": "Versionshinweise",
@@ -782,11 +795,11 @@ export const dict = {
"settings.updates.row.check.title": "Nach Updates suchen",
"settings.updates.row.check.description": "Manuell nach Updates suchen und installieren, wenn verfügbar",
"settings.updates.action.checkNow": "Jetzt prüfen",
"settings.updates.action.checking": "Wird geprüft...",
"settings.updates.action.downloading": "Wird heruntergeladen...",
"settings.updates.action.installing": "Wird installiert...",
"settings.updates.toast.latest.title": "Du bist auf dem neuesten Stand",
"settings.updates.toast.latest.description": "Du verwendest die aktuelle Version von OpenCode.",
"settings.updates.action.checking": "Wird geprüft",
"settings.updates.action.downloading": "Wird heruntergeladen",
"settings.updates.action.installing": "Wird installiert",
"settings.updates.toast.latest.title": "OpenCode ist auf dem neuesten Stand",
"settings.updates.toast.latest.description": "Die aktuelle Version von OpenCode wird verwendet.",
"sound.option.none": "Keine",
"sound.option.alert01": "Alarm 01",
"sound.option.alert02": "Alarm 02",
@@ -902,8 +915,8 @@ export const dict = {
"settings.permissions.tool.bash.description": "Shell-Befehle ausführen",
"settings.permissions.tool.task.title": "Aufgabe",
"settings.permissions.tool.task.description": "Unteragenten starten",
"settings.permissions.tool.skill.title": "Fähigkeit",
"settings.permissions.tool.skill.description": "Eine Fähigkeit nach Namen laden",
"settings.permissions.tool.skill.title": "Skill",
"settings.permissions.tool.skill.description": "Einen Skill anhand des Namens laden",
"settings.permissions.tool.lsp.title": "LSP",
"settings.permissions.tool.lsp.description": "Language-Server-Abfragen ausführen",
"settings.permissions.tool.todowrite.title": "Todo schreiben",
@@ -931,7 +944,7 @@ export const dict = {
"workspace.reset.success.title": "Arbeitsbereich zurückgesetzt",
"workspace.reset.success.description": "Der Arbeitsbereich entspricht jetzt dem Standard-Branch.",
"workspace.error.stillPreparing": "Arbeitsbereich wird noch vorbereitet",
"workspace.status.checking": "Suche nach nicht zusammengeführten Änderungen...",
"workspace.status.checking": "Suche nach nicht zusammengeführten Änderungen",
"workspace.status.error": "Git-Status konnte nicht überprüft werden.",
"workspace.status.clean": "Keine nicht zusammengeführten Änderungen erkannt.",
"workspace.status.dirty": "Nicht zusammengeführte Änderungen in diesem Arbeitsbereich erkannt.",
@@ -961,7 +974,7 @@ export const dict = {
"settings.providers.custom.description": "Fügen Sie einen OpenAI-kompatiblen Anbieter per Basis-URL hinzu.",
"app.server.unreachable": "Konnte {{server}} nicht erreichen",
"app.server.retrying": "Automatische erneute Verbindung...",
"app.server.retrying": "Verbindung wird automatisch erneut hergestellt…",
"app.server.otherServers": "Andere Server",
"dialog.server.add.usernamePlaceholder": "Benutzername",
"dialog.server.add.passwordPlaceholder": "Passwort",
@@ -969,12 +982,15 @@ export const dict = {
"session.review.noVcs.createGit.title": "Git-Repository erstellen",
"session.review.noVcs.createGit.description":
"Änderungen in diesem Projekt verfolgen, überprüfen und rückgängig machen",
"session.review.noVcs.createGit.actionLoading": "Git-Repository wird erstellt...",
"session.review.noVcs.createGit.actionLoading": "Git-Repository wird erstellt",
"session.review.noVcs.createGit.action": "Git-Repository erstellen",
"session.todo.progress": "{{done}} von {{total}} Aufgaben erledigt",
"session.question.progress": "{{current}} von {{total}} Fragen",
"session.header.open.finder": "Finder",
"session.header.open.fileExplorer": "Datei-Explorer",
"session.header.reveal.finder": "Im Finder anzeigen",
"session.header.reveal.fileExplorer": "Im Datei-Explorer anzeigen",
"session.header.reveal.containingFolder": "Übergeordneten Ordner öffnen",
"session.header.open.fileManager": "Dateimanager",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -989,29 +1005,38 @@ export const dict = {
"session.header.open.app.androidStudio": "Android Studio",
"session.header.open.app.powershell": "PowerShell",
"session.header.open.app.sublimeText": "Sublime Text",
"debugBar.ariaLabel": "Entwicklungs-Leistungsdiagnose",
"debugBar.ariaLabel": "Leistungsdiagnose für die Entwicklung",
"debugBar.na": "n.v.",
"debugBar.nav.label": "NAV",
"debugBar.nav.tip":
"Letzter abgeschlossener Routenübergang, der eine Sitzungsseite berührt, gemessen vom Start des Routers bis zum ersten Rendern nach dem Einschwingen.",
"Letzter abgeschlossener Routenübergang zu einer Sitzungsseite, gemessen vom Start des Routers bis zum ersten Rendering nach Abschluss des Übergangs.",
"debugBar.fps.label": "FPS",
"debugBar.fps.tip": "Gleitende Bilder pro Sekunde in den letzten 5 Sekunden.",
"debugBar.fps.tip": "Gleitender Mittelwert der Frames pro Sekunde in den letzten 5 Sekunden.",
"debugBar.frame.label": "FRAME",
"debugBar.frame.tip": "Schlechteste Frame-Zeit in den letzten 5 Sekunden.",
"debugBar.frame.tip": "Längste Framedauer in den letzten 5 Sekunden.",
"debugBar.jank.label": "JANK",
"debugBar.jank.tip": "Frames über 32ms in den letzten 5 Sekunden.",
"debugBar.jank.tip": "Frames über 32 ms in den letzten 5 Sekunden.",
"debugBar.long.label": "LONG",
"debugBar.long.tip": "Blockierte Zeit und Anzahl langer Aufgaben in den letzten 5 Sekunden. Max Aufgabe: {{max}}.",
"debugBar.long.tip":
"Blockierte Zeit und Anzahl langer Aufgaben in den letzten 5 Sekunden. Längste Aufgabe: {{max}}.",
"debugBar.delay.label": "DELAY",
"debugBar.delay.tip": "Schlechteste beobachtete Eingabeverzögerung in den letzten 5 Sekunden.",
"debugBar.inp.label": "INP",
"debugBar.inp.tip":
"Ungefähre Interaktionsdauer in den letzten 5 Sekunden. Dies ist INP-ähnlich, nicht das offizielle Web Vitals INP.",
"Ungefähre Interaktionsdauer in den letzten 5 Sekunden. Dies ist INP-ähnlich, nicht das offizielle Web-Vitals-INP.",
"debugBar.cls.label": "CLS",
"debugBar.cls.tip": "Kumulative Layoutverschiebung für die aktuelle App-Lebensdauer.",
"debugBar.cls.tip": "Kumulative Layoutverschiebung während der aktuellen App-Laufzeit.",
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Verwendeter JS-Heap vs Heap-Limit. Nur Chromium.",
"debugBar.mem.tip": "Verwendeter JS-Heap vs Heap-Limit. {{used}} von {{limit}}.",
"debugBar.mem.tipUnavailable": "Belegter JS-Heap im Verhältnis zum Heap-Limit. Nur Chromium.",
"debugBar.mem.tip": "Belegter JS-Heap im Verhältnis zum Heap-Limit. {{used}} von {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Fokusstile für alle interaktiven Elemente erzwingen",
"debugBar.focus.on": "EIN",
"debugBar.focus.off": "AUS",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Layoutrichtung für die gesamte App erzwingen, ohne die ausgewählte Sprache zu ändern",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Strg",
"common.key.alt": "Alt",
"common.key.shift": "Umschalt",
@@ -1032,7 +1057,116 @@ export const dict = {
"error.serverSDK.serverNotAvailable": "Server nicht verfügbar",
"error.childStore.persistedCacheCreateFailed": "Dauerhafter Cache konnte nicht erstellt werden",
"error.childStore.persistedProjectMetadataCreateFailed": "Dauerhafte Projektmetadaten konnten nicht erstellt werden",
"error.childStore.persistedProjectIconCreateFailed": "Dauerhaftes Projekticon konnte nicht erstellt werden",
"error.childStore.persistedProjectIconCreateFailed": "Dauerhaftes Projektsymbol konnte nicht erstellt werden",
"error.childStore.storeCreateFailed": "Speicher konnte nicht erstellt werden",
"terminal.connectionLost.abnormalClose": "WebSocket abnormal geschlossen: {{code}}",
"terminal.connectionLost.abnormalClose": "WebSocket unerwartet geschlossen: {{code}}",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Datei",
"desktop.menu.edit": "Bearbeiten",
"desktop.menu.view": "Ansicht",
"desktop.menu.go": "Gehe zu",
"desktop.menu.window": "Fenster",
"desktop.menu.help": "Hilfe",
"desktop.menu.checkForUpdates": "Nach Updates suchen…",
"desktop.menu.settings": "Einstellungen",
"desktop.menu.reloadWebview": "Webview neu laden",
"desktop.menu.restart": "Neu starten",
"desktop.menu.exportLogs": "Protokolle exportieren…",
"desktop.menu.newSession": "Neue Sitzung",
"desktop.menu.openProject": "Projekt öffnen…",
"desktop.menu.newWindow": "Neues Fenster",
"desktop.menu.closeWindow": "Fenster schließen",
"desktop.menu.undo": "Rückgängig",
"desktop.menu.redo": "Wiederholen",
"desktop.menu.cut": "Ausschneiden",
"desktop.menu.copy": "Kopieren",
"desktop.menu.paste": "Einfügen",
"desktop.menu.delete": "Löschen",
"desktop.menu.selectAll": "Alles auswählen",
"desktop.menu.toggleSidebar": "Seitenleiste umschalten",
"desktop.menu.toggleTerminal": "Terminal umschalten",
"desktop.menu.toggleFileTree": "Dateibaum umschalten",
"desktop.menu.reload": "Neu laden",
"desktop.menu.toggleDeveloperTools": "Entwicklertools umschalten",
"desktop.menu.actualSize": "Tatsächliche Größe",
"desktop.menu.zoomIn": "Vergrößern",
"desktop.menu.zoomOut": "Verkleinern",
"desktop.menu.toggleFullScreen": "Vollbildmodus umschalten",
"desktop.menu.back": "Zurück",
"desktop.menu.forward": "Vorwärts",
"desktop.menu.previousSession": "Vorherige Sitzung",
"desktop.menu.nextSession": "Nächste Sitzung",
"desktop.menu.previousProject": "Vorheriges Projekt",
"desktop.menu.nextProject": "Nächstes Projekt",
"desktop.menu.minimize": "Minimieren",
"desktop.menu.maximize": "Maximieren",
"desktop.menu.documentation": "OpenCode-Dokumentation",
"desktop.menu.supportForum": "Supportforum",
"desktop.menu.shareFeedback": "Feedback senden",
"desktop.menu.reportBug": "Fehler melden",
"desktop.menu.ariaLabel": "OpenCode-Menü",
"desktop.updater.dialog.checkFailed.message": "Die Suche nach Updates ist fehlgeschlagen.",
"desktop.updater.dialog.checkFailed.title": "Updatefehler",
"desktop.updater.dialog.upToDate.message": "Sie sind auf dem neuesten Stand.",
"desktop.updater.dialog.upToDate.title": "Keine Updates",
"desktop.updater.dialog.ready.message": "Update {{version}} wurde heruntergeladen. Jetzt neu starten?",
"desktop.updater.dialog.ready.title": "Update bereit",
"desktop.updater.dialog.restart": "Neu starten",
"desktop.updater.dialog.later": "Später",
"desktop.recovery.action.relaunch": "Neu starten",
"desktop.recovery.action.exportLogs": "Protokolle exportieren",
"desktop.recovery.action.keepWaiting": "Weiter warten",
"desktop.recovery.action.quit": "Beenden",
"desktop.recovery.loadFailed": "OpenCode konnte nicht geladen werden",
"desktop.recovery.terminated": "Das OpenCode-Fenster wurde unerwartet beendet",
"desktop.recovery.unresponsive": "OpenCode reagiert nicht",
"desktop.recovery.unresponsive.detail": "Sie können die App neu starten, die Protokolle öffnen oder weiter warten.",
"desktop.recovery.loadFailed.detail": "Fenster: {{window}}\nURL: {{url}}\nFehler: {{code}} {{description}}",
"desktop.recovery.terminated.detail": "Fenster: {{window}}\nGrund: {{reason}}\nCode: {{code}}",
"desktop.recovery.unknown": "<unbekannt>",
"desktop.dialog.chooseFolder": "Ordner auswählen",
"desktop.dialog.chooseFile": "Datei auswählen",
"desktop.dialog.saveFile": "Datei speichern",
"desktop.dialog.files": "Dateien",
"desktop.server.local": "Lokaler Server",
"desktop.wsl.error.windowsOnly": "WSL ist nur unter Windows verfügbar",
"desktop.wsl.error.unavailable": "WSL ist nicht verfügbar",
"desktop.wsl.error.listInstalled": "Installierte WSL-Distributionen konnten nicht aufgelistet werden",
"desktop.wsl.error.listOnline": "Verfügbare WSL-Distributionen konnten nicht aufgelistet werden",
"desktop.wsl.error.executeDistro": "In der Distribution können keine Befehle ausgeführt werden",
"desktop.wsl.error.installWsl": "WSL-Installation fehlgeschlagen",
"desktop.wsl.error.installDistro": "Distribution konnte nicht installiert werden: {{distro}}",
"desktop.wsl.error.installOpencode": "OpenCode-Installation fehlgeschlagen",
"desktop.wsl.error.alreadyAdded": "{{distro}} wurde bereits hinzugefügt",
"desktop.wsl.error.opencodeMissing": "opencode ist in dieser Distribution nicht installiert",
"desktop.wsl.error.opencodeCannotRun": "opencode ist installiert, konnte aber nicht ausgeführt werden",
"desktop.wsl.error.opencodeNotInstalled": "OpenCode ist in {{distro}} nicht installiert",
"desktop.wsl.error.updateVersion":
"Das OpenCode-Update wurde abgeschlossen, aber {{distro}} meldet weiterhin {{installed}}; erwartet wurde {{expected}}",
"desktop.wsl.error.noVersion": "keine Version",
"desktop.wsl.error.serverExited": "WSL-Server wurde nach dem Start beendet (code={{code}} signal={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"WSL-Server wurde beendet, bevor er betriebsbereit war (code={{code}} signal={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout":
"Zeitüberschreitung bei der Integritätsprüfung des Sidecars für {{distro}} nach {{timeout}} ms",
"desktop.wsl.error.commandTimeout": "Zeitüberschreitung bei {{command}} {{args}} nach {{timeout}} ms",
"desktop.wsl.error.failedPort": "Port konnte nicht abgerufen werden",
"desktop.picker.error.notSelected": "Im Auswahldialog wurde keine Datei ausgewählt",
"desktop.picker.error.sizeLimit": "Die ausgewählten Anhänge überschreiten das Limit von {{limit}} MB",
"command.logs.export": "Protokolle exportieren",
"help.tabs.toast.ariaLabel": "Neu: Tabs. Organisieren Sie Ihre Arbeit und aktiven Sitzungen mithilfe von Tabs",
"help.tabs.toast.dismiss": "Informationen zu Tabs schließen",
"help.tabs.title": "Neu: Tabs",
"help.tabs.description": "Organisieren Sie Ihre Arbeit und aktiven Sitzungen mithilfe von Tabs",
"help.tabs.date": "14. Juli",
"help.tabs.introduction": "OpenCode Desktop basiert jetzt auf Tabs.",
"help.tabs.sessions":
"Starten Sie eine neue Sitzung in einem Tab oder öffnen Sie eine vorhandene Sitzung aus einem Ihrer Projekte. Öffnen Sie einen neuen Tab, wenn Sie etwas Neues beginnen, und schließen Sie ihn, wenn Sie fertig sind.",
"help.tabs.organize":
"Wenn Sie einige Tabs geöffnet lassen, können Sie Ihre aktiven Sitzungen leichter organisieren. Benennen Sie Tabs einprägsam, wenn Sie sie länger behalten möchten.",
"help.tabs.home":
"Auf der neuen Startseite finden Sie alle Ihre Sitzungen und Projekte. Wenn Sie eine Sitzung auswählen, wird sie in einem Tab geöffnet.",
"help.tabs.persistence": "Wenn Sie die App erneut öffnen, sind Ihre Tabs weiterhin geöffnet.",
"help.tabs.worktrees":
"Das neue Design unterstützt Git-Worktrees noch nicht. Diese Funktion folgt in Kürze. Wenn Sie das bisherige Layout vorerst weiterverwenden möchten, können Sie in den Einstellungen zwischen den Layouts wechseln. Beachten Sie jedoch, dass das neue Layout in einigen Wochen dauerhaft verwendet wird.",
} satisfies Partial<Record<Keys, string>>
@@ -0,0 +1,41 @@
import { describe, expect, test } from "bun:test"
import {
createDesktopNativeBundle,
DESKTOP_NATIVE_ENGLISH,
DESKTOP_NATIVE_KEYS,
DESKTOP_NATIVE_MAX_PAYLOAD_BYTES,
formatDesktopNativeMessage,
parseDesktopNativeBundle,
} from "./desktop-native"
describe("desktop native translations", () => {
test("accepts the exact typed bundle", () => {
const bundle = createDesktopNativeBundle("en", (key) => DESKTOP_NATIVE_ENGLISH[key])
expect(parseDesktopNativeBundle(bundle)).toEqual(bundle)
})
test("rejects unsupported locales and mismatched key sets", () => {
const bundle = createDesktopNativeBundle("en", (key) => DESKTOP_NATIVE_ENGLISH[key])
expect(parseDesktopNativeBundle({ ...bundle, locale: "en-US" })).toBeUndefined()
expect(
parseDesktopNativeBundle({
...bundle,
messages: Object.fromEntries(DESKTOP_NATIVE_KEYS.slice(1).map((key) => [key, bundle.messages[key]])),
}),
).toBeUndefined()
expect(parseDesktopNativeBundle({ ...bundle, messages: { ...bundle.messages, extra: "no" } })).toBeUndefined()
expect(
parseDesktopNativeBundle({
...bundle,
messages: { ...bundle.messages, [DESKTOP_NATIVE_KEYS[0]]: "x".repeat(DESKTOP_NATIVE_MAX_PAYLOAD_BYTES) },
}),
).toBeUndefined()
expect(
parseDesktopNativeBundle({ ...bundle, messages: { ...bundle.messages, [DESKTOP_NATIVE_KEYS[0]]: 1 } }),
).toBeUndefined()
})
test("interpolates native templates without changing unknown placeholders", () => {
expect(formatDesktopNativeMessage("{{known}} {{unknown}}", { known: "yes" })).toBe("yes {{unknown}}")
})
})
+175
View File
@@ -0,0 +1,175 @@
export const DESKTOP_NATIVE_LOCALES = [
"en",
"zh",
"zht",
"ko",
"de",
"es",
"fr",
"da",
"ja",
"pl",
"ru",
"uk",
"bs",
"ar",
"no",
"br",
"th",
"tr",
"hi",
"nl",
"id",
"vi",
"it",
"ur",
"pa",
"az",
"fi",
"sv",
] as const
export type DesktopNativeLocale = (typeof DESKTOP_NATIVE_LOCALES)[number]
export const DESKTOP_NATIVE_ENGLISH = {
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "File",
"desktop.menu.edit": "Edit",
"desktop.menu.view": "View",
"desktop.menu.go": "Go",
"desktop.menu.window": "Window",
"desktop.menu.help": "Help",
"desktop.menu.checkForUpdates": "Check for Updates...",
"desktop.menu.settings": "Settings",
"desktop.menu.reloadWebview": "Reload Webview",
"desktop.menu.restart": "Restart",
"desktop.menu.exportLogs": "Export Logs...",
"desktop.menu.newSession": "New Session",
"desktop.menu.openProject": "Open Project...",
"desktop.menu.newWindow": "New Window",
"desktop.menu.closeWindow": "Close Window",
"desktop.menu.undo": "Undo",
"desktop.menu.redo": "Redo",
"desktop.menu.cut": "Cut",
"desktop.menu.copy": "Copy",
"desktop.menu.paste": "Paste",
"desktop.menu.delete": "Delete",
"desktop.menu.selectAll": "Select All",
"desktop.menu.toggleSidebar": "Toggle Sidebar",
"desktop.menu.toggleTerminal": "Toggle Terminal",
"desktop.menu.toggleFileTree": "Toggle File Tree",
"desktop.menu.reload": "Reload",
"desktop.menu.toggleDeveloperTools": "Toggle Developer Tools",
"desktop.menu.actualSize": "Actual Size",
"desktop.menu.zoomIn": "Zoom In",
"desktop.menu.zoomOut": "Zoom Out",
"desktop.menu.toggleFullScreen": "Toggle Full Screen",
"desktop.menu.back": "Back",
"desktop.menu.forward": "Forward",
"desktop.menu.previousSession": "Previous Session",
"desktop.menu.nextSession": "Next Session",
"desktop.menu.previousProject": "Previous Project",
"desktop.menu.nextProject": "Next Project",
"desktop.menu.minimize": "Minimize",
"desktop.menu.maximize": "Maximize",
"desktop.menu.documentation": "OpenCode Documentation",
"desktop.menu.supportForum": "Support Forum",
"desktop.menu.shareFeedback": "Share Feedback",
"desktop.menu.reportBug": "Report a Bug",
"desktop.menu.ariaLabel": "OpenCode menu",
"desktop.updater.dialog.checkFailed.message": "Update check failed.",
"desktop.updater.dialog.checkFailed.title": "Update Error",
"desktop.updater.dialog.upToDate.message": "You're up to date.",
"desktop.updater.dialog.upToDate.title": "No Updates",
"desktop.updater.dialog.ready.message": "Update {{version}} downloaded. Restart now?",
"desktop.updater.dialog.ready.title": "Update Ready",
"desktop.updater.dialog.restart": "Restart",
"desktop.updater.dialog.later": "Later",
"desktop.recovery.action.relaunch": "Relaunch",
"desktop.recovery.action.exportLogs": "Export Logs",
"desktop.recovery.action.keepWaiting": "Keep Waiting",
"desktop.recovery.action.quit": "Quit",
"desktop.recovery.loadFailed": "OpenCode failed to load",
"desktop.recovery.terminated": "OpenCode window terminated unexpectedly",
"desktop.recovery.unresponsive": "OpenCode is not responding",
"desktop.recovery.unresponsive.detail": "You can relaunch the app, open the logs, or keep waiting.",
"desktop.recovery.loadFailed.detail": "Window: {{window}}\nURL: {{url}}\nError: {{code}} {{description}}",
"desktop.recovery.terminated.detail": "Window: {{window}}\nReason: {{reason}}\nCode: {{code}}",
"desktop.recovery.unknown": "<unknown>",
"desktop.dialog.chooseFolder": "Choose a folder",
"desktop.dialog.chooseFile": "Choose a file",
"desktop.dialog.saveFile": "Save file",
"desktop.dialog.files": "Files",
"desktop.server.local": "Local Server",
"desktop.wsl.error.windowsOnly": "WSL is only available on Windows",
"desktop.wsl.error.unavailable": "WSL is unavailable",
"desktop.wsl.error.listInstalled": "Failed to list installed WSL distros",
"desktop.wsl.error.listOnline": "Failed to list online WSL distros",
"desktop.wsl.error.executeDistro": "Cannot execute commands in distro",
"desktop.wsl.error.installWsl": "WSL installation failed",
"desktop.wsl.error.installDistro": "Failed to install distro: {{distro}}",
"desktop.wsl.error.installOpencode": "OpenCode installation failed",
"desktop.wsl.error.alreadyAdded": "{{distro}} is already added",
"desktop.wsl.error.opencodeMissing": "opencode is not installed in this distro",
"desktop.wsl.error.opencodeCannotRun": "opencode is installed but could not run",
"desktop.wsl.error.opencodeNotInstalled": "OpenCode is not installed in {{distro}}",
"desktop.wsl.error.updateVersion":
"OpenCode update finished but {{distro}} still reports {{installed}}; expected {{expected}}",
"desktop.wsl.error.noVersion": "no version",
"desktop.wsl.error.serverExited": "WSL server exited after startup (code={{code}} signal={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"WSL server exited before becoming healthy (code={{code}} signal={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout": "Sidecar for {{distro}} health check timed out after {{timeout}}ms",
"desktop.wsl.error.commandTimeout": "{{command}} {{args}} timed out after {{timeout}}ms",
"desktop.wsl.error.failedPort": "Failed to get port",
"desktop.picker.error.notSelected": "File was not selected by the picker",
"desktop.picker.error.sizeLimit": "Selected attachments exceed the {{limit}} MB limit",
} as const
export type DesktopNativeKey = keyof typeof DESKTOP_NATIVE_ENGLISH
export type DesktopNativeMessages = Record<DesktopNativeKey, string>
export type DesktopNativeBundle = { locale: DesktopNativeLocale; messages: DesktopNativeMessages }
export const DESKTOP_NATIVE_KEYS = Object.keys(DESKTOP_NATIVE_ENGLISH) as DesktopNativeKey[]
export const DESKTOP_NATIVE_MAX_PAYLOAD_BYTES = 64 * 1024
export function createDesktopNativeBundle(
locale: DesktopNativeLocale,
translate: (key: DesktopNativeKey) => string,
): DesktopNativeBundle {
return {
locale,
messages: Object.fromEntries(DESKTOP_NATIVE_KEYS.map((key) => [key, translate(key)])) as DesktopNativeMessages,
}
}
export function parseDesktopNativeBundle(value: unknown): DesktopNativeBundle | undefined {
if (!value || typeof value !== "object" || Array.isArray(value)) return undefined
try {
if (new TextEncoder().encode(JSON.stringify(value)).byteLength > DESKTOP_NATIVE_MAX_PAYLOAD_BYTES) return undefined
} catch {
return undefined
}
const bundle = value as { locale?: unknown; messages?: unknown }
if (!DESKTOP_NATIVE_LOCALES.some((locale) => locale === bundle.locale)) return undefined
if (!bundle.messages || typeof bundle.messages !== "object" || Array.isArray(bundle.messages)) return undefined
const messages = bundle.messages as Record<string, unknown>
const keys = Object.keys(messages)
if (keys.length !== DESKTOP_NATIVE_KEYS.length) return undefined
if (!DESKTOP_NATIVE_KEYS.every((key) => typeof messages[key] === "string")) return undefined
if (!keys.every((key) => key in DESKTOP_NATIVE_ENGLISH)) return undefined
return bundle as DesktopNativeBundle
}
export function formatDesktopNativeMessage(message: string, params?: Record<string, string | number>) {
if (!params) return message
return message.replace(/\{\{([^{}]+)\}\}/g, (match, key: string) => {
const value = params[key]
return value === undefined ? match : String(value)
})
}
+37
View File
@@ -1,4 +1,7 @@
import { DESKTOP_NATIVE_ENGLISH } from "./desktop-native"
export const dict = {
...DESKTOP_NATIVE_ENGLISH,
"command.category.suggested": "Suggested",
"command.category.view": "View",
"command.category.project": "Project",
@@ -16,6 +19,7 @@ export const dict = {
"command.category.permissions": "Permissions",
"command.category.workspace": "Workspace",
"command.category.settings": "Settings",
"command.logs.export": "Export logs",
"theme.scheme.system": "System",
"theme.scheme.light": "Light",
@@ -131,6 +135,8 @@ export const dict = {
"provider.connect.title.anthropicProMax": "Login with Claude Pro/Max",
"provider.connect.selectMethod": "Select login method for {{provider}}.",
"provider.connect.method.apiKey": "API key",
"provider.connect.method.browser": "Browser",
"provider.connect.method.headless": "Headless",
"provider.connect.status.inProgress": "Authorization in progress...",
"provider.connect.status.waiting": "Waiting for authorization...",
"provider.connect.status.failed": "Authorization failed: {{error}}",
@@ -163,6 +169,7 @@ export const dict = {
"provider.connect.toast.connected.description": "{{provider}} models are now available to use.",
"provider.custom.title": "Custom provider",
"provider.custom.unavailable": "Custom providers are unavailable on this server",
"provider.custom.description.prefix": "Configure an OpenAI-compatible provider. See the ",
"provider.custom.description.link": "provider config docs",
"provider.custom.description.suffix": ".",
@@ -437,6 +444,22 @@ export const dict = {
"wsl.onboarding.desktopVersion": "desktop {{version}}",
"wsl.onboarding.versionMismatch": "Installed version does not match the desktop app version.",
"wsl.onboarding.adding": "Adding...",
"help.tabs.toast.ariaLabel": "Introducing Tabs. Organize your work and active sessions with tabs",
"help.tabs.toast.dismiss": "Dismiss Tabs information",
"help.tabs.title": "Introducing Tabs",
"help.tabs.description": "Organize your work and active sessions with tabs",
"help.tabs.date": "July 14",
"help.tabs.introduction": "OpenCode Desktop is now built around tabs.",
"help.tabs.sessions":
"Start a new session in a tab, or open an existing session from any of your projects. Open a new tab when you're starting something new, and close it when you're done.",
"help.tabs.organize":
"Keeping a few tabs open makes it easier to organize your active sessions. Rename tabs to something memorable if you plan to keep them around.",
"help.tabs.home":
"You'll find all your sessions and projects on the new Home screen. Selecting a session opens it in a tab.",
"help.tabs.persistence": "When you reopen the app, your tabs are still open.",
"help.tabs.worktrees":
"The new design does not support Git Worktrees yet, it's coming soon. So if you'd prefer to continue using the previous layout, you can switch between layouts in Settings. Just keep in mind that the new layout will become permanent in a few weeks.",
"server.row.noUsername": "no username",
"dialog.project.edit.title": "Edit project",
@@ -765,6 +788,12 @@ export const dict = {
"terminal.connectionLost.abnormalClose": "WebSocket closed abnormally: {{code}}",
"terminal.connectionLost.description":
"The terminal connection was interrupted. This can happen when the server restarts.",
"terminal.connectTicket.csrfError":
"PTY connect ticket rejected by origin or CSRF checks. Check the server CORS config.",
"terminal.connectTicket.statusError": "PTY connect ticket failed with {{status}}",
"titlebar.update": "Update",
"titlebar.updateVersion": "Update {{version}}",
"common.closeTab": "Close tab",
"common.dismiss": "Dismiss",
@@ -839,6 +868,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Used JS heap vs heap limit. Chromium only.",
"debugBar.mem.tip": "Used JS heap vs heap limit. {{used}} of {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Force focus styles on all interactive elements",
"debugBar.focus.on": "ON",
"debugBar.focus.off": "OFF",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Force the full app layout direction without changing the selected language",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"app.name.desktop": "OpenCode Desktop",
+244 -101
View File
@@ -1,4 +1,104 @@
export const dict = {
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Archivo",
"desktop.menu.edit": "Editar",
"desktop.menu.view": "Ver",
"desktop.menu.go": "Ir",
"desktop.menu.window": "Ventana",
"desktop.menu.help": "Ayuda",
"desktop.menu.checkForUpdates": "Buscar actualizaciones...",
"desktop.menu.settings": "Ajustes",
"desktop.menu.reloadWebview": "Volver a cargar la vista web",
"desktop.menu.restart": "Reiniciar",
"desktop.menu.exportLogs": "Exportar registros...",
"desktop.menu.newSession": "Nueva sesión",
"desktop.menu.openProject": "Abrir proyecto...",
"desktop.menu.newWindow": "Nueva ventana",
"desktop.menu.closeWindow": "Cerrar ventana",
"desktop.menu.undo": "Deshacer",
"desktop.menu.redo": "Rehacer",
"desktop.menu.cut": "Cortar",
"desktop.menu.copy": "Copiar",
"desktop.menu.paste": "Pegar",
"desktop.menu.delete": "Eliminar",
"desktop.menu.selectAll": "Seleccionar todo",
"desktop.menu.toggleSidebar": "Mostrar u ocultar barra lateral",
"desktop.menu.toggleTerminal": "Mostrar u ocultar terminal",
"desktop.menu.toggleFileTree": "Mostrar u ocultar árbol de archivos",
"desktop.menu.reload": "Volver a cargar",
"desktop.menu.toggleDeveloperTools": "Mostrar u ocultar herramientas para desarrolladores",
"desktop.menu.actualSize": "Tamaño real",
"desktop.menu.zoomIn": "Ampliar",
"desktop.menu.zoomOut": "Reducir",
"desktop.menu.toggleFullScreen": "Mostrar u ocultar pantalla completa",
"desktop.menu.back": "Atrás",
"desktop.menu.forward": "Adelante",
"desktop.menu.previousSession": "Sesión anterior",
"desktop.menu.nextSession": "Siguiente sesión",
"desktop.menu.previousProject": "Proyecto anterior",
"desktop.menu.nextProject": "Siguiente proyecto",
"desktop.menu.minimize": "Minimizar",
"desktop.menu.maximize": "Maximizar",
"desktop.menu.documentation": "Documentación de OpenCode",
"desktop.menu.supportForum": "Foro de asistencia",
"desktop.menu.shareFeedback": "Enviar comentarios",
"desktop.menu.reportBug": "Informar de un error",
"desktop.menu.ariaLabel": "Menú de OpenCode",
"desktop.updater.dialog.checkFailed.message": "No se pudo buscar actualizaciones.",
"desktop.updater.dialog.checkFailed.title": "Error de actualización",
"desktop.updater.dialog.upToDate.message": "Estás al día.",
"desktop.updater.dialog.upToDate.title": "No hay actualizaciones",
"desktop.updater.dialog.ready.message": "Se ha descargado la actualización {{version}}. ¿Quieres reiniciar ahora?",
"desktop.updater.dialog.ready.title": "Actualización lista",
"desktop.updater.dialog.restart": "Reiniciar",
"desktop.updater.dialog.later": "Más tarde",
"desktop.recovery.action.relaunch": "Volver a iniciar",
"desktop.recovery.action.exportLogs": "Exportar registros",
"desktop.recovery.action.keepWaiting": "Seguir esperando",
"desktop.recovery.action.quit": "Salir",
"desktop.recovery.loadFailed": "No se pudo cargar OpenCode",
"desktop.recovery.terminated": "La ventana de OpenCode se cerró de forma inesperada",
"desktop.recovery.unresponsive": "OpenCode no responde",
"desktop.recovery.unresponsive.detail":
"Puedes volver a iniciar la aplicación, abrir los registros o seguir esperando.",
"desktop.recovery.loadFailed.detail": "Ventana: {{window}}\nURL: {{url}}\nError: {{code}} {{description}}",
"desktop.recovery.terminated.detail": "Ventana: {{window}}\nMotivo: {{reason}}\nCódigo: {{code}}",
"desktop.recovery.unknown": "<desconocido>",
"desktop.dialog.chooseFolder": "Elegir una carpeta",
"desktop.dialog.chooseFile": "Elegir un archivo",
"desktop.dialog.saveFile": "Guardar archivo",
"desktop.dialog.files": "Archivos",
"desktop.server.local": "Servidor local",
"desktop.wsl.error.windowsOnly": "WSL solo está disponible en Windows",
"desktop.wsl.error.unavailable": "WSL no está disponible",
"desktop.wsl.error.listInstalled": "No se pudieron listar las distribuciones WSL instaladas",
"desktop.wsl.error.listOnline": "No se pudieron listar las distribuciones WSL en línea",
"desktop.wsl.error.executeDistro": "No se pueden ejecutar comandos en la distribución",
"desktop.wsl.error.installWsl": "No se pudo instalar WSL",
"desktop.wsl.error.installDistro": "No se pudo instalar la distribución: {{distro}}",
"desktop.wsl.error.installOpencode": "No se pudo instalar OpenCode",
"desktop.wsl.error.alreadyAdded": "Ya se ha añadido {{distro}}",
"desktop.wsl.error.opencodeMissing": "opencode no está instalado en esta distribución",
"desktop.wsl.error.opencodeCannotRun": "opencode está instalado, pero no se pudo ejecutar",
"desktop.wsl.error.opencodeNotInstalled": "OpenCode no está instalado en {{distro}}",
"desktop.wsl.error.updateVersion":
"La actualización de OpenCode finalizó, pero {{distro}} sigue indicando {{installed}}; se esperaba {{expected}}",
"desktop.wsl.error.noVersion": "sin versión",
"desktop.wsl.error.serverExited": "El servidor WSL se cerró después de iniciarse (código={{code}} señal={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"El servidor WSL se cerró antes de estar operativo (código={{code}} señal={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout":
"Se agotó el tiempo de espera de la comprobación de estado del sidecar de {{distro}} tras {{timeout}} ms",
"desktop.wsl.error.commandTimeout": "Se agotó el tiempo de espera de {{command}} {{args}} tras {{timeout}} ms",
"desktop.wsl.error.failedPort": "No se pudo obtener el puerto",
"desktop.picker.error.notSelected": "No se seleccionó ningún archivo en el selector",
"desktop.picker.error.sizeLimit": "Los adjuntos seleccionados superan el límite de {{limit}} MB",
"command.category.suggested": "Sugerido",
"command.category.view": "Ver",
"command.category.project": "Proyecto",
@@ -16,12 +116,13 @@ export const dict = {
"command.category.permissions": "Permisos",
"command.category.workspace": "Espacio de trabajo",
"command.category.settings": "Ajustes",
"command.logs.export": "Exportar registros",
"theme.scheme.system": "Sistema",
"theme.scheme.light": "Claro",
"theme.scheme.dark": "Oscuro",
"command.sidebar.toggle": "Alternar barra lateral",
"command.sidebar.toggle": "Mostrar u ocultar barra lateral",
"command.project.open": "Abrir proyecto",
"command.project.previous": "Proyecto anterior",
"command.project.next": "Siguiente proyecto",
@@ -37,12 +138,12 @@ export const dict = {
"command.palette": "Paleta de comandos",
"command.theme.cycle": "Alternar tema",
"command.theme.cycle": "Cambiar tema",
"command.theme.set": "Usar tema: {{theme}}",
"command.theme.scheme.cycle": "Alternar esquema de color",
"command.theme.scheme.cycle": "Cambiar esquema de color",
"command.theme.scheme.set": "Usar esquema de color: {{scheme}}",
"command.language.cycle": "Alternar idioma",
"command.language.cycle": "Cambiar idioma",
"command.language.set": "Usar idioma: {{language}}",
"command.session.new": "Nueva sesión",
@@ -52,12 +153,12 @@ export const dict = {
"command.context.addSelection": "Añadir selección al contexto",
"command.context.addSelection.description": "Añadir las líneas seleccionadas del archivo actual",
"command.input.focus": "Enfocar entrada",
"command.terminal.toggle": "Alternar terminal",
"command.fileTree.toggle": "Alternar árbol de archivos",
"command.review.toggle": "Alternar revisión",
"command.terminal.toggle": "Mostrar u ocultar terminal",
"command.fileTree.toggle": "Mostrar u ocultar árbol de archivos",
"command.review.toggle": "Mostrar u ocultar revisión",
"command.terminal.new": "Nueva terminal",
"command.terminal.new.description": "Crear una nueva pestaña de terminal",
"command.steps.toggle": "Alternar pasos",
"command.steps.toggle": "Mostrar u ocultar pasos",
"command.steps.toggle.description": "Mostrar u ocultar pasos para el mensaje actual",
"command.message.previous": "Mensaje anterior",
"command.message.previous.description": "Ir al mensaje de usuario anterior",
@@ -65,19 +166,19 @@ export const dict = {
"command.message.next.description": "Ir al siguiente mensaje de usuario",
"command.model.choose": "Elegir modelo",
"command.model.choose.description": "Seleccionar un modelo diferente",
"command.mcp.toggle": "Alternar MCPs",
"command.mcp.toggle.description": "Alternar MCPs",
"command.agent.cycle": "Alternar agente",
"command.mcp.toggle": "Activar o desactivar servidores MCP",
"command.mcp.toggle.description": "Activar o desactivar servidores MCP",
"command.agent.cycle": "Cambiar de agente",
"command.agent.cycle.description": "Cambiar al siguiente agente",
"command.agent.cycle.reverse": "Alternar agente hacia atrás",
"command.agent.cycle.reverse": "Cambiar al agente anterior",
"command.agent.cycle.reverse.description": "Cambiar al agente anterior",
"command.model.variant.cycle": "Alternar esfuerzo de pensamiento",
"command.model.variant.cycle": "Cambiar esfuerzo de razonamiento",
"command.model.variant.cycle.description": "Cambiar al siguiente nivel de esfuerzo",
"command.prompt.mode.shell": "Shell",
"command.prompt.mode.normal": "Prompt",
"command.permissions.autoaccept.enable": "Aceptar permisos automáticamente",
"command.permissions.autoaccept.disable": "Dejar de aceptar permisos automáticamente",
"command.workspace.toggle": "Alternar espacios de trabajo",
"command.workspace.toggle": "Activar o desactivar espacios de trabajo",
"command.workspace.toggle.description": "Habilitar o deshabilitar múltiples espacios de trabajo en la barra lateral",
"command.session.undo": "Deshacer",
"command.session.undo.description": "Deshacer el último mensaje",
@@ -100,17 +201,18 @@ export const dict = {
"dialog.provider.search.placeholder": "Buscar proveedores",
"dialog.provider.empty": "No se encontraron proveedores",
"dialog.provider.group.popular": "Popular",
"dialog.provider.group.other": "Otro",
"dialog.provider.group.popular": "Populares",
"dialog.provider.group.other": "Otros",
"dialog.provider.custom.label": "Proveedor personalizado compatible con OpenAI",
"dialog.provider.tag.recommended": "Recomendado",
"dialog.provider.opencode.note": "Modelos seleccionados incluyendo Claude, GPT, Gemini y s",
"dialog.provider.opencode.note": "Selección de modelos como Claude, GPT, Gemini y otros",
"dialog.provider.opencode.tagline": "Modelos optimizados y fiables",
"dialog.provider.opencodeGo.tagline": "Suscripción económica para todos",
"dialog.provider.anthropic.note": "Acceso directo a modelos Claude, incluyendo Pro y Max",
"dialog.provider.anthropic.note": "Acceso directo a modelos Claude, incluidos Pro y Max",
"dialog.provider.copilot.note": "Modelos de IA para asistencia de codificación a través de GitHub Copilot",
"dialog.provider.openai.note": "Modelos GPT para tareas de IA generales rápidas y capaces",
"dialog.provider.google.note": "Modelos Gemini para respuestas rápidas y estructuradas",
"dialog.provider.openrouter.note": "Accede a todos los modelos soportados desde un solo proveedor",
"dialog.provider.openrouter.note": "Accede a todos los modelos compatibles desde un solo proveedor",
"dialog.provider.vercel.note": "Acceso unificado a modelos de IA con enrutamiento inteligente",
"dialog.model.select.title": "Seleccionar modelo",
@@ -118,10 +220,11 @@ export const dict = {
"dialog.model.empty": "Sin resultados de modelos",
"dialog.model.manage": "Gestionar modelos",
"dialog.model.manage.description": "Personalizar qué modelos aparecen en el selector de modelos.",
"dialog.model.manage.provider.toggle": "Alternar todos los modelos de {{provider}}",
"dialog.model.manage.provider.toggle": "Mostrar u ocultar todos los modelos de {{provider}}",
"dialog.model.unpaid.freeModels.title": "Modelos gratuitos proporcionados por OpenCode",
"dialog.model.unpaid.addMore.title": "Añadir más modelos de proveedores populares",
"dialog.model.unpaid.viewMoreProviders": "Ver más de 70 proveedores",
"dialog.provider.viewAll": "Ver más proveedores",
@@ -129,6 +232,8 @@ export const dict = {
"provider.connect.title.anthropicProMax": "Iniciar sesión con Claude Pro/Max",
"provider.connect.selectMethod": "Seleccionar método de inicio de sesión para {{provider}}.",
"provider.connect.method.apiKey": "Clave API",
"provider.connect.method.browser": "Navegador",
"provider.connect.method.headless": "Sin navegador",
"provider.connect.status.inProgress": "Autorización en progreso...",
"provider.connect.status.waiting": "Esperando autorización...",
"provider.connect.status.failed": "Autorización fallida: {{error}}",
@@ -161,6 +266,7 @@ export const dict = {
"provider.connect.toast.connected.description": "Los modelos de {{provider}} ahora están disponibles para usar.",
"provider.custom.title": "Proveedor personalizado",
"provider.custom.unavailable": "Los proveedores personalizados no están disponibles en este servidor",
"provider.custom.description.prefix": "Configurar un proveedor compatible con OpenAI. Ver la ",
"provider.custom.description.link": "documentación de configuración del proveedor",
"provider.custom.description.suffix": ".",
@@ -173,7 +279,8 @@ export const dict = {
"provider.custom.field.baseURL.placeholder": "https://api.miproveedor.com/v1",
"provider.custom.field.apiKey.label": "Clave API",
"provider.custom.field.apiKey.placeholder": "Clave API",
"provider.custom.field.apiKey.description": "Opcional. Dejar vacío si gestionas la autenticación mediante cabeceras.",
"provider.custom.field.apiKey.description":
"Opcional. Déjalo vacío si gestionas la autenticación mediante encabezados.",
"provider.custom.models.label": "Modelos",
"provider.custom.models.id.label": "ID",
"provider.custom.models.id.placeholder": "id-modelo",
@@ -181,13 +288,13 @@ export const dict = {
"provider.custom.models.name.placeholder": "Nombre para mostrar",
"provider.custom.models.remove": "Eliminar modelo",
"provider.custom.models.add": "Añadir modelo",
"provider.custom.headers.label": "Cabeceras (opcional)",
"provider.custom.headers.key.label": "Cabecera",
"provider.custom.headers.key.placeholder": "Nombre-Cabecera",
"provider.custom.headers.label": "Encabezados (opcional)",
"provider.custom.headers.key.label": "Encabezado",
"provider.custom.headers.key.placeholder": "Nombre-Encabezado",
"provider.custom.headers.value.label": "Valor",
"provider.custom.headers.value.placeholder": "valor",
"provider.custom.headers.remove": "Eliminar cabecera",
"provider.custom.headers.add": "Añadir cabecera",
"provider.custom.headers.remove": "Eliminar encabezado",
"provider.custom.headers.add": "Añadir encabezado",
"provider.custom.error.providerID.required": "El ID del proveedor es obligatorio",
"provider.custom.error.providerID.format": "Usa letras minúsculas, números, guiones o guiones bajos",
"provider.custom.error.providerID.exists": "Ese ID de proveedor ya existe",
@@ -201,7 +308,7 @@ export const dict = {
"provider.disconnect.toast.disconnected.description": "Los modelos de {{provider}} ya no están disponibles.",
"model.tag.free": "Gratis",
"model.tag.latest": "Último",
"model.tag.latest": "Más reciente",
"model.provider.anthropic": "Anthropic",
"model.provider.openai": "OpenAI",
"model.provider.google": "Google",
@@ -211,7 +318,7 @@ export const dict = {
"model.input.image": "imagen",
"model.input.audio": "audio",
"model.input.video": "video",
"model.input.pdf": "pdf",
"model.input.pdf": "PDF",
"model.tooltip.allows": "Permite: {{inputs}}",
"model.tooltip.context.label": "Contexto",
"model.tooltip.inputs": "Entradas",
@@ -231,7 +338,7 @@ export const dict = {
"common.clear": "Limpiar",
"common.connect": "Conectar",
"common.disconnect": "Desconectar",
"common.continue": "Enviar",
"common.continue": "Continuar",
"common.submit": "Enviar",
"common.save": "Guardar",
"common.saving": "Guardando...",
@@ -250,7 +357,7 @@ export const dict = {
"session.child.backToParent": "Volver a la sesión principal.",
"prompt.example.1": "Arreglar un TODO en el código",
"prompt.example.2": "¿Cuál es el stack tecnológico de este proyecto?",
"prompt.example.2": "¿Qué tecnologías usa este proyecto?",
"prompt.example.3": "Arreglar pruebas rotas",
"prompt.example.4": "Explicar cómo funciona la autenticación",
"prompt.example.5": "Encontrar y arreglar vulnerabilidades de seguridad",
@@ -263,22 +370,22 @@ export const dict = {
"prompt.example.12": "Añadir validación de entrada",
"prompt.example.13": "Crear un nuevo componente para...",
"prompt.example.14": "¿Cómo despliego este proyecto?",
"prompt.example.15": "Revisar mi código para mejores prácticas",
"prompt.example.16": "Añadir manejo de errores a esta función",
"prompt.example.17": "Explicar este patrón de regex",
"prompt.example.15": "Revisar si mi código sigue las prácticas recomendadas",
"prompt.example.16": "Añadir gestión de errores a esta función",
"prompt.example.17": "Explicar este patrón de expresión regular",
"prompt.example.18": "Convertir esto a TypeScript",
"prompt.example.19": "Añadir logging en todo el código",
"prompt.example.19": "Añadir registros en todo el código",
"prompt.example.20": "¿Qué dependencias están desactualizadas?",
"prompt.example.21": "Ayúdame a escribir un script de migración",
"prompt.example.22": "Implementar caché para este endpoint",
"prompt.example.22": "Implementar caché para este punto de conexión",
"prompt.example.23": "Añadir paginación a esta lista",
"prompt.example.24": "Crear un comando CLI para...",
"prompt.example.25": "¿Cómo funcionan las variables de entorno aquí?",
"prompt.popover.emptyResults": "Sin resultados coincidentes",
"prompt.popover.emptyCommands": "Sin comandos coincidentes",
"prompt.dropzone.label": "Suelta imágenes, PDFs o archivos de texto aquí",
"prompt.dropzone.file.label": "Suelta para @mencionar archivo",
"prompt.dropzone.label": "Suelta aquí imágenes, archivos PDF o archivos de texto",
"prompt.dropzone.file.label": "Suelta para @mencionar el archivo",
"prompt.slash.badge.custom": "personalizado",
"prompt.slash.badge.skill": "skill",
"prompt.slash.badge.mcp": "mcp",
@@ -286,7 +393,7 @@ export const dict = {
"prompt.context.includeActiveFile": "Incluir archivo activo",
"prompt.context.removeActiveFile": "Eliminar archivo activo del contexto",
"prompt.context.removeFile": "Eliminar archivo del contexto",
"prompt.action.attachFile": "Adjuntar archivo",
"prompt.action.attachFile": "Añadir archivos",
"prompt.menu.addImagesAndFiles": "Añadir archivos y más",
"prompt.menu.imagesAndFiles": "Imágenes y archivos",
"prompt.menu.commands": "Comandos",
@@ -298,7 +405,8 @@ export const dict = {
"prompt.toast.pasteUnsupported.title": "Adjunto no compatible",
"prompt.toast.attachmentDuplicate.title": "Este archivo ya se ha subido",
"prompt.toast.pasteUnsupported.description": "Solo se pueden adjuntar imágenes, PDFs o archivos de texto aquí.",
"prompt.toast.pasteUnsupported.description":
"Aquí solo se pueden adjuntar imágenes, archivos PDF o archivos de texto.",
"prompt.toast.modelAgentRequired.title": "Selecciona un agente y modelo",
"prompt.toast.modelAgentRequired.description": "Elige un agente y modelo antes de enviar un prompt.",
"prompt.toast.worktreeCreateFailed.title": "Fallo al crear el árbol de trabajo",
@@ -308,16 +416,16 @@ export const dict = {
"prompt.toast.promptSendFailed.title": "Fallo al enviar prompt",
"prompt.toast.promptSendFailed.description": "No se pudo recuperar la sesión",
"dialog.mcp.title": "MCPs",
"dialog.mcp.title": "Servidores MCP",
"dialog.mcp.description": "{{enabled}} de {{total}} habilitados",
"dialog.mcp.empty": "No hay MCPs configurados",
"dialog.mcp.empty": "No hay servidores MCP configurados",
"dialog.lsp.empty": "LSPs detectados automáticamente por tipo de archivo",
"dialog.lsp.empty": "Servidores LSP detectados automáticamente por tipo de archivo",
"dialog.plugins.empty": "Plugins configurados en opencode.json",
"mcp.status.connected": "conectado",
"mcp.status.failed": "fallido",
"mcp.status.needs_auth": "necesita auth",
"mcp.status.needs_auth": "requiere autenticación",
"mcp.auth.clickToAuthenticate": "Haz clic para autenticar",
"mcp.status.disabled": "deshabilitado",
@@ -328,13 +436,13 @@ export const dict = {
"dialog.directory.action.selectFile": "Seleccionar archivo",
"dialog.directory.action.selectFolder": "Seleccionar carpeta",
"dialog.directory.root": "Raíz",
"dialog.directory.parent": "Superior",
"dialog.directory.parent": "Carpeta superior",
"dialog.directory.readError": "No se puede leer esta carpeta",
"dialog.server.title": "Servidores",
"dialog.server.description": "Cambiar a qué servidor de OpenCode se conecta esta app.",
"dialog.server.description": "Cambiar el servidor de OpenCode al que se conecta esta aplicación.",
"dialog.server.search.placeholder": "Buscar servidores",
"dialog.server.empty": "No hay servidores aún",
"dialog.server.empty": "Aún no hay servidores",
"dialog.server.add.title": "Añadir un servidor",
"dialog.server.add.url": "URL del servidor",
"dialog.server.add.placeholder": "http://localhost:4096",
@@ -348,7 +456,7 @@ export const dict = {
"dialog.server.edit.title": "Editar servidor",
"dialog.server.default.title": "Servidor predeterminado",
"dialog.server.default.description":
"Conectar a este servidor al iniciar la app en lugar de iniciar un servidor local. Requiere reinicio.",
"Conectar a este servidor al iniciar la aplicación en lugar de iniciar un servidor local. Requiere reiniciar.",
"dialog.server.default.none": "Ningún servidor seleccionado",
"dialog.server.default.set": "Establecer servidor actual como predeterminado",
"dialog.server.default.clear": "Limpiar",
@@ -356,7 +464,7 @@ export const dict = {
"dialog.server.menu.edit": "Editar",
"dialog.server.menu.default": "Establecer como predeterminado",
"dialog.server.menu.defaultRemove": "Quitar predeterminado",
"dialog.server.menu.defaultRemove": "Quitar como predeterminado",
"dialog.server.menu.delete": "Eliminar",
"dialog.server.current": "Servidor actual",
"dialog.server.status.default": "Predeterminado",
@@ -430,6 +538,22 @@ export const dict = {
"wsl.onboarding.versionMismatch": "La versión instalada no coincide con la versión de la aplicación de escritorio.",
"wsl.onboarding.adding": "Añadiendo...",
"help.tabs.toast.ariaLabel": "Presentamos las pestañas. Organiza tu trabajo y las sesiones activas con pestañas",
"help.tabs.toast.dismiss": "Descartar información sobre las pestañas",
"help.tabs.title": "Presentamos las pestañas",
"help.tabs.description": "Organiza tu trabajo y las sesiones activas con pestañas",
"help.tabs.date": "14 de julio",
"help.tabs.introduction": "OpenCode Desktop ahora se organiza en torno a pestañas.",
"help.tabs.sessions":
"Inicia una nueva sesión en una pestaña o abre una sesión existente de cualquiera de tus proyectos. Abre una pestaña nueva cuando empieces algo nuevo y ciérrala cuando termines.",
"help.tabs.organize":
"Mantener algunas pestañas abiertas facilita la organización de las sesiones activas. Cambia el nombre de las pestañas por uno fácil de recordar si piensas conservarlas.",
"help.tabs.home":
"Encontrarás todas tus sesiones y proyectos en la nueva pantalla Inicio. Al seleccionar una sesión, se abre en una pestaña.",
"help.tabs.persistence": "Cuando vuelvas a abrir la aplicación, las pestañas seguirán abiertas.",
"help.tabs.worktrees":
"El nuevo diseño aún no admite Git Worktrees, pero estarán disponibles pronto. Si prefieres seguir usando el diseño anterior, puedes cambiar de diseño en Ajustes. Ten en cuenta que el nuevo diseño será permanente dentro de unas semanas.",
"dialog.project.edit.title": "Editar proyecto",
"dialog.project.edit.name": "Nombre",
"dialog.project.edit.icon": "Icono",
@@ -443,7 +567,7 @@ export const dict = {
"Se ejecuta después de crear un nuevo espacio de trabajo (árbol de trabajo).",
"dialog.project.edit.worktree.startup.placeholder": "p. ej. bun install",
"context.breakdown.title": "Desglose de Contexto",
"context.breakdown.title": "Desglose del contexto",
"context.breakdown.note":
'Desglose aproximado de tokens de entrada. "Otro" incluye definiciones de herramientas y sobrecarga.',
"context.breakdown.system": "Sistema",
@@ -452,25 +576,25 @@ export const dict = {
"context.breakdown.tool": "Llamadas a herramientas",
"context.breakdown.other": "Otro",
"context.systemPrompt.title": "Prompt del Sistema",
"context.systemPrompt.title": "Prompt del sistema",
"context.rawMessages.title": "Mensajes en bruto",
"context.stats.session": "Sesión",
"context.stats.messages": "Mensajes",
"context.stats.provider": "Proveedor",
"context.stats.model": "Modelo",
"context.stats.limit": "Límite de Contexto",
"context.stats.totalTokens": "Tokens Totales",
"context.stats.limit": "Límite de contexto",
"context.stats.totalTokens": "Tokens totales",
"context.stats.usage": "Uso",
"context.stats.inputTokens": "Tokens de Entrada",
"context.stats.outputTokens": "Tokens de Salida",
"context.stats.reasoningTokens": "Tokens de Razonamiento",
"context.stats.cacheTokens": "Tokens de Caché (lectura/escritura)",
"context.stats.userMessages": "Mensajes de Usuario",
"context.stats.assistantMessages": "Mensajes de Asistente",
"context.stats.totalCost": "Costo Total",
"context.stats.sessionCreated": "Sesión Creada",
"context.stats.lastActivity": "Última Actividad",
"context.stats.inputTokens": "Tokens de entrada",
"context.stats.outputTokens": "Tokens de salida",
"context.stats.reasoningTokens": "Tokens de razonamiento",
"context.stats.cacheTokens": "Tokens de caché (lectura/escritura)",
"context.stats.userMessages": "Mensajes de usuario",
"context.stats.assistantMessages": "Mensajes de asistente",
"context.stats.totalCost": "Costo total",
"context.stats.sessionCreated": "Sesión creada",
"context.stats.lastActivity": "Última actividad",
"context.usage.tokens": "Tokens",
"context.usage.usage": "Uso",
@@ -524,12 +648,12 @@ export const dict = {
"toast.session.share.copyFailed.title": "Fallo al copiar URL al portapapeles",
"toast.session.share.success.title": "Sesión compartida",
"toast.session.share.success.description": "¡URL compartida copiada al portapapeles!",
"toast.session.share.success.description": "Enlace para compartir copiado al portapapeles.",
"toast.session.share.failed.title": "Fallo al compartir sesión",
"toast.session.share.failed.description": "Ocurrió un error al compartir la sesión",
"toast.session.unshare.success.title": "Sesión dejó de compartirse",
"toast.session.unshare.success.description": "¡La sesión dejó de compartirse exitosamente!",
"toast.session.unshare.success.title": "La sesión dejó de compartirse",
"toast.session.unshare.success.description": "La sesión dejó de compartirse correctamente.",
"toast.session.unshare.failed.title": "Fallo al dejar de compartir sesión",
"toast.session.unshare.failed.description": "Ocurrió un error al dejar de compartir la sesión",
@@ -545,13 +669,13 @@ export const dict = {
"error.page.description.localServerStartup": "Ocurrió un error al iniciar el servidor local.",
"error.page.details.label": "Detalles del error",
"error.page.action.restart": "Reiniciar",
"error.page.action.report": "Informar error",
"error.page.action.reported": "Error informado",
"error.page.action.report": "Informar del error",
"error.page.action.reported": "Error notificado",
"error.page.action.exportLogs": "Exportar registros",
"error.page.action.checking": "Comprobando...",
"error.page.action.checkUpdates": "Buscar actualizaciones",
"error.page.action.updateTo": "Actualizar a {{version}}",
"error.page.report.prefix": "Por favor reporta este error al equipo de OpenCode",
"error.page.report.prefix": "Informa de este error al equipo de OpenCode",
"error.page.report.discord": "en Discord",
"error.page.version": "Versión: {{version}}",
@@ -567,10 +691,10 @@ export const dict = {
"error.chain.status": "Estado: {{status}}",
"error.chain.retryable": "Reintentable: {{retryable}}",
"error.chain.responseBody": "Cuerpo de la respuesta:\n{{body}}",
"error.chain.didYouMean": "¿Quisiste decir: {{suggestions}}",
"error.chain.didYouMean": "¿Quizá quisiste decir {{suggestions}}?",
"error.chain.modelNotFound": "Modelo no encontrado: {{provider}}/{{model}}",
"error.chain.checkConfig": "Comprueba los nombres de proveedor/modelo en tu configuración (opencode.json)",
"error.chain.mcpFailed": 'El servidor MCP "{{name}}" falló. Nota, OpenCode no soporta autenticación MCP todavía.',
"error.chain.mcpFailed": 'El servidor MCP "{{name}}" falló. Nota: OpenCode aún no admite la autenticación MCP.',
"error.chain.providerAuthFailed": "Autenticación de proveedor fallida ({{provider}}): {{message}}",
"error.chain.providerInitFailed":
'Fallo al inicializar proveedor "{{provider}}". Comprueba credenciales y configuración.',
@@ -623,12 +747,12 @@ export const dict = {
"session.error.notFound.description": "Esta pestaña apunta a una sesión que ya no existe en este servidor.",
"session.error.notFound.closeTab": "Cerrar pestaña",
"session.error.serverConnection": "No se puede conectar a este servidor",
"session.review.filesChanged": "{{count}} Archivos Cambiados",
"session.review.filesChanged": "Archivos modificados: {{count}}",
"session.review.change.one": "Cambio",
"session.review.change.other": "Cambios",
"session.review.loadingChanges": "Cargando cambios...",
"session.review.empty": "No hay cambios en esta sesión aún",
"session.review.noVcs": "No se detectó Sistema de Control de Versiones Git, los cambios no se muestran",
"session.review.empty": "Aún no hay cambios en esta sesión",
"session.review.noVcs": "No se detectó ningún sistema de control de versiones Git; no se muestran los cambios",
"session.review.noSnapshot":
"El seguimiento de instantáneas está deshabilitado en la configuración, por lo que los cambios de sesión no están disponibles",
"session.review.noChanges": "Sin cambios",
@@ -638,13 +762,13 @@ export const dict = {
"session.files.selectToOpen": "Selecciona un archivo para abrir",
"session.files.all": "Todos los archivos",
"session.files.empty": "Sin archivos",
"session.files.binaryContent": "Archivo binario (el contenido no puede ser mostrado)",
"session.files.binaryContent": "Archivo binario (no se puede mostrar el contenido)",
"session.messages.renderEarlier": "Renderizar mensajes anteriores",
"session.messages.renderEarlier": "Mostrar mensajes anteriores",
"session.messages.loadingEarlier": "Cargando mensajes anteriores...",
"session.messages.loadEarlier": "Cargar mensajes anteriores",
"session.messages.loading": "Cargando mensajes...",
"session.messages.jumpToLatest": "Ir al último",
"session.messages.jumpToLatest": "Ir al mensaje más reciente",
"session.context.addToContext": "Añadir {{selection}} al contexto",
"session.todo.title": "Tareas",
@@ -653,14 +777,17 @@ export const dict = {
"session.question.minimize": "Minimizar pregunta",
"session.question.restore": "Restaurar pregunta",
"session.question.pending.one": "{{count}} pregunta pendiente",
"session.question.pending.many": "{{count}} de preguntas pendientes",
"session.question.pending.other": "{{count}} preguntas pendientes",
"session.followupDock.summary.one": "{{count}} mensaje en cola",
"session.followupDock.summary.many": "{{count}} de mensajes en cola",
"session.followupDock.summary.other": "{{count}} mensajes en cola",
"session.followupDock.sendNow": "Enviar ahora",
"session.followupDock.edit": "Editar",
"session.followupDock.collapse": "Contraer mensajes en cola",
"session.followupDock.expand": "Expandir mensajes en cola",
"session.revertDock.summary.one": "{{count}} mensaje revertido",
"session.revertDock.summary.many": "{{count}} de mensajes revertidos",
"session.revertDock.summary.other": "{{count}} mensajes revertidos",
"session.revertDock.collapse": "Contraer mensajes revertidos",
"session.revertDock.expand": "Expandir mensajes revertidos",
@@ -694,9 +821,9 @@ export const dict = {
"status.popover.tab.mcp": "MCP",
"status.popover.tab.lsp": "LSP",
"status.popover.tab.plugins": "Plugins",
"status.popover.action.manageServers": "Administrar servidores",
"status.popover.action.manageServers": "Gestionar servidores",
"session.share.popover.title": "Publicar en web",
"session.share.popover.title": "Publicar en la web",
"session.share.popover.description.shared":
"Esta sesión es pública en la web. Es accesible para cualquiera con el enlace.",
"session.share.popover.description.unshared":
@@ -721,12 +848,18 @@ export const dict = {
"terminal.connectionLost.title": "Conexión perdida",
"terminal.connectionLost.description":
"La conexión del terminal se interrumpió. Esto puede ocurrir cuando el servidor se reinicia.",
"terminal.connectTicket.csrfError":
"El ticket de conexión PTY fue rechazado por las comprobaciones de origen o CSRF. Comprueba la configuración CORS del servidor.",
"terminal.connectTicket.statusError": "El ticket de conexión PTY falló con {{status}}",
"titlebar.update": "Actualizar",
"titlebar.updateVersion": "Actualizar {{version}}",
"common.closeTab": "Cerrar pestaña",
"common.dismiss": "Descartar",
"common.requestFailed": "Solicitud fallida",
"common.moreOptions": "Más opciones",
"common.learnMore": "Saber más",
"common.learnMore": "Más información",
"common.rename": "Renombrar",
"common.reset": "Restablecer",
"common.archive": "Archivar",
@@ -736,15 +869,15 @@ export const dict = {
"common.loadMore": "Cargar más",
"common.key.esc": "ESC",
"sidebar.menu.toggle": "Alternar menú",
"sidebar.menu.toggle": "Mostrar u ocultar menú",
"sidebar.nav.projectsAndSessions": "Proyectos y sesiones",
"sidebar.settings": "Ajustes",
"sidebar.help": "Ayuda",
"sidebar.workspaces.enable": "Habilitar espacios de trabajo",
"sidebar.workspaces.disable": "Deshabilitar espacios de trabajo",
"sidebar.gettingStarted.title": "Empezando",
"sidebar.gettingStarted.title": "Primeros pasos",
"sidebar.gettingStarted.line1": "OpenCode incluye modelos gratuitos para que puedas empezar inmediatamente.",
"sidebar.gettingStarted.line2": "Conecta cualquier proveedor para usar modelos, inc. Claude, GPT, Gemini etc.",
"sidebar.gettingStarted.line2": "Conecta cualquier proveedor para usar modelos como Claude, GPT o Gemini.",
"sidebar.project.recentSessions": "Sesiones recientes",
"sidebar.project.viewAllSessions": "Ver todas las sesiones",
"sidebar.project.clearNotifications": "Borrar notificaciones",
@@ -772,9 +905,8 @@ export const dict = {
"settings.general.row.language.title": "Idioma",
"settings.general.row.language.description": "Cambiar el idioma de visualización para OpenCode",
"settings.general.row.shell.title": "Shell del terminal",
"settings.general.row.shell.description":
"Elige el shell que se usará en el terminal. Los shells compatibles también se usarán para las llamadas a herramientas del agente.",
"settings.general.row.shell.autoDefault": "Automático (Predeterminado)",
"settings.general.row.shell.description": "Shell que usan el terminal y las herramientas del agente",
"settings.general.row.shell.autoDefault": "Automático (predeterminado)",
"settings.general.row.shell.terminalOnly": "solo en el terminal",
"settings.general.row.appearance.title": "Apariencia",
"settings.general.row.appearance.description": "Personaliza cómo se ve OpenCode en tu dispositivo",
@@ -808,8 +940,9 @@ export const dict = {
"settings.general.row.mobileTitlebarBottom.title": "Navegación inferior",
"settings.general.row.mobileTitlebarBottom.description":
"Colocar la barra de título y las pestañas de sesión en la parte inferior de la pantalla en dispositivos móviles",
"settings.general.row.showCustomAgents.title": "Agentes personalizados",
"settings.general.row.showCustomAgents.description": "Mostrar el selector de agentes en el editor",
"settings.general.row.showCustomAgents.title": "Mostrar agente",
"settings.general.row.showCustomAgents.description":
"Cambiar de agente en el editor. Si se oculta, se usa el agente Build de forma predeterminada.",
"settings.general.row.reasoningSummaries.title": "Mostrar resúmenes de razonamiento",
"settings.general.row.reasoningSummaries.description":
"Mostrar resúmenes del razonamiento del modelo en la línea de tiempo",
@@ -828,9 +961,9 @@ export const dict = {
"settings.general.row.newInterfaceNotice.dismiss": "Descartar",
"settings.general.row.pinchZoom.title": "Pellizcar para ampliar",
"settings.general.row.pinchZoom.description":
"Permitir ampliar con el gesto de pellizco del panel táctil y con Ctrl-scroll",
"Permitir ampliar con el gesto de pellizco del panel táctil y con Ctrl + desplazamiento",
"settings.general.row.wayland.title": "Usar Wayland nativo",
"settings.general.row.wayland.description": "Deshabilitar fallback a X11 en Wayland. Requiere reinicio.",
"settings.general.row.wayland.description": "Deshabilitar el uso alternativo de X11 en Wayland. Requiere reiniciar.",
"settings.general.row.wayland.tooltip":
"En Linux con monitores de frecuencia de actualización mixta, Wayland nativo puede ser más estable.",
@@ -960,8 +1093,7 @@ export const dict = {
"settings.permissions.tool.read.title": "Leer",
"settings.permissions.tool.read.description": "Leer un archivo (coincide con la ruta del archivo)",
"settings.permissions.tool.edit.title": "Editar",
"settings.permissions.tool.edit.description":
"Modificar archivos, incluyendo ediciones, escrituras, parches y multi-ediciones",
"settings.permissions.tool.edit.description": "Modificar archivos mediante ediciones, escrituras y parches",
"settings.permissions.tool.glob.title": "Glob",
"settings.permissions.tool.glob.description": "Coincidir archivos usando patrones glob",
"settings.permissions.tool.grep.title": "Grep",
@@ -971,20 +1103,20 @@ export const dict = {
"settings.permissions.tool.bash.title": "Bash",
"settings.permissions.tool.bash.description": "Ejecutar comandos de shell",
"settings.permissions.tool.task.title": "Tarea",
"settings.permissions.tool.task.description": "Lanzar sub-agentes",
"settings.permissions.tool.task.description": "Iniciar subagentes",
"settings.permissions.tool.skill.title": "Habilidad",
"settings.permissions.tool.skill.description": "Cargar una habilidad por nombre",
"settings.permissions.tool.lsp.title": "LSP",
"settings.permissions.tool.lsp.description": "Ejecutar consultas de servidor de lenguaje",
"settings.permissions.tool.todowrite.title": "Escribir Todo",
"settings.permissions.tool.todowrite.title": "Escribir tareas",
"settings.permissions.tool.todowrite.description": "Actualizar la lista de tareas",
"settings.permissions.tool.webfetch.title": "Web Fetch",
"settings.permissions.tool.webfetch.title": "Obtener contenido web",
"settings.permissions.tool.webfetch.description": "Obtener contenido de una URL",
"settings.permissions.tool.websearch.title": "Búsqueda Web",
"settings.permissions.tool.websearch.title": "Búsqueda web",
"settings.permissions.tool.websearch.description": "Buscar en la web",
"settings.permissions.tool.external_directory.title": "Directorio Externo",
"settings.permissions.tool.external_directory.title": "Directorio externo",
"settings.permissions.tool.external_directory.description": "Acceder a archivos fuera del directorio del proyecto",
"settings.permissions.tool.doom_loop.title": "Bucle Infinito",
"settings.permissions.tool.doom_loop.title": "Bucle infinito",
"settings.permissions.tool.doom_loop.description": "Detectar llamadas a herramientas repetidas con entrada idéntica",
"session.delete.failed.title": "Fallo al eliminar sesión",
@@ -998,13 +1130,13 @@ export const dict = {
"workspace.create.failed.title": "Fallo al crear espacio de trabajo",
"workspace.delete.failed.title": "Fallo al eliminar espacio de trabajo",
"workspace.resetting.title": "Restableciendo espacio de trabajo",
"workspace.resetting.description": "Esto puede tomar un minuto.",
"workspace.resetting.description": "Esto puede tardar un minuto.",
"workspace.reset.failed.title": "Fallo al restablecer espacio de trabajo",
"workspace.reset.success.title": "Espacio de trabajo restablecido",
"workspace.reset.success.description": "El espacio de trabajo ahora coincide con la rama predeterminada.",
"workspace.error.stillPreparing": "El espacio de trabajo aún se está preparando",
"workspace.status.checking": "Comprobando cambios no fusionados...",
"workspace.status.error": "No se pudo verificar el estado de git.",
"workspace.status.error": "No se pudo verificar el estado de Git.",
"workspace.status.clean": "No se detectaron cambios no fusionados.",
"workspace.status.dirty": "Cambios no fusionados detectados en este espacio de trabajo.",
"workspace.delete.title": "Eliminar espacio de trabajo",
@@ -1046,6 +1178,9 @@ export const dict = {
"session.question.progress": "{{current}} de {{total}} preguntas",
"session.header.open.finder": "Finder",
"session.header.open.fileExplorer": "Explorador de archivos",
"session.header.reveal.finder": "Mostrar en Finder",
"session.header.reveal.fileExplorer": "Mostrar en el Explorador de archivos",
"session.header.reveal.containingFolder": "Abrir carpeta contenedora",
"session.header.open.fileManager": "Gestor de archivos",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -1064,13 +1199,13 @@ export const dict = {
"debugBar.na": "n/d",
"debugBar.nav.label": "NAV",
"debugBar.nav.tip":
"Última transición de ruta completada tocando una página de sesión, medida desde el inicio del router hasta el primer pintado después de asentarse.",
"Última transición de ruta completada que afecta a una página de sesión, medida desde el inicio del enrutador hasta el primer renderizado tras estabilizarse.",
"debugBar.fps.label": "FPS",
"debugBar.fps.tip": "Cuadros por segundo en los últimos 5 segundos.",
"debugBar.frame.label": "FRAME",
"debugBar.frame.tip": "Peor tiempo de cuadro en los últimos 5 segundos.",
"debugBar.jank.label": "JANK",
"debugBar.jank.tip": "Cuadros superiores a 32ms en los últimos 5 segundos.",
"debugBar.jank.tip": "Cuadros superiores a 32 ms en los últimos 5 segundos.",
"debugBar.long.label": "LONG",
"debugBar.long.tip": "Tiempo bloqueado y recuento de tareas largas en los últimos 5 segundos. Tarea máx: {{max}}.",
"debugBar.delay.label": "DELAY",
@@ -1079,10 +1214,18 @@ export const dict = {
"debugBar.inp.tip":
"Duración aproximada de la interacción en los últimos 5 segundos. Esto es similar a INP, no el INP oficial de Web Vitals.",
"debugBar.cls.label": "CLS",
"debugBar.cls.tip": "Cambio de diseño acumulativo para la vida útil actual de la aplicación.",
"debugBar.cls.tip": "Cambio de diseño acumulativo durante la ejecución actual de la aplicación.",
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Heap JS usado vs límite de heap. Solo Chromium.",
"debugBar.mem.tip": "Heap JS usado vs límite de heap. {{used}} de {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Forzar los estilos de foco en todos los elementos interactivos",
"debugBar.focus.on": "SÍ",
"debugBar.focus.off": "NO",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Forzar la dirección del diseño de toda la aplicación sin cambiar el idioma seleccionado",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Mayús",
File diff suppressed because it is too large Load Diff
+236 -88
View File
@@ -1,4 +1,104 @@
export const dict = {
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Fichier",
"desktop.menu.edit": "Édition",
"desktop.menu.view": "Affichage",
"desktop.menu.go": "Aller",
"desktop.menu.window": "Fenêtre",
"desktop.menu.help": "Aide",
"desktop.menu.checkForUpdates": "Rechercher les mises à jour...",
"desktop.menu.settings": "Paramètres",
"desktop.menu.reloadWebview": "Recharger la vue Web",
"desktop.menu.restart": "Redémarrer",
"desktop.menu.exportLogs": "Exporter les journaux...",
"desktop.menu.newSession": "Nouvelle session",
"desktop.menu.openProject": "Ouvrir un projet...",
"desktop.menu.newWindow": "Nouvelle fenêtre",
"desktop.menu.closeWindow": "Fermer la fenêtre",
"desktop.menu.undo": "Annuler",
"desktop.menu.redo": "Rétablir",
"desktop.menu.cut": "Couper",
"desktop.menu.copy": "Copier",
"desktop.menu.paste": "Coller",
"desktop.menu.delete": "Supprimer",
"desktop.menu.selectAll": "Tout sélectionner",
"desktop.menu.toggleSidebar": "Afficher ou masquer la barre latérale",
"desktop.menu.toggleTerminal": "Afficher ou masquer le terminal",
"desktop.menu.toggleFileTree": "Afficher ou masquer l'arborescence des fichiers",
"desktop.menu.reload": "Recharger",
"desktop.menu.toggleDeveloperTools": "Afficher ou masquer les outils de développement",
"desktop.menu.actualSize": "Taille réelle",
"desktop.menu.zoomIn": "Zoom avant",
"desktop.menu.zoomOut": "Zoom arrière",
"desktop.menu.toggleFullScreen": "Activer ou désactiver le mode plein écran",
"desktop.menu.back": "Précédent",
"desktop.menu.forward": "Suivant",
"desktop.menu.previousSession": "Session précédente",
"desktop.menu.nextSession": "Session suivante",
"desktop.menu.previousProject": "Projet précédent",
"desktop.menu.nextProject": "Projet suivant",
"desktop.menu.minimize": "Réduire",
"desktop.menu.maximize": "Agrandir",
"desktop.menu.documentation": "Documentation d'OpenCode",
"desktop.menu.supportForum": "Forum d'assistance",
"desktop.menu.shareFeedback": "Envoyer des commentaires",
"desktop.menu.reportBug": "Signaler un bogue",
"desktop.menu.ariaLabel": "Menu OpenCode",
"desktop.updater.dialog.checkFailed.message": "La recherche de mises à jour a échoué.",
"desktop.updater.dialog.checkFailed.title": "Erreur de mise à jour",
"desktop.updater.dialog.upToDate.message": "Vous êtes à jour.",
"desktop.updater.dialog.upToDate.title": "Aucune mise à jour",
"desktop.updater.dialog.ready.message": "La mise à jour {{version}} a été téléchargée. Redémarrer maintenant ?",
"desktop.updater.dialog.ready.title": "Mise à jour prête",
"desktop.updater.dialog.restart": "Redémarrer",
"desktop.updater.dialog.later": "Plus tard",
"desktop.recovery.action.relaunch": "Relancer",
"desktop.recovery.action.exportLogs": "Exporter les journaux",
"desktop.recovery.action.keepWaiting": "Continuer d'attendre",
"desktop.recovery.action.quit": "Quitter",
"desktop.recovery.loadFailed": "Échec du chargement d'OpenCode",
"desktop.recovery.terminated": "La fenêtre OpenCode s'est arrêtée de manière inattendue",
"desktop.recovery.unresponsive": "OpenCode ne répond pas",
"desktop.recovery.unresponsive.detail":
"Vous pouvez relancer l'application, ouvrir les journaux ou continuer d'attendre.",
"desktop.recovery.loadFailed.detail": "Fenêtre : {{window}}\nURL : {{url}}\nErreur : {{code}} {{description}}",
"desktop.recovery.terminated.detail": "Fenêtre : {{window}}\nMotif : {{reason}}\nCode : {{code}}",
"desktop.recovery.unknown": "<inconnu>",
"desktop.dialog.chooseFolder": "Sélectionner un dossier",
"desktop.dialog.chooseFile": "Sélectionner un fichier",
"desktop.dialog.saveFile": "Enregistrer le fichier",
"desktop.dialog.files": "Fichiers",
"desktop.server.local": "Serveur local",
"desktop.wsl.error.windowsOnly": "WSL est disponible uniquement sous Windows",
"desktop.wsl.error.unavailable": "WSL est indisponible",
"desktop.wsl.error.listInstalled": "Impossible de répertorier les distributions WSL installées",
"desktop.wsl.error.listOnline": "Impossible de répertorier les distributions WSL en ligne",
"desktop.wsl.error.executeDistro": "Impossible d'exécuter des commandes dans la distribution",
"desktop.wsl.error.installWsl": "Échec de l'installation de WSL",
"desktop.wsl.error.installDistro": "Échec de l'installation de la distribution : {{distro}}",
"desktop.wsl.error.installOpencode": "Échec de l'installation d'OpenCode",
"desktop.wsl.error.alreadyAdded": "{{distro}} a déjà été ajoutée",
"desktop.wsl.error.opencodeMissing": "opencode n'est pas installé dans cette distribution",
"desktop.wsl.error.opencodeCannotRun": "opencode est installé, mais n'a pas pu s'exécuter",
"desktop.wsl.error.opencodeNotInstalled": "OpenCode n'est pas installé dans {{distro}}",
"desktop.wsl.error.updateVersion":
"La mise à jour d'OpenCode est terminée, mais {{distro}} indique toujours {{installed}} au lieu de {{expected}}",
"desktop.wsl.error.noVersion": "aucune version",
"desktop.wsl.error.serverExited": "Le serveur WSL s'est arrêté après son démarrage (code={{code}} signal={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"Le serveur WSL s'est arrêté avant d'être opérationnel (code={{code}} signal={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout":
"La vérification de l'état du processus auxiliaire pour {{distro}} a dépassé le délai de {{timeout}} ms",
"desktop.wsl.error.commandTimeout": "{{command}} {{args}} a dépassé le délai de {{timeout}} ms",
"desktop.wsl.error.failedPort": "Impossible d'obtenir le port",
"desktop.picker.error.notSelected": "Aucun fichier n'a été sélectionné dans le sélecteur",
"desktop.picker.error.sizeLimit": "Les pièces jointes sélectionnées dépassent la limite de {{limit}} Mo",
"command.category.suggested": "Suggéré",
"command.category.view": "Affichage",
"command.category.project": "Projet",
@@ -16,6 +116,7 @@ export const dict = {
"command.category.permissions": "Permissions",
"command.category.workspace": "Espace de travail",
"command.category.settings": "Paramètres",
"command.logs.export": "Exporter les journaux",
"theme.scheme.system": "Système",
"theme.scheme.light": "Clair",
"theme.scheme.dark": "Sombre",
@@ -29,8 +130,8 @@ export const dict = {
"command.settings.open": "Ouvrir les paramètres",
"command.session.previous": "Session précédente",
"command.session.next": "Session suivante",
"command.session.previous.unseen": "Session non lue précédente",
"command.session.next.unseen": "Session non lue suivante",
"command.session.previous.unseen": "Session précédente non lue",
"command.session.next.unseen": "Session suivante non lue",
"command.session.archive": "Archiver la session",
"command.palette": "Palette de commandes",
"command.theme.cycle": "Changer de thème",
@@ -45,7 +146,7 @@ export const dict = {
"command.tab.reopenClosed": "Rouvrir l'onglet fermé",
"command.context.addSelection": "Ajouter la sélection au contexte",
"command.context.addSelection.description": "Ajouter les lignes sélectionnées du fichier actuel",
"command.input.focus": "Focus sur l'entrée",
"command.input.focus": "Activer la zone de saisie",
"command.terminal.toggle": "Basculer le terminal",
"command.fileTree.toggle": "Basculer l'arborescence des fichiers",
"command.review.toggle": "Basculer la revue",
@@ -59,8 +160,8 @@ export const dict = {
"command.message.next.description": "Aller au message utilisateur suivant",
"command.model.choose": "Choisir le modèle",
"command.model.choose.description": "Sélectionner un modèle différent",
"command.mcp.toggle": "Basculer MCP",
"command.mcp.toggle.description": "Basculer les MCPs",
"command.mcp.toggle": "Activer ou désactiver les MCP",
"command.mcp.toggle.description": "Activer ou désactiver les MCP",
"command.agent.cycle": "Changer d'agent",
"command.agent.cycle.description": "Passer à l'agent suivant",
"command.agent.cycle.reverse": "Changer d'agent (inverse)",
@@ -68,7 +169,7 @@ export const dict = {
"command.model.variant.cycle": "Changer l'effort de réflexion",
"command.model.variant.cycle.description": "Passer au niveau d'effort suivant",
"command.prompt.mode.shell": "Shell",
"command.prompt.mode.normal": "Prompt",
"command.prompt.mode.normal": "Invite",
"command.permissions.autoaccept.enable": "Accepter automatiquement les permissions",
"command.permissions.autoaccept.disable": "Arrêter d'accepter automatiquement les permissions",
"command.workspace.toggle": "Basculer les espaces de travail",
@@ -92,8 +193,9 @@ export const dict = {
"palette.group.files": "Fichiers",
"dialog.provider.search.placeholder": "Rechercher des fournisseurs",
"dialog.provider.empty": "Aucun fournisseur trouvé",
"dialog.provider.group.popular": "Populaire",
"dialog.provider.group.other": "Autre",
"dialog.provider.group.popular": "Populaires",
"dialog.provider.group.other": "Autres",
"dialog.provider.custom.label": "Fournisseur personnalisé compatible avec OpenAI",
"dialog.provider.tag.recommended": "Recommandé",
"dialog.provider.opencode.note": "Modèles sélectionnés incluant Claude, GPT, Gemini et plus",
"dialog.provider.opencode.tagline": "Modèles optimisés et fiables",
@@ -109,14 +211,17 @@ export const dict = {
"dialog.model.empty": "Aucun résultat de modèle",
"dialog.model.manage": "Gérer les modèles",
"dialog.model.manage.description": "Personnalisez les modèles qui apparaissent dans le sélecteur.",
"dialog.model.manage.provider.toggle": "Basculer tous les modèles {{provider}}",
"dialog.model.manage.provider.toggle": "Activer ou désactiver tous les modèles {{provider}}",
"dialog.model.unpaid.freeModels.title": "Modèles gratuits fournis par OpenCode",
"dialog.model.unpaid.addMore.title": "Ajouter plus de modèles de fournisseurs populaires",
"dialog.model.unpaid.viewMoreProviders": "Voir plus de 70 autres fournisseurs",
"dialog.provider.viewAll": "Voir plus de fournisseurs",
"provider.connect.title": "Connecter {{provider}}",
"provider.connect.title.anthropicProMax": "Connexion avec Claude Pro/Max",
"provider.connect.selectMethod": "Sélectionnez la méthode de connexion pour {{provider}}.",
"provider.connect.method.apiKey": "Clé API",
"provider.connect.method.browser": "Navigateur",
"provider.connect.method.headless": "Mode headless",
"provider.connect.status.inProgress": "Autorisation en cours...",
"provider.connect.status.waiting": "En attente d'autorisation...",
"provider.connect.status.failed": "Échec de l'autorisation : {{error}}",
@@ -148,19 +253,22 @@ export const dict = {
"provider.connect.toast.connected.title": "{{provider}} connecté",
"provider.connect.toast.connected.description": "Les modèles {{provider}} sont maintenant disponibles.",
"provider.custom.title": "Fournisseur personnalisé",
"provider.custom.description.prefix": "Configurer un fournisseur compatible OpenAI. Voir la ",
"provider.custom.description.link": "doc de config fournisseur",
"provider.custom.unavailable": "Les fournisseurs personnalisés ne sont pas disponibles sur ce serveur",
"provider.custom.description.prefix": "Configurez un fournisseur compatible avec OpenAI. Consultez la ",
"provider.custom.description.link": "documentation sur la configuration des fournisseurs",
"provider.custom.description.suffix": ".",
"provider.custom.field.providerID.label": "ID du fournisseur",
"provider.custom.field.providerID.placeholder": "monfournisseur",
"provider.custom.field.providerID.description": "Lettres minuscules, chiffres, traits d'union ou tirets bas",
"provider.custom.field.providerID.description":
"Lettres minuscules, chiffres, traits d'union ou traits de soulignement",
"provider.custom.field.name.label": "Nom d'affichage",
"provider.custom.field.name.placeholder": "Mon fournisseur IA",
"provider.custom.field.baseURL.label": "URL de base",
"provider.custom.field.baseURL.placeholder": "https://api.monfournisseur.com/v1",
"provider.custom.field.apiKey.label": "Clé API",
"provider.custom.field.apiKey.placeholder": "Clé API",
"provider.custom.field.apiKey.description": "Optionnel. Laisser vide si vous gérez l'auth via les en-têtes.",
"provider.custom.field.apiKey.description":
"Facultatif. Laissez ce champ vide si vous gérez l'authentification au moyen des en-têtes.",
"provider.custom.models.label": "Modèles",
"provider.custom.models.id.label": "ID",
"provider.custom.models.id.placeholder": "id-modele",
@@ -176,7 +284,8 @@ export const dict = {
"provider.custom.headers.remove": "Supprimer l'en-tête",
"provider.custom.headers.add": "Ajouter un en-tête",
"provider.custom.error.providerID.required": "L'ID du fournisseur est requis",
"provider.custom.error.providerID.format": "Utilisez des lettres minuscules, chiffres, traits d'union ou tirets bas",
"provider.custom.error.providerID.format":
"Utilisez des lettres minuscules, des chiffres, des traits d'union ou des traits de soulignement",
"provider.custom.error.providerID.exists": "Cet ID de fournisseur existe déjà",
"provider.custom.error.name.required": "Le nom d'affichage est requis",
"provider.custom.error.baseURL.required": "L'URL de base est requise",
@@ -186,7 +295,7 @@ export const dict = {
"provider.disconnect.toast.disconnected.title": "{{provider}} déconnecté",
"provider.disconnect.toast.disconnected.description": "Les modèles {{provider}} ne sont plus disponibles.",
"model.tag.free": "Gratuit",
"model.tag.latest": "Dernier",
"model.tag.latest": "Le plus récent",
"model.provider.anthropic": "Anthropic",
"model.provider.openai": "OpenAI",
"model.provider.google": "Google",
@@ -197,29 +306,29 @@ export const dict = {
"model.input.audio": "audio",
"model.input.video": "vidéo",
"model.input.pdf": "pdf",
"model.tooltip.allows": "Autorise : {{inputs}}",
"model.tooltip.allows": "Formats pris en charge : {{inputs}}",
"model.tooltip.context.label": "Contexte",
"model.tooltip.inputs": "Entrées",
"model.tooltip.model": "Modèle",
"model.tooltip.provider": "Fournisseur",
"model.tooltip.reasoning": "Raisonnement",
"model.tooltip.reasoning.allowed": "Autorise le raisonnement",
"model.tooltip.reasoning.allowed": "Raisonnement pris en charge",
"model.tooltip.reasoning.none": "Sans raisonnement",
"model.tooltip.context": "Limite de contexte {{limit}}",
"common.search.placeholder": "Rechercher",
"common.goBack": "Retour",
"common.goForward": "Avancer",
"common.goForward": "Suivant",
"common.loading": "Chargement",
"common.loading.ellipsis": "...",
"common.cancel": "Annuler",
"common.clear": "Effacer",
"common.connect": "Connecter",
"common.disconnect": "Déconnecter",
"common.continue": "Soumettre",
"common.continue": "Continuer",
"common.submit": "Soumettre",
"common.save": "Enregistrer",
"common.saving": "Enregistrement...",
"common.default": "Défaut",
"common.default": "Par défaut",
"common.attachment": "pièce jointe",
"prompt.placeholder.shell": "Entrez une commande shell... {{example}}",
"prompt.placeholder.normal": 'Demandez n\'importe quoi... "{{example}}"',
@@ -227,8 +336,8 @@ export const dict = {
"prompt.placeholder.summarizeComments": "Résumer les commentaires…",
"prompt.placeholder.summarizeComment": "Résumer le commentaire…",
"prompt.mode.shell": "Shell",
"prompt.mode.normal": "Prompt",
"prompt.mode.shell.exit": "esc pour quitter",
"prompt.mode.normal": "Invite",
"prompt.mode.shell.exit": "Échap pour quitter",
"session.child.promptDisabled": "Les sessions de sous-agents ne peuvent pas recevoir de messages.",
"session.child.backToParent": "Revenir à la session principale.",
"prompt.example.1": "Corriger un TODO dans la base de code",
@@ -237,7 +346,7 @@ export const dict = {
"prompt.example.4": "Expliquer comment fonctionne l'authentification",
"prompt.example.5": "Trouver et corriger les vulnérabilités de sécurité",
"prompt.example.6": "Ajouter des tests unitaires pour le service utilisateur",
"prompt.example.7": "Refactoriser cette fonction pour être plus lisible",
"prompt.example.7": "Refactoriser cette fonction pour la rendre plus lisible",
"prompt.example.8": "Que signifie cette erreur ?",
"prompt.example.9": "Aidez-moi à déboguer ce problème",
"prompt.example.10": "Générer la documentation de l'API",
@@ -245,11 +354,11 @@ export const dict = {
"prompt.example.12": "Ajouter une validation d'entrée",
"prompt.example.13": "Créer un nouveau composant pour...",
"prompt.example.14": "Comment déployer ce projet ?",
"prompt.example.15": "Vérifier mon code pour les meilleures pratiques",
"prompt.example.15": "Vérifier que mon code respecte les bonnes pratiques",
"prompt.example.16": "Ajouter la gestion des erreurs à cette fonction",
"prompt.example.17": "Expliquer ce modèle regex",
"prompt.example.17": "Expliquer cette expression régulière",
"prompt.example.18": "Convertir ceci en TypeScript",
"prompt.example.19": "Ajouter des logs dans toute la base de code",
"prompt.example.19": "Ajouter une journalisation dans toute la base de code",
"prompt.example.20": "Quelles dépendances sont obsolètes ?",
"prompt.example.21": "Aidez-moi à écrire un script de migration",
"prompt.example.22": "Implémenter la mise en cache pour ce point de terminaison",
@@ -261,7 +370,7 @@ export const dict = {
"prompt.dropzone.label": "Déposez des images, des PDF ou des fichiers texte ici",
"prompt.dropzone.file.label": "Déposez pour @mentionner le fichier",
"prompt.slash.badge.custom": "personnalisé",
"prompt.slash.badge.skill": "skill",
"prompt.slash.badge.skill": "compétence",
"prompt.slash.badge.mcp": "mcp",
"prompt.context.active": "actif",
"prompt.context.includeActiveFile": "Inclure le fichier actif",
@@ -281,21 +390,21 @@ export const dict = {
"prompt.toast.pasteUnsupported.description":
"Seules les images, les PDF ou les fichiers texte peuvent être joints ici.",
"prompt.toast.modelAgentRequired.title": "Sélectionnez un agent et un modèle",
"prompt.toast.modelAgentRequired.description": "Choisissez un agent et un modèle avant d'envoyer un message.",
"prompt.toast.modelAgentRequired.description": "Choisissez un agent et un modèle avant d'envoyer une invite.",
"prompt.toast.worktreeCreateFailed.title": "Échec de la création de l'arbre de travail",
"prompt.toast.sessionCreateFailed.title": "Échec de la création de la session",
"prompt.toast.shellSendFailed.title": "Échec de l'envoi de la commande shell",
"prompt.toast.commandSendFailed.title": "Échec de l'envoi de la commande",
"prompt.toast.promptSendFailed.title": "Échec de l'envoi du message",
"prompt.toast.promptSendFailed.title": "Échec de l'envoi de l'invite",
"prompt.toast.promptSendFailed.description": "Impossible de récupérer la session",
"dialog.mcp.title": "MCPs",
"dialog.mcp.description": "{{enabled}} sur {{total}} activés",
"dialog.mcp.title": "MCP",
"dialog.mcp.description": "MCP actifs : {{enabled}} sur {{total}}",
"dialog.mcp.empty": "Aucun MCP configuré",
"dialog.lsp.empty": "LSPs détectés automatiquement par type de fichier",
"dialog.plugins.empty": "Plugins configurés dans opencode.json",
"dialog.lsp.empty": "Serveurs LSP détectés automatiquement selon le type de fichier",
"dialog.plugins.empty": "Extensions configurées dans opencode.json",
"mcp.status.connected": "connecté",
"mcp.status.failed": "échoué",
"mcp.status.needs_auth": "nécessite auth",
"mcp.status.failed": "en échec",
"mcp.status.needs_auth": "authentification requise",
"mcp.auth.clickToAuthenticate": "Cliquez pour vous authentifier",
"mcp.status.disabled": "désactivé",
"dialog.fork.empty": "Aucun message à partir duquel bifurquer",
@@ -330,7 +439,7 @@ export const dict = {
"dialog.server.action.remove": "Supprimer le serveur",
"dialog.server.menu.edit": "Modifier",
"dialog.server.menu.default": "Définir par défaut",
"dialog.server.menu.defaultRemove": "Supprimer par défaut",
"dialog.server.menu.defaultRemove": "Ne plus utiliser par défaut",
"dialog.server.menu.delete": "Supprimer",
"dialog.server.current": "Serveur actuel",
"dialog.server.status.default": "Défaut",
@@ -400,9 +509,25 @@ export const dict = {
"wsl.onboarding.notFound": "introuvable",
"wsl.onboarding.version": "Version : {{version}}",
"wsl.onboarding.unknown": "inconnue",
"wsl.onboarding.desktopVersion": "desktop {{version}}",
"wsl.onboarding.versionMismatch": "La version installée ne correspond pas à celle de l'application desktop.",
"wsl.onboarding.desktopVersion": "application de bureau {{version}}",
"wsl.onboarding.versionMismatch": "La version installée ne correspond pas à celle de l'application de bureau.",
"wsl.onboarding.adding": "Ajout...",
"help.tabs.toast.ariaLabel":
"Présentation des onglets. Organisez votre travail et vos sessions actives à l'aide d'onglets",
"help.tabs.toast.dismiss": "Ignorer les informations sur les onglets",
"help.tabs.title": "Présentation des onglets",
"help.tabs.description": "Organisez votre travail et vos sessions actives à l'aide d'onglets",
"help.tabs.date": "14 juillet",
"help.tabs.introduction": "OpenCode Desktop s'articule désormais autour d'onglets.",
"help.tabs.sessions":
"Démarrez une nouvelle session dans un onglet ou ouvrez une session existante depuis l'un de vos projets. Ouvrez un nouvel onglet lorsque vous commencez une nouvelle tâche et fermez-le une fois celle-ci terminée.",
"help.tabs.organize":
"Garder quelques onglets ouverts facilite l'organisation de vos sessions actives. Si vous comptez les conserver, renommez-les pour pouvoir les reconnaître facilement.",
"help.tabs.home":
"Vous trouverez toutes vos sessions et tous vos projets sur le nouvel écran d'accueil. La sélection d'une session l'ouvre dans un onglet.",
"help.tabs.persistence": "Lorsque vous rouvrez l'application, vos onglets sont toujours ouverts.",
"help.tabs.worktrees":
"La nouvelle interface ne prend pas encore en charge les arbres de travail Git, mais cette fonctionnalité sera bientôt disponible. Si vous préférez continuer à utiliser la mise en page précédente, vous pouvez changer de mise en page dans les paramètres. N'oubliez pas que la nouvelle mise en page deviendra définitive dans quelques semaines.",
"dialog.project.edit.title": "Modifier le projet",
"dialog.project.edit.name": "Nom",
"dialog.project.edit.icon": "Icône",
@@ -417,13 +542,13 @@ export const dict = {
"dialog.project.edit.worktree.startup.placeholder": "p. ex. bun install",
"context.breakdown.title": "Répartition du contexte",
"context.breakdown.note":
"Répartition approximative des jetons d'entrée. \"Autre\" inclut les définitions d'outils et les frais généraux.",
"Répartition approximative des jetons d'entrée. \"Autre\" inclut les définitions d'outils et les données annexes.",
"context.breakdown.system": "Système",
"context.breakdown.user": "Utilisateur",
"context.breakdown.assistant": "Assistant",
"context.breakdown.tool": "Appels d'outils",
"context.breakdown.other": "Autre",
"context.systemPrompt.title": "Prompt système",
"context.systemPrompt.title": "Invite système",
"context.rawMessages.title": "Messages bruts",
"context.stats.session": "Session",
"context.stats.messages": "Messages",
@@ -437,7 +562,7 @@ export const dict = {
"context.stats.reasoningTokens": "Jetons de raisonnement",
"context.stats.cacheTokens": "Jetons de cache (lecture/écriture)",
"context.stats.userMessages": "Messages utilisateur",
"context.stats.assistantMessages": "Messages assistant",
"context.stats.assistantMessages": "Messages de l'assistant",
"context.stats.totalCost": "Coût total",
"context.stats.sessionCreated": "Session créée",
"context.stats.lastActivity": "Dernière activité",
@@ -465,16 +590,16 @@ export const dict = {
"language.th": "ไทย",
"language.tr": "Türkçe",
"toast.language.title": "Langue",
"toast.language.description": "Passé à {{language}}",
"toast.language.description": "Langue définie sur {{language}}",
"toast.theme.title": "Thème changé",
"toast.scheme.title": "Schéma de couleurs",
"toast.workspace.enabled.title": "Espaces de travail activés",
"toast.workspace.enabled.description": "Plusieurs worktrees sont désormais affichés dans la barre latérale",
"toast.workspace.enabled.description": "Plusieurs arbres de travail sont désormais affichés dans la barre latérale",
"toast.workspace.disabled.title": "Espaces de travail désactivés",
"toast.workspace.disabled.description": "Seul le worktree principal est affiché dans la barre latérale",
"toast.workspace.disabled.description": "Seul l'arbre de travail principal est affiché dans la barre latérale",
"toast.permissions.autoaccept.on.title": "Acceptation automatique des permissions",
"toast.permissions.autoaccept.on.description": "Les demandes de permission seront approuvées automatiquement",
"toast.permissions.autoaccept.off.title": "Acceptation automatique des permissions arrêtée",
"toast.permissions.autoaccept.off.title": "Acceptation automatique des permissions désactivée",
"toast.permissions.autoaccept.off.description": "Les demandes de permission nécessiteront une approbation",
"toast.model.none.title": "Aucun modèle sélectionné",
"toast.model.none.description": "Connectez un fournisseur pour résumer cette session",
@@ -487,17 +612,18 @@ export const dict = {
"toast.session.share.success.description": "URL de partage copiée dans le presse-papiers !",
"toast.session.share.failed.title": "Échec du partage de la session",
"toast.session.share.failed.description": "Une erreur s'est produite lors du partage de la session",
"toast.session.unshare.success.title": "Session non partagée",
"toast.session.unshare.success.description": "Session non partagée avec succès !",
"toast.session.unshare.failed.title": "Échec de l'annulation du partage",
"toast.session.unshare.failed.description": "Une erreur s'est produite lors de l'annulation du partage de la session",
"toast.session.unshare.success.title": "Partage de la session désactivé",
"toast.session.unshare.success.description": "Le partage de la session a bien été désactivé.",
"toast.session.unshare.failed.title": "Échec de la désactivation du partage",
"toast.session.unshare.failed.description":
"Une erreur s'est produite lors de la désactivation du partage de la session",
"toast.session.listFailed.title": "Échec du chargement des sessions pour {{project}}",
"toast.update.title": "Mise à jour disponible",
"toast.update.description":
"Une nouvelle version d'OpenCode ({{version}}) est maintenant disponible pour installation.",
"toast.update.action.installRestart": "Installer et redémarrer",
"toast.update.action.notYet": "Pas encore",
"error.page.title": "Quelque chose s'est mal passé",
"toast.update.action.notYet": "Plus tard",
"error.page.title": "Un problème est survenu",
"error.page.description": "Une erreur s'est produite lors du chargement de l'application.",
"error.page.description.localServerStartup": "Une erreur s'est produite lors du démarrage du serveur local.",
"error.page.details.label": "Détails de l'erreur",
@@ -520,13 +646,13 @@ export const dict = {
"error.chain.causedBy": "Causé par :",
"error.chain.apiError": "Erreur API",
"error.chain.status": "Statut : {{status}}",
"error.chain.retryable": "Réessayable : {{retryable}}",
"error.chain.retryable": "Nouvelle tentative possible : {{retryable}}",
"error.chain.responseBody": "Corps de la réponse :\n{{body}}",
"error.chain.didYouMean": "Vouliez-vous dire : {{suggestions}}",
"error.chain.modelNotFound": "Modèle introuvable : {{provider}}/{{model}}",
"error.chain.checkConfig": "Vérifiez votre configuration (opencode.json) pour les noms de fournisseur/modèle",
"error.chain.checkConfig": "Vérifiez les noms de fournisseur et de modèle dans votre configuration (opencode.json)",
"error.chain.mcpFailed":
"Le serveur MCP \"{{name}}\" a échoué. Notez qu'OpenCode ne supporte pas encore l'authentification MCP.",
"Le serveur MCP \"{{name}}\" a échoué. Notez qu'OpenCode ne prend pas encore en charge l'authentification MCP.",
"error.chain.providerAuthFailed": "Échec de l'authentification du fournisseur ({{provider}}) : {{message}}",
"error.chain.providerInitFailed":
'Échec de l\'initialisation du fournisseur "{{provider}}". Vérifiez les identifiants et la configuration.',
@@ -535,7 +661,7 @@ export const dict = {
"Le fichier de configuration à {{path}} n'est pas un JSON(C) valide : {{message}}",
"error.chain.configDirectoryTypo":
'Le répertoire "{{dir}}" dans {{path}} n\'est pas valide. Renommez le répertoire en "{{suggestion}}" ou supprimez-le. C\'est une faute de frappe courante.',
"error.chain.configFrontmatterError": "Échec de l'analyse du frontmatter dans {{path}} :\n{{message}}",
"error.chain.configFrontmatterError": "Échec de l'analyse de l'en-tête dans {{path}} :\n{{message}}",
"error.chain.configInvalid": "Le fichier de configuration à {{path}} est invalide",
"error.chain.configInvalidWithMessage": "Le fichier de configuration à {{path}} est invalide : {{message}}",
"notification.permission.title": "Permission requise",
@@ -583,7 +709,7 @@ export const dict = {
"session.review.noChanges": "Aucune modification",
"session.review.noUncommittedChanges": "Aucune modification non validée pour l'instant",
"session.review.noBranchChanges": "Aucune modification de branche pour l'instant",
"session.review.noVcs": "Aucun système de contrôle de version Git détecté, modifications non affichées",
"session.review.noVcs": "Aucun système de gestion de versions Git détecté ; modifications non affichées",
"session.review.noSnapshot":
"Le suivi des instantanés est désactivé dans la configuration, les modifications de session sont donc indisponibles",
"session.files.selectToOpen": "Sélectionnez un fichier à ouvrir",
@@ -594,7 +720,7 @@ export const dict = {
"session.messages.loadingEarlier": "Chargement des messages précédents...",
"session.messages.loadEarlier": "Charger les messages précédents",
"session.messages.loading": "Chargement des messages...",
"session.messages.jumpToLatest": "Aller au dernier",
"session.messages.jumpToLatest": "Aller au message le plus récent",
"session.context.addToContext": "Ajouter {{selection}} au contexte",
"session.todo.title": "Tâches",
"session.todo.collapse": "Réduire",
@@ -602,14 +728,17 @@ export const dict = {
"session.question.minimize": "Réduire la question",
"session.question.restore": "Restaurer la question",
"session.question.pending.one": "{{count}} question en attente",
"session.question.pending.many": "{{count}} de questions en attente",
"session.question.pending.other": "{{count}} questions en attente",
"session.followupDock.summary.one": "{{count}} message en file d'attente",
"session.followupDock.summary.many": "{{count}} de messages en file d'attente",
"session.followupDock.summary.other": "{{count}} messages en file d'attente",
"session.followupDock.sendNow": "Envoyer maintenant",
"session.followupDock.edit": "Modifier",
"session.followupDock.collapse": "Réduire les messages en file d'attente",
"session.followupDock.expand": "Développer les messages en file d'attente",
"session.revertDock.summary.one": "{{count}} message annulé",
"session.revertDock.summary.many": "{{count}} de messages annulés",
"session.revertDock.summary.other": "{{count}} messages annulés",
"session.revertDock.collapse": "Réduire les messages annulés",
"session.revertDock.expand": "Développer les messages annulés",
@@ -635,17 +764,17 @@ export const dict = {
"session.header.open.menu": "Options d'ouverture",
"session.header.open.copyPath": "Copier le chemin",
"status.popover.trigger": "Statut",
"status.popover.ariaLabel": "Configurations des serveurs",
"status.popover.ariaLabel": "Configuration des serveurs",
"status.popover.tab.servers": "Serveurs",
"status.popover.tab.mcp": "MCP",
"status.popover.tab.lsp": "LSP",
"status.popover.tab.plugins": "Plugins",
"status.popover.action.manageServers": "Gérer les serveurs",
"session.share.popover.title": "Publier sur le web",
"session.share.popover.title": "Publier sur le Web",
"session.share.popover.description.shared":
"Cette session est publique sur le web. Elle est accessible à toute personne disposant du lien.",
"Cette session est publique sur le Web. Elle est accessible à toute personne disposant du lien.",
"session.share.popover.description.unshared":
"Partager la session publiquement sur le web. Elle sera accessible à toute personne disposant du lien.",
"Rendre la session publique sur le Web. Elle sera accessible à toute personne disposant du lien.",
"session.share.action.share": "Partager",
"session.share.action.publish": "Publier",
"session.share.action.publishing": "Publication...",
@@ -656,7 +785,7 @@ export const dict = {
"session.share.copy.copyLink": "Copier le lien",
"lsp.tooltip.none": "Aucun serveur LSP",
"lsp.label.connected": "{{count}} LSP",
"prompt.loading": "Chargement du prompt...",
"prompt.loading": "Chargement de l'invite...",
"terminal.loading": "Chargement du terminal...",
"terminal.title": "Terminal",
"terminal.title.numbered": "Terminal {{number}}",
@@ -694,7 +823,7 @@ export const dict = {
"sidebar.empty.title": "Aucun projet ouvert",
"sidebar.empty.description": "Ouvrez un projet pour commencer",
"app.name.desktop": "OpenCode Desktop",
"settings.section.desktop": "Bureau",
"settings.section.desktop": "Application de bureau",
"settings.section.server": "Serveur",
"settings.tab.general": "Général",
"settings.tab.shortcuts": "Raccourcis",
@@ -710,10 +839,10 @@ export const dict = {
"settings.general.section.display": "Affichage",
"settings.general.row.language.title": "Langue",
"settings.general.row.language.description": "Changer la langue d'affichage pour OpenCode",
"settings.general.row.shell.title": "Shell du terminal",
"settings.general.row.shell.title": "Interpréteur de commandes du terminal",
"settings.general.row.shell.description":
"Choisissez le shell utilisé par votre terminal. Les shells compatibles sont également utilisés pour les appels d'outils de l'agent.",
"settings.general.row.shell.autoDefault": "Auto (par défaut)",
"settings.general.row.shell.autoDefault": "Automatique (par défaut)",
"settings.general.row.shell.terminalOnly": "terminal uniquement",
"settings.general.row.appearance.title": "Apparence",
"settings.general.row.appearance.description": "Personnaliser l'apparence d'OpenCode sur votre appareil",
@@ -727,22 +856,22 @@ export const dict = {
"settings.general.row.terminalFont.description": "Personnalisez la police utilisée dans le terminal",
"settings.general.row.uiFont.title": "Police de l'interface",
"settings.general.row.uiFont.description": "Personnaliser la police utilisée dans toute l'interface",
"settings.general.row.followup.title": "Comportement de suivi",
"settings.general.row.followup.title": "Comportement des messages de suivi",
"settings.general.row.followup.description":
"Choisissez si les messages de suivi dirigent immédiatement ou attendent dans une file d'attente",
"Choisissez si les messages de suivi orientent immédiatement l'agent ou sont placés dans une file d'attente",
"settings.general.row.followup.option.queue": "File d'attente",
"settings.general.row.followup.option.steer": "Diriger",
"settings.general.row.followup.option.steer": "Orienter",
"settings.general.row.showFileTree.title": "Arborescence des fichiers",
"settings.general.row.showFileTree.description": "Afficher le panneau d'arborescence des fichiers dans les sessions",
"settings.general.row.showNavigation.title": "Commandes de navigation",
"settings.general.row.showNavigation.description":
"Afficher les boutons précédent et suivant dans la barre de titre de l'application desktop",
"Afficher les boutons précédent et suivant dans la barre de titre de l'application de bureau",
"settings.general.row.showSearch.title": "Palette de commandes",
"settings.general.row.showSearch.description":
"Afficher le bouton de recherche et de palette de commandes dans la barre de titre",
"settings.general.row.showTerminal.title": "Terminal",
"settings.general.row.showTerminal.description":
"Afficher le bouton du terminal dans la barre de titre de l'application desktop",
"Afficher le bouton du terminal dans la barre de titre de l'application de bureau",
"settings.general.row.showStatus.title": "État du serveur",
"settings.general.row.showStatus.description": "Afficher le bouton d'état du serveur dans la barre de titre",
"settings.general.row.mobileTitlebarBottom.title": "Navigation en bas",
@@ -774,11 +903,13 @@ export const dict = {
"settings.general.row.wayland.tooltip":
"Sur Linux avec des moniteurs à taux de rafraîchissement mixte, Wayland natif peut être plus stable.",
"settings.general.row.releaseNotes.title": "Notes de version",
"settings.general.row.releaseNotes.description": 'Afficher des pop-ups "Quoi de neuf" après les mises à jour',
"settings.general.row.releaseNotes.description":
"Afficher les fenêtres contextuelles « Quoi de neuf » après les mises à jour",
"settings.updates.row.startup.title": "Vérifier les mises à jour au démarrage",
"settings.updates.row.startup.description": "Vérifier automatiquement les mises à jour au lancement d'OpenCode",
"settings.updates.row.check.title": "Vérifier les mises à jour",
"settings.updates.row.check.description": "Vérifier manuellement les mises à jour et installer si disponible",
"settings.updates.row.check.description":
"Rechercher manuellement les mises à jour et installer toute mise à jour disponible",
"settings.updates.action.checkNow": "Vérifier maintenant",
"settings.updates.action.checking": "Vérification...",
"settings.updates.action.downloading": "Téléchargement...",
@@ -846,12 +977,12 @@ export const dict = {
"settings.general.sounds.errors.title": "Erreurs",
"settings.general.sounds.errors.description": "Jouer un son lorsqu'une erreur se produit",
"settings.shortcuts.title": "Raccourcis clavier",
"settings.shortcuts.reset.button": "Rétablir les défauts",
"settings.shortcuts.reset.button": "Rétablir les valeurs par défaut",
"settings.shortcuts.reset.toast.title": "Raccourcis réinitialisés",
"settings.shortcuts.reset.toast.description": "Les raccourcis clavier ont été réinitialisés aux valeurs par défaut.",
"settings.shortcuts.conflict.title": "Raccourci déjà utilisé",
"settings.shortcuts.conflict.description": "{{keybind}} est déjà assigné à {{titles}}.",
"settings.shortcuts.unassigned": "Non assigné",
"settings.shortcuts.conflict.description": "{{keybind}} est déjà attribué à {{titles}}.",
"settings.shortcuts.unassigned": "Non attribué",
"settings.shortcuts.pressKeys": "Appuyez sur les touches",
"settings.shortcuts.search.placeholder": "Rechercher des raccourcis",
"settings.shortcuts.search.empty": "Aucun raccourci trouvé",
@@ -860,7 +991,7 @@ export const dict = {
"settings.shortcuts.group.navigation": "Navigation",
"settings.shortcuts.group.modelAndAgent": "Modèle et agent",
"settings.shortcuts.group.terminal": "Terminal",
"settings.shortcuts.group.prompt": "Prompt",
"settings.shortcuts.group.prompt": "Invite",
"settings.providers.title": "Fournisseurs",
"settings.providers.description": "Les paramètres des fournisseurs seront configurables ici.",
"settings.providers.section.connected": "Fournisseurs connectés",
@@ -889,9 +1020,9 @@ export const dict = {
"settings.permissions.tool.read.description": "Lecture d'un fichier (correspond au chemin du fichier)",
"settings.permissions.tool.edit.title": "Modifier",
"settings.permissions.tool.edit.description":
"Modifier des fichiers, y compris les modifications, écritures, patchs et multi-modifications",
"Modifier des fichiers, notamment au moyen des outils edit, write et patch",
"settings.permissions.tool.glob.title": "Glob",
"settings.permissions.tool.glob.description": "Correspondre aux fichiers utilisant des modèles glob",
"settings.permissions.tool.glob.description": "Rechercher des fichiers à l'aide de motifs glob",
"settings.permissions.tool.grep.title": "Grep",
"settings.permissions.tool.grep.description":
"Rechercher dans le contenu des fichiers à l'aide d'expressions régulières",
@@ -905,12 +1036,12 @@ export const dict = {
"settings.permissions.tool.skill.description": "Charger une compétence par son nom",
"settings.permissions.tool.lsp.title": "LSP",
"settings.permissions.tool.lsp.description": "Exécuter des requêtes de serveur de langage",
"settings.permissions.tool.todowrite.title": "Écrire Todo",
"settings.permissions.tool.todowrite.title": "Écrire les tâches",
"settings.permissions.tool.todowrite.description": "Mettre à jour la liste de tâches",
"settings.permissions.tool.webfetch.title": "Récupération Web",
"settings.permissions.tool.webfetch.description": "Récupérer le contenu d'une URL",
"settings.permissions.tool.websearch.title": "Recherche Web",
"settings.permissions.tool.websearch.description": "Rechercher sur le web",
"settings.permissions.tool.websearch.description": "Rechercher sur le Web",
"settings.permissions.tool.external_directory.title": "Répertoire externe",
"settings.permissions.tool.external_directory.description": "Accéder aux fichiers en dehors du répertoire du projet",
"settings.permissions.tool.doom_loop.title": "Boucle infernale",
@@ -931,7 +1062,7 @@ export const dict = {
"workspace.reset.success.description": "L'espace de travail correspond maintenant à la branche par défaut.",
"workspace.error.stillPreparing": "L'espace de travail est encore en cours de préparation",
"workspace.status.checking": "Vérification des modifications non fusionnées...",
"workspace.status.error": "Impossible de vérifier le statut git.",
"workspace.status.error": "Impossible de vérifier l'état de Git.",
"workspace.status.clean": "Aucune modification non fusionnée détectée.",
"workspace.status.dirty": "Modifications non fusionnées détectées dans cet espace de travail.",
"workspace.delete.title": "Supprimer l'espace de travail",
@@ -953,9 +1084,9 @@ export const dict = {
"error.server.invalidConfiguration": "Configuration invalide",
"common.moreCountSuffix": " (+{{count}} de plus)",
"common.time.justNow": "À l'instant",
"common.time.minutesAgo.short": "il y a {{count}}m",
"common.time.hoursAgo.short": "il y a {{count}}h",
"common.time.daysAgo.short": "il y a {{count}}j",
"common.time.minutesAgo.short": "il y a {{count}} min",
"common.time.hoursAgo.short": "il y a {{count}} h",
"common.time.daysAgo.short": "il y a {{count}} j",
"settings.providers.connected.environmentDescription": "Connecté à partir de vos variables d'environnement",
"settings.providers.custom.description": "Ajouter un fournisseur compatible avec OpenAI via l'URL de base.",
@@ -973,6 +1104,9 @@ export const dict = {
"session.question.progress": "{{current}} questions sur {{total}}",
"session.header.open.finder": "Finder",
"session.header.open.fileExplorer": "Explorateur de fichiers",
"session.header.reveal.finder": "Afficher dans le Finder",
"session.header.reveal.fileExplorer": "Afficher dans lExplorateur de fichiers",
"session.header.reveal.containingFolder": "Ouvrir le dossier contenant",
"session.header.open.fileManager": "Gestionnaire de fichiers",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -993,11 +1127,11 @@ export const dict = {
"debugBar.nav.tip":
"Dernière transition de route terminée touchant une page de session, mesurée du début du routeur jusqu'au premier affichage après stabilisation.",
"debugBar.fps.label": "FPS",
"debugBar.fps.tip": "Images par seconde glissantes sur les 5 dernières secondes.",
"debugBar.fps.tip": "Fréquence d'images calculée sur les 5 dernières secondes.",
"debugBar.frame.label": "FRAME",
"debugBar.frame.tip": "Pire temps d'image sur les 5 dernières secondes.",
"debugBar.frame.tip": "Durée d'image maximale sur les 5 dernières secondes.",
"debugBar.jank.label": "JANK",
"debugBar.jank.tip": "Images de plus de 32ms au cours des 5 dernières secondes.",
"debugBar.jank.tip": "Images de plus de 32 ms au cours des 5 dernières secondes.",
"debugBar.long.label": "LONG",
"debugBar.long.tip":
"Temps bloqué et nombre de tâches longues au cours des 5 dernières secondes. Tâche max : {{max}}.",
@@ -1005,12 +1139,20 @@ export const dict = {
"debugBar.delay.tip": "Pire délai d'entrée observé au cours des 5 dernières secondes.",
"debugBar.inp.label": "INP",
"debugBar.inp.tip":
"Durée approximative d'interaction au cours des 5 dernières secondes. Ceci est similaire à INP, pas le INP officiel des Web Vitals.",
"Durée approximative d'interaction au cours des 5 dernières secondes. Il s'agit d'une mesure similaire à l'INP, et non de l'INP officiel des Web Vitals.",
"debugBar.cls.label": "CLS",
"debugBar.cls.tip": "Décalage cumulatif de la mise en page pour la durée de vie actuelle de l'application.",
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Tas JS utilisé vs limite de tas. Chromium uniquement.",
"debugBar.mem.tip": "Tas JS utilisé vs limite de tas. {{used}} sur {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Forcer les styles de focus sur tous les éléments interactifs",
"debugBar.focus.on": "ACTIVÉ",
"debugBar.focus.off": "DÉSACTIVÉ",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Forcer le sens de disposition de toute lapplication sans changer la langue sélectionnée",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Maj",
@@ -1035,4 +1177,10 @@ export const dict = {
"error.childStore.persistedProjectIconCreateFailed": "Échec de la création de l'icône de projet persistante",
"error.childStore.storeCreateFailed": "Échec de la création du stockage",
"terminal.connectionLost.abnormalClose": "WebSocket fermé anormalement : {{code}}",
"terminal.connectTicket.csrfError":
"Le ticket de connexion PTY a été rejeté par les contrôles d'origine ou CSRF. Vérifiez la configuration CORS du serveur.",
"terminal.connectTicket.statusError": "Le ticket de connexion PTY a échoué avec le statut {{status}}",
"titlebar.update": "Mettre à jour",
"titlebar.updateVersion": "Mettre à jour {{version}}",
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+156 -17
View File
@@ -1,4 +1,102 @@
export const dict = {
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "ファイル",
"desktop.menu.edit": "編集",
"desktop.menu.view": "表示",
"desktop.menu.go": "移動",
"desktop.menu.window": "ウインドウ",
"desktop.menu.help": "ヘルプ",
"desktop.menu.checkForUpdates": "アップデートを確認...",
"desktop.menu.settings": "設定",
"desktop.menu.reloadWebview": "Webビューを再読み込み",
"desktop.menu.restart": "再起動",
"desktop.menu.exportLogs": "ログをエクスポート...",
"desktop.menu.newSession": "新しいセッション",
"desktop.menu.openProject": "プロジェクトを開く...",
"desktop.menu.newWindow": "新しいウインドウ",
"desktop.menu.closeWindow": "ウインドウを閉じる",
"desktop.menu.undo": "取り消す",
"desktop.menu.redo": "やり直す",
"desktop.menu.cut": "切り取り",
"desktop.menu.copy": "コピー",
"desktop.menu.paste": "ペースト",
"desktop.menu.delete": "削除",
"desktop.menu.selectAll": "すべてを選択",
"desktop.menu.toggleSidebar": "サイドバーの表示を切り替える",
"desktop.menu.toggleTerminal": "ターミナルの表示を切り替える",
"desktop.menu.toggleFileTree": "ファイルツリーの表示を切り替える",
"desktop.menu.reload": "再読み込み",
"desktop.menu.toggleDeveloperTools": "開発者ツールの表示を切り替える",
"desktop.menu.actualSize": "実際のサイズ",
"desktop.menu.zoomIn": "拡大",
"desktop.menu.zoomOut": "縮小",
"desktop.menu.toggleFullScreen": "フルスクリーン表示を切り替える",
"desktop.menu.back": "戻る",
"desktop.menu.forward": "進む",
"desktop.menu.previousSession": "前のセッション",
"desktop.menu.nextSession": "次のセッション",
"desktop.menu.previousProject": "前のプロジェクト",
"desktop.menu.nextProject": "次のプロジェクト",
"desktop.menu.minimize": "最小化",
"desktop.menu.maximize": "最大化",
"desktop.menu.documentation": "OpenCodeドキュメント",
"desktop.menu.supportForum": "サポートフォーラム",
"desktop.menu.shareFeedback": "フィードバックを送信",
"desktop.menu.reportBug": "バグを報告",
"desktop.menu.ariaLabel": "OpenCodeメニュー",
"desktop.updater.dialog.checkFailed.message": "アップデートを確認できませんでした。",
"desktop.updater.dialog.checkFailed.title": "アップデートエラー",
"desktop.updater.dialog.upToDate.message": "最新の状態です。",
"desktop.updater.dialog.upToDate.title": "アップデートはありません",
"desktop.updater.dialog.ready.message": "アップデート{{version}}をダウンロードしました。今すぐ再起動しますか?",
"desktop.updater.dialog.ready.title": "アップデートの準備ができました",
"desktop.updater.dialog.restart": "再起動",
"desktop.updater.dialog.later": "後で",
"desktop.recovery.action.relaunch": "再起動",
"desktop.recovery.action.exportLogs": "ログをエクスポート",
"desktop.recovery.action.keepWaiting": "待機を続ける",
"desktop.recovery.action.quit": "終了",
"desktop.recovery.loadFailed": "OpenCodeを読み込めませんでした",
"desktop.recovery.terminated": "OpenCodeのウインドウが予期せず終了しました",
"desktop.recovery.unresponsive": "OpenCodeが応答していません",
"desktop.recovery.unresponsive.detail": "アプリを再起動するか、ログを開くか、待機を続けることができます。",
"desktop.recovery.loadFailed.detail": "ウインドウ: {{window}}\nURL: {{url}}\nエラー: {{code}} {{description}}",
"desktop.recovery.terminated.detail": "ウインドウ: {{window}}\n理由: {{reason}}\nコード: {{code}}",
"desktop.recovery.unknown": "<不明>",
"desktop.dialog.chooseFolder": "フォルダを選択",
"desktop.dialog.chooseFile": "ファイルを選択",
"desktop.dialog.saveFile": "ファイルを保存",
"desktop.dialog.files": "ファイル",
"desktop.server.local": "ローカルサーバー",
"desktop.wsl.error.windowsOnly": "WSLはWindowsでのみ利用できます",
"desktop.wsl.error.unavailable": "WSLを利用できません",
"desktop.wsl.error.listInstalled": "インストール済みのWSLディストリビューションの一覧を取得できませんでした",
"desktop.wsl.error.listOnline": "オンラインのWSLディストリビューションの一覧を取得できませんでした",
"desktop.wsl.error.executeDistro": "ディストリビューションでコマンドを実行できません",
"desktop.wsl.error.installWsl": "WSLのインストールに失敗しました",
"desktop.wsl.error.installDistro": "ディストリビューションのインストールに失敗しました: {{distro}}",
"desktop.wsl.error.installOpencode": "OpenCodeのインストールに失敗しました",
"desktop.wsl.error.alreadyAdded": "{{distro}}はすでに追加されています",
"desktop.wsl.error.opencodeMissing": "このディストリビューションにはopencodeがインストールされていません",
"desktop.wsl.error.opencodeCannotRun": "opencodeはインストールされていますが、実行できませんでした",
"desktop.wsl.error.opencodeNotInstalled": "{{distro}}にはOpenCodeがインストールされていません",
"desktop.wsl.error.updateVersion":
"OpenCodeのアップデートは完了しましたが、{{distro}}から報告されたバージョンはまだ{{installed}}です。想定されるバージョンは{{expected}}です",
"desktop.wsl.error.noVersion": "バージョンなし",
"desktop.wsl.error.serverExited": "WSLサーバーが起動後に終了しました (code={{code}} signal={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"WSLサーバーが正常に稼働する前に終了しました (code={{code}} signal={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout": "{{distro}}のSidecarのヘルスチェックが{{timeout}}ms後にタイムアウトしました",
"desktop.wsl.error.commandTimeout": "{{command}} {{args}}が{{timeout}}ms後にタイムアウトしました",
"desktop.wsl.error.failedPort": "ポートを取得できませんでした",
"desktop.picker.error.notSelected": "ピッカーでファイルが選択されませんでした",
"desktop.picker.error.sizeLimit": "選択した添付ファイルが上限の{{limit}} MBを超えています",
"command.category.suggested": "おすすめ",
"command.category.view": "表示",
"command.category.project": "プロジェクト",
@@ -16,6 +114,7 @@ export const dict = {
"command.category.permissions": "権限",
"command.category.workspace": "ワークスペース",
"command.category.settings": "設定",
"command.logs.export": "ログをエクスポート",
"theme.scheme.system": "システム",
"theme.scheme.light": "ライト",
"theme.scheme.dark": "ダーク",
@@ -94,13 +193,14 @@ export const dict = {
"dialog.provider.empty": "プロバイダーが見つかりません",
"dialog.provider.group.popular": "人気",
"dialog.provider.group.other": "その他",
"dialog.provider.custom.label": "OpenAI互換のカスタムプロバイダー",
"dialog.provider.tag.recommended": "推奨",
"dialog.provider.opencode.note": "Claude, GPT, Geminiなどを含む厳選されたモデル",
"dialog.provider.opencode.tagline": "信頼性の高い最適化モデル",
"dialog.provider.opencodeGo.tagline": "すべての人に低価格のサブスクリプション",
"dialog.provider.anthropic.note": "Claude Pro/MaxまたはAPIキーで接続",
"dialog.provider.copilot.note": "CopilotまたはAPIキーで接続",
"dialog.provider.openai.note": "ChatGPT Pro/PlusまたはAPIキーで接続",
"dialog.provider.anthropic.note": "ProやMaxを含むClaudeモデルに直接アクセス",
"dialog.provider.copilot.note": "GitHub Copilotを通じてコーディングを支援するAIモデル",
"dialog.provider.openai.note": "高速で高性能な汎用AIタスク向けのGPTモデル",
"dialog.provider.google.note": "高速で構造化された応答のためのGeminiモデル",
"dialog.provider.openrouter.note": "1つのプロバイダーからすべてのサポートされているモデルにアクセス",
"dialog.provider.vercel.note": "スマートルーターによるAIモデルへの統合アクセス",
@@ -112,11 +212,14 @@ export const dict = {
"dialog.model.manage.provider.toggle": "すべての{{provider}}モデルを切り替え",
"dialog.model.unpaid.freeModels.title": "OpenCodeが提供する無料モデル",
"dialog.model.unpaid.addMore.title": "人気のプロバイダーからモデルを追加",
"dialog.model.unpaid.viewMoreProviders": "その他70以上のプロバイダーを見る",
"dialog.provider.viewAll": "さらにプロバイダーを表示",
"provider.connect.title": "{{provider}}を接続",
"provider.connect.title.anthropicProMax": "Claude Pro/Maxでログイン",
"provider.connect.selectMethod": "{{provider}}のログイン方法を選択してください。",
"provider.connect.method.apiKey": "APIキー",
"provider.connect.method.browser": "ブラウザ",
"provider.connect.method.headless": "ヘッドレス モード",
"provider.connect.status.inProgress": "認証中...",
"provider.connect.status.waiting": "認証を待機中...",
"provider.connect.status.failed": "認証に失敗しました: {{error}}",
@@ -147,6 +250,7 @@ export const dict = {
"provider.connect.toast.connected.title": "{{provider}}が接続されました",
"provider.connect.toast.connected.description": "{{provider}}モデルが使用可能になりました。",
"provider.custom.title": "カスタムプロバイダー",
"provider.custom.unavailable": "このサーバーではカスタムプロバイダーを利用できません",
"provider.custom.description.prefix": "OpenAI互換のプロバイダーを設定します。詳細は",
"provider.custom.description.link": "プロバイダー設定ドキュメント",
"provider.custom.description.suffix": "をご覧ください。",
@@ -195,7 +299,7 @@ export const dict = {
"model.input.image": "画像",
"model.input.audio": "音声",
"model.input.video": "動画",
"model.input.pdf": "pdf",
"model.input.pdf": "PDF",
"model.tooltip.allows": "対応: {{inputs}}",
"model.tooltip.context.label": "コンテキスト",
"model.tooltip.inputs": "入力",
@@ -214,7 +318,7 @@ export const dict = {
"common.clear": "クリア",
"common.connect": "接続",
"common.disconnect": "切断",
"common.continue": "送信",
"common.continue": "続行",
"common.submit": "送信",
"common.save": "保存",
"common.saving": "保存中...",
@@ -258,7 +362,7 @@ export const dict = {
"prompt.popover.emptyResults": "一致する結果がありません",
"prompt.popover.emptyCommands": "一致するコマンドがありません",
"prompt.dropzone.label": "画像、PDF、またはテキストファイルをここにドロップしてください",
"prompt.dropzone.file.label": "ドロップして@メンションファイルを追加",
"prompt.dropzone.file.label": "ドロップしてファイルを@メンション",
"prompt.slash.badge.custom": "カスタム",
"prompt.slash.badge.skill": "スキル",
"prompt.slash.badge.mcp": "mcp",
@@ -401,6 +505,22 @@ export const dict = {
"wsl.onboarding.desktopVersion": "デスクトップ {{version}}",
"wsl.onboarding.versionMismatch": "インストールされているバージョンがデスクトップアプリのバージョンと一致しません。",
"wsl.onboarding.adding": "追加中...",
"help.tabs.toast.ariaLabel": "タブのご紹介。タブを使って作業と進行中のセッションを整理できます",
"help.tabs.toast.dismiss": "タブに関する案内を閉じる",
"help.tabs.title": "タブのご紹介",
"help.tabs.description": "タブを使って作業と進行中のセッションを整理できます",
"help.tabs.date": "7月14日",
"help.tabs.introduction": "OpenCode Desktopでタブを中心とした操作ができるようになりました。",
"help.tabs.sessions":
"新しいセッションをタブで開始したり、プロジェクトから既存のセッションを開いたりできます。新しい作業を始めるときは新しいタブを開き、作業が終わったら閉じます。",
"help.tabs.organize":
"複数のタブを開いておくと、進行中のセッションを整理しやすくなります。タブを残しておく場合は、覚えやすい名前に変更できます。",
"help.tabs.home":
"新しいホーム画面には、すべてのセッションとプロジェクトが表示されます。セッションを選択するとタブで開きます。",
"help.tabs.persistence": "アプリを再度開いたときも、タブは開いたままです。",
"help.tabs.worktrees":
"新しいデザインはまだGitワークツリーに対応していませんが、近日中に対応する予定です。以前のレイアウトを引き続き使用する場合は、設定でレイアウトを切り替えることができます。新しいレイアウトは数週間後に標準となる予定です。",
"dialog.project.edit.title": "プロジェクトを編集",
"dialog.project.edit.name": "名前",
"dialog.project.edit.icon": "アイコン",
@@ -567,7 +687,7 @@ export const dict = {
"session.error.notFound.description": "このタブが参照するセッションは、このサーバーには存在しません。",
"session.error.notFound.closeTab": "タブを閉じる",
"session.error.serverConnection": "このサーバーに接続できません",
"session.review.filesChanged": "{{count}} ファイル変更",
"session.review.filesChanged": "変更されたファイル: {{count}}",
"session.review.change.one": "変更",
"session.review.change.other": "変更",
"session.review.loadingChanges": "変更を読み込み中...",
@@ -657,10 +777,10 @@ export const dict = {
"ターミナルの接続が中断されました。これはサーバーが再起動したときに発生することがあります。",
"common.closeTab": "タブを閉じる",
"common.dismiss": "閉じる",
"common.requestFailed": "リクエスト失敗",
"common.requestFailed": "リクエスト失敗しました",
"common.moreOptions": "その他のオプション",
"common.learnMore": "詳細",
"common.rename": "名前変更",
"common.rename": "名前変更",
"common.reset": "リセット",
"common.archive": "アーカイブ",
"common.delete": "削除",
@@ -734,8 +854,9 @@ export const dict = {
"settings.general.row.mobileTitlebarBottom.title": "下部ナビゲーション",
"settings.general.row.mobileTitlebarBottom.description":
"モバイルではタイトルバーとセッションタブを画面下部に配置します",
"settings.general.row.showCustomAgents.title": "カスタムエージェント",
"settings.general.row.showCustomAgents.description": "コンポーザーにエージェント選択を表示します",
"settings.general.row.showCustomAgents.title": "エージェントを表示",
"settings.general.row.showCustomAgents.description":
"コンポーザーでエージェントを切り替えます。非表示の場合は、デフォルトでBuildエージェントが使用されます。",
"settings.general.row.reasoningSummaries.title": "推論の要約を表示",
"settings.general.row.reasoningSummaries.description": "タイムラインにモデルの推論の要約を表示します",
"settings.general.row.shellToolPartsExpanded.title": "shell ツールパーツを展開",
@@ -846,7 +967,7 @@ export const dict = {
"settings.shortcuts.group.terminal": "ターミナル",
"settings.shortcuts.group.prompt": "プロンプト",
"settings.providers.title": "プロバイダー",
"settings.providers.description": "プロバイダー設定はここで構成できます。",
"settings.providers.description": "プロバイダー設定は今後ここで構成できるようになります。",
"settings.providers.section.connected": "接続済みプロバイダー",
"settings.providers.connected.empty": "接続済みプロバイダーはありません",
"settings.providers.section.popular": "人気のプロバイダー",
@@ -855,13 +976,13 @@ export const dict = {
"settings.providers.tag.custom": "カスタム",
"settings.providers.tag.other": "その他",
"settings.models.title": "モデル",
"settings.models.description": "モデル設定はここで構成できます。",
"settings.models.description": "モデル設定は今後ここで構成できるようになります。",
"settings.agents.title": "エージェント",
"settings.agents.description": "エージェント設定はここで構成できます。",
"settings.agents.description": "エージェント設定は今後ここで構成できるようになります。",
"settings.commands.title": "コマンド",
"settings.commands.description": "コマンド設定はここで構成できます。",
"settings.commands.description": "コマンド設定は今後ここで構成できるようになります。",
"settings.mcp.title": "MCP",
"settings.mcp.description": "MCP設定はここで構成できます。",
"settings.mcp.description": "MCP設定は今後ここで構成できるようになります。",
"settings.permissions.title": "権限",
"settings.permissions.description": "サーバーがデフォルトで使用できるツールを制御します。",
"settings.permissions.section.tools": "ツール",
@@ -955,6 +1076,9 @@ export const dict = {
"session.question.progress": "{{total}} 問中 {{current}} 問",
"session.header.open.finder": "Finder",
"session.header.open.fileExplorer": "エクスプローラー",
"session.header.reveal.finder": "Finderで表示",
"session.header.reveal.fileExplorer": "エクスプローラーで表示",
"session.header.reveal.containingFolder": "親フォルダーを開く",
"session.header.open.fileManager": "ファイルマネージャー",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -972,7 +1096,8 @@ export const dict = {
"debugBar.ariaLabel": "開発パフォーマンス診断",
"debugBar.na": "n/a",
"debugBar.nav.label": "NAV",
"debugBar.nav.tip": "セッションページに触れる最後に完了したルート遷移。ルーター開始から安定後の最初の描画まで測定。",
"debugBar.nav.tip":
"セッションページに関係する最後に完了したルート遷移。ルーターの開始から処理完了後の最初の描画までを測定。",
"debugBar.fps.label": "FPS",
"debugBar.fps.tip": "過去5秒間のローリングフレーム/秒。",
"debugBar.frame.label": "FRAME",
@@ -991,6 +1116,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "使用中の JS ヒープ対ヒープ制限。Chromium のみ。",
"debugBar.mem.tip": "使用中の JS ヒープ対ヒープ制限。{{limit}} 中 {{used}}。",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "すべてのインタラクティブ要素にフォーカススタイルを強制適用",
"debugBar.focus.on": "オン",
"debugBar.focus.off": "オフ",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "選択中の言語を変更せずに、アプリ全体のレイアウト方向を強制設定",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
@@ -1014,4 +1147,10 @@ export const dict = {
"error.childStore.persistedProjectIconCreateFailed": "永続プロジェクトアイコンの作成に失敗しました",
"error.childStore.storeCreateFailed": "ストアの作成に失敗しました",
"terminal.connectionLost.abnormalClose": "WebSocket が異常終了しました: {{code}}",
"terminal.connectTicket.csrfError":
"PTY接続チケットは、オリジンまたはCSRFチェックによって拒否されました。サーバーのCORS設定を確認してください。",
"terminal.connectTicket.statusError": "PTY接続チケットがステータス {{status}} で失敗しました",
"titlebar.update": "アップデート",
"titlebar.updateVersion": "アップデート {{version}}",
}
+161 -23
View File
@@ -19,7 +19,7 @@ export const dict = {
"theme.scheme.system": "시스템",
"theme.scheme.light": "라이트",
"theme.scheme.dark": "다크",
"command.sidebar.toggle": "사이드바 토글",
"command.sidebar.toggle": "사이드바 표시/숨기기",
"command.project.open": "프로젝트 열기",
"command.provider.connect": "공급자 연결",
"command.server.switch": "서버 전환",
@@ -42,12 +42,12 @@ export const dict = {
"command.context.addSelection": "선택 영역을 컨텍스트에 추가",
"command.context.addSelection.description": "현재 파일에서 선택한 줄을 추가",
"command.input.focus": "입력창 포커스",
"command.terminal.toggle": "터미널 토글",
"command.fileTree.toggle": "파일 트리 토글",
"command.review.toggle": "검토 토글",
"command.terminal.toggle": "터미널 표시/숨기기",
"command.fileTree.toggle": "파일 트리 표시/숨기기",
"command.review.toggle": "검토 표시/숨기기",
"command.terminal.new": "새 터미널",
"command.terminal.new.description": "새 터미널 탭 생성",
"command.steps.toggle": "단계 토글",
"command.steps.toggle": "단계 표시/숨기기",
"command.steps.toggle.description": "현재 메시지의 단계 표시/숨기기",
"command.message.previous": "이전 메시지",
"command.message.previous.description": "이전 사용자 메시지로 이동",
@@ -55,8 +55,8 @@ export const dict = {
"command.message.next.description": "다음 사용자 메시지로 이동",
"command.model.choose": "모델 선택",
"command.model.choose.description": "다른 모델 선택",
"command.mcp.toggle": "MCP 토글",
"command.mcp.toggle.description": "MCP 토글",
"command.mcp.toggle": "MCP 전환",
"command.mcp.toggle.description": "MCP 전환",
"command.agent.cycle": "에이전트 순환",
"command.agent.cycle.description": "다음 에이전트로 전환",
"command.agent.cycle.reverse": "에이전트 역순환",
@@ -90,13 +90,14 @@ export const dict = {
"dialog.provider.empty": "공급자 없음",
"dialog.provider.group.popular": "인기",
"dialog.provider.group.other": "기타",
"dialog.provider.custom.label": "OpenAI 호환 사용자 지정 공급자",
"dialog.provider.tag.recommended": "추천",
"dialog.provider.opencode.note": "Claude, GPT, Gemini 등을 포함한 엄선된 모델",
"dialog.provider.opencode.tagline": "신뢰할 수 있는 최적화 모델",
"dialog.provider.opencodeGo.tagline": "모두를 위한 저렴한 구독",
"dialog.provider.anthropic.note": "Claude Pro/Max 또는 API 키로 연결",
"dialog.provider.copilot.note": "Copilot 또는 API 키로 연결",
"dialog.provider.openai.note": "ChatGPT Pro/Plus 또는 API 키로 연결",
"dialog.provider.anthropic.note": "Pro 및 Max를 포함한 Claude 모델에 직접 액세스",
"dialog.provider.copilot.note": "GitHub Copilot을 통한 코딩 지원용 AI 모델",
"dialog.provider.openai.note": "빠르고 강력한 범용 AI 작업을 위한 GPT 모델",
"dialog.provider.google.note": "빠르고 구조화된 응답을 위한 Gemini 모델",
"dialog.provider.openrouter.note": "모든 지원 모델을 단일 공급자에서 액세스",
"dialog.provider.vercel.note": "스마트 라우팅을 통한 AI 모델 통합 액세스",
@@ -108,11 +109,14 @@ export const dict = {
"dialog.model.manage.provider.toggle": "모든 {{provider}} 모델 토글",
"dialog.model.unpaid.freeModels.title": "OpenCode에서 제공하는 무료 모델",
"dialog.model.unpaid.addMore.title": "인기 공급자의 모델 추가",
"dialog.model.unpaid.viewMoreProviders": "70개 이상의 공급자 더 보기",
"dialog.provider.viewAll": "더 많은 공급자 보기",
"provider.connect.title": "{{provider}} 연결",
"provider.connect.title.anthropicProMax": "Claude Pro/Max로 로그인",
"provider.connect.selectMethod": "{{provider}} 로그인 방법 선택",
"provider.connect.method.apiKey": "API 키",
"provider.connect.method.browser": "브라우저",
"provider.connect.method.headless": "헤드리스 모드",
"provider.connect.status.inProgress": "인증 진행 중...",
"provider.connect.status.waiting": "인증 대기 중...",
"provider.connect.status.failed": "인증 실패: {{error}}",
@@ -143,6 +147,7 @@ export const dict = {
"provider.connect.toast.connected.title": "{{provider}} 연결됨",
"provider.connect.toast.connected.description": "이제 {{provider}} 모델을 사용할 수 있습니다.",
"provider.custom.title": "사용자 지정 공급자",
"provider.custom.unavailable": "이 서버에서는 사용자 지정 공급자를 사용할 수 없습니다",
"provider.custom.description.prefix": "OpenAI 호환 공급자를 구성합니다. ",
"provider.custom.description.link": "공급자 구성 문서",
"provider.custom.description.suffix": "를 참조하세요.",
@@ -191,7 +196,7 @@ export const dict = {
"model.input.image": "이미지",
"model.input.audio": "오디오",
"model.input.video": "비디오",
"model.input.pdf": "pdf",
"model.input.pdf": "PDF",
"model.tooltip.allows": "지원: {{inputs}}",
"model.tooltip.reasoning.allowed": "추론 허용",
"model.tooltip.reasoning.none": "추론 없음",
@@ -204,7 +209,7 @@ export const dict = {
"common.cancel": "취소",
"common.connect": "연결",
"common.disconnect": "연결 해제",
"common.continue": "제출",
"common.continue": "계속",
"common.submit": "제출",
"common.save": "저장",
"common.saving": "저장 중...",
@@ -254,7 +259,7 @@ export const dict = {
"prompt.context.includeActiveFile": "활성 파일 포함",
"prompt.context.removeActiveFile": "컨텍스트에서 활성 파일 제거",
"prompt.context.removeFile": "컨텍스트에서 파일 제거",
"prompt.action.attachFile": "파일 첨부",
"prompt.action.attachFile": "파일 추가",
"prompt.menu.addImagesAndFiles": "파일 및 기타 항목 추가",
"prompt.menu.imagesAndFiles": "이미지 및 파일",
"prompt.menu.commands": "명령어",
@@ -589,15 +594,15 @@ export const dict = {
"settings.general.row.followup.title": "후속 조치 동작",
"settings.general.row.followup.description": "후속 프롬프트를 즉시 실행할지 대기열에 넣을지 선택하세요",
"settings.general.row.followup.option.queue": "대기열",
"settings.general.row.followup.option.steer": "조종",
"settings.general.row.followup.option.steer": "즉시 반영",
"settings.general.row.reasoningSummaries.title": "추론 요약 표시",
"settings.general.row.reasoningSummaries.description": "타임라인에 모델 추론 요약 표시",
"settings.general.row.shellToolPartsExpanded.title": "shell 도구 파트 펼치기",
"settings.general.row.shellToolPartsExpanded.title": "shell 도구 항목 펼치기",
"settings.general.row.shellToolPartsExpanded.description":
"타임라인에서 기본적으로 shell 도구 파트를 펼친 상태로 표시합니다",
"settings.general.row.editToolPartsExpanded.title": "edit 도구 파트 펼치기",
"타임라인에서 기본적으로 shell 도구 항목을 펼친 상태로 표시합니다",
"settings.general.row.editToolPartsExpanded.title": "edit 도구 항목 펼치기",
"settings.general.row.editToolPartsExpanded.description":
"타임라인에서 기본적으로 edit, write, patch 도구 파트를 펼친 상태로 표시합니다",
"타임라인에서 기본적으로 edit, write, patch 도구 항목을 펼친 상태로 표시합니다",
"settings.general.row.wayland.title": "네이티브 Wayland 사용",
"settings.general.row.wayland.description": "Wayland에서 X11 폴백을 비활성화합니다. 다시 시작해야 합니다.",
"settings.general.row.wayland.tooltip":
@@ -724,8 +729,8 @@ export const dict = {
"settings.permissions.tool.bash.description": "셸 명령어 실행",
"settings.permissions.tool.task.title": "작업",
"settings.permissions.tool.task.description": "하위 에이전트 실행",
"settings.permissions.tool.skill.title": "기술",
"settings.permissions.tool.skill.description": "이름으로 기술 로드",
"settings.permissions.tool.skill.title": "스킬",
"settings.permissions.tool.skill.description": "이름으로 스킬 불러오기",
"settings.permissions.tool.lsp.title": "LSP",
"settings.permissions.tool.lsp.description": "언어 서버 쿼리 실행",
"settings.permissions.tool.todowrite.title": "할 일 쓰기",
@@ -796,6 +801,9 @@ export const dict = {
"session.question.progress": "{{total}}개의 질문 중 {{current}}개",
"session.header.open.finder": "Finder",
"session.header.open.fileExplorer": "파일 탐색기",
"session.header.reveal.finder": "Finder에서 보기",
"session.header.reveal.fileExplorer": "파일 탐색기에서 보기",
"session.header.reveal.containingFolder": "이 항목이 있는 폴더 열기",
"session.header.open.fileManager": "파일 관리자",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -832,6 +840,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "사용된 JS 힙 대 힙 제한. Chromium 전용.",
"debugBar.mem.tip": "사용된 JS 힙 대 힙 제한. {{limit}} 중 {{used}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "모든 대화형 요소에 포커스 스타일 강제 적용",
"debugBar.focus.on": "켬",
"debugBar.focus.off": "끔",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "선택한 언어를 변경하지 않고 전체 앱의 레이아웃 방향 강제 설정",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
@@ -855,6 +871,12 @@ export const dict = {
"error.childStore.persistedProjectIconCreateFailed": "영구 프로젝트 아이콘 생성 실패",
"error.childStore.storeCreateFailed": "저장소 생성 실패",
"terminal.connectionLost.abnormalClose": "WebSocket이 비정상적으로 닫힘: {{code}}",
"terminal.connectTicket.csrfError":
"PTY 연결 티켓이 오리진 또는 CSRF 검사에서 거부되었습니다. 서버의 CORS 구성을 확인하세요.",
"terminal.connectTicket.statusError": "PTY 연결 티켓 실패(상태: {{status}})",
"titlebar.update": "업데이트",
"titlebar.updateVersion": "업데이트 {{version}}",
"command.project.previous": "이전 프로젝트",
"command.project.next": "다음 프로젝트",
@@ -957,7 +979,7 @@ export const dict = {
"home.sessions.group.today": "오늘",
"home.sessions.group.yesterday": "어제",
"home.sessions.group.older": "이전",
"home.providerTip": "75개 이상의 제공업체에 연결하여 Claude, GPT, Gemini 등의 다른 모델을 사용하세요",
"home.providerTip": "75개 이상의 공급자에 연결하여 Claude, GPT, Gemini 등의 다른 모델을 사용하세요",
"session.tab.unknown": "알 수 없는 세션",
"session.error.notFound": "이 세션을 찾을 수 없습니다",
@@ -1000,8 +1022,9 @@ export const dict = {
"settings.general.row.showStatus.description": "제목 표시줄에 서버 상태 버튼 표시",
"settings.general.row.mobileTitlebarBottom.title": "하단 탐색",
"settings.general.row.mobileTitlebarBottom.description": "모바일에서 제목 표시줄과 세션 탭을 화면 하단에 배치",
"settings.general.row.showCustomAgents.title": "사용자 지정 에이전트",
"settings.general.row.showCustomAgents.description": "입력창에 에이전트 선택기 표시",
"settings.general.row.showCustomAgents.title": "에이전트 표시",
"settings.general.row.showCustomAgents.description":
"입력창에서 에이전트를 전환합니다. 숨기면 기본적으로 Build 에이전트를 사용합니다.",
"settings.general.row.newInterface.title": "새 레이아웃",
"settings.general.row.newInterface.badge": "신규",
"settings.general.row.newInterface.description":
@@ -1013,4 +1036,119 @@ export const dict = {
"settings.general.row.pinchZoom.description": "트랙패드 핀치 및 Ctrl-스크롤 제스처로 확대/축소 허용",
"settings.updates.action.downloading": "다운로드 중...",
"settings.updates.action.installing": "설치 중...",
"command.logs.export": "로그 내보내기",
"help.tabs.toast.ariaLabel": "탭을 소개합니다. 탭으로 작업과 활성 세션을 정리하세요",
"help.tabs.toast.dismiss": "탭 정보 닫기",
"help.tabs.title": "탭 소개",
"help.tabs.description": "탭으로 작업과 활성 세션을 정리하세요",
"help.tabs.date": "7월 14일",
"help.tabs.introduction": "이제 OpenCode Desktop은 탭을 중심으로 구성됩니다.",
"help.tabs.sessions":
"탭에서 새 세션을 시작하거나 프로젝트에서 기존 세션을 여세요. 새로운 작업을 시작할 때 새 탭을 열고, 작업을 마치면 닫으세요.",
"help.tabs.organize":
"탭을 몇 개 열어 두면 활성 세션을 더 쉽게 정리할 수 있습니다. 탭을 계속 열어 둘 예정이라면 기억하기 쉬운 이름으로 바꾸세요.",
"help.tabs.home": "새 홈 화면에서 모든 세션과 프로젝트를 확인할 수 있습니다. 세션을 선택하면 탭에서 열립니다.",
"help.tabs.persistence": "앱을 다시 열어도 탭은 그대로 열려 있습니다.",
"help.tabs.worktrees":
"새 디자인은 아직 Git Worktrees를 지원하지 않지만 곧 지원할 예정입니다. 이전 레이아웃을 계속 사용하려면 설정에서 레이아웃을 전환할 수 있습니다. 단, 몇 주 후에는 새 레이아웃이 영구 적용됩니다.",
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "파일",
"desktop.menu.edit": "편집",
"desktop.menu.view": "보기",
"desktop.menu.go": "이동",
"desktop.menu.window": "윈도우",
"desktop.menu.help": "도움말",
"desktop.menu.checkForUpdates": "업데이트 확인...",
"desktop.menu.settings": "설정",
"desktop.menu.reloadWebview": "WebView 새로 고침",
"desktop.menu.restart": "다시 시작",
"desktop.menu.exportLogs": "로그 내보내기...",
"desktop.menu.newSession": "새 세션",
"desktop.menu.openProject": "프로젝트 열기...",
"desktop.menu.newWindow": "새 윈도우",
"desktop.menu.closeWindow": "윈도우 닫기",
"desktop.menu.undo": "실행 취소",
"desktop.menu.redo": "다시 실행",
"desktop.menu.cut": "잘라내기",
"desktop.menu.copy": "복사",
"desktop.menu.paste": "붙여넣기",
"desktop.menu.delete": "삭제",
"desktop.menu.selectAll": "모두 선택",
"desktop.menu.toggleSidebar": "사이드바 표시/숨기기",
"desktop.menu.toggleTerminal": "터미널 표시/숨기기",
"desktop.menu.toggleFileTree": "파일 트리 표시/숨기기",
"desktop.menu.reload": "새로 고침",
"desktop.menu.toggleDeveloperTools": "개발자 도구 표시/숨기기",
"desktop.menu.actualSize": "실제 크기",
"desktop.menu.zoomIn": "확대",
"desktop.menu.zoomOut": "축소",
"desktop.menu.toggleFullScreen": "전체 화면 전환",
"desktop.menu.back": "뒤로",
"desktop.menu.forward": "앞으로",
"desktop.menu.previousSession": "이전 세션",
"desktop.menu.nextSession": "다음 세션",
"desktop.menu.previousProject": "이전 프로젝트",
"desktop.menu.nextProject": "다음 프로젝트",
"desktop.menu.minimize": "최소화",
"desktop.menu.maximize": "최대화",
"desktop.menu.documentation": "OpenCode 문서",
"desktop.menu.supportForum": "지원 포럼",
"desktop.menu.shareFeedback": "피드백 보내기",
"desktop.menu.reportBug": "버그 신고",
"desktop.menu.ariaLabel": "OpenCode 메뉴",
"desktop.updater.dialog.checkFailed.message": "업데이트를 확인하지 못했습니다.",
"desktop.updater.dialog.checkFailed.title": "업데이트 오류",
"desktop.updater.dialog.upToDate.message": "최신 버전을 사용 중입니다.",
"desktop.updater.dialog.upToDate.title": "업데이트 없음",
"desktop.updater.dialog.ready.message": "업데이트 {{version}} 다운로드가 완료되었습니다. 지금 다시 시작할까요?",
"desktop.updater.dialog.ready.title": "업데이트 준비 완료",
"desktop.updater.dialog.restart": "다시 시작",
"desktop.updater.dialog.later": "나중에",
"desktop.recovery.action.relaunch": "다시 실행",
"desktop.recovery.action.exportLogs": "로그 내보내기",
"desktop.recovery.action.keepWaiting": "계속 기다리기",
"desktop.recovery.action.quit": "종료",
"desktop.recovery.loadFailed": "OpenCode를 불러오지 못했습니다",
"desktop.recovery.terminated": "OpenCode 윈도우가 예기치 않게 종료되었습니다",
"desktop.recovery.unresponsive": "OpenCode가 응답하지 않습니다",
"desktop.recovery.unresponsive.detail": "앱을 다시 실행하거나 로그를 열거나 계속 기다릴 수 있습니다.",
"desktop.recovery.loadFailed.detail": "윈도우: {{window}}\nURL: {{url}}\n오류: {{code}} {{description}}",
"desktop.recovery.terminated.detail": "윈도우: {{window}}\n원인: {{reason}}\n코드: {{code}}",
"desktop.recovery.unknown": "<알 수 없음>",
"desktop.dialog.chooseFolder": "폴더 선택",
"desktop.dialog.chooseFile": "파일 선택",
"desktop.dialog.saveFile": "파일 저장",
"desktop.dialog.files": "파일",
"desktop.server.local": "로컬 서버",
"desktop.wsl.error.windowsOnly": "WSL은 Windows에서만 사용할 수 있습니다",
"desktop.wsl.error.unavailable": "WSL을 사용할 수 없습니다",
"desktop.wsl.error.listInstalled": "설치된 WSL 배포판 목록을 가져오지 못했습니다",
"desktop.wsl.error.listOnline": "온라인 WSL 배포판 목록을 가져오지 못했습니다",
"desktop.wsl.error.executeDistro": "배포판에서 명령을 실행할 수 없습니다",
"desktop.wsl.error.installWsl": "WSL 설치 실패",
"desktop.wsl.error.installDistro": "배포판 설치 실패: {{distro}}",
"desktop.wsl.error.installOpencode": "OpenCode 설치 실패",
"desktop.wsl.error.alreadyAdded": "{{distro}} 배포판은 이미 추가되었습니다",
"desktop.wsl.error.opencodeMissing": "이 배포판에 opencode가 설치되어 있지 않습니다",
"desktop.wsl.error.opencodeCannotRun": "opencode가 설치되어 있지만 실행할 수 없습니다",
"desktop.wsl.error.opencodeNotInstalled": "{{distro}}에 OpenCode가 설치되어 있지 않습니다",
"desktop.wsl.error.updateVersion":
"OpenCode 업데이트가 완료되었지만 {{distro}}에서 여전히 {{installed}} 버전으로 표시됩니다. 예상 버전: {{expected}}",
"desktop.wsl.error.noVersion": "버전 없음",
"desktop.wsl.error.serverExited": "WSL 서버가 시작 후 종료되었습니다(코드={{code}} 신호={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"WSL 서버가 정상 상태가 되기 전에 종료되었습니다(코드={{code}} 신호={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout": "{{distro}} 사이드카의 상태 확인이 {{timeout}}ms 후 시간 초과되었습니다",
"desktop.wsl.error.commandTimeout": "{{command}} {{args}} 명령이 {{timeout}}ms 후 시간 초과되었습니다",
"desktop.wsl.error.failedPort": "포트를 가져오지 못했습니다",
"desktop.picker.error.notSelected": "선택기에서 파일을 선택하지 않았습니다",
"desktop.picker.error.sizeLimit": "선택한 첨부 파일이 {{limit}} MB 제한을 초과합니다",
}
File diff suppressed because it is too large Load Diff
+197 -55
View File
@@ -2,6 +2,105 @@ import { dict as en } from "./en"
type Keys = keyof typeof en
export const dict = {
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Arkiv",
"desktop.menu.edit": "Rediger",
"desktop.menu.view": "Vis",
"desktop.menu.go": "Gå",
"desktop.menu.window": "Vindu",
"desktop.menu.help": "Hjelp",
"desktop.menu.checkForUpdates": "Søk etter oppdateringer...",
"desktop.menu.settings": "Innstillinger",
"desktop.menu.reloadWebview": "Last inn WebView på nytt",
"desktop.menu.restart": "Start på nytt",
"desktop.menu.exportLogs": "Eksporter logger...",
"desktop.menu.newSession": "Ny sesjon",
"desktop.menu.openProject": "Åpne prosjekt...",
"desktop.menu.newWindow": "Nytt vindu",
"desktop.menu.closeWindow": "Lukk vindu",
"desktop.menu.undo": "Angre",
"desktop.menu.redo": "Gjør om",
"desktop.menu.cut": "Klipp ut",
"desktop.menu.copy": "Kopier",
"desktop.menu.paste": "Lim inn",
"desktop.menu.delete": "Slett",
"desktop.menu.selectAll": "Merk alt",
"desktop.menu.toggleSidebar": "Vis eller skjul sidepanel",
"desktop.menu.toggleTerminal": "Vis eller skjul terminal",
"desktop.menu.toggleFileTree": "Vis eller skjul filtreet",
"desktop.menu.reload": "Last inn på nytt",
"desktop.menu.toggleDeveloperTools": "Vis eller skjul utviklerverktøy",
"desktop.menu.actualSize": "Faktisk størrelse",
"desktop.menu.zoomIn": "Zoom inn",
"desktop.menu.zoomOut": "Zoom ut",
"desktop.menu.toggleFullScreen": "Slå fullskjerm av eller på",
"desktop.menu.back": "Tilbake",
"desktop.menu.forward": "Frem",
"desktop.menu.previousSession": "Forrige sesjon",
"desktop.menu.nextSession": "Neste sesjon",
"desktop.menu.previousProject": "Forrige prosjekt",
"desktop.menu.nextProject": "Neste prosjekt",
"desktop.menu.minimize": "Minimer",
"desktop.menu.maximize": "Maksimer",
"desktop.menu.documentation": "OpenCode-dokumentasjon",
"desktop.menu.supportForum": "Brukerstøtteforum",
"desktop.menu.shareFeedback": "Del tilbakemelding",
"desktop.menu.reportBug": "Rapporter en feil",
"desktop.menu.ariaLabel": "OpenCode-meny",
"desktop.updater.dialog.checkFailed.message": "Søket etter oppdateringer mislyktes.",
"desktop.updater.dialog.checkFailed.title": "Oppdateringsfeil",
"desktop.updater.dialog.upToDate.message": "Du har den nyeste versjonen.",
"desktop.updater.dialog.upToDate.title": "Ingen oppdateringer",
"desktop.updater.dialog.ready.message": "Oppdateringen {{version}} er lastet ned. Vil du starte på nytt nå?",
"desktop.updater.dialog.ready.title": "Oppdateringen er klar",
"desktop.updater.dialog.restart": "Start på nytt",
"desktop.updater.dialog.later": "Senere",
"desktop.recovery.action.relaunch": "Start appen på nytt",
"desktop.recovery.action.exportLogs": "Eksporter logger",
"desktop.recovery.action.keepWaiting": "Fortsett å vente",
"desktop.recovery.action.quit": "Avslutt",
"desktop.recovery.loadFailed": "OpenCode kunne ikke lastes inn",
"desktop.recovery.terminated": "OpenCode-vinduet ble uventet avsluttet",
"desktop.recovery.unresponsive": "OpenCode svarer ikke",
"desktop.recovery.unresponsive.detail": "Du kan starte appen på nytt, åpne loggene eller fortsette å vente.",
"desktop.recovery.loadFailed.detail": "Vindu: {{window}}\nURL: {{url}}\nFeil: {{code}} {{description}}",
"desktop.recovery.terminated.detail": "Vindu: {{window}}\nÅrsak: {{reason}}\nKode: {{code}}",
"desktop.recovery.unknown": "<ukjent>",
"desktop.dialog.chooseFolder": "Velg en mappe",
"desktop.dialog.chooseFile": "Velg en fil",
"desktop.dialog.saveFile": "Lagre fil",
"desktop.dialog.files": "Filer",
"desktop.server.local": "Lokal server",
"desktop.wsl.error.windowsOnly": "WSL er bare tilgjengelig på Windows",
"desktop.wsl.error.unavailable": "WSL er utilgjengelig",
"desktop.wsl.error.listInstalled": "Kunne ikke vise installerte WSL-distribusjoner",
"desktop.wsl.error.listOnline": "Kunne ikke vise tilgjengelige WSL-distribusjoner",
"desktop.wsl.error.executeDistro": "Kan ikke kjøre kommandoer i distribusjonen",
"desktop.wsl.error.installWsl": "Installasjonen av WSL mislyktes",
"desktop.wsl.error.installDistro": "Kunne ikke installere distribusjonen: {{distro}}",
"desktop.wsl.error.installOpencode": "Installasjonen av OpenCode mislyktes",
"desktop.wsl.error.alreadyAdded": "{{distro}} er allerede lagt til",
"desktop.wsl.error.opencodeMissing": "opencode er ikke installert i denne distribusjonen",
"desktop.wsl.error.opencodeCannotRun": "opencode er installert, men kunne ikke kjøres",
"desktop.wsl.error.opencodeNotInstalled": "OpenCode er ikke installert i {{distro}}",
"desktop.wsl.error.updateVersion":
"Oppdateringen av OpenCode er fullført, men {{distro}} rapporterer fortsatt {{installed}}; forventet {{expected}}",
"desktop.wsl.error.noVersion": "ingen versjon",
"desktop.wsl.error.serverExited": "WSL-serveren ble avsluttet etter oppstart (code={{code}} signal={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"WSL-serveren ble avsluttet før den var klar (code={{code}} signal={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout":
"Tidsavbrudd for tilstandskontrollen av sidecar for {{distro}} etter {{timeout}} ms",
"desktop.wsl.error.commandTimeout": "Tidsavbrudd for {{command}} {{args}} etter {{timeout}} ms",
"desktop.wsl.error.failedPort": "Kunne ikke hente port",
"desktop.picker.error.notSelected": "Ingen fil ble valgt i filvelgeren",
"desktop.picker.error.sizeLimit": "De valgte vedleggene overskrider grensen på {{limit}} MB",
"command.category.suggested": "Foreslått",
"command.category.view": "Visning",
"command.category.project": "Prosjekt",
@@ -19,6 +118,7 @@ export const dict = {
"command.category.permissions": "Tillatelser",
"command.category.workspace": "Arbeidsområde",
"command.category.settings": "Innstillinger",
"command.logs.export": "Eksporter logger",
"theme.scheme.system": "System",
"theme.scheme.light": "Lys",
@@ -31,8 +131,8 @@ export const dict = {
"command.settings.open": "Åpne innstillinger",
"command.session.previous": "Forrige sesjon",
"command.session.next": "Neste sesjon",
"command.session.previous.unseen": "Forrige uleste økt",
"command.session.next.unseen": "Neste uleste økt",
"command.session.previous.unseen": "Forrige uleste sesjon",
"command.session.next.unseen": "Neste uleste sesjon",
"command.session.archive": "Arkiver sesjon",
"command.palette": "Kommandopalett",
@@ -101,6 +201,7 @@ export const dict = {
"dialog.provider.empty": "Ingen leverandører funnet",
"dialog.provider.group.popular": "Populære",
"dialog.provider.group.other": "Andre",
"dialog.provider.custom.label": "Egendefinert OpenAI-kompatibel leverandør",
"dialog.provider.tag.recommended": "Anbefalt",
"dialog.provider.opencode.note": "Utvalgte modeller inkludert Claude, GPT, Gemini og mer",
"dialog.provider.opencode.tagline": "Pålitelige, optimaliserte modeller",
@@ -121,6 +222,7 @@ export const dict = {
"dialog.model.unpaid.freeModels.title": "Gratis modeller levert av OpenCode",
"dialog.model.unpaid.addMore.title": "Legg til flere modeller fra populære leverandører",
"dialog.model.unpaid.viewMoreProviders": "Se over 70 flere leverandører",
"dialog.provider.viewAll": "Vis flere leverandører",
@@ -128,12 +230,14 @@ export const dict = {
"provider.connect.title.anthropicProMax": "Logg inn med Claude Pro/Max",
"provider.connect.selectMethod": "Velg innloggingsmetode for {{provider}}.",
"provider.connect.method.apiKey": "API-nøkkel",
"provider.connect.method.browser": "Nettleser",
"provider.connect.method.headless": "Uten nettleser",
"provider.connect.status.inProgress": "Autorisering pågår...",
"provider.connect.status.waiting": "Venter på autorisering...",
"provider.connect.status.failed": "Autorisering mislyktes: {{error}}",
"provider.connect.apiKey.description":
"Skriv inn din {{provider}} API-nøkkel for å koble til kontoen din og bruke {{provider}}-modeller i OpenCode.",
"provider.connect.apiKey.label": "{{provider}} API-nøkkel",
"Skriv inn API-nøkkelen din for {{provider}} for å koble til kontoen din og bruke {{provider}}-modeller i OpenCode.",
"provider.connect.apiKey.label": "{{provider}}-API-nøkkel",
"provider.connect.apiKey.placeholder": "API-nøkkel",
"provider.connect.apiKey.required": "API-nøkkel er påkrevd",
"provider.connect.opencodeZen.line1":
@@ -147,7 +251,7 @@ export const dict = {
"provider.connect.oauth.code.visit.link": "denne lenken",
"provider.connect.oauth.code.visit.suffix":
" for å hente autorisasjonskoden din for å koble til kontoen din og bruke {{provider}}-modeller i OpenCode.",
"provider.connect.oauth.code.label": "{{method}} autorisasjonskode",
"provider.connect.oauth.code.label": "{{method}}-autorisasjonskode",
"provider.connect.oauth.code.placeholder": "Autorisasjonskode",
"provider.connect.oauth.code.required": "Autorisasjonskode er påkrevd",
"provider.connect.oauth.code.invalid": "Ugyldig autorisasjonskode",
@@ -160,6 +264,7 @@ export const dict = {
"provider.connect.toast.connected.description": "{{provider}}-modeller er nå tilgjengelige.",
"provider.custom.title": "Egendefinert leverandør",
"provider.custom.unavailable": "Egendefinerte leverandører er ikke tilgjengelige på denne serveren",
"provider.custom.description.prefix": "Konfigurer en OpenAI-kompatibel leverandør. Se ",
"provider.custom.description.link": "dokumentasjon for leverandørkonfigurasjon",
"provider.custom.description.suffix": ".",
@@ -168,11 +273,12 @@ export const dict = {
"provider.custom.field.providerID.description": "Små bokstaver, tall, bindestreker eller understreker",
"provider.custom.field.name.label": "Visningsnavn",
"provider.custom.field.name.placeholder": "Min AI-leverandør",
"provider.custom.field.baseURL.label": "Base-URL",
"provider.custom.field.baseURL.label": "Basis-URL",
"provider.custom.field.baseURL.placeholder": "https://api.myprovider.com/v1",
"provider.custom.field.apiKey.label": "API-nøkkel",
"provider.custom.field.apiKey.placeholder": "API-nøkkel",
"provider.custom.field.apiKey.description": "Valgfritt. La stå tomt hvis du administrerer autentisering via headers.",
"provider.custom.field.apiKey.description":
"Valgfritt. La stå tomt hvis du administrerer autentisering via HTTP-hoder.",
"provider.custom.models.label": "Modeller",
"provider.custom.models.id.label": "ID",
"provider.custom.models.id.placeholder": "modell-id",
@@ -180,18 +286,18 @@ export const dict = {
"provider.custom.models.name.placeholder": "Visningsnavn",
"provider.custom.models.remove": "Fjern modell",
"provider.custom.models.add": "Legg til modell",
"provider.custom.headers.label": "Headers (valgfritt)",
"provider.custom.headers.key.label": "Header",
"provider.custom.headers.key.placeholder": "Header-Navn",
"provider.custom.headers.label": "HTTP-hoder (valgfritt)",
"provider.custom.headers.key.label": "HTTP-hode",
"provider.custom.headers.key.placeholder": "Navn på HTTP-hode",
"provider.custom.headers.value.label": "Verdi",
"provider.custom.headers.value.placeholder": "verdi",
"provider.custom.headers.remove": "Fjern header",
"provider.custom.headers.add": "Legg til header",
"provider.custom.headers.remove": "Fjern HTTP-hode",
"provider.custom.headers.add": "Legg til HTTP-hode",
"provider.custom.error.providerID.required": "Leverandør-ID er påkrevd",
"provider.custom.error.providerID.format": "Bruk små bokstaver, tall, bindestreker eller understreker",
"provider.custom.error.providerID.exists": "Den leverandør-IDen finnes allerede",
"provider.custom.error.providerID.exists": "Denne leverandør-ID-en finnes allerede",
"provider.custom.error.name.required": "Visningsnavn er påkrevd",
"provider.custom.error.baseURL.required": "Base-URL er påkrevd",
"provider.custom.error.baseURL.required": "Basis-URL er påkrevd",
"provider.custom.error.baseURL.format": "Må starte med http:// eller https://",
"provider.custom.error.required": "Påkrevd",
"provider.custom.error.duplicate": "Duplikat",
@@ -224,7 +330,7 @@ export const dict = {
"common.cancel": "Avbryt",
"common.connect": "Koble til",
"common.disconnect": "Koble fra",
"common.continue": "Send inn",
"common.continue": "Fortsett",
"common.submit": "Send inn",
"common.save": "Lagre",
"common.saving": "Lagrer...",
@@ -245,13 +351,13 @@ export const dict = {
"prompt.example.3": "Fiks ødelagte tester",
"prompt.example.4": "Forklar hvordan autentisering fungerer",
"prompt.example.5": "Finn og fiks sikkerhetssårbarheter",
"prompt.example.6": "Legg til enhetstester for brukerservicen",
"prompt.example.6": "Legg til enhetstester for brukertjenesten",
"prompt.example.7": "Refaktorer denne funksjonen for bedre lesbarhet",
"prompt.example.8": "Hva betyr denne feilen?",
"prompt.example.9": "Hjelp meg med å feilsøke dette problemet",
"prompt.example.10": "Generer API-dokumentasjon",
"prompt.example.11": "Optimaliser databasespørringer",
"prompt.example.12": "Legg til inputvalidering",
"prompt.example.12": "Legg til inndatavalidering",
"prompt.example.13": "Lag en ny komponent for...",
"prompt.example.14": "Hvordan deployer jeg dette prosjektet?",
"prompt.example.15": "Gjennomgå koden min for beste praksis",
@@ -261,7 +367,7 @@ export const dict = {
"prompt.example.19": "Legg til logging i hele kodebasen",
"prompt.example.20": "Hvilke avhengigheter er utdaterte?",
"prompt.example.21": "Hjelp meg med å skrive et migreringsskript",
"prompt.example.22": "Implementer caching for dette endepunktet",
"prompt.example.22": "Implementer hurtigbufring for dette endepunktet",
"prompt.example.23": "Legg til paginering i denne listen",
"prompt.example.24": "Lag en CLI-kommando for...",
"prompt.example.25": "Hvordan fungerer miljøvariabler her?",
@@ -271,7 +377,7 @@ export const dict = {
"prompt.dropzone.label": "Slipp bilder, PDF-er eller tekstfiler her",
"prompt.dropzone.file.label": "Slipp for å @nevne fil",
"prompt.slash.badge.custom": "egendefinert",
"prompt.slash.badge.skill": "skill",
"prompt.slash.badge.skill": "ferdighet",
"prompt.slash.badge.mcp": "mcp",
"prompt.context.active": "aktiv",
"prompt.context.includeActiveFile": "Inkluder aktiv fil",
@@ -297,14 +403,14 @@ export const dict = {
"prompt.toast.shellSendFailed.title": "Kunne ikke sende shell-kommando",
"prompt.toast.commandSendFailed.title": "Kunne ikke sende kommando",
"prompt.toast.promptSendFailed.title": "Kunne ikke sende forespørsel",
"prompt.toast.promptSendFailed.description": "Kunne ikke hente økt",
"prompt.toast.promptSendFailed.description": "Kunne ikke hente sesjon",
"dialog.mcp.title": "MCP-er",
"dialog.mcp.description": "{{enabled}} av {{total}} aktivert",
"dialog.mcp.empty": "Ingen MCP-er konfigurert",
"dialog.lsp.empty": "LSP-er automatisk oppdaget fra filtyper",
"dialog.plugins.empty": "Plugins konfigurert i opencode.json",
"dialog.plugins.empty": "Programtillegg konfigurert i opencode.json",
"mcp.status.connected": "tilkoblet",
"mcp.status.failed": "mislyktes",
@@ -365,7 +471,8 @@ export const dict = {
"dialog.project.edit.worktree.startup.placeholder": "f.eks. bun install",
"context.breakdown.title": "Kontekstfordeling",
"context.breakdown.note": 'Omtrentlig fordeling av input-tokens. "Annet" inkluderer verktøydefinisjoner og overhead.',
"context.breakdown.note":
'Omtrentlig fordeling av inndatatokener. "Annet" inkluderer verktøydefinisjoner og overhead.',
"context.breakdown.system": "System",
"context.breakdown.user": "Bruker",
"context.breakdown.assistant": "Assistent",
@@ -380,19 +487,19 @@ export const dict = {
"context.stats.provider": "Leverandør",
"context.stats.model": "Modell",
"context.stats.limit": "Kontekstgrense",
"context.stats.totalTokens": "Totalt antall tokens",
"context.stats.totalTokens": "Totalt antall tokener",
"context.stats.usage": "Forbruk",
"context.stats.inputTokens": "Input-tokens",
"context.stats.outputTokens": "Output-tokens",
"context.stats.reasoningTokens": "Resonnerings-tokens",
"context.stats.cacheTokens": "Cache-tokens (les/skriv)",
"context.stats.inputTokens": "Inndatatokener",
"context.stats.outputTokens": "Utdatatokener",
"context.stats.reasoningTokens": "Resonneringstokener",
"context.stats.cacheTokens": "Hurtigbuffertokener (les/skriv)",
"context.stats.userMessages": "Brukermeldinger",
"context.stats.assistantMessages": "Assistentmeldinger",
"context.stats.totalCost": "Total kostnad",
"context.stats.sessionCreated": "Sesjon opprettet",
"context.stats.lastActivity": "Siste aktivitet",
"context.usage.tokens": "Tokens",
"context.usage.tokens": "Tokener",
"context.usage.usage": "Forbruk",
"context.usage.cost": "Kostnad",
"context.usage.clickToView": "Klikk for å se kontekst",
@@ -423,9 +530,9 @@ export const dict = {
"toast.scheme.title": "Fargevalg",
"toast.workspace.enabled.title": "Arbeidsområder aktivert",
"toast.workspace.enabled.description": "Flere worktrees vises nå i sidefeltet",
"toast.workspace.enabled.description": "Flere arbeidsområder vises nå i sidefeltet",
"toast.workspace.disabled.title": "Arbeidsområder deaktivert",
"toast.workspace.disabled.description": "Kun hoved-worktree vises i sidefeltet",
"toast.workspace.disabled.description": "Kun hovedarbeidsområdet vises i sidefeltet",
"toast.permissions.autoaccept.on.title": "Aksepterer tillatelser automatisk",
"toast.permissions.autoaccept.on.description": "Forespørsler om tillatelse vil bli godkjent automatisk",
@@ -473,7 +580,7 @@ export const dict = {
"error.page.version": "Versjon: {{version}}",
"error.dev.rootNotFound":
"Rotelement ikke funnet. Glemte du å legge det til i index.html? Eller kanskje id-attributten er feilstavet?",
"Rotelement ikke funnet. Glemte du å legge det til i index.html? Eller kanskje id-attributtet er feilstavet?",
"error.serverSync.connectFailed": "Kunne ikke koble til server. Kjører det en server på `{{url}}`?",
"directory.error.invalidUrl": "Ugyldig mappe i URL-en.",
@@ -573,7 +680,7 @@ export const dict = {
"status.popover.tab.servers": "Servere",
"status.popover.tab.mcp": "MCP",
"status.popover.tab.lsp": "LSP",
"status.popover.tab.plugins": "Plugins",
"status.popover.tab.plugins": "Programtillegg",
"status.popover.action.manageServers": "Administrer servere",
"session.share.popover.title": "Publiser på nett",
@@ -601,6 +708,12 @@ export const dict = {
"terminal.connectionLost.title": "Tilkobling mistet",
"terminal.connectionLost.description":
"Terminalforbindelsen ble avbrutt. Dette kan skje når serveren starter på nytt.",
"terminal.connectTicket.csrfError":
"Tilkoblingsbilletten for PTY ble avvist av opprinnelses- eller CSRF-kontroller. Kontroller serverens CORS-konfigurasjon.",
"terminal.connectTicket.statusError": "Tilkoblingsbilletten for PTY mislyktes med {{status}}",
"titlebar.update": "Oppdater",
"titlebar.updateVersion": "Oppdater {{version}}",
"common.closeTab": "Lukk fane",
"common.dismiss": "Avvis",
@@ -613,7 +726,7 @@ export const dict = {
"common.delete": "Slett",
"common.close": "Lukk",
"common.edit": "Rediger",
"common.loadMore": "Last flere",
"common.loadMore": "Last inn flere",
"common.key.esc": "ESC",
"sidebar.menu.toggle": "Veksle meny",
@@ -651,16 +764,17 @@ export const dict = {
"settings.general.row.appearance.title": "Utseende",
"settings.general.row.appearance.description": "Tilpass hvordan OpenCode ser ut på enheten din",
"settings.general.row.colorScheme.title": "Fargevalg",
"settings.general.row.colorScheme.description": "Velg om OpenCode skal følge systemets, lyst eller mørkt tema",
"settings.general.row.colorScheme.description":
"Velg om OpenCode skal følge systeminnstillingen eller bruke lyst eller mørkt tema",
"settings.general.row.theme.title": "Tema",
"settings.general.row.theme.description": "Tilpass hvordan OpenCode er tematisert.",
"settings.general.row.theme.description": "Tilpass temaet i OpenCode.",
"settings.general.row.font.title": "Kodefont",
"settings.general.row.font.description": "Tilpass skrifttypen som brukes i kodeblokker",
"settings.general.row.terminalFont.title": "Terminalskrift",
"settings.general.row.terminalFont.description": "Tilpass skrifttypen som brukes i terminalen",
"settings.general.row.uiFont.title": "UI-skrift",
"settings.general.row.uiFont.description": "Tilpass skrifttypen som brukes i hele grensesnittet",
"settings.general.row.followup.title": "Oppfølgingsadferd",
"settings.general.row.followup.title": "Oppfølgingsatferd",
"settings.general.row.followup.description": "Velg om oppfølgingsspørsmål skal kjøres umiddelbart eller vente i kø",
"settings.general.row.followup.option.queue": "Kø",
"settings.general.row.followup.option.steer": "Styr",
@@ -671,10 +785,10 @@ export const dict = {
"settings.general.row.editToolPartsExpanded.title": "Utvid edit-verktøydeler",
"settings.general.row.editToolPartsExpanded.description":
"Vis edit-, write- og patch-verktøydeler utvidet som standard i tidslinjen",
"settings.general.row.wayland.title": "Bruk innebygd Wayland",
"settings.general.row.wayland.description": "Deaktiver X11-fallback på Wayland. Krever omstart.",
"settings.general.row.wayland.title": "Bruk Wayland direkte",
"settings.general.row.wayland.description": "Deaktiver X11-reserveløsningen på Wayland. Krever omstart.",
"settings.general.row.wayland.tooltip":
"På Linux med skjermer med blandet oppdateringsfrekvens kan innebygd Wayland være mer stabilt.",
"På Linux med skjermer med blandet oppdateringsfrekvens kan direkte Wayland-støtte være mer stabilt.",
"settings.general.row.releaseNotes.title": "Utgivelsesnotater",
"settings.general.row.releaseNotes.description": 'Vis "Hva er nytt"-vinduer etter oppdateringer',
@@ -685,7 +799,7 @@ export const dict = {
"settings.updates.row.check.description": "Se etter oppdateringer manuelt og installer hvis tilgjengelig",
"settings.updates.action.checkNow": "Sjekk nå",
"settings.updates.action.checking": "Sjekker...",
"settings.updates.toast.latest.title": "Du er oppdatert",
"settings.updates.toast.latest.title": "OpenCode er oppdatert",
"settings.updates.toast.latest.description": "Du bruker den nyeste versjonen av OpenCode.",
"sound.option.none": "Ingen",
"sound.option.alert01": "Varsel 01",
@@ -754,7 +868,7 @@ export const dict = {
"settings.shortcuts.reset.toast.title": "Snarveier tilbakestilt",
"settings.shortcuts.reset.toast.description": "Tastatursnarveier er tilbakestilt til standard.",
"settings.shortcuts.conflict.title": "Snarvei allerede i bruk",
"settings.shortcuts.conflict.description": "{{keybind}} er allerede tilordnet til {{titles}}.",
"settings.shortcuts.conflict.description": "{{keybind}} er allerede tilordnet {{titles}}.",
"settings.shortcuts.unassigned": "Ikke tilordnet",
"settings.shortcuts.pressKeys": "Trykk taster",
"settings.shortcuts.search.placeholder": "Søk etter snarveier",
@@ -804,7 +918,7 @@ export const dict = {
"settings.permissions.tool.grep.title": "Grep",
"settings.permissions.tool.grep.description": "Søk i filinnhold ved hjelp av regulære uttrykk",
"settings.permissions.tool.list.title": "Liste",
"settings.permissions.tool.list.description": "List filer i en mappe",
"settings.permissions.tool.list.description": "List opp filer i en mappe",
"settings.permissions.tool.bash.title": "Bash",
"settings.permissions.tool.bash.description": "Kjør shell-kommandoer",
"settings.permissions.tool.task.title": "Oppgave",
@@ -822,7 +936,7 @@ export const dict = {
"settings.permissions.tool.external_directory.title": "Ekstern mappe",
"settings.permissions.tool.external_directory.description": "Få tilgang til filer utenfor prosjektmappen",
"settings.permissions.tool.doom_loop.title": "Doom Loop",
"settings.permissions.tool.doom_loop.description": "Oppdager gjentatte verktøykall med identisk input",
"settings.permissions.tool.doom_loop.description": "Oppdager gjentatte verktøykall med identiske inndata",
"session.delete.failed.title": "Kunne ikke slette sesjon",
"session.delete.title": "Slett sesjon",
@@ -867,14 +981,14 @@ export const dict = {
"common.time.hoursAgo.short": "{{count}} t siden",
"common.time.daysAgo.short": "{{count}} d siden",
"settings.providers.connected.environmentDescription": "Koblet til fra miljøvariablene dine",
"settings.providers.custom.description": "Legg til en OpenAI-kompatibel leverandør via basis-URL.",
"settings.providers.custom.description": "Legg til en OpenAI-kompatibel leverandør via en basis-URL.",
"app.server.unreachable": "Kunne ikke nå {{server}}",
"app.server.retrying": "Prøver på nytt automatisk...",
"app.server.otherServers": "Andre servere",
"dialog.server.add.usernamePlaceholder": "brukernavn",
"dialog.server.add.passwordPlaceholder": "passord",
"server.row.noUsername": "inget brukernavn",
"server.row.noUsername": "ikke noe brukernavn",
"session.review.noVcs.createGit.title": "Opprett et Git-depot",
"session.review.noVcs.createGit.description": "Spor, gjennomgå og angre endringer i dette prosjektet",
"session.review.noVcs.createGit.actionLoading": "Oppretter Git-depot...",
@@ -883,6 +997,9 @@ export const dict = {
"session.question.progress": "{{current}} av {{total}} spørsmål",
"session.header.open.finder": "Finder",
"session.header.open.fileExplorer": "Filutforsker",
"session.header.reveal.finder": "Vis i Finder",
"session.header.reveal.fileExplorer": "Vis i Filutforsker",
"session.header.reveal.containingFolder": "Åpne mappen som inneholder dette elementet",
"session.header.open.fileManager": "Filbehandler",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -901,25 +1018,33 @@ export const dict = {
"debugBar.na": "i/t",
"debugBar.nav.label": "NAV",
"debugBar.nav.tip":
"Siste fullførte ruteovergang som berører en sesjonsside, målt fra ruterstart til første opptegning etter at den har roet seg.",
"Siste fullførte ruteovergang som berører en sesjonsside, målt fra ruterstart til første gjengivelse etter at den har roet seg.",
"debugBar.fps.label": "FPS",
"debugBar.fps.tip": "Rullende bilder per sekund over de siste 5 sekundene.",
"debugBar.frame.label": "FRAME",
"debugBar.frame.tip": "Verste bildetid over de siste 5 sekundene.",
"debugBar.frame.tip": "Lengste bildetid over de siste 5 sekundene.",
"debugBar.jank.label": "JANK",
"debugBar.jank.tip": "Bilder over 32ms i de siste 5 sekundene.",
"debugBar.jank.tip": "Bilder som tar over 32 ms i de siste 5 sekundene.",
"debugBar.long.label": "LONG",
"debugBar.long.tip": "Blokkert tid og antall lange oppgaver i de siste 5 sekundene. Maks oppgave: {{max}}.",
"debugBar.long.tip": "Blokkert tid og antall lange oppgaver i de siste 5 sekundene. Lengste oppgave: {{max}}.",
"debugBar.delay.label": "DELAY",
"debugBar.delay.tip": "Verste observerte inndataforsinkelse i de siste 5 sekundene.",
"debugBar.delay.tip": "Lengste observerte inndataforsinkelse i de siste 5 sekundene.",
"debugBar.inp.label": "INP",
"debugBar.inp.tip":
"Omtrentlig interaksjonsvarighet over de siste 5 sekundene. Dette er INP-lignende, ikke den offisielle Web Vitals INP.",
"debugBar.cls.label": "CLS",
"debugBar.cls.tip": "Kumulativ layoutforskyvning for gjeldende app-levetid.",
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Brukt JS-heap vs heap-grense. Kun Chromium.",
"debugBar.mem.tip": "Brukt JS-heap vs heap-grense. {{used}} av {{limit}}.",
"debugBar.mem.tipUnavailable": "Brukt JS-heap kontra heap-grense. Kun Chromium.",
"debugBar.mem.tip": "Brukt JS-heap kontra heap-grense. {{used}} av {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Tving fokusstiler på alle interaktive elementer",
"debugBar.focus.on": "PÅ",
"debugBar.focus.off": "AV",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Tving layoutretningen for hele appen uten å endre valgt språk",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
@@ -1030,6 +1155,22 @@ export const dict = {
"wsl.onboarding.versionMismatch": "Den installerte versjonen samsvarer ikke med versjonen av skrivebordsappen.",
"wsl.onboarding.adding": "Legger til...",
"help.tabs.toast.ariaLabel": "Vi introduserer faner. Organiser arbeidet og de aktive sesjonene dine med faner",
"help.tabs.toast.dismiss": "Avvis informasjon om faner",
"help.tabs.title": "Vi introduserer faner",
"help.tabs.description": "Organiser arbeidet og de aktive sesjonene dine med faner",
"help.tabs.date": "14. juli",
"help.tabs.introduction": "OpenCode Desktop er nå bygget rundt faner.",
"help.tabs.sessions":
"Start en ny sesjon i en fane, eller åpne en eksisterende sesjon fra et av prosjektene dine. Åpne en ny fane når du skal begynne på noe nytt, og lukk den når du er ferdig.",
"help.tabs.organize":
"Når du har noen få faner åpne, blir det enklere å organisere de aktive sesjonene. Gi fanene navn som er lette å huske, hvis du planlegger å beholde dem.",
"help.tabs.home":
"Du finner alle sesjonene og prosjektene dine på den nye Hjem-skjermen. Når du velger en sesjon, åpnes den i en fane.",
"help.tabs.persistence": "Fanene er fortsatt åpne når du åpner appen på nytt.",
"help.tabs.worktrees":
"Det nye oppsettet støtter ikke Git Worktrees ennå, men støtte kommer snart. Hvis du foretrekker å fortsette med det forrige oppsettet, kan du bytte mellom oppsettene i Innstillinger. Vær oppmerksom på at det nye oppsettet blir permanent om noen uker.",
"language.uk": "Українська",
"error.page.description.localServerStartup": "Det oppstod en feil under oppstart av den lokale serveren.",
@@ -1058,7 +1199,7 @@ export const dict = {
"session.error.notFound.description": "Denne fanen peker til en sesjon som ikke lenger finnes på denne serveren.",
"session.error.notFound.closeTab": "Lukk fane",
"session.error.serverConnection": "Kan ikke koble til denne serveren",
"session.review.noUncommittedChanges": "Ingen ucommittede endringer ennå",
"session.review.noUncommittedChanges": "Ingen endringer som ikke er sjekket inn ennå",
"session.review.noBranchChanges": "Ingen grenendringer ennå",
"session.question.minimize": "Minimer spørsmål",
"session.question.restore": "Gjenopprett spørsmål",
@@ -1096,8 +1237,9 @@ export const dict = {
"settings.general.row.mobileTitlebarBottom.title": "Navigasjon nederst",
"settings.general.row.mobileTitlebarBottom.description":
"Plasser tittellinjen og sesjonsfanene nederst på mobilskjermen",
"settings.general.row.showCustomAgents.title": "Egendefinerte agenter",
"settings.general.row.showCustomAgents.description": "Vis agentvelgeren i skrivefeltet",
"settings.general.row.showCustomAgents.title": "Vis agent",
"settings.general.row.showCustomAgents.description":
"Bytt mellom agenter i skrivefeltet. Når velgeren er skjult, brukes Build-agenten som standard.",
"settings.general.row.newInterface.title": "Nytt oppsett",
"settings.general.row.newInterface.badge": "Ny",
"settings.general.row.newInterface.description":
File diff suppressed because it is too large Load Diff
+84 -5
View File
@@ -18,8 +18,29 @@ const appLocales = [
"tr",
"zh",
"zht",
"hi",
"nl",
"id",
"vi",
"it",
"ur",
"pa",
"az",
"fi",
"sv",
] as const
const desktopLocales = appLocales.filter((locale) => locale !== "th" && locale !== "tr")
const desktopLocales = appLocales
const pluralCategories: Partial<Record<(typeof appLocales)[number], readonly string[]>> = {
ar: ["zero", "two", "few", "many"],
br: ["many"],
bs: ["few"],
es: ["many"],
fr: ["many"],
it: ["many"],
pl: ["few", "many"],
ru: ["few", "many"],
uk: ["few", "many"],
}
const domains = [
{
@@ -43,18 +64,23 @@ const domains = [
] as const
describe.skipIf(!!process.env.CI)("i18n parity", () => {
test("non-English locales have every English key", async () => {
test("non-English locales have every English key and required plural variants", async () => {
for (const domain of domains) {
const source = await dictionary(domain.source)
for (const locale of domain.locales) {
const target = await dictionary(domain.target(locale))
const missing = Object.keys(source).filter((key) => !Object.hasOwn(target, key))
const extra = Object.keys(target).filter((key) => !Object.hasOwn(source, key))
const extra = Object.keys(target)
.filter((key) => !Object.hasOwn(source, key))
.sort()
const expected = pluralFamilies(source)
.flatMap((key) => (pluralCategories[locale] ?? []).map((category) => `${key}.${category}`))
.sort()
expect({ domain: domain.name, locale, missing, extra }).toEqual({
domain: domain.name,
locale,
missing: [],
extra: [],
extra: expected,
})
}
}
@@ -68,7 +94,17 @@ describe.skipIf(!!process.env.CI)("i18n parity", () => {
const mismatched = Object.keys(source).filter(
(key) => Object.hasOwn(target, key) && placeholders(source[key]).join() !== placeholders(target[key]).join(),
)
expect({ domain: domain.name, locale, mismatched }).toEqual({ domain: domain.name, locale, mismatched: [] })
const pluralMismatched = pluralFamilies(source).flatMap((key) =>
(pluralCategories[locale] ?? [])
.map((category) => `${key}.${category}`)
.filter((variant) => placeholders(source[`${key}.other`]).join() !== placeholders(target[variant]).join()),
)
expect({ domain: domain.name, locale, mismatched, pluralMismatched }).toEqual({
domain: domain.name,
locale,
mismatched: [],
pluralMismatched: [],
})
}
}
})
@@ -100,6 +136,38 @@ describe.skipIf(!!process.env.CI)("i18n parity", () => {
})
})
describe("i18n plural parity", () => {
test("locale-specific categories exist and preserve count placeholders", async () => {
for (const domain of domains.slice(0, 2)) {
const source = await dictionary(domain.source)
const families = pluralFamilies(source)
for (const locale of domain.locales) {
const target = await dictionary(domain.target(locale))
const missing = families.flatMap((key) =>
(pluralCategories[locale] ?? [])
.map((category) => `${key}.${category}`)
.filter((variant) => !Object.hasOwn(target, variant)),
)
const mismatched = families.flatMap((key) =>
(pluralCategories[locale] ?? [])
.map((category) => `${key}.${category}`)
.filter(
(variant) =>
Object.hasOwn(target, variant) &&
placeholders(source[`${key}.other`]).join() !== placeholders(target[variant]).join(),
),
)
expect({ domain: domain.name, locale, missing, mismatched }).toEqual({
domain: domain.name,
locale,
missing: [],
mismatched: [],
})
}
}
})
})
async function dictionary(file: string) {
const module: unknown = await import(file)
if (typeof module !== "object" || module === null || !("dict" in module) || !isDictionary(module.dict)) {
@@ -116,3 +184,14 @@ function isDictionary(value: unknown): value is Record<string, string> {
function placeholders(value: string) {
return Array.from(value.matchAll(/{{\s*([^}]+?)\s*}}/g), (match) => match[1]).sort()
}
function pluralFamilies(dictionary: Record<string, string>) {
return Object.keys(dictionary)
.filter(
(key) =>
key.endsWith(".one") &&
dictionary[key].includes("{{count}}") &&
dictionary[`${key.slice(0, -4)}.other`]?.includes("{{count}}"),
)
.map((key) => key.slice(0, -4))
}
+206 -60
View File
@@ -1,4 +1,103 @@
export const dict = {
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Plik",
"desktop.menu.edit": "Edycja",
"desktop.menu.view": "Widok",
"desktop.menu.go": "Przejdź",
"desktop.menu.window": "Okno",
"desktop.menu.help": "Pomoc",
"desktop.menu.checkForUpdates": "Sprawdź aktualizacje...",
"desktop.menu.settings": "Ustawienia",
"desktop.menu.reloadWebview": "Wczytaj ponownie widok internetowy",
"desktop.menu.restart": "Uruchom ponownie",
"desktop.menu.exportLogs": "Eksportuj dzienniki...",
"desktop.menu.newSession": "Nowa sesja",
"desktop.menu.openProject": "Otwórz projekt...",
"desktop.menu.newWindow": "Nowe okno",
"desktop.menu.closeWindow": "Zamknij okno",
"desktop.menu.undo": "Cofnij",
"desktop.menu.redo": "Ponów",
"desktop.menu.cut": "Wytnij",
"desktop.menu.copy": "Kopiuj",
"desktop.menu.paste": "Wklej",
"desktop.menu.delete": "Usuń",
"desktop.menu.selectAll": "Zaznacz wszystko",
"desktop.menu.toggleSidebar": "Przełącz pasek boczny",
"desktop.menu.toggleTerminal": "Przełącz terminal",
"desktop.menu.toggleFileTree": "Przełącz drzewo plików",
"desktop.menu.reload": "Wczytaj ponownie",
"desktop.menu.toggleDeveloperTools": "Przełącz narzędzia deweloperskie",
"desktop.menu.actualSize": "Rozmiar rzeczywisty",
"desktop.menu.zoomIn": "Powiększ",
"desktop.menu.zoomOut": "Pomniejsz",
"desktop.menu.toggleFullScreen": "Przełącz tryb pełnoekranowy",
"desktop.menu.back": "Wstecz",
"desktop.menu.forward": "Dalej",
"desktop.menu.previousSession": "Poprzednia sesja",
"desktop.menu.nextSession": "Następna sesja",
"desktop.menu.previousProject": "Poprzedni projekt",
"desktop.menu.nextProject": "Następny projekt",
"desktop.menu.minimize": "Minimalizuj",
"desktop.menu.maximize": "Maksymalizuj",
"desktop.menu.documentation": "Dokumentacja OpenCode",
"desktop.menu.supportForum": "Forum pomocy technicznej",
"desktop.menu.shareFeedback": "Prześlij opinię",
"desktop.menu.reportBug": "Zgłoś błąd",
"desktop.menu.ariaLabel": "Menu OpenCode",
"desktop.updater.dialog.checkFailed.message": "Nie udało się sprawdzić dostępności aktualizacji.",
"desktop.updater.dialog.checkFailed.title": "Błąd aktualizacji",
"desktop.updater.dialog.upToDate.message": "Masz najnowszą wersję.",
"desktop.updater.dialog.upToDate.title": "Brak aktualizacji",
"desktop.updater.dialog.ready.message": "Pobrano aktualizację {{version}}. Uruchomić ponownie teraz?",
"desktop.updater.dialog.ready.title": "Aktualizacja jest gotowa",
"desktop.updater.dialog.restart": "Uruchom ponownie",
"desktop.updater.dialog.later": "Później",
"desktop.recovery.action.relaunch": "Uruchom ponownie",
"desktop.recovery.action.exportLogs": "Eksportuj dzienniki",
"desktop.recovery.action.keepWaiting": "Czekaj dalej",
"desktop.recovery.action.quit": "Zakończ",
"desktop.recovery.loadFailed": "Nie udało się wczytać OpenCode",
"desktop.recovery.terminated": "Okno OpenCode zostało nieoczekiwanie zamknięte",
"desktop.recovery.unresponsive": "OpenCode nie odpowiada",
"desktop.recovery.unresponsive.detail": "Możesz ponownie uruchomić aplikację, otworzyć dzienniki lub nadal czekać.",
"desktop.recovery.loadFailed.detail": "Okno: {{window}}\nURL: {{url}}\nBłąd: {{code}} {{description}}",
"desktop.recovery.terminated.detail": "Okno: {{window}}\nPrzyczyna: {{reason}}\nKod: {{code}}",
"desktop.recovery.unknown": "<nieznane>",
"desktop.dialog.chooseFolder": "Wybierz folder",
"desktop.dialog.chooseFile": "Wybierz plik",
"desktop.dialog.saveFile": "Zapisz plik",
"desktop.dialog.files": "Pliki",
"desktop.server.local": "Serwer lokalny",
"desktop.wsl.error.windowsOnly": "WSL jest dostępny tylko w systemie Windows",
"desktop.wsl.error.unavailable": "WSL jest niedostępny",
"desktop.wsl.error.listInstalled": "Nie udało się wyświetlić listy zainstalowanych dystrybucji WSL",
"desktop.wsl.error.listOnline": "Nie udało się wyświetlić listy dystrybucji WSL dostępnych online",
"desktop.wsl.error.executeDistro": "Nie można wykonywać poleceń w dystrybucji",
"desktop.wsl.error.installWsl": "Nie udało się zainstalować WSL",
"desktop.wsl.error.installDistro": "Nie udało się zainstalować dystrybucji: {{distro}}",
"desktop.wsl.error.installOpencode": "Nie udało się zainstalować OpenCode",
"desktop.wsl.error.alreadyAdded": "Dystrybucja {{distro}} została już dodana",
"desktop.wsl.error.opencodeMissing": "Program opencode nie jest zainstalowany w tej dystrybucji",
"desktop.wsl.error.opencodeCannotRun": "Program opencode jest zainstalowany, ale nie można go uruchomić",
"desktop.wsl.error.opencodeNotInstalled": "OpenCode nie jest zainstalowany w dystrybucji {{distro}}",
"desktop.wsl.error.updateVersion":
"Aktualizacja OpenCode została ukończona, ale dystrybucja {{distro}} nadal zgłasza wersję {{installed}}; oczekiwano {{expected}}",
"desktop.wsl.error.noVersion": "brak wersji",
"desktop.wsl.error.serverExited": "Serwer WSL zakończył działanie po uruchomieniu (code={{code}} signal={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"Serwer WSL zakończył działanie przed osiągnięciem gotowości (code={{code}} signal={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout":
"Przekroczono limit czasu {{timeout}}ms podczas sprawdzania kondycji procesu sidecar dla dystrybucji {{distro}}",
"desktop.wsl.error.commandTimeout": "Polecenie {{command}} {{args}} przekroczyło limit czasu {{timeout}}ms",
"desktop.wsl.error.failedPort": "Nie udało się uzyskać portu",
"desktop.picker.error.notSelected": "Nie wybrano pliku w oknie wyboru",
"desktop.picker.error.sizeLimit": "Wybrane załączniki przekraczają limit {{limit}} MB",
"command.category.suggested": "Sugerowane",
"command.category.view": "Widok",
"command.category.project": "Projekt",
@@ -16,6 +115,7 @@ export const dict = {
"command.category.permissions": "Uprawnienia",
"command.category.workspace": "Przestrzeń robocza",
"command.category.settings": "Ustawienia",
"command.logs.export": "Eksportuj dzienniki",
"theme.scheme.system": "Systemowy",
"theme.scheme.light": "Jasny",
"theme.scheme.dark": "Ciemny",
@@ -45,7 +145,7 @@ export const dict = {
"command.tab.reopenClosed": "Otwórz ponownie zamkniętą kartę",
"command.context.addSelection": "Dodaj zaznaczenie do kontekstu",
"command.context.addSelection.description": "Dodaj zaznaczone linie z bieżącego pliku",
"command.input.focus": "Fokus na pole wejściowe",
"command.input.focus": "Przejdź do pola wprowadzania",
"command.terminal.toggle": "Przełącz terminal",
"command.fileTree.toggle": "Przełącz drzewo plików",
"command.review.toggle": "Przełącz przegląd",
@@ -82,7 +182,7 @@ export const dict = {
"command.session.fork": "Rozwidlij od wiadomości",
"command.session.fork.description": "Utwórz nową sesję od poprzedniej wiadomości",
"command.session.share": "Udostępnij sesję",
"command.session.share.description": "Udostępnij tę sesję i skopiuj URL do schowka",
"command.session.share.description": "Udostępnij tę sesję i skopiuj adres URL do schowka",
"command.session.unshare": "Przestań udostępniać sesję",
"command.session.unshare.description": "Zatrzymaj udostępnianie tej sesji",
"palette.search.placeholder": "Szukaj plików, poleceń i sesji",
@@ -94,10 +194,11 @@ export const dict = {
"dialog.provider.empty": "Nie znaleziono dostawców",
"dialog.provider.group.popular": "Popularne",
"dialog.provider.group.other": "Inne",
"dialog.provider.custom.label": "Niestandardowy dostawca zgodny z OpenAI",
"dialog.provider.tag.recommended": "Zalecane",
"dialog.provider.opencode.note": "Wyselekcjonowane modele, w tym Claude, GPT, Gemini i inne",
"dialog.provider.opencode.note": "Starannie dobrane modele, w tym Claude, GPT, Gemini i inne",
"dialog.provider.opencode.tagline": "Niezawodne, zoptymalizowane modele",
"dialog.provider.opencodeGo.tagline": "Tania subskrypcja dla każdego",
"dialog.provider.opencodeGo.tagline": "Niedroga subskrypcja dla każdego",
"dialog.provider.anthropic.note": "Bezpośredni dostęp do modeli Claude, w tym Pro i Max",
"dialog.provider.copilot.note": "Modele AI do pomocy w kodowaniu przez GitHub Copilot",
"dialog.provider.openai.note": "Modele GPT do szybkich i wszechstronnych zadań AI",
@@ -106,17 +207,20 @@ export const dict = {
"dialog.provider.vercel.note": "Ujednolicony dostęp do modeli AI z inteligentnym routingiem",
"dialog.model.select.title": "Wybierz model",
"dialog.model.search.placeholder": "Szukaj modeli",
"dialog.model.empty": "Brak wyników modelu",
"dialog.model.empty": "Nie znaleziono modeli",
"dialog.model.manage": "Zarządzaj modelami",
"dialog.model.manage.description": "Dostosuj, które modele pojawiają się w wyborze modelu.",
"dialog.model.manage.provider.toggle": "Przełącz wszystkie modele {{provider}}",
"dialog.model.unpaid.freeModels.title": "Darmowe modele dostarczane przez OpenCode",
"dialog.model.unpaid.addMore.title": "Dodaj więcej modeli od popularnych dostawców",
"dialog.model.unpaid.viewMoreProviders": "Zobacz ponad 70 innych dostawców",
"dialog.provider.viewAll": "Zobacz więcej dostawców",
"provider.connect.title": "Połącz {{provider}}",
"provider.connect.title.anthropicProMax": "Zaloguj się z Claude Pro/Max",
"provider.connect.title.anthropicProMax": "Zaloguj się za pomocą konta Claude Pro/Max",
"provider.connect.selectMethod": "Wybierz metodę logowania dla {{provider}}.",
"provider.connect.method.apiKey": "Klucz API",
"provider.connect.method.browser": "Przeglądarka",
"provider.connect.method.headless": "Bez przeglądarki",
"provider.connect.status.inProgress": "Autoryzacja w toku...",
"provider.connect.status.waiting": "Oczekiwanie na autoryzację...",
"provider.connect.status.failed": "Autoryzacja nie powiodła się: {{error}}",
@@ -126,9 +230,9 @@ export const dict = {
"provider.connect.apiKey.placeholder": "Klucz API",
"provider.connect.apiKey.required": "Klucz API jest wymagany",
"provider.connect.opencodeZen.line1":
"OpenCode Zen daje dostęp do wybranego zestawu niezawodnych, zoptymalizowanych modeli dla agentów kodujących.",
"OpenCode Zen daje dostęp do wybranego zestawu niezawodnych, zoptymalizowanych modeli dla agentów programistycznych.",
"provider.connect.opencodeZen.line2":
"Z jednym kluczem API uzyskasz dostęp do modeli takich jak Claude, GPT, Gemini, GLM i więcej.",
"Za pomocą jednego klucza API uzyskasz dostęp do modeli takich jak Claude, GPT, Gemini i GLM, a także wielu innych.",
"provider.connect.opencodeZen.visit.prefix": "Odwiedź ",
"provider.connect.opencodeZen.visit.link": "opencode.ai/zen",
"provider.connect.opencodeZen.visit.suffix": ", aby odebrać swój klucz API.",
@@ -148,6 +252,7 @@ export const dict = {
"provider.connect.toast.connected.title": "Połączono {{provider}}",
"provider.connect.toast.connected.description": "Modele {{provider}} są teraz dostępne do użycia.",
"provider.custom.title": "Dostawca niestandardowy",
"provider.custom.unavailable": "Niestandardowi dostawcy są niedostępni na tym serwerze",
"provider.custom.description.prefix": "Skonfiguruj dostawcę zgodnego z OpenAI. Zobacz ",
"provider.custom.description.link": "dokumentację konfiguracji dostawcy",
"provider.custom.description.suffix": ".",
@@ -156,7 +261,7 @@ export const dict = {
"provider.custom.field.providerID.description": "Małe litery, cyfry, łączniki lub podkreślenia",
"provider.custom.field.name.label": "Nazwa wyświetlana",
"provider.custom.field.name.placeholder": "Mój Dostawca AI",
"provider.custom.field.baseURL.label": "Bazowy URL",
"provider.custom.field.baseURL.label": "Bazowy adres URL",
"provider.custom.field.baseURL.placeholder": "https://api.mojdostawca.com/v1",
"provider.custom.field.apiKey.label": "Klucz API",
"provider.custom.field.apiKey.placeholder": "Klucz API",
@@ -180,7 +285,7 @@ export const dict = {
"provider.custom.error.providerID.format": "Używaj małych liter, cyfr, łączników lub podkreśleń",
"provider.custom.error.providerID.exists": "To ID dostawcy już istnieje",
"provider.custom.error.name.required": "Nazwa wyświetlana jest wymagana",
"provider.custom.error.baseURL.required": "Bazowy URL jest wymagany",
"provider.custom.error.baseURL.required": "Bazowy adres URL jest wymagany",
"provider.custom.error.baseURL.format": "Musi zaczynać się od http:// lub https://",
"provider.custom.error.required": "Wymagane",
"provider.custom.error.duplicate": "Duplikat",
@@ -216,7 +321,7 @@ export const dict = {
"common.clear": "Wyczyść",
"common.connect": "Połącz",
"common.disconnect": "Rozłącz",
"common.continue": "Prześlij",
"common.continue": "Kontynuuj",
"common.submit": "Prześlij",
"common.save": "Zapisz",
"common.saving": "Zapisywanie...",
@@ -229,46 +334,46 @@ export const dict = {
"prompt.placeholder.summarizeComment": "Podsumuj komentarz…",
"prompt.mode.shell": "Terminal",
"prompt.mode.normal": "Prompt",
"prompt.mode.shell.exit": "esc aby wyjść",
"prompt.mode.shell.exit": "Naciśnij Esc, aby wyjść",
"session.child.promptDisabled": "Nie można wysyłać promptów w sesjach podagentów.",
"session.child.backToParent": "Wróć do głównej sesji.",
"prompt.example.1": "Napraw TODO w bazie kodu",
"prompt.example.2": "Jaki jest stos technologiczny tego projektu?",
"prompt.example.3": "Napraw zepsute testy",
"prompt.example.4": "Wyjaśnij jak działa uwierzytelnianie",
"prompt.example.4": "Wyjaśnij, jak działa uwierzytelnianie",
"prompt.example.5": "Znajdź i napraw luki w zabezpieczeniach",
"prompt.example.6": "Dodaj testy jednostkowe dla serwisu użytkownika",
"prompt.example.7": "Zrefaktoryzuj tę funkcję, aby była bardziej czytelna",
"prompt.example.8": "Co oznacza ten błąd?",
"prompt.example.9": "Pomóż mi zdebugować ten problem",
"prompt.example.9": "Pomóż mi zdiagnozować ten problem",
"prompt.example.10": "Wygeneruj dokumentację API",
"prompt.example.11": "Zoptymalizuj zapytania do bazy danych",
"prompt.example.12": "Dodaj walidację danych wejściowych",
"prompt.example.13": "Utwórz nowy komponent dla...",
"prompt.example.14": "Jak wdrożyć ten projekt?",
"prompt.example.15": "Sprawdź mój kod pod kątem najlepszych praktyk",
"prompt.example.16": "Dodaj obsługę błędów do tej funkcję",
"prompt.example.16": "Dodaj obsługę błędów do tej funkcji",
"prompt.example.17": "Wyjaśnij ten wzorzec regex",
"prompt.example.18": "Przekonwertuj to na TypeScript",
"prompt.example.19": "Dodaj logowanie w całej bazie kodu",
"prompt.example.20": "Które zależności są przestarzałe?",
"prompt.example.21": "Pomóż mi napisać skrypt migracyjny",
"prompt.example.22": "Zaimplementuj cachowanie dla tego punktu końcowego",
"prompt.example.22": "Zaimplementuj buforowanie dla tego punktu końcowego",
"prompt.example.23": "Dodaj stronicowanie do tej listy",
"prompt.example.24": "Utwórz polecenie CLI dla...",
"prompt.example.25": "Jak działają tutaj zmienne środowiskowe?",
"prompt.popover.emptyResults": "Brak pasujących wyników",
"prompt.popover.emptyCommands": "Brak pasujących poleceń",
"prompt.dropzone.label": "Upuść tutaj obrazy, pliki PDF lub pliki tekstowe",
"prompt.dropzone.file.label": "Upuść, aby @wspomnieć plik",
"prompt.dropzone.file.label": "Upuść, aby oznaczyć plik za pomocą @",
"prompt.slash.badge.custom": "własne",
"prompt.slash.badge.skill": "skill",
"prompt.slash.badge.skill": "umiejętność",
"prompt.slash.badge.mcp": "mcp",
"prompt.context.active": "aktywny",
"prompt.context.includeActiveFile": "Dołącz aktywny plik",
"prompt.context.removeActiveFile": "Usuń aktywny plik z kontekstu",
"prompt.context.removeFile": "Usuń plik z kontekstu",
"prompt.action.attachFile": "Załącz plik",
"prompt.action.attachFile": "Dodaj pliki",
"prompt.menu.addImagesAndFiles": "Dodaj pliki i inne elementy",
"prompt.menu.imagesAndFiles": "Obrazy i pliki",
"prompt.menu.commands": "Polecenia",
@@ -289,12 +394,12 @@ export const dict = {
"prompt.toast.promptSendFailed.title": "Nie udało się wysłać zapytania",
"prompt.toast.promptSendFailed.description": "Nie udało się pobrać sesji",
"dialog.mcp.title": "MCP",
"dialog.mcp.description": "{{enabled}} z {{total}} włączone",
"dialog.mcp.description": "Włączone: {{enabled}} z {{total}}",
"dialog.mcp.empty": "Brak skonfigurowanych MCP",
"dialog.lsp.empty": "LSP wykryte automatycznie na podstawie typów plików",
"dialog.plugins.empty": "Wtyczki skonfigurowane w opencode.json",
"dialog.lsp.empty": "Serwery LSP wykrywane automatycznie na podstawie typów plików",
"dialog.plugins.empty": "Wtyczki skonfigurowane w pliku opencode.json",
"mcp.status.connected": "połączono",
"mcp.status.failed": "niepowodzenie",
"mcp.status.failed": "błąd",
"mcp.status.needs_auth": "wymaga autoryzacji",
"mcp.auth.clickToAuthenticate": "Kliknij, aby się uwierzytelnić",
"mcp.status.disabled": "wyłączone",
@@ -304,14 +409,14 @@ export const dict = {
"dialog.directory.action.selectFile": "Wybierz plik",
"dialog.directory.action.selectFolder": "Wybierz folder",
"dialog.directory.root": "Katalog główny",
"dialog.directory.parent": "Nadrzędny",
"dialog.directory.parent": "Folder nadrzędny",
"dialog.directory.readError": "Nie można odczytać tego folderu",
"dialog.server.title": "Serwery",
"dialog.server.description": "Przełącz serwer OpenCode, z którym łączy się ta aplikacja.",
"dialog.server.search.placeholder": "Szukaj serwerów",
"dialog.server.empty": "Brak serwerów",
"dialog.server.add.title": "Dodaj serwer",
"dialog.server.add.url": "URL serwera",
"dialog.server.add.url": "Adres URL serwera",
"dialog.server.add.placeholder": "http://localhost:4096",
"dialog.server.add.error": "Nie można połączyć się z serwerem",
"dialog.server.add.checking": "Sprawdzanie...",
@@ -323,7 +428,7 @@ export const dict = {
"dialog.server.edit.title": "Edytuj serwer",
"dialog.server.default.title": "Domyślny serwer",
"dialog.server.default.description":
"Połącz z tym serwerem przy uruchomieniu aplikacji zamiast uruchamiać lokalny serwer. Wymaga restartu.",
"Łącz się z tym serwerem przy uruchamianiu aplikacji zamiast uruchamiać serwer lokalny. Wymaga ponownego uruchomienia.",
"dialog.server.default.none": "Nie wybrano serwera",
"dialog.server.default.set": "Ustaw bieżący serwer jako domyślny",
"dialog.server.default.clear": "Wyczyść",
@@ -332,7 +437,7 @@ export const dict = {
"dialog.server.menu.default": "Ustaw jako domyślny",
"dialog.server.menu.defaultRemove": "Usuń domyślny",
"dialog.server.menu.delete": "Usuń",
"dialog.server.current": "Obecny serwer",
"dialog.server.current": "Bieżący serwer",
"dialog.server.status.default": "Domyślny",
"wsl.server.add": "Dodaj serwer WSL",
"wsl.server.addShort": "Dodaj WSL",
@@ -373,7 +478,7 @@ export const dict = {
"wsl.onboarding.distroStatus.ready": "Gotowa",
"wsl.onboarding.distroStatus.checking": "Sprawdzanie...",
"wsl.onboarding.distroStatus.opencodeMissing": "OpenCode nie jest zainstalowany",
"wsl.onboarding.distroStatus.missingTools": "Brak bash i curl",
"wsl.onboarding.distroStatus.missingTools": "Brak narzędzi bash i curl",
"wsl.onboarding.distroStatus.unsupported": "Nieobsługiwana · Użyj WSL 2",
"wsl.onboarding.needAnotherDistro": "Potrzebujesz innej dystrybucji?",
"wsl.onboarding.needAnotherDistroHint": "Zainstaluj dystrybucję systemu Linux z katalogu WSL",
@@ -394,7 +499,7 @@ export const dict = {
"wsl.onboarding.installDistro": "Zainstaluj dystrybucję",
"wsl.onboarding.searchDistros": "Szukaj dystrybucji",
"wsl.onboarding.wsl2Required": "Wymagany jest WSL 2.",
"wsl.onboarding.toolsRequired": "Ta dystrybucja wymaga bash i curl.",
"wsl.onboarding.toolsRequired": "Ta dystrybucja wymaga narzędzi bash i curl.",
"wsl.onboarding.openTerminal": "Otwórz terminal",
"wsl.onboarding.path": "Ścieżka: {{path}}",
"wsl.onboarding.notFound": "nie znaleziono",
@@ -403,12 +508,27 @@ export const dict = {
"wsl.onboarding.desktopVersion": "aplikacja komputerowa {{version}}",
"wsl.onboarding.versionMismatch": "Zainstalowana wersja nie jest zgodna z wersją aplikacji komputerowej.",
"wsl.onboarding.adding": "Dodawanie...",
"help.tabs.toast.ariaLabel": "Przedstawiamy karty. Organizuj pracę i aktywne sesje za pomocą kart",
"help.tabs.toast.dismiss": "Odrzuć informacje o kartach",
"help.tabs.title": "Przedstawiamy karty",
"help.tabs.description": "Organizuj pracę i aktywne sesje za pomocą kart",
"help.tabs.date": "14 lipca",
"help.tabs.introduction": "OpenCode Desktop korzysta teraz z układu opartego na kartach.",
"help.tabs.sessions":
"Rozpocznij nową sesję na karcie lub otwórz istniejącą sesję z dowolnego projektu. Otwórz nową kartę, gdy zaczynasz coś nowego, i zamknij ją po zakończeniu.",
"help.tabs.organize":
"Kilka otwartych kart ułatwia organizowanie aktywnych sesji. Jeśli chcesz zachować karty na dłużej, nadaj im łatwe do zapamiętania nazwy.",
"help.tabs.home":
"Wszystkie sesje i projekty znajdziesz na nowym ekranie głównym. Wybranie sesji powoduje otwarcie jej na karcie.",
"help.tabs.persistence": "Po ponownym otwarciu aplikacji karty pozostają otwarte.",
"help.tabs.worktrees":
"Nowy układ nie obsługuje jeszcze drzew roboczych Git, ale ta funkcja pojawi się wkrótce. Jeśli wolisz nadal korzystać z poprzedniego układu, możesz przełączać układy w Ustawieniach. Pamiętaj jednak, że za kilka tygodni nowy układ stanie się jedynym dostępnym.",
"dialog.project.edit.title": "Edytuj projekt",
"dialog.project.edit.name": "Nazwa",
"dialog.project.edit.icon": "Ikona",
"dialog.project.edit.icon.alt": "Ikona projektu",
"dialog.project.edit.icon.hint": "Kliknij lub przeciągnij obraz",
"dialog.project.edit.icon.recommended": "Zalecane: 128x128px",
"dialog.project.edit.icon.hint": "Kliknij, aby wybrać obraz, lub przeciągnij go tutaj",
"dialog.project.edit.icon.recommended": "Zalecane: 128 × 128 px",
"dialog.project.edit.color": "Kolor",
"dialog.project.edit.color.select": "Wybierz kolor {{color}}",
"dialog.project.edit.worktree.startup": "Skrypt uruchamiania przestrzeni roboczej",
@@ -468,9 +588,9 @@ export const dict = {
"toast.theme.title": "Przełączono motyw",
"toast.scheme.title": "Schemat kolorów",
"toast.workspace.enabled.title": "Przestrzenie robocze włączone",
"toast.workspace.enabled.description": "Kilka worktree jest teraz wyświetlanych na pasku bocznym",
"toast.workspace.enabled.description": "Kilka drzew roboczych jest teraz wyświetlanych na pasku bocznym",
"toast.workspace.disabled.title": "Przestrzenie robocze wyłączone",
"toast.workspace.disabled.description": "Tylko główny worktree jest wyświetlany na pasku bocznym",
"toast.workspace.disabled.description": "Tylko główne drzewo robocze jest wyświetlane na pasku bocznym",
"toast.permissions.autoaccept.on.title": "Automatyczne akceptowanie uprawnień",
"toast.permissions.autoaccept.on.description": "Żądania uprawnień będą automatycznie zatwierdzane",
"toast.permissions.autoaccept.off.title": "Zatrzymano automatyczne akceptowanie uprawnień",
@@ -481,9 +601,9 @@ export const dict = {
"toast.file.listFailed.title": "Nie udało się wyświetlić listy plików",
"toast.context.noLineSelection.title": "Brak zaznaczenia linii",
"toast.context.noLineSelection.description": "Najpierw wybierz zakres linii w zakładce pliku.",
"toast.session.share.copyFailed.title": "Nie udało się skopiować URL do schowka",
"toast.session.share.copyFailed.title": "Nie udało się skopiować adresu URL do schowka",
"toast.session.share.success.title": "Sesja udostępniona",
"toast.session.share.success.description": "Link udostępniania skopiowany do schowka!",
"toast.session.share.success.description": "Adres URL udostępnionej sesji skopiowano do schowka!",
"toast.session.share.failed.title": "Nie udało się udostępnić sesji",
"toast.session.share.failed.description": "Wystąpił błąd podczas udostępniania sesji",
"toast.session.unshare.success.title": "Zatrzymano udostępnianie sesji",
@@ -493,13 +613,13 @@ export const dict = {
"toast.session.listFailed.title": "Nie udało się załadować sesji dla {{project}}",
"toast.update.title": "Dostępna aktualizacja",
"toast.update.description": "Nowa wersja OpenCode ({{version}}) jest teraz dostępna do instalacji.",
"toast.update.action.installRestart": "Zainstaluj i zrestartuj",
"toast.update.action.installRestart": "Zainstaluj i uruchom ponownie",
"toast.update.action.notYet": "Jeszcze nie",
"error.page.title": "Coś poszło nie tak",
"error.page.description": "Wystąpił błąd podczas ładowania aplikacji.",
"error.page.description.localServerStartup": "Wystąpił błąd podczas uruchamiania serwera lokalnego.",
"error.page.details.label": "Szczegóły błędu",
"error.page.action.restart": "Restartuj",
"error.page.action.restart": "Uruchom ponownie",
"error.page.action.report": "Zgłoś błąd",
"error.page.action.reported": "Błąd zgłoszony",
"error.page.action.exportLogs": "Eksportuj dzienniki",
@@ -512,7 +632,7 @@ export const dict = {
"error.dev.rootNotFound":
"Nie znaleziono elementu głównego. Czy zapomniałeś dodać go do swojego index.html? A może atrybut id został błędnie wpisany?",
"error.serverSync.connectFailed": "Nie można połączyć się z serwerem. Czy serwer działa pod adresem `{{url}}`?",
"directory.error.invalidUrl": "Nieprawidłowy katalog w URL.",
"directory.error.invalidUrl": "Nieprawidłowy katalog w adresie URL.",
"error.chain.unknown": "Nieznany błąd",
"error.chain.causedBy": "Spowodowany przez:",
"error.chain.apiError": "Błąd API",
@@ -521,7 +641,7 @@ export const dict = {
"error.chain.responseBody": "Treść odpowiedzi:\n{{body}}",
"error.chain.didYouMean": "Czy miałeś na myśli: {{suggestions}}",
"error.chain.modelNotFound": "Model nie znaleziony: {{provider}}/{{model}}",
"error.chain.checkConfig": "Sprawdź swoją konfigurację (opencode.json) nazwy dostawców/modeli",
"error.chain.checkConfig": "Sprawdź nazwy dostawców i modeli w konfiguracji (opencode.json)",
"error.chain.mcpFailed":
"Serwer MCP „{{name}}” nie uruchomił się. Uwaga: OpenCode nie obsługuje jeszcze uwierzytelniania MCP.",
"error.chain.providerAuthFailed": "Uwierzytelnianie dostawcy nie powiodło się ({{provider}}): {{message}}",
@@ -576,7 +696,7 @@ export const dict = {
"session.review.change.other": "Zmiany",
"session.review.loadingChanges": "Ładowanie zmian...",
"session.review.empty": "Brak zmian w tej sesji",
"session.review.noVcs": "Nie wykryto systemu kontroli wersji Git, zmiany nie są wyświetlane",
"session.review.noVcs": "Nie wykryto systemu kontroli wersji Git, dlatego zmiany nie są wyświetlane",
"session.review.noSnapshot": "Śledzenie migawek jest wyłączone w konfiguracji, więc zmiany w sesji są niedostępne",
"session.review.noChanges": "Brak zmian",
"session.review.noUncommittedChanges": "Brak jeszcze niezatwierdzonych zmian",
@@ -597,14 +717,20 @@ export const dict = {
"session.question.minimize": "Zminimalizuj pytanie",
"session.question.restore": "Przywróć pytanie",
"session.question.pending.one": "{{count}} oczekujące pytanie",
"session.question.pending.few": "{{count}} oczekujące pytania",
"session.question.pending.many": "{{count}} oczekujących pytań",
"session.question.pending.other": "Pytania oczekujące: {{count}}",
"session.followupDock.summary.one": "{{count}} wiadomość w kolejce",
"session.followupDock.summary.few": "{{count}} wiadomości w kolejce",
"session.followupDock.summary.many": "{{count}} wiadomości w kolejce",
"session.followupDock.summary.other": "{{count}} wiadomości w kolejce",
"session.followupDock.sendNow": "Wyślij teraz",
"session.followupDock.edit": "Edytuj",
"session.followupDock.collapse": "Zwiń wiadomości w kolejce",
"session.followupDock.expand": "Rozwiń wiadomości w kolejce",
"session.revertDock.summary.one": "{{count}} cofnięta wiadomość",
"session.revertDock.summary.few": "{{count}} cofnięte wiadomości",
"session.revertDock.summary.many": "{{count}} cofniętych wiadomości",
"session.revertDock.summary.other": "{{count}} cofnięte wiadomości",
"session.revertDock.collapse": "Zwiń cofnięte wiadomości",
"session.revertDock.expand": "Rozwiń cofnięte wiadomości",
@@ -646,7 +772,7 @@ export const dict = {
"session.share.action.publishing": "Publikowanie...",
"session.share.action.unpublish": "Cofnij publikację",
"session.share.action.unpublishing": "Cofanie publikacji...",
"session.share.action.view": "Widok",
"session.share.action.view": "Wyświetl",
"session.share.copy.copied": "Skopiowano",
"session.share.copy.copyLink": "Kopiuj link",
"lsp.tooltip.none": "Brak serwerów LSP",
@@ -658,7 +784,13 @@ export const dict = {
"terminal.close": "Zamknij terminal",
"terminal.connectionLost.title": "Utracono połączenie",
"terminal.connectionLost.description":
"Połączenie z terminalem zostało przerwane. Może się to zdarzyć przy restarcie serwera.",
"Połączenie z terminalem zostało przerwane. Może się to zdarzyć podczas ponownego uruchamiania serwera.",
"terminal.connectTicket.csrfError":
"Bilet połączenia PTY został odrzucony podczas kontroli źródła lub CSRF. Sprawdź konfigurację CORS serwera.",
"terminal.connectTicket.statusError": "Bilet połączenia PTY zakończył się niepowodzeniem ze statusem {{status}}",
"titlebar.update": "Aktualizuj",
"titlebar.updateVersion": "Aktualizuj {{version}}",
"common.closeTab": "Zamknij kartę",
"common.dismiss": "Odrzuć",
"common.requestFailed": "Żądanie nie powiodło się",
@@ -687,7 +819,7 @@ export const dict = {
"sidebar.empty.title": "Brak otwartych projektów",
"sidebar.empty.description": "Otwórz projekt, aby rozpocząć",
"app.name.desktop": "OpenCode Desktop",
"settings.section.desktop": "Pulpit",
"settings.section.desktop": "Aplikacja komputerowa",
"settings.section.server": "Serwer",
"settings.tab.general": "Ogólne",
"settings.tab.shortcuts": "Skróty",
@@ -739,8 +871,9 @@ export const dict = {
"settings.general.row.mobileTitlebarBottom.title": "Dolna nawigacja",
"settings.general.row.mobileTitlebarBottom.description":
"Umieść pasek tytułu i karty sesji u dołu ekranu na urządzeniach mobilnych",
"settings.general.row.showCustomAgents.title": "Agenci niestandardowi",
"settings.general.row.showCustomAgents.description": "Pokaż wybór agenta w edytorze wiadomości",
"settings.general.row.showCustomAgents.title": "Wybór agenta",
"settings.general.row.showCustomAgents.description":
"Umożliwiaj przełączanie agentów w edytorze wiadomości. Po ukryciu domyślnie używany jest agent Build.",
"settings.general.row.reasoningSummaries.title": "Pokaż podsumowania wnioskowania",
"settings.general.row.reasoningSummaries.description": "Wyświetlaj podsumowania wnioskowania modelu na osi czasu",
"settings.general.row.shellToolPartsExpanded.title": "Rozwijaj elementy narzędzia shell",
@@ -758,13 +891,14 @@ export const dict = {
"settings.general.row.newInterfaceNotice.dismiss": "Odrzuć",
"settings.general.row.pinchZoom.title": "Powiększanie gestem szczypania",
"settings.general.row.pinchZoom.description":
"Zezwalaj na powiększanie gestem szczypania na gładziku i przewijaniem z klawiszem Ctrl",
"settings.general.row.wayland.title": "Użyj natywnego Wayland",
"settings.general.row.wayland.description": "Wyłącz fallback X11 na Wayland. Wymaga restartu.",
"Zezwalaj na powiększanie gestem szczypania na gładziku lub przez przewijanie z wciśniętym klawiszem Ctrl",
"settings.general.row.wayland.title": "Użyj natywnego protokołu Wayland",
"settings.general.row.wayland.description":
"Wyłącz awaryjne korzystanie z X11 w środowisku Wayland. Wymaga ponownego uruchomienia.",
"settings.general.row.wayland.tooltip":
"Na Linuxie z monitorami o różnym odświeżaniu, natywny Wayland może być bardziej stabilny.",
"W systemie Linux z monitorami o różnej częstotliwości odświeżania natywny protokół Wayland może być stabilniejszy.",
"settings.general.row.releaseNotes.title": "Informacje o wydaniu",
"settings.general.row.releaseNotes.description": 'Pokazuj wyskakujące okna "Co nowego" po aktualizacjach',
"settings.general.row.releaseNotes.description": "Pokazuj wyskakujące okna Co nowego po aktualizacjach",
"settings.updates.row.startup.title": "Sprawdzaj aktualizacje przy uruchomieniu",
"settings.updates.row.startup.description": "Automatycznie sprawdzaj aktualizacje podczas uruchamiania OpenCode",
"settings.updates.row.check.title": "Sprawdź aktualizacje",
@@ -878,7 +1012,8 @@ export const dict = {
"settings.permissions.tool.read.title": "Odczyt",
"settings.permissions.tool.read.description": "Odczyt pliku (pasuje do ścieżki pliku)",
"settings.permissions.tool.edit.title": "Edycja",
"settings.permissions.tool.edit.description": "Modyfikacja plików, w tym edycje, zapisy, łatki i multi-edycje",
"settings.permissions.tool.edit.description":
"Modyfikowanie plików, w tym edytowanie, zapisywanie, stosowanie łatek i edytowanie wielu plików",
"settings.permissions.tool.glob.title": "Glob",
"settings.permissions.tool.glob.description": "Dopasowywanie plików za pomocą wzorców glob",
"settings.permissions.tool.grep.title": "Grep",
@@ -888,7 +1023,7 @@ export const dict = {
"settings.permissions.tool.bash.title": "Bash",
"settings.permissions.tool.bash.description": "Uruchamianie poleceń powłoki",
"settings.permissions.tool.task.title": "Zadanie",
"settings.permissions.tool.task.description": "Uruchamianie pod-agentów",
"settings.permissions.tool.task.description": "Uruchamianie podagentów",
"settings.permissions.tool.skill.title": "Umiejętność",
"settings.permissions.tool.skill.description": "Ładowanie umiejętności według nazwy",
"settings.permissions.tool.lsp.title": "LSP",
@@ -919,7 +1054,7 @@ export const dict = {
"workspace.reset.success.description": "Przestrzeń robocza odpowiada teraz domyślnej gałęzi.",
"workspace.error.stillPreparing": "Przestrzeń robocza jest wciąż przygotowywana",
"workspace.status.checking": "Sprawdzanie niezscalonych zmian...",
"workspace.status.error": "Nie można zweryfikować statusu git.",
"workspace.status.error": "Nie można zweryfikować statusu Git.",
"workspace.status.clean": "Nie wykryto niezscalonych zmian.",
"workspace.status.dirty": "Wykryto niezscalone zmiany w tej przestrzeni roboczej.",
"workspace.delete.title": "Usuń przestrzeń roboczą",
@@ -945,7 +1080,7 @@ export const dict = {
"common.time.hoursAgo.short": "{{count}} godz. temu",
"common.time.daysAgo.short": "{{count}} dni temu",
"settings.providers.connected.environmentDescription": "Połączono ze zmiennymi środowiskowymi",
"settings.providers.custom.description": "Dodaj dostawcę zgodnego z OpenAI poprzez podstawowy URL.",
"settings.providers.custom.description": "Dodaj dostawcę zgodnego z OpenAI za pomocą bazowego adresu URL.",
"app.server.unreachable": "Nie można połączyć z {{server}}",
"app.server.retrying": "Ponawianie automatycznie...",
@@ -961,6 +1096,9 @@ export const dict = {
"session.question.progress": "{{current}} z {{total}} pytań",
"session.header.open.finder": "Finder",
"session.header.open.fileExplorer": "Eksplorator plików",
"session.header.reveal.finder": "Pokaż w Finderze",
"session.header.reveal.fileExplorer": "Pokaż w Eksploratorze plików",
"session.header.reveal.containingFolder": "Otwórz folder zawierający",
"session.header.open.fileManager": "Menedżer plików",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -975,17 +1113,17 @@ export const dict = {
"session.header.open.app.androidStudio": "Android Studio",
"session.header.open.app.powershell": "PowerShell",
"session.header.open.app.sublimeText": "Sublime Text",
"debugBar.ariaLabel": "Diagnostyka wydajności deweloperskiej",
"debugBar.ariaLabel": "Diagnostyka wydajności w środowisku deweloperskim",
"debugBar.na": "n.d.",
"debugBar.nav.label": "NAV",
"debugBar.nav.tip":
"Ostatnie zakończone przejście trasy dotykające strony sesji, mierzone od startu routera do pierwszego odrysowania po ustaleniu.",
"Ostatnie zakończone przejście między trasami obejmujące stronę sesji, mierzone od uruchomienia routera do pierwszego odrysowania po ustabilizowaniu widoku.",
"debugBar.fps.label": "FPS",
"debugBar.fps.tip": "Średnia liczba klatek na sekundę w ciągu ostatnich 5 sekund.",
"debugBar.frame.label": "FRAME",
"debugBar.frame.tip": "Najgorszy czas klatki w ciągu ostatnich 5 sekund.",
"debugBar.jank.label": "JANK",
"debugBar.jank.tip": "Klatki powyżej 32ms w ciągu ostatnich 5 sekund.",
"debugBar.jank.tip": "Klatki powyżej 32 ms w ciągu ostatnich 5 sekund.",
"debugBar.long.label": "LONG",
"debugBar.long.tip":
"Zablokowany czas i liczba długich zadań w ciągu ostatnich 5 sekund. Maksymalne zadanie: {{max}}.",
@@ -995,10 +1133,18 @@ export const dict = {
"debugBar.inp.tip":
"Przybliżony czas trwania interakcji w ciągu ostatnich 5 sekund. Jest to podobne do INP, a nie oficjalne Web Vitals INP.",
"debugBar.cls.label": "CLS",
"debugBar.cls.tip": "Skumulowane przesunięcie układu dla bieżącego czasu życia aplikacji.",
"debugBar.cls.tip": "Skumulowane przesunięcie układu od bieżącego uruchomienia aplikacji.",
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Użyta sterta JS vs limit sterty. Tylko Chromium.",
"debugBar.mem.tip": "Użyta sterta JS vs limit sterty. {{used}} z {{limit}}.",
"debugBar.mem.tipUnavailable": "Wykorzystana pamięć sterty JS względem jej limitu. Tylko Chromium.",
"debugBar.mem.tip": "Wykorzystana pamięć sterty JS względem jej limitu: {{used}} z {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Wymuś style fokusu dla wszystkich elementów interaktywnych",
"debugBar.focus.on": "WŁ.",
"debugBar.focus.off": "WYŁ.",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Wymuś kierunek układu całej aplikacji bez zmiany wybranego języka",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
+226 -81
View File
@@ -1,4 +1,103 @@
export const dict = {
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Файл",
"desktop.menu.edit": "Правка",
"desktop.menu.view": "Вид",
"desktop.menu.go": "Переход",
"desktop.menu.window": "Окно",
"desktop.menu.help": "Справка",
"desktop.menu.checkForUpdates": "Проверить наличие обновлений...",
"desktop.menu.settings": "Настройки",
"desktop.menu.reloadWebview": "Перезагрузить веб-представление",
"desktop.menu.restart": "Перезапустить",
"desktop.menu.exportLogs": "Экспортировать журналы...",
"desktop.menu.newSession": "Новая сессия",
"desktop.menu.openProject": "Открыть проект...",
"desktop.menu.newWindow": "Новое окно",
"desktop.menu.closeWindow": "Закрыть окно",
"desktop.menu.undo": "Отменить",
"desktop.menu.redo": "Повторить",
"desktop.menu.cut": "Вырезать",
"desktop.menu.copy": "Копировать",
"desktop.menu.paste": "Вставить",
"desktop.menu.delete": "Удалить",
"desktop.menu.selectAll": "Выбрать всё",
"desktop.menu.toggleSidebar": "Переключить боковую панель",
"desktop.menu.toggleTerminal": "Переключить терминал",
"desktop.menu.toggleFileTree": "Переключить дерево файлов",
"desktop.menu.reload": "Перезагрузить",
"desktop.menu.toggleDeveloperTools": "Переключить инструменты разработчика",
"desktop.menu.actualSize": "Фактический размер",
"desktop.menu.zoomIn": "Увеличить",
"desktop.menu.zoomOut": "Уменьшить",
"desktop.menu.toggleFullScreen": "Переключить полноэкранный режим",
"desktop.menu.back": "Назад",
"desktop.menu.forward": "Вперёд",
"desktop.menu.previousSession": "Предыдущая сессия",
"desktop.menu.nextSession": "Следующая сессия",
"desktop.menu.previousProject": "Предыдущий проект",
"desktop.menu.nextProject": "Следующий проект",
"desktop.menu.minimize": "Свернуть",
"desktop.menu.maximize": "Развернуть",
"desktop.menu.documentation": "Документация OpenCode",
"desktop.menu.supportForum": "Форум поддержки",
"desktop.menu.shareFeedback": "Отправить отзыв",
"desktop.menu.reportBug": "Сообщить об ошибке",
"desktop.menu.ariaLabel": "Меню OpenCode",
"desktop.updater.dialog.checkFailed.message": "Не удалось проверить наличие обновлений.",
"desktop.updater.dialog.checkFailed.title": "Ошибка обновления",
"desktop.updater.dialog.upToDate.message": "У вас установлена последняя версия.",
"desktop.updater.dialog.upToDate.title": "Обновлений нет",
"desktop.updater.dialog.ready.message": "Обновление {{version}} загружено. Перезапустить сейчас?",
"desktop.updater.dialog.ready.title": "Обновление готово",
"desktop.updater.dialog.restart": "Перезапустить",
"desktop.updater.dialog.later": "Позже",
"desktop.recovery.action.relaunch": "Запустить снова",
"desktop.recovery.action.exportLogs": "Экспортировать журналы",
"desktop.recovery.action.keepWaiting": "Продолжить ожидание",
"desktop.recovery.action.quit": "Выйти",
"desktop.recovery.loadFailed": "Не удалось загрузить OpenCode",
"desktop.recovery.terminated": "Окно OpenCode неожиданно завершило работу",
"desktop.recovery.unresponsive": "OpenCode не отвечает",
"desktop.recovery.unresponsive.detail": "Можно снова запустить приложение, открыть журналы или продолжить ожидание.",
"desktop.recovery.loadFailed.detail": "Окно: {{window}}\nURL: {{url}}\nОшибка: {{code}} {{description}}",
"desktop.recovery.terminated.detail": "Окно: {{window}}\nПричина: {{reason}}\nКод: {{code}}",
"desktop.recovery.unknown": "<неизвестно>",
"desktop.dialog.chooseFolder": "Выберите папку",
"desktop.dialog.chooseFile": "Выберите файл",
"desktop.dialog.saveFile": "Сохранить файл",
"desktop.dialog.files": "Файлы",
"desktop.server.local": "Локальный сервер",
"desktop.wsl.error.windowsOnly": "WSL доступна только в Windows",
"desktop.wsl.error.unavailable": "WSL недоступна",
"desktop.wsl.error.listInstalled": "Не удалось получить список установленных дистрибутивов WSL",
"desktop.wsl.error.listOnline": "Не удалось получить список доступных дистрибутивов WSL",
"desktop.wsl.error.executeDistro": "Не удаётся выполнять команды в дистрибутиве",
"desktop.wsl.error.installWsl": "Не удалось установить WSL",
"desktop.wsl.error.installDistro": "Не удалось установить дистрибутив: {{distro}}",
"desktop.wsl.error.installOpencode": "Не удалось установить OpenCode",
"desktop.wsl.error.alreadyAdded": "Дистрибутив {{distro}} уже добавлен",
"desktop.wsl.error.opencodeMissing": "opencode не установлен в этом дистрибутиве",
"desktop.wsl.error.opencodeCannotRun": "opencode установлен, но его не удалось запустить",
"desktop.wsl.error.opencodeNotInstalled": "OpenCode не установлен в {{distro}}",
"desktop.wsl.error.updateVersion":
"Обновление OpenCode завершено, но {{distro}} по-прежнему сообщает версию {{installed}}; ожидалась {{expected}}",
"desktop.wsl.error.noVersion": "нет версии",
"desktop.wsl.error.serverExited": "Сервер WSL завершил работу после запуска (код={{code}}, сигнал={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"Сервер WSL завершил работу до перехода в рабочее состояние (код={{code}}, сигнал={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout":
"Истекло время ожидания проверки работоспособности Sidecar для {{distro}} ({{timeout}} мс)",
"desktop.wsl.error.commandTimeout": "Истекло время ожидания выполнения {{command}} {{args}} ({{timeout}} мс)",
"desktop.wsl.error.failedPort": "Не удалось получить порт",
"desktop.picker.error.notSelected": "В средстве выбора не выбран файл",
"desktop.picker.error.sizeLimit": "Размер выбранных вложений превышает лимит {{limit}} МБ",
"command.category.suggested": "Предложено",
"command.category.view": "Просмотр",
"command.category.project": "Проект",
@@ -16,6 +115,7 @@ export const dict = {
"command.category.permissions": "Разрешения",
"command.category.workspace": "Рабочее пространство",
"command.category.settings": "Настройки",
"command.logs.export": "Экспортировать журналы",
"theme.scheme.system": "Системная",
"theme.scheme.light": "Светлая",
@@ -37,12 +137,12 @@ export const dict = {
"command.palette": "Палитра команд",
"command.theme.cycle": "Цикл тем",
"command.theme.cycle": "Переключить тему",
"command.theme.set": "Использовать тему: {{theme}}",
"command.theme.scheme.cycle": "Цикл цветовой схемы",
"command.theme.scheme.cycle": "Переключить цветовую схему",
"command.theme.scheme.set": "Использовать цветовую схему: {{scheme}}",
"command.language.cycle": "Цикл языков",
"command.language.cycle": "Переключить язык",
"command.language.set": "Использовать язык: {{language}}",
"command.session.new": "Новая сессия",
@@ -51,7 +151,7 @@ export const dict = {
"command.tab.reopenClosed": "Повторно открыть закрытую вкладку",
"command.context.addSelection": "Добавить выделение в контекст",
"command.context.addSelection.description": "Добавить выбранные строки из текущего файла",
"command.input.focus": "Фокус на поле ввода",
"command.input.focus": "Перейти к полю ввода",
"command.terminal.toggle": "Переключить терминал",
"command.fileTree.toggle": "Переключить дерево файлов",
"command.review.toggle": "Переключить обзор",
@@ -67,11 +167,11 @@ export const dict = {
"command.model.choose.description": "Выбрать другую модель",
"command.mcp.toggle": "Переключить MCP",
"command.mcp.toggle.description": "Переключить MCP",
"command.agent.cycle": "Цикл агентов",
"command.agent.cycle": "Следующий агент",
"command.agent.cycle.description": "Переключиться к следующему агенту",
"command.agent.cycle.reverse": "Цикл агентов назад",
"command.agent.cycle.reverse": "Предыдущий агент",
"command.agent.cycle.reverse.description": "Переключиться к предыдущему агенту",
"command.model.variant.cycle": "Цикл режимов мышления",
"command.model.variant.cycle": "Переключить уровень усилий",
"command.model.variant.cycle.description": "Переключиться к следующему уровню усилий",
"command.prompt.mode.shell": "Оболочка",
"command.prompt.mode.normal": "Промпт",
@@ -102,9 +202,10 @@ export const dict = {
"dialog.provider.empty": "Провайдеры не найдены",
"dialog.provider.group.popular": "Популярные",
"dialog.provider.group.other": "Другие",
"dialog.provider.custom.label": "Пользовательский провайдер, совместимый с OpenAI",
"dialog.provider.tag.recommended": "Рекомендуемые",
"dialog.provider.opencode.note": "Отобранные модели, включая Claude, GPT, Gemini и другие",
"dialog.provider.opencode.tagline": "Надежные оптимизированные модели",
"dialog.provider.opencode.tagline": "Надёжные оптимизированные модели",
"dialog.provider.opencodeGo.tagline": "Доступная подписка для всех",
"dialog.provider.anthropic.note": "Прямой доступ к моделям Claude, включая Pro и Max",
"dialog.provider.copilot.note": "ИИ-модели для помощи в кодировании через GitHub Copilot",
@@ -117,33 +218,36 @@ export const dict = {
"dialog.model.search.placeholder": "Поиск моделей",
"dialog.model.empty": "Модели не найдены",
"dialog.model.manage": "Управление моделями",
"dialog.model.manage.description": "Настройте какие модели появляются в выборе модели",
"dialog.model.manage.description": "Настройте, какие модели отображаются при выборе модели",
"dialog.model.manage.provider.toggle": "Переключить все модели {{provider}}",
"dialog.model.unpaid.freeModels.title": "Бесплатные модели от OpenCode",
"dialog.model.unpaid.addMore.title": "Добавьте больше моделей от популярных провайдеров",
"dialog.model.unpaid.viewMoreProviders": "Посмотреть ещё более 70 провайдеров",
"dialog.provider.viewAll": "Показать больше провайдеров",
"provider.connect.title": "Подключить {{provider}}",
"provider.connect.title.anthropicProMax": "Войти с помощью Claude Pro/Max",
"provider.connect.selectMethod": "Выберите способ входа для {{provider}}.",
"provider.connect.method.apiKey": "API ключ",
"provider.connect.method.apiKey": "Ключ API",
"provider.connect.method.browser": "Браузер",
"provider.connect.method.headless": "Без браузера",
"provider.connect.status.inProgress": "Авторизация...",
"provider.connect.status.waiting": "Ожидание авторизации...",
"provider.connect.status.failed": "Ошибка авторизации: {{error}}",
"provider.connect.apiKey.description":
"Введите ваш API ключ {{provider}} для подключения аккаунта и использования моделей {{provider}} в OpenCode.",
"provider.connect.apiKey.label": "{{provider}} API ключ",
"provider.connect.apiKey.placeholder": "API ключ",
"provider.connect.apiKey.required": "API ключ обязателен",
"Введите ключ API {{provider}}, чтобы подключить аккаунт и использовать модели {{provider}} в OpenCode.",
"provider.connect.apiKey.label": "Ключ API {{provider}}",
"provider.connect.apiKey.placeholder": "Ключ API",
"provider.connect.apiKey.required": "Требуется ключ API",
"provider.connect.opencodeZen.line1":
"OpenCode Zen даёт вам доступ к отобранным надёжным оптимизированным моделям для агентов программирования.",
"provider.connect.opencodeZen.line2":
"С одним API ключом вы получите доступ к таким моделям как Claude, GPT, Gemini, GLM и другим.",
"С одним ключом API вы получите доступ к таким моделям, как Claude, GPT, Gemini, GLM и другие.",
"provider.connect.opencodeZen.visit.prefix": "Посетите ",
"provider.connect.opencodeZen.visit.link": "opencode.ai/zen",
"provider.connect.opencodeZen.visit.suffix": " чтобы получить ваш API ключ.",
"provider.connect.opencodeZen.visit.suffix": ", чтобы получить ключ API.",
"provider.connect.oauth.code.visit.prefix": "Посетите ",
"provider.connect.oauth.code.visit.link": "эту ссылку",
"provider.connect.oauth.code.visit.suffix":
@@ -161,18 +265,19 @@ export const dict = {
"provider.connect.toast.connected.description": "Модели {{provider}} теперь доступны.",
"provider.custom.title": "Пользовательский провайдер",
"provider.custom.description.prefix": "Настройте OpenAI-совместимого провайдера. См. ",
"provider.custom.unavailable": "Пользовательские провайдеры недоступны на этом сервере",
"provider.custom.description.prefix": "Настройте провайдера, совместимого с OpenAI. См. ",
"provider.custom.description.link": "документацию по настройке провайдера",
"provider.custom.description.suffix": ".",
"provider.custom.field.providerID.label": "ID провайдера",
"provider.custom.field.providerID.placeholder": "myprovider",
"provider.custom.field.providerID.description": "Строчные буквы, цифры, дефисы или подчёркивания",
"provider.custom.field.name.label": "Отображаемое имя",
"provider.custom.field.name.placeholder": "Мой AI провайдер",
"provider.custom.field.name.placeholder": "Мой ИИ-провайдер",
"provider.custom.field.baseURL.label": "Базовый URL",
"provider.custom.field.baseURL.placeholder": "https://api.myprovider.com/v1",
"provider.custom.field.apiKey.label": "API ключ",
"provider.custom.field.apiKey.placeholder": "API ключ",
"provider.custom.field.apiKey.label": "Ключ API",
"provider.custom.field.apiKey.placeholder": "Ключ API",
"provider.custom.field.apiKey.description":
"Необязательно. Оставьте пустым, если управляете авторизацией через заголовки.",
"provider.custom.models.label": "Модели",
@@ -211,15 +316,15 @@ export const dict = {
"model.input.image": "изображение",
"model.input.audio": "аудио",
"model.input.video": "видео",
"model.input.pdf": "pdf",
"model.tooltip.allows": "Разрешено: {{inputs}}",
"model.input.pdf": "PDF",
"model.tooltip.allows": "Поддерживает: {{inputs}}",
"model.tooltip.context.label": "Контекст",
"model.tooltip.inputs": "Входные данные",
"model.tooltip.model": "Модель",
"model.tooltip.provider": "Провайдер",
"model.tooltip.reasoning": "Рассуждение",
"model.tooltip.reasoning.allowed": "Разрешает рассуждение",
"model.tooltip.reasoning.none": "Без рассуждения",
"model.tooltip.reasoning.allowed": "Поддерживает рассуждения",
"model.tooltip.reasoning.none": "Без рассуждений",
"model.tooltip.context": "Лимит контекста {{limit}}",
"common.search.placeholder": "Поиск",
@@ -231,7 +336,7 @@ export const dict = {
"common.clear": "Очистить",
"common.connect": "Подключить",
"common.disconnect": "Отключить",
"common.continue": "Отправить",
"common.continue": "Продолжить",
"common.submit": "Отправить",
"common.save": "Сохранить",
"common.saving": "Сохранение...",
@@ -241,8 +346,8 @@ export const dict = {
"prompt.placeholder.shell": "Введите команду оболочки... {{example}}",
"prompt.placeholder.normal": 'Спросите что угодно... "{{example}}"',
"prompt.placeholder.simple": "Спросите что угодно...",
"prompt.placeholder.summarizeComments": "Суммировать комментарии…",
"prompt.placeholder.summarizeComment": "Суммировать комментарий…",
"prompt.placeholder.summarizeComments": "Обобщить комментарии…",
"prompt.placeholder.summarizeComment": "Обобщить комментарий…",
"prompt.mode.shell": "Оболочка",
"prompt.mode.normal": "Промпт",
"prompt.mode.shell.exit": "esc для выхода",
@@ -252,33 +357,33 @@ export const dict = {
"prompt.example.1": "Исправить TODO в коде",
"prompt.example.2": "Какой технологический стек этого проекта?",
"prompt.example.3": "Исправить сломанные тесты",
"prompt.example.4": "Объясни как работает аутентификация",
"prompt.example.4": "Объясни, как работает аутентификация",
"prompt.example.5": "Найти и исправить уязвимости безопасности",
"prompt.example.6": "Добавить юнит-тесты для сервиса пользователя",
"prompt.example.6": "Добавить модульные тесты для службы пользователей",
"prompt.example.7": "Рефакторить эту функцию для лучшей читаемости",
"prompt.example.8": "Что означает эта ошибка?",
"prompt.example.9": "Помоги мне отладить эту проблему",
"prompt.example.10": "Сгенерировать документацию API",
"prompt.example.11": "Оптимизировать запросы к базе данных",
"prompt.example.12": "Добавить валидацию ввода",
"prompt.example.12": "Добавить проверку входных данных",
"prompt.example.13": "Создать новый компонент для...",
"prompt.example.14": "Как развернуть этот проект?",
"prompt.example.15": "Проверь мой код на лучшие практики",
"prompt.example.15": "Проверь, соответствует ли мой код рекомендациям",
"prompt.example.16": "Добавить обработку ошибок в эту функцию",
"prompt.example.17": "Объясни этот паттерн regex",
"prompt.example.18": "Конвертировать это в TypeScript",
"prompt.example.17": "Объясни это регулярное выражение",
"prompt.example.18": "Преобразовать это в TypeScript",
"prompt.example.19": "Добавить логирование по всему проекту",
"prompt.example.20": "Какие зависимости устарели?",
"prompt.example.21": "Помоги написать скрипт миграции",
"prompt.example.22": "Реализовать кэширование для этой конечной точки",
"prompt.example.22": "Реализовать кеширование для этой конечной точки",
"prompt.example.23": "Добавить пагинацию в этот список",
"prompt.example.24": "Создать CLI команду для...",
"prompt.example.25": "Как работают переменные окружения здесь?",
"prompt.example.24": "Создать CLI-команду для...",
"prompt.example.25": "Как здесь работают переменные окружения?",
"prompt.popover.emptyResults": "Нет совпадений",
"prompt.popover.emptyCommands": "Нет совпадающих команд",
"prompt.dropzone.label": "Перетащите сюда изображения, PDF или текстовые файлы",
"prompt.dropzone.file.label": "Отпустите для @упоминания файла",
"prompt.dropzone.file.label": "Отпустите, чтобы упомянуть файл через @",
"prompt.slash.badge.custom": "своё",
"prompt.slash.badge.skill": "навык",
"prompt.slash.badge.mcp": "mcp",
@@ -332,7 +437,7 @@ export const dict = {
"dialog.directory.readError": "Не удалось прочитать эту папку",
"dialog.server.title": "Серверы",
"dialog.server.description": "Переключите сервер OpenCode к которому подключается приложение.",
"dialog.server.description": "Выберите сервер OpenCode, к которому подключается приложение.",
"dialog.server.search.placeholder": "Поиск серверов",
"dialog.server.empty": "Серверов пока нет",
"dialog.server.add.title": "Добавить сервер",
@@ -356,7 +461,7 @@ export const dict = {
"dialog.server.menu.edit": "Редактировать",
"dialog.server.menu.default": "Сделать по умолчанию",
"dialog.server.menu.defaultRemove": "Удалить по умолчанию",
"dialog.server.menu.defaultRemove": "Отменить выбор по умолчанию",
"dialog.server.menu.delete": "Удалить",
"dialog.server.current": "Текущий сервер",
"dialog.server.status.default": "По умолч.",
@@ -405,7 +510,7 @@ export const dict = {
"wsl.onboarding.needAnotherDistroHint": "Установите дистрибутив Linux из каталога WSL",
"wsl.onboarding.wslNotInstalled.title": "WSL не установлена",
"wsl.onboarding.wslNotInstalled.description":
"Для добавления сервера WSL в OpenCode требуется WSL (Windows Subsystem for Linux)",
"Для добавления сервера WSL в OpenCode требуется WSL (Подсистема Windows для Linux)",
"wsl.onboarding.wslUnavailable.title": "WSL недоступна",
"wsl.onboarding.wslUnavailable.description": "OpenCode не смог проверить WSL на этом компьютере.",
"wsl.onboarding.installWsl": "Установить WSL",
@@ -430,12 +535,28 @@ export const dict = {
"wsl.onboarding.versionMismatch": "Установленная версия не соответствует версии приложения.",
"wsl.onboarding.adding": "Добавление...",
"help.tabs.toast.ariaLabel": "Представляем вкладки. Организуйте работу и активные сессии с помощью вкладок",
"help.tabs.toast.dismiss": "Закрыть сведения о вкладках",
"help.tabs.title": "Представляем вкладки",
"help.tabs.description": "Организуйте работу и активные сессии с помощью вкладок",
"help.tabs.date": "14 июля",
"help.tabs.introduction": "Теперь работа в OpenCode Desktop организована с помощью вкладок.",
"help.tabs.sessions":
"Начните новую сессию во вкладке или откройте существующую сессию из любого проекта. Открывайте новую вкладку, когда начинаете новую задачу, и закрывайте её по завершении.",
"help.tabs.organize":
"Несколько открытых вкладок упрощают организацию активных сессий. Если вы планируете оставить вкладки открытыми, присвойте им запоминающиеся названия.",
"help.tabs.home":
"Все сессии и проекты находятся на новом экране «Главная». При выборе сессии она открывается во вкладке.",
"help.tabs.persistence": "После повторного открытия приложения вкладки останутся открытыми.",
"help.tabs.worktrees":
"Новый дизайн пока не поддерживает Git Worktrees, но эта возможность скоро появится. Если вы предпочитаете прежний макет, переключиться между макетами можно в разделе «Настройки». Учтите, что через несколько недель новый макет станет постоянным.",
"dialog.project.edit.title": "Редактировать проект",
"dialog.project.edit.name": "Название",
"dialog.project.edit.icon": "Иконка",
"dialog.project.edit.icon.alt": "Иконка проекта",
"dialog.project.edit.icon": "Значок",
"dialog.project.edit.icon.alt": "Значок проекта",
"dialog.project.edit.icon.hint": "Нажмите или перетащите изображение",
"dialog.project.edit.icon.recommended": "Рекомендуется: 128x128px",
"dialog.project.edit.icon.recommended": "Рекомендуется: 128 x 128 пикселей",
"dialog.project.edit.color": "Цвет",
"dialog.project.edit.color.select": "Выбрать цвет {{color}}",
@@ -465,7 +586,7 @@ export const dict = {
"context.stats.inputTokens": "Входные токены",
"context.stats.outputTokens": "Выходные токены",
"context.stats.reasoningTokens": "Токены рассуждения",
"context.stats.cacheTokens": "Токены кэша (чтение/запись)",
"context.stats.cacheTokens": "Токены кеша (чтение/запись)",
"context.stats.userMessages": "Сообщения пользователя",
"context.stats.assistantMessages": "Сообщения ассистента",
"context.stats.totalCost": "Общая стоимость",
@@ -564,27 +685,27 @@ export const dict = {
"error.chain.causedBy": "Причина:",
"error.chain.apiError": "Ошибка API",
"error.chain.status": "Статус: {{status}}",
"error.chain.retryable": "Повторная попытка: {{retryable}}",
"error.chain.retryable": "Можно повторить: {{retryable}}",
"error.chain.responseBody": "Тело ответа:\n{{body}}",
"error.chain.didYouMean": "Возможно, вы имели в виду: {{suggestions}}",
"error.chain.modelNotFound": "Модель не найдена: {{provider}}/{{model}}",
"error.chain.checkConfig": "Проверьте названия провайдера/модели в конфиге (opencode.json)",
"error.chain.checkConfig": "Проверьте названия провайдера и модели в конфигурации (opencode.json)",
"error.chain.mcpFailed":
'MCP сервер "{{name}}" завершился с ошибкой. Обратите внимание, что OpenCode пока не поддерживает MCP авторизацию.',
'MCP-сервер "{{name}}" завершился с ошибкой. Обратите внимание: OpenCode пока не поддерживает MCP-авторизацию.',
"error.chain.providerAuthFailed": "Ошибка аутентификации провайдера ({{provider}}): {{message}}",
"error.chain.providerInitFailed":
'Не удалось инициализировать провайдера "{{provider}}". Проверьте учётные данные и конфигурацию.',
"error.chain.configJsonInvalid": "Конфигурационный файл по адресу {{path}} не является валидным JSON(C)",
"error.chain.configJsonInvalid": "Конфигурационный файл по адресу {{path}} содержит некорректный JSON(C)",
"error.chain.configJsonInvalidWithMessage":
"Конфигурационный файл по адресу {{path}} не является валидным JSON(C): {{message}}",
"Конфигурационный файл по адресу {{path}} содержит некорректный JSON(C): {{message}}",
"error.chain.configDirectoryTypo":
'Папка "{{dir}}" в {{path}} невалидна. Переименуйте папку в "{{suggestion}}" или удалите её. Это распространённая опечатка.',
'Папка "{{dir}}" в {{path}} недопустима. Переименуйте папку в "{{suggestion}}" или удалите её. Это распространённая опечатка.',
"error.chain.configFrontmatterError": "Не удалось разобрать frontmatter в {{path}}:\n{{message}}",
"error.chain.configInvalid": "Конфигурационный файл по адресу {{path}} невалиден",
"error.chain.configInvalidWithMessage": "Конфигурационный файл по адресу {{path}} невалиден: {{message}}",
"error.chain.configInvalid": "Недопустимый конфигурационный файл по адресу {{path}}",
"error.chain.configInvalidWithMessage": "Недопустимый конфигурационный файл по адресу {{path}}: {{message}}",
"notification.permission.title": "Требуется разрешение",
"notification.permission.description": "{{sessionTitle}} в {{projectName}} требуется разрешение",
"notification.permission.description": "Для {{sessionTitle}} в {{projectName}} требуется разрешение",
"notification.question.title": "Вопрос",
"notification.question.description": "У {{sessionTitle}} в {{projectName}} есть вопрос",
"notification.action.goToSession": "Перейти к сессии",
@@ -623,7 +744,7 @@ export const dict = {
"session.error.notFound.description": "Эта вкладка указывает на сессию, которой больше нет на этом сервере.",
"session.error.notFound.closeTab": "Закрыть вкладку",
"session.error.serverConnection": "Не удаётся подключиться к этому серверу",
"session.review.filesChanged": "{{count}} файлов изменено",
"session.review.filesChanged": "Изменено файлов: {{count}}",
"session.review.change.one": "Изменение",
"session.review.change.other": "Изменения",
"session.review.loadingChanges": "Загрузка изменений...",
@@ -650,15 +771,21 @@ export const dict = {
"session.question.minimize": "Свернуть вопрос",
"session.question.restore": "Восстановить вопрос",
"session.question.pending.one": "{{count}} вопрос без ответа",
"session.question.pending.few": "{{count}} вопроса без ответа",
"session.question.pending.many": "{{count}} вопросов без ответа",
"session.question.pending.other": "Вопросы без ответа: {{count}}",
"session.followupDock.summary.one": "{{count}} сообщение в очереди",
"session.followupDock.summary.other": "{{count}} сообщений в очереди",
"session.followupDock.summary.few": "{{count}} сообщения в очереди",
"session.followupDock.summary.many": "{{count}} сообщений в очереди",
"session.followupDock.summary.other": "Сообщений в очереди: {{count}}",
"session.followupDock.sendNow": "Отправить сейчас",
"session.followupDock.edit": "Редактировать",
"session.followupDock.collapse": "Свернуть сообщения в очереди",
"session.followupDock.expand": "Развернуть сообщения в очереди",
"session.revertDock.summary.one": "{{count}} сообщение возвращено",
"session.revertDock.summary.other": "{{count}} сообщений возвращено",
"session.revertDock.summary.few": "{{count}} сообщения возвращены",
"session.revertDock.summary.many": "{{count}} сообщений возвращено",
"session.revertDock.summary.other": "Возвращено сообщений: {{count}}",
"session.revertDock.collapse": "Свернуть возвращённые сообщения",
"session.revertDock.expand": "Развернуть возвращённые сообщения",
"session.revertDock.restore": "Восстановить сообщение",
@@ -707,7 +834,7 @@ export const dict = {
"session.share.copy.copied": "Скопировано",
"session.share.copy.copyLink": "Копировать ссылку",
"lsp.tooltip.none": "Нет LSP серверов",
"lsp.tooltip.none": "Нет LSP-серверов",
"lsp.label.connected": "{{count}} LSP",
"prompt.loading": "Загрузка запроса...",
@@ -718,6 +845,12 @@ export const dict = {
"terminal.connectionLost.title": "Соединение потеряно",
"terminal.connectionLost.description":
"Соединение с терминалом прервано. Это может произойти при перезапуске сервера.",
"terminal.connectTicket.csrfError":
"Билет подключения PTY отклонён при проверке источника или CSRF. Проверьте конфигурацию CORS сервера.",
"terminal.connectTicket.statusError": "Не удалось получить билет подключения PTY, статус: {{status}}",
"titlebar.update": "Обновить",
"titlebar.updateVersion": "Обновить {{version}}",
"common.closeTab": "Закрыть вкладку",
"common.dismiss": "Закрыть",
@@ -764,7 +897,7 @@ export const dict = {
"settings.general.section.updates": "Обновления",
"settings.general.section.sounds": "Звуковые эффекты",
"settings.general.section.feed": "Лента",
"settings.general.section.display": "Дисплей",
"settings.general.section.display": "Экран",
"settings.general.row.language.title": "Язык",
"settings.general.row.language.description": "Изменить язык отображения OpenCode",
@@ -774,7 +907,7 @@ export const dict = {
"settings.general.row.shell.autoDefault": "Авто (по умолчанию)",
"settings.general.row.shell.terminalOnly": "только терминал",
"settings.general.row.appearance.title": "Внешний вид",
"settings.general.row.appearance.description": "Настройте как OpenCode выглядит на вашем устройстве",
"settings.general.row.appearance.description": "Настройте внешний вид OpenCode на вашем устройстве",
"settings.general.row.colorScheme.title": "Цветовая схема",
"settings.general.row.colorScheme.description": "Выберите, следует ли OpenCode системной, светлой или тёмной теме",
"settings.general.row.theme.title": "Тема",
@@ -784,7 +917,7 @@ export const dict = {
"settings.general.row.terminalFont.title": "Шрифт терминала",
"settings.general.row.terminalFont.description": "Настройте шрифт, используемый в терминале",
"settings.general.row.uiFont.title": "Шрифт интерфейса",
"settings.general.row.uiFont.description": "Настройте шрифт, используемый во всем интерфейсе",
"settings.general.row.uiFont.description": "Настройте шрифт, используемый во всём интерфейсе",
"settings.general.row.followup.title": "Поведение уточняющих вопросов",
"settings.general.row.followup.description":
"Выберите, отправлять ли уточняющие вопросы сразу или помещать их в очередь",
@@ -804,8 +937,9 @@ export const dict = {
"settings.general.row.mobileTitlebarBottom.title": "Нижняя навигация",
"settings.general.row.mobileTitlebarBottom.description":
"На мобильных устройствах размещать строку заголовка и вкладки сессии внизу экрана",
"settings.general.row.showCustomAgents.title": "Пользовательские агенты",
"settings.general.row.showCustomAgents.description": "Показывать выбор агента в редакторе запросов",
"settings.general.row.showCustomAgents.title": "Выбор агента",
"settings.general.row.showCustomAgents.description":
"Показывать переключатель агентов в редакторе запросов. Если он скрыт, по умолчанию используется агент Build.",
"settings.general.row.reasoningSummaries.title": "Показывать сводки рассуждений",
"settings.general.row.reasoningSummaries.description": "Отображать сводки рассуждений модели в ленте",
@@ -822,11 +956,11 @@ export const dict = {
"settings.general.row.newInterfaceNotice.title": "Теперь вы используете новую компоновку",
"settings.general.row.newInterfaceNotice.description": "Прежняя компоновка больше недоступна",
"settings.general.row.newInterfaceNotice.dismiss": "Закрыть",
"settings.general.row.pinchZoom.title": "Масштабирование щипком",
"settings.general.row.pinchZoom.title": "Масштабирование сведением пальцев",
"settings.general.row.pinchZoom.description":
"Разрешить масштабирование жестом щипка на трекпаде и прокруткой с Ctrl",
"Разрешить масштабирование сведением пальцев на трекпаде и прокруткой с нажатой клавишей Ctrl",
"settings.general.row.wayland.title": "Использовать нативный Wayland",
"settings.general.row.wayland.description": "Отключить X11 fallback на Wayland. Требуется перезапуск.",
"settings.general.row.wayland.description": "Отключить резервный режим X11 в Wayland. Требуется перезапуск.",
"settings.general.row.wayland.tooltip":
"На Linux с мониторами разной частоты обновления нативный Wayland может быть стабильнее.",
@@ -892,22 +1026,22 @@ export const dict = {
"settings.general.notifications.agent.title": "Агент",
"settings.general.notifications.agent.description":
"Показывать системное уведомление когда агент завершён или требует внимания",
"Показывать системное уведомление, когда агент завершил работу или требует внимания",
"settings.general.notifications.permissions.title": "Разрешения",
"settings.general.notifications.permissions.description":
"Показывать системное уведомление когда требуется разрешение",
"Показывать системное уведомление, когда требуется разрешение",
"settings.general.notifications.errors.title": "Ошибки",
"settings.general.notifications.errors.description": "Показывать системное уведомление когда происходит ошибка",
"settings.general.notifications.errors.description": "Показывать системное уведомление, когда происходит ошибка",
"settings.general.sounds.agent.title": "Агент",
"settings.general.sounds.agent.description": "Воспроизводить звук когда агент завершён или требует внимания",
"settings.general.sounds.agent.description": "Воспроизводить звук, когда агент завершил работу или требует внимания",
"settings.general.sounds.permissions.title": "Разрешения",
"settings.general.sounds.permissions.description": "Воспроизводить звук когда требуется разрешение",
"settings.general.sounds.permissions.description": "Воспроизводить звук, когда требуется разрешение",
"settings.general.sounds.errors.title": "Ошибки",
"settings.general.sounds.errors.description": "Воспроизводить звук когда происходит ошибка",
"settings.general.sounds.errors.description": "Воспроизводить звук, когда происходит ошибка",
"settings.shortcuts.title": "Горячие клавиши",
"settings.shortcuts.reset.button": "Сбросить к умолчаниям",
"settings.shortcuts.reset.button": "Восстановить настройки по умолчанию",
"settings.shortcuts.reset.toast.title": "Горячие клавиши сброшены",
"settings.shortcuts.reset.toast.description": "Горячие клавиши были сброшены к значениям по умолчанию.",
"settings.shortcuts.conflict.title": "Сочетание уже используется",
@@ -943,7 +1077,7 @@ export const dict = {
"settings.mcp.description": "Настройки MCP будут доступны здесь.",
"settings.permissions.title": "Разрешения",
"settings.permissions.description": "Контролируйте какие инструменты сервер может использовать по умолчанию.",
"settings.permissions.description": "Укажите, какие инструменты сервер может использовать по умолчанию.",
"settings.permissions.section.tools": "Инструменты",
"settings.permissions.toast.updateFailed.title": "Не удалось обновить разрешения",
@@ -955,7 +1089,7 @@ export const dict = {
"settings.permissions.tool.read.description": "Чтение файла (по совпадению пути)",
"settings.permissions.tool.edit.title": "Редактирование",
"settings.permissions.tool.edit.description":
"Изменение файлов, включая редактирование, запись, патчи и мульти-редактирование",
"Изменение файлов, включая редактирование, запись, патчи и множественное редактирование",
"settings.permissions.tool.glob.title": "Glob",
"settings.permissions.tool.glob.description": "Сопоставление файлов по паттернам glob",
"settings.permissions.tool.grep.title": "Grep",
@@ -965,7 +1099,7 @@ export const dict = {
"settings.permissions.tool.bash.title": "Bash",
"settings.permissions.tool.bash.description": "Запуск команд оболочки",
"settings.permissions.tool.task.title": "Task",
"settings.permissions.tool.task.description": "Запуск подагентов",
"settings.permissions.tool.task.description": "Запуск субагентов",
"settings.permissions.tool.skill.title": "Skill",
"settings.permissions.tool.skill.description": "Загрузка навыка по имени",
"settings.permissions.tool.lsp.title": "LSP",
@@ -999,7 +1133,7 @@ export const dict = {
"workspace.reset.success.description": "Рабочее пространство теперь соответствует ветке по умолчанию.",
"workspace.error.stillPreparing": "Рабочее пространство всё ещё подготавливается",
"workspace.status.checking": "Проверка незафиксированных изменений...",
"workspace.status.error": "Не удалось проверить статус git.",
"workspace.status.error": "Не удалось проверить состояние Git.",
"workspace.status.clean": "Незафиксированных изменений не обнаружено.",
"workspace.status.dirty": "В этом рабочем пространстве обнаружены незафиксированные изменения.",
"workspace.delete.title": "Удалить рабочее пространство",
@@ -1010,13 +1144,13 @@ export const dict = {
"workspace.reset.button": "Сбросить рабочее пространство",
"workspace.reset.archived.none": "Активные сессии не будут архивированы.",
"workspace.reset.archived.one": "1 сессия будет архивирована.",
"workspace.reset.archived.many": "{{count}} сессий будет архивировано.",
"workspace.reset.archived.many": "Будут архивированы сессии: {{count}}.",
"workspace.reset.note": "Это сбросит рабочее пространство до соответствия ветке по умолчанию.",
"common.open": "Открыть",
"dialog.releaseNotes.action.getStarted": "Начать",
"dialog.releaseNotes.action.next": "Далее",
"dialog.releaseNotes.action.hideFuture": "Больше не показывать",
"dialog.releaseNotes.media.alt": "Превью релиза",
"dialog.releaseNotes.media.alt": "Предварительный просмотр выпуска",
"toast.project.reloadFailed.title": "Не удалось перезагрузить {{project}}",
"error.server.invalidConfiguration": "Недопустимая конфигурация",
"common.moreCountSuffix": " (ещё {{count}})",
@@ -1041,6 +1175,9 @@ export const dict = {
"session.question.progress": "{{current}} из {{total}} вопросов",
"session.header.open.finder": "Finder",
"session.header.open.fileExplorer": "Проводник",
"session.header.reveal.finder": "Показать в Finder",
"session.header.reveal.fileExplorer": "Показать в Проводнике",
"session.header.reveal.containingFolder": "Открыть папку расположения",
"session.header.open.fileManager": "Файловый менеджер",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -1059,7 +1196,7 @@ export const dict = {
"debugBar.na": "н/д",
"debugBar.nav.label": "NAV",
"debugBar.nav.tip":
"Последний завершенный переход маршрута, затрагивающий страницу сеанса, измеренный от запуска маршрутизатора до первой отрисовки после стабилизации.",
"Последний завершённый переход по маршруту, затрагивающий страницу сессии: от запуска маршрутизатора до первой отрисовки после стабилизации.",
"debugBar.fps.label": "FPS",
"debugBar.fps.tip": "Скользящая частота кадров в секунду за последние 5 секунд.",
"debugBar.frame.label": "FRAME",
@@ -1074,10 +1211,18 @@ export const dict = {
"debugBar.inp.tip":
"Приблизительная продолжительность взаимодействия за последние 5 секунд. Это похоже на INP, а не официальный Web Vitals INP.",
"debugBar.cls.label": "CLS",
"debugBar.cls.tip": "Кумулятивный сдвиг макета за текущее время жизни приложения.",
"debugBar.cls.tip": "Совокупное смещение макета за время работы приложения.",
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Используемая куча JS по сравнению с лимитом кучи. Только Chromium.",
"debugBar.mem.tip": "Используемая куча JS по сравнению с лимитом кучи. {{used}} из {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Принудительно применить стили фокуса ко всем интерактивным элементам",
"debugBar.focus.on": "ВКЛ.",
"debugBar.focus.off": "ВЫКЛ.",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Принудительно задать направление макета всего приложения, не меняя выбранный язык",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
@@ -1096,7 +1241,7 @@ export const dict = {
"error.page.circular": "[Циклично]",
"error.serverSDK.noServerAvailable": "Нет доступного сервера",
"error.serverSDK.serverNotAvailable": "Сервер недоступен",
"error.childStore.persistedCacheCreateFailed": "Не удалось создать постоянный кэш",
"error.childStore.persistedCacheCreateFailed": "Не удалось создать постоянный кеш",
"error.childStore.persistedProjectMetadataCreateFailed": "Не удалось создать постоянные метаданные проекта",
"error.childStore.persistedProjectIconCreateFailed": "Не удалось создать постоянный значок проекта",
"error.childStore.storeCreateFailed": "Не удалось создать хранилище",
File diff suppressed because it is too large Load Diff
+202 -65
View File
@@ -1,4 +1,102 @@
export const dict = {
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "ไฟล์",
"desktop.menu.edit": "แก้ไข",
"desktop.menu.view": "มุมมอง",
"desktop.menu.go": "ไป",
"desktop.menu.window": "หน้าต่าง",
"desktop.menu.help": "วิธีใช้",
"desktop.menu.checkForUpdates": "ตรวจหาการอัปเดต...",
"desktop.menu.settings": "การตั้งค่า",
"desktop.menu.reloadWebview": "โหลด Webview ใหม่",
"desktop.menu.restart": "เริ่มการทำงานใหม่",
"desktop.menu.exportLogs": "ส่งออกบันทึก...",
"desktop.menu.newSession": "เซสชันใหม่",
"desktop.menu.openProject": "เปิดโปรเจกต์...",
"desktop.menu.newWindow": "หน้าต่างใหม่",
"desktop.menu.closeWindow": "ปิดหน้าต่าง",
"desktop.menu.undo": "เลิกทำ",
"desktop.menu.redo": "ทำซ้ำ",
"desktop.menu.cut": "ตัด",
"desktop.menu.copy": "คัดลอก",
"desktop.menu.paste": "วาง",
"desktop.menu.delete": "ลบ",
"desktop.menu.selectAll": "เลือกทั้งหมด",
"desktop.menu.toggleSidebar": "สลับแถบด้านข้าง",
"desktop.menu.toggleTerminal": "สลับเทอร์มินัล",
"desktop.menu.toggleFileTree": "สลับแผนผังไฟล์",
"desktop.menu.reload": "โหลดใหม่",
"desktop.menu.toggleDeveloperTools": "สลับเครื่องมือสำหรับนักพัฒนา",
"desktop.menu.actualSize": "ขนาดจริง",
"desktop.menu.zoomIn": "ขยาย",
"desktop.menu.zoomOut": "ย่อ",
"desktop.menu.toggleFullScreen": "สลับโหมดเต็มหน้าจอ",
"desktop.menu.back": "ย้อนกลับ",
"desktop.menu.forward": "ไปข้างหน้า",
"desktop.menu.previousSession": "เซสชันก่อนหน้า",
"desktop.menu.nextSession": "เซสชันถัดไป",
"desktop.menu.previousProject": "โปรเจกต์ก่อนหน้า",
"desktop.menu.nextProject": "โปรเจกต์ถัดไป",
"desktop.menu.minimize": "ย่อหน้าต่าง",
"desktop.menu.maximize": "ขยายหน้าต่าง",
"desktop.menu.documentation": "เอกสาร OpenCode",
"desktop.menu.supportForum": "ฟอรัมสนับสนุน",
"desktop.menu.shareFeedback": "ส่งข้อคิดเห็น",
"desktop.menu.reportBug": "รายงานข้อบกพร่อง",
"desktop.menu.ariaLabel": "เมนู OpenCode",
"desktop.updater.dialog.checkFailed.message": "การตรวจหาการอัปเดตล้มเหลว",
"desktop.updater.dialog.checkFailed.title": "ข้อผิดพลาดในการอัปเดต",
"desktop.updater.dialog.upToDate.message": "คุณกำลังใช้เวอร์ชันล่าสุด",
"desktop.updater.dialog.upToDate.title": "ไม่มีการอัปเดต",
"desktop.updater.dialog.ready.message": "ดาวน์โหลดการอัปเดต {{version}} แล้ว เริ่มการทำงานใหม่ตอนนี้หรือไม่",
"desktop.updater.dialog.ready.title": "พร้อมอัปเดต",
"desktop.updater.dialog.restart": "เริ่มการทำงานใหม่",
"desktop.updater.dialog.later": "ภายหลัง",
"desktop.recovery.action.relaunch": "เปิดอีกครั้ง",
"desktop.recovery.action.exportLogs": "ส่งออกบันทึก",
"desktop.recovery.action.keepWaiting": "รอต่อไป",
"desktop.recovery.action.quit": "ออก",
"desktop.recovery.loadFailed": "โหลด OpenCode ไม่สำเร็จ",
"desktop.recovery.terminated": "หน้าต่าง OpenCode หยุดทำงานโดยไม่คาดคิด",
"desktop.recovery.unresponsive": "OpenCode ไม่ตอบสนอง",
"desktop.recovery.unresponsive.detail": "คุณสามารถเปิดแอปอีกครั้ง เปิดบันทึก หรือรอต่อไป",
"desktop.recovery.loadFailed.detail": "หน้าต่าง: {{window}}\nURL: {{url}}\nข้อผิดพลาด: {{code}} {{description}}",
"desktop.recovery.terminated.detail": "หน้าต่าง: {{window}}\nสาเหตุ: {{reason}}\nรหัส: {{code}}",
"desktop.recovery.unknown": "<ไม่ทราบ>",
"desktop.dialog.chooseFolder": "เลือกโฟลเดอร์",
"desktop.dialog.chooseFile": "เลือกไฟล์",
"desktop.dialog.saveFile": "บันทึกไฟล์",
"desktop.dialog.files": "ไฟล์",
"desktop.server.local": "เซิร์ฟเวอร์ภายในเครื่อง",
"desktop.wsl.error.windowsOnly": "WSL ใช้งานได้เฉพาะบน Windows เท่านั้น",
"desktop.wsl.error.unavailable": "WSL ไม่พร้อมใช้งาน",
"desktop.wsl.error.listInstalled": "ไม่สามารถแสดงรายการดิสโทร WSL ที่ติดตั้งแล้วได้",
"desktop.wsl.error.listOnline": "ไม่สามารถแสดงรายการดิสโทร WSL แบบออนไลน์ได้",
"desktop.wsl.error.executeDistro": "ไม่สามารถเรียกใช้คำสั่งในดิสโทรได้",
"desktop.wsl.error.installWsl": "การติดตั้ง WSL ล้มเหลว",
"desktop.wsl.error.installDistro": "ไม่สามารถติดตั้งดิสโทรได้: {{distro}}",
"desktop.wsl.error.installOpencode": "การติดตั้ง OpenCode ล้มเหลว",
"desktop.wsl.error.alreadyAdded": "เพิ่ม {{distro}} แล้ว",
"desktop.wsl.error.opencodeMissing": "ไม่ได้ติดตั้ง opencode ในดิสโทรนี้",
"desktop.wsl.error.opencodeCannotRun": "ติดตั้ง opencode แล้ว แต่ไม่สามารถเรียกใช้ได้",
"desktop.wsl.error.opencodeNotInstalled": "ไม่ได้ติดตั้ง OpenCode ใน {{distro}}",
"desktop.wsl.error.updateVersion":
"อัปเดต OpenCode เสร็จแล้ว แต่ {{distro}} ยังคงรายงานเวอร์ชัน {{installed}} ทั้งที่ควรเป็น {{expected}}",
"desktop.wsl.error.noVersion": "ไม่มีเวอร์ชัน",
"desktop.wsl.error.serverExited": "เซิร์ฟเวอร์ WSL หยุดทำงานหลังเริ่มต้น (code={{code}} signal={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"เซิร์ฟเวอร์ WSL หยุดทำงานก่อนพร้อมใช้งาน (code={{code}} signal={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout": "การตรวจสอบสถานะ Sidecar สำหรับ {{distro}} หมดเวลาหลังจาก {{timeout}}ms",
"desktop.wsl.error.commandTimeout": "{{command}} {{args}} หมดเวลาหลังจาก {{timeout}}ms",
"desktop.wsl.error.failedPort": "ไม่สามารถรับพอร์ตได้",
"desktop.picker.error.notSelected": "ไม่ได้เลือกไฟล์จากตัวเลือกไฟล์",
"desktop.picker.error.sizeLimit": "ไฟล์แนบที่เลือกมีขนาดเกินขีดจำกัด {{limit}} MB",
"command.category.suggested": "แนะนำ",
"command.category.view": "มุมมอง",
"command.category.project": "โปรเจกต์",
@@ -16,6 +114,7 @@ export const dict = {
"command.category.permissions": "สิทธิ์",
"command.category.workspace": "พื้นที่ทำงาน",
"command.category.settings": "การตั้งค่า",
"command.logs.export": "ส่งออกบันทึก",
"theme.scheme.system": "ระบบ",
"theme.scheme.light": "สว่าง",
@@ -53,7 +152,7 @@ export const dict = {
"command.context.addSelection.description": "เพิ่มบรรทัดที่เลือกจากไฟล์ปัจจุบัน",
"command.input.focus": "โฟกัสช่องป้อนข้อมูล",
"command.terminal.toggle": "สลับเทอร์มินัล",
"command.fileTree.toggle": "สลับต้นไม้ไฟล์",
"command.fileTree.toggle": "สลับแผนผังไฟล์",
"command.review.toggle": "สลับการตรวจสอบ",
"command.terminal.new": "เทอร์มินัลใหม่",
"command.terminal.new.description": "สร้างแท็บเทอร์มินัลใหม่",
@@ -79,8 +178,8 @@ export const dict = {
"command.permissions.autoaccept.disable": "หยุดยอมรับสิทธิ์โดยอัตโนมัติ",
"command.workspace.toggle": "สลับพื้นที่ทำงาน",
"command.workspace.toggle.description": "เปิดหรือปิดใช้งานพื้นที่ทำงานหลายรายการในแถบด้านข้าง",
"command.session.undo": "ยกเลิก",
"command.session.undo.description": "ยกเลิกข้อความล่าสุด",
"command.session.undo": "เลิกทำ",
"command.session.undo.description": "เลิกทำข้อความล่าสุด",
"command.session.redo": "ทำซ้ำ",
"command.session.redo.description": "ทำซ้ำข้อความที่ถูกยกเลิกล่าสุด",
"command.session.compact": "บีบอัดเซสชัน",
@@ -102,6 +201,7 @@ export const dict = {
"dialog.provider.empty": "ไม่พบผู้ให้บริการ",
"dialog.provider.group.popular": "ยอดนิยม",
"dialog.provider.group.other": "อื่น ๆ",
"dialog.provider.custom.label": "ผู้ให้บริการแบบกำหนดเองที่เข้ากันได้กับ OpenAI",
"dialog.provider.tag.recommended": "แนะนำ",
"dialog.provider.opencode.note": "โมเดลที่คัดสรร รวมถึง Claude, GPT, Gemini และอื่น ๆ",
"dialog.provider.opencode.tagline": "โมเดลที่เชื่อถือได้และปรับให้เหมาะสม",
@@ -122,6 +222,7 @@ export const dict = {
"dialog.model.unpaid.freeModels.title": "โมเดลฟรีที่จัดหาให้โดย OpenCode",
"dialog.model.unpaid.addMore.title": "เพิ่มโมเดลเพิ่มเติมจากผู้ให้บริการยอดนิยม",
"dialog.model.unpaid.viewMoreProviders": "ดูผู้ให้บริการเพิ่มเติมกว่า 70 ราย",
"dialog.provider.viewAll": "แสดงผู้ให้บริการเพิ่มเติม",
@@ -129,6 +230,8 @@ export const dict = {
"provider.connect.title.anthropicProMax": "เข้าสู่ระบบด้วย Claude Pro/Max",
"provider.connect.selectMethod": "เลือกวิธีการเข้าสู่ระบบสำหรับ {{provider}}",
"provider.connect.method.apiKey": "คีย์ API",
"provider.connect.method.browser": "เบราว์เซอร์",
"provider.connect.method.headless": "ไม่ใช้เบราว์เซอร์",
"provider.connect.status.inProgress": "กำลังอนุญาต...",
"provider.connect.status.waiting": "รอการอนุญาต...",
"provider.connect.status.failed": "การอนุญาตล้มเหลว: {{error}}",
@@ -143,11 +246,11 @@ export const dict = {
"ด้วยคีย์ API เดียวคุณจะได้รับการเข้าถึงโมเดล เช่น Claude, GPT, Gemini, GLM และอื่น ๆ",
"provider.connect.opencodeZen.visit.prefix": "เยี่ยมชม ",
"provider.connect.opencodeZen.visit.link": "opencode.ai/zen",
"provider.connect.opencodeZen.visit.suffix": " เพื่อรวบรวมคีย์ API ของคุณ",
"provider.connect.opencodeZen.visit.suffix": " เพื่อรับคีย์ API ของคุณ",
"provider.connect.oauth.code.visit.prefix": "เยี่ยมชม ",
"provider.connect.oauth.code.visit.link": "ลิงก์นี้",
"provider.connect.oauth.code.visit.suffix":
" เพื่อรวบรวมรหัสการอนุญาตของคุณเพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน OpenCode",
" เพื่อรับรหัสการอนุญาตสำหรับเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน OpenCode",
"provider.connect.oauth.code.label": "รหัสการอนุญาต {{method}}",
"provider.connect.oauth.code.placeholder": "รหัสการอนุญาต",
"provider.connect.oauth.code.required": "ต้องใช้รหัสการอนุญาต",
@@ -157,13 +260,14 @@ export const dict = {
"provider.connect.oauth.auto.visit.suffix":
" และป้อนรหัสด้านล่างเพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน OpenCode",
"provider.connect.oauth.auto.confirmationCode": "รหัสยืนยัน",
"provider.connect.toast.connected.title": "{{provider}} ที่เชื่อมต่อแล้ว",
"provider.connect.toast.connected.title": "เชื่อมต่อ {{provider}} แล้ว",
"provider.connect.toast.connected.description": "โมเดล {{provider}} พร้อมใช้งานแล้ว",
"provider.custom.title": "ผู้ให้บริการที่กำหนดเอง",
"provider.custom.unavailable": "ผู้ให้บริการที่กำหนดเองไม่พร้อมใช้งานบนเซิร์ฟเวอร์นี้",
"provider.custom.description.prefix": "กำหนดค่าผู้ให้บริการที่เข้ากันได้กับ OpenAI ดู ",
"provider.custom.description.link": "เอกสารการกำหนดค่าผู้ให้บริการ",
"provider.custom.description.suffix": ".",
"provider.custom.description.suffix": "",
"provider.custom.field.providerID.label": "รหัสผู้ให้บริการ",
"provider.custom.field.providerID.placeholder": "myprovider",
"provider.custom.field.providerID.description": "ตัวอักษรพิมพ์เล็ก ตัวเลข ยัติภังค์ หรือขีดล่าง",
@@ -197,7 +301,7 @@ export const dict = {
"provider.custom.error.required": "จำเป็น",
"provider.custom.error.duplicate": "ซ้ำ",
"provider.disconnect.toast.disconnected.title": "{{provider}} ที่ยกเลิกการเชื่อมต่อแล้ว",
"provider.disconnect.toast.disconnected.title": "ยกเลิกการเชื่อมต่อ {{provider}} แล้ว",
"provider.disconnect.toast.disconnected.description": "โมเดล {{provider}} ไม่พร้อมใช้งานอีกต่อไป",
"model.tag.free": "ฟรี",
@@ -212,7 +316,7 @@ export const dict = {
"model.input.audio": "เสียง",
"model.input.video": "วิดีโอ",
"model.input.pdf": "PDF",
"model.tooltip.allows": "อนุญาต: {{inputs}}",
"model.tooltip.allows": "รองรับ: {{inputs}}",
"model.tooltip.context.label": "บริบท",
"model.tooltip.inputs": "ข้อมูลนำเข้า",
"model.tooltip.model": "โมเดล",
@@ -224,14 +328,14 @@ export const dict = {
"common.search.placeholder": "ค้นหา",
"common.goBack": "ย้อนกลับ",
"common.goForward": "นำทางไปข้างหน้า",
"common.goForward": "ไปข้างหน้า",
"common.loading": "กำลังโหลด",
"common.loading.ellipsis": "...",
"common.cancel": "ยกเลิก",
"common.clear": "ล้าง",
"common.connect": "เชื่อมต่อ",
"common.disconnect": "ยกเลิกการเชื่อมต่อ",
"common.continue": "ส่ง",
"common.continue": "ดำเนินการต่อ",
"common.submit": "ส่ง",
"common.save": "บันทึก",
"common.saving": "กำลังบันทึก...",
@@ -246,8 +350,8 @@ export const dict = {
"prompt.mode.shell": "เชลล์",
"prompt.mode.normal": "พรอมต์",
"prompt.mode.shell.exit": "กด esc เพื่อออก",
"session.child.promptDisabled": "ไม่สามารถส่งพรอมต์ในเซสชันเอเจนต์ย่อยได้.",
"session.child.backToParent": "กลับไปยังเซสชันหลัก.",
"session.child.promptDisabled": "ไม่สามารถส่งพรอมต์ในเซสชันเอเจนต์ย่อยได้",
"session.child.backToParent": "กลับไปยังเซสชันหลัก",
"prompt.example.1": "แก้ไข TODO ในโค้ดเบส",
"prompt.example.2": "เทคโนโลยีของโปรเจกต์นี้คืออะไร?",
@@ -262,7 +366,7 @@ export const dict = {
"prompt.example.11": "ปรับปรุงการสืบค้นฐานข้อมูล",
"prompt.example.12": "เพิ่มการตรวจสอบข้อมูลนำเข้า",
"prompt.example.13": "สร้างคอมโพเนนต์ใหม่สำหรับ...",
"prompt.example.14": "ฉันจะทำให้โปรเจกต์นี้ทำงานได้อย่างไร?",
"prompt.example.14": "ฉันจะนำโปรเจกต์นี้ไปใช้งานได้อย่างไร?",
"prompt.example.15": "ตรวจสอบโค้ดของฉันเพื่อแนวทางปฏิบัติที่ดีที่สุด",
"prompt.example.16": "เพิ่มการจัดการข้อผิดพลาดในฟังก์ชันนี้",
"prompt.example.17": "อธิบายรูปแบบ regex นี้",
@@ -270,15 +374,15 @@ export const dict = {
"prompt.example.19": "เพิ่มการบันทึกทั่วทั้งโค้ดเบส",
"prompt.example.20": "มีการพึ่งพาอะไรที่ล้าสมัยอยู่?",
"prompt.example.21": "ช่วยฉันเขียนสคริปต์การย้ายข้อมูล",
"prompt.example.22": "ใช้งานแคชสำหรับจุดสิ้นสุดนี้",
"prompt.example.22": "ใช้แคชสำหรับเอนด์พอยต์นี้",
"prompt.example.23": "เพิ่มการแบ่งหน้าในรายการนี้",
"prompt.example.24": "สร้างคำสั่ง CLI สำหรับ...",
"prompt.example.25": "ตัวแปรสภาพแวดล้อมทำงานอย่างไรที่นี่?",
"prompt.popover.emptyResults": "ไม่พบผลลัพธ์ที่ตรงกัน",
"prompt.popover.emptyCommands": "ไม่พบคำสั่งที่ตรงกัน",
"prompt.dropzone.label": "ลากรูปภาพ, PDF หรือไฟล์ข้อความมาวางที่นี่",
"prompt.dropzone.file.label": "วางเพื่อ @กล่าวถึงไฟล์",
"prompt.dropzone.label": "ลากรูปภาพ PDF หรือไฟล์ข้อความมาวางที่นี่",
"prompt.dropzone.file.label": "วางเพื่ออ้างถึงไฟล์ด้วย @",
"prompt.slash.badge.custom": "กำหนดเอง",
"prompt.slash.badge.skill": "ทักษะ",
"prompt.slash.badge.mcp": "MCP",
@@ -298,14 +402,14 @@ export const dict = {
"prompt.toast.pasteUnsupported.title": "ไฟล์แนบที่ไม่รองรับ",
"prompt.toast.attachmentDuplicate.title": "ไฟล์นี้ถูกอัปโหลดแล้ว",
"prompt.toast.pasteUnsupported.description": "แนบได้เฉพาะรูปภาพ, PDF หรือไฟล์ข้อความเท่านั้น",
"prompt.toast.pasteUnsupported.description": "แนบได้เฉพาะรูปภาพ PDF หรือไฟล์ข้อความเท่านั้น",
"prompt.toast.modelAgentRequired.title": "เลือกเอเจนต์และโมเดล",
"prompt.toast.modelAgentRequired.description": "เลือกเอเจนต์และโมเดลก่อนส่งพรอม์",
"prompt.toast.modelAgentRequired.description": "เลือกเอเจนต์และโมเดลก่อนส่งพรอม์",
"prompt.toast.worktreeCreateFailed.title": "ไม่สามารถสร้าง worktree",
"prompt.toast.sessionCreateFailed.title": "ไม่สามารถสร้างเซสชัน",
"prompt.toast.shellSendFailed.title": "ไม่สามารถส่งคำสั่งเชลล์",
"prompt.toast.commandSendFailed.title": "ไม่สามารถส่งคำสั่ง",
"prompt.toast.promptSendFailed.title": "ไม่สามารถส่งพรอม์",
"prompt.toast.promptSendFailed.title": "ไม่สามารถส่งพรอม์",
"prompt.toast.promptSendFailed.description": "ไม่สามารถดึงเซสชันได้",
"dialog.mcp.title": "MCPs",
@@ -317,7 +421,7 @@ export const dict = {
"mcp.status.connected": "เชื่อมต่อแล้ว",
"mcp.status.failed": "ล้มเหลว",
"mcp.status.needs_auth": "ต้องการการตรวจสอบสิทธิ์",
"mcp.status.needs_auth": "ต้องยืนยันตัวตน",
"mcp.auth.clickToAuthenticate": "คลิกเพื่อยืนยันตัวตน",
"mcp.status.disabled": "ปิดใช้งาน",
@@ -327,7 +431,7 @@ export const dict = {
"dialog.directory.empty": "ไม่พบโฟลเดอร์",
"dialog.directory.action.selectFile": "เลือกไฟล์",
"dialog.directory.action.selectFolder": "เลือกโฟลเดอร์",
"dialog.directory.root": "ราก",
"dialog.directory.root": "โฟลเดอร์ราก",
"dialog.directory.parent": "โฟลเดอร์หลัก",
"dialog.directory.readError": "ไม่สามารถอ่านโฟลเดอร์นี้ได้",
@@ -369,30 +473,30 @@ export const dict = {
"wsl.onboarding.step.distro": "เลือกดิสโทร",
"wsl.onboarding.step.opencode": "OpenCode",
"wsl.onboarding.checkingRuntime": "กำลังตรวจสอบ WSL...",
"wsl.onboarding.restartRequired": "ต้องรีสตาร์ท Windows เพื่อให้การติดตั้ง WSL เสร็จสมบูรณ์.",
"wsl.onboarding.ready": "WSL พร้อมใช้งานแล้ว.",
"wsl.onboarding.required": "ต้องมี WSL เพื่อดำเนินการต่อ.",
"wsl.onboarding.restartRequired": "ต้องรีสตาร์ท Windows เพื่อให้การติดตั้ง WSL เสร็จสมบูรณ์",
"wsl.onboarding.ready": "WSL พร้อมใช้งานแล้ว",
"wsl.onboarding.required": "ต้องมี WSL เพื่อดำเนินการต่อ",
"wsl.onboarding.checkingDistros": "กำลังตรวจสอบดิสโทร...",
"wsl.onboarding.installingDistro": "กำลังติดตั้ง {{distro}}...",
"wsl.onboarding.checkingDistro": "กำลังตรวจสอบ {{distro}}...",
"wsl.onboarding.listingDistros": "กำลังแสดงรายการดิสโทร...",
"wsl.onboarding.distroReady": "{{distro}} พร้อมใช้งานแล้ว.",
"wsl.onboarding.distroNotInstalled": "ยังไม่ได้ติดตั้ง {{distro}}.",
"wsl.onboarding.openDistroOnce": "เปิด {{distro}} หนึ่งครั้งเพื่อให้การตั้งค่าเสร็จสมบูรณ์.",
"wsl.onboarding.finishingDistro": "กำลังตั้งค่า {{distro}} ให้เสร็จสมบูรณ์.",
"wsl.onboarding.pickDistro": "เลือกดิสโทรหรือติดตั้งจากรายการด้านล่าง.",
"wsl.onboarding.distroReady": "{{distro}} พร้อมใช้งานแล้ว",
"wsl.onboarding.distroNotInstalled": "ยังไม่ได้ติดตั้ง {{distro}}",
"wsl.onboarding.openDistroOnce": "เปิด {{distro}} หนึ่งครั้งเพื่อให้การตั้งค่าเสร็จสมบูรณ์",
"wsl.onboarding.finishingDistro": "กำลังตั้งค่า {{distro}} ให้เสร็จสมบูรณ์",
"wsl.onboarding.pickDistro": "เลือกดิสโทรหรือติดตั้งจากรายการด้านล่าง",
"wsl.onboarding.checkingOpencode": "กำลังตรวจสอบ OpenCode...",
"wsl.onboarding.checkingOpencodeIn": "กำลังตรวจสอบ OpenCode ใน {{distro}}...",
"wsl.onboarding.updatingOpencode": "กำลังอัปเดต OpenCode...",
"wsl.onboarding.updatingOpencodeIn": "กำลังอัปเดต OpenCode ใน {{distro}}...",
"wsl.onboarding.updateOpencodeIn": "อัปเดต OpenCode ใน {{distro}}.",
"wsl.onboarding.updateOpencodeIn": "อัปเดต OpenCode ใน {{distro}}",
"wsl.onboarding.updateOpencode": "อัปเดต OpenCode",
"wsl.onboarding.opencodeReadyIn": "OpenCode พร้อมใช้งานใน {{distro}} แล้ว.",
"wsl.onboarding.opencodeReady": "OpenCode พร้อมใช้งานแล้ว.",
"wsl.onboarding.installOpencodeIn": "ติดตั้ง OpenCode ใน {{distro}}.",
"wsl.onboarding.opencodeReadyIn": "OpenCode พร้อมใช้งานใน {{distro}} แล้ว",
"wsl.onboarding.opencodeReady": "OpenCode พร้อมใช้งานแล้ว",
"wsl.onboarding.installOpencodeIn": "ติดตั้ง OpenCode ใน {{distro}}",
"wsl.onboarding.installOpencode": "ติดตั้ง OpenCode",
"wsl.onboarding.chooseDistroFirst": "เลือกดิสโทรก่อน.",
"wsl.onboarding.loadFailed": "ไม่สามารถโหลดสถานะ WSL ได้.",
"wsl.onboarding.chooseDistroFirst": "เลือกดิสโทรก่อน",
"wsl.onboarding.loadFailed": "ไม่สามารถโหลดสถานะ WSL ได้",
"wsl.onboarding.loading": "กำลังโหลด...",
"wsl.onboarding.installedDistros": "ดิสโทรที่ติดตั้งแล้ว",
"wsl.onboarding.checkAgain": "ตรวจสอบอีกครั้ง",
@@ -407,29 +511,44 @@ export const dict = {
"wsl.onboarding.wslNotInstalled.description":
"ต้องมี WSL (Windows Subsystem for Linux) ก่อนที่ OpenCode จะเพิ่มเซิร์ฟเวอร์ WSL ได้",
"wsl.onboarding.wslUnavailable.title": "WSL ไม่พร้อมใช้งาน",
"wsl.onboarding.wslUnavailable.description": "OpenCode ไม่สามารถตรวจสอบ WSL บนเครื่องนี้ได้.",
"wsl.onboarding.wslUnavailable.description": "OpenCode ไม่สามารถตรวจสอบ WSL บนเครื่องนี้ได้",
"wsl.onboarding.installWsl": "ติดตั้ง WSL",
"wsl.onboarding.windowsRestartRequired":
"รีสตาร์ท Windows เพื่อให้การติดตั้ง WSL เสร็จสมบูรณ์ แล้วเปิด OpenCode อีกครั้ง.",
"รีสตาร์ท Windows เพื่อให้การติดตั้ง WSL เสร็จสมบูรณ์ แล้วเปิด OpenCode อีกครั้ง",
"wsl.onboarding.next": "ถัดไป",
"wsl.onboarding.refresh": "รีเฟรช",
"wsl.onboarding.allDistrosAdded": "เพิ่มดิสโทรที่ติดตั้งไว้ทั้งหมดแล้ว.",
"wsl.onboarding.noDistros": "ยังไม่พบดิสโทร.",
"wsl.onboarding.allDistrosAdded": "เพิ่มดิสโทรที่ติดตั้งไว้ทั้งหมดแล้ว",
"wsl.onboarding.noDistros": "ยังไม่พบดิสโทร",
"wsl.onboarding.install": "ติดตั้ง",
"wsl.onboarding.installing": "กำลังติดตั้ง...",
"wsl.onboarding.installDistro": "ติดตั้งดิสโทร",
"wsl.onboarding.searchDistros": "ค้นหาดิสโทร",
"wsl.onboarding.wsl2Required": "ต้องใช้ WSL 2.",
"wsl.onboarding.toolsRequired": "ดิสโทรนี้ต้องมี bash และ curl.",
"wsl.onboarding.wsl2Required": "ต้องใช้ WSL 2",
"wsl.onboarding.toolsRequired": "ดิสโทรนี้ต้องมี bash และ curl",
"wsl.onboarding.openTerminal": "เปิดเทอร์มินัล",
"wsl.onboarding.path": "เส้นทาง: {{path}}",
"wsl.onboarding.notFound": "ไม่พบ",
"wsl.onboarding.version": "เวอร์ชัน: {{version}}",
"wsl.onboarding.unknown": "ไม่ทราบ",
"wsl.onboarding.desktopVersion": "เดสก์ท็อป {{version}}",
"wsl.onboarding.versionMismatch": "เวอร์ชันที่ติดตั้งไม่ตรงกับเวอร์ชันของแอปเดสก์ท็อป.",
"wsl.onboarding.versionMismatch": "เวอร์ชันที่ติดตั้งไม่ตรงกับเวอร์ชันของแอปเดสก์ท็อป",
"wsl.onboarding.adding": "กำลังเพิ่ม...",
"help.tabs.toast.ariaLabel": "ขอแนะนำแท็บ จัดระเบียบงานและเซสชันที่ใช้งานอยู่ด้วยแท็บ",
"help.tabs.toast.dismiss": "ปิดข้อมูลเกี่ยวกับแท็บ",
"help.tabs.title": "ขอแนะนำแท็บ",
"help.tabs.description": "จัดระเบียบงานและเซสชันที่ใช้งานอยู่ด้วยแท็บ",
"help.tabs.date": "14 กรกฎาคม",
"help.tabs.introduction": "ตอนนี้ OpenCode Desktop สร้างขึ้นโดยใช้แท็บเป็นหลัก",
"help.tabs.sessions":
"เริ่มเซสชันใหม่ในแท็บ หรือเปิดเซสชันที่มีอยู่จากโปรเจกต์ใดก็ได้ เปิดแท็บใหม่เมื่อเริ่มงานใหม่ และปิดเมื่อทำงานเสร็จ",
"help.tabs.organize":
"การเปิดแท็บไว้สองสามแท็บช่วยให้จัดระเบียบเซสชันที่ใช้งานอยู่ได้ง่ายขึ้น เปลี่ยนชื่อแท็บให้จดจำได้ง่ายหากต้องการเก็บแท็บไว้",
"help.tabs.home": "คุณจะพบเซสชันและโปรเจกต์ทั้งหมดในหน้าจอหน้าหลักแบบใหม่ เมื่อเลือกเซสชัน เซสชันนั้นจะเปิดในแท็บ",
"help.tabs.persistence": "เมื่อเปิดแอปอีกครั้ง แท็บของคุณจะยังคงเปิดอยู่",
"help.tabs.worktrees":
"การออกแบบใหม่ยังไม่รองรับ Git Worktrees แต่จะรองรับเร็ว ๆ นี้ ดังนั้น หากต้องการใช้เค้าโครงก่อนหน้าต่อ คุณสามารถสลับเค้าโครงได้ในการตั้งค่า โปรดทราบว่าเค้าโครงใหม่จะกลายเป็นเค้าโครงถาวรภายในอีกไม่กี่สัปดาห์",
"dialog.project.edit.title": "แก้ไขโปรเจกต์",
"dialog.project.edit.name": "ชื่อ",
"dialog.project.edit.icon": "ไอคอน",
@@ -450,7 +569,7 @@ export const dict = {
"context.breakdown.tool": "การเรียกเครื่องมือ",
"context.breakdown.other": "อื่น ๆ",
"context.systemPrompt.title": "พรอม์ระบบ",
"context.systemPrompt.title": "พรอม์ระบบ",
"context.rawMessages.title": "ข้อความดิบ",
"context.stats.session": "เซสชัน",
@@ -540,7 +659,7 @@ export const dict = {
"error.page.title": "เกิดข้อผิดพลาด",
"error.page.description": "เกิดข้อผิดพลาดระหว่างการโหลดแอปพลิเคชัน",
"error.page.description.localServerStartup": "เกิดข้อผิดพลาดขณะเริ่มเซิร์ฟเวอร์ในเครื่อง.",
"error.page.description.localServerStartup": "เกิดข้อผิดพลาดขณะเริ่มเซิร์ฟเวอร์ในเครื่อง",
"error.page.details.label": "รายละเอียดข้อผิดพลาด",
"error.page.action.restart": "รีสตาร์ท",
"error.page.action.report": "รายงานข้อผิดพลาด",
@@ -584,7 +703,7 @@ export const dict = {
"notification.question.description": "{{sessionTitle}} ใน {{projectName}} มีคำถาม",
"notification.action.goToSession": "ไปที่เซสชัน",
"notification.session.responseReady.title": "การตอบสนองพร้อม",
"notification.session.responseReady.title": "คำตอบพร้อมแล้ว",
"notification.session.error.title": "ข้อผิดพลาดเซสชัน",
"notification.session.error.fallbackDescription": "เกิดข้อผิดพลาด",
@@ -606,7 +725,7 @@ export const dict = {
"home.sessions.group.today": "วันนี้",
"home.sessions.group.yesterday": "เมื่อวาน",
"home.sessions.group.older": "ก่อนหน้านี้",
"home.providerTip": "เชื่อมต่อกับผู้ให้บริการกว่า 75 รายเพื่อใช้โมเดลอื่นๆ รวมถึง Claude, GPT, Gemini และอีกมากมาย",
"home.providerTip": "เชื่อมต่อกับผู้ให้บริการกว่า 75 รายเพื่อใช้โมเดลอื่น ๆ รวมถึง Claude, GPT, Gemini และอีกมากมาย",
"session.tab.session": "เซสชัน",
"session.tab.review": "ตรวจสอบ",
@@ -614,7 +733,7 @@ export const dict = {
"session.tab.unknown": "เซสชันที่ไม่รู้จัก",
"session.panel.reviewAndFiles": "ตรวจสอบและไฟล์",
"session.error.notFound": "ไม่พบเซสชันนี้",
"session.error.notFound.description": "แท็บนี้อ้างถึงเซสชันที่ไม่มีอยู่บนเซิร์ฟเวอร์นี้แล้ว.",
"session.error.notFound.description": "แท็บนี้อ้างถึงเซสชันที่ไม่มีอยู่บนเซิร์ฟเวอร์นี้แล้ว",
"session.error.notFound.closeTab": "ปิดแท็บ",
"session.error.serverConnection": "ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์นี้",
"session.review.filesChanged": "{{count}} ไฟล์ที่เปลี่ยนแปลง",
@@ -704,13 +823,19 @@ export const dict = {
"lsp.tooltip.none": "ไม่มีเซิร์ฟเวอร์ LSP",
"lsp.label.connected": "{{count}} LSP",
"prompt.loading": "กำลังโหลดพรอม์...",
"prompt.loading": "กำลังโหลดพรอม์...",
"terminal.loading": "กำลังโหลดเทอร์มินัล...",
"terminal.title": "เทอร์มินัล",
"terminal.title.numbered": "เทอร์มินัล {{number}}",
"terminal.close": "ปิดเทอร์มินัล",
"terminal.connectionLost.title": "การเชื่อมต่อขาดหาย",
"terminal.connectionLost.description": "การเชื่อมต่อเทอร์มินัลถูกขัดจังหวะ อาจเกิดขึ้นเมื่อเซิร์ฟเวอร์รีสตาร์ท",
"terminal.connectTicket.csrfError":
"ตั๋วเชื่อมต่อ PTY ถูกปฏิเสธโดยการตรวจสอบต้นทางหรือ CSRF โปรดตรวจสอบการกำหนดค่า CORS ของเซิร์ฟเวอร์",
"terminal.connectTicket.statusError": "ตั๋วเชื่อมต่อ PTY ล้มเหลวโดยมีสถานะ {{status}}",
"titlebar.update": "อัปเดต",
"titlebar.updateVersion": "อัปเดต {{version}}",
"common.closeTab": "ปิดแท็บ",
"common.dismiss": "ปิด",
@@ -767,23 +892,23 @@ export const dict = {
"settings.general.row.shell.autoDefault": "อัตโนมัติ (ค่าเริ่มต้น)",
"settings.general.row.shell.terminalOnly": "เทอร์มินัลเท่านั้น",
"settings.general.row.appearance.title": "รูปลักษณ์",
"settings.general.row.appearance.description": "ปรับแต่งวิธีการที่ OpenCode มีลักษณะบนอุปกรณ์ของคุณ",
"settings.general.row.appearance.description": "ปรับแต่งรูปลักษณ์ของ OpenCode บนอุปกรณ์ของคุณ",
"settings.general.row.colorScheme.title": "โทนสี",
"settings.general.row.colorScheme.description": "เลือกว่าจะให้ OpenCode ใช้ธีมตามระบบ สว่าง หรือมืด",
"settings.general.row.theme.title": "ธีม",
"settings.general.row.theme.description": "ปรับแต่งวิธีการที่ OpenCode มีธีม",
"settings.general.row.font.title": "ฟอนต์โค้ด",
"settings.general.row.font.description": "ปรับแต่งฟอนต์ที่ใช้ในบล็อกโค้ด",
"settings.general.row.terminalFont.title": "ฟอนต์เทอร์มินัล",
"settings.general.row.terminalFont.description": "ปรับแต่งฟอนต์ที่ใช้ในเทอร์มินัล",
"settings.general.row.uiFont.title": "ฟอนต์ UI",
"settings.general.row.uiFont.description": "ปรับแต่งฟอนต์ที่ใช้ทั่วทั้งอินเทอร์เฟซ",
"settings.general.row.theme.description": "ปรับแต่งธีมของ OpenCode",
"settings.general.row.font.title": "แบบอักษรโค้ด",
"settings.general.row.font.description": "ปรับแต่งแบบอักษรที่ใช้ในบล็อกโค้ด",
"settings.general.row.terminalFont.title": "แบบอักษรเทอร์มินัล",
"settings.general.row.terminalFont.description": "ปรับแต่งแบบอักษรที่ใช้ในเทอร์มินัล",
"settings.general.row.uiFont.title": "แบบอักษร UI",
"settings.general.row.uiFont.description": "ปรับแต่งแบบอักษรที่ใช้ทั่วทั้งอินเทอร์เฟซ",
"settings.general.row.followup.title": "พฤติกรรมการติดตามผล",
"settings.general.row.followup.description": "เลือกว่าจะให้พรอม์ติดตามผลทำงานทันทีหรือรอในคิว",
"settings.general.row.followup.description": "เลือกว่าจะให้พรอม์ติดตามผลทำงานทันทีหรือรอในคิว",
"settings.general.row.followup.option.queue": "คิว",
"settings.general.row.followup.option.steer": "นำทาง",
"settings.general.row.showFileTree.title": "ต้นไม้ไฟล์",
"settings.general.row.showFileTree.description": "แสดงแผงต้นไม้ไฟล์ในเซสชัน",
"settings.general.row.showFileTree.title": "แผนผังไฟล์",
"settings.general.row.showFileTree.description": "แสดงแผงแผนผังไฟล์ในเซสชัน",
"settings.general.row.showNavigation.title": "ตัวควบคุมการนำทาง",
"settings.general.row.showNavigation.description": "แสดงปุ่มย้อนกลับและไปข้างหน้าในแถบชื่อเรื่องเดสก์ท็อป",
"settings.general.row.showSearch.title": "ชุดคำสั่ง",
@@ -795,8 +920,9 @@ export const dict = {
"settings.general.row.mobileTitlebarBottom.title": "การนำทางด้านล่าง",
"settings.general.row.mobileTitlebarBottom.description":
"วางแถบชื่อเรื่องและแท็บเซสชันไว้ด้านล่างของหน้าจอบนอุปกรณ์เคลื่อนที่",
"settings.general.row.showCustomAgents.title": "เอเจนต์ที่กำหนดเอง",
"settings.general.row.showCustomAgents.description": "แสดงตัวเลือกเอเจนต์ในช่องเขียนข้อความ",
"settings.general.row.showCustomAgents.title": "แสดงเอเจนต์",
"settings.general.row.showCustomAgents.description":
"สลับระหว่างเอเจนต์ในช่องเขียนข้อความ เมื่อซ่อน ระบบจะใช้เอเจนต์ Build เป็นค่าเริ่มต้น",
"settings.general.row.reasoningSummaries.title": "แสดงสรุปการใช้เหตุผล",
"settings.general.row.reasoningSummaries.description": "แสดงสรุปการใช้เหตุผลของโมเดลในไทม์ไลน์",
"settings.general.row.shellToolPartsExpanded.title": "ขยายส่วนเครื่องมือ shell",
@@ -908,7 +1034,7 @@ export const dict = {
"settings.shortcuts.group.navigation": "การนำทาง",
"settings.shortcuts.group.modelAndAgent": "โมเดลและเอเจนต์",
"settings.shortcuts.group.terminal": "เทอร์มินัล",
"settings.shortcuts.group.prompt": "พรอม์",
"settings.shortcuts.group.prompt": "พรอม์",
"settings.providers.title": "ผู้ให้บริการ",
"settings.providers.description": "การตั้งค่าผู้ให้บริการจะสามารถกำหนดค่าได้ที่นี่",
@@ -945,7 +1071,7 @@ export const dict = {
"settings.permissions.tool.glob.description": "จับคู่ไฟล์โดยใช้รูปแบบ glob",
"settings.permissions.tool.grep.title": "Grep",
"settings.permissions.tool.grep.description": "ค้นหาเนื้อหาไฟล์โดยใช้นิพจน์ทั่วไป",
"settings.permissions.tool.list.title": "รายการ",
"settings.permissions.tool.list.title": "แสดงรายการ",
"settings.permissions.tool.list.description": "แสดงรายการไฟล์ภายในไดเรกทอรี",
"settings.permissions.tool.bash.title": "Bash",
"settings.permissions.tool.bash.description": "เรียกใช้คำสั่งเชลล์",
@@ -1018,13 +1144,16 @@ export const dict = {
"dialog.server.add.passwordPlaceholder": "รหัสผ่าน",
"server.row.noUsername": "ไม่มีชื่อผู้ใช้",
"session.review.noVcs.createGit.title": "สร้าง Git รีโพซิทอรี",
"session.review.noVcs.createGit.description": "ติดตาม ตรวจสอบ และเลิกทำสิ่งเปลี่ยนแปลงในโปรเจกต์นี้",
"session.review.noVcs.createGit.description": "ติดตาม ตรวจสอบ และเลิกทำการเปลี่ยนแปลงในโปรเจกต์นี้",
"session.review.noVcs.createGit.actionLoading": "กำลังสร้าง Git รีโพซิทอรี...",
"session.review.noVcs.createGit.action": "สร้าง Git รีโพซิทอรี",
"session.todo.progress": "เสร็จสิ้น {{done}} จาก {{total}} รายการ",
"session.question.progress": "{{current}} จาก {{total}} คำถาม",
"session.header.open.finder": "Finder",
"session.header.open.fileExplorer": "File Explorer",
"session.header.reveal.finder": "แสดงใน Finder",
"session.header.reveal.fileExplorer": "แสดงใน File Explorer",
"session.header.reveal.containingFolder": "เปิดโฟลเดอร์ที่มีรายการนี้",
"session.header.open.fileManager": "File Manager",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -1062,6 +1191,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "JS heap ที่ใช้เทียบกับขีดจำกัด heap เฉพาะ Chromium",
"debugBar.mem.tip": "JS heap ที่ใช้เทียบกับขีดจำกัด heap {{used}} จาก {{limit}}",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "บังคับใช้สไตล์โฟกัสกับองค์ประกอบแบบโต้ตอบทั้งหมด",
"debugBar.focus.on": "เปิด",
"debugBar.focus.off": "ปิด",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "บังคับกำหนดทิศทางเค้าโครงของทั้งแอปโดยไม่เปลี่ยนภาษาที่เลือก",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
+201 -61
View File
@@ -3,6 +3,106 @@ import { dict as en } from "./en"
type Keys = keyof typeof en
export const dict = {
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Dosya",
"desktop.menu.edit": "Düzen",
"desktop.menu.view": "Görünüm",
"desktop.menu.go": "Git",
"desktop.menu.window": "Pencere",
"desktop.menu.help": "Yardım",
"desktop.menu.checkForUpdates": "Güncellemeleri kontrol et...",
"desktop.menu.settings": "Ayarlar",
"desktop.menu.reloadWebview": "Web görünümünü yeniden yükle",
"desktop.menu.restart": "Yeniden başlat",
"desktop.menu.exportLogs": "Günlükleri dışa aktar...",
"desktop.menu.newSession": "Yeni oturum",
"desktop.menu.openProject": "Proje aç...",
"desktop.menu.newWindow": "Yeni pencere",
"desktop.menu.closeWindow": "Pencereyi kapat",
"desktop.menu.undo": "Geri al",
"desktop.menu.redo": "Yinele",
"desktop.menu.cut": "Kes",
"desktop.menu.copy": "Kopyala",
"desktop.menu.paste": "Yapıştır",
"desktop.menu.delete": "Sil",
"desktop.menu.selectAll": "Tümünü seç",
"desktop.menu.toggleSidebar": "Kenar çubuğunu aç/kapat",
"desktop.menu.toggleTerminal": "Terminali aç/kapat",
"desktop.menu.toggleFileTree": "Dosya ağacını aç/kapat",
"desktop.menu.reload": "Yeniden yükle",
"desktop.menu.toggleDeveloperTools": "Geliştirici araçlarını aç/kapat",
"desktop.menu.actualSize": "Gerçek boyut",
"desktop.menu.zoomIn": "Yakınlaştır",
"desktop.menu.zoomOut": "Uzaklaştır",
"desktop.menu.toggleFullScreen": "Tam ekranı aç/kapat",
"desktop.menu.back": "Geri",
"desktop.menu.forward": "İleri",
"desktop.menu.previousSession": "Önceki oturum",
"desktop.menu.nextSession": "Sonraki oturum",
"desktop.menu.previousProject": "Önceki proje",
"desktop.menu.nextProject": "Sonraki proje",
"desktop.menu.minimize": "Simge durumuna küçült",
"desktop.menu.maximize": "Ekranı kapla",
"desktop.menu.documentation": "OpenCode belgeleri",
"desktop.menu.supportForum": "Destek forumu",
"desktop.menu.shareFeedback": "Geri bildirim paylaş",
"desktop.menu.reportBug": "Hata bildir",
"desktop.menu.ariaLabel": "OpenCode menüsü",
"desktop.updater.dialog.checkFailed.message": "Güncellemeler kontrol edilemedi.",
"desktop.updater.dialog.checkFailed.title": "Güncelleme hatası",
"desktop.updater.dialog.upToDate.message": "En son sürümü kullanıyorsunuz.",
"desktop.updater.dialog.upToDate.title": "Güncelleme yok",
"desktop.updater.dialog.ready.message": "{{version}} güncellemesi indirildi. Şimdi yeniden başlatılsın mı?",
"desktop.updater.dialog.ready.title": "Güncelleme hazır",
"desktop.updater.dialog.restart": "Yeniden başlat",
"desktop.updater.dialog.later": "Daha sonra",
"desktop.recovery.action.relaunch": "Uygulamayı yeniden başlat",
"desktop.recovery.action.exportLogs": "Günlükleri dışa aktar",
"desktop.recovery.action.keepWaiting": "Beklemeye devam et",
"desktop.recovery.action.quit": "Çık",
"desktop.recovery.loadFailed": "OpenCode yüklenemedi",
"desktop.recovery.terminated": "OpenCode penceresi beklenmedik şekilde sonlandırıldı",
"desktop.recovery.unresponsive": "OpenCode yanıt vermiyor",
"desktop.recovery.unresponsive.detail":
"Uygulamayı yeniden başlatabilir, günlükleri açabilir veya beklemeye devam edebilirsiniz.",
"desktop.recovery.loadFailed.detail": "Pencere: {{window}}\nURL: {{url}}\nHata: {{code}} {{description}}",
"desktop.recovery.terminated.detail": "Pencere: {{window}}\nNeden: {{reason}}\nKod: {{code}}",
"desktop.recovery.unknown": "<bilinmiyor>",
"desktop.dialog.chooseFolder": "Bir klasör seçin",
"desktop.dialog.chooseFile": "Bir dosya seçin",
"desktop.dialog.saveFile": "Dosyayı kaydedin",
"desktop.dialog.files": "Dosyalar",
"desktop.server.local": "Yerel sunucu",
"desktop.wsl.error.windowsOnly": "WSL yalnızca Windows'ta kullanılabilir",
"desktop.wsl.error.unavailable": "WSL kullanılamıyor",
"desktop.wsl.error.listInstalled": "Kurulu WSL dağıtımları listelenemedi",
"desktop.wsl.error.listOnline": "Çevrimiçi WSL dağıtımları listelenemedi",
"desktop.wsl.error.executeDistro": "Dağıtımda komutlar çalıştırılamıyor",
"desktop.wsl.error.installWsl": "WSL kurulamadı",
"desktop.wsl.error.installDistro": "Dağıtım kurulamadı: {{distro}}",
"desktop.wsl.error.installOpencode": "OpenCode kurulamadı",
"desktop.wsl.error.alreadyAdded": "{{distro}} zaten eklendi",
"desktop.wsl.error.opencodeMissing": "opencode bu dağıtımda kurulu değil",
"desktop.wsl.error.opencodeCannotRun": "opencode kurulu ancak çalıştırılamadı",
"desktop.wsl.error.opencodeNotInstalled": "OpenCode, {{distro}} içinde kurulu değil",
"desktop.wsl.error.updateVersion":
"OpenCode güncellemesi tamamlandı ancak {{distro}} hâlâ {{installed}} sürümünü bildiriyor; beklenen sürüm: {{expected}}",
"desktop.wsl.error.noVersion": "sürüm yok",
"desktop.wsl.error.serverExited": "WSL sunucusu başlatıldıktan sonra kapandı (code={{code}} signal={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"WSL sunucusu kullanıma hazır duruma gelmeden kapandı (code={{code}} signal={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout":
"{{distro}} Sidecar sistem durumu denetimi {{timeout}} ms sonra zaman aşımına uğradı",
"desktop.wsl.error.commandTimeout": "{{command}} {{args}} komutu {{timeout}} ms sonra zaman aşımına uğradı",
"desktop.wsl.error.failedPort": "Bağlantı noktası alınamadı",
"desktop.picker.error.notSelected": "Dosya seçici tarafından dosya seçilmedi",
"desktop.picker.error.sizeLimit": "Seçilen ekler {{limit}} MB sınırını aşıyor",
"command.category.suggested": "Önerilen",
"command.category.view": "Görünüm",
"command.category.project": "Proje",
@@ -20,6 +120,7 @@ export const dict = {
"command.category.permissions": "İzinler",
"command.category.workspace": "Çalışma Alanı",
"command.category.settings": "Ayarlar",
"command.logs.export": "Günlükleri dışa aktar",
"theme.scheme.system": "Sistem",
"theme.scheme.light": "Açık",
@@ -78,9 +179,9 @@ export const dict = {
"command.model.variant.cycle": "Düşünme eforu değiştir",
"command.model.variant.cycle.description": "Sonraki efor seviyesine geç",
"command.prompt.mode.shell": "Kabuk",
"command.prompt.mode.normal": "Komut",
"command.permissions.autoaccept.enable": "Düzenlemeleri otomatik kabul et",
"command.permissions.autoaccept.disable": "Otomatik kabulü durdur",
"command.prompt.mode.normal": "İstem",
"command.permissions.autoaccept.enable": "İzinleri otomatik kabul et",
"command.permissions.autoaccept.disable": "İzinleri otomatik kabul etmeyi durdur",
"command.workspace.toggle": "Çalışma alanlarını aç/kapat",
"command.workspace.toggle.description": "Kenar çubuğunda birden fazla çalışma alanını göster veya gizle",
"command.session.undo": "Geri al",
@@ -106,9 +207,10 @@ export const dict = {
"dialog.provider.empty": "Sağlayıcı bulunamadı",
"dialog.provider.group.popular": "Popüler",
"dialog.provider.group.other": "Diğer",
"dialog.provider.custom.label": "Özel OpenAI uyumlu sağlayıcı",
"dialog.provider.tag.recommended": "Önerilen",
"dialog.provider.opencode.note": "Claude, GPT, Gemini ve daha fazlasını içeren seçilmiş modeller",
"dialog.provider.opencode.tagline": "Güvenilir optimize edilmiş modeller",
"dialog.provider.opencode.tagline": "Güvenilir, optimize edilmiş modeller",
"dialog.provider.opencodeGo.tagline": "Herkes için düşük maliyetli abonelik",
"dialog.provider.anthropic.note": "Pro ve Max dahil Claude modellerine doğrudan erişim",
"dialog.provider.copilot.note": "GitHub Copilot üzerinden kodlama yardımı için yapay zekâ modelleri",
@@ -126,6 +228,7 @@ export const dict = {
"dialog.model.unpaid.freeModels.title": "OpenCode tarafından sunulan ücretsiz modeller",
"dialog.model.unpaid.addMore.title": "Popüler sağlayıcılardan daha fazla model ekleyin",
"dialog.model.unpaid.viewMoreProviders": "70'ten fazla sağlayıcı daha görüntüle",
"dialog.provider.viewAll": "Daha fazla sağlayıcı göster",
@@ -133,6 +236,8 @@ export const dict = {
"provider.connect.title.anthropicProMax": "Claude Pro/Max ile giriş yap",
"provider.connect.selectMethod": "{{provider}} için giriş yöntemini seçin.",
"provider.connect.method.apiKey": "API anahtarı",
"provider.connect.method.browser": "Tarayıcı",
"provider.connect.method.headless": "Tarayıcısız",
"provider.connect.status.inProgress": "Yetkilendirme devam ediyor...",
"provider.connect.status.waiting": "Yetkilendirme bekleniyor...",
"provider.connect.status.failed": "Yetkilendirme başarısız: {{error}}",
@@ -165,10 +270,11 @@ export const dict = {
"provider.connect.toast.connected.description": "{{provider}} modelleri artık kullanımda.",
"provider.custom.title": "Özel sağlayıcı",
"provider.custom.unavailable": "Özel sağlayıcılar bu sunucuda kullanılamıyor",
"provider.custom.description.prefix": "OpenAI uyumlu bir sağlayıcı yapılandırın. ",
"provider.custom.description.link": "Sağlayıcı yapılandırma dökümanları",
"provider.custom.description.link": "sağlayıcı yapılandırma dokümanları",
"provider.custom.description.suffix": " sayfasına bakın.",
"provider.custom.field.providerID.label": "Sağlayıcı kimlik",
"provider.custom.field.providerID.label": "Sağlayıcı kimliği",
"provider.custom.field.providerID.placeholder": "saglayicim",
"provider.custom.field.providerID.description": "Küçük harfler, rakamlar, tire veya alt çizgi",
"provider.custom.field.name.label": "Görünen ad",
@@ -178,7 +284,7 @@ export const dict = {
"provider.custom.field.apiKey.label": "API anahtarı",
"provider.custom.field.apiKey.placeholder": "API anahtarı",
"provider.custom.field.apiKey.description":
"İsteğe bağlı. Kimlik doğrulamayı başlıklar ile yönetiyorsanız boş bırakın.",
"İsteğe bağlı. Kimlik doğrulamayı başlıklarla yönetiyorsanız boş bırakın.",
"provider.custom.models.label": "Modeller",
"provider.custom.models.id.label": "Kimlik",
"provider.custom.models.id.placeholder": "model-kimlik",
@@ -193,9 +299,9 @@ export const dict = {
"provider.custom.headers.value.placeholder": "değer",
"provider.custom.headers.remove": "Başlığı kaldır",
"provider.custom.headers.add": "Başlık ekle",
"provider.custom.error.providerID.required": "Sağlayıcı kimlik gerekli",
"provider.custom.error.providerID.required": "Sağlayıcı kimliği gerekli",
"provider.custom.error.providerID.format": "Küçük harf, rakam, tire veya alt çizgi kullanın",
"provider.custom.error.providerID.exists": "Bu sağlayıcı kimlik zaten mevcut",
"provider.custom.error.providerID.exists": "Bu sağlayıcı kimliği zaten mevcut",
"provider.custom.error.name.required": "Görünen ad gerekli",
"provider.custom.error.baseURL.required": "Temel URL gerekli",
"provider.custom.error.baseURL.format": "http:// veya https:// ile başlamalı",
@@ -203,7 +309,7 @@ export const dict = {
"provider.custom.error.duplicate": "Tekrar",
"provider.disconnect.toast.disconnected.title": "{{provider}} bağlantısı kesildi",
"provider.disconnect.toast.disconnected.description": "{{provider}} modelleri artık kullanılabilir değil.",
"provider.disconnect.toast.disconnected.description": "{{provider}} modelleri artık kullanılamıyor.",
"model.tag.free": "Ücretsiz",
"model.tag.latest": "En yeni",
@@ -223,9 +329,9 @@ export const dict = {
"model.tooltip.model": "Model",
"model.tooltip.provider": "Sağlayıcı",
"model.tooltip.reasoning": "Akıl yürütme",
"model.tooltip.reasoning.allowed": "Akıl yürütme destekler",
"model.tooltip.reasoning.allowed": "Akıl yürütmeyi destekler",
"model.tooltip.reasoning.none": "Akıl yürütme yok",
"model.tooltip.context": "Bağlam limiti {{limit}}",
"model.tooltip.context": "Bağlam sınırı {{limit}}",
"common.search.placeholder": "Ara",
"common.goBack": "Geri git",
@@ -235,8 +341,8 @@ export const dict = {
"common.cancel": "İptal",
"common.clear": "Temizle",
"common.connect": "Bağlan",
"common.disconnect": "Bağlantı Kes",
"common.continue": "Gönder",
"common.disconnect": "Bağlantıyı kes",
"common.continue": "Devam et",
"common.submit": "Gönder",
"common.save": "Kaydet",
"common.saving": "Kaydediliyor...",
@@ -249,7 +355,7 @@ export const dict = {
"prompt.placeholder.summarizeComments": "Yorumları özetle…",
"prompt.placeholder.summarizeComment": "Yorumu özetle…",
"prompt.mode.shell": "Kabuk",
"prompt.mode.normal": "Komut",
"prompt.mode.normal": "İstem",
"prompt.mode.shell.exit": "çıkmak için esc",
"session.child.promptDisabled": "Alt ajan oturumlarına istem gönderilemez.",
"session.child.backToParent": "Ana oturuma dön.",
@@ -266,30 +372,30 @@ export const dict = {
"prompt.example.10": "API dokümantasyonu oluştur",
"prompt.example.11": "Veritabanı sorgularını optimize et",
"prompt.example.12": "Girdi doğrulama ekle",
"prompt.example.13": "İçin yeni bir bileşen oluştur...",
"prompt.example.13": "... için yeni bir bileşen oluştur",
"prompt.example.14": "Bu projeyi nasıl dağıtabilirim?",
"prompt.example.15": "Kodumu en iyi uygulamalar için incele",
"prompt.example.16": "Bu fonksiyona hata yönetimi ekle",
"prompt.example.17": "Bu regex kalıbını açıkla",
"prompt.example.18": "Bunu TypeScript'e dönüştür",
"prompt.example.19": "Kod tabanı boyunca loglama ekle",
"prompt.example.19": "Kod tabanının tamamına günlük kaydı ekle",
"prompt.example.20": "Hangi bağımlılıklar güncellenmemiş?",
"prompt.example.21": "Bir göç betiği yazmama yardım et",
"prompt.example.21": "Bir geçiş betiği yazmama yardım et",
"prompt.example.22": "Bu uç nokta için önbellekleme uygula",
"prompt.example.23": "Bu listeye sayfalama ekle",
"prompt.example.24": "İçin bir CLI komutu oluştur...",
"prompt.example.24": "... için bir CLI komutu oluştur",
"prompt.example.25": "Ortam değişkenleri burada nasıl çalışıyor?",
"prompt.popover.emptyResults": "Eşleşen sonuç yok",
"prompt.popover.emptyCommands": "Eşleşen komut yok",
"prompt.dropzone.label": "Resimleri, PDF'leri veya metin dosyalarını buraya bırakın",
"prompt.dropzone.file.label": "@bahsetmek için dosyayı bırakın",
"prompt.dropzone.file.label": "Dosyayı @ ile belirtmek için buraya bırakın",
"prompt.slash.badge.custom": "özel",
"prompt.slash.badge.skill": "beceri",
"prompt.slash.badge.mcp": "mcp",
"prompt.context.active": "aktif",
"prompt.context.includeActiveFile": "Aktif dosyayı dahil et",
"prompt.context.removeActiveFile": "Aktif dosyayı bağlamdan çıkar",
"prompt.context.active": "etkin",
"prompt.context.includeActiveFile": "Etkin dosyayı dahil et",
"prompt.context.removeActiveFile": "Etkin dosyayı bağlamdan çıkar",
"prompt.context.removeFile": "Dosyayı bağlamdan çıkar",
"prompt.action.attachFile": "Dosya ekle",
"prompt.menu.addImagesAndFiles": "Dosya ve daha fazlasını ekle",
@@ -305,16 +411,16 @@ export const dict = {
"prompt.toast.attachmentDuplicate.title": "Bu dosya zaten yüklendi",
"prompt.toast.pasteUnsupported.description": "Buraya yalnızca resimler, PDF'ler veya metin dosyaları eklenebilir.",
"prompt.toast.modelAgentRequired.title": "Bir ajan ve model seçin",
"prompt.toast.modelAgentRequired.description": "Komut göndermeden önce bir ajan ve model seçin.",
"prompt.toast.modelAgentRequired.description": "İstem göndermeden önce bir ajan ve model seçin.",
"prompt.toast.worktreeCreateFailed.title": "Çalışma ağacı oluşturulamadı",
"prompt.toast.sessionCreateFailed.title": "Oturum oluşturulamadı",
"prompt.toast.shellSendFailed.title": "Kabuk komutu gönderilemedi",
"prompt.toast.commandSendFailed.title": "Komut gönderilemedi",
"prompt.toast.promptSendFailed.title": "Komut gönderilemedi",
"prompt.toast.promptSendFailed.title": "İstem gönderilemedi",
"prompt.toast.promptSendFailed.description": "Oturum alınamadı",
"dialog.mcp.title": "MCP'ler",
"dialog.mcp.description": "{{total}} içerisinden {{enabled}} etkin",
"dialog.mcp.description": "Toplam {{total}} öğeden {{enabled}} tanesi etkin",
"dialog.mcp.empty": "Yapılandırılmış MCP yok",
"dialog.lsp.empty": "LSP'ler dosya türlerinden otomatik algılanır",
@@ -349,7 +455,7 @@ export const dict = {
"dialog.server.add.name": "Sunucu adı (isteğe bağlı)",
"dialog.server.add.namePlaceholder": "Localhost",
"dialog.server.add.username": "Kullanıcı adı (isteğe bağlı)",
"dialog.server.add.password": "Şifre (isteğe bağlı)",
"dialog.server.add.password": "Parola (isteğe bağlı)",
"dialog.server.edit.title": "Sunucuyu düzenle",
"dialog.server.default.title": "Varsayılan sunucu",
"dialog.server.default.description":
@@ -435,6 +541,22 @@ export const dict = {
"wsl.onboarding.versionMismatch": "Kurulu sürüm masaüstü uygulamasının sürümüyle eşleşmiyor.",
"wsl.onboarding.adding": "Ekleniyor...",
"help.tabs.toast.ariaLabel": "Sekmelerle tanışın. Çalışmalarınızı ve etkin oturumlarınızı sekmelerle düzenleyin",
"help.tabs.toast.dismiss": "Sekmeler bilgilerini kapat",
"help.tabs.title": "Sekmelerle tanışın",
"help.tabs.description": "Çalışmalarınızı ve etkin oturumlarınızı sekmelerle düzenleyin",
"help.tabs.date": "14 Temmuz",
"help.tabs.introduction": "OpenCode Desktop artık sekmeler üzerine kurulu.",
"help.tabs.sessions":
"Bir sekmede yeni oturum başlatın veya projelerinizden mevcut bir oturumu açın. Yeni bir işe başlarken yeni sekme açın, işiniz bittiğinde sekmeyi kapatın.",
"help.tabs.organize":
"Birkaç sekmeyi açık tutmak, etkin oturumlarınızı düzenlemenizi kolaylaştırır. Sekmeleri açık tutmayı planlıyorsanız onlara akılda kalıcı adlar verin.",
"help.tabs.home":
"Tüm oturumlarınızı ve projelerinizi yeni Ana Sayfa ekranında bulabilirsiniz. Bir oturum seçtiğinizde oturum bir sekmede açılır.",
"help.tabs.persistence": "Uygulamayı yeniden açtığınızda sekmeleriniz açık kalır.",
"help.tabs.worktrees":
"Yeni tasarım henüz Git Worktrees'i desteklemiyor; bu özellik yakında kullanıma sunulacak. Önceki düzeni kullanmaya devam etmek isterseniz Ayarlar'da düzenler arasında geçiş yapabilirsiniz. Yeni düzenin birkaç hafta içinde kalıcı olacağını unutmayın.",
"dialog.project.edit.title": "Projeyi düzenle",
"dialog.project.edit.name": "Ad",
"dialog.project.edit.icon": "Simge",
@@ -455,14 +577,14 @@ export const dict = {
"context.breakdown.tool": "Araç Çağrıları",
"context.breakdown.other": "Diğer",
"context.systemPrompt.title": "Sistem Komutu",
"context.systemPrompt.title": "Sistem İstemi",
"context.rawMessages.title": "Ham mesajlar",
"context.stats.session": "Oturum",
"context.stats.messages": "Mesajlar",
"context.stats.provider": "Sağlayıcı",
"context.stats.model": "Model",
"context.stats.limit": "Bağlam Limiti",
"context.stats.limit": "Bağlam Sınırı",
"context.stats.totalTokens": "Toplam Token",
"context.stats.usage": "Kullanım",
"context.stats.inputTokens": "Girdi Tokenleri",
@@ -472,7 +594,7 @@ export const dict = {
"context.stats.userMessages": "Kullanıcı Mesajları",
"context.stats.assistantMessages": "Asistan Mesajları",
"context.stats.totalCost": "Toplam Maliyet",
"context.stats.sessionCreated": "Oturum Oluşturulma",
"context.stats.sessionCreated": "Oturum Oluşturma",
"context.stats.lastActivity": "Son Etkinlik",
"context.usage.tokens": "Tokenler",
@@ -511,10 +633,10 @@ export const dict = {
"toast.workspace.disabled.title": "Çalışma alanları devre dışı bırakıldı",
"toast.workspace.disabled.description": "Kenar çubuğunda yalnızca ana çalışma ağacı gösterilecek",
"toast.permissions.autoaccept.on.title": "Düzenlemeler otomatik kabul ediliyor",
"toast.permissions.autoaccept.on.description": "Düzenleme ve yazma izinleri otomatik olarak onaylanacak",
"toast.permissions.autoaccept.off.title": "Otomatik kabul durduruldu",
"toast.permissions.autoaccept.off.description": "Düzenleme ve yazma izinleri onay gerektirecek",
"toast.permissions.autoaccept.on.title": "İzinler otomatik kabul ediliyor",
"toast.permissions.autoaccept.on.description": "İzin istekleri otomatik olarak onaylanacak",
"toast.permissions.autoaccept.off.title": "İzinleri otomatik kabul etme durduruldu",
"toast.permissions.autoaccept.off.description": "İzin istekleri onay gerektirecek",
"toast.model.none.title": "Model seçilmedi",
"toast.model.none.description": "Bu oturumu özetlemek için bir sağlayıcı bağlayın",
@@ -554,8 +676,8 @@ export const dict = {
"error.page.action.checking": "Kontrol ediliyor...",
"error.page.action.checkUpdates": "Güncellemeleri kontrol et",
"error.page.action.updateTo": "{{version}} sürümüne güncelle",
"error.page.report.prefix": "Lütfen bu hatayı OpenCode ekibine bildirin",
"error.page.report.discord": "Discord üzerinden",
"error.page.report.prefix": "Lütfen bu hatayı OpenCode ekibine",
"error.page.report.discord": "Discord üzerinden bildirin",
"error.page.version": "Sürüm: {{version}}",
"error.dev.rootNotFound":
@@ -572,9 +694,9 @@ export const dict = {
"error.chain.responseBody": "Yanıt gövdesi:\n{{body}}",
"error.chain.didYouMean": "Bunu mu demek istediniz: {{suggestions}}",
"error.chain.modelNotFound": "Model bulunamadı: {{provider}}/{{model}}",
"error.chain.checkConfig": "Yapılandırma dosyanızı (opencode.json) sağlayıcı/model adlarını kontrol edin",
"error.chain.checkConfig": "Yapılandırma dosyanızdaki (opencode.json) sağlayıcı/model adlarını kontrol edin",
"error.chain.mcpFailed":
'MCP sunucusu "{{name}}" başarısız oldu. Not: OpenCode henüz MCP kimlik doğrulamasını desteklemiyor.',
'MCP sunucusu "{{name}}" çalıştırılamadı. Not: OpenCode henüz MCP kimlik doğrulamasını desteklemiyor.',
"error.chain.providerAuthFailed": "Sağlayıcı kimlik doğrulaması başarısız ({{provider}}): {{message}}",
"error.chain.providerInitFailed":
'"{{provider}}" sağlayıcısı başlatılamadı. Kimlik bilgilerini ve yapılandırmayı kontrol edin.',
@@ -624,9 +746,9 @@ export const dict = {
"session.panel.reviewAndFiles": "İnceleme ve dosyalar",
"session.error.notFound": "Bu oturum bulunamıyor",
"session.error.notFound.description": "Bu sekme, artık bu sunucuda bulunmayan bir oturuma yönlendiriyor.",
"session.error.notFound.closeTab": "Sekmeyi Kapat",
"session.error.notFound.closeTab": "Sekmeyi kapat",
"session.error.serverConnection": "Bu sunucuya bağlanılamıyor",
"session.review.filesChanged": "{{count}} Dosya Değişti",
"session.review.filesChanged": "{{count}} dosya değişti",
"session.review.change.one": "Değişiklik",
"session.review.change.other": "Değişiklik",
"session.review.loadingChanges": "Değişiklikler yükleniyor...",
@@ -635,7 +757,7 @@ export const dict = {
"session.review.noSnapshot":
"Yapılandırmada anlık görüntü takibi devre dışı bırakıldı, bu nedenle oturum değişiklikleri kullanılamıyor",
"session.review.noChanges": "Değişiklik yok",
"session.review.noUncommittedChanges": "Henüz commit edilmemiş değişiklik yok",
"session.review.noUncommittedChanges": "Henüz işlenmemiş değişiklik yok",
"session.review.noBranchChanges": "Henüz dal değişikliği yok",
"session.files.selectToOpen": "Açmak için bir dosya seçin",
@@ -669,7 +791,7 @@ export const dict = {
"session.revertDock.expand": "Geri alınan mesajları genişlet",
"session.revertDock.restore": "Mesajı geri yükle",
"session.new.title": "İstediğini yap",
"session.new.title": "Her şeyi geliştirin",
"session.new.project.new": "Yeni proje",
"session.new.project.search": "Proje ara",
"session.new.project.add": "Proje ekle",
@@ -690,6 +812,9 @@ export const dict = {
"session.header.open.ariaLabel": "{{app}} ile aç",
"session.header.open.menu": "Açma seçenekleri",
"session.header.open.copyPath": "Yolu kopyala",
"session.header.reveal.finder": "Finder'da göster",
"session.header.reveal.fileExplorer": "Dosya Gezgini'nde göster",
"session.header.reveal.containingFolder": "İçeren klasörü aç",
"status.popover.trigger": "Durum",
"status.popover.ariaLabel": "Sunucu yapılandırmaları",
@@ -710,19 +835,25 @@ export const dict = {
"session.share.action.unpublishing": "Yayından kaldırılıyor...",
"session.share.action.view": "Görüntüle",
"session.share.copy.copied": "Kopyalandı",
"session.share.copy.copyLink": "Bağlantı kopyala",
"session.share.copy.copyLink": "Bağlantıyı kopyala",
"lsp.tooltip.none": "LSP sunucusu yok",
"lsp.label.connected": "{{count}} LSP",
"prompt.loading": "Komut yükleniyor...",
"prompt.loading": "İstem yükleniyor...",
"terminal.loading": "Terminal yükleniyor...",
"terminal.title": "Terminal",
"terminal.title.numbered": "Terminal {{number}}",
"terminal.close": "Terminali kapat",
"terminal.connectionLost.title": "Bağlantı Kesildi",
"terminal.connectionLost.title": "Bağlantı kesildi",
"terminal.connectionLost.description":
"Terminal bağlantısı kesildi. Bu durum sunucu yeniden başladığında oluşabilir.",
"terminal.connectTicket.csrfError":
"PTY bağlantı bileti, kaynak veya CSRF denetimleri tarafından reddedildi. Sunucunun CORS yapılandırmasını kontrol edin.",
"terminal.connectTicket.statusError": "PTY bağlantı bileti {{status}} durumuyla başarısız oldu",
"titlebar.update": "Güncelle",
"titlebar.updateVersion": "Güncelle {{version}}",
"common.closeTab": "Sekmeyi kapat",
"common.dismiss": "Kapat",
@@ -785,15 +916,15 @@ export const dict = {
"OpenCode'un sistem, açık veya koyu temayı takip etip etmeyeceğini seçin",
"settings.general.row.theme.title": "Tema",
"settings.general.row.theme.description": "OpenCode'un temasını özelleştirin.",
"settings.general.row.font.title": "Kod Yazı Tipi",
"settings.general.row.font.title": "Kod yazı tipi",
"settings.general.row.font.description": "Kod bloklarında kullanılan yazı tipini özelleştirin",
"settings.general.row.terminalFont.title": "Terminal yazı tipi",
"settings.general.row.terminalFont.description": "Terminalde kullanılan yazı tipini özelleştirin",
"settings.general.row.uiFont.title": "Arayüz Yazı Tipi",
"settings.general.row.uiFont.title": "Arayüz yazı tipi",
"settings.general.row.uiFont.description": "Arayüz genelinde kullanılan yazı tipini özelleştirin",
"settings.general.row.followup.title": "Takip davranışı",
"settings.general.row.followup.description":
"Takip komutlarının hemen yönlendirilmesini mi yoksa sırada beklemesini mi istediğinizi seçin",
"Takip istemlerinin hemen yönlendirilmesini mi yoksa sırada beklemesini mi istediğinizi seçin",
"settings.general.row.followup.option.queue": "Sıra",
"settings.general.row.followup.option.steer": "Yönlendir",
"settings.general.row.showFileTree.title": "Dosya ağacı",
@@ -809,8 +940,9 @@ export const dict = {
"settings.general.row.mobileTitlebarBottom.title": "Alt gezinme",
"settings.general.row.mobileTitlebarBottom.description":
"Mobil cihazlarda başlık çubuğunu ve oturum sekmelerini ekranın altına yerleştir",
"settings.general.row.showCustomAgents.title": "Özel ajanlar",
"settings.general.row.showCustomAgents.description": "Yazma alanında ajan seçiciyi göster",
"settings.general.row.showCustomAgents.title": "Ajanı göster",
"settings.general.row.showCustomAgents.description":
"Düzenleyicide ajanlar arasında geçiş yapın. Gizlendiğinde varsayılan olarak Build ajanı kullanılır.",
"settings.general.row.reasoningSummaries.title": "Akıl yürütme özetlerini göster",
"settings.general.row.reasoningSummaries.description": "Zaman çizelgesinde model akıl yürütme özetlerini görüntüle",
"settings.general.row.shellToolPartsExpanded.title": "Kabuk araç bileşenlerini genişlet",
@@ -834,7 +966,7 @@ export const dict = {
"settings.general.row.wayland.description":
"Wayland'da X11 geri dönüşünü devre dışı bırak. Yeniden başlatma gerektirir.",
"settings.general.row.wayland.tooltip":
"Karışık yenileme hızlı monitörlere sahip Linux'ta yerel Wayland daha kararlı olabilir.",
"Farklı yenileme hızlarına sahip monitörlerin kullanıldığı Linux sistemlerinde yerel Wayland daha kararlı olabilir.",
"settings.general.row.releaseNotes.title": "Sürüm notları",
"settings.general.row.releaseNotes.description": "Güncellemelerden sonra Yenilikler bildirimlerini göster",
@@ -928,7 +1060,7 @@ export const dict = {
"settings.shortcuts.group.navigation": "Gezinme",
"settings.shortcuts.group.modelAndAgent": "Model ve ajan",
"settings.shortcuts.group.terminal": "Terminal",
"settings.shortcuts.group.prompt": "Komut",
"settings.shortcuts.group.prompt": "İstem",
"settings.providers.title": "Sağlayıcılar",
"settings.providers.description": "Sağlayıcı ayarları burada yapılandırılabilecek.",
@@ -953,7 +1085,7 @@ export const dict = {
"settings.permissions.section.tools": "Araçlar",
"settings.permissions.toast.updateFailed.title": "İzinler güncellenemedi",
"settings.permissions.action.allow": "İzin Ver",
"settings.permissions.action.allow": "İzin ver",
"settings.permissions.action.ask": "Sor",
"settings.permissions.action.deny": "Reddet",
@@ -993,7 +1125,7 @@ export const dict = {
"workspace.new": "Yeni çalışma alanı",
"workspace.type.local": "yerel",
"workspace.type.sandbox": "sandbox",
"workspace.type.sandbox": "korumalı alan",
"workspace.create.failed.title": "Çalışma alanı oluşturulamadı",
"workspace.delete.failed.title": "Çalışma alanı silinemedi",
"workspace.resetting.title": "Çalışma alanı sıfırlanıyor",
@@ -1025,9 +1157,9 @@ export const dict = {
"error.server.invalidConfiguration": "Geçersiz yapılandırma",
"common.moreCountSuffix": " (+{{count}} daha)",
"common.time.justNow": "Şimdi",
"common.time.minutesAgo.short": "{{count}}dk önce",
"common.time.hoursAgo.short": "{{count}}sa önce",
"common.time.daysAgo.short": "{{count}}g önce",
"common.time.minutesAgo.short": "{{count}} dk önce",
"common.time.hoursAgo.short": "{{count}} sa önce",
"common.time.daysAgo.short": "{{count}} gün önce",
"settings.providers.connected.environmentDescription": "Ortam değişkenlerinizden bağlandı",
"settings.providers.custom.description": "Temel URL üzerinden OpenAI uyumlu bir sağlayıcı ekleyin.",
@@ -1065,7 +1197,7 @@ export const dict = {
"debugBar.nav.tip":
"Yönlendirici başlangıcından yerleşme sonrası ilk boyamaya kadar ölçülen, bir oturum sayfasına dokunan son tamamlanmış rota geçişi.",
"debugBar.fps.label": "FPS",
"debugBar.fps.tip": "Son 5 saniyedeki kayan saniye başına kare sayısı.",
"debugBar.fps.tip": "Son 5 saniyedeki hareketli saniye başına kare ortalaması.",
"debugBar.frame.label": "FRAME",
"debugBar.frame.tip": "Son 5 saniyedeki en kötü kare süresi.",
"debugBar.jank.label": "JANK",
@@ -1079,14 +1211,22 @@ export const dict = {
"debugBar.cls.label": "CLS",
"debugBar.cls.tip": "Mevcut uygulama ömrü için kümülatif düzen kayması.",
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Kullanılan JS yığını vs yığın sınırı. Yalnızca Chromium.",
"debugBar.mem.tip": "Kullanılan JS yığını vs yığın sınırı. {{limit}} içinde {{used}}.",
"debugBar.mem.tipUnavailable": "Kullanılan JS yığınının yığın sınırına oranı. Yalnızca Chromium.",
"debugBar.mem.tip": "Kullanılan JS yığınının yığın sınırına oranı: {{used}} / {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Tüm etkileşimli öğelere odak stillerini zorla uygula",
"debugBar.focus.on": "AÇIK",
"debugBar.focus.off": "KAPALI",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Seçili dili değiştirmeden tüm uygulamanın düzen yönünü zorla ayarla",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
"common.key.meta": "Meta",
"common.key.space": "Boşluk",
"common.key.backspace": "Geri",
"common.key.backspace": "Geri Al",
"common.key.enter": "Enter",
"common.key.tab": "Tab",
"common.key.delete": "Delete",
+182 -34
View File
@@ -1,4 +1,104 @@
export const dict = {
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "Файл",
"desktop.menu.edit": "Редагування",
"desktop.menu.view": "Вигляд",
"desktop.menu.go": "Перехід",
"desktop.menu.window": "Вікно",
"desktop.menu.help": "Довідка",
"desktop.menu.checkForUpdates": "Перевірити наявність оновлень...",
"desktop.menu.settings": "Налаштування",
"desktop.menu.reloadWebview": "Перезавантажити вебподання",
"desktop.menu.restart": "Перезапустити",
"desktop.menu.exportLogs": "Експортувати журнали...",
"desktop.menu.newSession": "Нова сесія",
"desktop.menu.openProject": "Відкрити проєкт...",
"desktop.menu.newWindow": "Нове вікно",
"desktop.menu.closeWindow": "Закрити вікно",
"desktop.menu.undo": "Скасувати",
"desktop.menu.redo": "Повторити",
"desktop.menu.cut": "Вирізати",
"desktop.menu.copy": "Копіювати",
"desktop.menu.paste": "Вставити",
"desktop.menu.delete": "Видалити",
"desktop.menu.selectAll": "Вибрати все",
"desktop.menu.toggleSidebar": "Перемкнути бічну панель",
"desktop.menu.toggleTerminal": "Перемкнути термінал",
"desktop.menu.toggleFileTree": "Перемкнути дерево файлів",
"desktop.menu.reload": "Перезавантажити",
"desktop.menu.toggleDeveloperTools": "Перемкнути інструменти розробника",
"desktop.menu.actualSize": "Фактичний розмір",
"desktop.menu.zoomIn": "Збільшити",
"desktop.menu.zoomOut": "Зменшити",
"desktop.menu.toggleFullScreen": "Перемкнути повноекранний режим",
"desktop.menu.back": "Назад",
"desktop.menu.forward": "Вперед",
"desktop.menu.previousSession": "Попередня сесія",
"desktop.menu.nextSession": "Наступна сесія",
"desktop.menu.previousProject": "Попередній проєкт",
"desktop.menu.nextProject": "Наступний проєкт",
"desktop.menu.minimize": "Згорнути",
"desktop.menu.maximize": "Розгорнути",
"desktop.menu.documentation": "Документація OpenCode",
"desktop.menu.supportForum": "Форум підтримки",
"desktop.menu.shareFeedback": "Надіслати відгук",
"desktop.menu.reportBug": "Повідомити про помилку",
"desktop.menu.ariaLabel": "Меню OpenCode",
"desktop.updater.dialog.checkFailed.message": "Не вдалося перевірити наявність оновлень.",
"desktop.updater.dialog.checkFailed.title": "Помилка оновлення",
"desktop.updater.dialog.upToDate.message": "У вас найновіша версія.",
"desktop.updater.dialog.upToDate.title": "Оновлень немає",
"desktop.updater.dialog.ready.message": "Оновлення {{version}} завантажено. Перезапустити зараз?",
"desktop.updater.dialog.ready.title": "Оновлення готове",
"desktop.updater.dialog.restart": "Перезапустити",
"desktop.updater.dialog.later": "Пізніше",
"desktop.recovery.action.relaunch": "Запустити повторно",
"desktop.recovery.action.exportLogs": "Експортувати журнали",
"desktop.recovery.action.keepWaiting": "Продовжити очікування",
"desktop.recovery.action.quit": "Завершити роботу",
"desktop.recovery.loadFailed": "Не вдалося завантажити OpenCode",
"desktop.recovery.terminated": "Роботу вікна OpenCode несподівано завершено",
"desktop.recovery.unresponsive": "OpenCode не відповідає",
"desktop.recovery.unresponsive.detail":
"Ви можете повторно запустити програму, відкрити журнали або продовжити очікування.",
"desktop.recovery.loadFailed.detail": "Вікно: {{window}}\nURL: {{url}}\nПомилка: {{code}} {{description}}",
"desktop.recovery.terminated.detail": "Вікно: {{window}}\nПричина: {{reason}}\nКод: {{code}}",
"desktop.recovery.unknown": "<невідомо>",
"desktop.dialog.chooseFolder": "Виберіть папку",
"desktop.dialog.chooseFile": "Виберіть файл",
"desktop.dialog.saveFile": "Зберегти файл",
"desktop.dialog.files": "Файли",
"desktop.server.local": "Локальний сервер",
"desktop.wsl.error.windowsOnly": "WSL доступна лише у Windows",
"desktop.wsl.error.unavailable": "WSL недоступна",
"desktop.wsl.error.listInstalled": "Не вдалося отримати список встановлених дистрибутивів WSL",
"desktop.wsl.error.listOnline": "Не вдалося отримати список доступних онлайн дистрибутивів WSL",
"desktop.wsl.error.executeDistro": "Не вдалося виконати команди в дистрибутиві",
"desktop.wsl.error.installWsl": "Не вдалося встановити WSL",
"desktop.wsl.error.installDistro": "Не вдалося встановити дистрибутив: {{distro}}",
"desktop.wsl.error.installOpencode": "Не вдалося встановити OpenCode",
"desktop.wsl.error.alreadyAdded": "{{distro}} уже додано",
"desktop.wsl.error.opencodeMissing": "opencode не встановлено в цьому дистрибутиві",
"desktop.wsl.error.opencodeCannotRun": "opencode встановлено, але його не вдалося запустити",
"desktop.wsl.error.opencodeNotInstalled": "OpenCode не встановлено в {{distro}}",
"desktop.wsl.error.updateVersion":
"Оновлення OpenCode завершено, але {{distro}} усе ще повідомляє про версію {{installed}}; очікувалася {{expected}}",
"desktop.wsl.error.noVersion": "версію не вказано",
"desktop.wsl.error.serverExited": "Сервер WSL завершив роботу після запуску (code={{code}} signal={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"Сервер WSL завершив роботу, не досягнувши працездатного стану (code={{code}} signal={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout":
"Час очікування перевірки працездатності sidecar для {{distro}} минув через {{timeout}}мс",
"desktop.wsl.error.commandTimeout": "Час очікування {{command}} {{args}} минув через {{timeout}}мс",
"desktop.wsl.error.failedPort": "Не вдалося отримати порт",
"desktop.picker.error.notSelected": "Засіб вибору не повернув вибраний файл",
"desktop.picker.error.sizeLimit": "Вибрані вкладення перевищують обмеження в {{limit}} МБ",
"command.category.suggested": "Рекомендовані",
"command.category.view": "Вигляд",
"command.category.project": "Проєкт",
@@ -16,6 +116,7 @@ export const dict = {
"command.category.permissions": "Дозволи",
"command.category.workspace": "Робоча область",
"command.category.settings": "Налаштування",
"command.logs.export": "Експортувати журнали",
"theme.scheme.system": "Системна",
"theme.scheme.light": "Світла",
@@ -102,26 +203,28 @@ export const dict = {
"dialog.provider.empty": "Провайдерів не знайдено",
"dialog.provider.group.popular": "Популярні",
"dialog.provider.group.other": "Інші",
"dialog.provider.custom.label": "Користувацький провайдер, сумісний з OpenAI",
"dialog.provider.tag.recommended": "Рекомендовані",
"dialog.provider.opencode.note": "Відібрані моделі, включаючи Claude, GPT, Gemini та інші",
"dialog.provider.opencode.tagline": "Надійні оптимізовані моделі",
"dialog.provider.opencodeGo.tagline": "Недорога підписка для всіх",
"dialog.provider.anthropic.note": "Прямий доступ до моделей Claude, включаючи Pro та Max",
"dialog.provider.copilot.note": "Моделі AI для допомоги в кодуванні через GitHub Copilot",
"dialog.provider.openai.note": "Моделі GPT для швидких і універсальних завдань AI",
"dialog.provider.copilot.note": "Моделі ШІ для допомоги в кодуванні через GitHub Copilot",
"dialog.provider.openai.note": "Моделі GPT для швидких і універсальних завдань ШІ",
"dialog.provider.google.note": "Моделі Gemini для швидких структурованих відповідей",
"dialog.provider.openrouter.note": "Доступ до всіх підтримуваних моделей від одного провайдера",
"dialog.provider.vercel.note": "Уніфікований доступ до моделей AI з інтелектуальною маршрутизацією",
"dialog.provider.vercel.note": "Уніфікований доступ до моделей ШІ з інтелектуальною маршрутизацією",
"dialog.model.select.title": "Вибрати модель",
"dialog.model.search.placeholder": "Пошук моделей",
"dialog.model.empty": "Немає результатів моделей",
"dialog.model.empty": "Моделей не знайдено",
"dialog.model.manage": "Керувати моделями",
"dialog.model.manage.description": "Налаштуйте, які моделі відображатимуться у виборі моделей.",
"dialog.model.manage.provider.toggle": "Перемкнути всі моделі {{provider}}",
"dialog.model.unpaid.freeModels.title": "Безкоштовні моделі від OpenCode",
"dialog.model.unpaid.addMore.title": "Додати більше моделей від популярних провайдерів",
"dialog.model.unpaid.viewMoreProviders": "Переглянути ще понад 70 провайдерів",
"dialog.provider.viewAll": "Показати більше провайдерів",
@@ -129,6 +232,8 @@ export const dict = {
"provider.connect.title.anthropicProMax": "Увійти з Claude Pro/Max",
"provider.connect.selectMethod": "Виберіть спосіб входу для {{provider}}.",
"provider.connect.method.apiKey": "Ключ API",
"provider.connect.method.browser": "Браузер",
"provider.connect.method.headless": "Без графічного інтерфейсу",
"provider.connect.status.inProgress": "Авторизація виконується...",
"provider.connect.status.waiting": "Очікування авторизації...",
"provider.connect.status.failed": "Авторизація не вдалася: {{error}}",
@@ -161,6 +266,7 @@ export const dict = {
"provider.connect.toast.connected.description": "Моделі {{provider}} тепер доступні для використання.",
"provider.custom.title": "Користувацький провайдер",
"provider.custom.unavailable": "Користувацькі провайдери недоступні на цьому сервері",
"provider.custom.description.prefix": "Налаштуйте провайдера, сумісного з OpenAI. Перегляньте ",
"provider.custom.description.link": "документацію з налаштування провайдера",
"provider.custom.description.suffix": ".",
@@ -168,7 +274,7 @@ export const dict = {
"provider.custom.field.providerID.placeholder": "myprovider",
"provider.custom.field.providerID.description": "Малі літери, цифри, дефіси або підкреслення",
"provider.custom.field.name.label": "Відображувана назва",
"provider.custom.field.name.placeholder": "Мій AI Провайдер",
"provider.custom.field.name.placeholder": "Мій провайдер ШІ",
"provider.custom.field.baseURL.label": "Базовий URL",
"provider.custom.field.baseURL.placeholder": "https://api.myprovider.com/v1",
"provider.custom.field.apiKey.label": "Ключ API",
@@ -189,7 +295,7 @@ export const dict = {
"provider.custom.headers.value.placeholder": "значення",
"provider.custom.headers.remove": "Видалити заголовок",
"provider.custom.headers.add": "Додати заголовок",
"provider.custom.error.providerID.required": "ID провайдера обов'язкове",
"provider.custom.error.providerID.required": "ID провайдера обов'язковий",
"provider.custom.error.providerID.format": "Використовуйте малі літери, цифри, дефіси або підкреслення",
"provider.custom.error.providerID.exists": "ID провайдера вже існує",
"provider.custom.error.name.required": "Відображувана назва обов'язкова",
@@ -314,7 +420,7 @@ export const dict = {
"dialog.mcp.description": "{{enabled}} з {{total}} увімкнено",
"dialog.mcp.empty": "MCP не налаштовано",
"dialog.lsp.empty": "LSP автоматично виявлені за типами файлів",
"dialog.lsp.empty": "Сервери LSP автоматично виявляються за типами файлів",
"dialog.plugins.empty": "Плагіни налаштовані в opencode.json",
"mcp.status.connected": "підключено",
@@ -333,8 +439,8 @@ export const dict = {
"dialog.directory.parent": "Батьківська папка",
"dialog.directory.readError": "Не вдалося прочитати цю папку",
"app.server.unreachable": "Не вдалося досягти {{server}}",
"app.server.retrying": "Автоматичне повторення...",
"app.server.unreachable": "Не вдалося зв'язатися із {{server}}",
"app.server.retrying": "Автоматична повторна спроба...",
"app.server.otherServers": "Інші сервери",
"dialog.server.title": "Сервери",
@@ -364,7 +470,7 @@ export const dict = {
"dialog.server.menu.edit": "Редагувати",
"dialog.server.menu.default": "Встановити за замовчуванням",
"dialog.server.menu.defaultRemove": "Видалити за замовчуванням",
"dialog.server.menu.defaultRemove": "Скасувати використання за замовчуванням",
"dialog.server.menu.delete": "Видалити",
"dialog.server.current": "Поточний сервер",
"dialog.server.status.default": "За замовчуванням",
@@ -437,6 +543,22 @@ export const dict = {
"wsl.onboarding.desktopVersion": "десктопний застосунок {{version}}",
"wsl.onboarding.versionMismatch": "Встановлена версія не відповідає версії десктопного застосунку.",
"wsl.onboarding.adding": "Додавання...",
"help.tabs.toast.ariaLabel": "Представляємо вкладки. Упорядковуйте роботу й активні сесії за допомогою вкладок",
"help.tabs.toast.dismiss": "Закрити інформацію про вкладки",
"help.tabs.title": "Представляємо вкладки",
"help.tabs.description": "Упорядковуйте роботу й активні сесії за допомогою вкладок",
"help.tabs.date": "14 липня",
"help.tabs.introduction": "OpenCode Desktop тепер побудовано навколо вкладок.",
"help.tabs.sessions":
"Почніть нову сесію у вкладці або відкрийте наявну сесію з будь-якого свого проєкту. Відкривайте нову вкладку, коли починаєте щось нове, і закривайте її після завершення.",
"help.tabs.organize":
"Кілька відкритих вкладок полегшують упорядкування активних сесій. Якщо плануєте залишити вкладки відкритими, перейменуйте їх на щось пам'ятне.",
"help.tabs.home":
"Усі свої сесії та проєкти ви знайдете на новому екрані «Головна». Вибрана сесія відкриється у вкладці.",
"help.tabs.persistence": "Після повторного відкриття програми ваші вкладки залишаться відкритими.",
"help.tabs.worktrees":
"Новий дизайн поки не підтримує робочі дерева Git, але ця можливість незабаром з'явиться. Тож якщо ви бажаєте й надалі користуватися попереднім макетом, перемикатися між макетами можна в налаштуваннях. Зауважте, що за кілька тижнів новий макет стане постійним.",
"server.row.noUsername": "без імені користувача",
"dialog.project.edit.title": "Редагувати проєкт",
@@ -466,7 +588,7 @@ export const dict = {
"context.breakdown.other": "Інше",
"context.systemPrompt.title": "Системний запит",
"context.rawMessages.title": "Сировинні повідомлення",
"context.rawMessages.title": "Необроблені повідомлення",
"context.stats.session": "Сесія",
"context.stats.messages": "Повідомлення",
@@ -560,14 +682,14 @@ export const dict = {
"error.page.details.label": "Деталі помилки",
"error.page.action.restart": "Перезапустити",
"error.page.action.report": "Повідомити про помилку",
"error.page.action.reported": "Помилку повідомлено",
"error.page.action.reported": ро помилку повідомлено",
"error.page.action.exportLogs": "Експортувати журнали",
"error.page.action.checking": "Перевірка...",
"error.page.action.checkUpdates": "Перевірити оновлення",
"error.page.action.updateTo": "Оновити до {{version}}",
"error.page.circular": "[Циклічне]",
"error.page.report.prefix": "Будь ласка, повідомте про цю помилку команді OpenCode",
"error.page.report.discord": "на Discord",
"error.page.report.discord": "у Discord",
"error.page.version": "Версія: {{version}}",
"error.dev.rootNotFound":
@@ -587,7 +709,7 @@ export const dict = {
"error.chain.causedBy": "Причина:",
"error.chain.apiError": "Помилка API",
"error.chain.status": "Статус: {{status}}",
"error.chain.retryable": "Повторювано: {{retryable}}",
"error.chain.retryable": "Можна повторити: {{retryable}}",
"error.chain.responseBody": "Тіло відповіді:\n{{body}}",
"error.chain.didYouMean": "Можливо, ви мали на увазі: {{suggestions}}",
"error.chain.modelNotFound": "Модель не знайдено: {{provider}}/{{model}}",
@@ -663,7 +785,7 @@ export const dict = {
"session.files.selectToOpen": "Виберіть файл для відкриття",
"session.files.all": "Усі файли",
"session.files.empty": "Немає файлів",
"session.files.binaryContent": "Бінарний файл (вміст не може бути відображено)",
"session.files.binaryContent": "Двійковий файл (вміст неможливо відобразити)",
"session.messages.renderEarlier": "Відобразити раніші повідомлення",
"session.messages.loadingEarlier": "Завантаження раніших повідомлень...",
@@ -680,14 +802,20 @@ export const dict = {
"session.question.minimize": "Згорнути запитання",
"session.question.restore": "Відновити запитання",
"session.question.pending.one": "{{count}} запитання очікує відповіді",
"session.question.pending.few": "{{count}} запитання очікують відповіді",
"session.question.pending.many": "{{count}} запитань очікують відповіді",
"session.question.pending.other": "Запитання, що очікують відповіді: {{count}}",
"session.followupDock.summary.one": "{{count}} повідомлення в черзі",
"session.followupDock.summary.few": "{{count}} повідомлення в черзі",
"session.followupDock.summary.many": "{{count}} повідомлень у черзі",
"session.followupDock.summary.other": "{{count}} повідомлень у черзі",
"session.followupDock.sendNow": "Надіслати зараз",
"session.followupDock.edit": "Редагувати",
"session.followupDock.collapse": "Згорнути повідомлення в черзі",
"session.followupDock.expand": "Розгорнути повідомлення в черзі",
"session.revertDock.summary.one": "{{count}} скасоване повідомлення",
"session.revertDock.summary.few": "{{count}} скасовані повідомлення",
"session.revertDock.summary.many": "{{count}} скасованих повідомлень",
"session.revertDock.summary.other": "{{count}} скасованих повідомлень",
"session.revertDock.collapse": "Згорнути скасовані повідомлення",
"session.revertDock.expand": "Розгорнути скасовані повідомлення",
@@ -715,7 +843,10 @@ export const dict = {
"session.header.open.menu": "Параметри відкриття",
"session.header.open.copyPath": "Копіювати шлях",
"session.header.open.finder": "Finder",
"session.header.open.fileExplorer": "Провідник файлів",
"session.header.open.fileExplorer": "Файловий провідник",
"session.header.reveal.finder": "Показати у Finder",
"session.header.reveal.fileExplorer": "Показати у Файловому провіднику",
"session.header.reveal.containingFolder": "Відкрити папку розташування",
"session.header.open.fileManager": "Файловий менеджер",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -765,12 +896,18 @@ export const dict = {
"terminal.connectionLost.abnormalClose": "WebSocket закрито аномально: {{code}}",
"terminal.connectionLost.description":
"З'єднання з терміналом було перервано. Це може статися під час перезапуску сервера.",
"terminal.connectTicket.csrfError":
"Квиток підключення PTY відхилено через перевірку джерела або CSRF. Перевірте конфігурацію CORS сервера.",
"terminal.connectTicket.statusError": "Помилка квитка підключення PTY зі статусом {{status}}",
"titlebar.update": "Оновити",
"titlebar.updateVersion": "Оновити {{version}}",
"common.closeTab": "Закрити вкладку",
"common.dismiss": "Відхилити",
"common.moreCountSuffix": " (ще {{count}})",
"common.requestFailed": "Запит не виконано",
"common.moreOptions": "Більше опцій",
"common.moreOptions": "Більше параметрів",
"common.learnMore": "Дізнатися більше",
"common.rename": "Перейменувати",
"common.reset": "Скинути",
@@ -840,13 +977,21 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "Використана купа JS проти ліміту купи. Тільки Chromium.",
"debugBar.mem.tip": "Використана купа JS проти ліміту купи. {{used}} з {{limit}}.",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "Примусово застосувати стилі фокуса до всіх інтерактивних елементів",
"debugBar.focus.on": "УВІМК.",
"debugBar.focus.off": "ВИМК.",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "Примусово задати напрямок макета всієї програми, не змінюючи вибрану мову",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"app.name.desktop": "OpenCode Desktop",
"settings.section.desktop": "Робочий стіл",
"settings.section.desktop": "Десктопний застосунок",
"settings.section.server": "Сервер",
"settings.tab.general": "Загальні",
"settings.tab.shortcuts": "Скорочення",
"settings.tab.shortcuts": "Клавіатурні скорочення",
"settings.desktop.section.wsl": "WSL",
"settings.desktop.wsl.title": "Інтеграція WSL",
"settings.desktop.wsl.description": "Запускати сервер OpenCode всередині WSL на Windows.",
@@ -864,7 +1009,7 @@ export const dict = {
"settings.general.row.shell.title": "Командна оболонка термінала",
"settings.general.row.shell.description":
"Виберіть оболонку для термінала. Сумісні оболонки також використовуються для викликів інструментів агента.",
"settings.general.row.shell.autoDefault": "Авто (за замовчуванням)",
"settings.general.row.shell.autoDefault": "Автоматично (за замовчуванням)",
"settings.general.row.shell.terminalOnly": "тільки термінал",
"settings.general.row.appearance.title": "Зовнішній вигляд",
"settings.general.row.appearance.description": "Налаштуйте вигляд OpenCode на вашому пристрої",
@@ -885,18 +1030,21 @@ export const dict = {
"settings.general.row.showFileTree.title": "Дерево файлів",
"settings.general.row.showFileTree.description": "Показувати панель дерева файлів у сесіях",
"settings.general.row.showNavigation.title": "Елементи навігації",
"settings.general.row.showNavigation.description": "Показувати кнопки назад і вперед у заголовку робочого столу",
"settings.general.row.showNavigation.description":
"Показувати кнопки назад і вперед на панелі заголовка десктопного застосунку",
"settings.general.row.showSearch.title": "Палітра команд",
"settings.general.row.showSearch.description": "Показувати кнопку пошуку та палітри команд у заголовку",
"settings.general.row.showSearch.description": "Показувати кнопку пошуку та палітри команд на панелі заголовка",
"settings.general.row.showTerminal.title": "Термінал",
"settings.general.row.showTerminal.description": "Показувати кнопку термінала в заголовку робочого столу",
"settings.general.row.showTerminal.description":
"Показувати кнопку термінала на панелі заголовка десктопного застосунку",
"settings.general.row.showStatus.title": "Статус сервера",
"settings.general.row.showStatus.description": "Показувати кнопку статусу сервера в заголовку",
"settings.general.row.showStatus.description": "Показувати кнопку стану сервера на панелі заголовка",
"settings.general.row.mobileTitlebarBottom.title": "Нижня навігація",
"settings.general.row.mobileTitlebarBottom.description":
"Розмістити заголовок і вкладки сесії внизу екрана на мобільних пристроях",
"settings.general.row.showCustomAgents.title": "Користувацькі агенти",
"settings.general.row.showCustomAgents.description": "Показувати вибір агента в редакторі запиту",
"Розмістити панель заголовка та вкладки сесії внизу екрана на мобільних пристроях",
"settings.general.row.showCustomAgents.title": "Показувати агента",
"settings.general.row.showCustomAgents.description":
"Перемикатися між агентами в редакторі запиту. Якщо приховано, типовим є агент Build.",
"settings.general.row.reasoningSummaries.title": "Показувати підсумки мислення",
"settings.general.row.reasoningSummaries.description": "Відображати підсумки мислення моделі на часовій шкалі",
"settings.general.row.shellToolPartsExpanded.title": "Розгортати частини інструменту оболонки",
@@ -996,16 +1144,16 @@ export const dict = {
"settings.general.sounds.errors.title": "Помилки",
"settings.general.sounds.errors.description": "Відтворювати звук, коли виникає помилка",
"settings.shortcuts.title": "Скорочення клавіш",
"settings.shortcuts.reset.button": "Скинути до стандартних",
"settings.shortcuts.reset.toast.title": "Скорочення скинуто",
"settings.shortcuts.reset.toast.description": "Скорочення клавіш були скинуті до стандартних.",
"settings.shortcuts.conflict.title": "Скорочення вже використовується",
"settings.shortcuts.title": "Клавіатурні скорочення",
"settings.shortcuts.reset.button": "Відновити стандартні",
"settings.shortcuts.reset.toast.title": "Клавіатурні скорочення відновлено",
"settings.shortcuts.reset.toast.description": "Стандартні клавіатурні скорочення відновлено.",
"settings.shortcuts.conflict.title": "Клавіатурне скорочення вже використовується",
"settings.shortcuts.conflict.description": "{{keybind}} вже призначено для {{titles}}.",
"settings.shortcuts.unassigned": "Не призначено",
"settings.shortcuts.pressKeys": "Натисніть клавіші",
"settings.shortcuts.search.placeholder": "Пошук скорочень",
"settings.shortcuts.search.empty": "Скорочень не знайдено",
"settings.shortcuts.search.placeholder": "Пошук клавіатурних скорочень",
"settings.shortcuts.search.empty": "Клавіатурних скорочень не знайдено",
"settings.shortcuts.group.general": "Загальні",
"settings.shortcuts.group.session": "Сесія",
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+229 -94
View File
@@ -3,6 +3,104 @@ import { dict as en } from "./en"
type Keys = keyof typeof en
export const dict = {
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "文件",
"desktop.menu.edit": "编辑",
"desktop.menu.view": "视图",
"desktop.menu.go": "转到",
"desktop.menu.window": "窗口",
"desktop.menu.help": "帮助",
"desktop.menu.checkForUpdates": "检查更新...",
"desktop.menu.settings": "设置",
"desktop.menu.reloadWebview": "重新加载 Webview",
"desktop.menu.restart": "重启",
"desktop.menu.exportLogs": "导出日志...",
"desktop.menu.newSession": "新建会话",
"desktop.menu.openProject": "打开项目...",
"desktop.menu.newWindow": "新建窗口",
"desktop.menu.closeWindow": "关闭窗口",
"desktop.menu.undo": "撤销",
"desktop.menu.redo": "重做",
"desktop.menu.cut": "剪切",
"desktop.menu.copy": "复制",
"desktop.menu.paste": "粘贴",
"desktop.menu.delete": "删除",
"desktop.menu.selectAll": "全选",
"desktop.menu.toggleSidebar": "切换侧边栏",
"desktop.menu.toggleTerminal": "切换终端",
"desktop.menu.toggleFileTree": "切换文件树",
"desktop.menu.reload": "重新加载",
"desktop.menu.toggleDeveloperTools": "切换开发人员工具",
"desktop.menu.actualSize": "实际大小",
"desktop.menu.zoomIn": "放大",
"desktop.menu.zoomOut": "缩小",
"desktop.menu.toggleFullScreen": "切换全屏显示",
"desktop.menu.back": "后退",
"desktop.menu.forward": "前进",
"desktop.menu.previousSession": "上一个会话",
"desktop.menu.nextSession": "下一个会话",
"desktop.menu.previousProject": "上一个项目",
"desktop.menu.nextProject": "下一个项目",
"desktop.menu.minimize": "最小化",
"desktop.menu.maximize": "最大化",
"desktop.menu.documentation": "OpenCode 文档",
"desktop.menu.supportForum": "支持论坛",
"desktop.menu.shareFeedback": "提供反馈",
"desktop.menu.reportBug": "报告错误",
"desktop.menu.ariaLabel": "OpenCode 菜单",
"desktop.updater.dialog.checkFailed.message": "检查更新失败。",
"desktop.updater.dialog.checkFailed.title": "更新错误",
"desktop.updater.dialog.upToDate.message": "你使用的是最新版本。",
"desktop.updater.dialog.upToDate.title": "无可用更新",
"desktop.updater.dialog.ready.message": "已下载更新 {{version}}。是否立即重启?",
"desktop.updater.dialog.ready.title": "更新已就绪",
"desktop.updater.dialog.restart": "重启",
"desktop.updater.dialog.later": "稍后",
"desktop.recovery.action.relaunch": "重新启动",
"desktop.recovery.action.exportLogs": "导出日志",
"desktop.recovery.action.keepWaiting": "继续等待",
"desktop.recovery.action.quit": "退出",
"desktop.recovery.loadFailed": "OpenCode 加载失败",
"desktop.recovery.terminated": "OpenCode 窗口意外终止",
"desktop.recovery.unresponsive": "OpenCode 未响应",
"desktop.recovery.unresponsive.detail": "你可以重新启动应用、打开日志或继续等待。",
"desktop.recovery.loadFailed.detail": "窗口:{{window}}\nURL{{url}}\n错误:{{code}} {{description}}",
"desktop.recovery.terminated.detail": "窗口:{{window}}\n原因:{{reason}}\n代码:{{code}}",
"desktop.recovery.unknown": "<未知>",
"desktop.dialog.chooseFolder": "选择文件夹",
"desktop.dialog.chooseFile": "选择文件",
"desktop.dialog.saveFile": "保存文件",
"desktop.dialog.files": "文件",
"desktop.server.local": "本地服务器",
"desktop.wsl.error.windowsOnly": "WSL 仅在 Windows 上可用",
"desktop.wsl.error.unavailable": "WSL 不可用",
"desktop.wsl.error.listInstalled": "无法列出已安装的 WSL 发行版",
"desktop.wsl.error.listOnline": "无法列出在线 WSL 发行版",
"desktop.wsl.error.executeDistro": "无法在发行版中执行命令",
"desktop.wsl.error.installWsl": "WSL 安装失败",
"desktop.wsl.error.installDistro": "无法安装发行版:{{distro}}",
"desktop.wsl.error.installOpencode": "OpenCode 安装失败",
"desktop.wsl.error.alreadyAdded": "已添加 {{distro}}",
"desktop.wsl.error.opencodeMissing": "此发行版中未安装 opencode",
"desktop.wsl.error.opencodeCannotRun": "已安装 opencode,但无法运行",
"desktop.wsl.error.opencodeNotInstalled": "{{distro}} 中未安装 OpenCode",
"desktop.wsl.error.updateVersion":
"OpenCode 更新已完成,但 {{distro}} 仍报告版本 {{installed}};预期版本为 {{expected}}",
"desktop.wsl.error.noVersion": "无版本信息",
"desktop.wsl.error.serverExited": "WSL 服务器启动后退出(code={{code}} signal={{signal}}",
"desktop.wsl.error.serverExitedBeforeHealthy":
"WSL 服务器在进入正常状态前退出(code={{code}} signal={{signal}}{{output}}",
"desktop.wsl.error.healthTimeout": "{{distro}} 的 Sidecar 运行状况检查在 {{timeout}}ms 后超时",
"desktop.wsl.error.commandTimeout": "{{command}} {{args}} 在 {{timeout}}ms 后超时",
"desktop.wsl.error.failedPort": "无法获取端口",
"desktop.picker.error.notSelected": "文件选择器未选择文件",
"desktop.picker.error.sizeLimit": "所选附件超过 {{limit}} MB 的限制",
"command.category.suggested": "建议",
"command.category.view": "视图",
"command.category.project": "项目",
@@ -20,6 +118,7 @@ export const dict = {
"command.category.permissions": "权限",
"command.category.workspace": "工作区",
"command.category.settings": "设置",
"command.logs.export": "导出日志",
"theme.scheme.system": "系统",
"theme.scheme.light": "浅色",
@@ -86,8 +185,8 @@ export const dict = {
"command.model.choose": "选择模型",
"command.model.choose.description": "选择不同的模型",
"command.mcp.toggle": "切换 MCPs",
"command.mcp.toggle.description": "切换 MCPs",
"command.mcp.toggle": "启用或禁用 MCP 服务器",
"command.mcp.toggle.description": "启用或禁用 MCP 服务器",
"command.agent.cycle": "切换智能体",
"command.agent.cycle.description": "切换到下一个智能体",
@@ -110,9 +209,9 @@ export const dict = {
"command.session.undo.description": "撤销上一条消息",
"command.session.redo": "重做",
"command.session.redo.description": "重做上一条撤销的消息",
"command.session.compact": "精简会话",
"command.session.compact": "压缩会话",
"command.session.compact.description": "总结会话以减少上下文大小",
"command.session.fork": "从消息分叉",
"command.session.fork": "从消息创建新会话",
"command.session.fork.description": "从之前的消息创建新会话",
"command.session.share": "分享会话",
"command.session.share.description": "分享此会话并将链接复制到剪贴板",
@@ -129,16 +228,17 @@ export const dict = {
"dialog.provider.empty": "未找到提供商",
"dialog.provider.group.popular": "热门",
"dialog.provider.group.other": "其他",
"dialog.provider.custom.label": "自定义 OpenAI 兼容提供商",
"dialog.provider.tag.recommended": "推荐",
"dialog.provider.opencode.note": "使用 OpenCode Zen 或 API 密钥连接",
"dialog.provider.opencode.note": "精选模型,包括 Claude、GPT、Gemini 等",
"dialog.provider.opencode.tagline": "可靠的优化模型",
"dialog.provider.opencodeGo.tagline": "适合所有人的低成本订阅",
"dialog.provider.anthropic.note": "使用 Claude Pro/Max 或 API 密钥连接",
"dialog.provider.copilot.note": "使用 Copilot API 密钥连接",
"dialog.provider.openai.note": "使用 ChatGPT Pro/Plus 或 API 密钥连接",
"dialog.provider.google.note": "使用 Google 账号或 API 密钥连接",
"dialog.provider.openrouter.note": "使用 OpenRouter 账号或 API 密钥连接",
"dialog.provider.vercel.note": "使用 Vercel 账号或 API 密钥连接",
"dialog.provider.anthropic.note": "直接使用 Claude 模型,包括 Pro 和 Max",
"dialog.provider.copilot.note": "通过 GitHub Copilot 使用辅助编程 AI 模型",
"dialog.provider.openai.note": "适合快速处理各类 AI 任务的 GPT 模型",
"dialog.provider.google.note": "可快速生成结构化回复的 Gemini 模型",
"dialog.provider.openrouter.note": "通过一个提供商使用所有受支持的模型",
"dialog.provider.vercel.note": "通过智能路由统一使用 AI 模型",
"dialog.model.select.title": "选择模型",
"dialog.model.search.placeholder": "搜索模型",
@@ -148,6 +248,7 @@ export const dict = {
"dialog.model.manage.provider.toggle": "切换所有 {{provider}} 模型",
"dialog.model.unpaid.freeModels.title": "OpenCode 提供的免费模型",
"dialog.model.unpaid.addMore.title": "从热门提供商添加更多模型",
"dialog.model.unpaid.viewMoreProviders": "查看另外 70 多个提供商",
"dialog.provider.viewAll": "查看更多提供商",
@@ -155,11 +256,13 @@ export const dict = {
"provider.connect.title.anthropicProMax": "使用 Claude Pro/Max 登录",
"provider.connect.selectMethod": "选择 {{provider}} 的登录方式。",
"provider.connect.method.apiKey": "API 密钥",
"provider.connect.method.browser": "浏览器",
"provider.connect.method.headless": "无头模式",
"provider.connect.status.inProgress": "正在授权...",
"provider.connect.status.waiting": "等待授权...",
"provider.connect.status.failed": "授权失败:{{error}}",
"provider.connect.apiKey.description":
"输入你的 {{provider}} API 密钥以连接户,并在 OpenCode 中使用 {{provider}} 模型。",
"输入你的 {{provider}} API 密钥以连接户,并在 OpenCode 中使用 {{provider}} 模型。",
"provider.connect.apiKey.label": "{{provider}} API 密钥",
"provider.connect.apiKey.placeholder": "API 密钥",
"provider.connect.apiKey.required": "API 密钥为必填项",
@@ -170,19 +273,20 @@ export const dict = {
"provider.connect.opencodeZen.visit.suffix": " 获取你的 API 密钥。",
"provider.connect.oauth.code.visit.prefix": "访问 ",
"provider.connect.oauth.code.visit.link": "此链接",
"provider.connect.oauth.code.visit.suffix": " 获取授权码,以连接你的户并在 OpenCode 中使用 {{provider}} 模型。",
"provider.connect.oauth.code.visit.suffix": " 获取授权码,以连接你的户并在 OpenCode 中使用 {{provider}} 模型。",
"provider.connect.oauth.code.label": "{{method}} 授权码",
"provider.connect.oauth.code.placeholder": "授权码",
"provider.connect.oauth.code.required": "授权码为必填项",
"provider.connect.oauth.code.invalid": "授权码无效",
"provider.connect.oauth.auto.visit.prefix": "访问 ",
"provider.connect.oauth.auto.visit.link": "此链接",
"provider.connect.oauth.auto.visit.suffix": " 并输入以下代码,以连接你的户并在 OpenCode 中使用 {{provider}} 模型。",
"provider.connect.oauth.auto.visit.suffix": " 并输入以下代码,以连接你的户并在 OpenCode 中使用 {{provider}} 模型。",
"provider.connect.oauth.auto.confirmationCode": "确认码",
"provider.connect.toast.connected.title": "{{provider}} 已连接",
"provider.connect.toast.connected.description": "现在可以使用 {{provider}} 模型了。",
"provider.custom.title": "自定义提供商",
"provider.custom.unavailable": "此服务器上无法使用自定义提供商",
"provider.custom.description.prefix": "配置与 OpenAI 兼容的提供商。请查看",
"provider.custom.description.link": "提供商配置文档",
"provider.custom.description.suffix": "。",
@@ -233,7 +337,7 @@ export const dict = {
"model.input.image": "图像",
"model.input.audio": "音频",
"model.input.video": "视频",
"model.input.pdf": "pdf",
"model.input.pdf": "PDF",
"model.tooltip.allows": "支持:{{inputs}}",
"model.tooltip.context.label": "上下文",
"model.tooltip.inputs": "输入",
@@ -253,7 +357,7 @@ export const dict = {
"common.clear": "清除",
"common.connect": "连接",
"common.disconnect": "断开连接",
"common.continue": "提交",
"common.continue": "继续",
"common.submit": "提交",
"common.save": "保存",
"common.saving": "保存中...",
@@ -320,18 +424,18 @@ export const dict = {
"prompt.toast.pasteUnsupported.description": "此处仅能附加图片、PDF 或文本文件。",
"prompt.toast.modelAgentRequired.title": "请选择智能体和模型",
"prompt.toast.modelAgentRequired.description": "发送提示前请先选择智能体和模型。",
"prompt.toast.worktreeCreateFailed.title": "创建工作失败",
"prompt.toast.worktreeCreateFailed.title": "创建工作失败",
"prompt.toast.sessionCreateFailed.title": "创建会话失败",
"prompt.toast.shellSendFailed.title": "发送 shell 命令失败",
"prompt.toast.commandSendFailed.title": "发送命令失败",
"prompt.toast.promptSendFailed.title": "发送提示失败",
"prompt.toast.promptSendFailed.description": "无法获取会话",
"dialog.mcp.title": "MCPs",
"dialog.mcp.title": "MCP 服务器",
"dialog.mcp.description": "已启用 {{enabled}} / {{total}}",
"dialog.mcp.empty": "未配置 MCPs",
"dialog.mcp.empty": "未配置 MCP 服务器",
"dialog.lsp.empty": "已文件类型自动检测 LSPs",
"dialog.lsp.empty": "已根据文件类型自动检测 LSP",
"dialog.plugins.empty": "在 opencode.json 中配置的插件",
@@ -341,7 +445,7 @@ export const dict = {
"mcp.auth.clickToAuthenticate": "点击进行授权",
"mcp.status.disabled": "已禁用",
"dialog.fork.empty": "没有可用于分叉的消息",
"dialog.fork.empty": "没有可用于创建新会话的消息",
"dialog.directory.search.placeholder": "搜索文件夹",
"dialog.directory.empty": "未找到文件夹",
@@ -446,6 +550,21 @@ export const dict = {
"wsl.onboarding.versionMismatch": "已安装版本与桌面应用版本不一致。",
"wsl.onboarding.adding": "正在添加...",
"help.tabs.toast.ariaLabel": "标签页功能介绍。使用标签页整理工作和进行中的会话",
"help.tabs.toast.dismiss": "关闭标签页功能介绍",
"help.tabs.title": "标签页功能介绍",
"help.tabs.description": "使用标签页整理工作和进行中的会话",
"help.tabs.date": "7 月 14 日",
"help.tabs.introduction": "OpenCode Desktop 现已采用以标签页为核心的设计。",
"help.tabs.sessions":
"在标签页中开始新会话,或从任意项目打开现有会话。开始处理新任务时打开新标签页,完成后将其关闭。",
"help.tabs.organize":
"保持打开几个标签页,可更轻松地整理进行中的会话。如果打算保留某个标签页,请为其指定一个便于记忆的名称。",
"help.tabs.home": "你可以在新的主页中找到所有会话和项目。选择会话即可在标签页中将其打开。",
"help.tabs.persistence": "重新打开应用时,标签页仍会保持打开。",
"help.tabs.worktrees":
"新设计暂不支持 Git Worktrees,此功能即将推出。如果希望继续使用之前的布局,可在“设置”中切换布局。请注意,新布局将在几周后永久启用。",
"dialog.project.edit.title": "编辑项目",
"dialog.project.edit.name": "名称",
"dialog.project.edit.icon": "图标",
@@ -453,13 +572,13 @@ export const dict = {
"dialog.project.edit.icon.hint": "点击或拖拽图片",
"dialog.project.edit.icon.recommended": "建议:128x128px",
"dialog.project.edit.color": "颜色",
"dialog.project.edit.color.select": "选择{{color}}颜色",
"dialog.project.edit.color.select": "选择颜色:{{color}}",
"dialog.project.edit.worktree.startup": "工作区启动脚本",
"dialog.project.edit.worktree.startup.description": "创建新工作区 (worktree) 后运行。",
"dialog.project.edit.worktree.startup.description": "创建新工作区 (worktree) 后运行。",
"dialog.project.edit.worktree.startup.placeholder": "例如 bun install",
"context.breakdown.title": "上下文分",
"context.breakdown.note": "输入 token 的大致分。“其他”包含工具定义和开销。",
"context.breakdown.title": "上下文分",
"context.breakdown.note": "输入令牌的大致分。“其他”包含工具定义和开销。",
"context.breakdown.system": "系统",
"context.breakdown.user": "用户",
"context.breakdown.assistant": "助手",
@@ -472,18 +591,18 @@ export const dict = {
"context.stats.provider": "提供商",
"context.stats.model": "模型",
"context.stats.limit": "上下文限制",
"context.stats.totalTokens": "总 token",
"context.stats.totalTokens": "令牌总数",
"context.stats.usage": "使用率",
"context.stats.inputTokens": "输入 token",
"context.stats.outputTokens": "输出 token",
"context.stats.reasoningTokens": "推理 token",
"context.stats.cacheTokens": "缓存 token(读/写)",
"context.stats.inputTokens": "输入令牌",
"context.stats.outputTokens": "输出令牌",
"context.stats.reasoningTokens": "推理令牌",
"context.stats.cacheTokens": "缓存令牌(读/写)",
"context.stats.userMessages": "用户消息",
"context.stats.assistantMessages": "助手消息",
"context.stats.totalCost": "总成本",
"context.stats.sessionCreated": "创建时间",
"context.stats.lastActivity": "最后活动",
"context.usage.tokens": "Token",
"context.usage.tokens": "令牌数",
"context.usage.usage": "使用率",
"context.usage.cost": "成本",
"context.usage.clickToView": "点击查看上下文",
@@ -511,7 +630,7 @@ export const dict = {
"toast.language.title": "语言",
"toast.language.description": "已切换到{{language}}",
"toast.theme.title": "主题已切换",
"toast.scheme.title": "色方案",
"toast.scheme.title": "色方案",
"toast.workspace.enabled.title": "工作区已启用",
"toast.workspace.enabled.description": "侧边栏现在显示多个工作树",
"toast.workspace.disabled.title": "工作区已禁用",
@@ -569,7 +688,7 @@ export const dict = {
"error.chain.didYouMean": "你是不是想输入:{{suggestions}}",
"error.chain.modelNotFound": "未找到模型:{{provider}}/{{model}}",
"error.chain.checkConfig": "请检查你的配置 (opencode.json) 中的 provider/model 名称",
"error.chain.mcpFailed": 'MCP 服务器 "{{name}}" 启动失败。注意: OpenCode 暂不支持 MCP 认证。',
"error.chain.mcpFailed": 'MCP 服务器 "{{name}}" 启动失败。注意OpenCode 暂不支持 MCP 认证。',
"error.chain.providerAuthFailed": "提供商认证失败({{provider}}):{{message}}",
"error.chain.providerInitFailed": '无法初始化提供商 "{{provider}}"。请检查凭据和配置。',
"error.chain.configJsonInvalid": "配置文件 {{path}} 不是有效的 JSON(C)",
@@ -607,7 +726,7 @@ export const dict = {
"home.sessions.group.today": "今天",
"home.sessions.group.yesterday": "昨天",
"home.sessions.group.older": "更早",
"home.providerTip": "连接 75 个以上的提供商,使用 Claude、GPT、Gemini 等其他模型",
"home.providerTip": "连接 75 个以上的提供商,使用包括 Claude、GPT、Gemini 在内的更多模型",
"session.tab.session": "会话",
"session.tab.review": "审查",
@@ -618,12 +737,12 @@ export const dict = {
"session.error.notFound.description": "此标签页指向的会话已不存在于此服务器上。",
"session.error.notFound.closeTab": "关闭标签页",
"session.error.serverConnection": "无法连接到此服务器",
"session.review.filesChanged": "{{count}} 个文件变更",
"session.review.filesChanged": "{{count}} 个文件已更改",
"session.review.change.one": "更改",
"session.review.change.other": "更改",
"session.review.loadingChanges": "正在加载更改...",
"session.review.empty": "此会话暂无更改",
"session.review.noVcs": "未检测到 Git 版本控制系统,无法显示更改",
"session.review.noVcs": "未检测到 Git,无法显示更改",
"session.review.noSnapshot": "配置中已禁用快照跟踪,因此会话更改不可用",
"session.review.noChanges": "无更改",
"session.review.noUncommittedChanges": "尚无未提交的更改",
@@ -641,8 +760,8 @@ export const dict = {
"session.todo.title": "待办事项",
"session.todo.collapse": "折叠",
"session.todo.expand": "展开",
"session.question.minimize": "最小化问题",
"session.question.restore": "恢复问题",
"session.question.minimize": "收起问题",
"session.question.restore": "展开问题",
"session.question.pending.one": "{{count}} 个待处理问题",
"session.question.pending.other": "{{count}} 个待处理问题",
"session.followupDock.summary.one": "{{count}} 条排队消息",
@@ -656,7 +775,7 @@ export const dict = {
"session.revertDock.collapse": "折叠已回滚消息",
"session.revertDock.expand": "展开已回滚消息",
"session.revertDock.restore": "恢复消息",
"session.new.title": "构建任何东西",
"session.new.title": "构建任何内容",
"session.new.project.new": "新建项目",
"session.new.project.search": "搜索项目",
"session.new.project.add": "添加项目",
@@ -708,6 +827,11 @@ export const dict = {
"terminal.close": "关闭终端",
"terminal.connectionLost.title": "连接已丢失",
"terminal.connectionLost.description": "终端连接已中断。这可能发生在服务器重启时。",
"terminal.connectTicket.csrfError": "PTY 连接票证因来源或 CSRF 检查被拒绝。请检查服务器 CORS 配置。",
"terminal.connectTicket.statusError": "PTY 连接票证失败,状态为 {{status}}",
"titlebar.update": "更新",
"titlebar.updateVersion": "更新 {{version}}",
"common.closeTab": "关闭标签页",
"common.dismiss": "忽略",
@@ -775,8 +899,8 @@ export const dict = {
"settings.general.row.terminalFont.description": "自定义终端使用的字体",
"settings.general.row.uiFont.title": "界面字体",
"settings.general.row.uiFont.description": "自定义整个界面使用的字体",
"settings.general.row.followup.title": "跟进消息行为",
"settings.general.row.followup.description": "选择跟进提示是立即引导还是在队列中等待",
"settings.general.row.followup.title": "后续消息行为",
"settings.general.row.followup.description": "选择后续提示是立即引导当前会话还是排队等待",
"settings.general.row.followup.option.queue": "排队",
"settings.general.row.followup.option.steer": "引导",
"settings.general.row.showFileTree.title": "文件树",
@@ -791,14 +915,14 @@ export const dict = {
"settings.general.row.showStatus.description": "在标题栏中显示服务器状态按钮",
"settings.general.row.mobileTitlebarBottom.title": "底部导航",
"settings.general.row.mobileTitlebarBottom.description": "在移动设备上将标题栏和会话标签页置于屏幕底部",
"settings.general.row.showCustomAgents.title": "自定义智能体",
"settings.general.row.showCustomAgents.description": "在输入框中显示智能体选择器",
"settings.general.row.showCustomAgents.title": "显示智能体",
"settings.general.row.showCustomAgents.description": "在输入框中切换智能体。隐藏时默认使用 Build 智能体。",
"settings.general.row.reasoningSummaries.title": "显示推理摘要",
"settings.general.row.reasoningSummaries.description": "在时间线中显示模型推理摘要",
"settings.general.row.shellToolPartsExpanded.title": "展开 shell 工具部分",
"settings.general.row.shellToolPartsExpanded.description": "默认在时间线中展开 shell 工具部分",
"settings.general.row.editToolPartsExpanded.title": "展开编辑工具部分",
"settings.general.row.editToolPartsExpanded.description": "默认在时间线中展开 edit、write 和 patch 工具部分",
"settings.general.row.shellToolPartsExpanded.title": "展开 Shell 工具调用",
"settings.general.row.shellToolPartsExpanded.description": "默认在时间线中展开 Shell 工具调用详情",
"settings.general.row.editToolPartsExpanded.title": "展开编辑工具调用",
"settings.general.row.editToolPartsExpanded.description": "默认在时间线中展开 edit、write 和 patch 工具调用详情",
"settings.general.row.newInterface.title": "新布局",
"settings.general.row.newInterface.badge": "新",
"settings.general.row.newInterface.description": "使用新的标签页和主页布局。在有限时间内可在不同布局之间切换。",
@@ -806,7 +930,7 @@ export const dict = {
"settings.general.row.newInterfaceNotice.description": "之前的布局不再可用",
"settings.general.row.newInterfaceNotice.dismiss": "忽略",
"settings.general.row.pinchZoom.title": "双指缩放",
"settings.general.row.pinchZoom.description": "允许使用触控板双指捏合和 Ctrl-scroll 手势缩放",
"settings.general.row.pinchZoom.description": "允许使用触控板双指捏合和 Ctrl+滚轮手势缩放",
"settings.general.row.wayland.title": "使用原生 Wayland",
"settings.general.row.wayland.description": "在 Wayland 上禁用 X11 回退。需要重启。",
"settings.general.row.wayland.tooltip": "在混合刷新率显示器的 Linux 系统上,原生 Wayland 可能更稳定。",
@@ -835,41 +959,41 @@ export const dict = {
"sound.option.alert08": "警报 08",
"sound.option.alert09": "警报 09",
"sound.option.alert10": "警报 10",
"sound.option.bipbop01": "哔啵 01",
"sound.option.bipbop02": "哔啵 02",
"sound.option.bipbop03": "哔啵 03",
"sound.option.bipbop04": "哔啵 04",
"sound.option.bipbop05": "哔啵 05",
"sound.option.bipbop06": "哔啵 06",
"sound.option.bipbop07": "哔啵 07",
"sound.option.bipbop08": "哔啵 08",
"sound.option.bipbop09": "哔啵 09",
"sound.option.bipbop10": "哔啵 10",
"sound.option.staplebops01": "斯泰普博普斯 01",
"sound.option.staplebops02": "斯泰普博普斯 02",
"sound.option.staplebops03": "斯泰普博普斯 03",
"sound.option.staplebops04": "斯泰普博普斯 04",
"sound.option.staplebops05": "斯泰普博普斯 05",
"sound.option.staplebops06": "斯泰普博普斯 06",
"sound.option.staplebops07": "斯泰普博普斯 07",
"sound.option.nope01": " 01",
"sound.option.nope02": " 02",
"sound.option.nope03": " 03",
"sound.option.nope04": " 04",
"sound.option.nope05": " 05",
"sound.option.nope06": " 06",
"sound.option.nope07": " 07",
"sound.option.nope08": " 08",
"sound.option.nope09": " 09",
"sound.option.nope10": " 10",
"sound.option.nope11": " 11",
"sound.option.nope12": " 12",
"sound.option.yup01": " 01",
"sound.option.yup02": " 02",
"sound.option.yup03": " 03",
"sound.option.yup04": " 04",
"sound.option.yup05": " 05",
"sound.option.yup06": " 06",
"sound.option.bipbop01": "Bip-bop 01",
"sound.option.bipbop02": "Bip-bop 02",
"sound.option.bipbop03": "Bip-bop 03",
"sound.option.bipbop04": "Bip-bop 04",
"sound.option.bipbop05": "Bip-bop 05",
"sound.option.bipbop06": "Bip-bop 06",
"sound.option.bipbop07": "Bip-bop 07",
"sound.option.bipbop08": "Bip-bop 08",
"sound.option.bipbop09": "Bip-bop 09",
"sound.option.bipbop10": "Bip-bop 10",
"sound.option.staplebops01": "Staplebops 01",
"sound.option.staplebops02": "Staplebops 02",
"sound.option.staplebops03": "Staplebops 03",
"sound.option.staplebops04": "Staplebops 04",
"sound.option.staplebops05": "Staplebops 05",
"sound.option.staplebops06": "Staplebops 06",
"sound.option.staplebops07": "Staplebops 07",
"sound.option.nope01": "Nope 01",
"sound.option.nope02": "Nope 02",
"sound.option.nope03": "Nope 03",
"sound.option.nope04": "Nope 04",
"sound.option.nope05": "Nope 05",
"sound.option.nope06": "Nope 06",
"sound.option.nope07": "Nope 07",
"sound.option.nope08": "Nope 08",
"sound.option.nope09": "Nope 09",
"sound.option.nope10": "Nope 10",
"sound.option.nope11": "Nope 11",
"sound.option.nope12": "Nope 12",
"sound.option.yup01": "Yup 01",
"sound.option.yup02": "Yup 02",
"sound.option.yup03": "Yup 03",
"sound.option.yup04": "Yup 04",
"sound.option.yup05": "Yup 05",
"sound.option.yup06": "Yup 06",
"settings.general.notifications.agent.title": "智能体",
"settings.general.notifications.agent.description": "当智能体完成或需要注意时显示系统通知",
@@ -902,7 +1026,7 @@ export const dict = {
"settings.shortcuts.group.prompt": "提示",
"settings.providers.title": "提供商",
"settings.providers.description": "提供商设置将在此处可配置。",
"settings.providers.description": "可在此处配置提供商设置。",
"settings.providers.section.connected": "已连接的提供商",
"settings.providers.connected.empty": "没有已连接的提供商",
"settings.providers.section.popular": "热门提供商",
@@ -912,16 +1036,16 @@ export const dict = {
"settings.providers.tag.other": "其他",
"settings.models.title": "模型",
"settings.models.description": "模型设置将在此处可配置。",
"settings.models.description": "可在此处配置模型设置。",
"settings.agents.title": "智能体",
"settings.agents.description": "智能体设置将在此处可配置。",
"settings.agents.description": "可在此处配置智能体设置。",
"settings.commands.title": "命令",
"settings.commands.description": "命令设置将在此处可配置。",
"settings.commands.description": "可在此处配置命令设置。",
"settings.mcp.title": "MCP",
"settings.mcp.description": "MCP 设置将在此处可配置。",
"settings.mcp.description": "可在此处配置 MCP 设置。",
"settings.permissions.title": "权限",
"settings.permissions.description": "控制服务器默认可以使用哪些工具。",
@@ -933,12 +1057,12 @@ export const dict = {
"settings.permissions.tool.read.title": "读取",
"settings.permissions.tool.read.description": "读取文件(匹配文件路径)",
"settings.permissions.tool.edit.title": "编辑",
"settings.permissions.tool.edit.description": "修改文件,包括编辑、写入、补丁和多重编辑",
"settings.permissions.tool.edit.description": "修改文件,包括编辑、写入和应用补丁",
"settings.permissions.tool.glob.title": "Glob",
"settings.permissions.tool.glob.description": "使用 glob 模式匹配文件",
"settings.permissions.tool.grep.title": "Grep",
"settings.permissions.tool.grep.description": "使用正则表达式搜索文件内容",
"settings.permissions.tool.list.title": "列",
"settings.permissions.tool.list.title": "列出文件",
"settings.permissions.tool.list.description": "列出目录中的文件",
"settings.permissions.tool.bash.title": "Bash",
"settings.permissions.tool.bash.description": "运行 shell 命令",
@@ -950,7 +1074,7 @@ export const dict = {
"settings.permissions.tool.lsp.description": "运行语言服务器查询",
"settings.permissions.tool.todowrite.title": "更新待办",
"settings.permissions.tool.todowrite.description": "更新待办列表",
"settings.permissions.tool.webfetch.title": "网页获取",
"settings.permissions.tool.webfetch.title": "获取网页",
"settings.permissions.tool.webfetch.description": "从 URL 获取内容",
"settings.permissions.tool.websearch.title": "网页搜索",
"settings.permissions.tool.websearch.description": "搜索网页",
@@ -973,10 +1097,10 @@ export const dict = {
"workspace.resetting.description": "这可能需要一点时间。",
"workspace.reset.failed.title": "重置工作区失败",
"workspace.reset.success.title": "工作区已重置",
"workspace.reset.success.description": "工作区已与默认分支保持一致。",
"workspace.reset.success.description": "工作区已与默认分支一致。",
"workspace.error.stillPreparing": "工作区仍在准备中",
"workspace.status.checking": "正在检查未合并的更改...",
"workspace.status.error": "无法验证 git 状态。",
"workspace.status.error": "无法验证 Git 状态。",
"workspace.status.clean": "未检测到未合并的更改。",
"workspace.status.dirty": "检测到未合并的更改。",
"workspace.delete.title": "删除工作区",
@@ -993,7 +1117,7 @@ export const dict = {
"dialog.releaseNotes.action.getStarted": "开始",
"dialog.releaseNotes.action.next": "下一步",
"dialog.releaseNotes.action.hideFuture": "不再显示",
"dialog.releaseNotes.media.alt": "发布预览",
"dialog.releaseNotes.media.alt": "版本说明预览",
"toast.project.reloadFailed.title": "无法重新加载 {{project}}",
"error.server.invalidConfiguration": "配置无效",
"common.moreCountSuffix": " (还有 {{count}} 个)",
@@ -1018,6 +1142,9 @@ export const dict = {
"session.question.progress": "{{current}}/{{total}} 个问题",
"session.header.open.finder": "访达",
"session.header.open.fileExplorer": "文件资源管理器",
"session.header.reveal.finder": "在访达中显示",
"session.header.reveal.fileExplorer": "在文件资源管理器中显示",
"session.header.reveal.containingFolder": "打开所在文件夹",
"session.header.open.fileManager": "文件管理器",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -1053,6 +1180,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "使用的 JS 堆与堆限制。仅限 Chromium。",
"debugBar.mem.tip": "使用的 JS 堆与堆限制。{{used}} / {{limit}}。",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "强制所有交互元素显示焦点样式",
"debugBar.focus.on": "开",
"debugBar.focus.off": "关",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "在不更改所选语言的情况下,强制设置整个应用的布局方向",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
+257 -122
View File
@@ -3,6 +3,104 @@ import { dict as en } from "./en"
type Keys = keyof typeof en
export const dict = {
"desktop.menu.app": "OpenCode",
"desktop.menu.file": "檔案",
"desktop.menu.edit": "編輯",
"desktop.menu.view": "檢視",
"desktop.menu.go": "前往",
"desktop.menu.window": "視窗",
"desktop.menu.help": "說明",
"desktop.menu.checkForUpdates": "檢查更新...",
"desktop.menu.settings": "設定",
"desktop.menu.reloadWebview": "重新載入 Webview",
"desktop.menu.restart": "重新啟動",
"desktop.menu.exportLogs": "匯出記錄檔...",
"desktop.menu.newSession": "新增工作階段",
"desktop.menu.openProject": "開啟專案...",
"desktop.menu.newWindow": "新增視窗",
"desktop.menu.closeWindow": "關閉視窗",
"desktop.menu.undo": "復原",
"desktop.menu.redo": "重做",
"desktop.menu.cut": "剪下",
"desktop.menu.copy": "複製",
"desktop.menu.paste": "貼上",
"desktop.menu.delete": "刪除",
"desktop.menu.selectAll": "全選",
"desktop.menu.toggleSidebar": "切換側邊欄",
"desktop.menu.toggleTerminal": "切換終端機",
"desktop.menu.toggleFileTree": "切換檔案樹",
"desktop.menu.reload": "重新載入",
"desktop.menu.toggleDeveloperTools": "切換開發人員工具",
"desktop.menu.actualSize": "實際大小",
"desktop.menu.zoomIn": "放大",
"desktop.menu.zoomOut": "縮小",
"desktop.menu.toggleFullScreen": "切換全螢幕",
"desktop.menu.back": "上一頁",
"desktop.menu.forward": "下一頁",
"desktop.menu.previousSession": "上一個工作階段",
"desktop.menu.nextSession": "下一個工作階段",
"desktop.menu.previousProject": "上一個專案",
"desktop.menu.nextProject": "下一個專案",
"desktop.menu.minimize": "最小化",
"desktop.menu.maximize": "最大化",
"desktop.menu.documentation": "OpenCode 文件",
"desktop.menu.supportForum": "支援論壇",
"desktop.menu.shareFeedback": "提供意見回饋",
"desktop.menu.reportBug": "回報錯誤",
"desktop.menu.ariaLabel": "OpenCode 選單",
"desktop.updater.dialog.checkFailed.message": "檢查更新失敗。",
"desktop.updater.dialog.checkFailed.title": "更新錯誤",
"desktop.updater.dialog.upToDate.message": "目前已是最新版本。",
"desktop.updater.dialog.upToDate.title": "沒有更新",
"desktop.updater.dialog.ready.message": "已下載更新 {{version}}。要立即重新啟動嗎?",
"desktop.updater.dialog.ready.title": "更新已就緒",
"desktop.updater.dialog.restart": "重新啟動",
"desktop.updater.dialog.later": "稍後",
"desktop.recovery.action.relaunch": "重新啟動應用程式",
"desktop.recovery.action.exportLogs": "匯出記錄檔",
"desktop.recovery.action.keepWaiting": "繼續等待",
"desktop.recovery.action.quit": "結束",
"desktop.recovery.loadFailed": "OpenCode 載入失敗",
"desktop.recovery.terminated": "OpenCode 視窗意外終止",
"desktop.recovery.unresponsive": "OpenCode 沒有回應",
"desktop.recovery.unresponsive.detail": "你可以重新啟動應用程式、開啟記錄檔,或繼續等待。",
"desktop.recovery.loadFailed.detail": "視窗:{{window}}\nURL{{url}}\n錯誤:{{code}} {{description}}",
"desktop.recovery.terminated.detail": "視窗:{{window}}\n原因:{{reason}}\n代碼:{{code}}",
"desktop.recovery.unknown": "<未知>",
"desktop.dialog.chooseFolder": "選擇資料夾",
"desktop.dialog.chooseFile": "選擇檔案",
"desktop.dialog.saveFile": "儲存檔案",
"desktop.dialog.files": "檔案",
"desktop.server.local": "本機伺服器",
"desktop.wsl.error.windowsOnly": "WSL 僅適用於 Windows",
"desktop.wsl.error.unavailable": "WSL 無法使用",
"desktop.wsl.error.listInstalled": "無法列出已安裝的 WSL 發行版",
"desktop.wsl.error.listOnline": "無法列出線上 WSL 發行版",
"desktop.wsl.error.executeDistro": "無法在發行版中執行命令",
"desktop.wsl.error.installWsl": "WSL 安裝失敗",
"desktop.wsl.error.installDistro": "無法安裝發行版:{{distro}}",
"desktop.wsl.error.installOpencode": "OpenCode 安裝失敗",
"desktop.wsl.error.alreadyAdded": "已新增 {{distro}}",
"desktop.wsl.error.opencodeMissing": "此發行版中未安裝 opencode",
"desktop.wsl.error.opencodeCannotRun": "已安裝 opencode,但無法執行",
"desktop.wsl.error.opencodeNotInstalled": "{{distro}} 中未安裝 OpenCode",
"desktop.wsl.error.updateVersion":
"OpenCode 更新完成,但 {{distro}} 回報的版本仍為 {{installed}};預期版本為 {{expected}}",
"desktop.wsl.error.noVersion": "無版本資訊",
"desktop.wsl.error.serverExited": "WSL 伺服器在啟動後結束 (code={{code}} signal={{signal}})",
"desktop.wsl.error.serverExitedBeforeHealthy":
"WSL 伺服器在健全狀態確認前結束 (code={{code}} signal={{signal}}){{output}}",
"desktop.wsl.error.healthTimeout": "{{distro}} 的 Sidecar 健全狀態檢查在 {{timeout}}ms 後逾時",
"desktop.wsl.error.commandTimeout": "{{command}} {{args}} 在 {{timeout}}ms 後逾時",
"desktop.wsl.error.failedPort": "無法取得連接埠",
"desktop.picker.error.notSelected": "檔案選擇器未選取檔案",
"desktop.picker.error.sizeLimit": "所選附件超過 {{limit}} MB 的限制",
"command.category.suggested": "建議",
"command.category.view": "檢視",
"command.category.project": "專案",
@@ -21,6 +119,7 @@ export const dict = {
"command.category.workspace": "工作區",
"command.category.settings": "設定",
"command.logs.export": "匯出記錄檔",
"theme.scheme.system": "系統",
"theme.scheme.light": "淺色",
"theme.scheme.dark": "深色",
@@ -30,23 +129,23 @@ export const dict = {
"command.project.previous": "上一個專案",
"command.project.next": "下一個專案",
"command.project.index": "切換至專案 {{index}}",
"command.provider.connect": "連提供者",
"command.provider.connect": "連提供者",
"command.server.switch": "切換伺服器",
"command.settings.open": "開啟設定",
"command.session.previous": "上一個工作階段",
"command.session.next": "下一個工作階段",
"command.session.previous.unseen": "上一個未讀會話",
"command.session.next.unseen": "下一個未讀會話",
"command.session.previous.unseen": "上一個未讀工作階段",
"command.session.next.unseen": "下一個未讀工作階段",
"command.session.archive": "封存工作階段",
"command.palette": "命令面板",
"command.theme.cycle": "循環主題",
"command.theme.cycle": "依序切換主題",
"command.theme.set": "使用主題: {{theme}}",
"command.theme.scheme.cycle": "循環配色方案",
"command.theme.scheme.cycle": "依序切換配色方案",
"command.theme.scheme.set": "使用配色方案: {{scheme}}",
"command.language.cycle": "循環語言",
"command.language.cycle": "依序切換語言",
"command.language.set": "使用語言: {{language}}",
"command.session.new": "新增工作階段",
@@ -58,9 +157,9 @@ export const dict = {
"command.input.focus": "聚焦輸入框",
"command.terminal.toggle": "切換終端機",
"command.fileTree.toggle": "切換檔案樹",
"command.review.toggle": "切換審查",
"command.review.toggle": "切換檢閱",
"command.terminal.new": "新增終端機",
"command.terminal.new.description": "建立新的終端機標籤頁",
"command.terminal.new.description": "建立新的終端機頁",
"command.steps.toggle": "切換步驟",
"command.steps.toggle.description": "顯示或隱藏目前訊息的步驟",
"command.message.previous": "上一則訊息",
@@ -71,11 +170,11 @@ export const dict = {
"command.model.choose.description": "選擇不同的模型",
"command.mcp.toggle": "切換 MCP",
"command.mcp.toggle.description": "切換 MCP",
"command.agent.cycle": "循環代理程式",
"command.agent.cycle": "切換下一個代理程式",
"command.agent.cycle.description": "切換到下一個代理程式",
"command.agent.cycle.reverse": "反向循環代理程式",
"command.agent.cycle.reverse": "切換上一個代理程式",
"command.agent.cycle.reverse.description": "切換到上一個代理程式",
"command.model.variant.cycle": "循環思考強度",
"command.model.variant.cycle": "切換思考強度",
"command.model.variant.cycle.description": "切換到下一個強度等級",
"command.prompt.mode.shell": "Shell",
"command.prompt.mode.normal": "Prompt",
@@ -88,7 +187,7 @@ export const dict = {
"command.session.redo": "重做",
"command.session.redo.description": "重做上一則復原的訊息",
"command.session.compact": "精簡工作階段",
"command.session.compact.description": "總結工作階段以減少上下文大小",
"command.session.compact.description": "摘要工作階段以減少上下文大小",
"command.session.fork": "從訊息分支",
"command.session.fork.description": "從先前的訊息建立新工作階段",
"command.session.share": "分享工作階段",
@@ -106,13 +205,14 @@ export const dict = {
"dialog.provider.empty": "找不到提供者",
"dialog.provider.group.popular": "熱門",
"dialog.provider.group.other": "其他",
"dialog.provider.custom.label": "自訂 OpenAI 相容提供者",
"dialog.provider.tag.recommended": "推薦",
"dialog.provider.opencode.note": "精選模型,包含 Claude、GPT、Gemini 等等",
"dialog.provider.opencode.tagline": "可靠的優化模型",
"dialog.provider.opencode.tagline": "經過最佳化的可靠模型",
"dialog.provider.opencodeGo.tagline": "適合所有人的低成本訂閱",
"dialog.provider.anthropic.note": "使用 Claude Pro/Max 或 API 金鑰連線",
"dialog.provider.openai.note": "使用 ChatGPT Pro/Plus 或 API 金鑰連線",
"dialog.provider.copilot.note": "使用 Copilot API 金鑰連線",
"dialog.provider.anthropic.note": "直接存取 Claude 模型,包括 Pro 和 Max",
"dialog.provider.openai.note": "適合快速且功能強大的通用 AI 工作之 GPT 模型",
"dialog.provider.copilot.note": "透過 GitHub Copilot 使用程式設計輔助 AI 模型",
"dialog.provider.google.note": "Gemini 模型,提供快速且結構化的回應",
"dialog.provider.openrouter.note": "從單一提供者存取所有支援的模型",
"dialog.provider.vercel.note": "透過智慧路由統一存取 AI 模型",
@@ -126,6 +226,7 @@ export const dict = {
"dialog.model.unpaid.freeModels.title": "OpenCode 提供的免費模型",
"dialog.model.unpaid.addMore.title": "從熱門提供者新增更多模型",
"dialog.model.unpaid.viewMoreProviders": "查看另外 70 多個提供者",
"dialog.provider.viewAll": "查看更多提供者",
@@ -133,6 +234,8 @@ export const dict = {
"provider.connect.title.anthropicProMax": "使用 Claude Pro/Max 登入",
"provider.connect.selectMethod": "選擇 {{provider}} 的登入方式。",
"provider.connect.method.apiKey": "API 金鑰",
"provider.connect.method.browser": "瀏覽器",
"provider.connect.method.headless": "無頭模式",
"provider.connect.status.inProgress": "正在授權...",
"provider.connect.status.waiting": "等待授權...",
"provider.connect.status.failed": "授權失敗: {{error}}",
@@ -161,16 +264,17 @@ export const dict = {
"provider.connect.toast.connected.title": "{{provider}} 已連線",
"provider.connect.toast.connected.description": "現在可以使用 {{provider}} 模型了。",
"provider.custom.title": "自訂提供",
"provider.custom.description.prefix": "設定與 OpenAI 相容的提供商。請參閱",
"provider.custom.description.link": "提供商設定文件",
"provider.custom.title": "自訂提供",
"provider.custom.unavailable": "此伺服器無法使用自訂提供者",
"provider.custom.description.prefix": "設定與 OpenAI 相容的提供者。請參閱",
"provider.custom.description.link": "提供者設定文件",
"provider.custom.description.suffix": "。",
"provider.custom.field.providerID.label": "提供 ID",
"provider.custom.field.providerID.label": "提供 ID",
"provider.custom.field.providerID.placeholder": "myprovider",
"provider.custom.field.providerID.description": "使用小寫字母、數字、連字號或底線",
"provider.custom.field.name.label": "顯示名稱",
"provider.custom.field.name.placeholder": "我的 AI 提供",
"provider.custom.field.baseURL.label": "基 URL",
"provider.custom.field.name.placeholder": "我的 AI 提供",
"provider.custom.field.baseURL.label": "基 URL",
"provider.custom.field.baseURL.placeholder": "https://api.myprovider.com/v1",
"provider.custom.field.apiKey.label": "API 金鑰",
"provider.custom.field.apiKey.placeholder": "API 金鑰",
@@ -189,11 +293,11 @@ export const dict = {
"provider.custom.headers.value.placeholder": "value",
"provider.custom.headers.remove": "移除標頭",
"provider.custom.headers.add": "新增標頭",
"provider.custom.error.providerID.required": "提供 ID 為必填",
"provider.custom.error.providerID.required": "提供 ID 為必填",
"provider.custom.error.providerID.format": "請使用小寫字母、數字、連字號或底線",
"provider.custom.error.providerID.exists": "該提供 ID 已存在",
"provider.custom.error.providerID.exists": "該提供 ID 已存在",
"provider.custom.error.name.required": "顯示名稱為必填",
"provider.custom.error.baseURL.required": "基 URL 為必填",
"provider.custom.error.baseURL.required": "基 URL 為必填",
"provider.custom.error.baseURL.format": "必須以 http:// 或 https:// 開頭",
"provider.custom.error.required": "必填",
"provider.custom.error.duplicate": "重複",
@@ -212,12 +316,12 @@ export const dict = {
"model.input.image": "圖片",
"model.input.audio": "音訊",
"model.input.video": "影片",
"model.input.pdf": "pdf",
"model.input.pdf": "PDF",
"model.tooltip.allows": "支援: {{inputs}}",
"model.tooltip.context.label": "上下文",
"model.tooltip.inputs": "輸入",
"model.tooltip.model": "模型",
"model.tooltip.provider": "供應商",
"model.tooltip.provider": "提供者",
"model.tooltip.reasoning": "推理",
"model.tooltip.reasoning.allowed": "支援推理",
"model.tooltip.reasoning.none": "不支援推理",
@@ -231,7 +335,7 @@ export const dict = {
"common.clear": "清除",
"common.connect": "連線",
"common.disconnect": "中斷連線",
"common.continue": "提交",
"common.continue": "繼續",
"common.submit": "提交",
"common.save": "儲存",
"common.saving": "儲存中...",
@@ -239,10 +343,10 @@ export const dict = {
"common.attachment": "附件",
"prompt.placeholder.shell": "輸入 shell 命令... {{example}}",
"prompt.placeholder.normal": '隨便問點什麼... "{{example}}"',
"prompt.placeholder.simple": "隨便問點什麼...",
"prompt.placeholder.summarizeComments": "摘要評論…",
"prompt.placeholder.summarizeComment": "摘要這則評論…",
"prompt.placeholder.normal": "想問什麼都可以…「{{example}}」",
"prompt.placeholder.simple": "想問什麼都可以…",
"prompt.placeholder.summarizeComments": "摘要留言…",
"prompt.placeholder.summarizeComment": "摘要這則留言…",
"prompt.mode.shell": "Shell",
"prompt.mode.normal": "Prompt",
"prompt.mode.shell.exit": "按 esc 退出",
@@ -250,30 +354,30 @@ export const dict = {
"session.child.backToParent": "返回主要工作階段。",
"prompt.example.1": "修復程式碼庫中的一個 TODO",
"prompt.example.2": "這個專案的技術堆疊是什麼?",
"prompt.example.2": "這個專案的技術堆疊是什麼",
"prompt.example.3": "修復失敗的測試",
"prompt.example.4": "解釋驗證是如何運作的",
"prompt.example.5": "尋找並修復安全漏洞",
"prompt.example.6": "為使用者服務新增單元測試",
"prompt.example.7": "重構這個函式,讓它更易讀",
"prompt.example.8": "這個錯誤是什麼意思?",
"prompt.example.8": "這個錯誤是什麼意思",
"prompt.example.9": "幫我偵錯這個問題",
"prompt.example.10": "產生 API 文件",
"prompt.example.11": "最佳化資料庫查詢",
"prompt.example.12": "新增輸入驗證",
"prompt.example.13": "建立一個新的元件用於...",
"prompt.example.14": "我該如何部署這個專案?",
"prompt.example.15": "審查我的程式碼並給出最佳實務建議",
"prompt.example.14": "我該如何部署這個專案",
"prompt.example.15": "檢閱我的程式碼並提供最佳實務建議",
"prompt.example.16": "為這個函式新增錯誤處理",
"prompt.example.17": "解釋這個正規表示式",
"prompt.example.18": "把它轉換成 TypeScript",
"prompt.example.19": "在整個程式碼庫中新增日誌",
"prompt.example.20": "哪些相依性已經過期?",
"prompt.example.19": "在整個程式碼庫中加入記錄功能",
"prompt.example.20": "哪些相依性已經過期",
"prompt.example.21": "幫我寫一個遷移腳本",
"prompt.example.22": "為這個端點實作快取",
"prompt.example.23": "給這個清單新增分頁",
"prompt.example.23": "為這份清單加入分頁功能",
"prompt.example.24": "建立一個 CLI 命令用於...",
"prompt.example.25": "這裡的環境變數是怎麼運作的?",
"prompt.example.25": "這裡的環境變數是怎麼運作的",
"prompt.popover.emptyResults": "沒有符合的結果",
"prompt.popover.emptyCommands": "沒有符合的命令",
@@ -312,13 +416,13 @@ export const dict = {
"dialog.mcp.description": "已啟用 {{enabled}} / {{total}}",
"dialog.mcp.empty": "未設定 MCP",
"dialog.lsp.empty": "已從檔案類型自動偵測 LSPs",
"dialog.lsp.empty": "會根據檔案類型自動偵測 LSP",
"dialog.plugins.empty": "在 opencode.json 中設定的外掛程式",
"mcp.status.connected": "已連線",
"mcp.status.failed": "失敗",
"mcp.status.needs_auth": "需要授權",
"mcp.auth.clickToAuthenticate": "點擊以進行授權",
"mcp.auth.clickToAuthenticate": "按一下以進行授權",
"mcp.status.disabled": "已停用",
"dialog.fork.empty": "沒有可用於分支的訊息",
@@ -334,7 +438,7 @@ export const dict = {
"dialog.server.title": "伺服器",
"dialog.server.description": "切換此應用程式連線的 OpenCode 伺服器。",
"dialog.server.search.placeholder": "搜尋伺服器",
"dialog.server.empty": "無伺服器",
"dialog.server.empty": "無伺服器",
"dialog.server.add.title": "新增伺服器",
"dialog.server.add.url": "伺服器 URL",
"dialog.server.add.placeholder": "http://localhost:4096",
@@ -347,7 +451,7 @@ export const dict = {
"dialog.server.add.password": "密碼(選填)",
"dialog.server.edit.title": "編輯伺服器",
"dialog.server.default.title": "預設伺服器",
"dialog.server.default.description": "應用程式啟動時連線此伺服器,而不是啟動本伺服器。需要重新啟動。",
"dialog.server.default.description": "應用程式啟動時連線此伺服器,而不是啟動本伺服器。需要重新啟動。",
"dialog.server.default.none": "未選擇伺服器",
"dialog.server.default.set": "將目前伺服器設為預設",
"dialog.server.default.clear": "清除",
@@ -427,11 +531,26 @@ export const dict = {
"wsl.onboarding.versionMismatch": "已安裝版本與桌面應用程式版本不符。",
"wsl.onboarding.adding": "新增中...",
"help.tabs.toast.ariaLabel": "分頁功能介紹。使用分頁整理工作和進行中的工作階段",
"help.tabs.toast.dismiss": "關閉分頁功能資訊",
"help.tabs.title": "分頁功能介紹",
"help.tabs.description": "使用分頁整理工作和進行中的工作階段",
"help.tabs.date": "7 月 14 日",
"help.tabs.introduction": "OpenCode Desktop 現在以分頁為核心。",
"help.tabs.sessions":
"在分頁中開始新的工作階段,或從任一專案開啟現有的工作階段。開始新工作時請開啟新分頁,完成後再將其關閉。",
"help.tabs.organize":
"同時開啟幾個分頁,可讓進行中的工作階段更容易整理。如果打算保留分頁,請將其重新命名為容易記住的名稱。",
"help.tabs.home": "你可以在新的首頁找到所有工作階段和專案。選取工作階段即可在分頁中開啟。",
"help.tabs.persistence": "重新開啟應用程式時,分頁仍會保持開啟。",
"help.tabs.worktrees":
"新版設計尚未支援 Git Worktrees,此功能即將推出。如果你偏好繼續使用先前的版面,可以在設定中切換版面。請留意,新版面將在幾週後成為永久版面。",
"dialog.project.edit.title": "編輯專案",
"dialog.project.edit.name": "名稱",
"dialog.project.edit.icon": "圖示",
"dialog.project.edit.icon.alt": "專案圖示",
"dialog.project.edit.icon.hint": "點擊或拖曳圖片",
"dialog.project.edit.icon.hint": "按一下或拖曳圖片",
"dialog.project.edit.icon.recommended": "建議:128x128px",
"dialog.project.edit.color": "顏色",
"dialog.project.edit.color.select": "選擇{{color}}顏色",
@@ -439,11 +558,11 @@ export const dict = {
"dialog.project.edit.worktree.startup": "工作區啟動腳本",
"dialog.project.edit.worktree.startup.description": "在建立新的工作區 (worktree) 後執行。",
"dialog.project.edit.worktree.startup.placeholder": "例如 bun install",
"context.breakdown.title": "上下文分",
"context.breakdown.note": "輸入 token 的大致拆分。「其他」包含工具定義和額外開銷。",
"context.breakdown.title": "上下文分",
"context.breakdown.note": "輸入 token 的概略細分。「其他」包含工具定義和額外負擔。",
"context.breakdown.system": "系統",
"context.breakdown.user": "使用者",
"context.breakdown.assistant": "助",
"context.breakdown.assistant": "助",
"context.breakdown.tool": "工具呼叫",
"context.breakdown.other": "其他",
@@ -462,7 +581,7 @@ export const dict = {
"context.stats.reasoningTokens": "推理 token",
"context.stats.cacheTokens": "快取 token(讀/寫)",
"context.stats.userMessages": "使用者訊息",
"context.stats.assistantMessages": "助訊息",
"context.stats.assistantMessages": "助訊息",
"context.stats.totalCost": "總成本",
"context.stats.sessionCreated": "建立時間",
"context.stats.lastActivity": "最後活動",
@@ -470,7 +589,7 @@ export const dict = {
"context.usage.tokens": "Token",
"context.usage.usage": "使用量",
"context.usage.cost": "成本",
"context.usage.clickToView": "點擊查看上下文",
"context.usage.clickToView": "按一下以檢視上下文",
"context.usage.view": "檢視上下文用量",
"language.en": "English",
@@ -496,7 +615,7 @@ export const dict = {
"toast.language.description": "已切換到 {{language}}",
"toast.theme.title": "主題已切換",
"toast.scheme.title": "色方案",
"toast.scheme.title": "色方案",
"toast.workspace.enabled.title": "工作區已啟用",
"toast.workspace.enabled.description": "側邊欄現在顯示多個工作樹",
@@ -504,12 +623,12 @@ export const dict = {
"toast.workspace.disabled.description": "側邊欄只顯示主工作樹",
"toast.permissions.autoaccept.on.title": "正在自動接受權限",
"toast.permissions.autoaccept.on.description": "權限求將自動准",
"toast.permissions.autoaccept.on.description": "權限求將自動准",
"toast.permissions.autoaccept.off.title": "已停止自動接受權限",
"toast.permissions.autoaccept.off.description": "權限求將需要准",
"toast.permissions.autoaccept.off.description": "權限求將需要准",
"toast.model.none.title": "未選擇模型",
"toast.model.none.description": "請先連線提供者以總結此工作階段",
"toast.model.none.description": "請先連線提供者以摘要此工作階段",
"toast.file.loadFailed.title": "載入檔案失敗",
@@ -541,7 +660,7 @@ export const dict = {
"error.page.action.restart": "重新啟動",
"error.page.action.report": "回報錯誤",
"error.page.action.reported": "已回報錯誤",
"error.page.action.exportLogs": "匯出日誌",
"error.page.action.exportLogs": "匯出記錄檔",
"error.page.action.checking": "檢查中...",
"error.page.action.checkUpdates": "檢查更新",
"error.page.action.updateTo": "更新到 {{version}}",
@@ -549,9 +668,9 @@ export const dict = {
"error.page.report.discord": "在 Discord 上",
"error.page.version": "版本: {{version}}",
"error.dev.rootNotFound": "找不到根元素。你是不是忘了把它新增到 index.html? 或者 id 屬性拼錯了?",
"error.dev.rootNotFound": "找不到根元素。你是不是忘了把它新增到 index.html或者 id 屬性拼錯了",
"error.serverSync.connectFailed": "無法連線到伺服器。是否有伺服器正在 `{{url}}` 執行?",
"error.serverSync.connectFailed": "無法連線到伺服器。是否有伺服器正在 `{{url}}` 執行",
"directory.error.invalidUrl": "URL 中的目錄無效。",
"error.chain.unknown": "未知錯誤",
@@ -563,8 +682,8 @@ export const dict = {
"error.chain.didYouMean": "你是不是想輸入: {{suggestions}}",
"error.chain.modelNotFound": "找不到模型: {{provider}}/{{model}}",
"error.chain.checkConfig": "請檢查你的設定 (opencode.json) 中的 provider/model 名稱",
"error.chain.mcpFailed": 'MCP 伺服器 "{{name}}" 啟動失敗。注意: OpenCode 不支援 MCP 證。',
"error.chain.providerAuthFailed": "提供者證失敗 ({{provider}}): {{message}}",
"error.chain.mcpFailed": "MCP 伺服器{{name}}啟動失敗。注意OpenCode 不支援 MCP 證。",
"error.chain.providerAuthFailed": "提供者證失敗{{provider}}):{{message}}",
"error.chain.providerInitFailed": '無法初始化提供者 "{{provider}}"。請檢查憑證和設定。',
"error.chain.configJsonInvalid": "設定檔 {{path}} 不是有效的 JSON(C)",
"error.chain.configJsonInvalidWithMessage": "設定檔 {{path}} 不是有效的 JSON(C): {{message}}",
@@ -586,7 +705,7 @@ export const dict = {
"home.recentProjects": "最近專案",
"home.empty.title": "沒有最近專案",
"home.empty.description": "透過開啟本專案開始使用",
"home.empty.description": "開啟本專案開始使用",
"home.title": "首頁",
"home.projects": "專案",
"home.project.add": "新增專案",
@@ -602,13 +721,13 @@ export const dict = {
"home.sessions.group.today": "今天",
"home.sessions.group.yesterday": "昨天",
"home.sessions.group.older": "更早",
"home.providerTip": "連 75 個以上的供應商,使用 Claude、GPT、Gemini 等其他模型",
"home.providerTip": "連 75 個以上的提供者,使用 Claude、GPT、Gemini 等其他模型",
"session.tab.session": "工作階段",
"session.tab.review": "審查",
"session.tab.review": "檢閱",
"session.tab.context": "上下文",
"session.tab.unknown": "未知的工作階段",
"session.panel.reviewAndFiles": "審查與檔案",
"session.panel.reviewAndFiles": "檢閱與檔案",
"session.error.notFound": "找不到此工作階段",
"session.error.notFound.description": "此分頁指向的工作階段已不存在於此伺服器。",
"session.error.notFound.closeTab": "關閉分頁",
@@ -617,7 +736,7 @@ export const dict = {
"session.review.change.one": "變更",
"session.review.change.other": "變更",
"session.review.loadingChanges": "正在載入變更...",
"session.review.empty": "此工作階段無變更",
"session.review.empty": "此工作階段無變更",
"session.review.noChanges": "沒有變更",
"session.review.noUncommittedChanges": "尚無未提交的變更",
"session.review.noBranchChanges": "尚無分支變更",
@@ -635,7 +754,7 @@ export const dict = {
"session.messages.jumpToLatest": "跳到最新",
"session.context.addToContext": "將 {{selection}} 新增到上下文",
"session.todo.title": "待辦事項",
"session.todo.collapse": "折疊",
"session.todo.collapse": "收合",
"session.todo.expand": "展開",
"session.question.minimize": "最小化問題",
"session.question.restore": "還原問題",
@@ -647,13 +766,13 @@ export const dict = {
"session.followupDock.edit": "編輯",
"session.followupDock.collapse": "收合佇列訊息",
"session.followupDock.expand": "展開佇列訊息",
"session.revertDock.summary.one": "{{count}} 則已回復訊息",
"session.revertDock.summary.other": "{{count}} 則已回復訊息",
"session.revertDock.collapse": "收合已回復訊息",
"session.revertDock.expand": "展開已回復訊息",
"session.revertDock.summary.one": "{{count}} 則已還原的訊息",
"session.revertDock.summary.other": "{{count}} 則已還原的訊息",
"session.revertDock.collapse": "收合已還原的訊息",
"session.revertDock.expand": "展開已還原的訊息",
"session.revertDock.restore": "還原訊息",
"session.new.title": "建構任何東西",
"session.new.title": "實現任何想法",
"session.new.project.new": "新專案",
"session.new.project.search": "搜尋專案",
"session.new.project.add": "新增專案",
@@ -706,7 +825,12 @@ export const dict = {
"terminal.connectionLost.title": "連線中斷",
"terminal.connectionLost.description": "終端機連線已中斷。這可能會在伺服器重新啟動時發生。",
"common.closeTab": "關閉標籤頁",
"terminal.connectTicket.csrfError": "PTY 連線票證因來源或 CSRF 檢查而遭拒。請檢查伺服器 CORS 設定。",
"terminal.connectTicket.statusError": "PTY 連線票證失敗,狀態為 {{status}}",
"titlebar.update": "更新",
"titlebar.updateVersion": "更新 {{version}}",
"common.closeTab": "關閉分頁",
"common.dismiss": "忽略",
"common.requestFailed": "要求失敗",
"common.moreOptions": "更多選項",
@@ -832,41 +956,41 @@ export const dict = {
"sound.option.alert08": "警報 08",
"sound.option.alert09": "警報 09",
"sound.option.alert10": "警報 10",
"sound.option.bipbop01": "嗶啵 01",
"sound.option.bipbop02": "嗶啵 02",
"sound.option.bipbop03": "嗶啵 03",
"sound.option.bipbop04": "嗶啵 04",
"sound.option.bipbop05": "嗶啵 05",
"sound.option.bipbop06": "嗶啵 06",
"sound.option.bipbop07": "嗶啵 07",
"sound.option.bipbop08": "嗶啵 08",
"sound.option.bipbop09": "嗶啵 09",
"sound.option.bipbop10": "嗶啵 10",
"sound.option.staplebops01": "斯泰普博普斯 01",
"sound.option.staplebops02": "斯泰普博普斯 02",
"sound.option.staplebops03": "斯泰普博普斯 03",
"sound.option.staplebops04": "斯泰普博普斯 04",
"sound.option.staplebops05": "斯泰普博普斯 05",
"sound.option.staplebops06": "斯泰普博普斯 06",
"sound.option.staplebops07": "斯泰普博普斯 07",
"sound.option.nope01": " 01",
"sound.option.nope02": " 02",
"sound.option.nope03": " 03",
"sound.option.nope04": " 04",
"sound.option.nope05": " 05",
"sound.option.nope06": " 06",
"sound.option.nope07": " 07",
"sound.option.nope08": " 08",
"sound.option.nope09": " 09",
"sound.option.nope10": " 10",
"sound.option.nope11": " 11",
"sound.option.nope12": " 12",
"sound.option.yup01": " 01",
"sound.option.yup02": " 02",
"sound.option.yup03": " 03",
"sound.option.yup04": " 04",
"sound.option.yup05": " 05",
"sound.option.yup06": " 06",
"sound.option.bipbop01": "Bip-bop 01",
"sound.option.bipbop02": "Bip-bop 02",
"sound.option.bipbop03": "Bip-bop 03",
"sound.option.bipbop04": "Bip-bop 04",
"sound.option.bipbop05": "Bip-bop 05",
"sound.option.bipbop06": "Bip-bop 06",
"sound.option.bipbop07": "Bip-bop 07",
"sound.option.bipbop08": "Bip-bop 08",
"sound.option.bipbop09": "Bip-bop 09",
"sound.option.bipbop10": "Bip-bop 10",
"sound.option.staplebops01": "Staplebops 01",
"sound.option.staplebops02": "Staplebops 02",
"sound.option.staplebops03": "Staplebops 03",
"sound.option.staplebops04": "Staplebops 04",
"sound.option.staplebops05": "Staplebops 05",
"sound.option.staplebops06": "Staplebops 06",
"sound.option.staplebops07": "Staplebops 07",
"sound.option.nope01": "Nope 01",
"sound.option.nope02": "Nope 02",
"sound.option.nope03": "Nope 03",
"sound.option.nope04": "Nope 04",
"sound.option.nope05": "Nope 05",
"sound.option.nope06": "Nope 06",
"sound.option.nope07": "Nope 07",
"sound.option.nope08": "Nope 08",
"sound.option.nope09": "Nope 09",
"sound.option.nope10": "Nope 10",
"sound.option.nope11": "Nope 11",
"sound.option.nope12": "Nope 12",
"sound.option.yup01": "Yup 01",
"sound.option.yup02": "Yup 02",
"sound.option.yup03": "Yup 03",
"sound.option.yup04": "Yup 04",
"sound.option.yup05": "Yup 05",
"sound.option.yup06": "Yup 06",
"settings.general.notifications.agent.title": "代理程式",
"settings.general.notifications.agent.description": "當代理程式完成或需要注意時顯示系統通知",
"settings.general.notifications.permissions.title": "權限",
@@ -901,11 +1025,11 @@ export const dict = {
"settings.providers.title": "提供者",
"settings.providers.description": "提供者設定將在此處可設定。",
"settings.providers.section.connected": "已連線的提供",
"settings.providers.connected.empty": "沒有已連線的提供",
"settings.providers.section.popular": "熱門提供",
"settings.providers.section.connected": "已連線的提供",
"settings.providers.connected.empty": "沒有已連線的提供",
"settings.providers.section.popular": "熱門提供",
"settings.providers.tag.environment": "環境",
"settings.providers.tag.config": "配置",
"settings.providers.tag.config": "設定",
"settings.providers.tag.custom": "自訂",
"settings.providers.tag.other": "其他",
"settings.models.title": "模型",
@@ -957,11 +1081,11 @@ export const dict = {
"session.delete.failed.title": "刪除工作階段失敗",
"session.delete.title": "刪除工作階段",
"session.delete.confirm": '刪除工作階段 "{{name}}"?',
"session.delete.confirm": "要刪除工作階段{{name}}」嗎?",
"session.delete.button": "刪除工作階段",
"workspace.new": "新增工作區",
"workspace.type.local": "本",
"workspace.type.local": "本",
"workspace.type.sandbox": "沙盒",
"workspace.create.failed.title": "建立工作區失敗",
"workspace.delete.failed.title": "刪除工作區失敗",
@@ -969,27 +1093,27 @@ export const dict = {
"workspace.resetting.description": "這可能需要一點時間。",
"workspace.reset.failed.title": "重設工作區失敗",
"workspace.reset.success.title": "工作區已重設",
"workspace.reset.success.description": "工作區與預設分支保持一致。",
"workspace.reset.success.description": "工作區現在與預設分支一致。",
"workspace.error.stillPreparing": "工作區仍在準備中",
"workspace.status.checking": "正在檢查未合併的變更...",
"workspace.status.error": "無法驗證 git 狀態。",
"workspace.status.error": "無法驗證 Git 狀態。",
"workspace.status.clean": "未偵測到未合併的變更。",
"workspace.status.dirty": "偵測到未合併的變更。",
"workspace.delete.title": "刪除工作區",
"workspace.delete.confirm": '刪除工作區 "{{name}}"?',
"workspace.delete.confirm": "要刪除工作區{{name}}」嗎?",
"workspace.delete.button": "刪除工作區",
"workspace.reset.title": "重設工作區",
"workspace.reset.confirm": '重設工作區 "{{name}}"?',
"workspace.reset.confirm": "要重設工作區{{name}}」嗎?",
"workspace.reset.button": "重設工作區",
"workspace.reset.archived.none": "不會封存任何作用中工作階段。",
"workspace.reset.archived.one": "將封存 1 個工作階段。",
"workspace.reset.archived.many": "將封存 {{count}} 個工作階段。",
"workspace.reset.note": "這將把工作區重設為與預設分支一致。",
"common.open": "開",
"common.open": "開",
"dialog.releaseNotes.action.getStarted": "開始",
"dialog.releaseNotes.action.next": "下一步",
"dialog.releaseNotes.action.hideFuture": "不再顯示",
"dialog.releaseNotes.media.alt": "發佈預覽",
"dialog.releaseNotes.media.alt": "版本預覽",
"toast.project.reloadFailed.title": "無法重新載入 {{project}}",
"error.server.invalidConfiguration": "無效的設定",
"common.moreCountSuffix": " (還有 {{count}} 個)",
@@ -998,7 +1122,7 @@ export const dict = {
"common.time.hoursAgo.short": "{{count}}小時前",
"common.time.daysAgo.short": "{{count}}天前",
"settings.providers.connected.environmentDescription": "已從環境變數連線",
"settings.providers.custom.description": "透過基 URL 新增與 OpenAI 相容的提供者。",
"settings.providers.custom.description": "透過基 URL 新增與 OpenAI 相容的提供者。",
"app.server.unreachable": "無法連線至 {{server}}",
"app.server.retrying": "正在自動重試...",
@@ -1014,6 +1138,9 @@ export const dict = {
"session.question.progress": "{{current}}/{{total}} 個問題",
"session.header.open.finder": "Finder",
"session.header.open.fileExplorer": "檔案總管",
"session.header.reveal.finder": "在 Finder 中顯示",
"session.header.reveal.fileExplorer": "在檔案總管中顯示",
"session.header.reveal.containingFolder": "開啟所在的檔案夾",
"session.header.open.fileManager": "檔案管理員",
"session.header.open.app.vscode": "VS Code",
"session.header.open.app.cursor": "Cursor",
@@ -1033,11 +1160,11 @@ export const dict = {
"debugBar.nav.label": "NAV",
"debugBar.nav.tip": "最後一次完成的涉及工作階段頁面的路由轉換,從路由器啟動到穩定後的第一次繪製。",
"debugBar.fps.label": "FPS",
"debugBar.fps.tip": "過去 5 秒內的滾動幀率。",
"debugBar.fps.tip": "過去 5 秒內的移動影格率。",
"debugBar.frame.label": "FRAME",
"debugBar.frame.tip": "過去 5 秒內最差的時間。",
"debugBar.frame.tip": "過去 5 秒內最差的影格時間。",
"debugBar.jank.label": "JANK",
"debugBar.jank.tip": "過去 5 秒內超過 32ms 的。",
"debugBar.jank.tip": "過去 5 秒內超過 32ms 的影格。",
"debugBar.long.label": "LONG",
"debugBar.long.tip": "過去 5 秒內的阻塞時間和長任務計數。最大任務:{{max}}。",
"debugBar.delay.label": "DELAY",
@@ -1049,6 +1176,14 @@ export const dict = {
"debugBar.mem.label": "MEM",
"debugBar.mem.tipUnavailable": "使用的 JS 堆積與堆積限制。僅限 Chromium。",
"debugBar.mem.tip": "使用的 JS 堆積與堆積限制。{{used}} / {{limit}}。",
"debugBar.focus.label": "FOCUS",
"debugBar.focus.tip": "強制所有互動元素顯示焦點樣式",
"debugBar.focus.on": "開啟",
"debugBar.focus.off": "關閉",
"debugBar.direction.label": "DIR",
"debugBar.direction.tip": "在不變更所選語言的情況下,強制設定整個應用程式的版面配置方向",
"debugBar.direction.ltr": "LTR",
"debugBar.direction.rtl": "RTL",
"common.key.ctrl": "Ctrl",
"common.key.alt": "Alt",
"common.key.shift": "Shift",
+1 -1
View File
@@ -8,7 +8,7 @@ export { useTabs } from "./context/tabs"
export { useProviders } from "./hooks/use-providers"
export { ACCEPTED_FILE_EXTENSIONS, ACCEPTED_FILE_TYPES, filePickerFilters } from "./constants/file-picker"
export { useCommand } from "./context/command"
export { loadLocaleDict, normalizeLocale, type Locale } from "./context/language"
export { loadLocaleDict, normalizeLocale, type Locale, useLanguage } from "./context/language"
export { useWslServers } from "./wsl/context"
export { type DisplayBackend, type FatalRendererErrorLog, type Platform, PlatformProvider } from "./context/platform"
export { type UpdaterPlatform, type UpdaterState } from "./updater"
@@ -1,7 +1,6 @@
import type { Session } from "@opencode-ai/sdk/v2/client"
import { preloadMarkdown } from "@opencode-ai/session-ui/markdown-cache"
import { useDialog } from "@opencode-ai/ui/context/dialog"
import { useMarked } from "@opencode-ai/ui/context/marked"
import { useQuery } from "@tanstack/solid-query"
import { DateTime } from "luxon"
import { type Accessor, createEffect, createMemo, createRoot, type JSX, startTransition } from "solid-js"
@@ -44,7 +43,6 @@ export function createHomeSessionsController(home: HomeController) {
const command = useCommand()
const dialog = useDialog()
const language = useLanguage()
const marked = useMarked()
const projectDirectories = createMemo(() => {
const project = home.project.selected()
if (!project) return home.project.list().flatMap(directories)
@@ -119,7 +117,7 @@ export function createHomeSessionsController(home: HomeController) {
(ctx.sync.session.data.message[record.session.id] ?? []).flatMap((message) =>
(ctx.sync.session.data.part[message.id] ?? []).flatMap((part) => {
if (part.type !== "text" || !part.text) return []
return preloadMarkdown(part.text, part.id, marked)
return preloadMarkdown(part.text, part.id)
}),
),
),
+15 -14
View File
@@ -2278,7 +2278,7 @@ export default function LegacyLayout(props: ParentProps) {
data-component="sidebar-nav-desktop"
classList={{
"hidden xl:block": true,
"absolute inset-y-0 left-0": true,
"absolute inset-y-0 start-0": true,
"z-10": true,
}}
style={{ width: `${side()}px` }}
@@ -2301,7 +2301,7 @@ export default function LegacyLayout(props: ParentProps) {
<Show when={layout.sidebar.opened()}>
<div
class="hidden xl:block absolute inset-y-0 z-30 w-0 overflow-visible"
style={{ left: `${side()}px` }}
style={{ "inset-inline-start": `${side()}px` }}
onPointerDown={() => setState("sizing", true)}
>
<ResizeHandle
@@ -2320,8 +2320,8 @@ export default function LegacyLayout(props: ParentProps) {
</Show>
<div
class="hidden xl:block pointer-events-none absolute top-0 right-0 z-0 border-t border-border-weaker-base"
style={{ left: "calc(4rem + 12px)" }}
class="hidden xl:block pointer-events-none absolute top-0 end-0 z-0 border-t border-border-weaker-base"
style={{ "inset-inline-start": "calc(4rem + 12px)" }}
/>
<div class="xl:hidden">
@@ -2339,9 +2339,9 @@ export default function LegacyLayout(props: ParentProps) {
aria-label={language.t("sidebar.nav.projectsAndSessions")}
data-component="sidebar-nav-mobile"
classList={{
"@container fixed top-10 bottom-0 left-0 z-50 w-full max-w-[400px] overflow-hidden border-r border-border-weaker-base bg-background-base transition-transform duration-200 ease-out": true,
"@container fixed top-10 bottom-0 start-0 z-50 w-full max-w-[400px] overflow-hidden border-e border-border-weaker-base bg-background-base transition-transform duration-200 ease-out": true,
"translate-x-0": layout.mobileSidebar.opened(),
"-translate-x-full": !layout.mobileSidebar.opened(),
"ltr:-translate-x-full rtl:translate-x-full": !layout.mobileSidebar.opened(),
}}
onClick={(e) => e.stopPropagation()}
>
@@ -2352,9 +2352,9 @@ export default function LegacyLayout(props: ParentProps) {
<div
classList={{
"absolute inset-0": true,
"xl:inset-y-0 xl:right-0 xl:left-[var(--main-left)]": true,
"xl:inset-y-0 xl:end-0 xl:start-[var(--main-left)]": true,
"z-20": true,
"transition-[left] duration-200 ease-[cubic-bezier(0.22,1,0.36,1)] will-change-[left] motion-reduce:transition-none":
"transition-[inset-inline-start] duration-200 ease-[cubic-bezier(0.22,1,0.36,1)] will-change-[inset-inline-start] motion-reduce:transition-none":
!state.sizing,
}}
style={{
@@ -2363,7 +2363,7 @@ export default function LegacyLayout(props: ParentProps) {
>
<main
classList={{
"size-full overflow-x-hidden flex flex-col items-start contain-strict border-t border-border-weak-base bg-background-base xl:border-l xl:rounded-tl-[12px]": true,
"size-full overflow-x-hidden flex flex-col items-start contain-strict border-t border-border-weak-base bg-background-base xl:border-s xl:rounded-ss-[12px]": true,
}}
>
<Show when={!autoselecting.loading} fallback={<div class="size-full" />}>
@@ -2374,9 +2374,10 @@ export default function LegacyLayout(props: ParentProps) {
<div
classList={{
"hidden xl:flex absolute inset-y-0 left-16 z-30": true,
"hidden xl:flex absolute inset-y-0 start-16 z-30": true,
"opacity-100 translate-x-0 pointer-events-auto": state.peeked && !layout.sidebar.opened(),
"opacity-0 -translate-x-2 pointer-events-none": !state.peeked || layout.sidebar.opened(),
"opacity-0 ltr:-translate-x-2 rtl:translate-x-2 pointer-events-none":
!state.peeked || layout.sidebar.opened(),
"transition-[opacity,transform] motion-reduce:transition-none": true,
"duration-180 ease-out": state.peeked && !layout.sidebar.opened(),
"duration-120 ease-in": !state.peeked || layout.sidebar.opened(),
@@ -2398,14 +2399,14 @@ export default function LegacyLayout(props: ParentProps) {
<div
classList={{
"hidden xl:block pointer-events-none absolute inset-y-0 right-0 z-25 overflow-hidden": true,
"hidden xl:block pointer-events-none absolute inset-y-0 end-0 z-25 overflow-hidden": true,
"opacity-100 translate-x-0": state.peeked && !layout.sidebar.opened(),
"opacity-0 -translate-x-2": !state.peeked || layout.sidebar.opened(),
"opacity-0 ltr:-translate-x-2 rtl:translate-x-2": !state.peeked || layout.sidebar.opened(),
"transition-[opacity,transform] motion-reduce:transition-none": true,
"duration-180 ease-out": state.peeked && !layout.sidebar.opened(),
"duration-120 ease-in": !state.peeked || layout.sidebar.opened(),
}}
style={{ left: `calc(4rem + ${panel()}px)` }}
style={{ "inset-inline-start": `calc(4rem + ${panel()}px)` }}
>
<div class="h-full w-px" style={{ "box-shadow": "var(--shadow-sidebar-overlay)" }} />
</div>
+1 -1
View File
@@ -2282,7 +2282,7 @@ export default function Page() {
<div onPointerDown={() => size.start()}>
<ResizeHandle
classList={{
"-right-1": settings.general.newLayoutDesigns(),
"-end-1": settings.general.newLayoutDesigns(),
}}
direction="horizontal"
size={sessionPanelResizedWidth()}
@@ -18,11 +18,7 @@ export function SessionFollowupDock(props: {
const toggle = () => setStore("collapsed", (value) => !value)
const total = createMemo(() => props.items.length)
const label = createMemo(() =>
language.t(total() === 1 ? "session.followupDock.summary.one" : "session.followupDock.summary.other", {
count: total(),
}),
)
const label = createMemo(() => language.plural("session.followupDock.summary", total()))
const preview = createMemo(() => props.items[0]?.text ?? "")
return (
@@ -472,7 +472,7 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit
data-answered={answered(i())}
disabled={sending()}
onClick={() => jump(i())}
aria-label={`${language.t("ui.tool.questions")} ${i() + 1}`}
aria-label={language.t("ui.tool.questions.numbered", { number: i() + 1 })}
/>
)}
</For>
@@ -29,11 +29,7 @@ export function SessionRevertDock(props: {
const toggle = () => setStore("collapsed", (value) => !value)
const total = createMemo(() => props.items.length)
const label = createMemo(() =>
language.t(total() === 1 ? "session.revertDock.summary.one" : "session.revertDock.summary.other", {
count: total(),
}),
)
const label = createMemo(() => language.plural("session.revertDock.summary", total()))
const preview = createMemo(() => props.items[0]?.text ?? "")
const onHeaderKeyDown = (event: KeyboardEvent) => {
@@ -161,10 +161,7 @@ function TimelineDiffSummaryRow(props: { diffs: SummaryDiff[] }) {
>
<div data-slot="session-turn-diffs-header">
<span data-slot="session-turn-diffs-label">
{language.t(
props.diffs.length === 1 ? "ui.sessionTurn.diffs.changed.one" : "ui.sessionTurn.diffs.changed.other",
{ count: String(props.diffs.length) },
)}
{language.plural("ui.sessionTurn.diffs.changed", props.diffs.length)}
</span>
<DiffChanges changes={props.diffs} />
<Show when={overflow() > 0}>
@@ -1106,7 +1103,7 @@ export function MessageTimeline(props: {
return (
<TimelineRowFrame row={commentStripRow}>
<div class="w-full px-4 md:px-5 pb-2">
<div class="ml-auto max-w-[82%] overflow-x-auto no-scrollbar">
<div class="ms-auto max-w-[82%] overflow-x-auto no-scrollbar">
<div class="flex w-max min-w-full justify-end gap-2">
<Index each={comments()}>
{(comment) => (
+2 -1
View File
@@ -568,8 +568,9 @@ export function removePersisted(
export function persisted<T>(
target: string | PersistTarget,
store: [Store<T>, SetStoreFunction<T>],
platformOverride?: Platform,
): PersistedWithReady<T> {
const platform = usePlatform()
const platform = platformOverride ?? usePlatform()
const config = resolveTarget(typeof target === "string" ? { key: target } : target, platform)
const defaults = snapshot(store[0])
+12
View File
@@ -1,5 +1,17 @@
const pattern = /^(New session|Child session) - \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/
interface Info {
readonly title?: string
readonly parentID?: string
readonly time: {
readonly created: number
}
}
export function withTimestampedFallback(info: Info) {
return info.title ?? `${info.parentID ? "Child" : "New"} session - ${new Date(info.time.created).toISOString()}`
}
export function sessionTitle(title?: string) {
if (!title) return title
const match = title.match(pattern)
+20
View File
@@ -36,6 +36,14 @@ describe("normalizeSessionInfo", () => {
revert: { messageID: "message-1", partID: "part-1", snapshot: "snapshot" },
})
})
test("supplies timestamped titles for untitled current sessions", () => {
const root = currentSession("session-1")
const child = currentSession("session-2", "session-1")
expect(normalizeSessionInfo(root).title).toBe("New session - 1970-01-01T00:00:00.000Z")
expect(normalizeSessionInfo(child).title).toBe("Child session - 1970-01-01T00:00:00.000Z")
})
})
describe("listAllSessions", () => {
@@ -92,3 +100,15 @@ function sessionInfo(id: string, archived = false) {
location: { directory: "/repo" },
} as SessionInfo
}
function currentSession(id: string, parentID?: string) {
return {
id,
parentID,
projectID: "project-1",
cost: 0,
tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
time: { created: 0, updated: 0 },
location: { directory: "/repo" },
} as SessionInfo
}
+2 -1
View File
@@ -1,5 +1,6 @@
import type { SessionApi, SessionInfo, SessionListInput } from "@opencode-ai/client/promise"
import type { Session } from "@opencode-ai/sdk/v2/client"
import { withTimestampedFallback } from "./session-title"
export function normalizeSessionInfo(input: SessionInfo | Session): Session {
if (!("location" in input)) return input
@@ -13,7 +14,7 @@ export function normalizeSessionInfo(input: SessionInfo | Session): Session {
parentID: input.parentID,
cost: input.cost,
tokens: input.tokens,
title: input.title,
title: withTimestampedFallback(input),
agent: input.agent,
model: input.model,
version: "",
+2 -2
View File
@@ -48,7 +48,7 @@ describe("WSL server settings presentation", () => {
matchesDesktop: null,
error: null,
}),
).toBe("Install OpenCode")
).toBe("wsl.onboarding.installOpencode")
expect(
wslOpencodeAction({
distro: "Debian",
@@ -58,7 +58,7 @@ describe("WSL server settings presentation", () => {
matchesDesktop: false,
error: null,
}),
).toBe("Update OpenCode")
).toBe("wsl.onboarding.updateOpencode")
expect(
wslOpencodeAction({
distro: "Debian",
+2 -2
View File
@@ -53,8 +53,8 @@ export const wslRuntimeRetryable = (runtime: WslServerRuntime) =>
export function wslOpencodeAction(check?: WslOpencodeCheck) {
if (!check) return
if (!check.resolvedPath) return "Install OpenCode"
if (check.matchesDesktop === false) return "Update OpenCode"
if (!check.resolvedPath) return "wsl.onboarding.installOpencode"
if (check.matchesDesktop === false) return "wsl.onboarding.updateOpencode"
}
export function wslDistroReady(state: WslServersState | undefined, name: string) {
+1 -1
View File
@@ -124,7 +124,7 @@ export function WslServerSettings(props: {
disabled={busy() || request.isPending}
onClick={() => api && request.mutate(() => api.installOpencode(item.config.distro))}
>
{busy() ? language.t("wsl.server.updating") : label()}
{busy() ? language.t("wsl.server.updating") : language.t(label())}
</ButtonV2>
)}
</Show>
@@ -1,10 +1,11 @@
import { beforeAll, describe, expect, mock, test } from "bun:test"
import { describe, expect, test } from "bun:test"
import type { AsyncStorage } from "@solid-primitives/storage"
import { createEffect, createRoot } from "solid-js"
import type { Platform } from "@/context/platform"
import { createPromptReady, createPromptSession } from "@/context/prompt-state"
import { ServerScope } from "@/utils/server-scope"
import { createDraftStore } from "@/utils/draft-store"
let Prompt: typeof import("@/context/prompt")
let read: ((value: string | null) => void) | undefined
const storage: AsyncStorage = {
@@ -17,32 +18,25 @@ const storage: AsyncStorage = {
length: Promise.resolve(0),
}
beforeAll(async () => {
mock.module("@solidjs/router", () => ({
useParams: () => ({}),
useSearchParams: () => [{}],
useLocation: () => ({ pathname: "", query: {} }),
useNavigate: () => () => undefined,
}))
mock.module("@opencode-ai/ui/context", () => ({
createSimpleContext: () => ({
use: () => undefined,
provider: () => undefined,
}),
}))
mock.module("@/context/platform", () => ({
usePlatform: () => ({ platform: "desktop", storage: () => storage, draftStore: storage }),
}))
Prompt = await import("@/context/prompt")
})
const platform: Platform = {
platform: "web",
openExternal: () => undefined,
restart: async () => undefined,
notify: async () => undefined,
draftStore: {
...storage,
putBlob: async () => {
throw new Error("putBlob is not used by this test")
},
},
}
describe("prompt persistence", () => {
test("waits for an async draft to hydrate before reporting ready", async () => {
await new Promise<void>((resolve, reject) => {
createRoot((dispose) => {
const session = Prompt.createPromptSession(ServerScope.local, { draftID: "draft-async" })
const ready = Prompt.createPromptReady(() => session)
const session = createPromptSession(ServerScope.local, { draftID: "draft-async" }, undefined, platform)
const ready = createPromptReady(() => session)
expect(ready()).toBe(false)
expect(session.current()[0]).toMatchObject({ type: "text", content: "" })
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/cli",
"version": "1.18.12",
"version": "1.18.13",
"type": "module",
"license": "MIT",
"bin": {
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/codemode",
"version": "1.18.12",
"version": "1.18.13",
"description": "Effect-native confined code execution over schema-described tools",
"private": true,
"type": "module",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/console-app",
"version": "1.18.12",
"version": "1.18.13",
"type": "module",
"license": "MIT",
"scripts": {
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/console-core",
"version": "1.18.12",
"version": "1.18.13",
"private": true,
"type": "module",
"license": "MIT",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/console-function",
"version": "1.18.12",
"version": "1.18.13",
"$schema": "https://json.schemastore.org/package.json",
"private": true,
"type": "module",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/console-mail",
"version": "1.18.12",
"version": "1.18.13",
"dependencies": {
"@jsx-email/all": "2.2.3",
"@jsx-email/cli": "1.4.3",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/console-support",
"version": "1.18.12",
"version": "1.18.13",
"type": "module",
"license": "MIT",
"scripts": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package.json",
"version": "1.18.12",
"version": "1.18.13",
"name": "@opencode-ai/core",
"type": "module",
"license": "MIT",
+5
View File
@@ -2,3 +2,8 @@
- Renderer process should only call `window.api` from `src/preload`.
- Main process should register IPC handlers in `src/main/ipc.ts`.
- NEVER hardcode user-visible English strings in production code. ALWAYS use an i18n key for native menus, picker titles, dialogs, buttons, accessible labels, and displayed errors.
- When migrating existing copy to i18n, preserve the English text byte-for-byte unless the task explicitly requests a copy change.
- NEVER change existing English text or English keys to facilitate translation. English is intentional, designer-written source copy; adapt locale-specific translations and i18n mechanics around it.
- Do not translate from model knowledge alone. Verify terminology and grammar with Unicode CLDR locale/plural data, Microsoft Localization Style Guides and terminology, Apple localization/style guidance and localized platform UI, Mozilla localization style guides, Mozilla Pontoon, and the Firefox localization corpus at `github.com/mozilla-l10n/firefox-l10n`.
- Also use the relevant language authority or official dictionary for the locale (for example RAE/Fundéu, FranceTerme, Duden, TDK, Kotus/Kielitoimiston sanakirja, Språkrådet/Bokmålsordboka, Rada Języka Polskiego/PWN, the Russian and Arabic language academies, the Ukrainian Orthography, Taiwan MOE dictionaries, or the Royal Society of Thailand). Treat the English dictionary as the semantic source of truth and preserve placeholders, code identifiers, product names, and keyboard labels.
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@opencode-ai/desktop",
"private": true,
"version": "1.18.12",
"version": "1.18.13",
"type": "module",
"license": "MIT",
"homepage": "https://opencode.ai",
@@ -1,5 +1,6 @@
import { randomUUID } from "node:crypto"
import { open } from "node:fs/promises"
import { nativeT } from "./native-translations"
export const MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024
@@ -18,7 +19,7 @@ export function createPickedFileAuthorizations(
async read(sender: number, token: string, path: string) {
const selection = selections.get(token)
if (selection?.sender !== sender || !selection.paths.delete(path))
throw new Error("File was not selected by the picker")
throw new Error(nativeT("desktop.picker.error.notSelected"))
const bytes = await read(path, selection.remaining)
selection.remaining -= bytes.byteLength
if (selection.paths.size === 0) selections.delete(token)
@@ -33,7 +34,7 @@ export function createPickedFileAuthorizations(
export function assertAttachmentBudget(files: { size: number }[]) {
const total = files.reduce((sum, file) => sum + file.size, 0)
if (total <= MAX_ATTACHMENT_BYTES) return
throw new Error(`Selected attachments exceed the ${MAX_ATTACHMENT_BYTES / 1024 / 1024} MB limit`)
throw new Error(nativeT("desktop.picker.error.sizeLimit", { limit: MAX_ATTACHMENT_BYTES / 1024 / 1024 }))
}
export async function readAttachment(filePath: string, maxBytes = MAX_ATTACHMENT_BYTES) {
@@ -41,7 +42,7 @@ export async function readAttachment(filePath: string, maxBytes = MAX_ATTACHMENT
try {
const info = await file.stat()
if (info.size > maxBytes)
throw new Error(`Selected attachments exceed the ${MAX_ATTACHMENT_BYTES / 1024 / 1024} MB limit`)
throw new Error(nativeT("desktop.picker.error.sizeLimit", { limit: MAX_ATTACHMENT_BYTES / 1024 / 1024 }))
const bytes = Buffer.allocUnsafe(info.size)
let offset = 0
while (offset < info.size) {
+13 -14
View File
@@ -48,6 +48,7 @@ import { spawnWslSidecar } from "./wsl/sidecar"
import { migrate } from "./migrate"
import { cleanupStoreFiles } from "./store-cleanup"
import { startBackgroundCli } from "./background-cli"
import { setNativeTranslations } from "./native-translations"
const APP_NAMES: Record<string, string> = {
dev: "OpenCode Dev",
@@ -271,6 +272,14 @@ const main = Effect.gen(function* () {
registerRendererProtocol()
setDockIcon()
const updater = setupAutoUpdater(stopSidecars)
const menuDeps = {
trigger: (id: string) => {
const win = getLastFocusedWindow()
if (win) sendMenuCommand(win, id)
},
checkForUpdates: () => void showUpdaterDialog(updater, true),
relaunch,
}
registerIpcHandlers({
killSidecar: () => killSidecar(),
relaunch,
@@ -298,6 +307,9 @@ const main = Effect.gen(function* () {
setBackgroundColor: (color) => setBackgroundColor(color),
exportDebugLogs: () => exportDebugLogs(),
recordFatalRendererError: (error) => writeLog("renderer", "fatal renderer error", { ...error }, "error"),
setNativeTranslations: (bundle) => {
if (setNativeTranslations(bundle)) createMenu(menuDeps)
},
})
registerWslIpcHandlers(wslServers)
void updater.start()
@@ -397,20 +409,7 @@ const main = Effect.gen(function* () {
yield* Fiber.await(loadingTask)
const windows = restoreMainWindows()
if (windows.length) {
createMenu({
trigger: (id) => {
const win = getLastFocusedWindow()
if (win) sendMenuCommand(win, id)
},
checkForUpdates: () => {
void showUpdaterDialog(updater, true)
},
relaunch: () => {
relaunch()
},
})
}
if (windows.length) createMenu(menuDeps)
})
Effect.runFork(main)
+16 -4
View File
@@ -4,6 +4,7 @@ import { basename, join } from "node:path"
import { app, BrowserWindow, clipboard, dialog, ipcMain, shell } from "electron"
import type { IpcMainEvent, IpcMainInvokeEvent } from "electron"
import type { DesktopMenuAction } from "@opencode-ai/app/desktop-menu"
import { parseDesktopNativeBundle, type DesktopNativeBundle } from "@opencode-ai/app/i18n/desktop-native"
import type { FatalRendererError, ServerReadyData, TitlebarTheme } from "../preload/types"
import { runDesktopMenuAction } from "./desktop-menu-actions"
@@ -22,10 +23,11 @@ import {
import type { UpdaterController } from "./updater-controller"
import { createUpdaterSubscriptions } from "./updater-subscriptions"
import { createDesktopDraftStore } from "./draft-store"
import { nativeT } from "./native-translations"
const pickerFilters = (ext?: string[]) => {
if (!ext || ext.length === 0) return undefined
return [{ name: "Files", extensions: ext }]
return [{ name: nativeT("desktop.dialog.files"), extensions: ext }]
}
const pickedFiles = createPickedFileAuthorizations()
@@ -49,6 +51,7 @@ type Deps = {
setBackgroundColor: (color: string) => void
exportDebugLogs: () => Promise<string>
recordFatalRendererError: (error: FatalRendererError) => Promise<void> | void
setNativeTranslations: (bundle: DesktopNativeBundle) => void
}
export function registerIpcHandlers(deps: Deps) {
@@ -99,6 +102,15 @@ export function registerIpcHandlers(deps: Deps) {
ipcMain.handle("record-fatal-renderer-error", (_event: IpcMainInvokeEvent, error: FatalRendererError) =>
deps.recordFatalRendererError(error),
)
ipcMain.handle("set-native-translations", (event: IpcMainInvokeEvent, value: unknown) => {
const win = BrowserWindow.fromWebContents(event.sender)
if (!win || win.isDestroyed() || win.webContents !== event.sender || event.senderFrame !== event.sender.mainFrame) {
throw new Error("Invalid native translation sender")
}
const bundle = parseDesktopNativeBundle(value)
if (!bundle) throw new Error("Invalid native translation bundle")
deps.setNativeTranslations(bundle)
})
ipcMain.handle("store-get", (_event: IpcMainInvokeEvent, name: string, key: string) => {
try {
const store = getStore(name)
@@ -142,7 +154,7 @@ export function registerIpcHandlers(deps: Deps) {
async (_event: IpcMainInvokeEvent, opts?: { multiple?: boolean; title?: string; defaultPath?: string }) => {
const result = await dialog.showOpenDialog({
properties: ["openDirectory", ...(opts?.multiple ? ["multiSelections" as const] : []), "createDirectory"],
title: opts?.title ?? "Choose a folder",
title: opts?.title ?? nativeT("desktop.dialog.chooseFolder"),
defaultPath: opts?.defaultPath,
})
if (result.canceled) return null
@@ -158,7 +170,7 @@ export function registerIpcHandlers(deps: Deps) {
) => {
const result = await dialog.showOpenDialog({
properties: ["openFile", ...(opts?.multiple ? ["multiSelections" as const] : [])],
title: opts?.title ?? "Choose a file",
title: opts?.title ?? nativeT("desktop.dialog.chooseFile"),
defaultPath: opts?.defaultPath,
filters: pickerFilters(opts?.extensions),
})
@@ -188,7 +200,7 @@ export function registerIpcHandlers(deps: Deps) {
"save-file-picker",
async (_event: IpcMainInvokeEvent, opts?: { title?: string; defaultPath?: string }) => {
const result = await dialog.showSaveDialog({
title: opts?.title ?? "Save file",
title: opts?.title ?? nativeT("desktop.dialog.saveFile"),
defaultPath: opts?.defaultPath,
})
if (result.canceled) return null
+5 -4
View File
@@ -10,6 +10,7 @@ import {
import { UPDATER_ENABLED } from "./constants"
import { runDesktopMenuAction } from "./desktop-menu-actions"
import { openExternalURL } from "./windows"
import { nativeT } from "./native-translations"
type Deps = {
trigger: (id: string) => void
@@ -21,9 +22,9 @@ export function createMenu(deps: Deps) {
if (process.platform !== "darwin") return
const template = DESKTOP_MENU.filter((menu) => desktopMenuVisible(menu, "macos")).map((menu) => {
if (menu.role) return { role: nativeRole(menu.role) }
if (menu.role) return { role: nativeRole(menu.role), label: nativeT(menu.labelKey) }
return {
label: menu.label,
label: nativeT(menu.labelKey),
submenu: menu.items
?.filter((entry) => desktopMenuVisible(entry, "macos"))
.map((entry) => nativeItem(entry, deps)),
@@ -35,10 +36,10 @@ export function createMenu(deps: Deps) {
function nativeItem(entry: DesktopMenuEntry, deps: Deps): MenuItemConstructorOptions {
if (entry.type === "separator") return { type: "separator" }
if (entry.role) return { role: nativeRole(entry.role) }
if (entry.role) return { role: nativeRole(entry.role), label: entry.labelKey ? nativeT(entry.labelKey) : undefined }
const item: MenuItemConstructorOptions = {
label: entry.label,
label: entry.labelKey ? nativeT(entry.labelKey) : undefined,
accelerator: entry.accelerator?.macos,
enabled: entry.enabled === "updater" ? UPDATER_ENABLED : undefined,
}
@@ -0,0 +1,24 @@
import {
DESKTOP_NATIVE_ENGLISH,
DESKTOP_NATIVE_KEYS,
formatDesktopNativeMessage,
type DesktopNativeBundle,
type DesktopNativeKey,
} from "@opencode-ai/app/i18n/desktop-native"
let bundle: DesktopNativeBundle = { locale: "en", messages: { ...DESKTOP_NATIVE_ENGLISH } }
export function setNativeTranslations(next: DesktopNativeBundle) {
if (
next.locale === bundle.locale &&
DESKTOP_NATIVE_KEYS.every((key) => next.messages[key] === bundle.messages[key])
) {
return false
}
bundle = next
return true
}
export function nativeT(key: DesktopNativeKey, params?: Record<string, string | number>) {
return formatDesktopNativeMessage(bundle.messages[key], params)
}
+14 -5
View File
@@ -5,6 +5,7 @@ import { createUpdaterController, type UpdaterReadyRecord } from "./updater-cont
import { getLogger } from "./logging"
import { getStore } from "./store"
import { setAppQuitting } from "./windows"
import { nativeT } from "./native-translations"
const { autoUpdater } = pkg
const key = "ready"
@@ -63,21 +64,29 @@ export async function showUpdaterDialog(controller: ReturnType<typeof setupAutoU
const state = await controller.check()
if (state.status === "error") {
if (!alertOnFail) return
await dialog.showMessageBox({ type: "error", message: "Update check failed.", title: "Update Error" })
await dialog.showMessageBox({
type: "error",
message: nativeT("desktop.updater.dialog.checkFailed.message"),
title: nativeT("desktop.updater.dialog.checkFailed.title"),
})
return
}
if (state.status === "up-to-date") {
if (!alertOnFail) return
await dialog.showMessageBox({ type: "info", message: "You're up to date.", title: "No Updates" })
await dialog.showMessageBox({
type: "info",
message: nativeT("desktop.updater.dialog.upToDate.message"),
title: nativeT("desktop.updater.dialog.upToDate.title"),
})
return
}
if (state.status !== "ready") return
const response = await dialog.showMessageBox({
type: "info",
message: `Update ${state.version} downloaded. Restart now?`,
title: "Update Ready",
buttons: ["Restart", "Later"],
message: nativeT("desktop.updater.dialog.ready.message", { version: state.version }),
title: nativeT("desktop.updater.dialog.ready.title"),
buttons: [nativeT("desktop.updater.dialog.restart"), nativeT("desktop.updater.dialog.later")],
defaultId: 0,
cancelId: 1,
})
+33 -12
View File
@@ -12,6 +12,7 @@ import { exportDebugLogs, write as writeLog } from "./logging"
import { getStore, removeStoreFile } from "./store"
import { PINCH_ZOOM_ENABLED_KEY, WINDOW_IDS_KEY } from "./store-keys"
import { createUnresponsiveSampler } from "./unresponsive"
import { nativeT } from "./native-translations"
import { createWindowRegistry } from "./window-registry"
import { safeWindowURL } from "./window-state"
import { resolveExternalURL, resolveLocalFilePath } from "./external-url"
@@ -345,19 +346,20 @@ function wireWindowRecovery(win: BrowserWindow, name: string) {
let showing = false
const sampler = createUnresponsiveSampler(win, name)
const handle = async (button: string | undefined, wait: boolean) => {
if (button === "Export Logs") {
type RecoveryAction = "relaunch" | "export-logs" | "keep-waiting" | "quit"
const handle = async (action: RecoveryAction | undefined, wait: boolean) => {
if (action === "export-logs") {
const sampling = sampler.stopAndFlush()
await exportDebugLogs().catch((error) => writeLog("main", "failed to export debug logs", { error }, "error"))
if (wait && sampling) sampler.start()
return true
}
if (button === "Relaunch") {
if (action === "relaunch") {
sampler.stopAndFlush()
relaunchHandler()
return false
}
if (button === "Quit") {
if (action === "quit") {
sampler.stopAndFlush()
app.quit()
}
@@ -369,16 +371,26 @@ function wireWindowRecovery(win: BrowserWindow, name: string) {
showing = true
try {
while (!win.isDestroyed()) {
const buttons = wait ? ["Relaunch", "Export Logs", "Keep Waiting"] : ["Relaunch", "Export Logs", "Quit"]
const actions: { id: RecoveryAction; label: string }[] = wait
? [
{ id: "relaunch", label: nativeT("desktop.recovery.action.relaunch") },
{ id: "export-logs", label: nativeT("desktop.recovery.action.exportLogs") },
{ id: "keep-waiting", label: nativeT("desktop.recovery.action.keepWaiting") },
]
: [
{ id: "relaunch", label: nativeT("desktop.recovery.action.relaunch") },
{ id: "export-logs", label: nativeT("desktop.recovery.action.exportLogs") },
{ id: "quit", label: nativeT("desktop.recovery.action.quit") },
]
const result = await dialog.showMessageBox(win, {
type: "warning",
buttons,
buttons: actions.map((action) => action.label),
defaultId: 0,
cancelId: 2,
message,
detail,
})
if (await handle(buttons[result.response], wait)) continue
if (await handle(actions[result.response]?.id, wait)) continue
return
}
} finally {
@@ -410,8 +422,13 @@ function wireWindowRecovery(win: BrowserWindow, name: string) {
if (!isMainFrame || errorCode === -3) return
void show(
"OpenCode failed to load",
[`Window: ${name}`, `URL: ${validatedURL}`, `Error: ${errorCode} ${errorDescription}`].join("\n"),
nativeT("desktop.recovery.loadFailed"),
nativeT("desktop.recovery.loadFailed.detail", {
window: name,
url: validatedURL,
code: errorCode,
description: errorDescription,
}),
false,
)
}
@@ -426,15 +443,19 @@ function wireWindowRecovery(win: BrowserWindow, name: string) {
sampler.stopAndFlush()
writeLog("window", "renderer process gone", { window: name, currentURL: safeWindowURL(win), details }, "error")
void show(
"OpenCode window terminated unexpectedly",
[`Window: ${name}`, `Reason: ${details.reason}`, `Code: ${details.exitCode ?? "<unknown>"}`].join("\n"),
nativeT("desktop.recovery.terminated"),
nativeT("desktop.recovery.terminated.detail", {
window: name,
reason: details.reason,
code: details.exitCode ?? nativeT("desktop.recovery.unknown"),
}),
false,
)
})
win.on("unresponsive", () => {
writeLog("window", "renderer unresponsive", { window: name, currentURL: safeWindowURL(win) }, "error")
sampler.start()
void show("OpenCode is not responding", "You can relaunch the app, open the logs, or keep waiting.", true)
void show(nativeT("desktop.recovery.unresponsive"), nativeT("desktop.recovery.unresponsive.detail"), true)
})
win.on("responsive", () => {
writeLog("window", "renderer responsive", { window: name, currentURL: safeWindowURL(win) }, "error")
+3 -2
View File
@@ -3,6 +3,7 @@ import type { IpcMainInvokeEvent } from "electron"
import type { WslServersController } from "./servers"
import { requireWslIpcString, requireWslIpcStrings } from "./policy"
import type { WslServersState } from "../../preload/types"
import { nativeT } from "../native-translations"
export function registerWslIpcHandlers(controller: WslServersController) {
if (process.platform !== "win32") {
@@ -68,13 +69,13 @@ export function registerWslIpcHandlers(controller: WslServersController) {
function registerUnavailableWslIpcHandlers() {
const unavailable = () => {
throw new Error("WSL is only available on Windows")
throw new Error(nativeT("desktop.wsl.error.windowsOnly"))
}
const state = (): WslServersState => ({
runtime: {
available: false,
version: null,
error: "WSL is only available on Windows",
error: nativeT("desktop.wsl.error.windowsOnly"),
},
installed: [],
online: [],
+11 -6
View File
@@ -4,6 +4,7 @@ import { join } from "node:path"
import * as pty from "@lydell/node-pty"
import type { WslDistroProbe, WslInstalledDistro, WslOnlineDistro, WslRuntimeCheck } from "../../preload/types"
import { wslTerminalArgs } from "./policy"
import { nativeT } from "../native-translations"
export type WslCommandLine = {
stream: "stdout" | "stderr"
@@ -68,7 +69,9 @@ function runCommand(command: string, args: string[], opts: RunWslOptions = {}) {
} catch {
/* ignore */
}
reject(new Error(`${command} ${args.join(" ")} timed out after ${timeoutMs}ms`))
reject(
new Error(nativeT("desktop.wsl.error.commandTimeout", { command, args: args.join(" "), timeout: timeoutMs })),
)
}, timeoutMs)
let stdout = ""
@@ -139,7 +142,9 @@ function runInteractiveCommand(command: string, args: string[], opts: RunWslOpti
if (settled) return
settled = true
cleanup()
reject(new Error(`${command} ${args.join(" ")} timed out after ${timeoutMs}ms`))
reject(
new Error(nativeT("desktop.wsl.error.commandTimeout", { command, args: args.join(" "), timeout: timeoutMs })),
)
}, timeoutMs)
const abortHandler = () => {
@@ -214,7 +219,7 @@ export async function probeWslRuntime(opts?: RunWslOptions): Promise<WslRuntimeC
return {
available: false,
version: null,
error: summarize(version.stderr || version.stdout) || "WSL is unavailable",
error: summarize(version.stderr || version.stdout) || nativeT("desktop.wsl.error.unavailable"),
}
}
@@ -228,7 +233,7 @@ export async function probeWslRuntime(opts?: RunWslOptions): Promise<WslRuntimeC
export async function listInstalledWslDistros(opts?: RunWslOptions) {
const result = await runWsl(["--list", "--verbose"], opts)
if (result.code !== 0) {
throw new Error(summarize(result.stderr || result.stdout) || "Failed to list installed WSL distros")
throw new Error(summarize(result.stderr || result.stdout) || nativeT("desktop.wsl.error.listInstalled"))
}
return parseInstalledDistros(result.stdout)
}
@@ -236,7 +241,7 @@ export async function listInstalledWslDistros(opts?: RunWslOptions) {
export async function listOnlineWslDistros(opts?: RunWslOptions) {
const result = await runWsl(["--list", "--online"], opts)
if (result.code !== 0) {
throw new Error(summarize(result.stderr || result.stdout) || "Failed to list online WSL distros")
throw new Error(summarize(result.stderr || result.stdout) || nativeT("desktop.wsl.error.listOnline"))
}
return parseOnlineDistros(result.stdout)
}
@@ -284,7 +289,7 @@ export async function probeWslDistro(name: string, opts?: RunWslOptions): Promis
canExecute: false,
hasBash: false,
hasCurl: false,
error: summarize(executable.stderr || executable.stdout) || "Cannot execute commands in distro",
error: summarize(executable.stderr || executable.stdout) || nativeT("desktop.wsl.error.executeDistro"),
}
}
+9 -7
View File
@@ -15,6 +15,7 @@ import { WSL_SERVERS_KEY } from "../store-keys"
import { getStore } from "../store"
import { expectOpencodeVersion, pendingRestartAfterWslInstall, wslServerIdsToStartOnInitialize } from "./startup"
import { clearWslDistroState, wslServerIdToRestart } from "./policy"
import { nativeT } from "../native-translations"
import {
installWslDistro,
installWslOpencode,
@@ -327,7 +328,7 @@ export function createWslServersController(
await runJob({ kind: "install-wsl", startedAt: Date.now() }, async (abort) => {
const result = await installWslRuntimeElevated({ signal: abort.signal })
if (result.code !== 0) {
const message = summarize(result.stderr || result.stdout) || "WSL installation failed"
const message = summarize(result.stderr || result.stdout) || nativeT("desktop.wsl.error.installWsl")
throw new Error(message)
}
const runtime = await probeWslRuntime({ signal: abort.signal })
@@ -339,7 +340,8 @@ export function createWslServersController(
await runJob({ kind: "install-distro", distro: name, startedAt: Date.now() }, async (abort) => {
const result = await installWslDistro(name, { signal: abort.signal })
if (result.code !== 0) {
const message = summarize(result.stderr || result.stdout) || `Failed to install distro: ${name}`
const message =
summarize(result.stderr || result.stdout) || nativeT("desktop.wsl.error.installDistro", { distro: name })
throw new Error(message)
}
const distros = await refreshDistroLists({ signal: abort.signal })
@@ -362,7 +364,7 @@ export function createWslServersController(
await runJob({ kind: "install-opencode", distro: name, startedAt: Date.now() }, async (abort) => {
const result = await installWslOpencode(appVersion, name, { signal: abort.signal })
if (result.code !== 0) {
throw new Error(summarize(result.stderr || result.stdout) || "OpenCode installation failed")
throw new Error(summarize(result.stderr || result.stdout) || nativeT("desktop.wsl.error.installOpencode"))
}
await refreshOpencodeCheck(name, { signal: abort.signal })
expectOpencodeVersion(state.opencodeChecks[name]?.version ?? null, appVersion, name)
@@ -378,7 +380,7 @@ export function createWslServersController(
async addServer(distro: string): Promise<WslServerConfig> {
const id = wslServerIdForDistro(distro)
if (state.servers.some((item) => item.config.id === id)) {
throw new Error(`${distro} is already added`)
throw new Error(nativeT("desktop.wsl.error.alreadyAdded", { distro }))
}
const config: WslServerConfig = {
id,
@@ -475,7 +477,7 @@ function opencodeCheck(
version: null,
expectedVersion,
matchesDesktop: null,
error: "opencode is not installed in this distro",
error: nativeT("desktop.wsl.error.opencodeMissing"),
}
}
if (!version) {
@@ -485,7 +487,7 @@ function opencodeCheck(
version: null,
expectedVersion,
matchesDesktop: null,
error: "opencode is installed but could not run",
error: nativeT("desktop.wsl.error.opencodeCannotRun"),
}
}
return {
@@ -503,7 +505,7 @@ function distroProbeReady(probe: WslDistroProbe | undefined) {
}
function startupFailure(code: number | null, signal: NodeJS.Signals | null) {
return `WSL server exited after startup (code=${code ?? "null"} signal=${signal ?? "null"})`
return nativeT("desktop.wsl.error.serverExited", { code: code ?? "null", signal: signal ?? "null" })
}
// Re-export types used by callers
+9 -4
View File
@@ -5,6 +5,7 @@ import { app } from "electron"
import { checkHealth } from "../server"
import { type WslCommandLine, resolveWslOpencode, shellEscape, wslArgs } from "./runtime"
import { pollWslHealth } from "./startup"
import { nativeT } from "../native-translations"
export type WslSidecar = {
listener: { stop: () => void; onExit: (cb: (code: number | null, signal: NodeJS.Signals | null) => void) => void }
@@ -18,7 +19,7 @@ export async function spawnWslSidecar(
opts: { onLine?: (line: WslCommandLine) => void; healthTimeoutMs?: number } = {},
): Promise<WslSidecar> {
const opencode = await resolveWslOpencode(distro)
if (!opencode) throw new Error(`OpenCode is not installed in ${distro}`)
if (!opencode) throw new Error(nativeT("desktop.wsl.error.opencodeNotInstalled", { distro }))
const port = await allocatePort()
const password = randomUUID()
@@ -64,7 +65,7 @@ export async function spawnWslSidecar(
const timedOut = new Promise<never>(
(_, reject) =>
(timeout = setTimeout(
() => reject(new Error(`Sidecar for ${distro} health check timed out after ${timeoutMs}ms`)),
() => reject(new Error(nativeT("desktop.wsl.error.healthTimeout", { distro, timeout: timeoutMs }))),
timeoutMs,
)),
)
@@ -97,7 +98,7 @@ function allocatePort() {
const address = server.address()
if (typeof address !== "object" || !address) {
server.close()
reject(new Error("Failed to get port"))
reject(new Error(nativeT("desktop.wsl.error.failedPort")))
return
}
server.close(() => resolve(address.port))
@@ -125,5 +126,9 @@ function forwardLines(
function startupFailure(code: number | null, signal: NodeJS.Signals | null, recentOutput: string[]) {
const suffix = recentOutput.length ? `\n${recentOutput.join("\n")}` : ""
return `WSL server exited before becoming healthy (code=${code ?? "null"} signal=${signal ?? "null"})${suffix}`
return nativeT("desktop.wsl.error.serverExitedBeforeHealthy", {
code: code ?? "null",
signal: signal ?? "null",
output: suffix,
})
}
+7 -1
View File
@@ -1,3 +1,5 @@
import { nativeT } from "../native-translations"
export function wslServerIdsToStartOnInitialize(servers: { id: string }[]) {
return servers.map((server) => server.id)
}
@@ -5,7 +7,11 @@ export function wslServerIdsToStartOnInitialize(servers: { id: string }[]) {
export function expectOpencodeVersion(installed: string | null, expected: string, distro = "Debian") {
if (installed === expected) return
throw new Error(
`OpenCode update finished but ${distro} still reports ${installed ?? "no version"}; expected ${expected}`,
nativeT("desktop.wsl.error.updateVersion", {
distro,
installed: installed ?? nativeT("desktop.wsl.error.noVersion"),
expected,
}),
)
}
+1
View File
@@ -132,6 +132,7 @@ const api: ElectronAPI = {
exportDebugLogs: () => ipcRenderer.invoke("export-debug-logs"),
setForceFocus: (enabled) => ipcRenderer.invoke("set-force-focus", enabled),
recordFatalRendererError: (error) => ipcRenderer.invoke("record-fatal-renderer-error", error),
setNativeTranslations: (bundle) => ipcRenderer.invoke("set-native-translations", bundle),
}
contextBridge.exposeInMainWorld("api", api)

Some files were not shown because too many files have changed in this diff Show More