Repository navigation
Releases: slabbdev/navette
Release list
v1.9.0 — native input on all three engines (macOS verified)
macOS closes the native-input loop — all three engines now ship attempt-first OS-level key events.
- macOS (new):
show_windowis the focus gate — the ghost's window becomes a titled key window, the Window Server must confirmisKeyWindow, and only then are CGEvents posted (a keystroke can never land in someone else's app). Single characters carryCGEventKeyboardSetUnicodeString: the deliverede.keyis what the agent asked for on any layout — on AZERTY, keycode 0x00 produces 'q' natively; navette's events arrive as the requested character ('Z' uppercase with no shift). Delivery is verified in-page (isTrusted: true) beforemode: nativeis reported; anything less falls back to synthetic, mode always reported. Live-tested: a, Enter, Z, Tab, ArrowLeft — all native, zero fallbacks. (#3) - Windows: SendInput (unchanged, verified end-to-end).
- Linux: XTEST via x11rb (unchanged; X11/XWayland).
NAVETTE_EVAL_TIMEOUT_SECS(default 20, clamped 5–300) — slow or contended environments choose slow-success over false-timeout. (#7)
Carried from the v1.8.x train: cross-engine session isolation as a CI assertion, per-session WebView2 profiles + InPrivate, constant-time token compare, DNS-rebinding guard, credential-redacted proxy logs, docs/SECURITY.md, the CC BY 4.0 tollbooth dataset, and the signed-webhook demo.
Binaries for macOS arm64, Windows x64, Linux x64 + arm64.
v1.8.1 — session isolation on every engine, hardened loopback API
Cross-session cookie isolation is now a build-breaking CI assertion on macOS, Windows AND Linux.
- Windows: every session gets its own WebView2 profile (
with_profile_name) + InPrivate. InPrivate alone was not enough — all InPrivate controllers of one environment share a single profile (Edge InPrivate semantics, measured in CI); named profiles give each session an isolated cookies/storage/cache domain while sharing the runtime. (#6, closed) - macOS: non-persistent
WKWebsiteDataStoreper session (unchanged, now asserted). - Linux: isolated WebContexts per session, cookies never touch disk (now asserted). Known residual: WebKitGTK still writes HTTP cache/HSTS to
~/.cache/~/.local/share— needs the wry ephemeral-context lifetime fixed upstream. - Security hardening: constant-time token comparison; DNS-rebinding guard (non-local
Hostheader → 403,/healthexempt);--proxyURLs credential-redacted before logging. - Demo:
demo/signed-webhook— a 150-line HMAC-chained mock counterparty; fraud analysis as a diff, not a log read (#5).
Also in this train: the tollbooth dataset is CC BY 4.0 with x402/paywall signals (v1.8.0's bench round 2), and the walled-web post is live at https://dev.to/slabb/my-agent-met-the-real-web-403s-challenges-and-the-coming-tollbooth-1h2g
Binaries for macOS arm64, Windows x64, Linux x64 + arm64.
v1.8.0 — visible session windows & real pointer events
The human-login loop is closed: visible session windows + real pointer events.
session_show/session_hide— a ghost session can come on-screen with its page state intact (setReleasedWhenClosed:false— a user-closed window is recoverable too), for the one thing automation can't do alone: the first human login (OAuth, 2FA, a captcha, a password manager). Park it off-screen again and the agent keeps driving. This is the loop the newdemo/dailydevrecipe runs in production./clicknow dispatches PointerEvents (pointerover/pointerdown/pointerup) before the mouse events — Radix and headless-UI components open like they do for a human. Found in the wild: the kebab menu on daily.dev would not open without them.- macOS
/waitfix — the bridge stringifies JS booleans as1(NSNumber description), the probe compared againsttrue, so every present selector "timed out". The probe now accepts both spellings. - webviewkit — the backend contract is now a single kit trait, compile-enforced per backend instead of trusted by convention.
- Tollbooth round 2 — the walled-web bench now measures x402/paywall signals (HTTP 402,
X-Payment*/X402*headers, schema.orgisAccessibleForFree:false) alongside robots.txt AI clauses and llms.txt adoption: 200 URLs × 5 categories, dataset committed under CC BY 4.0 (bench/tollbooth-results.{json,csv}+bench/DATASET.md).
Binaries for macOS arm64, Windows x64, Linux x64 + arm64.
v1.7.0 — native keyboard input, honest modes
POST /key now attempts REAL OS-level keyboard events before the synthetic dispatch — and the response says which mode ran.
- Windows: SendInput to the focused WebView2 render widget (child-window focus, VK mapping, proper keyup pairs). The platform where native input is verified end-to-end.
- Linux: XTEST fake-input with a keysym→keycode scan of the live server keymap; the ghost window is brought on-screen and focused first.
- macOS: wired but reports
native unavailablefor now — CGEvents post, but routing into a headless WKWebView needs an app-bundle activation story the Window Server only grants real foreground apps (the experimental on-screen approach is preserved in git history).
Every response carries a mode field: native or synthetic. No lies in the protocol — when the native path refuses (headless CI, missing permissions), the synthetic fallback fires automatically and the caller knows exactly what happened.
Also fixed: the Linux key path no longer pumps GTK from the HTTP thread (a worker-thread gtk::main_iteration deadlocks the main loop — CI exit 52).
Binaries for macOS arm64, Windows x64, Linux x64 + arm64.
v1.6.0 — the operator release
Deploy navette on machines that are not yours.
--token SECRET: Bearer auth on every HTTP route (except/health) —Authorization: BearerorX-Navette-Token. An MCP host attaches to a protected serve with theNAVETTE_TOKENenv var. Loopback-only was never enough for shared machines and lab LANs.--proxy URL: HTTP CONNECT or SOCKS5, applied at webview creation on the wry backends (soup / WebView2 options / Network framework). Proxy credentials in the URL are refused loudly — the engine layer doesn't carry them; use IP allowlisting. macOS follows the system proxy.--user-agent UA: per-serve override at webview creation, WKWebView included.- linux-arm64 joins the release assets (aarch64 Linux is where agents actually run).
All three flags validated live: 401 without/with wrong token, 200 with Bearer and X-Navette-Token; navigator.userAgent override confirmed; a bogus --proxy blocks navigation while the API stays reachable.
Binaries: macOS arm64, Windows x64, Linux x64 + arm64.
v1.5.0 — the idle watchdog
The daemon keeps its reflexes and gives back its memory.
serve --idle-release <minutes>: sessions untouched for that long are dropped whole — window, webview, WebKit helper processes — while the daemon itself stays resident. The next request re-creates and re-warms on demand (the pre-warm path, 83 ms on the CI VM).0= off, the original always-warm promise. Idea credit: reid's point that local MCP helpers either hold VRAM forever or pay full startup every call — this is the middle path. Validated live on macOS (drop via the main thread) and Linux (drop via the event loop).- bench/tollbooth.py: ~200 real URLs across five categories (docs, news, e-commerce, dev-tools, social), measuring three independent walls per site — robots.txt AI clauses (10 agent user-agents), llms.txt adoption, and the agent path itself: real WebKit over a residential IP, classified ok / challenge / empty-js-gate / timeout. The dataset lands in the repo.
- README FAQ: the native-vs-ML extraction trade documented with both orders of magnitude (~10 ms/page DOM walk vs ~600 ms/page trained models) — two trades, not a ranking.
Binaries attached for macOS arm64, Windows x64, Linux x64.
v1.4.1 — --help / --version
A distributed CLI without --help is a broken first impression: unknown arguments used to silently start a serve. Now:
navette --help— usage, modes, routesnavette --version/-V/version
Binaries attached for macOS arm64, Windows x64, Linux x64.
v1.4.0 — upload, scroll, 16 tools
The agent loop is complete: upload, scroll, and every previous primitive, on all three OSes.
- POST /upload: fills a file input with in-memory content through a page-side DataTransfer — no OS dialog, identical JS on WKWebView, WebView2 and WebKitGTK. The CI smoke now proves a full round-trip: upload a 5-byte file, let the page's own JS read it, assert name:size.
- POST /scroll: absolute Y offset or scrollIntoView (centered).
- 16 MCP tools:
hover,key,scroll,upload,viewportjoined the original set. - eval_js fix worth the release on its own: the evaluation wrapper discarded its value on Windows/Linux — every
/evaluateand/readcall silently returnedundefined. CI now tests evaluate explicitly. (navigate → readthrough the fold path was never affected.) - bench workflow (workflow_dispatch): 30-page corpus, median/p95 for navigate+read, /read and /screenshot per engine, results in the step summary.
Known gaps, stated plainly: OS-level keyboard/mouse input (synthetic events today), request/response network interception, OS file-dialog automation.
Binaries attached for macOS arm64, Windows x64, Linux x64.
v1.3.0 — full platform parity
navette now does everything on every OS it runs on.
- Screenshots everywhere: WKWebView snapshot (macOS), PrintWindow PW_RENDERFULLCONTENT on the WebView2 render widget (Windows), X11 capture of the on-screened ghost window under a GTK pump (Linux). CI verifies a valid PNG on all three OSes.
- Cookie state everywhere: export/import with one JSON schema across OSes — an authenticated session saved on macOS restores on Linux. The Playwright storageState equivalent, no Chromium attached.
- Viewport control per session (screenshot dimensions follow it).
- Resident daemon on every platform: LaunchAgent (macOS), schtasks ONLOGON (Windows), systemd user unit (Linux).
- JS dialogs auto-handled in-page — alert no-ops, confirm accepts, prompt returns its default. Agents can no longer deadlock on a hidden modal.
- hover and key events join the API. 14 MCP tools now.
- Fixed a macOS cookie-import deadlock along the way (raw multi-argument msg_send replaced with typed Foundation APIs).
Binaries for macOS arm64, Windows x64 and Linux x64 are attached. One binary, ~630 KB, no Chromium download. Install: drop the file anywhere, run navette serve, or point your MCP host at it. CI green on all three OSes with the full smoke (navigate, read, screenshot, cookie round-trip).
v1.2.1 — cross-platform smoke green
The hardening release: navette now passes the same runtime smoke on all three OSes.
- CI green on macOS (WKWebView), Windows (WebView2) and Linux (WebKitGTK) — health, navigate, fold, read on every push.
- Five root-cause fixes behind the wry smoke failures:
- the fold result had no route back to the HTTP caller (pending consumed twice)
- page-load completion was not URL-matched — the initial about:blank load swallowed a cold-start navigate
- the fold wrapper discarded the extraction expression's return value
- gtk_init blocked on the missing D-Bus session bus in headless CI (gdb-proven)
- WebView2 stalls ~45 s on file:// URLs on GPU-less CI VMs — loopback http it is
- Boot-time session pre-warm (parity with the macOS backend): first navigate on the CI VM went 38 s → 83 ms.
- macOS remains the fully-featured platform: screenshots, cookie state export/import, resident daemon. wry parity lands next.
One binary, 626 KB, no Chromium attached.