@proxyhuman/protocol 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -151,7 +151,15 @@ var SessionEventSchema = import_zod.z.discriminatedUnion("type", [
151
151
  viewerCount: import_zod.z.number().int(),
152
152
  viewer: ViewerInfoSchema.optional()
153
153
  }),
154
- import_zod.z.object({ ts: import_zod.z.number(), type: import_zod.z.literal("action_recorded"), action: RecordedActionSchema }),
154
+ import_zod.z.object({
155
+ ts: import_zod.z.number(),
156
+ type: import_zod.z.literal("action_recorded"),
157
+ action: RecordedActionSchema,
158
+ /** The viewer that performed this action. Optional for backward
159
+ * compatibility with events recorded before per-action attribution
160
+ * was added. */
161
+ viewer: ViewerInfoSchema.optional()
162
+ }),
155
163
  import_zod.z.object({ ts: import_zod.z.number(), type: import_zod.z.literal("error"), message: import_zod.z.string(), detail: import_zod.z.string().optional() })
156
164
  ]);
157
165
  var NewSessionSchema = import_zod.z.object({
@@ -265,7 +273,10 @@ var SessionInfoSchema = import_zod.z.object({
265
273
  outcome: SessionOutcomeSchema.nullable(),
266
274
  prompt: import_zod.z.string().nullable(),
267
275
  publisher: PublisherInfoSchema.nullable(),
268
- target: TargetInfoSchema.nullable()
276
+ target: TargetInfoSchema.nullable(),
277
+ /** Most recent viewer to join (or leave) — what the dashboard list shows
278
+ * as the "picked up by" device. Null until the first viewer connects. */
279
+ lastViewer: ViewerInfoSchema.nullable().optional()
269
280
  });
270
281
  var SessionSummarySchema = import_zod.z.object({
271
282
  sessionId: import_zod.z.string(),
@@ -277,7 +288,9 @@ var SessionSummarySchema = import_zod.z.object({
277
288
  createdAt: import_zod.z.number(),
278
289
  endedAt: import_zod.z.number().nullable(),
279
290
  /** Last event-log append timestamp. */
280
- updatedAt: import_zod.z.number()
291
+ updatedAt: import_zod.z.number(),
292
+ /** Most recent viewer to join (or leave). Null until first viewer. */
293
+ lastViewer: ViewerInfoSchema.nullable().optional()
281
294
  });
282
295
  var SessionActionsResponseSchema = import_zod.z.object({
283
296
  sessionId: import_zod.z.string(),
package/dist/index.d.cts CHANGED
@@ -587,6 +587,23 @@ declare const SessionEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
587
587
  type: "human_done";
588
588
  ts: number;
589
589
  }>]>;
590
+ /** The viewer that performed this action. Optional for backward
591
+ * compatibility with events recorded before per-action attribution
592
+ * was added. */
593
+ viewer: z.ZodOptional<z.ZodObject<{
594
+ /** Random opaque id; persisted as the `ph_device` cookie on the viewer. */
595
+ deviceId: z.ZodNullable<z.ZodString>;
596
+ userAgent: z.ZodNullable<z.ZodString>;
597
+ ip: z.ZodNullable<z.ZodString>;
598
+ }, "strip", z.ZodTypeAny, {
599
+ userAgent: string | null;
600
+ deviceId: string | null;
601
+ ip: string | null;
602
+ }, {
603
+ userAgent: string | null;
604
+ deviceId: string | null;
605
+ ip: string | null;
606
+ }>>;
590
607
  }, "strip", z.ZodTypeAny, {
591
608
  type: "action_recorded";
592
609
  ts: number;
@@ -638,6 +655,11 @@ declare const SessionEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
638
655
  type: "human_done";
639
656
  ts: number;
640
657
  };
658
+ viewer?: {
659
+ userAgent: string | null;
660
+ deviceId: string | null;
661
+ ip: string | null;
662
+ } | undefined;
641
663
  }, {
642
664
  type: "action_recorded";
643
665
  ts: number;
@@ -689,6 +711,11 @@ declare const SessionEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
689
711
  type: "human_done";
690
712
  ts: number;
691
713
  };
714
+ viewer?: {
715
+ userAgent: string | null;
716
+ deviceId: string | null;
717
+ ip: string | null;
718
+ } | undefined;
692
719
  }>, z.ZodObject<{
693
720
  ts: z.ZodNumber;
694
721
  type: z.ZodLiteral<"error">;
@@ -1947,6 +1974,22 @@ declare const SessionInfoSchema: z.ZodObject<{
1947
1974
  browserVersion?: string | null | undefined;
1948
1975
  userAgent?: string | null | undefined;
1949
1976
  }>>;
1977
+ /** Most recent viewer to join (or leave) — what the dashboard list shows
1978
+ * as the "picked up by" device. Null until the first viewer connects. */
1979
+ lastViewer: z.ZodOptional<z.ZodNullable<z.ZodObject<{
1980
+ /** Random opaque id; persisted as the `ph_device` cookie on the viewer. */
1981
+ deviceId: z.ZodNullable<z.ZodString>;
1982
+ userAgent: z.ZodNullable<z.ZodString>;
1983
+ ip: z.ZodNullable<z.ZodString>;
1984
+ }, "strip", z.ZodTypeAny, {
1985
+ userAgent: string | null;
1986
+ deviceId: string | null;
1987
+ ip: string | null;
1988
+ }, {
1989
+ userAgent: string | null;
1990
+ deviceId: string | null;
1991
+ ip: string | null;
1992
+ }>>>;
1950
1993
  }, "strip", z.ZodTypeAny, {
1951
1994
  viewerCount: number;
1952
1995
  prompt: string | null;
@@ -1986,6 +2029,11 @@ declare const SessionInfoSchema: z.ZodObject<{
1986
2029
  state: "awaiting_viewer" | "streaming" | "paused" | "complete" | "failed" | "cancelled";
1987
2030
  createdAt: number;
1988
2031
  endedAt: number | null;
2032
+ lastViewer?: {
2033
+ userAgent: string | null;
2034
+ deviceId: string | null;
2035
+ ip: string | null;
2036
+ } | null | undefined;
1989
2037
  }, {
1990
2038
  viewerCount: number;
1991
2039
  prompt: string | null;
@@ -2025,6 +2073,11 @@ declare const SessionInfoSchema: z.ZodObject<{
2025
2073
  state: "awaiting_viewer" | "streaming" | "paused" | "complete" | "failed" | "cancelled";
2026
2074
  createdAt: number;
2027
2075
  endedAt: number | null;
2076
+ lastViewer?: {
2077
+ userAgent: string | null;
2078
+ deviceId: string | null;
2079
+ ip: string | null;
2080
+ } | null | undefined;
2028
2081
  }>;
2029
2082
  type SessionInfo = z.infer<typeof SessionInfoSchema>;
2030
2083
  declare const SessionSummarySchema: z.ZodObject<{
@@ -2086,6 +2139,21 @@ declare const SessionSummarySchema: z.ZodObject<{
2086
2139
  endedAt: z.ZodNullable<z.ZodNumber>;
2087
2140
  /** Last event-log append timestamp. */
2088
2141
  updatedAt: z.ZodNumber;
2142
+ /** Most recent viewer to join (or leave). Null until first viewer. */
2143
+ lastViewer: z.ZodOptional<z.ZodNullable<z.ZodObject<{
2144
+ /** Random opaque id; persisted as the `ph_device` cookie on the viewer. */
2145
+ deviceId: z.ZodNullable<z.ZodString>;
2146
+ userAgent: z.ZodNullable<z.ZodString>;
2147
+ ip: z.ZodNullable<z.ZodString>;
2148
+ }, "strip", z.ZodTypeAny, {
2149
+ userAgent: string | null;
2150
+ deviceId: string | null;
2151
+ ip: string | null;
2152
+ }, {
2153
+ userAgent: string | null;
2154
+ deviceId: string | null;
2155
+ ip: string | null;
2156
+ }>>>;
2089
2157
  }, "strip", z.ZodTypeAny, {
2090
2158
  viewerCount: number;
2091
2159
  prompt: string | null;
@@ -2112,6 +2180,11 @@ declare const SessionSummarySchema: z.ZodObject<{
2112
2180
  endedAt: number | null;
2113
2181
  actionCount: number;
2114
2182
  updatedAt: number;
2183
+ lastViewer?: {
2184
+ userAgent: string | null;
2185
+ deviceId: string | null;
2186
+ ip: string | null;
2187
+ } | null | undefined;
2115
2188
  }, {
2116
2189
  viewerCount: number;
2117
2190
  prompt: string | null;
@@ -2138,6 +2211,11 @@ declare const SessionSummarySchema: z.ZodObject<{
2138
2211
  endedAt: number | null;
2139
2212
  actionCount: number;
2140
2213
  updatedAt: number;
2214
+ lastViewer?: {
2215
+ userAgent: string | null;
2216
+ deviceId: string | null;
2217
+ ip: string | null;
2218
+ } | null | undefined;
2141
2219
  }>;
2142
2220
  type SessionSummary = z.infer<typeof SessionSummarySchema>;
2143
2221
  /** `GET /sessions/:sid/actions` */
@@ -2504,6 +2582,22 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
2504
2582
  browserVersion?: string | null | undefined;
2505
2583
  userAgent?: string | null | undefined;
2506
2584
  }>>;
2585
+ /** Most recent viewer to join (or leave) — what the dashboard list shows
2586
+ * as the "picked up by" device. Null until the first viewer connects. */
2587
+ lastViewer: z.ZodOptional<z.ZodNullable<z.ZodObject<{
2588
+ /** Random opaque id; persisted as the `ph_device` cookie on the viewer. */
2589
+ deviceId: z.ZodNullable<z.ZodString>;
2590
+ userAgent: z.ZodNullable<z.ZodString>;
2591
+ ip: z.ZodNullable<z.ZodString>;
2592
+ }, "strip", z.ZodTypeAny, {
2593
+ userAgent: string | null;
2594
+ deviceId: string | null;
2595
+ ip: string | null;
2596
+ }, {
2597
+ userAgent: string | null;
2598
+ deviceId: string | null;
2599
+ ip: string | null;
2600
+ }>>>;
2507
2601
  }, "strip", z.ZodTypeAny, {
2508
2602
  viewerCount: number;
2509
2603
  prompt: string | null;
@@ -2543,6 +2637,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
2543
2637
  state: "awaiting_viewer" | "streaming" | "paused" | "complete" | "failed" | "cancelled";
2544
2638
  createdAt: number;
2545
2639
  endedAt: number | null;
2640
+ lastViewer?: {
2641
+ userAgent: string | null;
2642
+ deviceId: string | null;
2643
+ ip: string | null;
2644
+ } | null | undefined;
2546
2645
  }, {
2547
2646
  viewerCount: number;
2548
2647
  prompt: string | null;
@@ -2582,6 +2681,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
2582
2681
  state: "awaiting_viewer" | "streaming" | "paused" | "complete" | "failed" | "cancelled";
2583
2682
  createdAt: number;
2584
2683
  endedAt: number | null;
2684
+ lastViewer?: {
2685
+ userAgent: string | null;
2686
+ deviceId: string | null;
2687
+ ip: string | null;
2688
+ } | null | undefined;
2585
2689
  }>;
2586
2690
  events: z.ZodArray<z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2587
2691
  ts: z.ZodNumber;
@@ -2815,6 +2919,23 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
2815
2919
  type: "human_done";
2816
2920
  ts: number;
2817
2921
  }>]>;
2922
+ /** The viewer that performed this action. Optional for backward
2923
+ * compatibility with events recorded before per-action attribution
2924
+ * was added. */
2925
+ viewer: z.ZodOptional<z.ZodObject<{
2926
+ /** Random opaque id; persisted as the `ph_device` cookie on the viewer. */
2927
+ deviceId: z.ZodNullable<z.ZodString>;
2928
+ userAgent: z.ZodNullable<z.ZodString>;
2929
+ ip: z.ZodNullable<z.ZodString>;
2930
+ }, "strip", z.ZodTypeAny, {
2931
+ userAgent: string | null;
2932
+ deviceId: string | null;
2933
+ ip: string | null;
2934
+ }, {
2935
+ userAgent: string | null;
2936
+ deviceId: string | null;
2937
+ ip: string | null;
2938
+ }>>;
2818
2939
  }, "strip", z.ZodTypeAny, {
2819
2940
  type: "action_recorded";
2820
2941
  ts: number;
@@ -2866,6 +2987,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
2866
2987
  type: "human_done";
2867
2988
  ts: number;
2868
2989
  };
2990
+ viewer?: {
2991
+ userAgent: string | null;
2992
+ deviceId: string | null;
2993
+ ip: string | null;
2994
+ } | undefined;
2869
2995
  }, {
2870
2996
  type: "action_recorded";
2871
2997
  ts: number;
@@ -2917,6 +3043,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
2917
3043
  type: "human_done";
2918
3044
  ts: number;
2919
3045
  };
