@opengeni/contracts 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -18,7 +18,8 @@ var SandboxBackend = z.enum([
18
18
  "e2b",
19
19
  "blaxel",
20
20
  "cloudflare",
21
- "vercel"
21
+ "vercel",
22
+ "selfhosted"
22
23
  ]);
23
24
  var SandboxOs = z.enum(["linux", "macos", "windows"]);
24
25
  var SandboxCapabilityName = z.enum([
@@ -295,6 +296,58 @@ var CAPABILITY_DESCRIPTORS = {
295
296
  nativeBucketMount: false,
296
297
  persistable: false,
297
298
  supportsRunAs: false
299
+ },
300
+ // Bring-your-own-compute: the user's OWN machine, enrolled via a Rust agent,
301
+ // becomes ONE shared whole-machine sandbox (the agent IS the box). It is the
302
+ // first backend to make macOS/Windows reachable (default linux). Desktop is
303
+ // capability-PROCLAIMED ("vnc-ws") — the agent serves a native display stack
304
+ // (Linux X11/Xvfb, macOS CGEvent/ScreenCaptureKit) consent-gated at enroll;
305
+ // the online/offline/consent/display negotiation lives in select.ts (M3), this
306
+ // row is the static feasibility ceiling. Always-on (process-lifetime, never
307
+ // idle-reaped) and NOT persistable — OpenGeni cannot snapshot the user's disk,
308
+ // so resume = "is the agent's subject live?", never a cold re-create. Ports
309
+ // surface on-demand through the stateless relay edge, which lands behind the
310
+ // `resolveExposedPort` swap-seam later; until then it reuses the existing
311
+ // `provider-tunnel` exposure kind (the relay IS the provider tunnel for the
312
+ // agent) so no new PortExposureKind literal — and no new switch arms — are
313
+ // introduced. supportsOnDemandPorts:true: the agent opens a stream channel for
314
+ // a port on request rather than pre-declaring 6080/7681 at construction.
315
+ selfhosted: {
316
+ backend: "selfhosted",
317
+ backendId: "selfhosted",
318
+ tier: "desktop",
319
+ os: { supported: ["linux", "macos", "windows"], default: "linux" },
320
+ capabilities: {
321
+ FileSystem: { available: true, readOnly: false },
322
+ Terminal: { available: true, transport: "pty-ws", pty: true },
323
+ // real PTY over the relay
324
+ Git: { available: true },
325
+ DesktopStream: { available: true, transport: "vnc-ws" },
326
+ // proclaimed; consent-gated at enroll
327
+ Recording: { available: true }
328
+ // boot invariant: == DesktopStream.available
329
+ },
330
+ lifetime: {
331
+ // Whole-machine, always-there: online while the agent process runs, offline
332
+ // when it stops. The lease is NEVER idle-killed (it's the user's machine,
333
+ // not a reapable cloud box) and there is nothing to suspend/resume — the
334
+ // machine simply is or isn't reachable.
335
+ requiresSnapshotRollover: false,
336
+ hasIdleKiller: false,
337
+ supportsSuspendResume: false,
338
+ resumeIsLockFree: true
339
+ // resume = address the live NATS subject; no provider lock
340
+ },
341
+ // persistable:false forces snapshot.kind:"none" (the descriptor invariant
342
+ // `persistable ⇒ snapshot.kind!=="none"`): OpenGeni cannot snapshot the
343
+ // user's disk — the machine itself is the persistence.
344
+ snapshot: { kind: "none", hasTarFallback: false },
345
+ portExposure: { kind: "provider-tunnel", supportsOnDemandPorts: true },
346
+ workspaceRoot: "/",
347
+ // agent-reported machine root (the whole machine is the sandbox)
348
+ nativeBucketMount: false,
349
+ persistable: false,
350
+ supportsRunAs: false
298
351
  }
299
352
  };
300
353
  var ReasoningEffort = z.enum(["none", "minimal", "low", "medium", "high", "xhigh"]);
@@ -372,7 +425,14 @@ var Permission = z.enum([
372
425
  "api_keys:manage",
373
426
  "environments:manage",
374
427
  "environments:use",
375
- "goals:manage"
428
+ "goals:manage",
429
+ // Bring-your-own-compute (M5). enrollments:read lists a workspace's machines;
430
+ // enrollments:manage approves a device-flow enrollment (the LOUD whole-machine
431
+ // consent) + revokes a machine. Distinct from sessions/stream perms because an
432
+ // enrollment grants WHOLE-MACHINE access to a user's own hardware — a high-trust,
433
+ // admin-shaped action. workspace:admin is the super-wildcard over both.
434
+ "enrollments:read",
435
+ "enrollments:manage"
376
436
  ]);
377
437
  var ProductAccessMode = z.enum(["local", "configured", "managed"]);
378
438
  var BillingMode = z.enum(["disabled", "stripe"]);
@@ -465,6 +525,84 @@ async function verifyDelegatedAccessToken(secret, token, nowSeconds = Math.floor
465
525
  }
466
526
  return payload.data;
467
527
  }
