@fias/arche-sdk 2.27.0 → 2.29.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.
package/dist/types.d.ts CHANGED
@@ -887,6 +887,16 @@ export interface FiasNavigationApi {
887
887
  export type ArcheHandoffPayloadInput = {
888
888
  kind: 'open_document';
889
889
  documentId: string;
890
+ }
891
+ /**
892
+ * Open a chat channel in the Chat arche (`openArche('arche_chat', …)`).
893
+ * `channelId` is `cch_` + 32 lowercase hex. A pointer, never access: Chat
894
+ * re-reads the channel under the user's own membership, and a non-member
895
+ * lands on the Chat home with a notice — make the user a member first.
896
+ */
897
+ | {
898
+ kind: 'open_channel';
899
+ channelId: string;
890
900
  } | {
891
901
  kind: 'sign_document';
892
902
  /** Idempotency key for this signing request. One uuid per user intent. */
@@ -1045,7 +1055,9 @@ export interface VaultUserDocumentSaveContentResult extends VaultDocumentSaveCon
1045
1055
  export interface VaultDocumentSearchOptions {
1046
1056
  /** Number of results to return. 1..50, default 10. */
1047
1057
  topK?: number;
1048
- /** Minimum cosine similarity (0..1). Default 0.5. */
1058
+ /** Minimum cosine similarity (0..1). Default: the floor of the platform's
1059
+ * current embedding model, which the platform keeps calibrated as the model
1060
+ * changes — pass a value only when you have measured one for your corpus. */
1049
1061
  minSimilarity?: number;
1050
1062
  /** When false, results omit the chunk content. Default true. */
1051
1063
  includeContent?: boolean;
@@ -1183,12 +1195,26 @@ export interface VaultDocumentUploadInitResult {
1183
1195
  requiredHeaders: Record<string, string>;
1184
1196
  /** ISO 8601 timestamp when the upload URL expires. */
1185
1197
  uploadUrlExpiresAt: string;
1198
+ /**
1199
+ * Where the file was kept: `'workspace'` when the user is working in a team
1200
+ * workspace that approved your arche to keep its files there (every member
1201
+ * using your arche can open it), `'personal'` otherwise (only this person
1202
+ * can). Absent on servers older than this field.
1203
+ */
1204
+ space?: 'workspace' | 'personal';
1186
1205
  }
1187
1206
  export interface VaultDocumentUploadResult {
1188
1207
  documentId: string;
1189
1208
  /** Status after finalize — `'uploaded'`, then `'available'` once the
1190
1209
  * extraction worker indexes the document for search. */
1191
1210
  status: string;
1211
+ /**
1212
+ * Where the file was kept: `'workspace'` when the user is working in a team
1213
+ * workspace that approved your arche to keep its files there (every member
1214
+ * using your arche can open it), `'personal'` otherwise (only this person
1215
+ * can). Absent on servers older than this field.
1216
+ */
1217
+ space?: 'workspace' | 'personal';
1192
1218
  /**
1193
1219
  * Only on a save into the user's Documents (`destination: 'documents'`,
1194
1220
  * `saveCopy`): the name the user kept — it may differ from the one you
@@ -1229,6 +1255,15 @@ export interface VaultDocumentReferenceResult {
1229
1255
  * - `vault:documents:read` — list, read, getDownloadUrl
1230
1256
  * - `vault:documents:write` — write, update, delete
1231
1257
  *
1258
+ * Where the files live: in the person's own Vault — or, while they work in a
1259
+ * team workspace whose owner or admin approved your arche, in that
1260
+ * workspace's Vault, counted against the workspace's storage. There the
1261
+ * files are the team's: every member using your arche lists and opens them,
1262
+ * members and above change them, viewers only open them
1263
+ * (`WORKSPACE_VIEWER_READ_ONLY`). A document id saved before the approval
1264
+ * still opens for the person who saved it. `write`/`upload` report which
1265
+ * one they used (`space`).
1266
+ *
1232
1267
  * Note: images returned from useImageGeneration() are auto-saved into
1233
1268
  * the arche's folder and the result includes a `documentId`. Pass that
1234
1269
  * documentId here to refresh the presigned URL after the original ~1h
@@ -1320,6 +1355,7 @@ export interface VaultDocumentsApi {
1320
1355
  * the bridge request body). For binaries or larger documents use `upload`. */
1321
1356
  write: (params: VaultDocumentWriteParams) => Promise<{
1322
1357
  documentId: string;
1358
+ space?: 'workspace' | 'personal';
1323
1359
  }>;
1324
1360
  /** Rename or retag a document. */
1325
1361
  update: (documentId: string, params: VaultDocumentUpdateParams) => Promise<void>;
@@ -1383,9 +1419,13 @@ export interface VaultDocumentsApi {
1383
1419
  checksumSha256: string;
1384
1420
  }) => Promise<VaultDocumentUploadResult>;
1385
1421
  }
1422
+ /** Media kind of a library asset — what `list` / `index` filter by. */
1423
+ export type ArcheAssetKind = 'image' | 'audio';
1386
1424
  /**
1387
- * One entry from the arche's published asset manifest. Surfaced to
1388
- * plugins via `useArcheAssets().list()`.
1425
+ * One IMAGE from the arche's published asset manifest — what
1426
+ * `useArcheAssets().list()` returns when you name no `kinds`. A listing that
1427
+ * names `kinds` returns {@link ArcheLibraryAsset}, which may also hold
1428
+ * {@link ArcheSoundAsset} entries.
1389
1429
  *
1390
1430
  * `signedUrl` is a short-lived (~5 min default) URL that loads through
1391
1431
  * api.fias.ai's signed proxy. Plugins should use `getUrl(assetId)` to
@@ -1414,6 +1454,23 @@ export interface ArcheAsset {
1414
1454
  */
1415
1455
  workspaceId?: string | null;
1416
1456
  }
1457
+ /**
1458
+ * A short sound effect from the asset library (≤ 1 MB, ≤ 30 s). Returned only
1459
+ * by a listing whose `kinds` include `'audio'`. Play it through Web Audio:
1460
+ * read its bytes with `useArcheAssetBytes()` and decode them once.
1461
+ */
1462
+ export interface ArcheSoundAsset extends Omit<ArcheAsset, 'contentType' | 'width' | 'height'> {
1463
+ /** MP3 or WAV — both decode with `decodeAudioData` in every browser. */
1464
+ contentType: 'audio/mpeg' | 'audio/wav';
1465
+ /** Sounds have no pixel grid. */
1466
+ width: null;
1467
+ height: null;
1468
+ }
1469
+ /**
1470
+ * Any library asset: an image or a sound. Narrow on `contentType` (or on
1471
+ * `width !== null`) before using an image's dimensions.
1472
+ */
1473
+ export type ArcheLibraryAsset = ArcheAsset | ArcheSoundAsset;
1417
1474
  export interface ArcheAssetsListOptions {
1418
1475
  cursor?: string;
1419
1476
  /** 1..1000. Default 50. */
@@ -1424,9 +1481,16 @@ export interface ArcheAssetsListOptions {
1424
1481
  * `['category:background']` — instead of pulling the whole manifest.
1425
1482
  */
1426
1483
  tags?: string[];
1484
+ /**
1485
+ * Which media kinds to return. Default `['image']`, so a plugin written
1486
+ * before the library held sounds never receives one. Pass `['audio']` for
1487
+ * sound effects, or `['image', 'audio']` for both.
1488
+ */
1489
+ kinds?: ArcheAssetKind[];
1427
1490
  }
1428
- export interface ArcheAssetsListResult {
1429
- entries: ArcheAsset[];
1491
+ /** A page of the listing. `T` is {@link ArcheLibraryAsset} when you listed with `kinds`. */
1492
+ export interface ArcheAssetsListResult<T extends ArcheLibraryAsset = ArcheAsset> {
1493
+ entries: T[];
1430
1494
  nextCursor: string | null;
1431
1495
  }
1432
1496
  export interface ArcheAssetsIndexOptions {
@@ -1434,6 +1498,8 @@ export interface ArcheAssetsIndexOptions {
1434
1498
  tags?: string[];
1435
1499
  /** Tag prefix that defines a folder. Defaults to `subject:`. */
1436
1500
  groupBy?: string;
1501
+ /** Which media kinds to index. Default `['image']` (see ArcheAssetsListOptions.kinds). */
1502
+ kinds?: ArcheAssetKind[];
1437
1503
  }
1438
1504
  /** A folder in the faceted library index: one signed cover + member count. */
1439
1505
  export interface ArcheAssetGroup {
@@ -1446,6 +1512,11 @@ export interface ArcheAssetGroup {
1446
1512
  signedUrl: string;
1447
1513
  /** Unix-seconds expiry of `signedUrl`. */
1448
1514
  expiresAt: number;
1515
+ /**
1516
+ * The cover's content type. An image whenever the folder has one; a
1517
+ * sound only for an audio-only folder (indexed with `kinds: ['audio']`).
1518
+ */
1519
+ contentType: ArcheLibraryAsset['contentType'];
1449
1520
  /** Representative member tags — category/subject/subcat/theme/tier. */
1450
1521
  tags: string[];
1451
1522
  };
@@ -1454,24 +1525,95 @@ export interface ArcheAssetsIndexResult {
1454
1525
  groups: ArcheAssetGroup[];
1455
1526
  }
1456
1527
  /**
1457
- * Asset library API. Permission: `assets:read`.
1528
+ * The part of a listed asset that `getBytes` / `getMany` reuse: its id and
1529
+ * signed URL. Any entry from `list()`, `getUrl()` or an index cover fits.
1530
+ */
1531
+ export type ArcheAssetRef = Pick<ArcheLibraryAsset, 'assetId' | 'signedUrl' | 'expiresAt'>;
1532
+ /** The bytes of one library asset, from {@link ArcheAssetBytesApi}. */
1533
+ export interface ArcheAssetBytes {
1534
+ contentType: ArcheLibraryAsset['contentType'];
1535
+ /** The asset's bytes — e.g. for `AudioContext.decodeAudioData` or a canvas. */
1536
+ bytes: ArrayBuffer;
1537
+ sizeBytes: number;
1538
+ }
1539
+ /**
1540
+ * Why `useArcheAssetBytes().getBytes` failed. `PERMISSION_DENIED` names the
1541
+ * missing permission: it needs `entities:client_invoke` as well as `assets:read`.
1542
+ */
1543
+ export type ArcheAssetErrorCode = 'PERMISSION_DENIED' | 'RATE_LIMIT' | 'ASSETS_UNAVAILABLE_IN_PREVIEW' | 'ASSET_URL_FORBIDDEN' | 'ASSET_URL_EXPIRED' | 'ASSET_TOO_LARGE' | 'ASSET_UNAVAILABLE' | 'INVALID_INPUT';
1544
+ /**
1545
+ * Asset library API. Permission: `assets:read`. To read an asset's bytes
1546
+ * (Web Audio, canvas) use {@link ArcheAssetBytesApi} via `useArcheAssetBytes()`.
1458
1547
  *
1459
- * The library is a contributor-curated set of images pinned to this
1548
+ * The library is a contributor-curated set of images and short sound
1549
+ * effects pinned to this
1460
1550
  * arche's published version — once the contributor publishes, the set
1461
1551
  * is immutable for that version's runtime. New uploads on the
1462
1552
  * contributor's side affect future published versions only.
1463
1553
  */
1464
1554
  export interface ArcheAssetsApi {
1465
- /** Page through the published asset manifest. */
1466
- list: (options?: ArcheAssetsListOptions) => Promise<ArcheAssetsListResult>;
1555
+ /**
1556
+ * Page through the published asset manifest. Images only unless you pass
1557
+ * `kinds`; with `kinds` the entries are typed {@link ArcheLibraryAsset}, so
1558
+ * narrow on `contentType` before using an image's dimensions.
1559
+ */
1560
+ list: {
1561
+ (options: ArcheAssetsListOptions & {
1562
+ kinds: ArcheAssetKind[];
1563
+ }): Promise<ArcheAssetsListResult<ArcheLibraryAsset>>;
1564
+ (options?: ArcheAssetsListOptions & {
1565
+ kinds?: undefined;
1566
+ }): Promise<ArcheAssetsListResult<ArcheAsset>>;
1567
+ (options?: ArcheAssetsListOptions): Promise<ArcheAssetsListResult<ArcheLibraryAsset>>;
1568
+ };
1467
1569
  /**
1468
1570
  * Faceted folder index: one signed cover + count per group (default
1469
1571
  * `subject:`). Renders a large library's folder grid in a single call; load
1470
1572
  * a folder's contents lazily with `list({ tags: ['subject:<id>'] })`.
1471
1573
  */
1472
1574
  index: (options?: ArcheAssetsIndexOptions) => Promise<ArcheAssetsIndexResult>;
1473
- /** Refresh the signed URL for a single asset. */
1474
- getUrl: (assetId: string) => Promise<ArcheAsset>;
1575
+ /**
1576
+ * Refresh the signed URL for a single asset. Typed as an image, which is
1577
+ * all an images-only listing hands you; for an id that may be a sound
1578
+ * (you listed with `kinds`), call `getUrl<ArcheLibraryAsset>(id)`.
1579
+ */
1580
+ getUrl: <T extends ArcheLibraryAsset = ArcheAsset>(assetId: string) => Promise<T>;
1581
+ }
1582
+ /**
1583
+ * Asset-library byte reads (`useArcheAssetBytes()`). Permissions:
1584
+ * `entities:client_invoke` AND `assets:read`.
1585
+ */
1586
+ export interface ArcheAssetBytesApi {
1587
+ /**
1588
+ * Read one asset's bytes — for Web Audio (`decodeAudioData`), canvas, or
1589
+ * anything else a URL cannot do (the plugin sandbox cannot fetch). Read
1590
+ * each sound once per session and keep the decoded buffer. Rejects with
1591
+ * an `ArcheAssetError`. Unavailable in the builder preview.
1592
+ *
1593
+ * Pass an entry straight from `list()` / `getUrl()` to reuse its signed
1594
+ * URL — one round trip instead of two. An `assetId`, or an entry whose URL
1595
+ * is about to expire, is first given a fresh URL. Calls made together (in
1596
+ * the same tick, e.g. `Promise.all(entries.map(getBytes))`) are sent as one
1597
+ * batch; to load many sounds, prefer {@link ArcheAssetBytesApi.getMany}.
1598
+ */
1599
+ getBytes: (asset: string | ArcheAssetRef) => Promise<ArcheAssetBytes>;
1600
+ /**
1601
+ * Read many assets in as few calls as possible — the way to load a game's
1602
+ * sound effects at startup. Pass entries straight from `list()` (their URLs
1603
+ * last about five minutes): up to 100 go in each call, so any number of
1604
+ * sounds takes one or two calls instead of one per sound — the bridge
1605
+ * blocks more than 50 calls in 5 seconds.
1606
+ *
1607
+ * Resolves to a map from `assetId` to that asset's bytes, or to the
1608
+ * `ArcheAssetError` that kept it from loading — one failed sound does not
1609
+ * fail the rest. Rejects with an `ArcheAssetError` only when the read as a
1610
+ * whole is refused (a missing permission, the builder preview, the rate
1611
+ * limit). An entry whose URL has lapsed is given a fresh one, up to 10 per
1612
+ * call; past that it comes back `ASSET_URL_EXPIRED` — list again.
1613
+ */
1614
+ getMany: (assets: ArcheAssetRef[]) => Promise<Record<string, ArcheAssetBytes | (Error & {
1615
+ code: ArcheAssetErrorCode;
1616
+ })>>;
1475
1617
  }
1476
1618
  /**
1477
1619
  * Why a content read failed. The first seven come from the host's content
@@ -1518,6 +1660,80 @@ export interface FiasContentApi {
1518
1660
  */
1519
1661
  getUrl(path: string): Promise<FiasContentUrl>;
1520
1662
  }
1663
+ /**
1664
+ * Why a local-store call failed. The first four come from the host's store;
1665
+ * `LOCAL_STORE_WRONG_KIND` from the typed getters (`getBytes` on a text
1666
+ * entry); `PERMISSION_DENIED` (the manifest lacks `storage:local`) and
1667
+ * `RATE_LIMIT` from the bridge.
1668
+ */
1669
+ export type FiasLocalStoreErrorCode = 'LOCAL_STORE_UNAVAILABLE' | 'LOCAL_STORE_KEY_INVALID' | 'LOCAL_STORE_VALUE_TOO_LARGE' | 'LOCAL_STORE_QUOTA_EXCEEDED' | 'LOCAL_STORE_WRONG_KIND' | 'INVALID_INPUT' | 'PERMISSION_DENIED' | 'RATE_LIMIT';
1670
+ /** What `put` accepts: text, bytes, or any JSON-serializable value. */
1671
+ export type FiasLocalStoreValue = string | ArrayBuffer | Uint8Array | FiasLocalStoreJson;
1672
+ export type FiasLocalStoreJson = null | boolean | number | string | FiasLocalStoreJson[] | {
1673
+ [key: string]: FiasLocalStoreJson;
1674
+ };
1675
+ /** One entry's metadata, as `list` returns it. */
1676
+ export interface FiasLocalStoreEntryMeta {
1677
+ key: string;
1678
+ sizeBytes: number;
1679
+ /** ISO-8601, the last `put`. */
1680
+ updatedAt: string;
1681
+ }
1682
+ /** One entry with its value — a string, an `ArrayBuffer` for bytes, or JSON, as it was put. */
1683
+ export interface FiasLocalStoreEntry extends FiasLocalStoreEntryMeta {
1684
+ value: string | ArrayBuffer | FiasLocalStoreJson;
1685
+ }
1686
+ /** How much of this plugin's budget (for this user, in this workspace) is in use. */
1687
+ export interface FiasLocalStoreEstimate {
1688
+ usedBytes: number;
1689
+ budgetBytes: number;
1690
+ }
1691
+ export interface FiasLocalStoreApi {
1692
+ /** The entry, or null. The value comes back as the kind it was put. */
1693
+ get(key: string): Promise<FiasLocalStoreEntry | null>;
1694
+ /**
1695
+ * Up to 100 entries in one call, in the order asked, null for a missing
1696
+ * key — restore a journal without a call per key. Throws
1697
+ * `LOCAL_STORE_VALUE_TOO_LARGE` when the entries hold more than 64 MB
1698
+ * together (read fewer at a time) and `INVALID_INPUT` for an empty or
1699
+ * over-long key list.
1700
+ */
1701
+ getMany(keys: string[]): Promise<Array<FiasLocalStoreEntry | null>>;
1702
+ /** A text entry, or null. Throws `LOCAL_STORE_WRONG_KIND` if the entry holds bytes or JSON. */
1703
+ getText(key: string): Promise<string | null>;
1704
+ /** A bytes entry, or null. Throws `LOCAL_STORE_WRONG_KIND` if the entry holds text or JSON. */
1705
+ getBytes(key: string): Promise<ArrayBuffer | null>;
1706
+ /**
1707
+ * A JSON entry, or null. A text entry is parsed as JSON (so `put(key,
1708
+ * JSON.stringify(x))` and `put(key, x)` read back the same); throws
1709
+ * `LOCAL_STORE_WRONG_KIND` for bytes. A stored JSON `null` reads as null,
1710
+ * indistinguishable from an absent key — use `get` if that matters.
1711
+ */
1712
+ getJson<T = unknown>(key: string): Promise<T | null>;
1713
+ /**
1714
+ * Store or overwrite. A string, bytes (`ArrayBuffer` / `Uint8Array`), or
1715
+ * plain JSON (no `Date`, `Map`, `Blob` or other typed arrays — those are
1716
+ * refused rather than stored as something else). One value ≤ 64 MB; the
1717
+ * plugin's whole store for this user ≤ 256 MB (or a quarter of the browser's
1718
+ * quota if smaller) and ≤ 10,000 entries; each entry is also charged its key
1719
+ * and a small fixed overhead. Over a limit the call throws instead of
1720
+ * evicting anything. Put a large snapshot as bytes: JSON is validated and
1721
+ * serialized on the host page on every write.
1722
+ */
1723
+ put(key: string, value: FiasLocalStoreValue): Promise<{
1724
+ sizeBytes: number;
1725
+ }>;
1726
+ /** Remove one entry. Idempotent. */
1727
+ delete(key: string): Promise<void>;
1728
+ /** Entries' metadata, optionally under a key prefix, sorted by key. */
1729
+ list(prefix?: string): Promise<FiasLocalStoreEntryMeta[]>;
1730
+ /** Remove every entry of this plugin's store for the signed-in user in the current workspace. */
1731
+ clear(): Promise<{
1732
+ deleted: number;
1733
+ }>;
1734
+ /** Bytes in use and the budget, so you can decide what to keep before a `put` is refused. */
1735
+ estimate(): Promise<FiasLocalStoreEstimate>;
1736
+ }
1521
1737
  /** Where an asset sits in the moderation lifecycle, from the author's view. */
1522
1738
  export type CommunityAssetStatus =
1523
1739
  /** Awaiting a verdict. Nobody else can see it yet. */
@@ -1719,6 +1935,223 @@ export interface CompanyEmailSendResult {
1719
1935
  /** Recipients counted as sent (`accepted` + `unknown`). */
1720
1936
  sent: number;
1721
1937
  }
1938
+ /** An outside account the acting workspace lets this app use (ADR-029 §2). */
1939
+ export interface FiasConnection {
1940
+ connectionId: string;
1941
+ /** Provider id, e.g. `'x'`, `'linkedin'`. */
1942
+ provider: string;
1943
+ providerDisplayName: string;
1944
+ accountDisplayName: string | null;
1945
+ /** The account's handle, without `@`. */
1946
+ accountHandle: string | null;
1947
+ accountAvatarUrl: string | null;
1948
+ /** `needs_reconnect`: a person has to connect it again before it can be used. */
1949
+ status: 'active' | 'needs_reconnect';
1950
+ }
1951
+ export type FiasConnectResult = {
1952
+ connectionId: string;
1953
+ provider: string;
1954
+ } | {
1955
+ canceled: true;
1956
+ };
1957
+ export interface FiasConnectionsApi {
1958
+ /** The accounts the workspace the app is open in lets it use. */
1959
+ list: () => Promise<FiasConnection[]>;
1960
+ /**
1961
+ * Ask the person to connect an account at `provider`, or let this app use one
1962
+ * the workspace already connected. The HOST draws the screen and makes every
1963
+ * grant; resolves `{ canceled: true }` when they decline.
1964
+ */
1965
+ connect: (provider: string) => Promise<FiasConnectResult>;
1966
+ /** Give up this app's access to one connection. */
1967
+ release: (connectionId: string) => Promise<void>;
1968
+ }
1969
+ /** One X post. Images are Vault document ids: this app's own files, or ones shared with it. */
1970
+ export interface FiasXPostInput {
1971
+ text: string;
1972
+ /** Images (PNG, JPEG, WebP or GIF, 5 MB each) — at most 4 across the whole publish. */
1973
+ mediaDocumentIds?: string[];
1974
+ }
1975
+ export interface FiasXPublishParams {
1976
+ connectionId: string;
1977
+ /** One post, or a thread of up to 10. */
1978
+ posts: FiasXPostInput[];
1979
+ /** Reply to this post id. */
1980
+ replyToPostId?: string;
1981
+ /** A poll on a single post with no images. */
1982
+ poll?: {
1983
+ options: string[];
1984
+ durationMinutes: number;
1985
+ };
1986
+ }
1987
+ export interface FiasXPublishResult {
1988
+ posts: Array<{
1989
+ postId: string;
1990
+ url: string;
1991
+ }>;
1992
+ /** False when X stopped part-way through a thread: `posts` is what went out. */
1993
+ complete: boolean;
1994
+ /** Where a thread stopped (1-based) and X's reason; present only when `complete` is false. */
1995
+ stopped?: {
1996
+ atPost: number;
1997
+ reason: string;
1998
+ };
1999
+ }
2000
+ export interface FiasXUser {
2001
+ id: string;
2002
+ name: string;
2003
+ username: string;
2004
+ profileImageUrl?: string;
2005
+ description?: string;
2006
+ verified: boolean;
2007
+ verifiedType: 'blue' | 'government' | 'business' | 'none';
2008
+ followersCount: number;
2009
+ }
2010
+ export interface FiasXPost {
2011
+ postId: string;
2012
+ text: string;
2013
+ createdAt: string | null;
2014
+ mediaUrl: string | null;
2015
+ likes: number | null;
2016
+ replies: number | null;
2017
+ reposts: number | null;
2018
+ views: number | null;
2019
+ }
2020
+ export interface FiasXPostMetrics {
2021
+ postId: string;
2022
+ likes: number;
2023
+ replies: number;
2024
+ reposts: number;
2025
+ views: number;
2026
+ }
2027
+ export interface FiasXAccountStats {
2028
+ followers: number;
2029
+ following: number;
2030
+ posts: number;
2031
+ listed: number;
2032
+ }
2033
+ /**
2034
+ * X, as an account the workspace let this app use. Every call names the
2035
+ * connection (from `useFiasConnections`) and is charged to the user per X
2036
+ * request. `publishPost` shows the person a confirm sheet first — the text,
2037
+ * every image and the cost — and resolves only once they approve; a decline
2038
+ * rejects with `USER_DECLINED`, and a host already showing another sheet with
2039
+ * `SHEET_BUSY`. The approval covers the images' exact bytes: an image file
2040
+ * changed after asking rejects with `MEDIA_CHANGED` and nothing is posted.
2041
+ */
2042
+ export interface FiasXApi {
2043
+ publishPost: (params: FiasXPublishParams) => Promise<FiasXPublishResult>;
2044
+ searchUsers: (connectionId: string, query: string, options?: {
2045
+ maxResults?: number;
2046
+ }) => Promise<FiasXUser[]>;
2047
+ /**
2048
+ * Recent posts by `userId`, or by the connected account when omitted.
2049
+ * `sinceId`: only posts newer than that one — re-reading an account pays
2050
+ * only for its new posts, since each post returned is billed.
2051
+ */
2052
+ getUserPosts: (connectionId: string, options?: {
2053
+ userId?: string;
2054
+ maxResults?: number;
2055
+ sinceId?: string;
2056
+ }) => Promise<FiasXPost[]>;
2057
+ getPostMetrics: (connectionId: string, postIds: string[]) => Promise<FiasXPostMetrics[]>;
2058
+ getAccountStats: (connectionId: string) => Promise<FiasXAccountStats>;
2059
+ }
2060
+ export interface FiasLinkedInPublishParams {
2061
+ connectionId: string;
2062
+ /** Up to 3,000 characters. */
2063
+ text: string;
2064
+ /** Up to 9 images (PNG, JPEG or GIF, 8 MB each): this app's files or ones shared with it. */
2065
+ mediaDocumentIds?: string[];
2066
+ /** A link LinkedIn previews (when there are no images). */
2067
+ link?: string;
2068
+ /** Organizations to mention; each `name` must appear in `text`. */
2069
+ mentions?: Array<{
2070
+ name: string;
2071
+ urn: string;
2072
+ }>;
2073
+ visibility?: 'PUBLIC' | 'CONNECTIONS' | 'LOGGED_IN';
2074
+ }
2075
+ export interface FiasLinkedInOrganization {
2076
+ id: string;
2077
+ name: string;
2078
+ /** `urn:li:organization:<id>` — what a mention names. */
2079
+ urn: string;
2080
+ }
2081
+ /**
2082
+ * LinkedIn, as a member account the workspace let this app use. Every call
2083
+ * names the connection and is charged to the user. `publishPost` shows the
2084
+ * person a confirm sheet first; a decline rejects with `USER_DECLINED`.
2085
+ */
2086
+ export interface FiasLinkedInApi {
2087
+ publishPost: (params: FiasLinkedInPublishParams) => Promise<{
2088
+ postUrn: string;
2089
+ url: string | null;
2090
+ }>;
2091
+ searchOrganizations: (connectionId: string, vanityName: string) => Promise<FiasLinkedInOrganization[]>;
2092
+ }
2093
+ /** One call to schedule for later (ADR-029 §5). */
2094
+ export interface FiasScheduleParams {
2095
+ /** The entity, e.g. `X_ENTITY_ID`. */
2096
+ entityId: string;
2097
+ /** A verb that can be scheduled, e.g. `'publish_post'`. */
2098
+ verb: string;
2099
+ /** Exactly what the verb takes now (without `op`) — e.g. `{ connectionId, posts }`. */
2100
+ payload: Record<string, unknown>;
2101
+ /** When to send it: 5 minutes to 60 days from now. */
2102
+ fireAt: Date | string;
2103
+ }
2104
+ export interface FiasSchedule {
2105
+ scheduleId: string;
2106
+ entityId: string;
2107
+ verb: string;
2108
+ /** What it does, in the platform's words ("Post to X"). */
2109
+ summary: string;
2110
+ fireAt: string | null;
2111
+ /**
2112
+ * `refused`: something changed before it was due (the account was
2113
+ * disconnected, the app lost access, the approved time passed while it was
2114
+ * paused, …) and nothing was sent — see `refusal`. `partial`: a thread the
2115
+ * provider stopped part-way; some of it went out. `paused`: the person paused
2116
+ * it in Fias.
2117
+ */
2118
+ status: 'scheduled' | 'paused' | 'sent' | 'partial' | 'refused' | 'failed' | 'cancelled';
2119
+ refusal?: {
2120
+ code: string;
2121
+ message: string;
2122
+ };
2123
+ /**
2124
+ * Once `sent` or `partial`: what the call returned — the same output an
2125
+ * immediate call gives (for X `publish_post`, `{ posts: [{ postId, url }], complete }`),
2126
+ * so the app can record where it went. Absent before then, or if too large to relay.
2127
+ */
2128
+ output?: Record<string, unknown>;
2129
+ }
2130
+ export interface FiasScheduleListOptions {
2131
+ /** How many to return, 1–100. Default 20, or the number of `scheduleIds`. */
2132
+ limit?: number;
2133
+ /** Only these schedules (1–100 ids from `schedule()`); ids that are not this app's are left out. */
2134
+ scheduleIds?: string[];
2135
+ }
2136
+ /**
2137
+ * Schedule ONE call for later. For an action outside Fias the person approves
2138
+ * exactly what will be sent, and when, in a confirm sheet first; a decline
2139
+ * rejects with `USER_DECLINED`. There is no edit: cancel, and schedule again.
2140
+ */
2141
+ export interface FiasSchedulesApi {
2142
+ schedule: (params: FiasScheduleParams) => Promise<{
2143
+ scheduleId: string;
2144
+ fireAt: string;
2145
+ }>;
2146
+ /**
2147
+ * This app's schedules in the workspace it is open in, newest first: the
2148
+ * newest 20 unless `limit` says otherwise (at most 100). Pass `scheduleIds`
2149
+ * to follow just the schedules you are waiting on.
2150
+ */
2151
+ list: (options?: FiasScheduleListOptions) => Promise<FiasSchedule[]>;
2152
+ /** Cancel one before it is sent. */
2153
+ cancel: (scheduleId: string) => Promise<void>;
2154
+ }
1722
2155
  export interface CompanyEmailApi {
1723
2156
  /**
1724
2157
  * Send one email AS the Company this app is being used in, from its verified
@@ -1899,6 +2332,23 @@ export interface FiasTextModel {
1899
2332
  outputCreditsPerMillionTokens: number;
1900
2333
  } | null;
1901
2334
  }
2335
+ /**
2336
+ * The Fias workspace the plugin was opened in — the user's own (`personal`) or
2337
+ * an organization's (`org`) — and the user's role there. Fixed for as long as
2338
+ * the plugin is open: when the user switches workspace, the host offers to
2339
+ * reopen the plugin there, and the reopened plugin receives the new value.
2340
+ *
2341
+ * It carries no id and no name, and grants nothing; the platform applies the
2342
+ * workspace to every call on its own. An org workspace that has approved the
2343
+ * app gives it a shared space (`useFiasWorkspaces().openForWorkspace()`), named
2344
+ * after the workspace — that space's id is the plugin's key for per-workspace
2345
+ * data.
2346
+ */
2347
+ export interface FiasHolder {
2348
+ type: 'personal' | 'org';
2349
+ /** The user's role in it. Always `owner` for a personal workspace. */
2350
+ role: 'owner' | 'admin' | 'member' | 'viewer';
2351
+ }
1902
2352
  export interface BridgeInitMessage {
1903
2353
  type: 'init';
1904
2354
  messageId: string;
@@ -1921,6 +2371,12 @@ export interface BridgeInitMessage {
1921
2371
  * backwards compat with older hosts.
1922
2372
  */
1923
2373
  textModels?: FiasTextModel[] | null;
2374
+ /**
2375
+ * The workspace the plugin was opened in — present only when the plugin
2376
+ * declared `user:profile:read` or `data:workspace`. `null`/absent when the
2377
+ * host could not resolve it, and from older hosts.
2378
+ */
2379
+ holder?: FiasHolder | null;
1924
2380
  /**
1925
2381
  * Bridge protocol version the HOST speaks. Optional for backwards
1926
2382
  * compat with hosts pre-dating the versioning work — absence is
@@ -2034,6 +2490,14 @@ export interface DataStoreFieldBound {
2034
2490
  * - `nonNegative` — named numeric fields must be ≥ 0 when present.
2035
2491
  * - `fieldBounds` — numeric bounds, e.g. `issued lte authorized`.
2036
2492
  * - `immutableFields` — set-once fields an overwrite must carry unchanged.
2493
+ * - `references` — a field holds the key of a document that must exist in
2494
+ * another collection of the same scope (e.g. a security's `stakeholderId`
2495
+ * → `stakeholders`). Checked at the end of the write (a batch may create
2496
+ * both together); deleting a referenced document is refused.
2497
+ * - `ledgerSums` — a counter field may only change by exactly the sum of the
2498
+ * matching rows appended to an append-only ledger collection in the same
2499
+ * write (e.g. a security's `quantityOutstanding` by its transactions'
2500
+ * `quantityDelta`), and ledger rows naming a counter must be matched by it.
2037
2501
  *
2038
2502
  * Violations reject the write with code `CONSTRAINT_VIOLATION`.
2039
2503
  */
@@ -2042,6 +2506,47 @@ export interface DataStoreCollectionConstraints {
2042
2506
  nonNegative?: string[];
2043
2507
  fieldBounds?: DataStoreFieldBound[];
2044
2508
  immutableFields?: string[];
2509
+ references?: DataStoreReference[];
2510
+ ledgerSums?: DataStoreLedgerSum[];
2511
+ }
2512
+ /**
2513
+ * Counter-follows-ledger: `field` on this collection's documents may only
2514
+ * change by the sum of the matching rows appended to `ledger` (an append-only
2515
+ * collection of the same scope) in the same write. Checked at the end of the
2516
+ * write, so a batch may write the ledger rows and the counter in any order.
2517
+ */
2518
+ export interface DataStoreLedgerSum {
2519
+ /** Numeric counter field (absent/null counts as 0). */
2520
+ field: string;
2521
+ /** The append-only ledger collection. */
2522
+ ledger: string;
2523
+ /** Which ledger rows count, and with what sign (1–4 terms). */
2524
+ terms: DataStoreLedgerSumTerm[];
2525
+ }
2526
+ /** A ledger row counts toward the counter whose key its `key` field holds. */
2527
+ export interface DataStoreLedgerSumTerm {
2528
+ /** Ledger-row field naming the counter document's key. */
2529
+ key: string;
2530
+ /** Numeric ledger-row field to add. */
2531
+ amount: string;
2532
+ /** Subtract instead (e.g. the receiving side of a transfer row). */
2533
+ negate?: boolean;
2534
+ /** Only rows whose `field` holds one of these strings count. */
2535
+ when?: {
2536
+ field: string;
2537
+ in: string[];
2538
+ };
2539
+ }
2540
+ /**
2541
+ * One declared reference: `field` holds the key of a document in
2542
+ * `collection` (same arche, same scope). Skipped when the field is absent or
2543
+ * null; the writer must be able to read the target collection.
2544
+ */
2545
+ export interface DataStoreReference {
2546
+ /** Dot-notation path into the document data holding the target key. */
2547
+ field: string;
2548
+ /** Target collection name. */
2549
+ collection: string;
2045
2550
  }
2046
2551
  /**
2047
2552
  * One precondition on an atomic {@link FiasDataStoreApi.batch}: evaluated by
@@ -2345,6 +2850,13 @@ export interface DataStoreWorkspace {
2345
2850
  createdAt: string;
2346
2851
  /** Soft-archive timestamp; null while active. */
2347
2852
  archivedAt: string | null;
2853
+ /**
2854
+ * True for the shared space of a Fias workspace (see
2855
+ * `FiasWorkspacesApi.openForWorkspace`): its members are the Fias
2856
+ * workspace's members, so the member methods refuse with
2857
+ * `HOLDER_BACKED_WORKSPACE`. Absent from older hosts.
2858
+ */
2859
+ holderBacked?: boolean;
2348
2860
  }
2349
2861
  /** A member of a workspace. Members are addressed by username — the platform
2350
2862
  * userId is internal and never exposed to plugins or users. */
@@ -2374,11 +2886,27 @@ export interface DataStoreWorkspaceMember {
2374
2886
  export interface FiasWorkspacesApi {
2375
2887
  /** Create a workspace; the caller becomes its owner. */
2376
2888
  create: (displayName: string) => Promise<DataStoreWorkspace>;
2889
+ /**
2890
+ * Open the shared space of the Fias org workspace the plugin was opened in
2891
+ * (see `useFiasHolder`), creating it on first use. It exists only once a
2892
+ * workspace owner or admin has approved the app. Its `displayName` is the
2893
+ * workspace's name, and its members are that workspace's members, with their
2894
+ * workspace roles — nobody manages a member list, and someone who leaves the
2895
+ * workspace loses access at once. Every member gets the same space, and it
2896
+ * answers only while the plugin is open in that workspace. Rejects with
2897
+ * `HOLDER_NOT_ELIGIBLE` in a personal workspace, before the workspace has
2898
+ * approved the app, and for a viewer when the space does not exist yet.
2899
+ */
2900
+ openForWorkspace: () => Promise<DataStoreWorkspace>;
2377
2901
  /** List the workspaces the caller is an active member of. */
2378
2902
  list: () => Promise<DataStoreWorkspace[]>;
2379
2903
  /** Get a single workspace (caller must be a member). */
2380
2904
  get: (workspaceId: string) => Promise<DataStoreWorkspace>;
2381
- /** Archive a workspace (owner only). */
2905
+ /**
2906
+ * Archive a workspace (owner only). Final: an archived workspace cannot be
2907
+ * reopened, and it is deleted with its documents 30 days later — tell your
2908
+ * user before they archive.
2909
+ */
2382
2910
  archive: (workspaceId: string) => Promise<void>;
2383
2911
  /** List a workspace's members (any member). */
2384
2912
  listMembers: (workspaceId: string) => Promise<DataStoreWorkspaceMember[]>;