3046
+ viewer?: {
3047
+ userAgent: string | null;
3048
+ deviceId: string | null;
3049
+ ip: string | null;
3050
+ } | undefined;
2920
3051
  }>, z.ZodObject<{
2921
3052
  ts: z.ZodNumber;
2922
3053
  type: z.ZodLiteral<"error">;
@@ -3165,6 +3296,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
3165
3296
  state: "awaiting_viewer" | "streaming" | "paused" | "complete" | "failed" | "cancelled";
3166
3297
  createdAt: number;
3167
3298
  endedAt: number | null;
3299
+ lastViewer?: {
3300
+ userAgent: string | null;
3301
+ deviceId: string | null;
3302
+ ip: string | null;
3303
+ } | null | undefined;
3168
3304
  };
3169
3305
  events: ({
3170
3306
  type: "state_changed";
@@ -3240,6 +3376,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
3240
3376
  type: "human_done";
3241
3377
  ts: number;
3242
3378
  };
3379
+ viewer?: {
3380
+ userAgent: string | null;
3381
+ deviceId: string | null;
3382
+ ip: string | null;
3383
+ } | undefined;
3243
3384
  } | {
3244
3385
  message: string;
3245
3386
  type: "error";
@@ -3335,6 +3476,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
3335
3476
  state: "awaiting_viewer" | "streaming" | "paused" | "complete" | "failed" | "cancelled";
3336
3477
  createdAt: number;
3337
3478
  endedAt: number | null;
3479
+ lastViewer?: {
3480
+ userAgent: string | null;
3481
+ deviceId: string | null;
3482
+ ip: string | null;
3483
+ } | null | undefined;
3338
3484
  };
