mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-08-28 19:11:03 +08:00
fix: preserve Kilo identity after upstream merge
This commit is contained in:
@@ -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"]
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
<!-- packages/opencode/src/session/network.ts -->
|
||||
- <https://kilo.ai/>
|
||||
<!-- packages/opencode/src/cli/cmd/generate.ts -->
|
||||
<!-- packages/opencode/src/kilocode/server/httpapi/public.ts -->
|
||||
<!-- packages/opencode/src/provider/provider.ts -->
|
||||
- <https://kilo.ai/discord>
|
||||
<!-- packages/kilo-vscode/webview-ui/src/components/chat/FeedbackDialog.tsx -->
|
||||
@@ -131,6 +132,7 @@
|
||||
<!-- packages/opencode/src/config/model-id.ts -->
|
||||
- <https://opencode.ai/>
|
||||
<!-- packages/opencode/src/cli/cmd/generate.ts -->
|
||||
<!-- packages/opencode/src/kilocode/server/httpapi/public.ts -->
|
||||
- <https://opencode.ai/auth>
|
||||
<!-- packages/opencode/src/cli/cmd/providers.ts -->
|
||||
- <https://opencode.ai/docs/agents>
|
||||
|
||||
@@ -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])
|
||||
}
|
||||
|
||||
@@ -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: {
|
||||
</Match>
|
||||
<Match when={state().stage === "reject"}>
|
||||
<box paddingLeft={1}>
|
||||
<text fg={props.theme.muted}>Tell OpenCode what to do differently</text>
|
||||
<text fg={props.theme.muted}>{"Tell Kilo what to do differently" /* kilocode_change */}</text>
|
||||
</box>
|
||||
</Match>
|
||||
</Switch>
|
||||
|
||||
@@ -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}`),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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/<timestamp>-<pid>.jsonl. Also writes
|
||||
// ~/.local/share/kilo/log/direct/<timestamp>-<pid>.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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -30,6 +30,7 @@ type Spec = {
|
||||
}
|
||||
|
||||
export function matchLegacyKiloOpenApi(input: Record<string, unknown>) {
|
||||
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<string, unknown>) {
|
||||
}
|
||||
}
|
||||
|
||||
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<string, unknown>)[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" }] }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
])
|
||||
|
||||
@@ -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 })
|
||||
|
||||
@@ -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")
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 })
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -36,7 +36,7 @@ export async function getCurrentVersion(): Promise<string> {
|
||||
*/
|
||||
export async function preserveVersion(filePath: string, options: PreserveOptions = {}): Promise<VersionPreserveResult> {
|
||||
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<VersionPreserveResult> {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user