@vm0/cli 4.37.0 → 4.38.1

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.
Files changed (2) hide show
  1. package/index.js +1494 -222
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -6,8 +6,8 @@ var __export = (target, all) => {
6
6
  };
7
7
 
8
8
  // src/index.ts
9
- import { Command as Command24 } from "commander";
10
- import chalk27 from "chalk";
9
+ import { Command as Command27 } from "commander";
10
+ import chalk29 from "chalk";
11
11
 
12
12
  // src/lib/auth.ts
13
13
  import chalk from "chalk";
@@ -984,10 +984,10 @@ function mergeDefs(...defs) {
984
984
  function cloneDef(schema) {
985
985
  return mergeDefs(schema._zod.def);
986
986
  }
987
- function getElementAtPath(obj, path15) {
988
- if (!path15)
987
+ function getElementAtPath(obj, path16) {
988
+ if (!path16)
989
989
  return obj;
990
- return path15.reduce((acc, key) => acc?.[key], obj);
990
+ return path16.reduce((acc, key) => acc?.[key], obj);
991
991
  }
992
992
  function promiseAllObject(promisesObj) {
993
993
  const keys = Object.keys(promisesObj);
@@ -1346,11 +1346,11 @@ function aborted(x, startIndex = 0) {
1346
1346
  }
1347
1347
  return false;
1348
1348
  }
1349
- function prefixIssues(path15, issues) {
1349
+ function prefixIssues(path16, issues) {
1350
1350
  return issues.map((iss) => {
1351
1351
  var _a;
1352
1352
  (_a = iss).path ?? (_a.path = []);
1353
- iss.path.unshift(path15);
1353
+ iss.path.unshift(path16);
1354
1354
  return iss;
1355
1355
  });
1356
1356
  }
@@ -1518,7 +1518,7 @@ function treeifyError(error43, _mapper) {
1518
1518
  return issue2.message;
1519
1519
  };
1520
1520
  const result = { errors: [] };
1521
- const processError = (error44, path15 = []) => {
1521
+ const processError = (error44, path16 = []) => {
1522
1522
  var _a, _b;
1523
1523
  for (const issue2 of error44.issues) {
1524
1524
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -1528,7 +1528,7 @@ function treeifyError(error43, _mapper) {
1528
1528
  } else if (issue2.code === "invalid_element") {
1529
1529
  processError({ issues: issue2.issues }, issue2.path);
1530
1530
  } else {
1531
- const fullpath = [...path15, ...issue2.path];
1531
+ const fullpath = [...path16, ...issue2.path];
1532
1532
  if (fullpath.length === 0) {
1533
1533
  result.errors.push(mapper(issue2));
1534
1534
  continue;
@@ -1560,8 +1560,8 @@ function treeifyError(error43, _mapper) {
1560
1560
  }
1561
1561
  function toDotPath(_path) {
1562
1562
  const segs = [];
1563
- const path15 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1564
- for (const seg of path15) {
1563
+ const path16 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1564
+ for (const seg of path16) {
1565
1565
  if (typeof seg === "number")
1566
1566
  segs.push(`[${seg}]`);
1567
1567
  else if (typeof seg === "symbol")
@@ -2760,7 +2760,7 @@ var $ZodBase64 = /* @__PURE__ */ $constructor("$ZodBase64", (inst, def) => {
2760
2760
  function isValidBase64URL(data) {
2761
2761
  if (!base64url.test(data))
2762
2762
  return false;
2763
- const base643 = data.replace(/[-_]/g, (c11) => c11 === "-" ? "+" : "/");
2763
+ const base643 = data.replace(/[-_]/g, (c16) => c16 === "-" ? "+" : "/");
2764
2764
  const padded = base643.padEnd(Math.ceil(base643.length / 4) * 4, "=");
2765
2765
  return isValidBase64(padded);
2766
2766
  }
@@ -11672,9 +11672,9 @@ var ZodDate = /* @__PURE__ */ $constructor("ZodDate", (inst, def) => {
11672
11672
  ZodType.init(inst, def);
11673
11673
  inst.min = (value, params) => inst.check(_gte(value, params));
11674
11674
  inst.max = (value, params) => inst.check(_lte(value, params));
11675
- const c11 = inst._zod.bag;
11676
- inst.minDate = c11.minimum ? new Date(c11.minimum) : null;
11677
- inst.maxDate = c11.maximum ? new Date(c11.maximum) : null;
11675
+ const c16 = inst._zod.bag;
11676
+ inst.minDate = c16.minimum ? new Date(c16.minimum) : null;
11677
+ inst.maxDate = c16.maximum ? new Date(c16.maximum) : null;
11678
11678
  });
11679
11679
  function date3(params) {
11680
11680
  return _date(ZodDate, params);
@@ -12267,8 +12267,123 @@ var apiErrorSchema = external_exports.object({
12267
12267
  })
12268
12268
  });
12269
12269
 
12270
- // ../../packages/core/src/contracts/composes.ts
12270
+ // ../../packages/core/src/contracts/runners.ts
12271
12271
  var c = initContract();
12272
+ var firewallRuleSchema = external_exports.object({
12273
+ domain: external_exports.string().optional(),
12274
+ ip: external_exports.string().optional(),
12275
+ /** Terminal rule - value is the action (ALLOW or DENY) */
12276
+ final: external_exports.enum(["ALLOW", "DENY"]).optional(),
12277
+ /** Action for domain/ip rules */
12278
+ action: external_exports.enum(["ALLOW", "DENY"]).optional()
12279
+ });
12280
+ var experimentalFirewallSchema = external_exports.object({
12281
+ enabled: external_exports.boolean(),
12282
+ rules: external_exports.array(firewallRuleSchema).optional(),
12283
+ experimental_mitm: external_exports.boolean().optional(),
12284
+ experimental_seal_secrets: external_exports.boolean().optional()
12285
+ });
12286
+ var runnerGroupSchema = external_exports.string().regex(
12287
+ /^[a-z0-9-]+\/[a-z0-9-]+$/,
12288
+ "Runner group must be in scope/name format (e.g., acme/production)"
12289
+ );
12290
+ var jobSchema = external_exports.object({
12291
+ runId: external_exports.string().uuid(),
12292
+ prompt: external_exports.string(),
12293
+ agentComposeVersionId: external_exports.string(),
12294
+ vars: external_exports.record(external_exports.string(), external_exports.string()).nullable(),
12295
+ secretNames: external_exports.array(external_exports.string()).nullable(),
12296
+ checkpointId: external_exports.string().uuid().nullable()
12297
+ });
12298
+ var runnersPollContract = c.router({
12299
+ poll: {
12300
+ method: "POST",
12301
+ path: "/api/runners/poll",
12302
+ body: external_exports.object({
12303
+ group: runnerGroupSchema
12304
+ }),
12305
+ responses: {
12306
+ 200: external_exports.object({
12307
+ job: jobSchema.nullable()
12308
+ }),
12309
+ 400: apiErrorSchema,
12310
+ 401: apiErrorSchema,
12311
+ 500: apiErrorSchema
12312
+ },
12313
+ summary: "Poll for pending jobs (long-polling with 30s timeout)"
12314
+ }
12315
+ });
12316
+ var storageEntrySchema = external_exports.object({
12317
+ mountPath: external_exports.string(),
12318
+ archiveUrl: external_exports.string().nullable()
12319
+ });
12320
+ var artifactEntrySchema = external_exports.object({
12321
+ mountPath: external_exports.string(),
12322
+ archiveUrl: external_exports.string().nullable(),
12323
+ vasStorageName: external_exports.string(),
12324
+ vasVersionId: external_exports.string()
12325
+ });
12326
+ var storageManifestSchema = external_exports.object({
12327
+ storages: external_exports.array(storageEntrySchema),
12328
+ artifact: artifactEntrySchema.nullable()
12329
+ });
12330
+ var resumeSessionSchema = external_exports.object({
12331
+ sessionId: external_exports.string(),
12332
+ sessionHistory: external_exports.string()
12333
+ });
12334
+ var storedExecutionContextSchema = external_exports.object({
12335
+ workingDir: external_exports.string(),
12336
+ storageManifest: storageManifestSchema.nullable(),
12337
+ environment: external_exports.record(external_exports.string(), external_exports.string()).nullable(),
12338
+ resumeSession: resumeSessionSchema.nullable(),
12339
+ encryptedSecrets: external_exports.string().nullable(),
12340
+ // AES-256-GCM encrypted secrets
12341
+ cliAgentType: external_exports.string(),
12342
+ experimentalFirewall: experimentalFirewallSchema.optional()
12343
+ });
12344
+ var executionContextSchema = external_exports.object({
12345
+ runId: external_exports.string().uuid(),
12346
+ prompt: external_exports.string(),
12347
+ agentComposeVersionId: external_exports.string(),
12348
+ vars: external_exports.record(external_exports.string(), external_exports.string()).nullable(),
12349
+ secretNames: external_exports.array(external_exports.string()).nullable(),
12350
+ checkpointId: external_exports.string().uuid().nullable(),
12351
+ sandboxToken: external_exports.string(),
12352
+ // New fields for E2B parity:
12353
+ workingDir: external_exports.string(),
12354
+ storageManifest: storageManifestSchema.nullable(),
12355
+ environment: external_exports.record(external_exports.string(), external_exports.string()).nullable(),
12356
+ resumeSession: resumeSessionSchema.nullable(),
12357
+ secretValues: external_exports.array(external_exports.string()).nullable(),
12358
+ cliAgentType: external_exports.string(),
12359
+ // Experimental firewall configuration
12360
+ experimentalFirewall: experimentalFirewallSchema.optional()
12361
+ });
12362
+ var runnersJobClaimContract = c.router({
12363
+ claim: {
12364
+ method: "POST",
12365
+ path: "/api/runners/jobs/:id/claim",
12366
+ pathParams: external_exports.object({
12367
+ id: external_exports.string().uuid()
12368
+ }),
12369
+ body: external_exports.object({}),
12370
+ responses: {
12371
+ 200: executionContextSchema,
12372
+ 400: apiErrorSchema,
12373
+ 401: apiErrorSchema,
12374
+ 403: apiErrorSchema,
12375
+ // Job does not belong to user
12376
+ 404: apiErrorSchema,
12377
+ 409: apiErrorSchema,
12378
+ // Already claimed
12379
+ 500: apiErrorSchema
12380
+ },
12381
+ summary: "Claim a pending job for execution"
12382
+ }
12383
+ });
12384
+
12385
+ // ../../packages/core/src/contracts/composes.ts
12386
+ var c2 = initContract();
12272
12387
  var composeVersionQuerySchema = external_exports.preprocess(
12273
12388
  (val) => val === void 0 || val === null ? void 0 : String(val),
12274
12389
  external_exports.string().min(1, "Missing version query parameter").regex(
@@ -12341,7 +12456,13 @@ var agentDefinitionSchema = external_exports.object({
12341
12456
  /^[a-z0-9-]+\/[a-z0-9-]+$/,
12342
12457
  "Runner group must be in scope/name format (e.g., acme/production)"
12343
12458
  )
12344
- }).optional()
12459
+ }).optional(),
12460
+ /**
12461
+ * Experimental firewall configuration for network egress control.
12462
+ * Requires experimental_runner to be configured.
12463
+ * When enabled, filters outbound traffic by domain/IP rules.
12464
+ */
12465
+ experimental_firewall: experimentalFirewallSchema.optional()
12345
12466
  });
12346
12467
  var agentComposeContentSchema = external_exports.object({
12347
12468
  version: external_exports.string().min(1, "Version is required"),
@@ -12363,7 +12484,7 @@ var createComposeResponseSchema = external_exports.object({
12363
12484
  action: external_exports.enum(["created", "existing"]),
12364
12485
  updatedAt: external_exports.string()
12365
12486
  });
12366
- var composesMainContract = c.router({
12487
+ var composesMainContract = c2.router({
12367
12488
  /**
12368
12489
  * GET /api/agent/composes?name={name}&scope={scope}
12369
12490
  * Get agent compose by name with HEAD version content
@@ -12405,7 +12526,7 @@ var composesMainContract = c.router({
12405
12526
  summary: "Create or update agent compose version"
12406
12527
  }
12407
12528
  });
12408
- var composesByIdContract = c.router({
12529
+ var composesByIdContract = c2.router({
12409
12530
  /**
12410
12531
  * GET /api/agent/composes/:id
12411
12532
  * Get agent compose by ID with HEAD version content
@@ -12424,7 +12545,7 @@ var composesByIdContract = c.router({
12424
12545
  summary: "Get agent compose by ID"
12425
12546
  }
12426
12547
  });
12427
- var composesVersionsContract = c.router({
12548
+ var composesVersionsContract = c2.router({
12428
12549
  /**
12429
12550
  * GET /api/agent/composes/versions?composeId={id}&version={hash|tag}
12430
12551
  * Resolve a version specifier to a full version ID
@@ -12448,9 +12569,36 @@ var composesVersionsContract = c.router({
12448
12569
  summary: "Resolve version specifier to full version ID"
12449
12570
  }
12450
12571
  });
12572
+ var composeListItemSchema = external_exports.object({
12573
+ name: external_exports.string(),
12574
+ headVersionId: external_exports.string().nullable(),
12575
+ updatedAt: external_exports.string()
12576
+ });
12577
+ var composesListContract = c2.router({
12578
+ /**
12579
+ * GET /api/agent/composes/list?scope={scope}
12580
+ * List all agent composes for a scope
12581
+ * If scope is not provided, uses the authenticated user's default scope
12582
+ */
12583
+ list: {
12584
+ method: "GET",
12585
+ path: "/api/agent/composes/list",
12586
+ query: external_exports.object({
12587
+ scope: external_exports.string().optional()
12588
+ }),
12589
+ responses: {
12590
+ 200: external_exports.object({
12591
+ composes: external_exports.array(composeListItemSchema)
12592
+ }),
12593
+ 400: apiErrorSchema,
12594
+ 401: apiErrorSchema
12595
+ },
12596
+ summary: "List all agent composes for a scope"
12597
+ }
12598
+ });
12451
12599
 
12452
12600
  // ../../packages/core/src/contracts/runs.ts
12453
- var c2 = initContract();
12601
+ var c3 = initContract();
12454
12602
  var runStatusSchema = external_exports.enum([
12455
12603
  "pending",
12456
12604
  "running",
@@ -12525,7 +12673,7 @@ var eventsResponseSchema = external_exports.object({
12525
12673
  run: runStateSchema,
12526
12674
  provider: external_exports.string()
12527
12675
  });
12528
- var runsMainContract = c2.router({
12676
+ var runsMainContract = c3.router({
12529
12677
  /**
12530
12678
  * POST /api/agent/runs
12531
12679
  * Create and execute a new agent run
@@ -12543,7 +12691,7 @@ var runsMainContract = c2.router({
12543
12691
  summary: "Create and execute agent run"
12544
12692
  }
12545
12693
  });
12546
- var runsByIdContract = c2.router({
12694
+ var runsByIdContract = c3.router({
12547
12695
  /**
12548
12696
  * GET /api/agent/runs/:id
12549
12697
  * Get agent run status and results
@@ -12563,7 +12711,7 @@ var runsByIdContract = c2.router({
12563
12711
  summary: "Get agent run by ID"
12564
12712
  }
12565
12713
  });
12566
- var runEventsContract = c2.router({
12714
+ var runEventsContract = c3.router({
12567
12715
  /**
12568
12716
  * GET /api/agent/runs/:id/events
12569
12717
  * Poll for agent run events with pagination
@@ -12624,7 +12772,7 @@ var telemetryResponseSchema = external_exports.object({
12624
12772
  systemLog: external_exports.string(),
12625
12773
  metrics: external_exports.array(telemetryMetricSchema)
12626
12774
  });
12627
- var runTelemetryContract = c2.router({
12775
+ var runTelemetryContract = c3.router({
12628
12776
  /**
12629
12777
  * GET /api/agent/runs/:id/telemetry
12630
12778
  * Get aggregated telemetry data for a run (legacy combined format)
@@ -12643,7 +12791,7 @@ var runTelemetryContract = c2.router({
12643
12791
  summary: "Get run telemetry data"
12644
12792
  }
12645
12793
  });
12646
- var runSystemLogContract = c2.router({
12794
+ var runSystemLogContract = c3.router({
12647
12795
  /**
12648
12796
  * GET /api/agent/runs/:id/telemetry/system-log
12649
12797
  * Get system log with pagination
@@ -12667,7 +12815,7 @@ var runSystemLogContract = c2.router({
12667
12815
  summary: "Get system log with pagination"
12668
12816
  }
12669
12817
  });
12670
- var runMetricsContract = c2.router({
12818
+ var runMetricsContract = c3.router({
12671
12819
  /**
12672
12820
  * GET /api/agent/runs/:id/telemetry/metrics
12673
12821
  * Get metrics with pagination
@@ -12691,7 +12839,7 @@ var runMetricsContract = c2.router({
12691
12839
  summary: "Get metrics with pagination"
12692
12840
  }
12693
12841
  });
12694
- var runAgentEventsContract = c2.router({
12842
+ var runAgentEventsContract = c3.router({
12695
12843
  /**
12696
12844
  * GET /api/agent/runs/:id/telemetry/agent
12697
12845
  * Get agent events with pagination (for vm0 logs default)
@@ -12715,7 +12863,7 @@ var runAgentEventsContract = c2.router({
12715
12863
  summary: "Get agent events with pagination"
12716
12864
  }
12717
12865
  });
12718
- var runNetworkLogsContract = c2.router({
12866
+ var runNetworkLogsContract = c3.router({
12719
12867
  /**
12720
12868
  * GET /api/agent/runs/:id/telemetry/network
12721
12869
  * Get network logs with pagination (for vm0 logs --network)
@@ -12741,7 +12889,7 @@ var runNetworkLogsContract = c2.router({
12741
12889
  });
12742
12890
 
12743
12891
  // ../../packages/core/src/contracts/storages.ts
12744
- var c3 = initContract();
12892
+ var c4 = initContract();
12745
12893
  var storageTypeSchema = external_exports.enum(["volume", "artifact"]);
12746
12894
  var versionQuerySchema = external_exports.preprocess(
12747
12895
  (val) => val === void 0 || val === null ? void 0 : String(val),
@@ -12755,7 +12903,7 @@ var uploadStorageResponseSchema = external_exports.object({
12755
12903
  type: storageTypeSchema,
12756
12904
  deduplicated: external_exports.boolean()
12757
12905
  });
12758
- var storagesContract = c3.router({
12906
+ var storagesContract = c4.router({
12759
12907
  /**
12760
12908
  * POST /api/storages
12761
12909
  * Upload a storage (tar.gz file)
@@ -12771,7 +12919,7 @@ var storagesContract = c3.router({
12771
12919
  method: "POST",
12772
12920
  path: "/api/storages",
12773
12921
  contentType: "multipart/form-data",
12774
- body: c3.type(),
12922
+ body: c4.type(),
12775
12923
  responses: {
12776
12924
  200: uploadStorageResponseSchema,
12777
12925
  400: apiErrorSchema,
@@ -12799,9 +12947,9 @@ var storagesContract = c3.router({
12799
12947
  }),
12800
12948
  responses: {
12801
12949
  // Binary response - actual handling done at route level
12802
- 200: c3.otherResponse({
12950
+ 200: c4.otherResponse({
12803
12951
  contentType: "application/gzip",
12804
- body: c3.type()
12952
+ body: c4.type()
12805
12953
  }),
12806
12954
  400: apiErrorSchema,
12807
12955
  401: apiErrorSchema,
@@ -12825,7 +12973,7 @@ var presignedUploadSchema = external_exports.object({
12825
12973
  key: external_exports.string(),
12826
12974
  presignedUrl: external_exports.string().url()
12827
12975
  });
12828
- var storagesPrepareContract = c3.router({
12976
+ var storagesPrepareContract = c4.router({
12829
12977
  prepare: {
12830
12978
  method: "POST",
12831
12979
  path: "/api/storages/prepare",
@@ -12857,7 +13005,7 @@ var storagesPrepareContract = c3.router({
12857
13005
  summary: "Prepare for direct S3 upload"
12858
13006
  }
12859
13007
  });
12860
- var storagesCommitContract = c3.router({
13008
+ var storagesCommitContract = c4.router({
12861
13009
  commit: {
12862
13010
  method: "POST",
12863
13011
  path: "/api/storages/commit",
@@ -12888,7 +13036,7 @@ var storagesCommitContract = c3.router({
12888
13036
  summary: "Commit uploaded storage"
12889
13037
  }
12890
13038
  });
12891
- var storagesDownloadContract = c3.router({
13039
+ var storagesDownloadContract = c4.router({
12892
13040
  download: {
12893
13041
  method: "GET",
12894
13042
  path: "/api/storages/download",
@@ -12922,7 +13070,7 @@ var storagesDownloadContract = c3.router({
12922
13070
  summary: "Get presigned download URL"
12923
13071
  }
12924
13072
  });
12925
- var storagesListContract = c3.router({
13073
+ var storagesListContract = c4.router({
12926
13074
  list: {
12927
13075
  method: "GET",
12928
13076
  path: "/api/storages/list",
@@ -12946,7 +13094,7 @@ var storagesListContract = c3.router({
12946
13094
  });
12947
13095
 
12948
13096
  // ../../packages/core/src/contracts/webhooks.ts
12949
- var c4 = initContract();
13097
+ var c5 = initContract();
12950
13098
  var agentEventSchema = external_exports.object({
12951
13099
  type: external_exports.string(),
12952
13100
  sequenceNumber: external_exports.number().int().positive()
@@ -12958,7 +13106,7 @@ var artifactSnapshotSchema = external_exports.object({
12958
13106
  var volumeVersionsSnapshotSchema = external_exports.object({
12959
13107
  versions: external_exports.record(external_exports.string(), external_exports.string())
12960
13108
  });
12961
- var webhookEventsContract = c4.router({
13109
+ var webhookEventsContract = c5.router({
12962
13110
  /**
12963
13111
  * POST /api/webhooks/agent/events
12964
13112
  * Receive agent events from E2B sandbox
@@ -12984,7 +13132,7 @@ var webhookEventsContract = c4.router({
12984
13132
  summary: "Receive agent events from sandbox"
12985
13133
  }
12986
13134
  });
12987
- var webhookCompleteContract = c4.router({
13135
+ var webhookCompleteContract = c5.router({
12988
13136
  /**
12989
13137
  * POST /api/webhooks/agent/complete
12990
13138
  * Handle agent run completion (success or failure)
@@ -13010,7 +13158,7 @@ var webhookCompleteContract = c4.router({
13010
13158
  summary: "Handle agent run completion"
13011
13159
  }
13012
13160
  });
13013
- var webhookCheckpointsContract = c4.router({
13161
+ var webhookCheckpointsContract = c5.router({
13014
13162
  /**
13015
13163
  * POST /api/webhooks/agent/checkpoints
13016
13164
  * Create checkpoint for completed agent run
@@ -13042,7 +13190,7 @@ var webhookCheckpointsContract = c4.router({
13042
13190
  summary: "Create checkpoint for agent run"
13043
13191
  }
13044
13192
  });
13045
- var webhookHeartbeatContract = c4.router({
13193
+ var webhookHeartbeatContract = c5.router({
13046
13194
  /**
13047
13195
  * POST /api/webhooks/agent/heartbeat
13048
13196
  * Receive heartbeat signals from E2B sandbox
@@ -13065,7 +13213,7 @@ var webhookHeartbeatContract = c4.router({
13065
13213
  summary: "Receive heartbeat from sandbox"
13066
13214
  }
13067
13215
  });
13068
- var webhookStoragesContract = c4.router({
13216
+ var webhookStoragesContract = c5.router({
13069
13217
  /**
13070
13218
  * POST /api/webhooks/agent/storages
13071
13219
  * Create a new version of a storage from sandbox
@@ -13080,7 +13228,7 @@ var webhookStoragesContract = c4.router({
13080
13228
  method: "POST",
13081
13229
  path: "/api/webhooks/agent/storages",
13082
13230
  contentType: "multipart/form-data",
13083
- body: c4.type(),
13231
+ body: c5.type(),
13084
13232
  responses: {
13085
13233
  200: external_exports.object({
13086
13234
  versionId: external_exports.string(),
@@ -13096,7 +13244,7 @@ var webhookStoragesContract = c4.router({
13096
13244
  summary: "Upload storage version from sandbox"
13097
13245
  }
13098
13246
  });
13099
- var webhookStoragesIncrementalContract = c4.router({
13247
+ var webhookStoragesIncrementalContract = c5.router({
13100
13248
  /**
13101
13249
  * POST /api/webhooks/agent/storages/incremental
13102
13250
  * Create a new version using incremental upload
@@ -13113,7 +13261,7 @@ var webhookStoragesIncrementalContract = c4.router({
13113
13261
  method: "POST",
13114
13262
  path: "/api/webhooks/agent/storages/incremental",
13115
13263
  contentType: "multipart/form-data",
13116
- body: c4.type(),
13264
+ body: c5.type(),
13117
13265
  responses: {
13118
13266
  200: external_exports.object({
13119
13267
  versionId: external_exports.string(),
@@ -13153,7 +13301,7 @@ var networkLogSchema = external_exports.object({
13153
13301
  request_size: external_exports.number(),
13154
13302
  response_size: external_exports.number()
13155
13303
  });
13156
- var webhookTelemetryContract = c4.router({
13304
+ var webhookTelemetryContract = c5.router({
13157
13305
  /**
13158
13306
  * POST /api/webhooks/agent/telemetry
13159
13307
  * Receive telemetry data (system log, metrics, and network logs) from sandbox
@@ -13180,7 +13328,7 @@ var webhookTelemetryContract = c4.router({
13180
13328
  summary: "Receive telemetry data from sandbox"
13181
13329
  }
13182
13330
  });
13183
- var webhookStoragesPrepareContract = c4.router({
13331
+ var webhookStoragesPrepareContract = c5.router({
13184
13332
  prepare: {
13185
13333
  method: "POST",
13186
13334
  path: "/api/webhooks/agent/storages/prepare",
@@ -13211,7 +13359,7 @@ var webhookStoragesPrepareContract = c4.router({
13211
13359
  summary: "Prepare for direct S3 upload from sandbox"
13212
13360
  }
13213
13361
  });
13214
- var webhookStoragesCommitContract = c4.router({
13362
+ var webhookStoragesCommitContract = c5.router({
13215
13363
  commit: {
13216
13364
  method: "POST",
13217
13365
  path: "/api/webhooks/agent/storages/commit",
@@ -13245,12 +13393,12 @@ var webhookStoragesCommitContract = c4.router({
13245
13393
  });
13246
13394
 
13247
13395
  // ../../packages/core/src/contracts/cli-auth.ts
13248
- var c5 = initContract();
13396
+ var c6 = initContract();
13249
13397
  var oauthErrorSchema = external_exports.object({
13250
13398
  error: external_exports.string(),
13251
13399
  error_description: external_exports.string()
13252
13400
  });
13253
- var cliAuthDeviceContract = c5.router({
13401
+ var cliAuthDeviceContract = c6.router({
13254
13402
  /**
13255
13403
  * POST /api/cli/auth/device
13256
13404
  * Initiate device authorization flow
@@ -13272,7 +13420,7 @@ var cliAuthDeviceContract = c5.router({
13272
13420
  summary: "Initiate device authorization flow"
13273
13421
  }
13274
13422
  });
13275
- var cliAuthTokenContract = c5.router({
13423
+ var cliAuthTokenContract = c6.router({
13276
13424
  /**
13277
13425
  * POST /api/cli/auth/token
13278
13426
  * Exchange device code for access token
@@ -13302,8 +13450,8 @@ var cliAuthTokenContract = c5.router({
13302
13450
  });
13303
13451
 
13304
13452
  // ../../packages/core/src/contracts/auth.ts
13305
- var c6 = initContract();
13306
- var authContract = c6.router({
13453
+ var c7 = initContract();
13454
+ var authContract = c7.router({
13307
13455
  /**
13308
13456
  * GET /api/auth/me
13309
13457
  * Get current user information
@@ -13325,7 +13473,7 @@ var authContract = c6.router({
13325
13473
  });
13326
13474
 
13327
13475
  // ../../packages/core/src/contracts/cron.ts
13328
- var c7 = initContract();
13476
+ var c8 = initContract();
13329
13477
  var cleanupResultSchema = external_exports.object({
13330
13478
  runId: external_exports.string(),
13331
13479
  sandboxId: external_exports.string().nullable(),
@@ -13337,7 +13485,7 @@ var cleanupResponseSchema = external_exports.object({
13337
13485
  errors: external_exports.number(),
13338
13486
  results: external_exports.array(cleanupResultSchema)
13339
13487
  });
13340
- var cronCleanupSandboxesContract = c7.router({
13488
+ var cronCleanupSandboxesContract = c8.router({
13341
13489
  /**
13342
13490
  * GET /api/cron/cleanup-sandboxes
13343
13491
  * Cron job to cleanup sandboxes that have stopped sending heartbeats
@@ -13369,7 +13517,7 @@ var proxyErrorSchema = external_exports.object({
13369
13517
  });
13370
13518
 
13371
13519
  // ../../packages/core/src/contracts/scopes.ts
13372
- var c8 = initContract();
13520
+ var c9 = initContract();
13373
13521
  var scopeTypeSchema = external_exports.enum(["personal", "organization", "system"]);
13374
13522
  var scopeSlugSchema = external_exports.string().min(3, "Scope slug must be at least 3 characters").max(64, "Scope slug must be at most 64 characters").regex(
13375
13523
  /^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]{1,2}$/,
@@ -13394,7 +13542,7 @@ var updateScopeRequestSchema = external_exports.object({
13394
13542
  slug: scopeSlugSchema,
13395
13543
  force: external_exports.boolean().optional().default(false)
13396
13544
  });
13397
- var scopeContract = c8.router({
13545
+ var scopeContract = c9.router({
13398
13546
  /**
13399
13547
  * GET /api/scope
13400
13548
  * Get current user's scope
@@ -13449,7 +13597,7 @@ var scopeContract = c8.router({
13449
13597
  });
13450
13598
 
13451
13599
  // ../../packages/core/src/contracts/sessions.ts
13452
- var c9 = initContract();
13600
+ var c10 = initContract();
13453
13601
  var sessionResponseSchema = external_exports.object({
13454
13602
  id: external_exports.string(),
13455
13603
  agentComposeId: external_exports.string(),
@@ -13483,7 +13631,7 @@ var checkpointResponseSchema = external_exports.object({
13483
13631
  volumeVersionsSnapshot: volumeVersionsSnapshotSchema2.nullable(),
13484
13632
  createdAt: external_exports.string()
13485
13633
  });
13486
- var sessionsByIdContract = c9.router({
13634
+ var sessionsByIdContract = c10.router({
13487
13635
  /**
13488
13636
  * GET /api/agent/sessions/:id
13489
13637
  * Get session by ID
@@ -13503,7 +13651,7 @@ var sessionsByIdContract = c9.router({
13503
13651
  summary: "Get session by ID"
13504
13652
  }
13505
13653
  });
13506
- var checkpointsByIdContract = c9.router({
13654
+ var checkpointsByIdContract = c10.router({
13507
13655
  /**
13508
13656
  * GET /api/agent/checkpoints/:id
13509
13657
  * Get checkpoint by ID
@@ -13524,104 +13672,913 @@ var checkpointsByIdContract = c9.router({
13524
13672
  }
13525
13673
  });
13526
13674
 
13527
- // ../../packages/core/src/contracts/runners.ts
13528
- var c10 = initContract();
13529
- var runnerGroupSchema = external_exports.string().regex(
13530
- /^[a-z0-9-]+\/[a-z0-9-]+$/,
13531
- "Runner group must be in scope/name format (e.g., acme/production)"
13532
- );
13533
- var jobSchema = external_exports.object({
13534
- runId: external_exports.string().uuid(),
13535
- prompt: external_exports.string(),
13536
- agentComposeVersionId: external_exports.string(),
13537
- vars: external_exports.record(external_exports.string(), external_exports.string()).nullable(),
13538
- secretNames: external_exports.array(external_exports.string()).nullable(),
13539
- checkpointId: external_exports.string().uuid().nullable()
13675
+ // ../../packages/core/src/contracts/public/common.ts
13676
+ var publicApiErrorTypeSchema = external_exports.enum([
13677
+ "api_error",
13678
+ // Internal server error (5xx)
13679
+ "invalid_request_error",
13680
+ // Bad parameters (400)
13681
+ "authentication_error",
13682
+ // Auth failure (401)
13683
+ "not_found_error",
13684
+ // Resource missing (404)
13685
+ "conflict_error"
13686
+ // Resource conflict (409)
13687
+ ]);
13688
+ var publicApiErrorSchema = external_exports.object({
13689
+ error: external_exports.object({
13690
+ type: publicApiErrorTypeSchema,
13691
+ code: external_exports.string(),
13692
+ message: external_exports.string(),
13693
+ param: external_exports.string().optional(),
13694
+ doc_url: external_exports.string().url().optional()
13695
+ })
13540
13696
  });
13541
- var runnersPollContract = c10.router({
13542
- poll: {
13697
+ var paginationSchema = external_exports.object({
13698
+ has_more: external_exports.boolean(),
13699
+ next_cursor: external_exports.string().nullable()
13700
+ });
13701
+ function createPaginatedResponseSchema(dataSchema) {
13702
+ return external_exports.object({
13703
+ data: external_exports.array(dataSchema),
13704
+ pagination: paginationSchema
13705
+ });
13706
+ }
13707
+ var listQuerySchema = external_exports.object({
13708
+ cursor: external_exports.string().optional(),
13709
+ limit: external_exports.coerce.number().min(1).max(100).default(20)
13710
+ });
13711
+ var requestIdSchema = external_exports.string().uuid();
13712
+ var timestampSchema = external_exports.string().datetime();
13713
+
13714
+ // ../../packages/core/src/contracts/public/agents.ts
13715
+ var c11 = initContract();
13716
+ var publicAgentSchema = external_exports.object({
13717
+ id: external_exports.string(),
13718
+ name: external_exports.string(),
13719
+ current_version_id: external_exports.string().nullable(),
13720
+ created_at: timestampSchema,
13721
+ updated_at: timestampSchema
13722
+ });
13723
+ var agentVersionSchema = external_exports.object({
13724
+ id: external_exports.string(),
13725
+ agent_id: external_exports.string(),
13726
+ version_number: external_exports.number(),
13727
+ config: external_exports.unknown(),
13728
+ // Agent YAML configuration
13729
+ created_at: timestampSchema
13730
+ });
13731
+ var publicAgentDetailSchema = publicAgentSchema.extend({
13732
+ config: external_exports.unknown().optional()
13733
+ });
13734
+ var paginatedAgentsSchema = createPaginatedResponseSchema(publicAgentSchema);
13735
+ var paginatedAgentVersionsSchema = createPaginatedResponseSchema(agentVersionSchema);
13736
+ var createAgentRequestSchema = external_exports.object({
13737
+ name: external_exports.string().min(1).max(100).regex(
13738
+ /^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/,
13739
+ "Name must be lowercase alphanumeric with hyphens, not starting or ending with hyphen"
13740
+ ),
13741
+ config: external_exports.unknown()
13742
+ // Agent YAML configuration
13743
+ });
13744
+ var updateAgentRequestSchema = external_exports.object({
13745
+ config: external_exports.unknown()
13746
+ // New agent configuration (creates new version)
13747
+ });
13748
+ var agentListQuerySchema = listQuerySchema.extend({
13749
+ name: external_exports.string().optional()
13750
+ });
13751
+ var publicAgentsListContract = c11.router({
13752
+ list: {
13753
+ method: "GET",
13754
+ path: "/v1/agents",
13755
+ query: agentListQuerySchema,
13756
+ responses: {
13757
+ 200: paginatedAgentsSchema,
13758
+ 401: publicApiErrorSchema,
13759
+ 500: publicApiErrorSchema
13760
+ },
13761
+ summary: "List agents",
13762
+ description: "List all agents in the current scope with pagination. Use the `name` query parameter to filter by agent name."
13763
+ },
13764
+ create: {
13543
13765
  method: "POST",
13544
- path: "/api/runners/poll",
13545
- body: external_exports.object({
13546
- group: runnerGroupSchema
13766
+ path: "/v1/agents",
13767
+ body: createAgentRequestSchema,
13768
+ responses: {
13769
+ 201: publicAgentDetailSchema,
13770
+ 400: publicApiErrorSchema,
13771
+ 401: publicApiErrorSchema,
13772
+ 409: publicApiErrorSchema,
13773
+ 500: publicApiErrorSchema
13774
+ },
13775
+ summary: "Create agent",
13776
+ description: "Create a new agent with the given configuration"
13777
+ }
13778
+ });
13779
+ var publicAgentByIdContract = c11.router({
13780
+ get: {
13781
+ method: "GET",
13782
+ path: "/v1/agents/:id",
13783
+ pathParams: external_exports.object({
13784
+ id: external_exports.string().min(1, "Agent ID is required")
13547
13785
  }),
13548
13786
  responses: {
13549
- 200: external_exports.object({
13550
- job: jobSchema.nullable()
13551
- }),
13552
- 400: apiErrorSchema,
13553
- 401: apiErrorSchema,
13554
- 500: apiErrorSchema
13787
+ 200: publicAgentDetailSchema,
13788
+ 401: publicApiErrorSchema,
13789
+ 404: publicApiErrorSchema,
13790
+ 500: publicApiErrorSchema
13555
13791
  },
13556
- summary: "Poll for pending jobs (long-polling with 30s timeout)"
13792
+ summary: "Get agent",
13793
+ description: "Get agent details by ID"
13794
+ },
13795
+ update: {
13796
+ method: "PUT",
13797
+ path: "/v1/agents/:id",
13798
+ pathParams: external_exports.object({
13799
+ id: external_exports.string().min(1, "Agent ID is required")
13800
+ }),
13801
+ body: updateAgentRequestSchema,
13802
+ responses: {
13803
+ 200: publicAgentDetailSchema,
13804
+ 400: publicApiErrorSchema,
13805
+ 401: publicApiErrorSchema,
13806
+ 404: publicApiErrorSchema,
13807
+ 500: publicApiErrorSchema
13808
+ },
13809
+ summary: "Update agent",
13810
+ description: "Update agent configuration. Creates a new version if config changes."
13811
+ },
13812
+ delete: {
13813
+ method: "DELETE",
13814
+ path: "/v1/agents/:id",
13815
+ pathParams: external_exports.object({
13816
+ id: external_exports.string().min(1, "Agent ID is required")
13817
+ }),
13818
+ body: external_exports.undefined(),
13819
+ responses: {
13820
+ 204: external_exports.undefined(),
13821
+ 401: publicApiErrorSchema,
13822
+ 404: publicApiErrorSchema,
13823
+ 500: publicApiErrorSchema
13824
+ },
13825
+ summary: "Delete agent",
13826
+ description: "Archive an agent (soft delete)"
13557
13827
  }
13558
13828
  });
13559
- var storageEntrySchema = external_exports.object({
13560
- mountPath: external_exports.string(),
13561
- archiveUrl: external_exports.string().nullable()
13829
+ var publicAgentVersionsContract = c11.router({
13830
+ list: {
13831
+ method: "GET",
13832
+ path: "/v1/agents/:id/versions",
13833
+ pathParams: external_exports.object({
13834
+ id: external_exports.string().min(1, "Agent ID is required")
13835
+ }),
13836
+ query: listQuerySchema,
13837
+ responses: {
13838
+ 200: paginatedAgentVersionsSchema,
13839
+ 401: publicApiErrorSchema,
13840
+ 404: publicApiErrorSchema,
13841
+ 500: publicApiErrorSchema
13842
+ },
13843
+ summary: "List agent versions",
13844
+ description: "List all versions of an agent with pagination"
13845
+ }
13562
13846
  });
13563
- var artifactEntrySchema = external_exports.object({
13564
- mountPath: external_exports.string(),
13565
- archiveUrl: external_exports.string().nullable(),
13566
- vasStorageName: external_exports.string(),
13567
- vasVersionId: external_exports.string()
13847
+
13848
+ // ../../packages/core/src/contracts/public/runs.ts
13849
+ var c12 = initContract();
13850
+ var publicRunStatusSchema = external_exports.enum([
13851
+ "pending",
13852
+ "running",
13853
+ "completed",
13854
+ "failed",
13855
+ "timeout",
13856
+ "cancelled"
13857
+ ]);
13858
+ var publicRunSchema = external_exports.object({
13859
+ id: external_exports.string(),
13860
+ agent_id: external_exports.string(),
13861
+ agent_name: external_exports.string(),
13862
+ status: publicRunStatusSchema,
13863
+ prompt: external_exports.string(),
13864
+ created_at: timestampSchema,
13865
+ started_at: timestampSchema.nullable(),
13866
+ completed_at: timestampSchema.nullable()
13867
+ });
13868
+ var publicRunDetailSchema = publicRunSchema.extend({
13869
+ output: external_exports.string().nullable(),
13870
+ error: external_exports.string().nullable(),
13871
+ execution_time_ms: external_exports.number().nullable(),
13872
+ checkpoint_id: external_exports.string().nullable(),
13873
+ session_id: external_exports.string().nullable(),
13874
+ artifacts: external_exports.record(external_exports.string(), external_exports.string()).optional(),
13875
+ volumes: external_exports.record(external_exports.string(), external_exports.string()).optional()
13568
13876
  });
13569
- var storageManifestSchema = external_exports.object({
13570
- storages: external_exports.array(storageEntrySchema),
13571
- artifact: artifactEntrySchema.nullable()
13877
+ var paginatedRunsSchema = createPaginatedResponseSchema(publicRunSchema);
13878
+ var createRunRequestSchema = external_exports.object({
13879
+ // Agent identification (one of: agent, agent_id, session_id, checkpoint_id)
13880
+ agent: external_exports.string().optional(),
13881
+ // Agent name
13882
+ agent_id: external_exports.string().optional(),
13883
+ // Agent ID
13884
+ agent_version: external_exports.string().optional(),
13885
+ // Version specifier (e.g., "latest", "v1", specific ID)
13886
+ // Continue session
13887
+ session_id: external_exports.string().optional(),
13888
+ // Resume from checkpoint
13889
+ checkpoint_id: external_exports.string().optional(),
13890
+ // Required
13891
+ prompt: external_exports.string().min(1, "Prompt is required"),
13892
+ // Optional configuration
13893
+ variables: external_exports.record(external_exports.string(), external_exports.string()).optional(),
13894
+ secrets: external_exports.record(external_exports.string(), external_exports.string()).optional(),
13895
+ artifacts: external_exports.record(external_exports.string(), external_exports.string()).optional(),
13896
+ // artifact_name -> version
13897
+ volumes: external_exports.record(external_exports.string(), external_exports.string()).optional()
13898
+ // volume_name -> version
13572
13899
  });
13573
- var resumeSessionSchema = external_exports.object({
13574
- sessionId: external_exports.string(),
13575
- sessionHistory: external_exports.string()
13900
+ var runListQuerySchema = listQuerySchema.extend({
13901
+ agent_id: external_exports.string().optional(),
13902
+ status: publicRunStatusSchema.optional(),
13903
+ since: timestampSchema.optional()
13576
13904
  });
13577
- var storedExecutionContextSchema = external_exports.object({
13578
- workingDir: external_exports.string(),
13579
- storageManifest: storageManifestSchema.nullable(),
13580
- environment: external_exports.record(external_exports.string(), external_exports.string()).nullable(),
13581
- resumeSession: resumeSessionSchema.nullable(),
13582
- encryptedSecrets: external_exports.string().nullable(),
13583
- // AES-256-GCM encrypted secrets
13584
- cliAgentType: external_exports.string(),
13585
- experimentalNetworkSecurity: external_exports.boolean().optional()
13905
+ var publicRunsListContract = c12.router({
13906
+ list: {
13907
+ method: "GET",
13908
+ path: "/v1/runs",
13909
+ query: runListQuerySchema,
13910
+ responses: {
13911
+ 200: paginatedRunsSchema,
13912
+ 401: publicApiErrorSchema,
13913
+ 500: publicApiErrorSchema
13914
+ },
13915
+ summary: "List runs",
13916
+ description: "List runs with optional filtering by agent, status, and time"
13917
+ },
13918
+ create: {
13919
+ method: "POST",
13920
+ path: "/v1/runs",
13921
+ body: createRunRequestSchema,
13922
+ responses: {
13923
+ 202: publicRunDetailSchema,
13924
+ // Async operation
13925
+ 400: publicApiErrorSchema,
13926
+ 401: publicApiErrorSchema,
13927
+ 404: publicApiErrorSchema,
13928
+ 500: publicApiErrorSchema
13929
+ },
13930
+ summary: "Create run",
13931
+ description: "Create and execute a new agent run. Returns 202 Accepted as runs execute asynchronously."
13932
+ }
13586
13933
  });
13587
- var executionContextSchema = external_exports.object({
13588
- runId: external_exports.string().uuid(),
13589
- prompt: external_exports.string(),
13590
- agentComposeVersionId: external_exports.string(),
13591
- vars: external_exports.record(external_exports.string(), external_exports.string()).nullable(),
13592
- secretNames: external_exports.array(external_exports.string()).nullable(),
13593
- checkpointId: external_exports.string().uuid().nullable(),
13594
- sandboxToken: external_exports.string(),
13595
- // New fields for E2B parity:
13596
- workingDir: external_exports.string(),
13597
- storageManifest: storageManifestSchema.nullable(),
13598
- environment: external_exports.record(external_exports.string(), external_exports.string()).nullable(),
13599
- resumeSession: resumeSessionSchema.nullable(),
13600
- secretValues: external_exports.array(external_exports.string()).nullable(),
13601
- cliAgentType: external_exports.string(),
13602
- // Network security mode flag
13603
- experimentalNetworkSecurity: external_exports.boolean().optional()
13934
+ var publicRunByIdContract = c12.router({
13935
+ get: {
13936
+ method: "GET",
13937
+ path: "/v1/runs/:id",
13938
+ pathParams: external_exports.object({
13939
+ id: external_exports.string().min(1, "Run ID is required")
13940
+ }),
13941
+ responses: {
13942
+ 200: publicRunDetailSchema,
13943
+ 401: publicApiErrorSchema,
13944
+ 404: publicApiErrorSchema,
13945
+ 500: publicApiErrorSchema
13946
+ },
13947
+ summary: "Get run",
13948
+ description: "Get run details by ID"
13949
+ }
13604
13950
  });
13605
- var runnersJobClaimContract = c10.router({
13606
- claim: {
13951
+ var publicRunCancelContract = c12.router({
13952
+ cancel: {
13607
13953
  method: "POST",
13608
- path: "/api/runners/jobs/:id/claim",
13954
+ path: "/v1/runs/:id/cancel",
13609
13955
  pathParams: external_exports.object({
13610
- id: external_exports.string().uuid()
13956
+ id: external_exports.string().min(1, "Run ID is required")
13611
13957
  }),
13612
- body: external_exports.object({}),
13958
+ body: external_exports.undefined(),
13613
13959
  responses: {
13614
- 200: executionContextSchema,
13615
- 400: apiErrorSchema,
13616
- 401: apiErrorSchema,
13617
- 403: apiErrorSchema,
13618
- // Job does not belong to user
13619
- 404: apiErrorSchema,
13620
- 409: apiErrorSchema,
13621
- // Already claimed
13622
- 500: apiErrorSchema
13960
+ 200: publicRunDetailSchema,
13961
+ 400: publicApiErrorSchema,
13962
+ // Run not in cancellable state
13963
+ 401: publicApiErrorSchema,
13964
+ 404: publicApiErrorSchema,
13965
+ 500: publicApiErrorSchema
13623
13966
  },
13624
- summary: "Claim a pending job for execution"
13967
+ summary: "Cancel run",
13968
+ description: "Cancel a pending or running execution"
13969
+ }
13970
+ });
13971
+ var logEntrySchema = external_exports.object({
13972
+ timestamp: timestampSchema,
13973
+ type: external_exports.enum(["agent", "system", "network"]),
13974
+ level: external_exports.enum(["debug", "info", "warn", "error"]),
13975
+ message: external_exports.string(),
13976
+ metadata: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
13977
+ });
13978
+ var paginatedLogsSchema = createPaginatedResponseSchema(logEntrySchema);
13979
+ var logsQuerySchema = listQuerySchema.extend({
13980
+ type: external_exports.enum(["agent", "system", "network", "all"]).default("all"),
13981
+ since: timestampSchema.optional(),
13982
+ until: timestampSchema.optional(),
13983
+ order: external_exports.enum(["asc", "desc"]).default("asc")
13984
+ });
13985
+ var publicRunLogsContract = c12.router({
13986
+ getLogs: {
13987
+ method: "GET",
13988
+ path: "/v1/runs/:id/logs",
13989
+ pathParams: external_exports.object({
13990
+ id: external_exports.string().min(1, "Run ID is required")
13991
+ }),
13992
+ query: logsQuerySchema,
13993
+ responses: {
13994
+ 200: paginatedLogsSchema,
13995
+ 401: publicApiErrorSchema,
13996
+ 404: publicApiErrorSchema,
13997
+ 500: publicApiErrorSchema
13998
+ },
13999
+ summary: "Get run logs",
14000
+ description: "Get unified logs for a run. Combines agent, system, and network logs."
14001
+ }
14002
+ });
14003
+ var metricPointSchema = external_exports.object({
14004
+ timestamp: timestampSchema,
14005
+ cpu_percent: external_exports.number(),
14006
+ memory_used_mb: external_exports.number(),
14007
+ memory_total_mb: external_exports.number(),
14008
+ disk_used_mb: external_exports.number(),
14009
+ disk_total_mb: external_exports.number()
14010
+ });
14011
+ var metricsSummarySchema = external_exports.object({
14012
+ avg_cpu_percent: external_exports.number(),
14013
+ max_memory_used_mb: external_exports.number(),
14014
+ total_duration_ms: external_exports.number().nullable()
14015
+ });
14016
+ var metricsResponseSchema2 = external_exports.object({
14017
+ data: external_exports.array(metricPointSchema),
14018
+ summary: metricsSummarySchema
14019
+ });
14020
+ var publicRunMetricsContract = c12.router({
14021
+ getMetrics: {
14022
+ method: "GET",
14023
+ path: "/v1/runs/:id/metrics",
14024
+ pathParams: external_exports.object({
14025
+ id: external_exports.string().min(1, "Run ID is required")
14026
+ }),
14027
+ responses: {
14028
+ 200: metricsResponseSchema2,
14029
+ 401: publicApiErrorSchema,
14030
+ 404: publicApiErrorSchema,
14031
+ 500: publicApiErrorSchema
14032
+ },
14033
+ summary: "Get run metrics",
14034
+ description: "Get CPU, memory, and disk metrics for a run"
14035
+ }
14036
+ });
14037
+ var sseEventTypeSchema = external_exports.enum([
14038
+ "status",
14039
+ // Run status change
14040
+ "output",
14041
+ // Agent output
14042
+ "error",
14043
+ // Error occurred
14044
+ "complete",
14045
+ // Run completed
14046
+ "heartbeat"
14047
+ // Keep-alive
14048
+ ]);
14049
+ var sseEventSchema = external_exports.object({
14050
+ event: sseEventTypeSchema,
14051
+ data: external_exports.unknown(),
14052
+ id: external_exports.string().optional()
14053
+ // For Last-Event-ID reconnection
14054
+ });
14055
+ var publicRunEventsContract = c12.router({
14056
+ streamEvents: {
14057
+ method: "GET",
14058
+ path: "/v1/runs/:id/events",
14059
+ pathParams: external_exports.object({
14060
+ id: external_exports.string().min(1, "Run ID is required")
14061
+ }),
14062
+ query: external_exports.object({
14063
+ last_event_id: external_exports.string().optional()
14064
+ // For reconnection
14065
+ }),
14066
+ responses: {
14067
+ 200: external_exports.any(),
14068
+ // SSE stream - actual content is text/event-stream
14069
+ 401: publicApiErrorSchema,
14070
+ 404: publicApiErrorSchema,
14071
+ 500: publicApiErrorSchema
14072
+ },
14073
+ summary: "Stream run events",
14074
+ description: "Stream real-time events for a run using Server-Sent Events (SSE). Set Accept: text/event-stream header."
14075
+ }
14076
+ });
14077
+
14078
+ // ../../packages/core/src/contracts/public/artifacts.ts
14079
+ var c13 = initContract();
14080
+ var publicArtifactSchema = external_exports.object({
14081
+ id: external_exports.string(),
14082
+ name: external_exports.string(),
14083
+ current_version_id: external_exports.string().nullable(),
14084
+ size: external_exports.number(),
14085
+ // Total size in bytes
14086
+ file_count: external_exports.number(),
14087
+ created_at: timestampSchema,
14088
+ updated_at: timestampSchema
14089
+ });
14090
+ var artifactVersionSchema = external_exports.object({
14091
+ id: external_exports.string(),
14092
+ // SHA-256 content hash
14093
+ artifact_id: external_exports.string(),
14094
+ size: external_exports.number(),
14095
+ // Size in bytes
14096
+ file_count: external_exports.number(),
14097
+ message: external_exports.string().nullable(),
14098
+ // Optional commit message
14099
+ created_by: external_exports.string(),
14100
+ created_at: timestampSchema
14101
+ });
14102
+ var publicArtifactDetailSchema = publicArtifactSchema.extend({
14103
+ current_version: artifactVersionSchema.nullable()
14104
+ });
14105
+ var paginatedArtifactsSchema = createPaginatedResponseSchema(publicArtifactSchema);
14106
+ var paginatedArtifactVersionsSchema = createPaginatedResponseSchema(
14107
+ artifactVersionSchema
14108
+ );
14109
+ var createArtifactRequestSchema = external_exports.object({
14110
+ name: external_exports.string().min(1).max(100).regex(
14111
+ /^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/,
14112
+ "Name must be lowercase alphanumeric with hyphens, not starting or ending with hyphen"
14113
+ )
14114
+ });
14115
+ var fileEntrySchema = external_exports.object({
14116
+ path: external_exports.string(),
14117
+ size: external_exports.number(),
14118
+ hash: external_exports.string().optional()
14119
+ // SHA-256 hash of file content
14120
+ });
14121
+ var prepareUploadRequestSchema = external_exports.object({
14122
+ files: external_exports.array(fileEntrySchema),
14123
+ message: external_exports.string().optional()
14124
+ // Optional commit message
14125
+ });
14126
+ var presignedUploadSchema2 = external_exports.object({
14127
+ path: external_exports.string(),
14128
+ upload_url: external_exports.string(),
14129
+ // Presigned S3 URL
14130
+ upload_id: external_exports.string()
14131
+ // For multi-part uploads
14132
+ });
14133
+ var prepareUploadResponseSchema = external_exports.object({
14134
+ upload_session_id: external_exports.string(),
14135
+ files: external_exports.array(presignedUploadSchema2),
14136
+ expires_at: timestampSchema
14137
+ });
14138
+ var commitUploadRequestSchema = external_exports.object({
14139
+ upload_session_id: external_exports.string(),
14140
+ message: external_exports.string().optional()
14141
+ });
14142
+ var downloadResponseSchema = external_exports.object({
14143
+ version_id: external_exports.string(),
14144
+ files: external_exports.array(
14145
+ external_exports.object({
14146
+ path: external_exports.string(),
14147
+ size: external_exports.number(),
14148
+ download_url: external_exports.string()
14149
+ // Presigned S3 URL
14150
+ })
14151
+ ),
14152
+ expires_at: timestampSchema
14153
+ });
14154
+ var publicArtifactsListContract = c13.router({
14155
+ list: {
14156
+ method: "GET",
14157
+ path: "/v1/artifacts",
14158
+ query: listQuerySchema,
14159
+ responses: {
14160
+ 200: paginatedArtifactsSchema,
14161
+ 401: publicApiErrorSchema,
14162
+ 500: publicApiErrorSchema
14163
+ },
14164
+ summary: "List artifacts",
14165
+ description: "List all artifacts in the current scope with pagination"
14166
+ },
14167
+ create: {
14168
+ method: "POST",
14169
+ path: "/v1/artifacts",
14170
+ body: createArtifactRequestSchema,
14171
+ responses: {
14172
+ 201: publicArtifactDetailSchema,
14173
+ 400: publicApiErrorSchema,
14174
+ 401: publicApiErrorSchema,
14175
+ 409: publicApiErrorSchema,
14176
+ 500: publicApiErrorSchema
14177
+ },
14178
+ summary: "Create artifact",
14179
+ description: "Create a new empty artifact container"
14180
+ }
14181
+ });
14182
+ var publicArtifactByIdContract = c13.router({
14183
+ get: {
14184
+ method: "GET",
14185
+ path: "/v1/artifacts/:id",
14186
+ pathParams: external_exports.object({
14187
+ id: external_exports.string().min(1, "Artifact ID is required")
14188
+ }),
14189
+ responses: {
14190
+ 200: publicArtifactDetailSchema,
14191
+ 401: publicApiErrorSchema,
14192
+ 404: publicApiErrorSchema,
14193
+ 500: publicApiErrorSchema
14194
+ },
14195
+ summary: "Get artifact",
14196
+ description: "Get artifact details by ID"
14197
+ },
14198
+ delete: {
14199
+ method: "DELETE",
14200
+ path: "/v1/artifacts/:id",
14201
+ pathParams: external_exports.object({
14202
+ id: external_exports.string().min(1, "Artifact ID is required")
14203
+ }),
14204
+ body: external_exports.undefined(),
14205
+ responses: {
14206
+ 204: external_exports.undefined(),
14207
+ 401: publicApiErrorSchema,
14208
+ 404: publicApiErrorSchema,
14209
+ 500: publicApiErrorSchema
14210
+ },
14211
+ summary: "Delete artifact",
14212
+ description: "Delete an artifact and all its versions"
14213
+ }
14214
+ });
14215
+ var publicArtifactVersionsContract = c13.router({
14216
+ list: {
14217
+ method: "GET",
14218
+ path: "/v1/artifacts/:id/versions",
14219
+ pathParams: external_exports.object({
14220
+ id: external_exports.string().min(1, "Artifact ID is required")
14221
+ }),
14222
+ query: listQuerySchema,
14223
+ responses: {
14224
+ 200: paginatedArtifactVersionsSchema,
14225
+ 401: publicApiErrorSchema,
14226
+ 404: publicApiErrorSchema,
14227
+ 500: publicApiErrorSchema
14228
+ },
14229
+ summary: "List artifact versions",
14230
+ description: "List all versions of an artifact with pagination"
14231
+ }
14232
+ });
14233
+ var publicArtifactUploadContract = c13.router({
14234
+ prepareUpload: {
14235
+ method: "POST",
14236
+ path: "/v1/artifacts/:id/upload",
14237
+ pathParams: external_exports.object({
14238
+ id: external_exports.string().min(1, "Artifact ID is required")
14239
+ }),
14240
+ body: prepareUploadRequestSchema,
14241
+ responses: {
14242
+ 200: prepareUploadResponseSchema,
14243
+ 400: publicApiErrorSchema,
14244
+ 401: publicApiErrorSchema,
14245
+ 404: publicApiErrorSchema,
14246
+ 500: publicApiErrorSchema
14247
+ },
14248
+ summary: "Prepare artifact upload",
14249
+ description: "Get presigned URLs for direct S3 upload. Returns upload URLs for each file."
14250
+ }
14251
+ });
14252
+ var publicArtifactCommitContract = c13.router({
14253
+ commitUpload: {
14254
+ method: "POST",
14255
+ path: "/v1/artifacts/:id/commit",
14256
+ pathParams: external_exports.object({
14257
+ id: external_exports.string().min(1, "Artifact ID is required")
14258
+ }),
14259
+ body: commitUploadRequestSchema,
14260
+ responses: {
14261
+ 200: artifactVersionSchema,
14262
+ 400: publicApiErrorSchema,
14263
+ 401: publicApiErrorSchema,
14264
+ 404: publicApiErrorSchema,
14265
+ 500: publicApiErrorSchema
14266
+ },
14267
+ summary: "Commit artifact upload",
14268
+ description: "Finalize an upload session and create a new artifact version."
14269
+ }
14270
+ });
14271
+ var publicArtifactDownloadContract = c13.router({
14272
+ download: {
14273
+ method: "GET",
14274
+ path: "/v1/artifacts/:id/download",
14275
+ pathParams: external_exports.object({
14276
+ id: external_exports.string().min(1, "Artifact ID is required")
14277
+ }),
14278
+ query: external_exports.object({
14279
+ version_id: external_exports.string().optional()
14280
+ // Defaults to current version
14281
+ }),
14282
+ responses: {
14283
+ 200: downloadResponseSchema,
14284
+ 401: publicApiErrorSchema,
14285
+ 404: publicApiErrorSchema,
14286
+ 500: publicApiErrorSchema
14287
+ },
14288
+ summary: "Download artifact",
14289
+ description: "Get presigned URLs for downloading artifact files. Defaults to current version."
14290
+ }
14291
+ });
14292
+
14293
+ // ../../packages/core/src/contracts/public/volumes.ts
14294
+ var c14 = initContract();
14295
+ var publicVolumeSchema = external_exports.object({
14296
+ id: external_exports.string(),
14297
+ name: external_exports.string(),
14298
+ current_version_id: external_exports.string().nullable(),
14299
+ size: external_exports.number(),
14300
+ // Total size in bytes
14301
+ file_count: external_exports.number(),
14302
+ created_at: timestampSchema,
14303
+ updated_at: timestampSchema
14304
+ });
14305
+ var volumeVersionSchema = external_exports.object({
14306
+ id: external_exports.string(),
14307
+ // SHA-256 content hash
14308
+ volume_id: external_exports.string(),
14309
+ size: external_exports.number(),
14310
+ // Size in bytes
14311
+ file_count: external_exports.number(),
14312
+ message: external_exports.string().nullable(),
14313
+ // Optional commit message
14314
+ created_by: external_exports.string(),
14315
+ created_at: timestampSchema
14316
+ });
14317
+ var publicVolumeDetailSchema = publicVolumeSchema.extend({
14318
+ current_version: volumeVersionSchema.nullable()
14319
+ });
14320
+ var paginatedVolumesSchema = createPaginatedResponseSchema(publicVolumeSchema);
14321
+ var paginatedVolumeVersionsSchema = createPaginatedResponseSchema(volumeVersionSchema);
14322
+ var createVolumeRequestSchema = external_exports.object({
14323
+ name: external_exports.string().min(1).max(100).regex(
14324
+ /^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/,
14325
+ "Name must be lowercase alphanumeric with hyphens, not starting or ending with hyphen"
14326
+ )
14327
+ });
14328
+ var fileEntrySchema2 = external_exports.object({
14329
+ path: external_exports.string(),
14330
+ size: external_exports.number(),
14331
+ hash: external_exports.string().optional()
14332
+ // SHA-256 hash of file content
14333
+ });
14334
+ var prepareUploadRequestSchema2 = external_exports.object({
14335
+ files: external_exports.array(fileEntrySchema2),
14336
+ message: external_exports.string().optional()
14337
+ // Optional commit message
14338
+ });
14339
+ var presignedUploadSchema3 = external_exports.object({
14340
+ path: external_exports.string(),
14341
+ upload_url: external_exports.string(),
14342
+ // Presigned S3 URL
14343
+ upload_id: external_exports.string()
14344
+ // For multi-part uploads
14345
+ });
14346
+ var prepareUploadResponseSchema2 = external_exports.object({
14347
+ upload_session_id: external_exports.string(),
14348
+ files: external_exports.array(presignedUploadSchema3),
14349
+ expires_at: timestampSchema
14350
+ });
14351
+ var commitUploadRequestSchema2 = external_exports.object({
14352
+ upload_session_id: external_exports.string(),
14353
+ message: external_exports.string().optional()
14354
+ });
14355
+ var downloadResponseSchema2 = external_exports.object({
14356
+ version_id: external_exports.string(),
14357
+ files: external_exports.array(
14358
+ external_exports.object({
14359
+ path: external_exports.string(),
14360
+ size: external_exports.number(),
14361
+ download_url: external_exports.string()
14362
+ // Presigned S3 URL
14363
+ })
14364
+ ),
14365
+ expires_at: timestampSchema
14366
+ });
14367
+ var publicVolumesListContract = c14.router({
14368
+ list: {
14369
+ method: "GET",
14370
+ path: "/v1/volumes",
14371
+ query: listQuerySchema,
14372
+ responses: {
14373
+ 200: paginatedVolumesSchema,
14374
+ 401: publicApiErrorSchema,
14375
+ 500: publicApiErrorSchema
14376
+ },
14377
+ summary: "List volumes",
14378
+ description: "List all volumes in the current scope with pagination"
14379
+ },
14380
+ create: {
14381
+ method: "POST",
14382
+ path: "/v1/volumes",
14383
+ body: createVolumeRequestSchema,
14384
+ responses: {
14385
+ 201: publicVolumeDetailSchema,
14386
+ 400: publicApiErrorSchema,
14387
+ 401: publicApiErrorSchema,
14388
+ 409: publicApiErrorSchema,
14389
+ 500: publicApiErrorSchema
14390
+ },
14391
+ summary: "Create volume",
14392
+ description: "Create a new empty volume container"
14393
+ }
14394
+ });
14395
+ var publicVolumeByIdContract = c14.router({
14396
+ get: {
14397
+ method: "GET",
14398
+ path: "/v1/volumes/:id",
14399
+ pathParams: external_exports.object({
14400
+ id: external_exports.string().min(1, "Volume ID is required")
14401
+ }),
14402
+ responses: {
14403
+ 200: publicVolumeDetailSchema,
14404
+ 401: publicApiErrorSchema,
14405
+ 404: publicApiErrorSchema,
14406
+ 500: publicApiErrorSchema
14407
+ },
14408
+ summary: "Get volume",
14409
+ description: "Get volume details by ID"
14410
+ },
14411
+ delete: {
14412
+ method: "DELETE",
14413
+ path: "/v1/volumes/:id",
14414
+ pathParams: external_exports.object({
14415
+ id: external_exports.string().min(1, "Volume ID is required")
14416
+ }),
14417
+ body: external_exports.undefined(),
14418
+ responses: {
14419
+ 204: external_exports.undefined(),
14420
+ 401: publicApiErrorSchema,
14421
+ 404: publicApiErrorSchema,
14422
+ 500: publicApiErrorSchema
14423
+ },
14424
+ summary: "Delete volume",
14425
+ description: "Delete a volume and all its versions"
14426
+ }
14427
+ });
14428
+ var publicVolumeVersionsContract = c14.router({
14429
+ list: {
14430
+ method: "GET",
14431
+ path: "/v1/volumes/:id/versions",
14432
+ pathParams: external_exports.object({
14433
+ id: external_exports.string().min(1, "Volume ID is required")
14434
+ }),
14435
+ query: listQuerySchema,
14436
+ responses: {
14437
+ 200: paginatedVolumeVersionsSchema,
14438
+ 401: publicApiErrorSchema,
14439
+ 404: publicApiErrorSchema,
14440
+ 500: publicApiErrorSchema
14441
+ },
14442
+ summary: "List volume versions",
14443
+ description: "List all versions of a volume with pagination"
14444
+ }
14445
+ });
14446
+ var publicVolumeUploadContract = c14.router({
14447
+ prepareUpload: {
14448
+ method: "POST",
14449
+ path: "/v1/volumes/:id/upload",
14450
+ pathParams: external_exports.object({
14451
+ id: external_exports.string().min(1, "Volume ID is required")
14452
+ }),
14453
+ body: prepareUploadRequestSchema2,
14454
+ responses: {
14455
+ 200: prepareUploadResponseSchema2,
14456
+ 400: publicApiErrorSchema,
14457
+ 401: publicApiErrorSchema,
14458
+ 404: publicApiErrorSchema,
14459
+ 500: publicApiErrorSchema
14460
+ },
14461
+ summary: "Prepare volume upload",
14462
+ description: "Get presigned URLs for direct S3 upload. Returns upload URLs for each file."
14463
+ }
14464
+ });
14465
+ var publicVolumeCommitContract = c14.router({
14466
+ commitUpload: {
14467
+ method: "POST",
14468
+ path: "/v1/volumes/:id/commit",
14469
+ pathParams: external_exports.object({
14470
+ id: external_exports.string().min(1, "Volume ID is required")
14471
+ }),
14472
+ body: commitUploadRequestSchema2,
14473
+ responses: {
14474
+ 200: volumeVersionSchema,
14475
+ 400: publicApiErrorSchema,
14476
+ 401: publicApiErrorSchema,
14477
+ 404: publicApiErrorSchema,
14478
+ 500: publicApiErrorSchema
14479
+ },
14480
+ summary: "Commit volume upload",
14481
+ description: "Finalize an upload session and create a new volume version."
14482
+ }
14483
+ });
14484
+ var publicVolumeDownloadContract = c14.router({
14485
+ download: {
14486
+ method: "GET",
14487
+ path: "/v1/volumes/:id/download",
14488
+ pathParams: external_exports.object({
14489
+ id: external_exports.string().min(1, "Volume ID is required")
14490
+ }),
14491
+ query: external_exports.object({
14492
+ version_id: external_exports.string().optional()
14493
+ // Defaults to current version
14494
+ }),
14495
+ responses: {
14496
+ 200: downloadResponseSchema2,
14497
+ 401: publicApiErrorSchema,
14498
+ 404: publicApiErrorSchema,
14499
+ 500: publicApiErrorSchema
14500
+ },
14501
+ summary: "Download volume",
14502
+ description: "Get presigned URLs for downloading volume files. Defaults to current version."
14503
+ }
14504
+ });
14505
+
14506
+ // ../../packages/core/src/contracts/public/tokens.ts
14507
+ var c15 = initContract();
14508
+ var publicTokenSchema = external_exports.object({
14509
+ id: external_exports.string(),
14510
+ name: external_exports.string(),
14511
+ token_prefix: external_exports.string(),
14512
+ // First 12 chars for identification (e.g., "vm0_live_abc")
14513
+ last_used_at: timestampSchema.nullable(),
14514
+ expires_at: timestampSchema,
14515
+ created_at: timestampSchema
14516
+ });
14517
+ var publicTokenDetailSchema = publicTokenSchema.extend({
14518
+ token: external_exports.string().optional()
14519
+ // Full token value, only returned on creation
14520
+ });
14521
+ var paginatedTokensSchema = createPaginatedResponseSchema(publicTokenSchema);
14522
+ var createTokenRequestSchema = external_exports.object({
14523
+ name: external_exports.string().min(1, "Name is required").max(100, "Name too long"),
14524
+ expires_in_days: external_exports.number().min(1).max(365).optional()
14525
+ // null for no expiry (default 90 days)
14526
+ });
14527
+ var publicTokensListContract = c15.router({
14528
+ list: {
14529
+ method: "GET",
14530
+ path: "/v1/tokens",
14531
+ query: listQuerySchema,
14532
+ responses: {
14533
+ 200: paginatedTokensSchema,
14534
+ 401: publicApiErrorSchema
14535
+ },
14536
+ summary: "List API tokens",
14537
+ description: "List all API tokens for the authenticated user"
14538
+ },
14539
+ create: {
14540
+ method: "POST",
14541
+ path: "/v1/tokens",
14542
+ body: createTokenRequestSchema,
14543
+ responses: {
14544
+ 201: publicTokenDetailSchema,
14545
+ // Includes full token value
14546
+ 400: publicApiErrorSchema,
14547
+ 401: publicApiErrorSchema
14548
+ },
14549
+ summary: "Create API token",
14550
+ description: "Create a new API token. The token value is only returned once on creation."
14551
+ }
14552
+ });
14553
+ var publicTokenByIdContract = c15.router({
14554
+ get: {
14555
+ method: "GET",
14556
+ path: "/v1/tokens/:id",
14557
+ pathParams: external_exports.object({
14558
+ id: external_exports.string()
14559
+ }),
14560
+ responses: {
14561
+ 200: publicTokenSchema,
14562
+ // Does NOT include token value
14563
+ 401: publicApiErrorSchema,
14564
+ 404: publicApiErrorSchema
14565
+ },
14566
+ summary: "Get API token",
14567
+ description: "Get details of an API token (does not include the token value)"
14568
+ },
14569
+ delete: {
14570
+ method: "DELETE",
14571
+ path: "/v1/tokens/:id",
14572
+ pathParams: external_exports.object({
14573
+ id: external_exports.string()
14574
+ }),
14575
+ responses: {
14576
+ 204: external_exports.undefined(),
14577
+ 401: publicApiErrorSchema,
14578
+ 404: publicApiErrorSchema
14579
+ },
14580
+ summary: "Revoke API token",
14581
+ description: "Permanently revoke an API token. This action cannot be undone."
13625
14582
  }
13626
14583
  });
13627
14584
 
@@ -14067,7 +15024,7 @@ var ApiClient = class {
14067
15024
  /**
14068
15025
  * Generic GET request
14069
15026
  */
14070
- async get(path15) {
15027
+ async get(path16) {
14071
15028
  const baseUrl = await this.getBaseUrl();
14072
15029
  const token = await getToken();
14073
15030
  if (!token) {
@@ -14080,7 +15037,7 @@ var ApiClient = class {
14080
15037
  if (bypassSecret) {
14081
15038
  headers["x-vercel-protection-bypass"] = bypassSecret;
14082
15039
  }
14083
- return fetch(`${baseUrl}${path15}`, {
15040
+ return fetch(`${baseUrl}${path16}`, {
14084
15041
  method: "GET",
14085
15042
  headers
14086
15043
  });
@@ -14088,7 +15045,7 @@ var ApiClient = class {
14088
15045
  /**
14089
15046
  * Generic POST request
14090
15047
  */
14091
- async post(path15, options) {
15048
+ async post(path16, options) {
14092
15049
  const baseUrl = await this.getBaseUrl();
14093
15050
  const token = await getToken();
14094
15051
  if (!token) {
@@ -14104,7 +15061,7 @@ var ApiClient = class {
14104
15061
  if (bypassSecret) {
14105
15062
  headers["x-vercel-protection-bypass"] = bypassSecret;
14106
15063
  }
14107
- return fetch(`${baseUrl}${path15}`, {
15064
+ return fetch(`${baseUrl}${path16}`, {
14108
15065
  method: "POST",
14109
15066
  headers,
14110
15067
  body: options?.body
@@ -14113,7 +15070,7 @@ var ApiClient = class {
14113
15070
  /**
14114
15071
  * Generic DELETE request
14115
15072
  */
14116
- async delete(path15) {
15073
+ async delete(path16) {
14117
15074
  const baseUrl = await this.getBaseUrl();
14118
15075
  const token = await getToken();
14119
15076
  if (!token) {
@@ -14126,7 +15083,7 @@ var ApiClient = class {
14126
15083
  if (bypassSecret) {
14127
15084
  headers["x-vercel-protection-bypass"] = bypassSecret;
14128
15085
  }
14129
- return fetch(`${baseUrl}${path15}`, {
15086
+ return fetch(`${baseUrl}${path16}`, {
14130
15087
  method: "DELETE",
14131
15088
  headers
14132
15089
  });
@@ -15460,9 +16417,9 @@ var CodexEventParser = class {
15460
16417
  }
15461
16418
  }
15462
16419
  if (itemType === "file_change" && item.changes && item.changes.length > 0) {
15463
- const changes = item.changes.map((c11) => {
15464
- const action = c11.kind === "add" ? "Created" : c11.kind === "modify" ? "Modified" : "Deleted";
15465
- return `${action}: ${c11.path}`;
16420
+ const changes = item.changes.map((c16) => {
16421
+ const action = c16.kind === "add" ? "Created" : c16.kind === "modify" ? "Modified" : "Deleted";
16422
+ return `${action}: ${c16.path}`;
15466
16423
  }).join("\n");
15467
16424
  return {
15468
16425
  type: "text",
@@ -15803,9 +16760,9 @@ var CodexEventRenderer = class {
15803
16760
  return;
15804
16761
  }
15805
16762
  if (itemType === "file_change" && item.changes && item.changes.length > 0) {
15806
- const summary = item.changes.map((c11) => {
15807
- const icon = c11.kind === "add" ? "+" : c11.kind === "delete" ? "-" : "~";
15808
- return `${icon}${c11.path}`;
16763
+ const summary = item.changes.map((c16) => {
16764
+ const icon = c16.kind === "add" ? "+" : c16.kind === "delete" ? "-" : "~";
16765
+ return `${icon}${c16.path}`;
15809
16766
  }).join(", ");
15810
16767
  console.log(chalk4.green("[files]") + ` ${summary}`);
15811
16768
  return;
@@ -17694,7 +18651,7 @@ async function autoPullArtifact(runOutput, artifactDir) {
17694
18651
  }
17695
18652
  var cookCmd = new Command17().name("cook").description("One-click agent preparation and execution from vm0.yaml");
17696
18653
  cookCmd.argument("[prompt]", "Prompt for the agent").option("-y, --yes", "Skip confirmation prompts").action(async (prompt, options) => {
17697
- const shouldExit = await checkAndUpgrade("4.37.0", prompt);
18654
+ const shouldExit = await checkAndUpgrade("4.38.1", prompt);
17698
18655
  if (shouldExit) {
17699
18656
  process.exit(0);
17700
18657
  }
@@ -18344,10 +19301,324 @@ var setCommand = new Command20().name("set").description("Set your scope slug").
18344
19301
  // src/commands/scope/index.ts
18345
19302
  var scopeCommand = new Command21().name("scope").description("Manage your scope (namespace for images)").addCommand(statusCommand3).addCommand(setCommand);
18346
19303
 
18347
- // src/commands/init.ts
19304
+ // src/commands/agents/index.ts
19305
+ import { Command as Command24 } from "commander";
19306
+
19307
+ // src/commands/agents/list.ts
18348
19308
  import { Command as Command22 } from "commander";
18349
19309
  import chalk25 from "chalk";
18350
- import path13 from "path";
19310
+ var listCommand3 = new Command22().name("list").alias("ls").description("List all agent composes").option("-s, --scope <scope>", "Scope to list composes from").action(async (options) => {
19311
+ try {
19312
+ const url2 = options.scope ? `/api/agent/composes/list?scope=${encodeURIComponent(options.scope)}` : "/api/agent/composes/list";
19313
+ const response = await apiClient.get(url2);
19314
+ if (!response.ok) {
19315
+ const error43 = await response.json();
19316
+ throw new Error(error43.error?.message || "List failed");
19317
+ }
19318
+ const data = await response.json();
19319
+ if (data.composes.length === 0) {
19320
+ console.log(chalk25.dim("No agent composes found"));
19321
+ console.log(
19322
+ chalk25.dim(" Create one with: vm0 compose <agent-compose.yaml>")
19323
+ );
19324
+ return;
19325
+ }
19326
+ const nameWidth = Math.max(4, ...data.composes.map((c16) => c16.name.length));
19327
+ const header = ["NAME".padEnd(nameWidth), "VERSION", "UPDATED"].join(
19328
+ " "
19329
+ );
19330
+ console.log(chalk25.dim(header));
19331
+ for (const compose of data.composes) {
19332
+ const versionShort = compose.headVersionId ? compose.headVersionId.slice(0, 8) : chalk25.dim("-");
19333
+ const row = [
19334
+ compose.name.padEnd(nameWidth),
19335
+ versionShort,
19336
+ formatRelativeTime(compose.updatedAt)
19337
+ ].join(" ");
19338
+ console.log(row);
19339
+ }
19340
+ } catch (error43) {
19341
+ console.error(chalk25.red("\u2717 Failed to list agent composes"));
19342
+ if (error43 instanceof Error) {
19343
+ if (error43.message.includes("Not authenticated")) {
19344
+ console.error(chalk25.dim(" Run: vm0 auth login"));
19345
+ } else {
19346
+ console.error(chalk25.dim(` ${error43.message}`));
19347
+ }
19348
+ }
19349
+ process.exit(1);
19350
+ }
19351
+ });
19352
+
19353
+ // src/commands/agents/inspect.ts
19354
+ import { Command as Command23 } from "commander";
19355
+ import chalk26 from "chalk";
19356
+
19357
+ // src/lib/source-derivation.ts
19358
+ import * as fs9 from "fs/promises";
19359
+ import * as path13 from "path";
19360
+ import * as os7 from "os";
19361
+ function extractVariableReferences2(environment) {
19362
+ const secrets = [];
19363
+ const vars = [];
19364
+ for (const value of Object.values(environment)) {
19365
+ const matches = value.matchAll(/\$\{?([A-Z_][A-Z0-9_]*)\}?/g);
19366
+ for (const match of matches) {
19367
+ const varName = match[1];
19368
+ if (!varName) continue;
19369
+ if (varName.endsWith("_KEY") || varName.endsWith("_SECRET") || varName.endsWith("_TOKEN") || varName.endsWith("_PASSWORD") || varName.includes("API_KEY") || varName.includes("SECRET")) {
19370
+ if (!secrets.includes(varName)) {
19371
+ secrets.push(varName);
19372
+ }
19373
+ } else {
19374
+ if (!vars.includes(varName)) {
19375
+ vars.push(varName);
19376
+ }
19377
+ }
19378
+ }
19379
+ }
19380
+ return { secrets: secrets.sort(), vars: vars.sort() };
19381
+ }
19382
+ async function fetchSkillFrontmatter(skillUrl, tempDir) {
19383
+ try {
19384
+ const parsed = parseGitHubTreeUrl2(skillUrl);
19385
+ const skillDir = await downloadGitHubSkill(parsed, tempDir);
19386
+ const frontmatter = await readSkillFrontmatter(skillDir);
19387
+ return { skillName: parsed.skillName, frontmatter };
19388
+ } catch {
19389
+ return null;
19390
+ }
19391
+ }
19392
+ async function deriveAgentVariableSources(agent, options) {
19393
+ const { secrets: secretNames, vars: varNames } = agent.environment ? extractVariableReferences2(agent.environment) : { secrets: [], vars: [] };
19394
+ const secretSources = /* @__PURE__ */ new Map();
19395
+ const varSources = /* @__PURE__ */ new Map();
19396
+ for (const name of secretNames) {
19397
+ secretSources.set(name, { name, source: "agent environment" });
19398
+ }
19399
+ for (const name of varNames) {
19400
+ varSources.set(name, { name, source: "agent environment" });
19401
+ }
19402
+ if (options?.skipNetwork || !agent.skills || agent.skills.length === 0) {
19403
+ return {
19404
+ secrets: Array.from(secretSources.values()),
19405
+ vars: Array.from(varSources.values())
19406
+ };
19407
+ }
19408
+ const tempDir = await fs9.mkdtemp(
19409
+ path13.join(os7.tmpdir(), "vm0-source-derivation-")
19410
+ );
19411
+ try {
19412
+ const skillResults = await Promise.all(
19413
+ agent.skills.map((url2) => fetchSkillFrontmatter(url2, tempDir))
19414
+ );
19415
+ for (const result of skillResults) {
19416
+ if (!result) continue;
19417
+ const { skillName, frontmatter } = result;
19418
+ if (frontmatter.vm0_secrets) {
19419
+ for (const secretName of frontmatter.vm0_secrets) {
19420
+ if (secretSources.has(secretName)) {
19421
+ secretSources.set(secretName, {
19422
+ name: secretName,
19423
+ source: `skill: ${skillName}`,
19424
+ skillName
19425
+ });
19426
+ }
19427
+ }
19428
+ }
19429
+ if (frontmatter.vm0_vars) {
19430
+ for (const varName of frontmatter.vm0_vars) {
19431
+ if (varSources.has(varName)) {
19432
+ varSources.set(varName, {
19433
+ name: varName,
19434
+ source: `skill: ${skillName}`,
19435
+ skillName
19436
+ });
19437
+ }
19438
+ }
19439
+ }
19440
+ }
19441
+ } finally {
19442
+ await fs9.rm(tempDir, { recursive: true, force: true });
19443
+ }
19444
+ return {
19445
+ secrets: Array.from(secretSources.values()),
19446
+ vars: Array.from(varSources.values())
19447
+ };
19448
+ }
19449
+ async function deriveComposeVariableSources(content, options) {
19450
+ const results = /* @__PURE__ */ new Map();
19451
+ const entries = Object.entries(content.agents);
19452
+ const sourcesPromises = entries.map(async ([agentName, agent]) => {
19453
+ const sources = await deriveAgentVariableSources(agent, options);
19454
+ return { agentName, sources };
19455
+ });
19456
+ const sourcesResults = await Promise.all(sourcesPromises);
19457
+ for (const { agentName, sources } of sourcesResults) {
19458
+ results.set(agentName, sources);
19459
+ }
19460
+ return results;
19461
+ }
19462
+
19463
+ // src/commands/agents/inspect.ts
19464
+ function formatComposeOutput(name, versionId, content, variableSources) {
19465
+ console.log(chalk26.bold("Name:") + ` ${name}`);
19466
+ console.log(chalk26.bold("Version:") + ` ${versionId}`);
19467
+ console.log();
19468
+ console.log(chalk26.bold("Agents:"));
19469
+ for (const [agentName, agent] of Object.entries(content.agents)) {
19470
+ console.log(` ${chalk26.cyan(agentName)}:`);
19471
+ console.log(` Provider: ${agent.provider}`);
19472
+ if (agent.image) {
19473
+ console.log(` Image: ${agent.image}`);
19474
+ }
19475
+ if (agent.apps && agent.apps.length > 0) {
19476
+ console.log(` Apps:`);
19477
+ for (const app of agent.apps) {
19478
+ console.log(` - ${app}`);
19479
+ }
19480
+ }
19481
+ if (agent.working_dir) {
19482
+ console.log(` Working Dir: ${agent.working_dir}`);
19483
+ }
19484
+ if (agent.volumes && agent.volumes.length > 0) {
19485
+ console.log(` Volumes:`);
19486
+ for (const vol of agent.volumes) {
19487
+ const volumeDef = content.volumes?.[vol];
19488
+ if (volumeDef) {
19489
+ console.log(` - ${vol}:${volumeDef.version.slice(0, 8)}`);
19490
+ } else {
19491
+ console.log(` - ${vol}`);
19492
+ }
19493
+ }
19494
+ }
19495
+ if (agent.skills && agent.skills.length > 0) {
19496
+ console.log(` Skills:`);
19497
+ for (const skill of agent.skills) {
19498
+ console.log(` - ${skill}`);
19499
+ }
19500
+ }
19501
+ const agentSources = variableSources?.get(agentName);
19502
+ if (agentSources) {
19503
+ if (agentSources.secrets.length > 0) {
19504
+ console.log(` Secrets:`);
19505
+ for (const secret of agentSources.secrets) {
19506
+ const sourceInfo = chalk26.dim(`(${secret.source})`);
19507
+ console.log(` - ${secret.name.padEnd(20)} ${sourceInfo}`);
19508
+ }
19509
+ }
19510
+ if (agentSources.vars.length > 0) {
19511
+ console.log(` Vars:`);
19512
+ for (const v of agentSources.vars) {
19513
+ const sourceInfo = chalk26.dim(`(${v.source})`);
19514
+ console.log(` - ${v.name.padEnd(20)} ${sourceInfo}`);
19515
+ }
19516
+ }
19517
+ }
19518
+ if (agent.experimental_runner) {
19519
+ console.log(` Runner: ${agent.experimental_runner.group}`);
19520
+ }
19521
+ if (agent.experimental_network_security) {
19522
+ console.log(` Network Security: enabled`);
19523
+ }
19524
+ }
19525
+ }
19526
+ var inspectCommand = new Command23().name("inspect").description("Inspect an agent compose").argument(
19527
+ "<name[:version]>",
19528
+ "Agent name with optional version (e.g., my-agent:latest or my-agent:a1b2c3d4)"
19529
+ ).option("-s, --scope <scope>", "Scope to look up the compose from").option("--no-sources", "Skip fetching skills to determine variable sources").action(
19530
+ async (argument, options) => {
19531
+ try {
19532
+ const colonIndex = argument.lastIndexOf(":");
19533
+ let name;
19534
+ let version2;
19535
+ if (colonIndex === -1) {
19536
+ name = argument;
19537
+ version2 = "latest";
19538
+ } else {
19539
+ name = argument.slice(0, colonIndex);
19540
+ version2 = argument.slice(colonIndex + 1) || "latest";
19541
+ }
19542
+ let compose;
19543
+ try {
19544
+ compose = await apiClient.getComposeByName(name, options.scope);
19545
+ } catch (error43) {
19546
+ if (error43 instanceof Error && error43.message.includes("not found")) {
19547
+ console.error(chalk26.red(`\u2717 Agent compose not found: ${name}`));
19548
+ console.error(chalk26.dim(" Run: vm0 agents list"));
19549
+ process.exit(1);
19550
+ }
19551
+ throw error43;
19552
+ }
19553
+ let resolvedVersionId = compose.headVersionId;
19554
+ if (version2 !== "latest" && compose.headVersionId) {
19555
+ if (version2.length < 64) {
19556
+ try {
19557
+ const versionInfo = await apiClient.getComposeVersion(
19558
+ compose.id,
19559
+ version2
19560
+ );
19561
+ resolvedVersionId = versionInfo.versionId;
19562
+ } catch (error43) {
19563
+ if (error43 instanceof Error && error43.message.includes("not found")) {
19564
+ console.error(chalk26.red(`\u2717 Version not found: ${version2}`));
19565
+ console.error(
19566
+ chalk26.dim(
19567
+ ` HEAD version: ${compose.headVersionId?.slice(0, 8)}`
19568
+ )
19569
+ );
19570
+ process.exit(1);
19571
+ }
19572
+ throw error43;
19573
+ }
19574
+ } else {
19575
+ resolvedVersionId = version2;
19576
+ }
19577
+ }
19578
+ if (!resolvedVersionId || !compose.content) {
19579
+ console.error(chalk26.red(`\u2717 No version found for: ${name}`));
19580
+ process.exit(1);
19581
+ }
19582
+ const content = compose.content;
19583
+ let variableSources;
19584
+ if (options.sources !== false) {
19585
+ try {
19586
+ variableSources = await deriveComposeVariableSources(content);
19587
+ } catch {
19588
+ console.error(
19589
+ chalk26.yellow(
19590
+ "\u26A0 Warning: Failed to fetch skill sources, showing basic info"
19591
+ )
19592
+ );
19593
+ }
19594
+ }
19595
+ formatComposeOutput(
19596
+ compose.name,
19597
+ resolvedVersionId,
19598
+ content,
19599
+ variableSources
19600
+ );
19601
+ } catch (error43) {
19602
+ console.error(chalk26.red("\u2717 Failed to inspect agent compose"));
19603
+ if (error43 instanceof Error) {
19604
+ if (error43.message.includes("Not authenticated")) {
19605
+ console.error(chalk26.dim(" Run: vm0 auth login"));
19606
+ } else {
19607
+ console.error(chalk26.dim(` ${error43.message}`));
19608
+ }
19609
+ }
19610
+ process.exit(1);
19611
+ }
19612
+ }
19613
+ );
19614
+
19615
+ // src/commands/agents/index.ts
19616
+ var agentsCommand = new Command24().name("agents").description("Manage agent composes").addCommand(listCommand3).addCommand(inspectCommand);
19617
+
19618
+ // src/commands/init.ts
19619
+ import { Command as Command25 } from "commander";
19620
+ import chalk27 from "chalk";
19621
+ import path14 from "path";
18351
19622
  import { existsSync as existsSync9 } from "fs";
18352
19623
  import { writeFile as writeFile7 } from "fs/promises";
18353
19624
  var VM0_YAML_FILE = "vm0.yaml";
@@ -18387,14 +19658,14 @@ function checkExistingFiles() {
18387
19658
  if (existsSync9(AGENTS_MD_FILE)) existingFiles.push(AGENTS_MD_FILE);
18388
19659
  return existingFiles;
18389
19660
  }
18390
- var initCommand3 = new Command22().name("init").description("Initialize a new VM0 project in the current directory").option("-f, --force", "Overwrite existing files").option("-n, --name <name>", "Agent name (required in non-interactive mode)").action(async (options) => {
19661
+ var initCommand3 = new Command25().name("init").description("Initialize a new VM0 project in the current directory").option("-f, --force", "Overwrite existing files").option("-n, --name <name>", "Agent name (required in non-interactive mode)").action(async (options) => {
18391
19662
  const existingFiles = checkExistingFiles();
18392
19663
  if (existingFiles.length > 0 && !options.force) {
18393
19664
  for (const file2 of existingFiles) {
18394
- console.log(chalk25.red(`\u2717 ${file2} already exists`));
19665
+ console.log(chalk27.red(`\u2717 ${file2} already exists`));
18395
19666
  }
18396
19667
  console.log();
18397
- console.log(`To overwrite: ${chalk25.cyan("vm0 init --force")}`);
19668
+ console.log(`To overwrite: ${chalk27.cyan("vm0 init --force")}`);
18398
19669
  process.exit(1);
18399
19670
  }
18400
19671
  let agentName;
@@ -18402,12 +19673,12 @@ var initCommand3 = new Command22().name("init").description("Initialize a new VM
18402
19673
  agentName = options.name.trim();
18403
19674
  } else if (!isInteractive()) {
18404
19675
  console.error(
18405
- chalk25.red("\u2717 --name flag is required in non-interactive mode")
19676
+ chalk27.red("\u2717 --name flag is required in non-interactive mode")
18406
19677
  );
18407
- console.error(chalk25.dim(" Usage: vm0 init --name <agent-name>"));
19678
+ console.error(chalk27.dim(" Usage: vm0 init --name <agent-name>"));
18408
19679
  process.exit(1);
18409
19680
  } else {
18410
- const dirName = path13.basename(process.cwd());
19681
+ const dirName = path14.basename(process.cwd());
18411
19682
  const defaultName = validateAgentName(dirName) ? dirName : void 0;
18412
19683
  const name = await promptText(
18413
19684
  "Enter agent name",
@@ -18420,42 +19691,42 @@ var initCommand3 = new Command22().name("init").description("Initialize a new VM
18420
19691
  }
18421
19692
  );
18422
19693
  if (name === void 0) {
18423
- console.log(chalk25.dim("Cancelled"));
19694
+ console.log(chalk27.dim("Cancelled"));
18424
19695
  return;
18425
19696
  }
18426
19697
  agentName = name;
18427
19698
  }
18428
19699
  if (!agentName || !validateAgentName(agentName)) {
18429
- console.log(chalk25.red("\u2717 Invalid agent name"));
19700
+ console.log(chalk27.red("\u2717 Invalid agent name"));
18430
19701
  console.log(
18431
- chalk25.dim(" Must be 3-64 characters, alphanumeric and hyphens only")
19702
+ chalk27.dim(" Must be 3-64 characters, alphanumeric and hyphens only")
18432
19703
  );
18433
- console.log(chalk25.dim(" Must start and end with letter or number"));
19704
+ console.log(chalk27.dim(" Must start and end with letter or number"));
18434
19705
  process.exit(1);
18435
19706
  }
18436
19707
  await writeFile7(VM0_YAML_FILE, generateVm0Yaml(agentName));
18437
19708
  const vm0Status = existingFiles.includes(VM0_YAML_FILE) ? " (overwritten)" : "";
18438
- console.log(chalk25.green(`\u2713 Created ${VM0_YAML_FILE}${vm0Status}`));
19709
+ console.log(chalk27.green(`\u2713 Created ${VM0_YAML_FILE}${vm0Status}`));
18439
19710
  await writeFile7(AGENTS_MD_FILE, generateAgentsMd());
18440
19711
  const agentsStatus = existingFiles.includes(AGENTS_MD_FILE) ? " (overwritten)" : "";
18441
- console.log(chalk25.green(`\u2713 Created ${AGENTS_MD_FILE}${agentsStatus}`));
19712
+ console.log(chalk27.green(`\u2713 Created ${AGENTS_MD_FILE}${agentsStatus}`));
18442
19713
  console.log();
18443
19714
  console.log("Next steps:");
18444
19715
  console.log(
18445
- ` 1. Get your Claude Code token: ${chalk25.cyan("claude setup-token")}`
19716
+ ` 1. Get your Claude Code token: ${chalk27.cyan("claude setup-token")}`
18446
19717
  );
18447
19718
  console.log(` 2. Set the environment variable (or add to .env file):`);
18448
- console.log(chalk25.dim(` export CLAUDE_CODE_OAUTH_TOKEN=<your-token>`));
18449
- console.log(` 3. Run your agent: ${chalk25.cyan('vm0 cook "your prompt"')}`);
19719
+ console.log(chalk27.dim(` export CLAUDE_CODE_OAUTH_TOKEN=<your-token>`));
19720
+ console.log(` 3. Run your agent: ${chalk27.cyan('vm0 cook "your prompt"')}`);
18450
19721
  });
18451
19722
 
18452
19723
  // src/commands/setup-github.ts
18453
- import { Command as Command23 } from "commander";
18454
- import chalk26 from "chalk";
19724
+ import { Command as Command26 } from "commander";
19725
+ import chalk28 from "chalk";
18455
19726
  import { existsSync as existsSync10 } from "fs";
18456
19727
  import { mkdir as mkdir7, readFile as readFile8, writeFile as writeFile8 } from "fs/promises";
18457
19728
  import { execSync, spawnSync } from "child_process";
18458
- import path14 from "path";
19729
+ import path15 from "path";
18459
19730
  import { parse as parseYaml5 } from "yaml";
18460
19731
  function isGhInstalled() {
18461
19732
  try {
@@ -18487,74 +19758,74 @@ function getRelativeWorkingDir(gitRoot) {
18487
19758
  if (cwd === gitRoot) {
18488
19759
  return null;
18489
19760
  }
18490
- const relativePath = path14.relative(gitRoot, cwd);
19761
+ const relativePath = path15.relative(gitRoot, cwd);
18491
19762
  return relativePath.replace(/\\/g, "/");
18492
19763
  }
18493
19764
  async function checkPrerequisites() {
18494
19765
  console.log("Checking prerequisites...");
18495
19766
  const gitRoot = getGitRoot();
18496
19767
  if (!gitRoot) {
18497
- console.log(chalk26.red("\u2717 Not in a git repository"));
19768
+ console.log(chalk28.red("\u2717 Not in a git repository"));
18498
19769
  console.log();
18499
19770
  console.log("This command must be run from within a git repository.");
18500
19771
  console.log();
18501
19772
  console.log("To initialize a git repository, run:");
18502
- console.log(` ${chalk26.cyan("git init")}`);
19773
+ console.log(` ${chalk28.cyan("git init")}`);
18503
19774
  process.exit(1);
18504
19775
  }
18505
- console.log(chalk26.green("\u2713 Git repository detected"));
19776
+ console.log(chalk28.green("\u2713 Git repository detected"));
18506
19777
  if (!isGhInstalled()) {
18507
- console.log(chalk26.red("\u2717 GitHub CLI (gh) is not installed"));
19778
+ console.log(chalk28.red("\u2717 GitHub CLI (gh) is not installed"));
18508
19779
  console.log();
18509
19780
  console.log("GitHub CLI is required for this command.");
18510
19781
  console.log();
18511
- console.log(` macOS: ${chalk26.cyan("brew install gh")}`);
18512
- console.log(` Other: ${chalk26.cyan("https://cli.github.com/")}`);
19782
+ console.log(` macOS: ${chalk28.cyan("brew install gh")}`);
19783
+ console.log(` Other: ${chalk28.cyan("https://cli.github.com/")}`);
18513
19784
  console.log();
18514
19785
  console.log("After installation, run:");
18515
- console.log(` ${chalk26.cyan("gh auth login")}`);
19786
+ console.log(` ${chalk28.cyan("gh auth login")}`);
18516
19787
  console.log();
18517
19788
  console.log("Then try again:");
18518
- console.log(` ${chalk26.cyan("vm0 setup-github")}`);
19789
+ console.log(` ${chalk28.cyan("vm0 setup-github")}`);
18519
19790
  process.exit(1);
18520
19791
  }
18521
- console.log(chalk26.green("\u2713 GitHub CLI (gh) is installed"));
19792
+ console.log(chalk28.green("\u2713 GitHub CLI (gh) is installed"));
18522
19793
  if (!isGhAuthenticated()) {
18523
- console.log(chalk26.red("\u2717 GitHub CLI is not authenticated"));
19794
+ console.log(chalk28.red("\u2717 GitHub CLI is not authenticated"));
18524
19795
  console.log();
18525
19796
  console.log("Please authenticate GitHub CLI first:");
18526
- console.log(` ${chalk26.cyan("gh auth login")}`);
19797
+ console.log(` ${chalk28.cyan("gh auth login")}`);
18527
19798
  console.log();
18528
19799
  console.log("Then try again:");
18529
- console.log(` ${chalk26.cyan("vm0 setup-github")}`);
19800
+ console.log(` ${chalk28.cyan("vm0 setup-github")}`);
18530
19801
  process.exit(1);
18531
19802
  }
18532
- console.log(chalk26.green("\u2713 GitHub CLI is authenticated"));
19803
+ console.log(chalk28.green("\u2713 GitHub CLI is authenticated"));
18533
19804
  const token = await getToken();
18534
19805
  if (!token) {
18535
- console.log(chalk26.red("\u2717 VM0 not authenticated"));
19806
+ console.log(chalk28.red("\u2717 VM0 not authenticated"));
18536
19807
  console.log();
18537
19808
  console.log("Please authenticate with VM0 first:");
18538
- console.log(` ${chalk26.cyan("vm0 auth login")}`);
19809
+ console.log(` ${chalk28.cyan("vm0 auth login")}`);
18539
19810
  console.log();
18540
19811
  console.log("Then try again:");
18541
- console.log(` ${chalk26.cyan("vm0 setup-github")}`);
19812
+ console.log(` ${chalk28.cyan("vm0 setup-github")}`);
18542
19813
  process.exit(1);
18543
19814
  }
18544
- console.log(chalk26.green("\u2713 VM0 authenticated"));
19815
+ console.log(chalk28.green("\u2713 VM0 authenticated"));
18545
19816
  if (!existsSync10("vm0.yaml")) {
18546
- console.log(chalk26.red("\u2717 vm0.yaml not found"));
19817
+ console.log(chalk28.red("\u2717 vm0.yaml not found"));
18547
19818
  console.log();
18548
19819
  console.log("This command requires a vm0.yaml configuration file.");
18549
19820
  console.log();
18550
19821
  console.log("To create one, run:");
18551
- console.log(` ${chalk26.cyan("vm0 init")}`);
19822
+ console.log(` ${chalk28.cyan("vm0 init")}`);
18552
19823
  console.log();
18553
19824
  console.log("Then try again:");
18554
- console.log(` ${chalk26.cyan("vm0 setup-github")}`);
19825
+ console.log(` ${chalk28.cyan("vm0 setup-github")}`);
18555
19826
  process.exit(1);
18556
19827
  }
18557
- console.log(chalk26.green("\u2713 vm0.yaml found"));
19828
+ console.log(chalk28.green("\u2713 vm0.yaml found"));
18558
19829
  return { token, gitRoot };
18559
19830
  }
18560
19831
  function generatePublishYaml(workingDir) {
@@ -18711,7 +19982,7 @@ function displaySecretsTable(secretStatuses, varStatuses) {
18711
19982
  if (secretStatuses.length > 0) {
18712
19983
  console.log("\u2502 Secrets: \u2502");
18713
19984
  for (const s of secretStatuses) {
18714
- const status = s.found ? chalk26.green("\u2713") : chalk26.red("\u2717");
19985
+ const status = s.found ? chalk28.green("\u2713") : chalk28.red("\u2717");
18715
19986
  const source = s.found ? `(from ${s.source})` : "not found";
18716
19987
  const paddedName = (s.name + " ").padEnd(23, ".");
18717
19988
  console.log(`\u2502 ${status} ${paddedName} ${source.padEnd(19)}\u2502`);
@@ -18720,7 +19991,7 @@ function displaySecretsTable(secretStatuses, varStatuses) {
18720
19991
  if (varStatuses.length > 0) {
18721
19992
  console.log("\u2502 Variables: \u2502");
18722
19993
  for (const v of varStatuses) {
18723
- const status = v.found ? chalk26.green("\u2713") : chalk26.red("\u2717");
19994
+ const status = v.found ? chalk28.green("\u2713") : chalk28.red("\u2717");
18724
19995
  const source = v.found ? `(from ${v.source})` : "not found";
18725
19996
  const paddedName = (v.name + " ").padEnd(23, ".");
18726
19997
  console.log(`\u2502 ${status} ${paddedName} ${source.padEnd(19)}\u2502`);
@@ -18732,17 +20003,17 @@ function showManualSetupInstructions(secrets, vars) {
18732
20003
  console.log("Skipped automatic setup. Configure secrets manually:");
18733
20004
  console.log();
18734
20005
  console.log(" Step 1: Get your VM0 token");
18735
- console.log(` ${chalk26.cyan("vm0 auth setup-token")}`);
20006
+ console.log(` ${chalk28.cyan("vm0 auth setup-token")}`);
18736
20007
  console.log();
18737
20008
  console.log(" Step 2: Set GitHub secrets");
18738
20009
  for (const s of secrets) {
18739
- console.log(` ${chalk26.cyan(`gh secret set ${s}`)}`);
20010
+ console.log(` ${chalk28.cyan(`gh secret set ${s}`)}`);
18740
20011
  }
18741
20012
  if (vars.length > 0) {
18742
20013
  console.log();
18743
20014
  console.log(" Step 3: Set GitHub variables");
18744
20015
  for (const v of vars) {
18745
- console.log(` ${chalk26.cyan(`gh variable set ${v}`)}`);
20016
+ console.log(` ${chalk28.cyan(`gh variable set ${v}`)}`);
18746
20017
  }
18747
20018
  }
18748
20019
  }
@@ -18785,7 +20056,7 @@ function showWorkflowsCreatedMessage() {
18785
20056
  console.log("\u2502 3. Push to main branch to trigger publish \u2502");
18786
20057
  console.log("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
18787
20058
  }
18788
- var setupGithubCommand = new Command23().name("setup-github").description("Initialize GitHub Actions workflows for agent deployment").option("-f, --force", "Overwrite existing workflow files").option("-y, --yes", "Auto-confirm all prompts").option("--skip-secrets", "Skip automatic secrets/variables setup").action(
20059
+ var setupGithubCommand = new Command26().name("setup-github").description("Initialize GitHub Actions workflows for agent deployment").option("-f, --force", "Overwrite existing workflow files").option("-y, --yes", "Auto-confirm all prompts").option("--skip-secrets", "Skip automatic secrets/variables setup").action(
18789
20060
  async (options) => {
18790
20061
  const prereqs = await checkPrerequisites();
18791
20062
  if (!prereqs) {
@@ -18799,23 +20070,23 @@ var setupGithubCommand = new Command23().name("setup-github").description("Initi
18799
20070
  const config2 = parseYaml5(content);
18800
20071
  const agents = config2.agents;
18801
20072
  const agentName = Object.keys(agents)[0];
18802
- console.log(chalk26.green(`\u2713 Agent: ${agentName}`));
20073
+ console.log(chalk28.green(`\u2713 Agent: ${agentName}`));
18803
20074
  const { secrets, vars } = extractSecretsAndVars(config2);
18804
20075
  console.log(
18805
- chalk26.green(
20076
+ chalk28.green(
18806
20077
  `\u2713 Found ${secrets.length} secrets, ${vars.length} variables`
18807
20078
  )
18808
20079
  );
18809
20080
  console.log();
18810
- const publishPath = path14.join(gitRoot, ".github/workflows/publish.yml");
18811
- const runPath = path14.join(gitRoot, ".github/workflows/run.yml");
20081
+ const publishPath = path15.join(gitRoot, ".github/workflows/publish.yml");
20082
+ const runPath = path15.join(gitRoot, ".github/workflows/run.yml");
18812
20083
  const displayPublishPath = ".github/workflows/publish.yml";
18813
20084
  const displayRunPath = ".github/workflows/run.yml";
18814
20085
  const existingFiles = [];
18815
20086
  if (existsSync10(publishPath)) existingFiles.push(displayPublishPath);
18816
20087
  if (existsSync10(runPath)) existingFiles.push(displayRunPath);
18817
20088
  if (existingFiles.length > 0 && !options.force) {
18818
- console.log(chalk26.yellow("\u26A0 Existing workflow files detected:"));
20089
+ console.log(chalk28.yellow("\u26A0 Existing workflow files detected:"));
18819
20090
  for (const file2 of existingFiles) {
18820
20091
  console.log(` \u2022 ${file2}`);
18821
20092
  }
@@ -18828,23 +20099,23 @@ var setupGithubCommand = new Command23().name("setup-github").description("Initi
18828
20099
  if (!overwrite) {
18829
20100
  console.log();
18830
20101
  console.log("Aborted. To force overwrite, run:");
18831
- console.log(` ${chalk26.cyan("vm0 setup-github --force")}`);
20102
+ console.log(` ${chalk28.cyan("vm0 setup-github --force")}`);
18832
20103
  process.exit(0);
18833
20104
  }
18834
20105
  }
18835
20106
  console.log();
18836
20107
  }
18837
20108
  console.log("Creating workflow files...");
18838
- await mkdir7(path14.join(gitRoot, ".github/workflows"), { recursive: true });
20109
+ await mkdir7(path15.join(gitRoot, ".github/workflows"), { recursive: true });
18839
20110
  await writeFile8(publishPath, generatePublishYaml(workingDir));
18840
20111
  const publishStatus = existingFiles.includes(displayPublishPath) ? "Overwrote" : "Created";
18841
- console.log(chalk26.green(`\u2713 ${publishStatus} ${displayPublishPath}`));
20112
+ console.log(chalk28.green(`\u2713 ${publishStatus} ${displayPublishPath}`));
18842
20113
  await writeFile8(runPath, generateRunYaml(agentName, secrets, vars));
18843
20114
  const runStatus = existingFiles.includes(displayRunPath) ? "Overwrote" : "Created";
18844
- console.log(chalk26.green(`\u2713 ${runStatus} ${displayRunPath}`));
20115
+ console.log(chalk28.green(`\u2713 ${runStatus} ${displayRunPath}`));
18845
20116
  console.log();
18846
20117
  if (options.skipSecrets) {
18847
- console.log(chalk26.green("\u2713 Done (secrets setup skipped)"));
20118
+ console.log(chalk28.green("\u2713 Done (secrets setup skipped)"));
18848
20119
  return;
18849
20120
  }
18850
20121
  const { secretStatuses, varStatuses } = await detectSecretValues(
@@ -18884,14 +20155,14 @@ var setupGithubCommand = new Command23().name("setup-github").description("Initi
18884
20155
  if (s.found && s.value) {
18885
20156
  const success2 = setGitHubSecret(s.name, s.value);
18886
20157
  if (success2) {
18887
- console.log(` ${chalk26.green("\u2713")} ${s.name}`);
20158
+ console.log(` ${chalk28.green("\u2713")} ${s.name}`);
18888
20159
  } else {
18889
- console.log(` ${chalk26.red("\u2717")} ${s.name} (failed)`);
20160
+ console.log(` ${chalk28.red("\u2717")} ${s.name} (failed)`);
18890
20161
  failedSecrets.push(s.name);
18891
20162
  }
18892
20163
  } else {
18893
20164
  console.log(
18894
- ` ${chalk26.yellow("\u26A0")} ${s.name} (skipped - not found)`
20165
+ ` ${chalk28.yellow("\u26A0")} ${s.name} (skipped - not found)`
18895
20166
  );
18896
20167
  }
18897
20168
  }
@@ -18903,14 +20174,14 @@ var setupGithubCommand = new Command23().name("setup-github").description("Initi
18903
20174
  if (v.found && v.value) {
18904
20175
  const success2 = setGitHubVariable(v.name, v.value);
18905
20176
  if (success2) {
18906
- console.log(` ${chalk26.green("\u2713")} ${v.name}`);
20177
+ console.log(` ${chalk28.green("\u2713")} ${v.name}`);
18907
20178
  } else {
18908
- console.log(` ${chalk26.red("\u2717")} ${v.name} (failed)`);
20179
+ console.log(` ${chalk28.red("\u2717")} ${v.name} (failed)`);
18909
20180
  failedVars.push(v.name);
18910
20181
  }
18911
20182
  } else {
18912
20183
  console.log(
18913
- ` ${chalk26.yellow("\u26A0")} ${v.name} (skipped - not found)`
20184
+ ` ${chalk28.yellow("\u26A0")} ${v.name} (skipped - not found)`
18914
20185
  );
18915
20186
  }
18916
20187
  }
@@ -18933,10 +20204,10 @@ var setupGithubCommand = new Command23().name("setup-github").description("Initi
18933
20204
  );
18934
20205
 
18935
20206
  // src/index.ts
18936
- var program = new Command24();
18937
- program.name("vm0").description("VM0 CLI - A modern build tool").version("4.37.0");
20207
+ var program = new Command27();
20208
+ program.name("vm0").description("VM0 CLI - A modern build tool").version("4.38.1");
18938
20209
  program.command("info").description("Display environment information").action(async () => {
18939
- console.log(chalk27.bold("System Information:"));
20210
+ console.log(chalk29.bold("System Information:"));
18940
20211
  console.log(`Node Version: ${process.version}`);
18941
20212
  console.log(`Platform: ${process.platform}`);
18942
20213
  console.log(`Architecture: ${process.arch}`);
@@ -18963,6 +20234,7 @@ program.addCommand(artifactCommand);
18963
20234
  program.addCommand(cookCommand);
18964
20235
  program.addCommand(logsCommand);
18965
20236
  program.addCommand(scopeCommand);
20237
+ program.addCommand(agentsCommand);
18966
20238
  program.addCommand(initCommand3);
18967
20239
  program.addCommand(setupGithubCommand);
18968
20240
  if (process.argv[1]?.endsWith("index.js") || process.argv[1]?.endsWith("index.ts") || process.argv[1]?.endsWith("vm0")) {