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()
setIcon(targetId, adornment): void;Defined in: packages/sdk/src/tab-adornment.ts:229
Parameters
targetId
string
adornment
Returns
void
Inherited from
clearIcon()
clearIcon(targetId, adornmentId): void;Defined in: packages/sdk/src/tab-adornment.ts:230
Parameters
targetId
string
adornmentId
string
Returns
void
Inherited from
bindIcon()
bindIcon(binder): Disposable;Defined in: packages/sdk/src/tab-adornment.ts:231
Parameters
binder
Returns
Inherited from
setHighlight()
setHighlight(targetId, adornment): void;Defined in: packages/sdk/src/tab-adornment.ts:233
Parameters
targetId
string
adornment
Returns
void
Inherited from
TabAdornmentMethods.setHighlight
clearHighlight()
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()
bindHighlight(binder): Disposable;Defined in: packages/sdk/src/tab-adornment.ts:235
Parameters
binder
Returns
Inherited from
TabAdornmentMethods.bindHighlight
setIndicator()
setIndicator(targetId, adornment): void;Defined in: packages/sdk/src/tab-adornment.ts:237
Parameters
targetId
string
adornment
Returns
void
Inherited from
TabAdornmentMethods.setIndicator
clearIndicator()
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()
flashIndicator(targetId, flash): void;Defined in: packages/sdk/src/tab-adornment.ts:239
Parameters
targetId
string
flash
Returns
void
Inherited from
TabAdornmentMethods.flashIndicator
bindIndicator()
bindIndicator(binder): Disposable;Defined in: packages/sdk/src/tab-adornment.ts:240
Parameters
binder
Returns
Inherited from
TabAdornmentMethods.bindIndicator
setActivity()
setActivity(targetId, adornment): void;Defined in: packages/sdk/src/tab-adornment.ts:242
Parameters
targetId
string
adornment
Returns
void
Inherited from
TabAdornmentMethods.setActivity
clearActivity()
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()
flashActivity(targetId, flash): void;Defined in: packages/sdk/src/tab-adornment.ts:244
Parameters
targetId
string
flash
Returns
void
Inherited from
TabAdornmentMethods.flashActivity
bindActivity()
bindActivity(binder): Disposable;Defined in: packages/sdk/src/tab-adornment.ts:245
Parameters
binder
Returns
Inherited from
TabAdornmentMethods.bindActivity
getIcons()
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
Inherited from
getHighlight()
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()
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
Inherited from
TabAdornmentMethods.getIndicators
getActivities()
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
Inherited from
TabAdornmentMethods.getActivities
invalidateTabAdornments()
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()
subscribeTabAdornments(listener): Disposable;Defined in: packages/sdk/src/tab-adornment.ts:260
Parameters
listener
() => void
Returns
Inherited from
TabAdornmentMethods.subscribeTabAdornments
create()
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?
Returns
TerminalRecord | undefined
closeWorkspace()
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()
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
const term = ctx.terminals.create({ cwd: workspaceFolder });
if (term) ctx.terminals.sendText(term.id, "npm run build");close()
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()
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()
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
Example
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()
focus(terminalId): void;Defined in: packages/sdk/src/terminal-service.ts:226
Parameters
terminalId
string
Returns
void
registerTabDecoration()
registerTabDecoration(provider): Disposable;Defined in: packages/sdk/src/terminal-service.ts:232
Parameters
provider
Returns
Deprecated
Prefer TerminalService.bindIndicator. Thin shim that registers a trailing-indicator binder for terminal tabs only.
getTabDecoration()
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()
invalidateTabDecorations(): void;Defined in: packages/sdk/src/terminal-service.ts:243
Returns
void
Deprecated
Prefer TerminalService.invalidateTabAdornments.
subscribeTabDecorations()
subscribeTabDecorations(listener): Disposable;Defined in: packages/sdk/src/terminal-service.ts:248
Parameters
listener
() => void
Returns
Deprecated
Prefer TerminalService.subscribeTabAdornments.
subscribeOsc()
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?
Returns
Example
// 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()
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?
Returns
Examples
// 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);// 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()
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()
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
Example
// Clear a "needs attention" marker once the user views the terminal.
ctx.subscriptions.push(
ctx.terminals.subscribeActive((terminalId) => {
if (terminalId) attention.delete(terminalId);
}),
);