@nivaro/react 0.2.6 → 0.2.8

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.d.ts CHANGED
@@ -17,6 +17,7 @@ import { ReactPortal } from 'react';
17
17
  import { ReportDateRange } from '@nivaro/sdk';
18
18
  import { ReportEntityFilter } from '@nivaro/sdk';
19
19
  import { ReportQueryWidgetConfig } from '@nivaro/sdk';
20
+ import { ReportWidget } from '@nivaro/sdk';
20
21
  import { UseMutationResult } from '@tanstack/react-query';
21
22
  import { UseQueryResult } from '@tanstack/react-query';
22
23
  import { UserScopesInfo } from '@nivaro/sdk';
@@ -500,7 +501,7 @@ export declare function BulkActionButtons({ targets, enabledKeys, tone, disabled
500
501
  onDone?: (result: BulkRunResult & {
501
502
  action: AvailableBulkAction;
502
503
  }) => void;
503
- }): JSX.Element | null;
504
+ }): JSX.Element;
504
505
 
505
506
  declare interface BulkRunResult {
506
507
  succeeded: number;
@@ -515,6 +516,8 @@ declare interface BulkRunResult {
515
516
  declare interface BulkTarget {
516
517
  collection: string;
517
518
  id: string | number;
519
+ /** Optional display label — names the row in per-row result lists. */
520
+ label?: string | null;
518
521
  }
519
522
 
520
523
  /**
@@ -531,6 +534,15 @@ export declare function CacheStamp({ envelope, onRefresh, refreshing, className
531
534
  className?: string;
532
535
  }): JSX.Element | null;
533
536
 
537
+ export declare function CallerChangesSection({ caller, hours }: {
538
+ /** `k<api key id>` or `u<user id>`. */
539
+ caller: {
540
+ key: string;
541
+ label: string;
542
+ };
543
+ hours: number;
544
+ }): JSX.Element;
545
+
534
546
  export declare function canOpenCatalogItem(collection: string | null | undefined): boolean;
535
547
 
536
548
  export declare function canOpenChatRoom(): boolean;
@@ -539,6 +551,8 @@ export declare function canOpenDm(): boolean;
539
551
 
540
552
  export declare function canPreviewFile(type: string | null | undefined): boolean;
541
553
 
554
+ export declare function canViewAs(): boolean;
555
+
542
556
  /**
543
557
  * Grab the replay link for an error being reported right now. Resolves null
544
558
  * when no recorder is active (both settings off, recording failed, or the
@@ -888,7 +902,7 @@ export declare function ChatRoomList({ rooms, onOpen, onNewGroup, archivedView,
888
902
  loading?: boolean;
889
903
  }): JSX.Element;
890
904
 
891
- export declare function ChatRoomView({ room, label, onBack, onOpenSettings, renderMessageBody, initialUnread, anchor: anchorProp }: {
905
+ export declare function ChatRoomView({ room, label: labelProp, onBack, onOpenSettings, renderMessageBody, initialUnread, anchor: anchorProp }: {
892
906
  room: string;
893
907
  label: string;
894
908
  onBack: () => void;
@@ -1049,7 +1063,7 @@ export declare interface CollectionBrowserColumn {
1049
1063
  filterable?: boolean;
1050
1064
  }
1051
1065
 
1052
- export declare function CollectionBrowserView({ collection, quickFilters, initialColumns, initialSort, pageSize, initialSearch, initialFilters, initialConditions, onOpenItem, showCreate, className }: CollectionBrowserViewProps): React_2.JSX.Element;
1066
+ export declare function CollectionBrowserView({ collection, quickFilters, initialColumns, initialSort, pageSize, initialSearch, initialFilters, initialConditions, onOpenItem, initialAiPrompt, extraViews, showCreate, className }: CollectionBrowserViewProps): React_2.JSX.Element;
1053
1067
 
1054
1068
  export declare interface CollectionBrowserViewProps {
1055
1069
  collection: string;
@@ -1077,6 +1091,17 @@ export declare interface CollectionBrowserViewProps {
1077
1091
  }>;
1078
1092
  /** Override row-open behavior; defaults to NavigationContext itemUrl. */
