@ai-matrx/meet 0.8.0 → 0.9.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.
@@ -1,6 +1,6 @@
1
- export { A as AiPanel, a as AttendanceNotice, b as Avatar, C as Captions, c as ChatPanel, d as ConnectionDot, e as ConsentNotice, f as ControlBar, g as ControlButton, H as HostMenu, L as LobbyPanel, M as MeetSkinRoom, h as MeetingOverlays, i as MenuItem, P as PanelShell, j as ParticipantTile, k as PeoplePanel, l as PersonMenu, m as Popover, n as PreJoin, Q as QualityBars, R as ReactionOverlay, o as RecordingIndicator, S as SettingsPanel, p as ShortcutsSheet, q as Stage, T as Toast } from '../components-BOUmOiPj.cjs';
1
+ export { A as AiPanel, a as AttendanceNotice, b as Avatar, C as Captions, c as ChatPanel, d as ConnectionDot, e as ConsentNotice, f as ControlBar, g as ControlButton, H as HostMenu, L as LobbyPanel, M as MeetSkinRoom, h as MeetingOverlays, i as MenuItem, P as PanelShell, j as ParticipantTile, k as PeoplePanel, l as PersonMenu, m as Popover, n as PreJoin, Q as QualityBars, R as ReactionOverlay, o as RecordingIndicator, S as SettingsPanel, p as ShortcutsSheet, q as Stage, T as Toast } from '../components-BeCQ9h0h.cjs';
2
2
  import { ReactNode, SVGProps } from 'react';
3
- import { C as CollabPanel } from '../collab-Bss-_Jfp.cjs';
3
+ import { C as CollabPanel } from '../collab-B6scmSST.cjs';
4
4
 
5
5
  /**
6
6
  * POLLS, Q&A, THE SHARED WHITEBOARD AND BREAKOUT ROOMS — the in-room surfaces (Meet wave 5).
@@ -1,6 +1,6 @@
1
- export { A as AiPanel, a as AttendanceNotice, b as Avatar, C as Captions, c as ChatPanel, d as ConnectionDot, e as ConsentNotice, f as ControlBar, g as ControlButton, H as HostMenu, L as LobbyPanel, M as MeetSkinRoom, h as MeetingOverlays, i as MenuItem, P as PanelShell, j as ParticipantTile, k as PeoplePanel, l as PersonMenu, m as Popover, n as PreJoin, Q as QualityBars, R as ReactionOverlay, o as RecordingIndicator, S as SettingsPanel, p as ShortcutsSheet, q as Stage, T as Toast } from '../components-BmgstFx_.js';
1
+ export { A as AiPanel, a as AttendanceNotice, b as Avatar, C as Captions, c as ChatPanel, d as ConnectionDot, e as ConsentNotice, f as ControlBar, g as ControlButton, H as HostMenu, L as LobbyPanel, M as MeetSkinRoom, h as MeetingOverlays, i as MenuItem, P as PanelShell, j as ParticipantTile, k as PeoplePanel, l as PersonMenu, m as Popover, n as PreJoin, Q as QualityBars, R as ReactionOverlay, o as RecordingIndicator, S as SettingsPanel, p as ShortcutsSheet, q as Stage, T as Toast } from '../components-D0TqyeiY.js';
2
2
  import { ReactNode, SVGProps } from 'react';
3
- import { C as CollabPanel } from '../collab-Bss-_Jfp.js';
3
+ import { C as CollabPanel } from '../collab-B6scmSST.js';
4
4
 
5
5
  /**
6
6
  * POLLS, Q&A, THE SHARED WHITEBOARD AND BREAKOUT ROOMS — the in-room surfaces (Meet wave 5).
@@ -59,11 +59,18 @@ var MeetError = class extends Error {
59
59
  /** What to DO. Rendered to the user for the device codes. */
60
60
  remedy;
61
61
  cause;
