@arbidocs/sdk 0.3.9 → 0.3.10

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/session.ts","../src/crypto/sodium.ts","../src/crypto/keypairs.ts","../src/crypto/credentials.ts","../src/middleware/bearer-auth.ts","../src/middleware/workspace-key.ts","../src/middleware/auto-relogin.ts","../src/relogin/handler.ts","../src/storage/indexed-db.ts","../src/auth/register.ts","../src/auth/login.ts","../src/auth/logout.ts","../src/auth/change-password.ts","../src/client.ts","../src/websocket.ts"],"names":["sodium","createFetchClient"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * SessionManager - In-memory session state for SDK consumers\n *\n * Replaces Zustand for SDK consumers. Simple in-memory store with subscribe pattern.\n * Implements TokenProvider, WorkspaceKeyProvider, and AuthStateProvider —\n * plugs directly into middleware and relogin handler without any framework.\n */\n\nimport type { TokenProvider, WorkspaceKeyProvider } from './middleware/types'\nimport type { AuthStateProvider } from './relogin/types'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface SessionState {\n accessToken: string | null\n userEmail: string | null\n userExtId: string | null\n selectedWorkspaceId: string | null\n cachedWorkspaceHeaders: Record<string, string>\n isSsoMode: boolean\n isAuth0Authenticated: boolean\n auth0AccessToken: string | null\n}\n\nexport interface SessionManager {\n getState(): Readonly<SessionState>\n setAccessToken(token: string | null): void\n setUser(email: string, extId?: string): void\n setSelectedWorkspace(id: string | null): void\n setCachedWorkspaceHeader(workspaceId: string, header: string): void\n clearWorkspaceHeaders(): void\n getWorkspaceKeyHeader(): string | null\n setSsoState(\n opts: Partial<{\n isSsoMode: boolean\n isAuth0Authenticated: boolean\n auth0AccessToken: string | null\n }>\n ): void\n clear(): void\n subscribe(listener: (state: SessionState) => void): () => void\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nfunction createInitialState(): SessionState {\n return {\n accessToken: null,\n userEmail: null,\n userExtId: null,\n selectedWorkspaceId: null,\n cachedWorkspaceHeaders: {},\n isSsoMode: false,\n isAuth0Authenticated: false,\n auth0AccessToken: null,\n }\n}\n\nexport function createSessionManager(): SessionManager {\n let state: SessionState = createInitialState()\n const listeners = new Set<(state: SessionState) => void>()\n\n function notify() {\n const snapshot = { ...state }\n for (const listener of listeners) {\n listener(snapshot)\n }\n }\n\n return {\n getState() {\n return state\n },\n\n setAccessToken(token: string | null) {\n state = { ...state, accessToken: token }\n notify()\n },\n\n setUser(email: string, extId?: string) {\n state = { ...state, userEmail: email, userExtId: extId ?? state.userExtId }\n notify()\n },\n\n setSelectedWorkspace(id: string | null) {\n state = { ...state, selectedWorkspaceId: id }\n notify()\n },\n\n setCachedWorkspaceHeader(workspaceId: string, header: string) {\n state = {\n ...state,\n cachedWorkspaceHeaders: {\n ...state.cachedWorkspaceHeaders,\n [workspaceId]: header,\n },\n }\n notify()\n },\n\n clearWorkspaceHeaders() {\n state = { ...state, cachedWorkspaceHeaders: {} }\n notify()\n },\n\n getWorkspaceKeyHeader(): string | null {\n const { selectedWorkspaceId, cachedWorkspaceHeaders } = state\n if (!selectedWorkspaceId) return null\n return cachedWorkspaceHeaders[selectedWorkspaceId] ?? null\n },\n\n setSsoState(opts) {\n state = {\n ...state,\n isSsoMode: opts.isSsoMode ?? state.isSsoMode,\n isAuth0Authenticated: opts.isAuth0Authenticated ?? state.isAuth0Authenticated,\n auth0AccessToken:\n opts.auth0AccessToken !== undefined ? opts.auth0AccessToken : state.auth0AccessToken,\n }\n notify()\n },\n\n clear() {\n state = createInitialState()\n notify()\n },\n\n subscribe(listener: (state: SessionState) => void) {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n }\n}\n\n// ============================================================================\n// Provider adapters\n// ============================================================================\n\n/**\n * Create a TokenProvider from a SessionManager\n */\nexport function createTokenProvider(session: SessionManager): TokenProvider {\n return {\n getAccessToken: () => session.getState().accessToken,\n }\n}\n\n/**\n * Create a WorkspaceKeyProvider from a SessionManager\n */\nexport function createWorkspaceKeyProvider(session: SessionManager): WorkspaceKeyProvider {\n return {\n getWorkspaceKeyHeader: () => session.getWorkspaceKeyHeader(),\n }\n}\n\n/**\n * Create an AuthStateProvider from a SessionManager\n */\nexport function createAuthStateProvider(session: SessionManager): AuthStateProvider {\n return {\n getUserEmail: () => session.getState().userEmail,\n\n getSsoState: () => {\n const s = session.getState()\n return {\n isSsoMode: s.isSsoMode,\n isAuth0Authenticated: s.isAuth0Authenticated,\n auth0AccessToken: s.auth0AccessToken,\n }\n },\n\n getSelectedWorkspaceId: () => session.getState().selectedWorkspaceId,\n\n setAccessToken: (token: string) => session.setAccessToken(token),\n\n clearWorkspaceHeaders: () => session.clearWorkspaceHeaders(),\n\n setCachedWorkspaceHeader: (workspaceId: string, header: string) =>\n session.setCachedWorkspaceHeader(workspaceId, header),\n }\n}\n","/**\n * Layer 1: Pure libsodium wrappers\n *\n * All low-level cryptographic operations using libsodium-wrappers-sumo.\n * No application logic — just type-safe wrappers around sodium functions.\n */\n\nimport sodium from 'libsodium-wrappers-sumo'\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\nexport interface KeyPair {\n publicKey: Uint8Array\n secretKey: Uint8Array\n}\n\nexport interface UserKeypairs {\n signingKeyPair: KeyPair // Ed25519 for signing/authentication\n encryptionKeyPair: KeyPair // X25519 derived from Ed25519 for encryption\n}\n\n// ============================================================================\n// libsodium initialization\n// ============================================================================\n\nlet sodiumReady: Promise<void> | null = null\n\n/**\n * Initialize sodium library\n */\nexport async function initSodium(): Promise<void> {\n if (sodiumReady) {\n await sodiumReady\n return\n }\n\n sodiumReady = sodium.ready\n await sodiumReady\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Convert base64 string to Uint8Array\n */\nexport function base64ToBytes(base64String: string): Uint8Array {\n return sodium.from_base64(base64String, sodium.base64_variants.ORIGINAL)\n}\n\n/**\n * Convert Uint8Array to base64 string\n */\nexport function bytesToBase64(bytes: Uint8Array): string {\n return sodium.to_base64(bytes, sodium.base64_variants.ORIGINAL)\n}\n\n/**\n * Base64 encode a Uint8Array (for compatibility with existing code)\n */\nexport function base64Encode(bytes: Uint8Array): string {\n const binString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join('')\n return btoa(binString)\n}\n\n/**\n * Base64 decode to Uint8Array (for compatibility with existing code)\n */\nexport function base64Decode(base64: string): Uint8Array {\n const binString = atob(base64)\n return Uint8Array.from(binString, (m) => m.codePointAt(0) || 0)\n}\n\n// ============================================================================\n// Core Cryptographic Functions\n// ============================================================================\n\n/**\n * Deterministic salt generation for Argon2id\n */\nfunction generateSalt(username: string, deploymentDomain: string): Uint8Array {\n if (!deploymentDomain) {\n throw new Error('Deployment domain must be provided for salt generation')\n }\n const normalized = username.toLowerCase()\n const saltString = `${normalized}|${deploymentDomain}`\n // Use SHA-256 to create a deterministic salt, then take first 16 bytes\n // (Argon2id requires exactly 16 bytes for salt)\n const hash = sodium.crypto_hash_sha256(sodium.from_string(saltString))\n return hash.slice(0, 16) // Return first 16 bytes\n}\n\n/**\n * Generate Ed25519 signing keypair and derive X25519 encryption keypair\n *\n * @param username - User's email/username\n * @param password - User's password\n * @param deploymentDomain - Deployment domain for salt derivation\n * @returns Object with Ed25519 signing keypair and derived X25519 encryption keypair\n */\nexport async function generateKeyPairs(\n username: string,\n password: string,\n deploymentDomain: string\n): Promise<{\n signing: { publicKey: Uint8Array; privateKey: Uint8Array; publicKeyBase64: string }\n encryption: { publicKey: Uint8Array; privateKey: Uint8Array; publicKeyBase64: string }\n}> {\n await initSodium()\n\n if (!deploymentDomain) {\n throw new Error('Deployment domain not available. Cannot generate keys.')\n }\n\n // Generate deterministic salt for key derivation\n const salt = generateSalt(username, deploymentDomain)\n\n // Derive seed using Argon2id\n const seed = sodium.crypto_pwhash(\n 32, // 32 bytes for Ed25519 seed\n password,\n salt,\n sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,\n sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE,\n sodium.crypto_pwhash_ALG_ARGON2ID13\n )\n\n // Generate Ed25519 signing keypair from seed\n const signingKeyPair = sodium.crypto_sign_seed_keypair(seed)\n\n // Derive X25519 encryption keypair from Ed25519 keypair\n const encryptionPublicKey = sodium.crypto_sign_ed25519_pk_to_curve25519(signingKeyPair.publicKey)\n const encryptionPrivateKey = sodium.crypto_sign_ed25519_sk_to_curve25519(\n signingKeyPair.privateKey\n )\n\n return {\n signing: {\n publicKey: signingKeyPair.publicKey,\n privateKey: signingKeyPair.privateKey,\n publicKeyBase64: sodium.to_base64(signingKeyPair.publicKey, sodium.base64_variants.ORIGINAL),\n },\n encryption: {\n publicKey: encryptionPublicKey,\n privateKey: encryptionPrivateKey,\n publicKeyBase64: sodium.to_base64(encryptionPublicKey, sodium.base64_variants.ORIGINAL),\n },\n }\n}\n\n/**\n * Sign a message with Ed25519 private key\n *\n * @param message - Message to sign (string)\n * @param privateKey - Ed25519 private key (64 bytes)\n * @returns Base64-encoded signature\n */\nexport function signMessage(message: string, privateKey: Uint8Array): string {\n const messageBytes = sodium.from_string(message)\n const signature = sodium.crypto_sign_detached(messageBytes, privateKey)\n return base64Encode(signature)\n}\n\n/**\n * Create Workspace-Key header for API requests using SealedBox\n */\nexport async function createWorkspaceKeyHeader(\n workspaceKey: Uint8Array,\n serverSessionPublicKey: Uint8Array\n): Promise<string> {\n await initSodium()\n\n // Encrypt workspace key using SealedBox (anonymous encryption)\n const encryptedKey = sealedBoxEncrypt(workspaceKey, serverSessionPublicKey)\n\n // Return just the encrypted key value\n return encryptedKey\n}\n\n/**\n * Decrypt data using SealedBox (anonymous decryption).\n *\n * @param encryptedBase64 - Base64-encoded SealedBox encrypted data\n * @param userEncryptionPrivateKey - User's X25519 private key (32 bytes)\n * @returns Decrypted data\n */\nexport function sealedBoxDecrypt(\n encryptedBase64: string,\n userEncryptionPrivateKey: Uint8Array\n): Uint8Array {\n const encrypted = base64ToBytes(encryptedBase64)\n\n // Get the public key from private key for SealedBox\n const publicKey = sodium.crypto_scalarmult_base(userEncryptionPrivateKey)\n\n // Decrypt using SealedBox\n const decrypted = sodium.crypto_box_seal_open(encrypted, publicKey, userEncryptionPrivateKey)\n\n return decrypted\n}\n\n/**\n * Encrypt data using SealedBox (anonymous encryption).\n *\n * @param message - Data to encrypt\n * @param publicKey - Recipient's X25519 public key (32 bytes)\n * @returns Base64-encoded encrypted data\n */\nexport function sealedBoxEncrypt(message: Uint8Array, publicKey: Uint8Array): string {\n // Encrypt using SealedBox\n const encrypted = sodium.crypto_box_seal(message, publicKey)\n\n return bytesToBase64(encrypted)\n}\n\n/**\n * Derive X25519 public key from X25519 private key\n * Used for instant re-login when we have stored private key\n */\nexport function derivePublicKey(privateKey: Uint8Array): Uint8Array {\n return sodium.crypto_scalarmult_base(privateKey)\n}\n\n/**\n * Derive X25519 keypair from Ed25519 keypair\n * Used when we have stored Ed25519 keys and need X25519 for encryption\n */\nexport function deriveEncryptionKeypairFromSigning(signingKeyPair: KeyPair): KeyPair {\n const encryptionPublicKey = sodium.crypto_sign_ed25519_pk_to_curve25519(signingKeyPair.publicKey)\n const encryptionPrivateKey = sodium.crypto_sign_ed25519_sk_to_curve25519(signingKeyPair.secretKey)\n return {\n publicKey: encryptionPublicKey,\n secretKey: encryptionPrivateKey,\n }\n}\n\n// ============================================================================\n// E2E Message Encryption (ECDH + Symmetric)\n// ============================================================================\n\n/**\n * Precompute shared secret for ECDH encryption.\n *\n * Call once per contact, cache for efficiency.\n *\n * @param theirPublicKeyBase64 - Other party's X25519 public key (base64)\n * @param myPrivateKey - Your X25519 private key (Uint8Array)\n * @returns 32-byte shared secret (Uint8Array)\n */\nexport async function computeSharedSecret(\n theirPublicKeyBase64: string,\n myPrivateKey: Uint8Array\n): Promise<Uint8Array> {\n await initSodium()\n const theirPublicKey = base64ToBytes(theirPublicKeyBase64)\n return sodium.crypto_box_beforenm(theirPublicKey, myPrivateKey)\n}\n\n/**\n * Encrypt a message using precomputed shared secret.\n *\n * @param message - Plaintext message to encrypt\n * @param sharedSecret - Precomputed 32-byte shared secret\n * @returns Base64-encoded ciphertext (nonce prepended)\n */\nexport async function encryptMessageWithSharedSecret(\n message: string,\n sharedSecret: Uint8Array\n): Promise<string> {\n await initSodium()\n\n const messageBytes = sodium.from_string(message)\n const nonce = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES)\n const ciphertext = sodium.crypto_box_easy_afternm(messageBytes, nonce, sharedSecret)\n\n const combined = new Uint8Array(nonce.length + ciphertext.length)\n combined.set(nonce, 0)\n combined.set(ciphertext, nonce.length)\n\n return bytesToBase64(combined)\n}\n\n/**\n * Decrypt a message using precomputed shared secret.\n *\n * @param encryptedBase64 - Base64-encoded ciphertext (nonce prepended)\n * @param sharedSecret - Precomputed 32-byte shared secret\n * @returns Decrypted plaintext message\n */\nexport async function decryptMessageWithSharedSecret(\n encryptedBase64: string,\n sharedSecret: Uint8Array\n): Promise<string> {\n await initSodium()\n\n const combined = base64ToBytes(encryptedBase64)\n const nonce = combined.slice(0, sodium.crypto_box_NONCEBYTES)\n const ciphertext = combined.slice(sodium.crypto_box_NONCEBYTES)\n const decrypted = sodium.crypto_box_open_easy_afternm(ciphertext, nonce, sharedSecret)\n\n return sodium.to_string(decrypted)\n}\n\n/**\n * Encrypt a message for a specific recipient using ECDH (X25519 + XSalsa20-Poly1305).\n *\n * @param message - Plaintext message to encrypt\n * @param recipientPublicKeyBase64 - Recipient's X25519 public key (base64)\n * @param senderPrivateKey - Sender's X25519 private key (Uint8Array)\n * @returns Base64-encoded ciphertext (nonce prepended)\n */\nexport async function encryptMessage(\n message: string,\n recipientPublicKeyBase64: string,\n senderPrivateKey: Uint8Array\n): Promise<string> {\n await initSodium()\n\n const recipientPublicKey = base64ToBytes(recipientPublicKeyBase64)\n const messageBytes = sodium.from_string(message)\n\n // Generate random nonce\n const nonce = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES)\n\n // Encrypt using crypto_box (ECDH + XSalsa20-Poly1305)\n const ciphertext = sodium.crypto_box_easy(\n messageBytes,\n nonce,\n recipientPublicKey,\n senderPrivateKey\n )\n\n // Prepend nonce to ciphertext for transmission\n const combined = new Uint8Array(nonce.length + ciphertext.length)\n combined.set(nonce, 0)\n combined.set(ciphertext, nonce.length)\n\n return bytesToBase64(combined)\n}\n\n/**\n * Decrypt a message from a specific sender using ECDH (X25519 + XSalsa20-Poly1305).\n *\n * @param encryptedBase64 - Base64-encoded ciphertext (nonce prepended)\n * @param senderPublicKeyBase64 - Sender's X25519 public key (base64)\n * @param recipientPrivateKey - Recipient's X25519 private key (Uint8Array)\n * @returns Decrypted plaintext message\n * @throws Error if decryption fails (wrong keys or tampered message)\n */\nexport async function decryptMessage(\n encryptedBase64: string,\n senderPublicKeyBase64: string,\n recipientPrivateKey: Uint8Array\n): Promise<string> {\n await initSodium()\n\n const combined = base64ToBytes(encryptedBase64)\n const senderPublicKey = base64ToBytes(senderPublicKeyBase64)\n\n // Extract nonce and ciphertext\n const nonce = combined.slice(0, sodium.crypto_box_NONCEBYTES)\n const ciphertext = combined.slice(sodium.crypto_box_NONCEBYTES)\n\n // Decrypt using crypto_box_open (ECDH + XSalsa20-Poly1305)\n const decrypted = sodium.crypto_box_open_easy(\n ciphertext,\n nonce,\n senderPublicKey,\n recipientPrivateKey\n )\n\n return sodium.to_string(decrypted)\n}\n","/**\n * Layer 2: User keypair generation\n *\n * Generates Ed25519 signing and X25519 encryption keypairs from email + password.\n * Takes `deploymentDomain` as an explicit parameter (no window.RUNTIME_CONFIG).\n */\n\nimport { generateKeyPairs, type KeyPair, type UserKeypairs } from './sodium'\n\n/**\n * Generate user keypairs deterministically using Argon2id.\n *\n * Creates Ed25519 signing keypair and derives X25519 encryption keypair.\n * Ed25519 is used for authentication (signing), X25519 for encryption.\n *\n * This is a zero-knowledge system - the server never sees private keys.\n *\n * @param username - User's email/username\n * @param password - User's password\n * @param deploymentDomain - Deployment domain (used for salt derivation)\n * @returns Object with Ed25519 signing keypair and X25519 encryption keypair\n */\nexport async function generateUserKeypairs(\n username: string,\n password: string,\n deploymentDomain: string\n): Promise<UserKeypairs> {\n if (!deploymentDomain) {\n throw new Error('Deployment domain must be provided. Cannot generate keypairs.')\n }\n\n // Generate keypairs using the libsodium implementation\n const keypairs = await generateKeyPairs(username, password, deploymentDomain)\n\n const signingKeyPair: KeyPair = {\n publicKey: keypairs.signing.publicKey,\n secretKey: keypairs.signing.privateKey,\n }\n\n const encryptionKeyPair: KeyPair = {\n publicKey: keypairs.encryption.publicKey,\n secretKey: keypairs.encryption.privateKey,\n }\n\n return {\n signingKeyPair,\n encryptionKeyPair,\n }\n}\n","/**\n * Layer 3: High-level credential generation\n *\n * Generates registration, login, and password-change credentials.\n * Uses inline type definitions (structurally identical to OpenAPI schema types)\n * to avoid coupling the crypto module to the schema file.\n */\n\nimport { signMessage, base64Encode } from './sodium'\nimport { generateUserKeypairs } from './keypairs'\n\n// ============================================================================\n// Inline types (structurally identical to OpenAPI schema equivalents)\n// ============================================================================\n\nexport interface RegisterRequest {\n email: string\n signing_key: string\n verification_credential: string\n given_name?: string | null\n family_name?: string | null\n picture?: string | null\n}\n\nexport interface LoginRequest {\n email: string\n signature: string\n timestamp: number\n sso_token?: string | null\n}\n\nexport interface ChangePasswordRequest {\n signature: string\n timestamp: number\n new_signing_key: string\n rewrapped_workspace_keys: Record<string, string>\n}\n\n// ============================================================================\n// Credential types\n// ============================================================================\n\n/**\n * Credentials returned by generate functions.\n * Contains both the backend request AND client-side private keys.\n * Private keys never leave the client.\n */\nexport interface RegistrationCredentials {\n request: RegisterRequest\n signingPrivateKey: Uint8Array\n}\n\nexport interface LoginCredentials {\n request: LoginRequest\n signingPrivateKey: Uint8Array\n}\n\nexport interface PasswordChangeCredentials {\n request: Omit<ChangePasswordRequest, 'rewrapped_workspace_keys'>\n newSigningPrivateKey: Uint8Array\n}\n\n// ============================================================================\n// Credential generation functions\n// ============================================================================\n\n/**\n * Generate registration credentials with Ed25519 signing key.\n *\n * Creates Ed25519 keypair deterministically from email + password.\n * Server receives the Ed25519 public key (signing_key) and derives X25519 from it.\n *\n * @param registrationData - Registration fields (signing_key will be generated)\n * @param password - User's password (to generate keypair)\n * @param deploymentDomain - Deployment domain for salt derivation\n * @returns RegistrationCredentials with request body and private key (kept separate)\n */\nexport async function generateRegistrationCredentials(\n registrationData: Omit<RegisterRequest, 'signing_key'>,\n password: string,\n deploymentDomain: string\n): Promise<RegistrationCredentials> {\n const { signingKeyPair } = await generateUserKeypairs(\n registrationData.email,\n password,\n deploymentDomain\n )\n\n const request: RegisterRequest = {\n ...registrationData,\n signing_key: base64Encode(signingKeyPair.publicKey),\n }\n\n return { request, signingPrivateKey: signingKeyPair.secretKey }\n}\n\n/**\n * Generate login credentials with Ed25519 signature authentication.\n *\n * Derives Ed25519 keypair from email + password and signs \"email|timestamp\".\n * Server verifies signature using stored Ed25519 public key.\n *\n * @param loginData - Login fields (signature and timestamp will be generated)\n * @param password - User's password (to regenerate keypair)\n * @param deploymentDomain - Deployment domain for salt derivation\n * @returns LoginCredentials with request body and private key (kept separate)\n */\nexport async function generateLoginCredentials(\n loginData: Omit<LoginRequest, 'signature' | 'timestamp'>,\n password: string,\n deploymentDomain: string\n): Promise<LoginCredentials> {\n const { signingKeyPair } = await generateUserKeypairs(loginData.email, password, deploymentDomain)\n\n const timestamp = Math.floor(Date.now() / 1000)\n const message = `${loginData.email}|${timestamp}`\n const signature = signMessage(message, signingKeyPair.secretKey)\n\n const request: LoginRequest = {\n ...loginData,\n signature,\n timestamp,\n }\n\n return { request, signingPrivateKey: signingKeyPair.secretKey }\n}\n\n/**\n * Generate login credentials using an existing signing key (for password recovery).\n *\n * Bypasses password derivation and uses the provided key directly.\n *\n * @param loginData - Login fields (signature and timestamp will be generated)\n * @param signingPrivateKey - The Ed25519 signing private key (64 bytes)\n * @returns LoginCredentials with request body and private key\n */\nexport function generateLoginCredentialsFromKey(\n loginData: Omit<LoginRequest, 'signature' | 'timestamp'>,\n signingPrivateKey: Uint8Array\n): LoginCredentials {\n if (signingPrivateKey.length !== 64) {\n throw new Error('Invalid signing key: must be exactly 64 bytes')\n }\n\n const timestamp = Math.floor(Date.now() / 1000)\n const message = `${loginData.email}|${timestamp}`\n const signature = signMessage(message, signingPrivateKey)\n\n const request: LoginRequest = {\n ...loginData,\n signature,\n timestamp,\n }\n\n return { request, signingPrivateKey }\n}\n\n/**\n * Generate change password credentials with Ed25519 signature authentication.\n *\n * Signs \"email|timestamp\" with current Ed25519 key to prove knowledge of current password.\n * Provides new Ed25519 public key derived from new password.\n *\n * @param email - User's email address\n * @param currentPassword - Current password (to sign with current key)\n * @param newPassword - New password (to generate new key)\n * @param deploymentDomain - Deployment domain for salt derivation\n * @returns PasswordChangeCredentials with request body and new private key (kept separate)\n */\nexport async function generatePasswordChangeCredentials(\n email: string,\n currentPassword: string,\n newPassword: string,\n deploymentDomain: string\n): Promise<PasswordChangeCredentials> {\n const currentKeypairs = await generateUserKeypairs(email, currentPassword, deploymentDomain)\n const newKeypairs = await generateUserKeypairs(email, newPassword, deploymentDomain)\n\n const timestamp = Math.floor(Date.now() / 1000)\n const message = `${email}|${timestamp}`\n const signature = signMessage(message, currentKeypairs.signingKeyPair.secretKey)\n\n const request: Omit<ChangePasswordRequest, 'rewrapped_workspace_keys'> = {\n signature,\n timestamp,\n new_signing_key: base64Encode(newKeypairs.signingKeyPair.publicKey),\n }\n\n return { request, newSigningPrivateKey: newKeypairs.signingKeyPair.secretKey }\n}\n\n/**\n * Generate password change credentials for recovery mode.\n *\n * Used when the user is recovering their account with a recovery key.\n * Signs with the existing signing key (from recovery) instead of deriving from password.\n *\n * @param email - User's email address\n * @param currentSigningKey - Current signing key (from recovery)\n * @param newPassword - New password (to generate new key)\n * @param deploymentDomain - Deployment domain for salt derivation\n * @returns PasswordChangeCredentials with request body and new private key\n */\nexport async function generateRecoveryPasswordChangeCredentials(\n email: string,\n currentSigningKey: Uint8Array,\n newPassword: string,\n deploymentDomain: string\n): Promise<PasswordChangeCredentials> {\n const newKeypairs = await generateUserKeypairs(email, newPassword, deploymentDomain)\n\n const timestamp = Math.floor(Date.now() / 1000)\n const message = `${email}|${timestamp}`\n const signature = signMessage(message, currentSigningKey)\n\n const request: Omit<ChangePasswordRequest, 'rewrapped_workspace_keys'> = {\n signature,\n timestamp,\n new_signing_key: base64Encode(newKeypairs.signingKeyPair.publicKey),\n }\n\n return { request, newSigningPrivateKey: newKeypairs.signingKeyPair.secretKey }\n}\n","/**\n * Bearer Auth Middleware\n *\n * Injects Authorization header on every request using the provided TokenProvider.\n */\n\nimport type { Middleware } from 'openapi-fetch'\nimport type { BearerAuthMiddlewareConfig } from './types'\n\nexport function createBearerAuthMiddleware(config: BearerAuthMiddlewareConfig): Middleware {\n return {\n async onRequest({ request }) {\n const accessToken = config.tokenProvider.getAccessToken()\n if (accessToken) {\n request.headers.set('Authorization', `Bearer ${accessToken}`)\n }\n return request\n },\n }\n}\n","/**\n * Workspace Key Middleware\n *\n * Injects Workspace-Key header on workspace-scoped requests.\n * URL matching is data-driven via WorkspaceKeyUrlConfig.\n */\n\nimport type { Middleware } from 'openapi-fetch'\nimport type { WorkspaceKeyMiddlewareConfig, WorkspaceKeyUrlConfig } from './types'\n\n/**\n * Check if a URL needs the Workspace-Key header based on URL patterns.\n */\nexport function needsWorkspaceKey(url: string, urlConfig: WorkspaceKeyUrlConfig): boolean {\n // Skip if it matches an exclude pattern\n if (urlConfig.excludePatterns.some((pattern) => url.includes(pattern))) {\n return false\n }\n\n // Include if it matches an include pattern\n return urlConfig.includePatterns.some((pattern) => url.includes(pattern))\n}\n\nexport function createWorkspaceKeyMiddleware(config: WorkspaceKeyMiddlewareConfig): Middleware {\n return {\n async onRequest({ request }) {\n if (needsWorkspaceKey(request.url, config.urlConfig)) {\n const workspaceHeader = config.workspaceKeyProvider.getWorkspaceKeyHeader()\n if (workspaceHeader) {\n request.headers.set('Workspace-Key', workspaceHeader)\n }\n }\n return request\n },\n }\n}\n","/**\n * Auto Re-login Middleware\n *\n * Handles 401 and 400 responses by triggering re-login and retrying the request.\n * Framework-agnostic — the actual re-login logic is provided via ReloginHandler.\n */\n\nimport type { Middleware } from 'openapi-fetch'\nimport type { AutoReloginMiddlewareConfig } from './types'\n\nexport function createAutoReloginMiddleware(config: AutoReloginMiddlewareConfig): Middleware {\n return {\n async onResponse({ response, request }) {\n // Handle 400 errors on protected endpoints - try instant re-login once\n if (response.status === 400) {\n const isSafeMethod = ['GET', 'HEAD', 'DELETE'].includes(request.method)\n\n if (isSafeMethod) {\n console.info('[API] 400 error on protected endpoint - triggering instant re-login')\n const newToken = await config.reloginHandler()\n if (newToken) {\n const newRequest = request.clone()\n newRequest.headers.set('Authorization', `Bearer ${newToken}`)\n console.info('[API] Retrying request after re-login')\n return fetch(newRequest)\n }\n }\n }\n\n if (response.status === 401) {\n const excludePatterns = config.reloginExcludePatterns ?? []\n const isExcluded = excludePatterns.some((pattern) => request.url.includes(pattern))\n\n // Retry ALL requests after re-login, not just safe methods\n if (!isExcluded) {\n const newToken = await config.reloginHandler()\n if (newToken) {\n try {\n const newRequest = request.clone()\n newRequest.headers.set('Authorization', `Bearer ${newToken}`)\n\n console.info('[API] Retrying request after re-login:', request.method, request.url)\n return fetch(newRequest)\n } catch (cloneError) {\n // If cloning fails (rare - only for streaming requests), notify caller\n console.warn('[API] Could not clone request for retry:', cloneError)\n config.onRetryCloneFailed?.()\n }\n }\n }\n }\n\n return response\n },\n }\n}\n","/**\n * Re-login Handler Factory\n *\n * Framework-agnostic instant re-login using stored private key.\n * All app-specific dependencies (state management, crypto, storage,\n * API transport) are injected via provider interfaces.\n *\n * Zero external dependencies beyond TypeScript types.\n */\n\nimport type { ReloginDeps } from './types'\n\n/**\n * Create a re-login handler with injected dependencies.\n *\n * Returns a function: `() => Promise<string | null>`\n * Resolves to the new access token, or null on failure.\n *\n * Includes debounce protection: if multiple 401s occur simultaneously,\n * they all wait for the same re-login promise.\n */\nexport function createReloginHandler(deps: ReloginDeps): () => Promise<string | null> {\n let reloginPromise: Promise<string | null> | null = null\n\n return function instantReLogin(): Promise<string | null> {\n if (reloginPromise) {\n console.info('[API] Re-login already in progress, waiting...')\n return reloginPromise\n }\n\n reloginPromise = (async () => {\n try {\n await deps.crypto.ensureReady()\n\n const userEmail = deps.authState.getUserEmail()\n if (!userEmail) {\n console.warn('[API] No user email found for instant re-login')\n return null\n }\n\n const session = await deps.sessionStorage.getSession()\n if (!session) {\n console.warn('[API] No session found for instant re-login')\n return null\n }\n\n // Derive encryption key from signing key (for workspace key decryption)\n // Ed25519 secret key is 64 bytes: [32-byte seed][32-byte public key]\n const ed25519PublicKey = session.signingPrivateKey.slice(32, 64)\n const encryptionKeyPair = deps.crypto.deriveEncryptionKeypair({\n publicKey: ed25519PublicKey,\n secretKey: session.signingPrivateKey,\n })\n\n // Create timestamp and signature for login\n const timestamp = Math.floor(Date.now() / 1000)\n const message = `${userEmail}|${timestamp}`\n const signature = deps.crypto.signMessage(message, session.signingPrivateKey)\n\n console.info('[API] Attempting instant re-login')\n\n // SSO token handling\n const ssoState = deps.authState.getSsoState()\n console.info('[API] Re-login SSO mode:', ssoState.isSsoMode)\n console.info('[API] Auth0 authenticated:', ssoState.isAuth0Authenticated)\n console.info('[API] Persisted Auth0 token available:', !!ssoState.auth0AccessToken)\n\n const isSsoAccount =\n ssoState.isSsoMode || ssoState.isAuth0Authenticated || !!ssoState.auth0AccessToken\n\n // Try to get SSO token from the injected provider\n let ssoToken: string | null = null\n\n if (deps.ssoTokenProvider) {\n console.info('[API] SSO token provider available: true')\n try {\n ssoToken = await deps.ssoTokenProvider.getToken()\n console.info(\n '[API] Got SSO token from provider:',\n ssoToken ? 'yes (length: ' + ssoToken.length + ')' : 'no'\n )\n } catch (error) {\n console.error('[API] Failed to get SSO token from provider:', error)\n }\n } else {\n console.info('[API] SSO token provider available: false')\n }\n\n // Fallback to persisted token\n if (!ssoToken && ssoState.auth0AccessToken) {\n ssoToken = ssoState.auth0AccessToken\n console.info(\n '[API] Using persisted SSO token (length:',\n ssoToken.length,\n ') - may be expired'\n )\n }\n\n if (!ssoToken && isSsoAccount) {\n console.warn('[API] SSO account requires token but none available - aborting re-login')\n return null\n }\n\n // Perform login via injected provider\n const loginResult = await deps.loginProvider.login({\n email: userEmail,\n signature,\n timestamp,\n ssoToken: ssoToken ?? undefined,\n })\n\n if (!loginResult) {\n console.warn('[API] Instant re-login failed')\n return null\n }\n\n // Save new session key (so it survives page reload)\n await deps.sessionStorage.saveSession({\n signingPrivateKey: session.signingPrivateKey,\n serverSessionKey: loginResult.sessionKey,\n userExtId: loginResult.userExtId,\n })\n\n // Notify consumers (e.g. cache update)\n deps.onReloginSuccess?.({\n email: userEmail,\n accessToken: loginResult.accessToken,\n userExtId: loginResult.userExtId,\n serverSessionKey: loginResult.sessionKey,\n })\n\n deps.authState.setAccessToken(loginResult.accessToken)\n\n // Clear cached workspace headers — they were encrypted with the old session key\n deps.authState.clearWorkspaceHeaders()\n\n // Re-open currently selected workspace to get a workspace-scoped JWT\n const selectedWorkspaceId = deps.authState.getSelectedWorkspaceId()\n if (selectedWorkspaceId) {\n try {\n const wrappedKey = await deps.workspaceKeyRefreshProvider.getWrappedKey(\n loginResult.accessToken,\n selectedWorkspaceId\n )\n\n if (wrappedKey) {\n // Decrypt workspace key with user's encryption key\n const workspaceKey = deps.crypto.sealedBoxDecrypt(\n wrappedKey,\n encryptionKeyPair.secretKey\n )\n\n // Create encrypted key with NEW server session key\n const encryptedWorkspaceKey = await deps.crypto.createWorkspaceKeyHeader(\n workspaceKey,\n loginResult.sessionKey\n )\n\n // Cache the encrypted key (for copy operations / opened flag)\n deps.authState.setCachedWorkspaceHeader(selectedWorkspaceId, encryptedWorkspaceKey)\n\n // Call /open to get workspace-scoped JWT\n if (deps.workspaceOpenProvider) {\n const workspaceJwt = await deps.workspaceOpenProvider.openWorkspace(\n loginResult.accessToken,\n selectedWorkspaceId,\n encryptedWorkspaceKey\n )\n if (workspaceJwt) {\n deps.authState.setAccessToken(workspaceJwt)\n console.info('[API] Workspace-scoped JWT obtained after re-login')\n }\n }\n }\n } catch (error) {\n console.error('[API] Failed to re-open workspace after re-login:', error)\n }\n }\n\n console.info('[API] Re-login successful')\n return loginResult.accessToken\n } catch (error) {\n console.error('[API] Instant re-login error:', error)\n return null\n } finally {\n reloginPromise = null\n }\n })()\n\n return reloginPromise\n }\n}\n","/**\n * storage.ts - IndexedDB Storage Module\n *\n * Handles persistent storage of cryptographic keys and session data.\n *\n * Storage Strategy (with encryption-at-rest):\n * - Private keys encrypted with non-extractable Web Crypto AES-GCM key\n * - Wrapping key stored as opaque CryptoKey object (can't be exported)\n * - Session data persists across page refreshes\n *\n * Database Schema:\n * - Store: 'session' - User session data (encrypted private key only)\n * - Store: 'wrapping-key' - Non-extractable CryptoKey for encrypting private keys\n *\n * Security Model:\n * - Passive attacks (reading IndexedDB) get encrypted data + opaque CryptoKey\n * - Active attacks (calling decrypt) can still access keys (XSS with code execution)\n * - Defense-in-depth: Requires active XSS, not just storage access\n *\n * Ported from: /home/dev/ARBI/src/static/js/storage.js\n */\n\nconst DB_NAME = 'arbi-crypto'\nconst DB_VERSION = 2 // Incremented for new wrapping-key store\n\nlet db: IDBDatabase | null = null\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * SessionData in IndexedDB - PERSISTED ENCRYPTED DATA\n * Everything needed to resume session without re-login:\n * - signingPrivateKey: Ed25519 private key (64 bytes, encrypted at rest)\n * Used for authentication (signing). X25519 encryption key is derived from this.\n * - serverSessionKey: Server session key for workspace key encryption (encrypted at rest)\n * - userExtId: User external ID (not sensitive, stored in plain text)\n *\n * Note: accessToken is stored in Zustand (persisted separately), not here.\n */\nexport interface SessionData {\n signingPrivateKey: Uint8Array // Ed25519 (64 bytes) - X25519 derived from this\n serverSessionKey?: Uint8Array\n userExtId?: string\n}\n\n/**\n * How session is stored in IndexedDB (with ALL sensitive data encrypted)\n */\ninterface StoredSession {\n id: string\n encryptedSigningPrivateKey: Uint8Array\n signingPrivateKeyIV: Uint8Array\n encryptedServerSessionKey?: Uint8Array\n serverSessionKeyIV?: Uint8Array\n userExtId?: string\n timestamp: number\n}\n\ninterface WrappingKeyData {\n id: string\n key: CryptoKey\n created: number\n}\n\n// ============================================================================\n// Database Initialization\n// ============================================================================\n\n/**\n * Initialize IndexedDB database.\n *\n * Creates two object stores:\n * - 'session': Stores user session data (with encrypted private key)\n * - 'wrapping-key': Stores non-extractable CryptoKey for key encryption\n */\nexport async function initializeDatabase(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION)\n\n request.onerror = () => {\n console.error('[STORAGE] Failed to open IndexedDB:', request.error)\n reject(request.error)\n }\n\n request.onsuccess = () => {\n db = request.result\n resolve(db)\n }\n\n request.onupgradeneeded = (event) => {\n const database = (event.target as IDBOpenDBRequest).result\n\n // Create 'session' store if it doesn't exist\n if (!database.objectStoreNames.contains('session')) {\n database.createObjectStore('session', { keyPath: 'id' })\n }\n\n // Create 'wrapping-key' store if it doesn't exist (v2+)\n if (!database.objectStoreNames.contains('wrapping-key')) {\n database.createObjectStore('wrapping-key', { keyPath: 'id' })\n }\n }\n })\n}\n\n/**\n * Ensure database is initialized before operations.\n */\nasync function ensureDatabase(): Promise<void> {\n if (!db) {\n await initializeDatabase()\n }\n}\n\n// ============================================================================\n// Wrapping Key Management (Web Crypto Non-Extractable Keys)\n// ============================================================================\n\n/**\n * Generate or retrieve the non-extractable wrapping key.\n *\n * This key is used to encrypt private keys before storing in IndexedDB.\n * - Generated once per browser (survives page refreshes)\n * - Stored as opaque CryptoKey object in IndexedDB\n * - Non-extractable: XSS can't dump the raw key bytes\n * - Can still be used for encrypt/decrypt operations\n *\n * @returns Non-extractable AES-GCM key\n */\nasync function getOrCreateWrappingKey(): Promise<CryptoKey> {\n await ensureDatabase()\n\n if (!db) {\n throw new Error('Database not initialized')\n }\n\n return new Promise((resolve, reject) => {\n if (!db) {\n reject(new Error('Database not initialized'))\n return\n }\n\n const transaction = db.transaction(['wrapping-key'], 'readwrite')\n const store = transaction.objectStore('wrapping-key')\n const request = store.get('master')\n\n request.onsuccess = () => {\n const result = request.result as WrappingKeyData | undefined\n\n if (result?.key) {\n resolve(result.key)\n } else {\n // Generate new non-extractable wrapping key\n // We need to generate the key and store it, but the transaction will auto-commit\n // after this callback. So we need to open a NEW transaction for the put.\n crypto.subtle\n .generateKey(\n {\n name: 'AES-GCM',\n length: 256,\n },\n false, // ❌ NON-EXTRACTABLE - Can't be exported!\n ['encrypt', 'decrypt']\n )\n .then((key) => {\n // Open a NEW transaction to store the key\n if (!db) {\n reject(new Error('Database not initialized'))\n return\n }\n\n const putTransaction = db.transaction(['wrapping-key'], 'readwrite')\n const putStore = putTransaction.objectStore('wrapping-key')\n const putRequest = putStore.put({\n id: 'master',\n key: key,\n created: Date.now(),\n } as WrappingKeyData)\n\n putRequest.onsuccess = () => {\n resolve(key)\n }\n\n putRequest.onerror = () => {\n reject(new Error('Failed to store wrapping key'))\n }\n })\n .catch((error) => {\n const errorMsg = error instanceof Error ? error.message : String(error)\n reject(new Error(`Failed to generate wrapping key: ${errorMsg}`))\n })\n }\n }\n\n request.onerror = () => {\n reject(new Error('Failed to retrieve wrapping key from IndexedDB'))\n }\n })\n}\n\n/**\n * Encrypt data using the non-extractable wrapping key.\n *\n * @param data - Data to encrypt\n * @returns Encrypted data and IV\n */\nasync function encryptWithWrappingKey(\n data: Uint8Array\n): Promise<{ ciphertext: Uint8Array; iv: Uint8Array }> {\n const wrappingKey = await getOrCreateWrappingKey()\n\n // Generate random IV for AES-GCM\n const iv = crypto.getRandomValues(new Uint8Array(12))\n\n // Encrypt the data\n const ciphertext = await crypto.subtle.encrypt(\n {\n name: 'AES-GCM',\n iv: iv,\n },\n wrappingKey,\n data as BufferSource\n )\n\n return {\n ciphertext: new Uint8Array(ciphertext),\n iv: iv,\n }\n}\n\n/**\n * Decrypt data using the non-extractable wrapping key.\n *\n * @param ciphertext - Encrypted data\n * @param iv - Initialization vector\n * @returns Decrypted data\n */\nasync function decryptWithWrappingKey(ciphertext: Uint8Array, iv: Uint8Array): Promise<Uint8Array> {\n const wrappingKey = await getOrCreateWrappingKey()\n\n const decrypted = await crypto.subtle.decrypt(\n {\n name: 'AES-GCM',\n iv: iv as BufferSource,\n },\n wrappingKey,\n ciphertext as BufferSource\n )\n\n return new Uint8Array(decrypted)\n}\n\n// ============================================================================\n// Session Storage\n// ============================================================================\n\n/**\n * Store session data in IndexedDB (ALL data encrypted at rest).\n *\n * Stores everything needed to resume session without re-login:\n * - signingPrivateKey: User's Ed25519 private key (ENCRYPTED)\n * - serverSessionKey: Server session key (ENCRYPTED)\n * - userExtId: User external ID (plain text, not sensitive)\n *\n * Note: accessToken is NOT stored here - it's in Zustand (persisted separately).\n *\n * @param sessionData - Complete session data to persist\n */\nexport async function saveSession(sessionData: SessionData): Promise<void> {\n await ensureDatabase()\n\n if (!db) {\n throw new Error('Database not initialized')\n }\n\n try {\n // Encrypt the signing private key (required)\n const encryptedSigningKey = await encryptWithWrappingKey(sessionData.signingPrivateKey)\n\n // Encrypt optional fields if present\n let encryptedServerSessionKey: { ciphertext: Uint8Array; iv: Uint8Array } | undefined\n\n if (sessionData.serverSessionKey) {\n encryptedServerSessionKey = await encryptWithWrappingKey(sessionData.serverSessionKey)\n }\n\n return new Promise((resolve, reject) => {\n if (!db) {\n reject(new Error('Database not initialized'))\n return\n }\n\n const transaction = db.transaction(['session'], 'readwrite')\n const store = transaction.objectStore('session')\n\n const data: StoredSession = {\n id: 'current',\n encryptedSigningPrivateKey: encryptedSigningKey.ciphertext,\n signingPrivateKeyIV: encryptedSigningKey.iv,\n encryptedServerSessionKey: encryptedServerSessionKey?.ciphertext,\n serverSessionKeyIV: encryptedServerSessionKey?.iv,\n userExtId: sessionData.userExtId,\n timestamp: Date.now(),\n }\n\n const request = store.put(data)\n\n request.onsuccess = () => {\n resolve()\n }\n\n request.onerror = () => {\n console.error('[STORAGE] Failed to save session:', request.error)\n reject(request.error)\n }\n })\n } catch (error) {\n console.error('[STORAGE] Failed to encrypt session data:', error)\n throw error\n }\n}\n\n/**\n * Retrieve session data from IndexedDB (with decrypted private key).\n *\n * @returns Session data or null if not found\n */\nexport async function getSession(): Promise<SessionData | null> {\n await ensureDatabase()\n\n if (!db) {\n throw new Error('Database not initialized')\n }\n\n return new Promise((resolve, reject) => {\n if (!db) {\n reject(new Error('Database not initialized'))\n return\n }\n\n const transaction = db.transaction(['session'], 'readonly')\n const store = transaction.objectStore('session')\n const request = store.get('current')\n\n request.onsuccess = async () => {\n const result = request.result as StoredSession | undefined\n\n if (result) {\n try {\n // Decrypt the signing private key (required)\n const signingPrivateKey = await decryptWithWrappingKey(\n result.encryptedSigningPrivateKey,\n result.signingPrivateKeyIV\n )\n\n // Decrypt optional fields if present\n let serverSessionKey\n\n if (result.encryptedServerSessionKey && result.serverSessionKeyIV) {\n serverSessionKey = await decryptWithWrappingKey(\n result.encryptedServerSessionKey,\n result.serverSessionKeyIV\n )\n }\n\n resolve({\n signingPrivateKey,\n serverSessionKey,\n userExtId: result.userExtId,\n })\n } catch (error) {\n console.error('[STORAGE] Failed to decrypt session data:', error)\n reject(error)\n }\n } else {\n resolve(null)\n }\n }\n\n request.onerror = () => {\n console.error('[STORAGE] Failed to get session:', request.error)\n reject(request.error)\n }\n })\n}\n\n/**\n * Update the signing private key in IndexedDB (used when changing password).\n * This re-encrypts the new key while preserving other session data.\n *\n * @param newSigningPrivateKey - New Ed25519 private key to store\n */\nexport async function updateSigningPrivateKey(newSigningPrivateKey: Uint8Array): Promise<void> {\n await ensureDatabase()\n\n try {\n // Get existing session to preserve serverSessionKey, etc.\n const existingSession = await getSession()\n\n if (!existingSession) {\n throw new Error('No existing session to update')\n }\n\n // Save complete session with new signing key\n await saveSession({\n signingPrivateKey: newSigningPrivateKey,\n serverSessionKey: existingSession.serverSessionKey,\n userExtId: existingSession.userExtId,\n })\n } catch (error) {\n console.error('[STORAGE] Failed to update signing private key:', error)\n throw error\n }\n}\n\n/**\n * Clear session data from IndexedDB.\n */\nexport async function clearSession(): Promise<void> {\n await ensureDatabase()\n\n if (!db) {\n throw new Error('Database not initialized')\n }\n\n return new Promise((resolve, reject) => {\n if (!db) {\n reject(new Error('Database not initialized'))\n return\n }\n\n const transaction = db.transaction(['session'], 'readwrite')\n const store = transaction.objectStore('session')\n const request = store.delete('current')\n\n request.onsuccess = () => {\n resolve()\n }\n\n request.onerror = () => {\n console.error('[STORAGE] Failed to clear session:', request.error)\n reject(request.error)\n }\n })\n}\n\n/**\n * Clear the wrapping key from IndexedDB.\n *\n * ⚠️ WARNING: This will make all encrypted private keys unrecoverable!\n * Only call this during full logout/reset.\n */\nasync function clearWrappingKey(): Promise<void> {\n await ensureDatabase()\n\n if (!db) {\n throw new Error('Database not initialized')\n }\n\n return new Promise((resolve, reject) => {\n if (!db) {\n reject(new Error('Database not initialized'))\n return\n }\n\n const transaction = db.transaction(['wrapping-key'], 'readwrite')\n const store = transaction.objectStore('wrapping-key')\n const request = store.delete('master')\n\n request.onsuccess = () => {\n resolve()\n }\n\n request.onerror = () => {\n console.error('[STORAGE] Failed to clear wrapping key:', request.error)\n reject(request.error)\n }\n })\n}\n\n/**\n * Clear all data from IndexedDB (session + wrapping key).\n *\n * Used during logout to ensure all cryptographic material is removed.\n */\nexport async function clearAllData(): Promise<void> {\n await clearSession()\n await clearWrappingKey()\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Check if a session exists in IndexedDB.\n *\n * @returns True if session exists\n */\nexport async function hasSession(): Promise<boolean> {\n const session = await getSession()\n return session !== null\n}\n","/**\n * Registration flow\n *\n * Generates Ed25519 keypair → posts to /v1/user/register\n */\n\nimport type createFetchClient from 'openapi-fetch'\nimport type { paths } from '../schema'\nimport type { SessionManager } from '../session'\nimport { generateRegistrationCredentials } from '../crypto'\nimport { saveSession } from '../storage'\n\nexport interface RegisterParams {\n email: string\n password: string\n verificationCode: string\n firstName?: string\n lastName?: string\n picture?: string\n}\n\nexport interface RegisterResult {\n signingPrivateKey: Uint8Array\n}\n\nexport async function register(\n params: RegisterParams,\n deps: {\n fetchClient: ReturnType<typeof createFetchClient<paths>>\n session: SessionManager\n deploymentDomain: string\n }\n): Promise<RegisterResult> {\n const credentials = await generateRegistrationCredentials(\n {\n email: params.email,\n verification_credential: params.verificationCode,\n given_name: params.firstName,\n family_name: params.lastName,\n picture: params.picture,\n },\n params.password,\n deps.deploymentDomain\n )\n\n const response = await deps.fetchClient.POST('/v1/user/register', {\n body: credentials.request,\n })\n\n if (response.error) {\n throw new Error(\n `Registration failed: ${typeof response.error === 'object' && response.error !== null && 'detail' in response.error ? (response.error as { detail?: string }).detail : 'Unknown error'}`\n )\n }\n\n return { signingPrivateKey: credentials.signingPrivateKey }\n}\n","/**\n * Login flow\n *\n * Generates Ed25519 signature → posts to /v1/user/login → saves session\n */\n\nimport type createFetchClient from 'openapi-fetch'\nimport type { paths } from '../schema'\nimport type { SessionManager } from '../session'\nimport { generateLoginCredentials, generateLoginCredentialsFromKey, base64ToBytes } from '../crypto'\nimport { saveSession } from '../storage'\n\nexport interface LoginParams {\n email: string\n password: string\n ssoToken?: string\n}\n\nexport interface LoginWithKeyParams {\n email: string\n signingPrivateKey: Uint8Array\n ssoToken?: string\n}\n\nexport interface LoginResult {\n accessToken: string\n userExtId?: string\n signingPrivateKey: Uint8Array\n serverSessionKey: Uint8Array\n}\n\nexport async function login(\n params: LoginParams,\n deps: {\n fetchClient: ReturnType<typeof createFetchClient<paths>>\n session: SessionManager\n deploymentDomain: string\n }\n): Promise<LoginResult> {\n const credentials = await generateLoginCredentials(\n {\n email: params.email,\n sso_token: params.ssoToken,\n },\n params.password,\n deps.deploymentDomain\n )\n\n return performLogin(credentials.request, credentials.signingPrivateKey, deps)\n}\n\nexport async function loginWithKey(\n params: LoginWithKeyParams,\n deps: {\n fetchClient: ReturnType<typeof createFetchClient<paths>>\n session: SessionManager\n deploymentDomain: string\n }\n): Promise<LoginResult> {\n const credentials = generateLoginCredentialsFromKey(\n {\n email: params.email,\n sso_token: params.ssoToken,\n },\n params.signingPrivateKey\n )\n\n return performLogin(credentials.request, credentials.signingPrivateKey, deps)\n}\n\nasync function performLogin(\n request: { email: string; signature: string; timestamp: number; sso_token?: string | null },\n signingPrivateKey: Uint8Array,\n deps: {\n fetchClient: ReturnType<typeof createFetchClient<paths>>\n session: SessionManager\n }\n): Promise<LoginResult> {\n const response = await deps.fetchClient.POST('/v1/user/login', {\n body: request,\n })\n\n if (response.error || !response.data) {\n throw new Error(\n `Login failed: ${typeof response.error === 'object' && response.error !== null && 'detail' in response.error ? (response.error as { detail?: string }).detail : 'Unknown error'}`\n )\n }\n\n const data = response.data\n const serverSessionKey = base64ToBytes(data.session_key)\n\n // Save session to IndexedDB\n await saveSession({\n signingPrivateKey,\n serverSessionKey,\n userExtId: data.user.external_id ?? undefined,\n })\n\n // Update in-memory session\n deps.session.setAccessToken(data.access_token)\n deps.session.setUser(request.email, data.user.external_id ?? undefined)\n\n return {\n accessToken: data.access_token,\n userExtId: data.user.external_id ?? undefined,\n signingPrivateKey,\n serverSessionKey,\n }\n}\n","/**\n * Logout flow\n *\n * Clears session manager + IndexedDB storage\n */\n\nimport type { SessionManager } from '../session'\nimport { clearAllData } from '../storage'\n\nexport async function logout(session: SessionManager): Promise<void> {\n session.clear()\n await clearAllData()\n}\n","/**\n * Change password flow\n *\n * Generates old + new credentials → posts to /v1/user/change_password → updates stored key\n */\n\nimport type createFetchClient from 'openapi-fetch'\nimport type { paths } from '../schema'\nimport type { SessionManager } from '../session'\nimport { generatePasswordChangeCredentials } from '../crypto'\nimport { updateSigningPrivateKey } from '../storage'\n\nexport interface ChangePasswordParams {\n email: string\n currentPassword: string\n newPassword: string\n rewrappedWorkspaceKeys?: Record<string, string>\n}\n\nexport interface ChangePasswordResult {\n newSigningPrivateKey: Uint8Array\n}\n\nexport async function changePassword(\n params: ChangePasswordParams,\n deps: {\n fetchClient: ReturnType<typeof createFetchClient<paths>>\n session: SessionManager\n deploymentDomain: string\n }\n): Promise<ChangePasswordResult> {\n const credentials = await generatePasswordChangeCredentials(\n params.email,\n params.currentPassword,\n params.newPassword,\n deps.deploymentDomain\n )\n\n const response = await deps.fetchClient.POST('/v1/user/change_password', {\n body: {\n ...credentials.request,\n rewrapped_workspace_keys: params.rewrappedWorkspaceKeys ?? {},\n },\n })\n\n if (response.error) {\n throw new Error(\n `Password change failed: ${typeof response.error === 'object' && response.error !== null && 'detail' in response.error ? (response.error as { detail?: string }).detail : 'Unknown error'}`\n )\n }\n\n // Update stored signing key\n await updateSigningPrivateKey(credentials.newSigningPrivateKey)\n\n return { newSigningPrivateKey: credentials.newSigningPrivateKey }\n}\n","/**\n * createArbiClient() — SDK entry point\n *\n * Factory that wires together:\n * - SessionManager (in-memory state)\n * - Crypto providers (libsodium wrappers)\n * - Login / WorkspaceKeyRefresh providers (openapi-fetch transport)\n * - Relogin handler (zero-knowledge re-authentication)\n * - openapi-fetch client with 3 middleware layers\n * - High-level auth methods (register, login, logout, changePassword)\n *\n * Returns an ArbiClient object that SDK consumers interact with.\n */\n\nimport createFetchClient from 'openapi-fetch'\nimport type { paths } from './schema'\nimport {\n createSessionManager,\n createTokenProvider,\n createWorkspaceKeyProvider,\n createAuthStateProvider,\n type SessionManager,\n} from './session'\nimport {\n initSodium,\n signMessage,\n sealedBoxDecrypt,\n deriveEncryptionKeypairFromSigning,\n createWorkspaceKeyHeader,\n base64ToBytes,\n bytesToBase64,\n base64Encode,\n base64Decode,\n sealedBoxEncrypt,\n derivePublicKey,\n computeSharedSecret,\n encryptMessageWithSharedSecret,\n decryptMessageWithSharedSecret,\n encryptMessage,\n decryptMessage,\n generateUserKeypairs,\n} from './crypto'\nimport { createBearerAuthMiddleware } from './middleware/bearer-auth'\nimport { createWorkspaceKeyMiddleware } from './middleware/workspace-key'\nimport { createAutoReloginMiddleware } from './middleware/auto-relogin'\nimport type { WorkspaceKeyUrlConfig } from './middleware/types'\nimport { createReloginHandler } from './relogin'\nimport type { CryptoProvider, LoginProvider, WorkspaceKeyRefreshProvider } from './relogin/types'\nimport { getSession, saveSession } from './storage'\nimport { register, login, loginWithKey, logout, changePassword } from './auth'\nimport type {\n RegisterParams,\n RegisterResult,\n LoginParams,\n LoginWithKeyParams,\n LoginResult,\n ChangePasswordParams,\n ChangePasswordResult,\n} from './auth'\n\n// ============================================================================\n// API path prefix — single source of truth for route matching\n// ============================================================================\n\nexport const API_PREFIX = '/v1' as const\n\n// ============================================================================\n// Default URL config (matches ARBI backend API patterns)\n// ============================================================================\n\nconst DEFAULT_WORKSPACE_KEY_URL_CONFIG: WorkspaceKeyUrlConfig = {\n excludePatterns: [\n `${API_PREFIX}/user/`,\n `${API_PREFIX}/health/`,\n `${API_PREFIX}/configs/`,\n `${API_PREFIX}/workspace/create`,\n ],\n includePatterns: [\n `${API_PREFIX}/workspace/wrk-`,\n `${API_PREFIX}/document/`,\n `${API_PREFIX}/conversation/`,\n `${API_PREFIX}/assistant/`,\n `${API_PREFIX}/tag/`,\n ],\n}\n\n// ============================================================================\n// Client options\n// ============================================================================\n\nexport interface ArbiClientOptions {\n /** Base URL for the ARBI API (e.g. \"https://api.mydeployment.com\") */\n baseUrl: string\n /** Deployment domain used for deterministic key derivation (e.g. \"mydeployment.com\") */\n deploymentDomain: string\n /** Optional custom URL patterns for workspace key injection */\n workspaceKeyUrlConfig?: WorkspaceKeyUrlConfig\n /** URL patterns that should never trigger re-login */\n reloginExcludePatterns?: string[]\n /** Include credentials (cookies) in requests. Default: true */\n credentials?: RequestCredentials\n /** Optional SSO token provider */\n ssoTokenProvider?: { getToken(): Promise<string | null> } | null\n /** Optional callback when re-login succeeds */\n onReloginSuccess?: (data: {\n email: string\n accessToken: string\n userExtId?: string\n serverSessionKey: Uint8Array\n }) => void\n}\n\n// ============================================================================\n// ArbiClient interface\n// ============================================================================\n\nexport interface ArbiClient {\n /** Type-safe openapi-fetch client with middleware */\n fetch: ReturnType<typeof createFetchClient<paths>>\n\n /** In-memory session state */\n session: SessionManager\n\n /** High-level auth operations */\n auth: {\n register(params: RegisterParams): Promise<RegisterResult>\n login(params: LoginParams): Promise<LoginResult>\n loginWithKey(params: LoginWithKeyParams): Promise<LoginResult>\n logout(): Promise<void>\n changePassword(params: ChangePasswordParams): Promise<ChangePasswordResult>\n /** Instant re-login using stored private key */\n relogin(): Promise<string | null>\n }\n\n /** Crypto utilities */\n crypto: {\n initSodium: typeof initSodium\n generateUserKeypairs(email: string, password: string): ReturnType<typeof generateUserKeypairs>\n signMessage: typeof signMessage\n sealedBoxDecrypt: typeof sealedBoxDecrypt\n sealedBoxEncrypt: typeof sealedBoxEncrypt\n createWorkspaceKeyHeader: typeof createWorkspaceKeyHeader\n deriveEncryptionKeypairFromSigning: typeof deriveEncryptionKeypairFromSigning\n derivePublicKey: typeof derivePublicKey\n base64ToBytes: typeof base64ToBytes\n bytesToBase64: typeof bytesToBase64\n base64Encode: typeof base64Encode\n base64Decode: typeof base64Decode\n computeSharedSecret: typeof computeSharedSecret\n encryptMessage: typeof encryptMessage\n decryptMessage: typeof decryptMessage\n encryptMessageWithSharedSecret: typeof encryptMessageWithSharedSecret\n decryptMessageWithSharedSecret: typeof decryptMessageWithSharedSecret\n }\n\n /** IndexedDB storage operations */\n storage: {\n getSession: typeof getSession\n saveSession: typeof saveSession\n }\n}\n\n// ============================================================================\n// Retry wrapper for transient connection errors (ECONNREFUSED, ECONNRESET, etc.)\n// ============================================================================\n\nconst RETRYABLE_CODES = new Set([\n 'ECONNREFUSED',\n 'ECONNRESET',\n 'ETIMEDOUT',\n 'UND_ERR_CONNECT_TIMEOUT',\n])\nconst MAX_RETRIES = 3\nconst BASE_DELAY_MS = 200\n\nfunction isRetryableError(err: unknown): boolean {\n if (!(err instanceof Error)) return false\n // Node/undici errors nest the cause\n const cause = (err as { cause?: { code?: string } }).cause\n if (cause?.code && RETRYABLE_CODES.has(cause.code)) return true\n // Fallback: check message for known patterns\n const msg = err.message || ''\n return RETRYABLE_CODES.has(msg) || msg.includes('ECONNREFUSED') || msg.includes('ECONNRESET')\n}\n\nfunction createRetryFetch(): typeof globalThis.fetch {\n return async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n let lastError: unknown\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n try {\n const fetchInput = input instanceof Request ? input.clone() : input\n return await globalThis.fetch(fetchInput, init)\n } catch (err) {\n lastError = err\n if (attempt < MAX_RETRIES && isRetryableError(err)) {\n await new Promise((r) => setTimeout(r, BASE_DELAY_MS * 2 ** attempt))\n continue\n }\n throw err\n }\n }\n throw lastError\n }\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nexport function createArbiClient(options: ArbiClientOptions): ArbiClient {\n const {\n baseUrl,\n deploymentDomain,\n workspaceKeyUrlConfig = DEFAULT_WORKSPACE_KEY_URL_CONFIG,\n reloginExcludePatterns = [`${API_PREFIX}/user/login`],\n credentials = 'include',\n ssoTokenProvider = null,\n onReloginSuccess,\n } = options\n\n // 0. Create retry-aware fetch for resilience against transient connection errors\n const retryFetch = createRetryFetch()\n\n // 1. Create SessionManager\n const session = createSessionManager()\n\n // 2. Create provider adapters\n const tokenProvider = createTokenProvider(session)\n const workspaceKeyProvider = createWorkspaceKeyProvider(session)\n const authState = createAuthStateProvider(session)\n\n // 3. Create CryptoProvider\n const cryptoProvider: CryptoProvider = {\n ensureReady: initSodium,\n signMessage,\n deriveEncryptionKeypair: deriveEncryptionKeypairFromSigning,\n sealedBoxDecrypt,\n createWorkspaceKeyHeader,\n fromBase64: base64ToBytes,\n }\n\n // 4. Create LoginProvider (raw fetch client for login — no middleware)\n const loginProvider: LoginProvider = {\n async login(payload) {\n const rawFetch = createFetchClient<paths>({\n baseUrl,\n credentials,\n fetch: retryFetch,\n })\n\n const response = await rawFetch.POST('/v1/user/login', {\n body: {\n email: payload.email,\n signature: payload.signature,\n timestamp: payload.timestamp,\n sso_token: payload.ssoToken,\n },\n })\n\n if (response.error || !response.data) {\n console.warn('[API] Login call failed:', response.error)\n return null\n }\n\n const data = response.data\n return {\n accessToken: data.access_token,\n sessionKey: base64ToBytes(data.session_key),\n userExtId: data.user.external_id ?? undefined,\n }\n },\n }\n\n // 5. Create WorkspaceKeyRefreshProvider\n const workspaceKeyRefreshProvider: WorkspaceKeyRefreshProvider = {\n async getWrappedKey(accessToken, workspaceId) {\n const workspacesResponse = await retryFetch(`${baseUrl}${API_PREFIX}/user/workspaces`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n credentials,\n })\n\n if (!workspacesResponse.ok) return null\n\n const workspacesData = await workspacesResponse.json()\n const workspace = workspacesData.find(\n (w: { external_id: string; wrapped_key?: string }) => w.external_id === workspaceId\n )\n\n return workspace?.wrapped_key ?? null\n },\n }\n\n // 6. Create relogin handler\n const reloginHandler = createReloginHandler({\n crypto: cryptoProvider,\n sessionStorage: { getSession, saveSession },\n authState,\n ssoTokenProvider,\n loginProvider,\n workspaceKeyRefreshProvider,\n onReloginSuccess,\n })\n\n // 7. Create openapi-fetch client with middleware\n const fetchClient = createFetchClient<paths>({\n baseUrl,\n credentials,\n fetch: retryFetch,\n })\n\n fetchClient.use(createBearerAuthMiddleware({ tokenProvider }))\n\n fetchClient.use(\n createWorkspaceKeyMiddleware({\n workspaceKeyProvider,\n urlConfig: workspaceKeyUrlConfig,\n })\n )\n\n fetchClient.use(\n createAutoReloginMiddleware({\n reloginHandler,\n reloginExcludePatterns,\n })\n )\n\n // 8. Auth + fetch deps for high-level methods\n const authDeps = {\n fetchClient,\n session,\n deploymentDomain,\n }\n\n // 9. Build and return ArbiClient\n return {\n fetch: fetchClient,\n session,\n\n auth: {\n register: (params) => register(params, authDeps),\n login: (params) => login(params, authDeps),\n loginWithKey: (params) => loginWithKey(params, authDeps),\n logout: () => logout(session),\n changePassword: (params) => changePassword(params, authDeps),\n relogin: reloginHandler,\n },\n\n crypto: {\n initSodium,\n generateUserKeypairs: (email, password) =>\n generateUserKeypairs(email, password, deploymentDomain),\n signMessage,\n sealedBoxDecrypt,\n sealedBoxEncrypt,\n createWorkspaceKeyHeader,\n deriveEncryptionKeypairFromSigning,\n derivePublicKey,\n base64ToBytes,\n bytesToBase64,\n base64Encode,\n base64Decode,\n computeSharedSecret,\n encryptMessage,\n decryptMessage,\n encryptMessageWithSharedSecret,\n decryptMessageWithSharedSecret,\n },\n\n storage: {\n getSession,\n saveSession,\n },\n }\n}\n","/**\n * WebSocket helpers — pure functions, no runtime dependencies.\n *\n * Consumers bring their own WebSocket implementation (browser native, Node 22+, ws package).\n * This module provides URL building, auth message creation, typed message parsing,\n * and type guards for the discriminated-union server messages.\n */\n\nimport type { components } from './schema'\nimport { API_PREFIX } from './client'\n\n// ==========================================\n// Type aliases from OpenAPI schema\n// ==========================================\n\nexport type WsAuthMessage = components['schemas']['AuthMessage']\nexport type WsAuthResultMessage = components['schemas']['AuthResultMessage']\nexport type WsTaskUpdateMessage = components['schemas']['TaskUpdateMessage']\nexport type WsBatchCompleteMessage = components['schemas']['BatchCompleteMessage']\nexport type WsConnectionClosedMessage = components['schemas']['ConnectionClosedMessage']\nexport type WsErrorMessage = components['schemas']['ErrorMessage']\nexport type WsPresenceUpdateMessage = components['schemas']['PresenceUpdateMessage']\nexport type WsNotificationResponse = components['schemas']['NotificationResponse']\n\n/** Union of all server → client message types (discriminated on `type` field). */\nexport type WebSocketServerMessage =\n | WsTaskUpdateMessage\n | WsAuthResultMessage\n | WsConnectionClosedMessage\n | WsPresenceUpdateMessage\n | WsErrorMessage\n | WsNotificationResponse\n | WsBatchCompleteMessage\n\n/** Union of all client → server message types. */\nexport type WebSocketClientMessage = WsAuthMessage\n\n// ==========================================\n// Pure helper functions\n// ==========================================\n\n/**\n * Build a WebSocket URL from an HTTP(S) base URL.\n *\n * \"https://box-105.arbibox.com\" → \"wss://box-105.arbibox.com/v1/notifications/ws\"\n * \"http://localhost:8000\" → \"ws://localhost:8000/v1/notifications/ws\"\n */\nexport function buildWebSocketUrl(baseUrl: string): string {\n const wsScheme = baseUrl.startsWith('https') ? 'wss' : 'ws'\n const hostAndPath = baseUrl.replace(/^https?:\\/\\//, '').replace(/\\/+$/, '')\n return `${wsScheme}://${hostAndPath}${API_PREFIX}/notifications/ws`\n}\n\n/**\n * Create the JSON auth message to send after WebSocket connection opens.\n * Returns the serialized JSON string ready to send.\n */\nexport function createAuthMessage(accessToken: string): string {\n const msg: WsAuthMessage = { type: 'auth', token: accessToken }\n return JSON.stringify(msg)\n}\n\n/**\n * Parse a raw WebSocket message string into a typed server message.\n * Returns `null` for unparseable data. Accepts any object with a string `type`\n * field — no hardcoded list of known types, so this stays valid as the schema evolves.\n */\nexport function parseServerMessage(data: string): WebSocketServerMessage | null {\n try {\n const parsed = JSON.parse(data)\n if (typeof parsed === 'object' && parsed !== null && typeof parsed.type === 'string') {\n return parsed as WebSocketServerMessage\n }\n return null\n } catch {\n return null\n }\n}\n\n/**\n * Type guard to narrow a server message to a specific type by its `type` field value.\n *\n * Usage:\n * if (isMessageType(msg, 'task_update')) {\n * // msg is WsTaskUpdateMessage\n * }\n */\nexport function isMessageType<T extends WebSocketServerMessage>(\n msg: WebSocketServerMessage,\n type: T['type']\n): msg is T {\n return msg.type === type\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/fetch.ts","../src/config.ts","../src/auth.ts","../src/sse.ts","../src/websocket.ts","../src/format.ts","../src/operations/documents.ts","../src/operations/workspaces.ts","../src/operations/conversations.ts","../src/operations/assistant.ts","../src/operations/tags.ts","../src/operations/contacts.ts","../src/operations/doctags.ts","../src/operations/dm.ts","../src/operations/settings.ts","../src/operations/agentconfig.ts","../src/operations/health.ts","../src/operations/files.ts","../src/arbi.ts"],"names":["path","os","fs","createArbiClient","base64ToBytes","deriveEncryptionKeypairFromSigning","sealedBoxDecrypt","createWorkspaceKeyHeader","buildWebSocketUrl","createAuthMessage","parseServerMessage","isMessageType","uploadFile"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Core error types and throwing error utilities.\n *\n * Unlike CLI helpers which call process.exit(1), these throw typed errors\n * that consumers (CLI, MCP) can catch and handle in their own way.\n */\n\nexport class ArbiError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ArbiError'\n }\n}\n\nexport class ArbiApiError extends ArbiError {\n public readonly apiError?: unknown\n\n constructor(message: string, apiError?: unknown) {\n super(message)\n this.name = 'ArbiApiError'\n this.apiError = apiError\n }\n}\n\n/**\n * Check API response and throw on error. Returns narrowed non-null data.\n */\nexport function requireData<T>(result: { data?: T; error?: unknown }, message: string): T {\n if (result.error || !result.data) {\n throw new ArbiApiError(message, result.error)\n }\n return result.data\n}\n\n/**\n * Check API response for delete/void operations (no data expected).\n */\nexport function requireOk(result: { error?: unknown }, message: string): void {\n if (result.error) {\n throw new ArbiApiError(message, result.error)\n }\n}\n\n/**\n * Extract a human-readable message from an unknown error value.\n * Centralises the `err instanceof Error ? err.message : String(err)` pattern.\n */\nexport function getErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err)\n}\n","/**\n * Authenticated fetch utility — eliminates repeated raw-fetch boilerplate\n * in operations that can't use the typed SDK client (streaming, multipart, etc.).\n */\n\ninterface AuthHeaders {\n baseUrl: string\n accessToken: string\n workspaceKeyHeader: string\n}\n\ninterface AuthFetchOptions extends AuthHeaders {\n /** URL path relative to baseUrl (e.g. '/v1/document/upload'). */\n path: string\n method?: string\n body?: string | FormData | ArrayBuffer | ReadableStream | Blob | null\n /** Extra headers to merge in. */\n headers?: Record<string, string>\n}\n\nconst STATUS_MESSAGES: Record<number, string> = {\n 401: 'Token has expired. Please run: arbi login',\n 503: 'The selected LLM is not responding. Please retry or select another model.',\n}\n\n/**\n * Make an authenticated fetch request with standard error handling.\n * Automatically sets Authorization + workspace-key headers.\n * Throws on non-ok responses with a human-readable message.\n */\nexport async function authenticatedFetch(options: AuthFetchOptions): Promise<Response> {\n const { baseUrl, accessToken, workspaceKeyHeader, path, method, body, headers } = options\n\n const res = await fetch(`${baseUrl}${path}`, {\n method: method ?? (body ? 'POST' : 'GET'),\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'workspace-key': workspaceKeyHeader,\n ...headers,\n },\n body,\n })\n\n if (!res.ok) {\n const knownMessage = STATUS_MESSAGES[res.status]\n if (knownMessage) throw new Error(knownMessage)\n const text = await res.text().catch(() => '')\n throw new Error(`Request failed: ${res.status} ${text}`)\n }\n\n return res\n}\n\nexport type { AuthHeaders }\n","/**\n * Configuration persistence — types, interface, and file-based implementation.\n *\n * Both CLI and MCP share the same ~/.arbi/ config directory.\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport { ArbiError } from './errors.js'\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport interface CliConfig {\n baseUrl: string\n deploymentDomain: string\n selectedWorkspaceId?: string\n autoUpdate?: boolean\n notifications?: boolean\n}\n\nexport interface CliCredentials {\n email: string\n signingPrivateKeyBase64: string\n serverSessionKeyBase64: string\n}\n\nexport interface ChatSession {\n /** Last assistant message ID — used as previous_response_id for follow-ups */\n lastMessageExtId: string | null\n /** Conversation external ID — used to restore chat history on restart */\n conversationExtId: string | null\n}\n\n// ── ConfigStore interface ────────────────────────────────────────────────────\n\nexport interface ConfigStore {\n getConfig(): CliConfig | null\n saveConfig(config: CliConfig): void\n updateConfig(updates: Partial<CliConfig>): void\n requireConfig(): CliConfig\n getCredentials(): CliCredentials | null\n saveCredentials(creds: CliCredentials): void\n deleteCredentials(): void\n requireCredentials(): CliCredentials\n getChatSession(): ChatSession\n saveChatSession(session: ChatSession): void\n updateChatSession(updates: Partial<ChatSession>): void\n clearChatSession(): void\n}\n\n// ── File-based implementation ────────────────────────────────────────────────\n\nconst DEFAULT_SESSION: ChatSession = {\n lastMessageExtId: null,\n conversationExtId: null,\n}\n\nexport class FileConfigStore implements ConfigStore {\n private readonly configDir: string\n private readonly configFile: string\n private readonly credentialsFile: string\n private readonly sessionFile: string\n\n constructor(configDir?: string) {\n this.configDir = configDir ?? process.env.ARBI_CONFIG_DIR ?? path.join(os.homedir(), '.arbi')\n this.configFile = path.join(this.configDir, 'config.json')\n this.credentialsFile = path.join(this.configDir, 'credentials.json')\n this.sessionFile = path.join(this.configDir, 'session.json')\n }\n\n private ensureConfigDir(): void {\n if (!fs.existsSync(this.configDir)) {\n fs.mkdirSync(this.configDir, { recursive: true, mode: 0o700 })\n }\n }\n\n private writeSecureFile(filePath: string, data: object): void {\n this.ensureConfigDir()\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\\n', { mode: 0o600 })\n }\n\n private readJsonFile<T>(filePath: string): T | null {\n try {\n const content = fs.readFileSync(filePath, 'utf-8')\n return JSON.parse(content) as T\n } catch {\n return null\n }\n }\n\n // ── Config ──────────────────────────────────────────────────────────────\n\n getConfig(): CliConfig | null {\n return this.readJsonFile<CliConfig>(this.configFile)\n }\n\n saveConfig(config: CliConfig): void {\n this.writeSecureFile(this.configFile, config)\n }\n\n updateConfig(updates: Partial<CliConfig>): void {\n const existing = this.getConfig() || ({} as Partial<CliConfig>)\n this.saveConfig({ ...existing, ...updates } as CliConfig)\n }\n\n requireConfig(): CliConfig {\n const config = this.getConfig()\n if (!config?.baseUrl) {\n throw new ArbiError('Not configured. Run: arbi config set-url <url>')\n }\n return config\n }\n\n // ── Credentials ─────────────────────────────────────────────────────────\n\n getCredentials(): CliCredentials | null {\n return this.readJsonFile<CliCredentials>(this.credentialsFile)\n }\n\n saveCredentials(creds: CliCredentials): void {\n this.writeSecureFile(this.credentialsFile, creds)\n }\n\n deleteCredentials(): void {\n try {\n fs.unlinkSync(this.credentialsFile)\n } catch {\n // Already gone\n }\n }\n\n requireCredentials(): CliCredentials {\n const creds = this.getCredentials()\n if (!creds) {\n throw new ArbiError('Not logged in. Run: arbi login')\n }\n return creds\n }\n\n // ── Chat session ────────────────────────────────────────────────────────\n\n getChatSession(): ChatSession {\n return this.readJsonFile<ChatSession>(this.sessionFile) || { ...DEFAULT_SESSION }\n }\n\n saveChatSession(session: ChatSession): void {\n this.writeSecureFile(this.sessionFile, session)\n }\n\n updateChatSession(updates: Partial<ChatSession>): void {\n const existing = this.getChatSession()\n this.saveChatSession({ ...existing, ...updates })\n }\n\n clearChatSession(): void {\n this.saveChatSession({ ...DEFAULT_SESSION })\n }\n}\n","/**\n * Parameterized authentication functions.\n *\n * Unlike CLI's client.ts, these take explicit params instead of reading from disk.\n * This allows both CLI and MCP to use them with their own config sources.\n */\n\nimport {\n createArbiClient,\n sealedBoxDecrypt,\n deriveEncryptionKeypairFromSigning,\n createWorkspaceKeyHeader,\n base64ToBytes,\n type ArbiClient,\n type LoginResult,\n} from '@arbidocs/client'\nimport { ArbiError } from './errors.js'\nimport type { CliConfig, CliCredentials, ConfigStore } from './config.js'\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport interface AuthenticatedClient {\n arbi: ArbiClient\n loginResult: LoginResult\n}\n\nexport interface AuthContext {\n arbi: ArbiClient\n loginResult: LoginResult\n config: CliConfig\n}\n\nexport interface WorkspaceContext extends AuthContext {\n workspaceId: string\n accessToken: string\n workspaceKeyHeader: string\n}\n\n// ── Workspace choice formatting ──────────────────────────────────────────────\n\n/** Minimal workspace shape required by formatWorkspaceChoices. */\ninterface WorkspaceForChoice {\n name: string\n external_id: string\n shared_document_count: number\n private_document_count: number\n}\n\n/**\n * Format a list of workspaces into prompt-friendly choices.\n * Returns `{ name, value, description }` objects suitable for @inquirer/prompts\n * or any similar select component.\n */\nexport function formatWorkspaceChoices(\n wsList: WorkspaceForChoice[]\n): Array<{ name: string; value: string; description: string }> {\n return wsList.map((ws) => {\n const totalDocs = ws.shared_document_count + ws.private_document_count\n return {\n name: `${ws.name} (${totalDocs} docs)`,\n value: ws.external_id,\n description: ws.external_id,\n }\n })\n}\n\n// ── Functions ────────────────────────────────────────────────────────────────\n\n/**\n * Create an SDK client, init sodium, and log in with stored signing key.\n * Returns the client + login result (which includes serverSessionKey).\n */\nexport async function createAuthenticatedClient(\n config: CliConfig,\n creds: CliCredentials,\n store: ConfigStore\n): Promise<AuthenticatedClient> {\n const arbi = createArbiClient({\n baseUrl: config.baseUrl,\n deploymentDomain: config.deploymentDomain,\n credentials: 'omit',\n })\n\n await arbi.crypto.initSodium()\n\n const signingPrivateKey = base64ToBytes(creds.signingPrivateKeyBase64)\n\n const loginResult = await arbi.auth.loginWithKey({\n email: creds.email,\n signingPrivateKey,\n })\n\n // Update stored server session key (it changes each login)\n store.saveCredentials({\n ...creds,\n serverSessionKeyBase64: arbi.crypto.bytesToBase64(loginResult.serverSessionKey),\n })\n\n return { arbi, loginResult }\n}\n\n/**\n * Interactive (password-based) login flow.\n *\n * Creates an SDK client, initializes sodium, authenticates with email/password,\n * and persists the derived credentials to the config store.\n *\n * Use this for CLI/TUI login commands. For session recovery from stored keys,\n * use createAuthenticatedClient() instead.\n */\nexport async function performPasswordLogin(\n config: CliConfig,\n email: string,\n password: string,\n store: ConfigStore\n): Promise<AuthContext> {\n const arbi = createArbiClient({\n baseUrl: config.baseUrl,\n deploymentDomain: config.deploymentDomain,\n credentials: 'omit',\n })\n\n await arbi.crypto.initSodium()\n\n const loginResult = await arbi.auth.login({ email, password })\n\n store.saveCredentials({\n email,\n signingPrivateKeyBase64: arbi.crypto.bytesToBase64(loginResult.signingPrivateKey),\n serverSessionKeyBase64: arbi.crypto.bytesToBase64(loginResult.serverSessionKey),\n })\n\n return { arbi, loginResult, config }\n}\n\n/**\n * Decrypt wrapped workspace key and set it as the active workspace header.\n */\nexport async function selectWorkspace(\n arbi: ArbiClient,\n workspaceId: string,\n wrappedKey: string,\n serverSessionKey: Uint8Array,\n signingPrivateKeyBase64: string\n): Promise<void> {\n const signingPrivateKey = base64ToBytes(signingPrivateKeyBase64)\n\n // Ed25519 public key is the last 32 bytes of the 64-byte private key\n const ed25519PublicKey = signingPrivateKey.slice(32, 64)\n const encryptionKeyPair = deriveEncryptionKeypairFromSigning({\n publicKey: ed25519PublicKey,\n secretKey: signingPrivateKey,\n })\n\n const workspaceKey = sealedBoxDecrypt(wrappedKey, encryptionKeyPair.secretKey)\n const header = await createWorkspaceKeyHeader(workspaceKey, serverSessionKey)\n\n arbi.session.setSelectedWorkspace(workspaceId)\n arbi.session.setCachedWorkspaceHeader(workspaceId, header)\n}\n\n/**\n * Generate an encrypted workspace key for the given workspace.\n * Used for operations that need a key for a workspace other than the current one\n * (e.g., copy documents to a target workspace).\n */\nexport async function generateEncryptedWorkspaceKey(\n arbi: ArbiClient,\n wrappedKey: string,\n serverSessionKey: Uint8Array,\n signingPrivateKeyBase64: string\n): Promise<string> {\n const signingPrivateKey = base64ToBytes(signingPrivateKeyBase64)\n const ed25519PublicKey = signingPrivateKey.slice(32, 64)\n const encryptionKeyPair = deriveEncryptionKeypairFromSigning({\n publicKey: ed25519PublicKey,\n secretKey: signingPrivateKey,\n })\n\n const workspaceKey = sealedBoxDecrypt(wrappedKey, encryptionKeyPair.secretKey)\n return createWorkspaceKeyHeader(workspaceKey, serverSessionKey)\n}\n\n/**\n * Find a workspace by ID in the user's workspace list, select it, and return workspace info.\n */\nexport async function selectWorkspaceById(\n arbi: ArbiClient,\n workspaceId: string,\n serverSessionKey: Uint8Array,\n signingPrivateKeyBase64: string\n): Promise<{ external_id: string; name: string; wrapped_key: string }> {\n const { data: workspaces, error } = await arbi.fetch.GET('/v1/user/workspaces')\n if (error || !workspaces) {\n throw new ArbiError('Failed to fetch workspaces')\n }\n\n const ws = workspaces.find((w) => w.external_id === workspaceId)\n if (!ws || !ws.wrapped_key) {\n throw new ArbiError(`Workspace ${workspaceId} not found or has no encryption key`)\n }\n\n await selectWorkspace(\n arbi,\n ws.external_id,\n ws.wrapped_key,\n serverSessionKey,\n signingPrivateKeyBase64\n )\n\n // Exchange workspace key for a workspace-scoped JWT\n const workspaceKeyHeader = arbi.session.getWorkspaceKeyHeader()\n if (workspaceKeyHeader) {\n const { data: openResult, error: openError } = await arbi.fetch.POST(\n '/v1/workspace/{workspace_ext_id}/open',\n {\n params: { path: { workspace_ext_id: ws.external_id } },\n body: { workspace_key: workspaceKeyHeader },\n }\n )\n if (!openError && openResult?.access_token) {\n arbi.session.setAccessToken(openResult.access_token)\n }\n }\n\n return { external_id: ws.external_id, name: ws.name, wrapped_key: ws.wrapped_key }\n}\n\n/**\n * Authenticate and return the SDK client + config.\n * Throws ArbiError instead of calling process.exit.\n */\nexport async function resolveAuth(store: ConfigStore): Promise<AuthContext> {\n const config = store.requireConfig()\n const creds = store.requireCredentials()\n const { arbi, loginResult } = await createAuthenticatedClient(config, creds, store)\n return { arbi, loginResult, config }\n}\n\n/**\n * Authenticate, resolve workspace, and set up headers.\n * Throws ArbiError instead of calling process.exit.\n */\nexport async function resolveWorkspace(\n store: ConfigStore,\n workspaceOpt?: string\n): Promise<WorkspaceContext> {\n const config = store.requireConfig()\n const creds = store.requireCredentials()\n const workspaceId = workspaceOpt || config.selectedWorkspaceId\n\n if (!workspaceId) {\n throw new ArbiError('No workspace selected. Run: arbi workspace select <id>')\n }\n\n const { arbi, loginResult } = await createAuthenticatedClient(config, creds, store)\n await selectWorkspaceById(\n arbi,\n workspaceId,\n loginResult.serverSessionKey,\n creds.signingPrivateKeyBase64\n )\n\n const accessToken = arbi.session.getState().accessToken\n const workspaceKeyHeader = arbi.session.getWorkspaceKeyHeader()\n\n if (!accessToken || !workspaceKeyHeader) {\n throw new ArbiError('Authentication error — missing token or workspace key')\n }\n\n return { arbi, loginResult, config, workspaceId, accessToken, workspaceKeyHeader }\n}\n","/**\n * Server-Sent Events (SSE) parsing utilities.\n *\n * Extracted from CLI ask.ts for shared use by CLI and MCP.\n */\n\nimport type {\n SSEStreamStartData,\n AgentStepEvent,\n UserMessageEvent,\n MessageMetadataPayload,\n UserInputRequestEvent,\n ArtifactEvent,\n ResponseCreatedEvent,\n ResponseOutputTextDeltaEvent,\n ResponseOutputTextDoneEvent,\n ResponseOutputItemAddedEvent,\n ResponseOutputItemDoneEvent,\n ResponseContentPartAddedEvent,\n ResponseCompletedEvent,\n ResponseFailedEvent,\n ResponseUsage,\n} from './sse-types.js'\n\nexport interface SSEEvent {\n event: string\n data: string\n}\n\n/**\n * Parse SSE events from a chunk of text, combining with a buffer\n * of incomplete data from previous chunks.\n *\n * Returns parsed events and any remaining incomplete data.\n */\nexport function parseSSEEvents(\n chunk: string,\n buffer: string\n): { events: SSEEvent[]; remaining: string } {\n const combined = buffer + chunk\n const events: SSEEvent[] = []\n const parts = combined.split('\\n\\n')\n const remaining = parts.pop() || ''\n\n for (const part of parts) {\n if (!part.trim()) continue\n let eventType = ''\n let eventData = ''\n for (const line of part.split('\\n')) {\n if (line.startsWith('event: ')) eventType = line.slice(7).trim()\n else if (line.startsWith('data: ')) eventData = line.slice(6)\n }\n if (eventType && eventData) events.push({ event: eventType, data: eventData })\n }\n\n return { events, remaining }\n}\n\n/**\n * Callbacks for streaming SSE events. All callbacks are optional —\n * omitted callbacks simply ignore that event type.\n */\nexport interface SSEStreamCallbacks {\n onStreamStart?: (data: SSEStreamStartData) => void\n onToken?: (content: string) => void\n onTextDone?: (text: string) => void\n onOutputItemAdded?: (data: ResponseOutputItemAddedEvent) => void\n onOutputItemDone?: (data: ResponseOutputItemDoneEvent) => void\n onContentPartAdded?: (data: ResponseContentPartAddedEvent) => void\n onAgentStep?: (data: AgentStepEvent) => void\n onError?: (message: string) => void\n onUserMessage?: (data: UserMessageEvent) => void\n onMetadata?: (data: MessageMetadataPayload) => void\n onUserInputRequest?: (data: UserInputRequestEvent) => void\n onArtifact?: (data: ArtifactEvent) => void\n onElapsedTime?: (t: number) => void\n onUsage?: (usage: ResponseUsage) => void\n onComplete?: () => void\n}\n\n/**\n * Result returned after the SSE stream is fully consumed.\n */\nexport interface SSEStreamResult {\n text: string\n assistantMessageExtId: string | null\n agentSteps: string[]\n errors: string[]\n userMessage: UserMessageEvent | null\n metadata: MessageMetadataPayload | null\n artifacts: ArtifactEvent[]\n usage: ResponseUsage | null\n}\n\n/**\n * Stream SSE events from a Response, invoking callbacks as events arrive.\n *\n * This is the primary streaming function — use it when you need real-time\n * event handling (CLI streaming to stdout, TUI rendering, etc.).\n *\n * Also accumulates the full response and returns it, so callers can use\n * both the streaming callbacks and the final result.\n */\nexport async function streamSSE(\n response: Response,\n callbacks: SSEStreamCallbacks = {}\n): Promise<SSEStreamResult> {\n if (!response.body) {\n throw new Error('No response body')\n }\n\n const reader = response.body.getReader()\n const decoder = new TextDecoder('utf-8')\n let sseBuffer = ''\n let text = ''\n let assistantMessageExtId: string | null = null\n const agentSteps: string[] = []\n const errors: string[] = []\n const artifacts: ArtifactEvent[] = []\n let userMessage: UserMessageEvent | null = null\n let metadata: MessageMetadataPayload | null = null\n let usage: ResponseUsage | null = null\n\n // Each handler receives the raw JSON string and parses to the correct type.\n const eventHandlers: Record<string, (raw: string) => void> = {\n // OpenAI Responses API events (dot-separated names from server)\n 'response.created': (raw) => {\n const data: ResponseCreatedEvent = JSON.parse(raw)\n const id = data.response?.id\n if (id) assistantMessageExtId = id\n callbacks.onStreamStart?.({ assistant_message_ext_id: id })\n if (data.t != null) callbacks.onElapsedTime?.(data.t)\n },\n 'response.output_item.added': (raw) => {\n const data: ResponseOutputItemAddedEvent = JSON.parse(raw)\n callbacks.onOutputItemAdded?.(data)\n },\n 'response.content_part.added': (raw) => {\n const data: ResponseContentPartAddedEvent = JSON.parse(raw)\n callbacks.onContentPartAdded?.(data)\n },\n 'response.output_text.delta': (raw) => {\n const data: ResponseOutputTextDeltaEvent = JSON.parse(raw)\n if (data.delta) {\n text += data.delta\n callbacks.onToken?.(data.delta)\n }\n },\n 'response.output_text.done': (raw) => {\n const data: ResponseOutputTextDoneEvent = JSON.parse(raw)\n callbacks.onTextDone?.(data.text)\n },\n 'response.output_item.done': (raw) => {\n const data: ResponseOutputItemDoneEvent = JSON.parse(raw)\n callbacks.onOutputItemDone?.(data)\n },\n 'response.completed': (raw) => {\n const data: ResponseCompletedEvent = JSON.parse(raw)\n if (data.response?.usage) {\n usage = data.response.usage\n callbacks.onUsage?.(data.response.usage)\n }\n if (data.t != null) callbacks.onElapsedTime?.(data.t)\n callbacks.onComplete?.()\n },\n 'response.failed': (raw) => {\n const data: ResponseFailedEvent = JSON.parse(raw)\n const message = data.response?.error?.message || 'Unknown streaming error'\n errors.push(message)\n callbacks.onError?.(message)\n },\n // ARBI-specific events (dot-prefixed from server)\n 'arbi.agent_step': (raw) => {\n const data: AgentStepEvent = JSON.parse(raw)\n const focus = data.focus || data.step || ''\n if (focus) agentSteps.push(focus)\n callbacks.onAgentStep?.(data)\n if (data.t != null) callbacks.onElapsedTime?.(data.t)\n },\n 'arbi.user_message': (raw) => {\n const data: UserMessageEvent = JSON.parse(raw)\n userMessage = data\n callbacks.onUserMessage?.(data)\n },\n 'arbi.message_metadata': (raw) => {\n const data: MessageMetadataPayload = JSON.parse(raw)\n metadata = data\n callbacks.onMetadata?.(data)\n },\n 'arbi.user_input_request': (raw) => {\n const data: UserInputRequestEvent = JSON.parse(raw)\n callbacks.onUserInputRequest?.(data)\n },\n 'arbi.artifact': (raw) => {\n const data: ArtifactEvent = JSON.parse(raw)\n artifacts.push(data)\n callbacks.onArtifact?.(data)\n },\n 'response.complete': () => {\n callbacks.onComplete?.()\n },\n }\n\n const processEvents = (events: SSEEvent[]) => {\n for (const { event, data } of events) {\n try {\n const handler = eventHandlers[event]\n if (handler) handler(data)\n } catch {\n /* skip unparseable events */\n }\n }\n }\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n const { events, remaining } = parseSSEEvents(decoder.decode(value, { stream: true }), sseBuffer)\n sseBuffer = remaining\n processEvents(events)\n }\n\n // Process any remaining buffered data\n if (sseBuffer.trim()) {\n const { events } = parseSSEEvents(sseBuffer + '\\n\\n', '')\n processEvents(events)\n }\n\n return {\n text,\n assistantMessageExtId,\n agentSteps,\n errors,\n userMessage,\n metadata,\n artifacts,\n usage,\n }\n}\n\n/**\n * Consume an entire SSE stream without streaming callbacks.\n * Convenience alias for `streamSSE(response)`.\n */\nexport const consumeSSEStream = streamSSE\n","/**\n * WebSocket connection manager.\n *\n * Uses Node.js native WebSocket (available in Node 22+).\n * Authenticates via SDK helpers, routes typed messages to the consumer.\n */\n\nimport {\n buildWebSocketUrl,\n createAuthMessage,\n parseServerMessage,\n isMessageType,\n type WebSocketServerMessage,\n type WsAuthResultMessage,\n type WsTaskUpdateMessage,\n type WsBatchCompleteMessage,\n type WsErrorMessage,\n type WsPresenceUpdateMessage,\n type WsNotificationResponse,\n} from '@arbidocs/client'\n\nconst AUTH_TIMEOUT_MS = 10_000\nconst MAX_BACKOFF_MS = 30_000\n\nexport interface WsConnection {\n close: () => void\n}\n\nexport interface ConnectOptions {\n baseUrl: string\n accessToken: string\n onMessage: (msg: WebSocketServerMessage) => void\n onClose?: (code: number, reason: string) => void\n}\n\nexport interface ReconnectOptions extends ConnectOptions {\n maxRetries?: number\n initialDelayMs?: number\n onReconnecting?: (attempt: number, maxRetries: number) => void\n onReconnected?: () => void\n onReconnectFailed?: () => void\n}\n\nexport interface ReconnectableWsConnection {\n close: () => void\n}\n\n/**\n * Open a WebSocket, authenticate, and start routing messages.\n *\n * Resolves after a successful `auth_result`, rejects on auth failure or timeout.\n * Subsequent messages are dispatched to `onMessage`.\n */\nexport function connectWebSocket(options: ConnectOptions): Promise<WsConnection> {\n const { baseUrl, accessToken, onMessage, onClose } = options\n const url = buildWebSocketUrl(baseUrl)\n\n return new Promise<WsConnection>((resolve, reject) => {\n const ws = new WebSocket(url)\n let authenticated = false\n\n const timeout = setTimeout(() => {\n if (!authenticated) {\n ws.close()\n reject(new Error('WebSocket auth timed out'))\n }\n }, AUTH_TIMEOUT_MS)\n\n ws.addEventListener('open', () => {\n ws.send(createAuthMessage(accessToken))\n })\n\n ws.addEventListener('message', (event) => {\n const data = typeof event.data === 'string' ? event.data : String(event.data)\n const msg = parseServerMessage(data)\n if (!msg) return\n\n if (!authenticated) {\n if (isMessageType<WsAuthResultMessage>(msg, 'auth_result')) {\n clearTimeout(timeout)\n if (msg.success) {\n authenticated = true\n resolve({ close: () => ws.close() })\n } else {\n ws.close()\n reject(new Error(`WebSocket auth failed: ${msg.reason || 'unknown'}`))\n }\n }\n return\n }\n\n onMessage(msg)\n })\n\n ws.addEventListener('close', (event) => {\n clearTimeout(timeout)\n if (!authenticated) {\n reject(new Error(`WebSocket closed before auth (code ${event.code})`))\n return\n }\n onClose?.(event.code, event.reason)\n })\n\n ws.addEventListener('error', () => {\n // The close event will fire after error, so we handle rejection there.\n // This prevents unhandled rejection from the error event itself.\n })\n })\n}\n\n/**\n * Connect WebSocket with automatic reconnection on disconnect.\n *\n * Initial connection throws on failure (same as connectWebSocket).\n * After successful auth, disconnects trigger exponential backoff reconnection.\n * Call close() on the returned handle to stop reconnection attempts.\n */\nexport async function connectWithReconnect(\n options: ReconnectOptions\n): Promise<ReconnectableWsConnection> {\n const {\n maxRetries = 10,\n initialDelayMs = 1000,\n onReconnecting,\n onReconnected,\n onReconnectFailed,\n onClose,\n ...connectOpts\n } = options\n\n let closed = false\n let reconnectTimer: ReturnType<typeof setTimeout> | null = null\n let currentConnection: WsConnection | null = null\n\n const scheduleReconnect = async () => {\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n if (closed) return\n\n const delay = Math.min(initialDelayMs * Math.pow(2, attempt - 1), MAX_BACKOFF_MS)\n onReconnecting?.(attempt, maxRetries)\n\n await new Promise<void>((resolve) => {\n reconnectTimer = setTimeout(resolve, delay)\n })\n\n if (closed) return\n\n try {\n currentConnection = await connectWebSocket({\n ...connectOpts,\n onClose: (code, reason) => {\n currentConnection = null\n onClose?.(code, reason)\n if (!closed) scheduleReconnect()\n },\n })\n onReconnected?.()\n return\n } catch {\n // Retry on next iteration\n }\n }\n\n if (!closed) onReconnectFailed?.()\n }\n\n // Initial connection — throws on failure (no retry)\n currentConnection = await connectWebSocket({\n ...connectOpts,\n onClose: (code, reason) => {\n currentConnection = null\n onClose?.(code, reason)\n if (!closed) scheduleReconnect()\n },\n })\n\n return {\n close: () => {\n closed = true\n if (reconnectTimer) clearTimeout(reconnectTimer)\n currentConnection?.close()\n currentConnection = null\n },\n }\n}\n\n// ── Document processing waiter ───────────────────────────────────────────────\n\nconst DOC_TERMINAL_STATUSES = new Set(['completed', 'failed', 'skipped'])\n\nexport interface DocumentWaiterOptions {\n /** Base URL of the ARBI server (e.g. \"https://app.arbi.city\"). */\n baseUrl: string\n /** JWT access token for WebSocket authentication. */\n accessToken: string\n /** Optional callback invoked for every task_update on tracked documents. */\n onStatus?: (msg: WsTaskUpdateMessage) => void\n}\n\nexport interface DocumentWaiter {\n /** Register document IDs to track. Can be called multiple times. */\n addDocIds(ids: string[]): void\n /** Block until all tracked documents reach terminal status. */\n waitUntilDone(timeoutMs?: number): Promise<Map<string, string>>\n /** Close the WebSocket without waiting. */\n close(): void\n}\n\n/**\n * Open a WebSocket and start collecting document status events.\n *\n * Call this BEFORE uploading so no events are missed. Then call `addDocIds()`\n * once you know the IDs, and `waitUntilDone()` to block until all reach a\n * terminal status (completed, failed, or skipped).\n *\n * Mirrors the backend SDK's `ArbiWebSocket.wait_for_docs()` pattern.\n *\n * @example\n * ```ts\n * const waiter = createDocumentWaiter({ baseUrl, accessToken })\n * const result = await uploadDocuments(...)\n * waiter.addDocIds(result.doc_ext_ids)\n * const statuses = await waiter.waitUntilDone(120_000)\n * ```\n */\nexport function createDocumentWaiter(options: DocumentWaiterOptions): DocumentWaiter {\n const { baseUrl, accessToken, onStatus } = options\n\n const tracked = new Set<string>()\n const results = new Map<string, string>()\n let resolveWait: ((results: Map<string, string>) => void) | null = null\n let authenticated = false\n\n const url = buildWebSocketUrl(baseUrl)\n const ws = new WebSocket(url)\n\n const checkDone = () => {\n if (resolveWait && [...tracked].every((id) => results.has(id))) {\n resolveWait(results)\n resolveWait = null\n }\n }\n\n ws.addEventListener('open', () => {\n ws.send(createAuthMessage(accessToken))\n })\n\n ws.addEventListener('message', (event) => {\n const data = typeof event.data === 'string' ? event.data : String(event.data)\n const msg = parseServerMessage(data)\n if (!msg) return\n\n if (!authenticated) {\n if (msg.type === 'auth_result') {\n authenticated = (msg as { success?: boolean }).success === true\n }\n return\n }\n\n if (isMessageType<WsTaskUpdateMessage>(msg, 'task_update')) {\n if (!tracked.has(msg.doc_ext_id)) return\n\n onStatus?.(msg)\n\n if (DOC_TERMINAL_STATUSES.has(msg.status)) {\n results.set(msg.doc_ext_id, msg.status)\n checkDone()\n }\n }\n })\n\n return {\n addDocIds(ids: string[]) {\n for (const id of ids) tracked.add(id)\n checkDone()\n },\n\n waitUntilDone(timeoutMs = 120_000): Promise<Map<string, string>> {\n if ([...tracked].every((id) => results.has(id))) {\n ws.close()\n return Promise.resolve(results)\n }\n\n return new Promise<Map<string, string>>((resolve, reject) => {\n resolveWait = (r) => {\n ws.close()\n resolve(r)\n }\n\n setTimeout(() => {\n const pending = [...tracked].filter((id) => !results.has(id))\n ws.close()\n reject(\n new Error(\n `waitForDocuments timed out after ${timeoutMs}ms. Still pending: ${pending.join(', ')}`\n )\n )\n }, timeoutMs)\n })\n },\n\n close() {\n ws.close()\n },\n }\n}\n\n// ── Message formatting (shared by TUI + CLI) ────────────────────────────────\n\nexport type MessageLevel = 'info' | 'success' | 'error' | 'warning'\n\nexport interface FormattedWsMessage {\n text: string\n level: MessageLevel\n}\n\n/** Check if a message is a notification (has sender/recipient, not a system message). */\nfunction isNotification(msg: WebSocketServerMessage): msg is WsNotificationResponse {\n return 'sender' in msg && 'recipient' in msg\n}\n\n/**\n * Format a WebSocket message into display text + severity level.\n * Shared by TUI (toasts) and CLI (stderr lines) — single source of truth.\n */\nexport function formatWsMessage(msg: WebSocketServerMessage): FormattedWsMessage {\n if (isMessageType<WsTaskUpdateMessage>(msg, 'task_update')) {\n const progress = msg.progress > 0 ? ` (${Math.round(msg.progress)}%)` : ''\n const text = `${msg.file_name} — ${msg.status}${progress}`\n\n if (msg.status === 'completed') return { text, level: 'success' }\n if (msg.status === 'failed') return { text, level: 'error' }\n return { text, level: 'info' }\n }\n\n if (isMessageType<WsBatchCompleteMessage>(msg, 'batch_complete')) {\n const count = msg.doc_ext_ids.length\n return {\n text: `Batch complete: ${msg.batch_type} — ${count} doc${count !== 1 ? 's' : ''}`,\n level: 'success',\n }\n }\n\n if (isMessageType<WsErrorMessage>(msg, 'error')) {\n return { text: msg.message, level: 'error' }\n }\n\n if (isMessageType<WsPresenceUpdateMessage>(msg, 'presence_update')) {\n return { text: `${msg.user_id} is ${msg.status}`, level: 'info' }\n }\n\n if (isNotification(msg)) {\n const sender = msg.sender?.email || 'someone'\n const content = msg.content ?? msg.type\n return { text: `${sender}: ${content}`, level: 'info' }\n }\n\n return { text: `${msg.type}`, level: 'info' }\n}\n","/**\n * Shared formatting utilities.\n */\n\n/**\n * Converts file size in bytes to human-readable format.\n *\n * @param bytes File size in bytes\n * @param fallback String to return for null/undefined values (default: 'N/A')\n * @returns Formatted string (e.g., \"1.5 MB\", \"250 KB\")\n */\nexport function formatFileSize(bytes: number | null | undefined, fallback = 'N/A'): string {\n if (bytes === null || bytes === undefined) return fallback\n\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`\n}\n\n/** Minimal user shape used for display formatting. */\nexport type UserInfo = {\n external_id?: string\n email?: string\n given_name?: string\n family_name?: string\n}\n\n/**\n * Format a user's display name from given_name + family_name.\n * Returns empty string if no name parts are available.\n */\nexport function formatUserName(user: UserInfo | null | undefined): string {\n if (!user) return ''\n return [user.given_name, user.family_name].filter(Boolean).join(' ')\n}\n","/**\n * Document operations — list, get, delete, update, upload-url, parsed content, upload, download.\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { ArbiClient, components } from '@arbidocs/client'\nimport { requireData, requireOk } from '../errors.js'\nimport { authenticatedFetch, type AuthHeaders } from '../fetch.js'\n\ntype DocUpdateRequest = components['schemas']['DocUpdateRequest']\n\nexport async function listDocuments(arbi: ArbiClient) {\n return requireData(await arbi.fetch.GET('/v1/document/list'), 'Failed to fetch documents')\n}\n\nexport async function getDocuments(arbi: ArbiClient, externalIds: string[]) {\n return requireData(\n await arbi.fetch.GET('/v1/document/', { params: { query: { external_ids: externalIds } } }),\n 'Failed to fetch documents'\n )\n}\n\nexport async function deleteDocuments(arbi: ArbiClient, externalIds: string[]) {\n requireOk(\n await arbi.fetch.DELETE('/v1/document/', { body: { external_ids: externalIds } }),\n 'Failed to delete documents'\n )\n}\n\nexport async function updateDocuments(arbi: ArbiClient, documents: DocUpdateRequest[]) {\n return requireData(\n await arbi.fetch.PATCH('/v1/document/', { body: { documents } }),\n 'Failed to update documents'\n )\n}\n\nexport async function uploadUrl(\n arbi: ArbiClient,\n urls: string[],\n workspaceId: string,\n shared = false\n) {\n return requireData(\n await arbi.fetch.POST('/v1/document/upload-url', {\n params: {\n query: { urls, workspace_ext_id: workspaceId, shared },\n },\n }),\n 'Failed to upload from URLs'\n )\n}\n\n/**\n * Get parsed document content.\n */\nexport async function getParsedContent(\n auth: AuthHeaders,\n docId: string,\n stage: string\n): Promise<Record<string, unknown>> {\n const res = await authenticatedFetch({\n ...auth,\n path: `/v1/document/${docId}/parsed-${stage}`,\n })\n return res.json() as Promise<Record<string, unknown>>\n}\n\n/**\n * Upload a file to a workspace. Uses raw fetch for multipart upload.\n */\nexport async function uploadFile(\n auth: AuthHeaders,\n workspaceId: string,\n fileData: Blob,\n fileName: string\n): Promise<{ doc_ext_ids: string[]; duplicates?: string[] }> {\n const formData = new FormData()\n formData.append('files', fileData, fileName)\n\n const res = await authenticatedFetch({\n ...auth,\n path: `/v1/document/upload?workspace_ext_id=${workspaceId}`,\n method: 'POST',\n body: formData,\n })\n\n return res.json() as Promise<{ doc_ext_ids: string[]; duplicates?: string[] }>\n}\n\n/**\n * Upload a local file by path. Handles readFileSync + basename + Blob + uploadFile.\n * Convenience wrapper for CLI/TUI consumers that work with file system paths.\n */\nexport async function uploadLocalFile(\n auth: AuthHeaders,\n workspaceId: string,\n filePath: string\n): Promise<{ doc_ext_ids: string[]; duplicates?: string[]; fileName: string }> {\n const fileBuffer = fs.readFileSync(filePath)\n const fileName = path.basename(filePath)\n const result = await uploadFile(auth, workspaceId, new Blob([fileBuffer]), fileName)\n return { ...result, fileName }\n}\n\n/**\n * Download a document. Returns the response for the caller to handle.\n */\nexport async function downloadDocument(auth: AuthHeaders, docId: string): Promise<Response> {\n return authenticatedFetch({\n ...auth,\n path: `/v1/document/${docId}/download`,\n })\n}\n","/**\n * Workspace operations — list, create, delete, update, users, copy.\n */\n\nimport type { ArbiClient, components } from '@arbidocs/client'\nimport { requireData, requireOk } from '../errors.js'\n\ntype WorkspaceUpdateRequest = components['schemas']['WorkspaceUpdateRequest']\n\nexport async function listWorkspaces(arbi: ArbiClient) {\n return requireData(await arbi.fetch.GET('/v1/user/workspaces'), 'Failed to fetch workspaces')\n}\n\nexport async function createWorkspace(\n arbi: ArbiClient,\n name: string,\n description?: string | null,\n isPublic = false\n) {\n return requireData(\n await arbi.fetch.POST('/v1/workspace/create_protected', {\n body: { name, description: description ?? null, is_public: isPublic },\n }),\n 'Failed to create workspace'\n )\n}\n\nexport async function deleteWorkspaces(arbi: ArbiClient, workspaceIds: string[]) {\n requireOk(\n await arbi.fetch.DELETE('/v1/workspace/', {\n body: { external_ids: workspaceIds },\n }),\n 'Failed to delete workspace(s)'\n )\n}\n\nexport async function updateWorkspace(arbi: ArbiClient, body: WorkspaceUpdateRequest) {\n return requireData(\n await arbi.fetch.PATCH('/v1/workspace/', { body }),\n 'Failed to update workspace'\n )\n}\n\nexport async function listWorkspaceUsers(arbi: ArbiClient) {\n return requireData(await arbi.fetch.GET('/v1/workspace/users'), 'Failed to fetch workspace users')\n}\n\nexport async function addWorkspaceUsers(\n arbi: ArbiClient,\n emails: string[],\n role: 'owner' | 'collaborator' | 'guest' = 'collaborator'\n) {\n return requireData(\n await arbi.fetch.POST('/v1/workspace/users', {\n body: { emails, role },\n }),\n 'Failed to add users'\n )\n}\n\nexport async function removeWorkspaceUsers(arbi: ArbiClient, userIds: string[]) {\n requireOk(\n await arbi.fetch.DELETE('/v1/workspace/users', {\n body: { users: userIds.map((id) => ({ user_ext_id: id })) },\n }),\n 'Failed to remove users'\n )\n}\n\nexport async function setUserRole(\n arbi: ArbiClient,\n userIds: string[],\n role: 'owner' | 'collaborator' | 'guest'\n) {\n return requireData(\n await arbi.fetch.PATCH('/v1/workspace/users', {\n body: { user_ext_ids: userIds, role },\n }),\n 'Failed to update roles'\n )\n}\n\nexport async function copyDocuments(\n arbi: ArbiClient,\n targetWorkspaceId: string,\n docIds: string[],\n targetWorkspaceKey: string\n) {\n return requireData(\n await arbi.fetch.POST('/v1/workspace/copy', {\n body: {\n target_workspace_ext_id: targetWorkspaceId,\n target_workspace_key: targetWorkspaceKey,\n items: docIds,\n },\n }),\n 'Failed to copy documents'\n )\n}\n","/**\n * Conversation operations — list, threads, delete, share, title, messages.\n */\n\nimport type { ArbiClient } from '@arbidocs/client'\nimport { requireData } from '../errors.js'\n\nexport async function listConversations(arbi: ArbiClient) {\n return requireData(await arbi.fetch.GET('/v1/conversation/list'), 'Failed to fetch conversations')\n}\n\nexport async function getConversationThreads(arbi: ArbiClient, conversationId: string) {\n return requireData(\n await arbi.fetch.GET('/v1/conversation/{conversation_ext_id}/threads', {\n params: { path: { conversation_ext_id: conversationId } },\n }),\n 'Failed to fetch threads'\n )\n}\n\nexport async function deleteConversation(arbi: ArbiClient, conversationId: string) {\n return requireData(\n await arbi.fetch.DELETE('/v1/conversation/{conversation_ext_id}', {\n params: { path: { conversation_ext_id: conversationId } },\n }),\n 'Failed to delete conversation'\n )\n}\n\nexport async function shareConversation(arbi: ArbiClient, conversationId: string) {\n return requireData(\n await arbi.fetch.POST('/v1/conversation/{conversation_ext_id}/share', {\n params: { path: { conversation_ext_id: conversationId } },\n }),\n 'Failed to share conversation'\n )\n}\n\nexport async function updateConversationTitle(\n arbi: ArbiClient,\n conversationId: string,\n title: string\n) {\n return requireData(\n await arbi.fetch.PATCH('/v1/conversation/{conversation_ext_id}/title', {\n params: { path: { conversation_ext_id: conversationId } },\n body: { title },\n }),\n 'Failed to update title'\n )\n}\n\nexport async function getMessage(arbi: ArbiClient, messageId: string) {\n return requireData(\n await arbi.fetch.GET('/v1/conversation/message/{message_ext_id}', {\n params: { path: { message_ext_id: messageId } },\n }),\n 'Failed to fetch message'\n )\n}\n\nexport async function deleteMessage(arbi: ArbiClient, messageId: string) {\n return requireData(\n await arbi.fetch.DELETE('/v1/conversation/message/{message_ext_id}', {\n params: { path: { message_ext_id: messageId } },\n }),\n 'Failed to delete message'\n )\n}\n","/**\n * Assistant operations — retrieve (search-only) and query (with LLM).\n *\n * retrieve: Uses the typed SDK route POST /v1/assistant/retrieve.\n * Returns matching chunks without LLM generation.\n *\n * queryAssistant: Returns the raw Response for SSE streaming.\n * Uses raw fetch because the SDK client doesn't support streaming responses.\n */\n\nimport type { ArbiClient, components } from '@arbidocs/client'\nimport { requireData } from '../errors.js'\nimport { authenticatedFetch, type AuthHeaders } from '../fetch.js'\n\ntype MessageInput = components['schemas']['MessageInput']\ntype ToolEntry = NonNullable<MessageInput['tools']>[string]\n\n// ── Retrieval tool builder ──────────────────────────────────────────────────\n\nexport function buildRetrievalChunkTool(\n docIds: string[],\n searchMode?: 'semantic' | 'keyword' | 'hybrid'\n): components['schemas']['RetrievalChunkTool'] {\n return {\n name: 'retrieval_chunk',\n description: 'retrieval chunk',\n tool_args: { doc_ext_ids: docIds, ...(searchMode ? { search_mode: searchMode } : {}) },\n tool_responses: {},\n }\n}\n\nexport function buildRetrievalFullContextTool(\n docIds: string[]\n): components['schemas']['RetrievalFullContextTool'] {\n return {\n name: 'retrieval_full_context',\n description: 'retrieval full context',\n tool_args: { doc_ext_ids: docIds },\n tool_responses: {},\n }\n}\n\nexport function buildRetrievalTocTool(docIds: string[]): components['schemas']['RetrievalTOCTool'] {\n return {\n name: 'retrieval_toc',\n description: 'retrieval toc',\n tool_args: { doc_ext_ids: docIds },\n tool_responses: {},\n }\n}\n\n// ── Retrieve (search-only, uses typed SDK) ──────────────────────────────────\n\nexport interface RetrieveOptions {\n arbi: ArbiClient\n workspaceId: string\n query: string\n docIds: string[]\n searchMode?: 'semantic' | 'keyword' | 'hybrid'\n fullContextDocIds?: string[]\n tocDocIds?: string[]\n model?: string\n}\n\nexport interface ChunkMetadata {\n doc_ext_id?: string | null\n doc_title?: string | null\n chunk_ext_id: string\n chunk_pg_idx: number\n chunk_doc_idx: number\n page_number: number\n score?: number | null\n rerank_score?: number | null\n tokens?: number | null\n created_at: string\n heading: boolean\n}\n\nexport interface Chunk {\n metadata: ChunkMetadata\n content: string\n}\n\nexport interface RetrieveResult {\n retrieval_chunk?: {\n tool_responses: Record<string, Chunk[]>\n }\n retrieval_full_context?: {\n tool_responses: Record<string, Chunk[]>\n }\n retrieval_toc?: {\n tool_responses: Record<string, Record<string, unknown>[]>\n }\n}\n\n/**\n * Search documents and return matching chunks without LLM generation.\n * Uses the typed SDK route POST /v1/assistant/retrieve.\n */\nexport async function retrieve(options: RetrieveOptions): Promise<RetrieveResult> {\n const { arbi, workspaceId, query, docIds, searchMode, fullContextDocIds, tocDocIds, model } =\n options\n\n const tools: Record<string, ToolEntry> = {\n retrieval_chunk: buildRetrievalChunkTool(docIds, searchMode),\n }\n\n if (fullContextDocIds && fullContextDocIds.length > 0) {\n tools.retrieval_full_context = buildRetrievalFullContextTool(fullContextDocIds)\n }\n\n if (tocDocIds && tocDocIds.length > 0) {\n tools.retrieval_toc = buildRetrievalTocTool(tocDocIds)\n }\n\n const body: MessageInput = {\n input: query,\n workspace_ext_id: workspaceId,\n stream: false,\n tools,\n ...(model ? { model } : {}),\n }\n\n const { data, error } = await arbi.fetch.POST('/v1/assistant/retrieve', { body })\n\n if (error) {\n throw new Error(`Retrieve failed: ${JSON.stringify(error)}`)\n }\n\n // Response type is `unknown` in schema, cast to our typed result\n return data as RetrieveResult\n}\n\n// ── Query (with LLM, raw fetch for SSE streaming) ───────────────────────────\n\nexport interface AssistantQueryOptions extends AuthHeaders {\n workspaceId: string\n question: string\n docIds: string[]\n previousResponseId?: string | null\n model?: string\n}\n\n/**\n * Send a query to the RAG assistant. Returns the raw Response\n * so the caller can stream or buffer as needed.\n *\n * Uses raw fetch (not the SDK client) because we need the streaming\n * Response body — the SDK client consumes the body to parse JSON.\n */\nexport async function queryAssistant(options: AssistantQueryOptions): Promise<Response> {\n const { workspaceId, question, docIds, previousResponseId, model, ...auth } = options\n\n const body: MessageInput = {\n input: question,\n workspace_ext_id: workspaceId,\n stream: true,\n tools: {\n retrieval_chunk: buildRetrievalChunkTool(docIds),\n retrieval_full_context: buildRetrievalFullContextTool([]),\n },\n ...(previousResponseId ? { previous_response_id: previousResponseId } : {}),\n ...(model ? { model } : {}),\n }\n\n return authenticatedFetch({\n ...auth,\n path: '/v1/assistant/query',\n method: 'POST',\n body: JSON.stringify(body),\n headers: { 'Content-Type': 'application/json' },\n })\n}\n\n// ── Respond to agent (human-in-the-loop) ──────────────────────────────────\n\n/**\n * Respond to an agent's question during a human-in-the-loop workflow.\n * The assistant_message_ext_id identifies which agent message to answer.\n */\nexport async function respondToAgent(\n arbi: ArbiClient,\n assistantMessageExtId: string,\n answer: string\n) {\n return requireData(\n await arbi.fetch.POST('/v1/assistant/respond', {\n body: { assistant_message_ext_id: assistantMessageExtId, answer },\n }),\n 'Failed to respond to agent'\n )\n}\n","/**\n * Tag operations — list, create, delete, update.\n */\n\nimport type { ArbiClient, components } from '@arbidocs/client'\nimport { requireData } from '../errors.js'\n\ntype UpdateTagRequest = components['schemas']['UpdateTagRequest']\n\nexport async function listTags(arbi: ArbiClient) {\n return requireData(await arbi.fetch.GET('/v1/tag/list'), 'Failed to fetch tags')\n}\n\nexport async function createTag(\n arbi: ArbiClient,\n options: {\n name: string\n workspaceId?: string\n tagType?: components['schemas']['TagFormat']\n instruction?: string | null\n shared?: boolean\n }\n) {\n return requireData(\n await arbi.fetch.POST('/v1/tag/', {\n body: {\n name: options.name,\n tag_type: options.tagType ?? { type: 'checkbox', options: [] },\n instruction: options.instruction ?? null,\n shared: options.shared ?? false,\n },\n }),\n 'Failed to create tag'\n )\n}\n\nexport async function deleteTag(arbi: ArbiClient, tagId: string) {\n return requireData(\n await arbi.fetch.DELETE('/v1/tag/{tag_ext_id}', {\n params: { path: { tag_ext_id: tagId } },\n }),\n 'Failed to delete tag'\n )\n}\n\nexport async function updateTag(arbi: ArbiClient, tagId: string, body: UpdateTagRequest) {\n return requireData(\n await arbi.fetch.PATCH('/v1/tag/{tag_ext_id}', {\n params: { path: { tag_ext_id: tagId } },\n body,\n }),\n 'Failed to update tag'\n )\n}\n","/**\n * Contact operations — list, add, remove.\n */\n\nimport type { ArbiClient } from '@arbidocs/client'\nimport { requireData, requireOk } from '../errors.js'\n\nexport async function listContacts(arbi: ArbiClient) {\n return requireData(await arbi.fetch.GET('/v1/user/contacts'), 'Failed to fetch contacts')\n}\n\nexport async function addContacts(arbi: ArbiClient, emails: string[]) {\n return requireData(\n await arbi.fetch.POST('/v1/user/contacts', { body: { emails } }),\n 'Failed to add contacts'\n )\n}\n\nexport async function removeContacts(arbi: ArbiClient, contactIds: string[]) {\n requireOk(\n await arbi.fetch.DELETE('/v1/user/contacts', { body: { contact_ids: contactIds } }),\n 'Failed to remove contacts'\n )\n}\n\n/**\n * Group contacts by registration status.\n * Returns registered contacts and pending (not yet registered) contacts.\n */\nexport function groupContactsByStatus<T extends { status: string }>(\n contactList: T[]\n): { registered: T[]; pending: T[] } {\n const registered: T[] = []\n const pending: T[] = []\n for (const c of contactList) {\n if (c.status === 'registered') {\n registered.push(c)\n } else {\n pending.push(c)\n }\n }\n return { registered, pending }\n}\n","/**\n * Document-tag (doctag) operations — assign, remove, generate.\n */\n\nimport type { ArbiClient, components } from '@arbidocs/client'\nimport { requireData, requireOk } from '../errors.js'\n\ntype CitationData = components['schemas']['CitationData']\n\nexport async function assignDocTags(\n arbi: ArbiClient,\n tagId: string,\n docIds: string[],\n note?: string | null\n) {\n return requireData(\n await arbi.fetch.POST('/v1/document/doctag', {\n body: { tag_ext_id: tagId, doc_ext_ids: docIds, note: note ?? null },\n }),\n 'Failed to create doctags'\n )\n}\n\nexport async function removeDocTags(arbi: ArbiClient, tagId: string, docIds: string[]) {\n requireOk(\n await arbi.fetch.DELETE('/v1/document/doctag', {\n body: { tag_ext_id: tagId, doc_ext_ids: docIds },\n }),\n 'Failed to delete doctags'\n )\n}\n\nexport async function updateDocTag(\n arbi: ArbiClient,\n tagId: string,\n docId: string,\n updates: { note?: string | null; citations?: Record<string, CitationData> | null }\n) {\n return requireData(\n await arbi.fetch.PATCH('/v1/document/doctag', {\n body: { tag_ext_id: tagId, doc_ext_id: docId, ...updates },\n }),\n 'Failed to update doctag'\n )\n}\n\nexport async function generateDocTags(arbi: ArbiClient, tagIds: string[], docIds: string[]) {\n return requireData(\n await arbi.fetch.POST('/v1/document/doctag/generate', {\n body: { tag_ext_ids: tagIds, doc_ext_ids: docIds },\n }),\n 'Failed to generate doctags'\n )\n}\n","/**\n * Direct message / notification operations — list, send, mark read, delete.\n */\n\nimport type { ArbiClient } from '@arbidocs/client'\nimport { requireData, requireOk } from '../errors.js'\n\nexport async function listDMs(arbi: ArbiClient) {\n return requireData(await arbi.fetch.GET('/v1/notifications/'), 'Failed to fetch messages')\n}\n\nexport async function sendDM(\n arbi: ArbiClient,\n messages: Array<{ recipient_ext_id: string; content: string }>\n) {\n return requireData(\n await arbi.fetch.POST('/v1/notifications/', {\n body: { messages },\n }),\n 'Failed to send message'\n )\n}\n\nexport async function markRead(arbi: ArbiClient, messageIds: string[]) {\n return requireData(\n await arbi.fetch.PATCH('/v1/notifications/', {\n body: { updates: messageIds.map((id) => ({ external_id: id, read: true })) },\n }),\n 'Failed to update messages'\n )\n}\n\nexport async function deleteDMs(arbi: ArbiClient, messageIds: string[]) {\n requireOk(\n await arbi.fetch.DELETE('/v1/notifications/', { body: { external_ids: messageIds } }),\n 'Failed to delete messages'\n )\n}\n","/**\n * User settings operations — get, update.\n */\n\nimport type { ArbiClient, components } from '@arbidocs/client'\nimport { requireData, requireOk } from '../errors.js'\n\ntype UserSettingsUpdate = components['schemas']['UserSettingsUpdate']\n\nexport async function getSettings(arbi: ArbiClient) {\n return requireData(await arbi.fetch.GET('/v1/user/settings'), 'Failed to fetch settings')\n}\n\nexport async function updateSettings(arbi: ArbiClient, body: UserSettingsUpdate) {\n requireOk(await arbi.fetch.PATCH('/v1/user/settings', { body }), 'Failed to update settings')\n}\n","/**\n * Agent configuration operations — list, get, save, delete, schema, models.\n */\n\nimport type { ArbiClient, components } from '@arbidocs/client'\nimport { requireData } from '../errors.js'\n\ntype ConfigUpdateData = components['schemas']['ConfigUpdateData']\n\nexport async function listConfigs(arbi: ArbiClient) {\n return requireData(\n await arbi.fetch.GET('/v1/configs/versions'),\n 'Failed to fetch config versions'\n )\n}\n\nexport async function getConfig(arbi: ArbiClient, configId: string) {\n return requireData(\n await arbi.fetch.GET('/v1/configs/{config_ext_id}', {\n params: { path: { config_ext_id: configId } },\n }),\n 'Failed to fetch configuration'\n )\n}\n\nexport async function saveConfig(arbi: ArbiClient, body: ConfigUpdateData) {\n return requireData(\n await arbi.fetch.POST('/v1/configs/', { body }),\n 'Failed to save configuration'\n )\n}\n\nexport async function deleteConfig(arbi: ArbiClient, configId: string) {\n return requireData(\n await arbi.fetch.DELETE('/v1/configs/{config_ext_id}', {\n params: { path: { config_ext_id: configId } },\n }),\n 'Failed to delete configuration'\n )\n}\n\nexport async function getSchema(arbi: ArbiClient) {\n return requireData(await arbi.fetch.GET('/v1/configs/schema'), 'Failed to fetch config schema')\n}\n\nexport async function getModels(arbi: ArbiClient) {\n return requireData(await arbi.fetch.GET('/v1/health/models'), 'Failed to fetch models')\n}\n","/**\n * Health and model operations.\n */\n\nimport type { ArbiClient } from '@arbidocs/client'\nimport { requireData } from '../errors.js'\n\nexport async function getHealth(arbi: ArbiClient) {\n return requireData(await arbi.fetch.GET('/v1/health/'), 'Failed to fetch health status')\n}\n\nexport async function getHealthModels(arbi: ArbiClient) {\n return requireData(await arbi.fetch.GET('/v1/health/models'), 'Failed to fetch models')\n}\n\nexport async function getRemoteModels(arbi: ArbiClient) {\n return requireData(\n await arbi.fetch.GET('/v1/health/remote-models'),\n 'Failed to fetch remote models'\n )\n}\n\nexport async function getMcpTools(arbi: ArbiClient) {\n return requireData(await arbi.fetch.GET('/v1/health/mcp-tools'), 'Failed to fetch MCP tools')\n}\n","/**\n * File operations — OpenAI-compatible Files API (list, get, delete, upload, content).\n */\n\nimport type { ArbiClient, components } from '@arbidocs/client'\nimport { requireData } from '../errors.js'\nimport { authenticatedFetch, type AuthHeaders } from '../fetch.js'\n\ntype FileObject = components['schemas']['FileObject']\ntype FileDeleteResponse = components['schemas']['FileDeleteResponse']\ntype FileListResponse = components['schemas']['FileListResponse']\n\nexport type { FileObject, FileDeleteResponse, FileListResponse }\n\nexport interface ListFilesOptions {\n purpose?: string | null\n limit?: number\n order?: string\n after?: string | null\n}\n\nexport async function listFiles(arbi: ArbiClient, options?: ListFilesOptions) {\n return requireData(\n await arbi.fetch.GET('/v1/files', {\n params: { query: options ?? {} },\n }),\n 'Failed to list files'\n )\n}\n\nexport async function getFile(arbi: ArbiClient, fileId: string) {\n return requireData(\n await arbi.fetch.GET('/v1/files/{file_id}', {\n params: { path: { file_id: fileId } },\n }),\n 'Failed to get file'\n )\n}\n\nexport async function deleteFile(arbi: ArbiClient, fileId: string) {\n return requireData(\n await arbi.fetch.DELETE('/v1/files/{file_id}', {\n params: { path: { file_id: fileId } },\n }),\n 'Failed to delete file'\n )\n}\n\n/**\n * Upload a file via the OpenAI-compatible Files API.\n * Uses raw fetch for multipart upload.\n */\nexport async function uploadFile(\n auth: AuthHeaders,\n fileData: Blob,\n fileName: string,\n purpose = 'assistants'\n): Promise<FileObject> {\n const formData = new FormData()\n formData.append('file', fileData, fileName)\n formData.append('purpose', purpose)\n\n const res = await authenticatedFetch({\n ...auth,\n path: '/v1/files',\n method: 'POST',\n body: formData,\n })\n\n return res.json() as Promise<FileObject>\n}\n\n/**\n * Get file content (binary). Returns the raw Response for the caller to handle.\n */\nexport async function getFileContent(auth: AuthHeaders, fileId: string): Promise<Response> {\n return authenticatedFetch({\n ...auth,\n path: `/v1/files/${fileId}/content`,\n })\n}\n","/**\n * High-level convenience class that wraps the full ARBI stack into a simple API.\n *\n * Handles SDK client creation, sodium initialization, authentication,\n * workspace key decryption, and delegates to all operations modules.\n *\n * Usage:\n * const arbi = new Arbi({ url: 'https://arbi.mycompany.com' })\n * await arbi.login('user@example.com', 'password')\n * const workspaces = await arbi.workspaces.list()\n * await arbi.selectWorkspace(workspaces[0].external_id)\n * const docs = await arbi.documents.list()\n */\n\nimport {\n createArbiClient,\n type ArbiClient,\n type LoginResult,\n type components,\n} from '@arbidocs/client'\n\ntype DocUpdateRequest = components['schemas']['DocUpdateRequest']\ntype WorkspaceUpdateRequest = components['schemas']['WorkspaceUpdateRequest']\ntype UpdateTagRequest = components['schemas']['UpdateTagRequest']\ntype TagFormat = components['schemas']['TagFormat']\ntype CitationData = components['schemas']['CitationData']\ntype UserSettingsUpdate = components['schemas']['UserSettingsUpdate']\ntype ConfigUpdateData = components['schemas']['ConfigUpdateData']\nimport { ArbiError } from './errors.js'\nimport { selectWorkspace as selectWorkspaceInternal } from './auth.js'\nimport { streamSSE, type SSEStreamCallbacks, type SSEStreamResult } from './sse.js'\nimport type {\n SSEStreamStartData,\n AgentStepEvent,\n UserMessageEvent,\n MessageMetadataPayload,\n UserInputRequestEvent,\n ArtifactEvent,\n} from './sse-types.js'\nimport * as documentsOps from './operations/documents.js'\nimport * as workspacesOps from './operations/workspaces.js'\nimport * as conversationsOps from './operations/conversations.js'\nimport * as assistantOps from './operations/assistant.js'\nimport * as tagsOps from './operations/tags.js'\nimport * as contactsOps from './operations/contacts.js'\nimport * as doctagsOps from './operations/doctags.js'\nimport * as dmOps from './operations/dm.js'\nimport * as settingsOps from './operations/settings.js'\nimport * as agentconfigOps from './operations/agentconfig.js'\nimport * as healthOps from './operations/health.js'\nimport * as filesOps from './operations/files.js'\n\n// ── Options ─────────────────────────────────────────────────────────────────\n\nexport interface ArbiOptions {\n /** Backend API URL (e.g. 'https://arbi.mycompany.com') */\n url: string\n /** Deployment domain for key derivation. Defaults to hostname of url. */\n deploymentDomain?: string\n /** Include credentials (cookies) in requests. Default: 'omit' for SDK consumers. */\n credentials?: 'include' | 'omit' | 'same-origin'\n}\n\n// ── Assistant query options ─────────────────────────────────────────────────\n\nexport interface QueryOptions {\n /** Document IDs to search against */\n docIds: string[]\n /** Previous response ID for follow-up questions */\n previousResponseId?: string | null\n /** Model to use for generation */\n model?: string\n /** Called for each streaming token */\n onToken?: (content: string) => void\n /** Called when stream starts */\n onStreamStart?: (data: SSEStreamStartData) => void\n /** Called for each agent step */\n onAgentStep?: (data: AgentStepEvent) => void\n /** Called on stream error */\n onError?: (message: string) => void\n /** Called when a user message event is received */\n onUserMessage?: (data: UserMessageEvent) => void\n /** Called when message metadata is received */\n onMetadata?: (data: MessageMetadataPayload) => void\n /** Called when the agent requests user input */\n onUserInputRequest?: (data: UserInputRequestEvent) => void\n /** Called when an artifact event is received */\n onArtifact?: (data: ArtifactEvent) => void\n /** Called when backend elapsed time is received */\n onElapsedTime?: (t: number) => void\n /** Called when stream completes */\n onComplete?: () => void\n}\n\n// ── Arbi class ──────────────────────────────────────────────────────────────\n\nexport class Arbi {\n private client: ArbiClient | null = null\n private loginResult: LoginResult | null = null\n private currentWorkspaceId: string | null = null\n private readonly options: ArbiOptions\n\n constructor(options: ArbiOptions) {\n this.options = options\n }\n\n // ── Lifecycle ───────────────────────────────────────────────────────────\n\n /** Initialize the SDK client and sodium crypto. Called automatically by login(). */\n async init(): Promise<ArbiClient> {\n if (this.client) return this.client\n\n const domain = this.options.deploymentDomain ?? new URL(this.options.url).hostname\n\n this.client = createArbiClient({\n baseUrl: this.options.url,\n deploymentDomain: domain,\n credentials: this.options.credentials ?? 'omit',\n })\n\n await this.client.crypto.initSodium()\n return this.client\n }\n\n /**\n * Request a verification email for registration.\n * The user will receive an email with a 3-word verification code.\n */\n async requestVerification(email: string): Promise<void> {\n const client = await this.init()\n await client.fetch.POST('/v1/user/verify-email', { body: { email } })\n }\n\n /**\n * Register a new account using the verification code received by email.\n */\n async register(params: {\n email: string\n password: string\n verificationCode: string\n firstName?: string\n lastName?: string\n }): Promise<void> {\n const client = await this.init()\n await client.auth.register(params)\n }\n\n /**\n * Log in with email and password.\n * Initializes the SDK client if not already done.\n */\n async login(email: string, password: string): Promise<void> {\n const client = await this.init()\n this.loginResult = await client.auth.login({ email, password })\n }\n\n /**\n * Recover a session using a stored signing private key (base64).\n * Useful for session recovery without re-entering the password.\n */\n async loginWithKey(email: string, signingPrivateKeyBase64: string): Promise<void> {\n const client = await this.init()\n const signingPrivateKey = client.crypto.base64ToBytes(signingPrivateKeyBase64)\n this.loginResult = await client.auth.loginWithKey({ email, signingPrivateKey })\n }\n\n /**\n * Select a workspace by ID. Fetches the workspace list, finds the matching\n * workspace, decrypts the wrapped key, and sets up auth headers.\n */\n async selectWorkspace(workspaceId: string): Promise<void> {\n const client = this.requireClient()\n const lr = this.requireLogin()\n\n const allWorkspaces = await workspacesOps.listWorkspaces(client)\n const ws = allWorkspaces.find((w) => w.external_id === workspaceId)\n if (!ws || !ws.wrapped_key) {\n throw new ArbiError(`Workspace ${workspaceId} not found or has no encryption key`)\n }\n\n const signingPrivateKeyBase64 = client.crypto.bytesToBase64(lr.signingPrivateKey)\n await selectWorkspaceInternal(\n client,\n ws.external_id,\n ws.wrapped_key,\n lr.serverSessionKey,\n signingPrivateKeyBase64\n )\n\n this.currentWorkspaceId = ws.external_id\n }\n\n /** Log out and clear internal state. */\n async logout(): Promise<void> {\n if (this.client) {\n await this.client.auth.logout()\n }\n if (this.loginResult) {\n this.loginResult.signingPrivateKey.fill(0)\n this.loginResult.serverSessionKey.fill(0)\n }\n this.loginResult = null\n this.currentWorkspaceId = null\n }\n\n // ── Accessors ─────────────────────────────────────────────────────────\n\n /** Get the underlying ArbiClient (throws if not initialized). */\n getClient(): ArbiClient {\n return this.requireClient()\n }\n\n /** Get the current workspace ID (throws if none selected). */\n getWorkspaceId(): string {\n return this.requireWorkspace()\n }\n\n /** Check if the user is logged in. */\n get isLoggedIn(): boolean {\n return this.loginResult !== null\n }\n\n /** Check if a workspace is selected. */\n get hasWorkspace(): boolean {\n return this.currentWorkspaceId !== null\n }\n\n // ── Auth headers (for raw fetch operations) ───────────────────────────\n\n private getAuthHeaders() {\n const client = this.requireClient()\n const accessToken = client.session.getState().accessToken\n const workspaceKeyHeader = client.session.getWorkspaceKeyHeader()\n\n if (!accessToken || !workspaceKeyHeader) {\n throw new ArbiError('Missing access token or workspace key header')\n }\n\n return {\n baseUrl: this.options.url,\n accessToken,\n workspaceKeyHeader,\n }\n }\n\n // ── Workspaces ────────────────────────────────────────────────────────\n\n readonly workspaces = {\n list: () => workspacesOps.listWorkspaces(this.requireClient()),\n\n create: (name: string, description?: string | null, isPublic?: boolean) =>\n workspacesOps.createWorkspace(this.requireClient(), name, description, isPublic),\n\n delete: (workspaceIds: string[]) =>\n workspacesOps.deleteWorkspaces(this.requireClient(), workspaceIds),\n\n update: (body: WorkspaceUpdateRequest) =>\n workspacesOps.updateWorkspace(this.requireClient(), body),\n\n listUsers: () => workspacesOps.listWorkspaceUsers(this.requireClient()),\n\n addUsers: (emails: string[], role?: 'owner' | 'collaborator' | 'guest') =>\n workspacesOps.addWorkspaceUsers(this.requireClient(), emails, role),\n\n removeUsers: (userIds: string[]) =>\n workspacesOps.removeWorkspaceUsers(this.requireClient(), userIds),\n\n setUserRole: (userIds: string[], role: 'owner' | 'collaborator' | 'guest') =>\n workspacesOps.setUserRole(this.requireClient(), userIds, role),\n\n copyDocuments: (targetWorkspaceId: string, docIds: string[], targetWorkspaceKey: string) =>\n workspacesOps.copyDocuments(\n this.requireClient(),\n targetWorkspaceId,\n docIds,\n targetWorkspaceKey\n ),\n }\n\n // ── Documents ─────────────────────────────────────────────────────────\n\n readonly documents = {\n list: () => documentsOps.listDocuments(this.requireClient()),\n\n get: (externalIds: string[]) => documentsOps.getDocuments(this.requireClient(), externalIds),\n\n delete: (externalIds: string[]) =>\n documentsOps.deleteDocuments(this.requireClient(), externalIds),\n\n update: (documents: DocUpdateRequest[]) =>\n documentsOps.updateDocuments(this.requireClient(), documents),\n\n uploadUrl: (urls: string[], shared?: boolean, workspaceId?: string) =>\n documentsOps.uploadUrl(\n this.requireClient(),\n urls,\n workspaceId ?? this.requireWorkspace(),\n shared\n ),\n\n uploadFile: (fileData: Blob, fileName: string, workspaceId?: string) =>\n documentsOps.uploadFile(\n this.getAuthHeaders(),\n workspaceId ?? this.requireWorkspace(),\n fileData,\n fileName\n ),\n\n download: (docId: string) => documentsOps.downloadDocument(this.getAuthHeaders(), docId),\n\n getParsedContent: (docId: string, stage: string) =>\n documentsOps.getParsedContent(this.getAuthHeaders(), docId, stage),\n }\n\n // ── Conversations ─────────────────────────────────────────────────────\n\n readonly conversations = {\n list: () => conversationsOps.listConversations(this.requireClient()),\n\n getThreads: (conversationId: string) =>\n conversationsOps.getConversationThreads(this.requireClient(), conversationId),\n\n delete: (conversationId: string) =>\n conversationsOps.deleteConversation(this.requireClient(), conversationId),\n\n share: (conversationId: string) =>\n conversationsOps.shareConversation(this.requireClient(), conversationId),\n\n updateTitle: (conversationId: string, title: string) =>\n conversationsOps.updateConversationTitle(this.requireClient(), conversationId, title),\n\n getMessage: (messageId: string) => conversationsOps.getMessage(this.requireClient(), messageId),\n\n deleteMessage: (messageId: string) =>\n conversationsOps.deleteMessage(this.requireClient(), messageId),\n }\n\n // ── Assistant ─────────────────────────────────────────────────────────\n\n readonly assistant = {\n /**\n * Send a question to the RAG assistant with streaming support.\n * Returns the accumulated result after the stream completes.\n */\n query: async (question: string, options: QueryOptions): Promise<SSEStreamResult> => {\n const auth = this.getAuthHeaders()\n const workspaceId = this.requireWorkspace()\n\n const response = await assistantOps.queryAssistant({\n ...auth,\n workspaceId,\n question,\n docIds: options.docIds,\n previousResponseId: options.previousResponseId,\n model: options.model,\n })\n\n const callbacks: SSEStreamCallbacks = {\n onToken: options.onToken,\n onStreamStart: options.onStreamStart,\n onAgentStep: options.onAgentStep,\n onError: options.onError,\n onUserMessage: options.onUserMessage,\n onMetadata: options.onMetadata,\n onUserInputRequest: options.onUserInputRequest,\n onArtifact: options.onArtifact,\n onElapsedTime: options.onElapsedTime,\n onComplete: options.onComplete,\n }\n\n return streamSSE(response, callbacks)\n },\n\n /**\n * Respond to an agent's question during a human-in-the-loop workflow.\n */\n respond: (assistantMessageExtId: string, answer: string) =>\n assistantOps.respondToAgent(this.requireClient(), assistantMessageExtId, answer),\n\n /**\n * Search documents without LLM generation (retrieval only).\n */\n retrieve: (\n query: string,\n docIds: string[],\n options?: {\n searchMode?: 'semantic' | 'keyword' | 'hybrid'\n fullContextDocIds?: string[]\n tocDocIds?: string[]\n model?: string\n }\n ) =>\n assistantOps.retrieve({\n arbi: this.requireClient(),\n workspaceId: this.requireWorkspace(),\n query,\n docIds,\n ...options,\n }),\n }\n\n // ── Tags ──────────────────────────────────────────────────────────────\n\n readonly tags = {\n list: () => tagsOps.listTags(this.requireClient()),\n\n create: (options: {\n name: string\n workspaceId?: string\n tagType?: TagFormat\n instruction?: string | null\n shared?: boolean\n }) =>\n tagsOps.createTag(this.requireClient(), {\n ...options,\n workspaceId: options.workspaceId ?? this.requireWorkspace(),\n }),\n\n delete: (tagId: string) => tagsOps.deleteTag(this.requireClient(), tagId),\n\n update: (tagId: string, body: UpdateTagRequest) =>\n tagsOps.updateTag(this.requireClient(), tagId, body),\n }\n\n // ── Document Tags ─────────────────────────────────────────────────────\n\n readonly doctags = {\n assign: (tagId: string, docIds: string[], note?: string | null) =>\n doctagsOps.assignDocTags(this.requireClient(), tagId, docIds, note),\n\n remove: (tagId: string, docIds: string[]) =>\n doctagsOps.removeDocTags(this.requireClient(), tagId, docIds),\n\n update: (\n tagId: string,\n docId: string,\n updates: { note?: string | null; citations?: Record<string, CitationData> | null }\n ) => doctagsOps.updateDocTag(this.requireClient(), tagId, docId, updates),\n\n generate: (tagIds: string[], docIds: string[]) =>\n doctagsOps.generateDocTags(this.requireClient(), tagIds, docIds),\n }\n\n // ── Contacts ──────────────────────────────────────────────────────────\n\n readonly contacts = {\n list: () => contactsOps.listContacts(this.requireClient()),\n add: (emails: string[]) => contactsOps.addContacts(this.requireClient(), emails),\n remove: (contactIds: string[]) => contactsOps.removeContacts(this.requireClient(), contactIds),\n groupByStatus: contactsOps.groupContactsByStatus,\n }\n\n // ── Direct Messages ───────────────────────────────────────────────────\n\n readonly dm = {\n list: () => dmOps.listDMs(this.requireClient()),\n send: (messages: Array<{ recipient_ext_id: string; content: string }>) =>\n dmOps.sendDM(this.requireClient(), messages),\n markRead: (messageIds: string[]) => dmOps.markRead(this.requireClient(), messageIds),\n delete: (messageIds: string[]) => dmOps.deleteDMs(this.requireClient(), messageIds),\n }\n\n // ── Settings ──────────────────────────────────────────────────────────\n\n readonly settings = {\n get: () => settingsOps.getSettings(this.requireClient()),\n update: (body: UserSettingsUpdate) => settingsOps.updateSettings(this.requireClient(), body),\n }\n\n // ── Agent Configuration ───────────────────────────────────────────────\n\n readonly agentConfig = {\n list: () => agentconfigOps.listConfigs(this.requireClient()),\n get: (configId: string) => agentconfigOps.getConfig(this.requireClient(), configId),\n save: (body: ConfigUpdateData) => agentconfigOps.saveConfig(this.requireClient(), body),\n delete: (configId: string) => agentconfigOps.deleteConfig(this.requireClient(), configId),\n getSchema: () => agentconfigOps.getSchema(this.requireClient()),\n getModels: () => agentconfigOps.getModels(this.requireClient()),\n }\n\n // ── Health ────────────────────────────────────────────────────────────\n\n readonly health = {\n check: () => healthOps.getHealth(this.requireClient()),\n models: () => healthOps.getHealthModels(this.requireClient()),\n remoteModels: () => healthOps.getRemoteModels(this.requireClient()),\n mcpTools: () => healthOps.getMcpTools(this.requireClient()),\n }\n\n // ── Files (OpenAI-compatible) ────────────────────────────────────────\n\n readonly files = {\n list: (options?: filesOps.ListFilesOptions) =>\n filesOps.listFiles(this.requireClient(), options),\n\n get: (fileId: string) => filesOps.getFile(this.requireClient(), fileId),\n\n delete: (fileId: string) => filesOps.deleteFile(this.requireClient(), fileId),\n\n upload: (fileData: Blob, fileName: string, purpose?: string) =>\n filesOps.uploadFile(this.getAuthHeaders(), fileData, fileName, purpose),\n\n getContent: (fileId: string) => filesOps.getFileContent(this.getAuthHeaders(), fileId),\n }\n\n // ── Internal guards ───────────────────────────────────────────────────\n\n private requireClient(): ArbiClient {\n if (!this.client) {\n throw new ArbiError('Not initialized. Call login() or init() first.')\n }\n return this.client\n }\n\n private requireLogin(): LoginResult {\n if (!this.loginResult) {\n throw new ArbiError('Not logged in. Call login() first.')\n }\n return this.loginResult\n }\n\n private requireWorkspace(): string {\n if (!this.currentWorkspaceId) {\n throw new ArbiError('No workspace selected. Call selectWorkspace() first.')\n }\n return this.currentWorkspaceId\n }\n}\n"]}