(
allowlistBundleIds: string[],
displayId?: number,
)
| 302 | // ── Pre-action sequence (hide + defocus) ──────────────────────────── |
| 303 | |
| 304 | async prepareForAction( |
| 305 | allowlistBundleIds: string[], |
| 306 | displayId?: number, |
| 307 | ): Promise<string[]> { |
| 308 | if (!getHideBeforeActionEnabled()) { |
| 309 | return [] |
| 310 | } |
| 311 | // prepareDisplay isn't @MainActor (plain Task{}), but its .hide() calls |
| 312 | // trigger window-manager events that queue on CFRunLoop. Without the |
| 313 | // pump, those pile up during Swift's ~1s of usleeps and flush all at |
| 314 | // once when the next pumped call runs — visible window flashing. |
| 315 | // Electron drains CFRunLoop continuously so Cowork doesn't see this. |
| 316 | // Worst-case 100ms + 5×200ms safety-net ≈ 1.1s, well under the 30s |
| 317 | // drainRunLoop ceiling. |
| 318 | // |
| 319 | // "Continue with action execution even if switching fails" — the |
| 320 | // frontmost gate in toolCalls.ts catches any actual unsafe state. |
| 321 | return drainRunLoop(async () => { |
| 322 | try { |
| 323 | const result = await cu.apps.prepareDisplay( |
| 324 | allowlistBundleIds, |
| 325 | surrogateHost, |
| 326 | displayId, |
| 327 | ) |
| 328 | if (result.activated) { |
| 329 | logForDebugging( |
| 330 | `[computer-use] prepareForAction: activated ${result.activated}`, |
| 331 | ) |
| 332 | } |
| 333 | return result.hidden |
| 334 | } catch (err) { |
| 335 | logForDebugging( |
| 336 | `[computer-use] prepareForAction failed; continuing to action: ${errorMessage(err)}`, |
| 337 | { level: 'warn' }, |
| 338 | ) |
| 339 | return [] |
| 340 | } |
| 341 | }) |
| 342 | }, |
| 343 | |
| 344 | async previewHideSet( |
| 345 | allowlistBundleIds: string[], |
nothing calls this directly
no test coverage detected