From 624be2310dfef74dd058ff31a0eaaa74f330866e Mon Sep 17 00:00:00 2001 From: Alex Alecu Date: Wed, 15 Apr 2026 14:09:24 +0300 Subject: [PATCH] fix(cli): fix disable auto-approve leaving stale config and UI --- .../opencode/src/kilocode/config/config.ts | 5 +- .../src/kilocode/permission/routes.ts | 6 ++- .../permission-allow-everything.test.ts | 47 +++++++++++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/packages/opencode/src/kilocode/config/config.ts b/packages/opencode/src/kilocode/config/config.ts index 64f12bd4bdb..c729f95df95 100644 --- a/packages/opencode/src/kilocode/config/config.ts +++ b/packages/opencode/src/kilocode/config/config.ts @@ -292,13 +292,14 @@ export namespace KilocodeConfig { // ── Config merge utilities ─────────────────────────────────────────── - /** Recursively remove keys whose value is null (used after mergeDeep to honor delete sentinels). */ + /** Recursively remove keys whose value is null or becomes an empty object after stripping. */ export function stripNulls(obj: Record): Record { const result: Record = {} for (const [key, value] of Object.entries(obj)) { if (value === null) continue if (isRecord(value)) { - result[key] = stripNulls(value) + const stripped = stripNulls(value) + if (Object.keys(stripped).length > 0) result[key] = stripped } else { result[key] = value } diff --git a/packages/opencode/src/kilocode/permission/routes.ts b/packages/opencode/src/kilocode/permission/routes.ts index ae68d4a3843..b1235804f26 100644 --- a/packages/opencode/src/kilocode/permission/routes.ts +++ b/packages/opencode/src/kilocode/permission/routes.ts @@ -1,10 +1,12 @@ import { Hono } from "hono" import { describeRoute, resolver, validator } from "hono-openapi" import z from "zod" +import { Bus } from "@/bus" import { Config } from "@/config/config" import { Permission } from "@/permission" import { Session } from "@/session" import { SessionID } from "@/session/schema" // kilocode_change +import { Event } from "../../server/event" import { errors } from "../../server/error" import { lazy } from "../../util/lazy" @@ -52,8 +54,9 @@ export const PermissionKilocodeRoutes = lazy(() => return c.json(true) } - await Config.updateGlobal({ permission: { "*": { "*": null } } }, { dispose: false }) + await Config.updateGlobal({ permission: { "*": null } }, { dispose: false }) await Permission.allowEverything({ enable: false }) + await Bus.publish(Event.ConfigUpdated, {}) return c.json(true) } @@ -65,6 +68,7 @@ export const PermissionKilocodeRoutes = lazy(() => }) } else { await Config.updateGlobal({ permission: Permission.toConfig(rules) }, { dispose: false }) + await Bus.publish(Event.ConfigUpdated, {}) } await Permission.allowEverything({ diff --git a/packages/opencode/test/server/permission-allow-everything.test.ts b/packages/opencode/test/server/permission-allow-everything.test.ts index b2c841cf183..d913d56b9c4 100644 --- a/packages/opencode/test/server/permission-allow-everything.test.ts +++ b/packages/opencode/test/server/permission-allow-everything.test.ts @@ -8,6 +8,53 @@ import { Session } from "../../src/session" import { tmpdir } from "../fixture/fixture" describe("permission.allowEverything endpoint", () => { + test("disables global allow-all and removes wildcard from config", async () => { + await using tmp = await tmpdir({ git: true }) + + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const app = Server.Default().app + + // Enable global auto-approve + const enable = await app.request("/permission/allow-everything", { + method: "POST", + headers: { "Content-Type": "application/json", "x-kilo-directory": tmp.path }, + body: JSON.stringify({ enable: true }), + }) + expect(enable.status).toBe(200) + + // Disable global auto-approve + const disable = await app.request("/permission/allow-everything", { + method: "POST", + headers: { "Content-Type": "application/json", "x-kilo-directory": tmp.path }, + body: JSON.stringify({ enable: false }), + }) + expect(disable.status).toBe(200) + expect(await disable.json()).toBe(true) + + // After disabling, permission requests should not be auto-approved + const session = await Session.create({}) + const pending = Permission.ask({ + id: PermissionID.make("permission_global_disable"), + sessionID: session.id, + permission: "bash", + patterns: ["ls"], + metadata: {}, + always: [], + ruleset: [], + }) + + await Permission.reply({ + requestID: PermissionID.make("permission_global_disable"), + reply: "reject", + }) + + await expect(pending).rejects.toBeInstanceOf(Permission.RejectedError) + }, + }) + }) + test("disables session-scoped allow-all without touching global config", async () => { await using tmp = await tmpdir({ git: true })