From d22d08bbced0a85628e2ecd2773ca36ab2d14af4 Mon Sep 17 00:00:00 2001 From: "kiloconnect[bot]" <240665456+kiloconnect[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 15:00:59 +0000 Subject: [PATCH] chore: remove stale desktop package references --- .../workflows/check-opencode-annotations.yml | 3 - AGENTS.md | 8 +- TESTING.md | 2 +- packages/kilo-vscode/AGENTS.md | 26 +- .../src/commands/toggle-auto-approve.ts | 3 +- packages/kilo-vscode/src/provider-actions.ts | 2 +- .../cli-backend/connection-service.ts | 3 +- .../services/cli-backend/sdk-sse-adapter.ts | 7 +- .../services/cli-backend/server-manager.ts | 6 +- .../kilo-vscode/tests/unit/local-diff.test.ts | 2 +- .../agent-manager/terminal/TerminalTab.tsx | 7 +- .../webview-ui/src/context/session.tsx | 1 - .../webview-ui/src/hooks/usePromptHistory.ts | 5 +- .../tests/check-opencode-annotations.test.ts | 9 - .../ui/src/theme/desktop-theme.schema.json | 4 +- script/check-opencode-annotations.ts | 3 - script/publish.ts | 2 - script/raw-changelog.ts | 10 +- script/upstream/README.md | 23 +- script/upstream/fix-kilocode-markers.ts | 4 +- script/upstream/index.ts | 8 - script/upstream/merge.ts | 55 +-- script/upstream/transforms/lock-files.ts | 22 -- script/upstream/transforms/skip-files.test.ts | 4 +- script/upstream/transforms/transform-i18n.ts | 8 - .../transforms/transform-package-json.ts | 4 - .../transforms/transform-take-theirs.ts | 27 -- script/upstream/transforms/transform-tauri.ts | 363 ------------------ script/upstream/transforms/transform-web.ts | 5 - script/upstream/utils/config.ts | 26 +- script/upstream/utils/report.test.ts | 2 +- script/upstream/utils/report.ts | 39 +- 32 files changed, 53 insertions(+), 640 deletions(-) delete mode 100644 script/upstream/transforms/transform-tauri.ts diff --git a/.github/workflows/check-opencode-annotations.yml b/.github/workflows/check-opencode-annotations.yml index cde9056873..e1588c0fc4 100644 --- a/.github/workflows/check-opencode-annotations.yml +++ b/.github/workflows/check-opencode-annotations.yml @@ -6,9 +6,6 @@ on: - ".github/**" - "github/**" - "sdks/vscode/**" - - "packages/app/**" - - "packages/desktop/**" - - "packages/desktop-electron/**" - "packages/extensions/**" - "packages/opencode/**" - "packages/script/**" diff --git a/AGENTS.md b/AGENTS.md index 74dc60eceb..d13cf58895 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -43,10 +43,8 @@ All products are clients of the **CLI** (`packages/opencode/`), which contains t | Product | Package | Description | |---|---|---| -| Kilo CLI | `packages/opencode/` | Core engine. TUI, `kilo run`, `kilo serve`, `kilo web`. Fork of upstream OpenCode. | +| Kilo CLI | `packages/opencode/` | Core engine. TUI, `kilo run`, `kilo serve`. Fork of upstream OpenCode. | | Kilo VS Code Extension | `packages/kilo-vscode/` | VS Code extension. Bundles the CLI binary, spawns `kilo serve` as a child process. Includes the **Agent Manager** — a multi-session orchestration panel with git worktree isolation. | -| OpenCode Desktop | `packages/desktop/` | Standalone Tauri native app. Bundles CLI as sidecar. Single-session UI. Unrelated to the VS Code extension. Not actively maintained — synced from upstream fork. | -| OpenCode Web | `packages/app/` | Shared SolidJS frontend used by both the desktop app and `kilo web` CLI command. Not actively maintained — synced from upstream fork. | **Agent Manager** refers to a feature inside `packages/kilo-vscode/` (extension code in `src/agent-manager/`, webview in `webview-ui/agent-manager/`). It is not a standalone product. See the extension's `AGENTS.md` for details. @@ -64,9 +62,7 @@ Turborepo + Bun workspaces. The packages you'll work with most: | `packages/kilo-gateway/` | `@kilocode/kilo-gateway` | Kilo auth, provider routing, API integration | | `packages/kilo-telemetry/` | `@kilocode/kilo-telemetry` | PostHog analytics + OpenTelemetry | | `packages/kilo-i18n/` | `@kilocode/kilo-i18n` | Internationalization / translations | -| `packages/kilo-ui/` | `@kilocode/kilo-ui` | SolidJS component library shared by the extension webview and `packages/app/` | -| `packages/app/` | `@opencode-ai/app` | Shared SolidJS web UI for desktop app and `kilo web` | -| `packages/desktop/` | `@opencode-ai/desktop` | Tauri desktop app shell | +| `packages/kilo-ui/` | `@kilocode/kilo-ui` | SolidJS component library shared by the extension webview and docs screenshot stories | | `packages/util/` | `@opencode-ai/util` | Shared utilities (error, path, retry, slug, etc.) | | `packages/plugin/` | `@kilocode/plugin` | Plugin/tool interface definitions | diff --git a/TESTING.md b/TESTING.md index 5d17ca66d6..bee6135c5d 100644 --- a/TESTING.md +++ b/TESTING.md @@ -1,6 +1,6 @@ # TESTING.md -How to spin up the **local main-branch** Kilo backend and test it with `curl` / `fetch`. Aimed at a running Kilo CLI agent iterating on backend fixes without rebuilding the VS Code extension, TUI, or desktop app. +How to spin up the **local main-branch** Kilo backend and test it with `curl` / `fetch`. Aimed at a running Kilo CLI agent iterating on backend fixes without rebuilding the VS Code extension or TUI. All examples use plain shell + `curl`. Writing TypeScript files is a last resort (see Section 8). diff --git a/packages/kilo-vscode/AGENTS.md b/packages/kilo-vscode/AGENTS.md index 898161058f..a1583f8dbc 100644 --- a/packages/kilo-vscode/AGENTS.md +++ b/packages/kilo-vscode/AGENTS.md @@ -4,7 +4,7 @@ This file provides guidance to agents when working with code in this repository. ## Product Context -Kilo Code is an open source AI coding agent platform. It ships as multiple products that all build on the same backend. This package (`packages/kilo-vscode/`) is the **VS Code extension** — one of several clients. +Kilo Code is an open source AI coding agent platform. It ships as a CLI and editor clients that all build on the same backend. This package (`packages/kilo-vscode/`) is the **VS Code extension**. ### Products and How They Relate @@ -18,12 +18,12 @@ Every client spawns or connects to a `kilo serve` process and communicates via H │ AI agents, tools, sessions, │ │ providers, config, MCP, LSP │ │ Hono HTTP server + SSE │ - └──┬──────────┬──────────┬───────┘ - │ │ │ - ┌───────┴──┐ ┌────┴────┐ ┌───┴──────────┐ - │ TUI │ │ VS Code │ │ Desktop / Web│ - │ (builtin)│ │Extension│ │ │ - └──────────┘ └─────────┘ └──────────────┘ + └──┬──────────┬──────────────────┘ + │ │ + ┌───────┴──┐ ┌────┴────┐ + │ TUI │ │ VS Code │ + │ (builtin)│ │Extension│ + └──────────┘ └─────────┘ ``` | Product | Package | What it is | How it uses the CLI | @@ -31,10 +31,6 @@ Every client spawns or connects to a `kilo serve` process and communicates via H | Kilo CLI (TUI) | `packages/opencode/` | Interactive terminal UI (SolidJS + OpenTUI) | In-process — TUI and server run together | | Kilo CLI (`kilo run`) | `packages/opencode/` | Non-interactive headless mode for scripting | In-process — no network socket | | **Kilo VS Code Extension** | **`packages/kilo-vscode/`** | VS Code extension with sidebar chat + Agent Manager | Bundles CLI binary, spawns `kilo serve --port 0` as child process | -| OpenCode Desktop | `packages/desktop/` | Standalone native app (Tauri) | Bundles CLI binary as sidecar, spawns `kilo serve` | -| OpenCode Web (`kilo web`) | `packages/opencode/` + `packages/app/` | Browser-based UI | CLI starts server + opens browser | - -**OpenCode Desktop** (`packages/desktop/`) and `kilo web` both render the shared `@opencode-ai/app` SolidJS frontend (`packages/app/`). They differ only in the platform layer (Tauri native APIs vs browser APIs). Neither has any relationship to this extension or the Agent Manager — they are independent clients of the same `kilo serve` backend. ### Kilo-Domain Packages @@ -42,7 +38,7 @@ Every client spawns or connects to a `kilo serve` process and communicates via H |---|---|---| | `packages/kilo-vscode/` | `kilo-code` | **This package.** VS Code extension. | | `packages/kilo-gateway/` | `@kilocode/kilo-gateway` | Auth (device flow), AI provider routing (OpenRouter), Kilo API integration (profile, balance, teams) | -| `packages/kilo-ui/` | `@kilocode/kilo-ui` | SolidJS component library (40+ components, built on `@kobalte/core`). Shared by this extension's webview and `packages/app/` | +| `packages/kilo-ui/` | `@kilocode/kilo-ui` | SolidJS component library (40+ components, built on `@kobalte/core`). Shared by this extension's webview and docs screenshot stories | | `packages/kilo-telemetry/` | `@kilocode/kilo-telemetry` | PostHog analytics + OpenTelemetry tracing for the CLI | | `packages/kilo-i18n/` | `@kilocode/kilo-i18n` | Translation strings (16 languages) | | `packages/kilo-docs/` | `@kilocode/kilo-docs` | Documentation site (Next.js + Markdoc) | @@ -53,8 +49,6 @@ Every client spawns or connects to a `kilo serve` process and communicates via H |---|---|---| | `packages/opencode/` | `@kilocode/cli` | Core CLI — forked from upstream OpenCode. AI agents, tools, sessions, server. | | `packages/sdk/js/` | `@kilocode/sdk` | Auto-generated TypeScript SDK client for the server API. Do not edit `src/gen/` by hand. | -| `packages/app/` | `@opencode-ai/app` | Shared SolidJS web UI consumed by desktop app and `kilo web` | -| `packages/desktop/` | `@opencode-ai/desktop` | Tauri desktop app shell | | `packages/ui/` | `@opencode-ai/ui` | Shared UI primitives | | `packages/util/` | `@opencode-ai/util` | Shared utilities (error, path, retry, slug) | | `packages/plugin/` | `@kilocode/plugin` | Plugin/tool interface definitions | @@ -181,8 +175,8 @@ New webview features must use **`@kilocode/kilo-ui`** components instead of raw - Global styles imported via `import "@kilocode/kilo-ui/styles"` in [`index.tsx`](webview-ui/src/index.tsx:2) - [`chat.css`](webview-ui/src/styles/chat.css) is being progressively migrated — when replacing a component with kilo-ui, remove the corresponding CSS rules from it - New CSS for components not yet in kilo-ui goes into `chat.css` grouped by comment-delimited sections (`/* Component Name */`). Once a kilo-ui equivalent exists, remove the section. -- **Check the desktop app first**: [`packages/app/src/`](../../packages/app/src/) is the reference implementation for how kilo-ui components are composed together. Always check how the app uses a component before implementing it in the webview — don't just look at the component API in isolation. -- **`data-component` and `data-slot` attributes carry CSS styling** — kilo-ui uses `[data-component]` and `[data-slot]` attribute selectors, not class names. When the app uses e.g. `data-component="permission-prompt"` and `data-slot="permission-actions"`, these get kilo-ui styling for free. +- **Check existing webview usages first**: `webview-ui/src/` and `packages/kilo-ui/src/stories/` show how kilo-ui components are composed. Do not rely only on the component API in isolation. +- **`data-component` and `data-slot` attributes carry CSS styling** — kilo-ui uses `[data-component]` and `[data-slot]` attribute selectors, not class names. Reuse existing component slots where available so shared styles apply consistently. - **Prefer kilo-ui styles**: Always reuse existing kilo-ui CSS variables, tokens, and component styles instead of writing custom CSS. If a style doesn't exist in kilo-ui yet, add it there and reuse it rather than inlining or duplicating styles in the webview. - **Icons**: kilo-ui has 75+ custom SVG icons in [`packages/ui/src/components/icon.tsx`](../../packages/ui/src/components/icon.tsx). To list all available icon names: `node -e "const c=require('fs').readFileSync('../../packages/ui/src/components/icon.tsx','utf8');[...c.matchAll(/^\\s{2}[\"']?([\\w-]+)[\"']?:\\s*\x60/gm)].map(m=>m[1]).sort().forEach(n=>console.log(n))"`. Icon names use both hyphenated (`arrow-left`) and bare-word (`brain`, `console`, `providers`) keys. diff --git a/packages/kilo-vscode/src/commands/toggle-auto-approve.ts b/packages/kilo-vscode/src/commands/toggle-auto-approve.ts index ee89231288..f553c43034 100644 --- a/packages/kilo-vscode/src/commands/toggle-auto-approve.ts +++ b/packages/kilo-vscode/src/commands/toggle-auto-approve.ts @@ -26,8 +26,7 @@ const KEY = "enabled" /** * Runtime auto-accept toggle for permissions. * - * Mirrors the desktop app pattern (packages/app/src/context/permission.tsx): - * instead of writing to the config file, we intercept `permission.asked` SSE + * Instead of writing to the config file, we intercept `permission.asked` SSE * events and auto-reply "once" to each. This avoids config-layer issues * (merged vs global, sparse defaults) and works even when the sidebar is closed. */ diff --git a/packages/kilo-vscode/src/provider-actions.ts b/packages/kilo-vscode/src/provider-actions.ts index e86312f68a..cf7cb1f908 100644 --- a/packages/kilo-vscode/src/provider-actions.ts +++ b/packages/kilo-vscode/src/provider-actions.ts @@ -258,7 +258,7 @@ export async function disconnectProvider( // Config-sourced providers stay "connected" after auth.remove because the // server rebuilds state from config. Add to disabled_providers so the server // excludes them. The config entry is preserved (user may re-enable later). - // This matches the desktop app's disableProvider() pattern. + // This mirrors the server's disabled provider config behavior. if (configured && !oauth) { const disabled = globalConfig.disabled_providers ?? [] if (!disabled.includes(id)) { diff --git a/packages/kilo-vscode/src/services/cli-backend/connection-service.ts b/packages/kilo-vscode/src/services/cli-backend/connection-service.ts index a1540d3ee2..3b5a9e0d95 100644 --- a/packages/kilo-vscode/src/services/cli-backend/connection-service.ts +++ b/packages/kilo-vscode/src/services/cli-backend/connection-service.ts @@ -28,7 +28,7 @@ function isNotFound(err: unknown) { return false } -// Poll /global/health at the same interval as packages/app/src/context/server.tsx. +// Poll /global/health every 10 seconds. // This provides a second detection channel for server death independent of the SSE heartbeat. const HEALTH_POLL_INTERVAL_MS = 10_000 @@ -514,7 +514,6 @@ export class KiloConnectionService { /** * Start polling GET /global/health every 10 seconds. - * Ported from packages/app/src/context/server.tsx (HEALTH_POLL_INTERVAL_MS). * Provides a second detection channel for server death independent of the SSE heartbeat. * If the health check fails while we believe we are connected, the SSE client is * disconnected so its reconnect loop kicks in immediately. diff --git a/packages/kilo-vscode/src/services/cli-backend/sdk-sse-adapter.ts b/packages/kilo-vscode/src/services/cli-backend/sdk-sse-adapter.ts index 374d34a16b..299a4a9453 100644 --- a/packages/kilo-vscode/src/services/cli-backend/sdk-sse-adapter.ts +++ b/packages/kilo-vscode/src/services/cli-backend/sdk-sse-adapter.ts @@ -8,14 +8,14 @@ export type SSEStateHandler = (state: "connecting" | "connected" | "disconnected * SSE adapter that consumes the SDK's `client.global.event()` AsyncGenerator * and distributes events to subscribers via a pub/sub interface. * - * Follows the same reconnection pattern as the app (`packages/app/src/context/global-sdk.tsx`): + * Follows the original web client reconnection pattern: * - Outer `while (!aborted)` loop for reconnection * - Per-attempt AbortController so heartbeat timeout can cancel a stale connection * - Heartbeat timeout to detect zombie connections * * In this VS Code extension context the connection is localhost (extension ↔ * child-process server), so zombie-connection scenarios are less likely than in - * the web app (which goes through proxies/CDNs). We keep the heartbeat for + * a browser client (which goes through proxies/CDNs). We keep the heartbeat for * consistency with the original strategy but use a generous 90 s timeout to * avoid false-positive reconnections during idle periods. * @@ -33,8 +33,7 @@ export class SdkSSEAdapter { private attemptController: AbortController | null = null private heartbeatTimer: ReturnType | null = null - // 15s matches packages/app/src/context/global-sdk.tsx — server sends heartbeats - // every 10s, so this gives a 5s grace window before forcing a reconnect. + // Server sends heartbeats every 10s, so this gives a 5s grace window before forcing a reconnect. // Reduced from 90s: with 90s a dead connection could linger for ~1.5 minutes. private static readonly HEARTBEAT_TIMEOUT_MS = 15_000 private static readonly RECONNECT_DELAY_MS = 250 diff --git a/packages/kilo-vscode/src/services/cli-backend/server-manager.ts b/packages/kilo-vscode/src/services/cli-backend/server-manager.ts index e63488e8b2..7e3c7dc82e 100644 --- a/packages/kilo-vscode/src/services/cli-backend/server-manager.ts +++ b/packages/kilo-vscode/src/services/cli-backend/server-manager.ts @@ -167,8 +167,7 @@ export class ServerManager { /** * Kill a process and its entire process group. - * On Unix, we send the signal to -pid (negative) to reach the whole group, - * mirroring the desktop app's ProcessGroup::leader() + start_kill() pattern. + * On Unix, we send the signal to -pid (negative) to reach the whole group. * On Windows, process.kill() on the child handle is sufficient. */ private static killProcess(proc: ChildProcess, signal: NodeJS.Signals = "SIGTERM"): void { @@ -197,8 +196,7 @@ export class ServerManager { console.log("[Kilo New] ServerManager: 🔴 Disposing — sending SIGTERM to process group, PID:", proc.pid) ServerManager.killProcess(proc, "SIGTERM") - // SIGKILL fallback after 5s: mirrors the desktop app going straight to - // start_kill(). Ensures the process tree dies even if SIGTERM is ignored + // SIGKILL fallback after 5s. Ensures the process tree dies even if SIGTERM is ignored // or Instance.disposeAll() hangs past the serve.ts shutdown timeout. const timer = setTimeout(() => { if (proc.exitCode === null) { diff --git a/packages/kilo-vscode/tests/unit/local-diff.test.ts b/packages/kilo-vscode/tests/unit/local-diff.test.ts index fdcfefede1..8e65718216 100644 --- a/packages/kilo-vscode/tests/unit/local-diff.test.ts +++ b/packages/kilo-vscode/tests/unit/local-diff.test.ts @@ -52,7 +52,7 @@ async function withRepo(run: (dir: string, base: string) => Promise): Prom describe("generatedLike", () => { it("matches files in ignored folders", () => { expect(generatedLike("node_modules/foo.js")).toBe(true) - expect(generatedLike("packages/app/node_modules/foo/index.js")).toBe(true) + expect(generatedLike("packages/opencode/node_modules/foo/index.js")).toBe(true) expect(generatedLike("dist/bundle.js")).toBe(true) expect(generatedLike("build/out.js")).toBe(true) expect(generatedLike(".git/HEAD")).toBe(true) diff --git a/packages/kilo-vscode/webview-ui/agent-manager/terminal/TerminalTab.tsx b/packages/kilo-vscode/webview-ui/agent-manager/terminal/TerminalTab.tsx index 6bfd96b894..aa1aec4ad0 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/terminal/TerminalTab.tsx +++ b/packages/kilo-vscode/webview-ui/agent-manager/terminal/TerminalTab.tsx @@ -70,11 +70,8 @@ function cssVar(name: string, fallback: string): string { * that's the signal VS Code uses to flip `vscode-light` ↔ `vscode-dark` * / `vscode-high-contrast`. * - * Matches the intent of opencode desktop's - * `packages/app/src/components/terminal.tsx:236-255` approach (memo on - * theme mode + `setOptionIfSupported(term, "theme", colors)`), just - * driven by a MutationObserver because VS Code is the source of truth - * here rather than their own Solid theme signal. + * Driven by a MutationObserver because VS Code is the source of truth here + * rather than a Solid theme signal. */ function readTheme() { return { diff --git a/packages/kilo-vscode/webview-ui/src/context/session.tsx b/packages/kilo-vscode/webview-ui/src/context/session.tsx index 2227815500..f0e6a538e1 100644 --- a/packages/kilo-vscode/webview-ui/src/context/session.tsx +++ b/packages/kilo-vscode/webview-ui/src/context/session.tsx @@ -1503,7 +1503,6 @@ export const SessionProvider: ParentComponent = (props) => { }) } - // Matches desktop app's event-reducer.ts: message.removed handler. // Splices the message from the store and deletes its parts. function handleMessageRemoved(sessionID: string, messageID: string) { setStore("messages", sessionID, (msgs = []) => msgs.filter((m) => m.id !== messageID)) diff --git a/packages/kilo-vscode/webview-ui/src/hooks/usePromptHistory.ts b/packages/kilo-vscode/webview-ui/src/hooks/usePromptHistory.ts index 085e919e0f..b373d131f3 100644 --- a/packages/kilo-vscode/webview-ui/src/hooks/usePromptHistory.ts +++ b/packages/kilo-vscode/webview-ui/src/hooks/usePromptHistory.ts @@ -1,10 +1,9 @@ /** * Prompt history navigation hook. * Arrow Up/Down at cursor boundaries cycles through previously sent prompts, - * matching the behavior of the CLI TUI and the desktop app. + * matching the behavior of the CLI TUI. * - * Entries persist via localStorage (same pattern as the desktop app's - * Persist.global), surviving webview hide/show cycles. + * Entries persist via localStorage, surviving webview hide/show cycles. */ import { createSignal } from "solid-js" diff --git a/packages/script/tests/check-opencode-annotations.test.ts b/packages/script/tests/check-opencode-annotations.test.ts index 4e992954d9..93f7464de9 100644 --- a/packages/script/tests/check-opencode-annotations.test.ts +++ b/packages/script/tests/check-opencode-annotations.test.ts @@ -8,9 +8,6 @@ const SCOPES = [ "packages/opencode", "packages/extensions", "packages/ui", - "packages/app", - "packages/desktop", - "packages/desktop-electron", "packages/shared", "packages/script", "packages/storybook", @@ -178,9 +175,6 @@ describe("isExempt", () => { ["packages/opencode/src/config/config.ts", false], ["packages/opencode/src/indexing/search-service.ts", false], ["packages/ui/src/components/icon.tsx", false], - ["packages/app/src/index.ts", false], - ["packages/desktop/src/main.ts", false], - ["packages/desktop-electron/src/main/index.ts", false], ["sdks/vscode/src/extension.ts", false], ["packages/extensions/zed/extension.toml", false], ["github/script/release", false], @@ -199,9 +193,6 @@ describe("isChecked", () => { const cases: Array<[string, boolean]> = [ ["packages/opencode/src/index.ts", true], ["packages/ui/src/components/icon.tsx", true], - ["packages/app/src/index.ts", true], - ["packages/desktop/src/main.ts", true], - ["packages/desktop-electron/src/main/index.ts", true], ["sdks/vscode/src/extension.ts", true], ["packages/extensions/zed/extension.toml", true], ["packages/shared/src/index.ts", true], diff --git a/packages/ui/src/theme/desktop-theme.schema.json b/packages/ui/src/theme/desktop-theme.schema.json index 36f4c2c991..b29591a63b 100644 --- a/packages/ui/src/theme/desktop-theme.schema.json +++ b/packages/ui/src/theme/desktop-theme.schema.json @@ -1,8 +1,8 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://opencode.ai/desktop-theme.json", - "title": "OpenCode Desktop Theme", - "description": "A theme definition for the OpenCode desktop application", + "title": "OpenCode UI Theme", + "description": "A theme definition for OpenCode UI components", "type": "object", "required": ["name", "id", "light", "dark"], "properties": { diff --git a/script/check-opencode-annotations.ts b/script/check-opencode-annotations.ts index 53ab14b7c9..ba58596066 100644 --- a/script/check-opencode-annotations.ts +++ b/script/check-opencode-annotations.ts @@ -39,9 +39,6 @@ const SCOPES = [ "packages/opencode", "packages/extensions", "packages/ui", - "packages/app", - "packages/desktop", - "packages/desktop-electron", "packages/shared", "packages/script", "packages/storybook", diff --git a/script/publish.ts b/script/publish.ts index 7350d048ca..8ab9f96e95 100755 --- a/script/publish.ts +++ b/script/publish.ts @@ -92,8 +92,6 @@ if (Script.release) { // kilocode_change end // kilocode_change start - // await import(`../packages/desktop/scripts/finalize-latest-json.ts`) - // await import(`../packages/desktop-electron/scripts/finalize-latest-yml.ts`) // kilocode_change end // kilocode_change start - mark prerelease GitHub releases accordingly diff --git a/script/raw-changelog.ts b/script/raw-changelog.ts index 6c9cd7b4f0..961c288ee4 100644 --- a/script/raw-changelog.ts +++ b/script/raw-changelog.ts @@ -31,12 +31,10 @@ const team = [ .then((x) => x.filter((x) => x && !x.startsWith("#")))), ...bot, ] -const order = ["Core", "TUI", "Desktop", "SDK", "Extensions"] as const +const order = ["Core", "TUI", "SDK", "Extensions"] as const const sections = { core: "Core", tui: "TUI", - app: "Desktop", - tauri: "Desktop", sdk: "SDK", plugin: "SDK", "extensions/zed": "Extensions", @@ -75,7 +73,7 @@ async function diff(base: string, head: string) { } function section(areas: Set) { - const priority = ["core", "tui", "app", "tauri", "sdk", "plugin", "extensions/zed", "extensions/vscode", "github"] + const priority = ["core", "tui", "sdk", "plugin", "extensions/zed", "extensions/vscode", "github"] for (const area of priority) { if (areas.has(area)) return sections[area as keyof typeof sections] } @@ -116,7 +114,7 @@ async function commits(from: string, to: string) { } const log = - await $`git log ${base}..${head} --format=%H -- packages/opencode packages/sdk packages/plugin packages/desktop packages/app sdks/vscode packages/extensions github`.text() + await $`git log ${base}..${head} --format=%H -- packages/opencode packages/sdk packages/plugin sdks/vscode packages/extensions github`.text() const list: Commit[] = [] for (const hash of log.split("\n").filter(Boolean)) { @@ -130,8 +128,6 @@ async function commits(from: string, to: string) { for (const file of diff.split("\n").filter(Boolean)) { if (file.startsWith("packages/opencode/src/cli/cmd/")) areas.add("tui") else if (file.startsWith("packages/opencode/")) areas.add("core") - else if (file.startsWith("packages/desktop/src-tauri/")) areas.add("tauri") - else if (file.startsWith("packages/desktop/") || file.startsWith("packages/app/")) areas.add("app") else if (file.startsWith("packages/sdk/") || file.startsWith("packages/plugin/")) areas.add("sdk") else if (file.startsWith("packages/extensions/")) areas.add("extensions/zed") else if (file.startsWith("sdks/vscode/") || file.startsWith("github/")) areas.add("extensions/vscode") diff --git a/script/upstream/README.md b/script/upstream/README.md index 9a664ecbb8..075171cdb7 100644 --- a/script/upstream/README.md +++ b/script/upstream/README.md @@ -46,7 +46,6 @@ bun run merge.ts --version v1.1.50 --base-branch catrielmuller/kilo-opencode-v1. | `transforms/skip-files.ts` | Skip/remove files that shouldn't exist in Kilo | | `transforms/transform-i18n.ts` | Transform i18n files with Kilo branding | | `transforms/transform-take-theirs.ts` | Take upstream + apply Kilo branding for branding-only files | -| `transforms/transform-tauri.ts` | Transform Tauri/Desktop config files | | `transforms/transform-package-json.ts` | Enhanced package.json with Kilo dependency injection | | `transforms/transform-scripts.ts` | Transform script files with GitHub API references | | `transforms/transform-extensions.ts` | Transform extension files (Zed, etc.) | @@ -82,7 +81,6 @@ The merge automation follows this process, applying **all transformations BEFORE - Preserve Kilo's versions - Transform i18n files with Kilo branding - Transform branding-only files (UI components, configs) - - Transform Tauri/Desktop config files - Transform package.json files (names, deps, Kilo injections) - Transform script files (GitHub API references) - Transform extension files (Zed, etc.) @@ -132,19 +130,10 @@ Configuration is defined in `utils/config.ts`: // Files to take upstream + apply Kilo branding transforms takeTheirsAndTransform: [ - "packages/app/src/components/**/*.tsx", - "packages/app/src/context/**/*.tsx", "packages/ui/src/**/*.tsx", // ... ], - // Tauri/Desktop config files - tauriFiles: [ - "packages/desktop/src-tauri/*.json", - "packages/desktop/src-tauri/src/*.rs", - // ... - ], - // Kilo-specific directories (preserved) kiloDirectories: [ "packages/opencode/src/kilocode", @@ -168,11 +157,10 @@ The following transforms are applied to the opencode branch before merging: 3. **Versions** - Preserve Kilo's version numbers 4. **i18n files** - OpenCode -> Kilo in user-visible strings 5. **Branding files** - UI components, configs with branding only -6. **Tauri configs** - Desktop app identifiers, names -7. **package.json** - Names, dependencies, Kilo injections -8. **Scripts** - GitHub API references -9. **Extensions** - Zed, etc. -10. **Web/docs** - Documentation files +6. **package.json** - Names, dependencies, Kilo injections +7. **Scripts** - GitHub API references +8. **Extensions** - Zed, etc. +9. **Web/docs** - Documentation files ### Post-Merge Strategies @@ -181,8 +169,7 @@ After merging, any remaining conflicts are handled based on file type: | File Type | Strategy | Description | |---|---|---| | i18n files | `i18n-transform` | Take upstream, apply Kilo branding | -| App components | `take-theirs-transform` | Take upstream, apply branding (no logic changes) | -| Tauri configs | `tauri-transform` | Take upstream, transform identifiers/names | +| UI components | `take-theirs-transform` | Take upstream, apply branding (no logic changes) | | package.json | `package-transform` | Take upstream, transform names, inject Kilo deps | | Script files | `script-transform` | Take upstream, transform GitHub references | | Extensions | `extension-transform` | Take upstream, apply branding | diff --git a/script/upstream/fix-kilocode-markers.ts b/script/upstream/fix-kilocode-markers.ts index 0011583939..7299bedd0c 100644 --- a/script/upstream/fix-kilocode-markers.ts +++ b/script/upstream/fix-kilocode-markers.ts @@ -18,7 +18,6 @@ import { error, header, info, success, warn } from "./utils/logger" import { transformI18nContent } from "./transforms/transform-i18n" import { applyBrandingTransforms } from "./transforms/transform-take-theirs" import { applyScriptTransforms } from "./transforms/transform-scripts" -import { applyTauriTransforms } from "./transforms/transform-tauri" import { applyExtensionTransforms } from "./transforms/transform-extensions" import { applyWebTransforms } from "./transforms/transform-web" import { applyPackageNameTransforms } from "./transforms/package-names" @@ -149,8 +148,7 @@ async function translate(file: string, text: string) { const script = applyScriptTransforms(names).result const branded = applyBrandingTransforms(script).result const i18n = transformI18nContent(branded).result - const tauri = applyTauriTransforms(i18n, file).result - const ext = applyExtensionTransforms(tauri, file).result + const ext = applyExtensionTransforms(i18n, file).result const web = applyWebTransforms(ext).result return workflow(file, web) diff --git a/script/upstream/index.ts b/script/upstream/index.ts index c0c39cbe9a..e823b69c7e 100644 --- a/script/upstream/index.ts +++ b/script/upstream/index.ts @@ -35,14 +35,6 @@ export { matchesPattern, } from "./transforms/transform-take-theirs" -export { - transformConflictedTauri, - transformTauriFile, - transformAllTauri, - isTauriFile, - applyTauriTransforms, -} from "./transforms/transform-tauri" - export { transformConflictedPackageJson, transformPackageJson, diff --git a/script/upstream/merge.ts b/script/upstream/merge.ts index 01affc03ca..49b81da7ac 100644 --- a/script/upstream/merge.ts +++ b/script/upstream/merge.ts @@ -25,31 +25,18 @@ import * as logger from "./utils/logger" import * as version from "./utils/version" import * as report from "./utils/report" import * as worktree from "./utils/worktree" -import { defaultConfig, loadConfig, type MergeConfig } from "./utils/config" +import { loadConfig } from "./utils/config" import { transformAll as transformPackageNames } from "./transforms/package-names" import { preserveAllVersions } from "./transforms/preserve-versions" import { keepOursFiles, resetToOurs } from "./transforms/keep-ours" -import { skipFiles, skipSpecificFiles } from "./transforms/skip-files" +import { skipFiles } from "./transforms/skip-files" import { transformConflictedI18n, transformAllI18n } from "./transforms/transform-i18n" // New transforms for auto-resolving more conflict types -import { - transformConflictedTakeTheirs, - shouldTakeTheirs, - transformAllTakeTheirs, -} from "./transforms/transform-take-theirs" -import { transformConflictedTauri, isTauriFile, transformAllTauri } from "./transforms/transform-tauri" -import { - transformConflictedPackageJson, - isPackageJson, - transformAllPackageJson, -} from "./transforms/transform-package-json" -import { transformConflictedScripts, isScriptFile, transformAllScripts } from "./transforms/transform-scripts" -import { - transformConflictedExtensions, - isExtensionFile, - transformAllExtensions, -} from "./transforms/transform-extensions" -import { transformConflictedWeb, isWebFile, transformAllWeb } from "./transforms/transform-web" +import { transformConflictedTakeTheirs, transformAllTakeTheirs } from "./transforms/transform-take-theirs" +import { transformConflictedPackageJson, transformAllPackageJson } from "./transforms/transform-package-json" +import { transformConflictedScripts, transformAllScripts } from "./transforms/transform-scripts" +import { transformConflictedExtensions, transformAllExtensions } from "./transforms/transform-extensions" +import { transformConflictedWeb, transformAllWeb } from "./transforms/transform-web" import { resolveLockFileConflicts, regenerateLockFiles } from "./transforms/lock-files" interface MergeOptions { @@ -470,14 +457,6 @@ async function main() { logger.success(`Transformed ${brandingCount} files with Kilo branding`) } - // 6e. Transform Tauri/Desktop config files - logger.info("Transforming Tauri/Desktop config files...") - const tauriPreResults = await transformAllTauri({ dryRun: false, verbose: options.verbose }) - const tauriPreCount = tauriPreResults.filter((r) => r.action === "transformed" && r.replacements > 0).length - if (tauriPreCount > 0) { - logger.success(`Transformed ${tauriPreCount} Tauri config files`) - } - // 6f. Transform package.json files (names, deps, Kilo injections) logger.info("Transforming package.json files...") const pkgPreResults = await transformAllPackageJson({ dryRun: false, verbose: options.verbose }) @@ -629,26 +608,6 @@ async function main() { } } - // Transform Tauri files - conflictedFiles = await git.getConflictedFiles() - if (conflictedFiles.length > 0) { - const tauriResults = await transformConflictedTauri(conflictedFiles, { - dryRun: false, - verbose: options.verbose, - }) - const tauriCount = tauriResults.filter((r) => r.action === "transformed").length - if (tauriCount > 0) { - logger.success(`Auto-resolved ${tauriCount} Tauri conflicts`) - } - const tauriFlagged = tauriResults.filter((r) => r.action === "flagged").map((r) => r.file) - if (tauriFlagged.length > 0) { - logger.warn( - `${tauriFlagged.length} Tauri file(s) have kilocode_change markers — flagged for manual resolution`, - ) - flaggedFiles.push(...tauriFlagged) - } - } - // Transform package.json files conflictedFiles = await git.getConflictedFiles() if (conflictedFiles.length > 0) { diff --git a/script/upstream/transforms/lock-files.ts b/script/upstream/transforms/lock-files.ts index 08e18f74cb..f1c2ae84c8 100644 --- a/script/upstream/transforms/lock-files.ts +++ b/script/upstream/transforms/lock-files.ts @@ -121,28 +121,6 @@ export async function regenerateLockFiles(options: LockFileOptions = {}): Promis } } - // Check for Cargo.lock in Tauri package - const cargoLockPath = "packages/desktop/src-tauri/Cargo.lock" - const hasCargoLock = await Bun.file(cargoLockPath).exists() - - if (hasCargoLock) { - if (options.dryRun) { - info("[DRY-RUN] Would regenerate Cargo.lock via 'cargo generate-lockfile'") - results.push({ file: cargoLockPath, action: "regenerated", dryRun: true }) - } else { - info("Regenerating Cargo.lock...") - const result = await $`cargo generate-lockfile`.cwd("packages/desktop/src-tauri").quiet().nothrow() - if (result.exitCode === 0) { - success("Regenerated Cargo.lock") - results.push({ file: cargoLockPath, action: "regenerated", dryRun: false }) - } else { - // Cargo might not be installed, just warn - warn(`Could not regenerate Cargo.lock (cargo may not be installed): ${result.stderr.toString()}`) - results.push({ file: cargoLockPath, action: "skipped", dryRun: false }) - } - } - } - // Note about nix/hashes.json - regenerated by CI, not locally const nixHashesPath = "nix/hashes.json" const hasNixHashes = await Bun.file(nixHashesPath).exists() diff --git a/script/upstream/transforms/skip-files.test.ts b/script/upstream/transforms/skip-files.test.ts index e3b1229c02..e31d9a9689 100644 --- a/script/upstream/transforms/skip-files.test.ts +++ b/script/upstream/transforms/skip-files.test.ts @@ -7,8 +7,8 @@ test("matches hosted package glob paths", () => { expect(shouldSkip("packages/console/app/package.json", ["packages/console/**"])).toBe(true) }) -test("does not match sibling package glob paths", () => { - expect(shouldSkip("packages/app/package.json", ["packages/web/**"])).toBe(false) +test("matches removed app package glob paths", () => { + expect(shouldSkip("packages/app/package.json", ["packages/app/**"])).toBe(true) }) test("matches extension glob paths", () => { diff --git a/script/upstream/transforms/transform-i18n.ts b/script/upstream/transforms/transform-i18n.ts index 9af27f3f80..a5769c7990 100644 --- a/script/upstream/transforms/transform-i18n.ts +++ b/script/upstream/transforms/transform-i18n.ts @@ -10,7 +10,6 @@ * String replacement rules: * - opencode.ai -> kilo.ai (domain) * - app.opencode.ai -> app.kilo.ai (app domain) - * - OpenCode Desktop -> Kilo Desktop (desktop app name) * - OpenCode -> Kilo (product name in user-visible text) * - opencode upgrade -> kilo upgrade (CLI commands) * - npx opencode -> npx kilo (CLI invocation) @@ -74,13 +73,6 @@ const I18N_REPLACEMENTS: StringReplacement[] = [ description: "Main domain (excluding zen)", }, - // Product name (specific phrases first) - { - pattern: /OpenCode Desktop/g, - replacement: "Kilo Desktop", - description: "Desktop app name", - }, - // CLI commands (be careful with order) { pattern: /npx opencode(?!\w)/g, diff --git a/script/upstream/transforms/transform-package-json.ts b/script/upstream/transforms/transform-package-json.ts index 685cecf0eb..bbc812ea95 100644 --- a/script/upstream/transforms/transform-package-json.ts +++ b/script/upstream/transforms/transform-package-json.ts @@ -186,10 +186,6 @@ const KILO_DEPENDENCIES: Record> = { "@kilocode/kilo-gateway": "workspace:*", "@kilocode/kilo-telemetry": "workspace:*", }, - // packages/app/package.json needs these - "packages/app/package.json": { - "@kilocode/kilo-i18n": "workspace:*", - }, } // Kilo-specific bin entries to set on specific packages diff --git a/script/upstream/transforms/transform-take-theirs.ts b/script/upstream/transforms/transform-take-theirs.ts index 0fd39f9c41..d2a144ac02 100644 --- a/script/upstream/transforms/transform-take-theirs.ts +++ b/script/upstream/transforms/transform-take-theirs.ts @@ -61,13 +61,6 @@ const BRANDING_REPLACEMENTS: BrandingReplacement[] = [ description: "Main domain (excluding zen)", }, - // Product name (specific phrases first) - { - pattern: /OpenCode Desktop/g, - replacement: "Kilo Desktop", - description: "Desktop app name", - }, - // CLI commands { pattern: /npx opencode(?!\w)/g, @@ -133,16 +126,6 @@ const BRANDING_REPLACEMENTS: BrandingReplacement[] = [ }, ] -// Patterns that should NOT be replaced (preserved as-is) -const PRESERVE_PATTERNS = [ - /opencode\.json/g, // Config filename - /\.opencode\//g, // Directory name - /\.opencode`/g, // Directory name in template strings - /"\.opencode"/g, // Directory name in quotes - /'\.opencode'/g, // Directory name in single quotes - /\/\/\s*kilocode_change/g, // Already has marker -] - /** * Check if a file matches any of the patterns */ @@ -169,16 +152,6 @@ export function applyBrandingTransforms(content: string, verbose = false): { res continue } - // Check if line has preserve patterns - let hasPreserve = false - for (const pattern of PRESERVE_PATTERNS) { - pattern.lastIndex = 0 - if (pattern.test(line)) { - hasPreserve = true - pattern.lastIndex = 0 - } - } - let result = line let count = 0 diff --git a/script/upstream/transforms/transform-tauri.ts b/script/upstream/transforms/transform-tauri.ts deleted file mode 100644 index a5608e00fc..0000000000 --- a/script/upstream/transforms/transform-tauri.ts +++ /dev/null @@ -1,363 +0,0 @@ -#!/usr/bin/env bun -/** - * Transform Tauri/Desktop config files with Kilo branding - * - * This script handles Tauri configuration files (JSON, TOML, Rust) by: - * 1. Taking upstream's version as the base - * 2. Applying predictable Kilo branding transforms - * - * Handles: - * - tauri.conf.json / tauri.prod.conf.json - * - Cargo.toml / Cargo.lock - * - Rust source files (*.rs) - */ - -import { $ } from "bun" -import { info, success, warn, debug } from "../utils/logger" -import { defaultConfig } from "../utils/config" -import { oursHasKilocodeChanges } from "../utils/git" - -export interface TauriTransformResult { - file: string - action: "transformed" | "skipped" | "failed" | "flagged" - replacements: number - dryRun: boolean -} - -export interface TauriTransformOptions { - dryRun?: boolean - verbose?: boolean -} - -interface TauriReplacement { - pattern: RegExp - replacement: string - description: string - fileTypes?: string[] // Only apply to these file extensions -} - -// Tauri-specific replacements -const TAURI_REPLACEMENTS: TauriReplacement[] = [ - // JSON config - product names - { - pattern: /"productName":\s*"OpenCode[^"]*"/g, - replacement: '"productName": "Kilo"', - description: "Product name in JSON", - fileTypes: [".json"], - }, - { - pattern: /"title":\s*"OpenCode[^"]*"/g, - replacement: '"title": "Kilo"', - description: "Title in JSON", - fileTypes: [".json"], - }, - - // JSON config - identifiers - { - pattern: /ai\.opencode\.desktop\.dev/g, - replacement: "ai.kilo.desktop.dev", - description: "Dev identifier", - }, - { - pattern: /ai\.opencode\.desktop/g, - replacement: "ai.kilo.desktop", - description: "Prod identifier", - }, - - // Binary names - { - pattern: /opencode-cli/g, - replacement: "kilo-cli", - description: "CLI binary name", - }, - { - pattern: /"mainBinaryName":\s*"[Oo]pen[Cc]ode"/g, - replacement: '"mainBinaryName": "Kilo"', - description: "Main binary name", - fileTypes: [".json"], - }, - - // GitHub references - { - pattern: /github\.com\/anomalyco\/opencode/g, - replacement: "github.com/Kilo-Org/kilocode", - description: "GitHub URL", - }, - { - pattern: /anomalyco\/opencode/g, - replacement: "Kilo-Org/kilocode", - description: "GitHub repo", - }, - - // Cargo.toml specific - { - pattern: /name\s*=\s*"opencode-desktop"/g, - replacement: 'name = "kilo-desktop"', - description: "Cargo package name", - fileTypes: [".toml"], - }, - { - pattern: /authors\s*=\s*\["OpenCode"\]/g, - replacement: 'authors = ["Kilo"]', - description: "Cargo authors", - fileTypes: [".toml"], - }, - { - pattern: /name\s*=\s*"opencode_lib"/g, - replacement: 'name = "kilo_lib"', - description: "Cargo lib name", - fileTypes: [".toml"], - }, - - // Rust source specific - { - pattern: /opencode\.db/g, - replacement: "kilo.db", - description: "Database filename", - fileTypes: [".rs"], - }, - { - pattern: /opencode\.settings\.dat/g, - replacement: "kilo.settings.dat", - description: "Settings file name", - fileTypes: [".rs"], - }, - { - pattern: /"\.opencode\/bin"/g, - replacement: '".kilo/bin"', - description: "CLI install dir", - fileTypes: [".rs"], - }, - { - pattern: /CLI_BINARY_NAME\s*=\s*"opencode"/g, - replacement: 'CLI_BINARY_NAME = "kilo"', - description: "CLI binary constant", - fileTypes: [".rs"], - }, - { - pattern: /opencode_lib::run/g, - replacement: "kilo_lib::run", - description: "Lib run call", - fileTypes: [".rs"], - }, - { - pattern: /killall opencode-cli/g, - replacement: "killall kilo-cli", - description: "Killall command", - fileTypes: [".rs"], - }, - - // Domain - { - pattern: /opencode\.ai/g, - replacement: "kilo.ai", - description: "Domain", - }, - - // Environment variables (exclude OPENCODE_API_KEY) - { - pattern: /OPENCODE_(?!API_KEY)([A-Z_]+)/g, - replacement: "KILO_$1", - description: "Env variable", - fileTypes: [".rs"], - }, - { - pattern: /__OPENCODE__/g, - replacement: "__KILO__", - description: "Window global", - fileTypes: [".rs", ".tsx"], - }, - { - pattern: /OPENCODE_PORT/g, - replacement: "KILO_PORT", - description: "Port env var", - }, -] - -/** - * Check if a file is a Tauri config file - */ -export function isTauriFile(file: string): boolean { - const patterns = defaultConfig.tauriFiles - - return patterns.some((pattern) => { - const regex = new RegExp("^" + pattern.replace(/\./g, "\\.").replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*") + "$") - return regex.test(file) - }) -} - -/** - * Get file extension - */ -function getExtension(file: string): string { - const match = file.match(/\.[^.]+$/) - return match ? match[0] : "" -} - -/** - * Apply Tauri-specific transforms to content - */ -export function applyTauriTransforms( - content: string, - file: string, - verbose = false, -): { result: string; replacements: number } { - const ext = getExtension(file) - let result = content - let total = 0 - - for (const { pattern, replacement, description, fileTypes } of TAURI_REPLACEMENTS) { - // Skip if this replacement is for specific file types and doesn't match - if (fileTypes && !fileTypes.includes(ext)) { - continue - } - - pattern.lastIndex = 0 - - if (pattern.test(result)) { - pattern.lastIndex = 0 - const before = result - result = result.replace(pattern, replacement) - - if (before !== result) { - total++ - if (verbose) debug(` ${description}`) - } - } - } - - return { result, replacements: total } -} - -/** - * Transform a single Tauri file - */ -export async function transformTauriFile( - file: string, - options: TauriTransformOptions = {}, -): Promise { - if (options.dryRun) { - info(`[DRY-RUN] Would transform Tauri file: ${file}`) - return { file, action: "transformed", replacements: 0, dryRun: true } - } - - // If our version has kilocode_change markers, flag for manual resolution - if (await oursHasKilocodeChanges(file)) { - warn(`${file} has kilocode_change markers — skipping auto-transform, needs manual resolution`) - return { file, action: "flagged", replacements: 0, dryRun: false } - } - - try { - // Take upstream's version first - await $`git checkout --theirs ${file}`.quiet().nothrow() - await $`git add ${file}`.quiet().nothrow() - - // Read content - const content = await Bun.file(file).text() - - // Apply transforms - const { result, replacements } = applyTauriTransforms(content, file, options.verbose) - - // Write back if changed - if (replacements > 0) { - await Bun.write(file, result) - await $`git add ${file}`.quiet().nothrow() - } - - success(`Transformed Tauri file ${file}: ${replacements} replacements`) - return { file, action: "transformed", replacements, dryRun: false } - } catch (err) { - warn(`Failed to transform Tauri file ${file}: ${err}`) - return { file, action: "failed", replacements: 0, dryRun: false } - } -} - -/** - * Transform conflicted Tauri files - */ -export async function transformConflictedTauri( - files: string[], - options: TauriTransformOptions = {}, -): Promise { - const results: TauriTransformResult[] = [] - - for (const file of files) { - if (!isTauriFile(file)) { - debug(`Skipping ${file} - not a Tauri file`) - results.push({ file, action: "skipped", replacements: 0, dryRun: options.dryRun ?? false }) - continue - } - - const result = await transformTauriFile(file, options) - results.push(result) - } - - return results -} - -/** - * Transform all Tauri files (pre-merge, on opencode branch) - */ -export async function transformAllTauri(options: TauriTransformOptions = {}): Promise { - const { Glob } = await import("bun") - const results: TauriTransformResult[] = [] - const patterns = defaultConfig.tauriFiles - - for (const pattern of patterns) { - const glob = new Glob(pattern) - - for await (const path of glob.scan({ absolute: false })) { - const file = Bun.file(path) - if (!(await file.exists())) continue - - try { - const content = await file.text() - const { result, replacements } = applyTauriTransforms(content, path, options.verbose) - - if (replacements > 0 && !options.dryRun) { - await Bun.write(path, result) - success(`Transformed Tauri ${path}: ${replacements} replacements`) - } else if (options.dryRun && replacements > 0) { - info(`[DRY-RUN] Would transform Tauri ${path}: ${replacements} replacements`) - } - - results.push({ file: path, action: "transformed", replacements, dryRun: options.dryRun ?? false }) - } catch (err) { - warn(`Failed to transform Tauri ${path}: ${err}`) - results.push({ file: path, action: "failed", replacements: 0, dryRun: options.dryRun ?? false }) - } - } - } - - return results -} - -// CLI entry point -if (import.meta.main) { - const args = process.argv.slice(2) - const dryRun = args.includes("--dry-run") - const verbose = args.includes("--verbose") - - const files = args.filter((a) => !a.startsWith("--")) - - if (files.length === 0) { - info("Usage: transform-tauri.ts [--dry-run] [--verbose] ...") - process.exit(1) - } - - if (dryRun) { - info("Running in dry-run mode") - } - - const results = await transformConflictedTauri(files, { dryRun, verbose }) - - const transformed = results.filter((r) => r.action === "transformed") - const total = results.reduce((sum, r) => sum + r.replacements, 0) - - console.log() - success(`Transformed ${transformed.length} Tauri files with ${total} replacements`) - - if (dryRun) { - info("Run without --dry-run to apply changes") - } -} diff --git a/script/upstream/transforms/transform-web.ts b/script/upstream/transforms/transform-web.ts index e7d368560c..b6d0b6877e 100644 --- a/script/upstream/transforms/transform-web.ts +++ b/script/upstream/transforms/transform-web.ts @@ -56,11 +56,6 @@ const WEB_REPLACEMENTS: WebReplacement[] = [ }, // Product names - { - pattern: /OpenCode Desktop/g, - replacement: "Kilo Desktop", - description: "Desktop name", - }, { pattern: /\bOpenCode\b(?!\.json|\/| Zen)/g, replacement: "Kilo", diff --git a/script/upstream/utils/config.ts b/script/upstream/utils/config.ts index 1ce29e1d0d..d8dd0c020a 100644 --- a/script/upstream/utils/config.ts +++ b/script/upstream/utils/config.ts @@ -21,9 +21,6 @@ export interface MergeConfig { /** Files that should take upstream version and apply Kilo branding transforms */ takeTheirsAndTransform: string[] - /** Tauri/Desktop config files with predictable branding patterns */ - tauriFiles: string[] - /** Script files with GitHub API references */ scriptFiles: string[] @@ -142,6 +139,9 @@ export const defaultConfig: MergeConfig = { "packages/function/**", "packages/docs/**", "packages/identity/**", + "packages/app/**", + "packages/desktop/**", + "packages/desktop-electron/**", // GitHub Action - Kilo version is fully ported and complete "github/index.ts", "github/package.json", @@ -153,27 +153,9 @@ export const defaultConfig: MergeConfig = { // Files that should take upstream version and apply Kilo branding transforms // These are files with only branding differences, no logic changes takeTheirsAndTransform: [ - // App components with branding only - "packages/app/src/components/**/*.tsx", - "packages/app/src/context/**/*.tsx", - "packages/app/src/pages/**/*.tsx", // UI components "packages/ui/src/components/**/*.tsx", "packages/ui/src/context/**/*.tsx", - // Desktop TypeScript files (not Rust) - "packages/desktop/src/**/*.ts", - // E2E and test fixtures - "packages/app/e2e/**/*.ts", - "packages/app/script/**/*.ts", - ], - - // Tauri/Desktop config files with predictable branding patterns - tauriFiles: [ - "packages/desktop/src-tauri/tauri.conf.json", - "packages/desktop/src-tauri/tauri.prod.conf.json", - "packages/desktop/src-tauri/Cargo.toml", - "packages/desktop/src-tauri/Cargo.lock", - "packages/desktop/src-tauri/src/*.rs", ], // Script files with GitHub API references @@ -228,7 +210,7 @@ export const defaultConfig: MergeConfig = { originRemote: "origin", // i18n translation files that need Kilo branding transforms - i18nPatterns: ["packages/*/src/i18n/*.ts", "packages/desktop/src/i18n/*.ts"], + i18nPatterns: ["packages/*/src/i18n/*.ts"], } export function loadConfig(overrides?: Partial): MergeConfig { diff --git a/script/upstream/utils/report.test.ts b/script/upstream/utils/report.test.ts index e74f889c44..d0dc3963d8 100644 --- a/script/upstream/utils/report.test.ts +++ b/script/upstream/utils/report.test.ts @@ -11,7 +11,7 @@ test("recommends skip for hosted package globs", () => { }) test("does not recommend skip for unrelated packages", () => { - expect(getRecommendation("packages/app/package.json", [], ["packages/web/**"]).recommendation).toBe( + expect(getRecommendation("packages/ui/package.json", [], ["packages/web/**"]).recommendation).toBe( "package-transform", ) }) diff --git a/script/upstream/utils/report.ts b/script/upstream/utils/report.ts index 787361fd39..41c42ff0c2 100644 --- a/script/upstream/utils/report.ts +++ b/script/upstream/utils/report.ts @@ -20,7 +20,7 @@ export interface ConflictReport { export interface ConflictFile { path: string - type: "markdown" | "package" | "code" | "config" | "i18n" | "tauri" | "script" | "extension" | "web" | "other" + type: "markdown" | "package" | "code" | "config" | "i18n" | "script" | "extension" | "web" | "other" recommendation: | "keep-ours" | "keep-theirs" @@ -29,7 +29,6 @@ export interface ConflictFile { | "skip" | "i18n-transform" | "take-theirs-transform" - | "tauri-transform" | "package-transform" | "script-transform" | "extension-transform" @@ -45,16 +44,6 @@ function isI18nFile(path: string): boolean { return /packages\/[^/]+\/src\/i18n\/[^/]+\.ts$/.test(path) && !path.endsWith("/index.ts") } -/** - * Check if a file is a Tauri/Desktop config file - */ -function isTauriFile(path: string): boolean { - return ( - path.includes("packages/desktop/src-tauri/") && - (path.endsWith(".json") || path.endsWith(".toml") || path.endsWith(".rs") || path.endsWith(".lock")) - ) -} - /** * Check if a file is a script file */ @@ -80,17 +69,7 @@ function isWebFile(path: string): boolean { * Check if a file should use take-theirs + transform strategy */ function shouldTakeTheirsTransform(path: string): boolean { - const patterns = [ - /^packages\/app\/src\/components\/.*\.tsx$/, - /^packages\/app\/src\/context\/.*\.tsx$/, - /^packages\/app\/src\/pages\/.*\.tsx$/, - /^packages\/ui\/src\/.*\.tsx$/, - /^packages\/desktop\/src\/.*\.ts$/, - /^packages\/app\/e2e\/.*\.ts$/, - /^packages\/app\/script\/.*\.ts$/, - /^github\/index\.ts$/, - /^packages\/slack\/src\/.*\.ts$/, - ] + const patterns = [/^packages\/ui\/src\/.*\.tsx$/, /^github\/index\.ts$/, /^packages\/slack\/src\/.*\.ts$/] return patterns.some((p) => p.test(path)) } @@ -99,7 +78,6 @@ function shouldTakeTheirsTransform(path: string): boolean { */ export function classifyFile(path: string): ConflictFile["type"] { if (isI18nFile(path)) return "i18n" - if (isTauriFile(path)) return "tauri" if (isScriptFile(path)) return "script" if (isExtensionFile(path)) return "extension" if (isWebFile(path)) return "web" @@ -194,17 +172,6 @@ export function getRecommendation( recommendation: "i18n-transform", reason: "i18n file: take upstream translations and apply Kilo branding", } - case "tauri": - if (currentContent?.includes("kilocode_change")) { - return { - recommendation: "manual", - reason: "Tauri config has kilocode_change markers — auto-transform skipped, needs manual review", - } - } - return { - recommendation: "tauri-transform", - reason: "Tauri config: take upstream and apply Kilo branding transforms", - } case "script": if (currentContent?.includes("kilocode_change")) { return { @@ -348,7 +315,6 @@ export function generateMarkdownReport(report: ConflictReport): string { "skip", "i18n-transform", "take-theirs-transform", - "tauri-transform", "package-transform", "script-transform", "extension-transform", @@ -367,7 +333,6 @@ export function generateMarkdownReport(report: ConflictReport): string { skip: "Skip (Auto-Remove)", "i18n-transform": "i18n Transform (Auto-Apply Kilo Branding)", "take-theirs-transform": "Take Upstream + Kilo Branding (Auto)", - "tauri-transform": "Tauri Config Transform (Auto)", "package-transform": "Package.json Transform (Auto)", "script-transform": "Script Transform (Auto)", "extension-transform": "Extension Transform (Auto)",