@sandblocks/cli 0.6.8 → 0.6.10

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/dist/cli.js CHANGED
@@ -12578,6 +12578,23 @@ class SandblocksClient {
12578
12578
  listSandboxes(projectId) {
12579
12579
  return this.request(`/v1/projects/${encodeURIComponent(projectId)}/sandboxes`);
12580
12580
  }
12581
+ cleanupSandboxes(input) {
12582
+ return this.request(`/v1/projects/${encodeURIComponent(input.projectId)}/sandboxes/cleanup`, {
12583
+ method: "POST",
12584
+ body: JSON.stringify({
12585
+ ids: input.ids,
12586
+ stack: input.stack,
12587
+ deploymentType: input.deploymentType,
12588
+ statuses: input.statuses,
12589
+ olderThanHours: input.olderThanHours,
12590
+ dryRun: input.dryRun,
12591
+ purge: input.purge
12592
+ })
12593
+ });
12594
+ }
12595
+ removeSandbox(projectId, sandboxId, purge = true) {
12596
+ return this.cleanupSandboxes({ projectId, ids: [sandboxId], purge });
12597
+ }
12581
12598
  listAgentSessions(projectId, sandboxId) {
12582
12599
  return this.request(`/v1/projects/${encodeURIComponent(projectId)}/sandboxes/${encodeURIComponent(sandboxId)}/agent-sessions`);
12583
12600
  }
@@ -13286,10 +13303,11 @@ async function create(args, dependencies) {
13286
13303
  projectId,
13287
13304
  sandboxId,
13288
13305
  workspaceId,
13289
- pool: dependencies.option(options, "pool") ?? process.env.SANDBLOCKS_WORKER_POOL ?? "build-fleet",
13306
+ pool: dependencies.option(options, "pool") ?? process.env.SANDBLOCKS_WORKER_POOL ?? (preview.mode === "development" ? undefined : "build-fleet"),
13290
13307
  apiUrl,
13291
13308
  apiKey,
13292
13309
  idempotencyKey: `${sandboxId}:workspace-import`,
13310
+ requiredWorkerRole: preview.mode === "development" ? "development" : "build",
13293
13311
  source: dependencies.source,
13294
13312
  ..."image" in loaded.manifest.workspace && loaded.manifest.workspace.image ? { workspaceImage: loaded.manifest.workspace.image } : {}
13295
13313
  });
