Skip to content

feat(devtools)!: finish Messages + terminals convergence on Devframe 0.7.7 - #1032

Merged
antfu merged 1 commit into
nuxt:mainfrom
antfubot:wet-snails-roll
Jul 22, 2026
Merged

feat(devtools)!: finish Messages + terminals convergence on Devframe 0.7.7#1032
antfu merged 1 commit into
nuxt:mainfrom
antfubot:wet-snails-roll

Conversation

@antfubot

Copy link
Copy Markdown
Collaborator

Why

Implements plans/vite-devtools-integration/02-platform-services-cleanup.md and moves the platform-service integration onto Devframe 0.7.7. It finishes two partially-landed migrations: client notifications now flow through the stable Messages hub boundary, and all terminal output surfaces in Vite DevTools' built-in Terminals dock rather than a bespoke transport.

What

  • Devframe 0.7.7: bump devframe / @devframes/hub (workspace overrides + lockfile).
  • Messages: the client notifier targeted the removed Devframe 0.6 devframes-plugin-messages:add, so client toasts failed best-effort. It now calls the stable hub:messages:add, keeping notify/level defaults and numeric toast lifetimes.
  • Unique session ids: repeating analyze-build, install, uninstall, or a package update reused a fixed id and collided with retained Devframe sessions. Each run now gets a unique, readable id, threaded through the two-phase module flow.
  • Terminals bridge: the devtools:terminal:* hooks are projected onto ctx.terminals as output + final-status only. Pre-ready registrations, output, and exit are buffered and replayed (a process exiting before connect no longer stays stuck running); re-registration mints a fresh session; superseded runs are dropped.
  • Decoupled UI cleanup: analyze-build and module-install UI state derive from awaited RPCs / refreshed info instead of broad onTerminalExit broadcasts, which are now the minimal completion signal for generic package updates only.
  • Deprecations: the ignored TerminalState restart/terminate fields are marked deprecated (removal in v5) and the migration guide documents the output-only bridge.

Devframe 0.7.7 also exposes a public terminals.remove(), so the previous private-method shim is gone.

Verification

typecheck, lint, test:unit (incl. new coverage for the message transport, unique-id generation, and bridge buffering/re-registration/status mapping), a full build, and test:e2e:dev all pass.

This PR was created with the help of an agent.

…0.7.7

- bump devframe/@devframes/hub to 0.7.7
- route client notifications through the stable hub:messages:add boundary
- give each Nuxt-owned process run (analyze-build, install/uninstall,
  package update) a unique terminal-session id to avoid duplicate-id errors
- rewrite the devtools:terminal:* bridge as an output+status-only projection
  onto the built-in Terminals dock, with pre-ready buffering and per-run
  generations
- derive analyze-build/module-install UI state from awaited RPCs and refreshed
  info instead of broad onTerminalExit broadcasts
- deprecate the ignored TerminalState action fields (v5 removal)
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The change introduces unique terminal session IDs, generation-aware bridging for legacy terminal hooks, and buffered output/status replay across DevTools readiness. Analyze-build and npm RPC flows now expose or accept session IDs and use refreshed state instead of terminal-exit broadcasts for selected UI updates. Module actions guarantee cleanup, notification payload construction is centralized, terminal capability APIs are documented as deprecated, migration guidance is added, and related tests and dependency pins are updated.

Estimated code review effort: 4 (Complex) | ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.10% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: completing Messages and terminals convergence on Devframe 0.7.7.
Description check ✅ Passed The description matches the changeset and accurately describes the messaging, terminal, and session-id updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/devtools/test/notify.test.ts (1)

4-29: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Exercise the changed notify() entry point.

