Harden Mac VM screenshots against blank VNC frames - #315
Conversation
The latest updates on your projects. Learn more about Vercel for GitHub. |
📝 WalkthroughWalkthroughVNC screenshot capture now detects blank/black frames, counts retry attempts, sends periodic wake actions, and includes attempt counts in operation messages. Work sessions hook detects when lanes are missing but referenced by sessions, then triggers a lightweight lane refresh once per project root with retry on failure. ChangesVNC Blank Frame Handling
Work Sessions Lane Recovery
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Capy auto-review is paused for this organization because the monthly auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews. |
arul28
commented
May 17, 2026
@copilot review but do not make fixes |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
arul28
commented
May 17, 2026
@copilot review but do not make fixes |
Uh oh!
There was an error while loading. Please reload this page.
Summary
Verification
ADE PR creation note: attempted the ADE CLI path first, but this renamed branch could not be imported/attached to the existing worktree lane; using gh fallback per shipLane.
Summary by CodeRabbit
Bug Fixes
Tests
Greptile Summary
This PR hardens Mac VM VNC screenshot capture against blank/black framebuffer responses, adding retry logic with display-wake actions, and fixes a race where Work sessions load before lane state is available.
rfbDirectClient.tsgainsisLikelyBlankRgbaFrame(sampled RGBA analysis at 0.3% threshold) and a retry loop that wakes the display with a pointer move and Shift tap every 1–3 blank frames, then re-requests a full frame every 250 ms until a real frame or the outer timeout arrives.useWorkSessions.tsadds a one-shotrefreshLanescall when sessions reference a lane butlanes[]is still empty, gated by a ref so failures and subsequent session refreshes don't trigger additional calls.Confidence Score: 5/5
The changes are well-scoped and the retry/gating logic is correctly structured; no paths introduce data loss or incorrect state.
Both the VNC retry loop and the lane-recovery effect are correctly guarded:
settledprevents double-resolution,cleanup()always cancels the retry timer before the promise settles, and the lane-recovery ref gate survives errors without enabling rapid re-fires. Tests exercise the key edge cases (cursor-only patch, failure gating). The one timing nuance (retryTimer nulled before requestFullFrame) is extremely unlikely to manifest in production and has no safety impact.No files require special attention;
rfbDirectClient.tscarries the most logic density and warrants a second read, but all paths are covered by the new tests.Important Files Changed
onlisteners, blank-frame detection loop, display-wake side effects, and proper cleanup; logic is sound with one minor timing nuance around retryTimer nulling.Sequence Diagram
sequenceDiagram participant Caller participant captureVncScreenshot participant VncClient participant retryTimer Caller->>captureVncScreenshot: captureVncScreenshot(connection, 15s) captureVncScreenshot->>VncClient: connect + authenticate captureVncScreenshot->>VncClient: requestFullFrame() captureVncScreenshot->>captureVncScreenshot: register on(firstFrameUpdate, frameUpdated) VncClient-->>captureVncScreenshot: frameUpdated (blank frame) captureVncScreenshot->>captureVncScreenshot: isLikelyBlankRgbaFrame → true captureVncScreenshot->>captureVncScreenshot: blankFrameAttempts++ captureVncScreenshot->>VncClient: wakeVncDisplay (pointer + Shift) captureVncScreenshot->>retryTimer: setTimeout(250ms) retryTimer-->>captureVncScreenshot: fires captureVncScreenshot->>VncClient: requestFullFrame() VncClient-->>captureVncScreenshot: frameUpdated (real frame) captureVncScreenshot->>captureVncScreenshot: isLikelyBlankRgbaFrame → false captureVncScreenshot->>captureVncScreenshot: makeOpaqueRgba + encodeRgbaPng captureVncScreenshot->>captureVncScreenshot: cleanup() — remove listeners, clear timers captureVncScreenshot-->>Caller: "DirectVncScreenshot { pngData, blankFrameAttempts }" note over captureVncScreenshot: If outer timeout fires first → finishWithError with retry count in messagePrompt To Fix All With AI
Reviews (2): Last reviewed commit: "ship: iteration 1 - address Greptile fee..." | Re-trigger Greptile