···1414import { deleteEnv, listEnvs, putEnv } from "./cmd/env";
1515import { getSshKey, putKeys } from "./cmd/sshkeys";
1616import { getTailscaleAuthKey, putAuthKey } from "./cmd/tailscale";
1717-1818-const c = {
1919- primary: (s: string) => chalk.rgb(0, 232, 198)(s),
2020- secondary: (s: string) => chalk.rgb(0, 198, 232)(s),
2121- accent: (s: string) => chalk.rgb(130, 100, 255)(s),
2222- highlight: (s: string) => chalk.rgb(100, 232, 130)(s),
2323- muted: (s: string) => chalk.rgb(200, 210, 220)(s),
2424- link: (s: string) => chalk.rgb(255, 160, 100)(s),
2525- sky: (s: string) => chalk.rgb(0, 210, 255)(s),
2626-};
1717+import { exposePort } from "./cmd/expose";
1818+import { unexposePort } from "./cmd/unexpose";
1919+import { createVolume, deleteVolume, listVolumes } from "./cmd/volume";
2020+import { deleteFile, listFiles, putFile } from "./cmd/file";
2121+import consola from "consola";
2222+import { listPorts } from "./cmd/ports";
2323+import { c } from "./theme";
27242825const program = new Command();
2926···111108 .argument("<sandbox>", "the sandbox to delete")
112109 .description("delete the given sandbox")
113110 .action(deleteSandbox);
111111+112112+program
113113+ .command("expose")
114114+ .argument("<sandbox>", "the sandbox to expose a port for")
115115+ .argument("<port>", "the port to expose", (val) => {
116116+ const port = parseInt(val, 10);
117117+ if (isNaN(port)) {
118118+ consola.error(`port must be a number, got: ${val}`);
119119+ process.exit(1);
120120+ }
121121+ return port;
122122+ })
123123+ .description("expose a port from the given sandbox to the internet")
124124+ .action(exposePort);
125125+126126+program
127127+ .command("unexpose")
128128+ .argument("<sandbox>", "the sandbox to unexpose a port for")
129129+ .argument("<port>", "the port to unexpose", (val) => {
130130+ const port = parseInt(val, 10);
131131+ if (isNaN(port)) {
132132+ consola.error(`port must be a number, got: ${val}`);
133133+ process.exit(1);
134134+ }
135135+ return port;
136136+ })
137137+ .description("unexpose a port from the given sandbox")
138138+ .action(unexposePort);
139139+140140+const volume = program.command("volume").description("manage volumes");
141141+142142+volume
143143+ .command("put")
144144+ .argument("<sandbox>", "the sandbox to put the volume in")
145145+ .argument("<name>", "the name of the volume")
146146+ .argument("<path>", "the path to mount the volume at")
147147+ .description("put a volume in the given sandbox")
148148+ .action(createVolume);
149149+150150+volume
151151+ .command("list")
152152+ .aliases(["ls"])
153153+ .argument("<sandbox>", "the sandbox to list volumes for")
154154+ .description("list volumes in the given sandbox")
155155+ .action(listVolumes);
156156+157157+volume
158158+ .command("delete")
159159+ .aliases(["rm", "remove"])
160160+ .argument("<id>", "the ID of the volume to delete")
161161+ .description("delete a volume")
162162+ .action(deleteVolume);
163163+164164+const file = program.command("file").description("manage files");
165165+166166+file
167167+ .command("put")
168168+ .argument("<sandbox>", "the sandbox to put the file in")
169169+ .argument("<path>", "the remote path to upload the file to")
170170+ .option(
171171+ "--local-path, -f <localPath>",
172172+ "the local path of the file to upload",
173173+ )
174174+ .description("upload a file to the given sandbox")
175175+ .action(putFile);
176176+177177+file
178178+ .command("list")
179179+ .aliases(["ls"])
180180+ .argument("<sandbox>", "the sandbox to list files for")
181181+ .description("list files in the given sandbox")
182182+ .action(listFiles);
183183+184184+file
185185+ .command("delete")
186186+ .aliases(["rm", "remove"])
187187+ .argument("<id>", "the ID of the file to delete")
188188+ .description("delete a file")
189189+ .action(deleteFile);
190190+191191+program
192192+ .command("ports")
193193+ .argument("<sandbox>", "the sandbox to list exposed ports for")
194194+ .description("list exposed ports for a sandbox")
195195+ .action(listPorts);
114196115197const secret = program.command("secret").description("manage secrets");
116198