3339
3485
  events: ({
3340
3486
  type: "state_changed";
@@ -3410,6 +3556,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
3410
3556
  type: "human_done";
3411
3557
  ts: number;
3412
3558
  };
3559
+ viewer?: {
3560
+ userAgent: string | null;
3561
+ deviceId: string | null;
3562
+ ip: string | null;
3563
+ } | undefined;
3413
3564
  } | {
3414
3565
  message: string;
3415
3566
  type: "error";
@@ -3482,6 +3633,21 @@ declare const UserSessionsResponseSchema: z.ZodObject<{
3482
3633
  endedAt: z.ZodNullable<z.ZodNumber>;
3483
3634
  /** Last event-log append timestamp. */
3484
3635
  updatedAt: z.ZodNumber;
3636
+ /** Most recent viewer to join (or leave). Null until first viewer. */
3637
+ lastViewer: z.ZodOptional<z.ZodNullable<z.ZodObject<{
3638
+ /** Random opaque id; persisted as the `ph_device` cookie on the viewer. */
3639
+ deviceId: z.ZodNullable<z.ZodString>;
3640
+ userAgent: z.ZodNullable<z.ZodString>;
3641
+ ip: z.ZodNullable<z.ZodString>;
3642
+ }, "strip", z.ZodTypeAny, {
3643
+ userAgent: string | null;
3644
+ deviceId: string | null;
3645
+ ip: string | null;
3646
+ }, {
3647
+ userAgent: string | null;
3648
+ deviceId: string | null;
3649
+ ip: string | null;
3650
+ }>>>;
3485
3651
  }, "strip", z.ZodTypeAny, {
3486
3652
  viewerCount: number;
3487
3653
  prompt: string | null;
@@ -3508,6 +3674,11 @@ declare const UserSessionsResponseSchema: z.ZodObject<{
3508
3674
  endedAt: number | null;
3509
3675
  actionCount: number;
3510
3676
  updatedAt: number;
3677
+ lastViewer?: {
3678
+ userAgent: string | null;
3679
+ deviceId: string | null;
3680
+ ip: string | null;
3681
+ } | null | undefined;
3511
3682
  }, {
3512
3683
  viewerCount: number;
3513
3684
  prompt: string | null;
@@ -3534,6 +3705,11 @@ declare const UserSessionsResponseSchema: z.ZodObject<{
3534
3705
  endedAt: number | null;
3535
3706
  actionCount: number;
3536
3707
  updatedAt: number;
3708
+ lastViewer?: {
3709
+ userAgent: string | null;
3710
+ deviceId: string | null;
3711
+ ip: string | null;
3712
+ } | null | undefined;
3537
3713
  }>, "many">;
3538
3714
  /** Opaque cursor for the next page, or null when there are no more. */
3539
3715
  nextCursor: z.ZodNullable<z.ZodString>;
@@ -3564,6 +3740,11 @@ declare const UserSessionsResponseSchema: z.ZodObject<{
3564
3740
  endedAt: number | null;
3565
3741
  actionCount: number;
3566
3742
  updatedAt: number;
3743
+ lastViewer?: {
3744
+ userAgent: string | null;
3745
+ deviceId: string | null;
3746
+ ip: string | null;
3747
+ } | null | undefined;
3567
3748
  }[];
3568
3749
  nextCursor: string | null;
3569
3750
  }, {
@@ -3593,6 +3774,11 @@ declare const UserSessionsResponseSchema: z.ZodObject<{
3593
3774
  endedAt: number | null;
3594
3775
  actionCount: number;
3595
3776
  updatedAt: number;
3777
+ lastViewer?: {
3778
+ userAgent: string | null;
3779
+ deviceId: string | null;
3780
+ ip: string | null;
3781
+ } | null | undefined;
3596
3782
  }[];
3597
3783
  nextCursor: string | null;
3598
3784
  }>;
package/dist/index.d.ts CHANGED
@@ -587,6 +587,23 @@ declare const SessionEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
587
587
  type: "human_done";
588
588
  ts: number;
589
589
  }>]>;
