From 1463bbdc3937315d8ae7bb2042ef9e504bbfc04a Mon Sep 17 00:00:00 2001 From: Anand Pant Date: Sat, 28 Feb 2026 15:40:01 -0600 Subject: [PATCH 1/2] Make Daytona sandbox lifecycle policies configurable and stop hardcoding auto-stop/delete values, while right-sizing standard Blacksmith CI jobs to 2 vCPU to lower cost for this lightweight workload. --- .github/workflows/check.yml | 6 +-- .github/workflows/publish-package.yml | 4 +- .github/workflows/validate-pr-title.yml | 2 +- README.md | 8 +++ src/analyze-repos.ts | 71 ++++++++++++++++++++++--- src/start-opencode-daytona.ts | 70 +++++++++++++++++++++--- 6 files changed, 139 insertions(+), 22 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 16d66e9..a156204 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -17,7 +17,7 @@ env: jobs: Check: name: Check - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: blacksmith-2vcpu-ubuntu-2404 steps: - name: Checkout uses: actions/checkout@v4 @@ -47,7 +47,7 @@ jobs: BuildPackage: name: Build Package Artifact - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: blacksmith-2vcpu-ubuntu-2404 needs: Check steps: - name: Checkout @@ -84,7 +84,7 @@ jobs: PackageE2E: name: Package Install E2E - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: blacksmith-2vcpu-ubuntu-2404 needs: BuildPackage steps: - name: Setup Node diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml index 758e597..710912e 100644 --- a/.github/workflows/publish-package.yml +++ b/.github/workflows/publish-package.yml @@ -16,7 +16,7 @@ permissions: jobs: resolve-merge-context: name: Resolve Merge Context - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: blacksmith-2vcpu-ubuntu-2404 permissions: contents: read pull-requests: read @@ -122,7 +122,7 @@ jobs: publish-and-manage-bump: name: Publish Package + Manage Bump PR - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: blacksmith-2vcpu-ubuntu-2404 needs: resolve-merge-context permissions: contents: write diff --git a/.github/workflows/validate-pr-title.yml b/.github/workflows/validate-pr-title.yml index df3e0a2..eac2bce 100644 --- a/.github/workflows/validate-pr-title.yml +++ b/.github/workflows/validate-pr-title.yml @@ -10,7 +10,7 @@ permissions: jobs: ValidatePrTitle: name: ValidatePrTitle - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: blacksmith-2vcpu-ubuntu-2404 steps: - name: Validate pull request title env: diff --git a/README.md b/README.md index 31fcc83..0369ac2 100644 --- a/README.md +++ b/README.md @@ -160,8 +160,15 @@ Useful `start` flags: bun run start -- --port 3000 --target us --sandbox-name opencode-dev bun run start -- --keep-sandbox bun run start -- --no-open +bun run start -- --auto-stop-interval 60 +bun run start -- --auto-stop-interval 0 --auto-delete-interval -1 ``` +`start` and `analyze` also honor these env vars when flags are omitted: + +- `DAYTONA_AUTO_STOP_INTERVAL` (minutes, `0` disables auto-stop) +- `DAYTONA_AUTO_DELETE_INTERVAL` (minutes, `-1` disables auto-delete) + --- ## Repository Audit Workflow @@ -195,6 +202,7 @@ bun run analyze -- https://github.com/owner/repo-one https://github.com/owner/re bun run analyze -- --out-dir findings --model zai-coding-plan/glm-4.7-flash --target us bun run analyze -- --vision bun run analyze -- --analyze-timeout-sec 3600 --keep-sandbox +bun run analyze -- --auto-stop-interval 30 --auto-delete-interval -1 --input example.md ``` If no URLs and no `--input` are provided, the script uses `example.md` when it exists. diff --git a/src/analyze-repos.ts b/src/analyze-repos.ts index 4c64287..dabb566 100644 --- a/src/analyze-repos.ts +++ b/src/analyze-repos.ts @@ -14,6 +14,8 @@ type CliOptions = { createTimeoutSec: number; installTimeoutSec: number; analyzeTimeoutSec: number; + autoStopInterval?: number; + autoDeleteInterval?: number; keepSandbox: boolean; target?: string; model?: string; @@ -52,6 +54,32 @@ function parsePositiveInt(value: string, flag: string): number { return parsed; } +function parseAutoStopInterval(value: string | undefined, source: string): number | undefined { + if (value === undefined) { + return undefined; + } + const parsed = Number.parseInt(value, 10); + if (!Number.isInteger(parsed) || parsed < 0) { + throw new Error( + `${source} must be a non-negative integer (0 disables auto-stop). Received "${value}".`, + ); + } + return parsed; +} + +function parseAutoDeleteInterval(value: string | undefined, source: string): number | undefined { + if (value === undefined) { + return undefined; + } + const parsed = Number.parseInt(value, 10); + if (!Number.isInteger(parsed) || (parsed !== -1 && parsed <= 0)) { + throw new Error( + `${source} must be -1 (disable auto-delete) or a positive integer. Received "${value}".`, + ); + } + return parsed; +} + function requireEnv(name: string): string { const value = process.env[name]; if (!value) { @@ -178,6 +206,8 @@ function parseCliOptions(): CliOptions { "create-timeout-sec": { type: "string", default: "180" }, "install-timeout-sec": { type: "string", default: "900" }, "analyze-timeout-sec": { type: "string", default: "2400" }, + "auto-stop-interval": { type: "string" }, + "auto-delete-interval": { type: "string" }, "keep-sandbox": { type: "boolean", default: false }, target: { type: "string" }, model: { type: "string" }, @@ -203,6 +233,8 @@ Options: --create-timeout-sec Sandbox creation timeout (default: 180) --install-timeout-sec OpenCode install timeout (default: 900) --analyze-timeout-sec Per-repo analysis timeout (default: 2400) + --auto-stop-interval Daytona auto-stop interval (minutes, 0 disables) + --auto-delete-interval Daytona auto-delete interval (minutes, -1 disables) --target Daytona target override --model OpenCode model (default: zai-coding-plan/glm-4.7-flash) --variant Model variant (example: xhigh) @@ -213,12 +245,24 @@ Options: process.exit(0); } + const autoStopInterval = + parseAutoStopInterval(values["auto-stop-interval"], "--auto-stop-interval") ?? + parseAutoStopInterval(process.env.DAYTONA_AUTO_STOP_INTERVAL, "DAYTONA_AUTO_STOP_INTERVAL"); + const autoDeleteInterval = + parseAutoDeleteInterval(values["auto-delete-interval"], "--auto-delete-interval") ?? + parseAutoDeleteInterval( + process.env.DAYTONA_AUTO_DELETE_INTERVAL, + "DAYTONA_AUTO_DELETE_INTERVAL", + ); + return { inputFile: values.input, outDir: values["out-dir"], createTimeoutSec: parsePositiveInt(values["create-timeout-sec"], "--create-timeout-sec"), installTimeoutSec: parsePositiveInt(values["install-timeout-sec"], "--install-timeout-sec"), analyzeTimeoutSec: parsePositiveInt(values["analyze-timeout-sec"], "--analyze-timeout-sec"), + autoStopInterval, + autoDeleteInterval, keepSandbox: values["keep-sandbox"], target: values.target, model: values.model, @@ -615,14 +659,25 @@ async function analyzeOneRepo(params: { const sandboxName = sanitizeSlug( `audit-${slug}-${Date.now().toString(36)}${Math.random().toString(36).slice(2, 6)}`, ).slice(0, 63); - sandbox = await daytona.create( - { - name: sandboxName, - language: "typescript", - autoStopInterval: 0, - }, - { timeout: options.createTimeoutSec }, - ); + + const createParams: { + name: string; + language: "typescript"; + autoStopInterval?: number; + autoDeleteInterval?: number; + } = { + name: sandboxName, + language: "typescript", + }; + + if (options.autoStopInterval !== undefined) { + createParams.autoStopInterval = options.autoStopInterval; + } + if (options.autoDeleteInterval !== undefined) { + createParams.autoDeleteInterval = options.autoDeleteInterval; + } + + sandbox = await daytona.create(createParams, { timeout: options.createTimeoutSec }); console.log(`[analyze] (${runPrefix}) Sandbox ready: ${sandbox.id}`); const userHome = (await sandbox.getUserHomeDir()) ?? "/home/daytona"; diff --git a/src/start-opencode-daytona.ts b/src/start-opencode-daytona.ts index 9c5b2a5..cc1c86b 100644 --- a/src/start-opencode-daytona.ts +++ b/src/start-opencode-daytona.ts @@ -13,6 +13,8 @@ type CliOptions = { sandboxName?: string; createTimeoutSec: number; installTimeoutSec: number; + autoStopInterval?: number; + autoDeleteInterval?: number; target?: string; openUi: boolean; }; @@ -45,6 +47,32 @@ function parsePort(value: string): number { return parsed; } +function parseAutoStopInterval(value: string | undefined, source: string): number | undefined { + if (value === undefined) { + return undefined; + } + const parsed = Number.parseInt(value, 10); + if (!Number.isInteger(parsed) || parsed < 0) { + throw new Error( + `${source} must be a non-negative integer (0 disables auto-stop). Received "${value}".`, + ); + } + return parsed; +} + +function parseAutoDeleteInterval(value: string | undefined, source: string): number | undefined { + if (value === undefined) { + return undefined; + } + const parsed = Number.parseInt(value, 10); + if (!Number.isInteger(parsed) || (parsed !== -1 && parsed <= 0)) { + throw new Error( + `${source} must be -1 (disable auto-delete) or a positive integer. Received "${value}".`, + ); + } + return parsed; +} + function parseCliOptions(): CliOptions { const { values } = parseArgs({ options: { @@ -54,6 +82,8 @@ function parseCliOptions(): CliOptions { "sandbox-name": { type: "string" }, "create-timeout-sec": { type: "string", default: "180" }, "install-timeout-sec": { type: "string", default: "900" }, + "auto-stop-interval": { type: "string" }, + "auto-delete-interval": { type: "string" }, target: { type: "string" }, "no-open": { type: "boolean", default: false }, }, @@ -70,6 +100,8 @@ Options: --sandbox-name Custom sandbox name --create-timeout-sec Sandbox creation timeout seconds (default: 180) --install-timeout-sec OpenCode install timeout seconds (default: 900) + --auto-stop-interval Daytona auto-stop interval (minutes, 0 disables) + --auto-delete-interval Daytona auto-delete interval (minutes, -1 disables) --keep-sandbox Keep sandbox after stopping (default: false) --no-open Do not auto-open OpenCode URL -h, --help Show this help @@ -77,12 +109,24 @@ Options: process.exit(0); } + const autoStopInterval = + parseAutoStopInterval(values["auto-stop-interval"], "--auto-stop-interval") ?? + parseAutoStopInterval(process.env.DAYTONA_AUTO_STOP_INTERVAL, "DAYTONA_AUTO_STOP_INTERVAL"); + const autoDeleteInterval = + parseAutoDeleteInterval(values["auto-delete-interval"], "--auto-delete-interval") ?? + parseAutoDeleteInterval( + process.env.DAYTONA_AUTO_DELETE_INTERVAL, + "DAYTONA_AUTO_DELETE_INTERVAL", + ); + return { port: parsePort(values.port), keepSandbox: values["keep-sandbox"], sandboxName: values["sandbox-name"], createTimeoutSec: parsePositiveInt(values["create-timeout-sec"], "--create-timeout-sec"), installTimeoutSec: parsePositiveInt(values["install-timeout-sec"], "--install-timeout-sec"), + autoStopInterval, + autoDeleteInterval, target: values.target, openUi: !values["no-open"], }; @@ -410,14 +454,24 @@ async function main(): Promise { try { console.log("[local] Creating Daytona sandbox..."); - sandbox = await daytona.create( - { - name: options.sandboxName, - language: "typescript", - autoStopInterval: 0, - }, - { timeout: options.createTimeoutSec }, - ); + const createParams: { + name?: string; + language: "typescript"; + autoStopInterval?: number; + autoDeleteInterval?: number; + } = { + name: options.sandboxName, + language: "typescript", + }; + + if (options.autoStopInterval !== undefined) { + createParams.autoStopInterval = options.autoStopInterval; + } + if (options.autoDeleteInterval !== undefined) { + createParams.autoDeleteInterval = options.autoDeleteInterval; + } + + sandbox = await daytona.create(createParams, { timeout: options.createTimeoutSec }); console.log(`[local] Sandbox ready: ${sandbox.id}`); const userHome = (await sandbox.getUserHomeDir()) ?? "/home/daytona"; From b4f62143063cc87fc8e45d73dec8a4b96a32f434 Mon Sep 17 00:00:00 2001 From: Anand Pant Date: Sat, 28 Feb 2026 18:21:08 -0600 Subject: [PATCH 2/2] Set a fixed Daytona lifecycle policy so sandboxes auto-stop/archive by default and remove lifecycle flags/env overrides from start/analyze CLI flows to keep managed usage simple. --- README.md | 9 +---- src/analyze-repos.ts | 67 ++++++----------------------------- src/start-opencode-daytona.ts | 67 ++++++----------------------------- 3 files changed, 21 insertions(+), 122 deletions(-) diff --git a/README.md b/README.md index 0369ac2..ebc2cc9 100644 --- a/README.md +++ b/README.md @@ -160,15 +160,8 @@ Useful `start` flags: bun run start -- --port 3000 --target us --sandbox-name opencode-dev bun run start -- --keep-sandbox bun run start -- --no-open -bun run start -- --auto-stop-interval 60 -bun run start -- --auto-stop-interval 0 --auto-delete-interval -1 ``` -`start` and `analyze` also honor these env vars when flags are omitted: - -- `DAYTONA_AUTO_STOP_INTERVAL` (minutes, `0` disables auto-stop) -- `DAYTONA_AUTO_DELETE_INTERVAL` (minutes, `-1` disables auto-delete) - --- ## Repository Audit Workflow @@ -192,6 +185,7 @@ bun run start -- --auto-stop-interval 0 --auto-delete-interval -1 - Auto-installs missing `git` and `node/npm` inside sandbox - Forwards provider env vars (`OPENAI_*`, `ANTHROPIC_*`, `XAI_*`, `OPENROUTER_*`, `ZHIPU_*`, `MINIMAX_*`, etc.) - Syncs local OpenCode config files from `~/.config/opencode` when present +- Uses a fixed Daytona lifecycle policy: auto-stop after 15 minutes, auto-archive after 30 minutes, auto-delete disabled - Auto-catalogs findings into Obsidian when enabled via `shpit.toml`, with optional automatic `ob sync` in headless mode ### Examples @@ -202,7 +196,6 @@ bun run analyze -- https://github.com/owner/repo-one https://github.com/owner/re bun run analyze -- --out-dir findings --model zai-coding-plan/glm-4.7-flash --target us bun run analyze -- --vision bun run analyze -- --analyze-timeout-sec 3600 --keep-sandbox -bun run analyze -- --auto-stop-interval 30 --auto-delete-interval -1 --input example.md ``` If no URLs and no `--input` are provided, the script uses `example.md` when it exists. diff --git a/src/analyze-repos.ts b/src/analyze-repos.ts index dabb566..c541b3a 100644 --- a/src/analyze-repos.ts +++ b/src/analyze-repos.ts @@ -14,8 +14,6 @@ type CliOptions = { createTimeoutSec: number; installTimeoutSec: number; analyzeTimeoutSec: number; - autoStopInterval?: number; - autoDeleteInterval?: number; keepSandbox: boolean; target?: string; model?: string; @@ -24,6 +22,12 @@ type CliOptions = { urls: string[]; }; +const SANDBOX_LIFECYCLE_POLICY = { + autoStopInterval: 15, + autoArchiveInterval: 30, + autoDeleteInterval: -1, +} as const; + type DaytonaCompatClient = { configApi: { configControllerGetConfig: () => Promise<{ @@ -54,32 +58,6 @@ function parsePositiveInt(value: string, flag: string): number { return parsed; } -function parseAutoStopInterval(value: string | undefined, source: string): number | undefined { - if (value === undefined) { - return undefined; - } - const parsed = Number.parseInt(value, 10); - if (!Number.isInteger(parsed) || parsed < 0) { - throw new Error( - `${source} must be a non-negative integer (0 disables auto-stop). Received "${value}".`, - ); - } - return parsed; -} - -function parseAutoDeleteInterval(value: string | undefined, source: string): number | undefined { - if (value === undefined) { - return undefined; - } - const parsed = Number.parseInt(value, 10); - if (!Number.isInteger(parsed) || (parsed !== -1 && parsed <= 0)) { - throw new Error( - `${source} must be -1 (disable auto-delete) or a positive integer. Received "${value}".`, - ); - } - return parsed; -} - function requireEnv(name: string): string { const value = process.env[name]; if (!value) { @@ -206,8 +184,6 @@ function parseCliOptions(): CliOptions { "create-timeout-sec": { type: "string", default: "180" }, "install-timeout-sec": { type: "string", default: "900" }, "analyze-timeout-sec": { type: "string", default: "2400" }, - "auto-stop-interval": { type: "string" }, - "auto-delete-interval": { type: "string" }, "keep-sandbox": { type: "boolean", default: false }, target: { type: "string" }, model: { type: "string" }, @@ -233,8 +209,6 @@ Options: --create-timeout-sec Sandbox creation timeout (default: 180) --install-timeout-sec OpenCode install timeout (default: 900) --analyze-timeout-sec Per-repo analysis timeout (default: 2400) - --auto-stop-interval Daytona auto-stop interval (minutes, 0 disables) - --auto-delete-interval Daytona auto-delete interval (minutes, -1 disables) --target Daytona target override --model OpenCode model (default: zai-coding-plan/glm-4.7-flash) --variant Model variant (example: xhigh) @@ -245,24 +219,12 @@ Options: process.exit(0); } - const autoStopInterval = - parseAutoStopInterval(values["auto-stop-interval"], "--auto-stop-interval") ?? - parseAutoStopInterval(process.env.DAYTONA_AUTO_STOP_INTERVAL, "DAYTONA_AUTO_STOP_INTERVAL"); - const autoDeleteInterval = - parseAutoDeleteInterval(values["auto-delete-interval"], "--auto-delete-interval") ?? - parseAutoDeleteInterval( - process.env.DAYTONA_AUTO_DELETE_INTERVAL, - "DAYTONA_AUTO_DELETE_INTERVAL", - ); - return { inputFile: values.input, outDir: values["out-dir"], createTimeoutSec: parsePositiveInt(values["create-timeout-sec"], "--create-timeout-sec"), installTimeoutSec: parsePositiveInt(values["install-timeout-sec"], "--install-timeout-sec"), analyzeTimeoutSec: parsePositiveInt(values["analyze-timeout-sec"], "--analyze-timeout-sec"), - autoStopInterval, - autoDeleteInterval, keepSandbox: values["keep-sandbox"], target: values.target, model: values.model, @@ -660,23 +622,14 @@ async function analyzeOneRepo(params: { `audit-${slug}-${Date.now().toString(36)}${Math.random().toString(36).slice(2, 6)}`, ).slice(0, 63); - const createParams: { - name: string; - language: "typescript"; - autoStopInterval?: number; - autoDeleteInterval?: number; - } = { + const createParams = { name: sandboxName, language: "typescript", + autoStopInterval: SANDBOX_LIFECYCLE_POLICY.autoStopInterval, + autoArchiveInterval: SANDBOX_LIFECYCLE_POLICY.autoArchiveInterval, + autoDeleteInterval: SANDBOX_LIFECYCLE_POLICY.autoDeleteInterval, }; - if (options.autoStopInterval !== undefined) { - createParams.autoStopInterval = options.autoStopInterval; - } - if (options.autoDeleteInterval !== undefined) { - createParams.autoDeleteInterval = options.autoDeleteInterval; - } - sandbox = await daytona.create(createParams, { timeout: options.createTimeoutSec }); console.log(`[analyze] (${runPrefix}) Sandbox ready: ${sandbox.id}`); diff --git a/src/start-opencode-daytona.ts b/src/start-opencode-daytona.ts index cc1c86b..7e22f27 100644 --- a/src/start-opencode-daytona.ts +++ b/src/start-opencode-daytona.ts @@ -13,12 +13,16 @@ type CliOptions = { sandboxName?: string; createTimeoutSec: number; installTimeoutSec: number; - autoStopInterval?: number; - autoDeleteInterval?: number; target?: string; openUi: boolean; }; +const SANDBOX_LIFECYCLE_POLICY = { + autoStopInterval: 15, + autoArchiveInterval: 30, + autoDeleteInterval: -1, +} as const; + type LogCursor = { value: string }; type DaytonaCompatClient = { configApi: { @@ -47,32 +51,6 @@ function parsePort(value: string): number { return parsed; } -function parseAutoStopInterval(value: string | undefined, source: string): number | undefined { - if (value === undefined) { - return undefined; - } - const parsed = Number.parseInt(value, 10); - if (!Number.isInteger(parsed) || parsed < 0) { - throw new Error( - `${source} must be a non-negative integer (0 disables auto-stop). Received "${value}".`, - ); - } - return parsed; -} - -function parseAutoDeleteInterval(value: string | undefined, source: string): number | undefined { - if (value === undefined) { - return undefined; - } - const parsed = Number.parseInt(value, 10); - if (!Number.isInteger(parsed) || (parsed !== -1 && parsed <= 0)) { - throw new Error( - `${source} must be -1 (disable auto-delete) or a positive integer. Received "${value}".`, - ); - } - return parsed; -} - function parseCliOptions(): CliOptions { const { values } = parseArgs({ options: { @@ -82,8 +60,6 @@ function parseCliOptions(): CliOptions { "sandbox-name": { type: "string" }, "create-timeout-sec": { type: "string", default: "180" }, "install-timeout-sec": { type: "string", default: "900" }, - "auto-stop-interval": { type: "string" }, - "auto-delete-interval": { type: "string" }, target: { type: "string" }, "no-open": { type: "boolean", default: false }, }, @@ -100,8 +76,6 @@ Options: --sandbox-name Custom sandbox name --create-timeout-sec Sandbox creation timeout seconds (default: 180) --install-timeout-sec OpenCode install timeout seconds (default: 900) - --auto-stop-interval Daytona auto-stop interval (minutes, 0 disables) - --auto-delete-interval Daytona auto-delete interval (minutes, -1 disables) --keep-sandbox Keep sandbox after stopping (default: false) --no-open Do not auto-open OpenCode URL -h, --help Show this help @@ -109,24 +83,12 @@ Options: process.exit(0); } - const autoStopInterval = - parseAutoStopInterval(values["auto-stop-interval"], "--auto-stop-interval") ?? - parseAutoStopInterval(process.env.DAYTONA_AUTO_STOP_INTERVAL, "DAYTONA_AUTO_STOP_INTERVAL"); - const autoDeleteInterval = - parseAutoDeleteInterval(values["auto-delete-interval"], "--auto-delete-interval") ?? - parseAutoDeleteInterval( - process.env.DAYTONA_AUTO_DELETE_INTERVAL, - "DAYTONA_AUTO_DELETE_INTERVAL", - ); - return { port: parsePort(values.port), keepSandbox: values["keep-sandbox"], sandboxName: values["sandbox-name"], createTimeoutSec: parsePositiveInt(values["create-timeout-sec"], "--create-timeout-sec"), installTimeoutSec: parsePositiveInt(values["install-timeout-sec"], "--install-timeout-sec"), - autoStopInterval, - autoDeleteInterval, target: values.target, openUi: !values["no-open"], }; @@ -454,23 +416,14 @@ async function main(): Promise { try { console.log("[local] Creating Daytona sandbox..."); - const createParams: { - name?: string; - language: "typescript"; - autoStopInterval?: number; - autoDeleteInterval?: number; - } = { + const createParams = { name: options.sandboxName, language: "typescript", + autoStopInterval: SANDBOX_LIFECYCLE_POLICY.autoStopInterval, + autoArchiveInterval: SANDBOX_LIFECYCLE_POLICY.autoArchiveInterval, + autoDeleteInterval: SANDBOX_LIFECYCLE_POLICY.autoDeleteInterval, }; - if (options.autoStopInterval !== undefined) { - createParams.autoStopInterval = options.autoStopInterval; - } - if (options.autoDeleteInterval !== undefined) { - createParams.autoDeleteInterval = options.autoDeleteInterval; - } - sandbox = await daytona.create(createParams, { timeout: options.createTimeoutSec }); console.log(`[local] Sandbox ready: ${sandbox.id}`);