@claxedo/sandbox-manager 0.10.2 → 0.10.3

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.
@@ -138,6 +138,27 @@ var boatBilling = {
138
138
  large: { size: "large", vcpu: 8, memoryGb: 16, usdPerHour: 0.072 }
139
139
  }
140
140
  };
141
+ var AGENT37_USD_PER_MONTH = { vcpu: 0.8, memoryGb: 0.7, diskGb: 0.09 };
142
+ var AGENT37_MONTH_HOURS = 730;
143
+ var agent37MachineShapes = {
144
+ small: { cpu: 2, memory: 4, disk: 10 },
145
+ default: { cpu: 4, memory: 8, disk: 20 },
146
+ large: { cpu: 4, memory: 16, disk: 40 }
147
+ };
148
+ function agent37Rate(shape) {
149
+ const usdPerMonth = shape.cpu * AGENT37_USD_PER_MONTH.vcpu + shape.memory * AGENT37_USD_PER_MONTH.memoryGb + shape.disk * AGENT37_USD_PER_MONTH.diskGb;
150
+ return { size: `${shape.cpu} vCPU / ${shape.memory} GB`, vcpu: shape.cpu, memoryGb: shape.memory, usdPerHour: usdPerMonth / AGENT37_MONTH_HOURS };
151
+ }
152
+ var agent37Billing = {
153
+ source: { url: "https://www.agent37.com/docs/agents-api/billing", readOn: "2026-11-11" },
154
+ meter: "Agent37 meters an instance per minute at a monthly rate over 730 hours: $0.80 per vCPU, $0.70 per GB of memory and $0.09 per GB of disk while it runs, and the disk alone while it is stopped.",
155
+ rates: {
156
+ small: agent37Rate(agent37MachineShapes.small),
157
+ default: agent37Rate(agent37MachineShapes.default),
158
+ large: agent37Rate(agent37MachineShapes.large)
159
+ },
160
+ excludes: `the disk of a stopped instance, billed at $${AGENT37_USD_PER_MONTH.diskGb} per GB a month until the instance is deleted`
161
+ };
141
162
  var CLOUDFLARE_USD_PER_GIB_SECOND_MEMORY = 25e-7;
142
163
  var CLOUDFLARE_USD_PER_GB_SECOND_DISK = 7e-8;
143
164
  var CLOUDFLARE_USD_PER_VCPU_SECOND_ACTIVE = 2e-5;
@@ -172,6 +193,7 @@ var sandboxDriverCredentialFields = {
172
193
  { key: "worker_url", label: "Worker URL" }
173
194
  ],
174
195
  boat: [{ key: "api_key", label: "API Key", secret: true }],
196
+ agent37: [{ key: "api_key", label: "API Key", secret: true }],
175
197
  docker: [{ key: "image", label: "Image" }]
176
198
  };