528
+ var EnrollmentBearerPayload = z.object({
529
+ workspaceId: z.string().uuid(),
530
+ agentId: z.string().uuid(),
531
+ enrollmentId: z.string().uuid(),
532
+ // The Account-scoped control-plane subject prefix the agent subscribes to.
533
+ subjectPrefix: z.string().min(1),
534
+ exp: z.number().int().positive()
535
+ });
536
+ async function signEnrollmentBearer(secret, payload) {
537
+ const encodedPayload = base64UrlEncode(JSON.stringify(EnrollmentBearerPayload.parse(payload)));
538
+ const signature = await hmacSha256Base64Url(secret, encodedPayload);
539
+ return `oge_${encodedPayload}.${signature}`;
540
+ }
541
+ async function verifyEnrollmentBearer(secret, token, nowSeconds = Math.floor(Date.now() / 1e3)) {
542
+ if (!token.startsWith("oge_")) {
543
+ return null;
544
+ }
545
+ const withoutPrefix = token.slice("oge_".length);
546
+ const dot = withoutPrefix.lastIndexOf(".");
547
+ if (dot <= 0) {
548
+ return null;
549
+ }
550
+ const encodedPayload = withoutPrefix.slice(0, dot);
551
+ const signature = withoutPrefix.slice(dot + 1);
552
+ const expected = await hmacSha256Base64Url(secret, encodedPayload);
553
+ if (!constantTimeEqual(signature, expected)) {
554
+ return null;
555
+ }
556
+ const payload = EnrollmentBearerPayload.safeParse(JSON.parse(base64UrlDecode(encodedPayload)));
557
+ if (!payload.success || payload.data.exp < nowSeconds) {
558
+ return null;
559
+ }
560
+ return payload.data;
561
+ }
562
+ var EnrollTokenPayload = z.object({
563
+ // Domain-separation claim — fixed "enroll" so an `oge_`/`ogd_`/`ogs_` payload (no
564
+ // typ, or a different typ) can never satisfy verifyEnrollToken even past the prefix.
565
+ typ: z.literal("enroll"),
566
+ workspaceId: z.string().uuid(),
567
+ accountId: z.string().uuid(),
568
+ // The screen-control consent baked into the token at mint (the minting user's
569
+ // decision); the exchange records it as consentedScreenControl on the enrollment.
570
+ allowScreenControl: z.boolean(),
571
+ iat: z.number().int().nonnegative(),
572
+ exp: z.number().int().positive()
573
+ });
574
+ async function signEnrollToken(secret, payload) {
575
+ const encodedPayload = base64UrlEncode(JSON.stringify(EnrollTokenPayload.parse(payload)));
576
+ const signature = await hmacSha256Base64Url(secret, encodedPayload);
577
+ return `oget_${encodedPayload}.${signature}`;
578
+ }
579
+ async function verifyEnrollToken(secret, token, nowSeconds = Math.floor(Date.now() / 1e3)) {
580
+ if (!token.startsWith("oget_")) {
581
+ return null;
582
+ }
583
+ const withoutPrefix = token.slice("oget_".length);
584
+ const dot = withoutPrefix.lastIndexOf(".");
585
+ if (dot <= 0) {
586
+ return null;
587
+ }
588
+ const encodedPayload = withoutPrefix.slice(0, dot);
589
+ const signature = withoutPrefix.slice(dot + 1);
590
+ const expected = await hmacSha256Base64Url(secret, encodedPayload);
591
+ if (!constantTimeEqual(signature, expected)) {
592
+ return null;
593
+ }
594
+ let decoded;
595
+ try {
596
+ decoded = JSON.parse(base64UrlDecode(encodedPayload));
597
+ } catch {
598
+ return null;
599
+ }
600
+ const payload = EnrollTokenPayload.safeParse(decoded);
601
+ if (!payload.success || payload.data.exp < nowSeconds) {
602
+ return null;
603
+ }
604
+ return payload.data;
605
+ }
468
606
  var StreamTokenPayload = z.object({
469
607
  workspaceId: z.string().uuid(),
470
608
  sessionId: z.string().uuid(),
@@ -512,6 +650,47 @@ async function verifyStreamToken(secret, token, nowSeconds = Math.floor(Date.now
512
650
  }
513
651
  return payload.data;
514
652
  }
653
+ var RelayTokenPayload = z.object({
654
+ // The workspace the agent (and its channels) belong to — the relay asserts this
655
+ // equals the channel-key's ws so a producer can only register its own channels.
656
+ workspaceId: z.string().uuid(),
657
+ // The agent (machine) id — the relay asserts this equals the channel-key's agent.
658
+ agentId: z.string().uuid(),
659
+ // Expiry (unix seconds). Enrollment-scoped horizon (re-minted on re-enroll).
660
+ exp: z.number().int().positive()
661
+ });
662
+ async function signRelayToken(secret, payload) {
663
+ const encodedPayload = base64UrlEncode(JSON.stringify(RelayTokenPayload.parse(payload)));
664
+ const signature = await hmacSha256Base64Url(secret, encodedPayload);
665
+ return `ogr_${encodedPayload}.${signature}`;
666
+ }
667
+ async function verifyRelayToken(secret, token, nowSeconds = Math.floor(Date.now() / 1e3)) {
668
+ if (!token.startsWith("ogr_")) {
669
+ return null;
670
+ }
671
+ const withoutPrefix = token.slice("ogr_".length);
672
+ const dot = withoutPrefix.lastIndexOf(".");
673
+ if (dot <= 0) {
674
+ return null;
675
+ }
676
+ const encodedPayload = withoutPrefix.slice(0, dot);
677
+ const signature = withoutPrefix.slice(dot + 1);
678
+ const expected = await hmacSha256Base64Url(secret, encodedPayload);
679
+ if (!constantTimeEqual(signature, expected)) {
680
+ return null;
681
+ }
682
+ let decoded;
683
+ try {
684
+ decoded = JSON.parse(base64UrlDecode(encodedPayload));
685
+ } catch {
686
+ return null;
687
+ }
688
+ const payload = RelayTokenPayload.safeParse(decoded);
689
+ if (!payload.success || payload.data.exp < nowSeconds) {
690
+ return null;
691
+ }
692
+ return payload.data;
693
+ }
515
694
  var CreateWorkspaceRequest = z.object({
516
695
  accountId: z.string().uuid().optional(),
517
696
  name: z.string().min(1),
@@ -634,6 +813,10 @@ var LimitDecision = z.discriminatedUnion("allowed", [
634
813
  z.object({ allowed: z.literal(true) }),
635
814
  z.object({ allowed: z.literal(false), code: z.string(), message: z.string() })
636
815
  ]);
816
+ var EntitlementDecision = z.discriminatedUnion("allowed", [
817
+ z.object({ allowed: z.literal(true), quantity: z.number().optional() }),
818
+ z.object({ allowed: z.literal(false), reason: z.string(), code: z.string().optional(), quantity: z.number().optional() })
819
+ ]);
637
820
  var BillingBalance = z.object({
638
821
  accountId: z.string().uuid(),
639
822
  balanceMicros: z.number().int(),
@@ -752,7 +935,17 @@ var DocumentSearchRequest = z.object({
752
935
  });
753
936
  var ToolRef = z.object({
754
937
  kind: z.literal("mcp"),
755
- id: z.string().min(1)
938
+ id: z.string().min(1),
939
+ // Non-fatal-on-connect marker for an AUTO-ATTACHED (workspace-default)
940
+ // capability MCP server: when true, a connect / tools-list failure (e.g. an
941
+ // expired capability credential returning 401) must SKIP that server with a
942
+ // logged warning and let the turn proceed, rather than failing the whole
943
+ // turn before the model runs. Absent/false ⇒ STRICT: an unavailable server
944
+ // fails the turn (the contract for EXPLICITLY-requested tools). This flag is
945
+ // set server-side only, at the default-capability auto-attach seam; it is
946
+ // stripped from client-supplied tool refs so an explicit request always
947
+ // stays strict.
948
+ optional: z.boolean().optional()
756
949
  });
757
950
  var ResourceRefConflictError = class extends Error {
758
951
  constructor(message) {
@@ -761,17 +954,22 @@ var ResourceRefConflictError = class extends Error {
761
954
  }
762
955
  };
763
956
  function mergeToolRefs(existing, additions) {
764
- const seen = /* @__PURE__ */ new Set();
765
- const out = [];
957
+ const byKey = /* @__PURE__ */ new Map();
958
+ const order = [];
766
959
  for (const tool of [...existing, ...additions]) {
767
960
  const key = `${tool.kind}:${tool.id}`;
768
- if (seen.has(key)) {
961
+ const prior = byKey.get(key);
962
+ if (!prior) {
963
+ byKey.set(key, tool);
964
+ order.push(key);
769
965
  continue;
770
966
  }
771
- seen.add(key);
772
- out.push(tool);
967
+ if (prior.optional === true && tool.optional !== true) {
968
+ const { optional: _dropped, ...strict } = prior;
969
+ byKey.set(key, strict);
970
+ }
773
971
  }
774
- return out;
972
+ return order.map((key) => byKey.get(key));
775
973
  }
776
974
  function mergeResourceRefs(existing, additions, options = {}) {
777
975
  const out = [...existing];
@@ -1346,6 +1544,13 @@ var Session = z.object({
1346
1544
  // own id for a singleton group (today's 1:1 default); equals the parent's
1347
1545
  // group when spawned shared (both sessions run in ONE box).
1348
1546
  sandboxGroupId: z.string().uuid(),
1547
+ // The first-class swappable-sandbox POINTER (bring-your-own-compute M2). NULL
1548
+ // resolves to the session's own group sandbox (the backward-compat default);
1549
+ // a swap sets it to the target sandbox row. active_epoch is the second epoch
1550
+ // ABOVE the lease epoch, bumped on every swap so the routing proxy can fence a
1551
+ // stale in-flight op and retry against the new active sandbox.
1552
+ activeSandboxId: z.string().uuid().nullable(),
1553
+ activeEpoch: z.number().int().nonnegative(),
1349
1554
  environmentId: z.string().uuid().nullable(),
1350
1555
  // Non-default first-party MCP token permissions (manager-style sessions);
1351
1556
  // null means the fixed worker default set.
@@ -1366,6 +1571,12 @@ var Session = z.object({
1366
1571
  // signal. Null until a turn with usage has completed.
1367
1572
  lastInputTokens: z.number().int().nonnegative().nullable(),
1368
1573
  lastSequence: z.number().int().nonnegative(),
1574
+ // Multi-account Codex (P1). codexPinnedCredentialId: the account this session is
1575
+ // manually PINNED to (null ⇒ follow the workspace active pointer).
1576
+ // codexLastCredentialId: the account the most recent turn actually ran on (the
1577
+ // "Running on:" indicator's source). Both are credential-row ids, null until set.
1578
+ codexPinnedCredentialId: z.string().uuid().nullable(),
1579
+ codexLastCredentialId: z.string().uuid().nullable(),
1369
1580
  createdAt: z.string(),
1370
1581
  updatedAt: z.string()
1371
1582
  });
@@ -1441,7 +1652,11 @@ var SessionEventType = z.enum([
1441
1652
  // PTY stdout/stderr bytes (separate from command.output)
1442
1653
  "terminal.pty.exited",
1443
1654
  // PTY session ended (exitCode/reason)
1444
- "session.title_set"
1655
+ "session.title_set",
1656
+ // Multi-account Codex (P1): the account a session's turn runs on changed
1657
+ // (manual switch in P1; failover/rotation in P3 reuse the same event). Drives
1658
+ // the in-session "Running on:" indicator's live flip.
1659
+ "codex.account.switched"
1445
1660
  ]);
1446
1661
  var StreamUrlRotatedPayload = z.object({
1447
1662
  url: z.string().url(),
@@ -1847,6 +2062,17 @@ var CreateSessionRequest = z.object({
1847
2062
  model: z.string().min(1).optional(),
1848
2063
  reasoningEffort: ReasoningEffort.optional(),
1849
2064
  sandboxBackend: SandboxBackend.optional(),
2065
+ // The enrolled machine (a sandbox id) to run this session on; seeds the
2066
+ // active-sandbox pointer at creation so the FIRST turn routes to the chosen
2067
+ // machine (race-free: the pointer is committed before the worker turn
2068
+ // workflow can read it). An invalid/unowned/offline target fails the create.
2069
+ targetSandboxId: z.string().uuid().optional(),
2070
+ // The working directory the targeted machine runs the session under — the
2071
+ // path/cwd base for its agent exec, terminal, and file dock. Free-form pass-
2072
+ // through: a launch-workspace_root-relative subdir or an absolute machine path
2073
+ // (the agent's resolve_cwd handles both). Only valid WITH targetSandboxId
2074
+ // (workingDir alone is a 422); omitted ⇒ the machine's default workspace_root.
2075
+ workingDir: z.string().min(1).optional(),
1850
2076
  // Workspace environment attachment is fixed at session creation; follow-up
1851
2077
  // user.message events cannot switch or add one.
1852
2078
  environmentId: z.string().uuid().optional(),
@@ -1876,6 +2102,11 @@ var CreateSessionRequest = z.object({
1876
2102
  // A shared spawn inherits the box's (backend, os) — it is literally the same
1877
2103
  // box; the child cannot pick its own backend. Cross-workspace sharing is
1878
2104
  // forbidden by construction (the parent/group reads are RLS-workspace-scoped).
2105
+ // ENV-AWARE: the box's environment is fixed at creation, so a share requires
2106
+ // the SAME environmentId as the creator's box. On a mismatch the inherited
2107
+ // default silently falls back to an own box; an explicit "shared"/{groupId}
2108
+ // request 422s at create (instead of the first turn dying on the SDK's
2109
+ // manifest-env guard).
1879
2110
  sandbox: z.union([
1880
2111
  z.literal("shared"),
1881
2112
  z.literal("new"),
@@ -1956,7 +2187,17 @@ var CapabilityUnavailableReason = z.enum([
1956
2187
  "not_provisioned",
1957
2188
  "disabled_by_policy",
1958
2189
  "lease_cold",
1959
- "tier_headless"
2190
+ "tier_headless",
2191
+ // Selfhosted (bring-your-own-compute) negotiation states (M1 additive; the
2192
+ // selfhosted negotiation in select.ts wires them in M3):
2193
+ "agent_offline",
2194
+ // the enrolled agent process is not running / unreachable
2195
+ "agent_reconnecting",
2196
+ // a transient blip — the agent is reconnecting (warmable)
2197
+ "consent_required",
2198
+ // whole-machine / screen-control consent not yet acknowledged
2199
+ "display_unavailable"
2200
+ // headless machine with no display stack (no DesktopStream)
1960
2201
  ]);
1961
2202
  var SessionCapabilities = z.object({
1962
2203
  sessionId: z.string().uuid(),
@@ -1995,8 +2236,11 @@ var SessionCapabilities = z.object({
1995
2236
  reason: CapabilityUnavailableReason.nullable()
1996
2237
  }),
1997
2238
  DesktopStream: z.object({
1998
- transport: z.enum(["vnc-ws", "rdp-ws", "webrtc"]).nullable(),
1999
- client: z.enum(["novnc", "web-rdp"]).nullable(),
2239
+ // "relay-frames" is the selfhosted framebuffer stream: PNG-per-frame protobuf
2240
+ // datagrams spliced over the relay (NOT RFB). The viewer renders it with the
2241
+ // "frames" client (a canvas painter), distinct from Modal's "vnc-ws"/"novnc".
2242
+ transport: z.enum(["vnc-ws", "rdp-ws", "webrtc", "relay-frames"]).nullable(),
2243
+ client: z.enum(["novnc", "web-rdp", "frames"]).nullable(),
2000
2244
  mode: z.enum(["read-only", "interactive"]).default("read-only"),
2001
2245
  url: z.string().url().nullable(),
2002
2246
  token: z.string().nullable(),
@@ -2070,6 +2314,209 @@ var ViewerHeartbeatResponse = z.object({
2070
2314
  // false ⇒ the holder was reaped or the epoch is stale; the client re-attaches.
2071
2315
  alive: z.boolean()
2072
2316
  });
2317
+ var EnrollmentOs = z.enum(["linux", "macos", "windows"]);
2318
+ var EnrollmentArch = z.enum(["x86_64", "aarch64"]);
2319
+ var DeviceEnrollmentStartRequest = z.object({
2320
+ // The agent's ed25519 public key (the machine identity the enrollment binds to).
2321
+ publicKey: z.string().min(1).max(1024),
2322
+ os: EnrollmentOs.default("linux"),
2323
+ arch: EnrollmentArch.default("x86_64"),
2324
+ // Human-friendly machine name (hostname by default).
2325
+ machineName: z.string().min(1).max(256).optional(),
2326
+ // v1 only supports whole-machine; kept explicit so the consent is recorded.
2327
+ exposure: z.literal("whole-machine").default("whole-machine"),
2328
+ // The agent can offer a display (a real screen / Xvfb is available).
2329
+ canOfferDisplay: z.boolean().default(false),
2330
+ // The agent requests screen control (computer-use); the user's allow_screen_control
2331
+ // at approve is the AUTHORITATIVE consent.
2332
+ requestsScreenControl: z.boolean().default(false),
2333
+ // The workspace this machine is enrolling into. The agent is told this at install
2334
+ // (the user picks the workspace, or the install/enroll token carries it). The user
2335
+ // who approves must hold a grant in THIS workspace — that binding is what makes
2336
+ // the (user-unauthenticated) start safe: it cannot grant access to a workspace no
2337
+ // authorized user later approves in.
2338
+ workspaceId: z.string().uuid()
2339
+ });
2340
+ var DeviceEnrollmentStartResponse = z.object({
2341
+ deviceCode: z.string(),
2342
+ userCode: z.string(),
2343
+ verificationUri: z.string(),
2344
+ verificationUriComplete: z.string(),
2345
+ intervalSeconds: z.number().int().positive(),
2346
+ expiresInSeconds: z.number().int().positive()
2347
+ });
2348
+ var DeviceEnrollmentApproveRequest = z.object({
2349
+ userCode: z.string().min(1).max(64),
2350
+ allowScreenControl: z.boolean().default(false)
2351
+ });
2352
+ var DeviceEnrollmentApproveResponse = z.object({
2353
+ approved: z.boolean(),
2354
+ enrollmentId: z.string().uuid(),
2355
+ sandboxId: z.string().uuid(),
2356
+ allowScreenControl: z.boolean()
2357
+ });
2358
+ var DeviceEnrollmentPollRequest = z.object({
2359
+ deviceCode: z.string().min(1).max(256)
2360
+ });
2361
+ var DeviceEnrollmentState = z.enum(["pending", "authorized", "denied", "expired", "disabled"]);
2362
+ var EnrollmentCredentialsResponse = z.object({
2363
+ agentId: z.string().uuid(),
2364
+ workspaceId: z.string().uuid(),
2365
+ // The signed bearer the agent presents to the control plane (the `oge_` token).
2366
+ bearer: z.string(),
2367
+ // The Account-scoped control-plane subject prefix the agent subscribes to:
2368
+ // agent.<workspaceId>.<agentId>.
2369
+ subjectPrefix: z.string(),
2370
+ // Connect info for the control plane + stream relay (may be empty when not yet
2371
+ // configured for this deployment — the agent surfaces "control plane unconfigured").
2372
+ natsUrls: z.array(z.string()),
2373
+ relayUrl: z.string(),
2374
+ // The agent's PRODUCER token for the relay edge (the `ogr_` token; M8b). Presented
2375
+ // as StreamOpen.token when the agent registers a pty/desktop channel; the relay
2376
+ // verifies it then pairs the producer with the viewer (whose `ogs_` token the
2377
+ // relay also verifies). Empty when the relay-token plane is unconfigured for this
2378
+ // deployment (graceful degrade — the agent then presents an empty token the relay
2379
+ // rejects, surfacing the gap loudly rather than silently producing a dead stream).
2380
+ relayToken: z.string(),
2381
+ // VESTIGIAL (M-AUTH): there is no per-machine NATS Account creds file. The agent
2382
+ // presents the `bearer` above as the NATS connect AUTH-TOKEN; the server's
2383
+ // auth-callout responder validates it and mints a workspace-scoped user JWT. This
2384
+ // field echoes the bearer so a consumer reading it as the connect credential still
2385
+ // works; new consumers should read `bearer` directly.
2386
+ natsAccountCreds: z.string(),
2387
+ // The minisign public key the agent pins for self-update verification.
2388
+ updatePublicKey: z.string(),
2389
+ consentedWholeMachine: z.boolean(),
2390
+ consentedScreenControl: z.boolean()
2391
+ });
2392
+ var DeviceEnrollmentPollResponse = z.object({
2393
+ state: DeviceEnrollmentState,
2394
+ // Present only when state === "authorized".
2395
+ credentials: EnrollmentCredentialsResponse.optional()
2396
+ });
2397
+ var EnrollmentSummary = z.object({
2398
+ id: z.string().uuid(),
2399
+ pubkey: z.string(),
2400
+ exposure: z.literal("whole-machine"),
2401
+ hasDisplay: z.boolean(),
2402
+ allowScreenControl: z.boolean(),
2403
+ status: z.enum(["active", "revoked"]),
2404
+ os: EnrollmentOs,
2405
+ arch: z.string(),
2406
+ lastSeenAt: z.string().nullable(),
2407
+ createdAt: z.string(),
2408
+ revokedAt: z.string().nullable()
2409
+ });
2410
+ var ListEnrollmentsResponse = z.object({
2411
+ enrollments: z.array(EnrollmentSummary)
2412
+ });
2413
+ var RevokeEnrollmentResponse = z.object({
2414
+ revoked: z.boolean()
2415
+ });
2416
+ var DeviceEnrollmentLookupRequest = z.object({
2417
+ userCode: z.string().min(1).max(64)
2418
+ });
2419
+ var DeviceEnrollmentLookupMachine = z.object({
2420
+ machineName: z.string().nullable(),
2421
+ os: EnrollmentOs,
2422
+ arch: z.string(),
2423
+ canOfferDisplay: z.boolean(),
2424
+ requestsScreenControl: z.boolean()
2425
+ });
2426
+ var DeviceEnrollmentLookupResponse = z.object({
2427
+ workspaceId: z.string().uuid(),
2428
+ userCode: z.string(),
2429
+ machine: DeviceEnrollmentLookupMachine,
2430
+ expiresAt: z.string()
2431
+ });
2432
+ var DeviceEnrollmentDenyRequest = z.object({
2433
+ userCode: z.string().min(1).max(64)
2434
+ });
2435
+ var DeviceEnrollmentDenyResponse = z.object({
2436
+ denied: z.boolean()
2437
+ });
2438
+ var MintEnrollTokenRequest = z.object({
2439
+ allowScreenControl: z.boolean().default(false)
2440
+ });
2441
+ var MintEnrollTokenResponse = z.object({
2442
+ // The `oget_` token. SECRET — the UI shows it once with a copy-now warning.
2443
+ token: z.string(),
2444
+ expiresAt: z.string(),
2445
+ expiresInSeconds: z.number().int().positive()
2446
+ });
2447
+ var EnrollTokenExchangeRequest = z.object({
2448
+ // The `oget_` enroll token (the auth + the workspace/account/consent grant).
2449
+ token: z.string().min(1),
2450
+ // The agent's ed25519 public key (the machine identity the enrollment binds to).
2451
+ publicKey: z.string().min(1).max(1024),
2452
+ os: EnrollmentOs.default("linux"),
2453
+ arch: EnrollmentArch.default("x86_64"),
2454
+ machineName: z.string().min(1).max(256).optional(),
2455
+ // v1 only supports whole-machine; kept explicit so the consent is recorded.
2456
+ exposure: z.literal("whole-machine").default("whole-machine"),
2457
+ canOfferDisplay: z.boolean().default(false),
2458
+ // The agent's REQUEST; the token's allowScreenControl is the AUTHORITATIVE consent.
2459
+ requestsScreenControl: z.boolean().default(false)
2460
+ });
2461
+ var EnrollTokenExchangeResponse = z.object({
2462
+ credentials: EnrollmentCredentialsResponse
2463
+ });
2464
+ var MetricSample = z.object({
2465
+ cpuPct: z.number(),
2466
+ load1: z.number(),
2467
+ load5: z.number(),
2468
+ load15: z.number(),
2469
+ memUsedBytes: z.number().int(),
2470
+ memTotalBytes: z.number().int(),
2471
+ diskUsedBytes: z.number().int(),
2472
+ diskTotalBytes: z.number().int(),
2473
+ gpuUtilPct: z.number().nullable(),
2474
+ gpuMemBytes: z.number().int().nullable(),
2475
+ runQueue: z.number(),
2476
+ sampledAt: z.string()
2477
+ });
2478
+ var MachineState = z.enum([
2479
+ "online",
2480
+ "reconnecting",
2481
+ "offline",
2482
+ "consent_required",
2483
+ "display_unavailable",
2484
+ "enrolling"
2485
+ ]);
2486
+ var MachineKind = z.enum(["modal", "selfhosted"]);
2487
+ var MachineView = z.object({
2488
+ sandboxId: z.string(),
2489
+ enrollmentId: z.string().nullable(),
2490
+ name: z.string(),
2491
+ kind: MachineKind,
2492
+ state: MachineState,
2493
+ active: z.boolean(),
2494
+ isSessionGroup: z.boolean(),
2495
+ os: z.string(),
2496
+ arch: z.string(),
2497
+ hasDisplay: z.boolean(),
2498
+ allowScreenControl: z.boolean(),
2499
+ sharedSessionCount: z.number().int(),
2500
+ lastSeenAt: z.string().nullable(),
2501
+ metrics: MetricSample.nullable()
2502
+ });
2503
+ var MachinesResponse = z.object({
2504
+ activeSandboxId: z.string().nullable(),
2505
+ activeEpoch: z.number().int(),
2506
+ machines: z.array(MachineView)
2507
+ });
2508
+ var SwapActiveSandboxRequest = z.object({
2509
+ target: z.string().min(1)
2510
+ });
2511
+ var SwapActiveSandboxResponse = z.object({
2512
+ swapped: z.boolean(),
2513
+ activeSandboxId: z.string().nullable(),
2514
+ activeEpoch: z.number().int(),
2515
+ reason: z.string().optional()
2516
+ });
2517
+ var MachineMetricsSeriesResponse = z.object({
2518
+ samples: z.array(MetricSample)
2519
+ });
2073
2520
  var ClientModel = z.object({
2074
2521
  id: z.string(),
2075
2522
  label: z.string(),
@@ -2192,6 +2639,18 @@ export {
2192
2639
  CreateWorkspaceRequest,
2193
2640
  DESKTOP_STREAM_PORT,
2194
2641
  DelegatedAccessTokenPayload,
2642
+ DeviceEnrollmentApproveRequest,
2643
+ DeviceEnrollmentApproveResponse,
2644
+ DeviceEnrollmentDenyRequest,
2645
+ DeviceEnrollmentDenyResponse,
2646
+ DeviceEnrollmentLookupMachine,
2647
+ DeviceEnrollmentLookupRequest,
2648
+ DeviceEnrollmentLookupResponse,
2649
+ DeviceEnrollmentPollRequest,
2650
+ DeviceEnrollmentPollResponse,
2651
+ DeviceEnrollmentStartRequest,
2652
+ DeviceEnrollmentStartResponse,
2653
+ DeviceEnrollmentState,
2195
2654
  DiscoverMcpCapabilitiesResponse,
2196
2655
  Document,
2197
2656
  DocumentBase,
@@ -2200,6 +2659,15 @@ export {
2200
2659
  DocumentStatus,
2201
2660
  EnableCapabilityRequest,
2202
2661
  EnablePackRequest,
2662
+ EnrollTokenExchangeRequest,
2663
+ EnrollTokenExchangeResponse,
2664
+ EnrollTokenPayload,
2665
+ EnrollmentArch,
2666
+ EnrollmentBearerPayload,
2667
+ EnrollmentCredentialsResponse,
2668
+ EnrollmentOs,
2669
+ EnrollmentSummary,
2670
+ EntitlementDecision,
2203
2671
  EntitlementValue,
2204
2672
  Entitlements,
2205
2673
  EntitlementsMode,
@@ -2248,9 +2716,18 @@ export {
2248
2716
  GoalSpec,
2249
2717
  LimitAction,
2250
2718
  LimitDecision,
2719
+ ListEnrollmentsResponse,
2251
2720
  ListWorkspaceMembersResponse,
2721
+ MachineKind,
2722
+ MachineMetricsSeriesResponse,
2723
+ MachineState,
2724
+ MachineView,
2725
+ MachinesResponse,
2252
2726
  ManagedAccount,
2253
2727
  MarketingDailyAnalysisTaskRequest,
2728
+ MetricSample,
2729
+ MintEnrollTokenRequest,
2730
+ MintEnrollTokenResponse,
2254
2731
  PackInstallation,
2255
2732
  PackInstallationStatus,
2256
2733
  PageInfo,
@@ -2270,10 +2747,12 @@ export {
2270
2747
  RecordingMode,
2271
2748
  RecordingStartedPayload,
2272
2749
  RegisterCapabilityPackRequest,
2750
+ RelayTokenPayload,
2273
2751
  ReorderSessionTurnsRequest,
2274
2752
  RepositoryResourceRef,
2275
2753
  ResourceRef,
2276
2754
  ResourceRefConflictError,
2755
+ RevokeEnrollmentResponse,
2277
2756
  SandboxBackend,
2278
2757
  SandboxCapabilityName,
2279
2758
  SandboxCommandOutputDeltaPayload,
@@ -2312,6 +2791,8 @@ export {
2312
2791
  StreamRevokedPayload,
2313
2792
  StreamTokenPayload,
2314
2793
  StreamUrlRotatedPayload,
2794
+ SwapActiveSandboxRequest,
2795
+ SwapActiveSandboxResponse,
2315
2796
  TERMINAL_STREAM_PORT,
2316
2797
  TerminalExecRequest,
2317
2798
  TerminalExecResponse,
@@ -2346,9 +2827,15 @@ export {
2346
2827
  reasoningEffortForMetadata,
2347
2828
  resourceIdentityKey,
2348
2829
  signDelegatedAccessToken,
2830
+ signEnrollToken,
2831
+ signEnrollmentBearer,
2832
+ signRelayToken,
2349
2833
  signStreamToken,
2350
2834
  stableJson,
2351
2835
  verifyDelegatedAccessToken,
2836
+ verifyEnrollToken,
2837
+ verifyEnrollmentBearer,
2838
+ verifyRelayToken,
2352
2839
  verifyStreamToken
2353
2840
  };
2354
2841
  //# sourceMappingURL=index.js.map