These tests validate buildMessageEntry() but never invoke notify() from packages/devtools/client/composables/notify.ts, Lines 13-16. Add a mocked RPC test asserting the hub:messages:add target and generated payload.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/devtools/test/notify.test.ts` around lines 4 - 29, Extend the client
notify transport tests to invoke notify() from the notify composable rather than
only testing buildMessageEntry(). Mock the RPC transport and assert that
notify() targets MESSAGES_ADD_RPC ('hub:messages:add') with the generated
message payload, while preserving the existing entry-construction tests.
packages/devtools/client/composables/notify.ts (1)

16-16: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Avoid bypassing the RPC contract with as any.

The cast can hide an incorrect RPC name or payload shape. Add hub:messages:add to the RPC method typing if needed, then call it without the cast.

Suggested direction
-    await client.call(MESSAGES_ADD_RPC as any, buildMessageEntry(input))
+    await client.call(MESSAGES_ADD_RPC, buildMessageEntry(input))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/devtools/client/composables/notify.ts` at line 16, Update the RPC
typing used by the notify flow to include the hub:messages:add method and its
expected payload, then change the call in the notification function to use
MESSAGES_ADD_RPC without an any cast. Preserve the existing
buildMessageEntry(input) payload behavior while allowing the typed RPC contract
to validate both method name and arguments.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/devtools/src/server-rpc/analyze-build.ts`:
- Around line 32-45: Update the session-start flow around startChildProcess to
reserve the build slot before awaiting terminal creation, and make the existing
request guard reject when either promise or activeSessionId is set. Wrap
terminal creation in catch handling that clears or refreshes activeSessionId
before rethrowing, while preserving the successful session assignment and build
lifecycle behavior.

---

Nitpick comments:
In `@packages/devtools/client/composables/notify.ts`:
- Line 16: Update the RPC typing used by the notify flow to include the
hub:messages:add method and its expected payload, then change the call in the
notification function to use MESSAGES_ADD_RPC without an any cast. Preserve the
existing buildMessageEntry(input) payload behavior while allowing the typed RPC
contract to validate both method name and arguments.

In `@packages/devtools/test/notify.test.ts`:
- Around line 4-29: Extend the client notify transport tests to invoke notify()
from the notify composable rather than only testing buildMessageEntry(). Mock
the RPC transport and assert that notify() targets MESSAGES_ADD_RPC
('hub:messages:add') with the generated message payload, while preserving the
existing entry-construction tests.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 01a39ed7-7987-4e27-ae83-5bcfefacf5f8

📥 Commits

Reviewing files that changed from the base of the PR and between 6b9bff9 and c0d7b09.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (20)
  • docs/content/2.module/3.migration-v4.md
  • packages/devtools-kit/src/_types/analyze-build.ts
  • packages/devtools-kit/src/_types/rpc.ts
  • packages/devtools-kit/src/_types/terminals.ts
  • packages/devtools/client/components/ModuleItemInstall.vue
  • packages/devtools/client/composables/notify.ts
  • packages/devtools/client/composables/npm.ts
  • packages/devtools/client/composables/state-subprocess.ts
  • packages/devtools/client/pages/modules/analyze-build.vue
  • packages/devtools/client/setup/client-rpc.ts
  • packages/devtools/src/notify-transport.ts
  • packages/devtools/src/server-rpc/analyze-build.ts
  • packages/devtools/src/server-rpc/npm.ts
  • packages/devtools/src/server-rpc/terminals.ts
  • packages/devtools/src/types/ui-state.ts
  • packages/devtools/src/utils/session-id.ts
  • packages/devtools/test/notify.test.ts
  • packages/devtools/test/session-id.test.ts
  • packages/devtools/test/terminals-bridge.test.ts
  • pnpm-workspace.yaml
💤 Files with no reviewable changes (1)
  • packages/devtools/src/types/ui-state.ts

Comment on lines +32 to 45
// A fresh id per run — completed sessions linger in the dock, so a fixed id
// would collide (`DF8200`) on the next build.
const sessionId = createUniqueSessionId('devtools:analyze-build')
activeSessionId = sessionId

const session = await kit.terminals.startChildProcess({
command: 'npx',
args: ['nuxi', 'analyze', '--no-serve', '--name', name],
cwd: nuxt.options.rootDir,
}, {
id: processId,
id: sessionId,
title: 'Analyze Build',
icon: 'logos-nuxt-icon',
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Close the start-up race and clear failed session state.

promise is not assigned until after startChildProcess() resolves. Two requests can both pass Line 25, launch separate builds, and overwrite activeSessionId; a startup rejection also leaves that ID set while isBuilding is false. Reserve the slot before the await (for example, guard on promise || activeSessionId) and clear/refresh activeSessionId in a catch around terminal creation before rethrowing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/devtools/src/server-rpc/analyze-build.ts` around lines 32 - 45,
Update the session-start flow around startChildProcess to reserve the build slot
before awaiting terminal creation, and make the existing request guard reject
when either promise or activeSessionId is set. Wrap terminal creation in catch
handling that clears or refreshes activeSessionId before rethrowing, while
preserving the successful session assignment and build lifecycle behavior.

@antfu
antfu merged commit c081250 into nuxt:main Jul 22, 2026
5 of 6 checks passed
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.

2 participants