Skip to content

Interface: TerminalService ​

Defined in: packages/sdk/src/terminal-service.ts:144

Consumer API for the terminal domain, exposed as ExtensionContext.terminals. The terminal is a core feature — a built-in DockKind like the editor — so this mirrors EditorService: create opens a terminal tab in a workspace, and closeWorkspace reaps a workspace's terminals. WorkspaceService.delete calls closeWorkspace for you; the primitive remains available for surgical reaping without deleting the workspace. The tab itself is rendered by the core dock from the workspace's terminal records.

Tab chrome adornments (setIcon / setIndicator / …) take a terminal session id as the target — see TabAdornmentMethods.

Extends ​

Methods ​

setIcon() ​

ts
setIcon(targetId, adornment): void;

Defined in: packages/sdk/src/tab-adornment.ts:229

Parameters ​

targetId ​

string

adornment ​

TabIconAdornment

Returns ​

void

Inherited from ​

TabAdornmentMethods.setIcon


clearIcon() ​

ts
clearIcon(targetId, adornmentId): void;

Defined in: packages/sdk/src/tab-adornment.ts:230

Parameters ​

targetId ​

string

adornmentId ​

string

Returns ​

void

Inherited from ​

TabAdornmentMethods.clearIcon


bindIcon() ​

ts
bindIcon(binder): Disposable;

Defined in: packages/sdk/src/tab-adornment.ts:231

Parameters ​

binder ​

TabIconBinder

Returns ​

Disposable

Inherited from ​

TabAdornmentMethods.bindIcon


setHighlight() ​

ts
setHighlight(targetId, adornment): void;

Defined in: packages/sdk/src/tab-adornment.ts:233

Parameters ​

targetId ​

string

adornment ​

TabHighlightAdornment

Returns ​

void

Inherited from ​

TabAdornmentMethods.setHighlight


clearHighlight() ​

ts
clearHighlight(targetId, adornmentId): void;

Defined in: packages/sdk/src/tab-adornment.ts:234

Parameters ​

targetId ​

string

adornmentId ​

string

Returns ​

void

Inherited from ​

TabAdornmentMethods.clearHighlight


bindHighlight() ​

ts
bindHighlight(binder): Disposable;

Defined in: packages/sdk/src/tab-adornment.ts:235

Parameters ​

binder ​

TabHighlightBinder

Returns ​

Disposable

Inherited from ​

TabAdornmentMethods.bindHighlight


setIndicator() ​

ts
setIndicator(targetId, adornment): void;

Defined in: packages/sdk/src/tab-adornment.ts:237

Parameters ​

targetId ​

string

adornment ​

TabIndicatorAdornment

Returns ​

void

Inherited from ​

TabAdornmentMethods.setIndicator


clearIndicator() ​

ts
clearIndicator(targetId, adornmentId): void;

Defined in: packages/sdk/src/tab-adornment.ts:238

Parameters ​

targetId ​

string

adornmentId ​

string

Returns ​

void

Inherited from ​

TabAdornmentMethods.clearIndicator


flashIndicator() ​

ts
flashIndicator(targetId, flash): void;

Defined in: packages/sdk/src/tab-adornment.ts:239

Parameters ​

targetId ​

string

flash ​

TabIndicatorFlash

Returns ​

void

Inherited from ​

TabAdornmentMethods.flashIndicator


bindIndicator() ​

ts
bindIndicator(binder): Disposable;

Defined in: packages/sdk/src/tab-adornment.ts:240

Parameters ​

binder ​

TabIndicatorBinder

Returns ​

Disposable

Inherited from ​

TabAdornmentMethods.bindIndicator


setActivity() ​

ts
setActivity(targetId, adornment): void;

Defined in: packages/sdk/src/tab-adornment.ts:242

Parameters ​

targetId ​

string

adornment ​

TabActivityAdornment

Returns ​

void

Inherited from ​

TabAdornmentMethods.setActivity


clearActivity() ​

ts
clearActivity(targetId, adornmentId): void;

Defined in: packages/sdk/src/tab-adornment.ts:243

Parameters ​

targetId ​

string

adornmentId ​

string

Returns ​

void

Inherited from ​

TabAdornmentMethods.clearActivity