177
199
  var sandboxDriverLabels = {
@@ -179,6 +201,7 @@ var sandboxDriverLabels = {
179
201
  vercel: "Vercel",
180
202
  cloudflare: "Cloudflare",
181
203
  boat: "Boat",
204
+ agent37: "Agent37",
182
205
  docker: "Docker"
183
206
  };
184
207
 
@@ -249,8 +272,8 @@ var sandboxDriverCatalog = {
249
272
  hostWatchesIdle: true,
250
273
  targetAccess: "relay",
251
274
  secretBrokering: "native",
252
- // Credential handlers do not restrict unrelated destinations.
253
- egressControl: "none",
275
+ // The sandbox Worker starts the container without internet and routes each allowed host through itself; a Worker that cannot confirm that refuses the start.
276
+ egressControl: "hosts",
254
277
  // A container snapshot holds the whole root filesystem; the platform keeps it 30 days past its last restore and offers no deletion.
255
278
  persistence: {
256
279
  resume: "replacement-restore",
@@ -288,6 +311,33 @@ var sandboxDriverCatalog = {
288
311
  machineClasses: ["small", "default", "large"]
289
312
  }
290
313
  },
314
+ agent37: {
315
+ id: "agent37",
316
+ label: sandboxDriverLabels.agent37,
317
+ credentialFields: sandboxDriverCredentialFields.agent37,
318
+ runtimeNetwork: { controlPlane: "direct", relay: "configured" },
319
+ runtimeEnv: "callback",
320
+ preparedImage: true,
321
+ billing: agent37Billing,
322
+ metadata: {
323
+ driverRunsIn: ["worker", "node"],
324
+ hostStopBehavior: "suspends-host",
325
+ hostResumeBehavior: "same-host",
326
+ targetAccess: "relay",
327
+ secretBrokering: "none",
328
+ // An instance's network policy lists domains, reached over HTTPS on 443 alone, and IPv4 ranges; private ranges stay blocked whatever it lists.
329
+ egressControl: "hosts-and-cidrs",
330
+ persistence: {
331
+ resume: "same-sandbox",
332
+ capture: "none",
333
+ clone: false,
334
+ captureSource: "not-applicable",
335
+ retention: "provider-managed",
336
+ restoreMount: "same-resource"
337
+ },
338
+ machineClasses: ["small", "default", "large"]
339
+ }
340
+ },
291
341
  docker: {
292
342
  id: "docker",
293
343
  label: sandboxDriverLabels.docker,
@@ -15,11 +15,6 @@ function asRecord(value) {
15
15
  return isRecord(value) ? value : void 0;
16
16
  }
17
17
  var CLAXEDO_TOOL_NAMES = [
18
- "task_list",
19
- "task_get",
20
- "task_create",
21
- "task_edit",
22
- "task_start",
23
18
  "session_create",
24
19
  "sessions_list",
25
20
  "session_get",
@@ -30,8 +25,6 @@ var CLAXEDO_TOOL_NAMES = [
30
25
  "session_rename",
31
26
  "session_delete",
32
27
  "session_changes",
33
- "documents_list",
34
- "documents_open",
35
28
  "subagent_capabilities",
36
29
  "create_subagent",
37
30
  "subagent_status",
@@ -157,17 +150,17 @@ var AGENT_PRESENTATION_EVENT_TYPES = Object.keys(AGENT_PRESENTATION_EVENT_TYPE_R
157
150
  var mode = (id, name, description, level) => ({
158
151
  id,
159
152
  name,
160
- description,
153
+ ...description ? { description } : {},
161
154
  ...level ? { level } : {}
162
155
  });
163
156
  var CLAUDE_PERMISSION_MODES = {
164
157
  modes: [
165
- mode("default", "Default", "Standard behavior, prompts for dangerous operations", "ask"),
166
- mode("acceptEdits", "Accept edits", "Auto-accept file edit operations"),
167
- mode("auto", "Auto", "Use a model classifier to approve/deny permission prompts", "auto"),
168
- mode("plan", "Plan", "Planning mode, no actual tool execution"),
169
- mode("dontAsk", "Don't ask", "Don't prompt for permissions, deny if not pre-approved"),
170
- mode("bypassPermissions", "Bypass permissions", "Bypass all permission checks", "full")
158
+ mode("default", "Default", "Asks before dangerous operations", "ask"),
159
+ mode("acceptEdits", "Accept edits"),
160
+ mode("auto", "Auto", "A model decides which actions to allow", "auto"),
161
+ mode("plan", "Plan", "Runs no tools"),
162
+ mode("dontAsk", "Don't ask", "Denies anything not pre-approved"),
163
+ mode("bypassPermissions", "Bypass permissions", "Runs everything without asking", "full")
171
164
  ],
172
165
  appliesFrom: "immediate",
173
166
  defaultModeId: "auto"
@@ -180,9 +173,18 @@ var CURSOR_PERMISSION_MODES = {
180
173
  ],
181
174
  appliesFrom: "next-turn"
182
175
  };
176
+ var ANTIGRAVITY_PERMISSION_MODES = {
177
+ modes: [
178
+ mode("default", "Default", "Ask before edits and commands, per your permission settings.", "ask"),
179
+ mode("accept-edits", "Accept edits", "Approve file edits in the workspace without asking."),
180
+ mode("plan", "Plan")
181
+ ],
182
+ appliesFrom: "immediate",
183
+ defaultModeId: "default"
184
+ };
183
185
  var CODEX_PERMISSION_MODES = {
184
186
  modes: [
185
- mode("read-only", "Read only", "Never asks; the sandbox permits reads only, so writes fail", "ask"),
187
+ mode("read-only", "Read only", "Never asks; writes fail", "ask"),
186
188
  mode("workspace-write", "Workspace write", "Runs commands inside the workspace without asking; escalates outside it", "auto"),
187
189
  mode("untrusted", "Untrusted", "Only trusted commands run without asking; anything else escalates"),
188
190
  mode("full-access", "Full access", "Never asks; full filesystem and network access", "full")
@@ -226,6 +228,15 @@ var AGENT_HARNESS_DEFINITIONS = [
226
228
  authSlot: "cursor",
227
229
  cloudHost: "workspace-runtime"
228
230
  },
231
+ {
232
+ key: "antigravity",
233
+ id: "antigravity",
234
+ access: "native",
235
+ label: "Antigravity",
236
+ authEnv: "GEMINI_API_KEY",
237
+ authSlot: "google",
238
+ cloudHost: "workspace-runtime"
239
+ },
229
240
  {
230
241
  key: "pi",
231
242
  id: "pi",
@@ -246,7 +257,7 @@ var AGENT_HARNESS_DEFINITIONS = [
246
257
  }
247
258
  ];
248
259
  var AGENT_HARNESS_KEYS = AGENT_HARNESS_DEFINITIONS.map((item) => item.key);
249
- var HARNESS_IDS = ["claude", "codex", "cursor"];
260
+ var HARNESS_IDS = ["claude", "codex", "cursor", "antigravity"];
250
261
  var HARNESS_TABLE = {
251
262
  claude: {
252
263
  label: "Claude Code",
@@ -276,6 +287,15 @@ var HARNESS_TABLE = {
276
287
  machineLoginServes: ["cursor-acp"],
277
288
  permissionModes: CURSOR_PERMISSION_MODES,
278
289
  defaultModelId: "auto"
290
+ },
291
+ antigravity: {
292
+ label: "Antigravity",
293
+ vendor: "Google",
294
+ providerIds: ["antigravity", "google"],
295
+ connectProvider: "antigravity",
296
+ vendorProvider: "google",
297
+ machineLoginServes: ["antigravity"],
298
+ permissionModes: ANTIGRAVITY_PERMISSION_MODES
279
299
  }
280
300
  };
281
301
  function harnessBindingIds(harness) {
@@ -451,6 +471,27 @@ var boatBilling = {
451
471
  large: { size: "large", vcpu: 8, memoryGb: 16, usdPerHour: 0.072 }
452
472
  }
453
473
  };
474
+ var AGENT37_USD_PER_MONTH = { vcpu: 0.8, memoryGb: 0.7, diskGb: 0.09 };
475
+ var AGENT37_MONTH_HOURS = 730;
476
+ var agent37MachineShapes = {
477
+ small: { cpu: 2, memory: 4, disk: 10 },
478
+ default: { cpu: 4, memory: 8, disk: 20 },
479
+ large: { cpu: 4, memory: 16, disk: 40 }
480
+ };
481
+ function agent37Rate(shape) {
482
+ const usdPerMonth = shape.cpu * AGENT37_USD_PER_MONTH.vcpu + shape.memory * AGENT37_USD_PER_MONTH.memoryGb + shape.disk * AGENT37_USD_PER_MONTH.diskGb;
483
+ return { size: `${shape.cpu} vCPU / ${shape.memory} GB`, vcpu: shape.cpu, memoryGb: shape.memory, usdPerHour: usdPerMonth / AGENT37_MONTH_HOURS };
484
+ }
485
+ var agent37Billing = {
486
+ source: { url: "https://www.agent37.com/docs/agents-api/billing", readOn: "2026-11-11" },
487
+ meter: "Agent37 meters an instance per minute at a monthly rate over 730 hours: $0.80 per vCPU, $0.70 per GB of memory and $0.09 per GB of disk while it runs, and the disk alone while it is stopped.",
488
+ rates: {
489
+ small: agent37Rate(agent37MachineShapes.small),
490
+ default: agent37Rate(agent37MachineShapes.default),
491
+ large: agent37Rate(agent37MachineShapes.large)
492
+ },
493
+ excludes: `the disk of a stopped instance, billed at $${AGENT37_USD_PER_MONTH.diskGb} per GB a month until the instance is deleted`
494
+ };
454
495
  var CLOUDFLARE_USD_PER_GIB_SECOND_MEMORY = 25e-7;
455
496
  var CLOUDFLARE_USD_PER_GB_SECOND_DISK = 7e-8;
456
497
  var CLOUDFLARE_USD_PER_VCPU_SECOND_ACTIVE = 2e-5;
@@ -485,6 +526,7 @@ var sandboxDriverCredentialFields = {
485
526
  { key: "worker_url", label: "Worker URL" }
486
527
  ],
487
528
  boat: [{ key: "api_key", label: "API Key", secret: true }],
529
+ agent37: [{ key: "api_key", label: "API Key", secret: true }],
488
530
  docker: [{ key: "image", label: "Image" }]
489
531
  };
490
532
  var sandboxDriverLabels = {
@@ -492,6 +534,7 @@ var sandboxDriverLabels = {
492
534
  vercel: "Vercel",
493
535
  cloudflare: "Cloudflare",
494
536
  boat: "Boat",
537
+ agent37: "Agent37",
495
538
  docker: "Docker"
496
539
  };
497
540
 
@@ -586,8 +629,8 @@ var sandboxDriverCatalog = {
586
629
  hostWatchesIdle: true,
587
630
  targetAccess: "relay",
588
631
  secretBrokering: "native",
589
- // Credential handlers do not restrict unrelated destinations.
590
- egressControl: "none",
632
+ // The sandbox Worker starts the container without internet and routes each allowed host through itself; a Worker that cannot confirm that refuses the start.
633
+ egressControl: "hosts",
591
634
  // A container snapshot holds the whole root filesystem; the platform keeps it 30 days past its last restore and offers no deletion.
592
635
  persistence: {
593
636
  resume: "replacement-restore",
@@ -625,6 +668,33 @@ var sandboxDriverCatalog = {
625
668
  machineClasses: ["small", "default", "large"]
626
669
  }
627
670
  },
671
+ agent37: {
672
+ id: "agent37",
673
+ label: sandboxDriverLabels.agent37,
674
+ credentialFields: sandboxDriverCredentialFields.agent37,
675
+ runtimeNetwork: { controlPlane: "direct", relay: "configured" },
676
+ runtimeEnv: "callback",
677
+ preparedImage: true,
678
+ billing: agent37Billing,
679
+ metadata: {
680
+ driverRunsIn: ["worker", "node"],
681
+ hostStopBehavior: "suspends-host",
682
+ hostResumeBehavior: "same-host",
683
+ targetAccess: "relay",
684
+ secretBrokering: "none",
685
+ // An instance's network policy lists domains, reached over HTTPS on 443 alone, and IPv4 ranges; private ranges stay blocked whatever it lists.
686
+ egressControl: "hosts-and-cidrs",
687
+ persistence: {
688
+ resume: "same-sandbox",
689
+ capture: "none",
690
+ clone: false,
691
+ captureSource: "not-applicable",
692
+ retention: "provider-managed",
693
+ restoreMount: "same-resource"
694
+ },
695
+ machineClasses: ["small", "default", "large"]
696
+ }
697
+ },
628
698
  docker: {
629
699
  id: "docker",
630
700
  label: sandboxDriverLabels.docker,
@@ -114,6 +114,27 @@ var boatBilling = {
114
114
  large: { size: "large", vcpu: 8, memoryGb: 16, usdPerHour: 0.072 }
115
115
  }
116
116
  };
117
+ var AGENT37_USD_PER_MONTH = { vcpu: 0.8, memoryGb: 0.7, diskGb: 0.09 };
118
+ var AGENT37_MONTH_HOURS = 730;
119
+ var agent37MachineShapes = {
120
+ small: { cpu: 2, memory: 4, disk: 10 },
121
+ default: { cpu: 4, memory: 8, disk: 20 },
122
+ large: { cpu: 4, memory: 16, disk: 40 }
123
+ };
124
+ function agent37Rate(shape) {
125
+ const usdPerMonth = shape.cpu * AGENT37_USD_PER_MONTH.vcpu + shape.memory * AGENT37_USD_PER_MONTH.memoryGb + shape.disk * AGENT37_USD_PER_MONTH.diskGb;
126
+ return { size: `${shape.cpu} vCPU / ${shape.memory} GB`, vcpu: shape.cpu, memoryGb: shape.memory, usdPerHour: usdPerMonth / AGENT37_MONTH_HOURS };
127
+ }
128
+ var agent37Billing = {
129
+ source: { url: "https://www.agent37.com/docs/agents-api/billing", readOn: "2026-11-11" },
130
+ meter: "Agent37 meters an instance per minute at a monthly rate over 730 hours: $0.80 per vCPU, $0.70 per GB of memory and $0.09 per GB of disk while it runs, and the disk alone while it is stopped.",
131
+ rates: {
132
+ small: agent37Rate(agent37MachineShapes.small),
133
+ default: agent37Rate(agent37MachineShapes.default),
134
+ large: agent37Rate(agent37MachineShapes.large)
135
+ },
136
+ excludes: `the disk of a stopped instance, billed at $${AGENT37_USD_PER_MONTH.diskGb} per GB a month until the instance is deleted`
137
+ };
117
138
  var CLOUDFLARE_USD_PER_GIB_SECOND_MEMORY = 25e-7;
118
139
  var CLOUDFLARE_USD_PER_GB_SECOND_DISK = 7e-8;
119
140
  var CLOUDFLARE_USD_PER_VCPU_SECOND_ACTIVE = 2e-5;
@@ -148,6 +169,7 @@ var sandboxDriverCredentialFields = {
148
169
  { key: "worker_url", label: "Worker URL" }
149
170
  ],
150
171
  boat: [{ key: "api_key", label: "API Key", secret: true }],
172
+ agent37: [{ key: "api_key", label: "API Key", secret: true }],
151
173
  docker: [{ key: "image", label: "Image" }]
152
174
  };
153
175
  var sandboxDriverLabels = {
@@ -155,6 +177,7 @@ var sandboxDriverLabels = {
155
177
  vercel: "Vercel",
156
178
  cloudflare: "Cloudflare",
157
179
  boat: "Boat",
180
+ agent37: "Agent37",
158
181
  docker: "Docker"
159
182
  };
160
183
 
@@ -225,8 +248,8 @@ var sandboxDriverCatalog = {
225
248
  hostWatchesIdle: true,
226
249
  targetAccess: "relay",
227
250
  secretBrokering: "native",
228
- // Credential handlers do not restrict unrelated destinations.
229
- egressControl: "none",
251
+ // The sandbox Worker starts the container without internet and routes each allowed host through itself; a Worker that cannot confirm that refuses the start.
252
+ egressControl: "hosts",
230
253
  // A container snapshot holds the whole root filesystem; the platform keeps it 30 days past its last restore and offers no deletion.
231
254
  persistence: {
232
255
  resume: "replacement-restore",
@@ -264,6 +287,33 @@ var sandboxDriverCatalog = {
264
287
  machineClasses: ["small", "default", "large"]
265
288
  }
266
289
  },
290
+ agent37: {
291
+ id: "agent37",
292
+ label: sandboxDriverLabels.agent37,
293
+ credentialFields: sandboxDriverCredentialFields.agent37,
294
+ runtimeNetwork: { controlPlane: "direct", relay: "configured" },
295
+ runtimeEnv: "callback",
296
+ preparedImage: true,
297
+ billing: agent37Billing,
298
+ metadata: {
299
+ driverRunsIn: ["worker", "node"],
300
+ hostStopBehavior: "suspends-host",
301
+ hostResumeBehavior: "same-host",
302
+ targetAccess: "relay",
303
+ secretBrokering: "none",
304
+ // An instance's network policy lists domains, reached over HTTPS on 443 alone, and IPv4 ranges; private ranges stay blocked whatever it lists.
305
+ egressControl: "hosts-and-cidrs",
306
+ persistence: {
307
+ resume: "same-sandbox",
308
+ capture: "none",
309
+ clone: false,
310
+ captureSource: "not-applicable",
311
+ retention: "provider-managed",
312
+ restoreMount: "same-resource"
313
+ },
314
+ machineClasses: ["small", "default", "large"]
315
+ }
316
+ },
267
317
  docker: {
268
318
  id: "docker",
269
319
  label: sandboxDriverLabels.docker,
@@ -1,4 +1,3 @@
1
- /** The status and lower-cased text a driver error carries, if it carries any. */
2
1
  export declare function driverErrorSignals(err: unknown): {
3
2
  status: number | undefined;
4
3
  text: string;
@@ -101,6 +101,27 @@ var boatBilling = {
101
101
  large: { size: "large", vcpu: 8, memoryGb: 16, usdPerHour: 0.072 }
102
102
  }
103
103
  };
104
+ var AGENT37_USD_PER_MONTH = { vcpu: 0.8, memoryGb: 0.7, diskGb: 0.09 };
105
+ var AGENT37_MONTH_HOURS = 730;
106
+ var agent37MachineShapes = {
107
+ small: { cpu: 2, memory: 4, disk: 10 },
108
+ default: { cpu: 4, memory: 8, disk: 20 },
109
+ large: { cpu: 4, memory: 16, disk: 40 }
110
+ };
111
+ function agent37Rate(shape) {
112
+ const usdPerMonth = shape.cpu * AGENT37_USD_PER_MONTH.vcpu + shape.memory * AGENT37_USD_PER_MONTH.memoryGb + shape.disk * AGENT37_USD_PER_MONTH.diskGb;
113
+ return { size: `${shape.cpu} vCPU / ${shape.memory} GB`, vcpu: shape.cpu, memoryGb: shape.memory, usdPerHour: usdPerMonth / AGENT37_MONTH_HOURS };
114
+ }
115
+ var agent37Billing = {
116
+ source: { url: "https://www.agent37.com/docs/agents-api/billing", readOn: "2026-11-11" },
117
+ meter: "Agent37 meters an instance per minute at a monthly rate over 730 hours: $0.80 per vCPU, $0.70 per GB of memory and $0.09 per GB of disk while it runs, and the disk alone while it is stopped.",
118
+ rates: {
119
+ small: agent37Rate(agent37MachineShapes.small),
120
+ default: agent37Rate(agent37MachineShapes.default),
121
+ large: agent37Rate(agent37MachineShapes.large)
122
+ },
123
+ excludes: `the disk of a stopped instance, billed at $${AGENT37_USD_PER_MONTH.diskGb} per GB a month until the instance is deleted`
124
+ };
104
125
  var CLOUDFLARE_USD_PER_GIB_SECOND_MEMORY = 25e-7;
105
126
  var CLOUDFLARE_USD_PER_GB_SECOND_DISK = 7e-8;
106
127
  var CLOUDFLARE_USD_PER_VCPU_SECOND_ACTIVE = 2e-5;
@@ -135,6 +156,7 @@ var sandboxDriverCredentialFields = {
135
156
  { key: "worker_url", label: "Worker URL" }
136
157
  ],
137
158
  boat: [{ key: "api_key", label: "API Key", secret: true }],
159
+ agent37: [{ key: "api_key", label: "API Key", secret: true }],
138
160
  docker: [{ key: "image", label: "Image" }]
139
161
  };
140
162
  var sandboxDriverLabels = {
@@ -142,6 +164,7 @@ var sandboxDriverLabels = {
142
164
  vercel: "Vercel",
143
165
  cloudflare: "Cloudflare",
144
166
  boat: "Boat",
167
+ agent37: "Agent37",
145
168
  docker: "Docker"
146
169
  };
147
170
 
@@ -212,8 +235,8 @@ var sandboxDriverCatalog = {
212
235
  hostWatchesIdle: true,
213
236
  targetAccess: "relay",
214
237
  secretBrokering: "native",
215
- // Credential handlers do not restrict unrelated destinations.
216
- egressControl: "none",
238
+ // The sandbox Worker starts the container without internet and routes each allowed host through itself; a Worker that cannot confirm that refuses the start.
239
+ egressControl: "hosts",
217
240
  // A container snapshot holds the whole root filesystem; the platform keeps it 30 days past its last restore and offers no deletion.
218
241
  persistence: {
219
242
  resume: "replacement-restore",
@@ -251,6 +274,33 @@ var sandboxDriverCatalog = {
251
274
  machineClasses: ["small", "default", "large"]
252
275
  }
253
276
  },
277
+ agent37: {
278
+ id: "agent37",
279
+ label: sandboxDriverLabels.agent37,
280
+ credentialFields: sandboxDriverCredentialFields.agent37,
281
+ runtimeNetwork: { controlPlane: "direct", relay: "configured" },
282
+ runtimeEnv: "callback",
283
+ preparedImage: true,
284
+ billing: agent37Billing,
285
+ metadata: {
286
+ driverRunsIn: ["worker", "node"],
287
+ hostStopBehavior: "suspends-host",
288
+ hostResumeBehavior: "same-host",
289
+ targetAccess: "relay",
290
+ secretBrokering: "none",
291
+ // An instance's network policy lists domains, reached over HTTPS on 443 alone, and IPv4 ranges; private ranges stay blocked whatever it lists.
292
+ egressControl: "hosts-and-cidrs",
293
+ persistence: {
294
+ resume: "same-sandbox",
295
+ capture: "none",
296
+ clone: false,
297
+ captureSource: "not-applicable",
298
+ retention: "provider-managed",
299
+ restoreMount: "same-resource"
300
+ },
301
+ machineClasses: ["small", "default", "large"]
302
+ }
303
+ },
254
304
  docker: {
255
305
  id: "docker",
256
306
  label: sandboxDriverLabels.docker,
@@ -492,17 +542,20 @@ function createVercelSandboxDriver(options) {
492
542
  "curl https://cursor.com/install -fsS | bash",
493
543
  "curl -fsSL https://ampcode.com/install.sh | bash",
494
544
  "curl -fsSL https://app.factory.ai/cli | sh",
545
+ "curl -fsSL https://antigravity.google/cli/install.sh | bash",
495
546
  "sudo ln -sf $HOME/.local/bin/agent /usr/local/bin/agent",
496
547
  "sudo ln -sf $HOME/.local/bin/cursor-agent /usr/local/bin/cursor-agent",
497
548
  "sudo ln -sf $HOME/.local/bin/amp /usr/local/bin/amp",
498
549
  "sudo ln -sf $HOME/.local/bin/droid /usr/local/bin/droid",
550
+ "sudo ln -sf $HOME/.local/bin/agy /usr/local/bin/agy",
499
551
  "command -v opencode",
500
552
  "command -v claude",
501
553
  "command -v codex",
502
554
  "command -v agent",
503
555
  "command -v cursor-agent",
504
556
  "command -v amp",
505
- "command -v droid"
557
+ "command -v droid",
558
+ "command -v agy"
506
559
  ].join(" && "));
507
560
  await runSetup(builder, [
508
561
  `sudo mkdir -p ${shell(RUNTIME_DIR)}`,
@@ -8,26 +8,32 @@ export declare function sandboxNetworkPolicyWithBrokeredHosts(policy: SandboxNet
8
8
  /** @see SandboxDriverMetadata.egressControl */
9
9
  export type SandboxEgressControl = "none" | "hosts" | "hosts-and-cidrs";
10
10
  /**
11
- * What the manager does with a caller's `net` for a given driver: enforce
12
- * where the driver can, and say so loudly rather than refuse where it cannot.
11
+ * What a start does with a restricted policy on a driver that cannot contain
12
+ * egress: `"refuse"` the start, or `"allow"` the sandbox to run with the policy
13
+ * withheld and the gap reported. Refusing is the default; allowing is the
14
+ * workspace owner's explicit, auditable decision.
15
+ */
16
+ export type SandboxUncontainedEgress = "refuse" | "allow";
17
+ /**
18
+ * What the manager does with a caller's `net` for a given driver.
13
19
  *
14
20
  * - `"enforce"` — the driver gets the policy verbatim and contains the
15
21
  * sandbox. Also the answer when the caller asked for no containment
16
22
  * (absent / `allow-all`), which is nothing to enforce.
17
- * - `"withhold"` — the driver declares `egressControl: "none"`, so there is no
18
- * containment to be had. The policy is NOT handed down: half the `"none"`
19
- * drivers throw on a restricted policy (docker, modal, boat) and the
20
- * other half silently drop it (cloudflare, the fetch bridge). Withholding at
21
- * the manager means the throwing drivers never see one — their throws stay
22
- * in place as their own last line of defence — and the silently-dropping
23
- * ones stop pretending. The sandbox comes up with UNRESTRICTED egress, which
24
- * is a real exposure, so the manager warns (see `onEgressUnenforced`).
25
- * - `"refuse"` — the driver HAS egress control but cannot express this
26
- * particular policy's encoding (a hosts-only driver handed an address-only
27
- * allowlist). Deliberately still fail-closed: this is a composition mistake
28
- * on an otherwise-enforcing driver, and degrading it to "withhold" would
29
- * weaken the enforcing path. `hostedSandboxNetworkPolicy` only ever emits
30
- * hosts, so no production path reaches it.
23
+ * - `"withhold"` — the driver declares `egressControl: "none"` and the
24
+ * start allows uncontained egress. The policy is NOT handed down: the
25
+ * `"none"` drivers throw on a restricted policy (docker, modal, boat), so
26
+ * withholding at the manager keeps their throws as their own last line of
27
+ * defence. The sandbox comes up with UNRESTRICTED egress, which is a real
28
+ * exposure, so the manager warns (see `onEgressUnenforced`).
29
+ * - `"refuse"` — either the driver declares `egressControl: "none"` and the
30
+ * start does not allow uncontained egress (`sandbox_egress_uncontained`,
31
+ * the default), or the driver HAS egress control but cannot express this
32
+ * particular policy's encoding (`sandbox_egress_policy_unenforceable`: a
33
+ * hosts-only driver handed an address-only allowlist). The second is a
34
+ * composition mistake on an otherwise-enforcing driver; degrading it to
35
+ * "withhold" would weaken the enforcing path, and `hostedSandboxNetworkPolicy`
36
+ * only ever emits hosts, so no production path reaches it.
31
37
  *
32
38
  * Pure, like `validateSandboxPersistenceCapabilities`, so the manager, the
33
39
  * composition layer, and tests can all ask the same question.
@@ -39,22 +45,18 @@ export type SandboxEgressDisposition = {
39
45
  reason: "sandbox_egress_uncontained";
40
46
  } | {
41
47
  action: "refuse";
42
- reason: "sandbox_egress_policy_unenforceable";
48
+ reason: "sandbox_egress_uncontained" | "sandbox_egress_policy_unenforceable";
43
49
  };
44
50
  /** @see SandboxEgressDisposition */
45
- export declare function sandboxEgressDisposition(control: SandboxEgressControl, net: SandboxNetworkPolicy | undefined): SandboxEgressDisposition;
51
+ export declare function sandboxEgressDisposition(control: SandboxEgressControl, net: SandboxNetworkPolicy | undefined, uncontained?: SandboxUncontainedEgress): SandboxEgressDisposition;
46
52
  /**
47
- * Emitted whenever a restricted egress policy is withheld because the composed
48
- * driver declares no egress control: an unrestricted sandbox that nobody was
49
- * told about is the exposure, so the degrade is never silent.
50
- *
51
- * Two phases, because a per-create line is easy to miss in request logs:
52
- * - `"composition"` — once per `createSandboxManager` per driver, at boot.
53
- * - `"ensure"` — every time a caller's policy is actually withheld, naming the
54
- * workspace and the allowlist that did not take effect.
53
+ * Emitted the first time per driver per isolate that a start which allows
54
+ * uncontained egress has its restricted policy withheld because the driver
55
+ * declares no egress control: an unrestricted sandbox that nobody was told
56
+ * about is the exposure, so the degrade is never silent. A start that refuses
57
+ * uncontained egress emits none: it never runs.
55
58
  */
56
59
  export type SandboxEgressUnenforcedEvent = {
57
- phase: "composition" | "ensure";
58
60
  reason: "sandbox_egress_uncontained";
59
61
  /** `SandboxDriver.id` of the composed driver. */
60
62
  driver: string;
@@ -62,12 +64,11 @@ export type SandboxEgressUnenforcedEvent = {
62
64
  egressControl: SandboxEgressControl;
63
65
  /** Ready-to-log sentence. Sinks that only forward text can use this alone. */
64
66
  message: string;
65
- /** Present on `"ensure"`. */
66
- workspaceId?: string;
67
- /** The start's placement labels. Present on `"ensure"`. */
67
+ workspaceId: string;
68
+ /** The start's placement labels. */
68
69
  labels?: Record<string, string>;
69
- /** The allowlist the caller asked for and did NOT get. Present on `"ensure"`. */
70
- requested?: SandboxNetworkPolicy;
70
+ /** The allowlist the caller asked for and did NOT get. */
71
+ requested: SandboxNetworkPolicy;
71
72
  };
72
73
  /**
73
74
  * A credential the SANDBOX must be able to USE for outbound requests but must
@@ -1,11 +1,8 @@
1
1
  import type { SandboxEgressControl, SandboxEgressUnenforcedEvent, SandboxNetworkPolicy } from "./egress-policy";
2
2
  /**
3
- * The two halves of the warning that a driver runs sandboxes with unrestricted
4
- * egress. The composition half is raised here, once per driver per isolate: a
5
- * per-create line lands in request logs and is easy to miss, this one lands
6
- * wherever the process starts, so an operator learns of it BEFORE the first
7
- * workspace exists. `withheld` is the start half, raised once per driver per
8
- * isolate from the first start whose policy the driver could not enforce.
3
+ * The warning that a start runs with unrestricted egress, raised once per
4
+ * driver per isolate from the first start whose policy the driver could not
5
+ * enforce. A refused start raises none: its refusal is that start's own answer.
9
6
  */
10
7
  export declare function createEgressWarnings(input: {
11
8
  driver: {
@@ -20,3 +17,4 @@ export declare function createEgressWarnings(input: {
20
17
  requested: SandboxNetworkPolicy;
21
18
  }): void;
22
19
  };
20
+ export type EgressWarnings = ReturnType<typeof createEgressWarnings>;