import { M as MeetHost } from './provider-Bo0_3bVk.js'; export { a as MeetDiagnostic, b as MeetProvider, c as MeetProviderProps, u as useCanRecord, d as useDeviceSnapshot, e as useIsHost, f as useLocalUserId, g as useMeetHost, h as useMeetSnapshot, i as useRequiredMeetHost, j as useRole } from './provider-Bo0_3bVk.js'; import { ReactNode, ComponentType } from 'react'; import { ObservedPhase, MeetObservation, GuestRecordAccessSetting, GuestRecordAccessResolution, MeetingRecordBundle, MeetingRecordCache, Stage } from './core.js'; export { ATTENDANCE_CSV_HEADER, AnnounceResult, ApplyRoomEventArgs, AttendanceKind, AttendanceRow, CALL_INVITE_KIND, CALL_INVITE_VERSION, CallInviteHandlerOptions, CallInvitePayload, CollabRuntime, CollabStoreLike, DEFAULT_PAGE_SIZE, FollowUpDraft, FollowUpRecipient, FollowUpSendResult, GUEST_RECORD_ACCESS_CHOICES, GUEST_RECORD_ACCESS_LEVELS, GUEST_RECORD_ACCESS_METADATA_KEY, GUEST_RECORD_NOT_SHARED, GuestRecordAccess, LiveKitDriverOptions, MEETING_INVITE_KIND, MEETING_INVITE_VERSION, MEETING_RECORD_GRACE_MS, MEET_EVENTS, MEET_REACTIONS, MeetCapabilities, MeetEvent, MeetingChatHistory, MeetingInviteHandlerOptions, MeetingInvitePayload, MeetingRecordAnswer, MeetingRecordChange, MeetingRecordFailure, MeetingRecordParts, MeetingRecordRestriction, MeetingRecordRestrictionNotice, MeetingRecordState, ObserveInput, ObservedConnection, REFUSED_ABSENCE, ROOM_EVENTS, ROOM_EVENT_PREFIX, RoomEventOutcome, RoomEventTopic, SpeakingWhileMutedDetector, SpeakingWhileMutedOptions, StageArgs, TranscriptBlock, TranscriptFormat, TranscriptMatch, UnsupportedReason, WrapUpStatus, absenceSentence, activeWrapUpSummary, activityAttention, announceMeeting, applyRoomEvent, assembleMeetingRecord, attendanceCsv, attendanceReport, attendanceTotals, attendeeKey, availableActivities, callInviteAction, callInviteText, callStateLabel, captionSegment, clockPosition, computeStage, countLabel, createCallInviteHandler, createLiveKitDriver, createMeetingInviteHandler, createMeetingRecordCache, createSpeakingWhileMutedDetector, createWebEffectsStorage, detectCapabilities, gridColumns, groupTranscript, guestRecordAccessExplanation, guestRecordAccessLabel, guestRecordAccessSetting, hasEnded, isMobileUserAgent, isRoomEventTopic, loadFollowUpDraft, loadGuestMeetingRecord, loadMeetingChat, loadMeetingRecord, loadMeetingRecordParts, mapConnectionState, mapQuality, meetingInviteAction, meetingLength, meetingTopic, meetingWhen, mergeCaption, mergeRecord, microphoneNoticeCode, moveToRoom, nextTranslationBatch, normalizeSpoken, notesDocument, observeMeeting, observedDevice, observedPhase, observedQuality, orderParticipants, participantAttributes, participantSummary, performCollab, playableRecordingFileId, pushMeetingToGoogleCalendar, readableTranscript, recordingNotice, recordingOffsetMs, roomTopic, rootAttributes, searchTranscript, sendFollowUp, setCaptionLanguage, setGuestRecordAccess, snapshotParticipant, staticObservation, summarizeMeetingRecordRestrictions, takeMoveRequest, takePanelRequest, transcriptDocument, uniqueAttendees, unsupportedWords, untranslatedLines, userTopic, wasRefused, wrapUpStatus } from './core.js'; import { b as MeetingRecord, c as ParticipantIdentity, T as TranscriptSource, C as CallInvite, U as UserId, f as CallMode, d as MeetParticipant, L as LobbyEntry, g as MeetingNote, W as WrapUpAnnouncement, R as RoomName, S as StageLayout, h as MeetingId, O as OrganizationId, i as MeetingAppPanel, j as CollabSnapshot, e as CollabPanel, P as ParticipantRole } from './collab-B85s8sQ8.js'; export { A as AccessTokenSource, k as AdmissionState, l as CAPTION_LANGUAGES, m as CallId, n as CallState, o as CallablePerson, p as ConnectionQuality, E as EMPTY_COLLAB, F as FILE_SESSION_PATH, I as InviteeInput, q as InviteeRole, J as JsonObject, r as JsonValue, M as MeetApi, s as MeetApiOptions, t as MeetApiRequest, u as MeetAppFocus, v as MeetBreakoutBroadcast, w as MeetBreakoutPlan, x as MeetBreakoutRoom, y as MeetCollabSettings, z as MeetFileMedia, a as MeetIdentity, B as MeetPoll, D as MeetPollOption, G as MeetPollState, H as MeetQuestion, K as MeetQuestionState, N as MeetStroke, Q as MeetingActivities, V as MeetingAttendee, X as MeetingChanges, Y as MeetingInvitee, Z as MeetingKind, _ as MeetingNoteKind, $ as MeetingOccurrence, a0 as MeetingSettings, a1 as NoteTakerState, a2 as ORGANIZATION_HEADER, a3 as ObserversVisibleTo, a4 as OccurrenceOverride, a5 as OccurrenceState, a6 as ParticipantStanding, a7 as ROLE_RANK, a8 as RecordingPolicy, a9 as RecordingRecord, aa as RecordingState, ab as RsvpAnswer, ac as RsvpInvitation, ad as RsvpState, ae as TranscriptSegment, af as UpcomingOccurrence, ag as appPanelOf, ah as applyCollabPacket, ai as asCallId, aj as asMeetingId, ak as asOrganizationId, al as asParticipantIdentity, am as asRoomName, an as asUserId, ao as assignedRoom, ap as autoAssign, aq as breakoutClosingMs, ar as breakoutRemainingMs, as as captureHeldOf, at as collabFromState, au as createMeetApi, av as defaultCaptionLanguage, aw as fileDownloadPath, ax as focusFromRow, ay as isGuest, az as isHostRole, aA as isLinkFollower, aB as isObserverRole, aC as loadMeetingActivities, aD as scheduleSettingsPatch, aE as withItem } from './collab-B85s8sQ8.js'; import { h as ModerationRequest, i as ModerationResult, j as MediaEffects, N as NoteTakerStatus, k as MeetAnswerCoverage, l as MeetPhase, J as JoinRequest, L as LeaveChoice, m as LeavePolicy, n as LocalMediaState, o as ModerationNotice, p as CollabRequest, g as MeetSnapshot, f as DeviceSnapshot, q as ConnectionRegion, S as ShareRegion } from './in-room-B9pch08I.js'; export { A as AskArgs, r as AudioProcessing, B as BrowserFamily, s as CONSENT_NOTICE_ATTRIBUTE, C as CallCenter, t as CallCenterOptions, u as CallOutcomePhase, v as CollabAction, w as CollabResult, x as ConnectionPolicy, y as ConnectionSupervisor, z as ConnectionSupervisorOptions, E as CreateCallInviteInput, F as CreateMeetingInput, G as DATA_TOPICS, H as DEFAULT_CONNECTION_POLICY, K as DEFAULT_EFFECTS, O as DEFAULT_LEAVE_POLICY, P as DataTopic, Q as DeviceKind, D as DeviceManager, U as DeviceManagerOptions, V as DeviceNotice, W as DeviceOffer, X as DeviceStorage, Y as DeviceUnavailableReason, Z as DriverConnectionState, _ as DriverParticipant, $ as DriverTrackKind, a0 as DriverTranscription, a1 as END_MEETING_NOT_SERVED, a2 as EffectsStorage, a3 as EndMeetingResult, a4 as ExitInput, a5 as ExitPhase, a6 as ExitResolution, a7 as ExitServerWord, a8 as Ghost, a9 as HostLeavePrompt, aa as IDLE_MEDIA, ab as IDLE_MEDIA_REGION, ac as IDLE_PHASES, ad as IDLE_TRACK, I as InRoomClient, ae as InRoomClientOptions, af as JOIN_REFUSAL_REASONS, ag as JoinRefusalReason, ah as LISTEN_ONLY_NOTICE, ai as LIVEKIT_BASE_DELAYS_MS, aj as LIVE_PHASES, ak as LibraryRecording, al as LocalTrackState, am as MEETING_PASS_HEADER, an as MEET_ANSWER_CONTEXT_EVENT, ao as MEET_ANSWER_EVENTS, ap as MEET_ROUTES, aq as MEET_RPCS, ar as MEET_SCHEMA, as as MEET_TABLES, at as MODERATION_ACTIONS, au as MediaDevicesLike, av as MediaKind, aw as MediaPlatform, ax as MediaRegionState, ay as MediaSupervisor, az as MediaSupervisorOptions, aA as MediaUnavailable, d as MeetAi, aB as MeetAiAnswer, aC as MeetAiOptions, aD as MeetDevice, aE as MeetError, aF as MeetErrorCode, aG as MeetGrants, aH as MeetPatch, c as MeetRepository, aI as MeetRoomDriver, M as MeetStore, aJ as MeetingSearchHit, aK as MeetingSearchSource, a as MeetingSession, aL as MeetingSessionOptions, aM as ModerationAction, aN as NOTE_TAKER_IDENTITY_PREFIX, aO as NOTE_TAKER_METADATA_KEY, aP as NO_GRANTS, aQ as NO_SHARE, aR as NameBook, aS as NetworkPort, aT as NoteTakerDispatch, aU as NoteTakerRefusal, aV as OsFamily, aW as PARTICIPANT_CAN_RECORD_ATTRIBUTE, aX as PARTICIPANT_HAND_ATTRIBUTE, aY as PARTICIPANT_ROLE_ATTRIBUTE, aZ as PARTICIPANT_STANDING_ATTRIBUTE, a_ as PermissionReading, a$ as PhaseEvent, b0 as PhaseEventType, b1 as PlatformDevice, b2 as REACTION_TTL_MS, b3 as RESUME_WINDOW_MS, b4 as ReconnectPolicyLike, b5 as ReconnectPolicyOptions, b as RecordingController, b6 as RecordingControllerOptions, b7 as RepositoryOptions, b8 as ResumeMarker, b9 as ResumeStorage, ba as RoomChatMessage, e as RoomDriverFactory, bb as RoomDriverHandlers, R as RoomEngine, bc as RoomEngineOptions, bd as RoomReaction, be as RoomToken, bf as RoomTokenStorage, bg as ScheduleMeetingInput, bh as TRANSCRIPTION_ATTRIBUTES, bi as TRANSCRIPTION_TOPIC, T as TokenClient, bj as TokenClientOptions, bk as TokenRequest, bl as VideoEffect, bm as WAITING_PHASES, bn as admissionPhase, bo as autoRejoinDelayMs, bp as canModerate, bq as canModerateParticipant, br as canTransition, bs as changesPatch, bt as classifyDeviceFailure, bu as connectionPolicyFrom, bv as createCallCenter, bw as createConnectionSupervisor, bx as createDeviceManager, by as createInRoomClient, bz as createMediaSupervisor, bA as createMeetAi, bB as createMeetRepository, bC as createMeetStore, bD as createMeetingSession, bE as createMemoryDeviceStorage, bF as createReachabilityProbe, bG as createReconnectPolicy, bH as createRecordingController, bI as createRoomEngine, bJ as createTokenClient, bK as createWebDeviceStorage, bL as createWebNetworkPort, bM as createWebResumeStorage, bN as createWebRoomTokenStorage, bO as detectBrowser, bP as detectOs, bQ as deviceChipLabel, bR as deviceFixSteps, bS as deviceNoticeCode, bT as deviceUnavailableReason, bU as displayNameFor, bV as hostUserIds, bW as httpUrlOf, bX as invalidMeetResponse, bY as isGuestIdentity, bZ as isJoinRefusalReason, b_ as isListenOnly, b$ as isLivePhase, c0 as isNoteTaker, c1 as isRealName, c2 as isRefusedPhase, c3 as isUnannouncedDeparture, c4 as isWaitingPhase, c5 as learnName, c6 as learnNames, c7 as leaveChoices, c8 as leavePolicyFrom, c9 as listenOnlyNotice, ca as meetingLink, cb as meetingPassHeaders, cc as meetingPath, cd as meetingSlug, ce as mergeGhosts, cf as nextPhase, cg as normalizeDeviceError, ch as normalizeMeetError, ci as noteTakerIdentity, cj as noteTakerLabel, ck as noteTakerParticipant, cl as noteTakerStatus, cm as parseRoomToken, cn as projectInvitee, co as projectLibraryRecording, cp as projectNote, cq as projectOccurrence, cr as projectOverride, cs as projectParticipant, ct as projectRsvpInvitation, cu as projectSearchHit, cv as projectSegment, cw as projectUpcoming, cx as readRefusalBody, cy as reasonOf, cz as recordingLabel, cA as refusalPhase, cB as rememberedMeetingPass, cC as resolveExit, cD as roleOf, cE as settingsPatch, cF as snippetRuns, cG as unavailableFrom, cH as webMediaPlatform } from './in-room-B9pch08I.js'; export { G as GuestRecordAccessControl } from './components-Bv605p5S.js'; import '@ai-matrx/messaging'; import 'livekit-client'; import '@ai-matrx/data/realtime'; import '@ai-matrx/browser-audio/core'; /** * THE OBSERVATION ROOT (CORE-DESIGN §5.6, step S0). * * Exactly one `[data-meet-root]` per tab on a meeting page, carrying the * HARNESS-CONTRACT's attributes derived from the store (`core/observation.ts`). * The package renders it once — `` wraps every screen in it, and a * consumer that draws its own screen around the room (link resolution, the * guest-name step, a Board layout) wraps that screen in `` too, with * a `phase` when there is no store yet. * * The wrapper is `display: contents`: it generates no box, so no layout, size * or stacking changes; it exists only to carry the attributes. It also * publishes `window.__matrxMeet` — diagnostics only, never a verdict. */ interface CoreRootOptions { /** The row the consumer resolved (the guest lane has no other copy). */ readonly meeting?: MeetingRecord | null | undefined; /** A screen the consumer renders before any store exists (resolving, a dead link). */ readonly phase?: ObservedPhase | undefined; readonly reason?: string | null | undefined; } /** The observation for this tab, one stable object per change. */ declare function useCoreObservation(options?: CoreRootOptions): MeetObservation; /** The root element's `data-meet-*` attributes. Spread onto ONE element per tab. */ declare function useCoreRootProps(options?: CoreRootOptions): Record; /** `` — the one observation root. Generates no box. */ declare function MeetRoot({ children, ...options }: CoreRootOptions & { children?: ReactNode; }): ReactNode; /** * THE HOOKS. Thin shells over the framework-free core — every one of them * exists so a consumer never writes the sequence itself. * * The rule that shapes this file: a hook returns DATA and ACTIONS, never a * "you must also call this on unmount" instruction. `useTrack` hands back a ref * callback whose cleanup is the detach; `useRoom` disposes with the component. * A correct-usage checklist in a README is a bug waiting for a deadline. * * 🚨 **NO HOOK IN THIS FILE THROWS WHEN THE PROVIDER IS INERT** (0.2.1). * `` is deliberately inert until a client, an organization and an * identity are all real — which is EVERY server render, every signed-out * visitor, and every moment before the active organization hydrates. Through * 0.2.0 these hooks called `useRequiredMeetHost()`, so the exact three-line * integration the README prescribes returned a 500 on every route for every * such visitor, and the first real consumer had to wrap our own components in * a host-side guard (register MRI-D1). A hook now reports an inert runtime as * DATA — empty lists, `canCall: false`, `available: false` — so the components * above render nothing or an honest sentence on their own. Only an ACTION * invoked with no runtime fails, and it fails loudly with a remedy; it can not * be reached from a surface that renders correctly. */ interface UseRoomResult { /** The contract phase, verbatim (CORE-DESIGN §3.1). */ readonly phase: MeetPhase; readonly participants: readonly MeetParticipant[]; readonly failure: { readonly message: string; readonly remedy: string; } | null; /** S7: already in this meeting on another tab or device — the pre-join offers the choice. */ readonly secondDevice: { readonly rule: string; } | null; join: (request: JoinRequest) => Promise; /** S7: offer Switch here / Join here too BEFORE Join when another tab of this browser has the person live. */ checkElsewhere: (roomName: RoomName) => Promise; leave: () => Promise; toggleMicrophone: () => Promise; toggleCamera: () => Promise; toggleScreenShare: () => Promise; /** False where the browser cannot share a screen at all (iOS), or the meeting's rule keeps this person from it: the control is absent. */ readonly canShareScreen: boolean; /** Someone ELSE is presenting right now, under a one-at-a-time rule: pressing Share asks first (`share-takeover`). */ /** False when the meeting's `share_who_can` rule keeps this person from presenting (the control is absent; no "present from a computer" hint either). */ readonly sharingAllowed: boolean; readonly otherPresenter: { readonly name: string; readonly rule: "one_takeover" | "one_replace"; } | null; toggleHand: () => Promise; react: (emoji: string) => Promise; /** To EVERYONE — saved through the server (Meet wave 2). */ sendChat: (text: string) => Promise; /** To ONE person — data plane only, never saved. */ sendPrivateChat: (to: ParticipantIdentity, text: string) => Promise; pin: (identity: ParticipantIdentity | null) => void; setLayout: (layout: StageLayout) => void; readonly local: MeetParticipant | null; } declare function useRoom(): UseRoomResult; /** The stage, recomputed only when the roster or the layout actually changes. */ declare function useStage(pageSize?: number): Stage; /** * Attach a participant's media to an element. The returned ref callback's * CLEANUP is the detach — there is nothing a consumer can forget to call. */ declare function useTrack(identity: ParticipantIdentity | null, kind: "camera" | "microphone" | "screen"): (element: HTMLMediaElement | null) => void; interface UseCallsResult { readonly incoming: readonly CallInvite[]; readonly outgoing: CallInvite | null; /** `null` for a guest identity — the UI renders nothing rather than a dead button. */ readonly canCall: boolean; call: (people: readonly UserId[], mode: CallMode) => Promise; accept: (invite: CallInvite) => Promise; decline: (invite: CallInvite, message?: string) => Promise; cancel: (invite: CallInvite) => Promise; } declare function useCalls(): UseCallsResult; interface UseLobbyResult { readonly waiting: readonly LobbyEntry[]; /** People this host (or a co-host) declined, who stay declined until it is lifted. */ readonly declined: readonly LobbyEntry[]; readonly canAdmit: boolean; admit: (entry: LobbyEntry) => Promise; deny: (entry: LobbyEntry) => Promise; admitAll: () => Promise; /** Lift a denial (`meet_undeny`) so the person may ask again. */ undeny: (entry: LobbyEntry) => Promise; } declare function useLobby(): UseLobbyResult; interface UseLeaveResult { /** What Leave offers this person, in order (S8: role + the meeting's `host_leave_prompt`). */ readonly choices: readonly LeaveChoice[]; readonly policy: LeavePolicy; /** The people a host may hand the run to (everyone else here, observers excluded). */ readonly candidates: readonly MeetParticipant[]; leave: () => Promise; /** End the meeting for everyone (server-decided; the room then ends for all, this tab too). */ endForAll: () => Promise; /** Hand the run's host powers to `person`, then leave. */ assignAndLeave: (person: MeetParticipant) => Promise; } /** S8 `leave-or-end-choice` / `host-leave-assign`: the Leave control's one read. */ declare function useLeave(): UseLeaveResult; interface UseRecordingResult { readonly state: string; readonly label: string | null; readonly canStart: boolean; readonly canStop: boolean; readonly consentNotice: string | null; start: () => Promise; stop: () => Promise; } declare function useRecording(): UseRecordingResult; /** One line of the transcript, as a panel renders it. */ interface TranscriptLine { readonly id: string; /** Who said it, as the room knows them. Surfaces group by THIS, not by name. */ readonly identity: ParticipantIdentity; readonly speaker: string; readonly text: string; readonly final: boolean; /** `caption` is a live hint; `record` is the durable transcript (D16). */ readonly source: TranscriptSource; } interface UseMeetAiResult { /** The note-taker's honest state, and the server's refusal if there was one. */ readonly noteTaker: NoteTakerStatus; /** The sentence for that state. Never a bare enum, never a spinner. */ readonly noteTakerLabel: string; /** True only for a host of a meeting whose AI is on. Guests get no control. */ readonly canControlNoteTaker: boolean; /** Live-window notes, oldest first. */ readonly notes: readonly MeetingNote[]; readonly decisions: readonly MeetingNote[]; readonly actionItems: readonly MeetingNote[]; /** The wrap-up summary, once the meeting has produced one. */ readonly summary: MeetingNote | null; /** * The wrap-up pass ANNOUNCED itself into this room (MRI-A12). `null` means it * has not been announced HERE — never that no summary exists. The ordinary * ending path deletes the LiveKit room before the pass runs, so this is * normally null and the summary is read on the post-meeting record. */ readonly wrapUp: WrapUpAnnouncement | null; readonly transcript: readonly TranscriptLine[]; readonly asking: boolean; /** The answer SO FAR. It grows while the answer streams. */ readonly answer: string | null; readonly coverage: MeetAnswerCoverage | null; /** The server's phase while an answer is being built. */ readonly phase: string | null; readonly error: { readonly message: string; readonly remedy: string; } | null; ask: (question: string) => Promise; startNoteTaker: () => Promise; stopNoteTaker: () => Promise; } /** * THE MEETING ASSISTANT, as a surface needs it. * * Everything below is DATA, including every failure. There is no state in which * this hook returns a spinner with nothing behind it: the note-taker is in one * of five named states or the server refused with a sentence, and an answer is * either arriving (visibly, token by token) or has failed with a remedy. */ declare function useMeetAi(): UseMeetAiResult; /** * CAPTIONS FOR ME (`captions-toggle`, `captions-unavailable`). * * The toggle is the viewer's own: it never changes what anyone else sees. Turning it on asks the * server to make sure the note-taker (the speech-to-text agent) is in the room, and the state * is read from what is TRUE — the note-taker's real state and the server's refusal — never from * a timer: `unavailable` carries the server's own sentence. */ interface UseCaptionsResult { readonly on: boolean; readonly state: "off" | "starting" | "live" | "unavailable"; /** Why captions are unavailable, in the server's words (or the note-taker's state). */ readonly reason: string | null; readonly remedy: string | null; readonly toggle: () => void; /** Try again after `unavailable`: asks for captions afresh and restarts the start ceiling. */ readonly retry: () => void; } declare function useCaptions(): UseCaptionsResult; /** * ENDING THE MEETING FOR EVERYONE — a host control with an honest failure. * * `POST /v1/meet/end` is served by MRI-A6. A server that has not landed it * answers 404, and this hook reports that as the sentence * `END_MEETING_NOT_SERVED` rather than pretending the meeting ended or leaving * a button that appears to do nothing. */ interface UseEndMeetingResult { readonly canEnd: boolean; readonly ending: boolean; readonly ended: boolean; /** The honest sentence when the attempt did not end the meeting. */ readonly notice: string | null; end: () => Promise; } declare function useEndMeeting(): UseEndMeetingResult; /** * THE CONSENT NOTICE (D10) — a property of this package, never a prop. * * Returns the sentence every participant must see while an agent is in the * room, or `null` when none is. There is deliberately no way to turn it off: * the org's policy decides whether a note-taker may run, and it never decides * whether the people in the room are told about it. */ declare function useConsentNotice(): string | null; declare function useLocalMedia(): LocalMediaState; /** * The listen-only sentence, or `null` while the microphone is live. The remedy, * when the device was refused rather than declined, is on * `useLocalMedia().microphone.unavailable`. */ declare function useListenOnlyNotice(): string | null; /** Live reactions, already expired. Rendering stale confetti is the alternative. */ declare function useReactions(): readonly { id: string; emoji: string; }[]; /** A ticking duration for the call header. One timer, not one per component. */ declare function useElapsed(startedAt: string | null): number; /** Whether the local actor may moderate a given participant. One rank check. */ declare function useCanModerate(target: MeetParticipant | undefined): boolean; /** * 🚨 EVERY HOST POWER, THROUGH THE SERVER (MRI-A11 → Meet wave 2). * * `canModerate` is the rank check — a host outranks a co-host outranks * everyone, and NOBODY may moderate themselves — so a surface renders a control * only where it would actually be honored. The act itself is a server call * (`core/in-room.ts`): through 0.7.x mute and remove were data packets nothing * listened to, which made them buttons that did nothing. * * `notice` is the server's last sentence (or refusal) for the actor — a control * that acted and said nothing is indistinguishable from one that did nothing. */ interface UseHostControlsResult { readonly isHost: boolean; /** The host itself (not a co-host) — only the host hands the meeting over. */ readonly isOwner: boolean; readonly notice: { readonly text: string; readonly failed: boolean; } | null; readonly busy: boolean; clearNotice: () => void; canModerate: (target: MeetParticipant) => boolean; run: (request: ModerationRequest) => Promise; mute: (target: MeetParticipant) => Promise; remove: (target: MeetParticipant) => Promise; } declare function useHostControls(): UseHostControlsResult; /** * THE HAND QUEUE — raised hands in the order they went up (Meet wave 2). * First raised, first called on; a late joiner learns the order from each * client's re-announcement (`room.ts`). */ declare function useHandQueue(): readonly MeetParticipant[]; /** This participant's noise suppression and background, and the setter. */ interface UseMediaEffectsResult { readonly effects: MediaEffects; /** False = this browser cannot run a background effect; the control is absent. */ readonly backgroundsSupported: boolean; set: (next: Partial) => Promise; } declare function useMediaEffects(): UseMediaEffectsResult; /** What a host last did to THIS participant, and a way to dismiss it. */ declare function useModerationNotice(): { notice: ModerationNotice | null; dismiss: () => void; }; /** * A live microphone level, 0..1, for a meter. Reads the given stream through an * `AnalyserNode`; returns 0 while there is none. One animation frame loop, * closed with the stream. */ declare function useAudioLevel(stream: MediaStream | null): number; /** * THE KEYBOARD SHORTCUTS (Meet wave 2) — Google Meet's own chords, so nobody * relearns anything: ⌘/Ctrl+D mute, ⌘/Ctrl+E camera, ⌘/Ctrl+Alt+H hand, * ⌘/Ctrl+Alt+C chat, ⌘/Ctrl+Alt+P people, Shift+? the shortcuts sheet. Never * fires while the person is typing in a field. */ declare const MEET_SHORTCUTS: readonly { readonly id: "mic" | "camera" | "hand" | "chat" | "people" | "help"; readonly keys: string; readonly label: string; }[]; declare function useMeetShortcuts(handlers: Partial void>>): void; declare function useMeeting(): MeetingRecord | null; declare function useMeetingId(): MeetingId | null; /** * THE MEETING AFTER THE MEETING (MRI-D2). * * A durable link outlives the room (R3), and until this hook existed it * resolved to a pre-join screen for a room nobody could enter — the summary, * decisions, action items, live notes, transcript and recording were reachable * only from SQL. This loads all of it from durable rows, states what the reader * is not allowed to see instead of rendering emptiness, and keeps the Q&A box * working against the record: `/intelligence/ask` reads the same durable rows * and answers a signed-in member long after the room closed. * * It is deliberately independent of the room store: nothing here needs a * LiveKit connection, a token, or a joined participant. */ interface UseMeetingRecordResult { readonly loading: boolean; readonly record: MeetingRecordBundle | null; /** A failure that stopped the WHOLE record loading. Partial refusals are in * `record.restrictions` — this is null whenever a record exists. */ readonly failure: { readonly message: string; readonly remedy: string; } | null; /** Q&A against the durable record. Streams, exactly as it does in-room. */ readonly asking: boolean; readonly answer: string | null; readonly coverage: MeetAnswerCoverage | null; readonly askError: { readonly message: string; readonly remedy: string; } | null; ask: (question: string) => Promise; reload: () => void; } declare function meetingRecordCache(): MeetingRecordCache; declare function useMeetingRecord(meeting: MeetingRecord | null): UseMeetingRecordResult; /** * EVERY MEETING THIS ORGANIZATION HAS, newest first — including the ended ones * (MRI-D2). A list that shows only live meetings is a list that empties itself * the moment the work is done, and it is what left every wrap-up unreachable. */ interface UseMeetingsResult { readonly loading: boolean; readonly meetings: readonly MeetingRecord[]; readonly hasMore: boolean; readonly failure: { readonly message: string; readonly remedy: string; } | null; reload: () => void; } declare function useMeetings(limit?: number, /** * The page's own organization filter. Absent/null = ALL the person's * organizations, which is the default on every visit. It is never the host's * active organization (active-org-is-never-a-list-filter.md). */ organizationFilter?: OrganizationId | null): UseMeetingsResult; /** * THE HOST'S CHOICE FOR ONE MEETING (MRF-1). * * Arman ruled on 2026-09-12 that guest access to the post-meeting record is a * configuration and never a question: the system's default, the organization's * override, and this — a host deciding for the meeting in front of them, * because they are the only person who knows who was in the room and what was * said in it. * * `setting` is what the host chose (`default` means "use my organization's"); * `effective` is what that resolves to RIGHT NOW, which is the only honest way * to render "use my organization's setting" — a label that does not say what * the organization's setting IS makes the host guess. * * The write is the SERVER's decision and it re-checks host power. This hook * never renders a control for a non-host; the component does that, and the * server refuses one anyway. */ interface UseGuestRecordAccessResult { readonly setting: GuestRecordAccessSetting; /** Null until the server has said what `default` means for this meeting. */ readonly effective: GuestRecordAccessResolution | null; readonly saving: boolean; readonly error: { readonly message: string; readonly remedy: string; } | null; choose: (setting: GuestRecordAccessSetting) => Promise; } declare function useGuestRecordAccess(meeting: MeetingRecord | null): UseGuestRecordAccessResult; /** * `` — the meeting page's one entry (CORE-DESIGN §5.3, S1). * * Everything that is not a look lives here, once, for every skin: the inert * guard, the observation root (S0), watching the room and the meeting's durable * feed, seeding the store with the row the consumer resolved, and the ended * meeting's record (a skin-external surface). It then renders the viewer's * skin — only `meet` until S9 adds the switcher. */ interface MeetingSkinRootProps { roomName: RoomName; meetingId?: string; slug?: string; /** * The meeting the host already resolved, when it has one (MRI-D2). * * 🚨 THIS IS WHAT MAKES AN ENDED MEETING WORK FOR A GUEST. Only * `meet_meeting_by_slug` is granted to `anon`; the `meet_meetings` TABLE is * not, so the durable-feed backfill — a table read — is refused for a * link-follower and `snapshot.meeting` stays null for them forever. A * consumer that resolved the slug through the RPC passes the row here, and * the record renders for exactly the reader who has nothing else. */ meeting?: MeetingRecord; onLeave?: () => void; /** * A HOST-PROVIDED control for the in-meeting header (matrx-frontend puts its * Intelligence icon for the meeting's AI jobs here). Rendered in the header * row of the live room only. The package never inspects it. */ headerControls?: ReactNode; /** * HR-360 wave 2 (MD-16): join as a SILENT OBSERVER — no camera, no microphone, no tile. * The server decides whether this person may (the host, a co-host, or someone named). */ observe?: boolean; } declare function MeetingSkinRoot(props: MeetingSkinRootProps): ReactNode; /** * THE MEETING RECORD — a skin-EXTERNAL surface (CORE-DESIGN §5.3). * * What a meeting is once the room is gone: the record view, the recording * player and the host's guest-access control. Outside the skin boundary — every * skin links to the same record — so it lives in `@ai-matrx/meet/react`. * It draws with the Meet skin's v0 primitives until the record gets its own * look (S9 is the pixel pass). */ /** * THE MEETING, AFTER THE MEETING (MRI-D2). * * 🚨 THE DEFECT THIS REPLACES. A meeting produced a wrap-up summary, decisions, * owner-assigned action items, live-note windows, a speaker-attributed * transcript and a recording — and then `/meet/` rendered ``, * offering to join a room that no longer existed. Everything the campaign built * after the room closed was reachable only from SQL. A durable link that * outlives the meeting (R3) has to resolve to the RECORD. * * The bar it is written to (PLAN §3, Fireflies/Otter recon): what was decided, * who owns what, what was said and by whom, and a question box over all of it. * * Nothing on this screen is computed in the browser. Every line is a durable * row; the answer is streamed from `/intelligence/ask`, which reads those same * rows server-side. A part the reader is not allowed to see says so IN WORDS — * an empty section is indistinguishable from a meeting where nothing happened. */ declare function MeetingRecordView({ meeting, onRejoin, }: { meeting: MeetingRecord; /** Optional: a recurring link can be re-opened. Absent for a one-off. */ onRejoin?: () => void; }): ReactNode; declare function RecordingPlayer(props: { fileId: string; }): ReactNode; /** * THE APP PANEL SLOT, FOR REACT (HR-360 wave 2, Meet register MD-15). * * The HOST APP registers its panels — `` around * the meeting — and the skin opens the one the meeting carries (`appPanelOf`) beside the call. * Nothing app-specific lives in this package: a panel is a key, a title and a component that * reads its record through the viewer's own doors. * * `useSharedFocus` is the panel's one shared "current section": the server keeps it per run * and tells the room on the existing collab packet, so every seat moves together. */ interface MeetAppPanelProps { /** The record the meeting carries. */ readonly recordId: string; /** The meeting's organization — the panel's records are read in it. */ readonly organizationId: string; /** The panel's key, e.g. `hr.review_360`. */ readonly panelKey: string; } interface MeetAppPanelEntry { /** The panel's header title. */ readonly title: string; readonly Component: ComponentType; } type MeetAppPanelRegistry = Readonly>; /** Register the host app's panels for every meeting rendered inside. */ declare function MeetAppPanels({ panels, children, }: { panels: MeetAppPanelRegistry; children: ReactNode; }): ReactNode; declare function useMeetAppPanelRegistry(): MeetAppPanelRegistry; interface ResolvedMeetAppPanel extends MeetAppPanelEntry { readonly panel: MeetingAppPanel; readonly organizationId: string; } /** * The panel this meeting carries AND this app registered, or null. A key the app did not * register resolves to null — the slot is absent, never a dead button. */ declare function useMeetAppPanel(meeting?: MeetingRecord | null): ResolvedMeetAppPanel | null; interface SharedFocus { /** The section everyone is on, or null before anyone moved it. */ readonly section: string | null; /** Who moved it last. */ readonly byName: string | null; /** False for an observer — they watch, the people in the meeting move the panel. */ readonly canMove: boolean; /** Move everyone to `section`. Resolves with the server's sentence or its refusal. */ setSection(section: string): Promise<{ ok: boolean; message: string; }>; } /** The app panel's one shared section focus (server-kept, on the collab packet). */ declare function useSharedFocus(panelKey: string): SharedFocus; /** * THE COLLAB AND CAPTION HOOKS — thin selectors over the core (CORE-DESIGN * §5.3, step S1). The logic lives in `core/collab-state.ts`; these only bind it * to the provider's store so every skin gets the same answers. */ interface UseCollabResult { readonly collab: CollabSnapshot | null; readonly isHost: boolean; readonly localIdentity: string | null; readonly breakoutRoomId: string | null; /** Perform one act; resolves with the server's sentence, or its refusal (never throws). */ act(request: CollabRequest): Promise<{ ok: boolean; message: string; itemId?: string | null; }>; /** Go to a breakout room (`null` = the main room). */ moveTo(roomId: string | null): Promise<{ ok: boolean; message: string; }>; } declare function useCollab(): UseCollabResult; /** The activities this person has, in the order Meet lists them. */ declare function useAvailableActivities(): CollabPanel[]; /** Something worth a dot on the Activities button. */ declare function useActivityAttention(): boolean; /** * The viewer's caption-translation choice and the translator's work queue. Finished * lines without a translation are sent in small batches; each line is translated once * per language for the whole meeting (server cache). */ declare function useCaptionTranslation(lines: readonly { id: string; text: string; final: boolean; }[]): { language: string | null; translations: Readonly>; error: string | null; }; /** Which collab panel the bar should open, asked by something else (a poll launched). */ declare function useCollabPanelRequest(onRequest: (panel: CollabPanel) => void): void; /** * THE SKIN FACADE — the ONLY module a skin may import (CORE-DESIGN §5.1, §5.4; * step S1). Guard: `scripts/check-skin-imports.mjs` (in `check:package` and * `pnpm test`): a file under `src/skins/` may import React, the design system, * files inside its own skin folder, and THIS module — nothing else. * * `useMeetCore()` is the facade over today's store: the runtime, the room * snapshot, devices, the server's role and the observation-contract reading, * as one object that changes only when one of them does. The re-exports below * are the headless hooks, pure helpers and types Meet skin v0 (today's in-call * UI, moved here unchanged) reads. Later steps (S6a+) replace the re-exports * with the `CoreSnapshot` slices and typed actions; a skin then reads * `useMeetCore()` alone. */ interface MeetCore { /** The runtime, or null while auth/organization resolve (render nothing). */ readonly host: MeetHost | null; readonly snapshot: MeetSnapshot | null; readonly devices: DeviceSnapshot | null; /** The server's word on this person's role (both carriers, MRI-A11). */ readonly role: ParticipantRole; readonly isHost: boolean; /** What the observation contract reads for this tab (S0). */ readonly observation: MeetObservation; /** * WHERE THIS TAB IS (CORE-DESIGN §3.1) — the contract's phase value, verbatim. A skin renders * one screen per phase (exhaustive) and NEVER decides a phase itself: every move goes through * `actions`, and the machine refuses any move its table does not allow. */ readonly phase: MeetPhase; /** `data-meet-reason` of a refused / terminal phase. */ readonly reason: string | null; /** A notice that came with the phase (`sent-to-waiting`), or null. */ readonly phaseNotice: string | null; /** The `connection` region (reconnecting is here, never a phase). */ readonly connection: ConnectionRegion; /** Show the reconnect banner: the drop outlasted `reconnect_banner_delay_ms` (S6b). */ readonly connectionBanner: boolean; /** The `share` region (a refused share is a notice, never a phase). */ readonly share: ShareRegion; /** The 1:1 call this tab is placing or answering (§3.6), or null. */ readonly call: { readonly invite: CallInvite; readonly direction: "outgoing" | "incoming"; } | null; /** The typed actions. None can move the phase on failure (§5.1). */ readonly actions: MeetCoreActions; } interface MeetCoreActions { /** Join from pre-join (the person's press). */ join(request: JoinRequest): Promise; /** Rejoin from `left` / `disconnected` / `superseded` / `inactive` (the person's press). */ rejoin(): Promise; leave(): Promise; /** Back to the device check from `left` / `disconnected` (the person's press). */ backToPrejoin(): void; /** Try again on a refusal: the link is looked up again (`refused:*` → `resolving`). */ retry(): void; /** The link resolved and the meeting screen mounted (`resolving` → `prejoin`). */ resolved(): void; dismissShareNotice(): void; /** Close a finished call's screen (`call_*` / `left` after a call → `resolving`). */ dismissCall(): void; } /** The one headless read a skin starts from. Stable until something moves. */ declare function useMeetCore(): MeetCore; /** * THE RINGING SURFACE — skin-EXTERNAL (CORE-DESIGN §5.3): an incoming call * rings on whatever page the person is on, outside any meeting skin. */ /** * Mount ONCE, high in the tree. Every incoming call rings here, on whatever * surface the user is on (R2). */ declare function IncomingCallHost(): ReactNode; declare function IncomingCallCard({ invite }: { invite: CallInvite; }): ReactNode; export { CallInvite, CallMode, CollabPanel, CollabRequest, CollabSnapshot, ConnectionRegion, type CoreRootOptions, DeviceSnapshot, GuestRecordAccessResolution, GuestRecordAccessSetting, IncomingCallCard, IncomingCallHost, JoinRequest, LeaveChoice, LeavePolicy, LobbyEntry, LocalMediaState, MEET_SHORTCUTS, MediaEffects, MeetAnswerCoverage, type MeetAppPanelEntry, type MeetAppPanelProps, type MeetAppPanelRegistry, MeetAppPanels, type MeetCore, MeetHost, MeetObservation, MeetParticipant, MeetPhase, MeetRoot, MeetSnapshot, MeetingAppPanel, MeetingId, MeetingNote, MeetingRecord, MeetingRecordBundle, MeetingRecordCache, MeetingRecordView, MeetingSkinRoot, type MeetingSkinRootProps, ModerationNotice, ModerationRequest, ModerationResult, NoteTakerStatus, ObservedPhase, OrganizationId, ParticipantIdentity, ParticipantRole, RecordingPlayer, type ResolvedMeetAppPanel, RoomName, ShareRegion, type SharedFocus, Stage, StageLayout, type TranscriptLine, TranscriptSource, type UseCallsResult, type UseCollabResult, type UseEndMeetingResult, type UseGuestRecordAccessResult, type UseHostControlsResult, type UseLobbyResult, type UseMediaEffectsResult, type UseMeetAiResult, type UseMeetingRecordResult, type UseMeetingsResult, type UseRecordingResult, type UseRoomResult, UserId, WrapUpAnnouncement, meetingRecordCache, useActivityAttention, useAudioLevel, useAvailableActivities, useCalls, useCanModerate, useCaptionTranslation, useCaptions, useCollab, useCollabPanelRequest, useConsentNotice, useCoreObservation, useCoreRootProps, useElapsed, useEndMeeting, useGuestRecordAccess, useHandQueue, useHostControls, useLeave, useListenOnlyNotice, useLobby, useLocalMedia, useMediaEffects, useMeetAi, useMeetAppPanel, useMeetAppPanelRegistry, useMeetCore, useMeetShortcuts, useMeeting, useMeetingId, useMeetingRecord, useMeetings, useModerationNotice, useReactions, useRecording, useRoom, useSharedFocus, useStage, useTrack };