@ai-matrx/sharing
v0.1.27
Published
Sharing for every AI Matrx entity: the permission doors, share links, and the share dialog.
Maintainers
Readme
@ai-matrx/sharing
Sharing for every AI Matrx entity: the permission doors, share links, and the share dialog.
Status: shipping and adopted by matrx-frontend. /core is the data half (configureSharing: the permission service, share links, registry, "shown to" reads); /react is THE share sheet (ShareModal, the link panels, the permission hooks; host UI through configureShareSheetUi); /access/react is the access gate screens (moved from @ai-matrx/data). Versions are cut by the daily npm publish batch or an explicit targeted release (highest served + patch). A source push does not start an npm release. package.json's version is not the release state; npm view @ai-matrx/sharing version is.
Sections
@ai-matrx/sharing/core- the data half:configureSharing, permission service, share links, registry@ai-matrx/sharing/react- the share sheet and its hooks; every host-only part has an announcing default@ai-matrx/sharing/access/react—"use client": request access, access denied, governed actions, hidden-by-me
@ai-matrx/sharing/access/react — the access gate screens
"use client" entry. Every screen and hook of the access gate: AccessGate, AccessDenied / AccessDeniedView,
SlugAccessGate, SettingAccessGate, ForbiddenSurfaceView, RequestAccess, RequestAccessPanel, BlindAccessAsk,
UnresolvedEntityRef, ServerReadRecheck, GovernedActionDialog, HiddenByMeButton, HiddenFilter,
ResourceActionRequestButtons, SettingRequestActionButtons, AccessRequestsSurface; hooks useAccessGate,
useAccessStates, useHiddenByMe (+ useHiddenItems, useHideForMe, useRemovalRights), useRequestAccess; and the
"can't remove it" opener (ensureRemovable, offerOwnerChoices, cantRemoveOpener, CantRemoveDialogHostBody).
Built on @ai-matrx/design-system and lucide-react; no next/*, no app imports.
RequestAccessPanel renders its view/edit choices with design-system buttons. The selected choice has
pressed state, and each choice label stays on one line while the row may wrap between choices.
Hosts configure access services as below; the panel owns these choice controls.
configureAccessUi(env) (module-level, merges; <AccessUiProvider env> overrides a subtree; useAccessUi() reads the
merged result). The pure half's Supabase client / ensureOrgId / CMS tokens come from configureAccess in @ai-matrx/data/access — call both once at boot; the screens read the same @ai-matrx/data/access module the app configures.
| Field | Kind | Default when absent |
|---|---|---|
| useLoginHref(), useCurrentUser() {id, displayName, email}, toast {success, error, warning, info?} | REQUIRED | reading one throws an error naming configureAccessUi({ field }) |
| Link, router {push, back, refresh}, searchParam(name), confirm(options), Textarea, renderUserIdentity, renderEntityRef, renderErrorMenu, navItemClasses, manualRequestActionKey | optional, working default | plain <a>, browser history/reload, kit confirm(), design-system Textarea, avatar + name, plain name (not a door), no error menu, app-shell nav CSS variables, request_access.manual |
| entityRegistry.tryGetEntityInfo, trash.restore, recordUnavailableCapture.resolve, settingRequestActions.get, resourceActionRequests.get, cms.createAccessRequest, settingDoorHref, reportFeedback, presentOrganizationRefusal, overlays | optional app feature | owners/records render as plain names; Restore, CMS asks, setting asks and platform-team asks FAIL VISIBLY naming the missing field; unknown request actions render without the primary action button; the rest are no-ops |
Hook-valued fields are called inside components: set them once at boot. ForbiddenSurface (async, reads headers() and the
session verdict) cannot live in a client entry, so the package ships ForbiddenSurfaceView; the app keeps a ~10-line server
wrapper in forbidden.tsx that reads the verdict and request path and renders it.