@@ -13456,7 +13474,7 @@ async function deployUnlocked(args, dependencies) {
13456
13474
  workspaceId: buildWorkspaceId,
13457
13475
  sandboxId: context.state.sandboxId,
13458
13476
  revisionId: deploymentId,
13459
- runtimeType: preview.deploymentType,
13477
+ runtimeType: managedEnvironmentId(context),
13460
13478
  serviceUrls,
13461
13479
  steps: serviceSteps,
13462
13480
  ..."image" in loaded.manifest.workspace && loaded.manifest.workspace.image ? { workspaceImage: loaded.manifest.workspace.image } : {},
@@ -13574,7 +13592,7 @@ async function deployUnlocked(args, dependencies) {
13574
13592
  workspaceId: context.state.workspaceId,
13575
13593
  deploymentId,
13576
13594
  sandboxId: context.state.sandboxId,
13577
- runtimeType: preview.deploymentType,
13595
+ runtimeType: managedEnvironmentId(context),
13578
13596
  stack,
13579
13597
  workspace: preview.workspace,
13580
13598
  artifactImage,
@@ -13630,7 +13648,7 @@ async function deployUnlocked(args, dependencies) {
13630
13648
  workspaceId: buildWorkspaceId ?? context.state.workspaceId,
13631
13649
  deploymentId,
13632
13650
  sandboxId: context.state.sandboxId,
13633
- runtimeType: preview.deploymentType,
13651
+ runtimeType: managedEnvironmentId(context),
13634
13652
  checks: preview.steps,
13635
13653
  serviceUrls: serviceUrls2,
13636
13654
  placement: {
@@ -13694,7 +13712,7 @@ async function deployDevelopmentUnlocked(context, loaded, preview) {
13694
13712
  workspaceId: context.state.workspaceId,
13695
13713
  sandboxId: context.state.sandboxId,
13696
13714
  revisionId: context.state.sourceRevision ?? deploymentId,
13697
- runtimeType: preview.deploymentType,
13715
+ runtimeType: managedEnvironmentId(context),
13698
13716
  serviceUrls,
13699
13717
  steps,
13700
13718
  ..."image" in loaded.manifest.workspace && loaded.manifest.workspace.image ? { workspaceImage: loaded.manifest.workspace.image } : {},
@@ -13721,7 +13739,7 @@ async function deployDevelopmentUnlocked(context, loaded, preview) {
13721
13739
  workspaceId: context.state.workspaceId,
13722
13740
  deploymentId,
13723
13741
  sandboxId: context.state.sandboxId,
13724
- runtimeType: preview.deploymentType,
13742
+ runtimeType: managedEnvironmentId(context),
13725
13743
  stack,
13726
13744
  workspace: preview.workspace,
13727
13745
  mutableDevelopment: true,
@@ -14148,16 +14166,19 @@ async function importSource(input) {
14148
14166
  "x-sandblocks-api-key": input.apiKey,
14149
14167
  "x-sandblocks-workspace-id": input.workspaceId,
14150
14168
  ...input.sandboxId ? { "x-sandblocks-sandbox-id": input.sandboxId } : {},
14151
- "x-sandblocks-worker-pool": input.pool,
14169
+ ...input.pool ? { "x-sandblocks-worker-pool": input.pool } : {},
14152
14170
  ...input.memoryReservationBytes ? { "x-sandblocks-memory-reservation-bytes": String(input.memoryReservationBytes) } : {},
14171
+ ...input.requiredWorkerRole ? { "x-sandblocks-worker-role": input.requiredWorkerRole } : {},
14153
14172
  ...input.workspaceImage ? { "x-sandblocks-workspace-image": input.workspaceImage } : {},
14154
14173
  "idempotency-key": input.idempotencyKey
14155
14174
  },
14156
14175
  body: new Blob([Uint8Array.from(source.bundle)])
14157
14176
  });
14158
14177
  const submitted = await response.json().catch(() => ({}));
14159
- if (!response.ok)
14160
- throw new Error(String(submitted?.error ?? `sandbox import failed (${response.status})`));
14178
+ if (!response.ok) {
14179
+ const placement = submitted?.placement ? `: ${JSON.stringify(submitted.placement)}` : "";
14180
+ throw new Error(`${String(submitted?.error ?? `sandbox import failed (${response.status})`)}${placement}`);
14181
+ }
14161
14182
  return {
14162
14183
  files: source.files,
14163
14184
  bytes: source.bundle.byteLength,
@@ -15675,6 +15696,9 @@ var HELP = `Sandblocks CLI
15675
15696
  sandblocks sandbox redeploy [directory] [--environment <id>] [--build-pool <pool>]
15676
15697
  sandblocks sandbox status [directory] [--environment <id>] [--json]
15677
15698
  sandblocks sandbox promote --project <id> --sandbox <id> [--json]
15699
+ sandblocks sandbox cleanup --project <id> [--sandbox <id>] [--stack <id>]
15700
+ [--deployment-type <id>] [--status <status>] [--older-than-hours <n>]
15701
+ [--dry-run] [--keep-records] [--json]
15678
15702
  sandblocks sandbox agent <run|list|get|cancel|redeploy> --project <id> --sandbox <id>
15679
15703
  [--repository <id>] [--provider <codex|claude-code|pi>] [--model <id>]
15680
15704
  [--prompt <text> | --prompt-file <path>] [--session <id>] [--wait] [--json]
@@ -16143,6 +16167,9 @@ function printResources(kind, action, body) {
16143
16167
  function objectRecord(value) {
16144
16168
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
16145
16169
  }
16170
+ function multiValue(value) {
16171
+ return Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
16172
+ }
16146
16173
  async function sandbox(args) {
16147
16174
  const [subcommand, ...rest] = args;
16148
16175
  if (isStatefulSandboxCommand(subcommand) && !(subcommand === "deploy" && rest.includes("--workspace"))) {
@@ -16157,6 +16184,8 @@ async function sandbox(args) {
16157
16184
  return sandboxDeploy(rest);
16158
16185
  if (subcommand === "promote")
16159
16186
  return sandboxPromote(rest);
16187
+ if (subcommand === "cleanup" || subcommand === "remove")
16188
+ return sandboxCleanup(rest);
16160
16189
  if (subcommand === "agent")
16161
16190
  return sandboxAgent(rest);
16162
16191
  if (subcommand !== "import")
@@ -16270,6 +16299,45 @@ async function waitForAgentSession(apiUrl, apiKey, projectId, sandboxId, session
16270
16299
  await Bun.sleep(1000);
16271
16300
  }
16272
16301
  }
16302
+ async function sandboxCleanup(args) {
16303
+ const options = parse2(args);
16304
+ const projectId = option2(options, "project");
16305
+ const apiUrl = (option2(options, "api-url") ?? process.env.SANDBLOCKS_API_URL ?? "").replace(/\/$/, "");
16306
+ const apiKey = option2(options, "api-key") ?? process.env.SANDBLOCKS_API_KEY;
16307
+ if (!projectId)
16308
+ throw new Error("sandbox cleanup requires --project");
16309
+ if (!apiUrl || !apiKey)
16310
+ throw new Error("sandbox cleanup requires API URL and API key");
16311
+ const ids = multiValue(options.sandbox);
16312
+ const statuses = multiValue(options.status);
16313
+ const stack = option2(options, "stack");
16314
+ const deploymentType = option2(options, "deployment-type");
16315
+ const olderThanHours = option2(options, "older-than-hours");
16316
+ if (!ids.length && !statuses.length && !stack && !deploymentType && !olderThanHours)
16317
+ throw new Error("sandbox cleanup requires --sandbox, --stack, --deployment-type, --status, or --older-than-hours");
16318
+ const result = await sandblocksRequest(apiUrl, apiKey, `/v1/projects/${encodeURIComponent(projectId)}/sandboxes/cleanup`, {
16319
+ method: "POST",
16320
+ body: JSON.stringify({
16321
+ ...ids.length ? { ids } : {},
16322
+ ...statuses.length ? { statuses } : {},
16323
+ ...stack ? { stack } : {},
16324
+ ...deploymentType ? { deploymentType } : {},
16325
+ ...olderThanHours ? { olderThanHours: Number(olderThanHours) } : {},
16326
+ dryRun: options["dry-run"] === true,
16327
+ purge: options["keep-records"] !== true
16328
+ })
16329
+ });
16330
+ if (options.json)
16331
+ console.log(JSON.stringify(result, null, 2));
16332
+ else {
16333
+ const selected = result.removed ?? result.matched ?? [];
16334
+ console.log(`${result.dryRun ? "matched" : "removed"} ${selected.length} deployment(s)`);
16335
+ for (const id2 of selected)
16336
+ console.log(` ${id2}`);
16337
+ for (const skipped of result.skipped ?? [])
16338
+ console.log(`skipped ${skipped.id}: ${skipped.reason}`);
16339
+ }
16340
+ }
16273
16341
  async function sandboxPromote(args) {
16274
16342
  const options = parse2(args);
16275
16343
  const projectId = option2(options, "project");
@@ -16591,7 +16659,9 @@ function parse2(args) {
16591
16659
  "rootless",
16592
16660
  "allow-unpinned-images",
16593
16661
  "read-only-root",
16594
- "resume"
16662
+ "resume",
16663
+ "dry-run",
16664
+ "keep-records"
16595
16665
  ].includes(rawKey)) {
16596
16666
  output[rawKey] = inline === undefined ? true : inline !== "false";
16597
16667
  continue;
@@ -16658,4 +16728,4 @@ export {
16658
16728
  parse2 as parse
16659
16729
  };
16660
16730
 
16661
- //# debugId=818C8E6D2946F5CD64756E2164756E21
16731
+ //# debugId=D7067CF7EF69C62A64756E2164756E21