@fias/arche-sdk 2.29.0 → 2.31.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.
Files changed (38) hide show
  1. package/dist/bridge.d.ts +32 -6
  2. package/dist/bridge.d.ts.map +1 -1
  3. package/dist/bridge.js +73 -2
  4. package/dist/bridge.js.map +1 -1
  5. package/dist/bridge.test.js +71 -0
  6. package/dist/bridge.test.js.map +1 -1
  7. package/dist/entity-ops.d.ts +12 -0
  8. package/dist/entity-ops.d.ts.map +1 -1
  9. package/dist/entity-ops.js +13 -1
  10. package/dist/entity-ops.js.map +1 -1
  11. package/dist/generated/permissions.d.ts +1 -1
  12. package/dist/generated/permissions.d.ts.map +1 -1
  13. package/dist/generated/permissions.js +8 -0
  14. package/dist/generated/permissions.js.map +1 -1
  15. package/dist/generated/surfaces.d.ts +119 -5
  16. package/dist/generated/surfaces.d.ts.map +1 -1
  17. package/dist/generated/surfaces.js +14 -6
  18. package/dist/generated/surfaces.js.map +1 -1
  19. package/dist/hooks.d.ts +161 -18
  20. package/dist/hooks.d.ts.map +1 -1
  21. package/dist/hooks.js +682 -38
  22. package/dist/hooks.js.map +1 -1
  23. package/dist/hooks.test.js +613 -0
  24. package/dist/hooks.test.js.map +1 -1
  25. package/dist/index.d.ts +2 -2
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +8 -3
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +555 -21
  30. package/dist/types.d.ts +489 -13
  31. package/dist/types.d.ts.map +1 -1
  32. package/dist/use-fias-access.render.test.d.ts +12 -0
  33. package/dist/use-fias-access.render.test.d.ts.map +1 -0
  34. package/dist/use-fias-access.render.test.js +407 -0
  35. package/dist/use-fias-access.render.test.js.map +1 -0
  36. package/package.json +3 -2
  37. package/templates/default/AGENTS.md +360 -27
  38. package/templates/default/CLAUDE.md +360 -27
package/dist/types.d.ts CHANGED
@@ -595,6 +595,32 @@ export interface ImageGenerationParams {
595
595
  * `referenceImage` is provided.
596
596
  */
597
597
  referenceStrength?: number;
598
+ /**
599
+ * Generate in a style from the user's Creative Library (ADR-037) — a style
600
+ * made in FiasWorks Studio, say. Needs `vault:creative:read`. The platform
601
+ * adds the style's reference pictures after your own references (up to
602
+ * three, while the model has room) and its words to the prompt; with no
603
+ * room left it carries the style in words, which needs a description
604
+ * (STYLE_NEEDS_DESCRIPTION otherwise). `version` pins one version of the
605
+ * style; leave it out for the current one. `pictures` chooses which of the
606
+ * style's pictures go, in order (1–3 of its `referenceDocumentIds`; an indoor
607
+ * picture for an indoor scene) — leave it out for its first. Get ids from
608
+ * `useCreativeLibrary`.
609
+ *
610
+ * Or `{ shipped: key }`: a style this arche ships for its players — listed
611
+ * in the manifest's `styles` with its pictures in the asset library tagged
612
+ * `style:<key>` (ADR-037 D7). No permission beyond this one. It is read
613
+ * from the arche's PUBLISHED version — publish once with the style before
614
+ * relying on it; the dev harness has none (SHIPPED_STYLE_UNAVAILABLE). The
615
+ * player pays, as for any generation.
616
+ */
617
+ creativeStyle?: {
618
+ styleId: string;
619
+ version?: number;
620
+ pictures?: string[];
621
+ } | {
622
+ shipped: string;
623
+ };
598
624
  }
