v0.7.3
v0.7.3 — Next 15 unblocked, monorepo workspaces, interactive picker
Two real-world install paths that didn't work in v0.7.2.
1 · Next 15 + next.config.ts no longer crashes
Next 15 (the version many users are still on — Next 16 just went stable) loads next.config.ts through a CJS require() step. With @hover-dev/next shipped as ESM-only (exports.import but no exports.require), Node's CJS resolver threw ERR_PACKAGE_PATH_NOT_EXPORTED before withHover() ever ran:
Error: No "exports" main defined in node_modules/@hover-dev/next/package.json
Fixed:
- tsup dual-build —
format: ['esm', 'cjs']produces both.jsand.cjsoutputs. - Conditional exports map — paired
import/requireconditions, each with its owntypesdeclaration (.d.ts/.d.cts). HoverScriptis now an async server component — dynamic-imports@hover-dev/widget-bootstrapso the ESM-only widget package stays out of the CJS bundle's top-level require graph. React 19 / App Router renders async server components natively, so the user-facing<HoverScript />shape is unchanged.
Verified working: Next 15 + next.config.ts, Next 15 + next.config.mjs, Next 16 + Turbopack.
2 · CLI handles turbo / pnpm-workspace / yarn-workspace monorepos
Previously npx @hover-dev/cli add at a monorepo root walked up to the root package.json, saw only turbo / TS / lint, and exited "Couldn't detect a supported bundler." Now:
isMonorepoRoot()+findWorkspaces()recognisepnpm-workspace.yaml,package.jsonworkspaces(array OR{ packages: [...] }), andturbo.json.- Dispatch logic:
- One workspace declares a supported bundler → installs into it automatically.
- Multiple matches in a TTY → interactive picker (
↑/↓orj/k, Enter to confirm,Esc/q/Ctrl-Cto cancel). - Multiple matches in non-TTY (CI, pipes) → lists candidates, exits 1, asks for
--cwd apps/web.
--cwd <path>/-C <path>flag for direct targeting (absolute or relative).detectPackageManagerwalks up to find a lockfile, so a sub-workspace without its ownpnpm-lock.yamlcorrectly inherits the root's pnpm/yarn/bun/npm choice.
3 · Interactive picker — no new dependency
packages/cli/src/picker.ts — 100-line native readline + ANSI escape sequences. The CLI's npx cold-start budget can't afford an inquirer / prompts dep (30+ extra module resolutions on first run). Hides cursor while painting, restores it on exit including on Ctrl-C, returns null in non-TTY so callers handle the fallback path.
Docs
docs/reference/cli.md— full monorepo behaviour, detection priority, Next two-file mutator described,--cwddocumented.docs/get-started/install.md— monorepo section +--cwdexample.README.md— monorepo note in the install section +--nextflag in the force-bundler list + "Next 15 + 16" support clearly called out.packages/cli/README.md— monorepo +--next.
Verified
pnpm typecheckclean across all 9 publishable packages + 11 examplespnpm test— 177 vitest tests across core / widget-bootstrap / vite-plugin- Playwright e2e (
basic-app/__vibe_tests__/login-and-counter.spec.ts) passes - Manual CJS resolution test: a
.cjsfile callingrequire('@hover-dev/next')from outside the monorepo succeeds andwithHover()runs synchronously
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.3.
Full Changelog: v0.7.2...v0.7.3