diff --git a/docs/content/2.module/1.utils-kit.md b/docs/content/2.module/1.utils-kit.md index 5b429b646f..c56d724e05 100644 --- a/docs/content/2.module/1.utils-kit.md +++ b/docs/content/2.module/1.utils-kit.md @@ -73,39 +73,60 @@ dock entries directly via the handle returned by A shorthand for call hook `devtools:customTabs:refresh`. It will refresh all custom tabs. +### Spawning terminals + +**Use Vite DevTools' own terminals host** (`ctx.terminals`), reached through the +connected context from [`onDevtoolsReady()`](#ondevtoolsready). It spawns and +owns the process and surfaces it in the built-in **Terminals** dock — no +Nuxt-specific wrapper needed: + +```ts +import { onDevtoolsReady } from '@nuxt/devtools-kit' + +onDevtoolsReady((ctx) => { + // Output-only child process + ctx.terminals.startChildProcess( + { command: 'npm', args: ['run', 'dev'] }, + { id: 'my-module:dev', title: 'Dev Server', icon: 'logos-npm-icon' }, + ) + + // Fully interactive PTY (powered by `zigpty`, with a graceful pipe fallback) + ctx.terminals.startPtySession( + { command: 'bash' }, + { id: 'my-module:shell', title: 'Shell', interactive: true }, + ) +}) +``` + +If your module needs to keep owning the process itself and merely stream output, +register a read-only session with `ctx.terminals.register({ id, title, status, stream })`. +See the [Vite DevTools Kit](https://github.com/vitejs/devtools) docs for the full +`ctx.terminals` API. + ### `startSubprocess()` ::warning -**Deprecated.** `startSubprocess()` is soft-deprecated (`NDT_DEP_0004`) in favour -of the Vite DevTools terminals host -(`nuxt.devtools.terminals.startChildProcess(...)`). It still works as a shim. See -the [migration guide](/module/migration-v4#ndt_dep_0004). +**Deprecated — do not use in new code.** `startSubprocess()` is soft-deprecated +(`NDT_DEP_0004`) in favour of the Vite DevTools terminals host, used from the +[`onDevtoolsReady`](#ondevtoolsready) hook +(`onDevtoolsReady((ctx) => ctx.terminals.startChildProcess(...))` — see +[Spawning terminals](#spawning-terminals) above). It still works as a shim +(bridged onto `ctx.terminals`), so existing modules keep working, but it emits +the `NDT_DEP_0004` deprecation diagnostic and will be removed in a future major. +See the [migration guide](/module/migration-v4#ndt_dep_0004). :: -Start a sub process using `tinyexec` and create a terminal tab in DevTools. +Legacy usage (module owns the process; output is surfaced as a read-only session +in the built-in **Terminals** dock): ```ts import { startSubprocess } from '@nuxt/devtools-kit' const subprocess = startSubprocess( - { - command: 'code-server', - args: [ - 'serve-local', - '--accept-server-license-terms', - '--without-connection-token', - `--port=${port}`, - ], - }, - { - id: 'devtools:vscode', - name: 'VS Code Server', - icon: 'logos-visual-studio-code', - }, + { command: 'vite', args: ['build', '--watch'] }, + { id: 'my-module:build', name: 'Build', icon: 'ph:terminal-duotone' }, ) -``` -```ts subprocess.restart() subprocess.terminate() ``` diff --git a/packages/devtools-kit/src/_types/hooks.ts b/packages/devtools-kit/src/_types/hooks.ts index e562875067..f658046c5b 100644 --- a/packages/devtools-kit/src/_types/hooks.ts +++ b/packages/devtools-kit/src/_types/hooks.ts @@ -53,7 +53,11 @@ declare module '@nuxt/schema' { 'devtools:customTabs:refresh': () => void /** - * Register a terminal. + * Register a terminal whose process is owned by the caller (module). + * + * The registered session is surfaced **read-only** in the built-in Vite + * DevTools **Terminals** dock; stream output into it via + * `devtools:terminal:write`. */ 'devtools:terminal:register': (terminal: TerminalState) => void @@ -78,16 +82,4 @@ declare module '@nuxt/schema' { } } -declare module '@nuxt/schema' { - /** - * Runtime Hooks - */ - interface RuntimeNuxtHooks { - /** - * On terminal data. - */ - 'devtools:terminal:data': (payload: { id: string, data: string }) => void - } -} - export {} diff --git a/packages/devtools-kit/src/_types/rpc.ts b/packages/devtools-kit/src/_types/rpc.ts index c5fafd8971..bf640669c6 100644 --- a/packages/devtools-kit/src/_types/rpc.ts +++ b/packages/devtools-kit/src/_types/rpc.ts @@ -8,7 +8,6 @@ import type { AssetEntry, AssetInfo, AutoImportsWithMetadata, ComponentRelations import type { NuxtDevtoolsNotifyInput } from './notify' import type { ModuleOptions, NuxtDevToolsOptions } from './options' import type { InstallModuleReturn, ServerDebugContext } from './server-ctx' -import type { TerminalAction, TerminalInfo } from './terminals' export interface ServerFunctions { // Static RPCs (can be provide on production build in the future) @@ -40,9 +39,7 @@ export interface ServerFunctions { runNpmCommand: (command: NpmCommandType, packageName: string, options?: NpmCommandOptions) => Promise<{ processId: string } | undefined> // Terminal - getTerminals: () => TerminalInfo[] - getTerminalDetail: (id: string) => Promise - runTerminalAction: (id: string, action: TerminalAction) => Promise + revealTerminal: (id: string) => Promise // Storage getStorageMounts: () => Promise @@ -87,7 +84,11 @@ export interface ClientFunctions { callHook: (hook: string, ...args: any[]) => Promise navigateTo: (path: string) => void - onTerminalData: (_: { id: string, data: string }) => void + /** + * Server→client signal that a terminal session has exited. Kept so the + * client can clear transient subprocess UI state (installing-modules / + * analyze-build / npm updates) when the underlying process finishes. + */ onTerminalExit: (_: { id: string, code?: number }) => void } diff --git a/packages/devtools/client/components/ModuleItem.vue b/packages/devtools/client/components/ModuleItem.vue index fdfe0b43bf..6e9aa3b1b3 100644 --- a/packages/devtools/client/components/ModuleItem.vue +++ b/packages/devtools/client/components/ModuleItem.vue @@ -1,7 +1,7 @@