From f51bd28ed8f933364228979f6130206027f3061f Mon Sep 17 00:00:00 2001 From: Dax Raad Date: Fri, 30 Jan 2026 15:43:29 -0500 Subject: [PATCH 01/40] ci: increase ARM runner to 8 vCPUs for faster Tauri builds --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3974d23ff..a1b492258 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -103,7 +103,7 @@ jobs: target: x86_64-pc-windows-msvc - host: blacksmith-4vcpu-ubuntu-2404 target: x86_64-unknown-linux-gnu - - host: blacksmith-4vcpu-ubuntu-2404-arm + - host: blacksmith-8vcpu-ubuntu-2404-arm target: aarch64-unknown-linux-gnu runs-on: ${{ matrix.settings.host }} steps: From 4a56491e42c07e30b95238a06c9b9175e4763444 Mon Sep 17 00:00:00 2001 From: Ryan Vogel Date: Fri, 30 Jan 2026 15:57:01 -0500 Subject: [PATCH 02/40] fix(provider): exclude chat models from textVerbosity setting (#11363) --- packages/opencode/src/provider/transform.ts | 3 + .../opencode/test/provider/transform.test.ts | 72 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts index 6ca089c2f..dcc2605ab 100644 --- a/packages/opencode/src/provider/transform.ts +++ b/packages/opencode/src/provider/transform.ts @@ -594,9 +594,12 @@ export namespace ProviderTransform { result["reasoningEffort"] = "medium" } + // Only set textVerbosity for non-chat gpt-5.x models + // Chat models (e.g. gpt-5.2-chat-latest) only support "medium" verbosity if ( input.model.api.id.includes("gpt-5.") && !input.model.api.id.includes("codex") && + !input.model.api.id.includes("-chat") && input.model.providerID !== "azure" ) { result["textVerbosity"] = "low" diff --git a/packages/opencode/test/provider/transform.test.ts b/packages/opencode/test/provider/transform.test.ts index 1d69a2a29..b818ab98c 100644 --- a/packages/opencode/test/provider/transform.test.ts +++ b/packages/opencode/test/provider/transform.test.ts @@ -103,6 +103,78 @@ describe("ProviderTransform.options - setCacheKey", () => { }) }) +describe("ProviderTransform.options - gpt-5 textVerbosity", () => { + const sessionID = "test-session-123" + + const createGpt5Model = (apiId: string) => + ({ + id: `openai/${apiId}`, + providerID: "openai", + api: { + id: apiId, + url: "https://api.openai.com", + npm: "@ai-sdk/openai", + }, + name: apiId, + capabilities: { + temperature: true, + reasoning: true, + attachment: true, + toolcall: true, + input: { text: true, audio: false, image: true, video: false, pdf: false }, + output: { text: true, audio: false, image: false, video: false, pdf: false }, + interleaved: false, + }, + cost: { input: 0.03, output: 0.06, cache: { read: 0.001, write: 0.002 } }, + limit: { context: 128000, output: 4096 }, + status: "active", + options: {}, + headers: {}, + }) as any + + test("gpt-5.2 should have textVerbosity set to low", () => { + const model = createGpt5Model("gpt-5.2") + const result = ProviderTransform.options({ model, sessionID, providerOptions: {} }) + expect(result.textVerbosity).toBe("low") + }) + + test("gpt-5.1 should have textVerbosity set to low", () => { + const model = createGpt5Model("gpt-5.1") + const result = ProviderTransform.options({ model, sessionID, providerOptions: {} }) + expect(result.textVerbosity).toBe("low") + }) + + test("gpt-5.2-chat-latest should NOT have textVerbosity set (only supports medium)", () => { + const model = createGpt5Model("gpt-5.2-chat-latest") + const result = ProviderTransform.options({ model, sessionID, providerOptions: {} }) + expect(result.textVerbosity).toBeUndefined() + }) + + test("gpt-5.1-chat-latest should NOT have textVerbosity set (only supports medium)", () => { + const model = createGpt5Model("gpt-5.1-chat-latest") + const result = ProviderTransform.options({ model, sessionID, providerOptions: {} }) + expect(result.textVerbosity).toBeUndefined() + }) + + test("gpt-5.2-chat should NOT have textVerbosity set", () => { + const model = createGpt5Model("gpt-5.2-chat") + const result = ProviderTransform.options({ model, sessionID, providerOptions: {} }) + expect(result.textVerbosity).toBeUndefined() + }) + + test("gpt-5-chat should NOT have textVerbosity set", () => { + const model = createGpt5Model("gpt-5-chat") + const result = ProviderTransform.options({ model, sessionID, providerOptions: {} }) + expect(result.textVerbosity).toBeUndefined() + }) + + test("gpt-5.2-codex should NOT have textVerbosity set (codex models excluded)", () => { + const model = createGpt5Model("gpt-5.2-codex") + const result = ProviderTransform.options({ model, sessionID, providerOptions: {} }) + expect(result.textVerbosity).toBeUndefined() + }) +}) + describe("ProviderTransform.maxOutputTokens", () => { test("returns 32k when modelLimit > 32k", () => { const modelLimit = 100000 From 77fa8ddc8828b5ebcc306621e6669c192d1492fe Mon Sep 17 00:00:00 2001 From: Filip <34747899+neriousy@users.noreply.github.com> Date: Fri, 30 Jan 2026 21:59:37 +0100 Subject: [PATCH 03/40] refactor(app): refactored tests + added project tests (#11349) --- packages/app/e2e/actions.ts | 160 ++++++++++++++++++ packages/app/e2e/app/navigation.spec.ts | 3 +- packages/app/e2e/app/palette.spec.ts | 8 +- packages/app/e2e/app/session.spec.ts | 2 +- packages/app/e2e/app/titlebar-history.spec.ts | 10 +- packages/app/e2e/files/file-open.spec.ts | 7 +- packages/app/e2e/files/file-viewer.spec.ts | 7 +- packages/app/e2e/fixtures.ts | 63 ++----- packages/app/e2e/models/model-picker.spec.ts | 2 +- .../app/e2e/models/models-visibility.spec.ts | 33 +--- .../app/e2e/projects/project-edit.spec.ts | 47 +++++ .../app/e2e/projects/projects-close.spec.ts | 77 +++++++++ .../app/e2e/projects/projects-switch.spec.ts | 34 ++++ packages/app/e2e/prompt/context.spec.ts | 2 +- .../app/e2e/prompt/prompt-mention.spec.ts | 2 +- .../app/e2e/prompt/prompt-slash-open.spec.ts | 2 +- packages/app/e2e/prompt/prompt.spec.ts | 8 +- packages/app/e2e/selectors.ts | 17 ++ .../e2e/settings/settings-language.spec.ts | 17 +- .../e2e/settings/settings-providers.spec.ts | 34 +--- packages/app/e2e/settings/settings.spec.ts | 36 +--- .../e2e/sidebar/sidebar-session-links.spec.ts | 10 +- packages/app/e2e/sidebar/sidebar.spec.ts | 19 +-- .../app/e2e/terminal/terminal-init.spec.ts | 3 +- packages/app/e2e/terminal/terminal.spec.ts | 3 +- packages/app/e2e/thinking-level.spec.ts | 2 +- packages/app/e2e/tsconfig.json | 2 +- packages/app/e2e/utils.ts | 6 - packages/app/src/pages/layout.tsx | 14 +- 29 files changed, 409 insertions(+), 221 deletions(-) create mode 100644 packages/app/e2e/actions.ts create mode 100644 packages/app/e2e/projects/project-edit.spec.ts create mode 100644 packages/app/e2e/projects/projects-close.spec.ts create mode 100644 packages/app/e2e/projects/projects-switch.spec.ts create mode 100644 packages/app/e2e/selectors.ts diff --git a/packages/app/e2e/actions.ts b/packages/app/e2e/actions.ts new file mode 100644 index 000000000..3da16d317 --- /dev/null +++ b/packages/app/e2e/actions.ts @@ -0,0 +1,160 @@ +import { expect, type Locator, type Page } from "@playwright/test" +import fs from "node:fs/promises" +import os from "node:os" +import path from "node:path" +import { execSync } from "node:child_process" +import { modKey, serverUrl } from "./utils" + +export async function defocus(page: Page) { + await page.mouse.click(5, 5) +} + +export async function openPalette(page: Page) { + await defocus(page) + await page.keyboard.press(`${modKey}+P`) + + const dialog = page.getByRole("dialog") + await expect(dialog).toBeVisible() + await expect(dialog.getByRole("textbox").first()).toBeVisible() + return dialog +} + +export async function closeDialog(page: Page, dialog: Locator) { + await page.keyboard.press("Escape") + const closed = await dialog + .waitFor({ state: "detached", timeout: 1500 }) + .then(() => true) + .catch(() => false) + + if (closed) return + + await page.keyboard.press("Escape") + const closedSecond = await dialog + .waitFor({ state: "detached", timeout: 1500 }) + .then(() => true) + .catch(() => false) + + if (closedSecond) return + + await page.locator('[data-component="dialog-overlay"]').click({ position: { x: 5, y: 5 } }) + await expect(dialog).toHaveCount(0) +} + +export async function isSidebarClosed(page: Page) { + const main = page.locator("main") + const classes = (await main.getAttribute("class")) ?? "" + return classes.includes("xl:border-l") +} + +export async function toggleSidebar(page: Page) { + await defocus(page) + await page.keyboard.press(`${modKey}+B`) +} + +export async function openSidebar(page: Page) { + if (!(await isSidebarClosed(page))) return + await toggleSidebar(page) + await expect(page.locator("main")).not.toHaveClass(/xl:border-l/) +} + +export async function closeSidebar(page: Page) { + if (await isSidebarClosed(page)) return + await toggleSidebar(page) + await expect(page.locator("main")).toHaveClass(/xl:border-l/) +} + +export async function openSettings(page: Page) { + await defocus(page) + + const dialog = page.getByRole("dialog") + await page.keyboard.press(`${modKey}+Comma`).catch(() => undefined) + + const opened = await dialog + .waitFor({ state: "visible", timeout: 3000 }) + .then(() => true) + .catch(() => false) + + if (opened) return dialog + + await page.getByRole("button", { name: "Settings" }).first().click() + await expect(dialog).toBeVisible() + return dialog +} + +export async function seedProjects(page: Page, input: { directory: string; extra?: string[] }) { + await page.addInitScript( + (args: { directory: string; serverUrl: string; extra: string[] }) => { + const key = "opencode.global.dat:server" + const raw = localStorage.getItem(key) + const parsed = (() => { + if (!raw) return undefined + try { + return JSON.parse(raw) as unknown + } catch { + return undefined + } + })() + + const store = parsed && typeof parsed === "object" ? (parsed as Record) : {} + const list = Array.isArray(store.list) ? store.list : [] + const lastProject = store.lastProject && typeof store.lastProject === "object" ? store.lastProject : {} + const projects = store.projects && typeof store.projects === "object" ? store.projects : {} + const nextProjects = { ...(projects as Record) } + + const add = (origin: string, directory: string) => { + const current = nextProjects[origin] + const items = Array.isArray(current) ? current : [] + const existing = items.filter( + (p): p is { worktree: string; expanded?: boolean } => + !!p && + typeof p === "object" && + "worktree" in p && + typeof (p as { worktree?: unknown }).worktree === "string", + ) + + if (existing.some((p) => p.worktree === directory)) return + nextProjects[origin] = [{ worktree: directory, expanded: true }, ...existing] + } + + const directories = [args.directory, ...args.extra] + for (const directory of directories) { + add("local", directory) + add(args.serverUrl, directory) + } + + localStorage.setItem( + key, + JSON.stringify({ + list, + projects: nextProjects, + lastProject, + }), + ) + }, + { directory: input.directory, serverUrl, extra: input.extra ?? [] }, + ) +} + +export async function createTestProject() { + const root = await fs.mkdtemp(path.join(os.tmpdir(), "opencode-e2e-project-")) + + await fs.writeFile(path.join(root, "README.md"), "# e2e\n") + + execSync("git init", { cwd: root, stdio: "ignore" }) + execSync("git add -A", { cwd: root, stdio: "ignore" }) + execSync('git -c user.name="e2e" -c user.email="e2e@example.com" commit -m "init" --allow-empty', { + cwd: root, + stdio: "ignore", + }) + + return root +} + +export async function cleanupTestProject(directory: string) { + await fs.rm(directory, { recursive: true, force: true }).catch(() => undefined) +} + +export function sessionIDFromUrl(url: string) { + const match = /\/session\/([^/?#]+)/.exec(url) + return match?.[1] +} diff --git a/packages/app/e2e/app/navigation.spec.ts b/packages/app/e2e/app/navigation.spec.ts index 0812ea018..328c950df 100644 --- a/packages/app/e2e/app/navigation.spec.ts +++ b/packages/app/e2e/app/navigation.spec.ts @@ -1,5 +1,6 @@ import { test, expect } from "../fixtures" -import { dirPath, promptSelector } from "../utils" +import { promptSelector } from "../selectors" +import { dirPath } from "../utils" test("project route redirects to /session", async ({ page, directory, slug }) => { await page.goto(dirPath(directory)) diff --git a/packages/app/e2e/app/palette.spec.ts b/packages/app/e2e/app/palette.spec.ts index 264b463bb..3ccfd7a92 100644 --- a/packages/app/e2e/app/palette.spec.ts +++ b/packages/app/e2e/app/palette.spec.ts @@ -1,14 +1,10 @@ import { test, expect } from "../fixtures" -import { modKey } from "../utils" +import { openPalette } from "../actions" test("search palette opens and closes", async ({ page, gotoSession }) => { await gotoSession() - await page.keyboard.press(`${modKey}+P`) - - const dialog = page.getByRole("dialog") - await expect(dialog).toBeVisible() - await expect(dialog.getByRole("textbox").first()).toBeVisible() + const dialog = await openPalette(page) await page.keyboard.press("Escape") await expect(dialog).toHaveCount(0) diff --git a/packages/app/e2e/app/session.spec.ts b/packages/app/e2e/app/session.spec.ts index 8d605f0c3..d35af7ef7 100644 --- a/packages/app/e2e/app/session.spec.ts +++ b/packages/app/e2e/app/session.spec.ts @@ -1,5 +1,5 @@ import { test, expect } from "../fixtures" -import { promptSelector } from "../utils" +import { promptSelector } from "../selectors" test("can open an existing session and type into the prompt", async ({ page, sdk, gotoSession }) => { const title = `e2e smoke ${Date.now()}` diff --git a/packages/app/e2e/app/titlebar-history.spec.ts b/packages/app/e2e/app/titlebar-history.spec.ts index 649e5e0dc..c7ff6566c 100644 --- a/packages/app/e2e/app/titlebar-history.spec.ts +++ b/packages/app/e2e/app/titlebar-history.spec.ts @@ -1,5 +1,6 @@ import { test, expect } from "../fixtures" -import { modKey, promptSelector } from "../utils" +import { openSidebar } from "../actions" +import { promptSelector } from "../selectors" test("titlebar back/forward navigates between sessions", async ({ page, slug, sdk, gotoSession }) => { await page.setViewportSize({ width: 1400, height: 800 }) @@ -14,12 +15,7 @@ test("titlebar back/forward navigates between sessions", async ({ page, slug, sd try { await gotoSession(one.id) - const main = page.locator("main") - const collapsed = ((await main.getAttribute("class")) ?? "").includes("xl:border-l") - if (collapsed) { - await page.keyboard.press(`${modKey}+B`) - await expect(main).not.toHaveClass(/xl:border-l/) - } + await openSidebar(page) const link = page.locator(`[data-session-id="${two.id}"] a`).first() await expect(link).toBeVisible() diff --git a/packages/app/e2e/files/file-open.spec.ts b/packages/app/e2e/files/file-open.spec.ts index e384f0b0d..dea35d25b 100644 --- a/packages/app/e2e/files/file-open.spec.ts +++ b/packages/app/e2e/files/file-open.spec.ts @@ -1,13 +1,10 @@ import { test, expect } from "../fixtures" -import { modKey } from "../utils" +import { openPalette } from "../actions" test("can open a file tab from the search palette", async ({ page, gotoSession }) => { await gotoSession() - await page.keyboard.press(`${modKey}+P`) - - const dialog = page.getByRole("dialog") - await expect(dialog).toBeVisible() + const dialog = await openPalette(page) const input = dialog.getByRole("textbox").first() await input.fill("package.json") diff --git a/packages/app/e2e/files/file-viewer.spec.ts b/packages/app/e2e/files/file-viewer.spec.ts index bed6d1d36..3dc0dead2 100644 --- a/packages/app/e2e/files/file-viewer.spec.ts +++ b/packages/app/e2e/files/file-viewer.spec.ts @@ -1,5 +1,5 @@ import { test, expect } from "../fixtures" -import { modKey } from "../utils" +import { openPalette } from "../actions" test("smoke file viewer renders real file content", async ({ page, gotoSession }) => { await gotoSession() @@ -7,10 +7,7 @@ test("smoke file viewer renders real file content", async ({ page, gotoSession } const sep = process.platform === "win32" ? "\\" : "/" const file = ["packages", "app", "package.json"].join(sep) - await page.keyboard.press(`${modKey}+P`) - - const dialog = page.getByRole("dialog") - await expect(dialog).toBeVisible() + const dialog = await openPalette(page) const input = dialog.getByRole("textbox").first() await input.fill(file) diff --git a/packages/app/e2e/fixtures.ts b/packages/app/e2e/fixtures.ts index c5315ff19..0c3150609 100644 --- a/packages/app/e2e/fixtures.ts +++ b/packages/app/e2e/fixtures.ts @@ -1,5 +1,7 @@ import { test as base, expect } from "@playwright/test" -import { createSdk, dirSlug, getWorktree, promptSelector, serverUrl, sessionPath } from "./utils" +import { seedProjects } from "./actions" +import { promptSelector } from "./selectors" +import { createSdk, dirSlug, getWorktree, sessionPath } from "./utils" type TestFixtures = { sdk: ReturnType @@ -29,54 +31,17 @@ export const test = base.extend({ await use(createSdk(directory)) }, gotoSession: async ({ page, directory }, use) => { - await page.addInitScript( - (input: { directory: string; serverUrl: string }) => { - const key = "opencode.global.dat:server" - const raw = localStorage.getItem(key) - const parsed = (() => { - if (!raw) return undefined - try { - return JSON.parse(raw) as unknown - } catch { - return undefined - } - })() - - const store = parsed && typeof parsed === "object" ? (parsed as Record) : {} - const list = Array.isArray(store.list) ? store.list : [] - const lastProject = store.lastProject && typeof store.lastProject === "object" ? store.lastProject : {} - const projects = store.projects && typeof store.projects === "object" ? store.projects : {} - const nextProjects = { ...(projects as Record) } - - const add = (origin: string) => { - const current = nextProjects[origin] - const items = Array.isArray(current) ? current : [] - const existing = items.filter( - (p): p is { worktree: string; expanded?: boolean } => - !!p && - typeof p === "object" && - "worktree" in p && - typeof (p as { worktree?: unknown }).worktree === "string", - ) - - if (existing.some((p) => p.worktree === input.directory)) return - nextProjects[origin] = [{ worktree: input.directory, expanded: true }, ...existing] - } - - add("local") - add(input.serverUrl) - - localStorage.setItem( - key, - JSON.stringify({ - list, - projects: nextProjects, - lastProject, - }), - ) - }, - { directory, serverUrl }, - ) + await seedProjects(page, { directory }) + await page.addInitScript(() => { + localStorage.setItem( + "opencode.global.dat:model", + JSON.stringify({ + recent: [{ providerID: "opencode", modelID: "big-pickle" }], + user: [], + variant: {}, + }), + ) + }) const gotoSession = async (sessionID?: string) => { await page.goto(sessionPath(directory, sessionID)) diff --git a/packages/app/e2e/models/model-picker.spec.ts b/packages/app/e2e/models/model-picker.spec.ts index a0c70aabe..df95e04d2 100644 --- a/packages/app/e2e/models/model-picker.spec.ts +++ b/packages/app/e2e/models/model-picker.spec.ts @@ -1,5 +1,5 @@ import { test, expect } from "../fixtures" -import { promptSelector } from "../utils" +import { promptSelector } from "../selectors" test("smoke model selection updates prompt footer", async ({ page, gotoSession }) => { await gotoSession() diff --git a/packages/app/e2e/models/models-visibility.spec.ts b/packages/app/e2e/models/models-visibility.spec.ts index 0db7580c2..36f14596d 100644 --- a/packages/app/e2e/models/models-visibility.spec.ts +++ b/packages/app/e2e/models/models-visibility.spec.ts @@ -1,5 +1,6 @@ import { test, expect } from "../fixtures" -import { modKey, promptSelector } from "../utils" +import { promptSelector } from "../selectors" +import { closeDialog, openSettings } from "../actions" test("hiding a model removes it from the model picker", async ({ page, gotoSession }) => { await gotoSession() @@ -27,18 +28,7 @@ test("hiding a model removes it from the model picker", async ({ page, gotoSessi await page.keyboard.press("Escape") await expect(picker).toHaveCount(0) - const settings = page.getByRole("dialog") - - await page.keyboard.press(`${modKey}+Comma`).catch(() => undefined) - const opened = await settings - .waitFor({ state: "visible", timeout: 3000 }) - .then(() => true) - .catch(() => false) - - if (!opened) { - await page.getByRole("button", { name: "Settings" }).first().click() - await expect(settings).toBeVisible() - } + const settings = await openSettings(page) await settings.getByRole("tab", { name: "Models" }).click() const search = settings.getByPlaceholder("Search models") @@ -52,22 +42,7 @@ test("hiding a model removes it from the model picker", async ({ page, gotoSessi await toggle.locator('[data-slot="switch-control"]').click() await expect(input).toHaveAttribute("aria-checked", "false") - await page.keyboard.press("Escape") - const closed = await settings - .waitFor({ state: "detached", timeout: 1500 }) - .then(() => true) - .catch(() => false) - if (!closed) { - await page.keyboard.press("Escape") - const closedSecond = await settings - .waitFor({ state: "detached", timeout: 1500 }) - .then(() => true) - .catch(() => false) - if (!closedSecond) { - await page.locator('[data-component="dialog-overlay"]').click({ position: { x: 5, y: 5 } }) - await expect(settings).toHaveCount(0) - } - } + await closeDialog(page, settings) await page.locator(promptSelector).click() await page.keyboard.type("/model") diff --git a/packages/app/e2e/projects/project-edit.spec.ts b/packages/app/e2e/projects/project-edit.spec.ts new file mode 100644 index 000000000..22d053f3d --- /dev/null +++ b/packages/app/e2e/projects/project-edit.spec.ts @@ -0,0 +1,47 @@ +import { test, expect } from "../fixtures" +import { openSidebar } from "../actions" + +test("dialog edit project updates name and startup script", async ({ page, gotoSession }) => { + await gotoSession() + await page.setViewportSize({ width: 1400, height: 800 }) + + await openSidebar(page) + + const open = async () => { + const header = page.locator(".group\\/project").first() + await header.hover() + const trigger = header.getByRole("button", { name: "More options" }).first() + await expect(trigger).toBeVisible() + await trigger.click({ force: true }) + + await page.getByRole("menuitem", { name: "Edit" }).click() + + const dialog = page.getByRole("dialog") + await expect(dialog).toBeVisible() + await expect(dialog.getByRole("heading", { level: 2 })).toHaveText("Edit project") + return dialog + } + + const name = `e2e project ${Date.now()}` + const startup = `echo e2e_${Date.now()}` + + const dialog = await open() + + const nameInput = dialog.getByLabel("Name") + await nameInput.fill(name) + + const startupInput = dialog.getByLabel("Workspace startup script") + await startupInput.fill(startup) + + await dialog.getByRole("button", { name: "Save" }).click() + await expect(dialog).toHaveCount(0) + + const header = page.locator(".group\\/project").first() + await expect(header).toContainText(name) + + const reopened = await open() + await expect(reopened.getByLabel("Name")).toHaveValue(name) + await expect(reopened.getByLabel("Workspace startup script")).toHaveValue(startup) + await reopened.getByRole("button", { name: "Cancel" }).click() + await expect(reopened).toHaveCount(0) +}) diff --git a/packages/app/e2e/projects/projects-close.spec.ts b/packages/app/e2e/projects/projects-close.spec.ts new file mode 100644 index 000000000..c3618740d --- /dev/null +++ b/packages/app/e2e/projects/projects-close.spec.ts @@ -0,0 +1,77 @@ +import { test, expect } from "../fixtures" +import { createTestProject, seedProjects, cleanupTestProject, openSidebar } from "../actions" +import { projectCloseHoverSelector, projectCloseMenuSelector, projectSwitchSelector } from "../selectors" +import { dirSlug } from "../utils" + +test("can close a project via hover card close button", async ({ page, directory, gotoSession }) => { + await page.setViewportSize({ width: 1400, height: 800 }) + + const other = await createTestProject() + const otherSlug = dirSlug(other) + await seedProjects(page, { directory, extra: [other] }) + + try { + await gotoSession() + + await openSidebar(page) + + const otherButton = page.locator(projectSwitchSelector(otherSlug)).first() + await expect(otherButton).toBeVisible() + await otherButton.hover() + + const close = page.locator(projectCloseHoverSelector(otherSlug)).first() + await expect(close).toBeVisible() + await close.click() + + await expect(otherButton).toHaveCount(0) + } finally { + await cleanupTestProject(other) + } +}) + +test("can close a project via project header more options menu", async ({ page, directory, gotoSession }) => { + await page.setViewportSize({ width: 1400, height: 800 }) + + const other = await createTestProject() + const otherName = other.split("/").pop() + const otherSlug = dirSlug(other) + await seedProjects(page, { directory, extra: [other] }) + + try { + await gotoSession() + + await openSidebar(page) + + const otherButton = page.locator(projectSwitchSelector(otherSlug)).first() + await expect(otherButton).toBeVisible() + await otherButton.click() + + await expect(page).toHaveURL(new RegExp(`/${otherSlug}/session`)) + + const header = page + .locator(".group\\/project") + .filter({ has: page.locator(`[data-action="project-menu"][data-project="${otherSlug}"]`) }) + .first() + await expect(header).toContainText(otherName) + + const trigger = header.locator(`[data-action="project-menu"][data-project="${otherSlug}"]`).first() + await expect(trigger).toHaveCount(1) + await trigger.focus() + await page.keyboard.press("Enter") + + const close = page + .locator(projectCloseMenuSelector(otherSlug)) + .or(page.getByRole("menuitem", { name: "Close" })) + .or( + page + .locator('[data-component="dropdown-menu-content"] [data-slot="dropdown-menu-item"]') + .filter({ hasText: "Close" }), + ) + .first() + await expect(close).toBeVisible({ timeout: 10_000 }) + await close.click({ force: true }) + await expect(otherButton).toHaveCount(0) + } finally { + await cleanupTestProject(other) + } +}) diff --git a/packages/app/e2e/projects/projects-switch.spec.ts b/packages/app/e2e/projects/projects-switch.spec.ts new file mode 100644 index 000000000..829ed8e57 --- /dev/null +++ b/packages/app/e2e/projects/projects-switch.spec.ts @@ -0,0 +1,34 @@ +import { test, expect } from "../fixtures" +import { defocus, createTestProject, seedProjects, cleanupTestProject } from "../actions" +import { projectSwitchSelector } from "../selectors" +import { dirSlug } from "../utils" + +test("can switch between projects from sidebar", async ({ page, directory, gotoSession }) => { + await page.setViewportSize({ width: 1400, height: 800 }) + + const other = await createTestProject() + const otherSlug = dirSlug(other) + + await seedProjects(page, { directory, extra: [other] }) + + try { + await gotoSession() + + await defocus(page) + + const currentSlug = dirSlug(directory) + const otherButton = page.locator(projectSwitchSelector(otherSlug)).first() + await expect(otherButton).toBeVisible() + await otherButton.click() + + await expect(page).toHaveURL(new RegExp(`/${otherSlug}/session`)) + + const currentButton = page.locator(projectSwitchSelector(currentSlug)).first() + await expect(currentButton).toBeVisible() + await currentButton.click() + + await expect(page).toHaveURL(new RegExp(`/${currentSlug}/session`)) + } finally { + await cleanupTestProject(other) + } +}) diff --git a/packages/app/e2e/prompt/context.spec.ts b/packages/app/e2e/prompt/context.spec.ts index f0f3f073a..9e8f998f2 100644 --- a/packages/app/e2e/prompt/context.spec.ts +++ b/packages/app/e2e/prompt/context.spec.ts @@ -1,5 +1,5 @@ import { test, expect } from "../fixtures" -import { promptSelector } from "../utils" +import { promptSelector } from "../selectors" test("context panel can be opened from the prompt", async ({ page, sdk, gotoSession }) => { const title = `e2e smoke context ${Date.now()}` diff --git a/packages/app/e2e/prompt/prompt-mention.spec.ts b/packages/app/e2e/prompt/prompt-mention.spec.ts index 85acb4c28..5cc9f6e68 100644 --- a/packages/app/e2e/prompt/prompt-mention.spec.ts +++ b/packages/app/e2e/prompt/prompt-mention.spec.ts @@ -1,5 +1,5 @@ import { test, expect } from "../fixtures" -import { promptSelector } from "../utils" +import { promptSelector } from "../selectors" test("smoke @mention inserts file pill token", async ({ page, gotoSession }) => { await gotoSession() diff --git a/packages/app/e2e/prompt/prompt-slash-open.spec.ts b/packages/app/e2e/prompt/prompt-slash-open.spec.ts index 3e769e330..b4a93099d 100644 --- a/packages/app/e2e/prompt/prompt-slash-open.spec.ts +++ b/packages/app/e2e/prompt/prompt-slash-open.spec.ts @@ -1,5 +1,5 @@ import { test, expect } from "../fixtures" -import { promptSelector } from "../utils" +import { promptSelector } from "../selectors" test("smoke /open opens file picker dialog", async ({ page, gotoSession }) => { await gotoSession() diff --git a/packages/app/e2e/prompt/prompt.spec.ts b/packages/app/e2e/prompt/prompt.spec.ts index b58e5e296..33f8d7ebc 100644 --- a/packages/app/e2e/prompt/prompt.spec.ts +++ b/packages/app/e2e/prompt/prompt.spec.ts @@ -1,10 +1,6 @@ import { test, expect } from "../fixtures" -import { promptSelector } from "../utils" - -function sessionIDFromUrl(url: string) { - const match = /\/session\/([^/?#]+)/.exec(url) - return match?.[1] -} +import { promptSelector } from "../selectors" +import { sessionIDFromUrl } from "../actions" test("can send a prompt and receive a reply", async ({ page, sdk, gotoSession }) => { test.setTimeout(120_000) diff --git a/packages/app/e2e/selectors.ts b/packages/app/e2e/selectors.ts new file mode 100644 index 000000000..9179a6fd5 --- /dev/null +++ b/packages/app/e2e/selectors.ts @@ -0,0 +1,17 @@ +export const promptSelector = '[data-component="prompt-input"]' +export const terminalSelector = '[data-component="terminal"]' + +export const modelVariantCycleSelector = '[data-action="model-variant-cycle"]' +export const settingsLanguageSelectSelector = '[data-action="settings-language"]' + +export const sidebarNavSelector = '[data-component="sidebar-nav-desktop"]' + +export const projectSwitchSelector = (slug: string) => + `${sidebarNavSelector} [data-action="project-switch"][data-project="${slug}"]` + +export const projectCloseHoverSelector = (slug: string) => `[data-action="project-close-hover"][data-project="${slug}"]` + +export const projectMenuTriggerSelector = (slug: string) => + `${sidebarNavSelector} [data-action="project-menu"][data-project="${slug}"]` + +export const projectCloseMenuSelector = (slug: string) => `[data-action="project-close-menu"][data-project="${slug}"]` diff --git a/packages/app/e2e/settings/settings-language.spec.ts b/packages/app/e2e/settings/settings-language.spec.ts index b2ef70bf8..b326a7d81 100644 --- a/packages/app/e2e/settings/settings-language.spec.ts +++ b/packages/app/e2e/settings/settings-language.spec.ts @@ -1,5 +1,6 @@ import { test, expect } from "../fixtures" -import { modKey, settingsLanguageSelectSelector } from "../utils" +import { settingsLanguageSelectSelector } from "../selectors" +import { openSettings } from "../actions" test("smoke changing language updates settings labels", async ({ page, gotoSession }) => { await page.addInitScript(() => { @@ -8,19 +9,7 @@ test("smoke changing language updates settings labels", async ({ page, gotoSessi await gotoSession() - const dialog = page.getByRole("dialog") - - await page.keyboard.press(`${modKey}+Comma`).catch(() => undefined) - - const opened = await dialog - .waitFor({ state: "visible", timeout: 3000 }) - .then(() => true) - .catch(() => false) - - if (!opened) { - await page.getByRole("button", { name: "Settings" }).first().click() - await expect(dialog).toBeVisible() - } + const dialog = await openSettings(page) const heading = dialog.getByRole("heading", { level: 2 }) await expect(heading).toHaveText("General") diff --git a/packages/app/e2e/settings/settings-providers.spec.ts b/packages/app/e2e/settings/settings-providers.spec.ts index 5b9325c2a..4b3b178cc 100644 --- a/packages/app/e2e/settings/settings-providers.spec.ts +++ b/packages/app/e2e/settings/settings-providers.spec.ts @@ -1,22 +1,11 @@ import { test, expect } from "../fixtures" -import { modKey, promptSelector } from "../utils" +import { promptSelector } from "../selectors" +import { closeDialog, openSettings } from "../actions" test("smoke providers settings opens provider selector", async ({ page, gotoSession }) => { await gotoSession() - const dialog = page.getByRole("dialog") - - await page.keyboard.press(`${modKey}+Comma`).catch(() => undefined) - - const opened = await dialog - .waitFor({ state: "visible", timeout: 3000 }) - .then(() => true) - .catch(() => false) - - if (!opened) { - await page.getByRole("button", { name: "Settings" }).first().click() - await expect(dialog).toBeVisible() - } + const dialog = await openSettings(page) await dialog.getByRole("tab", { name: "Providers" }).click() await expect(dialog.getByText("Connected providers", { exact: true })).toBeVisible() @@ -37,20 +26,5 @@ test("smoke providers settings opens provider selector", async ({ page, gotoSess const stillOpen = await dialog.isVisible().catch(() => false) if (!stillOpen) return - await page.keyboard.press("Escape") - const closed = await dialog - .waitFor({ state: "detached", timeout: 1500 }) - .then(() => true) - .catch(() => false) - if (closed) return - - await page.keyboard.press("Escape") - const closedSecond = await dialog - .waitFor({ state: "detached", timeout: 1500 }) - .then(() => true) - .catch(() => false) - if (closedSecond) return - - await page.locator('[data-component="dialog-overlay"]').click({ position: { x: 5, y: 5 } }) - await expect(dialog).toHaveCount(0) + await closeDialog(page, dialog) }) diff --git a/packages/app/e2e/settings/settings.spec.ts b/packages/app/e2e/settings/settings.spec.ts index 293a4ba9a..55b767076 100644 --- a/packages/app/e2e/settings/settings.spec.ts +++ b/packages/app/e2e/settings/settings.spec.ts @@ -1,44 +1,14 @@ import { test, expect } from "../fixtures" -import { modKey } from "../utils" +import { closeDialog, openSettings } from "../actions" test("smoke settings dialog opens, switches tabs, closes", async ({ page, gotoSession }) => { await gotoSession() - const dialog = page.getByRole("dialog") - - await page.keyboard.press(`${modKey}+Comma`).catch(() => undefined) - - const opened = await dialog - .waitFor({ state: "visible", timeout: 3000 }) - .then(() => true) - .catch(() => false) - - if (!opened) { - await page.getByRole("button", { name: "Settings" }).first().click() - await expect(dialog).toBeVisible() - } + const dialog = await openSettings(page) await dialog.getByRole("tab", { name: "Shortcuts" }).click() await expect(dialog.getByRole("button", { name: "Reset to defaults" })).toBeVisible() await expect(dialog.getByPlaceholder("Search shortcuts")).toBeVisible() - await page.keyboard.press("Escape") - - const closed = await dialog - .waitFor({ state: "detached", timeout: 1500 }) - .then(() => true) - .catch(() => false) - - if (closed) return - - await page.keyboard.press("Escape") - const closedSecond = await dialog - .waitFor({ state: "detached", timeout: 1500 }) - .then(() => true) - .catch(() => false) - - if (closedSecond) return - - await page.locator('[data-component="dialog-overlay"]').click({ position: { x: 5, y: 5 } }) - await expect(dialog).toHaveCount(0) + await closeDialog(page, dialog) }) diff --git a/packages/app/e2e/sidebar/sidebar-session-links.spec.ts b/packages/app/e2e/sidebar/sidebar-session-links.spec.ts index 8c3f69547..1c0f4fa71 100644 --- a/packages/app/e2e/sidebar/sidebar-session-links.spec.ts +++ b/packages/app/e2e/sidebar/sidebar-session-links.spec.ts @@ -1,5 +1,6 @@ import { test, expect } from "../fixtures" -import { modKey, promptSelector } from "../utils" +import { openSidebar } from "../actions" +import { promptSelector } from "../selectors" test("sidebar session links navigate to the selected session", async ({ page, slug, sdk, gotoSession }) => { const stamp = Date.now() @@ -13,12 +14,7 @@ test("sidebar session links navigate to the selected session", async ({ page, sl try { await gotoSession(one.id) - const main = page.locator("main") - const collapsed = ((await main.getAttribute("class")) ?? "").includes("xl:border-l") - if (collapsed) { - await page.keyboard.press(`${modKey}+B`) - await expect(main).not.toHaveClass(/xl:border-l/) - } + await openSidebar(page) const target = page.locator(`[data-session-id="${two.id}"] a`).first() await expect(target).toBeVisible() diff --git a/packages/app/e2e/sidebar/sidebar.spec.ts b/packages/app/e2e/sidebar/sidebar.spec.ts index ba58b1008..6239a04bd 100644 --- a/packages/app/e2e/sidebar/sidebar.spec.ts +++ b/packages/app/e2e/sidebar/sidebar.spec.ts @@ -1,21 +1,14 @@ import { test, expect } from "../fixtures" -import { modKey } from "../utils" +import { openSidebar, toggleSidebar } from "../actions" test("sidebar can be collapsed and expanded", async ({ page, gotoSession }) => { await gotoSession() - const main = page.locator("main") - const closedClass = /xl:border-l/ - const isClosed = await main.evaluate((node) => node.className.includes("xl:border-l")) + await openSidebar(page) - if (isClosed) { - await page.keyboard.press(`${modKey}+B`) - await expect(main).not.toHaveClass(closedClass) - } + await toggleSidebar(page) + await expect(page.locator("main")).toHaveClass(/xl:border-l/) - await page.keyboard.press(`${modKey}+B`) - await expect(main).toHaveClass(closedClass) - - await page.keyboard.press(`${modKey}+B`) - await expect(main).not.toHaveClass(closedClass) + await toggleSidebar(page) + await expect(page.locator("main")).not.toHaveClass(/xl:border-l/) }) diff --git a/packages/app/e2e/terminal/terminal-init.spec.ts b/packages/app/e2e/terminal/terminal-init.spec.ts index 6faa73a75..87934b66e 100644 --- a/packages/app/e2e/terminal/terminal-init.spec.ts +++ b/packages/app/e2e/terminal/terminal-init.spec.ts @@ -1,5 +1,6 @@ import { test, expect } from "../fixtures" -import { promptSelector, terminalSelector, terminalToggleKey } from "../utils" +import { promptSelector, terminalSelector } from "../selectors" +import { terminalToggleKey } from "../utils" test("smoke terminal mounts and can create a second tab", async ({ page, gotoSession }) => { await gotoSession() diff --git a/packages/app/e2e/terminal/terminal.spec.ts b/packages/app/e2e/terminal/terminal.spec.ts index aaf5c2d75..ef88aa34e 100644 --- a/packages/app/e2e/terminal/terminal.spec.ts +++ b/packages/app/e2e/terminal/terminal.spec.ts @@ -1,5 +1,6 @@ import { test, expect } from "../fixtures" -import { terminalSelector, terminalToggleKey } from "../utils" +import { terminalSelector } from "../selectors" +import { terminalToggleKey } from "../utils" test("terminal panel can be toggled", async ({ page, gotoSession }) => { await gotoSession() diff --git a/packages/app/e2e/thinking-level.spec.ts b/packages/app/e2e/thinking-level.spec.ts index 564ef3c1f..92200933e 100644 --- a/packages/app/e2e/thinking-level.spec.ts +++ b/packages/app/e2e/thinking-level.spec.ts @@ -1,5 +1,5 @@ import { test, expect } from "./fixtures" -import { modelVariantCycleSelector } from "./utils" +import { modelVariantCycleSelector } from "./selectors" test("smoke model variant cycle updates label", async ({ page, gotoSession }) => { await gotoSession() diff --git a/packages/app/e2e/tsconfig.json b/packages/app/e2e/tsconfig.json index 76438a03c..18e88ddc9 100644 --- a/packages/app/e2e/tsconfig.json +++ b/packages/app/e2e/tsconfig.json @@ -2,7 +2,7 @@ "extends": "../tsconfig.json", "compilerOptions": { "noEmit": true, - "types": ["node"] + "types": ["node", "bun"] }, "include": ["./**/*.ts"] } diff --git a/packages/app/e2e/utils.ts b/packages/app/e2e/utils.ts index 3dec12592..ec6cdf830 100644 --- a/packages/app/e2e/utils.ts +++ b/packages/app/e2e/utils.ts @@ -10,12 +10,6 @@ export const serverName = `${serverHost}:${serverPort}` export const modKey = process.platform === "darwin" ? "Meta" : "Control" export const terminalToggleKey = "Control+Backquote" -export const promptSelector = '[data-component="prompt-input"]' -export const terminalSelector = '[data-component="terminal"]' -export const modelVariantCycleSelector = '[data-action="model-variant-cycle"]' - -export const settingsLanguageSelectSelector = '[data-action="settings-language"]' - export function createSdk(directory?: string) { return createOpencodeClient({ baseUrl: serverUrl, directory, throwOnError: true }) } diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index 73480e8f2..f049dc3bc 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -2285,6 +2285,8 @@ export default function Layout(props: ParentProps) { } @@ -1968,15 +1938,11 @@ export const PromptInput: Component = (props) => { keybind={command.keybind("model.choose")} > - {(open) => ( - <> - - - - {local.model.current()?.name ?? language.t("dialog.model.select.title")} - - - )} + + + + {local.model.current()?.name ?? language.t("dialog.model.select.title")} + @@ -1989,13 +1955,10 @@ export const PromptInput: Component = (props) => { @@ -2009,7 +1972,7 @@ export const PromptInput: Component = (props) => { variant="ghost" onClick={() => permission.toggleAutoAccept(params.id!, sdk.directory)} classList={{ - "_hidden group-hover/prompt-input:flex items-center justify-center": true, + "_hidden group-hover/prompt-input:flex size-6 items-center justify-center": true, "text-text-base": !permission.isAutoAccepting(params.id!, sdk.directory), "hover:bg-surface-success-base": permission.isAutoAccepting(params.id!, sdk.directory), }} @@ -2031,7 +1994,7 @@ export const PromptInput: Component = (props) => { -
+
= (props) => { e.currentTarget.value = "" }} /> -
+
@@ -2074,7 +2036,7 @@ export const PromptInput: Component = (props) => {
{language.t("prompt.action.send")} - +
@@ -2085,7 +2047,7 @@ export const PromptInput: Component = (props) => { disabled={!prompt.dirty() && !working()} icon={working() ? "stop" : "arrow-up"} variant="primary" - class="h-6 w-5.5" + class="h-6 w-4.5" aria-label={working() ? language.t("prompt.action.stop") : language.t("prompt.action.send")} /> diff --git a/packages/app/src/components/session-context-usage.tsx b/packages/app/src/components/session-context-usage.tsx index 92b060212..1e37d8f6a 100644 --- a/packages/app/src/components/session-context-usage.tsx +++ b/packages/app/src/components/session-context-usage.tsx @@ -64,8 +64,8 @@ export function SessionContextUsage(props: SessionContextUsageProps) { } const circle = () => ( -
- +
+
) @@ -101,7 +101,7 @@ export function SessionContextUsage(props: SessionContextUsageProps) {
) } diff --git a/packages/app/src/components/settings-keybinds.tsx b/packages/app/src/components/settings-keybinds.tsx index efd18c8bd..393da0c2a 100644 --- a/packages/app/src/components/settings-keybinds.tsx +++ b/packages/app/src/components/settings-keybinds.tsx @@ -9,7 +9,6 @@ import fuzzysort from "fuzzysort" import { formatKeybind, parseKeybind, useCommand } from "@/context/command" import { useLanguage } from "@/context/language" import { useSettings } from "@/context/settings" -import { ScrollFade } from "@opencode-ai/ui/scroll-fade" const IS_MAC = typeof navigator === "object" && /(Mac|iPod|iPhone|iPad)/.test(navigator.platform) const PALETTE_ID = "command.palette" @@ -353,12 +352,7 @@ export const SettingsKeybinds: Component = () => { }) return ( - +
@@ -435,6 +429,6 @@ export const SettingsKeybinds: Component = () => {
- +
) } diff --git a/packages/desktop/src-tauri/src/lib.rs b/packages/desktop/src-tauri/src/lib.rs index d16416c9f..29ac86f29 100644 --- a/packages/desktop/src-tauri/src/lib.rs +++ b/packages/desktop/src-tauri/src/lib.rs @@ -345,7 +345,6 @@ pub fn run() { .decorations(false); let window = window_builder.build().expect("Failed to create window"); - let _ = window.show(); #[cfg(windows)] let _ = window.create_overlay_titlebar(); diff --git a/packages/ui/src/components/accordion.css b/packages/ui/src/components/accordion.css index b310eeedb..7bf287fe5 100644 --- a/packages/ui/src/components/accordion.css +++ b/packages/ui/src/components/accordion.css @@ -36,9 +36,7 @@ border-radius: var(--radius-md); overflow: clip; color: var(--text-strong); - transition-property: background-color, border-color; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); + transition: background-color 0.15s ease; /* text-12-regular */ font-family: var(--font-family-sans); @@ -60,48 +58,41 @@ } } - [data-slot="accordion-arrow"] { - flex-shrink: 0; - width: 16px; - height: 16px; - display: flex; - align-items: center; - justify-content: center; - color: var(--text-weak); - } - - [data-slot="accordion-content"] { - display: grid; - grid-template-rows: 0fr; - transition-property: grid-template-rows, opacity; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); - width: 100%; - - > * { - overflow: hidden; + &[data-expanded] { + [data-slot="accordion-trigger"] { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } - } - [data-slot="accordion-content"][data-expanded] { - grid-template-rows: 1fr; + [data-slot="accordion-content"] { + border: 1px solid var(--border-weak-base); + border-top: none; + border-bottom-left-radius: var(--radius-md); + border-bottom-right-radius: var(--radius-md); + } } - [data-slot="accordion-content"][data-closed] { - grid-template-rows: 0fr; + [data-slot="accordion-content"] { + overflow: hidden; + width: 100%; } + } +} - &[data-expanded] [data-slot="accordion-trigger"] { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - } +@keyframes slideDown { + from { + height: 0; + } + to { + height: var(--kb-accordion-content-height); + } +} - &[data-expanded] [data-slot="accordion-content"] { - border: 1px solid var(--border-weak-base); - border-top: none; - border-bottom-left-radius: var(--radius-md); - border-bottom-right-radius: var(--radius-md); - height: auto; - } +@keyframes slideUp { + from { + height: var(--kb-accordion-content-height); + } + to { + height: 0; } } diff --git a/packages/ui/src/components/accordion.tsx b/packages/ui/src/components/accordion.tsx index e30be95e0..535d38e3d 100644 --- a/packages/ui/src/components/accordion.tsx +++ b/packages/ui/src/components/accordion.tsx @@ -1,7 +1,6 @@ import { Accordion as Kobalte } from "@kobalte/core/accordion" -import { Accessor, createContext, splitProps, useContext } from "solid-js" +import { splitProps } from "solid-js" import type { ComponentProps, ParentProps } from "solid-js" -import { MorphChevron } from "./morph-chevron" export interface AccordionProps extends ComponentProps {} export interface AccordionItemProps extends ComponentProps {} @@ -9,8 +8,6 @@ export interface AccordionHeaderProps extends ComponentProps {} export interface AccordionContentProps extends ComponentProps {} -const AccordionItemContext = createContext>() - function AccordionRoot(props: AccordionProps) { const [split, rest] = splitProps(props, ["class", "classList"]) return ( @@ -25,19 +22,17 @@ function AccordionRoot(props: AccordionProps) { ) } -function AccordionItem(props: AccordionItemProps & { expanded?: boolean }) { - const [split, rest] = splitProps(props, ["class", "classList", "expanded"]) +function AccordionItem(props: AccordionItemProps) { + const [split, rest] = splitProps(props, ["class", "classList"]) return ( - split.expanded ?? false}> - - + ) } @@ -89,25 +84,9 @@ function AccordionContent(props: ParentProps) { ) } -export interface AccordionArrowProps extends ComponentProps<"div"> { - expanded?: boolean -} - -function AccordionArrow(props: AccordionArrowProps = {}) { - const [local, rest] = splitProps(props, ["expanded"]) - const contextExpanded = useContext(AccordionItemContext) - const isExpanded = () => local.expanded ?? contextExpanded?.() ?? false - return ( -
- -
- ) -} - export const Accordion = Object.assign(AccordionRoot, { Item: AccordionItem, Header: AccordionHeader, Trigger: AccordionTrigger, Content: AccordionContent, - Arrow: AccordionArrow, }) diff --git a/packages/ui/src/components/button.css b/packages/ui/src/components/button.css index 02a7ade71..d9b345923 100644 --- a/packages/ui/src/components/button.css +++ b/packages/ui/src/components/button.css @@ -8,13 +8,8 @@ text-decoration: none; user-select: none; cursor: default; - padding: 4px 8px; - white-space: nowrap; - transition-property: background-color, border-color, color, box-shadow, opacity; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); outline: none; - line-height: 20px; + white-space: nowrap; &[data-variant="primary"] { background-color: var(--button-primary-base); @@ -99,6 +94,7 @@ &:active:not(:disabled) { background-color: var(--button-secondary-base); scale: 0.99; + transition: all 150ms ease-out; } &:disabled { border-color: var(--border-disabled); @@ -113,27 +109,34 @@ } &[data-size="small"] { - padding: 2px 8px; + height: 22px; + padding: 0 8px; &[data-icon] { - padding: 2px 12px 2px 4px; + padding: 0 12px 0 4px; } + font-size: var(--font-size-small); + line-height: var(--line-height-large); gap: 4px; /* text-12-medium */ font-family: var(--font-family-sans); - font-size: var(--font-size-base); + font-size: var(--font-size-small); font-style: normal; font-weight: var(--font-weight-medium); + line-height: var(--line-height-large); /* 166.667% */ letter-spacing: var(--letter-spacing-normal); } &[data-size="normal"] { - padding: 4px 6px; + height: 24px; + line-height: 24px; + padding: 0 6px; &[data-icon] { - padding: 4px 12px 4px 4px; + padding: 0 12px 0 4px; } + font-size: var(--font-size-small); gap: 6px; /* text-12-medium */ @@ -145,10 +148,11 @@ } &[data-size="large"] { + height: 32px; padding: 6px 12px; &[data-icon] { - padding: 6px 12px 6px 8px; + padding: 0 12px 0 8px; } gap: 4px; @@ -158,6 +162,7 @@ font-size: 14px; font-style: normal; font-weight: var(--font-weight-medium); + line-height: var(--line-height-large); /* 142.857% */ letter-spacing: var(--letter-spacing-normal); } diff --git a/packages/ui/src/components/button.tsx b/packages/ui/src/components/button.tsx index b2d2004d3..7f974b2f7 100644 --- a/packages/ui/src/components/button.tsx +++ b/packages/ui/src/components/button.tsx @@ -4,7 +4,7 @@ import { Icon, IconProps } from "./icon" export interface ButtonProps extends ComponentProps, - Pick, "class" | "classList" | "children" | "style"> { + Pick, "class" | "classList" | "children"> { size?: "small" | "normal" | "large" variant?: "primary" | "secondary" | "ghost" icon?: IconProps["name"] diff --git a/packages/ui/src/components/card.css b/packages/ui/src/components/card.css index 809fbdacd..6dae47223 100644 --- a/packages/ui/src/components/card.css +++ b/packages/ui/src/components/card.css @@ -4,9 +4,7 @@ flex-direction: column; background-color: var(--surface-inset-base); border: 1px solid var(--border-weaker-base); - transition-property: background-color, border-color; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); + transition: background-color 0.15s ease; border-radius: var(--radius-md); padding: 6px 12px; overflow: clip; diff --git a/packages/ui/src/components/checkbox.css b/packages/ui/src/components/checkbox.css index cad0dd2dd..b10ebbbd1 100644 --- a/packages/ui/src/components/checkbox.css +++ b/packages/ui/src/components/checkbox.css @@ -4,18 +4,6 @@ gap: 12px; cursor: default; - [data-slot="checkbox-checkbox-control"] { - transition-property: border-color, background-color, box-shadow; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); - } - - [data-slot="checkbox-checkbox-indicator"] { - transition-property: opacity; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); - } - [data-slot="checkbox-checkbox-input"] { position: absolute; width: 1px; diff --git a/packages/ui/src/components/collapsible.css b/packages/ui/src/components/collapsible.css index cc62b2b87..1f20cf85d 100644 --- a/packages/ui/src/components/collapsible.css +++ b/packages/ui/src/components/collapsible.css @@ -4,9 +4,7 @@ flex-direction: column; background-color: var(--surface-inset-base); border: 1px solid var(--border-weaker-base); - transition-property: background-color, border-color; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); + transition: background-color 0.15s ease; border-radius: var(--radius-md); overflow: clip; @@ -46,28 +44,16 @@ display: flex; align-items: center; justify-content: center; - color: var(--text-weak); } } [data-slot="collapsible-content"] { - display: grid; - grid-template-rows: 0fr; - transition-property: grid-template-rows, opacity; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); + overflow: hidden; + /* animation: slideUp 250ms ease-out; */ - > * { - overflow: hidden; - } - - &[data-expanded] { - grid-template-rows: 1fr; - } - - &[data-closed] { - grid-template-rows: 0fr; - } + /* &[data-expanded] { */ + /* animation: slideDown 250ms ease-out; */ + /* } */ } &[data-variant="ghost"] { @@ -97,3 +83,21 @@ } } } + +@keyframes slideDown { + from { + height: 0; + } + to { + height: var(--kb-collapsible-content-height); + } +} + +@keyframes slideUp { + from { + height: var(--kb-collapsible-content-height); + } + to { + height: 0; + } +} diff --git a/packages/ui/src/components/collapsible.tsx b/packages/ui/src/components/collapsible.tsx index 55b7b6033..903afc308 100644 --- a/packages/ui/src/components/collapsible.tsx +++ b/packages/ui/src/components/collapsible.tsx @@ -1,8 +1,6 @@ import { Collapsible as Kobalte, CollapsibleRootProps } from "@kobalte/core/collapsible" -import { Accessor, ComponentProps, createContext, createSignal, ParentProps, splitProps, useContext } from "solid-js" -import { MorphChevron } from "./morph-chevron" - -const CollapsibleContext = createContext>() +import { ComponentProps, ParentProps, splitProps } from "solid-js" +import { Icon } from "./icon" export interface CollapsibleProps extends ParentProps { class?: string @@ -11,30 +9,17 @@ export interface CollapsibleProps extends ParentProps { } function CollapsibleRoot(props: CollapsibleProps) { - const [local, others] = splitProps(props, ["class", "classList", "variant", "open", "onOpenChange", "children"]) - const [internalOpen, setInternalOpen] = createSignal(local.open ?? false) - - const handleOpenChange = (open: boolean) => { - setInternalOpen(open) - local.onOpenChange?.(open) - } - + const [local, others] = splitProps(props, ["class", "classList", "variant"]) return ( - - - {local.children} - - + ) } @@ -47,10 +32,9 @@ function CollapsibleContent(props: ComponentProps) { } function CollapsibleArrow(props?: ComponentProps<"div">) { - const isOpen = useContext(CollapsibleContext) return (
- +
) } diff --git a/packages/ui/src/components/cycle-label.css b/packages/ui/src/components/cycle-label.css deleted file mode 100644 index e3b5256d4..000000000 --- a/packages/ui/src/components/cycle-label.css +++ /dev/null @@ -1,51 +0,0 @@ -.cycle-label { - --c-dur: 200ms; - --c-stag: 30ms; - --c-ease: cubic-bezier(0.25, 0, 0.5, 1); - --c-opacity-start: 0; - --c-opacity-end: 1; - --c-blur-start: 0px; - --c-blur-end: 0px; - --c-skew: 10deg; - - display: inline-flex; - position: relative; - - transform-style: preserve-3d; - perspective: 500px; - transition: width 200ms var(--c-ease); - will-change: width; - overflow: hidden; - - .cycle-char { - display: inline-block; - transform-style: preserve-3d; - min-width: 0.25em; - backface-visibility: hidden; - - transition: - transform var(--c-dur) var(--c-ease), - opacity var(--c-dur) var(--c-ease), - filter var(--c-dur) var(--c-ease); - transition-delay: calc(var(--i, 0) * var(--c-stag)); - - &.enter { - opacity: var(--c-opacity-end); - filter: blur(var(--c-blur-end)); - transform: translateY(0) rotateX(0) skewX(0); - } - - &.exit { - opacity: var(--c-opacity-start); - filter: blur(var(--c-blur-start)); - transform: translateY(50%) rotateX(90deg) skewX(var(--c-skew)); - } - - &.pre { - opacity: var(--c-opacity-start); - filter: blur(var(--c-blur-start)); - transition: none; - transform: translateY(-50%) rotateX(-90deg) skewX(calc(var(--c-skew) * -1)); - } - } -} diff --git a/packages/ui/src/components/cycle-label.tsx b/packages/ui/src/components/cycle-label.tsx deleted file mode 100644 index e34385a2c..000000000 --- a/packages/ui/src/components/cycle-label.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import "./cycle-label.css" -import { createEffect, createSignal, JSX, on } from "solid-js" - -export interface CycleLabelProps extends JSX.HTMLAttributes { - value: string - onValueChange?: (value: string) => void - duration?: number | ((value: string) => number) - stagger?: number - opacity?: [number, number] - blur?: [number, number] - skewX?: number - onAnimationStart?: () => void - onAnimationEnd?: () => void -} - -const segmenter = - typeof Intl !== "undefined" && Intl.Segmenter ? new Intl.Segmenter("en", { granularity: "grapheme" }) : null - -const getChars = (text: string): string[] => - segmenter ? Array.from(segmenter.segment(text), (s) => s.segment) : text.split("") - -const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) - -export function CycleLabel(props: CycleLabelProps) { - const getDuration = (text: string) => { - const d = props?.duration ?? 200 - return typeof d === "function" ? d(text) : d - } - const stagger = () => props?.stagger ?? 20 - const opacity = () => props?.opacity ?? [0, 1] - const blur = () => props?.blur ?? [0, 0] - const skewX = () => props?.skewX ?? 10 - - let containerRef: HTMLSpanElement | undefined - let isAnimating = false - const [currentText, setCurrentText] = createSignal(props.value) - - const setChars = (el: HTMLElement, text: string, state: "enter" | "exit" | "pre" = "enter") => { - el.innerHTML = "" - const chars = getChars(text) - chars.forEach((char, i) => { - const span = document.createElement("span") - span.textContent = char === " " ? "\u00A0" : char - span.className = `cycle-char ${state}` - span.style.setProperty("--i", String(i)) - el.appendChild(span) - }) - } - - const animateToText = async (newText: string) => { - if (!containerRef || isAnimating) return - if (newText === currentText()) return - - isAnimating = true - props.onAnimationStart?.() - - const dur = getDuration(newText) - const stag = stagger() - - containerRef.style.width = containerRef.offsetWidth + "px" - - const oldChars = containerRef.querySelectorAll(".cycle-char") - oldChars.forEach((c) => c.classList.replace("enter", "exit")) - - const clone = containerRef.cloneNode(false) as HTMLElement - Object.assign(clone.style, { - position: "absolute", - visibility: "hidden", - width: "auto", - transition: "none", - }) - setChars(clone, newText) - document.body.appendChild(clone) - const nextWidth = clone.offsetWidth - clone.remove() - - const exitTime = oldChars.length * stag + dur - await wait(exitTime * 0.3) - - containerRef.style.width = nextWidth + "px" - - const widthDur = 200 - await wait(widthDur * 0.3) - - setChars(containerRef, newText, "pre") - containerRef.offsetWidth - - Array.from(containerRef.children).forEach((c) => (c.className = "cycle-char enter")) - setCurrentText(newText) - props.onValueChange?.(newText) - - const enterTime = getChars(newText).length * stag + dur - await wait(enterTime) - - containerRef.style.width = "" - isAnimating = false - props.onAnimationEnd?.() - } - - createEffect( - on( - () => props.value, - (newValue) => { - if (newValue !== currentText()) { - animateToText(newValue) - } - }, - ), - ) - - const initRef = (el: HTMLSpanElement) => { - containerRef = el - setChars(el, props.value) - } - - return ( - - ) -} diff --git a/packages/ui/src/components/dialog.css b/packages/ui/src/components/dialog.css index b788945dc..2e66b644f 100644 --- a/packages/ui/src/components/dialog.css +++ b/packages/ui/src/components/dialog.css @@ -5,16 +5,6 @@ inset: 0; z-index: 50; background-color: hsl(from var(--background-base) h s l / 0.2); - - animation: overlayHide var(--transition-duration) var(--transition-easing) forwards; - - &[data-expanded] { - animation: overlayShow var(--transition-duration) var(--transition-easing) forwards; - } - - @starting-style { - animation: none; - } } [data-component="dialog"] { @@ -35,6 +25,7 @@ flex-direction: column; align-items: center; justify-items: start; + overflow: visible; [data-slot="dialog-content"] { display: flex; @@ -44,8 +35,16 @@ width: 100%; max-height: 100%; min-height: 280px; + overflow: auto; pointer-events: auto; + /* Hide scrollbar */ + scrollbar-width: none; + -ms-overflow-style: none; + &::-webkit-scrollbar { + display: none; + } + /* padding: 8px; */ /* padding: 8px 8px 0 8px; */ border-radius: var(--radius-xl); @@ -53,16 +52,6 @@ background-clip: padding-box; box-shadow: var(--shadow-lg-border-base); - animation: contentHide var(--transition-duration) var(--transition-easing) forwards; - - &[data-expanded] { - animation: contentShow var(--transition-duration) var(--transition-easing) forwards; - } - - @starting-style { - animation: none; - } - [data-slot="dialog-header"] { display: flex; padding: 20px; @@ -173,7 +162,7 @@ @keyframes contentShow { from { opacity: 0; - transform: translateY(2.5%) scale(0.975); + transform: scale(0.98); } to { opacity: 1; @@ -187,6 +176,6 @@ } to { opacity: 0; - transform: translateY(-2.5%) scale(0.975); + transform: scale(0.98); } } diff --git a/packages/ui/src/components/dropdown-menu.css b/packages/ui/src/components/dropdown-menu.css index 18266ac1a..cba041613 100644 --- a/packages/ui/src/components/dropdown-menu.css +++ b/packages/ui/src/components/dropdown-menu.css @@ -2,29 +2,26 @@ [data-component="dropdown-menu-sub-content"] { min-width: 8rem; overflow: hidden; - border: none; border-radius: var(--radius-md); - box-shadow: var(--shadow-xs-border); + border: 1px solid color-mix(in oklch, var(--border-base) 50%, transparent); background-clip: padding-box; background-color: var(--surface-raised-stronger-non-alpha); padding: 4px; - z-index: 100; + box-shadow: var(--shadow-md); + z-index: 50; transform-origin: var(--kb-menu-content-transform-origin); - &:focus-within, - &:focus { + &:focus, + &:focus-visible { outline: none; } - animation: dropdownMenuContentHide var(--transition-duration) var(--transition-easing) forwards; - - @starting-style { - animation: none; + &[data-closed] { + animation: dropdown-menu-close 0.15s ease-out; } &[data-expanded] { - pointer-events: auto; - animation: dropdownMenuContentShow var(--transition-duration) var(--transition-easing) forwards; + animation: dropdown-menu-open 0.15s ease-out; } } @@ -41,22 +38,18 @@ padding: 4px 8px; border-radius: var(--radius-sm); cursor: default; + user-select: none; outline: none; font-family: var(--font-family-sans); - font-size: var(--font-size-base); + font-size: var(--font-size-small); font-weight: var(--font-weight-medium); line-height: var(--line-height-large); letter-spacing: var(--letter-spacing-normal); color: var(--text-strong); - transition-property: background-color, color; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); - user-select: none; - - &:hover { - background-color: var(--surface-raised-base-hover); + &[data-highlighted] { + background: var(--surface-raised-base-hover); } &[data-disabled] { @@ -68,8 +61,6 @@ [data-slot="dropdown-menu-sub-trigger"] { &[data-expanded] { background: var(--surface-raised-base-hover); - outline: none; - border: none; } } @@ -111,24 +102,24 @@ } } -@keyframes dropdownMenuContentShow { +@keyframes dropdown-menu-open { from { opacity: 0; - transform: scaleY(0.95); + transform: scale(0.96); } to { opacity: 1; - transform: scaleY(1); + transform: scale(1); } } -@keyframes dropdownMenuContentHide { +@keyframes dropdown-menu-close { from { opacity: 1; - transform: scaleY(1); + transform: scale(1); } to { opacity: 0; - transform: scaleY(0.95); + transform: scale(0.96); } } diff --git a/packages/ui/src/components/hover-card.css b/packages/ui/src/components/hover-card.css index d23e43946..02d1f10ad 100644 --- a/packages/ui/src/components/hover-card.css +++ b/packages/ui/src/components/hover-card.css @@ -24,11 +24,11 @@ } &[data-closed] { - animation: hover-card-close var(--transition-duration) var(--transition-easing); + animation: hover-card-close 0.15s ease-out; } &[data-expanded] { - animation: hover-card-open var(--transition-duration) var(--transition-easing); + animation: hover-card-open 0.15s ease-out; } [data-slot="hover-card-body"] { diff --git a/packages/ui/src/components/icon-button.css b/packages/ui/src/components/icon-button.css index f1371bfa9..aa550e990 100644 --- a/packages/ui/src/components/icon-button.css +++ b/packages/ui/src/components/icon-button.css @@ -7,9 +7,6 @@ user-select: none; aspect-ratio: 1; flex-shrink: 0; - transition-property: background-color, color, opacity, box-shadow; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); &[data-variant="primary"] { background-color: var(--icon-strong-base); @@ -102,7 +99,7 @@ /* color: var(--icon-active); */ /* } */ } - &[data-selected]:not(:disabled) { + &:selected:not(:disabled) { background-color: var(--surface-raised-base-active); /* [data-slot="icon-svg"] { */ /* color: var(--icon-selected); */ diff --git a/packages/ui/src/components/icon.css b/packages/ui/src/components/icon.css index 467ff21bc..a2ebee30b 100644 --- a/packages/ui/src/components/icon.css +++ b/packages/ui/src/components/icon.css @@ -4,7 +4,7 @@ justify-content: center; flex-shrink: 0; /* resize: both; */ - aspect-ratio: 1 / 1; + aspect-ratio: 1/1; color: var(--icon-base); &[data-size="small"] { diff --git a/packages/ui/src/components/icon.tsx b/packages/ui/src/components/icon.tsx index 97488a42f..544c6abdd 100644 --- a/packages/ui/src/components/icon.tsx +++ b/packages/ui/src/components/icon.tsx @@ -80,16 +80,13 @@ const icons = { export interface IconProps extends ComponentProps<"svg"> { name: keyof typeof icons - size?: "small" | "normal" | "medium" | "large" | number + size?: "small" | "normal" | "medium" | "large" } export function Icon(props: IconProps) { const [local, others] = splitProps(props, ["name", "size", "class", "classList"]) return ( -
+
('[data-slot="list-item"][data-key]') @@ -268,7 +267,7 @@ export function List(props: ListProps & { ref?: (ref: ListRef) => void }) {searchAction()}
- +
0 || showAdd()} fallback={ @@ -340,7 +339,7 @@ export function List(props: ListProps & { ref?: (ref: ListRef) => void })
-
+
) } diff --git a/packages/ui/src/components/logo.css b/packages/ui/src/components/logo.css index 091649e8b..a909782b7 100644 --- a/packages/ui/src/components/logo.css +++ b/packages/ui/src/components/logo.css @@ -1,4 +1,4 @@ [data-component="logo-mark"] { width: 16px; - aspect-ratio: 4 / 5; + aspect-ratio: 4/5; } diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx index 9c975d549..7aad01ace 100644 --- a/packages/ui/src/components/message-part.tsx +++ b/packages/ui/src/components/message-part.tsx @@ -49,7 +49,6 @@ import { Tooltip } from "./tooltip" import { IconButton } from "./icon-button" import { createAutoScroll } from "../hooks" import { createResizeObserver } from "@solid-primitives/resize-observer" -import { MorphChevron } from "./morph-chevron" interface Diagnostic { range: { @@ -416,7 +415,7 @@ export function UserMessageDisplay(props: { message: UserMessage; parts: PartTyp toggleExpanded() }} > - +
props.expanded, - (expanded, prev) => { - if (prev === undefined) { - // Set initial state without animation - path?.setAttribute("d", expanded ? EXPANDED : COLLAPSED) - return - } - if (expanded) { - expandAnim?.beginElement() - } else { - collapseAnim?.beginElement() - } - }, - ), - ) - - return ( - - ) -} diff --git a/packages/ui/src/components/popover.css b/packages/ui/src/components/popover.css index d200fe8b2..b49542afd 100644 --- a/packages/ui/src/components/popover.css +++ b/packages/ui/src/components/popover.css @@ -15,35 +15,16 @@ transform-origin: var(--kb-popover-content-transform-origin); - animation: popoverContentHide var(--transition-duration) var(--transition-easing) forwards; - - @starting-style { - animation: none; - } - - &[data-expanded] { - pointer-events: auto; - animation: popoverContentShow var(--transition-duration) var(--transition-easing) forwards; - } - - [data-origin-top-right] { - transform-origin: top right; - } - - [data-origin-top-left] { - transform-origin: top left; - } - - [data-origin-bottom-right] { - transform-origin: bottom right; + &:focus-within { + outline: none; } - [data-origin-bottom-left] { - transform-origin: bottom left; + &[data-closed] { + animation: popover-close 0.15s ease-out; } - &:focus-within { - outline: none; + &[data-expanded] { + animation: popover-open 0.15s ease-out; } [data-slot="popover-header"] { @@ -94,39 +75,24 @@ } } -@keyframes popoverContentShow { +@keyframes popover-open { from { opacity: 0; - transform: scaleY(0.95); + transform: scale(0.96); } to { opacity: 1; - transform: scaleY(1); + transform: scale(1); } } -@keyframes popoverContentHide { +@keyframes popover-close { from { opacity: 1; - transform: scaleY(1); + transform: scale(1); } to { opacity: 0; - transform: scaleY(0.95); - } -} - -[data-component="model-popover-content"] { - transform-origin: var(--kb-popper-content-transform-origin); - pointer-events: none; - animation: popoverContentHide var(--transition-duration) var(--transition-easing) forwards; - - @starting-style { - animation: none; - } - - &[data-expanded] { - pointer-events: auto; - animation: popoverContentShow var(--transition-duration) var(--transition-easing) forwards; + transform: scale(0.96); } } diff --git a/packages/ui/src/components/progress-circle.css b/packages/ui/src/components/progress-circle.css index d8dc4e1d0..afaf72af6 100644 --- a/packages/ui/src/components/progress-circle.css +++ b/packages/ui/src/components/progress-circle.css @@ -1,10 +1,12 @@ [data-component="progress-circle"] { - color: inherit; + transform: rotate(-90deg); [data-slot="progress-circle-background"] { - transform-origin: 50% 50%; - transform: rotate(270deg); - stroke-opacity: 0.5; + stroke: var(--border-weak-base); + } + + [data-slot="progress-circle-progress"] { + stroke: var(--border-active); transition: stroke-dashoffset 0.35s cubic-bezier(0.65, 0, 0.35, 1); } } diff --git a/packages/ui/src/components/progress-circle.tsx b/packages/ui/src/components/progress-circle.tsx index 40d1e2022..02bd36bb7 100644 --- a/packages/ui/src/components/progress-circle.tsx +++ b/packages/ui/src/components/progress-circle.tsx @@ -1,4 +1,4 @@ -import { type ComponentProps, splitProps } from "solid-js" +import { type ComponentProps, createMemo, splitProps } from "solid-js" export interface ProgressCircleProps extends Pick, "class" | "classList"> { percentage: number @@ -9,15 +9,26 @@ export interface ProgressCircleProps extends Pick, "class" export function ProgressCircle(props: ProgressCircleProps) { const [split, rest] = splitProps(props, ["percentage", "size", "strokeWidth", "class", "classList"]) - const size = () => split.size || 18 - const r = 7 + const size = () => split.size || 16 + const strokeWidth = () => split.strokeWidth || 3 + + const viewBoxSize = 16 + const center = viewBoxSize / 2 + const radius = () => center - strokeWidth() / 2 + const circumference = createMemo(() => 2 * Math.PI * radius()) + + const offset = createMemo(() => { + const clampedPercentage = Math.max(0, Math.min(100, split.percentage || 0)) + const progress = clampedPercentage / 100 + return circumference() * (1 - progress) + }) return ( - - { - const pct = Math.min(100, Math.max(0, split.percentage)) - const angle = (pct / 100) * 2 * Math.PI - Math.PI / 2 - const x = 9 + r * Math.cos(angle) - const y = 9 + r * Math.sin(angle) - const largeArc = pct > 50 ? 1 : 0 - return `M9 2A${r} ${r} 0 ${largeArc} 1 ${x} ${y}L9 9Z` - })()} - fill="currentColor" + + ) diff --git a/packages/ui/src/components/radio-group.css b/packages/ui/src/components/radio-group.css index df51fc8e8..3d672bb30 100644 --- a/packages/ui/src/components/radio-group.css +++ b/packages/ui/src/components/radio-group.css @@ -27,9 +27,12 @@ content: ""; opacity: var(--indicator-opacity, 1); position: absolute; - transition-property: opacity, box-shadow, width, height, transform; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); + transition: + opacity 300ms ease-in-out, + box-shadow 100ms ease-in-out, + width 150ms ease, + height 150ms ease, + transform 150ms ease; } [data-slot="radio-group-item"] { @@ -43,9 +46,7 @@ content: ""; inset: 6px 0; position: absolute; - transition-property: opacity; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); + transition: opacity 150ms ease; width: 1px; transform: translateX(-0.5px); } @@ -71,9 +72,9 @@ padding: 6px 12px; place-content: center; position: relative; + transition-duration: 150ms; transition-property: color, opacity; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); + transition-timing-function: ease-in-out; user-select: none; } diff --git a/packages/ui/src/components/reasoning-icon.css b/packages/ui/src/components/reasoning-icon.css deleted file mode 100644 index b03f69a93..000000000 --- a/packages/ui/src/components/reasoning-icon.css +++ /dev/null @@ -1,8 +0,0 @@ -[data-component="reasoning-icon"] { - color: var(--icon-strong-base); - - [data-slot="reasoning-icon-percentage"] { - transition: clip-path 200ms cubic-bezier(0.25, 0, 0.5, 1); - clip-path: inset(calc(100% - var(--reasoning-icon-percentage) * 100%) 0 0 0); - } -} diff --git a/packages/ui/src/components/reasoning-icon.tsx b/packages/ui/src/components/reasoning-icon.tsx deleted file mode 100644 index 7bac49ffd..000000000 --- a/packages/ui/src/components/reasoning-icon.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { type ComponentProps, splitProps } from "solid-js" - -export interface ReasoningIconProps extends Pick, "class" | "classList"> { - percentage: number - size?: number - strokeWidth?: number -} - -export function ReasoningIcon(props: ReasoningIconProps) { - const [split, rest] = splitProps(props, ["percentage", "size", "strokeWidth", "class", "classList"]) - - const size = () => split.size || 16 - const strokeWidth = () => split.strokeWidth || 1.25 - - return ( - - - - - ) -} diff --git a/packages/ui/src/components/resize-handle.css b/packages/ui/src/components/resize-handle.css index 0aad9b967..c309ff838 100644 --- a/packages/ui/src/components/resize-handle.css +++ b/packages/ui/src/components/resize-handle.css @@ -6,9 +6,7 @@ content: ""; position: absolute; opacity: 0; - transition-property: opacity; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); + transition: opacity 0.15s ease-in-out; } &:hover::after, diff --git a/packages/ui/src/components/scroll-fade.css b/packages/ui/src/components/scroll-fade.css deleted file mode 100644 index ede5fabec..000000000 --- a/packages/ui/src/components/scroll-fade.css +++ /dev/null @@ -1,82 +0,0 @@ -[data-component="scroll-fade"] { - overflow: auto; - overscroll-behavior: contain; - scrollbar-width: none; - box-sizing: border-box; - color: inherit; - font: inherit; - -ms-overflow-style: none; - - &::-webkit-scrollbar { - display: none; - } - - &[data-direction="horizontal"] { - overflow-x: auto; - overflow-y: hidden; - - /* Both fades */ - &[data-fade-start][data-fade-end] { - mask-image: linear-gradient( - to right, - transparent, - black var(--scroll-fade-start), - black calc(100% - var(--scroll-fade-end)), - transparent - ); - -webkit-mask-image: linear-gradient( - to right, - transparent, - black var(--scroll-fade-start), - black calc(100% - var(--scroll-fade-end)), - transparent - ); - } - - /* Only start fade */ - &[data-fade-start]:not([data-fade-end]) { - mask-image: linear-gradient(to right, transparent, black var(--scroll-fade-start), black 100%); - -webkit-mask-image: linear-gradient(to right, transparent, black var(--scroll-fade-start), black 100%); - } - - /* Only end fade */ - &:not([data-fade-start])[data-fade-end] { - mask-image: linear-gradient(to right, black 0%, black calc(100% - var(--scroll-fade-end)), transparent); - -webkit-mask-image: linear-gradient(to right, black 0%, black calc(100% - var(--scroll-fade-end)), transparent); - } - } - - &[data-direction="vertical"] { - overflow-y: auto; - overflow-x: hidden; - - &[data-fade-start][data-fade-end] { - mask-image: linear-gradient( - to bottom, - transparent, - black var(--scroll-fade-start), - black calc(100% - var(--scroll-fade-end)), - transparent - ); - -webkit-mask-image: linear-gradient( - to bottom, - transparent, - black var(--scroll-fade-start), - black calc(100% - var(--scroll-fade-end)), - transparent - ); - } - - /* Only start fade */ - &[data-fade-start]:not([data-fade-end]) { - mask-image: linear-gradient(to bottom, transparent, black var(--scroll-fade-start), black 100%); - -webkit-mask-image: linear-gradient(to bottom, transparent, black var(--scroll-fade-start), black 100%); - } - - /* Only end fade */ - &:not([data-fade-start])[data-fade-end] { - mask-image: linear-gradient(to bottom, black 0%, black calc(100% - var(--scroll-fade-end)), transparent); - -webkit-mask-image: linear-gradient(to bottom, black 0%, black calc(100% - var(--scroll-fade-end)), transparent); - } - } -} diff --git a/packages/ui/src/components/scroll-fade.tsx b/packages/ui/src/components/scroll-fade.tsx deleted file mode 100644 index 0effb678a..000000000 --- a/packages/ui/src/components/scroll-fade.tsx +++ /dev/null @@ -1,207 +0,0 @@ -import { type JSX, createEffect, createSignal, onCleanup, onMount, splitProps } from "solid-js" -import "./scroll-fade.css" - -export interface ScrollFadeProps extends JSX.HTMLAttributes { - direction?: "horizontal" | "vertical" - fadeStartSize?: number - fadeEndSize?: number - trackTransformSelector?: string - ref?: (el: HTMLDivElement) => void -} - -export function ScrollFade(props: ScrollFadeProps) { - const [local, others] = splitProps(props, [ - "children", - "direction", - "fadeStartSize", - "fadeEndSize", - "trackTransformSelector", - "class", - "style", - "ref", - ]) - - const direction = () => local.direction ?? "vertical" - const fadeStartSize = () => local.fadeStartSize ?? 20 - const fadeEndSize = () => local.fadeEndSize ?? 20 - - const getTransformOffset = (element: Element): number => { - const style = getComputedStyle(element) - const transform = style.transform - if (!transform || transform === "none") return 0 - - const match = transform.match(/matrix(?:3d)?\(([^)]+)\)/) - if (!match) return 0 - - const values = match[1].split(",").map((v) => parseFloat(v.trim())) - const isHorizontal = direction() === "horizontal" - - if (transform.startsWith("matrix3d")) { - return isHorizontal ? -(values[12] || 0) : -(values[13] || 0) - } else { - return isHorizontal ? -(values[4] || 0) : -(values[5] || 0) - } - } - - let containerRef: HTMLDivElement | undefined - - const [fadeStart, setFadeStart] = createSignal(0) - const [fadeEnd, setFadeEnd] = createSignal(0) - const [isScrollable, setIsScrollable] = createSignal(false) - - let lastScrollPos = 0 - let lastTransformPos = 0 - let lastScrollSize = 0 - let lastClientSize = 0 - - const updateFade = () => { - if (!containerRef) return - - const isHorizontal = direction() === "horizontal" - const scrollPos = isHorizontal ? containerRef.scrollLeft : containerRef.scrollTop - const scrollSize = isHorizontal ? containerRef.scrollWidth : containerRef.scrollHeight - const clientSize = isHorizontal ? containerRef.clientWidth : containerRef.clientHeight - - let transformPos = 0 - if (local.trackTransformSelector) { - const transformElement = containerRef.querySelector(local.trackTransformSelector) - if (transformElement) { - transformPos = getTransformOffset(transformElement) - } - } - - const effectiveScrollPos = Math.max(scrollPos, transformPos) - - if ( - effectiveScrollPos === lastScrollPos && - transformPos === lastTransformPos && - scrollSize === lastScrollSize && - clientSize === lastClientSize - ) { - return - } - - lastScrollPos = effectiveScrollPos - lastTransformPos = transformPos - lastScrollSize = scrollSize - lastClientSize = clientSize - - const maxScroll = scrollSize - clientSize - const canScroll = maxScroll > 1 - - setIsScrollable(canScroll) - - if (!canScroll) { - setFadeStart(0) - setFadeEnd(0) - return - } - - const progress = maxScroll > 0 ? effectiveScrollPos / maxScroll : 0 - - const startProgress = Math.min(progress / 0.1, 1) - setFadeStart(startProgress * fadeStartSize()) - - const endProgress = progress > 0.9 ? (1 - progress) / 0.1 : 1 - setFadeEnd(Math.max(0, endProgress) * fadeEndSize()) - } - - onMount(() => { - if (!containerRef) return - - updateFade() - - let rafId: number | undefined - let isPolling = false - let pollTimeout: ReturnType | undefined - - const startPolling = () => { - if (isPolling) return - isPolling = true - - const pollScroll = () => { - updateFade() - rafId = requestAnimationFrame(pollScroll) - } - rafId = requestAnimationFrame(pollScroll) - } - - const stopPolling = () => { - if (!isPolling) return - isPolling = false - if (rafId !== undefined) { - cancelAnimationFrame(rafId) - rafId = undefined - } - } - - const schedulePollingStop = () => { - if (pollTimeout !== undefined) clearTimeout(pollTimeout) - pollTimeout = setTimeout(stopPolling, 1000) - } - - const onActivity = () => { - updateFade() - if (local.trackTransformSelector) { - startPolling() - schedulePollingStop() - } - } - - containerRef.addEventListener("scroll", onActivity, { passive: true }) - - const resizeObserver = new ResizeObserver(() => { - lastScrollSize = 0 - lastClientSize = 0 - onActivity() - }) - resizeObserver.observe(containerRef) - - const mutationObserver = new MutationObserver(() => { - lastScrollSize = 0 - lastClientSize = 0 - requestAnimationFrame(onActivity) - }) - mutationObserver.observe(containerRef, { - childList: true, - subtree: true, - characterData: true, - }) - - onCleanup(() => { - containerRef?.removeEventListener("scroll", onActivity) - resizeObserver.disconnect() - mutationObserver.disconnect() - stopPolling() - if (pollTimeout !== undefined) clearTimeout(pollTimeout) - }) - }) - - createEffect(() => { - local.children - requestAnimationFrame(updateFade) - }) - - return ( -
{ - containerRef = el - local.ref?.(el) - }} - data-component="scroll-fade" - data-direction={direction()} - data-scrollable={isScrollable() || undefined} - data-fade-start={fadeStart() > 0 || undefined} - data-fade-end={fadeEnd() > 0 || undefined} - class={local.class} - style={{ - ...(typeof local.style === "object" ? local.style : {}), - "--scroll-fade-start": `${fadeStart()}px`, - "--scroll-fade-end": `${fadeEnd()}px`, - }} - {...others} - > - {local.children} -
- ) -} diff --git a/packages/ui/src/components/scroll-reveal.tsx b/packages/ui/src/components/scroll-reveal.tsx deleted file mode 100644 index 6e5072dc8..000000000 --- a/packages/ui/src/components/scroll-reveal.tsx +++ /dev/null @@ -1,141 +0,0 @@ -import { type JSX, onCleanup, splitProps } from "solid-js" -import { ScrollFade, type ScrollFadeProps } from "./scroll-fade" - -const SCROLL_SPEED = 60 -const PAUSE_DURATION = 800 - -type ScrollAnimationState = { - rafId: number | null - startTime: number - running: boolean -} - -const startScrollAnimation = (containerEl: HTMLElement): ScrollAnimationState | null => { - containerEl.offsetHeight - - const extraWidth = containerEl.scrollWidth - containerEl.clientWidth - - if (extraWidth <= 0) { - return null - } - - const scrollDuration = (extraWidth / SCROLL_SPEED) * 1000 - const totalDuration = PAUSE_DURATION + scrollDuration + PAUSE_DURATION + scrollDuration + PAUSE_DURATION - - const state: ScrollAnimationState = { - rafId: null, - startTime: performance.now(), - running: true, - } - - const animate = (currentTime: number) => { - if (!state.running) return - - const elapsed = currentTime - state.startTime - const progress = (elapsed % totalDuration) / totalDuration - - const pausePercent = PAUSE_DURATION / totalDuration - const scrollPercent = scrollDuration / totalDuration - - const pauseEnd1 = pausePercent - const scrollEnd1 = pauseEnd1 + scrollPercent - const pauseEnd2 = scrollEnd1 + pausePercent - const scrollEnd2 = pauseEnd2 + scrollPercent - - let scrollPos = 0 - - if (progress < pauseEnd1) { - scrollPos = 0 - } else if (progress < scrollEnd1) { - const scrollProgress = (progress - pauseEnd1) / scrollPercent - scrollPos = scrollProgress * extraWidth - } else if (progress < pauseEnd2) { - scrollPos = extraWidth - } else if (progress < scrollEnd2) { - const scrollProgress = (progress - pauseEnd2) / scrollPercent - scrollPos = extraWidth * (1 - scrollProgress) - } else { - scrollPos = 0 - } - - containerEl.scrollLeft = scrollPos - state.rafId = requestAnimationFrame(animate) - } - - state.rafId = requestAnimationFrame(animate) - return state -} - -const stopScrollAnimation = (state: ScrollAnimationState | null, containerEl?: HTMLElement) => { - if (state) { - state.running = false - if (state.rafId !== null) { - cancelAnimationFrame(state.rafId) - } - } - if (containerEl) { - containerEl.scrollLeft = 0 - } -} - -export interface ScrollRevealProps extends Omit { - hoverDelay?: number -} - -export function ScrollReveal(props: ScrollRevealProps) { - const [local, others] = splitProps(props, ["children", "hoverDelay", "ref"]) - - const hoverDelay = () => local.hoverDelay ?? 300 - - let containerRef: HTMLDivElement | undefined - let hoverTimeout: ReturnType | undefined - let scrollAnimationState: ScrollAnimationState | null = null - - const handleMouseEnter: JSX.EventHandler = () => { - hoverTimeout = setTimeout(() => { - if (!containerRef) return - - containerRef.offsetHeight - - const isScrollable = containerRef.scrollWidth > containerRef.clientWidth + 1 - - if (isScrollable) { - stopScrollAnimation(scrollAnimationState, containerRef) - scrollAnimationState = startScrollAnimation(containerRef) - } - }, hoverDelay()) - } - - const handleMouseLeave: JSX.EventHandler = () => { - if (hoverTimeout) { - clearTimeout(hoverTimeout) - hoverTimeout = undefined - } - stopScrollAnimation(scrollAnimationState, containerRef) - scrollAnimationState = null - } - - onCleanup(() => { - if (hoverTimeout) { - clearTimeout(hoverTimeout) - } - stopScrollAnimation(scrollAnimationState, containerRef) - }) - - return ( - { - containerRef = el - local.ref?.(el) - }} - fadeStartSize={8} - fadeEndSize={8} - direction="horizontal" - onMouseEnter={handleMouseEnter} - onMouseLeave={handleMouseLeave} - {...others} - > - {local.children} - - ) -} diff --git a/packages/ui/src/components/select.css b/packages/ui/src/components/select.css index 5c7969883..25dd2eb40 100644 --- a/packages/ui/src/components/select.css +++ b/packages/ui/src/components/select.css @@ -1,13 +1,7 @@ [data-component="select"] { [data-slot="select-select-trigger"] { - display: flex; - padding: 4px 8px !important; - align-items: center; - justify-content: space-between; + padding: 0 4px 0 8px; box-shadow: none; - transition-property: background-color; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); [data-slot="select-select-trigger-value"] { overflow: hidden; @@ -21,10 +15,10 @@ align-items: center; justify-content: center; flex-shrink: 0; - color: var(--icon-base); + color: var(--text-weak); + transition: transform 0.1s ease-in-out; } - &:hover, &[data-expanded] { &[data-variant="secondary"] { background-color: var(--button-secondary-hover); @@ -36,42 +30,78 @@ background-color: var(--icon-strong-active); } } - &:not([data-expanded]):focus, + &:not([data-expanded]):focus-visible { &[data-variant="secondary"] { background-color: var(--button-secondary-base); } &[data-variant="ghost"] { - background-color: transparent; + background-color: var(--surface-raised-base-hover); } &[data-variant="primary"] { background-color: var(--icon-strong-base); } } } + + &[data-trigger-style="settings"] { + [data-slot="select-select-trigger"] { + padding: 6px 6px 6px 12px; + box-shadow: none; + border-radius: 6px; + min-width: 160px; + height: 32px; + justify-content: flex-end; + gap: 12px; + background-color: transparent; + + [data-slot="select-select-trigger-value"] { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: var(--font-size-base); + font-weight: var(--font-weight-regular); + } + [data-slot="select-select-trigger-icon"] { + width: 16px; + height: 20px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + color: var(--text-weak); + background-color: var(--surface-raised-base); + border-radius: 4px; + transition: transform 0.1s ease-in-out; + } + + &[data-slot="select-select-trigger"]:hover:not(:disabled), + &[data-slot="select-select-trigger"][data-expanded], + &[data-slot="select-select-trigger"][data-expanded]:hover:not(:disabled) { + background-color: var(--input-base); + box-shadow: var(--shadow-xs-border-base); + } + + &:not([data-expanded]):focus { + background-color: transparent; + box-shadow: none; + } + } + } } [data-component="select-content"] { - min-width: 8rem; + min-width: 104px; max-width: 23rem; overflow: hidden; border-radius: var(--radius-md); background-color: var(--surface-raised-stronger-non-alpha); padding: 4px; box-shadow: var(--shadow-xs-border); - z-index: 50; - transform-origin: var(--kb-popper-content-transform-origin); - pointer-events: none; - - animation: selectContentHide var(--transition-duration) var(--transition-easing) forwards; - - @starting-style { - animation: none; - } + z-index: 60; &[data-expanded] { - pointer-events: auto; - animation: selectContentShow var(--transition-duration) var(--transition-easing) forwards; + animation: select-open 0.15s ease-out; } [data-slot="select-select-content-list"] { @@ -81,38 +111,43 @@ overflow-x: hidden; display: flex; flex-direction: column; + &:focus { outline: none; } + > *:not([role="presentation"]) + *:not([role="presentation"]) { margin-top: 2px; } } + [data-slot="select-select-item"] { position: relative; display: flex; align-items: center; - padding: 4px 8px; + padding: 2px 8px; gap: 12px; - border-radius: var(--radius-sm); + border-radius: 4px; + cursor: default; /* text-12-medium */ font-family: var(--font-family-sans); - font-size: var(--font-size-base); + font-size: var(--font-size-small); font-style: normal; font-weight: var(--font-weight-medium); line-height: var(--line-height-large); /* 166.667% */ letter-spacing: var(--letter-spacing-normal); + color: var(--text-strong); - transition-property: background-color, color; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); + transition: + background-color 0.2s ease-in-out, + color 0.2s ease-in-out; outline: none; user-select: none; - &:hover { - background-color: var(--surface-raised-base-hover); + &[data-highlighted] { + background: var(--surface-raised-base-hover); } &[data-disabled] { background-color: var(--surface-raised-base); @@ -125,11 +160,6 @@ margin-left: auto; width: 16px; height: 16px; - color: var(--icon-strong-base); - - svg { - color: var(--icon-strong-base); - } } &:focus { outline: none; @@ -140,24 +170,33 @@ } } -@keyframes selectContentShow { - from { - opacity: 0; - transform: scaleY(0.95); +[data-component="select-content"][data-trigger-style="settings"] { + min-width: 160px; + border-radius: 8px; + padding: 0; + + [data-slot="select-select-content-list"] { + padding: 4px; } - to { - opacity: 1; - transform: scaleY(1); + + [data-slot="select-select-item"] { + /* text-14-regular */ + font-family: var(--font-family-sans); + font-size: var(--font-size-base); + font-style: normal; + font-weight: var(--font-weight-regular); + line-height: var(--line-height-large); + letter-spacing: var(--letter-spacing-normal); } } -@keyframes selectContentHide { +@keyframes select-open { from { - opacity: 1; - transform: scaleY(1); + opacity: 0; + transform: scale(0.95); } to { - opacity: 0; - transform: scaleY(0.95); + opacity: 1; + transform: scale(1); } } diff --git a/packages/ui/src/components/select.tsx b/packages/ui/src/components/select.tsx index fef00500a..0386c329e 100644 --- a/packages/ui/src/components/select.tsx +++ b/packages/ui/src/components/select.tsx @@ -1,10 +1,8 @@ import { Select as Kobalte } from "@kobalte/core/select" -import { createMemo, createSignal, onCleanup, splitProps, type ComponentProps, type JSX } from "solid-js" +import { createMemo, onCleanup, splitProps, type ComponentProps, type JSX } from "solid-js" import { pipe, groupBy, entries, map } from "remeda" -import { Show } from "solid-js" import { Button, ButtonProps } from "./button" import { Icon } from "./icon" -import { MorphChevron } from "./morph-chevron" export type SelectProps = Omit>, "value" | "onSelect" | "children"> & { placeholder?: string @@ -40,8 +38,6 @@ export function Select(props: SelectProps & Omit) "triggerVariant", ]) - const [isOpen, setIsOpen] = createSignal(false) - const state = { key: undefined as string | undefined, cleanup: undefined as (() => void) | void, @@ -89,7 +85,7 @@ export function Select(props: SelectProps & Omit) data-component="select" data-trigger-style={local.triggerVariant} placement={local.triggerVariant === "settings" ? "bottom-end" : "bottom-start"} - gutter={8} + gutter={4} value={local.current} options={grouped()} optionValue={(x) => (local.value ? local.value(x) : (x as string))} @@ -119,7 +115,7 @@ export function Select(props: SelectProps & Omit) : (itemProps.item.rawValue as string)} - + )} @@ -128,7 +124,6 @@ export function Select(props: SelectProps & Omit) stop() }} onOpenChange={(open) => { - setIsOpen(open) local.onOpenChange?.(open) if (!open) stop() }} @@ -154,12 +149,7 @@ export function Select(props: SelectProps & Omit) }} - - - - - - + diff --git a/packages/ui/src/components/session-review.css b/packages/ui/src/components/session-review.css index 4fc88b199..20d2fef15 100644 --- a/packages/ui/src/components/session-review.css +++ b/packages/ui/src/components/session-review.css @@ -63,8 +63,12 @@ [data-slot="accordion-item"] { [data-slot="accordion-content"] { - /* Use grid-template-rows for smooth height transition */ - display: grid; + display: none; + } + &[data-expanded] { + [data-slot="accordion-content"] { + display: block; + } } } @@ -126,9 +130,7 @@ cursor: pointer; border-radius: 4px; opacity: 0; - transition-property: opacity, background-color, color; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); + transition: opacity 0.15s ease; &:hover { color: var(--text-strong); diff --git a/packages/ui/src/components/session-review.tsx b/packages/ui/src/components/session-review.tsx index b5a359707..84ec934e2 100644 --- a/packages/ui/src/components/session-review.tsx +++ b/packages/ui/src/components/session-review.tsx @@ -290,8 +290,8 @@ export const SessionReview = (props: SessionReviewProps) => {
{i18n.t("ui.sessionReview.title")}
- - options={["unified", "split"]} + style} label={(style) => @@ -501,7 +501,6 @@ export const SessionReview = (props: SessionReviewProps) => { value={diff.file} id={diffId(diff.file)} data-file={diff.file} - expanded={open().includes(diff.file)} data-slot="session-review-accordion-item" data-selected={props.focusedFile === diff.file ? "" : undefined} > diff --git a/packages/ui/src/components/session-turn.css b/packages/ui/src/components/session-turn.css index 088b377cb..d1ade879e 100644 --- a/packages/ui/src/components/session-turn.css +++ b/packages/ui/src/components/session-turn.css @@ -102,11 +102,10 @@ [data-component="user-message"] [data-slot="user-message-text"] { max-height: var(--user-message-collapsed-height, 64px); - transition: max-height 200ms cubic-bezier(0.25, 0, 0.5, 1); } [data-component="user-message"][data-expanded="true"] [data-slot="user-message-text"] { - max-height: 2000px; + max-height: none; } [data-component="user-message"][data-can-expand="true"] [data-slot="user-message-text"] { @@ -152,6 +151,17 @@ background: transparent; cursor: pointer; color: var(--text-weak); + + [data-slot="icon-svg"] { + transition: transform 0.15s ease; + } + } + + [data-component="user-message"][data-expanded="true"] + [data-slot="user-message-text"] + [data-slot="user-message-expand"] + [data-slot="icon-svg"] { + transform: rotate(180deg); } [data-component="user-message"] [data-slot="user-message-text"] [data-slot="user-message-expand"]:hover { @@ -457,7 +467,6 @@ gap: 16px; align-items: center; justify-content: flex-end; - color: var(--icon-base); } [data-slot="session-turn-accordion-content"] { diff --git a/packages/ui/src/components/switch.css b/packages/ui/src/components/switch.css index 9ea722760..89e844732 100644 --- a/packages/ui/src/components/switch.css +++ b/packages/ui/src/components/switch.css @@ -26,9 +26,9 @@ border-radius: 3px; border: 1px solid var(--border-weak-base); background: var(--surface-base); - transition-property: background-color, border-color, box-shadow; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); + transition: + background-color 150ms, + border-color 150ms; } [data-slot="switch-thumb"] { @@ -47,9 +47,9 @@ 0 1px 3px 0 rgba(19, 16, 16, 0.08); transform: translateX(-1px); - transition-property: transform, background-color, border-color; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); + transition: + transform 150ms, + background-color 150ms; } [data-slot="switch-label"] { diff --git a/packages/ui/src/components/tabs.css b/packages/ui/src/components/tabs.css index dab07dab9..56c3e083f 100644 --- a/packages/ui/src/components/tabs.css +++ b/packages/ui/src/components/tabs.css @@ -58,9 +58,6 @@ border-bottom: 1px solid var(--border-weak-base); border-right: 1px solid var(--border-weak-base); background-color: var(--background-base); - transition-property: background-color, border-color, color; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); [data-slot="tabs-trigger"] { display: flex; diff --git a/packages/ui/src/components/tag.css b/packages/ui/src/components/tag.css index 5ffd2b911..0e8b7b9f1 100644 --- a/packages/ui/src/components/tag.css +++ b/packages/ui/src/components/tag.css @@ -8,9 +8,6 @@ border: 0.5px solid var(--border-weak-base); background: var(--surface-raised-base); color: var(--text-base); - transition-property: background-color, border-color, color; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); &[data-size="normal"] { height: 18px; diff --git a/packages/ui/src/context/dialog.tsx b/packages/ui/src/context/dialog.tsx index 413212512..afba5f648 100644 --- a/packages/ui/src/context/dialog.tsx +++ b/packages/ui/src/context/dialog.tsx @@ -28,7 +28,6 @@ const Context = createContext>() function init() { const [active, setActive] = createSignal() - const [renders, setRenders] = createSignal>({}) const timer = { current: undefined as ReturnType | undefined } const lock = { value: false } @@ -119,32 +118,12 @@ function init() { setActive({ id, node, dispose, owner, onClose, setClosing }) } - const render = (element: JSX.Element, id: string, owner: Owner) => { - setRenders((renders) => ({ ...renders, [id]: element })) - show( - () => element, - owner, - () => { - setRenders((renders) => { - const { [id]: _, ...rest } = renders - return rest - }) - }, - ) - } - - const isActive = (id: string) => { - return renders()[id] !== undefined - } - return { get active() { return active() }, - isActive, close, show, - render, } } @@ -173,17 +152,10 @@ export function useDialog() { get active() { return ctx.active }, - isActive(id: string) { - return ctx.isActive(id) - }, show(element: DialogElement, onClose?: () => void) { const base = ctx.active?.owner ?? owner ctx.show(element, base, onClose) }, - render(element: JSX.Element, id: string) { - const base = ctx.active?.owner ?? owner - ctx.render(element, id, base) - }, close() { ctx.close() }, diff --git a/packages/ui/src/styles/index.css b/packages/ui/src/styles/index.css index 7c8548734..3ed0310ef 100644 --- a/packages/ui/src/styles/index.css +++ b/packages/ui/src/styles/index.css @@ -33,10 +33,8 @@ @import "../components/markdown.css" layer(components); @import "../components/message-part.css" layer(components); @import "../components/message-nav.css" layer(components); -@import "../components/morph-chevron.css" layer(components); @import "../components/popover.css" layer(components); @import "../components/progress-circle.css" layer(components); -@import "../components/reasoning-icon.css" layer(components); @import "../components/radio-group.css" layer(components); @import "../components/resize-handle.css" layer(components); @import "../components/select.css" layer(components); diff --git a/packages/ui/src/styles/utilities.css b/packages/ui/src/styles/utilities.css index 82a913c88..8c954f1fe 100644 --- a/packages/ui/src/styles/utilities.css +++ b/packages/ui/src/styles/utilities.css @@ -1,17 +1,6 @@ :root { interpolate-size: allow-keywords; - /* Transition tokens */ - --transition-duration: 200ms; - --transition-easing: cubic-bezier(0.25, 0, 0.5, 1); - --transition-fast: 150ms; - --transition-slow: 300ms; - - /* Allow height transitions from 0 to auto */ - @supports (interpolate-size: allow-keywords) { - interpolate-size: allow-keywords; - } - [data-popper-positioner] { pointer-events: none; } @@ -140,34 +129,3 @@ line-height: var(--line-height-x-large); /* 120% */ letter-spacing: var(--letter-spacing-tightest); } - -/* Transition utility classes */ -.transition-colors { - transition-property: background-color, border-color, color, fill, stroke; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); -} - -.transition-opacity { - transition-property: opacity; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); -} - -.transition-transform { - transition-property: transform; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); -} - -.transition-shadow { - transition-property: box-shadow; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); -} - -.transition-interactive { - transition-property: background-color, border-color, color, box-shadow, opacity; - transition-duration: var(--transition-duration); - transition-timing-function: var(--transition-easing); -} From 597ae57bb16ea8b4314f718bc3250c8b9433d7dc Mon Sep 17 00:00:00 2001 From: opencode Date: Sat, 31 Jan 2026 13:48:22 +0000 Subject: [PATCH 35/40] release: v1.1.48 --- bun.lock | 30 +++++++++++++------------- packages/app/package.json | 2 +- packages/console/app/package.json | 2 +- packages/console/core/package.json | 2 +- packages/console/function/package.json | 2 +- packages/console/mail/package.json | 2 +- packages/desktop/package.json | 2 +- packages/enterprise/package.json | 2 +- packages/extensions/zed/extension.toml | 12 +++++------ packages/function/package.json | 2 +- packages/opencode/package.json | 2 +- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- packages/slack/package.json | 2 +- packages/ui/package.json | 2 +- packages/util/package.json | 2 +- packages/web/package.json | 2 +- sdks/vscode/package.json | 2 +- 18 files changed, 37 insertions(+), 37 deletions(-) diff --git a/bun.lock b/bun.lock index 746360f1b..085728363 100644 --- a/bun.lock +++ b/bun.lock @@ -23,7 +23,7 @@ }, "packages/app": { "name": "@opencode-ai/app", - "version": "1.1.47", + "version": "1.1.48", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -73,7 +73,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.1.47", + "version": "1.1.48", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -107,7 +107,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.1.47", + "version": "1.1.48", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -134,7 +134,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.1.47", + "version": "1.1.48", "dependencies": { "@ai-sdk/anthropic": "2.0.0", "@ai-sdk/openai": "2.0.2", @@ -158,7 +158,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.1.47", + "version": "1.1.48", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -182,7 +182,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.1.47", + "version": "1.1.48", "dependencies": { "@opencode-ai/app": "workspace:*", "@opencode-ai/ui": "workspace:*", @@ -213,7 +213,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.1.47", + "version": "1.1.48", "dependencies": { "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", @@ -242,7 +242,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.1.47", + "version": "1.1.48", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -258,7 +258,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.1.47", + "version": "1.1.48", "bin": { "opencode": "./bin/opencode", }, @@ -362,7 +362,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.1.47", + "version": "1.1.48", "dependencies": { "@opencode-ai/sdk": "workspace:*", "zod": "catalog:", @@ -382,7 +382,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.1.47", + "version": "1.1.48", "devDependencies": { "@hey-api/openapi-ts": "0.90.10", "@tsconfig/node22": "catalog:", @@ -393,7 +393,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.1.47", + "version": "1.1.48", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -406,7 +406,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.1.47", + "version": "1.1.48", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -448,7 +448,7 @@ }, "packages/util": { "name": "@opencode-ai/util", - "version": "1.1.47", + "version": "1.1.48", "dependencies": { "zod": "catalog:", }, @@ -459,7 +459,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.1.47", + "version": "1.1.48", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", diff --git a/packages/app/package.json b/packages/app/package.json index f9866cfda..e1232cb1c 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "1.1.47", + "version": "1.1.48", "description": "", "type": "module", "exports": { diff --git a/packages/console/app/package.json b/packages/console/app/package.json index 7fdb09a46..83405bf63 100644 --- a/packages/console/app/package.json +++ b/packages/console/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-app", - "version": "1.1.47", + "version": "1.1.48", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/console/core/package.json b/packages/console/core/package.json index 3ee986080..d110dc117 100644 --- a/packages/console/core/package.json +++ b/packages/console/core/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/console-core", - "version": "1.1.47", + "version": "1.1.48", "private": true, "type": "module", "license": "MIT", diff --git a/packages/console/function/package.json b/packages/console/function/package.json index bf8abdabb..e04aa5e31 100644 --- a/packages/console/function/package.json +++ b/packages/console/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-function", - "version": "1.1.47", + "version": "1.1.48", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/console/mail/package.json b/packages/console/mail/package.json index a4eaeec08..1f69a0c75 100644 --- a/packages/console/mail/package.json +++ b/packages/console/mail/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-mail", - "version": "1.1.47", + "version": "1.1.48", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 993489de9..4f60bd58a 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/desktop", "private": true, - "version": "1.1.47", + "version": "1.1.48", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index b7bf51afb..4e901e23e 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/enterprise", - "version": "1.1.47", + "version": "1.1.48", "private": true, "type": "module", "license": "MIT", diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index 527ea3994..576d6bbcd 100644 --- a/packages/extensions/zed/extension.toml +++ b/packages/extensions/zed/extension.toml @@ -1,7 +1,7 @@ id = "opencode" name = "OpenCode" description = "The open source coding agent." -version = "1.1.47" +version = "1.1.48" schema_version = 1 authors = ["Anomaly"] repository = "https://github.com/anomalyco/opencode" @@ -11,26 +11,26 @@ name = "OpenCode" icon = "./icons/opencode.svg" [agent_servers.opencode.targets.darwin-aarch64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.47/opencode-darwin-arm64.zip" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.48/opencode-darwin-arm64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.darwin-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.47/opencode-darwin-x64.zip" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.48/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.47/opencode-linux-arm64.tar.gz" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.48/opencode-linux-arm64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.47/opencode-linux-x64.tar.gz" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.48/opencode-linux-x64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.windows-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.47/opencode-windows-x64.zip" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.1.48/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/function/package.json b/packages/function/package.json index 6fdb0d309..88792e1e6 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/function", - "version": "1.1.47", + "version": "1.1.48", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 9d60283e8..4afb72430 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.1.47", + "version": "1.1.48", "name": "opencode", "type": "module", "license": "MIT", diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 2bcc3e8f9..5a4afbae4 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/plugin", - "version": "1.1.47", + "version": "1.1.48", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 0fc2cac34..f9bf9c1e0 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/sdk", - "version": "1.1.47", + "version": "1.1.48", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/slack/package.json b/packages/slack/package.json index 41879e230..3f5a30fad 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/slack", - "version": "1.1.47", + "version": "1.1.48", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/ui/package.json b/packages/ui/package.json index 5db88629f..769233119 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "1.1.47", + "version": "1.1.48", "type": "module", "license": "MIT", "exports": { diff --git a/packages/util/package.json b/packages/util/package.json index b776ce2ee..9a3f13b10 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/util", - "version": "1.1.47", + "version": "1.1.48", "private": true, "type": "module", "license": "MIT", diff --git a/packages/web/package.json b/packages/web/package.json index 7d2eb66cf..2db4cffe9 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -2,7 +2,7 @@ "name": "@opencode-ai/web", "type": "module", "license": "MIT", - "version": "1.1.47", + "version": "1.1.48", "scripts": { "dev": "astro dev", "dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev", diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json index 405514cca..2f4a49964 100644 --- a/sdks/vscode/package.json +++ b/sdks/vscode/package.json @@ -2,7 +2,7 @@ "name": "opencode", "displayName": "opencode", "description": "opencode for VS Code", - "version": "1.1.47", + "version": "1.1.48", "publisher": "sst-dev", "repository": { "type": "git", From b0b442da2ce107345a3767fedf95f43309939797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Catriel=20M=C3=BCller?= Date: Wed, 4 Feb 2026 14:43:20 -0300 Subject: [PATCH 36/40] refactor: kilo compat for v1.1.48 --- github/index.ts | 8 +- github/package.json | 5 +- package.json | 7 +- packages/app/e2e/utils.ts | 2 +- packages/app/package.json | 7 +- .../components/dialog-connect-provider.tsx | 2 +- .../src/components/dialog-custom-provider.tsx | 2 +- packages/app/src/components/dialog-fork.tsx | 2 +- .../src/components/dialog-select-server.tsx | 2 +- packages/app/src/components/file-tree.tsx | 2 +- packages/app/src/components/prompt-input.tsx | 2 +- .../src/components/session-context-usage.tsx | 2 +- .../session/session-context-tab.tsx | 2 +- .../app/src/components/settings-general.tsx | 2 +- .../app/src/components/status-popover.tsx | 2 +- packages/app/src/context/file.tsx | 2 +- packages/app/src/context/global-sdk.tsx | 2 +- packages/app/src/context/global-sync.tsx | 2 +- packages/app/src/context/highlights.tsx | 2 +- packages/app/src/context/layout.tsx | 2 +- packages/app/src/context/notification.tsx | 2 +- packages/app/src/context/permission.tsx | 2 +- packages/app/src/context/sdk.tsx | 2 +- packages/app/src/context/server.tsx | 2 +- packages/app/src/context/sync.tsx | 2 +- packages/app/src/i18n/ar.ts | 30 +++---- packages/app/src/i18n/br.ts | 30 +++---- packages/app/src/i18n/da.ts | 30 +++---- packages/app/src/i18n/de.ts | 30 +++---- packages/app/src/i18n/en.ts | 30 +++---- packages/app/src/i18n/es.ts | 30 +++---- packages/app/src/i18n/fr.ts | 30 +++---- packages/app/src/i18n/ja.ts | 30 +++---- packages/app/src/i18n/ko.ts | 30 +++---- packages/app/src/i18n/no.ts | 30 +++---- packages/app/src/i18n/pl.ts | 30 +++---- packages/app/src/i18n/ru.ts | 30 +++---- packages/app/src/i18n/th.ts | 26 +++--- packages/app/src/i18n/zh.ts | 30 +++---- packages/app/src/i18n/zht.ts | 30 +++---- packages/app/src/pages/directory-layout.tsx | 2 +- packages/app/src/pages/error.tsx | 2 +- packages/app/src/pages/layout.tsx | 6 +- packages/app/src/pages/session.tsx | 4 +- packages/app/src/utils/prompt.ts | 2 +- packages/console/app/package.json | 2 +- packages/console/core/package.json | 2 +- packages/console/function/package.json | 2 +- packages/console/mail/package.json | 2 +- packages/console/resource/package.json | 3 +- packages/desktop/package.json | 2 +- packages/desktop/src-tauri/Cargo.toml | 4 +- packages/desktop/src-tauri/src/cli.rs | 6 +- packages/desktop/src-tauri/src/lib.rs | 4 +- packages/desktop/src-tauri/src/main.rs | 2 +- packages/desktop/src-tauri/tauri.conf.json | 10 +-- .../desktop/src-tauri/tauri.prod.conf.json | 6 +- packages/desktop/src/i18n/ar.ts | 8 +- packages/desktop/src/i18n/br.ts | 8 +- packages/desktop/src/i18n/da.ts | 8 +- packages/desktop/src/i18n/de.ts | 8 +- packages/desktop/src/i18n/en.ts | 8 +- packages/desktop/src/i18n/es.ts | 8 +- packages/desktop/src/i18n/fr.ts | 8 +- packages/desktop/src/i18n/ja.ts | 8 +- packages/desktop/src/i18n/ko.ts | 8 +- packages/desktop/src/i18n/no.ts | 8 +- packages/desktop/src/i18n/pl.ts | 8 +- packages/desktop/src/i18n/ru.ts | 8 +- packages/desktop/src/i18n/zh.ts | 8 +- packages/desktop/src/i18n/zht.ts | 8 +- packages/desktop/src/menu.ts | 2 +- packages/enterprise/package.json | 2 +- packages/enterprise/src/core/share.ts | 2 +- .../enterprise/src/routes/share/[shareID].tsx | 2 +- packages/extensions/zed/extension.toml | 18 ++-- packages/function/package.json | 2 +- packages/opencode/package.json | 12 +-- packages/opencode/script/publish.ts | 22 ++--- packages/opencode/src/acp/agent.ts | 2 +- packages/opencode/src/acp/session.ts | 2 +- packages/opencode/src/acp/types.ts | 2 +- packages/opencode/src/cli/cmd/acp.ts | 2 +- packages/opencode/src/cli/cmd/auth.ts | 2 +- packages/opencode/src/cli/cmd/run.ts | 2 +- .../cli/cmd/tui/component/dialog-command.tsx | 2 +- .../cli/cmd/tui/component/dialog-provider.tsx | 2 +- .../cli/cmd/tui/component/prompt/history.tsx | 2 +- .../cli/cmd/tui/component/prompt/index.tsx | 2 +- .../src/cli/cmd/tui/context/keybind.tsx | 2 +- .../opencode/src/cli/cmd/tui/context/sdk.tsx | 2 +- .../opencode/src/cli/cmd/tui/context/sync.tsx | 4 +- .../session/dialog-fork-from-timeline.tsx | 2 +- .../tui/routes/session/dialog-timeline.tsx | 2 +- .../src/cli/cmd/tui/routes/session/header.tsx | 2 +- .../src/cli/cmd/tui/routes/session/index.tsx | 2 +- .../cli/cmd/tui/routes/session/permission.tsx | 2 +- .../cli/cmd/tui/routes/session/question.tsx | 2 +- .../cli/cmd/tui/routes/session/sidebar.tsx | 2 +- packages/opencode/src/cli/cmd/tui/thread.ts | 2 +- .../src/cli/cmd/tui/util/transcript.ts | 2 +- packages/opencode/src/cli/cmd/tui/worker.ts | 2 +- packages/opencode/src/plugin/codex.ts | 2 +- packages/opencode/src/plugin/copilot.ts | 2 +- packages/opencode/src/plugin/index.ts | 4 +- packages/opencode/src/provider/auth.ts | 2 +- packages/opencode/src/share/share-next.ts | 2 +- packages/opencode/src/tool/registry.ts | 2 +- .../test/acp/event-subscription.test.ts | 2 +- .../opencode/test/cli/tui/transcript.test.ts | 2 +- packages/plugin/package.json | 6 +- packages/plugin/src/index.ts | 2 +- packages/script/package.json | 3 +- packages/sdk/js/example/example.ts | 2 +- packages/sdk/js/package.json | 4 +- packages/slack/package.json | 4 +- packages/slack/src/index.ts | 2 +- packages/ui/package.json | 4 +- packages/ui/src/components/favicon.tsx | 2 +- packages/ui/src/components/message-nav.tsx | 2 +- packages/ui/src/components/message-part.tsx | 2 +- packages/ui/src/components/session-review.tsx | 2 +- packages/ui/src/components/session-turn.tsx | 4 +- packages/ui/src/context/data.tsx | 2 +- packages/ui/src/context/marked.tsx | 12 +-- packages/util/package.json | 2 +- packages/web/package.json | 2 +- packages/web/src/content/docs/1-0.mdx | 12 +-- packages/web/src/content/docs/acp.mdx | 24 +++--- packages/web/src/content/docs/agents.mdx | 32 +++---- packages/web/src/content/docs/cli.mdx | 66 +++++++------- packages/web/src/content/docs/commands.mdx | 6 +- packages/web/src/content/docs/config.mdx | 80 ++++++++--------- packages/web/src/content/docs/ecosystem.mdx | 38 ++++---- packages/web/src/content/docs/enterprise.mdx | 52 +++++------ packages/web/src/content/docs/formatters.mdx | 20 ++--- packages/web/src/content/docs/github.mdx | 70 +++++++-------- packages/web/src/content/docs/gitlab.mdx | 44 +++++----- packages/web/src/content/docs/ide.mdx | 14 +-- packages/web/src/content/docs/index.mdx | 68 +++++++-------- packages/web/src/content/docs/keybinds.mdx | 8 +- packages/web/src/content/docs/lsp.mdx | 14 +-- packages/web/src/content/docs/mcp-servers.mdx | 44 +++++----- packages/web/src/content/docs/models.mdx | 26 +++--- packages/web/src/content/docs/modes.mdx | 4 +- packages/web/src/content/docs/network.mdx | 6 +- packages/web/src/content/docs/permissions.mdx | 24 +++--- packages/web/src/content/docs/plugins.mdx | 12 +-- packages/web/src/content/docs/providers.mdx | 86 +++++++++---------- packages/web/src/content/docs/rules.mdx | 8 +- packages/web/src/content/docs/sdk.mdx | 2 +- packages/web/src/content/docs/server.mdx | 22 ++--- packages/web/src/content/docs/share.mdx | 10 +-- packages/web/src/content/docs/skills.mdx | 8 +- packages/web/src/content/docs/themes.mdx | 14 +-- packages/web/src/content/docs/tools.mdx | 36 ++++---- .../web/src/content/docs/troubleshooting.mdx | 38 ++++---- packages/web/src/content/docs/tui.mdx | 16 ++-- packages/web/src/content/docs/web.mdx | 20 ++--- packages/web/src/content/docs/zen.mdx | 24 +++--- script/changelog.ts | 8 +- script/duplicate-pr.ts | 2 +- script/stats.ts | 4 +- sdks/vscode/package.json | 2 +- 164 files changed, 922 insertions(+), 915 deletions(-) diff --git a/github/index.ts b/github/index.ts index 73378894c..0803eba28 100644 --- a/github/index.ts +++ b/github/index.ts @@ -6,7 +6,7 @@ import * as core from "@actions/core" import * as github from "@actions/github" import type { Context as GitHubContext } from "@actions/github/lib/context" import type { IssueCommentEvent, PullRequestReviewCommentEvent } from "@octokit/webhooks-types" -import { createOpencodeClient } from "@opencode-ai/sdk" +import { createOpencodeClient } from "@kilocode/sdk" import { spawn } from "node:child_process" type GitHubAuthor = { @@ -362,7 +362,7 @@ function useIssueId() { } function useShareUrl() { - return isMock() ? "https://dev.opencode.ai" : "https://opencode.ai" + return isMock() ? "https://dev.kilo.ai" : "https://kilo.ai" } async function getAccessToken() { @@ -373,7 +373,7 @@ async function getAccessToken() { let response if (isMock()) { - response = await fetch("https://api.opencode.ai/exchange_github_app_token_with_pat", { + response = await fetch("https://api.kilo.ai/exchange_github_app_token_with_pat", { method: "POST", headers: { Authorization: `Bearer ${useEnvMock().mockToken}`, @@ -382,7 +382,7 @@ async function getAccessToken() { }) } else { const oidcToken = await core.getIDToken("opencode-github-action") - response = await fetch("https://api.opencode.ai/exchange_github_app_token", { + response = await fetch("https://api.kilo.ai/exchange_github_app_token", { method: "POST", headers: { Authorization: `Bearer ${oidcToken}`, diff --git a/github/package.json b/github/package.json index e1b913abe..f263ee276 100644 --- a/github/package.json +++ b/github/package.json @@ -15,6 +15,7 @@ "@actions/github": "6.0.1", "@octokit/graphql": "9.0.1", "@octokit/rest": "catalog:", - "@opencode-ai/sdk": "workspace:*" - } + "@kilocode/sdk": "workspace:*" + }, + "version": "1.0.14" } diff --git a/package.json b/package.json index e1471d356..fa296ec4b 100644 --- a/package.json +++ b/package.json @@ -73,9 +73,9 @@ }, "dependencies": { "@aws-sdk/client-s3": "3.933.0", - "@opencode-ai/plugin": "workspace:*", + "@kilocode/plugin": "workspace:*", "@opencode-ai/script": "workspace:*", - "@opencode-ai/sdk": "workspace:*", + "@kilocode/sdk": "workspace:*", "typescript": "catalog:" }, "repository": { @@ -100,5 +100,6 @@ }, "patchedDependencies": { "ghostty-web@0.3.0": "patches/ghostty-web@0.3.0.patch" - } + }, + "version": "1.0.14" } diff --git a/packages/app/e2e/utils.ts b/packages/app/e2e/utils.ts index ec6cdf830..9dec8e054 100644 --- a/packages/app/e2e/utils.ts +++ b/packages/app/e2e/utils.ts @@ -1,4 +1,4 @@ -import { createOpencodeClient } from "@opencode-ai/sdk/v2/client" +import { createOpencodeClient } from "@kilocode/sdk/v2/client" import { base64Encode } from "@opencode-ai/util/encode" export const serverHost = process.env.PLAYWRIGHT_SERVER_HOST ?? "localhost" diff --git a/packages/app/package.json b/packages/app/package.json index e1232cb1c..cf4e0623e 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "1.1.48", + "version": "1.0.14", "description": "", "type": "module", "exports": { @@ -36,7 +36,7 @@ }, "dependencies": { "@kobalte/core": "catalog:", - "@opencode-ai/sdk": "workspace:*", + "@kilocode/sdk": "workspace:*", "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", "@shikijs/transformers": "3.9.2", @@ -64,6 +64,7 @@ "solid-list": "catalog:", "tailwindcss": "catalog:", "virtua": "catalog:", - "zod": "catalog:" + "zod": "catalog:", + "@kilocode/kilo-i18n": "workspace:*" } } diff --git a/packages/app/src/components/dialog-connect-provider.tsx b/packages/app/src/components/dialog-connect-provider.tsx index 65e322b43..a7d4a4ee2 100644 --- a/packages/app/src/components/dialog-connect-provider.tsx +++ b/packages/app/src/components/dialog-connect-provider.tsx @@ -1,4 +1,4 @@ -import type { ProviderAuthAuthorization } from "@opencode-ai/sdk/v2/client" +import type { ProviderAuthAuthorization } from "@kilocode/sdk/v2/client" import { Button } from "@opencode-ai/ui/button" import { useDialog } from "@opencode-ai/ui/context/dialog" import { Dialog } from "@opencode-ai/ui/dialog" diff --git a/packages/app/src/components/dialog-custom-provider.tsx b/packages/app/src/components/dialog-custom-provider.tsx index 28a947f3b..bfa822490 100644 --- a/packages/app/src/components/dialog-custom-provider.tsx +++ b/packages/app/src/components/dialog-custom-provider.tsx @@ -284,7 +284,7 @@ export function DialogCustomProvider(props: Props) {

Configure an OpenAI-compatible provider. See the{" "} - + provider config docs . diff --git a/packages/app/src/components/dialog-fork.tsx b/packages/app/src/components/dialog-fork.tsx index 09d62021f..b9200a1aa 100644 --- a/packages/app/src/components/dialog-fork.tsx +++ b/packages/app/src/components/dialog-fork.tsx @@ -7,7 +7,7 @@ import { useDialog } from "@opencode-ai/ui/context/dialog" import { Dialog } from "@opencode-ai/ui/dialog" import { List } from "@opencode-ai/ui/list" import { extractPromptFromParts } from "@/utils/prompt" -import type { TextPart as SDKTextPart } from "@opencode-ai/sdk/v2/client" +import type { TextPart as SDKTextPart } from "@kilocode/sdk/v2/client" import { base64Encode } from "@opencode-ai/util/encode" import { useLanguage } from "@/context/language" diff --git a/packages/app/src/components/dialog-select-server.tsx b/packages/app/src/components/dialog-select-server.tsx index e9e7646d5..2c0654444 100644 --- a/packages/app/src/components/dialog-select-server.tsx +++ b/packages/app/src/components/dialog-select-server.tsx @@ -8,7 +8,7 @@ import { IconButton } from "@opencode-ai/ui/icon-button" import { TextField } from "@opencode-ai/ui/text-field" import { normalizeServerUrl, serverDisplayName, useServer } from "@/context/server" import { usePlatform } from "@/context/platform" -import { createOpencodeClient } from "@opencode-ai/sdk/v2/client" +import { createOpencodeClient } from "@kilocode/sdk/v2/client" import { useNavigate } from "@solidjs/router" import { useLanguage } from "@/context/language" import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu" diff --git a/packages/app/src/components/file-tree.tsx b/packages/app/src/components/file-tree.tsx index d43310b19..e858065b3 100644 --- a/packages/app/src/components/file-tree.tsx +++ b/packages/app/src/components/file-tree.tsx @@ -16,7 +16,7 @@ import { type ParentProps, } from "solid-js" import { Dynamic } from "solid-js/web" -import type { FileNode } from "@opencode-ai/sdk/v2" +import type { FileNode } from "@kilocode/sdk/v2" type Kind = "add" | "del" | "mix" diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index 5c1d417eb..091b43385 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -54,7 +54,7 @@ import { usePermission } from "@/context/permission" import { useLanguage } from "@/context/language" import { useGlobalSync } from "@/context/global-sync" import { usePlatform } from "@/context/platform" -import { createOpencodeClient, type Message, type Part } from "@opencode-ai/sdk/v2/client" +import { createOpencodeClient, type Message, type Part } from "@kilocode/sdk/v2/client" import { Binary } from "@opencode-ai/util/binary" import { showToast } from "@opencode-ai/ui/toast" import { base64Encode } from "@opencode-ai/util/encode" diff --git a/packages/app/src/components/session-context-usage.tsx b/packages/app/src/components/session-context-usage.tsx index 1e37d8f6a..eb4648331 100644 --- a/packages/app/src/components/session-context-usage.tsx +++ b/packages/app/src/components/session-context-usage.tsx @@ -3,7 +3,7 @@ import { Tooltip } from "@opencode-ai/ui/tooltip" import { ProgressCircle } from "@opencode-ai/ui/progress-circle" import { Button } from "@opencode-ai/ui/button" import { useParams } from "@solidjs/router" -import { AssistantMessage } from "@opencode-ai/sdk/v2/client" +import { AssistantMessage } from "@kilocode/sdk/v2/client" import { findLast } from "@opencode-ai/util/array" import { useLayout } from "@/context/layout" diff --git a/packages/app/src/components/session/session-context-tab.tsx b/packages/app/src/components/session/session-context-tab.tsx index 37733caff..800b41ce6 100644 --- a/packages/app/src/components/session/session-context-tab.tsx +++ b/packages/app/src/components/session/session-context-tab.tsx @@ -11,7 +11,7 @@ import { Accordion } from "@opencode-ai/ui/accordion" import { StickyAccordionHeader } from "@opencode-ai/ui/sticky-accordion-header" import { Code } from "@opencode-ai/ui/code" import { Markdown } from "@opencode-ai/ui/markdown" -import type { AssistantMessage, Message, Part, UserMessage } from "@opencode-ai/sdk/v2/client" +import type { AssistantMessage, Message, Part, UserMessage } from "@kilocode/sdk/v2/client" import { useLanguage } from "@/context/language" interface SessionContextTabProps { diff --git a/packages/app/src/components/settings-general.tsx b/packages/app/src/components/settings-general.tsx index b26f6ba22..c121047b2 100644 --- a/packages/app/src/components/settings-general.tsx +++ b/packages/app/src/components/settings-general.tsx @@ -186,7 +186,7 @@ export const SettingsGeneral: Component = () => { description={ <> {language.t("settings.general.row.theme.description")}{" "} - {language.t("common.learnMore")} + {language.t("common.learnMore")} } > diff --git a/packages/app/src/components/status-popover.tsx b/packages/app/src/components/status-popover.tsx index 102c477a1..4a61b7ecd 100644 --- a/packages/app/src/components/status-popover.tsx +++ b/packages/app/src/components/status-popover.tsx @@ -13,7 +13,7 @@ import { useSDK } from "@/context/sdk" import { normalizeServerUrl, serverDisplayName, useServer } from "@/context/server" import { usePlatform } from "@/context/platform" import { useLanguage } from "@/context/language" -import { createOpencodeClient } from "@opencode-ai/sdk/v2/client" +import { createOpencodeClient } from "@kilocode/sdk/v2/client" import { DialogSelectServer } from "./dialog-select-server" import { showToast } from "@opencode-ai/ui/toast" diff --git a/packages/app/src/context/file.tsx b/packages/app/src/context/file.tsx index 7509334ed..6fbbe6a90 100644 --- a/packages/app/src/context/file.tsx +++ b/packages/app/src/context/file.tsx @@ -1,7 +1,7 @@ import { createEffect, createMemo, createRoot, onCleanup } from "solid-js" import { createStore, produce } from "solid-js/store" import { createSimpleContext } from "@opencode-ai/ui/context" -import type { FileContent, FileNode } from "@opencode-ai/sdk/v2" +import type { FileContent, FileNode } from "@kilocode/sdk/v2" import { showToast } from "@opencode-ai/ui/toast" import { useParams } from "@solidjs/router" import { getFilename } from "@opencode-ai/util/path" diff --git a/packages/app/src/context/global-sdk.tsx b/packages/app/src/context/global-sdk.tsx index 0cd4f6c99..383378867 100644 --- a/packages/app/src/context/global-sdk.tsx +++ b/packages/app/src/context/global-sdk.tsx @@ -1,4 +1,4 @@ -import { createOpencodeClient, type Event } from "@opencode-ai/sdk/v2/client" +import { createOpencodeClient, type Event } from "@kilocode/sdk/v2/client" import { createSimpleContext } from "@opencode-ai/ui/context" import { createGlobalEmitter } from "@solid-primitives/event-bus" import { batch, onCleanup } from "solid-js" diff --git a/packages/app/src/context/global-sync.tsx b/packages/app/src/context/global-sync.tsx index ad3d124b2..819a152b0 100644 --- a/packages/app/src/context/global-sync.tsx +++ b/packages/app/src/context/global-sync.tsx @@ -18,7 +18,7 @@ import { type PermissionRequest, type QuestionRequest, createOpencodeClient, -} from "@opencode-ai/sdk/v2/client" +} from "@kilocode/sdk/v2/client" import { createStore, produce, reconcile, type SetStoreFunction, type Store } from "solid-js/store" import { Binary } from "@opencode-ai/util/binary" import { retry } from "@opencode-ai/util/retry" diff --git a/packages/app/src/context/highlights.tsx b/packages/app/src/context/highlights.tsx index cc4c021be..2003387c4 100644 --- a/packages/app/src/context/highlights.tsx +++ b/packages/app/src/context/highlights.tsx @@ -7,7 +7,7 @@ import { useSettings } from "@/context/settings" import { persisted } from "@/utils/persist" import { DialogReleaseNotes, type Highlight } from "@/components/dialog-release-notes" -const CHANGELOG_URL = "https://opencode.ai/changelog.json" +const CHANGELOG_URL = "https://kilo.ai/changelog.json" type Store = { version?: string diff --git a/packages/app/src/context/layout.tsx b/packages/app/src/context/layout.tsx index d30fd11cf..cebe74edf 100644 --- a/packages/app/src/context/layout.tsx +++ b/packages/app/src/context/layout.tsx @@ -4,7 +4,7 @@ import { createSimpleContext } from "@opencode-ai/ui/context" import { useGlobalSync } from "./global-sync" import { useGlobalSDK } from "./global-sdk" import { useServer } from "./server" -import { Project } from "@opencode-ai/sdk/v2" +import { Project } from "@kilocode/sdk/v2" import { Persist, persisted, removePersisted } from "@/utils/persist" import { same } from "@/utils/same" import { createScrollPersistence, type SessionScroll } from "./layout-scroll" diff --git a/packages/app/src/context/notification.tsx b/packages/app/src/context/notification.tsx index 6c110cae1..5019cd2cb 100644 --- a/packages/app/src/context/notification.tsx +++ b/packages/app/src/context/notification.tsx @@ -10,7 +10,7 @@ import { useSettings } from "@/context/settings" import { Binary } from "@opencode-ai/util/binary" import { base64Encode } from "@opencode-ai/util/encode" import { decode64 } from "@/utils/base64" -import { EventSessionError } from "@opencode-ai/sdk/v2" +import { EventSessionError } from "@kilocode/sdk/v2" import { Persist, persisted } from "@/utils/persist" import { playSound, soundSrc } from "@/utils/sound" diff --git a/packages/app/src/context/permission.tsx b/packages/app/src/context/permission.tsx index a701dbd1f..d78e1c5ef 100644 --- a/packages/app/src/context/permission.tsx +++ b/packages/app/src/context/permission.tsx @@ -1,7 +1,7 @@ import { createMemo, onCleanup } from "solid-js" import { createStore, produce } from "solid-js/store" import { createSimpleContext } from "@opencode-ai/ui/context" -import type { PermissionRequest } from "@opencode-ai/sdk/v2/client" +import type { PermissionRequest } from "@kilocode/sdk/v2/client" import { Persist, persisted } from "@/utils/persist" import { useGlobalSDK } from "@/context/global-sdk" import { useGlobalSync } from "./global-sync" diff --git a/packages/app/src/context/sdk.tsx b/packages/app/src/context/sdk.tsx index 123aa4e73..9705605b5 100644 --- a/packages/app/src/context/sdk.tsx +++ b/packages/app/src/context/sdk.tsx @@ -1,4 +1,4 @@ -import { createOpencodeClient, type Event } from "@opencode-ai/sdk/v2/client" +import { createOpencodeClient, type Event } from "@kilocode/sdk/v2/client" import { createSimpleContext } from "@opencode-ai/ui/context" import { createGlobalEmitter } from "@solid-primitives/event-bus" import { createEffect, createMemo, onCleanup } from "solid-js" diff --git a/packages/app/src/context/server.tsx b/packages/app/src/context/server.tsx index c307f6e72..abf95cb22 100644 --- a/packages/app/src/context/server.tsx +++ b/packages/app/src/context/server.tsx @@ -1,4 +1,4 @@ -import { createOpencodeClient } from "@opencode-ai/sdk/v2/client" +import { createOpencodeClient } from "@kilocode/sdk/v2/client" import { createSimpleContext } from "@opencode-ai/ui/context" import { batch, createEffect, createMemo, onCleanup } from "solid-js" import { createStore } from "solid-js/store" diff --git a/packages/app/src/context/sync.tsx b/packages/app/src/context/sync.tsx index 5c8e140c3..77f66520e 100644 --- a/packages/app/src/context/sync.tsx +++ b/packages/app/src/context/sync.tsx @@ -5,7 +5,7 @@ import { retry } from "@opencode-ai/util/retry" import { createSimpleContext } from "@opencode-ai/ui/context" import { useGlobalSync } from "./global-sync" import { useSDK } from "./sdk" -import type { Message, Part } from "@opencode-ai/sdk/v2/client" +import type { Message, Part } from "@kilocode/sdk/v2/client" const keyFor = (directory: string, id: string) => `${directory}\n${id}` diff --git a/packages/app/src/i18n/ar.ts b/packages/app/src/i18n/ar.ts index 8ca05cdfe..970b5851a 100644 --- a/packages/app/src/i18n/ar.ts +++ b/packages/app/src/i18n/ar.ts @@ -101,7 +101,7 @@ export const dict = { "dialog.model.manage": "إدارة النماذج", "dialog.model.manage.description": "تخصيص النماذج التي تظهر في محدد النماذج.", - "dialog.model.unpaid.freeModels.title": "نماذج مجانية مقدمة من OpenCode", + "dialog.model.unpaid.freeModels.title": "نماذج مجانية مقدمة من Kilo", "dialog.model.unpaid.addMore.title": "إضافة المزيد من النماذج من موفرين مشهورين", "dialog.provider.viewAll": "عرض المزيد من الموفرين", @@ -114,7 +114,7 @@ export const dict = { "provider.connect.status.waiting": "في انتظار التفويض...", "provider.connect.status.failed": "فشل التفويض: {{error}}", "provider.connect.apiKey.description": - "أدخل مفتاح واجهة برمجة تطبيقات {{provider}} الخاص بك لتوصيل حسابك واستخدام نماذج {{provider}} في OpenCode.", + "أدخل مفتاح واجهة برمجة تطبيقات {{provider}} الخاص بك لتوصيل حسابك واستخدام نماذج {{provider}} في Kilo.", "provider.connect.apiKey.label": "مفتاح واجهة برمجة تطبيقات {{provider}}", "provider.connect.apiKey.placeholder": "مفتاح API", "provider.connect.apiKey.required": "مفتاح API مطلوب", @@ -128,7 +128,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "قم بزيارة ", "provider.connect.oauth.code.visit.link": "هذا الرابط", "provider.connect.oauth.code.visit.suffix": - " للحصول على رمز التفويض الخاص بك لتوصيل حسابك واستخدام نماذج {{provider}} في OpenCode.", + " للحصول على رمز التفويض الخاص بك لتوصيل حسابك واستخدام نماذج {{provider}} في Kilo.", "provider.connect.oauth.code.label": "رمز تفويض {{method}}", "provider.connect.oauth.code.placeholder": "رمز التفويض", "provider.connect.oauth.code.required": "رمز التفويض مطلوب", @@ -136,7 +136,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "قم بزيارة ", "provider.connect.oauth.auto.visit.link": "هذا الرابط", "provider.connect.oauth.auto.visit.suffix": - " وأدخل الرمز أدناه لتوصيل حسابك واستخدام نماذج {{provider}} في OpenCode.", + " وأدخل الرمز أدناه لتوصيل حسابك واستخدام نماذج {{provider}} في Kilo.", "provider.connect.oauth.auto.confirmationCode": "رمز التأكيد", "provider.connect.toast.connected.title": "تم توصيل {{provider}}", "provider.connect.toast.connected.description": "نماذج {{provider}} متاحة الآن للاستخدام.", @@ -247,7 +247,7 @@ export const dict = { "dialog.directory.empty": "لم يتم العثور على مجلدات", "dialog.server.title": "الخوادم", - "dialog.server.description": "تبديل خادم OpenCode الذي يتصل به هذا التطبيق.", + "dialog.server.description": "تبديل خادم Kilo الذي يتصل به هذا التطبيق.", "dialog.server.search.placeholder": "البحث في الخوادم", "dialog.server.empty": "لا توجد خوادم بعد", "dialog.server.add.title": "إضافة خادم", @@ -366,7 +366,7 @@ export const dict = { "toast.session.listFailed.title": "فشل تحميل الجلسات لـ {{project}}", "toast.update.title": "تحديث متاح", - "toast.update.description": "نسخة جديدة من OpenCode ({{version}}) متاحة الآن للتثبيت.", + "toast.update.description": "نسخة جديدة من Kilo ({{version}}) متاحة الآن للتثبيت.", "toast.update.action.installRestart": "تثبيت وإعادة تشغيل", "toast.update.action.notYet": "ليس الآن", @@ -377,7 +377,7 @@ export const dict = { "error.page.action.checking": "جارٍ التحقق...", "error.page.action.checkUpdates": "التحقق من وجود تحديثات", "error.page.action.updateTo": "تحديث إلى {{version}}", - "error.page.report.prefix": "يرجى الإبلاغ عن هذا الخطأ لفريق OpenCode", + "error.page.report.prefix": "يرجى الإبلاغ عن هذا الخطأ لفريق Kilo", "error.page.report.discord": "على Discord", "error.page.version": "الإصدار: {{version}}", @@ -395,7 +395,7 @@ export const dict = { "error.chain.didYouMean": "هل كنت تعني: {{suggestions}}", "error.chain.modelNotFound": "النموذج غير موجود: {{provider}}/{{model}}", "error.chain.checkConfig": "تحقق من أسماء الموفر/النموذج في التكوين (opencode.json)", - "error.chain.mcpFailed": 'فشل خادم MCP "{{name}}". لاحظ أن OpenCode لا يدعم مصادقة MCP بعد.', + "error.chain.mcpFailed": 'فشل خادم MCP "{{name}}". لاحظ أن Kilo لا يدعم مصادقة MCP بعد.', "error.chain.providerAuthFailed": "فشلت مصادقة الموفر ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'فشل تهيئة الموفر "{{provider}}". تحقق من بيانات الاعتماد والتكوين.', "error.chain.configJsonInvalid": "ملف التكوين في {{path}} ليس JSON(C) صالحًا", @@ -500,12 +500,12 @@ export const dict = { "sidebar.workspaces.enable": "تمكين مساحات العمل", "sidebar.workspaces.disable": "تعطيل مساحات العمل", "sidebar.gettingStarted.title": "البدء", - "sidebar.gettingStarted.line1": "يتضمن OpenCode نماذج مجانية حتى تتمكن من البدء فورًا.", + "sidebar.gettingStarted.line1": "يتضمن Kilo نماذج مجانية حتى تتمكن من البدء فورًا.", "sidebar.gettingStarted.line2": "قم بتوصيل أي موفر لاستخدام النماذج، بما في ذلك Claude و GPT و Gemini وما إلى ذلك.", "sidebar.project.recentSessions": "الجلسات الحديثة", "sidebar.project.viewAllSessions": "عرض جميع الجلسات", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "سطح المكتب", "settings.section.server": "الخادم", "settings.tab.general": "عام", @@ -517,11 +517,11 @@ export const dict = { "settings.general.section.sounds": "المؤثرات الصوتية", "settings.general.row.language.title": "اللغة", - "settings.general.row.language.description": "تغيير لغة العرض لـ OpenCode", + "settings.general.row.language.description": "تغيير لغة العرض لـ Kilo", "settings.general.row.appearance.title": "المظهر", - "settings.general.row.appearance.description": "تخصيص كيفية ظهور OpenCode على جهازك", + "settings.general.row.appearance.description": "تخصيص كيفية ظهور Kilo على جهازك", "settings.general.row.theme.title": "السمة", - "settings.general.row.theme.description": "تخصيص سمة OpenCode.", + "settings.general.row.theme.description": "تخصيص سمة Kilo.", "settings.general.row.font.title": "الخط", "settings.general.row.font.description": "تخصيص الخط الأحادي المستخدم في كتل التعليمات البرمجية", @@ -529,13 +529,13 @@ export const dict = { "settings.general.row.releaseNotes.description": 'عرض نوافذ "ما الجديد" المنبثقة بعد التحديثات', "settings.updates.row.startup.title": "التحقق من التحديثات عند بدء التشغيل", - "settings.updates.row.startup.description": "التحقق تلقائيًا من التحديثات عند تشغيل OpenCode", + "settings.updates.row.startup.description": "التحقق تلقائيًا من التحديثات عند تشغيل Kilo", "settings.updates.row.check.title": "التحقق من التحديثات", "settings.updates.row.check.description": "التحقق يدويًا من التحديثات وتثبيتها إذا كانت متاحة", "settings.updates.action.checkNow": "تحقق الآن", "settings.updates.action.checking": "جارٍ التحقق...", "settings.updates.toast.latest.title": "أنت على آخر إصدار", - "settings.updates.toast.latest.description": "أنت تستخدم أحدث إصدار من OpenCode.", + "settings.updates.toast.latest.description": "أنت تستخدم أحدث إصدار من Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/br.ts b/packages/app/src/i18n/br.ts index ad0772cd8..008d83404 100644 --- a/packages/app/src/i18n/br.ts +++ b/packages/app/src/i18n/br.ts @@ -101,7 +101,7 @@ export const dict = { "dialog.model.manage": "Gerenciar modelos", "dialog.model.manage.description": "Personalizar quais modelos aparecem no seletor de modelos.", - "dialog.model.unpaid.freeModels.title": "Modelos gratuitos fornecidos pelo OpenCode", + "dialog.model.unpaid.freeModels.title": "Modelos gratuitos fornecidos pelo Kilo", "dialog.model.unpaid.addMore.title": "Adicionar mais modelos de provedores populares", "dialog.provider.viewAll": "Ver mais provedores", @@ -114,7 +114,7 @@ export const dict = { "provider.connect.status.waiting": "Aguardando autorização...", "provider.connect.status.failed": "Autorização falhou: {{error}}", "provider.connect.apiKey.description": - "Digite sua chave de API do {{provider}} para conectar sua conta e usar modelos do {{provider}} no OpenCode.", + "Digite sua chave de API do {{provider}} para conectar sua conta e usar modelos do {{provider}} no Kilo.", "provider.connect.apiKey.label": "Chave de API do {{provider}}", "provider.connect.apiKey.placeholder": "Chave de API", "provider.connect.apiKey.required": "A chave de API é obrigatória", @@ -128,7 +128,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Visite ", "provider.connect.oauth.code.visit.link": "este link", "provider.connect.oauth.code.visit.suffix": - " para obter seu código de autorização e conectar sua conta para usar modelos do {{provider}} no OpenCode.", + " para obter seu código de autorização e conectar sua conta para usar modelos do {{provider}} no Kilo.", "provider.connect.oauth.code.label": "Código de autorização {{method}}", "provider.connect.oauth.code.placeholder": "Código de autorização", "provider.connect.oauth.code.required": "O código de autorização é obrigatório", @@ -136,7 +136,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Visite ", "provider.connect.oauth.auto.visit.link": "este link", "provider.connect.oauth.auto.visit.suffix": - " e digite o código abaixo para conectar sua conta e usar modelos do {{provider}} no OpenCode.", + " e digite o código abaixo para conectar sua conta e usar modelos do {{provider}} no Kilo.", "provider.connect.oauth.auto.confirmationCode": "Código de confirmação", "provider.connect.toast.connected.title": "{{provider}} conectado", "provider.connect.toast.connected.description": "Modelos do {{provider}} agora estão disponíveis para uso.", @@ -246,7 +246,7 @@ export const dict = { "dialog.directory.empty": "Nenhuma pasta encontrada", "dialog.server.title": "Servidores", - "dialog.server.description": "Trocar para qual servidor OpenCode este aplicativo se conecta.", + "dialog.server.description": "Trocar para qual servidor Kilo este aplicativo se conecta.", "dialog.server.search.placeholder": "Buscar servidores", "dialog.server.empty": "Nenhum servidor ainda", "dialog.server.add.title": "Adicionar um servidor", @@ -365,7 +365,7 @@ export const dict = { "toast.session.listFailed.title": "Falha ao carregar sessões para {{project}}", "toast.update.title": "Atualização disponível", - "toast.update.description": "Uma nova versão do OpenCode ({{version}}) está disponível para instalação.", + "toast.update.description": "Uma nova versão do Kilo ({{version}}) está disponível para instalação.", "toast.update.action.installRestart": "Instalar e reiniciar", "toast.update.action.notYet": "Agora não", @@ -376,7 +376,7 @@ export const dict = { "error.page.action.checking": "Verificando...", "error.page.action.checkUpdates": "Verificar atualizações", "error.page.action.updateTo": "Atualizar para {{version}}", - "error.page.report.prefix": "Por favor, reporte este erro para a equipe do OpenCode", + "error.page.report.prefix": "Por favor, reporte este erro para a equipe do Kilo", "error.page.report.discord": "no Discord", "error.page.version": "Versão: {{version}}", @@ -394,7 +394,7 @@ export const dict = { "error.chain.didYouMean": "Você quis dizer: {{suggestions}}", "error.chain.modelNotFound": "Modelo não encontrado: {{provider}}/{{model}}", "error.chain.checkConfig": "Verifique os nomes de provedor/modelo na sua configuração (opencode.json)", - "error.chain.mcpFailed": 'Servidor MCP "{{name}}" falhou. Nota: OpenCode ainda não suporta autenticação MCP.', + "error.chain.mcpFailed": 'Servidor MCP "{{name}}" falhou. Nota: Kilo ainda não suporta autenticação MCP.', "error.chain.providerAuthFailed": "Autenticação do provedor falhou ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'Falha ao inicializar provedor "{{provider}}". Verifique credenciais e configuração.', @@ -504,12 +504,12 @@ export const dict = { "sidebar.workspaces.enable": "Habilitar espaços de trabalho", "sidebar.workspaces.disable": "Desabilitar espaços de trabalho", "sidebar.gettingStarted.title": "Começando", - "sidebar.gettingStarted.line1": "OpenCode inclui modelos gratuitos para você começar imediatamente.", + "sidebar.gettingStarted.line1": "Kilo inclui modelos gratuitos para você começar imediatamente.", "sidebar.gettingStarted.line2": "Conecte qualquer provedor para usar modelos, incluindo Claude, GPT, Gemini etc.", "sidebar.project.recentSessions": "Sessões recentes", "sidebar.project.viewAllSessions": "Ver todas as sessões", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Desktop", "settings.section.server": "Servidor", "settings.tab.general": "Geral", @@ -521,11 +521,11 @@ export const dict = { "settings.general.section.sounds": "Efeitos sonoros", "settings.general.row.language.title": "Idioma", - "settings.general.row.language.description": "Alterar o idioma de exibição do OpenCode", + "settings.general.row.language.description": "Alterar o idioma de exibição do Kilo", "settings.general.row.appearance.title": "Aparência", - "settings.general.row.appearance.description": "Personalize como o OpenCode aparece no seu dispositivo", + "settings.general.row.appearance.description": "Personalize como o Kilo aparece no seu dispositivo", "settings.general.row.theme.title": "Tema", - "settings.general.row.theme.description": "Personalize como o OpenCode é tematizado.", + "settings.general.row.theme.description": "Personalize como o Kilo é tematizado.", "settings.general.row.font.title": "Fonte", "settings.general.row.font.description": "Personalize a fonte monoespaçada usada em blocos de código", @@ -533,13 +533,13 @@ export const dict = { "settings.general.row.releaseNotes.description": 'Mostrar pop-ups de "Novidades" após atualizações', "settings.updates.row.startup.title": "Verificar atualizações ao iniciar", - "settings.updates.row.startup.description": "Verificar atualizações automaticamente quando o OpenCode iniciar", + "settings.updates.row.startup.description": "Verificar atualizações automaticamente quando o Kilo iniciar", "settings.updates.row.check.title": "Verificar atualizações", "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.toast.latest.title": "Você está atualizado", - "settings.updates.toast.latest.description": "Você está usando a versão mais recente do OpenCode.", + "settings.updates.toast.latest.description": "Você está usando a versão mais recente do Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/da.ts b/packages/app/src/i18n/da.ts index 031d92d4b..8cb56ff95 100644 --- a/packages/app/src/i18n/da.ts +++ b/packages/app/src/i18n/da.ts @@ -101,7 +101,7 @@ export const dict = { "dialog.model.manage": "Administrer modeller", "dialog.model.manage.description": "Tilpas hvilke modeller der vises i modelvælgeren.", - "dialog.model.unpaid.freeModels.title": "Gratis modeller leveret af OpenCode", + "dialog.model.unpaid.freeModels.title": "Gratis modeller leveret af Kilo", "dialog.model.unpaid.addMore.title": "Tilføj flere modeller fra populære udbydere", "dialog.provider.viewAll": "Vis flere udbydere", @@ -114,7 +114,7 @@ export const dict = { "provider.connect.status.waiting": "Venter på godkendelse...", "provider.connect.status.failed": "Godkendelse mislykkedes: {{error}}", "provider.connect.apiKey.description": - "Indtast din {{provider}} API-nøgle for at forbinde din konto og bruge {{provider}} modeller i OpenCode.", + "Indtast din {{provider}} API-nøgle for at forbinde din konto og bruge {{provider}} modeller i Kilo.", "provider.connect.apiKey.label": "{{provider}} API-nøgle", "provider.connect.apiKey.placeholder": "API-nøgle", "provider.connect.apiKey.required": "API-nøgle er påkrævet", @@ -128,7 +128,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Besøg ", "provider.connect.oauth.code.visit.link": "dette link", "provider.connect.oauth.code.visit.suffix": - " for at hente din godkendelseskode for at forbinde din konto og bruge {{provider}} modeller i OpenCode.", + " for at hente din godkendelseskode for at forbinde din konto og bruge {{provider}} modeller i Kilo.", "provider.connect.oauth.code.label": "{{method}} godkendelseskode", "provider.connect.oauth.code.placeholder": "Godkendelseskode", "provider.connect.oauth.code.required": "Godkendelseskode er påkrævet", @@ -136,7 +136,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Besøg ", "provider.connect.oauth.auto.visit.link": "dette link", "provider.connect.oauth.auto.visit.suffix": - " og indtast koden nedenfor for at forbinde din konto og bruge {{provider}} modeller i OpenCode.", + " og indtast koden nedenfor for at forbinde din konto og bruge {{provider}} modeller i Kilo.", "provider.connect.oauth.auto.confirmationCode": "Bekræftelseskode", "provider.connect.toast.connected.title": "{{provider}} forbundet", "provider.connect.toast.connected.description": "{{provider}} modeller er nu tilgængelige.", @@ -247,7 +247,7 @@ export const dict = { "dialog.directory.empty": "Ingen mapper fundet", "dialog.server.title": "Servere", - "dialog.server.description": "Skift hvilken OpenCode-server denne app forbinder til.", + "dialog.server.description": "Skift hvilken Kilo-server denne app forbinder til.", "dialog.server.search.placeholder": "Søg servere", "dialog.server.empty": "Ingen servere endnu", "dialog.server.add.title": "Tilføj en server", @@ -367,7 +367,7 @@ export const dict = { "toast.session.listFailed.title": "Kunne ikke indlæse sessioner for {{project}}", "toast.update.title": "Opdatering tilgængelig", - "toast.update.description": "En ny version af OpenCode ({{version}}) er nu tilgængelig til installation.", + "toast.update.description": "En ny version af Kilo ({{version}}) er nu tilgængelig til installation.", "toast.update.action.installRestart": "Installer og genstart", "toast.update.action.notYet": "Ikke endnu", @@ -378,7 +378,7 @@ export const dict = { "error.page.action.checking": "Tjekker...", "error.page.action.checkUpdates": "Tjek for opdateringer", "error.page.action.updateTo": "Opdater til {{version}}", - "error.page.report.prefix": "Rapporter venligst denne fejl til OpenCode-teamet", + "error.page.report.prefix": "Rapporter venligst denne fejl til Kilo-teamet", "error.page.report.discord": "på Discord", "error.page.version": "Version: {{version}}", @@ -396,7 +396,7 @@ export const dict = { "error.chain.didYouMean": "Mente du: {{suggestions}}", "error.chain.modelNotFound": "Model ikke fundet: {{provider}}/{{model}}", "error.chain.checkConfig": "Tjek dine konfigurations (opencode.json) udbyder/modelnavne", - "error.chain.mcpFailed": 'MCP-server "{{name}}" fejlede. Bemærk, OpenCode understøtter ikke MCP-godkendelse endnu.', + "error.chain.mcpFailed": 'MCP-server "{{name}}" fejlede. Bemærk, Kilo understøtter ikke MCP-godkendelse endnu.', "error.chain.providerAuthFailed": "Udbydergodkendelse mislykkedes ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'Kunne ikke initialisere udbyder "{{provider}}". Tjek legitimationsoplysninger og konfiguration.', @@ -504,12 +504,12 @@ export const dict = { "sidebar.workspaces.enable": "Aktiver arbejdsområder", "sidebar.workspaces.disable": "Deaktiver arbejdsområder", "sidebar.gettingStarted.title": "Kom i gang", - "sidebar.gettingStarted.line1": "OpenCode inkluderer gratis modeller så du kan starte med det samme.", + "sidebar.gettingStarted.line1": "Kilo inkluderer gratis modeller så du kan starte med det samme.", "sidebar.gettingStarted.line2": "Forbind enhver udbyder for at bruge modeller, inkl. Claude, GPT, Gemini osv.", "sidebar.project.recentSessions": "Seneste sessioner", "sidebar.project.viewAllSessions": "Vis alle sessioner", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Desktop", "settings.section.server": "Server", "settings.tab.general": "Generelt", @@ -521,11 +521,11 @@ export const dict = { "settings.general.section.sounds": "Lydeffekter", "settings.general.row.language.title": "Sprog", - "settings.general.row.language.description": "Ændr visningssproget for OpenCode", + "settings.general.row.language.description": "Ændr visningssproget for Kilo", "settings.general.row.appearance.title": "Udseende", - "settings.general.row.appearance.description": "Tilpas hvordan OpenCode ser ud på din enhed", + "settings.general.row.appearance.description": "Tilpas hvordan Kilo ser ud på din enhed", "settings.general.row.theme.title": "Tema", - "settings.general.row.theme.description": "Tilpas hvordan OpenCode er temabestemt.", + "settings.general.row.theme.description": "Tilpas hvordan Kilo er temabestemt.", "settings.general.row.font.title": "Skrifttype", "settings.general.row.font.description": "Tilpas mono-skrifttypen brugt i kodeblokke", @@ -533,13 +533,13 @@ export const dict = { "settings.general.row.releaseNotes.description": 'Vis "Hvad er nyt"-popups efter opdateringer', "settings.updates.row.startup.title": "Tjek for opdateringer ved opstart", - "settings.updates.row.startup.description": "Tjek automatisk for opdateringer, når OpenCode starter", + "settings.updates.row.startup.description": "Tjek automatisk for opdateringer, når Kilo starter", "settings.updates.row.check.title": "Tjek for opdateringer", "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.toast.latest.title": "Du er opdateret", - "settings.updates.toast.latest.description": "Du kører den nyeste version af OpenCode.", + "settings.updates.toast.latest.description": "Du kører den nyeste version af Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", diff --git a/packages/app/src/i18n/de.ts b/packages/app/src/i18n/de.ts index 9febfcff1..96149c288 100644 --- a/packages/app/src/i18n/de.ts +++ b/packages/app/src/i18n/de.ts @@ -105,7 +105,7 @@ export const dict = { "dialog.model.manage": "Modelle verwalten", "dialog.model.manage.description": "Anpassen, welche Modelle in der Modellauswahl erscheinen.", - "dialog.model.unpaid.freeModels.title": "Kostenlose Modelle von OpenCode", + "dialog.model.unpaid.freeModels.title": "Kostenlose Modelle von Kilo", "dialog.model.unpaid.addMore.title": "Weitere Modelle von beliebten Anbietern hinzufügen", "dialog.provider.viewAll": "Mehr Anbieter anzeigen", @@ -118,7 +118,7 @@ export const dict = { "provider.connect.status.waiting": "Warten auf Autorisierung...", "provider.connect.status.failed": "Autorisierung fehlgeschlagen: {{error}}", "provider.connect.apiKey.description": - "Geben Sie Ihren {{provider}} API-Schlüssel ein, um Ihr Konto zu verbinden und {{provider}} Modelle in OpenCode zu nutzen.", + "Geben Sie Ihren {{provider}} API-Schlüssel ein, um Ihr Konto zu verbinden und {{provider}} Modelle in Kilo zu nutzen.", "provider.connect.apiKey.label": "{{provider}} API-Schlüssel", "provider.connect.apiKey.placeholder": "API-Schlüssel", "provider.connect.apiKey.required": "API-Schlüssel ist erforderlich", @@ -132,7 +132,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Besuchen Sie ", "provider.connect.oauth.code.visit.link": "diesen Link", "provider.connect.oauth.code.visit.suffix": - ", um Ihren Autorisierungscode zu erhalten, Ihr Konto zu verbinden und {{provider}} Modelle in OpenCode zu nutzen.", + ", um Ihren Autorisierungscode zu erhalten, Ihr Konto zu verbinden und {{provider}} Modelle in Kilo zu nutzen.", "provider.connect.oauth.code.label": "{{method}} Autorisierungscode", "provider.connect.oauth.code.placeholder": "Autorisierungscode", "provider.connect.oauth.code.required": "Autorisierungscode ist erforderlich", @@ -140,7 +140,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Besuchen Sie ", "provider.connect.oauth.auto.visit.link": "diesen Link", "provider.connect.oauth.auto.visit.suffix": - " und geben Sie den untenstehenden Code ein, um Ihr Konto zu verbinden und {{provider}} Modelle in OpenCode zu nutzen.", + " und geben Sie den untenstehenden Code ein, um Ihr Konto zu verbinden und {{provider}} Modelle in Kilo zu nutzen.", "provider.connect.oauth.auto.confirmationCode": "Bestätigungscode", "provider.connect.toast.connected.title": "{{provider}} verbunden", "provider.connect.toast.connected.description": "{{provider}} Modelle sind jetzt verfügbar.", @@ -252,7 +252,7 @@ export const dict = { "dialog.directory.empty": "Keine Ordner gefunden", "dialog.server.title": "Server", - "dialog.server.description": "Wechseln Sie den OpenCode-Server, mit dem sich diese App verbindet.", + "dialog.server.description": "Wechseln Sie den Kilo-Server, mit dem sich diese App verbindet.", "dialog.server.search.placeholder": "Server durchsuchen", "dialog.server.empty": "Noch keine Server", "dialog.server.add.title": "Server hinzufügen", @@ -373,7 +373,7 @@ export const dict = { "toast.session.listFailed.title": "Sitzungen für {{project}} konnten nicht geladen werden", "toast.update.title": "Update verfügbar", - "toast.update.description": "Eine neue Version von OpenCode ({{version}}) ist zur Installation verfügbar.", + "toast.update.description": "Eine neue Version von Kilo ({{version}}) ist zur Installation verfügbar.", "toast.update.action.installRestart": "Installieren und neu starten", "toast.update.action.notYet": "Noch nicht", @@ -384,7 +384,7 @@ export const dict = { "error.page.action.checking": "Prüfen...", "error.page.action.checkUpdates": "Nach Updates suchen", "error.page.action.updateTo": "Auf {{version}} aktualisieren", - "error.page.report.prefix": "Bitte melden Sie diesen Fehler dem OpenCode-Team", + "error.page.report.prefix": "Bitte melden Sie diesen Fehler dem Kilo-Team", "error.page.report.discord": "auf Discord", "error.page.version": "Version: {{version}}", @@ -403,7 +403,7 @@ export const dict = { "error.chain.modelNotFound": "Modell nicht gefunden: {{provider}}/{{model}}", "error.chain.checkConfig": "Überprüfen Sie Ihre Konfiguration (opencode.json) auf Anbieter-/Modellnamen", "error.chain.mcpFailed": - 'MCP-Server "{{name}}" fehlgeschlagen. Hinweis: OpenCode unterstützt noch keine MCP-Authentifizierung.', + 'MCP-Server "{{name}}" fehlgeschlagen. Hinweis: Kilo unterstützt noch keine MCP-Authentifizierung.', "error.chain.providerAuthFailed": "Anbieter-Authentifizierung fehlgeschlagen ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'Anbieter "{{provider}}" konnte nicht initialisiert werden. Überprüfen Sie Anmeldeinformationen und Konfiguration.', @@ -513,13 +513,13 @@ export const dict = { "sidebar.workspaces.enable": "Arbeitsbereiche aktivieren", "sidebar.workspaces.disable": "Arbeitsbereiche deaktivieren", "sidebar.gettingStarted.title": "Erste Schritte", - "sidebar.gettingStarted.line1": "OpenCode enthält kostenlose Modelle, damit Sie sofort loslegen können.", + "sidebar.gettingStarted.line1": "Kilo enthält kostenlose Modelle, damit Sie sofort loslegen können.", "sidebar.gettingStarted.line2": "Verbinden Sie einen beliebigen Anbieter, um Modelle wie Claude, GPT, Gemini usw. zu nutzen.", "sidebar.project.recentSessions": "Letzte Sitzungen", "sidebar.project.viewAllSessions": "Alle Sitzungen anzeigen", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Desktop", "settings.section.server": "Server", "settings.tab.general": "Allgemein", @@ -531,11 +531,11 @@ export const dict = { "settings.general.section.sounds": "Soundeffekte", "settings.general.row.language.title": "Sprache", - "settings.general.row.language.description": "Die Anzeigesprache für OpenCode ändern", + "settings.general.row.language.description": "Die Anzeigesprache für Kilo ändern", "settings.general.row.appearance.title": "Erscheinungsbild", - "settings.general.row.appearance.description": "Anpassen, wie OpenCode auf Ihrem Gerät aussieht", + "settings.general.row.appearance.description": "Anpassen, wie Kilo auf Ihrem Gerät aussieht", "settings.general.row.theme.title": "Thema", - "settings.general.row.theme.description": "Das Thema von OpenCode anpassen.", + "settings.general.row.theme.description": "Das Thema von Kilo anpassen.", "settings.general.row.font.title": "Schriftart", "settings.general.row.font.description": "Die in Codeblöcken verwendete Monospace-Schriftart anpassen", @@ -543,13 +543,13 @@ export const dict = { "settings.general.row.releaseNotes.description": '"Neuigkeiten"-Pop-ups nach Updates anzeigen', "settings.updates.row.startup.title": "Beim Start nach Updates suchen", - "settings.updates.row.startup.description": "Beim Start von OpenCode automatisch nach Updates suchen", + "settings.updates.row.startup.description": "Beim Start von Kilo automatisch nach Updates suchen", "settings.updates.row.check.title": "Nach Updates suchen", "settings.updates.row.check.description": "Manuell nach Updates suchen und installieren, wenn verfügbar", "settings.updates.action.checkNow": "Jetzt prüfen", "settings.updates.action.checking": "Wird geprüft...", "settings.updates.toast.latest.title": "Du bist auf dem neuesten Stand", - "settings.updates.toast.latest.description": "Du verwendest die aktuelle Version von OpenCode.", + "settings.updates.toast.latest.description": "Du verwendest die aktuelle Version von Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts index a6a50506a..d7831c7a4 100644 --- a/packages/app/src/i18n/en.ts +++ b/packages/app/src/i18n/en.ts @@ -105,7 +105,7 @@ export const dict = { "dialog.model.manage": "Manage models", "dialog.model.manage.description": "Customize which models appear in the model selector.", - "dialog.model.unpaid.freeModels.title": "Free models provided by OpenCode", + "dialog.model.unpaid.freeModels.title": "Free models provided by Kilo", "dialog.model.unpaid.addMore.title": "Add more models from popular providers", "dialog.provider.viewAll": "Show more providers", @@ -118,7 +118,7 @@ export const dict = { "provider.connect.status.waiting": "Waiting for authorization...", "provider.connect.status.failed": "Authorization failed: {{error}}", "provider.connect.apiKey.description": - "Enter your {{provider}} API key to connect your account and use {{provider}} models in OpenCode.", + "Enter your {{provider}} API key to connect your account and use {{provider}} models in Kilo.", "provider.connect.apiKey.label": "{{provider}} API key", "provider.connect.apiKey.placeholder": "API key", "provider.connect.apiKey.required": "API key is required", @@ -132,7 +132,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Visit ", "provider.connect.oauth.code.visit.link": "this link", "provider.connect.oauth.code.visit.suffix": - " to collect your authorization code to connect your account and use {{provider}} models in OpenCode.", + " to collect your authorization code to connect your account and use {{provider}} models in Kilo.", "provider.connect.oauth.code.label": "{{method}} authorization code", "provider.connect.oauth.code.placeholder": "Authorization code", "provider.connect.oauth.code.required": "Authorization code is required", @@ -140,7 +140,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Visit ", "provider.connect.oauth.auto.visit.link": "this link", "provider.connect.oauth.auto.visit.suffix": - " and enter the code below to connect your account and use {{provider}} models in OpenCode.", + " and enter the code below to connect your account and use {{provider}} models in Kilo.", "provider.connect.oauth.auto.confirmationCode": "Confirmation code", "provider.connect.toast.connected.title": "{{provider}} connected", "provider.connect.toast.connected.description": "{{provider}} models are now available to use.", @@ -253,7 +253,7 @@ export const dict = { "dialog.directory.empty": "No folders found", "dialog.server.title": "Servers", - "dialog.server.description": "Switch which OpenCode server this app connects to.", + "dialog.server.description": "Switch which Kilo server this app connects to.", "dialog.server.search.placeholder": "Search servers", "dialog.server.empty": "No servers yet", "dialog.server.add.title": "Add a server", @@ -373,7 +373,7 @@ export const dict = { "toast.session.listFailed.title": "Failed to load sessions for {{project}}", "toast.update.title": "Update available", - "toast.update.description": "A new version of OpenCode ({{version}}) is now available to install.", + "toast.update.description": "A new version of Kilo ({{version}}) is now available to install.", "toast.update.action.installRestart": "Install and restart", "toast.update.action.notYet": "Not yet", @@ -384,7 +384,7 @@ export const dict = { "error.page.action.checking": "Checking...", "error.page.action.checkUpdates": "Check for updates", "error.page.action.updateTo": "Update to {{version}}", - "error.page.report.prefix": "Please report this error to the OpenCode team", + "error.page.report.prefix": "Please report this error to the Kilo team", "error.page.report.discord": "on Discord", "error.page.version": "Version: {{version}}", @@ -402,7 +402,7 @@ 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, Kilo 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.', @@ -513,12 +513,12 @@ export const dict = { "sidebar.workspaces.enable": "Enable workspaces", "sidebar.workspaces.disable": "Disable workspaces", "sidebar.gettingStarted.title": "Getting started", - "sidebar.gettingStarted.line1": "OpenCode includes free models so you can start immediately.", + "sidebar.gettingStarted.line1": "Kilo includes free models so you can start immediately.", "sidebar.gettingStarted.line2": "Connect any provider to use models, inc. Claude, GPT, Gemini etc.", "sidebar.project.recentSessions": "Recent sessions", "sidebar.project.viewAllSessions": "View all sessions", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Desktop", "settings.section.server": "Server", @@ -531,11 +531,11 @@ export const dict = { "settings.general.section.sounds": "Sound effects", "settings.general.row.language.title": "Language", - "settings.general.row.language.description": "Change the display language for OpenCode", + "settings.general.row.language.description": "Change the display language for Kilo", "settings.general.row.appearance.title": "Appearance", - "settings.general.row.appearance.description": "Customise how OpenCode looks on your device", + "settings.general.row.appearance.description": "Customise how Kilo looks on your device", "settings.general.row.theme.title": "Theme", - "settings.general.row.theme.description": "Customise how OpenCode is themed.", + "settings.general.row.theme.description": "Customise how Kilo is themed.", "settings.general.row.font.title": "Font", "settings.general.row.font.description": "Customise the mono font used in code blocks", @@ -543,13 +543,13 @@ export const dict = { "settings.general.row.releaseNotes.description": "Show What's New popups after updates", "settings.updates.row.startup.title": "Check for updates on startup", - "settings.updates.row.startup.description": "Automatically check for updates when OpenCode launches", + "settings.updates.row.startup.description": "Automatically check for updates when Kilo launches", "settings.updates.row.check.title": "Check for updates", "settings.updates.row.check.description": "Manually check for updates and install if available", "settings.updates.action.checkNow": "Check now", "settings.updates.action.checking": "Checking...", "settings.updates.toast.latest.title": "You're up to date", - "settings.updates.toast.latest.description": "You're running the latest version of OpenCode.", + "settings.updates.toast.latest.description": "You're running the latest version of Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/es.ts b/packages/app/src/i18n/es.ts index ee75a143d..ab8584259 100644 --- a/packages/app/src/i18n/es.ts +++ b/packages/app/src/i18n/es.ts @@ -101,7 +101,7 @@ export const dict = { "dialog.model.manage": "Gestionar modelos", "dialog.model.manage.description": "Personalizar qué modelos aparecen en el selector de modelos.", - "dialog.model.unpaid.freeModels.title": "Modelos gratuitos proporcionados por OpenCode", + "dialog.model.unpaid.freeModels.title": "Modelos gratuitos proporcionados por Kilo", "dialog.model.unpaid.addMore.title": "Añadir más modelos de proveedores populares", "dialog.provider.viewAll": "Ver más proveedores", @@ -114,7 +114,7 @@ export const dict = { "provider.connect.status.waiting": "Esperando autorización...", "provider.connect.status.failed": "Autorización fallida: {{error}}", "provider.connect.apiKey.description": - "Introduce tu clave API de {{provider}} para conectar tu cuenta y usar modelos de {{provider}} en OpenCode.", + "Introduce tu clave API de {{provider}} para conectar tu cuenta y usar modelos de {{provider}} en Kilo.", "provider.connect.apiKey.label": "Clave API de {{provider}}", "provider.connect.apiKey.placeholder": "Clave API", "provider.connect.apiKey.required": "La clave API es obligatoria", @@ -128,7 +128,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Visita ", "provider.connect.oauth.code.visit.link": "este enlace", "provider.connect.oauth.code.visit.suffix": - " para obtener tu código de autorización para conectar tu cuenta y usar modelos de {{provider}} en OpenCode.", + " para obtener tu código de autorización para conectar tu cuenta y usar modelos de {{provider}} en Kilo.", "provider.connect.oauth.code.label": "Código de autorización {{method}}", "provider.connect.oauth.code.placeholder": "Código de autorización", "provider.connect.oauth.code.required": "El código de autorización es obligatorio", @@ -136,7 +136,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Visita ", "provider.connect.oauth.auto.visit.link": "este enlace", "provider.connect.oauth.auto.visit.suffix": - " e introduce el código a continuación para conectar tu cuenta y usar modelos de {{provider}} en OpenCode.", + " e introduce el código a continuación para conectar tu cuenta y usar modelos de {{provider}} en Kilo.", "provider.connect.oauth.auto.confirmationCode": "Código de confirmación", "provider.connect.toast.connected.title": "{{provider}} conectado", "provider.connect.toast.connected.description": "Los modelos de {{provider}} ahora están disponibles para usar.", @@ -247,7 +247,7 @@ export const dict = { "dialog.directory.empty": "No se encontraron carpetas", "dialog.server.title": "Servidores", - "dialog.server.description": "Cambiar a qué servidor de OpenCode se conecta esta app.", + "dialog.server.description": "Cambiar a qué servidor de Kilo se conecta esta app.", "dialog.server.search.placeholder": "Buscar servidores", "dialog.server.empty": "No hay servidores aún", "dialog.server.add.title": "Añadir un servidor", @@ -368,7 +368,7 @@ export const dict = { "toast.session.listFailed.title": "Fallo al cargar sesiones para {{project}}", "toast.update.title": "Actualización disponible", - "toast.update.description": "Una nueva versión de OpenCode ({{version}}) está disponible para instalar.", + "toast.update.description": "Una nueva versión de Kilo ({{version}}) está disponible para instalar.", "toast.update.action.installRestart": "Instalar y reiniciar", "toast.update.action.notYet": "Todavía no", @@ -379,7 +379,7 @@ export const dict = { "error.page.action.checking": "Comprobando...", "error.page.action.checkUpdates": "Buscar actualizaciones", "error.page.action.updateTo": "Actualizar a {{version}}", - "error.page.report.prefix": "Por favor reporta este error al equipo de OpenCode", + "error.page.report.prefix": "Por favor reporta este error al equipo de Kilo", "error.page.report.discord": "en Discord", "error.page.version": "Versión: {{version}}", @@ -397,7 +397,7 @@ export const dict = { "error.chain.didYouMean": "¿Quisiste decir: {{suggestions}}", "error.chain.modelNotFound": "Modelo no encontrado: {{provider}}/{{model}}", "error.chain.checkConfig": "Comprueba los nombres de proveedor/modelo en tu configuración (opencode.json)", - "error.chain.mcpFailed": 'El servidor MCP "{{name}}" falló. Nota, OpenCode no soporta autenticación MCP todavía.', + "error.chain.mcpFailed": 'El servidor MCP "{{name}}" falló. Nota, Kilo no soporta autenticación MCP todavía.', "error.chain.providerAuthFailed": "Autenticación de proveedor fallida ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'Fallo al inicializar proveedor "{{provider}}". Comprueba credenciales y configuración.', @@ -507,12 +507,12 @@ export const dict = { "sidebar.workspaces.enable": "Habilitar espacios de trabajo", "sidebar.workspaces.disable": "Deshabilitar espacios de trabajo", "sidebar.gettingStarted.title": "Empezando", - "sidebar.gettingStarted.line1": "OpenCode incluye modelos gratuitos para que puedas empezar inmediatamente.", + "sidebar.gettingStarted.line1": "Kilo incluye modelos gratuitos para que puedas empezar inmediatamente.", "sidebar.gettingStarted.line2": "Conecta cualquier proveedor para usar modelos, inc. Claude, GPT, Gemini etc.", "sidebar.project.recentSessions": "Sesiones recientes", "sidebar.project.viewAllSessions": "Ver todas las sesiones", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Escritorio", "settings.section.server": "Servidor", "settings.tab.general": "General", @@ -524,11 +524,11 @@ export const dict = { "settings.general.section.sounds": "Efectos de sonido", "settings.general.row.language.title": "Idioma", - "settings.general.row.language.description": "Cambiar el idioma de visualización para OpenCode", + "settings.general.row.language.description": "Cambiar el idioma de visualización para Kilo", "settings.general.row.appearance.title": "Apariencia", - "settings.general.row.appearance.description": "Personaliza cómo se ve OpenCode en tu dispositivo", + "settings.general.row.appearance.description": "Personaliza cómo se ve Kilo en tu dispositivo", "settings.general.row.theme.title": "Tema", - "settings.general.row.theme.description": "Personaliza el tema de OpenCode.", + "settings.general.row.theme.description": "Personaliza el tema de Kilo.", "settings.general.row.font.title": "Fuente", "settings.general.row.font.description": "Personaliza la fuente mono usada en bloques de código", @@ -537,13 +537,13 @@ export const dict = { 'Mostrar ventanas emergentes de "Novedades" después de las actualizaciones', "settings.updates.row.startup.title": "Buscar actualizaciones al iniciar", - "settings.updates.row.startup.description": "Buscar actualizaciones automáticamente cuando se inicia OpenCode", + "settings.updates.row.startup.description": "Buscar actualizaciones automáticamente cuando se inicia Kilo", "settings.updates.row.check.title": "Buscar actualizaciones", "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.toast.latest.title": "Estás al día", - "settings.updates.toast.latest.description": "Estás usando la última versión de OpenCode.", + "settings.updates.toast.latest.description": "Estás usando la última versión de Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", diff --git a/packages/app/src/i18n/fr.ts b/packages/app/src/i18n/fr.ts index f0652a981..d615ff2c8 100644 --- a/packages/app/src/i18n/fr.ts +++ b/packages/app/src/i18n/fr.ts @@ -101,7 +101,7 @@ export const dict = { "dialog.model.manage": "Gérer les modèles", "dialog.model.manage.description": "Personnalisez les modèles qui apparaissent dans le sélecteur.", - "dialog.model.unpaid.freeModels.title": "Modèles gratuits fournis par OpenCode", + "dialog.model.unpaid.freeModels.title": "Modèles gratuits fournis par Kilo", "dialog.model.unpaid.addMore.title": "Ajouter plus de modèles de fournisseurs populaires", "dialog.provider.viewAll": "Voir plus de fournisseurs", @@ -114,7 +114,7 @@ export const dict = { "provider.connect.status.waiting": "En attente d'autorisation...", "provider.connect.status.failed": "Échec de l'autorisation : {{error}}", "provider.connect.apiKey.description": - "Entrez votre clé API {{provider}} pour connecter votre compte et utiliser les modèles {{provider}} dans OpenCode.", + "Entrez votre clé API {{provider}} pour connecter votre compte et utiliser les modèles {{provider}} dans Kilo.", "provider.connect.apiKey.label": "Clé API {{provider}}", "provider.connect.apiKey.placeholder": "Clé API", "provider.connect.apiKey.required": "La clé API est requise", @@ -128,7 +128,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Visitez ", "provider.connect.oauth.code.visit.link": "ce lien", "provider.connect.oauth.code.visit.suffix": - " pour récupérer votre code d'autorisation afin de connecter votre compte et utiliser les modèles {{provider}} dans OpenCode.", + " pour récupérer votre code d'autorisation afin de connecter votre compte et utiliser les modèles {{provider}} dans Kilo.", "provider.connect.oauth.code.label": "Code d'autorisation {{method}}", "provider.connect.oauth.code.placeholder": "Code d'autorisation", "provider.connect.oauth.code.required": "Le code d'autorisation est requis", @@ -136,7 +136,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Visitez ", "provider.connect.oauth.auto.visit.link": "ce lien", "provider.connect.oauth.auto.visit.suffix": - " et entrez le code ci-dessous pour connecter votre compte et utiliser les modèles {{provider}} dans OpenCode.", + " et entrez le code ci-dessous pour connecter votre compte et utiliser les modèles {{provider}} dans Kilo.", "provider.connect.oauth.auto.confirmationCode": "Code de confirmation", "provider.connect.toast.connected.title": "{{provider}} connecté", "provider.connect.toast.connected.description": "Les modèles {{provider}} sont maintenant disponibles.", @@ -247,7 +247,7 @@ export const dict = { "dialog.directory.empty": "Aucun dossier trouvé", "dialog.server.title": "Serveurs", - "dialog.server.description": "Changez le serveur OpenCode auquel cette application se connecte.", + "dialog.server.description": "Changez le serveur Kilo auquel cette application se connecte.", "dialog.server.search.placeholder": "Rechercher des serveurs", "dialog.server.empty": "Aucun serveur pour l'instant", "dialog.server.add.title": "Ajouter un serveur", @@ -371,7 +371,7 @@ export const dict = { "toast.update.title": "Mise à jour disponible", "toast.update.description": - "Une nouvelle version d'OpenCode ({{version}}) est maintenant disponible pour installation.", + "Une nouvelle version d'Kilo ({{version}}) est maintenant disponible pour installation.", "toast.update.action.installRestart": "Installer et redémarrer", "toast.update.action.notYet": "Pas encore", @@ -382,7 +382,7 @@ export const dict = { "error.page.action.checking": "Vérification...", "error.page.action.checkUpdates": "Vérifier les mises à jour", "error.page.action.updateTo": "Mettre à jour vers {{version}}", - "error.page.report.prefix": "Veuillez signaler cette erreur à l'équipe OpenCode", + "error.page.report.prefix": "Veuillez signaler cette erreur à l'équipe Kilo", "error.page.report.discord": "sur Discord", "error.page.version": "Version : {{version}}", @@ -402,7 +402,7 @@ export const dict = { "error.chain.modelNotFound": "Modèle introuvable : {{provider}}/{{model}}", "error.chain.checkConfig": "Vérifiez votre configuration (opencode.json) pour les noms de fournisseur/modèle", "error.chain.mcpFailed": - "Le serveur MCP \"{{name}}\" a échoué. Notez qu'OpenCode ne supporte pas encore l'authentification MCP.", + "Le serveur MCP \"{{name}}\" a échoué. Notez qu'Kilo ne supporte pas encore l'authentification MCP.", "error.chain.providerAuthFailed": "Échec de l'authentification du fournisseur ({{provider}}) : {{message}}", "error.chain.providerInitFailed": 'Échec de l\'initialisation du fournisseur "{{provider}}". Vérifiez les identifiants et la configuration.', @@ -513,13 +513,13 @@ export const dict = { "sidebar.workspaces.disable": "Désactiver les espaces de travail", "sidebar.gettingStarted.title": "Commencer", "sidebar.gettingStarted.line1": - "OpenCode inclut des modèles gratuits pour que vous puissiez commencer immédiatement.", + "Kilo inclut des modèles gratuits pour que vous puissiez commencer immédiatement.", "sidebar.gettingStarted.line2": "Connectez n'importe quel fournisseur pour utiliser des modèles, y compris Claude, GPT, Gemini etc.", "sidebar.project.recentSessions": "Sessions récentes", "sidebar.project.viewAllSessions": "Voir toutes les sessions", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Bureau", "settings.section.server": "Serveur", "settings.tab.general": "Général", @@ -531,11 +531,11 @@ export const dict = { "settings.general.section.sounds": "Effets sonores", "settings.general.row.language.title": "Langue", - "settings.general.row.language.description": "Changer la langue d'affichage pour OpenCode", + "settings.general.row.language.description": "Changer la langue d'affichage pour Kilo", "settings.general.row.appearance.title": "Apparence", - "settings.general.row.appearance.description": "Personnaliser l'apparence d'OpenCode sur votre appareil", + "settings.general.row.appearance.description": "Personnaliser l'apparence d'Kilo sur votre appareil", "settings.general.row.theme.title": "Thème", - "settings.general.row.theme.description": "Personnaliser le thème d'OpenCode.", + "settings.general.row.theme.description": "Personnaliser le thème d'Kilo.", "settings.general.row.font.title": "Police", "settings.general.row.font.description": "Personnaliser la police mono utilisée dans les blocs de code", @@ -543,13 +543,13 @@ export const dict = { "settings.general.row.releaseNotes.description": 'Afficher des pop-ups "Quoi de neuf" après les mises à jour', "settings.updates.row.startup.title": "Vérifier les mises à jour au démarrage", - "settings.updates.row.startup.description": "Vérifier automatiquement les mises à jour au lancement d'OpenCode", + "settings.updates.row.startup.description": "Vérifier automatiquement les mises à jour au lancement d'Kilo", "settings.updates.row.check.title": "Vérifier les mises à jour", "settings.updates.row.check.description": "Vérifier manuellement les mises à jour et installer si disponible", "settings.updates.action.checkNow": "Vérifier maintenant", "settings.updates.action.checking": "Vérification...", "settings.updates.toast.latest.title": "Vous êtes à jour", - "settings.updates.toast.latest.description": "Vous utilisez la dernière version d'OpenCode.", + "settings.updates.toast.latest.description": "Vous utilisez la dernière version d'Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", diff --git a/packages/app/src/i18n/ja.ts b/packages/app/src/i18n/ja.ts index ffe536814..c0e1dacd7 100644 --- a/packages/app/src/i18n/ja.ts +++ b/packages/app/src/i18n/ja.ts @@ -101,7 +101,7 @@ export const dict = { "dialog.model.manage": "モデルを管理", "dialog.model.manage.description": "モデルセレクターに表示するモデルをカスタマイズします。", - "dialog.model.unpaid.freeModels.title": "OpenCodeが提供する無料モデル", + "dialog.model.unpaid.freeModels.title": "Kiloが提供する無料モデル", "dialog.model.unpaid.addMore.title": "人気のプロバイダーからモデルを追加", "dialog.provider.viewAll": "さらにプロバイダーを表示", @@ -114,7 +114,7 @@ export const dict = { "provider.connect.status.waiting": "認証を待機中...", "provider.connect.status.failed": "認証に失敗しました: {{error}}", "provider.connect.apiKey.description": - "{{provider}}のAPIキーを入力してアカウントを接続し、OpenCodeで{{provider}}モデルを使用します。", + "{{provider}}のAPIキーを入力してアカウントを接続し、Kiloで{{provider}}モデルを使用します。", "provider.connect.apiKey.label": "{{provider}} APIキー", "provider.connect.apiKey.placeholder": "APIキー", "provider.connect.apiKey.required": "APIキーが必要です", @@ -127,7 +127,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": " ", "provider.connect.oauth.code.visit.link": "このリンク", "provider.connect.oauth.code.visit.suffix": - " にアクセスして認証コードを取得し、アカウントを接続してOpenCodeで{{provider}}モデルを使用してください。", + " にアクセスして認証コードを取得し、アカウントを接続してKiloで{{provider}}モデルを使用してください。", "provider.connect.oauth.code.label": "{{method}} 認証コード", "provider.connect.oauth.code.placeholder": "認証コード", "provider.connect.oauth.code.required": "認証コードが必要です", @@ -135,7 +135,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": " ", "provider.connect.oauth.auto.visit.link": "このリンク", "provider.connect.oauth.auto.visit.suffix": - " にアクセスし、以下のコードを入力してアカウントを接続し、OpenCodeで{{provider}}モデルを使用してください。", + " にアクセスし、以下のコードを入力してアカウントを接続し、Kiloで{{provider}}モデルを使用してください。", "provider.connect.oauth.auto.confirmationCode": "確認コード", "provider.connect.toast.connected.title": "{{provider}}が接続されました", "provider.connect.toast.connected.description": "{{provider}}モデルが使用可能になりました。", @@ -246,7 +246,7 @@ export const dict = { "dialog.directory.empty": "フォルダが見つかりません", "dialog.server.title": "サーバー", - "dialog.server.description": "このアプリが接続するOpenCodeサーバーを切り替えます。", + "dialog.server.description": "このアプリが接続するKiloサーバーを切り替えます。", "dialog.server.search.placeholder": "サーバーを検索", "dialog.server.empty": "サーバーはまだありません", "dialog.server.add.title": "サーバーを追加", @@ -366,7 +366,7 @@ export const dict = { "toast.session.listFailed.title": "{{project}}のセッション読み込みに失敗しました", "toast.update.title": "アップデートが利用可能です", - "toast.update.description": "OpenCodeの新しいバージョン ({{version}}) がインストール可能です。", + "toast.update.description": "Kiloの新しいバージョン ({{version}}) がインストール可能です。", "toast.update.action.installRestart": "インストールして再起動", "toast.update.action.notYet": "今はしない", @@ -377,7 +377,7 @@ export const dict = { "error.page.action.checking": "確認中...", "error.page.action.checkUpdates": "アップデートを確認", "error.page.action.updateTo": "{{version}}にアップデート", - "error.page.report.prefix": "このエラーをOpenCodeチームに報告してください: ", + "error.page.report.prefix": "このエラーをKiloチームに報告してください: ", "error.page.report.discord": "Discord", "error.page.version": "バージョン: {{version}}", @@ -395,7 +395,7 @@ export const dict = { "error.chain.didYouMean": "もしかして: {{suggestions}}", "error.chain.modelNotFound": "モデルが見つかりません: {{provider}}/{{model}}", "error.chain.checkConfig": "config (opencode.json) のプロバイダー/モデル名を確認してください", - "error.chain.mcpFailed": 'MCPサーバー "{{name}}" が失敗しました。注意: OpenCodeはまだMCP認証をサポートしていません。', + "error.chain.mcpFailed": 'MCPサーバー "{{name}}" が失敗しました。注意: KiloはまだMCP認証をサポートしていません。', "error.chain.providerAuthFailed": "プロバイダー認証に失敗しました ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'プロバイダー "{{provider}}" の初期化に失敗しました。認証情報と設定を確認してください。', @@ -504,12 +504,12 @@ export const dict = { "sidebar.workspaces.enable": "ワークスペースを有効化", "sidebar.workspaces.disable": "ワークスペースを無効化", "sidebar.gettingStarted.title": "はじめに", - "sidebar.gettingStarted.line1": "OpenCodeには無料モデルが含まれているため、すぐに開始できます。", + "sidebar.gettingStarted.line1": "Kiloには無料モデルが含まれているため、すぐに開始できます。", "sidebar.gettingStarted.line2": "プロバイダーを接続して、Claude、GPT、Geminiなどのモデルを使用できます。", "sidebar.project.recentSessions": "最近のセッション", "sidebar.project.viewAllSessions": "すべてのセッションを表示", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "デスクトップ", "settings.section.server": "サーバー", "settings.tab.general": "一般", @@ -521,11 +521,11 @@ export const dict = { "settings.general.section.sounds": "効果音", "settings.general.row.language.title": "言語", - "settings.general.row.language.description": "OpenCodeの表示言語を変更します", + "settings.general.row.language.description": "Kiloの表示言語を変更します", "settings.general.row.appearance.title": "外観", - "settings.general.row.appearance.description": "デバイスでのOpenCodeの表示をカスタマイズします", + "settings.general.row.appearance.description": "デバイスでのKiloの表示をカスタマイズします", "settings.general.row.theme.title": "テーマ", - "settings.general.row.theme.description": "OpenCodeのテーマをカスタマイズします。", + "settings.general.row.theme.description": "Kiloのテーマをカスタマイズします。", "settings.general.row.font.title": "フォント", "settings.general.row.font.description": "コードブロックで使用する等幅フォントをカスタマイズします", @@ -533,13 +533,13 @@ export const dict = { "settings.general.row.releaseNotes.description": "アップデート後に「新機能」ポップアップを表示", "settings.updates.row.startup.title": "起動時にアップデートを確認", - "settings.updates.row.startup.description": "OpenCode の起動時に自動でアップデートを確認します", + "settings.updates.row.startup.description": "Kilo の起動時に自動でアップデートを確認します", "settings.updates.row.check.title": "アップデートを確認", "settings.updates.row.check.description": "手動でアップデートを確認し、利用可能ならインストールします", "settings.updates.action.checkNow": "今すぐ確認", "settings.updates.action.checking": "確認中...", "settings.updates.toast.latest.title": "最新です", - "settings.updates.toast.latest.description": "OpenCode は最新バージョンです。", + "settings.updates.toast.latest.description": "Kilo は最新バージョンです。", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", diff --git a/packages/app/src/i18n/ko.ts b/packages/app/src/i18n/ko.ts index 6c30e0123..8deb6bc1b 100644 --- a/packages/app/src/i18n/ko.ts +++ b/packages/app/src/i18n/ko.ts @@ -105,7 +105,7 @@ export const dict = { "dialog.model.manage": "모델 관리", "dialog.model.manage.description": "모델 선택기에 표시할 모델 사용자 지정", - "dialog.model.unpaid.freeModels.title": "OpenCode에서 제공하는 무료 모델", + "dialog.model.unpaid.freeModels.title": "Kilo에서 제공하는 무료 모델", "dialog.model.unpaid.addMore.title": "인기 공급자의 모델 추가", "dialog.provider.viewAll": "더 많은 공급자 보기", @@ -118,7 +118,7 @@ export const dict = { "provider.connect.status.waiting": "인증 대기 중...", "provider.connect.status.failed": "인증 실패: {{error}}", "provider.connect.apiKey.description": - "{{provider}} API 키를 입력하여 계정을 연결하고 OpenCode에서 {{provider}} 모델을 사용하세요.", + "{{provider}} API 키를 입력하여 계정을 연결하고 Kilo에서 {{provider}} 모델을 사용하세요.", "provider.connect.apiKey.label": "{{provider}} API 키", "provider.connect.apiKey.placeholder": "API 키", "provider.connect.apiKey.required": "API 키가 필요합니다", @@ -131,7 +131,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "", "provider.connect.oauth.code.visit.link": "이 링크", "provider.connect.oauth.code.visit.suffix": - "를 방문하여 인증 코드를 받아 계정을 연결하고 OpenCode에서 {{provider}} 모델을 사용하세요.", + "를 방문하여 인증 코드를 받아 계정을 연결하고 Kilo에서 {{provider}} 모델을 사용하세요.", "provider.connect.oauth.code.label": "{{method}} 인증 코드", "provider.connect.oauth.code.placeholder": "인증 코드", "provider.connect.oauth.code.required": "인증 코드가 필요합니다", @@ -139,7 +139,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "", "provider.connect.oauth.auto.visit.link": "이 링크", "provider.connect.oauth.auto.visit.suffix": - "를 방문하고 아래 코드를 입력하여 계정을 연결하고 OpenCode에서 {{provider}} 모델을 사용하세요.", + "를 방문하고 아래 코드를 입력하여 계정을 연결하고 Kilo에서 {{provider}} 모델을 사용하세요.", "provider.connect.oauth.auto.confirmationCode": "확인 코드", "provider.connect.toast.connected.title": "{{provider}} 연결됨", "provider.connect.toast.connected.description": "이제 {{provider}} 모델을 사용할 수 있습니다.", @@ -250,7 +250,7 @@ export const dict = { "dialog.directory.empty": "폴더 없음", "dialog.server.title": "서버", - "dialog.server.description": "이 앱이 연결할 OpenCode 서버를 전환합니다.", + "dialog.server.description": "이 앱이 연결할 Kilo 서버를 전환합니다.", "dialog.server.search.placeholder": "서버 검색", "dialog.server.empty": "서버 없음", "dialog.server.add.title": "서버 추가", @@ -369,7 +369,7 @@ export const dict = { "toast.session.listFailed.title": "{{project}}에 대한 세션을 로드하지 못했습니다", "toast.update.title": "업데이트 가능", - "toast.update.description": "OpenCode의 새 버전({{version}})을 설치할 수 있습니다.", + "toast.update.description": "Kilo의 새 버전({{version}})을 설치할 수 있습니다.", "toast.update.action.installRestart": "설치 및 다시 시작", "toast.update.action.notYet": "나중에", @@ -380,7 +380,7 @@ export const dict = { "error.page.action.checking": "확인 중...", "error.page.action.checkUpdates": "업데이트 확인", "error.page.action.updateTo": "{{version}} 버전으로 업데이트", - "error.page.report.prefix": "이 오류를 OpenCode 팀에 제보해 주세요: ", + "error.page.report.prefix": "이 오류를 Kilo 팀에 제보해 주세요: ", "error.page.report.discord": "Discord", "error.page.version": "버전: {{version}}", @@ -398,7 +398,7 @@ export const dict = { "error.chain.didYouMean": "혹시 {{suggestions}}을(를) 의미하셨나요?", "error.chain.modelNotFound": "모델을 찾을 수 없음: {{provider}}/{{model}}", "error.chain.checkConfig": "구성(opencode.json)의 공급자/모델 이름을 확인하세요", - "error.chain.mcpFailed": 'MCP 서버 "{{name}}" 실패. 참고: OpenCode는 아직 MCP 인증을 지원하지 않습니다.', + "error.chain.mcpFailed": 'MCP 서버 "{{name}}" 실패. 참고: Kilo는 아직 MCP 인증을 지원하지 않습니다.', "error.chain.providerAuthFailed": "공급자 인증 실패 ({{provider}}): {{message}}", "error.chain.providerInitFailed": '공급자 "{{provider}}" 초기화 실패. 자격 증명과 구성을 확인하세요.', "error.chain.configJsonInvalid": "{{path}}의 구성 파일이 유효한 JSON(C)가 아닙니다", @@ -505,12 +505,12 @@ export const dict = { "sidebar.workspaces.enable": "작업 공간 활성화", "sidebar.workspaces.disable": "작업 공간 비활성화", "sidebar.gettingStarted.title": "시작하기", - "sidebar.gettingStarted.line1": "OpenCode에는 무료 모델이 포함되어 있어 즉시 시작할 수 있습니다.", + "sidebar.gettingStarted.line1": "Kilo에는 무료 모델이 포함되어 있어 즉시 시작할 수 있습니다.", "sidebar.gettingStarted.line2": "Claude, GPT, Gemini 등을 포함한 모델을 사용하려면 공급자를 연결하세요.", "sidebar.project.recentSessions": "최근 세션", "sidebar.project.viewAllSessions": "모든 세션 보기", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "데스크톱", "settings.section.server": "서버", "settings.tab.general": "일반", @@ -522,11 +522,11 @@ export const dict = { "settings.general.section.sounds": "효과음", "settings.general.row.language.title": "언어", - "settings.general.row.language.description": "OpenCode 표시 언어 변경", + "settings.general.row.language.description": "Kilo 표시 언어 변경", "settings.general.row.appearance.title": "모양", - "settings.general.row.appearance.description": "기기에서 OpenCode가 보이는 방식 사용자 지정", + "settings.general.row.appearance.description": "기기에서 Kilo가 보이는 방식 사용자 지정", "settings.general.row.theme.title": "테마", - "settings.general.row.theme.description": "OpenCode 테마 사용자 지정", + "settings.general.row.theme.description": "Kilo 테마 사용자 지정", "settings.general.row.font.title": "글꼴", "settings.general.row.font.description": "코드 블록에 사용되는 고정폭 글꼴 사용자 지정", @@ -534,13 +534,13 @@ export const dict = { "settings.general.row.releaseNotes.description": "업데이트 후 '새 소식' 팝업 표시", "settings.updates.row.startup.title": "시작 시 업데이트 확인", - "settings.updates.row.startup.description": "OpenCode를 실행할 때 업데이트를 자동으로 확인합니다", + "settings.updates.row.startup.description": "Kilo를 실행할 때 업데이트를 자동으로 확인합니다", "settings.updates.row.check.title": "업데이트 확인", "settings.updates.row.check.description": "업데이트를 수동으로 확인하고, 사용 가능하면 설치합니다", "settings.updates.action.checkNow": "지금 확인", "settings.updates.action.checking": "확인 중...", "settings.updates.toast.latest.title": "최신 상태입니다", - "settings.updates.toast.latest.description": "현재 최신 버전의 OpenCode를 사용 중입니다.", + "settings.updates.toast.latest.description": "현재 최신 버전의 Kilo를 사용 중입니다.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", diff --git a/packages/app/src/i18n/no.ts b/packages/app/src/i18n/no.ts index 132c0b6c1..b18ccf57d 100644 --- a/packages/app/src/i18n/no.ts +++ b/packages/app/src/i18n/no.ts @@ -104,7 +104,7 @@ export const dict = { "dialog.model.manage": "Administrer modeller", "dialog.model.manage.description": "Tilpass hvilke modeller som vises i modellvelgeren.", - "dialog.model.unpaid.freeModels.title": "Gratis modeller levert av OpenCode", + "dialog.model.unpaid.freeModels.title": "Gratis modeller levert av Kilo", "dialog.model.unpaid.addMore.title": "Legg til flere modeller fra populære leverandører", "dialog.provider.viewAll": "Vis flere leverandører", @@ -117,7 +117,7 @@ export const dict = { "provider.connect.status.waiting": "Venter på autorisering...", "provider.connect.status.failed": "Autorisering mislyktes: {{error}}", "provider.connect.apiKey.description": - "Skriv inn din {{provider}} API-nøkkel for å koble til kontoen din og bruke {{provider}}-modeller i OpenCode.", + "Skriv inn din {{provider}} API-nøkkel for å koble til kontoen din og bruke {{provider}}-modeller i Kilo.", "provider.connect.apiKey.label": "{{provider}} API-nøkkel", "provider.connect.apiKey.placeholder": "API-nøkkel", "provider.connect.apiKey.required": "API-nøkkel er påkrevd", @@ -131,7 +131,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Besøk ", "provider.connect.oauth.code.visit.link": "denne lenken", "provider.connect.oauth.code.visit.suffix": - " for å hente autorisasjonskoden din for å koble til kontoen din og bruke {{provider}}-modeller i OpenCode.", + " for å hente autorisasjonskoden din for å koble til kontoen din og bruke {{provider}}-modeller i Kilo.", "provider.connect.oauth.code.label": "{{method}} autorisasjonskode", "provider.connect.oauth.code.placeholder": "Autorisasjonskode", "provider.connect.oauth.code.required": "Autorisasjonskode er påkrevd", @@ -139,7 +139,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Besøk ", "provider.connect.oauth.auto.visit.link": "denne lenken", "provider.connect.oauth.auto.visit.suffix": - " og skriv inn koden nedenfor for å koble til kontoen din og bruke {{provider}}-modeller i OpenCode.", + " og skriv inn koden nedenfor for å koble til kontoen din og bruke {{provider}}-modeller i Kilo.", "provider.connect.oauth.auto.confirmationCode": "Bekreftelseskode", "provider.connect.toast.connected.title": "{{provider}} tilkoblet", "provider.connect.toast.connected.description": "{{provider}}-modeller er nå tilgjengelige.", @@ -250,7 +250,7 @@ export const dict = { "dialog.directory.empty": "Ingen mapper funnet", "dialog.server.title": "Servere", - "dialog.server.description": "Bytt hvilken OpenCode-server denne appen kobler til.", + "dialog.server.description": "Bytt hvilken Kilo-server denne appen kobler til.", "dialog.server.search.placeholder": "Søk etter servere", "dialog.server.empty": "Ingen servere ennå", "dialog.server.add.title": "Legg til en server", @@ -369,7 +369,7 @@ export const dict = { "toast.session.listFailed.title": "Kunne ikke laste sesjoner for {{project}}", "toast.update.title": "Oppdatering tilgjengelig", - "toast.update.description": "En ny versjon av OpenCode ({{version}}) er nå tilgjengelig for installasjon.", + "toast.update.description": "En ny versjon av Kilo ({{version}}) er nå tilgjengelig for installasjon.", "toast.update.action.installRestart": "Installer og start på nytt", "toast.update.action.notYet": "Ikke nå", @@ -380,7 +380,7 @@ export const dict = { "error.page.action.checking": "Sjekker...", "error.page.action.checkUpdates": "Se etter oppdateringer", "error.page.action.updateTo": "Oppdater til {{version}}", - "error.page.report.prefix": "Vennligst rapporter denne feilen til OpenCode-teamet", + "error.page.report.prefix": "Vennligst rapporter denne feilen til Kilo-teamet", "error.page.report.discord": "på Discord", "error.page.version": "Versjon: {{version}}", @@ -398,7 +398,7 @@ export const dict = { "error.chain.didYouMean": "Mente du: {{suggestions}}", "error.chain.modelNotFound": "Modell ikke funnet: {{provider}}/{{model}}", "error.chain.checkConfig": "Sjekk leverandør-/modellnavnene i konfigurasjonen din (opencode.json)", - "error.chain.mcpFailed": 'MCP-server "{{name}}" mislyktes. Merk at OpenCode ikke støtter MCP-autentisering ennå.', + "error.chain.mcpFailed": 'MCP-server "{{name}}" mislyktes. Merk at Kilo ikke støtter MCP-autentisering ennå.', "error.chain.providerAuthFailed": "Leverandørautentisering mislyktes ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'Kunne ikke initialisere leverandør "{{provider}}". Sjekk legitimasjon og konfigurasjon.', @@ -507,12 +507,12 @@ export const dict = { "sidebar.workspaces.enable": "Aktiver arbeidsområder", "sidebar.workspaces.disable": "Deaktiver arbeidsområder", "sidebar.gettingStarted.title": "Kom i gang", - "sidebar.gettingStarted.line1": "OpenCode inkluderer gratis modeller så du kan starte umiddelbart.", + "sidebar.gettingStarted.line1": "Kilo inkluderer gratis modeller så du kan starte umiddelbart.", "sidebar.gettingStarted.line2": "Koble til en leverandør for å bruke modeller, inkl. Claude, GPT, Gemini osv.", "sidebar.project.recentSessions": "Nylige sesjoner", "sidebar.project.viewAllSessions": "Vis alle sesjoner", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Skrivebord", "settings.section.server": "Server", "settings.tab.general": "Generelt", @@ -524,11 +524,11 @@ export const dict = { "settings.general.section.sounds": "Lydeffekter", "settings.general.row.language.title": "Språk", - "settings.general.row.language.description": "Endre visningsspråket for OpenCode", + "settings.general.row.language.description": "Endre visningsspråket for Kilo", "settings.general.row.appearance.title": "Utseende", - "settings.general.row.appearance.description": "Tilpass hvordan OpenCode ser ut på enheten din", + "settings.general.row.appearance.description": "Tilpass hvordan Kilo ser ut på enheten din", "settings.general.row.theme.title": "Tema", - "settings.general.row.theme.description": "Tilpass hvordan OpenCode er tematisert.", + "settings.general.row.theme.description": "Tilpass hvordan Kilo er tematisert.", "settings.general.row.font.title": "Skrift", "settings.general.row.font.description": "Tilpass mono-skriften som brukes i kodeblokker", @@ -536,13 +536,13 @@ export const dict = { "settings.general.row.releaseNotes.description": 'Vis "Hva er nytt"-vinduer etter oppdateringer', "settings.updates.row.startup.title": "Se etter oppdateringer ved oppstart", - "settings.updates.row.startup.description": "Se automatisk etter oppdateringer når OpenCode starter", + "settings.updates.row.startup.description": "Se automatisk etter oppdateringer når Kilo starter", "settings.updates.row.check.title": "Se etter oppdateringer", "settings.updates.row.check.description": "Se etter oppdateringer manuelt og installer hvis tilgjengelig", "settings.updates.action.checkNow": "Sjekk nå", "settings.updates.action.checking": "Sjekker...", "settings.updates.toast.latest.title": "Du er oppdatert", - "settings.updates.toast.latest.description": "Du bruker den nyeste versjonen av OpenCode.", + "settings.updates.toast.latest.description": "Du bruker den nyeste versjonen av Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", diff --git a/packages/app/src/i18n/pl.ts b/packages/app/src/i18n/pl.ts index efed3eeb1..2194b1b25 100644 --- a/packages/app/src/i18n/pl.ts +++ b/packages/app/src/i18n/pl.ts @@ -101,7 +101,7 @@ export const dict = { "dialog.model.manage": "Zarządzaj modelami", "dialog.model.manage.description": "Dostosuj, które modele pojawiają się w wyborze modelu.", - "dialog.model.unpaid.freeModels.title": "Darmowe modele dostarczane przez OpenCode", + "dialog.model.unpaid.freeModels.title": "Darmowe modele dostarczane przez Kilo", "dialog.model.unpaid.addMore.title": "Dodaj więcej modeli od popularnych dostawców", "dialog.provider.viewAll": "Zobacz więcej dostawców", @@ -114,7 +114,7 @@ export const dict = { "provider.connect.status.waiting": "Oczekiwanie na autoryzację...", "provider.connect.status.failed": "Autoryzacja nie powiodła się: {{error}}", "provider.connect.apiKey.description": - "Wprowadź swój klucz API {{provider}}, aby połączyć konto i używać modeli {{provider}} w OpenCode.", + "Wprowadź swój klucz API {{provider}}, aby połączyć konto i używać modeli {{provider}} w Kilo.", "provider.connect.apiKey.label": "Klucz API {{provider}}", "provider.connect.apiKey.placeholder": "Klucz API", "provider.connect.apiKey.required": "Klucz API jest wymagany", @@ -128,7 +128,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Odwiedź ", "provider.connect.oauth.code.visit.link": "ten link", "provider.connect.oauth.code.visit.suffix": - ", aby odebrać kod autoryzacyjny, połączyć konto i używać modeli {{provider}} w OpenCode.", + ", aby odebrać kod autoryzacyjny, połączyć konto i używać modeli {{provider}} w Kilo.", "provider.connect.oauth.code.label": "Kod autoryzacyjny {{method}}", "provider.connect.oauth.code.placeholder": "Kod autoryzacyjny", "provider.connect.oauth.code.required": "Kod autoryzacyjny jest wymagany", @@ -136,7 +136,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Odwiedź ", "provider.connect.oauth.auto.visit.link": "ten link", "provider.connect.oauth.auto.visit.suffix": - " i wprowadź poniższy kod, aby połączyć konto i używać modeli {{provider}} w OpenCode.", + " i wprowadź poniższy kod, aby połączyć konto i używać modeli {{provider}} w Kilo.", "provider.connect.oauth.auto.confirmationCode": "Kod potwierdzający", "provider.connect.toast.connected.title": "Połączono {{provider}}", "provider.connect.toast.connected.description": "Modele {{provider}} są teraz dostępne do użycia.", @@ -247,7 +247,7 @@ export const dict = { "dialog.directory.empty": "Nie znaleziono folderów", "dialog.server.title": "Serwery", - "dialog.server.description": "Przełącz serwer OpenCode, z którym łączy się ta aplikacja.", + "dialog.server.description": "Przełącz serwer Kilo, z którym łączy się ta aplikacja.", "dialog.server.search.placeholder": "Szukaj serwerów", "dialog.server.empty": "Brak serwerów", "dialog.server.add.title": "Dodaj serwer", @@ -367,7 +367,7 @@ export const dict = { "toast.session.listFailed.title": "Nie udało się załadować sesji dla {{project}}", "toast.update.title": "Dostępna aktualizacja", - "toast.update.description": "Nowa wersja OpenCode ({{version}}) jest teraz dostępna do instalacji.", + "toast.update.description": "Nowa wersja Kilo ({{version}}) jest teraz dostępna do instalacji.", "toast.update.action.installRestart": "Zainstaluj i zrestartuj", "toast.update.action.notYet": "Jeszcze nie", @@ -378,7 +378,7 @@ export const dict = { "error.page.action.checking": "Sprawdzanie...", "error.page.action.checkUpdates": "Sprawdź aktualizacje", "error.page.action.updateTo": "Zaktualizuj do {{version}}", - "error.page.report.prefix": "Proszę zgłosić ten błąd do zespołu OpenCode", + "error.page.report.prefix": "Proszę zgłosić ten błąd do zespołu Kilo", "error.page.report.discord": "na Discordzie", "error.page.version": "Wersja: {{version}}", @@ -397,7 +397,7 @@ export const dict = { "error.chain.modelNotFound": "Model nie znaleziony: {{provider}}/{{model}}", "error.chain.checkConfig": "Sprawdź swoją konfigurację (opencode.json) nazwy dostawców/modeli", "error.chain.mcpFailed": - 'Serwer MCP "{{name}}" nie powiódł się. Uwaga, OpenCode nie obsługuje jeszcze uwierzytelniania MCP.', + 'Serwer MCP "{{name}}" nie powiódł się. Uwaga, Kilo 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ę.', @@ -506,12 +506,12 @@ export const dict = { "sidebar.workspaces.enable": "Włącz przestrzenie robocze", "sidebar.workspaces.disable": "Wyłącz przestrzenie robocze", "sidebar.gettingStarted.title": "Pierwsze kroki", - "sidebar.gettingStarted.line1": "OpenCode zawiera darmowe modele, więc możesz zacząć od razu.", + "sidebar.gettingStarted.line1": "Kilo zawiera darmowe modele, więc możesz zacząć od razu.", "sidebar.gettingStarted.line2": "Połącz dowolnego dostawcę, aby używać modeli, w tym Claude, GPT, Gemini itp.", "sidebar.project.recentSessions": "Ostatnie sesje", "sidebar.project.viewAllSessions": "Zobacz wszystkie sesje", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Pulpit", "settings.section.server": "Serwer", "settings.tab.general": "Ogólne", @@ -523,11 +523,11 @@ export const dict = { "settings.general.section.sounds": "Efekty dźwiękowe", "settings.general.row.language.title": "Język", - "settings.general.row.language.description": "Zmień język wyświetlania dla OpenCode", + "settings.general.row.language.description": "Zmień język wyświetlania dla Kilo", "settings.general.row.appearance.title": "Wygląd", - "settings.general.row.appearance.description": "Dostosuj wygląd OpenCode na swoim urządzeniu", + "settings.general.row.appearance.description": "Dostosuj wygląd Kilo na swoim urządzeniu", "settings.general.row.theme.title": "Motyw", - "settings.general.row.theme.description": "Dostosuj motyw OpenCode.", + "settings.general.row.theme.description": "Dostosuj motyw Kilo.", "settings.general.row.font.title": "Czcionka", "settings.general.row.font.description": "Dostosuj czcionkę mono używaną w blokach kodu", @@ -535,13 +535,13 @@ export const dict = { "settings.general.row.releaseNotes.description": 'Pokazuj wyskakujące okna "Co nowego" po aktualizacjach', "settings.updates.row.startup.title": "Sprawdzaj aktualizacje przy uruchomieniu", - "settings.updates.row.startup.description": "Automatycznie sprawdzaj aktualizacje podczas uruchamiania OpenCode", + "settings.updates.row.startup.description": "Automatycznie sprawdzaj aktualizacje podczas uruchamiania Kilo", "settings.updates.row.check.title": "Sprawdź aktualizacje", "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.toast.latest.title": "Masz najnowszą wersję", - "settings.updates.toast.latest.description": "Korzystasz z najnowszej wersji OpenCode.", + "settings.updates.toast.latest.description": "Korzystasz z najnowszej wersji Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/ru.ts b/packages/app/src/i18n/ru.ts index 0728c4a34..200a6c79f 100644 --- a/packages/app/src/i18n/ru.ts +++ b/packages/app/src/i18n/ru.ts @@ -101,7 +101,7 @@ export const dict = { "dialog.model.manage": "Управление моделями", "dialog.model.manage.description": "Настройте какие модели появляются в выборе модели", - "dialog.model.unpaid.freeModels.title": "Бесплатные модели от OpenCode", + "dialog.model.unpaid.freeModels.title": "Бесплатные модели от Kilo", "dialog.model.unpaid.addMore.title": "Добавьте больше моделей от популярных провайдеров", "dialog.provider.viewAll": "Показать больше провайдеров", @@ -114,7 +114,7 @@ export const dict = { "provider.connect.status.waiting": "Ожидание авторизации...", "provider.connect.status.failed": "Ошибка авторизации: {{error}}", "provider.connect.apiKey.description": - "Введите ваш API ключ {{provider}} для подключения аккаунта и использования моделей {{provider}} в OpenCode.", + "Введите ваш API ключ {{provider}} для подключения аккаунта и использования моделей {{provider}} в Kilo.", "provider.connect.apiKey.label": "{{provider}} API ключ", "provider.connect.apiKey.placeholder": "API ключ", "provider.connect.apiKey.required": "API ключ обязателен", @@ -128,7 +128,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "Посетите ", "provider.connect.oauth.code.visit.link": "эту ссылку", "provider.connect.oauth.code.visit.suffix": - " чтобы получить код авторизации для подключения аккаунта и использования моделей {{provider}} в OpenCode.", + " чтобы получить код авторизации для подключения аккаунта и использования моделей {{provider}} в Kilo.", "provider.connect.oauth.code.label": "{{method}} код авторизации", "provider.connect.oauth.code.placeholder": "Код авторизации", "provider.connect.oauth.code.required": "Код авторизации обязателен", @@ -136,7 +136,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "Посетите ", "provider.connect.oauth.auto.visit.link": "эту ссылку", "provider.connect.oauth.auto.visit.suffix": - " и введите код ниже для подключения аккаунта и использования моделей {{provider}} в OpenCode.", + " и введите код ниже для подключения аккаунта и использования моделей {{provider}} в Kilo.", "provider.connect.oauth.auto.confirmationCode": "Код подтверждения", "provider.connect.toast.connected.title": "{{provider}} подключён", "provider.connect.toast.connected.description": "Модели {{provider}} теперь доступны.", @@ -247,7 +247,7 @@ export const dict = { "dialog.directory.empty": "Папки не найдены", "dialog.server.title": "Серверы", - "dialog.server.description": "Переключите сервер OpenCode к которому подключается приложение.", + "dialog.server.description": "Переключите сервер Kilo к которому подключается приложение.", "dialog.server.search.placeholder": "Поиск серверов", "dialog.server.empty": "Серверов пока нет", "dialog.server.add.title": "Добавить сервер", @@ -368,7 +368,7 @@ export const dict = { "toast.session.listFailed.title": "Не удалось загрузить сессии для {{project}}", "toast.update.title": "Доступно обновление", - "toast.update.description": "Новая версия OpenCode ({{version}}) доступна для установки.", + "toast.update.description": "Новая версия Kilo ({{version}}) доступна для установки.", "toast.update.action.installRestart": "Установить и перезапустить", "toast.update.action.notYet": "Пока нет", @@ -379,7 +379,7 @@ export const dict = { "error.page.action.checking": "Проверка...", "error.page.action.checkUpdates": "Проверить обновления", "error.page.action.updateTo": "Обновить до {{version}}", - "error.page.report.prefix": "Пожалуйста, сообщите об этой ошибке команде OpenCode", + "error.page.report.prefix": "Пожалуйста, сообщите об этой ошибке команде Kilo", "error.page.report.discord": "в Discord", "error.page.version": "Версия: {{version}}", @@ -398,7 +398,7 @@ export const dict = { "error.chain.modelNotFound": "Модель не найдена: {{provider}}/{{model}}", "error.chain.checkConfig": "Проверьте названия провайдера/модели в конфиге (opencode.json)", "error.chain.mcpFailed": - 'MCP сервер "{{name}}" завершился с ошибкой. Обратите внимание, что OpenCode пока не поддерживает MCP авторизацию.', + 'MCP сервер "{{name}}" завершился с ошибкой. Обратите внимание, что Kilo пока не поддерживает MCP авторизацию.', "error.chain.providerAuthFailed": "Ошибка аутентификации провайдера ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'Не удалось инициализировать провайдера "{{provider}}". Проверьте учётные данные и конфигурацию.', @@ -508,13 +508,13 @@ export const dict = { "sidebar.workspaces.enable": "Включить рабочие пространства", "sidebar.workspaces.disable": "Отключить рабочие пространства", "sidebar.gettingStarted.title": "Начало работы", - "sidebar.gettingStarted.line1": "OpenCode включает бесплатные модели, чтобы вы могли начать сразу.", + "sidebar.gettingStarted.line1": "Kilo включает бесплатные модели, чтобы вы могли начать сразу.", "sidebar.gettingStarted.line2": "Подключите любого провайдера для использования моделей, включая Claude, GPT, Gemini и др.", "sidebar.project.recentSessions": "Недавние сессии", "sidebar.project.viewAllSessions": "Посмотреть все сессии", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "Приложение", "settings.section.server": "Сервер", "settings.tab.general": "Основные", @@ -526,11 +526,11 @@ export const dict = { "settings.general.section.sounds": "Звуковые эффекты", "settings.general.row.language.title": "Язык", - "settings.general.row.language.description": "Изменить язык отображения OpenCode", + "settings.general.row.language.description": "Изменить язык отображения Kilo", "settings.general.row.appearance.title": "Внешний вид", - "settings.general.row.appearance.description": "Настройте как OpenCode выглядит на вашем устройстве", + "settings.general.row.appearance.description": "Настройте как Kilo выглядит на вашем устройстве", "settings.general.row.theme.title": "Тема", - "settings.general.row.theme.description": "Настройте оформление OpenCode.", + "settings.general.row.theme.description": "Настройте оформление Kilo.", "settings.general.row.font.title": "Шрифт", "settings.general.row.font.description": "Настройте моноширинный шрифт для блоков кода", @@ -538,13 +538,13 @@ export const dict = { "settings.general.row.releaseNotes.description": 'Показывать всплывающие окна "Что нового" после обновлений', "settings.updates.row.startup.title": "Проверять обновления при запуске", - "settings.updates.row.startup.description": "Автоматически проверять обновления при запуске OpenCode", + "settings.updates.row.startup.description": "Автоматически проверять обновления при запуске Kilo", "settings.updates.row.check.title": "Проверить обновления", "settings.updates.row.check.description": "Проверить обновления вручную и установить, если доступны", "settings.updates.action.checkNow": "Проверить сейчас", "settings.updates.action.checking": "Проверка...", "settings.updates.toast.latest.title": "У вас последняя версия", - "settings.updates.toast.latest.description": "Вы используете последнюю версию OpenCode.", + "settings.updates.toast.latest.description": "Вы используете последнюю версию Kilo.", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", "font.option.firaCode": "Fira Code", diff --git a/packages/app/src/i18n/th.ts b/packages/app/src/i18n/th.ts index 9ccb61ac7..c8c86f9ed 100644 --- a/packages/app/src/i18n/th.ts +++ b/packages/app/src/i18n/th.ts @@ -105,7 +105,7 @@ export const dict = { "dialog.model.manage": "จัดการโมเดล", "dialog.model.manage.description": "ปรับแต่งโมเดลที่จะปรากฏในตัวเลือกโมเดล", - "dialog.model.unpaid.freeModels.title": "โมเดลฟรีที่จัดหาให้โดย OpenCode", + "dialog.model.unpaid.freeModels.title": "โมเดลฟรีที่จัดหาให้โดย Kilo", "dialog.model.unpaid.addMore.title": "เพิ่มโมเดลเพิ่มเติมจากผู้ให้บริการยอดนิยม", "dialog.provider.viewAll": "แสดงผู้ให้บริการเพิ่มเติม", @@ -118,7 +118,7 @@ export const dict = { "provider.connect.status.waiting": "รอการอนุญาต...", "provider.connect.status.failed": "การอนุญาตล้มเหลว: {{error}}", "provider.connect.apiKey.description": - "ป้อนคีย์ API ของ {{provider}} เพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน OpenCode", + "ป้อนคีย์ API ของ {{provider}} เพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน Kilo", "provider.connect.apiKey.label": "คีย์ API ของ {{provider}}", "provider.connect.apiKey.placeholder": "คีย์ API", "provider.connect.apiKey.required": "ต้องใช้คีย์ API", @@ -132,7 +132,7 @@ export const dict = { "provider.connect.oauth.code.visit.prefix": "เยี่ยมชม ", "provider.connect.oauth.code.visit.link": "ลิงก์นี้", "provider.connect.oauth.code.visit.suffix": - " เพื่อรวบรวมรหัสการอนุญาตของคุณเพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน OpenCode", + " เพื่อรวบรวมรหัสการอนุญาตของคุณเพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน Kilo", "provider.connect.oauth.code.label": "รหัสการอนุญาต {{method}}", "provider.connect.oauth.code.placeholder": "รหัสการอนุญาต", "provider.connect.oauth.code.required": "ต้องใช้รหัสการอนุญาต", @@ -140,7 +140,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "เยี่ยมชม ", "provider.connect.oauth.auto.visit.link": "ลิงก์นี้", "provider.connect.oauth.auto.visit.suffix": - " และป้อนรหัสด้านล่างเพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน OpenCode", + " และป้อนรหัสด้านล่างเพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน Kilo", "provider.connect.oauth.auto.confirmationCode": "รหัสยืนยัน", "provider.connect.toast.connected.title": "{{provider}} ที่เชื่อมต่อแล้ว", "provider.connect.toast.connected.description": "โมเดล {{provider}} พร้อมใช้งานแล้ว", @@ -252,7 +252,7 @@ export const dict = { "dialog.directory.empty": "ไม่พบโฟลเดอร์", "dialog.server.title": "เซิร์ฟเวอร์", - "dialog.server.description": "สลับเซิร์ฟเวอร์ OpenCode ที่แอปนี้เชื่อมต่อด้วย", + "dialog.server.description": "สลับเซิร์ฟเวอร์ Kilo ที่แอปนี้เชื่อมต่อด้วย", "dialog.server.search.placeholder": "ค้นหาเซิร์ฟเวอร์", "dialog.server.empty": "ยังไม่มีเซิร์ฟเวอร์", "dialog.server.add.title": "เพิ่มเซิร์ฟเวอร์", @@ -372,7 +372,7 @@ export const dict = { "toast.session.listFailed.title": "ไม่สามารถโหลดเซสชันสำหรับ {{project}}", "toast.update.title": "มีการอัปเดต", - "toast.update.description": "เวอร์ชันใหม่ของ OpenCode ({{version}}) พร้อมใช้งานสำหรับติดตั้ง", + "toast.update.description": "เวอร์ชันใหม่ของ Kilo ({{version}}) พร้อมใช้งานสำหรับติดตั้ง", "toast.update.action.installRestart": "ติดตั้งและรีสตาร์ท", "toast.update.action.notYet": "ยังไม่", @@ -383,7 +383,7 @@ export const dict = { "error.page.action.checking": "กำลังตรวจสอบ...", "error.page.action.checkUpdates": "ตรวจสอบการอัปเดต", "error.page.action.updateTo": "อัปเดตเป็น {{version}}", - "error.page.report.prefix": "โปรดรายงานข้อผิดพลาดนี้ให้ทีม OpenCode", + "error.page.report.prefix": "โปรดรายงานข้อผิดพลาดนี้ให้ทีม Kilo", "error.page.report.discord": "บน Discord", "error.page.version": "เวอร์ชัน: {{version}}", @@ -400,7 +400,7 @@ export const dict = { "error.chain.didYouMean": "คุณหมายถึง: {{suggestions}}", "error.chain.modelNotFound": "ไม่พบโมเดล: {{provider}}/{{model}}", "error.chain.checkConfig": "ตรวจสอบการกำหนดค่าของคุณ (opencode.json) ชื่อผู้ให้บริการ/โมเดล", - "error.chain.mcpFailed": 'เซิร์ฟเวอร์ MCP "{{name}}" ล้มเหลว โปรดทราบว่า OpenCode ยังไม่รองรับการตรวจสอบสิทธิ์ MCP', + "error.chain.mcpFailed": 'เซิร์ฟเวอร์ MCP "{{name}}" ล้มเหลว โปรดทราบว่า Kilo ยังไม่รองรับการตรวจสอบสิทธิ์ MCP', "error.chain.providerAuthFailed": "การตรวจสอบสิทธิ์ผู้ให้บริการล้มเหลว ({{provider}}): {{message}}", "error.chain.providerInitFailed": 'ไม่สามารถเริ่มต้นผู้ให้บริการ "{{provider}}" ตรวจสอบข้อมูลรับรองและการกำหนดค่า', "error.chain.configJsonInvalid": "ไฟล์กำหนดค่าที่ {{path}} ไม่ใช่ JSON(C) ที่ถูกต้อง", @@ -507,12 +507,12 @@ export const dict = { "sidebar.workspaces.enable": "เปิดใช้งานพื้นที่ทำงาน", "sidebar.workspaces.disable": "ปิดใช้งานพื้นที่ทำงาน", "sidebar.gettingStarted.title": "เริ่มต้นใช้งาน", - "sidebar.gettingStarted.line1": "OpenCode รวมถึงโมเดลฟรีเพื่อให้คุณเริ่มต้นได้ทันที", + "sidebar.gettingStarted.line1": "Kilo รวมถึงโมเดลฟรีเพื่อให้คุณเริ่มต้นได้ทันที", "sidebar.gettingStarted.line2": "เชื่อมต่อผู้ให้บริการใด ๆ เพื่อใช้โมเดล รวมถึง Claude, GPT, Gemini ฯลฯ", "sidebar.project.recentSessions": "เซสชันล่าสุด", "sidebar.project.viewAllSessions": "ดูเซสชันทั้งหมด", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "เดสก์ท็อป", "settings.section.server": "เซิร์ฟเวอร์", @@ -525,11 +525,11 @@ export const dict = { "settings.general.section.sounds": "เสียงเอฟเฟกต์", "settings.general.row.language.title": "ภาษา", - "settings.general.row.language.description": "เปลี่ยนภาษาที่แสดงสำหรับ OpenCode", + "settings.general.row.language.description": "เปลี่ยนภาษาที่แสดงสำหรับ Kilo", "settings.general.row.appearance.title": "รูปลักษณ์", - "settings.general.row.appearance.description": "ปรับแต่งวิธีการที่ OpenCode มีลักษณะบนอุปกรณ์ของคุณ", + "settings.general.row.appearance.description": "ปรับแต่งวิธีการที่ Kilo มีลักษณะบนอุปกรณ์ของคุณ", "settings.general.row.theme.title": "ธีม", - "settings.general.row.theme.description": "ปรับแต่งวิธีการที่ OpenCode มีธีม", + "settings.general.row.theme.description": "ปรับแต่งวิธีการที่ Kilo มีธีม", "settings.general.row.font.title": "ฟอนต์", "settings.general.row.font.description": "ปรับแต่งฟอนต์โมโนที่ใช้ในบล็อกโค้ด", diff --git a/packages/app/src/i18n/zh.ts b/packages/app/src/i18n/zh.ts index 2266c109b..fb8a65378 100644 --- a/packages/app/src/i18n/zh.ts +++ b/packages/app/src/i18n/zh.ts @@ -109,7 +109,7 @@ export const dict = { "dialog.model.manage": "管理模型", "dialog.model.manage.description": "自定义模型选择器中显示的模型。", - "dialog.model.unpaid.freeModels.title": "OpenCode 提供的免费模型", + "dialog.model.unpaid.freeModels.title": "Kilo 提供的免费模型", "dialog.model.unpaid.addMore.title": "从热门提供商添加更多模型", "dialog.provider.viewAll": "查看更多提供商", @@ -122,7 +122,7 @@ export const dict = { "provider.connect.status.waiting": "等待授权...", "provider.connect.status.failed": "授权失败:{{error}}", "provider.connect.apiKey.description": - "输入你的 {{provider}} API 密钥以连接帐户,并在 OpenCode 中使用 {{provider}} 模型。", + "输入你的 {{provider}} API 密钥以连接帐户,并在 Kilo 中使用 {{provider}} 模型。", "provider.connect.apiKey.label": "{{provider}} API 密钥", "provider.connect.apiKey.placeholder": "API 密钥", "provider.connect.apiKey.required": "API 密钥为必填项", @@ -133,14 +133,14 @@ export const dict = { "provider.connect.opencodeZen.visit.suffix": " 获取你的 API 密钥。", "provider.connect.oauth.code.visit.prefix": "访问 ", "provider.connect.oauth.code.visit.link": "此链接", - "provider.connect.oauth.code.visit.suffix": " 获取授权码,以连接你的帐户并在 OpenCode 中使用 {{provider}} 模型。", + "provider.connect.oauth.code.visit.suffix": " 获取授权码,以连接你的帐户并在 Kilo 中使用 {{provider}} 模型。", "provider.connect.oauth.code.label": "{{method}} 授权码", "provider.connect.oauth.code.placeholder": "授权码", "provider.connect.oauth.code.required": "授权码为必填项", "provider.connect.oauth.code.invalid": "授权码无效", "provider.connect.oauth.auto.visit.prefix": "访问 ", "provider.connect.oauth.auto.visit.link": "此链接", - "provider.connect.oauth.auto.visit.suffix": " 并输入以下代码,以连接你的帐户并在 OpenCode 中使用 {{provider}} 模型。", + "provider.connect.oauth.auto.visit.suffix": " 并输入以下代码,以连接你的帐户并在 Kilo 中使用 {{provider}} 模型。", "provider.connect.oauth.auto.confirmationCode": "确认码", "provider.connect.toast.connected.title": "{{provider}} 已连接", "provider.connect.toast.connected.description": "现在可以使用 {{provider}} 模型了。", @@ -251,7 +251,7 @@ export const dict = { "dialog.directory.empty": "未找到文件夹", "dialog.server.title": "服务器", - "dialog.server.description": "切换此应用连接的 OpenCode 服务器。", + "dialog.server.description": "切换此应用连接的 Kilo 服务器。", "dialog.server.search.placeholder": "搜索服务器", "dialog.server.empty": "暂无服务器", "dialog.server.add.title": "添加服务器", @@ -369,7 +369,7 @@ export const dict = { "toast.session.listFailed.title": "无法加载 {{project}} 的会话", "toast.update.title": "有可用更新", - "toast.update.description": "OpenCode 有新版本 ({{version}}) 可安装。", + "toast.update.description": "Kilo 有新版本 ({{version}}) 可安装。", "toast.update.action.installRestart": "安装并重启", "toast.update.action.notYet": "稍后", @@ -380,7 +380,7 @@ export const dict = { "error.page.action.checking": "检查中...", "error.page.action.checkUpdates": "检查更新", "error.page.action.updateTo": "更新到 {{version}}", - "error.page.report.prefix": "请将此错误报告给 OpenCode 团队", + "error.page.report.prefix": "请将此错误报告给 Kilo 团队", "error.page.report.discord": "在 Discord 上", "error.page.version": "版本:{{version}}", @@ -397,7 +397,7 @@ export const dict = { "error.chain.didYouMean": "你是不是想输入:{{suggestions}}", "error.chain.modelNotFound": "未找到模型:{{provider}}/{{model}}", "error.chain.checkConfig": "请检查你的配置 (opencode.json) 中的 provider/model 名称", - "error.chain.mcpFailed": 'MCP 服务器 "{{name}}" 启动失败。注意: OpenCode 暂不支持 MCP 认证。', + "error.chain.mcpFailed": 'MCP 服务器 "{{name}}" 启动失败。注意: Kilo 暂不支持 MCP 认证。', "error.chain.providerAuthFailed": "提供商认证失败({{provider}}):{{message}}", "error.chain.providerInitFailed": '无法初始化提供商 "{{provider}}"。请检查凭据和配置。', "error.chain.configJsonInvalid": "配置文件 {{path}} 不是有效的 JSON(C)", @@ -502,12 +502,12 @@ export const dict = { "sidebar.workspaces.enable": "启用工作区", "sidebar.workspaces.disable": "禁用工作区", "sidebar.gettingStarted.title": "入门", - "sidebar.gettingStarted.line1": "OpenCode 提供免费模型,你可以立即开始使用。", + "sidebar.gettingStarted.line1": "Kilo 提供免费模型,你可以立即开始使用。", "sidebar.gettingStarted.line2": "连接任意提供商即可使用更多模型,如 Claude、GPT、Gemini 等。", "sidebar.project.recentSessions": "最近会话", "sidebar.project.viewAllSessions": "查看全部会话", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "桌面", "settings.section.server": "服务器", "settings.tab.general": "通用", @@ -519,24 +519,24 @@ export const dict = { "settings.general.section.sounds": "音效", "settings.general.row.language.title": "语言", - "settings.general.row.language.description": "更改 OpenCode 的显示语言", + "settings.general.row.language.description": "更改 Kilo 的显示语言", "settings.general.row.appearance.title": "外观", - "settings.general.row.appearance.description": "自定义 OpenCode 在你的设备上的外观", + "settings.general.row.appearance.description": "自定义 Kilo 在你的设备上的外观", "settings.general.row.theme.title": "主题", - "settings.general.row.theme.description": "自定义 OpenCode 的主题。", + "settings.general.row.theme.description": "自定义 Kilo 的主题。", "settings.general.row.font.title": "字体", "settings.general.row.font.description": "自定义代码块使用的等宽字体", "settings.general.row.releaseNotes.title": "发行说明", "settings.general.row.releaseNotes.description": "更新后显示“新功能”弹窗", "settings.updates.row.startup.title": "启动时检查更新", - "settings.updates.row.startup.description": "在 OpenCode 启动时自动检查更新", + "settings.updates.row.startup.description": "在 Kilo 启动时自动检查更新", "settings.updates.row.check.title": "检查更新", "settings.updates.row.check.description": "手动检查更新并在有更新时安装", "settings.updates.action.checkNow": "立即检查", "settings.updates.action.checking": "正在检查...", "settings.updates.toast.latest.title": "已是最新版本", - "settings.updates.toast.latest.description": "你正在使用最新版本的 OpenCode。", + "settings.updates.toast.latest.description": "你正在使用最新版本的 Kilo。", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", diff --git a/packages/app/src/i18n/zht.ts b/packages/app/src/i18n/zht.ts index 30837e56f..b4cb07d0b 100644 --- a/packages/app/src/i18n/zht.ts +++ b/packages/app/src/i18n/zht.ts @@ -105,7 +105,7 @@ export const dict = { "dialog.model.manage": "管理模型", "dialog.model.manage.description": "自訂模型選擇器中顯示的模型。", - "dialog.model.unpaid.freeModels.title": "OpenCode 提供的免費模型", + "dialog.model.unpaid.freeModels.title": "Kilo 提供的免費模型", "dialog.model.unpaid.addMore.title": "從熱門提供者新增更多模型", "dialog.provider.viewAll": "查看更多提供者", @@ -118,7 +118,7 @@ export const dict = { "provider.connect.status.waiting": "等待授權...", "provider.connect.status.failed": "授權失敗: {{error}}", "provider.connect.apiKey.description": - "輸入你的 {{provider}} API 金鑰以連線帳戶,並在 OpenCode 中使用 {{provider}} 模型。", + "輸入你的 {{provider}} API 金鑰以連線帳戶,並在 Kilo 中使用 {{provider}} 模型。", "provider.connect.apiKey.label": "{{provider}} API 金鑰", "provider.connect.apiKey.placeholder": "API 金鑰", "provider.connect.apiKey.required": "API 金鑰為必填", @@ -129,7 +129,7 @@ export const dict = { "provider.connect.opencodeZen.visit.suffix": " 取得你的 API 金鑰。", "provider.connect.oauth.code.visit.prefix": "造訪 ", "provider.connect.oauth.code.visit.link": "此連結", - "provider.connect.oauth.code.visit.suffix": " 取得授權碼,以連線你的帳戶並在 OpenCode 中使用 {{provider}} 模型。", + "provider.connect.oauth.code.visit.suffix": " 取得授權碼,以連線你的帳戶並在 Kilo 中使用 {{provider}} 模型。", "provider.connect.oauth.code.label": "{{method}} 授權碼", "provider.connect.oauth.code.placeholder": "授權碼", "provider.connect.oauth.code.required": "授權碼為必填", @@ -137,7 +137,7 @@ export const dict = { "provider.connect.oauth.auto.visit.prefix": "造訪 ", "provider.connect.oauth.auto.visit.link": "此連結", "provider.connect.oauth.auto.visit.suffix": - " 並輸入以下程式碼,以連線你的帳戶並在 OpenCode 中使用 {{provider}} 模型。", + " 並輸入以下程式碼,以連線你的帳戶並在 Kilo 中使用 {{provider}} 模型。", "provider.connect.oauth.auto.confirmationCode": "確認碼", "provider.connect.toast.connected.title": "{{provider}} 已連線", "provider.connect.toast.connected.description": "現在可以使用 {{provider}} 模型了。", @@ -248,7 +248,7 @@ export const dict = { "dialog.directory.empty": "找不到資料夾", "dialog.server.title": "伺服器", - "dialog.server.description": "切換此應用程式連線的 OpenCode 伺服器。", + "dialog.server.description": "切換此應用程式連線的 Kilo 伺服器。", "dialog.server.search.placeholder": "搜尋伺服器", "dialog.server.empty": "暫無伺服器", "dialog.server.add.title": "新增伺服器", @@ -366,7 +366,7 @@ export const dict = { "toast.session.listFailed.title": "無法載入 {{project}} 的工作階段", "toast.update.title": "有可用更新", - "toast.update.description": "OpenCode 有新版本 ({{version}}) 可安裝。", + "toast.update.description": "Kilo 有新版本 ({{version}}) 可安裝。", "toast.update.action.installRestart": "安裝並重新啟動", "toast.update.action.notYet": "稍後", @@ -377,7 +377,7 @@ export const dict = { "error.page.action.checking": "檢查中...", "error.page.action.checkUpdates": "檢查更新", "error.page.action.updateTo": "更新到 {{version}}", - "error.page.report.prefix": "請將此錯誤回報給 OpenCode 團隊", + "error.page.report.prefix": "請將此錯誤回報給 Kilo 團隊", "error.page.report.discord": "在 Discord 上", "error.page.version": "版本: {{version}}", @@ -394,7 +394,7 @@ export const dict = { "error.chain.didYouMean": "你是不是想輸入: {{suggestions}}", "error.chain.modelNotFound": "找不到模型: {{provider}}/{{model}}", "error.chain.checkConfig": "請檢查你的設定 (opencode.json) 中的 provider/model 名稱", - "error.chain.mcpFailed": 'MCP 伺服器 "{{name}}" 啟動失敗。注意: OpenCode 暫不支援 MCP 認證。', + "error.chain.mcpFailed": 'MCP 伺服器 "{{name}}" 啟動失敗。注意: Kilo 暫不支援 MCP 認證。', "error.chain.providerAuthFailed": "提供者認證失敗 ({{provider}}): {{message}}", "error.chain.providerInitFailed": '無法初始化提供者 "{{provider}}"。請檢查憑證和設定。', "error.chain.configJsonInvalid": "設定檔 {{path}} 不是有效的 JSON(C)", @@ -499,12 +499,12 @@ export const dict = { "sidebar.workspaces.enable": "啟用工作區", "sidebar.workspaces.disable": "停用工作區", "sidebar.gettingStarted.title": "開始使用", - "sidebar.gettingStarted.line1": "OpenCode 提供免費模型,你可以立即開始使用。", + "sidebar.gettingStarted.line1": "Kilo 提供免費模型,你可以立即開始使用。", "sidebar.gettingStarted.line2": "連線任意提供者即可使用更多模型,如 Claude、GPT、Gemini 等。", "sidebar.project.recentSessions": "最近工作階段", "sidebar.project.viewAllSessions": "查看全部工作階段", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "Kilo Desktop", "settings.section.desktop": "桌面", "settings.section.server": "伺服器", "settings.tab.general": "一般", @@ -516,11 +516,11 @@ export const dict = { "settings.general.section.sounds": "音效", "settings.general.row.language.title": "語言", - "settings.general.row.language.description": "變更 OpenCode 的顯示語言", + "settings.general.row.language.description": "變更 Kilo 的顯示語言", "settings.general.row.appearance.title": "外觀", - "settings.general.row.appearance.description": "自訂 OpenCode 在你的裝置上的外觀", + "settings.general.row.appearance.description": "自訂 Kilo 在你的裝置上的外觀", "settings.general.row.theme.title": "主題", - "settings.general.row.theme.description": "自訂 OpenCode 的主題。", + "settings.general.row.theme.description": "自訂 Kilo 的主題。", "settings.general.row.font.title": "字型", "settings.general.row.font.description": "自訂程式碼區塊使用的等寬字型", @@ -528,13 +528,13 @@ export const dict = { "settings.general.row.releaseNotes.description": "更新後顯示「新功能」彈出視窗", "settings.updates.row.startup.title": "啟動時檢查更新", - "settings.updates.row.startup.description": "在 OpenCode 啟動時自動檢查更新", + "settings.updates.row.startup.description": "在 Kilo 啟動時自動檢查更新", "settings.updates.row.check.title": "檢查更新", "settings.updates.row.check.description": "手動檢查更新並在有更新時安裝", "settings.updates.action.checkNow": "立即檢查", "settings.updates.action.checking": "檢查中...", "settings.updates.toast.latest.title": "已是最新版本", - "settings.updates.toast.latest.description": "你正在使用最新版本的 OpenCode。", + "settings.updates.toast.latest.description": "你正在使用最新版本的 Kilo。", "font.option.ibmPlexMono": "IBM Plex Mono", "font.option.cascadiaCode": "Cascadia Code", diff --git a/packages/app/src/pages/directory-layout.tsx b/packages/app/src/pages/directory-layout.tsx index 037b08c72..e9591c785 100644 --- a/packages/app/src/pages/directory-layout.tsx +++ b/packages/app/src/pages/directory-layout.tsx @@ -6,7 +6,7 @@ import { LocalProvider } from "@/context/local" import { DataProvider } from "@opencode-ai/ui/context" import { iife } from "@opencode-ai/util/iife" -import type { QuestionAnswer } from "@opencode-ai/sdk/v2" +import type { QuestionAnswer } from "@kilocode/sdk/v2" import { decode64 } from "@/utils/base64" import { showToast } from "@opencode-ai/ui/toast" import { useLanguage } from "@/context/language" diff --git a/packages/app/src/pages/error.tsx b/packages/app/src/pages/error.tsx index 6d6faf6fa..c1d3c4cb5 100644 --- a/packages/app/src/pages/error.tsx +++ b/packages/app/src/pages/error.tsx @@ -272,7 +272,7 @@ export const ErrorPage: Component = (props) => {