glimpse
Small Firefox/Selenium browser utilities packaged with Nix.
The project provides a glimpse CLI with subcommands for page automation and provider-backed search. It runs Firefox headless by default. The Nix package wraps the binary so firefox and geckodriver are available on PATH.
Requirements
Nix Usage
Nix is the easiest way to run this project. It provides Node.js, Firefox, and geckodriver.
nix run .#glimpse -- exec https://example.com --js='return document.title'
Local Node Usage
If running directly with Node.js, install dependencies and make sure firefox and geckodriver are available on PATH.
npm install
node index.js exec https://example.com --js='return document.title'
Glimpse CLI
glimpse <command> [options]
Common options:
--no-headless- show Firefox instead of running headless--url=<server>- connect to an existing WebDriver server--timeout=<ms>- maximum wait time in milliseconds for command waits (default:10000)--wait-js=<code>- poll JavaScript until it returns a truthy value before command-specific behavior--wait-until=<state>- wait for document readiness:none,interactive, orcomplete(default:none)--js=<code>- execute inline JavaScript after loading the page and before command-specific behavior--script=<file>- execute JavaScript from a file after loading the page and before command-specific behavior
Running glimpse with no arguments or with --help prints human-readable help. Runtime and validation errors are emitted as structured JSON on stderr with ok: false, a stable error code, a human-readable message, and elapsedMs.
Snapshot A Page
Return an agent-friendly structured view of a page.
nix run .#glimpse -- snapshot https://example.com
Wait for asynchronous page state before extracting the snapshot:
nix run .#glimpse -- snapshot https://example.com --wait-until=complete --wait-js='return document.body.innerText.length > 0'
Output:
{
"ok": true,
"url": "https://example.com/",
"title": "Example Domain",
"result": {
"text": "Example Domain\nThis domain is for use in illustrative examples...",
"headings": [
{
"level": 1,
"text": "Example Domain"
}
],
"links": [
{
"text": "More information...",
"href": "https://www.iana.org/domains/example"
}
],
"buttons": [],
"inputs": [],
"forms": []
}
}
Snapshot includes page text, headings, links, buttons, inputs, and forms. Heading extraction is best-effort and does not fail the snapshot if heading metadata cannot be extracted.
Reader View To Markdown
Open a page with Firefox Reader View and print the readable article content as Markdown.
nix run .#glimpse -- reader https://example.com/article
Write Markdown to a file:
nix run .#glimpse -- reader https://example.com/article --output=article.md
Other formats are available:
nix run .#glimpse -- reader https://example.com/article --format=json
nix run .#glimpse -- reader https://example.com/article --format=html
nix run .#glimpse -- reader https://example.com/article --format=text
Options:
--format=<format>- outputmarkdown,html,text, orjson(default:markdown)--output=<file>- write output to a file
Execute JavaScript
JavaScript execution is available as a top-level option for every glimpse command. The script runs after loading the page and before command-specific behavior.
Use the exec command when you only want to print the returned JavaScript value.
Inline JavaScript:
nix run .#glimpse -- exec https://example.com --js='return document.title'
JavaScript from a file:
nix run .#glimpse -- exec https://example.com --script=extract.js
The script should explicitly return a value:
return {
title: document.title,
links: Array.from(document.querySelectorAll("a")).map((a) => a.href),
};
Objects and arrays are printed as formatted JSON. Primitive values are printed directly.
Screenshot A Page
Save a PNG screenshot after loading a page.
nix run .#glimpse -- screenshot https://example.com --output=example.png
Run JavaScript before taking the screenshot:
nix run .#glimpse -- screenshot https://example.com --js='document.body.style.zoom = "80%"' --output=example.png
If --output is omitted, the screenshot is saved to screenshot.png.
Output:
{
"ok": true,
"result": {
"path": "example.png"
},
"elapsedMs": 842
}
Search With A Provider
Search using a supported provider and print a JSON array of results. Currently only Kagi is supported.
Kagi requires --token=<token> or a KAGI_TOKEN environment variable. The token is validated by the Kagi provider and sent to Kagi as the token query parameter.
KAGI_TOKEN=... nix run .#glimpse -- search --provider=kagi "nix flakes selenium webdriver"
Local usage:
KAGI_TOKEN=... ./result/bin/glimpse search "nix flakes selenium webdriver"
Options:
--provider=<provider>- search provider:kagi(default:kagi)--token=<token>- Kagi token (default:KAGI_TOKEN)--no-headless- show Firefox instead of running headless--url=<server>- connect to an existing WebDriver server--timeout=<ms>- wait time for results before returning[](default:10000)
Output is a JSON array of search results:
[
{
"title": "Result title",
"url": "https://example.com",
"description": "Result description"
}
]
Build
Build the default package, which contains glimpse:
nix build .#default
Run the built tool:
./result/bin/glimpse exec https://example.com --js='return document.title'
KAGI_TOKEN=... ./result/bin/glimpse search "example query"
Development
Enter the dev shell:
nix develop
Run linting:
npm run lint
Run smoke tests. These require Firefox and geckodriver on PATH and use local data: HTML pages.
npm test
Run focused smoke tests by tag when iterating on a specific area:
npm run test:list
npm run test:snapshot
npm run test:wait
npm run test:errors
node test/smoke.js snapshot js
Useful local commands:
node index.js snapshot 'data:text/html,<title>Hello</title><h1>Hello</h1>'
node index.js exec 'data:text/html,<title>Hello</title>' --js='return document.title'
node index.js screenshot 'data:text/html,<title>Hello</title>' --output=/tmp/page.png
node index.js reader 'https://example.com/article'
Project Structure
index.js-glimpseCLI with subcommands, including Firefox Reader View extraction and provider-backed searchdriver.js- Firefox WebDriver creation and geckodriver resolutionkagi.js- reusable Kagi search provider implementationflake.nix- Nix dev shell, package, wrappers, and appsKAGI.md- Kagi-specific notes