@fias/arche-sdk 2.28.0 → 2.30.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 (42) hide show
  1. package/dist/bridge.d.ts +42 -6
  2. package/dist/bridge.d.ts.map +1 -1
  3. package/dist/bridge.js +93 -2
  4. package/dist/bridge.js.map +1 -1
  5. package/dist/bridge.test.js +89 -0
  6. package/dist/bridge.test.js.map +1 -1
  7. package/dist/entity-ops.d.ts +27 -1
  8. package/dist/entity-ops.d.ts.map +1 -1
  9. package/dist/entity-ops.js +84 -6
  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 +10 -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 +220 -18
  20. package/dist/hooks.d.ts.map +1 -1
  21. package/dist/hooks.js +792 -39
  22. package/dist/hooks.js.map +1 -1
  23. package/dist/hooks.test.js +702 -0
  24. package/dist/hooks.test.js.map +1 -1
  25. package/dist/index.d.ts +4 -2
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +24 -2
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +771 -28
  30. package/dist/limits.d.ts +72 -0
  31. package/dist/limits.d.ts.map +1 -0
  32. package/dist/limits.js +75 -0
  33. package/dist/limits.js.map +1 -0
  34. package/dist/types.d.ts +720 -10
  35. package/dist/types.d.ts.map +1 -1
  36. package/dist/use-fias-access.render.test.d.ts +12 -0
  37. package/dist/use-fias-access.render.test.d.ts.map +1 -0
  38. package/dist/use-fias-access.render.test.js +407 -0
  39. package/dist/use-fias-access.render.test.js.map +1 -0
  40. package/package.json +3 -2
  41. package/templates/default/AGENTS.md +391 -13
  42. package/templates/default/CLAUDE.md +391 -13
package/dist/index.mjs CHANGED
@@ -273,9 +273,17 @@ var FiasBridge = class {
273
273
  this.vendoredAssets = null;
274
274
  this.textModels = null;
275
275
  this.textModelListeners = /* @__PURE__ */ new Set();
276
+ this.holder = null;
277
+ this.holderListeners = /* @__PURE__ */ new Set();
276
278
  this.currentPath = "";
279
+ // Host-chrome state (useFiasChrome). `null` until init, and from a host
280
+ // older than the chrome lane — `hasChrome` tells the two apart.
281
+ this.chrome = null;
282
+ this.hasChrome = false;
283
+ this.chromeListeners = /* @__PURE__ */ new Set();
277
284
  this.hostOrigin = "";
278
285
  this.themeListeners = /* @__PURE__ */ new Set();
286
+ this.accessListeners = /* @__PURE__ */ new Set();
279
287
  this.navigationListeners = /* @__PURE__ */ new Set();
280
288
  this.stepNavigationListeners = /* @__PURE__ */ new Set();
281
289
  // Preview-state preservation (preview mode only). Keyed so multiple
@@ -327,12 +335,21 @@ var FiasBridge = class {
327
335
  this.theme = mergeThemeWithDefaults(initMsg.payload.theme);
328
336
  this.vendoredAssets = initMsg.payload.vendoredAssets ?? null;
329
337
  this.textModels = initMsg.payload.textModels ?? null;
338
+ this.holder = initMsg.payload.holder ?? null;
330
339
  this.currentPath = initMsg.payload.currentPath;
340
+ this.hasChrome = "chrome" in initMsg.payload;
341
+ this.chrome = initMsg.payload.chrome ?? null;
331
342
  this.initialized = true;
332
343
  this.initResolve?.();
333
344
  for (const listener of this.navigationListeners) {
334
345
  listener(this.currentPath);
335
346
  }
347
+ for (const listener of this.holderListeners) {
348
+ listener(this.holder);
349
+ }
350
+ for (const listener of this.chromeListeners) {
351
+ listener(this.chrome);
352
+ }
336
353
  return;
337
354
  }
338
355
  if (this.hostOrigin && event.origin !== this.hostOrigin) return;
@@ -343,6 +360,10 @@ var FiasBridge = class {
343
360
  }
344
361
  return;
345
362
  }
