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
71 lines
3.5 KiB
Markdown
71 lines
3.5 KiB
Markdown
# 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:
|
|
|
|
```bash
|
|
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.
|