From 6e66979f9ec78822c7f2836689ae65a2ef43b35d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Catriel=20M=C3=BCller?= Date: Mon, 2 Feb 2026 18:32:22 -0300 Subject: [PATCH 01/15] feat: envrc flake support --- .envrc | 4 ++++ flake.nix | 29 ++++++++++++++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 .envrc diff --git a/.envrc b/.envrc new file mode 100644 index 0000000000..533548463c --- /dev/null +++ b/.envrc @@ -0,0 +1,4 @@ +# Check if nix command is available before trying to use flake +if command -v nix >/dev/null 2>&1; then + use flake +fi \ No newline at end of file diff --git a/flake.nix b/flake.nix index fdcc499a07..f1e24bed5e 100644 --- a/flake.nix +++ b/flake.nix @@ -19,15 +19,26 @@ in { devShells = forEachSystem (pkgs: { - default = pkgs.mkShell { - packages = with pkgs; [ - bun - nodejs_20 - pkg-config - openssl - git - ]; - }; + default = + let + kilo = pkgs.writeShellScriptBin "kilo" '' + cd "$KILO_ROOT" + exec ${pkgs.bun}/bin/bun dev "$@" + ''; + in + pkgs.mkShell { + packages = with pkgs; [ + bun + nodejs_20 + pkg-config + openssl + git + kilo + ]; + shellHook = '' + export KILO_ROOT="$PWD" + ''; + }; }); packages = forEachSystem ( From 9ab79857ce544a413bee9973857c465c022a7b65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Catriel=20M=C3=BCller?= Date: Tue, 3 Feb 2026 08:04:27 +0100 Subject: [PATCH 02/15] Code Agent (#84) * refactor: rename build agent to code * refactor: add backward compat for build config --- packages/opencode/script/seed-e2e.ts | 2 +- packages/opencode/src/agent/agent.ts | 30 +- packages/opencode/src/config/config.ts | 4 +- .../opencode/src/kilocode/components/tips.tsx | 2 +- .../opencode/src/kilocode/modes-migrator.ts | 3 +- packages/opencode/src/session/prompt.ts | 10 +- .../{build-switch.txt => code-switch.txt} | 2 +- packages/opencode/src/tool/plan.ts | 18 +- .../test/acp/event-subscription.test.ts | 6 +- packages/opencode/test/agent/agent.test.ts | 273 +++++++++++++----- .../opencode/test/cli/tui/transcript.test.ts | 22 +- .../opencode/test/config/agent-color.test.ts | 4 +- .../opencode/test/tool/apply_patch.test.ts | 2 +- packages/opencode/test/tool/bash.test.ts | 2 +- .../test/tool/external-directory.test.ts | 2 +- packages/opencode/test/tool/grep.test.ts | 2 +- packages/opencode/test/tool/read.test.ts | 6 +- packages/sdk/js/src/v2/gen/types.gen.ts | 2 +- 18 files changed, 271 insertions(+), 121 deletions(-) rename packages/opencode/src/session/prompt/{build-switch.txt => code-switch.txt} (76%) diff --git a/packages/opencode/script/seed-e2e.ts b/packages/opencode/script/seed-e2e.ts index 0384a2c2e3..98693b807a 100644 --- a/packages/opencode/script/seed-e2e.ts +++ b/packages/opencode/script/seed-e2e.ts @@ -26,7 +26,7 @@ const seed = async () => { sessionID: session.id, role: "user" as const, time: { created: now }, - agent: "build", + agent: "code", // kilocode_change - renamed from "build" to "code" model: { providerID, modelID, diff --git a/packages/opencode/src/agent/agent.ts b/packages/opencode/src/agent/agent.ts index f1727c2a73..0b7cde850b 100644 --- a/packages/opencode/src/agent/agent.ts +++ b/packages/opencode/src/agent/agent.ts @@ -72,9 +72,11 @@ export namespace Agent { const user = PermissionNext.fromConfig(cfg.permission ?? {}) const result: Record = { - build: { - name: "build", + // kilocode_change start + code: { + name: "code", description: "The default agent. Executes tools based on configured permissions.", + // kilocode_change end options: {}, permission: PermissionNext.merge( defaults, @@ -201,19 +203,23 @@ export namespace Agent { } for (const [key, value] of Object.entries(cfg.agent ?? {})) { + // kilocode_change start + // Treat "build" config as "code" for backward compatibility + const effectiveKey = key === "build" ? "code" : key if (value.disable) { - delete result[key] + delete result[effectiveKey] continue } - let item = result[key] + let item = result[effectiveKey] if (!item) - item = result[key] = { - name: key, + item = result[effectiveKey] = { + name: effectiveKey, mode: "all", permission: PermissionNext.merge(defaults, user), options: {}, native: false, } + // kilocode_change end if (value.model) item.model = Provider.parseModel(value.model) item.prompt = value.prompt ?? item.prompt item.description = value.description ?? item.description @@ -248,7 +254,10 @@ export namespace Agent { }) export async function get(agent: string) { - return state().then((x) => x[agent]) + // kilocode_change start - Treat "build" as "code" for backward compatibility + const effectiveAgent = agent === "build" ? "code" : agent + return state().then((x) => x[effectiveAgent]) + // kilocode_change end } export async function list() { @@ -256,7 +265,7 @@ export namespace Agent { return pipe( await state(), values(), - sortBy([(x) => (cfg.default_agent ? x.name === cfg.default_agent : x.name === "build"), "desc"]), + sortBy([(x) => (cfg.default_agent ? x.name === cfg.default_agent : x.name === "code"), "desc"]), // kilocode_change - renamed from "build" to "code" ) } @@ -265,8 +274,11 @@ export namespace Agent { const agents = await state() if (cfg.default_agent) { - const agent = agents[cfg.default_agent] + // kilocode_change start - Treat "build" as "code" for backward compatibility + const effectiveDefault = cfg.default_agent === "build" ? "code" : cfg.default_agent + const agent = agents[effectiveDefault] if (!agent) throw new Error(`default agent "${cfg.default_agent}" not found`) + // kilocode_change end if (agent.mode === "subagent") throw new Error(`default agent "${cfg.default_agent}" is a subagent`) if (agent.hidden === true) throw new Error(`default agent "${cfg.default_agent}" is hidden`) return agent.name diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index afa754b24d..f39327b679 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -1013,12 +1013,14 @@ export namespace Config { .string() .describe("Small model to use for tasks like title generation in the format of provider/model") .optional(), + // kilocode_change - renamed from "build" to "code" default_agent: z .string() .optional() .describe( - "Default agent to use when none is specified. Must be a primary agent. Falls back to 'build' if not set or if the specified agent is invalid.", + "Default agent to use when none is specified. Must be a primary agent. Falls back to 'code' if not set or if the specified agent is invalid.", ), + // kilocode_change end username: z .string() .optional() diff --git a/packages/opencode/src/kilocode/components/tips.tsx b/packages/opencode/src/kilocode/components/tips.tsx index 0a2c4cb929..1e09b5c170 100644 --- a/packages/opencode/src/kilocode/components/tips.tsx +++ b/packages/opencode/src/kilocode/components/tips.tsx @@ -54,7 +54,7 @@ export function Tips() { const TIPS = [ "Type {highlight}@{/highlight} followed by a filename to fuzzy search and attach files", "Start a message with {highlight}!{/highlight} to run shell commands directly (e.g., {highlight}!ls -la{/highlight})", - "Press {highlight}Tab{/highlight} to cycle between Build and Plan agents", + "Press {highlight}Tab{/highlight} to cycle between Code and Plan agents", "Use {highlight}/undo{/highlight} to revert the last message and file changes", "Use {highlight}/redo{/highlight} to restore previously undone messages and file changes", "Drag and drop images into the terminal to add them as context", diff --git a/packages/opencode/src/kilocode/modes-migrator.ts b/packages/opencode/src/kilocode/modes-migrator.ts index ca99a63d63..8d73cb916b 100644 --- a/packages/opencode/src/kilocode/modes-migrator.ts +++ b/packages/opencode/src/kilocode/modes-migrator.ts @@ -23,7 +23,8 @@ export namespace ModesMigrator { } // Default modes to skip - these have native Opencode equivalents - const DEFAULT_MODE_SLUGS = new Set(["code", "architect", "ask", "debug", "orchestrator"]) + // kilocode_change - added "build" for backward compatibility after renaming "build" to "code" + const DEFAULT_MODE_SLUGS = new Set(["code", "build", "architect", "ask", "debug", "orchestrator"]) // Group to permission mapping const GROUP_TO_PERMISSION: Record = { diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index 94eabdef7f..6cc7d0b63d 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -18,7 +18,7 @@ import { SystemPrompt } from "./system" import { InstructionPrompt } from "./instruction" import { Plugin } from "../plugin" import PROMPT_PLAN from "../session/prompt/plan.txt" -import BUILD_SWITCH from "../session/prompt/build-switch.txt" +import CODE_SWITCH from "../session/prompt/code-switch.txt" import MAX_STEPS from "../session/prompt/max-steps.txt" import { defer } from "../util/defer" import { clone } from "remeda" @@ -1214,13 +1214,15 @@ export namespace SessionPrompt { }) } const wasPlan = input.messages.some((msg) => msg.info.role === "assistant" && msg.info.agent === "plan") - if (wasPlan && input.agent.name === "build") { + // kilocode_change start - renamed from "build" to "code" + if (wasPlan && input.agent.name === "code") { + // kilocode_change end userMessage.parts.push({ id: Identifier.ascending("part"), messageID: userMessage.info.id, sessionID: userMessage.info.sessionID, type: "text", - text: BUILD_SWITCH, + text: CODE_SWITCH, synthetic: true, }) } @@ -1241,7 +1243,7 @@ export namespace SessionPrompt { sessionID: userMessage.info.sessionID, type: "text", text: - BUILD_SWITCH + "\n\n" + `A plan file exists at ${plan}. You should execute on the plan defined within it`, + CODE_SWITCH + "\n\n" + `A plan file exists at ${plan}. You should execute on the plan defined within it`, synthetic: true, }) userMessage.parts.push(part) diff --git a/packages/opencode/src/session/prompt/build-switch.txt b/packages/opencode/src/session/prompt/code-switch.txt similarity index 76% rename from packages/opencode/src/session/prompt/build-switch.txt rename to packages/opencode/src/session/prompt/code-switch.txt index 3737b74d89..4407f011c1 100644 --- a/packages/opencode/src/session/prompt/build-switch.txt +++ b/packages/opencode/src/session/prompt/code-switch.txt @@ -1,5 +1,5 @@ -Your operational mode has changed from plan to build. +Your operational mode has changed from plan to code. You are no longer in read-only mode. You are permitted to make file changes, run shell commands, and utilize your arsenal of tools as needed. diff --git a/packages/opencode/src/tool/plan.ts b/packages/opencode/src/tool/plan.ts index 6cb7a691c8..c93a522768 100644 --- a/packages/opencode/src/tool/plan.ts +++ b/packages/opencode/src/tool/plan.ts @@ -27,13 +27,15 @@ export const PlanExitTool = Tool.define("plan_exit", { sessionID: ctx.sessionID, questions: [ { - question: `Plan at ${plan} is complete. Would you like to switch to the build agent and start implementing?`, - header: "Build Agent", + // kilocode_change start + question: `Plan at ${plan} is complete. Would you like to switch to the code agent and start implementing?`, + header: "Code Agent", custom: false, options: [ - { label: "Yes", description: "Switch to build agent and start implementing the plan" }, + { label: "Yes", description: "Switch to code agent and start implementing the plan" }, { label: "No", description: "Stay with plan agent to continue refining the plan" }, ], + // kilocode_change end }, ], tool: ctx.callID ? { messageID: ctx.messageID, callID: ctx.callID } : undefined, @@ -51,7 +53,7 @@ export const PlanExitTool = Tool.define("plan_exit", { time: { created: Date.now(), }, - agent: "build", + agent: "code", // kilocode_change - renamed from "build" to "code" model, } await Session.updateMessage(userMsg) @@ -64,11 +66,13 @@ export const PlanExitTool = Tool.define("plan_exit", { synthetic: true, } satisfies MessageV2.TextPart) + // kilocode_change start return { - title: "Switching to build agent", - output: "User approved switching to build agent. Wait for further instructions.", + title: "Switching to code agent", + output: "User approved switching to code agent. Wait for further instructions.", metadata: {}, } + // kilocode_change end }, }) @@ -88,7 +92,7 @@ export const PlanEnterTool = Tool.define("plan_enter", { custom: false, options: [ { label: "Yes", description: "Switch to plan agent for research and planning" }, - { label: "No", description: "Stay with build agent to continue making changes" }, + { label: "No", description: "Stay with code agent to continue making changes" }, // kilocode_change - renamed from "build" to "code" ], }, ], diff --git a/packages/opencode/test/acp/event-subscription.test.ts b/packages/opencode/test/acp/event-subscription.test.ts index a38432ea32..db5410af2e 100644 --- a/packages/opencode/test/acp/event-subscription.test.ts +++ b/packages/opencode/test/acp/event-subscription.test.ts @@ -159,8 +159,10 @@ function createFakeAgent() { return { data: [ { - name: "build", - description: "build", + // kilocode_change start - renamed from "build" to "code" + name: "code", + description: "code", + // kilocode_change end mode: "agent", }, ], diff --git a/packages/opencode/test/agent/agent.test.ts b/packages/opencode/test/agent/agent.test.ts index 1ff303b766..4f50d65850 100644 --- a/packages/opencode/test/agent/agent.test.ts +++ b/packages/opencode/test/agent/agent.test.ts @@ -17,7 +17,7 @@ test("returns default native agents when no config", async () => { fn: async () => { const agents = await Agent.list() const names = agents.map((a) => a.name) - expect(names).toContain("build") + expect(names).toContain("code") // kilocode_change expect(names).toContain("plan") expect(names).toContain("general") expect(names).toContain("explore") @@ -28,20 +28,22 @@ test("returns default native agents when no config", async () => { }) }) -test("build agent has correct default properties", async () => { +// kilocode_change start - renamed from "build" to "code" +test("code agent has correct default properties", async () => { await using tmp = await tmpdir() await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - expect(build).toBeDefined() - expect(build?.mode).toBe("primary") - expect(build?.native).toBe(true) - expect(evalPerm(build, "edit")).toBe("allow") - expect(evalPerm(build, "bash")).toBe("allow") + const code = await Agent.get("code") + expect(code).toBeDefined() + expect(code?.mode).toBe("primary") + expect(code?.native).toBe(true) + expect(evalPerm(code, "edit")).toBe("allow") + expect(evalPerm(code, "bash")).toBe("allow") }, }) }) +// kilocode_change end test("plan agent denies edits except .opencode/plans/*", async () => { await using tmp = await tmpdir() @@ -137,26 +139,30 @@ test("custom agent config overrides native agent properties", async () => { await using tmp = await tmpdir({ config: { agent: { - build: { + // kilocode_change start + code: { model: "anthropic/claude-3", - description: "Custom build agent", + description: "Custom code agent", temperature: 0.7, color: "#FF0000", }, + // kilocode_change end }, }, }) await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - expect(build).toBeDefined() - expect(build?.model?.providerID).toBe("anthropic") - expect(build?.model?.modelID).toBe("claude-3") - expect(build?.description).toBe("Custom build agent") - expect(build?.temperature).toBe(0.7) - expect(build?.color).toBe("#FF0000") - expect(build?.native).toBe(true) + // kilocode_change start - renamed from "build" to "code" + const code = await Agent.get("code") + expect(code).toBeDefined() + expect(code?.model?.providerID).toBe("anthropic") + expect(code?.model?.modelID).toBe("claude-3") + expect(code?.description).toBe("Custom code agent") + expect(code?.temperature).toBe(0.7) + expect(code?.color).toBe("#FF0000") + expect(code?.native).toBe(true) + // kilocode_change end }, }) }) @@ -185,7 +191,9 @@ test("agent permission config merges with defaults", async () => { await using tmp = await tmpdir({ config: { agent: { - build: { + // kilocode_change start + code: { + // kilocode_change end permission: { bash: { "rm -rf *": "deny", @@ -198,12 +206,14 @@ test("agent permission config merges with defaults", async () => { await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - expect(build).toBeDefined() + // kilocode_change start - renamed from "build" to "code" + const code = await Agent.get("code") + expect(code).toBeDefined() // Specific pattern is denied - expect(PermissionNext.evaluate("bash", "rm -rf *", build!.permission).action).toBe("deny") + expect(PermissionNext.evaluate("bash", "rm -rf *", code!.permission).action).toBe("deny") // Edit still allowed - expect(evalPerm(build, "edit")).toBe("allow") + expect(evalPerm(code, "edit")).toBe("allow") + // kilocode_change end }, }) }) @@ -219,9 +229,11 @@ test("global permission config applies to all agents", async () => { await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - expect(build).toBeDefined() - expect(evalPerm(build, "bash")).toBe("deny") + // kilocode_change start - renamed from "build" to "code" + const code = await Agent.get("code") + expect(code).toBeDefined() + expect(evalPerm(code, "bash")).toBe("deny") + // kilocode_change end }, }) }) @@ -230,7 +242,9 @@ test("agent steps/maxSteps config sets steps property", async () => { await using tmp = await tmpdir({ config: { agent: { - build: { steps: 50 }, + // kilocode_change start - renamed from "build" to "code" + code: { steps: 50 }, + // kilocode_change end plan: { maxSteps: 100 }, }, }, @@ -238,9 +252,9 @@ test("agent steps/maxSteps config sets steps property", async () => { await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") + const code = await Agent.get("code") // kilocode_change const plan = await Agent.get("plan") - expect(build?.steps).toBe(50) + expect(code?.steps).toBe(50) // kilocode_change expect(plan?.steps).toBe(100) }, }) @@ -267,15 +281,17 @@ test("agent name can be overridden", async () => { await using tmp = await tmpdir({ config: { agent: { - build: { name: "Builder" }, + code: { name: "Coder" }, // kilocode_change }, }, }) await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - expect(build?.name).toBe("Builder") + // kilocode_change start - renamed from "build" to "code" + const code = await Agent.get("code") + expect(code?.name).toBe("Coder") + // kilocode_change end }, }) }) @@ -284,15 +300,17 @@ test("agent prompt can be set from config", async () => { await using tmp = await tmpdir({ config: { agent: { - build: { prompt: "Custom system prompt" }, + code: { prompt: "Custom system prompt" }, // kilocode_change }, }, }) await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - expect(build?.prompt).toBe("Custom system prompt") + // kilocode_change start - renamed from "build" to "code" + const code = await Agent.get("code") + expect(code?.prompt).toBe("Custom system prompt") + // kilocode_change end }, }) }) @@ -301,7 +319,7 @@ test("unknown agent properties are placed into options", async () => { await using tmp = await tmpdir({ config: { agent: { - build: { + code: { random_property: "hello", another_random: 123, }, @@ -311,9 +329,11 @@ test("unknown agent properties are placed into options", async () => { await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - expect(build?.options.random_property).toBe("hello") - expect(build?.options.another_random).toBe(123) + // kilocode_change start - renamed from "build" to "code" + const code = await Agent.get("code") + expect(code?.options.random_property).toBe("hello") + expect(code?.options.another_random).toBe(123) + // kilocode_change end }, }) }) @@ -322,7 +342,9 @@ test("agent options merge correctly", async () => { await using tmp = await tmpdir({ config: { agent: { - build: { + // kilocode_change start - renamed from "build" to "code" + code: { + // kilocode_change end options: { custom_option: true, another_option: "value", @@ -334,9 +356,11 @@ test("agent options merge correctly", async () => { await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - expect(build?.options.custom_option).toBe(true) - expect(build?.options.another_option).toBe("value") + // kilocode_change start - renamed from "build" to "code" + const code = await Agent.get("code") + expect(code?.options.custom_option).toBe(true) + expect(code?.options.another_option).toBe("value") + // kilocode_change end }, }) }) @@ -385,9 +409,11 @@ test("default permission includes doom_loop and external_directory as ask", asyn await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - expect(evalPerm(build, "doom_loop")).toBe("ask") - expect(evalPerm(build, "external_directory")).toBe("ask") + // kilocode_change start - renamed from "build" to "code" + const code = await Agent.get("code") + expect(evalPerm(code, "doom_loop")).toBe("ask") + expect(evalPerm(code, "external_directory")).toBe("ask") + // kilocode_change end }, }) }) @@ -397,8 +423,10 @@ test("webfetch is allowed by default", async () => { await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - expect(evalPerm(build, "webfetch")).toBe("allow") + // kilocode_change start - renamed from "build" to "code" + const code = await Agent.get("code") + expect(evalPerm(code, "webfetch")).toBe("allow") + // kilocode_change end }, }) }) @@ -407,7 +435,9 @@ test("legacy tools config converts to permissions", async () => { await using tmp = await tmpdir({ config: { agent: { - build: { + // kilocode_change start - renamed from "build" to "code" + code: { + // kilocode_change end tools: { bash: false, read: false, @@ -419,9 +449,11 @@ test("legacy tools config converts to permissions", async () => { await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - expect(evalPerm(build, "bash")).toBe("deny") - expect(evalPerm(build, "read")).toBe("deny") + // kilocode_change start - renamed from "build" to "code" + const code = await Agent.get("code") + expect(evalPerm(code, "bash")).toBe("deny") + expect(evalPerm(code, "read")).toBe("deny") + // kilocode_change end }, }) }) @@ -430,7 +462,9 @@ test("legacy tools config maps write/edit/patch/multiedit to edit permission", a await using tmp = await tmpdir({ config: { agent: { - build: { + // kilocode_change start - renamed from "build" to "code" + code: { + // kilocode_change end tools: { write: false, }, @@ -441,8 +475,10 @@ test("legacy tools config maps write/edit/patch/multiedit to edit permission", a await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - expect(evalPerm(build, "edit")).toBe("deny") + // kilocode_change start - renamed from "build" to "code" + const code = await Agent.get("code") + expect(evalPerm(code, "edit")).toBe("deny") + // kilocode_change end }, }) }) @@ -459,10 +495,12 @@ test("Truncate.DIR is allowed even when user denies external_directory globally" await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - expect(PermissionNext.evaluate("external_directory", Truncate.DIR, build!.permission).action).toBe("allow") - expect(PermissionNext.evaluate("external_directory", Truncate.GLOB, build!.permission).action).toBe("allow") - expect(PermissionNext.evaluate("external_directory", "/some/other/path", build!.permission).action).toBe("deny") + // kilocode_change start - renamed from "build" to "code" + const code = await Agent.get("code") + expect(PermissionNext.evaluate("external_directory", Truncate.DIR, code!.permission).action).toBe("allow") + expect(PermissionNext.evaluate("external_directory", Truncate.GLOB, code!.permission).action).toBe("allow") + expect(PermissionNext.evaluate("external_directory", "/some/other/path", code!.permission).action).toBe("deny") + // kilocode_change end }, }) }) @@ -472,7 +510,9 @@ test("Truncate.DIR is allowed even when user denies external_directory per-agent await using tmp = await tmpdir({ config: { agent: { - build: { + // kilocode_change start - renamed from "build" to "code" + code: { + // kilocode_change end permission: { external_directory: "deny", }, @@ -483,10 +523,12 @@ test("Truncate.DIR is allowed even when user denies external_directory per-agent await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - expect(PermissionNext.evaluate("external_directory", Truncate.DIR, build!.permission).action).toBe("allow") - expect(PermissionNext.evaluate("external_directory", Truncate.GLOB, build!.permission).action).toBe("allow") - expect(PermissionNext.evaluate("external_directory", "/some/other/path", build!.permission).action).toBe("deny") + // kilocode_change start - renamed from "build" to "code" + const code = await Agent.get("code") + expect(PermissionNext.evaluate("external_directory", Truncate.DIR, code!.permission).action).toBe("allow") + expect(PermissionNext.evaluate("external_directory", Truncate.GLOB, code!.permission).action).toBe("allow") + expect(PermissionNext.evaluate("external_directory", "/some/other/path", code!.permission).action).toBe("deny") + // kilocode_change end }, }) }) @@ -506,20 +548,24 @@ test("explicit Truncate.DIR deny is respected", async () => { await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - expect(PermissionNext.evaluate("external_directory", Truncate.DIR, build!.permission).action).toBe("deny") - expect(PermissionNext.evaluate("external_directory", Truncate.GLOB, build!.permission).action).toBe("deny") + // kilocode_change start - renamed from "build" to "code" + const code = await Agent.get("code") + expect(PermissionNext.evaluate("external_directory", Truncate.DIR, code!.permission).action).toBe("deny") + expect(PermissionNext.evaluate("external_directory", Truncate.GLOB, code!.permission).action).toBe("deny") + // kilocode_change end }, }) }) -test("defaultAgent returns build when no default_agent config", async () => { +// kilocode_change start - renamed from "build" to "code" +test("defaultAgent returns code when no default_agent config", async () => { + // kilocode_change end await using tmp = await tmpdir() await Instance.provide({ directory: tmp.path, fn: async () => { const agent = await Agent.defaultAgent() - expect(agent).toBe("build") + expect(agent).toBe("code") // kilocode_change }, }) }) @@ -601,11 +647,15 @@ test("defaultAgent throws when default_agent points to non-existent agent", asyn }) }) -test("defaultAgent returns plan when build is disabled and default_agent not set", async () => { +// kilocode_change start - renamed from "build" to "code" +test("defaultAgent returns plan when code is disabled and default_agent not set", async () => { + // kilocode_change end await using tmp = await tmpdir({ config: { agent: { - build: { disable: true }, + // kilocode_change start - renamed from "build" to "code" + code: { disable: true }, + // kilocode_change end }, }, }) @@ -613,7 +663,7 @@ test("defaultAgent returns plan when build is disabled and default_agent not set directory: tmp.path, fn: async () => { const agent = await Agent.defaultAgent() - // build is disabled, so it should return plan (next primary agent) + // kilocode_change - code is disabled, so it should return plan (next primary agent) expect(agent).toBe("plan") }, }) @@ -623,7 +673,9 @@ test("defaultAgent throws when all primary agents are disabled", async () => { await using tmp = await tmpdir({ config: { agent: { - build: { disable: true }, + // kilocode_change start - renamed from "build" to "code" + code: { disable: true }, + // kilocode_change end plan: { disable: true }, }, }, @@ -631,8 +683,81 @@ test("defaultAgent throws when all primary agents are disabled", async () => { await Instance.provide({ directory: tmp.path, fn: async () => { - // build and plan are disabled, no primary-capable agents remain + // kilocode_change - code and plan are disabled, no primary-capable agents remain await expect(Agent.defaultAgent()).rejects.toThrow("no primary visible agent found") }, }) }) + +// kilocode_change start - Backward compatibility tests for "build" -> "code" rename +test("Agent.get('build') returns code agent for backward compatibility", async () => { + await using tmp = await tmpdir() + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const build = await Agent.get("build") + const code = await Agent.get("code") + expect(build).toBeDefined() + expect(build).toBe(code) + expect(build?.name).toBe("code") + }, + }) +}) + +test("agent.build config applies to code agent for backward compatibility", async () => { + await using tmp = await tmpdir({ + config: { + agent: { + build: { + temperature: 0.8, + color: "#00FF00", + }, + }, + }, + }) + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const code = await Agent.get("code") + expect(code).toBeDefined() + expect(code?.temperature).toBe(0.8) + expect(code?.color).toBe("#00FF00") + }, + }) +}) + +test("default_agent: 'build' returns code agent for backward compatibility", async () => { + await using tmp = await tmpdir({ + config: { + default_agent: "build", + }, + }) + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const agent = await Agent.defaultAgent() + expect(agent).toBe("code") + }, + }) +}) + +test("agent.build disable removes code agent for backward compatibility", async () => { + await using tmp = await tmpdir({ + config: { + agent: { + build: { disable: true }, + }, + }, + }) + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const code = await Agent.get("code") + expect(code).toBeUndefined() + const agents = await Agent.list() + const names = agents.map((a) => a.name) + expect(names).not.toContain("code") + }, + }) +}) +// kilocode_change end diff --git a/packages/opencode/test/cli/tui/transcript.test.ts b/packages/opencode/test/cli/tui/transcript.test.ts index 8dd5187545..2f4b5bd9b0 100644 --- a/packages/opencode/test/cli/tui/transcript.test.ts +++ b/packages/opencode/test/cli/tui/transcript.test.ts @@ -13,7 +13,7 @@ describe("transcript", () => { id: "msg_123", sessionID: "ses_123", role: "assistant", - agent: "build", + agent: "code", // kilocode_change modelID: "claude-sonnet-4-20250514", providerID: "anthropic", mode: "", @@ -26,7 +26,7 @@ describe("transcript", () => { test("includes metadata when enabled", () => { const result = formatAssistantHeader(baseMsg, true) - expect(result).toBe("## Assistant (Build · claude-sonnet-4-20250514 · 5.4s)\n\n") + expect(result).toBe("## Assistant (Code · claude-sonnet-4-20250514 · 5.4s)\n\n") // kilocode_change }) test("excludes metadata when disabled", () => { @@ -37,7 +37,7 @@ describe("transcript", () => { test("handles missing completed time", () => { const msg = { ...baseMsg, time: { created: 1000000 } } const result = formatAssistantHeader(msg as AssistantMessage, true) - expect(result).toBe("## Assistant (Build · claude-sonnet-4-20250514)\n\n") + expect(result).toBe("## Assistant (Code · claude-sonnet-4-20250514)\n\n") // kilocode_change }) test("titlecases agent name", () => { @@ -178,7 +178,7 @@ describe("transcript", () => { id: "msg_123", sessionID: "ses_123", role: "user", - agent: "build", + agent: "code", // kilocode_change model: { providerID: "anthropic", modelID: "claude-sonnet-4-20250514" }, time: { created: 1000000 }, } @@ -193,7 +193,7 @@ describe("transcript", () => { id: "msg_123", sessionID: "ses_123", role: "assistant", - agent: "build", + agent: "code", // kilocode_change modelID: "claude-sonnet-4-20250514", providerID: "anthropic", mode: "", @@ -205,7 +205,7 @@ describe("transcript", () => { } const parts: Part[] = [{ id: "p1", sessionID: "ses_123", messageID: "msg_123", type: "text", text: "Hi there" }] const result = formatMessage(msg, parts, options) - expect(result).toContain("## Assistant (Build · claude-sonnet-4-20250514 · 5.4s)") + expect(result).toContain("## Assistant (Code · claude-sonnet-4-20250514 · 5.4s)") // kilocode_change expect(result).toContain("Hi there") }) }) @@ -223,7 +223,7 @@ describe("transcript", () => { id: "msg_1", sessionID: "ses_abc123", role: "user" as const, - agent: "build", + agent: "code", // kilocode_change model: { providerID: "anthropic", modelID: "claude-sonnet-4-20250514" }, time: { created: 1000000000000 }, }, @@ -234,7 +234,7 @@ describe("transcript", () => { id: "msg_2", sessionID: "ses_abc123", role: "assistant" as const, - agent: "build", + agent: "code", // kilocode_change modelID: "claude-sonnet-4-20250514", providerID: "anthropic", mode: "", @@ -255,7 +255,7 @@ describe("transcript", () => { expect(result).toContain("**Session ID:** ses_abc123") expect(result).toContain("## User") expect(result).toContain("Hello") - expect(result).toContain("## Assistant (Build · claude-sonnet-4-20250514 · 0.5s)") + expect(result).toContain("## Assistant (Code · claude-sonnet-4-20250514 · 0.5s)") // kilocode_change expect(result).toContain("Hi!") expect(result).toContain("---") }) @@ -272,7 +272,7 @@ describe("transcript", () => { id: "msg_1", sessionID: "ses_abc123", role: "assistant" as const, - agent: "build", + agent: "code", // kilocode_change modelID: "claude-sonnet-4-20250514", providerID: "anthropic", mode: "", @@ -290,7 +290,7 @@ describe("transcript", () => { const result = formatTranscript(session, messages, options) expect(result).toContain("## Assistant\n\n") - expect(result).not.toContain("Build") + expect(result).not.toContain("Code") // kilocode_change expect(result).not.toContain("claude-sonnet-4-20250514") }) }) diff --git a/packages/opencode/test/config/agent-color.test.ts b/packages/opencode/test/config/agent-color.test.ts index a2c3742967..273537b1f7 100644 --- a/packages/opencode/test/config/agent-color.test.ts +++ b/packages/opencode/test/config/agent-color.test.ts @@ -14,7 +14,7 @@ test("agent color parsed from project config", async () => { JSON.stringify({ $schema: "https://opencode.ai/config.json", agent: { - build: { color: "#FFA500" }, + code: { color: "#FFA500" }, // kilocode_change }, }), ) @@ -24,7 +24,7 @@ test("agent color parsed from project config", async () => { directory: tmp.path, fn: async () => { const cfg = await Config.get() - expect(cfg.agent?.["build"]?.color).toBe("#FFA500") + expect(cfg.agent?.["code"]?.color).toBe("#FFA500") // kilocode_change }, }) }) diff --git a/packages/opencode/test/tool/apply_patch.test.ts b/packages/opencode/test/tool/apply_patch.test.ts index a08e235885..3a12210f33 100644 --- a/packages/opencode/test/tool/apply_patch.test.ts +++ b/packages/opencode/test/tool/apply_patch.test.ts @@ -9,7 +9,7 @@ const baseCtx = { sessionID: "test", messageID: "", callID: "", - agent: "build", + agent: "code", // kilocode_change abort: AbortSignal.any([]), messages: [], metadata: () => {}, diff --git a/packages/opencode/test/tool/bash.test.ts b/packages/opencode/test/tool/bash.test.ts index 454293c8fb..3f19db304b 100644 --- a/packages/opencode/test/tool/bash.test.ts +++ b/packages/opencode/test/tool/bash.test.ts @@ -10,7 +10,7 @@ const ctx = { sessionID: "test", messageID: "", callID: "", - agent: "build", + agent: "code", // kilocode_change abort: AbortSignal.any([]), messages: [], metadata: () => {}, diff --git a/packages/opencode/test/tool/external-directory.test.ts b/packages/opencode/test/tool/external-directory.test.ts index 33c5e2c739..716dd9a3ff 100644 --- a/packages/opencode/test/tool/external-directory.test.ts +++ b/packages/opencode/test/tool/external-directory.test.ts @@ -9,7 +9,7 @@ const baseCtx: Omit = { sessionID: "test", messageID: "", callID: "", - agent: "build", + agent: "code", // kilocode_change abort: AbortSignal.any([]), messages: [], metadata: () => {}, diff --git a/packages/opencode/test/tool/grep.test.ts b/packages/opencode/test/tool/grep.test.ts index e774580df6..7c7b31cf58 100644 --- a/packages/opencode/test/tool/grep.test.ts +++ b/packages/opencode/test/tool/grep.test.ts @@ -8,7 +8,7 @@ const ctx = { sessionID: "test", messageID: "", callID: "", - agent: "build", + agent: "code", // kilocode_change abort: AbortSignal.any([]), messages: [], metadata: () => {}, diff --git a/packages/opencode/test/tool/read.test.ts b/packages/opencode/test/tool/read.test.ts index afa14bc6cb..dda648c558 100644 --- a/packages/opencode/test/tool/read.test.ts +++ b/packages/opencode/test/tool/read.test.ts @@ -12,7 +12,7 @@ const ctx = { sessionID: "test", messageID: "", callID: "", - agent: "build", + agent: "code", // kilocode_change abort: AbortSignal.any([]), messages: [], metadata: () => {}, @@ -136,7 +136,9 @@ describe("tool.read env file permissions", () => { ["environment.ts", false], ] - describe.each(["build", "plan"])("agent=%s", (agentName) => { + // kilocode_change start - renamed from "build" to "code" + describe.each(["code", "plan"])("agent=%s", (agentName) => { + // kilocode_change end test.each(cases)("%s asks=%s", async (filename, shouldAsk) => { await using tmp = await tmpdir({ init: (dir) => Bun.write(path.join(dir, filename), "content"), diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index d80734812a..a1a1d481bf 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -1671,7 +1671,7 @@ export type Config = { */ small_model?: string /** - * Default agent to use when none is specified. Must be a primary agent. Falls back to 'build' if not set or if the specified agent is invalid. + * Default agent to use when none is specified. Must be a primary agent. Falls back to 'code' if not set or if the specified agent is invalid. */ default_agent?: string /** From 3603dbd408d7072bb91486ffcfb3d37665290353 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Tue, 3 Feb 2026 07:05:22 +0000 Subject: [PATCH 03/15] chore: generate --- packages/sdk/openapi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sdk/openapi.json b/packages/sdk/openapi.json index a02c5dff37..74c91210bc 100644 --- a/packages/sdk/openapi.json +++ b/packages/sdk/openapi.json @@ -9821,7 +9821,7 @@ "type": "string" }, "default_agent": { - "description": "Default agent to use when none is specified. Must be a primary agent. Falls back to 'build' if not set or if the specified agent is invalid.", + "description": "Default agent to use when none is specified. Must be a primary agent. Falls back to 'code' if not set or if the specified agent is invalid.", "type": "string" }, "username": { From 6147c37715a02b24fdc0027b39f411191d322625 Mon Sep 17 00:00:00 2001 From: Bernardo Ferrari Date: Tue, 3 Feb 2026 04:23:35 -0300 Subject: [PATCH 04/15] Improve news on hover (#83) --- .../components/dialog-kilo-notifications.tsx | 75 +++++++++++++------ .../tui/components/notification-banner.tsx | 24 ++++-- 2 files changed, 69 insertions(+), 30 deletions(-) diff --git a/packages/kilo-gateway/src/tui/components/dialog-kilo-notifications.tsx b/packages/kilo-gateway/src/tui/components/dialog-kilo-notifications.tsx index 4b2d75577d..166dedc9c3 100644 --- a/packages/kilo-gateway/src/tui/components/dialog-kilo-notifications.tsx +++ b/packages/kilo-gateway/src/tui/components/dialog-kilo-notifications.tsx @@ -6,7 +6,7 @@ * Each notification shows title, message, and clickable action link. */ -import { For } from "solid-js" +import { createSignal, For } from "solid-js" import { getTUIDependencies } from "../context.js" import type { KilocodeNotification } from "../../api/notifications.js" @@ -20,6 +20,7 @@ export function DialogKiloNotifications(props: DialogKiloNotificationsProps) { const TextAttributes = deps.TextAttributes const dialog = deps.useDialog() const { theme } = deps.useTheme() + const [closeHover, setCloseHover] = createSignal(false) deps.useKeyboard((evt: any) => { if (evt.name === "escape" || evt.name === "return") { @@ -33,33 +34,59 @@ export function DialogKiloNotifications(props: DialogKiloNotificationsProps) { News - esc + setCloseHover(true)} + onMouseOut={() => setCloseHover(false)} + onMouseUp={() => dialog.clear()} + > + esc + - + - {(notification) => ( - - - * - - {notification.title} - + {(notification) => { + const [hover, setHover] = createSignal(false) + + return ( + setHover(true)} + onMouseOut={() => setHover(false)} + > + + * + + {notification.title} + + + + + {notification.message} + + {notification.action && ( + + + [{notification.action.actionText}] + + + )} + - - - {notification.message} - - {notification.action && ( - - - [{notification.action.actionText}] - - - )} - - - )} + ) + }} diff --git a/packages/kilo-gateway/src/tui/components/notification-banner.tsx b/packages/kilo-gateway/src/tui/components/notification-banner.tsx index cc13e77bed..f156cbd36b 100644 --- a/packages/kilo-gateway/src/tui/components/notification-banner.tsx +++ b/packages/kilo-gateway/src/tui/components/notification-banner.tsx @@ -10,7 +10,7 @@ * Message text with word wrap... */ -import { Show } from "solid-js" +import { createSignal, Show } from "solid-js" import { getTUIDependencies } from "../context.js" import type { KilocodeNotification } from "../../api/notifications.js" @@ -23,19 +23,31 @@ interface NotificationBannerProps { export function NotificationBanner(props: NotificationBannerProps) { const deps = getTUIDependencies() const { theme } = deps.useTheme() + const [hover, setHover] = createSignal(false) return ( - + setHover(true)} + onMouseOut={() => setHover(false)} + onMouseUp={props.onClick} + > {/* Line 1: Icon + Title + Count */} - + * - + {props.notification.title} 0}> - + ({props.totalCount} new) @@ -43,7 +55,7 @@ export function NotificationBanner(props: NotificationBannerProps) { {/* Line 2: Message (indented to align under title) */} - + {props.notification.message} From 13ed01bd2b302377e287f683a554a76270dce12e Mon Sep 17 00:00:00 2001 From: Marius Date: Tue, 3 Feb 2026 09:39:35 +0100 Subject: [PATCH 05/15] docs: align contributing guidelines and community docs with kilocode (#82) - Update CONTRIBUTING.md with simplified Kilo CLI-specific content - Add CODE_OF_CONDUCT.md matching kilocode community standards - Add PRIVACY.md for Kilo CLI - Update LICENSE copyright to Kilo Code - Update SECURITY.md with Kilo CLI references - Update PR template with kilocode's detailed format --- .github/pull_request_template.md | 36 ++++- CODE_OF_CONDUCT.md | 128 +++++++++++++++++ CONTRIBUTING.md | 240 +++++-------------------------- LICENSE | 2 +- PRIVACY.md | 28 ++++ README.md | 14 +- SECURITY.md | 10 +- 7 files changed, 243 insertions(+), 215 deletions(-) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 PRIVACY.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index b4369fa1a4..ec41b02e95 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,3 +1,35 @@ -### What does this PR do? +## Context -### How did you verify your code works? + + +## Implementation + + + +## Screenshots + +| before | after | +| ------ | ----- | +| | | + +## How to Test + + + +## Get in Touch + + diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..b4dca2d1c5 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Kilo Code Community Code of Conduct + +## Our Pledge + +We as community members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or + advances of any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email + address, without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +hi@kilo.ai. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9b12e41a25..1d00372f96 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,32 +1,22 @@ -# Contributing to OpenCode +# Contributing to Kilo CLI -We want to make it easy for you to contribute to OpenCode. Here are the most common type of changes that get merged: +See [the Documentation for details on contributing](https://kilo.ai/docs/extending/contributing-to-kilo). -- Bug fixes -- Additional LSPs / Formatters -- Improvements to LLM performance -- Support for new providers -- Fixes for environment-specific quirks -- Missing standard behavior -- Documentation improvements +## TL;DR -However, any UI or core product feature must go through a design review with the core team before implementation. +There are lots of ways to contribute to the project: -If you are unsure if a PR would be accepted, feel free to ask a maintainer or look for issues with any of the following labels: +- **Code Contributions:** Implement new features or fix bugs +- **Documentation:** Improve existing docs or create new guides +- **Bug Reports:** Report issues you encounter +- **Feature Requests:** Suggest new features or improvements +- **Community Support:** Help other users in the community -- [`help wanted`](https://github.com/Kilo-Org/kilo/issues?q=is%3Aissue%20state%3Aopen%20label%3Ahelp-wanted) -- [`good first issue`](https://github.com/Kilo-Org/kilo/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22good%20first%20issue%22) -- [`bug`](https://github.com/Kilo-Org/kilo/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug) -- [`perf`](https://github.com/Kilo-Org/kilo/issues?q=is%3Aopen%20is%3Aissue%20label%3A%22perf%22) +The Kilo Community is [on Discord](https://kilo.ai/discord). -> [!NOTE] -> PRs that ignore these guardrails will likely be closed. +## Developing Kilo CLI -Want to take on an issue? Leave a comment and a maintainer may assign it to you unless it is something we are already working on. - -## Developing OpenCode - -- Requirements: Bun 1.3+ +- **Requirements:** Bun 1.3+ - Install dependencies and start the dev server from the repo root: ```bash @@ -36,225 +26,63 @@ Want to take on an issue? Leave a comment and a maintainer may assign it to you ### Running against a different directory -By default, `bun dev` runs OpenCode in the `packages/opencode` directory. To run it against a different directory or repository: +By default, `bun dev` runs Kilo CLI in the `packages/kilo-cli` directory. To run it against a different directory or repository: ```bash bun dev ``` -To run OpenCode in the root of the opencode repo itself: +To run Kilo CLI in the root of the repo itself: ```bash bun dev . ``` -### Building a "localcode" +### Building a "local" binary To compile a standalone executable: ```bash -./packages/opencode/script/build.ts --single +./packages/kilo-cli/script/build.ts --single ``` Then run it with: ```bash -./packages/opencode/dist/opencode-/bin/opencode +./packages/kilo-cli/dist/kilo-cli-/bin/kilo ``` Replace `` with your platform (e.g., `darwin-arm64`, `linux-x64`). -- Core pieces: - - `packages/opencode`: OpenCode core business logic & server. - - `packages/opencode/src/cli/cmd/tui/`: The TUI code, written in SolidJS with [opentui](https://github.com/sst/opentui) - - `packages/app`: The shared web UI components, written in SolidJS - - `packages/desktop`: The native desktop app, built with Tauri (wraps `packages/app`) - - `packages/plugin`: Source for `@kilocode/plugin` +### Understanding bun dev vs kilo -### Understanding bun dev vs opencode - -During development, `bun dev` is the local equivalent of the built `opencode` command. Both run the same CLI interface: +During development, `bun dev` is the local equivalent of the built `kilo` command. Both run the same CLI interface: ```bash # Development (from project root) bun dev --help # Show all available commands bun dev serve # Start headless API server bun dev web # Start server + open web interface -bun dev # Start TUI in specific directory # Production -opencode --help # Show all available commands -opencode serve # Start headless API server -opencode web # Start server + open web interface -opencode # Start TUI in specific directory +kilo --help # Show all available commands +kilo serve # Start headless API server +kilo web # Start server + open web interface ``` -### Running the API Server +### Pull Request Expectations -To start the OpenCode headless API server: - -```bash -bun dev serve -``` - -This starts the headless server on port 4096 by default. You can specify a different port: - -```bash -bun dev serve --port 8080 -``` - -### Running the Web App - -To test UI changes during development: - -1. **First, start the OpenCode server** (see [Running the API Server](#running-the-api-server) section above) -2. **Then run the web app:** - -```bash -bun run --cwd packages/app dev -``` - -This starts a local dev server at http://localhost:5173 (or similar port shown in output). Most UI changes can be tested here, but the server must be running for full functionality. - -### Running the Desktop App - -The desktop app is a native Tauri application that wraps the web UI. - -To run the native desktop app: - -```bash -bun run --cwd packages/desktop tauri dev -``` - -This starts the web dev server on http://localhost:1420 and opens the native window. - -If you only want the web dev server (no native shell): - -```bash -bun run --cwd packages/desktop dev -``` - -To create a production `dist/` and build the native app bundle: - -```bash -bun run --cwd packages/desktop tauri build -``` - -This runs `bun run --cwd packages/desktop build` automatically via Tauri’s `beforeBuildCommand`. - -> [!NOTE] -> Running the desktop app requires additional Tauri dependencies (Rust toolchain, platform-specific libraries). See the [Tauri prerequisites](https://v2.tauri.app/start/prerequisites/) for setup instructions. - -> [!NOTE] -> If you make changes to the API or SDK (e.g. `packages/opencode/src/server/server.ts`), run `./script/generate.ts` to regenerate the SDK and related files. - -Please try to follow the [style guide](./AGENTS.md) - -### Setting up a Debugger - -Bun debugging is currently rough around the edges. We hope this guide helps you get set up and avoid some pain points. - -The most reliable way to debug OpenCode is to run it manually in a terminal via `bun run --inspect= dev ...` and attach -your debugger via that URL. Other methods can result in breakpoints being mapped incorrectly, at least in VSCode (YMMV). - -Caveats: - -- If you want to run the OpenCode TUI and have breakpoints triggered in the server code, you might need to run `bun dev spawn` instead of - the usual `bun dev`. This is because `bun dev` runs the server in a worker thread and breakpoints might not work there. -- If `spawn` does not work for you, you can debug the server separately: - - Debug server: `bun run --inspect=ws://localhost:6499/ --cwd packages/opencode ./src/index.ts serve --port 4096`, - then attach TUI with `opencode attach http://localhost:4096` - - Debug TUI: `bun run --inspect=ws://localhost:6499/ --cwd packages/opencode --conditions=browser ./src/index.ts` - -Other tips and tricks: - -- You might want to use `--inspect-wait` or `--inspect-brk` instead of `--inspect`, depending on your workflow -- Specifying `--inspect=ws://localhost:6499/` on every invocation can be tiresome, you may want to `export BUN_OPTIONS=--inspect=ws://localhost:6499/` instead - -#### VSCode Setup - -If you use VSCode, you can use our example configurations [.vscode/settings.example.json](.vscode/settings.example.json) and [.vscode/launch.example.json](.vscode/launch.example.json). - -Some debug methods that can be problematic: - -- Debug configurations with `"request": "launch"` can have breakpoints incorrectly mapped and thus unusable -- The same problem arises when running OpenCode in the VSCode `JavaScript Debug Terminal` - -With that said, you may want to try these methods, as they might work for you. - -## Pull Request Expectations - -### Issue First Policy - -**All PRs must reference an existing issue.** Before opening a PR, open an issue describing the bug or feature. This helps maintainers triage and prevents duplicate work. PRs without a linked issue may be closed without review. - -- Use `Fixes #123` or `Closes #123` in your PR description to link the issue -- For small fixes, a brief issue is fine - just enough context for maintainers to understand the problem - -### General Requirements - -- Keep pull requests small and focused -- Explain the issue and why your change fixes it -- Before adding new functionality, ensure it doesn't already exist elsewhere in the codebase - -### UI Changes - -If your PR includes UI changes, please include screenshots or videos showing the before and after. This helps maintainers review faster and gives you quicker feedback. - -### Logic Changes - -For non-UI changes (bug fixes, new features, refactors), explain **how you verified it works**: - -- What did you test? -- How can a reviewer reproduce/confirm the fix? - -### No AI-Generated Walls of Text - -Long, AI-generated PR descriptions and issues are not acceptable and may be ignored. Respect the maintainers' time: - -- Write short, focused descriptions -- Explain what changed and why in your own words -- If you can't explain it briefly, your PR might be too large - -### PR Titles - -PR titles should follow conventional commit standards: - -- `feat:` new feature or functionality -- `fix:` bug fix -- `docs:` documentation or README changes -- `chore:` maintenance tasks, dependency updates, etc. -- `refactor:` code refactoring without changing behavior -- `test:` adding or updating tests - -You can optionally include a scope to indicate which package is affected: - -- `feat(app):` feature in the app package -- `fix(desktop):` bug fix in the desktop package -- `chore(opencode):` maintenance in the opencode package - -Examples: - -- `docs: update contributing guidelines` -- `fix: resolve crash on startup` -- `feat: add dark mode support` -- `feat(app): add dark mode support` -- `fix(desktop): resolve crash on startup` -- `chore: bump dependency versions` +- **Issue First Policy:** All PRs must reference an existing issue. +- **UI Changes:** Include screenshots or videos (before/after). +- **Logic Changes:** Explain how you verified it works. +- **PR Titles:** Follow conventional commit standards (`feat:`, `fix:`, `docs:`, etc.). ### Style Preferences -These are not strictly enforced, they are just general guidelines: - -- **Functions:** Keep logic within a single function unless breaking it out adds clear reuse or composition benefits. -- **Destructuring:** Do not do unnecessary destructuring of variables. -- **Control flow:** Avoid `else` statements. -- **Error handling:** Prefer `.catch(...)` instead of `try`/`catch` when possible. -- **Types:** Reach for precise types and avoid `any`. -- **Variables:** Stick to immutable patterns and avoid `let`. -- **Naming:** Choose concise single-word identifiers when they remain descriptive. -- **Runtime APIs:** Use Bun helpers such as `Bun.file()` when they fit the use case. - -## Feature Requests - -For net-new functionality, start with a design conversation. Open an issue describing the problem, your proposed approach (optional), and why it belongs in OpenCode. The core team will help decide whether it should move forward; please wait for that approval instead of opening a feature PR directly. +- **Functions:** Keep logic within a single function unless breaking it out adds clear reuse. +- **Destructuring:** Avoid unnecessary destructuring. +- **Control flow:** Avoid `else` statements; prefer early returns. +- **Types:** Avoid `any`. +- **Variables:** Prefer `const`. +- **Naming:** Concise single-word identifiers when descriptive. +- **Runtime APIs:** Use Bun helpers (e.g., `Bun.file()`). diff --git a/LICENSE b/LICENSE index 6439474bee..81a8bb2f98 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 opencode +Copyright (c) 2025 Kilo Code Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/PRIVACY.md b/PRIVACY.md new file mode 100644 index 0000000000..065b6a58b4 --- /dev/null +++ b/PRIVACY.md @@ -0,0 +1,28 @@ +# Kilo CLI Privacy Policy + +**Last Updated: March 7th, 2025** + +Kilo CLI respects your privacy and is committed to transparency about how we handle your data. Below is a simple breakdown of where key pieces of data go—and, importantly, where they don't. + +### **Where Your Data Goes (And Where It Doesn't)** + +- **Code & Files**: Kilo CLI accesses files on your local machine when needed for AI-assisted features. When you send commands to Kilo CLI, relevant files may be transmitted to your chosen AI model provider (e.g., OpenAI, Anthropic, OpenRouter) to generate responses. We do not have access to this data, but AI providers may store it per their privacy policies. +- **Commands**: Any commands executed through Kilo CLI happen on your local environment. However, when you use AI-powered features, the relevant code and context from your commands may be transmitted to your chosen AI model provider (e.g., OpenAI, Anthropic, OpenRouter) to generate responses. We do not have access to or store this data, but AI providers may process it per their privacy policies. +- **Prompts & AI Requests**: When you use AI-powered features, your prompts and relevant project context are sent to your chosen AI model provider (e.g., OpenAI, Anthropic, OpenRouter) to generate responses. We do not store or process this data. These AI providers have their own privacy policies and may store data per their terms of service. +- **API Keys & Credentials**: If you enter an API key (e.g., to connect an AI model), it is stored locally on your device and never sent to us or any third party, except the provider you have chosen. + +### **Your Choices & Control** + +- You can run models locally to prevent data being sent to third-parties. + +### **Security & Updates** + +We take reasonable measures to secure your data, but no system is 100% secure. If our privacy policy changes, we will update this document and note the changes in our release notes. + +### **Contact Us** + +For any privacy-related questions, you can reach out to us at hi@kilo.ai. + +--- + +By using Kilo CLI, you agree to this Privacy Policy. diff --git a/README.md b/README.md index 9d443a6982..df67978d3e 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,18 @@ --- +### Installation + +```bash +# npm +npm install -g @kilocode/cli + +# Or run directly with npx +npx @kilocode/cli +``` + +Then run `kilo` in any project directory to start. + ### Agents Kilo CLI includes two built-in agents you can switch between using the `Tab` key: @@ -69,7 +81,7 @@ If you're interested in contributing, please read our [contributing docs](./CONT #### Where did Kilo CLI come from? -Kilo CLI is a fork of [OpenCode](https://github.com/Kilo-Org/kilo), enhanced to work within the Kilo agentic engineering platform. +Kilo CLI is a fork of [OpenCode](https://github.com/anomalyco/opencode), enhanced to work within the Kilo agentic engineering platform. --- diff --git a/SECURITY.md b/SECURITY.md index 88015f337f..beb53a8a65 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,17 +4,17 @@ ### Overview -OpenCode is an AI-powered coding assistant that runs locally on your machine. It provides an agent system with access to powerful tools including shell execution, file operations, and web access. +Kilo CLI is an AI-powered coding assistant that runs locally on your machine. It provides an agent system with access to powerful tools including shell execution, file operations, and web access. ### No Sandbox -OpenCode does **not** sandbox the agent. The permission system exists as a UX feature to help users stay aware of what actions the agent is taking - it prompts for confirmation before executing commands, writing files, etc. However, it is not designed to provide security isolation. +Kilo CLI does **not** sandbox the agent. The permission system exists as a UX feature to help users stay aware of what actions the agent is taking - it prompts for confirmation before executing commands, writing files, etc. However, it is not designed to provide security isolation. -If you need true isolation, run OpenCode inside a Docker container or VM. +If you need true isolation, run Kilo CLI inside a Docker container or VM. ### Server Mode -Server mode is opt-in only. When enabled, set `OPENCODE_SERVER_PASSWORD` to require HTTP Basic Auth. Without this, the server runs unauthenticated (with a warning). It is the end user's responsibility to secure the server - any functionality it provides is not a vulnerability. +Server mode is opt-in only. When enabled, set `KILO_SERVER_PASSWORD` to require HTTP Basic Auth. Without this, the server runs unauthenticated (with a warning). It is the end user's responsibility to secure the server - any functionality it provides is not a vulnerability. ### Out of Scope @@ -38,4 +38,4 @@ The team will send a response indicating the next steps in handling your report. ## Escalation -If you do not receive an acknowledgement of your report within 6 business days, you may send an email to security@anoma.ly +If you do not receive an acknowledgement of your report within 6 business days, you may send an email to hi@kilo.ai From b468a59726202ae20b38481addba3aa1eaab5578 Mon Sep 17 00:00:00 2001 From: Marius Date: Tue, 3 Feb 2026 09:40:15 +0100 Subject: [PATCH 06/15] fix: add repository field for npm provenance validation (#85) --- packages/opencode/script/build.ts | 4 ++++ packages/opencode/script/publish.ts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/packages/opencode/script/build.ts b/packages/opencode/script/build.ts index 13857fe4d4..92af0fd5bf 100755 --- a/packages/opencode/script/build.ts +++ b/packages/opencode/script/build.ts @@ -171,6 +171,10 @@ for (const item of targets) { version: Script.version, os: [item.os], cpu: [item.arch], + repository: { + type: "git", + url: "https://github.com/Kilo-Org/kilo", + }, }, null, 2, diff --git a/packages/opencode/script/publish.ts b/packages/opencode/script/publish.ts index 4ce0074ab3..a6f37171a5 100755 --- a/packages/opencode/script/publish.ts +++ b/packages/opencode/script/publish.ts @@ -31,6 +31,10 @@ await Bun.file(`./dist/${pkg.name}/package.json`).write( }, version: Script.version, optionalDependencies: binaries, + repository: { + type: "git", + url: "https://github.com/Kilo-Org/kilo", + }, }, null, 2, From 38c6b26db900619f9c432778871d7dbf48f78228 Mon Sep 17 00:00:00 2001 From: Marius Date: Tue, 3 Feb 2026 09:42:20 +0100 Subject: [PATCH 07/15] feat: add Claude extended thinking variants for Kilo Gateway (#86) Enable reasoning effort level cycling (Ctrl+T) for Claude models through Kilo Gateway by: - Adding @kilocode/kilo-gateway to sdkKey() to use 'openrouter' key for provider options - Adding dedicated variants() case for Claude/Anthropic models with full effort levels (none, minimal, low, medium, high, xhigh) - Supporting grok-3-mini reasoning variants through Kilo Gateway - Fixing smallOptions() to use correct reasoning.effort format OpenRouter maps effort levels to budget_tokens percentages: - xhigh: 95%, high: 80%, medium: 50%, low: 20%, minimal: 10%, none: 0% --- packages/opencode/src/provider/transform.ts | 21 +++- .../opencode/test/provider/transform.test.ts | 97 +++++++++++++++++++ 2 files changed, 114 insertions(+), 4 deletions(-) diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts index 10f4bd7aee..4fecb5b44e 100644 --- a/packages/opencode/src/provider/transform.ts +++ b/packages/opencode/src/provider/transform.ts @@ -34,6 +34,7 @@ export namespace ProviderTransform { case "@ai-sdk/gateway": return "gateway" case "@openrouter/ai-sdk-provider": + case "@kilocode/kilo-gateway": // kilocode_change return "openrouter" } return undefined @@ -330,7 +331,8 @@ export namespace ProviderTransform { // see: https://docs.x.ai/docs/guides/reasoning#control-how-hard-the-model-thinks if (id.includes("grok") && id.includes("grok-3-mini")) { - if (model.api.npm === "@openrouter/ai-sdk-provider") { + if (model.api.npm === "@openrouter/ai-sdk-provider" || model.api.npm === "@kilocode/kilo-gateway") { + // kilocode_change return { low: { reasoning: { effort: "low" } }, high: { reasoning: { effort: "high" } }, @@ -344,8 +346,18 @@ export namespace ProviderTransform { if (id.includes("grok")) return {} switch (model.api.npm) { + // kilocode_change start + case "@kilocode/kilo-gateway": + // Claude/Anthropic models support reasoning via effort levels + // OpenRouter maps these to budget_tokens percentages (xhigh=95%, high=80%, medium=50%, low=20%, minimal=10%, none=0%) + if (model.id.includes("claude") || model.id.includes("anthropic")) { + return Object.fromEntries(OPENAI_EFFORTS.map((effort) => [effort, { reasoning: { effort } }])) + } + if (!model.id.includes("gpt") && !model.id.includes("gemini-3")) return {} + return Object.fromEntries(OPENAI_EFFORTS.map((effort) => [effort, { reasoning: { effort } }])) + // kilocode_change end + case "@openrouter/ai-sdk-provider": - case "@kilocode/kilo-gateway": // kilocode_change if (!model.id.includes("gpt") && !model.id.includes("gemini-3")) return {} return Object.fromEntries(OPENAI_EFFORTS.map((effort) => [effort, { reasoning: { effort } }])) @@ -632,11 +644,12 @@ export namespace ProviderTransform { } return { thinkingConfig: { thinkingBudget: 0 } } } - if (model.providerID === "openrouter") { + if (model.providerID === "openrouter" || model.api.npm === "@kilocode/kilo-gateway") { + // kilocode_change if (model.api.id.includes("google")) { return { reasoning: { enabled: false } } } - return { reasoningEffort: "minimal" } + return { reasoning: { effort: "minimal" } } // kilocode_change - use reasoning.effort for OpenRouter API } return {} } diff --git a/packages/opencode/test/provider/transform.test.ts b/packages/opencode/test/provider/transform.test.ts index 1d69a2a295..61c1615b26 100644 --- a/packages/opencode/test/provider/transform.test.ts +++ b/packages/opencode/test/provider/transform.test.ts @@ -1206,6 +1206,103 @@ describe("ProviderTransform.variants", () => { }) }) + // kilocode_change start + describe("@kilocode/kilo-gateway", () => { + test("claude models return OPENAI_EFFORTS with reasoning", () => { + const model = createMockModel({ + id: "kilo/anthropic/claude-sonnet-4", + providerID: "kilo", + api: { + id: "anthropic/claude-sonnet-4", + url: "https://gateway.kilo.ai", + npm: "@kilocode/kilo-gateway", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["none", "minimal", "low", "medium", "high", "xhigh"]) + expect(result.none).toEqual({ reasoning: { effort: "none" } }) + expect(result.low).toEqual({ reasoning: { effort: "low" } }) + expect(result.medium).toEqual({ reasoning: { effort: "medium" } }) + expect(result.high).toEqual({ reasoning: { effort: "high" } }) + expect(result.xhigh).toEqual({ reasoning: { effort: "xhigh" } }) + }) + + test("anthropic models return OPENAI_EFFORTS with reasoning", () => { + const model = createMockModel({ + id: "kilo/anthropic/claude-opus-4", + providerID: "kilo", + api: { + id: "anthropic/claude-opus-4", + url: "https://gateway.kilo.ai", + npm: "@kilocode/kilo-gateway", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["none", "minimal", "low", "medium", "high", "xhigh"]) + expect(result.low).toEqual({ reasoning: { effort: "low" } }) + }) + + test("gpt models return OPENAI_EFFORTS with reasoning", () => { + const model = createMockModel({ + id: "kilo/openai/gpt-5", + providerID: "kilo", + api: { + id: "openai/gpt-5", + url: "https://gateway.kilo.ai", + npm: "@kilocode/kilo-gateway", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["none", "minimal", "low", "medium", "high", "xhigh"]) + expect(result.low).toEqual({ reasoning: { effort: "low" } }) + }) + + test("gemini-3 models return OPENAI_EFFORTS with reasoning", () => { + const model = createMockModel({ + id: "kilo/google/gemini-3-pro", + providerID: "kilo", + api: { + id: "google/gemini-3-pro", + url: "https://gateway.kilo.ai", + npm: "@kilocode/kilo-gateway", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["none", "minimal", "low", "medium", "high", "xhigh"]) + }) + + test("non-qualifying models return empty object", () => { + const model = createMockModel({ + id: "kilo/meta/llama-4", + providerID: "kilo", + api: { + id: "meta/llama-4", + url: "https://gateway.kilo.ai", + npm: "@kilocode/kilo-gateway", + }, + }) + const result = ProviderTransform.variants(model) + expect(result).toEqual({}) + }) + + test("grok-3-mini returns low and high with reasoning", () => { + const model = createMockModel({ + id: "kilo/x-ai/grok-3-mini", + providerID: "kilo", + api: { + id: "x-ai/grok-3-mini", + url: "https://gateway.kilo.ai", + npm: "@kilocode/kilo-gateway", + }, + }) + const result = ProviderTransform.variants(model) + expect(Object.keys(result)).toEqual(["low", "high"]) + expect(result.low).toEqual({ reasoning: { effort: "low" } }) + expect(result.high).toEqual({ reasoning: { effort: "high" } }) + }) + }) + // kilocode_change end + describe("@ai-sdk/gateway", () => { test("returns OPENAI_EFFORTS with reasoningEffort", () => { const model = createMockModel({ From f27c1a827759c7f8fee05b40b35f4fb9b24e00e0 Mon Sep 17 00:00:00 2001 From: Marius Date: Tue, 3 Feb 2026 10:22:12 +0100 Subject: [PATCH 08/15] Revert "feat: add Claude extended thinking variants for Kilo Gateway (#86)" (#87) This reverts commit 38c6b26db900619f9c432778871d7dbf48f78228. --- packages/opencode/src/provider/transform.ts | 21 +--- .../opencode/test/provider/transform.test.ts | 97 ------------------- 2 files changed, 4 insertions(+), 114 deletions(-) diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts index 4fecb5b44e..10f4bd7aee 100644 --- a/packages/opencode/src/provider/transform.ts +++ b/packages/opencode/src/provider/transform.ts @@ -34,7 +34,6 @@ export namespace ProviderTransform { case "@ai-sdk/gateway": return "gateway" case "@openrouter/ai-sdk-provider": - case "@kilocode/kilo-gateway": // kilocode_change return "openrouter" } return undefined @@ -331,8 +330,7 @@ export namespace ProviderTransform { // see: https://docs.x.ai/docs/guides/reasoning#control-how-hard-the-model-thinks if (id.includes("grok") && id.includes("grok-3-mini")) { - if (model.api.npm === "@openrouter/ai-sdk-provider" || model.api.npm === "@kilocode/kilo-gateway") { - // kilocode_change + if (model.api.npm === "@openrouter/ai-sdk-provider") { return { low: { reasoning: { effort: "low" } }, high: { reasoning: { effort: "high" } }, @@ -346,18 +344,8 @@ export namespace ProviderTransform { if (id.includes("grok")) return {} switch (model.api.npm) { - // kilocode_change start - case "@kilocode/kilo-gateway": - // Claude/Anthropic models support reasoning via effort levels - // OpenRouter maps these to budget_tokens percentages (xhigh=95%, high=80%, medium=50%, low=20%, minimal=10%, none=0%) - if (model.id.includes("claude") || model.id.includes("anthropic")) { - return Object.fromEntries(OPENAI_EFFORTS.map((effort) => [effort, { reasoning: { effort } }])) - } - if (!model.id.includes("gpt") && !model.id.includes("gemini-3")) return {} - return Object.fromEntries(OPENAI_EFFORTS.map((effort) => [effort, { reasoning: { effort } }])) - // kilocode_change end - case "@openrouter/ai-sdk-provider": + case "@kilocode/kilo-gateway": // kilocode_change if (!model.id.includes("gpt") && !model.id.includes("gemini-3")) return {} return Object.fromEntries(OPENAI_EFFORTS.map((effort) => [effort, { reasoning: { effort } }])) @@ -644,12 +632,11 @@ export namespace ProviderTransform { } return { thinkingConfig: { thinkingBudget: 0 } } } - if (model.providerID === "openrouter" || model.api.npm === "@kilocode/kilo-gateway") { - // kilocode_change + if (model.providerID === "openrouter") { if (model.api.id.includes("google")) { return { reasoning: { enabled: false } } } - return { reasoning: { effort: "minimal" } } // kilocode_change - use reasoning.effort for OpenRouter API + return { reasoningEffort: "minimal" } } return {} } diff --git a/packages/opencode/test/provider/transform.test.ts b/packages/opencode/test/provider/transform.test.ts index 61c1615b26..1d69a2a295 100644 --- a/packages/opencode/test/provider/transform.test.ts +++ b/packages/opencode/test/provider/transform.test.ts @@ -1206,103 +1206,6 @@ describe("ProviderTransform.variants", () => { }) }) - // kilocode_change start - describe("@kilocode/kilo-gateway", () => { - test("claude models return OPENAI_EFFORTS with reasoning", () => { - const model = createMockModel({ - id: "kilo/anthropic/claude-sonnet-4", - providerID: "kilo", - api: { - id: "anthropic/claude-sonnet-4", - url: "https://gateway.kilo.ai", - npm: "@kilocode/kilo-gateway", - }, - }) - const result = ProviderTransform.variants(model) - expect(Object.keys(result)).toEqual(["none", "minimal", "low", "medium", "high", "xhigh"]) - expect(result.none).toEqual({ reasoning: { effort: "none" } }) - expect(result.low).toEqual({ reasoning: { effort: "low" } }) - expect(result.medium).toEqual({ reasoning: { effort: "medium" } }) - expect(result.high).toEqual({ reasoning: { effort: "high" } }) - expect(result.xhigh).toEqual({ reasoning: { effort: "xhigh" } }) - }) - - test("anthropic models return OPENAI_EFFORTS with reasoning", () => { - const model = createMockModel({ - id: "kilo/anthropic/claude-opus-4", - providerID: "kilo", - api: { - id: "anthropic/claude-opus-4", - url: "https://gateway.kilo.ai", - npm: "@kilocode/kilo-gateway", - }, - }) - const result = ProviderTransform.variants(model) - expect(Object.keys(result)).toEqual(["none", "minimal", "low", "medium", "high", "xhigh"]) - expect(result.low).toEqual({ reasoning: { effort: "low" } }) - }) - - test("gpt models return OPENAI_EFFORTS with reasoning", () => { - const model = createMockModel({ - id: "kilo/openai/gpt-5", - providerID: "kilo", - api: { - id: "openai/gpt-5", - url: "https://gateway.kilo.ai", - npm: "@kilocode/kilo-gateway", - }, - }) - const result = ProviderTransform.variants(model) - expect(Object.keys(result)).toEqual(["none", "minimal", "low", "medium", "high", "xhigh"]) - expect(result.low).toEqual({ reasoning: { effort: "low" } }) - }) - - test("gemini-3 models return OPENAI_EFFORTS with reasoning", () => { - const model = createMockModel({ - id: "kilo/google/gemini-3-pro", - providerID: "kilo", - api: { - id: "google/gemini-3-pro", - url: "https://gateway.kilo.ai", - npm: "@kilocode/kilo-gateway", - }, - }) - const result = ProviderTransform.variants(model) - expect(Object.keys(result)).toEqual(["none", "minimal", "low", "medium", "high", "xhigh"]) - }) - - test("non-qualifying models return empty object", () => { - const model = createMockModel({ - id: "kilo/meta/llama-4", - providerID: "kilo", - api: { - id: "meta/llama-4", - url: "https://gateway.kilo.ai", - npm: "@kilocode/kilo-gateway", - }, - }) - const result = ProviderTransform.variants(model) - expect(result).toEqual({}) - }) - - test("grok-3-mini returns low and high with reasoning", () => { - const model = createMockModel({ - id: "kilo/x-ai/grok-3-mini", - providerID: "kilo", - api: { - id: "x-ai/grok-3-mini", - url: "https://gateway.kilo.ai", - npm: "@kilocode/kilo-gateway", - }, - }) - const result = ProviderTransform.variants(model) - expect(Object.keys(result)).toEqual(["low", "high"]) - expect(result.low).toEqual({ reasoning: { effort: "low" } }) - expect(result.high).toEqual({ reasoning: { effort: "high" } }) - }) - }) - // kilocode_change end - describe("@ai-sdk/gateway", () => { test("returns OPENAI_EFFORTS with reasoningEffort", () => { const model = createMockModel({ From 70aba4ff969811e8c99a4f45a757e457c401f227 Mon Sep 17 00:00:00 2001 From: Marius Date: Tue, 3 Feb 2026 10:45:43 +0100 Subject: [PATCH 09/15] fix: include encrypted reasoning content for GPT models via Kilo Gateway (#88) GPT models accessed through Kilo Gateway were missing the 'include: ["reasoning.encrypted_content"]' option, causing organization_id mismatch errors when encrypted reasoning content was passed back in multi-turn conversations. - Add reasoningSummary and include options to effortVariants for Kilo Gateway - Extend options() condition to include @kilocode/kilo-gateway npm package --- packages/opencode/src/provider/transform.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts index 10f4bd7aee..a024882a3c 100644 --- a/packages/opencode/src/provider/transform.ts +++ b/packages/opencode/src/provider/transform.ts @@ -345,10 +345,24 @@ export namespace ProviderTransform { switch (model.api.npm) { case "@openrouter/ai-sdk-provider": - case "@kilocode/kilo-gateway": // kilocode_change if (!model.id.includes("gpt") && !model.id.includes("gemini-3")) return {} return Object.fromEntries(OPENAI_EFFORTS.map((effort) => [effort, { reasoning: { effort } }])) + // kilocode_change start - GPT models via Kilo need encrypted reasoning content to avoid org_id mismatch + case "@kilocode/kilo-gateway": + if (!model.id.includes("gpt") && !model.id.includes("gemini-3")) return {} + return Object.fromEntries( + OPENAI_EFFORTS.map((effort) => [ + effort, + { + reasoning: { effort }, + reasoningSummary: "auto", + include: ["reasoning.encrypted_content"], + }, + ]), + ) + // kilocode_change end + // TODO: YOU CANNOT SET max_tokens if this is set!!! case "@ai-sdk/gateway": return Object.fromEntries(OPENAI_EFFORTS.map((effort) => [effort, { reasoningEffort: effort }])) @@ -604,7 +618,8 @@ export namespace ProviderTransform { result["textVerbosity"] = "low" } - if (input.model.providerID.startsWith("opencode")) { + // kilocode_change - include kilo provider for encrypted reasoning content + if (input.model.providerID.startsWith("opencode") || input.model.api.npm === "@kilocode/kilo-gateway") { result["promptCacheKey"] = input.sessionID result["include"] = ["reasoning.encrypted_content"] result["reasoningSummary"] = "auto" From e871803ff81fc1780d38a46fd1ca6a06c87862ca Mon Sep 17 00:00:00 2001 From: Marius Date: Tue, 3 Feb 2026 11:16:52 +0100 Subject: [PATCH 10/15] fix: use reasoningEffort instead of nested reasoning object for Kilo Gateway (#89) --- packages/opencode/src/provider/transform.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts index a024882a3c..875bf513aa 100644 --- a/packages/opencode/src/provider/transform.ts +++ b/packages/opencode/src/provider/transform.ts @@ -355,7 +355,7 @@ export namespace ProviderTransform { OPENAI_EFFORTS.map((effort) => [ effort, { - reasoning: { effort }, + reasoningEffort: effort, reasoningSummary: "auto", include: ["reasoning.encrypted_content"], }, From 246f4071e6d7409368bfb648b24b99d24219cc94 Mon Sep 17 00:00:00 2001 From: Marius Date: Tue, 3 Feb 2026 12:57:42 +0100 Subject: [PATCH 11/15] ci: skip stable changelog generation (#91) --- .github/workflows/publish-stable.yml | 1 + script/publish-start.ts | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish-stable.yml b/.github/workflows/publish-stable.yml index 8051910a2b..d81b0ce5db 100644 --- a/.github/workflows/publish-stable.yml +++ b/.github/workflows/publish-stable.yml @@ -68,6 +68,7 @@ jobs: env: OPENCODE_CHANNEL: latest OPENCODE_VERSION: ${{ inputs.version }} + OPENCODE_SKIP_NOTES: "1" NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/script/publish-start.ts b/script/publish-start.ts index 385a2384bc..d8564ba973 100755 --- a/script/publish-start.ts +++ b/script/publish-start.ts @@ -37,7 +37,10 @@ let notes: string[] = [] console.log("=== publishing ===\n") -if (!Script.preview) { +const skipNotes = process.env["OPENCODE_SKIP_NOTES"] === "1" // kilocode_change +if (skipNotes) console.log("changelog skipped: OPENCODE_SKIP_NOTES=1") // kilocode_change + +if (!Script.preview && !skipNotes) { const previous = await getLatestRelease() notes = await buildNotes(previous, "HEAD") // notes.unshift(highlightsTemplate) From 869b61b920f7e6b059da0b7e43d9ba828059ea07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Catriel=20M=C3=BCller?= Date: Tue, 3 Feb 2026 13:17:15 +0100 Subject: [PATCH 12/15] fix: fix release archives (#94) --- packages/opencode/script/publish.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/opencode/script/publish.ts b/packages/opencode/script/publish.ts index a6f37171a5..489bb5ba51 100755 --- a/packages/opencode/script/publish.ts +++ b/packages/opencode/script/publish.ts @@ -59,6 +59,7 @@ for (const tag of tags) { if (!Script.preview) { // Create archives for GitHub release + await $`mkdir -p dist/@kilocode` // kilocode_change for (const key of Object.keys(binaries)) { if (key.includes("linux")) { await $`tar -czf ../../${key}.tar.gz *`.cwd(`dist/${key}/bin`) From fe1b5f9a55dcdc10ce7c0dafe105ee776b933c08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Catriel=20M=C3=BCller?= Date: Tue, 3 Feb 2026 09:31:47 -0300 Subject: [PATCH 13/15] fix: fix release archives --- .github/workflows/publish-next.yml | 72 ------------------- packages/opencode/script/pack.ts | 9 ++- .../opencode/script/publish-registries.ts | 14 ++-- packages/opencode/script/publish.ts | 10 ++- script/publish-start.ts | 2 +- 5 files changed, 25 insertions(+), 82 deletions(-) delete mode 100644 .github/workflows/publish-next.yml diff --git a/.github/workflows/publish-next.yml b/.github/workflows/publish-next.yml deleted file mode 100644 index e55cbb8d1f..0000000000 --- a/.github/workflows/publish-next.yml +++ /dev/null @@ -1,72 +0,0 @@ -# kilocode_change - new file -# -# Next Release Workflow for Kilo CLI -# =================================== -# -# HOW TO RELEASE: -# 1. Go to GitHub Actions → publish-next -# 2. Click "Run workflow" -# 3. Optionally enter a version (e.g., 1.2.0-next.1) -# 4. Click "Run workflow" -# -# HOW USERS INSTALL: -# npm install -g @kilocode/cli@next -# -# REQUIRED GITHUB SECRETS: -# - NPM_TOKEN: npm authentication token with publish access to @kilocode/cli -# (Get from: npmjs.com → Access Tokens → Generate New Token → Automation) -# -# WHAT THIS DOES: -# - Runs the existing publish-start.ts script with OPENCODE_CHANNEL=next -# - Builds all platform binaries (Linux, macOS, Windows, x64, ARM64) -# - Publishes to npm with @next tag (won't affect stable users) -# - Version format: 0.0.0-next-{timestamp} (auto) or custom (manual input) -# - Does NOT create git tags or GitHub releases (preview mode) -# -name: publish-next -run-name: "next release ${{ inputs.version || 'auto' }}" - -on: - workflow_dispatch: - inputs: - version: - description: "Override version (optional, e.g., 1.2.0-next.1)" - required: false - type: string - -concurrency: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.version }} - -permissions: - id-token: write - contents: write - packages: write - -jobs: - publish-next: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - run: git fetch --force --tags - - - uses: ./.github/actions/setup-bun - - - uses: actions/setup-node@v4 - with: - node-version: "24" - registry-url: "https://registry.npmjs.org" - - - name: Publish Next - run: ./script/publish-start.ts - env: - OPENCODE_CHANNEL: next - OPENCODE_VERSION: ${{ inputs.version }} - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - uses: actions/upload-artifact@v4 - with: - name: kilocode-cli-next - path: packages/opencode/dist diff --git a/packages/opencode/script/pack.ts b/packages/opencode/script/pack.ts index 6534112c28..497e7f3ad1 100755 --- a/packages/opencode/script/pack.ts +++ b/packages/opencode/script/pack.ts @@ -52,13 +52,18 @@ for (const tag of tags) { if (!Script.preview) { // Create archives for GitHub release + // kilocode_change start - use absolute paths to avoid issues with scoped package names containing '/' + const archiveDir = `${dir}/dist/archives` + await $`mkdir -p ${archiveDir}` for (const key of Object.keys(binaries)) { + const archiveName = key.replace("/", "-") // @kilocode/cli-linux-arm64 → @kilocode-cli-linux-arm64 if (key.includes("linux")) { - await $`tar -czf ../../${key}.tar.gz *`.cwd(`dist/${key}/bin`) + await $`tar -czf ${archiveDir}/${archiveName}.tar.gz *`.cwd(`dist/${key}/bin`) } else { - await $`zip -r ../../${key}.zip *`.cwd(`dist/${key}/bin`) + await $`zip -r ${archiveDir}/${archiveName}.zip *`.cwd(`dist/${key}/bin`) } } + // kilocode_change end const image = "ghcr.io/Kilo-Org/kilo" const platforms = "linux/amd64,linux/arm64" diff --git a/packages/opencode/script/publish-registries.ts b/packages/opencode/script/publish-registries.ts index b6d1b686a8..41d990b5df 100644 --- a/packages/opencode/script/publish-registries.ts +++ b/packages/opencode/script/publish-registries.ts @@ -4,14 +4,20 @@ import { Script } from "@opencode-ai/script" if (!Script.preview) { // Calculate SHA values - const arm64Sha = await $`sha256sum ./dist/@kilocode/cli-linux-arm64.tar.gz | cut -d' ' -f1` + // kilocode_change start - archives now use '-' instead of '/' and are in archives/ subdirectory + const arm64Sha = await $`sha256sum ./dist/archives/@kilocode-cli-linux-arm64.tar.gz | cut -d' ' -f1` .text() .then((x) => x.trim()) - const x64Sha = await $`sha256sum ./dist/@kilocode/cli-linux-x64.tar.gz | cut -d' ' -f1`.text().then((x) => x.trim()) - const macX64Sha = await $`sha256sum ./dist/@kilocode/cli-darwin-x64.zip | cut -d' ' -f1`.text().then((x) => x.trim()) - const macArm64Sha = await $`sha256sum ./dist/@kilocode/cli-darwin-arm64.zip | cut -d' ' -f1` + const x64Sha = await $`sha256sum ./dist/archives/@kilocode-cli-linux-x64.tar.gz | cut -d' ' -f1` .text() .then((x) => x.trim()) + const macX64Sha = await $`sha256sum ./dist/archives/@kilocode-cli-darwin-x64.zip | cut -d' ' -f1` + .text() + .then((x) => x.trim()) + const macArm64Sha = await $`sha256sum ./dist/archives/@kilocode-cli-darwin-arm64.zip | cut -d' ' -f1` + .text() + .then((x) => x.trim()) + // kilocode_change end const [pkgver, _subver = ""] = Script.version.split(/(-.*)/, 2) diff --git a/packages/opencode/script/publish.ts b/packages/opencode/script/publish.ts index 489bb5ba51..1fe4a2cd79 100755 --- a/packages/opencode/script/publish.ts +++ b/packages/opencode/script/publish.ts @@ -59,14 +59,18 @@ for (const tag of tags) { if (!Script.preview) { // Create archives for GitHub release - await $`mkdir -p dist/@kilocode` // kilocode_change + // kilocode_change start - use absolute paths to avoid issues with scoped package names containing '/' + const archiveDir = `${dir}/dist/archives` + await $`mkdir -p ${archiveDir}` for (const key of Object.keys(binaries)) { + const archiveName = key.replace("/", "-") // @kilocode/cli-linux-arm64 → @kilocode-cli-linux-arm64 if (key.includes("linux")) { - await $`tar -czf ../../${key}.tar.gz *`.cwd(`dist/${key}/bin`) + await $`tar -czf ${archiveDir}/${archiveName}.tar.gz *`.cwd(`dist/${key}/bin`) } else { - await $`zip -r ../../${key}.zip *`.cwd(`dist/${key}/bin`) + await $`zip -r ${archiveDir}/${archiveName}.zip *`.cwd(`dist/${key}/bin`) } } + // kilocode_change end const image = "ghcr.io/kilo-org/kilo" // kilocode_change const platforms = "linux/amd64,linux/arm64" diff --git a/script/publish-start.ts b/script/publish-start.ts index d8564ba973..9e91c2425c 100755 --- a/script/publish-start.ts +++ b/script/publish-start.ts @@ -89,7 +89,7 @@ if (!Script.preview) { await $`git cherry-pick HEAD..origin/dev`.nothrow() await $`git push origin HEAD --tags --no-verify --force-with-lease` await new Promise((resolve) => setTimeout(resolve, 5_000)) - await $`gh release create v${Script.version} -d --title "v${Script.version}" --notes ${notes.join("\n") || "No notable changes"} ./packages/opencode/dist/*.zip ./packages/opencode/dist/*.tar.gz` + await $`gh release create v${Script.version} -d --title "v${Script.version}" --notes ${notes.join("\n") || "No notable changes"} ./packages/opencode/dist/archives/*.zip ./packages/opencode/dist/archives/*.tar.gz` // kilocode_change - archives now in subdirectory const release = await $`gh release view v${Script.version} --json id,tagName`.json() output += `release=${release.id}\n` output += `tag=${release.tagName}\n` From 60466fa9ca9c566ee9552ce20bb08487872b65fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Catriel=20M=C3=BCller?= Date: Tue, 3 Feb 2026 09:45:00 -0300 Subject: [PATCH 14/15] fix: fix docker buildx --- .github/workflows/publish-stable.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/publish-stable.yml b/.github/workflows/publish-stable.yml index d81b0ce5db..840f7e8b1f 100644 --- a/.github/workflows/publish-stable.yml +++ b/.github/workflows/publish-stable.yml @@ -53,6 +53,19 @@ jobs: - uses: ./.github/actions/setup-bun + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - uses: actions/setup-node@v4 with: node-version: "24" From c8578187c7769f32d37a11d92379f56e17657a21 Mon Sep 17 00:00:00 2001 From: kilocode Date: Tue, 3 Feb 2026 13:22:03 +0000 Subject: [PATCH 15/15] release: v1.0.13 --- bun.lock | 34 +++++++++++++------------- packages/app/package.json | 2 +- packages/console/app/package.json | 2 +- packages/console/core/package.json | 2 +- packages/console/function/package.json | 2 +- packages/console/mail/package.json | 2 +- packages/desktop/package.json | 2 +- packages/enterprise/package.json | 2 +- packages/extensions/zed/extension.toml | 12 ++++----- packages/function/package.json | 2 +- packages/kilo-gateway/package.json | 2 +- packages/kilo-telemetry/package.json | 2 +- packages/opencode/package.json | 4 +-- packages/plugin/package.json | 4 +-- packages/sdk/js/package.json | 4 +-- packages/slack/package.json | 2 +- packages/ui/package.json | 2 +- packages/util/package.json | 2 +- packages/web/package.json | 2 +- sdks/vscode/package.json | 2 +- 20 files changed, 44 insertions(+), 44 deletions(-) diff --git a/bun.lock b/bun.lock index 453b22de0f..6de021cfbc 100644 --- a/bun.lock +++ b/bun.lock @@ -24,7 +24,7 @@ }, "packages/app": { "name": "@opencode-ai/app", - "version": "1.1.42", + "version": "1.0.13", "dependencies": { "@kilocode/sdk": "workspace:*", "@kobalte/core": "catalog:", @@ -74,7 +74,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.1.42", + "version": "1.0.13", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -108,7 +108,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.1.42", + "version": "1.0.13", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -135,7 +135,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.1.42", + "version": "1.0.13", "dependencies": { "@ai-sdk/anthropic": "2.0.0", "@ai-sdk/openai": "2.0.2", @@ -159,7 +159,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.1.42", + "version": "1.0.13", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -183,7 +183,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.1.42", + "version": "1.0.13", "dependencies": { "@opencode-ai/app": "workspace:*", "@opencode-ai/ui": "workspace:*", @@ -213,7 +213,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.1.42", + "version": "1.0.13", "dependencies": { "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", @@ -242,7 +242,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.1.42", + "version": "1.0.13", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -258,7 +258,7 @@ }, "packages/kilo-gateway": { "name": "@kilocode/kilo-gateway", - "version": "1.0.0", + "version": "1.0.13", "dependencies": { "@clack/prompts": "1.0.0-alpha.1", "@kilocode/plugin": "workspace:*", @@ -290,7 +290,7 @@ }, "packages/kilo-telemetry": { "name": "@kilocode/kilo-telemetry", - "version": "1.0.0", + "version": "1.0.13", "dependencies": { "@kilocode/kilo-gateway": "workspace:*", "@opentelemetry/api": "1.9.0", @@ -310,7 +310,7 @@ }, "packages/opencode": { "name": "@kilocode/cli", - "version": "1.1.42", + "version": "1.0.13", "bin": { "kilo": "./bin/kilo", }, @@ -416,7 +416,7 @@ }, "packages/plugin": { "name": "@kilocode/plugin", - "version": "1.1.42", + "version": "1.0.13", "dependencies": { "@kilocode/sdk": "workspace:*", "zod": "catalog:", @@ -436,7 +436,7 @@ }, "packages/sdk/js": { "name": "@kilocode/sdk", - "version": "1.1.42", + "version": "1.0.13", "devDependencies": { "@hey-api/openapi-ts": "0.90.10", "@tsconfig/node22": "catalog:", @@ -447,7 +447,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.1.42", + "version": "1.0.13", "dependencies": { "@kilocode/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -460,7 +460,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.1.42", + "version": "1.0.13", "dependencies": { "@kilocode/sdk": "workspace:*", "@kobalte/core": "catalog:", @@ -502,7 +502,7 @@ }, "packages/util": { "name": "@opencode-ai/util", - "version": "1.1.42", + "version": "1.0.13", "dependencies": { "zod": "catalog:", }, @@ -513,7 +513,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.1.42", + "version": "1.0.13", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", diff --git a/packages/app/package.json b/packages/app/package.json index 4471c8987b..f93e0fc1ab 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "1.1.42", + "version": "1.0.13", "description": "", "type": "module", "exports": { diff --git a/packages/console/app/package.json b/packages/console/app/package.json index f1b0aca8f5..0f8379a4c0 100644 --- a/packages/console/app/package.json +++ b/packages/console/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-app", - "version": "1.1.42", + "version": "1.0.13", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/console/core/package.json b/packages/console/core/package.json index 59a9d2ecc4..eb967c4883 100644 --- a/packages/console/core/package.json +++ b/packages/console/core/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/console-core", - "version": "1.1.42", + "version": "1.0.13", "private": true, "type": "module", "license": "MIT", diff --git a/packages/console/function/package.json b/packages/console/function/package.json index 8cfdc1c0af..4d673c0709 100644 --- a/packages/console/function/package.json +++ b/packages/console/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-function", - "version": "1.1.42", + "version": "1.0.13", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/console/mail/package.json b/packages/console/mail/package.json index 622d34815c..fe58a23586 100644 --- a/packages/console/mail/package.json +++ b/packages/console/mail/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-mail", - "version": "1.1.42", + "version": "1.0.13", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 5ba2ec347b..7ec49676be 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/desktop", "private": true, - "version": "1.1.42", + "version": "1.0.13", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index d0e2b0135d..3af8040468 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/enterprise", - "version": "1.1.42", + "version": "1.0.13", "private": true, "type": "module", "license": "MIT", diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index dfd89907bb..ab7b0bd412 100644 --- a/packages/extensions/zed/extension.toml +++ b/packages/extensions/zed/extension.toml @@ -1,7 +1,7 @@ id = "opencode" name = "OpenCode" description = "The open source coding agent." -version = "1.1.42" +version = "1.0.13" schema_version = 1 authors = ["Anomaly"] repository = "https://github.com/Kilo-Org/kilo" @@ -11,26 +11,26 @@ name = "OpenCode" icon = "./icons/opencode.svg" [agent_servers.opencode.targets.darwin-aarch64] -archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.1.42/opencode-darwin-arm64.zip" +archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.0.13/opencode-darwin-arm64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.darwin-x86_64] -archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.1.42/opencode-darwin-x64.zip" +archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.0.13/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.1.42/opencode-linux-arm64.tar.gz" +archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.0.13/opencode-linux-arm64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-x86_64] -archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.1.42/opencode-linux-x64.tar.gz" +archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.0.13/opencode-linux-x64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.windows-x86_64] -archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.1.42/opencode-windows-x64.zip" +archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.0.13/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/function/package.json b/packages/function/package.json index 34a0f5c7ba..b58b40e9ad 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/function", - "version": "1.1.42", + "version": "1.0.13", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/kilo-gateway/package.json b/packages/kilo-gateway/package.json index f244e05f13..1d0dbfc5eb 100644 --- a/packages/kilo-gateway/package.json +++ b/packages/kilo-gateway/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/kilo-gateway", - "version": "1.0.0", + "version": "1.0.13", "type": "module", "license": "MIT", "description": "Unified Kilo Gateway package for OpenCode - authentication, provider, and API integration", diff --git a/packages/kilo-telemetry/package.json b/packages/kilo-telemetry/package.json index 35b5502e36..8534864dc1 100644 --- a/packages/kilo-telemetry/package.json +++ b/packages/kilo-telemetry/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/kilo-telemetry", - "version": "1.0.0", + "version": "1.0.13", "type": "module", "license": "MIT", "description": "Telemetry for Kilo CLI - PostHog analytics integration", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 2e26efe8e7..d7b0977ab0 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.1.42", + "version": "1.0.13", "name": "@kilocode/cli", "type": "module", "license": "MIT", @@ -75,12 +75,12 @@ "@hono/zod-validator": "catalog:", "@kilocode/kilo-gateway": "workspace:*", "@kilocode/kilo-telemetry": "workspace:*", + "@kilocode/plugin": "workspace:*", "@kilocode/sdk": "workspace:*", "@modelcontextprotocol/sdk": "1.25.2", "@octokit/graphql": "9.0.2", "@octokit/rest": "catalog:", "@openauthjs/openauth": "catalog:", - "@kilocode/plugin": "workspace:*", "@opencode-ai/script": "workspace:*", "@opencode-ai/util": "workspace:*", "@openrouter/ai-sdk-provider": "1.5.2", diff --git a/packages/plugin/package.json b/packages/plugin/package.json index a72846f170..a615192f82 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/plugin", - "version": "1.1.42", + "version": "1.0.13", "type": "module", "license": "MIT", "scripts": { @@ -25,4 +25,4 @@ "typescript": "catalog:", "@typescript/native-preview": "catalog:" } -} +} \ No newline at end of file diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 12c433abcd..9ad5fcfea9 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/sdk", - "version": "1.1.42", + "version": "1.0.13", "type": "module", "license": "MIT", "scripts": { @@ -30,4 +30,4 @@ "publishConfig": { "directory": "dist" } -} +} \ No newline at end of file diff --git a/packages/slack/package.json b/packages/slack/package.json index f6703a01d1..26794fb5b7 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/slack", - "version": "1.1.42", + "version": "1.0.13", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/ui/package.json b/packages/ui/package.json index 9efd23fd29..b8dbc98a30 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "1.1.42", + "version": "1.0.13", "type": "module", "license": "MIT", "exports": { diff --git a/packages/util/package.json b/packages/util/package.json index 06677a1132..38143cd603 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/util", - "version": "1.1.42", + "version": "1.0.13", "private": true, "type": "module", "license": "MIT", diff --git a/packages/web/package.json b/packages/web/package.json index 4e22998717..9f1a7b62a9 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -2,7 +2,7 @@ "name": "@opencode-ai/web", "type": "module", "license": "MIT", - "version": "1.1.42", + "version": "1.0.13", "scripts": { "dev": "astro dev", "dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev", diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json index 00a8e373c7..f957c454b7 100644 --- a/sdks/vscode/package.json +++ b/sdks/vscode/package.json @@ -2,7 +2,7 @@ "name": "opencode", "displayName": "opencode", "description": "opencode for VS Code", - "version": "1.1.42", + "version": "1.0.13", "publisher": "sst-dev", "repository": { "type": "git",