From 4feb0c903d9e193dace32f7a1361135ce2b2c4a1 Mon Sep 17 00:00:00 2001 From: Bruno Agatao Date: Fri, 7 Aug 2026 19:29:13 +0200 Subject: [PATCH] fix(vscode): preserve approval metadata when slimming tool parts for the webview --- .../src/kilo-provider/slim-metadata.ts | 4 ++++ .../tests/unit/slim-metadata.test.ts | 20 +++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/kilo-vscode/src/kilo-provider/slim-metadata.ts b/packages/kilo-vscode/src/kilo-provider/slim-metadata.ts index df8d576e03..9175ea673d 100644 --- a/packages/kilo-vscode/src/kilo-provider/slim-metadata.ts +++ b/packages/kilo-vscode/src/kilo-provider/slim-metadata.ts @@ -73,6 +73,7 @@ function slimEdit(state: Record): Record { } } if (meta.diagnostics) result.diagnostics = meta.diagnostics + if (meta.approval) result.approval = meta.approval next.metadata = result return next } @@ -84,6 +85,7 @@ function slimPatch(state: Record): Record { if (isObj(meta)) { const slim: Record = {} if (meta.diagnostics) slim.diagnostics = meta.diagnostics + if (meta.approval) slim.approval = meta.approval if (Array.isArray(meta.files)) { slim.files = (meta.files as Record[]).map((f) => { const diff = patch(f.patch) ?? patch(f.diff) @@ -115,6 +117,7 @@ function slimMultiedit(state: Record): Record if (isObj(meta)) { const slim: Record = {} if (meta.diagnostics) slim.diagnostics = meta.diagnostics + if (meta.approval) slim.approval = meta.approval if (Array.isArray(meta.results)) { slim.results = (meta.results as Record[]).map((r) => { const rs: Record = {} @@ -149,6 +152,7 @@ function slimWrite(state: Record): Record { if (meta.filepath) slim.filepath = meta.filepath if (meta.exists !== undefined) slim.exists = meta.exists if (meta.diagnostics) slim.diagnostics = meta.diagnostics + if (meta.approval) slim.approval = meta.approval const fd = meta.filediff if (isObj(fd)) { slim.filediff = { diff --git a/packages/kilo-vscode/tests/unit/slim-metadata.test.ts b/packages/kilo-vscode/tests/unit/slim-metadata.test.ts index 21c62f4722..96ee681858 100644 --- a/packages/kilo-vscode/tests/unit/slim-metadata.test.ts +++ b/packages/kilo-vscode/tests/unit/slim-metadata.test.ts @@ -30,6 +30,10 @@ const BIG = "x".repeat(200_000) // 200 KB — typical file content size const DIAG = [ { range: { start: { line: 1, character: 0 }, end: { line: 1, character: 5 } }, message: "err", severity: 1 }, ] +// Regression for #13001: slimmers used to rebuild `metadata` from an explicit allowlist that +// didn't include `approval`, silently dropping the auto-approval reason (and the +// outside-workspace note) before it ever reached the webview. +const APPROVAL = { source: "agent", agent: "code", outsideWorkspace: true, outsideWorkspacePath: "/tmp/a.ts" } // --------------------------------------------------------------------------- // Tests @@ -96,6 +100,7 @@ describe("slimPart", () => { diff: BIG, filediff: { file: "/a.ts", patch: PATCH, before: BIG, after: BIG, additions: 3, deletions: 1 }, diagnostics: { "/a.ts": DIAG }, + approval: APPROVAL, }, }) @@ -103,7 +108,7 @@ describe("slimPart", () => { expect(bytes(slimPart(heavy))).toBeLessThan(MAX_SLIM_BYTES) }) - it("keeps filediff counts and diagnostics", () => { + it("keeps filediff counts, diagnostics, and approval", () => { const slim = slimPart(heavy) as Record const meta = slim.state.metadata expect(meta.filediff.file).toBe("/a.ts") @@ -111,6 +116,7 @@ describe("slimPart", () => { expect(meta.filediff.additions).toBe(3) expect(meta.filediff.deletions).toBe(1) expect(meta.diagnostics).toEqual({ "/a.ts": DIAG }) + expect(meta.approval).toEqual(APPROVAL) }) it("keeps output and input intact", () => { @@ -176,6 +182,7 @@ describe("slimPart", () => { }, ], diagnostics: { "/a.ts": DIAG }, + approval: APPROVAL, }, }) @@ -183,7 +190,7 @@ describe("slimPart", () => { expect(bytes(slimPart(heavy))).toBeLessThan(MAX_SLIM_BYTES) }) - it("keeps file summary fields and diagnostics", () => { + it("keeps file summary fields, diagnostics, and approval", () => { const slim = slimPart(heavy) as Record const meta = slim.state.metadata expect(meta.files[0].filePath).toBe("/a.ts") @@ -193,6 +200,7 @@ describe("slimPart", () => { expect(meta.files[0].additions).toBe(5) expect(meta.files[1].type).toBe("add") expect(meta.diagnostics).toEqual({ "/a.ts": DIAG }) + expect(meta.approval).toEqual(APPROVAL) }) it("drops unknown heavy metadata fields", () => { @@ -266,6 +274,7 @@ describe("slimPart", () => { }, { filediff: { file: "/b.ts", before: BIG, after: BIG, additions: 2, deletions: 0 }, diagnostics: {} }, ], + approval: APPROVAL, }, }) @@ -273,7 +282,7 @@ describe("slimPart", () => { expect(bytes(slimPart(heavy))).toBeLessThan(MAX_SLIM_BYTES) }) - it("keeps filediff counts and per-result diagnostics", () => { + it("keeps filediff counts, per-result diagnostics, and approval", () => { const slim = slimPart(heavy) as Record const meta = slim.state.metadata expect(meta.results[0].filediff.file).toBe("/a.ts") @@ -282,6 +291,7 @@ describe("slimPart", () => { expect(meta.results[0].diagnostics).toEqual({ "/a.ts": DIAG }) expect(meta.results[1].filediff.file).toBe("/b.ts") expect(meta.diagnostics).toEqual({ "/a.ts": DIAG }) + expect(meta.approval).toEqual(APPROVAL) }) it("drops unknown heavy metadata fields", () => { @@ -318,6 +328,7 @@ describe("slimPart", () => { diff: BIG, filediff: { file: "/a.ts", patch: PATCH, before: BIG, after: BIG, additions: 100, deletions: 0 }, diagnostics: { "/a.ts": DIAG }, + approval: APPROVAL, }, }) @@ -325,7 +336,7 @@ describe("slimPart", () => { expect(bytes(slimPart(heavy))).toBeLessThan(MAX_SLIM_BYTES) }) - it("keeps filepath, exists, filediff counts, diagnostics", () => { + it("keeps filepath, exists, filediff counts, diagnostics, and approval", () => { const slim = slimPart(heavy) as Record const meta = slim.state.metadata expect(meta.filepath).toBe("/a.ts") @@ -335,6 +346,7 @@ describe("slimPart", () => { expect(meta.filediff.additions).toBe(100) expect(meta.filediff.deletions).toBe(0) expect(meta.diagnostics).toEqual({ "/a.ts": DIAG }) + expect(meta.approval).toEqual(APPROVAL) }) it("drops unknown heavy metadata fields", () => {