@arbidocs/blocks 0.4.71 → 0.4.73

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 (179) hide show
  1. package/dist/agents/index.cjs +404 -266
  2. package/dist/agents/index.js +10 -8
  3. package/dist/agents/tasks/TaskActivityTimeline.d.ts +1 -1
  4. package/dist/agents/tasks/WorkflowThreadStrip.d.ts +58 -0
  5. package/dist/agents/tasks/index.d.ts +1 -0
  6. package/dist/agents/workflows/WorkflowRunner.d.ts +70 -0
  7. package/dist/agents/workflows/index.d.ts +7 -1
  8. package/dist/agents/workflows/planSteps.d.ts +28 -0
  9. package/dist/agents/workflows/run.d.ts +97 -0
  10. package/dist/agents/workflows/skillMarkdown.d.ts +15 -0
  11. package/dist/agents/workflows/types.d.ts +109 -0
  12. package/dist/agents/workflows/useWorkflowPreview.d.ts +14 -0
  13. package/dist/agents/workflows/useWorkflowView.d.ts +54 -0
  14. package/dist/agents/workflows/workflow.d.ts +3 -1
  15. package/dist/calendar/CalendarGrid.d.ts +2 -0
  16. package/dist/calendar/CalendarList.d.ts +2 -0
  17. package/dist/calendar/CalendarSettingsForm.d.ts +2 -0
  18. package/dist/calendar/EventDetails.d.ts +2 -0
  19. package/dist/calendar/EventEditor.d.ts +2 -0
  20. package/dist/calendar/MiniMonth.d.ts +2 -0
  21. package/dist/calendar/RecurrenceEditor.d.ts +13 -0
  22. package/dist/calendar/RoomFinder.d.ts +2 -0
  23. package/dist/calendar/SchedulingAssistant.d.ts +2 -0
  24. package/dist/calendar/ScopeDialog.d.ts +2 -0
  25. package/dist/calendar/TimeZonePicker.d.ts +2 -0
  26. package/dist/calendar/colors.d.ts +4 -0
  27. package/dist/calendar/draft.d.ts +43 -0
  28. package/dist/calendar/format.d.ts +14 -0
  29. package/dist/calendar/grid-model.d.ts +24 -0
  30. package/dist/calendar/index.cjs +4122 -0
  31. package/dist/calendar/index.cjs.map +1 -0
  32. package/dist/calendar/index.d.ts +30 -0
  33. package/dist/calendar/index.js +4043 -0
  34. package/dist/calendar/index.js.map +1 -0
  35. package/dist/calendar/labels.d.ts +4 -0
  36. package/dist/calendar/recurrence-labels.d.ts +22 -0
  37. package/dist/calendar/recurrence.d.ts +66 -0
  38. package/dist/calendar/reminders.d.ts +26 -0
  39. package/dist/calendar/scheduling.d.ts +27 -0
  40. package/dist/calendar/types.d.ts +605 -0
  41. package/dist/calendar/ui.d.ts +16 -0
  42. package/dist/calendar/zone.d.ts +56 -0
  43. package/dist/chat/index.cjs +123 -123
  44. package/dist/chat/index.js +3 -3
  45. package/dist/chunk-2P3T23C7.js +1250 -0
  46. package/dist/chunk-2P3T23C7.js.map +1 -0
  47. package/dist/{chunk-XNRGCQPZ.cjs → chunk-3SFFTSOI.cjs} +5 -5
  48. package/dist/{chunk-XNRGCQPZ.cjs.map → chunk-3SFFTSOI.cjs.map} +1 -1
  49. package/dist/{chunk-7WM62NMM.cjs → chunk-6OL5S7MJ.cjs} +5 -2
  50. package/dist/chunk-6OL5S7MJ.cjs.map +1 -0
  51. package/dist/chunk-7D737FLE.cjs +43 -0
  52. package/dist/chunk-7D737FLE.cjs.map +1 -0
  53. package/dist/{chunk-VUEZARW5.cjs → chunk-B3WCKBJ7.cjs} +278 -5
  54. package/dist/chunk-B3WCKBJ7.cjs.map +1 -0
  55. package/dist/{chunk-L5UPP2HC.js → chunk-D46ZAPEE.js} +5 -2
  56. package/dist/chunk-D46ZAPEE.js.map +1 -0
  57. package/dist/{chunk-LFGJAZ5H.js → chunk-DDF5GPIJ.js} +6 -36
  58. package/dist/chunk-DDF5GPIJ.js.map +1 -0
  59. package/dist/chunk-DETZZBG2.cjs +91 -0
  60. package/dist/chunk-DETZZBG2.cjs.map +1 -0
  61. package/dist/chunk-EVUEIBNU.js +89 -0
  62. package/dist/chunk-EVUEIBNU.js.map +1 -0
  63. package/dist/{chunk-CXWESDIZ.cjs → chunk-F4RUCUXF.cjs} +6 -6
  64. package/dist/{chunk-CXWESDIZ.cjs.map → chunk-F4RUCUXF.cjs.map} +1 -1
  65. package/dist/{chunk-DABEWNL2.js → chunk-G5DP27DU.js} +3 -3
  66. package/dist/{chunk-DABEWNL2.js.map → chunk-G5DP27DU.js.map} +1 -1
  67. package/dist/{chunk-VZGBCBYB.js → chunk-GJV2G4FC.js} +276 -7
  68. package/dist/chunk-GJV2G4FC.js.map +1 -0
  69. package/dist/chunk-GTNUQBXI.cjs +1296 -0
  70. package/dist/chunk-GTNUQBXI.cjs.map +1 -0
  71. package/dist/{chunk-7M22KND4.cjs → chunk-IUR565UW.cjs} +303 -530
  72. package/dist/chunk-IUR565UW.cjs.map +1 -0
  73. package/dist/{chunk-5DM6VU4L.cjs → chunk-KJ3QEKOJ.cjs} +3 -3
  74. package/dist/{chunk-5DM6VU4L.cjs.map → chunk-KJ3QEKOJ.cjs.map} +1 -1
  75. package/dist/{chunk-THO7DZNN.cjs → chunk-MUMH3Z6K.cjs} +20 -15
  76. package/dist/chunk-MUMH3Z6K.cjs.map +1 -0
  77. package/dist/{chunk-3TVTG7FK.js → chunk-ORA2XE7U.js} +4 -4
  78. package/dist/{chunk-3TVTG7FK.js.map → chunk-ORA2XE7U.js.map} +1 -1
  79. package/dist/{chunk-5HOAOKZL.js → chunk-OYMWV45N.js} +21 -16
  80. package/dist/chunk-OYMWV45N.js.map +1 -0
  81. package/dist/{chunk-HLMFU7L2.js → chunk-QDNXEB3T.js} +272 -488
  82. package/dist/chunk-QDNXEB3T.js.map +1 -0
  83. package/dist/{chunk-ILGHS6ZV.js → chunk-SB5ZKOYN.js} +3 -3
  84. package/dist/{chunk-ILGHS6ZV.js.map → chunk-SB5ZKOYN.js.map} +1 -1
  85. package/dist/{chunk-CPMNAJLF.js → chunk-TX2ZICS7.js} +24 -4
  86. package/dist/chunk-TX2ZICS7.js.map +1 -0
  87. package/dist/{chunk-2ZTONLT5.cjs → chunk-ULWRNGGE.cjs} +25 -4
  88. package/dist/chunk-ULWRNGGE.cjs.map +1 -0
  89. package/dist/{chunk-BMWZTNZB.js → chunk-VRPRAU3J.js} +3 -3
  90. package/dist/{chunk-BMWZTNZB.js.map → chunk-VRPRAU3J.js.map} +1 -1
  91. package/dist/{chunk-LTA2IAQB.cjs → chunk-WOYUXVVQ.cjs} +8 -8
  92. package/dist/{chunk-LTA2IAQB.cjs.map → chunk-WOYUXVVQ.cjs.map} +1 -1
  93. package/dist/chunk-XD2M6LIG.js +41 -0
  94. package/dist/chunk-XD2M6LIG.js.map +1 -0
  95. package/dist/{chunk-WBDK4PIA.cjs → chunk-Z5VUZ6YD.cjs} +6 -37
  96. package/dist/chunk-Z5VUZ6YD.cjs.map +1 -0
  97. package/dist/collaboration/index.cjs +44 -45
  98. package/dist/collaboration/index.js +2 -3
  99. package/dist/connect/docx.cjs +2 -2
  100. package/dist/connect/docx.js +1 -1
  101. package/dist/connect/index.cjs +370 -48
  102. package/dist/connect/index.cjs.map +1 -1
  103. package/dist/connect/index.d.ts +2 -1
  104. package/dist/connect/index.js +331 -12
  105. package/dist/connect/index.js.map +1 -1
  106. package/dist/connection/ConnectedSettings.d.ts +13 -0
  107. package/dist/connection/ConnectedWorkflowBuilder.d.ts +44 -0
  108. package/dist/connection/ConnectedWorkflowRunner.d.ts +27 -0
  109. package/dist/connection/useWorkflowThread.d.ts +34 -0
  110. package/dist/document-tools/index.cjs +4 -5
  111. package/dist/document-tools/index.cjs.map +1 -1
  112. package/dist/document-tools/index.js +1 -2
  113. package/dist/document-tools/index.js.map +1 -1
  114. package/dist/facts/index.cjs +1 -1
  115. package/dist/facts/index.js +1 -1
  116. package/dist/files/import/index.d.ts +0 -1
  117. package/dist/files/index.cjs +31 -169
  118. package/dist/files/index.cjs.map +1 -1
  119. package/dist/files/index.js +8 -147
  120. package/dist/files/index.js.map +1 -1
  121. package/dist/home/index.cjs +21 -20
  122. package/dist/home/index.cjs.map +1 -1
  123. package/dist/home/index.js +3 -2
  124. package/dist/home/index.js.map +1 -1
  125. package/dist/index.cjs +680 -542
  126. package/dist/index.cjs.map +1 -1
  127. package/dist/index.js +15 -13
  128. package/dist/index.js.map +1 -1
  129. package/dist/settings/Billing.d.ts +4 -0
  130. package/dist/settings/IdentityVerification.d.ts +83 -0
  131. package/dist/settings/PlanBadge.d.ts +2 -2
  132. package/dist/settings/PlanCard.d.ts +6 -1
  133. package/dist/settings/ProfileCard.d.ts +5 -1
  134. package/dist/settings/SubscriptionParts.d.ts +6 -2
  135. package/dist/settings/index.cjs +128 -95
  136. package/dist/settings/index.cjs.map +1 -1
  137. package/dist/settings/index.d.ts +1 -0
  138. package/dist/settings/index.js +64 -47
  139. package/dist/settings/index.js.map +1 -1
  140. package/dist/shell/ActionCluster.d.ts +3 -1
  141. package/dist/shell/index.cjs +54 -54
  142. package/dist/shell/index.js +2 -2
  143. package/dist/studio/index.cjs +6 -6
  144. package/dist/studio/index.js +4 -4
  145. package/dist/workflow-canvas/StepInspector.d.ts +46 -0
  146. package/dist/workflow-canvas/TriggerInspector.d.ts +46 -0
  147. package/dist/workflow-canvas/WorkflowBuilder.d.ts +55 -0
  148. package/dist/workflow-canvas/WorkflowCanvas.d.ts +65 -0
  149. package/dist/workflow-canvas/edit.d.ts +54 -0
  150. package/dist/workflow-canvas/index.cjs +1609 -0
  151. package/dist/workflow-canvas/index.cjs.map +1 -0
  152. package/dist/workflow-canvas/index.d.ts +13 -0
  153. package/dist/workflow-canvas/index.js +1579 -0
  154. package/dist/workflow-canvas/index.js.map +1 -0
  155. package/dist/workflow-canvas/trigger.d.ts +51 -0
  156. package/dist/workspaces/index.cjs +2 -3
  157. package/dist/workspaces/index.cjs.map +1 -1
  158. package/dist/workspaces/index.js +1 -2
  159. package/dist/workspaces/index.js.map +1 -1
  160. package/package.json +41 -12
  161. package/src/calendar/calendar.css +316 -0
  162. package/src/workflow-canvas/canvas.css +113 -0
  163. package/dist/chunk-2ZTONLT5.cjs.map +0 -1
  164. package/dist/chunk-5HOAOKZL.js.map +0 -1
  165. package/dist/chunk-7M22KND4.cjs.map +0 -1
  166. package/dist/chunk-7WM62NMM.cjs.map +0 -1
  167. package/dist/chunk-CPMNAJLF.js.map +0 -1
  168. package/dist/chunk-DCDVWPMB.cjs +0 -29
  169. package/dist/chunk-DCDVWPMB.cjs.map +0 -1
  170. package/dist/chunk-HLMFU7L2.js.map +0 -1
  171. package/dist/chunk-L5UPP2HC.js.map +0 -1
  172. package/dist/chunk-LFGJAZ5H.js.map +0 -1
  173. package/dist/chunk-THO7DZNN.cjs.map +0 -1
  174. package/dist/chunk-TJMKFY5P.js +0 -27
  175. package/dist/chunk-TJMKFY5P.js.map +0 -1
  176. package/dist/chunk-VUEZARW5.cjs.map +0 -1
  177. package/dist/chunk-VZGBCBYB.js.map +0 -1
  178. package/dist/chunk-WBDK4PIA.cjs.map +0 -1
  179. package/dist/files/import/CalendarImportRow.d.ts +0 -26