1079
1093
  onOpenItem?: (id: string | number) => void;
1094
+ /** Ask the table this question once on open (e.g. a command-palette
1095
+ * hand-off, `?ai=` on the host route). */
1096
+ initialAiPrompt?: string;
1097
+ /** Host-supplied display modes beside the table (e.g. a spreadsheet or
1098
+ * calendar the host app owns). Each renders instead of the table. */
1099
+ extraViews?: Array<{
1100
+ key: string;
1101
+ label: string;
1102
+ icon?: React_2.ReactNode;
1103
+ render: () => React_2.ReactNode;
1104
+ }>;
1080
1105
  showCreate?: boolean;
1081
1106
  className?: string;
1082
1107
  }
@@ -2080,6 +2105,16 @@ export declare function fiscalQuarterOf(d: Date, startMonth?: number): number;
2080
2105
 
2081
2106
  export declare function fiscalYearOf(d: Date, startMonth?: number): number;
2082
2107
 
2108
+ /** Bring a field or a child row of the open record into view (ItemEditForm
2109
+ * listens for 'nvr:record-focus'). */
2110
+ export declare function focusRecordTarget(target: {
2111
+ collection: string;
2112
+ item: string;
2113
+ field?: string;
2114
+ childCollection?: string;
2115
+ rowId?: string;
2116
+ }): void;
2117
+
2083
2118
  /** The window event a host's socket layer dispatches on `client:force-refresh`. */
2084
2119
  export declare const FORCE_RELOAD_EVENT = "nvr:force-refresh";
2085
2120
 
