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.

at 1241cd4e999bb3f48dca4cab7bcff14fe6f5d6ad 95 lines 2.6 kB view raw
1import cors from "cors"; 2import express from "express"; 3import morgan from "morgan"; 4import { consola } from "consola"; 5import bsky from "bsky"; 6import { contextMiddleware, ctx } from "context"; 7import { createServer } from "lexicon"; 8import chalk from "chalk"; 9import API from "./xrpc"; 10import ssh, { attachWebSocket as attachSshWebSocket } from "./ssh"; 11import tty, { attachWebSocket as attachTtyWebSocket } from "./tty"; 12import pty, { attachWebSocket as attachPtyWebSocket } from "./pty"; 13import { createRateLimiter } from "./ratelimiter"; 14import { createServer as createHttpServer } from "node:http"; 15import type { IncomingMessage } from "node:http"; 16import type { Duplex } from "node:stream"; 17 18let xrpcServer = createServer({ 19 validateResponse: false, 20 payload: { 21 jsonLimit: 100 * 1024, // 100kb 22 textLimit: 100 * 1024, // 100kb 23 blobLimit: 5 * 1024 * 1024, // 5mb 24 }, 25}); 26 27xrpcServer = API(xrpcServer, ctx); 28 29const app = express(); 30 31app.use(contextMiddleware); 32app.use(cors()); 33app.use(morgan("dev")); 34app.use(createRateLimiter({ windowMs: 30_000, max: 500 })); 35 36const banner = ` 37 ___ __ __ 38 / _ \\___ ____/ /_____ / /____ ___ _ __ 39 / ___/ _ \\/ __/ '_/ -_) __/ -_) _ \\ |/ / 40 /_/ \\___/\\__/_/\\_\\__/\\__/\\__/_/ /_/___/ 41 42 `; 43 44app.get("/", (req, res) => { 45 const accept = req.headers.accept || ""; 46 const wantsHTML = accept.includes("text/html"); 47 48 if (wantsHTML) { 49 res.contentType("text/html"); 50 res.send(`<pre>${banner}</pre>`); 51 return; 52 } 53 res.contentType("text/plain"); 54 res.send(banner); 55}); 56 57app.use(bsky); 58app.use(xrpcServer.xrpc.router); 59app.use("/ssh", ssh); 60app.use("/tty", tty); 61app.use("/pty", pty); 62 63const httpServer = createHttpServer(app); 64 65const wsHandlers = [ 66 attachPtyWebSocket("/pty"), 67 attachTtyWebSocket("/tty"), 68 attachSshWebSocket("/ssh"), 69]; 70 71httpServer.on( 72 "upgrade", 73 (req: IncomingMessage, socket: Duplex, head: Buffer) => { 74 const pathname = new URL(req.url ?? "", "http://localhost").pathname; 75 for (const { wss, pathRegex } of wsHandlers) { 76 const match = pathname.match(pathRegex); 77 if (match) { 78 wss.handleUpgrade(req, socket, head, (ws) => { 79 wss.emit("connection", ws, req, match[1]!); 80 }); 81 return; 82 } 83 } 84 // No handler matched — reject cleanly 85 socket.write("HTTP/1.1 404 Not Found\r\nConnection: close\r\n\r\n"); 86 socket.destroy(); 87 }, 88); 89 90httpServer.listen(process.env.POCKETENV_XPRC_PORT || 8789, () => { 91 consola.log(chalk.greenBright(banner)); 92 consola.info( 93 `Pocketenv XRPC API is running on port ${process.env.POCKETENV_XPRC_PORT || 8789}`, 94 ); 95});