diff --git a/packages/experimental/cua-macos/src/shared-native.ts b/packages/experimental/cua-macos/src/shared-native.ts index 0fe2cf6436..7539276a8c 100644 --- a/packages/experimental/cua-macos/src/shared-native.ts +++ b/packages/experimental/cua-macos/src/shared-native.ts @@ -13,8 +13,8 @@ export type { NativeChannel } from '@deepseek-ai/dsh-cua/native-client' const Ready = z.object({ type: z.literal('ready'), protocol: z.literal(1), runtimeKey: z.string(), - pid: z.number().int().positive(), instanceId: z.string().min(1), -}).strict() + instanceId: z.string().min(1), +}) const Refusal = z.object({ type: z.literal('error'), code: z.string().min(1), message: z.string() }).strict() const handshakeByteLimit = 8192 type LauncherExit = [PromiseSettledResult, PromiseSettledResult] diff --git a/packages/experimental/cua-macos/tests/guidance.spec.ts b/packages/experimental/cua-macos/tests/guidance.spec.ts index f0f5679623..ae947d7ab7 100644 --- a/packages/experimental/cua-macos/tests/guidance.spec.ts +++ b/packages/experimental/cua-macos/tests/guidance.spec.ts @@ -56,8 +56,8 @@ it('inlines discovery, restoration, screenshot, and mouse-move return records', expect(lines.find(line => line.startsWith(`- ${name}(`))).toMatch(/ -> \(?\{ /) } expect(COMMON_GUIDANCE).toContain("{ platform: string, permissions: { accessibility: boolean, screenRecording: boolean }, appLevelAccessibility: boolean, keyboard: ('app' | 'window')[], sessionLocked: boolean | null, methods: string[], coordinateSpace: 'screenshot-pixels', browser: false }") - expect(COMMON_GUIDANCE).toContain('{ id: string, displayName: string, isRunning: true, pid: number }[]') - expect(COMMON_GUIDANCE).toContain('({ id: string, displayName: string, path: string } & ({ isRunning: true, pid: number } | { isRunning: false }))[]') + expect(COMMON_GUIDANCE).toContain('{ id: string, displayName: string, isRunning: true }[]') + expect(COMMON_GUIDANCE).toContain('{ id: string, displayName: string, path: string, isRunning: boolean }[]') expect(COMMON_GUIDANCE).toContain('bounds: { x: number, y: number, width: number, height: number }, isOnScreen: boolean, onCurrentSpace: boolean | null') }) diff --git a/packages/experimental/cua-windows/src/native-runtime.ts b/packages/experimental/cua-windows/src/native-runtime.ts index bf5da9aff3..0386d60f19 100644 --- a/packages/experimental/cua-windows/src/native-runtime.ts +++ b/packages/experimental/cua-windows/src/native-runtime.ts @@ -11,9 +11,9 @@ import { z } from 'zod' import { connectWindowsPipe, type WindowsConnection, type WindowsTransport } from './native-transport.ts' const Ready = z.object({ - type: z.literal('ready'), protocol: z.literal(1), runtimeKey: z.string(), instanceId: z.string().min(1), -}).strict() -const Started = Ready.extend({ endpoint: z.string().min(1), launcherId: z.string().min(1) }).strict() + type: z.literal('ready'), protocol: z.literal(1), runtimeKey: z.string().min(1), instanceId: z.string().min(1), +}) +const Started = Ready.extend({ endpoint: z.string().min(1), launcherId: z.string().min(1) }) // Private transport control frames have fixed encoding; operation replies pass through unchanged. const closedFrame = Buffer.from('{"type":"closed"}\n') type Owner = { subprocess: Pick } @@ -238,7 +238,7 @@ class WindowsChannel implements NativeChannel { } const response = await frame const accepted = Ready.parse(response.value) - if (accepted.runtimeKey !== ready.runtimeKey || accepted.instanceId !== ready.instanceId || accepted.pid !== ready.pid) + if (accepted.runtimeKey !== ready.runtimeKey || accepted.instanceId !== ready.instanceId) throw new NativeError('NATIVE_PROTOCOL', 'Windows pipe belongs to another helper instance') this.startup.signal.throwIfAborted() admitted = true diff --git a/packages/experimental/cua-windows/tests/native-runtime.spec.ts b/packages/experimental/cua-windows/tests/native-runtime.spec.ts index b3eb03caf2..5e526ab4d7 100644 --- a/packages/experimental/cua-windows/tests/native-runtime.spec.ts +++ b/packages/experimental/cua-windows/tests/native-runtime.spec.ts @@ -199,7 +199,12 @@ it.each(['wrong-runtime', 'wrong-instance', 'extra', 'malformed', 'oversized', ' }, ) -it.each(['wrong-instance', 'wrong-pid', 'extra', 'malformed', 'oversized'] as const)( +it.each(['wrong-pid', 'extra'] as const)('ignores unused %s handshake metadata', async (handshake) => { + const f = await fixture({ handshake }) + await expect(f.client().request('input', {}, new AbortController().signal)).resolves.toMatchObject({ connection: 1 }) +}) + +it.each(['wrong-instance', 'malformed', 'oversized'] as const)( 'rejects a %s Agent handshake before dispatch', async (handshake) => { const f = await fixture({ handshake }) await expect(f.client().request('input', {}, new AbortController().signal)).rejects.toThrow() diff --git a/packages/experimental/cua/src/access-types.ts b/packages/experimental/cua/src/access-types.ts index 0a587124d4..f37a5ea679 100644 --- a/packages/experimental/cua/src/access-types.ts +++ b/packages/experimental/cua/src/access-types.ts @@ -6,7 +6,6 @@ export type { CuaApplicationGrant, CuaApplicationId } from './application-types. export type CuaSystemPermission = 'accessibility' | 'screenRecording' /** Observed process; neither the helper nor its parent is assumed to be the TCC owner. */ export interface CuaPermissionProcess { - pid: number path?: string | undefined name?: string | undefined } diff --git a/packages/experimental/cua/src/access.ts b/packages/experimental/cua/src/access.ts index 535bfe84fb..507d628024 100644 --- a/packages/experimental/cua/src/access.ts +++ b/packages/experimental/cua/src/access.ts @@ -19,7 +19,7 @@ interface ControlOptions extends AccessOptions { permissionParameters: (method: 'requestPermission' | 'openPermissionSettings', permission: CuaSystemPermission, locale: string) => Record } type Control = (method: string, params: Record) => Promise -const permissionProcess = z.object({ pid: z.number().int().positive(), path: z.string().optional(), name: z.string().optional() }) +const permissionProcess = z.object({ path: z.string().optional(), name: z.string().optional() }) const systemPermissions = z.discriminatedUnion('platform', [z.object({ platform: z.literal('darwin'), accessibility: z.boolean(), screenRecording: z.boolean(), helper: permissionProcess, parent: permissionProcess, launchApplication: z.object({ name: z.string().min(1), path: z.string().min(1), icon: ApplicationIcon.optional() }).optional(), diff --git a/packages/experimental/cua/src/api.ts b/packages/experimental/cua/src/api.ts index 22039c6591..f41a4f61e4 100644 --- a/packages/experimental/cua/src/api.ts +++ b/packages/experimental/cua/src/api.ts @@ -59,7 +59,7 @@ export function createCuaApi(dispatch: CuaDispatch, sink?: CuaObservationSink): }, async listApps(options) { const result = AppsResult.parse(await call('listApps', {})).map(app => ({ - id: app.bundleId || String(app.pid), displayName: app.name, isRunning: true as const, pid: app.pid, + id: app.id ?? (app.bundleId || app.name), displayName: app.name, isRunning: true as const, })) await emit(sink, result, options) return result diff --git a/packages/experimental/cua/src/guidance.ts b/packages/experimental/cua/src/guidance.ts index df935f6525..a28de6d0ca 100644 --- a/packages/experimental/cua/src/guidance.ts +++ b/packages/experimental/cua/src/guidance.ts @@ -8,10 +8,10 @@ Signatures show resolved return values after await. ActionResult = { dispatched: Setup and discovery: - cua.getCapabilities(options?: { emit?: boolean }) -> { platform: string, permissions: { accessibility: boolean, screenRecording: boolean }, appLevelAccessibility: boolean, keyboard: ('app' | 'window')[], sessionLocked: boolean | null, methods: string[], coordinateSpace: 'screenshot-pixels', browser: false } — inspect reported permissions, sessionLocked, methods, and keyboard scopes without requesting permissions. -- cua.listApps(options?: { emit?: boolean }) -> { id: string, displayName: string, isRunning: true, pid: number }[] — enumerate running applications. -- cua.findApps(query: string, options?: { emit?: boolean }) -> ({ id: string, displayName: string, path: string } & ({ isRunning: true, pid: number } | { isRunning: false }))[] — search installed applications, including stopped matches; only running matches carry pid. -- cua.getState(options?: { emit?: boolean }) -> { apps: { id: string, displayName: string, isRunning: true, pid: number }[], browsers: [] } — summarize running applications; this is not an accessibility observation. -- cua.getApp(selector: string) -> App — select an application by name, bundle ID, absolute path, or running PID string, obtain consent, launch in the background if needed, and read initial AX state silently; it does not activate the app. +- cua.listApps(options?: { emit?: boolean }) -> { id: string, displayName: string, isRunning: true }[] — enumerate running applications. +- cua.findApps(query: string, options?: { emit?: boolean }) -> { id: string, displayName: string, path: string, isRunning: boolean }[] — search installed applications, including stopped matches. +- cua.getState(options?: { emit?: boolean }) -> { apps: { id: string, displayName: string, isRunning: true }[], browsers: [] } — summarize running applications; this is not an accessibility observation. +- cua.getApp(selector: string) -> App — select an application by provider-issued discovery ID, name, bundle ID, or absolute path where supported, obtain consent, launch in the background if needed, and read initial AX state silently; it does not activate the app. - app.getWindows(options?: { emit?: boolean }) -> { windowId: number, appName: string, title: string, bounds: { x: number, y: number, width: number, height: number }, isOnScreen: boolean, onCurrentSpace: boolean | null }[] — enumerate windows with global native bounds; null onCurrentSpace means unknown Space membership. - app.getWindow(windowId: number) -> Window — select one window and read its initial AX state silently; do this before any window screenshot or coordinate input. - app.activate() -> ActionResult — request explicit foreground activation; use only when foreground access is required. diff --git a/packages/experimental/cua/src/protocol.ts b/packages/experimental/cua/src/protocol.ts index 538c95cfe6..ad54407c51 100644 --- a/packages/experimental/cua/src/protocol.ts +++ b/packages/experimental/cua/src/protocol.ts @@ -4,7 +4,6 @@ import { z } from 'zod' import type { CuaAppHandle, CuaSnapshotId } from './types.ts' const id = z.number().int().positive().max(2 ** 32 - 1) -const pid = z.number().int().positive().max(2 ** 31 - 1) const point = z.number().nonnegative() const relativePoint = z.number().int().min(0).max(999) const app = { appHandle: z.string().min(1) } @@ -101,11 +100,12 @@ export const AppResult = z.object({ appHandle: z.string().min(1).transform(value => value as CuaAppHandle), name: z.string(), bundleId: z.string().optional(), running: z.boolean(), }) -/** Running application records from the helper. */ -export const AppsResult = z.array(z.object({ pid, name: z.string(), bundleId: z.string().optional() })) -/** Installed application matches keep running and stopped records distinct. */ -export const FoundAppsResult = z.array(z.intersection(z.object({ id: z.string().min(1), displayName: z.string(), path: z.string().min(1) }), - z.discriminatedUnion('isRunning', [z.object({ isRunning: z.literal(true), pid }), z.object({ isRunning: z.literal(false) })]))) +/** Running application metadata used for selection; other native fields are ignored. */ +export const AppsResult = z.array(z.object({ id: z.string().min(1).optional(), name: z.string(), bundleId: z.string().optional() })) +/** Installed application matches and their current running state. */ +export const FoundAppsResult = z.array(z.object({ + id: z.string().min(1), displayName: z.string(), path: z.string().min(1), isRunning: z.boolean(), +})) /** Current windows and their global native bounds. */ export const WindowsResult = z.array(z.object({ windowId: id, appName: z.string(), title: z.string(), bounds, diff --git a/packages/experimental/cua/src/types.ts b/packages/experimental/cua/src/types.ts index c059a546f2..f35c839abf 100644 --- a/packages/experimental/cua/src/types.ts +++ b/packages/experimental/cua/src/types.ts @@ -51,8 +51,8 @@ export type CuaStartupCapabilities = Pick< 'platform' | 'methods' | 'appLevelAccessibility' | 'keyboard' | 'browser' | 'coordinateSpace' > /** App discovery result accepted by getApp. */ -export type CuaAppInfo = Pick, 'id' | 'displayName' | 'isRunning' | 'pid'> -/** An installed application match; running matches include a process identifier. */ +export type CuaAppInfo = Pick & { isRunning: true } +/** An installed application match with its current running state. */ export type CuaFoundAppInfo = z.output[number] /** Window bounds in the provider's global native units. Local operations use an origin of [0,0]. */ export type CuaBounds = CuaWindowInfo['bounds'] @@ -273,7 +273,7 @@ export interface CuaApi { getState(options?: CuaObservationOptions): Promise<{ apps: CuaAppInfo[]; browsers: [] }> /** * Select an app, obtain consent, launch it in the background if necessary, and silently retain initial AX state. - * @param selector - Exact name, bundle ID, absolute application path or running PID string; ambiguous names reject. + * @param selector - Provider-issued identifier, exact name, bundle ID or absolute application path; ambiguous selectors reject. * @returns An application handle tied to this process lifetime; its initial tree read becomes the current snapshot. */ getApp(selector: string): Promise diff --git a/packages/experimental/cua/tests/access.spec.ts b/packages/experimental/cua/tests/access.spec.ts index ef6f6c203f..74dea0c738 100644 --- a/packages/experimental/cua/tests/access.spec.ts +++ b/packages/experimental/cua/tests/access.spec.ts @@ -398,7 +398,8 @@ it('preserves captured launch metadata separately from the current helper parent const launchApplication = { name: 'Visual Studio Code', path: '/Applications/Visual Studio Code.app', icon: 'data:image/png;base64,aWNvbg==' } control.request.mockResolvedValueOnce({ platform: 'darwin' as const, accessibility: false, screenRecording: false, helper: { pid: 9 }, parent: { pid: 1, path: '/sbin/launchd' }, launchApplication }) - expect(await f.ctx.cuaAccess.systemStatus()).toMatchObject({ parent: { pid: 1 }, launchApplication }) + expect(await f.ctx.cuaAccess.systemStatus()).toEqual({ platform: 'darwin', accessibility: false, screenRecording: false, + helper: {}, parent: { path: '/sbin/launchd' }, launchApplication }) }) diff --git a/packages/experimental/cua/tests/api.spec.ts b/packages/experimental/cua/tests/api.spec.ts index cbaa419951..707bfc7089 100644 --- a/packages/experimental/cua/tests/api.spec.ts +++ b/packages/experimental/cua/tests/api.spec.ts @@ -27,7 +27,7 @@ function fixture(withSink = true) { const dispatch = vi.fn(async ({ method, params }: CuaOperation): Promise => { switch (method) { case 'getCapabilities': return currentCapabilities - case 'listApps': return [selected, { pid: 18, name: 'Utility' }] + case 'listApps': return [selected, { id: 'utility-selector', pid: 4, name: 'Utility' }] case 'getApp': return selected case 'listWindows': return windows case 'mouseMove': return { ...delivered, hoverRoute: 'accessibility', systemPointerMoved: false } @@ -59,12 +59,12 @@ function screenshot(overrides: Record = {}): JsonValue { } describe('application discovery', () => { - it('reports permissions and discovers both bundle and PID selectors without activating an app', async () => { + it('reports permissions and discovers provider-issued selectors without activating an app', async () => { const f = fixture() expect(await f.api.getCapabilities()).toEqual(capabilities) expect(await f.api.getState()).toEqual({ apps: [ - { id: 'test.editor', displayName: 'Editor', isRunning: true, pid: 17 }, - { id: '18', displayName: 'Utility', isRunning: true, pid: 18 }, + { id: 'test.editor', displayName: 'Editor', isRunning: true }, + { id: 'utility-selector', displayName: 'Utility', isRunning: true }, ], browsers: [] }) expect(f.dispatch.mock.calls.map(([operation]) => operation.method)).toEqual(['getCapabilities', 'listApps']) const emitted = f.sink.text.mock.calls.map(([text]): unknown => JSON.parse(text)) @@ -72,6 +72,19 @@ describe('application discovery', () => { expect(f.sink.text).toHaveBeenCalledTimes(2) }) + it('passes a discovered selector unchanged to application selection', async () => { + const f = fixture() + const apps = await f.api.listApps({ emit: false }) + await f.api.getApp(apps[1]!.id) + expect(f.dispatch).toHaveBeenCalledWith({ method: 'getApp', params: { selector: 'utility-selector' } }) + }) + + it('uses the application name when discovery has no identifier', async () => { + const f = fixture() + f.dispatch.mockResolvedValueOnce([{ pid: 18, name: 'Utility' }]) + expect(await f.api.listApps({ emit: false })).toEqual([{ id: 'Utility', displayName: 'Utility', isRunning: true }]) + }) + it('returns observations without requiring an output sink', async () => { const f = fixture(false) expect(await f.api.getCapabilities({ emit: false })).toEqual(capabilities) @@ -94,9 +107,9 @@ describe('application discovery', () => { const f = fixture() const matches = [ { id: 'test.stopped', displayName: 'Stopped', path: '/Applications/Stopped.app', isRunning: false }, - { id: 'test.running', displayName: 'Running', path: '/Applications/Running.app', isRunning: true, pid: 17 }, + { id: 'test.running', displayName: 'Running', path: '/Applications/Running.app', isRunning: true }, ] - f.dispatch.mockResolvedValueOnce(matches) + f.dispatch.mockResolvedValueOnce([matches[0]!, { ...matches[1]!, pid: 17 }]) expect(await f.api.findApps('Editor')).toEqual(matches) expect(f.dispatch).toHaveBeenLastCalledWith({ method: 'findApps', params: { query: 'Editor' } }) expect(f.sink.text).toHaveBeenLastCalledWith(JSON.stringify(matches)) @@ -113,7 +126,7 @@ describe('application discovery', () => { const f = fixture() f.dispatch.mockResolvedValueOnce({ platform: 'macos' }) await expect(f.api.getCapabilities()).rejects.toThrow() - f.dispatch.mockResolvedValueOnce([{ pid: 0, name: 'Invalid' }]) + f.dispatch.mockResolvedValueOnce([{ id: '', name: 'Invalid' }]) await expect(f.api.listApps()).rejects.toThrow() f.dispatch.mockResolvedValueOnce({ ...selected, appHandle: '' }) await expect(f.api.getApp('Editor')).rejects.toThrow() diff --git a/packages/experimental/cua/tests/bridge.spec.ts b/packages/experimental/cua/tests/bridge.spec.ts index 14a36baaba..f9deb49f7f 100644 --- a/packages/experimental/cua/tests/bridge.spec.ts +++ b/packages/experimental/cua/tests/bridge.spec.ts @@ -16,7 +16,7 @@ const capabilities: CuaCapabilities = { keyboard: ['app'], sessionLocked: false, methods: ['getCapabilities', 'getApp', 'getState', 'screenshot'], coordinateSpace: 'screenshot-pixels', browser: false, } -const selected = { appHandle: 'app-17', pid: 17, name: 'Editor', running: true } +const selected = { appHandle: 'app-17', name: 'Editor', running: true } const bounds = { x: 0, y: 0, width: 640, height: 480 } const snapshot = { appHandle: 'app-17', windowId: null, snapshotId: 'snapshot-1', tree: '0 button', truncated: false, @@ -56,8 +56,8 @@ it('propagates a denied action without retrying it', async () => { }) it('supports callers that retain observations without a text callback', async () => { - const cua = connectCua(() => async () => [{ pid: 17, name: 'Editor' }]) - await expect(cua.listApps()).resolves.toEqual([{ id: '17', displayName: 'Editor', isRunning: true, pid: 17 }]) + const cua = connectCua(() => async () => [{ id: 'editor-selector', name: 'Editor' }]) + await expect(cua.listApps()).resolves.toEqual([{ id: 'editor-selector', displayName: 'Editor', isRunning: true }]) }) it.each([null, 'text only', { content: [{ type: 'text', text: '{}' }] }])('rejects an unusable tool result %j', async (result) => { diff --git a/packages/experimental/cua/tests/controller.client.spec.ts b/packages/experimental/cua/tests/controller.client.spec.ts index 81575d1eb8..31b402fdfd 100644 --- a/packages/experimental/cua/tests/controller.client.spec.ts +++ b/packages/experimental/cua/tests/controller.client.spec.ts @@ -7,7 +7,7 @@ import { expect, it, onTestFinished, vi } from 'vitest' import type { CuaApplicationId, CuaApplicationState, CuaSystemPermissionState } from '../src/access-types.ts' import { PermissionController } from '../src/client/controller.ts' -const value: CuaSystemPermissionState = { platform: 'darwin' as const, accessibility: true, screenRecording: false, helper: { pid: 9 }, parent: { pid: 8 } } +const value: CuaSystemPermissionState = { platform: 'darwin' as const, accessibility: true, screenRecording: false, helper: {}, parent: {} } const applications: CuaApplicationState = { allowedApps: [], blockedApps: [], persistentAvailable: true } type CuaRemote = Context['remote']['cuaAccess'] diff --git a/packages/experimental/cua/tests/mount.client.spec.ts b/packages/experimental/cua/tests/mount.client.spec.ts index dcbd253ae6..bd39c2623f 100644 --- a/packages/experimental/cua/tests/mount.client.spec.ts +++ b/packages/experimental/cua/tests/mount.client.spec.ts @@ -14,7 +14,7 @@ import type { ApplicationApprovalProps } from '../src/client/ApplicationApproval const contribution: TypertRemoteContribution = { package: '@deepseek-ai/dsh-cua', descriptors: [] } const value: CuaApplicationState & { system: CuaSystemPermissionState } = { - system: { platform: 'darwin' as const, accessibility: false, screenRecording: false, helper: { pid: 2 }, parent: { pid: 1 } }, + system: { platform: 'darwin' as const, accessibility: false, screenRecording: false, helper: {}, parent: {} }, allowedApps: [], blockedApps: [], persistentAvailable: true } function actionsOf(value: Record): asserts value is Record & PermissionFace { diff --git a/packages/experimental/cua/tests/panel.client.spec.tsx b/packages/experimental/cua/tests/panel.client.spec.tsx index 613f24fce3..c3b9d083fb 100644 --- a/packages/experimental/cua/tests/panel.client.spec.tsx +++ b/packages/experimental/cua/tests/panel.client.spec.tsx @@ -12,7 +12,7 @@ import { en, zh } from '../src/client/locales.ts' afterEach(() => { cleanup(); vi.useRealTimers() }) const value: CuaApplicationState & { system: Extract } = { system: { platform: 'darwin' as const, accessibility: false, screenRecording: true, - helper: { pid: 9, path: '/native/helper' }, parent: { pid: 8, path: '/host/node' } }, + helper: { path: '/native/helper' }, parent: { path: '/host/node' } }, allowedApps: [], blockedApps: [], persistentAvailable: true } function observe(value: CuaApplicationState & { system: CuaSystemPermissionState }) { @@ -232,7 +232,7 @@ it.each([en, zh])('shows four requirements with the target application beside ea const f = fixture() render() const application = { name: 'Visual Studio Code.app', path: '/Applications/Visual Studio Code.app', icon: 'data:image/png;base64,aWNvbg==' } - f.publish({ ...observe({ ...value, system: { ...value.system, parent: { pid: 1, path: '/sbin/launchd' }, launchApplication: application } }) }) + f.publish({ ...observe({ ...value, system: { ...value.system, parent: { path: '/sbin/launchd' }, launchApplication: application } }) }) const requirements = screen.getByRole('region', { name: dictionary.title }) expect(within(requirements).getAllByRole('group')).toHaveLength(4) expect(screen.getByRole('region', { name: dictionary.applicationsTitle })).toBeTruthy() @@ -440,7 +440,7 @@ it('retains a known read-only configuration and query failure throughout managem it.each([true, false, null] as const)('shows Windows desktop access for lock state %s without macOS permission actions', (sessionLocked) => { const f = fixture() f.publish({ ...observe(value), system: { value: { platform: 'windows', sessionLocked, captureAvailable: true, - elevated: false, helper: { pid: 9, path: 'C:\\helper.exe' } }, error: null, busy: false } }) + elevated: false, helper: { path: 'C:\\helper.exe' } }, error: null, busy: false } }) render() const desktop = screen.getByRole('group', { name: en.windowsDesktop }) const capture = screen.getByRole('group', { name: en.windowsCapture }) @@ -452,7 +452,7 @@ it.each([true, false, null] as const)('shows Windows desktop access for lock sta expect(screen.queryByRole('button', { name: en.granted })).toBeNull() expect(screen.queryByText('C:\\helper.exe')).toBeNull() f.publish({ system: { value: { platform: 'windows', sessionLocked: false, captureAvailable: false, - elevated: true, helper: { pid: 9 } }, error: null, busy: false } }) + elevated: true, helper: {} }, error: null, busy: false } }) expect(within(capture).getByText(en.unavailable)).toBeTruthy() expect(screen.getByText(en.elevated, { exact: false })).toBeTruthy() f.publish({ system: { ...f.state.getSnapshot().system, error: 'offline' } }) @@ -462,7 +462,7 @@ it.each([true, false, null] as const)('shows Windows desktop access for lock sta it.each([[true, true], [false, true], [false, false], [null, true]] as const)('offers Windows setup for lock=%s and capture=%s', (sessionLocked, captureAvailable) => { const f = fixture(), onDismiss = vi.fn() f.publish({ system: { value: { platform: 'windows', sessionLocked, captureAvailable, - elevated: false, helper: { pid: 9 } }, error: null, busy: false } }) + elevated: false, helper: {} }, error: null, busy: false } }) render() const needsSetup = sessionLocked !== false || !captureAvailable expect(screen.queryByRole('dialog') !== null).toBe(needsSetup) diff --git a/packages/extensions/tool-cordis/src/api-catalog.ts b/packages/extensions/tool-cordis/src/api-catalog.ts index 74a5703129..e182793ce2 100644 --- a/packages/extensions/tool-cordis/src/api-catalog.ts +++ b/packages/extensions/tool-cordis/src/api-catalog.ts @@ -6324,7 +6324,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'CuaPermissionProcess', - declaration: 'export interface CuaPermissionProcess {\n pid: number;\n path?: string | undefined;\n name?: string | undefined;\n}', + declaration: 'export interface CuaPermissionProcess {\n path?: string | undefined;\n name?: string | undefined;\n}', }, { name: 'CuaSystemPermission', @@ -6332,7 +6332,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [ }, { name: 'CuaSystemPermissionState', - declaration: 'export type CuaSystemPermissionState = {\n platform: \'darwin\';\n accessibility: boolean;\n screenRecording: boolean;\n helper: CuaPermissionProcess;\n parent: CuaPermissionProcess;\n launchApplication?: {\n name: string;\n path: string;\n icon?: string | undefined;\n } | undefined;\n} | {\n platform: \'win32\';\n sessionLocked: boolean | null;\n captureAvailable: boolean;\n elevated: boolean;\n helper: CuaPermissionProcess;\n};', + declaration: 'export type CuaSystemPermissionState = {\n platform: \'darwin\';\n accessibility: boolean;\n screenRecording: boolean;\n helper: CuaPermissionProcess;\n parent: CuaPermissionProcess;\n launchApplication?: {\n name: string;\n path: string;\n icon?: string | undefined;\n } | undefined;\n} | {\n platform: \'windows\';\n sessionLocked: boolean | null;\n captureAvailable: boolean;\n elevated: boolean;\n helper: CuaPermissionProcess;\n};', }, { name: 'DailyInput',