From b5213921c1fd0ac294557abd1dc44fe15420e009 Mon Sep 17 00:00:00 2001 From: marius-kilocode Date: Mon, 1 Jun 2026 16:58:26 +0200 Subject: [PATCH] fix: preserve Kilo identity after upstream merge --- packages/extensions/zed/extension.toml | 12 ++--- packages/kilo-docs/source-links.md | 2 + packages/opencode/bin/kilo | 6 ++- .../src/cli/cmd/run/footer.permission.tsx | 4 +- .../src/cli/cmd/run/permission.shared.ts | 4 +- packages/opencode/src/cli/cmd/run/tool.ts | 2 +- packages/opencode/src/cli/cmd/run/trace.ts | 2 +- .../src/cli/cmd/run/variant.shared.ts | 2 +- .../src/kilocode/server/httpapi/public.ts | 20 ++++++++ packages/opencode/src/tool/repo_clone.txt | 2 +- .../test/cli/run/permission.shared.test.ts | 4 +- .../test/kilocode/bin-tree-sitter-env.test.ts | 6 ++- .../test/server/httpapi-instance.test.ts | 4 +- script/check-forbidden-strings.ts | 3 ++ .../transforms/preserve-versions.test.ts | 37 ++++++++++++++ .../upstream/transforms/preserve-versions.ts | 51 ++++++++++++++----- 16 files changed, 128 insertions(+), 33 deletions(-) create mode 100644 script/upstream/transforms/preserve-versions.test.ts diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index aba2476b2c..f1f6586884 100644 --- a/packages/extensions/zed/extension.toml +++ b/packages/extensions/zed/extension.toml @@ -1,7 +1,7 @@ id = "kilo" name = "Kilo" description = "The open source coding agent." -version = "1.14.42" +version = "7.3.18" schema_version = 1 authors = ["Anomaly"] repository = "https://github.com/Kilo-Org/kilocode" @@ -11,26 +11,26 @@ name = "Kilo" icon = "./icons/opencode.svg" [agent_servers.opencode.targets.darwin-aarch64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v1.14.42/opencode-darwin-arm64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.18/opencode-darwin-arm64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.darwin-x86_64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v1.14.42/opencode-darwin-x64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.18/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v1.14.42/opencode-linux-arm64.tar.gz" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.18/opencode-linux-arm64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-x86_64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v1.14.42/opencode-linux-x64.tar.gz" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.18/opencode-linux-x64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.windows-x86_64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v1.14.42/opencode-windows-x64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.18/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/kilo-docs/source-links.md b/packages/kilo-docs/source-links.md index 2c26eb8918..0bb224440a 100644 --- a/packages/kilo-docs/source-links.md +++ b/packages/kilo-docs/source-links.md @@ -102,6 +102,7 @@ - + - @@ -131,6 +132,7 @@ - + - - diff --git a/packages/opencode/bin/kilo b/packages/opencode/bin/kilo index 3815df2fa5..bd5a5322fd 100755 --- a/packages/opencode/bin/kilo +++ b/packages/opencode/bin/kilo @@ -16,7 +16,8 @@ function configureTreeSitterResources(target) { } // kilocode_change end -function run(target, fallback) { // kilocode_change - preserve cached binary fallback +function run(target, fallback) { + // kilocode_change - preserve cached binary fallback configureTreeSitterResources(target) // kilocode_change // kilocode_change start - fall through if the cached binary cannot be spawned const child = (() => { @@ -37,7 +38,8 @@ function run(target, fallback) { // kilocode_change - preserve cached binary fal // kilocode_change end const forwarders = {} - const clear = () => { // kilocode_change - remove listeners before cached binary fallback + const clear = () => { + // kilocode_change - remove listeners before cached binary fallback for (const signal of forwardedSignals) { process.removeListener(signal, forwarders[signal]) } diff --git a/packages/opencode/src/cli/cmd/run/footer.permission.tsx b/packages/opencode/src/cli/cmd/run/footer.permission.tsx index 0ab567c14a..bddd5e4083 100644 --- a/packages/opencode/src/cli/cmd/run/footer.permission.tsx +++ b/packages/opencode/src/cli/cmd/run/footer.permission.tsx @@ -99,7 +99,7 @@ function RejectField(props: { minHeight={1} maxHeight={3} wrapMode="word" - placeholder="Tell OpenCode what to do differently" + placeholder={"Tell Kilo what to do differently" /* kilocode_change */} placeholderColor={props.theme.muted} textColor={props.theme.text} focusedTextColor={props.theme.text} @@ -288,7 +288,7 @@ export function RunPermissionBody(props: { - Tell OpenCode what to do differently + {"Tell Kilo what to do differently" /* kilocode_change */} diff --git a/packages/opencode/src/cli/cmd/run/permission.shared.ts b/packages/opencode/src/cli/cmd/run/permission.shared.ts index 32051efb0b..2db4193696 100644 --- a/packages/opencode/src/cli/cmd/run/permission.shared.ts +++ b/packages/opencode/src/cli/cmd/run/permission.shared.ts @@ -125,11 +125,11 @@ export function permissionInfo(request: PermissionRequest): PermissionInfo { export function permissionAlwaysLines(request: PermissionRequest): string[] { if (request.always.length === 1 && request.always[0] === "*") { - return [`This will allow ${request.permission} until OpenCode is restarted.`] + return [`This will allow ${request.permission} until Kilo is restarted.`] // kilocode_change } return [ - "This will allow the following patterns until OpenCode is restarted.", + "This will allow the following patterns until Kilo is restarted.", // kilocode_change ...request.always.map((item) => `- ${item}`), ] } diff --git a/packages/opencode/src/cli/cmd/run/tool.ts b/packages/opencode/src/cli/cmd/run/tool.ts index e9247cf694..0afd841f7d 100644 --- a/packages/opencode/src/cli/cmd/run/tool.ts +++ b/packages/opencode/src/cli/cmd/run/tool.ts @@ -1,4 +1,4 @@ -// Per-tool display rules shared across `opencode run` output paths. +// Per-tool display rules shared across `kilo run` output paths. // kilocode_change // // Each known tool (bash, edit, write, task, etc.) has a ToolRule that controls // five display hooks: diff --git a/packages/opencode/src/cli/cmd/run/trace.ts b/packages/opencode/src/cli/cmd/run/trace.ts index de7dfa04cb..63c51c7ad2 100644 --- a/packages/opencode/src/cli/cmd/run/trace.ts +++ b/packages/opencode/src/cli/cmd/run/trace.ts @@ -1,7 +1,7 @@ // Dev-only JSONL event trace for direct interactive mode. // // Enable with KILO_DIRECT_TRACE=1. Writes one JSON line per event to -// ~/.local/share/opencode/log/direct/-.jsonl. Also writes +// ~/.local/share/kilo/log/direct/-.jsonl. Also writes // kilocode_change // a latest.json pointer so you can quickly find the most recent trace. // // The trace captures the full closed loop: outbound prompts, inbound SDK diff --git a/packages/opencode/src/cli/cmd/run/variant.shared.ts b/packages/opencode/src/cli/cmd/run/variant.shared.ts index 9e95413e0b..6fe66dd209 100644 --- a/packages/opencode/src/cli/cmd/run/variant.shared.ts +++ b/packages/opencode/src/cli/cmd/run/variant.shared.ts @@ -3,7 +3,7 @@ // Variants are provider-specific reasoning effort levels (e.g., "high", "max"). // Resolution priority: CLI --variant flag > saved preference > session history. // -// The saved variant persists across sessions in ~/.local/state/opencode/model.json +// The saved variant persists across sessions in ~/.local/state/kilo/model.json // kilocode_change // so your last-used variant sticks. Cycling (ctrl+t) updates both the active // variant and the persisted file. import path from "path" diff --git a/packages/opencode/src/kilocode/server/httpapi/public.ts b/packages/opencode/src/kilocode/server/httpapi/public.ts index bd3fdd7f6d..abd4c11524 100644 --- a/packages/opencode/src/kilocode/server/httpapi/public.ts +++ b/packages/opencode/src/kilocode/server/httpapi/public.ts @@ -30,6 +30,7 @@ type Spec = { } export function matchLegacyKiloOpenApi(input: Record) { + rebrand(input) const spec = input as Spec const body = spec.paths?.["/kilo/organization"]?.post?.requestBody?.content?.["application/json"]?.schema const ref = body?.$ref?.replace("#/components/schemas/", "") @@ -79,6 +80,25 @@ export function matchLegacyKiloOpenApi(input: Record) { } } +function rebrand(value: unknown): void { + if (Array.isArray(value)) { + for (const item of value) rebrand(item) + return + } + if (!value || typeof value !== "object") return + for (const [key, item] of Object.entries(value)) { + if (typeof item !== "string") { + rebrand(item) + continue + } + ;(value as Record)[key] = item + .replaceAll("OpenCode", "Kilo") + .replaceAll("opencode.local", "kilo.local") + .replaceAll("opencode serve", "kilo serve") + .replaceAll("https://opencode.ai/", "https://kilo.ai/") + } +} + function nullable(schema: Schema): Schema { if (schema.anyOf?.some((item) => item.type === "null")) return schema return { anyOf: [schema, { type: "null" }] } diff --git a/packages/opencode/src/tool/repo_clone.txt b/packages/opencode/src/tool/repo_clone.txt index 7944015506..3d6d0f2a6f 100644 --- a/packages/opencode/src/tool/repo_clone.txt +++ b/packages/opencode/src/tool/repo_clone.txt @@ -1,4 +1,4 @@ -- Clone or refresh a repository into OpenCode's managed cache under the data directory +- Clone or refresh a repository into Kilo's managed cache under the data directory - Accepts git URLs, forge host/path references, or GitHub owner/repo shorthand - Returns the cached absolute local path so other tools can explore the cloned source - Use this before Read, Glob, or Grep when the code you need lives outside the current workspace diff --git a/packages/opencode/test/cli/run/permission.shared.test.ts b/packages/opencode/test/cli/run/permission.shared.test.ts index 0b12adc491..aa843ccbbc 100644 --- a/packages/opencode/test/cli/run/permission.shared.test.ts +++ b/packages/opencode/test/cli/run/permission.shared.test.ts @@ -132,11 +132,11 @@ describe("run permission shared", () => { test("formats always-allow copy for wildcard and explicit patterns", () => { expect(permissionAlwaysLines(req({ permission: "bash", always: ["*"] }))).toEqual([ - "This will allow bash until OpenCode is restarted.", + "This will allow bash until Kilo is restarted.", ]) expect(permissionAlwaysLines(req({ always: ["src/**/*.ts", "src/**/*.tsx"] }))).toEqual([ - "This will allow the following patterns until OpenCode is restarted.", + "This will allow the following patterns until Kilo is restarted.", "- src/**/*.ts", "- src/**/*.tsx", ]) diff --git a/packages/opencode/test/kilocode/bin-tree-sitter-env.test.ts b/packages/opencode/test/kilocode/bin-tree-sitter-env.test.ts index 2120570327..c81b92840f 100644 --- a/packages/opencode/test/kilocode/bin-tree-sitter-env.test.ts +++ b/packages/opencode/test/kilocode/bin-tree-sitter-env.test.ts @@ -4,14 +4,16 @@ import { tmpdir } from "os" import { join } from "path" const script = join(import.meta.dir, "..", "..", "bin", "kilo") +const platform = process.platform === "win32" ? "windows" : process.platform +const binary = platform === "windows" ? "kilo.exe" : "kilo" describe("bin/kilo tree-sitter resources", () => { async function setup(root: string, nested: boolean) { const dir = nested - ? join(root, "node_modules", "@kilocode", "cli-darwin-arm64", "bin") + ? join(root, "node_modules", "@kilocode", `cli-${platform}-${process.arch}`, "bin") : join(root, "node_modules", "@kilocode", "cli", "bin") const wasm = join(dir, "tree-sitter") - const bin = join(dir, nested ? "kilo" : ".kilo") + const bin = join(dir, nested ? binary : ".kilo") const log = join(root, nested ? "nested-env.txt" : "cached-env.txt") await mkdir(wasm, { recursive: true }) diff --git a/packages/opencode/test/server/httpapi-instance.test.ts b/packages/opencode/test/server/httpapi-instance.test.ts index 314a4adb5b..631b4bfd5b 100644 --- a/packages/opencode/test/server/httpapi-instance.test.ts +++ b/packages/opencode/test/server/httpapi-instance.test.ts @@ -60,7 +60,8 @@ describe("instance HttpApi", () => { expect(response.status).toBe(200) expect(response.headers["content-type"]).toContain("application/json") - expect(yield* response.json).toMatchObject({ + const spec = yield* response.json + expect(spec).toMatchObject({ openapi: expect.any(String), info: expect.any(Object), paths: expect.objectContaining({ @@ -68,6 +69,7 @@ describe("instance HttpApi", () => { "/session": expect.any(Object), }), }) + expect(JSON.stringify(spec)).not.toContain("OpenCode") }), ) diff --git a/script/check-forbidden-strings.ts b/script/check-forbidden-strings.ts index aa1aa8ad7f..f3941bab05 100644 --- a/script/check-forbidden-strings.ts +++ b/script/check-forbidden-strings.ts @@ -41,6 +41,9 @@ const forbidden: { pattern: string; reason: string; allow?: string[] }[] = [ }, { pattern: `"HTTP-Referer": "https://opencode.ai/"`, reason: "attributes outbound LLM traffic to upstream" }, { pattern: `"http-referer": "https://opencode.ai/"`, reason: "attributes outbound LLM traffic to upstream" }, + { pattern: "Tell OpenCode what to do differently", reason: "direct-mode permission UI uses upstream branding" }, + { pattern: "until OpenCode is restarted", reason: "permission copy uses upstream branding" }, + { pattern: "OpenCode's managed cache", reason: "Scout tool description uses upstream branding" }, // Candidates -- enable once the underlying call sites have been rebranded. // Each one currently fires on real leaks; uncomment after fixing the listed diff --git a/script/upstream/transforms/preserve-versions.test.ts b/script/upstream/transforms/preserve-versions.test.ts new file mode 100644 index 0000000000..5d22454c18 --- /dev/null +++ b/script/upstream/transforms/preserve-versions.test.ts @@ -0,0 +1,37 @@ +import { describe, expect, test } from "bun:test" +import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises" +import { tmpdir } from "node:os" +import { join } from "node:path" +import { preserveZedVersion } from "./preserve-versions" + +describe("preserveZedVersion", () => { + test("preserves the Kilo extension version and release archives", async () => { + const dir = await mkdtemp(join(tmpdir(), "kilo-zed-version-")) + const file = join(dir, "extension.toml") + try { + await writeFile( + file, + [ + 'version = "1.14.42"', + 'archive = "https://github.com/Kilo-Org/kilocode/releases/download/v1.14.42/opencode-linux-x64.tar.gz"', + "", + ].join("\n"), + ) + + expect(await preserveZedVersion(file, { targetVersion: "7.3.18" })).toMatchObject({ + file, + originalVersion: "1.14.42", + preserved: true, + }) + expect(await readFile(file, "utf8")).toBe( + [ + 'version = "7.3.18"', + 'archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.18/opencode-linux-x64.tar.gz"', + "", + ].join("\n"), + ) + } finally { + await rm(dir, { recursive: true, force: true }) + } + }) +}) diff --git a/script/upstream/transforms/preserve-versions.ts b/script/upstream/transforms/preserve-versions.ts index 4fdd568ec8..30ee53a4e0 100644 --- a/script/upstream/transforms/preserve-versions.ts +++ b/script/upstream/transforms/preserve-versions.ts @@ -36,7 +36,7 @@ export async function getCurrentVersion(): Promise { */ export async function preserveVersion(filePath: string, options: PreserveOptions = {}): Promise { const file = Bun.file(filePath) - let content = await file.text() + const content = await file.text() // Extract current version const versionMatch = content.match(/"version":\s*"([^"]+)"/) @@ -61,6 +61,30 @@ export async function preserveVersion(filePath: string, options: PreserveOptions } } +export async function preserveZedVersion( + filePath: string, + options: PreserveOptions = {}, +): Promise { + const file = Bun.file(filePath) + const content = await file.text() + const versionMatch = content.match(/^version = "([^"]+)"/m) + const originalVersion = versionMatch ? versionMatch[1] : "unknown" + const targetVersion = options.targetVersion || (await getCurrentVersion()) + const next = content + .replace(/^version = "[^"]+"/m, `version = "${targetVersion}"`) + .replace(/\/releases\/download\/v[^/]+\//g, `/releases/download/v${targetVersion}/`) + const changed = next !== content + + if (changed && !options.dryRun) await Bun.write(filePath, next) + + return { + file: filePath, + originalVersion, + preserved: changed, + dryRun: options.dryRun ?? false, + } +} + /** * Preserve versions in all package.json files */ @@ -75,25 +99,28 @@ export async function preserveAllVersions(options: PreserveOptions = {}): Promis info(`Target version: ${targetVersion}`) + const track = (result: VersionPreserveResult) => { + if (!result.preserved) return + results.push(result) + if (options.dryRun) { + info(`[DRY-RUN] Would preserve ${result.file}: ${result.originalVersion} -> ${targetVersion}`) + return + } + success(`Preserved ${result.file}: ${result.originalVersion} -> ${targetVersion}`) + } + for await (const path of glob.scan({ absolute: true })) { // Skip excluded paths if (excludes.some((ex) => path.includes(ex.replace(/\*\*/g, "")))) { continue } - const result = await preserveVersion(path, { ...options, targetVersion }) - - if (result.preserved) { - results.push(result) - - if (options.dryRun) { - info(`[DRY-RUN] Would preserve ${result.file}: ${result.originalVersion} -> ${targetVersion}`) - } else { - success(`Preserved ${result.file}: ${result.originalVersion} -> ${targetVersion}`) - } - } + track(await preserveVersion(path, { ...options, targetVersion })) } + const zed = "packages/extensions/zed/extension.toml" + if (await Bun.file(zed).exists()) track(await preserveZedVersion(zed, { ...options, targetVersion })) + return results }