@axiom-lattice/opensandbox-gateway 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,98 @@
1
+ import z from "zod";
2
+
3
+ const bindMountSchema = z.object({
4
+ type: z.literal("bind"),
5
+ source: z.string().min(1),
6
+ readonly: z.boolean().optional(),
7
+ });
8
+
9
+ const namedMountSchema = z.object({
10
+ type: z.literal("named"),
11
+ name: z.string().min(1),
12
+ readonly: z.boolean().optional(),
13
+ });
14
+
15
+ const tmpfsMountSchema = z.object({
16
+ type: z.literal("tmpfs"),
17
+ sizeMib: z.number().int().positive().optional(),
18
+ });
19
+
20
+ export const volumeSchema = z.union([
21
+ bindMountSchema,
22
+ namedMountSchema,
23
+ tmpfsMountSchema,
24
+ ]);
25
+
26
+ export const ensureSandboxSchema = z.object({
27
+ image: z.string().optional(),
28
+ cpus: z.number().int().positive().optional(),
29
+ memoryMib: z.number().int().positive().optional(),
30
+ env: z.record(z.string()).optional(),
31
+ volumes: z.record(volumeSchema).optional(),
32
+ });
33
+
34
+ export const sandboxNameParamsSchema = z.object({
35
+ name: z.string().min(1),
36
+ });
37
+
38
+ export const listSandboxesQuerySchema = z.object({
39
+ status: z.enum(["running", "stopped", "crashed", "unknown"]).optional(),
40
+ image: z.string().min(1).optional(),
41
+ search: z.string().min(1).optional(),
42
+ });
43
+
44
+ const sandboxAndPathSchema = z.object({
45
+ sandboxName: z.string().min(1),
46
+ path: z.string().min(1),
47
+ });
48
+
49
+ export const readFileSchema = sandboxAndPathSchema;
50
+
51
+ export const writeFileSchema = sandboxAndPathSchema.extend({
52
+ content: z.string(),
53
+ });
54
+
55
+ export const listPathSchema = sandboxAndPathSchema.extend({
56
+ recursive: z.boolean().optional(),
57
+ });
58
+
59
+ export const findFilesSchema = sandboxAndPathSchema.extend({
60
+ pattern: z.string().min(1),
61
+ });
62
+
63
+ export const searchInFileSchema = sandboxAndPathSchema.extend({
64
+ query: z.string().min(1),
65
+ });
66
+
67
+ export const replaceInFileSchema = sandboxAndPathSchema.extend({
68
+ search: z.string(),
69
+ replace: z.string(),
70
+ });
71
+
72
+ export const uploadFileSchema = sandboxAndPathSchema.and(
73
+ z.union([
74
+ z.object({ contentBase64: z.string() }),
75
+ z.object({ content: z.string().transform((content) => Buffer.from(content).toString("base64")) }),
76
+ ])
77
+ );
78
+
79
+ export const downloadFileSchema = sandboxAndPathSchema;
80
+
81
+ export const shellExecSchema = z.object({
82
+ sandboxName: z.string().min(1),
83
+ command: z.string().min(1),
84
+ exec_dir: z.string().optional(),
85
+ timeout: z.number().int().positive().optional(),
86
+ });
87
+
88
+ export const sandboxLogsSchema = z.object({
89
+ tail: z.number().int().positive().optional(),
90
+ since: z.string().optional(),
91
+ until: z.string().optional(),
92
+ sources: z.array(z.string()).optional(),
93
+ });
94
+
95
+ export type EnsureSandboxInput = z.infer<typeof ensureSandboxSchema>;
96
+ export type ListSandboxesQuery = z.infer<typeof listSandboxesQuerySchema>;
97
+ export type ShellExecInput = z.infer<typeof shellExecSchema>;
98
+ export type SandboxLogsInput = z.infer<typeof sandboxLogsSchema>;
@@ -0,0 +1,23 @@
1
+ import z from "zod";
2
+
3
+ export const volumeFsReadSchema = z.object({
4
+ path: z.string(),
5
+ });
6
+
7
+ export const volumeFsWriteSchema = z.object({
8
+ path: z.string(),
9
+ content: z.string(),
10
+ });
11
+
12
+ export const volumeFsListSchema = z.object({
13
+ path: z.string(),
14
+ });
15
+
16
+ export const volumeFsUploadSchema = z.object({
17
+ path: z.string(),
18
+ contentBase64: z.string().min(1),
19
+ });
20
+
21
+ export const volumeFsDownloadSchema = z.object({
22
+ path: z.string(),
23
+ });
package/src/server.ts ADDED
@@ -0,0 +1,50 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ import { buildApp } from "./app";
3
+ import { parseServerArgs, resolveServerConfig } from "./lib/server-cli";
4
+
5
+ export async function startServer({
6
+ argv = process.argv.slice(2),
7
+ env = process.env,
8
+ app,
9
+ }: {
10
+ argv?: string[];
11
+ env?: NodeJS.ProcessEnv;
12
+ app?: Pick<FastifyInstance, "listen" | "close">;
13
+ } = {}): Promise<Pick<FastifyInstance, "listen" | "close">> {
14
+ const config = resolveServerConfig({ args: parseServerArgs(argv), env });
15
+ const resolvedApp = app ?? (await buildApp({ apiKey: config.apiKey }));
16
+
17
+ const removeSignalHandlers = (): void => {
18
+ process.off("SIGINT", onSigInt);
19
+ process.off("SIGTERM", onSigTerm);
20
+ };
21
+
22
+ const close = async (): Promise<undefined> => {
23
+ removeSignalHandlers();
24
+ return resolvedApp.close();
25
+ };
26
+
27
+ const onSigInt = () => { void shutdown(0); };
28
+ const onSigTerm = () => { void shutdown(0); };
29
+
30
+ const shutdown = async (code: number): Promise<void> => {
31
+ try {
32
+ await close();
33
+ process.exit(code);
34
+ } catch (error) {
35
+ console.error("Failed to shutdown opensandbox-gateway cleanly", error);
36
+ process.exit(1);
37
+ }
38
+ };
39
+
40
+ process.once("SIGINT", onSigInt);
41
+ process.once("SIGTERM", onSigTerm);
42
+
43
+ try {
44
+ await resolvedApp.listen({ port: config.port, host: config.host });
45
+ return { listen: resolvedApp.listen.bind(resolvedApp), close: close as FastifyInstance["close"] };
46
+ } catch (error) {
47
+ removeSignalHandlers();
48
+ throw error;
49
+ }
50
+ }
@@ -0,0 +1,32 @@
1
+ import type { PullImageInput } from "../schemas/images";
2
+
3
+ export type ImageRecord = {
4
+ ref: string;
5
+ sourceType: string;
6
+ cached: boolean;
7
+ size?: number;
8
+ createdAt?: string;
9
+ lastUsedAt?: string;
10
+ };
11
+
12
+ export class ImageService {
13
+ async listImages(): Promise<{ items: ImageRecord[]; total: number }> {
14
+ return { items: [], total: 0 };
15
+ }
16
+
17
+ async pullImage(_input: PullImageInput): Promise<ImageRecord> {
18
+ throw new Error("Image pull not supported in OpenSandbox gateway");
19
+ }
20
+
21
+ async getImage(ref: string): Promise<ImageRecord> {
22
+ return {
23
+ ref,
24
+ sourceType: "oci",
25
+ cached: false,
26
+ };
27
+ }
28
+
29
+ async deleteImage(ref: string): Promise<{ ref: string }> {
30
+ return { ref };
31
+ }
32
+ }