590
+ /** The viewer that performed this action. Optional for backward
591
+ * compatibility with events recorded before per-action attribution
592
+ * was added. */
593
+ viewer: z.ZodOptional<z.ZodObject<{
594
+ /** Random opaque id; persisted as the `ph_device` cookie on the viewer. */
595
+ deviceId: z.ZodNullable<z.ZodString>;
596
+ userAgent: z.ZodNullable<z.ZodString>;
597
+ ip: z.ZodNullable<z.ZodString>;
598
+ }, "strip", z.ZodTypeAny, {
599
+ userAgent: string | null;
600
+ deviceId: string | null;
601
+ ip: string | null;
602
+ }, {
603
+ userAgent: string | null;
604
+ deviceId: string | null;
605
+ ip: string | null;
606
+ }>>;
590
607
  }, "strip", z.ZodTypeAny, {
591
608
  type: "action_recorded";
592
609
  ts: number;
@@ -638,6 +655,11 @@ declare const SessionEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
638
655
  type: "human_done";
639
656
  ts: number;
640
657
  };
658
+ viewer?: {
659
+ userAgent: string | null;
660
+ deviceId: string | null;
661
+ ip: string | null;
662
+ } | undefined;
641
663
  }, {
642
664
  type: "action_recorded";
643
665
  ts: number;
@@ -689,6 +711,11 @@ declare const SessionEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
689
711
  type: "human_done";
690
712
  ts: number;
691
713
  };
