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({})