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.

Populate port preview URLs after sandbox start

Expose ports after sandbox.start, collect preview URLs, and save
them to sandboxPorts.previewUrl per port. Remove the previous update
that set status/startedAt on the sandboxes row.

+26 -12
+26 -12
apps/cf-sandbox/src/index.ts
··· 350 350 `/${volume.users?.did || ""}${volume.users?.did ? "/" : ""}${volume.sandbox_volumes.id}/`, 351 351 ), 352 352 ), 353 - ...params[6].map((port) => 354 - sandbox?.expose(port.sandbox_ports.exposedPort, hostname), 355 - ), 356 353 ]); 357 354 358 355 if (record.repo) { ··· 365 362 } 366 363 367 364 await sandbox.start(); 368 - await c.var.db 369 - .update(sandboxes) 370 - .set({ 371 - status: "RUNNING", 372 - startedAt: new Date(), 373 - sandboxId: record.name, 374 - }) 375 - .where(eq(sandboxes.id, c.req.param("sandboxId"))) 376 - .execute(); 365 + 366 + const previewUrls = await Promise.all( 367 + params[6].map((port) => 368 + sandbox?.expose(port.sandbox_ports.exposedPort, hostname), 369 + ), 370 + ); 371 + 372 + await Promise.all( 373 + previewUrls.map((url, i) => { 374 + if (url) { 375 + return c.var.db 376 + .update(sandboxPorts) 377 + .set({ previewUrl: url }) 378 + .where( 379 + and( 380 + eq(sandboxPorts.sandboxId, record.id), 381 + eq( 382 + sandboxPorts.exposedPort, 383 + params[6][i].sandbox_ports.exposedPort, 384 + ), 385 + ), 386 + ) 387 + .execute(); 388 + } 389 + }), 390 + ); 377 391 } catch (err) { 378 392 const errorMessage = err instanceof Error ? err.message : "Unknown error"; 379 393 consola.error("Failed to start sandbox:", errorMessage);