From abf1c88b2536cda3e3abe8b07cf2ae8e815177ea Mon Sep 17 00:00:00 2001 From: Alex Alecu Date: Thu, 21 May 2026 14:42:59 +0300 Subject: [PATCH] fix(cli): preserve local-review command context --- packages/opencode/src/session/prompt.ts | 2 +- .../local-review-command-httpapi.test.ts | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 packages/opencode/test/kilocode/server/local-review-command-httpapi.test.ts diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index 36ca71f581e..5f06bc275b8 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -1879,7 +1879,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the const agentName = cmd.agent ?? input.agent ?? (yield* agents.defaultAgent()) // kilocode_change start - allow Kilo commands to consume input before template interpolation - const resolved = yield* Effect.promise(() => + const resolved = yield* EffectBridge.fromPromise(() => KiloSessionPrompt.resolveCommand({ command: input.command, source: cmd.source, diff --git a/packages/opencode/test/kilocode/server/local-review-command-httpapi.test.ts b/packages/opencode/test/kilocode/server/local-review-command-httpapi.test.ts new file mode 100644 index 00000000000..b819fa97445 --- /dev/null +++ b/packages/opencode/test/kilocode/server/local-review-command-httpapi.test.ts @@ -0,0 +1,50 @@ +import { afterEach, describe, expect, test } from "bun:test" +import { Flag } from "@opencode-ai/core/flag/flag" +import { Server } from "../../../src/server/server" +import { SessionPaths } from "../../../src/server/routes/instance/httpapi/groups/session" +import { resetDatabase } from "../../fixture/db" +import { disposeAllInstances, tmpdir } from "../../fixture/fixture" + +const flag = Flag.KILO_EXPERIMENTAL_HTTPAPI + +afterEach(async () => { + Flag.KILO_EXPERIMENTAL_HTTPAPI = flag + await disposeAllInstances() + await resetDatabase() +}) + +describe("POST /session/:sessionID/command local-review", () => { + test("keeps invalid-base failures scoped to review validation", async () => { + await using tmp = await tmpdir({ git: true, config: { formatter: false, lsp: false } }) + Flag.KILO_EXPERIMENTAL_HTTPAPI = true + + const app = Server.Default().app + const headers = { "Content-Type": "application/json", "x-kilo-directory": tmp.path } + const created = await app.request(SessionPaths.create, { + method: "POST", + headers, + body: JSON.stringify({}), + }) + expect(created.status).toBe(200) + const session = (await created.json()) as { id: string } + + const failed = await app.request(SessionPaths.command.replace(":sessionID", session.id), { + method: "POST", + headers, + body: JSON.stringify({ + command: "local-review", + arguments: "__missing_local_review_base__", + }), + }) + expect(failed.status).not.toBe(200) + const body = (await failed.json()) as { name: string; data: { message: string } } + expect(body.data.message).toContain( + 'Base branch or ref not found or has no common history: "__missing_local_review_base__"', + ) + expect(body.data.message).not.toContain("No context found for instance") + + const history = await app.request(SessionPaths.messages.replace(":sessionID", session.id), { headers }) + expect(history.status).toBe(200) + expect(await history.json()).toEqual([]) + }) +})