From 75447d86b01217c5b92bd6ac6bc8b0e2a0680f2e Mon Sep 17 00:00:00 2001 From: Jasper Hugo Date: Fri, 9 Oct 2026 10:23:04 +0200 Subject: [PATCH] fix(desktop): reject array capability metadata Signed-off-by: Jasper Hugo --- .../src/acp/__tests__/capabilities.test.ts | 20 +++++++++++++++++++ ui/desktop/src/acp/capabilities.ts | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/ui/desktop/src/acp/__tests__/capabilities.test.ts b/ui/desktop/src/acp/__tests__/capabilities.test.ts index 537f10a894..876b22b81a 100644 --- a/ui/desktop/src/acp/__tests__/capabilities.test.ts +++ b/ui/desktop/src/acp/__tests__/capabilities.test.ts @@ -34,6 +34,26 @@ describe('ACP capabilities', () => { expect(hasEmptyExtensionSelectionCapability(initializeResponseWithMeta(meta))).toBe(false); } }); + + it('accepts empty-selection capability objects with fields', () => { + expect( + hasEmptyExtensionSelectionCapability( + initializeResponseWithMeta({ + goose: { emptyExtensionSelection: { version: 1 } }, + }) + ) + ).toBe(true); + }); + + it.each([ + [], + { goose: [] }, + { goose: { emptyExtensionSelection: [] } }, + { goose: { emptyExtensionSelection: ['supported'] } }, + ])('rejects array capability metadata: %j', (meta) => { + expect(hasEmptyExtensionSelectionCapability(initializeResponseWithMeta(meta))).toBe(false); + }); + it('detects local inference support from Goose metadata', () => { expect( hasLocalInferenceCapability( diff --git a/ui/desktop/src/acp/capabilities.ts b/ui/desktop/src/acp/capabilities.ts index 66b2d4a7aa..f04bed1203 100644 --- a/ui/desktop/src/acp/capabilities.ts +++ b/ui/desktop/src/acp/capabilities.ts @@ -67,5 +67,5 @@ export function hasEmptyExtensionSelectionCapability( } function isRecord(value: unknown): value is Record { - return typeof value === 'object' && value !== null; + return typeof value === 'object' && value !== null && !Array.isArray(value); }