the universal sandbox runtime for agents and humans.
pocketenv.io
sandbox
openclaw
agent
claude-code
vercel-sandbox
deno-sandbox
cloudflare-sandbox
atproto
sprites
daytona
1import chalk from "chalk";
2import consola from "consola";
3import { Sandbox } from "@pocketenv/sdk";
4import CliTable3 from "cli-table3";
5import { c } from "../theme";
6import dayjs from "dayjs";
7import relativeTime from "dayjs/plugin/relativeTime";
8import { configureSdk } from "../lib/sdk";
9import { client } from "../client";
10import getAccessToken from "../lib/getAccessToken";
11import { env } from "../lib/env";
12
13dayjs.extend(relativeTime);
14
15export async function listVolumes(sandboxName: string) {
16 await configureSdk();
17
18 const sandbox = await Sandbox.get(sandboxName);
19 const { volumes } = await sandbox.volume.list();
20
21 const table = new CliTable3({
22 head: [
23 c.primary("ID"),
24 c.primary("NAME"),
25 c.primary("PATH"),
26 c.primary("CREATED AT"),
27 ],
28 chars: {
29 top: "",
30 "top-mid": "",
31 "top-left": "",
32 "top-right": "",
33 bottom: "",
34 "bottom-mid": "",
35 "bottom-left": "",
36 "bottom-right": "",
37 left: "",
38 "left-mid": "",
39 mid: "",
40 "mid-mid": "",
41 right: "",
42 "right-mid": "",
43 middle: " ",
44 },
45 style: {
46 border: [],
47 head: [],
48 },
49 });
50
51 for (const volume of volumes) {
52 table.push([
53 c.secondary(volume.id),
54 volume.name,
55 volume.path ?? "",
56 dayjs(volume.createdAt).fromNow(),
57 ]);
58 }
59
60 consola.log(table.toString());
61}
62
63export async function createVolume(
64 sandboxName: string,
65 name: string,
66 volumePath: string,
67) {
68 await configureSdk();
69
70 try {
71 const sandbox = await Sandbox.get(sandboxName);
72 await sandbox.volume.create(name, { path: volumePath });
73
74 consola.success(
75 `Volume ${chalk.rgb(0, 232, 198)(name)} successfully mounted in sandbox ${chalk.rgb(0, 232, 198)(sandboxName)} at path ${chalk.rgb(0, 232, 198)(volumePath)}`,
76 );
77 } catch (error) {
78 consola.error("Failed to create volume:", error);
79 }
80}
81
82export async function deleteVolume(id: string) {
83 const token = await getAccessToken();
84
85 try {
86 await client.post(`/xrpc/io.pocketenv.volume.deleteVolume`, undefined, {
87 params: { id },
88 headers: {
89 Authorization: `Bearer ${env.POCKETENV_TOKEN || token}`,
90 },
91 });
92 } catch (error) {
93 consola.error(`Failed to delete volume: ${error}`);
94 return;
95 }
96
97 consola.success(
98 `Volume ${chalk.rgb(0, 232, 198)(id)} successfully deleted from sandbox`,
99 );
100}