@roamcode.ai/server 1.2.0 → 1.3.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.d.ts CHANGED
@@ -95,7 +95,7 @@ interface ServerRuntimeConfig {
95
95
  dataDir: string;
96
96
  /**
97
97
  * Trust X-Forwarded-* (passed to Fastify as `trustProxy`). Default false. PREFER a specific proxy IP/CIDR
98
- * (e.g. "127.0.0.1" for a same-host cloudflared/Caddy) over `true`: `true` trusts EVERY hop and takes the
98
+ * (e.g. "127.0.0.1" for a same-host Caddy process) over `true`: `true` trusts EVERY hop and takes the
99
99
  * left-most XFF entry, which a client can prepend to spoof `request.ip` and poison the rate limiter. A
100
100
  * string here is Fastify's trustProxy spec (IP, CIDR, or comma-list); boolean true = trust all hops.
101
101
  */
@@ -171,7 +171,7 @@ type AuthCheckResult = {
171
171
  * WebSocket upgrade.
172
172
  *
173
173
  * Proxy lockout caveat: the lockout is keyed by `clientKey` (`request.ip`).
174
- * Behind a reverse proxy (Caddy / Cloudflare) `request.ip` is the proxy's IP
174
+ * Behind a reverse proxy, `request.ip` is the proxy's IP
175
175
  * for EVERY client, collapsing the per-client lockout to one shared key. To
176
176
  * stop that from self-DoS-ing the sole legitimate user, {@link check} validates
177
177
  * the token FIRST: a CORRECT token is ALWAYS accepted, even while its key is
@@ -743,6 +743,36 @@ interface DeviceEnrollment {
743
743
  token: string;
744
744
  device: DeviceInfo;
745
745
  }
746
+ type CloudDeviceEnrollmentState = "prepared" | "local-finalized" | "cloud-report-pending" | "complete" | "revoked";
747
+ interface CloudDeviceEnrollmentPrepareInput {
748
+ enrollmentId: string;
749
+ deviceId: string;
750
+ challenge: string;
751
+ name: string;
752
+ token: string;
753
+ relayIdentityPublicKey: string;
754
+ durableRelayCredentialHash: string;
755
+ }
756
+ interface CloudDeviceEnrollmentProgress {
757
+ enrollmentId: string;
758
+ deviceId: string;
759
+ state: CloudDeviceEnrollmentState;
760
+ durableRelayCredentialHash: string;
761
+ temporaryRelayCredentialHash?: string;
762
+ controlPlaneDeviceId?: string;
763
+ device?: DeviceInfo;
764
+ }
765
+ interface PendingCloudDevicePromotion {
766
+ enrollmentId: string;
767
+ deviceId: string;
768
+ expectedCredentialHash: string;
769
+ credentialHash: string;
770
+ controlPlaneDeviceId: string;
771
+ brokerPromoted: boolean;
772
+ }
773
+ declare class CloudDeviceEnrollmentConflictError extends Error {
774
+ constructor();
775
+ }
746
776
  interface DeviceStore {
747
777
  readonly mode: "sqlite" | "memory-fallback";
748
778
  issuePairing(now?: number, scopes?: DeviceScope[]): PairingTicket;
@@ -761,6 +791,22 @@ interface DeviceStore {
761
791
  /** Resolve a per-device bearer credential and best-effort touch its last-seen time. */
762
792
  authenticate(token: string, now?: number, requiredScope?: DeviceScope): DeviceInfo | undefined;
763
793
  relayIdentity(id: string): DeviceRelayIdentity | undefined;
794
+ /** Persist only digests before contacting the control plane; exact replays resume the same saga. */
795
+ beginCloudDeviceEnrollment(input: CloudDeviceEnrollmentPrepareInput, now?: number): CloudDeviceEnrollmentProgress;
796
+ /** Atomically inserts the canonical relay actor and advances the saga after control-plane confirmation. */
797
+ finalizeCloudDeviceEnrollment(enrollmentId: string, temporaryRelayCredentialHash: string, controlPlaneDeviceId: string, now?: number): CloudDeviceEnrollmentProgress;
798
+ /** Persist the successful broker CAS before the control-plane completion report is attempted. */
799
+ markCloudDeviceEnrollmentPromoted(enrollmentId: string, expectedCredentialHash: string, credentialHash: string, now?: number): CloudDeviceEnrollmentProgress;
800
+ /** Marks activation durable only after the broker CAS and control-plane report both commit. */
801
+ completeCloudDeviceEnrollment(enrollmentId: string, expectedCredentialHash: string, credentialHash: string, now?: number): CloudDeviceEnrollmentProgress;
802
+ /** Tombstone a control-plane-revoked enrollment and remove its still-inert local actor. */
803
+ revokeCloudDeviceEnrollment(enrollmentId: string, controlPlaneDeviceId: string, expectedCredentialHash: string, credentialHash: string, now?: number): CloudDeviceEnrollmentProgress;
804
+ /** Pending local actors must not normal-auth until broker promotion and a fresh cloud grant both commit. */
805
+ cloudDeviceEnrollmentPending(deviceId: string): boolean;
806
+ /** Return a bounded, oldest-attempted-first recovery page without materializing the full queue. */
807
+ pendingCloudDevicePromotions(now?: number, limit?: number): PendingCloudDevicePromotion[];
808
+ /** Move an exact still-pending promotion behind other queued work after a failed recovery attempt. */
809
+ deferCloudDevicePromotion(enrollmentId: string, expectedCredentialHash: string, credentialHash: string, now?: number): boolean;
764
810
  list(): DeviceInfo[];
765
811
  rename(id: string, name: string): DeviceInfo | undefined;
766
812
  revoke(id: string): boolean;
@@ -773,6 +819,8 @@ interface OpenDeviceStoreOptions {
773
819
  generateSecret?: () => string;
774
820
  generateToken?: () => string;
775
821
  generateId?: () => string;
822
+ /** Test/portable hook; a loader failure selects the bounded in-memory fallback. */
823
+ loadDatabase?: () => typeof better_sqlite3;
776
824
  }
777
825
  declare function normalizeDeviceScopes(value: unknown): DeviceScope[] | undefined;
778
826
  /** Keep device labels useful in UI while refusing control characters and unbounded payloads. */
@@ -866,10 +914,10 @@ declare class InputLeaseCoordinator {
866
914
  type TeamStoreMode = "sqlite" | "memory-fallback";
867
915
  type TeamMemberKind = "person" | "service";
868
916
  type TeamMemberStatus = "active" | "suspended" | "removed";
869
- type TeamRole = "viewer" | "operator" | "workspace-manager" | "extension-manager" | "policy-admin" | "organization-admin";
917
+ type TeamRole = "viewer" | "operator" | "node-admin" | "workspace-manager" | "extension-manager" | "policy-admin" | "organization-admin";
870
918
  type TeamScopeType = "team" | "host" | "workspace";
871
919
  type TeamPrincipalType = "device" | "host" | "local" | "relay";
872
- type TeamPermission = "team:read" | "sessions:read" | "sessions:operate" | "attention:read" | "attention:manage" | "presence:read" | "presence:write" | "workspaces:manage" | "extensions:manage" | "policy:manage" | "members:manage" | "audit:read" | "fleet:read";
920
+ type TeamPermission = "team:read" | "sessions:read" | "sessions:operate" | "attention:read" | "attention:manage" | "presence:read" | "presence:write" | "workspaces:manage" | "extensions:manage" | "policy:manage" | "members:manage" | "node-access:manage" | "audit:read" | "fleet:read";
873
921
  interface TeamRecord {
874
922
  id: string;
875
923
  name: string;
@@ -948,6 +996,11 @@ interface TeamStore {
948
996
  scopeType?: TeamScopeType;
949
997
  scopeId?: string;
950
998
  }, now?: number): TeamRoleBinding;
999
+ setNodeAccessRole(input: {
1000
+ memberId: string;
1001
+ nodeId: string;
1002
+ role: "viewer" | "operator" | "node-admin";
1003
+ }, now?: number): TeamRoleBinding;
951
1004
  revokeRole(id: string, now?: number): boolean;
952
1005
  listPrincipalBindings(memberId?: string): TeamPrincipalBinding[];
953
1006
  bindPrincipal(input: {
@@ -1247,6 +1300,8 @@ interface RelayAccountRecord {
1247
1300
  updatedAt: number;
1248
1301
  }
1249
1302
  interface RelayAccountFields {
1303
+ /** Stable control-plane identity. Omit for the legacy server-generated account flow. */
1304
+ id?: string;
1250
1305
  label: string;
1251
1306
  plan?: RelayAccountPlan;
1252
1307
  maxRoutes?: number;
@@ -1279,6 +1334,8 @@ interface RelayAccountStore {
1279
1334
  /** Verify ownership for recovery without granting a suspended account route access. */
1280
1335
  verifyCredential(credential: string): RelayAccountRecord | undefined;
1281
1336
  authenticate(credential: string): RelayAccountRecord | undefined;
1337
+ /** Constant-time comparison for idempotent control-plane provisioning and credential rotation. */
1338
+ credentialMatches(id: string, credential: RelayAccountCredentialInput): boolean;
1282
1339
  updateAccount(id: string, input: UpdateRelayAccountInput, expectedRevision: number, now?: number): RelayAccountRecord | undefined;
1283
1340
  rotateCredential(id: string, credential: RelayAccountCredentialInput, expectedRevision: number, now?: number): RelayAccountRecord | undefined;
1284
1341
  close(): void;
@@ -1299,7 +1356,8 @@ declare function openRelayAccountStore(options: OpenRelayAccountStoreOptions): R
1299
1356
 
1300
1357
  interface RelayDeviceProvisioner {
1301
1358
  putDevice(deviceId: string, credentialHash: string, expiresAt?: number): Promise<void>;
1302
- revokeDevice(deviceId: string): Promise<void>;
1359
+ promoteDevice(deviceId: string, expectedCredentialHash: string, credentialHash: string): Promise<void>;
1360
+ revokeDevice(deviceId: string, expectedCredentialHash?: string): Promise<void>;
1303
1361
  }
1304
1362
  interface RelayDeviceProvisionerOptions {
1305
1363
  relayUrl: string;
@@ -1335,7 +1393,9 @@ interface RelayPairingBootstrap {
1335
1393
  generateDeviceCredential?: () => string;
1336
1394
  }
1337
1395
  declare function normalizeRelayAppUrl(value: string): string;
1338
- declare function buildRelayPairingUrl(appUrl: string, pairing: RelayPairingPackage): string;
1396
+ declare function buildRelayPairingUrl(appUrl: string, pairing: RelayPairingPackage, options?: {
1397
+ hostedApp?: boolean;
1398
+ }): string;
1339
1399
 
1340
1400
  declare const BLIND_RELAY_PROTOCOL_VERSION: 1;
1341
1401
  declare const BLIND_RELAY_DEFAULT_MAX_FRAME_BYTES = 1500000;
@@ -1412,6 +1472,711 @@ declare function relayRpcResponse(input: {
1412
1472
  body?: Uint8Array;
1413
1473
  }): RelayRpcResponse;
1414
1474
 
1475
+ declare const CLOUD_CONTRACT_VERSION: 1;
1476
+ declare const CLOUD_AUTHORIZATION_CONTRACT_VERSION: 2;
1477
+ declare const CLOUD_AUTHORIZATION_SIGNATURE_ALGORITHM: "Ed25519";
1478
+ declare const CLOUD_AUTHORIZATION_SIGNATURE_ALGORITHM_V2: "Ed25519-SHA256";
1479
+ declare const CLOUD_AUTHORIZATION_SIGNATURE_DOMAIN = "roamcode-cloud-authorization-snapshot-v1";
1480
+ declare const CLOUD_AUTHORIZATION_SIGNATURE_DOMAIN_V2 = "roamcode-cloud-authorization-snapshot-v2";
1481
+ declare const CLOUD_AUTHORIZATION_PERMISSIONS: readonly ["team:read", "sessions:read", "sessions:operate", "attention:read", "attention:manage", "presence:read", "presence:write", "workspaces:manage", "extensions:manage", "policy:manage", "members:manage", "node-access:manage", "audit:read", "fleet:read"];
1482
+ declare const CloudRelayHostIdentitySchema: z.ZodObject<{
1483
+ publicKey: z.ZodString;
1484
+ fingerprint: z.ZodString;
1485
+ }, z.core.$strict>;
1486
+ declare const CloudAuthorizationPermissionSchema: z.ZodEnum<{
1487
+ "team:read": "team:read";
1488
+ "sessions:read": "sessions:read";
1489
+ "sessions:operate": "sessions:operate";
1490
+ "attention:read": "attention:read";
1491
+ "attention:manage": "attention:manage";
1492
+ "presence:read": "presence:read";
1493
+ "presence:write": "presence:write";
1494
+ "workspaces:manage": "workspaces:manage";
1495
+ "extensions:manage": "extensions:manage";
1496
+ "policy:manage": "policy:manage";
1497
+ "members:manage": "members:manage";
1498
+ "node-access:manage": "node-access:manage";
1499
+ "audit:read": "audit:read";
1500
+ "fleet:read": "fleet:read";
1501
+ }>;
1502
+ declare const CloudHostHeartbeatV1Schema: z.ZodObject<{
1503
+ v: z.ZodLiteral<1>;
1504
+ kind: z.ZodLiteral<"host-heartbeat">;
1505
+ organizationId: z.ZodString;
1506
+ hostId: z.ZodString;
1507
+ instanceId: z.ZodString;
1508
+ sentAt: z.ZodNumber;
1509
+ sequence: z.ZodNumber;
1510
+ softwareVersion: z.ZodString;
1511
+ state: z.ZodEnum<{
1512
+ ready: "ready";
1513
+ draining: "draining";
1514
+ }>;
1515
+ authorizationRevision: z.ZodNullable<z.ZodNumber>;
1516
+ relayHostIdentity: z.ZodOptional<z.ZodObject<{
1517
+ publicKey: z.ZodString;
1518
+ fingerprint: z.ZodString;
1519
+ }, z.core.$strict>>;
1520
+ capabilities: z.ZodArray<z.ZodString>;
1521
+ }, z.core.$strict>;
1522
+ declare const CloudAuthorizationScopeV1Schema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1523
+ type: z.ZodLiteral<"organization">;
1524
+ }, z.core.$strict>, z.ZodObject<{
1525
+ type: z.ZodLiteral<"host">;
1526
+ id: z.ZodString;
1527
+ }, z.core.$strict>, z.ZodObject<{
1528
+ type: z.ZodLiteral<"workspace">;
1529
+ id: z.ZodString;
1530
+ }, z.core.$strict>], "type">;
1531
+ declare const CloudAuthorizationGrantV1Schema: z.ZodObject<{
1532
+ principalType: z.ZodEnum<{
1533
+ device: "device";
1534
+ relay: "relay";
1535
+ }>;
1536
+ principalId: z.ZodString;
1537
+ permissions: z.ZodArray<z.ZodEnum<{
1538
+ "team:read": "team:read";
1539
+ "sessions:read": "sessions:read";
1540
+ "sessions:operate": "sessions:operate";
1541
+ "attention:read": "attention:read";
1542
+ "attention:manage": "attention:manage";
1543
+ "presence:read": "presence:read";
1544
+ "presence:write": "presence:write";
1545
+ "workspaces:manage": "workspaces:manage";
1546
+ "extensions:manage": "extensions:manage";
1547
+ "policy:manage": "policy:manage";
1548
+ "members:manage": "members:manage";
1549
+ "node-access:manage": "node-access:manage";
1550
+ "audit:read": "audit:read";
1551
+ "fleet:read": "fleet:read";
1552
+ }>>;
1553
+ scope: z.ZodDiscriminatedUnion<[z.ZodObject<{
1554
+ type: z.ZodLiteral<"organization">;
1555
+ }, z.core.$strict>, z.ZodObject<{
1556
+ type: z.ZodLiteral<"host">;
1557
+ id: z.ZodString;
1558
+ }, z.core.$strict>, z.ZodObject<{
1559
+ type: z.ZodLiteral<"workspace">;
1560
+ id: z.ZodString;
1561
+ }, z.core.$strict>], "type">;
1562
+ }, z.core.$strict>;
1563
+ declare const CloudAuthorizationSnapshotV1Schema: z.ZodObject<{
1564
+ v: z.ZodLiteral<1>;
1565
+ kind: z.ZodLiteral<"authorization-snapshot">;
1566
+ organizationId: z.ZodString;
1567
+ hostId: z.ZodString;
1568
+ revision: z.ZodNumber;
1569
+ issuedAt: z.ZodNumber;
1570
+ notBefore: z.ZodNumber;
1571
+ expiresAt: z.ZodNumber;
1572
+ grants: z.ZodArray<z.ZodObject<{
1573
+ principalType: z.ZodEnum<{
1574
+ device: "device";
1575
+ relay: "relay";
1576
+ }>;
1577
+ principalId: z.ZodString;
1578
+ permissions: z.ZodArray<z.ZodEnum<{
1579
+ "team:read": "team:read";
1580
+ "sessions:read": "sessions:read";
1581
+ "sessions:operate": "sessions:operate";
1582
+ "attention:read": "attention:read";
1583
+ "attention:manage": "attention:manage";
1584
+ "presence:read": "presence:read";
1585
+ "presence:write": "presence:write";
1586
+ "workspaces:manage": "workspaces:manage";
1587
+ "extensions:manage": "extensions:manage";
1588
+ "policy:manage": "policy:manage";
1589
+ "members:manage": "members:manage";
1590
+ "node-access:manage": "node-access:manage";
1591
+ "audit:read": "audit:read";
1592
+ "fleet:read": "fleet:read";
1593
+ }>>;
1594
+ scope: z.ZodDiscriminatedUnion<[z.ZodObject<{
1595
+ type: z.ZodLiteral<"organization">;
1596
+ }, z.core.$strict>, z.ZodObject<{
1597
+ type: z.ZodLiteral<"host">;
1598
+ id: z.ZodString;
1599
+ }, z.core.$strict>, z.ZodObject<{
1600
+ type: z.ZodLiteral<"workspace">;
1601
+ id: z.ZodString;
1602
+ }, z.core.$strict>], "type">;
1603
+ }, z.core.$strict>>;
1604
+ }, z.core.$strict>;
1605
+ declare const CloudAuthorizationSnapshotV2Schema: z.ZodObject<{
1606
+ v: z.ZodLiteral<2>;
1607
+ kind: z.ZodLiteral<"authorization-snapshot">;
1608
+ organizationId: z.ZodString;
1609
+ hostId: z.ZodString;
1610
+ revision: z.ZodNumber;
1611
+ issuedAt: z.ZodNumber;
1612
+ notBefore: z.ZodNumber;
1613
+ expiresAt: z.ZodNumber;
1614
+ grants: z.ZodArray<z.ZodObject<{
1615
+ principalType: z.ZodEnum<{
1616
+ device: "device";
1617
+ relay: "relay";
1618
+ }>;
1619
+ principalId: z.ZodString;
1620
+ permissions: z.ZodArray<z.ZodEnum<{
1621
+ "team:read": "team:read";
1622
+ "sessions:read": "sessions:read";
1623
+ "sessions:operate": "sessions:operate";
1624
+ "attention:read": "attention:read";
1625
+ "attention:manage": "attention:manage";
1626
+ "presence:read": "presence:read";
1627
+ "presence:write": "presence:write";
1628
+ "workspaces:manage": "workspaces:manage";
1629
+ "extensions:manage": "extensions:manage";
1630
+ "policy:manage": "policy:manage";
1631
+ "members:manage": "members:manage";
1632
+ "node-access:manage": "node-access:manage";
1633
+ "audit:read": "audit:read";
1634
+ "fleet:read": "fleet:read";
1635
+ }>>;
1636
+ scope: z.ZodDiscriminatedUnion<[z.ZodObject<{
1637
+ type: z.ZodLiteral<"organization">;
1638
+ }, z.core.$strict>, z.ZodObject<{
1639
+ type: z.ZodLiteral<"host">;
1640
+ id: z.ZodString;
1641
+ }, z.core.$strict>, z.ZodObject<{
1642
+ type: z.ZodLiteral<"workspace">;
1643
+ id: z.ZodString;
1644
+ }, z.core.$strict>], "type">;
1645
+ }, z.core.$strict>>;
1646
+ }, z.core.$strict>;
1647
+ declare const CloudAuthorizationSnapshotSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1648
+ v: z.ZodLiteral<1>;
1649
+ kind: z.ZodLiteral<"authorization-snapshot">;
1650
+ organizationId: z.ZodString;
1651
+ hostId: z.ZodString;
1652
+ revision: z.ZodNumber;
1653
+ issuedAt: z.ZodNumber;
1654
+ notBefore: z.ZodNumber;
1655
+ expiresAt: z.ZodNumber;
1656
+ grants: z.ZodArray<z.ZodObject<{
1657
+ principalType: z.ZodEnum<{
1658
+ device: "device";
1659
+ relay: "relay";
1660
+ }>;
1661
+ principalId: z.ZodString;
1662
+ permissions: z.ZodArray<z.ZodEnum<{
1663
+ "team:read": "team:read";
1664
+ "sessions:read": "sessions:read";
1665
+ "sessions:operate": "sessions:operate";
1666
+ "attention:read": "attention:read";
1667
+ "attention:manage": "attention:manage";
1668
+ "presence:read": "presence:read";
1669
+ "presence:write": "presence:write";
1670
+ "workspaces:manage": "workspaces:manage";
1671
+ "extensions:manage": "extensions:manage";
1672
+ "policy:manage": "policy:manage";
1673
+ "members:manage": "members:manage";
1674
+ "node-access:manage": "node-access:manage";
1675
+ "audit:read": "audit:read";
1676
+ "fleet:read": "fleet:read";
1677
+ }>>;
1678
+ scope: z.ZodDiscriminatedUnion<[z.ZodObject<{
1679
+ type: z.ZodLiteral<"organization">;
1680
+ }, z.core.$strict>, z.ZodObject<{
1681
+ type: z.ZodLiteral<"host">;
1682
+ id: z.ZodString;
1683
+ }, z.core.$strict>, z.ZodObject<{
1684
+ type: z.ZodLiteral<"workspace">;
1685
+ id: z.ZodString;
1686
+ }, z.core.$strict>], "type">;
1687
+ }, z.core.$strict>>;
1688
+ }, z.core.$strict>, z.ZodObject<{
1689
+ v: z.ZodLiteral<2>;
1690
+ kind: z.ZodLiteral<"authorization-snapshot">;
1691
+ organizationId: z.ZodString;
1692
+ hostId: z.ZodString;
1693
+ revision: z.ZodNumber;
1694
+ issuedAt: z.ZodNumber;
1695
+ notBefore: z.ZodNumber;
1696
+ expiresAt: z.ZodNumber;
1697
+ grants: z.ZodArray<z.ZodObject<{
1698
+ principalType: z.ZodEnum<{
1699
+ device: "device";
1700
+ relay: "relay";
1701
+ }>;
1702
+ principalId: z.ZodString;
1703
+ permissions: z.ZodArray<z.ZodEnum<{
1704
+ "team:read": "team:read";
1705
+ "sessions:read": "sessions:read";
1706
+ "sessions:operate": "sessions:operate";
1707
+ "attention:read": "attention:read";
1708
+ "attention:manage": "attention:manage";
1709
+ "presence:read": "presence:read";
1710
+ "presence:write": "presence:write";
1711
+ "workspaces:manage": "workspaces:manage";
1712
+ "extensions:manage": "extensions:manage";
1713
+ "policy:manage": "policy:manage";
1714
+ "members:manage": "members:manage";
1715
+ "node-access:manage": "node-access:manage";
1716
+ "audit:read": "audit:read";
1717
+ "fleet:read": "fleet:read";
1718
+ }>>;
1719
+ scope: z.ZodDiscriminatedUnion<[z.ZodObject<{
1720
+ type: z.ZodLiteral<"organization">;
1721
+ }, z.core.$strict>, z.ZodObject<{
1722
+ type: z.ZodLiteral<"host">;
1723
+ id: z.ZodString;
1724
+ }, z.core.$strict>, z.ZodObject<{
1725
+ type: z.ZodLiteral<"workspace">;
1726
+ id: z.ZodString;
1727
+ }, z.core.$strict>], "type">;
1728
+ }, z.core.$strict>>;
1729
+ }, z.core.$strict>], "v">;
1730
+ declare const SignedCloudAuthorizationSnapshotV1Schema: z.ZodObject<{
1731
+ v: z.ZodLiteral<1>;
1732
+ kind: z.ZodLiteral<"signed-authorization-snapshot">;
1733
+ algorithm: z.ZodLiteral<"Ed25519">;
1734
+ keyId: z.ZodString;
1735
+ snapshot: z.ZodObject<{
1736
+ v: z.ZodLiteral<1>;
1737
+ kind: z.ZodLiteral<"authorization-snapshot">;
1738
+ organizationId: z.ZodString;
1739
+ hostId: z.ZodString;
1740
+ revision: z.ZodNumber;
1741
+ issuedAt: z.ZodNumber;
1742
+ notBefore: z.ZodNumber;
1743
+ expiresAt: z.ZodNumber;
1744
+ grants: z.ZodArray<z.ZodObject<{
1745
+ principalType: z.ZodEnum<{
1746
+ device: "device";
1747
+ relay: "relay";
1748
+ }>;
1749
+ principalId: z.ZodString;
1750
+ permissions: z.ZodArray<z.ZodEnum<{
1751
+ "team:read": "team:read";
1752
+ "sessions:read": "sessions:read";
1753
+ "sessions:operate": "sessions:operate";
1754
+ "attention:read": "attention:read";
1755
+ "attention:manage": "attention:manage";
1756
+ "presence:read": "presence:read";
1757
+ "presence:write": "presence:write";
1758
+ "workspaces:manage": "workspaces:manage";
1759
+ "extensions:manage": "extensions:manage";
1760
+ "policy:manage": "policy:manage";
1761
+ "members:manage": "members:manage";
1762
+ "node-access:manage": "node-access:manage";
1763
+ "audit:read": "audit:read";
1764
+ "fleet:read": "fleet:read";
1765
+ }>>;
1766
+ scope: z.ZodDiscriminatedUnion<[z.ZodObject<{
1767
+ type: z.ZodLiteral<"organization">;
1768
+ }, z.core.$strict>, z.ZodObject<{
1769
+ type: z.ZodLiteral<"host">;
1770
+ id: z.ZodString;
1771
+ }, z.core.$strict>, z.ZodObject<{
1772
+ type: z.ZodLiteral<"workspace">;
1773
+ id: z.ZodString;
1774
+ }, z.core.$strict>], "type">;
1775
+ }, z.core.$strict>>;
1776
+ }, z.core.$strict>;
1777
+ signature: z.ZodString;
1778
+ }, z.core.$strict>;
1779
+ declare const SignedCloudAuthorizationSnapshotV2Schema: z.ZodObject<{
1780
+ v: z.ZodLiteral<2>;
1781
+ kind: z.ZodLiteral<"signed-authorization-snapshot">;
1782
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
1783
+ keyId: z.ZodString;
1784
+ snapshot: z.ZodObject<{
1785
+ v: z.ZodLiteral<2>;
1786
+ kind: z.ZodLiteral<"authorization-snapshot">;
1787
+ organizationId: z.ZodString;
1788
+ hostId: z.ZodString;
1789
+ revision: z.ZodNumber;
1790
+ issuedAt: z.ZodNumber;
1791
+ notBefore: z.ZodNumber;
1792
+ expiresAt: z.ZodNumber;
1793
+ grants: z.ZodArray<z.ZodObject<{
1794
+ principalType: z.ZodEnum<{
1795
+ device: "device";
1796
+ relay: "relay";
1797
+ }>;
1798
+ principalId: z.ZodString;
1799
+ permissions: z.ZodArray<z.ZodEnum<{
1800
+ "team:read": "team:read";
1801
+ "sessions:read": "sessions:read";
1802
+ "sessions:operate": "sessions:operate";
1803
+ "attention:read": "attention:read";
1804
+ "attention:manage": "attention:manage";
1805
+ "presence:read": "presence:read";
1806
+ "presence:write": "presence:write";
1807
+ "workspaces:manage": "workspaces:manage";
1808
+ "extensions:manage": "extensions:manage";
1809
+ "policy:manage": "policy:manage";
1810
+ "members:manage": "members:manage";
1811
+ "node-access:manage": "node-access:manage";
1812
+ "audit:read": "audit:read";
1813
+ "fleet:read": "fleet:read";
1814
+ }>>;
1815
+ scope: z.ZodDiscriminatedUnion<[z.ZodObject<{
1816
+ type: z.ZodLiteral<"organization">;
1817
+ }, z.core.$strict>, z.ZodObject<{
1818
+ type: z.ZodLiteral<"host">;
1819
+ id: z.ZodString;
1820
+ }, z.core.$strict>, z.ZodObject<{
1821
+ type: z.ZodLiteral<"workspace">;
1822
+ id: z.ZodString;
1823
+ }, z.core.$strict>], "type">;
1824
+ }, z.core.$strict>>;
1825
+ }, z.core.$strict>;
1826
+ signature: z.ZodString;
1827
+ }, z.core.$strict>;
1828
+ declare const SignedCloudAuthorizationSnapshotSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1829
+ v: z.ZodLiteral<1>;
1830
+ kind: z.ZodLiteral<"signed-authorization-snapshot">;
1831
+ algorithm: z.ZodLiteral<"Ed25519">;
1832
+ keyId: z.ZodString;
1833
+ snapshot: z.ZodObject<{
1834
+ v: z.ZodLiteral<1>;
1835
+ kind: z.ZodLiteral<"authorization-snapshot">;
1836
+ organizationId: z.ZodString;
1837
+ hostId: z.ZodString;
1838
+ revision: z.ZodNumber;
1839
+ issuedAt: z.ZodNumber;
1840
+ notBefore: z.ZodNumber;
1841
+ expiresAt: z.ZodNumber;
1842
+ grants: z.ZodArray<z.ZodObject<{
1843
+ principalType: z.ZodEnum<{
1844
+ device: "device";
1845
+ relay: "relay";
1846
+ }>;
1847
+ principalId: z.ZodString;
1848
+ permissions: z.ZodArray<z.ZodEnum<{
1849
+ "team:read": "team:read";
1850
+ "sessions:read": "sessions:read";
1851
+ "sessions:operate": "sessions:operate";
1852
+ "attention:read": "attention:read";
1853
+ "attention:manage": "attention:manage";
1854
+ "presence:read": "presence:read";
1855
+ "presence:write": "presence:write";
1856
+ "workspaces:manage": "workspaces:manage";
1857
+ "extensions:manage": "extensions:manage";
1858
+ "policy:manage": "policy:manage";
1859
+ "members:manage": "members:manage";
1860
+ "node-access:manage": "node-access:manage";
1861
+ "audit:read": "audit:read";
1862
+ "fleet:read": "fleet:read";
1863
+ }>>;
1864
+ scope: z.ZodDiscriminatedUnion<[z.ZodObject<{
1865
+ type: z.ZodLiteral<"organization">;
1866
+ }, z.core.$strict>, z.ZodObject<{
1867
+ type: z.ZodLiteral<"host">;
1868
+ id: z.ZodString;
1869
+ }, z.core.$strict>, z.ZodObject<{
1870
+ type: z.ZodLiteral<"workspace">;
1871
+ id: z.ZodString;
1872
+ }, z.core.$strict>], "type">;
1873
+ }, z.core.$strict>>;
1874
+ }, z.core.$strict>;
1875
+ signature: z.ZodString;
1876
+ }, z.core.$strict>, z.ZodObject<{
1877
+ v: z.ZodLiteral<2>;
1878
+ kind: z.ZodLiteral<"signed-authorization-snapshot">;
1879
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
1880
+ keyId: z.ZodString;
1881
+ snapshot: z.ZodObject<{
1882
+ v: z.ZodLiteral<2>;
1883
+ kind: z.ZodLiteral<"authorization-snapshot">;
1884
+ organizationId: z.ZodString;
1885
+ hostId: z.ZodString;
1886
+ revision: z.ZodNumber;
1887
+ issuedAt: z.ZodNumber;
1888
+ notBefore: z.ZodNumber;
1889
+ expiresAt: z.ZodNumber;
1890
+ grants: z.ZodArray<z.ZodObject<{
1891
+ principalType: z.ZodEnum<{
1892
+ device: "device";
1893
+ relay: "relay";
1894
+ }>;
1895
+ principalId: z.ZodString;
1896
+ permissions: z.ZodArray<z.ZodEnum<{
1897
+ "team:read": "team:read";
1898
+ "sessions:read": "sessions:read";
1899
+ "sessions:operate": "sessions:operate";
1900
+ "attention:read": "attention:read";
1901
+ "attention:manage": "attention:manage";
1902
+ "presence:read": "presence:read";
1903
+ "presence:write": "presence:write";
1904
+ "workspaces:manage": "workspaces:manage";
1905
+ "extensions:manage": "extensions:manage";
1906
+ "policy:manage": "policy:manage";
1907
+ "members:manage": "members:manage";
1908
+ "node-access:manage": "node-access:manage";
1909
+ "audit:read": "audit:read";
1910
+ "fleet:read": "fleet:read";
1911
+ }>>;
1912
+ scope: z.ZodDiscriminatedUnion<[z.ZodObject<{
1913
+ type: z.ZodLiteral<"organization">;
1914
+ }, z.core.$strict>, z.ZodObject<{
1915
+ type: z.ZodLiteral<"host">;
1916
+ id: z.ZodString;
1917
+ }, z.core.$strict>, z.ZodObject<{
1918
+ type: z.ZodLiteral<"workspace">;
1919
+ id: z.ZodString;
1920
+ }, z.core.$strict>], "type">;
1921
+ }, z.core.$strict>>;
1922
+ }, z.core.$strict>;
1923
+ signature: z.ZodString;
1924
+ }, z.core.$strict>], "v">;
1925
+ declare const CloudAuthorizationTrustedKeySchema: z.ZodObject<{
1926
+ keyId: z.ZodString;
1927
+ algorithm: z.ZodLiteral<"Ed25519">;
1928
+ publicKey: z.ZodString;
1929
+ notBefore: z.ZodOptional<z.ZodNumber>;
1930
+ notAfter: z.ZodOptional<z.ZodNumber>;
1931
+ trustExpiresAt: z.ZodOptional<z.ZodNumber>;
1932
+ }, z.core.$strict>;
1933
+ declare const CloudAuthorizationTrustedKeyV2Schema: z.ZodObject<{
1934
+ keyId: z.ZodString;
1935
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
1936
+ publicKey: z.ZodString;
1937
+ notBefore: z.ZodOptional<z.ZodNumber>;
1938
+ notAfter: z.ZodOptional<z.ZodNumber>;
1939
+ trustExpiresAt: z.ZodOptional<z.ZodNumber>;
1940
+ }, z.core.$strict>;
1941
+ declare const CloudAuthorizationTrustedKeyAnySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1942
+ keyId: z.ZodString;
1943
+ algorithm: z.ZodLiteral<"Ed25519">;
1944
+ publicKey: z.ZodString;
1945
+ notBefore: z.ZodOptional<z.ZodNumber>;
1946
+ notAfter: z.ZodOptional<z.ZodNumber>;
1947
+ trustExpiresAt: z.ZodOptional<z.ZodNumber>;
1948
+ }, z.core.$strict>, z.ZodObject<{
1949
+ keyId: z.ZodString;
1950
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
1951
+ publicKey: z.ZodString;
1952
+ notBefore: z.ZodOptional<z.ZodNumber>;
1953
+ notAfter: z.ZodOptional<z.ZodNumber>;
1954
+ trustExpiresAt: z.ZodOptional<z.ZodNumber>;
1955
+ }, z.core.$strict>], "algorithm">;
1956
+ type CloudAuthorizationPermission = z.infer<typeof CloudAuthorizationPermissionSchema>;
1957
+ type CloudRelayHostIdentity = z.infer<typeof CloudRelayHostIdentitySchema>;
1958
+ type CloudHostHeartbeatV1 = z.infer<typeof CloudHostHeartbeatV1Schema>;
1959
+ type CloudAuthorizationScopeV1 = z.infer<typeof CloudAuthorizationScopeV1Schema>;
1960
+ type CloudAuthorizationGrantV1 = z.infer<typeof CloudAuthorizationGrantV1Schema>;
1961
+ type CloudAuthorizationSnapshotV1 = z.infer<typeof CloudAuthorizationSnapshotV1Schema>;
1962
+ type CloudAuthorizationSnapshotV2 = z.infer<typeof CloudAuthorizationSnapshotV2Schema>;
1963
+ type CloudAuthorizationSnapshot = z.infer<typeof CloudAuthorizationSnapshotSchema>;
1964
+ type SignedCloudAuthorizationSnapshotV1 = z.infer<typeof SignedCloudAuthorizationSnapshotV1Schema>;
1965
+ type SignedCloudAuthorizationSnapshotV2 = z.infer<typeof SignedCloudAuthorizationSnapshotV2Schema>;
1966
+ type SignedCloudAuthorizationSnapshot = z.infer<typeof SignedCloudAuthorizationSnapshotSchema>;
1967
+ type CloudAuthorizationTrustedKeyV1 = z.infer<typeof CloudAuthorizationTrustedKeySchema>;
1968
+ type CloudAuthorizationTrustedKeyV2 = z.infer<typeof CloudAuthorizationTrustedKeyV2Schema>;
1969
+ type CloudAuthorizationTrustedKey = z.infer<typeof CloudAuthorizationTrustedKeyAnySchema>;
1970
+ type CloudAuthorizationVerificationErrorCode = "INVALID_ENVELOPE" | "INVALID_KEYRING" | "UNKNOWN_KEY" | "KEY_NOT_ACTIVE" | "TRUST_EXPIRED" | "ALGORITHM_MISMATCH" | "INVALID_PUBLIC_KEY" | "INVALID_SIGNATURE";
1971
+ declare class CloudAuthorizationVerificationError extends Error {
1972
+ readonly code: CloudAuthorizationVerificationErrorCode;
1973
+ constructor(code: CloudAuthorizationVerificationErrorCode, message: string);
1974
+ }
1975
+ declare function canonicalCloudJson(value: unknown): string;
1976
+ declare function parseCloudHostHeartbeat(value: unknown): CloudHostHeartbeatV1;
1977
+ declare function parseCloudAuthorizationSnapshot(value: unknown): CloudAuthorizationSnapshot;
1978
+ declare function parseSignedCloudAuthorizationSnapshot(value: unknown): SignedCloudAuthorizationSnapshot;
1979
+ /**
1980
+ * Exact, domain-separated bytes that the cloud control plane signs and the host verifies.
1981
+ *
1982
+ * V1 signs the raw protected envelope for self-host compatibility. V2 signs exactly the SHA-256 digest of the
1983
+ * protected envelope so hardware signers never receive attacker-amplifiable snapshot bytes.
1984
+ */
1985
+ declare function cloudAuthorizationSnapshotSigningPayload(snapshot: unknown, keyId: string): Buffer;
1986
+ /** Verifies one envelope against any active key id, allowing safe overlap during signing-key rotation. */
1987
+ declare function verifySignedCloudAuthorizationSnapshot(value: unknown, trustedKeys: readonly CloudAuthorizationTrustedKey[], verificationTime?: number): SignedCloudAuthorizationSnapshot;
1988
+
1989
+ declare const CLOUD_AUTHORIZATION_FILE = "cloud-authorization.json";
1990
+ declare const CLOUD_AUTHORIZATION_LAST_GOOD_FILE = "cloud-authorization.last-good.json";
1991
+ declare const CLOUD_AUTHORIZATION_CLOCK_SKEW_MS: number;
1992
+ type CloudAuthorizationSnapshotStatus = "unavailable" | "pending" | "active" | "expired";
1993
+ type CloudAuthorizationPrincipalType = "device" | "relay";
1994
+ type CloudAuthorizationStoreErrorCode = "TARGET_MISMATCH" | "CONTRACT_MISMATCH" | "REPLAY" | "TEMPORAL_REGRESSION" | "ISSUED_IN_FUTURE" | "ISSUED_TOO_OLD" | "NOT_YET_VALID" | "EXPIRED" | "PERSISTENCE_CORRUPT" | "PERSISTENCE_UNSAFE" | "REVISION_CONFLICT";
1995
+ declare class CloudAuthorizationStoreError extends Error {
1996
+ readonly code: CloudAuthorizationStoreErrorCode;
1997
+ constructor(code: CloudAuthorizationStoreErrorCode, message: string);
1998
+ }
1999
+ interface StoredCloudAuthorizationSnapshot {
2000
+ acceptedAt: number;
2001
+ envelope: SignedCloudAuthorizationSnapshot;
2002
+ snapshot: CloudAuthorizationSnapshot;
2003
+ }
2004
+ interface CloudAuthorizationState {
2005
+ status: CloudAuthorizationSnapshotStatus;
2006
+ revision?: number;
2007
+ notBefore?: number;
2008
+ expiresAt?: number;
2009
+ }
2010
+ interface CloudAuthorizationDecision {
2011
+ allowed: boolean;
2012
+ reason: "cloud-grant" | "cloud-authorization-unavailable" | "cloud-authorization-pending" | "cloud-authorization-expired" | "cloud-principal-unbound" | "cloud-missing-permission" | "cloud-host-mismatch";
2013
+ revision?: number;
2014
+ }
2015
+ interface OpenCloudAuthorizationStoreOptions {
2016
+ dataDir: string;
2017
+ organizationId: string;
2018
+ hostId: string;
2019
+ trustedKeys: readonly CloudAuthorizationTrustedKey[] | (() => readonly CloudAuthorizationTrustedKey[]);
2020
+ /** Provisioned authorization contract. An envelope from another version is never accepted as a downgrade. */
2021
+ authorizationVersion?: 1 | 2;
2022
+ now?: () => number;
2023
+ clockSkewMs?: number;
2024
+ }
2025
+ interface CloudAuthorizationStore {
2026
+ readonly path: string;
2027
+ readonly backupPath: string;
2028
+ getLastKnownGood(): StoredCloudAuthorizationSnapshot | undefined;
2029
+ getState(now?: number): CloudAuthorizationState;
2030
+ getActiveSnapshot(now?: number): CloudAuthorizationSnapshot | undefined;
2031
+ apply(value: unknown, now?: number): StoredCloudAuthorizationSnapshot;
2032
+ reload(): StoredCloudAuthorizationSnapshot | undefined;
2033
+ authorize(actorType: CloudAuthorizationPrincipalType, actorId: string, permission: CloudAuthorizationPermission, resource?: TeamAuthorizationResource, now?: number): CloudAuthorizationDecision;
2034
+ }
2035
+ declare function openCloudAuthorizationStore(options: OpenCloudAuthorizationStoreOptions): CloudAuthorizationStore;
2036
+
2037
+ declare const DEFAULT_CLOUD_CONTROL_PLANE_URL = "https://roamcode.ai";
2038
+ declare const CLOUD_DEVICE_ENROLLMENT_CONFIRM_PATH = "/api/v1/hosts/device-enrollments/confirm";
2039
+ declare const CLOUD_DEVICE_ENROLLMENT_COMPLETE_PATH = "/api/v1/hosts/device-enrollments/complete";
2040
+ declare const CLOUD_DEVICE_ENROLLMENT_HOST_ROUTE = "/api/v1/cloud/device-enrollments/confirm";
2041
+ declare const CloudDeviceEnrollmentRequestSchema: z.ZodObject<{
2042
+ v: z.ZodLiteral<1>;
2043
+ enrollmentId: z.ZodUUID;
2044
+ challenge: z.ZodString;
2045
+ }, z.core.$strict>;
2046
+ declare const CloudHostDeviceEnrollmentConfirmationSchema: z.ZodObject<{
2047
+ v: z.ZodLiteral<1>;
2048
+ kind: z.ZodLiteral<"host-device-enrollment-confirmation">;
2049
+ enrollmentId: z.ZodUUID;
2050
+ challenge: z.ZodString;
2051
+ actorId: z.ZodString;
2052
+ deviceIdentityPublicKey: z.ZodOptional<z.ZodString>;
2053
+ }, z.core.$strict>;
2054
+ declare const CloudHostDeviceEnrollmentCompletionSchema: z.ZodObject<{
2055
+ v: z.ZodLiteral<1>;
2056
+ kind: z.ZodLiteral<"host-device-enrollment-completion">;
2057
+ enrollmentId: z.ZodUUID;
2058
+ actorId: z.ZodString;
2059
+ temporaryRelayCredentialHash: z.ZodString;
2060
+ durableRelayCredentialHash: z.ZodString;
2061
+ }, z.core.$strict>;
2062
+ declare const CloudRelayDeviceEnrollmentPayloadSchema: z.ZodObject<{
2063
+ v: z.ZodLiteral<1>;
2064
+ kind: z.ZodLiteral<"cloud-device-enrollment">;
2065
+ enrollmentId: z.ZodUUID;
2066
+ challenge: z.ZodString;
2067
+ name: z.ZodString;
2068
+ localDeviceToken: z.ZodString;
2069
+ durableRelayCredential: z.ZodString;
2070
+ }, z.core.$strict>;
2071
+ declare const CloudRelayDeviceEnrollmentAuthSchema: z.ZodObject<{
2072
+ token: z.ZodString;
2073
+ relayCredential: z.ZodString;
2074
+ cloudEnrollment: z.ZodObject<{
2075
+ v: z.ZodLiteral<1>;
2076
+ kind: z.ZodLiteral<"cloud-device-enrollment">;
2077
+ enrollmentId: z.ZodUUID;
2078
+ challenge: z.ZodString;
2079
+ name: z.ZodString;
2080
+ localDeviceToken: z.ZodString;
2081
+ durableRelayCredential: z.ZodString;
2082
+ }, z.core.$strict>;
2083
+ }, z.core.$strict>;
2084
+ declare const CloudHostDeviceEnrollmentCompletionResponseSchema: z.ZodObject<{
2085
+ v: z.ZodLiteral<1>;
2086
+ state: z.ZodEnum<{
2087
+ revoked: "revoked";
2088
+ active: "active";
2089
+ }>;
2090
+ deviceId: z.ZodUUID;
2091
+ }, z.core.$strict>;
2092
+ type CloudDeviceEnrollmentRequest = z.infer<typeof CloudDeviceEnrollmentRequestSchema>;
2093
+ type CloudHostDeviceEnrollmentConfirmation = z.infer<typeof CloudHostDeviceEnrollmentConfirmationSchema>;
2094
+ type CloudHostDeviceEnrollmentCompletion = z.infer<typeof CloudHostDeviceEnrollmentCompletionSchema>;
2095
+ type CloudHostDeviceEnrollmentCompletionResult = z.infer<typeof CloudHostDeviceEnrollmentCompletionResponseSchema>;
2096
+ type CloudRelayDeviceEnrollmentPayload = z.infer<typeof CloudRelayDeviceEnrollmentPayloadSchema>;
2097
+ type CloudRelayDeviceEnrollmentAuth = z.infer<typeof CloudRelayDeviceEnrollmentAuthSchema>;
2098
+ interface CloudDeviceEnrollmentConfirmationResult {
2099
+ actorId: string;
2100
+ deviceId: string;
2101
+ temporaryRelayCredentialHash?: string;
2102
+ deviceIdentity?: {
2103
+ publicKey: string;
2104
+ fingerprint: string;
2105
+ };
2106
+ }
2107
+ interface CloudRelayDeviceEnrollmentSaga {
2108
+ enroll(input: {
2109
+ actorId: string;
2110
+ deviceIdentityPublicKey: string;
2111
+ cloudEnrollment: unknown;
2112
+ }): Promise<{
2113
+ device: DeviceInfo;
2114
+ token: string;
2115
+ }>;
2116
+ recover(): Promise<{
2117
+ completed: number;
2118
+ failed: number;
2119
+ }>;
2120
+ }
2121
+ interface CloudDeviceEnrollmentConfirmer {
2122
+ confirm(input: CloudHostDeviceEnrollmentConfirmation): Promise<CloudDeviceEnrollmentConfirmationResult>;
2123
+ complete(input: CloudHostDeviceEnrollmentCompletion): Promise<CloudHostDeviceEnrollmentCompletionResult>;
2124
+ }
2125
+ interface CloudDeviceEnrollmentRuntimeConfig {
2126
+ controlPlaneOrigin: string;
2127
+ hostCredential: string;
2128
+ }
2129
+ type CloudDeviceEnrollmentErrorCode = "REJECTED" | "UNAVAILABLE" | "INVALID_RESPONSE";
2130
+ declare class CloudDeviceEnrollmentError extends Error {
2131
+ readonly code: CloudDeviceEnrollmentErrorCode;
2132
+ readonly retryable: boolean;
2133
+ constructor(code: CloudDeviceEnrollmentErrorCode, retryable: boolean);
2134
+ }
2135
+ interface CreateCloudDeviceEnrollmentConfirmerOptions extends CloudDeviceEnrollmentRuntimeConfig {
2136
+ fetch?: typeof globalThis.fetch;
2137
+ timeoutMs?: number;
2138
+ }
2139
+ /** Normalize an origin once so a client payload can never choose where the host credential is sent. */
2140
+ declare function normalizeCloudControlPlaneOrigin(value: string): string;
2141
+ /** Read a host capability without following links or accepting permissions that expose it to other users. */
2142
+ declare function readCloudHostCredentialFile(path: string): string;
2143
+ /** URL-only configuration is harmless; cloud host enrollment is enabled only when its credential file is set. */
2144
+ declare function resolveCloudDeviceEnrollmentConfig(env: NodeJS.ProcessEnv): CloudDeviceEnrollmentRuntimeConfig | undefined;
2145
+ declare function createCloudDeviceEnrollmentConfirmer(options: CreateCloudDeviceEnrollmentConfirmerOptions): CloudDeviceEnrollmentConfirmer;
2146
+ interface CreateCloudRelayDeviceEnrollmentSagaOptions {
2147
+ devices: DeviceStore;
2148
+ confirmer: CloudDeviceEnrollmentConfirmer;
2149
+ provisioner: RelayDeviceProvisioner;
2150
+ refreshAuthorization?: () => Promise<unknown>;
2151
+ /** Managed Nodes must observe the newly confirmed relay actor in a fresh signed snapshot before activation. */
2152
+ authorizationReady?: (actorId: string) => boolean;
2153
+ now?: () => number;
2154
+ }
2155
+ /** The control plane has one canonical identity namespace for both direct and relay-connected browsers. */
2156
+ declare function cloudDeviceEnrollmentAuthorizationReady(authorizationStore: Pick<CloudAuthorizationStore, "getActiveSnapshot">, actorId: string): boolean;
2157
+ /**
2158
+ * Commits a browser enrollment in three durable phases. The control plane sees only the signed device public key;
2159
+ * local and relay bearer credentials stay inside the encrypted browser-to-Node channel and are persisted as hashes.
2160
+ */
2161
+ declare function createCloudRelayDeviceEnrollmentSaga(options: CreateCloudRelayDeviceEnrollmentSagaOptions): CloudRelayDeviceEnrollmentSaga;
2162
+ interface CloudDeviceEnrollmentRecoveryLoop {
2163
+ start(): void;
2164
+ stop(): Promise<void>;
2165
+ }
2166
+ interface CreateCloudDeviceEnrollmentRecoveryLoopOptions {
2167
+ saga: Pick<CloudRelayDeviceEnrollmentSaga, "recover">;
2168
+ intervalMs?: number;
2169
+ onResult?: (result: {
2170
+ completed: number;
2171
+ failed: number;
2172
+ }) => void;
2173
+ }
2174
+ /**
2175
+ * Starts one recovery attempt immediately and retries on a fixed cadence without ever overlapping attempts.
2176
+ * The saga itself caps each pass and every network client it calls has a request timeout.
2177
+ */
2178
+ declare function createCloudDeviceEnrollmentRecoveryLoop(options: CreateCloudDeviceEnrollmentRecoveryLoopOptions): CloudDeviceEnrollmentRecoveryLoop;
2179
+
1415
2180
  type RelayHostStatus = "idle" | "connecting" | "online" | "reconnecting" | "stopped";
1416
2181
  interface RelayHostMetrics {
1417
2182
  status: RelayHostStatus;
@@ -1445,6 +2210,8 @@ interface RelayHostConnectorOptions {
1445
2210
  onStatus?: (status: RelayHostStatus) => void;
1446
2211
  /** Promotes a five-minute broker bootstrap credential after the E2E pairing claim commits. */
1447
2212
  promoteDevice?: (deviceId: string, credentialHash: string) => Promise<void>;
2213
+ /** Account-driven browser enrollment over the already encrypted relay auth channel. */
2214
+ cloudDeviceEnrollment?: CloudRelayDeviceEnrollmentSaga;
1448
2215
  }
1449
2216
  interface RelayTerminalOpenRequest {
1450
2217
  streamId: string;
@@ -1519,6 +2286,681 @@ declare function writeRelayHostConfig(dataDir: string, input: RelayHostConfigInp
1519
2286
  declare function removeRelayHostConfig(dataDir: string): boolean;
1520
2287
  declare function resolveRelayHostConfig(env: NodeJS.ProcessEnv, dataDir: string): RelayHostRuntimeConfig | undefined;
1521
2288
 
2289
+ declare const CLOUD_AUTHORIZATION_KEYSET_SIGNATURE_DOMAIN = "roamcode-cloud-authorization-keyset-v1";
2290
+ declare const CLOUD_AUTHORIZATION_KEYSET_SIGNATURE_DOMAIN_V2 = "roamcode-cloud-authorization-keyset-v2";
2291
+ declare const CLOUD_AUTHORIZATION_KEYSET_PATH = "/api/v1/meta/authorization-keyset";
2292
+ declare const CLOUD_KEYSET_CLOCK_SKEW_MS: number;
2293
+ declare const CloudAuthorizationKeysetKeyV1Schema: z.ZodObject<{
2294
+ keyId: z.ZodString;
2295
+ algorithm: z.ZodLiteral<"Ed25519">;
2296
+ publicKey: z.ZodString;
2297
+ notBefore: z.ZodNumber;
2298
+ notAfter: z.ZodNullable<z.ZodNumber>;
2299
+ status: z.ZodEnum<{
2300
+ current: "current";
2301
+ previous: "previous";
2302
+ }>;
2303
+ }, z.core.$strict>;
2304
+ declare const CloudAuthorizationKeysetKeyV2Schema: z.ZodObject<{
2305
+ keyId: z.ZodString;
2306
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
2307
+ publicKey: z.ZodString;
2308
+ notBefore: z.ZodNumber;
2309
+ notAfter: z.ZodNullable<z.ZodNumber>;
2310
+ status: z.ZodEnum<{
2311
+ current: "current";
2312
+ previous: "previous";
2313
+ }>;
2314
+ }, z.core.$strict>;
2315
+ declare const CloudAuthorizationKeysetV1Schema: z.ZodObject<{
2316
+ v: z.ZodLiteral<1>;
2317
+ kind: z.ZodLiteral<"authorization-keyset">;
2318
+ issuedAt: z.ZodNumber;
2319
+ expiresAt: z.ZodNumber;
2320
+ keys: z.ZodArray<z.ZodObject<{
2321
+ keyId: z.ZodString;
2322
+ algorithm: z.ZodLiteral<"Ed25519">;
2323
+ publicKey: z.ZodString;
2324
+ notBefore: z.ZodNumber;
2325
+ notAfter: z.ZodNullable<z.ZodNumber>;
2326
+ status: z.ZodEnum<{
2327
+ current: "current";
2328
+ previous: "previous";
2329
+ }>;
2330
+ }, z.core.$strict>>;
2331
+ }, z.core.$strict>;
2332
+ declare const CloudAuthorizationKeysetV2Schema: z.ZodObject<{
2333
+ v: z.ZodLiteral<2>;
2334
+ kind: z.ZodLiteral<"authorization-keyset">;
2335
+ issuedAt: z.ZodNumber;
2336
+ expiresAt: z.ZodNumber;
2337
+ keys: z.ZodArray<z.ZodObject<{
2338
+ keyId: z.ZodString;
2339
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
2340
+ publicKey: z.ZodString;
2341
+ notBefore: z.ZodNumber;
2342
+ notAfter: z.ZodNullable<z.ZodNumber>;
2343
+ status: z.ZodEnum<{
2344
+ current: "current";
2345
+ previous: "previous";
2346
+ }>;
2347
+ }, z.core.$strict>>;
2348
+ }, z.core.$strict>;
2349
+ declare const CloudAuthorizationKeysetSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
2350
+ v: z.ZodLiteral<1>;
2351
+ kind: z.ZodLiteral<"authorization-keyset">;
2352
+ issuedAt: z.ZodNumber;
2353
+ expiresAt: z.ZodNumber;
2354
+ keys: z.ZodArray<z.ZodObject<{
2355
+ keyId: z.ZodString;
2356
+ algorithm: z.ZodLiteral<"Ed25519">;
2357
+ publicKey: z.ZodString;
2358
+ notBefore: z.ZodNumber;
2359
+ notAfter: z.ZodNullable<z.ZodNumber>;
2360
+ status: z.ZodEnum<{
2361
+ current: "current";
2362
+ previous: "previous";
2363
+ }>;
2364
+ }, z.core.$strict>>;
2365
+ }, z.core.$strict>, z.ZodObject<{
2366
+ v: z.ZodLiteral<2>;
2367
+ kind: z.ZodLiteral<"authorization-keyset">;
2368
+ issuedAt: z.ZodNumber;
2369
+ expiresAt: z.ZodNumber;
2370
+ keys: z.ZodArray<z.ZodObject<{
2371
+ keyId: z.ZodString;
2372
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
2373
+ publicKey: z.ZodString;
2374
+ notBefore: z.ZodNumber;
2375
+ notAfter: z.ZodNullable<z.ZodNumber>;
2376
+ status: z.ZodEnum<{
2377
+ current: "current";
2378
+ previous: "previous";
2379
+ }>;
2380
+ }, z.core.$strict>>;
2381
+ }, z.core.$strict>], "v">;
2382
+ declare const SignedCloudAuthorizationKeysetSignatureV1Schema: z.ZodObject<{
2383
+ keyId: z.ZodString;
2384
+ algorithm: z.ZodLiteral<"Ed25519">;
2385
+ signature: z.ZodString;
2386
+ }, z.core.$strict>;
2387
+ declare const SignedCloudAuthorizationKeysetSignatureV2Schema: z.ZodObject<{
2388
+ keyId: z.ZodString;
2389
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
2390
+ signature: z.ZodString;
2391
+ }, z.core.$strict>;
2392
+ declare const SignedCloudAuthorizationKeysetV1Schema: z.ZodObject<{
2393
+ v: z.ZodLiteral<1>;
2394
+ kind: z.ZodLiteral<"signed-authorization-keyset">;
2395
+ keyset: z.ZodObject<{
2396
+ v: z.ZodLiteral<1>;
2397
+ kind: z.ZodLiteral<"authorization-keyset">;
2398
+ issuedAt: z.ZodNumber;
2399
+ expiresAt: z.ZodNumber;
2400
+ keys: z.ZodArray<z.ZodObject<{
2401
+ keyId: z.ZodString;
2402
+ algorithm: z.ZodLiteral<"Ed25519">;
2403
+ publicKey: z.ZodString;
2404
+ notBefore: z.ZodNumber;
2405
+ notAfter: z.ZodNullable<z.ZodNumber>;
2406
+ status: z.ZodEnum<{
2407
+ current: "current";
2408
+ previous: "previous";
2409
+ }>;
2410
+ }, z.core.$strict>>;
2411
+ }, z.core.$strict>;
2412
+ signatures: z.ZodArray<z.ZodObject<{
2413
+ keyId: z.ZodString;
2414
+ algorithm: z.ZodLiteral<"Ed25519">;
2415
+ signature: z.ZodString;
2416
+ }, z.core.$strict>>;
2417
+ }, z.core.$strict>;
2418
+ declare const SignedCloudAuthorizationKeysetV2Schema: z.ZodObject<{
2419
+ v: z.ZodLiteral<2>;
2420
+ kind: z.ZodLiteral<"signed-authorization-keyset">;
2421
+ keyset: z.ZodObject<{
2422
+ v: z.ZodLiteral<2>;
2423
+ kind: z.ZodLiteral<"authorization-keyset">;
2424
+ issuedAt: z.ZodNumber;
2425
+ expiresAt: z.ZodNumber;
2426
+ keys: z.ZodArray<z.ZodObject<{
2427
+ keyId: z.ZodString;
2428
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
2429
+ publicKey: z.ZodString;
2430
+ notBefore: z.ZodNumber;
2431
+ notAfter: z.ZodNullable<z.ZodNumber>;
2432
+ status: z.ZodEnum<{
2433
+ current: "current";
2434
+ previous: "previous";
2435
+ }>;
2436
+ }, z.core.$strict>>;
2437
+ }, z.core.$strict>;
2438
+ signatures: z.ZodArray<z.ZodObject<{
2439
+ keyId: z.ZodString;
2440
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
2441
+ signature: z.ZodString;
2442
+ }, z.core.$strict>>;
2443
+ }, z.core.$strict>;
2444
+ declare const SignedCloudAuthorizationKeysetSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
2445
+ v: z.ZodLiteral<1>;
2446
+ kind: z.ZodLiteral<"signed-authorization-keyset">;
2447
+ keyset: z.ZodObject<{
2448
+ v: z.ZodLiteral<1>;
2449
+ kind: z.ZodLiteral<"authorization-keyset">;
2450
+ issuedAt: z.ZodNumber;
2451
+ expiresAt: z.ZodNumber;
2452
+ keys: z.ZodArray<z.ZodObject<{
2453
+ keyId: z.ZodString;
2454
+ algorithm: z.ZodLiteral<"Ed25519">;
2455
+ publicKey: z.ZodString;
2456
+ notBefore: z.ZodNumber;
2457
+ notAfter: z.ZodNullable<z.ZodNumber>;
2458
+ status: z.ZodEnum<{
2459
+ current: "current";
2460
+ previous: "previous";
2461
+ }>;
2462
+ }, z.core.$strict>>;
2463
+ }, z.core.$strict>;
2464
+ signatures: z.ZodArray<z.ZodObject<{
2465
+ keyId: z.ZodString;
2466
+ algorithm: z.ZodLiteral<"Ed25519">;
2467
+ signature: z.ZodString;
2468
+ }, z.core.$strict>>;
2469
+ }, z.core.$strict>, z.ZodObject<{
2470
+ v: z.ZodLiteral<2>;
2471
+ kind: z.ZodLiteral<"signed-authorization-keyset">;
2472
+ keyset: z.ZodObject<{
2473
+ v: z.ZodLiteral<2>;
2474
+ kind: z.ZodLiteral<"authorization-keyset">;
2475
+ issuedAt: z.ZodNumber;
2476
+ expiresAt: z.ZodNumber;
2477
+ keys: z.ZodArray<z.ZodObject<{
2478
+ keyId: z.ZodString;
2479
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
2480
+ publicKey: z.ZodString;
2481
+ notBefore: z.ZodNumber;
2482
+ notAfter: z.ZodNullable<z.ZodNumber>;
2483
+ status: z.ZodEnum<{
2484
+ current: "current";
2485
+ previous: "previous";
2486
+ }>;
2487
+ }, z.core.$strict>>;
2488
+ }, z.core.$strict>;
2489
+ signatures: z.ZodArray<z.ZodObject<{
2490
+ keyId: z.ZodString;
2491
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
2492
+ signature: z.ZodString;
2493
+ }, z.core.$strict>>;
2494
+ }, z.core.$strict>], "v">;
2495
+ type CloudAuthorizationKeysetKeyV1 = z.infer<typeof CloudAuthorizationKeysetKeyV1Schema>;
2496
+ type CloudAuthorizationKeysetKeyV2 = z.infer<typeof CloudAuthorizationKeysetKeyV2Schema>;
2497
+ type CloudAuthorizationKeysetKey = CloudAuthorizationKeysetKeyV1 | CloudAuthorizationKeysetKeyV2;
2498
+ type CloudAuthorizationKeysetV1 = z.infer<typeof CloudAuthorizationKeysetV1Schema>;
2499
+ type CloudAuthorizationKeysetV2 = z.infer<typeof CloudAuthorizationKeysetV2Schema>;
2500
+ type CloudAuthorizationKeyset = z.infer<typeof CloudAuthorizationKeysetSchema>;
2501
+ type SignedCloudAuthorizationKeysetV1 = z.infer<typeof SignedCloudAuthorizationKeysetV1Schema>;
2502
+ type SignedCloudAuthorizationKeysetV2 = z.infer<typeof SignedCloudAuthorizationKeysetV2Schema>;
2503
+ type SignedCloudAuthorizationKeyset = z.infer<typeof SignedCloudAuthorizationKeysetSchema>;
2504
+ type CloudKeysetVerificationErrorCode = "INVALID_KEYSET" | "INVALID_PINNED_KEY" | "ISSUED_IN_FUTURE" | "EXPIRED" | "PIN_EXPIRED" | "UNTRUSTED_ROTATION" | "KEYSET_ROLLBACK";
2505
+ declare class CloudKeysetVerificationError extends Error {
2506
+ readonly code: CloudKeysetVerificationErrorCode;
2507
+ constructor(code: CloudKeysetVerificationErrorCode);
2508
+ }
2509
+ declare function parseCloudAuthorizationKeyset(value: unknown): CloudAuthorizationKeyset;
2510
+ declare function cloudAuthorizationKeysetSigningPayload(keyset: unknown): Buffer;
2511
+ declare function cloudAuthorizationTrustedKeysFromKeyset(value: unknown): readonly CloudAuthorizationTrustedKey[];
2512
+ declare function verifySignedCloudAuthorizationKeyset(value: unknown, pinnedKeysetValue: unknown, now?: number, clockSkewMs?: number): SignedCloudAuthorizationKeyset;
2513
+
2514
+ declare const CLOUD_HOST_CONFIG_FILE = "cloud-host.json";
2515
+ declare const CloudHostConfigV1Schema: z.ZodPipe<z.ZodObject<{
2516
+ v: z.ZodLiteral<1>;
2517
+ kind: z.ZodLiteral<"roamcode-cloud-host-config">;
2518
+ organizationId: z.ZodUUID;
2519
+ hostId: z.ZodUUID;
2520
+ controlPlaneOrigin: z.ZodString;
2521
+ hostCredential: z.ZodString;
2522
+ authorization: z.ZodObject<{
2523
+ algorithm: z.ZodLiteral<"Ed25519">;
2524
+ signatureDomain: z.ZodLiteral<"roamcode-cloud-authorization-snapshot-v1">;
2525
+ keysetSignatureDomain: z.ZodLiteral<"roamcode-cloud-authorization-keyset-v1">;
2526
+ keyset: z.ZodObject<{
2527
+ v: z.ZodLiteral<1>;
2528
+ kind: z.ZodLiteral<"authorization-keyset">;
2529
+ issuedAt: z.ZodNumber;
2530
+ expiresAt: z.ZodNumber;
2531
+ keys: z.ZodArray<z.ZodObject<{
2532
+ keyId: z.ZodString;
2533
+ algorithm: z.ZodLiteral<"Ed25519">;
2534
+ publicKey: z.ZodString;
2535
+ notBefore: z.ZodNumber;
2536
+ notAfter: z.ZodNullable<z.ZodNumber>;
2537
+ status: z.ZodEnum<{
2538
+ current: "current";
2539
+ previous: "previous";
2540
+ }>;
2541
+ }, z.core.$strict>>;
2542
+ }, z.core.$strict>;
2543
+ }, z.core.$strict>;
2544
+ heartbeatIntervalSeconds: z.ZodNumber;
2545
+ authorizationRefreshIntervalSeconds: z.ZodNumber;
2546
+ }, z.core.$strict>, z.ZodTransform<{
2547
+ controlPlaneOrigin: string;
2548
+ v: 1;
2549
+ kind: "roamcode-cloud-host-config";
2550
+ organizationId: string;
2551
+ hostId: string;
2552
+ hostCredential: string;
2553
+ authorization: {
2554
+ algorithm: "Ed25519";
2555
+ signatureDomain: "roamcode-cloud-authorization-snapshot-v1";
2556
+ keysetSignatureDomain: "roamcode-cloud-authorization-keyset-v1";
2557
+ keyset: {
2558
+ v: 1;
2559
+ kind: "authorization-keyset";
2560
+ issuedAt: number;
2561
+ expiresAt: number;
2562
+ keys: {
2563
+ keyId: string;
2564
+ algorithm: "Ed25519";
2565
+ publicKey: string;
2566
+ notBefore: number;
2567
+ notAfter: number | null;
2568
+ status: "current" | "previous";
2569
+ }[];
2570
+ };
2571
+ };
2572
+ heartbeatIntervalSeconds: number;
2573
+ authorizationRefreshIntervalSeconds: number;
2574
+ }, {
2575
+ v: 1;
2576
+ kind: "roamcode-cloud-host-config";
2577
+ organizationId: string;
2578
+ hostId: string;
2579
+ controlPlaneOrigin: string;
2580
+ hostCredential: string;
2581
+ authorization: {
2582
+ algorithm: "Ed25519";
2583
+ signatureDomain: "roamcode-cloud-authorization-snapshot-v1";
2584
+ keysetSignatureDomain: "roamcode-cloud-authorization-keyset-v1";
2585
+ keyset: {
2586
+ v: 1;
2587
+ kind: "authorization-keyset";
2588
+ issuedAt: number;
2589
+ expiresAt: number;
2590
+ keys: {
2591
+ keyId: string;
2592
+ algorithm: "Ed25519";
2593
+ publicKey: string;
2594
+ notBefore: number;
2595
+ notAfter: number | null;
2596
+ status: "current" | "previous";
2597
+ }[];
2598
+ };
2599
+ };
2600
+ heartbeatIntervalSeconds: number;
2601
+ authorizationRefreshIntervalSeconds: number;
2602
+ }>>;
2603
+ declare const CloudHostConfigV2Schema: z.ZodPipe<z.ZodObject<{
2604
+ v: z.ZodLiteral<2>;
2605
+ kind: z.ZodLiteral<"roamcode-cloud-host-config">;
2606
+ organizationId: z.ZodUUID;
2607
+ hostId: z.ZodUUID;
2608
+ controlPlaneOrigin: z.ZodString;
2609
+ hostCredential: z.ZodString;
2610
+ authorization: z.ZodObject<{
2611
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
2612
+ signatureDomain: z.ZodLiteral<"roamcode-cloud-authorization-snapshot-v2">;
2613
+ keysetSignatureDomain: z.ZodLiteral<"roamcode-cloud-authorization-keyset-v2">;
2614
+ keyset: z.ZodObject<{
2615
+ v: z.ZodLiteral<2>;
2616
+ kind: z.ZodLiteral<"authorization-keyset">;
2617
+ issuedAt: z.ZodNumber;
2618
+ expiresAt: z.ZodNumber;
2619
+ keys: z.ZodArray<z.ZodObject<{
2620
+ keyId: z.ZodString;
2621
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
2622
+ publicKey: z.ZodString;
2623
+ notBefore: z.ZodNumber;
2624
+ notAfter: z.ZodNullable<z.ZodNumber>;
2625
+ status: z.ZodEnum<{
2626
+ current: "current";
2627
+ previous: "previous";
2628
+ }>;
2629
+ }, z.core.$strict>>;
2630
+ }, z.core.$strict>;
2631
+ }, z.core.$strict>;
2632
+ heartbeatIntervalSeconds: z.ZodNumber;
2633
+ authorizationRefreshIntervalSeconds: z.ZodNumber;
2634
+ }, z.core.$strict>, z.ZodTransform<{
2635
+ controlPlaneOrigin: string;
2636
+ v: 2;
2637
+ kind: "roamcode-cloud-host-config";
2638
+ organizationId: string;
2639
+ hostId: string;
2640
+ hostCredential: string;
2641
+ authorization: {
2642
+ algorithm: "Ed25519-SHA256";
2643
+ signatureDomain: "roamcode-cloud-authorization-snapshot-v2";
2644
+ keysetSignatureDomain: "roamcode-cloud-authorization-keyset-v2";
2645
+ keyset: {
2646
+ v: 2;
2647
+ kind: "authorization-keyset";
2648
+ issuedAt: number;
2649
+ expiresAt: number;
2650
+ keys: {
2651
+ keyId: string;
2652
+ algorithm: "Ed25519-SHA256";
2653
+ publicKey: string;
2654
+ notBefore: number;
2655
+ notAfter: number | null;
2656
+ status: "current" | "previous";
2657
+ }[];
2658
+ };
2659
+ };
2660
+ heartbeatIntervalSeconds: number;
2661
+ authorizationRefreshIntervalSeconds: number;
2662
+ }, {
2663
+ v: 2;
2664
+ kind: "roamcode-cloud-host-config";
2665
+ organizationId: string;
2666
+ hostId: string;
2667
+ controlPlaneOrigin: string;
2668
+ hostCredential: string;
2669
+ authorization: {
2670
+ algorithm: "Ed25519-SHA256";
2671
+ signatureDomain: "roamcode-cloud-authorization-snapshot-v2";
2672
+ keysetSignatureDomain: "roamcode-cloud-authorization-keyset-v2";
2673
+ keyset: {
2674
+ v: 2;
2675
+ kind: "authorization-keyset";
2676
+ issuedAt: number;
2677
+ expiresAt: number;
2678
+ keys: {
2679
+ keyId: string;
2680
+ algorithm: "Ed25519-SHA256";
2681
+ publicKey: string;
2682
+ notBefore: number;
2683
+ notAfter: number | null;
2684
+ status: "current" | "previous";
2685
+ }[];
2686
+ };
2687
+ };
2688
+ heartbeatIntervalSeconds: number;
2689
+ authorizationRefreshIntervalSeconds: number;
2690
+ }>>;
2691
+ declare const CloudHostConfigSchema: z.ZodUnion<readonly [z.ZodPipe<z.ZodObject<{
2692
+ v: z.ZodLiteral<1>;
2693
+ kind: z.ZodLiteral<"roamcode-cloud-host-config">;
2694
+ organizationId: z.ZodUUID;
2695
+ hostId: z.ZodUUID;
2696
+ controlPlaneOrigin: z.ZodString;
2697
+ hostCredential: z.ZodString;
2698
+ authorization: z.ZodObject<{
2699
+ algorithm: z.ZodLiteral<"Ed25519">;
2700
+ signatureDomain: z.ZodLiteral<"roamcode-cloud-authorization-snapshot-v1">;
2701
+ keysetSignatureDomain: z.ZodLiteral<"roamcode-cloud-authorization-keyset-v1">;
2702
+ keyset: z.ZodObject<{
2703
+ v: z.ZodLiteral<1>;
2704
+ kind: z.ZodLiteral<"authorization-keyset">;
2705
+ issuedAt: z.ZodNumber;
2706
+ expiresAt: z.ZodNumber;
2707
+ keys: z.ZodArray<z.ZodObject<{
2708
+ keyId: z.ZodString;
2709
+ algorithm: z.ZodLiteral<"Ed25519">;
2710
+ publicKey: z.ZodString;
2711
+ notBefore: z.ZodNumber;
2712
+ notAfter: z.ZodNullable<z.ZodNumber>;
2713
+ status: z.ZodEnum<{
2714
+ current: "current";
2715
+ previous: "previous";
2716
+ }>;
2717
+ }, z.core.$strict>>;
2718
+ }, z.core.$strict>;
2719
+ }, z.core.$strict>;
2720
+ heartbeatIntervalSeconds: z.ZodNumber;
2721
+ authorizationRefreshIntervalSeconds: z.ZodNumber;
2722
+ }, z.core.$strict>, z.ZodTransform<{
2723
+ controlPlaneOrigin: string;
2724
+ v: 1;
2725
+ kind: "roamcode-cloud-host-config";
2726
+ organizationId: string;
2727
+ hostId: string;
2728
+ hostCredential: string;
2729
+ authorization: {
2730
+ algorithm: "Ed25519";
2731
+ signatureDomain: "roamcode-cloud-authorization-snapshot-v1";
2732
+ keysetSignatureDomain: "roamcode-cloud-authorization-keyset-v1";
2733
+ keyset: {
2734
+ v: 1;
2735
+ kind: "authorization-keyset";
2736
+ issuedAt: number;
2737
+ expiresAt: number;
2738
+ keys: {
2739
+ keyId: string;
2740
+ algorithm: "Ed25519";
2741
+ publicKey: string;
2742
+ notBefore: number;
2743
+ notAfter: number | null;
2744
+ status: "current" | "previous";
2745
+ }[];
2746
+ };
2747
+ };
2748
+ heartbeatIntervalSeconds: number;
2749
+ authorizationRefreshIntervalSeconds: number;
2750
+ }, {
2751
+ v: 1;
2752
+ kind: "roamcode-cloud-host-config";
2753
+ organizationId: string;
2754
+ hostId: string;
2755
+ controlPlaneOrigin: string;
2756
+ hostCredential: string;
2757
+ authorization: {
2758
+ algorithm: "Ed25519";
2759
+ signatureDomain: "roamcode-cloud-authorization-snapshot-v1";
2760
+ keysetSignatureDomain: "roamcode-cloud-authorization-keyset-v1";
2761
+ keyset: {
2762
+ v: 1;
2763
+ kind: "authorization-keyset";
2764
+ issuedAt: number;
2765
+ expiresAt: number;
2766
+ keys: {
2767
+ keyId: string;
2768
+ algorithm: "Ed25519";
2769
+ publicKey: string;
2770
+ notBefore: number;
2771
+ notAfter: number | null;
2772
+ status: "current" | "previous";
2773
+ }[];
2774
+ };
2775
+ };
2776
+ heartbeatIntervalSeconds: number;
2777
+ authorizationRefreshIntervalSeconds: number;
2778
+ }>>, z.ZodPipe<z.ZodObject<{
2779
+ v: z.ZodLiteral<2>;
2780
+ kind: z.ZodLiteral<"roamcode-cloud-host-config">;
2781
+ organizationId: z.ZodUUID;
2782
+ hostId: z.ZodUUID;
2783
+ controlPlaneOrigin: z.ZodString;
2784
+ hostCredential: z.ZodString;
2785
+ authorization: z.ZodObject<{
2786
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
2787
+ signatureDomain: z.ZodLiteral<"roamcode-cloud-authorization-snapshot-v2">;
2788
+ keysetSignatureDomain: z.ZodLiteral<"roamcode-cloud-authorization-keyset-v2">;
2789
+ keyset: z.ZodObject<{
2790
+ v: z.ZodLiteral<2>;
2791
+ kind: z.ZodLiteral<"authorization-keyset">;
2792
+ issuedAt: z.ZodNumber;
2793
+ expiresAt: z.ZodNumber;
2794
+ keys: z.ZodArray<z.ZodObject<{
2795
+ keyId: z.ZodString;
2796
+ algorithm: z.ZodLiteral<"Ed25519-SHA256">;
2797
+ publicKey: z.ZodString;
2798
+ notBefore: z.ZodNumber;
2799
+ notAfter: z.ZodNullable<z.ZodNumber>;
2800
+ status: z.ZodEnum<{
2801
+ current: "current";
2802
+ previous: "previous";
2803
+ }>;
2804
+ }, z.core.$strict>>;
2805
+ }, z.core.$strict>;
2806
+ }, z.core.$strict>;
2807
+ heartbeatIntervalSeconds: z.ZodNumber;
2808
+ authorizationRefreshIntervalSeconds: z.ZodNumber;
2809
+ }, z.core.$strict>, z.ZodTransform<{
2810
+ controlPlaneOrigin: string;
2811
+ v: 2;
2812
+ kind: "roamcode-cloud-host-config";
2813
+ organizationId: string;
2814
+ hostId: string;
2815
+ hostCredential: string;
2816
+ authorization: {
2817
+ algorithm: "Ed25519-SHA256";
2818
+ signatureDomain: "roamcode-cloud-authorization-snapshot-v2";
2819
+ keysetSignatureDomain: "roamcode-cloud-authorization-keyset-v2";
2820
+ keyset: {
2821
+ v: 2;
2822
+ kind: "authorization-keyset";
2823
+ issuedAt: number;
2824
+ expiresAt: number;
2825
+ keys: {
2826
+ keyId: string;
2827
+ algorithm: "Ed25519-SHA256";
2828
+ publicKey: string;
2829
+ notBefore: number;
2830
+ notAfter: number | null;
2831
+ status: "current" | "previous";
2832
+ }[];
2833
+ };
2834
+ };
2835
+ heartbeatIntervalSeconds: number;
2836
+ authorizationRefreshIntervalSeconds: number;
2837
+ }, {
2838
+ v: 2;
2839
+ kind: "roamcode-cloud-host-config";
2840
+ organizationId: string;
2841
+ hostId: string;
2842
+ controlPlaneOrigin: string;
2843
+ hostCredential: string;
2844
+ authorization: {
2845
+ algorithm: "Ed25519-SHA256";
2846
+ signatureDomain: "roamcode-cloud-authorization-snapshot-v2";
2847
+ keysetSignatureDomain: "roamcode-cloud-authorization-keyset-v2";
2848
+ keyset: {
2849
+ v: 2;
2850
+ kind: "authorization-keyset";
2851
+ issuedAt: number;
2852
+ expiresAt: number;
2853
+ keys: {
2854
+ keyId: string;
2855
+ algorithm: "Ed25519-SHA256";
2856
+ publicKey: string;
2857
+ notBefore: number;
2858
+ notAfter: number | null;
2859
+ status: "current" | "previous";
2860
+ }[];
2861
+ };
2862
+ };
2863
+ heartbeatIntervalSeconds: number;
2864
+ authorizationRefreshIntervalSeconds: number;
2865
+ }>>]>;
2866
+ type CloudHostConfigV1 = z.output<typeof CloudHostConfigV1Schema>;
2867
+ type CloudHostConfigV2 = z.output<typeof CloudHostConfigV2Schema>;
2868
+ type CloudHostConfig = z.output<typeof CloudHostConfigSchema>;
2869
+ interface ResolvedCloudHostConfig {
2870
+ path: string;
2871
+ config: CloudHostConfig;
2872
+ }
2873
+ declare function cloudHostConfigPath(dataDir: string): string;
2874
+ declare function readCloudHostConfig(path: string): CloudHostConfig | undefined;
2875
+ declare function writeCloudHostConfig(path: string, value: unknown): CloudHostConfig;
2876
+ /** Remove a managed host configuration without following links or deleting an unowned file. */
2877
+ declare function removeCloudHostConfig(path: string): boolean;
2878
+ declare function replaceCloudHostAuthorizationKeyset(path: string, current: CloudHostConfig, keyset: CloudAuthorizationKeyset): CloudHostConfig;
2879
+ declare function resolveCloudHostConfig(env: NodeJS.ProcessEnv, dataDir: string): ResolvedCloudHostConfig | undefined;
2880
+
2881
+ declare const CLOUD_HOST_HEARTBEAT_PATH = "/api/v1/hosts/heartbeat";
2882
+ declare const CLOUD_HOST_AUTHORIZATION_SNAPSHOT_PATH = "/api/v1/hosts/authorization-snapshot";
2883
+ declare const CLOUD_HOST_MAX_SIGNED_RESPONSE_BYTES: number;
2884
+ interface CloudHostRuntimeStatus {
2885
+ running: boolean;
2886
+ heartbeatFailures: number;
2887
+ authorizationFailures: number;
2888
+ authorizationIssue?: CloudHostAuthorizationIssue;
2889
+ lastHeartbeatAt?: number;
2890
+ lastAuthorizationAt?: number;
2891
+ authorization: CloudAuthorizationState;
2892
+ }
2893
+ type CloudHostAuthorizationIssue = "connectivity" | "credential-rejected" | "invalid-control-plane-response" | "authorization-verification-failed" | "trust-expired";
2894
+ interface CloudHostRuntime {
2895
+ start(): void;
2896
+ stop(): Promise<void>;
2897
+ sendHeartbeat(state?: "ready" | "draining"): Promise<void>;
2898
+ refreshAuthorizationKeyset(): Promise<boolean>;
2899
+ refreshAuthorizationSnapshot(): Promise<number>;
2900
+ syncAuthorization(): Promise<number>;
2901
+ /** Waits out an older in-flight poll, then starts a snapshot request from the resulting durable revision. */
2902
+ syncAuthorizationFresh(): Promise<number>;
2903
+ status(): CloudHostRuntimeStatus;
2904
+ }
2905
+ interface CreateCloudHostRuntimeOptions {
2906
+ config: CloudHostConfig;
2907
+ authorizationStore: CloudAuthorizationStore;
2908
+ instanceId: string;
2909
+ softwareVersion: string;
2910
+ capabilities: readonly string[] | (() => readonly string[]);
2911
+ /** Stable P-256 host identity advertised for browser enrollment pinning; private key never leaves this Node. */
2912
+ relayHostIdentity?: CloudRelayHostIdentity;
2913
+ /** Called only after a signed rotation verifies against the currently pinned keyset. Must persist atomically. */
2914
+ replaceAuthorizationKeyset: (keyset: CloudAuthorizationKeyset) => void;
2915
+ fetch?: typeof globalThis.fetch;
2916
+ now?: () => number;
2917
+ random?: () => number;
2918
+ requestTimeoutMs?: number;
2919
+ setTimeout?: typeof globalThis.setTimeout;
2920
+ clearTimeout?: typeof globalThis.clearTimeout;
2921
+ }
2922
+ type CloudHostRuntimeErrorCode = "UNAVAILABLE" | "REJECTED" | "INVALID_RESPONSE" | "KEYSET_REPLAY";
2923
+ declare class CloudHostRuntimeError extends Error {
2924
+ readonly code: CloudHostRuntimeErrorCode;
2925
+ readonly retryable: boolean;
2926
+ constructor(code: CloudHostRuntimeErrorCode, retryable: boolean);
2927
+ }
2928
+ declare function createCloudHostRuntime(options: CreateCloudHostRuntimeOptions): CloudHostRuntime;
2929
+
2930
+ type CompositeAuthorizationReason = TeamAuthorizationDecision["reason"] | CloudAuthorizationDecision["reason"];
2931
+ interface CompositeAuthorizationDecision {
2932
+ allowed: boolean;
2933
+ reason: CompositeAuthorizationReason;
2934
+ source: "local" | "team" | "cloud";
2935
+ roles: TeamRole[];
2936
+ member?: TeamMember;
2937
+ cloudRevision?: number;
2938
+ }
2939
+ interface CompositeAuthorizer {
2940
+ authorize(actorType: TeamPrincipalType, actorId: string, permission: TeamPermission, resource?: TeamAuthorizationResource): CompositeAuthorizationDecision;
2941
+ }
2942
+ interface CreateCompositeAuthorizerOptions {
2943
+ teamStore: TeamStore;
2944
+ /** Omit for self-hosted mode; presence makes a valid cloud grant an additional requirement for remote actors. */
2945
+ cloudStore?: CloudAuthorizationStore;
2946
+ /**
2947
+ * The managed control plane may assign the same physical Node a cloud Host id that differs from the
2948
+ * command-center store's local Host id. TeamStore must continue authorizing against the local id while the
2949
+ * signed cloud snapshot must see its own target id, so translate only the cloud layer at this composition
2950
+ * boundary instead of leaking a connection alias into every local resource.
2951
+ */
2952
+ cloudHostId?: string;
2953
+ /** Persisted managed ownership without a usable cloud store remains fail-closed for every remote actor. */
2954
+ requireCloud?: boolean;
2955
+ now?: () => number;
2956
+ }
2957
+ /**
2958
+ * Composes cloud grants with the existing local TeamStore policy. Self-hosted callers keep TeamStore behavior
2959
+ * exactly; cloud-managed callers must pass both layers. Host and local recovery principals never depend on cloud
2960
+ * availability, so an expired or unreachable control plane cannot lock an operator out of their own machine.
2961
+ */
2962
+ declare function createCompositeAuthorizer(options: CreateCompositeAuthorizerOptions): CompositeAuthorizer;
2963
+
1522
2964
  interface LoopbackRelayTerminalOptions {
1523
2965
  baseUrl(): string | undefined;
1524
2966
  issueTicket(token: string): Promise<string>;
@@ -2232,6 +3674,224 @@ declare function privacySafeAuditMetadata(value: Record<string, unknown> | undef
2232
3674
  declare function openControlStore(opts: OpenControlStoreOptions): ControlStore;
2233
3675
  declare const CONTROL_IDEMPOTENCY_TTL_MS: number;
2234
3676
 
3677
+ type SessionAutomationStoreMode = "sqlite" | "memory-fallback";
3678
+ type AutomationOwnerType = "person" | "organization";
3679
+ type SessionAutomationTrigger = {
3680
+ type: "manual";
3681
+ };
3682
+ type SessionAutomationRunStatus = "starting" | "running" | "needs-input" | "ready" | "failed" | "cancelled";
3683
+ type SessionAutomationBootstrapState = "pending" | "submitting" | "submitted";
3684
+ type SessionAutomationBootstrapClaim = "claimed" | "already-started" | "missing";
3685
+ interface SessionAutomationDefinition {
3686
+ id: string;
3687
+ owner: {
3688
+ type: AutomationOwnerType;
3689
+ id: string;
3690
+ };
3691
+ name: string;
3692
+ enabled: boolean;
3693
+ nodeId: string;
3694
+ agentRuntimeId: string;
3695
+ provider: string;
3696
+ cwd: string;
3697
+ instruction: string;
3698
+ runtimeOptions: Record<string, unknown>;
3699
+ trigger: SessionAutomationTrigger;
3700
+ revision: number;
3701
+ createdAt: number;
3702
+ updatedAt: number;
3703
+ }
3704
+ interface SessionAutomationRun {
3705
+ id: string;
3706
+ automationId: string;
3707
+ definitionRevision: number;
3708
+ invocationId: string;
3709
+ sessionId: string;
3710
+ nodeId: string;
3711
+ agentRuntimeId: string;
3712
+ cwd: string;
3713
+ status: SessionAutomationRunStatus;
3714
+ failureCode?: string;
3715
+ createdAt: number;
3716
+ updatedAt: number;
3717
+ }
3718
+ /**
3719
+ * Private, immutable launch input captured with a Run. It is intentionally separate from SessionAutomationRun so
3720
+ * ordinary API projections cannot accidentally disclose instructions or provider launch options.
3721
+ */
3722
+ interface SessionAutomationRunInputSnapshot {
3723
+ runId: string;
3724
+ automationId: string;
3725
+ definitionRevision: number;
3726
+ provider: string;
3727
+ instruction: string;
3728
+ runtimeOptions: Record<string, unknown>;
3729
+ bootstrapState: SessionAutomationBootstrapState;
3730
+ }
3731
+ interface CreateSessionAutomationRunInput {
3732
+ automationId: string;
3733
+ definitionRevision: number;
3734
+ invocationId: string;
3735
+ sessionId: string;
3736
+ nodeId: string;
3737
+ agentRuntimeId: string;
3738
+ cwd: string;
3739
+ /** Explicit values preserve the exact revision selected by a caller racing a later definition update. */
3740
+ provider?: string;
3741
+ instruction?: string;
3742
+ runtimeOptions?: Record<string, unknown>;
3743
+ }
3744
+ interface CreateSessionAutomationInput {
3745
+ owner: {
3746
+ type: AutomationOwnerType;
3747
+ id: string;
3748
+ };
3749
+ name: string;
3750
+ enabled?: boolean;
3751
+ nodeId: string;
3752
+ agentRuntimeId: string;
3753
+ provider: string;
3754
+ cwd: string;
3755
+ instruction: string;
3756
+ runtimeOptions?: Record<string, unknown>;
3757
+ trigger?: SessionAutomationTrigger;
3758
+ }
3759
+ interface UpdateSessionAutomationInput {
3760
+ name?: string;
3761
+ enabled?: boolean;
3762
+ nodeId?: string;
3763
+ agentRuntimeId?: string;
3764
+ provider?: string;
3765
+ cwd?: string;
3766
+ instruction?: string;
3767
+ runtimeOptions?: Record<string, unknown>;
3768
+ trigger?: SessionAutomationTrigger;
3769
+ }
3770
+ interface SessionAutomationStore {
3771
+ readonly mode: SessionAutomationStoreMode;
3772
+ getNodeOwner(nodeId: string): {
3773
+ type: AutomationOwnerType;
3774
+ id: string;
3775
+ } | undefined;
3776
+ list(owner?: {
3777
+ type: AutomationOwnerType;
3778
+ id: string;
3779
+ }): SessionAutomationDefinition[];
3780
+ get(id: string): SessionAutomationDefinition | undefined;
3781
+ getIncludingRemoved(id: string): SessionAutomationDefinition | undefined;
3782
+ create(input: CreateSessionAutomationInput, now?: number): SessionAutomationDefinition;
3783
+ update(id: string, input: UpdateSessionAutomationInput, expectedRevision: number, now?: number): SessionAutomationDefinition | undefined;
3784
+ transferOwner(from: {
3785
+ type: AutomationOwnerType;
3786
+ id: string;
3787
+ }, to: {
3788
+ type: AutomationOwnerType;
3789
+ id: string;
3790
+ }, nodeId: string, now?: number): number;
3791
+ remove(id: string): boolean;
3792
+ getRun(id: string): SessionAutomationRun | undefined;
3793
+ getRunInputSnapshot(id: string): SessionAutomationRunInputSnapshot | undefined;
3794
+ getRunByInvocationId(invocationId: string): SessionAutomationRun | undefined;
3795
+ getRunBySessionId(sessionId: string): SessionAutomationRun | undefined;
3796
+ createRun(input: CreateSessionAutomationRunInput, now?: number): SessionAutomationRun;
3797
+ beginRunBootstrap(id: string): SessionAutomationBootstrapClaim;
3798
+ completeRunBootstrap(id: string, now?: number): SessionAutomationRun | undefined;
3799
+ setRunStatus(id: string, status: Exclude<SessionAutomationRunStatus, "starting" | "failed">, now?: number): SessionAutomationRun | undefined;
3800
+ markRunFailed(id: string, failureCode: string, now?: number): SessionAutomationRun | undefined;
3801
+ listRuns(automationId?: string, limit?: number): SessionAutomationRun[];
3802
+ close(): void;
3803
+ }
3804
+ interface OpenSessionAutomationStoreOptions {
3805
+ dbPath: string;
3806
+ generateAutomationId?: () => string;
3807
+ generateRunId?: () => string;
3808
+ loadDatabase?: () => typeof better_sqlite3;
3809
+ }
3810
+ declare class SessionAutomationRevisionConflictError extends Error {
3811
+ readonly current: SessionAutomationDefinition;
3812
+ constructor(current: SessionAutomationDefinition);
3813
+ }
3814
+ declare function openSessionAutomationStore(opts: OpenSessionAutomationStoreOptions): SessionAutomationStore;
3815
+
3816
+ interface OwnerRef {
3817
+ type: "person" | "organization";
3818
+ id: string;
3819
+ }
3820
+ interface ProductContext {
3821
+ kind: "personal" | "organization";
3822
+ id: string;
3823
+ name: string;
3824
+ }
3825
+ interface NodeAlias {
3826
+ kind: "command-host" | "cloud-host" | "peer-host" | "direct-host" | "relay-route";
3827
+ id: string;
3828
+ }
3829
+ interface NodeRecord {
3830
+ id: string;
3831
+ owner: OwnerRef;
3832
+ name: string;
3833
+ status: "online" | "offline" | "degraded";
3834
+ platform: string;
3835
+ lastSeenAt: number;
3836
+ aliases: NodeAlias[];
3837
+ }
3838
+ type AgentRuntimeAuthState = "ready" | "required" | "unknown" | "error";
3839
+ interface AgentRuntimeRecord {
3840
+ id: string;
3841
+ nodeId: string;
3842
+ provider: string;
3843
+ displayName: string;
3844
+ availability: "available" | "unavailable";
3845
+ authState: AgentRuntimeAuthState;
3846
+ version?: string;
3847
+ capabilities: string[];
3848
+ activeSessionCount: number;
3849
+ observedAt: number;
3850
+ }
3851
+ interface NodeProjectionInput {
3852
+ host: Pick<HostRecord, "id" | "label">;
3853
+ owner: OwnerRef;
3854
+ status: NodeRecord["status"];
3855
+ platform: string;
3856
+ lastSeenAt: number;
3857
+ aliases?: readonly NodeAlias[];
3858
+ }
3859
+ interface AgentRuntimeDescriptor {
3860
+ id: string;
3861
+ displayName: string;
3862
+ version?: string;
3863
+ enabled?: boolean;
3864
+ capabilities: Readonly<Record<string, boolean>>;
3865
+ }
3866
+ type ProviderValueMap<T> = Readonly<Record<string, T | undefined>> | ReadonlyMap<string, T>;
3867
+ interface AgentRuntimeProjectionInput {
3868
+ nodeId: string;
3869
+ descriptors: readonly AgentRuntimeDescriptor[];
3870
+ availabilityByProvider: ProviderValueMap<ProviderAvailability>;
3871
+ authStateByProvider?: ProviderValueMap<AgentRuntimeAuthState>;
3872
+ activeSessionCountByProvider?: ProviderValueMap<number>;
3873
+ /** Product-level capabilities that are intentionally outside the versioned adapter manifest contract. */
3874
+ additionalCapabilitiesByProvider?: Readonly<Record<string, readonly string[] | undefined>>;
3875
+ observedAt: number;
3876
+ }
3877
+ /** Map a canonical owner to the context label used by product navigation. */
3878
+ declare function productContextFromOwner(owner: OwnerRef, name: string): ProductContext;
3879
+ /** Recover the canonical owner reference without leaking presentation-only context fields. */
3880
+ declare function ownerFromProductContext(context: ProductContext): OwnerRef;
3881
+ /**
3882
+ * Runtime ids are opaque because node and adapter ids can originate in different trust domains.
3883
+ * JSON tuple framing prevents ambiguous concatenation, while base64url keeps the result route-safe.
3884
+ */
3885
+ declare function agentRuntimeId(nodeId: string, provider: string): string;
3886
+ /** Project the persistent command host into the product Node model without changing its identity. */
3887
+ declare function projectNodeRecord(input: NodeProjectionInput): NodeRecord;
3888
+ /**
3889
+ * Build the public runtime inventory from bounded provider facts. The projection deliberately picks
3890
+ * fields instead of spreading descriptors or probes, so probe detail, paths, credentials, and option
3891
+ * payloads cannot cross this boundary.
3892
+ */
3893
+ declare function projectAgentRuntimeRecords(input: AgentRuntimeProjectionInput): AgentRuntimeRecord[];
3894
+
2235
3895
  /**
2236
3896
  * Origin / CSWSH (cross-site WebSocket hijacking) guard for the WS upgrade and state-changing HTTP.
2237
3897
  *
@@ -3457,6 +5117,17 @@ declare class TerminalManager {
3457
5117
  private cleanupRecordPaths;
3458
5118
  private applyRuntimeSignal;
3459
5119
  write(id: string, data: string): void;
5120
+ /**
5121
+ * Start a newly-created automation Session and submit its task exactly once. `create()` is intentionally
5122
+ * lazy, so writing before an attach would be a silent no-op; this method first owns a private attachment,
5123
+ * waits for the provider TUI's idle composer (not merely a banner/auth/trust frame), then sends one bracketed
5124
+ * paste and releases the attachment.
5125
+ * The task never enters argv, logs, audit metadata, or a WebSocket URL.
5126
+ */
5127
+ bootstrapTask(id: string, task: string, options?: {
5128
+ readyTimeoutMs?: number;
5129
+ signal?: AbortSignal;
5130
+ }): Promise<void>;
3460
5131
  resize(id: string, cols: number, rows: number): void;
3461
5132
  stop(id: string): void;
3462
5133
  get(id: string): TerminalMeta | undefined;
@@ -3816,6 +5487,8 @@ interface CreateServerDeps {
3816
5487
  commandStore?: CommandCenterStore;
3817
5488
  /** Durable idempotency, privacy-safe audit, and automation definitions/runs. */
3818
5489
  controlStore?: ControlStore;
5490
+ /** Durable coding automations that launch real terminal Sessions on one exact Node/runtime/cwd. */
5491
+ sessionAutomationStore?: SessionAutomationStore;
3819
5492
  /** Guarded git worktree lifecycle, confined to FS_ROOT and injectable for isolated tests. */
3820
5493
  worktreeService?: WorktreeService;
3821
5494
  /** Durable verified adapter/plugin package inventory. start.ts supplies a SQLite-backed manager. */
@@ -3919,12 +5592,16 @@ interface CreateServerDeps {
3919
5592
  wsTickets?: WsTicketStore;
3920
5593
  /** One-writer/many-observer terminal input coordinator. Injectable for deterministic multi-client tests. */
3921
5594
  inputLeases?: InputLeaseCoordinator;
5595
+ /** Managed-cloud terminal authorization poll cadence. Injectable only so socket revocation tests stay fast. */
5596
+ terminalAuthorizationRecheckMs?: number;
3922
5597
  /** Team policy seam: direct local mode permits confirmed takeover; enterprise policy can deny it here. */
3923
5598
  authorizeInputTakeover?: (principal: InputLeasePrincipal, sessionId: string) => boolean;
3924
5599
  /** Optional policy seam for acquiring/writing input. Team RBAC is applied in addition when enabled. */
3925
5600
  authorizeInputWrite?: (principal: InputLeasePrincipal, sessionId: string) => boolean;
3926
5601
  /** Durable team membership and role assignments. start.ts supplies SQLite; tests may inject memory. */
3927
5602
  teamStore?: TeamStore;
5603
+ /** Additive local-team + signed-cloud authorization. Omit to preserve exact self-hosted TeamStore behavior. */
5604
+ authorizer?: CompositeAuthorizer;
3928
5605
  /** Durable organization policy. Disabled by default; enforced uniformly when explicitly enabled. */
3929
5606
  policyStore?: PolicyStore;
3930
5607
  /** Durable, explicitly scoped host-to-host API connections. Raw peer credentials never leave this store. */
@@ -3941,11 +5618,47 @@ interface CreateServerDeps {
3941
5618
  activeChannels: number;
3942
5619
  reconnects: number;
3943
5620
  };
5621
+ /** Privacy-safe managed-host sync status. Presence means cloud management is configured. */
5622
+ cloudStatus?: () => CloudHostRuntimeStatus;
5623
+ /** Signed managed-cloud authorization authority, used only for read-only Node grant projection. */
5624
+ cloudAuthorizationStore?: CloudAuthorizationStore;
5625
+ /** Managed ownership remains read-only/fail-closed even if its signed cloud store is temporarily unavailable. */
5626
+ managedAuthorization?: boolean;
5627
+ /** Canonical product ownership for this Node. Local installs default to the Personal context. */
5628
+ nodeOwner?: OwnerRef;
5629
+ /** Non-authoritative connection identifiers that resolve to this persistent command-host Node. */
5630
+ nodeAliases?: readonly NodeAlias[];
5631
+ /** Product context label; never used as an authorization decision. */
5632
+ nodeOwnerName?: string;
3944
5633
  /** Optional hosted/self-hosted bootstrap; absent means relay works for already-provisioned devices only. */
3945
5634
  relayPairing?: RelayPairingBootstrap;
5635
+ /**
5636
+ * Optional hosted control-plane bridge. The request actor always comes from DeviceStore authentication;
5637
+ * clients can supply only their one-use enrollment challenge.
5638
+ */
5639
+ cloudDeviceEnrollmentConfirmer?: CloudDeviceEnrollmentConfirmer;
3946
5640
  /** Late-bound host connector hook so device revocation closes relay channels immediately. */
3947
5641
  onDeviceRevoked?: (deviceId: string) => void;
3948
5642
  }
5643
+ type CloudStatusSyncState = "not-configured" | "syncing" | "healthy" | "pending" | "degraded" | "expired";
5644
+ type CloudStatusRecoveryAction = "none" | "wait-for-cloud-sync" | "wait-for-authorization-activation" | "check-host-connectivity" | "reauthorize-host" | "contact-organization-admin";
5645
+ interface CloudStatusResponse {
5646
+ v: 1;
5647
+ mode: "self-hosted" | "managed";
5648
+ configured: boolean;
5649
+ sync: {
5650
+ state: CloudStatusSyncState;
5651
+ lastSuccessfulAt: number | null;
5652
+ };
5653
+ authorization: {
5654
+ status: "not-configured" | CloudHostRuntimeStatus["authorization"]["status"];
5655
+ revision: number | null;
5656
+ expiresAt: number | null;
5657
+ expired: boolean;
5658
+ };
5659
+ action: CloudStatusRecoveryAction;
5660
+ }
5661
+ declare function cloudStatusResponse(status?: CloudHostRuntimeStatus): CloudStatusResponse;
3949
5662
  interface CreateServerResult {
3950
5663
  app: FastifyInstance;
3951
5664
  authGate: AuthGate;
@@ -4097,11 +5810,22 @@ declare function claudePreflightWarning(availability: ClaudeAvailability): strin
4097
5810
  * (the probe is short-timeout-guarded). Injectable probe + log sink so it's testable without a spawn.
4098
5811
  */
4099
5812
  declare function runClaudePreflight(probe: ClaudeVersionProbe, warn?: (msg: string) => void): Promise<void>;
4100
- declare function startServer(env?: NodeJS.ProcessEnv): Promise<CreateServerResult & {
5813
+ interface StartServerOptions {
5814
+ /** Shared control-plane transport seam for isolated embedding and startup tests. */
5815
+ fetch?: typeof globalThis.fetch;
5816
+ }
5817
+ declare function cloudHostCapabilities(input: {
5818
+ authorizationVersion: number;
5819
+ terminalAvailable: boolean;
5820
+ relayEnabled: boolean;
5821
+ managedDeviceEnrollmentEnabled: boolean;
5822
+ }): string[];
5823
+ declare function startServer(env?: NodeJS.ProcessEnv, options?: StartServerOptions): Promise<CreateServerResult & {
4101
5824
  url: string;
4102
5825
  token?: string;
4103
5826
  tokenGenerated: boolean;
4104
5827
  relayHost?: RelayHostConnector;
5828
+ cloudHostRuntime?: CloudHostRuntime;
4105
5829
  }>;
4106
5830
 
4107
5831
  interface ProcessLifecycleTarget {
@@ -4309,4 +6033,4 @@ declare function codexClassifierVersionWarning(codexVersion: string | undefined)
4309
6033
 
4310
6034
  declare const SERVER_PACKAGE = "@roamcode.ai/server";
4311
6035
 
4312
- export { ADAPTER_CONTRACT_VERSION, API_PATH_DENYLIST, type AdapterCapabilityName, AdapterManifestError, type AdapterManifestV1, type AdapterPackageManifestV1, type AdapterRuntimeV1, type AdapterStateAuthority, type AgentActivity, type AgentProvider, type AgentRecord, type AttachSpawnOptions, type AttentionItem, type AttentionKind, type AttentionState, type AuditActorType, type AuditRecord, type AuditResult, type AuthCheckResult, AuthGate, type AuthGateOptions, type AutomationAction, type AutomationDefinition, type AutomationRun, type AutomationTrigger, BLIND_RELAY_DEFAULT_MAX_BYTES_PER_MINUTE, BLIND_RELAY_DEFAULT_MAX_CONNECTIONS_PER_ROUTE, BLIND_RELAY_DEFAULT_MAX_FRAME_BYTES, BLIND_RELAY_DEFAULT_MAX_MESSAGES_PER_MINUTE, BLIND_RELAY_DEFAULT_MAX_QUEUE_BYTES, BLIND_RELAY_DEFAULT_MAX_TOTAL_CONNECTIONS, BLIND_RELAY_PROTOCOL_VERSION, type Bar, type BlindRelayMetrics, type BlindRelayServer, CHECK_CACHE_MS, CLASSIFIER_TESTED_UP_TO, CLAUDE_LATEST_CACHE_MS, CLAUDE_VERSION_CACHE_MS, CLAUDE_VERSION_TIMEOUT_MS, CODEX_CLASSIFIER_TESTED_UP_TO, CODEX_EXECUTABLE_PROBE_TIMEOUT_MS, CODEX_OSC_MAX_CARRY, CONTROL_IDEMPOTENCY_TTL_MS, type CaptureOptions, type ChangelogEntry, type ClaudeAuthDeps, ClaudeAuthService, type ClaudeAuthStatus, type ClaudeAvailability, type ClaudeLatestDeps, ClaudeLatestService, type ClaudeMetadataRunner, ClaudeMetadataService, type ClaudeModelCatalogItem, type ClaudeSessionOptions, type ClaudeVersionProbe, type CodexAccount, CodexAppServerClient, type CodexAppServerClientOptions, type CodexDeviceLogin, type CodexExecutableDeps, type CodexExecutableProbe, type CodexExecutableResolution, type CodexInstallProvenance, CodexLatestService, type CodexLoginCompletion, type CodexLoginStatus, type CodexMetadataDiagnostics, type CodexMetadataRpc, CodexMetadataService, type CodexMetadataServiceOptions, type CodexModel, type CodexOscParser, type CodexProfileClientLifecycle, type CodexSessionOptions, type CodexSpawnLease, type CodexThreadInventoryEntry, type CodexThreadPersistence, CodexThreadResolver, type CodexThreadResolverOptions, type CodexUsage, type CodexVersionInfo, CommandCenterRevisionConflictError, type CommandCenterStore, type CommandCenterStoreMode, type CommandEvent, type CommandLayoutEnvelope, type ControlStore, type ControlStoreMode, type CreateAutomationInput, type CreateBlindRelayOptions, type CreateClaudeProviderOptions, type CreateCodexProfileClientLifecycleOptions, type CreateCodexProviderOptions, type CreateInstalledAdapterProviderOptions, type CreatePeerInput, type CreatePluginRuntimeOptions, type CreatePushDispatcherDeps, type CreateRelayAccountInput, type CreateServerDeps, type CreateServerResult, type CreateWebPushSendOptions, type CreateWorktreeInput, type CreateWorktreeResult, type CreateWorktreeServiceOptions, type DeviceEnrollment, type DeviceInfo, DevicePairingError, type DeviceRelayIdentity, type DeviceScope, type DeviceStore, type DirEntry, type DirListing, type DirSearchResult, type DurableRelayIdentity, type EnterprisePolicy, type EnterprisePolicyAction, type EnterprisePolicyContext, type EnterprisePolicyDecision, EnterprisePolicyRevisionConflictError, type EnterprisePolicyUpdate, ExtensionError, type ExtensionKind, type ExtensionManager, type ExtensionManifestV1, type ExtensionPolicyMode, type ExtensionTrust, type ExtensionVersionRecord, FETCH_TIMEOUT_MS, type FetchLatest, type FetchManifest, type FetchReleases, FsError, type FsErrorCode, FsService, type FsServiceOptions, type GitHubRelease, type HooksSettingsDocument, type HostRecord, INPUT_LEASE_TTL_MS, type IPty, type IdempotencyRecord, type InputLease, type InputLeaseAcquireResult, type InputLeaseActorType, InputLeaseCoordinator, type InputLeaseCoordinatorOptions, type InputLeaseEvent, type InputLeasePrincipal, type InstallExtensionInput, type InstallServiceContext, type InstallServiceResult, type InstallationKind, type InstalledExtension, type LaunchIntent, type LoopbackRelayHttpOptions, type LoopbackRelayTerminalOptions, type ManagedInstallOptions, type ManagedInstallResult, type ManagedInstallStatus, type ManagedPaths, type MarketplaceEntry, type McpConfigDocument, type ModelWeekBar, OPENAI_CODE_SIGNING_TEAM_ID, type OpenApiBuildOptions, type OpenCommandCenterStoreOptions, type OpenControlStoreOptions, type OpenDeviceStoreOptions, type OpenExtensionManagerOptions, type OpenPeerStoreOptions, type OpenPolicyStoreOptions, type OpenPushStoreOptions, type OpenRelayAccountStoreOptions, type OpenRelayRouteStoreOptions, type OpenSessionStoreOptions, type OpenTeamStoreOptions, type OriginCheckOptions, PAIRING_TTL_MS, PRESENCE_HEARTBEAT_MS, PRESENCE_TTL_MS, PWA_BOOT_WATCHDOG_SHA256, PWA_CONTENT_SECURITY_POLICY, type PairingTicket, type PaneStatus, type PeerAction, type PeerConnection, type PeerJsonResponse, type PeerRecord, PeerRequestError, PeerRevisionConflictError, type PeerStatus, type PeerStore, type PeerStoreMode, type PersistedRelayHostConfig, type PluginAuditEvent, type PluginManifestV1, type PluginPermission, type PluginRunInput, type PluginRunResult, type PluginRuntime, PluginRuntimeError, type PolicyStore, type PolicyStoreMode, PresenceCoordinator, type PresenceCoordinatorOptions, type PresenceEvent, type PresenceHeartbeatInput, type PresenceMode, type PresenceRecord, type PresenceTarget, type ProcessLifecycleHandle, type ProcessLifecycleOptions, type ProcessLifecycleTarget, type ProcessSpec, type ProviderAdapterV1, type ProviderAvailability, ProviderError, type ProviderId, ProviderOptionsError, type ProviderProcessContext, ProviderRegistry, type ProviderRuntimeSignal, type ProviderRuntimeSignalParser, type ProviderSessionOptions, type PtySpawn, type PublicRelayRouteRecord, type PushDispatcher, type PushEvent, type PushEventKind, type PushPayload, type PushRecipient, type PushSendFn, type PushStore, type PushSubscriptionRecord, RELAY_CHANNEL_MAX_AGE_MS, RELAY_CHANNEL_MAX_FRAMES, RELAY_HANDSHAKE_MAX_SKEW_MS, RELAY_MAX_PLAINTEXT_BYTES, RELAY_PROTOCOL_VERSION, RELAY_RPC_MAX_BODY_BYTES, RELAY_RPC_MAX_PATH_BYTES, RELAY_WIRE_MAX_ENVELOPE_BYTES, RELAY_WIRE_PROTOCOL_VERSION, RUNNING_BUILD, RUNNING_VERSION, type RateLimitDecision, RateLimiter, type RateLimiterOptions, type RegisterStaticOptions, type RelayAccountCredentialInput, type RelayAccountCredentialMaterial, type RelayAccountPlan, type RelayAccountRecord, RelayAccountRevisionConflictError, type RelayAccountStatus, type RelayAccountStore, type RelayAccountStoreMode, type RelayChannelOptions, RelayCipherState, RelayCryptoError, type RelayCryptoErrorCode, type RelayDeviceProvisioner, type RelayDeviceProvisionerOptions, type RelayDeviceRouteRecord, type RelayDirection, type RelayEncryptedFrame, type RelayEphemeralKeyPair, type RelayFrameKind, type RelayHandshakeHello, type RelayHostConfigInput, type RelayHostConnector, type RelayHostConnectorOptions, type RelayHostMetrics, type RelayHostRuntimeConfig, type RelayHostStatus, type RelayHttpBridge, type RelayHttpHandlers, type RelayHttpOpenRequest, type RelayHttpOpener, type RelayHttpResponseHead, type RelayIdentity, type RelayIdentityStoreOptions, type RelayPairingBootstrap, type RelayPairingPackage, type RelayRole, type RelayRouteRecord, type RelayRouteStore, type RelayRpcMethod, type RelayRpcRequest, type RelayRpcResponse, type RelayStoreMode, type RelayTerminalBridge, type RelayTerminalHandlers, type RelayTerminalOpenRequest, type RelayTerminalOpener, type RelayWireEnvelope, type ReleaseRecord, type RenderLaunchdOptions, type RenderSystemdOptions, type ResolveAccessTokenOptions, type ResolveCodexExecutableOptions, type ResolveCodexThreadOptions, type ResolveVapidKeysOptions, type ReturnTypeOfDescriptors, type RunClaudeVersion, type RunUsage, SEARCH_MAX_DEPTH, SEARCH_MAX_DIRS, SEARCH_MAX_RESULTS, SERVER_PACKAGE, SHELL_PATH_ALLOWLIST, type ServerConfig, type ServerRuntimeConfig, type ServiceRecord, type SessionDefaults, SessionDefaultsConflictError, type SessionFileDirection, type SessionFileKind, type SessionFileStorage, type SessionPlacement, type SessionStore, type StartedBlindRelay, type StoreMode, type StoredExternalSession, type StoredSession, type StoredSessionDefaults, type StoredSessionFile, type StoredStatus, type TeamAuthorizationDecision, type TeamAuthorizationResource, type TeamMember, type TeamMemberKind, type TeamMemberStatus, type TeamPermission, type TeamPrincipalBinding, type TeamPrincipalType, type TeamRecord, TeamRevisionConflictError, type TeamRole, type TeamRoleBinding, type TeamScopeType, type TeamStore, type TeamStoreMode, TerminalManager, type TerminalManagerDeps, type TerminalMeta, TerminalProcess, type TerminalProcessOptions, type TerminalSub, USAGE_CACHE_MS, USAGE_TIMEOUT_MS, type UpdateAction, type UpdateAutomationInput, type UpdatePeerInput, type UpdatePolicyMode, type UpdateRelayAccountInput, type UpdateState, type UpdateStatus, Updater, type UpdaterDeps, type UpdaterFs, type UsageInfo, UsageService, type UsageServiceDeps, type VapidKeys, type VerifiedPeerIdentity, type VersionInfo, WS_TICKET_TTL_MS, type WorkspaceKind, type WorkspaceRecord, WorktreeError, type WorktreeErrorCode, type WorktreeRecord, type WorktreeService, type WsTicketContext, WsTicketStore, type WsTicketStoreOptions, adapterCapabilityNames, assertConfigAllowsStart, buildCodexArgs, buildHooksSettingsDocument, buildMcpConfigDocument, buildOpenApiDocument, buildPushPayload, buildRelayPairingUrl, buildServicePath, capturePane, classifierVersionWarning, classifyCodexPane, classifyPaneStatus, claudePreflightWarning, codexClassifierVersionWarning, compareVersions, computeBuildDrift, computeInstallDrift, createBlindRelayServer, createClaudeAuthService, createClaudeLatestService, createClaudeMetadataRunner, createClaudeProvider, createClaudeVersionProbe, createCodexOscParser, createCodexProfileClientLifecycle, createCodexProvider, createCodexThreadInventory, createCodexThreadPersistence, createInstalledAdapterProvider, createLoopbackRelayHttpOpener, createLoopbackRelayTerminalOpener, createPluginRuntime, createPushDispatcher, createRelayDeviceProvisioner, createRelayHandshakeHello, createRelayHostConnector, createServer, createUpdater, createUsageRunner, createUsageService, createWebPushSend, createWorktreeService, currentAgentIdForSession, decodeRelayWireEnvelope, defaultFetchManifest, defaultFetchReleases, defaultProbeCodexExecutable, defaultRunClaudeVersion, defaultUpdaterFs, defineAdapterManifest, detectTerminalSupport, enableService, encodeRelayWireEnvelope, ensureDataDir, establishRelayChannel, evaluateEnterprisePolicy, extractBearerToken, extractLoginUrl, generateAccessToken, generateRelayAccountCredential, generateRelayCredential, generateRelayEphemeralKeyPair, generateRelayIdentity, hasEncodedSep, hkdfSha256, hookAuthFileContent, hookAuthPathFor, hooksSettingsPathFor, inspectExtensionPackage, installManagedRelease, installProcessLifecycle, installService, isCodexProfileClientLifecycle, isLoopbackAddress, isNewerMajorMinor, isOriginAllowed, isPublicForRequest, isPublicPath, isRelayDirectExecution, isShellPath, isStableVersion, isTeamRole, isTeamScopeType, listTmuxSessions, loadConfig, loadOrCreateRelayIdentity, loadServerConfig, looksLikeAssetRequest, managedPaths, mcpConfigPathFor, migrateServiceToLauncher, normalizeAutomationAction, normalizeAutomationInput, normalizeAutomationTrigger, normalizeCommandCenterLabel, normalizeDeviceName, normalizeDeviceScopes, normalizeOrigin, normalizePeerBaseUrl, normalizeProviderAvailability, normalizeRelayAppUrl, normalizeRelease, normalizeSessionDefaults, openCommandCenterStore, openControlStore, openDeviceStore, openExtensionManager, openPeerStore, openPolicyStore, openPushStore, openRelayAccountStore, openRelayRouteStore, openSessionStore, openTeamStore, parseAllowedOrigins, parseAuthStatus, parseClaudeVersion, parseCodexOscNotifications, parseCodexVersion, parseLegacyClaudeArgs, parseMarketplaceIndex, parseNpmLatest, parseProviderOptions, parseRelayRpcRequest, parseReleaseNotes, parseUsage, pathForGate, persistAccessToken, privacySafeAuditMetadata, providerPreflightWarning, publicAdapterDescriptor, readActiveVersion, readPreviousVersion, readRelayHostConfig, readServiceRecord, registerStatic, relativeWhen, relayAccountCredentialHash, relayAccountCredentialLookup, relayConnectUrl, relayCredentialHash, relayHostConfigPath, relayIdentityFingerprint, relayRpcResponse, removeRelayHostConfig, renderLaunchdPlist, renderManagedLauncher, renderSystemdUnit, requestPeerJson, resetCodexThreadResolutionCoordinatorForTests, resolveAccessToken, resolveCodexExecutable, resolveDataDir, resolveInstallRoot, resolveRelayHostConfig, resolveVapidKeys, restartService, runClaudePreflight, runProviderPreflight, safeProcessErrorSummary, searchMarketplace, stableReleases, startBlindRelay, startServer, teamRolePermissions, tmuxSessionName, validateAdapterManifest, validateAdapterOptionSchema, validateRelayIdentity, verifyPeerConnection, verifyRelayHandshakeHello, writeManagedLauncher, writeRelayHostConfig };
6036
+ export { ADAPTER_CONTRACT_VERSION, API_PATH_DENYLIST, type AdapterCapabilityName, AdapterManifestError, type AdapterManifestV1, type AdapterPackageManifestV1, type AdapterRuntimeV1, type AdapterStateAuthority, type AgentActivity, type AgentProvider, type AgentRecord, type AgentRuntimeAuthState, type AgentRuntimeRecord, type AttachSpawnOptions, type AttentionItem, type AttentionKind, type AttentionState, type AuditActorType, type AuditRecord, type AuditResult, type AuthCheckResult, AuthGate, type AuthGateOptions, type AutomationAction, type AutomationDefinition, type AutomationRun, type AutomationTrigger, BLIND_RELAY_DEFAULT_MAX_BYTES_PER_MINUTE, BLIND_RELAY_DEFAULT_MAX_CONNECTIONS_PER_ROUTE, BLIND_RELAY_DEFAULT_MAX_FRAME_BYTES, BLIND_RELAY_DEFAULT_MAX_MESSAGES_PER_MINUTE, BLIND_RELAY_DEFAULT_MAX_QUEUE_BYTES, BLIND_RELAY_DEFAULT_MAX_TOTAL_CONNECTIONS, BLIND_RELAY_PROTOCOL_VERSION, type Bar, type BlindRelayMetrics, type BlindRelayServer, CHECK_CACHE_MS, CLASSIFIER_TESTED_UP_TO, CLAUDE_LATEST_CACHE_MS, CLAUDE_VERSION_CACHE_MS, CLAUDE_VERSION_TIMEOUT_MS, CLOUD_AUTHORIZATION_CLOCK_SKEW_MS, CLOUD_AUTHORIZATION_CONTRACT_VERSION, CLOUD_AUTHORIZATION_FILE, CLOUD_AUTHORIZATION_KEYSET_PATH, CLOUD_AUTHORIZATION_KEYSET_SIGNATURE_DOMAIN, CLOUD_AUTHORIZATION_KEYSET_SIGNATURE_DOMAIN_V2, CLOUD_AUTHORIZATION_LAST_GOOD_FILE, CLOUD_AUTHORIZATION_PERMISSIONS, CLOUD_AUTHORIZATION_SIGNATURE_ALGORITHM, CLOUD_AUTHORIZATION_SIGNATURE_ALGORITHM_V2, CLOUD_AUTHORIZATION_SIGNATURE_DOMAIN, CLOUD_AUTHORIZATION_SIGNATURE_DOMAIN_V2, CLOUD_CONTRACT_VERSION, CLOUD_DEVICE_ENROLLMENT_COMPLETE_PATH, CLOUD_DEVICE_ENROLLMENT_CONFIRM_PATH, CLOUD_DEVICE_ENROLLMENT_HOST_ROUTE, CLOUD_HOST_AUTHORIZATION_SNAPSHOT_PATH, CLOUD_HOST_CONFIG_FILE, CLOUD_HOST_HEARTBEAT_PATH, CLOUD_HOST_MAX_SIGNED_RESPONSE_BYTES, CLOUD_KEYSET_CLOCK_SKEW_MS, CODEX_CLASSIFIER_TESTED_UP_TO, CODEX_EXECUTABLE_PROBE_TIMEOUT_MS, CODEX_OSC_MAX_CARRY, CONTROL_IDEMPOTENCY_TTL_MS, type CaptureOptions, type ChangelogEntry, type ClaudeAuthDeps, ClaudeAuthService, type ClaudeAuthStatus, type ClaudeAvailability, type ClaudeLatestDeps, ClaudeLatestService, type ClaudeMetadataRunner, ClaudeMetadataService, type ClaudeModelCatalogItem, type ClaudeSessionOptions, type ClaudeVersionProbe, type CloudAuthorizationDecision, type CloudAuthorizationGrantV1, CloudAuthorizationGrantV1Schema, type CloudAuthorizationKeyset, type CloudAuthorizationKeysetKey, type CloudAuthorizationKeysetKeyV1, CloudAuthorizationKeysetKeyV1Schema, type CloudAuthorizationKeysetKeyV2, CloudAuthorizationKeysetKeyV2Schema, CloudAuthorizationKeysetSchema, type CloudAuthorizationKeysetV1, CloudAuthorizationKeysetV1Schema, type CloudAuthorizationKeysetV2, CloudAuthorizationKeysetV2Schema, type CloudAuthorizationPermission, CloudAuthorizationPermissionSchema, type CloudAuthorizationPrincipalType, type CloudAuthorizationScopeV1, CloudAuthorizationScopeV1Schema, type CloudAuthorizationSnapshot, CloudAuthorizationSnapshotSchema, type CloudAuthorizationSnapshotStatus, type CloudAuthorizationSnapshotV1, CloudAuthorizationSnapshotV1Schema, type CloudAuthorizationSnapshotV2, CloudAuthorizationSnapshotV2Schema, type CloudAuthorizationState, type CloudAuthorizationStore, CloudAuthorizationStoreError, type CloudAuthorizationStoreErrorCode, type CloudAuthorizationTrustedKey, CloudAuthorizationTrustedKeyAnySchema, CloudAuthorizationTrustedKeySchema, type CloudAuthorizationTrustedKeyV1, type CloudAuthorizationTrustedKeyV2, CloudAuthorizationTrustedKeyV2Schema, CloudAuthorizationVerificationError, type CloudAuthorizationVerificationErrorCode, type CloudDeviceEnrollmentConfirmationResult, type CloudDeviceEnrollmentConfirmer, CloudDeviceEnrollmentConflictError, CloudDeviceEnrollmentError, type CloudDeviceEnrollmentErrorCode, type CloudDeviceEnrollmentPrepareInput, type CloudDeviceEnrollmentProgress, type CloudDeviceEnrollmentRecoveryLoop, type CloudDeviceEnrollmentRequest, CloudDeviceEnrollmentRequestSchema, type CloudDeviceEnrollmentRuntimeConfig, type CloudDeviceEnrollmentState, type CloudHostAuthorizationIssue, type CloudHostConfig, CloudHostConfigSchema, type CloudHostConfigV1, CloudHostConfigV1Schema, type CloudHostConfigV2, CloudHostConfigV2Schema, type CloudHostDeviceEnrollmentCompletion, type CloudHostDeviceEnrollmentCompletionResult, CloudHostDeviceEnrollmentCompletionSchema, type CloudHostDeviceEnrollmentConfirmation, CloudHostDeviceEnrollmentConfirmationSchema, type CloudHostHeartbeatV1, CloudHostHeartbeatV1Schema, type CloudHostRuntime, CloudHostRuntimeError, type CloudHostRuntimeErrorCode, type CloudHostRuntimeStatus, CloudKeysetVerificationError, type CloudKeysetVerificationErrorCode, type CloudRelayDeviceEnrollmentAuth, CloudRelayDeviceEnrollmentAuthSchema, type CloudRelayDeviceEnrollmentPayload, CloudRelayDeviceEnrollmentPayloadSchema, type CloudRelayDeviceEnrollmentSaga, type CloudStatusRecoveryAction, type CloudStatusResponse, type CloudStatusSyncState, type CodexAccount, CodexAppServerClient, type CodexAppServerClientOptions, type CodexDeviceLogin, type CodexExecutableDeps, type CodexExecutableProbe, type CodexExecutableResolution, type CodexInstallProvenance, CodexLatestService, type CodexLoginCompletion, type CodexLoginStatus, type CodexMetadataDiagnostics, type CodexMetadataRpc, CodexMetadataService, type CodexMetadataServiceOptions, type CodexModel, type CodexOscParser, type CodexProfileClientLifecycle, type CodexSessionOptions, type CodexSpawnLease, type CodexThreadInventoryEntry, type CodexThreadPersistence, CodexThreadResolver, type CodexThreadResolverOptions, type CodexUsage, type CodexVersionInfo, CommandCenterRevisionConflictError, type CommandCenterStore, type CommandCenterStoreMode, type CommandEvent, type CommandLayoutEnvelope, type CompositeAuthorizationDecision, type CompositeAuthorizationReason, type CompositeAuthorizer, type ControlStore, type ControlStoreMode, type CreateAutomationInput, type CreateBlindRelayOptions, type CreateClaudeProviderOptions, type CreateCloudDeviceEnrollmentConfirmerOptions, type CreateCloudDeviceEnrollmentRecoveryLoopOptions, type CreateCloudHostRuntimeOptions, type CreateCloudRelayDeviceEnrollmentSagaOptions, type CreateCodexProfileClientLifecycleOptions, type CreateCodexProviderOptions, type CreateCompositeAuthorizerOptions, type CreateInstalledAdapterProviderOptions, type CreatePeerInput, type CreatePluginRuntimeOptions, type CreatePushDispatcherDeps, type CreateRelayAccountInput, type CreateServerDeps, type CreateServerResult, type CreateSessionAutomationInput, type CreateSessionAutomationRunInput, type CreateWebPushSendOptions, type CreateWorktreeInput, type CreateWorktreeResult, type CreateWorktreeServiceOptions, DEFAULT_CLOUD_CONTROL_PLANE_URL, type DeviceEnrollment, type DeviceInfo, DevicePairingError, type DeviceRelayIdentity, type DeviceScope, type DeviceStore, type DirEntry, type DirListing, type DirSearchResult, type DurableRelayIdentity, type EnterprisePolicy, type EnterprisePolicyAction, type EnterprisePolicyContext, type EnterprisePolicyDecision, EnterprisePolicyRevisionConflictError, type EnterprisePolicyUpdate, ExtensionError, type ExtensionKind, type ExtensionManager, type ExtensionManifestV1, type ExtensionPolicyMode, type ExtensionTrust, type ExtensionVersionRecord, FETCH_TIMEOUT_MS, type FetchLatest, type FetchManifest, type FetchReleases, FsError, type FsErrorCode, FsService, type FsServiceOptions, type GitHubRelease, type HooksSettingsDocument, type HostRecord, INPUT_LEASE_TTL_MS, type IPty, type IdempotencyRecord, type InputLease, type InputLeaseAcquireResult, type InputLeaseActorType, InputLeaseCoordinator, type InputLeaseCoordinatorOptions, type InputLeaseEvent, type InputLeasePrincipal, type InstallExtensionInput, type InstallServiceContext, type InstallServiceResult, type InstallationKind, type InstalledExtension, type LaunchIntent, type LoopbackRelayHttpOptions, type LoopbackRelayTerminalOptions, type ManagedInstallOptions, type ManagedInstallResult, type ManagedInstallStatus, type ManagedPaths, type MarketplaceEntry, type McpConfigDocument, type ModelWeekBar, type NodeAlias, type NodeRecord, OPENAI_CODE_SIGNING_TEAM_ID, type OpenApiBuildOptions, type OpenCloudAuthorizationStoreOptions, type OpenCommandCenterStoreOptions, type OpenControlStoreOptions, type OpenDeviceStoreOptions, type OpenExtensionManagerOptions, type OpenPeerStoreOptions, type OpenPolicyStoreOptions, type OpenPushStoreOptions, type OpenRelayAccountStoreOptions, type OpenRelayRouteStoreOptions, type OpenSessionAutomationStoreOptions, type OpenSessionStoreOptions, type OpenTeamStoreOptions, type OriginCheckOptions, type OwnerRef, PAIRING_TTL_MS, PRESENCE_HEARTBEAT_MS, PRESENCE_TTL_MS, PWA_BOOT_WATCHDOG_SHA256, PWA_CONTENT_SECURITY_POLICY, type PairingTicket, type PaneStatus, type PeerAction, type PeerConnection, type PeerJsonResponse, type PeerRecord, PeerRequestError, PeerRevisionConflictError, type PeerStatus, type PeerStore, type PeerStoreMode, type PendingCloudDevicePromotion, type PersistedRelayHostConfig, type PluginAuditEvent, type PluginManifestV1, type PluginPermission, type PluginRunInput, type PluginRunResult, type PluginRuntime, PluginRuntimeError, type PolicyStore, type PolicyStoreMode, PresenceCoordinator, type PresenceCoordinatorOptions, type PresenceEvent, type PresenceHeartbeatInput, type PresenceMode, type PresenceRecord, type PresenceTarget, type ProcessLifecycleHandle, type ProcessLifecycleOptions, type ProcessLifecycleTarget, type ProcessSpec, type ProductContext, type ProviderAdapterV1, type ProviderAvailability, ProviderError, type ProviderId, ProviderOptionsError, type ProviderProcessContext, ProviderRegistry, type ProviderRuntimeSignal, type ProviderRuntimeSignalParser, type ProviderSessionOptions, type PtySpawn, type PublicRelayRouteRecord, type PushDispatcher, type PushEvent, type PushEventKind, type PushPayload, type PushRecipient, type PushSendFn, type PushStore, type PushSubscriptionRecord, RELAY_CHANNEL_MAX_AGE_MS, RELAY_CHANNEL_MAX_FRAMES, RELAY_HANDSHAKE_MAX_SKEW_MS, RELAY_MAX_PLAINTEXT_BYTES, RELAY_PROTOCOL_VERSION, RELAY_RPC_MAX_BODY_BYTES, RELAY_RPC_MAX_PATH_BYTES, RELAY_WIRE_MAX_ENVELOPE_BYTES, RELAY_WIRE_PROTOCOL_VERSION, RUNNING_BUILD, RUNNING_VERSION, type RateLimitDecision, RateLimiter, type RateLimiterOptions, type RegisterStaticOptions, type RelayAccountCredentialInput, type RelayAccountCredentialMaterial, type RelayAccountPlan, type RelayAccountRecord, RelayAccountRevisionConflictError, type RelayAccountStatus, type RelayAccountStore, type RelayAccountStoreMode, type RelayChannelOptions, RelayCipherState, RelayCryptoError, type RelayCryptoErrorCode, type RelayDeviceProvisioner, type RelayDeviceProvisionerOptions, type RelayDeviceRouteRecord, type RelayDirection, type RelayEncryptedFrame, type RelayEphemeralKeyPair, type RelayFrameKind, type RelayHandshakeHello, type RelayHostConfigInput, type RelayHostConnector, type RelayHostConnectorOptions, type RelayHostMetrics, type RelayHostRuntimeConfig, type RelayHostStatus, type RelayHttpBridge, type RelayHttpHandlers, type RelayHttpOpenRequest, type RelayHttpOpener, type RelayHttpResponseHead, type RelayIdentity, type RelayIdentityStoreOptions, type RelayPairingBootstrap, type RelayPairingPackage, type RelayRole, type RelayRouteRecord, type RelayRouteStore, type RelayRpcMethod, type RelayRpcRequest, type RelayRpcResponse, type RelayStoreMode, type RelayTerminalBridge, type RelayTerminalHandlers, type RelayTerminalOpenRequest, type RelayTerminalOpener, type RelayWireEnvelope, type ReleaseRecord, type RenderLaunchdOptions, type RenderSystemdOptions, type ResolveAccessTokenOptions, type ResolveCodexExecutableOptions, type ResolveCodexThreadOptions, type ResolveVapidKeysOptions, type ResolvedCloudHostConfig, type ReturnTypeOfDescriptors, type RunClaudeVersion, type RunUsage, SEARCH_MAX_DEPTH, SEARCH_MAX_DIRS, SEARCH_MAX_RESULTS, SERVER_PACKAGE, SHELL_PATH_ALLOWLIST, type ServerConfig, type ServerRuntimeConfig, type ServiceRecord, type SessionAutomationDefinition, SessionAutomationRevisionConflictError, type SessionAutomationRun, type SessionAutomationRunStatus, type SessionAutomationStore, type SessionAutomationStoreMode, type SessionAutomationTrigger, type SessionDefaults, SessionDefaultsConflictError, type SessionFileDirection, type SessionFileKind, type SessionFileStorage, type SessionPlacement, type SessionStore, type SignedCloudAuthorizationKeyset, SignedCloudAuthorizationKeysetSchema, SignedCloudAuthorizationKeysetSignatureV1Schema, SignedCloudAuthorizationKeysetSignatureV2Schema, type SignedCloudAuthorizationKeysetV1, SignedCloudAuthorizationKeysetV1Schema, type SignedCloudAuthorizationKeysetV2, SignedCloudAuthorizationKeysetV2Schema, type SignedCloudAuthorizationSnapshot, SignedCloudAuthorizationSnapshotSchema, type SignedCloudAuthorizationSnapshotV1, SignedCloudAuthorizationSnapshotV1Schema, type SignedCloudAuthorizationSnapshotV2, SignedCloudAuthorizationSnapshotV2Schema, type StartServerOptions, type StartedBlindRelay, type StoreMode, type StoredCloudAuthorizationSnapshot, type StoredExternalSession, type StoredSession, type StoredSessionDefaults, type StoredSessionFile, type StoredStatus, type TeamAuthorizationDecision, type TeamAuthorizationResource, type TeamMember, type TeamMemberKind, type TeamMemberStatus, type TeamPermission, type TeamPrincipalBinding, type TeamPrincipalType, type TeamRecord, TeamRevisionConflictError, type TeamRole, type TeamRoleBinding, type TeamScopeType, type TeamStore, type TeamStoreMode, TerminalManager, type TerminalManagerDeps, type TerminalMeta, TerminalProcess, type TerminalProcessOptions, type TerminalSub, USAGE_CACHE_MS, USAGE_TIMEOUT_MS, type UpdateAction, type UpdateAutomationInput, type UpdatePeerInput, type UpdatePolicyMode, type UpdateRelayAccountInput, type UpdateSessionAutomationInput, type UpdateState, type UpdateStatus, Updater, type UpdaterDeps, type UpdaterFs, type UsageInfo, UsageService, type UsageServiceDeps, type VapidKeys, type VerifiedPeerIdentity, type VersionInfo, WS_TICKET_TTL_MS, type WorkspaceKind, type WorkspaceRecord, WorktreeError, type WorktreeErrorCode, type WorktreeRecord, type WorktreeService, type WsTicketContext, WsTicketStore, type WsTicketStoreOptions, adapterCapabilityNames, agentRuntimeId, assertConfigAllowsStart, buildCodexArgs, buildHooksSettingsDocument, buildMcpConfigDocument, buildOpenApiDocument, buildPushPayload, buildRelayPairingUrl, buildServicePath, canonicalCloudJson, capturePane, classifierVersionWarning, classifyCodexPane, classifyPaneStatus, claudePreflightWarning, cloudAuthorizationKeysetSigningPayload, cloudAuthorizationSnapshotSigningPayload, cloudAuthorizationTrustedKeysFromKeyset, cloudDeviceEnrollmentAuthorizationReady, cloudHostCapabilities, cloudHostConfigPath, cloudStatusResponse, codexClassifierVersionWarning, compareVersions, computeBuildDrift, computeInstallDrift, createBlindRelayServer, createClaudeAuthService, createClaudeLatestService, createClaudeMetadataRunner, createClaudeProvider, createClaudeVersionProbe, createCloudDeviceEnrollmentConfirmer, createCloudDeviceEnrollmentRecoveryLoop, createCloudHostRuntime, createCloudRelayDeviceEnrollmentSaga, createCodexOscParser, createCodexProfileClientLifecycle, createCodexProvider, createCodexThreadInventory, createCodexThreadPersistence, createCompositeAuthorizer, createInstalledAdapterProvider, createLoopbackRelayHttpOpener, createLoopbackRelayTerminalOpener, createPluginRuntime, createPushDispatcher, createRelayDeviceProvisioner, createRelayHandshakeHello, createRelayHostConnector, createServer, createUpdater, createUsageRunner, createUsageService, createWebPushSend, createWorktreeService, currentAgentIdForSession, decodeRelayWireEnvelope, defaultFetchManifest, defaultFetchReleases, defaultProbeCodexExecutable, defaultRunClaudeVersion, defaultUpdaterFs, defineAdapterManifest, detectTerminalSupport, enableService, encodeRelayWireEnvelope, ensureDataDir, establishRelayChannel, evaluateEnterprisePolicy, extractBearerToken, extractLoginUrl, generateAccessToken, generateRelayAccountCredential, generateRelayCredential, generateRelayEphemeralKeyPair, generateRelayIdentity, hasEncodedSep, hkdfSha256, hookAuthFileContent, hookAuthPathFor, hooksSettingsPathFor, inspectExtensionPackage, installManagedRelease, installProcessLifecycle, installService, isCodexProfileClientLifecycle, isLoopbackAddress, isNewerMajorMinor, isOriginAllowed, isPublicForRequest, isPublicPath, isRelayDirectExecution, isShellPath, isStableVersion, isTeamRole, isTeamScopeType, listTmuxSessions, loadConfig, loadOrCreateRelayIdentity, loadServerConfig, looksLikeAssetRequest, managedPaths, mcpConfigPathFor, migrateServiceToLauncher, normalizeAutomationAction, normalizeAutomationInput, normalizeAutomationTrigger, normalizeCloudControlPlaneOrigin, normalizeCommandCenterLabel, normalizeDeviceName, normalizeDeviceScopes, normalizeOrigin, normalizePeerBaseUrl, normalizeProviderAvailability, normalizeRelayAppUrl, normalizeRelease, normalizeSessionDefaults, openCloudAuthorizationStore, openCommandCenterStore, openControlStore, openDeviceStore, openExtensionManager, openPeerStore, openPolicyStore, openPushStore, openRelayAccountStore, openRelayRouteStore, openSessionAutomationStore, openSessionStore, openTeamStore, ownerFromProductContext, parseAllowedOrigins, parseAuthStatus, parseClaudeVersion, parseCloudAuthorizationKeyset, parseCloudAuthorizationSnapshot, parseCloudHostHeartbeat, parseCodexOscNotifications, parseCodexVersion, parseLegacyClaudeArgs, parseMarketplaceIndex, parseNpmLatest, parseProviderOptions, parseRelayRpcRequest, parseReleaseNotes, parseSignedCloudAuthorizationSnapshot, parseUsage, pathForGate, persistAccessToken, privacySafeAuditMetadata, productContextFromOwner, projectAgentRuntimeRecords, projectNodeRecord, providerPreflightWarning, publicAdapterDescriptor, readActiveVersion, readCloudHostConfig, readCloudHostCredentialFile, readPreviousVersion, readRelayHostConfig, readServiceRecord, registerStatic, relativeWhen, relayAccountCredentialHash, relayAccountCredentialLookup, relayConnectUrl, relayCredentialHash, relayHostConfigPath, relayIdentityFingerprint, relayRpcResponse, removeCloudHostConfig, removeRelayHostConfig, renderLaunchdPlist, renderManagedLauncher, renderSystemdUnit, replaceCloudHostAuthorizationKeyset, requestPeerJson, resetCodexThreadResolutionCoordinatorForTests, resolveAccessToken, resolveCloudDeviceEnrollmentConfig, resolveCloudHostConfig, resolveCodexExecutable, resolveDataDir, resolveInstallRoot, resolveRelayHostConfig, resolveVapidKeys, restartService, runClaudePreflight, runProviderPreflight, safeProcessErrorSummary, searchMarketplace, stableReleases, startBlindRelay, startServer, teamRolePermissions, tmuxSessionName, validateAdapterManifest, validateAdapterOptionSchema, validateRelayIdentity, verifyPeerConnection, verifyRelayHandshakeHello, verifySignedCloudAuthorizationKeyset, verifySignedCloudAuthorizationSnapshot, writeCloudHostConfig, writeManagedLauncher, writeRelayHostConfig };