@axiom-lattice/microsandbox-service 0.0.46 → 0.0.48

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @axiom-lattice/microsandbox-service
2
2
 
3
+ ## 0.0.48
4
+
5
+ ### Patch Changes
6
+
7
+ - f2dce99: fix bugs
8
+
9
+ ## 0.0.47
10
+
11
+ ### Patch Changes
12
+
13
+ - 13cd999: fix sandbox
14
+
3
15
  ## 0.0.46
4
16
 
5
17
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  buildApp
3
- } from "./chunk-XKHPYRQU.mjs";
3
+ } from "./chunk-KVJG7R3I.mjs";
4
4
 
5
5
  // src/lib/server-cli.ts
6
6
  function parsePort(raw, source) {
@@ -97,4 +97,4 @@ async function startServer({
97
97
  export {
98
98
  startServer
99
99
  };
100
- //# sourceMappingURL=chunk-62MHJDP4.mjs.map
100
+ //# sourceMappingURL=chunk-5F6UN2VW.mjs.map
@@ -1,7 +1,10 @@
1
1
  // src/services/SandboxRegistry.ts
2
2
  import { Sandbox, MountBuilder } from "microsandbox";
3
+ import { readdirSync, readFileSync, unlinkSync } from "fs";
4
+ import { join } from "path";
3
5
  var DEFAULT_IMAGE = process.env.MICROSANDBOX_IMAGE ?? "daytonaio/sandbox:0.6.0";
4
6
  var CACHE_TTL_MS = 3e5;
7
+ var SANDBOX_AGENT_SOCKET_DIR = "/root/.microsandbox/run/agent";
5
8
  function extractConfig(configJson) {
6
9
  try {
7
10
  const raw = JSON.parse(configJson);
@@ -32,11 +35,50 @@ var SandboxRegistry = class {
32
35
  constructor() {
33
36
  this.handles = /* @__PURE__ */ new Map();
34
37
  this.creating = /* @__PURE__ */ new Map();
38
+ this.cleanupOrphanedSockets();
35
39
  }
36
40
  remove(name) {
37
41
  this.handles.delete(name);
38
42
  this.creating.delete(name);
39
43
  }
44
+ cleanupOrphanedSockets() {
45
+ try {
46
+ const activeSockets = /* @__PURE__ */ new Set();
47
+ const unixSockets = readFileSync("/proc/net/unix", "utf-8");
48
+ for (const line of unixSockets.split("\n")) {
49
+ const path2 = line.trim().split(" ").pop();
50
+ if (path2 && path2.startsWith(SANDBOX_AGENT_SOCKET_DIR)) {
51
+ activeSockets.add(path2);
52
+ }
53
+ }
54
+ for (const entry of readdirSync(SANDBOX_AGENT_SOCKET_DIR)) {
55
+ const fullPath = join(SANDBOX_AGENT_SOCKET_DIR, entry);
56
+ if (!activeSockets.has(fullPath)) {
57
+ unlinkSync(fullPath);
58
+ console.log(`[SandboxRegistry] removed orphaned socket: ${entry}`);
59
+ }
60
+ }
61
+ } catch (err) {
62
+ if (err.code !== "ENOENT") {
63
+ console.log(`[SandboxRegistry] socket cleanup skipped: ${err.message}`);
64
+ }
65
+ }
66
+ }
67
+ async stopAndRemove(name) {
68
+ try {
69
+ const handle = await Sandbox.get(name);
70
+ if (handle.status === "running") {
71
+ try {
72
+ const native = await handle.connect();
73
+ await native.stop();
74
+ } catch {
75
+ }
76
+ }
77
+ await Sandbox.remove(name);
78
+ } catch {
79
+ }
80
+ this.cleanupOrphanedSockets();
81
+ }
40
82
  async waitForFs(native, maxRetries = 10) {
41
83
  const fs2 = native.fs();
42
84
  for (let i = 0; i < maxRetries; i++) {
@@ -100,11 +142,9 @@ var SandboxRegistry = class {
100
142
  console.log(`[SandboxRegistry] Sandbox.get name=${name} status=${handle.status} elapsed=${Date.now() - tGet}ms`);
101
143
  originalConfig = extractConfig(handle.configJson);
102
144
  if (handle.status === "running" || handle.status === "stopped") {
103
- if (createOptions && this.hasConfigMismatch(originalConfig, createOptions)) {
104
- try {
105
- await Sandbox.remove(name);
106
- } catch {
107
- }
145
+ const isNewConnection = !cached;
146
+ if (isNewConnection && createOptions && this.hasConfigMismatch(originalConfig, createOptions)) {
147
+ await this.stopAndRemove(name);
108
148
  native = void 0;
109
149
  } else if (handle.status === "running") {
110
150
  const tConnect = Date.now();
@@ -123,17 +163,14 @@ var SandboxRegistry = class {
123
163
  console.log(`[SandboxRegistry] waitForFs name=${name} elapsed=${Date.now() - tFs}ms`);
124
164
  } catch {
125
165
  if (!native) {
126
- try {
127
- await Sandbox.remove(name);
128
- } catch {
129
- }
166
+ await this.stopAndRemove(name);
130
167
  }
131
168
  }
132
169
  }
133
170
  } else if (handle.status === "crashed" || handle.status === "draining") {
134
- await Sandbox.remove(name);
171
+ await this.stopAndRemove(name);
135
172
  } else {
136
- await Sandbox.remove(name);
173
+ await this.stopAndRemove(name);
137
174
  }
138
175
  } catch {
139
176
  native = void 0;
@@ -212,7 +249,7 @@ var SandboxRegistry = class {
212
249
  native = await tryCreate();
213
250
  } catch (err) {
214
251
  if (err instanceof Error && err.message.includes("already exists")) {
215
- await Sandbox.remove(name);
252
+ await this.stopAndRemove(name);
216
253
  native = await tryCreate();
217
254
  } else {
218
255
  throw err;
@@ -229,6 +266,8 @@ var SandboxRegistry = class {
229
266
  return native;
230
267
  })();
231
268
  this.creating.set(name, creation);
269
+ creation.catch(() => {
270
+ });
232
271
  void creation.finally(() => this.creating.delete(name));
233
272
  return creation;
234
273
  }
@@ -407,7 +446,7 @@ var MicrosandboxRuntimeService = class {
407
446
  }
408
447
  async deleteSandbox(name) {
409
448
  this.registry.remove(name);
410
- await Sandbox2.remove(name);
449
+ await this.registry.stopAndRemove(name);
411
450
  return { name, status: "unknown" };
412
451
  }
413
452
  async listSandboxes(_query) {
@@ -1231,4 +1270,4 @@ export {
1231
1270
  MicrosandboxRuntimeService,
1232
1271
  buildApp
1233
1272
  };
1234
- //# sourceMappingURL=chunk-XKHPYRQU.mjs.map
1273
+ //# sourceMappingURL=chunk-KVJG7R3I.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/services/SandboxRegistry.ts","../src/services/MicrosandboxRuntimeService.ts","../src/lib/msb.ts","../src/app.ts","../src/lib/errors.ts","../src/lib/http.ts","../src/routes/health.ts","../src/controllers/images.ts","../src/schemas/images.ts","../src/routes/images.ts","../src/schemas/sandbox.ts","../src/controllers/sandbox.ts","../src/routes/sandbox.ts","../src/controllers/volume-fs.ts","../src/schemas/volume-fs.ts","../src/routes/volume-fs.ts","../src/services/ImageService.ts","../src/swagger.ts"],"sourcesContent":["import { Sandbox, MountBuilder } from \"microsandbox\";\nimport type { SandboxHandle } from \"microsandbox\";\nimport { readdirSync, readFileSync, unlinkSync } from \"fs\";\nimport { join } from \"path\";\n\nconst DEFAULT_IMAGE = process.env.MICROSANDBOX_IMAGE ?? \"daytonaio/sandbox:0.6.0\";\nconst CACHE_TTL_MS = 300_000;\nconst SANDBOX_AGENT_SOCKET_DIR = \"/root/.microsandbox/run/agent\";\n\nfunction extractConfig(configJson: string): {\n image: string;\n cpus: number;\n memoryMib: number;\n env: Record<string, string>;\n mounts: Array<{ guest: string; type: string; source?: string; name?: string; size_mib?: number; readonly?: boolean }>;\n} | undefined {\n try {\n const raw = JSON.parse(configJson);\n const image = typeof raw.image === \"string\" ? raw.image\n : raw.image?.Oci?.reference ?? \"\";\n const env: Record<string, string> = {};\n const rawEnv = raw.env;\n if (Array.isArray(rawEnv)) {\n for (const entry of rawEnv) {\n if (Array.isArray(entry) && entry.length >= 2) {\n env[String(entry[0])] = String(entry[1]);\n }\n }\n } else if (rawEnv && typeof rawEnv === \"object\") {\n Object.assign(env, rawEnv);\n }\n return {\n image,\n cpus: raw.cpus ?? 1,\n memoryMib: raw.memory_mib ?? raw.memoryMib ?? 512,\n env,\n mounts: Array.isArray(raw.mounts) ? raw.mounts : [],\n };\n } catch {\n return undefined;\n }\n}\n\nexport class SandboxRegistry {\n private handles = new Map<string, { native: unknown; expiresAt: number; createOptions?: Record<string, unknown> }>();\n private creating = new Map<string, Promise<unknown>>();\n\n constructor() {\n this.cleanupOrphanedSockets();\n }\n\n remove(name: string): void {\n this.handles.delete(name);\n this.creating.delete(name);\n }\n\n cleanupOrphanedSockets(): void {\n try {\n const activeSockets = new Set<string>();\n const unixSockets = readFileSync(\"/proc/net/unix\", \"utf-8\");\n for (const line of unixSockets.split(\"\\n\")) {\n const path = line.trim().split(\" \").pop();\n if (path && path.startsWith(SANDBOX_AGENT_SOCKET_DIR)) {\n activeSockets.add(path);\n }\n }\n for (const entry of readdirSync(SANDBOX_AGENT_SOCKET_DIR)) {\n const fullPath = join(SANDBOX_AGENT_SOCKET_DIR, entry);\n if (!activeSockets.has(fullPath)) {\n unlinkSync(fullPath);\n console.log(`[SandboxRegistry] removed orphaned socket: ${entry}`);\n }\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n console.log(`[SandboxRegistry] socket cleanup skipped: ${(err as Error).message}`);\n }\n }\n }\n\n async stopAndRemove(name: string): Promise<void> {\n try {\n const handle = await Sandbox.get(name);\n if (handle.status === \"running\") {\n try {\n const native = await handle.connect();\n await (native as { stop(): Promise<void> }).stop();\n } catch { /* ignore */ }\n }\n await Sandbox.remove(name);\n } catch { /* ignore */ }\n this.cleanupOrphanedSockets();\n }\n\n private async waitForFs(native: unknown, maxRetries = 10): Promise<void> {\n const fs = (native as { fs(): { list(path: string): Promise<unknown> } }).fs();\n for (let i = 0; i < maxRetries; i++) {\n try {\n await fs.list(\"/\");\n return;\n } catch {\n await new Promise((r) => setTimeout(r, 200));\n }\n }\n throw new Error(\"FS not ready after start\");\n }\n\n private hasConfigMismatch(\n originalConfig: ReturnType<typeof extractConfig>,\n createOptions: Record<string, unknown>\n ): boolean {\n const volumeDefs = createOptions.volumes as Record<string, { type: string }> | undefined;\n const requestEnv = createOptions.env as Record<string, string> | undefined;\n\n if (volumeDefs && Object.keys(volumeDefs).length > 0) {\n const existingGuests = new Set((originalConfig?.mounts ?? []).map((m: { guest: string }) => m.guest));\n const requestedGuests = new Set(Object.keys(volumeDefs));\n if (existingGuests.size !== requestedGuests.size ||\n ![...requestedGuests].every(g => existingGuests.has(g))) {\n console.log(`[SandboxRegistry] volumes mismatch, recreating...`);\n return true;\n }\n }\n\n if (requestEnv && originalConfig?.env) {\n for (const [key, value] of Object.entries(requestEnv)) {\n if (originalConfig.env[key] !== value) {\n console.log(`[SandboxRegistry] env mismatch (key=${key}), recreating...`);\n return true;\n }\n }\n }\n\n return false;\n }\n\n async ensure(name: string, createOptions?: Record<string, unknown>): Promise<unknown> {\n const tStart = Date.now();\n\n const cached = this.handles.get(name);\n if (cached && Date.now() < cached.expiresAt) {\n cached.expiresAt = Date.now() + CACHE_TTL_MS;\n console.log(`[SandboxRegistry] ensure name=${name} CACHE_HIT elapsed=${Date.now() - tStart}ms`);\n return cached.native;\n }\n\n if (cached) {\n console.log(`[SandboxRegistry] ensure name=${name} TTL_EXPIRED elapsed=${Date.now() - tStart}ms reconnect...`);\n }\n\n const inflight = this.creating.get(name);\n if (inflight) {\n console.log(`[SandboxRegistry] ensure name=${name} AWAITING_INFLIGHT`);\n return inflight;\n }\n\n const creation = (async () => {\n const tCreate = Date.now();\n let native: unknown;\n const image = (createOptions?.image as string) ?? DEFAULT_IMAGE;\n const cpus = (createOptions?.cpus as number) ?? 1;\n const memoryMib = (createOptions?.memoryMib as number) ?? 512;\n const env = (createOptions?.env as Record<string, string>) ?? undefined;\n\n let originalConfig: ReturnType<typeof extractConfig>;\n\n try {\n const tGet = Date.now();\n const handle: SandboxHandle = await Sandbox.get(name);\n console.log(`[SandboxRegistry] Sandbox.get name=${name} status=${handle.status} elapsed=${Date.now() - tGet}ms`);\n\n originalConfig = extractConfig(handle.configJson);\n\n if (handle.status === \"running\" || handle.status === \"stopped\") {\n const isNewConnection = !cached;\n if (isNewConnection && createOptions && this.hasConfigMismatch(originalConfig, createOptions)) {\n await this.stopAndRemove(name);\n native = undefined;\n } else if (handle.status === \"running\") {\n const tConnect = Date.now();\n native = await handle.connect();\n console.log(`[SandboxRegistry] handle.connect name=${name} elapsed=${Date.now() - tConnect}ms`);\n const tFs = Date.now();\n await this.waitForFs(native);\n console.log(`[SandboxRegistry] waitForFs name=${name} elapsed=${Date.now() - tFs}ms`);\n } else {\n try {\n const tStart2 = Date.now();\n native = await Sandbox.startDetached(name);\n console.log(`[SandboxRegistry] startDetached name=${name} elapsed=${Date.now() - tStart2}ms`);\n const tFs = Date.now();\n await this.waitForFs(native);\n console.log(`[SandboxRegistry] waitForFs name=${name} elapsed=${Date.now() - tFs}ms`);\n } catch {\n if (!native) {\n await this.stopAndRemove(name);\n }\n }\n }\n } else if (handle.status === \"crashed\" || handle.status === \"draining\") {\n await this.stopAndRemove(name);\n } else {\n await this.stopAndRemove(name);\n }\n } catch {\n native = undefined;\n }\n console.log(`[SandboxRegistry] phase=existing_check name=${name} hasNative=${!!native} elapsed=${Date.now() - tCreate}ms`);\n\n if (!native) {\n const effectiveOptions = createOptions ?? cached?.createOptions;\n if (!effectiveOptions) {\n console.log(`[SandboxRegistry] ensure name=${name} NOT_FOUND elapsed=${Date.now() - tStart}ms`);\n throw new Error(`Sandbox ${name} not found`);\n }\n if (!createOptions && cached?.createOptions) {\n console.log(`[SandboxRegistry] ensure name=${name} RECOVER_OPTIONS elapsed=${Date.now() - tStart}ms`);\n }\n const tBuild = Date.now();\n const volumeDefs = effectiveOptions?.volumes as Record<string, { type: string; source?: string; name?: string; sizeMib?: number; readonly?: boolean }> | undefined;\n const resolvedImage = (effectiveOptions?.image as string) ?? originalConfig?.image ?? image;\n console.log(\n `[SandboxRegistry] create sandbox=${name} image=${resolvedImage} ` +\n `from=${(effectiveOptions?.image as string) ? \"request\" : originalConfig?.image ? \"originalConfig\" : \"default\"}`\n );\n const resolvedCpus = (effectiveOptions?.cpus as number) ?? originalConfig?.cpus ?? cpus;\n const resolvedMemoryMib = (effectiveOptions?.memoryMib as number) ?? originalConfig?.memoryMib ?? memoryMib;\n const resolvedEnv = (effectiveOptions?.env as Record<string, string>) ?? originalConfig?.env ?? env;\n const resolvedMounts = originalConfig?.mounts ?? [];\n\n const applyVolumes = (b: ReturnType<typeof Sandbox.builder>): void => {\n if (volumeDefs) {\n for (const [guestPath, def] of Object.entries(volumeDefs)) {\n const mb = new MountBuilder(guestPath);\n if (def.type === \"bind\" && def.source) {\n mb.bind(def.source);\n } else if (def.type === \"named\" && def.name) {\n mb.named(def.name);\n } else if (def.type === \"tmpfs\") {\n mb.tmpfs();\n if (def.sizeMib) {\n mb.size(def.sizeMib);\n }\n }\n if (def.readonly) {\n mb.readonly();\n }\n b.volume(guestPath, () => mb);\n }\n } else {\n for (const mount of resolvedMounts) {\n const mb = new MountBuilder(mount.guest);\n if (mount.type === \"Bind\" || mount.type === \"bind\") {\n if (mount.source) mb.bind(mount.source);\n } else if (mount.type === \"Named\" || mount.type === \"named\") {\n if (mount.name) mb.named(mount.name);\n } else if (mount.type === \"Tmpfs\" || mount.type === \"tmpfs\") {\n mb.tmpfs();\n if (mount.size_mib) mb.size(mount.size_mib);\n }\n if (mount.readonly) {\n mb.readonly();\n }\n b.volume(mount.guest, () => mb);\n }\n }\n };\n\n const tryCreate = async () => {\n const builder = Sandbox.builder(name)\n .detached(true)\n .image(resolvedImage)\n .cpus(resolvedCpus)\n .memory(resolvedMemoryMib);\n if (resolvedEnv) {\n builder.envs(resolvedEnv);\n }\n applyVolumes(builder);\n const tCreateInner = Date.now();\n const result = await builder.create();\n console.log(\n `[SandboxRegistry] builder.create name=${name} image=${resolvedImage} ` +\n `elapsed=${Date.now() - tCreateInner}ms ` +\n `envKeys=${resolvedEnv ? Object.keys(resolvedEnv).join(\",\") : \"none\"} ` +\n `volumes=${volumeDefs ? Object.keys(volumeDefs).join(\",\") : \"none\"}`\n );\n return result;\n };\n try {\n native = await tryCreate();\n } catch (err) {\n if (err instanceof Error && err.message.includes(\"already exists\")) {\n await this.stopAndRemove(name);\n native = await tryCreate();\n } else {\n throw err;\n }\n }\n console.log(`[SandboxRegistry] phase=create_sandbox name=${name} elapsed=${Date.now() - tBuild}ms`);\n const tFs = Date.now();\n await this.waitForFs(native);\n console.log(`[SandboxRegistry] waitForFs name=${name} elapsed=${Date.now() - tFs}ms`);\n }\n\n const totalElapsed = Date.now() - tStart;\n this.handles.set(name, { native, expiresAt: Date.now() + CACHE_TTL_MS, createOptions: createOptions ?? cached?.createOptions });\n console.log(`[SandboxRegistry] ensure DONE name=${name} total=${totalElapsed}ms cacheTTL=${Math.round(CACHE_TTL_MS / 1000)}s`);\n return native;\n })();\n\n this.creating.set(name, creation);\n creation.catch(() => {});\n void creation.finally(() => this.creating.delete(name));\n\n return creation;\n }\n}\n","import { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { Sandbox, Volume } from \"microsandbox\";\nimport type { SandboxHandle } from \"microsandbox\";\nimport type { LogReadSource } from \"microsandbox\";\nimport type { EnsureSandboxInput, ListSandboxesQuery, ShellExecInput } from \"../schemas/sandbox\";\nimport type { SandboxLogsInput } from \"../schemas/sandbox\";\nimport type { SandboxRuntimeMetrics } from \"../types/runtime-service\";\nimport { getMsbPath } from \"../lib/msb\";\nimport { SandboxRegistry } from \"./SandboxRegistry\";\n\nconst execAsync = promisify(exec);\n\ntype VolumeConfig = NonNullable<EnsureSandboxInput[\"volumes\"]>[string];\n\ntype RuntimeNative = {\n fs(): {\n readString(path: string): Promise<string>;\n readToString(path: string): Promise<string>;\n write(path: string, data: Buffer): Promise<void>;\n list(path: string): Promise<Array<{ path: string; kind: string; size?: number; modified?: unknown }>>;\n read(path: string): Promise<Buffer | Uint8Array | string>;\n mkdir(path: string): Promise<void>;\n };\n exec(cmd: string, args?: string[]): Promise<{\n stdout(): string;\n stderr(): string;\n get code(): number;\n }>;\n shell(script: string): Promise<{\n stdout(): string;\n stderr(): string;\n get code(): number;\n }>;\n stop(): Promise<void>;\n kill(): Promise<void>;\n};\n\ntype SandboxConfig = {\n name: string;\n image: unknown;\n memoryMib?: number;\n cpus?: number;\n env?: unknown;\n volumes?: Record<string, unknown>;\n};\n\nfunction parseConfigJson(configJson: string): SandboxConfig {\n try {\n const raw = JSON.parse(configJson);\n const rawVolumes = raw.volumes ?? raw.mounts;\n const volumes: Record<string, unknown> = {};\n if (Array.isArray(rawVolumes)) {\n for (const mount of rawVolumes) {\n if (mount && typeof mount === \"object\" && \"guest\" in mount) {\n volumes[String(mount.guest)] = mount;\n }\n }\n } else if (rawVolumes && typeof rawVolumes === \"object\") {\n Object.assign(volumes, rawVolumes);\n }\n return {\n name: raw.name ?? \"\",\n image: raw.image ?? \"\",\n memoryMib: raw.memoryMib ?? raw.memory_mib,\n cpus: raw.cpus,\n env: raw.env ?? {},\n volumes,\n };\n } catch {\n return { name: \"\", image: \"\" };\n }\n}\n\nfunction msToIsoString(ms: number | Date | null | undefined): string {\n if (ms == null) return \"\";\n if (ms instanceof Date) return ms.toISOString();\n return new Date(ms).toISOString();\n}\n\ntype MsbInspectEnvVolumes = {\n env: unknown;\n volumes: Record<string, unknown>;\n};\n\nfunction parseMsbInspectEnvVolumes(stdout: string): MsbInspectEnvVolumes {\n const data = JSON.parse(stdout);\n const env = data?.config?.env ?? {};\n\n const volumes: Record<string, unknown> = {};\n const rawMounts = data?.config?.mounts;\n if (Array.isArray(rawMounts)) {\n for (const mount of rawMounts) {\n if (mount && typeof mount === \"object\" && \"guest\" in mount) {\n volumes[String(mount.guest)] = mount;\n }\n }\n }\n\n return { env, volumes };\n}\n\nexport class MicrosandboxRuntimeService {\n constructor(private deps: { registry?: SandboxRegistry } = {}) {}\n\n private get registry(): SandboxRegistry {\n return this.deps.registry ?? (this.deps.registry = new SandboxRegistry());\n }\n\n private resolvePath(path: string): string {\n if (path === \"~\" || path === \"~/\") {\n return \"/\";\n }\n if (path.startsWith(\"~/\")) {\n return `/${path.slice(2)}`;\n }\n return path;\n }\n\n private toListItem(info: {\n name: string;\n status: string;\n configJson: string;\n createdAt?: number | Date | null;\n updatedAt?: number | Date | null;\n }): {\n name: string;\n status: string;\n image: unknown;\n cpus?: number;\n memoryMib?: number;\n envCount: number;\n volumeCount: number;\n createdAt: string;\n updatedAt: string;\n } {\n const config = parseConfigJson(info.configJson);\n const env = config.env ? (Array.isArray(config.env) ? config.env : config.env) : [];\n const envCount = Array.isArray(env) ? env.length : Object.keys(env as Record<string, unknown>).length;\n const volumes = config.volumes ?? {};\n\n return {\n name: info.name,\n status: info.status,\n image: config.image,\n cpus: config.cpus,\n memoryMib: config.memoryMib,\n envCount,\n volumeCount: Object.keys(volumes).length,\n createdAt: msToIsoString(info.createdAt),\n updatedAt: msToIsoString(info.updatedAt),\n };\n }\n\n private async readMsbInspect(name: string): Promise<MsbInspectEnvVolumes | undefined> {\n try {\n const { stdout } = await execAsync(\n `${getMsbPath()} inspect ${name} --format json`,\n { timeout: 5000 }\n );\n return parseMsbInspectEnvVolumes(stdout);\n } catch {\n return undefined;\n }\n }\n\n private async ensureNamedVolumes(volumes?: EnsureSandboxInput[\"volumes\"]): Promise<void> {\n if (!volumes) {\n return;\n }\n\n const defaultQuotaMib = Number(process.env.MICROSANDBOX_VOLUME_QUOTA_MIB ?? \"2048\");\n\n const namedVolumes = Object.values(volumes).filter(\n (v): v is Extract<VolumeConfig, { type: \"named\" }> => v.type === \"named\"\n );\n\n await Promise.all(\n namedVolumes.map(async (definition) => {\n try {\n await Volume.get(definition.name);\n } catch {\n await Volume.builder(definition.name).quota(defaultQuotaMib).create();\n }\n })\n );\n }\n\n private async getOrEnsureNative(name: string): Promise<RuntimeNative> {\n return (await this.registry.ensure(name)) as RuntimeNative;\n }\n\n async ensureSandbox(\n name: string,\n input: EnsureSandboxInput\n ): Promise<{\n name: string;\n status: string;\n }> {\n const image = input.image ?? process.env.MICROSANDBOX_IMAGE ?? \"python:3.11-slim\";\n const cpus = input.cpus ?? Number(process.env.MICROSANDBOX_CPUS ?? \"1\");\n const memoryMib = input.memoryMib ?? Number(process.env.MICROSANDBOX_MEMORY ?? \"512\");\n\n await this.ensureNamedVolumes(input.volumes);\n\n await this.registry.ensure(name, {\n image,\n cpus,\n memoryMib,\n env: input.env,\n volumes: input.volumes,\n });\n\n return {\n name,\n status: \"running\",\n };\n }\n\n async startSandbox(name: string): Promise<{ name: string; status: string }> {\n await this.registry.ensure(name);\n return { name, status: \"running\" };\n }\n\n async stopSandbox(name: string): Promise<{ name: string; status: string }> {\n try {\n const native = await this.getOrEnsureNative(name);\n await native.stop();\n return { name, status: \"stopped\" };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"write to relay\")) {\n return { name, status: \"unknown\" };\n }\n throw error;\n } finally {\n this.registry.remove(name);\n }\n }\n\n async killSandbox(name: string): Promise<{ name: string; status: string }> {\n try {\n const native = await this.getOrEnsureNative(name);\n await native.kill();\n return { name, status: \"unknown\" };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"write to relay\")) {\n return { name, status: \"unknown\" };\n }\n throw error;\n } finally {\n this.registry.remove(name);\n }\n }\n\n async deleteSandbox(name: string): Promise<{ name: string; status: string }> {\n this.registry.remove(name);\n await this.registry.stopAndRemove(name);\n return { name, status: \"unknown\" };\n }\n\n async listSandboxes(_query: ListSandboxesQuery): Promise<{\n items: Array<{\n name: string;\n status: string;\n image: unknown;\n cpus?: number;\n memoryMib?: number;\n envCount: number;\n volumeCount: number;\n createdAt: string;\n updatedAt: string;\n }>;\n total: number;\n }> {\n const all: SandboxHandle[] = await Sandbox.list();\n\n const items = all\n .map((info) =>\n this.toListItem({\n name: info.name,\n status: info.status,\n configJson: info.configJson,\n createdAt: info.createdAt,\n updatedAt: info.updatedAt,\n })\n )\n .filter((item) => {\n if (_query.status && item.status !== _query.status) {\n return false;\n }\n\n if (_query.image && item.image !== _query.image) {\n return false;\n }\n\n if (_query.search) {\n const haystack = [item.name, item.image]\n .filter((value): value is string => Boolean(value))\n .join(\" \")\n .toLowerCase();\n\n if (!haystack.includes(_query.search.toLowerCase())) {\n return false;\n }\n }\n\n return true;\n });\n\n return { items, total: items.length };\n }\n\n async getSandbox(\n name: string\n ): Promise<{\n name: string;\n status: string;\n image: unknown;\n cpus?: number;\n memoryMib?: number;\n env: unknown;\n volumes: Record<string, unknown>;\n metrics?: SandboxRuntimeMetrics;\n createdAt: string;\n updatedAt: string;\n } | undefined> {\n try {\n const handle: SandboxHandle = await Sandbox.get(name);\n const config = parseConfigJson(handle.configJson);\n\n const msbData = await this.readMsbInspect(name);\n const env = msbData?.env ?? config.env ?? {};\n const volumes = msbData?.volumes ?? config.volumes ?? {};\n\n let metrics: SandboxRuntimeMetrics | undefined;\n\n try {\n const m = await handle.metrics();\n metrics = {\n cpuPercent: m.cpuPercent,\n memoryBytes: m.memoryBytes,\n memoryLimitBytes: m.memoryLimitBytes,\n diskReadBytes: m.diskReadBytes,\n diskWriteBytes: m.diskWriteBytes,\n netRxBytes: m.netRxBytes,\n netTxBytes: m.netTxBytes,\n uptimeMs: m.uptimeMs,\n timestampMs: m.timestamp.getTime(),\n };\n } catch {\n metrics = undefined;\n }\n\n return {\n name: handle.name,\n status: handle.status,\n image: config.image,\n cpus: config.cpus,\n memoryMib: config.memoryMib,\n env,\n volumes,\n metrics,\n createdAt: msToIsoString(handle.createdAt),\n updatedAt: msToIsoString(handle.updatedAt),\n };\n } catch {\n return undefined;\n }\n }\n\n async getStatus(name: string): Promise<{ name: string; status: string }> {\n try {\n const handle: SandboxHandle = await Sandbox.get(name);\n return { name, status: handle.status };\n } catch {\n return { name, status: \"unknown\" };\n }\n }\n\n async readFile(sandboxName: string, path: string): Promise<{ path: string; content: string }> {\n const resolvedPath = this.resolvePath(path);\n const native = await this.getOrEnsureNative(sandboxName);\n const fs = native.fs();\n const content = typeof fs.readToString === \"function\"\n ? await fs.readToString(resolvedPath)\n : await fs.readString(resolvedPath);\n return { path: resolvedPath, content };\n }\n\n async writeFile(sandboxName: string, path: string, content: string): Promise<{ path: string }> {\n const resolvedPath = this.resolvePath(path);\n const native = await this.getOrEnsureNative(sandboxName);\n const parts = resolvedPath.split(\"/\").filter(Boolean);\n for (let i = 1; i < parts.length; i++) {\n const dir = \"/\" + parts.slice(0, i).join(\"/\");\n try {\n await native.fs().mkdir(dir);\n } catch {\n // directory may already exist or parent missing, continue\n }\n }\n await native.fs().write(resolvedPath, Buffer.from(content));\n return { path: resolvedPath };\n }\n\n async listPath(\n sandboxName: string,\n path: string,\n recursive?: boolean\n ): Promise<{ entries: Array<{ path: string; type: string }> }> {\n const resolvedPath = this.resolvePath(path);\n const native = await this.getOrEnsureNative(sandboxName);\n const entries = await native.fs().list(resolvedPath);\n return {\n entries: entries.map((entry) => ({\n path: entry.path,\n type: entry.kind,\n })),\n };\n }\n\n async findFiles(sandboxName: string, path: string, pattern: string): Promise<{ files: string[] }> {\n const resolvedPath = this.resolvePath(path);\n const native = await this.getOrEnsureNative(sandboxName);\n const matchFlag = pattern.includes(\"/\") ? \"-path\" : \"-name\";\n const output = await native.exec(\"find\", [resolvedPath, matchFlag, pattern, \"-type\", \"f\"]);\n return { files: output.stdout().split(\"\\n\").filter(Boolean) };\n }\n\n async searchInFile(\n sandboxName: string,\n path: string,\n query: string\n ): Promise<{ matches: Array<{ line: number; content: string }> }> {\n const resolvedPath = this.resolvePath(path);\n const native = await this.getOrEnsureNative(sandboxName);\n let stdout: string;\n\n try {\n const output = await native.exec(\"grep\", [\"-n\", \"-E\", query, resolvedPath]);\n stdout = output.stdout();\n } catch (error) {\n if (typeof error === \"object\" && error !== null && \"code\" in error && error.code === 1) {\n return { matches: [] };\n }\n\n throw error;\n }\n\n return {\n matches: stdout\n .split(\"\\n\")\n .filter(Boolean)\n .map((line) => {\n const separator = line.indexOf(\":\");\n return {\n line: Number(line.slice(0, separator)),\n content: line.slice(separator + 1),\n };\n }),\n };\n }\n\n async replaceInFile(\n sandboxName: string,\n input: { path: string; search: string; replace: string }\n ): Promise<{ replaced: number }> {\n const resolvedPath = this.resolvePath(input.path);\n const native = await this.getOrEnsureNative(sandboxName);\n const fs = native.fs();\n const original = typeof fs.readToString === \"function\"\n ? await fs.readToString(resolvedPath)\n : await fs.readString(resolvedPath);\n\n if (!input.search) {\n return { replaced: 0 };\n }\n\n const occurrences = original.split(input.search).length - 1;\n if (occurrences === 0) {\n return { replaced: 0 };\n }\n\n const updated = original.split(input.search).join(input.replace);\n await fs.write(resolvedPath, Buffer.from(updated));\n\n return { replaced: occurrences };\n }\n\n async uploadFile(sandboxName: string, path: string, contentBase64: string): Promise<{ path: string }> {\n const resolvedPath = this.resolvePath(path);\n const native = await this.getOrEnsureNative(sandboxName);\n await native.fs().write(resolvedPath, Buffer.from(contentBase64, \"base64\"));\n return { path: resolvedPath };\n }\n\n async downloadFile(sandboxName: string, path: string): Promise<{ path: string; contentBase64: string }> {\n const resolvedPath = this.resolvePath(path);\n const native = await this.getOrEnsureNative(sandboxName);\n const data = await native.fs().read(resolvedPath);\n const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data);\n return { path: resolvedPath, contentBase64: buffer.toString(\"base64\") };\n }\n\n async execCommand(input: ShellExecInput): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n const native = await this.getOrEnsureNative(input.sandboxName);\n const output = await native.shell(input.command);\n\n return {\n stdout: output.stdout(),\n stderr: output.stderr(),\n exitCode: output.code ?? 0,\n };\n }\n\n async getSandboxLogs(\n name: string,\n opts: SandboxLogsInput\n ): Promise<{\n entries: Array<{\n timestamp: string;\n source: string;\n sessionId: number | null;\n text: string;\n }>;\n }> {\n const handle: SandboxHandle = await Sandbox.get(name);\n\n const logOpts: { tail?: number; since?: Date; until?: Date; sources?: readonly LogReadSource[] } = {};\n\n if (opts.tail !== undefined) {\n logOpts.tail = opts.tail;\n }\n\n if (opts.since) {\n logOpts.since = new Date(opts.since);\n }\n\n if (opts.until) {\n logOpts.until = new Date(opts.until);\n }\n\n if (opts.sources && opts.sources.length > 0) {\n logOpts.sources = opts.sources as LogReadSource[];\n } else {\n logOpts.sources = [\"all\" as LogReadSource];\n }\n\n const entries = await handle.logs(logOpts);\n\n return {\n entries: entries.map((entry) => ({\n timestamp: entry.timestamp.toISOString(),\n source: entry.source,\n sessionId: entry.sessionId,\n text: entry.text(),\n })),\n };\n }\n}\n","export function getMsbPath(): string {\n return process.env.MICROSANDBOX_CLI_PATH ?? `${process.env.HOME ?? \"/root\"}/.microsandbox/bin/msb`;\n}\n","import cors from \"@fastify/cors\";\nimport multipart from \"@fastify/multipart\";\nimport sensible from \"@fastify/sensible\";\nimport fastify, { type FastifyInstance } from \"fastify\";\nimport { toErrorResponse } from \"./lib/errors\";\nimport { registerHealthRoutes } from \"./routes/health\";\nimport { registerImageRoutes } from \"./routes/images\";\nimport { registerSandboxRoutes } from \"./routes/sandbox\";\nimport { registerVolumeFsRoutes } from \"./routes/volume-fs\";\nimport { ImageService } from \"./services/ImageService\";\nimport { MicrosandboxRuntimeService } from \"./services/MicrosandboxRuntimeService\";\nimport { configureSwagger } from \"./swagger\";\nimport type { RuntimeService } from \"./types/runtime-service\";\n\nexport async function buildApp({\n runtimeService = new MicrosandboxRuntimeService(),\n imageService = new ImageService(),\n apiKey,\n}: {\n runtimeService?: RuntimeService;\n imageService?: ImageService;\n apiKey?: string;\n} = {}): Promise<FastifyInstance> {\n const app = fastify({\n logger: false,\n bodyLimit: Number(process.env.BODY_LIMIT) || 100 * 1024 * 1024,\n });\n\n app.register(cors, {\n delegator: (request, callback) => {\n callback(null, {\n origin: true,\n methods: request.headers[\"access-control-request-method\"] ?? \"*\",\n allowedHeaders: request.headers[\"access-control-request-headers\"],\n });\n },\n });\n app.register(sensible);\n app.register(multipart);\n\n if (apiKey) {\n app.addHook(\"onRequest\", async (request, reply) => {\n if (request.method === \"OPTIONS\" || !request.url.startsWith(\"/api/\")) {\n return;\n }\n\n if (request.headers.authorization !== `Bearer ${apiKey}`) {\n await reply.code(401).send({\n success: false,\n error: {\n code: \"UNAUTHORIZED\",\n message: \"Unauthorized\",\n },\n });\n }\n });\n }\n\n registerHealthRoutes(app);\n registerSandboxRoutes(app, runtimeService);\n registerImageRoutes(app, imageService);\n registerVolumeFsRoutes(app);\n\n app.setErrorHandler((error, _request, reply) => {\n const { statusCode, body } = toErrorResponse(error);\n reply.status(statusCode).send(body);\n });\n\n await configureSwagger(app);\n\n return app;\n}\n","export class HttpError extends Error {\n constructor(\n public statusCode: number,\n public code: string,\n message: string\n ) {\n super(message);\n }\n}\n\nexport function toErrorResponse(error: unknown): {\n statusCode: number;\n body: {\n success: false;\n error: {\n code: string;\n message: string;\n };\n };\n} {\n if (error instanceof HttpError) {\n return {\n statusCode: error.statusCode,\n body: {\n success: false,\n error: {\n code: error.code,\n message: error.message,\n },\n },\n };\n }\n\n return {\n statusCode: 500,\n body: {\n success: false,\n error: {\n code: \"INTERNAL_ERROR\",\n message: error instanceof Error ? error.message : String(error),\n },\n },\n };\n}\n","export type SuccessResponse<T> = {\n success: true;\n data: T;\n};\n\nexport function ok<T>(data: T): SuccessResponse<T> {\n return {\n success: true,\n data,\n };\n}\n","import type { FastifyInstance } from \"fastify\";\nimport { ok } from \"../lib/http\";\n\nexport function registerHealthRoutes(app: FastifyInstance): void {\n app.get(\"/health\", async () => ok({ status: \"ok\" }));\n}\n","import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport { ZodError } from \"zod\";\nimport { HttpError } from \"../lib/errors\";\nimport { ok } from \"../lib/http\";\nimport { ImageService } from \"../services/ImageService\";\nimport { imageRefQuerySchema, pullImageSchema } from \"../schemas/images\";\n\nfunction parseOrThrow<T>(parse: () => T): T {\n try {\n return parse();\n } catch (error) {\n if (error instanceof ZodError) {\n throw new HttpError(400, \"INVALID_REQUEST\", error.issues[0]?.message ?? \"Invalid request\");\n }\n\n throw error;\n }\n}\n\nexport function createImageController(imageService: ImageService) {\n return {\n listImages: async (_request: FastifyRequest, reply: FastifyReply) => {\n return reply.send(ok(await imageService.listImages()));\n },\n pullImage: async (request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply) => {\n const body = parseOrThrow(() => pullImageSchema.parse(request.body ?? {}));\n return reply.send(ok(await imageService.pullImage(body)));\n },\n getImage: async (request: FastifyRequest<{ Querystring: unknown }>, reply: FastifyReply) => {\n const query = parseOrThrow(() => imageRefQuerySchema.parse(request.query ?? {}));\n return reply.send(ok(await imageService.getImage(query.ref)));\n },\n deleteImage: async (request: FastifyRequest<{ Querystring: unknown }>, reply: FastifyReply) => {\n const query = parseOrThrow(() => imageRefQuerySchema.parse(request.query ?? {}));\n return reply.send(ok(await imageService.deleteImage(query.ref)));\n },\n };\n}\n","import z from \"zod\";\n\nexport const imageRefQuerySchema = z.object({\n ref: z.string().min(1),\n});\n\nexport const pullImageSchema = z.object({\n ref: z.string().min(1),\n});\n\nexport type ImageRefQuery = z.infer<typeof imageRefQuerySchema>;\nexport type PullImageInput = z.infer<typeof pullImageSchema>;\n","import type { FastifyInstance } from \"fastify\";\nimport { createImageController } from \"../controllers/images\";\nimport { ImageService } from \"../services/ImageService\";\n\nexport function registerImageRoutes(app: FastifyInstance, imageService: ImageService): void {\n const controller = createImageController(imageService);\n\n app.get(\"/api/images\", controller.listImages);\n app.post(\"/api/images/pull\", controller.pullImage);\n app.get(\"/api/images/detail\", controller.getImage);\n app.delete(\"/api/images/detail\", controller.deleteImage);\n}\n","import z from \"zod\";\n\nconst bindMountSchema = z.object({\n type: z.literal(\"bind\"),\n source: z.string().min(1),\n readonly: z.boolean().optional(),\n});\n\nconst namedMountSchema = z.object({\n type: z.literal(\"named\"),\n name: z.string().min(1),\n readonly: z.boolean().optional(),\n});\n\nconst tmpfsMountSchema = z.object({\n type: z.literal(\"tmpfs\"),\n sizeMib: z.number().int().positive().optional(),\n});\n\nexport const volumeSchema = z.union([\n bindMountSchema,\n namedMountSchema,\n tmpfsMountSchema,\n]);\n\nexport const ensureSandboxSchema = z.object({\n image: z.string().optional(),\n cpus: z.number().int().positive().optional(),\n memoryMib: z.number().int().positive().optional(),\n env: z.record(z.string()).optional(),\n volumes: z.record(volumeSchema).optional(),\n});\n\nexport const sandboxNameParamsSchema = z.object({\n name: z.string().min(1),\n});\n\nexport const listSandboxesQuerySchema = z.object({\n status: z.enum([\"running\", \"stopped\", \"crashed\", \"unknown\"]).optional(),\n image: z.string().min(1).optional(),\n search: z.string().min(1).optional(),\n});\n\nconst sandboxAndPathSchema = z.object({\n sandboxName: z.string().min(1),\n path: z.string().min(1),\n});\n\nexport const readFileSchema = sandboxAndPathSchema;\n\nexport const writeFileSchema = sandboxAndPathSchema.extend({\n content: z.string(),\n});\n\nexport const listPathSchema = sandboxAndPathSchema.extend({\n recursive: z.boolean().optional(),\n});\n\nexport const findFilesSchema = sandboxAndPathSchema.extend({\n pattern: z.string().min(1),\n});\n\nexport const searchInFileSchema = sandboxAndPathSchema.extend({\n query: z.string().min(1),\n});\n\nexport const replaceInFileSchema = sandboxAndPathSchema.extend({\n search: z.string(),\n replace: z.string(),\n});\n\nexport const uploadFileSchema = sandboxAndPathSchema.and(\n z.union([\n z.object({ contentBase64: z.string() }),\n z.object({ content: z.string().transform((content) => Buffer.from(content).toString(\"base64\")) }),\n ])\n);\n\nexport const downloadFileSchema = sandboxAndPathSchema;\n\nexport const shellExecSchema = z.object({\n sandboxName: z.string().min(1),\n command: z.string().min(1),\n exec_dir: z.string().optional(),\n timeout: z.number().int().positive().optional(),\n});\n\nexport const sandboxLogsSchema = z.object({\n tail: z.number().int().positive().optional(),\n since: z.string().optional(),\n until: z.string().optional(),\n sources: z.array(z.string()).optional(),\n});\n\nexport type EnsureSandboxInput = z.infer<typeof ensureSandboxSchema>;\nexport type ListSandboxesQuery = z.infer<typeof listSandboxesQuerySchema>;\nexport type ShellExecInput = z.infer<typeof shellExecSchema>;\nexport type SandboxLogsInput = z.infer<typeof sandboxLogsSchema>;\n","import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport {\n downloadFileSchema,\n ensureSandboxSchema,\n findFilesSchema,\n listSandboxesQuerySchema,\n listPathSchema,\n readFileSchema,\n replaceInFileSchema,\n sandboxLogsSchema,\n sandboxNameParamsSchema,\n searchInFileSchema,\n shellExecSchema,\n uploadFileSchema,\n writeFileSchema,\n} from \"../schemas/sandbox\";\nimport { HttpError } from \"../lib/errors\";\nimport { ok } from \"../lib/http\";\nimport type { RuntimeService } from \"../types/runtime-service\";\n\nexport function createSandboxController(runtimeService: RuntimeService): {\n ensureSandbox(\n request: FastifyRequest<{ Params: { name: string }; Body: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n startSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n stopSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n killSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n deleteSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n listSandboxes(\n request: FastifyRequest<{ Querystring: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n getSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n getStatus(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n getSandboxLogs(\n request: FastifyRequest<{ Params: { name: string }; Body: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n readFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n writeFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n listPath(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n findFiles(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n searchInFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n replaceInFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n uploadFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n downloadFile(\n request: FastifyRequest<{ Querystring: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n execCommand(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n} {\n return {\n ensureSandbox: async (\n request: FastifyRequest<{ Params: { name: string }; Body: unknown }>,\n reply: FastifyReply\n ) => {\n const body = ensureSandboxSchema.parse(request.body ?? {});\n const result = await runtimeService.ensureSandbox(request.params.name, body);\n return reply.send(ok(result));\n },\n\n startSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.startSandbox(request.params.name)));\n },\n\n stopSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.stopSandbox(request.params.name)));\n },\n\n killSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.killSandbox(request.params.name)));\n },\n\n deleteSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.deleteSandbox(request.params.name)));\n },\n\n listSandboxes: async (request, reply) => {\n const query = listSandboxesQuerySchema.parse(request.query ?? {});\n return reply.send(ok(await runtimeService.listSandboxes(query)));\n },\n\n getSandbox: async (request, reply) => {\n const params = sandboxNameParamsSchema.parse(request.params ?? {});\n const sandbox = await runtimeService.getSandbox(params.name);\n\n if (!sandbox) {\n throw new HttpError(404, \"SANDBOX_NOT_FOUND\", `Sandbox '${params.name}' not found`);\n }\n\n return reply.send(ok(sandbox));\n },\n\n getStatus: async (request, reply) => {\n return reply.send(ok(await runtimeService.getStatus(request.params.name)));\n },\n\n getSandboxLogs: async (request, reply) => {\n const body = sandboxLogsSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.getSandboxLogs(request.params.name, body)));\n },\n\n readFile: async (request, reply) => {\n const body = readFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.readFile(body.sandboxName, body.path)));\n },\n\n writeFile: async (request, reply) => {\n const body = writeFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.writeFile(body.sandboxName, body.path, body.content)));\n },\n\n listPath: async (request, reply) => {\n const body = listPathSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.listPath(body.sandboxName, body.path, body.recursive)));\n },\n\n findFiles: async (request, reply) => {\n const body = findFilesSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.findFiles(body.sandboxName, body.path, body.pattern)));\n },\n\n searchInFile: async (request, reply) => {\n const body = searchInFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.searchInFile(body.sandboxName, body.path, body.query)));\n },\n\n replaceInFile: async (request, reply) => {\n const body = replaceInFileSchema.parse(request.body ?? {});\n return reply.send(\n ok(\n await runtimeService.replaceInFile(body.sandboxName, {\n path: body.path,\n search: body.search,\n replace: body.replace,\n })\n )\n );\n },\n\n uploadFile: async (request, reply) => {\n const body = uploadFileSchema.parse(request.body ?? {});\n const contentBase64 = \"contentBase64\" in body ? body.contentBase64 : Buffer.from(body.content).toString(\"base64\");\n return reply.send(ok(await runtimeService.uploadFile(body.sandboxName, body.path, contentBase64)));\n },\n\n downloadFile: async (request, reply) => {\n const query = downloadFileSchema.parse(request.query ?? {});\n return reply.send(ok(await runtimeService.downloadFile(query.sandboxName, query.path)));\n },\n\n execCommand: async (request, reply) => {\n const body = shellExecSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.execCommand(body)));\n },\n };\n}\n","import type { FastifyInstance } from \"fastify\";\nimport { createSandboxController } from \"../controllers/sandbox\";\nimport type { RuntimeService } from \"../types/runtime-service\";\n\nexport function registerSandboxRoutes(\n app: FastifyInstance,\n runtimeService: RuntimeService\n): void {\n const controller = createSandboxController(runtimeService);\n\n app.get(\"/api/sandboxes\", controller.listSandboxes);\n app.get(\"/api/sandboxes/:name\", controller.getSandbox);\n app.put(\"/api/sandboxes/:name\", controller.ensureSandbox);\n app.post(\"/api/sandboxes/:name/start\", controller.startSandbox);\n app.post(\"/api/sandboxes/:name/stop\", controller.stopSandbox);\n app.post(\"/api/sandboxes/:name/kill\", controller.killSandbox);\n app.delete(\"/api/sandboxes/:name\", controller.deleteSandbox);\n app.get(\"/api/sandboxes/:name/status\", controller.getStatus);\n app.post(\"/api/sandboxes/:name/logs\", controller.getSandboxLogs);\n\n app.post(\"/api/files/read\", controller.readFile);\n app.post(\"/api/files/write\", controller.writeFile);\n app.post(\"/api/files/list\", controller.listPath);\n app.post(\"/api/files/find\", controller.findFiles);\n app.post(\"/api/files/search\", controller.searchInFile);\n app.post(\"/api/files/replace\", controller.replaceInFile);\n app.post(\"/api/files/upload\", controller.uploadFile);\n app.get(\"/api/files/download\", controller.downloadFile);\n\n app.post(\"/api/shell/exec\", controller.execCommand);\n}\n","import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport fs from \"fs/promises\";\nimport os from \"os\";\nimport path from \"path\";\nimport { Volume } from \"microsandbox\";\nimport z from \"zod\";\nimport { HttpError } from \"../lib/errors\";\nimport { ok } from \"../lib/http\";\nimport {\n volumeFsReadSchema,\n volumeFsWriteSchema,\n volumeFsListSchema,\n volumeFsUploadSchema,\n volumeFsDownloadSchema,\n} from \"../schemas/volume-fs\";\n\ninterface VolumeFsParams {\n name: string;\n}\n\nconst MSB_DATA_DIR = path.join(os.homedir(), \".microsandbox\");\n\nasync function resolveVolumeHostPath(name: string): Promise<string> {\n try {\n const handle = await Volume.get(name);\n const vol = await Volume.builder(handle.name).create();\n return vol.path;\n } catch {\n try {\n const vol = await Volume.builder(name).create();\n return vol.path;\n } catch {\n return path.join(MSB_DATA_DIR, \"volumes\", name);\n }\n }\n}\n\nfunction resolveGuestPath(hostRoot: string, guestPath: string): string {\n const normalized = guestPath === \"~\" ? \"\" : guestPath.replace(/^~\\//, \"\");\n const resolved = path.join(hostRoot, path.normalize(normalized).replace(/^(\\.\\.(\\/|\\\\|$))+/, \"\"));\n if (!resolved.startsWith(hostRoot + path.sep) && resolved !== hostRoot) {\n throw new HttpError(403, \"PATH_TRAVERSAL\", \"Path traversal detected\");\n }\n return resolved;\n}\n\nexport function createVolumeFsController(): {\n readFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n writeFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string; content: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n listPath(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n downloadFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Querystring: { path: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n uploadFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string; contentBase64: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n} {\n return {\n readFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath } = volumeFsReadSchema.parse(request.body ?? {});\n const hostRoot = await resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n const content = await fs.readFile(fullPath, \"utf-8\");\n return reply.send(ok({ path: guestPath, content }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(404, \"VOLUME_READ_ERROR\", `Failed to read from volume '${name}': ${String(err)}`);\n }\n },\n\n writeFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath, content } = volumeFsWriteSchema.parse(request.body ?? {});\n const hostRoot = await resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n await fs.writeFile(fullPath, content, \"utf-8\");\n return reply.send(ok({ path: guestPath }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(500, \"VOLUME_WRITE_ERROR\", `Failed to write to volume '${name}': ${String(err)}`);\n }\n },\n\n listPath: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath } = volumeFsListSchema.parse(request.body ?? {});\n const hostRoot = await resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n const dirents = await fs.readdir(fullPath, { withFileTypes: true });\n const entries = dirents.map((d) => ({\n path: guestPath ? `${guestPath}/${d.name}` : d.name,\n kind: d.isDirectory() ? \"directory\" : d.isSymbolicLink() ? \"symlink\" : \"file\",\n size: 0,\n mode: 0,\n }));\n return reply.send(ok({ entries }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(404, \"VOLUME_LIST_ERROR\", `Failed to list volume '${name}': ${String(err)}`);\n }\n },\n\n downloadFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath } = volumeFsDownloadSchema.parse(request.query ?? {});\n const hostRoot = await resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n const buf = await fs.readFile(fullPath);\n const contentBase64 = buf.toString(\"base64\");\n return reply.send(ok({ path: guestPath, contentBase64 }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(404, \"VOLUME_DOWNLOAD_ERROR\", `Failed to download from volume '${name}': ${String(err)}`);\n }\n },\n\n uploadFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath, contentBase64 } = volumeFsUploadSchema.parse(request.body ?? {});\n const hostRoot = await resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n const data = Buffer.from(contentBase64, \"base64\");\n await fs.writeFile(fullPath, data);\n return reply.send(ok({ path: guestPath }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(500, \"VOLUME_UPLOAD_ERROR\", `Failed to upload to volume '${name}': ${String(err)}`);\n }\n },\n };\n}\n","import z from \"zod\";\n\nexport const volumeFsReadSchema = z.object({\n path: z.string(),\n});\n\nexport const volumeFsWriteSchema = z.object({\n path: z.string(),\n content: z.string(),\n});\n\nexport const volumeFsListSchema = z.object({\n path: z.string(),\n});\n\nexport const volumeFsUploadSchema = z.object({\n path: z.string(),\n contentBase64: z.string().min(1),\n});\n\nexport const volumeFsDownloadSchema = z.object({\n path: z.string(),\n});\n","import type { FastifyInstance } from \"fastify\";\nimport { createVolumeFsController } from \"../controllers/volume-fs\";\n\nexport function registerVolumeFsRoutes(app: FastifyInstance): void {\n const controller = createVolumeFsController();\n\n app.post(\"/api/volumes/:name/fs/read\", controller.readFile);\n app.post(\"/api/volumes/:name/fs/write\", controller.writeFile);\n app.post(\"/api/volumes/:name/fs/list\", controller.listPath);\n app.get(\"/api/volumes/:name/fs/download\", controller.downloadFile);\n app.post(\"/api/volumes/:name/fs/upload\", controller.uploadFile);\n}\n","import { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { PullImageInput } from \"../schemas/images\";\nimport { getMsbPath } from \"../lib/msb\";\n\nconst execAsync = promisify(exec);\n\nexport type ImageRecord = {\n ref: string;\n sourceType: string;\n cached: boolean;\n size?: number;\n createdAt?: string;\n lastUsedAt?: string;\n};\n\ntype ImageBindings = {\n list(): Promise<ImageRecord[]>;\n pull(ref: string): Promise<ImageRecord>;\n inspect(ref: string): Promise<ImageRecord>;\n remove(ref: string): Promise<void>;\n};\n\ntype CliImageInfo = {\n architecture: string;\n created_at: string;\n digest: string;\n layer_count: number;\n os: string;\n reference: string;\n size_bytes: number;\n};\n\nclass MicrosandboxImageBindings implements ImageBindings {\n private get msb(): string {\n return getMsbPath();\n }\n\n async list(): Promise<ImageRecord[]> {\n const { stdout } = await execAsync(`${this.msb} image ls --format json`);\n const images: CliImageInfo[] = JSON.parse(stdout);\n return images.map((img) => ({\n ref: img.reference,\n sourceType: \"oci\",\n cached: true,\n size: img.size_bytes,\n createdAt: img.created_at,\n }));\n }\n\n async pull(ref: string): Promise<ImageRecord> {\n await execAsync(`${this.msb} image pull ${ref}`);\n return this.inspect(ref);\n }\n\n async inspect(ref: string): Promise<ImageRecord> {\n const { stdout } = await execAsync(`${this.msb} image inspect ${ref} --format json`);\n const img: CliImageInfo = JSON.parse(stdout);\n return {\n ref: img.reference,\n sourceType: \"oci\",\n cached: true,\n size: img.size_bytes,\n createdAt: img.created_at,\n };\n }\n\n async remove(ref: string): Promise<void> {\n await execAsync(`${this.msb} image rm ${ref}`);\n }\n}\n\nexport class ImageService {\n constructor(\n private readonly deps: {\n bindings?: ImageBindings;\n } = {}\n ) {}\n\n private get bindings(): ImageBindings {\n return this.deps.bindings ?? new MicrosandboxImageBindings();\n }\n\n async listImages(): Promise<{ items: ImageRecord[]; total: number }> {\n const items = await this.bindings.list();\n return { items, total: items.length };\n }\n\n async pullImage(input: PullImageInput): Promise<ImageRecord> {\n return await this.bindings.pull(input.ref);\n }\n\n async getImage(ref: string): Promise<ImageRecord> {\n return await this.bindings.inspect(ref);\n }\n\n async deleteImage(ref: string): Promise<{ ref: string }> {\n await this.bindings.remove(ref);\n return { ref };\n }\n}\n","import type { FastifyInstance } from \"fastify\";\nimport swagger from \"@fastify/swagger\";\nimport swaggerUi from \"@fastify/swagger-ui\";\n\nexport const defaultSwaggerConfig = {\n openapi: {\n openapi: \"3.0.0\",\n info: {\n title: \"Microsandbox Service API\",\n description:\n \"Sandbox lifecycle management, file operations, shell execution, and image registry\",\n version: \"1.0.0\",\n },\n servers: [\n {\n url: \"http://localhost:4002\",\n description: \"Local development\",\n },\n ],\n components: {\n securitySchemes: {\n bearerAuth: {\n type: \"http\" as const,\n scheme: \"bearer\" as const,\n bearerFormat: \"API Key\",\n },\n },\n },\n tags: [\n { name: \"Sandboxes\", description: \"Sandbox lifecycle (CRUD, start, stop, kill)\" },\n { name: \"Files\", description: \"Read, write, list, search, upload, download files inside sandboxes\" },\n { name: \"Shell\", description: \"Execute commands inside sandboxes\" },\n { name: \"Images\", description: \"OCI image management (list, pull, inspect, delete)\" },\n { name: \"Volumes\", description: \"Named volume filesystem operations\" },\n { name: \"Health\", description: \"Service health check\" },\n ],\n },\n};\n\nexport const defaultSwaggerUiConfig = {\n routePrefix: \"/api-docs\",\n uiConfig: {\n docExpansion: \"list\" as const,\n deepLinking: true,\n },\n staticCSP: true,\n transformStaticCSP: (header: string) => header,\n};\n\nexport async function configureSwagger(\n app: FastifyInstance,\n customSwaggerConfig?: Partial<typeof defaultSwaggerConfig>,\n customSwaggerUiConfig?: Partial<typeof defaultSwaggerUiConfig>\n) {\n const swaggerConfig = { ...defaultSwaggerConfig, ...customSwaggerConfig };\n const swaggerUiConfig = {\n ...defaultSwaggerUiConfig,\n ...customSwaggerUiConfig,\n };\n\n await app.register(swagger, swaggerConfig);\n await app.register(swaggerUi, swaggerUiConfig);\n}\n"],"mappings":"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","names":["path","fs","Sandbox","path","Sandbox","fs","z","Volume","z","z","Volume","z","exec","promisify","execAsync","promisify","exec"]}
package/dist/cli.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startServer
4
- } from "./chunk-62MHJDP4.mjs";
5
- import "./chunk-XKHPYRQU.mjs";
4
+ } from "./chunk-5F6UN2VW.mjs";
5
+ import "./chunk-KVJG7R3I.mjs";
6
6
 
7
7
  // src/cli.ts
8
8
  void startServer().catch((error) => {
package/dist/index.d.mts CHANGED
@@ -292,7 +292,10 @@ declare function buildApp({ runtimeService, imageService, apiKey, }?: {
292
292
  declare class SandboxRegistry {
293
293
  private handles;
294
294
  private creating;
295
+ constructor();
295
296
  remove(name: string): void;
297
+ cleanupOrphanedSockets(): void;
298
+ stopAndRemove(name: string): Promise<void>;
296
299
  private waitForFs;
297
300
  private hasConfigMismatch;
298
301
  ensure(name: string, createOptions?: Record<string, unknown>): Promise<unknown>;
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  MicrosandboxRuntimeService,
3
3
  SandboxRegistry,
4
4
  buildApp
5
- } from "./chunk-XKHPYRQU.mjs";
5
+ } from "./chunk-KVJG7R3I.mjs";
6
6
  export {
7
7
  MicrosandboxRuntimeService,
8
8
  SandboxRegistry,
package/dist/server.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  startServer
3
- } from "./chunk-62MHJDP4.mjs";
4
- import "./chunk-XKHPYRQU.mjs";
3
+ } from "./chunk-5F6UN2VW.mjs";
4
+ import "./chunk-KVJG7R3I.mjs";
5
5
  export {
6
6
  startServer
7
7
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiom-lattice/microsandbox-service",
3
- "version": "0.0.46",
3
+ "version": "0.0.48",
4
4
  "main": "dist/index.mjs",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -31,7 +31,7 @@
31
31
  "@fastify/swagger": "^9.5.1",
32
32
  "@fastify/swagger-ui": "^5.2.3",
33
33
  "fastify": "^5.5.0",
34
- "microsandbox": "^0.5.10",
34
+ "microsandbox": "^0.6.2",
35
35
  "zod": "3.25.76"
36
36
  },
37
37
  "devDependencies": {
@@ -107,7 +107,7 @@ describe("SandboxRegistry", () => {
107
107
  expect(createDetached).toHaveBeenCalled();
108
108
  });
109
109
 
110
- it("removes draining sandboxes and recreates them", async () => {
110
+ it("removes draining sandboxes and recreates them with createOptions", async () => {
111
111
  const native = makeNative("created");
112
112
 
113
113
  (Sandbox.get as jest.Mock).mockResolvedValue({
@@ -118,23 +118,18 @@ describe("SandboxRegistry", () => {
118
118
 
119
119
  const registry = new SandboxRegistry();
120
120
 
121
- await registry.ensure("tenant-d");
121
+ await registry.ensure("tenant-d", { image: "python:3.11-slim" });
122
122
 
123
123
  expect(Sandbox.remove).toHaveBeenCalledWith("tenant-d");
124
124
  expect(createDetached).toHaveBeenCalled();
125
125
  });
126
126
 
127
- it("uses the current default image when creating a sandbox without an explicit image", async () => {
128
- const native = makeNative("created");
129
-
127
+ it("throws NOT_FOUND when ensure is called without createOptions and sandbox does not exist", async () => {
130
128
  (Sandbox.get as jest.Mock).mockRejectedValue(new Error("not found"));
131
- createDetached.mockResolvedValue(native);
132
129
 
133
130
  const registry = new SandboxRegistry();
134
131
 
135
- await registry.ensure("tenant-f");
136
-
137
- expect(createDetached).toHaveBeenCalled();
132
+ await expect(registry.ensure("tenant-f")).rejects.toThrow("Sandbox tenant-f not found");
138
133
  });
139
134
 
140
135
  it("creates a fresh handle after cache invalidation", async () => {
@@ -254,7 +254,7 @@ export class MicrosandboxRuntimeService {
254
254
 
255
255
  async deleteSandbox(name: string): Promise<{ name: string; status: string }> {
256
256
  this.registry.remove(name);
257
- await Sandbox.remove(name);
257
+ await this.registry.stopAndRemove(name);
258
258
  return { name, status: "unknown" };
259
259
  }
260
260
 
@@ -1,8 +1,11 @@
1
1
  import { Sandbox, MountBuilder } from "microsandbox";
2
2
  import type { SandboxHandle } from "microsandbox";
3
+ import { readdirSync, readFileSync, unlinkSync } from "fs";
4
+ import { join } from "path";
3
5
 
4
6
  const DEFAULT_IMAGE = process.env.MICROSANDBOX_IMAGE ?? "daytonaio/sandbox:0.6.0";
5
7
  const CACHE_TTL_MS = 300_000;
8
+ const SANDBOX_AGENT_SOCKET_DIR = "/root/.microsandbox/run/agent";
6
9
 
7
10
  function extractConfig(configJson: string): {
8
11
  image: string;
@@ -42,11 +45,53 @@ export class SandboxRegistry {
42
45
  private handles = new Map<string, { native: unknown; expiresAt: number; createOptions?: Record<string, unknown> }>();
43
46
  private creating = new Map<string, Promise<unknown>>();
44
47
 
48
+ constructor() {
49
+ this.cleanupOrphanedSockets();
50
+ }
51
+
45
52
  remove(name: string): void {
46
53
  this.handles.delete(name);
47
54
  this.creating.delete(name);
48
55
  }
49
56
 
57
+ cleanupOrphanedSockets(): void {
58
+ try {
59
+ const activeSockets = new Set<string>();
60
+ const unixSockets = readFileSync("/proc/net/unix", "utf-8");
61
+ for (const line of unixSockets.split("\n")) {
62
+ const path = line.trim().split(" ").pop();
63
+ if (path && path.startsWith(SANDBOX_AGENT_SOCKET_DIR)) {
64
+ activeSockets.add(path);
65
+ }
66
+ }
67
+ for (const entry of readdirSync(SANDBOX_AGENT_SOCKET_DIR)) {
68
+ const fullPath = join(SANDBOX_AGENT_SOCKET_DIR, entry);
69
+ if (!activeSockets.has(fullPath)) {
70
+ unlinkSync(fullPath);
71
+ console.log(`[SandboxRegistry] removed orphaned socket: ${entry}`);
72
+ }
73
+ }
74
+ } catch (err) {
75
+ if ((err as NodeJS.ErrnoException).code !== "ENOENT") {
76
+ console.log(`[SandboxRegistry] socket cleanup skipped: ${(err as Error).message}`);
77
+ }
78
+ }
79
+ }
80
+
81
+ async stopAndRemove(name: string): Promise<void> {
82
+ try {
83
+ const handle = await Sandbox.get(name);
84
+ if (handle.status === "running") {
85
+ try {
86
+ const native = await handle.connect();
87
+ await (native as { stop(): Promise<void> }).stop();
88
+ } catch { /* ignore */ }
89
+ }
90
+ await Sandbox.remove(name);
91
+ } catch { /* ignore */ }
92
+ this.cleanupOrphanedSockets();
93
+ }
94
+
50
95
  private async waitForFs(native: unknown, maxRetries = 10): Promise<void> {
51
96
  const fs = (native as { fs(): { list(path: string): Promise<unknown> } }).fs();
52
97
  for (let i = 0; i < maxRetries; i++) {
@@ -127,8 +172,9 @@ export class SandboxRegistry {
127
172
  originalConfig = extractConfig(handle.configJson);
128
173
 
129
174
  if (handle.status === "running" || handle.status === "stopped") {
130
- if (createOptions && this.hasConfigMismatch(originalConfig, createOptions)) {
131
- try { await Sandbox.remove(name); } catch { /* ignore */ }
175
+ const isNewConnection = !cached;
176
+ if (isNewConnection && createOptions && this.hasConfigMismatch(originalConfig, createOptions)) {
177
+ await this.stopAndRemove(name);
132
178
  native = undefined;
133
179
  } else if (handle.status === "running") {
134
180
  const tConnect = Date.now();
@@ -147,14 +193,14 @@ export class SandboxRegistry {
147
193
  console.log(`[SandboxRegistry] waitForFs name=${name} elapsed=${Date.now() - tFs}ms`);
148
194
  } catch {
149
195
  if (!native) {
150
- try { await Sandbox.remove(name); } catch { /* already running */ }
196
+ await this.stopAndRemove(name);
151
197
  }
152
198
  }
153
199
  }
154
200
  } else if (handle.status === "crashed" || handle.status === "draining") {
155
- await Sandbox.remove(name);
201
+ await this.stopAndRemove(name);
156
202
  } else {
157
- await Sandbox.remove(name);
203
+ await this.stopAndRemove(name);
158
204
  }
159
205
  } catch {
160
206
  native = undefined;
@@ -244,7 +290,7 @@ export class SandboxRegistry {
244
290
  native = await tryCreate();
245
291
  } catch (err) {
246
292
  if (err instanceof Error && err.message.includes("already exists")) {
247
- await Sandbox.remove(name);
293
+ await this.stopAndRemove(name);
248
294
  native = await tryCreate();
249
295
  } else {
250
296
  throw err;
@@ -263,6 +309,7 @@ export class SandboxRegistry {
263
309
  })();
264
310
 
265
311
  this.creating.set(name, creation);
312
+ creation.catch(() => {});
266
313
  void creation.finally(() => this.creating.delete(name));
267
314
 
268
315
  return creation;
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/services/SandboxRegistry.ts","../src/services/MicrosandboxRuntimeService.ts","../src/lib/msb.ts","../src/app.ts","../src/lib/errors.ts","../src/lib/http.ts","../src/routes/health.ts","../src/controllers/images.ts","../src/schemas/images.ts","../src/routes/images.ts","../src/schemas/sandbox.ts","../src/controllers/sandbox.ts","../src/routes/sandbox.ts","../src/controllers/volume-fs.ts","../src/schemas/volume-fs.ts","../src/routes/volume-fs.ts","../src/services/ImageService.ts","../src/swagger.ts"],"sourcesContent":["import { Sandbox, MountBuilder } from \"microsandbox\";\nimport type { SandboxHandle } from \"microsandbox\";\n\nconst DEFAULT_IMAGE = process.env.MICROSANDBOX_IMAGE ?? \"daytonaio/sandbox:0.6.0\";\nconst CACHE_TTL_MS = 300_000;\n\nfunction extractConfig(configJson: string): {\n image: string;\n cpus: number;\n memoryMib: number;\n env: Record<string, string>;\n mounts: Array<{ guest: string; type: string; source?: string; name?: string; size_mib?: number; readonly?: boolean }>;\n} | undefined {\n try {\n const raw = JSON.parse(configJson);\n const image = typeof raw.image === \"string\" ? raw.image\n : raw.image?.Oci?.reference ?? \"\";\n const env: Record<string, string> = {};\n const rawEnv = raw.env;\n if (Array.isArray(rawEnv)) {\n for (const entry of rawEnv) {\n if (Array.isArray(entry) && entry.length >= 2) {\n env[String(entry[0])] = String(entry[1]);\n }\n }\n } else if (rawEnv && typeof rawEnv === \"object\") {\n Object.assign(env, rawEnv);\n }\n return {\n image,\n cpus: raw.cpus ?? 1,\n memoryMib: raw.memory_mib ?? raw.memoryMib ?? 512,\n env,\n mounts: Array.isArray(raw.mounts) ? raw.mounts : [],\n };\n } catch {\n return undefined;\n }\n}\n\nexport class SandboxRegistry {\n private handles = new Map<string, { native: unknown; expiresAt: number; createOptions?: Record<string, unknown> }>();\n private creating = new Map<string, Promise<unknown>>();\n\n remove(name: string): void {\n this.handles.delete(name);\n this.creating.delete(name);\n }\n\n private async waitForFs(native: unknown, maxRetries = 10): Promise<void> {\n const fs = (native as { fs(): { list(path: string): Promise<unknown> } }).fs();\n for (let i = 0; i < maxRetries; i++) {\n try {\n await fs.list(\"/\");\n return;\n } catch {\n await new Promise((r) => setTimeout(r, 200));\n }\n }\n throw new Error(\"FS not ready after start\");\n }\n\n private hasConfigMismatch(\n originalConfig: ReturnType<typeof extractConfig>,\n createOptions: Record<string, unknown>\n ): boolean {\n const volumeDefs = createOptions.volumes as Record<string, { type: string }> | undefined;\n const requestEnv = createOptions.env as Record<string, string> | undefined;\n\n if (volumeDefs && Object.keys(volumeDefs).length > 0) {\n const existingGuests = new Set((originalConfig?.mounts ?? []).map((m: { guest: string }) => m.guest));\n const requestedGuests = new Set(Object.keys(volumeDefs));\n if (existingGuests.size !== requestedGuests.size ||\n ![...requestedGuests].every(g => existingGuests.has(g))) {\n console.log(`[SandboxRegistry] volumes mismatch, recreating...`);\n return true;\n }\n }\n\n if (requestEnv && originalConfig?.env) {\n for (const [key, value] of Object.entries(requestEnv)) {\n if (originalConfig.env[key] !== value) {\n console.log(`[SandboxRegistry] env mismatch (key=${key}), recreating...`);\n return true;\n }\n }\n }\n\n return false;\n }\n\n async ensure(name: string, createOptions?: Record<string, unknown>): Promise<unknown> {\n const tStart = Date.now();\n\n const cached = this.handles.get(name);\n if (cached && Date.now() < cached.expiresAt) {\n cached.expiresAt = Date.now() + CACHE_TTL_MS;\n console.log(`[SandboxRegistry] ensure name=${name} CACHE_HIT elapsed=${Date.now() - tStart}ms`);\n return cached.native;\n }\n\n if (cached) {\n console.log(`[SandboxRegistry] ensure name=${name} TTL_EXPIRED elapsed=${Date.now() - tStart}ms reconnect...`);\n }\n\n const inflight = this.creating.get(name);\n if (inflight) {\n console.log(`[SandboxRegistry] ensure name=${name} AWAITING_INFLIGHT`);\n return inflight;\n }\n\n const creation = (async () => {\n const tCreate = Date.now();\n let native: unknown;\n const image = (createOptions?.image as string) ?? DEFAULT_IMAGE;\n const cpus = (createOptions?.cpus as number) ?? 1;\n const memoryMib = (createOptions?.memoryMib as number) ?? 512;\n const env = (createOptions?.env as Record<string, string>) ?? undefined;\n\n let originalConfig: ReturnType<typeof extractConfig>;\n\n try {\n const tGet = Date.now();\n const handle: SandboxHandle = await Sandbox.get(name);\n console.log(`[SandboxRegistry] Sandbox.get name=${name} status=${handle.status} elapsed=${Date.now() - tGet}ms`);\n\n originalConfig = extractConfig(handle.configJson);\n\n if (handle.status === \"running\" || handle.status === \"stopped\") {\n if (createOptions && this.hasConfigMismatch(originalConfig, createOptions)) {\n try { await Sandbox.remove(name); } catch { /* ignore */ }\n native = undefined;\n } else if (handle.status === \"running\") {\n const tConnect = Date.now();\n native = await handle.connect();\n console.log(`[SandboxRegistry] handle.connect name=${name} elapsed=${Date.now() - tConnect}ms`);\n const tFs = Date.now();\n await this.waitForFs(native);\n console.log(`[SandboxRegistry] waitForFs name=${name} elapsed=${Date.now() - tFs}ms`);\n } else {\n try {\n const tStart2 = Date.now();\n native = await Sandbox.startDetached(name);\n console.log(`[SandboxRegistry] startDetached name=${name} elapsed=${Date.now() - tStart2}ms`);\n const tFs = Date.now();\n await this.waitForFs(native);\n console.log(`[SandboxRegistry] waitForFs name=${name} elapsed=${Date.now() - tFs}ms`);\n } catch {\n if (!native) {\n try { await Sandbox.remove(name); } catch { /* already running */ }\n }\n }\n }\n } else if (handle.status === \"crashed\" || handle.status === \"draining\") {\n await Sandbox.remove(name);\n } else {\n await Sandbox.remove(name);\n }\n } catch {\n native = undefined;\n }\n console.log(`[SandboxRegistry] phase=existing_check name=${name} hasNative=${!!native} elapsed=${Date.now() - tCreate}ms`);\n\n if (!native) {\n const effectiveOptions = createOptions ?? cached?.createOptions;\n if (!effectiveOptions) {\n console.log(`[SandboxRegistry] ensure name=${name} NOT_FOUND elapsed=${Date.now() - tStart}ms`);\n throw new Error(`Sandbox ${name} not found`);\n }\n if (!createOptions && cached?.createOptions) {\n console.log(`[SandboxRegistry] ensure name=${name} RECOVER_OPTIONS elapsed=${Date.now() - tStart}ms`);\n }\n const tBuild = Date.now();\n const volumeDefs = effectiveOptions?.volumes as Record<string, { type: string; source?: string; name?: string; sizeMib?: number; readonly?: boolean }> | undefined;\n const resolvedImage = (effectiveOptions?.image as string) ?? originalConfig?.image ?? image;\n console.log(\n `[SandboxRegistry] create sandbox=${name} image=${resolvedImage} ` +\n `from=${(effectiveOptions?.image as string) ? \"request\" : originalConfig?.image ? \"originalConfig\" : \"default\"}`\n );\n const resolvedCpus = (effectiveOptions?.cpus as number) ?? originalConfig?.cpus ?? cpus;\n const resolvedMemoryMib = (effectiveOptions?.memoryMib as number) ?? originalConfig?.memoryMib ?? memoryMib;\n const resolvedEnv = (effectiveOptions?.env as Record<string, string>) ?? originalConfig?.env ?? env;\n const resolvedMounts = originalConfig?.mounts ?? [];\n\n const applyVolumes = (b: ReturnType<typeof Sandbox.builder>): void => {\n if (volumeDefs) {\n for (const [guestPath, def] of Object.entries(volumeDefs)) {\n const mb = new MountBuilder(guestPath);\n if (def.type === \"bind\" && def.source) {\n mb.bind(def.source);\n } else if (def.type === \"named\" && def.name) {\n mb.named(def.name);\n } else if (def.type === \"tmpfs\") {\n mb.tmpfs();\n if (def.sizeMib) {\n mb.size(def.sizeMib);\n }\n }\n if (def.readonly) {\n mb.readonly();\n }\n b.volume(guestPath, () => mb);\n }\n } else {\n for (const mount of resolvedMounts) {\n const mb = new MountBuilder(mount.guest);\n if (mount.type === \"Bind\" || mount.type === \"bind\") {\n if (mount.source) mb.bind(mount.source);\n } else if (mount.type === \"Named\" || mount.type === \"named\") {\n if (mount.name) mb.named(mount.name);\n } else if (mount.type === \"Tmpfs\" || mount.type === \"tmpfs\") {\n mb.tmpfs();\n if (mount.size_mib) mb.size(mount.size_mib);\n }\n if (mount.readonly) {\n mb.readonly();\n }\n b.volume(mount.guest, () => mb);\n }\n }\n };\n\n const tryCreate = async () => {\n const builder = Sandbox.builder(name)\n .detached(true)\n .image(resolvedImage)\n .cpus(resolvedCpus)\n .memory(resolvedMemoryMib);\n if (resolvedEnv) {\n builder.envs(resolvedEnv);\n }\n applyVolumes(builder);\n const tCreateInner = Date.now();\n const result = await builder.create();\n console.log(\n `[SandboxRegistry] builder.create name=${name} image=${resolvedImage} ` +\n `elapsed=${Date.now() - tCreateInner}ms ` +\n `envKeys=${resolvedEnv ? Object.keys(resolvedEnv).join(\",\") : \"none\"} ` +\n `volumes=${volumeDefs ? Object.keys(volumeDefs).join(\",\") : \"none\"}`\n );\n return result;\n };\n try {\n native = await tryCreate();\n } catch (err) {\n if (err instanceof Error && err.message.includes(\"already exists\")) {\n await Sandbox.remove(name);\n native = await tryCreate();\n } else {\n throw err;\n }\n }\n console.log(`[SandboxRegistry] phase=create_sandbox name=${name} elapsed=${Date.now() - tBuild}ms`);\n const tFs = Date.now();\n await this.waitForFs(native);\n console.log(`[SandboxRegistry] waitForFs name=${name} elapsed=${Date.now() - tFs}ms`);\n }\n\n const totalElapsed = Date.now() - tStart;\n this.handles.set(name, { native, expiresAt: Date.now() + CACHE_TTL_MS, createOptions: createOptions ?? cached?.createOptions });\n console.log(`[SandboxRegistry] ensure DONE name=${name} total=${totalElapsed}ms cacheTTL=${Math.round(CACHE_TTL_MS / 1000)}s`);\n return native;\n })();\n\n this.creating.set(name, creation);\n void creation.finally(() => this.creating.delete(name));\n\n return creation;\n }\n}\n","import { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { Sandbox, Volume } from \"microsandbox\";\nimport type { SandboxHandle } from \"microsandbox\";\nimport type { LogReadSource } from \"microsandbox\";\nimport type { EnsureSandboxInput, ListSandboxesQuery, ShellExecInput } from \"../schemas/sandbox\";\nimport type { SandboxLogsInput } from \"../schemas/sandbox\";\nimport type { SandboxRuntimeMetrics } from \"../types/runtime-service\";\nimport { getMsbPath } from \"../lib/msb\";\nimport { SandboxRegistry } from \"./SandboxRegistry\";\n\nconst execAsync = promisify(exec);\n\ntype VolumeConfig = NonNullable<EnsureSandboxInput[\"volumes\"]>[string];\n\ntype RuntimeNative = {\n fs(): {\n readString(path: string): Promise<string>;\n readToString(path: string): Promise<string>;\n write(path: string, data: Buffer): Promise<void>;\n list(path: string): Promise<Array<{ path: string; kind: string; size?: number; modified?: unknown }>>;\n read(path: string): Promise<Buffer | Uint8Array | string>;\n mkdir(path: string): Promise<void>;\n };\n exec(cmd: string, args?: string[]): Promise<{\n stdout(): string;\n stderr(): string;\n get code(): number;\n }>;\n shell(script: string): Promise<{\n stdout(): string;\n stderr(): string;\n get code(): number;\n }>;\n stop(): Promise<void>;\n kill(): Promise<void>;\n};\n\ntype SandboxConfig = {\n name: string;\n image: unknown;\n memoryMib?: number;\n cpus?: number;\n env?: unknown;\n volumes?: Record<string, unknown>;\n};\n\nfunction parseConfigJson(configJson: string): SandboxConfig {\n try {\n const raw = JSON.parse(configJson);\n const rawVolumes = raw.volumes ?? raw.mounts;\n const volumes: Record<string, unknown> = {};\n if (Array.isArray(rawVolumes)) {\n for (const mount of rawVolumes) {\n if (mount && typeof mount === \"object\" && \"guest\" in mount) {\n volumes[String(mount.guest)] = mount;\n }\n }\n } else if (rawVolumes && typeof rawVolumes === \"object\") {\n Object.assign(volumes, rawVolumes);\n }\n return {\n name: raw.name ?? \"\",\n image: raw.image ?? \"\",\n memoryMib: raw.memoryMib ?? raw.memory_mib,\n cpus: raw.cpus,\n env: raw.env ?? {},\n volumes,\n };\n } catch {\n return { name: \"\", image: \"\" };\n }\n}\n\nfunction msToIsoString(ms: number | Date | null | undefined): string {\n if (ms == null) return \"\";\n if (ms instanceof Date) return ms.toISOString();\n return new Date(ms).toISOString();\n}\n\ntype MsbInspectEnvVolumes = {\n env: unknown;\n volumes: Record<string, unknown>;\n};\n\nfunction parseMsbInspectEnvVolumes(stdout: string): MsbInspectEnvVolumes {\n const data = JSON.parse(stdout);\n const env = data?.config?.env ?? {};\n\n const volumes: Record<string, unknown> = {};\n const rawMounts = data?.config?.mounts;\n if (Array.isArray(rawMounts)) {\n for (const mount of rawMounts) {\n if (mount && typeof mount === \"object\" && \"guest\" in mount) {\n volumes[String(mount.guest)] = mount;\n }\n }\n }\n\n return { env, volumes };\n}\n\nexport class MicrosandboxRuntimeService {\n constructor(private deps: { registry?: SandboxRegistry } = {}) {}\n\n private get registry(): SandboxRegistry {\n return this.deps.registry ?? (this.deps.registry = new SandboxRegistry());\n }\n\n private resolvePath(path: string): string {\n if (path === \"~\" || path === \"~/\") {\n return \"/\";\n }\n if (path.startsWith(\"~/\")) {\n return `/${path.slice(2)}`;\n }\n return path;\n }\n\n private toListItem(info: {\n name: string;\n status: string;\n configJson: string;\n createdAt?: number | Date | null;\n updatedAt?: number | Date | null;\n }): {\n name: string;\n status: string;\n image: unknown;\n cpus?: number;\n memoryMib?: number;\n envCount: number;\n volumeCount: number;\n createdAt: string;\n updatedAt: string;\n } {\n const config = parseConfigJson(info.configJson);\n const env = config.env ? (Array.isArray(config.env) ? config.env : config.env) : [];\n const envCount = Array.isArray(env) ? env.length : Object.keys(env as Record<string, unknown>).length;\n const volumes = config.volumes ?? {};\n\n return {\n name: info.name,\n status: info.status,\n image: config.image,\n cpus: config.cpus,\n memoryMib: config.memoryMib,\n envCount,\n volumeCount: Object.keys(volumes).length,\n createdAt: msToIsoString(info.createdAt),\n updatedAt: msToIsoString(info.updatedAt),\n };\n }\n\n private async readMsbInspect(name: string): Promise<MsbInspectEnvVolumes | undefined> {\n try {\n const { stdout } = await execAsync(\n `${getMsbPath()} inspect ${name} --format json`,\n { timeout: 5000 }\n );\n return parseMsbInspectEnvVolumes(stdout);\n } catch {\n return undefined;\n }\n }\n\n private async ensureNamedVolumes(volumes?: EnsureSandboxInput[\"volumes\"]): Promise<void> {\n if (!volumes) {\n return;\n }\n\n const defaultQuotaMib = Number(process.env.MICROSANDBOX_VOLUME_QUOTA_MIB ?? \"2048\");\n\n const namedVolumes = Object.values(volumes).filter(\n (v): v is Extract<VolumeConfig, { type: \"named\" }> => v.type === \"named\"\n );\n\n await Promise.all(\n namedVolumes.map(async (definition) => {\n try {\n await Volume.get(definition.name);\n } catch {\n await Volume.builder(definition.name).quota(defaultQuotaMib).create();\n }\n })\n );\n }\n\n private async getOrEnsureNative(name: string): Promise<RuntimeNative> {\n return (await this.registry.ensure(name)) as RuntimeNative;\n }\n\n async ensureSandbox(\n name: string,\n input: EnsureSandboxInput\n ): Promise<{\n name: string;\n status: string;\n }> {\n const image = input.image ?? process.env.MICROSANDBOX_IMAGE ?? \"python:3.11-slim\";\n const cpus = input.cpus ?? Number(process.env.MICROSANDBOX_CPUS ?? \"1\");\n const memoryMib = input.memoryMib ?? Number(process.env.MICROSANDBOX_MEMORY ?? \"512\");\n\n await this.ensureNamedVolumes(input.volumes);\n\n await this.registry.ensure(name, {\n image,\n cpus,\n memoryMib,\n env: input.env,\n volumes: input.volumes,\n });\n\n return {\n name,\n status: \"running\",\n };\n }\n\n async startSandbox(name: string): Promise<{ name: string; status: string }> {\n await this.registry.ensure(name);\n return { name, status: \"running\" };\n }\n\n async stopSandbox(name: string): Promise<{ name: string; status: string }> {\n try {\n const native = await this.getOrEnsureNative(name);\n await native.stop();\n return { name, status: \"stopped\" };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"write to relay\")) {\n return { name, status: \"unknown\" };\n }\n throw error;\n } finally {\n this.registry.remove(name);\n }\n }\n\n async killSandbox(name: string): Promise<{ name: string; status: string }> {\n try {\n const native = await this.getOrEnsureNative(name);\n await native.kill();\n return { name, status: \"unknown\" };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"write to relay\")) {\n return { name, status: \"unknown\" };\n }\n throw error;\n } finally {\n this.registry.remove(name);\n }\n }\n\n async deleteSandbox(name: string): Promise<{ name: string; status: string }> {\n this.registry.remove(name);\n await Sandbox.remove(name);\n return { name, status: \"unknown\" };\n }\n\n async listSandboxes(_query: ListSandboxesQuery): Promise<{\n items: Array<{\n name: string;\n status: string;\n image: unknown;\n cpus?: number;\n memoryMib?: number;\n envCount: number;\n volumeCount: number;\n createdAt: string;\n updatedAt: string;\n }>;\n total: number;\n }> {\n const all: SandboxHandle[] = await Sandbox.list();\n\n const items = all\n .map((info) =>\n this.toListItem({\n name: info.name,\n status: info.status,\n configJson: info.configJson,\n createdAt: info.createdAt,\n updatedAt: info.updatedAt,\n })\n )\n .filter((item) => {\n if (_query.status && item.status !== _query.status) {\n return false;\n }\n\n if (_query.image && item.image !== _query.image) {\n return false;\n }\n\n if (_query.search) {\n const haystack = [item.name, item.image]\n .filter((value): value is string => Boolean(value))\n .join(\" \")\n .toLowerCase();\n\n if (!haystack.includes(_query.search.toLowerCase())) {\n return false;\n }\n }\n\n return true;\n });\n\n return { items, total: items.length };\n }\n\n async getSandbox(\n name: string\n ): Promise<{\n name: string;\n status: string;\n image: unknown;\n cpus?: number;\n memoryMib?: number;\n env: unknown;\n volumes: Record<string, unknown>;\n metrics?: SandboxRuntimeMetrics;\n createdAt: string;\n updatedAt: string;\n } | undefined> {\n try {\n const handle: SandboxHandle = await Sandbox.get(name);\n const config = parseConfigJson(handle.configJson);\n\n const msbData = await this.readMsbInspect(name);\n const env = msbData?.env ?? config.env ?? {};\n const volumes = msbData?.volumes ?? config.volumes ?? {};\n\n let metrics: SandboxRuntimeMetrics | undefined;\n\n try {\n const m = await handle.metrics();\n metrics = {\n cpuPercent: m.cpuPercent,\n memoryBytes: m.memoryBytes,\n memoryLimitBytes: m.memoryLimitBytes,\n diskReadBytes: m.diskReadBytes,\n diskWriteBytes: m.diskWriteBytes,\n netRxBytes: m.netRxBytes,\n netTxBytes: m.netTxBytes,\n uptimeMs: m.uptimeMs,\n timestampMs: m.timestamp.getTime(),\n };\n } catch {\n metrics = undefined;\n }\n\n return {\n name: handle.name,\n status: handle.status,\n image: config.image,\n cpus: config.cpus,\n memoryMib: config.memoryMib,\n env,\n volumes,\n metrics,\n createdAt: msToIsoString(handle.createdAt),\n updatedAt: msToIsoString(handle.updatedAt),\n };\n } catch {\n return undefined;\n }\n }\n\n async getStatus(name: string): Promise<{ name: string; status: string }> {\n try {\n const handle: SandboxHandle = await Sandbox.get(name);\n return { name, status: handle.status };\n } catch {\n return { name, status: \"unknown\" };\n }\n }\n\n async readFile(sandboxName: string, path: string): Promise<{ path: string; content: string }> {\n const resolvedPath = this.resolvePath(path);\n const native = await this.getOrEnsureNative(sandboxName);\n const fs = native.fs();\n const content = typeof fs.readToString === \"function\"\n ? await fs.readToString(resolvedPath)\n : await fs.readString(resolvedPath);\n return { path: resolvedPath, content };\n }\n\n async writeFile(sandboxName: string, path: string, content: string): Promise<{ path: string }> {\n const resolvedPath = this.resolvePath(path);\n const native = await this.getOrEnsureNative(sandboxName);\n const parts = resolvedPath.split(\"/\").filter(Boolean);\n for (let i = 1; i < parts.length; i++) {\n const dir = \"/\" + parts.slice(0, i).join(\"/\");\n try {\n await native.fs().mkdir(dir);\n } catch {\n // directory may already exist or parent missing, continue\n }\n }\n await native.fs().write(resolvedPath, Buffer.from(content));\n return { path: resolvedPath };\n }\n\n async listPath(\n sandboxName: string,\n path: string,\n recursive?: boolean\n ): Promise<{ entries: Array<{ path: string; type: string }> }> {\n const resolvedPath = this.resolvePath(path);\n const native = await this.getOrEnsureNative(sandboxName);\n const entries = await native.fs().list(resolvedPath);\n return {\n entries: entries.map((entry) => ({\n path: entry.path,\n type: entry.kind,\n })),\n };\n }\n\n async findFiles(sandboxName: string, path: string, pattern: string): Promise<{ files: string[] }> {\n const resolvedPath = this.resolvePath(path);\n const native = await this.getOrEnsureNative(sandboxName);\n const matchFlag = pattern.includes(\"/\") ? \"-path\" : \"-name\";\n const output = await native.exec(\"find\", [resolvedPath, matchFlag, pattern, \"-type\", \"f\"]);\n return { files: output.stdout().split(\"\\n\").filter(Boolean) };\n }\n\n async searchInFile(\n sandboxName: string,\n path: string,\n query: string\n ): Promise<{ matches: Array<{ line: number; content: string }> }> {\n const resolvedPath = this.resolvePath(path);\n const native = await this.getOrEnsureNative(sandboxName);\n let stdout: string;\n\n try {\n const output = await native.exec(\"grep\", [\"-n\", \"-E\", query, resolvedPath]);\n stdout = output.stdout();\n } catch (error) {\n if (typeof error === \"object\" && error !== null && \"code\" in error && error.code === 1) {\n return { matches: [] };\n }\n\n throw error;\n }\n\n return {\n matches: stdout\n .split(\"\\n\")\n .filter(Boolean)\n .map((line) => {\n const separator = line.indexOf(\":\");\n return {\n line: Number(line.slice(0, separator)),\n content: line.slice(separator + 1),\n };\n }),\n };\n }\n\n async replaceInFile(\n sandboxName: string,\n input: { path: string; search: string; replace: string }\n ): Promise<{ replaced: number }> {\n const resolvedPath = this.resolvePath(input.path);\n const native = await this.getOrEnsureNative(sandboxName);\n const fs = native.fs();\n const original = typeof fs.readToString === \"function\"\n ? await fs.readToString(resolvedPath)\n : await fs.readString(resolvedPath);\n\n if (!input.search) {\n return { replaced: 0 };\n }\n\n const occurrences = original.split(input.search).length - 1;\n if (occurrences === 0) {\n return { replaced: 0 };\n }\n\n const updated = original.split(input.search).join(input.replace);\n await fs.write(resolvedPath, Buffer.from(updated));\n\n return { replaced: occurrences };\n }\n\n async uploadFile(sandboxName: string, path: string, contentBase64: string): Promise<{ path: string }> {\n const resolvedPath = this.resolvePath(path);\n const native = await this.getOrEnsureNative(sandboxName);\n await native.fs().write(resolvedPath, Buffer.from(contentBase64, \"base64\"));\n return { path: resolvedPath };\n }\n\n async downloadFile(sandboxName: string, path: string): Promise<{ path: string; contentBase64: string }> {\n const resolvedPath = this.resolvePath(path);\n const native = await this.getOrEnsureNative(sandboxName);\n const data = await native.fs().read(resolvedPath);\n const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data);\n return { path: resolvedPath, contentBase64: buffer.toString(\"base64\") };\n }\n\n async execCommand(input: ShellExecInput): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n const native = await this.getOrEnsureNative(input.sandboxName);\n const output = await native.shell(input.command);\n\n return {\n stdout: output.stdout(),\n stderr: output.stderr(),\n exitCode: output.code ?? 0,\n };\n }\n\n async getSandboxLogs(\n name: string,\n opts: SandboxLogsInput\n ): Promise<{\n entries: Array<{\n timestamp: string;\n source: string;\n sessionId: number | null;\n text: string;\n }>;\n }> {\n const handle: SandboxHandle = await Sandbox.get(name);\n\n const logOpts: { tail?: number; since?: Date; until?: Date; sources?: readonly LogReadSource[] } = {};\n\n if (opts.tail !== undefined) {\n logOpts.tail = opts.tail;\n }\n\n if (opts.since) {\n logOpts.since = new Date(opts.since);\n }\n\n if (opts.until) {\n logOpts.until = new Date(opts.until);\n }\n\n if (opts.sources && opts.sources.length > 0) {\n logOpts.sources = opts.sources as LogReadSource[];\n } else {\n logOpts.sources = [\"all\" as LogReadSource];\n }\n\n const entries = await handle.logs(logOpts);\n\n return {\n entries: entries.map((entry) => ({\n timestamp: entry.timestamp.toISOString(),\n source: entry.source,\n sessionId: entry.sessionId,\n text: entry.text(),\n })),\n };\n }\n}\n","export function getMsbPath(): string {\n return process.env.MICROSANDBOX_CLI_PATH ?? `${process.env.HOME ?? \"/root\"}/.microsandbox/bin/msb`;\n}\n","import cors from \"@fastify/cors\";\nimport multipart from \"@fastify/multipart\";\nimport sensible from \"@fastify/sensible\";\nimport fastify, { type FastifyInstance } from \"fastify\";\nimport { toErrorResponse } from \"./lib/errors\";\nimport { registerHealthRoutes } from \"./routes/health\";\nimport { registerImageRoutes } from \"./routes/images\";\nimport { registerSandboxRoutes } from \"./routes/sandbox\";\nimport { registerVolumeFsRoutes } from \"./routes/volume-fs\";\nimport { ImageService } from \"./services/ImageService\";\nimport { MicrosandboxRuntimeService } from \"./services/MicrosandboxRuntimeService\";\nimport { configureSwagger } from \"./swagger\";\nimport type { RuntimeService } from \"./types/runtime-service\";\n\nexport async function buildApp({\n runtimeService = new MicrosandboxRuntimeService(),\n imageService = new ImageService(),\n apiKey,\n}: {\n runtimeService?: RuntimeService;\n imageService?: ImageService;\n apiKey?: string;\n} = {}): Promise<FastifyInstance> {\n const app = fastify({\n logger: false,\n bodyLimit: Number(process.env.BODY_LIMIT) || 100 * 1024 * 1024,\n });\n\n app.register(cors, {\n delegator: (request, callback) => {\n callback(null, {\n origin: true,\n methods: request.headers[\"access-control-request-method\"] ?? \"*\",\n allowedHeaders: request.headers[\"access-control-request-headers\"],\n });\n },\n });\n app.register(sensible);\n app.register(multipart);\n\n if (apiKey) {\n app.addHook(\"onRequest\", async (request, reply) => {\n if (request.method === \"OPTIONS\" || !request.url.startsWith(\"/api/\")) {\n return;\n }\n\n if (request.headers.authorization !== `Bearer ${apiKey}`) {\n await reply.code(401).send({\n success: false,\n error: {\n code: \"UNAUTHORIZED\",\n message: \"Unauthorized\",\n },\n });\n }\n });\n }\n\n registerHealthRoutes(app);\n registerSandboxRoutes(app, runtimeService);\n registerImageRoutes(app, imageService);\n registerVolumeFsRoutes(app);\n\n app.setErrorHandler((error, _request, reply) => {\n const { statusCode, body } = toErrorResponse(error);\n reply.status(statusCode).send(body);\n });\n\n await configureSwagger(app);\n\n return app;\n}\n","export class HttpError extends Error {\n constructor(\n public statusCode: number,\n public code: string,\n message: string\n ) {\n super(message);\n }\n}\n\nexport function toErrorResponse(error: unknown): {\n statusCode: number;\n body: {\n success: false;\n error: {\n code: string;\n message: string;\n };\n };\n} {\n if (error instanceof HttpError) {\n return {\n statusCode: error.statusCode,\n body: {\n success: false,\n error: {\n code: error.code,\n message: error.message,\n },\n },\n };\n }\n\n return {\n statusCode: 500,\n body: {\n success: false,\n error: {\n code: \"INTERNAL_ERROR\",\n message: error instanceof Error ? error.message : String(error),\n },\n },\n };\n}\n","export type SuccessResponse<T> = {\n success: true;\n data: T;\n};\n\nexport function ok<T>(data: T): SuccessResponse<T> {\n return {\n success: true,\n data,\n };\n}\n","import type { FastifyInstance } from \"fastify\";\nimport { ok } from \"../lib/http\";\n\nexport function registerHealthRoutes(app: FastifyInstance): void {\n app.get(\"/health\", async () => ok({ status: \"ok\" }));\n}\n","import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport { ZodError } from \"zod\";\nimport { HttpError } from \"../lib/errors\";\nimport { ok } from \"../lib/http\";\nimport { ImageService } from \"../services/ImageService\";\nimport { imageRefQuerySchema, pullImageSchema } from \"../schemas/images\";\n\nfunction parseOrThrow<T>(parse: () => T): T {\n try {\n return parse();\n } catch (error) {\n if (error instanceof ZodError) {\n throw new HttpError(400, \"INVALID_REQUEST\", error.issues[0]?.message ?? \"Invalid request\");\n }\n\n throw error;\n }\n}\n\nexport function createImageController(imageService: ImageService) {\n return {\n listImages: async (_request: FastifyRequest, reply: FastifyReply) => {\n return reply.send(ok(await imageService.listImages()));\n },\n pullImage: async (request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply) => {\n const body = parseOrThrow(() => pullImageSchema.parse(request.body ?? {}));\n return reply.send(ok(await imageService.pullImage(body)));\n },\n getImage: async (request: FastifyRequest<{ Querystring: unknown }>, reply: FastifyReply) => {\n const query = parseOrThrow(() => imageRefQuerySchema.parse(request.query ?? {}));\n return reply.send(ok(await imageService.getImage(query.ref)));\n },\n deleteImage: async (request: FastifyRequest<{ Querystring: unknown }>, reply: FastifyReply) => {\n const query = parseOrThrow(() => imageRefQuerySchema.parse(request.query ?? {}));\n return reply.send(ok(await imageService.deleteImage(query.ref)));\n },\n };\n}\n","import z from \"zod\";\n\nexport const imageRefQuerySchema = z.object({\n ref: z.string().min(1),\n});\n\nexport const pullImageSchema = z.object({\n ref: z.string().min(1),\n});\n\nexport type ImageRefQuery = z.infer<typeof imageRefQuerySchema>;\nexport type PullImageInput = z.infer<typeof pullImageSchema>;\n","import type { FastifyInstance } from \"fastify\";\nimport { createImageController } from \"../controllers/images\";\nimport { ImageService } from \"../services/ImageService\";\n\nexport function registerImageRoutes(app: FastifyInstance, imageService: ImageService): void {\n const controller = createImageController(imageService);\n\n app.get(\"/api/images\", controller.listImages);\n app.post(\"/api/images/pull\", controller.pullImage);\n app.get(\"/api/images/detail\", controller.getImage);\n app.delete(\"/api/images/detail\", controller.deleteImage);\n}\n","import z from \"zod\";\n\nconst bindMountSchema = z.object({\n type: z.literal(\"bind\"),\n source: z.string().min(1),\n readonly: z.boolean().optional(),\n});\n\nconst namedMountSchema = z.object({\n type: z.literal(\"named\"),\n name: z.string().min(1),\n readonly: z.boolean().optional(),\n});\n\nconst tmpfsMountSchema = z.object({\n type: z.literal(\"tmpfs\"),\n sizeMib: z.number().int().positive().optional(),\n});\n\nexport const volumeSchema = z.union([\n bindMountSchema,\n namedMountSchema,\n tmpfsMountSchema,\n]);\n\nexport const ensureSandboxSchema = z.object({\n image: z.string().optional(),\n cpus: z.number().int().positive().optional(),\n memoryMib: z.number().int().positive().optional(),\n env: z.record(z.string()).optional(),\n volumes: z.record(volumeSchema).optional(),\n});\n\nexport const sandboxNameParamsSchema = z.object({\n name: z.string().min(1),\n});\n\nexport const listSandboxesQuerySchema = z.object({\n status: z.enum([\"running\", \"stopped\", \"crashed\", \"unknown\"]).optional(),\n image: z.string().min(1).optional(),\n search: z.string().min(1).optional(),\n});\n\nconst sandboxAndPathSchema = z.object({\n sandboxName: z.string().min(1),\n path: z.string().min(1),\n});\n\nexport const readFileSchema = sandboxAndPathSchema;\n\nexport const writeFileSchema = sandboxAndPathSchema.extend({\n content: z.string(),\n});\n\nexport const listPathSchema = sandboxAndPathSchema.extend({\n recursive: z.boolean().optional(),\n});\n\nexport const findFilesSchema = sandboxAndPathSchema.extend({\n pattern: z.string().min(1),\n});\n\nexport const searchInFileSchema = sandboxAndPathSchema.extend({\n query: z.string().min(1),\n});\n\nexport const replaceInFileSchema = sandboxAndPathSchema.extend({\n search: z.string(),\n replace: z.string(),\n});\n\nexport const uploadFileSchema = sandboxAndPathSchema.and(\n z.union([\n z.object({ contentBase64: z.string() }),\n z.object({ content: z.string().transform((content) => Buffer.from(content).toString(\"base64\")) }),\n ])\n);\n\nexport const downloadFileSchema = sandboxAndPathSchema;\n\nexport const shellExecSchema = z.object({\n sandboxName: z.string().min(1),\n command: z.string().min(1),\n exec_dir: z.string().optional(),\n timeout: z.number().int().positive().optional(),\n});\n\nexport const sandboxLogsSchema = z.object({\n tail: z.number().int().positive().optional(),\n since: z.string().optional(),\n until: z.string().optional(),\n sources: z.array(z.string()).optional(),\n});\n\nexport type EnsureSandboxInput = z.infer<typeof ensureSandboxSchema>;\nexport type ListSandboxesQuery = z.infer<typeof listSandboxesQuerySchema>;\nexport type ShellExecInput = z.infer<typeof shellExecSchema>;\nexport type SandboxLogsInput = z.infer<typeof sandboxLogsSchema>;\n","import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport {\n downloadFileSchema,\n ensureSandboxSchema,\n findFilesSchema,\n listSandboxesQuerySchema,\n listPathSchema,\n readFileSchema,\n replaceInFileSchema,\n sandboxLogsSchema,\n sandboxNameParamsSchema,\n searchInFileSchema,\n shellExecSchema,\n uploadFileSchema,\n writeFileSchema,\n} from \"../schemas/sandbox\";\nimport { HttpError } from \"../lib/errors\";\nimport { ok } from \"../lib/http\";\nimport type { RuntimeService } from \"../types/runtime-service\";\n\nexport function createSandboxController(runtimeService: RuntimeService): {\n ensureSandbox(\n request: FastifyRequest<{ Params: { name: string }; Body: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n startSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n stopSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n killSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n deleteSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n listSandboxes(\n request: FastifyRequest<{ Querystring: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n getSandbox(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n getStatus(\n request: FastifyRequest<{ Params: { name: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n getSandboxLogs(\n request: FastifyRequest<{ Params: { name: string }; Body: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n readFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n writeFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n listPath(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n findFiles(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n searchInFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n replaceInFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n uploadFile(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n downloadFile(\n request: FastifyRequest<{ Querystring: unknown }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n execCommand(request: FastifyRequest<{ Body: unknown }>, reply: FastifyReply): Promise<FastifyReply>;\n} {\n return {\n ensureSandbox: async (\n request: FastifyRequest<{ Params: { name: string }; Body: unknown }>,\n reply: FastifyReply\n ) => {\n const body = ensureSandboxSchema.parse(request.body ?? {});\n const result = await runtimeService.ensureSandbox(request.params.name, body);\n return reply.send(ok(result));\n },\n\n startSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.startSandbox(request.params.name)));\n },\n\n stopSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.stopSandbox(request.params.name)));\n },\n\n killSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.killSandbox(request.params.name)));\n },\n\n deleteSandbox: async (request, reply) => {\n return reply.send(ok(await runtimeService.deleteSandbox(request.params.name)));\n },\n\n listSandboxes: async (request, reply) => {\n const query = listSandboxesQuerySchema.parse(request.query ?? {});\n return reply.send(ok(await runtimeService.listSandboxes(query)));\n },\n\n getSandbox: async (request, reply) => {\n const params = sandboxNameParamsSchema.parse(request.params ?? {});\n const sandbox = await runtimeService.getSandbox(params.name);\n\n if (!sandbox) {\n throw new HttpError(404, \"SANDBOX_NOT_FOUND\", `Sandbox '${params.name}' not found`);\n }\n\n return reply.send(ok(sandbox));\n },\n\n getStatus: async (request, reply) => {\n return reply.send(ok(await runtimeService.getStatus(request.params.name)));\n },\n\n getSandboxLogs: async (request, reply) => {\n const body = sandboxLogsSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.getSandboxLogs(request.params.name, body)));\n },\n\n readFile: async (request, reply) => {\n const body = readFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.readFile(body.sandboxName, body.path)));\n },\n\n writeFile: async (request, reply) => {\n const body = writeFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.writeFile(body.sandboxName, body.path, body.content)));\n },\n\n listPath: async (request, reply) => {\n const body = listPathSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.listPath(body.sandboxName, body.path, body.recursive)));\n },\n\n findFiles: async (request, reply) => {\n const body = findFilesSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.findFiles(body.sandboxName, body.path, body.pattern)));\n },\n\n searchInFile: async (request, reply) => {\n const body = searchInFileSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.searchInFile(body.sandboxName, body.path, body.query)));\n },\n\n replaceInFile: async (request, reply) => {\n const body = replaceInFileSchema.parse(request.body ?? {});\n return reply.send(\n ok(\n await runtimeService.replaceInFile(body.sandboxName, {\n path: body.path,\n search: body.search,\n replace: body.replace,\n })\n )\n );\n },\n\n uploadFile: async (request, reply) => {\n const body = uploadFileSchema.parse(request.body ?? {});\n const contentBase64 = \"contentBase64\" in body ? body.contentBase64 : Buffer.from(body.content).toString(\"base64\");\n return reply.send(ok(await runtimeService.uploadFile(body.sandboxName, body.path, contentBase64)));\n },\n\n downloadFile: async (request, reply) => {\n const query = downloadFileSchema.parse(request.query ?? {});\n return reply.send(ok(await runtimeService.downloadFile(query.sandboxName, query.path)));\n },\n\n execCommand: async (request, reply) => {\n const body = shellExecSchema.parse(request.body ?? {});\n return reply.send(ok(await runtimeService.execCommand(body)));\n },\n };\n}\n","import type { FastifyInstance } from \"fastify\";\nimport { createSandboxController } from \"../controllers/sandbox\";\nimport type { RuntimeService } from \"../types/runtime-service\";\n\nexport function registerSandboxRoutes(\n app: FastifyInstance,\n runtimeService: RuntimeService\n): void {\n const controller = createSandboxController(runtimeService);\n\n app.get(\"/api/sandboxes\", controller.listSandboxes);\n app.get(\"/api/sandboxes/:name\", controller.getSandbox);\n app.put(\"/api/sandboxes/:name\", controller.ensureSandbox);\n app.post(\"/api/sandboxes/:name/start\", controller.startSandbox);\n app.post(\"/api/sandboxes/:name/stop\", controller.stopSandbox);\n app.post(\"/api/sandboxes/:name/kill\", controller.killSandbox);\n app.delete(\"/api/sandboxes/:name\", controller.deleteSandbox);\n app.get(\"/api/sandboxes/:name/status\", controller.getStatus);\n app.post(\"/api/sandboxes/:name/logs\", controller.getSandboxLogs);\n\n app.post(\"/api/files/read\", controller.readFile);\n app.post(\"/api/files/write\", controller.writeFile);\n app.post(\"/api/files/list\", controller.listPath);\n app.post(\"/api/files/find\", controller.findFiles);\n app.post(\"/api/files/search\", controller.searchInFile);\n app.post(\"/api/files/replace\", controller.replaceInFile);\n app.post(\"/api/files/upload\", controller.uploadFile);\n app.get(\"/api/files/download\", controller.downloadFile);\n\n app.post(\"/api/shell/exec\", controller.execCommand);\n}\n","import type { FastifyReply, FastifyRequest } from \"fastify\";\nimport fs from \"fs/promises\";\nimport os from \"os\";\nimport path from \"path\";\nimport { Volume } from \"microsandbox\";\nimport z from \"zod\";\nimport { HttpError } from \"../lib/errors\";\nimport { ok } from \"../lib/http\";\nimport {\n volumeFsReadSchema,\n volumeFsWriteSchema,\n volumeFsListSchema,\n volumeFsUploadSchema,\n volumeFsDownloadSchema,\n} from \"../schemas/volume-fs\";\n\ninterface VolumeFsParams {\n name: string;\n}\n\nconst MSB_DATA_DIR = path.join(os.homedir(), \".microsandbox\");\n\nasync function resolveVolumeHostPath(name: string): Promise<string> {\n try {\n const handle = await Volume.get(name);\n const vol = await Volume.builder(handle.name).create();\n return vol.path;\n } catch {\n try {\n const vol = await Volume.builder(name).create();\n return vol.path;\n } catch {\n return path.join(MSB_DATA_DIR, \"volumes\", name);\n }\n }\n}\n\nfunction resolveGuestPath(hostRoot: string, guestPath: string): string {\n const normalized = guestPath === \"~\" ? \"\" : guestPath.replace(/^~\\//, \"\");\n const resolved = path.join(hostRoot, path.normalize(normalized).replace(/^(\\.\\.(\\/|\\\\|$))+/, \"\"));\n if (!resolved.startsWith(hostRoot + path.sep) && resolved !== hostRoot) {\n throw new HttpError(403, \"PATH_TRAVERSAL\", \"Path traversal detected\");\n }\n return resolved;\n}\n\nexport function createVolumeFsController(): {\n readFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n writeFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string; content: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n listPath(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n downloadFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Querystring: { path: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n uploadFile(\n request: FastifyRequest<{ Params: VolumeFsParams; Body: { path: string; contentBase64: string } }>,\n reply: FastifyReply\n ): Promise<FastifyReply>;\n} {\n return {\n readFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath } = volumeFsReadSchema.parse(request.body ?? {});\n const hostRoot = await resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n const content = await fs.readFile(fullPath, \"utf-8\");\n return reply.send(ok({ path: guestPath, content }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(404, \"VOLUME_READ_ERROR\", `Failed to read from volume '${name}': ${String(err)}`);\n }\n },\n\n writeFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath, content } = volumeFsWriteSchema.parse(request.body ?? {});\n const hostRoot = await resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n await fs.writeFile(fullPath, content, \"utf-8\");\n return reply.send(ok({ path: guestPath }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(500, \"VOLUME_WRITE_ERROR\", `Failed to write to volume '${name}': ${String(err)}`);\n }\n },\n\n listPath: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath } = volumeFsListSchema.parse(request.body ?? {});\n const hostRoot = await resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n const dirents = await fs.readdir(fullPath, { withFileTypes: true });\n const entries = dirents.map((d) => ({\n path: guestPath ? `${guestPath}/${d.name}` : d.name,\n kind: d.isDirectory() ? \"directory\" : d.isSymbolicLink() ? \"symlink\" : \"file\",\n size: 0,\n mode: 0,\n }));\n return reply.send(ok({ entries }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(404, \"VOLUME_LIST_ERROR\", `Failed to list volume '${name}': ${String(err)}`);\n }\n },\n\n downloadFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath } = volumeFsDownloadSchema.parse(request.query ?? {});\n const hostRoot = await resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n const buf = await fs.readFile(fullPath);\n const contentBase64 = buf.toString(\"base64\");\n return reply.send(ok({ path: guestPath, contentBase64 }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(404, \"VOLUME_DOWNLOAD_ERROR\", `Failed to download from volume '${name}': ${String(err)}`);\n }\n },\n\n uploadFile: async (request, reply) => {\n const { name } = request.params;\n\n try {\n const { path: guestPath, contentBase64 } = volumeFsUploadSchema.parse(request.body ?? {});\n const hostRoot = await resolveVolumeHostPath(name);\n const fullPath = resolveGuestPath(hostRoot, guestPath);\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n const data = Buffer.from(contentBase64, \"base64\");\n await fs.writeFile(fullPath, data);\n return reply.send(ok({ path: guestPath }));\n } catch (err: unknown) {\n if (err instanceof z.ZodError) {\n throw new HttpError(400, \"VALIDATION_ERROR\", err.message);\n }\n if (err instanceof HttpError) throw err;\n throw new HttpError(500, \"VOLUME_UPLOAD_ERROR\", `Failed to upload to volume '${name}': ${String(err)}`);\n }\n },\n };\n}\n","import z from \"zod\";\n\nexport const volumeFsReadSchema = z.object({\n path: z.string(),\n});\n\nexport const volumeFsWriteSchema = z.object({\n path: z.string(),\n content: z.string(),\n});\n\nexport const volumeFsListSchema = z.object({\n path: z.string(),\n});\n\nexport const volumeFsUploadSchema = z.object({\n path: z.string(),\n contentBase64: z.string().min(1),\n});\n\nexport const volumeFsDownloadSchema = z.object({\n path: z.string(),\n});\n","import type { FastifyInstance } from \"fastify\";\nimport { createVolumeFsController } from \"../controllers/volume-fs\";\n\nexport function registerVolumeFsRoutes(app: FastifyInstance): void {\n const controller = createVolumeFsController();\n\n app.post(\"/api/volumes/:name/fs/read\", controller.readFile);\n app.post(\"/api/volumes/:name/fs/write\", controller.writeFile);\n app.post(\"/api/volumes/:name/fs/list\", controller.listPath);\n app.get(\"/api/volumes/:name/fs/download\", controller.downloadFile);\n app.post(\"/api/volumes/:name/fs/upload\", controller.uploadFile);\n}\n","import { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { PullImageInput } from \"../schemas/images\";\nimport { getMsbPath } from \"../lib/msb\";\n\nconst execAsync = promisify(exec);\n\nexport type ImageRecord = {\n ref: string;\n sourceType: string;\n cached: boolean;\n size?: number;\n createdAt?: string;\n lastUsedAt?: string;\n};\n\ntype ImageBindings = {\n list(): Promise<ImageRecord[]>;\n pull(ref: string): Promise<ImageRecord>;\n inspect(ref: string): Promise<ImageRecord>;\n remove(ref: string): Promise<void>;\n};\n\ntype CliImageInfo = {\n architecture: string;\n created_at: string;\n digest: string;\n layer_count: number;\n os: string;\n reference: string;\n size_bytes: number;\n};\n\nclass MicrosandboxImageBindings implements ImageBindings {\n private get msb(): string {\n return getMsbPath();\n }\n\n async list(): Promise<ImageRecord[]> {\n const { stdout } = await execAsync(`${this.msb} image ls --format json`);\n const images: CliImageInfo[] = JSON.parse(stdout);\n return images.map((img) => ({\n ref: img.reference,\n sourceType: \"oci\",\n cached: true,\n size: img.size_bytes,\n createdAt: img.created_at,\n }));\n }\n\n async pull(ref: string): Promise<ImageRecord> {\n await execAsync(`${this.msb} image pull ${ref}`);\n return this.inspect(ref);\n }\n\n async inspect(ref: string): Promise<ImageRecord> {\n const { stdout } = await execAsync(`${this.msb} image inspect ${ref} --format json`);\n const img: CliImageInfo = JSON.parse(stdout);\n return {\n ref: img.reference,\n sourceType: \"oci\",\n cached: true,\n size: img.size_bytes,\n createdAt: img.created_at,\n };\n }\n\n async remove(ref: string): Promise<void> {\n await execAsync(`${this.msb} image rm ${ref}`);\n }\n}\n\nexport class ImageService {\n constructor(\n private readonly deps: {\n bindings?: ImageBindings;\n } = {}\n ) {}\n\n private get bindings(): ImageBindings {\n return this.deps.bindings ?? new MicrosandboxImageBindings();\n }\n\n async listImages(): Promise<{ items: ImageRecord[]; total: number }> {\n const items = await this.bindings.list();\n return { items, total: items.length };\n }\n\n async pullImage(input: PullImageInput): Promise<ImageRecord> {\n return await this.bindings.pull(input.ref);\n }\n\n async getImage(ref: string): Promise<ImageRecord> {\n return await this.bindings.inspect(ref);\n }\n\n async deleteImage(ref: string): Promise<{ ref: string }> {\n await this.bindings.remove(ref);\n return { ref };\n }\n}\n","import type { FastifyInstance } from \"fastify\";\nimport swagger from \"@fastify/swagger\";\nimport swaggerUi from \"@fastify/swagger-ui\";\n\nexport const defaultSwaggerConfig = {\n openapi: {\n openapi: \"3.0.0\",\n info: {\n title: \"Microsandbox Service API\",\n description:\n \"Sandbox lifecycle management, file operations, shell execution, and image registry\",\n version: \"1.0.0\",\n },\n servers: [\n {\n url: \"http://localhost:4002\",\n description: \"Local development\",\n },\n ],\n components: {\n securitySchemes: {\n bearerAuth: {\n type: \"http\" as const,\n scheme: \"bearer\" as const,\n bearerFormat: \"API Key\",\n },\n },\n },\n tags: [\n { name: \"Sandboxes\", description: \"Sandbox lifecycle (CRUD, start, stop, kill)\" },\n { name: \"Files\", description: \"Read, write, list, search, upload, download files inside sandboxes\" },\n { name: \"Shell\", description: \"Execute commands inside sandboxes\" },\n { name: \"Images\", description: \"OCI image management (list, pull, inspect, delete)\" },\n { name: \"Volumes\", description: \"Named volume filesystem operations\" },\n { name: \"Health\", description: \"Service health check\" },\n ],\n },\n};\n\nexport const defaultSwaggerUiConfig = {\n routePrefix: \"/api-docs\",\n uiConfig: {\n docExpansion: \"list\" as const,\n deepLinking: true,\n },\n staticCSP: true,\n transformStaticCSP: (header: string) => header,\n};\n\nexport async function configureSwagger(\n app: FastifyInstance,\n customSwaggerConfig?: Partial<typeof defaultSwaggerConfig>,\n customSwaggerUiConfig?: Partial<typeof defaultSwaggerUiConfig>\n) {\n const swaggerConfig = { ...defaultSwaggerConfig, ...customSwaggerConfig };\n const swaggerUiConfig = {\n ...defaultSwaggerUiConfig,\n ...customSwaggerUiConfig,\n };\n\n await app.register(swagger, swaggerConfig);\n await app.register(swaggerUi, swaggerUiConfig);\n}\n"],"mappings":";AAAA,SAAS,SAAS,oBAAoB;AAGtC,IAAM,gBAAgB,QAAQ,IAAI,sBAAsB;AACxD,IAAM,eAAe;AAErB,SAAS,cAAc,YAMT;AACZ,MAAI;AACF,UAAM,MAAM,KAAK,MAAM,UAAU;AACjC,UAAM,QAAQ,OAAO,IAAI,UAAU,WAAW,IAAI,QAC9C,IAAI,OAAO,KAAK,aAAa;AACjC,UAAM,MAA8B,CAAC;AACrC,UAAM,SAAS,IAAI;AACnB,QAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,iBAAW,SAAS,QAAQ;AAC1B,YAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,UAAU,GAAG;AAC7C,cAAI,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,OAAO,MAAM,CAAC,CAAC;AAAA,QACzC;AAAA,MACF;AAAA,IACF,WAAW,UAAU,OAAO,WAAW,UAAU;AAC/C,aAAO,OAAO,KAAK,MAAM;AAAA,IAC3B;AACA,WAAO;AAAA,MACL;AAAA,MACA,MAAM,IAAI,QAAQ;AAAA,MAClB,WAAW,IAAI,cAAc,IAAI,aAAa;AAAA,MAC9C;AAAA,MACA,QAAQ,MAAM,QAAQ,IAAI,MAAM,IAAI,IAAI,SAAS,CAAC;AAAA,IACpD;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,IAAM,kBAAN,MAAsB;AAAA,EAAtB;AACL,SAAQ,UAAU,oBAAI,IAA6F;AACnH,SAAQ,WAAW,oBAAI,IAA8B;AAAA;AAAA,EAErD,OAAO,MAAoB;AACzB,SAAK,QAAQ,OAAO,IAAI;AACxB,SAAK,SAAS,OAAO,IAAI;AAAA,EAC3B;AAAA,EAEA,MAAc,UAAU,QAAiB,aAAa,IAAmB;AACvE,UAAMA,MAAM,OAA8D,GAAG;AAC7E,aAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,UAAI;AACF,cAAMA,IAAG,KAAK,GAAG;AACjB;AAAA,MACF,QAAQ;AACN,cAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAAA,MAC7C;AAAA,IACF;AACA,UAAM,IAAI,MAAM,0BAA0B;AAAA,EAC5C;AAAA,EAEQ,kBACN,gBACA,eACS;AACT,UAAM,aAAa,cAAc;AACjC,UAAM,aAAa,cAAc;AAEjC,QAAI,cAAc,OAAO,KAAK,UAAU,EAAE,SAAS,GAAG;AACpD,YAAM,iBAAiB,IAAI,KAAK,gBAAgB,UAAU,CAAC,GAAG,IAAI,CAAC,MAAyB,EAAE,KAAK,CAAC;AACpG,YAAM,kBAAkB,IAAI,IAAI,OAAO,KAAK,UAAU,CAAC;AACvD,UAAI,eAAe,SAAS,gBAAgB,QACxC,CAAC,CAAC,GAAG,eAAe,EAAE,MAAM,OAAK,eAAe,IAAI,CAAC,CAAC,GAAG;AAC3D,gBAAQ,IAAI,mDAAmD;AAC/D,eAAO;AAAA,MACT;AAAA,IACF;AAEA,QAAI,cAAc,gBAAgB,KAAK;AACrC,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AACrD,YAAI,eAAe,IAAI,GAAG,MAAM,OAAO;AACrC,kBAAQ,IAAI,uCAAuC,GAAG,kBAAkB;AACxE,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAO,MAAc,eAA2D;AACpF,UAAM,SAAS,KAAK,IAAI;AAExB,UAAM,SAAS,KAAK,QAAQ,IAAI,IAAI;AACpC,QAAI,UAAU,KAAK,IAAI,IAAI,OAAO,WAAW;AAC3C,aAAO,YAAY,KAAK,IAAI,IAAI;AAChC,cAAQ,IAAI,iCAAiC,IAAI,sBAAsB,KAAK,IAAI,IAAI,MAAM,IAAI;AAC9F,aAAO,OAAO;AAAA,IAChB;AAEA,QAAI,QAAQ;AACV,cAAQ,IAAI,iCAAiC,IAAI,wBAAwB,KAAK,IAAI,IAAI,MAAM,iBAAiB;AAAA,IAC/G;AAEA,UAAM,WAAW,KAAK,SAAS,IAAI,IAAI;AACvC,QAAI,UAAU;AACZ,cAAQ,IAAI,iCAAiC,IAAI,oBAAoB;AACrE,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,YAAY;AAC5B,YAAM,UAAU,KAAK,IAAI;AACzB,UAAI;AACJ,YAAM,QAAS,eAAe,SAAoB;AAClD,YAAM,OAAQ,eAAe,QAAmB;AAChD,YAAM,YAAa,eAAe,aAAwB;AAC1D,YAAM,MAAO,eAAe,OAAkC;AAE9D,UAAI;AAEJ,UAAI;AACF,cAAM,OAAO,KAAK,IAAI;AACtB,cAAM,SAAwB,MAAM,QAAQ,IAAI,IAAI;AACpD,gBAAQ,IAAI,sCAAsC,IAAI,WAAW,OAAO,MAAM,YAAY,KAAK,IAAI,IAAI,IAAI,IAAI;AAE/G,yBAAiB,cAAc,OAAO,UAAU;AAEhD,YAAI,OAAO,WAAW,aAAa,OAAO,WAAW,WAAW;AAC9D,cAAI,iBAAiB,KAAK,kBAAkB,gBAAgB,aAAa,GAAG;AAC1E,gBAAI;AAAE,oBAAM,QAAQ,OAAO,IAAI;AAAA,YAAG,QAAQ;AAAA,YAAe;AACzD,qBAAS;AAAA,UACX,WAAW,OAAO,WAAW,WAAW;AACtC,kBAAM,WAAW,KAAK,IAAI;AAC1B,qBAAS,MAAM,OAAO,QAAQ;AAC9B,oBAAQ,IAAI,yCAAyC,IAAI,YAAY,KAAK,IAAI,IAAI,QAAQ,IAAI;AAC9F,kBAAM,MAAM,KAAK,IAAI;AACrB,kBAAM,KAAK,UAAU,MAAM;AAC3B,oBAAQ,IAAI,oCAAoC,IAAI,YAAY,KAAK,IAAI,IAAI,GAAG,IAAI;AAAA,UACtF,OAAO;AACL,gBAAI;AACF,oBAAM,UAAU,KAAK,IAAI;AACzB,uBAAS,MAAM,QAAQ,cAAc,IAAI;AACzC,sBAAQ,IAAI,wCAAwC,IAAI,YAAY,KAAK,IAAI,IAAI,OAAO,IAAI;AAC5F,oBAAM,MAAM,KAAK,IAAI;AACrB,oBAAM,KAAK,UAAU,MAAM;AAC3B,sBAAQ,IAAI,oCAAoC,IAAI,YAAY,KAAK,IAAI,IAAI,GAAG,IAAI;AAAA,YACtF,QAAQ;AACN,kBAAI,CAAC,QAAQ;AACX,oBAAI;AAAE,wBAAM,QAAQ,OAAO,IAAI;AAAA,gBAAG,QAAQ;AAAA,gBAAwB;AAAA,cACpE;AAAA,YACF;AAAA,UACF;AAAA,QACF,WAAW,OAAO,WAAW,aAAa,OAAO,WAAW,YAAY;AACtE,gBAAM,QAAQ,OAAO,IAAI;AAAA,QAC3B,OAAO;AACL,gBAAM,QAAQ,OAAO,IAAI;AAAA,QAC3B;AAAA,MACF,QAAQ;AACN,iBAAS;AAAA,MACX;AACA,cAAQ,IAAI,+CAA+C,IAAI,cAAc,CAAC,CAAC,MAAM,YAAY,KAAK,IAAI,IAAI,OAAO,IAAI;AAEzH,UAAI,CAAC,QAAQ;AACX,cAAM,mBAAmB,iBAAiB,QAAQ;AAClD,YAAI,CAAC,kBAAkB;AACrB,kBAAQ,IAAI,iCAAiC,IAAI,sBAAsB,KAAK,IAAI,IAAI,MAAM,IAAI;AAC9F,gBAAM,IAAI,MAAM,WAAW,IAAI,YAAY;AAAA,QAC7C;AACA,YAAI,CAAC,iBAAiB,QAAQ,eAAe;AAC3C,kBAAQ,IAAI,iCAAiC,IAAI,4BAA4B,KAAK,IAAI,IAAI,MAAM,IAAI;AAAA,QACtG;AACA,cAAM,SAAS,KAAK,IAAI;AACxB,cAAM,aAAa,kBAAkB;AACrC,cAAM,gBAAiB,kBAAkB,SAAoB,gBAAgB,SAAS;AACtF,gBAAQ;AAAA,UACN,oCAAoC,IAAI,UAAU,aAAa,SACtD,kBAAkB,QAAmB,YAAY,gBAAgB,QAAQ,mBAAmB,SAAS;AAAA,QAChH;AACA,cAAM,eAAgB,kBAAkB,QAAmB,gBAAgB,QAAQ;AACnF,cAAM,oBAAqB,kBAAkB,aAAwB,gBAAgB,aAAa;AAClG,cAAM,cAAe,kBAAkB,OAAkC,gBAAgB,OAAO;AAChG,cAAM,iBAAiB,gBAAgB,UAAU,CAAC;AAElD,cAAM,eAAe,CAAC,MAAgD;AACpE,cAAI,YAAY;AACd,uBAAW,CAAC,WAAW,GAAG,KAAK,OAAO,QAAQ,UAAU,GAAG;AACzD,oBAAM,KAAK,IAAI,aAAa,SAAS;AACrC,kBAAI,IAAI,SAAS,UAAU,IAAI,QAAQ;AACrC,mBAAG,KAAK,IAAI,MAAM;AAAA,cACpB,WAAW,IAAI,SAAS,WAAW,IAAI,MAAM;AAC3C,mBAAG,MAAM,IAAI,IAAI;AAAA,cACnB,WAAW,IAAI,SAAS,SAAS;AAC/B,mBAAG,MAAM;AACT,oBAAI,IAAI,SAAS;AACf,qBAAG,KAAK,IAAI,OAAO;AAAA,gBACrB;AAAA,cACF;AACA,kBAAI,IAAI,UAAU;AAChB,mBAAG,SAAS;AAAA,cACd;AACA,gBAAE,OAAO,WAAW,MAAM,EAAE;AAAA,YAC9B;AAAA,UACF,OAAO;AACL,uBAAW,SAAS,gBAAgB;AAClC,oBAAM,KAAK,IAAI,aAAa,MAAM,KAAK;AACvC,kBAAI,MAAM,SAAS,UAAU,MAAM,SAAS,QAAQ;AAClD,oBAAI,MAAM,OAAQ,IAAG,KAAK,MAAM,MAAM;AAAA,cACxC,WAAW,MAAM,SAAS,WAAW,MAAM,SAAS,SAAS;AAC3D,oBAAI,MAAM,KAAM,IAAG,MAAM,MAAM,IAAI;AAAA,cACrC,WAAW,MAAM,SAAS,WAAW,MAAM,SAAS,SAAS;AAC3D,mBAAG,MAAM;AACT,oBAAI,MAAM,SAAU,IAAG,KAAK,MAAM,QAAQ;AAAA,cAC5C;AACA,kBAAI,MAAM,UAAU;AAClB,mBAAG,SAAS;AAAA,cACd;AACA,gBAAE,OAAO,MAAM,OAAO,MAAM,EAAE;AAAA,YAChC;AAAA,UACF;AAAA,QACF;AAEA,cAAM,YAAY,YAAY;AAC5B,gBAAM,UAAU,QAAQ,QAAQ,IAAI,EACjC,SAAS,IAAI,EACb,MAAM,aAAa,EACnB,KAAK,YAAY,EACjB,OAAO,iBAAiB;AAC3B,cAAI,aAAa;AACf,oBAAQ,KAAK,WAAW;AAAA,UAC1B;AACA,uBAAa,OAAO;AACpB,gBAAM,eAAe,KAAK,IAAI;AAC9B,gBAAM,SAAS,MAAM,QAAQ,OAAO;AACpC,kBAAQ;AAAA,YACN,yCAAyC,IAAI,UAAU,aAAa,YACzD,KAAK,IAAI,IAAI,YAAY,cACzB,cAAc,OAAO,KAAK,WAAW,EAAE,KAAK,GAAG,IAAI,MAAM,YACzD,aAAa,OAAO,KAAK,UAAU,EAAE,KAAK,GAAG,IAAI,MAAM;AAAA,UACpE;AACA,iBAAO;AAAA,QACT;AACA,YAAI;AACF,mBAAS,MAAM,UAAU;AAAA,QAC3B,SAAS,KAAK;AACZ,cAAI,eAAe,SAAS,IAAI,QAAQ,SAAS,gBAAgB,GAAG;AAClE,kBAAM,QAAQ,OAAO,IAAI;AACzB,qBAAS,MAAM,UAAU;AAAA,UAC3B,OAAO;AACL,kBAAM;AAAA,UACR;AAAA,QACF;AACA,gBAAQ,IAAI,+CAA+C,IAAI,YAAY,KAAK,IAAI,IAAI,MAAM,IAAI;AAClG,cAAM,MAAM,KAAK,IAAI;AACrB,cAAM,KAAK,UAAU,MAAM;AAC3B,gBAAQ,IAAI,oCAAoC,IAAI,YAAY,KAAK,IAAI,IAAI,GAAG,IAAI;AAAA,MACtF;AAEA,YAAM,eAAe,KAAK,IAAI,IAAI;AAClC,WAAK,QAAQ,IAAI,MAAM,EAAE,QAAQ,WAAW,KAAK,IAAI,IAAI,cAAc,eAAe,iBAAiB,QAAQ,cAAc,CAAC;AAC9H,cAAQ,IAAI,sCAAsC,IAAI,UAAU,YAAY,eAAe,KAAK,MAAM,eAAe,GAAI,CAAC,GAAG;AAC7H,aAAO;AAAA,IACT,GAAG;AAEH,SAAK,SAAS,IAAI,MAAM,QAAQ;AAChC,SAAK,SAAS,QAAQ,MAAM,KAAK,SAAS,OAAO,IAAI,CAAC;AAEtD,WAAO;AAAA,EACT;AACF;;;AC7QA,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B,SAAS,WAAAC,UAAS,cAAc;;;ACFzB,SAAS,aAAqB;AACnC,SAAO,QAAQ,IAAI,yBAAyB,GAAG,QAAQ,IAAI,QAAQ,OAAO;AAC5E;;;ADSA,IAAM,YAAY,UAAU,IAAI;AAoChC,SAAS,gBAAgB,YAAmC;AAC1D,MAAI;AACF,UAAM,MAAM,KAAK,MAAM,UAAU;AACjC,UAAM,aAAa,IAAI,WAAW,IAAI;AACtC,UAAM,UAAmC,CAAC;AAC1C,QAAI,MAAM,QAAQ,UAAU,GAAG;AAC7B,iBAAW,SAAS,YAAY;AAC9B,YAAI,SAAS,OAAO,UAAU,YAAY,WAAW,OAAO;AAC1D,kBAAQ,OAAO,MAAM,KAAK,CAAC,IAAI;AAAA,QACjC;AAAA,MACF;AAAA,IACF,WAAW,cAAc,OAAO,eAAe,UAAU;AACvD,aAAO,OAAO,SAAS,UAAU;AAAA,IACnC;AACA,WAAO;AAAA,MACL,MAAM,IAAI,QAAQ;AAAA,MAClB,OAAO,IAAI,SAAS;AAAA,MACpB,WAAW,IAAI,aAAa,IAAI;AAAA,MAChC,MAAM,IAAI;AAAA,MACV,KAAK,IAAI,OAAO,CAAC;AAAA,MACjB;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO,EAAE,MAAM,IAAI,OAAO,GAAG;AAAA,EAC/B;AACF;AAEA,SAAS,cAAc,IAA8C;AACnE,MAAI,MAAM,KAAM,QAAO;AACvB,MAAI,cAAc,KAAM,QAAO,GAAG,YAAY;AAC9C,SAAO,IAAI,KAAK,EAAE,EAAE,YAAY;AAClC;AAOA,SAAS,0BAA0B,QAAsC;AACvE,QAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,QAAM,MAAM,MAAM,QAAQ,OAAO,CAAC;AAElC,QAAM,UAAmC,CAAC;AAC1C,QAAM,YAAY,MAAM,QAAQ;AAChC,MAAI,MAAM,QAAQ,SAAS,GAAG;AAC5B,eAAW,SAAS,WAAW;AAC7B,UAAI,SAAS,OAAO,UAAU,YAAY,WAAW,OAAO;AAC1D,gBAAQ,OAAO,MAAM,KAAK,CAAC,IAAI;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,KAAK,QAAQ;AACxB;AAEO,IAAM,6BAAN,MAAiC;AAAA,EACtC,YAAoB,OAAuC,CAAC,GAAG;AAA3C;AAAA,EAA4C;AAAA,EAEhE,IAAY,WAA4B;AACtC,WAAO,KAAK,KAAK,aAAa,KAAK,KAAK,WAAW,IAAI,gBAAgB;AAAA,EACzE;AAAA,EAEQ,YAAYC,OAAsB;AACxC,QAAIA,UAAS,OAAOA,UAAS,MAAM;AACjC,aAAO;AAAA,IACT;AACA,QAAIA,MAAK,WAAW,IAAI,GAAG;AACzB,aAAO,IAAIA,MAAK,MAAM,CAAC,CAAC;AAAA,IAC1B;AACA,WAAOA;AAAA,EACT;AAAA,EAEQ,WAAW,MAgBjB;AACA,UAAM,SAAS,gBAAgB,KAAK,UAAU;AAC9C,UAAM,MAAM,OAAO,MAAO,MAAM,QAAQ,OAAO,GAAG,IAAI,OAAO,MAAM,OAAO,MAAO,CAAC;AAClF,UAAM,WAAW,MAAM,QAAQ,GAAG,IAAI,IAAI,SAAS,OAAO,KAAK,GAA8B,EAAE;AAC/F,UAAM,UAAU,OAAO,WAAW,CAAC;AAEnC,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,QAAQ,KAAK;AAAA,MACb,OAAO,OAAO;AAAA,MACd,MAAM,OAAO;AAAA,MACb,WAAW,OAAO;AAAA,MAClB;AAAA,MACA,aAAa,OAAO,KAAK,OAAO,EAAE;AAAA,MAClC,WAAW,cAAc,KAAK,SAAS;AAAA,MACvC,WAAW,cAAc,KAAK,SAAS;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,MAAc,eAAe,MAAyD;AACpF,QAAI;AACF,YAAM,EAAE,OAAO,IAAI,MAAM;AAAA,QACvB,GAAG,WAAW,CAAC,YAAY,IAAI;AAAA,QAC/B,EAAE,SAAS,IAAK;AAAA,MAClB;AACA,aAAO,0BAA0B,MAAM;AAAA,IACzC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,mBAAmB,SAAwD;AACvF,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAEA,UAAM,kBAAkB,OAAO,QAAQ,IAAI,iCAAiC,MAAM;AAElF,UAAM,eAAe,OAAO,OAAO,OAAO,EAAE;AAAA,MAC1C,CAAC,MAAqD,EAAE,SAAS;AAAA,IACnE;AAEA,UAAM,QAAQ;AAAA,MACZ,aAAa,IAAI,OAAO,eAAe;AACrC,YAAI;AACF,gBAAM,OAAO,IAAI,WAAW,IAAI;AAAA,QAClC,QAAQ;AACN,gBAAM,OAAO,QAAQ,WAAW,IAAI,EAAE,MAAM,eAAe,EAAE,OAAO;AAAA,QACtE;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAc,kBAAkB,MAAsC;AACpE,WAAQ,MAAM,KAAK,SAAS,OAAO,IAAI;AAAA,EACzC;AAAA,EAEA,MAAM,cACJ,MACA,OAIC;AACD,UAAM,QAAQ,MAAM,SAAS,QAAQ,IAAI,sBAAsB;AAC/D,UAAM,OAAO,MAAM,QAAQ,OAAO,QAAQ,IAAI,qBAAqB,GAAG;AACtE,UAAM,YAAY,MAAM,aAAa,OAAO,QAAQ,IAAI,uBAAuB,KAAK;AAEpF,UAAM,KAAK,mBAAmB,MAAM,OAAO;AAE3C,UAAM,KAAK,SAAS,OAAO,MAAM;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK,MAAM;AAAA,MACX,SAAS,MAAM;AAAA,IACjB,CAAC;AAED,WAAO;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,MAAyD;AAC1E,UAAM,KAAK,SAAS,OAAO,IAAI;AAC/B,WAAO,EAAE,MAAM,QAAQ,UAAU;AAAA,EACnC;AAAA,EAEA,MAAM,YAAY,MAAyD;AACzE,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,kBAAkB,IAAI;AAChD,YAAM,OAAO,KAAK;AAClB,aAAO,EAAE,MAAM,QAAQ,UAAU;AAAA,IACnC,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,gBAAgB,GAAG;AACtE,eAAO,EAAE,MAAM,QAAQ,UAAU;AAAA,MACnC;AACA,YAAM;AAAA,IACR,UAAE;AACA,WAAK,SAAS,OAAO,IAAI;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,MAAyD;AACzE,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,kBAAkB,IAAI;AAChD,YAAM,OAAO,KAAK;AAClB,aAAO,EAAE,MAAM,QAAQ,UAAU;AAAA,IACnC,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,gBAAgB,GAAG;AACtE,eAAO,EAAE,MAAM,QAAQ,UAAU;AAAA,MACnC;AACA,YAAM;AAAA,IACR,UAAE;AACA,WAAK,SAAS,OAAO,IAAI;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,MAAyD;AAC3E,SAAK,SAAS,OAAO,IAAI;AACzB,UAAMC,SAAQ,OAAO,IAAI;AACzB,WAAO,EAAE,MAAM,QAAQ,UAAU;AAAA,EACnC;AAAA,EAEA,MAAM,cAAc,QAajB;AACD,UAAM,MAAuB,MAAMA,SAAQ,KAAK;AAEhD,UAAM,QAAQ,IACX;AAAA,MAAI,CAAC,SACJ,KAAK,WAAW;AAAA,QACd,MAAM,KAAK;AAAA,QACX,QAAQ,KAAK;AAAA,QACb,YAAY,KAAK;AAAA,QACjB,WAAW,KAAK;AAAA,QAChB,WAAW,KAAK;AAAA,MAClB,CAAC;AAAA,IACH,EACC,OAAO,CAAC,SAAS;AAChB,UAAI,OAAO,UAAU,KAAK,WAAW,OAAO,QAAQ;AAClD,eAAO;AAAA,MACT;AAEA,UAAI,OAAO,SAAS,KAAK,UAAU,OAAO,OAAO;AAC/C,eAAO;AAAA,MACT;AAEA,UAAI,OAAO,QAAQ;AACjB,cAAM,WAAW,CAAC,KAAK,MAAM,KAAK,KAAK,EACpC,OAAO,CAAC,UAA2B,QAAQ,KAAK,CAAC,EACjD,KAAK,GAAG,EACR,YAAY;AAEf,YAAI,CAAC,SAAS,SAAS,OAAO,OAAO,YAAY,CAAC,GAAG;AACnD,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,aAAO;AAAA,IACT,CAAC;AAEH,WAAO,EAAE,OAAO,OAAO,MAAM,OAAO;AAAA,EACtC;AAAA,EAEA,MAAM,WACJ,MAYa;AACb,QAAI;AACF,YAAM,SAAwB,MAAMA,SAAQ,IAAI,IAAI;AACpD,YAAM,SAAS,gBAAgB,OAAO,UAAU;AAEhD,YAAM,UAAU,MAAM,KAAK,eAAe,IAAI;AAC9C,YAAM,MAAM,SAAS,OAAO,OAAO,OAAO,CAAC;AAC3C,YAAM,UAAU,SAAS,WAAW,OAAO,WAAW,CAAC;AAEvD,UAAI;AAEJ,UAAI;AACF,cAAM,IAAI,MAAM,OAAO,QAAQ;AAC/B,kBAAU;AAAA,UACR,YAAY,EAAE;AAAA,UACd,aAAa,EAAE;AAAA,UACf,kBAAkB,EAAE;AAAA,UACpB,eAAe,EAAE;AAAA,UACjB,gBAAgB,EAAE;AAAA,UAClB,YAAY,EAAE;AAAA,UACd,YAAY,EAAE;AAAA,UACd,UAAU,EAAE;AAAA,UACZ,aAAa,EAAE,UAAU,QAAQ;AAAA,QACnC;AAAA,MACF,QAAQ;AACN,kBAAU;AAAA,MACZ;AAEA,aAAO;AAAA,QACL,MAAM,OAAO;AAAA,QACb,QAAQ,OAAO;AAAA,QACf,OAAO,OAAO;AAAA,QACd,MAAM,OAAO;AAAA,QACb,WAAW,OAAO;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW,cAAc,OAAO,SAAS;AAAA,QACzC,WAAW,cAAc,OAAO,SAAS;AAAA,MAC3C;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,UAAU,MAAyD;AACvE,QAAI;AACF,YAAM,SAAwB,MAAMA,SAAQ,IAAI,IAAI;AACpD,aAAO,EAAE,MAAM,QAAQ,OAAO,OAAO;AAAA,IACvC,QAAQ;AACN,aAAO,EAAE,MAAM,QAAQ,UAAU;AAAA,IACnC;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,aAAqBD,OAA0D;AAC5F,UAAM,eAAe,KAAK,YAAYA,KAAI;AAC1C,UAAM,SAAS,MAAM,KAAK,kBAAkB,WAAW;AACvD,UAAME,MAAK,OAAO,GAAG;AACrB,UAAM,UAAU,OAAOA,IAAG,iBAAiB,aACvC,MAAMA,IAAG,aAAa,YAAY,IAClC,MAAMA,IAAG,WAAW,YAAY;AACpC,WAAO,EAAE,MAAM,cAAc,QAAQ;AAAA,EACvC;AAAA,EAEA,MAAM,UAAU,aAAqBF,OAAc,SAA4C;AAC7F,UAAM,eAAe,KAAK,YAAYA,KAAI;AAC1C,UAAM,SAAS,MAAM,KAAK,kBAAkB,WAAW;AACvD,UAAM,QAAQ,aAAa,MAAM,GAAG,EAAE,OAAO,OAAO;AACpD,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,MAAM,MAAM,MAAM,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG;AAC5C,UAAI;AACF,cAAM,OAAO,GAAG,EAAE,MAAM,GAAG;AAAA,MAC7B,QAAQ;AAAA,MAER;AAAA,IACF;AACA,UAAM,OAAO,GAAG,EAAE,MAAM,cAAc,OAAO,KAAK,OAAO,CAAC;AAC1D,WAAO,EAAE,MAAM,aAAa;AAAA,EAC9B;AAAA,EAEA,MAAM,SACJ,aACAA,OACA,WAC6D;AAC7D,UAAM,eAAe,KAAK,YAAYA,KAAI;AAC1C,UAAM,SAAS,MAAM,KAAK,kBAAkB,WAAW;AACvD,UAAM,UAAU,MAAM,OAAO,GAAG,EAAE,KAAK,YAAY;AACnD,WAAO;AAAA,MACL,SAAS,QAAQ,IAAI,CAAC,WAAW;AAAA,QAC/B,MAAM,MAAM;AAAA,QACZ,MAAM,MAAM;AAAA,MACd,EAAE;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,MAAM,UAAU,aAAqBA,OAAc,SAA+C;AAChG,UAAM,eAAe,KAAK,YAAYA,KAAI;AAC1C,UAAM,SAAS,MAAM,KAAK,kBAAkB,WAAW;AACvD,UAAM,YAAY,QAAQ,SAAS,GAAG,IAAI,UAAU;AACpD,UAAM,SAAS,MAAM,OAAO,KAAK,QAAQ,CAAC,cAAc,WAAW,SAAS,SAAS,GAAG,CAAC;AACzF,WAAO,EAAE,OAAO,OAAO,OAAO,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO,EAAE;AAAA,EAC9D;AAAA,EAEA,MAAM,aACJ,aACAA,OACA,OACgE;AAChE,UAAM,eAAe,KAAK,YAAYA,KAAI;AAC1C,UAAM,SAAS,MAAM,KAAK,kBAAkB,WAAW;AACvD,QAAI;AAEJ,QAAI;AACF,YAAM,SAAS,MAAM,OAAO,KAAK,QAAQ,CAAC,MAAM,MAAM,OAAO,YAAY,CAAC;AAC1E,eAAS,OAAO,OAAO;AAAA,IACzB,SAAS,OAAO;AACd,UAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAS,MAAM,SAAS,GAAG;AACtF,eAAO,EAAE,SAAS,CAAC,EAAE;AAAA,MACvB;AAEA,YAAM;AAAA,IACR;AAEA,WAAO;AAAA,MACL,SAAS,OACN,MAAM,IAAI,EACV,OAAO,OAAO,EACd,IAAI,CAAC,SAAS;AACb,cAAM,YAAY,KAAK,QAAQ,GAAG;AAClC,eAAO;AAAA,UACL,MAAM,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;AAAA,UACrC,SAAS,KAAK,MAAM,YAAY,CAAC;AAAA,QACnC;AAAA,MACF,CAAC;AAAA,IACL;AAAA,EACF;AAAA,EAEA,MAAM,cACJ,aACA,OAC+B;AAC/B,UAAM,eAAe,KAAK,YAAY,MAAM,IAAI;AAChD,UAAM,SAAS,MAAM,KAAK,kBAAkB,WAAW;AACvD,UAAME,MAAK,OAAO,GAAG;AACrB,UAAM,WAAW,OAAOA,IAAG,iBAAiB,aACxC,MAAMA,IAAG,aAAa,YAAY,IAClC,MAAMA,IAAG,WAAW,YAAY;AAEpC,QAAI,CAAC,MAAM,QAAQ;AACjB,aAAO,EAAE,UAAU,EAAE;AAAA,IACvB;AAEA,UAAM,cAAc,SAAS,MAAM,MAAM,MAAM,EAAE,SAAS;AAC1D,QAAI,gBAAgB,GAAG;AACrB,aAAO,EAAE,UAAU,EAAE;AAAA,IACvB;AAEA,UAAM,UAAU,SAAS,MAAM,MAAM,MAAM,EAAE,KAAK,MAAM,OAAO;AAC/D,UAAMA,IAAG,MAAM,cAAc,OAAO,KAAK,OAAO,CAAC;AAEjD,WAAO,EAAE,UAAU,YAAY;AAAA,EACjC;AAAA,EAEA,MAAM,WAAW,aAAqBF,OAAc,eAAkD;AACpG,UAAM,eAAe,KAAK,YAAYA,KAAI;AAC1C,UAAM,SAAS,MAAM,KAAK,kBAAkB,WAAW;AACvD,UAAM,OAAO,GAAG,EAAE,MAAM,cAAc,OAAO,KAAK,eAAe,QAAQ,CAAC;AAC1E,WAAO,EAAE,MAAM,aAAa;AAAA,EAC9B;AAAA,EAEA,MAAM,aAAa,aAAqBA,OAAgE;AACtG,UAAM,eAAe,KAAK,YAAYA,KAAI;AAC1C,UAAM,SAAS,MAAM,KAAK,kBAAkB,WAAW;AACvD,UAAM,OAAO,MAAM,OAAO,GAAG,EAAE,KAAK,YAAY;AAChD,UAAM,SAAS,OAAO,SAAS,IAAI,IAAI,OAAO,OAAO,KAAK,IAAI;AAC9D,WAAO,EAAE,MAAM,cAAc,eAAe,OAAO,SAAS,QAAQ,EAAE;AAAA,EACxE;AAAA,EAEA,MAAM,YAAY,OAAsF;AACtG,UAAM,SAAS,MAAM,KAAK,kBAAkB,MAAM,WAAW;AAC7D,UAAM,SAAS,MAAM,OAAO,MAAM,MAAM,OAAO;AAE/C,WAAO;AAAA,MACL,QAAQ,OAAO,OAAO;AAAA,MACtB,QAAQ,OAAO,OAAO;AAAA,MACtB,UAAU,OAAO,QAAQ;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,MAAM,eACJ,MACA,MAQC;AACD,UAAM,SAAwB,MAAMC,SAAQ,IAAI,IAAI;AAEpD,UAAM,UAA6F,CAAC;AAEpG,QAAI,KAAK,SAAS,QAAW;AAC3B,cAAQ,OAAO,KAAK;AAAA,IACtB;AAEA,QAAI,KAAK,OAAO;AACd,cAAQ,QAAQ,IAAI,KAAK,KAAK,KAAK;AAAA,IACrC;AAEA,QAAI,KAAK,OAAO;AACd,cAAQ,QAAQ,IAAI,KAAK,KAAK,KAAK;AAAA,IACrC;AAEA,QAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;AAC3C,cAAQ,UAAU,KAAK;AAAA,IACzB,OAAO;AACL,cAAQ,UAAU,CAAC,KAAsB;AAAA,IAC3C;AAEA,UAAM,UAAU,MAAM,OAAO,KAAK,OAAO;AAEzC,WAAO;AAAA,MACL,SAAS,QAAQ,IAAI,CAAC,WAAW;AAAA,QAC/B,WAAW,MAAM,UAAU,YAAY;AAAA,QACvC,QAAQ,MAAM;AAAA,QACd,WAAW,MAAM;AAAA,QACjB,MAAM,MAAM,KAAK;AAAA,MACnB,EAAE;AAAA,IACJ;AAAA,EACF;AACF;;;AE/iBA,OAAO,UAAU;AACjB,OAAO,eAAe;AACtB,OAAO,cAAc;AACrB,OAAO,aAAuC;;;ACHvC,IAAM,YAAN,cAAwB,MAAM;AAAA,EACnC,YACS,YACA,MACP,SACA;AACA,UAAM,OAAO;AAJN;AACA;AAAA,EAIT;AACF;AAEO,SAAS,gBAAgB,OAS9B;AACA,MAAI,iBAAiB,WAAW;AAC9B,WAAO;AAAA,MACL,YAAY,MAAM;AAAA,MAClB,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM,MAAM;AAAA,UACZ,SAAS,MAAM;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AACF;;;ACtCO,SAAS,GAAM,MAA6B;AACjD,SAAO;AAAA,IACL,SAAS;AAAA,IACT;AAAA,EACF;AACF;;;ACPO,SAAS,qBAAqB,KAA4B;AAC/D,MAAI,IAAI,WAAW,YAAY,GAAG,EAAE,QAAQ,KAAK,CAAC,CAAC;AACrD;;;ACJA,SAAS,gBAAgB;;;ACDzB,OAAO,OAAO;AAEP,IAAM,sBAAsB,EAAE,OAAO;AAAA,EAC1C,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC;AACvB,CAAC;AAEM,IAAM,kBAAkB,EAAE,OAAO;AAAA,EACtC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC;AACvB,CAAC;;;ADDD,SAAS,aAAgB,OAAmB;AAC1C,MAAI;AACF,WAAO,MAAM;AAAA,EACf,SAAS,OAAO;AACd,QAAI,iBAAiB,UAAU;AAC7B,YAAM,IAAI,UAAU,KAAK,mBAAmB,MAAM,OAAO,CAAC,GAAG,WAAW,iBAAiB;AAAA,IAC3F;AAEA,UAAM;AAAA,EACR;AACF;AAEO,SAAS,sBAAsB,cAA4B;AAChE,SAAO;AAAA,IACL,YAAY,OAAO,UAA0B,UAAwB;AACnE,aAAO,MAAM,KAAK,GAAG,MAAM,aAAa,WAAW,CAAC,CAAC;AAAA,IACvD;AAAA,IACA,WAAW,OAAO,SAA4C,UAAwB;AACpF,YAAM,OAAO,aAAa,MAAM,gBAAgB,MAAM,QAAQ,QAAQ,CAAC,CAAC,CAAC;AACzE,aAAO,MAAM,KAAK,GAAG,MAAM,aAAa,UAAU,IAAI,CAAC,CAAC;AAAA,IAC1D;AAAA,IACA,UAAU,OAAO,SAAmD,UAAwB;AAC1F,YAAM,QAAQ,aAAa,MAAM,oBAAoB,MAAM,QAAQ,SAAS,CAAC,CAAC,CAAC;AAC/E,aAAO,MAAM,KAAK,GAAG,MAAM,aAAa,SAAS,MAAM,GAAG,CAAC,CAAC;AAAA,IAC9D;AAAA,IACA,aAAa,OAAO,SAAmD,UAAwB;AAC7F,YAAM,QAAQ,aAAa,MAAM,oBAAoB,MAAM,QAAQ,SAAS,CAAC,CAAC,CAAC;AAC/E,aAAO,MAAM,KAAK,GAAG,MAAM,aAAa,YAAY,MAAM,GAAG,CAAC,CAAC;AAAA,IACjE;AAAA,EACF;AACF;;;AEjCO,SAAS,oBAAoB,KAAsB,cAAkC;AAC1F,QAAM,aAAa,sBAAsB,YAAY;AAErD,MAAI,IAAI,eAAe,WAAW,UAAU;AAC5C,MAAI,KAAK,oBAAoB,WAAW,SAAS;AACjD,MAAI,IAAI,sBAAsB,WAAW,QAAQ;AACjD,MAAI,OAAO,sBAAsB,WAAW,WAAW;AACzD;;;ACXA,OAAOE,QAAO;AAEd,IAAM,kBAAkBA,GAAE,OAAO;AAAA,EAC/B,MAAMA,GAAE,QAAQ,MAAM;AAAA,EACtB,QAAQA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,UAAUA,GAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AAED,IAAM,mBAAmBA,GAAE,OAAO;AAAA,EAChC,MAAMA,GAAE,QAAQ,OAAO;AAAA,EACvB,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACtB,UAAUA,GAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AAED,IAAM,mBAAmBA,GAAE,OAAO;AAAA,EAChC,MAAMA,GAAE,QAAQ,OAAO;AAAA,EACvB,SAASA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAChD,CAAC;AAEM,IAAM,eAAeA,GAAE,MAAM;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,sBAAsBA,GAAE,OAAO;AAAA,EAC1C,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,MAAMA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EAC3C,WAAWA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EAChD,KAAKA,GAAE,OAAOA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACnC,SAASA,GAAE,OAAO,YAAY,EAAE,SAAS;AAC3C,CAAC;AAEM,IAAM,0BAA0BA,GAAE,OAAO;AAAA,EAC9C,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC;AAEM,IAAM,2BAA2BA,GAAE,OAAO;AAAA,EAC/C,QAAQA,GAAE,KAAK,CAAC,WAAW,WAAW,WAAW,SAAS,CAAC,EAAE,SAAS;AAAA,EACtE,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EAClC,QAAQA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AACrC,CAAC;AAED,IAAM,uBAAuBA,GAAE,OAAO;AAAA,EACpC,aAAaA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC;AAEM,IAAM,iBAAiB;AAEvB,IAAM,kBAAkB,qBAAqB,OAAO;AAAA,EACzD,SAASA,GAAE,OAAO;AACpB,CAAC;AAEM,IAAM,iBAAiB,qBAAqB,OAAO;AAAA,EACxD,WAAWA,GAAE,QAAQ,EAAE,SAAS;AAClC,CAAC;AAEM,IAAM,kBAAkB,qBAAqB,OAAO;AAAA,EACzD,SAASA,GAAE,OAAO,EAAE,IAAI,CAAC;AAC3B,CAAC;AAEM,IAAM,qBAAqB,qBAAqB,OAAO;AAAA,EAC5D,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC;AACzB,CAAC;AAEM,IAAM,sBAAsB,qBAAqB,OAAO;AAAA,EAC7D,QAAQA,GAAE,OAAO;AAAA,EACjB,SAASA,GAAE,OAAO;AACpB,CAAC;AAEM,IAAM,mBAAmB,qBAAqB;AAAA,EACnDA,GAAE,MAAM;AAAA,IACNA,GAAE,OAAO,EAAE,eAAeA,GAAE,OAAO,EAAE,CAAC;AAAA,IACtCA,GAAE,OAAO,EAAE,SAASA,GAAE,OAAO,EAAE,UAAU,CAAC,YAAY,OAAO,KAAK,OAAO,EAAE,SAAS,QAAQ,CAAC,EAAE,CAAC;AAAA,EAClG,CAAC;AACH;AAEO,IAAM,qBAAqB;AAE3B,IAAM,kBAAkBA,GAAE,OAAO;AAAA,EACtC,aAAaA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,SAASA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,UAAUA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,SAASA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAChD,CAAC;AAEM,IAAM,oBAAoBA,GAAE,OAAO;AAAA,EACxC,MAAMA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EAC3C,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,SAASA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AACxC,CAAC;;;ACxEM,SAAS,wBAAwB,gBAiDtC;AACA,SAAO;AAAA,IACL,eAAe,OACb,SACA,UACG;AACH,YAAM,OAAO,oBAAoB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACzD,YAAM,SAAS,MAAM,eAAe,cAAc,QAAQ,OAAO,MAAM,IAAI;AAC3E,aAAO,MAAM,KAAK,GAAG,MAAM,CAAC;AAAA,IAC9B;AAAA,IAEA,cAAc,OAAO,SAAS,UAAU;AACtC,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,aAAa,QAAQ,OAAO,IAAI,CAAC,CAAC;AAAA,IAC9E;AAAA,IAEA,aAAa,OAAO,SAAS,UAAU;AACrC,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,YAAY,QAAQ,OAAO,IAAI,CAAC,CAAC;AAAA,IAC7E;AAAA,IAEA,aAAa,OAAO,SAAS,UAAU;AACrC,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,YAAY,QAAQ,OAAO,IAAI,CAAC,CAAC;AAAA,IAC7E;AAAA,IAEA,eAAe,OAAO,SAAS,UAAU;AACvC,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,cAAc,QAAQ,OAAO,IAAI,CAAC,CAAC;AAAA,IAC/E;AAAA,IAEA,eAAe,OAAO,SAAS,UAAU;AACvC,YAAM,QAAQ,yBAAyB,MAAM,QAAQ,SAAS,CAAC,CAAC;AAChE,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,cAAc,KAAK,CAAC,CAAC;AAAA,IACjE;AAAA,IAEA,YAAY,OAAO,SAAS,UAAU;AACpC,YAAM,SAAS,wBAAwB,MAAM,QAAQ,UAAU,CAAC,CAAC;AACjE,YAAM,UAAU,MAAM,eAAe,WAAW,OAAO,IAAI;AAE3D,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI,UAAU,KAAK,qBAAqB,YAAY,OAAO,IAAI,aAAa;AAAA,MACpF;AAEA,aAAO,MAAM,KAAK,GAAG,OAAO,CAAC;AAAA,IAC/B;AAAA,IAEA,WAAW,OAAO,SAAS,UAAU;AACnC,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,UAAU,QAAQ,OAAO,IAAI,CAAC,CAAC;AAAA,IAC3E;AAAA,IAEA,gBAAgB,OAAO,SAAS,UAAU;AACxC,YAAM,OAAO,kBAAkB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACvD,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,eAAe,QAAQ,OAAO,MAAM,IAAI,CAAC,CAAC;AAAA,IACtF;AAAA,IAEA,UAAU,OAAO,SAAS,UAAU;AAClC,YAAM,OAAO,eAAe,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACpD,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,SAAS,KAAK,aAAa,KAAK,IAAI,CAAC,CAAC;AAAA,IAClF;AAAA,IAEA,WAAW,OAAO,SAAS,UAAU;AACnC,YAAM,OAAO,gBAAgB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACrD,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,UAAU,KAAK,aAAa,KAAK,MAAM,KAAK,OAAO,CAAC,CAAC;AAAA,IACjG;AAAA,IAEA,UAAU,OAAO,SAAS,UAAU;AAClC,YAAM,OAAO,eAAe,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACpD,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,SAAS,KAAK,aAAa,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC;AAAA,IAClG;AAAA,IAEA,WAAW,OAAO,SAAS,UAAU;AACnC,YAAM,OAAO,gBAAgB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACrD,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,UAAU,KAAK,aAAa,KAAK,MAAM,KAAK,OAAO,CAAC,CAAC;AAAA,IACjG;AAAA,IAEA,cAAc,OAAO,SAAS,UAAU;AACtC,YAAM,OAAO,mBAAmB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACxD,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,aAAa,KAAK,aAAa,KAAK,MAAM,KAAK,KAAK,CAAC,CAAC;AAAA,IAClG;AAAA,IAEA,eAAe,OAAO,SAAS,UAAU;AACvC,YAAM,OAAO,oBAAoB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACzD,aAAO,MAAM;AAAA,QACX;AAAA,UACE,MAAM,eAAe,cAAc,KAAK,aAAa;AAAA,YACnD,MAAM,KAAK;AAAA,YACX,QAAQ,KAAK;AAAA,YACb,SAAS,KAAK;AAAA,UAChB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IAEA,YAAY,OAAO,SAAS,UAAU;AACpC,YAAM,OAAO,iBAAiB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACtD,YAAM,gBAAgB,mBAAmB,OAAO,KAAK,gBAAgB,OAAO,KAAK,KAAK,OAAO,EAAE,SAAS,QAAQ;AAChH,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,WAAW,KAAK,aAAa,KAAK,MAAM,aAAa,CAAC,CAAC;AAAA,IACnG;AAAA,IAEA,cAAc,OAAO,SAAS,UAAU;AACtC,YAAM,QAAQ,mBAAmB,MAAM,QAAQ,SAAS,CAAC,CAAC;AAC1D,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,aAAa,MAAM,aAAa,MAAM,IAAI,CAAC,CAAC;AAAA,IACxF;AAAA,IAEA,aAAa,OAAO,SAAS,UAAU;AACrC,YAAM,OAAO,gBAAgB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACrD,aAAO,MAAM,KAAK,GAAG,MAAM,eAAe,YAAY,IAAI,CAAC,CAAC;AAAA,IAC9D;AAAA,EACF;AACF;;;AC3KO,SAAS,sBACd,KACA,gBACM;AACN,QAAM,aAAa,wBAAwB,cAAc;AAEzD,MAAI,IAAI,kBAAkB,WAAW,aAAa;AAClD,MAAI,IAAI,wBAAwB,WAAW,UAAU;AACrD,MAAI,IAAI,wBAAwB,WAAW,aAAa;AACxD,MAAI,KAAK,8BAA8B,WAAW,YAAY;AAC9D,MAAI,KAAK,6BAA6B,WAAW,WAAW;AAC5D,MAAI,KAAK,6BAA6B,WAAW,WAAW;AAC5D,MAAI,OAAO,wBAAwB,WAAW,aAAa;AAC3D,MAAI,IAAI,+BAA+B,WAAW,SAAS;AAC3D,MAAI,KAAK,6BAA6B,WAAW,cAAc;AAE/D,MAAI,KAAK,mBAAmB,WAAW,QAAQ;AAC/C,MAAI,KAAK,oBAAoB,WAAW,SAAS;AACjD,MAAI,KAAK,mBAAmB,WAAW,QAAQ;AAC/C,MAAI,KAAK,mBAAmB,WAAW,SAAS;AAChD,MAAI,KAAK,qBAAqB,WAAW,YAAY;AACrD,MAAI,KAAK,sBAAsB,WAAW,aAAa;AACvD,MAAI,KAAK,qBAAqB,WAAW,UAAU;AACnD,MAAI,IAAI,uBAAuB,WAAW,YAAY;AAEtD,MAAI,KAAK,mBAAmB,WAAW,WAAW;AACpD;;;AC7BA,OAAO,QAAQ;AACf,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,UAAAC,eAAc;AACvB,OAAOC,QAAO;;;ACLd,OAAOC,QAAO;AAEP,IAAM,qBAAqBA,GAAE,OAAO;AAAA,EACzC,MAAMA,GAAE,OAAO;AACjB,CAAC;AAEM,IAAM,sBAAsBA,GAAE,OAAO;AAAA,EAC1C,MAAMA,GAAE,OAAO;AAAA,EACf,SAASA,GAAE,OAAO;AACpB,CAAC;AAEM,IAAM,qBAAqBA,GAAE,OAAO;AAAA,EACzC,MAAMA,GAAE,OAAO;AACjB,CAAC;AAEM,IAAM,uBAAuBA,GAAE,OAAO;AAAA,EAC3C,MAAMA,GAAE,OAAO;AAAA,EACf,eAAeA,GAAE,OAAO,EAAE,IAAI,CAAC;AACjC,CAAC;AAEM,IAAM,yBAAyBA,GAAE,OAAO;AAAA,EAC7C,MAAMA,GAAE,OAAO;AACjB,CAAC;;;ADFD,IAAM,eAAe,KAAK,KAAK,GAAG,QAAQ,GAAG,eAAe;AAE5D,eAAe,sBAAsB,MAA+B;AAClE,MAAI;AACF,UAAM,SAAS,MAAMC,QAAO,IAAI,IAAI;AACpC,UAAM,MAAM,MAAMA,QAAO,QAAQ,OAAO,IAAI,EAAE,OAAO;AACrD,WAAO,IAAI;AAAA,EACb,QAAQ;AACN,QAAI;AACF,YAAM,MAAM,MAAMA,QAAO,QAAQ,IAAI,EAAE,OAAO;AAC9C,aAAO,IAAI;AAAA,IACb,QAAQ;AACN,aAAO,KAAK,KAAK,cAAc,WAAW,IAAI;AAAA,IAChD;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,UAAkB,WAA2B;AACrE,QAAM,aAAa,cAAc,MAAM,KAAK,UAAU,QAAQ,QAAQ,EAAE;AACxE,QAAM,WAAW,KAAK,KAAK,UAAU,KAAK,UAAU,UAAU,EAAE,QAAQ,qBAAqB,EAAE,CAAC;AAChG,MAAI,CAAC,SAAS,WAAW,WAAW,KAAK,GAAG,KAAK,aAAa,UAAU;AACtE,UAAM,IAAI,UAAU,KAAK,kBAAkB,yBAAyB;AAAA,EACtE;AACA,SAAO;AACT;AAEO,SAAS,2BAqBd;AACA,SAAO;AAAA,IACL,UAAU,OAAO,SAAS,UAAU;AAClC,YAAM,EAAE,KAAK,IAAI,QAAQ;AAEzB,UAAI;AACF,cAAM,EAAE,MAAM,UAAU,IAAI,mBAAmB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACvE,cAAM,WAAW,MAAM,sBAAsB,IAAI;AACjD,cAAM,WAAW,iBAAiB,UAAU,SAAS;AACrD,cAAM,UAAU,MAAM,GAAG,SAAS,UAAU,OAAO;AACnD,eAAO,MAAM,KAAK,GAAG,EAAE,MAAM,WAAW,QAAQ,CAAC,CAAC;AAAA,MACpD,SAAS,KAAc;AACrB,YAAI,eAAeC,GAAE,UAAU;AAC7B,gBAAM,IAAI,UAAU,KAAK,oBAAoB,IAAI,OAAO;AAAA,QAC1D;AACA,YAAI,eAAe,UAAW,OAAM;AACpC,cAAM,IAAI,UAAU,KAAK,qBAAqB,+BAA+B,IAAI,MAAM,OAAO,GAAG,CAAC,EAAE;AAAA,MACtG;AAAA,IACF;AAAA,IAEA,WAAW,OAAO,SAAS,UAAU;AACnC,YAAM,EAAE,KAAK,IAAI,QAAQ;AAEzB,UAAI;AACF,cAAM,EAAE,MAAM,WAAW,QAAQ,IAAI,oBAAoB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACjF,cAAM,WAAW,MAAM,sBAAsB,IAAI;AACjD,cAAM,WAAW,iBAAiB,UAAU,SAAS;AACrD,cAAM,GAAG,MAAM,KAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1D,cAAM,GAAG,UAAU,UAAU,SAAS,OAAO;AAC7C,eAAO,MAAM,KAAK,GAAG,EAAE,MAAM,UAAU,CAAC,CAAC;AAAA,MAC3C,SAAS,KAAc;AACrB,YAAI,eAAeA,GAAE,UAAU;AAC7B,gBAAM,IAAI,UAAU,KAAK,oBAAoB,IAAI,OAAO;AAAA,QAC1D;AACA,YAAI,eAAe,UAAW,OAAM;AACpC,cAAM,IAAI,UAAU,KAAK,sBAAsB,8BAA8B,IAAI,MAAM,OAAO,GAAG,CAAC,EAAE;AAAA,MACtG;AAAA,IACF;AAAA,IAEA,UAAU,OAAO,SAAS,UAAU;AAClC,YAAM,EAAE,KAAK,IAAI,QAAQ;AAEzB,UAAI;AACF,cAAM,EAAE,MAAM,UAAU,IAAI,mBAAmB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACvE,cAAM,WAAW,MAAM,sBAAsB,IAAI;AACjD,cAAM,WAAW,iBAAiB,UAAU,SAAS;AACrD,cAAM,UAAU,MAAM,GAAG,QAAQ,UAAU,EAAE,eAAe,KAAK,CAAC;AAClE,cAAM,UAAU,QAAQ,IAAI,CAAC,OAAO;AAAA,UAClC,MAAM,YAAY,GAAG,SAAS,IAAI,EAAE,IAAI,KAAK,EAAE;AAAA,UAC/C,MAAM,EAAE,YAAY,IAAI,cAAc,EAAE,eAAe,IAAI,YAAY;AAAA,UACvE,MAAM;AAAA,UACN,MAAM;AAAA,QACR,EAAE;AACF,eAAO,MAAM,KAAK,GAAG,EAAE,QAAQ,CAAC,CAAC;AAAA,MACnC,SAAS,KAAc;AACrB,YAAI,eAAeA,GAAE,UAAU;AAC7B,gBAAM,IAAI,UAAU,KAAK,oBAAoB,IAAI,OAAO;AAAA,QAC1D;AACA,YAAI,eAAe,UAAW,OAAM;AACpC,cAAM,IAAI,UAAU,KAAK,qBAAqB,0BAA0B,IAAI,MAAM,OAAO,GAAG,CAAC,EAAE;AAAA,MACjG;AAAA,IACF;AAAA,IAEA,cAAc,OAAO,SAAS,UAAU;AACtC,YAAM,EAAE,KAAK,IAAI,QAAQ;AAEzB,UAAI;AACF,cAAM,EAAE,MAAM,UAAU,IAAI,uBAAuB,MAAM,QAAQ,SAAS,CAAC,CAAC;AAC5E,cAAM,WAAW,MAAM,sBAAsB,IAAI;AACjD,cAAM,WAAW,iBAAiB,UAAU,SAAS;AACrD,cAAM,MAAM,MAAM,GAAG,SAAS,QAAQ;AACtC,cAAM,gBAAgB,IAAI,SAAS,QAAQ;AAC3C,eAAO,MAAM,KAAK,GAAG,EAAE,MAAM,WAAW,cAAc,CAAC,CAAC;AAAA,MAC1D,SAAS,KAAc;AACrB,YAAI,eAAeA,GAAE,UAAU;AAC7B,gBAAM,IAAI,UAAU,KAAK,oBAAoB,IAAI,OAAO;AAAA,QAC1D;AACA,YAAI,eAAe,UAAW,OAAM;AACpC,cAAM,IAAI,UAAU,KAAK,yBAAyB,mCAAmC,IAAI,MAAM,OAAO,GAAG,CAAC,EAAE;AAAA,MAC9G;AAAA,IACF;AAAA,IAEA,YAAY,OAAO,SAAS,UAAU;AACpC,YAAM,EAAE,KAAK,IAAI,QAAQ;AAEzB,UAAI;AACF,cAAM,EAAE,MAAM,WAAW,cAAc,IAAI,qBAAqB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACxF,cAAM,WAAW,MAAM,sBAAsB,IAAI;AACjD,cAAM,WAAW,iBAAiB,UAAU,SAAS;AACrD,cAAM,GAAG,MAAM,KAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1D,cAAM,OAAO,OAAO,KAAK,eAAe,QAAQ;AAChD,cAAM,GAAG,UAAU,UAAU,IAAI;AACjC,eAAO,MAAM,KAAK,GAAG,EAAE,MAAM,UAAU,CAAC,CAAC;AAAA,MAC3C,SAAS,KAAc;AACrB,YAAI,eAAeA,GAAE,UAAU;AAC7B,gBAAM,IAAI,UAAU,KAAK,oBAAoB,IAAI,OAAO;AAAA,QAC1D;AACA,YAAI,eAAe,UAAW,OAAM;AACpC,cAAM,IAAI,UAAU,KAAK,uBAAuB,+BAA+B,IAAI,MAAM,OAAO,GAAG,CAAC,EAAE;AAAA,MACxG;AAAA,IACF;AAAA,EACF;AACF;;;AEtKO,SAAS,uBAAuB,KAA4B;AACjE,QAAM,aAAa,yBAAyB;AAE5C,MAAI,KAAK,8BAA8B,WAAW,QAAQ;AAC1D,MAAI,KAAK,+BAA+B,WAAW,SAAS;AAC5D,MAAI,KAAK,8BAA8B,WAAW,QAAQ;AAC1D,MAAI,IAAI,kCAAkC,WAAW,YAAY;AACjE,MAAI,KAAK,gCAAgC,WAAW,UAAU;AAChE;;;ACXA,SAAS,QAAAC,aAAY;AACrB,SAAS,aAAAC,kBAAiB;AAI1B,IAAMC,aAAYC,WAAUC,KAAI;AA4BhC,IAAM,4BAAN,MAAyD;AAAA,EACvD,IAAY,MAAc;AACxB,WAAO,WAAW;AAAA,EACpB;AAAA,EAEA,MAAM,OAA+B;AACnC,UAAM,EAAE,OAAO,IAAI,MAAMF,WAAU,GAAG,KAAK,GAAG,yBAAyB;AACvE,UAAM,SAAyB,KAAK,MAAM,MAAM;AAChD,WAAO,OAAO,IAAI,CAAC,SAAS;AAAA,MAC1B,KAAK,IAAI;AAAA,MACT,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,MAAM,IAAI;AAAA,MACV,WAAW,IAAI;AAAA,IACjB,EAAE;AAAA,EACJ;AAAA,EAEA,MAAM,KAAK,KAAmC;AAC5C,UAAMA,WAAU,GAAG,KAAK,GAAG,eAAe,GAAG,EAAE;AAC/C,WAAO,KAAK,QAAQ,GAAG;AAAA,EACzB;AAAA,EAEA,MAAM,QAAQ,KAAmC;AAC/C,UAAM,EAAE,OAAO,IAAI,MAAMA,WAAU,GAAG,KAAK,GAAG,kBAAkB,GAAG,gBAAgB;AACnF,UAAM,MAAoB,KAAK,MAAM,MAAM;AAC3C,WAAO;AAAA,MACL,KAAK,IAAI;AAAA,MACT,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,MAAM,IAAI;AAAA,MACV,WAAW,IAAI;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,KAA4B;AACvC,UAAMA,WAAU,GAAG,KAAK,GAAG,aAAa,GAAG,EAAE;AAAA,EAC/C;AACF;AAEO,IAAM,eAAN,MAAmB;AAAA,EACxB,YACmB,OAEb,CAAC,GACL;AAHiB;AAAA,EAGhB;AAAA,EAEH,IAAY,WAA0B;AACpC,WAAO,KAAK,KAAK,YAAY,IAAI,0BAA0B;AAAA,EAC7D;AAAA,EAEA,MAAM,aAA+D;AACnE,UAAM,QAAQ,MAAM,KAAK,SAAS,KAAK;AACvC,WAAO,EAAE,OAAO,OAAO,MAAM,OAAO;AAAA,EACtC;AAAA,EAEA,MAAM,UAAU,OAA6C;AAC3D,WAAO,MAAM,KAAK,SAAS,KAAK,MAAM,GAAG;AAAA,EAC3C;AAAA,EAEA,MAAM,SAAS,KAAmC;AAChD,WAAO,MAAM,KAAK,SAAS,QAAQ,GAAG;AAAA,EACxC;AAAA,EAEA,MAAM,YAAY,KAAuC;AACvD,UAAM,KAAK,SAAS,OAAO,GAAG;AAC9B,WAAO,EAAE,IAAI;AAAA,EACf;AACF;;;ACnGA,OAAO,aAAa;AACpB,OAAO,eAAe;AAEf,IAAM,uBAAuB;AAAA,EAClC,SAAS;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,MACJ,OAAO;AAAA,MACP,aACE;AAAA,MACF,SAAS;AAAA,IACX;AAAA,IACA,SAAS;AAAA,MACP;AAAA,QACE,KAAK;AAAA,QACL,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,YAAY;AAAA,MACV,iBAAiB;AAAA,QACf,YAAY;AAAA,UACV,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,IACA,MAAM;AAAA,MACJ,EAAE,MAAM,aAAa,aAAa,8CAA8C;AAAA,MAChF,EAAE,MAAM,SAAS,aAAa,qEAAqE;AAAA,MACnG,EAAE,MAAM,SAAS,aAAa,oCAAoC;AAAA,MAClE,EAAE,MAAM,UAAU,aAAa,qDAAqD;AAAA,MACpF,EAAE,MAAM,WAAW,aAAa,qCAAqC;AAAA,MACrE,EAAE,MAAM,UAAU,aAAa,uBAAuB;AAAA,IACxD;AAAA,EACF;AACF;AAEO,IAAM,yBAAyB;AAAA,EACpC,aAAa;AAAA,EACb,UAAU;AAAA,IACR,cAAc;AAAA,IACd,aAAa;AAAA,EACf;AAAA,EACA,WAAW;AAAA,EACX,oBAAoB,CAAC,WAAmB;AAC1C;AAEA,eAAsB,iBACpB,KACA,qBACA,uBACA;AACA,QAAM,gBAAgB,EAAE,GAAG,sBAAsB,GAAG,oBAAoB;AACxE,QAAM,kBAAkB;AAAA,IACtB,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAEA,QAAM,IAAI,SAAS,SAAS,aAAa;AACzC,QAAM,IAAI,SAAS,WAAW,eAAe;AAC/C;;;AdhDA,eAAsB,SAAS;AAAA,EAC7B,iBAAiB,IAAI,2BAA2B;AAAA,EAChD,eAAe,IAAI,aAAa;AAAA,EAChC;AACF,IAII,CAAC,GAA6B;AAChC,QAAM,MAAM,QAAQ;AAAA,IAClB,QAAQ;AAAA,IACR,WAAW,OAAO,QAAQ,IAAI,UAAU,KAAK,MAAM,OAAO;AAAA,EAC5D,CAAC;AAED,MAAI,SAAS,MAAM;AAAA,IACjB,WAAW,CAAC,SAAS,aAAa;AAChC,eAAS,MAAM;AAAA,QACb,QAAQ;AAAA,QACR,SAAS,QAAQ,QAAQ,+BAA+B,KAAK;AAAA,QAC7D,gBAAgB,QAAQ,QAAQ,gCAAgC;AAAA,MAClE,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AACD,MAAI,SAAS,QAAQ;AACrB,MAAI,SAAS,SAAS;AAEtB,MAAI,QAAQ;AACV,QAAI,QAAQ,aAAa,OAAO,SAAS,UAAU;AACjD,UAAI,QAAQ,WAAW,aAAa,CAAC,QAAQ,IAAI,WAAW,OAAO,GAAG;AACpE;AAAA,MACF;AAEA,UAAI,QAAQ,QAAQ,kBAAkB,UAAU,MAAM,IAAI;AACxD,cAAM,MAAM,KAAK,GAAG,EAAE,KAAK;AAAA,UACzB,SAAS;AAAA,UACT,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS;AAAA,UACX;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAEA,uBAAqB,GAAG;AACxB,wBAAsB,KAAK,cAAc;AACzC,sBAAoB,KAAK,YAAY;AACrC,yBAAuB,GAAG;AAE1B,MAAI,gBAAgB,CAAC,OAAO,UAAU,UAAU;AAC9C,UAAM,EAAE,YAAY,KAAK,IAAI,gBAAgB,KAAK;AAClD,UAAM,OAAO,UAAU,EAAE,KAAK,IAAI;AAAA,EACpC,CAAC;AAED,QAAM,iBAAiB,GAAG;AAE1B,SAAO;AACT;","names":["fs","Sandbox","path","Sandbox","fs","z","Volume","z","z","Volume","z","exec","promisify","execAsync","promisify","exec"]}