@arbidocs/client 0.4.166 → 0.4.168

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -3563,6 +3563,12 @@ interface paths {
3563
3563
  /**
3564
3564
  * Cancel Response
3565
3565
  * @description Stop an owned response while preserving its agent login and sandbox.
3566
+ *
3567
+ * The stop is the person's decision and is stored whatever state the run is in. The run is cancelled here when
3568
+ * it runs on this process, else through the ``cancel_response`` broadcast, and a stop marker lets its heartbeat
3569
+ * pick the stop up if the broadcast never reached it. When the run does not confirm within ``STOP_CONFIRM_S``
3570
+ * (its process is not servicing its event loop, or is gone) the endpoint stores the turn ``cancelled`` itself,
3571
+ * so a reload never shows the stopped turn generating again.
3566
3572
  */
3567
3573
  post: operations['cancel_response'];
3568
3574
  delete?: never;
@@ -4998,7 +5004,9 @@ interface paths {
4998
5004
  * webinar, on stage (403 ``not_on_stage``).
4999
5005
  * * ``composite``: the host's view, host only, ``audio_video`` recordings only (422 ``composite_needs_video``).
5000
5006
  *
5001
- * 409 ``recording_stopped`` once the recording has stopped.
5007
+ * A new track is taken while recording and for the stop's grace window (409 ``recording_stopped`` later), like the
5008
+ * parts: the in-flight tail of someone whose first part comes at the stop (a recording shorter than one part, or
5009
+ * a speaker who started in its last part) belongs to the recording.
5002
5010
  */
5003
5011
  post: operations['create_call_recording_track'];
5004
5012
  delete?: never;
@@ -5047,7 +5055,9 @@ interface paths {
5047
5055
  * @description Commit an uploaded part: the object must exist (409 ``part_not_uploaded``) and be no larger than declared
5048
5056
  * plus a small tolerance (422 ``size_mismatch``: the object is deleted; presign and PUT again). The stored size is
5049
5057
  * recorded and counts towards the project's storage from now on. Committing a committed part returns it. 404 for
5050
- * an undeclared ``seq``; 409 ``recording_stopped`` after the stop's grace window.
5058
+ * an undeclared ``seq``; 409 ``recording_stopped`` after the stop's grace window. A part committed after the stop
5059
+ * (the tail) is announced to the room audience, WS ``call.recording_updated {call_ext_id, recording_ext_id}``, so
5060
+ * the Recording cards already shown re-read the recording.
5051
5061
  */
5052
5062
  post: operations['commit_call_recording_part'];
5053
5063
  delete?: never;
@@ -8090,7 +8100,8 @@ interface components {
8090
8100
  * session_pubkey_b64 (optional): If set, the grant is temporary and scoped to the
8091
8101
  * recipient's current session (identified by this X25519 public key). The workspace
8092
8102
  * key is stored in that session's Redis entry and the workspaceusers row expires when
8093
- * the session expires. Omit for a permanent grant (default behaviour).
8103
+ * the session expires. Omit for a permanent grant for paid recipients. External
8104
+ * recipients always receive a Redis-backed grant of at most 24 hours.
8094
8105
  *
8095
8106
  * confirm_invite (default False): an email that isn't a registered user is never
8096
8107
  * invited on a call with this unset — it's silently left out of the response (same
@@ -8125,8 +8136,12 @@ interface components {
8125
8136
  workspace_ext_id?: string | null;
8126
8137
  /** Session Pubkey B64 */
8127
8138
  session_pubkey_b64?: string | null;
8128
- /** External access duration in seconds, at most 24 hours. @default 86400 */
8129
- access_duration_seconds?: number;
8139
+ /**
8140
+ * Access Duration Seconds
8141
+ * @description External recipients always receive an expiring grant, at most 24 hours, across login sessions.
8142
+ * @default 86400
8143
+ */
8144
+ access_duration_seconds: number;
8130
8145
  /** Confirm Invite */
8131
8146
  confirm_invite?: boolean | null;
8132
8147
  /** Resource Type */
@@ -8605,8 +8620,8 @@ interface components {
8605
8620
  SUGGESTED_QUERIES: boolean;
8606
8621
  /**
8607
8622
  * Artifacts Enabled
8608
- * @description Enable the create_artifact tool for generating standalone documents (summaries, reports, drafts) displayed in a side panel.
8609
- * @default false
8623
+ * @description Documents: enable the create_artifact tool, which drafts standalone documents (letters, reports, summaries) and saves them to the workspace as Word documents.
8624
+ * @default true
8610
8625
  */
8611
8626
  ARTIFACTS_ENABLED: boolean;
8612
8627
  /**
@@ -8804,12 +8819,12 @@ interface components {
8804
8819
  *
8805
8820
  * DOCUMENT STRATEGY, in order:
8806
8821
  * 1. Listing or cataloguing documents: use the document index already in your prompt — no tool calls needed.
8807
- * 2. Getting oriented in a document you have not read: call get_table_of_contents FIRST. It is cheap, returns the heading structure with page references, and tells you which pages actually matter. Do this before any read_document on a document longer than a few pages, rather than reading blind and then discovering the structure.
8822
+ * [[if get_table_of_contents, search_inside_documents, read_document: 2. Getting oriented in a document you have not read: call get_table_of_contents FIRST. It is cheap, returns the heading structure with page references, and tells you which pages actually matter. Do this before any read_document on a document longer than a few pages, rather than reading blind and then discovering the structure.
8808
8823
  * 3. Specific questions across several documents: search_inside_documents to locate the passages, then read_document on the pages it points to.
8809
8824
  * 4. Reading a document: read_document with page ranges for the sections you need, or with no ranges to load the complete text. A read with no ranges returns the WHOLE document — once you have it there is nothing further to retrieve from that document. Do not read it again, do not re-read ranges out of it, and do not ask for its outline afterwards.
8810
8825
  * 5. Prefer digest=true from the outset. It is the normal retrieval mode: findings with citations, compact context. Decide against it only when the task needs the exact words — translation, quotation, close reading of style or drafting. Choosing digest=false IS that decision, and it is final for that document: digest is a way of retrieving, not a way of processing text you already hold, so once you have loaded a document in full a digest of it is refused. Reason over the text you have.
8811
8826
  * 6. Open-ended investigative queries ("find interesting things", "what's notable", "what stands out", "explore X", "what should I know about", "any findings", "anything unusual", "key insights"): ALWAYS call search_inside_documents with multiple diverse queries covering different aspects of the documents before answering. The document index is never sufficient for investigative answers — you must retrieve actual content.
8812
- * 7. Never search for meta-queries like "summary", "overview", or "all documents" — search for the actual subject matter.
8827
+ * 7. Never search for meta-queries like "summary", "overview", or "all documents" — search for the actual subject matter.]]
8813
8828
  *
8814
8829
  * FORMATTING:
8815
8830
  * - Start your answer directly with the content.
@@ -8890,8 +8905,8 @@ interface components {
8890
8905
  SUGGESTED_QUERIES: boolean;
8891
8906
  /**
8892
8907
  * Artifacts Enabled
8893
- * @description Enable the create_artifact tool for generating standalone documents (summaries, reports, drafts) displayed in a side panel.
8894
- * @default false
8908
+ * @description Documents: enable the create_artifact tool, which drafts standalone documents (letters, reports, summaries) and saves them to the workspace as Word documents.
8909
+ * @default true
8895
8910
  */
8896
8911
  ARTIFACTS_ENABLED: boolean;
8897
8912
  /**
@@ -9003,7 +9018,7 @@ interface components {
9003
9018
  * "DEEP_RESEARCH_ENABLED": true,
9004
9019
  * "SUBAGENTS_ENABLED": true,
9005
9020
  * "SUGGESTED_QUERIES": true,
9006
- * "ARTIFACTS_ENABLED": false,
9021
+ * "ARTIFACTS_ENABLED": true,
9007
9022
  * "IMAGE_ENABLED": true,
9008
9023
  * "VISION_ENABLED": false,
9009
9024
  * "CONVERSATION_SEARCH_ENABLED": true,
@@ -9033,7 +9048,7 @@ interface components {
9033
9048
  * "AGENT_MAX_RUN_TOKENS": 1500000,
9034
9049
  * "AGENT_MAX_SUBAGENT_SPAWNS": 4,
9035
9050
  * "AGENT_HISTORY_TOKEN_BUDGET": 48000,
9036
- * "AGENT_SYSTEM_PROMPT": "Answer any question the user asks. You have access to workspace documents — use them when relevant. When no documents are relevant, answer from your own knowledge. Always provide a helpful answer.\n\nWhen using documents, retrieve actual document content — do not rely on metadata or headings alone. Cross-check information across sources. Not all assertions in sources are factual — some are arguments by a party. Attribute claims to their source where parties disagree.\n\nDOCUMENT INDEX:\nThe \"Workspace Documents\" table in your system prompt lists every document with its Id, Title, Date, and Pages. The Subject field is a brief navigation label only — it does not contain enough information to answer questions about a document's content. Use this table directly when the user asks to list, catalogue, or tabulate documents — do NOT call any tools for that. Only use tools when you need to read or search document content.\n\nREADING TOOL RESULTS:\nEvery retrieval result opens with a CAPTION line naming the call that produced it, what it contains, and what it does not (for example \"FULL CONTENT … complete verbatim text, all 10 pages\" or \"DIGEST … verbatim page text is NOT part of this result\"). The caption also tells you when you already retrieved that material earlier in this turn. Read it before choosing your next call — it is the record of what you already hold.\n\nDOCUMENT STRATEGY, in order:\n1. Listing or cataloguing documents: use the document index already in your prompt — no tool calls needed.\n2. Getting oriented in a document you have not read: call get_table_of_contents FIRST. It is cheap, returns the heading structure with page references, and tells you which pages actually matter. Do this before any read_document on a document longer than a few pages, rather than reading blind and then discovering the structure.\n3. Specific questions across several documents: search_inside_documents to locate the passages, then read_document on the pages it points to.\n4. Reading a document: read_document with page ranges for the sections you need, or with no ranges to load the complete text. A read with no ranges returns the WHOLE document — once you have it there is nothing further to retrieve from that document. Do not read it again, do not re-read ranges out of it, and do not ask for its outline afterwards.\n5. Prefer digest=true from the outset. It is the normal retrieval mode: findings with citations, compact context. Decide against it only when the task needs the exact words — translation, quotation, close reading of style or drafting. Choosing digest=false IS that decision, and it is final for that document: digest is a way of retrieving, not a way of processing text you already hold, so once you have loaded a document in full a digest of it is refused. Reason over the text you have.\n6. Open-ended investigative queries (\"find interesting things\", \"what's notable\", \"what stands out\", \"explore X\", \"what should I know about\", \"any findings\", \"anything unusual\", \"key insights\"): ALWAYS call search_inside_documents with multiple diverse queries covering different aspects of the documents before answering. The document index is never sufficient for investigative answers — you must retrieve actual content.\n7. Never search for meta-queries like \"summary\", \"overview\", or \"all documents\" — search for the actual subject matter.\n\nFORMATTING:\n- Start your answer directly with the content.\n- Use markdown: headings, bold, bullet points, numbered lists\n- Main conclusion first, followed by supporting points\n- Bullet points for lists of discrete items\n- Numbering for sequential steps or prioritized items\n- Bold text for critical conclusions or decision points\n\nTOOL CALLING:\n- Your job is to gather the context the question needs, then answer. Do not give a final answer while there is relevant context you have not yet retrieved — but material already in your context counts as retrieved, and fetching it a second time is not progress. If the question touches a workspace document, always check the source — never answer from a past turn's reply alone.\n- Always invoke tools using the tool-calling mechanism. Say what a call is doing in its `focus` argument.\n\nEFFICIENCY:\n1. Before each step, review the results of prior steps. Adapt your approach based on what you learned — if a call was rejected or returned poor results, adjust your strategy.\n2. Call multiple tools in parallel when a query has several aspects.\n3. NEVER repeat a tool call with the same arguments, and never re-retrieve material you already hold — the caption on each result tells you what that is.\n4. Use targeted queries and narrow page ranges per retrieval call.\n5. Stop when you have sufficient evidence — do not over-research."
9051
+ * "AGENT_SYSTEM_PROMPT": "Answer any question the user asks. You have access to workspace documents — use them when relevant. When no documents are relevant, answer from your own knowledge. Always provide a helpful answer.\n\nWhen using documents, retrieve actual document content — do not rely on metadata or headings alone. Cross-check information across sources. Not all assertions in sources are factual — some are arguments by a party. Attribute claims to their source where parties disagree.\n\nDOCUMENT INDEX:\nThe \"Workspace Documents\" table in your system prompt lists every document with its Id, Title, Date, and Pages. The Subject field is a brief navigation label only — it does not contain enough information to answer questions about a document's content. Use this table directly when the user asks to list, catalogue, or tabulate documents — do NOT call any tools for that. Only use tools when you need to read or search document content.\n\nREADING TOOL RESULTS:\nEvery retrieval result opens with a CAPTION line naming the call that produced it, what it contains, and what it does not (for example \"FULL CONTENT … complete verbatim text, all 10 pages\" or \"DIGEST … verbatim page text is NOT part of this result\"). The caption also tells you when you already retrieved that material earlier in this turn. Read it before choosing your next call — it is the record of what you already hold.\n\nDOCUMENT STRATEGY, in order:\n1. Listing or cataloguing documents: use the document index already in your prompt — no tool calls needed.\n[[if get_table_of_contents, search_inside_documents, read_document: 2. Getting oriented in a document you have not read: call get_table_of_contents FIRST. It is cheap, returns the heading structure with page references, and tells you which pages actually matter. Do this before any read_document on a document longer than a few pages, rather than reading blind and then discovering the structure.\n3. Specific questions across several documents: search_inside_documents to locate the passages, then read_document on the pages it points to.\n4. Reading a document: read_document with page ranges for the sections you need, or with no ranges to load the complete text. A read with no ranges returns the WHOLE document — once you have it there is nothing further to retrieve from that document. Do not read it again, do not re-read ranges out of it, and do not ask for its outline afterwards.\n5. Prefer digest=true from the outset. It is the normal retrieval mode: findings with citations, compact context. Decide against it only when the task needs the exact words — translation, quotation, close reading of style or drafting. Choosing digest=false IS that decision, and it is final for that document: digest is a way of retrieving, not a way of processing text you already hold, so once you have loaded a document in full a digest of it is refused. Reason over the text you have.\n6. Open-ended investigative queries (\"find interesting things\", \"what's notable\", \"what stands out\", \"explore X\", \"what should I know about\", \"any findings\", \"anything unusual\", \"key insights\"): ALWAYS call search_inside_documents with multiple diverse queries covering different aspects of the documents before answering. The document index is never sufficient for investigative answers — you must retrieve actual content.\n7. Never search for meta-queries like \"summary\", \"overview\", or \"all documents\" — search for the actual subject matter.]]\n\nFORMATTING:\n- Start your answer directly with the content.\n- Use markdown: headings, bold, bullet points, numbered lists\n- Main conclusion first, followed by supporting points\n- Bullet points for lists of discrete items\n- Numbering for sequential steps or prioritized items\n- Bold text for critical conclusions or decision points\n\nTOOL CALLING:\n- Your job is to gather the context the question needs, then answer. Do not give a final answer while there is relevant context you have not yet retrieved — but material already in your context counts as retrieved, and fetching it a second time is not progress. If the question touches a workspace document, always check the source — never answer from a past turn's reply alone.\n- Always invoke tools using the tool-calling mechanism. Say what a call is doing in its `focus` argument.\n\nEFFICIENCY:\n1. Before each step, review the results of prior steps. Adapt your approach based on what you learned — if a call was rejected or returned poor results, adjust your strategy.\n2. Call multiple tools in parallel when a query has several aspects.\n3. NEVER repeat a tool call with the same arguments, and never re-retrieve material you already hold — the caption on each result tells you what that is.\n4. Use targeted queries and narrow page ranges per retrieval call.\n5. Stop when you have sufficient evidence — do not over-research."
9037
9052
  * }
9038
9053
  */
9039
9054
  Agents: components['schemas']['AgentsConfig'];
@@ -9195,7 +9210,7 @@ interface components {
9195
9210
  * "API_TYPE": "remote",
9196
9211
  * "ENABLE_THINKING": true,
9197
9212
  * "MODEL_NAME": "Wise",
9198
- * "SYSTEM_INSTRUCTION": "You are a research planning assistant. Your job is to analyze a user query and produce a concise, numbered research plan.\n\nYou have access to a workspace of documents. The available tools for executing the plan are:\n- search_inside_documents: Search workspace documents for relevant passages (semantic, keyword, or hybrid). Use digest=true to extract learnings.\n- read_document: Read page ranges or entire documents. Use digest=true to extract learnings with citations.\n- get_table_of_contents: Get document headings with page references\n\nConsider:\n- What information is needed to answer the query\n- Which documents are likely relevant based on the document index\n- What search queries and document passages to examine\n- What order of operations will be most efficient\n- Whether parallel searches can be used for different aspects\n\nRespond with ONLY the plan (numbered steps). Do not execute any steps.",
9213
+ * "SYSTEM_INSTRUCTION": "You are a research planning assistant. Your job is to analyze a user query and produce a concise, numbered research plan.\n\nYou have access to a workspace of documents.[[if search_inside_documents, read_document, get_table_of_contents: The available tools for executing the plan are:\n- search_inside_documents: Search workspace documents for relevant passages (semantic, keyword, or hybrid). Use digest=true to extract learnings.\n- read_document: Read page ranges or entire documents. Use digest=true to extract learnings with citations.\n- get_table_of_contents: Get document headings with page references]]\n\nConsider:\n- What information is needed to answer the query\n- Which documents are likely relevant based on the document index\n- What search queries and document passages to examine\n- What order of operations will be most efficient\n- Whether parallel searches can be used for different aspects\n\nRespond with ONLY the plan (numbered steps). Do not execute any steps.",
9199
9214
  * "TEMPERATURE": 0.3,
9200
9215
  * "MAX_TOKENS": 0,
9201
9216
  * "MAX_TOKEN_SIZE_TO_ANSWER": 200000,
@@ -12853,6 +12868,11 @@ interface components {
12853
12868
  * @default false
12854
12869
  */
12855
12870
  is_identity_verified: boolean;
12871
+ /**
12872
+ * Temporary Access Only
12873
+ * @default false
12874
+ */
12875
+ temporary_access_only: boolean;
12856
12876
  /** Signing Private Key */
12857
12877
  signing_private_key: string;
12858
12878
  };
@@ -13169,6 +13189,11 @@ interface components {
13169
13189
  * @default false
13170
13190
  */
13171
13191
  is_identity_verified: boolean;
13192
+ /**
13193
+ * Temporary Access Only
13194
+ * @default false
13195
+ */
13196
+ temporary_access_only: boolean;
13172
13197
  /** Can Create Projects */
13173
13198
  can_create_projects: boolean;
13174
13199
  /**
@@ -13861,6 +13886,11 @@ interface components {
13861
13886
  error_message?: string | null;
13862
13887
  /** Failed Stage */
13863
13888
  failed_stage?: string | null;
13889
+ /**
13890
+ * Status Seq
13891
+ * @default 0
13892
+ */
13893
+ status_seq: number;
13864
13894
  /** N Pages */
13865
13895
  n_pages?: number | null;
13866
13896
  /** N Chunks */
@@ -17279,6 +17309,13 @@ interface components {
17279
17309
  /** Premium Default */
17280
17310
  premium_default?: string | null;
17281
17311
  };
17312
+ /** NamedSigner */
17313
+ NamedSigner: {
17314
+ /** Email */
17315
+ email: string;
17316
+ /** Name */
17317
+ name: string;
17318
+ };
17282
17319
  /** NativeAliasRead */
17283
17320
  NativeAliasRead: {
17284
17321
  /** Email */
@@ -17874,10 +17911,10 @@ interface components {
17874
17911
  * @description System instruction for the planning LLM.
17875
17912
  * @default You are a research planning assistant. Your job is to analyze a user query and produce a concise, numbered research plan.
17876
17913
  *
17877
- * You have access to a workspace of documents. The available tools for executing the plan are:
17914
+ * You have access to a workspace of documents.[[if search_inside_documents, read_document, get_table_of_contents: The available tools for executing the plan are:
17878
17915
  * - search_inside_documents: Search workspace documents for relevant passages (semantic, keyword, or hybrid). Use digest=true to extract learnings.
17879
17916
  * - read_document: Read page ranges or entire documents. Use digest=true to extract learnings with citations.
17880
- * - get_table_of_contents: Get document headings with page references
17917
+ * - get_table_of_contents: Get document headings with page references]]
17881
17918
  *
17882
17919
  * Consider:
17883
17920
  * - What information is needed to answer the query
@@ -21645,6 +21682,11 @@ interface components {
21645
21682
  SuggestSignatureFieldsResponse: {
21646
21683
  /** Fields */
21647
21684
  fields: components['schemas']['SuggestedSignatureField'][];
21685
+ /**
21686
+ * Signers
21687
+ * @description The signers the Word document's placed fields name, with the name each gives, in document order: known even when the PDF shows none of the fields' anchors (fields then placed by hand)
21688
+ */
21689
+ signers?: components['schemas']['NamedSigner'][];
21648
21690
  };
21649
21691
  /** SuggestedSignatureField */
21650
21692
  SuggestedSignatureField: {
@@ -22231,6 +22273,10 @@ interface components {
22231
22273
  failed_stage?: string | null;
22232
22274
  /** Folder */
22233
22275
  folder?: string | null;
22276
+ /** Seq */
22277
+ seq?: number | null;
22278
+ /** Updated At */
22279
+ updated_at?: string | null;
22234
22280
  };
22235
22281
  /** TaxQuoteLine */
22236
22282
  TaxQuoteLine: {
@@ -23363,8 +23409,11 @@ interface components {
23363
23409
  * @default false
23364
23410
  */
23365
23411
  is_identity_verified: boolean;
23366
- /** Read-only: external recipients may only receive temporary workspace access. */
23367
- temporary_access_only?: boolean;
23412
+ /**
23413
+ * Temporary Access Only
23414
+ * @default false
23415
+ */
23416
+ temporary_access_only: boolean;
23368
23417
  };
23369
23418
  /**
23370
23419
  * UserRole
@@ -24447,7 +24496,7 @@ interface components {
24447
24496
  * @description User (or agent) with their role in a workspace.
24448
24497
  *
24449
24498
  * For agents: agent_ext_id is set (agt-XXXXXXXX), name is user.given_name.
24450
- * is_temporary: True when the grant is session-scoped (expires_at is set in DB).
24499
+ * is_temporary: True when the grant expires (expires_at is set in DB).
24451
24500
  */
24452
24501
  WorkspaceUserResponse: {
24453
24502
  user: components['schemas']['UserResponse'];
@@ -24479,7 +24528,7 @@ interface components {
24479
24528
  * @default false
24480
24529
  */
24481
24530
  is_temporary: boolean;
24482
- /** Fixed UTC expiry of temporary access. */
24531
+ /** Access Expires At */
24483
24532
  access_expires_at?: string | null;
24484
24533
  };
24485
24534
  /**
@@ -37894,6 +37943,7 @@ interface TokenProvider {
37894
37943
  interface BearerAuthMiddlewareConfig {
37895
37944
  tokenProvider: TokenProvider;
37896
37945
  }
37946
+ /** The new access token, or `null`. Ending a session the server refused is the handler's job. */
37897
37947
  type ReloginHandler = () => Promise<string | null>;
37898
37948
  interface AutoReloginMiddlewareConfig {
37899
37949
  reloginHandler: ReloginHandler;
@@ -37906,9 +37956,12 @@ interface AutoReloginMiddlewareConfig {
37906
37956
  * re-opens the workspace) is tried instead.
37907
37957
  */
37908
37958
  reopenWorkspaceHandler?: () => Promise<boolean>;
37959
+ /**
37960
+ * Deposit a workspace's key on the session (it named a workspace whose key the session lacks:
37961
+ * 409 `workspace_key_required`). Resolves true when done; the request is then sent again, once.
37962
+ */
37963
+ primeWorkspaceHandler?: (workspaceId: string) => Promise<boolean>;
37909
37964
  onRetryCloneFailed?: () => void;
37910
- /** Called when re-login was attempted but failed (returned null). Use to clear stale auth state. */
37911
- onReloginFailed?: () => void;
37912
37965
  }
37913
37966
 
37914
37967
  /**
@@ -37931,26 +37984,33 @@ interface CryptoProvider {
37931
37984
  interface SessionKeys {
37932
37985
  signingPrivateKey: Uint8Array;
37933
37986
  serverSessionKey?: Uint8Array;
37987
+ /** The account these keys belong to. */
37988
+ userExtId?: string;
37934
37989
  /** The identity wrapped under the password key (see SessionData.wrappedIdentityKey). */
37935
37990
  wrappedIdentityKey?: string | null;
37936
37991
  }
37937
- interface SessionStorageProvider {
37992
+ /**
37993
+ * Where the signed-in identity is kept between page loads (the signing key and the server session
37994
+ * key). Browsers default to the bundled encrypted IndexedDB store; Node hosts pass a file-backed
37995
+ * one. A silent re-login reads the key from here and saves the new server session key back.
37996
+ */
37997
+ interface SessionPersistence {
37938
37998
  getSession(): Promise<SessionKeys | null>;
37939
- saveSession(data: SessionKeys & {
37940
- userExtId?: string;
37941
- }): Promise<void>;
37999
+ saveSession(data: SessionKeys): Promise<void>;
37942
38000
  }
37943
38001
  interface AuthStateProvider {
37944
38002
  getUserEmail(): string | null;
37945
- getSsoState(): {
37946
- isSsoMode: boolean;
37947
- isAuth0Authenticated: boolean;
37948
- auth0AccessToken: string | null;
37949
- };
38003
+ /** True when this deployment signs in through SSO: a re-login then needs an SSO token. */
38004
+ isSsoMode(): boolean;
37950
38005
  getSelectedWorkspaceId(): string | null;
37951
38006
  setAccessToken(token: string): void;
37952
38007
  }
37953
- interface SsoTokenProvider {
38008
+ /**
38009
+ * The SSO provider's access token for a re-login, or `null` when there is none. The SDK knows no
38010
+ * SSO vendor: the host (or a blocks adapter, e.g. Auth0) supplies this. It is only asked when the
38011
+ * session is in SSO mode.
38012
+ */
38013
+ interface SsoTokenSource {
37954
38014
  getToken(): Promise<string | null>;
37955
38015
  }
37956
38016
  /** Result of a successful login API call */
@@ -37961,14 +38021,17 @@ interface LoginResult$1 {
37961
38021
  /** The login response's `wrapped_identity_key`, saved with the session. */
37962
38022
  wrappedIdentityKey?: string | null;
37963
38023
  }
37964
- /** Performs the login API call. Transport details are the consumer's concern. */
38024
+ /**
38025
+ * Performs the login API call: the result, `null` when the server refused it, `'unreachable'` when
38026
+ * the server could not be reached.
38027
+ */
37965
38028
  interface LoginProvider {
37966
38029
  login(payload: {
37967
38030
  email: string;
37968
38031
  signature: string;
37969
38032
  timestamp: number;
37970
38033
  ssoToken?: string;
37971
- }): Promise<LoginResult$1 | null>;
38034
+ }): Promise<LoginResult$1 | 'unreachable' | null>;
37972
38035
  }
37973
38036
  /**
37974
38037
  * Fetches the wrapped workspace key for a given workspace after re-login.
@@ -37990,48 +38053,98 @@ type OnReloginSuccess = (data: {
37990
38053
  userExtId?: string;
37991
38054
  serverSessionKey: Uint8Array;
37992
38055
  }) => void | Promise<void>;
38056
+ /**
38057
+ * Why a re-login returned no token:
38058
+ * - `not-ready`: nothing to re-login with yet (no user, no stored key): a login is still finishing;
38059
+ * - `unreachable`: the server could not be reached: an outage, not an expired session;
38060
+ * - `refused`: the attempt failed (the server refused it, no SSO token, a crypto error): the
38061
+ * session is over.
38062
+ */
38063
+ type ReloginFailure = 'not-ready' | 'unreachable' | 'refused';
37993
38064
  interface ReloginDeps {
37994
38065
  crypto: CryptoProvider;
37995
- sessionStorage: SessionStorageProvider;
38066
+ persistence: SessionPersistence;
37996
38067
  authState: AuthStateProvider;
37997
- ssoTokenProvider: SsoTokenProvider | null;
38068
+ sso: SsoTokenSource | null;
37998
38069
  loginProvider: LoginProvider;
37999
38070
  workspaceKeyRefreshProvider: WorkspaceKeyRefreshProvider;
38000
38071
  workspaceOpenProvider?: WorkspaceOpenProvider;
38001
38072
  onReloginSuccess?: OnReloginSuccess;
38073
+ /** Called once per failed attempt (concurrent callers share it), with the reason. */
38074
+ onReloginFailed?: (reason: ReloginFailure) => void;
38002
38075
  }
38003
38076
 
38004
38077
  /**
38005
- * SessionManager - In-memory session state for SDK consumers
38078
+ * SessionManager: the signed-in session's state, the one source the transport, the SDK and a host's
38079
+ * UI read: the token, the user, SSO mode, the server session key and whether a login finished.
38006
38080
  *
38007
- * Replaces Zustand for SDK consumers. Simple in-memory store with subscribe pattern.
38008
- * Implements TokenProvider and AuthStateProvider —
38009
- * plugs directly into middleware and relogin handler without any framework.
38081
+ * In memory by default. A browser host passes `storage` (`browserSessionStateStorage()`) so the
38082
+ * session survives a reload. Implements TokenProvider and AuthStateProvider for the middleware and the
38083
+ * re-login, without any framework.
38010
38084
  */
38011
38085
 
38086
+ /** The signed-in user as the login returned it (and as profile edits keep it). */
38087
+ type SessionUser = components['schemas']['UserResponse'];
38012
38088
  interface SessionState {
38013
38089
  accessToken: string | null;
38014
38090
  userEmail: string | null;
38015
38091
  userExtId: string | null;
38016
38092
  selectedWorkspaceId: string | null;
38093
+ /** The account signs in through SSO: a re-login needs the SSO provider's token. */
38017
38094
  isSsoMode: boolean;
38018
- isAuth0Authenticated: boolean;
38019
- auth0AccessToken: string | null;
38095
+ /** The signed-in user; `null` signed out (and for a session seeded with an email only). */
38096
+ user: SessionUser | null;
38097
+ /**
38098
+ * A login finished on this device and was not signed out. A new tab (or an offline unlock) is
38099
+ * signed in with no token yet: the next request re-logs in.
38100
+ */
38101
+ signedIn: boolean;
38102
+ /** This server session's key, which workspace keys are sealed to. In memory only. */
38103
+ serverSessionKey: Uint8Array | null;
38104
+ }
38105
+ /** What a finished login puts in the session, all at once. */
38106
+ interface SessionSignIn {
38107
+ /** `null` for an offline unlock: no server session yet. */
38108
+ accessToken: string | null;
38109
+ user: SessionUser;
38110
+ isSsoMode: boolean;
38111
+ serverSessionKey: Uint8Array | null;
38112
+ }
38113
+ /** The part of the session kept across reloads (never the server session key). */
38114
+ type StoredSessionState = Pick<SessionState, 'accessToken' | 'userEmail' | 'userExtId' | 'isSsoMode' | 'user' | 'signedIn'>;
38115
+ /** Where a browser keeps the session across reloads. */
38116
+ interface SessionStateStorage {
38117
+ load(): Partial<StoredSessionState> | null;
38118
+ save(state: StoredSessionState): void;
38119
+ }
38120
+ interface SessionManagerOptions {
38121
+ storage?: SessionStateStorage;
38020
38122
  }
38021
38123
  interface SessionManager {
38124
+ /** The current state: the same object until something in it changes. */
38022
38125
  getState(): Readonly<SessionState>;
38023
38126
  setAccessToken(token: string | null): void;
38024
38127
  setUser(email: string, extId?: string): void;
38128
+ /** Change the signed-in user's fields (a profile edit, a verified tick). */
38129
+ updateUser(patch: Partial<SessionUser>): void;
38025
38130
  setSelectedWorkspace(id: string | null): void;
38026
- setSsoState(opts: Partial<{
38027
- isSsoMode: boolean;
38028
- isAuth0Authenticated: boolean;
38029
- auth0AccessToken: string | null;
38030
- }>): void;
38131
+ setSsoMode(isSsoMode: boolean): void;
38132
+ setServerSessionKey(key: Uint8Array | null): void;
38133
+ /** A login finished: token, user, SSO mode and server session key in one change. */
38134
+ signIn(session: SessionSignIn): void;
38135
+ /** The session is over (logout, or it could not be recovered): drop the token and the user. */
38031
38136
  clear(): void;
38032
38137
  subscribe(listener: (state: SessionState) => void): () => void;
38033
38138
  }
38034
- declare function createSessionManager(): SessionManager;
38139
+ declare function createSessionManager(options?: SessionManagerOptions): SessionManager;
38140
+ /** sessionStorage key of the access token: per tab, so each tab has its own server session. */
38141
+ declare const ACCESS_TOKEN_STORAGE_KEY = "arbi_access_token";
38142
+ /**
38143
+ * The browser's session storage: the access token per tab (sessionStorage), the user and the
38144
+ * signed-in flag per browser (localStorage), so a new tab is signed in and re-logs in for a token
38145
+ * of its own. The keys themselves stay in the encrypted IndexedDB store (`SessionPersistence`).
38146
+ */
38147
+ declare function browserSessionStateStorage(): SessionStateStorage;
38035
38148
 
38036
38149
  /**
38037
38150
  * Layer 1: Pure libsodium wrappers
@@ -38260,6 +38373,25 @@ declare function parseCallFragment(hash: string): {
38260
38373
  key: Uint8Array;
38261
38374
  linkVersion: number | null;
38262
38375
  } | null;
38376
+ /** `<origin>/call/<id>#k=…&v=…` — the shareable call link (the key travels in the fragment only). */
38377
+ declare function buildCallLink(origin: string, callExtId: string, key: Uint8Array, linkVersion: number): string;
38378
+ /** Someone a call key can be sealed to: their user id and X25519 public key (base64). */
38379
+ interface CallPeer {
38380
+ external_id: string;
38381
+ encryption_public_key?: string | null;
38382
+ }
38383
+ /**
38384
+ * K sealed to each peer that has an encryption key, by user id. Agents and keyless users are
38385
+ * skipped, and so is `exclude` (the caller, who holds K already).
38386
+ */
38387
+ declare function sealCallKeyForPeers(key: Uint8Array, peers: readonly CallPeer[], exclude?: string | null): Promise<Record<string, string>>;
38388
+ /**
38389
+ * My copy of a call's K from the call row (`my_sealed_key`, sealed to me as its creator or an
38390
+ * invitee); null when I have none or it does not open.
38391
+ */
38392
+ declare function openCallKeyOf(call: {
38393
+ my_sealed_key?: string | null;
38394
+ }, encryptionSecretKey: Uint8Array): Promise<Uint8Array | null>;
38263
38395
 
38264
38396
  /**
38265
38397
  * Chat keys (`/v1/chats`). Every chat message, title and attachment manifest is
@@ -38568,6 +38700,69 @@ interface OfflineSealerOptions {
38568
38700
  /** A sealer for one offline store, namespaced so stores can't read each other's records. */
38569
38701
  declare function createOfflineSealer(namespace: string, { locked, keypair: getKeypair }: OfflineSealerOptions): OfflineSealer;
38570
38702
 
38703
+ /**
38704
+ * The user's workspace keys on this client: what the workspace lists said (each workspace's key,
38705
+ * wrapped to the user, and which are public, with none), and depositing a workspace's key on the
38706
+ * server session without opening it (`/prime-key`).
38707
+ *
38708
+ * One per client, so every `Arbi` on the client (a host recreates its `Arbi` per session and per
38709
+ * opened workspace) and the client's own recovery share it: a list read once, by whoever read it,
38710
+ * serves every later open. A request refused with 409 `workspace_key_required` primes the
38711
+ * workspace it names and is sent again (see the auto re-login middleware).
38712
+ */
38713
+
38714
+ /** A workspace as a workspace list has it (only what the keys need). */
38715
+ interface ListedWorkspaceKey {
38716
+ external_id: string;
38717
+ wrapped_key?: string | null;
38718
+ is_public?: boolean | null;
38719
+ /** A member without an account key: a temporary grant whose key lives in the server session. */
38720
+ is_member?: boolean | null;
38721
+ }
38722
+ interface WorkspaceKeys {
38723
+ /** Remember what a workspace list said. Returns the list. */
38724
+ remember<T extends ListedWorkspaceKey>(workspaces: T[]): T[];
38725
+ /**
38726
+ * The workspace's key, wrapped to the user: from what was remembered, else from a fresh list
38727
+ * (a workspace created or shared since), or a fresh list with `refresh` (a key that no longer
38728
+ * opens: access re-granted with a new key). `null` for a public workspace the user holds no key
38729
+ * for, or one they hold a temporary (session-scoped or fixed-expiry) grant to. Throws when the user cannot see the workspace.
38730
+ */
38731
+ wrappedKey(workspaceId: string, options?: {
38732
+ refresh?: boolean;
38733
+ }): Promise<{
38734
+ wrappedKey: string | null;
38735
+ fromCache: boolean;
38736
+ }>;
38737
+ /**
38738
+ * Make a workspace usable for requests that name it, without opening it: its key, sealed to this
38739
+ * server session, is deposited with `/prime-key`. Once per server session (a re-login rotates
38740
+ * it); concurrent calls share one request; `force` deposits again (the server lost it).
38741
+ */
38742
+ prime(workspaceId: string, options?: {
38743
+ force?: boolean;
38744
+ }): Promise<void>;
38745
+ /** Forget these workspaces (deleted). */
38746
+ forget(workspaceIds: string[]): void;
38747
+ /** Forget everything (another user, signed out). */
38748
+ clear(): void;
38749
+ }
38750
+ interface WorkspaceKeysDeps {
38751
+ crypto: Pick<CryptoProvider, 'ensureReady' | 'sealKeyForSession'>;
38752
+ /** The workspace key, unwrapped with the signing key. */
38753
+ unwrapWorkspaceKey(wrappedKey: string, signingPrivateKey: Uint8Array): Uint8Array;
38754
+ persistence: SessionPersistence;
38755
+ getAccessToken(): string | null;
38756
+ /** The server session key in use (the session's), else the stored one is read. */
38757
+ getServerSessionKey(): Uint8Array | null;
38758
+ listWorkspaces(accessToken: string): Promise<ListedWorkspaceKey[] | null>;
38759
+ /** POST `/v1/workspace/{id}/prime-key`; throws when refused. */
38760
+ primeKey(accessToken: string, workspaceId: string, sealedKey: string): Promise<void>;
38761
+ }
38762
+ declare function createWorkspaceKeys(deps: WorkspaceKeysDeps): WorkspaceKeys;
38763
+ /** The workspace a 409 `{detail: {code: "workspace_key_required", workspace_ext_id}}` names. */
38764
+ declare function workspaceKeyRequiredOf(body: unknown): string | null;
38765
+
38571
38766
  /**
38572
38767
  * storage.ts - IndexedDB Storage Module
38573
38768
  *
@@ -38696,16 +38891,39 @@ interface RegisterResult {
38696
38891
  * identity → saves session
38697
38892
  */
38698
38893
 
38894
+ type LoginResponse = components['schemas']['LoginResponse'];
38699
38895
  interface LoginParams {
38700
38896
  email: string;
38701
38897
  password: string;
38898
+ /** An SSO account signs in with its provider's token too (the session is then in SSO mode). */
38702
38899
  ssoToken?: string;
38900
+ /** Profile fields to use instead of the login response's (a new SSO account's provider name). */
38901
+ profile?: Partial<Pick<SessionUser, 'given_name' | 'family_name' | 'picture'>>;
38703
38902
  }
38704
38903
  interface LoginWithKeyParams {
38705
38904
  email: string;
38706
38905
  signingPrivateKey: Uint8Array;
38707
38906
  ssoToken?: string;
38708
38907
  }
38908
+ /**
38909
+ * The host's part of every sign-in (password, key, SSO), around the client's own: `before` runs once
38910
+ * the server accepted the login and the identity opened, before anything is stored, so the host can
38911
+ * clear the previous user's state; `after` runs once the session is signed in.
38912
+ */
38913
+ interface SignInHooks {
38914
+ before?(next: {
38915
+ user: LoginResponse['user'];
38916
+ }): Promise<void> | void;
38917
+ after?(signedIn: {
38918
+ response: LoginResponse;
38919
+ serverSessionKey: Uint8Array;
38920
+ }): void;
38921
+ }
38922
+ /** A refused auth request: its message, and the server's `detail` and status for the caller. */
38923
+ declare function authRequestError(what: string, error: unknown, status: number | undefined): Error & {
38924
+ detail?: unknown;
38925
+ status?: number;
38926
+ };
38709
38927
  /** The signed-in user's profile as the login response carries it. */
38710
38928
  interface LoginProfile {
38711
38929
  givenName: string;
@@ -38719,6 +38937,8 @@ interface LoginProfile {
38719
38937
  isIdentityVerified?: boolean;
38720
38938
  }
38721
38939
  interface LoginResult {
38940
+ /** The login response itself (workspaces, a pending share, the user). */
38941
+ response?: LoginResponse;
38722
38942
  accessToken: string;
38723
38943
  userExtId?: string;
38724
38944
  /** Owner's ext_id for agent accounts; null/undefined for human users */
@@ -38818,83 +39038,111 @@ declare function readSessionClaims(token: string | null | undefined): SessionCla
38818
39038
 
38819
39039
  declare const API_PREFIX: "/v1";
38820
39040
  interface ArbiClientOptions {
38821
- /** Base URL for the ARBI API (e.g. "https://api.mydeployment.com") */
38822
- baseUrl: string;
39041
+ /**
39042
+ * Base URL for the ARBI API (e.g. "https://api.mydeployment.com"; `''` for the page's own
39043
+ * origin). A function is read on every request: a host whose configuration arrives after the
39044
+ * client is made (a runtime config file) passes a getter.
39045
+ */
39046
+ baseUrl: string | (() => string);
38823
39047
  /** Deployment domain used for deterministic key derivation (e.g. "mydeployment.com") */
38824
- deploymentDomain: string;
39048
+ deploymentDomain: string | (() => string);
38825
39049
  /** URL patterns that should never trigger re-login */
38826
39050
  reloginExcludePatterns?: string[];
38827
39051
  /** Include credentials (cookies) in requests. Default: true */
38828
39052
  credentials?: RequestCredentials;
38829
- /** Optional SSO token provider */
38830
- ssoTokenProvider?: {
38831
- getToken(): Promise<string | null>;
38832
- } | null;
38833
- /** Optional callback when re-login succeeds */
38834
- onReloginSuccess?: (data: {
38835
- email: string;
38836
- accessToken: string;
38837
- userExtId?: string;
38838
- serverSessionKey: Uint8Array;
38839
- }) => void;
38840
39053
  /**
38841
- * Called when the session cannot be recovered: a request failed with 401 (or 400 "No active
38842
- * workspace") and neither a workspace re-open nor a silent re-login worked because the server
38843
- * REFUSED it (not a network failure, which leaves the session alone). The host shows "your
38844
- * session expired, sign in again". Not called before anyone has logged in.
39054
+ * The session state (token, user, selected workspace, SSO mode), read on every request. Default:
39055
+ * an in-memory one. A host app that keeps the session in its own store passes an adapter over it;
39056
+ * its `clear()` is called when the session ends (logout, or a re-login the server refused).
38845
39057
  */
38846
- onSessionExpired?: () => void;
39058
+ session?: SessionManager;
38847
39059
  /**
38848
- * Optional session storage provider for the relogin handler.
38849
- *
38850
- * Browsers get the bundled IndexedDB implementation by default. Node
38851
- * consumers (CLI, SDK integration tests) should pass a file-backed
38852
- * adapter — without one, the auto-relogin middleware has nowhere to
38853
- * read the signing key from on a 401 and falls back to surfacing the
38854
- * error as-is.
39060
+ * Where the signing key and server session key are kept between page loads. Browsers default to
39061
+ * the bundled encrypted IndexedDB store; Node consumers (CLI, integration tests) pass a
39062
+ * file-backed one, or a 401 has no key to re-login with.
38855
39063
  */
38856
- sessionStorage?: SessionStorageProvider;
39064
+ persistence?: SessionPersistence;
39065
+ /**
39066
+ * The workspace a re-login re-opens, when the host's navigation keeps it rather than the session
39067
+ * (`session.selectedWorkspaceId`).
39068
+ */
39069
+ selectedWorkspace?: () => string | null;
39070
+ /** The SSO provider's token for re-logins of SSO accounts (see `SsoTokenSource`). */
39071
+ sso?: SsoTokenSource | null;
39072
+ /**
39073
+ * Extra openapi-fetch middleware, run after the bearer token is added and before the re-login
39074
+ * middleware sees the response (e.g. a host's handling of 402 Payment Required).
39075
+ */
39076
+ middleware?: Middleware[];
39077
+ /** The host's part of every sign-in (`SignInHooks`): clear the previous user, then follow up. */
39078
+ signIn?: SignInHooks;
39079
+ /** Optional callback when re-login succeeds */
39080
+ onReloginSuccess?: OnReloginSuccess;
39081
+ /** A request re-logged in but could not be re-sent (its body was already consumed). */
39082
+ onRetryCloneFailed?: () => void;
38857
39083
  /**
38858
39084
  * Optional user email to seed the in-memory session at creation time.
38859
39085
  * Ensures the auto-relogin middleware can re-authenticate even when
38860
39086
  * the client is constructed from cached credentials (no login call).
38861
39087
  */
38862
39088
  userEmail?: string;
38863
- /**
38864
- * Run on a transport the host app already has instead of building one: its authenticated fetch
38865
- * client, its session state and its re-login. One session, one re-login loop; `baseUrl`,
38866
- * `credentials`, `ssoTokenProvider`, `sessionStorage`, `userEmail` and the re-login callbacks
38867
- * are the host's business then and are not used.
38868
- */
38869
- transport?: ArbiClientTransport;
38870
- }
38871
- /** What an `ArbiClient` sends requests over: built by `createArbiClient`, or the host's own. */
38872
- interface ArbiClientTransport {
38873
- /** Type-safe openapi-fetch client whose middleware adds the token and re-logs in on a 401. */
38874
- fetch: ReturnType<typeof createFetchClient<paths>>;
38875
- /** Session state (token, user, selected workspace), read on every call. */
38876
- session: SessionManager;
38877
- /** Silent re-login: the new access token, or `null` when the session cannot be recovered. */
38878
- relogin(): Promise<string | null>;
38879
- /** Re-open the selected workspace without a new login; `false` when it could not. */
38880
- reopenWorkspace(): Promise<boolean>;
38881
39089
  }
38882
39090
  interface ArbiClient {
38883
39091
  /** Type-safe openapi-fetch client with middleware */
38884
39092
  fetch: ReturnType<typeof createFetchClient<paths>>;
38885
39093
  /** In-memory session state */
38886
39094
  session: SessionManager;
39095
+ /**
39096
+ * The user's workspace keys: the wrapped keys the workspace lists returned (shared by everything
39097
+ * on this client), and depositing a workspace's key on the session without opening it. A request
39098
+ * refused with 409 `workspace_key_required` primes the workspace it names and is sent again.
39099
+ */
39100
+ workspaceKeys: WorkspaceKeys;
38887
39101
  /** High-level auth operations */
38888
39102
  auth: {
38889
39103
  register(params: RegisterParams): Promise<RegisterResult>;
38890
39104
  login(params: LoginParams): Promise<LoginResult>;
38891
39105
  loginWithKey(params: LoginWithKeyParams): Promise<LoginResult>;
38892
- logout(): Promise<void>;
39106
+ /**
39107
+ * Sign out: the server session ends (every session of the user with `everywhere`), the session
39108
+ * state is cleared and, with `everywhere`, so are the keys kept on this device. A single sign-out
39109
+ * keeps them, so the user can unlock offline. Best-effort on the server: offline still signs out.
39110
+ */
39111
+ logout(options?: {
39112
+ everywhere?: boolean;
39113
+ }): Promise<void>;
39114
+ /**
39115
+ * Sign in on this device with no server (offline): the password must open the identity saved
39116
+ * at the last login here. Signed in without a token; the next request online re-logs in.
39117
+ * Throws `'no-session'` (nothing saved here) or `'bad-password'`.
39118
+ */
39119
+ unlock(params: {
39120
+ email: string;
39121
+ password: string;
39122
+ }): Promise<void>;
39123
+ /**
39124
+ * After a reload: put the stored server session key back in the session. `false` (and the
39125
+ * session cleared) when the session says signed in but this device holds no keys.
39126
+ */
39127
+ restore(): Promise<boolean>;
38893
39128
  changePassword(params: ChangePasswordParams): Promise<ChangePasswordResult>;
38894
- /** Instant re-login using stored private key (re-opens the selected workspace too) */
39129
+ /**
39130
+ * Silent re-login with the stored key (and the SSO token for an SSO account); re-opens the
39131
+ * selected workspace. Concurrent calls share one attempt and a success is reused for 5s. The
39132
+ * new token, or `null`. When the server refused it the session is over: `session.clear()` runs
39133
+ * and `onSessionExpired` listeners fire. A login still finishing or an unreachable server
39134
+ * leaves the session alone.
39135
+ */
38895
39136
  relogin(): Promise<string | null>;
38896
39137
  /** Re-open the selected workspace on the server session, without a new login */
38897
39138
  reopenWorkspace(): Promise<boolean>;
39139
+ /**
39140
+ * Seal every workspace key the user holds to this server session, so a session derived from it
39141
+ * (an MCP session) reaches every workspace. Best-effort.
39142
+ */
39143
+ openAllWorkspaces(): Promise<void>;
39144
+ /** Subscribe to "the session could not be recovered" (see `relogin`). Returns an unsubscribe. */
39145
+ onSessionExpired(listener: () => void): () => void;
38898
39146
  };
38899
39147
  /** Crypto utilities */
38900
39148
  crypto: {
@@ -39033,7 +39281,7 @@ declare function createReloginHandler(deps: ReloginDeps): () => Promise<string |
39033
39281
 
39034
39282
  interface ReopenDeps {
39035
39283
  crypto: Pick<CryptoProvider, 'ensureReady' | 'deriveEncryptionKeypair' | 'sealedBoxDecrypt' | 'sealKeyForSession'>;
39036
- sessionStorage: SessionStorageProvider;
39284
+ persistence: SessionPersistence;
39037
39285
  authState: Pick<AuthStateProvider, 'getSelectedWorkspaceId'>;
39038
39286
  getAccessToken(): string | null;
39039
39287
  workspaceKeyRefreshProvider: WorkspaceKeyRefreshProvider;
@@ -39045,5 +39293,27 @@ interface ReopenDeps {
39045
39293
  * Concurrent calls share one in-flight attempt.
39046
39294
  */
39047
39295
  declare function createWorkspaceReopener(deps: ReopenDeps): () => Promise<boolean>;
39296
+ interface OpenAllDeps {
39297
+ crypto: Pick<CryptoProvider, 'ensureReady' | 'sealKeyForSession' | 'fromBase64'>;
39298
+ persistence: SessionPersistence;
39299
+ getAccessToken(): string | null;
39300
+ /** The session's own X25519 key (the token's `sk` claim), which workspace keys are sealed to. */
39301
+ getSessionKey(accessToken: string): string | null;
39302
+ /** The workspace key, unwrapped with the signing key. */
39303
+ unwrapWorkspaceKey(wrappedKey: string, signingPrivateKey: Uint8Array): Uint8Array;
39304
+ listWorkspaces(accessToken: string): Promise<Array<{
39305
+ external_id: string;
39306
+ wrapped_key?: string | null;
39307
+ }> | null>;
39308
+ workspaceOpenProvider: WorkspaceOpenProvider;
39309
+ }
39310
+ /**
39311
+ * Returns `openAllWorkspaces()`: seal every workspace key the user holds to this server session
39312
+ * (`/open` each, sequentially), so a session derived from it (an MCP session copies the browser
39313
+ * session's keys) can reach every workspace. Best-effort: a workspace that fails is logged and
39314
+ * skipped. Sequential on purpose: the server's per-session key store is a read-modify-write, so
39315
+ * parallel opens overwrite each other.
39316
+ */
39317
+ declare function createAllWorkspacesOpener(deps: OpenAllDeps): () => Promise<void>;
39048
39318
 
39049
- export { type $defs, API_PREFIX, type ArbiClient, type ArbiClientOptions, type ArbiClientTransport, type AuthStateProvider, type AutoReloginMiddlewareConfig, type BearerAuthMiddlewareConfig, CALL_KEY_BYTES, CHAT_KEY_BYTES, type ChangePasswordParams, type ChangePasswordRequest, type ChangePasswordResult, type CryptoProvider, ENCRYPTED_RECOVERY_KEY_SIZE, type KeyLoginCredentials, type KeyPair, type LoginCredentials, type LoginParams, type LoginProfile, type LoginProvider, type LoginRequest, type LoginResult, type LoginWithKeyParams, type OfflineSealer, type OfflineSealerOptions, type OnReloginSuccess, type ParsedRecoveryUrl, type PasswordChangeCredentials, RECOVERY_KEY_ERRORS, type RecoveryKeyParams, type RecoveryKeyValidationResult, type RegisterParams, type RegisterRequest, type RegisterResult, type RegistrationCredentials, type ReloginDeps, type ReloginHandler, type ReopenDeps, SECURE_MAIL_KEY_BYTES, type SealedSecureMail, type SecureMailCiphertexts, type SecureMailClaim, type SessionClaims, type SessionData, type SessionKeys, type SessionManager, type SessionState, type SessionStorageProvider, type SsoTokenProvider, type TokenProvider, UNENCRYPTED_RECOVERY_KEY_SIZE, type UserKeypairs, type WebSocketClientMessage, type WebSocketServerMessage, type WorkspaceKeyRefreshProvider, type WorkspaceOpenProvider, type WsAgentDmStatusMessage, type WsAuthMessage, type WsAuthResultMessage, type WsBatchCompleteMessage, type WsChatMessageMessage, type WsChatReadMessage, type WsChatUpdatedMessage, type WsConnectionClosedMessage, type WsConversationMessagePostedMessage, type WsErrorMessage, type WsNotificationResponse, type WsPresenceUpdateMessage, type WsResponseCompleteMessage, type WsTaskUpdateMessage, base64Decode, base64Encode, base64ToBytes, base64UrlToBytes, buildCallFragment, buildWebSocketUrl, bytesToBase64, bytesToBase64Url, canPersistSession, changePassword, clearAllData, clearSession, type components, computeSharedSecret, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createOfflineSealer, createRecoveryFile, createRecoveryUrl, createReloginHandler, createSessionManager, createWorkspaceReopener, decodeCallKey, decodeSecureMailKey, decryptCallTitle, decryptFile, decryptMessage, decryptMessageWithSharedSecret, decryptRecoveryKey, decryptWithChatKey, deriveDirectChatKey, deriveEncryptionKeypairFromSigning, derivePublicKey, encodeCallKey, encryptCallTitle, encryptFile, encryptMessage, encryptMessageWithSharedSecret, encryptRecoveryKey, encryptWithChatKey, encryptionKeypairFromSigningKey, generateCallKey, generateChatKey, generateIdentityKeypair, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRegistrationCredentials, generateUserKeypairs, getRecoveryKeyFilename, getSession, getUserEncryptionKeypair, hasSession, identityFromLoginResponse, initSodium, initializeDatabase, isEncryptedRecoveryKey, isMessageType, openSealedCallKey, openSealedChatKey, openSecureMail, type operations, parseCallFragment, parseRecoveryUrl, parseServerMessage, passwordChangeErrorMessage, type paths, prewarmKeyPairs, readSessionClaims, saveSession, sealCallKey, sealChatKey, sealKeyForSession, sealSecureMail, sealedBoxDecrypt, sealedBoxEncrypt, secureMailClaim, signMessage, unlockIdentityWithPassword, unwrapIdentityKey, unwrapWorkspaceKey, updateWrappedIdentityKey, validateRecoveryKeyFile, type webhooks, wrapIdentityKey };
39319
+ export { type $defs, ACCESS_TOKEN_STORAGE_KEY, API_PREFIX, type ArbiClient, type ArbiClientOptions, type AuthStateProvider, type AutoReloginMiddlewareConfig, type BearerAuthMiddlewareConfig, CALL_KEY_BYTES, CHAT_KEY_BYTES, type CallPeer, type ChangePasswordParams, type ChangePasswordRequest, type ChangePasswordResult, type CryptoProvider, ENCRYPTED_RECOVERY_KEY_SIZE, type KeyLoginCredentials, type KeyPair, type ListedWorkspaceKey, type LoginCredentials, type LoginParams, type LoginProfile, type LoginProvider, type LoginRequest, type LoginResponse, type LoginResult, type LoginWithKeyParams, type OfflineSealer, type OfflineSealerOptions, type OnReloginSuccess, type OpenAllDeps, type ParsedRecoveryUrl, type PasswordChangeCredentials, RECOVERY_KEY_ERRORS, type RecoveryKeyParams, type RecoveryKeyValidationResult, type RegisterParams, type RegisterRequest, type RegisterResult, type RegistrationCredentials, type ReloginDeps, type ReloginFailure, type ReloginHandler, type ReopenDeps, SECURE_MAIL_KEY_BYTES, type SealedSecureMail, type SecureMailCiphertexts, type SecureMailClaim, type SessionClaims, type SessionData, type SessionKeys, type SessionManager, type SessionManagerOptions, type SessionPersistence, type SessionSignIn, type SessionState, type SessionStateStorage, type SessionUser, type SignInHooks, type SsoTokenSource, type StoredSessionState, type TokenProvider, UNENCRYPTED_RECOVERY_KEY_SIZE, type UserKeypairs, type WebSocketClientMessage, type WebSocketServerMessage, type WorkspaceKeyRefreshProvider, type WorkspaceKeys, type WorkspaceOpenProvider, type WsAgentDmStatusMessage, type WsAuthMessage, type WsAuthResultMessage, type WsBatchCompleteMessage, type WsChatMessageMessage, type WsChatReadMessage, type WsChatUpdatedMessage, type WsConnectionClosedMessage, type WsConversationMessagePostedMessage, type WsErrorMessage, type WsNotificationResponse, type WsPresenceUpdateMessage, type WsResponseCompleteMessage, type WsTaskUpdateMessage, authRequestError, base64Decode, base64Encode, base64ToBytes, base64UrlToBytes, browserSessionStateStorage, buildCallFragment, buildCallLink, buildWebSocketUrl, bytesToBase64, bytesToBase64Url, canPersistSession, changePassword, clearAllData, clearSession, type components, computeSharedSecret, createAllWorkspacesOpener, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createOfflineSealer, createRecoveryFile, createRecoveryUrl, createReloginHandler, createSessionManager, createWorkspaceKeys, createWorkspaceReopener, decodeCallKey, decodeSecureMailKey, decryptCallTitle, decryptFile, decryptMessage, decryptMessageWithSharedSecret, decryptRecoveryKey, decryptWithChatKey, deriveDirectChatKey, deriveEncryptionKeypairFromSigning, derivePublicKey, encodeCallKey, encryptCallTitle, encryptFile, encryptMessage, encryptMessageWithSharedSecret, encryptRecoveryKey, encryptWithChatKey, encryptionKeypairFromSigningKey, generateCallKey, generateChatKey, generateIdentityKeypair, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRegistrationCredentials, generateUserKeypairs, getRecoveryKeyFilename, getSession, getUserEncryptionKeypair, hasSession, identityFromLoginResponse, initSodium, initializeDatabase, isEncryptedRecoveryKey, isMessageType, openCallKeyOf, openSealedCallKey, openSealedChatKey, openSecureMail, type operations, parseCallFragment, parseRecoveryUrl, parseServerMessage, passwordChangeErrorMessage, type paths, prewarmKeyPairs, readSessionClaims, saveSession, sealCallKey, sealCallKeyForPeers, sealChatKey, sealKeyForSession, sealSecureMail, sealedBoxDecrypt, sealedBoxEncrypt, secureMailClaim, signMessage, unlockIdentityWithPassword, unwrapIdentityKey, unwrapWorkspaceKey, updateWrappedIdentityKey, validateRecoveryKeyFile, type webhooks, workspaceKeyRequiredOf, wrapIdentityKey };