CLI
@hover-dev/cli is the zero-install Hover CLI. Exposed as the hover bin once installed.
npx @hover-dev/cli setup
setup reads your package.json to pick the right Hover integration (Vite / Astro / Nuxt / Next / Webpack), sniffs your lockfile to pick the package manager (pnpm / yarn / bun / npm), spawns the install command, then uses magicast to AST-mutate your bundler config.
Commands
| Command | What it does |
|---|---|
setup | Install + wire the integration into your bundler (detailed below). |
run "<prompt>" | Drive the debug Chrome from the terminal — no widget. --save <slug> crystallizes a spec. See CLI mode. |
optimize <spec> | The optional AI optimization pass — propose an improved spec (candidate + diff, original kept). |
extract | Lift flows repeated across specs into shared Page Objects + fixtures. |
re-record <spec> | Regenerate a spec against the current UI (replays its Original prompt:). |
run is the CLI-only authoring path; the others post-process specs you've already saved — the same operations the widget's Save / Optimize / Re-record do.
hover run (CLI mode)
Drive Hover entirely from the terminal — no widget, no DOM injection. Useful when you'd rather not (or can't) inject the widget into a page: scripting, non-bundler projects, or terminal preference.
hover run "test the login flow" --url http://localhost:5173 --save login
--url <devUrl>— the page to open / drive (picks the matching tab).--save <slug>— crystallize the verified run into__vibe_tests__/<slug>.spec.ts. Omit it to just watch the run.--agent <id>/--model <m>— override the agent (defaultclaude) / model (defaultsonnet);HOVER_AGENT/HOVER_MODELenv vars work too.
It needs only @hover-dev/core — no setup, no bundler config (setup exists to inject the widget; CLI mode doesn't use it):
npm i -D @hover-dev/core @hover-dev/cli
hover run auto-launches the isolated debug Chrome if one isn't already up (the same persistent profile the widget uses), then drives it over CDP. It is not headless — it's a real, visible Chrome you log into once; the first run on a flow that needs auth asks you to log in and re-run, later runs reuse the session. After --save, polish it with hover optimize <slug>; the spec runs in CI with no agent.
What CLI mode does not cover (these need the in-page widget): Record mode, the Fix prompt, and voice.
setup flags
--vite Force the Vite integration (vite-plugin-hover)
--astro Force the Astro integration (@hover-dev/astro)
--nuxt Force the Nuxt integration (@hover-dev/nuxt)
--next Force the Next integration (@hover-dev/next)
--webpack Force the Webpack integration (webpack-plugin-hover)
--cwd <path> Target a specific workspace (monorepos). Absolute or
relative to where you invoked the CLI. -C is the short form.
--dry-run Preview the install + config edits without applying them
Monorepo support
Recognised shapes: pnpm-workspace (pnpm-workspace.yaml), npm/yarn workspaces (workspaces field), turbo (turbo.json).
Run the CLI from the repo root:
npx @hover-dev/cli setup
The CLI enumerates the declared workspaces and detects bundlers in each.
- Exactly one match — dispatches automatically. The CLI installs the Hover package into that workspace and edits its config file (not the root).
- Multiple matches in a TTY — an interactive picker appears.
↑/↓(orj/k) to move,Enterto confirm,Esc/q/Ctrl-Cto cancel. - Multiple matches in CI / piped invocation — the CLI prints the candidates and exits 1; re-run with
--cwd apps/web(or whichever workspace path). - No match — the CLI tells you it's a monorepo root with no supported bundler in any declared workspace, and points you at
--cwd.
You can always skip detection and target one app directly:
npx @hover-dev/cli setup --cwd apps/web
Run the CLI once per app you want to wire. There is no --all mode by design — each install gets independent install / mutate failure modes you can react to.
The package manager is detected by walking up from the target workspace until it finds a lockfile, so a pnpm-managed monorepo with a single root pnpm-lock.yaml works without surprise — sub-workspaces don't need their own lockfile.
Idempotency
Running npx @hover-dev/cli setup twice on the same project no-ops the second time. Safe to put in a setup script.
Detection priority
Frameworks are matched in this order so a project whose dep tree legitimately contains a lower-priority framework still routes to the right shim:
astronuxtnext— checked before webpack so Next projects (Turbopack default since Next 16) route to@hover-dev/next, notwebpack-plugin-hover.webpack— matches onwebpack-cli(the user-facing dep), not a transitivewebpack(every Vite project has webpack somewhere).vite— catch-all for Vite-based projects that aren't Astro / Nuxt / Svelte.
An explicit --<framework> flag overrides detection entirely.
Next.js: two-file mutator + one manual step
For Next, the CLI does two file edits:
- Wraps the user's
next.config.{mjs,js,ts}export inwithHover(...). - Creates (or merges into)
instrumentation.tsat the project root or undersrc/, calling Hover'sregister()from inside the user's ownregister()hook.
It deliberately does not auto-edit app/layout.tsx. The <HoverScript /> insertion is printed as a one-liner for you to paste — AST-mutating user JSX invites whitespace drift and Server Component shape surprises.