the universal sandbox runtime for agents and humans. pocketenv.io
sandbox openclaw agent claude-code vercel-sandbox deno-sandbox cloudflare-sandbox atproto sprites daytona
7
fork

Configure Feed

Select the types of activity you want to include in your feed.

Buffer SSH output until SSE client connects

+14 -2
+14 -2
apps/api/src/ssh/index.ts
··· 10 10 client: Client; 11 11 stream: NodeJS.ReadWriteStream | null; 12 12 sseRes: import("express").Response | null; 13 + buffer: string[]; 13 14 } 14 15 15 16 const sessions = new Map<string, SSHSession>(); ··· 65 66 client, 66 67 stream: null, 67 68 sseRes: null, 69 + buffer: [], 68 70 }; 69 71 70 72 sessions.set(sessionId, session); ··· 83 85 session.stream = stream; 84 86 85 87 stream.on("data", (data: Buffer) => { 88 + const encoded = Buffer.from(data).toString("base64"); 86 89 if (session.sseRes && !session.sseRes.writableEnded) { 87 - const encoded = Buffer.from(data).toString("base64"); 88 90 session.sseRes.write(`data: ${encoded}\n\n`); 91 + } else { 92 + session.buffer.push(encoded); 89 93 } 90 94 }); 91 95 ··· 100 104 }); 101 105 102 106 stream.stderr.on("data", (data: Buffer) => { 107 + const encoded = Buffer.from(data).toString("base64"); 103 108 if (session.sseRes && !session.sseRes.writableEnded) { 104 - const encoded = Buffer.from(data).toString("base64"); 105 109 session.sseRes.write(`data: ${encoded}\n\n`); 110 + } else { 111 + session.buffer.push(encoded); 106 112 } 107 113 }); 108 114 ··· 162 168 res.write(`event: connected\ndata: ${sessionId}\n\n`); 163 169 164 170 session.sseRes = res; 171 + 172 + // Flush buffered output that arrived before the SSE client connected 173 + for (const encoded of session.buffer) { 174 + res.write(`data: ${encoded}\n\n`); 175 + } 176 + session.buffer = []; 165 177 166 178 // Handle client disconnect 167 179 req.on("close", () => {