From 4089cf0a10a8db87447671a8d20ef391b87b7730 Mon Sep 17 00:00:00 2001 From: minhn4 Date: Sat, 8 Aug 2026 18:41:49 +0700 Subject: [PATCH 1/2] refactor(desktop): rebrand user-facing text and identifiers to codev Every user-visible "OpenCode" the desktop app renders becomes "CoDev Code": crash and unresponsive dialogs, the window title, the updater and CLI-installed i18n strings (en + es, with the CLI-command hint 'opencode' -> 'codev'), the unpackaged app-name fallback, the AppStream metainfo Linux software centres show, the OS deep-link handler name, the README, and package.json identity (upstream homepage/author dropped, as packages/opencode and packages/app carry neither). Codebase identifiers are renamed Opencode -> Codev across the WSL CLI-check code and the deep-link surfaces it shares with packages/app, together with the internal wire values whose producer and consumer both ship from this repo: the virtual:opencode-server module id, the vite plugin names, the wsl-servers-install-opencode IPC channel, the install-opencode job kind, the __OPENCODE__ deep-link bridge global, the opencode:deep-link renderer event, the onboarding temp dir, and the wsl.onboarding.installOpencode* i18n keys. Also fixes a real bug: the debug-log export read server logs from /opencode/log, but the fork CLI writes to /codev/log (core/global.ts app = "codev"), so the export silently collected none. Deliberately preserved: @opencode-ai/* package ids, the ai.opencode.desktop appIds and opencode:// scheme, the publish targets and legacy launcher, the persisted on-disk store names, the basic-auth username (must match the server default), and the ../opencode/dist build paths. Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 12 +++ DIVERGENCES.md | 6 +- packages/app/src/app.tsx | 2 +- packages/app/src/i18n/en.ts | 4 +- packages/app/src/i18n/es.ts | 4 +- packages/app/src/index.ts | 2 +- packages/app/src/pages/layout/deep-links.ts | 8 +- packages/app/src/pages/layout/helpers.test.ts | 4 +- packages/app/src/wsl/dialog-add-server.tsx | 4 +- packages/app/src/wsl/settings-model.test.ts | 18 ++-- packages/app/src/wsl/settings-model.ts | 36 ++++---- packages/app/src/wsl/settings.tsx | 10 +-- packages/app/src/wsl/types.ts | 8 +- packages/desktop/README.md | 4 +- packages/desktop/electron-builder.config.ts | 4 +- packages/desktop/electron.vite.config.ts | 8 +- packages/desktop/package.json | 5 -- packages/desktop/scripts/copy-metainfo.ts | 21 ++--- packages/desktop/src/main/env.d.ts | 2 +- packages/desktop/src/main/index.ts | 4 +- .../desktop/src/main/install-state.test.ts | 2 +- packages/desktop/src/main/logging.ts | 4 +- packages/desktop/src/main/server.ts | 2 +- packages/desktop/src/main/sidecar.ts | 2 +- packages/desktop/src/main/windows.ts | 6 +- packages/desktop/src/main/wsl/ipc.ts | 8 +- packages/desktop/src/main/wsl/policy.ts | 10 +-- packages/desktop/src/main/wsl/runtime.ts | 4 +- packages/desktop/src/main/wsl/servers.test.ts | 64 +++++++-------- packages/desktop/src/main/wsl/servers.ts | 82 +++++++++---------- packages/desktop/src/main/wsl/sidecar.ts | 8 +- packages/desktop/src/main/wsl/startup.ts | 4 +- packages/desktop/src/preload/index.ts | 2 +- packages/desktop/src/preload/types.ts | 2 +- packages/desktop/src/renderer/env.d.ts | 2 +- packages/desktop/src/renderer/i18n/en.ts | 6 +- packages/desktop/src/renderer/i18n/es.ts | 6 +- packages/desktop/src/renderer/index.html | 2 +- packages/desktop/src/renderer/index.tsx | 8 +- .../src/renderer/wsl/connections.test.ts | 2 +- 40 files changed, 197 insertions(+), 195 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21e2397190..f308ee7011 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,18 @@ file is the human-readable summary of what changed and why. shadow) so the icon sits correctly next to native apps; all three channels ship the same mark for now. +- **The desktop app says CoDev Code, not opencode** — every user-visible string + the app still rendered as "OpenCode" is rebranded: the window title, the crash + and unresponsive dialogs, the updater and CLI-installed messages (English and + Spanish, and the CLI-command hint now names `codev`), the unpackaged app name, + the Linux software-centre listing, and the deep-link handler name the OS shows. + Internally, the WSL CLI-management code and the desktop↔web wire values were + renamed to codev as well. + +- **Debug-log export actually collects the CLI's logs** — "Export logs" read from + a stale `opencode` directory while the CLI writes its logs under `codev`, so the + server logs were silently missing from the exported archive. Fixed. + ### Desktop / Web UI - **No wordmark on the new-session screen, and the composer is centred** — the diff --git a/DIVERGENCES.md b/DIVERGENCES.md index a5b4695817..46c59b9f95 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -149,6 +149,7 @@ from the squash message first, or use a plain merge. | `packages/app/src/assets/help/` (introducing-tabs.mp4, placeholder.png, home.png, tabs.png — whole directory) | Deleted | The 13 MB promo video's and the v1.18 home/tabs screenshots' only consumer was the removed `TabsInfoPopup` (row above) and they bloat every clone; `placeholder.png` is referenced by nothing. | Keep deleted (`git rm` the upstream side of modify/delete conflicts); delete new upstream assets under this directory whose only consumer is the removed popup. | | `packages/app/src/desktop-menu.ts`, `packages/app/src/components/windows-app-menu.tsx` | App-menu label "OpenCode" → "CoDev Code"; "OpenCode Documentation" item → "CoDev Code Documentation" (href `opencode.ai/docs` stays — real URL); trigger `aria-label` "OpenCode menu" → "CoDev Code menu" (×2) | Visible menu branding, incl. screen-reader labels. | Keep our labels; take upstream's surrounding menu changes. Rebrand any new "OpenCode" label/aria-label. | | Hardcoded product-string rebrand in TUI + web app: `packages/tui/src/app.tsx`, `packages/tui/src/routes/session/permission.tsx`, `packages/tui/src/attention.ts` (+ `packages/opencode/test/cli/cmd/tui/attention.test.ts`), `packages/app/src/wsl/settings-model.ts` (+ `.test.ts`), `packages/ui/src/components/favicon.tsx` | User-visible "OpenCode" strings outside the i18n dicts → fork brand: update-complete toast "Successfully updated to OpenCode v…" → "CoDev Code"; permission dialog "…until OpenCode is restarted" → "CoDev Code" (the sibling patterns line was already rebranded); OS-notification fallback title `opencode` → `codev` and built-in sound-pack display name "OpenCode Default" → "CoDev Code Default" (pack id `opencode.default` stays — internal identifier; the three default-title expectations in `packages/opencode/test/cli/cmd/tui/attention.test.ts` follow, while its explicit-title pass-through fixture stays `opencode`); WSL settings actions "Install/Update OpenCode" → "…CoDev Code" (+ test expectations/titles; fixture paths `/usr/local/bin/opencode` stay); PWA `apple-mobile-web-app-title` "OpenCode" → "CoDev Code" (matches the rebranded `site.webmanifest`, favicon-assets row) | These render in surfaces the fork ships (TUI + embedded web UI); the i18n-dict strings remain a known gap (UI branding bullet below). | Keep our strings; take upstream's surrounding changes. Rebrand any new hardcoded user-visible "OpenCode" string in these surfaces; leave identifiers, URLs, and fixture paths. | +| Desktop app text + identifier rebrand: `packages/desktop/**` (README, `package.json`, `src/renderer/index.html`, `src/renderer/i18n/{en,es}.ts`, `src/main/{index,windows,server,logging}.ts`, `src/main/wsl/{sidecar,startup,servers,servers.test}.ts`, `src/main/install-state.test.ts`, `scripts/copy-metainfo.ts`, `electron-builder.config.ts`) plus the WSL/deep-link surfaces it shares with `packages/app` (`src/wsl/{types,settings-model,settings-model.test,settings,dialog-add-server}.ts(x)`, `src/i18n/{en,es}.ts`, `src/pages/layout/{deep-links,helpers.test}.ts`, `src/app.tsx`, `src/index.ts`) and `packages/desktop/src/{preload,renderer}` | Every user-visible "OpenCode" the desktop app renders → "CoDev Code": crash dialogs, window ``, updater/CLI-installed i18n (en+es, with the CLI-command hint `'opencode'`→`'codev'`), the unpackaged app-name fallback `"OpenCode Dev"`, the AppStream metainfo (product name, description, `developer` → `<name>CoDev</name>` with the upstream `id="ly.anoma"` dropped, the three URLs repointed to the fork repo, upstream's lander screenshot removed), the OS deep-link handler display name, README, and `package.json` (upstream `homepage`/`author` removed — `packages/opencode` and `packages/app` declare neither). Codebase identifiers renamed `Opencode`→`Codev`/`opencode`→`codev` (`WslOpencodeCheck`, `resolveWslOpencode`, `installWslOpencode`, `expectOpencodeVersion`, `releaseOpencodeResolve`, `checkOpencode`/`refreshOpencodeCheck*`/`setOpencodeCheck`, `opencodeChecks`, `wslOpencodeAction`, …) together with the internal wire values whose producer and consumer both ship here (`virtual:opencode-server`, the `opencode:{node-pty,virtual-server,copy-server}` vite plugin names, the `wsl-servers-install-opencode` IPC channel, the `install-opencode` job kind, the `__OPENCODE__` deep-link bridge global, the `opencode:deep-link` renderer event, the `opencode-onboarding-` temp dir, the `wsl.onboarding.installOpencode*` i18n keys), and the server-log collector path `<xdgData>/opencode/log` → `/codev/log` (a real bug fix — the fork CLI writes to `<xdgData>/codev/log`, `packages/core/src/global.ts` `app = "codev"`, so debug-log export was silently collecting nothing). Two stale product-named locals renamed to what they hold (`opencode`→`binary` in wsl/sidecar.ts, `opencode`→`checked` in the servers test). | The fork ships the desktop app, so every surface it shows and every identifier a maintainer reads should say codev. | Keep our strings + identifiers; take upstream's surrounding changes. PRESERVED deliberately, do not rename: `@opencode-ai/*` package ids, the `ai.opencode.desktop*` appIds and `opencode://` scheme + `schemes:["opencode"]` (identity plumbing), the `owner:"anomalyco"`/`repo:"opencode"`/`packageName:"opencode"` publish targets and `opencode-desktop.desktop` legacy launcher, the persisted on-disk store names (`opencode.settings`, `opencode.{draft,workspace,global,window,updater}.*`, the `opencode` data dir in install-state), the basic-auth username `"opencode"` (must match the server default in `packages/server/src/auth.ts`), and the `../opencode/dist` build paths. | | Browser-opened docs-site links: `packages/tui/src/app.tsx`, `packages/app/src/desktop-menu.ts`, `packages/app/src/components/{settings-general,settings-v2/general,dialog-custom-provider}.tsx`, `packages/app/src/pages/{home,layout,error}.tsx`, `packages/app/src/i18n/{en,es}.ts`, `packages/opencode/src/cli/cmd/{providers,github.handler}.ts` | Links the app opens in the user's browser repointed from `opencode.ai` to the fork's hosted docs. Each one derives its base from `DOCS_URL` (`packages/codev-brand/src/index.ts`, base64-encoded) rather than hardcoding the host: the site is locale-routed and the Code docs live under `/code`, and no URL takes a trailing slash (the site 308-redirects `…/themes/` to `…/themes`). Sites: TUI "Open docs" command and app Documentation menu item → docs root; settings theme "Learn more" (v1 + v2) → `…/code/themes`; custom-provider dialog link → `…/code/providers#custom-provider`; CLI Cloudflare-gateway hint → `…/code/providers#cloudflare-ai-gateway`; GitHub-agent hint → `…/code/github`; home/layout sidebar Help buttons `opencode.ai/desktop-feedback` → docs root. The error page's report button `opencode.ai/desktop-feedback` → `github.com/quickbeard/codev-code/issues` instead (it's a report action, not a docs lookup), icon `discord` → `github`, and the en/es `error.page.report.*` strings → "…CoDev Code team" / "on GitHub". Help submenu (rendered by the shipped web UI's Windows app menu too): "Support Forum" (upstream Discord invite) deleted — the fork has no forum; "Share Feedback"/"Report a Bug" → `github.com/quickbeard/codev-code/issues/new?template=feature-request.yml`/`bug-report.yml` (the fork's template names are hyphenated, unlike upstream's underscored ones). | Fork users should land on the fork's docs and report issues to the fork, not upstream's site/Discord. NOT repointed: Zen/Go product URLs (`opencode.ai/zen`, `/go`, `/auth`), `$schema`/theme-schema ids, API/share/changelog endpoints, MCP OAuth `client_uri`, prompt-file mentions. Also NOT on this base: the ripgrep mirror (`/codev/docs/code/downloads/…`, see its own row) — it is a `public/` static asset, not locale-routed content, and 404s under `/en/docs/code`. | Keep our URLs, icon, and strings; take upstream's surrounding changes. Repoint any new browser-opened `opencode.ai` docs/help link to the fork docs base; leave the NOT-repointed list. | | `packages/desktop/src/main/index.ts`, `packages/desktop/src/main/windows.ts` | APP_NAMES + window title → "CoDev Code" (Dev/Beta variants too) | Desktop app display name. | Keep our names. | | `packages/desktop/electron-builder.config.ts` | `productName` ×3 → "CoDev Code…"; artifactName → `codev-code-desktop-…`; protocol display name | Installer/product branding. appId (`ai.opencode.desktop`) and the `opencode://` deep-link scheme stay upstream — identity plumbing wired into main/index.ts and app deep-links; do not rename casually. | Keep our names; take upstream's other config. | @@ -197,9 +198,8 @@ from the squash message first, or use a plain merge. assets, and the hardcoded TUI/web-app product strings are rebranded (see table). Still upstream-branded, deliberately: in-app i18n strings mentioning "OpenCode" in the `en`/`es` locale files (see the locale-trim rows above; revisit with a runtime display-name shim if - it matters), desktop-only hardcoded strings (`packages/desktop` renderer `<title>` and the - crash dialogs in `main/windows.ts` — the fork doesn't ship the desktop app; revisit before - shipping it), `favicon-v3.ico` + `social-share.png` (binary formats we can't author well — + it matters; the desktop app's own i18n dicts `packages/desktop/src/renderer/i18n/{en,es}.ts` + are now rebranded, see the desktop-rebrand row), `favicon-v3.ico` + `social-share.png` (binary formats we can't author well — need design assets; note the docs site serves the upstream-branded `social-share.png` as its `og:image`), the OAuth callback pages (`packages/core/src/oauth/page.ts` — its `WORDMARK` constant is a second copy of the opencode wordmark geometry, and the page's headline/message/ diff --git a/packages/app/src/app.tsx b/packages/app/src/app.tsx index b4496ba7de..558e7ad0dd 100644 --- a/packages/app/src/app.tsx +++ b/packages/app/src/app.tsx @@ -238,7 +238,7 @@ function UiI18nBridge(props: ParentProps) { declare global { interface Window { - __OPENCODE__?: { + __CODEV__?: { deepLinks?: string[] } api?: { diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts index 0a001ce8b7..c4c5fa0fd7 100644 --- a/packages/app/src/i18n/en.ts +++ b/packages/app/src/i18n/en.ts @@ -397,8 +397,8 @@ export const dict = { "wsl.onboarding.updateOpencode": "Update OpenCode", "wsl.onboarding.opencodeReadyIn": "OpenCode is ready in {{distro}}.", "wsl.onboarding.opencodeReady": "OpenCode is ready.", - "wsl.onboarding.installOpencodeIn": "Install OpenCode in {{distro}}.", - "wsl.onboarding.installOpencode": "Install OpenCode", + "wsl.onboarding.installCodevIn": "Install CoDev Code in {{distro}}.", + "wsl.onboarding.installCodev": "Install CoDev Code", "wsl.onboarding.chooseDistroFirst": "Choose a distro first.", "wsl.onboarding.loadFailed": "Failed to load WSL state.", "wsl.onboarding.loading": "Loading...", diff --git a/packages/app/src/i18n/es.ts b/packages/app/src/i18n/es.ts index 819df3fe93..2bee3e620a 100644 --- a/packages/app/src/i18n/es.ts +++ b/packages/app/src/i18n/es.ts @@ -388,8 +388,8 @@ export const dict = { "wsl.onboarding.updateOpencode": "Actualizar OpenCode", "wsl.onboarding.opencodeReadyIn": "OpenCode está listo en {{distro}}.", "wsl.onboarding.opencodeReady": "OpenCode está listo.", - "wsl.onboarding.installOpencodeIn": "Instala OpenCode en {{distro}}.", - "wsl.onboarding.installOpencode": "Instalar OpenCode", + "wsl.onboarding.installCodevIn": "Instala CoDev Code en {{distro}}.", + "wsl.onboarding.installCodev": "Instalar CoDev Code", "wsl.onboarding.chooseDistroFirst": "Elige primero una distribución.", "wsl.onboarding.loadFailed": "No se pudo cargar el estado de WSL.", "wsl.onboarding.loading": "Cargando...", diff --git a/packages/app/src/index.ts b/packages/app/src/index.ts index d18e05fc9c..7389b22796 100644 --- a/packages/app/src/index.ts +++ b/packages/app/src/index.ts @@ -17,7 +17,7 @@ export { type WslInstalledDistro, type WslJob, type WslOnlineDistro, - type WslOpencodeCheck, + type WslCodevCheck, type WslRuntimeCheck, type WslServerConfig, type WslServerItem, diff --git a/packages/app/src/pages/layout/deep-links.ts b/packages/app/src/pages/layout/deep-links.ts index 5dca421f74..9c2ca725c4 100644 --- a/packages/app/src/pages/layout/deep-links.ts +++ b/packages/app/src/pages/layout/deep-links.ts @@ -1,4 +1,4 @@ -export const deepLinkEvent = "opencode:deep-link" +export const deepLinkEvent = "codev:deep-link" const parseUrl = (input: string) => { if (!input.startsWith("opencode://")) return @@ -37,14 +37,14 @@ export const collectNewSessionDeepLinks = (urls: string[]) => urls.map(parseNewSessionDeepLink).filter((link): link is { directory: string; prompt?: string } => !!link) type OpenCodeWindow = Window & { - __OPENCODE__?: { + __CODEV__?: { deepLinks?: string[] } } export const drainPendingDeepLinks = (target: OpenCodeWindow) => { - const pending = target.__OPENCODE__?.deepLinks ?? [] + const pending = target.__CODEV__?.deepLinks ?? [] if (pending.length === 0) return [] - if (target.__OPENCODE__) target.__OPENCODE__.deepLinks = [] + if (target.__CODEV__) target.__CODEV__.deepLinks = [] return pending } diff --git a/packages/app/src/pages/layout/helpers.test.ts b/packages/app/src/pages/layout/helpers.test.ts index df87ddfecd..e442496721 100644 --- a/packages/app/src/pages/layout/helpers.test.ts +++ b/packages/app/src/pages/layout/helpers.test.ts @@ -100,10 +100,10 @@ describe("layout deep links", () => { test("drains global deep links once", () => { const target = { - __OPENCODE__: { + __CODEV__: { deepLinks: ["opencode://open-project?directory=/a"], }, - } as unknown as Window & { __OPENCODE__?: { deepLinks?: string[] } } + } as unknown as Window & { __CODEV__?: { deepLinks?: string[] } } expect(drainPendingDeepLinks(target)).toEqual(["opencode://open-project?directory=/a"]) expect(drainPendingDeepLinks(target)).toEqual([]) diff --git a/packages/app/src/wsl/dialog-add-server.tsx b/packages/app/src/wsl/dialog-add-server.tsx index 3c0b7ee35b..01555fdd7f 100644 --- a/packages/app/src/wsl/dialog-add-server.tsx +++ b/packages/app/src/wsl/dialog-add-server.tsx @@ -338,8 +338,8 @@ function useWslAddServerController(props: DialogWslServerProps) { const distro = model().selectedDistro const action = button.action if (!distro || !action) return - if (action === "install-opencode") { - await run(() => api.installOpencode(distro)) + if (action === "install-codev") { + await run(() => api.installCodev(distro)) return } setStore("adding", true) diff --git a/packages/app/src/wsl/settings-model.test.ts b/packages/app/src/wsl/settings-model.test.ts index 99d3e522cc..21a2ef8ac4 100644 --- a/packages/app/src/wsl/settings-model.test.ts +++ b/packages/app/src/wsl/settings-model.test.ts @@ -6,7 +6,7 @@ import { autoProbePlan, createProbeFailureGate, runAddableProbePlan, - wslOpencodeAction, + wslCodevAction, wslRuntimeRetryable, } from "./settings-model" import type { WslServersState } from "./types" @@ -19,7 +19,7 @@ function readyState(input: Partial<WslServersState> = {}): WslServersState { installed: [], online: [], distroProbes: {}, - opencodeChecks: {}, + codevChecks: {}, pendingRestart: false, servers: [], job: null, @@ -38,9 +38,9 @@ describe("WSL server settings presentation", () => { }) test("offers install and update only when CoDev Code needs attention", () => { - expect(wslOpencodeAction(undefined)).toBeUndefined() + expect(wslCodevAction(undefined)).toBeUndefined() expect( - wslOpencodeAction({ + wslCodevAction({ distro: "Debian", resolvedPath: null, version: null, @@ -50,7 +50,7 @@ describe("WSL server settings presentation", () => { }), ).toBe("Install CoDev Code") expect( - wslOpencodeAction({ + wslCodevAction({ distro: "Debian", resolvedPath: "/usr/local/bin/opencode", version: "1.2.2", @@ -60,7 +60,7 @@ describe("WSL server settings presentation", () => { }), ).toBe("Update CoDev Code") expect( - wslOpencodeAction({ + wslCodevAction({ distro: "Debian", resolvedPath: "/usr/local/bin/opencode", version: "1.2.3", @@ -188,7 +188,7 @@ describe("WSL server settings presentation", () => { distroProbes: { Debian: { name: "Debian", canExecute: true, hasBash: true, hasCurl: true, error: null }, }, - opencodeChecks: { + codevChecks: { Debian: { distro: "Debian", resolvedPath: "/home/me/.opencode/bin/opencode", @@ -208,10 +208,10 @@ describe("WSL server settings presentation", () => { }) expect(model.distroStatuses.Debian).toEqual({ - label: { key: "wsl.onboarding.installOpencode" }, + label: { key: "wsl.onboarding.installCodev" }, tone: "warning", }) - expect(model.primaryButton.action).toBe("install-opencode") + expect(model.primaryButton.action).toBe("install-codev") }) test("delegates addable probe plans to one batch command", async () => { diff --git a/packages/app/src/wsl/settings-model.ts b/packages/app/src/wsl/settings-model.ts index f79ab2b8de..3dcb3aa86c 100644 --- a/packages/app/src/wsl/settings-model.ts +++ b/packages/app/src/wsl/settings-model.ts @@ -2,7 +2,7 @@ import fuzzysort from "fuzzysort" import type { WslInstalledDistro, WslOnlineDistro, - WslOpencodeCheck, + WslCodevCheck, WslServersPlatform, WslServerRuntime, WslServersState, @@ -24,7 +24,7 @@ export type AddServerPrimaryButton = { variant: "neutral" | "contrast" label: AddServerText disabled: boolean - action: "install-opencode" | "add" | null + action: "install-codev" | "add" | null loading: boolean width: string | null } @@ -51,7 +51,7 @@ function isHiddenDistro(name: string) { export const wslRuntimeRetryable = (runtime: WslServerRuntime) => runtime.kind === "failed" || runtime.kind === "stopped" -export function wslOpencodeAction(check?: WslOpencodeCheck) { +export function wslCodevAction(check?: WslCodevCheck) { if (!check) return if (!check.resolvedPath) return "Install CoDev Code" if (check.matchesDesktop === false) return "Update CoDev Code" @@ -80,7 +80,7 @@ export function addServerViewModel(input: { const existingServerDistros = new Set((state?.servers ?? []).map((item) => item.config.distro)) const addableInstalledDistros = visibleInstalledDistros.filter((item) => !existingServerDistros.has(item.name)) const selectedDistro = addServerSelectedDistro(input.selectedDistro, visibleInstalledDistros, addableInstalledDistros) - const opencodeCheck = selectedDistro ? (state?.opencodeChecks[selectedDistro] ?? null) : null + const codevCheck = selectedDistro ? (state?.codevChecks[selectedDistro] ?? null) : null const installableDistros = addServerInstallableDistros(visibleInstalledDistros, visibleOnlineDistros) const filteredInstallableDistros = addServerFilteredInstallableDistros(installableDistros, input.catalogSearch) const catalogTarget = addServerCatalogTarget(input.catalogTarget, filteredInstallableDistros) @@ -93,7 +93,7 @@ export function addServerViewModel(input: { visibleOnlineDistros, addableInstalledDistros, selectedDistro, - opencodeCheck, + codevCheck, wslReady: !!state?.runtime?.available && !state?.pendingRestart, distroStatuses: Object.fromEntries( addableInstalledDistros.flatMap((item) => { @@ -105,7 +105,7 @@ export function addServerViewModel(input: { primaryButton: addServerPrimaryButton({ state, selectedDistro, - opencodeCheck, + codevCheck, adding: input.adding, probingAddable: input.probingAddable, }), @@ -165,7 +165,7 @@ function addServerDistroStatus(input: { if (!probe.hasBash || !probe.hasCurl) { return { label: { key: "wsl.onboarding.distroStatus.missingTools" }, tone: "warning" } } - const check = input.state?.opencodeChecks[input.name] + const check = input.state?.codevChecks[input.name] if (!check) { if (input.probingAddable || (job?.kind === "probe-addable" && job.distros.includes(input.name))) { return checkingStatus() @@ -174,7 +174,7 @@ function addServerDistroStatus(input: { } if (check.matchesDesktop === false) return { label: { key: "wsl.onboarding.updateOpencode" }, tone: "warning" } if (!check.resolvedPath) return { label: { key: "wsl.onboarding.distroStatus.opencodeMissing" }, tone: "warning" } - if (check.error) return { label: { key: "wsl.onboarding.installOpencode" }, tone: "warning" } + if (check.error) return { label: { key: "wsl.onboarding.installCodev" }, tone: "warning" } return { label: { key: "wsl.onboarding.distroStatus.ready" }, tone: "success" } } @@ -185,7 +185,7 @@ function checkingStatus(): DistroStatus { function addServerPrimaryButton(input: { state: WslServersState | undefined selectedDistro: string | null - opencodeCheck: WslOpencodeCheck | null + codevCheck: WslCodevCheck | null adding: boolean probingAddable: boolean }): AddServerPrimaryButton { @@ -194,12 +194,12 @@ function addServerPrimaryButton(input: { const probingOpencode = probingSelected || (ready && - (!input.opencodeCheck || + (!input.codevCheck || (!!input.selectedDistro && input.state?.job?.kind === "probe-addable" && input.state.job.distros.includes(input.selectedDistro)))) const installingOpencode = - input.state?.job?.kind === "install-opencode" && input.state.job.distro === input.selectedDistro + input.state?.job?.kind === "install-codev" && input.state.job.distro === input.selectedDistro if (!ready || probingOpencode) { return { variant: "contrast", @@ -210,17 +210,17 @@ function addServerPrimaryButton(input: { width: null, } } - if (!addServerOpencodeReady(input.opencodeCheck)) { - const update = !!input.opencodeCheck?.resolvedPath && input.opencodeCheck.matchesDesktop === false + if (!addServerOpencodeReady(input.codevCheck)) { + const update = !!input.codevCheck?.resolvedPath && input.codevCheck.matchesDesktop === false return { variant: "neutral", label: installingOpencode ? { key: "wsl.onboarding.updatingOpencode" } : update ? { key: "wsl.onboarding.updateOpencode" } - : { key: "wsl.onboarding.installOpencode" }, + : { key: "wsl.onboarding.installCodev" }, disabled: !!input.state?.job || input.adding, - action: "install-opencode", + action: "install-codev", loading: installingOpencode, width: update ? "138px" : "129px", } @@ -235,7 +235,7 @@ function addServerPrimaryButton(input: { } } -function addServerOpencodeReady(check: WslOpencodeCheck | null) { +function addServerOpencodeReady(check: WslCodevCheck | null) { return !!check?.resolvedPath && check.matchesDesktop !== false && !check.error } @@ -245,7 +245,7 @@ function addServerSelectedDistroSettled(state: WslServersState | undefined, sele if (installed?.version === 1) return false if (!state?.distroProbes[selectedDistro]) return false if (!wslDistroReady(state, selectedDistro)) return true - return !!state.opencodeChecks[selectedDistro] + return !!state.codevChecks[selectedDistro] } function addServerInstallableDistros(installedDistros: WslInstalledDistro[], onlineDistros: WslOnlineDistro[]) { @@ -286,7 +286,7 @@ export function addableProbePlan(input: { const pending = ordered.flatMap((item) => { if (item.version === 1) return [] if (!state.distroProbes[item.name]) return [`distro:${item.name}`] - if (wslDistroReady(state, item.name) && !state.opencodeChecks[item.name]) return [`opencode:${item.name}`] + if (wslDistroReady(state, item.name) && !state.codevChecks[item.name]) return [`opencode:${item.name}`] return [] }) if (!pending.length) return diff --git a/packages/app/src/wsl/settings.tsx b/packages/app/src/wsl/settings.tsx index 82616c6dcf..ce68e47eeb 100644 --- a/packages/app/src/wsl/settings.tsx +++ b/packages/app/src/wsl/settings.tsx @@ -15,7 +15,7 @@ import { ServerConnection } from "@/context/server" import { showToast } from "@/utils/toast" import { DialogAddWslServer } from "./dialog-add-server" import { useWslServers } from "./context" -import { wslOpencodeAction, wslRuntimeRetryable } from "./settings-model" +import { wslCodevAction, wslRuntimeRetryable } from "./settings-model" type Controller = ReturnType<typeof useServerManagementController> @@ -94,9 +94,9 @@ export function WslServerSettings(props: { <For each={props.servers()}> {(item) => { const key = ServerConnection.Key.make(item.config.id) - const check = () => wsl.data?.opencodeChecks[item.config.distro] - const opencodeAction = () => wslOpencodeAction(check()) - const busy = () => wsl.data?.job?.kind === "install-opencode" && wsl.data.job.distro === item.config.distro + const check = () => wsl.data?.codevChecks[item.config.distro] + const opencodeAction = () => wslCodevAction(check()) + const busy = () => wsl.data?.job?.kind === "install-codev" && wsl.data.job.distro === item.config.distro return ( <div class="settings-v2-servers-row"> <div class="settings-v2-servers-lead"> @@ -122,7 +122,7 @@ export function WslServerSettings(props: { <ButtonV2 size="small" disabled={busy() || request.isPending} - onClick={() => api && request.mutate(() => api.installOpencode(item.config.distro))} + onClick={() => api && request.mutate(() => api.installCodev(item.config.distro))} > {busy() ? language.t("wsl.server.updating") : label()} </ButtonV2> diff --git a/packages/app/src/wsl/types.ts b/packages/app/src/wsl/types.ts index 0dd44a54d1..016a99118e 100644 --- a/packages/app/src/wsl/types.ts +++ b/packages/app/src/wsl/types.ts @@ -23,7 +23,7 @@ export type WslDistroProbe = { error: string | null } -export type WslOpencodeCheck = { +export type WslCodevCheck = { distro: string resolvedPath: string | null version: string | null @@ -54,14 +54,14 @@ export type WslJob = | { kind: "install-wsl"; startedAt: number } | { kind: "install-distro"; distro: string; startedAt: number } | { kind: "probe-addable"; distros: string[]; startedAt: number } - | { kind: "install-opencode"; distro: string; startedAt: number } + | { kind: "install-codev"; distro: string; startedAt: number } export type WslServersState = { runtime: WslRuntimeCheck | null installed: WslInstalledDistro[] online: WslOnlineDistro[] distroProbes: Record<string, WslDistroProbe> - opencodeChecks: Record<string, WslOpencodeCheck> + codevChecks: Record<string, WslCodevCheck> pendingRestart: boolean servers: WslServerItem[] job: WslJob | null @@ -77,7 +77,7 @@ export type WslServersPlatform = { installWsl(): Promise<void> installDistro(name: string): Promise<void> probeAddable(distros: string[]): Promise<void> - installOpencode(name: string): Promise<void> + installCodev(name: string): Promise<void> openTerminal(name: string): Promise<void> addServer(distro: string): Promise<WslServerConfig> removeServer(id: string): Promise<void> diff --git a/packages/desktop/README.md b/packages/desktop/README.md index 6dd9a202ad..11dfa4439d 100644 --- a/packages/desktop/README.md +++ b/packages/desktop/README.md @@ -1,6 +1,6 @@ -# OpenCode Desktop +# CoDev Code Desktop -The OpenCode Desktop app, built with Electron. +The CoDev Code Desktop app, built with Electron. ## Development diff --git a/packages/desktop/electron-builder.config.ts b/packages/desktop/electron-builder.config.ts index af7adbc221..d6b3049b32 100644 --- a/packages/desktop/electron-builder.config.ts +++ b/packages/desktop/electron-builder.config.ts @@ -124,7 +124,7 @@ function getConfig() { ...base, appId, productName: "CoDev Code Beta", - protocols: { name: "OpenCode Beta", schemes: ["opencode"] }, + protocols: { name: "CoDev Code Beta", schemes: ["opencode"] }, publish: { provider: "github", owner: "anomalyco", repo: "opencode-beta", channel: "latest" }, rpm: { packageName: "opencode-beta" }, } @@ -134,7 +134,7 @@ function getConfig() { ...base, appId, productName: "CoDev Code", - protocols: { name: "OpenCode", schemes: ["opencode"] }, + protocols: { name: "CoDev Code", schemes: ["opencode"] }, publish: { provider: "github", owner: "anomalyco", repo: "opencode", channel: "latest" }, deb: { fpm: [legacyDesktopEntryFpm] }, rpm: { packageName: "opencode", fpm: [legacyDesktopEntryFpm] }, diff --git a/packages/desktop/electron.vite.config.ts b/packages/desktop/electron.vite.config.ts index 15bd30a5bc..c3e92e1194 100644 --- a/packages/desktop/electron.vite.config.ts +++ b/packages/desktop/electron.vite.config.ts @@ -55,21 +55,21 @@ const require = __cjs_mod__.createRequire(import.meta.url); }, plugins: [ { - name: "opencode:node-pty-narrower", + name: "codev:node-pty-narrower", enforce: "pre", resolveId(s) { if (s === "@lydell/node-pty") return nodePtyPkg }, }, { - name: "opencode:virtual-server-module", + name: "codev:virtual-server-module", enforce: "pre", resolveId(id) { - if (id === "virtual:opencode-server") return this.resolve(`${CODEV_SERVER_DIST}/node.js`) + if (id === "virtual:codev-server") return this.resolve(`${CODEV_SERVER_DIST}/node.js`) }, }, { - name: "opencode:copy-server-assets", + name: "codev:copy-server-assets", async writeBundle() { for (const l of await fs.readdir(CODEV_SERVER_DIST)) { if (!l.endsWith(".wasm")) continue diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 8dc726ac1a..5cef1ca8b9 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -4,11 +4,6 @@ "version": "1.18.4-8", "type": "module", "license": "MIT", - "homepage": "https://opencode.ai", - "author": { - "name": "OpenCode", - "email": "hello@opencode.ai" - }, "scripts": { "typecheck": "tsgo -b", "predev": "bun ./scripts/predev.ts", diff --git a/packages/desktop/scripts/copy-metainfo.ts b/packages/desktop/scripts/copy-metainfo.ts index e7585ccafd..00d4460d24 100644 --- a/packages/desktop/scripts/copy-metainfo.ts +++ b/packages/desktop/scripts/copy-metainfo.ts @@ -4,7 +4,8 @@ const arg = process.argv[2] const channel = arg === "dev" || arg === "beta" || arg === "prod" ? arg : resolveChannel() const appId = channel === "prod" ? "ai.opencode.desktop" : `ai.opencode.desktop.${channel}` -const productName = channel === "prod" ? "OpenCode" : `OpenCode ${channel.charAt(0).toUpperCase() + channel.slice(1)}` +const productName = + channel === "prod" ? "CoDev Code" : `CoDev Code ${channel.charAt(0).toUpperCase() + channel.slice(1)}` const summary = `Open source AI coding agent${channel !== "prod" ? ` (${channel})` : ""}` const xml = `<?xml version="1.0" encoding="UTF-8"?> @@ -17,13 +18,13 @@ const xml = `<?xml version="1.0" encoding="UTF-8"?> <name>${productName}</name> <summary>${summary}</summary> - <developer id="ly.anoma"> - <name>Anomaly Innovations Inc.</name> + <developer> + <name>CoDev</name> </developer> <description> <p> - OpenCode is an open source agent that helps you write and run code with any AI model. + CoDev Code is an open source agent that helps you write and run code with any AI model. </p> </description> @@ -31,15 +32,9 @@ const xml = `<?xml version="1.0" encoding="UTF-8"?> <content_rating type="oars-1.1" /> - <url type="bugtracker">https://github.com/anomalyco/opencode/issues</url> - <url type="homepage">https://opencode.ai</url> - <url type="vcs-browser">https://github.com/anomalyco/opencode</url> - - <screenshots> - <screenshot type="default"> - <image>https://raw.githubusercontent.com/anomalyco/opencode/b75d4d1c5ec449585d515c756fc81f080a157a9a/packages/web/src/assets/lander/screenshot.png</image> - </screenshot> - </screenshots> + <url type="bugtracker">https://github.com/quickbeard/codev-code/issues</url> + <url type="homepage">https://github.com/quickbeard/codev-code</url> + <url type="vcs-browser">https://github.com/quickbeard/codev-code</url> </component> ` diff --git a/packages/desktop/src/main/env.d.ts b/packages/desktop/src/main/env.d.ts index f436dbb292..13a56d9853 100644 --- a/packages/desktop/src/main/env.d.ts +++ b/packages/desktop/src/main/env.d.ts @@ -6,7 +6,7 @@ interface ImportMeta { readonly env: ImportMetaEnv } -declare module "virtual:opencode-server" { +declare module "virtual:codev-server" { export namespace Server { export const listen: typeof import("../../../opencode/dist/types/src/node").Server.listen export type Listener = import("../../../opencode/dist/types/src/node").Server.Listener diff --git a/packages/desktop/src/main/index.ts b/packages/desktop/src/main/index.ts index a2ffca14db..ad88352e1c 100644 --- a/packages/desktop/src/main/index.ts +++ b/packages/desktop/src/main/index.ts @@ -124,7 +124,7 @@ const main = Effect.gen(function* () { const onboardingTestRoot = ((): string | undefined => { if (!TEST_ONBOARDING) return - const root = join(tmpdir(), `opencode-onboarding-${randomUUID()}`) + const root = join(tmpdir(), `codev-onboarding-${randomUUID()}`) rmSync(root, { recursive: true, force: true }) ;["data", "config", "cache", "state", "desktop", "session"].forEach((dir) => mkdirSync(join(root, dir), { recursive: true }), @@ -136,7 +136,7 @@ const main = Effect.gen(function* () { process.env.XDG_STATE_HOME = join(root, "state") return root })() - app.setName(app.isPackaged ? APP_NAMES[CHANNEL] : "OpenCode Dev") + app.setName(app.isPackaged ? APP_NAMES[CHANNEL] : "CoDev Code Dev") app.setAppUserModelId(appId) app.setPath( "userData", diff --git a/packages/desktop/src/main/install-state.test.ts b/packages/desktop/src/main/install-state.test.ts index e85d11815e..676a4e7cff 100644 --- a/packages/desktop/src/main/install-state.test.ts +++ b/packages/desktop/src/main/install-state.test.ts @@ -10,7 +10,7 @@ describe("hasExistingAppState", () => { expect(hasExistingAppState([file("Local State"), directory("Crashpad")])).toBe(false) }) - test("recognizes state written by an earlier OpenCode launch", () => { + test("recognizes state written by an earlier CoDev Code launch", () => { expect(hasExistingAppState([file("opencode.settings")])).toBe(true) expect(hasExistingAppState([file("opencode.global.dat")])).toBe(true) expect(hasExistingAppState([file("window-state-abc.json")])).toBe(true) diff --git a/packages/desktop/src/main/logging.ts b/packages/desktop/src/main/logging.ts index 8866fd78ef..7e89d2b694 100644 --- a/packages/desktop/src/main/logging.ts +++ b/packages/desktop/src/main/logging.ts @@ -54,7 +54,7 @@ export async function exportDebugLogs() { await netLog.stopLogging().catch((error) => write("network", "failed to stop net log", { error })) } - const output = join(app.getPath("downloads"), `opencode-debug-${stamp()}.zip`) + const output = join(app.getPath("downloads"), `codev-debug-${stamp()}.zip`) try { write("main", "exporting debug logs", { output }) await writeZip(output, [ @@ -151,7 +151,7 @@ function manifest() { function serverLogRoots() { const xdgData = process.env.XDG_DATA_HOME || join(homedir(), ".local", "share") - return [...new Set([join(xdgData, "opencode", "log"), join(app.getPath("userData"), "opencode", "log")])] + return [...new Set([join(xdgData, "codev", "log"), join(app.getPath("userData"), "codev", "log")])] } type Entry = { name: string; path?: string; data?: Buffer } diff --git a/packages/desktop/src/main/server.ts b/packages/desktop/src/main/server.ts index 92849f80f0..6033b93826 100644 --- a/packages/desktop/src/main/server.ts +++ b/packages/desktop/src/main/server.ts @@ -16,7 +16,7 @@ type SidecarMessage = export type SidecarListener = { stop: () => Promise<void> } -const SIDECAR_SERVICE_NAME = "opencode server" +const SIDECAR_SERVICE_NAME = "codev server" const SIDECAR_START_STALL_TIMEOUT = 60_000 const SIDECAR_STOP_TIMEOUT = 6_000 diff --git a/packages/desktop/src/main/sidecar.ts b/packages/desktop/src/main/sidecar.ts index b6dd322c2b..9eef25bdf9 100644 --- a/packages/desktop/src/main/sidecar.ts +++ b/packages/desktop/src/main/sidecar.ts @@ -54,7 +54,7 @@ async function start(command: StartCommand) { ensureLoopbackNoProxy() useSystemCertificates() useEnvProxy() - const { Server } = await import("virtual:opencode-server") + const { Server } = await import("virtual:codev-server") listener = await Server.listen({ port: command.port, diff --git a/packages/desktop/src/main/windows.ts b/packages/desktop/src/main/windows.ts index 2b806cb6c6..226f51d450 100644 --- a/packages/desktop/src/main/windows.ts +++ b/packages/desktop/src/main/windows.ts @@ -373,7 +373,7 @@ function wireWindowRecovery(win: BrowserWindow, name: string) { if (!isMainFrame || errorCode === -3) return void show( - "OpenCode failed to load", + "CoDev Code failed to load", [`Window: ${name}`, `URL: ${validatedURL}`, `Error: ${errorCode} ${errorDescription}`].join("\n"), false, ) @@ -389,7 +389,7 @@ function wireWindowRecovery(win: BrowserWindow, name: string) { sampler.stopAndFlush() writeLog("window", "renderer process gone", { window: name, currentURL: safeWindowURL(win), details }, "error") void show( - "OpenCode window terminated unexpectedly", + "CoDev Code window terminated unexpectedly", [`Window: ${name}`, `Reason: ${details.reason}`, `Code: ${details.exitCode ?? "<unknown>"}`].join("\n"), false, ) @@ -397,7 +397,7 @@ function wireWindowRecovery(win: BrowserWindow, name: string) { win.on("unresponsive", () => { writeLog("window", "renderer unresponsive", { window: name, currentURL: safeWindowURL(win) }, "error") sampler.start() - void show("OpenCode is not responding", "You can relaunch the app, open the logs, or keep waiting.", true) + void show("CoDev Code is not responding", "You can relaunch the app, open the logs, or keep waiting.", true) }) win.on("responsive", () => { writeLog("window", "renderer responsive", { window: name, currentURL: safeWindowURL(win) }, "error") diff --git a/packages/desktop/src/main/wsl/ipc.ts b/packages/desktop/src/main/wsl/ipc.ts index c3a2271bf6..90ebaa4dd3 100644 --- a/packages/desktop/src/main/wsl/ipc.ts +++ b/packages/desktop/src/main/wsl/ipc.ts @@ -49,8 +49,8 @@ export function registerWslIpcHandlers(controller: WslServersController) { ipcMain.handle("wsl-servers-probe-addable", (_event: IpcMainInvokeEvent, distros: string[]) => controller.probeAddable(requireWslIpcStrings("distro", distros)), ) - ipcMain.handle("wsl-servers-install-opencode", (_event: IpcMainInvokeEvent, name: string) => - controller.installOpencode(requireWslIpcString("distro", name)), + ipcMain.handle("wsl-servers-install-codev", (_event: IpcMainInvokeEvent, name: string) => + controller.installCodev(requireWslIpcString("distro", name)), ) ipcMain.handle("wsl-servers-open-terminal", (_event: IpcMainInvokeEvent, name: string) => controller.openTerminal(requireWslIpcString("distro", name)), @@ -79,7 +79,7 @@ function registerUnavailableWslIpcHandlers() { installed: [], online: [], distroProbes: {}, - opencodeChecks: {}, + codevChecks: {}, pendingRestart: false, servers: [], job: null, @@ -95,7 +95,7 @@ function registerUnavailableWslIpcHandlers() { ipcMain.handle("wsl-servers-install-wsl", unavailable) ipcMain.handle("wsl-servers-install-distro", unavailable) ipcMain.handle("wsl-servers-probe-addable", unavailable) - ipcMain.handle("wsl-servers-install-opencode", unavailable) + ipcMain.handle("wsl-servers-install-codev", unavailable) ipcMain.handle("wsl-servers-open-terminal", unavailable) ipcMain.handle("wsl-servers-add", unavailable) ipcMain.handle("wsl-servers-remove", unavailable) diff --git a/packages/desktop/src/main/wsl/policy.ts b/packages/desktop/src/main/wsl/policy.ts index 4ceee26c6b..ecf40271b8 100644 --- a/packages/desktop/src/main/wsl/policy.ts +++ b/packages/desktop/src/main/wsl/policy.ts @@ -1,4 +1,4 @@ -import type { WslDistroProbe, WslOpencodeCheck, WslServerItem } from "../../preload/types" +import type { WslDistroProbe, WslCodevCheck, WslServerItem } from "../../preload/types" export function wslServerIdToRestart(servers: WslServerItem[], distro: string) { return servers.find((item) => item.config.distro === distro)?.config.id @@ -6,14 +6,14 @@ export function wslServerIdToRestart(servers: WslServerItem[], distro: string) { export function clearWslDistroState( distroProbes: Record<string, WslDistroProbe>, - opencodeChecks: Record<string, WslOpencodeCheck>, + codevChecks: Record<string, WslCodevCheck>, distro: string, ) { const nextDistroProbes = { ...distroProbes } - const nextOpencodeChecks = { ...opencodeChecks } + const nextCodevChecks = { ...codevChecks } delete nextDistroProbes[distro] - delete nextOpencodeChecks[distro] - return { distroProbes: nextDistroProbes, opencodeChecks: nextOpencodeChecks } + delete nextCodevChecks[distro] + return { distroProbes: nextDistroProbes, codevChecks: nextCodevChecks } } export function wslTerminalArgs(distro?: string | null) { diff --git a/packages/desktop/src/main/wsl/runtime.ts b/packages/desktop/src/main/wsl/runtime.ts index 458443731b..0f6dc00f38 100644 --- a/packages/desktop/src/main/wsl/runtime.ts +++ b/packages/desktop/src/main/wsl/runtime.ts @@ -259,7 +259,7 @@ export async function installWslDistro(name: string, opts?: RunWslOptions) { ) } -export async function installWslOpencode(version: string, distro: string, opts?: RunWslOptions) { +export async function installWslCodev(version: string, distro: string, opts?: RunWslOptions) { return runInteractiveCommand( resolveSystem32Command("wsl.exe"), wslArgs( @@ -302,7 +302,7 @@ export async function probeWslDistro(name: string, opts?: RunWslOptions): Promis } } -export async function resolveWslOpencode(distro: string, opts?: RunWslOptions) { +export async function resolveWslCodev(distro: string, opts?: RunWslOptions) { return firstLine( ( await runWslSh( diff --git a/packages/desktop/src/main/wsl/servers.test.ts b/packages/desktop/src/main/wsl/servers.test.ts index 35b688d3c8..82d19d62ff 100644 --- a/packages/desktop/src/main/wsl/servers.test.ts +++ b/packages/desktop/src/main/wsl/servers.test.ts @@ -7,7 +7,7 @@ import { wslTerminalArgs, } from "./policy" import { - expectOpencodeVersion, + expectCodevVersion, pendingRestartAfterWslInstall, pollWslHealth, wslServerIdsToStartOnInitialize, @@ -15,7 +15,7 @@ import { import { createWslServersController, type WslServerConfig } from "./servers" let persistedServers: WslServerConfig[] = [] -let releaseOpencodeResolve: (() => void) | undefined +let releaseCodevResolve: (() => void) | undefined test("starts every configured WSL server on initialization", () => { expect( @@ -27,13 +27,13 @@ test("starts every configured WSL server on initialization", () => { }) test("rejects an update that did not install the desktop version", () => { - expect(() => expectOpencodeVersion("1.16.2", "1.16.2")).not.toThrow() - expect(() => expectOpencodeVersion("1.14.35", "1.16.2")).toThrow( - "OpenCode update finished but Debian still reports 1.14.35; expected 1.16.2", + expect(() => expectCodevVersion("1.16.2", "1.16.2")).not.toThrow() + expect(() => expectCodevVersion("1.14.35", "1.16.2")).toThrow( + "CoDev Code update finished but Debian still reports 1.14.35; expected 1.16.2", ) }) -test("restarts an existing distro server after updating OpenCode", () => { +test("restarts an existing distro server after updating CoDev Code", () => { expect( wslServerIdToRestart( [ @@ -64,7 +64,7 @@ test("clears cached distro probes when removing a WSL server", () => { }, "Debian", ), - ).toEqual({ distroProbes: {}, opencodeChecks: {} }) + ).toEqual({ distroProbes: {}, codevChecks: {} }) }) test("opens terminals for distro names containing spaces", () => { @@ -104,9 +104,9 @@ test("derives a required Windows restart from the post-install runtime probe", ( expect(pendingRestartAfterWslInstall({ available: true, version: "WSL version: 2.6.1", error: null })).toBe(false) }) -test("ignores stale background OpenCode checks after removing a WSL server", async () => { +test("ignores stale background CoDev Code checks after removing a WSL server", async () => { persistedServers = [] - releaseOpencodeResolve = undefined + releaseCodevResolve = undefined const controller = createWslServersController( "1.16.2", async () => ({ @@ -122,18 +122,18 @@ test("ignores stale background OpenCode checks after removing a WSL server", asy ) await controller.addServer("Debian") - await waitFor(() => !!releaseOpencodeResolve) + await waitFor(() => !!releaseCodevResolve) await controller.removeServer("wsl:Debian") - releaseOpencodeResolve?.() + releaseCodevResolve?.() await new Promise((resolve) => setTimeout(resolve, 0)) expect(controller.getState().servers).toEqual([]) - expect(controller.getState().opencodeChecks).toEqual({}) + expect(controller.getState().codevChecks).toEqual({}) }) -test("ignores stale startup OpenCode checks after removing a WSL server", async () => { +test("ignores stale startup CoDev Code checks after removing a WSL server", async () => { persistedServers = [{ id: "wsl:Debian", distro: "Debian" }] - releaseOpencodeResolve = undefined + releaseCodevResolve = undefined const controller = createWslServersController( "1.16.2", async () => new Promise<never>(() => undefined), @@ -141,20 +141,20 @@ test("ignores stale startup OpenCode checks after removing a WSL server", async ) await controller.initialize() - await waitFor(() => !!releaseOpencodeResolve) + await waitFor(() => !!releaseCodevResolve) await controller.removeServer("wsl:Debian") - releaseOpencodeResolve?.() + releaseCodevResolve?.() await new Promise((resolve) => setTimeout(resolve, 0)) expect(controller.getState().servers).toEqual([]) - expect(controller.getState().opencodeChecks).toEqual({}) + expect(controller.getState().codevChecks).toEqual({}) }) -test("probes addable distros in parallel before checking OpenCode", async () => { +test("probes addable distros in parallel before checking CoDev Code", async () => { persistedServers = [] const started: string[] = [] const release = new Map<string, () => void>() - const opencode: string[] = [] + const checked: string[] = [] const controller = createWslServersController("1.16.2", async () => new Promise<never>(() => undefined), { ...testControllerOptions(), probeDistro: async (distro) => { @@ -162,8 +162,8 @@ test("probes addable distros in parallel before checking OpenCode", async () => await new Promise<void>((resolve) => release.set(distro, resolve)) return { name: distro, canExecute: true, hasBash: true, hasCurl: true, error: null } }, - resolveOpencode: async (distro) => { - opencode.push(distro) + resolveCodev: async (distro) => { + checked.push(distro) return "/home/me/.opencode/bin/opencode" }, }) @@ -171,19 +171,19 @@ test("probes addable distros in parallel before checking OpenCode", async () => const task = controller.probeAddable(["Debian", "Ubuntu"]) await waitFor(() => started.length === 2) expect(started).toEqual(["Debian", "Ubuntu"]) - expect(opencode).toEqual([]) + expect(checked).toEqual([]) release.get("Debian")?.() release.get("Ubuntu")?.() await task expect(Object.keys(controller.getState().distroProbes)).toEqual(["Debian", "Ubuntu"]) - expect(opencode).toEqual(["Debian", "Ubuntu"]) - expect(Object.keys(controller.getState().opencodeChecks)).toEqual(["Debian", "Ubuntu"]) + expect(checked).toEqual(["Debian", "Ubuntu"]) + expect(Object.keys(controller.getState().codevChecks)).toEqual(["Debian", "Ubuntu"]) }) -test("does not check OpenCode in addable distros that cannot execute commands", async () => { +test("does not check CoDev Code in addable distros that cannot execute commands", async () => { persistedServers = [] - const opencode: string[] = [] + const checked: string[] = [] const controller = createWslServersController("1.16.2", async () => new Promise<never>(() => undefined), { ...testControllerOptions(), probeDistro: async (distro) => ({ @@ -193,8 +193,8 @@ test("does not check OpenCode in addable distros that cannot execute commands", hasCurl: distro === "Debian", error: distro === "Debian" ? null : "Open Ubuntu once to finish setup", }), - resolveOpencode: async (distro) => { - opencode.push(distro) + resolveCodev: async (distro) => { + checked.push(distro) return "/home/me/.opencode/bin/opencode" }, }) @@ -202,8 +202,8 @@ test("does not check OpenCode in addable distros that cannot execute commands", await controller.probeAddable(["Debian", "Ubuntu"]) expect(Object.keys(controller.getState().distroProbes)).toEqual(["Debian", "Ubuntu"]) - expect(opencode).toEqual(["Debian"]) - expect(Object.keys(controller.getState().opencodeChecks)).toEqual(["Debian"]) + expect(checked).toEqual(["Debian"]) + expect(Object.keys(controller.getState().codevChecks)).toEqual(["Debian"]) }) async function waitFor(check: () => boolean) { @@ -221,9 +221,9 @@ function testControllerOptions() { persistedServers = servers }, readCommandVersion: async () => "1.16.2", - resolveOpencode: async () => { + resolveCodev: async () => { await new Promise<void>((resolve) => { - releaseOpencodeResolve = resolve + releaseCodevResolve = resolve }) return "/home/me/.opencode/bin/opencode" }, diff --git a/packages/desktop/src/main/wsl/servers.ts b/packages/desktop/src/main/wsl/servers.ts index 2f5cdb00ff..deba0598e1 100644 --- a/packages/desktop/src/main/wsl/servers.ts +++ b/packages/desktop/src/main/wsl/servers.ts @@ -3,7 +3,7 @@ import type { WslInstalledDistro, WslJob, WslOnlineDistro, - WslOpencodeCheck, + WslCodevCheck, WslRuntimeCheck, WslServerConfig, WslServerItem, @@ -13,11 +13,11 @@ import type { } from "../../preload/types" import { WSL_SERVERS_KEY } from "../store-keys" import { getStore } from "../store" -import { expectOpencodeVersion, pendingRestartAfterWslInstall, wslServerIdsToStartOnInitialize } from "./startup" +import { expectCodevVersion, pendingRestartAfterWslInstall, wslServerIdsToStartOnInitialize } from "./startup" import { clearWslDistroState, wslServerIdToRestart } from "./policy" import { installWslDistro, - installWslOpencode, + installWslCodev, installWslRuntimeElevated, listInstalledWslDistros, listOnlineWslDistros, @@ -25,7 +25,7 @@ import { probeWslDistro, probeWslRuntime, readWslCommandVersion, - resolveWslOpencode, + resolveWslCodev, summarize, } from "./runtime" @@ -48,7 +48,7 @@ type WslServersControllerOptions = { readServers?: () => WslServerConfig[] writeServers?: (servers: WslServerConfig[]) => void probeDistro?: typeof probeWslDistro - resolveOpencode?: typeof resolveWslOpencode + resolveCodev?: typeof resolveWslCodev readCommandVersion?: typeof readWslCommandVersion } @@ -121,25 +121,25 @@ export function createWslServersController( updateServer(id, (item) => ({ ...item, runtime })) } - const setOpencodeCheck = (distro: string, check: WslOpencodeCheck) => { + const setCodevCheck = (distro: string, check: WslCodevCheck) => { setState({ - opencodeChecks: { - ...state.opencodeChecks, + codevChecks: { + ...state.codevChecks, [distro]: check, }, }) } - const checkOpencode = async (distro: string, opts?: { signal?: AbortSignal }) => { - const resolved = await (options?.resolveOpencode ?? resolveWslOpencode)(distro, opts) + const checkCodev = async (distro: string, opts?: { signal?: AbortSignal }) => { + const resolved = await (options?.resolveCodev ?? resolveWslCodev)(distro, opts) const version = resolved ? await (options?.readCommandVersion ?? readWslCommandVersion)(resolved, distro, opts) : null - return opencodeCheck(distro, resolved, version, appVersion) + return codevCheck(distro, resolved, version, appVersion) } - const refreshOpencodeCheck = async (distro: string, opts?: { signal?: AbortSignal }) => { - setOpencodeCheck(distro, await checkOpencode(distro, opts)) + const refreshCodevCheck = async (distro: string, opts?: { signal?: AbortSignal }) => { + setCodevCheck(distro, await checkCodev(distro, opts)) } const probeAddableDistros = async (distros: string[], opts?: { signal?: AbortSignal }) => { @@ -153,14 +153,14 @@ export function createWslServersController( setState({ distroProbes: { ...state.distroProbes, ...Object.fromEntries(distroProbes) } }) } - const opencodeChecks = await Promise.all( + const codevChecks = await Promise.all( unique .filter((distro) => distroProbeReady(state.distroProbes[distro])) - .filter((distro) => !state.opencodeChecks[distro]) - .map(async (distro) => [distro, await checkOpencode(distro, opts)] as const), + .filter((distro) => !state.codevChecks[distro]) + .map(async (distro) => [distro, await checkCodev(distro, opts)] as const), ) - if (opencodeChecks.length) { - setState({ opencodeChecks: { ...state.opencodeChecks, ...Object.fromEntries(opencodeChecks) } }) + if (codevChecks.length) { + setState({ codevChecks: { ...state.codevChecks, ...Object.fromEntries(codevChecks) } }) } } @@ -168,29 +168,29 @@ export function createWslServersController( return state.servers.some((item) => item.config.id === id && item.config.distro === distro) } - const refreshOpencodeCheckBackground = (id: string, distro: string) => { - void checkOpencode(distro) + const refreshCodevCheckBackground = (id: string, distro: string) => { + void checkCodev(distro) .then((check) => { if (!hasServer(id, distro)) return - setOpencodeCheck(distro, check) + setCodevCheck(distro, check) }) .catch((error) => { const message = error instanceof Error ? error.message : String(error) - logger?.error("wsl opencode check failed", { id, distro, message }) + logger?.error("wsl codev check failed", { id, distro, message }) }) } - const refreshOpencodeChecks = async () => { + const refreshCodevChecks = async () => { await Promise.all( state.servers.map((item) => - checkOpencode(item.config.distro) + checkCodev(item.config.distro) .then((check) => { if (!hasServer(item.config.id, item.config.distro)) return - setOpencodeCheck(item.config.distro, check) + setCodevCheck(item.config.distro, check) }) .catch((error) => { const message = error instanceof Error ? error.message : String(error) - logger?.error("wsl opencode check failed", { + logger?.error("wsl codev check failed", { id: item.config.id, distro: item.config.distro, message, @@ -251,7 +251,7 @@ export function createWslServersController( setRuntime(id, { kind: "failed", message }) logger?.error("wsl sidecar exited", { id, distro: item.config.distro, code, signal }) }) - refreshOpencodeCheckBackground(id, item.config.distro) + refreshCodevCheckBackground(id, item.config.distro) logger?.log("wsl sidecar ready", { id, distro: item.config.distro, url: sidecar.url }) } catch (error) { const message = error instanceof Error ? error.message : String(error) @@ -303,7 +303,7 @@ export function createWslServersController( async initialize() { refreshFromStore() - void refreshOpencodeChecks() + void refreshCodevChecks() for (const id of wslServerIdsToStartOnInitialize(state.servers.map((item) => item.config))) void startServer(id) }, @@ -358,14 +358,14 @@ export function createWslServersController( }) }, - async installOpencode(name: string) { - await runJob({ kind: "install-opencode", distro: name, startedAt: Date.now() }, async (abort) => { - const result = await installWslOpencode(appVersion, name, { signal: abort.signal }) + async installCodev(name: string) { + await runJob({ kind: "install-codev", distro: name, startedAt: Date.now() }, async (abort) => { + const result = await installWslCodev(appVersion, name, { signal: abort.signal }) if (result.code !== 0) { - throw new Error(summarize(result.stderr || result.stdout) || "OpenCode installation failed") + throw new Error(summarize(result.stderr || result.stdout) || "CoDev Code installation failed") } - await refreshOpencodeCheck(name, { signal: abort.signal }) - expectOpencodeVersion(state.opencodeChecks[name]?.version ?? null, appVersion, name) + await refreshCodevCheck(name, { signal: abort.signal }) + expectCodevVersion(state.codevChecks[name]?.version ?? null, appVersion, name) const id = wslServerIdToRestart(state.servers, name) if (id) await startServer(id) }) @@ -400,7 +400,7 @@ export function createWslServersController( persistServers(remaining) setState({ servers: state.servers.filter((item) => item.config.id !== id), - ...(distro ? clearWslDistroState(state.distroProbes, state.opencodeChecks, distro) : {}), + ...(distro ? clearWslDistroState(state.distroProbes, state.codevChecks, distro) : {}), }) }, @@ -426,7 +426,7 @@ function initialState(): WslServersState { installed: [], online: [], distroProbes: {}, - opencodeChecks: {}, + codevChecks: {}, pendingRestart: false, servers: [], job: null, @@ -462,12 +462,12 @@ function normalizePersistedServer(value: unknown): WslServerConfig[] { ] } -function opencodeCheck( +function codevCheck( distro: string, resolvedPath: string | null, version: string | null, expectedVersion: string, -): WslOpencodeCheck { +): WslCodevCheck { if (!resolvedPath) { return { distro, @@ -475,7 +475,7 @@ function opencodeCheck( version: null, expectedVersion, matchesDesktop: null, - error: "opencode is not installed in this distro", + error: "codev is not installed in this distro", } } if (!version) { @@ -485,7 +485,7 @@ function opencodeCheck( version: null, expectedVersion, matchesDesktop: null, - error: "opencode is installed but could not run", + error: "codev is installed but could not run", } } return { @@ -512,7 +512,7 @@ export type { WslOnlineDistro, WslRuntimeCheck, WslDistroProbe, - WslOpencodeCheck, + WslCodevCheck, WslServerConfig, WslServerItem, WslServerRuntime, diff --git a/packages/desktop/src/main/wsl/sidecar.ts b/packages/desktop/src/main/wsl/sidecar.ts index ea365119ff..a10cdac59a 100644 --- a/packages/desktop/src/main/wsl/sidecar.ts +++ b/packages/desktop/src/main/wsl/sidecar.ts @@ -3,7 +3,7 @@ import { randomUUID } from "node:crypto" import { createServer } from "node:net" import { app } from "electron" import { checkHealth } from "../server" -import { type WslCommandLine, resolveWslOpencode, shellEscape, wslArgs } from "./runtime" +import { type WslCommandLine, resolveWslCodev, shellEscape, wslArgs } from "./runtime" import { pollWslHealth } from "./startup" export type WslSidecar = { @@ -17,8 +17,8 @@ export async function spawnWslSidecar( distro: string, opts: { onLine?: (line: WslCommandLine) => void; healthTimeoutMs?: number } = {}, ): Promise<WslSidecar> { - const opencode = await resolveWslOpencode(distro) - if (!opencode) throw new Error(`OpenCode is not installed in ${distro}`) + const binary = await resolveWslCodev(distro) + if (!binary) throw new Error(`CoDev Code is not installed in ${distro}`) const port = await allocatePort() const password = randomUUID() @@ -34,7 +34,7 @@ export async function spawnWslSidecar( `export CODEV_SERVER_USERNAME=${shellEscape(username)}`, `export CODEV_SERVER_PASSWORD=${shellEscape(password)}`, 'export XDG_STATE_HOME="$HOME/.local/state"', - `exec ${shellEscape(opencode)} --print-logs --log-level ${app.isPackaged ? "WARN" : "INFO"} serve --hostname 0.0.0.0 --port ${port}`, + `exec ${shellEscape(binary)} --print-logs --log-level ${app.isPackaged ? "WARN" : "INFO"} serve --hostname 0.0.0.0 --port ${port}`, ].join("\n") const child = spawn("wsl", wslArgs(["bash", "-se"], distro), { stdio: ["pipe", "pipe", "pipe"], diff --git a/packages/desktop/src/main/wsl/startup.ts b/packages/desktop/src/main/wsl/startup.ts index bfe7accfed..4a85c13f3a 100644 --- a/packages/desktop/src/main/wsl/startup.ts +++ b/packages/desktop/src/main/wsl/startup.ts @@ -2,10 +2,10 @@ export function wslServerIdsToStartOnInitialize(servers: { id: string }[]) { return servers.map((server) => server.id) } -export function expectOpencodeVersion(installed: string | null, expected: string, distro = "Debian") { +export function expectCodevVersion(installed: string | null, expected: string, distro = "Debian") { if (installed === expected) return throw new Error( - `OpenCode update finished but ${distro} still reports ${installed ?? "no version"}; expected ${expected}`, + `CoDev Code update finished but ${distro} still reports ${installed ?? "no version"}; expected ${expected}`, ) } diff --git a/packages/desktop/src/preload/index.ts b/packages/desktop/src/preload/index.ts index 87eac1fa80..510cf93080 100644 --- a/packages/desktop/src/preload/index.ts +++ b/packages/desktop/src/preload/index.ts @@ -30,7 +30,7 @@ const api: ElectronAPI = { installWsl: () => ipcRenderer.invoke("wsl-servers-install-wsl"), installDistro: (name) => ipcRenderer.invoke("wsl-servers-install-distro", name), probeAddable: (distros) => ipcRenderer.invoke("wsl-servers-probe-addable", distros), - installOpencode: (name) => ipcRenderer.invoke("wsl-servers-install-opencode", name), + installCodev: (name) => ipcRenderer.invoke("wsl-servers-install-codev", name), openTerminal: (name) => ipcRenderer.invoke("wsl-servers-open-terminal", name), addServer: (distro) => ipcRenderer.invoke("wsl-servers-add", distro), removeServer: (id) => ipcRenderer.invoke("wsl-servers-remove", id), diff --git a/packages/desktop/src/preload/types.ts b/packages/desktop/src/preload/types.ts index 5fbace72c7..4534e529b9 100644 --- a/packages/desktop/src/preload/types.ts +++ b/packages/desktop/src/preload/types.ts @@ -6,7 +6,7 @@ export type { WslInstalledDistro, WslJob, WslOnlineDistro, - WslOpencodeCheck, + WslCodevCheck, WslRuntimeCheck, WslServerConfig, WslServerItem, diff --git a/packages/desktop/src/renderer/env.d.ts b/packages/desktop/src/renderer/env.d.ts index 6dff3baf1c..355c87e3da 100644 --- a/packages/desktop/src/renderer/env.d.ts +++ b/packages/desktop/src/renderer/env.d.ts @@ -3,7 +3,7 @@ import type { ElectronAPI } from "../preload/types" declare global { interface Window { api: ElectronAPI - __OPENCODE__?: { + __CODEV__?: { deepLinks?: string[] } } diff --git a/packages/desktop/src/renderer/i18n/en.ts b/packages/desktop/src/renderer/i18n/en.ts index 4c30380d56..791e7f83cb 100644 --- a/packages/desktop/src/renderer/i18n/en.ts +++ b/packages/desktop/src/renderer/i18n/en.ts @@ -11,17 +11,17 @@ export const dict = { "desktop.updater.checkFailed.title": "Update Check Failed", "desktop.updater.checkFailed.message": "Failed to check for updates", "desktop.updater.none.title": "No Update Available", - "desktop.updater.none.message": "You are already using the latest version of OpenCode", + "desktop.updater.none.message": "You are already using the latest version of CoDev Code", "desktop.updater.downloadFailed.title": "Update Failed", "desktop.updater.downloadFailed.message": "Failed to download update", "desktop.updater.downloaded.title": "Update Downloaded", "desktop.updater.downloaded.prompt": - "Version {{version}} of OpenCode has been downloaded, would you like to install it and relaunch?", + "Version {{version}} of CoDev Code has been downloaded, would you like to install it and relaunch?", "desktop.updater.installFailed.title": "Update Failed", "desktop.updater.installFailed.message": "Failed to install update", "desktop.cli.installed.title": "CLI Installed", - "desktop.cli.installed.message": "CLI installed to {{path}}\n\nRestart your terminal to use the 'opencode' command.", + "desktop.cli.installed.message": "CLI installed to {{path}}\n\nRestart your terminal to use the 'codev' command.", "desktop.cli.failed.title": "Installation Failed", "desktop.cli.failed.message": "Failed to install CLI: {{error}}", } diff --git a/packages/desktop/src/renderer/i18n/es.ts b/packages/desktop/src/renderer/i18n/es.ts index 80504a8f24..e1dd9a030c 100644 --- a/packages/desktop/src/renderer/i18n/es.ts +++ b/packages/desktop/src/renderer/i18n/es.ts @@ -11,17 +11,17 @@ export const dict = { "desktop.updater.checkFailed.title": "Comprobación de actualizaciones fallida", "desktop.updater.checkFailed.message": "No se pudieron buscar actualizaciones", "desktop.updater.none.title": "No hay actualizaciones disponibles", - "desktop.updater.none.message": "Ya estás usando la versión más reciente de OpenCode", + "desktop.updater.none.message": "Ya estás usando la versión más reciente de CoDev Code", "desktop.updater.downloadFailed.title": "Actualización fallida", "desktop.updater.downloadFailed.message": "No se pudo descargar la actualización", "desktop.updater.downloaded.title": "Actualización descargada", "desktop.updater.downloaded.prompt": - "Se ha descargado la versión {{version}} de OpenCode. ¿Quieres instalarla y reiniciar?", + "Se ha descargado la versión {{version}} de CoDev Code. ¿Quieres instalarla y reiniciar?", "desktop.updater.installFailed.title": "Actualización fallida", "desktop.updater.installFailed.message": "No se pudo instalar la actualización", "desktop.cli.installed.title": "CLI instalada", - "desktop.cli.installed.message": "CLI instalada en {{path}}\n\nReinicia tu terminal para usar el comando 'opencode'.", + "desktop.cli.installed.message": "CLI instalada en {{path}}\n\nReinicia tu terminal para usar el comando 'codev'.", "desktop.cli.failed.title": "Instalación fallida", "desktop.cli.failed.message": "No se pudo instalar la CLI: {{error}}", } diff --git a/packages/desktop/src/renderer/index.html b/packages/desktop/src/renderer/index.html index b7c429fb64..e0a8b2c168 100644 --- a/packages/desktop/src/renderer/index.html +++ b/packages/desktop/src/renderer/index.html @@ -3,7 +3,7 @@ <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <title>OpenCode + CoDev Code diff --git a/packages/desktop/src/renderer/index.tsx b/packages/desktop/src/renderer/index.tsx index 903d39353d..05e9b74c2a 100644 --- a/packages/desktop/src/renderer/index.tsx +++ b/packages/desktop/src/renderer/index.tsx @@ -63,7 +63,7 @@ void initI18n() const [updaterState, setUpdaterState] = createSignal({ status: "disabled" }) void window.api.updater.subscribe(setUpdaterState) -const deepLinkEvent = "opencode:deep-link" +const deepLinkEvent = "codev:deep-link" type DesktopWindowState = { id?: string @@ -71,9 +71,9 @@ type DesktopWindowState = { const emitDeepLinks = (urls: string[]) => { if (urls.length === 0) return - window.__OPENCODE__ ??= {} - const pending = window.__OPENCODE__.deepLinks ?? [] - window.__OPENCODE__.deepLinks = [...pending, ...urls] + window.__CODEV__ ??= {} + const pending = window.__CODEV__.deepLinks ?? [] + window.__CODEV__.deepLinks = [...pending, ...urls] window.dispatchEvent(new CustomEvent(deepLinkEvent, { detail: { urls } })) } diff --git a/packages/desktop/src/renderer/wsl/connections.test.ts b/packages/desktop/src/renderer/wsl/connections.test.ts index 341241a6b6..9428e15681 100644 --- a/packages/desktop/src/renderer/wsl/connections.test.ts +++ b/packages/desktop/src/renderer/wsl/connections.test.ts @@ -7,7 +7,7 @@ const state = (kind: "starting" | "ready" | "failed" | "stopped"): WslServersSta installed: [], online: [], distroProbes: {}, - opencodeChecks: {}, + codevChecks: {}, pendingRestart: false, job: null, servers: [ From 65c9092411597a6a07bba64d585fa3724767e143 Mon Sep 17 00:00:00 2001 From: minhn4 Date: Sun, 9 Aug 2026 10:21:30 +0700 Subject: [PATCH 2/2] refactor(app): rebrand user-facing i18n strings to CoDev Code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The desktop app embeds the packages/app web UI, whose en/es i18n dicts still rendered "OpenCode" in settings descriptions, update toasts, the WSL onboarding flow, the server-switcher dialog, the MCP error, the getting-started sidebar, the provider-connect prompts, and the desktop app name. Rebrand all 28 app-self-reference strings per locale; the i18n keys are untouched (they carry Opencode/opencode, which never match the exact-case OpenCode in the values). Also renames the deep-link bridge window type OpenCodeWindow -> CodevWindow, matching the __CODEV__ global it describes. Deliberately preserved: the hosted-service names "OpenCode Zen" / "OpenCode Go" and the Zen free-models title, plus every opencode.ai URL — the fork routes to those real services, so the text must match where users land. The built-in "OpenCode" theme name is also kept: it names a specific palette and the fork ships its own codev theme alongside it. Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 8 +-- DIVERGENCES.md | 11 ++-- packages/app/src/i18n/en.ts | 58 ++++++++++----------- packages/app/src/i18n/es.ts | 58 ++++++++++----------- packages/app/src/pages/layout/deep-links.ts | 4 +- 5 files changed, 72 insertions(+), 67 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f308ee7011..db574fac2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,9 +21,11 @@ file is the human-readable summary of what changed and why. - **The desktop app says CoDev Code, not opencode** — every user-visible string the app still rendered as "OpenCode" is rebranded: the window title, the crash - and unresponsive dialogs, the updater and CLI-installed messages (English and - Spanish, and the CLI-command hint now names `codev`), the unpackaged app name, - the Linux software-centre listing, and the deep-link handler name the OS shows. + and unresponsive dialogs, the updater and CLI-installed messages, the settings + descriptions, the update toasts, the WSL onboarding steps, the server-switcher + dialog, and the app name — in both English and Spanish, with the CLI-command + hint now naming `codev`. (The hosted "OpenCode Zen" / "OpenCode Go" model + services keep their real names, since the app still connects to them.) Internally, the WSL CLI-management code and the desktop↔web wire values were renamed to codev as well. diff --git a/DIVERGENCES.md b/DIVERGENCES.md index 46c59b9f95..81331c55aa 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -150,6 +150,7 @@ from the squash message first, or use a plain merge. | `packages/app/src/desktop-menu.ts`, `packages/app/src/components/windows-app-menu.tsx` | App-menu label "OpenCode" → "CoDev Code"; "OpenCode Documentation" item → "CoDev Code Documentation" (href `opencode.ai/docs` stays — real URL); trigger `aria-label` "OpenCode menu" → "CoDev Code menu" (×2) | Visible menu branding, incl. screen-reader labels. | Keep our labels; take upstream's surrounding menu changes. Rebrand any new "OpenCode" label/aria-label. | | Hardcoded product-string rebrand in TUI + web app: `packages/tui/src/app.tsx`, `packages/tui/src/routes/session/permission.tsx`, `packages/tui/src/attention.ts` (+ `packages/opencode/test/cli/cmd/tui/attention.test.ts`), `packages/app/src/wsl/settings-model.ts` (+ `.test.ts`), `packages/ui/src/components/favicon.tsx` | User-visible "OpenCode" strings outside the i18n dicts → fork brand: update-complete toast "Successfully updated to OpenCode v…" → "CoDev Code"; permission dialog "…until OpenCode is restarted" → "CoDev Code" (the sibling patterns line was already rebranded); OS-notification fallback title `opencode` → `codev` and built-in sound-pack display name "OpenCode Default" → "CoDev Code Default" (pack id `opencode.default` stays — internal identifier; the three default-title expectations in `packages/opencode/test/cli/cmd/tui/attention.test.ts` follow, while its explicit-title pass-through fixture stays `opencode`); WSL settings actions "Install/Update OpenCode" → "…CoDev Code" (+ test expectations/titles; fixture paths `/usr/local/bin/opencode` stay); PWA `apple-mobile-web-app-title` "OpenCode" → "CoDev Code" (matches the rebranded `site.webmanifest`, favicon-assets row) | These render in surfaces the fork ships (TUI + embedded web UI); the i18n-dict strings remain a known gap (UI branding bullet below). | Keep our strings; take upstream's surrounding changes. Rebrand any new hardcoded user-visible "OpenCode" string in these surfaces; leave identifiers, URLs, and fixture paths. | | Desktop app text + identifier rebrand: `packages/desktop/**` (README, `package.json`, `src/renderer/index.html`, `src/renderer/i18n/{en,es}.ts`, `src/main/{index,windows,server,logging}.ts`, `src/main/wsl/{sidecar,startup,servers,servers.test}.ts`, `src/main/install-state.test.ts`, `scripts/copy-metainfo.ts`, `electron-builder.config.ts`) plus the WSL/deep-link surfaces it shares with `packages/app` (`src/wsl/{types,settings-model,settings-model.test,settings,dialog-add-server}.ts(x)`, `src/i18n/{en,es}.ts`, `src/pages/layout/{deep-links,helpers.test}.ts`, `src/app.tsx`, `src/index.ts`) and `packages/desktop/src/{preload,renderer}` | Every user-visible "OpenCode" the desktop app renders → "CoDev Code": crash dialogs, window ``, updater/CLI-installed i18n (en+es, with the CLI-command hint `'opencode'`→`'codev'`), the unpackaged app-name fallback `"OpenCode Dev"`, the AppStream metainfo (product name, description, `developer` → `<name>CoDev</name>` with the upstream `id="ly.anoma"` dropped, the three URLs repointed to the fork repo, upstream's lander screenshot removed), the OS deep-link handler display name, README, and `package.json` (upstream `homepage`/`author` removed — `packages/opencode` and `packages/app` declare neither). Codebase identifiers renamed `Opencode`→`Codev`/`opencode`→`codev` (`WslOpencodeCheck`, `resolveWslOpencode`, `installWslOpencode`, `expectOpencodeVersion`, `releaseOpencodeResolve`, `checkOpencode`/`refreshOpencodeCheck*`/`setOpencodeCheck`, `opencodeChecks`, `wslOpencodeAction`, …) together with the internal wire values whose producer and consumer both ship here (`virtual:opencode-server`, the `opencode:{node-pty,virtual-server,copy-server}` vite plugin names, the `wsl-servers-install-opencode` IPC channel, the `install-opencode` job kind, the `__OPENCODE__` deep-link bridge global, the `opencode:deep-link` renderer event, the `opencode-onboarding-` temp dir, the `wsl.onboarding.installOpencode*` i18n keys), and the server-log collector path `<xdgData>/opencode/log` → `/codev/log` (a real bug fix — the fork CLI writes to `<xdgData>/codev/log`, `packages/core/src/global.ts` `app = "codev"`, so debug-log export was silently collecting nothing). Two stale product-named locals renamed to what they hold (`opencode`→`binary` in wsl/sidecar.ts, `opencode`→`checked` in the servers test). | The fork ships the desktop app, so every surface it shows and every identifier a maintainer reads should say codev. | Keep our strings + identifiers; take upstream's surrounding changes. PRESERVED deliberately, do not rename: `@opencode-ai/*` package ids, the `ai.opencode.desktop*` appIds and `opencode://` scheme + `schemes:["opencode"]` (identity plumbing), the `owner:"anomalyco"`/`repo:"opencode"`/`packageName:"opencode"` publish targets and `opencode-desktop.desktop` legacy launcher, the persisted on-disk store names (`opencode.settings`, `opencode.{draft,workspace,global,window,updater}.*`, the `opencode` data dir in install-state), the basic-auth username `"opencode"` (must match the server default in `packages/server/src/auth.ts`), and the `../opencode/dist` build paths. | +| `packages/app/src/i18n/{en,es}.ts`, `packages/app/src/pages/layout/deep-links.ts` | App-self-reference "OpenCode" → "CoDev Code" across the shared web UI's i18n dicts (28 strings per locale): settings row descriptions, the update toasts, the WSL onboarding step/status strings, the `dialog.server.description`, `error.chain.mcpFailed`, `sidebar.gettingStarted.line1`, the provider-connect "use {{provider}} models in OpenCode" lines, and `app.name.desktop`. The Zen free-models dialog title (`dialog.model.unpaid.freeModels.title`, "Free models provided by OpenCode") was **neutralized** to "Free models included" / "Modelos gratuitos incluidos" rather than rebranded or kept — it read oddly branded either way. i18n **keys** are untouched (they carry `Opencode`/lowercase `opencode`, which never match the exact-case `OpenCode` in values). The deep-link bridge window type `OpenCodeWindow` → `CodevWindow` (its `__CODEV__` global was already renamed in the desktop row). | These render in the desktop app (and the web console), which the fork ships; closes the "in-app i18n strings" gap for this package. | Keep our strings; take upstream's surrounding changes. PRESERVED deliberately: the real external-service names **"OpenCode Zen"** / **"OpenCode Go"** (in the `opencodeZen.*` provider-connect keys and the "OpenCode Go" upsell), plus every `opencode.ai/*` URL — the fork routes to those actual services, so the display text must match what users land on. The built-in **"OpenCode" theme** name (`packages/ui/src/theme/context.tsx`, the shiki theme id, `desktop-theme.schema.json`) is also kept — it names a specific palette, and the fork ships its own `codev` theme alongside it. | | Browser-opened docs-site links: `packages/tui/src/app.tsx`, `packages/app/src/desktop-menu.ts`, `packages/app/src/components/{settings-general,settings-v2/general,dialog-custom-provider}.tsx`, `packages/app/src/pages/{home,layout,error}.tsx`, `packages/app/src/i18n/{en,es}.ts`, `packages/opencode/src/cli/cmd/{providers,github.handler}.ts` | Links the app opens in the user's browser repointed from `opencode.ai` to the fork's hosted docs. Each one derives its base from `DOCS_URL` (`packages/codev-brand/src/index.ts`, base64-encoded) rather than hardcoding the host: the site is locale-routed and the Code docs live under `/code`, and no URL takes a trailing slash (the site 308-redirects `…/themes/` to `…/themes`). Sites: TUI "Open docs" command and app Documentation menu item → docs root; settings theme "Learn more" (v1 + v2) → `…/code/themes`; custom-provider dialog link → `…/code/providers#custom-provider`; CLI Cloudflare-gateway hint → `…/code/providers#cloudflare-ai-gateway`; GitHub-agent hint → `…/code/github`; home/layout sidebar Help buttons `opencode.ai/desktop-feedback` → docs root. The error page's report button `opencode.ai/desktop-feedback` → `github.com/quickbeard/codev-code/issues` instead (it's a report action, not a docs lookup), icon `discord` → `github`, and the en/es `error.page.report.*` strings → "…CoDev Code team" / "on GitHub". Help submenu (rendered by the shipped web UI's Windows app menu too): "Support Forum" (upstream Discord invite) deleted — the fork has no forum; "Share Feedback"/"Report a Bug" → `github.com/quickbeard/codev-code/issues/new?template=feature-request.yml`/`bug-report.yml` (the fork's template names are hyphenated, unlike upstream's underscored ones). | Fork users should land on the fork's docs and report issues to the fork, not upstream's site/Discord. NOT repointed: Zen/Go product URLs (`opencode.ai/zen`, `/go`, `/auth`), `$schema`/theme-schema ids, API/share/changelog endpoints, MCP OAuth `client_uri`, prompt-file mentions. Also NOT on this base: the ripgrep mirror (`/codev/docs/code/downloads/…`, see its own row) — it is a `public/` static asset, not locale-routed content, and 404s under `/en/docs/code`. | Keep our URLs, icon, and strings; take upstream's surrounding changes. Repoint any new browser-opened `opencode.ai` docs/help link to the fork docs base; leave the NOT-repointed list. | | `packages/desktop/src/main/index.ts`, `packages/desktop/src/main/windows.ts` | APP_NAMES + window title → "CoDev Code" (Dev/Beta variants too) | Desktop app display name. | Keep our names. | | `packages/desktop/electron-builder.config.ts` | `productName` ×3 → "CoDev Code…"; artifactName → `codev-code-desktop-…`; protocol display name | Installer/product branding. appId (`ai.opencode.desktop`) and the `opencode://` deep-link scheme stay upstream — identity plumbing wired into main/index.ts and app deep-links; do not rename casually. | Keep our names; take upstream's other config. | @@ -196,10 +197,12 @@ from the squash message first, or use a plain merge. - **UI branding**: TUI banner, default-theme accent, desktop/web app names, favicon/PWA assets, and the hardcoded TUI/web-app product strings are rebranded (see table). Still - upstream-branded, deliberately: in-app i18n strings mentioning "OpenCode" in the `en`/`es` - locale files (see the locale-trim rows above; revisit with a runtime display-name shim if - it matters; the desktop app's own i18n dicts `packages/desktop/src/renderer/i18n/{en,es}.ts` - are now rebranded, see the desktop-rebrand row), `favicon-v3.ico` + `social-share.png` (binary formats we can't author well — + upstream-branded, deliberately: the `packages/app` and `packages/desktop` i18n `en`/`es` + dicts are now rebranded (see the app-i18n and desktop-rebrand rows) except the real + external-service names "OpenCode Zen" / "OpenCode Go" and the Zen free-models title, which + stay because the fork routes to those actual services (`opencode.ai/zen` `/go`, kept per the + URLs bullet); the remaining upstream-branded i18n is in other packages' dicts (revisit with a + runtime display-name shim if it matters), `favicon-v3.ico` + `social-share.png` (binary formats we can't author well — need design assets; note the docs site serves the upstream-branded `social-share.png` as its `og:image`), the OAuth callback pages (`packages/core/src/oauth/page.ts` — its `WORDMARK` constant is a second copy of the opencode wordmark geometry, and the page's headline/message/ diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts index c4c5fa0fd7..8cebeaebdf 100644 --- a/packages/app/src/i18n/en.ts +++ b/packages/app/src/i18n/en.ts @@ -121,7 +121,7 @@ export const dict = { "dialog.model.manage.description": "Customize which models appear in the model selector.", "dialog.model.manage.provider.toggle": "Toggle all {{provider}} models", - "dialog.model.unpaid.freeModels.title": "Free models provided by OpenCode", + "dialog.model.unpaid.freeModels.title": "Free models included", "dialog.model.unpaid.addMore.title": "Add more models from popular providers", "dialog.model.unpaid.viewMoreProviders": "See 70+ more providers", @@ -135,7 +135,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 CoDev Code.", "provider.connect.apiKey.label": "{{provider}} API key", "provider.connect.apiKey.placeholder": "API key", "provider.connect.apiKey.required": "API key is required", @@ -149,7 +149,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 CoDev Code.", "provider.connect.oauth.code.label": "{{method}} authorization code", "provider.connect.oauth.code.placeholder": "Authorization code", "provider.connect.oauth.code.required": "Authorization code is required", @@ -157,7 +157,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 CoDev Code.", "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.", @@ -338,7 +338,7 @@ export const dict = { "app.server.otherServers": "Other servers", "dialog.server.title": "Servers", - "dialog.server.description": "Switch which OpenCode server this app connects to.", + "dialog.server.description": "Switch which CoDev Code server this app connects to.", "dialog.server.search.placeholder": "Search servers", "dialog.server.empty": "No servers yet", "dialog.server.add.title": "Add server", @@ -375,7 +375,7 @@ export const dict = { "wsl.server.retryStart": "Retry start", "wsl.server.updating": "Updating...", "wsl.onboarding.step.distro": "Choose distro", - "wsl.onboarding.step.opencode": "OpenCode", + "wsl.onboarding.step.opencode": "CoDev Code", "wsl.onboarding.checkingRuntime": "Checking WSL...", "wsl.onboarding.restartRequired": "Windows needs a restart to finish installing WSL.", "wsl.onboarding.ready": "WSL is ready.", @@ -389,14 +389,14 @@ export const dict = { "wsl.onboarding.openDistroOnce": "Open {{distro}} once to finish setup.", "wsl.onboarding.finishingDistro": "Finishing setup for {{distro}}.", "wsl.onboarding.pickDistro": "Pick a distro or install one below.", - "wsl.onboarding.checkingOpencode": "Checking OpenCode...", - "wsl.onboarding.checkingOpencodeIn": "Checking OpenCode in {{distro}}...", - "wsl.onboarding.updatingOpencode": "Updating OpenCode...", - "wsl.onboarding.updatingOpencodeIn": "Updating OpenCode in {{distro}}...", - "wsl.onboarding.updateOpencodeIn": "Update OpenCode in {{distro}}.", - "wsl.onboarding.updateOpencode": "Update OpenCode", - "wsl.onboarding.opencodeReadyIn": "OpenCode is ready in {{distro}}.", - "wsl.onboarding.opencodeReady": "OpenCode is ready.", + "wsl.onboarding.checkingOpencode": "Checking CoDev Code...", + "wsl.onboarding.checkingOpencodeIn": "Checking CoDev Code in {{distro}}...", + "wsl.onboarding.updatingOpencode": "Updating CoDev Code...", + "wsl.onboarding.updatingOpencodeIn": "Updating CoDev Code in {{distro}}...", + "wsl.onboarding.updateOpencodeIn": "Update CoDev Code in {{distro}}.", + "wsl.onboarding.updateOpencode": "Update CoDev Code", + "wsl.onboarding.opencodeReadyIn": "CoDev Code is ready in {{distro}}.", + "wsl.onboarding.opencodeReady": "CoDev Code is ready.", "wsl.onboarding.installCodevIn": "Install CoDev Code in {{distro}}.", "wsl.onboarding.installCodev": "Install CoDev Code", "wsl.onboarding.chooseDistroFirst": "Choose a distro first.", @@ -406,18 +406,18 @@ export const dict = { "wsl.onboarding.checkAgain": "Check again", "wsl.onboarding.distroStatus.ready": "Ready", "wsl.onboarding.distroStatus.checking": "Checking...", - "wsl.onboarding.distroStatus.opencodeMissing": "OpenCode not installed", + "wsl.onboarding.distroStatus.opencodeMissing": "CoDev Code not installed", "wsl.onboarding.distroStatus.missingTools": "Missing bash, curl", "wsl.onboarding.distroStatus.unsupported": "Unsupported · Use WSL 2", "wsl.onboarding.needAnotherDistro": "Need another distro?", "wsl.onboarding.needAnotherDistroHint": "Install a Linux distribution from the WSL catalog", "wsl.onboarding.wslNotInstalled.title": "WSL not installed", "wsl.onboarding.wslNotInstalled.description": - "WSL (Windows Subsystem for Linux) is required before OpenCode can add a WSL server", + "WSL (Windows Subsystem for Linux) is required before CoDev Code can add a WSL server", "wsl.onboarding.wslUnavailable.title": "WSL unavailable", - "wsl.onboarding.wslUnavailable.description": "OpenCode could not verify WSL on this machine.", + "wsl.onboarding.wslUnavailable.description": "CoDev Code could not verify WSL on this machine.", "wsl.onboarding.installWsl": "Install WSL", - "wsl.onboarding.windowsRestartRequired": "Restart Windows to finish installing WSL, then reopen OpenCode.", + "wsl.onboarding.windowsRestartRequired": "Restart Windows to finish installing WSL, then reopen CoDev Code.", "wsl.onboarding.next": "Next", "wsl.onboarding.refresh": "Refresh", "wsl.onboarding.allDistrosAdded": "All installed distros are already added.", @@ -548,7 +548,7 @@ export const dict = { "toast.project.reloadFailed.title": "Failed to reload {{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 CoDev Code ({{version}}) is now available to install.", "toast.update.action.installRestart": "Install and restart", "toast.update.action.notYet": "Not yet", @@ -590,7 +590,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 (codev.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, CoDev Code 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.', @@ -807,7 +807,7 @@ 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": "CoDev Code 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", @@ -839,7 +839,7 @@ export const dict = { "debugBar.mem.tipUnavailable": "Used JS heap vs heap limit. Chromium only.", "debugBar.mem.tip": "Used JS heap vs heap limit. {{used}} of {{limit}}.", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "CoDev Code Desktop", "settings.section.desktop": "Desktop", "settings.section.server": "Server", @@ -847,7 +847,7 @@ export const dict = { "settings.tab.shortcuts": "Shortcuts", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "WSL integration", - "settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.", + "settings.desktop.wsl.description": "Run the CoDev Code server inside WSL on Windows.", "settings.general.section.appearance": "Appearance", "settings.general.section.advanced": "Advanced", @@ -858,17 +858,17 @@ export const dict = { "settings.general.section.display": "Display", "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 CoDev Code", "settings.general.row.shell.title": "Terminal shell", "settings.general.row.shell.description": "Shell used by the terminal and agent tools", "settings.general.row.shell.autoDefault": "Auto (Default)", "settings.general.row.shell.terminalOnly": "terminal only", "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 CoDev Code looks on your device", "settings.general.row.colorScheme.title": "Color scheme", - "settings.general.row.colorScheme.description": "Choose whether OpenCode follows the system, light, or dark theme", + "settings.general.row.colorScheme.description": "Choose whether CoDev Code follows the system, light, or dark theme", "settings.general.row.theme.title": "Theme", - "settings.general.row.theme.description": "Customise how OpenCode is themed.", + "settings.general.row.theme.description": "Customise how CoDev Code is themed.", "settings.general.row.font.title": "Code Font", "settings.general.row.font.description": "Customise the font used in code blocks", "settings.general.row.terminalFont.title": "Terminal Font", @@ -922,7 +922,7 @@ 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 CoDev Code 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", @@ -930,7 +930,7 @@ export const dict = { "settings.updates.action.downloading": "Downloading...", "settings.updates.action.installing": "Installing...", "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 CoDev Code.", "sound.option.none": "None", "sound.option.alert01": "Alert 01", "sound.option.alert02": "Alert 02", diff --git a/packages/app/src/i18n/es.ts b/packages/app/src/i18n/es.ts index 2bee3e620a..93ffc4bcd0 100644 --- a/packages/app/src/i18n/es.ts +++ b/packages/app/src/i18n/es.ts @@ -120,7 +120,7 @@ export const dict = { "dialog.model.manage.description": "Personalizar qué modelos aparecen en el selector de modelos.", "dialog.model.manage.provider.toggle": "Alternar todos los modelos de {{provider}}", - "dialog.model.unpaid.freeModels.title": "Modelos gratuitos proporcionados por OpenCode", + "dialog.model.unpaid.freeModels.title": "Modelos gratuitos incluidos", "dialog.model.unpaid.addMore.title": "Añadir más modelos de proveedores populares", "dialog.provider.viewAll": "Ver más proveedores", @@ -133,7 +133,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 CoDev Code.", "provider.connect.apiKey.label": "Clave API de {{provider}}", "provider.connect.apiKey.placeholder": "Clave API", "provider.connect.apiKey.required": "La clave API es obligatoria", @@ -147,7 +147,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 CoDev Code.", "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", @@ -155,7 +155,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 CoDev Code.", "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.", @@ -331,7 +331,7 @@ export const dict = { "dialog.directory.readError": "No se puede leer esta carpeta", "dialog.server.title": "Servidores", - "dialog.server.description": "Cambiar a qué servidor de OpenCode se conecta esta app.", + "dialog.server.description": "Cambiar a qué servidor de CoDev Code 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", @@ -366,7 +366,7 @@ export const dict = { "wsl.server.retryStart": "Reintentar el inicio", "wsl.server.updating": "Actualizando...", "wsl.onboarding.step.distro": "Elegir distribución", - "wsl.onboarding.step.opencode": "OpenCode", + "wsl.onboarding.step.opencode": "CoDev Code", "wsl.onboarding.checkingRuntime": "Comprobando WSL...", "wsl.onboarding.restartRequired": "Es necesario reiniciar Windows para terminar de instalar WSL.", "wsl.onboarding.ready": "WSL está listo.", @@ -380,14 +380,14 @@ export const dict = { "wsl.onboarding.openDistroOnce": "Abre {{distro}} una vez para completar la configuración.", "wsl.onboarding.finishingDistro": "Completando la configuración de {{distro}}.", "wsl.onboarding.pickDistro": "Elige una distribución o instala una abajo.", - "wsl.onboarding.checkingOpencode": "Comprobando OpenCode...", - "wsl.onboarding.checkingOpencodeIn": "Comprobando OpenCode en {{distro}}...", - "wsl.onboarding.updatingOpencode": "Actualizando OpenCode...", - "wsl.onboarding.updatingOpencodeIn": "Actualizando OpenCode en {{distro}}...", - "wsl.onboarding.updateOpencodeIn": "Actualiza OpenCode en {{distro}}.", - "wsl.onboarding.updateOpencode": "Actualizar OpenCode", - "wsl.onboarding.opencodeReadyIn": "OpenCode está listo en {{distro}}.", - "wsl.onboarding.opencodeReady": "OpenCode está listo.", + "wsl.onboarding.checkingOpencode": "Comprobando CoDev Code...", + "wsl.onboarding.checkingOpencodeIn": "Comprobando CoDev Code en {{distro}}...", + "wsl.onboarding.updatingOpencode": "Actualizando CoDev Code...", + "wsl.onboarding.updatingOpencodeIn": "Actualizando CoDev Code en {{distro}}...", + "wsl.onboarding.updateOpencodeIn": "Actualiza CoDev Code en {{distro}}.", + "wsl.onboarding.updateOpencode": "Actualizar CoDev Code", + "wsl.onboarding.opencodeReadyIn": "CoDev Code está listo en {{distro}}.", + "wsl.onboarding.opencodeReady": "CoDev Code está listo.", "wsl.onboarding.installCodevIn": "Instala CoDev Code en {{distro}}.", "wsl.onboarding.installCodev": "Instalar CoDev Code", "wsl.onboarding.chooseDistroFirst": "Elige primero una distribución.", @@ -397,19 +397,19 @@ export const dict = { "wsl.onboarding.checkAgain": "Comprobar de nuevo", "wsl.onboarding.distroStatus.ready": "Lista", "wsl.onboarding.distroStatus.checking": "Comprobando...", - "wsl.onboarding.distroStatus.opencodeMissing": "OpenCode no está instalado", + "wsl.onboarding.distroStatus.opencodeMissing": "CoDev Code no está instalado", "wsl.onboarding.distroStatus.missingTools": "Faltan bash y curl", "wsl.onboarding.distroStatus.unsupported": "No compatible · Usa WSL 2", "wsl.onboarding.needAnotherDistro": "¿Necesitas otra distribución?", "wsl.onboarding.needAnotherDistroHint": "Instala una distribución de Linux desde el catálogo de WSL", "wsl.onboarding.wslNotInstalled.title": "WSL no está instalado", "wsl.onboarding.wslNotInstalled.description": - "Se necesita WSL (Subsistema de Windows para Linux) para que OpenCode pueda añadir un servidor WSL", + "Se necesita WSL (Subsistema de Windows para Linux) para que CoDev Code pueda añadir un servidor WSL", "wsl.onboarding.wslUnavailable.title": "WSL no disponible", - "wsl.onboarding.wslUnavailable.description": "OpenCode no pudo comprobar WSL en este equipo.", + "wsl.onboarding.wslUnavailable.description": "CoDev Code no pudo comprobar WSL en este equipo.", "wsl.onboarding.installWsl": "Instalar WSL", "wsl.onboarding.windowsRestartRequired": - "Reinicia Windows para terminar de instalar WSL y, después, vuelve a abrir OpenCode.", + "Reinicia Windows para terminar de instalar WSL y, después, vuelve a abrir CoDev Code.", "wsl.onboarding.next": "Siguiente", "wsl.onboarding.refresh": "Actualizar", "wsl.onboarding.allDistrosAdded": "Ya se han añadido todas las distribuciones instaladas.", @@ -535,7 +535,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 CoDev Code ({{version}}) está disponible para instalar.", "toast.update.action.installRestart": "Instalar y reiniciar", "toast.update.action.notYet": "Todavía no", @@ -569,7 +569,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 (codev.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, CoDev Code 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.', @@ -742,7 +742,7 @@ 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": "CoDev Code 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", @@ -750,7 +750,7 @@ export const dict = { "sidebar.empty.title": "No hay proyectos abiertos", "sidebar.empty.description": "Abre un proyecto para empezar", - "app.name.desktop": "OpenCode Desktop", + "app.name.desktop": "CoDev Code Desktop", "settings.section.desktop": "Escritorio", "settings.section.server": "Servidor", @@ -758,7 +758,7 @@ export const dict = { "settings.tab.shortcuts": "Atajos", "settings.desktop.section.wsl": "WSL", "settings.desktop.wsl.title": "Integración con WSL", - "settings.desktop.wsl.description": "Ejecutar el servidor OpenCode dentro de WSL en Windows.", + "settings.desktop.wsl.description": "Ejecutar el servidor CoDev Code dentro de WSL en Windows.", "settings.general.section.appearance": "Apariencia", "settings.general.section.advanced": "Avanzado", @@ -769,18 +769,18 @@ export const dict = { "settings.general.section.display": "Pantalla", "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 CoDev Code", "settings.general.row.shell.title": "Shell del terminal", "settings.general.row.shell.description": "Elige el shell que se usará en el terminal. Los shells compatibles también se usarán para las llamadas a herramientas del agente.", "settings.general.row.shell.autoDefault": "Automático (Predeterminado)", "settings.general.row.shell.terminalOnly": "solo en el terminal", "settings.general.row.appearance.title": "Apariencia", - "settings.general.row.appearance.description": "Personaliza cómo se ve OpenCode en tu dispositivo", + "settings.general.row.appearance.description": "Personaliza cómo se ve CoDev Code en tu dispositivo", "settings.general.row.colorScheme.title": "Esquema de color", - "settings.general.row.colorScheme.description": "Elige si OpenCode sigue el tema del sistema, claro u oscuro", + "settings.general.row.colorScheme.description": "Elige si CoDev Code sigue el tema del sistema, claro u oscuro", "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 CoDev Code.", "settings.general.row.font.title": "Fuente de código", "settings.general.row.font.description": "Personaliza la fuente usada en bloques de código", "settings.general.row.terminalFont.title": "Fuente del terminal", @@ -838,7 +838,7 @@ 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 CoDev Code", "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", @@ -846,7 +846,7 @@ export const dict = { "settings.updates.action.downloading": "Descargando...", "settings.updates.action.installing": "Instalando...", "settings.updates.toast.latest.title": "Estás al día", - "settings.updates.toast.latest.description": "Estás usando la última versión de OpenCode.", + "settings.updates.toast.latest.description": "Estás usando la última versión de CoDev Code.", "sound.option.none": "Ninguno", "sound.option.alert01": "Alerta 01", "sound.option.alert02": "Alerta 02", diff --git a/packages/app/src/pages/layout/deep-links.ts b/packages/app/src/pages/layout/deep-links.ts index 9c2ca725c4..9ae80595e4 100644 --- a/packages/app/src/pages/layout/deep-links.ts +++ b/packages/app/src/pages/layout/deep-links.ts @@ -36,13 +36,13 @@ export const collectOpenProjectDeepLinks = (urls: string[]) => export const collectNewSessionDeepLinks = (urls: string[]) => urls.map(parseNewSessionDeepLink).filter((link): link is { directory: string; prompt?: string } => !!link) -type OpenCodeWindow = Window & { +type CodevWindow = Window & { __CODEV__?: { deepLinks?: string[] } } -export const drainPendingDeepLinks = (target: OpenCodeWindow) => { +export const drainPendingDeepLinks = (target: CodevWindow) => { const pending = target.__CODEV__?.deepLinks ?? [] if (pending.length === 0) return [] if (target.__CODEV__) target.__CODEV__.deepLinks = []