@@ -57,7 +57,12 @@ function ConnectionProvider({
57
57
  isLiveConfigured ? "connecting" : "disconnected"
58
58
  );
59
59
  const [user, setUser] = react.useState(null);
60
- const [workspaceId, setWorkspaceId] = react.useState(null);
60
+ const [workspaceId, setWorkspaceIdState] = react.useState(null);
61
+ const workspaceIdRef = react.useRef(null);
62
+ const selectWorkspaceId = react.useCallback((id) => {
63
+ workspaceIdRef.current = id;
64
+ setWorkspaceIdState(id);
65
+ }, []);
61
66
  const [mode, setMode] = react.useState("demo");
62
67
  const [error, setError] = react.useState(null);
63
68
  const storageUserRef = react.useRef(null);
@@ -66,11 +71,11 @@ function ConnectionProvider({
66
71
  rememberSessionUser(config.apiUrl, null);
67
72
  storageUserRef.current = null;
68
73
  setUser(null);
69
- setWorkspaceId(null);
74
+ selectWorkspaceId(null);
70
75
  setStatus("disconnected");
71
76
  setError(SESSION_EXPIRED_MESSAGE);
72
77
  }),
73
- [arbi, config.apiUrl]
78
+ [arbi, config.apiUrl, selectWorkspaceId]
74
79
  );
