feat: add ensure_pty for deferred PTY creation with client dimensions
New ensure_pty message: creates PTY if not running, or resizes and sends replay buffer if already active. This allows the frontend to request PTY creation with actual terminal dimensions after xterm.js FitAddon calculates the correct cols/rows for the container. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -29,6 +29,8 @@ export type BackendMessageType =
|
||||
| 'create_pty'
|
||||
| 'kill_pty'
|
||||
| 'resize'
|
||||
| 'ensure_pty'
|
||||
| 'request_replay'
|
||||
| 'list_directories'
|
||||
| 'list_sessions';
|
||||
|
||||
|
||||
32
src/main.ts
32
src/main.ts
@ -81,13 +81,16 @@ class ClaudeCliProxy {
|
||||
case 'create_pty':
|
||||
this.handleCreatePty(msg.payload as CreatePtyPayload);
|
||||
break;
|
||||
case 'ensure_pty':
|
||||
this.handleEnsurePty(msg.payload as CreatePtyPayload);
|
||||
break;
|
||||
case 'kill_pty':
|
||||
this.handleKillPty(msg.payload as KillPtyPayload);
|
||||
break;
|
||||
case 'resize':
|
||||
this.handleResize(msg.payload as ResizePayload);
|
||||
break;
|
||||
case 'request_replay' as any: {
|
||||
case 'request_replay': {
|
||||
const { chatId } = msg.payload as { chatId: string };
|
||||
const replay = this.pty.getReplayBuffer(chatId);
|
||||
if (replay) {
|
||||
@ -116,23 +119,15 @@ class ClaudeCliProxy {
|
||||
const activePtys = new Set(this.pty.listPtys());
|
||||
const chatIds = new Set(payload.chats.map((c) => c.id));
|
||||
|
||||
// Send replay + pty_ready for already running PTYs
|
||||
// PTYs for new chats will be created via ensure_pty from frontend
|
||||
for (const chat of payload.chats) {
|
||||
if (activePtys.has(chat.id)) {
|
||||
// PTY exists — send replay + ready
|
||||
const replay = this.pty.getReplayBuffer(chat.id);
|
||||
if (replay) {
|
||||
this.ws.sendBinary(encodeBinaryFrame(DIR_PTY_OUTPUT, chat.id, replay));
|
||||
}
|
||||
this.ws.send({ type: 'pty_ready', payload: { chatId: chat.id } });
|
||||
} else if (chat.workDir) {
|
||||
// PTY not running — create it
|
||||
this.handleCreatePty({
|
||||
chatId: chat.id,
|
||||
dir: chat.workDir,
|
||||
resumeSessionId: chat.sessionId ?? undefined,
|
||||
cols: chat.cols ?? 120,
|
||||
rows: chat.rows ?? 40,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,6 +161,21 @@ class ClaudeCliProxy {
|
||||
this.ws.send({ type: 'pty_ready', payload: { chatId: payload.chatId } });
|
||||
}
|
||||
|
||||
private handleEnsurePty(payload: CreatePtyPayload): void {
|
||||
if (this.pty.hasPty(payload.chatId)) {
|
||||
// PTY already exists — resize to match client, send replay + ready
|
||||
this.pty.resizePty(payload.chatId, payload.cols, payload.rows);
|
||||
const replay = this.pty.getReplayBuffer(payload.chatId);
|
||||
if (replay) {
|
||||
this.ws.sendBinary(encodeBinaryFrame(DIR_PTY_OUTPUT, payload.chatId, replay));
|
||||
}
|
||||
this.ws.send({ type: 'pty_ready', payload: { chatId: payload.chatId } });
|
||||
} else {
|
||||
// PTY doesn't exist — create with client's dimensions
|
||||
this.handleCreatePty(payload);
|
||||
}
|
||||
}
|
||||
|
||||
private handleKillPty(payload: KillPtyPayload): void {
|
||||
this.pty.killPty(payload.chatId);
|
||||
this.ws.send({ type: 'pty_closed', payload: { chatId: payload.chatId, exitCode: 0 } });
|
||||
|
||||
Reference in New Issue
Block a user