Screenshot replies: prefer ab's fullPath/safePath contract over base64/filePath (auto-pull without the relay payload)
From the #212 audit (ab 2.1.150, crr/arav-rog, 2026-09-22). nb's contract is in good shape for what ab now relies on: bridge.json verbs (87) match nbrowser_describe (87), the timeouts block is declared (default 60, screenshot/record prefixes 120) and statusVerb: nbrowser_status is there. Nothing else is needed. One small thing:
Screenshot reply shape. nbrowser_describe declares nbrowser_screenshot -> {base64, filePath?, ok} and nbrowser_screenshot_full_res -> {base64, ok}. ab's delivery contract is fullPath (+ optional safePath): a reply carrying those is auto-pulled to the CALLER's machine with localPath/localSafePath added, which is how an AI in a container reads the image without a second call. filePath does not trigger it.
The base64 path does work — ab's CLI saves any reply's base64 PNG to the caller's screenshot cache (generic since 2.1.146, resized to ≤1500 px unless the verb name ends _full_res) — so nb is better off than pup here. But sending a big base64 through the relay for every capture is the expensive way to do it; fullPath + safePath (kicad_screenshot_all is the reference) gets the same result with a streamed pull.
Also noted, not a complaint: nbrowser_screenshot with no session/tab refuses with a clear no_target explanation rather than grabbing whatever is in front of the user. That is exactly the right behaviour.