599
625
  /**
600
626
  * A reference image for `useImageGeneration`: an asset from this arche's
@@ -799,6 +825,105 @@ export interface AudioGenerationApi {
799
825
  result: AudioGenerationResult | null;
800
826
  error: Error | null;
801
827
  }
828
+ /**
829
+ * The host chrome around a plugin's arche, as the host reports it (`init`
830
+ * and every `chrome_update`). See `useFiasChrome`.
831
+ *
832
+ * "Focus mode" is the platform's expand: the platform header, the arche's
833
+ * own header and the suggested-arches sidebar are hidden so the arche fills
834
+ * the viewport, and the host draws a thin bar with the way back — Fias home,
835
+ * Worktop, Fias AI, Collapse — unless the plugin suppresses it and draws its
836
+ * own.
837
+ */
838
+ export interface FiasChromeState {
839
+ /** The arche is expanded (platform header + sidebar hidden). */
840
+ focusMode: boolean;
841
+ /**
842
+ * Whether focus mode exists on this surface at all — only the normal
843
+ * signed-in layout has chrome to hide. False on public, full-screen and
844
+ * embedded views, where `setFocusMode` is ignored.
845
+ */
846
+ focusModeAvailable: boolean;
847
+ /**
848
+ * Whether the layout draws the suggested-arches sidebar for this arche —
849
+ * false where the manifest declined it (`showSidebar: false`) and on
850
+ * surfaces that never had one. Hide your sidebar toggle when false.
851
+ */
852
+ sidebarAvailable: boolean;
853
+ /** The sidebar is collapsed (only meaningful when `sidebarAvailable`). */
854
+ sidebarCollapsed: boolean;
855
+ /**
856
+ * In focus mode, the host draws its thin bar (Fias home · Worktop · Fias
857
+ * AI · Collapse). False when the plugin suppressed it to draw its own.
858
+ */
859
+ hostExpandedBar: boolean;
860
+ /**
861
+ * The host draws its default expand button over the plugin. False once a
862
+ * plugin takes the chrome over (mounting `useFiasChrome` does that) or
863
+ * when the manifest declined it (`showExpandButton: false`). The takeover
864
+ * also removes the host's re-open control for a collapsed sidebar — a
865
+ * plugin that owns its chrome draws its own (`setSidebarCollapsed(false)`).
866
+ */
867
+ hostExpandButton: boolean;
868
+ /**
869
+ * Where the person came from, when a Fias tool opened this arche — the forge
870
+ * page's "Open FiasWorks Studio", say (ADR-037 D8) — or null. `useOpener`
871
+ * reads it without taking the chrome over. A host older than this field
872
+ * sends none (read it as null).
873
+ */
874
+ opener?: FiasOpener | null;
875
+ }
876
+ /** A Fias tool this arche was opened from (ADR-037 D8). */
877
+ export interface FiasOpener {
878
+ /** What it is: a Fias Forge, or an arche in the Arche Builder. */
879
+ kind: 'forge' | 'builder';
880
+ /** The arche's name as the person knows it ("My Arche"). */
881
+ name: string;
882
+ }
883
+ /** What `chrome_set` may carry — every present key a boolean. */
884
+ export interface FiasChromeSetPayload {
885
+ focusMode?: boolean;
886
+ sidebarCollapsed?: boolean;
887
+ hostExpandedBar?: boolean;
888
+ hostExpandButton?: boolean;
889
+ }
890
+ /** The host destinations a plugin may leave for — a closed enum, never a URL. */
891
+ export type FiasChromeNavigateTarget = 'home' | 'worktop' | 'opener';
892
+ /**
893
+ * Host-chrome API available via useFiasChrome() — the state above plus the
894
+ * controls the platform's own focus-mode bar carries, so a plugin can place
895
+ * them where its design wants them.
896
+ */
897
+ export interface FiasChromeApi extends FiasChromeState {
898
+ /**
899
+ * The host delivered chrome state. False before `init` lands and on a host
900
+ * older than this API — the state fields then hold inert defaults and the
901
+ * setters are no-ops, so a plugin can render unconditionally.
902
+ */
903
+ supported: boolean;
904
+ /** Expand (`true`) or collapse (`false`) — the platform's own expand/contract. */
905
+ setFocusMode: (on: boolean) => void;
906
+ /** Collapse or reopen the suggested-arches sidebar (when `sidebarAvailable`). */
907
+ setSidebarCollapsed: (collapsed: boolean) => void;
908
+ /**
909
+ * Keep (`true`, the default) or suppress (`false`) the host's focus-mode
910
+ * bar. Suppress it ONLY if you draw your own way back — once the chrome is
911
+ * hidden that bar is the only one. Focus mode you set persists across
912
+ * reloads only while the bar is kept; with it suppressed a reload restores
913
+ * the chrome, so a broken collapse control of yours is never a trap.
914
+ */
915
+ setHostExpandedBar: (shown: boolean) => void;
916
+ /** Leave the arche for Fias home (`/`). */
917
+ goToFiasHome: () => void;
918
+ /** Leave the arche for the user's Worktop. */
919
+ goToWorktop: () => void;
920
+ /**
921
+ * Ask the host to open the Fias AI panel. No permission needed; no text can
922
+ * be passed (the assistant's input belongs to the user); the host debounces
923
+ * and honours the user's last dismissal — never call it on mount or in a loop.
924
+ */
925
+ openAssistant: () => void;
926
+ }
802
927
  /**
803
928
  * Navigation API available via useFiasNavigation() hook.
804
929
  */
@@ -1782,8 +1907,10 @@ export interface CommunityAssetUrl {
1782
1907
  }
