Skip to content

feat(core): add passive mode for the injected overlay#465

Open
antfubot wants to merge 4 commits into
mainfrom
busy-cooks-switch
Open

feat(core): add passive mode for the injected overlay#465
antfubot wants to merge 4 commits into
mainfrom
busy-cooks-switch

Conversation

@antfubot

@antfubot antfubot commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Description

Introduces a passive mode for the embedded (injected) DevTools overlay, modeled on Nuxt DevTools' opt-in reveal.

What changed

  • Two client entries, node picks one. The DevTools() plugin resolves the project's visibility per HTML request and injects one of:
    • @vitejs/devtools/client/injectnormal: mounts the floating docks immediately.
    • @vitejs/devtools/client/inject-passivepassive (default): keeps the docks hidden and prints a styled console hint to reveal them with Shift+Alt+D (⇧ ⌥ D on macOS).
  • Activation persists per project. Pressing the shortcut mounts the docks and writes a marker file to the project's node_modules/.vite-devtools/mode.json. Since the entry is chosen node-side per request, the next full load injects the normal entry directly. The flag lives under node_modules (not Vite's cacheDir) so vite --force doesn't reset it.
  • In-page transitions, no reload. A shared runtime (inject/runtime.ts) backs both entries, so activating (shortcut) and the "Hide DevTools (Passive Mode)" palette command switch modes in-page without a reload.
  • Persistence channel. POST /__devtools/__mode.json { enabled } writes/clears the flag (served unauthenticated — it only toggles the local overlay and writes a marker; the docks still require WS trust for project data).
  • Opt out. DevTools({ visibility: 'normal' }) always injects the normal entry (visibility: 'passive' | 'normal', default 'passive').
  • Adds diagnostic DTK0033 (mode-persist failure) with docs, a node-side unit test, and updates the Getting Started + Client Context guides.

Verification

  • pnpm typecheck, pnpm test (338 pass), pnpm build, pnpm lint all green.
  • End-to-end against the core playground dev server: by default node injects inject-passive; POST {enabled:true} writes the flag and the next HTML load injects inject (normal); POST {enabled:false} reverts. Injection chain (HTML → html-proxy → virtual module → entry) confirmed for both entries. In-browser DOM behavior wasn't exercised (no browser available in the sandbox).

Linked Issues

Additional context

Reviewers may want to focus on the node-side entry selection in packages/core/src/node/plugins/injection.ts (decision made in transformIndexHtml, re-evaluated per request so no cache invalidation is needed) and the unauthenticated persistence endpoint in packages/core/src/node/server.ts.

This PR was created with the help of an agent.

antfubot added 2 commits July 23, 2026 08:12
The embedded DevTools client now starts in passive mode by default: the
floating docks stay hidden and the console prints a hint to reveal them
with Shift+Alt+D. Activating persists a per-project flag in node_modules,
so later dev sessions on the machine boot straight into normal mode. A
"Hide DevTools" command returns to passive mode; `passive: false` opts out.
Replace the boolean `passive` DevTools option with a clearer
`visibility: 'passive' | 'normal'` enum, defaulting to `'passive'`.
@pkg-pr-new

pkg-pr-new Bot commented Jul 23, 2026

Copy link
Copy Markdown

Open in StackBlitz

@vitejs/devtools

npm i https://pkg.pr.new/@vitejs/devtools@465

@vitejs/devtools-kit

npm i https://pkg.pr.new/@vitejs/devtools-kit@465

@vitejs/devtools-oxc

npm i https://pkg.pr.new/@vitejs/devtools-oxc@465

@vitejs/devtools-rolldown

npm i https://pkg.pr.new/@vitejs/devtools-rolldown@465

@vitejs/devtools-vite

npm i https://pkg.pr.new/@vitejs/devtools-vite@465

@vitejs/devtools-vitest

npm i https://pkg.pr.new/@vitejs/devtools-vitest@465

commit: b07f7c7

antfubot added 2 commits July 23, 2026 08:39
# Conflicts:
#	packages/core/src/client/webcomponents/state/context.ts
Move the passive-vs-normal decision to the node side: the injection
plugin now picks which client entry to inject per HTML request from the
project's resolved visibility (and the persisted flag), instead of one
client that fetches its mode at runtime.

- `@vitejs/devtools/client/inject` — normal, mounts the docks immediately
- `@vitejs/devtools/client/inject-passive` — passive, hint + shortcut
- shared runtime handles in-page activate / hide transitions (no reload)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant