コンテンツにスキップ
ドキュメントAspire を試す
ドキュメント試す

Test TUI and shell apps using WithTerminal

このコンテンツはまだ日本語訳がありません。

If you have a terminal user interface (TUI) application or a shell-based experience that you want to exercise while it runs under Aspire, add WithTerminal(...) to the resource. Aspire then exposes an interactive terminal session that you can attach to from the Aspire dashboard or from the aspire terminal CLI command.

apphost.ts
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const agent = await builder.addExecutable("agent", "my-agent", ".")
.withTerminal();
await builder.build().run();

Once the app is running, open the resource’s terminal page in the dashboard—or run aspire terminal attach agent—to interact with the process just as you would in a local shell.

Reach for WithTerminal when a resource is interactive rather than a plain background service:

  • A TUI application—for example, an agent, a diagnostics console, or a curses-style tool—that draws a full-screen interface you want to see and drive.
  • A shell-based experience where you want an interactive prompt inside a container or executable while it runs as part of your app model.
  • Any resource you want to poke at live during development without leaving the Aspire dashboard or CLI.

The debugger is not attached automatically

Section titled “The debugger is not attached automatically”

When you apply WithTerminal, Aspire runs the resource as a plain process and does not automatically attach the debugger. If you need to debug the resource, attach the debugger manually to the running process from your IDE.

Terminal sessions support multiple simultaneous viewers. You can open two browser tabs pointing at the same terminal—or a browser tab and the CLI together—and both stay responsive: input and output are mirrored to every attached peer.

One peer holds the primary role and drives the terminal’s dimensions, while the others attach as viewers. From the CLI you can join as a passive viewer with aspire terminal attach <resource> --viewer, and take control later with the Ctrl+B T hotkey.

The terminal session is described by a set of options with sensible defaults:

OptionDefaultDescription
Columns120The initial number of columns for the terminal grid.
Rows30The initial number of rows for the terminal grid.
ShowTerminalHostfalseWhether the hidden per-replica terminal host resources appear in the dashboard and CLI resource lists. Set to true to diagnose terminal-host startup or connectivity issues.
apphost.ts
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const agent = await builder.addExecutable("agent", "my-agent", ".")
.withTerminal();
await builder.build().run();

Each replica of a resource gets its own independent terminal session. Aspire creates one terminal host per parent replica, so requesting three replicas yields three separate terminals. The order of WithReplicas and WithTerminal does not matter—the final replica count is always honored:

apphost.ts
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const agent = await builder.addExecutable("agent", "my-agent", ".")
.withReplicas(3)
.withTerminal();
await builder.build().run();

When a resource has more than one replica, choose which one to attach to with aspire terminal attach <resource> --replica <index> (indices are 0-based), or pick interactively when prompted.

When a resource has WithTerminal applied, its Console Logs page in the Aspire dashboard gains a live terminal session alongside the usual console log stream. You can drive the running process directly in the browser without leaving the dashboard. For example, you can type commands, scroll the scrollback buffer, and switch between replicas. Each replica appears as its own entry (for example, agent-r0, agent-r1, agent-r2) with an independent session.

The page picks a default view based on the resource’s state at the moment you navigate to it:

  • Running (the PTY is live) → the page defaults to the Terminal view, so the interactive session is the first thing you see.
  • Waiting/Starting or already Exited/Finished/FailedToStart → the page defaults to the Console logs view, so hosting messages—such as “Waiting for resource X to become healthy…” or a startup failure—and post-exit output remain visible immediately.

Open the toolbar’s options (⋯) menu and choose Terminal or Console logs to switch views manually at any time. Both views stay live while you’re on the page: switching between them never tears down the terminal session or loses console log scrollback, and a later state transition (for example, WaitingRunning) doesn’t auto-switch the view once you’ve navigated to the page. Selecting a different resource re-evaluates the default for that resource.

In the Aspire VS Code extension, any resource configured with WithTerminal() gains an Open terminal entry in its right-click context menu. Selecting Open terminal runs aspire terminal attach <resource> and opens the session as an editor-style terminal tab directly in VS Code—no separate shell window needed.

For multi-replica resources, the extension automatically passes --replica <index> so the correct instance is attached. The --apphost flag is included when the current AppHost connection information is available, so the command connects without requiring you to specify the AppHost separately.

The aspire terminal command group lets you list and attach to terminal sessions from your shell. Because WithTerminal is experimental, these commands are hidden behind a feature flag. Enable them with:

Enable the aspire terminal commands
aspire config set features.terminalCommandsEnabled true

Then:

  • aspire terminal ps lists every terminal-enabled resource in the running AppHost, with grid size, attached-peer count, and per-replica health.
  • aspire terminal attach attaches your local terminal to a resource’s interactive PTY session.