From a4fb151d7c2de6096cae326016dc7dff2052a34f Mon Sep 17 00:00:00 2001 From: rrader26 Date: Mon, 11 May 2026 18:33:19 -0400 Subject: [PATCH] fix(desktop): add listTargets() to MacosAxapiBackend (main broken) PRs #18 (MacosAxapiBackend) and #19 (listTargets interface change) merged in conflicting order: #19 made listTargets() required on the DesktopCaptureBackend interface, but #18 was written before #19 so the macOS implementation doesn't implement it. Main is currently broken with two TS2420/TS2741 errors: src/desktop/macos-axapi-backend.ts:78 Class 'MacosAxapiBackend' incorrectly implements interface 'DesktopCaptureBackend'. Property 'listTargets' is missing. src/mcp/dispatcher.ts:374 Property 'listTargets' is missing in type 'MacosAxapiBackend'. Fix: mirror the WindowsUiaBackend.listTargets() implementation in MacosAxapiBackend. Same JSON-RPC call (list_windows on the bridge), same camelCase->snake_case field mapping. No behaviour change to existing methods. Tests: new listTargets test on MacosAxapiBackend mirrors the Windows test. Full suite: 317 passed, 10 skipped, 0 failed. This was foreseen in PR #19's description ("PR #18 will need the same listTargets() implementation. Will update that PR as a follow-up commit on the feat/desktop-macos-axapi-backend branch after #18 merges"). Now landing it. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/desktop/macos-axapi-backend.ts | 24 ++++++++++++++++++++++++ test/desktop/macos-axapi-backend.test.ts | 11 +++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/desktop/macos-axapi-backend.ts b/src/desktop/macos-axapi-backend.ts index 5386bcb..80ddf19 100644 --- a/src/desktop/macos-axapi-backend.ts +++ b/src/desktop/macos-axapi-backend.ts @@ -33,6 +33,7 @@ import type { CaptureDesktopOptions, DesktopCapture, DesktopCaptureBackend, + DesktopTargetSummary, ExecuteDesktopAction, ExecuteDesktopOptions, ExecuteDesktopResult, @@ -106,6 +107,20 @@ export class MacosAxapiBackend implements DesktopCaptureBackend { // ── DesktopCaptureBackend implementation ───────────────────────── + async listTargets(): Promise { + await this.ensureStarted() + const result = (await this.call('list_windows', {})) as { windows?: RawWindowSummary[] } + const raw = result?.windows ?? [] + return raw.map((w) => ({ + window_id: w.windowId, + process_name: w.processName ?? undefined, + process_id: w.processId ?? undefined, + window_title: w.windowTitle, + window_class: w.windowClass ?? undefined, + has_focus: !!w.hasFocus, + })) + } + async capture(opts: CaptureDesktopOptions = {}): Promise { await this.ensureStarted() const params = { @@ -397,6 +412,15 @@ function resolveBridgePath(): string { // Wire format mapping (shared with Windows backend) // ────────────────────────────────────────────────────────────────────── +interface RawWindowSummary { + windowId: string + processName?: string | null + processId?: number | null + windowTitle: string + windowClass?: string | null + hasFocus: boolean +} + interface RawDesktopCapture { platform: 'windows' | 'macos' | 'linux' processName?: string | null diff --git a/test/desktop/macos-axapi-backend.test.ts b/test/desktop/macos-axapi-backend.test.ts index e99424a..e7f82c6 100644 --- a/test/desktop/macos-axapi-backend.test.ts +++ b/test/desktop/macos-axapi-backend.test.ts @@ -37,6 +37,17 @@ describe('MacosAxapiBackend', () => { expect(backend.name).toBe('macos_axapi') }) + it('listTargets maps the bridge `windows` array to snake_case DesktopTargetSummary', async () => { + backend = makeBackend() + const targets = await backend.listTargets() + expect(targets.length).toBeGreaterThan(0) + const w = targets[0] + expect(w.window_title).toBe('Fake Window 1') + expect(w.process_name).toBe('FakeApp.exe') + expect(w.process_id).toBe(42) + expect(w.has_focus).toBe(true) + }) + it('captures via the bridge and maps the response to DesktopCapture', async () => { backend = makeBackend() const cap = await backend.capture({})