@ai-matrx/meet 0.8.1 → 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.
@@ -164,11 +164,18 @@ var MeetError = class extends Error {
164
164
  /** What to DO. Rendered to the user for the device codes. */
165
165
  remedy;
166
166
  cause;
167
- constructor(code, message, remedy, cause) {
167
+ /**
168
+ * The join gate's reason code (CORE-DESIGN §2.5) when the server named one: `not_found`,
169
+ * `cancelled`, `ended`, `locked`, `removed`, `lobby_rejects`, `not_invited`… The phase
170
+ * renders `refused:<reason>` (or `ended`) from it — never from the HTTP status.
171
+ */
172
+ reason;
173
+ constructor(code, message, remedy, cause, reason) {
168
174
  super(message);
169
175
  this.name = "MeetError";
170
176
  this.code = code;
171
177
  this.remedy = remedy;
178
+ this.reason = reason ?? null;
172
179
  if (cause !== void 0) this.cause = cause;
173
180
  }
174
181
  /** True when retrying after the host re-establishes a session is the fix. */
@@ -241,7 +248,7 @@ var MEET_ROUTES = {
241
248
  /**
242
249
  * THE POST-MEETING RECORD FOR A READER WITH NO DATABASE (MRF-1). A `GET`,
243
250
  * authorized by the room token this device already holds, carried in the
244
- * `x-meet-room-token` header — never a query parameter, because a bearer
251
+ * `x-meet-pass` header — never a query parameter, because a bearer
245
252
  * credential in a URL lands in access logs, referrers and history.
246
253
  */
247
254
  record: "/api/v1/meet/record",
@@ -249,7 +256,7 @@ var MEET_ROUTES = {
249
256
  recordAccess: "/api/v1/meet/record/access",
250
257
  /**
251
258
  * KEEP YOUR NOTES (2026-10-01): a guest who just created an account presents
252
- * their kept pass in `x-meet-room-token` with their new session, and the
259
+ * their kept pass in `x-meet-pass` with their new session, and the
253
260
  * meeting they attended becomes theirs to read. Idempotent; never a grant.
254
261
  */
255
262
  claim: "/api/v1/meet/claim",
@@ -271,7 +278,7 @@ var MEET_ROUTES = {
271
278
  * Meet wave 2: EVERY in-meeting host power (mute, stop video, mute all, ask to
272
279
  * unmute, spotlight, lower hands, co-host, hand over, rename, remove, report).
273
280
  * Decided by the server from the meeting itself; a guest's pass rides
274
- * `x-meet-room-token`.
281
+ * `x-meet-pass`.
275
282
  */
276
283
  moderate: "/api/v1/meet/moderate",
277
284
  /** Meet wave 2: the SAVED chat — `POST` sends to everyone, `GET ?meeting_id=` reads history. */
@@ -331,11 +338,15 @@ function listenOnlyNotice(media) {
331
338
 
332
339
  // src/core/types.ts
333
340
  var ROLE_RANK = {
334
- host: 3,
335
- cohost: 2,
341
+ host: 4,
342
+ cohost: 3,
343
+ presenter: 2,
336
344
  participant: 1,
337
- guest: 0
345
+ viewer: 0
338
346
  };
347
+ function isLinkFollower(standing) {
348
+ return standing === "guest" || standing === "outsider";
349
+ }
339
350
  function isHostRole(role) {
340
351
  return role === "host" || role === "cohost";
341
352
  }
@@ -413,9 +424,18 @@ function effectiveRole(snapshot) {
413
424
  const fromToken = snapshot.grants.role;
414
425
  return ROLE_RANK[fromRoster] >= ROLE_RANK[fromToken] ? fromRoster : fromToken;
415
426
  }
427
+ function effectiveStanding(snapshot) {
428
+ if (snapshot.grants.standing != null) return snapshot.grants.standing;
429
+ const me = snapshot.participants.find((p) => p.identity === snapshot.localIdentity);
430
+ return me?.standing ?? null;
431
+ }
416
432
  var REACTION_TTL_MS = 5e3;
417
433
 
418
434
  // src/core/observation.ts
435
+ function observedRole(role, standing) {
436
+ if (role === "host" || role === "cohost") return role;
437
+ return isLinkFollower(standing) ? "guest" : "participant";
438
+ }
419
439
  function observedDevice(track) {
420
440
  if (track.enabled) return "on";
421
441
  const refused = track.unavailable;
@@ -443,6 +463,8 @@ function observedPhase(input) {
443
463
  const raw = snapshot.phase;
444
464
  const live = raw === "connected" || raw === "reconnecting";
445
465
  if (endedRecord(snapshot, input.meeting ?? null) && !live) return "ended";
466
+ const reason = raw === "failed" ? snapshot.failure?.reason ?? null : null;
467
+ if (reason !== null) return reason === "ended" ? "ended" : `refused:${reason}`;
446
468
  switch (raw) {
447
469
  case "idle":
448
470
  case "failed":
@@ -463,12 +485,13 @@ function observe(input) {
463
485
  const { snapshot } = input;
464
486
  const phase = observedPhase(input);
465
487
  const inCall = phase === "in_call";
466
- const role = inCall && snapshot !== null ? effectiveRole(snapshot) : "none";
467
- const canAdmit = role !== "none" && ADMITTER_ROLES.has(role);
488
+ const actual = inCall && snapshot !== null ? effectiveRole(snapshot) : "none";
489
+ const canAdmit = actual !== "none" && ADMITTER_ROLES.has(actual);
490
+ const role = actual === "none" || snapshot === null ? "none" : observedRole(actual, effectiveStanding(snapshot));
468
491
  const deviceInPlay = phase === "joining" || inCall;
469
492
  return {
470
493
  phase,
471
- reason: null,
494
+ reason: phase.startsWith("refused:") ? phase.slice("refused:".length) : null,
472
495
  role,
473
496
  connection: snapshot?.phase === "reconnecting" ? "reconnecting" : "stable",
474
497
  hostPresent: inCall && snapshot !== null ? snapshot.participants.some((p) => ADMITTER_ROLES.has(p.role)) : null,
@@ -511,7 +534,7 @@ function participantAttributes(p) {
511
534
  "data-meet-participant": "",
512
535
  "data-meet-participant-identity": p.identity,
513
536
  "data-meet-participant-name": p.displayName,
514
- "data-meet-participant-role": p.role,
537
+ "data-meet-participant-role": observedRole(p.role, p.standing),
515
538
  "data-meet-participant-self": String(p.isLocal)
516
539
  };
517
540
  const quality = observedQuality(p.quality);
@@ -2779,10 +2802,13 @@ function ConnectionDot({ quality }) {
2779
2802
  if (quality === "excellent" || quality === "good" || quality === "unknown") return null;
2780
2803
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: `mx-meet__quality mx-meet__quality--${quality}`, title: `Connection ${quality}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(WifiLowIcon, { width: 14, height: 14 }) });
2781
2804
  }
2782
- function RoleBadge({ role }) {
2805
+ function RoleBadge({
2806
+ role,
2807
+ standing
2808
+ }) {
2783
2809
  if (role === "host") return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "mx-meet__badge", children: "Host" });
2784
2810
  if (role === "cohost") return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "mx-meet__badge", children: "Co-host" });
2785
- if (role === "guest") return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "mx-meet__badge", children: "Guest" });
2811
+ if (isLinkFollower(standing)) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "mx-meet__badge", children: "Guest" });
2786
2812
  return null;
2787
2813
  }
2788
2814
  function ParticipantTile({
@@ -2832,7 +2858,7 @@ function ParticipantTile({
2832
2858
  participant.displayName,
2833
2859
  participant.isLocal ? " (you)" : "",
2834
2860
  participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "mx-meet__badge", children: "AI" }) : null,
2835
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RoleBadge, { role: participant.role })
2861
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RoleBadge, { role: participant.role, standing: participant.standing })
2836
2862
  ] }),
2837
2863
  !participant.micEnabled ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MicOffIcon, { width: 14, height: 14 }) : null,
2838
2864
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(QualityBars, { quality: participant.quality })
@@ -3571,7 +3597,13 @@ function PeoplePanel({
3571
3597
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "mx-meet__person-name", children: [
3572
3598
  participant.displayName,
3573
3599
  participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "mx-meet__you", children: " (you)" }) : null,
3574
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RoleBadge, { role: participant.identity === local ? myRole : participant.role }),
3600
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3601
+ RoleBadge,
3602
+ {
3603
+ role: participant.identity === local ? myRole : participant.role,
3604
+ standing: participant.standing
3605
+ }
3606
+ ),
3575
3607
  isNoteTaker(participant) ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null,
3576
3608
  snapshot?.spotlight === participant.identity ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "mx-meet__badge", children: "Spotlight" }) : null
3577
3609
  ] }),