diff --git a/src/connection/protocol.ts b/src/connection/protocol.ts index 718a789..b753602 100644 --- a/src/connection/protocol.ts +++ b/src/connection/protocol.ts @@ -29,6 +29,8 @@ export type BackendMessageType = | 'create_pty' | 'kill_pty' | 'resize' + | 'ensure_pty' + | 'request_replay' | 'list_directories' | 'list_sessions'; diff --git a/src/main.ts b/src/main.ts index 007ac36..514c4bd 100644 --- a/src/main.ts +++ b/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 } });