nbshot — notes-browser capture helper

nbshot is a thin command-line client for the notes browser's control socket. It drives an already-running desktop browser over its JSON-RPC control interface — typically to navigate to a note and capture it — without touching the on-screen window, so it never steals focus from whatever else you are doing on the display.

Installed at ~/bin/nbshot (on PATH); source of truth is notes-browser/nbshot in the gdata-server repo.

Prerequisites

• A notes browser is running with a Unix control socket, e.g. notes_browser.py --url http://127.0.0.1:8021 --control-unix-socket ~/tmp/notes-browser.sock (providing the socket path auto-enables Unix control).

• The browser has a display (it is a wxPython GUI). Capture works even when the window is hidden or behind others — see below.

• The target note key exists in whatever store the browser was pointed at (public 8021 or private 8121).

Usage

nbshot <note-key> [out.png]        navigate + off-screen capture (default out ~/tmp/nbshot.png)
nbshot --caps                      list every control method the browser exposes
nbshot --rpc <method> [json]       send any control method and print the JSON reply
nbshot -h | --help                 show help

The socket path defaults to ~/tmp/notes-browser.sock and can be overridden with the NOTES_BROWSER_SOCK environment variable — set it to talk to a different instance (e.g. a private-store browser on its own socket).

The plain form prints the absolute path of the written PNG on success, or exits non-zero with a message if the socket is unreachable or the method returns an error.

How the capture works (and why it doesn't disturb the screen)

nbshot's capture uses the ui.capture_content control method, which renders the browser's HtmlWindow cell tree straight to an off-screen bitmap. Consequences:

• No window raise and no focus theft — you can keep using the screen while captures run.

• It captures the full page, not just the visible viewport, so tall notes (charts, long tables) come out complete.

• It renders content only (no toolbar/nav chrome). The older on-screen ui.capture_screenshot (which blitted the visible window and needed it raised) was removed 2026-07-29; an on-screen blit survives only inside selection.set_and_capture and ui.capture_sixel, which need the painted widget.

Control protocol

Requests are newline-terminated JSON-RPC 2.0 over the AF_UNIX socket: {"jsonrpc":"2.0","id":1,"method":M,"params":{...}}\n. No auth token is required unless the browser was started with control_token set. Full method list and framing details are in the gdata-browser note's "Control Interface" section; nbshot --caps prints the live list.

Handy methods for --rpc: navigate.go_to_page {key}, navigate.back/forward/home/refresh, page.get_current, page.get_document_json, view.zoom_in/out/reset, status.capabilities.

Examples

# Start a public-store browser bound to the control socket
notes_browser.py --url http://127.0.0.1:8021 --control-unix-socket ~/tmp/notes-browser.sock &

# Navigate + capture a note off-screen
nbshot fitness/bodypump-attendance ~/tmp/bodypump.png

# What can this browser do?
nbshot --caps

# Arbitrary calls
nbshot --rpc navigate.home
nbshot --rpc page.get_current
nbshot --rpc view.zoom_set '{"percent": 150}'

# Drive a second (private-store) browser on its own socket
NOTES_BROWSER_SOCK=~/tmp/notes-browser-private.sock nbshot CONTENTS ~/tmp/private.png

Troubleshooting

cannot connect / connection refused — no browser is listening on that socket path. Check the browser is running and was started with --control-unix-socket; confirm the path (ss -xl | grep notes-browser) and NOTES_BROWSER_SOCK. Note the socket is bound relative to the browser's launch directory unless an absolute path was given.

wrong note captured — the browser is a shared instance; another caller may have navigated it. nbshot always navigates first, but there is no locking. Re-run, or use a dedicated instance.

blank / short image — the page had not finished loading, or the window client width is very small. The browser lays the content out at its current width; give it a moment after navigation.

updated 2026-07-29  ·  tags gdata-server, gdata-browser, tooling, automation