Skip to content

v0.7.2

Choose a tag to compare

@github-actions github-actions released this 27 May 05:30
· 134 commits to main since this release
856cdfb

v0.7.2 — mode wiring + audit hardening

Three groups of fixes, all surgical (no refactors, no new features).

1 · Mode chrome flags wired end-to-end (originally tagged v0.7.1)

  • handleLaunchChrome / check-cdp / focus-debug / agent preflight / mcpConfig all consume effectiveLaunchExtras() — security mode now actually launches Chrome on 9333 with --proxy-server + SPKI pin in real user flow. v0.7.0 stored modeChromeProxy but nobody read it; smokes hid the bug because e2e-smoke called launchDebugChrome directly.
  • systemPromptAdditions walks every loaded plugin (not just active-mode plugin). Plugin contributing an always-on prompt without a mode now works.
  • switchMode rolls back currentModeId / modeChromeProxy / mcpEnvOverrides + rebroadcasts modes on activate-hook failure. v0.7.0 left state half-applied.
  • replayFlow refuses cross-origin replay by default. Opt-in via allowCrossOrigin: true on the MCP tool. Prevents agent accidentally probing third-party APIs the dev server calls (Stripe / Sentry / analytics).
  • replayFlow gets a 30s default timeout (AbortSignal.timeout). Hung target no longer blocks the MCP tool indefinitely.

2 · Audit hardening — round 1

  • widget WS reconnectdetachWs() unbinds the previous socket's handlers before swap; scheduleReconnect() guarded against double-scheduling so a paired error+close can't queue two reconnects.
  • widget save-menu race — deferred addEventListener is tracked in attachTimer; a closeMenu() inside the same tick cancels it, so listeners can never attach after close and leak.
  • widget pagehide — new releaseVoiceResources() stops the mic interval, calls recognizer.stop(), and cancels the speaker queue on tab close / HMR reload.
  • core sendIfOpen helper — new utility in service/types.ts. The deferred agents broadcast on connect now guards readyState and .catches a getAvailability rejection (was an unhandled promise).
  • raiseWindowrunCapture / runDetached track a settled flag — a child that errors and then closes can no longer resolve / reject twice.
  • saveHandlers — an onSaved failure (e.g. listSkills) no longer overwrites the artifact's success message with a fake "save failed" error; logged as a warning instead.
  • webpack-plugin — hard floor if (mode !== 'development') return; regardless of custom enabled callback. Prod HTML never gets widget injection.

3 · Audit hardening — round 2

  • duplicate session_end on cancel — a user-initiated cancel() already sent a synthetic session_end{cancelled:true}; the subsequent AbortError surfacing in the for-await catch used to send a second session_end{isError:true}. Catch is now gated on !cancelled and also skips preflight invalidation (CDP isn't suspect — the user just stopped).
  • defaultDisallowedTools on descriptor — the 18-item hard-sandbox deny list moves onto claudeAgent; service.ts pulls invokedDescriptor.defaultDisallowedTools instead of hard-coding the list at the call site. Future agents own their own deny list.
  • error path — switched to sendIfOpen for parity with the cancel-path catch.

Verified

  • pnpm typecheck clean across all 9 publishable packages
  • pnpm test — 177 vitest tests across core / widget-bootstrap / vite-plugin
  • Playwright e2e (basic-app/__vibe_tests__/login-and-counter.spec.ts) passes
  • All 5 security smokes pass

Packages on npm

@hover-dev/core · @hover-dev/widget-bootstrap · @hover-dev/astro · @hover-dev/nuxt · @hover-dev/next · @hover-dev/cli · @hover-dev/security · vite-plugin-hover · webpack-plugin-hover — all at 0.7.2.

Full Changelog: v0.7.0...v0.7.2