Skip to content

v0.12.0

Choose a tag to compare

@github-actions github-actions released this 29 May 10:02
· 120 commits to main since this release
34b0abe

Highlights

πŸ›‘οΈ Security spec recording β€” closes the v0.7 loop

When @hover-dev/security is active, the agent's replay_flow MCP tool gains two parameters:

  • intent β€” one-line human description, e.g. "IDOR: access another user's order"
  • expectStatus β€” the HTTP status that proves the security control works, e.g. 403

When the agent passes both, Hover records the replay as a security check in the control plane. After a probing session, the widget's Save-as β†’ Security spec entry writes __vibe_tests__/<slug>.security.spec.ts β€” plain @playwright/test using the request fixture, one test() per recorded check:

test.describe('security: orders-idor', () => {
  test("01 β€” IDOR: access another user's order", async ({ request }) => {
    // Recorded as a vulnerability: observed 200, expected 403.
    // After fix, this test passes (server now returns 403).
    const response = await request.get('http://localhost:5174/api/orders/999');
    expect(response.status()).toBe(403);
    // Coarse PII-leak guard: a real 4xx should be short.
    const body = await response.text();
    expect(body.length).toBeLessThan(500);
  });
});

CI runs it without MITM, without the agent. Today's IDOR is tomorrow's CI gate.

See the Security spec feature page for the full walkthrough.

Two new plugin extension points

The Save dropdown wasn't previously extensible by plugins β€” it had a hard-coded list of three artefacts (Skill / Spec / Jira CSV). v0.12 generalises:

  • HoverPluginManifest.saveHandlers (server) β€” plugins declare { type, label, handle(ctx) }. The service routes incoming save:<type> WS messages to the matching plugin handler. No SkillStep[] coercion β€” plugins own their own write semantics.
  • WidgetPluginSpec.saveEntries (widget) β€” plugins declare { type, label, sub?, fields?, confirmLabel?, successMsgTemplate? }. The Save-as dropdown queries the active plugin via host.getActiveSaveEntries() and appends them.

@hover-dev/security's "Security spec" entry uses both APIs. A hypothetical perf-probe plugin could register save:perf:report the same way without touching core.

What's NOT in this release

  • --all / --failed batch security-spec recording β€” single spec per save still. Same rationale as v0.11 re-record: rejected on purpose to avoid blind token burn; on the roadmap for v0.13+.
  • Automatic auth in CI β€” Playwright's storageState is the right mechanic; the spec emits a TODO header pointing at the FAQ. See Security spec auth setup.

Caveats

  • Both intent AND expectStatus required to record. Missing either β†’ the replay still works, but isn't recorded. The MCP server's response includes a hint when one is supplied and the other isn't.
  • PII-leak guard is coarse β€” body.length < 500 for 4xx expectations. Tighten by hand for high-value endpoints.
  • Auth state needs storageState. Spec emits an ⚠ Authentication TODO header always; FAQ has the recipe.

Roadmap

  • v0.12 βœ“ Security spec recording (this release)
  • v0.13+ or sibling repo β†’ Chrome extension

Validation

  • pnpm typecheck clean across all 10 publishable packages.
  • pnpm --filter @hover-dev/core test: 176 tests pass.
  • pnpm --filter @hover-dev/security test: 17 new tests pass.
  • pnpm test:e2e: 5 Playwright tests on examples/basic-app pass (no regressions from Save dropdown / onmessage chain changes).
  • Manual smoke (agent recording real checks + spec round-trip) deferred to post-release.

Full diff

v0.11.0...v0.12.0