diff options
| author | GitHub Action <[email protected]> | 2026-01-20 23:58:59 +0000 |
|---|---|---|
| committer | GitHub Action <[email protected]> | 2026-01-20 23:58:59 +0000 |
| commit | bb8bf32abe55ac49c45eb4801a61db6ca3c3b453 (patch) | |
| tree | 966e2344896cd538192004f118b121db09c5af26 | |
| parent | 233d003b4926ec615ff15c1ddd54a1719a62ef13 (diff) | |
| download | opencode-bb8bf32abe55ac49c45eb4801a61db6ca3c3b453.tar.gz opencode-bb8bf32abe55ac49c45eb4801a61db6ca3c3b453.zip | |
chore: generate
20 files changed, 161 insertions, 123 deletions
diff --git a/packages/app/src/components/dialog-connect-provider.tsx b/packages/app/src/components/dialog-connect-provider.tsx index fa72ccef3..63f3c5dbe 100644 --- a/packages/app/src/components/dialog-connect-provider.tsx +++ b/packages/app/src/components/dialog-connect-provider.tsx @@ -236,8 +236,12 @@ export function DialogConnectProvider(props: { provider: string }) { <Switch> <Match when={provider().id === "opencode"}> <div class="flex flex-col gap-4"> - <div class="text-14-regular text-text-base">{language.t("provider.connect.opencodeZen.line1")}</div> - <div class="text-14-regular text-text-base">{language.t("provider.connect.opencodeZen.line2")}</div> + <div class="text-14-regular text-text-base"> + {language.t("provider.connect.opencodeZen.line1")} + </div> + <div class="text-14-regular text-text-base"> + {language.t("provider.connect.opencodeZen.line2")} + </div> <div class="text-14-regular text-text-base"> {language.t("provider.connect.opencodeZen.visit.prefix")} <Link href="https://opencode.ai/zen" tabIndex={-1}> @@ -317,7 +321,9 @@ export function DialogConnectProvider(props: { provider: string }) { <div class="flex flex-col gap-6"> <div class="text-14-regular text-text-base"> {language.t("provider.connect.oauth.code.visit.prefix")} - <Link href={store.authorization!.url}>{language.t("provider.connect.oauth.code.visit.link")}</Link> + <Link href={store.authorization!.url}> + {language.t("provider.connect.oauth.code.visit.link")} + </Link> {language.t("provider.connect.oauth.code.visit.suffix", { provider: provider().name })} </div> <form onSubmit={handleSubmit} class="flex flex-col items-start gap-4"> @@ -367,7 +373,9 @@ export function DialogConnectProvider(props: { provider: string }) { <div class="flex flex-col gap-6"> <div class="text-14-regular text-text-base"> {language.t("provider.connect.oauth.auto.visit.prefix")} - <Link href={store.authorization!.url}>{language.t("provider.connect.oauth.auto.visit.link")}</Link> + <Link href={store.authorization!.url}> + {language.t("provider.connect.oauth.auto.visit.link")} + </Link> {language.t("provider.connect.oauth.auto.visit.suffix", { provider: provider().name })} </div> <TextField diff --git a/packages/app/src/components/dialog-select-model-unpaid.tsx b/packages/app/src/components/dialog-select-model-unpaid.tsx index 6ac1fa678..98cf57508 100644 --- a/packages/app/src/components/dialog-select-model-unpaid.tsx +++ b/packages/app/src/components/dialog-select-model-unpaid.tsx @@ -62,9 +62,9 @@ export const DialogSelectModelUnpaid: Component = () => { </div> <div class="px-1.5 pb-1.5"> <div class="w-full rounded-sm border border-border-weak-base bg-surface-raised-base"> - <div class="w-full flex flex-col items-start gap-4 px-1.5 pt-4 pb-4"> + <div class="w-full flex flex-col items-start gap-4 px-1.5 pt-4 pb-4"> <div class="px-2 text-14-medium text-text-base">{language.t("dialog.model.unpaid.addMore.title")}</div> - <div class="w-full"> + <div class="w-full"> <List class="w-full px-0" key={(x) => x?.id} diff --git a/packages/app/src/components/dialog-select-server.tsx b/packages/app/src/components/dialog-select-server.tsx index 9b401afbd..bb0ad5b43 100644 --- a/packages/app/src/components/dialog-select-server.tsx +++ b/packages/app/src/components/dialog-select-server.tsx @@ -200,9 +200,7 @@ export function DialogSelectServer() { <div class="mt-6 px-3 flex flex-col gap-1.5"> <div class="px-3"> <h3 class="text-14-regular text-text-weak">{language.t("dialog.server.default.title")}</h3> - <p class="text-12-regular text-text-weak mt-1"> - {language.t("dialog.server.default.description")} - </p> + <p class="text-12-regular text-text-weak mt-1">{language.t("dialog.server.default.description")}</p> </div> <div class="flex items-center gap-2 px-3 py-2"> <Show @@ -210,7 +208,9 @@ export function DialogSelectServer() { fallback={ <Show when={server.url} - fallback={<span class="text-14-regular text-text-weak">{language.t("dialog.server.default.none")}</span>} + fallback={ + <span class="text-14-regular text-text-weak">{language.t("dialog.server.default.none")}</span> + } > <Button variant="secondary" diff --git a/packages/app/src/components/session/session-context-tab.tsx b/packages/app/src/components/session/session-context-tab.tsx index 3758dd6e8..b41578910 100644 --- a/packages/app/src/components/session/session-context-tab.tsx +++ b/packages/app/src/components/session/session-context-tab.tsx @@ -261,7 +261,10 @@ export function SessionContextTab(props: SessionContextTabProps) { value: `${number(c?.cacheRead)} / ${number(c?.cacheWrite)}`, }, { label: language.t("context.stats.userMessages"), value: count.user.toLocaleString(language.locale()) }, - { label: language.t("context.stats.assistantMessages"), value: count.assistant.toLocaleString(language.locale()) }, + { + label: language.t("context.stats.assistantMessages"), + value: count.assistant.toLocaleString(language.locale()), + }, { label: language.t("context.stats.totalCost"), value: cost() }, { label: language.t("context.stats.sessionCreated"), value: time(props.info()?.time.created) }, { label: language.t("context.stats.lastActivity"), value: time(c?.message.time.created) }, @@ -402,9 +405,7 @@ export function SessionContextTab(props: SessionContextTabProps) { )} </For> </div> - <div class="hidden text-11-regular text-text-weaker"> - {language.t("context.breakdown.note")} - </div> + <div class="hidden text-11-regular text-text-weaker">{language.t("context.breakdown.note")}</div> </div> </Show> diff --git a/packages/app/src/components/session/session-header.tsx b/packages/app/src/components/session/session-header.tsx index 66221fd42..1bdbbb6a0 100644 --- a/packages/app/src/components/session/session-header.tsx +++ b/packages/app/src/components/session/session-header.tsx @@ -183,7 +183,10 @@ export function SessionHeader() { }} aria-hidden={!showReview()} > - <TooltipKeybind title={language.t("command.review.toggle")} keybind={command.keybind("review.toggle")}> + <TooltipKeybind + title={language.t("command.review.toggle")} + keybind={command.keybind("review.toggle")} + > <Button variant="ghost" class="group/review-toggle size-6 p-0" diff --git a/packages/app/src/components/settings-general.tsx b/packages/app/src/components/settings-general.tsx index 5f3519a74..c356b269b 100644 --- a/packages/app/src/components/settings-general.tsx +++ b/packages/app/src/components/settings-general.tsx @@ -15,13 +15,11 @@ export const SettingsGeneral: Component = () => { Object.entries(theme.themes()).map(([id, def]) => ({ id, name: def.name ?? id })), ) - const colorSchemeOptions = createMemo( - (): { value: ColorScheme; label: string }[] => [ - { value: "system", label: language.t("theme.scheme.system") }, - { value: "light", label: language.t("theme.scheme.light") }, - { value: "dark", label: language.t("theme.scheme.dark") }, - ], - ) + const colorSchemeOptions = createMemo((): { value: ColorScheme; label: string }[] => [ + { value: "system", label: language.t("theme.scheme.system") }, + { value: "light", label: language.t("theme.scheme.light") }, + { value: "dark", label: language.t("theme.scheme.dark") }, + ]) const languageOptions = createMemo(() => language.locales.map((locale) => ({ @@ -107,7 +105,7 @@ export const SettingsGeneral: Component = () => { title={language.t("settings.general.row.theme.title")} description={ <> - {language.t("settings.general.row.theme.description")} {" "} + {language.t("settings.general.row.theme.description")}{" "} <a href="#" class="text-text-interactive-base"> {language.t("common.learnMore")} </a> diff --git a/packages/app/src/context/global-sync.tsx b/packages/app/src/context/global-sync.tsx index 1738cb38b..18eacbd60 100644 --- a/packages/app/src/context/global-sync.tsx +++ b/packages/app/src/context/global-sync.tsx @@ -658,10 +658,7 @@ function createGlobalSync() { .then((x) => x.data) .catch(() => undefined) if (!health?.healthy) { - setGlobalStore( - "error", - new Error(language.t("error.globalSync.connectFailed", { url: globalSDK.url })), - ) + setGlobalStore("error", new Error(language.t("error.globalSync.connectFailed", { url: globalSDK.url }))) return } diff --git a/packages/app/src/context/notification.tsx b/packages/app/src/context/notification.tsx index 579c36999..976f6e5c0 100644 --- a/packages/app/src/context/notification.tsx +++ b/packages/app/src/context/notification.tsx @@ -96,7 +96,11 @@ export const { use: useNotification, provider: NotificationProvider } = createSi const href = `/${base64Encode(directory)}/session/${sessionID}` if (settings.notifications.agent()) { - void platform.notify(language.t("notification.session.responseReady.title"), session?.title ?? sessionID, href) + void platform.notify( + language.t("notification.session.responseReady.title"), + session?.title ?? sessionID, + href, + ) } break } @@ -117,7 +121,8 @@ export const { use: useNotification, provider: NotificationProvider } = createSi error, }) const description = - session?.title ?? (typeof error === "string" ? error : language.t("notification.session.error.fallbackDescription")) + session?.title ?? + (typeof error === "string" ? error : language.t("notification.session.error.fallbackDescription")) const href = sessionID ? `/${base64Encode(directory)}/session/${sessionID}` : `/${base64Encode(directory)}` if (settings.notifications.errors()) { void platform.notify(language.t("notification.session.error.title"), description, href) diff --git a/packages/app/src/entry.tsx b/packages/app/src/entry.tsx index c366ad27f..a375a7ac6 100644 --- a/packages/app/src/entry.tsx +++ b/packages/app/src/entry.tsx @@ -19,7 +19,7 @@ if (import.meta.env.DEV && !(root instanceof HTMLElement)) { })() const key = "error.dev.rootNotFound" as const - const message = locale === "zh" ? zh[key] ?? en[key] : en[key] + const message = locale === "zh" ? (zh[key] ?? en[key]) : en[key] throw new Error(message) } diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts index 5db336330..992685909 100644 --- a/packages/app/src/i18n/en.ts +++ b/packages/app/src/i18n/en.ts @@ -144,7 +144,7 @@ export const dict = { "common.attachment": "attachment", "prompt.placeholder.shell": "Enter shell command...", - "prompt.placeholder.normal": "Ask anything... \"{{example}}\"", + "prompt.placeholder.normal": 'Ask anything... "{{example}}"', "prompt.mode.shell": "Shell", "prompt.mode.shell.exit": "esc to exit", @@ -219,7 +219,8 @@ export const dict = { "dialog.server.add.checking": "Checking...", "dialog.server.add.button": "Add", "dialog.server.default.title": "Default server", - "dialog.server.default.description": "Connect to this server on app launch instead of starting a local server. Requires restart.", + "dialog.server.default.description": + "Connect to this server on app launch instead of starting a local server. Requires restart.", "dialog.server.default.none": "No server selected", "dialog.server.default.set": "Set current server as default", "dialog.server.default.clear": "Clear", @@ -233,7 +234,7 @@ export const dict = { "dialog.project.edit.color": "Color", "context.breakdown.title": "Context Breakdown", - "context.breakdown.note": "Approximate breakdown of input tokens. \"Other\" includes tool definitions and overhead.", + "context.breakdown.note": 'Approximate breakdown of input tokens. "Other" includes tool definitions and overhead.', "context.breakdown.system": "System", "context.breakdown.user": "User", "context.breakdown.assistant": "Assistant", @@ -327,14 +328,14 @@ export const dict = { "error.chain.didYouMean": "Did you mean: {{suggestions}}", "error.chain.modelNotFound": "Model not found: {{provider}}/{{model}}", "error.chain.checkConfig": "Check your config (opencode.json) provider/model names", - "error.chain.mcpFailed": - "MCP server \"{{name}}\" failed. Note, OpenCode does not support MCP authentication yet.", + "error.chain.mcpFailed": 'MCP server "{{name}}" failed. Note, OpenCode does not support MCP authentication yet.', "error.chain.providerAuthFailed": "Provider authentication failed ({{provider}}): {{message}}", - "error.chain.providerInitFailed": "Failed to initialize provider \"{{provider}}\". Check credentials and configuration.", + "error.chain.providerInitFailed": + 'Failed to initialize provider "{{provider}}". Check credentials and configuration.', "error.chain.configJsonInvalid": "Config file at {{path}} is not valid JSON(C)", "error.chain.configJsonInvalidWithMessage": "Config file at {{path}} is not valid JSON(C): {{message}}", "error.chain.configDirectoryTypo": - "Directory \"{{dir}}\" in {{path}} is not valid. Rename the directory to \"{{suggestion}}\" or remove it. This is a common typo.", + 'Directory "{{dir}}" in {{path}} is not valid. Rename the directory to "{{suggestion}}" or remove it. This is a common typo.', "error.chain.configFrontmatterError": "Failed to parse frontmatter in {{path}}:\n{{message}}", "error.chain.configInvalid": "Config file at {{path}} is invalid", "error.chain.configInvalidWithMessage": "Config file at {{path}} is invalid: {{message}}", @@ -374,8 +375,10 @@ export const dict = { "session.header.search.placeholder": "Search {{project}}", "session.share.popover.title": "Publish on web", - "session.share.popover.description.shared": "This session is public on the web. It is accessible to anyone with the link.", - "session.share.popover.description.unshared": "Share session publicly on the web. It will be accessible to anyone with the link.", + "session.share.popover.description.shared": + "This session is public on the web. It is accessible to anyone with the link.", + "session.share.popover.description.unshared": + "Share session publicly on the web. It will be accessible to anyone with the link.", "session.share.action.share": "Share", "session.share.action.publish": "Publish", "session.share.action.publishing": "Publishing...", @@ -433,7 +436,8 @@ export const dict = { "settings.general.row.font.description": "Customise the mono font used in code blocks", "settings.general.notifications.agent.title": "Agent", - "settings.general.notifications.agent.description": "Show system notification when the agent is complete or needs attention", + "settings.general.notifications.agent.description": + "Show system notification when the agent is complete or needs attention", "settings.general.notifications.permissions.title": "Permissions", "settings.general.notifications.permissions.description": "Show system notification when a permission is required", "settings.general.notifications.errors.title": "Errors", @@ -530,10 +534,10 @@ export const dict = { "workspace.status.clean": "No unmerged changes detected.", "workspace.status.dirty": "Unmerged changes detected in this workspace.", "workspace.delete.title": "Delete workspace", - "workspace.delete.confirm": "Delete workspace \"{{name}}\"?", + "workspace.delete.confirm": 'Delete workspace "{{name}}"?', "workspace.delete.button": "Delete workspace", "workspace.reset.title": "Reset workspace", - "workspace.reset.confirm": "Reset workspace \"{{name}}\"?", + "workspace.reset.confirm": 'Reset workspace "{{name}}"?', "workspace.reset.button": "Reset workspace", "workspace.reset.archived.none": "No active sessions will be archived.", "workspace.reset.archived.one": "1 session will be archived.", diff --git a/packages/app/src/i18n/zh.ts b/packages/app/src/i18n/zh.ts index bd809bdb9..ace06f3db 100644 --- a/packages/app/src/i18n/zh.ts +++ b/packages/app/src/i18n/zh.ts @@ -108,7 +108,8 @@ export const dict = { "provider.connect.status.inProgress": "正在授权...", "provider.connect.status.waiting": "等待授权...", "provider.connect.status.failed": "授权失败: {{error}}", - "provider.connect.apiKey.description": "输入你的 {{provider}} API 密钥以连接帐户,并在 OpenCode 中使用 {{provider}} 模型。", + "provider.connect.apiKey.description": + "输入你的 {{provider}} API 密钥以连接帐户,并在 OpenCode 中使用 {{provider}} 模型。", "provider.connect.apiKey.label": "{{provider}} API 密钥", "provider.connect.apiKey.placeholder": "API 密钥", "provider.connect.apiKey.required": "API 密钥为必填项", @@ -143,7 +144,7 @@ export const dict = { "common.attachment": "附件", "prompt.placeholder.shell": "输入 shell 命令...", - "prompt.placeholder.normal": "随便问点什么... \"{{example}}\"", + "prompt.placeholder.normal": '随便问点什么... "{{example}}"', "prompt.mode.shell": "Shell", "prompt.mode.shell.exit": "按 esc 退出", @@ -325,12 +326,13 @@ export const dict = { "error.chain.didYouMean": "你是不是想输入: {{suggestions}}", "error.chain.modelNotFound": "未找到模型: {{provider}}/{{model}}", "error.chain.checkConfig": "请检查你的配置 (opencode.json) 中的 provider/model 名称", - "error.chain.mcpFailed": "MCP 服务器 \"{{name}}\" 启动失败。注意: OpenCode 暂不支持 MCP 认证。", + "error.chain.mcpFailed": 'MCP 服务器 "{{name}}" 启动失败。注意: OpenCode 暂不支持 MCP 认证。', "error.chain.providerAuthFailed": "提供商认证失败 ({{provider}}): {{message}}", - "error.chain.providerInitFailed": "无法初始化提供商 \"{{provider}}\"。请检查凭据和配置。", + "error.chain.providerInitFailed": '无法初始化提供商 "{{provider}}"。请检查凭据和配置。', "error.chain.configJsonInvalid": "配置文件 {{path}} 不是有效的 JSON(C)", "error.chain.configJsonInvalidWithMessage": "配置文件 {{path}} 不是有效的 JSON(C): {{message}}", - "error.chain.configDirectoryTypo": "{{path}} 中的目录 \"{{dir}}\" 无效。请将目录重命名为 \"{{suggestion}}\" 或移除它。这是一个常见拼写错误。", + "error.chain.configDirectoryTypo": + '{{path}} 中的目录 "{{dir}}" 无效。请将目录重命名为 "{{suggestion}}" 或移除它。这是一个常见拼写错误。', "error.chain.configFrontmatterError": "无法解析 {{path}} 中的 frontmatter:\n{{message}}", "error.chain.configInvalid": "配置文件 {{path}} 无效", "error.chain.configInvalidWithMessage": "配置文件 {{path}} 无效: {{message}}", @@ -526,10 +528,10 @@ export const dict = { "workspace.status.clean": "未检测到未合并的更改。", "workspace.status.dirty": "检测到未合并的更改。", "workspace.delete.title": "删除工作区", - "workspace.delete.confirm": "删除工作区 \"{{name}}\"?", + "workspace.delete.confirm": '删除工作区 "{{name}}"?', "workspace.delete.button": "删除工作区", "workspace.reset.title": "重置工作区", - "workspace.reset.confirm": "重置工作区 \"{{name}}\"?", + "workspace.reset.confirm": '重置工作区 "{{name}}"?', "workspace.reset.button": "重置工作区", "workspace.reset.archived.none": "不会归档任何活跃会话。", "workspace.reset.archived.one": "将归档 1 个会话。", diff --git a/packages/app/src/pages/error.tsx b/packages/app/src/pages/error.tsx index 460c87295..6d6faf6fa 100644 --- a/packages/app/src/pages/error.tsx +++ b/packages/app/src/pages/error.tsx @@ -78,9 +78,10 @@ function formatInitError(error: InitError, t: Translator): string { suggestions?: string[] } - const suggestionsLine = Array.isArray(suggestions) && suggestions.length - ? [t("error.chain.didYouMean", { suggestions: suggestions.join(", ") })] - : [] + const suggestionsLine = + Array.isArray(suggestions) && suggestions.length + ? [t("error.chain.didYouMean", { suggestions: suggestions.join(", ") })] + : [] return [ t("error.chain.modelNotFound", { provider: providerID, model: modelID }), @@ -253,7 +254,9 @@ export const ErrorPage: Component<ErrorPageProps> = (props) => { when={store.version} fallback={ <Button size="large" variant="ghost" onClick={checkForUpdates} disabled={store.checking}> - {store.checking ? language.t("error.page.action.checking") : language.t("error.page.action.checkUpdates")} + {store.checking + ? language.t("error.page.action.checking") + : language.t("error.page.action.checkUpdates")} </Button> } > diff --git a/packages/app/src/pages/home.tsx b/packages/app/src/pages/home.tsx index efed2e658..4007129b5 100644 --- a/packages/app/src/pages/home.tsx +++ b/packages/app/src/pages/home.tsx @@ -76,13 +76,13 @@ export default function Home() { </Button> <Switch> <Match when={sync.data.project.length > 0}> - <div class="mt-20 w-full flex flex-col gap-4"> - <div class="flex gap-2 items-center justify-between pl-3"> - <div class="text-14-medium text-text-strong">{language.t("home.recentProjects")}</div> - <Button icon="folder-add-left" size="normal" class="pl-2 pr-3" onClick={chooseProject}> - {language.t("command.project.open")} - </Button> - </div> + <div class="mt-20 w-full flex flex-col gap-4"> + <div class="flex gap-2 items-center justify-between pl-3"> + <div class="text-14-medium text-text-strong">{language.t("home.recentProjects")}</div> + <Button icon="folder-add-left" size="normal" class="pl-2 pr-3" onClick={chooseProject}> + {language.t("command.project.open")} + </Button> + </div> <ul class="flex flex-col gap-2"> <For each={sync.data.project diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index 2cbc97a55..172ae7174 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -1909,9 +1909,9 @@ export default function Layout(props: ParentProps) { trigger={trigger} onOpenChange={setOpen} > - <div class="-m-3 p-2 flex flex-col w-72"> - <div class="px-4 pt-2 pb-1 text-14-medium text-text-strong truncate">{displayName(props.project)}</div> - <div class="px-4 pb-2 text-12-medium text-text-weak">{language.t("sidebar.project.recentSessions")}</div> + <div class="-m-3 p-2 flex flex-col w-72"> + <div class="px-4 pt-2 pb-1 text-14-medium text-text-strong truncate">{displayName(props.project)}</div> + <div class="px-4 pb-2 text-12-medium text-text-weak">{language.t("sidebar.project.recentSessions")}</div> <div class="px-2 pb-2 flex flex-col gap-2"> <Show when={workspaceEnabled()} @@ -2177,22 +2177,22 @@ export default function Layout(props: ParentProps) { class="shrink-0 size-6 rounded-md opacity-0 group-hover/project:opacity-100 data-[expanded]:opacity-100 data-[expanded]:bg-surface-base-active" /> <DropdownMenu.Portal> - <DropdownMenu.Content class="mt-1"> - <DropdownMenu.Item onSelect={() => dialog.show(() => <DialogEditProject project={p} />)}> + <DropdownMenu.Content class="mt-1"> + <DropdownMenu.Item onSelect={() => dialog.show(() => <DialogEditProject project={p} />)}> <DropdownMenu.ItemLabel>{language.t("common.edit")}</DropdownMenu.ItemLabel> - </DropdownMenu.Item> - <DropdownMenu.Item onSelect={() => layout.sidebar.toggleWorkspaces(p.worktree)}> - <DropdownMenu.ItemLabel> + </DropdownMenu.Item> + <DropdownMenu.Item onSelect={() => layout.sidebar.toggleWorkspaces(p.worktree)}> + <DropdownMenu.ItemLabel> {layout.sidebar.workspaces(p.worktree)() ? language.t("sidebar.workspaces.disable") : language.t("sidebar.workspaces.enable")} - </DropdownMenu.ItemLabel> - </DropdownMenu.Item> - <DropdownMenu.Separator /> - <DropdownMenu.Item onSelect={() => closeProject(p.worktree)}> + </DropdownMenu.ItemLabel> + </DropdownMenu.Item> + <DropdownMenu.Separator /> + <DropdownMenu.Item onSelect={() => closeProject(p.worktree)}> <DropdownMenu.ItemLabel>{language.t("common.close")}</DropdownMenu.ItemLabel> - </DropdownMenu.Item> - </DropdownMenu.Content> + </DropdownMenu.Item> + </DropdownMenu.Content> </DropdownMenu.Portal> </DropdownMenu> </div> diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx index ebc6b8c23..562176c1b 100644 --- a/packages/app/src/pages/session.tsx +++ b/packages/app/src/pages/session.tsx @@ -673,14 +673,14 @@ export default function Page() { }, ...(sync.data.config.share !== "disabled" ? [ - { - id: "session.share", - title: language.t("command.session.share"), - description: language.t("command.session.share.description"), - category: language.t("command.category.session"), - slash: "share", - disabled: !params.id || !!info()?.share?.url, - onSelect: async () => { + { + id: "session.share", + title: language.t("command.session.share"), + description: language.t("command.session.share.description"), + category: language.t("command.category.session"), + slash: "share", + disabled: !params.id || !!info()?.share?.url, + onSelect: async () => { if (!params.id) return await sdk.client.session .share({ sessionID: params.id }) @@ -708,14 +708,14 @@ export default function Page() { ) }, }, - { - id: "session.unshare", - title: language.t("command.session.unshare"), - description: language.t("command.session.unshare.description"), - category: language.t("command.category.session"), - slash: "unshare", - disabled: !params.id || !info()?.share?.url, - onSelect: async () => { + { + id: "session.unshare", + title: language.t("command.session.unshare"), + description: language.t("command.session.unshare.description"), + category: language.t("command.category.session"), + slash: "unshare", + disabled: !params.id || !info()?.share?.url, + onSelect: async () => { if (!params.id) return await sdk.client.session .unshare({ sessionID: params.id }) @@ -1262,7 +1262,9 @@ export default function Page() { <Show when={diffsReady()} fallback={ - <div class="px-4 py-4 text-text-weak">{language.t("session.review.loadingChanges")}</div> + <div class="px-4 py-4 text-text-weak"> + {language.t("session.review.loadingChanges")} + </div> } > <SessionReviewTab @@ -1283,13 +1285,15 @@ export default function Page() { </Show> </Match> <Match when={true}> - <div class="h-full px-4 pb-30 flex flex-col items-center justify-center text-center gap-6"> - <Mark class="w-14 opacity-10" /> - <div class="text-14-regular text-text-weak max-w-56">{language.t("session.review.empty")}</div> + <div class="h-full px-4 pb-30 flex flex-col items-center justify-center text-center gap-6"> + <Mark class="w-14 opacity-10" /> + <div class="text-14-regular text-text-weak max-w-56"> + {language.t("session.review.empty")} </div> - </Match> - </Switch> - </div> + </div> + </Match> + </Switch> + </div> } > <div class="relative w-full h-full min-w-0"> @@ -1502,11 +1506,11 @@ export default function Page() { <Show when={diffs()}> <DiffChanges changes={diffs()} variant="bars" /> </Show> - <div class="flex items-center gap-1.5"> - <div>{language.t("session.tab.review")}</div> - <Show when={info()?.summary?.files}> - <div class="text-12-medium text-text-strong h-4 px-2 flex flex-col items-center justify-center rounded-full bg-surface-base"> - {info()?.summary?.files ?? 0} + <div class="flex items-center gap-1.5"> + <div>{language.t("session.tab.review")}</div> + <Show when={info()?.summary?.files}> + <div class="text-12-medium text-text-strong h-4 px-2 flex flex-col items-center justify-center rounded-full bg-surface-base"> + {info()?.summary?.files ?? 0} </div> </Show> </div> @@ -1558,7 +1562,9 @@ export default function Page() { <Show when={diffsReady()} fallback={ - <div class="px-6 py-4 text-text-weak">{language.t("session.review.loadingChanges")}</div> + <div class="px-6 py-4 text-text-weak"> + {language.t("session.review.loadingChanges")} + </div> } > <SessionReviewTab @@ -1575,13 +1581,15 @@ export default function Page() { </Show> </Match> <Match when={true}> - <div class="h-full px-6 pb-30 flex flex-col items-center justify-center text-center gap-6"> - <Mark class="w-14 opacity-10" /> - <div class="text-14-regular text-text-weak max-w-56">{language.t("session.review.empty")}</div> + <div class="h-full px-6 pb-30 flex flex-col items-center justify-center text-center gap-6"> + <Mark class="w-14 opacity-10" /> + <div class="text-14-regular text-text-weak max-w-56"> + {language.t("session.review.empty")} </div> - </Match> - </Switch> - </div> + </div> + </Match> + </Switch> + </div> </Show> </Tabs.Content> </Show> @@ -1871,13 +1879,15 @@ export default function Page() { </div> )} </For> - <div class="flex-1" /> - <div class="text-text-weak pr-2">{language.t("common.loading")}...</div> + <div class="flex-1" /> + <div class="text-text-weak pr-2">{language.t("common.loading")}...</div> + </div> + <div class="flex-1 flex items-center justify-center text-text-weak"> + {language.t("terminal.loading")} + </div> </div> - <div class="flex-1 flex items-center justify-center text-text-weak">{language.t("terminal.loading")}</div> - </div> - } - > + } + > <DragDropProvider onDragStart={handleTerminalDragStart} onDragEnd={handleTerminalDragEnd} diff --git a/packages/enterprise/src/app.tsx b/packages/enterprise/src/app.tsx index 1d408ac94..6f9cdcafb 100644 --- a/packages/enterprise/src/app.tsx +++ b/packages/enterprise/src/app.tsx @@ -57,7 +57,7 @@ function detectLocale() { function UiI18nBridge(props: ParentProps) { const locale = createMemo(() => detectLocale()) const t = (key: keyof typeof uiEn, params?: UiI18nParams) => { - const value = locale() === "zh" ? uiZh[key] ?? uiEn[key] : uiEn[key] + const value = locale() === "zh" ? (uiZh[key] ?? uiEn[key]) : uiEn[key] const text = value ?? String(key) return resolveTemplate(text, params) } diff --git a/packages/ui/src/components/list.tsx b/packages/ui/src/components/list.tsx index d81440c11..066363502 100644 --- a/packages/ui/src/components/list.tsx +++ b/packages/ui/src/components/list.tsx @@ -228,9 +228,7 @@ export function List<T>(props: ListProps<T> & { ref?: (ref: ListRef) => void }) when={flat().length > 0} fallback={ <div data-slot="list-empty-state"> - <div data-slot="list-message"> - {emptyMessage()} - </div> + <div data-slot="list-message">{emptyMessage()}</div> </div> } > diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx index 8e2a36885..340c13745 100644 --- a/packages/ui/src/components/message-part.tsx +++ b/packages/ui/src/components/message-part.tsx @@ -417,7 +417,11 @@ export function UserMessageDisplay(props: { message: UserMessage; parts: PartTyp <Icon name="chevron-down" size="small" /> </button> <div data-slot="user-message-copy-wrapper"> - <Tooltip value={copied() ? i18n.t("ui.message.copied") : i18n.t("ui.message.copy")} placement="top" gutter={8}> + <Tooltip + value={copied() ? i18n.t("ui.message.copied") : i18n.t("ui.message.copy")} + placement="top" + gutter={8} + > <IconButton icon={copied() ? "check" : "copy"} variant="secondary" diff --git a/specs/06-app-i18n-audit.md b/specs/06-app-i18n-audit.md index c4c735226..0362ec212 100644 --- a/specs/06-app-i18n-audit.md +++ b/specs/06-app-i18n-audit.md @@ -163,6 +163,7 @@ Completed (2026-01-20): ### 15) File Load Failure Toast (Duplicate) Files: + - `packages/app/src/context/file.tsx` - `packages/app/src/context/local.tsx` @@ -220,13 +221,17 @@ Also reuse existing command keys for tooltip titles whenever possible (e.g. `com ## Appendix: Remaining Files At-a-Glance Pages: + - (none) Components: + - (none) Context: + - (none) Utils: + - (none) diff --git a/specs/07-ui-i18n-audit.md b/specs/07-ui-i18n-audit.md index 26bc552bb..e3c746867 100644 --- a/specs/07-ui-i18n-audit.md +++ b/specs/07-ui-i18n-audit.md @@ -27,7 +27,7 @@ Why this is the best long-term shape: ### Proposed Architecture -1) **UI provides an i18n context (no persistence)** +1. **UI provides an i18n context (no persistence)** - Add `packages/ui/src/context/i18n.tsx`: - Exports `I18nProvider` and `useI18n()`. @@ -36,14 +36,14 @@ Why this is the best long-term shape: - `locale()` accessor for locale-sensitive formatting (Luxon/Intl). - Context should have a safe default (English) so UI components can render even if a consumer forgets the provider. -2) **UI owns UI strings (dictionaries live in UI)** +2. **UI owns UI strings (dictionaries live in UI)** - Add `packages/ui/src/i18n/en.ts` and `packages/ui/src/i18n/zh.ts`. - Export them from `@opencode-ai/ui` via `packages/ui/package.json` exports (e.g. `"./i18n/*": "./src/i18n/*.ts"`). - Use a clear namespace prefix for all UI keys to avoid collisions: - Recommended: `ui.*` (e.g. `ui.sessionReview.title`). -3) **Consumers merge dictionaries and provide `t`/`locale` once** +3. **Consumers merge dictionaries and provide `t`/`locale` once** - `packages/app/`: - Keep `packages/app/src/context/language.tsx` as the source of truth for locale selection/persistence. |
