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 main 114 lines 2.9 kB view raw
1import consola from "consola"; 2import dayjs from "dayjs"; 3import relativeTime from "dayjs/plugin/relativeTime"; 4import { Sandbox } from "@pocketenv/sdk"; 5import CliTable3 from "cli-table3"; 6import { c } from "../theme"; 7import { editor } from "@inquirer/prompts"; 8import fs from "fs/promises"; 9import path from "path"; 10import { configureSdk } from "../lib/sdk"; 11import { client } from "../client"; 12import getAccessToken from "../lib/getAccessToken"; 13import { env } from "../lib/env"; 14 15dayjs.extend(relativeTime); 16 17export async function putFile( 18 sandboxName: string, 19 remotePath: string, 20 localPath?: string, 21) { 22 let content: string; 23 if (!process.stdin.isTTY) { 24 const chunks: Buffer[] = []; 25 for await (const chunk of process.stdin) chunks.push(chunk); 26 content = Buffer.concat(chunks).toString().trim(); 27 } else if (localPath) { 28 const resolvedPath = path.resolve(localPath); 29 try { 30 await fs.access(resolvedPath); 31 } catch (err) { 32 consola.error(`No such file: ${c.error(localPath)}`); 33 process.exit(1); 34 } 35 content = await fs.readFile(resolvedPath, "utf-8"); 36 } else { 37 content = ( 38 await editor({ 39 message: "File content (opens in $EDITOR):", 40 waitForUserInput: false, 41 }) 42 ).trim(); 43 } 44 45 await configureSdk(); 46 47 try { 48 const sandbox = await Sandbox.get(sandboxName); 49 await sandbox.file.write(remotePath, content); 50 consola.success( 51 `File ${c.primary(remotePath)} successfully created in sandbox ${c.primary(sandboxName)}`, 52 ); 53 } catch (error) { 54 consola.error(`Failed to create file: ${error}`); 55 } 56} 57 58export async function listFiles(sandboxName: string) { 59 await configureSdk(); 60 61 const sandbox = await Sandbox.get(sandboxName); 62 const { files } = await sandbox.file.list(); 63 64 const table = new CliTable3({ 65 head: [c.primary("ID"), c.primary("PATH"), c.primary("CREATED AT")], 66 chars: { 67 top: "", 68 "top-mid": "", 69 "top-left": "", 70 "top-right": "", 71 bottom: "", 72 "bottom-mid": "", 73 "bottom-left": "", 74 "bottom-right": "", 75 left: "", 76 "left-mid": "", 77 mid: "", 78 "mid-mid": "", 79 right: "", 80 "right-mid": "", 81 middle: " ", 82 }, 83 style: { 84 border: [], 85 head: [], 86 }, 87 }); 88 89 for (const file of files) { 90 table.push([ 91 c.secondary(file.id), 92 file.path, 93 dayjs(file.createdAt).fromNow(), 94 ]); 95 } 96 97 consola.log(table.toString()); 98} 99 100export async function deleteFile(id: string) { 101 const token = await getAccessToken(); 102 103 try { 104 await client.post(`/xrpc/io.pocketenv.file.deleteFile`, undefined, { 105 params: { id }, 106 headers: { 107 Authorization: `Bearer ${env.POCKETENV_TOKEN || token}`, 108 }, 109 }); 110 consola.success(`File ${c.primary(id)} successfully deleted from sandbox`); 111 } catch (error) { 112 consola.error(`Failed to delete file: ${error}`); 113 } 114}