現在のコンテナで、サンドボックス用の対話型 PTY ターミナルを作成して制御します。
考え方とブラウザー接続の手順は ターミナル を参照してください。
argv(通常はシェル)からターミナルを起動します。ターミナルリソースが作成されると解決します。プロセスの exec と同じ規則です。暗黙のシェルラップはなく、argv の各項目はシェルエスケープされません。
createTerminal(options: CreateTerminalOptions): Promise<Terminal>| フィールド | 型 | 説明 |
|---|---|---|
command |
SandboxCommand |
PTY 上で実行する argv。必須です。例: ['bash'] または ['/bin/bash']。 |
cwd |
string |
ターミナルプロセスの作業ディレクトリ。 |
env |
Record<string, string> |
このターミナル用の環境変数オーバーレイ。以降の起動は変更しません。 |
cols |
number |
初期幅(列数)。 |
rows |
number |
初期高さ(行数)。 |
bufferSize |
number |
再生用の出力バッファーサイズ(ランタイムが対応している場合)。 |
SandboxCommand はプロセス exec と同じ argv 型です。readonly [executable: string, ...args: string[]]
Promise<Terminal> — 現在のコンテナ内のターミナルに対するハンドルです。
const terminal = await sandbox.createTerminal({
command: ["bash"],
cwd: "/workspace",
env: { TERM: "xterm-256color" },
cols: 120,
rows: 40,
});
console.log(terminal.id);const terminal = await sandbox.createTerminal({
command: ["bash"],
cwd: "/workspace",
env: { TERM: "xterm-256color" },
cols: 120,
rows: 40,
});
console.log(terminal.id);現在のコンテナ内のターミナルのハンドルを返します。なければ null です。
コンテナが動いていなくても起動しません。コンテナが起動していないとき、現在のコンテナでターミナル ID が不明なとき、またはそのターミナルが同じサンドボックス ID の以前のコンテナに属していたときは null を返します。
getTerminal(id: string): Promise<Terminal | null>このサンドボックスの現在のコンテナ内のターミナルを一覧します。コンテナが動いていなくても起動しません。コンテナが起動していないときは空のリストを返します。
listTerminals(): Promise<Terminal[]>| メンバー | 説明 |
|---|---|
id |
現在のコンテナ内のターミナル ID。 |
getSnapshot() |
現在のスナップショット(running / exited / error)。 |
write(data) |
PTY(stdin)にバイトを書き込みます。 |
resize(cols, rows) |
PTY のサイズを変更します。 |
output(options?) |
カーソルベースの出力イベントストリーム。 |
waitForExit(options?) |
ターミナルが完了するまで待ちます。 |
interrupt() |
ターミナルセッションに割り込みを送ります(Ctrl-C 相当)。 |
terminate() |
ターミナルリソースを終了します。 |
connect(request, opts?) |
ブラウザーの WebSocket アップグレードを受け付け、このターミナルに接続します。 |
interface TerminalSnapshot {
id: string;
pid?: number;
command: SandboxCommand;
cwd?: string;
status: "running" | "exited" | "error";
exit?: ProcessExit;
error?: ProcessFailure;
}write(data: Uint8Array): Promise<void>PTY にバイトを書き込みます。ブラウザーのキー入力は通常 connect() 経由で届きます。
resize(cols: number, rows: number): Promise<void>output(options?: TerminalOutputOptions): Promise<ReadableStream<TerminalOutputEvent>>| フィールド | 型 | 説明 |
|---|---|---|
since |
string |
不透明なカーソル。前回のイベントの続きから再開します。 |
replay |
boolean |
再開時にバッファー済みの履歴を含めます。 |
follow |
boolean |
ライブ出力のためストリームを開いたままにします。 |
signal |
AbortSignal |
この購読だけをキャンセルします。ターミナルは動き続けます。 |
type TerminalOutputEvent =
| {
type: "data";
terminalId: string;
cursor: string;
timestamp: string;
data: Uint8Array;
}
| {
type: "terminal";
terminalId: string;
cursor: string;
timestamp: string;
state: "exited";
exit: ProcessExit;
}
| {
type: "terminal";
terminalId: string;
cursor: string;
timestamp: string;
state: "error";
error: ProcessFailure;
}
| {
type: "truncated";
terminalId: string;
cursor?: string;
timestamp: string;
};同じコンテナの同じターミナルで、あとから再接続したり output({ since, replay: true }) を呼ぶ場合は、配信済みイベントの最新 cursor を保持してください。
waitForExit(options?: {
timeout?: number;
signal?: AbortSignal;
}): Promise<ProcessExit>ローカルの timeout / signal は待機だけをキャンセルします。ターミナルは終了しません。止めるときは terminate() または interrupt() を呼び出してください。
interrupt(): Promise<void>
terminate(): Promise<void>これらはターミナル制御操作です。exec ハンドルのプロセス kill(signal) とは異なります。
ブラウザー(または他のクライアント)の WebSocket アップグレードリクエストを、このターミナルに接続します。
connect(
request: Request,
options?: {
cursor?: string;
cols?: number;
rows?: number;
},
): Promise<Response>requestは WebSocket アップグレードリクエストである必要があります。cursorは、クライアントが持っている場合、前回の切断後の出力再生を再開します。cols/rowsを指定すると、この接続の PTY サイズを設定します。
Worker がクライアントに返すべき WebSocket アップグレード Response を返します。
const url = new URL(request.url);
const terminalId = url.searchParams.get("terminalId");
if (!terminalId) {
return new Response("terminalId is required", { status: 400 });
}
const terminal = await sandbox.getTerminal(terminalId);
if (!terminal) {
return new Response("Terminal not found", { status: 404 });
}
return terminal.connect(request, {
cursor: url.searchParams.get("cursor") ?? undefined,
cols: 120,
rows: 40,
});const url = new URL(request.url);
const terminalId = url.searchParams.get("terminalId");
if (!terminalId) {
return new Response("terminalId is required", { status: 400 });
}
const terminal = await sandbox.getTerminal(terminalId);
if (!terminal) {
return new Response("Terminal not found", { status: 404 });
}
return terminal.connect(request, {
cursor: url.searchParams.get("cursor") ?? undefined,
cols: 120,
rows: 40,
});Worker と xterm.js の一連の手順は ターミナル を参照してください。
SandboxAddon は xterm.js ↗ をプレビューのターミナルに統合します。
import { SandboxAddon } from "@cloudflare/sandbox/xterm";
const addon = new SandboxAddon({
// `origin` is already a WebSocket origin (`wss://` or `ws://`).
getWebSocketUrl: ({ sandboxId, terminalId, cursor, origin }) => {
const params = new URLSearchParams({ sandboxId });
if (terminalId) params.set("terminalId", terminalId);
if (cursor) params.set("cursor", cursor);
return `${origin}/ws/terminal?${params}`;
},
reconnect: true,
onStateChange: (state, error) => {
/* update UI */
},
});import { SandboxAddon } from "@cloudflare/sandbox/xterm";
const addon = new SandboxAddon({
// `origin` is already a WebSocket origin (`wss://` or `ws://`).
getWebSocketUrl: ({ sandboxId, terminalId, cursor, origin }) => {
const params = new URLSearchParams({ sandboxId });
if (terminalId) params.set("terminalId", terminalId);
if (cursor) params.set("cursor", cursor);
return `${origin}/ws/terminal?${params}`;
},
reconnect: true,
onStateChange: (state, error) => {
/* update UI */
},
});| 項目 | プレビューの詳細 |
|---|---|
| 接続先 | { sandboxId, terminalId? } |
getWebSocketUrl のパラメーター |
sandboxId、terminalId?、cursor?、origin |
| プロパティ | state、sandboxId、terminalId |
@xterm/xterm はプレビューパッケージのオプションの peer dependency です。
| 状況 | クラス / 結果 |
|---|---|
| 現在のコンテナで不明なターミナル ID | TerminalNotFoundError |
コンテナ未起動時の getTerminal / listTerminals |
null / [](エラーではありません。コンテナは起動しません) |
| 以前のコンテナのハンドルまたはターミナル ID | StaleTerminalHandleError |
| 作成時の作業ディレクトリが不正 | InvalidTerminalCwdError |
| 出力カーソルが不正 | InvalidTerminalCursorError |
| 制御操作が失敗 | TerminalControlError |
復旧の案内: エラーと復旧。完全な一覧: Errors API。生存期間: プロセスの生存期間。