75
80
  react.useEffect(
76
81
  () => arbi.user.onProfileChange?.(
@@ -83,8 +88,8 @@ function ConnectionProvider({
83
88
  setStatus("demo");
84
89
  setError(null);
85
90
  setUser({ name: config.demoUser.name, email: config.demoUser.email });
86
- setWorkspaceId(demoWorkspaceId);
87
- }, [config.demoUser.name, config.demoUser.email, demoWorkspaceId]);
91
+ selectWorkspaceId(demoWorkspaceId);
92
+ }, [config.demoUser.name, config.demoUser.email, demoWorkspaceId, selectWorkspaceId]);
88
93
  const login = react.useCallback(
89
94
  async (email, password, restoring = false) => {
90
95
  setError(null);
@@ -109,7 +114,7 @@ function ConnectionProvider({
109
114
  const preferred = persisted ?? config.workspaceId;
110
115
  const target = (preferred ? workspaces.find((w) => w.external_id === preferred) : void 0) ?? workspaces[0];
111
116
  await arbi.selectWorkspace(target.external_id);
112
- setWorkspaceId(target.external_id);
117
+ selectWorkspaceId(target.external_id);
113
118
  persistWorkspace(config.apiUrl, storageUserRef.current, target.external_id);
114
119
  }
115
120
  let resolved = { name: email.split("@")[0], email };
@@ -143,7 +148,7 @@ function ConnectionProvider({
143
148
  setStatus("error");
144
149
  }
145
150
  },
146
- [arbi, enterDemo, isLiveConfigured, config.workspaceId, config.apiUrl]
151
+ [arbi, enterDemo, isLiveConfigured, config.workspaceId, config.apiUrl, selectWorkspaceId]
147
152
  );
148
153
  const recoveryStarted = react.useRef(false);
149
154
  react.useEffect(() => {
@@ -163,27 +168,27 @@ function ConnectionProvider({
163
168
  void arbi.logout?.();
164
169
  }
165
170
  setUser(null);
166
- setWorkspaceId(null);
171
+ selectWorkspaceId(null);
167
172
  persistWorkspace(config.apiUrl, storageUserRef.current, null);
168
173
  storageUserRef.current = null;
169
174
  setStatus("disconnected");
170
175
  setError(null);
171
- }, [arbi, mode, config.apiUrl]);
176
+ }, [arbi, mode, config.apiUrl, selectWorkspaceId]);
172
177
  const setWorkspace = react.useCallback(
173
178
  async (id) => {
174
179
  if (mode === "live" && arbi.isLoggedIn) {
175
180
  await arbi.selectWorkspace(id);
176
181
  }
177
- setWorkspaceId(id);
182
+ selectWorkspaceId(id);
178
183
  persistWorkspace(config.apiUrl, storageUserRef.current, id);
179
184
  },
180
- [arbi, mode, config.apiUrl]
185
+ [arbi, mode, config.apiUrl, selectWorkspaceId]
181
186
  );
182
187
  const ensureWorkspaceOpen = react.useCallback(async () => {
183
188
  if (mode !== "live" || !arbi.isLoggedIn) return;
184
- const id = workspaceId ?? readPersistedWorkspace(config.apiUrl, storageUserRef.current) ?? config.workspaceId;
189
+ const id = workspaceIdRef.current ?? readPersistedWorkspace(config.apiUrl, storageUserRef.current) ?? config.workspaceId;
185
190
  if (id) await arbi.selectWorkspace(id);
186
- }, [arbi, mode, workspaceId, config.apiUrl, config.workspaceId]);
191
+ }, [arbi, mode, config.apiUrl, config.workspaceId]);
187
192
  const value = react.useMemo(
188
193
  () => ({
189
194
  mode,
@@ -233,5 +238,5 @@ exports.ConnectionProvider = ConnectionProvider;
233
238
  exports.SESSION_EXPIRED_MESSAGE = SESSION_EXPIRED_MESSAGE;
234
239
  exports.isAuthenticated = isAuthenticated;
235
240
  exports.useConnection = useConnection;
236
- //# sourceMappingURL=chunk-THO7DZNN.cjs.map
237
- //# sourceMappingURL=chunk-THO7DZNN.cjs.map
241
+ //# sourceMappingURL=chunk-MUMH3Z6K.cjs.map
242
+ //# sourceMappingURL=chunk-MUMH3Z6K.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/connection/ConnectionProvider.tsx"],"names":["createContext","useArbi","useState","useRef","useCallback","useEffect","useMemo","jsx","useContext"],"mappings":"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","file":"chunk-MUMH3Z6K.cjs","sourcesContent":["/**\n * The demo/live connection layer for a host app. Holds auth + workspace\n * selection state and exposes it via {@link useConnection}, so every surface\n * works identically whether it's talking to a live ARBI backend or the seeded\n * demo workspace. Host-specific values (backend URL, demo identity, default\n * workspace/assistant ids) arrive once through {@link ArbiConnectionConfig}.\n */\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react'\nimport { useArbi, type LoginProfile } from '@arbidocs/react'\nimport type { ArbiMode, ArbiUser, ConnectionStatus, ArbiConnectionConfig } from './types'\n\ninterface ConnectionValue {\n mode: ArbiMode\n status: ConnectionStatus\n user: ArbiUser | null\n workspaceId: string | null\n apiConfigured: boolean\n apiUrl: string\n /**\n * The deployment domain the user's keys are derived for (`arbi.getDeploymentDomain()`), for the\n * document tools' e-signing. `undefined` in demo mode.\n */\n deploymentDomain: string | undefined\n error: string | null\n /** Default assistant config ext_id (for the AI hooks). */\n assistantConfig?: string\n /** Fallback workspace ext_id when none is actively selected. */\n fallbackWorkspaceId?: string\n /** Authenticate. Live login when a backend is configured, otherwise the demo workspace. */\n login: (email: string, password: string) => Promise<void>\n /** One-click demo entry (no backend required). */\n enterDemo: () => void\n logout: () => void\n /**\n * Affirmatively select a workspace: opens it on the server (via the SDK),\n * updates the app-wide state, and persists the choice so it survives future\n * logins. This is the single entry point for \"the user is now in workspace X\".\n */\n setWorkspace: (id: string) => Promise<void>\n /**\n * Re-assert the selected workspace on the server session (idempotent `/open`).\n * Call before a workspace-scoped write when the session may have lost its open\n * workspace (token re-login, backend restart, session expiry) — the server\n * resolves the workspace from the session, so a dropped `/open` yields\n * \"No active workspace\" until it's re-opened.\n */\n ensureWorkspaceOpen: () => Promise<void>\n}\n\nconst ConnectionContext = createContext<ConnectionValue | null>(null)\n\n/**\n * Persist the affirmatively-selected workspace per backend AND per signed-in user, so a returning\n * user lands back in the workspace they last chose, while the next person on a shared browser\n * never starts from someone else's workspace id. Namespaced by apiUrl so distinct deployments\n * (and the demo workspace) don't clobber each other. Cleared on logout.\n */\nconst WORKSPACE_STORAGE_PREFIX = 'arbi:selectedWorkspace'\nconst sessionUserKey = (apiUrl: string) => `arbi:sessionUser:${apiUrl}`\nfunction rememberSessionUser(apiUrl: string, email: string | null) {\n try {\n if (email) window.localStorage.setItem(sessionUserKey(apiUrl), normalizeUserKey(email))\n else window.localStorage.removeItem(sessionUserKey(apiUrl))\n } catch {\n /* Storage may be unavailable. */\n }\n}\nconst normalizeUserKey = (email: string) => email.trim().toLowerCase()\n\n/** Exported for tests. */\nexport const workspaceStorageKey = (apiUrl: string, userKey: string) =>\n `${WORKSPACE_STORAGE_PREFIX}:${apiUrl || 'demo'}:${normalizeUserKey(userKey)}`\n\n/** The pre-isolation key (apiUrl only). Never read: removed so it cannot leak across users. */\nconst legacyWorkspaceStorageKey = (apiUrl: string) =>\n `${WORKSPACE_STORAGE_PREFIX}:${apiUrl || 'demo'}`\n\nfunction readPersistedWorkspace(apiUrl: string, userKey: string | null): string | null {\n if (!userKey) return null\n try {\n return window.localStorage.getItem(workspaceStorageKey(apiUrl, userKey))\n } catch {\n return null\n }\n}\n\nfunction persistWorkspace(apiUrl: string, userKey: string | null, id: string | null): void {\n if (!userKey) return\n try {\n if (id) window.localStorage.setItem(workspaceStorageKey(apiUrl, userKey), id)\n else window.localStorage.removeItem(workspaceStorageKey(apiUrl, userKey))\n window.localStorage.removeItem(legacyWorkspaceStorageKey(apiUrl))\n } catch {\n // Storage unavailable (private mode, SSR) — selection stays in-memory only.\n }\n}\n\n/** Shown on the sign-in screen after the session could not be recovered. */\nexport const SESSION_EXPIRED_MESSAGE = 'Your session expired. Sign in again.'\n\n/** The connection user for a profile: its full name, falling back to the email local part. */\nfunction userFromProfile(profile: LoginProfile, externalId?: string): ArbiUser {\n const fullName = [profile.givenName, profile.familyName]\n .map((part) => part?.trim())\n .filter(Boolean)\n .join(' ')\n return {\n name: fullName || profile.email.split('@')[0],\n email: profile.email,\n externalId,\n picture: profile.picture,\n }\n}\n\nexport function ConnectionProvider({\n config,\n children,\n}: {\n config: ArbiConnectionConfig\n children: ReactNode\n}) {\n const arbi = useArbi()\n const isLiveConfigured = config.apiUrl.length > 0\n const demoWorkspaceId = config.demoWorkspaceId ?? 'demo-workspace'\n\n const [status, setStatus] = useState<ConnectionStatus>(\n isLiveConfigured ? 'connecting' : 'disconnected'\n )\n const [user, setUser] = useState<ArbiUser | null>(null)\n const [workspaceId, setWorkspaceIdState] = useState<string | null>(null)\n // The selected workspace as of now, not as of the last render: a flow that switches workspace\n // and then re-opens it in the same async chain (a step that creates a matter, then starts its\n // thread) must not re-open the one it just left.\n const workspaceIdRef = useRef<string | null>(null)\n const selectWorkspaceId = useCallback((id: string | null) => {\n workspaceIdRef.current = id\n setWorkspaceIdState(id)\n }, [])\n const [mode, setMode] = useState<ArbiMode>('demo')\n const [error, setError] = useState<string | null>(null)\n // Who the persisted workspace belongs to; set at sign-in, cleared at logout.\n const storageUserRef = useRef<string | null>(null)\n\n // The SDK could not recover the session (token refused, workspace not re-openable): drop to\n // 'disconnected' with a plain message, so the host's gate sends the user to sign in instead of\n // every call failing with a raw backend error. The remembered workspace is kept for next login.\n useEffect(\n () =>\n arbi.onSessionExpired?.(() => {\n rememberSessionUser(config.apiUrl, null)\n storageUserRef.current = null\n setUser(null)\n selectWorkspaceId(null)\n setStatus('disconnected')\n setError(SESSION_EXPIRED_MESSAGE)\n }),\n [arbi, config.apiUrl, selectWorkspaceId]\n )\n\n // A saved name, picture or email reaches every surface reading `useConnection().user`.\n useEffect(\n () =>\n arbi.user.onProfileChange?.((profile) =>\n setUser((current) => (current ? userFromProfile(profile, current.externalId) : current))\n ),\n [arbi]\n )\n\n const enterDemo = useCallback(() => {\n setMode('demo')\n setStatus('demo')\n setError(null)\n setUser({ name: config.demoUser.name, email: config.demoUser.email })\n selectWorkspaceId(demoWorkspaceId)\n }, [config.demoUser.name, config.demoUser.email, demoWorkspaceId, selectWorkspaceId])\n\n const login = useCallback(\n async (email: string, password: string, restoring = false) => {\n setError(null)\n // No backend configured → run the seeded demo workspace.\n if (!isLiveConfigured) {\n enterDemo()\n return\n }\n setStatus('connecting')\n setMode('live')\n try {\n if (restoring) {\n if (!(await arbi.restoreSession(email))) {\n rememberSessionUser(config.apiUrl, null)\n setStatus('disconnected')\n return\n }\n } else await arbi.login(email, password)\n storageUserRef.current = normalizeUserKey(email)\n const workspaces = await arbi.workspaces.list()\n if (workspaces?.length) {\n // Prefer the workspace the user last affirmatively selected (persisted),\n // then the configured workspace (there may be several — e.g. a\n // marketing/KM workspace), then whichever happens to be first. Ternary\n // (not `&&`) so an empty value can't leak `\"\"` into `target`.\n const persisted = readPersistedWorkspace(config.apiUrl, storageUserRef.current)\n const preferred = persisted ?? config.workspaceId\n const target =\n (preferred ? workspaces.find((w) => w.external_id === preferred) : undefined) ??\n workspaces[0]\n await arbi.selectWorkspace(target.external_id)\n selectWorkspaceId(target.external_id)\n persistWorkspace(config.apiUrl, storageUserRef.current, target.external_id)\n }\n // The profile (name + avatar) comes with the login response. A session restored without\n // a login has none, so fall back to finding ourselves in the workspace roster; the email\n // local part is only the last resort, never the answer when a profile name exists.\n let resolved: ArbiUser = { name: email.split('@')[0], email }\n const me = arbi.user.identity()\n const profile = arbi.user.profile?.()\n if (profile) {\n resolved = userFromProfile(profile, me?.externalId)\n } else {\n try {\n const members = await arbi.workspaces.listUsers()\n const self = members.find((m) => m.user.external_id === me?.externalId)?.user\n if (self) {\n const fullName = [self.given_name, self.family_name].filter(Boolean).join(' ').trim()\n resolved = {\n name: fullName || email.split('@')[0],\n email: self.email || email,\n externalId: self.external_id,\n picture: self.picture ?? null,\n }\n } else if (me?.externalId) {\n resolved.externalId = me.externalId\n }\n } catch {\n // Roster not available (e.g. no workspace) — keep the fallback identity.\n }\n }\n setUser(resolved)\n rememberSessionUser(config.apiUrl, email)\n setStatus('authenticated')\n } catch (e) {\n // Surface the real error — no silent fallback to a fake session.\n setError(e instanceof Error ? e.message : 'Sign-in failed. Check your credentials.')\n setStatus('error')\n }\n },\n [arbi, enterDemo, isLiveConfigured, config.workspaceId, config.apiUrl, selectWorkspaceId]\n )\n\n // Run once even under StrictMode; passwords and signing keys are never stored here.\n const recoveryStarted = useRef(false)\n useEffect(() => {\n if (recoveryStarted.current || !isLiveConfigured) return\n recoveryStarted.current = true\n let email: string | null = null\n try {\n email = window.localStorage.getItem(sessionUserKey(config.apiUrl))\n } catch {\n /* unavailable */\n }\n if (email) void login(email, '', true)\n else setStatus('disconnected')\n }, [isLiveConfigured, config.apiUrl, login])\n\n const logout = useCallback(() => {\n rememberSessionUser(config.apiUrl, null)\n if (mode === 'live') {\n void arbi.logout?.()\n }\n setUser(null)\n selectWorkspaceId(null)\n persistWorkspace(config.apiUrl, storageUserRef.current, null)\n storageUserRef.current = null\n setStatus('disconnected')\n setError(null)\n }, [arbi, mode, config.apiUrl, selectWorkspaceId])\n\n // Affirmative selection: open the workspace on the server (live), then remember\n // it in state + storage so every surface — and the next login — is in sync.\n const setWorkspace = useCallback(\n async (id: string) => {\n if (mode === 'live' && arbi.isLoggedIn) {\n await arbi.selectWorkspace(id)\n }\n selectWorkspaceId(id)\n persistWorkspace(config.apiUrl, storageUserRef.current, id)\n },\n [arbi, mode, config.apiUrl, selectWorkspaceId]\n )\n\n // Re-open the selected workspace on the session if the server may have dropped\n // it. Idempotent: re-running `/open` for the already-selected workspace is safe.\n const ensureWorkspaceOpen = useCallback(async () => {\n if (mode !== 'live' || !arbi.isLoggedIn) return\n const id =\n workspaceIdRef.current ??\n readPersistedWorkspace(config.apiUrl, storageUserRef.current) ??\n config.workspaceId\n if (id) await arbi.selectWorkspace(id)\n }, [arbi, mode, config.apiUrl, config.workspaceId])\n\n const value = useMemo<ConnectionValue>(\n () => ({\n mode,\n status,\n user,\n workspaceId,\n apiConfigured: isLiveConfigured,\n apiUrl: config.apiUrl,\n deploymentDomain: isLiveConfigured ? arbi.getDeploymentDomain() : undefined,\n error,\n assistantConfig: config.assistantConfig,\n fallbackWorkspaceId: config.workspaceId,\n login,\n enterDemo,\n logout,\n setWorkspace,\n ensureWorkspaceOpen,\n }),\n [\n mode,\n status,\n user,\n workspaceId,\n isLiveConfigured,\n config.apiUrl,\n arbi,\n config.assistantConfig,\n config.workspaceId,\n error,\n login,\n enterDemo,\n logout,\n setWorkspace,\n ensureWorkspaceOpen,\n ]\n )\n\n return <ConnectionContext.Provider value={value}>{children}</ConnectionContext.Provider>\n}\n\nexport function useConnection(): ConnectionValue {\n const ctx = useContext(ConnectionContext)\n if (!ctx) throw new Error('useConnection must be used within ConnectionProvider')\n return ctx\n}\n\nexport const isAuthenticated = (s: ConnectionStatus) => s === 'demo' || s === 'authenticated'\n"]}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { AssistantDock } from './chunk-DABEWNL2.js';
3
- import { useConnection } from './chunk-5HOAOKZL.js';
2
+ import { useConnection } from './chunk-OYMWV45N.js';
3
+ import { AssistantDock } from './chunk-G5DP27DU.js';
4
4
  import { useCallback } from 'react';
5
5
  import { useAiTask, useWorkspaceDocs as useWorkspaceDocs$1, useSemanticSearch as useSemanticSearch$1, useWorkspaceUsers, useArbiChat } from '@arbidocs/react';
6
6
  export { redlineStats, textToArtifact, toRedlineMarkdown } from '@arbidocs/react';
@@ -64,5 +64,5 @@ function ConnectedAssistantDock(props) {
64
64
  }
65
65
 
66
66
  export { ConnectedAssistantDock, useConnectedAiTask, useConnectedChat, useSemanticSearch, useWorkspaceDocs };
67
- //# sourceMappingURL=chunk-3TVTG7FK.js.map
68
- //# sourceMappingURL=chunk-3TVTG7FK.js.map
67
+ //# sourceMappingURL=chunk-ORA2XE7U.js.map
68
+ //# sourceMappingURL=chunk-ORA2XE7U.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/connection/ai.tsx"],"names":["useKitAiTask","useKitWorkspaceDocs","useKitSemanticSearch"],"mappings":"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","file":"chunk-3TVTG7FK.js","sourcesContent":["/**\n * The connected agent hooks — thin adapters over the reusable AI kit in\n * `@arbidocs/react`. The streaming/accumulation/search plumbing lives once in\n * the SDK; these hooks only bind the *workspace source* (from the connection\n * context, falling back to the configured workspace) and inject the host's\n * default assistant *configuration* so call sites needn't know the config\n * ext_id. An explicit `opts.model` still wins.\n */\nimport { useCallback } from 'react'\nimport {\n useAiTask as useKitAiTask,\n useWorkspaceDocs as useKitWorkspaceDocs,\n useSemanticSearch as useKitSemanticSearch,\n useArbiChat,\n useWorkspaceUsers,\n type ArbiChat,\n type UseArbiChatOptions,\n type AiRunOptions,\n} from '@arbidocs/react'\nimport { useConnection } from './ConnectionProvider'\nimport { AssistantDock, type AssistantDockProps } from '../chat/AssistantDock'\nimport type { MentionCandidate } from '../chat/mentions'\n\nexport type { AiTaskStatus, AiRunOptions, SearchChunk, ArtifactEvent } from '@arbidocs/react'\n\n/** Client-side redlining, re-exported so a host app has one import surface. */\nexport { toRedlineMarkdown, redlineStats, textToArtifact } from '@arbidocs/react'\n\n/**\n * The kit's `useAiTask` with the host's default assistant configuration\n * injected, so call sites needn't know the config ext_id.\n */\nexport function useConnectedAiTask() {\n const { assistantConfig } = useConnection()\n const task = useKitAiTask()\n const kitRun = task.run\n const run = useCallback(\n (question: string, docIds: string[], opts?: AiRunOptions) =>\n kitRun(question, docIds, { ...opts, model: opts?.model ?? assistantConfig }),\n [kitRun, assistantConfig]\n )\n return { ...task, run }\n}\n\n/** Resolve the active workspace + its document ids (what we ground the agent on). */\nexport function useWorkspaceDocs() {\n const { workspaceId, fallbackWorkspaceId } = useConnection()\n return useKitWorkspaceDocs(workspaceId ?? fallbackWorkspaceId)\n}\n\n/** Search the active workspace's documents and return the top matching passages. */\nexport function useSemanticSearch() {\n const { docIds } = useWorkspaceDocs()\n return useKitSemanticSearch(docIds)\n}\n\n/**\n * The chat controller for `ChatPage` bound to the connection: the active workspace and the host's\n * default assistant configuration are injected, so a host writes\n * `<ChatPage chat={useConnectedChat()} />`.\n */\nexport function useConnectedChat(\n options?: Omit<UseArbiChatOptions, 'workspaceId'>\n): ArbiChat & { mentionCandidates: MentionCandidate[] } {\n const { workspaceId, fallbackWorkspaceId, assistantConfig, user, status, ensureWorkspaceOpen } =\n useConnection()\n const wsId = workspaceId ?? fallbackWorkspaceId\n const { data: members = [] } = useWorkspaceUsers(wsId, {\n enabled: status === 'authenticated' && !!wsId,\n beforeFetch: ensureWorkspaceOpen,\n })\n const mentionCandidates: MentionCandidate[] = [\n { id: 'assistant', kind: 'assistant', label: 'Assistant' },\n ...(status === 'authenticated' ? members : [])\n .filter(\n (member) =>\n !member.agent_ext_id &&\n member.user.external_id !== user?.externalId &&\n !member.user.external_id.startsWith('agt-')\n )\n .map((member) => ({\n id: member.user.external_id,\n kind: 'user' as const,\n label:\n [member.user.given_name, member.user.family_name].filter(Boolean).join(' ') ||\n member.user.email,\n description: member.user.email,\n }))\n .sort((a, b) => a.label.localeCompare(b.label)),\n ]\n const chat = useArbiChat({\n ...options,\n workspaceId: workspaceId ?? fallbackWorkspaceId,\n model: options?.model ?? assistantConfig,\n })\n return {\n ...chat,\n mentionCandidates,\n messages: chat.messages.map((message) => ({\n ...message,\n ...(message.authorId\n ? {\n senderName:\n message.authorId === user?.externalId\n ? user?.name || user?.email\n : mentionCandidates.find((candidate) => candidate.id === message.authorId)?.label,\n }\n : {}),\n })),\n }\n}\n\n/**\n * The assistant dock bound to the connection: mount it once in the layout (`Shell.Root`'s `aside`)\n * and put `AssistantDockToggle` in the topbar. Chat state lives here, so it survives closing the dock.\n */\nexport function ConnectedAssistantDock(props: Omit<AssistantDockProps, 'chat'>) {\n const chat = useConnectedChat()\n return <AssistantDock {...props} chat={chat} />\n}\n"]}
1
+ {"version":3,"sources":["../src/connection/ai.tsx"],"names":["useKitAiTask","useKitWorkspaceDocs","useKitSemanticSearch"],"mappings":"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","file":"chunk-ORA2XE7U.js","sourcesContent":["/**\n * The connected agent hooks — thin adapters over the reusable AI kit in\n * `@arbidocs/react`. The streaming/accumulation/search plumbing lives once in\n * the SDK; these hooks only bind the *workspace source* (from the connection\n * context, falling back to the configured workspace) and inject the host's\n * default assistant *configuration* so call sites needn't know the config\n * ext_id. An explicit `opts.model` still wins.\n */\nimport { useCallback } from 'react'\nimport {\n useAiTask as useKitAiTask,\n useWorkspaceDocs as useKitWorkspaceDocs,\n useSemanticSearch as useKitSemanticSearch,\n useArbiChat,\n useWorkspaceUsers,\n type ArbiChat,\n type UseArbiChatOptions,\n type AiRunOptions,\n} from '@arbidocs/react'\nimport { useConnection } from './ConnectionProvider'\nimport { AssistantDock, type AssistantDockProps } from '../chat/AssistantDock'\nimport type { MentionCandidate } from '../chat/mentions'\n\nexport type { AiTaskStatus, AiRunOptions, SearchChunk, ArtifactEvent } from '@arbidocs/react'\n\n/** Client-side redlining, re-exported so a host app has one import surface. */\nexport { toRedlineMarkdown, redlineStats, textToArtifact } from '@arbidocs/react'\n\n/**\n * The kit's `useAiTask` with the host's default assistant configuration\n * injected, so call sites needn't know the config ext_id.\n */\nexport function useConnectedAiTask() {\n const { assistantConfig } = useConnection()\n const task = useKitAiTask()\n const kitRun = task.run\n const run = useCallback(\n (question: string, docIds: string[], opts?: AiRunOptions) =>\n kitRun(question, docIds, { ...opts, model: opts?.model ?? assistantConfig }),\n [kitRun, assistantConfig]\n )\n return { ...task, run }\n}\n\n/** Resolve the active workspace + its document ids (what we ground the agent on). */\nexport function useWorkspaceDocs() {\n const { workspaceId, fallbackWorkspaceId } = useConnection()\n return useKitWorkspaceDocs(workspaceId ?? fallbackWorkspaceId)\n}\n\n/** Search the active workspace's documents and return the top matching passages. */\nexport function useSemanticSearch() {\n const { docIds } = useWorkspaceDocs()\n return useKitSemanticSearch(docIds)\n}\n\n/**\n * The chat controller for `ChatPage` bound to the connection: the active workspace and the host's\n * default assistant configuration are injected, so a host writes\n * `<ChatPage chat={useConnectedChat()} />`.\n */\nexport function useConnectedChat(\n options?: Omit<UseArbiChatOptions, 'workspaceId'>\n): ArbiChat & { mentionCandidates: MentionCandidate[] } {\n const { workspaceId, fallbackWorkspaceId, assistantConfig, user, status, ensureWorkspaceOpen } =\n useConnection()\n const wsId = workspaceId ?? fallbackWorkspaceId\n const { data: members = [] } = useWorkspaceUsers(wsId, {\n enabled: status === 'authenticated' && !!wsId,\n beforeFetch: ensureWorkspaceOpen,\n })\n const mentionCandidates: MentionCandidate[] = [\n { id: 'assistant', kind: 'assistant', label: 'Assistant' },\n ...(status === 'authenticated' ? members : [])\n .filter(\n (member) =>\n !member.agent_ext_id &&\n member.user.external_id !== user?.externalId &&\n !member.user.external_id.startsWith('agt-')\n )\n .map((member) => ({\n id: member.user.external_id,\n kind: 'user' as const,\n label:\n [member.user.given_name, member.user.family_name].filter(Boolean).join(' ') ||\n member.user.email,\n description: member.user.email,\n }))\n .sort((a, b) => a.label.localeCompare(b.label)),\n ]\n const chat = useArbiChat({\n ...options,\n workspaceId: workspaceId ?? fallbackWorkspaceId,\n model: options?.model ?? assistantConfig,\n })\n return {\n ...chat,\n mentionCandidates,\n messages: chat.messages.map((message) => ({\n ...message,\n ...(message.authorId\n ? {\n senderName:\n message.authorId === user?.externalId\n ? user?.name || user?.email\n : mentionCandidates.find((candidate) => candidate.id === message.authorId)?.label,\n }\n : {}),\n })),\n }\n}\n\n/**\n * The assistant dock bound to the connection: mount it once in the layout (`Shell.Root`'s `aside`)\n * and put `AssistantDockToggle` in the topbar. Chat state lives here, so it survives closing the dock.\n */\nexport function ConnectedAssistantDock(props: Omit<AssistantDockProps, 'chat'>) {\n const chat = useConnectedChat()\n return <AssistantDock {...props} chat={chat} />\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { createContext, useState, useRef, useEffect, useCallback, useMemo, useContext } from 'react';
2
+ import { createContext, useState, useRef, useCallback, useEffect, useMemo, useContext } from 'react';
3
3
  import { useArbi } from '@arbidocs/react';
4
4
  import { jsx } from 'react/jsx-runtime';
5
5
 
@@ -55,7 +55,12 @@ function ConnectionProvider({
55
55
  isLiveConfigured ? "connecting" : "disconnected"
56
56
  );
57
57
  const [user, setUser] = useState(null);
58
- const [workspaceId, setWorkspaceId] = useState(null);
58
+ const [workspaceId, setWorkspaceIdState] = useState(null);
59
+ const workspaceIdRef = useRef(null);
60
+ const selectWorkspaceId = useCallback((id) => {
61
+ workspaceIdRef.current = id;
62
+ setWorkspaceIdState(id);
63
+ }, []);
59
64
  const [mode, setMode] = useState("demo");
60
65
  const [error, setError] = useState(null);
61
66
  const storageUserRef = useRef(null);
@@ -64,11 +69,11 @@ function ConnectionProvider({
64
69
  rememberSessionUser(config.apiUrl, null);
65
70
  storageUserRef.current = null;
66
71
  setUser(null);
67
- setWorkspaceId(null);
72
+ selectWorkspaceId(null);
68
73
  setStatus("disconnected");
69
74
  setError(SESSION_EXPIRED_MESSAGE);
70
75
  }),
71
- [arbi, config.apiUrl]
76
+ [arbi, config.apiUrl, selectWorkspaceId]
72
77
  );
73
78
  useEffect(
74
79
  () => arbi.user.onProfileChange?.(
@@ -81,8 +86,8 @@ function ConnectionProvider({
81
86
  setStatus("demo");
82
87
  setError(null);
83
88
  setUser({ name: config.demoUser.name, email: config.demoUser.email });
84
- setWorkspaceId(demoWorkspaceId);
85
- }, [config.demoUser.name, config.demoUser.email, demoWorkspaceId]);
89
+ selectWorkspaceId(demoWorkspaceId);
90
+ }, [config.demoUser.name, config.demoUser.email, demoWorkspaceId, selectWorkspaceId]);
86
91
  const login = useCallback(
87
92
  async (email, password, restoring = false) => {
88
93
  setError(null);
@@ -107,7 +112,7 @@ function ConnectionProvider({
107
112
  const preferred = persisted ?? config.workspaceId;
108
113
  const target = (preferred ? workspaces.find((w) => w.external_id === preferred) : void 0) ?? workspaces[0];
109
114
  await arbi.selectWorkspace(target.external_id);
110
- setWorkspaceId(target.external_id);
115
+ selectWorkspaceId(target.external_id);
111
116
  persistWorkspace(config.apiUrl, storageUserRef.current, target.external_id);
112
117
  }
113
118
  let resolved = { name: email.split("@")[0], email };
@@ -141,7 +146,7 @@ function ConnectionProvider({
141
146
  setStatus("error");
142
147
  }
143
148
  },
144
- [arbi, enterDemo, isLiveConfigured, config.workspaceId, config.apiUrl]
149
+ [arbi, enterDemo, isLiveConfigured, config.workspaceId, config.apiUrl, selectWorkspaceId]
145
150
  );
146
151
  const recoveryStarted = useRef(false);
147
152
  useEffect(() => {
@@ -161,27 +166,27 @@ function ConnectionProvider({
161
166
  void arbi.logout?.();
162
167
  }
163
168
  setUser(null);
164
- setWorkspaceId(null);
169
+ selectWorkspaceId(null);
165
170
  persistWorkspace(config.apiUrl, storageUserRef.current, null);
166
171
  storageUserRef.current = null;
167
172
  setStatus("disconnected");
168
173
  setError(null);
169
- }, [arbi, mode, config.apiUrl]);
174
+ }, [arbi, mode, config.apiUrl, selectWorkspaceId]);
170
175
  const setWorkspace = useCallback(
171
176
  async (id) => {
172
177
  if (mode === "live" && arbi.isLoggedIn) {
173
178
  await arbi.selectWorkspace(id);
174
179
  }
175
- setWorkspaceId(id);
180
+ selectWorkspaceId(id);
176
181
  persistWorkspace(config.apiUrl, storageUserRef.current, id);
177
182
  },
178
- [arbi, mode, config.apiUrl]
183
+ [arbi, mode, config.apiUrl, selectWorkspaceId]
179
184
  );
180
185
  const ensureWorkspaceOpen = useCallback(async () => {
181
186
  if (mode !== "live" || !arbi.isLoggedIn) return;
182
- const id = workspaceId ?? readPersistedWorkspace(config.apiUrl, storageUserRef.current) ?? config.workspaceId;
187
+ const id = workspaceIdRef.current ?? readPersistedWorkspace(config.apiUrl, storageUserRef.current) ?? config.workspaceId;
183
188
  if (id) await arbi.selectWorkspace(id);
184
- }, [arbi, mode, workspaceId, config.apiUrl, config.workspaceId]);
189
+ }, [arbi, mode, config.apiUrl, config.workspaceId]);
185
190
  const value = useMemo(
186
191
  () => ({
187
192
  mode,
@@ -228,5 +233,5 @@ function useConnection() {
228
233
  var isAuthenticated = (s) => s === "demo" || s === "authenticated";
229
234
 
230
235
  export { ConnectionProvider, SESSION_EXPIRED_MESSAGE, isAuthenticated, useConnection };
231
- //# sourceMappingURL=chunk-5HOAOKZL.js.map
232
- //# sourceMappingURL=chunk-5HOAOKZL.js.map
236
+ //# sourceMappingURL=chunk-OYMWV45N.js.map
237
+ //# sourceMappingURL=chunk-OYMWV45N.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/connection/ConnectionProvider.tsx"],"names":[],"mappings":"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","file":"chunk-OYMWV45N.js","sourcesContent":["/**\n * The demo/live connection layer for a host app. Holds auth + workspace\n * selection state and exposes it via {@link useConnection}, so every surface\n * works identically whether it's talking to a live ARBI backend or the seeded\n * demo workspace. Host-specific values (backend URL, demo identity, default\n * workspace/assistant ids) arrive once through {@link ArbiConnectionConfig}.\n */\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react'\nimport { useArbi, type LoginProfile } from '@arbidocs/react'\nimport type { ArbiMode, ArbiUser, ConnectionStatus, ArbiConnectionConfig } from './types'\n\ninterface ConnectionValue {\n mode: ArbiMode\n status: ConnectionStatus\n user: ArbiUser | null\n workspaceId: string | null\n apiConfigured: boolean\n apiUrl: string\n /**\n * The deployment domain the user's keys are derived for (`arbi.getDeploymentDomain()`), for the\n * document tools' e-signing. `undefined` in demo mode.\n */\n deploymentDomain: string | undefined\n error: string | null\n /** Default assistant config ext_id (for the AI hooks). */\n assistantConfig?: string\n /** Fallback workspace ext_id when none is actively selected. */\n fallbackWorkspaceId?: string\n /** Authenticate. Live login when a backend is configured, otherwise the demo workspace. */\n login: (email: string, password: string) => Promise<void>\n /** One-click demo entry (no backend required). */\n enterDemo: () => void\n logout: () => void\n /**\n * Affirmatively select a workspace: opens it on the server (via the SDK),\n * updates the app-wide state, and persists the choice so it survives future\n * logins. This is the single entry point for \"the user is now in workspace X\".\n */\n setWorkspace: (id: string) => Promise<void>\n /**\n * Re-assert the selected workspace on the server session (idempotent `/open`).\n * Call before a workspace-scoped write when the session may have lost its open\n * workspace (token re-login, backend restart, session expiry) — the server\n * resolves the workspace from the session, so a dropped `/open` yields\n * \"No active workspace\" until it's re-opened.\n */\n ensureWorkspaceOpen: () => Promise<void>\n}\n\nconst ConnectionContext = createContext<ConnectionValue | null>(null)\n\n/**\n * Persist the affirmatively-selected workspace per backend AND per signed-in user, so a returning\n * user lands back in the workspace they last chose, while the next person on a shared browser\n * never starts from someone else's workspace id. Namespaced by apiUrl so distinct deployments\n * (and the demo workspace) don't clobber each other. Cleared on logout.\n */\nconst WORKSPACE_STORAGE_PREFIX = 'arbi:selectedWorkspace'\nconst sessionUserKey = (apiUrl: string) => `arbi:sessionUser:${apiUrl}`\nfunction rememberSessionUser(apiUrl: string, email: string | null) {\n try {\n if (email) window.localStorage.setItem(sessionUserKey(apiUrl), normalizeUserKey(email))\n else window.localStorage.removeItem(sessionUserKey(apiUrl))\n } catch {\n /* Storage may be unavailable. */\n }\n}\nconst normalizeUserKey = (email: string) => email.trim().toLowerCase()\n\n/** Exported for tests. */\nexport const workspaceStorageKey = (apiUrl: string, userKey: string) =>\n `${WORKSPACE_STORAGE_PREFIX}:${apiUrl || 'demo'}:${normalizeUserKey(userKey)}`\n\n/** The pre-isolation key (apiUrl only). Never read: removed so it cannot leak across users. */\nconst legacyWorkspaceStorageKey = (apiUrl: string) =>\n `${WORKSPACE_STORAGE_PREFIX}:${apiUrl || 'demo'}`\n\nfunction readPersistedWorkspace(apiUrl: string, userKey: string | null): string | null {\n if (!userKey) return null\n try {\n return window.localStorage.getItem(workspaceStorageKey(apiUrl, userKey))\n } catch {\n return null\n }\n}\n\nfunction persistWorkspace(apiUrl: string, userKey: string | null, id: string | null): void {\n if (!userKey) return\n try {\n if (id) window.localStorage.setItem(workspaceStorageKey(apiUrl, userKey), id)\n else window.localStorage.removeItem(workspaceStorageKey(apiUrl, userKey))\n window.localStorage.removeItem(legacyWorkspaceStorageKey(apiUrl))\n } catch {\n // Storage unavailable (private mode, SSR) — selection stays in-memory only.\n }\n}\n\n/** Shown on the sign-in screen after the session could not be recovered. */\nexport const SESSION_EXPIRED_MESSAGE = 'Your session expired. Sign in again.'\n\n/** The connection user for a profile: its full name, falling back to the email local part. */\nfunction userFromProfile(profile: LoginProfile, externalId?: string): ArbiUser {\n const fullName = [profile.givenName, profile.familyName]\n .map((part) => part?.trim())\n .filter(Boolean)\n .join(' ')\n return {\n name: fullName || profile.email.split('@')[0],\n email: profile.email,\n externalId,\n picture: profile.picture,\n }\n}\n\nexport function ConnectionProvider({\n config,\n children,\n}: {\n config: ArbiConnectionConfig\n children: ReactNode\n}) {\n const arbi = useArbi()\n const isLiveConfigured = config.apiUrl.length > 0\n const demoWorkspaceId = config.demoWorkspaceId ?? 'demo-workspace'\n\n const [status, setStatus] = useState<ConnectionStatus>(\n isLiveConfigured ? 'connecting' : 'disconnected'\n )\n const [user, setUser] = useState<ArbiUser | null>(null)\n const [workspaceId, setWorkspaceIdState] = useState<string | null>(null)\n // The selected workspace as of now, not as of the last render: a flow that switches workspace\n // and then re-opens it in the same async chain (a step that creates a matter, then starts its\n // thread) must not re-open the one it just left.\n const workspaceIdRef = useRef<string | null>(null)\n const selectWorkspaceId = useCallback((id: string | null) => {\n workspaceIdRef.current = id\n setWorkspaceIdState(id)\n }, [])\n const [mode, setMode] = useState<ArbiMode>('demo')\n const [error, setError] = useState<string | null>(null)\n // Who the persisted workspace belongs to; set at sign-in, cleared at logout.\n const storageUserRef = useRef<string | null>(null)\n\n // The SDK could not recover the session (token refused, workspace not re-openable): drop to\n // 'disconnected' with a plain message, so the host's gate sends the user to sign in instead of\n // every call failing with a raw backend error. The remembered workspace is kept for next login.\n useEffect(\n () =>\n arbi.onSessionExpired?.(() => {\n rememberSessionUser(config.apiUrl, null)\n storageUserRef.current = null\n setUser(null)\n selectWorkspaceId(null)\n setStatus('disconnected')\n setError(SESSION_EXPIRED_MESSAGE)\n }),\n [arbi, config.apiUrl, selectWorkspaceId]\n )\n\n // A saved name, picture or email reaches every surface reading `useConnection().user`.\n useEffect(\n () =>\n arbi.user.onProfileChange?.((profile) =>\n setUser((current) => (current ? userFromProfile(profile, current.externalId) : current))\n ),\n [arbi]\n )\n\n const enterDemo = useCallback(() => {\n setMode('demo')\n setStatus('demo')\n setError(null)\n setUser({ name: config.demoUser.name, email: config.demoUser.email })\n selectWorkspaceId(demoWorkspaceId)\n }, [config.demoUser.name, config.demoUser.email, demoWorkspaceId, selectWorkspaceId])\n\n const login = useCallback(\n async (email: string, password: string, restoring = false) => {\n setError(null)\n // No backend configured → run the seeded demo workspace.\n if (!isLiveConfigured) {\n enterDemo()\n return\n }\n setStatus('connecting')\n setMode('live')\n try {\n if (restoring) {\n if (!(await arbi.restoreSession(email))) {\n rememberSessionUser(config.apiUrl, null)\n setStatus('disconnected')\n return\n }\n } else await arbi.login(email, password)\n storageUserRef.current = normalizeUserKey(email)\n const workspaces = await arbi.workspaces.list()\n if (workspaces?.length) {\n // Prefer the workspace the user last affirmatively selected (persisted),\n // then the configured workspace (there may be several — e.g. a\n // marketing/KM workspace), then whichever happens to be first. Ternary\n // (not `&&`) so an empty value can't leak `\"\"` into `target`.\n const persisted = readPersistedWorkspace(config.apiUrl, storageUserRef.current)\n const preferred = persisted ?? config.workspaceId\n const target =\n (preferred ? workspaces.find((w) => w.external_id === preferred) : undefined) ??\n workspaces[0]\n await arbi.selectWorkspace(target.external_id)\n selectWorkspaceId(target.external_id)\n persistWorkspace(config.apiUrl, storageUserRef.current, target.external_id)\n }\n // The profile (name + avatar) comes with the login response. A session restored without\n // a login has none, so fall back to finding ourselves in the workspace roster; the email\n // local part is only the last resort, never the answer when a profile name exists.\n let resolved: ArbiUser = { name: email.split('@')[0], email }\n const me = arbi.user.identity()\n const profile = arbi.user.profile?.()\n if (profile) {\n resolved = userFromProfile(profile, me?.externalId)\n } else {\n try {\n const members = await arbi.workspaces.listUsers()\n const self = members.find((m) => m.user.external_id === me?.externalId)?.user\n if (self) {\n const fullName = [self.given_name, self.family_name].filter(Boolean).join(' ').trim()\n resolved = {\n name: fullName || email.split('@')[0],\n email: self.email || email,\n externalId: self.external_id,\n picture: self.picture ?? null,\n }\n } else if (me?.externalId) {\n resolved.externalId = me.externalId\n }\n } catch {\n // Roster not available (e.g. no workspace) — keep the fallback identity.\n }\n }\n setUser(resolved)\n rememberSessionUser(config.apiUrl, email)\n setStatus('authenticated')\n } catch (e) {\n // Surface the real error — no silent fallback to a fake session.\n setError(e instanceof Error ? e.message : 'Sign-in failed. Check your credentials.')\n setStatus('error')\n }\n },\n [arbi, enterDemo, isLiveConfigured, config.workspaceId, config.apiUrl, selectWorkspaceId]\n )\n\n // Run once even under StrictMode; passwords and signing keys are never stored here.\n const recoveryStarted = useRef(false)\n useEffect(() => {\n if (recoveryStarted.current || !isLiveConfigured) return\n recoveryStarted.current = true\n let email: string | null = null\n try {\n email = window.localStorage.getItem(sessionUserKey(config.apiUrl))\n } catch {\n /* unavailable */\n }\n if (email) void login(email, '', true)\n else setStatus('disconnected')\n }, [isLiveConfigured, config.apiUrl, login])\n\n const logout = useCallback(() => {\n rememberSessionUser(config.apiUrl, null)\n if (mode === 'live') {\n void arbi.logout?.()\n }\n setUser(null)\n selectWorkspaceId(null)\n persistWorkspace(config.apiUrl, storageUserRef.current, null)\n storageUserRef.current = null\n setStatus('disconnected')\n setError(null)\n }, [arbi, mode, config.apiUrl, selectWorkspaceId])\n\n // Affirmative selection: open the workspace on the server (live), then remember\n // it in state + storage so every surface — and the next login — is in sync.\n const setWorkspace = useCallback(\n async (id: string) => {\n if (mode === 'live' && arbi.isLoggedIn) {\n await arbi.selectWorkspace(id)\n }\n selectWorkspaceId(id)\n persistWorkspace(config.apiUrl, storageUserRef.current, id)\n },\n [arbi, mode, config.apiUrl, selectWorkspaceId]\n )\n\n // Re-open the selected workspace on the session if the server may have dropped\n // it. Idempotent: re-running `/open` for the already-selected workspace is safe.\n const ensureWorkspaceOpen = useCallback(async () => {\n if (mode !== 'live' || !arbi.isLoggedIn) return\n const id =\n workspaceIdRef.current ??\n readPersistedWorkspace(config.apiUrl, storageUserRef.current) ??\n config.workspaceId\n if (id) await arbi.selectWorkspace(id)\n }, [arbi, mode, config.apiUrl, config.workspaceId])\n\n const value = useMemo<ConnectionValue>(\n () => ({\n mode,\n status,\n user,\n workspaceId,\n apiConfigured: isLiveConfigured,\n apiUrl: config.apiUrl,\n deploymentDomain: isLiveConfigured ? arbi.getDeploymentDomain() : undefined,\n error,\n assistantConfig: config.assistantConfig,\n fallbackWorkspaceId: config.workspaceId,\n login,\n enterDemo,\n logout,\n setWorkspace,\n ensureWorkspaceOpen,\n }),\n [\n mode,\n status,\n user,\n workspaceId,\n isLiveConfigured,\n config.apiUrl,\n arbi,\n config.assistantConfig,\n config.workspaceId,\n error,\n login,\n enterDemo,\n logout,\n setWorkspace,\n ensureWorkspaceOpen,\n ]\n )\n\n return <ConnectionContext.Provider value={value}>{children}</ConnectionContext.Provider>\n}\n\nexport function useConnection(): ConnectionValue {\n const ctx = useContext(ConnectionContext)\n if (!ctx) throw new Error('useConnection must be used within ConnectionProvider')\n return ctx\n}\n\nexport const isAuthenticated = (s: ConnectionStatus) => s === 'demo' || s === 'authenticated'\n"]}