@@ -2465,7 +2500,7 @@ export declare interface ImportDefinition {
2465
2500
  description: string | null;
2466
2501
  staging_table: string | null;
2467
2502
  procedure: string | null;
2468
- loader: 'bulk' | 'insert' | null;
2503
+ loader: 'bulk' | 'bulk_only' | 'insert' | null;
2469
2504
  file_types: string | null;
2470
2505
  is_active: boolean;
2471
2506
  sort: number;
@@ -2483,6 +2518,13 @@ export declare interface ImportDefinition {
2483
2518
  /** JSON array of flow ids run in order after a successful run (migration 294). */
2484
2519
  post_run_flows?: string | null;
2485
2520
  receipt?: string | null;
2521
+ /** #802 — runs sharing a group never overlap; null = the staging table. */
2522
+ lock_group?: string | null;
2523
+ /** #719 — JSON string[] of collections the procedure writes (rollups recomputed). */
2524
+ recalc_rollups?: string | null;
2525
+ /** #846 — days after the last completed run the staging table is emptied; opt-in, null/0 = keep. */
2526
+ staging_purge_days?: number | null;
2527
+ staging_purged_at?: string | null;
2486
2528
  }
2487
2529
 
2488
2530
  declare interface ImportDryRun {
@@ -2585,6 +2627,8 @@ export declare interface ImportJob {
2585
2627
  started_at: string | null;
2586
2628
  completed_at: string | null;
2587
2629
  rolled_back_at?: string | null;
2630
+ /** #748 — rows were written through the items service. */
2631
+ through_items?: boolean;
2588
2632
  }
2589
2633
 
2590
2634
  export declare type ImportJobStatus = 'pending' | 'processing' | 'complete' | 'failed';
@@ -2652,7 +2696,7 @@ export declare interface ImportRun {
2652
2696
  procedure: string | null;
2653
2697
  /** null / 'proc' = stored procedure, 'service', or a registered processor key. */
2654
2698
  processor?: string | null;
2655
- loader: 'bulk' | 'insert' | null;
2699
+ loader: 'bulk' | 'bulk_only' | 'insert' | null;
2656
2700
  definition_active: boolean | null;
2657
2701
  file_name: string | null;
2658
2702
  file_size: string | number | null;
@@ -2767,6 +2811,20 @@ export declare function InboundCallersView({ hours: initialHours }: {
2767
2811
  hours?: number;
2768
2812
  }): JSX.Element;
2769
2813
 
2814
+ /**
2815
+ * A trigger (any inline element) that opens the request behind an inbound
2816
+ * write. The event-path sheet opens AFTER the popover closes, so a sheet
2817
+ * never mounts inside a popover.
2818
+ */
2819
+ export declare function InboundRequestPopover({ activityId, callerName, collection, itemId, children, align }: {
2820
+ activityId: number;
2821
+ callerName: string;
2822
+ collection: string;
2823
+ itemId: string;
2824
+ children: ReactNode;
2825
+ align?: 'start' | 'center' | 'end';
2826
+ }): JSX.Element;
2827
+
2770
2828
  /**
2771
2829
  * Inbound: health first — the host's own live queue (an ingest backlog, say), then whether
2772
2830
  * scheduled imports are arriving on time — and investigation last, since who
@@ -2994,6 +3052,16 @@ export declare interface IntegrationPartnerCard {
2994
3052
  missing: number;
2995
3053
  overdue: number;
2996
3054
  };
3055
+ /** #612 — health-probe uptime over 24h; null when the API is not probed. */
3056
+ uptime24?: {
3057
+ pct: number | null;
3058
+ probes: number;
3059
+ buckets: Array<{
3060
+ at: string;
3061
+ ok: number;
3062
+ failed: number;
3063
+ }>;
3064
+ } | null;
2997
3065
  }
2998
3066
 
2999
3067
  export declare interface IntegrationPartnerDetail {
@@ -3046,6 +3114,29 @@ export declare type IntegrationPathDetail = {
3046
3114
  from?: string | null;
3047
3115
  to?: string | null;
3048
3116
  comment?: string | null;
3117
+ } | {
3118
+ type: 'notify';
3119
+ recipient: string;
3120
+ /** Admins only; null for everyone else. */
3121
+ subject: string | null;
3122
+ category?: string | null;
3123
+ lane?: string | null;
3124
+ channels: Array<{
3125
+ channel: string;
3126
+ status: string;
3127
+ reason?: string | null;
3128
+ }>;
3129
+ } | {
3130
+ type: 'mail';
3131
+ status: string;
3132
+ /** Admins only; null for everyone else. */
3133
+ subject: string | null;
3134
+ template?: string | null;
3135
+ /** Addresses — admins only; null for everyone else. */
3136
+ to?: string | null;
3137
+ recipients: number;
3138
+ mail_log_id: number;
3139
+ error?: string | null;
3049
3140
  };
3050
3141
 
3051
3142
  /** One step of an event's path, with the steps it set off under it. */
@@ -3077,11 +3168,11 @@ export declare interface IntegrationPathNode {
3077
3168
  members?: IntegrationPathNode[];
3078
3169
  }
3079
3170
 
3080
- /** The filter-pill set the collection browser offers (its own conditions[]
3081
- * round trip to `/items/:collection` — the queue has no equivalent server
3082
- * path, so it gets the column but not the filter). Values are the same
3083
- * bucket names `applyIntegrationsFilter` (api/src/services/items.ts) reads,
3084
- * so a picked value needs no translation before it rides a condition. */
3171
+ /** The filter set the collection browser (a `$integrations` condition to
3172
+ * `/items/:collection`) and the queue (`filters.integrations`, #630 —
3173
+ * services/queue-integrations.ts) both offer. Values are the bucket names
3174
+ * `applyIntegrationsFilter` (api/src/services/items.ts) reads, so a picked
3175
+ * value needs no translation on either surface. */
3085
3176
  export declare const INTEGRATIONS_FILTER_OPTIONS: {
3086
3177
  value: string;
3087
3178
  label: string;
@@ -3179,26 +3270,6 @@ export declare interface IntegrationSignalView {
3179
3270
  shown: number;
3180
3271
  }
3181
3272
 
3182
- export declare function IntegrationStatusBanner({ collection, itemId }: IntegrationStatusBannerProps): JSX.Element | null;
3183
-
3184
- /**
3185
- * One line per partner on the record: were they told, when, and if not, why
3186
- * not. Sits above `ErpFailureBanner`, which keeps the payload/response view
3187
- * and the retry mutation — this answers a different question ("was the
3188
- * partner told, and when") and does not replace it.
3189
- *
3190
- * Renders nothing when the record has no obligations, so a collection with
3191
- * no integrations pays one cached request and shows no chrome.
3192
- *
3193
- * `roleForTone` is imported from `IntegrationObligationsView` (the board)
3194
- * rather than duplicated here, so the board and this banner can never
3195
- * disagree about what "overdue" looks like.
3196
- */
3197
- export declare interface IntegrationStatusBannerProps {
3198
- collection: string;
3199
- itemId: string | number;
3200
- }
3201
-
3202
3273
  /** Whether this browser pinned the chat panel open — hosts read it for their
3203
3274
  * initial open state, so a pinned panel is still there after a reload. */
3204
3275
  export declare function isChatPanelPinned(): boolean;
@@ -4258,6 +4329,16 @@ export declare function OpsTasksView({ onNotice }: {
4258
4329
  onNotice?: (message: string) => void;
4259
4330
  }): JSX.Element;
4260
4331
 
4332
+ /** #615 — the Integrations dialog's "What goes out next" block. */
4333
+ export declare function OutboundPreviewSection({ collection, itemId, onShowRequest, onJump }: {
4334
+ collection: string;
4335
+ itemId: string;
4336
+ /** Open the request log row a comparison was made against. */
4337
+ onShowRequest?: (submissionId: number) => void;
4338
+ /** A readiness issue jumps to a line — the hosting dialog closes first. */
4339
+ onJump?: () => void;
4340
+ }): JSX.Element | null;
4341
+
4261
4342
  /**
4262
4343
  * Lets a host put transient overlay state — a drill-down sheet and how deep it
4263
4344
  * is — into browser history, so Back closes the sheet instead of abandoning the
@@ -4407,6 +4488,11 @@ declare interface PartnerContract {
4407
4488
  detail: string | null;
4408
4489
  }
4409
4490
 
4491
+ export declare function PartnerDependenciesPanel({ callerKey, label }: {
4492
+ callerKey: string;
4493
+ label: string;
4494
+ }): JSX.Element;
4495
+
4410
4496
  export declare function PartnerDetail({ apiId, onClose, initialTab }: PartnerDetailProps): JSX.Element;
4411
4497
 
4412
4498
  export declare interface PartnerDetailProps {
@@ -4423,7 +4509,7 @@ export declare interface PartnersViewProps {
4423
4509
  onOpenChange?: (id: number | null) => void;
4424
4510
  }
4425
4511
 
4426
- declare type PathStepKind = 'request' | 'cron' | 'import' | 'feed' | 'write' | 'transition' | 'flow' | 'push' | 'attempt' | 'partner_call' | 'group';
4512
+ declare type PathStepKind = 'request' | 'cron' | 'import' | 'feed' | 'write' | 'transition' | 'flow' | 'push' | 'attempt' | 'partner_call' | 'notify' | 'mail' | 'group';
4427
4513
 
4428
4514
  declare interface PendingTask {
4429
4515
  title: string;
@@ -4437,6 +4523,38 @@ declare interface PendingTask {
4437
4523
  priority?: string;
4438
4524
  }
4439
4525
 
4526
+ /**
4527
+ * The same, minus machine identities (bots, integrations, service accounts,
4528
+ * placeholders — `account_kind` set). A person picking a contact or an
4529
+ * assignee should only ever be offered people; admins keep the machine
4530
+ * accounts because they occasionally configure one on purpose.
4531
+ */
4532
+ export declare const PEOPLE_USER_OPTION_FILTER: {
4533
+ _and: ({
4534
+ is_redacted: {
4535
+ _eq: boolean;
4536
+ };
4537
+ _or?: undefined;
4538
+ } | {
4539
+ _or: ({
4540
+ status: {
4541
+ _neq: string;
4542
+ _null?: undefined;
4543
+ };
4544
+ } | {
4545
+ status: {
4546
+ _null: boolean;
4547
+ _neq?: undefined;
4548
+ };
4549
+ })[];
4550
+ is_redacted?: undefined;
4551
+ } | {
4552
+ account_kind: {
4553
+ _null: boolean;
4554
+ };
4555
+ })[];
4556
+ };
4557
+
4440
4558
  /**
4441
4559
  * The identity band at the top of someone's page: who they are, whether
4442
4560
  * they are reachable right now, and the three ways to reach them. Admin-only
@@ -4530,6 +4648,12 @@ export declare interface PersonProfileData {
4530
4648
  values: string[];
4531
4649
  }>;
4532
4650
  open_tasks: number;
4651
+ /** When they are usually around (UTC hours, 10th–90th percentile of their actions). */
4652
+ typical_hours_utc?: {
4653
+ start: number;
4654
+ end: number;
4655
+ samples: number;
4656
+ } | null;
4533
4657
  admin: {
4534
4658
  account_kind: string | null;
4535
4659
  city: string | null;
@@ -4667,6 +4791,33 @@ export declare function PipelineTransitionButtons({ collection, item, onBeforeTr
4667
4791
  wrap?: boolean;
4668
4792
  }): JSX.Element | null;
4669
4793
 
4794
+ export declare interface PlanGridHost {
4795
+ renderRowHistory?: (args: PlanGridRowHistoryArgs) => ReactNode | null;
4796
+ }
4797
+
4798
+ export declare const PlanGridHostContext: Context<PlanGridHost | null>;
4799
+
4800
+ /**
4801
+ * What a host may put in place of a plan grid's generic parts (#842). Core
4802
+ * stays domain-free: a host that has a richer history for a collection (a
4803
+ * forecast history with restores and accuracy) renders it here; returning
4804
+ * null keeps the generic row-history sheet.
4805
+ */
4806
+ export declare interface PlanGridRowHistoryArgs {
4807
+ /** The plan rows' collection ("forecasts"). */
4808
+ collection: string;
4809
+ /** The record the grid belongs to. */
4810
+ parentId: string;
4811
+ /** The saved row, when there is one. */
4812
+ rowId: string | null;
4813
+ /** The row's key value ("2026"). */
4814
+ key: string;
4815
+ /** The row's category id when the key is split by category, else null. */
4816
+ category: string | null;
4817
+ categoryLabel: (id: string | number) => string;
4818
+ onClose: () => void;
4819
+ }
4820
+
4670
4821
  /** Play the configured notification sound. No-op for 'off'/unknown/unavailable audio. */
4671
4822
  export declare function playNotificationSound(kind: NotificationSound | string | null | undefined): void;
4672
4823
 
@@ -4760,6 +4911,24 @@ declare type ProposalPollAnswer = {
4760
4911
  json: any;
4761
4912
  };
4762
4913
 
4914
+ /**
4915
+ * "Ready" / "2 lines missing Sales order" beside a button that sends
4916
+ * something to a partner. Give it a transition id (the pipeline pre-flight)
4917
+ * or an item action id (the extension's own pre-flight).
4918
+ */
4919
+ export declare function PushReadinessChip({ collection, itemId, transitionId, itemActionId, label, compact, onJump }: {
4920
+ collection: string;
4921
+ itemId: string;
4922
+ transitionId?: string;
4923
+ itemActionId?: string;
4924
+ /** What the button does — "Submit to Warehouse". */
4925
+ label: string;
4926
+ /** Header use: a dot + a short word; the popover says the rest. */
4927
+ compact?: boolean;
4928
+ /** Called before a jump — a hosting dialog closes so the line shows. */
4929
+ onJump?: () => void;
4930
+ }): JSX.Element | null;
4931
+
4763
4932
  export declare function QualityRulesView({ className }: {
4764
4933
  className?: string;
4765
4934
  }): JSX.Element;
@@ -5325,6 +5494,48 @@ export declare function RecordDrilldownSheet({ collection, itemId, layoutId, roo
5325
5494
  onClose: () => void;
5326
5495
  }): JSX.Element;
5327
5496
 
5497
+ export declare function RecordGraphExplorer({ collection, itemId, className }: {
5498
+ collection: string;
5499
+ itemId: string;
5500
+ className?: string;
5501
+ }): JSX.Element;
5502
+
5503
+ export declare interface RecordGraphGroup {
5504
+ key: string;
5505
+ direction: 'out' | 'in' | 'm2m';
5506
+ field: string;
5507
+ label: string;
5508
+ collection: string;
5509
+ collection_label: string;
5510
+ total: number;
5511
+ items: RecordGraphNode[];
5512
+ }
5513
+
5514
+ /**
5515
+ * Relationship explorer (#998). A record's neighbourhood drawn as a tree that
5516
+ * grows one hop at a time: the record, the relations it takes part in
5517
+ * (grouped — "Purchase orders · 3"), and the records behind each group. Any
5518
+ * record node expands the same way, so a workflow → its PO → the PO's
5519
+ * invoices is three clicks. Clicking a record opens it in the drill sheet
5520
+ * (or navigates when the host has none).
5521
+ *
5522
+ * Every hop is read as the viewer by GET /record-graph/:collection/:id, so
5523
+ * the picture never shows a record the viewer could not open themselves.
5524
+ */
5525
+ export declare interface RecordGraphNode {
5526
+ collection: string;
5527
+ id: string;
5528
+ label: string;
5529
+ }
5530
+
5531
+ /** Right sheet hosting the explorer — hosts mount it beside the record form. */
5532
+ export declare function RecordGraphSheet({ collection, itemId, open, onOpenChange }: {
5533
+ collection: string;
5534
+ itemId: string;
5535
+ open: boolean;
5536
+ onOpenChange: (v: boolean) => void;
5537
+ }): JSX.Element;
5538
+
5328
5539
  export declare function RecordGridEditor({ config }: {
5329
5540
  config: RecordGridEditorConfig;
5330
5541
  }): JSX.Element;
@@ -5488,6 +5699,9 @@ export declare function registerLayoutSlot(plugin: LayoutSlotPlugin): void;
5488
5699
 
5489
5700
  export declare function registerRoomOpener(fn: RoomOpener): () => void;
5490
5701
 
5702
+ /** Register the host's opener. Returns an unregister function. */
5703
+ export declare function registerViewAsOpener(fn: ViewAsOpener): () => void;
5704
+
5491
5705
  export declare function RelatedRecordsPanel({ collection, itemId, title, defaultExpanded }: {
5492
5706
  collection: string;
5493
5707
  itemId: string;
@@ -5603,6 +5817,20 @@ export declare interface ReportViewProps {
5603
5817
  emptyState?: React.ReactNode;
5604
5818
  }
5605
5819
 
5820
+ /**
5821
+ * One saved report widget on its own, outside its report's grid — how a host
5822
+ * places a report widget on a dashboard canvas (#1044). The widget is drawn at
5823
+ * column 0 of an absent grid, so its report-grid placement does nothing and
5824
+ * the card fills whatever cell holds it. Drill-through goes to the host's
5825
+ * DrilldownContext when there is one.
5826
+ */
5827
+ export declare function ReportWidgetCard({ reportId, widget, dateRange, entityFilters }: {
5828
+ reportId: string;
5829
+ widget: ReportWidget;
5830
+ dateRange?: ReportDateRange | null;
5831
+ entityFilters?: ReportEntityFilter[];
5832
+ }): JSX.Element;
5833
+
5606
5834
  export declare function resolveCollectionIcon(iconName: string | null | undefined): React.ElementType | null;
5607
5835
 
5608
5836
  export declare function resolveNotificationTarget(collection: string | null | undefined, item: string | null | undefined, routes: NotificationRouteMap): NotificationTarget;
@@ -6871,6 +7099,8 @@ export declare function usePeerReadAt(room: string | null): string | null;
6871
7099
 
6872
7100
  export declare function usePersonProfile(userId: string | null | undefined): UseQueryResult<NoInfer<PersonProfileData | null>, Error>;
6873
7101
 
7102
+ export declare function usePlanGridHost(): PlanGridHost | null;
7103
+
6874
7104
  /**
6875
7105
  * The quick picker BEFORE a record exists — the "+ New" menus open it, and on
6876
7106
  * Create the host navigates to the new-record page with the picks in
@@ -6964,6 +7194,33 @@ export declare function useRoomMembership(): {
6964
7194
 
6965
7195
  export declare function useRoomPins(room: string | null): NoInfer<PinnedMessage[]>;
6966
7196
 
7197
+ /** The user-picker option filter for this viewer (#732). */
7198
+ export declare function userOptionFilter(isAdmin: boolean): {
7199
+ _and: ({
7200
+ is_redacted: {
7201
+ _eq: boolean;
7202
+ };
7203
+ _or?: undefined;
7204
+ } | {
7205
+ _or: ({
7206
+ status: {
7207
+ _neq: string;
7208
+ _null?: undefined;
7209
+ };
7210
+ } | {
7211
+ status: {
7212
+ _null: boolean;
7213
+ _neq?: undefined;
7214
+ };
7215
+ })[];
7216
+ is_redacted?: undefined;
7217
+ } | {
7218
+ account_kind: {
7219
+ _null: boolean;
7220
+ };
7221
+ })[];
7222
+ };
7223
+
6967
7224
  /** Stacked avatar cluster (+N) with a hover/pinnable portal roster whose rows
6968
7225
  * are UserChips — the single user-display primitive for owners/user lists.
6969
7226
  * Reused by the item-header Owners chip and the collection browser. */
@@ -7070,6 +7327,23 @@ declare interface ValidationResult {
7070
7327
  unknownTokens: string[];
7071
7328
  }
7072
7329
 
7330
+ export declare function viewAs(person: {
7331
+ id: string;
7332
+ name: string;
7333
+ }): void | Promise<void>;
7334
+
7335
+ /**
7336
+ * "View as" registry (#640). A profile page offers "View as <person>" only
7337
+ * while the host app has said how it opens itself as someone else — the
7338
+ * admin opens a new tab on a per-tab masquerade token; a host without the
7339
+ * idea never registers and the button never shows. Same shape as the chat
7340
+ * DM opener registry.
7341
+ */
7342
+ declare type ViewAsOpener = (person: {
7343
+ id: string;
7344
+ name: string;
7345
+ }) => void | Promise<void>;
7346
+
7073
7347
  export declare function WidgetSlot({ widgetId, inputBindings, itemDraft, itemCollection, ready, label, defaultExpanded, frameless, apiBase: apiBaseProp, compact, strip, onClientAction, onWidgetType, onContentChange }: WidgetSlotProps): JSX.Element | null;
7074
7348
 
7075
7349
  declare interface WidgetSlotProps {