flashActivity() ​

ts
flashActivity(targetId, flash): void;

Defined in: packages/sdk/src/tab-adornment.ts:244

Parameters ​

targetId ​

string

flash ​

TabActivityFlash

Returns ​

void

Inherited from ​

TabAdornmentMethods.flashActivity


bindActivity() ​

ts
bindActivity(binder): Disposable;

Defined in: packages/sdk/src/tab-adornment.ts:245

Parameters ​

binder ​

TabActivityBinder

Returns ​

Disposable

Inherited from ​

TabAdornmentMethods.bindActivity


getIcons() ​

ts
getIcons(targetId): TabIconAdornment[];

Defined in: packages/sdk/src/tab-adornment.ts:248

All leading icons for targetId, in set/bind order.

Parameters ​

targetId ​

string

Returns ​

TabIconAdornment[]

Inherited from ​

TabAdornmentMethods.getIcons


getHighlight() ​

ts
getHighlight(targetId): TabHighlightAdornment | null;

Defined in: packages/sdk/src/tab-adornment.ts:253

The whole-tab highlight for targetId, or null if none. At most one applies — first found across set/bind order.

Parameters ​

targetId ​

string

Returns ​

TabHighlightAdornment | null

Inherited from ​

TabAdornmentMethods.getHighlight


getIndicators() ​

ts
getIndicators(targetId): TabIndicatorAdornment[];

Defined in: packages/sdk/src/tab-adornment.ts:255

All trailing indicators for targetId, in set/bind/flash order.

Parameters ​

targetId ​

string

Returns ​

TabIndicatorAdornment[]

Inherited from ​

TabAdornmentMethods.getIndicators


getActivities() ​

ts
getActivities(targetId): TabActivityAdornment[];

Defined in: packages/sdk/src/tab-adornment.ts:257

All trailing activities for targetId, in set/bind/flash order.

Parameters ​

targetId ​

string

Returns ​

TabActivityAdornment[]

Inherited from ​

TabAdornmentMethods.getActivities


invalidateTabAdornments() ​

ts
invalidateTabAdornments(): void;

Defined in: packages/sdk/src/tab-adornment.ts:259

Signal that binder data changed — re-query provide and re-render.

Returns ​

void

Inherited from ​

TabAdornmentMethods.invalidateTabAdornments


subscribeTabAdornments() ​

ts
subscribeTabAdornments(listener): Disposable;

Defined in: packages/sdk/src/tab-adornment.ts:260

Parameters ​

listener ​

() => void

Returns ​

Disposable

Inherited from ​

TabAdornmentMethods.subscribeTabAdornments


create() ​

ts
create(input?): TerminalRecord | undefined;

Defined in: packages/sdk/src/terminal-service.ts:154

Open a new terminal in a workspace (defaults to the active one). Returns the created TerminalRecord; the PTY session spawns lazily when its tab mounts.

Returns undefined only when input.workspaceId is not given and there is no active workspace at the time of the call — in normal use this does not happen because activating any workspace happens before extensions run.

Parameters ​

input? ​

CreateTerminalInput

Returns ​

TerminalRecord | undefined


closeWorkspace() ​

ts
closeWorkspace(workspaceId): void;

Defined in: packages/sdk/src/terminal-service.ts:160

Close and kill every terminal in a workspace. WorkspaceService.delete reaps terminals the same way automatically, so this is for reaping a workspace's terminals surgically, without deleting the workspace itself.

Parameters ​

workspaceId ​

string

Returns ​

void


sendText() ​

ts
sendText(
   terminalId, 
   text, 
   addNewline?): void;

Defined in: packages/sdk/src/terminal-service.ts:181

Write text to a terminal's PTY as if the user typed it. By default a carriage return is appended so the line executes; pass addNewline: false to stage text without running it.

Works even if the terminal tab has never been shown: the PTY spawns lazily on first mount, and sendText force-spawns it on demand (a later mount then attaches to that same session). No-op for an unknown terminalId.

Parameters ​

terminalId ​

string

The TerminalRecord.id to write to.

text ​

string

The text to send.

addNewline? ​

boolean

Append a carriage return to execute. Defaults to true.

Returns ​

void

Example ​

