@pagelines/sdk 1.0.516 → 1.0.518

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,"file":"sdkClient.js","sources":["../api.ts","../../../node_modules/.pnpm/nanostores@1.3.0/node_modules/nanostores/clean-stores/index.js","../../../node_modules/.pnpm/nanostores@1.3.0/node_modules/nanostores/atom/index.js","../sdkStorage.ts","../clients/AgentClient.ts","../clients/AuthClient.ts","../clients/BillingClient.ts","../clients/ChatClient.ts","../clients/UserClient.ts","../sdkClient.ts"],"sourcesContent":["import type { Hono } from 'hono'\nimport { APP_PORT, APP_PROD_URL, createRefreshingFetch } from '@pagelines/core'\nimport { hc } from 'hono/client'\nimport { cookieUtil } from '@pagelines/core'\n\nexport interface RefreshFetchHooks {\n getDeviceId: () => string | null\n onAccessTokenRefreshed: (token: string) => void\n onTerminalFailure: () => void\n}\n\nexport interface ApiClientSettings {\n isDev: boolean\n apiBase?: string\n [key: string]: unknown\n}\n\n/**\n * Resolve API base URL from settings.\n * Centralizes the isDev/apiBase/production URL logic used across SDK clients.\n */\nexport function resolveApiBase(apiBase?: string, isDev?: boolean): string {\n return apiBase || (isDev ? `http://localhost:${APP_PORT}` : APP_PROD_URL)\n}\n\n/**\n * Create fully typed Hono RPC client for PageLines SDK\n *\n * @template TAppType - The Hono app type from the server (enables full type safety)\n * @param settings - Configuration for API base URL and environment\n * @param responseHandler - Optional handler to process ApiResponse for auto user/token updates\n * @returns Typed Hono client with response interceptor\n *\n * @example\n * ```typescript\n * import type { SDKAppType } from '@/modules/main/server'\n * const client = createApiClient<SDKAppType>({ isDev: true })\n * const response = await client.api.auth['check-email'].$post({ json: { email } })\n * ```\n */\nexport function createApiClient<TAppType extends Hono = any>(\n settings: ApiClientSettings,\n responseHandler?: (response: any) => void,\n refreshHooks?: RefreshFetchHooks,\n): ReturnType<typeof hc<TAppType>> {\n const baseUrl = resolveApiBase(settings.apiBase, settings.isDev)\n\n // Wrap raw fetch with single-flight 401→refresh→retry behavior. Without\n // this, embed users get logged out every 15 min when the access JWT expires\n // (PR-S2 split tokens; SDK only tracked the access half).\n const baseFetch: typeof globalThis.fetch = refreshHooks\n ? createRefreshingFetch({\n fetch: globalThis.fetch.bind(globalThis),\n getDeviceId: refreshHooks.getDeviceId,\n refreshUrl: `${baseUrl}/api/auth/refresh`,\n onAccessTokenRefreshed: refreshHooks.onAccessTokenRefreshed,\n onTerminalFailure: refreshHooks.onTerminalFailure,\n })\n : globalThis.fetch.bind(globalThis)\n\n // Create typed Hono RPC client with response interceptor\n const client = hc<TAppType>(baseUrl, {\n fetch: async (input: RequestInfo | URL, init?: RequestInit) => {\n const token = cookieUtil.getAuthToken()\n\n const response = await baseFetch(input, {\n ...init,\n headers: {\n ...init?.headers,\n 'Content-Type': 'application/json',\n // Only include Authorization header if token exists\n ...(token && { 'Authorization': `Bearer ${token}` }),\n },\n // 'include' so the browser attaches the HttpOnly pl-refresh-token\n // cookie when /refresh is hit. Server allows credentials per origin\n // (no CORS wildcard) so iOS/Android-WebView and same-origin web both\n // work; embeds on third-party sites must be on a CORS-allowed origin.\n credentials: 'include',\n })\n\n // Intercept response to process ApiResponse pattern\n if (responseHandler) {\n // Wrap the original response's json method directly\n const originalJson = response.json.bind(response)\n\n // Override json method on the response object itself\n response.json = async () => {\n const result = await originalJson()\n\n // Process ApiResponse pattern if it has user or token fields.\n // refreshToken is no longer a body field (HttpOnly cookie).\n if (typeof result === 'object' && result !== null) {\n if ('ok' in result && ('user' in result || 'token' in result)) {\n responseHandler(result)\n }\n }\n\n return result\n }\n }\n\n return response\n },\n })\n\n return client\n}\n","import { cleanTasks } from '../task/index.js'\n\nexport const clean = Symbol('clean')\n\nexport const cleanStores = (...stores) => {\n if (process.env.NODE_ENV === 'production') {\n throw new Error(\n 'cleanStores() can be used only during development or tests'\n )\n }\n cleanTasks()\n for (let $store of stores) {\n if ($store) {\n if ($store.mocked) delete $store.mocked\n if ($store[clean]) $store[clean]()\n }\n }\n}\n","import { clean } from '../clean-stores/index.js'\n\nlet listenerQueue = []\nlet lqIndex = 0\nconst QUEUE_ITEMS_PER_LISTENER = 4\n// Use globalThis.nanostoresGlobal to store epoch so all module instances share\n// the same counter. This fixes issues when Nano Store is bundled separately\n// in different parts of an application (e.g., tree-shaking separates core\n// from React), causing each bundle to have its own epoch instance.\nexport const nanostoresGlobal = (globalThis.nanostoresGlobal ||= { epoch: 0 })\n\n/* @__NO_SIDE_EFFECTS__ */\nexport const atom = initialValue => {\n let listeners = []\n let $atom = {\n get() {\n if (!$atom.lc) {\n $atom.listen(() => {})()\n }\n return $atom.value\n },\n init: initialValue,\n lc: 0,\n listen(listener) {\n $atom.lc = listeners.push(listener)\n\n return () => {\n for (\n let i = lqIndex + QUEUE_ITEMS_PER_LISTENER;\n i < listenerQueue.length;\n ) {\n if (listenerQueue[i] === listener) {\n listenerQueue.splice(i, QUEUE_ITEMS_PER_LISTENER)\n } else {\n i += QUEUE_ITEMS_PER_LISTENER\n }\n }\n\n let index = listeners.indexOf(listener)\n if (~index) {\n listeners.splice(index, 1)\n if (!--$atom.lc) $atom.off()\n }\n }\n },\n notify(oldValue, changedKey) {\n nanostoresGlobal.epoch++\n let runListenerQueue = !listenerQueue.length\n for (let listener of listeners) {\n listenerQueue.push(listener, $atom.value, oldValue, changedKey)\n }\n\n if (runListenerQueue) {\n for (\n lqIndex = 0;\n lqIndex < listenerQueue.length;\n lqIndex += QUEUE_ITEMS_PER_LISTENER\n ) {\n listenerQueue[lqIndex](\n listenerQueue[lqIndex + 1],\n listenerQueue[lqIndex + 2],\n listenerQueue[lqIndex + 3]\n )\n }\n listenerQueue.length = 0\n }\n },\n /* It will be called on last listener unsubscribing.\n We will redefine it in onMount and onStop. */\n off() {},\n set(newValue) {\n let oldValue = $atom.value\n if (oldValue !== newValue) {\n $atom.value = newValue\n $atom.notify(oldValue)\n }\n },\n subscribe(listener) {\n let unbind = $atom.listen(listener)\n listener($atom.value)\n return unbind\n },\n value: initialValue\n }\n\n if (process.env.NODE_ENV !== 'production') {\n $atom[clean] = () => {\n listeners = []\n $atom.lc = 0\n $atom.off()\n }\n }\n\n return $atom\n}\n\nexport const readonlyType = store => store\n","import type { Ref } from 'vue'\nimport type { EnrichedUser } from '@pagelines/core'\nimport { atom } from 'nanostores'\nimport { watch } from 'vue'\nimport { cookieUtil, createLogger } from '@pagelines/core'\n\n// Global nanostores shared via globalThis so SDK and app bundles use the same\n// atoms when both run on the same page (Astro multi-island, dashboard preview\n// of a widget, etc.). Each bundle has its own Vue instance — without these\n// globals, signing in to one wouldn't reflect in the other.\n//\n// Refresh credential is NOT in nanostores — it lives in an HttpOnly cookie\n// the browser owns. JS cannot read or write it.\nconst _g = globalThis as Record<string, any>\nconst $globalActiveUser = (_g.__PL_AUTH_USER__ ??= atom<EnrichedUser | undefined>(undefined)) as ReturnType<typeof atom<EnrichedUser | undefined>>\nconst $globalToken = (_g.__PL_AUTH_TOKEN__ ??= atom<string | null>(null)) as ReturnType<typeof atom<string | null>>\nconst $globalDeviceId = (_g.__PL_AUTH_DEVICE_ID__ ??= atom<string | null>(null)) as ReturnType<typeof atom<string | null>>\n\nexport interface AuthRefs {\n activeUser: Ref<EnrichedUser | undefined>\n token: Ref<string | null>\n deviceId: Ref<string | null>\n}\n\n/**\n * SDKStorage - Handles all storage, sync, and persistence for PageLinesSDK\n *\n * Three storage layers, each with a clear job:\n * - Vue refs — runtime source of truth (in-memory)\n * - cookies — survive reload, JS-readable for headers (access token + deviceId)\n * - nanostores — bridge SDK widget bundle ↔ main app bundle on same page\n * - localStorage — UX optimization for cold-load (user object only, never tokens)\n *\n * The refresh credential lives in an HttpOnly cookie the server owns — JS\n * has no access to it, so it never touches any of these layers.\n */\nexport class SDKStorage {\n private logger = createLogger('SDKStorage')\n\n /**\n * Check if localStorage is fully functional (some test environments provide partial mocks)\n */\n private isLocalStorageFunctional(): boolean {\n return typeof window !== 'undefined'\n && typeof localStorage?.getItem === 'function'\n && typeof localStorage?.setItem === 'function'\n && typeof localStorage?.removeItem === 'function'\n }\n\n /**\n * Sync Vue reactive refs with global nanostores for cross-bundle persistence.\n */\n syncWithGlobalStores(refs: AuthRefs): void {\n const { activeUser, token, deviceId } = refs\n\n // 1. Restore from global store on init\n const storedUser = $globalActiveUser.get()\n const storedToken = $globalToken.get()\n const storedDevice = $globalDeviceId.get()\n\n if (storedUser) activeUser.value = storedUser\n if (storedToken) token.value = storedToken\n if (storedDevice) deviceId.value = storedDevice\n\n // 2. Vue refs → global stores (for persistence)\n watch(activeUser, (v) => $globalActiveUser.set(v), { immediate: true })\n watch(token, (v) => $globalToken.set(v), { immediate: true })\n watch(deviceId, (v) => $globalDeviceId.set(v), { immediate: true })\n\n // 3. Global stores → Vue refs (for cross-page updates)\n $globalActiveUser.subscribe((v) => { if (v !== activeUser.value) activeUser.value = v })\n $globalToken.subscribe((v) => { if (v !== token.value) token.value = v })\n $globalDeviceId.subscribe((v) => { if (v !== deviceId.value) deviceId.value = v })\n }\n\n /**\n * Load user and token from browser storage on initialization.\n * deviceId comes from a server-set non-HttpOnly cookie (read-only for JS).\n */\n loadFromStorage(refs: AuthRefs): void {\n if (typeof window === 'undefined')\n return\n\n const savedToken = cookieUtil.getAuthToken()\n if (savedToken) refs.token.value = savedToken\n\n const savedDevice = cookieUtil.getDeviceId()\n if (savedDevice) refs.deviceId.value = savedDevice\n\n // Try to load user from localStorage for immediate availability\n if (this.isLocalStorageFunctional()) {\n try {\n const savedUser = localStorage.getItem('pagelines-user')\n if (savedUser) {\n refs.activeUser.value = JSON.parse(savedUser)\n }\n } catch (error) {\n this.logger.error('Failed to load user from localStorage', { data: error })\n }\n }\n }\n\n /**\n * Save current user and access token to browser storage.\n * deviceId is server-owned (Set-Cookie) — JS doesn't write it.\n */\n saveToStorage(refs: AuthRefs): void {\n if (typeof window === 'undefined')\n return\n\n if (refs.token.value) cookieUtil.setAuthToken(refs.token.value)\n else cookieUtil.removeAuthToken()\n\n // Save user to localStorage for quick loading\n if (this.isLocalStorageFunctional()) {\n try {\n if (refs.activeUser.value) {\n localStorage.setItem('pagelines-user', JSON.stringify(refs.activeUser.value))\n } else {\n localStorage.removeItem('pagelines-user')\n }\n } catch (error) {\n this.logger.error('Failed to save user to localStorage', { data: error })\n }\n }\n }\n\n /**\n * Clear local stored user data and JS-owned tokens. Server-owned cookies\n * (pl-refresh-token, pl-device-id) are cleared by /api/auth/logout via\n * Set-Cookie max-age=0 — JS can't touch them.\n */\n clearStorage(): void {\n if (typeof window === 'undefined')\n return\n\n cookieUtil.removeAuthToken()\n\n if (this.isLocalStorageFunctional()) {\n try {\n localStorage.removeItem('pagelines-user')\n } catch (error) {\n this.logger.error('Failed to clear user from localStorage', { data: error })\n }\n }\n\n // Clear global stores\n $globalActiveUser.set(undefined)\n $globalToken.set(null)\n $globalDeviceId.set(null)\n }\n\n /**\n * Generic localStorage getter\n */\n getItem(key: string): string | null {\n if (!this.isLocalStorageFunctional())\n return null\n\n try {\n return localStorage.getItem(key)\n } catch (error) {\n this.logger.error('Failed to get item from localStorage', { key, error })\n return null\n }\n }\n\n /**\n * Generic localStorage setter\n */\n setItem(key: string, value: string): void {\n if (!this.isLocalStorageFunctional())\n return\n\n try {\n localStorage.setItem(key, value)\n } catch (error) {\n this.logger.error('Failed to set item in localStorage', { key, error })\n }\n }\n}\n","import type { AgentConfig } from '@pagelines/core'\nimport type { SDKContext } from './types'\nimport { resolveApiBase } from '../api'\n\nexport class AgentClient {\n constructor(private ctx: SDKContext) {}\n\n async create(args: { name: string, orgId?: string }): Promise<AgentConfig> {\n const orgId = args.orgId || this.resolveOrgId()\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n\n const response = await fetch(`${apiBase}/api/agents`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(this.ctx.token.value && { Authorization: `Bearer ${this.ctx.token.value}` }),\n },\n body: JSON.stringify({ name: args.name, orgId }),\n })\n\n const data = await response.json() as { ok: boolean, data?: AgentConfig[], error?: string }\n\n if (!data.ok || !data.data?.[0]) {\n const msg = data.error || 'Failed to create agent'\n this.ctx.error.value = msg\n throw new Error(msg)\n }\n\n this.ctx.processApiResponse(data as any)\n return data.data[0]\n }\n\n async getStatus(args: { agentId: string }): Promise<{\n status: string\n ready: boolean\n error?: string\n }> {\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n\n const response = await fetch(`${apiBase}/api/agents/${args.agentId}/status`, {\n headers: {\n ...(this.ctx.token.value && { Authorization: `Bearer ${this.ctx.token.value}` }),\n },\n })\n\n const data = await response.json() as { ok: boolean, data?: { status: string, ready: boolean, error?: string } }\n\n if (!data.ok || !data.data) {\n return { status: 'unknown', ready: false, error: 'Failed to check status' }\n }\n\n return data.data\n }\n\n /**\n * Poll until the agent is ready. `onStatus` receives the server-reported\n * status string verbatim ('starting', 'provisioning', 'running', …) so\n * the caller renders feedback tied to actual provisioner state, not a\n * rotating set of decorative messages decoupled from reality. Per\n * first-principles → \"Always give feedback — no magic\": a spinner that\n * emits unrelated copy is closer to magic than to feedback. Map status\n * names to user copy at the call site.\n */\n async waitUntilReady(args: {\n agentId: string\n onStatus?: (status: string) => void\n timeoutMs?: number\n pollIntervalMs?: number\n }): Promise<void> {\n const { agentId, onStatus, timeoutMs = 300_000, pollIntervalMs = 3_000 } = args\n const start = Date.now()\n let lastStatus: string | undefined\n\n while (Date.now() - start < timeoutMs) {\n const status = await this.getStatus({ agentId })\n\n if (status.ready) {\n onStatus?.('running')\n return\n }\n\n if (status.status === 'error')\n throw new Error(status.error || 'Provisioning failed')\n\n // Only fire onStatus when the kind changes — avoids spamming the\n // caller's UI with redundant updates on every 3s tick.\n if (status.status !== lastStatus) {\n onStatus?.(status.status)\n lastStatus = status.status\n }\n\n await new Promise((r) => setTimeout(r, pollIntervalMs))\n }\n\n throw new Error('Agent provisioning timed out — please try again')\n }\n\n /** Send a typed webhook event to a bot agent. No auth required — the proxy is public. */\n async webhook<T = Record<string, unknown>>(args: {\n agentId: string\n type: string\n data: T\n meta?: { source?: string, timestamp?: string, correlationId?: string, [key: string]: unknown }\n }): Promise<{ ok: boolean, error?: string }> {\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n const url = `${apiBase}/api/bot-api/agents/${args.agentId}/webhook`\n\n const body: Record<string, unknown> = { type: args.type, data: args.data }\n if (args.meta) body.meta = args.meta\n\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n\n if (!res.ok) {\n const text = await res.text().catch(() => 'Unknown error')\n throw new Error(`Webhook delivery failed (${res.status}): ${text.slice(0, 200)}`)\n }\n\n return res.json() as Promise<{ ok: boolean, error?: string }>\n }\n\n private resolveOrgId(): string {\n const user = this.ctx.activeUser.value\n const orgId = user?.orgs?.[0]?.orgId\n if (!orgId) {\n throw new Error('No organization found. Please sign in first.')\n }\n return orgId\n }\n}\n","import type { EnrichedUser } from '@pagelines/core'\nimport type { SDKContext } from './types'\nimport { resolveApiBase } from '../api'\n\n/**\n * Run an async operation with loading/error state management.\n * Sets loading=true and error=null before, loading=false in finally.\n */\nasync function withLoadingState<T>(ctx: SDKContext, fn: () => Promise<T>): Promise<T> {\n ctx.loading.value = true\n ctx.error.value = null\n try {\n return await fn()\n } finally {\n ctx.loading.value = false\n }\n}\n\nexport class AuthClient {\n constructor(private ctx: SDKContext) {}\n\n async sendCode(email: string): Promise<void> {\n return withLoadingState(this.ctx, async () => {\n try {\n const response = await this.ctx.api.auth['check-email'].$post({\n json: { email },\n })\n const data = await response.json()\n if (!data.ok) {\n this.ctx.error.value = data.error\n throw new Error(data.error)\n }\n } catch (err) {\n this.ctx.logger.error('Send code error', { data: err })\n const errorMessage = err instanceof Error ? err.message : 'Failed to send verification code'\n this.ctx.error.value = errorMessage\n throw err\n }\n })\n }\n\n async verifyCode(email: string, code: string): Promise<void> {\n return withLoadingState(this.ctx, async () => {\n try {\n const response = await this.ctx.api.auth['verify-code'].$post({\n json: { email, code },\n })\n const data = await response.json()\n if (!data.ok) {\n this.ctx.error.value = data.error\n throw new Error(data.error)\n }\n } catch (err) {\n this.ctx.logger.error('Verify code error', { data: err })\n const errorMessage = err instanceof Error ? err.message : 'Failed to verify code'\n this.ctx.error.value = errorMessage\n throw err\n }\n })\n }\n\n async logout(): Promise<void> {\n return withLoadingState(this.ctx, async () => {\n try {\n await this.ctx.api.auth.logout.$post()\n } catch (err) {\n this.ctx.logger.error('Logout error (user still logged out locally)', { data: err })\n }\n // Always clear local state regardless of API success\n this.ctx.activeUser.value = undefined\n this.ctx.token.value = null\n this.ctx.storage.clearStorage()\n })\n }\n\n async getCurrentUser(): Promise<EnrichedUser | undefined> {\n if (!this.ctx.token.value) {\n return undefined\n }\n\n return withLoadingState(this.ctx, async () => {\n try {\n // /api/users/me is on the OpenAPI sub-app — not in Hono RPC's type\n // tree. Use plain fetch with the canonical path. Envelope is\n // `{ ok: true, data: enrichedUser }` (no top-level `user` field).\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n const response = await fetch(`${apiBase}/api/users/me`, {\n method: 'GET',\n headers: { Authorization: `Bearer ${this.ctx.token.value}` },\n })\n const data = await response.json() as { ok: true, data: EnrichedUser } | { ok: false, error: string }\n\n if (!data.ok) {\n this.ctx.error.value = data.error\n if (data.error.includes('Authentication')) {\n this.ctx.activeUser.value = undefined\n this.ctx.token.value = null\n this.ctx.storage.clearStorage()\n }\n return undefined\n }\n\n // Set activeUser directly — `/users/me` envelope is\n // `{ ok: true, data: enrichedUser }`. processApiResponse is shaped\n // for sign-in responses (token + user + deviceId at the top level);\n // synthesizing a fake legacy envelope to feed it is shadow-state.\n // The token check guards against stale in-flight responses landing\n // after a logout cleared the session.\n if (this.ctx.token.value)\n this.ctx.activeUser.value = data.data\n return data.data\n } catch (err) {\n this.ctx.logger.error('Get current user error', { data: err })\n this.ctx.error.value = err instanceof Error ? err.message : 'Failed to get user info'\n return undefined\n }\n })\n }\n\n async requestAuthCode(args: { email: string }): Promise<boolean> {\n return withLoadingState(this.ctx, async () => {\n try {\n const response = await this.ctx.api.auth['check-email'].$post({\n json: { email: args.email },\n })\n const data = await response.json()\n if (!data.ok) {\n this.ctx.error.value = data.error\n this.ctx.logger.error('Failed to request auth code', { email: args.email, error: data.error })\n return false\n }\n this.ctx.logger.info('Auth code requested successfully', { email: args.email })\n return true\n } catch (err) {\n this.ctx.logger.error('Request auth code error', { email: args.email, error: err })\n this.ctx.error.value = err instanceof Error ? err.message : 'Failed to request auth code'\n return false\n }\n })\n }\n\n async loginWithCode(args: {\n email: string\n code: string\n orgId?: string\n autoCreateContact?: boolean\n }): Promise<boolean> {\n return withLoadingState(this.ctx, async () => {\n try {\n const response = await this.ctx.api.auth['verify-code'].$post({\n json: { email: args.email, code: args.code },\n })\n const data = await response.json()\n if (!data.ok) {\n this.ctx.error.value = data.error\n this.ctx.logger.error('Login failed', { email: args.email, error: data.error })\n return false\n }\n this.ctx.logger.info('Login successful', { email: args.email })\n return true\n } catch (err) {\n this.ctx.logger.error('Login with code error', { email: args.email, error: err })\n this.ctx.error.value = err instanceof Error ? err.message : 'Login failed'\n return false\n }\n })\n }\n\n loginWithGoogle(args?: { onSuccess?: (user: EnrichedUser) => void, onError?: (error: string) => void }): void {\n if (typeof window === 'undefined') {\n this.ctx.logger.error('loginWithGoogle: Only available in browser')\n return\n }\n\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n const origin = window.location.origin\n const popupUrl = `${apiBase}/auth/google-popup?origin=${encodeURIComponent(origin)}`\n\n // Open centered popup\n const width = 500\n const height = 600\n const left = window.screenX + (window.outerWidth - width) / 2\n const top = window.screenY + (window.outerHeight - height) / 2\n const popup = window.open(\n popupUrl,\n 'google-auth',\n `width=${width},height=${height},left=${left},top=${top},popup=yes`,\n )\n\n if (!popup) {\n const msg = 'Popup was blocked. Please allow popups for this site.'\n this.ctx.error.value = msg\n args?.onError?.(msg)\n return\n }\n\n // Listen for postMessage from popup\n const handler = (event: MessageEvent) => {\n // Validate origin -- must be our API base\n const expectedOrigin = new URL(apiBase).origin\n if (event.origin !== expectedOrigin) return\n\n if (event.data?.type === 'auth-success') {\n window.removeEventListener('message', handler)\n const { token, user } = event.data\n\n // Process the auth response the same way as other login methods\n this.ctx.processApiResponse({ ok: true, data: {}, token, user })\n\n this.ctx.logger.info('Google login successful')\n args?.onSuccess?.(user)\n } else if (event.data?.type === 'auth-error') {\n window.removeEventListener('message', handler)\n const errorMsg = event.data.error || 'Google authentication failed'\n this.ctx.error.value = errorMsg\n this.ctx.logger.error('Google login failed', { error: errorMsg })\n args?.onError?.(errorMsg)\n }\n }\n\n window.addEventListener('message', handler)\n\n // Clean up listener if popup is closed without completing auth\n const checkClosed = setInterval(() => {\n if (popup.closed) {\n clearInterval(checkClosed)\n window.removeEventListener('message', handler)\n }\n }, 500)\n }\n}\n","import type { SDKContext } from './types'\nimport { resolveApiBase } from '../api'\n\nexport interface BillingStatus {\n plan?: string\n status: string\n hasActiveBilling: boolean\n maxAgents: number\n trialEnd?: string\n trialDaysRemaining?: number\n}\n\nexport class BillingClient {\n constructor(private ctx: SDKContext) {}\n\n async startTrial(args?: { returnUrl?: string, planKey?: string }): Promise<void> {\n const orgId = this.resolveOrgId()\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n\n const response = await fetch(`${apiBase}/api/billing/checkout/create`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(this.ctx.token.value && { Authorization: `Bearer ${this.ctx.token.value}` }),\n },\n body: JSON.stringify({\n orgId,\n ...(args?.returnUrl && { returnUrl: args.returnUrl }),\n ...(args?.planKey && { planKey: args.planKey }),\n }),\n })\n\n const data = await response.json() as { ok: boolean, data?: { url: string }, error?: string }\n\n if (!data.ok || !data.data?.url) {\n const msg = data.error || 'Failed to create checkout session'\n this.ctx.error.value = msg\n throw new Error(msg)\n }\n\n window.location.href = data.data.url\n }\n\n async confirmCheckout(_args?: { sessionId?: string }): Promise<BillingStatus> {\n return this.getStatus()\n }\n\n async getStatus(): Promise<BillingStatus> {\n const orgId = this.resolveOrgId()\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n\n const response = await fetch(`${apiBase}/api/billing/details/${orgId}`, {\n headers: {\n ...(this.ctx.token.value && { Authorization: `Bearer ${this.ctx.token.value}` }),\n },\n })\n\n const data = await response.json() as {\n ok: boolean\n data?: { plan: string, status: string, maxAgents: number, trialEnd?: string, trialDaysRemaining?: number }\n error?: string\n }\n\n if (!data.ok || !data.data) {\n return {\n plan: undefined,\n status: 'none',\n hasActiveBilling: false,\n maxAgents: 0,\n }\n }\n\n const ACTIVE_STATUSES = ['active', 'trialing']\n\n return {\n plan: data.data.plan,\n status: data.data.status,\n hasActiveBilling: ACTIVE_STATUSES.includes(data.data.status),\n maxAgents: data.data.maxAgents,\n ...(data.data.trialEnd && { trialEnd: data.data.trialEnd }),\n ...(data.data.trialDaysRemaining !== undefined && { trialDaysRemaining: data.data.trialDaysRemaining }),\n }\n }\n\n private resolveOrgId(): string {\n const user = this.ctx.activeUser.value\n const orgId = user?.orgs?.[0]?.orgId\n if (!orgId) {\n throw new Error('No organization found. Please sign in first.')\n }\n return orgId\n }\n}\n","import type { ApiResponse, ChatAttachmentInput } from '@pagelines/core'\nimport type { ChatAttachment, ChatMessage } from '../agent/schema'\nimport type { SDKContext } from './types'\nimport { shortId } from '@pagelines/core'\nimport { resolveApiBase } from '../api'\n\n/**\n * Stripped down view of the substrate's `Message` row. The SDK can't import\n * Drizzle's `$inferSelect` (server-only), so we restate the wire shape here.\n * Mirrors `src/modules/db/tables/schema/messages.ts → Message` — keep in sync.\n */\ninterface SubstrateMessage {\n messageId: string\n conversationId: string\n participantId: string\n role: 'user' | 'assistant' | 'system'\n content: string\n sequence: string\n clientNonce: string | null\n metadata: {\n attachments?: ChatAttachment[]\n issue?: { code: string, bucket: 'account' | 'error', actionLabel: string, actionUrl: string, help?: string }\n [key: string]: any\n } | null\n status: string | null\n createdAt: string\n updatedAt: string\n}\n\n/**\n * Wire format of the substrate SSE stream — frames look like:\n * event: <name>\\n\n * data: <json>\\n\n * \\n\n * Mirrors `src/modules/messaging/types.ts → ChatEvent`.\n */\ntype ChatEvent\n = | { event: 'message', data: { message: SubstrateMessage } }\n | { event: 'message_delta', data: { delta: string, turnId: string, messageId?: string, role?: 'assistant' | 'system' } }\n | { event: 'working_state', data: { description: string } }\n | { event: 'working_end', data: Record<string, never> }\n | { event: 'error', data: {\n code: string\n message: string\n bucket?: 'account' | 'error'\n actionLabel?: string\n actionUrl?: string\n help?: string\n } }\n | { event: 'stream_end', data: Record<string, never> }\n\nconst KNOWN_EVENTS = new Set(['message', 'message_delta', 'working_state', 'working_end', 'error', 'stream_end'])\n\nfunction parseChatEvent(frame: string): ChatEvent | null {\n const lines = frame.split('\\n').filter((l) => l.length > 0)\n let name: string | undefined\n let payload: string | undefined\n for (const line of lines) {\n if (line.startsWith('event:'))\n name = line.slice(6).trim()\n else if (line.startsWith('data:'))\n payload = line.slice(5).trim()\n }\n if (!name || payload === undefined || !KNOWN_EVENTS.has(name))\n return null\n try {\n return { event: name, data: JSON.parse(payload) } as ChatEvent\n } catch {\n return null\n }\n}\n\nfunction toChatMessage(message: SubstrateMessage): ChatMessage | undefined {\n if (message.role !== 'assistant' && message.role !== 'system')\n return undefined\n return {\n id: message.messageId,\n text: message.content,\n sender: message.role === 'system' ? 'system' : 'agent',\n timestamp: message.createdAt,\n ...(message.metadata?.attachments?.length\n ? { attachments: message.metadata.attachments }\n : {}),\n ...(message.metadata?.issue ? { issue: message.metadata.issue } : {}),\n }\n}\n\nexport class ChatClient {\n constructor(private ctx: SDKContext) {}\n\n /**\n * Public/visitor chat — anonymous chat against an agent's public handle,\n * routed through the messaging substrate. Same SSE wire format as\n * `chatStreamAuthenticated` — the only difference is the route (no auth,\n * handle-based lookup, anonymousId instead of userId).\n *\n * The visitor identity is `anonymousId` — caller is responsible for\n * generating + persisting it (typically `sdk.user.generateAnonId()`\n * which stores a stable ID in localStorage).\n */\n async chatStreamPublic(args: {\n handle: string\n message: string\n anonymousId: string\n attachments?: ChatAttachmentInput[]\n context?: string\n onDelta: (text: string, role?: 'assistant' | 'system') => void\n onMessage?: (message: ChatMessage) => void\n onDone: (conversationId: string) => void\n onError: (error: string) => void\n onStatus?: (status: string) => void\n }): Promise<void> {\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n const url = `${apiBase}/api/agents/public/${encodeURIComponent(args.handle)}/chat/v2/stream`\n\n let conversationId = ''\n let errorSeen = false\n let assistantSeen = false\n let reader: ReadableStreamDefaultReader<Uint8Array> | undefined\n\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n message: args.message,\n anonymousId: args.anonymousId,\n ...(args.attachments?.length ? { attachments: args.attachments } : {}),\n ...(args.context ? { context: args.context } : {}),\n }),\n })\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({ error: 'Request failed' })) as { error?: string }\n args.onError(errorBody.error || `HTTP ${res.status}`)\n return\n }\n\n // Server emits the resolved conversationId in a response header so the\n // SDK can persist it across page loads (e.g. for \"resume conversation\"\n // flows). The substrate would also have a `message` event with the\n // conversationId on the persisted user msg, but the header arrives\n // first and is cheaper to parse.\n conversationId = res.headers.get('X-Conversation-Id') || ''\n reader = res.body?.getReader()\n if (!reader) {\n args.onError('No response stream')\n return\n }\n\n const decoder = new TextDecoder()\n let buffer = ''\n outer: while (true) {\n const { done, value } = await reader.read()\n if (done)\n break\n buffer += decoder.decode(value, { stream: true })\n let sep = buffer.indexOf('\\n\\n')\n while (sep !== -1) {\n const frame = buffer.slice(0, sep)\n buffer = buffer.slice(sep + 2)\n const event = parseChatEvent(frame)\n if (event) {\n if (event.event === 'working_state') {\n args.onStatus?.(event.data.description)\n } else if (event.event === 'message_delta') {\n args.onDelta(event.data.delta, event.data.role)\n } else if (event.event === 'error') {\n errorSeen = true\n args.onError(event.data.message)\n break outer\n } else if (event.event === 'message' && (event.data.message.role === 'assistant' || event.data.message.role === 'system')) {\n assistantSeen = true\n const message = toChatMessage(event.data.message)\n if (message)\n args.onMessage?.(message)\n // Wait for stream_end — the v2 route emits it after the\n // assistant message lands so deltas-then-message ordering is\n // preserved without breaking out early.\n } else if (event.event === 'stream_end') {\n break outer\n }\n }\n sep = buffer.indexOf('\\n\\n')\n }\n }\n\n if (!errorSeen && assistantSeen)\n args.onDone(conversationId)\n else if (!errorSeen)\n args.onError('Stream ended before reply arrived')\n } catch (err) {\n args.onError(err instanceof Error ? err.message : 'Stream failed')\n } finally {\n try {\n await reader?.cancel()\n } catch {\n // Stream already closed.\n }\n }\n }\n\n\n /**\n * Authenticated chat — substrate-backed (POST /api/messages + SSE on\n * /api/chat/:agentId/stream). Same callback contract as the legacy\n * `chatStream` so callers don't need to know which transport runs underneath.\n * Mirrors `src/modules/agent/client.ts → sendChatMessageStream`.\n */\n async chatStreamAuthenticated(args: {\n agentId: string\n message: string\n attachments?: ChatAttachmentInput[]\n /** Reserved — substrate resolves conversation server-side from (userId, agentId). */\n conversationId?: string\n /** Reserved — substrate replays history from the canonical messages table. */\n history?: Array<{ role: 'user' | 'assistant', content: string }>\n onDelta: (text: string, role?: 'assistant' | 'system') => void\n onMessage?: (message: ChatMessage) => void\n onDone: (conversationId: string) => void\n onError: (error: string) => void\n onStatus?: (status: string) => void\n }): Promise<void> {\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n const authHeaders: Record<string, string> = this.ctx.token.value\n ? { Authorization: `Bearer ${this.ctx.token.value}` }\n : {}\n\n // 1. Persist + publish the user turn.\n const clientNonce = `nonce_${shortId(16)}`\n let userMessage: SubstrateMessage\n try {\n const res = await fetch(`${apiBase}/api/messages`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...authHeaders },\n body: JSON.stringify({ agentId: args.agentId, content: args.message, clientNonce }),\n })\n const result = await res.json() as ApiResponse<SubstrateMessage>\n if (!result.ok) {\n args.onError(result.error || `Send failed: HTTP ${res.status}`)\n return\n }\n userMessage = result.data\n } catch (err) {\n args.onError(err instanceof Error ? err.message : 'Send failed')\n return\n }\n\n // 2. Tail events generated AFTER the user message (`since` is exclusive).\n let errorSeen = false\n let assistantSeen = false\n let reader: ReadableStreamDefaultReader<Uint8Array> | undefined\n try {\n const streamRes = await fetch(`${apiBase}/api/chat/${encodeURIComponent(args.agentId)}/stream?since=${encodeURIComponent(userMessage.sequence)}`, {\n headers: authHeaders,\n })\n if (!streamRes.ok) {\n args.onError(`Stream failed: HTTP ${streamRes.status}`)\n return\n }\n reader = streamRes.body?.getReader()\n if (!reader) {\n args.onError('No response stream')\n return\n }\n\n const decoder = new TextDecoder()\n let buffer = ''\n outer: while (true) {\n const { done, value } = await reader.read()\n if (done)\n break\n buffer += decoder.decode(value, { stream: true })\n let sep = buffer.indexOf('\\n\\n')\n while (sep !== -1) {\n const frame = buffer.slice(0, sep)\n buffer = buffer.slice(sep + 2)\n const event = parseChatEvent(frame)\n if (event) {\n if (event.event === 'working_state') {\n args.onStatus?.(event.data.description)\n } else if (event.event === 'message_delta') {\n args.onDelta(event.data.delta, event.data.role)\n } else if (event.event === 'error') {\n errorSeen = true\n args.onError(event.data.message)\n break outer\n } else if (event.event === 'message' && (event.data.message.role === 'assistant' || event.data.message.role === 'system')) {\n assistantSeen = true\n const message = toChatMessage(event.data.message)\n if (message)\n args.onMessage?.(message)\n break outer\n } else if (event.event === 'stream_end') {\n break outer\n }\n }\n sep = buffer.indexOf('\\n\\n')\n }\n }\n\n if (!errorSeen && assistantSeen)\n args.onDone(userMessage.conversationId)\n else if (!errorSeen)\n args.onError('Stream ended before reply arrived')\n } catch (err) {\n args.onError(err instanceof Error ? err.message : 'Stream failed')\n } finally {\n try {\n await reader?.cancel()\n } catch {\n // Stream already closed.\n }\n }\n }\n\n}\n","import type { AgentConfig } from '@pagelines/core'\nimport { objectId } from '@pagelines/core'\nimport type { SDKContext } from './types'\n\nexport class UserClient {\n constructor(private ctx: SDKContext) {}\n\n async getPublicAgent(args: { handle: string }): Promise<AgentConfig | undefined> {\n this.ctx.loading.value = true\n this.ctx.error.value = null\n\n try {\n const response = await this.ctx.api.agents.public[':handle'].$get({\n param: { handle: args.handle },\n })\n\n const data = await response.json()\n\n if (!data.ok) {\n this.ctx.error.value = data.error\n this.ctx.logger.error('Failed to fetch public agent', { handle: args.handle, error: data.error })\n return undefined\n }\n\n return data.data\n } catch (err) {\n this.ctx.logger.error('Get public agent error', { handle: args.handle, error: err })\n this.ctx.error.value = err instanceof Error ? err.message : 'Failed to fetch agent'\n return undefined\n } finally {\n this.ctx.loading.value = false\n }\n }\n\n async getAgentByEmail(args: { email: string }): Promise<AgentConfig | undefined> {\n this.ctx.loading.value = true\n this.ctx.error.value = null\n\n try {\n const response = await this.ctx.api.agents['by-email'][':email'].$get({\n param: { email: args.email },\n })\n\n const data = await response.json()\n\n if (!data.ok) {\n this.ctx.error.value = data.error\n this.ctx.logger.error('Failed to fetch agent by email', { email: args.email, error: data.error })\n return undefined\n }\n\n return data.data\n } catch (err) {\n this.ctx.logger.error('Get agent by email error', { email: args.email, error: err })\n this.ctx.error.value = err instanceof Error ? err.message : 'Failed to fetch agent'\n return undefined\n } finally {\n this.ctx.loading.value = false\n }\n }\n\n generateAnonId(): string {\n const storageKey = 'pagelinesAnonId'\n let anonId = this.ctx.storage.getItem(storageKey)\n\n if (!anonId) {\n anonId = objectId({ prefix: 'anon' })\n this.ctx.storage.setItem(storageKey, anonId)\n }\n\n return anonId\n }\n\n track(args: {\n event: 'view_profile' | 'profile_interaction'\n agentId: string\n properties?: Record<string, any>\n }): void {\n try {\n // Track event via postMessage to parent window if embedded\n if (typeof window !== 'undefined' && window.parent !== window) {\n window.parent.postMessage({\n type: 'pagelines_track',\n event: args.event,\n agentId: args.agentId,\n properties: args.properties || {},\n }, '*')\n }\n\n this.ctx.logger.info('SDK event tracked', { event: args.event, agentId: args.agentId })\n } catch (err) {\n this.ctx.logger.error('Track event error', { error: err, args })\n }\n }\n}\n","import type { hc } from 'hono/client'\n// Use stub type for production builds (aliased in vite.config.sdk.ts)\n// Dev uses real SDKAppType from server via alias\nimport type { SDKAppType } from '@/modules/main/server'\nimport type { ApiResponse, EnrichedUser } from '@pagelines/core'\nimport { objectId, SettingsObject } from '@pagelines/core'\nimport { computed, ref } from 'vue'\nimport { createApiClient } from './api'\nimport { SDKStorage } from './sdkStorage'\nimport { AgentClient } from './clients/AgentClient'\nimport { AuthClient } from './clients/AuthClient'\nimport { BillingClient } from './clients/BillingClient'\nimport { ChatClient } from './clients/ChatClient'\nimport { UserClient } from './clients/UserClient'\nimport type { SDKContext } from './clients/types'\n\nexport interface PageLinesSDKSettings {\n apiBase?: string\n isDev?: boolean\n [key: string]: unknown\n}\n\n/**\n * Browser-only singleton manager\n * Browser: Uses globalThis for cross-bundle singleton (www + widget)\n * Node.js SSR: No singleton - each request gets new instance (prevents request bleeding)\n */\nclass SDKGlobal {\n private key = '__PAGELINES_SDK__'\n\n get(): PageLinesSDK | undefined {\n if (typeof window === 'undefined')\n return undefined\n return (globalThis as any)[this.key]\n }\n\n set(instance: PageLinesSDK): void {\n if (typeof window !== 'undefined')\n (globalThis as any)[this.key] = instance\n }\n\n delete(): void {\n if (typeof window !== 'undefined')\n delete (globalThis as any)[this.key]\n }\n}\n\n// Module-scoped singleton manager\nconst sdkGlobal = new SDKGlobal()\n\nexport class PageLinesSDK extends SettingsObject<PageLinesSDKSettings> {\n /**\n * Get singleton instance in browser (creates if doesn't exist)\n * Node.js: Always creates new instance (no singleton)\n * Recommended: Use this instead of constructor for shared state\n */\n static getInstance(settings: PageLinesSDKSettings = {}): PageLinesSDK {\n // Browser: return singleton or create\n // Node: always create new (no singleton)\n return sdkGlobal.get() || new PageLinesSDK(settings)\n }\n\n // Vue reactive state\n activeUser = ref<EnrichedUser | undefined>()\n token = ref<string | null>(null)\n // Refresh credential lives in HttpOnly pl-refresh-token cookie — JS never\n // holds it, so no reactive ref. /api/auth/refresh reads the cookie via the\n // browser's automatic credentials: 'include' attach.\n deviceId = ref<string | null>(null)\n loading = ref(false)\n error = ref<string | null>(null)\n apiBase = this.settings.apiBase || undefined\n\n // Storage handler for persistence\n private storage = new SDKStorage()\n\n // Auto-managed session ID for usage tracking\n private sessionId = objectId({ prefix: 'ses' })\n\n get isDev() {\n return this.settings.isDev ?? (\n typeof window !== 'undefined'\n ? window.location.hostname === 'localhost' || window.location.hostname.includes('127.0.0.1')\n : false\n )\n }\n\n // Typed Hono RPC client - uses SDKAppType (auth/self/usage routes only)\n // Initialized in constructor (definite assignment via singleton pattern)\n private apiClient!: ReturnType<typeof hc<SDKAppType>>\n\n // The stub `Hono<any, any, any>` makes `hc<SDKAppType>` resolve to `any`\n // for prod-build speed; in dev the alias points at the real SDKAppType\n // and we get full route typing. Either way `.api` is a valid access.\n private get api() {\n return this.apiClient.api\n }\n\n // Computed properties derived from activeUser (matches UserClient pattern)\n currentAgent = computed(() => {\n const user = this.activeUser.value\n if (!user?.agents)\n return undefined\n\n const agentId = user.primaryAgentId || user.agents[0]?.agentId\n if (!agentId)\n return undefined\n\n return user.agents.find((a) => a.agentId === agentId)\n })\n\n currentOrg = computed(() => {\n const agent = this.currentAgent.value\n if (!agent?.orgId)\n return undefined\n\n const user = this.activeUser.value\n if (!user?.orgs)\n return undefined\n\n return user.orgs.find((org) => org.orgId === agent.orgId)\n })\n\n // Initialization state\n initialized?: Promise<EnrichedUser | undefined>\n resolveUser?: (value: EnrichedUser | undefined) => void\n\n // Sub-clients (new preferred API surface)\n readonly agent!: AgentClient\n readonly auth!: AuthClient\n readonly billing!: BillingClient\n readonly chat!: ChatClient\n readonly user!: UserClient\n\n constructor(settings: PageLinesSDKSettings = {}) {\n // Browser: return existing singleton\n // Node: always create new\n const existing = sdkGlobal.get()\n if (existing) {\n console.debug('[PageLinesSDK] Returning existing singleton instance')\n return existing\n }\n\n super('PageLinesSDK', settings)\n\n // Browser: set singleton reference (no-op in Node)\n sdkGlobal.set(this)\n\n // Create typed Hono RPC client with response handler + auto-refresh on 401.\n // Refresh credential is in the HttpOnly cookie; the browser attaches it\n // automatically when /refresh is hit with credentials: 'include'.\n this.apiClient = createApiClient<SDKAppType>(\n { isDev: this.isDev, apiBase: this.apiBase },\n this.processApiResponse.bind(this),\n {\n getDeviceId: () => this.deviceId.value,\n onAccessTokenRefreshed: (token) => {\n this.token.value = token\n this.persistAuth()\n },\n onTerminalFailure: () => {\n this.clearSession()\n },\n },\n )\n\n // Build shared context for sub-clients\n const ctx: SDKContext = {\n api: this.api,\n apiBase: this.apiBase,\n isDev: this.isDev,\n activeUser: this.activeUser,\n token: this.token,\n loading: this.loading,\n error: this.error,\n currentAgent: this.currentAgent,\n storage: this.storage,\n sessionId: this.sessionId,\n logger: this.logger,\n processApiResponse: this.processApiResponse.bind(this),\n }\n\n // Initialize sub-clients\n this.agent = new AgentClient(ctx)\n this.auth = new AuthClient(ctx)\n this.billing = new BillingClient(ctx)\n this.chat = new ChatClient(ctx)\n this.user = new UserClient(ctx)\n\n this.logger.info('PageLinesSDK initialized')\n\n // Initialize from storage using handler\n this.storage.loadFromStorage(this.authRefs())\n\n // Sync with global stores for persistence across navigation\n this.storage.syncWithGlobalStores(this.authRefs())\n\n // Set up initialization promise (same pattern as UserClient)\n this.initialized = new Promise((resolve) => {\n this.resolveUser = resolve\n })\n\n // Auto-fetch user if token exists (mirrors UserClient pattern)\n if (this.token.value && !this.activeUser.value) {\n this.auth.getCurrentUser().then((user) => {\n if (this.resolveUser) {\n this.resolveUser(user)\n this.resolveUser = undefined\n }\n }).catch((err: unknown) => {\n this.logger.error('Auto user fetch failed', { data: err })\n if (this.resolveUser) {\n this.resolveUser(undefined)\n this.resolveUser = undefined\n }\n })\n } else if (this.activeUser.value) {\n // Resolve immediately if we already have a user from storage\n this.resolveUser?.(this.activeUser.value)\n } else {\n // No token, resolve with undefined\n this.resolveUser?.(undefined)\n }\n }\n\n // Process ApiResponse for automatic user/token updates - public for dependency injection\n processApiResponse(response: ApiResponse<any>): void {\n if (!response.ok) return\n\n let dirty = false\n\n if (response.user) {\n this.activeUser.value = response.user\n this.logger.info('User updated from API response', { data: response.user })\n dirty = true\n }\n\n if (response.token) {\n this.token.value = response.token\n this.logger.info('Token updated from API response')\n dirty = true\n }\n\n // deviceId rides inside data.* on /verify-code and Apple/Google routes.\n // Server ALSO sets it as a non-HttpOnly cookie — we mirror to the ref\n // so the rest of the SDK can observe \"we're paired\" reactively.\n const incomingDeviceId = (response.data as { deviceId?: string } | undefined)?.deviceId\n if (incomingDeviceId) {\n this.deviceId.value = incomingDeviceId\n dirty = true\n }\n\n if (dirty) this.persistAuth()\n\n // Resolve initialization promise\n if (this.resolveUser) {\n this.resolveUser(response.user)\n this.resolveUser = undefined\n }\n }\n\n private authRefs() {\n return {\n activeUser: this.activeUser,\n token: this.token,\n deviceId: this.deviceId,\n }\n }\n\n private persistAuth() {\n this.storage.saveToStorage(this.authRefs())\n }\n\n // Clear all user data and tokens\n clearSession(): void {\n this.logger.info('Clearing session')\n this.activeUser.value = undefined\n this.token.value = null\n this.deviceId.value = null\n this.error.value = null\n this.storage.clearStorage()\n }\n\n // Full reset - clears session + state + destroys singleton\n clear(): void {\n this.logger.info('Clearing SDK completely')\n\n // 1. Clear session data\n this.clearSession()\n\n // 2. Reset other state\n this.loading.value = false\n this.sessionId = objectId({ prefix: 'ses' })\n\n // 3. Destroy singleton (no-op in Node)\n sdkGlobal.delete()\n }\n}\n"],"names":["resolveApiBase","apiBase","isDev","APP_PORT","APP_PROD_URL","__name","createApiClient","settings","responseHandler","refreshHooks","baseUrl","baseFetch","createRefreshingFetch","hc","input","init","token","cookieUtil","response","originalJson","result","clean","listenerQueue","lqIndex","QUEUE_ITEMS_PER_LISTENER","nanostoresGlobal","atom","initialValue","listeners","$atom","listener","i","index","oldValue","changedKey","runListenerQueue","newValue","unbind","_g","$globalActiveUser","$globalToken","$globalDeviceId","_SDKStorage","__publicField","createLogger","refs","activeUser","deviceId","storedUser","storedToken","storedDevice","watch","v","savedToken","savedDevice","savedUser","error","key","value","SDKStorage","_AgentClient","ctx","args","orgId","data","msg","agentId","onStatus","timeoutMs","pollIntervalMs","start","lastStatus","status","r","url","body","res","text","AgentClient","withLoadingState","fn","_AuthClient","email","err","errorMessage","code","origin","popupUrl","width","height","left","top","popup","handler","event","expectedOrigin","user","errorMsg","checkClosed","AuthClient","_BillingClient","_args","ACTIVE_STATUSES","BillingClient","KNOWN_EVENTS","parseChatEvent","frame","lines","l","name","payload","line","toChatMessage","message","_ChatClient","conversationId","errorSeen","assistantSeen","reader","errorBody","decoder","buffer","outer","done","sep","authHeaders","clientNonce","shortId","userMessage","streamRes","ChatClient","_UserClient","storageKey","anonId","objectId","UserClient","_SDKGlobal","instance","SDKGlobal","sdkGlobal","_PageLinesSDK","SettingsObject","existing","ref","computed","a","agent","org","resolve","dirty","incomingDeviceId","PageLinesSDK"],"mappings":"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","x_google_ignoreList":[1,2]}
1
+ {"version":3,"file":"sdkClient.js","sources":["../api.ts","../../../node_modules/.pnpm/nanostores@1.3.0/node_modules/nanostores/clean-stores/index.js","../../../node_modules/.pnpm/nanostores@1.3.0/node_modules/nanostores/atom/index.js","../sdkStorage.ts","../clients/AgentClient.ts","../clients/AuthClient.ts","../clients/BillingClient.ts","../clients/ChatClient.ts","../clients/UserClient.ts","../sdkClient.ts"],"sourcesContent":["import type { ApiResponse } from '@pagelines/core'\nimport { APP_PORT, APP_PROD_URL, cookieUtil, createRefreshingFetch } from '@pagelines/core'\n\nexport interface RefreshFetchHooks {\n getDeviceId: () => string | null\n onAccessTokenRefreshed: (token: string) => void\n onTerminalFailure: () => void\n}\n\nexport interface ApiClientSettings {\n isDev: boolean\n apiBase?: string\n [key: string]: unknown\n}\n\n/**\n * Resolve API base URL from settings.\n * Centralizes the isDev/apiBase/production URL logic used across SDK clients.\n */\nexport function resolveApiBase(apiBase?: string, isDev?: boolean): string {\n return apiBase || (isDev ? `http://localhost:${APP_PORT}` : APP_PROD_URL)\n}\n\nexport function createApiFetch(\n settings: ApiClientSettings,\n responseHandler?: (response: ApiResponse) => void,\n refreshHooks?: RefreshFetchHooks,\n): typeof globalThis.fetch {\n const baseUrl = resolveApiBase(settings.apiBase, settings.isDev)\n\n const baseFetch: typeof globalThis.fetch = refreshHooks\n ? createRefreshingFetch({\n fetch: globalThis.fetch.bind(globalThis),\n getDeviceId: refreshHooks.getDeviceId,\n refreshUrl: `${baseUrl}/api/auth/refresh`,\n onAccessTokenRefreshed: refreshHooks.onAccessTokenRefreshed,\n onTerminalFailure: refreshHooks.onTerminalFailure,\n })\n : globalThis.fetch.bind(globalThis)\n\n return async (input: RequestInfo | URL, init?: RequestInit) => {\n const token = cookieUtil.getAuthToken()\n const headers = new Headers(init?.headers)\n if (!headers.has('Content-Type'))\n headers.set('Content-Type', 'application/json')\n if (token && !headers.has('Authorization'))\n headers.set('Authorization', `Bearer ${token}`)\n\n const requestInput = typeof input === 'string' && input.startsWith('/')\n ? `${baseUrl}${input}`\n : input\n\n const response = await baseFetch(requestInput, {\n ...init,\n headers,\n credentials: 'include',\n })\n\n if (responseHandler) {\n const originalJson = response.json.bind(response)\n response.json = async () => {\n const result = await originalJson()\n if (typeof result === 'object' && result !== null) {\n if ('ok' in result && ('user' in result || 'token' in result))\n responseHandler(result as ApiResponse)\n }\n return result\n }\n }\n\n return response\n }\n}\n","import { cleanTasks } from '../task/index.js'\n\nexport const clean = Symbol('clean')\n\nexport const cleanStores = (...stores) => {\n if (process.env.NODE_ENV === 'production') {\n throw new Error(\n 'cleanStores() can be used only during development or tests'\n )\n }\n cleanTasks()\n for (let $store of stores) {\n if ($store) {\n if ($store.mocked) delete $store.mocked\n if ($store[clean]) $store[clean]()\n }\n }\n}\n","import { clean } from '../clean-stores/index.js'\n\nlet listenerQueue = []\nlet lqIndex = 0\nconst QUEUE_ITEMS_PER_LISTENER = 4\n// Use globalThis.nanostoresGlobal to store epoch so all module instances share\n// the same counter. This fixes issues when Nano Store is bundled separately\n// in different parts of an application (e.g., tree-shaking separates core\n// from React), causing each bundle to have its own epoch instance.\nexport const nanostoresGlobal = (globalThis.nanostoresGlobal ||= { epoch: 0 })\n\n/* @__NO_SIDE_EFFECTS__ */\nexport const atom = initialValue => {\n let listeners = []\n let $atom = {\n get() {\n if (!$atom.lc) {\n $atom.listen(() => {})()\n }\n return $atom.value\n },\n init: initialValue,\n lc: 0,\n listen(listener) {\n $atom.lc = listeners.push(listener)\n\n return () => {\n for (\n let i = lqIndex + QUEUE_ITEMS_PER_LISTENER;\n i < listenerQueue.length;\n ) {\n if (listenerQueue[i] === listener) {\n listenerQueue.splice(i, QUEUE_ITEMS_PER_LISTENER)\n } else {\n i += QUEUE_ITEMS_PER_LISTENER\n }\n }\n\n let index = listeners.indexOf(listener)\n if (~index) {\n listeners.splice(index, 1)\n if (!--$atom.lc) $atom.off()\n }\n }\n },\n notify(oldValue, changedKey) {\n nanostoresGlobal.epoch++\n let runListenerQueue = !listenerQueue.length\n for (let listener of listeners) {\n listenerQueue.push(listener, $atom.value, oldValue, changedKey)\n }\n\n if (runListenerQueue) {\n for (\n lqIndex = 0;\n lqIndex < listenerQueue.length;\n lqIndex += QUEUE_ITEMS_PER_LISTENER\n ) {\n listenerQueue[lqIndex](\n listenerQueue[lqIndex + 1],\n listenerQueue[lqIndex + 2],\n listenerQueue[lqIndex + 3]\n )\n }\n listenerQueue.length = 0\n }\n },\n /* It will be called on last listener unsubscribing.\n We will redefine it in onMount and onStop. */\n off() {},\n set(newValue) {\n let oldValue = $atom.value\n if (oldValue !== newValue) {\n $atom.value = newValue\n $atom.notify(oldValue)\n }\n },\n subscribe(listener) {\n let unbind = $atom.listen(listener)\n listener($atom.value)\n return unbind\n },\n value: initialValue\n }\n\n if (process.env.NODE_ENV !== 'production') {\n $atom[clean] = () => {\n listeners = []\n $atom.lc = 0\n $atom.off()\n }\n }\n\n return $atom\n}\n\nexport const readonlyType = store => store\n","import type { Ref } from 'vue'\nimport type { EnrichedUser } from '@pagelines/core'\nimport { atom } from 'nanostores'\nimport { watch } from 'vue'\nimport { cookieUtil, createLogger } from '@pagelines/core'\n\n// Global nanostores shared via globalThis so SDK and app bundles use the same\n// atoms when both run on the same page (Astro multi-island, dashboard preview\n// of a widget, etc.). Each bundle has its own Vue instance — without these\n// globals, signing in to one wouldn't reflect in the other.\n//\n// Refresh credential is NOT in nanostores — it lives in an HttpOnly cookie\n// the browser owns. JS cannot read or write it.\nconst _g = globalThis as Record<string, any>\nconst $globalActiveUser = (_g.__PL_AUTH_USER__ ??= atom<EnrichedUser | undefined>(undefined)) as ReturnType<typeof atom<EnrichedUser | undefined>>\nconst $globalToken = (_g.__PL_AUTH_TOKEN__ ??= atom<string | null>(null)) as ReturnType<typeof atom<string | null>>\nconst $globalDeviceId = (_g.__PL_AUTH_DEVICE_ID__ ??= atom<string | null>(null)) as ReturnType<typeof atom<string | null>>\n\nexport interface AuthRefs {\n activeUser: Ref<EnrichedUser | undefined>\n token: Ref<string | null>\n deviceId: Ref<string | null>\n}\n\n/**\n * SDKStorage - Handles all storage, sync, and persistence for PageLinesSDK\n *\n * Three storage layers, each with a clear job:\n * - Vue refs — runtime source of truth (in-memory)\n * - cookies — survive reload, JS-readable for headers (access token + deviceId)\n * - nanostores — bridge SDK widget bundle ↔ main app bundle on same page\n * - localStorage — UX optimization for cold-load (user object only, never tokens)\n *\n * The refresh credential lives in an HttpOnly cookie the server owns — JS\n * has no access to it, so it never touches any of these layers.\n */\nexport class SDKStorage {\n private logger = createLogger('SDKStorage')\n\n /**\n * Check if localStorage is fully functional (some test environments provide partial mocks)\n */\n private isLocalStorageFunctional(): boolean {\n return typeof window !== 'undefined'\n && typeof localStorage?.getItem === 'function'\n && typeof localStorage?.setItem === 'function'\n && typeof localStorage?.removeItem === 'function'\n }\n\n /**\n * Sync Vue reactive refs with global nanostores for cross-bundle persistence.\n */\n syncWithGlobalStores(refs: AuthRefs): void {\n const { activeUser, token, deviceId } = refs\n\n // 1. Restore from global store on init\n const storedUser = $globalActiveUser.get()\n const storedToken = $globalToken.get()\n const storedDevice = $globalDeviceId.get()\n\n if (storedUser) activeUser.value = storedUser\n if (storedToken) token.value = storedToken\n if (storedDevice) deviceId.value = storedDevice\n\n // 2. Vue refs → global stores (for persistence)\n watch(activeUser, (v) => $globalActiveUser.set(v), { immediate: true })\n watch(token, (v) => $globalToken.set(v), { immediate: true })\n watch(deviceId, (v) => $globalDeviceId.set(v), { immediate: true })\n\n // 3. Global stores → Vue refs (for cross-page updates)\n $globalActiveUser.subscribe((v) => { if (v !== activeUser.value) activeUser.value = v })\n $globalToken.subscribe((v) => { if (v !== token.value) token.value = v })\n $globalDeviceId.subscribe((v) => { if (v !== deviceId.value) deviceId.value = v })\n }\n\n /**\n * Load user and token from browser storage on initialization.\n * deviceId comes from a server-set non-HttpOnly cookie (read-only for JS).\n */\n loadFromStorage(refs: AuthRefs): void {\n if (typeof window === 'undefined')\n return\n\n const savedToken = cookieUtil.getAuthToken()\n if (savedToken) refs.token.value = savedToken\n\n const savedDevice = cookieUtil.getDeviceId()\n if (savedDevice) refs.deviceId.value = savedDevice\n\n // Try to load user from localStorage for immediate availability\n if (this.isLocalStorageFunctional()) {\n try {\n const savedUser = localStorage.getItem('pagelines-user')\n if (savedUser) {\n refs.activeUser.value = JSON.parse(savedUser)\n }\n } catch (error) {\n this.logger.error('Failed to load user from localStorage', { data: error })\n }\n }\n }\n\n /**\n * Save current user and access token to browser storage.\n * deviceId is server-owned (Set-Cookie) — JS doesn't write it.\n */\n saveToStorage(refs: AuthRefs): void {\n if (typeof window === 'undefined')\n return\n\n if (refs.token.value) cookieUtil.setAuthToken(refs.token.value)\n else cookieUtil.removeAuthToken()\n\n // Save user to localStorage for quick loading\n if (this.isLocalStorageFunctional()) {\n try {\n if (refs.activeUser.value) {\n localStorage.setItem('pagelines-user', JSON.stringify(refs.activeUser.value))\n } else {\n localStorage.removeItem('pagelines-user')\n }\n } catch (error) {\n this.logger.error('Failed to save user to localStorage', { data: error })\n }\n }\n }\n\n /**\n * Clear local stored user data and JS-owned tokens. Server-owned cookies\n * (pl-refresh-token, pl-device-id) are cleared by /api/auth/logout via\n * Set-Cookie max-age=0 — JS can't touch them.\n */\n clearStorage(): void {\n if (typeof window === 'undefined')\n return\n\n cookieUtil.removeAuthToken()\n\n if (this.isLocalStorageFunctional()) {\n try {\n localStorage.removeItem('pagelines-user')\n } catch (error) {\n this.logger.error('Failed to clear user from localStorage', { data: error })\n }\n }\n\n // Clear global stores\n $globalActiveUser.set(undefined)\n $globalToken.set(null)\n $globalDeviceId.set(null)\n }\n\n /**\n * Generic localStorage getter\n */\n getItem(key: string): string | null {\n if (!this.isLocalStorageFunctional())\n return null\n\n try {\n return localStorage.getItem(key)\n } catch (error) {\n this.logger.error('Failed to get item from localStorage', { key, error })\n return null\n }\n }\n\n /**\n * Generic localStorage setter\n */\n setItem(key: string, value: string): void {\n if (!this.isLocalStorageFunctional())\n return\n\n try {\n localStorage.setItem(key, value)\n } catch (error) {\n this.logger.error('Failed to set item in localStorage', { key, error })\n }\n }\n}\n","import type { AgentConfig } from '@pagelines/core'\nimport type { SDKContext } from './types'\nimport { resolveApiBase } from '../api'\n\nexport class AgentClient {\n constructor(private ctx: SDKContext) {}\n\n async create(args: { name: string, orgId?: string }): Promise<AgentConfig> {\n const orgId = args.orgId || this.resolveOrgId()\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n\n const response = await fetch(`${apiBase}/api/agents`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(this.ctx.token.value && { Authorization: `Bearer ${this.ctx.token.value}` }),\n },\n body: JSON.stringify({ name: args.name, orgId }),\n })\n\n const data = await response.json() as { ok: boolean, data?: AgentConfig[], error?: string }\n\n if (!data.ok || !data.data?.[0]) {\n const msg = data.error || 'Failed to create agent'\n this.ctx.error.value = msg\n throw new Error(msg)\n }\n\n this.ctx.processApiResponse(data as any)\n return data.data[0]\n }\n\n async getStatus(args: { agentId: string }): Promise<{\n status: string\n ready: boolean\n error?: string\n }> {\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n\n const response = await fetch(`${apiBase}/api/agents/${args.agentId}/status`, {\n headers: {\n ...(this.ctx.token.value && { Authorization: `Bearer ${this.ctx.token.value}` }),\n },\n })\n\n const data = await response.json() as { ok: boolean, data?: { status: string, ready: boolean, error?: string } }\n\n if (!data.ok || !data.data) {\n return { status: 'unknown', ready: false, error: 'Failed to check status' }\n }\n\n return data.data\n }\n\n /**\n * Poll until the agent is ready. `onStatus` receives the server-reported\n * status string verbatim ('starting', 'provisioning', 'running', …) so\n * the caller renders feedback tied to actual provisioner state, not a\n * rotating set of decorative messages decoupled from reality. Per\n * first-principles → \"Always give feedback — no magic\": a spinner that\n * emits unrelated copy is closer to magic than to feedback. Map status\n * names to user copy at the call site.\n */\n async waitUntilReady(args: {\n agentId: string\n onStatus?: (status: string) => void\n timeoutMs?: number\n pollIntervalMs?: number\n }): Promise<void> {\n const { agentId, onStatus, timeoutMs = 300_000, pollIntervalMs = 3_000 } = args\n const start = Date.now()\n let lastStatus: string | undefined\n\n while (Date.now() - start < timeoutMs) {\n const status = await this.getStatus({ agentId })\n\n if (status.ready) {\n onStatus?.('running')\n return\n }\n\n if (status.status === 'error')\n throw new Error(status.error || 'Provisioning failed')\n\n // Only fire onStatus when the kind changes — avoids spamming the\n // caller's UI with redundant updates on every 3s tick.\n if (status.status !== lastStatus) {\n onStatus?.(status.status)\n lastStatus = status.status\n }\n\n await new Promise((r) => setTimeout(r, pollIntervalMs))\n }\n\n throw new Error('Agent provisioning timed out — please try again')\n }\n\n /** Send a typed webhook event to a bot agent. No auth required — the proxy is public. */\n async webhook<T = Record<string, unknown>>(args: {\n agentId: string\n type: string\n data: T\n meta?: { source?: string, timestamp?: string, correlationId?: string, [key: string]: unknown }\n }): Promise<{ ok: boolean, error?: string }> {\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n const url = `${apiBase}/api/bot-api/webhooks/agents/${args.agentId}`\n\n const body: Record<string, unknown> = { type: args.type, data: args.data }\n if (args.meta) body.meta = args.meta\n\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n\n if (!res.ok) {\n const text = await res.text().catch(() => 'Unknown error')\n throw new Error(`Webhook delivery failed (${res.status}): ${text.slice(0, 200)}`)\n }\n\n return res.json() as Promise<{ ok: boolean, error?: string }>\n }\n\n private resolveOrgId(): string {\n const user = this.ctx.activeUser.value\n const orgId = user?.orgs?.[0]?.orgId\n if (!orgId) {\n throw new Error('No organization found. Please sign in first.')\n }\n return orgId\n }\n}\n","import type { EnrichedUser } from '@pagelines/core'\nimport type { SDKContext } from './types'\nimport { resolveApiBase } from '../api'\n\n/**\n * Run an async operation with loading/error state management.\n * Sets loading=true and error=null before, loading=false in finally.\n */\nasync function withLoadingState<T>(ctx: SDKContext, fn: () => Promise<T>): Promise<T> {\n ctx.loading.value = true\n ctx.error.value = null\n try {\n return await fn()\n } finally {\n ctx.loading.value = false\n }\n}\n\nexport class AuthClient {\n constructor(private ctx: SDKContext) {}\n\n async sendCode(email: string): Promise<void> {\n return withLoadingState(this.ctx, async () => {\n try {\n const response = await this.ctx.apiFetch('/api/auth/check-email', {\n method: 'POST',\n body: JSON.stringify({ email }),\n })\n const data = await response.json() as { ok: true } | { ok: false, error: string }\n if (!data.ok) {\n this.ctx.error.value = data.error\n throw new Error(data.error)\n }\n } catch (err) {\n this.ctx.logger.error('Send code error', { data: err })\n const errorMessage = err instanceof Error ? err.message : 'Failed to send verification code'\n this.ctx.error.value = errorMessage\n throw err\n }\n })\n }\n\n async verifyCode(email: string, code: string): Promise<void> {\n return withLoadingState(this.ctx, async () => {\n try {\n const response = await this.ctx.apiFetch('/api/auth/verify-code', {\n method: 'POST',\n body: JSON.stringify({ email, code }),\n })\n const data = await response.json() as { ok: true } | { ok: false, error: string }\n if (!data.ok) {\n this.ctx.error.value = data.error\n throw new Error(data.error)\n }\n } catch (err) {\n this.ctx.logger.error('Verify code error', { data: err })\n const errorMessage = err instanceof Error ? err.message : 'Failed to verify code'\n this.ctx.error.value = errorMessage\n throw err\n }\n })\n }\n\n async logout(): Promise<void> {\n return withLoadingState(this.ctx, async () => {\n try {\n await this.ctx.apiFetch('/api/auth/logout', { method: 'POST' })\n } catch (err) {\n this.ctx.logger.error('Logout error (user still logged out locally)', { data: err })\n }\n // Always clear local state regardless of API success\n this.ctx.activeUser.value = undefined\n this.ctx.token.value = null\n this.ctx.storage.clearStorage()\n })\n }\n\n async getCurrentUser(): Promise<EnrichedUser | undefined> {\n if (!this.ctx.token.value) {\n return undefined\n }\n\n return withLoadingState(this.ctx, async () => {\n try {\n const response = await this.ctx.apiFetch('/api/users/me', {\n method: 'GET',\n })\n const data = await response.json() as { ok: true, data: EnrichedUser } | { ok: false, error: string }\n\n if (!data.ok) {\n this.ctx.error.value = data.error\n if (data.error.includes('Authentication')) {\n this.ctx.activeUser.value = undefined\n this.ctx.token.value = null\n this.ctx.storage.clearStorage()\n }\n return undefined\n }\n\n // Set activeUser directly — `/users/me` envelope is\n // `{ ok: true, data: enrichedUser }`. processApiResponse is shaped\n // for sign-in responses (token + user + deviceId at the top level);\n // synthesizing a fake legacy envelope to feed it is shadow-state.\n // The token check guards against stale in-flight responses landing\n // after a logout cleared the session.\n if (this.ctx.token.value)\n this.ctx.activeUser.value = data.data\n return data.data\n } catch (err) {\n this.ctx.logger.error('Get current user error', { data: err })\n this.ctx.error.value = err instanceof Error ? err.message : 'Failed to get user info'\n return undefined\n }\n })\n }\n\n async requestAuthCode(args: { email: string }): Promise<boolean> {\n return withLoadingState(this.ctx, async () => {\n try {\n const response = await this.ctx.apiFetch('/api/auth/check-email', {\n method: 'POST',\n body: JSON.stringify({ email: args.email }),\n })\n const data = await response.json() as { ok: true } | { ok: false, error: string }\n if (!data.ok) {\n this.ctx.error.value = data.error\n this.ctx.logger.error('Failed to request auth code', { email: args.email, error: data.error })\n return false\n }\n this.ctx.logger.info('Auth code requested successfully', { email: args.email })\n return true\n } catch (err) {\n this.ctx.logger.error('Request auth code error', { email: args.email, error: err })\n this.ctx.error.value = err instanceof Error ? err.message : 'Failed to request auth code'\n return false\n }\n })\n }\n\n async loginWithCode(args: {\n email: string\n code: string\n orgId?: string\n autoCreateContact?: boolean\n }): Promise<boolean> {\n return withLoadingState(this.ctx, async () => {\n try {\n const response = await this.ctx.apiFetch('/api/auth/verify-code', {\n method: 'POST',\n body: JSON.stringify({ email: args.email, code: args.code }),\n })\n const data = await response.json() as { ok: true } | { ok: false, error: string }\n if (!data.ok) {\n this.ctx.error.value = data.error\n this.ctx.logger.error('Login failed', { email: args.email, error: data.error })\n return false\n }\n this.ctx.logger.info('Login successful', { email: args.email })\n return true\n } catch (err) {\n this.ctx.logger.error('Login with code error', { email: args.email, error: err })\n this.ctx.error.value = err instanceof Error ? err.message : 'Login failed'\n return false\n }\n })\n }\n\n loginWithGoogle(args?: { onSuccess?: (user: EnrichedUser) => void, onError?: (error: string) => void }): void {\n if (typeof window === 'undefined') {\n this.ctx.logger.error('loginWithGoogle: Only available in browser')\n return\n }\n\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n const origin = window.location.origin\n const popupUrl = `${apiBase}/auth/google-popup?origin=${encodeURIComponent(origin)}`\n\n // Open centered popup\n const width = 500\n const height = 600\n const left = window.screenX + (window.outerWidth - width) / 2\n const top = window.screenY + (window.outerHeight - height) / 2\n const popup = window.open(\n popupUrl,\n 'google-auth',\n `width=${width},height=${height},left=${left},top=${top},popup=yes`,\n )\n\n if (!popup) {\n const msg = 'Popup was blocked. Please allow popups for this site.'\n this.ctx.error.value = msg\n args?.onError?.(msg)\n return\n }\n\n // Listen for postMessage from popup\n const handler = (event: MessageEvent) => {\n // Validate origin -- must be our API base\n const expectedOrigin = new URL(apiBase).origin\n if (event.origin !== expectedOrigin) return\n\n if (event.data?.type === 'auth-success') {\n window.removeEventListener('message', handler)\n const { token, user } = event.data\n\n // Process the auth response the same way as other login methods\n this.ctx.processApiResponse({ ok: true, data: {}, token, user })\n\n this.ctx.logger.info('Google login successful')\n args?.onSuccess?.(user)\n } else if (event.data?.type === 'auth-error') {\n window.removeEventListener('message', handler)\n const errorMsg = event.data.error || 'Google authentication failed'\n this.ctx.error.value = errorMsg\n this.ctx.logger.error('Google login failed', { error: errorMsg })\n args?.onError?.(errorMsg)\n }\n }\n\n window.addEventListener('message', handler)\n\n // Clean up listener if popup is closed without completing auth\n const checkClosed = setInterval(() => {\n if (popup.closed) {\n clearInterval(checkClosed)\n window.removeEventListener('message', handler)\n }\n }, 500)\n }\n}\n","import type { SDKContext } from './types'\nimport { resolveApiBase } from '../api'\n\nexport interface BillingStatus {\n plan?: string\n status: string\n hasActiveBilling: boolean\n maxAgents: number\n trialEnd?: string\n trialDaysRemaining?: number\n}\n\nexport class BillingClient {\n constructor(private ctx: SDKContext) {}\n\n async startTrial(args?: { returnUrl?: string, planKey?: string }): Promise<void> {\n const orgId = this.resolveOrgId()\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n\n const response = await fetch(`${apiBase}/api/billing/checkout/create`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(this.ctx.token.value && { Authorization: `Bearer ${this.ctx.token.value}` }),\n },\n body: JSON.stringify({\n orgId,\n ...(args?.returnUrl && { returnUrl: args.returnUrl }),\n ...(args?.planKey && { planKey: args.planKey }),\n }),\n })\n\n const data = await response.json() as { ok: boolean, data?: { url: string }, error?: string }\n\n if (!data.ok || !data.data?.url) {\n const msg = data.error || 'Failed to create checkout session'\n this.ctx.error.value = msg\n throw new Error(msg)\n }\n\n window.location.href = data.data.url\n }\n\n async confirmCheckout(_args?: { sessionId?: string }): Promise<BillingStatus> {\n return this.getStatus()\n }\n\n async getStatus(): Promise<BillingStatus> {\n const orgId = this.resolveOrgId()\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n\n const response = await fetch(`${apiBase}/api/billing/details/${orgId}`, {\n headers: {\n ...(this.ctx.token.value && { Authorization: `Bearer ${this.ctx.token.value}` }),\n },\n })\n\n const data = await response.json() as {\n ok: boolean\n data?: { plan: string, status: string, maxAgents: number, trialEnd?: string, trialDaysRemaining?: number }\n error?: string\n }\n\n if (!data.ok || !data.data) {\n return {\n plan: undefined,\n status: 'none',\n hasActiveBilling: false,\n maxAgents: 0,\n }\n }\n\n const ACTIVE_STATUSES = ['active', 'trialing']\n\n return {\n plan: data.data.plan,\n status: data.data.status,\n hasActiveBilling: ACTIVE_STATUSES.includes(data.data.status),\n maxAgents: data.data.maxAgents,\n ...(data.data.trialEnd && { trialEnd: data.data.trialEnd }),\n ...(data.data.trialDaysRemaining !== undefined && { trialDaysRemaining: data.data.trialDaysRemaining }),\n }\n }\n\n private resolveOrgId(): string {\n const user = this.ctx.activeUser.value\n const orgId = user?.orgs?.[0]?.orgId\n if (!orgId) {\n throw new Error('No organization found. Please sign in first.')\n }\n return orgId\n }\n}\n","import type { ApiResponse, ChatAttachmentInput } from '@pagelines/core'\nimport type { ChatAttachment, ChatMessage } from '../agent/schema'\nimport type { SDKContext } from './types'\nimport { shortId } from '@pagelines/core'\nimport { resolveApiBase } from '../api'\n\n/**\n * Stripped down view of the substrate's `Message` row. The SDK can't import\n * Drizzle's `$inferSelect` (server-only), so we restate the wire shape here.\n * Mirrors `src/modules/db/tables/schema/messages.ts → Message` — keep in sync.\n */\ninterface SubstrateMessage {\n messageId: string\n conversationId: string\n // Author participant row — NULL for `role: 'system'` (authorless turns).\n authorParticipantId: string | null\n systemKind: string | null\n role: 'user' | 'assistant' | 'system'\n content: string\n sequence: string\n clientNonce: string | null\n metadata: {\n attachments?: ChatAttachment[]\n issue?: { code: string, bucket: 'account' | 'error', actionLabel: string, actionUrl: string, help?: string }\n [key: string]: any\n } | null\n status: string | null\n createdAt: string\n updatedAt: string\n}\n\n/**\n * Wire format of the substrate SSE stream — frames look like:\n * event: <name>\\n\n * data: <json>\\n\n * \\n\n * Mirrors the canonical `zChatEvent` union in `@pagelines/core`\n * (`packages/core/src/wire/chat-event.ts`) — all seven event variants must\n * stay in sync. TODO: import `zChatEvent` directly instead of hand-restating.\n */\ntype ChatEvent\n = | { event: 'status', data: { liveStatus: string, sinceAt?: string, errorReason?: string, blocker?: unknown } }\n | { event: 'message', data: { message: SubstrateMessage } }\n | { event: 'message_delta', data: { delta: string, turnId: string, messageId?: string, role?: 'assistant' | 'system' } }\n | { event: 'working_state', data: { description: string } }\n | { event: 'working_end', data: Record<string, never> }\n | { event: 'error', data: {\n code: string\n message: string\n bucket?: 'account' | 'error'\n actionLabel?: string\n actionUrl?: string\n help?: string\n } }\n | { event: 'stream_end', data: Record<string, never> }\n\nconst KNOWN_EVENTS = new Set(['status', 'message', 'message_delta', 'working_state', 'working_end', 'error', 'stream_end'])\n\nfunction parseChatEvent(frame: string): ChatEvent | null {\n const lines = frame.split('\\n').filter((l) => l.length > 0)\n let name: string | undefined\n let payload: string | undefined\n for (const line of lines) {\n if (line.startsWith('event:'))\n name = line.slice(6).trim()\n else if (line.startsWith('data:'))\n payload = line.slice(5).trim()\n }\n if (!name || payload === undefined || !KNOWN_EVENTS.has(name))\n return null\n try {\n return { event: name, data: JSON.parse(payload) } as ChatEvent\n } catch {\n return null\n }\n}\n\nfunction toChatMessage(message: SubstrateMessage): ChatMessage | undefined {\n if (message.role !== 'assistant' && message.role !== 'system')\n return undefined\n return {\n id: message.messageId,\n text: message.content,\n sender: message.role === 'system' ? 'system' : 'agent',\n timestamp: message.createdAt,\n ...(message.metadata?.attachments?.length\n ? { attachments: message.metadata.attachments }\n : {}),\n ...(message.metadata?.issue ? { issue: message.metadata.issue } : {}),\n }\n}\n\nexport class ChatClient {\n constructor(private ctx: SDKContext) {}\n\n /**\n * Public/visitor chat — anonymous chat against an agent's public handle,\n * routed through the messaging substrate. Same SSE wire format as\n * `chatStreamAuthenticated` — the only difference is the route (no auth,\n * handle-based lookup, anonymousId instead of userId).\n *\n * The visitor identity is `anonymousId` — caller is responsible for\n * generating + persisting it (typically `sdk.user.generateAnonId()`\n * which stores a stable ID in localStorage).\n */\n async chatStreamPublic(args: {\n handle: string\n message: string\n anonymousId: string\n attachments?: ChatAttachmentInput[]\n context?: string\n onDelta: (text: string, role?: 'assistant' | 'system') => void\n onMessage?: (message: ChatMessage) => void\n onDone: (conversationId: string) => void\n onError: (error: string) => void\n onStatus?: (status: string) => void\n }): Promise<void> {\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n const url = `${apiBase}/api/agents/public/${encodeURIComponent(args.handle)}/chat/v2/stream`\n\n let conversationId = ''\n let errorSeen = false\n let assistantSeen = false\n let reader: ReadableStreamDefaultReader<Uint8Array> | undefined\n\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n message: args.message,\n anonymousId: args.anonymousId,\n ...(args.attachments?.length ? { attachments: args.attachments } : {}),\n ...(args.context ? { context: args.context } : {}),\n }),\n })\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({ error: 'Request failed' })) as { error?: string }\n args.onError(errorBody.error || `HTTP ${res.status}`)\n return\n }\n\n // Server emits the resolved conversationId in a response header so the\n // SDK can persist it across page loads (e.g. for \"resume conversation\"\n // flows). The substrate would also have a `message` event with the\n // conversationId on the persisted user msg, but the header arrives\n // first and is cheaper to parse.\n conversationId = res.headers.get('X-Conversation-Id') || ''\n reader = res.body?.getReader()\n if (!reader) {\n args.onError('No response stream')\n return\n }\n\n const decoder = new TextDecoder()\n let buffer = ''\n outer: while (true) {\n const { done, value } = await reader.read()\n if (done)\n break\n buffer += decoder.decode(value, { stream: true })\n let sep = buffer.indexOf('\\n\\n')\n while (sep !== -1) {\n const frame = buffer.slice(0, sep)\n buffer = buffer.slice(sep + 2)\n const event = parseChatEvent(frame)\n if (event) {\n if (event.event === 'working_state') {\n args.onStatus?.(event.data.description)\n } else if (event.event === 'message_delta') {\n args.onDelta(event.data.delta, event.data.role)\n } else if (event.event === 'error') {\n errorSeen = true\n args.onError(event.data.message)\n break outer\n } else if (event.event === 'message' && (event.data.message.role === 'assistant' || event.data.message.role === 'system')) {\n assistantSeen = true\n const message = toChatMessage(event.data.message)\n if (message)\n args.onMessage?.(message)\n // Wait for stream_end — the v2 route emits it after the\n // assistant message lands so deltas-then-message ordering is\n // preserved without breaking out early.\n } else if (event.event === 'stream_end') {\n break outer\n }\n }\n sep = buffer.indexOf('\\n\\n')\n }\n }\n\n if (!errorSeen && assistantSeen)\n args.onDone(conversationId)\n else if (!errorSeen)\n args.onError('Stream ended before reply arrived')\n } catch (err) {\n args.onError(err instanceof Error ? err.message : 'Stream failed')\n } finally {\n try {\n await reader?.cancel()\n } catch {\n // Stream already closed.\n }\n }\n }\n\n\n /**\n * Authenticated chat — substrate-backed:\n * POST /api/conversations, open SSE from that conversation's latest\n * sequence, then POST /api/messages. Opening the stream before send keeps\n * fast working_state / message_delta frames from outrunning the subscriber.\n * Same callback contract as `chatStream` so callers don't need transport details.\n * Mirrors `src/modules/agent/client.ts → sendChatMessageStream`.\n */\n async chatStreamAuthenticated(args: {\n agentId: string\n message: string\n attachments?: ChatAttachmentInput[]\n /** Reserved — substrate resolves conversation server-side from (userId, agentId). */\n conversationId?: string\n /** Reserved — substrate replays history from the canonical messages table. */\n history?: Array<{ role: 'user' | 'assistant', content: string }>\n onDelta: (text: string, role?: 'assistant' | 'system') => void\n onMessage?: (message: ChatMessage) => void\n onDone: (conversationId: string) => void\n onError: (error: string) => void\n onStatus?: (status: string) => void\n }): Promise<void> {\n const apiBase = resolveApiBase(this.ctx.apiBase, this.ctx.isDev)\n const authHeaders: Record<string, string> = this.ctx.token.value\n ? { Authorization: `Bearer ${this.ctx.token.value}` }\n : {}\n\n // 1. Resolve the conversation — `POST /conversations` returns the\n // singleton (user, agent) conversationId. Chat is conversation-addressed.\n let conversationId: string\n let latestSequence: string | null = null\n try {\n const res = await fetch(`${apiBase}/api/conversations`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...authHeaders },\n body: JSON.stringify({ agentId: args.agentId }),\n })\n const result = await res.json() as ApiResponse<{ conversationId: string, latestSequence?: string | null }>\n if (!result.ok) {\n args.onError(result.error || `Conversation failed: HTTP ${res.status}`)\n return\n }\n conversationId = result.data.conversationId\n latestSequence = result.data.latestSequence ?? null\n } catch (err) {\n args.onError(err instanceof Error ? err.message : 'Conversation failed')\n return\n }\n\n let sendStarted = false\n let sendFailed = false\n let errorSeen = false\n let assistantSeen = false\n let streamClosed = false\n let streamOpenTimedOut = false\n let reader: ReadableStreamDefaultReader<Uint8Array> | undefined\n const streamAbort = new AbortController()\n let streamReadySettled = false\n let streamReadyTimer: ReturnType<typeof setTimeout> | undefined\n let resolveStreamReady: (value: 'ready' | 'failed') => void = () => {}\n const streamReady = new Promise<'ready' | 'failed'>((resolve) => {\n resolveStreamReady = resolve\n })\n const settleStreamReady = (value: 'ready' | 'failed') => {\n if (streamReadySettled)\n return\n streamReadySettled = true\n if (streamReadyTimer)\n clearTimeout(streamReadyTimer)\n resolveStreamReady(value)\n }\n const cancelReader = () => {\n reader?.cancel().catch(() => {\n // Stream already closed or never opened.\n })\n }\n const streamUrl = latestSequence\n ? `${apiBase}/api/conversations/${encodeURIComponent(conversationId)}/stream?since=${encodeURIComponent(latestSequence)}`\n : `${apiBase}/api/conversations/${encodeURIComponent(conversationId)}/stream`\n\n streamReadyTimer = setTimeout(() => {\n streamOpenTimedOut = true\n errorSeen = true\n args.onError('Timed out opening stream')\n streamAbort.abort()\n settleStreamReady('failed')\n }, 10000)\n\n const streamPromise = (async () => {\n try {\n const streamRes = await fetch(streamUrl, {\n headers: authHeaders,\n signal: streamAbort.signal,\n })\n if (!streamRes.ok) {\n errorSeen = true\n settleStreamReady('failed')\n args.onError(`Stream failed: HTTP ${streamRes.status}`)\n return\n }\n reader = streamRes.body?.getReader()\n if (!reader) {\n errorSeen = true\n settleStreamReady('failed')\n args.onError('No response stream')\n return\n }\n settleStreamReady('ready')\n\n const decoder = new TextDecoder()\n let buffer = ''\n outer: while (true) {\n const { done, value } = await reader.read()\n if (done)\n break\n buffer += decoder.decode(value, { stream: true })\n let sep = buffer.indexOf('\\n\\n')\n while (sep !== -1) {\n const frame = buffer.slice(0, sep)\n buffer = buffer.slice(sep + 2)\n const event = parseChatEvent(frame)\n if (event) {\n if (event.event === 'working_state') {\n if (sendStarted)\n args.onStatus?.(event.data.description)\n } else if (event.event === 'message_delta') {\n if (sendStarted)\n args.onDelta(event.data.delta, event.data.role)\n } else if (event.event === 'error') {\n errorSeen = true\n args.onError(event.data.message)\n break outer\n } else if (event.event === 'message' && (event.data.message.role === 'assistant' || event.data.message.role === 'system')) {\n if (!sendStarted)\n continue\n assistantSeen = true\n const message = toChatMessage(event.data.message)\n if (message)\n args.onMessage?.(message)\n break outer\n } else if (event.event === 'stream_end') {\n break outer\n }\n }\n sep = buffer.indexOf('\\n\\n')\n }\n }\n\n if (!errorSeen && assistantSeen)\n args.onDone(conversationId)\n else if (!errorSeen && sendStarted && !sendFailed)\n args.onError('Stream ended before reply arrived')\n } catch (err) {\n if (!sendFailed && !streamOpenTimedOut) {\n errorSeen = true\n settleStreamReady('failed')\n args.onError(err instanceof Error ? err.message : 'Stream failed')\n }\n } finally {\n streamClosed = true\n try {\n await reader?.cancel()\n } catch {\n // Stream already closed.\n }\n }\n })()\n\n const ready = await streamReady\n if (ready === 'failed') {\n await streamPromise\n return\n }\n if (streamClosed) {\n args.onError('Stream closed before send')\n await streamPromise\n return\n }\n\n // 2. Persist + publish the user turn against the resolved conversation.\n const clientNonce = `nonce_${shortId(16)}`\n try {\n sendStarted = true\n const res = await fetch(`${apiBase}/api/messages`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...authHeaders },\n body: JSON.stringify({\n conversationId,\n content: args.message,\n clientNonce,\n ...(args.attachments && args.attachments.length > 0 ? { attachments: args.attachments } : {}),\n }),\n })\n const result = await res.json() as ApiResponse<SubstrateMessage>\n if (!result.ok) {\n sendFailed = true\n streamAbort.abort()\n cancelReader()\n args.onError(result.error || `Send failed: HTTP ${res.status}`)\n await streamPromise\n return\n }\n } catch (err) {\n sendFailed = true\n streamAbort.abort()\n cancelReader()\n args.onError(err instanceof Error ? err.message : 'Send failed')\n await streamPromise\n return\n }\n\n await streamPromise\n }\n\n}\n","import type { AgentConfig } from '@pagelines/core'\nimport { objectId } from '@pagelines/core'\nimport type { SDKContext } from './types'\n\nexport class UserClient {\n constructor(private ctx: SDKContext) {}\n\n async getPublicAgent(args: { handle: string }): Promise<AgentConfig | undefined> {\n this.ctx.loading.value = true\n this.ctx.error.value = null\n\n try {\n const response = await this.ctx.apiFetch(`/api/agents/public/${encodeURIComponent(args.handle)}`)\n\n const data = await response.json() as { ok: true, data: AgentConfig } | { ok: false, error: string }\n\n if (!data.ok) {\n this.ctx.error.value = data.error\n this.ctx.logger.error('Failed to fetch public agent', { handle: args.handle, error: data.error })\n return undefined\n }\n\n return data.data\n } catch (err) {\n this.ctx.logger.error('Get public agent error', { handle: args.handle, error: err })\n this.ctx.error.value = err instanceof Error ? err.message : 'Failed to fetch agent'\n return undefined\n } finally {\n this.ctx.loading.value = false\n }\n }\n\n async getAgentByEmail(args: { email: string }): Promise<AgentConfig | undefined> {\n this.ctx.loading.value = true\n this.ctx.error.value = null\n\n try {\n const response = await this.ctx.apiFetch(`/api/agents/by-email/${encodeURIComponent(args.email)}`)\n\n const data = await response.json() as { ok: true, data: AgentConfig } | { ok: false, error: string }\n\n if (!data.ok) {\n this.ctx.error.value = data.error\n this.ctx.logger.error('Failed to fetch agent by email', { email: args.email, error: data.error })\n return undefined\n }\n\n return data.data\n } catch (err) {\n this.ctx.logger.error('Get agent by email error', { email: args.email, error: err })\n this.ctx.error.value = err instanceof Error ? err.message : 'Failed to fetch agent'\n return undefined\n } finally {\n this.ctx.loading.value = false\n }\n }\n\n generateAnonId(): string {\n const storageKey = 'pagelinesAnonId'\n let anonId = this.ctx.storage.getItem(storageKey)\n\n if (!anonId) {\n anonId = objectId({ prefix: 'anon' })\n this.ctx.storage.setItem(storageKey, anonId)\n }\n\n return anonId\n }\n\n track(args: {\n event: 'view_profile' | 'profile_interaction'\n agentId: string\n properties?: Record<string, any>\n }): void {\n try {\n // Track event via postMessage to parent window if embedded\n if (typeof window !== 'undefined' && window.parent !== window) {\n window.parent.postMessage({\n type: 'pagelines_track',\n event: args.event,\n agentId: args.agentId,\n properties: args.properties || {},\n }, '*')\n }\n\n this.ctx.logger.info('SDK event tracked', { event: args.event, agentId: args.agentId })\n } catch (err) {\n this.ctx.logger.error('Track event error', { error: err, args })\n }\n }\n}\n","import type { ApiResponse, EnrichedUser } from '@pagelines/core'\nimport { objectId, SettingsObject } from '@pagelines/core'\nimport { computed, ref } from 'vue'\nimport { createApiFetch } from './api'\nimport { SDKStorage } from './sdkStorage'\nimport { AgentClient } from './clients/AgentClient'\nimport { AuthClient } from './clients/AuthClient'\nimport { BillingClient } from './clients/BillingClient'\nimport { ChatClient } from './clients/ChatClient'\nimport { UserClient } from './clients/UserClient'\nimport type { SDKContext } from './clients/types'\n\nexport interface PageLinesSDKSettings {\n apiBase?: string\n isDev?: boolean\n [key: string]: unknown\n}\n\n/**\n * Browser-only singleton manager\n * Browser: Uses globalThis for cross-bundle singleton (www + widget)\n * Node.js SSR: No singleton - each request gets new instance (prevents request bleeding)\n */\nclass SDKGlobal {\n private key = '__PAGELINES_SDK__'\n\n get(): PageLinesSDK | undefined {\n if (typeof window === 'undefined')\n return undefined\n return (globalThis as any)[this.key]\n }\n\n set(instance: PageLinesSDK): void {\n if (typeof window !== 'undefined')\n (globalThis as any)[this.key] = instance\n }\n\n delete(): void {\n if (typeof window !== 'undefined')\n delete (globalThis as any)[this.key]\n }\n}\n\n// Module-scoped singleton manager\nconst sdkGlobal = new SDKGlobal()\n\nexport class PageLinesSDK extends SettingsObject<PageLinesSDKSettings> {\n /**\n * Get singleton instance in browser (creates if doesn't exist)\n * Node.js: Always creates new instance (no singleton)\n * Recommended: Use this instead of constructor for shared state\n */\n static getInstance(settings: PageLinesSDKSettings = {}): PageLinesSDK {\n // Browser: return singleton or create\n // Node: always create new (no singleton)\n return sdkGlobal.get() || new PageLinesSDK(settings)\n }\n\n // Vue reactive state\n activeUser = ref<EnrichedUser | undefined>()\n token = ref<string | null>(null)\n // Refresh credential lives in HttpOnly pl-refresh-token cookie — JS never\n // holds it, so no reactive ref. /api/auth/refresh reads the cookie via the\n // browser's automatic credentials: 'include' attach.\n deviceId = ref<string | null>(null)\n loading = ref(false)\n error = ref<string | null>(null)\n apiBase = this.settings.apiBase || undefined\n\n // Storage handler for persistence\n private storage = new SDKStorage()\n\n // Auto-managed session ID for usage tracking\n private sessionId = objectId({ prefix: 'ses' })\n\n get isDev() {\n return this.settings.isDev ?? (\n typeof window !== 'undefined'\n ? window.location.hostname === 'localhost' || window.location.hostname.includes('127.0.0.1')\n : false\n )\n }\n\n // Computed properties derived from activeUser (matches UserClient pattern)\n currentAgent = computed(() => {\n const user = this.activeUser.value\n if (!user?.agents)\n return undefined\n\n const agentId = user.primaryAgentId || user.agents[0]?.agentId\n if (!agentId)\n return undefined\n\n return user.agents.find((a) => a.agentId === agentId)\n })\n\n currentOrg = computed(() => {\n const agent = this.currentAgent.value\n if (!agent?.orgId)\n return undefined\n\n const user = this.activeUser.value\n if (!user?.orgs)\n return undefined\n\n return user.orgs.find((org) => org.orgId === agent.orgId)\n })\n\n // Initialization state\n initialized?: Promise<EnrichedUser | undefined>\n resolveUser?: (value: EnrichedUser | undefined) => void\n\n // Sub-clients (new preferred API surface)\n readonly agent!: AgentClient\n readonly auth!: AuthClient\n readonly billing!: BillingClient\n readonly chat!: ChatClient\n readonly user!: UserClient\n\n constructor(settings: PageLinesSDKSettings = {}) {\n // Browser: return existing singleton\n // Node: always create new\n const existing = sdkGlobal.get()\n if (existing) {\n console.debug('[PageLinesSDK] Returning existing singleton instance')\n return existing\n }\n\n super('PageLinesSDK', settings)\n\n // Browser: set singleton reference (no-op in Node)\n sdkGlobal.set(this)\n\n // Shared fetch with response handler + auto-refresh on 401.\n // Refresh credential is in the HttpOnly cookie; the browser attaches it\n // automatically when /refresh is hit with credentials: 'include'.\n const apiFetch = createApiFetch(\n { isDev: this.isDev, apiBase: this.apiBase },\n this.processApiResponse.bind(this),\n {\n getDeviceId: () => this.deviceId.value,\n onAccessTokenRefreshed: (token) => {\n this.token.value = token\n this.persistAuth()\n },\n onTerminalFailure: () => {\n this.clearSession()\n },\n },\n )\n\n // Build shared context for sub-clients\n const ctx: SDKContext = {\n apiFetch,\n apiBase: this.apiBase,\n isDev: this.isDev,\n activeUser: this.activeUser,\n token: this.token,\n loading: this.loading,\n error: this.error,\n currentAgent: this.currentAgent,\n storage: this.storage,\n sessionId: this.sessionId,\n logger: this.logger,\n processApiResponse: this.processApiResponse.bind(this),\n }\n\n // Initialize sub-clients\n this.agent = new AgentClient(ctx)\n this.auth = new AuthClient(ctx)\n this.billing = new BillingClient(ctx)\n this.chat = new ChatClient(ctx)\n this.user = new UserClient(ctx)\n\n this.logger.info('PageLinesSDK initialized')\n\n // Initialize from storage using handler\n this.storage.loadFromStorage(this.authRefs())\n\n // Sync with global stores for persistence across navigation\n this.storage.syncWithGlobalStores(this.authRefs())\n\n // Set up initialization promise (same pattern as UserClient)\n this.initialized = new Promise((resolve) => {\n this.resolveUser = resolve\n })\n\n // Auto-fetch user if token exists (mirrors UserClient pattern)\n if (this.token.value && !this.activeUser.value) {\n this.auth.getCurrentUser().then((user) => {\n if (this.resolveUser) {\n this.resolveUser(user)\n this.resolveUser = undefined\n }\n }).catch((err: unknown) => {\n this.logger.error('Auto user fetch failed', { data: err })\n if (this.resolveUser) {\n this.resolveUser(undefined)\n this.resolveUser = undefined\n }\n })\n } else if (this.activeUser.value) {\n // Resolve immediately if we already have a user from storage\n this.resolveUser?.(this.activeUser.value)\n } else {\n // No token, resolve with undefined\n this.resolveUser?.(undefined)\n }\n }\n\n // Process ApiResponse for automatic user/token updates - public for dependency injection\n processApiResponse(response: ApiResponse<any>): void {\n if (!response.ok) return\n\n let dirty = false\n\n if (response.user) {\n this.activeUser.value = response.user\n this.logger.info('User updated from API response', { data: response.user })\n dirty = true\n }\n\n if (response.token) {\n this.token.value = response.token\n this.logger.info('Token updated from API response')\n dirty = true\n }\n\n // deviceId rides inside data.* on /verify-code and Apple/Google routes.\n // Server ALSO sets it as a non-HttpOnly cookie — we mirror to the ref\n // so the rest of the SDK can observe \"we're paired\" reactively.\n const incomingDeviceId = (response.data as { deviceId?: string } | undefined)?.deviceId\n if (incomingDeviceId) {\n this.deviceId.value = incomingDeviceId\n dirty = true\n }\n\n if (dirty) this.persistAuth()\n\n // Resolve initialization promise\n if (this.resolveUser) {\n this.resolveUser(response.user)\n this.resolveUser = undefined\n }\n }\n\n private authRefs() {\n return {\n activeUser: this.activeUser,\n token: this.token,\n deviceId: this.deviceId,\n }\n }\n\n private persistAuth() {\n this.storage.saveToStorage(this.authRefs())\n }\n\n // Clear all user data and tokens\n clearSession(): void {\n this.logger.info('Clearing session')\n this.activeUser.value = undefined\n this.token.value = null\n this.deviceId.value = null\n this.error.value = null\n this.storage.clearStorage()\n }\n\n // Full reset - clears session + state + destroys singleton\n clear(): void {\n this.logger.info('Clearing SDK completely')\n\n // 1. Clear session data\n this.clearSession()\n\n // 2. Reset other state\n this.loading.value = false\n this.sessionId = objectId({ prefix: 'ses' })\n\n // 3. Destroy singleton (no-op in Node)\n sdkGlobal.delete()\n }\n}\n"],"names":["resolveApiBase","apiBase","isDev","APP_PORT","APP_PROD_URL","__name","createApiFetch","settings","responseHandler","refreshHooks","baseUrl","baseFetch","createRefreshingFetch","input","init","token","cookieUtil","headers","requestInput","response","originalJson","result","clean","listenerQueue","lqIndex","QUEUE_ITEMS_PER_LISTENER","nanostoresGlobal","atom","initialValue","listeners","$atom","listener","i","index","oldValue","changedKey","runListenerQueue","newValue","unbind","_g","$globalActiveUser","$globalToken","$globalDeviceId","_SDKStorage","__publicField","createLogger","refs","activeUser","deviceId","storedUser","storedToken","storedDevice","watch","v","savedToken","savedDevice","savedUser","error","key","value","SDKStorage","_AgentClient","ctx","args","orgId","data","msg","agentId","onStatus","timeoutMs","pollIntervalMs","start","lastStatus","status","r","url","body","res","text","AgentClient","withLoadingState","fn","_AuthClient","email","err","errorMessage","code","origin","popupUrl","width","height","left","top","popup","handler","event","expectedOrigin","user","errorMsg","checkClosed","AuthClient","_BillingClient","_args","ACTIVE_STATUSES","BillingClient","KNOWN_EVENTS","parseChatEvent","frame","lines","l","name","payload","line","toChatMessage","message","_ChatClient","conversationId","errorSeen","assistantSeen","reader","errorBody","decoder","buffer","outer","done","sep","authHeaders","latestSequence","sendStarted","sendFailed","streamClosed","streamOpenTimedOut","streamAbort","streamReadySettled","streamReadyTimer","resolveStreamReady","streamReady","resolve","settleStreamReady","cancelReader","streamUrl","streamPromise","streamRes","clientNonce","shortId","ChatClient","_UserClient","storageKey","anonId","objectId","UserClient","_SDKGlobal","instance","SDKGlobal","sdkGlobal","_PageLinesSDK","SettingsObject","existing","ref","computed","a","agent","org","dirty","incomingDeviceId","PageLinesSDK"],"mappings":"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","x_google_ignoreList":[1,2]}
@@ -32,6 +32,7 @@ export declare class PLWidget {
32
32
  private sdk;
33
33
  private container;
34
34
  private static modalInstances;
35
+ static create(config: WidgetConfig): PLWidget;
35
36
  /**
36
37
  * Auto-collect page context from the current document.
37
38
  * Returns a concise summary string the agent can use to understand
@@ -34,8 +34,8 @@ export declare function useWidgetState(props: {
34
34
  quality?: "high" | "low" | "standard" | undefined;
35
35
  createdAt?: string | undefined;
36
36
  updatedAt?: string | undefined;
37
- type?: "image" | "audio" | "video" | "document" | undefined;
38
- mediaType?: "image" | "audio" | "video" | "document" | undefined;
37
+ type?: "audio" | "document" | "image" | "video" | undefined;
38
+ mediaType?: "audio" | "document" | "image" | "video" | undefined;
39
39
  className?: string | undefined;
40
40
  width?: number | undefined;
41
41
  height?: number | undefined;
@@ -57,8 +57,8 @@ export declare function useWidgetState(props: {
57
57
  quality?: "high" | "low" | "standard" | undefined;
58
58
  createdAt?: string | undefined;
59
59
  updatedAt?: string | undefined;
60
- type?: "image" | "audio" | "video" | "document" | undefined;
61
- mediaType?: "image" | "audio" | "video" | "document" | undefined;
60
+ type?: "audio" | "document" | "image" | "video" | undefined;
61
+ mediaType?: "audio" | "document" | "image" | "video" | undefined;
62
62
  className?: string | undefined;
63
63
  width?: number | undefined;
64
64
  height?: number | undefined;
@@ -72,12 +72,11 @@ export declare function useWidgetState(props: {
72
72
  handle: string;
73
73
  }[] | null | undefined;
74
74
  model?: string | null | undefined;
75
- lastActivityAt?: string | null | undefined;
75
+ lastActiveAt?: string | null | undefined;
76
76
  lastMessageAt?: string | null | undefined;
77
77
  instanceId?: string | null | undefined;
78
78
  instanceProvider?: string | null | undefined;
79
79
  imageVersion?: string | null | undefined;
80
- deployEnv?: string | undefined;
81
80
  runtime?: string | undefined;
82
81
  botServerUrl?: string | null | undefined;
83
82
  desiredStatus?: "active" | "stopped" | null | undefined;
@@ -98,6 +97,14 @@ export declare function useWidgetState(props: {
98
97
  liveStatus?: "error" | "stopped" | "unknown" | "running" | "starting" | "stopping" | "warming" | "never_started" | "unreachable" | "not-deployed" | undefined;
99
98
  sinceAt?: string | undefined;
100
99
  errorReason?: string | undefined;
100
+ blocker?: {
101
+ bucket: "error" | "account";
102
+ code: "billing_no_plan" | "billing_past_due" | "billing_runaway_cap" | "billing_budget_reached" | "agent_not_deployed" | "agent_boot_failed" | "agent_unreachable" | "agent_wake_timeout" | "stream_timeout" | "stream_disconnect" | "empty_stream" | "rate_limit";
103
+ title: string;
104
+ actionLabel: string;
105
+ actionUrl: string;
106
+ help?: string | undefined;
107
+ } | undefined;
101
108
  } | undefined, {
102
109
  agentId?: string | undefined;
103
110
  handle?: string | undefined;
@@ -125,8 +132,8 @@ export declare function useWidgetState(props: {
125
132
  quality?: "high" | "low" | "standard" | undefined;
126
133
  createdAt?: string | undefined;
127
134
  updatedAt?: string | undefined;
128
- type?: "image" | "audio" | "video" | "document" | undefined;
129
- mediaType?: "image" | "audio" | "video" | "document" | undefined;
135
+ type?: "audio" | "document" | "image" | "video" | undefined;
136
+ mediaType?: "audio" | "document" | "image" | "video" | undefined;
130
137
  className?: string | undefined;
131
138
  width?: number | undefined;
132
139
  height?: number | undefined;
@@ -148,8 +155,8 @@ export declare function useWidgetState(props: {
148
155
  quality?: "high" | "low" | "standard" | undefined;
149
156
  createdAt?: string | undefined;
150
157
  updatedAt?: string | undefined;
151
- type?: "image" | "audio" | "video" | "document" | undefined;
152
- mediaType?: "image" | "audio" | "video" | "document" | undefined;
158
+ type?: "audio" | "document" | "image" | "video" | undefined;
159
+ mediaType?: "audio" | "document" | "image" | "video" | undefined;
153
160
  className?: string | undefined;
154
161
  width?: number | undefined;
155
162
  height?: number | undefined;
@@ -163,12 +170,11 @@ export declare function useWidgetState(props: {
163
170
  handle: string;
164
171
  }[] | null | undefined;
165
172
  model?: string | null | undefined;
166
- lastActivityAt?: string | null | undefined;
173
+ lastActiveAt?: string | null | undefined;
167
174
  lastMessageAt?: string | null | undefined;
168
175
  instanceId?: string | null | undefined;
169
176
  instanceProvider?: string | null | undefined;
170
177
  imageVersion?: string | null | undefined;
171
- deployEnv?: string | undefined;
172
178
  runtime?: string | undefined;
173
179
  botServerUrl?: string | null | undefined;
174
180
  desiredStatus?: "active" | "stopped" | null | undefined;
@@ -189,6 +195,14 @@ export declare function useWidgetState(props: {
189
195
  liveStatus?: "error" | "stopped" | "unknown" | "running" | "starting" | "stopping" | "warming" | "never_started" | "unreachable" | "not-deployed" | undefined;
190
196
  sinceAt?: string | undefined;
191
197
  errorReason?: string | undefined;
198
+ blocker?: {
199
+ bucket: "error" | "account";
200
+ code: "billing_no_plan" | "billing_past_due" | "billing_runaway_cap" | "billing_budget_reached" | "agent_not_deployed" | "agent_boot_failed" | "agent_unreachable" | "agent_wake_timeout" | "stream_timeout" | "stream_disconnect" | "empty_stream" | "rate_limit";
201
+ title: string;
202
+ actionLabel: string;
203
+ actionUrl: string;
204
+ help?: string | undefined;
205
+ } | undefined;
192
206
  } | {
193
207
  agentId?: string | undefined;
194
208
  handle?: string | undefined;
@@ -216,8 +230,8 @@ export declare function useWidgetState(props: {
216
230
  quality?: "high" | "low" | "standard" | undefined;
217
231
  createdAt?: string | undefined;
218
232
  updatedAt?: string | undefined;
219
- type?: "image" | "audio" | "video" | "document" | undefined;
220
- mediaType?: "image" | "audio" | "video" | "document" | undefined;
233
+ type?: "audio" | "document" | "image" | "video" | undefined;
234
+ mediaType?: "audio" | "document" | "image" | "video" | undefined;
221
235
  className?: string | undefined;
222
236
  width?: number | undefined;
223
237
  height?: number | undefined;
@@ -239,8 +253,8 @@ export declare function useWidgetState(props: {
239
253
  quality?: "high" | "low" | "standard" | undefined;
240
254
  createdAt?: string | undefined;
241
255
  updatedAt?: string | undefined;
242
- type?: "image" | "audio" | "video" | "document" | undefined;
243
- mediaType?: "image" | "audio" | "video" | "document" | undefined;
256
+ type?: "audio" | "document" | "image" | "video" | undefined;
257
+ mediaType?: "audio" | "document" | "image" | "video" | undefined;
244
258
  className?: string | undefined;
245
259
  width?: number | undefined;
246
260
  height?: number | undefined;
@@ -254,12 +268,11 @@ export declare function useWidgetState(props: {
254
268
  handle: string;
255
269
  }[] | null | undefined;
256
270
  model?: string | null | undefined;
257
- lastActivityAt?: string | null | undefined;
271
+ lastActiveAt?: string | null | undefined;
258
272
  lastMessageAt?: string | null | undefined;
259
273
  instanceId?: string | null | undefined;
260
274
  instanceProvider?: string | null | undefined;
261
275
  imageVersion?: string | null | undefined;
262
- deployEnv?: string | undefined;
263
276
  runtime?: string | undefined;
264
277
  botServerUrl?: string | null | undefined;
265
278
  desiredStatus?: "active" | "stopped" | null | undefined;
@@ -280,6 +293,14 @@ export declare function useWidgetState(props: {
280
293
  liveStatus?: "error" | "stopped" | "unknown" | "running" | "starting" | "stopping" | "warming" | "never_started" | "unreachable" | "not-deployed" | undefined;
281
294
  sinceAt?: string | undefined;
282
295
  errorReason?: string | undefined;
296
+ blocker?: {
297
+ bucket: "error" | "account";
298
+ code: "billing_no_plan" | "billing_past_due" | "billing_runaway_cap" | "billing_budget_reached" | "agent_not_deployed" | "agent_boot_failed" | "agent_unreachable" | "agent_wake_timeout" | "stream_timeout" | "stream_disconnect" | "empty_stream" | "rate_limit";
299
+ title: string;
300
+ actionLabel: string;
301
+ actionUrl: string;
302
+ help?: string | undefined;
303
+ } | undefined;
283
304
  } | undefined>;
284
305
  currentContext: import('vue').Ref<string | undefined, string | undefined>;
285
306
  currentFirstMessage: import('vue').Ref<string | undefined, string | undefined>;