Seed library
Coverage of new patterns grows by adding worked examples, not by changing core. A seed is a human-written example — "when the captured steps look like this, the Playwright code should look like that" — that the optimization pass generalizes from as few-shot.
Writing a seed
Drop a JSON file in <projectRoot>/.hover/rules/:
{
"name": "oauth-popup",
"signature": ["browser_click", "browser_tabs:select"],
"note": "sign in through a provider popup that opens a new tab",
"example": {
"steps": [
{ "tool": "browser_click", "element": "Sign in with Google button" },
{ "tool": "browser_tabs", "action": "select", "idx": 1 }
],
"code": "const [popup] = await Promise.all([\n context.waitForEvent('page'),\n page.getByRole('button', { name: 'Sign in with Google' }).click(),\n]);\nawait popup.getByLabel('Email').fill('user@example.com');"
}
}
signatureis a cheap relevance filter — Hover only feeds a seed to the pass when one of its base tools appears in the spec. It is not exact-matched.codemust obey the same rules as generated specs:getByRole/getByLabel/getByTextselectors, no XPath, nowaitForTimeout.
No fork, no plugin code — just an example file. Share seeds with your team by
committing .hover/rules/, or with the community as a package.
Built-in seeds
Hover ships a small built-in set for high-certainty, app-agnostic patterns (e.g.
download → waitForEvent('download') pairing). The bar to be built-in is
high: only deterministic, can't-mislead patterns qualify. High-frequency
fixed-structure shapes like popup are hardcoded straight into the translator
instead; semantic judgements (which feedback text to assert) stay as standing
instructions in the pass, not seeds.