ts
const term = ctx.terminals.create({ cwd: workspaceFolder });
if (term) ctx.terminals.sendText(term.id, "npm run build");

close() ​

ts
close(terminalId): void;

Defined in: packages/sdk/src/terminal-service.ts:188

Close one terminal tab and kill its PTY session. No-op if the id is unknown. To reap every terminal in a workspace at once use TerminalService.closeWorkspace.

Parameters ​

terminalId ​

string

Returns ​

void


rename() ​

ts
rename(terminalId, name): void;

Defined in: packages/sdk/src/terminal-service.ts:196

Set a terminal's user-facing name (TerminalRecord.customName), shown on its tab and persisted across restarts. Passing an empty string clears the custom name, letting the PTY-derived title take over again. No-op for an unknown terminalId.

Parameters ​

terminalId ​

string

name ​

string

Returns ​

void


getTabMenuItems() ​

ts
getTabMenuItems(terminalId): MenuEntry[];

Defined in: packages/sdk/src/terminal-service.ts:224

The rows of this terminal's tab context menu — Rename…, then whatever extensions contributed on the "terminal/tab"surface.

Use it when your own UI lists terminals (an agent list, a session picker) so right-clicking a row offers the same actions as right-clicking the tab, contributions included, instead of a menu that drifts from it. Returns an empty array for a terminal no workspace owns.

Parameters ​

terminalId ​

string

Returns ​

MenuEntry[]

Example ​

ts
ctx.ui.showMenu({
  items: [
    { label: "Mark as seen", run: () => ctx.agents.acknowledge(id) },
    { type: "separator" },
    ...ctx.terminals.getTabMenuItems(id),
  ],
  at: { x: e.clientX, y: e.clientY },
});

focus() ​

ts
focus(terminalId): void;

Defined in: packages/sdk/src/terminal-service.ts:226

Parameters ​

terminalId ​

string

Returns ​

void


registerTabDecoration() ​

ts
registerTabDecoration(provider): Disposable;

Defined in: packages/sdk/src/terminal-service.ts:232

Parameters ​

provider ​

TerminalTabDecorationProvider

Returns ​

Disposable

Deprecated ​

Prefer TerminalService.bindIndicator. Thin shim that registers a trailing-indicator binder for terminal tabs only.


getTabDecoration() ​

ts
getTabDecoration(terminalId): 
  | TabIndicatorContribution
  | null;

Defined in: packages/sdk/src/terminal-service.ts:238

Parameters ​

terminalId ​

string

Returns ​

| TabIndicatorContribution | null

Deprecated ​

Prefer TerminalService.getIndicators. Returns the first trailing indicator for a terminal tab, or null.


invalidateTabDecorations() ​

ts
invalidateTabDecorations(): void;

Defined in: packages/sdk/src/terminal-service.ts:243

Returns ​

void

Deprecated ​

Prefer TerminalService.invalidateTabAdornments.


subscribeTabDecorations() ​

ts
subscribeTabDecorations(listener): Disposable;

Defined in: packages/sdk/src/terminal-service.ts:248

Parameters ​

listener ​

() => void

Returns ​

Disposable

Deprecated ​

Prefer TerminalService.subscribeTabAdornments.


subscribeOsc() ​

ts
subscribeOsc(
   terminalId, 
   handler, 
   options?): Disposable;

Defined in: packages/sdk/src/terminal-service.ts:293

Subscribe to raw OSC (Operating System Command) escape sequences emitted by the terminal identified by terminalId. The handler is called once per parsed sequence — regardless of whether the terminal's panel is currently visible — making it suitable for background status monitoring.

The subscription is keyed to the terminal record id (e.g. "term_…"), not the underlying PTY session id, so it survives terminal recreation within the same record.

Returns a Disposable that cancels the subscription.

Parameters ​

terminalId ​

string

handler ​

(event, origin) => void

options? ​

SubscribeOutputOptions

Returns ​

Disposable

Example ​

ts
// Detect Claude Code busy/idle state from OSC 0 title sequences: it
// prefixes the title with an animated spinner glyph while busy, and with
// the idle char below when awaiting input. Accept both spinner ranges —
// current builds animate the half-filled circles ◐/◑, older ones used
// braille (which Codex CLI still does).
const SPINNERS = [
  [0x25d0, 0x25d3], // ◐ ◑ ◒ ◓
  [0x2800, 0x28ff], // ⠋ ⠙ ⠏ …
];
const IDLE_CHAR     = '\u2733'; // ✳

