Files
glimpse/AGENTS.md
Evan Reichard e3d7c28820 feat: add persistent browser server with auto-discovery
Add `glimpse serve` which starts geckodriver + Firefox and proxies
WebDriver requests through a Unix socket at
$XDG_RUNTIME_DIR/glimpse-<uid>.sock. All commands auto-discover the
socket and reuse the running browser session (~300ms vs ~2-3s per
command).

The proxy intercepts session create/delete to keep Firefox alive:
new session requests return the existing session ID, delete session
navigates to about:blank instead of closing Firefox.

- `glimpse serve` starts in foreground, logs to stderr
- `glimpse serve --stop` sends shutdown via socket
- `glimpse serve --status` prints JSON status
- SIGTERM/SIGINT do full cleanup (Firefox + geckodriver + socket)
- Second instance detected and rejected with exit code 1
- GLIMPSE_SOCKET_PATH env var for test isolation
- Three new smoke tests for serve lifecycle
2026-05-02 20:32:23 -04:00

3.5 KiB

Project Guidelines

Purpose

This project provides small Firefox/Selenium browser utilities packaged by Nix:

  • glimpse - headless browser CLI with subcommands for page extraction, JS execution, screenshots, and search

Keep the tools simple, scriptable, and JSON-friendly.

Commands

Prefer relevant checks after changes because the full suite can take time:

npm run lint
npm run test:list
node test/smoke.js <tag-or-name>

For smoke testing without external network dependencies, use focused tags or scripts such as npm run test:wait, npm run test:errors, or node test/smoke.js reader js. Run npm test and nix build .#default --no-link when the change is broad, touches packaging, or needs full validation. Smoke tests require Firefox and geckodriver on PATH and use local data: HTML pages.

Do not attempt a live Kagi test unless KAGI_TOKEN is available.

CLI Conventions

  • glimpse is the generic CLI and should use subcommands.
  • Keep search as the glimpse search subcommand.
  • Do not reintroduce a top-level --search flag to glimpse.
  • Browser execution should be headless by default.
  • Use --no-headless as the opt-out.
  • Keep --url=<server> support for connecting to an existing WebDriver server.
  • --timeout=<seconds> is a top-level option for command waits and defaults to 10.
  • --wait-js=<code> and --wait-until=<state> are top-level wait options available to every glimpse subcommand.
  • --js=<code> and --script=<file> are top-level options available to every glimpse subcommand and run before command-specific behavior.
  • Prefer structured JSON output for objects/arrays.
  • CLI errors should be structured JSON on stderr with ok: false, stable error.code, error.message, and elapsedMs.

Current glimpse subcommands:

  • reader <url> - extract page content as Markdown (tries Firefox Reader View, falls back to raw Turndown conversion); supports --no-reader to skip Reader View, --format=json for structured output
  • exec <url> --js=<code> or --script=<file> - execute JavaScript and return the result
  • screenshot <url> --output=<file> - save a PNG screenshot
  • search <query> - search with a supported provider and output JSON results
  • serve - start a persistent browser server (geckodriver + Firefox) for faster repeat commands; auto-discovered via Unix socket, --stop to shut down, --status to check

Runtime Requirements

The Nix package must ensure both firefox and geckodriver are available to installed binaries. The current wrapper does this by prefixing PATH for glimpse.

If running outside Nix, document that Firefox and geckodriver must be on PATH.

Code Style

  • Use TypeScript with ES modules; source lives in src/**/*.ts and builds to dist/.
  • Keep code direct and minimal; avoid abstractions until they are needed.
  • Add short Title Case comments above cohesive logic blocks.
  • Prefer exact, actionable error messages.
  • Keep command-line parsing simple unless a real need for a parser library appears.

Nix Notes

  • Update npmDepsHash whenever package-lock.json changes.
  • Keep the source filter excluding .git, .direnv, node_modules, and result.
  • packages.default should contain glimpse.
  • apps.default should run glimpse.

Kagi Notes

Kagi search requires --token=<token> or KAGI_TOKEN. The token is validated by the Kagi provider and passed to Kagi as the token query parameter. The agent may not have this token, so live search validation is best-effort only.