714
+ viewer?: {
715
+ userAgent: string | null;
716
+ deviceId: string | null;
717
+ ip: string | null;
718
+ } | undefined;
692
719
  }>, z.ZodObject<{
693
720
  ts: z.ZodNumber;
694
721
  type: z.ZodLiteral<"error">;
@@ -1947,6 +1974,22 @@ declare const SessionInfoSchema: z.ZodObject<{
1947
1974
  browserVersion?: string | null | undefined;
1948
1975
  userAgent?: string | null | undefined;
1949
1976
  }>>;
1977
+ /** Most recent viewer to join (or leave) — what the dashboard list shows
1978
+ * as the "picked up by" device. Null until the first viewer connects. */
1979
+ lastViewer: z.ZodOptional<z.ZodNullable<z.ZodObject<{
1980
+ /** Random opaque id; persisted as the `ph_device` cookie on the viewer. */
1981
+ deviceId: z.ZodNullable<z.ZodString>;
1982
+ userAgent: z.ZodNullable<z.ZodString>;
1983
+ ip: z.ZodNullable<z.ZodString>;
1984
+ }, "strip", z.ZodTypeAny, {
1985
+ userAgent: string | null;
1986
+ deviceId: string | null;
1987
+ ip: string | null;
1988
+ }, {
1989
+ userAgent: string | null;
1990
+ deviceId: string | null;
1991
+ ip: string | null;
1992
+ }>>>;
1950
1993
  }, "strip", z.ZodTypeAny, {
1951
1994
  viewerCount: number;
1952
1995
  prompt: string | null;
@@ -1986,6 +2029,11 @@ declare const SessionInfoSchema: z.ZodObject<{
1986
2029
  state: "awaiting_viewer" | "streaming" | "paused" | "complete" | "failed" | "cancelled";
1987
2030
  createdAt: number;
1988
2031
  endedAt: number | null;
2032
+ lastViewer?: {
2033
+ userAgent: string | null;
2034
+ deviceId: string | null;
2035
+ ip: string | null;
2036
+ } | null | undefined;
1989
2037
  }, {
1990
2038
  viewerCount: number;
1991
2039
  prompt: string | null;
@@ -2025,6 +2073,11 @@ declare const SessionInfoSchema: z.ZodObject<{
2025
2073
  state: "awaiting_viewer" | "streaming" | "paused" | "complete" | "failed" | "cancelled";
2026
2074
  createdAt: number;
2027
2075
  endedAt: number | null;
2076
+ lastViewer?: {
2077
+ userAgent: string | null;
2078
+ deviceId: string | null;
2079
+ ip: string | null;
2080
+ } | null | undefined;
2028
2081
  }>;
2029
2082
  type SessionInfo = z.infer<typeof SessionInfoSchema>;
2030
2083
  declare const SessionSummarySchema: z.ZodObject<{
@@ -2086,6 +2139,21 @@ declare const SessionSummarySchema: z.ZodObject<{
2086
2139
  endedAt: z.ZodNullable<z.ZodNumber>;
2087
2140
  /** Last event-log append timestamp. */
2088
2141
  updatedAt: z.ZodNumber;
2142
+ /** Most recent viewer to join (or leave). Null until first viewer. */
2143
+ lastViewer: z.ZodOptional<z.ZodNullable<z.ZodObject<{
2144
+ /** Random opaque id; persisted as the `ph_device` cookie on the viewer. */
2145
+ deviceId: z.ZodNullable<z.ZodString>;
2146
+ userAgent: z.ZodNullable<z.ZodString>;
2147
+ ip: z.ZodNullable<z.ZodString>;
2148
+ }, "strip", z.ZodTypeAny, {
2149
+ userAgent: string | null;
2150
+ deviceId: string | null;
2151
+ ip: string | null;
2152
+ }, {
2153
+ userAgent: string | null;
2154
+ deviceId: string | null;
2155
+ ip: string | null;
2156
+ }>>>;
2089
2157
  }, "strip", z.ZodTypeAny, {
2090
2158
  viewerCount: number;
2091
2159
  prompt: string | null;
@@ -2112,6 +2180,11 @@ declare const SessionSummarySchema: z.ZodObject<{
2112
2180
  endedAt: number | null;
2113
2181
  actionCount: number;
2114
2182
  updatedAt: number;
2183
+ lastViewer?: {
2184
+ userAgent: string | null;
2185
+ deviceId: string | null;
2186
+ ip: string | null;
2187
+ } | null | undefined;
2115
2188
  }, {
2116
2189
  viewerCount: number;
2117
2190
  prompt: string | null;
@@ -2138,6 +2211,11 @@ declare const SessionSummarySchema: z.ZodObject<{
2138
2211
  endedAt: number | null;
2139
2212
  actionCount: number;
2140
2213
  updatedAt: number;
2214
+ lastViewer?: {
2215
+ userAgent: string | null;
2216
+ deviceId: string | null;
2217
+ ip: string | null;
2218
+ } | null | undefined;
2141
2219
  }>;
2142
2220
  type SessionSummary = z.infer<typeof SessionSummarySchema>;
2143
2221
  /** `GET /sessions/:sid/actions` */
@@ -2504,6 +2582,22 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
2504
2582
  browserVersion?: string | null | undefined;
2505
2583
  userAgent?: string | null | undefined;
2506
2584
  }>>;
2585
+ /** Most recent viewer to join (or leave) — what the dashboard list shows
2586
+ * as the "picked up by" device. Null until the first viewer connects. */
2587
+ lastViewer: z.ZodOptional<z.ZodNullable<z.ZodObject<{
2588
+ /** Random opaque id; persisted as the `ph_device` cookie on the viewer. */
2589
+ deviceId: z.ZodNullable<z.ZodString>;
2590
+ userAgent: z.ZodNullable<z.ZodString>;
2591
+ ip: z.ZodNullable<z.ZodString>;
2592
+ }, "strip", z.ZodTypeAny, {
2593
+ userAgent: string | null;
2594
+ deviceId: string | null;
2595
+ ip: string | null;
2596
+ }, {
2597
+ userAgent: string | null;
2598
+ deviceId: string | null;
2599
+ ip: string | null;
2600
+ }>>>;
2507
2601
  }, "strip", z.ZodTypeAny, {
2508
2602
  viewerCount: number;
2509
2603
  prompt: string | null;
@@ -2543,6 +2637,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
2543
2637
  state: "awaiting_viewer" | "streaming" | "paused" | "complete" | "failed" | "cancelled";
2544
2638
  createdAt: number;
2545
2639
  endedAt: number | null;
2640
+ lastViewer?: {
2641
+ userAgent: string | null;
2642
+ deviceId: string | null;
2643
+ ip: string | null;
2644
+ } | null | undefined;
2546
2645
  }, {
2547
2646
  viewerCount: number;
2548
2647
  prompt: string | null;
@@ -2582,6 +2681,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
2582
2681
  state: "awaiting_viewer" | "streaming" | "paused" | "complete" | "failed" | "cancelled";
2583
2682
  createdAt: number;
2584
2683
  endedAt: number | null;
2684
+ lastViewer?: {
2685
+ userAgent: string | null;
2686
+ deviceId: string | null;
2687
+ ip: string | null;
2688
+ } | null | undefined;
2585
2689
  }>;
2586
2690
  events: z.ZodArray<z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2587
2691
  ts: z.ZodNumber;
@@ -2815,6 +2919,23 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
2815
2919
  type: "human_done";
2816
2920
  ts: number;
2817
2921
  }>]>;
2922
+ /** The viewer that performed this action. Optional for backward
2923
+ * compatibility with events recorded before per-action attribution
2924
+ * was added. */
2925
+ viewer: z.ZodOptional<z.ZodObject<{
2926
+ /** Random opaque id; persisted as the `ph_device` cookie on the viewer. */
2927
+ deviceId: z.ZodNullable<z.ZodString>;
2928
+ userAgent: z.ZodNullable<z.ZodString>;
2929
+ ip: z.ZodNullable<z.ZodString>;
2930
+ }, "strip", z.ZodTypeAny, {
2931
+ userAgent: string | null;
2932
+ deviceId: string | null;
2933
+ ip: string | null;
2934
+ }, {
2935
+ userAgent: string | null;
2936
+ deviceId: string | null;
2937
+ ip: string | null;
2938
+ }>>;
2818
2939
  }, "strip", z.ZodTypeAny, {
2819
2940
  type: "action_recorded";
2820
2941
  ts: number;
@@ -2866,6 +2987,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
2866
2987
  type: "human_done";
2867
2988
  ts: number;
2868
2989
  };