1783
1908
  export interface CommunityAssetPublishInput {
1784
1909
  /**
1785
- * The `fileId` from a `useImageGeneration()` result — the image must be one
1786
- * YOU created or uploaded, in your own Fias files.
1910
+ * The `fileId` of an image the user made IN THIS APP: a `useImageGeneration()`
1911
+ * result, or a picture uploaded through `useVaultDocuments().upload()`. A
1912
+ * file in the user's Documents (even one they granted you) is not
1913
+ * publishable by id — save your own copy with `upload()` first.
1787
1914
  *
1788
1915
  * Required here, while `ImageGenerationResult.fileId` is OPTIONAL (it is
1789
1916
  * absent if the generated image was never written to the user's files). That
@@ -1811,7 +1938,8 @@ export interface CommunityAssetPublishInput {
1811
1938
  * One item's outcome from `publishMany`. Items succeed or fail INDEPENDENTLY —
1812
1939
  * a single rejected page must not sink a whole book — and retrying only the
1813
1940
  * failures is safe: publishing the same bytes twice returns the first result
1814
- * rather than creating a duplicate.
1941
+ * rather than creating a duplicate. An item the user can't pay the safety check
1942
+ * for fails with `INSUFFICIENT_CREDITS`; the ones before it still went through.
1815
1943
  */
1816
1944
  export type CommunityAssetPublishResult = {
1817
1945
  clientRef: string | null;
@@ -1842,8 +1970,14 @@ export type CommunityAssetReportReason = 'sexual' | 'violence' | 'hate' | 'illeg
1842
1970
  export interface CommunityAssetsApi {
1843
1971
  /**
1844
1972
  * Publish one image you created so other users of this arche can see it.
1845
- * Free. It becomes visible only after moderation — expect
1973
+ * It becomes visible only after moderation — expect
1846
1974
  * `status: 'pending_moderation'` back, not `'published'`.
1975
+ *
1976
+ * The user pays for each picture's safety check (0.6 credits, charged when it
1977
+ * runs; publishing the same bytes again costs nothing). A user who can't pay
1978
+ * for it — and for their pictures still waiting to be checked — is refused
1979
+ * with `INSUFFICIENT_CREDITS` before anything is stored; tell them, rather
1980
+ * than retrying.
1847
1981
  */
1848
1982
  publish: (input: CommunityAssetPublishInput) => Promise<CommunityAsset>;
1849
1983
  /** Publish up to 20 at once; each item succeeds or fails on its own. */
@@ -1966,6 +2100,123 @@ export interface FiasConnectionsApi {
1966
2100
  /** Give up this app's access to one connection. */
1967
2101
  release: (connectionId: string) => Promise<void>;
1968
2102
  }
2103
+ export type FiasCreativeItemKind = 'style' | 'character';
2104
+ /** A style or character, as the Creative Library returns it. */
2105
+ export interface FiasCreativeItem {
2106
+ itemId: string;
2107
+ kind: FiasCreativeItemKind;
2108
+ name: string;
2109
+ /** The version shown — the current one unless you asked for another. */
2110
+ version: number;
2111
+ currentVersion: number;
2112
+ /** A style's description, or a character's appearance. */
2113
+ words: string;
2114
+ /** Vault document ids of the reference pictures, best first. */
2115
+ referenceDocumentIds: string[];
2116
+ /** A character's style: a library style id or a built-in style key. Null for a style. */
2117
+ styleRef: string | null;
2118
+ /** YOUR arche's own fields on this item; other arches' are never shown. */
2119
+ extension: Record<string, unknown> | null;
2120
+ /** The arche that created it, when one did. */
2121
+ sourceArcheId: string | null;
2122
+ createdAt: string;
2123
+ updatedAt: string;
2124
+ deletedAt: string | null;
2125
+ /** `get` only: short-lived (5 minute) inline preview URLs of the reference pictures. */
2126
+ previews?: Array<{
2127
+ documentId: string;
2128
+ url: string;
2129
+ expiresAt: string;
2130
+ }>;
2131
+ }
2132
+ export interface FiasCreativeItemFields {
2133
+ name?: string;
2134
+ words?: string;
2135
+ /** Images THIS arche created (e.g. with `useVaultDocuments().upload`), in the same library. */
2136
+ referenceDocumentIds?: string[];
2137
+ styleRef?: string | null;
2138
+ /** Your arche's own fields; `null` removes them on update. At most 16 KB. */
2139
+ extension?: Record<string, unknown> | null;
2140
+ }
2141
+ export interface FiasCreativeLibraryApi {
2142
+ /**
2143
+ * Styles and characters, most recently changed first — the whole library
2144
+ * (it holds at most 500); with `includeDeleted`, the 500 most recently changed.
2145
+ */
2146
+ list: (options?: {
2147
+ kind?: FiasCreativeItemKind;
2148
+ includeDeleted?: boolean;
2149
+ }) => Promise<FiasCreativeItem[]>;
2150
+ /** One item, with preview URLs; pass `version` for an earlier version. */
2151
+ get: (itemId: string, version?: number) => Promise<FiasCreativeItem>;
2152
+ /** Needs `vault:creative:write`. A style has 1–100 pictures; a character exactly one. */
2153
+ create: (fields: FiasCreativeItemFields & {
2154
+ kind: FiasCreativeItemKind;
2155
+ name: string;
2156
+ }) => Promise<FiasCreativeItem>;
2157
+ /**
2158
+ * Writes the next version; fields left out carry forward. Pass
2159
+ * `expectedVersion` to fail with CREATIVE_VERSION_CONFLICT if someone else
2160
+ * changed it first.
2161
+ */
2162
+ update: (itemId: string, fields: FiasCreativeItemFields & {
2163
+ expectedVersion?: number;
2164
+ }) => Promise<FiasCreativeItem>;
2165
+ /** To the trash (versions kept); `restore` brings it back. */
2166
+ remove: (itemId: string) => Promise<FiasCreativeItem>;
2167
+ restore: (itemId: string) => Promise<FiasCreativeItem>;
2168
+ /**
2169
+ * Let the person pick one style or character in a sheet Fias draws, with
2170
+ * its pictures — what `list` would return, nothing more. Resolves with the
2171
+ * item picked, or `{ canceled: true }` when they close the sheet. Rejects
2172
+ * with `PICKER_UNAVAILABLE` where there is no picker (the dev harness, the
2173
+ * builder preview) and `SHEET_BUSY` while another Fias sheet is open.
2174
+ */
2175
+ pick: (options?: {
2176
+ kind?: FiasCreativeItemKind;
2177
+ }) => Promise<FiasCreativePickResult>;
2178
+ }
2179
+ /**
2180
+ * Where the person came from, and what you can do about it (ADR-037 D8) —
2181
+ * `useOpener()`.
2182
+ */
2183
+ export interface FiasOpenerApi {
2184
+ /** The Fias tool that opened this arche, or null — then show neither action. */
2185
+ opener: FiasOpener | null;
2186
+ /** Take the person back to `opener`. Does nothing without one. */
2187
+ returnTo: () => void;
2188
+ /**
2189
+ * Offer one of YOUR files (a Vault file this arche created) to `opener`:
2190
+ * Fias shows the person a sheet naming the file and the destination, and
2191
+ * their Send moves it — into a Fias Forge's `public/`, or an Arche Builder
2192
+ * arche's asset library. `name` is the name it should land as. Requires
2193
+ * `opener:send`. Resolves `{ sent: true, name }` once it arrived (the name
2194
+ * it landed as), or `{ canceled: true }`. Rejects with `NO_OPENER` without
2195
+ * an `opener`, `SHEET_BUSY` while another Fias sheet is open, and
2196
+ * `SEND_UNAVAILABLE` where there is none (the dev harness).
2197
+ */
2198
+ send: (file: {
2199
+ fileId: string;
2200
+ name?: string;
2201
+ }) => Promise<FiasSendToOpenerResult>;
2202
+ }
2203
+ export type FiasSendToOpenerResult = {
2204
+ sent: true;
2205
+ name: string;
2206
+ } | {
2207
+ canceled: true;
2208
+ };
2209
+ /** What `useCreativeLibrary().pick()` resolves with. */
2210
+ export type FiasCreativePickResult = {
2211
+ item: {
2212
+ itemId: string;
2213
+ kind: FiasCreativeItemKind;
2214
+ name: string;
2215
+ version: number;
2216
+ };
2217
+ } | {
2218
+ canceled: true;
2219
+ };
1969
2220
  /** One X post. Images are Vault document ids: this app's own files, or ones shared with it. */
1970
2221
  export interface FiasXPostInput {
1971
2222
  text: string;
@@ -2164,7 +2415,7 @@ export interface CompanyEmailApi {
2164
2415
  /**
2165
2416
  * Message types sent from the plugin iframe to the parent frame.
2166
2417
  */
2167
- export type PluginToHostMessageType = 'ready' | 'resize' | 'toast' | 'get_user' | 'get_theme' | 'storage_read' | 'storage_write' | 'storage_list' | 'storage_delete' | 'entity_invoke' | 'client_entity_invoke' | 'image_generate' | 'entities_list_image' | 'audio_generate' | 'surface_invoke' | 'navigate' | 'open_arche' | 'data_create_collection' | 'data_list_collections' | 'data_delete_collection' | 'data_put' | 'data_get' | 'data_query' | 'data_delete' | 'data_batch' | 'data_search' | 'workspace_create' | 'workspace_list' | 'workspace_get' | 'workspace_archive' | 'workspace_list_members' | 'workspace_add_member' | 'workspace_update_member' | 'workspace_remove_member' | 'store_get_products' | 'store_purchase' | 'store_get_entitlements' | 'store_get_purchase_history' | 'store_restore' | 'store_cancel_subscription' | 'vault_documents_list' | 'vault_documents_read' | 'vault_documents_read_many' | 'vault_documents_download_url' | 'vault_documents_get_urls' | 'vault_documents_search' | 'vault_documents_write' | 'vault_documents_update' | 'vault_documents_delete' | 'vault_documents_attach' | 'vault_documents_detach' | 'vault_documents_upload_init' | 'vault_documents_upload_finalize' | 'vault_documents_upload' | 'vault_documents_pick' | 'arche_assets_list' | 'arche_assets_index' | 'arche_assets_get_url' | 'preview_state' | 'subscription_unsubscribe' | 'ai_actions_declare' | 'ai_state' | 'ai_action_result' | 'ai_open';
2418
+ export type PluginToHostMessageType = 'ready' | 'resize' | 'toast' | 'get_user' | 'get_theme' | 'storage_read' | 'storage_write' | 'storage_list' | 'storage_delete' | 'entity_invoke' | 'client_entity_invoke' | 'image_generate' | 'entities_list_image' | 'audio_generate' | 'surface_invoke' | 'navigate' | 'open_arche' | 'data_create_collection' | 'data_list_collections' | 'data_delete_collection' | 'data_put' | 'data_get' | 'data_query' | 'data_delete' | 'data_batch' | 'data_search' | 'workspace_create' | 'workspace_list' | 'workspace_get' | 'workspace_archive' | 'workspace_list_members' | 'workspace_add_member' | 'workspace_update_member' | 'workspace_remove_member' | 'store_get_products' | 'store_purchase' | 'store_get_entitlements' | 'store_get_purchase_history' | 'store_restore' | 'store_cancel_subscription' | 'vault_documents_list' | 'vault_documents_read' | 'vault_documents_read_many' | 'vault_documents_download_url' | 'vault_documents_get_urls' | 'vault_documents_search' | 'vault_documents_write' | 'vault_documents_update' | 'vault_documents_delete' | 'vault_documents_attach' | 'vault_documents_detach' | 'vault_documents_upload_init' | 'vault_documents_upload_finalize' | 'vault_documents_upload' | 'vault_documents_pick' | 'arche_assets_list' | 'arche_assets_index' | 'arche_assets_get_url' | 'preview_state' | 'subscription_unsubscribe' | 'ai_actions_declare' | 'ai_state' | 'ai_action_result' | 'ai_open' | 'chrome_set' | 'chrome_navigate';
2168
2419
  /**
2169
2420
  * One Fias AI action a plugin declares — what the platform assistant may do
2170
2421
  * in this plugin's UI while it is open. Mirrors the platform's
@@ -2204,18 +2455,33 @@ export interface FiasAIActionsDeclaration {
2204
2455
  /**
2205
2456
  * Why a realtime subscription ended (ADR-012 Phase M4). Closed union so
2206
2457
  * hooks can distinguish terminal endings (`authorization_revoked`,
2207
- * `collection_deleted`) from ones worth resubscribing after conditions
2208
- * change (`limit`, `transport_error`, `lease_expired`).
2458
+ * `collection_deleted` — the observed resource is gone, whatever its kind)
2459
+ * from ones worth resubscribing after conditions change (`limit`,
2460
+ * `transport_error`, `lease_expired`).
2209
2461
  */
2210
2462
  export type SubscriptionEndedReason = 'authorization_revoked' | 'lease_expired' | 'collection_deleted' | 'limit' | 'transport_error' | 'unsubscribed';
2211
2463
  /**
2212
- * State reported by useDataSubscription().
2464
+ * A realtime invalidation delivered to a subscriber (ADR-012 Phase M4).
2465
+ * Notify-then-refetch: it says only that the observed resource changed.
2466
+ * `resource` is the resource's public identifier as you subscribed to it —
2467
+ * a datastore collection's name, a chat channel's id.
2213
2468
  */
2214
- export interface DataSubscriptionState {
2469
+ export interface SubscriptionEvent {
2470
+ resource: string;
2471
+ changed: true;
2472
+ /** @deprecated Alias of `resource`, kept for bundles built before the `resource` rename; removed in the next major. */
2473
+ collection?: string;
2474
+ }
2475
+ /**
2476
+ * State reported by useEntitySubscription() and useDataSubscription().
2477
+ */
2478
+ export interface EntitySubscriptionState {
2215
2479
  status: 'subscribing' | 'active' | 'ended';
2216
2480
  /** Set once status === 'ended'. */
2217
2481
  endedReason?: SubscriptionEndedReason;
2218
2482
  }
2483
+ /** State reported by useDataSubscription() — the same shape as every entity subscription. */
2484
+ export type DataSubscriptionState = EntitySubscriptionState;
2219
2485
  /**
2220
2486
  * Step navigation API available via useStepNavigation() hook.
2221
2487
  */
@@ -2241,7 +2507,7 @@ export interface StepNavigationOptions {
2241
2507
  /**
2242
2508
  * Message types sent from the parent frame to the plugin iframe.
2243
2509
  */
2244
- export type HostToPluginMessageType = 'init' | 'response' | 'theme_update' | 'navigate_update' | 'step_navigate' | 'stream_token' | 'text_models_update' | 'preview_state_capture' | 'preview_state_restore' | 'subscription_event' | 'subscription_ended' | 'ai_action_dispatch' | 'arche_handoff';
2510
+ export type HostToPluginMessageType = 'init' | 'response' | 'theme_update' | 'access_update' | 'navigate_update' | 'chrome_update' | 'step_navigate' | 'stream_token' | 'text_models_update' | 'preview_state_capture' | 'preview_state_restore' | 'subscription_event' | 'subscription_ended' | 'ai_action_dispatch' | 'arche_handoff';
2245
2511
  /**
2246
2512
  * Base message structure for all bridge communication.
2247
2513
  */
@@ -2358,6 +2624,12 @@ export interface BridgeInitMessage {
2358
2624
  theme: FiasTheme;
2359
2625
  /** Plugin-relative path — see `FiasNavigationApi.currentPath`. */
2360
2626
  currentPath: string;
2627
+ /**
2628
+ * The host-chrome state for this arche — see `FiasChromeState`. Absent
2629
+ * from hosts older than `useFiasChrome` (the hook then reports
2630
+ * `supported: false`), and null on a surface with no chrome of its own.
2631
+ */
2632
+ chrome?: FiasChromeState | null;
2361
2633
  /**
2362
2634
  * Self-hosted vendored-library asset URLs (keyed by import specifier) —
2363
2635
  * present only when the plugin declared `sandbox:vendored-libraries` and the
@@ -2432,6 +2704,20 @@ export interface DataStoreCollection {
2432
2704
  * plugin can VERIFY its declared constraints took effect.
2433
2705
  */
2434
2706
  constraints?: DataStoreCollectionConstraints | null;
2707
+ /**
2708
+ * The app-role permissions that protect this collection (workspace scope,
2709
+ * apps that declare `access` in fias-plugin.json); null = none. Set once,
2710
+ * from the manifest only. Returned so a plugin can VERIFY its declaration
2711
+ * took effect — absent from older platforms.
2712
+ */
2713
+ readPermission?: string | null;
2714
+ writePermission?: string | null;
2715
+ /**
2716
+ * The audiences (manifest `access.audiences`) this collection's documents
2717
+ * may be placed in (ADR-034); null = none. Set with the permissions, then
2718
+ * only grows. Absent from older platforms.
2719
+ */
2720
+ audiences?: string[] | null;
2435
2721
  /**
2436
2722
  * Which plugin project created this collection, as the dev harness reported
2437
2723
  * it. Display metadata only — never a scope or an authorization input.
@@ -2601,9 +2887,15 @@ export interface DataStoreBatchOptions {
2601
2887
  * read-back. Absent on platforms without conditional-write support.
2602
2888
  */
2603
2889
  export interface DataStoreBatchResult {
2890
+ /**
2891
+ * Each put's key — the server-generated one for a put without a key, in a
2892
+ * collection with audiences — its version, and the audience it sits in
2893
+ * (where it has one).
2894
+ */
2604
2895
  written?: {
2605
2896
  key: string;
2606
2897
  version?: number;
2898
+ audience?: string;
2607
2899
  }[];
2608
2900
  }
2609
2901
  /**
@@ -2614,6 +2906,14 @@ export interface DataStoreBatchResult {
2614
2906
  */
2615
2907
  export interface DataStorePutResult {
2616
2908
  version?: number;
2909
+ /**
2910
+ * The document's key — the one the server generated for a create in a
2911
+ * collection with audiences (see {@link FiasDataStoreApi.create}). Absent
2912
+ * from hosts that predate audiences.
2913
+ */
2914
+ key?: string;
2915
+ /** The audience the document sits in, in a collection with audiences. */
2916
+ audience?: string;
2617
2917
  }
2618
2918
  /**
2619
2919
  * A document returned from the data store.
@@ -2639,6 +2939,12 @@ export interface DataStoreDocument<T = Record<string, unknown>> {
2639
2939
  * absent otherwise.
2640
2940
  */
2641
2941
  authoredByCollaborator?: boolean;
2942
+ /**
2943
+ * The audience the document is placed in, in a collection with audiences
2944
+ * (ADR-034): who may read it is decided by the platform from the
2945
+ * audience's readers, never by your code. Absent elsewhere.
2946
+ */
2947
+ audience?: string;
2642
2948
  }
2643
2949
  /**
2644
2950
  * Filter condition for querying documents.
@@ -2727,6 +3033,8 @@ export interface DataStoreSearchMatch<T = Record<string, unknown>> {
2727
3033
  version?: number;
2728
3034
  /** Present on shared-scope matches: see {@link DataStoreDocument.authoredByCollaborator}. */
2729
3035
  authoredByCollaborator?: boolean;
3036
+ /** The match's audience, in a collection with audiences — see {@link DataStoreDocument.audience}. */
3037
+ audience?: string;
2730
3038
  }
2731
3039
  /**
2732
3040
  * Data Store API available via useFiasDataStore() hook.
@@ -2761,7 +3069,14 @@ export interface FiasDataStoreApi {
2761
3069
  }) => Promise<DataStoreCollection>;
2762
3070
  /** List all collections for this arche. */
2763
3071
  listCollections: () => Promise<DataStoreCollection[]>;
2764
- /** Delete a collection and all its documents. */
3072
+ /**
3073
+ * Delete a collection and all its documents. Only an arche collaborator
3074
+ * (owner or publisher) may; anyone else gets `FORBIDDEN`. On a published app
3075
+ * it works only while the collection is EMPTY: one that still holds
3076
+ * documents (every user's, workspace's and tenant's) is refused with
3077
+ * `COLLECTION_NOT_EMPTY`. Sandbox tenants (fias-dev, builder preview, test
3078
+ * channel) can delete any.
3079
+ */
2765
3080
  deleteCollection: (name: string) => Promise<void>;
2766
3081
  /**
2767
3082
  * Write (upsert) a document by key. For a `workspace`-scoped collection pass
@@ -2771,7 +3086,30 @@ export interface FiasDataStoreApi {
2771
3086
  * Resolves with the document's post-write `version` (ADR-014) so a follow-up
2772
3087
  * conditional batch can assert it without a read-back.
2773
3088
  */
2774
- put: <T extends Record<string, unknown> = Record<string, unknown>>(collection: string, key: string, data: T, options?: DataStoreScopeOptions) => Promise<DataStorePutResult>;
3089
+ put: <T extends Record<string, unknown> = Record<string, unknown>>(collection: string,
3090
+ /**
3091
+ * The document to write. In a collection with audiences keys are made by
3092
+ * the server: pass `null` to create one (or use {@link create}); a key
3093
+ * names an existing document you may change, and anything else —
3094
+ * missing, or in an audience you cannot read — is refused alike
3095
+ * (`DOCUMENT_NOT_FOUND`). Passing `{ audience }` with a key MOVES the
3096
+ * document to that audience.
3097
+ */
3098
+ key: string | null, data: T, options?: DataStoreScopeOptions) => Promise<DataStorePutResult>;
3099
+ /**
3100
+ * Create a document in a collection with audiences (ADR-034): the server
3101
+ * makes its key and places it in `options.audience`, which you must name.
3102
+ * Placing needs the audience's `disclosedBy` permission — not its read
3103
+ * permission, so a person can file something they will not see afterwards.
3104
+ * Resolves with the new key. Only in collections with audiences — in one
3105
+ * without, a create is `INVALID_DOCUMENT_KEY` (keys there are yours). A
3106
+ * platform that predates audiences rejects the call as invalid parameters
3107
+ * (`INVALID_PARAMS`); `AUDIENCES_UNAVAILABLE` is only a backstop for a host
3108
+ * that accepted it yet returned no key.
3109
+ */
3110
+ create: <T extends Record<string, unknown> = Record<string, unknown>>(collection: string, data: T, options: DataStoreScopeOptions & {
3111
+ audience: string;
3112
+ }) => Promise<Required<Pick<DataStorePutResult, 'key'>> & DataStorePutResult>;
2775
3113
  /** Get a document by key. Returns null if not found. Pass `{ workspaceId }`
2776
3114
  * for a workspace-scoped collection. */
2777
3115
  get: <T extends Record<string, unknown> = Record<string, unknown>>(collection: string, key: string, options?: DataStoreScopeOptions) => Promise<T | null>;
@@ -2821,6 +3159,15 @@ export interface FiasDataStoreApi {
2821
3159
  export interface DataStoreScopeOptions {
2822
3160
  /** Target workspace for a `workspace`-scoped collection. */
2823
3161
  workspaceId?: string;
3162
+ /**
3163
+ * An audience of a collection with audiences (ADR-034, the manifest's
3164
+ * `access.audiences`): where `put`/`create` places the document, or the one
3165
+ * audience `get`/`query`/`search` look in (by default they read every
3166
+ * audience the user reads). Ignored by `delete`. Naming one before the
3167
+ * workspace has turned the app's roles on is refused
3168
+ * (`ACCESS_SETUP_REQUIRED`).
3169
+ */
3170
+ audience?: string;
2824
3171
  }
2825
3172
  /**
2826
3173
  * One write in an atomic batch (see {@link FiasDataStoreApi.batch}). A `put`
@@ -2830,9 +3177,12 @@ export interface DataStoreScopeOptions {
2830
3177
  export type DataStoreBatchOp = {
2831
3178
  op: 'put';
2832
3179
  collection: string;
2833
- key: string;
3180
+ /** Omit to create with a server-generated key (collections with audiences). */
3181
+ key?: string;
2834
3182
  data: Record<string, unknown>;
2835
3183
  workspaceId?: string;
3184
+ /** Where to place (or move) the document — see {@link DataStoreScopeOptions.audience}. */
3185
+ audience?: string;
2836
3186
  } | {
2837
3187
  op: 'delete';
2838
3188
  collection: string;
@@ -2919,6 +3269,132 @@ export interface FiasWorkspacesApi {
2919
3269
  /** Remove a member by username (owner/admin, or yourself; keeps the one-owner invariant). */
2920
3270
  removeMember: (workspaceId: string, username: string) => Promise<void>;
2921
3271
  }
3272
+ /**
3273
+ * The current user's access in one workspace where only workspace TIERS
3274
+ * (owner/admin/member/viewer) apply: an app that declares no roles, or a
3275
+ * workspace outside an organization, where roles never apply.
3276
+ */
3277
+ export interface FiasTierAccess {
3278
+ mode: 'tier';
3279
+ workspaceId: string;
3280
+ /**
3281
+ * The user's tier in this workspace, or `null` when they have none: not a
3282
+ * member, an expired or removed membership, or a workspace this app cannot
3283
+ * see from where it is open.
3284
+ */
3285
+ tier: WorkspaceRole | null;
3286
+ /** ISO-8601 expiry of the user's membership, or `null` when it does not expire. */
3287
+ expiresAt: string | null;
3288
+ }
3289
+ /**
3290
+ * An app that declares roles (manifest `access`), in an org workspace that has
3291
+ * not turned them on: it runs on TIERS until an owner activates roles. Collections that existed before the app declared roles work
3292
+ * as before; one created already protected is refused with
3293
+ * `ACCESS_SETUP_REQUIRED`.
3294
+ */
3295
+ export interface FiasLegacyAccess {
3296
+ mode: 'legacy';
3297
+ workspaceId: string;
3298
+ tier: WorkspaceRole;
3299
+ /** ISO-8601 expiry of the user's membership, or `null` when it does not expire. */
3300
+ expiresAt: string | null;
3301
+ }
3302
+ /** One app role the user holds that counts now. */
3303
+ export interface FiasAccessRole {
3304
+ /** The role id your manifest declares. */
3305
+ id: string;
3306
+ /** ISO-8601 expiry of this assignment, or `null` when it does not expire. */
3307
+ expiresAt: string | null;
3308
+ }
3309
+ /**
3310
+ * An app that declares roles, in an org workspace where they are on: the
3311
+ * user's roles that count at their current tier, and the permissions those
3312
+ * roles grant. A role whose `minTier` the user's tier does not meet is left
3313
+ * out — it grants nothing until they are promoted.
3314
+ */
3315
+ export interface FiasRolesAccess {
3316
+ mode: 'roles';
3317
+ workspaceId: string;
3318
+ tier: WorkspaceRole;
3319
+ /** ISO-8601 expiry of the user's membership, or `null` when it does not expire. */
3320
+ expiresAt: string | null;
3321
+ roles: FiasAccessRole[];
3322
+ /** The permission ids the user holds here, sorted. */
3323
+ permissions: string[];
3324
+ /**
3325
+ * The audiences (manifest `access.audiences`) those permissions read, and
3326
+ * the ones they may place documents in. Across the app — a collection lists
3327
+ * which of them it uses, and reading one also needs the collection's own
3328
+ * read permission. Empty while the workspace is still placing its existing
3329
+ * documents. Absent from hosts that predate audiences.
3330
+ */
3331
+ audiences?: {
3332
+ readable: string[];
3333
+ disclosable: string[];
3334
+ };
3335
+ }
3336
+ /**
3337
+ * The current user's own access in a workspace, from `useFiasAccess()`.
3338
+ *
3339
+ * `mode` says which model answered: `'tier'` for an app without roles (or a
3340
+ * workspace outside an organization, where roles never apply), `'legacy'`
3341
+ * for an app whose roles this workspace has not turned on yet, and
3342
+ * `'roles'` when they are on. Handle a `mode` you do not recognise by hiding
3343
+ * the controls it would gate, never by showing them.
3344
+ *
3345
+ * **A UI hint, never security.** The platform checks every read and write on
3346
+ * arrival; this only lets you hide controls a user could not use anyway.
3347
+ */
3348
+ export type FiasAccess = FiasTierAccess | FiasLegacyAccess | FiasRolesAccess;
3349
+ /** What `useFiasAccess()` returns. */
3350
+ export interface FiasAccessState {
3351
+ /** The user's access, or `null` while loading, on error, or with no workspace given. */
3352
+ access: FiasAccess | null;
3353
+ /**
3354
+ * True until the first answer for this workspace. A later ask (focus,
3355
+ * `access_update`, `refetch()`) keeps the answer it has and does not set it.
3356
+ */
3357
+ isLoading: boolean;
3358
+ /** A failure other than "no access here" (which is `access.tier === null`). */
3359
+ error: Error | null;
3360
+ /**
3361
+ * Whether the user holds `permission` here: true only in `'roles'` mode,
3362
+ * with that permission. Always false in `'tier'` and `'legacy'` mode, where
3363
+ * permissions are not in force — branch on `access.mode` (and the tier)
3364
+ * there.
3365
+ */
3366
+ can: (permission: string) => boolean;
3367
+ /**
3368
+ * Whether the user reads `audience` here — true only in `'roles'` mode. A
3369
+ * UI hint like `can()`: the platform only ever returns documents of the
3370
+ * audiences the user reads. Reading a document also needs its collection's
3371
+ * `readPermission`; this does not check that — `can()` it too.
3372
+ */
3373
+ canReadAudience: (audience: string) => boolean;
3374
+ /** Whether the user may place documents in `audience` here — true only in `'roles'` mode. */
3375
+ canDiscloseTo: (audience: string) => boolean;
3376
+ /**
3377
+ * Ask again. The answer is a snapshot and is NOT pushed when the user's
3378
+ * access changes elsewhere, so call this when it may have: after the app
3379
+ * changes a membership itself, or when the platform refuses an action with
3380
+ * `FORBIDDEN` / `NOT_A_MEMBER`. A refetch of the same workspace keeps the
3381
+ * current answer until the new one arrives.
3382
+ */
3383
+ refetch: () => void;
3384
+ /**
3385
+ * Open Fias's access sheet for the workspace the person is acting in: their
3386
+ * own access to this app's data, why, asking for more, and — for an access
3387
+ * manager — managing roles. Drawn by Fias; the app passes nothing and
3388
+ * changes nothing itself. Resolves once the person closes it (and refetches
3389
+ * when their access changed); rejects with `NOT_IN_WORKSPACE` in a Personal
3390
+ * workspace, where app roles never apply, `SHEET_BUSY` while another Fias
3391
+ * sheet is open, or `ACCESS_UNAVAILABLE` where no Fias host can draw it (the
3392
+ * dev harness). Requires `data:workspace`.
3393
+ */
3394
+ openAccessDialog: () => Promise<{
3395
+ changed: boolean;
3396
+ }>;
3397
+ }
2922
3398
  /**
2923
3399
  * IAP product type (mirrors Apple StoreKit).
2924
3400
  */