62
- constructor(code, message, remedy, cause) {
62
+ /**
63
+ * The join gate's reason code (CORE-DESIGN §2.5) when the server named one: `not_found`,
64
+ * `cancelled`, `ended`, `locked`, `removed`, `lobby_rejects`, `not_invited`… The phase
65
+ * renders `refused:<reason>` (or `ended`) from it — never from the HTTP status.
66
+ */
67
+ reason;
68
+ constructor(code, message, remedy, cause, reason) {
63
69
  super(message);
64
70
  this.name = "MeetError";
65
71
  this.code = code;
66
72
  this.remedy = remedy;
73
+ this.reason = reason ?? null;
67
74
  if (cause !== void 0) this.cause = cause;
68
75
  }
69
76
  /** True when retrying after the host re-establishes a session is the fix. */
@@ -136,7 +143,7 @@ var MEET_ROUTES = {
136
143
  /**
137
144
  * THE POST-MEETING RECORD FOR A READER WITH NO DATABASE (MRF-1). A `GET`,
138
145
  * authorized by the room token this device already holds, carried in the
139
- * `x-meet-room-token` header — never a query parameter, because a bearer
146
+ * `x-meet-pass` header — never a query parameter, because a bearer
140
147
  * credential in a URL lands in access logs, referrers and history.
141
148
  */
142
149
  record: "/api/v1/meet/record",
@@ -144,7 +151,7 @@ var MEET_ROUTES = {
144
151
  recordAccess: "/api/v1/meet/record/access",
145
152
  /**
146
153
  * KEEP YOUR NOTES (2026-10-01): a guest who just created an account presents
147
- * their kept pass in `x-meet-room-token` with their new session, and the
154
+ * their kept pass in `x-meet-pass` with their new session, and the
148
155
  * meeting they attended becomes theirs to read. Idempotent; never a grant.
149
156
  */
150
157
  claim: "/api/v1/meet/claim",
@@ -166,7 +173,7 @@ var MEET_ROUTES = {
166
173
  * Meet wave 2: EVERY in-meeting host power (mute, stop video, mute all, ask to
167
174
  * unmute, spotlight, lower hands, co-host, hand over, rename, remove, report).
168
175
  * Decided by the server from the meeting itself; a guest's pass rides
169
- * `x-meet-room-token`.
176
+ * `x-meet-pass`.
170
177
  */
171
178
  moderate: "/api/v1/meet/moderate",
172
179
  /** Meet wave 2: the SAVED chat — `POST` sends to everyone, `GET ?meeting_id=` reads history. */
@@ -226,11 +233,15 @@ function listenOnlyNotice(media) {
226
233
 
227
234
  // src/core/types.ts
228
235
  var ROLE_RANK = {
229
- host: 3,
230
- cohost: 2,
236
+ host: 4,
237
+ cohost: 3,
238
+ presenter: 2,
231
239
  participant: 1,
232
- guest: 0
240
+ viewer: 0
233
241
  };
242
+ function isLinkFollower(standing) {
243
+ return standing === "guest" || standing === "outsider";
244
+ }
234
245
  function isHostRole(role) {
235
246
  return role === "host" || role === "cohost";
236
247
  }
@@ -308,9 +319,18 @@ function effectiveRole(snapshot) {
308
319
  const fromToken = snapshot.grants.role;
309
320
  return ROLE_RANK[fromRoster] >= ROLE_RANK[fromToken] ? fromRoster : fromToken;
310
321
  }
322
+ function effectiveStanding(snapshot) {
323
+ if (snapshot.grants.standing != null) return snapshot.grants.standing;
324
+ const me = snapshot.participants.find((p) => p.identity === snapshot.localIdentity);
325
+ return me?.standing ?? null;
326
+ }
311
327
  var REACTION_TTL_MS = 5e3;
312
328
 
313
329
  // src/core/observation.ts
330
+ function observedRole(role, standing) {
331
+ if (role === "host" || role === "cohost") return role;
332
+ return isLinkFollower(standing) ? "guest" : "participant";
333
+ }
314
334
  function observedDevice(track) {
315
335
  if (track.enabled) return "on";
316
336
  const refused = track.unavailable;
@@ -338,6 +358,8 @@ function observedPhase(input) {
338
358
  const raw = snapshot.phase;
339
359
  const live = raw === "connected" || raw === "reconnecting";
340
360
  if (endedRecord(snapshot, input.meeting ?? null) && !live) return "ended";
361
+ const reason = raw === "failed" ? snapshot.failure?.reason ?? null : null;
362
+ if (reason !== null) return reason === "ended" ? "ended" : `refused:${reason}`;
341
363
  switch (raw) {
342
364
  case "idle":
343
365
  case "failed":
@@ -358,12 +380,13 @@ function observe(input) {
358
380
  const { snapshot } = input;
359
381
  const phase = observedPhase(input);
360
382
  const inCall = phase === "in_call";
361
- const role = inCall && snapshot !== null ? effectiveRole(snapshot) : "none";
362
- const canAdmit = role !== "none" && ADMITTER_ROLES.has(role);
383
+ const actual = inCall && snapshot !== null ? effectiveRole(snapshot) : "none";
384
+ const canAdmit = actual !== "none" && ADMITTER_ROLES.has(actual);
385
+ const role = actual === "none" || snapshot === null ? "none" : observedRole(actual, effectiveStanding(snapshot));
363
386
  const deviceInPlay = phase === "joining" || inCall;
364
387
  return {
365
388
  phase,
366
- reason: null,
389
+ reason: phase.startsWith("refused:") ? phase.slice("refused:".length) : null,
367
390
  role,
368
391
  connection: snapshot?.phase === "reconnecting" ? "reconnecting" : "stable",
369
392
  hostPresent: inCall && snapshot !== null ? snapshot.participants.some((p) => ADMITTER_ROLES.has(p.role)) : null,
@@ -406,7 +429,7 @@ function participantAttributes(p) {
406
429
  "data-meet-participant": "",
407
430
  "data-meet-participant-identity": p.identity,
408
431
  "data-meet-participant-name": p.displayName,
409
- "data-meet-participant-role": p.role,
432
+ "data-meet-participant-role": observedRole(p.role, p.standing),
410
433
  "data-meet-participant-self": String(p.isLocal)
411
434
  };
412
435
  const quality = observedQuality(p.quality);
@@ -2687,10 +2710,13 @@ function ConnectionDot({ quality }) {
2687
2710
  if (quality === "excellent" || quality === "good" || quality === "unknown") return null;
2688
2711
  return /* @__PURE__ */ jsx5("span", { className: `mx-meet__quality mx-meet__quality--${quality}`, title: `Connection ${quality}`, children: /* @__PURE__ */ jsx5(WifiLowIcon, { width: 14, height: 14 }) });
2689
2712
  }
2690
- function RoleBadge({ role }) {
2713
+ function RoleBadge({
2714
+ role,
2715
+ standing
2716
+ }) {
2691
2717
  if (role === "host") return /* @__PURE__ */ jsx5("span", { className: "mx-meet__badge", children: "Host" });
2692
2718
  if (role === "cohost") return /* @__PURE__ */ jsx5("span", { className: "mx-meet__badge", children: "Co-host" });
2693
- if (role === "guest") return /* @__PURE__ */ jsx5("span", { className: "mx-meet__badge", children: "Guest" });
2719
+ if (isLinkFollower(standing)) return /* @__PURE__ */ jsx5("span", { className: "mx-meet__badge", children: "Guest" });
2694
2720
  return null;
2695
2721
  }
2696
2722
  function ParticipantTile({
@@ -2740,7 +2766,7 @@ function ParticipantTile({
2740
2766
  participant.displayName,
2741
2767
  participant.isLocal ? " (you)" : "",
2742
2768
  participant.isAgent ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__badge", children: "AI" }) : null,
2743
- /* @__PURE__ */ jsx5(RoleBadge, { role: participant.role })
2769
+ /* @__PURE__ */ jsx5(RoleBadge, { role: participant.role, standing: participant.standing })
2744
2770
  ] }),
2745
2771
  !participant.micEnabled ? /* @__PURE__ */ jsx5(MicOffIcon, { width: 14, height: 14 }) : null,
2746
2772
  /* @__PURE__ */ jsx5(QualityBars, { quality: participant.quality })
@@ -3479,7 +3505,13 @@ function PeoplePanel({
3479
3505
  /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
3480
3506
  participant.displayName,
3481
3507
  participant.identity === local ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__you", children: " (you)" }) : null,
3482
- /* @__PURE__ */ jsx5(RoleBadge, { role: participant.identity === local ? myRole : participant.role }),
3508
+ /* @__PURE__ */ jsx5(
3509
+ RoleBadge,
3510
+ {
3511
+ role: participant.identity === local ? myRole : participant.role,
3512
+ standing: participant.standing
3513
+ }
3514
+ ),
3483
3515
  isNoteTaker(participant) ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null,
3484
3516
  snapshot?.spotlight === participant.identity ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__badge", children: "Spotlight" }) : null
3485
3517
  ] }),