2990
+ viewer?: {
2991
+ userAgent: string | null;
2992
+ deviceId: string | null;
2993
+ ip: string | null;
2994
+ } | undefined;
2869
2995
  }, {
2870
2996
  type: "action_recorded";
2871
2997
  ts: number;
@@ -2917,6 +3043,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
2917
3043
  type: "human_done";
2918
3044
  ts: number;
2919
3045
  };
3046
+ viewer?: {
3047
+ userAgent: string | null;
3048
+ deviceId: string | null;
3049
+ ip: string | null;
3050
+ } | undefined;
2920
3051
  }>, z.ZodObject<{
2921
3052
  ts: z.ZodNumber;
2922
3053
  type: z.ZodLiteral<"error">;
@@ -3165,6 +3296,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
3165
3296
  state: "awaiting_viewer" | "streaming" | "paused" | "complete" | "failed" | "cancelled";
3166
3297
  createdAt: number;
3167
3298
  endedAt: number | null;
3299
+ lastViewer?: {
3300
+ userAgent: string | null;
3301
+ deviceId: string | null;
3302
+ ip: string | null;
3303
+ } | null | undefined;
3168
3304
  };
3169
3305
  events: ({
3170
3306
  type: "state_changed";
@@ -3240,6 +3376,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
3240
3376
  type: "human_done";
3241
3377
  ts: number;
3242
3378
  };
3379
+ viewer?: {
3380
+ userAgent: string | null;
3381
+ deviceId: string | null;
3382
+ ip: string | null;
3383
+ } | undefined;
3243
3384
  } | {
3244
3385
  message: string;
3245
3386
  type: "error";
@@ -3335,6 +3476,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
3335
3476
  state: "awaiting_viewer" | "streaming" | "paused" | "complete" | "failed" | "cancelled";
3336
3477
  createdAt: number;
3337
3478
  endedAt: number | null;
3479
+ lastViewer?: {
3480
+ userAgent: string | null;
3481
+ deviceId: string | null;
3482
+ ip: string | null;
3483
+ } | null | undefined;
3338
3484
  };
