@rstreamlabs/tunnels 3.2.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -39,10 +39,18 @@ __export(index_exports, {
39
39
  RstreamTunnelsClient: () => RstreamTunnelsClient,
40
40
  RstreamTunnelsResource: () => RstreamTunnelsResource,
41
41
  RstreamTunnelsRessource: () => RstreamTunnelsResource,
42
+ RstreamWebTTYResource: () => RstreamWebTTYResource,
42
43
  RstreamWebhookResource: () => RstreamWebhookResource,
43
44
  RstreamWebhookRessource: () => RstreamWebhookResource,
44
45
  Tunnels: () => RstreamTunnelsClient,
46
+ WEBHOOK_DELIVERY_ID_HEADER: () => WEBHOOK_DELIVERY_ID_HEADER,
47
+ WEBHOOK_EVENT_ID_HEADER: () => WEBHOOK_EVENT_ID_HEADER,
48
+ WEBHOOK_EVENT_TYPE_HEADER: () => WEBHOOK_EVENT_TYPE_HEADER,
49
+ WEBHOOK_ID_HEADER: () => WEBHOOK_ID_HEADER,
50
+ WEBHOOK_SIGNATURE_HEADER: () => WEBHOOK_SIGNATURE_HEADER,
45
51
  Watch: () => Watch,
52
+ attachWebTTYParticipantParamsSchema: () => attachWebTTYParticipantParamsSchema,
53
+ buildWebhookHeaders: () => buildWebhookHeaders,
46
54
  clientFilterSchema: () => clientFilterSchema,
47
55
  clientSchema: () => clientSchema,
48
56
  createAPITURNCredentials: () => createAPITURNCredentials,
@@ -50,28 +58,59 @@ __export(index_exports, {
50
58
  createAuthTokenFromClientCredentials: () => createAuthTokenFromClientCredentials,
51
59
  createPATTURNCredentials: () => createPATTURNCredentials,
52
60
  createTURNCredentials: () => createTURNCredentials,
61
+ createWebTTYControlRequestParamsSchema: () => createWebTTYControlRequestParamsSchema,
62
+ detachWebTTYParticipantParamsSchema: () => detachWebTTYParticipantParamsSchema,
53
63
  engineOpenApiDocument: () => engineOpenApiDocument,
54
64
  engineOpenApiJson: () => engineOpenApiJson,
55
65
  eventSchema: () => eventSchema,
66
+ formatStreamAccessPath: () => formatStreamAccessPath,
56
67
  formatTunnelHost: () => formatTunnelHost,
68
+ generateWebhookSigningSecret: () => generateWebhookSigningSecret,
57
69
  listClientsParamsSchema: () => listClientsParamsSchema,
58
70
  listClientsResponseSchema: () => listClientsResponseSchema,
59
71
  listTunnelsParamsSchema: () => listTunnelsParamsSchema,
60
72
  listTunnelsResponseSchema: () => listTunnelsResponseSchema,
73
+ listWebTTYControlRequestsParamsSchema: () => listWebTTYControlRequestsParamsSchema,
74
+ listWebTTYKeyGrantDecryptMaterialParamsSchema: () => listWebTTYKeyGrantDecryptMaterialParamsSchema,
75
+ listWebTTYSessionGroupsParamsSchema: () => listWebTTYSessionGroupsParamsSchema,
76
+ listWebTTYSessionsParamsSchema: () => listWebTTYSessionsParamsSchema,
61
77
  normalizeEngineAddress: () => normalizeEngineAddress,
62
78
  parseWebTTYServers: () => parseWebTTYServers,
63
79
  projectLogEventsSchema: () => projectLogEventsSchema,
80
+ readWebTTYSessionEventsParamsSchema: () => readWebTTYSessionEventsParamsSchema,
64
81
  resolveControlPlaneCredentials: () => resolveControlPlaneCredentials,
65
82
  resolveManagedTunnelsProject: () => resolveManagedTunnelsProject,
66
83
  resolveTunnelsAPIURL: () => resolveTunnelsAPIURL,
67
84
  resolveTunnelsCredentials: () => resolveTunnelsCredentials,
68
85
  resolveTunnelsEngine: () => resolveTunnelsEngine,
86
+ resolveWebTTYControlRequestParamsSchema: () => resolveWebTTYControlRequestParamsSchema,
87
+ signWebhookPayload: () => signWebhookPayload,
69
88
  streamEndpointSchema: () => streamEndpointSchema,
89
+ streamEntrySchema: () => streamEntrySchema,
70
90
  streamSummaryEventSchema: () => streamSummaryEventSchema,
71
91
  streamSummarySchema: () => streamSummarySchema,
72
92
  streamTLSInfoSchema: () => streamTLSInfoSchema,
93
+ streamWebTTYMetadataSchema: () => streamWebTTYMetadataSchema,
73
94
  tunnelFilterSchema: () => tunnelFilterSchema,
74
95
  turnCredentialModeSchema: () => turnCredentialModeSchema,
96
+ webTTYCapabilitiesSchema: () => webTTYCapabilitiesSchema,
97
+ webTTYContextMetadataSchema: () => webTTYContextMetadataSchema,
98
+ webTTYControlRequestSchema: () => webTTYControlRequestSchema,
99
+ webTTYCryptoMetadataSchema: () => webTTYCryptoMetadataSchema,
100
+ webTTYEncryptionModeSchema: () => webTTYEncryptionModeSchema,
101
+ webTTYKeyGrantDecryptMaterialSchema: () => webTTYKeyGrantDecryptMaterialSchema,
102
+ webTTYKeyGrantSchema: () => webTTYKeyGrantSchema,
103
+ webTTYOriginSchema: () => webTTYOriginSchema,
104
+ webTTYParticipantLiveSchema: () => webTTYParticipantLiveSchema,
105
+ webTTYParticipantRoleSchema: () => webTTYParticipantRoleSchema,
106
+ webTTYParticipantSchema: () => webTTYParticipantSchema,
107
+ webTTYRecordingModeSchema: () => webTTYRecordingModeSchema,
108
+ webTTYSessionEventSchema: () => webTTYSessionEventSchema,
109
+ webTTYSessionGroupSchema: () => webTTYSessionGroupSchema,
110
+ webTTYSessionLiveSchema: () => webTTYSessionLiveSchema,
111
+ webTTYSessionModeSchema: () => webTTYSessionModeSchema,
112
+ webTTYSessionSchema: () => webTTYSessionSchema,
113
+ webTTYTransportSchema: () => webTTYTransportSchema,
75
114
  webhookEventsSchema: () => webhookEventsSchema,
76
115
  webttyServerSchema: () => webttyServerSchema,
77
116
  wsEventsSchema: () => wsEventsSchema
@@ -294,191 +333,264 @@ var RstreamClientsResource = class {
294
333
  }
295
334
  };
296
335
 
297
- // src/stream.ts
336
+ // src/webtty-schemas.ts
298
337
  var z2 = __toESM(require("zod"));
299
- var nonEmptyStringSchema = z2.string().min(1);
300
- var isoDateTimeSchema = z2.string().datetime({ offset: true });
301
- var ipAddressSchema = z2.string();
302
- var intNonNegSchema = z2.number().int().nonnegative();
303
- var numNonNegSchema = z2.number().nonnegative();
304
- var geolocationSchema = z2.object({
305
- country: z2.string().optional(),
306
- region: z2.string().optional()
338
+ var webTTYTransportSchema = z2.enum([
339
+ "plain",
340
+ "websocket",
341
+ "webtransport"
342
+ ]);
343
+ var webTTYRecordingModeSchema = z2.enum(["recorded", "private"]);
344
+ var webTTYEncryptionModeSchema = z2.enum(["managed", "e2e"]);
345
+ var webTTYSessionModeSchema = z2.enum([
346
+ "interactive",
347
+ "non-interactive"
348
+ ]);
349
+ var webTTYOriginSchema = z2.enum([
350
+ "human",
351
+ "codex",
352
+ "api",
353
+ "automation",
354
+ "ci",
355
+ "scheduled-job"
356
+ ]);
357
+ var webTTYParticipantRoleSchema = z2.enum(["controller", "spectator"]);
358
+ var webTTYInitiatorKindSchema = z2.enum([
359
+ "user",
360
+ "app",
361
+ "agent",
362
+ "service-account"
363
+ ]);
364
+ var webTTYContextMetadataSchema = z2.object({
365
+ origin: webTTYOriginSchema.optional(),
366
+ origin_id: z2.string().optional(),
367
+ purpose: z2.string().optional(),
368
+ initiator_kind: webTTYInitiatorKindSchema.optional(),
369
+ agent_name: z2.string().optional(),
370
+ agent_version: z2.string().optional(),
371
+ request_id: z2.string().optional(),
372
+ labels: z2.record(z2.string(), z2.string()).optional()
373
+ }).passthrough();
374
+
375
+ // src/stream.ts
376
+ var z3 = __toESM(require("zod"));
377
+ var nonEmptyStringSchema = z3.string().min(1);
378
+ var isoDateTimeSchema = z3.string().datetime({ offset: true });
379
+ var ipAddressSchema = z3.string();
380
+ var intNonNegSchema = z3.number().int().nonnegative();
381
+ var numNonNegSchema = z3.number().nonnegative();
382
+ var geolocationSchema = z3.object({
383
+ country: z3.string().optional(),
384
+ region: z3.string().optional()
307
385
  });
308
- var streamTLSInfoSchema = z2.object({
309
- version: z2.string().min(1).optional(),
310
- cipher: z2.string().min(1).optional(),
311
- protocol: z2.string().min(1).optional(),
312
- curve: z2.string().min(1).optional(),
313
- ech: z2.boolean().optional()
386
+ var streamTLSInfoSchema = z3.object({
387
+ version: z3.string().min(1).optional(),
388
+ cipher: z3.string().min(1).optional(),
389
+ protocol: z3.string().min(1).optional(),
390
+ curve: z3.string().min(1).optional(),
391
+ ech: z3.boolean().optional()
314
392
  });
315
- var streamEndpointSchema = z2.object({
393
+ var streamEndpointSchema = z3.object({
316
394
  ip: ipAddressSchema.optional(),
317
395
  geolocation: geolocationSchema.optional(),
318
396
  tls: streamTLSInfoSchema.optional()
319
397
  });
320
- var httpHeadersSchema = z2.record(
321
- z2.string(),
322
- z2.union([z2.string(), z2.array(z2.string())])
398
+ var httpHeadersSchema = z3.record(
399
+ z3.string(),
400
+ z3.union([z3.string(), z3.array(z3.string())])
323
401
  );
324
- var httpProtocolSchema = z2.enum(["http/1.1", "h2", "h2c", "h3"]);
325
- var httpRequestSchema = z2.object({
402
+ var httpProtocolSchema = z3.enum(["http/1.1", "h2", "h2c", "h3"]);
403
+ var httpRequestSchema = z3.object({
326
404
  method: nonEmptyStringSchema,
327
- scheme: z2.string().min(1).optional(),
405
+ scheme: z3.string().min(1).optional(),
328
406
  host: nonEmptyStringSchema.optional(),
329
407
  path: nonEmptyStringSchema.optional(),
330
- query: z2.string().optional(),
408
+ query: z3.string().optional(),
331
409
  url: nonEmptyStringSchema.optional(),
332
410
  headers: httpHeadersSchema.optional(),
333
- userAgent: z2.string().optional()
411
+ userAgent: z3.string().optional()
334
412
  });
335
- var httpResponseSchema = z2.object({
336
- status: z2.number().int().min(100).max(999),
413
+ var httpResponseSchema = z3.object({
414
+ status: z3.number().int().min(100).max(999),
337
415
  headers: httpHeadersSchema.optional()
338
416
  });
339
- var httpRequestStageSchema = z2.object({
417
+ var httpRequestStageSchema = z3.object({
340
418
  protocol: httpProtocolSchema.optional(),
341
419
  request: httpRequestSchema
342
420
  });
343
- var httpResponseStageSchema = z2.object({
421
+ var httpResponseStageSchema = z3.object({
344
422
  protocol: httpProtocolSchema.optional(),
345
423
  response: httpResponseSchema
346
424
  });
347
- var tokenSourceSchema = z2.enum([
425
+ var streamEntrySchema = z3.object({
426
+ kind: z3.enum([
427
+ "published_tunnel",
428
+ "private_rstream",
429
+ "proxy_egress",
430
+ "internal"
431
+ ]),
432
+ transport: z3.enum(["rstream", "tls", "quic", "dtls", "http", "tcp"]).optional()
433
+ });
434
+ var tokenSourceSchema = z3.enum([
348
435
  "authorization",
349
436
  "query",
350
437
  "client",
351
438
  "unknown"
352
439
  ]);
353
- var tokenTypeSchema = z2.enum(["auth", "pat", "app", "unknown"]);
354
- var firewallRuleSchema = z2.discriminatedUnion("kind", [
355
- z2.object({ kind: z2.literal("none") }),
356
- z2.object({ kind: z2.literal("mtls") }),
357
- z2.object({
358
- kind: z2.literal("rstream_auth"),
359
- source: z2.literal("rstream_auth")
440
+ var tokenTypeSchema = z3.enum(["auth", "pat", "app", "unknown"]);
441
+ var firewallRuleSchema = z3.discriminatedUnion("kind", [
442
+ z3.object({ kind: z3.literal("none") }),
443
+ z3.object({ kind: z3.literal("mtls") }),
444
+ z3.object({
445
+ kind: z3.literal("rstream_auth"),
446
+ source: z3.literal("rstream_auth")
360
447
  }),
361
- z2.object({
362
- kind: z2.literal("token"),
448
+ z3.object({
449
+ kind: z3.literal("rstream"),
450
+ source: z3.literal("private_rstream").optional()
451
+ }),
452
+ z3.object({
453
+ kind: z3.literal("token"),
363
454
  source: tokenSourceSchema.optional(),
364
455
  tokenType: tokenTypeSchema.optional()
365
456
  })
366
457
  ]);
367
- var unauthorizedSourceSchema = z2.object({
458
+ var unauthorizedSourceSchema = z3.object({
368
459
  source: tokenSourceSchema
369
460
  });
370
- var unauthorizedReasonSchema = (shape) => z2.object(shape).merge(unauthorizedSourceSchema);
371
- var unauthorizedSchema = z2.discriminatedUnion("reason", [
461
+ var unauthorizedReasonSchema = (shape) => z3.object(shape).merge(unauthorizedSourceSchema);
462
+ var unauthorizedSchema = z3.discriminatedUnion("reason", [
372
463
  unauthorizedReasonSchema({
373
- reason: z2.literal("missing_token")
464
+ reason: z3.literal("missing_token")
374
465
  }),
375
466
  unauthorizedReasonSchema({
376
- reason: z2.literal("invalid_token")
467
+ reason: z3.literal("invalid_token")
377
468
  }),
378
469
  unauthorizedReasonSchema({
379
- reason: z2.literal("expired_token")
470
+ reason: z3.literal("expired_token")
380
471
  }),
381
472
  unauthorizedReasonSchema({
382
- reason: z2.literal("invalid_secret")
473
+ reason: z3.literal("invalid_secret")
383
474
  }),
384
475
  unauthorizedReasonSchema({
385
- reason: z2.literal("user_mismatch")
476
+ reason: z3.literal("user_mismatch")
386
477
  }),
387
478
  unauthorizedReasonSchema({
388
- reason: z2.literal("insufficient_scope")
479
+ reason: z3.literal("insufficient_scope")
389
480
  }),
390
481
  unauthorizedReasonSchema({
391
- reason: z2.literal("policy_denied"),
392
- policy: z2.enum(["ip", "geo", "mtls", "challenge", "other"]),
393
- value: z2.string().optional()
482
+ reason: z3.literal("policy_denied"),
483
+ policy: z3.enum(["ip", "geo", "mtls", "challenge", "other"]),
484
+ value: z3.string().optional()
394
485
  })
395
486
  ]);
396
- var failureSchema = z2.discriminatedUnion("kind", [
397
- z2.object({
398
- kind: z2.literal("timeout"),
487
+ var failureSchema = z3.discriminatedUnion("kind", [
488
+ z3.object({
489
+ kind: z3.literal("timeout"),
399
490
  timeoutMs: intNonNegSchema.optional(),
400
- message: z2.string().optional()
491
+ message: z3.string().optional()
401
492
  }),
402
- z2.object({
403
- kind: z2.literal("unauthorized"),
493
+ z3.object({
494
+ kind: z3.literal("unauthorized"),
404
495
  why: unauthorizedSchema,
405
- message: z2.string().optional()
496
+ message: z3.string().optional()
406
497
  }),
407
- z2.object({
408
- kind: z2.literal("not_found"),
409
- resource: z2.enum(["tunnel", "client", "route"]),
410
- message: z2.string().optional()
498
+ z3.object({
499
+ kind: z3.literal("not_found"),
500
+ resource: z3.enum(["tunnel", "client", "route"]),
501
+ message: z3.string().optional()
411
502
  }),
412
- z2.object({
413
- kind: z2.literal("refused"),
414
- reason: z2.enum(["capacity", "policy", "unsupported", "other"]),
415
- message: z2.string().optional()
503
+ z3.object({
504
+ kind: z3.literal("refused"),
505
+ reason: z3.enum(["capacity", "policy", "unsupported", "other"]),
506
+ message: z3.string().optional()
416
507
  }),
417
- z2.object({ kind: z2.literal("io"), message: z2.string().optional() }),
418
- z2.object({ kind: z2.literal("internal"), message: z2.string().optional() })
508
+ z3.object({ kind: z3.literal("io"), message: z3.string().optional() }),
509
+ z3.object({ kind: z3.literal("internal"), message: z3.string().optional() })
419
510
  ]);
420
- var firewallSchema = z2.discriminatedUnion("decision", [
421
- z2.object({ decision: z2.literal("allowed"), rule: firewallRuleSchema }),
422
- z2.object({
423
- decision: z2.literal("denied"),
511
+ var firewallSchema = z3.discriminatedUnion("decision", [
512
+ z3.object({ decision: z3.literal("allowed"), rule: firewallRuleSchema }),
513
+ z3.object({
514
+ decision: z3.literal("denied"),
424
515
  rule: firewallRuleSchema,
425
516
  failure: failureSchema
426
517
  })
427
518
  ]);
428
- var routedTunnelSchema = z2.object({
519
+ var routedTunnelSchema = z3.object({
429
520
  tunnelId: nonEmptyStringSchema.optional(),
430
- tunnelName: z2.string().optional(),
431
- hostname: z2.string().optional(),
432
- protocol: z2.string().optional(),
433
- published: z2.boolean().optional(),
434
- type: z2.string().optional(),
435
- tlsMode: z2.string().optional(),
436
- httpVersion: z2.string().optional(),
437
- httpUseTls: z2.boolean().optional(),
438
- upstreamTls: z2.boolean().optional(),
439
- tokenAuth: z2.boolean().optional(),
440
- mtls_auth: z2.boolean().optional()
521
+ tunnelName: z3.string().optional(),
522
+ hostname: z3.string().optional(),
523
+ protocol: z3.string().optional(),
524
+ published: z3.boolean().optional(),
525
+ type: z3.string().optional(),
526
+ tlsMode: z3.string().optional(),
527
+ httpVersion: z3.string().optional(),
528
+ httpUseTls: z3.boolean().optional(),
529
+ upstreamTls: z3.boolean().optional(),
530
+ tokenAuth: z3.boolean().optional(),
531
+ mtls_auth: z3.boolean().optional()
441
532
  });
442
- var routingSchema = z2.discriminatedUnion("decision", [
443
- z2.object({ decision: z2.literal("routed"), tunnel: routedTunnelSchema }),
444
- z2.object({ decision: z2.literal("not_routed"), failure: failureSchema })
533
+ var routingSchema = z3.discriminatedUnion("decision", [
534
+ z3.object({ decision: z3.literal("routed"), tunnel: routedTunnelSchema }),
535
+ z3.object({ decision: z3.literal("not_routed"), failure: failureSchema })
445
536
  ]);
446
- var streamConnectedMetricsSchema = z2.object({
537
+ var streamConnectedMetricsSchema = z3.object({
447
538
  establish_ms: numNonNegSchema,
448
539
  duration_ms: numNonNegSchema,
449
540
  upstream_bytes: intNonNegSchema,
450
541
  downstream_bytes: intNonNegSchema
451
542
  });
452
- var streamFailedMetricsSchema = z2.object({
543
+ var streamFailedMetricsSchema = z3.object({
453
544
  time_to_fail_ms: numNonNegSchema.optional(),
454
545
  establish_ms: numNonNegSchema.optional()
455
546
  });
456
- var terminationSchema = z2.object({
457
- by: z2.enum(["downstream", "upstream", "server", "unknown"]),
458
- reason: z2.enum(["closed", "reset", "timeout", "error", "unknown"]),
459
- message: z2.string().optional()
547
+ var terminationSchema = z3.object({
548
+ by: z3.enum(["downstream", "upstream", "server", "unknown"]),
549
+ reason: z3.enum(["closed", "reset", "timeout", "error", "unknown"]),
550
+ message: z3.string().optional()
460
551
  });
461
- var responseConnectedSchema = z2.object({
462
- outcome: z2.literal("connected"),
552
+ var responseConnectedSchema = z3.object({
553
+ outcome: z3.literal("connected"),
463
554
  established_at: isoDateTimeSchema,
464
555
  upstream: streamEndpointSchema.optional(),
465
556
  metrics: streamConnectedMetricsSchema,
466
557
  termination: terminationSchema.optional(),
467
558
  http: httpResponseStageSchema.optional()
468
559
  });
469
- var responseFailedSchema = z2.object({
470
- outcome: z2.literal("failed"),
560
+ var responseFailedSchema = z3.object({
561
+ outcome: z3.literal("failed"),
471
562
  failure: failureSchema,
472
563
  upstream: streamEndpointSchema.optional(),
473
564
  metrics: streamFailedMetricsSchema.optional(),
474
565
  termination: terminationSchema.optional(),
475
566
  http: httpResponseStageSchema.optional()
476
567
  });
477
- var responseSchema = z2.discriminatedUnion("outcome", [
568
+ var responseSchema = z3.discriminatedUnion("outcome", [
478
569
  responseConnectedSchema,
479
570
  responseFailedSchema
480
571
  ]);
481
- var streamSummarySchema = z2.object({
572
+ var streamWebTTYMetadataSchema = z3.object({
573
+ server_id: nonEmptyStringSchema.optional(),
574
+ session_id: nonEmptyStringSchema.optional(),
575
+ session_group_id: nonEmptyStringSchema.optional(),
576
+ participant_id: nonEmptyStringSchema.optional(),
577
+ participant_role: webTTYParticipantRoleSchema.optional(),
578
+ controller: z3.boolean().optional(),
579
+ recording_mode: webTTYRecordingModeSchema.optional(),
580
+ encryption_mode: webTTYEncryptionModeSchema.optional(),
581
+ encryption_policy: z3.enum(["disabled", "explicit_key", "workspace_managed"]).optional(),
582
+ e2e: z3.boolean().optional(),
583
+ client_proof: z3.enum(["none", "required"]).optional(),
584
+ session_mode: webTTYSessionModeSchema.optional(),
585
+ downstream_transport: webTTYTransportSchema.optional(),
586
+ upstream_transport: webTTYTransportSchema.optional(),
587
+ origin: webTTYOriginSchema.optional(),
588
+ origin_id: z3.string().optional(),
589
+ initiator_kind: webTTYInitiatorKindSchema.optional(),
590
+ device_id: z3.string().optional(),
591
+ browser_id: z3.string().optional()
592
+ }).passthrough();
593
+ var streamSummarySchema = z3.object({
482
594
  workspace_id: nonEmptyStringSchema.optional(),
483
595
  project_id: nonEmptyStringSchema.optional(),
484
596
  cluster_id: nonEmptyStringSchema.optional(),
@@ -488,80 +600,561 @@ var streamSummarySchema = z2.object({
488
600
  stream_id: nonEmptyStringSchema,
489
601
  created_at: isoDateTimeSchema,
490
602
  terminated_at: isoDateTimeSchema,
491
- request: z2.object({
603
+ request: z3.object({
492
604
  downstream: streamEndpointSchema,
605
+ entry: streamEntrySchema.optional(),
493
606
  http: httpRequestStageSchema.optional()
494
607
  }),
495
608
  firewall: firewallSchema,
496
609
  routing: routingSchema,
610
+ webtty: streamWebTTYMetadataSchema.optional(),
497
611
  response: responseSchema
498
612
  });
613
+ function formatStreamAccessPath(entry) {
614
+ if (!entry) return void 0;
615
+ switch (entry.kind) {
616
+ case "published_tunnel":
617
+ return "Public URL";
618
+ case "private_rstream":
619
+ return "Private rstream dial";
620
+ case "proxy_egress":
621
+ return "Proxy egress";
622
+ case "internal":
623
+ return "Internal";
624
+ default:
625
+ return void 0;
626
+ }
627
+ }
628
+
629
+ // src/webtty-resource.ts
630
+ var z4 = __toESM(require("zod"));
631
+ var isoDateTimeSchema2 = z4.string().datetime({ offset: true });
632
+ var decimalCursorSchema = z4.string().regex(/^\d+$/);
633
+ var webTTYSequenceCursorInputSchema = z4.union([
634
+ decimalCursorSchema,
635
+ z4.number().int().nonnegative().safe().transform(String)
636
+ ]);
637
+ var webTTYSessionStatusSchema = z4.enum([
638
+ "opening",
639
+ "active",
640
+ "closing",
641
+ "closed",
642
+ "errored"
643
+ ]);
644
+ var webTTYControlRequestStatusSchema = z4.enum([
645
+ "pending",
646
+ "granted",
647
+ "refused",
648
+ "revoked",
649
+ "expired"
650
+ ]);
651
+ var webTTYEventDirectionSchema = z4.enum([
652
+ "client_to_server",
653
+ "server_to_client",
654
+ "engine_internal"
655
+ ]);
656
+ var webTTYStreamTypeSchema = z4.enum(["stdin", "stdout", "stderr"]);
657
+ var webTTYSessionEventTypeSchema = z4.enum([
658
+ "open",
659
+ "ack",
660
+ "data",
661
+ "resize",
662
+ "close",
663
+ "error",
664
+ "participant",
665
+ "control",
666
+ "recording_state"
667
+ ]);
668
+ var jsonRecordSchema = z4.record(z4.string(), z4.unknown());
669
+ function rejectCryptoKeyEnvelopes(crypto3, ctx, path) {
670
+ if (crypto3 === null || typeof crypto3 !== "object") {
671
+ return;
672
+ }
673
+ if (Object.prototype.hasOwnProperty.call(crypto3, "key_envelopes")) {
674
+ ctx.addIssue({
675
+ code: z4.ZodIssueCode.custom,
676
+ message: "key_envelopes are available only from the WebTTY decrypt-material endpoint.",
677
+ path: [...path, "key_envelopes"]
678
+ });
679
+ }
680
+ }
681
+ var webTTYCapabilitiesSchema = z4.object({
682
+ managed_protocol: z4.boolean(),
683
+ store_configured: z4.boolean(),
684
+ session_listing: z4.boolean(),
685
+ recording: z4.boolean(),
686
+ replay: z4.boolean(),
687
+ live_attach: z4.boolean(),
688
+ control_transfer: z4.boolean(),
689
+ e2e: z4.boolean(),
690
+ implemented_transports: z4.array(webTTYTransportSchema),
691
+ recording_modes: z4.array(webTTYRecordingModeSchema),
692
+ encryption_modes: z4.array(webTTYEncryptionModeSchema),
693
+ required_permissions: z4.record(z4.string(), z4.array(z4.string()))
694
+ });
695
+ var webTTYSessionLiveSchema = z4.object({
696
+ available: z4.boolean(),
697
+ attachable: z4.boolean(),
698
+ participant_count: z4.number().int().nonnegative(),
699
+ controller_participant_id: z4.string().optional(),
700
+ has_upstream: z4.boolean()
701
+ });
702
+ var webTTYParticipantLiveSchema = z4.object({
703
+ connected: z4.boolean(),
704
+ controller: z4.boolean()
705
+ });
706
+ var webTTYSessionSchema = z4.object({
707
+ id: z4.string(),
708
+ workspace_id: z4.string().optional(),
709
+ project_id: z4.string().optional(),
710
+ cluster_id: z4.string().optional(),
711
+ server_id: z4.string().optional(),
712
+ tunnel_id: z4.string(),
713
+ client_id: z4.string().optional(),
714
+ initiator_user_id: z4.string().optional(),
715
+ group_id: z4.string().optional(),
716
+ status: webTTYSessionStatusSchema,
717
+ session_mode: webTTYSessionModeSchema,
718
+ recording_mode: webTTYRecordingModeSchema,
719
+ encryption_mode: webTTYEncryptionModeSchema,
720
+ downstream_transport: webTTYTransportSchema.optional(),
721
+ upstream_transport: webTTYTransportSchema.optional(),
722
+ command_meta: z4.unknown().optional(),
723
+ context: webTTYContextMetadataSchema.optional(),
724
+ started_at: isoDateTimeSchema2,
725
+ ended_at: isoDateTimeSchema2.optional(),
726
+ exit_code: z4.number().int().optional(),
727
+ error_code: z4.string().optional(),
728
+ error_message: z4.string().optional(),
729
+ live: webTTYSessionLiveSchema.optional()
730
+ }).passthrough();
731
+ var webTTYSessionGroupSchema = z4.object({
732
+ id: z4.string(),
733
+ workspace_id: z4.string().optional(),
734
+ project_id: z4.string().optional(),
735
+ initiator_user_id: z4.string().optional(),
736
+ context: webTTYContextMetadataSchema.optional(),
737
+ created_at: isoDateTimeSchema2,
738
+ updated_at: isoDateTimeSchema2,
739
+ closed_at: isoDateTimeSchema2.optional()
740
+ }).passthrough();
741
+ var webTTYParticipantSchema = z4.object({
742
+ id: z4.string(),
743
+ session_id: z4.string(),
744
+ user_id: z4.string().optional(),
745
+ device_id: z4.string().optional(),
746
+ browser_id: z4.string().optional(),
747
+ role: webTTYParticipantRoleSchema,
748
+ attached_at: isoDateTimeSchema2,
749
+ detached_at: isoDateTimeSchema2.optional(),
750
+ controller: z4.boolean(),
751
+ grant_state: z4.string().optional(),
752
+ attach_grant: z4.string().optional(),
753
+ attach_grant_expires_at: isoDateTimeSchema2.optional(),
754
+ live: webTTYParticipantLiveSchema.optional()
755
+ }).passthrough();
756
+ var webTTYCryptoMetadataSchema = z4.object({
757
+ payload_suite: z4.string().optional(),
758
+ payload_key_id: z4.string().optional(),
759
+ nonce: z4.string().optional(),
760
+ key_envelope_suite: z4.string().optional(),
761
+ key_envelopes: z4.unknown().optional(),
762
+ key_context: z4.unknown().optional(),
763
+ key_context_raw: z4.string().optional()
764
+ }).passthrough();
765
+ var webTTYSessionEventSchema = z4.object({
766
+ id: z4.string(),
767
+ session_id: z4.string(),
768
+ seq: decimalCursorSchema,
769
+ created_at: isoDateTimeSchema2,
770
+ type: webTTYSessionEventTypeSchema,
771
+ direction: webTTYEventDirectionSchema.optional(),
772
+ stream_type: webTTYStreamTypeSchema.optional(),
773
+ participant_id: z4.string().optional(),
774
+ payload_length: z4.number().int().nonnegative().optional(),
775
+ payload_ciphertext: z4.string().optional(),
776
+ payload_plaintext: z4.string().optional(),
777
+ crypto: webTTYCryptoMetadataSchema.optional(),
778
+ prev_hash: z4.string().optional(),
779
+ hash: z4.string().optional(),
780
+ metadata: z4.unknown().optional()
781
+ }).passthrough().superRefine((value, ctx) => {
782
+ rejectCryptoKeyEnvelopes(value.crypto, ctx, ["crypto"]);
783
+ });
784
+ var webTTYKeyGrantBaseShape = {
785
+ id: z4.string(),
786
+ session_id: z4.string(),
787
+ recipient_id: z4.string(),
788
+ recipient_kind: z4.string(),
789
+ granted_by: z4.string().optional(),
790
+ crypto: webTTYCryptoMetadataSchema,
791
+ created_at: isoDateTimeSchema2,
792
+ revoked_at: isoDateTimeSchema2.optional()
793
+ };
794
+ var webTTYKeyGrantSchema = z4.object(webTTYKeyGrantBaseShape).passthrough().superRefine((value, ctx) => {
795
+ if (Object.prototype.hasOwnProperty.call(value, "wrapped_key")) {
796
+ ctx.addIssue({
797
+ code: z4.ZodIssueCode.custom,
798
+ message: "wrapped_key is available only from the WebTTY decrypt-material endpoint.",
799
+ path: ["wrapped_key"]
800
+ });
801
+ }
802
+ rejectCryptoKeyEnvelopes(value.crypto, ctx, ["crypto"]);
803
+ });
804
+ var webTTYKeyGrantDecryptMaterialSchema = z4.object({
805
+ ...webTTYKeyGrantBaseShape,
806
+ wrapped_key: z4.string().optional()
807
+ }).passthrough();
808
+ var webTTYControlRequestSchema = z4.object({
809
+ id: z4.string(),
810
+ session_id: z4.string(),
811
+ requester_participant_id: z4.string(),
812
+ requester_user_id: z4.string().optional(),
813
+ approver_participant_id: z4.string().optional(),
814
+ approver_user_id: z4.string().optional(),
815
+ status: webTTYControlRequestStatusSchema,
816
+ reason: z4.string().optional(),
817
+ metadata: z4.unknown().optional(),
818
+ created_at: isoDateTimeSchema2,
819
+ updated_at: isoDateTimeSchema2,
820
+ resolved_at: isoDateTimeSchema2.optional(),
821
+ expires_at: isoDateTimeSchema2.optional()
822
+ }).passthrough();
823
+ var listWebTTYSessionsFiltersSchema = z4.object({
824
+ server_id: z4.string().optional(),
825
+ tunnel_id: z4.string().optional(),
826
+ user_id: z4.string().optional(),
827
+ group_id: z4.string().optional(),
828
+ origin: webTTYOriginSchema.optional(),
829
+ status: webTTYSessionStatusSchema.optional(),
830
+ started_from: isoDateTimeSchema2.optional(),
831
+ started_to: isoDateTimeSchema2.optional()
832
+ });
833
+ var listWebTTYSessionsParamsSchema = z4.object({
834
+ limit: z4.number().int().min(1).optional(),
835
+ filters: listWebTTYSessionsFiltersSchema.optional()
836
+ });
837
+ var listWebTTYSessionGroupsFiltersSchema = z4.object({
838
+ initiator_user_id: z4.string().optional(),
839
+ origin: webTTYOriginSchema.optional(),
840
+ created_from: isoDateTimeSchema2.optional(),
841
+ created_to: isoDateTimeSchema2.optional()
842
+ });
843
+ var listWebTTYSessionGroupsParamsSchema = z4.object({
844
+ limit: z4.number().int().min(1).optional(),
845
+ filters: listWebTTYSessionGroupsFiltersSchema.optional()
846
+ });
847
+ var readWebTTYSessionEventsParamsSchema = z4.object({
848
+ from_seq: webTTYSequenceCursorInputSchema.optional(),
849
+ limit: z4.number().int().min(1).optional()
850
+ });
851
+ var listWebTTYKeyGrantDecryptMaterialParamsSchema = z4.object({
852
+ recipient_id: z4.string().optional(),
853
+ recipient_kind: z4.string().optional()
854
+ });
855
+ var listWebTTYControlRequestsFiltersSchema = z4.object({
856
+ status: webTTYControlRequestStatusSchema.optional(),
857
+ requester_user_id: z4.string().optional()
858
+ });
859
+ var listWebTTYControlRequestsParamsSchema = z4.object({
860
+ limit: z4.number().int().min(1).optional(),
861
+ filters: listWebTTYControlRequestsFiltersSchema.optional()
862
+ });
863
+ var attachWebTTYParticipantParamsSchema = z4.object({
864
+ role: z4.literal("spectator").optional(),
865
+ device_id: z4.string().optional(),
866
+ browser_id: z4.string().optional(),
867
+ transport: webTTYTransportSchema.optional(),
868
+ grant_state: z4.string().optional(),
869
+ metadata: jsonRecordSchema.optional()
870
+ });
871
+ var detachWebTTYParticipantParamsSchema = z4.object({
872
+ reason: z4.string().optional(),
873
+ metadata: jsonRecordSchema.optional()
874
+ });
875
+ var createWebTTYControlRequestParamsSchema = z4.object({
876
+ participant_id: z4.string(),
877
+ reason: z4.string().optional(),
878
+ metadata: jsonRecordSchema.optional(),
879
+ expires_at: isoDateTimeSchema2.optional()
880
+ });
881
+ var resolveWebTTYControlRequestParamsSchema = z4.object({
882
+ action: z4.enum(["grant", "refuse", "revoke"]),
883
+ approver_participant_id: z4.string().optional(),
884
+ reason: z4.string().optional()
885
+ });
886
+ var webTTYSessionListSchema = z4.array(webTTYSessionSchema);
887
+ var webTTYSessionGroupListSchema = z4.array(webTTYSessionGroupSchema);
888
+ var webTTYParticipantListSchema = z4.array(webTTYParticipantSchema);
889
+ var webTTYSessionEventListSchema = z4.array(webTTYSessionEventSchema);
890
+ var webTTYKeyGrantListSchema = z4.array(webTTYKeyGrantSchema);
891
+ var webTTYKeyGrantDecryptMaterialListSchema = z4.array(
892
+ webTTYKeyGrantDecryptMaterialSchema
893
+ );
894
+ var webTTYControlRequestListSchema = z4.array(webTTYControlRequestSchema);
895
+ function pathId(kind, value) {
896
+ const normalized = value.trim();
897
+ if (!normalized) {
898
+ throw new Error(`${kind} is required.`);
899
+ }
900
+ return encodeURIComponent(normalized);
901
+ }
902
+ function pathWithParams(path, params) {
903
+ if (params === void 0) {
904
+ return path;
905
+ }
906
+ return `${path}?params=${encodeURIComponent(JSON.stringify(params))}`;
907
+ }
908
+ var RstreamWebTTYResource = class {
909
+ client;
910
+ constructor(client) {
911
+ this.client = client;
912
+ }
913
+ async capabilities() {
914
+ const response = await this.client.request(
915
+ "/webtty/capabilities",
916
+ {
917
+ method: "GET"
918
+ }
919
+ );
920
+ return webTTYCapabilitiesSchema.parse(response);
921
+ }
922
+ async listGroups(params) {
923
+ const parsed = params === void 0 ? void 0 : listWebTTYSessionGroupsParamsSchema.parse(params);
924
+ const response = await this.client.request(
925
+ pathWithParams("/webtty/groups", parsed),
926
+ { method: "GET" }
927
+ );
928
+ return webTTYSessionGroupListSchema.parse(response);
929
+ }
930
+ async getGroup(groupId) {
931
+ const response = await this.client.request(
932
+ `/webtty/groups/${pathId("Session group ID", groupId)}`,
933
+ { method: "GET" }
934
+ );
935
+ return webTTYSessionGroupSchema.parse(response);
936
+ }
937
+ async listSessions(params) {
938
+ const parsed = params === void 0 ? void 0 : listWebTTYSessionsParamsSchema.parse(params);
939
+ const response = await this.client.request(
940
+ pathWithParams("/webtty/sessions", parsed),
941
+ { method: "GET" }
942
+ );
943
+ return webTTYSessionListSchema.parse(response);
944
+ }
945
+ async getSession(sessionId) {
946
+ const response = await this.client.request(
947
+ `/webtty/sessions/${pathId("Session ID", sessionId)}`,
948
+ { method: "GET" }
949
+ );
950
+ return webTTYSessionSchema.parse(response);
951
+ }
952
+ async listParticipants(sessionId) {
953
+ const response = await this.client.request(
954
+ `/webtty/sessions/${pathId("Session ID", sessionId)}/participants`,
955
+ { method: "GET" }
956
+ );
957
+ return webTTYParticipantListSchema.parse(response);
958
+ }
959
+ async attachParticipant(sessionId, params = {}) {
960
+ const response = await this.client.request(
961
+ `/webtty/sessions/${pathId("Session ID", sessionId)}/participants`,
962
+ {
963
+ body: JSON.stringify(attachWebTTYParticipantParamsSchema.parse(params)),
964
+ headers: { "Content-Type": "application/json" },
965
+ method: "POST"
966
+ }
967
+ );
968
+ return webTTYParticipantSchema.parse(response);
969
+ }
970
+ async detachParticipant(sessionId, participantId, params = {}) {
971
+ const response = await this.client.request(
972
+ `/webtty/sessions/${pathId("Session ID", sessionId)}/participants/${pathId("Participant ID", participantId)}`,
973
+ {
974
+ body: JSON.stringify(detachWebTTYParticipantParamsSchema.parse(params)),
975
+ headers: { "Content-Type": "application/json" },
976
+ method: "POST"
977
+ }
978
+ );
979
+ return webTTYParticipantSchema.parse(response);
980
+ }
981
+ async readEvents(sessionId, params) {
982
+ const parsed = params === void 0 ? void 0 : readWebTTYSessionEventsParamsSchema.parse(params);
983
+ const response = await this.client.request(
984
+ pathWithParams(
985
+ `/webtty/sessions/${pathId("Session ID", sessionId)}/events`,
986
+ parsed
987
+ ),
988
+ { method: "GET" }
989
+ );
990
+ return webTTYSessionEventListSchema.parse(response);
991
+ }
992
+ async listKeyGrants(sessionId) {
993
+ const response = await this.client.request(
994
+ `/webtty/sessions/${pathId("Session ID", sessionId)}/key-grants`,
995
+ { method: "GET" }
996
+ );
997
+ return webTTYKeyGrantListSchema.parse(response);
998
+ }
999
+ async listKeyGrantDecryptMaterial(sessionId, params) {
1000
+ const parsed = params === void 0 ? void 0 : listWebTTYKeyGrantDecryptMaterialParamsSchema.parse(params);
1001
+ const response = await this.client.request(
1002
+ pathWithParams(
1003
+ `/webtty/sessions/${pathId("Session ID", sessionId)}/key-grants/decrypt-material`,
1004
+ parsed
1005
+ ),
1006
+ { method: "GET" }
1007
+ );
1008
+ return webTTYKeyGrantDecryptMaterialListSchema.parse(response);
1009
+ }
1010
+ async listControlRequests(sessionId, params) {
1011
+ const parsed = params === void 0 ? void 0 : listWebTTYControlRequestsParamsSchema.parse(params);
1012
+ const response = await this.client.request(
1013
+ pathWithParams(
1014
+ `/webtty/sessions/${pathId("Session ID", sessionId)}/control-requests`,
1015
+ parsed
1016
+ ),
1017
+ { method: "GET" }
1018
+ );
1019
+ return webTTYControlRequestListSchema.parse(response);
1020
+ }
1021
+ async createControlRequest(sessionId, params) {
1022
+ const response = await this.client.request(
1023
+ `/webtty/sessions/${pathId("Session ID", sessionId)}/control-requests`,
1024
+ {
1025
+ body: JSON.stringify(
1026
+ createWebTTYControlRequestParamsSchema.parse(params)
1027
+ ),
1028
+ headers: { "Content-Type": "application/json" },
1029
+ method: "POST"
1030
+ }
1031
+ );
1032
+ return webTTYControlRequestSchema.parse(response);
1033
+ }
1034
+ async resolveControlRequest(sessionId, requestId, params) {
1035
+ const response = await this.client.request(
1036
+ `/webtty/sessions/${pathId("Session ID", sessionId)}/control-requests/${pathId("Control request ID", requestId)}`,
1037
+ {
1038
+ body: JSON.stringify(
1039
+ resolveWebTTYControlRequestParamsSchema.parse(params)
1040
+ ),
1041
+ headers: { "Content-Type": "application/json" },
1042
+ method: "POST"
1043
+ }
1044
+ );
1045
+ return webTTYControlRequestSchema.parse(response);
1046
+ }
1047
+ };
499
1048
 
500
1049
  // src/event.ts
501
1050
  var import_tunnel = require("@rstreamlabs/rstream/tunnel");
502
- var z3 = __toESM(require("zod"));
503
- var isoDateTimeSchema2 = z3.string().datetime({ offset: true });
504
- var initialStateSchema = z3.object({
505
- snapshot_at: isoDateTimeSchema2,
506
- clients: z3.array(clientSchema),
507
- tunnels: z3.array(import_tunnel.tunnelSchema)
1051
+ var z5 = __toESM(require("zod"));
1052
+ var isoDateTimeSchema3 = z5.string().datetime({ offset: true });
1053
+ var initialStateSchema = z5.object({
1054
+ snapshot_at: isoDateTimeSchema3,
1055
+ clients: z5.array(clientSchema),
1056
+ tunnels: z5.array(import_tunnel.tunnelSchema)
508
1057
  });
509
- var eventBaseSchema = z3.object({
510
- id: z3.string().optional(),
511
- created_at: isoDateTimeSchema2.optional(),
512
- user_id: z3.string().optional(),
513
- workspace_id: z3.string().optional(),
514
- project_id: z3.string().optional(),
515
- cluster_id: z3.string().optional()
1058
+ var eventBaseSchema = z5.object({
1059
+ id: z5.string().optional(),
1060
+ created_at: isoDateTimeSchema3.optional(),
1061
+ user_id: z5.string().optional(),
1062
+ workspace_id: z5.string().optional(),
1063
+ project_id: z5.string().optional(),
1064
+ cluster_id: z5.string().optional()
516
1065
  });
517
- var withEventBase = (shape) => z3.object(shape).merge(eventBaseSchema).passthrough();
1066
+ var withEventBase = (shape) => z5.object(shape).merge(eventBaseSchema).passthrough();
518
1067
  var stateInitialEventSchema = withEventBase({
519
- type: z3.literal("state.initial"),
1068
+ type: z5.literal("state.initial"),
520
1069
  object: initialStateSchema
521
1070
  });
522
1071
  var streamSummaryEventSchema = withEventBase({
523
- type: z3.literal("stream.summary"),
1072
+ type: z5.literal("stream.summary"),
524
1073
  object: streamSummarySchema
525
1074
  });
526
1075
  var commonEventsSchema = [
527
1076
  withEventBase({
528
- type: z3.literal("client.created"),
1077
+ type: z5.literal("client.created"),
529
1078
  object: clientSchema
530
1079
  }),
531
1080
  withEventBase({
532
- type: z3.literal("client.updated"),
1081
+ type: z5.literal("client.updated"),
533
1082
  object: clientSchema
534
1083
  }),
535
1084
  withEventBase({
536
- type: z3.literal("client.deleted"),
1085
+ type: z5.literal("client.deleted"),
537
1086
  object: clientSchema
538
1087
  }),
539
1088
  withEventBase({
540
- type: z3.literal("tunnel.created"),
1089
+ type: z5.literal("tunnel.created"),
541
1090
  object: import_tunnel.tunnelSchema
542
1091
  }),
543
1092
  withEventBase({
544
- type: z3.literal("tunnel.updated"),
1093
+ type: z5.literal("tunnel.updated"),
545
1094
  object: import_tunnel.tunnelSchema
546
1095
  }),
547
1096
  withEventBase({
548
- type: z3.literal("tunnel.deleted"),
1097
+ type: z5.literal("tunnel.deleted"),
549
1098
  object: import_tunnel.tunnelSchema
550
1099
  })
551
1100
  ];
1101
+ var webTTYEventsSchema = [
1102
+ withEventBase({
1103
+ type: z5.literal("webtty.session.created"),
1104
+ object: webTTYSessionSchema
1105
+ }),
1106
+ withEventBase({
1107
+ type: z5.literal("webtty.session.updated"),
1108
+ object: z5.union([webTTYSessionSchema, webTTYSessionGroupSchema])
1109
+ }),
1110
+ withEventBase({
1111
+ type: z5.literal("webtty.session.ended"),
1112
+ object: webTTYSessionSchema
1113
+ }),
1114
+ withEventBase({
1115
+ type: z5.literal("webtty.participant.joined"),
1116
+ object: webTTYParticipantSchema
1117
+ }),
1118
+ withEventBase({
1119
+ type: z5.literal("webtty.participant.updated"),
1120
+ object: webTTYParticipantSchema
1121
+ }),
1122
+ withEventBase({
1123
+ type: z5.literal("webtty.participant.left"),
1124
+ object: webTTYParticipantSchema
1125
+ }),
1126
+ withEventBase({
1127
+ type: z5.literal("webtty.control.requested"),
1128
+ object: webTTYControlRequestSchema
1129
+ }),
1130
+ withEventBase({
1131
+ type: z5.literal("webtty.control.granted"),
1132
+ object: webTTYControlRequestSchema
1133
+ }),
1134
+ withEventBase({
1135
+ type: z5.literal("webtty.control.refused"),
1136
+ object: webTTYControlRequestSchema
1137
+ }),
1138
+ withEventBase({
1139
+ type: z5.literal("webtty.control.revoked"),
1140
+ object: webTTYControlRequestSchema
1141
+ })
1142
+ ];
552
1143
  var webhookDeliverableEventsSchema = [
553
1144
  commonEventsSchema[0],
554
1145
  commonEventsSchema[2],
555
1146
  commonEventsSchema[3],
556
- commonEventsSchema[5]
1147
+ commonEventsSchema[5],
1148
+ ...webTTYEventsSchema
557
1149
  ];
558
- var wsEventsSchema = z3.union([
1150
+ var wsEventsSchema = z5.union([
559
1151
  stateInitialEventSchema,
560
- ...commonEventsSchema
1152
+ ...commonEventsSchema,
1153
+ ...webTTYEventsSchema
561
1154
  ]);
562
- var webhookEventsSchema = z3.union(webhookDeliverableEventsSchema);
1155
+ var webhookEventsSchema = z5.union(webhookDeliverableEventsSchema);
563
1156
  var projectLogEventsSchema = streamSummaryEventSchema;
564
- var eventSchema = z3.union([
1157
+ var eventSchema = z5.union([
565
1158
  wsEventsSchema,
566
1159
  webhookEventsSchema,
567
1160
  projectLogEventsSchema
@@ -569,7 +1162,7 @@ var eventSchema = z3.union([
569
1162
 
570
1163
  // src/tunnel.ts
571
1164
  var import_tunnel2 = require("@rstreamlabs/rstream/tunnel");
572
- var z4 = __toESM(require("zod"));
1165
+ var z6 = __toESM(require("zod"));
573
1166
  var DEFAULT_PUBLISHED_PORT = 443;
574
1167
  var tunnelFilterSchema = import_tunnel2.tunnelSchema.pick({
575
1168
  id: true,
@@ -584,11 +1177,11 @@ var tunnelFilterSchema = import_tunnel2.tunnelSchema.pick({
584
1177
  http_version: true,
585
1178
  labels: true
586
1179
  }).partial();
587
- var listTunnelsParamsSchema = z4.object({
588
- limit: z4.number().int().min(1).optional(),
1180
+ var listTunnelsParamsSchema = z6.object({
1181
+ limit: z6.number().int().min(1).optional(),
589
1182
  filters: tunnelFilterSchema.optional()
590
1183
  });
591
- var listTunnelsResponseSchema = z4.array(import_tunnel2.tunnelSchema);
1184
+ var listTunnelsResponseSchema = z6.array(import_tunnel2.tunnelSchema);
592
1185
  function formatTunnelHost(tunnel) {
593
1186
  if (!tunnel.hostname) return tunnel.host;
594
1187
  if (!tunnel.port || tunnel.port === DEFAULT_PUBLISHED_PORT) {
@@ -599,7 +1192,7 @@ function formatTunnelHost(tunnel) {
599
1192
 
600
1193
  // src/openapi.ts
601
1194
  var import_tunnel5 = require("@rstreamlabs/rstream/tunnel");
602
- var z5 = __toESM(require("zod"));
1195
+ var z7 = __toESM(require("zod"));
603
1196
  var jsonContentType = "application/json";
604
1197
  var openApiContentType = "application/vnd.oai.openapi+json;version=3.1";
605
1198
  function isRecord(value) {
@@ -613,10 +1206,10 @@ function dropSchemaKeyword(value) {
613
1206
  }
614
1207
  function jsonSchemaFor(schema) {
615
1208
  return dropSchemaKeyword(
616
- z5.toJSONSchema(schema, {
1209
+ z7.toJSONSchema(schema, {
617
1210
  unrepresentable: "any",
618
1211
  override: (ctx) => {
619
- if (ctx.zodSchema instanceof z5.ZodDate) {
1212
+ if (ctx.zodSchema instanceof z7.ZodDate) {
620
1213
  ctx.jsonSchema.type = "string";
621
1214
  ctx.jsonSchema.format = "date-time";
622
1215
  }
@@ -683,7 +1276,7 @@ var readEngineStreamsRules = [
683
1276
  action: "read"
684
1277
  }
685
1278
  ];
686
- var watchParamsSchema = z5.object({
1279
+ var watchParamsSchema = z7.object({
687
1280
  clients: clientFilterSchema.optional(),
688
1281
  tunnels: tunnelFilterSchema.optional()
689
1282
  });
@@ -712,6 +1305,40 @@ var enginePermissions = {
712
1305
  action: ["create", "delete"]
713
1306
  }
714
1307
  ]
1308
+ },
1309
+ "webtty.sessions.read-only": {
1310
+ name: "WebTTY Sessions: Read-Only",
1311
+ description: "List managed WebTTY sessions, participants, replay state, and join as a spectator.",
1312
+ rules: [
1313
+ {
1314
+ resource: "engine.webtty.sessions",
1315
+ action: "read"
1316
+ }
1317
+ ]
1318
+ },
1319
+ "webtty.sessions.read-write": {
1320
+ name: "WebTTY Sessions: Read and Write",
1321
+ description: "Create managed WebTTY sessions and coordinate control requests for active sessions.",
1322
+ rules: [
1323
+ {
1324
+ resource: "engine.webtty.sessions",
1325
+ action: ["read", "write"]
1326
+ }
1327
+ ]
1328
+ },
1329
+ "webtty.logs.read-only": {
1330
+ name: "WebTTY Session Logs: Read-Only",
1331
+ description: "Read managed WebTTY session logs. End-to-end encrypted content still requires trusted local key material.",
1332
+ rules: [
1333
+ {
1334
+ resource: "engine.webtty.sessions",
1335
+ action: "read"
1336
+ },
1337
+ {
1338
+ resource: "engine.webtty.logs",
1339
+ action: "read"
1340
+ }
1341
+ ]
715
1342
  }
716
1343
  };
717
1344
  var engineOpenApiDocument = {
@@ -831,11 +1458,14 @@ var engineOpenApiDocument = {
831
1458
  "tunnels.resources.read-only",
832
1459
  "tunnels.streams.create-delete"
833
1460
  ],
834
- "operate-webtty": [
1461
+ "run-tunnel-webtty": [
835
1462
  "tunnels.resources.read-only",
836
1463
  "tunnels.tunnels.create-delete",
837
1464
  "tunnels.streams.create-delete"
838
- ]
1465
+ ],
1466
+ "join-managed-webtty": ["webtty.sessions.read-only"],
1467
+ "control-managed-webtty": ["webtty.sessions.read-write"],
1468
+ "read-managed-webtty-recordings": ["webtty.logs.read-only"]
839
1469
  },
840
1470
  paths: {
841
1471
  "/api/openapi.json": {
@@ -1103,20 +1733,20 @@ var import_rstream8 = require("@rstreamlabs/rstream");
1103
1733
  var import_rstream9 = require("@rstreamlabs/rstream");
1104
1734
  var import_rstream10 = require("@rstreamlabs/rstream");
1105
1735
  var import_turn = require("@rstreamlabs/rstream/turn");
1106
- var z6 = __toESM(require("zod"));
1736
+ var z8 = __toESM(require("zod"));
1107
1737
  var import_crypto = __toESM(require("crypto"));
1108
1738
  var defaultTURNPort = 3478;
1109
1739
  var defaultTURNSPort = 5349;
1110
1740
  var defaultTURNCredentialTTLSeconds = 10 * 60;
1111
1741
  var maxTURNCredentialTTLSeconds = 60 * 60;
1112
- var turnTokenClaimsSchema = z6.object({
1113
- exp: z6.number().int().optional(),
1114
- iat: z6.number().int().optional(),
1115
- token_endpoint: z6.string().regex(/^[0-9a-f]{8}$/i).optional(),
1116
- tokendpoint: z6.string().regex(/^[0-9a-f]{8}$/i).optional(),
1117
- type: z6.enum(["app", "auth", "pat"])
1742
+ var turnTokenClaimsSchema = z8.object({
1743
+ exp: z8.number().int().optional(),
1744
+ iat: z8.number().int().optional(),
1745
+ token_endpoint: z8.string().regex(/^[0-9a-f]{8}$/i).optional(),
1746
+ tokendpoint: z8.string().regex(/^[0-9a-f]{8}$/i).optional(),
1747
+ type: z8.enum(["app", "auth", "pat"])
1118
1748
  });
1119
- var turnCredentialModeSchema = z6.enum(["api", "app", "pat"]);
1749
+ var turnCredentialModeSchema = z8.enum(["api", "app", "pat"]);
1120
1750
  function normalizeOptionalString2(value) {
1121
1751
  const normalized = value?.trim();
1122
1752
  return normalized ? normalized : void 0;
@@ -1477,9 +2107,18 @@ var RstreamTURNResource = class {
1477
2107
 
1478
2108
  // src/webhooks-resource.ts
1479
2109
  var import_crypto2 = __toESM(require("crypto"));
2110
+ var WEBHOOK_SIGNATURE_HEADER = "rstream-signature";
2111
+ var WEBHOOK_EVENT_ID_HEADER = "rstream-event-id";
2112
+ var WEBHOOK_EVENT_TYPE_HEADER = "rstream-event-type";
2113
+ var WEBHOOK_ID_HEADER = "rstream-webhook-id";
2114
+ var WEBHOOK_DELIVERY_ID_HEADER = "rstream-delivery-id";
1480
2115
  var SIGNATURE_HEX_BYTES = 32;
2116
+ var webhookSecretBytes = 32;
1481
2117
  var signatureHexSchema = /^[0-9a-fA-F]{64}$/;
1482
2118
  var timestampSchema = /^\d+$/;
2119
+ function payloadBuffer(payload) {
2120
+ return Buffer.isBuffer(payload) ? payload : Buffer.from(payload);
2121
+ }
1483
2122
  function parseSignatureTimestamp(timestamp) {
1484
2123
  if (!timestampSchema.test(timestamp)) {
1485
2124
  throw new Error("Invalid signature timestamp");
@@ -1496,6 +2135,19 @@ function normalizeTolerance(tolerance) {
1496
2135
  }
1497
2136
  return tolerance;
1498
2137
  }
2138
+ function normalizeTimestamp(timestamp) {
2139
+ if (timestamp === void 0) {
2140
+ return Math.floor(Date.now() / 1e3);
2141
+ }
2142
+ const seconds = timestamp instanceof Date ? timestamp.getTime() / 1e3 : timestamp;
2143
+ if (!Number.isFinite(seconds) || seconds < 0) {
2144
+ throw new Error("Invalid webhook signature timestamp");
2145
+ }
2146
+ return Math.floor(seconds);
2147
+ }
2148
+ function signedPayload(timestamp, payload) {
2149
+ return Buffer.concat([Buffer.from(`${timestamp}.`, "utf8"), payload]);
2150
+ }
1499
2151
  function readSignature(signature) {
1500
2152
  if (!signatureHexSchema.test(signature)) {
1501
2153
  return void 0;
@@ -1512,9 +2164,42 @@ function assertSecretConfigured(secret) {
1512
2164
  throw new Error("Webhook signing secret is required");
1513
2165
  }
1514
2166
  }
2167
+ function assertNonEmpty(value, label) {
2168
+ const normalized = value.trim();
2169
+ if (normalized.length === 0) {
2170
+ throw new Error(`${label} is required`);
2171
+ }
2172
+ return normalized;
2173
+ }
2174
+ function generateWebhookSigningSecret() {
2175
+ return `whsec_${import_crypto2.default.randomBytes(webhookSecretBytes).toString("base64url")}`;
2176
+ }
2177
+ function signWebhookPayload(payload, secret, timestamp) {
2178
+ assertSecretConfigured(secret);
2179
+ const timestampSeconds = normalizeTimestamp(timestamp).toString();
2180
+ const signature = import_crypto2.default.createHmac("sha256", secret).update(signedPayload(timestampSeconds, payloadBuffer(payload))).digest("hex");
2181
+ return `t=${timestampSeconds},v1=${signature}`;
2182
+ }
2183
+ function buildWebhookHeaders(payload, event, secret, options) {
2184
+ const eventId = assertNonEmpty(event.id ?? "", "Webhook event id");
2185
+ const eventType = assertNonEmpty(event.type, "Webhook event type");
2186
+ const webhookId = assertNonEmpty(options.webhookId, "Webhook id");
2187
+ const deliveryId = assertNonEmpty(options.deliveryId, "Webhook delivery id");
2188
+ return {
2189
+ [WEBHOOK_SIGNATURE_HEADER]: signWebhookPayload(
2190
+ payload,
2191
+ secret,
2192
+ options.timestamp
2193
+ ),
2194
+ [WEBHOOK_EVENT_ID_HEADER]: eventId,
2195
+ [WEBHOOK_EVENT_TYPE_HEADER]: eventType,
2196
+ [WEBHOOK_ID_HEADER]: webhookId,
2197
+ [WEBHOOK_DELIVERY_ID_HEADER]: deliveryId
2198
+ };
2199
+ }
1515
2200
  var RstreamWebhookResource = class {
1516
2201
  async event(payload, header, secret, tolerance = 300, receivedAt = Date.now()) {
1517
- const payloadBuffer = Buffer.isBuffer(payload) ? payload : Buffer.from(payload);
2202
+ const rawPayload = payloadBuffer(payload);
1518
2203
  const signatureHeader = Array.isArray(header) ? header[0] : header.toString();
1519
2204
  if (!signatureHeader) {
1520
2205
  throw new Error("No signature header");
@@ -1534,8 +2219,7 @@ var RstreamWebhookResource = class {
1534
2219
  `Webhook signature timestamp outside tolerance: ${now}, ${timestampNum}`
1535
2220
  );
1536
2221
  }
1537
- const signedPayload = `${timestamp}.${payloadBuffer.toString("utf8")}`;
1538
- const expectedSignature = import_crypto2.default.createHmac("sha256", secret).update(signedPayload).digest();
2222
+ const expectedSignature = import_crypto2.default.createHmac("sha256", secret).update(signedPayload(timestamp, rawPayload)).digest();
1539
2223
  const signatureMatched = signatures.some(
1540
2224
  (signature) => signatureMatches(signature, expectedSignature)
1541
2225
  );
@@ -1543,9 +2227,7 @@ var RstreamWebhookResource = class {
1543
2227
  throw new Error("Signature verification failed");
1544
2228
  }
1545
2229
  try {
1546
- return webhookEventsSchema.parse(
1547
- JSON.parse(payloadBuffer.toString("utf8"))
1548
- );
2230
+ return webhookEventsSchema.parse(JSON.parse(rawPayload.toString("utf8")));
1549
2231
  } catch (error) {
1550
2232
  throw new Error(
1551
2233
  `Failed to parse webhook payload: ${error instanceof Error ? error.message : String(error)}`,
@@ -1553,6 +2235,15 @@ var RstreamWebhookResource = class {
1553
2235
  );
1554
2236
  }
1555
2237
  }
2238
+ generateSigningSecret() {
2239
+ return generateWebhookSigningSecret();
2240
+ }
2241
+ sign(payload, secret, timestamp) {
2242
+ return signWebhookPayload(payload, secret, timestamp);
2243
+ }
2244
+ headers(payload, event, secret, options) {
2245
+ return buildWebhookHeaders(payload, event, secret, options);
2246
+ }
1556
2247
  };
1557
2248
 
1558
2249
  // src/tunnels.ts
@@ -1671,6 +2362,9 @@ var RstreamTunnelsClient = class {
1671
2362
  get webhooks() {
1672
2363
  return new RstreamWebhookResource();
1673
2364
  }
2365
+ get webtty() {
2366
+ return new RstreamWebTTYResource(this);
2367
+ }
1674
2368
  get turn() {
1675
2369
  return new RstreamTURNResource(this);
1676
2370
  }
@@ -1885,8 +2579,8 @@ var Watch = class {
1885
2579
  };
1886
2580
 
1887
2581
  // src/webtty.ts
1888
- var z7 = __toESM(require("zod"));
1889
- var osFamilySchema = z7.enum([
2582
+ var z9 = __toESM(require("zod"));
2583
+ var osFamilySchema = z9.enum([
1890
2584
  "linux",
1891
2585
  "macos",
1892
2586
  "windows",
@@ -1894,25 +2588,38 @@ var osFamilySchema = z7.enum([
1894
2588
  "openbsd",
1895
2589
  "freebsd"
1896
2590
  ]);
1897
- var webttyCapabilitySchema = z7.enum(["exec", "fs"]);
1898
- var webttyFSModeSchema = z7.enum(["read-write", "read-only"]);
1899
- var webttyServerSchema = z7.object({
1900
- tunnel_id: z7.string(),
1901
- host: z7.string(),
1902
- token_auth: z7.boolean(),
1903
- capabilities: z7.array(webttyCapabilitySchema).optional(),
1904
- exec_path: z7.string().optional(),
1905
- fs_path: z7.string().optional(),
2591
+ var webttyCapabilitySchema = z9.enum(["exec", "fs"]);
2592
+ var webttyFSModeSchema = z9.enum(["read-write", "read-only"]);
2593
+ var webttyEncryptionPolicySchema = z9.enum([
2594
+ "disabled",
2595
+ "explicit_key",
2596
+ "workspace_managed"
2597
+ ]);
2598
+ var webttyServerSchema = z9.object({
2599
+ tunnel_id: z9.string(),
2600
+ tunnel_protocol: z9.enum(["http", "webtty"]),
2601
+ managed: z9.boolean(),
2602
+ host: z9.string(),
2603
+ token_auth: z9.boolean(),
2604
+ server_id: z9.string().optional(),
2605
+ server_name: z9.string().optional(),
2606
+ host_key_id: z9.string().optional(),
2607
+ e2e: z9.enum(["disabled", "required"]).optional(),
2608
+ client_proof: z9.enum(["none", "required"]).optional(),
2609
+ encryption_policy: webttyEncryptionPolicySchema.optional(),
2610
+ capabilities: z9.array(webttyCapabilitySchema).optional(),
2611
+ exec_path: z9.string().optional(),
2612
+ fs_path: z9.string().optional(),
1906
2613
  fs_mode: webttyFSModeSchema.optional(),
1907
2614
  os_family: osFamilySchema.optional(),
1908
- arch: z7.string().optional(),
1909
- os_id: z7.string().optional(),
1910
- os_version_id: z7.string().optional(),
1911
- os_version_codename: z7.string().optional(),
1912
- os_pretty_name: z7.string().optional(),
1913
- kernel_release: z7.string().optional(),
1914
- hostname: z7.string().optional(),
1915
- labels: z7.record(z7.string(), z7.string().optional()).optional()
2615
+ arch: z9.string().optional(),
2616
+ os_id: z9.string().optional(),
2617
+ os_version_id: z9.string().optional(),
2618
+ os_version_codename: z9.string().optional(),
2619
+ os_pretty_name: z9.string().optional(),
2620
+ kernel_release: z9.string().optional(),
2621
+ hostname: z9.string().optional(),
2622
+ labels: z9.record(z9.string(), z9.string().optional()).optional()
1916
2623
  });
1917
2624
  function isWebTTYCapability(value) {
1918
2625
  return webttyCapabilitySchema.safeParse(value).success;
@@ -1933,9 +2640,10 @@ function webTTYHasCapability(capabilities, capability) {
1933
2640
  function parser(tunnel) {
1934
2641
  if (tunnel.status !== "online") return null;
1935
2642
  if (tunnel.publish !== true) return null;
1936
- if (tunnel.protocol !== "http") return null;
2643
+ const managedProtocol = tunnel.protocol === "webtty";
2644
+ if (tunnel.protocol !== "http" && !managedProtocol) return null;
1937
2645
  const tunnelLabels = tunnel.labels ?? {};
1938
- if (tunnelLabels["application-protocol"] !== "rstream.webtty") {
2646
+ if (!managedProtocol && tunnelLabels["application-protocol"] !== "rstream.webtty") {
1939
2647
  return null;
1940
2648
  }
1941
2649
  const capabilities = webTTYCapabilitiesForLabels(tunnelLabels);
@@ -1948,8 +2656,16 @@ function parser(tunnel) {
1948
2656
  }
1949
2657
  const candidate = {
1950
2658
  tunnel_id: tunnel.id,
2659
+ tunnel_protocol: tunnel.protocol,
2660
+ managed: managedProtocol,
1951
2661
  host: formatTunnelHost(tunnel),
1952
2662
  token_auth: tunnel.token_auth === true,
2663
+ server_id: tunnelLabels["rstream.webtty.server_id"],
2664
+ server_name: tunnelLabels["rstream.webtty.server_name"],
2665
+ host_key_id: tunnelLabels["rstream.webtty.host_key_id"],
2666
+ e2e: tunnelLabels["rstream.webtty.e2e"],
2667
+ client_proof: tunnelLabels["rstream.webtty.client_proof"],
2668
+ encryption_policy: tunnelLabels["rstream.webtty.encryption_policy"],
1953
2669
  capabilities,
1954
2670
  exec_path: webTTYHasCapability(capabilities, "exec") ? tunnelLabels["rstream.webtty.exec.path"] ?? "/" : void 0,
1955
2671
  fs_path: webTTYHasCapability(capabilities, "fs") ? tunnelLabels["rstream.webtty.fs.path"] ?? "/fs" : void 0,
@@ -1982,10 +2698,18 @@ function parseWebTTYServers(tunnels) {
1982
2698
  RstreamTunnelsClient,
1983
2699
  RstreamTunnelsResource,
1984
2700
  RstreamTunnelsRessource,
2701
+ RstreamWebTTYResource,
1985
2702
  RstreamWebhookResource,
1986
2703
  RstreamWebhookRessource,
1987
2704
  Tunnels,
2705
+ WEBHOOK_DELIVERY_ID_HEADER,
2706
+ WEBHOOK_EVENT_ID_HEADER,
2707
+ WEBHOOK_EVENT_TYPE_HEADER,
2708
+ WEBHOOK_ID_HEADER,
2709
+ WEBHOOK_SIGNATURE_HEADER,
1988
2710
  Watch,
2711
+ attachWebTTYParticipantParamsSchema,
2712
+ buildWebhookHeaders,
1989
2713
  clientFilterSchema,
1990
2714
  clientSchema,
1991
2715
  createAPITURNCredentials,
@@ -1993,28 +2717,59 @@ function parseWebTTYServers(tunnels) {
1993
2717
  createAuthTokenFromClientCredentials,
1994
2718
  createPATTURNCredentials,
1995
2719
  createTURNCredentials,
2720
+ createWebTTYControlRequestParamsSchema,
2721
+ detachWebTTYParticipantParamsSchema,
1996
2722
  engineOpenApiDocument,
1997
2723
  engineOpenApiJson,
1998
2724
  eventSchema,
2725
+ formatStreamAccessPath,
1999
2726
  formatTunnelHost,
2727
+ generateWebhookSigningSecret,
2000
2728
  listClientsParamsSchema,
2001
2729
  listClientsResponseSchema,
2002
2730
  listTunnelsParamsSchema,
2003
2731
  listTunnelsResponseSchema,
2732
+ listWebTTYControlRequestsParamsSchema,
2733
+ listWebTTYKeyGrantDecryptMaterialParamsSchema,
2734
+ listWebTTYSessionGroupsParamsSchema,
2735
+ listWebTTYSessionsParamsSchema,
2004
2736
  normalizeEngineAddress,
2005
2737
  parseWebTTYServers,
2006
2738
  projectLogEventsSchema,
2739
+ readWebTTYSessionEventsParamsSchema,
2007
2740
  resolveControlPlaneCredentials,
2008
2741
  resolveManagedTunnelsProject,
2009
2742
  resolveTunnelsAPIURL,
2010
2743
  resolveTunnelsCredentials,
2011
2744
  resolveTunnelsEngine,
2745
+ resolveWebTTYControlRequestParamsSchema,
2746
+ signWebhookPayload,
2012
2747
  streamEndpointSchema,
2748
+ streamEntrySchema,
2013
2749
  streamSummaryEventSchema,
2014
2750
  streamSummarySchema,
2015
2751
  streamTLSInfoSchema,
2752
+ streamWebTTYMetadataSchema,
2016
2753
  tunnelFilterSchema,
2017
2754
  turnCredentialModeSchema,
2755
+ webTTYCapabilitiesSchema,
2756
+ webTTYContextMetadataSchema,
2757
+ webTTYControlRequestSchema,
2758
+ webTTYCryptoMetadataSchema,
2759
+ webTTYEncryptionModeSchema,
2760
+ webTTYKeyGrantDecryptMaterialSchema,
2761
+ webTTYKeyGrantSchema,
2762
+ webTTYOriginSchema,
2763
+ webTTYParticipantLiveSchema,
2764
+ webTTYParticipantRoleSchema,
2765
+ webTTYParticipantSchema,
2766
+ webTTYRecordingModeSchema,
2767
+ webTTYSessionEventSchema,
2768
+ webTTYSessionGroupSchema,
2769
+ webTTYSessionLiveSchema,
2770
+ webTTYSessionModeSchema,
2771
+ webTTYSessionSchema,
2772
+ webTTYTransportSchema,
2018
2773
  webhookEventsSchema,
2019
2774
  webttyServerSchema,
2020
2775
  wsEventsSchema