* Restart the GPU process to recover from macOS compositor freezes
macOS display sleep can leave Chromium's GPU-process display link stuck
on a stale display, so the compositor stops producing frames and the
window looks frozen — unresponsive to clicks and keys — even though the
renderer stays alive.
setupDarwinCompositorWatchdog polls the renderer for frame production
and, on a sustained stall while the window is visible and unlocked,
restarts the GPU process so Chromium rebuilds the display link. This
replaces setupDarwinPaintRefresh, whose invalidate/resize nudges did
not address the dead display link.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Give compositor watchdog a module home
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
The daemon was dying silently with no log trail. Two compounding causes:
1. uncaughtException/unhandledRejection handlers in index.ts called
process.exit(1) immediately after logger.fatal, but pino is configured
with async streams (sync: false console + rotating-file-stream), so the
fatal entry never flushed. main().catch already worked around this with
a 200ms setTimeout — extract exitAfterPinoFlush() and apply it to the
process-level handlers too.
2. socket.send() in the relay transport adapter and ws.send() in
sendToClient/sendBinaryToClient were unprotected. The ws library throws
synchronously on send-after-close, and the readyState === 1 check has a
race window. With an active foreground turn streaming agent_stream
output, a peer-side disconnect could turn into an uncaughtException —
which (per #1) then exited without logging.
Wrap the three send sites in try/catch and warn-log on failure; let
onclose/onerror drive cleanup. The readyState fast-path stays as an
optimization.
Refs getpaseo/paseo#612
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Typing @ in the chat input to reference a file froze the app on huge
workspaces. Two compounding causes:
1. The autocomplete hook fed fileFilterQuery straight into the React
Query key, so every keystroke fired a new directory_suggestions
request and a fresh BFS scan on the daemon. Added a 180 ms debounce
that mirrors the existing pattern in new-workspace-screen so rapid
typing coalesces into one request.
2. searchWorkspaceEntries only ignored node_modules, so dist, build,
target, out, coverage, vendor and __pycache__ each consumed the
5,000-entry scan budget before any real source file was reached.
Extended WORKSPACE_IGNORED_DIRECTORY_NAMES with those names and
added a regression test that proves a deep source file is still
reachable when those directories are full of bait entries.
Refs #599
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Allow `OPENAI_REALTIME_URL` env var to override the hardcoded
`wss://api.openai.com/v1/realtime?intent=transcription` endpoint, with
the current value as default. Pairs with the OpenAI SDK's existing
`OPENAI_BASE_URL` support that already makes HTTP audio endpoints
reroutable. Unblocks pointing the realtime session at any OpenAI
Realtime API protocol-compatible backend (Azure OpenAI, Alibaba
Bailian / DashScope, self-hosted compat layers) without further
changes.
Closes#569
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>