3339
3485
  events: ({
3340
3486
  type: "state_changed";
@@ -3410,6 +3556,11 @@ declare const SessionDetailResponseSchema: z.ZodObject<{
3410
3556
  type: "human_done";
3411
3557
  ts: number;
3412
3558
  };
3559
+ viewer?: {
3560
+ userAgent: string | null;
3561
+ deviceId: string | null;
3562
+ ip: string | null;
3563
+ } | undefined;
3413
3564
  } | {
3414
3565
  message: string;
3415
3566
  type: "error";
@@ -3482,6 +3633,21 @@ declare const UserSessionsResponseSchema: z.ZodObject<{
3482
3633
  endedAt: z.ZodNullable<z.ZodNumber>;
3483
3634
  /** Last event-log append timestamp. */
3484
3635
  updatedAt: z.ZodNumber;
3636
+ /** Most recent viewer to join (or leave). Null until first viewer. */
3637
+ lastViewer: z.ZodOptional<z.ZodNullable<z.ZodObject<{
3638
+ /** Random opaque id; persisted as the `ph_device` cookie on the viewer. */
3639
+ deviceId: z.ZodNullable<z.ZodString>;
3640
+ userAgent: z.ZodNullable<z.ZodString>;
3641
+ ip: z.ZodNullable<z.ZodString>;
3642
+ }, "strip", z.ZodTypeAny, {
3643
+ userAgent: string | null;
3644
+ deviceId: string | null;
3645
+ ip: string | null;
3646
+ }, {
3647
+ userAgent: string | null;
3648
+ deviceId: string | null;
3649
+ ip: string | null;
3650
+ }>>>;
3485
3651
  }, "strip", z.ZodTypeAny, {
3486
3652
  viewerCount: number;
3487
3653
  prompt: string | null;
@@ -3508,6 +3674,11 @@ declare const UserSessionsResponseSchema: z.ZodObject<{
3508
3674
  endedAt: number | null;
3509
3675
  actionCount: number;
3510
3676
  updatedAt: number;
3677
+ lastViewer?: {
3678
+ userAgent: string | null;
3679
+ deviceId: string | null;
3680
+ ip: string | null;
3681
+ } | null | undefined;
3511
3682
  }, {
3512
3683
  viewerCount: number;
3513
3684
  prompt: string | null;
@@ -3534,6 +3705,11 @@ declare const UserSessionsResponseSchema: z.ZodObject<{
3534
3705
  endedAt: number | null;
3535
3706
  actionCount: number;
3536
3707
  updatedAt: number;
3708
+ lastViewer?: {
3709
+ userAgent: string | null;
3710
+ deviceId: string | null;
3711
+ ip: string | null;
3712
+ } | null | undefined;
3537
3713
  }>, "many">;
3538
3714
  /** Opaque cursor for the next page, or null when there are no more. */
3539
3715
  nextCursor: z.ZodNullable<z.ZodString>;
@@ -3564,6 +3740,11 @@ declare const UserSessionsResponseSchema: z.ZodObject<{
3564
3740
  endedAt: number | null;
3565
3741
  actionCount: number;
3566
3742
  updatedAt: number;
3743
+ lastViewer?: {
3744
+ userAgent: string | null;
3745
+ deviceId: string | null;
3746
+ ip: string | null;
3747
+ } | null | undefined;
3567
3748
  }[];
3568
3749
  nextCursor: string | null;
3569
3750
  }, {
@@ -3593,6 +3774,11 @@ declare const UserSessionsResponseSchema: z.ZodObject<{
3593
3774
  endedAt: number | null;
3594
3775
  actionCount: number;
3595
3776
  updatedAt: number;
3777
+ lastViewer?: {
3778
+ userAgent: string | null;
3779
+ deviceId: string | null;
3780
+ ip: string | null;
3781
+ } | null | undefined;
3596
3782
  }[];
3597
3783
  nextCursor: string | null;
3598
3784
  }>;
package/dist/index.js CHANGED
@@ -95,7 +95,15 @@ var SessionEventSchema = z.discriminatedUnion("type", [
95
95
  viewerCount: z.number().int(),
96
96
  viewer: ViewerInfoSchema.optional()
97
97
  }),
98
- z.object({ ts: z.number(), type: z.literal("action_recorded"), action: RecordedActionSchema }),
98
+ z.object({
99
+ ts: z.number(),
100
+ type: z.literal("action_recorded"),
101
+ action: RecordedActionSchema,
102
+ /** The viewer that performed this action. Optional for backward
103
+ * compatibility with events recorded before per-action attribution
104
+ * was added. */
105
+ viewer: ViewerInfoSchema.optional()
106
+ }),
99
107
  z.object({ ts: z.number(), type: z.literal("error"), message: z.string(), detail: z.string().optional() })
100
108
  ]);
101
109
  var NewSessionSchema = z.object({
@@ -209,7 +217,10 @@ var SessionInfoSchema = z.object({
209
217
  outcome: SessionOutcomeSchema.nullable(),
210
218
  prompt: z.string().nullable(),
211
219
  publisher: PublisherInfoSchema.nullable(),
212
- target: TargetInfoSchema.nullable()
220
+ target: TargetInfoSchema.nullable(),
221
+ /** Most recent viewer to join (or leave) — what the dashboard list shows
222
+ * as the "picked up by" device. Null until the first viewer connects. */
223
+ lastViewer: ViewerInfoSchema.nullable().optional()
213
224
  });
214
225
  var SessionSummarySchema = z.object({
215
226
  sessionId: z.string(),
@@ -221,7 +232,9 @@ var SessionSummarySchema = z.object({
221
232
  createdAt: z.number(),
222
233
  endedAt: z.number().nullable(),
223
234
  /** Last event-log append timestamp. */
224
- updatedAt: z.number()
235
+ updatedAt: z.number(),
236
+ /** Most recent viewer to join (or leave). Null until first viewer. */
237
+ lastViewer: ViewerInfoSchema.nullable().optional()
225
238
  });
226
239
  var SessionActionsResponseSchema = z.object({
227
240
  sessionId: z.string(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proxyhuman/protocol",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "ProxyHuman wire-format contract: WebSocket message types, REST response shapes, session lifecycle states. Consumed by @proxyhuman/mcp and the api-worker.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",