# 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 ``` 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=` support for connecting to an existing WebDriver server. - `--timeout=` is a top-level option for command waits and defaults to `10`. - `--wait-js=` and `--wait-until=` are top-level wait options available to every `glimpse` subcommand. - `--js=` and `--script=` 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 ` - 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 --js=` or `--script=` - execute JavaScript and return the result - `screenshot --output=` - save a PNG screenshot - `search ` - 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=` 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.