const sub = ctx.terminals.subscribeOsc(terminalId, ({ code, payload }) => {
  if (code !== 0) return;
  const first = payload.charCodeAt(0);
  const spinning = SPINNERS.some(([lo, hi]) => first >= lo && first <= hi);
  if (spinning)                           setStatus('busy');
  else if (payload.startsWith(IDLE_CHAR)) setStatus('idle');
});
ctx.subscriptions.push(sub);

Remarks ​

OSC sequences ride the raw output stream, so the same replay rule applies as for TerminalService.subscribeOutput: by default only sequences from live output are delivered, and { includeReplay: true } adds those found in the scrollback replayed on attach. Status titles are the usual reason to leave it off — a replayed "busy" title describes a turn that is already over.


subscribeOutput() ​

ts
subscribeOutput(
   terminalId, 
   handler, 
   options?): Disposable;

Defined in: packages/sdk/src/terminal-service.ts:350

Subscribe to the raw PTY output stream of the terminal identified by terminalId. The handler is called with every chunk of bytes the PTY produces — including ANSI escape sequences, OSC sequences, and all other control characters — exactly as they arrive, with no parsing or filtering.

This fires even when the terminal's panel is not visible, so it is suitable for background monitoring (e.g. detecting output activity to confirm an agent is still running). Keep handlers lightweight: they execute synchronously on every PTY chunk, which can be multiple times per second while a program is active.

The subscription is keyed to the terminal record id (e.g. "term_…"), not the underlying PTY session id, so it survives terminal recreation within the same record.

By default only live output is delivered. A terminal session outlives the app, so attaching to one replays its recent scrollback; without this default every reattach would look like a burst of activity happening right now. Pass { includeReplay: true } to receive that history too — each chunk then arrives with an OutputOrigin saying which kind it is.

Returns a Disposable that cancels the subscription.

Parameters ​

terminalId ​

string

handler ​

(data, origin) => void

options? ​

SubscribeOutputOptions

Returns ​

Disposable

Examples ​

ts
// Track the last time any output arrived to confirm agent activity.
// Replayed scrollback is excluded by default, so re-attaching to a
// long-idle terminal doesn't read as fresh activity.
let lastOutputAt = 0;
const sub = ctx.terminals.subscribeOutput(terminalId, () => {
  lastOutputAt = Date.now();
});
ctx.subscriptions.push(sub);
ts
// Opt in to the replayed scrollback — needed to work out what is running
// in a terminal you just attached to — and keep the two apart.
const sub = ctx.terminals.subscribeOutput(
  terminalId,
  (chunk, { replay }) => {
    identifyProgram(chunk);           // history is evidence
    if (!replay) noteActivity();      // …but only live output is activity
  },
  { includeReplay: true },
);
ctx.subscriptions.push(sub);

getActive() ​

ts
getActive(): string | null;

Defined in: packages/sdk/src/terminal-service.ts:363

The record id of the terminal tab that is currently active in the active workspace's center dock, or null when an editor tab (or nothing) is active. "Active" is the dock's single active panel — the tab the user is looking at and typing into — so a terminal merely visible in a non-active split does not count.

Returns ​

string | null


subscribeActive() ​

ts
subscribeActive(listener): Disposable;

Defined in: packages/sdk/src/terminal-service.ts:385

Subscribe to active-terminal changes. The listener receives the terminal record id whenever a terminal tab becomes the active center-dock panel, and null when activation moves elsewhere (an editor tab, or no panel — including transiently during a workspace switch, before the incoming workspace's active tab is published).

Fires on tab activation, group activation, and workspace switches. Returns a Disposable that cancels the subscription.

Parameters ​

listener ​

(terminalId) => void

Returns ​

Disposable

Example ​

ts
// Clear a "needs attention" marker once the user views the terminal.
ctx.subscriptions.push(
  ctx.terminals.subscribeActive((terminalId) => {
    if (terminalId) attention.delete(terminalId);
  }),
);