363
+ if (data.type === "access_update") {
364
+ for (const listener of this.accessListeners) listener();
365
+ return;
366
+ }
346
367
  if (data.type === "text_models_update") {
347
368
  if (Array.isArray(data.payload)) {
348
369
  this.textModels = data.payload;
@@ -359,6 +380,16 @@ var FiasBridge = class {
359
380
  }
360
381
  return;
361
382
  }
383
+ if (data.type === "chrome_update") {
384
+ if (data.payload && typeof data.payload === "object") {
385
+ this.hasChrome = true;
386
+ this.chrome = data.payload;
387
+ for (const listener of this.chromeListeners) {
388
+ listener(this.chrome);
389
+ }
390
+ }
391
+ return;
392
+ }
362
393
  if (data.type === "step_navigate") {
363
394
  const { nodeId } = data.payload;
364
395
  if (typeof nodeId === "string") {
@@ -586,6 +617,37 @@ var FiasBridge = class {
586
617
  getCurrentPath() {
587
618
  return this.currentPath;
588
619
  }
620
+ /**
621
+ * The host-chrome state, or null before init / from a host without the
622
+ * chrome lane (`hasChromeSupport` tells the two apart). See `useFiasChrome`.
623
+ */
624
+ getChrome() {
625
+ return this.chrome;
626
+ }
627
+ /** True once a host has delivered chrome state (init or chrome_update). */
628
+ hasChromeSupport() {
629
+ return this.hasChrome;
630
+ }
631
+ /** Called on init and on every chrome_update. */
632
+ onChromeUpdate(listener) {
633
+ this.chromeListeners.add(listener);
634
+ return () => this.chromeListeners.delete(listener);
635
+ }
636
+ /**
637
+ * Set host-chrome state for this arche (fire-and-forget; the host echoes the
638
+ * result as chrome_update). Every present key must be a boolean — the host
639
+ * drops the whole message otherwise. See `useFiasChrome`.
640
+ */
641
+ setChrome(patch) {
642
+ this.send("chrome_set", patch);
643
+ }
644
+ /**
645
+ * Leave the arche for a host destination — a closed enum, never a URL.
646
+ * See `useFiasChrome`.
647
+ */
648
+ navigateHost(target) {
649
+ this.send("chrome_navigate", { target });
650
+ }
589
651
  /**
590
652
  * The live text-model catalog, or null until the host has delivered it (or
591
653
  * when the plugin lacks `entities:invoke`). See `useTextModels`.
@@ -593,6 +655,19 @@ var FiasBridge = class {
593
655
  getTextModels() {
594
656
  return this.textModels;
595
657
  }
658
+ /**
659
+ * The workspace the plugin was opened in, or null before init, without
660
+ * `user:profile:read` / `data:workspace`, or from an older host. Fixed for
661
+ * the life of the plugin. See `useFiasHolder`.
662
+ */
663
+ getHolder() {
664
+ return this.holder;
665
+ }
666
+ /** Called once, when init delivers the holder. */
667
+ onHolderReady(listener) {
668
+ this.holderListeners.add(listener);
669
+ return () => this.holderListeners.delete(listener);
670
+ }
596
671
  onTextModelsUpdate(listener) {
597
672
  this.textModelListeners.add(listener);
598
673
  return () => this.textModelListeners.delete(listener);
@@ -601,6 +676,14 @@ var FiasBridge = class {
601
676
  this.themeListeners.add(listener);
602
677
  return () => this.themeListeners.delete(listener);
603
678
  }
679
+ /**
680
+ * The host says the person's own access may have changed (ADR-034) — after
681
+ * its access sheet changed it. Carries nothing: ask `my_access` again.
682
+ */
683
+ onAccessUpdate(listener) {
684
+ this.accessListeners.add(listener);
685
+ return () => this.accessListeners.delete(listener);
686
+ }
604
687
  onNavigationUpdate(listener) {
605
688
  this.navigationListeners.add(listener);
606
689
  return () => this.navigationListeners.delete(listener);
@@ -724,7 +807,9 @@ var FiasBridge = class {
724
807
  }
725
808
  this.pendingRequests.clear();
726
809
  this.themeListeners.clear();
810
+ this.accessListeners.clear();
727
811
  this.textModelListeners.clear();
812
+ this.holderListeners.clear();
728
813
  this.navigationListeners.clear();
729
814
  this.stepNavigationListeners.clear();
730
815
  this.previewStateProviders.clear();
@@ -757,7 +842,7 @@ var FiasBridge = class {
757
842
  /**
758
843
  * Listens for the terminal ending of a logical realtime subscription.
759
844
  * Reasons are a closed union — `authorization_revoked` and
760
- * `collection_deleted` are definitive; the rest may be worth a fresh
845
+ * `collection_deleted` (the resource is gone) are definitive; the rest may be worth a fresh
761
846
  * subscribe once conditions change.
762
847
  */
763
848
  onSubscriptionEnded(subscriptionId, listener) {
@@ -1068,17 +1153,46 @@ var PLUGIN_WORKSPACES_ENTITY_ID = "ent_intg_plugin_workspaces_00000";
1068
1153
  var PLUGIN_STORE_ENTITY_ID = "ent_intg_plugin_store_0000000000";
1069
1154
  var VAULT_USER_DOCUMENTS_ENTITY_ID = "ent_intg_vault_documents_0000000";
1070
1155
  var VAULT_ARCHE_DOCUMENTS_ENTITY_ID = "ent_intg_vault_arche_docs_000000";
1156
+ var VAULT_CREATIVE_ENTITY_ID = "ent_intg_vault_creative_00000000";
1071
1157
  var COMMUNITY_ASSETS_ENTITY_ID = "ent_intg_community_assets_000000";
1072
1158
  var DOCUMENT_SIGN_ENTITY_ID = "ent_intg_document_sign_000000000";
1073
1159
  var COMPANY_EMAIL_SEND_ENTITY_ID = "ent_intg_company_email_send_0000";
1160
+ var CONNECTIONS_ENTITY_ID = "ent_intg_connections_00000000000";
1161
+ var CONNECTIONS_CONNECT_ENTITY_ID = "ent_intg_connections_connect_000";
1162
+ var X_ENTITY_ID = "ent_intg_twitter_000000000000000";
1163
+ var LINKEDIN_ENTITY_ID = "ent_intg_linkedin_00000000000000";
1164
+ var ACTION_CONFIRMATION_ENTITY_ID = "ent_intg_action_confirmation_000";
1165
+ var APP_ACCESS_DIALOG_ENTITY_ID = "ent_intg_app_access_dialog_00000";
1166
+ var CREATIVE_PICKER_ENTITY_ID = "ent_intg_creative_picker_0000000";
1167
+ var SCHEDULED_INVOCATIONS_ENTITY_ID = "ent_intg_scheduled_invocations00";
1168
+ var CONFIRM_TIMEOUT_MS = 10 * 60 * 1e3;
1169
+ var APPROVED_CALL_TIMEOUT_MS = 2 * 60 * 1e3;
1074
1170
  var COMMUNITY_ASSET_MAX_URL_BATCH = 50;
1075
1171
  var COMMUNITY_ASSET_MAX_PUBLISH_BATCH = 20;
1076
1172
  async function invokeEntityOp(bridge, entityId, op, args = {}) {
1077
- const res = await bridge.request("entity_invoke", {
1078
- entityId,
1079
- payload: { op, ...args }
1080
- });
1081
- return res.output;
1173
+ const payload = { op, ...args };
1174
+ const res = await bridge.request("entity_invoke", { entityId, payload });
1175
+ if (!res.confirmationRequired) return res.output;
1176
+ return confirmAndResend(bridge, entityId, payload, res.confirmationRequired.pendingActionId);
1177
+ }
1178
+ async function confirmAndResend(bridge, entityId, payload, pendingActionId) {
1179
+ const answer = await bridge.request(
1180
+ "client_entity_invoke",
1181
+ { entityId: ACTION_CONFIRMATION_ENTITY_ID, input: { pendingActionId } },
1182
+ CONFIRM_TIMEOUT_MS
1183
+ );
1184
+ if (answer && "error" in answer) {
1185
+ throw new FiasBridgeError(answer.error.message, answer.error.code);
1186
+ }
1187
+ if (!answer?.approved) {
1188
+ throw new FiasBridgeError("The person declined this action", "USER_DECLINED");
1189
+ }
1190
+ const done = await bridge.request(
1191
+ "entity_invoke",
1192
+ { entityId, payload, pendingActionId },
1193
+ APPROVED_CALL_TIMEOUT_MS
1194
+ );
1195
+ return done.output;
1082
1196
  }
1083
1197
  async function invokeStoreOp(bridge, op, args = {}) {
1084
1198
  return bridge.request("entity_invoke", {
@@ -1259,6 +1373,15 @@ function useTextModels() {
1259
1373
  }, [bridge]);
1260
1374
  return models;
1261
1375
  }
1376
+ function useFiasHolder() {
1377
+ const bridge = useBridge();
1378
+ const [holder, setHolder] = useState2(bridge.getHolder());
1379
+ useEffect2(() => {
1380
+ setHolder(bridge.getHolder());
1381
+ return bridge.onHolderReady(setHolder);
1382
+ }, [bridge]);
1383
+ return holder;
1384
+ }
1262
1385
  var IMAGE_GENERATE_TIMEOUT_MS = 32e4;
1263
1386
  function useImageGeneration() {
1264
1387
  const bridge = useBridge();
@@ -1518,6 +1641,72 @@ function usePersistentState(key, initialValue) {
1518
1641
  );
1519
1642
  return [value, setValue];
1520
1643
  }
1644
+ var INERT_CHROME = {
1645
+ focusMode: false,
1646
+ focusModeAvailable: false,
1647
+ sidebarAvailable: false,
1648
+ sidebarCollapsed: false,
1649
+ hostExpandedBar: true,
1650
+ hostExpandButton: true
1651
+ };
1652
+ function useFiasChrome() {
1653
+ const bridge = useBridge();
1654
+ const [chrome, setChrome] = useState2(bridge.getChrome());
1655
+ const [supported, setSupported] = useState2(bridge.hasChromeSupport());
1656
+ useEffect2(() => {
1657
+ let cancelled = false;
1658
+ bridge.waitForInit().then(() => {
1659
+ if (cancelled) return;
1660
+ setChrome(bridge.getChrome());
1661
+ setSupported(bridge.hasChromeSupport());
1662
+ });
1663
+ const unsubscribe = bridge.onChromeUpdate((next) => {
1664
+ setChrome(next);
1665
+ setSupported(bridge.hasChromeSupport());
1666
+ });
1667
+ return () => {
1668
+ cancelled = true;
1669
+ unsubscribe();
1670
+ };
1671
+ }, [bridge]);
1672
+ useEffect2(() => {
1673
+ bridge.setChrome({ hostExpandButton: false });
1674
+ }, [bridge]);
1675
+ const setFocusMode = useCallback((on) => bridge.setChrome({ focusMode: on }), [bridge]);
1676
+ const setSidebarCollapsed = useCallback(
1677
+ (collapsed) => bridge.setChrome({ sidebarCollapsed: collapsed }),
1678
+ [bridge]
1679
+ );
1680
+ const setHostExpandedBar = useCallback(
1681
+ (shown) => bridge.setChrome({ hostExpandedBar: shown }),
1682
+ [bridge]
1683
+ );
1684
+ const goToFiasHome = useCallback(() => bridge.navigateHost("home"), [bridge]);
1685
+ const goToWorktop = useCallback(() => bridge.navigateHost("worktop"), [bridge]);
1686
+ const openAssistant = useCallback(() => bridge.openAssistant(), [bridge]);
1687
+ return useMemo2(
1688
+ () => ({
1689
+ ...chrome ?? INERT_CHROME,
1690
+ supported: supported && chrome !== null,
1691
+ setFocusMode,
1692
+ setSidebarCollapsed,
1693
+ setHostExpandedBar,
1694
+ goToFiasHome,
1695
+ goToWorktop,
1696
+ openAssistant
1697
+ }),
1698
+ [
1699
+ chrome,
1700
+ supported,
1701
+ setFocusMode,
1702
+ setSidebarCollapsed,
1703
+ setHostExpandedBar,
1704
+ goToFiasHome,
1705
+ goToWorktop,
1706
+ openAssistant
1707
+ ]
1708
+ );
1709
+ }
1521
1710
  function useStepNavigation(initialStep, options) {
1522
1711
  const bridge = useBridge();
1523
1712
  const persistKey = options?.persistKey;
@@ -1619,15 +1808,34 @@ function useFiasDataStore() {
1619
1808
  "put",
1620
1809
  {
1621
1810
  collection,
1622
- key,
1811
+ // No key: the server makes one (collections with audiences, ADR-034).
1812
+ ...key !== null ? { key } : {},
1623
1813
  data,
1624
- workspaceId: options?.workspaceId
1814
+ workspaceId: options?.workspaceId,
1815
+ ...options?.audience !== void 0 ? { audience: options.audience } : {}
1625
1816
  }
1626
1817
  );
1627
- return { version: res?.version };
1818
+ return {
1819
+ version: res?.version,
1820
+ ...res?.key !== void 0 ? { key: res.key } : {},
1821
+ ...res?.audience !== void 0 ? { audience: res.audience } : {}
1822
+ };
1628
1823
  },
1629
1824
  [bridge]
1630
1825
  );
1826
+ const create = useCallback(
1827
+ async (collection, data, options) => {
1828
+ const result = await put(collection, null, data, options);
1829
+ if (result.key === void 0) {
1830
+ throw new FiasBridgeError(
1831
+ "This Fias does not support creating documents in audiences yet",
1832
+ "AUDIENCES_UNAVAILABLE"
1833
+ );
1834
+ }
1835
+ return { ...result, key: result.key };
1836
+ },
1837
+ [put]
1838
+ );
1631
1839
  const get = useCallback(
1632
1840
  async (collection, key, options) => {
1633
1841
  const res = await invokeEntityOp(
@@ -1637,7 +1845,8 @@ function useFiasDataStore() {
1637
1845
  {
1638
1846
  collection,
1639
1847
  key,
1640
- workspaceId: options?.workspaceId
1848
+ workspaceId: options?.workspaceId,
1849
+ ...options?.audience !== void 0 ? { audience: options.audience } : {}
1641
1850
  }
1642
1851
  );
1643
1852
  return res.data;
@@ -1649,7 +1858,8 @@ function useFiasDataStore() {
1649
1858
  const res = await invokeEntityOp(bridge, PLUGIN_DATASTORE_ENTITY_ID, "get", {
1650
1859
  collection,
1651
1860
  key,
1652
- workspaceId: options?.workspaceId
1861
+ workspaceId: options?.workspaceId,
1862
+ ...options?.audience !== void 0 ? { audience: options.audience } : {}
1653
1863
  });
1654
1864
  if (res.data === null || res.data === void 0) return null;
1655
1865
  return {
@@ -1657,7 +1867,8 @@ function useFiasDataStore() {
1657
1867
  data: res.data,
1658
1868
  updatedAt: res.updatedAt ?? "",
1659
1869
  ...res.version !== void 0 ? { version: res.version } : {},
1660
- ...res.authoredByCollaborator !== void 0 ? { authoredByCollaborator: res.authoredByCollaborator } : {}
1870
+ ...res.authoredByCollaborator !== void 0 ? { authoredByCollaborator: res.authoredByCollaborator } : {},
1871
+ ...res.audience !== void 0 ? { audience: res.audience } : {}
1661
1872
  };
1662
1873
  },
1663
1874
  [bridge]
@@ -1674,7 +1885,8 @@ function useFiasDataStore() {
1674
1885
  // answered WORKSPACE_REQUIRED, pointing the author at the collection
1675
1886
  // rather than at the call. Take the scope arg when it carries one and
1676
1887
  // otherwise leave whatever the spread put there.
1677
- ...scope?.workspaceId !== void 0 ? { workspaceId: scope.workspaceId } : {}
1888
+ ...scope?.workspaceId !== void 0 ? { workspaceId: scope.workspaceId } : {},
1889
+ ...scope?.audience !== void 0 ? { audience: scope.audience } : {}
1678
1890
  });
1679
1891
  },
1680
1892
  [bridge]
@@ -1690,7 +1902,8 @@ function useFiasDataStore() {
1690
1902
  query: queryText,
1691
1903
  ...options,
1692
1904
  // See `query` above — never blank a caller-supplied workspaceId.
1693
- ...scope?.workspaceId !== void 0 ? { workspaceId: scope.workspaceId } : {}
1905
+ ...scope?.workspaceId !== void 0 ? { workspaceId: scope.workspaceId } : {},
1906
+ ...scope?.audience !== void 0 ? { audience: scope.audience } : {}
1694
1907
  }
1695
1908
  );
1696
1909
  return res.matches;
@@ -1728,6 +1941,7 @@ function useFiasDataStore() {
1728
1941
  listCollections,
1729
1942
  deleteCollection,
1730
1943
  put,
1944
+ create,
1731
1945
  get,
1732
1946
  getDocument,
1733
1947
  query,
@@ -1740,6 +1954,7 @@ function useFiasDataStore() {
1740
1954
  listCollections,
1741
1955
  deleteCollection,
1742
1956
  put,
1957
+ create,
1743
1958
  get,
1744
1959
  getDocument,
1745
1960
  query,
@@ -1763,6 +1978,15 @@ function useFiasWorkspaces() {
1763
1978
  },
1764
1979
  [bridge]
1765
1980
  );
1981
+ const openForWorkspace = useCallback(async () => {
1982
+ const res = await invokeEntityOp(
1983
+ bridge,
1984
+ PLUGIN_WORKSPACES_ENTITY_ID,
1985
+ "create",
1986
+ { forActingHolder: true }
1987
+ );
1988
+ return res.workspace;
1989
+ }, [bridge]);
1766
1990
  const list = useCallback(async () => {
1767
1991
  const res = await invokeEntityOp(
1768
1992
  bridge,
@@ -1840,10 +2064,237 @@ function useFiasWorkspaces() {
1840
2064
  [bridge]
1841
2065
  );
1842
2066
  return useMemo2(
1843
- () => ({ create, list, get, archive, listMembers, addMember, updateMember, removeMember }),
1844
- [create, list, get, archive, listMembers, addMember, updateMember, removeMember]
2067
+ () => ({
2068
+ create,
2069
+ openForWorkspace,
2070
+ list,
2071
+ get,
2072
+ archive,
2073
+ listMembers,
2074
+ addMember,
2075
+ updateMember,
2076
+ removeMember
2077
+ }),
2078
+ [
2079
+ create,
2080
+ openForWorkspace,
2081
+ list,
2082
+ get,
2083
+ archive,
2084
+ listMembers,
2085
+ addMember,
2086
+ updateMember,
2087
+ removeMember
2088
+ ]
1845
2089
  );
1846
2090
  }
2091
+ var NO_WORKSPACE_ACCESS_CODES = /* @__PURE__ */ new Set([
2092
+ "NOT_A_MEMBER",
2093
+ "WORKSPACE_NOT_FOUND"
2094
+ ]);
2095
+ function useFiasAccess(workspaceId) {
2096
+ const bridge = useBridge();
2097
+ const known = workspaceId ? peekSharedAccess(bridge, workspaceId) : void 0;
2098
+ const [settled, setSettled] = useState2(known?.settled ?? null);
2099
+ const [fetching, setFetching] = useState2(known ? known.fetching : !!workspaceId);
2100
+ useEffect2(() => {
2101
+ if (!workspaceId) return;
2102
+ const shared = sharedAccessFor(bridge, workspaceId);
2103
+ const sync = () => {
2104
+ setSettled(shared.settled);
2105
+ setFetching(shared.fetching);
2106
+ };
2107
+ const unsubscribe = subscribeSharedAccess(shared, sync);
2108
+ askSharedAccess(shared, "ensure");
2109
+ sync();
2110
+ return unsubscribe;
2111
+ }, [bridge, workspaceId]);
2112
+ const refetch = useCallback(() => {
2113
+ if (workspaceId) askSharedAccess(sharedAccessFor(bridge, workspaceId), "again");
2114
+ }, [bridge, workspaceId]);
2115
+ const openAccessDialog = useCallback(async () => {
2116
+ let answer;
2117
+ try {
2118
+ answer = await bridge.request(
2119
+ "client_entity_invoke",
2120
+ { entityId: APP_ACCESS_DIALOG_ENTITY_ID, input: {} },
2121
+ ACCESS_SHEET_TIMEOUT_MS
2122
+ );
2123
+ } catch (err) {
2124
+ if (err instanceof FiasBridgeError && err.code === "BRIDGE_ERROR" && err.message.includes("no client-side executor")) {
2125
+ throw new FiasBridgeError("Managing access is not available here", "ACCESS_UNAVAILABLE");
2126
+ }
2127
+ throw err;
2128
+ }
2129
+ if (answer && "error" in answer) {
2130
+ throw new FiasBridgeError(answer.error.message, answer.error.code);
2131
+ }
2132
+ const changed = answer?.changed === true;
2133
+ if (changed) refetch();
2134
+ return { changed };
2135
+ }, [bridge, refetch]);
2136
+ const own = workspaceId && settled?.workspaceId === workspaceId ? settled : null;
2137
+ const current = known ? known.settled : own;
2138
+ const access = current?.access ?? null;
2139
+ const error = current?.error ?? null;
2140
+ const isLoading = !!workspaceId && (current === null || (known ? known.fetching : fetching));
2141
+ const can = useCallback(
2142
+ (permission) => access?.mode === "roles" && access.permissions.includes(permission),
2143
+ [access]
2144
+ );
2145
+ const canReadAudience = useCallback(
2146
+ (audience) => access?.mode === "roles" && (access.audiences?.readable.includes(audience) ?? false),
2147
+ [access]
2148
+ );
2149
+ const canDiscloseTo = useCallback(
2150
+ (audience) => access?.mode === "roles" && (access.audiences?.disclosable.includes(audience) ?? false),
2151
+ [access]
2152
+ );
2153
+ return useMemo2(
2154
+ () => ({
2155
+ access,
2156
+ isLoading,
2157
+ error,
2158
+ refetch,
2159
+ can,
2160
+ canReadAudience,
2161
+ canDiscloseTo,
2162
+ openAccessDialog
2163
+ }),
2164
+ [access, isLoading, error, refetch, can, canReadAudience, canDiscloseTo, openAccessDialog]
2165
+ );
2166
+ }
2167
+ var lastAccessAnswers = /* @__PURE__ */ new Map();
2168
+ var FOCUS_REFETCH_MIN_MS = 3e4;
2169
+ var ACCESS_SHEET_TIMEOUT_MS = 30 * 60 * 1e3;
2170
+ var sharedAccessByBridge = /* @__PURE__ */ new WeakMap();
2171
+ function peekSharedAccess(bridge, workspaceId) {
2172
+ return sharedAccessByBridge.get(bridge)?.get(workspaceId);
2173
+ }
2174
+ function sharedAccessFor(bridge, workspaceId) {
2175
+ let byWorkspace = sharedAccessByBridge.get(bridge);
2176
+ if (!byWorkspace) {
2177
+ byWorkspace = /* @__PURE__ */ new Map();
2178
+ sharedAccessByBridge.set(bridge, byWorkspace);
2179
+ }
2180
+ let shared = byWorkspace.get(workspaceId);
2181
+ if (!shared) {
2182
+ shared = {
2183
+ bridge,
2184
+ workspaceId,
2185
+ settled: null,
2186
+ fetching: false,
2187
+ answered: false,
2188
+ answeredAt: 0,
2189
+ inFlight: null,
2190
+ scheduled: false,
2191
+ again: false,
2192
+ listeners: /* @__PURE__ */ new Set(),
2193
+ stopListening: null
2194
+ };
2195
+ byWorkspace.set(workspaceId, shared);
2196
+ }
2197
+ return shared;
2198
+ }
2199
+ function releaseSharedAccess(shared) {
2200
+ if (shared.listeners.size > 0 || shared.inFlight || shared.scheduled) return;
2201
+ const byWorkspace = sharedAccessByBridge.get(shared.bridge);
2202
+ if (byWorkspace?.get(shared.workspaceId) === shared) byWorkspace.delete(shared.workspaceId);
2203
+ }
2204
+ function notifySharedAccess(shared) {
2205
+ for (const listener of Array.from(shared.listeners)) listener();
2206
+ }
2207
+ function subscribeSharedAccess(shared, listener) {
2208
+ shared.listeners.add(listener);
2209
+ if (!shared.stopListening) {
2210
+ const unsubscribe = shared.bridge.onAccessUpdate(() => askSharedAccess(shared, "again"));
2211
+ const onFocus = () => {
2212
+ if (Date.now() - shared.answeredAt >= FOCUS_REFETCH_MIN_MS) {
2213
+ askSharedAccess(shared, "join");
2214
+ }
2215
+ };
2216
+ const win = typeof window === "undefined" ? null : window;
2217
+ win?.addEventListener("focus", onFocus);
2218
+ shared.stopListening = () => {
2219
+ unsubscribe();
2220
+ win?.removeEventListener("focus", onFocus);
2221
+ };
2222
+ }
2223
+ return () => {
2224
+ shared.listeners.delete(listener);
2225
+ if (shared.listeners.size === 0 && shared.stopListening) {
2226
+ shared.stopListening();
2227
+ shared.stopListening = null;
2228
+ }
2229
+ releaseSharedAccess(shared);
2230
+ };
2231
+ }
2232
+ function askSharedAccess(shared, demand) {
2233
+ if (shared.inFlight) {
2234
+ if (demand === "again") shared.again = true;
2235
+ return;
2236
+ }
2237
+ if (shared.scheduled) return;
2238
+ if (demand === "ensure" && shared.answered) return;
2239
+ shared.scheduled = true;
2240
+ void Promise.resolve().then(() => {
2241
+ shared.scheduled = false;
2242
+ startSharedAccess(shared);
2243
+ });
2244
+ }
2245
+ function settleSharedAccess(shared, access) {
2246
+ const answer = JSON.stringify(access);
2247
+ const before = lastAccessAnswers.get(shared.workspaceId);
2248
+ const noAccess = access.mode === "tier" && access.tier === null;
2249
+ if (noAccess || before !== void 0 && before !== answer) clearSdkReadCaches();
2250
+ lastAccessAnswers.set(shared.workspaceId, answer);
2251
+ shared.answered = true;
2252
+ shared.answeredAt = Date.now();
2253
+ shared.settled = { workspaceId: shared.workspaceId, access, error: null };
2254
+ }
2255
+ function startSharedAccess(shared) {
2256
+ if (shared.listeners.size === 0) {
2257
+ releaseSharedAccess(shared);
2258
+ return;
2259
+ }
2260
+ const { bridge, workspaceId } = shared;
2261
+ const background = shared.answered;
2262
+ if (!background) {
2263
+ shared.fetching = true;
2264
+ notifySharedAccess(shared);
2265
+ }
2266
+ shared.inFlight = (async () => {
2267
+ try {
2268
+ const res = await invokeEntityOp(
2269
+ bridge,
2270
+ PLUGIN_WORKSPACES_ENTITY_ID,
2271
+ "my_access",
2272
+ { workspaceId }
2273
+ );
2274
+ if (shared.listeners.size > 0) settleSharedAccess(shared, res.access);
2275
+ } catch (err) {
2276
+ if (shared.listeners.size === 0) {
2277
+ } else if (err instanceof FiasBridgeError && NO_WORKSPACE_ACCESS_CODES.has(err.code)) {
2278
+ settleSharedAccess(shared, { mode: "tier", workspaceId, tier: null, expiresAt: null });
2279
+ } else if (!background) {
2280
+ shared.settled = {
2281
+ workspaceId,
2282
+ access: null,
2283
+ error: err instanceof Error ? err : new Error(String(err))
2284
+ };
2285
+ }
2286
+ } finally {
2287
+ shared.fetching = false;
2288
+ shared.inFlight = null;
2289
+ if (shared.again) {
2290
+ shared.again = false;
2291
+ askSharedAccess(shared, "again");
2292
+ }
2293
+ notifySharedAccess(shared);
2294
+ releaseSharedAccess(shared);
2295
+ }
2296
+ })();
2297
+ }
1847
2298
  function useFiasStore() {
1848
2299
  const bridge = useBridge();
1849
2300
  const [products, setProducts] = useState2([]);
@@ -1929,6 +2380,12 @@ function useFiasStore() {
1929
2380
  var DOWNLOAD_URL_REFRESH_BUFFER_MS = 6e4;
1930
2381
  var downloadUrlCache = /* @__PURE__ */ new Map();
1931
2382
  var downloadUrlInflight = /* @__PURE__ */ new Map();
2383
+ function clearSdkReadCaches() {
2384
+ downloadUrlGeneration += 1;
2385
+ downloadUrlCache.clear();
2386
+ downloadUrlInflight.clear();
2387
+ }
2388
+ var downloadUrlGeneration = 0;
1932
2389
  async function fetchVaultDocumentDownloadUrl(documentId) {
1933
2390
  const now = Date.now();
1934
2391
  const cached = downloadUrlCache.get(documentId);
@@ -1938,6 +2395,7 @@ async function fetchVaultDocumentDownloadUrl(documentId) {
1938
2395
  const inflight = downloadUrlInflight.get(documentId);
1939
2396
  if (inflight) return inflight;
1940
2397
  const bridge = getBridge();
2398
+ const generation = downloadUrlGeneration;
1941
2399
  const promise = bridge.request(
1942
2400
  "vault_documents_download_url",
1943
2401
  { documentId }
@@ -1947,14 +2405,16 @@ async function fetchVaultDocumentDownloadUrl(documentId) {
1947
2405
  expiresAt: new Date(result.expiresAt).getTime(),
1948
2406
  contentType: result.contentType
1949
2407
  };
1950
- downloadUrlCache.set(documentId, {
1951
- url: normalized.url,
1952
- expiresAt: normalized.expiresAt,
1953
- contentType: normalized.contentType
1954
- });
2408
+ if (generation === downloadUrlGeneration) {
2409
+ downloadUrlCache.set(documentId, {
2410
+ url: normalized.url,
2411
+ expiresAt: normalized.expiresAt,
2412
+ contentType: normalized.contentType
2413
+ });
2414
+ }
1955
2415
  return normalized;
1956
2416
  }).finally(() => {
1957
- downloadUrlInflight.delete(documentId);
2417
+ if (downloadUrlInflight.get(documentId) === promise) downloadUrlInflight.delete(documentId);
1958
2418
  });
1959
2419
  downloadUrlInflight.set(documentId, promise);
1960
2420
  return promise;
@@ -2715,13 +3175,22 @@ function useFiasPreviewState(key, getState, onRestore) {
2715
3175
  );
2716
3176
  }, [bridge, key]);
2717
3177
  }
2718
- function useDataSubscription(collection, onInvalidate, options) {
3178
+ function stableStringify(value) {
3179
+ return JSON.stringify(
3180
+ value,
3181
+ (_key, v) => v && typeof v === "object" && !Array.isArray(v) ? Object.fromEntries(
3182
+ Object.keys(v).sort().map((k) => [k, v[k]])
3183
+ ) : v
3184
+ );
3185
+ }
3186
+ function useEntitySubscription(entityId, payload, onInvalidate, options) {
2719
3187
  const bridge = useBridge();
2720
3188
  const [state, setState] = useState2({ status: "subscribing" });
2721
3189
  const onInvalidateRef = useRef(onInvalidate);
2722
3190
  onInvalidateRef.current = onInvalidate;
2723
3191
  const enabled = options?.enabled ?? true;
2724
- const workspaceId = options?.workspaceId;
3192
+ const minRefetchIntervalMs = Math.max(0, options?.minRefetchIntervalMs ?? 0);
3193
+ const payloadKey = stableStringify(payload);
2725
3194
  useEffect2(() => {
2726
3195
  if (!enabled) {
2727
3196
  setState({ status: "ended", endedReason: "unsubscribed" });
@@ -2733,12 +3202,27 @@ function useDataSubscription(collection, onInvalidate, options) {
2733
3202
  let unsubscribeEnded = null;
2734
3203
  let refetching = false;
2735
3204
  let trailing = false;
3205
+ let lastRunAt = -Infinity;
3206
+ let intervalTimer = null;
2736
3207
  const runInvalidate = async () => {
2737
- if (refetching) {
3208
+ if (refetching || intervalTimer) {
3209
+ trailing = true;
3210
+ return;
3211
+ }
3212
+ const wait = lastRunAt + minRefetchIntervalMs - Date.now();
3213
+ if (wait > 0) {
2738
3214
  trailing = true;
3215
+ intervalTimer = setTimeout(() => {
3216
+ intervalTimer = null;
3217
+ if (trailing && !cancelled) {
3218
+ trailing = false;
3219
+ void runInvalidate();
3220
+ }
3221
+ }, wait);
2739
3222
  return;
2740
3223
  }
2741
3224
  refetching = true;
3225
+ lastRunAt = Date.now();
2742
3226
  try {
2743
3227
  await onInvalidateRef.current();
2744
3228
  } catch {
@@ -2753,8 +3237,8 @@ function useDataSubscription(collection, onInvalidate, options) {
2753
3237
  void (async () => {
2754
3238
  try {
2755
3239
  const res = await bridge.request("entity_invoke", {
2756
- entityId: PLUGIN_DATASTORE_ENTITY_ID,
2757
- payload: { op: "subscribe", collection, workspaceId }
3240
+ entityId,
3241
+ payload: JSON.parse(payloadKey)
2758
3242
  });
2759
3243
  const subscription = res?.output;
2760
3244
  if (!subscription || subscription.kind !== "subscription" || typeof subscription.subscriptionId !== "string") {
@@ -2778,13 +3262,28 @@ function useDataSubscription(collection, onInvalidate, options) {
2778
3262
  })();
2779
3263
  return () => {
2780
3264
  cancelled = true;
3265
+ if (intervalTimer) clearTimeout(intervalTimer);
2781
3266
  unsubscribeEvent?.();
2782
3267
  unsubscribeEnded?.();
2783
3268
  if (subscriptionId) bridge.releaseSubscription(subscriptionId);
2784
3269
  };
2785
- }, [bridge, collection, workspaceId, enabled]);
3270
+ }, [bridge, entityId, payloadKey, enabled, minRefetchIntervalMs]);
2786
3271
  return state;
2787
3272
  }
3273
+ function useDataSubscription(collection, onInvalidate, options) {
3274
+ const audience = options?.audience;
3275
+ return useEntitySubscription(
3276
+ PLUGIN_DATASTORE_ENTITY_ID,
3277
+ {
3278
+ op: "subscribe",
3279
+ collection,
3280
+ workspaceId: options?.workspaceId,
3281
+ ...audience !== void 0 ? { audience } : {}
3282
+ },
3283
+ onInvalidate,
3284
+ { enabled: options?.enabled }
3285
+ );
3286
+ }
2788
3287
  function useVaultUserDocuments() {
2789
3288
  const bridge = useBridge();
2790
3289
  const pick = useCallback(
@@ -2984,6 +3483,162 @@ async function fetchCommunityAssetUrls(bridge, assetIds) {
2984
3483
  }
2985
3484
  return hits;
2986
3485
  }
3486
+ var CREATIVE_PICKER_TIMEOUT_MS = 30 * 60 * 1e3;
3487
+ function useCreativeLibrary() {
3488
+ const bridge = useBridge();
3489
+ return useMemo2(() => {
3490
+ const item = async (op, args) => (await invokeEntityOp(bridge, VAULT_CREATIVE_ENTITY_ID, op, args)).item;
3491
+ return {
3492
+ list: async (options = {}) => (await invokeEntityOp(
3493
+ bridge,
3494
+ VAULT_CREATIVE_ENTITY_ID,
3495
+ "list_items",
3496
+ { ...options }
3497
+ )).items,
3498
+ get: (itemId, version) => item("get_item", { itemId, ...version !== void 0 ? { version } : {} }),
3499
+ create: (fields) => item("create_item", { referenceDocumentIds: [], ...fields }),
3500
+ update: (itemId, fields) => item("update_item", { itemId, ...fields }),
3501
+ remove: (itemId) => item("delete_item", { itemId }),
3502
+ restore: (itemId) => item("restore_item", { itemId }),
3503
+ pick: async (options = {}) => {
3504
+ let answer;
3505
+ try {
3506
+ answer = await bridge.request(
3507
+ "client_entity_invoke",
3508
+ {
3509
+ entityId: CREATIVE_PICKER_ENTITY_ID,
3510
+ input: options.kind ? { kind: options.kind } : {}
3511
+ },
3512
+ CREATIVE_PICKER_TIMEOUT_MS
3513
+ );
3514
+ } catch (err) {
3515
+ if (err instanceof FiasBridgeError && err.code === "BRIDGE_ERROR" && err.message.includes("no client-side executor")) {
3516
+ throw new FiasBridgeError(
3517
+ "The Creative Library picker is not available here",
3518
+ "PICKER_UNAVAILABLE"
3519
+ );
3520
+ }
3521
+ throw err;
3522
+ }
3523
+ if (answer && "error" in answer) {
3524
+ throw new FiasBridgeError(answer.error.message, answer.error.code);
3525
+ }
3526
+ return answer;
3527
+ }
3528
+ };
3529
+ }, [bridge]);
3530
+ }
3531
+ var CONNECT_TIMEOUT_MS = 10 * 60 * 1e3;
3532
+ function useFiasConnections() {
3533
+ const bridge = useBridge();
3534
+ const list = useCallback(async () => {
3535
+ const res = await invokeEntityOp(
3536
+ bridge,
3537
+ CONNECTIONS_ENTITY_ID,
3538
+ "list"
3539
+ );
3540
+ return res.connections;
3541
+ }, [bridge]);
3542
+ const connect = useCallback(
3543
+ async (provider) => {
3544
+ const result = await bridge.request(
3545
+ "client_entity_invoke",
3546
+ { entityId: CONNECTIONS_CONNECT_ENTITY_ID, input: { provider } },
3547
+ CONNECT_TIMEOUT_MS
3548
+ );
3549
+ if (result && "error" in result) {
3550
+ throw new FiasBridgeError(result.error.message, result.error.code);
3551
+ }
3552
+ return result;
3553
+ },
3554
+ [bridge]
3555
+ );
3556
+ const release = useCallback(
3557
+ async (connectionId) => {
3558
+ await invokeEntityOp(bridge, CONNECTIONS_ENTITY_ID, "release", { connectionId });
3559
+ },
3560
+ [bridge]
3561
+ );
3562
+ return useMemo2(() => ({ list, connect, release }), [list, connect, release]);
3563
+ }
3564
+ function useFiasX() {
3565
+ const bridge = useBridge();
3566
+ return useMemo2(
3567
+ () => ({
3568
+ publishPost: (params) => invokeEntityOp(bridge, X_ENTITY_ID, "publish_post", { ...params }),
3569
+ searchUsers: async (connectionId, query, options) => (await invokeEntityOp(bridge, X_ENTITY_ID, "search_users", {
3570
+ connectionId,
3571
+ query,
3572
+ ...options
3573
+ })).users,
3574
+ getUserPosts: async (connectionId, options) => (await invokeEntityOp(bridge, X_ENTITY_ID, "get_user_posts", {
3575
+ connectionId,
3576
+ ...options
3577
+ })).posts,
3578
+ getPostMetrics: async (connectionId, postIds) => (await invokeEntityOp(
3579
+ bridge,
3580
+ X_ENTITY_ID,
3581
+ "get_post_metrics",
3582
+ { connectionId, postIds }
3583
+ )).metrics,
3584
+ getAccountStats: (connectionId) => invokeEntityOp(bridge, X_ENTITY_ID, "get_account_stats", {
3585
+ connectionId
3586
+ })
3587
+ }),
3588
+ [bridge]
3589
+ );
3590
+ }
3591
+ function useFiasSchedules() {
3592
+ const bridge = useBridge();
3593
+ return useMemo2(
3594
+ () => ({
3595
+ schedule: (params) => invokeEntityOp(
3596
+ bridge,
3597
+ SCHEDULED_INVOCATIONS_ENTITY_ID,
3598
+ "schedule",
3599
+ {
3600
+ entityId: params.entityId,
3601
+ verb: params.verb,
3602
+ payload: params.payload,
3603
+ fireAt: params.fireAt instanceof Date ? params.fireAt.toISOString() : params.fireAt
3604
+ }
3605
+ ),
3606
+ list: async (options) => (await invokeEntityOp(
3607
+ bridge,
3608
+ SCHEDULED_INVOCATIONS_ENTITY_ID,
3609
+ "list",
3610
+ {
3611
+ ...options?.limit !== void 0 ? { limit: options.limit } : {},
3612
+ ...options?.scheduleIds ? { scheduleIds: options.scheduleIds } : {}
3613
+ }
3614
+ )).schedules,
3615
+ cancel: async (scheduleId) => {
3616
+ await invokeEntityOp(bridge, SCHEDULED_INVOCATIONS_ENTITY_ID, "cancel", { scheduleId });
3617
+ }
3618
+ }),
3619
+ [bridge]
3620
+ );
3621
+ }
3622
+ function useFiasLinkedIn() {
3623
+ const bridge = useBridge();
3624
+ return useMemo2(
3625
+ () => ({
3626
+ publishPost: (params) => invokeEntityOp(
3627
+ bridge,
3628
+ LINKEDIN_ENTITY_ID,
3629
+ "publish_post",
3630
+ { ...params }
3631
+ ),
3632
+ searchOrganizations: async (connectionId, vanityName) => (await invokeEntityOp(
3633
+ bridge,
3634
+ LINKEDIN_ENTITY_ID,
3635
+ "search_organizations",
3636
+ { connectionId, query: vanityName }
3637
+ )).organizations
3638
+ }),
3639
+ [bridge]
3640
+ );
3641
+ }
2987
3642
  function useCompanyEmail() {
2988
3643
  const bridge = useBridge();
2989
3644
  const send = useCallback(
@@ -3227,6 +3882,8 @@ var AUDIO_VOICE_DESIGN_SURFACE_KEY = "audio.voice-design";
3227
3882
  var useElevenLabsVoiceDesign = () => useSurface(
3228
3883
  AUDIO_VOICE_DESIGN_SURFACE_KEY
3229
3884
  );
3885
+ var IMAGE_CREATE_ASSET_SURFACE_KEY = "image.create-asset";
3886
+ var useCreateAsset = () => useSurface(IMAGE_CREATE_ASSET_SURFACE_KEY);
3230
3887
  var IMAGE_SMART_CONTROL_SURFACE_KEY = "image.smart-control";
3231
3888
  var useSmartControl = () => useSurface(IMAGE_SMART_CONTROL_SURFACE_KEY);
3232
3889
  var IMAGE_SMART_ERASE_SURFACE_KEY = "image.smart-erase";
@@ -3270,6 +3927,7 @@ var VALID_PLUGIN_PERMISSIONS = [
3270
3927
  "assets:community:publish",
3271
3928
  "assets:community:read",
3272
3929
  "assets:read",
3930
+ "connections:use",
3273
3931
  "data:agents",
3274
3932
  "data:search",
3275
3933
  "data:store",
@@ -3282,14 +3940,18 @@ var VALID_PLUGIN_PERMISSIONS = [
3282
3940
  "entities:image_generate",
3283
3941
  "entities:invoke",
3284
3942
  "entities:web_search",
3943
+ "litcraft:hub",
3285
3944
  "navigation:open_arche",
3286
3945
  "sandbox:vendored-libraries",
3946
+ "schedule:invoke",
3287
3947
  "storage:local",
3288
3948
  "storage:sandbox",
3289
3949
  "store:purchase",
3290
3950
  "theme:read",
3291
3951
  "user:profile:read",
3292
3952
  "vault:arche-saves:write",
3953
+ "vault:creative:read",
3954
+ "vault:creative:write",
3293
3955
  "vault:documents:read",
3294
3956
  "vault:documents:write",
3295
3957
  "vault:user-documents:edit",
@@ -3305,6 +3967,7 @@ var PLUGIN_PERMISSION_DESCRIPTIONS = {
3305
3967
  "assets:community:publish": "Share images you made here so other people using this arche can see them, and manage what you have shared.",
3306
3968
  "assets:community:read": "Show you images that other people using this arche have shared. Everything shared is checked before anyone can see it.",
3307
3969
  "assets:read": "Show images and play sounds from this arche's published asset library.",
3970
+ "connections:use": "Use outside accounts (like X or LinkedIn) that you connect and let it use \u2014 you choose each account and each workspace, approve what it posts, and can take access away any time in Workspace Controls.",
3308
3971
  "data:agents": "Let Fias AI, and assistants you connect with an API key and allow here, read this arche's data \u2014 and change it where it says so \u2014 even while it is closed.",
3309
3972
  "data:search": "Search this arche's own data semantically \u2014 costs credits per search.",
3310
3973
  "data:store": "Save structured data in this arche's own private database.",
@@ -3317,14 +3980,18 @@ var PLUGIN_PERMISSION_DESCRIPTIONS = {
3317
3980
  "entities:image_generate": "Generate images with platform AI \u2014 costs credits.",
3318
3981
  "entities:invoke": "Use platform AI (text) on your behalf \u2014 costs credits.",
3319
3982
  "entities:web_search": "Search the live web on your behalf \u2014 costs credits.",
3983
+ "litcraft:hub": "See your LitCraft profile, stats and inventory, and the LitCraft community leaderboards, play time and activity. It can hide your name on leaderboards, but only you can show it again.",
3320
3984
  "navigation:open_arche": "Open other arches for you (navigation only).",
3321
3985
  "sandbox:vendored-libraries": "Load platform-hosted libraries (like the PDF renderer) from the trusted CDN.",
3986
+ "schedule:invoke": "Schedule an action for later \u2014 like a post at 9 AM tomorrow. You approve exactly what will be sent and when, and can see or cancel what it scheduled.",
3322
3987
  "storage:local": "Keep its working files on this device, so a refresh or crash does not lose your work. Nothing leaves your device; cleared when you sign out or when someone else signs in here.",
3323
3988
  "storage:sandbox": "Save files in this arche's own private storage.",
3324
3989
  "store:purchase": "Offer purchases inside the arche (you approve each purchase).",
3325
3990
  "theme:read": "Match your platform theme.",
3326
3991
  "user:profile:read": "See your display name and avatar.",
3327
3992
  "vault:arche-saves:write": "Saves files to your Arche Saves automatically.",
3993
+ "vault:creative:read": "See and use your styles and characters, including their reference pictures \u2014 in a team workspace only after its owner or admin approves it there.",
3994
+ "vault:creative:write": "Create and change your styles and characters. Earlier versions are kept.",
3328
3995
  "vault:documents:read": "Read files this arche itself created, in its own folders of your Vault.",
3329
3996
  "vault:documents:write": "Create and manage its own files, in its own folder of your Vault.",
3330
3997
  "vault:user-documents:edit": "Save changes to files of yours that you let it edit \u2014 you choose each file, earlier versions are kept unless you turned version history off, and you can remove access any time in Vault \u2192 Arche Access.",
@@ -5416,6 +6083,63 @@ function useFiasFonts() {
5416
6083
  return useMemo3(() => ({ fonts: FONT_CATALOG, ensureFontLoaded }), []);
5417
6084
  }
5418
6085
 
6086
+ // src/limits.ts
6087
+ var X_PUBLISH_LIMITS = {
6088
+ MAX_TEXT_CHARACTERS: 25e3,
6089
+ MAX_IMAGES_PER_POST: 4,
6090
+ MAX_IMAGES_PER_PUBLISH: 4,
6091
+ MAX_THREAD_POSTS: 10,
6092
+ MIN_POLL_OPTIONS: 2,
6093
+ MAX_POLL_OPTIONS: 4,
6094
+ MAX_POLL_OPTION_CHARACTERS: 25,
6095
+ MIN_POLL_MINUTES: 5,
6096
+ MAX_POLL_MINUTES: 10080,
6097
+ IMAGE_MIME_TYPES: ["image/png", "image/jpeg", "image/webp", "image/gif"],
6098
+ MAX_IMAGE_BYTES: 5 * 1024 * 1024
6099
+ };
6100
+ var LINKEDIN_PUBLISH_LIMITS = {
6101
+ MAX_TEXT_CHARACTERS: 3e3,
6102
+ MAX_IMAGES: 9,
6103
+ IMAGE_MIME_TYPES: ["image/png", "image/jpeg", "image/gif"],
6104
+ MAX_IMAGE_BYTES: 8 * 1024 * 1024
6105
+ };
6106
+ var SCHEDULE_LIMITS = {
6107
+ /** Waiting at once, per person, per app. */
6108
+ MAX_ACTIVE_PER_USER_ARCHE: 25,
6109
+ /** The earliest a call may be scheduled, from now. */
6110
+ MIN_LEAD_SECONDS: 5 * 60,
6111
+ /** The latest, from now. */
6112
+ MAX_LEAD_DAYS: 60
6113
+ };
6114
+ var DATA_STORE_LIMITS = {
6115
+ /** One document's `data`, serialized. */
6116
+ MAX_DOCUMENT_SIZE_BYTES: 100 * 1024,
6117
+ /** Per owner — one user, one workspace, or the app's shared data — per collection. */
6118
+ MAX_DOCUMENTS_PER_OWNER_PER_COLLECTION: 1e4,
6119
+ /** Writes in one atomic `batch`. */
6120
+ MAX_BATCH_OPERATIONS: 100
6121
+ };
6122
+ var DATA_STORE_RATE_LIMITS_PER_MINUTE = {
6123
+ put: 120,
6124
+ get: 300,
6125
+ query: 60,
6126
+ delete: 60,
6127
+ /** Counted in units of 25 operations: a full 100-op batch is 4. */
6128
+ batch: 30
6129
+ };
6130
+ var FIAS_AI_MANIFEST_LIMITS = {
6131
+ MAX_ACTIONS: 30,
6132
+ MAX_ID_LENGTH: 100,
6133
+ MAX_DESCRIPTION_LENGTH: 1e3,
6134
+ MAX_CATEGORY_LENGTH: 100,
6135
+ MAX_BLOCK_DESCRIPTION_LENGTH: 2e3,
6136
+ MAX_PARAMETER_SCHEMA_BYTES: 4096,
6137
+ MAX_AVAILABLE_WHEN_KEYS: 8,
6138
+ MAX_AVAILABLE_WHEN_KEY_LENGTH: 64,
6139
+ MAX_AVAILABLE_WHEN_STRING_LENGTH: 100,
6140
+ MAX_BLOCK_SERIALIZED_BYTES: 32 * 1024
6141
+ };
6142
+
5419
6143
  // src/panels.ts
5420
6144
  var PANEL_MIN_ELEMENTS = 1;
5421
6145
  var PANEL_MAX_ELEMENTS = 24;
@@ -5823,8 +6547,11 @@ export {
5823
6547
  AUDIO_VOICE_DESIGN_SURFACE_KEY,
5824
6548
  ArcheAssetError,
5825
6549
  DARK_THEME,
6550
+ DATA_STORE_LIMITS,
6551
+ DATA_STORE_RATE_LIMITS_PER_MINUTE,
5826
6552
  ENTITY_INVOCATION_HISTORY_LIMITS,
5827
6553
  ENTITY_INVOCATION_REQUEST_LIMITS,
6554
+ FIAS_AI_MANIFEST_LIMITS,
5828
6555
  FONT_CATALOG,
5829
6556
  FONT_PAIRINGS,
5830
6557
  FiasBridge,
@@ -5833,6 +6560,7 @@ export {
5833
6560
  FiasLocalStoreError,
5834
6561
  FiasProvider,
5835
6562
  GRAMMAR_CHECK_ENTITY_ID,
6563
+ IMAGE_CREATE_ASSET_SURFACE_KEY,
5836
6564
  IMAGE_SMART_CONTROL_SURFACE_KEY,
5837
6565
  IMAGE_SMART_ERASE_SURFACE_KEY,
5838
6566
  IMAGE_SMART_IMAGE_TO_IMAGE_SURFACE_KEY,
@@ -5846,6 +6574,8 @@ export {
5846
6574
  IMAGE_SMART_VECTORIZE_SURFACE_KEY,
5847
6575
  INTEGRATION_WEB_SEARCH_SURFACE_KEY,
5848
6576
  LIGHT_THEME,
6577
+ LINKEDIN_ENTITY_ID,
6578
+ LINKEDIN_PUBLISH_LIMITS,
5849
6579
  NLLB_LANGUAGES,
5850
6580
  NLLB_TRANSLATION_ENTITY_ID,
5851
6581
  PANEL_BUTTON_LABEL_MAX_LENGTH,
@@ -5867,10 +6597,13 @@ export {
5867
6597
  PLUGIN_LOCAL_STORE_ENTITY_ID,
5868
6598
  PLUGIN_PERMISSION_DESCRIPTIONS,
5869
6599
  REASONING_EFFORTS,
6600
+ SCHEDULE_LIMITS,
5870
6601
  SDK_BRIDGE_PROTOCOL_VERSION,
5871
6602
  SDK_REQUIRES_HOST_PROTOCOL_VERSION,
5872
6603
  THEME_CATALOG,
5873
6604
  VALID_PLUGIN_PERMISSIONS,
6605
+ X_ENTITY_ID,
6606
+ X_PUBLISH_LIMITS,
5874
6607
  checkInvocationHistory,
5875
6608
  checkInvocationRequestSize,
5876
6609
  checkReasoningParameter,
@@ -5892,6 +6625,8 @@ export {
5892
6625
  useClientEntity,
5893
6626
  useCommunityAssets,
5894
6627
  useCompanyEmail,
6628
+ useCreateAsset,
6629
+ useCreativeLibrary,
5895
6630
  useDataSubscription,
5896
6631
  useDocumentSign,
5897
6632
  useElevenLabsAudioIsolation,
@@ -5903,18 +6638,26 @@ export {
5903
6638
  useElevenLabsVoiceChanger,
5904
6639
  useElevenLabsVoiceDesign,
5905
6640
  useEntityInvocation,
6641
+ useEntitySubscription,
5906
6642
  useFiasAIActions,
6643
+ useFiasAccess,
6644
+ useFiasChrome,
6645
+ useFiasConnections,
5907
6646
  useFiasContent,
5908
6647
  useFiasDataStore,
5909
6648
  useFiasFonts,
6649
+ useFiasHolder,
6650
+ useFiasLinkedIn,
5910
6651
  useFiasNavigation,
5911
6652
  useFiasPreviewState,
6653
+ useFiasSchedules,
5912
6654
  useFiasStorage,
5913
6655
  useFiasStore,
5914
6656
  useFiasTheme,
5915
6657
  useFiasUser,
5916
6658
  useFiasVendoredAssets,
5917
6659
  useFiasWorkspaces,
6660
+ useFiasX,
5918
6661
  useGeminiTranscribe,
5919
6662
  useGeminiTts,
5920
6663
  useImageEntities,