diff --git a/bun.lock b/bun.lock index 907c04c31d2..6af38c1f784 100644 --- a/bun.lock +++ b/bun.lock @@ -29,7 +29,7 @@ }, "packages/app": { "name": "@opencode-ai/app", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@dnd-kit/abstract": "0.5.0", "@dnd-kit/dom": "0.5.0", @@ -93,7 +93,7 @@ }, "packages/cli": { "name": "@opencode-ai/cli", - "version": "1.17.14", + "version": "1.17.15", "bin": { "lildax": "./bin/lildax.cjs", }, @@ -141,7 +141,7 @@ }, "packages/codemode": { "name": "@opencode-ai/codemode", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "acorn": "8.15.0", "effect": "catalog:", @@ -155,7 +155,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -191,7 +191,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -218,7 +218,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@ai-sdk/anthropic": "3.0.82", "@ai-sdk/openai": "3.0.48", @@ -240,7 +240,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -264,7 +264,7 @@ }, "packages/console/support": { "name": "@opencode-ai/console-support", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@opencode-ai/console-core": "workspace:*", @@ -284,7 +284,7 @@ }, "packages/core": { "name": "@opencode-ai/core", - "version": "1.17.14", + "version": "1.17.15", "bin": { "opencode": "./bin/opencode", }, @@ -378,7 +378,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@zip.js/zip.js": "2.7.62", "effect": "catalog:", @@ -432,7 +432,7 @@ }, "packages/effect-drizzle-sqlite": { "name": "@opencode-ai/effect-drizzle-sqlite", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "drizzle-orm": "catalog:", "effect": "catalog:", @@ -446,7 +446,7 @@ }, "packages/effect-sqlite-node": { "name": "@opencode-ai/effect-sqlite-node", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "effect": "catalog:", }, @@ -458,7 +458,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@hono/standard-validator": "catalog:", "@opencode-ai/core": "workspace:*", @@ -490,7 +490,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -506,7 +506,7 @@ }, "packages/http-recorder": { "name": "@opencode-ai/http-recorder", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@effect/platform-node": "4.0.0-beta.83", "@effect/platform-node-shared": "4.0.0-beta.83", @@ -537,7 +537,7 @@ }, "packages/llm": { "name": "@opencode-ai/llm", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@opencode-ai/schema": "workspace:*", "@smithy/eventstream-codec": "4.2.14", @@ -556,7 +556,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.17.14", + "version": "1.17.15", "bin": { "opencode": "./bin/opencode", }, @@ -687,7 +687,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@ai-sdk/provider": "3.0.8", "@opencode-ai/sdk": "workspace:*", @@ -763,7 +763,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "cross-spawn": "catalog:", }, @@ -778,7 +778,7 @@ }, "packages/server": { "name": "@opencode-ai/server", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@opencode-ai/core": "workspace:*", "@opencode-ai/protocol": "workspace:*", @@ -793,7 +793,7 @@ }, "packages/session-ui": { "name": "@opencode-ai/session-ui", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/core": "workspace:*", @@ -837,7 +837,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -850,7 +850,7 @@ }, "packages/stats/app": { "name": "@opencode-ai/stats-app", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@ibm/plex": "6.4.1", "@opencode-ai/stats-core": "workspace:*", @@ -883,7 +883,7 @@ }, "packages/stats/core": { "name": "@opencode-ai/stats-core", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@aws-sdk/client-athena": "3.933.0", "@planetscale/database": "1.19.0", @@ -902,7 +902,7 @@ }, "packages/stats/server": { "name": "@opencode-ai/stats-server", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@aws-sdk/client-firehose": "3.933.0", "@effect/platform-node": "catalog:", @@ -943,7 +943,7 @@ }, "packages/tui": { "name": "@opencode-ai/tui", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@opencode-ai/core": "workspace:*", "@opencode-ai/plugin": "workspace:*", @@ -970,7 +970,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@kobalte/core": "catalog:", "@pierre/diffs": "catalog:", @@ -1021,7 +1021,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.17.14", + "version": "1.17.15", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", diff --git a/package.json b/package.json index e5526b22ffb..e65499f878c 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "prepare": "husky", "random": "echo 'Random script'", "sso": "aws sso login --sso-session=opencode --no-browser", + "translate:app": "bun run script/translate-app.ts", "test": "echo 'do not run tests from root' && exit 1" }, "workspaces": { diff --git a/packages/app/package.json b/packages/app/package.json index 739dfc5ba0e..7430a614bfa 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "1.17.14", + "version": "1.17.15", "description": "", "type": "module", "exports": { diff --git a/packages/app/src/app.tsx b/packages/app/src/app.tsx index 9c2e7d6a1f0..b7f87a09cd2 100644 --- a/packages/app/src/app.tsx +++ b/packages/app/src/app.tsx @@ -9,7 +9,7 @@ import { Font } from "@opencode-ai/ui/font" import { Splash } from "@opencode-ai/ui/logo" import { ThemeProvider } from "@opencode-ai/ui/theme/context" import { MetaProvider } from "@solidjs/meta" -import { type BaseRouterProps, Navigate, Route, Router, useParams, useSearchParams } from "@solidjs/router" +import { type BaseRouterProps, Navigate, Route, Router, useNavigate, useParams, useSearchParams } from "@solidjs/router" import { QueryClient, QueryClientProvider } from "@tanstack/solid-query" import { Effect } from "effect" import { @@ -32,7 +32,7 @@ import { CommandProvider, useCommand, type CommandOption } from "@/context/comma import { CommentsProvider } from "@/context/comments" import { FileProvider } from "@/context/file" import { ServerSDKProvider } from "@/context/server-sdk" -import { ServerSyncProvider } from "@/context/server-sync" +import { ServerSyncProvider, useServerSync } from "@/context/server-sync" import { GlobalProvider, useGlobal } from "@/context/global" import { HighlightsProvider } from "@/context/highlights" import { LanguageProvider, type Locale, useLanguage } from "@/context/language" @@ -52,9 +52,10 @@ import LegacyLayout from "@/pages/layout" import NewLayout from "@/pages/layout-new" import { ErrorPage } from "./pages/error" import { useCheckServerHealth } from "./utils/server-health" -import { legacySessionServer, requireServerKey, sessionHref } from "./utils/session-route" +import { legacySessionHref, legacySessionServer, requireServerKey, sessionHref } from "./utils/session-route" +import { createSessionLineage } from "@/pages/session/session-lineage" -import { SessionPage, TargetSessionRouteContent } from "@/pages/session" +import { SessionPage, SessionRouteErrorBoundary, TargetSessionRouteContent } from "@/pages/session" import { NewHome, LegacyHome } from "@/pages/home" const NewSession = lazy(() => import("@/pages/new-session")) @@ -88,10 +89,14 @@ const SessionRoute = () => { tabs.newDraft({ server: server.key, directory: sdk().directory }, search.prompt) }) - return + return ( + + + + ) } -const TargetSessionRoute = () => { +function TargetServerRoute(props: ParentProps) { const params = useParams<{ serverKey: string; id: string }>() const global = useGlobal() const conn = createMemo(() => { @@ -105,14 +110,47 @@ const TargetSessionRoute = () => { // re-resolves reactively instead); both rely on this key for server changes. - - - + {props.children} ) } +const TargetSessionRoute = () => ( + + + +) + +function LegacyTargetSessionRoute() { + const params = useParams<{ serverKey: string; id: string }>() + return ( + + + + + + ) +} + +function LegacyTargetSessionRedirect() { + const params = useParams<{ id: string }>() + const navigate = useNavigate() + const sync = useServerSync() + const current = createSessionLineage( + () => params.id, + () => sync().session.lineage, + ) + + createEffect(() => { + const directory = current()?.session.directory + if (!directory) return + navigate(legacySessionHref(directory, params.id), { replace: true }) + }) + + return null +} + // Wraps the non-draft routes. They are gated on (and keyed to) the globally selected // server via ServerKey, then provide the server-scoped shell (Permission/Layout/ // Notification/Models + the visual Layout) for that server. @@ -186,7 +224,7 @@ declare global { deepLinks?: string[] } api?: { - setTitlebar?: (theme: { mode: "light" | "dark" }) => Promise + setTitlebar?: (theme: { mode: "light" | "dark"; scheme?: "system" | "light" | "dark" }) => Promise exportDebugLogs?: () => Promise } } @@ -320,8 +358,8 @@ export function AppBaseProviders(props: ParentProps<{ locale?: Locale }>) { { - void window.api?.setTitlebar?.({ mode }) + onThemeApplied={(_, mode, scheme) => { + void window.api?.setTitlebar?.({ mode, scheme }) }} > @@ -542,7 +580,14 @@ function Routes(props: { serverScoped?: JSX.Element }) { {routeProps.children} )} > - {} + + { + <> + + + + } + } /> @@ -550,15 +595,15 @@ function Routes(props: { serverScoped?: JSX.Element }) { - + + - ) } -function LegacyTargetSessionRoute() { +function NewLayoutLegacySessionRedirect() { const server = useServer() const tabs = useTabs() const params = useParams<{ id: string }>() diff --git a/packages/app/src/components/command-palette.ts b/packages/app/src/components/command-palette.ts new file mode 100644 index 00000000000..b61a61977ee --- /dev/null +++ b/packages/app/src/components/command-palette.ts @@ -0,0 +1,325 @@ +import { base64Encode } from "@opencode-ai/core/util/encode" +import { getFilename } from "@opencode-ai/core/util/path" +import { useDialog } from "@opencode-ai/ui/context/dialog" +import { useNavigate } from "@solidjs/router" +import { createMemo, onCleanup } from "solid-js" +import { useCommand, type CommandOption } from "@/context/command" +import { useFile } from "@/context/file" +import { useLanguage } from "@/context/language" +import { useLayout } from "@/context/layout" +import { useServerSDK, type ServerSDK } from "@/context/server-sdk" +import { useServerSync } from "@/context/server-sync" +import { createSessionTabs } from "@/pages/session/helpers" +import { useSessionLayout } from "@/pages/session/session-layout" +import { decode64 } from "@/utils/base64" + +export type CommandPaletteEntry = { + id: string + type: "command" | "file" | "session" + title: string + description?: string + keybind?: string + category: string + option?: CommandOption + path?: string + directory?: string + sessionID?: string + archived?: number + updated?: number +} + +const ENTRY_LIMIT = 5 +const COMMON_COMMAND_IDS = [ + "session.new", + "workspace.new", + "session.previous", + "session.next", + "terminal.toggle", + "review.toggle", +] as const + +export function uniqueCommandPaletteEntries(items: CommandPaletteEntry[]) { + const seen = new Set() + return items.filter((item) => { + if (seen.has(item.id)) return false + seen.add(item.id) + return true + }) +} + +export function createCommandPaletteFileEntry(path: string, category: string): CommandPaletteEntry { + return { + id: "file:" + path, + type: "file", + title: path, + category, + path, + } +} + +export function createCommandPaletteFileOpener(onOpenFile?: (path: string) => void) { + const file = useFile() + const layout = useLayout() + const { tabs, view } = useSessionLayout() + + return (path: string) => { + const value = file.tab(path) + void tabs().open(value) + void file.load(path) + if (!view().reviewPanel.opened()) view().reviewPanel.open() + layout.fileTree.setTab("all") + onOpenFile?.(path) + tabs().setActive(value) + } +} + +export function createCommandPaletteModel(props: { filesOnly?: () => boolean; onOpenFile?: (path: string) => void }) { + const command = useCommand() + const language = useLanguage() + const layout = useLayout() + const file = useFile() + const dialog = useDialog() + const navigate = useNavigate() + const serverSDK = useServerSDK()() + const serverSync = useServerSync() + const { params, tabs } = useSessionLayout() + const openFile = createCommandPaletteFileOpener(props.onOpenFile) + const state = { cleanup: undefined as (() => void) | void, committed: false } + const filesOnly = () => props.filesOnly?.() ?? false + + const allowedCommands = createMemo(() => { + if (filesOnly()) return [] + return command.options.filter( + (option) => + !option.disabled && !option.hidden && !option.id.startsWith("suggested.") && option.id !== "file.open", + ) + }) + const commandEntries = createMemo(() => { + const category = language.t("palette.group.commands") + return allowedCommands().map((option) => createCommandEntry(option, category)) + }) + const preferredCommandEntries = createMemo(() => { + const all = allowedCommands() + const order = new Map(COMMON_COMMAND_IDS.map((id, index) => [id, index])) + const picked = all.filter((option) => order.has(option.id)) + const base = picked.length ? picked : all.slice(0, ENTRY_LIMIT) + const sorted = picked.length ? [...base].sort((a, b) => (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0)) : base + const category = language.t("palette.group.commands") + return sorted.map((option) => createCommandEntry(option, category)) + }) + + const tabState = createSessionTabs({ + tabs, + pathFromTab: file.pathFromTab, + normalizeTab: (tab) => (tab.startsWith("file://") ? file.tab(tab) : tab), + }) + const recentFileEntries = createMemo(() => { + const all = tabState.openedTabs() + const active = tabState.activeFileTab() + const order = active ? [active, ...all.filter((item) => item !== active)] : all + const seen = new Set() + const category = language.t("palette.group.files") + return order + .map((item) => file.pathFromTab(item)) + .filter((path): path is string => { + if (!path || seen.has(path)) return false + seen.add(path) + return true + }) + .slice(0, ENTRY_LIMIT) + .map((path) => createCommandPaletteFileEntry(path, category)) + }) + const rootFileEntries = createMemo(() => { + const category = language.t("palette.group.files") + return file.tree + .children("") + .filter((node) => node.type === "file") + .map((node) => node.path) + .sort((a, b) => a.localeCompare(b)) + .slice(0, ENTRY_LIMIT) + .map((path) => createCommandPaletteFileEntry(path, category)) + }) + + const projectDirectory = createMemo(() => decode64(params.dir) ?? "") + const project = createMemo(() => { + const directory = projectDirectory() + if (!directory) return undefined + return layout.projects.list().find((item) => item.worktree === directory || item.sandboxes?.includes(directory)) + }) + const workspaces = createMemo(() => { + const directory = projectDirectory() + const current = project() + if (!current) return directory ? [directory] : [] + const dirs = [current.worktree, ...(current.sandboxes ?? [])] + if (directory && !dirs.includes(directory)) return [...dirs, directory] + return dirs + }) + const homedir = createMemo(() => serverSync().data.path.home) + const sessions = createSessionEntries({ + workspaces, + label: (directory) => { + const current = project() + const kind = + current && directory === current.worktree + ? language.t("workspace.type.local") + : language.t("workspace.type.sandbox") + const [store] = serverSync().child(directory, { bootstrap: false }) + const home = homedir() + const path = home ? directory.replace(home, "~") : directory + const name = store.vcs?.branch ?? getFilename(directory) + return `${kind} : ${name || path}` + }, + load: (directory) => serverSDK.client.session.list({ directory, roots: true }), + untitled: () => language.t("command.session.new"), + category: () => language.t("command.category.session"), + }) + + const highlight = (item: CommandPaletteEntry | undefined) => { + state.cleanup?.() + state.cleanup = undefined + if (item?.type !== "command") return + state.cleanup = item.option?.onHighlight?.() + } + + const select = (item: CommandPaletteEntry | undefined) => { + if (!item) return + state.committed = true + state.cleanup = undefined + dialog.close() + if (item.type === "command") { + item.option?.onSelect?.("palette") + return + } + if (item.type === "session") { + if (!item.directory || !item.sessionID) return + navigate(`/${base64Encode(item.directory)}/session/${item.sessionID}`) + return + } + if (!item.path) return + openFile(item.path) + } + + onCleanup(() => { + if (state.committed) return + state.cleanup?.() + }) + + return { + language, + file, + commandEntries, + preferredCommandEntries, + recentFileEntries, + rootFileEntries, + sessions, + highlight, + select, + close: () => dialog.close(), + } +} + +function createCommandEntry(option: CommandOption, category: string): CommandPaletteEntry { + return { + id: "command:" + option.id, + type: "command", + title: option.title, + description: option.description, + keybind: option.keybind, + category, + option, + } +} + +function createSessionEntries(props: { + workspaces: () => string[] + label: (directory: string) => string + load: (directory: string) => ReturnType + untitled: () => string + category: () => string +}) { + const state: { + token: number + inflight: Promise | undefined + cached: CommandPaletteEntry[] | undefined + } = { token: 0, inflight: undefined, cached: undefined } + + return (text: string) => { + if (!text.trim()) { + state.token += 1 + state.inflight = undefined + state.cached = undefined + return [] as CommandPaletteEntry[] + } + if (state.cached) return state.cached + if (state.inflight) return state.inflight + + const current = state.token + const dirs = props.workspaces() + if (dirs.length === 0) return [] as CommandPaletteEntry[] + + state.inflight = Promise.all( + dirs.map((directory) => { + const description = props.label(directory) + return props + .load(directory) + .then((result) => + (result.data ?? []) + .filter((session) => !!session?.id) + .map((session) => ({ + id: session.id, + title: session.title ?? props.untitled(), + description, + directory, + archived: session.time?.archived, + updated: session.time?.updated, + })), + ) + .catch(() => [] as SessionEntryInput[]) + }), + ) + .then((results) => { + if (state.token !== current) return [] as CommandPaletteEntry[] + const seen = new Set() + const next = results + .flat() + .filter((item) => { + const key = `${item.directory}:${item.id}` + if (seen.has(key)) return false + seen.add(key) + return true + }) + .map((item) => createSessionEntry(item, props.category())) + state.cached = next + return next + }) + .catch(() => [] as CommandPaletteEntry[]) + .finally(() => { + state.inflight = undefined + }) + + return state.inflight + } +} + +type SessionEntryInput = { + directory: string + id: string + title: string + description: string + archived?: number + updated?: number +} + +function createSessionEntry(input: SessionEntryInput, category: string): CommandPaletteEntry { + return { + id: `session:${input.directory}:${input.id}`, + type: "session", + title: input.title, + description: input.description, + category, + directory: input.directory, + sessionID: input.id, + archived: input.archived, + updated: input.updated, + } +} diff --git a/packages/app/src/components/dialog-command-palette-v2.css b/packages/app/src/components/dialog-command-palette-v2.css new file mode 100644 index 00000000000..a4019928aa1 --- /dev/null +++ b/packages/app/src/components/dialog-command-palette-v2.css @@ -0,0 +1,220 @@ +.command-palette-v2 { + overflow: hidden; +} + +/* Anchor to the top edge of where a centered 480px-tall dialog would sit, so the + top stays put while the content-driven height grows and shrinks. */ +[data-component="dialog-v2"]:has(.command-palette-v2) { + align-items: flex-start; +} + +[data-component="dialog-v2"]:has(.command-palette-v2) [data-slot="dialog-container"] { + width: min(calc(100vw - 24px), 640px); + height: auto; + min-height: 280px; + max-height: min(calc(100vh - 96px), 480px); + margin-top: max(48px, calc((100vh - 480px) / 2)); + border-radius: 12px; + background: var(--v2-background-bg-base); + box-shadow: var(--v2-elevation-floating); +} + +.command-palette-v2-body { + display: flex; + min-height: 0; + flex: 1; + flex-direction: column; + gap: 0; + padding: 0; +} + +.command-palette-v2-search { + flex-shrink: 0; + padding: 6px; +} + +.command-palette-v2-search [data-component="text-input-v2"] { + width: 100%; + height: 36px; + border-radius: 6px; + outline: 0; + background: color-mix(in srgb, var(--v2-background-bg-layer-02) 60%, transparent); + box-shadow: none; + transition: + background-color 120ms ease-in-out, + box-shadow 120ms ease-in-out; +} + +.command-palette-v2-search [data-component="text-input-v2"]:where(:hover):not([data-disabled], [data-invalid]), +.command-palette-v2-search [data-component="text-input-v2"]:where(:focus-within):not([data-disabled], [data-invalid]) { + background: var(--v2-background-bg-layer-02); + box-shadow: none; +} + +.command-palette-v2-search [data-component="text-input-v2"] [data-slot="text-input-v2-value"] { + border-radius: 6px; + background: transparent; + gap: 8px; +} + +.command-palette-v2-search [data-component="text-input-v2"] [data-slot="text-input-v2-leading-icon"] { + padding-left: 12px; +} + +.command-palette-v2-search [data-component="text-input-v2"] [data-slot="text-input-v2-input"] { + border-radius: 6px; + background: transparent; +} + +.command-palette-v2-scroll { + min-height: 0; + flex: 1; +} + +.command-palette-v2-results { + display: flex; + flex-direction: column; + gap: 16px; + padding: 6px 6px 8px; +} + +.command-palette-v2-group { + display: flex; + flex-direction: column; + gap: 1px; +} + +.command-palette-v2-group-title { + margin: 6px 0; + padding: 0 12px; + color: var(--v2-text-text-muted); + font-size: 13px; + font-weight: 440; + line-height: 16px; + letter-spacing: -0.04px; + user-select: none; +} + +.command-palette-v2-row { + display: flex; + width: 100%; + height: 36px; + flex-shrink: 0; + align-items: center; + justify-content: space-between; + gap: 8px; + padding: 0 12px; + border: 0; + border-radius: 6px; + background: transparent; + color: var(--v2-text-text-base); + text-align: left; + cursor: default; + scroll-margin: 6px 0; +} + +.command-palette-v2-row[data-active] { + background: var(--v2-overlay-simple-overlay-hover); +} + +.command-palette-v2-row:focus-visible { + background: var(--v2-overlay-simple-overlay-hover); + outline: none; +} + +.command-palette-v2-row-main { + display: flex; + min-width: 0; + flex: 1; + align-items: center; + gap: 8px; +} + +.command-palette-v2-row-icon { + flex-shrink: 0; + color: var(--v2-icon-icon-muted); +} + +.command-palette-v2-row-text { + display: flex; + min-width: 0; + align-items: center; + gap: 6px; +} + +.command-palette-v2-title { + min-width: 0; + overflow: hidden; + color: var(--v2-text-text-base); + font-size: 13px; + font-weight: 530; + line-height: 16px; + letter-spacing: -0.04px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.command-palette-v2-description, +.command-palette-v2-meta { + min-width: 0; + overflow: hidden; + color: var(--v2-text-text-muted); + font-size: 13px; + font-weight: 440; + line-height: 16px; + letter-spacing: -0.04px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.command-palette-v2-meta { + flex-shrink: 0; +} + +.command-palette-v2-file-path { + display: flex; + min-width: 0; + align-items: baseline; + font-size: 13px; + line-height: 16px; + letter-spacing: -0.04px; +} + +.command-palette-v2-file-dir { + min-width: 0; + overflow: hidden; + color: var(--v2-text-text-muted); + font-weight: 440; + text-overflow: ellipsis; + white-space: nowrap; +} + +.command-palette-v2-file-name { + flex-shrink: 0; + color: var(--v2-text-text-base); + font-weight: 530; + white-space: nowrap; +} + +.command-palette-v2-state { + display: grid; + min-height: 120px; + place-items: center; + color: var(--v2-text-text-muted); + font-size: 13px; + font-weight: 440; + line-height: 16px; + letter-spacing: -0.04px; +} + +@media (max-width: 640px) { + .command-palette-v2-row-text { + flex-direction: column; + align-items: flex-start; + gap: 1px; + } + + .command-palette-v2-description { + max-width: 100%; + } +} diff --git a/packages/app/src/components/dialog-command-palette-v2.tsx b/packages/app/src/components/dialog-command-palette-v2.tsx new file mode 100644 index 00000000000..b1cafe1e7a4 --- /dev/null +++ b/packages/app/src/components/dialog-command-palette-v2.tsx @@ -0,0 +1,221 @@ +import { getDirectory, getFilename } from "@opencode-ai/core/util/path" +import { FileIcon } from "@opencode-ai/ui/file-icon" +import { ScrollView } from "@opencode-ai/ui/scroll-view" +import { Dialog, DialogBody } from "@opencode-ai/ui/v2/dialog-v2" +import { Icon } from "@opencode-ai/ui/v2/icon" +import { KeybindV2 } from "@opencode-ai/ui/v2/keybind-v2" +import { TextInputV2 } from "@opencode-ai/ui/v2/text-input-v2" +import { createEffect, createMemo, createResource, createSignal, For, Match, Show, Switch } from "solid-js" +import { formatKeybindParts } from "@/context/command" +import { useLanguage } from "@/context/language" +import { getRelativeTime } from "@/utils/time" +import { + createCommandPaletteFileEntry, + createCommandPaletteModel, + uniqueCommandPaletteEntries, + type CommandPaletteEntry, +} from "./command-palette" +import "./dialog-command-palette-v2.css" + +function groups(entries: CommandPaletteEntry[]) { + const map = new Map() + for (const entry of entries) map.set(entry.category, [...(map.get(entry.category) ?? []), entry]) + return Array.from(map.entries()).map(([category, entries]) => ({ category, entries })) +} + +function matchesEntry(entry: CommandPaletteEntry, query: string) { + const value = query.toLowerCase() + return [entry.title, entry.description, entry.category].some((text) => text?.toLowerCase().includes(value)) +} + +export function DialogCommandPaletteV2(props: { onOpenFile?: (path: string) => void }) { + const palette = createCommandPaletteModel(props) + const [query, setQuery] = createSignal("") + const [active, setActive] = createSignal(0) + + const loadItems = async (text: string) => { + const q = text.trim() + if (!q) return [...palette.preferredCommandEntries(), ...palette.recentFileEntries()] + + const [files, nextSessions] = await Promise.all([palette.file.searchFiles(q), Promise.resolve(palette.sessions(q))]) + const category = palette.language.t("palette.group.files") + return [ + ...palette.commandEntries().filter((entry) => matchesEntry(entry, q)), + ...nextSessions.filter((entry) => matchesEntry(entry, q)), + ...files.map((path) => createCommandPaletteFileEntry(path, category)), + ] + } + + const [entries] = createResource(query, loadItems, { initialValue: [] as CommandPaletteEntry[] }) + // Render stale results while a new query loads to avoid flashing "Loading" per keystroke. + const visibleEntries = createMemo(() => uniqueCommandPaletteEntries(entries.latest ?? [])) + const groupedEntries = createMemo(() => groups(visibleEntries())) + const activeEntry = createMemo(() => visibleEntries()[active()]) + + createEffect(() => { + query() + visibleEntries() + setActive(0) + }) + + createEffect(() => { + palette.highlight(activeEntry()) + }) + + let resultsRef: HTMLDivElement | undefined + + const move = (delta: -1 | 1) => { + const count = visibleEntries().length + if (count === 0) return + setActive((index) => (index + delta + count) % count) + requestAnimationFrame(() => { + resultsRef?.querySelector("[data-active]")?.scrollIntoView({ block: "nearest" }) + }) + } + + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === "ArrowDown") { + event.preventDefault() + move(1) + return + } + if (event.key === "ArrowUp") { + event.preventDefault() + move(-1) + return + } + if (event.key === "Enter") { + event.preventDefault() + palette.select(activeEntry()) + return + } + if (event.key === "Escape") { + event.preventDefault() + palette.close() + } + } + + return ( + + + + (resultsRef = el)}> +
+ 0} + fallback={ +
+ {entries.loading ? palette.language.t("common.loading") : palette.language.t("palette.empty")} +
+ } + > + + {(group) => ( +
+ +
{group.category}
+
+ + {(item) => ( + setActive(visibleEntries().findIndex((entry) => entry.id === item.id))} + onSelect={() => palette.select(item)} + /> + )} + +
+ )} +
+
+
+
+
+
+ ) +} + +function PaletteRow(props: { + item: CommandPaletteEntry + active: boolean + language: ReturnType + onActive: () => void + onSelect: () => void +}) { + return ( + + ) +} diff --git a/packages/app/src/components/dialog-select-file.tsx b/packages/app/src/components/dialog-select-file.tsx index 49a0d5961aa..d7c6c2a84f4 100644 --- a/packages/app/src/components/dialog-select-file.tsx +++ b/packages/app/src/components/dialog-select-file.tsx @@ -1,329 +1,84 @@ -import { useDialog } from "@opencode-ai/ui/context/dialog" import { Dialog } from "@opencode-ai/ui/dialog" import { FileIcon } from "@opencode-ai/ui/file-icon" import { Icon } from "@opencode-ai/ui/icon" import { Keybind } from "@opencode-ai/ui/keybind" import { List } from "@opencode-ai/ui/list" -import { base64Encode } from "@opencode-ai/core/util/encode" import { getDirectory, getFilename } from "@opencode-ai/core/util/path" -import { useNavigate } from "@solidjs/router" -import { createMemo, createSignal, lazy, Match, onCleanup, Show, Switch } from "solid-js" -import { formatKeybind, useCommand, type CommandOption } from "@/context/command" -import { useServerSDK, type ServerSDK } from "@/context/server-sdk" -import { useServerSync } from "@/context/server-sync" -import { useLayout } from "@/context/layout" -import { useFile } from "@/context/file" +import { createMemo, createSignal, lazy, Match, Show, Switch } from "solid-js" +import { formatKeybind } from "@/context/command" +import { useServerSDK } from "@/context/server-sdk" import { useLanguage } from "@/context/language" import { usePlatform } from "@/context/platform" import { useSettings } from "@/context/settings" import { useSessionLayout } from "@/pages/session/session-layout" -import { createSessionTabs } from "@/pages/session/helpers" import { decode64 } from "@/utils/base64" import { getRelativeTime } from "@/utils/time" +import { + createCommandPaletteFileEntry, + createCommandPaletteFileOpener, + createCommandPaletteModel, + uniqueCommandPaletteEntries, + type CommandPaletteEntry, +} from "./command-palette" const DialogSelectFileV2 = lazy(() => import("./dialog-select-directory-v2").then((module) => ({ default: module.DialogSelectDirectoryV2 })), ) - -type EntryType = "command" | "file" | "session" - -type Entry = { - id: string - type: EntryType - title: string - description?: string - keybind?: string - category: string - option?: CommandOption - path?: string - directory?: string - sessionID?: string - archived?: number - updated?: number -} +const DialogCommandPaletteV2 = lazy(() => + import("./dialog-command-palette-v2").then((module) => ({ default: module.DialogCommandPaletteV2 })), +) type DialogSelectFileMode = "all" | "files" -const ENTRY_LIMIT = 5 -const COMMON_COMMAND_IDS = [ - "session.new", - "workspace.new", - "session.previous", - "session.next", - "terminal.toggle", - "review.toggle", -] as const - -const uniqueEntries = (items: Entry[]) => { - const seen = new Set() - const out: Entry[] = [] - for (const item of items) { - if (seen.has(item.id)) continue - seen.add(item.id) - out.push(item) - } - return out -} - -const createCommandEntry = (option: CommandOption, category: string): Entry => ({ - id: "command:" + option.id, - type: "command", - title: option.title, - description: option.description, - keybind: option.keybind, - category, - option, -}) - -const createFileEntry = (path: string, category: string): Entry => ({ - id: "file:" + path, - type: "file", - title: path, - category, - path, -}) - -const createSessionEntry = ( - input: { - directory: string - id: string - title: string - description: string - archived?: number - updated?: number - }, - category: string, -): Entry => ({ - id: `session:${input.directory}:${input.id}`, - type: "session", - title: input.title, - description: input.description, - category, - directory: input.directory, - sessionID: input.id, - archived: input.archived, - updated: input.updated, -}) - -function createCommandEntries(props: { - filesOnly: () => boolean - command: ReturnType - language: ReturnType -}) { - const allowed = createMemo(() => { - if (props.filesOnly()) return [] - return props.command.options.filter( - (option) => - !option.disabled && !option.hidden && !option.id.startsWith("suggested.") && option.id !== "file.open", - ) - }) - - const list = createMemo(() => { - const category = props.language.t("palette.group.commands") - return allowed().map((option) => createCommandEntry(option, category)) - }) - - const picks = createMemo(() => { - const all = allowed() - const order = new Map(COMMON_COMMAND_IDS.map((id, index) => [id, index])) - const picked = all.filter((option) => order.has(option.id)) - const base = picked.length ? picked : all.slice(0, ENTRY_LIMIT) - const sorted = picked.length ? [...base].sort((a, b) => (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0)) : base - const category = props.language.t("palette.group.commands") - return sorted.map((option) => createCommandEntry(option, category)) - }) - - return { allowed, list, picks } -} - -function createFileEntries(props: { - file: ReturnType - tabs: () => ReturnType["tabs"]> - language: ReturnType -}) { - const tabState = createSessionTabs({ - tabs: props.tabs, - pathFromTab: props.file.pathFromTab, - normalizeTab: (tab) => (tab.startsWith("file://") ? props.file.tab(tab) : tab), - }) - const recent = createMemo(() => { - const all = tabState.openedTabs() - const active = tabState.activeFileTab() - const order = active ? [active, ...all.filter((item) => item !== active)] : all - const seen = new Set() - const category = props.language.t("palette.group.files") - const items: Entry[] = [] - - for (const item of order) { - const path = props.file.pathFromTab(item) - if (!path) continue - if (seen.has(path)) continue - seen.add(path) - items.push(createFileEntry(path, category)) - } - - return items.slice(0, ENTRY_LIMIT) - }) - - const root = createMemo(() => { - const category = props.language.t("palette.group.files") - const nodes = props.file.tree.children("") - const paths = nodes - .filter((node) => node.type === "file") - .map((node) => node.path) - .sort((a, b) => a.localeCompare(b)) - return paths.slice(0, ENTRY_LIMIT).map((path) => createFileEntry(path, category)) - }) - - return { recent, root } -} - -function createSessionEntries(props: { - workspaces: () => string[] - label: (directory: string) => string - serverSDK: ServerSDK - language: ReturnType -}) { - const state: { - token: number - inflight: Promise | undefined - cached: Entry[] | undefined - } = { - token: 0, - inflight: undefined, - cached: undefined, - } - - const sessions = (text: string) => { - const query = text.trim() - if (!query) { - state.token += 1 - state.inflight = undefined - state.cached = undefined - return [] as Entry[] - } - - if (state.cached) return state.cached - if (state.inflight) return state.inflight - - const current = state.token - const dirs = props.workspaces() - if (dirs.length === 0) return [] as Entry[] - - state.inflight = Promise.all( - dirs.map((directory) => { - const description = props.label(directory) - return props.serverSDK.client.session - .list({ directory, roots: true }) - .then((x) => - (x.data ?? []) - .filter((s) => !!s?.id) - .map((s) => ({ - id: s.id, - title: s.title ?? props.language.t("command.session.new"), - description, - directory, - archived: s.time?.archived, - updated: s.time?.updated, - })), - ) - .catch( - () => - [] as { - id: string - title: string - description: string - directory: string - archived?: number - updated?: number - }[], - ) - }), - ) - .then((results) => { - if (state.token !== current) return [] as Entry[] - const seen = new Set() - const category = props.language.t("command.category.session") - const next = results - .flat() - .filter((item) => { - const key = `${item.directory}:${item.id}` - if (seen.has(key)) return false - seen.add(key) - return true - }) - .map((item) => createSessionEntry(item, category)) - state.cached = next - return next - }) - .catch(() => [] as Entry[]) - .finally(() => { - state.inflight = undefined - }) - - return state.inflight - } - - return { sessions } -} - export function DialogSelectFile(props: { mode?: DialogSelectFileMode; onOpenFile?: (path: string) => void }) { - const command = useCommand() - const language = useLanguage() const platform = usePlatform() const settings = useSettings() - const layout = useLayout() - const file = useFile() - const dialog = useDialog() - const navigate = useNavigate() - const serverSDK = useServerSDK() - const serverSync = useServerSync() - const { params, tabs, view } = useSessionLayout() const filesOnly = () => props.mode === "files" - const state = { cleanup: undefined as (() => void) | void, committed: false } - const [grouped, setGrouped] = createSignal(false) - const commandEntries = createCommandEntries({ filesOnly, command, language }) - const fileEntries = createFileEntries({ file, tabs, language }) - const projectDirectory = createMemo(() => decode64(params.dir) ?? "") - const project = createMemo(() => { - const directory = projectDirectory() - if (!directory) return - return layout.projects.list().find((p) => p.worktree === directory || p.sandboxes?.includes(directory)) - }) - const workspaces = createMemo(() => { - const directory = projectDirectory() - const current = project() - if (!current) return directory ? [directory] : [] - - const dirs = [current.worktree, ...(current.sandboxes ?? [])] - if (directory && !dirs.includes(directory)) return [...dirs, directory] - return dirs - }) - const homedir = createMemo(() => serverSync().data.path.home) - const label = (directory: string) => { - const current = project() - const kind = - current && directory === current.worktree - ? language.t("workspace.type.local") - : language.t("workspace.type.sandbox") - const [store] = serverSync().child(directory, { bootstrap: false }) - const home = homedir() - const path = home ? directory.replace(home, "~") : directory - const name = store.vcs?.branch ?? getFilename(directory) - return `${kind} : ${name || path}` + if (!filesOnly() && settings.general.newLayoutDesigns()) { + return } - const { sessions } = createSessionEntries({ workspaces, label, serverSDK: serverSDK(), language }) + if (filesOnly() && platform.platform === "desktop" && settings.general.newLayoutDesigns()) { + return + } + + return +} + +function DialogSelectFileDesktopV2(props: { onOpenFile?: (path: string) => void }) { + const language = useLanguage() + const serverSDK = useServerSDK() + const { params } = useSessionLayout() + const projectDirectory = createMemo(() => decode64(params.dir) ?? "") + const openFile = createCommandPaletteFileOpener(props.onOpenFile) + + return ( + { + if (typeof result !== "string") return + openFile(result) + }} + /> + ) +} + +function DialogSelectFileLegacy(props: { filesOnly: () => boolean; onOpenFile?: (path: string) => void }) { + const palette = createCommandPaletteModel(props) + const [grouped, setGrouped] = createSignal(false) const items = async (text: string) => { const query = text.trim() setGrouped(query.length > 0) - if (!query && filesOnly()) { - const loaded = file.tree.state("")?.loaded - const pending = loaded ? Promise.resolve() : file.tree.list("") - const next = uniqueEntries([...fileEntries.recent(), ...fileEntries.root()]) + if (!query && props.filesOnly()) { + const loaded = palette.file.tree.state("")?.loaded + const pending = loaded ? Promise.resolve() : palette.file.tree.list("") + const next = uniqueCommandPaletteEntries([...palette.recentFileEntries(), ...palette.rootFileEntries()]) if (loaded || next.length > 0) { void pending @@ -331,79 +86,24 @@ export function DialogSelectFile(props: { mode?: DialogSelectFileMode; onOpenFil } await pending - return uniqueEntries([...fileEntries.recent(), ...fileEntries.root()]) + return uniqueCommandPaletteEntries([...palette.recentFileEntries(), ...palette.rootFileEntries()]) } - if (!query) return [...commandEntries.picks(), ...fileEntries.recent()] + if (!query) return [...palette.preferredCommandEntries(), ...palette.recentFileEntries()] - if (filesOnly()) { - const files = await file.searchFiles(query) - const category = language.t("palette.group.files") - return files.map((path) => createFileEntry(path, category)) + if (props.filesOnly()) { + const files = await palette.file.searchFiles(query) + const category = palette.language.t("palette.group.files") + return files.map((path) => createCommandPaletteFileEntry(path, category)) } - const [files, nextSessions] = await Promise.all([file.searchFiles(query), Promise.resolve(sessions(query))]) - const category = language.t("palette.group.files") - const entries = files.map((path) => createFileEntry(path, category)) - return [...commandEntries.list(), ...nextSessions, ...entries] - } - - const handleMove = (item: Entry | undefined) => { - state.cleanup?.() - if (!item) return - if (item.type !== "command") return - state.cleanup = item.option?.onHighlight?.() - } - - const open = (path: string) => { - const value = file.tab(path) - void tabs().open(value) - void file.load(path) - if (!view().reviewPanel.opened()) view().reviewPanel.open() - layout.fileTree.setTab("all") - props.onOpenFile?.(path) - tabs().setActive(value) - } - - const handleSelect = (item: Entry | undefined) => { - if (!item) return - state.committed = true - state.cleanup = undefined - dialog.close() - - if (item.type === "command") { - item.option?.onSelect?.("palette") - return - } - - if (item.type === "session") { - if (!item.directory || !item.sessionID) return - navigate(`/${base64Encode(item.directory)}/session/${item.sessionID}`) - return - } - - if (!item.path) return - open(item.path) - } - - onCleanup(() => { - if (state.committed) return - state.cleanup?.() - }) - - if (filesOnly() && platform.platform === "desktop" && settings.general.newLayoutDesigns()) { - return ( - { - if (typeof result !== "string") return - open(result) - }} - /> - ) + const [files, nextSessions] = await Promise.all([ + palette.file.searchFiles(query), + Promise.resolve(palette.sessions(query)), + ]) + const category = palette.language.t("palette.group.files") + const entries = files.map((path) => createCommandPaletteFileEntry(path, category)) + return [...palette.commandEntries(), ...nextSessions, ...entries] } return ( @@ -411,21 +111,21 @@ export function DialogSelectFile(props: { mode?: DialogSelectFileMode; onOpenFil item.id} filterKeys={["title", "description", "category"]} skipFilter={(item) => item.type === "file"} groupBy={grouped() ? (item) => item.category : () => ""} - onMove={handleMove} - onSelect={handleSelect} + onMove={(item: CommandPaletteEntry | undefined) => palette.highlight(item)} + onSelect={(item: CommandPaletteEntry | undefined) => palette.select(item)} > {(item) => ( - {formatKeybind(item.keybind ?? "", language.t)} + {formatKeybind(item.keybind ?? "", palette.language.t)} @@ -479,7 +179,7 @@ export function DialogSelectFile(props: { mode?: DialogSelectFileMode; onOpenFil - {getRelativeTime(new Date(item.updated!).toISOString(), language.t)} + {getRelativeTime(new Date(item.updated!).toISOString(), palette.language.t)} diff --git a/packages/app/src/components/dialog-select-model.tsx b/packages/app/src/components/dialog-select-model.tsx index cea5f34d0d9..23857946d0e 100644 --- a/packages/app/src/components/dialog-select-model.tsx +++ b/packages/app/src/components/dialog-select-model.tsx @@ -24,6 +24,7 @@ import { Tooltip } from "@opencode-ai/ui/tooltip" import { Icon } from "@opencode-ai/ui/v2/icon" import { Tag as TagV2 } from "@opencode-ai/ui/v2/badge-v2" import { MenuV2 } from "@opencode-ai/ui/v2/menu-v2" +import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2" import { ModelTooltip } from "./model-tooltip" import { useLanguage } from "@/context/language" import { decode64 } from "@/utils/base64" @@ -92,6 +93,7 @@ const ModelList: Component<{ class="w-full" placement="right-start" gutter={12} + openDelay={0} value={} > {node} @@ -446,26 +448,41 @@ export function ModelSelectorPopoverV2(props: { {(item) => ( - { - setStore("active", modelKey(item)) - setTimeout(() => searchRef?.focus()) - }} - onSelect={() => selectModel(item)} + + } > - {item.name} - - {language.t("model.tag.free")} - - - {language.t("model.tag.latest")} - - + { + setStore("active", modelKey(item)) + setTimeout(() => searchRef?.focus()) + }} + onSelect={() => selectModel(item)} + > + {item.name} + + {language.t("model.tag.free")} + + + {language.t("model.tag.latest")} + + + )} diff --git a/packages/app/src/components/model-tooltip.tsx b/packages/app/src/components/model-tooltip.tsx index 53164dae85e..7253c069173 100644 --- a/packages/app/src/components/model-tooltip.tsx +++ b/packages/app/src/components/model-tooltip.tsx @@ -1,4 +1,4 @@ -import { Show, type Component } from "solid-js" +import { Show, type Component, type JSX } from "solid-js" import { useLanguage } from "@/context/language" type InputKey = "text" | "image" | "audio" | "video" | "pdf" @@ -23,7 +23,18 @@ type ModelInfo = { } } -export const ModelTooltip: Component<{ model: ModelInfo; latest?: boolean; free?: boolean }> = (props) => { +function ModelTooltipRow(props: { name: JSX.Element; value: JSX.Element }) { + return ( +
+ {props.name} + {props.value} +
+ ) +} + +export const ModelTooltip: Component<{ model: ModelInfo; latest?: boolean; free?: boolean; v2?: boolean }> = ( + props, +) => { const language = useLanguage() const sourceName = (model: ModelInfo) => { const value = `${model.id} ${model.name}`.toLowerCase() @@ -51,6 +62,13 @@ export const ModelTooltip: Component<{ model: ModelInfo; latest?: boolean; free? const suffix = tags.length ? ` (${tags.join(", ")})` : "" return `${sourceName(props.model)} ${props.model.name}${suffix}` } + const name = () => { + const tags: Array = [] + if (props.latest) tags.push(language.t("model.tag.latest")) + if (props.free) tags.push(language.t("model.tag.free")) + const suffix = tags.length ? ` (${tags.join(", ")})` : "" + return `${props.model.name}${suffix}` + } const inputs = () => { if (props.model.capabilities) { const input = props.model.capabilities.input @@ -73,6 +91,21 @@ export const ModelTooltip: Component<{ model: ModelInfo; latest?: boolean; free? : language.t("model.tooltip.reasoning.none") } const context = () => language.t("model.tooltip.context", { limit: props.model.limit.context.toLocaleString() }) + const contextLimit = () => props.model.limit.context.toLocaleString(language.intl()) + + if (props.v2) { + return ( +
+ + + + {(value) => } + + + +
+ ) + } return (
diff --git a/packages/app/src/components/settings-general.tsx b/packages/app/src/components/settings-general.tsx index cbbf33d2b13..c424a62a89b 100644 --- a/packages/app/src/components/settings-general.tsx +++ b/packages/app/src/components/settings-general.tsx @@ -440,11 +440,6 @@ export const SettingsGeneral: Component = () => { value={(o) => o.value} label={(o) => o.label} onSelect={(option) => option && theme.setColorScheme(option.value)} - onHighlight={(option) => { - if (!option) return - theme.previewColorScheme(option.value) - return () => theme.cancelPreview() - }} variant="secondary" size="small" triggerVariant="settings" @@ -471,11 +466,6 @@ export const SettingsGeneral: Component = () => { if (!option) return theme.setTheme(option.id) }} - onHighlight={(option) => { - if (!option) return - theme.previewTheme(option.id) - return () => theme.cancelPreview() - }} variant="secondary" size="small" triggerVariant="settings" diff --git a/packages/app/src/components/settings-v2/general.tsx b/packages/app/src/components/settings-v2/general.tsx index 0dd48a5523c..69dfb77fb0e 100644 --- a/packages/app/src/components/settings-v2/general.tsx +++ b/packages/app/src/components/settings-v2/general.tsx @@ -422,11 +422,6 @@ export const SettingsGeneralV2: Component<{ value={(o) => o.value} label={(o) => o.label} onSelect={(option) => option && theme.setColorScheme(option.value)} - onHighlight={(option) => { - if (!option) return - theme.previewColorScheme(option.value) - return () => theme.cancelPreview() - }} /> @@ -454,11 +449,6 @@ export const SettingsGeneralV2: Component<{ if (!option) return theme.setTheme(option.id) }} - onHighlight={(option) => { - if (!option) return - theme.previewTheme(option.id) - return () => theme.cancelPreview() - }} /> diff --git a/packages/app/src/components/titlebar-tab-nav.tsx b/packages/app/src/components/titlebar-tab-nav.tsx index 7f064932bcb..a397046f9b3 100644 --- a/packages/app/src/components/titlebar-tab-nav.tsx +++ b/packages/app/src/components/titlebar-tab-nav.tsx @@ -246,18 +246,23 @@ export function TabNavItem(props: { }} class="flex h-full min-w-0 flex-1 flex-row items-center gap-1.5 text-[13px] font-medium text-v2-text-text-faint group-data-[active='true']:text-v2-text-text-base group-data-[editing='true']:text-v2-text-text-base [-webkit-user-drag:none]" > - - {(session) => ( - + + - )} - + )} + + { titleEl = el diff --git a/packages/app/src/components/titlebar-tab-strip.tsx b/packages/app/src/components/titlebar-tab-strip.tsx index 6705ac1919f..7ef53324cdb 100644 --- a/packages/app/src/components/titlebar-tab-strip.tsx +++ b/packages/app/src/components/titlebar-tab-strip.tsx @@ -40,6 +40,7 @@ function SessionTabSlot(props: { let ref!: HTMLDivElement const sdk = createMemo(() => props.serverCtx()?.sdk ?? null) const cachedSession = createMemo(() => props.serverCtx()?.sync.session.peek(props.tab.sessionId)) + const persisted = createMemo(() => tabs.info[props.id]) const [loadedSession] = createResource( () => { const ctx = props.serverCtx() @@ -71,8 +72,10 @@ function SessionTabSlot(props: { createEffect(() => { const value = session() + if (!value) return + tabs.rememberSessionInfo(props.tab, value) const current = sdk() - if (!value || !current) return + if (!current) return createTabPromptState(tabs, props.tab, current.scope, { dir: base64Encode(value.directory), id: value.id, @@ -86,7 +89,7 @@ function SessionTabSlot(props: { data-tab-key={props.id} data-active={props.active()} class="relative flex w-56 min-w-7 max-w-56 flex-shrink" - classList={{ hidden: !session() && !missingSession() }} + classList={{ hidden: !session() && !missingSession() && !persisted()?.title }} > { @@ -95,7 +98,7 @@ function SessionTabSlot(props: { href={tabHref(props.tab)} server={props.tab.server} session={session} - fallbackTitle={missingSession() ? language.t("session.tab.unknown") : undefined} + fallbackTitle={persisted()?.title ?? (missingSession() ? language.t("session.tab.unknown") : undefined)} onTitleChange={(title) => { const value = session() const ctx = props.serverCtx() diff --git a/packages/app/src/context/command.test.ts b/packages/app/src/context/command.test.ts index 2b956287c54..4297dd89bd3 100644 --- a/packages/app/src/context/command.test.ts +++ b/packages/app/src/context/command.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from "bun:test" -import { upsertCommandRegistration } from "./command" +import { resolveKeybindOption, upsertCommandRegistration } from "./command" describe("upsertCommandRegistration", () => { test("replaces keyed registrations", () => { @@ -23,3 +23,19 @@ describe("upsertCommandRegistration", () => { expect(next[1]?.options).toBe(one) }) }) + +describe("resolveKeybindOption", () => { + test("prefers a matching contextual command over the global fallback", () => { + const fallback = { id: "tab.close", title: "Close tab" } + const contextual = { id: "terminal.close", title: "Close terminal", when: () => true } + + expect(resolveKeybindOption([fallback, contextual], new KeyboardEvent("keydown"))).toBe(contextual) + }) + + test("uses the global fallback outside the command context", () => { + const fallback = { id: "tab.close", title: "Close tab" } + const contextual = { id: "terminal.close", title: "Close terminal", when: () => false } + + expect(resolveKeybindOption([fallback, contextual], new KeyboardEvent("keydown"))).toBe(fallback) + }) +}) diff --git a/packages/app/src/context/command.tsx b/packages/app/src/context/command.tsx index 0c935307ade..467a1115b55 100644 --- a/packages/app/src/context/command.tsx +++ b/packages/app/src/context/command.tsx @@ -82,10 +82,15 @@ export interface CommandOption { suggested?: boolean disabled?: boolean hidden?: boolean + when?: (event: KeyboardEvent) => boolean onSelect?: (source?: "palette" | "keybind" | "slash") => void onHighlight?: () => (() => void) | void } +export function resolveKeybindOption(candidates: CommandOption[] | undefined, event: KeyboardEvent) { + return candidates?.find((option) => option.when?.(event)) ?? candidates?.find((option) => !option.when) +} + type CommandSource = "palette" | "keybind" | "slash" export type CommandCatalogItem = { @@ -334,7 +339,7 @@ export const { use: useCommand, provider: CommandProvider } = createSimpleContex }) const keymap = createMemo(() => { - const map = new Map() + const map = new Map() for (const option of options()) { if (option.id.startsWith(SUGGESTED_PREFIX)) continue if (option.disabled) continue @@ -344,8 +349,12 @@ export const { use: useCommand, provider: CommandProvider } = createSimpleContex for (const kb of keybinds) { if (!kb.key) continue const sig = signature(kb.key, kb.ctrl, kb.meta, kb.shift, kb.alt) - if (map.has(sig)) continue - map.set(sig, option) + const existing = map.get(sig) + if (existing) { + existing.push(option) + continue + } + map.set(sig, [option]) } } return map @@ -374,7 +383,7 @@ export const { use: useCommand, provider: CommandProvider } = createSimpleContex const sig = signatureFromEvent(event) const isPalette = palette().has(sig) - const option = keymap().get(sig) + const option = resolveKeybindOption(keymap().get(sig), event) const modified = event.ctrlKey || event.metaKey || event.altKey const isTab = event.key === "Tab" @@ -383,17 +392,19 @@ export const { use: useCommand, provider: CommandProvider } = createSimpleContex if (isPalette) { event.preventDefault() + event.stopPropagation() showPalette() return } if (!option) return event.preventDefault() + event.stopPropagation() option.onSelect?.("keybind") } onMount(() => { - makeEventListener(document, "keydown", handleKeyDown) + makeEventListener(document, "keydown", handleKeyDown, { capture: true }) }) function register(cb: () => CommandOption[]): void diff --git a/packages/app/src/context/tabs.tsx b/packages/app/src/context/tabs.tsx index 11155d2ca47..47ed77e781e 100644 --- a/packages/app/src/context/tabs.tsx +++ b/packages/app/src/context/tabs.tsx @@ -28,6 +28,11 @@ export type DraftTab = { export type Tab = SessionTab | DraftTab +export type TabInfo = { + title?: string + directory?: string +} + type RecentTab = { key?: string } @@ -64,6 +69,7 @@ export const { use: useTabs, provider: TabsProvider } = createSimpleContext({ createStore([]), ) const [recent, setRecent, , recentReady] = persisted(Persist.window("tabs.recent"), createStore({})) + const [info, setInfo] = persisted(Persist.window("tabs.info"), createStore>({})) const [closed, setClosed, , closedReady] = persisted(Persist.window("tabs.closed"), createStore([])) const params = useParams() @@ -102,6 +108,15 @@ export const { use: useTabs, provider: TabsProvider } = createSimpleContext({ for (const key of draftPersistedKeys()) removePersisted(Persist.draft(draftID, key), platform) } + const removeInfo = (key: string) => { + if (!info[key]) return + setInfo( + produce((draft) => { + delete draft[key] + }), + ) + } + onCleanup(memory.dispose) createEffect(() => { @@ -110,11 +125,19 @@ export const { use: useTabs, provider: TabsProvider } = createSimpleContext({ const next = store.filter((tab) => servers.has(tab.server)) if (next.length !== store.length) { for (const tab of store) { - if (!servers.has(tab.server)) memory.remove(tabKey(tab)) + if (!servers.has(tab.server)) { + const key = tabKey(tab) + memory.remove(key) + removeInfo(key) + } } setStore(() => next) } if (recent.key && !next.some((tab) => tabKey(tab) === recent.key)) setRecentKey(undefined) + const keys = new Set(next.map(tabKey)) + for (const key of Object.keys(info)) { + if (!keys.has(key)) removeInfo(key) + } }) createEffect(() => { @@ -150,6 +173,7 @@ export const { use: useTabs, provider: TabsProvider } = createSimpleContext({ if (nextTab) navigateTab(nextTab) }).finally(() => closing.delete(key)) memory.remove(key) + removeInfo(key) if (draftID) removeDraftPersisted(draftID) } @@ -264,6 +288,7 @@ export const { use: useTabs, provider: TabsProvider } = createSimpleContext({ const removed = store.filter((tab) => tab.server === key).map(tabKey) setStore((tabs) => tabs.filter((tab) => tab.server !== key)) for (const key of removed) memory.remove(key) + for (const key of removed) removeInfo(key) if (recent.key && removed.includes(recent.key)) setRecentKey(undefined) for (const draftID of drafts) removeDraftPersisted(draftID) if (server.key === key) navigate("/") @@ -318,6 +343,14 @@ export const { use: useTabs, provider: TabsProvider } = createSimpleContext({ if (recent.key && removed.includes(recent.key)) setRecentKey(undefined) }) for (const key of removed) memory.remove(key) + for (const key of removed) removeInfo(key) + }, + rememberSessionInfo(tab: SessionTab, session: Session) { + const key = tabKey(tab) + const next = { title: session.title, directory: session.directory } + const current = info[key] + if (current?.title === next.title && current.directory === next.directory) return + setInfo(key, next) }, select: navigateTab, remember(tab: Tab) { @@ -342,6 +375,6 @@ export const { use: useTabs, provider: TabsProvider } = createSimpleContext({ }, } - return { ...actions, store, ready, recentReady } + return { ...actions, store, info, ready, recentReady } }, }) diff --git a/packages/app/src/i18n/ar.ts b/packages/app/src/i18n/ar.ts index a5174a59000..c60920d1076 100644 --- a/packages/app/src/i18n/ar.ts +++ b/packages/app/src/i18n/ar.ts @@ -21,6 +21,9 @@ export const dict = { "theme.scheme.dark": "داكن", "command.sidebar.toggle": "تبديل الشريط الجانبي", "command.project.open": "فتح مشروع", + "command.project.previous": "المشروع السابق", + "command.project.next": "المشروع التالي", + "command.project.index": "التبديل إلى المشروع {{index}}", "command.provider.connect": "اتصال بموفر", "command.server.switch": "تبديل الخادم", "command.settings.open": "فتح الإعدادات", @@ -39,6 +42,7 @@ export const dict = { "command.session.new": "جلسة جديدة", "command.file.open": "فتح ملف", "command.tab.close": "إغلاق علامة التبويب", + "command.tab.reopenClosed": "إعادة فتح علامة التبويب المغلقة", "command.context.addSelection": "إضافة التحديد إلى السياق", "command.context.addSelection.description": "إضافة الأسطر المحددة من الملف الحالي", "command.input.focus": "التركيز على حقل الإدخال", @@ -193,6 +197,11 @@ export const dict = { "model.input.video": "فيديو", "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.context": "حد السياق {{limit}}", @@ -202,6 +211,7 @@ export const dict = { "common.loading": "جارٍ التحميل", "common.loading.ellipsis": "...", "common.cancel": "إلغاء", + "common.clear": "مسح", "common.connect": "اتصال", "common.disconnect": "قطع الاتصال", "common.continue": "إرسال", @@ -218,6 +228,8 @@ export const dict = { "prompt.mode.shell": "Shell", "prompt.mode.normal": "Prompt", "prompt.mode.shell.exit": "esc للخروج", + "session.child.promptDisabled": "لا يمكن إرسال موجّهات إلى جلسات الوكلاء الفرعيين.", + "session.child.backToParent": "العودة إلى الجلسة الرئيسية.", "prompt.example.1": "إصلاح TODO في قاعدة التعليمات البرمجية", "prompt.example.2": "ما هو المكدس التقني لهذا المشروع؟", "prompt.example.3": "إصلاح الاختبارات المعطلة", @@ -314,6 +326,74 @@ export const dict = { "dialog.server.menu.delete": "حذف", "dialog.server.current": "الخادم الحالي", "dialog.server.status.default": "افتراضي", + "wsl.server.add": "إضافة خادم WSL", + "wsl.server.addShort": "إضافة WSL", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "خادم WSL", + "wsl.server.retryStart": "إعادة محاولة التشغيل", + "wsl.server.updating": "جارٍ التحديث...", + "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.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.checkingOpencode": "جارٍ التحقق من OpenCode...", + "wsl.onboarding.checkingOpencodeIn": "جارٍ التحقق من OpenCode في {{distro}}...", + "wsl.onboarding.updatingOpencode": "جارٍ تحديث OpenCode...", + "wsl.onboarding.updatingOpencodeIn": "جارٍ تحديث 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.installOpencode": "تثبيت OpenCode", + "wsl.onboarding.chooseDistroFirst": "اختر توزيعة أولاً.", + "wsl.onboarding.loadFailed": "فشل تحميل حالة WSL.", + "wsl.onboarding.loading": "جارٍ التحميل...", + "wsl.onboarding.installedDistros": "التوزيعات المثبتة", + "wsl.onboarding.checkAgain": "تحقق مجددًا", + "wsl.onboarding.distroStatus.ready": "جاهزة", + "wsl.onboarding.distroStatus.checking": "جارٍ التحقق...", + "wsl.onboarding.distroStatus.opencodeMissing": "OpenCode غير مثبت", + "wsl.onboarding.distroStatus.missingTools": "bash و curl مفقودان", + "wsl.onboarding.distroStatus.unsupported": "غير مدعومة · استخدم WSL 2", + "wsl.onboarding.needAnotherDistro": "هل تحتاج إلى توزيعة أخرى؟", + "wsl.onboarding.needAnotherDistroHint": "ثبّت توزيعة Linux من كتالوج WSL", + "wsl.onboarding.wslNotInstalled.title": "WSL غير مثبت", + "wsl.onboarding.wslNotInstalled.description": + "يلزم WSL (نظام Windows الفرعي لـ Linux) قبل أن يتمكن OpenCode من إضافة خادم WSL", + "wsl.onboarding.wslUnavailable.title": "WSL غير متاح", + "wsl.onboarding.wslUnavailable.description": "تعذر على OpenCode التحقق من WSL على هذا الجهاز.", + "wsl.onboarding.installWsl": "تثبيت WSL", + "wsl.onboarding.windowsRestartRequired": "أعد تشغيل Windows لإكمال تثبيت WSL، ثم أعد فتح OpenCode.", + "wsl.onboarding.next": "التالي", + "wsl.onboarding.refresh": "تحديث", + "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.openTerminal": "فتح المحطة الطرفية", + "wsl.onboarding.path": "المسار: {{path}}", + "wsl.onboarding.notFound": "غير موجود", + "wsl.onboarding.version": "الإصدار: {{version}}", + "wsl.onboarding.unknown": "غير معروف", + "wsl.onboarding.desktopVersion": "سطح المكتب {{version}}", + "wsl.onboarding.versionMismatch": "لا يتطابق الإصدار المثبت مع إصدار تطبيق سطح المكتب.", + "wsl.onboarding.adding": "جارٍ الإضافة...", "dialog.project.edit.title": "تحرير المشروع", "dialog.project.edit.name": "الاسم", "dialog.project.edit.icon": "أيقونة", @@ -370,6 +450,7 @@ export const dict = { "language.no": "Norsk", "language.br": "Português (Brasil)", "language.bs": "Bosanski", + "language.uk": "Українська", "language.th": "ไทย", "language.tr": "Türkçe", "toast.language.title": "لغة", @@ -406,10 +487,12 @@ export const dict = { "toast.update.action.notYet": "ليس الآن", "error.page.title": "حدث خطأ ما", "error.page.description": "حدث خطأ أثناء تحميل التطبيق.", + "error.page.description.localServerStartup": "حدث خطأ أثناء بدء تشغيل الخادم المحلي.", "error.page.details.label": "تفاصيل الخطأ", "error.page.action.restart": "إعادة تشغيل", "error.page.action.report": "الإبلاغ عن الخطأ", "error.page.action.reported": "تم الإبلاغ عن الخطأ", + "error.page.action.exportLogs": "تصدير السجلات", "error.page.action.checking": "جارٍ التحقق...", "error.page.action.checkUpdates": "التحقق من وجود تحديثات", "error.page.action.updateTo": "تحديث إلى {{version}}", @@ -450,16 +533,38 @@ export const dict = { "home.recentProjects": "المشاريع الحديثة", "home.empty.title": "لا توجد مشاريع حديثة", "home.empty.description": "ابدأ بفتح مشروع محلي", + "home.title": "الرئيسية", + "home.projects": "المشاريع", + "home.project.add": "إضافة مشروع", + "home.recentlyClosed": "المغلقة مؤخرًا", + "home.server.collapse": "طي مشاريع الخادم", + "home.server.expand": "توسيع مشاريع الخادم", + "home.sessions.search.placeholder": "البحث في الجلسات", + "home.sessions.search.placeholder.scoped": "البحث في جلسات {{scope}}", + "home.sessions.search.sessions": "الجلسات", + "home.sessions.search.noResults": "لم يتم العثور على جلسات لـ {{query}}", + "home.sessions.empty": "لا يوجد شيء هنا بعد", + "home.sessions.empty.description": "أنشئ جلسة للبدء", + "home.sessions.group.today": "اليوم", + "home.sessions.group.yesterday": "أمس", + "home.sessions.group.older": "الأقدم", "session.tab.session": "جلسة", "session.tab.review": "مراجعة", "session.tab.context": "سياق", + "session.tab.unknown": "جلسة غير معروفة", "session.panel.reviewAndFiles": "المراجعة والملفات", + "session.error.notFound": "لا يمكن العثور على هذه الجلسة", + "session.error.notFound.description": "يشير هذا التبويب إلى جلسة لم تعد موجودة على هذا الخادم.", + "session.error.notFound.closeTab": "إغلاق علامة التبويب", + "session.error.serverConnection": "تعذر الاتصال بهذا الخادم", "session.review.filesChanged": "تم تغيير {{count}} ملفات", "session.review.change.one": "تغيير", "session.review.change.other": "تغييرات", "session.review.loadingChanges": "جارٍ تحميل التغييرات...", "session.review.empty": "لا توجد تغييرات في هذه الجلسة بعد", "session.review.noChanges": "لا توجد تغييرات", + "session.review.noUncommittedChanges": "لا توجد تغييرات غير مُودَعة بعد", + "session.review.noBranchChanges": "لا توجد تغييرات في الفرع بعد", "session.review.noVcs": "لم يتم اكتشاف نظام التحكم في الإصدار Git، لن يتم عرض التغييرات", "session.review.noSnapshot": "تم تعطيل تتبع اللقطات في التكوين، لذا فإن تغييرات الجلسة غير متوفرة", "session.files.selectToOpen": "اختر ملفًا لفتحه", @@ -475,6 +580,10 @@ export const dict = { "session.todo.title": "المهام", "session.todo.collapse": "طي", "session.todo.expand": "توسيع", + "session.question.minimize": "تصغير السؤال", + "session.question.restore": "استعادة السؤال", + "session.question.pending.one": "{{count}} سؤال معلق", + "session.question.pending.other": "الأسئلة المعلقة: {{count}}", "session.followupDock.summary.one": "{{count}} رسالة في الانتظار", "session.followupDock.summary.other": "{{count}} رسائل في الانتظار", "session.followupDock.sendNow": "إرسال الآن", @@ -487,9 +596,16 @@ export const dict = { "session.revertDock.expand": "توسيع الرسائل التي تم التراجع عنها", "session.revertDock.restore": "استعادة الرسالة", "session.new.title": "ابنِ أي شيء", + "session.new.project.new": "مشروع جديد", + "session.new.project.search": "البحث عن المشاريع", + "session.new.project.add": "إضافة مشروع", "session.new.worktree.main": "الفرع الرئيسي", "session.new.worktree.mainWithBranch": "الفرع الرئيسي ({{branch}})", "session.new.worktree.create": "إنشاء شجرة عمل جديدة", + "session.new.workspace.runIn": "تشغيل الجلسة في", + "session.new.workspace.triggerLocal": "محلي", + "session.new.workspace.local": "المستودع المحلي", + "session.new.workspace.existing": "مساحة عمل…", "session.new.lastModified": "آخر تعديل", "session.header.search.placeholder": "بحث {{project}}", "session.header.searchFiles": "بحث عن الملفات", @@ -550,6 +666,8 @@ export const dict = { "sidebar.project.recentSessions": "الجلسات الحديثة", "sidebar.project.viewAllSessions": "عرض جميع الجلسات", "sidebar.project.clearNotifications": "مسح الإشعارات", + "sidebar.empty.title": "لا توجد مشاريع مفتوحة", + "sidebar.empty.description": "افتح مشروعًا للبدء", "app.name.desktop": "OpenCode Desktop", "settings.section.desktop": "سطح المكتب", "settings.section.server": "الخادم", @@ -559,6 +677,7 @@ export const dict = { "settings.desktop.wsl.title": "تكامل WSL", "settings.desktop.wsl.description": "تشغيل خادم OpenCode داخل WSL على Windows.", "settings.general.section.appearance": "المظهر", + "settings.general.section.advanced": "متقدم", "settings.general.section.notifications": "إشعارات النظام", "settings.general.section.updates": "التحديثات", "settings.general.section.sounds": "المؤثرات الصوتية", @@ -566,6 +685,11 @@ export const dict = { "settings.general.section.display": "شاشة العرض", "settings.general.row.language.title": "اللغة", "settings.general.row.language.description": "تغيير لغة العرض لـ OpenCode", + "settings.general.row.shell.title": "Shell المحطة الطرفية", + "settings.general.row.shell.description": + "اختر shell المستخدم في المحطة الطرفية. تُستخدم واجهات shell المتوافقة أيضًا في استدعاءات أدوات الوكيل.", + "settings.general.row.shell.autoDefault": "تلقائي (افتراضي)", + "settings.general.row.shell.terminalOnly": "المحطة الطرفية فقط", "settings.general.row.appearance.title": "المظهر", "settings.general.row.appearance.description": "تخصيص كيفية ظهور OpenCode على جهازك", "settings.general.row.colorScheme.title": "مخطط الألوان", @@ -574,14 +698,29 @@ export const dict = { "settings.general.row.theme.description": "تخصيص سمة OpenCode.", "settings.general.row.font.title": "خط الكود", "settings.general.row.font.description": "خصّص الخط المستخدم في كتل التعليمات البرمجية", - "settings.general.row.terminalFont.title": "Terminal Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "settings.general.row.terminalFont.title": "خط الطرفية", + "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.option.queue": "قائمة انتظار", "settings.general.row.followup.option.steer": "توجيه", + "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": "لوحة الأوامر", + "settings.general.row.showSearch.description": "إظهار زر البحث ولوحة الأوامر في شريط العنوان", + "settings.general.row.showTerminal.title": "المحطة الطرفية", + "settings.general.row.showTerminal.description": "إظهار زر المحطة الطرفية في شريط عنوان سطح المكتب", + "settings.general.row.showStatus.title": "حالة الخادم", + "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.reasoningSummaries.title": "إظهار ملخصات الاستنتاج", "settings.general.row.reasoningSummaries.description": "عرض ملخصات استنتاج النموذج في الشريط الزمني", "settings.general.row.shellToolPartsExpanded.title": "توسيع أجزاء أداة shell", @@ -590,6 +729,11 @@ export const dict = { "settings.general.row.editToolPartsExpanded.title": "توسيع أجزاء أداة edit", "settings.general.row.editToolPartsExpanded.description": "إظهار أجزاء أدوات edit و write و patch موسعة بشكل افتراضي في الشريط الزمني", + "settings.general.row.newLayoutDesigns.title": "التخطيط والتصاميم الجديدة", + "settings.general.row.newLayoutDesigns.description": + "تمكين التخطيط والصفحة الرئيسية ومحرر الرسائل وواجهة الجلسة المعاد تصميمها", + "settings.general.row.pinchZoom.title": "التكبير بإيماءة القرص", + "settings.general.row.pinchZoom.description": "السماح بإيماءة القرص على لوحة اللمس وإيماءة Ctrl-scroll للتكبير", "settings.general.row.wayland.title": "استخدام Wayland الأصلي", "settings.general.row.wayland.description": "تعطيل التراجع إلى X11 على Wayland. يتطلب إعادة التشغيل.", "settings.general.row.wayland.tooltip": @@ -602,6 +746,8 @@ export const dict = { "settings.updates.row.check.description": "التحقق يدويًا من التحديثات وتثبيتها إذا كانت متاحة", "settings.updates.action.checkNow": "تحقق الآن", "settings.updates.action.checking": "جارٍ التحقق...", + "settings.updates.action.downloading": "جارٍ التنزيل...", + "settings.updates.action.installing": "جارٍ التثبيت...", "settings.updates.toast.latest.title": "أنت على آخر إصدار", "settings.updates.toast.latest.description": "أنت تستخدم أحدث إصدار من OpenCode.", "sound.option.none": "بلا", diff --git a/packages/app/src/i18n/br.ts b/packages/app/src/i18n/br.ts index 2e53bb1af0e..12911744e2c 100644 --- a/packages/app/src/i18n/br.ts +++ b/packages/app/src/i18n/br.ts @@ -21,6 +21,9 @@ export const dict = { "theme.scheme.dark": "Escuro", "command.sidebar.toggle": "Alternar barra lateral", "command.project.open": "Abrir projeto", + "command.project.previous": "Projeto anterior", + "command.project.next": "Próximo projeto", + "command.project.index": "Alternar para o projeto {{index}}", "command.provider.connect": "Conectar provedor", "command.server.switch": "Trocar servidor", "command.settings.open": "Abrir configurações", @@ -39,6 +42,7 @@ export const dict = { "command.session.new": "Nova sessão", "command.file.open": "Abrir arquivo", "command.tab.close": "Fechar aba", + "command.tab.reopenClosed": "Reabrir aba fechada", "command.context.addSelection": "Adicionar seleção ao contexto", "command.context.addSelection.description": "Adicionar as linhas selecionadas do arquivo atual", "command.input.focus": "Focar entrada", @@ -193,6 +197,11 @@ export const dict = { "model.input.video": "vídeo", "model.input.pdf": "pdf", "model.tooltip.allows": "Permite: {{inputs}}", + "model.tooltip.context.label": "Contexto", + "model.tooltip.inputs": "Entradas", + "model.tooltip.model": "Modelo", + "model.tooltip.provider": "Provedor", + "model.tooltip.reasoning": "Raciocínio", "model.tooltip.reasoning.allowed": "Permite raciocínio", "model.tooltip.reasoning.none": "Sem raciocínio", "model.tooltip.context": "Limite de contexto {{limit}}", @@ -202,6 +211,7 @@ export const dict = { "common.loading": "Carregando", "common.loading.ellipsis": "...", "common.cancel": "Cancelar", + "common.clear": "Limpar", "common.connect": "Conectar", "common.disconnect": "Desconectar", "common.continue": "Enviar", @@ -218,6 +228,8 @@ export const dict = { "prompt.mode.shell": "Shell", "prompt.mode.normal": "Prompt", "prompt.mode.shell.exit": "esc para sair", + "session.child.promptDisabled": "Não é possível enviar prompts em sessões de subagentes.", + "session.child.backToParent": "Voltar à sessão principal.", "prompt.example.1": "Corrigir um TODO no código", "prompt.example.2": "Qual é a stack tecnológica deste projeto?", "prompt.example.3": "Corrigir testes quebrados", @@ -314,6 +326,75 @@ export const dict = { "dialog.server.menu.delete": "Excluir", "dialog.server.current": "Servidor atual", "dialog.server.status.default": "Padrão", + "wsl.server.add": "Adicionar servidor WSL", + "wsl.server.addShort": "Adicionar WSL", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "Servidor WSL", + "wsl.server.retryStart": "Tentar iniciar novamente", + "wsl.server.updating": "Atualizando...", + "wsl.onboarding.step.distro": "Escolher distribuição", + "wsl.onboarding.step.opencode": "OpenCode", + "wsl.onboarding.checkingRuntime": "Verificando o WSL...", + "wsl.onboarding.restartRequired": "O Windows precisa ser reiniciado para concluir a instalação do WSL.", + "wsl.onboarding.ready": "O WSL está pronto.", + "wsl.onboarding.required": "O WSL é necessário para continuar.", + "wsl.onboarding.checkingDistros": "Verificando distribuições...", + "wsl.onboarding.installingDistro": "Instalando {{distro}}...", + "wsl.onboarding.checkingDistro": "Verificando {{distro}}...", + "wsl.onboarding.listingDistros": "Listando distribuições...", + "wsl.onboarding.distroReady": "{{distro}} está pronta.", + "wsl.onboarding.distroNotInstalled": "{{distro}} ainda não está instalada.", + "wsl.onboarding.openDistroOnce": "Abra {{distro}} uma vez para concluir a configuração.", + "wsl.onboarding.finishingDistro": "Concluindo a configuração de {{distro}}.", + "wsl.onboarding.pickDistro": "Escolha uma distribuição ou instale uma abaixo.", + "wsl.onboarding.checkingOpencode": "Verificando o OpenCode...", + "wsl.onboarding.checkingOpencodeIn": "Verificando o OpenCode em {{distro}}...", + "wsl.onboarding.updatingOpencode": "Atualizando o OpenCode...", + "wsl.onboarding.updatingOpencodeIn": "Atualizando o OpenCode em {{distro}}...", + "wsl.onboarding.updateOpencodeIn": "Atualize o OpenCode em {{distro}}.", + "wsl.onboarding.updateOpencode": "Atualizar o OpenCode", + "wsl.onboarding.opencodeReadyIn": "O OpenCode está pronto em {{distro}}.", + "wsl.onboarding.opencodeReady": "O OpenCode está pronto.", + "wsl.onboarding.installOpencodeIn": "Instale o OpenCode em {{distro}}.", + "wsl.onboarding.installOpencode": "Instalar o OpenCode", + "wsl.onboarding.chooseDistroFirst": "Escolha primeiro uma distribuição.", + "wsl.onboarding.loadFailed": "Falha ao carregar o estado do WSL.", + "wsl.onboarding.loading": "Carregando...", + "wsl.onboarding.installedDistros": "Distribuições instaladas", + "wsl.onboarding.checkAgain": "Verificar novamente", + "wsl.onboarding.distroStatus.ready": "Pronta", + "wsl.onboarding.distroStatus.checking": "Verificando...", + "wsl.onboarding.distroStatus.opencodeMissing": "OpenCode não instalado", + "wsl.onboarding.distroStatus.missingTools": "bash e curl ausentes", + "wsl.onboarding.distroStatus.unsupported": "Sem suporte · Use o WSL 2", + "wsl.onboarding.needAnotherDistro": "Precisa de outra distribuição?", + "wsl.onboarding.needAnotherDistroHint": "Instale uma distribuição Linux pelo catálogo do WSL", + "wsl.onboarding.wslNotInstalled.title": "WSL não instalado", + "wsl.onboarding.wslNotInstalled.description": + "O WSL (Windows Subsystem for Linux) é necessário para que o OpenCode possa adicionar um servidor WSL", + "wsl.onboarding.wslUnavailable.title": "WSL indisponível", + "wsl.onboarding.wslUnavailable.description": "O OpenCode não conseguiu verificar o WSL neste computador.", + "wsl.onboarding.installWsl": "Instalar o WSL", + "wsl.onboarding.windowsRestartRequired": + "Reinicie o Windows para concluir a instalação do WSL e abra o OpenCode novamente.", + "wsl.onboarding.next": "Próximo", + "wsl.onboarding.refresh": "Atualizar", + "wsl.onboarding.allDistrosAdded": "Todas as distribuições instaladas já foram adicionadas.", + "wsl.onboarding.noDistros": "Nenhuma distribuição detectada ainda.", + "wsl.onboarding.install": "Instalar", + "wsl.onboarding.installing": "Instalando...", + "wsl.onboarding.installDistro": "Instalar distribuição", + "wsl.onboarding.searchDistros": "Buscar distribuições", + "wsl.onboarding.wsl2Required": "O WSL 2 é necessário.", + "wsl.onboarding.toolsRequired": "Esta distribuição precisa do bash e do curl.", + "wsl.onboarding.openTerminal": "Abrir terminal", + "wsl.onboarding.path": "Caminho: {{path}}", + "wsl.onboarding.notFound": "não encontrado", + "wsl.onboarding.version": "Versão: {{version}}", + "wsl.onboarding.unknown": "desconhecido", + "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...", "dialog.project.edit.title": "Editar projeto", "dialog.project.edit.name": "Nome", "dialog.project.edit.icon": "Ícone", @@ -371,6 +452,7 @@ export const dict = { "language.no": "Norsk", "language.br": "Português (Brasil)", "language.bs": "Bosanski", + "language.uk": "Українська", "language.th": "ไทย", "language.tr": "Türkçe", "toast.language.title": "Idioma", @@ -407,10 +489,12 @@ export const dict = { "toast.update.action.notYet": "Agora não", "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.action.restart": "Reiniciar", "error.page.action.report": "Reportar erro", "error.page.action.reported": "Erro reportado", + "error.page.action.exportLogs": "Exportar logs", "error.page.action.checking": "Verificando...", "error.page.action.checkUpdates": "Verificar atualizações", "error.page.action.updateTo": "Atualizar para {{version}}", @@ -453,10 +537,30 @@ export const dict = { "home.recentProjects": "Projetos recentes", "home.empty.title": "Nenhum projeto recente", "home.empty.description": "Comece abrindo um projeto local", + "home.title": "Início", + "home.projects": "Projetos", + "home.project.add": "Adicionar projeto", + "home.recentlyClosed": "Projetos fechados recentemente", + "home.server.collapse": "Recolher projetos do servidor", + "home.server.expand": "Expandir projetos do servidor", + "home.sessions.search.placeholder": "Buscar sessões", + "home.sessions.search.placeholder.scoped": "Buscar sessões em {{scope}}", + "home.sessions.search.sessions": "Sessões", + "home.sessions.search.noResults": "Nenhuma sessão encontrada para {{query}}", + "home.sessions.empty": "Nada por aqui ainda", + "home.sessions.empty.description": "Crie uma sessão para começar", + "home.sessions.group.today": "Hoje", + "home.sessions.group.yesterday": "Ontem", + "home.sessions.group.older": "Mais antigas", "session.tab.session": "Sessão", "session.tab.review": "Revisão", "session.tab.context": "Contexto", + "session.tab.unknown": "Sessão desconhecida", "session.panel.reviewAndFiles": "Revisão e arquivos", + "session.error.notFound": "Esta sessão não foi encontrada", + "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.change.one": "Alteração", "session.review.change.other": "Alterações", @@ -466,6 +570,8 @@ export const dict = { "session.review.noSnapshot": "O rastreamento de snapshot está desabilitado na configuração, então as alterações da sessão estão indisponíveis", "session.review.noChanges": "Sem alterações", + "session.review.noUncommittedChanges": "Ainda não há alterações sem commit", + "session.review.noBranchChanges": "Ainda não há alterações na branch", "session.files.selectToOpen": "Selecione um arquivo para abrir", "session.files.all": "Todos os arquivos", "session.files.empty": "Nenhum arquivo", @@ -479,6 +585,10 @@ export const dict = { "session.todo.title": "Tarefas", "session.todo.collapse": "Recolher", "session.todo.expand": "Expandir", + "session.question.minimize": "Minimizar pergunta", + "session.question.restore": "Restaurar pergunta", + "session.question.pending.one": "{{count}} pergunta pendente", + "session.question.pending.other": "{{count}} perguntas pendentes", "session.followupDock.summary.one": "{{count}} mensagem na fila", "session.followupDock.summary.other": "{{count}} mensagens na fila", "session.followupDock.sendNow": "Enviar agora", @@ -491,9 +601,16 @@ export const dict = { "session.revertDock.expand": "Expandir mensagens revertidas", "session.revertDock.restore": "Restaurar mensagem", "session.new.title": "Crie qualquer coisa", + "session.new.project.new": "Novo projeto", + "session.new.project.search": "Buscar projetos", + "session.new.project.add": "Adicionar projeto", "session.new.worktree.main": "Branch principal", "session.new.worktree.mainWithBranch": "Branch principal ({{branch}})", "session.new.worktree.create": "Criar novo worktree", + "session.new.workspace.runIn": "Executar sessão em", + "session.new.workspace.triggerLocal": "Local", + "session.new.workspace.local": "Repositório local", + "session.new.workspace.existing": "Espaço de trabalho…", "session.new.lastModified": "Última modificação", "session.header.search.placeholder": "Buscar {{project}}", "session.header.searchFiles": "Buscar arquivos", @@ -557,15 +674,18 @@ export const dict = { "sidebar.project.recentSessions": "Sessões recentes", "sidebar.project.viewAllSessions": "Ver todas as sessões", "sidebar.project.clearNotifications": "Limpar notificações", + "sidebar.empty.title": "Nenhum projeto aberto", + "sidebar.empty.description": "Abra um projeto para começar", "app.name.desktop": "OpenCode Desktop", "settings.section.desktop": "Desktop", "settings.section.server": "Servidor", "settings.tab.general": "Geral", "settings.tab.shortcuts": "Atalhos", "settings.desktop.section.wsl": "WSL", - "settings.desktop.wsl.title": "WSL integration", + "settings.desktop.wsl.title": "Integração com WSL", "settings.desktop.wsl.description": "Executar o servidor OpenCode dentro do WSL no Windows.", "settings.general.section.appearance": "Aparência", + "settings.general.section.advanced": "Avançado", "settings.general.section.notifications": "Notificações do sistema", "settings.general.section.updates": "Atualizações", "settings.general.section.sounds": "Efeitos sonoros", @@ -573,6 +693,11 @@ export const dict = { "settings.general.section.display": "Tela", "settings.general.row.language.title": "Idioma", "settings.general.row.language.description": "Alterar o idioma de exibição do OpenCode", + "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.terminalOnly": "somente no terminal", "settings.general.row.appearance.title": "Aparência", "settings.general.row.appearance.description": "Personalize como o OpenCode aparece no seu dispositivo", "settings.general.row.colorScheme.title": "Esquema de cores", @@ -581,8 +706,8 @@ export const dict = { "settings.general.row.theme.description": "Personalize como o OpenCode é tematizado.", "settings.general.row.font.title": "Fonte de código", "settings.general.row.font.description": "Personalize a fonte usada em blocos de código", - "settings.general.row.terminalFont.title": "Terminal Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "settings.general.row.terminalFont.title": "Fonte do terminal", + "settings.general.row.terminalFont.description": "Personalize a fonte usada no terminal", "settings.general.row.uiFont.title": "Fonte da interface", "settings.general.row.uiFont.description": "Personalize a fonte usada em toda a interface", "settings.general.row.followup.title": "Comportamento de acompanhamento", @@ -590,6 +715,22 @@ export const dict = { "Escolha se os prompts de acompanhamento orientam imediatamente ou esperam na fila", "settings.general.row.followup.option.queue": "Fila", "settings.general.row.followup.option.steer": "Orientar", + "settings.general.row.showFileTree.title": "Árvore de arquivos", + "settings.general.row.showFileTree.description": "Mostrar o painel da árvore de arquivos nas sessões", + "settings.general.row.showNavigation.title": "Controles de navegação", + "settings.general.row.showNavigation.description": + "Mostrar os botões de voltar e avançar na barra de título do desktop", + "settings.general.row.showSearch.title": "Paleta de comandos", + "settings.general.row.showSearch.description": "Mostrar o botão de busca e paleta de comandos na barra de título", + "settings.general.row.showTerminal.title": "Terminal", + "settings.general.row.showTerminal.description": "Mostrar o botão do terminal na barra de título do desktop", + "settings.general.row.showStatus.title": "Status do servidor", + "settings.general.row.showStatus.description": "Mostrar o botão de status do servidor na barra de título", + "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.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", @@ -598,6 +739,12 @@ export const dict = { "settings.general.row.editToolPartsExpanded.title": "Expandir partes da ferramenta de edição", "settings.general.row.editToolPartsExpanded.description": "Mostrar partes das ferramentas de edição, escrita e patch expandidas por padrão na linha do tempo", + "settings.general.row.newLayoutDesigns.title": "Novo layout e design", + "settings.general.row.newLayoutDesigns.description": + "Ativar o layout, a página inicial, a área de composição e a interface de sessão reformulados", + "settings.general.row.pinchZoom.title": "Zoom com gesto de pinça", + "settings.general.row.pinchZoom.description": + "Permitir gestos de pinça no trackpad e de Ctrl+rolagem para aplicar zoom", "settings.general.row.wayland.title": "Usar Wayland nativo", "settings.general.row.wayland.description": "Desabilitar fallback X11 no Wayland. Requer reinicialização.", "settings.general.row.wayland.tooltip": @@ -610,6 +757,8 @@ export const dict = { "settings.updates.row.check.description": "Verificar atualizações manualmente e instalar se houver", "settings.updates.action.checkNow": "Verificar agora", "settings.updates.action.checking": "Verificando...", + "settings.updates.action.downloading": "Baixando...", + "settings.updates.action.installing": "Instalando...", "settings.updates.toast.latest.title": "Você está atualizado", "settings.updates.toast.latest.description": "Você está usando a versão mais recente do OpenCode.", "sound.option.none": "Nenhum", diff --git a/packages/app/src/i18n/bs.ts b/packages/app/src/i18n/bs.ts index c5b9e1a6d82..086ecc1b4c0 100644 --- a/packages/app/src/i18n/bs.ts +++ b/packages/app/src/i18n/bs.ts @@ -23,6 +23,9 @@ export const dict = { "command.sidebar.toggle": "Prikaži/sakrij bočnu traku", "command.project.open": "Otvori projekat", + "command.project.previous": "Prethodni projekat", + "command.project.next": "Sljedeći projekat", + "command.project.index": "Prebaci na projekat {{index}}", "command.provider.connect": "Poveži provajdera", "command.server.switch": "Promijeni server", "command.settings.open": "Otvori postavke", @@ -45,6 +48,7 @@ export const dict = { "command.session.new": "Nova sesija", "command.file.open": "Otvori datoteku", "command.tab.close": "Zatvori karticu", + "command.tab.reopenClosed": "Ponovo otvori zatvorenu karticu", "command.context.addSelection": "Dodaj odabir u kontekst", "command.context.addSelection.description": "Dodaj odabrane linije iz trenutne datoteke", "command.input.focus": "Fokusiraj polje za unos", @@ -209,6 +213,11 @@ export const dict = { "model.input.video": "video", "model.input.pdf": "pdf", "model.tooltip.allows": "Podržava: {{inputs}}", + "model.tooltip.context.label": "Kontekst", + "model.tooltip.inputs": "Ulazi", + "model.tooltip.model": "Model", + "model.tooltip.provider": "Provajder", + "model.tooltip.reasoning": "Rasuđivanje", "model.tooltip.reasoning.allowed": "Podržava rasuđivanje", "model.tooltip.reasoning.none": "Bez rasuđivanja", "model.tooltip.context": "Limit konteksta {{limit}}", @@ -219,6 +228,7 @@ export const dict = { "common.loading": "Učitavanje", "common.loading.ellipsis": "...", "common.cancel": "Otkaži", + "common.clear": "Očisti", "common.connect": "Poveži", "common.disconnect": "Prekini vezu", "common.continue": "Pošalji", @@ -236,6 +246,8 @@ export const dict = { "prompt.mode.shell": "Shell", "prompt.mode.normal": "Prompt", "prompt.mode.shell.exit": "esc za izlaz", + "session.child.promptDisabled": "Sesijama podagenta nije moguće slati upite.", + "session.child.backToParent": "Nazad na glavnu sesiju.", "prompt.example.1": "Popravi TODO u bazi koda", "prompt.example.2": "Koji je tehnološki stack ovog projekta?", @@ -342,6 +354,75 @@ export const dict = { "dialog.server.menu.delete": "Izbriši", "dialog.server.current": "Trenutni server", "dialog.server.status.default": "Podrazumijevano", + "wsl.server.add": "Dodaj WSL server", + "wsl.server.addShort": "Dodaj WSL", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "WSL server", + "wsl.server.retryStart": "Ponovi pokretanje", + "wsl.server.updating": "Ažuriranje...", + "wsl.onboarding.step.distro": "Odaberi distribuciju", + "wsl.onboarding.step.opencode": "OpenCode", + "wsl.onboarding.checkingRuntime": "Provjera WSL-a...", + "wsl.onboarding.restartRequired": "Potrebno je ponovo pokrenuti Windows da bi se završila instalacija WSL-a.", + "wsl.onboarding.ready": "WSL je spreman.", + "wsl.onboarding.required": "WSL je potreban za nastavak.", + "wsl.onboarding.checkingDistros": "Provjera distribucija...", + "wsl.onboarding.installingDistro": "Instaliranje {{distro}}...", + "wsl.onboarding.checkingDistro": "Provjera {{distro}}...", + "wsl.onboarding.listingDistros": "Učitavanje liste distribucija...", + "wsl.onboarding.distroReady": "Distribucija {{distro}} je spremna.", + "wsl.onboarding.distroNotInstalled": "Distribucija {{distro}} još nije instalirana.", + "wsl.onboarding.openDistroOnce": "Otvori {{distro}} jednom da završiš postavljanje.", + "wsl.onboarding.finishingDistro": "Završavanje postavljanja za {{distro}}.", + "wsl.onboarding.pickDistro": "Odaberi distribuciju ili instaliraj jednu ispod.", + "wsl.onboarding.checkingOpencode": "Provjera OpenCode...", + "wsl.onboarding.checkingOpencodeIn": "Provjera OpenCode u distribuciji {{distro}}...", + "wsl.onboarding.updatingOpencode": "Ažuriranje OpenCode...", + "wsl.onboarding.updatingOpencodeIn": "Ažuriranje OpenCode u distribuciji {{distro}}...", + "wsl.onboarding.updateOpencodeIn": "Ažuriraj OpenCode u distribuciji {{distro}}.", + "wsl.onboarding.updateOpencode": "Ažuriraj OpenCode", + "wsl.onboarding.opencodeReadyIn": "OpenCode je spreman u distribuciji {{distro}}.", + "wsl.onboarding.opencodeReady": "OpenCode je spreman.", + "wsl.onboarding.installOpencodeIn": "Instaliraj OpenCode u distribuciji {{distro}}.", + "wsl.onboarding.installOpencode": "Instaliraj OpenCode", + "wsl.onboarding.chooseDistroFirst": "Prvo odaberi distribuciju.", + "wsl.onboarding.loadFailed": "Nije uspjelo učitavanje WSL stanja.", + "wsl.onboarding.loading": "Učitavanje...", + "wsl.onboarding.installedDistros": "Instalirane distribucije", + "wsl.onboarding.checkAgain": "Provjeri ponovo", + "wsl.onboarding.distroStatus.ready": "Spremno", + "wsl.onboarding.distroStatus.checking": "Provjera...", + "wsl.onboarding.distroStatus.opencodeMissing": "OpenCode nije instaliran", + "wsl.onboarding.distroStatus.missingTools": "Nedostaju bash i curl", + "wsl.onboarding.distroStatus.unsupported": "Nije podržano · Koristi WSL 2", + "wsl.onboarding.needAnotherDistro": "Treba ti druga distribucija?", + "wsl.onboarding.needAnotherDistroHint": "Instaliraj Linux distribuciju iz WSL kataloga", + "wsl.onboarding.wslNotInstalled.title": "WSL nije instaliran", + "wsl.onboarding.wslNotInstalled.description": + "WSL (Windows Subsystem for Linux) je potreban da bi OpenCode mogao dodati WSL server", + "wsl.onboarding.wslUnavailable.title": "WSL nije dostupan", + "wsl.onboarding.wslUnavailable.description": "OpenCode nije mogao provjeriti WSL na ovom uređaju.", + "wsl.onboarding.installWsl": "Instaliraj WSL", + "wsl.onboarding.windowsRestartRequired": + "Ponovo pokreni Windows da završiš instalaciju WSL-a, zatim ponovo otvori OpenCode.", + "wsl.onboarding.next": "Dalje", + "wsl.onboarding.refresh": "Osvježi", + "wsl.onboarding.allDistrosAdded": "Sve instalirane distribucije su već dodane.", + "wsl.onboarding.noDistros": "Još nema otkrivenih distribucija.", + "wsl.onboarding.install": "Instaliraj", + "wsl.onboarding.installing": "Instaliranje...", + "wsl.onboarding.installDistro": "Instaliraj distribuciju", + "wsl.onboarding.searchDistros": "Pretraži distribucije", + "wsl.onboarding.wsl2Required": "Potreban je WSL 2.", + "wsl.onboarding.toolsRequired": "Ovoj distribuciji su potrebni bash i curl.", + "wsl.onboarding.openTerminal": "Otvori terminal", + "wsl.onboarding.path": "Putanja: {{path}}", + "wsl.onboarding.notFound": "nije pronađeno", + "wsl.onboarding.version": "Verzija: {{version}}", + "wsl.onboarding.unknown": "nepoznato", + "wsl.onboarding.desktopVersion": "desktop {{version}}", + "wsl.onboarding.versionMismatch": "Instalirana verzija ne odgovara verziji desktop aplikacije.", + "wsl.onboarding.adding": "Dodavanje...", "dialog.project.edit.title": "Uredi projekat", "dialog.project.edit.name": "Naziv", @@ -405,6 +486,7 @@ export const dict = { "language.no": "Norsk", "language.br": "Português (Brasil)", "language.bs": "Bosanski", + "language.uk": "Українська", "language.th": "ไทย", "language.tr": "Türkçe", @@ -453,10 +535,12 @@ export const dict = { "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.report": "Prijavi grešku", "error.page.action.reported": "Greška prijavljena", + "error.page.action.exportLogs": "Izvezi logove", "error.page.action.checking": "Provjera...", "error.page.action.checkUpdates": "Provjeri ažuriranja", "error.page.action.updateTo": "Ažuriraj na {{version}}", @@ -504,11 +588,31 @@ export const dict = { "home.recentProjects": "Nedavni projekti", "home.empty.title": "Nema nedavnih projekata", "home.empty.description": "Kreni tako što ćeš otvoriti lokalni projekat", + "home.title": "Početna", + "home.projects": "Projekti", + "home.project.add": "Dodaj projekat", + "home.recentlyClosed": "Nedavno zatvoreni projekti", + "home.server.collapse": "Sažmi projekte servera", + "home.server.expand": "Proširi projekte servera", + "home.sessions.search.placeholder": "Pretraži sesije", + "home.sessions.search.placeholder.scoped": "Pretraži sesije u {{scope}}", + "home.sessions.search.sessions": "Sesije", + "home.sessions.search.noResults": "Nema pronađenih sesija za {{query}}", + "home.sessions.empty": "Ovdje još nema ničega", + "home.sessions.empty.description": "Kreiraj sesiju za početak", + "home.sessions.group.today": "Danas", + "home.sessions.group.yesterday": "Jučer", + "home.sessions.group.older": "Starije", "session.tab.session": "Sesija", "session.tab.review": "Pregled", "session.tab.context": "Kontekst", + "session.tab.unknown": "Nepoznata sesija", "session.panel.reviewAndFiles": "Pregled i datoteke", + "session.error.notFound": "Ova sesija nije pronađena", + "session.error.notFound.description": "Ova kartica upućuje na sesiju koja više ne postoji na ovom serveru.", + "session.error.notFound.closeTab": "Zatvori karticu", + "session.error.serverConnection": "Nije moguće povezati se s ovim serverom", "session.review.filesChanged": "Izmijenjeno {{count}} datoteka", "session.review.change.one": "Izmjena", "session.review.change.other": "Izmjene", @@ -518,6 +622,8 @@ export const dict = { "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.noBranchChanges": "Još nema promjena na grani", "session.files.selectToOpen": "Odaberi datoteku za otvaranje", "session.files.all": "Sve datoteke", @@ -534,6 +640,10 @@ export const dict = { "session.todo.title": "Zadaci", "session.todo.collapse": "Sažmi", "session.todo.expand": "Proširi", + "session.question.minimize": "Minimiziraj pitanje", + "session.question.restore": "Vrati pitanje", + "session.question.pending.one": "{{count}} pitanje na čekanju", + "session.question.pending.other": "{{count}} pitanja na čekanju", "session.followupDock.summary.one": "{{count}} poruka na čekanju", "session.followupDock.summary.other": "{{count}} poruka na čekanju", "session.followupDock.sendNow": "Pošalji sada", @@ -547,9 +657,16 @@ export const dict = { "session.revertDock.restore": "Vrati poruku", "session.new.title": "Napravi bilo šta", + "session.new.project.new": "Novi projekat", + "session.new.project.search": "Pretraži projekte", + "session.new.project.add": "Dodaj projekat", "session.new.worktree.main": "Glavna grana", "session.new.worktree.mainWithBranch": "Glavna grana ({{branch}})", "session.new.worktree.create": "Kreiraj novi worktree", + "session.new.workspace.runIn": "Pokreni sesiju u", + "session.new.workspace.triggerLocal": "Lokalno", + "session.new.workspace.local": "Lokalni repozitorij", + "session.new.workspace.existing": "Radni prostor…", "session.new.lastModified": "Posljednja izmjena", "session.header.search.placeholder": "Pretraži {{project}}", @@ -618,6 +735,8 @@ export const dict = { "sidebar.project.recentSessions": "Nedavne sesije", "sidebar.project.viewAllSessions": "Prikaži sve sesije", "sidebar.project.clearNotifications": "Očisti obavijesti", + "sidebar.empty.title": "Nema otvorenih projekata", + "sidebar.empty.description": "Otvori projekat za početak", "app.name.desktop": "OpenCode Desktop", @@ -630,6 +749,7 @@ export const dict = { "settings.desktop.wsl.description": "Pokreni OpenCode server unutar WSL-a na Windowsu.", "settings.general.section.appearance": "Izgled", + "settings.general.section.advanced": "Napredno", "settings.general.section.notifications": "Sistemske obavijesti", "settings.general.section.updates": "Ažuriranja", "settings.general.section.sounds": "Zvučni efekti", @@ -638,6 +758,11 @@ export const dict = { "settings.general.row.language.title": "Jezik", "settings.general.row.language.description": "Promijeni jezik prikaza u OpenCode-u", + "settings.general.row.shell.title": "Shell terminala", + "settings.general.row.shell.description": + "Odaberi shell koji se koristi za terminal. Kompatibilni shellovi koriste se i za pozive alata agenta.", + "settings.general.row.shell.autoDefault": "Automatski (podrazumijevano)", + "settings.general.row.shell.terminalOnly": "samo terminal", "settings.general.row.appearance.title": "Izgled", "settings.general.row.appearance.description": "Prilagodi kako OpenCode izgleda na tvom uređaju", "settings.general.row.colorScheme.title": "Šema boja", @@ -646,14 +771,30 @@ export const dict = { "settings.general.row.theme.description": "Prilagodi temu OpenCode-a.", "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": "Terminal Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "settings.general.row.terminalFont.title": "Font terminala", + "settings.general.row.terminalFont.description": "Prilagodite 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", "settings.general.row.followup.description": "Odaberi da li upiti nadovezivanja usmjeravaju odmah ili čekaju u redu", "settings.general.row.followup.option.queue": "Red čekanja", "settings.general.row.followup.option.steer": "Usmjeri", + "settings.general.row.showFileTree.title": "Stablo datoteka", + "settings.general.row.showFileTree.description": "Prikaži stablo datoteka u sesijama", + "settings.general.row.showNavigation.title": "Kontrole navigacije", + "settings.general.row.showNavigation.description": + "Prikaži dugmad za nazad i naprijed u naslovnoj traci desktop aplikacije", + "settings.general.row.showSearch.title": "Paleta komandi", + "settings.general.row.showSearch.description": "Prikaži dugme za pretragu i paletu komandi u naslovnoj traci", + "settings.general.row.showTerminal.title": "Terminal", + "settings.general.row.showTerminal.description": "Prikaži dugme terminala u naslovnoj traci desktop aplikacije", + "settings.general.row.showStatus.title": "Status servera", + "settings.general.row.showStatus.description": "Prikaži dugme statusa servera u naslovnoj traci", + "settings.general.row.mobileTitlebarBottom.title": "Donja navigacija", + "settings.general.row.mobileTitlebarBottom.description": + "Postavi naslovnu traku i kartice sesije na dno ekrana na mobilnim uređajima", + "settings.general.row.showCustomAgents.title": "Prilagođeni agenti", + "settings.general.row.showCustomAgents.description": "Prikaži izbor agenta u uređivaču poruke", "settings.general.row.reasoningSummaries.title": "Prikaži sažetke rasuđivanja", "settings.general.row.reasoningSummaries.description": "Prikaži sažetke rasuđivanja modela na vremenskoj traci", @@ -663,6 +804,12 @@ export const dict = { "settings.general.row.editToolPartsExpanded.title": "Proširi dijelove alata za uređivanje", "settings.general.row.editToolPartsExpanded.description": "Prikaži dijelove alata za uređivanje, pisanje i patch podrazumijevano proširene na vremenskoj traci", + "settings.general.row.newLayoutDesigns.title": "Novi raspored i dizajn", + "settings.general.row.newLayoutDesigns.description": + "Omogući redizajnirani raspored, početnu stranicu, uređivač poruke i interfejs sesije", + "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.tooltip": @@ -677,6 +824,8 @@ export const dict = { "settings.updates.row.check.description": "Ručno provjeri ažuriranja i instaliraj ako su dostupna", "settings.updates.action.checkNow": "Provjeri sada", "settings.updates.action.checking": "Provjera...", + "settings.updates.action.downloading": "Preuzimanje...", + "settings.updates.action.installing": "Instaliranje...", "settings.updates.toast.latest.title": "Sve je ažurno", "settings.updates.toast.latest.description": "Koristiš najnoviju verziju OpenCode-a.", "sound.option.none": "Nijedan", diff --git a/packages/app/src/i18n/da.ts b/packages/app/src/i18n/da.ts index ad43c1d1114..859bea230b2 100644 --- a/packages/app/src/i18n/da.ts +++ b/packages/app/src/i18n/da.ts @@ -23,6 +23,9 @@ export const dict = { "command.sidebar.toggle": "Skift sidebjælke", "command.project.open": "Åbn projekt", + "command.project.previous": "Forrige projekt", + "command.project.next": "Næste projekt", + "command.project.index": "Skift til projekt {{index}}", "command.provider.connect": "Tilslut udbyder", "command.server.switch": "Skift server", "command.settings.open": "Åbn indstillinger", @@ -45,6 +48,7 @@ export const dict = { "command.session.new": "Ny session", "command.file.open": "Åbn fil", "command.tab.close": "Luk fane", + "command.tab.reopenClosed": "Åbn lukket fane igen", "command.context.addSelection": "Tilføj markering til kontekst", "command.context.addSelection.description": "Tilføj markerede linjer fra den aktuelle fil", "command.input.focus": "Fokuser inputfelt", @@ -208,6 +212,11 @@ export const dict = { "model.input.video": "video", "model.input.pdf": "pdf", "model.tooltip.allows": "Tillader: {{inputs}}", + "model.tooltip.context.label": "Kontekst", + "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.context": "Kontekstgrænse {{limit}}", @@ -217,6 +226,7 @@ export const dict = { "common.loading": "Indlæser", "common.loading.ellipsis": "...", "common.cancel": "Annuller", + "common.clear": "Ryd", "common.connect": "Forbind", "common.disconnect": "Frakobl", "common.continue": "Indsend", @@ -234,6 +244,8 @@ export const dict = { "prompt.mode.shell": "Shell", "prompt.mode.normal": "Prompt", "prompt.mode.shell.exit": "esc for at afslutte", + "session.child.promptDisabled": "Der kan ikke sendes prompts til underagentsessioner.", + "session.child.backToParent": "Tilbage til hovedsessionen.", "prompt.example.1": "Ret en TODO i koden", "prompt.example.2": "Hvad er teknologistakken for dette projekt?", @@ -340,6 +352,75 @@ export const dict = { "dialog.server.menu.delete": "Slet", "dialog.server.current": "Nuværende server", "dialog.server.status.default": "Standard", + "wsl.server.add": "Tilføj WSL-server", + "wsl.server.addShort": "Tilføj WSL", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "WSL-server", + "wsl.server.retryStart": "Prøv at starte igen", + "wsl.server.updating": "Opdaterer...", + "wsl.onboarding.step.distro": "Vælg distribution", + "wsl.onboarding.step.opencode": "OpenCode", + "wsl.onboarding.checkingRuntime": "Tjekker WSL...", + "wsl.onboarding.restartRequired": "Windows skal genstartes for at fuldføre installationen af WSL.", + "wsl.onboarding.ready": "WSL er klar.", + "wsl.onboarding.required": "WSL er påkrævet for at fortsætte.", + "wsl.onboarding.checkingDistros": "Tjekker distributioner...", + "wsl.onboarding.installingDistro": "Installerer {{distro}}...", + "wsl.onboarding.checkingDistro": "Tjekker {{distro}}...", + "wsl.onboarding.listingDistros": "Henter liste over distributioner...", + "wsl.onboarding.distroReady": "{{distro}} er klar.", + "wsl.onboarding.distroNotInstalled": "{{distro}} er ikke installeret endnu.", + "wsl.onboarding.openDistroOnce": "Åbn {{distro}} én gang for at fuldføre opsætningen.", + "wsl.onboarding.finishingDistro": "Fuldfører opsætningen af {{distro}}.", + "wsl.onboarding.pickDistro": "Vælg en distribution, eller installer en nedenfor.", + "wsl.onboarding.checkingOpencode": "Tjekker OpenCode...", + "wsl.onboarding.checkingOpencodeIn": "Tjekker OpenCode i {{distro}}...", + "wsl.onboarding.updatingOpencode": "Opdaterer OpenCode...", + "wsl.onboarding.updatingOpencodeIn": "Opdaterer OpenCode i {{distro}}...", + "wsl.onboarding.updateOpencodeIn": "Opdater OpenCode i {{distro}}.", + "wsl.onboarding.updateOpencode": "Opdater OpenCode", + "wsl.onboarding.opencodeReadyIn": "OpenCode er klar i {{distro}}.", + "wsl.onboarding.opencodeReady": "OpenCode er klar.", + "wsl.onboarding.installOpencodeIn": "Installer OpenCode i {{distro}}.", + "wsl.onboarding.installOpencode": "Installer OpenCode", + "wsl.onboarding.chooseDistroFirst": "Vælg først en distribution.", + "wsl.onboarding.loadFailed": "Kunne ikke indlæse WSL-status.", + "wsl.onboarding.loading": "Indlæser...", + "wsl.onboarding.installedDistros": "Installerede distributioner", + "wsl.onboarding.checkAgain": "Tjek igen", + "wsl.onboarding.distroStatus.ready": "Klar", + "wsl.onboarding.distroStatus.checking": "Tjekker...", + "wsl.onboarding.distroStatus.opencodeMissing": "OpenCode er ikke installeret", + "wsl.onboarding.distroStatus.missingTools": "Mangler bash, curl", + "wsl.onboarding.distroStatus.unsupported": "Ikke understøttet · Brug WSL 2", + "wsl.onboarding.needAnotherDistro": "Har du brug for en anden distribution?", + "wsl.onboarding.needAnotherDistroHint": "Installer en Linux-distribution fra WSL-kataloget", + "wsl.onboarding.wslNotInstalled.title": "WSL er ikke installeret", + "wsl.onboarding.wslNotInstalled.description": + "WSL (Windows Subsystem for Linux) er påkrævet, før OpenCode kan tilføje en WSL-server", + "wsl.onboarding.wslUnavailable.title": "WSL er ikke tilgængelig", + "wsl.onboarding.wslUnavailable.description": "OpenCode kunne ikke bekræfte WSL på denne maskine.", + "wsl.onboarding.installWsl": "Installer WSL", + "wsl.onboarding.windowsRestartRequired": + "Genstart Windows for at fuldføre installationen af WSL, og åbn derefter OpenCode igen.", + "wsl.onboarding.next": "Næste", + "wsl.onboarding.refresh": "Opdater", + "wsl.onboarding.allDistrosAdded": "Alle installerede distributioner er allerede tilføjet.", + "wsl.onboarding.noDistros": "Ingen distributioner fundet endnu.", + "wsl.onboarding.install": "Installer", + "wsl.onboarding.installing": "Installerer...", + "wsl.onboarding.installDistro": "Installer distribution", + "wsl.onboarding.searchDistros": "Søg efter distributioner", + "wsl.onboarding.wsl2Required": "WSL 2 er påkrævet.", + "wsl.onboarding.toolsRequired": "Denne distribution kræver bash og curl.", + "wsl.onboarding.openTerminal": "Åbn terminal", + "wsl.onboarding.path": "Sti: {{path}}", + "wsl.onboarding.notFound": "ikke fundet", + "wsl.onboarding.version": "Version: {{version}}", + "wsl.onboarding.unknown": "ukendt", + "wsl.onboarding.desktopVersion": "desktop {{version}}", + "wsl.onboarding.versionMismatch": "Den installerede version matcher ikke desktopappens version.", + "wsl.onboarding.adding": "Tilføjer...", "dialog.project.edit.title": "Rediger projekt", "dialog.project.edit.name": "Navn", @@ -403,6 +484,7 @@ export const dict = { "language.no": "Norsk", "language.br": "Português (Brasil)", "language.bs": "Bosanski", + "language.uk": "Українська", "language.th": "ไทย", "language.tr": "Türkçe", @@ -450,10 +532,12 @@ export const dict = { "error.page.title": "Noget gik galt", "error.page.description": "Der opstod en fejl under indlæsning af applikationen.", + "error.page.description.localServerStartup": "Der opstod en fejl under start af den lokale server.", "error.page.details.label": "Fejldetaljer", "error.page.action.restart": "Genstart", "error.page.action.report": "Rapportér fejl", "error.page.action.reported": "Fejl rapporteret", + "error.page.action.exportLogs": "Eksportér logfiler", "error.page.action.checking": "Tjekker...", "error.page.action.checkUpdates": "Tjek for opdateringer", "error.page.action.updateTo": "Opdater til {{version}}", @@ -501,11 +585,31 @@ export const dict = { "home.recentProjects": "Seneste projekter", "home.empty.title": "Ingen seneste projekter", "home.empty.description": "Kom i gang ved at åbne et lokalt projekt", + "home.title": "Hjem", + "home.projects": "Projekter", + "home.project.add": "Tilføj projekt", + "home.recentlyClosed": "Lukket for nylig", + "home.server.collapse": "Skjul serverprojekter", + "home.server.expand": "Udvid serverprojekter", + "home.sessions.search.placeholder": "Søg i sessioner", + "home.sessions.search.placeholder.scoped": "Søg i sessioner i {{scope}}", + "home.sessions.search.sessions": "Sessioner", + "home.sessions.search.noResults": "Ingen sessioner fundet for {{query}}", + "home.sessions.empty": "Intet her endnu", + "home.sessions.empty.description": "Opret en session for at komme i gang", + "home.sessions.group.today": "I dag", + "home.sessions.group.yesterday": "I går", + "home.sessions.group.older": "Ældre", "session.tab.session": "Session", "session.tab.review": "Gennemgang", "session.tab.context": "Kontekst", + "session.tab.unknown": "Ukendt session", "session.panel.reviewAndFiles": "Gennemgang og filer", + "session.error.notFound": "Denne session kan ikke findes", + "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.change.one": "Ændring", "session.review.change.other": "Ændringer", @@ -515,6 +619,8 @@ export const dict = { "session.review.noSnapshot": "Snapshot-sporing er deaktiveret i konfigurationen, så sessionsændringer er ikke tilgængelige", "session.review.noChanges": "Ingen ændringer", + "session.review.noUncommittedChanges": "Ingen ændringer uden commit endnu", + "session.review.noBranchChanges": "Ingen grenændringer endnu", "session.files.selectToOpen": "Vælg en fil at åbne", "session.files.all": "Alle filer", "session.files.empty": "Ingen filer", @@ -529,6 +635,10 @@ export const dict = { "session.todo.title": "Opgaver", "session.todo.collapse": "Skjul", "session.todo.expand": "Udvid", + "session.question.minimize": "Minimer spørgsmål", + "session.question.restore": "Gendan spørgsmål", + "session.question.pending.one": "{{count}} afventende spørgsmål", + "session.question.pending.other": "{{count}} afventende spørgsmål", "session.followupDock.summary.one": "{{count}} besked i kø", "session.followupDock.summary.other": "{{count}} beskeder i kø", "session.followupDock.sendNow": "Send nu", @@ -542,9 +652,16 @@ export const dict = { "session.revertDock.restore": "Gendan besked", "session.new.title": "Byg hvad som helst", + "session.new.project.new": "Nyt projekt", + "session.new.project.search": "Søg efter projekter", + "session.new.project.add": "Tilføj projekt", "session.new.worktree.main": "Hovedgren", "session.new.worktree.mainWithBranch": "Hovedgren ({{branch}})", "session.new.worktree.create": "Opret nyt worktree", + "session.new.workspace.runIn": "Kør session i", + "session.new.workspace.triggerLocal": "Lokal", + "session.new.workspace.local": "Lokalt repository", + "session.new.workspace.existing": "Arbejdsområde…", "session.new.lastModified": "Sidst ændret", "session.header.search.placeholder": "Søg {{project}}", @@ -614,6 +731,8 @@ export const dict = { "sidebar.project.recentSessions": "Seneste sessioner", "sidebar.project.viewAllSessions": "Vis alle sessioner", "sidebar.project.clearNotifications": "Ryd notifikationer", + "sidebar.empty.title": "Ingen åbne projekter", + "sidebar.empty.description": "Åbn et projekt for at komme i gang", "app.name.desktop": "OpenCode Desktop", "settings.section.desktop": "Desktop", @@ -625,6 +744,7 @@ export const dict = { "settings.desktop.wsl.description": "Kør OpenCode-serveren inde i WSL på Windows.", "settings.general.section.appearance": "Udseende", + "settings.general.section.advanced": "Avanceret", "settings.general.section.notifications": "Systemmeddelelser", "settings.general.section.updates": "Opdateringer", "settings.general.section.sounds": "Lydeffekter", @@ -633,6 +753,11 @@ export const dict = { "settings.general.row.language.title": "Sprog", "settings.general.row.language.description": "Ændr visningssproget for OpenCode", + "settings.general.row.shell.title": "Terminalshell", + "settings.general.row.shell.description": + "Vælg den shell, der bruges i din terminal. Kompatible shells bruges også til agentens værktøjskald.", + "settings.general.row.shell.autoDefault": "Automatisk (standard)", + "settings.general.row.shell.terminalOnly": "kun terminal", "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", @@ -641,14 +766,29 @@ export const dict = { "settings.general.row.theme.description": "Tilpas hvordan OpenCode er temabestemt.", "settings.general.row.font.title": "Kode-skrifttype", "settings.general.row.font.description": "Tilpas skrifttypen, der bruges i kodeblokke", - "settings.general.row.terminalFont.title": "Terminal Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "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.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ø", "settings.general.row.followup.option.steer": "Styr", + "settings.general.row.showFileTree.title": "Filtræ", + "settings.general.row.showFileTree.description": "Vis filtræspanelet i sessioner", + "settings.general.row.showNavigation.title": "Navigationsknapper", + "settings.general.row.showNavigation.description": "Vis tilbage- og frem-knapperne i desktopappens titellinje", + "settings.general.row.showSearch.title": "Kommandopalette", + "settings.general.row.showSearch.description": "Vis knappen til søgning og kommandopaletten i titellinjen", + "settings.general.row.showTerminal.title": "Terminal", + "settings.general.row.showTerminal.description": "Vis terminalknappen i desktopappens titellinje", + "settings.general.row.showStatus.title": "Serverstatus", + "settings.general.row.showStatus.description": "Vis serverstatusknappen i titellinjen", + "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", @@ -657,6 +797,11 @@ export const dict = { "settings.general.row.editToolPartsExpanded.title": "Udvid edit-værktøjsdele", "settings.general.row.editToolPartsExpanded.description": "Vis edit-, write- og patch-værktøjsdele udvidet som standard i tidslinjen", + "settings.general.row.newLayoutDesigns.title": "Nyt layout og design", + "settings.general.row.newLayoutDesigns.description": + "Aktivér det nydesignede layout, startsiden, promptfeltet og sessionsbrugerfladen", + "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.description": "Deaktiver X11-fallback på Wayland. Kræver genstart.", "settings.general.row.wayland.tooltip": @@ -671,6 +816,8 @@ export const dict = { "settings.updates.row.check.description": "Tjek manuelt for opdateringer og installer, hvis tilgængelig", "settings.updates.action.checkNow": "Tjek nu", "settings.updates.action.checking": "Tjekker...", + "settings.updates.action.downloading": "Downloader...", + "settings.updates.action.installing": "Installerer...", "settings.updates.toast.latest.title": "Du er opdateret", "settings.updates.toast.latest.description": "Du kører den nyeste version af OpenCode.", diff --git a/packages/app/src/i18n/de.ts b/packages/app/src/i18n/de.ts index d0ec9507e06..c96dc232a5d 100644 --- a/packages/app/src/i18n/de.ts +++ b/packages/app/src/i18n/de.ts @@ -25,6 +25,9 @@ export const dict = { "theme.scheme.dark": "Dunkel", "command.sidebar.toggle": "Seitenleiste umschalten", "command.project.open": "Projekt öffnen", + "command.project.previous": "Vorheriges Projekt", + "command.project.next": "Nächstes Projekt", + "command.project.index": "Zu Projekt {{index}} wechseln", "command.provider.connect": "Anbieter verbinden", "command.server.switch": "Server wechseln", "command.settings.open": "Einstellungen öffnen", @@ -43,6 +46,7 @@ export const dict = { "command.session.new": "Neue Sitzung", "command.file.open": "Datei öffnen", "command.tab.close": "Tab schließen", + "command.tab.reopenClosed": "Geschlossenen Tab wieder öffnen", "command.context.addSelection": "Auswahl zum Kontext hinzufügen", "command.context.addSelection.description": "Ausgewählte Zeilen aus der aktuellen Datei hinzufügen", "command.input.focus": "Eingabefeld fokussieren", @@ -198,6 +202,11 @@ export const dict = { "model.input.video": "Video", "model.input.pdf": "PDF", "model.tooltip.allows": "Erlaubt: {{inputs}}", + "model.tooltip.context.label": "Kontext", + "model.tooltip.inputs": "Eingaben", + "model.tooltip.model": "Modell", + "model.tooltip.provider": "Anbieter", + "model.tooltip.reasoning": "Reasoning", "model.tooltip.reasoning.allowed": "Erlaubt Reasoning", "model.tooltip.reasoning.none": "Kein Reasoning", "model.tooltip.context": "Kontextlimit {{limit}}", @@ -207,6 +216,7 @@ export const dict = { "common.loading": "Laden", "common.loading.ellipsis": "...", "common.cancel": "Abbrechen", + "common.clear": "Leeren", "common.connect": "Verbinden", "common.disconnect": "Trennen", "common.continue": "Absenden", @@ -223,6 +233,8 @@ export const dict = { "prompt.mode.shell": "Shell", "prompt.mode.normal": "Prompt", "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", "prompt.example.2": "Was ist der Tech-Stack dieses Projekts?", "prompt.example.3": "Fehlerhafte Tests beheben", @@ -320,6 +332,75 @@ export const dict = { "dialog.server.menu.delete": "Löschen", "dialog.server.current": "Aktueller Server", "dialog.server.status.default": "Standard", + "wsl.server.add": "WSL-Server hinzufügen", + "wsl.server.addShort": "WSL hinzufügen", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "WSL-Server", + "wsl.server.retryStart": "Start erneut versuchen", + "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.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.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.updateOpencodeIn": "Aktualisieren Sie OpenCode in {{distro}}.", + "wsl.onboarding.updateOpencode": "OpenCode aktualisieren", + "wsl.onboarding.opencodeReadyIn": "OpenCode ist in {{distro}} bereit.", + "wsl.onboarding.opencodeReady": "OpenCode ist bereit.", + "wsl.onboarding.installOpencodeIn": "Installieren Sie OpenCode in {{distro}}.", + "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.installedDistros": "Installierte Distributionen", + "wsl.onboarding.checkAgain": "Erneut prüfen", + "wsl.onboarding.distroStatus.ready": "Bereit", + "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", + "wsl.onboarding.needAnotherDistro": "Andere Distribution benötigt?", + "wsl.onboarding.needAnotherDistroHint": "Installieren Sie eine Linux-Distribution aus dem WSL-Katalog", + "wsl.onboarding.wslNotInstalled.title": "WSL nicht installiert", + "wsl.onboarding.wslNotInstalled.description": + "WSL (Windows Subsystem for Linux) ist erforderlich, bevor OpenCode einen WSL-Server hinzufügen kann", + "wsl.onboarding.wslUnavailable.title": "WSL nicht verfügbar", + "wsl.onboarding.wslUnavailable.description": "OpenCode konnte WSL auf diesem Computer nicht überprüfen.", + "wsl.onboarding.installWsl": "WSL installieren", + "wsl.onboarding.windowsRestartRequired": + "Starten Sie Windows neu, um die WSL-Installation abzuschließen, und öffnen Sie dann OpenCode erneut.", + "wsl.onboarding.next": "Weiter", + "wsl.onboarding.refresh": "Aktualisieren", + "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.installDistro": "Distribution installieren", + "wsl.onboarding.searchDistros": "Distributionen durchsuchen", + "wsl.onboarding.wsl2Required": "WSL 2 ist erforderlich.", + "wsl.onboarding.toolsRequired": "Diese Distribution benötigt bash und curl.", + "wsl.onboarding.openTerminal": "Terminal öffnen", + "wsl.onboarding.path": "Pfad: {{path}}", + "wsl.onboarding.notFound": "nicht gefunden", + "wsl.onboarding.version": "Version: {{version}}", + "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...", "dialog.project.edit.title": "Projekt bearbeiten", "dialog.project.edit.name": "Name", "dialog.project.edit.icon": "Icon", @@ -378,6 +459,7 @@ export const dict = { "language.no": "Norsk", "language.br": "Português (Brasil)", "language.bs": "Bosanski", + "language.uk": "Українська", "language.th": "ไทย", "language.tr": "Türkçe", "toast.language.title": "Sprache", @@ -414,10 +496,12 @@ export const dict = { "toast.update.action.notYet": "Noch nicht", "error.page.title": "Etwas ist schiefgelaufen", "error.page.description": "Beim Laden der Anwendung ist ein Fehler aufgetreten.", + "error.page.description.localServerStartup": "Beim Starten des lokalen Servers ist ein Fehler aufgetreten.", "error.page.details.label": "Fehlerdetails", "error.page.action.restart": "Neustart", "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.checkUpdates": "Nach Updates suchen", "error.page.action.updateTo": "Auf {{version}} aktualisieren", @@ -461,10 +545,31 @@ export const dict = { "home.recentProjects": "Letzte Projekte", "home.empty.title": "Keine letzten Projekte", "home.empty.description": "Starten Sie, indem Sie ein lokales Projekt öffnen", + "home.title": "Startseite", + "home.projects": "Projekte", + "home.project.add": "Projekt hinzufügen", + "home.recentlyClosed": "Kürzlich geschlossen", + "home.server.collapse": "Serverprojekte einklappen", + "home.server.expand": "Serverprojekte ausklappen", + "home.sessions.search.placeholder": "Sitzungen durchsuchen", + "home.sessions.search.placeholder.scoped": "Sitzungen in {{scope}} durchsuchen", + "home.sessions.search.sessions": "Sitzungen", + "home.sessions.search.noResults": "Keine Sitzungen für {{query}} gefunden", + "home.sessions.empty": "Hier ist noch nichts", + "home.sessions.empty.description": "Erstellen Sie eine Sitzung, um loszulegen", + "home.sessions.group.today": "Heute", + "home.sessions.group.yesterday": "Gestern", + "home.sessions.group.older": "Älter", "session.tab.session": "Sitzung", "session.tab.review": "Überprüfung", "session.tab.context": "Kontext", + "session.tab.unknown": "Unbekannte Sitzung", "session.panel.reviewAndFiles": "Überprüfung und Dateien", + "session.error.notFound": "Diese Sitzung wurde nicht gefunden", + "session.error.notFound.description": + "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.change.one": "Änderung", "session.review.change.other": "Änderungen", @@ -474,6 +579,8 @@ export const dict = { "session.review.noSnapshot": "Snapshot-Tracking ist in der Konfiguration deaktiviert, daher sind Sitzungsänderungen nicht verfügbar", "session.review.noChanges": "Keine Änderungen", + "session.review.noUncommittedChanges": "Noch keine nicht committeten Änderungen", + "session.review.noBranchChanges": "Noch keine Branch-Änderungen", "session.files.selectToOpen": "Datei zum Öffnen auswählen", "session.files.all": "Alle Dateien", "session.files.empty": "Keine Dateien", @@ -487,6 +594,10 @@ export const dict = { "session.todo.title": "Aufgaben", "session.todo.collapse": "Einklappen", "session.todo.expand": "Ausklappen", + "session.question.minimize": "Frage minimieren", + "session.question.restore": "Frage wiederherstellen", + "session.question.pending.one": "{{count}} ausstehende Frage", + "session.question.pending.other": "{{count}} ausstehende Fragen", "session.followupDock.summary.one": "{{count}} Nachricht in der Warteschlange", "session.followupDock.summary.other": "{{count}} Nachrichten in der Warteschlange", "session.followupDock.sendNow": "Jetzt senden", @@ -499,9 +610,16 @@ export const dict = { "session.revertDock.expand": "Zurückgesetzte Nachrichten ausklappen", "session.revertDock.restore": "Nachricht wiederherstellen", "session.new.title": "Baue, was du willst", + "session.new.project.new": "Neues Projekt", + "session.new.project.search": "Projekte durchsuchen", + "session.new.project.add": "Projekt hinzufügen", "session.new.worktree.main": "Haupt-Branch", "session.new.worktree.mainWithBranch": "Haupt-Branch ({{branch}})", "session.new.worktree.create": "Neuen Worktree erstellen", + "session.new.workspace.runIn": "Sitzung ausführen in", + "session.new.workspace.triggerLocal": "Lokal", + "session.new.workspace.local": "Lokales Repository", + "session.new.workspace.existing": "Arbeitsbereich…", "session.new.lastModified": "Zuletzt geändert", "session.header.search.placeholder": "{{project}} durchsuchen", "session.header.searchFiles": "Dateien suchen", @@ -566,6 +684,8 @@ export const dict = { "sidebar.project.recentSessions": "Letzte Sitzungen", "sidebar.project.viewAllSessions": "Alle Sitzungen anzeigen", "sidebar.project.clearNotifications": "Benachrichtigungen löschen", + "sidebar.empty.title": "Keine Projekte geöffnet", + "sidebar.empty.description": "Öffnen Sie ein Projekt, um loszulegen", "app.name.desktop": "OpenCode Desktop", "settings.section.desktop": "Desktop", "settings.section.server": "Server", @@ -575,6 +695,7 @@ export const dict = { "settings.desktop.wsl.title": "WSL-Integration", "settings.desktop.wsl.description": "OpenCode-Server innerhalb von WSL unter Windows ausführen.", "settings.general.section.appearance": "Erscheinungsbild", + "settings.general.section.advanced": "Erweitert", "settings.general.section.notifications": "Systembenachrichtigungen", "settings.general.section.updates": "Updates", "settings.general.section.sounds": "Soundeffekte", @@ -582,6 +703,11 @@ export const dict = { "settings.general.section.display": "Anzeige", "settings.general.row.language.title": "Sprache", "settings.general.row.language.description": "Die Anzeigesprache für OpenCode ändern", + "settings.general.row.shell.title": "Terminal-Shell", + "settings.general.row.shell.description": + "Wählen Sie die Shell für Ihr Terminal aus. Kompatible Shells werden auch für Tool-Aufrufe von Agenten verwendet.", + "settings.general.row.shell.autoDefault": "Automatisch (Standard)", + "settings.general.row.shell.terminalOnly": "nur Terminal", "settings.general.row.appearance.title": "Erscheinungsbild", "settings.general.row.appearance.description": "Anpassen, wie OpenCode auf Ihrem Gerät aussieht", "settings.general.row.colorScheme.title": "Farbschema", @@ -591,8 +717,8 @@ export const dict = { "settings.general.row.theme.description": "Das Thema von OpenCode anpassen.", "settings.general.row.font.title": "Code-Schriftart", "settings.general.row.font.description": "Die in Codeblöcken verwendete Schriftart anpassen", - "settings.general.row.terminalFont.title": "Terminal Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "settings.general.row.terminalFont.title": "Terminalschriftart", + "settings.general.row.terminalFont.description": "Passe die im Terminal verwendete Schriftart an", "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", @@ -600,6 +726,23 @@ export const dict = { "Wählen Sie, ob Folgefragen 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", + "settings.general.row.showFileTree.description": "Dateibaum in Sitzungen anzeigen", + "settings.general.row.showNavigation.title": "Navigationssteuerung", + "settings.general.row.showNavigation.description": + "Schaltflächen zum Vor- und Zurücknavigieren in der Desktop-Titelleiste anzeigen", + "settings.general.row.showSearch.title": "Befehlspalette", + "settings.general.row.showSearch.description": + "Schaltfläche für Suche und Befehlspalette in der Titelleiste anzeigen", + "settings.general.row.showTerminal.title": "Terminal", + "settings.general.row.showTerminal.description": "Terminal-Schaltfläche in der Desktop-Titelleiste anzeigen", + "settings.general.row.showStatus.title": "Serverstatus", + "settings.general.row.showStatus.description": "Serverstatus-Schaltfläche in der Titelleiste anzeigen", + "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.reasoningSummaries.title": "Reasoning-Zusammenfassungen anzeigen", "settings.general.row.reasoningSummaries.description": "Zusammenfassungen des Modell-Reasonings in der Timeline anzeigen", @@ -609,6 +752,11 @@ export const dict = { "settings.general.row.editToolPartsExpanded.title": "Edit-Tool-Abschnitte ausklappen", "settings.general.row.editToolPartsExpanded.description": "Edit-, Write- und Patch-Tool-Abschnitte standardmäßig in der Timeline ausgeklappt anzeigen", + "settings.general.row.newLayoutDesigns.title": "Neues Layout und Design", + "settings.general.row.newLayoutDesigns.description": + "Neu gestaltetes Layout, Startseite, Eingabebereich und Sitzungsoberfläche aktivieren", + "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.tooltip": @@ -621,6 +769,8 @@ export const dict = { "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.", "sound.option.none": "Keine", diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts index 66e60df30e0..3da8183bb7e 100644 --- a/packages/app/src/i18n/en.ts +++ b/packages/app/src/i18n/en.ts @@ -212,6 +212,11 @@ export const dict = { "model.input.video": "video", "model.input.pdf": "pdf", "model.tooltip.allows": "Allows: {{inputs}}", + "model.tooltip.context.label": "Context", + "model.tooltip.inputs": "Inputs", + "model.tooltip.model": "Model", + "model.tooltip.provider": "Provider", + "model.tooltip.reasoning": "Reasoning", "model.tooltip.reasoning.allowed": "Allows reasoning", "model.tooltip.reasoning.none": "No reasoning", "model.tooltip.context": "Context limit {{limit}}", diff --git a/packages/app/src/i18n/es.ts b/packages/app/src/i18n/es.ts index a6371d7312a..5ef7862cd69 100644 --- a/packages/app/src/i18n/es.ts +++ b/packages/app/src/i18n/es.ts @@ -23,6 +23,9 @@ export const dict = { "command.sidebar.toggle": "Alternar barra lateral", "command.project.open": "Abrir proyecto", + "command.project.previous": "Proyecto anterior", + "command.project.next": "Siguiente proyecto", + "command.project.index": "Cambiar al proyecto {{index}}", "command.provider.connect": "Conectar proveedor", "command.server.switch": "Cambiar servidor", "command.settings.open": "Abrir ajustes", @@ -45,6 +48,7 @@ export const dict = { "command.session.new": "Nueva sesión", "command.file.open": "Abrir archivo", "command.tab.close": "Cerrar pestaña", + "command.tab.reopenClosed": "Reabrir pestaña cerrada", "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", @@ -208,6 +212,11 @@ export const dict = { "model.input.video": "video", "model.input.pdf": "pdf", "model.tooltip.allows": "Permite: {{inputs}}", + "model.tooltip.context.label": "Contexto", + "model.tooltip.inputs": "Entradas", + "model.tooltip.model": "Modelo", + "model.tooltip.provider": "Proveedor", + "model.tooltip.reasoning": "Razonamiento", "model.tooltip.reasoning.allowed": "Permite razonamiento", "model.tooltip.reasoning.none": "Sin razonamiento", "model.tooltip.context": "Límite de contexto {{limit}}", @@ -218,6 +227,7 @@ export const dict = { "common.loading": "Cargando", "common.loading.ellipsis": "...", "common.cancel": "Cancelar", + "common.clear": "Limpiar", "common.connect": "Conectar", "common.disconnect": "Desconectar", "common.continue": "Enviar", @@ -235,6 +245,8 @@ export const dict = { "prompt.mode.shell": "Shell", "prompt.mode.normal": "Prompt", "prompt.mode.shell.exit": "esc para salir", + "session.child.promptDisabled": "No se pueden enviar prompts a las sesiones de subagentes.", + "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?", @@ -341,6 +353,75 @@ export const dict = { "dialog.server.menu.delete": "Eliminar", "dialog.server.current": "Servidor actual", "dialog.server.status.default": "Predeterminado", + "wsl.server.add": "Añadir servidor WSL", + "wsl.server.addShort": "Añadir WSL", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "Servidor WSL", + "wsl.server.retryStart": "Reintentar el inicio", + "wsl.server.updating": "Actualizando...", + "wsl.onboarding.step.distro": "Elegir distribución", + "wsl.onboarding.step.opencode": "OpenCode", + "wsl.onboarding.checkingRuntime": "Comprobando WSL...", + "wsl.onboarding.restartRequired": "Es necesario reiniciar Windows para terminar de instalar WSL.", + "wsl.onboarding.ready": "WSL está listo.", + "wsl.onboarding.required": "Se necesita WSL para continuar.", + "wsl.onboarding.checkingDistros": "Comprobando distribuciones...", + "wsl.onboarding.installingDistro": "Instalando {{distro}}...", + "wsl.onboarding.checkingDistro": "Comprobando {{distro}}...", + "wsl.onboarding.listingDistros": "Listando distribuciones...", + "wsl.onboarding.distroReady": "La distribución {{distro}} está lista.", + "wsl.onboarding.distroNotInstalled": "La distribución {{distro}} aún no está instalada.", + "wsl.onboarding.openDistroOnce": "Abre {{distro}} una vez para completar la configuración.", + "wsl.onboarding.finishingDistro": "Completando la configuración de {{distro}}.", + "wsl.onboarding.pickDistro": "Elige una distribución o instala una abajo.", + "wsl.onboarding.checkingOpencode": "Comprobando OpenCode...", + "wsl.onboarding.checkingOpencodeIn": "Comprobando OpenCode en {{distro}}...", + "wsl.onboarding.updatingOpencode": "Actualizando OpenCode...", + "wsl.onboarding.updatingOpencodeIn": "Actualizando OpenCode en {{distro}}...", + "wsl.onboarding.updateOpencodeIn": "Actualiza OpenCode en {{distro}}.", + "wsl.onboarding.updateOpencode": "Actualizar OpenCode", + "wsl.onboarding.opencodeReadyIn": "OpenCode está listo en {{distro}}.", + "wsl.onboarding.opencodeReady": "OpenCode está listo.", + "wsl.onboarding.installOpencodeIn": "Instala OpenCode en {{distro}}.", + "wsl.onboarding.installOpencode": "Instalar OpenCode", + "wsl.onboarding.chooseDistroFirst": "Elige primero una distribución.", + "wsl.onboarding.loadFailed": "No se pudo cargar el estado de WSL.", + "wsl.onboarding.loading": "Cargando...", + "wsl.onboarding.installedDistros": "Distribuciones instaladas", + "wsl.onboarding.checkAgain": "Comprobar de nuevo", + "wsl.onboarding.distroStatus.ready": "Lista", + "wsl.onboarding.distroStatus.checking": "Comprobando...", + "wsl.onboarding.distroStatus.opencodeMissing": "OpenCode no está instalado", + "wsl.onboarding.distroStatus.missingTools": "Faltan bash y curl", + "wsl.onboarding.distroStatus.unsupported": "No compatible · Usa WSL 2", + "wsl.onboarding.needAnotherDistro": "¿Necesitas otra distribución?", + "wsl.onboarding.needAnotherDistroHint": "Instala una distribución de Linux desde el catálogo de WSL", + "wsl.onboarding.wslNotInstalled.title": "WSL no está instalado", + "wsl.onboarding.wslNotInstalled.description": + "Se necesita WSL (Subsistema de Windows para Linux) para que OpenCode pueda añadir un servidor WSL", + "wsl.onboarding.wslUnavailable.title": "WSL no disponible", + "wsl.onboarding.wslUnavailable.description": "OpenCode no pudo comprobar WSL en este equipo.", + "wsl.onboarding.installWsl": "Instalar WSL", + "wsl.onboarding.windowsRestartRequired": + "Reinicia Windows para terminar de instalar WSL y, después, vuelve a abrir OpenCode.", + "wsl.onboarding.next": "Siguiente", + "wsl.onboarding.refresh": "Actualizar", + "wsl.onboarding.allDistrosAdded": "Ya se han añadido todas las distribuciones instaladas.", + "wsl.onboarding.noDistros": "Aún no se han detectado distribuciones.", + "wsl.onboarding.install": "Instalar", + "wsl.onboarding.installing": "Instalando...", + "wsl.onboarding.installDistro": "Instalar distribución", + "wsl.onboarding.searchDistros": "Buscar distribuciones", + "wsl.onboarding.wsl2Required": "Se necesita WSL 2.", + "wsl.onboarding.toolsRequired": "Esta distribución necesita bash y curl.", + "wsl.onboarding.openTerminal": "Abrir terminal", + "wsl.onboarding.path": "Ruta: {{path}}", + "wsl.onboarding.notFound": "no encontrado", + "wsl.onboarding.version": "Versión: {{version}}", + "wsl.onboarding.unknown": "desconocida", + "wsl.onboarding.desktopVersion": "escritorio {{version}}", + "wsl.onboarding.versionMismatch": "La versión instalada no coincide con la versión de la aplicación de escritorio.", + "wsl.onboarding.adding": "Añadiendo...", "dialog.project.edit.title": "Editar proyecto", "dialog.project.edit.name": "Nombre", @@ -405,6 +486,7 @@ export const dict = { "language.no": "Norsk", "language.br": "Português (Brasil)", "language.bs": "Bosanski", + "language.uk": "Українська", "language.th": "ไทย", "language.tr": "Türkçe", @@ -453,10 +535,12 @@ export const dict = { "error.page.title": "Algo salió mal", "error.page.description": "Ocurrió un error al cargar la aplicación.", + "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.exportLogs": "Exportar registros", "error.page.action.checking": "Comprobando...", "error.page.action.checkUpdates": "Buscar actualizaciones", "error.page.action.updateTo": "Actualizar a {{version}}", @@ -505,11 +589,31 @@ export const dict = { "home.recentProjects": "Proyectos recientes", "home.empty.title": "Sin proyectos recientes", "home.empty.description": "Empieza abriendo un proyecto local", + "home.title": "Inicio", + "home.projects": "Proyectos", + "home.project.add": "Añadir proyecto", + "home.recentlyClosed": "Proyectos cerrados recientemente", + "home.server.collapse": "Contraer proyectos del servidor", + "home.server.expand": "Expandir proyectos del servidor", + "home.sessions.search.placeholder": "Buscar sesiones", + "home.sessions.search.placeholder.scoped": "Buscar sesiones en {{scope}}", + "home.sessions.search.sessions": "Sesiones", + "home.sessions.search.noResults": "No se encontraron sesiones para {{query}}", + "home.sessions.empty": "Aún no hay nada", + "home.sessions.empty.description": "Crea una sesión para empezar", + "home.sessions.group.today": "Hoy", + "home.sessions.group.yesterday": "Ayer", + "home.sessions.group.older": "Anteriores", "session.tab.session": "Sesión", "session.tab.review": "Revisión", "session.tab.context": "Contexto", + "session.tab.unknown": "Sesión desconocida", "session.panel.reviewAndFiles": "Revisión y archivos", + "session.error.notFound": "No se encuentra esta sesión", + "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.change.one": "Cambio", "session.review.change.other": "Cambios", @@ -519,6 +623,8 @@ export const dict = { "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", + "session.review.noUncommittedChanges": "Aún no hay cambios sin confirmar", + "session.review.noBranchChanges": "Aún no hay cambios en la rama", "session.files.selectToOpen": "Selecciona un archivo para abrir", "session.files.all": "Todos los archivos", @@ -535,6 +641,10 @@ export const dict = { "session.todo.title": "Tareas", "session.todo.collapse": "Contraer", "session.todo.expand": "Expandir", + "session.question.minimize": "Minimizar pregunta", + "session.question.restore": "Restaurar pregunta", + "session.question.pending.one": "{{count}} pregunta pendiente", + "session.question.pending.other": "{{count}} preguntas pendientes", "session.followupDock.summary.one": "{{count}} mensaje en cola", "session.followupDock.summary.other": "{{count}} mensajes en cola", "session.followupDock.sendNow": "Enviar ahora", @@ -548,9 +658,16 @@ export const dict = { "session.revertDock.restore": "Restaurar mensaje", "session.new.title": "Construye lo que quieras", + "session.new.project.new": "Nuevo proyecto", + "session.new.project.search": "Buscar proyectos", + "session.new.project.add": "Añadir proyecto", "session.new.worktree.main": "Rama principal", "session.new.worktree.mainWithBranch": "Rama principal ({{branch}})", "session.new.worktree.create": "Crear nuevo árbol de trabajo", + "session.new.workspace.runIn": "Ejecutar sesión en", + "session.new.workspace.triggerLocal": "Local", + "session.new.workspace.local": "Repositorio local", + "session.new.workspace.existing": "Espacio de trabajo…", "session.new.lastModified": "Última modificación", "session.header.search.placeholder": "Buscar {{project}}", @@ -621,6 +738,8 @@ export const dict = { "sidebar.project.recentSessions": "Sesiones recientes", "sidebar.project.viewAllSessions": "Ver todas las sesiones", "sidebar.project.clearNotifications": "Borrar notificaciones", + "sidebar.empty.title": "No hay proyectos abiertos", + "sidebar.empty.description": "Abre un proyecto para empezar", "app.name.desktop": "OpenCode Desktop", @@ -633,6 +752,7 @@ export const dict = { "settings.desktop.wsl.description": "Ejecutar el servidor OpenCode dentro de WSL en Windows.", "settings.general.section.appearance": "Apariencia", + "settings.general.section.advanced": "Avanzado", "settings.general.section.notifications": "Notificaciones del sistema", "settings.general.section.updates": "Actualizaciones", "settings.general.section.sounds": "Efectos de sonido", @@ -641,6 +761,11 @@ 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.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", "settings.general.row.colorScheme.title": "Esquema de color", @@ -649,8 +774,8 @@ export const dict = { "settings.general.row.theme.description": "Personaliza el tema de OpenCode.", "settings.general.row.font.title": "Fuente de código", "settings.general.row.font.description": "Personaliza la fuente usada en bloques de código", - "settings.general.row.terminalFont.title": "Terminal Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "settings.general.row.terminalFont.title": "Fuente del terminal", + "settings.general.row.terminalFont.description": "Personaliza la fuente utilizada en el terminal", "settings.general.row.uiFont.title": "Fuente de la interfaz", "settings.general.row.uiFont.description": "Personaliza la fuente usada en toda la interfaz", "settings.general.row.followup.title": "Comportamiento de seguimiento", @@ -658,6 +783,23 @@ export const dict = { "Elige si los prompts de seguimiento se dirigen inmediatamente o esperan en una cola", "settings.general.row.followup.option.queue": "Cola", "settings.general.row.followup.option.steer": "Dirigir", + "settings.general.row.showFileTree.title": "Árbol de archivos", + "settings.general.row.showFileTree.description": "Mostrar el panel del árbol de archivos en las sesiones", + "settings.general.row.showNavigation.title": "Controles de navegación", + "settings.general.row.showNavigation.description": + "Mostrar los botones para retroceder y avanzar en la barra de título de la aplicación de escritorio", + "settings.general.row.showSearch.title": "Paleta de comandos", + "settings.general.row.showSearch.description": + "Mostrar el botón de búsqueda y paleta de comandos en la barra de título", + "settings.general.row.showTerminal.title": "Terminal", + "settings.general.row.showTerminal.description": "Mostrar el botón del terminal en la barra de título", + "settings.general.row.showStatus.title": "Estado del servidor", + "settings.general.row.showStatus.description": "Mostrar el botón de estado del servidor en la barra de título", + "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.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", @@ -667,6 +809,12 @@ export const dict = { "settings.general.row.editToolPartsExpanded.title": "Expandir partes de la herramienta de edición", "settings.general.row.editToolPartsExpanded.description": "Mostrar las partes de las herramientas de edición, escritura y parcheado expandidas por defecto en la línea de tiempo", + "settings.general.row.newLayoutDesigns.title": "Nuevo diseño y estilos", + "settings.general.row.newLayoutDesigns.description": + "Activar el nuevo diseño de la interfaz, la página de inicio, el editor y las sesiones", + "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", "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.tooltip": @@ -682,6 +830,8 @@ export const dict = { "settings.updates.row.check.description": "Buscar actualizaciones manualmente e instalarlas si hay alguna", "settings.updates.action.checkNow": "Buscar ahora", "settings.updates.action.checking": "Buscando...", + "settings.updates.action.downloading": "Descargando...", + "settings.updates.action.installing": "Instalando...", "settings.updates.toast.latest.title": "Estás al día", "settings.updates.toast.latest.description": "Estás usando la última versión de OpenCode.", "sound.option.none": "Ninguno", diff --git a/packages/app/src/i18n/fr.ts b/packages/app/src/i18n/fr.ts index 7ebd34e66ba..77a543180d2 100644 --- a/packages/app/src/i18n/fr.ts +++ b/packages/app/src/i18n/fr.ts @@ -21,6 +21,9 @@ export const dict = { "theme.scheme.dark": "Sombre", "command.sidebar.toggle": "Basculer la barre latérale", "command.project.open": "Ouvrir un projet", + "command.project.previous": "Projet précédent", + "command.project.next": "Projet suivant", + "command.project.index": "Passer au projet {{index}}", "command.provider.connect": "Connecter un fournisseur", "command.server.switch": "Changer de serveur", "command.settings.open": "Ouvrir les paramètres", @@ -39,6 +42,7 @@ export const dict = { "command.session.new": "Nouvelle session", "command.file.open": "Ouvrir un fichier", "command.tab.close": "Fermer l'onglet", + "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", @@ -193,6 +197,11 @@ export const dict = { "model.input.video": "vidéo", "model.input.pdf": "pdf", "model.tooltip.allows": "Autorise : {{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.none": "Sans raisonnement", "model.tooltip.context": "Limite de contexte {{limit}}", @@ -202,6 +211,7 @@ export const dict = { "common.loading": "Chargement", "common.loading.ellipsis": "...", "common.cancel": "Annuler", + "common.clear": "Effacer", "common.connect": "Connecter", "common.disconnect": "Déconnecter", "common.continue": "Soumettre", @@ -218,6 +228,8 @@ export const dict = { "prompt.mode.shell": "Shell", "prompt.mode.normal": "Prompt", "prompt.mode.shell.exit": "esc 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", "prompt.example.2": "Quelle est la pile technique de ce projet ?", "prompt.example.3": "Réparer les tests échoués", @@ -315,6 +327,75 @@ export const dict = { "dialog.server.menu.delete": "Supprimer", "dialog.server.current": "Serveur actuel", "dialog.server.status.default": "Défaut", + "wsl.server.add": "Ajouter un serveur WSL", + "wsl.server.addShort": "Ajouter WSL", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "Serveur WSL", + "wsl.server.retryStart": "Réessayer de démarrer", + "wsl.server.updating": "Mise à jour...", + "wsl.onboarding.step.distro": "Choisir une distribution", + "wsl.onboarding.step.opencode": "OpenCode", + "wsl.onboarding.checkingRuntime": "Vérification de WSL...", + "wsl.onboarding.restartRequired": "Windows doit redémarrer pour terminer l'installation de WSL.", + "wsl.onboarding.ready": "WSL est prêt.", + "wsl.onboarding.required": "WSL est requis pour continuer.", + "wsl.onboarding.checkingDistros": "Vérification des distributions...", + "wsl.onboarding.installingDistro": "Installation de {{distro}}...", + "wsl.onboarding.checkingDistro": "Vérification de {{distro}}...", + "wsl.onboarding.listingDistros": "Récupération de la liste des distributions...", + "wsl.onboarding.distroReady": "{{distro}} est prête.", + "wsl.onboarding.distroNotInstalled": "{{distro}} n'est pas encore installée.", + "wsl.onboarding.openDistroOnce": "Ouvrez {{distro}} une fois pour terminer la configuration.", + "wsl.onboarding.finishingDistro": "Finalisation de la configuration de {{distro}}.", + "wsl.onboarding.pickDistro": "Choisissez une distribution ou installez-en une ci-dessous.", + "wsl.onboarding.checkingOpencode": "Vérification d'OpenCode...", + "wsl.onboarding.checkingOpencodeIn": "Vérification d'OpenCode dans {{distro}}...", + "wsl.onboarding.updatingOpencode": "Mise à jour d'OpenCode...", + "wsl.onboarding.updatingOpencodeIn": "Mise à jour d'OpenCode dans {{distro}}...", + "wsl.onboarding.updateOpencodeIn": "Mettez à jour OpenCode dans {{distro}}.", + "wsl.onboarding.updateOpencode": "Mettre à jour OpenCode", + "wsl.onboarding.opencodeReadyIn": "OpenCode est prêt dans {{distro}}.", + "wsl.onboarding.opencodeReady": "OpenCode est prêt.", + "wsl.onboarding.installOpencodeIn": "Installez OpenCode dans {{distro}}.", + "wsl.onboarding.installOpencode": "Installer OpenCode", + "wsl.onboarding.chooseDistroFirst": "Choisissez d'abord une distribution.", + "wsl.onboarding.loadFailed": "Impossible de charger l'état de WSL.", + "wsl.onboarding.loading": "Chargement...", + "wsl.onboarding.installedDistros": "Distributions installées", + "wsl.onboarding.checkAgain": "Vérifier à nouveau", + "wsl.onboarding.distroStatus.ready": "Prête", + "wsl.onboarding.distroStatus.checking": "Vérification...", + "wsl.onboarding.distroStatus.opencodeMissing": "OpenCode non installé", + "wsl.onboarding.distroStatus.missingTools": "bash et curl manquants", + "wsl.onboarding.distroStatus.unsupported": "Non prise en charge · Utilisez WSL 2", + "wsl.onboarding.needAnotherDistro": "Besoin d'une autre distribution ?", + "wsl.onboarding.needAnotherDistroHint": "Installez une distribution Linux depuis le catalogue WSL", + "wsl.onboarding.wslNotInstalled.title": "WSL n'est pas installé", + "wsl.onboarding.wslNotInstalled.description": + "WSL (Windows Subsystem for Linux) est requis avant qu'OpenCode puisse ajouter un serveur WSL", + "wsl.onboarding.wslUnavailable.title": "WSL indisponible", + "wsl.onboarding.wslUnavailable.description": "OpenCode n'a pas pu vérifier WSL sur cet appareil.", + "wsl.onboarding.installWsl": "Installer WSL", + "wsl.onboarding.windowsRestartRequired": + "Redémarrez Windows pour terminer l'installation de WSL, puis rouvrez OpenCode.", + "wsl.onboarding.next": "Suivant", + "wsl.onboarding.refresh": "Actualiser", + "wsl.onboarding.allDistrosAdded": "Toutes les distributions installées ont déjà été ajoutées.", + "wsl.onboarding.noDistros": "Aucune distribution détectée pour l'instant.", + "wsl.onboarding.install": "Installer", + "wsl.onboarding.installing": "Installation...", + "wsl.onboarding.installDistro": "Installer une distribution", + "wsl.onboarding.searchDistros": "Rechercher des distributions", + "wsl.onboarding.wsl2Required": "WSL 2 est requis.", + "wsl.onboarding.toolsRequired": "Cette distribution nécessite bash et curl.", + "wsl.onboarding.openTerminal": "Ouvrir le terminal", + "wsl.onboarding.path": "Chemin : {{path}}", + "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.adding": "Ajout...", "dialog.project.edit.title": "Modifier le projet", "dialog.project.edit.name": "Nom", "dialog.project.edit.icon": "Icône", @@ -373,6 +454,7 @@ export const dict = { "language.no": "Norsk", "language.br": "Português (Brasil)", "language.bs": "Bosanski", + "language.uk": "Українська", "language.th": "ไทย", "language.tr": "Türkçe", "toast.language.title": "Langue", @@ -410,10 +492,12 @@ export const dict = { "toast.update.action.notYet": "Pas encore", "error.page.title": "Quelque chose s'est mal passé", "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", "error.page.action.restart": "Redémarrer", "error.page.action.report": "Signaler l'erreur", "error.page.action.reported": "Erreur signalée", + "error.page.action.exportLogs": "Exporter les journaux", "error.page.action.checking": "Vérification...", "error.page.action.checkUpdates": "Vérifier les mises à jour", "error.page.action.updateTo": "Mettre à jour vers {{version}}", @@ -458,16 +542,38 @@ export const dict = { "home.recentProjects": "Projets récents", "home.empty.title": "Aucun projet récent", "home.empty.description": "Commencez par ouvrir un projet local", + "home.title": "Accueil", + "home.projects": "Projets", + "home.project.add": "Ajouter un projet", + "home.recentlyClosed": "Récemment fermés", + "home.server.collapse": "Réduire les projets du serveur", + "home.server.expand": "Développer les projets du serveur", + "home.sessions.search.placeholder": "Rechercher des sessions", + "home.sessions.search.placeholder.scoped": "Rechercher les sessions dans {{scope}}", + "home.sessions.search.sessions": "Sessions", + "home.sessions.search.noResults": "Aucune session trouvée pour {{query}}", + "home.sessions.empty": "Rien ici pour l'instant", + "home.sessions.empty.description": "Créez une session pour commencer", + "home.sessions.group.today": "Aujourd'hui", + "home.sessions.group.yesterday": "Hier", + "home.sessions.group.older": "Plus anciennes", "session.tab.session": "Session", "session.tab.review": "Revue", "session.tab.context": "Contexte", + "session.tab.unknown": "Session inconnue", "session.panel.reviewAndFiles": "Revue et fichiers", + "session.error.notFound": "Cette session est introuvable", + "session.error.notFound.description": "Cet onglet pointe vers une session qui n'existe plus sur ce serveur.", + "session.error.notFound.closeTab": "Fermer l'onglet", + "session.error.serverConnection": "Impossible de se connecter à ce serveur", "session.review.filesChanged": "{{count}} fichiers modifiés", "session.review.change.one": "Modification", "session.review.change.other": "Modifications", "session.review.loadingChanges": "Chargement des modifications...", "session.review.empty": "Aucune modification dans cette session pour l'instant", "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.noSnapshot": "Le suivi des instantanés est désactivé dans la configuration, les modifications de session sont donc indisponibles", @@ -484,6 +590,10 @@ export const dict = { "session.todo.title": "Tâches", "session.todo.collapse": "Réduire", "session.todo.expand": "Développer", + "session.question.minimize": "Réduire la question", + "session.question.restore": "Restaurer la question", + "session.question.pending.one": "{{count}} question en attente", + "session.question.pending.other": "{{count}} questions en attente", "session.followupDock.summary.one": "{{count}} message en file d'attente", "session.followupDock.summary.other": "{{count}} messages en file d'attente", "session.followupDock.sendNow": "Envoyer maintenant", @@ -496,9 +606,16 @@ export const dict = { "session.revertDock.expand": "Développer les messages annulés", "session.revertDock.restore": "Restaurer le message", "session.new.title": "Créez ce que vous voulez", + "session.new.project.new": "Nouveau projet", + "session.new.project.search": "Rechercher des projets", + "session.new.project.add": "Ajouter un projet", "session.new.worktree.main": "Branche principale", "session.new.worktree.mainWithBranch": "Branche principale ({{branch}})", "session.new.worktree.create": "Créer un nouvel arbre de travail", + "session.new.workspace.runIn": "Exécuter la session dans", + "session.new.workspace.triggerLocal": "Local", + "session.new.workspace.local": "Dépôt local", + "session.new.workspace.existing": "Espace de travail…", "session.new.lastModified": "Dernière modification", "session.header.search.placeholder": "Rechercher {{project}}", "session.header.searchFiles": "Rechercher des fichiers", @@ -564,6 +681,8 @@ export const dict = { "sidebar.project.recentSessions": "Sessions récentes", "sidebar.project.viewAllSessions": "Voir toutes les sessions", "sidebar.project.clearNotifications": "Effacer les notifications", + "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.server": "Serveur", @@ -573,6 +692,7 @@ export const dict = { "settings.desktop.wsl.title": "Intégration WSL", "settings.desktop.wsl.description": "Exécuter le serveur OpenCode dans WSL sur Windows.", "settings.general.section.appearance": "Apparence", + "settings.general.section.advanced": "Avancé", "settings.general.section.notifications": "Notifications système", "settings.general.section.updates": "Mises à jour", "settings.general.section.sounds": "Effets sonores", @@ -580,6 +700,11 @@ 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.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.terminalOnly": "terminal uniquement", "settings.general.row.appearance.title": "Apparence", "settings.general.row.appearance.description": "Personnaliser l'apparence d'OpenCode sur votre appareil", "settings.general.row.colorScheme.title": "Schéma de couleurs", @@ -588,8 +713,8 @@ export const dict = { "settings.general.row.theme.description": "Personnaliser le thème d'OpenCode.", "settings.general.row.font.title": "Police de code", "settings.general.row.font.description": "Personnaliser la police utilisée dans les blocs de code", - "settings.general.row.terminalFont.title": "Terminal Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "settings.general.row.terminalFont.title": "Police du terminal", + "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", @@ -597,6 +722,24 @@ export const dict = { "Choisissez si les messages de suivi dirigent immédiatement ou attendent dans une file d'attente", "settings.general.row.followup.option.queue": "File d'attente", "settings.general.row.followup.option.steer": "Diriger", + "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", + "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", + "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", + "settings.general.row.mobileTitlebarBottom.description": + "Placer la barre de titre et les onglets de session en bas de l'écran sur mobile", + "settings.general.row.showCustomAgents.title": "Agents personnalisés", + "settings.general.row.showCustomAgents.description": "Afficher le sélecteur d'agent dans la zone de saisie", "settings.general.row.reasoningSummaries.title": "Afficher les résumés de raisonnement", "settings.general.row.reasoningSummaries.description": "Afficher les résumés de raisonnement du modèle dans la chronologie", @@ -606,6 +749,12 @@ export const dict = { "settings.general.row.editToolPartsExpanded.title": "Développer les parties de l'outil edit", "settings.general.row.editToolPartsExpanded.description": "Afficher les parties des outils edit, write et patch développées par défaut dans la chronologie", + "settings.general.row.newLayoutDesigns.title": "Nouvelle mise en page et nouveaux designs", + "settings.general.row.newLayoutDesigns.description": + "Activer la nouvelle mise en page et les nouvelles interfaces d'accueil, de saisie et de session", + "settings.general.row.pinchZoom.title": "Pincer pour zoomer", + "settings.general.row.pinchZoom.description": + "Autoriser les gestes de pincement du pavé tactile et Ctrl-défilement pour zoomer", "settings.general.row.wayland.title": "Utiliser Wayland natif", "settings.general.row.wayland.description": "Désactiver le repli X11 sur Wayland. Nécessite un redémarrage.", "settings.general.row.wayland.tooltip": @@ -618,6 +767,8 @@ export const dict = { "settings.updates.row.check.description": "Vérifier manuellement les mises à jour et installer si disponible", "settings.updates.action.checkNow": "Vérifier maintenant", "settings.updates.action.checking": "Vérification...", + "settings.updates.action.downloading": "Téléchargement...", + "settings.updates.action.installing": "Installation...", "settings.updates.toast.latest.title": "Vous êtes à jour", "settings.updates.toast.latest.description": "Vous utilisez la dernière version d'OpenCode.", "sound.option.none": "Aucun", diff --git a/packages/app/src/i18n/ja.ts b/packages/app/src/i18n/ja.ts index ad5dcf5387a..24d1a29e8a2 100644 --- a/packages/app/src/i18n/ja.ts +++ b/packages/app/src/i18n/ja.ts @@ -21,6 +21,9 @@ export const dict = { "theme.scheme.dark": "ダーク", "command.sidebar.toggle": "サイドバーの切り替え", "command.project.open": "プロジェクトを開く", + "command.project.previous": "前のプロジェクト", + "command.project.next": "次のプロジェクト", + "command.project.index": "プロジェクト{{index}}に切り替え", "command.provider.connect": "プロバイダーに接続", "command.server.switch": "サーバーの切り替え", "command.settings.open": "設定を開く", @@ -39,6 +42,7 @@ export const dict = { "command.session.new": "新しいセッション", "command.file.open": "ファイルを開く", "command.tab.close": "タブを閉じる", + "command.tab.reopenClosed": "閉じたタブを再度開く", "command.context.addSelection": "選択範囲をコンテキストに追加", "command.context.addSelection.description": "現在のファイルから選択した行を追加", "command.input.focus": "入力欄にフォーカス", @@ -149,7 +153,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": "My AI Provider", + "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キー", @@ -192,6 +196,11 @@ export const dict = { "model.input.video": "動画", "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.context": "コンテキスト上限 {{limit}}", @@ -201,6 +210,7 @@ export const dict = { "common.loading": "読み込み中", "common.loading.ellipsis": "...", "common.cancel": "キャンセル", + "common.clear": "クリア", "common.connect": "接続", "common.disconnect": "切断", "common.continue": "送信", @@ -217,6 +227,8 @@ export const dict = { "prompt.mode.shell": "シェル", "prompt.mode.normal": "プロンプト", "prompt.mode.shell.exit": "escで終了", + "session.child.promptDisabled": "サブエージェントのセッションにはプロンプトを送信できません。", + "session.child.backToParent": "メインセッションに戻る。", "prompt.example.1": "コードベースのTODOを修正", "prompt.example.2": "このプロジェクトの技術スタックは何ですか?", "prompt.example.3": "壊れたテストを修正", @@ -313,6 +325,75 @@ export const dict = { "dialog.server.menu.delete": "削除", "dialog.server.current": "現在のサーバー", "dialog.server.status.default": "デフォルト", + "wsl.server.add": "WSLサーバーを追加", + "wsl.server.addShort": "WSLを追加", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "WSLサーバー", + "wsl.server.retryStart": "起動を再試行", + "wsl.server.updating": "更新中...", + "wsl.onboarding.step.distro": "ディストリビューションを選択", + "wsl.onboarding.step.opencode": "OpenCode", + "wsl.onboarding.checkingRuntime": "WSLを確認中...", + "wsl.onboarding.restartRequired": "WSLのインストールを完了するにはWindowsの再起動が必要です。", + "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.checkingOpencode": "OpenCodeを確認中...", + "wsl.onboarding.checkingOpencodeIn": "{{distro}}内のOpenCodeを確認中...", + "wsl.onboarding.updatingOpencode": "OpenCodeを更新中...", + "wsl.onboarding.updatingOpencodeIn": "{{distro}}内のOpenCodeを更新中...", + "wsl.onboarding.updateOpencodeIn": "{{distro}}内のOpenCodeを更新してください。", + "wsl.onboarding.updateOpencode": "OpenCodeを更新", + "wsl.onboarding.opencodeReadyIn": "{{distro}}内のOpenCodeの準備ができました。", + "wsl.onboarding.opencodeReady": "OpenCodeの準備ができました。", + "wsl.onboarding.installOpencodeIn": "{{distro}}にOpenCodeをインストールしてください。", + "wsl.onboarding.installOpencode": "OpenCodeをインストール", + "wsl.onboarding.chooseDistroFirst": "先にディストリビューションを選択してください。", + "wsl.onboarding.loadFailed": "WSLの状態を読み込めませんでした。", + "wsl.onboarding.loading": "読み込み中...", + "wsl.onboarding.installedDistros": "インストール済みのディストリビューション", + "wsl.onboarding.checkAgain": "再確認", + "wsl.onboarding.distroStatus.ready": "準備完了", + "wsl.onboarding.distroStatus.checking": "確認中...", + "wsl.onboarding.distroStatus.opencodeMissing": "OpenCodeがインストールされていません", + "wsl.onboarding.distroStatus.missingTools": "bash、curlがありません", + "wsl.onboarding.distroStatus.unsupported": "非対応 · WSL 2を使用してください", + "wsl.onboarding.needAnotherDistro": "別のディストリビューションが必要ですか?", + "wsl.onboarding.needAnotherDistroHint": "WSLカタログからLinuxディストリビューションをインストール", + "wsl.onboarding.wslNotInstalled.title": "WSLがインストールされていません", + "wsl.onboarding.wslNotInstalled.description": + "OpenCodeでWSLサーバーを追加するには、WSL (Windows Subsystem for Linux) が必要です", + "wsl.onboarding.wslUnavailable.title": "WSLを利用できません", + "wsl.onboarding.wslUnavailable.description": "このマシンのWSLを確認できませんでした。", + "wsl.onboarding.installWsl": "WSLをインストール", + "wsl.onboarding.windowsRestartRequired": + "WSLのインストールを完了するにはWindowsを再起動し、OpenCodeをもう一度開いてください。", + "wsl.onboarding.next": "次へ", + "wsl.onboarding.refresh": "更新", + "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.openTerminal": "ターミナルを開く", + "wsl.onboarding.path": "パス: {{path}}", + "wsl.onboarding.notFound": "見つかりません", + "wsl.onboarding.version": "バージョン: {{version}}", + "wsl.onboarding.unknown": "不明", + "wsl.onboarding.desktopVersion": "デスクトップ {{version}}", + "wsl.onboarding.versionMismatch": "インストールされているバージョンがデスクトップアプリのバージョンと一致しません。", + "wsl.onboarding.adding": "追加中...", "dialog.project.edit.title": "プロジェクトを編集", "dialog.project.edit.name": "名前", "dialog.project.edit.icon": "アイコン", @@ -370,6 +451,7 @@ export const dict = { "language.no": "Norsk", "language.br": "Português (Brasil)", "language.bs": "Bosanski", + "language.uk": "Українська", "language.th": "ไทย", "language.tr": "Türkçe", "toast.language.title": "言語", @@ -406,10 +488,12 @@ export const dict = { "toast.update.action.notYet": "今はしない", "error.page.title": "問題が発生しました", "error.page.description": "アプリケーションの読み込み中にエラーが発生しました。", + "error.page.description.localServerStartup": "ローカルサーバーの起動中にエラーが発生しました。", "error.page.details.label": "エラー詳細", "error.page.action.restart": "再起動", "error.page.action.report": "エラーを報告", "error.page.action.reported": "エラーを報告しました", + "error.page.action.exportLogs": "ログをエクスポート", "error.page.action.checking": "確認中...", "error.page.action.checkUpdates": "アップデートを確認", "error.page.action.updateTo": "{{version}}にアップデート", @@ -451,10 +535,30 @@ export const dict = { "home.recentProjects": "最近のプロジェクト", "home.empty.title": "最近のプロジェクトはありません", "home.empty.description": "ローカルプロジェクトを開いて始めましょう", + "home.title": "ホーム", + "home.projects": "プロジェクト", + "home.project.add": "プロジェクトを追加", + "home.recentlyClosed": "最近閉じたプロジェクト", + "home.server.collapse": "サーバーのプロジェクトを折りたたむ", + "home.server.expand": "サーバーのプロジェクトを展開", + "home.sessions.search.placeholder": "セッションを検索", + "home.sessions.search.placeholder.scoped": "{{scope}}のセッションを検索", + "home.sessions.search.sessions": "セッション", + "home.sessions.search.noResults": "{{query}}に一致するセッションが見つかりません", + "home.sessions.empty": "まだ何もありません", + "home.sessions.empty.description": "セッションを作成して始めましょう", + "home.sessions.group.today": "今日", + "home.sessions.group.yesterday": "昨日", + "home.sessions.group.older": "それ以前", "session.tab.session": "セッション", "session.tab.review": "レビュー", "session.tab.context": "コンテキスト", + "session.tab.unknown": "不明なセッション", "session.panel.reviewAndFiles": "レビューとファイル", + "session.error.notFound": "このセッションが見つかりません", + "session.error.notFound.description": "このタブが参照するセッションは、このサーバーには存在しません。", + "session.error.notFound.closeTab": "タブを閉じる", + "session.error.serverConnection": "このサーバーに接続できません", "session.review.filesChanged": "{{count}} ファイル変更", "session.review.change.one": "変更", "session.review.change.other": "変更", @@ -463,6 +567,8 @@ export const dict = { "session.review.noVcs": "Gitバージョン管理システムが検出されないため、変更は表示されません", "session.review.noSnapshot": "設定でスナップショット追跡が無効になっているため、セッションの変更は利用できません", "session.review.noChanges": "変更なし", + "session.review.noUncommittedChanges": "コミットされていない変更はまだありません", + "session.review.noBranchChanges": "ブランチの変更はまだありません", "session.files.selectToOpen": "開くファイルを選択", "session.files.all": "すべてのファイル", "session.files.empty": "ファイルなし", @@ -476,6 +582,10 @@ export const dict = { "session.todo.title": "ToDo", "session.todo.collapse": "折りたたむ", "session.todo.expand": "展開", + "session.question.minimize": "質問を最小化", + "session.question.restore": "質問を復元", + "session.question.pending.one": "{{count}}件の保留中の質問", + "session.question.pending.other": "{{count}}件の保留中の質問", "session.followupDock.summary.one": "{{count}} 件のメッセージが待機中", "session.followupDock.summary.other": "{{count}} 件のメッセージが待機中", "session.followupDock.sendNow": "今すぐ送信", @@ -488,9 +598,16 @@ export const dict = { "session.revertDock.expand": "ロールバックされたメッセージを展開", "session.revertDock.restore": "メッセージを復元", "session.new.title": "何でも作る", + "session.new.project.new": "新しいプロジェクト", + "session.new.project.search": "プロジェクトを検索", + "session.new.project.add": "プロジェクトを追加", "session.new.worktree.main": "メインブランチ", "session.new.worktree.mainWithBranch": "メインブランチ ({{branch}})", "session.new.worktree.create": "新しいワークツリーを作成", + "session.new.workspace.runIn": "セッションの実行先", + "session.new.workspace.triggerLocal": "ローカル", + "session.new.workspace.local": "ローカルリポジトリ", + "session.new.workspace.existing": "ワークスペース…", "session.new.lastModified": "最終更新", "session.header.search.placeholder": "{{project}}を検索", "session.header.searchFiles": "ファイルを検索", @@ -554,6 +671,8 @@ export const dict = { "sidebar.project.recentSessions": "最近のセッション", "sidebar.project.viewAllSessions": "すべてのセッションを表示", "sidebar.project.clearNotifications": "通知をクリア", + "sidebar.empty.title": "開いているプロジェクトはありません", + "sidebar.empty.description": "プロジェクトを開いて始めましょう", "app.name.desktop": "OpenCode Desktop", "settings.section.desktop": "デスクトップ", "settings.section.server": "サーバー", @@ -563,6 +682,7 @@ export const dict = { "settings.desktop.wsl.title": "WSL連携", "settings.desktop.wsl.description": "WindowsのWSL環境でOpenCodeサーバーを実行します。", "settings.general.section.appearance": "外観", + "settings.general.section.advanced": "詳細設定", "settings.general.section.notifications": "システム通知", "settings.general.section.updates": "アップデート", "settings.general.section.sounds": "効果音", @@ -570,6 +690,11 @@ export const dict = { "settings.general.section.display": "ディスプレイ", "settings.general.row.language.title": "言語", "settings.general.row.language.description": "OpenCodeの表示言語を変更します", + "settings.general.row.shell.title": "ターミナルシェル", + "settings.general.row.shell.description": + "ターミナルで使用するシェルを選択します。互換性のあるシェルはエージェントのツール呼び出しにも使用されます。", + "settings.general.row.shell.autoDefault": "自動 (デフォルト)", + "settings.general.row.shell.terminalOnly": "ターミナルのみ", "settings.general.row.appearance.title": "外観", "settings.general.row.appearance.description": "デバイスでのOpenCodeの表示をカスタマイズします", "settings.general.row.colorScheme.title": "配色", @@ -578,8 +703,8 @@ export const dict = { "settings.general.row.theme.description": "OpenCodeのテーマをカスタマイズします。", "settings.general.row.font.title": "コードフォント", "settings.general.row.font.description": "コードブロックで使用するフォントをカスタマイズします", - "settings.general.row.terminalFont.title": "Terminal Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "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": "フォローアップの動作", @@ -587,6 +712,21 @@ export const dict = { "フォローアッププロンプトを即座に実行するか、キューで待機させるかを選択します", "settings.general.row.followup.option.queue": "キューに追加", "settings.general.row.followup.option.steer": "即座に実行 (Steer)", + "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": "コマンドパレット", + "settings.general.row.showSearch.description": "タイトルバーに検索とコマンドパレットのボタンを表示します", + "settings.general.row.showTerminal.title": "ターミナル", + "settings.general.row.showTerminal.description": "デスクトップのタイトルバーにターミナルボタンを表示します", + "settings.general.row.showStatus.title": "サーバーステータス", + "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.reasoningSummaries.title": "推論の要約を表示", "settings.general.row.reasoningSummaries.description": "タイムラインにモデルの推論の要約を表示します", "settings.general.row.shellToolPartsExpanded.title": "shell ツールパーツを展開", @@ -595,6 +735,12 @@ export const dict = { "settings.general.row.editToolPartsExpanded.title": "edit ツールパーツを展開", "settings.general.row.editToolPartsExpanded.description": "タイムラインで edit、write、patch ツールパーツをデフォルトで展開して表示します", + "settings.general.row.newLayoutDesigns.title": "新しいレイアウトとデザイン", + "settings.general.row.newLayoutDesigns.description": + "刷新されたレイアウト、ホーム、コンポーザー、セッションUIを有効にします", + "settings.general.row.pinchZoom.title": "ピンチでズーム", + "settings.general.row.pinchZoom.description": + "トラックパッドのピンチ操作とCtrl+スクロール操作によるズームを許可します", "settings.general.row.wayland.title": "ネイティブWaylandを使用", "settings.general.row.wayland.description": "WaylandでのX11フォールバックを無効にします。再起動が必要です。", "settings.general.row.wayland.tooltip": @@ -607,6 +753,8 @@ export const dict = { "settings.updates.row.check.description": "手動でアップデートを確認し、利用可能ならインストールします", "settings.updates.action.checkNow": "今すぐ確認", "settings.updates.action.checking": "確認中...", + "settings.updates.action.downloading": "ダウンロード中...", + "settings.updates.action.installing": "インストール中...", "settings.updates.toast.latest.title": "最新です", "settings.updates.toast.latest.description": "OpenCode は最新バージョンです。", "sound.option.none": "なし", diff --git a/packages/app/src/i18n/ko.ts b/packages/app/src/i18n/ko.ts index 15f1f28013e..cf789f5644b 100644 --- a/packages/app/src/i18n/ko.ts +++ b/packages/app/src/i18n/ko.ts @@ -575,8 +575,8 @@ export const dict = { "settings.general.row.theme.description": "OpenCode 테마 사용자 지정", "settings.general.row.font.title": "코드 글꼴", "settings.general.row.font.description": "코드 블록에 사용되는 글꼴을 사용자 지정", - "settings.general.row.terminalFont.title": "Terminal Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "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": "후속 조치 동작", @@ -848,4 +848,155 @@ export const dict = { "error.childStore.persistedProjectIconCreateFailed": "영구 프로젝트 아이콘 생성 실패", "error.childStore.storeCreateFailed": "저장소 생성 실패", "terminal.connectionLost.abnormalClose": "WebSocket이 비정상적으로 닫힘: {{code}}", + + "command.project.previous": "이전 프로젝트", + "command.project.next": "다음 프로젝트", + "command.project.index": "{{index}}번 프로젝트로 전환", + "command.tab.reopenClosed": "닫은 탭 다시 열기", + "model.tooltip.context.label": "컨텍스트", + "model.tooltip.inputs": "입력", + "model.tooltip.model": "모델", + "model.tooltip.provider": "공급자", + "model.tooltip.reasoning": "추론", + "common.clear": "지우기", + "session.child.promptDisabled": "하위 에이전트 세션에는 프롬프트를 입력할 수 없습니다.", + "session.child.backToParent": "메인 세션으로 돌아가기.", + + "wsl.server.add": "WSL 서버 추가", + "wsl.server.addShort": "WSL 추가", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "WSL 서버", + "wsl.server.retryStart": "시작 재시도", + "wsl.server.updating": "업데이트 중...", + "wsl.onboarding.step.distro": "배포판 선택", + "wsl.onboarding.step.opencode": "OpenCode", + "wsl.onboarding.checkingRuntime": "WSL 확인 중...", + "wsl.onboarding.restartRequired": "WSL 설치를 완료하려면 Windows를 다시 시작해야 합니다.", + "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.checkingOpencode": "OpenCode 확인 중...", + "wsl.onboarding.checkingOpencodeIn": "{{distro}}에서 OpenCode 확인 중...", + "wsl.onboarding.updatingOpencode": "OpenCode 업데이트 중...", + "wsl.onboarding.updatingOpencodeIn": "{{distro}}에서 OpenCode 업데이트 중...", + "wsl.onboarding.updateOpencodeIn": "{{distro}}에서 OpenCode를 업데이트하세요.", + "wsl.onboarding.updateOpencode": "OpenCode 업데이트", + "wsl.onboarding.opencodeReadyIn": "{{distro}}에서 OpenCode를 사용할 준비가 되었습니다.", + "wsl.onboarding.opencodeReady": "OpenCode가 준비되었습니다.", + "wsl.onboarding.installOpencodeIn": "{{distro}}에 OpenCode를 설치하세요.", + "wsl.onboarding.installOpencode": "OpenCode 설치", + "wsl.onboarding.chooseDistroFirst": "먼저 배포판을 선택하세요.", + "wsl.onboarding.loadFailed": "WSL 상태를 불러오지 못했습니다.", + "wsl.onboarding.loading": "로딩 중...", + "wsl.onboarding.installedDistros": "설치된 배포판", + "wsl.onboarding.checkAgain": "다시 확인", + "wsl.onboarding.distroStatus.ready": "준비됨", + "wsl.onboarding.distroStatus.checking": "확인 중...", + "wsl.onboarding.distroStatus.opencodeMissing": "OpenCode가 설치되지 않음", + "wsl.onboarding.distroStatus.missingTools": "bash, curl 없음", + "wsl.onboarding.distroStatus.unsupported": "지원되지 않음 · WSL 2 사용", + "wsl.onboarding.needAnotherDistro": "다른 배포판이 필요하신가요?", + "wsl.onboarding.needAnotherDistroHint": "WSL 카탈로그에서 Linux 배포판을 설치하세요", + "wsl.onboarding.wslNotInstalled.title": "WSL이 설치되지 않음", + "wsl.onboarding.wslNotInstalled.description": + "OpenCode에서 WSL 서버를 추가하려면 WSL (Windows Subsystem for Linux)이 필요합니다", + "wsl.onboarding.wslUnavailable.title": "WSL을 사용할 수 없음", + "wsl.onboarding.wslUnavailable.description": "OpenCode에서 이 컴퓨터의 WSL을 확인할 수 없습니다.", + "wsl.onboarding.installWsl": "WSL 설치", + "wsl.onboarding.windowsRestartRequired": "WSL 설치를 완료하려면 Windows를 다시 시작한 다음 OpenCode를 다시 여세요.", + "wsl.onboarding.next": "다음", + "wsl.onboarding.refresh": "새로 고침", + "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.openTerminal": "터미널 열기", + "wsl.onboarding.path": "경로: {{path}}", + "wsl.onboarding.notFound": "찾을 수 없음", + "wsl.onboarding.version": "버전: {{version}}", + "wsl.onboarding.unknown": "알 수 없음", + "wsl.onboarding.desktopVersion": "데스크톱 {{version}}", + "wsl.onboarding.versionMismatch": "설치된 버전이 데스크톱 앱 버전과 일치하지 않습니다.", + "wsl.onboarding.adding": "추가 중...", + + "language.uk": "Українська", + "error.page.description.localServerStartup": "로컬 서버를 시작하는 동안 오류가 발생했습니다.", + "error.page.action.exportLogs": "로그 내보내기", + + "home.title": "홈", + "home.projects": "프로젝트", + "home.project.add": "프로젝트 추가", + "home.recentlyClosed": "최근에 닫은 항목", + "home.server.collapse": "서버 프로젝트 접기", + "home.server.expand": "서버 프로젝트 펼치기", + "home.sessions.search.placeholder": "세션 검색", + "home.sessions.search.placeholder.scoped": "{{scope}}에서 세션 검색", + "home.sessions.search.sessions": "세션", + "home.sessions.search.noResults": "{{query}}에 해당하는 세션을 찾을 수 없습니다", + "home.sessions.empty": "아직 아무것도 없습니다", + "home.sessions.empty.description": "세션을 생성하여 시작하세요", + "home.sessions.group.today": "오늘", + "home.sessions.group.yesterday": "어제", + "home.sessions.group.older": "이전", + + "session.tab.unknown": "알 수 없는 세션", + "session.error.notFound": "이 세션을 찾을 수 없습니다", + "session.error.notFound.description": "이 탭은 이 서버에 더 이상 존재하지 않는 세션을 가리킵니다.", + "session.error.notFound.closeTab": "탭 닫기", + "session.error.serverConnection": "이 서버에 연결할 수 없습니다", + "session.review.noUncommittedChanges": "아직 커밋되지 않은 변경 사항이 없습니다", + "session.review.noBranchChanges": "아직 브랜치 변경 사항이 없습니다", + "session.question.minimize": "질문 최소화", + "session.question.restore": "질문 복원", + "session.question.pending.one": "{{count}}개의 대기 중인 질문", + "session.question.pending.other": "{{count}}개의 대기 중인 질문", + "session.new.project.new": "새 프로젝트", + "session.new.project.search": "프로젝트 검색", + "session.new.project.add": "프로젝트 추가", + "session.new.workspace.runIn": "세션 실행 위치", + "session.new.workspace.triggerLocal": "로컬", + "session.new.workspace.local": "로컬 저장소", + "session.new.workspace.existing": "작업 공간…", + + "sidebar.empty.title": "열린 프로젝트 없음", + "sidebar.empty.description": "프로젝트를 열어 시작하세요", + + "settings.general.section.advanced": "고급", + "settings.general.row.shell.title": "터미널 셸", + "settings.general.row.shell.description": + "터미널에서 사용할 셸을 선택하세요. 호환되는 셸은 에이전트 도구 호출에도 사용됩니다.", + "settings.general.row.shell.autoDefault": "자동 (기본값)", + "settings.general.row.shell.terminalOnly": "터미널 전용", + "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": "명령 팔레트", + "settings.general.row.showSearch.description": "제목 표시줄에 검색 및 명령 팔레트 버튼 표시", + "settings.general.row.showTerminal.title": "터미널", + "settings.general.row.showTerminal.description": "데스크톱 제목 표시줄에 터미널 버튼 표시", + "settings.general.row.showStatus.title": "서버 상태", + "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.newLayoutDesigns.title": "새 레이아웃 및 디자인", + "settings.general.row.newLayoutDesigns.description": "새롭게 디자인된 레이아웃, 홈, 입력창 및 세션 UI 활성화", + "settings.general.row.pinchZoom.title": "핀치 줌", + "settings.general.row.pinchZoom.description": "트랙패드 핀치 및 Ctrl-스크롤 제스처로 확대/축소 허용", + "settings.updates.action.downloading": "다운로드 중...", + "settings.updates.action.installing": "설치 중...", } diff --git a/packages/app/src/i18n/no.ts b/packages/app/src/i18n/no.ts index 8ec11de192a..f3faa313829 100644 --- a/packages/app/src/i18n/no.ts +++ b/packages/app/src/i18n/no.ts @@ -77,7 +77,7 @@ export const dict = { "command.permissions.autoaccept.enable": "Aksepter tillatelser automatisk", "command.permissions.autoaccept.disable": "Stopp automatisk akseptering av tillatelser", "command.workspace.toggle": "Veksle arbeidsområder", - "command.workspace.toggle.description": "Enable or disable multiple workspaces in the sidebar", + "command.workspace.toggle.description": "Aktiver eller deaktiver flere arbeidsområder i sidefeltet", "command.session.undo": "Angre", "command.session.undo.description": "Angre siste melding", "command.session.redo": "Gjør om", @@ -469,7 +469,7 @@ export const dict = { "Rotelement ikke funnet. Glemte du å legge det til i index.html? Eller kanskje id-attributten er feilstavet?", "error.serverSync.connectFailed": "Kunne ikke koble til server. Kjører det en server på `{{url}}`?", - "directory.error.invalidUrl": "Invalid directory in URL.", + "directory.error.invalidUrl": "Ugyldig mappe i URL-en.", "error.chain.unknown": "Ukjent feil", "error.chain.causedBy": "Forårsaket av:", @@ -649,8 +649,8 @@ export const dict = { "settings.general.row.theme.description": "Tilpass hvordan OpenCode er tematisert.", "settings.general.row.font.title": "Kodefont", "settings.general.row.font.description": "Tilpass skrifttypen som brukes i kodeblokker", - "settings.general.row.terminalFont.title": "Terminal Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "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", @@ -936,4 +936,163 @@ export const dict = { "error.childStore.persistedProjectIconCreateFailed": "Kunne ikke opprette vedvarende prosjektikon", "error.childStore.storeCreateFailed": "Kunne ikke opprette lager", "terminal.connectionLost.abnormalClose": "WebSocket lukket unormalt: {{code}}", + + "command.project.previous": "Forrige prosjekt", + "command.project.next": "Neste prosjekt", + "command.project.index": "Bytt til prosjekt {{index}}", + "command.tab.reopenClosed": "Åpne lukket fane på nytt", + + "model.tooltip.context.label": "Kontekst", + "model.tooltip.inputs": "Inndata", + "model.tooltip.model": "Modell", + "model.tooltip.provider": "Leverandør", + "model.tooltip.reasoning": "Resonnering", + + "common.clear": "Tøm", + + "session.child.promptDisabled": "Underagentsesjoner kan ikke motta forespørsler.", + "session.child.backToParent": "Tilbake til hovedsesjonen.", + + "wsl.server.add": "Legg til WSL-server", + "wsl.server.addShort": "Legg til WSL", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "WSL-server", + "wsl.server.retryStart": "Prøv å starte på nytt", + "wsl.server.updating": "Oppdaterer...", + "wsl.onboarding.step.distro": "Velg distribusjon", + "wsl.onboarding.step.opencode": "OpenCode", + "wsl.onboarding.checkingRuntime": "Sjekker WSL...", + "wsl.onboarding.restartRequired": "Windows må startes på nytt for å fullføre installasjonen av WSL.", + "wsl.onboarding.ready": "WSL er klart.", + "wsl.onboarding.required": "WSL kreves for å fortsette.", + "wsl.onboarding.checkingDistros": "Sjekker distribusjoner...", + "wsl.onboarding.installingDistro": "Installerer {{distro}}...", + "wsl.onboarding.checkingDistro": "Sjekker {{distro}}...", + "wsl.onboarding.listingDistros": "Lister distribusjoner...", + "wsl.onboarding.distroReady": "{{distro}} er klar.", + "wsl.onboarding.distroNotInstalled": "{{distro}} er ikke installert ennå.", + "wsl.onboarding.openDistroOnce": "Åpne {{distro}} én gang for å fullføre oppsettet.", + "wsl.onboarding.finishingDistro": "Fullfører oppsettet for {{distro}}.", + "wsl.onboarding.pickDistro": "Velg en distribusjon eller installer en nedenfor.", + "wsl.onboarding.checkingOpencode": "Sjekker OpenCode...", + "wsl.onboarding.checkingOpencodeIn": "Sjekker OpenCode i {{distro}}...", + "wsl.onboarding.updatingOpencode": "Oppdaterer OpenCode...", + "wsl.onboarding.updatingOpencodeIn": "Oppdaterer OpenCode i {{distro}}...", + "wsl.onboarding.updateOpencodeIn": "Oppdater OpenCode i {{distro}}.", + "wsl.onboarding.updateOpencode": "Oppdater OpenCode", + "wsl.onboarding.opencodeReadyIn": "OpenCode er klar i {{distro}}.", + "wsl.onboarding.opencodeReady": "OpenCode er klar.", + "wsl.onboarding.installOpencodeIn": "Installer OpenCode i {{distro}}.", + "wsl.onboarding.installOpencode": "Installer OpenCode", + "wsl.onboarding.chooseDistroFirst": "Velg en distribusjon først.", + "wsl.onboarding.loadFailed": "Kunne ikke laste inn WSL-status.", + "wsl.onboarding.loading": "Laster...", + "wsl.onboarding.installedDistros": "Installerte distribusjoner", + "wsl.onboarding.checkAgain": "Sjekk på nytt", + "wsl.onboarding.distroStatus.ready": "Klar", + "wsl.onboarding.distroStatus.checking": "Sjekker...", + "wsl.onboarding.distroStatus.opencodeMissing": "OpenCode er ikke installert", + "wsl.onboarding.distroStatus.missingTools": "Mangler bash, curl", + "wsl.onboarding.distroStatus.unsupported": "Ikke støttet · Bruk WSL 2", + "wsl.onboarding.needAnotherDistro": "Trenger du en annen distribusjon?", + "wsl.onboarding.needAnotherDistroHint": "Installer en Linux-distribusjon fra WSL-katalogen", + "wsl.onboarding.wslNotInstalled.title": "WSL er ikke installert", + "wsl.onboarding.wslNotInstalled.description": + "WSL (Windows Subsystem for Linux) kreves før OpenCode kan legge til en WSL-server", + "wsl.onboarding.wslUnavailable.title": "WSL er utilgjengelig", + "wsl.onboarding.wslUnavailable.description": "OpenCode kunne ikke bekrefte WSL på denne maskinen.", + "wsl.onboarding.installWsl": "Installer WSL", + "wsl.onboarding.windowsRestartRequired": + "Start Windows på nytt for å fullføre installasjonen av WSL, og åpne deretter OpenCode på nytt.", + "wsl.onboarding.next": "Neste", + "wsl.onboarding.refresh": "Oppdater", + "wsl.onboarding.allDistrosAdded": "Alle installerte distribusjoner er allerede lagt til.", + "wsl.onboarding.noDistros": "Ingen distribusjoner oppdaget ennå.", + "wsl.onboarding.install": "Installer", + "wsl.onboarding.installing": "Installerer...", + "wsl.onboarding.installDistro": "Installer distribusjon", + "wsl.onboarding.searchDistros": "Søk etter distribusjoner", + "wsl.onboarding.wsl2Required": "WSL 2 er påkrevd.", + "wsl.onboarding.toolsRequired": "Denne distribusjonen trenger bash og curl.", + "wsl.onboarding.openTerminal": "Åpne terminal", + "wsl.onboarding.path": "Bane: {{path}}", + "wsl.onboarding.notFound": "ikke funnet", + "wsl.onboarding.version": "Versjon: {{version}}", + "wsl.onboarding.unknown": "ukjent", + "wsl.onboarding.desktopVersion": "skrivebordsapp {{version}}", + "wsl.onboarding.versionMismatch": "Den installerte versjonen samsvarer ikke med versjonen av skrivebordsappen.", + "wsl.onboarding.adding": "Legger til...", + + "language.uk": "Українська", + + "error.page.description.localServerStartup": "Det oppstod en feil under oppstart av den lokale serveren.", + "error.page.action.exportLogs": "Eksporter logger", + + "home.title": "Hjem", + "home.projects": "Prosjekter", + "home.project.add": "Legg til prosjekt", + "home.recentlyClosed": "Nylig lukket", + "home.server.collapse": "Fold sammen serverprosjekter", + "home.server.expand": "Utvid serverprosjekter", + "home.sessions.search.placeholder": "Søk etter sesjoner", + "home.sessions.search.placeholder.scoped": "Søk etter sesjoner i {{scope}}", + "home.sessions.search.sessions": "Sesjoner", + "home.sessions.search.noResults": "Ingen sesjoner funnet for {{query}}", + "home.sessions.empty": "Ingenting her ennå", + "home.sessions.empty.description": "Opprett en sesjon for å komme i gang", + "home.sessions.group.today": "I dag", + "home.sessions.group.yesterday": "I går", + "home.sessions.group.older": "Eldre", + + "session.tab.unknown": "Ukjent sesjon", + "session.error.notFound": "Denne sesjonen finnes ikke", + "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.noBranchChanges": "Ingen grenendringer ennå", + "session.question.minimize": "Minimer spørsmål", + "session.question.restore": "Gjenopprett spørsmål", + "session.question.pending.one": "{{count}} ventende spørsmål", + "session.question.pending.other": "{{count}} ventende spørsmål", + "session.new.project.new": "Nytt prosjekt", + "session.new.project.search": "Søk etter prosjekter", + "session.new.project.add": "Legg til prosjekt", + "session.new.workspace.runIn": "Kjør sesjonen i", + "session.new.workspace.triggerLocal": "Lokalt", + "session.new.workspace.local": "Lokalt depot", + "session.new.workspace.existing": "Arbeidsområde…", + + "sidebar.empty.title": "Ingen åpne prosjekter", + "sidebar.empty.description": "Åpne et prosjekt for å komme i gang", + + "settings.general.section.advanced": "Avansert", + "settings.general.row.shell.title": "Terminalskall", + "settings.general.row.shell.description": + "Velg skallet som skal brukes i terminalen. Kompatible skall brukes også til agentens verktøykall.", + "settings.general.row.shell.autoDefault": "Automatisk (standard)", + "settings.general.row.shell.terminalOnly": "kun terminal", + "settings.general.row.showFileTree.title": "Filtre", + "settings.general.row.showFileTree.description": "Vis filtrepanelet i sesjoner", + "settings.general.row.showNavigation.title": "Navigasjonskontroller", + "settings.general.row.showNavigation.description": + "Vis tilbake- og fremoverknappene på tittellinjen i skrivebordsappen", + "settings.general.row.showSearch.title": "Kommandopalett", + "settings.general.row.showSearch.description": "Vis knappen for søk og kommandopalett på tittellinjen", + "settings.general.row.showTerminal.title": "Terminal", + "settings.general.row.showTerminal.description": "Vis terminalknappen på tittellinjen i skrivebordsappen", + "settings.general.row.showStatus.title": "Serverstatus", + "settings.general.row.showStatus.description": "Vis serverstatusknappen på tittellinjen", + "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.newLayoutDesigns.title": "Ny layout og utforming", + "settings.general.row.newLayoutDesigns.description": + "Aktiver ny layout og utforming for startsiden, skrivefeltet og sesjonsgrensesnittet", + "settings.general.row.pinchZoom.title": "Knip for å zoome", + "settings.general.row.pinchZoom.description": "Tillat knipebevegelser på styreflaten og Ctrl-rulling for å zoome", + "settings.updates.action.downloading": "Laster ned...", + "settings.updates.action.installing": "Installerer...", } satisfies Partial> diff --git a/packages/app/src/i18n/parity.test.ts b/packages/app/src/i18n/parity.test.ts index 8ad1beb56b0..725b5f68a0c 100644 --- a/packages/app/src/i18n/parity.test.ts +++ b/packages/app/src/i18n/parity.test.ts @@ -1,33 +1,118 @@ import { describe, expect, test } from "bun:test" -import { dict as en } from "./en" -import { dict as ar } from "./ar" -import { dict as br } from "./br" -import { dict as bs } from "./bs" -import { dict as da } from "./da" -import { dict as de } from "./de" -import { dict as es } from "./es" -import { dict as fr } from "./fr" -import { dict as ja } from "./ja" -import { dict as ko } from "./ko" -import { dict as no } from "./no" -import { dict as pl } from "./pl" -import { dict as ru } from "./ru" -import { dict as uk } from "./uk" -import { dict as th } from "./th" -import { dict as zh } from "./zh" -import { dict as zht } from "./zht" -import { dict as tr } from "./tr" -const locales = [ar, br, bs, da, de, es, fr, ja, ko, no, pl, ru, uk, th, tr, zh, zht] -const keys = ["command.session.previous.unseen", "command.session.next.unseen"] as const +const appLocales = [ + "ar", + "br", + "bs", + "da", + "de", + "es", + "fr", + "ja", + "ko", + "no", + "pl", + "ru", + "uk", + "th", + "tr", + "zh", + "zht", +] as const +const desktopLocales = appLocales.filter((locale) => locale !== "th" && locale !== "tr") + +const domains = [ + { + name: "app", + source: "./en.ts", + target: (locale: string) => `./${locale}.ts`, + locales: appLocales, + }, + { + name: "ui", + source: "../../../ui/src/i18n/en.ts", + target: (locale: string) => `../../../ui/src/i18n/${locale}.ts`, + locales: appLocales, + }, + { + name: "desktop", + source: "../../../desktop/src/renderer/i18n/en.ts", + target: (locale: string) => `../../../desktop/src/renderer/i18n/${locale}.ts`, + locales: desktopLocales, + }, +] as const describe("i18n parity", () => { - test("non-English locales translate targeted unseen session keys", () => { - for (const locale of locales) { - for (const key of keys) { - expect(locale[key]).toBeDefined() - expect(locale[key]).not.toBe(en[key]) + test("non-English locales have every English key", 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)) + expect({ domain: domain.name, locale, missing, extra }).toEqual({ + domain: domain.name, + locale, + missing: [], + extra: [], + }) + } + } + }) + + test("non-English locales preserve English placeholders", 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 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: [] }) + } + } + }) + + test("non-English locales translate targeted unseen session keys", async () => { + const source = await dictionary("./en.ts") + for (const locale of appLocales) { + const target = await dictionary(`./${locale}.ts`) + for (const key of ["command.session.previous.unseen", "command.session.next.unseen"]) { + expect(target[key]).toBeDefined() + expect(target[key]).not.toBe(source[key]) + } + } + }) + + test("changed-file summary keys preserve rendered English copy and localize complete phrases", async () => { + const source = await dictionary("../../../ui/src/i18n/en.ts") + expect(source["ui.sessionTurn.diffs.changed.one"].replace("{{count}}", "1")).toBe("1 Changed file") + expect(source["ui.sessionTurn.diffs.changed.other"].replace("{{count}}", "2")).toBe("2 Changed files") + expect(source["ui.sessionTurn.diffs.changed"]).toBeUndefined() + + for (const locale of appLocales) { + const target = await dictionary(`../../../ui/src/i18n/${locale}.ts`) + for (const key of ["ui.sessionTurn.diffs.changed.one", "ui.sessionTurn.diffs.changed.other"]) { + expect(target[key].trim()).not.toBe("") + expect(placeholders(target[key])).toEqual(["count"]) } } }) }) + +async function dictionary(file: string) { + const module: unknown = await import(file) + if (typeof module !== "object" || module === null || !("dict" in module) || !isDictionary(module.dict)) { + throw new Error(`Invalid translation dictionary: ${file}`) + } + return module.dict +} + +function isDictionary(value: unknown): value is Record { + if (typeof value !== "object" || value === null || Array.isArray(value)) return false + return Object.values(value).every((item) => typeof item === "string") +} + +function placeholders(value: string) { + return Array.from(value.matchAll(/{{\s*([^}]+?)\s*}}/g), (match) => match[1]).sort() +} diff --git a/packages/app/src/i18n/pl.ts b/packages/app/src/i18n/pl.ts index fcf9927da01..295d8e615a5 100644 --- a/packages/app/src/i18n/pl.ts +++ b/packages/app/src/i18n/pl.ts @@ -21,6 +21,9 @@ export const dict = { "theme.scheme.dark": "Ciemny", "command.sidebar.toggle": "Przełącz pasek boczny", "command.project.open": "Otwórz projekt", + "command.project.previous": "Poprzedni projekt", + "command.project.next": "Następny projekt", + "command.project.index": "Przełącz na projekt {{index}}", "command.provider.connect": "Połącz dostawcę", "command.server.switch": "Przełącz serwer", "command.settings.open": "Otwórz ustawienia", @@ -39,6 +42,7 @@ export const dict = { "command.session.new": "Nowa sesja", "command.file.open": "Otwórz plik", "command.tab.close": "Zamknij kartę", + "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", @@ -194,6 +198,11 @@ export const dict = { "model.input.video": "wideo", "model.input.pdf": "pdf", "model.tooltip.allows": "Obsługuje: {{inputs}}", + "model.tooltip.context.label": "Kontekst", + "model.tooltip.inputs": "Dane wejściowe", + "model.tooltip.model": "Model", + "model.tooltip.provider": "Dostawca", + "model.tooltip.reasoning": "Wnioskowanie", "model.tooltip.reasoning.allowed": "Obsługuje wnioskowanie", "model.tooltip.reasoning.none": "Brak wnioskowania", "model.tooltip.context": "Limit kontekstu {{limit}}", @@ -203,6 +212,7 @@ export const dict = { "common.loading": "Ładowanie", "common.loading.ellipsis": "...", "common.cancel": "Anuluj", + "common.clear": "Wyczyść", "common.connect": "Połącz", "common.disconnect": "Rozłącz", "common.continue": "Prześlij", @@ -219,6 +229,8 @@ export const dict = { "prompt.mode.shell": "Terminal", "prompt.mode.normal": "Prompt", "prompt.mode.shell.exit": "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", @@ -315,6 +327,75 @@ export const dict = { "dialog.server.menu.delete": "Usuń", "dialog.server.current": "Obecny serwer", "dialog.server.status.default": "Domyślny", + "wsl.server.add": "Dodaj serwer WSL", + "wsl.server.addShort": "Dodaj WSL", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "Serwer WSL", + "wsl.server.retryStart": "Ponów uruchamianie", + "wsl.server.updating": "Aktualizowanie...", + "wsl.onboarding.step.distro": "Wybierz dystrybucję", + "wsl.onboarding.step.opencode": "OpenCode", + "wsl.onboarding.checkingRuntime": "Sprawdzanie WSL...", + "wsl.onboarding.restartRequired": "Aby dokończyć instalację WSL, uruchom ponownie system Windows.", + "wsl.onboarding.ready": "WSL jest gotowy.", + "wsl.onboarding.required": "Aby kontynuować, wymagany jest WSL.", + "wsl.onboarding.checkingDistros": "Sprawdzanie dystrybucji...", + "wsl.onboarding.installingDistro": "Instalowanie {{distro}}...", + "wsl.onboarding.checkingDistro": "Sprawdzanie {{distro}}...", + "wsl.onboarding.listingDistros": "Pobieranie listy dystrybucji...", + "wsl.onboarding.distroReady": "Dystrybucja {{distro}} jest gotowa.", + "wsl.onboarding.distroNotInstalled": "Dystrybucja {{distro}} nie jest jeszcze zainstalowana.", + "wsl.onboarding.openDistroOnce": "Uruchom raz {{distro}}, aby dokończyć konfigurację.", + "wsl.onboarding.finishingDistro": "Kończenie konfiguracji {{distro}}.", + "wsl.onboarding.pickDistro": "Wybierz dystrybucję lub zainstaluj jedną z poniższych.", + "wsl.onboarding.checkingOpencode": "Sprawdzanie OpenCode...", + "wsl.onboarding.checkingOpencodeIn": "Sprawdzanie OpenCode w dystrybucji {{distro}}...", + "wsl.onboarding.updatingOpencode": "Aktualizowanie OpenCode...", + "wsl.onboarding.updatingOpencodeIn": "Aktualizowanie OpenCode w dystrybucji {{distro}}...", + "wsl.onboarding.updateOpencodeIn": "Zaktualizuj OpenCode w dystrybucji {{distro}}.", + "wsl.onboarding.updateOpencode": "Zaktualizuj OpenCode", + "wsl.onboarding.opencodeReadyIn": "OpenCode jest gotowy w dystrybucji {{distro}}.", + "wsl.onboarding.opencodeReady": "OpenCode jest gotowy.", + "wsl.onboarding.installOpencodeIn": "Zainstaluj OpenCode w dystrybucji {{distro}}.", + "wsl.onboarding.installOpencode": "Zainstaluj OpenCode", + "wsl.onboarding.chooseDistroFirst": "Najpierw wybierz dystrybucję.", + "wsl.onboarding.loadFailed": "Nie udało się załadować stanu WSL.", + "wsl.onboarding.loading": "Ładowanie...", + "wsl.onboarding.installedDistros": "Zainstalowane dystrybucje", + "wsl.onboarding.checkAgain": "Sprawdź ponownie", + "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.unsupported": "Nieobsługiwana · Użyj WSL 2", + "wsl.onboarding.needAnotherDistro": "Potrzebujesz innej dystrybucji?", + "wsl.onboarding.needAnotherDistroHint": "Zainstaluj dystrybucję systemu Linux z katalogu WSL", + "wsl.onboarding.wslNotInstalled.title": "WSL nie jest zainstalowany", + "wsl.onboarding.wslNotInstalled.description": + "WSL (Podsystem Windows dla systemu Linux) jest wymagany, zanim OpenCode będzie mógł dodać serwer WSL", + "wsl.onboarding.wslUnavailable.title": "WSL jest niedostępny", + "wsl.onboarding.wslUnavailable.description": "OpenCode nie mógł zweryfikować WSL na tym komputerze.", + "wsl.onboarding.installWsl": "Zainstaluj WSL", + "wsl.onboarding.windowsRestartRequired": + "Uruchom ponownie system Windows, aby dokończyć instalację WSL, a następnie ponownie otwórz OpenCode.", + "wsl.onboarding.next": "Dalej", + "wsl.onboarding.refresh": "Odśwież", + "wsl.onboarding.allDistrosAdded": "Wszystkie zainstalowane dystrybucje zostały już dodane.", + "wsl.onboarding.noDistros": "Nie wykryto jeszcze żadnych dystrybucji.", + "wsl.onboarding.install": "Zainstaluj", + "wsl.onboarding.installing": "Instalowanie...", + "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.openTerminal": "Otwórz terminal", + "wsl.onboarding.path": "Ścieżka: {{path}}", + "wsl.onboarding.notFound": "nie znaleziono", + "wsl.onboarding.version": "Wersja: {{version}}", + "wsl.onboarding.unknown": "nieznana", + "wsl.onboarding.desktopVersion": "aplikacja komputerowa {{version}}", + "wsl.onboarding.versionMismatch": "Zainstalowana wersja nie jest zgodna z wersją aplikacji komputerowej.", + "wsl.onboarding.adding": "Dodawanie...", "dialog.project.edit.title": "Edytuj projekt", "dialog.project.edit.name": "Nazwa", "dialog.project.edit.icon": "Ikona", @@ -324,7 +405,8 @@ export const dict = { "dialog.project.edit.color": "Kolor", "dialog.project.edit.color.select": "Wybierz kolor {{color}}", "dialog.project.edit.worktree.startup": "Skrypt uruchamiania przestrzeni roboczej", - "dialog.project.edit.worktree.startup.description": "Runs after creating a new workspace (worktree).", + "dialog.project.edit.worktree.startup.description": + "Uruchamiany po utworzeniu nowej przestrzeni roboczej (worktree).", "dialog.project.edit.worktree.startup.placeholder": "np. bun install", "context.breakdown.title": "Podział kontekstu", "context.breakdown.note": 'Przybliżony podział tokenów wejściowych. "Inne" obejmuje definicje narzędzi i narzut.', @@ -371,6 +453,7 @@ export const dict = { "language.no": "Norsk", "language.br": "Português (Brasil)", "language.bs": "Bosanski", + "language.uk": "Українська", "language.th": "ไทย", "language.tr": "Türkçe", "toast.language.title": "Język", @@ -407,10 +490,12 @@ export const dict = { "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.report": "Zgłoś błąd", "error.page.action.reported": "Błąd zgłoszony", + "error.page.action.exportLogs": "Eksportuj dzienniki", "error.page.action.checking": "Sprawdzanie...", "error.page.action.checkUpdates": "Sprawdź aktualizacje", "error.page.action.updateTo": "Zaktualizuj do {{version}}", @@ -430,7 +515,8 @@ export const dict = { "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.mcpFailed": 'MCP server "{{name}}" failed. Note, OpenCode does not support MCP authentication yet.', + "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}}", "error.chain.providerInitFailed": 'Nie udało się zainicjować dostawcy "{{provider}}". Sprawdź poświadczenia i konfigurację.', @@ -452,10 +538,30 @@ export const dict = { "home.recentProjects": "Ostatnie projekty", "home.empty.title": "Brak ostatnich projektów", "home.empty.description": "Zacznij od otwarcia lokalnego projektu", + "home.title": "Strona główna", + "home.projects": "Projekty", + "home.project.add": "Dodaj projekt", + "home.recentlyClosed": "Ostatnio zamknięte", + "home.server.collapse": "Zwiń projekty serwera", + "home.server.expand": "Rozwiń projekty serwera", + "home.sessions.search.placeholder": "Szukaj sesji", + "home.sessions.search.placeholder.scoped": "Szukaj sesji w {{scope}}", + "home.sessions.search.sessions": "Sesje", + "home.sessions.search.noResults": "Nie znaleziono sesji dla {{query}}", + "home.sessions.empty": "Jeszcze nic tu nie ma", + "home.sessions.empty.description": "Utwórz sesję, aby rozpocząć", + "home.sessions.group.today": "Dzisiaj", + "home.sessions.group.yesterday": "Wczoraj", + "home.sessions.group.older": "Starsze", "session.tab.session": "Sesja", "session.tab.review": "Przegląd", "session.tab.context": "Kontekst", + "session.tab.unknown": "Nieznana sesja", "session.panel.reviewAndFiles": "Przegląd i pliki", + "session.error.notFound": "Nie można znaleźć tej sesji", + "session.error.notFound.description": "Ta karta wskazuje sesję, która nie istnieje już na tym serwerze.", + "session.error.notFound.closeTab": "Zamknij kartę", + "session.error.serverConnection": "Nie można połączyć się z tym serwerem", "session.review.filesChanged": "Zmieniono {{count}} plików", "session.review.change.one": "Zmiana", "session.review.change.other": "Zmiany", @@ -464,6 +570,8 @@ export const dict = { "session.review.noVcs": "Nie wykryto systemu kontroli wersji Git, 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", + "session.review.noBranchChanges": "Brak jeszcze zmian w gałęzi", "session.files.selectToOpen": "Wybierz plik do otwarcia", "session.files.all": "Wszystkie pliki", "session.files.empty": "Brak plików", @@ -477,6 +585,10 @@ export const dict = { "session.todo.title": "Zadania", "session.todo.collapse": "Zwiń", "session.todo.expand": "Rozwiń", + "session.question.minimize": "Zminimalizuj pytanie", + "session.question.restore": "Przywróć pytanie", + "session.question.pending.one": "{{count}} oczekujące pytanie", + "session.question.pending.other": "Pytania oczekujące: {{count}}", "session.followupDock.summary.one": "{{count}} wiadomość w kolejce", "session.followupDock.summary.other": "{{count}} wiadomości w kolejce", "session.followupDock.sendNow": "Wyślij teraz", @@ -489,9 +601,16 @@ export const dict = { "session.revertDock.expand": "Rozwiń cofnięte wiadomości", "session.revertDock.restore": "Przywróć wiadomość", "session.new.title": "Zbuduj cokolwiek", + "session.new.project.new": "Nowy projekt", + "session.new.project.search": "Szukaj projektów", + "session.new.project.add": "Dodaj projekt", "session.new.worktree.main": "Główna gałąź", "session.new.worktree.mainWithBranch": "Główna gałąź ({{branch}})", "session.new.worktree.create": "Utwórz nowe drzewo robocze", + "session.new.workspace.runIn": "Uruchom sesję w", + "session.new.workspace.triggerLocal": "Lokalnie", + "session.new.workspace.local": "Lokalne repozytorium", + "session.new.workspace.existing": "Przestrzeń robocza…", "session.new.lastModified": "Ostatnio zmodyfikowano", "session.header.search.placeholder": "Szukaj {{project}}", "session.header.searchFiles": "Szukaj plików", @@ -555,15 +674,18 @@ export const dict = { "sidebar.project.recentSessions": "Ostatnie sesje", "sidebar.project.viewAllSessions": "Zobacz wszystkie sesje", "sidebar.project.clearNotifications": "Wyczyść powiadomienia", + "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.server": "Serwer", "settings.tab.general": "Ogólne", "settings.tab.shortcuts": "Skróty", "settings.desktop.section.wsl": "WSL", - "settings.desktop.wsl.title": "WSL integration", - "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.", + "settings.desktop.wsl.title": "Integracja z WSL", + "settings.desktop.wsl.description": "Uruchamiaj serwer OpenCode wewnątrz WSL w systemie Windows.", "settings.general.section.appearance": "Wygląd", + "settings.general.section.advanced": "Zaawansowane", "settings.general.section.notifications": "Powiadomienia systemowe", "settings.general.section.updates": "Aktualizacje", "settings.general.section.sounds": "Efekty dźwiękowe", @@ -571,6 +693,11 @@ export const dict = { "settings.general.section.display": "Ekran", "settings.general.row.language.title": "Język", "settings.general.row.language.description": "Zmień język wyświetlania dla OpenCode", + "settings.general.row.shell.title": "Powłoka terminala", + "settings.general.row.shell.description": + "Wybierz powłokę używaną w terminalu. Zgodne powłoki są również używane przez wywołania narzędzi agenta.", + "settings.general.row.shell.autoDefault": "Automatycznie (domyślna)", + "settings.general.row.shell.terminalOnly": "tylko terminal", "settings.general.row.appearance.title": "Wygląd", "settings.general.row.appearance.description": "Dostosuj wygląd OpenCode na swoim urządzeniu", "settings.general.row.colorScheme.title": "Schemat kolorów", @@ -580,14 +707,30 @@ export const dict = { "settings.general.row.theme.description": "Dostosuj motyw OpenCode.", "settings.general.row.font.title": "Czcionka kodu", "settings.general.row.font.description": "Dostosuj czcionkę używaną w blokach kodu", - "settings.general.row.terminalFont.title": "Terminal Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "settings.general.row.terminalFont.title": "Czcionka terminala", + "settings.general.row.terminalFont.description": "Dostosuj czcionkę używaną w terminalu", "settings.general.row.uiFont.title": "Czcionka interfejsu", "settings.general.row.uiFont.description": "Dostosuj czcionkę używaną w całym interfejsie", "settings.general.row.followup.title": "Zachowanie kontynuacji", "settings.general.row.followup.description": "Wybierz, czy kontynuacja ma być natychmiastowa, czy czekać w kolejce", "settings.general.row.followup.option.queue": "Kolejka", "settings.general.row.followup.option.steer": "Sterowanie", + "settings.general.row.showFileTree.title": "Drzewo plików", + "settings.general.row.showFileTree.description": "Pokaż panel drzewa plików w sesjach", + "settings.general.row.showNavigation.title": "Elementy nawigacji", + "settings.general.row.showNavigation.description": + "Pokaż przyciski Wstecz i Dalej na pasku tytułu aplikacji komputerowej", + "settings.general.row.showSearch.title": "Paleta poleceń", + "settings.general.row.showSearch.description": "Pokaż przycisk wyszukiwania i palety poleceń na pasku tytułu", + "settings.general.row.showTerminal.title": "Terminal", + "settings.general.row.showTerminal.description": "Pokaż przycisk terminala na pasku tytułu aplikacji komputerowej", + "settings.general.row.showStatus.title": "Status serwera", + "settings.general.row.showStatus.description": "Pokaż przycisk statusu serwera na pasku tytułu", + "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.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", @@ -596,6 +739,12 @@ export const dict = { "settings.general.row.editToolPartsExpanded.title": "Rozwijaj elementy narzędzia edit", "settings.general.row.editToolPartsExpanded.description": "Domyślnie pokazuj rozwinięte elementy narzędzi edit, write i patch na osi czasu", + "settings.general.row.newLayoutDesigns.title": "Nowy układ i wygląd", + "settings.general.row.newLayoutDesigns.description": + "Włącz przeprojektowany układ, stronę główną, edytor wiadomości i interfejs sesji", + "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.", "settings.general.row.wayland.tooltip": @@ -608,6 +757,8 @@ export const dict = { "settings.updates.row.check.description": "Ręcznie sprawdź aktualizacje i zainstaluj, jeśli są dostępne", "settings.updates.action.checkNow": "Sprawdź teraz", "settings.updates.action.checking": "Sprawdzanie...", + "settings.updates.action.downloading": "Pobieranie...", + "settings.updates.action.installing": "Instalowanie...", "settings.updates.toast.latest.title": "Masz najnowszą wersję", "settings.updates.toast.latest.description": "Korzystasz z najnowszej wersji OpenCode.", "sound.option.none": "Brak", diff --git a/packages/app/src/i18n/ru.ts b/packages/app/src/i18n/ru.ts index b2f58b101b4..7ef78bb4805 100644 --- a/packages/app/src/i18n/ru.ts +++ b/packages/app/src/i18n/ru.ts @@ -23,6 +23,9 @@ export const dict = { "command.sidebar.toggle": "Переключить боковую панель", "command.project.open": "Открыть проект", + "command.project.previous": "Предыдущий проект", + "command.project.next": "Следующий проект", + "command.project.index": "Переключиться на проект {{index}}", "command.provider.connect": "Подключить провайдера", "command.server.switch": "Переключить сервер", "command.settings.open": "Открыть настройки", @@ -45,6 +48,7 @@ export const dict = { "command.session.new": "Новая сессия", "command.file.open": "Открыть файл", "command.tab.close": "Закрыть вкладку", + "command.tab.reopenClosed": "Повторно открыть закрытую вкладку", "command.context.addSelection": "Добавить выделение в контекст", "command.context.addSelection.description": "Добавить выбранные строки из текущего файла", "command.input.focus": "Фокус на поле ввода", @@ -208,6 +212,11 @@ export const dict = { "model.input.video": "видео", "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.context": "Лимит контекста {{limit}}", @@ -218,6 +227,7 @@ export const dict = { "common.loading": "Загрузка", "common.loading.ellipsis": "...", "common.cancel": "Отмена", + "common.clear": "Очистить", "common.connect": "Подключить", "common.disconnect": "Отключить", "common.continue": "Отправить", @@ -235,6 +245,8 @@ export const dict = { "prompt.mode.shell": "Оболочка", "prompt.mode.normal": "Промпт", "prompt.mode.shell.exit": "esc для выхода", + "session.child.promptDisabled": "В сессиях субагентов нельзя отправлять запросы.", + "session.child.backToParent": "Вернуться к основной сессии.", "prompt.example.1": "Исправить TODO в коде", "prompt.example.2": "Какой технологический стек этого проекта?", @@ -341,6 +353,75 @@ export const dict = { "dialog.server.menu.delete": "Удалить", "dialog.server.current": "Текущий сервер", "dialog.server.status.default": "По умолч.", + "wsl.server.add": "Добавить сервер WSL", + "wsl.server.addShort": "Добавить WSL", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "Сервер WSL", + "wsl.server.retryStart": "Повторить запуск", + "wsl.server.updating": "Обновление...", + "wsl.onboarding.step.distro": "Выбрать дистрибутив", + "wsl.onboarding.step.opencode": "OpenCode", + "wsl.onboarding.checkingRuntime": "Проверка WSL...", + "wsl.onboarding.restartRequired": "Чтобы завершить установку WSL, перезапустите Windows.", + "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.checkingOpencode": "Проверка OpenCode...", + "wsl.onboarding.checkingOpencodeIn": "Проверка OpenCode в {{distro}}...", + "wsl.onboarding.updatingOpencode": "Обновление OpenCode...", + "wsl.onboarding.updatingOpencodeIn": "Обновление 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.installOpencode": "Установить OpenCode", + "wsl.onboarding.chooseDistroFirst": "Сначала выберите дистрибутив.", + "wsl.onboarding.loadFailed": "Не удалось загрузить состояние WSL.", + "wsl.onboarding.loading": "Загрузка...", + "wsl.onboarding.installedDistros": "Установленные дистрибутивы", + "wsl.onboarding.checkAgain": "Проверить снова", + "wsl.onboarding.distroStatus.ready": "Готов", + "wsl.onboarding.distroStatus.checking": "Проверка...", + "wsl.onboarding.distroStatus.opencodeMissing": "OpenCode не установлен", + "wsl.onboarding.distroStatus.missingTools": "Отсутствуют bash и curl", + "wsl.onboarding.distroStatus.unsupported": "Не поддерживается · Используйте WSL 2", + "wsl.onboarding.needAnotherDistro": "Нужен другой дистрибутив?", + "wsl.onboarding.needAnotherDistroHint": "Установите дистрибутив Linux из каталога WSL", + "wsl.onboarding.wslNotInstalled.title": "WSL не установлена", + "wsl.onboarding.wslNotInstalled.description": + "Для добавления сервера WSL в OpenCode требуется WSL (Windows Subsystem for Linux)", + "wsl.onboarding.wslUnavailable.title": "WSL недоступна", + "wsl.onboarding.wslUnavailable.description": "OpenCode не смог проверить WSL на этом компьютере.", + "wsl.onboarding.installWsl": "Установить WSL", + "wsl.onboarding.windowsRestartRequired": + "Перезапустите Windows, чтобы завершить установку WSL, затем снова откройте OpenCode.", + "wsl.onboarding.next": "Далее", + "wsl.onboarding.refresh": "Обновить", + "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.openTerminal": "Открыть терминал", + "wsl.onboarding.path": "Путь: {{path}}", + "wsl.onboarding.notFound": "не найден", + "wsl.onboarding.version": "Версия: {{version}}", + "wsl.onboarding.unknown": "неизвестно", + "wsl.onboarding.desktopVersion": "приложение {{version}}", + "wsl.onboarding.versionMismatch": "Установленная версия не соответствует версии приложения.", + "wsl.onboarding.adding": "Добавление...", "dialog.project.edit.title": "Редактировать проект", "dialog.project.edit.name": "Название", @@ -405,6 +486,7 @@ export const dict = { "language.no": "Norsk", "language.br": "Português (Brasil)", "language.bs": "Bosanski", + "language.uk": "Українська", "language.th": "ไทย", "language.tr": "Türkçe", @@ -452,10 +534,12 @@ export const dict = { "error.page.title": "Что-то пошло не так", "error.page.description": "Произошла ошибка при загрузке приложения.", + "error.page.description.localServerStartup": "Произошла ошибка при запуске локального сервера.", "error.page.details.label": "Детали ошибки", "error.page.action.restart": "Перезапустить", "error.page.action.report": "Сообщить об ошибке", "error.page.action.reported": "Об ошибке сообщено", + "error.page.action.exportLogs": "Экспортировать журналы", "error.page.action.checking": "Проверка...", "error.page.action.checkUpdates": "Проверить обновления", "error.page.action.updateTo": "Обновить до {{version}}", @@ -505,11 +589,31 @@ export const dict = { "home.recentProjects": "Недавние проекты", "home.empty.title": "Нет недавних проектов", "home.empty.description": "Начните с открытия локального проекта", + "home.title": "Главная", + "home.projects": "Проекты", + "home.project.add": "Добавить проект", + "home.recentlyClosed": "Недавно закрытые", + "home.server.collapse": "Свернуть проекты сервера", + "home.server.expand": "Развернуть проекты сервера", + "home.sessions.search.placeholder": "Поиск сессий", + "home.sessions.search.placeholder.scoped": "Поиск сессий в {{scope}}", + "home.sessions.search.sessions": "Сессии", + "home.sessions.search.noResults": "Сессии по запросу {{query}} не найдены", + "home.sessions.empty": "Здесь пока ничего нет", + "home.sessions.empty.description": "Создайте сессию, чтобы начать", + "home.sessions.group.today": "Сегодня", + "home.sessions.group.yesterday": "Вчера", + "home.sessions.group.older": "Ранее", "session.tab.session": "Сессия", "session.tab.review": "Обзор", "session.tab.context": "Контекст", + "session.tab.unknown": "Неизвестная сессия", "session.panel.reviewAndFiles": "Обзор и файлы", + "session.error.notFound": "Эта сессия не найдена", + "session.error.notFound.description": "Эта вкладка указывает на сессию, которой больше нет на этом сервере.", + "session.error.notFound.closeTab": "Закрыть вкладку", + "session.error.serverConnection": "Не удаётся подключиться к этому серверу", "session.review.filesChanged": "{{count}} файлов изменено", "session.review.change.one": "Изменение", "session.review.change.other": "Изменения", @@ -518,6 +622,8 @@ export const dict = { "session.review.noVcs": "Система контроля версий Git не обнаружена, изменения не отображаются", "session.review.noSnapshot": "Отслеживание снимков отключено в настройках, поэтому изменения сессии недоступны", "session.review.noChanges": "Нет изменений", + "session.review.noUncommittedChanges": "Пока нет незафиксированных изменений", + "session.review.noBranchChanges": "Пока нет изменений в ветке", "session.files.selectToOpen": "Выберите файл, чтобы открыть", "session.files.all": "Все файлы", "session.files.empty": "Нет файлов", @@ -532,6 +638,10 @@ export const dict = { "session.todo.title": "Задачи", "session.todo.collapse": "Свернуть", "session.todo.expand": "Развернуть", + "session.question.minimize": "Свернуть вопрос", + "session.question.restore": "Восстановить вопрос", + "session.question.pending.one": "{{count}} вопрос без ответа", + "session.question.pending.other": "Вопросы без ответа: {{count}}", "session.followupDock.summary.one": "{{count}} сообщение в очереди", "session.followupDock.summary.other": "{{count}} сообщений в очереди", "session.followupDock.sendNow": "Отправить сейчас", @@ -545,9 +655,16 @@ export const dict = { "session.revertDock.restore": "Восстановить сообщение", "session.new.title": "Создавайте что угодно", + "session.new.project.new": "Новый проект", + "session.new.project.search": "Поиск проектов", + "session.new.project.add": "Добавить проект", "session.new.worktree.main": "Основная ветка", "session.new.worktree.mainWithBranch": "Основная ветка ({{branch}})", "session.new.worktree.create": "Создать новый worktree", + "session.new.workspace.runIn": "Запустить сессию в", + "session.new.workspace.triggerLocal": "Локально", + "session.new.workspace.local": "Локальный репозиторий", + "session.new.workspace.existing": "Рабочее пространство…", "session.new.lastModified": "Последнее изменение", "session.header.search.placeholder": "Поиск {{project}}", @@ -619,6 +736,8 @@ export const dict = { "sidebar.project.recentSessions": "Недавние сессии", "sidebar.project.viewAllSessions": "Посмотреть все сессии", "sidebar.project.clearNotifications": "Очистить уведомления", + "sidebar.empty.title": "Нет открытых проектов", + "sidebar.empty.description": "Откройте проект, чтобы начать", "app.name.desktop": "OpenCode Desktop", "settings.section.desktop": "Приложение", @@ -630,6 +749,7 @@ export const dict = { "settings.desktop.wsl.description": "Запускать сервер OpenCode внутри WSL на Windows.", "settings.general.section.appearance": "Внешний вид", + "settings.general.section.advanced": "Дополнительно", "settings.general.section.notifications": "Системные уведомления", "settings.general.section.updates": "Обновления", "settings.general.section.sounds": "Звуковые эффекты", @@ -638,6 +758,11 @@ export const dict = { "settings.general.row.language.title": "Язык", "settings.general.row.language.description": "Изменить язык отображения OpenCode", + "settings.general.row.shell.title": "Оболочка терминала", + "settings.general.row.shell.description": + "Выберите оболочку для терминала. Совместимые оболочки также используются агентом при вызове инструментов.", + "settings.general.row.shell.autoDefault": "Авто (по умолчанию)", + "settings.general.row.shell.terminalOnly": "только терминал", "settings.general.row.appearance.title": "Внешний вид", "settings.general.row.appearance.description": "Настройте как OpenCode выглядит на вашем устройстве", "settings.general.row.colorScheme.title": "Цветовая схема", @@ -646,8 +771,8 @@ export const dict = { "settings.general.row.theme.description": "Настройте оформление OpenCode.", "settings.general.row.font.title": "Шрифт кода", "settings.general.row.font.description": "Настройте шрифт, используемый в блоках кода", - "settings.general.row.terminalFont.title": "Terminal Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "settings.general.row.terminalFont.title": "Шрифт терминала", + "settings.general.row.terminalFont.description": "Настройте шрифт, используемый в терминале", "settings.general.row.uiFont.title": "Шрифт интерфейса", "settings.general.row.uiFont.description": "Настройте шрифт, используемый во всем интерфейсе", "settings.general.row.followup.title": "Поведение уточняющих вопросов", @@ -655,6 +780,22 @@ export const dict = { "Выберите, отправлять ли уточняющие вопросы сразу или помещать их в очередь", "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.showNavigation.title": "Элементы навигации", + "settings.general.row.showNavigation.description": + "Показывать кнопки «Назад» и «Вперёд» в строке заголовка приложения", + "settings.general.row.showSearch.title": "Палитра команд", + "settings.general.row.showSearch.description": "Показывать кнопку поиска и палитры команд в строке заголовка", + "settings.general.row.showTerminal.title": "Терминал", + "settings.general.row.showTerminal.description": "Показывать кнопку терминала в строке заголовка приложения", + "settings.general.row.showStatus.title": "Состояние сервера", + "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.reasoningSummaries.title": "Показывать сводки рассуждений", "settings.general.row.reasoningSummaries.description": "Отображать сводки рассуждений модели в ленте", @@ -664,6 +805,12 @@ export const dict = { "settings.general.row.editToolPartsExpanded.title": "Разворачивать элементы инструмента edit", "settings.general.row.editToolPartsExpanded.description": "Показывать элементы инструментов edit, write и patch в ленте развернутыми по умолчанию", + "settings.general.row.newLayoutDesigns.title": "Новая компоновка и оформление", + "settings.general.row.newLayoutDesigns.description": + "Включить обновлённую компоновку, главную страницу, редактор запросов и интерфейс сессии", + "settings.general.row.pinchZoom.title": "Масштабирование щипком", + "settings.general.row.pinchZoom.description": + "Разрешить масштабирование жестом щипка на трекпаде и прокруткой с Ctrl", "settings.general.row.wayland.title": "Использовать нативный Wayland", "settings.general.row.wayland.description": "Отключить X11 fallback на Wayland. Требуется перезапуск.", "settings.general.row.wayland.tooltip": @@ -678,6 +825,8 @@ export const dict = { "settings.updates.row.check.description": "Проверить обновления вручную и установить, если доступны", "settings.updates.action.checkNow": "Проверить сейчас", "settings.updates.action.checking": "Проверка...", + "settings.updates.action.downloading": "Загрузка...", + "settings.updates.action.installing": "Установка...", "settings.updates.toast.latest.title": "У вас последняя версия", "settings.updates.toast.latest.description": "Вы используете последнюю версию OpenCode.", "sound.option.none": "Нет", diff --git a/packages/app/src/i18n/th.ts b/packages/app/src/i18n/th.ts index d066f3c616b..686db7407c5 100644 --- a/packages/app/src/i18n/th.ts +++ b/packages/app/src/i18n/th.ts @@ -23,6 +23,9 @@ export const dict = { "command.sidebar.toggle": "สลับแถบข้าง", "command.project.open": "เปิดโปรเจกต์", + "command.project.previous": "โปรเจกต์ก่อนหน้า", + "command.project.next": "โปรเจกต์ถัดไป", + "command.project.index": "สลับไปยังโปรเจกต์ {{index}}", "command.provider.connect": "เชื่อมต่อผู้ให้บริการ", "command.server.switch": "สลับเซิร์ฟเวอร์", "command.settings.open": "เปิดการตั้งค่า", @@ -32,7 +35,7 @@ export const dict = { "command.session.next.unseen": "เซสชันที่ยังไม่ได้อ่านถัดไป", "command.session.archive": "จัดเก็บเซสชัน", - "command.palette": "คำสั่งค้นหา", + "command.palette": "ชุดคำสั่ง", "command.theme.cycle": "เปลี่ยนธีม", "command.theme.set": "ใช้ธีม: {{theme}}", @@ -45,6 +48,7 @@ export const dict = { "command.session.new": "เซสชันใหม่", "command.file.open": "เปิดไฟล์", "command.tab.close": "ปิดแท็บ", + "command.tab.reopenClosed": "เปิดแท็บที่ปิดไปอีกครั้ง", "command.context.addSelection": "เพิ่มส่วนที่เลือกไปยังบริบท", "command.context.addSelection.description": "เพิ่มบรรทัดที่เลือกจากไฟล์ปัจจุบัน", "command.input.focus": "โฟกัสช่องป้อนข้อมูล", @@ -163,7 +167,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": "My AI Provider", + "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", @@ -208,6 +212,11 @@ export const dict = { "model.input.video": "วิดีโอ", "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.context": "ขีดจำกัดบริบท {{limit}}", @@ -218,6 +227,7 @@ export const dict = { "common.loading": "กำลังโหลด", "common.loading.ellipsis": "...", "common.cancel": "ยกเลิก", + "common.clear": "ล้าง", "common.connect": "เชื่อมต่อ", "common.disconnect": "ยกเลิกการเชื่อมต่อ", "common.continue": "ส่ง", @@ -235,6 +245,8 @@ export const dict = { "prompt.mode.shell": "เชลล์", "prompt.mode.normal": "พรอมต์", "prompt.mode.shell.exit": "กด esc เพื่อออก", + "session.child.promptDisabled": "ไม่สามารถส่งพรอมต์ในเซสชันเอเจนต์ย่อยได้.", + "session.child.backToParent": "กลับไปยังเซสชันหลัก.", "prompt.example.1": "แก้ไข TODO ในโค้ดเบส", "prompt.example.2": "เทคโนโลยีของโปรเจกต์นี้คืออะไร?", @@ -341,6 +353,75 @@ export const dict = { "dialog.server.menu.delete": "ลบ", "dialog.server.current": "เซิร์ฟเวอร์ปัจจุบัน", "dialog.server.status.default": "ค่าเริ่มต้น", + "wsl.server.add": "เพิ่มเซิร์ฟเวอร์ WSL", + "wsl.server.addShort": "เพิ่ม WSL", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "เซิร์ฟเวอร์ WSL", + "wsl.server.retryStart": "ลองเริ่มอีกครั้ง", + "wsl.server.updating": "กำลังอัปเดต...", + "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.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.checkingOpencode": "กำลังตรวจสอบ OpenCode...", + "wsl.onboarding.checkingOpencodeIn": "กำลังตรวจสอบ OpenCode ใน {{distro}}...", + "wsl.onboarding.updatingOpencode": "กำลังอัปเดต OpenCode...", + "wsl.onboarding.updatingOpencodeIn": "กำลังอัปเดต 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.installOpencode": "ติดตั้ง OpenCode", + "wsl.onboarding.chooseDistroFirst": "เลือกดิสโทรก่อน.", + "wsl.onboarding.loadFailed": "ไม่สามารถโหลดสถานะ WSL ได้.", + "wsl.onboarding.loading": "กำลังโหลด...", + "wsl.onboarding.installedDistros": "ดิสโทรที่ติดตั้งแล้ว", + "wsl.onboarding.checkAgain": "ตรวจสอบอีกครั้ง", + "wsl.onboarding.distroStatus.ready": "พร้อมใช้งาน", + "wsl.onboarding.distroStatus.checking": "กำลังตรวจสอบ...", + "wsl.onboarding.distroStatus.opencodeMissing": "ยังไม่ได้ติดตั้ง OpenCode", + "wsl.onboarding.distroStatus.missingTools": "ไม่มี bash, curl", + "wsl.onboarding.distroStatus.unsupported": "ไม่รองรับ · ใช้ WSL 2", + "wsl.onboarding.needAnotherDistro": "ต้องการดิสโทรอื่น?", + "wsl.onboarding.needAnotherDistroHint": "ติดตั้งดิสทริบิวชัน Linux จากแค็ตตาล็อก WSL", + "wsl.onboarding.wslNotInstalled.title": "ยังไม่ได้ติดตั้ง WSL", + "wsl.onboarding.wslNotInstalled.description": + "ต้องมี WSL (Windows Subsystem for Linux) ก่อนที่ OpenCode จะเพิ่มเซิร์ฟเวอร์ WSL ได้", + "wsl.onboarding.wslUnavailable.title": "WSL ไม่พร้อมใช้งาน", + "wsl.onboarding.wslUnavailable.description": "OpenCode ไม่สามารถตรวจสอบ WSL บนเครื่องนี้ได้.", + "wsl.onboarding.installWsl": "ติดตั้ง WSL", + "wsl.onboarding.windowsRestartRequired": + "รีสตาร์ท Windows เพื่อให้การติดตั้ง WSL เสร็จสมบูรณ์ แล้วเปิด OpenCode อีกครั้ง.", + "wsl.onboarding.next": "ถัดไป", + "wsl.onboarding.refresh": "รีเฟรช", + "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.openTerminal": "เปิดเทอร์มินัล", + "wsl.onboarding.path": "เส้นทาง: {{path}}", + "wsl.onboarding.notFound": "ไม่พบ", + "wsl.onboarding.version": "เวอร์ชัน: {{version}}", + "wsl.onboarding.unknown": "ไม่ทราบ", + "wsl.onboarding.desktopVersion": "เดสก์ท็อป {{version}}", + "wsl.onboarding.versionMismatch": "เวอร์ชันที่ติดตั้งไม่ตรงกับเวอร์ชันของแอปเดสก์ท็อป.", + "wsl.onboarding.adding": "กำลังเพิ่ม...", "dialog.project.edit.title": "แก้ไขโปรเจกต์", "dialog.project.edit.name": "ชื่อ", @@ -403,6 +484,7 @@ export const dict = { "language.no": "Norsk", "language.br": "Português (Brasil)", "language.bs": "Bosanski", + "language.uk": "Українська", "language.th": "ไทย", "language.tr": "Türkçe", @@ -451,10 +533,12 @@ export const dict = { "error.page.title": "เกิดข้อผิดพลาด", "error.page.description": "เกิดข้อผิดพลาดระหว่างการโหลดแอปพลิเคชัน", + "error.page.description.localServerStartup": "เกิดข้อผิดพลาดขณะเริ่มเซิร์ฟเวอร์ในเครื่อง.", "error.page.details.label": "รายละเอียดข้อผิดพลาด", "error.page.action.restart": "รีสตาร์ท", "error.page.action.report": "รายงานข้อผิดพลาด", "error.page.action.reported": "รายงานข้อผิดพลาดแล้ว", + "error.page.action.exportLogs": "ส่งออกบันทึก", "error.page.action.checking": "กำลังตรวจสอบ...", "error.page.action.checkUpdates": "ตรวจสอบการอัปเดต", "error.page.action.updateTo": "อัปเดตเป็น {{version}}", @@ -500,11 +584,31 @@ export const dict = { "home.recentProjects": "โปรเจกต์ล่าสุด", "home.empty.title": "ไม่มีโปรเจกต์ล่าสุด", "home.empty.description": "เริ่มต้นโดยเปิดโปรเจกต์ในเครื่อง", + "home.title": "หน้าหลัก", + "home.projects": "โปรเจกต์", + "home.project.add": "เพิ่มโปรเจกต์", + "home.recentlyClosed": "ที่ปิดไปล่าสุด", + "home.server.collapse": "ย่อโปรเจกต์ของเซิร์ฟเวอร์", + "home.server.expand": "ขยายโปรเจกต์ของเซิร์ฟเวอร์", + "home.sessions.search.placeholder": "ค้นหาเซสชัน", + "home.sessions.search.placeholder.scoped": "ค้นหาเซสชันใน {{scope}}", + "home.sessions.search.sessions": "เซสชัน", + "home.sessions.search.noResults": "ไม่พบเซสชันสำหรับ {{query}}", + "home.sessions.empty": "ยังไม่มีอะไรที่นี่", + "home.sessions.empty.description": "สร้างเซสชันเพื่อเริ่มต้น", + "home.sessions.group.today": "วันนี้", + "home.sessions.group.yesterday": "เมื่อวาน", + "home.sessions.group.older": "ก่อนหน้านี้", "session.tab.session": "เซสชัน", "session.tab.review": "ตรวจสอบ", "session.tab.context": "บริบท", + "session.tab.unknown": "เซสชันที่ไม่รู้จัก", "session.panel.reviewAndFiles": "ตรวจสอบและไฟล์", + "session.error.notFound": "ไม่พบเซสชันนี้", + "session.error.notFound.description": "แท็บนี้อ้างถึงเซสชันที่ไม่มีอยู่บนเซิร์ฟเวอร์นี้แล้ว.", + "session.error.notFound.closeTab": "ปิดแท็บ", + "session.error.serverConnection": "ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์นี้", "session.review.filesChanged": "{{count}} ไฟล์ที่เปลี่ยนแปลง", "session.review.change.one": "การเปลี่ยนแปลง", "session.review.change.other": "การเปลี่ยนแปลง", @@ -513,6 +617,8 @@ export const dict = { "session.review.noVcs": "ไม่ตรวจพบระบบควบคุมเวอร์ชัน Git การเปลี่ยนแปลงจะไม่แสดง", "session.review.noSnapshot": "การติดตามสแนปชอตถูกปิดใช้งานในการกำหนดค่า ดังนั้นการเปลี่ยนแปลงเซสชันจึงไม่พร้อมใช้งาน", "session.review.noChanges": "ไม่มีการเปลี่ยนแปลง", + "session.review.noUncommittedChanges": "ยังไม่มีการเปลี่ยนแปลงที่รอคอมมิต", + "session.review.noBranchChanges": "ยังไม่มีการเปลี่ยนแปลงในสาขา", "session.files.selectToOpen": "เลือกไฟล์เพื่อเปิด", "session.files.empty": "ไม่มีไฟล์", @@ -529,6 +635,10 @@ export const dict = { "session.todo.title": "สิ่งที่ต้องทำ", "session.todo.collapse": "ย่อ", "session.todo.expand": "ขยาย", + "session.question.minimize": "ย่อคำถาม", + "session.question.restore": "คืนค่าคำถาม", + "session.question.pending.one": "คำถามที่รอดำเนินการ {{count}} ข้อ", + "session.question.pending.other": "คำถามที่รอดำเนินการ {{count}} ข้อ", "session.followupDock.summary.one": "{{count}} ข้อความในคิว", "session.followupDock.summary.other": "{{count}} ข้อความในคิว", "session.followupDock.sendNow": "ส่งทันที", @@ -542,9 +652,16 @@ export const dict = { "session.revertDock.restore": "กู้คืนข้อความ", "session.new.title": "สร้างอะไรก็ได้", + "session.new.project.new": "โปรเจกต์ใหม่", + "session.new.project.search": "ค้นหาโปรเจกต์", + "session.new.project.add": "เพิ่มโปรเจกต์", "session.new.worktree.main": "สาขาหลัก", "session.new.worktree.mainWithBranch": "สาขาหลัก ({{branch}})", "session.new.worktree.create": "สร้าง worktree ใหม่", + "session.new.workspace.runIn": "เรียกใช้เซสชันใน", + "session.new.workspace.triggerLocal": "ในเครื่อง", + "session.new.workspace.local": "รีโพซิทอรีในเครื่อง", + "session.new.workspace.existing": "พื้นที่ทำงาน…", "session.new.lastModified": "แก้ไขล่าสุด", "session.header.search.placeholder": "ค้นหา {{project}}", @@ -612,6 +729,8 @@ export const dict = { "sidebar.project.recentSessions": "เซสชันล่าสุด", "sidebar.project.viewAllSessions": "ดูเซสชันทั้งหมด", "sidebar.project.clearNotifications": "ล้างการแจ้งเตือน", + "sidebar.empty.title": "ไม่มีโปรเจกต์ที่เปิดอยู่", + "sidebar.empty.description": "เปิดโปรเจกต์เพื่อเริ่มต้น", "app.name.desktop": "OpenCode Desktop", @@ -624,6 +743,7 @@ export const dict = { "settings.desktop.wsl.description": "เรียกใช้เซิร์ฟเวอร์ OpenCode ภายใน WSL บน Windows", "settings.general.section.appearance": "รูปลักษณ์", + "settings.general.section.advanced": "ขั้นสูง", "settings.general.section.notifications": "การแจ้งเตือนระบบ", "settings.general.section.updates": "การอัปเดต", "settings.general.section.sounds": "เสียงเอฟเฟกต์", @@ -632,6 +752,11 @@ export const dict = { "settings.general.row.language.title": "ภาษา", "settings.general.row.language.description": "เปลี่ยนภาษาที่แสดงสำหรับ OpenCode", + "settings.general.row.shell.title": "เชลล์เทอร์มินัล", + "settings.general.row.shell.description": + "เลือกเชลล์ที่จะใช้กับเทอร์มินัล เชลล์ที่เข้ากันได้จะใช้สำหรับการเรียกเครื่องมือของเอเจนต์ด้วย", + "settings.general.row.shell.autoDefault": "อัตโนมัติ (ค่าเริ่มต้น)", + "settings.general.row.shell.terminalOnly": "เทอร์มินัลเท่านั้น", "settings.general.row.appearance.title": "รูปลักษณ์", "settings.general.row.appearance.description": "ปรับแต่งวิธีการที่ OpenCode มีลักษณะบนอุปกรณ์ของคุณ", "settings.general.row.colorScheme.title": "โทนสี", @@ -640,14 +765,29 @@ export const dict = { "settings.general.row.theme.description": "ปรับแต่งวิธีการที่ OpenCode มีธีม", "settings.general.row.font.title": "ฟอนต์โค้ด", "settings.general.row.font.description": "ปรับแต่งฟอนต์ที่ใช้ในบล็อกโค้ด", - "settings.general.row.terminalFont.title": "Terminal Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "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.option.queue": "คิว", "settings.general.row.followup.option.steer": "นำทาง", + "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": "ชุดคำสั่ง", + "settings.general.row.showSearch.description": "แสดงปุ่มค้นหาและชุดคำสั่งในแถบชื่อเรื่อง", + "settings.general.row.showTerminal.title": "เทอร์มินัล", + "settings.general.row.showTerminal.description": "แสดงปุ่มเทอร์มินัลในแถบชื่อเรื่องเดสก์ท็อป", + "settings.general.row.showStatus.title": "สถานะเซิร์ฟเวอร์", + "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.reasoningSummaries.title": "แสดงสรุปการใช้เหตุผล", "settings.general.row.reasoningSummaries.description": "แสดงสรุปการใช้เหตุผลของโมเดลในไทม์ไลน์", "settings.general.row.shellToolPartsExpanded.title": "ขยายส่วนเครื่องมือ shell", @@ -655,6 +795,11 @@ export const dict = { "settings.general.row.editToolPartsExpanded.title": "ขยายส่วนเครื่องมือ edit", "settings.general.row.editToolPartsExpanded.description": "แสดงส่วนเครื่องมือ edit, write และ patch แบบขยายตามค่าเริ่มต้นในไทม์ไลน์", + "settings.general.row.newLayoutDesigns.title": "เลย์เอาต์และดีไซน์ใหม่", + "settings.general.row.newLayoutDesigns.description": + "เปิดใช้เลย์เอาต์ หน้าแรก ช่องเขียนข้อความ และ UI เซสชันที่ออกแบบใหม่", + "settings.general.row.pinchZoom.title": "บีบนิ้วเพื่อซูม", + "settings.general.row.pinchZoom.description": "อนุญาตให้ใช้ท่าบีบนิ้วบนแทร็คแพดและ Ctrl-scroll เพื่อซูม", "settings.general.row.wayland.title": "ใช้ Wayland แบบเนทีฟ", "settings.general.row.wayland.description": "ปิดใช้งาน X11 fallback บน Wayland ต้องรีสตาร์ท", "settings.general.row.wayland.tooltip": "บน Linux ที่มีจอภาพรีเฟรชเรตแบบผสม Wayland แบบเนทีฟอาจเสถียรกว่า", @@ -668,6 +813,8 @@ export const dict = { "settings.updates.row.check.description": "ตรวจสอบการอัปเดตด้วยตนเองและติดตั้งหากมี", "settings.updates.action.checkNow": "ตรวจสอบทันที", "settings.updates.action.checking": "กำลังตรวจสอบ...", + "settings.updates.action.downloading": "กำลังดาวน์โหลด...", + "settings.updates.action.installing": "กำลังติดตั้ง...", "settings.updates.toast.latest.title": "คุณเป็นเวอร์ชันล่าสุดแล้ว", "settings.updates.toast.latest.description": "คุณกำลังใช้งาน OpenCode เวอร์ชันล่าสุด", @@ -857,10 +1004,10 @@ export const dict = { "dialog.server.add.usernamePlaceholder": "ชื่อผู้ใช้", "dialog.server.add.passwordPlaceholder": "รหัสผ่าน", "server.row.noUsername": "ไม่มีชื่อผู้ใช้", - "session.review.noVcs.createGit.title": "สร้าง Git repository", + "session.review.noVcs.createGit.title": "สร้าง Git รีโพซิทอรี", "session.review.noVcs.createGit.description": "ติดตาม ตรวจสอบ และเลิกทำสิ่งเปลี่ยนแปลงในโปรเจกต์นี้", - "session.review.noVcs.createGit.actionLoading": "กำลังสร้าง Git repository...", - "session.review.noVcs.createGit.action": "สร้าง Git repository", + "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", diff --git a/packages/app/src/i18n/tr.ts b/packages/app/src/i18n/tr.ts index 90531735994..b578f89cca8 100644 --- a/packages/app/src/i18n/tr.ts +++ b/packages/app/src/i18n/tr.ts @@ -27,6 +27,9 @@ export const dict = { "command.sidebar.toggle": "Kenar çubuğunu aç/kapat", "command.project.open": "Proje aç", + "command.project.previous": "Önceki proje", + "command.project.next": "Sonraki proje", + "command.project.index": "{{index}} numaralı projeye geç", "command.provider.connect": "Sağlayıcı bağla", "command.server.switch": "Sunucu değiştir", "command.settings.open": "Ayarları aç", @@ -49,6 +52,7 @@ export const dict = { "command.session.new": "Yeni oturum", "command.file.open": "Dosya aç", "command.tab.close": "Sekmeyi kapat", + "command.tab.reopenClosed": "Kapatılan sekmeyi yeniden aç", "command.context.addSelection": "Seçimi bağlama ekle", "command.context.addSelection.description": "Mevcut dosyadan seçili satırları ekle", "command.input.focus": "Girişi odakla", @@ -132,7 +136,7 @@ export const dict = { "provider.connect.status.waiting": "Yetkilendirme bekleniyor...", "provider.connect.status.failed": "Yetkilendirme başarısız: {{error}}", "provider.connect.apiKey.description": - "{{provider}} hesabınızı bağlamak ve OpenCode'da {{provider}} modellerini kullanmak için {{provider}} API anahtarınızı girin.", + "{{provider}} hesabınızı bağlamak ve OpenCode'da {{provider}} modellerini kullanmak için API anahtarınızı girin.", "provider.connect.apiKey.label": "{{provider}} API anahtarı", "provider.connect.apiKey.placeholder": "API anahtarı", "provider.connect.apiKey.required": "API anahtarı gerekli", @@ -143,10 +147,10 @@ export const dict = { "provider.connect.opencodeZen.visit.prefix": "", "provider.connect.opencodeZen.visit.link": "opencode.ai/zen", "provider.connect.opencodeZen.visit.suffix": " adresini ziyaret ederek API anahtarınızı alın.", - "provider.connect.oauth.code.visit.prefix": - "Hesabınızı bağlamak ve OpenCode'da {{provider}} modellerini kullanmak için ", + "provider.connect.oauth.code.visit.prefix": "Yetkilendirme kodunuzu almak için ", "provider.connect.oauth.code.visit.link": "bu bağlantıya", - "provider.connect.oauth.code.visit.suffix": " tıklayarak yetkilendirme kodunuzu alın.", + "provider.connect.oauth.code.visit.suffix": + " gidin; ardından hesabınızı bağlayarak OpenCode'da {{provider}} modellerini kullanın.", "provider.connect.oauth.code.label": "{{method}} yetkilendirme kodu", "provider.connect.oauth.code.placeholder": "Yetkilendirme kodu", "provider.connect.oauth.code.required": "Yetkilendirme kodu gerekli", @@ -213,6 +217,11 @@ export const dict = { "model.input.video": "video", "model.input.pdf": "pdf", "model.tooltip.allows": "Kabul eder: {{inputs}}", + "model.tooltip.context.label": "Bağlam", + "model.tooltip.inputs": "Girdiler", + "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.none": "Akıl yürütme yok", "model.tooltip.context": "Bağlam limiti {{limit}}", @@ -223,6 +232,7 @@ export const dict = { "common.loading": "Yükleniyor", "common.loading.ellipsis": "...", "common.cancel": "İptal", + "common.clear": "Temizle", "common.connect": "Bağlan", "common.disconnect": "Bağlantı Kes", "common.continue": "Gönder", @@ -240,6 +250,8 @@ export const dict = { "prompt.mode.shell": "Kabuk", "prompt.mode.normal": "Komut", "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.", "prompt.example.1": "Kod tabanındaki bir TODO'yu düzelt", "prompt.example.2": "Bu projenin teknoloji yığını nedir?", @@ -346,6 +358,75 @@ export const dict = { "dialog.server.menu.delete": "Sil", "dialog.server.current": "Mevcut Sunucu", "dialog.server.status.default": "Varsayılan", + "wsl.server.add": "WSL sunucusu ekle", + "wsl.server.addShort": "WSL ekle", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "WSL sunucusu", + "wsl.server.retryStart": "Başlatmayı yeniden dene", + "wsl.server.updating": "Güncelleniyor...", + "wsl.onboarding.step.distro": "Dağıtım seç", + "wsl.onboarding.step.opencode": "OpenCode", + "wsl.onboarding.checkingRuntime": "WSL kontrol ediliyor...", + "wsl.onboarding.restartRequired": "WSL kurulumunu tamamlamak için Windows'un yeniden başlatılması gerekiyor.", + "wsl.onboarding.ready": "WSL hazır.", + "wsl.onboarding.required": "Devam etmek için WSL gerekli.", + "wsl.onboarding.checkingDistros": "Dağıtımlar kontrol ediliyor...", + "wsl.onboarding.installingDistro": "{{distro}} kuruluyor...", + "wsl.onboarding.checkingDistro": "{{distro}} kontrol ediliyor...", + "wsl.onboarding.listingDistros": "Dağıtımlar listeleniyor...", + "wsl.onboarding.distroReady": "{{distro}} hazır.", + "wsl.onboarding.distroNotInstalled": "{{distro}} henüz kurulu değil.", + "wsl.onboarding.openDistroOnce": "Kurulumu tamamlamak için {{distro}} dağıtımını bir kez açın.", + "wsl.onboarding.finishingDistro": "{{distro}} kurulumu tamamlanıyor.", + "wsl.onboarding.pickDistro": "Bir dağıtım seçin veya aşağıdan bir dağıtım kurun.", + "wsl.onboarding.checkingOpencode": "OpenCode kontrol ediliyor...", + "wsl.onboarding.checkingOpencodeIn": "{{distro}} içinde OpenCode kontrol ediliyor...", + "wsl.onboarding.updatingOpencode": "OpenCode güncelleniyor...", + "wsl.onboarding.updatingOpencodeIn": "{{distro}} içinde OpenCode güncelleniyor...", + "wsl.onboarding.updateOpencodeIn": "{{distro}} içindeki OpenCode'u güncelleyin.", + "wsl.onboarding.updateOpencode": "OpenCode'u güncelle", + "wsl.onboarding.opencodeReadyIn": "{{distro}} içinde OpenCode hazır.", + "wsl.onboarding.opencodeReady": "OpenCode hazır.", + "wsl.onboarding.installOpencodeIn": "OpenCode'u {{distro}} içine kurun.", + "wsl.onboarding.installOpencode": "OpenCode'u kur", + "wsl.onboarding.chooseDistroFirst": "Önce bir dağıtım seçin.", + "wsl.onboarding.loadFailed": "WSL durumu yüklenemedi.", + "wsl.onboarding.loading": "Yükleniyor...", + "wsl.onboarding.installedDistros": "Kurulu dağıtımlar", + "wsl.onboarding.checkAgain": "Tekrar kontrol et", + "wsl.onboarding.distroStatus.ready": "Hazır", + "wsl.onboarding.distroStatus.checking": "Kontrol ediliyor...", + "wsl.onboarding.distroStatus.opencodeMissing": "OpenCode kurulu değil", + "wsl.onboarding.distroStatus.missingTools": "bash ve curl eksik", + "wsl.onboarding.distroStatus.unsupported": "Desteklenmiyor · WSL 2 kullanın", + "wsl.onboarding.needAnotherDistro": "Başka bir dağıtım mı gerekiyor?", + "wsl.onboarding.needAnotherDistroHint": "WSL kataloğundan bir Linux dağıtımı kurun", + "wsl.onboarding.wslNotInstalled.title": "WSL kurulu değil", + "wsl.onboarding.wslNotInstalled.description": + "OpenCode'un WSL sunucusu ekleyebilmesi için önce WSL (Linux için Windows Alt Sistemi) kurulmalıdır", + "wsl.onboarding.wslUnavailable.title": "WSL kullanılamıyor", + "wsl.onboarding.wslUnavailable.description": "OpenCode bu makinede WSL'yi doğrulayamadı.", + "wsl.onboarding.installWsl": "WSL'yi kur", + "wsl.onboarding.windowsRestartRequired": + "WSL kurulumunu tamamlamak için Windows'u yeniden başlatın, ardından OpenCode'u tekrar açın.", + "wsl.onboarding.next": "İleri", + "wsl.onboarding.refresh": "Yenile", + "wsl.onboarding.allDistrosAdded": "Kurulu tüm dağıtımlar zaten eklenmiş.", + "wsl.onboarding.noDistros": "Henüz dağıtım algılanmadı.", + "wsl.onboarding.install": "Kur", + "wsl.onboarding.installing": "Kuruluyor...", + "wsl.onboarding.installDistro": "Dağıtım kur", + "wsl.onboarding.searchDistros": "Dağıtım ara", + "wsl.onboarding.wsl2Required": "WSL 2 gerekli.", + "wsl.onboarding.toolsRequired": "Bu dağıtım için bash ve curl gerekli.", + "wsl.onboarding.openTerminal": "Terminali aç", + "wsl.onboarding.path": "Yol: {{path}}", + "wsl.onboarding.notFound": "bulunamadı", + "wsl.onboarding.version": "Sürüm: {{version}}", + "wsl.onboarding.unknown": "bilinmiyor", + "wsl.onboarding.desktopVersion": "masaüstü {{version}}", + "wsl.onboarding.versionMismatch": "Kurulu sürüm masaüstü uygulamasının sürümüyle eşleşmiyor.", + "wsl.onboarding.adding": "Ekleniyor...", "dialog.project.edit.title": "Projeyi düzenle", "dialog.project.edit.name": "Ad", @@ -408,6 +489,7 @@ export const dict = { "language.no": "Norsk", "language.br": "Português (Brasil)", "language.bs": "Bosanski", + "language.uk": "Українська", "language.th": "ไทย", "language.tr": "Türkçe", @@ -456,10 +538,12 @@ export const dict = { "error.page.title": "Bir şeyler yanlış gitti", "error.page.description": "Uygulama yüklenirken bir hata oluştu.", + "error.page.description.localServerStartup": "Yerel sunucu başlatılırken bir hata oluştu.", "error.page.details.label": "Hata Detayları", "error.page.action.restart": "Yeniden Başlat", "error.page.action.report": "Hatayı Bildir", "error.page.action.reported": "Hata Bildirildi", + "error.page.action.exportLogs": "Günlükleri Dışa Aktar", "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", @@ -509,11 +593,31 @@ export const dict = { "home.recentProjects": "Son projeler", "home.empty.title": "Son proje yok", "home.empty.description": "Yerel bir proje açarak başlayın", + "home.title": "Ana Sayfa", + "home.projects": "Projeler", + "home.project.add": "Proje ekle", + "home.recentlyClosed": "Yakın zamanda kapatılanlar", + "home.server.collapse": "Sunucu projelerini daralt", + "home.server.expand": "Sunucu projelerini genişlet", + "home.sessions.search.placeholder": "Oturum ara", + "home.sessions.search.placeholder.scoped": "{{scope}} kapsamında oturum ara", + "home.sessions.search.sessions": "Oturumlar", + "home.sessions.search.noResults": "{{query}} için oturum bulunamadı", + "home.sessions.empty": "Henüz burada bir şey yok", + "home.sessions.empty.description": "Başlamak için bir oturum oluşturun", + "home.sessions.group.today": "Bugün", + "home.sessions.group.yesterday": "Dün", + "home.sessions.group.older": "Daha eski", "session.tab.session": "Oturum", "session.tab.review": "İnceleme", "session.tab.context": "Bağlam", + "session.tab.unknown": "Bilinmeyen Oturum", "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.serverConnection": "Bu sunucuya bağlanılamıyor", "session.review.filesChanged": "{{count}} Dosya Değişti", "session.review.change.one": "Değişiklik", "session.review.change.other": "Değişiklik", @@ -523,6 +627,8 @@ 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.noBranchChanges": "Henüz dal değişikliği yok", "session.files.selectToOpen": "Açmak için bir dosya seçin", "session.files.all": "Tüm dosyalar", @@ -539,6 +645,10 @@ export const dict = { "session.todo.title": "Görevler", "session.todo.collapse": "Daralt", "session.todo.expand": "Genişlet", + "session.question.minimize": "Soruyu küçült", + "session.question.restore": "Soruyu geri yükle", + "session.question.pending.one": "{{count}} bekleyen soru", + "session.question.pending.other": "{{count}} bekleyen soru", "session.followupDock.summary.one": "{{count}} sıradaki mesaj", "session.followupDock.summary.other": "{{count}} sıradaki mesaj", "session.followupDock.sendNow": "Şimdi gönder", @@ -552,9 +662,16 @@ export const dict = { "session.revertDock.restore": "Mesajı geri yükle", "session.new.title": "İstediğini yap", + "session.new.project.new": "Yeni proje", + "session.new.project.search": "Proje ara", + "session.new.project.add": "Proje ekle", "session.new.worktree.main": "Ana dal", "session.new.worktree.mainWithBranch": "Ana dal ({{branch}})", "session.new.worktree.create": "Yeni çalışma ağacı oluştur", + "session.new.workspace.runIn": "Oturumu şurada çalıştır", + "session.new.workspace.triggerLocal": "Yerel", + "session.new.workspace.local": "Yerel depo", + "session.new.workspace.existing": "Çalışma alanı…", "session.new.lastModified": "Son değişiklik", "session.header.search.placeholder": "{{project}} ara", @@ -624,6 +741,8 @@ export const dict = { "sidebar.project.recentSessions": "Son oturumlar", "sidebar.project.viewAllSessions": "Tüm oturumları görüntüle", "sidebar.project.clearNotifications": "Bildirimleri temizle", + "sidebar.empty.title": "Açık proje yok", + "sidebar.empty.description": "Başlamak için bir proje açın", "app.name.desktop": "OpenCode Masaüstü", @@ -636,6 +755,7 @@ export const dict = { "settings.desktop.wsl.description": "OpenCode sunucusunu Windows'ta WSL içinde çalıştırın.", "settings.general.section.appearance": "Görünüm", + "settings.general.section.advanced": "Gelişmiş", "settings.general.section.notifications": "Sistem bildirimleri", "settings.general.section.updates": "Güncellemeler", "settings.general.section.sounds": "Ses efektleri", @@ -644,6 +764,11 @@ export const dict = { "settings.general.row.language.title": "Dil", "settings.general.row.language.description": "OpenCode'un görünüm dilini değiştirin", + "settings.general.row.shell.title": "Terminal Kabuğu", + "settings.general.row.shell.description": + "Terminalinizde kullanılacak kabuğu seçin. Uyumlu kabuklar, ajan araç çağrılarında da kullanılır.", + "settings.general.row.shell.autoDefault": "Otomatik (Varsayılan)", + "settings.general.row.shell.terminalOnly": "yalnızca terminal", "settings.general.row.appearance.title": "Görünüm", "settings.general.row.appearance.description": "OpenCode'un cihazınızdaki görünümünü özelleştirin", "settings.general.row.colorScheme.title": "Renk şeması", @@ -653,8 +778,8 @@ export const dict = { "settings.general.row.theme.description": "OpenCode'un temasını özelleştirin.", "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 Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "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.description": "Arayüz genelinde kullanılan yazı tipini özelleştirin", "settings.general.row.followup.title": "Takip davranışı", @@ -662,6 +787,21 @@ export const dict = { "Takip komutlarının 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ı", + "settings.general.row.showFileTree.description": "Oturumlarda dosya ağacı panelini göster", + "settings.general.row.showNavigation.title": "Gezinme denetimleri", + "settings.general.row.showNavigation.description": "Masaüstü başlık çubuğunda geri ve ileri düğmelerini göster", + "settings.general.row.showSearch.title": "Komut paleti", + "settings.general.row.showSearch.description": "Başlık çubuğunda arama ve komut paleti düğmesini göster", + "settings.general.row.showTerminal.title": "Terminal", + "settings.general.row.showTerminal.description": "Masaüstü başlık çubuğunda terminal düğmesini göster", + "settings.general.row.showStatus.title": "Sunucu durumu", + "settings.general.row.showStatus.description": "Başlık çubuğunda sunucu durumu düğmesini göster", + "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.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", @@ -670,6 +810,12 @@ export const dict = { "settings.general.row.editToolPartsExpanded.title": "Düzenleme araç bileşenlerini genişlet", "settings.general.row.editToolPartsExpanded.description": "Zaman çizelgesinde düzenleme, yazma ve yama araç bileşenlerini varsayılan olarak genişletilmiş göster", + "settings.general.row.newLayoutDesigns.title": "Yeni düzen ve tasarımlar", + "settings.general.row.newLayoutDesigns.description": + "Yeniden tasarlanan düzeni, ana sayfayı, yazma alanını ve oturum arayüzünü etkinleştir", + "settings.general.row.pinchZoom.title": "Sıkıştırarak yakınlaştır", + "settings.general.row.pinchZoom.description": + "İzleme dörtgeninde sıkıştırma ve Ctrl-kaydırma hareketleriyle yakınlaştırmaya izin ver", "settings.general.row.wayland.title": "Yerel Wayland kullan", "settings.general.row.wayland.description": @@ -686,6 +832,8 @@ export const dict = { "settings.updates.row.check.description": "Elle güncelleme kontrolü yap ve varsa yükle", "settings.updates.action.checkNow": "Şimdi kontrol et", "settings.updates.action.checking": "Kontrol ediliyor...", + "settings.updates.action.downloading": "İndiriliyor...", + "settings.updates.action.installing": "Kuruluyor...", "settings.updates.toast.latest.title": "Güncelsiniz", "settings.updates.toast.latest.description": "OpenCode'un en son sürümünü kullanıyorsunuz.", diff --git a/packages/app/src/i18n/uk.ts b/packages/app/src/i18n/uk.ts index d875766e885..ff18c8e342e 100644 --- a/packages/app/src/i18n/uk.ts +++ b/packages/app/src/i18n/uk.ts @@ -48,6 +48,7 @@ export const dict = { "command.session.new": "Нова сесія", "command.file.open": "Відкрити файл", "command.tab.close": "Закрити вкладку", + "command.tab.reopenClosed": "Повторно відкрити закриту вкладку", "command.context.addSelection": "Додати виділення до контексту", "command.context.addSelection.description": "Додати вибрані рядки з поточного файлу", "command.input.focus": "Фокус на полі введення", @@ -212,6 +213,11 @@ export const dict = { "model.input.video": "відео", "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.context": "Ліміт контексту {{limit}}", @@ -222,6 +228,7 @@ export const dict = { "common.loading": "Завантаження", "common.loading.ellipsis": "...", "common.cancel": "Скасувати", + "common.clear": "Очистити", "common.open": "Відкрити", "common.connect": "Підключити", "common.disconnect": "Відключити", @@ -354,6 +361,75 @@ export const dict = { "dialog.server.menu.delete": "Видалити", "dialog.server.current": "Поточний сервер", "dialog.server.status.default": "За замовчуванням", + "wsl.server.add": "Додати сервер WSL", + "wsl.server.addShort": "Додати WSL", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "Сервер WSL", + "wsl.server.retryStart": "Повторити запуск", + "wsl.server.updating": "Оновлення...", + "wsl.onboarding.step.distro": "Вибрати дистрибутив", + "wsl.onboarding.step.opencode": "OpenCode", + "wsl.onboarding.checkingRuntime": "Перевірка WSL...", + "wsl.onboarding.restartRequired": "Щоб завершити встановлення WSL, потрібно перезапустити Windows.", + "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.checkingOpencode": "Перевірка OpenCode...", + "wsl.onboarding.checkingOpencodeIn": "Перевірка OpenCode у {{distro}}...", + "wsl.onboarding.updatingOpencode": "Оновлення OpenCode...", + "wsl.onboarding.updatingOpencodeIn": "Оновлення 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.installOpencode": "Встановити OpenCode", + "wsl.onboarding.chooseDistroFirst": "Спочатку виберіть дистрибутив.", + "wsl.onboarding.loadFailed": "Не вдалося завантажити стан WSL.", + "wsl.onboarding.loading": "Завантаження...", + "wsl.onboarding.installedDistros": "Встановлені дистрибутиви", + "wsl.onboarding.checkAgain": "Перевірити ще раз", + "wsl.onboarding.distroStatus.ready": "Готовий", + "wsl.onboarding.distroStatus.checking": "Перевірка...", + "wsl.onboarding.distroStatus.opencodeMissing": "OpenCode не встановлено", + "wsl.onboarding.distroStatus.missingTools": "Немає bash і curl", + "wsl.onboarding.distroStatus.unsupported": "Не підтримується · Використовуйте WSL 2", + "wsl.onboarding.needAnotherDistro": "Потрібен інший дистрибутив?", + "wsl.onboarding.needAnotherDistroHint": "Встановіть дистрибутив Linux із каталогу WSL", + "wsl.onboarding.wslNotInstalled.title": "WSL не встановлено", + "wsl.onboarding.wslNotInstalled.description": + "Для додавання сервера WSL в OpenCode потрібна WSL (Підсистема Windows для Linux)", + "wsl.onboarding.wslUnavailable.title": "WSL недоступна", + "wsl.onboarding.wslUnavailable.description": "OpenCode не вдалося перевірити WSL на цьому комп'ютері.", + "wsl.onboarding.installWsl": "Встановити WSL", + "wsl.onboarding.windowsRestartRequired": + "Перезапустіть Windows, щоб завершити встановлення WSL, а потім знову відкрийте OpenCode.", + "wsl.onboarding.next": "Далі", + "wsl.onboarding.refresh": "Оновити", + "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.openTerminal": "Відкрити термінал", + "wsl.onboarding.path": "Шлях: {{path}}", + "wsl.onboarding.notFound": "не знайдено", + "wsl.onboarding.version": "Версія: {{version}}", + "wsl.onboarding.unknown": "невідомо", + "wsl.onboarding.desktopVersion": "десктопний застосунок {{version}}", + "wsl.onboarding.versionMismatch": "Встановлена версія не відповідає версії десктопного застосунку.", + "wsl.onboarding.adding": "Додавання...", "server.row.noUsername": "без імені користувача", "dialog.project.edit.title": "Редагувати проєкт", @@ -473,10 +549,12 @@ export const dict = { "error.page.title": "Щось пішло не так", "error.page.description": "Під час завантаження програми сталася помилка.", + "error.page.description.localServerStartup": "Під час запуску локального сервера сталася помилка.", "error.page.details.label": "Деталі помилки", "error.page.action.restart": "Перезапустити", "error.page.action.report": "Повідомити про помилку", "error.page.action.reported": "Помилку повідомлено", + "error.page.action.exportLogs": "Експортувати журнали", "error.page.action.checking": "Перевірка...", "error.page.action.checkUpdates": "Перевірити оновлення", "error.page.action.updateTo": "Оновити до {{version}}", @@ -533,11 +611,31 @@ export const dict = { "home.recentProjects": "Нещодавні проєкти", "home.empty.title": "Немає нещодавніх проєктів", "home.empty.description": "Почніть, відкривши локальний проєкт", + "home.title": "Головна", + "home.projects": "Проєкти", + "home.project.add": "Додати проєкт", + "home.recentlyClosed": "Нещодавно закриті", + "home.server.collapse": "Згорнути проєкти сервера", + "home.server.expand": "Розгорнути проєкти сервера", + "home.sessions.search.placeholder": "Пошук сесій", + "home.sessions.search.placeholder.scoped": "Пошук сесій у {{scope}}", + "home.sessions.search.sessions": "Сесії", + "home.sessions.search.noResults": "Сесій за запитом {{query}} не знайдено", + "home.sessions.empty": "Тут поки нічого немає", + "home.sessions.empty.description": "Створіть сесію, щоб почати", + "home.sessions.group.today": "Сьогодні", + "home.sessions.group.yesterday": "Учора", + "home.sessions.group.older": "Раніше", "session.tab.session": "Сесія", "session.tab.review": "Огляд", "session.tab.context": "Контекст", + "session.tab.unknown": "Невідома сесія", "session.panel.reviewAndFiles": "Огляд і файли", + "session.error.notFound": "Цю сесію не знайдено", + "session.error.notFound.description": "Ця вкладка посилається на сесію, якої більше немає на цьому сервері.", + "session.error.notFound.closeTab": "Закрити вкладку", + "session.error.serverConnection": "Не вдається підключитися до цього сервера", "session.review.filesChanged": "Змінено файлів: {{count}}", "session.review.change.one": "Зміна", "session.review.change.other": "Зміни", @@ -570,6 +668,10 @@ export const dict = { "session.todo.expand": "Розгорнути", "session.todo.progress": "Виконано {{done}} з {{total}} завдань", "session.question.progress": "{{current}} з {{total}} запитань", + "session.question.minimize": "Згорнути запитання", + "session.question.restore": "Відновити запитання", + "session.question.pending.one": "{{count}} запитання очікує відповіді", + "session.question.pending.other": "Запитання, що очікують відповіді: {{count}}", "session.followupDock.summary.one": "{{count}} повідомлення в черзі", "session.followupDock.summary.other": "{{count}} повідомлень у черзі", "session.followupDock.sendNow": "Надіслати зараз", @@ -583,9 +685,16 @@ export const dict = { "session.revertDock.restore": "Відновити повідомлення", "session.new.title": "Створити що завгодно", + "session.new.project.new": "Новий проєкт", + "session.new.project.search": "Пошук проєктів", + "session.new.project.add": "Додати проєкт", "session.new.worktree.main": "Основна гілка", "session.new.worktree.mainWithBranch": "Основна гілка ({{branch}})", "session.new.worktree.create": "Створити нове робоче дерево", + "session.new.workspace.runIn": "Запустити сесію в", + "session.new.workspace.triggerLocal": "Локально", + "session.new.workspace.local": "Локальний репозиторій", + "session.new.workspace.existing": "Робоча область…", "session.new.lastModified": "Востаннє змінено", "session.header.search.placeholder": "Пошук {{project}}", @@ -773,6 +882,11 @@ export const dict = { "settings.general.row.showTerminal.description": "Показувати кнопку термінала в заголовку робочого столу", "settings.general.row.showStatus.title": "Статус сервера", "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.reasoningSummaries.title": "Показувати підсумки мислення", "settings.general.row.reasoningSummaries.description": "Відображати підсумки мислення моделі на часовій шкалі", "settings.general.row.shellToolPartsExpanded.title": "Розгортати частини інструменту оболонки", @@ -781,6 +895,12 @@ export const dict = { "settings.general.row.editToolPartsExpanded.title": "Розгортати частини інструменту редагування", "settings.general.row.editToolPartsExpanded.description": "Показувати частини інструментів редагування, запису та патчів розгорнутими за замовчуванням на часовій шкалі", + "settings.general.row.newLayoutDesigns.title": "Новий макет і дизайн", + "settings.general.row.newLayoutDesigns.description": + "Увімкнути оновлений макет та інтерфейси головної сторінки, редактора запитів і сесії", + "settings.general.row.pinchZoom.title": "Масштабування щипком", + "settings.general.row.pinchZoom.description": + "Дозволити масштабування жестом щипка на трекпаді та прокручуванням із Ctrl", "settings.general.row.wayland.title": "Використовувати нативний Wayland", "settings.general.row.wayland.description": "Вимкнути резервний X11 на Wayland. Потребує перезапуску.", @@ -796,6 +916,8 @@ export const dict = { "settings.updates.row.check.description": "Вручну перевірити наявність оновлень і встановити, якщо доступні", "settings.updates.action.checkNow": "Перевірити зараз", "settings.updates.action.checking": "Перевірка...", + "settings.updates.action.downloading": "Завантаження...", + "settings.updates.action.installing": "Встановлення...", "settings.updates.toast.latest.title": "У вас актуальна версія", "settings.updates.toast.latest.description": "Ви використовуєте останню версію OpenCode.", "sound.option.none": "Немає", diff --git a/packages/app/src/i18n/zh.ts b/packages/app/src/i18n/zh.ts index 15d873ee04a..3cccc0c82d4 100644 --- a/packages/app/src/i18n/zh.ts +++ b/packages/app/src/i18n/zh.ts @@ -28,6 +28,9 @@ export const dict = { "command.sidebar.toggle": "切换侧边栏", "command.project.open": "打开项目", + "command.project.previous": "上一个项目", + "command.project.next": "下一个项目", + "command.project.index": "切换到项目 {{index}}", "command.provider.connect": "连接提供商", @@ -56,6 +59,7 @@ export const dict = { "command.file.open": "打开文件", "command.tab.close": "关闭标签页", + "command.tab.reopenClosed": "重新打开已关闭的标签页", "command.context.addSelection": "将所选内容添加到上下文", "command.context.addSelection.description": "添加当前文件中选中的行", @@ -230,6 +234,11 @@ export const dict = { "model.input.video": "视频", "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.context": "上下文上限 {{limit}}", @@ -240,6 +249,7 @@ export const dict = { "common.loading": "加载中", "common.loading.ellipsis": "...", "common.cancel": "取消", + "common.clear": "清除", "common.connect": "连接", "common.disconnect": "断开连接", "common.continue": "提交", @@ -257,6 +267,8 @@ export const dict = { "prompt.mode.shell": "Shell", "prompt.mode.normal": "Prompt", "prompt.mode.shell.exit": "按 esc 退出", + "session.child.promptDisabled": "无法向子智能体会话发送提示词。", + "session.child.backToParent": "返回主会话。", "prompt.example.1": "修复代码库中的一个 TODO", "prompt.example.2": "这个项目的技术栈是什么?", "prompt.example.3": "修复失败的测试", @@ -359,6 +371,73 @@ export const dict = { "dialog.server.menu.delete": "删除", "dialog.server.current": "当前服务器", "dialog.server.status.default": "默认", + "wsl.server.add": "添加 WSL 服务器", + "wsl.server.addShort": "添加 WSL", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "WSL 服务器", + "wsl.server.retryStart": "重试启动", + "wsl.server.updating": "正在更新...", + "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.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.checkingOpencode": "正在检查 OpenCode...", + "wsl.onboarding.checkingOpencodeIn": "正在检查 {{distro}} 中的 OpenCode...", + "wsl.onboarding.updatingOpencode": "正在更新 OpenCode...", + "wsl.onboarding.updatingOpencodeIn": "正在更新 {{distro}} 中的 OpenCode...", + "wsl.onboarding.updateOpencodeIn": "更新 {{distro}} 中的 OpenCode。", + "wsl.onboarding.updateOpencode": "更新 OpenCode", + "wsl.onboarding.opencodeReadyIn": "{{distro}} 中的 OpenCode 已就绪。", + "wsl.onboarding.opencodeReady": "OpenCode 已就绪。", + "wsl.onboarding.installOpencodeIn": "在 {{distro}} 中安装 OpenCode。", + "wsl.onboarding.installOpencode": "安装 OpenCode", + "wsl.onboarding.chooseDistroFirst": "请先选择发行版。", + "wsl.onboarding.loadFailed": "加载 WSL 状态失败。", + "wsl.onboarding.loading": "加载中...", + "wsl.onboarding.installedDistros": "已安装的发行版", + "wsl.onboarding.checkAgain": "重新检查", + "wsl.onboarding.distroStatus.ready": "已就绪", + "wsl.onboarding.distroStatus.checking": "检查中...", + "wsl.onboarding.distroStatus.opencodeMissing": "未安装 OpenCode", + "wsl.onboarding.distroStatus.missingTools": "缺少 bash、curl", + "wsl.onboarding.distroStatus.unsupported": "不支持 · 请使用 WSL 2", + "wsl.onboarding.needAnotherDistro": "需要其他发行版?", + "wsl.onboarding.needAnotherDistroHint": "从 WSL 目录安装 Linux 发行版", + "wsl.onboarding.wslNotInstalled.title": "未安装 WSL", + "wsl.onboarding.wslNotInstalled.description": "OpenCode 需要 WSL(Windows Subsystem for Linux)才能添加 WSL 服务器", + "wsl.onboarding.wslUnavailable.title": "WSL 不可用", + "wsl.onboarding.wslUnavailable.description": "OpenCode 无法验证此设备上的 WSL。", + "wsl.onboarding.installWsl": "安装 WSL", + "wsl.onboarding.windowsRestartRequired": "重启 Windows 以完成 WSL 安装,然后重新打开 OpenCode。", + "wsl.onboarding.next": "下一步", + "wsl.onboarding.refresh": "刷新", + "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.openTerminal": "打开终端", + "wsl.onboarding.path": "路径:{{path}}", + "wsl.onboarding.notFound": "未找到", + "wsl.onboarding.version": "版本:{{version}}", + "wsl.onboarding.unknown": "未知", + "wsl.onboarding.desktopVersion": "桌面版 {{version}}", + "wsl.onboarding.versionMismatch": "已安装版本与桌面应用版本不一致。", + "wsl.onboarding.adding": "正在添加...", "dialog.project.edit.title": "编辑项目", "dialog.project.edit.name": "名称", @@ -418,6 +497,7 @@ export const dict = { "language.no": "Norsk", "language.br": "Português (Brasil)", "language.bs": "Bosanski", + "language.uk": "Українська", "language.th": "ไทย", "language.tr": "Türkçe", @@ -456,10 +536,12 @@ export const dict = { "error.page.title": "出了点问题", "error.page.description": "加载应用程序时发生错误。", + "error.page.description.localServerStartup": "启动本地服务器时发生错误。", "error.page.details.label": "错误详情", "error.page.action.restart": "重启", "error.page.action.report": "上报错误", "error.page.action.reported": "错误已上报", + "error.page.action.exportLogs": "导出日志", "error.page.action.checking": "检查中...", "error.page.action.checkUpdates": "检查更新", "error.page.action.updateTo": "更新到 {{version}}", @@ -506,6 +588,9 @@ export const dict = { "home.title": "主页", "home.projects": "项目", "home.project.add": "添加项目", + "home.recentlyClosed": "最近关闭", + "home.server.collapse": "折叠服务器项目", + "home.server.expand": "展开服务器项目", "home.sessions.search.placeholder": "搜索会话", "home.sessions.search.placeholder.scoped": "在 {{scope}} 中搜索会话", "home.sessions.search.sessions": "会话", @@ -519,7 +604,12 @@ export const dict = { "session.tab.session": "会话", "session.tab.review": "审查", "session.tab.context": "上下文", + "session.tab.unknown": "未知会话", "session.panel.reviewAndFiles": "审查和文件", + "session.error.notFound": "找不到此会话", + "session.error.notFound.description": "此标签页指向的会话已不存在于此服务器上。", + "session.error.notFound.closeTab": "关闭标签页", + "session.error.serverConnection": "无法连接到此服务器", "session.review.filesChanged": "{{count}} 个文件变更", "session.review.change.one": "更改", "session.review.change.other": "更改", @@ -528,6 +618,8 @@ export const dict = { "session.review.noVcs": "未检测到 Git 版本控制系统,无法显示更改", "session.review.noSnapshot": "配置中已禁用快照跟踪,因此会话更改不可用", "session.review.noChanges": "无更改", + "session.review.noUncommittedChanges": "尚无未提交的更改", + "session.review.noBranchChanges": "尚无分支更改", "session.files.selectToOpen": "选择要打开的文件", "session.files.all": "所有文件", "session.files.empty": "无文件", @@ -541,6 +633,10 @@ export const dict = { "session.todo.title": "待办事项", "session.todo.collapse": "折叠", "session.todo.expand": "展开", + "session.question.minimize": "最小化问题", + "session.question.restore": "恢复问题", + "session.question.pending.one": "{{count}} 个待处理问题", + "session.question.pending.other": "{{count}} 个待处理问题", "session.followupDock.summary.one": "{{count}} 条排队消息", "session.followupDock.summary.other": "{{count}} 条排队消息", "session.followupDock.sendNow": "立即发送", @@ -553,9 +649,16 @@ export const dict = { "session.revertDock.expand": "展开已回滚消息", "session.revertDock.restore": "恢复消息", "session.new.title": "构建任何东西", + "session.new.project.new": "新建项目", + "session.new.project.search": "搜索项目", + "session.new.project.add": "添加项目", "session.new.worktree.main": "主分支", "session.new.worktree.mainWithBranch": "主分支({{branch}})", "session.new.worktree.create": "创建新的 worktree", + "session.new.workspace.runIn": "运行会话的位置", + "session.new.workspace.triggerLocal": "本地", + "session.new.workspace.local": "本地仓库", + "session.new.workspace.existing": "工作区…", "session.new.lastModified": "最后修改", "session.header.search.placeholder": "搜索 {{project}}", "session.header.searchFiles": "搜索文件", @@ -623,6 +726,8 @@ export const dict = { "sidebar.project.recentSessions": "最近会话", "sidebar.project.viewAllSessions": "查看全部会话", "sidebar.project.clearNotifications": "清除通知", + "sidebar.empty.title": "没有打开的项目", + "sidebar.empty.description": "打开一个项目以开始使用", "app.name.desktop": "OpenCode Desktop", @@ -637,6 +742,7 @@ export const dict = { "settings.desktop.wsl.description": "在 Windows 的 WSL 环境中运行 OpenCode 服务器。", "settings.general.section.appearance": "外观", + "settings.general.section.advanced": "高级", "settings.general.section.notifications": "系统通知", "settings.general.section.updates": "更新", "settings.general.section.sounds": "音效", @@ -644,6 +750,10 @@ export const dict = { "settings.general.section.display": "显示", "settings.general.row.language.title": "语言", "settings.general.row.language.description": "更改 OpenCode 的显示语言", + "settings.general.row.shell.title": "终端 Shell", + "settings.general.row.shell.description": "选择终端使用的 shell。兼容的 shell 也会用于智能体工具调用。", + "settings.general.row.shell.autoDefault": "自动(默认)", + "settings.general.row.shell.terminalOnly": "仅终端", "settings.general.row.appearance.title": "外观", "settings.general.row.appearance.description": "自定义 OpenCode 在你的设备上的外观", "settings.general.row.colorScheme.title": "配色方案", @@ -652,20 +762,38 @@ export const dict = { "settings.general.row.theme.description": "自定义 OpenCode 的主题。", "settings.general.row.font.title": "代码字体", "settings.general.row.font.description": "自定义代码块使用的字体", - "settings.general.row.terminalFont.title": "Terminal Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "settings.general.row.terminalFont.title": "终端字体", + "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.option.queue": "排队", "settings.general.row.followup.option.steer": "引导", + "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": "命令面板", + "settings.general.row.showSearch.description": "在标题栏中显示搜索和命令面板按钮", + "settings.general.row.showTerminal.title": "终端", + "settings.general.row.showTerminal.description": "在桌面版标题栏中显示终端按钮", + "settings.general.row.showStatus.title": "服务器状态", + "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.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.newLayoutDesigns.title": "新版布局和设计", + "settings.general.row.newLayoutDesigns.description": "启用重新设计的布局、主页、输入框和会话界面", + "settings.general.row.pinchZoom.title": "双指缩放", + "settings.general.row.pinchZoom.description": "允许使用触控板双指捏合和 Ctrl-scroll 手势缩放", "settings.general.row.wayland.title": "使用原生 Wayland", "settings.general.row.wayland.description": "在 Wayland 上禁用 X11 回退。需要重启。", "settings.general.row.wayland.tooltip": "在混合刷新率显示器的 Linux 系统上,原生 Wayland 可能更稳定。", @@ -678,6 +806,8 @@ export const dict = { "settings.updates.row.check.description": "手动检查更新并在有更新时安装", "settings.updates.action.checkNow": "立即检查", "settings.updates.action.checking": "正在检查...", + "settings.updates.action.downloading": "正在下载...", + "settings.updates.action.installing": "正在安装...", "settings.updates.toast.latest.title": "已是最新版本", "settings.updates.toast.latest.description": "你正在使用最新版本的 OpenCode。", diff --git a/packages/app/src/i18n/zht.ts b/packages/app/src/i18n/zht.ts index 7998dde3ef8..afe285f6e54 100644 --- a/packages/app/src/i18n/zht.ts +++ b/packages/app/src/i18n/zht.ts @@ -27,6 +27,9 @@ export const dict = { "command.sidebar.toggle": "切換側邊欄", "command.project.open": "開啟專案", + "command.project.previous": "上一個專案", + "command.project.next": "下一個專案", + "command.project.index": "切換至專案 {{index}}", "command.provider.connect": "連接提供者", "command.server.switch": "切換伺服器", "command.settings.open": "開啟設定", @@ -49,6 +52,7 @@ export const dict = { "command.session.new": "新增工作階段", "command.file.open": "開啟檔案", "command.tab.close": "關閉分頁", + "command.tab.reopenClosed": "重新開啟已關閉的分頁", "command.context.addSelection": "將選取內容加入上下文", "command.context.addSelection.description": "加入目前檔案中選取的行", "command.input.focus": "聚焦輸入框", @@ -209,6 +213,11 @@ export const dict = { "model.input.video": "影片", "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.context": "上下文上限 {{limit}}", @@ -218,6 +227,7 @@ export const dict = { "common.loading": "載入中", "common.loading.ellipsis": "...", "common.cancel": "取消", + "common.clear": "清除", "common.connect": "連線", "common.disconnect": "中斷連線", "common.continue": "提交", @@ -235,6 +245,8 @@ export const dict = { "prompt.mode.shell": "Shell", "prompt.mode.normal": "Prompt", "prompt.mode.shell.exit": "按 esc 退出", + "session.child.promptDisabled": "無法在子代理程式工作階段中輸入提示詞。", + "session.child.backToParent": "返回主要工作階段。", "prompt.example.1": "修復程式碼庫中的一個 TODO", "prompt.example.2": "這個專案的技術堆疊是什麼?", @@ -340,6 +352,73 @@ export const dict = { "dialog.server.menu.delete": "刪除", "dialog.server.current": "目前伺服器", "dialog.server.status.default": "預設", + "wsl.server.add": "新增 WSL 伺服器", + "wsl.server.addShort": "新增 WSL", + "wsl.server.label": "WSL", + "wsl.server.menu.label": "WSL 伺服器", + "wsl.server.retryStart": "重試啟動", + "wsl.server.updating": "更新中...", + "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.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.checkingOpencode": "正在檢查 OpenCode...", + "wsl.onboarding.checkingOpencodeIn": "正在檢查 {{distro}} 中的 OpenCode...", + "wsl.onboarding.updatingOpencode": "正在更新 OpenCode...", + "wsl.onboarding.updatingOpencodeIn": "正在更新 {{distro}} 中的 OpenCode...", + "wsl.onboarding.updateOpencodeIn": "更新 {{distro}} 中的 OpenCode。", + "wsl.onboarding.updateOpencode": "更新 OpenCode", + "wsl.onboarding.opencodeReadyIn": "{{distro}} 中的 OpenCode 已就緒。", + "wsl.onboarding.opencodeReady": "OpenCode 已就緒。", + "wsl.onboarding.installOpencodeIn": "在 {{distro}} 中安裝 OpenCode。", + "wsl.onboarding.installOpencode": "安裝 OpenCode", + "wsl.onboarding.chooseDistroFirst": "請先選擇發行版。", + "wsl.onboarding.loadFailed": "無法載入 WSL 狀態。", + "wsl.onboarding.loading": "載入中...", + "wsl.onboarding.installedDistros": "已安裝的發行版", + "wsl.onboarding.checkAgain": "再次檢查", + "wsl.onboarding.distroStatus.ready": "就緒", + "wsl.onboarding.distroStatus.checking": "檢查中...", + "wsl.onboarding.distroStatus.opencodeMissing": "未安裝 OpenCode", + "wsl.onboarding.distroStatus.missingTools": "缺少 bash、curl", + "wsl.onboarding.distroStatus.unsupported": "不支援 · 請使用 WSL 2", + "wsl.onboarding.needAnotherDistro": "需要其他發行版?", + "wsl.onboarding.needAnotherDistroHint": "從 WSL 目錄安裝 Linux 發行版", + "wsl.onboarding.wslNotInstalled.title": "未安裝 WSL", + "wsl.onboarding.wslNotInstalled.description": "新增 WSL 伺服器前,必須先安裝 WSL(Windows Subsystem for Linux)", + "wsl.onboarding.wslUnavailable.title": "WSL 無法使用", + "wsl.onboarding.wslUnavailable.description": "OpenCode 無法確認此電腦上的 WSL。", + "wsl.onboarding.installWsl": "安裝 WSL", + "wsl.onboarding.windowsRestartRequired": "重新啟動 Windows 以完成 WSL 安裝,然後重新開啟 OpenCode。", + "wsl.onboarding.next": "下一步", + "wsl.onboarding.refresh": "重新整理", + "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.openTerminal": "開啟終端機", + "wsl.onboarding.path": "路徑: {{path}}", + "wsl.onboarding.notFound": "找不到", + "wsl.onboarding.version": "版本: {{version}}", + "wsl.onboarding.unknown": "未知", + "wsl.onboarding.desktopVersion": "桌面版 {{version}}", + "wsl.onboarding.versionMismatch": "已安裝版本與桌面應用程式版本不符。", + "wsl.onboarding.adding": "新增中...", "dialog.project.edit.title": "編輯專案", "dialog.project.edit.name": "名稱", @@ -402,6 +481,7 @@ export const dict = { "language.no": "Norsk", "language.br": "Português (Brasil)", "language.bs": "Bosanski", + "language.uk": "Українська", "language.th": "ไทย", "language.tr": "Türkçe", @@ -449,10 +529,12 @@ export const dict = { "error.page.title": "出了點問題", "error.page.description": "載入應用程式時發生錯誤。", + "error.page.description.localServerStartup": "啟動本機伺服器時發生錯誤。", "error.page.details.label": "錯誤詳情", "error.page.action.restart": "重新啟動", "error.page.action.report": "回報錯誤", "error.page.action.reported": "已回報錯誤", + "error.page.action.exportLogs": "匯出日誌", "error.page.action.checking": "檢查中...", "error.page.action.checkUpdates": "檢查更新", "error.page.action.updateTo": "更新到 {{version}}", @@ -498,17 +580,39 @@ export const dict = { "home.recentProjects": "最近專案", "home.empty.title": "沒有最近專案", "home.empty.description": "透過開啟本地專案開始使用", + "home.title": "首頁", + "home.projects": "專案", + "home.project.add": "新增專案", + "home.recentlyClosed": "最近關閉", + "home.server.collapse": "收合伺服器專案", + "home.server.expand": "展開伺服器專案", + "home.sessions.search.placeholder": "搜尋工作階段", + "home.sessions.search.placeholder.scoped": "在 {{scope}} 中搜尋工作階段", + "home.sessions.search.sessions": "工作階段", + "home.sessions.search.noResults": "找不到符合 {{query}} 的工作階段", + "home.sessions.empty": "這裡還沒有內容", + "home.sessions.empty.description": "建立工作階段以開始使用", + "home.sessions.group.today": "今天", + "home.sessions.group.yesterday": "昨天", + "home.sessions.group.older": "更早", "session.tab.session": "工作階段", "session.tab.review": "審查", "session.tab.context": "上下文", + "session.tab.unknown": "未知的工作階段", "session.panel.reviewAndFiles": "審查與檔案", + "session.error.notFound": "找不到此工作階段", + "session.error.notFound.description": "此分頁指向的工作階段已不存在於此伺服器。", + "session.error.notFound.closeTab": "關閉分頁", + "session.error.serverConnection": "無法連線至此伺服器", "session.review.filesChanged": "{{count}} 個檔案變更", "session.review.change.one": "變更", "session.review.change.other": "變更", "session.review.loadingChanges": "正在載入變更...", "session.review.empty": "此工作階段暫無變更", "session.review.noChanges": "沒有變更", + "session.review.noUncommittedChanges": "尚無未提交的變更", + "session.review.noBranchChanges": "尚無分支變更", "session.review.noVcs": "未偵測到 Git 版本控制系統,無法顯示變更", "session.review.noSnapshot": "設定中已停用快照追蹤,因此無法使用工作階段變更", "session.files.selectToOpen": "選取要開啟的檔案", @@ -525,6 +629,10 @@ export const dict = { "session.todo.title": "待辦事項", "session.todo.collapse": "折疊", "session.todo.expand": "展開", + "session.question.minimize": "最小化問題", + "session.question.restore": "還原問題", + "session.question.pending.one": "{{count}} 個待處理問題", + "session.question.pending.other": "{{count}} 個待處理問題", "session.followupDock.summary.one": "{{count}} 則佇列訊息", "session.followupDock.summary.other": "{{count}} 則佇列訊息", "session.followupDock.sendNow": "立即傳送", @@ -538,9 +646,16 @@ export const dict = { "session.revertDock.restore": "還原訊息", "session.new.title": "建構任何東西", + "session.new.project.new": "新專案", + "session.new.project.search": "搜尋專案", + "session.new.project.add": "新增專案", "session.new.worktree.main": "主分支", "session.new.worktree.mainWithBranch": "主分支 ({{branch}})", "session.new.worktree.create": "建立新的 worktree", + "session.new.workspace.runIn": "工作階段執行位置", + "session.new.workspace.triggerLocal": "本機", + "session.new.workspace.local": "本機儲存庫", + "session.new.workspace.existing": "工作區…", "session.new.lastModified": "最後修改", "session.header.search.placeholder": "搜尋 {{project}}", @@ -608,6 +723,8 @@ export const dict = { "sidebar.project.recentSessions": "最近工作階段", "sidebar.project.viewAllSessions": "查看全部工作階段", "sidebar.project.clearNotifications": "清除通知", + "sidebar.empty.title": "未開啟任何專案", + "sidebar.empty.description": "開啟專案以開始使用", "app.name.desktop": "OpenCode Desktop", "settings.section.desktop": "桌面", @@ -619,6 +736,7 @@ export const dict = { "settings.desktop.wsl.description": "在 Windows 上的 WSL 中執行 OpenCode 伺服器。", "settings.general.section.appearance": "外觀", + "settings.general.section.advanced": "進階", "settings.general.section.notifications": "系統通知", "settings.general.section.updates": "更新", "settings.general.section.sounds": "音效", @@ -627,6 +745,10 @@ export const dict = { "settings.general.row.language.title": "語言", "settings.general.row.language.description": "變更 OpenCode 的顯示語言", + "settings.general.row.shell.title": "終端機 Shell", + "settings.general.row.shell.description": "選擇終端機使用的 Shell。相容的 Shell 也會用於代理程式工具呼叫。", + "settings.general.row.shell.autoDefault": "自動(預設)", + "settings.general.row.shell.terminalOnly": "僅限終端機", "settings.general.row.appearance.title": "外觀", "settings.general.row.appearance.description": "自訂 OpenCode 在你的裝置上的外觀", "settings.general.row.colorScheme.title": "配色方案", @@ -635,14 +757,28 @@ export const dict = { "settings.general.row.theme.description": "自訂 OpenCode 的主題。", "settings.general.row.font.title": "程式碼字型", "settings.general.row.font.description": "自訂程式碼區塊使用的字型", - "settings.general.row.terminalFont.title": "Terminal Font", - "settings.general.row.terminalFont.description": "Customise the font used in the terminal", + "settings.general.row.terminalFont.title": "終端機字型", + "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.option.queue": "佇列", "settings.general.row.followup.option.steer": "引導", + "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": "命令面板", + "settings.general.row.showSearch.description": "在標題列中顯示搜尋和命令面板按鈕", + "settings.general.row.showTerminal.title": "終端機", + "settings.general.row.showTerminal.description": "在桌面標題列中顯示終端機按鈕", + "settings.general.row.showStatus.title": "伺服器狀態", + "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.reasoningSummaries.title": "顯示推理摘要", "settings.general.row.reasoningSummaries.description": "在時間軸中顯示模型推理摘要", @@ -650,6 +786,10 @@ export const dict = { "settings.general.row.shellToolPartsExpanded.description": "在時間軸中預設展開 shell 工具區塊", "settings.general.row.editToolPartsExpanded.title": "展開 edit 工具區塊", "settings.general.row.editToolPartsExpanded.description": "在時間軸中預設展開 edit、write 和 patch 工具區塊", + "settings.general.row.newLayoutDesigns.title": "新版面與設計", + "settings.general.row.newLayoutDesigns.description": "啟用重新設計的版面、首頁、輸入區和工作階段介面", + "settings.general.row.pinchZoom.title": "雙指縮放", + "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 可能更穩定。", @@ -663,6 +803,8 @@ export const dict = { "settings.updates.row.check.description": "手動檢查更新並在有更新時安裝", "settings.updates.action.checkNow": "立即檢查", "settings.updates.action.checking": "檢查中...", + "settings.updates.action.downloading": "下載中...", + "settings.updates.action.installing": "安裝中...", "settings.updates.toast.latest.title": "已是最新版本", "settings.updates.toast.latest.description": "你正在使用最新版本的 OpenCode。", diff --git a/packages/app/src/index.css b/packages/app/src/index.css index bc6866f9767..78a9e103a7f 100644 --- a/packages/app/src/index.css +++ b/packages/app/src/index.css @@ -224,7 +224,26 @@ [data-slot="model-selector-scroll"]::before { top: 0; - background: linear-gradient(to bottom, var(--v2-background-bg-layer-01), transparent); + height: 12px; + background: linear-gradient( + 180deg, + color-mix(in srgb, var(--v2-background-bg-layer-01) 80%, transparent) 0%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 78.3336%, transparent) 4.7%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 76.4824%, transparent) 8.9%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 74.368%, transparent) 12.8%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 71.9123%, transparent) 16.56%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 69.037%, transparent) 20.37%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 65.664%, transparent) 24.4%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 61.715%, transparent) 28.83%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 57.1117%, transparent) 33.84%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 51.776%, transparent) 39.6%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 45.6296%, transparent) 46.3%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 38.5944%, transparent) 54.1%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 30.592%, transparent) 63.2%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 21.5443%, transparent) 73.76%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 11.373%, transparent) 85.97%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 0%, transparent) 100% + ); } [data-slot="manage-models-scroll"]::before { @@ -239,7 +258,26 @@ [data-slot="model-selector-scroll"]::after { bottom: 0; - background: linear-gradient(to top, var(--v2-background-bg-layer-01), transparent); + height: 12px; + background: linear-gradient( + 0deg, + color-mix(in srgb, var(--v2-background-bg-layer-01) 80%, transparent) 0%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 78.3336%, transparent) 4.7%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 76.4824%, transparent) 8.9%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 74.368%, transparent) 12.8%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 71.9123%, transparent) 16.56%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 69.037%, transparent) 20.37%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 65.664%, transparent) 24.4%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 61.715%, transparent) 28.83%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 57.1117%, transparent) 33.84%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 51.776%, transparent) 39.6%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 45.6296%, transparent) 46.3%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 38.5944%, transparent) 54.1%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 30.592%, transparent) 63.2%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 21.5443%, transparent) 73.76%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 11.373%, transparent) 85.97%, + color-mix(in srgb, var(--v2-background-bg-layer-01) 0%, transparent) 100% + ); } @supports (animation-timeline: --home-projects-scroll) and (timeline-scope: --home-projects-scroll) { diff --git a/packages/app/src/pages/home.tsx b/packages/app/src/pages/home.tsx index efbab7809ee..c4d84a96f84 100644 --- a/packages/app/src/pages/home.tsx +++ b/packages/app/src/pages/home.tsx @@ -35,7 +35,7 @@ import { usePlatform } from "@/context/platform" import { DateTime } from "luxon" import { useDialog } from "@opencode-ai/ui/context/dialog" import { useDirectoryPicker } from "@/components/directory-picker" -import { useSettingsCommand } from "@/components/settings-dialog" +import { useSettingsDialog } from "@/components/settings-dialog" import { DialogSelectServer, useServerManagementController } from "@/components/dialog-select-server" import { DialogServerV2 } from "@/components/settings-v2/dialog-server-v2" import { ServerConnection, serverName, useServer } from "@/context/server" @@ -267,7 +267,7 @@ export function NewHome() { const command = useCommand() const notification = useNotification() const marked = useMarked() - const openSettings = useSettingsCommand() + const openSettings = useSettingsDialog() let focusSessionSearch: (() => void) | undefined const [state, setState] = createStore({ search: "", @@ -1278,7 +1278,7 @@ function HomeSessionSearch(props: {
-