{"version":3,"sources":["../../../tools/browser/core.ts","../../../package.json","../../../version.ts","../../../tools/utils/resilience.ts","../../../logger.ts","../../../tools/browser/live.ts","../../../tools/browser/errors.ts","../../../tools/browser/profiles/types.ts","../../../tools/browser/profiles/core.ts","../../../core/error.ts","../../../core/client.ts","../../../core/resource.ts"],"sourcesContent":["/**\n * Core implementation for browser automation tasks\n */\n\nimport { fetchWithRetry, withTimeout } from '../utils/resilience.js';\nimport { logger } from '../../logger.js';\nimport type {\n  BrowserConfig,\n  BrowserTaskInput,\n  BrowserTaskInputWithSchema,\n  BrowserTaskResult,\n  BrowserTaskWithPromise,\n  BrowserTaskWithPromiseAndSchema,\n  RecordingStatus,\n  RecordingWithMethods,\n  ErrorsResponse,\n  LiveSessionOptions,\n  IframeOptions,\n  WebpOptions,\n  WebpResponse,\n} from './types.js';\nimport { buildLiveUrl, buildLiveIframe, buildEmbedCode, resolvePreset } from './live.js';\nimport { ProfilesClient } from './profiles/core.js';\nimport { MorphAPIClient } from '../../core/client.js';\nimport { APIResource } from '../../core/resource.js';\n\nconst DEFAULT_CONFIG = {\n  apiUrl: process.env.MORPH_ENVIRONMENT === 'DEV' \n    ? 'http://localhost:8000'\n    : 'https://browser.morphllm.com',\n  timeout: 1000000, // 10 minutes for complex tasks\n  debug: false,\n};\n\n/**\n * BrowserClient class for easier usage with instance configuration\n *\n * @deprecated Prefer the unified `MorphClient` (`new MorphClient({ apiKey }).browser`).\n * Standalone clients remain only for backwards compatibility and may be removed in a future\n * major version — do not use them in new code.\n */\nexport class BrowserClient extends APIResource {\n  private config: BrowserConfig;\n\n  /**\n   * Profile management - create and manage browser profiles for storing login state.\n   */\n  public profiles: ProfilesClient;\n\n  constructor(clientOrConfig: MorphAPIClient | BrowserConfig = {}) {\n    const isClient = clientOrConfig instanceof MorphAPIClient;\n    super(\n      isClient\n        ? clientOrConfig\n        : new MorphAPIClient({\n            apiKey: clientOrConfig.apiKey,\n            browserURL: clientOrConfig.apiUrl,\n            timeout: clientOrConfig.timeout,\n            retryConfig: clientOrConfig.retryConfig,\n            debug: clientOrConfig.debug,\n          }),\n    );\n    // Browser is a distinct service: keep its own wire (raw fetch in the\n    // module functions below) but source the host/key/retries from the shared\n    // transport so configuration lives in one place.\n    this.config = isClient\n      ? {\n          ...DEFAULT_CONFIG,\n          apiUrl: clientOrConfig.browserURL,\n          apiKey: clientOrConfig.resolveApiKey(),\n          retryConfig: clientOrConfig.retryConfig,\n          debug: clientOrConfig.debug,\n        }\n      : { ...DEFAULT_CONFIG, ...clientOrConfig };\n    this.profiles = new ProfilesClient(this.config);\n  }\n\n  /**\n   * Execute a browser automation task\n   */\n  async execute(input: BrowserTaskInput): Promise<BrowserTaskResult> {\n    return executeBrowserTask(input, this.config);\n  }\n\n  async createTask(input: BrowserTaskInput): Promise<BrowserTaskWithPromise>;\n  async createTask<T>(input: BrowserTaskInputWithSchema<T>): Promise<BrowserTaskWithPromiseAndSchema<T>>;\n  async createTask<T>(\n    input: BrowserTaskInput | BrowserTaskInputWithSchema<T>\n  ): Promise<BrowserTaskWithPromise | BrowserTaskWithPromiseAndSchema<T>> {\n    const apiUrl = this.config.apiUrl || DEFAULT_CONFIG.apiUrl;\n    const debug = this.config.debug || false;\n    \n    const hasTask = typeof input.task === 'string' && input.task.trim().length > 0;\n    const hasDiff = typeof (input as any).diff === 'string' && (input as any).diff.trim().length > 0;\n\n    if (!hasTask && !hasDiff) {\n      throw new Error('Browser task requires either \"task\" (natural language) or \"diff\" (PR-review planning)');\n    }\n\n    logger.debug('Browser', 'create_task', { task: (input.task ?? '').slice(0, 100), url: input.url, endpoint: `${apiUrl}/browser-task/async` });\n    \n    const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n    if (this.config.apiKey) headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n    \n    // Call ASYNC endpoint for immediate return with live URL\n    const response = await fetch(`${apiUrl}/browser-task/async`, {\n      method: 'POST',\n      headers,\n      body: JSON.stringify({\n        task: input.task,\n        diff: input.diff,\n        url: input.url,\n        max_steps: input.maxSteps ?? 10,\n        model: input.model ?? 'morph-computer-use-v0',\n        viewport_width: input.viewportWidth ?? 1280,\n        viewport_height: input.viewportHeight ?? 720,\n        external_id: input.externalId,\n        repo_id: input.repoId,\n        repo_full_name: input.repoFullName,\n        commit_id: input.commitId,\n        record_video: input.recordVideo ?? false,\n        video_width: input.videoWidth ?? input.viewportWidth ?? 1280,\n        video_height: input.videoHeight ?? input.viewportHeight ?? 720,\n        allow_resizing: input.allowResizing ?? false,\n        structured_output: 'schema' in input ? stringifyStructuredOutput(input.schema) : undefined,\n        auth: input.auth,\n        profile_id: input.profileId,\n        force_query_params: input.forceQueryParams,\n      }),\n    });\n\n    if (!response.ok) {\n      const errorText = await response.text().catch(() => response.statusText);\n      logger.error('Browser', 'create_task_error', { status: response.status, error: errorText });\n      throw new Error(`HTTP ${response.status}: ${errorText}`);\n    }\n\n    const result = mapTaskResult(await response.json());\n    logger.debug('Browser', 'task_created', { recording_id: result.recordingId, task_id: result.taskId, debug_url: !!result.debugUrl });\n    \n    if ('schema' in input) {\n      return wrapTaskResponseWithSchema(result, this.config, input.schema);\n    } else {\n      return wrapTaskResponse(result, this.config);\n    }\n  }\n\n  /**\n   * Execute task with recording and wait for video to be ready\n   */\n  async executeWithRecording(\n    input: BrowserTaskInput & { recordVideo: true }\n  ): Promise<BrowserTaskResult & { recording?: RecordingWithMethods }> {\n    return executeWithRecording(input, this.config);\n  }\n\n  /**\n   * Get recording status and URLs\n   */\n  async getRecording(recordingId: string): Promise<RecordingWithMethods> {\n    return getRecording(recordingId, this.config);\n  }\n\n  /**\n   * Wait for recording to complete with automatic polling\n   */\n  async waitForRecording(\n    recordingId: string,\n    options?: { timeout?: number; pollInterval?: number }\n  ): Promise<RecordingWithMethods> {\n    return waitForRecording(recordingId, this.config, options);\n  }\n\n  /**\n   * Get errors from recording with screenshots\n   */\n  async getErrors(recordingId: string): Promise<ErrorsResponse> {\n    return getErrors(recordingId, this.config);\n  }\n\n  /**\n   * Get animated WebP preview of recording\n   */\n  async getWebp(\n    recordingId: string,\n    options?: WebpOptions\n  ): Promise<WebpResponse> {\n    return getWebp(recordingId, this.config, options);\n  }\n\n  /**\n   * Check if browser worker service is healthy\n   */\n  async checkHealth(): Promise<{\n    ok: boolean;\n    google_configured: boolean;\n    database_configured: boolean;\n    s3_configured: boolean;\n    error?: string;\n  }> {\n    return checkHealth(this.config);\n  }\n}\n\n/**\n * Execute a natural language browser automation task\n * \n * Returns the full task result including rich agent history data (urls, errors, \n * action_history, judgement, etc.). When using this as an agent tool, use the\n * formatResult() functions from the SDK adapters to return a concise summary.\n * \n * @param input - Task parameters\n * @param config - Optional configuration (apiKey, apiUrl to override default)\n * @returns Task result with success status, findings, and comprehensive execution history\n * \n * @example\n * ```typescript\n * const result = await executeBrowserTask(\n *   {\n *     task: \"Test checkout flow for buying a pineapple\",\n *     url: \"https://3000-abc.e2b.dev\",\n *     maxSteps: 20,\n *     repoId: \"my-project\",\n *     commitId: \"uuid-here\"\n *   },\n *   {\n *     apiKey: process.env.MORPH_API_KEY,\n *     // apiUrl: 'http://localhost:8001' // Override for local testing\n *   }\n * );\n * \n * if (result.success) {\n *   console.log('Task completed:', result.result);\n *   console.log('URLs visited:', result.urls);\n *   console.log('Actions taken:', result.actionNames);\n *   console.log('Has errors:', result.hasErrors);\n *   console.log('Replay:', result.replayUrl);\n * }\n * ```\n */\nexport async function executeBrowserTask(\n  input: BrowserTaskInput,\n  config: BrowserConfig = {}\n): Promise<BrowserTaskResult> {\n  const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n  const timeout = config.timeout || DEFAULT_CONFIG.timeout;\n  const debug = config.debug || false;\n\n  if (!input.task || input.task.trim().length === 0) {\n    return { \n      success: false, \n      error: 'Task description is required. Example: \"Go to example.com and click the login button\"' \n    };\n  }\n\n  if (input.maxSteps !== undefined && (input.maxSteps < 1 || input.maxSteps > 50)) {\n    return { \n      success: false, \n      error: 'maxSteps must be between 1 and 50. Use more steps for complex multi-page flows.'\n    };\n  }\n\n  logger.debug('Browser', 'execute_start', { task: input.task.slice(0, 100), url: input.url, max_steps: input.maxSteps ?? 10, record_video: input.recordVideo ?? false });\n\n  const startTime = Date.now();\n\n  try {\n    const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n    if (config.apiKey) headers['Authorization'] = `Bearer ${config.apiKey}`;\n\n    const fetchPromise = fetchWithRetry(\n      `${apiUrl}/browser-task`,\n      {\n        method: 'POST',\n        headers,\n        body: JSON.stringify({\n          task: input.task,\n          url: input.url,\n          max_steps: input.maxSteps ?? 10,\n          model: input.model ?? 'morph-computer-use-v0',\n          viewport_width: input.viewportWidth ?? 1280,\n          viewport_height: input.viewportHeight ?? 720,\n          external_id: input.externalId,\n          repo_id: input.repoId,\n          commit_id: input.commitId,\n          record_video: input.recordVideo ?? false,\n          video_width: input.videoWidth ?? input.viewportWidth ?? 1280,\n          video_height: input.videoHeight ?? input.viewportHeight ?? 720,\n          allow_resizing: input.allowResizing ?? false,\n          structured_output: input.structuredOutput,\n          auth: input.auth,\n          profile_id: input.profileId,\n          force_query_params: input.forceQueryParams,\n        }),\n      },\n      config.retryConfig\n    );\n\n    const response = await withTimeout(\n      fetchPromise,\n      timeout,\n      `Browser task timed out after ${timeout}ms. Consider increasing timeout or reducing maxSteps.`\n    );\n\n    if (!response.ok) {\n      const errorText = await response.text().catch(() => response.statusText);\n      logger.error('Browser', 'execute_error', { status: response.status, error: errorText });\n      throw new Error(`HTTP ${response.status}: ${errorText}`);\n    }\n\n    const result: BrowserTaskResult = mapTaskResult(await response.json());\n    const elapsed = Date.now() - startTime;\n    logger.debug('Browser', 'execute_complete', { success: result.success, latency_ms: elapsed, steps: result.stepsTaken ?? 0, recording_id: result.recordingId });\n\n    return result;\n\n  } catch (error) {\n    if (error instanceof Error) {\n      // Handle network errors\n      if (error.message.includes('ECONNREFUSED') || error.message.includes('fetch failed')) {\n        return {\n          success: false,\n          error: `Cannot connect to browser worker at ${apiUrl}. Ensure the service is running and accessible. For local dev, set MORPH_ENVIRONMENT=DEV.`,\n        };\n      }\n\n      return {\n        success: false,\n        error: error.message,\n      };\n    }\n\n    return {\n      success: false,\n      error: String(error),\n    };\n  }\n}\n\n/**\n * Get recording status and video URL\n * \n * @param recordingId - Recording UUID from BrowserTaskResult\n * @param config - Configuration with apiKey\n * @returns Recording with convenience methods (.getWebp(), .getErrors())\n * \n * @example\n * ```typescript\n * const recording = await getRecording('uuid-here', { apiKey: 'key' });\n * \n * // Get animated WebP\n * const { webpUrl } = await recording.getWebp({ width: 780 });\n * \n * // Get errors with screenshots\n * const { errors } = await recording.getErrors();\n * ```\n */\nexport async function getRecording(\n  recordingId: string,\n  config: BrowserConfig = {}\n): Promise<RecordingWithMethods> {\n  const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n  const debug = config.debug || false;\n\n  if (!config.apiKey) {\n    throw new Error('API key required for getRecording');\n  }\n\n  if (debug) console.log(`[Browser] getRecording: ${recordingId}`);\n\n  const response = await fetch(`${apiUrl}/recordings/${recordingId}`, {\n    method: 'GET',\n    headers: { 'Authorization': `Bearer ${config.apiKey}` },\n  });\n\n  if (!response.ok) {\n    const errorText = await response.text().catch(() => response.statusText);\n    if (debug) console.error(`[Browser] getRecording error: ${response.status} - ${errorText}`);\n    throw new Error(`HTTP ${response.status}: ${errorText}`);\n  }\n\n  const data: RecordingStatus = mapRecordingStatus(await response.json());\n  if (debug) console.log(`[Browser] Recording status: ${data.status}`);\n\n  // Return recording with convenience methods\n  return {\n    ...data,\n    getWebp: (options?: WebpOptions) => getWebp(recordingId, config, options),\n    getErrors: () => getErrors(recordingId, config),\n  };\n}\n\n/**\n * Wait for recording to complete with automatic polling\n * \n * @param recordingId - Recording UUID\n * @param config - Configuration with apiKey\n * @param options - Polling options\n * @returns Recording status when completed or errored\n * \n * @example\n * ```typescript\n * const result = await executeBrowserTask({ task: '...', recordVideo: true }, config);\n * if (result.recordingId) {\n *   const recording = await waitForRecording(result.recordingId, config, {\n *     timeout: 60000,  // 1 minute\n *     pollInterval: 2000  // Check every 2 seconds\n *   });\n *   console.log('Video URL:', recording.videoUrl);\n * }\n * ```\n */\nexport async function waitForRecording(\n  recordingId: string,\n  config: BrowserConfig = {},\n  options: { timeout?: number; pollInterval?: number } = {}\n): Promise<RecordingWithMethods> {\n  const timeout = options.timeout ?? 60000; // Default 1 minute\n  const pollInterval = options.pollInterval ?? 2000; // Default 2 seconds\n  const startTime = Date.now();\n\n  while (Date.now() - startTime < timeout) {\n    const status = await getRecording(recordingId, config);\n    \n    if (status.status === 'COMPLETED' || status.status === 'ERROR') {\n      return status;\n    }\n\n    // Wait before next poll\n    await new Promise(resolve => setTimeout(resolve, pollInterval));\n  }\n\n  throw new Error(`Recording timeout after ${timeout}ms - status still pending`);\n}\n\n/**\n * Execute task with recording and wait for video to be ready\n * \n * @param input - Task parameters with recordVideo=true\n * @param config - Configuration with apiKey\n * @returns Task result with ready video URL\n * \n * @example\n * ```typescript\n * const result = await executeWithRecording(\n *   {\n *     task: \"Test checkout flow\",\n *     url: \"https://example.com\",\n *     recordVideo: true,\n *     repoId: \"my-project\"\n *   },\n *   { apiKey: process.env.MORPH_API_KEY }\n * );\n * \n * console.log('Task result:', result.result);\n * console.log('Video URL:', result.recording?.videoUrl);\n * ```\n */\nexport async function executeWithRecording(\n  input: BrowserTaskInput & { recordVideo: true },\n  config: BrowserConfig = {}\n): Promise<BrowserTaskResult & { recording?: RecordingWithMethods }> {\n  // Execute task with recording\n  const taskResult = await executeBrowserTask(input, config);\n\n  // If recording was created, wait for it to complete\n  if (taskResult.recordingId) {\n    try {\n      const recording = await waitForRecording(\n        taskResult.recordingId,\n        config,\n        { timeout: 60000, pollInterval: 2000 }\n      );\n      return {\n        ...taskResult,\n        recording,\n      };\n    } catch (error) {\n      // Return task result even if recording fails\n      // Still attach convenience methods for consistent API\n      const errorRecording: RecordingWithMethods = {\n        id: taskResult.recordingId,\n        status: 'ERROR',\n        error: error instanceof Error ? error.message : String(error),\n        createdAt: new Date().toISOString(),\n        getWebp: (options?: WebpOptions) => getWebp(taskResult.recordingId!, config, options),\n        getErrors: () => getErrors(taskResult.recordingId!, config),\n      };\n      return {\n        ...taskResult,\n        recording: errorRecording,\n      };\n    }\n  }\n\n  return taskResult;\n}\n\n/**\n * Get errors from recording with screenshots\n * \n * Screenshots are captured in real-time (500ms after error occurs) during the browser session.\n * \n * @param recordingId - Recording UUID from BrowserTaskResult\n * @param config - Configuration with apiKey\n * @returns Errors with real-time screenshots\n * \n * @example\n * ```typescript\n * const { errors, totalErrors } = await getErrors('uuid-here', { apiKey: 'key' });\n * \n * console.log(`Found ${totalErrors} errors`);\n * \n * errors.forEach(err => {\n *   console.log(`[${err.type}] ${err.message}`);\n *   if (err.url) console.log(`  URL: ${err.url}`);\n *   if (err.screenshotUrl) console.log(`  Screenshot: ${err.screenshotUrl}`);\n *   \n *   // Download screenshot\n *   if (err.screenshotUrl) {\n *     const response = await fetch(err.screenshotUrl);\n *     const screenshot = await response.arrayBuffer();\n *     // Save or process screenshot\n *   }\n * });\n * ```\n */\nexport async function getErrors(\n  recordingId: string,\n  config: BrowserConfig = {}\n): Promise<ErrorsResponse> {\n  const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n  const debug = config.debug || false;\n\n  if (!config.apiKey) {\n    throw new Error('API key required for getErrors');\n  }\n\n  if (debug) console.log(`[Browser] getErrors: ${recordingId}`);\n\n  const response = await fetch(`${apiUrl}/recordings/${recordingId}/errors`, {\n    method: 'GET',\n    headers: { 'Authorization': `Bearer ${config.apiKey}` },\n  });\n\n  if (!response.ok) {\n    const errorText = await response.text().catch(() => response.statusText);\n    if (debug) console.error(`[Browser] getErrors error: ${response.status} - ${errorText}`);\n    throw new Error(`HTTP ${response.status}: ${errorText}`);\n  }\n\n  const errors = mapErrorsResponse(await response.json());\n  if (debug) console.log(`[Browser] Found ${errors.totalErrors} errors`);\n\n  return errors;\n}\n\n/**\n * Helper to serialize Zod schema for API\n */\nfunction stringifyStructuredOutput(schema: any): string {\n  try {\n    return JSON.stringify({\n      type: 'object',\n      description: 'Zod schema definition (Zod v3)',\n      zodDef: schema._def,\n    });\n  } catch (error) {\n    console.warn('[Browser] Failed to serialize Zod schema:', error);\n    return JSON.stringify({\n      type: 'object',\n      description: 'Schema serialization failed',\n    });\n  }\n}\n\n/**\n * Parse and validate structured task output\n */\nfunction parseStructuredTaskOutput<T>(\n  result: BrowserTaskResult,\n  schema: any\n): BrowserTaskResult & { parsed: T | null } {\n  if (!result.output) {\n    return { ...result, parsed: null };\n  }\n\n  try {\n    const parsed = JSON.parse(result.output);\n    const validated = schema.parse(parsed) as T;\n    return { ...result, parsed: validated };\n  } catch (error) {\n    if (error instanceof SyntaxError) {\n      return { ...result, parsed: null };\n    }\n    throw error;\n  }\n}\n\nfunction mapTaskResult(api: any): BrowserTaskResult {\n  if (!api || typeof api !== 'object') {\n    return api as BrowserTaskResult;\n  }\n\n  return {\n    success: api.success,\n    result: api.result,\n    error: api.error,\n    stepsTaken: api.steps_taken,\n    executionTimeMs: api.execution_time_ms,\n    urls: api.urls,\n    actionNames: api.action_names,\n    errors: api.errors,\n    modelActions: api.model_actions,\n    isDone: api.is_done,\n    actionHistory: api.action_history,\n    actionResults: api.action_results,\n    hasErrors: api.has_errors,\n    numberOfSteps: api.number_of_steps,\n    judgement: api.judgement,\n    isValidated: api.is_validated,\n    replayId: api.replay_id,\n    replayUrl: api.replay_url,\n    recordingId: api.recording_id,\n    recordingStatus: api.recording_status,\n    taskId: api.task_id,\n    status: api.status,\n    output: api.output,\n    debugUrl: api.debug_url,\n  };\n}\n\nfunction mapRecordingStatus(api: any): RecordingStatus {\n  return {\n    id: api.id,\n    status: api.status,\n    replayUrl: api.replay_url,\n    networkUrl: api.network_url,\n    consoleUrl: api.console_url,\n    videoUrl: api.video_url,\n    result: api.result,\n    totalEvents: api.total_events,\n    fileSize: api.file_size,\n    duration: api.duration,\n    error: api.error,\n    createdAt: api.created_at,\n  };\n}\n\nfunction mapBrowserError(api: any): ErrorsResponse['errors'][number] {\n  return {\n    type: api.type,\n    message: api.message,\n    url: api.url,\n    timestamp: api.timestamp,\n    screenshotUrl: api.screenshot_url,\n    capturedAt: api.captured_at,\n    status: api.status,\n  };\n}\n\nfunction mapErrorsResponse(api: any): ErrorsResponse {\n  return {\n    recordingId: api.recording_id,\n    totalErrors: api.total_errors,\n    errors: Array.isArray(api.errors) ? api.errors.map(mapBrowserError) : [],\n  };\n}\n\nfunction mapWebpResponse(api: any): WebpResponse {\n  return {\n    webpUrl: api.webp_url,\n    cached: api.cached,\n    width: api.width,\n    fps: api.fps,\n    maxDuration: api.max_duration,\n    fileSize: api.file_size,\n    maxSizeMb: api.max_size_mb,\n    budgetMet: api.budget_met,\n    qualityUsed: api.quality_used,\n    attempts: api.attempts,\n  };\n}\n\n/**\n * Get current task status\n */\nasync function getTaskStatus(\n  taskId: string,\n  config: BrowserConfig\n): Promise<BrowserTaskResult> {\n  const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n  const debug = config.debug || false;\n\n  if (debug) console.log(`[Browser] getTaskStatus: ${taskId}`);\n\n  const headers: Record<string, string> = {};\n  if (config.apiKey) headers['Authorization'] = `Bearer ${config.apiKey}`;\n\n  const response = await fetch(`${apiUrl}/tasks/${taskId}`, {\n    method: 'GET',\n    headers,\n  });\n\n  if (!response.ok) {\n    const errorText = await response.text().catch(() => response.statusText);\n    if (debug) console.error(`[Browser] getTaskStatus error: ${response.status} - ${errorText}`);\n    throw new Error(`HTTP ${response.status}: ${errorText}`);\n  }\n\n  const result: BrowserTaskResult = mapTaskResult(await response.json());\n  if (debug) console.log(`[Browser] Task status: ${result.status}`);\n\n  return result;\n}\n\n/**\n * Generate live URL for watching task execution in real-time\n */\nfunction generateLiveUrl(taskId: string, config: BrowserConfig): string {\n  const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n  const baseUrl = apiUrl.replace('/api', '');\n  return `${baseUrl}/tasks/${taskId}/live`;\n}\n\n/**\n * Poll task until completion\n */\nasync function pollTaskUntilComplete(\n  taskId: string,\n  config: BrowserConfig,\n  pollConfig: { interval?: number; timeout?: number } = {}\n): Promise<BrowserTaskResult> {\n  const interval = pollConfig.interval ?? 2000; // 2 seconds\n  const timeout = pollConfig.timeout ?? 300000; // 5 minutes\n  const startTime = Date.now();\n\n  while (Date.now() - startTime < timeout) {\n    const status = await getTaskStatus(taskId, config);\n    \n    if (status.status === 'completed' || status.status === 'failed') {\n      return status;\n    }\n\n    await new Promise(resolve => setTimeout(resolve, interval));\n  }\n\n  throw new Error(`Task polling timeout after ${timeout}ms`);\n}\n\n/**\n * Wrap task response with convenience methods\n */\nfunction wrapTaskResponse(\n  result: BrowserTaskResult,\n  config: BrowserConfig\n): BrowserTaskWithPromise {\n  const debugUrl = result.debugUrl ?? '';\n\n  const wrapped: BrowserTaskWithPromise = {\n    ...result,\n    debugUrl,\n    taskId: result.taskId || '',\n    liveUrl: result.taskId\n      ? generateLiveUrl(result.taskId, config)\n      : debugUrl,\n    complete: async (pollConfig?: { interval?: number; timeout?: number }) => {\n      // If we have a taskId, poll task status endpoint\n      if (result.taskId) {\n        return pollTaskUntilComplete(result.taskId!, config, pollConfig);\n      }\n      // If we have a recordingId, poll recording status instead\n      if (result.recordingId) {\n        const recording = await waitForRecording(\n          result.recordingId,\n          config,\n          pollConfig\n        );\n        // Return a result-like object (recording doesn't have full task result)\n        return {\n          ...result,\n          recordingStatus: recording.status,\n        } as BrowserTaskResult;\n      }\n      // No way to poll completion\n      throw new Error('Cannot poll completion: no taskId or recordingId available');\n    },\n    // Add Steel live session helpers - either functional or error-throwing\n    getLiveUrl: debugUrl\n      ? (options?: LiveSessionOptions) => buildLiveUrl(debugUrl, options)\n      : () => {\n          throw new Error(\n            'Live sessions not available. Your backend must return a debugUrl in the response. Contact support@morphllm.com if you need help.'\n          );\n        },\n    getLiveIframe: debugUrl\n      ? (optionsOrPreset?: string | IframeOptions) => {\n          const options = resolvePreset(optionsOrPreset);\n          return buildLiveIframe(debugUrl, options);\n        }\n      : () => {\n          throw new Error(\n            'Live sessions not available. Your backend must return a debugUrl in the response. Contact support@morphllm.com if you need help.'\n          );\n        },\n    getEmbedCode: debugUrl\n      ? () => buildEmbedCode(debugUrl)\n      : () => {\n          throw new Error(\n            'Live sessions not available. Your backend must return a debugUrl in the response. Contact support@morphllm.com if you need help.'\n          );\n        },\n  };\n\n  return wrapped;\n}\n\n/**\n * Wrap task response with schema validation\n */\nfunction wrapTaskResponseWithSchema<T>(\n  result: BrowserTaskResult,\n  config: BrowserConfig,\n  schema: any\n): BrowserTaskWithPromiseAndSchema<T> {\n  const debugUrl = result.debugUrl ?? '';\n  const parsed = result.output\n    ? parseStructuredTaskOutput<T>(result, schema)\n    : { ...result, parsed: null };\n\n  const wrapped: BrowserTaskWithPromiseAndSchema<T> = {\n    ...parsed,\n    debugUrl,\n    taskId: result.taskId || '',\n    liveUrl: result.taskId\n      ? generateLiveUrl(result.taskId, config)\n      : debugUrl,\n    complete: async (pollConfig?: { interval?: number; timeout?: number }) => {\n      // If we have a taskId, poll task status endpoint\n      if (result.taskId) {\n        const finalResult = await pollTaskUntilComplete(result.taskId!, config, pollConfig);\n        return parseStructuredTaskOutput<T>(finalResult, schema);\n      }\n      // If we have a recordingId, poll recording status instead\n      if (result.recordingId) {\n        const recording = await waitForRecording(\n          result.recordingId,\n          config,\n          pollConfig\n        );\n        // Return parsed result (recording doesn't have task output)\n        return {\n          ...parsed,\n          recordingStatus: recording.status,\n        };\n      }\n      // No way to poll completion\n      throw new Error('Cannot poll completion: no taskId or recordingId available');\n    },\n    // Add Steel live session helpers - either functional or error-throwing\n    getLiveUrl: debugUrl\n      ? (options?: LiveSessionOptions) => buildLiveUrl(debugUrl, options)\n      : () => {\n          throw new Error(\n            'Live sessions not available. Your backend must return a debugUrl in the response. ' +\n            'Contact support@morphllm.com if you need help enabling live sessions. '\n          );\n        },\n    getLiveIframe: debugUrl\n      ? (optionsOrPreset?: string | IframeOptions) => {\n          const options = resolvePreset(optionsOrPreset);\n          return buildLiveIframe(debugUrl, options);\n        }\n      : () => {\n          throw new Error(\n            'Live sessions not available. Your backend must return a debugUrl in the response. ' +\n            'Contact support@morphllm.com if you need help enabling live sessions.'\n          );\n        },\n    getEmbedCode: debugUrl\n      ? () => buildEmbedCode(debugUrl)\n      : () => {\n          throw new Error(\n            'Live sessions not available. Your backend must return a debugUrl in the response. ' +\n            'Contact support@morphllm.com if you need help enabling live sessions.'\n          );\n        },\n  };\n\n  return wrapped;\n}\n\n/**\n * Get animated WebP preview of recording\n * \n * Converts the native video recording to an animated WebP. Results are cached in S3.\n * \n * @param recordingId - Recording UUID from BrowserTaskResult\n * @param config - Configuration with apiKey\n * @param options - WebP generation options\n * @returns WebP URL and metadata\n * \n * @example\n * ```typescript\n * const webp = await getWebp('uuid-here', { apiKey: 'key' }, {\n *   width: 780,\n *   fps: 10,\n *   quality: 65,\n *   maxDuration: 15\n * });\n * console.log('WebP URL:', webp.webpUrl);\n * console.log('From cache:', webp.cached);\n * ```\n */\nexport async function getWebp(\n  recordingId: string,\n  config: BrowserConfig = {},\n  options: WebpOptions = {}\n): Promise<WebpResponse> {\n  const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n  const debug = config.debug || false;\n\n  if (!config.apiKey) {\n    throw new Error('API key required for getWebp');\n  }\n\n  // Build query params\n  const params = new URLSearchParams();\n  if (options.maxDuration !== undefined) params.set('max_duration', String(options.maxDuration));\n  if (options.fps !== undefined) params.set('fps', String(options.fps));\n  if (options.width !== undefined) params.set('width', String(options.width));\n  if (options.quality !== undefined) params.set('quality', String(options.quality));\n  if (options.maxSizeMb !== undefined) params.set('max_size_mb', String(options.maxSizeMb));\n\n  const url = `${apiUrl}/recordings/${recordingId}/webp${params.toString() ? '?' + params.toString() : ''}`;\n  \n  if (debug) console.log(`[Browser] getWebp: ${url}`);\n\n  const response = await fetch(url, {\n    method: 'GET',\n    headers: { 'Authorization': `Bearer ${config.apiKey}` },\n  });\n\n  if (!response.ok) {\n    const errorText = await response.text().catch(() => response.statusText);\n    if (debug) console.error(`[Browser] getWebp error: ${response.status} - ${errorText}`);\n    throw new Error(`HTTP ${response.status}: ${errorText}`);\n  }\n\n  const result = mapWebpResponse(await response.json());\n  if (debug) console.log(`[Browser] WebP ready: ${result.webpUrl} (cached: ${result.cached})`);\n\n  return result;\n}\n\n/**\n * Check if browser worker service is healthy\n * \n * @param config - Optional configuration\n * @returns Health status\n */\nexport async function checkHealth(config: BrowserConfig = {}): Promise<{\n  ok: boolean;\n  google_configured: boolean;\n  database_configured: boolean;\n  s3_configured: boolean;\n  error?: string;\n}> {\n  const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n\n  try {\n    const response = await fetch(`${apiUrl}/health`, {\n      method: 'GET',\n      headers: config.apiKey\n        ? { 'Authorization': `Bearer ${config.apiKey}` }\n        : {},\n    });\n\n    if (!response.ok) {\n      throw new Error(`HTTP ${response.status}`);\n    }\n\n    const data = await response.json();\n    return {\n      ok: true,\n      google_configured: data.google_configured ?? false,\n      database_configured: data.database_configured ?? false,\n      s3_configured: data.s3_configured ?? false,\n    };\n  } catch (error) {\n    return {\n      ok: false,\n      google_configured: false,\n      database_configured: false,\n      s3_configured: false,\n      error: error instanceof Error ? error.message : String(error),\n    };\n  }\n}\n","{\n  \"name\": \"@morphllm/morphsdk\",\n  \"version\": \"0.2.194\",\n  \"description\": \"TypeScript SDK and CLI for Morph Fast Apply integration\",\n  \"type\": \"module\",\n  \"main\": \"./dist/index.cjs\",\n  \"module\": \"./dist/index.js\",\n  \"types\": \"./dist/index.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"types\": \"./dist/index.d.ts\",\n      \"import\": \"./dist/index.js\",\n      \"require\": \"./dist/index.cjs\"\n    },\n    \"./logger\": {\n      \"types\": \"./dist/logger.d.ts\",\n      \"import\": \"./dist/logger.js\",\n      \"require\": \"./dist/logger.cjs\"\n    },\n    \"./edge\": {\n      \"types\": \"./dist/edge.d.ts\",\n      \"import\": \"./dist/edge.js\",\n      \"require\": \"./dist/edge.cjs\"\n    },\n    \"./tools/warp-grep\": {\n      \"types\": \"./dist/tools/warp_grep/index.d.ts\",\n      \"import\": \"./dist/tools/warp_grep/index.js\",\n      \"require\": \"./dist/tools/warp_grep/index.cjs\"\n    },\n    \"./tools/warp-grep/openai\": {\n      \"types\": \"./dist/tools/warp_grep/openai.d.ts\",\n      \"import\": \"./dist/tools/warp_grep/openai.js\",\n      \"require\": \"./dist/tools/warp_grep/openai.cjs\"\n    },\n    \"./tools/warp-grep/anthropic\": {\n      \"types\": \"./dist/tools/warp_grep/anthropic.d.ts\",\n      \"import\": \"./dist/tools/warp_grep/anthropic.js\",\n      \"require\": \"./dist/tools/warp_grep/anthropic.cjs\"\n    },\n    \"./tools/warp-grep/vercel\": {\n      \"types\": \"./dist/tools/warp_grep/vercel.d.ts\",\n      \"import\": \"./dist/tools/warp_grep/vercel.js\",\n      \"require\": \"./dist/tools/warp_grep/vercel.cjs\"\n    },\n    \"./tools/warp-grep/client\": {\n      \"types\": \"./dist/tools/warp_grep/client.d.ts\",\n      \"import\": \"./dist/tools/warp_grep/client.js\",\n      \"require\": \"./dist/tools/warp_grep/client.cjs\"\n    },\n    \"./tools/warp-grep/gemini\": {\n      \"types\": \"./dist/tools/warp_grep/gemini.d.ts\",\n      \"import\": \"./dist/tools/warp_grep/gemini.js\",\n      \"require\": \"./dist/tools/warp_grep/gemini.cjs\"\n    },\n    \"./tools/warp-grep/harness\": {\n      \"types\": \"./dist/tools/warp_grep/harness.d.ts\",\n      \"import\": \"./dist/tools/warp_grep/harness.js\",\n      \"require\": \"./dist/tools/warp_grep/harness.cjs\"\n    },\n    \"./tracing\": {\n      \"types\": \"./dist/tracing/index.d.ts\",\n      \"import\": \"./dist/tracing/index.js\",\n      \"require\": \"./dist/tracing/index.cjs\"\n    },\n    \"./tracing/otel\": {\n      \"types\": \"./dist/tracing/otel.d.ts\",\n      \"import\": \"./dist/tracing/otel.js\",\n      \"require\": \"./dist/tracing/otel.cjs\"\n    },\n    \"./tools/fastapply\": {\n      \"types\": \"./dist/tools/fastapply/index.d.ts\",\n      \"import\": \"./dist/tools/fastapply/index.js\",\n      \"require\": \"./dist/tools/fastapply/index.cjs\"\n    },\n    \"./tools/fastapply/anthropic\": {\n      \"types\": \"./dist/tools/fastapply/anthropic.d.ts\",\n      \"import\": \"./dist/tools/fastapply/anthropic.js\",\n      \"require\": \"./dist/tools/fastapply/anthropic.cjs\"\n    },\n    \"./tools/fastapply/openai\": {\n      \"types\": \"./dist/tools/fastapply/openai.d.ts\",\n      \"import\": \"./dist/tools/fastapply/openai.js\",\n      \"require\": \"./dist/tools/fastapply/openai.cjs\"\n    },\n    \"./tools/fastapply/vercel\": {\n      \"types\": \"./dist/tools/fastapply/vercel.d.ts\",\n      \"import\": \"./dist/tools/fastapply/vercel.js\",\n      \"require\": \"./dist/tools/fastapply/vercel.cjs\"\n    },\n    \"./tools/codebase-search\": {\n      \"types\": \"./dist/tools/codebase_search/index.d.ts\",\n      \"import\": \"./dist/tools/codebase_search/index.js\",\n      \"require\": \"./dist/tools/codebase_search/index.cjs\"\n    },\n    \"./tools/codebase-search/anthropic\": {\n      \"types\": \"./dist/tools/codebase_search/anthropic.d.ts\",\n      \"import\": \"./dist/tools/codebase_search/anthropic.js\",\n      \"require\": \"./dist/tools/codebase_search/anthropic.cjs\"\n    },\n    \"./tools/codebase-search/openai\": {\n      \"types\": \"./dist/tools/codebase_search/openai.d.ts\",\n      \"import\": \"./dist/tools/codebase_search/openai.js\",\n      \"require\": \"./dist/tools/codebase_search/openai.cjs\"\n    },\n    \"./tools/codebase-search/vercel\": {\n      \"types\": \"./dist/tools/codebase_search/vercel.d.ts\",\n      \"import\": \"./dist/tools/codebase_search/vercel.js\",\n      \"require\": \"./dist/tools/codebase_search/vercel.cjs\"\n    },\n    \"./tools/git\": {\n      \"types\": \"./dist/git/index.d.ts\",\n      \"import\": \"./dist/git/index.js\",\n      \"require\": \"./dist/git/index.cjs\"\n    },\n    \"./tools/browser\": {\n      \"types\": \"./dist/tools/browser/index.d.ts\",\n      \"import\": \"./dist/tools/browser/index.js\",\n      \"require\": \"./dist/tools/browser/index.cjs\"\n    },\n    \"./tools/browser/anthropic\": {\n      \"types\": \"./dist/tools/browser/anthropic.d.ts\",\n      \"import\": \"./dist/tools/browser/anthropic.js\",\n      \"require\": \"./dist/tools/browser/anthropic.cjs\"\n    },\n    \"./tools/browser/openai\": {\n      \"types\": \"./dist/tools/browser/openai.d.ts\",\n      \"import\": \"./dist/tools/browser/openai.js\",\n      \"require\": \"./dist/tools/browser/openai.cjs\"\n    },\n    \"./tools/browser/vercel\": {\n      \"types\": \"./dist/tools/browser/vercel.d.ts\",\n      \"import\": \"./dist/tools/browser/vercel.js\",\n      \"require\": \"./dist/tools/browser/vercel.cjs\"\n    },\n    \"./tools/browser/profiles\": {\n      \"types\": \"./dist/tools/browser/profiles/index.d.ts\",\n      \"import\": \"./dist/tools/browser/profiles/index.js\",\n      \"require\": \"./dist/tools/browser/profiles/index.cjs\"\n    },\n    \"./modelrouter\": {\n      \"types\": \"./dist/modelrouter/index.d.ts\",\n      \"import\": \"./dist/modelrouter/index.js\",\n      \"require\": \"./dist/modelrouter/index.cjs\"\n    },\n    \"./tools/compact\": {\n      \"types\": \"./dist/tools/compact/index.d.ts\",\n      \"import\": \"./dist/tools/compact/index.js\",\n      \"require\": \"./dist/tools/compact/index.cjs\"\n    },\n    \"./tools/reflex\": {\n      \"types\": \"./dist/tools/reflex/index.d.ts\",\n      \"import\": \"./dist/tools/reflex/index.js\",\n      \"require\": \"./dist/tools/reflex/index.cjs\"\n    },\n    \"./tools/traces\": {\n      \"types\": \"./dist/tools/traces/index.d.ts\",\n      \"import\": \"./dist/tools/traces/index.js\",\n      \"require\": \"./dist/tools/traces/index.cjs\"\n    },\n    \"./subagents\": {\n      \"types\": \"./dist/subagents/index.d.ts\",\n      \"import\": \"./dist/subagents/index.js\",\n      \"require\": \"./dist/subagents/index.cjs\"\n    },\n    \"./subagents/vercel\": {\n      \"types\": \"./dist/subagents/vercel.d.ts\",\n      \"import\": \"./dist/subagents/vercel.js\",\n      \"require\": \"./dist/subagents/vercel.cjs\"\n    },\n    \"./subagents/anthropic\": {\n      \"types\": \"./dist/subagents/anthropic.d.ts\",\n      \"import\": \"./dist/subagents/anthropic.js\",\n      \"require\": \"./dist/subagents/anthropic.cjs\"\n    }\n  },\n  \"files\": [\n    \"dist/**/*.js\",\n    \"dist/**/*.cjs\",\n    \"dist/**/*.d.ts\",\n    \"dist/**/*.map\",\n    \"!dist/**/__tests__/**\",\n    \"!dist/**/*.test.*\"\n  ],\n  \"scripts\": {\n    \"build\": \"tsup version.ts index.ts edge.ts client.ts core/index.ts core/client.ts core/resource.ts core/error.ts tools/index.ts tools/fastapply/index.ts tools/fastapply/core.ts tools/fastapply/apply.ts tools/fastapply/types.ts tools/fastapply/prompts.ts tools/fastapply/anthropic.ts tools/fastapply/openai.ts tools/fastapply/vercel.ts tools/codebase_search/index.ts tools/codebase_search/core.ts tools/codebase_search/types.ts tools/codebase_search/prompts.ts tools/codebase_search/anthropic.ts tools/codebase_search/openai.ts tools/codebase_search/vercel.ts tools/warp_grep/index.ts tools/warp_grep/client.ts tools/warp_grep/openai.ts tools/warp_grep/anthropic.ts tools/warp_grep/vercel.ts tools/warp_grep/gemini.ts tools/warp_grep/harness.ts tools/warp_grep/agent/config.ts tools/warp_grep/agent/parser.ts tools/warp_grep/agent/runner.ts tools/warp_grep/agent/types.ts tools/warp_grep/agent/formatter.ts tools/warp_grep/providers/types.ts tools/warp_grep/providers/local.ts tools/warp_grep/providers/remote.ts tools/warp_grep/providers/code_storage_http.ts tools/warp_grep/tools/grep.ts tools/warp_grep/tools/analyse.ts tools/warp_grep/tools/read.ts tools/warp_grep/tools/finish.ts tools/warp_grep/utils/paths.ts tools/warp_grep/utils/github.ts tools/warp_grep/utils/ripgrep.ts tools/warp_grep/utils/format.ts tools/warp_grep/utils/files.ts git/index.ts git/client.ts git/config.ts git/types.ts tools/browser/index.ts tools/browser/core.ts tools/browser/types.ts tools/browser/prompts.ts tools/browser/anthropic.ts tools/browser/openai.ts tools/browser/vercel.ts tools/browser/live.ts tools/browser/errors.ts tools/browser/profiles/index.ts tools/browser/profiles/core.ts tools/browser/profiles/types.ts modelrouter/index.ts modelrouter/core.ts modelrouter/types.ts tools/compact/index.ts tools/compact/core.ts tools/compact/types.ts tools/reflex/index.ts tools/reflex/core.ts tools/reflex/types.ts tools/traces/index.ts tools/traces/core.ts tools/traces/types.ts tools/utils/resilience.ts subagents/index.ts subagents/types.ts subagents/prompts.ts subagents/vercel.ts subagents/anthropic.ts tracing/index.ts tracing/core.ts tracing/interaction.ts tracing/otel.ts tracing/types.ts --format esm,cjs --sourcemap --clean --dts --dts-resolve\",\n    \"prepare\": \"npm run build\",\n    \"typecheck\": \"tsc --noEmit\",\n    \"lint\": \"eslint .\",\n    \"test\": \"vitest run\",\n    \"test:watch\": \"vitest watch\",\n    \"test:anthropic\": \"vitest run anthropic\",\n    \"test:openai\": \"vitest run openai\",\n    \"test:vercel\": \"vitest run vercel\",\n    \"test:git\": \"vitest run git\",\n    \"test:browser\": \"vitest run browser\",\n    \"test:agent\": \"npx tsx tests/fullAgentTest.ts\",\n    \"test:integration\": \"npx tsx tests/fullIntegrationTest.ts\",\n    \"test:e2e\": \"vitest run --config vitest.e2e.config.ts\",\n    \"release:patch\": \"npm version patch && npm publish\",\n    \"release:minor\": \"npm version minor && npm publish\",\n    \"release:major\": \"npm version major && npm publish\"\n  },\n  \"keywords\": [\n    \"morph\",\n    \"fast-apply\",\n    \"cli\",\n    \"sdk\",\n    \"edit-file\"\n  ],\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"@opentelemetry/api\": \"^1.9.0\",\n    \"@opentelemetry/exporter-trace-otlp-http\": \"^0.203.0\",\n    \"@opentelemetry/sdk-trace-base\": \"^2.7.1\",\n    \"@traceloop/node-server-sdk\": \"^0.27.0\",\n    \"@vscode/ripgrep\": \"^1.17.0\",\n    \"ai\": \">=5.0.0\",\n    \"diff\": \"^7.0.0\",\n    \"isomorphic-git\": \"^1.25.10\",\n    \"openai\": \"^4.52.7\",\n    \"zod\": \">=3.23.0\"\n  },\n  \"devDependencies\": {\n    \"@ai-sdk/anthropic\": \"^2.0.70\",\n    \"@ai-sdk/openai\": \"^2.0.35\",\n    \"@anthropic-ai/sdk\": \"^0.30.1\",\n    \"@google/generative-ai\": \"^0.24.1\",\n    \"@types/diff\": \"^7.0.2\",\n    \"@types/node\": \"^20.14.10\",\n    \"@typescript-eslint/eslint-plugin\": \"^7.18.0\",\n    \"@typescript-eslint/parser\": \"^7.18.0\",\n    \"dotenv\": \"^16.4.5\",\n    \"eslint\": \"^8.57.0\",\n    \"shx\": \"^0.3.4\",\n    \"tsup\": \"^8.5.0\",\n    \"tsx\": \"^4.16.2\",\n    \"typescript\": \"^5.5.4\",\n    \"vitest\": \"^2.1.6\"\n  },\n  \"peerDependencies\": {\n    \"@anthropic-ai/sdk\": \">=0.25.0\",\n    \"@google/generative-ai\": \">=0.21.0\",\n    \"ai\": \">=5.0.0\",\n    \"zod\": \">=3.23.0\"\n  },\n  \"peerDependenciesMeta\": {\n    \"@anthropic-ai/sdk\": {\n      \"optional\": true\n    },\n    \"@google/generative-ai\": {\n      \"optional\": true\n    },\n    \"ai\": {\n      \"optional\": true\n    },\n    \"zod\": {\n      \"optional\": true\n    }\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  }\n}\n","import pkg from './package.json' with { type: 'json' };\nexport const SDK_VERSION: string = pkg.version;\n","/**\n * Resilience utilities for retry logic and timeout handling\n */\n\nimport { SDK_VERSION } from '../../version.js';\n\nexport interface RetryConfig {\n  maxRetries?: number;        // Default: 3\n  initialDelay?: number;      // Default: 1000ms\n  maxDelay?: number;          // Default: 30000ms\n  backoffMultiplier?: number; // Default: 2\n  retryableErrors?: string[]; // Default: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND']\n  onRetry?: (attempt: number, error: Error) => void;\n}\n\nconst DEFAULT_RETRY_CONFIG: Required<Omit<RetryConfig, 'onRetry'>> = {\n  maxRetries: 3,\n  initialDelay: 1000,\n  maxDelay: 30000,\n  backoffMultiplier: 2,\n  retryableErrors: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND'],\n};\n\n/**\n * Retry a fetch request with exponential backoff\n * \n * @param url - Request URL\n * @param options - Fetch options\n * @param retryConfig - Retry configuration\n * @returns Response from fetch\n * \n * @example\n * ```typescript\n * const response = await fetchWithRetry(\n *   'https://api.example.com/data',\n *   { method: 'POST', body: JSON.stringify(data) },\n *   { maxRetries: 5, initialDelay: 500 }\n * );\n * ```\n */\nexport async function fetchWithRetry(\n  url: string,\n  options: RequestInit,\n  retryConfig: RetryConfig = {}\n): Promise<Response> {\n  const {\n    maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,\n    initialDelay = DEFAULT_RETRY_CONFIG.initialDelay,\n    maxDelay = DEFAULT_RETRY_CONFIG.maxDelay,\n    backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,\n    retryableErrors = DEFAULT_RETRY_CONFIG.retryableErrors,\n    onRetry,\n  } = retryConfig;\n\n  let lastError: Error | null = null;\n  let delay = initialDelay;\n\n  // Inject SDK version header (caller-provided headers can override)\n  options = { ...options, headers: { 'X-Morph-SDK-Version': SDK_VERSION, ...options.headers } };\n\n  for (let attempt = 0; attempt <= maxRetries; attempt++) {\n    try {\n      const response = await fetch(url, options);\n      \n      // Retry on 429 (rate limit) or 503 (service unavailable)\n      if (response.status === 429 || response.status === 503) {\n        if (attempt < maxRetries) {\n          // Check for Retry-After header\n          const retryAfter = response.headers.get('Retry-After');\n          const waitTime = retryAfter \n            ? parseInt(retryAfter) * 1000 \n            : Math.min(delay, maxDelay);\n          \n          const error = new Error(`HTTP ${response.status}: Retrying after ${waitTime}ms`);\n          if (onRetry) {\n            onRetry(attempt + 1, error);\n          }\n          \n          await sleep(waitTime);\n          delay *= backoffMultiplier;\n          continue;\n        }\n      }\n\n      return response;\n    } catch (error) {\n      lastError = error as Error;\n      \n      // Check if error is retryable\n      const isRetryable = retryableErrors.some(errType => \n        lastError?.message?.includes(errType)\n      );\n\n      if (!isRetryable || attempt === maxRetries) {\n        throw lastError;\n      }\n\n      // Exponential backoff\n      const waitTime = Math.min(delay, maxDelay);\n      if (onRetry) {\n        onRetry(attempt + 1, lastError);\n      }\n      \n      await sleep(waitTime);\n      delay *= backoffMultiplier;\n    }\n  }\n\n  throw lastError || new Error('Max retries exceeded');\n}\n\n/**\n * Add timeout to any promise\n * \n * @param promise - Promise to wrap with timeout\n * @param timeoutMs - Timeout in milliseconds\n * @param errorMessage - Optional custom error message\n * @returns Promise that rejects if timeout is reached\n * \n * @example\n * ```typescript\n * const result = await withTimeout(\n *   fetchData(),\n *   5000,\n *   'Data fetch timed out'\n * );\n * ```\n */\nexport async function withTimeout<T>(\n  promise: Promise<T>,\n  timeoutMs: number,\n  errorMessage?: string\n): Promise<T> {\n  let timeoutId: NodeJS.Timeout | number;\n  \n  const timeoutPromise = new Promise<never>((_, reject) => {\n    timeoutId = setTimeout(() => {\n      reject(new Error(errorMessage || `Operation timed out after ${timeoutMs}ms`));\n    }, timeoutMs);\n  });\n\n  try {\n    const result = await Promise.race([promise, timeoutPromise]);\n    clearTimeout(timeoutId!);\n    return result;\n  } catch (error) {\n    clearTimeout(timeoutId!);\n    throw error;\n  }\n}\n\n/**\n * Sleep for specified milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n  return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Unified error type for all tools\n */\nexport class MorphError extends Error {\n  constructor(\n    message: string,\n    public code: string,\n    public statusCode?: number,\n    public retryable: boolean = false\n  ) {\n    super(message);\n    this.name = 'MorphError';\n  }\n}\n\n\n","/**\n * Edge-safe logger.\n *\n * This module is imported transitively by the edge entrypoint\n * (`@morphllm/morphsdk/edge`) via fastapply, modelrouter, etc.\n * Edge runtimes (Vercel Edge Functions, Cloudflare Workers, Deno Deploy)\n * run on V8 isolates — not Node.js — so Node built-ins like fs don't\n * exist. A top-level static import of fs would crash at module-load time,\n * even if createWriteStream is only called conditionally.\n *\n * Fix: we use a dynamic import() behind a runtime check. In Node the\n * import resolves and file logging works normally. In edge runtimes the\n * import rejects and we silently fall back to console-only logging.\n */\n\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\ninterface WriteStream {\n  write(chunk: string): boolean;\n}\n\nclass MorphLogger {\n  private enabled: boolean;\n  private fileStream: WriteStream | null;\n  /** Resolves once the file stream is initialized (or immediately if no file logging). */\n  readonly ready: Promise<void>;\n\n  constructor() {\n    this.enabled = typeof process !== 'undefined' &&\n      (process.env.MORPH_DEBUG === '1' || !!process.env.MORPH_LOG_FILE);\n    this.fileStream = null;\n\n    const f = typeof process !== 'undefined' ? process.env.MORPH_LOG_FILE : undefined;\n    if (f) {\n      // Dynamic import — never evaluated at parse time, so edge runtimes\n      // don't blow up with \"Module 'fs' not found\".\n      this.ready = import('fs')\n        .then((fs) => {\n          this.fileStream = fs.createWriteStream(f, { flags: 'a' });\n        })\n        .catch(() => {\n          // Edge runtime — fs unavailable, silently skip file logging\n        });\n    } else {\n      this.ready = Promise.resolve();\n    }\n  }\n\n  debug(component: string, msg: string, data?: Record<string, unknown>) { this._log('debug', component, msg, data); }\n  info(component: string, msg: string, data?: Record<string, unknown>) { this._log('info', component, msg, data); }\n  warn(component: string, msg: string, data?: Record<string, unknown>) { this._log('warn', component, msg, data); }\n  error(component: string, msg: string, data?: Record<string, unknown>) { this._log('error', component, msg, data); }\n\n  enable() { this.enabled = true; }\n  get isEnabled() { return this.enabled; }\n\n  private _log(level: LogLevel, component: string, msg: string, data?: Record<string, unknown>) {\n    if (level !== 'error' && !this.enabled) return;\n    const ts = new Date().toISOString();\n    const prefix = `[${ts}] [${level.toUpperCase()}] [${component}]`;\n    console.error(data ? `${prefix} ${msg} ${JSON.stringify(data)}` : `${prefix} ${msg}`);\n    this.fileStream?.write(JSON.stringify({ ts, level, component, msg, ...(data && { data }) }) + '\\n');\n  }\n}\n\nexport const logger = new MorphLogger();\n","/**\n * Live session utilities for Morph browser sessions\n * \n * Provides helpers for embedding and sharing live browser sessions with WebRTC streaming.\n */\n\nimport type { LiveSessionOptions, IframeOptions } from './types.js';\n\n/**\n * Preset configurations for common use cases\n */\nexport const LIVE_PRESETS = {\n  /** Read-only monitoring (no interaction) */\n  readonly: { interactive: false } as LiveSessionOptions,\n  /** Interactive control (human-in-the-loop) */\n  interactive: { interactive: true } as LiveSessionOptions,\n  /** Watch-only without controls */\n  monitoring: { interactive: false, showControls: false } as LiveSessionOptions,\n} as const;\n\n/**\n * Build a live session URL with query parameters\n * \n * @param debugUrl - Live session debug URL (e.g., from task.debugUrl)\n * @param options - Live session configuration options\n * @returns URL with query parameters for iframe embedding\n * \n * @example\n * ```typescript\n * const url = buildLiveUrl(task.debugUrl, { interactive: true });\n * // Returns: https://example.com/sessions/abc?interactive=true\n * ```\n */\nexport function buildLiveUrl(\n  debugUrl: string,\n  options: LiveSessionOptions = {}\n): string {\n  if (!debugUrl) {\n    throw new Error(\n      'debugUrl is required. Ensure your backend returns debugUrl in the task response. ' +\n      'Contact support@morphllm.com if you need help.'\n    );\n  }\n\n  const normalized = normalizeLiveUrl(debugUrl);\n  const url = new URL(normalized);\n  \n  // Add query parameters for supported options\n  if (options.interactive !== undefined) {\n    url.searchParams.set('interactive', String(options.interactive));\n  }\n  \n  if (options.theme) {\n    url.searchParams.set('theme', options.theme);\n  }\n  \n  if (options.showControls !== undefined) {\n    url.searchParams.set('showControls', String(options.showControls));\n  }\n  \n  if (options.pageId) {\n    url.searchParams.set('pageId', options.pageId);\n  }\n  \n  if (options.pageIndex) {\n    url.searchParams.set('pageIndex', options.pageIndex);\n  }\n  \n  return url.toString();\n}\n\n/**\n * Convert a CDP WebSocket scheme to HTTPS.\n *\n * Browser-use's live viewer expects `wss=https://UUID.cdpN.browser-use.com`\n * but CDP URLs use `wss://`. This swaps the scheme.\n */\nfunction cdpToHttps(wsUrl: string): string {\n  return wsUrl.replace(/^wss:\\/\\//, 'https://').replace(/^ws:\\/\\//, 'http://');\n}\n\n/**\n * Normalize any debug URL into a valid browser-use live viewer URL.\n *\n * Handles three input formats:\n *  1. Already-correct `https://live.browser-use.com?wss=https://...` — pass through\n *  2. Already-correct but with wrong scheme `...?wss=wss://...` — fix the wss param\n *  3. Raw CDP URL `wss://UUID.cdpN.browser-use.com` — wrap into live viewer URL\n */\nfunction normalizeLiveUrl(debugUrl: string): string {\n  const trimmed = debugUrl.trim();\n  if (!trimmed) return trimmed;\n\n  // Case 3: raw CDP WebSocket URL → wrap into live viewer\n  if (trimmed.startsWith('wss://') || trimmed.startsWith('ws://')) {\n    return `https://live.browser-use.com?wss=${encodeURIComponent(cdpToHttps(trimmed))}`;\n  }\n\n  let url: URL;\n  try {\n    url = new URL(trimmed);\n  } catch {\n    return trimmed;\n  }\n\n  // Case 2: live viewer URL with wrong scheme in wss param → fix it\n  const wssParam = url.searchParams.get('wss');\n  if (wssParam && (wssParam.startsWith('wss://') || wssParam.startsWith('ws://'))) {\n    url.searchParams.set('wss', cdpToHttps(wssParam));\n  }\n\n  return url.toString();\n}\n\n/**\n * Build iframe HTML for embedding a live session\n * \n * @param debugUrl - Live session debug URL\n * @param options - Iframe configuration including dimensions and session options\n * @returns HTML iframe element as string\n * \n * @example\n * ```typescript\n * const iframe = buildLiveIframe(task.debugUrl, {\n *   interactive: true,\n *   width: '100%',\n *   height: '600px'\n * });\n * ```\n */\nexport function buildLiveIframe(\n  debugUrl: string,\n  options: IframeOptions = {}\n): string {\n  const {\n    width = '100%',\n    height = '600px',\n    style = '',\n    className = '',\n    ...sessionOptions\n  } = options;\n\n  const src = buildLiveUrl(debugUrl, sessionOptions);\n  \n  // Convert numeric dimensions to pixels\n  const widthStr = typeof width === 'number' ? `${width}px` : width;\n  const heightStr = typeof height === 'number' ? `${height}px` : height;\n  \n  // Build style attribute\n  const baseStyle = `width: ${widthStr}; height: ${heightStr}; border: none;`;\n  const fullStyle = style ? `${baseStyle} ${style}` : baseStyle;\n  \n  // Build iframe attributes\n  const attributes = [\n    `src=\"${src}\"`,\n    `style=\"${fullStyle}\"`,\n  ];\n  \n  if (className) {\n    attributes.push(`class=\"${className}\"`);\n  }\n  \n  return `<iframe ${attributes.join(' ')}></iframe>`;\n}\n\n/**\n * Build complete embed code with HTML snippet\n * \n * @param debugUrl - Live session debug URL\n * @param options - Iframe configuration\n * @returns Multi-line HTML snippet ready to copy-paste\n * \n * @example\n * ```typescript\n * const code = buildEmbedCode(task.debugUrl, { interactive: false });\n * console.log(code);\n * // <!-- Embed Morph Live Session -->\n * // <iframe src=\"...\" style=\"...\"></iframe>\n * ```\n */\nexport function buildEmbedCode(\n  debugUrl: string,\n  options: IframeOptions = {}\n): string {\n  const iframe = buildLiveIframe(debugUrl, options);\n  return `<!-- Embed Morph Live Session -->\\n${iframe}`;\n}\n\n/**\n * Get live session options from preset name or custom config\n * \n * @internal\n */\nexport function resolvePreset(\n  optionsOrPreset?: string | IframeOptions\n): IframeOptions {\n  if (!optionsOrPreset) {\n    return {};\n  }\n  \n  if (typeof optionsOrPreset === 'string') {\n    const preset = LIVE_PRESETS[optionsOrPreset as keyof typeof LIVE_PRESETS];\n    if (!preset) {\n      throw new Error(\n        `Unknown preset: ${optionsOrPreset}. Available presets: ${Object.keys(LIVE_PRESETS).join(', ')}`\n      );\n    }\n    return preset;\n  }\n  \n  return optionsOrPreset;\n}\n","/**\n * Custom error classes for browser automation and profiles.\n *\n * @example\n * ```typescript\n * try {\n *   await morph.browser.profiles.createProfile({ name: '', repoId: 'owner/repo' });\n * } catch (e) {\n *   if (e instanceof MorphValidationError) {\n *     console.log('Validation failed:', e.field, e.message);\n *   } else if (e instanceof MorphAPIError) {\n *     console.log('API error:', e.code, e.statusCode);\n *   }\n * }\n * ```\n */\n\n/**\n * Error codes for Morph Browser SDK\n */\nexport type MorphErrorCode =\n  // Validation errors\n  | 'validation_error'\n  | 'invalid_parameter'\n  | 'missing_required_field'\n  // Authentication errors\n  | 'authentication_required'\n  | 'invalid_api_key'\n  | 'insufficient_permissions'\n  // Resource errors\n  | 'profile_not_found'\n  | 'session_not_found'\n  | 'resource_not_found'\n  // Limit errors\n  | 'profile_limit_exceeded'\n  | 'rate_limit_exceeded'\n  // Session errors\n  | 'session_expired'\n  | 'session_save_failed'\n  // Network errors\n  | 'network_error'\n  | 'timeout'\n  | 'service_unavailable';\n\n/**\n * Base error class for all Morph SDK errors.\n */\nexport class MorphError extends Error {\n  /** Error code for programmatic handling */\n  readonly code: MorphErrorCode;\n  /** Original cause of the error, if any */\n  readonly cause?: Error;\n\n  constructor(message: string, code: MorphErrorCode, cause?: Error) {\n    super(message);\n    this.name = 'MorphError';\n    this.code = code;\n    this.cause = cause;\n\n    // Maintains proper stack trace in V8 environments\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, this.constructor);\n    }\n  }\n\n  /**\n   * Returns a JSON representation of the error for logging.\n   */\n  toJSON() {\n    return {\n      name: this.name,\n      message: this.message,\n      code: this.code,\n      cause: this.cause?.message,\n    };\n  }\n}\n\n/**\n * Error thrown when API request validation fails.\n */\nexport class MorphValidationError extends MorphError {\n  /** The field that failed validation */\n  readonly field?: string;\n\n  constructor(message: string, field?: string) {\n    super(message, 'validation_error');\n    this.name = 'MorphValidationError';\n    this.field = field;\n  }\n\n  toJSON() {\n    return {\n      ...super.toJSON(),\n      field: this.field,\n    };\n  }\n}\n\n/**\n * Error thrown when an API request fails.\n */\nexport class MorphAPIError extends MorphError {\n  /** HTTP status code */\n  readonly statusCode: number;\n  /** Request ID for debugging (if available) */\n  readonly requestId?: string;\n  /** Raw response body */\n  readonly rawResponse?: string;\n\n  constructor(\n    message: string,\n    code: MorphErrorCode,\n    statusCode: number,\n    options?: {\n      requestId?: string;\n      rawResponse?: string;\n      cause?: Error;\n    }\n  ) {\n    super(message, code, options?.cause);\n    this.name = 'MorphAPIError';\n    this.statusCode = statusCode;\n    this.requestId = options?.requestId;\n    this.rawResponse = options?.rawResponse;\n  }\n\n  toJSON() {\n    return {\n      ...super.toJSON(),\n      statusCode: this.statusCode,\n      requestId: this.requestId,\n    };\n  }\n}\n\n/**\n * Error thrown when authentication fails.\n */\nexport class MorphAuthenticationError extends MorphAPIError {\n  constructor(message: string = 'Authentication required. Please provide a valid API key.') {\n    super(message, 'authentication_required', 401);\n    this.name = 'MorphAuthenticationError';\n  }\n}\n\n/**\n * Error thrown when rate limit is exceeded.\n */\nexport class MorphRateLimitError extends MorphAPIError {\n  /** When the rate limit resets (Unix timestamp) */\n  readonly resetAt?: number;\n  /** Number of seconds until reset */\n  readonly retryAfter?: number;\n\n  constructor(\n    message: string = 'Rate limit exceeded. Please retry later.',\n    options?: {\n      resetAt?: number;\n      retryAfter?: number;\n      requestId?: string;\n    }\n  ) {\n    super(message, 'rate_limit_exceeded', 429, { requestId: options?.requestId });\n    this.name = 'MorphRateLimitError';\n    this.resetAt = options?.resetAt;\n    this.retryAfter = options?.retryAfter;\n  }\n\n  toJSON() {\n    return {\n      ...super.toJSON(),\n      resetAt: this.resetAt,\n      retryAfter: this.retryAfter,\n    };\n  }\n}\n\n/**\n * Error thrown when a resource is not found.\n */\nexport class MorphNotFoundError extends MorphAPIError {\n  /** The type of resource that was not found */\n  readonly resourceType: string;\n  /** The ID of the resource that was not found */\n  readonly resourceId?: string;\n\n  constructor(resourceType: string, resourceId?: string) {\n    const message = resourceId\n      ? `${resourceType} '${resourceId}' not found`\n      : `${resourceType} not found`;\n    super(message, 'resource_not_found', 404);\n    this.name = 'MorphNotFoundError';\n    this.resourceType = resourceType;\n    this.resourceId = resourceId;\n  }\n\n  toJSON() {\n    return {\n      ...super.toJSON(),\n      resourceType: this.resourceType,\n      resourceId: this.resourceId,\n    };\n  }\n}\n\n/**\n * Error thrown when profile limit is exceeded.\n */\nexport class MorphProfileLimitError extends MorphAPIError {\n  /** Current number of profiles */\n  readonly currentCount?: number;\n  /** Maximum allowed profiles for the plan */\n  readonly maxAllowed?: number;\n\n  constructor(\n    message: string = 'Profile limit exceeded for your plan.',\n    options?: {\n      currentCount?: number;\n      maxAllowed?: number;\n      requestId?: string;\n    }\n  ) {\n    super(message, 'profile_limit_exceeded', 403, { requestId: options?.requestId });\n    this.name = 'MorphProfileLimitError';\n    this.currentCount = options?.currentCount;\n    this.maxAllowed = options?.maxAllowed;\n  }\n\n  toJSON() {\n    return {\n      ...super.toJSON(),\n      currentCount: this.currentCount,\n      maxAllowed: this.maxAllowed,\n    };\n  }\n}\n\n/**\n * Parse an API error response and return the appropriate error class.\n */\nexport function parseAPIError(\n  statusCode: number,\n  responseText: string,\n  requestId?: string\n): MorphAPIError {\n  // Try to parse JSON error response\n  let errorData: { detail?: string; code?: string; message?: string } = {};\n  try {\n    errorData = JSON.parse(responseText);\n  } catch {\n    // Not JSON, use raw text\n  }\n\n  const message = errorData.detail || errorData.message || responseText || 'Unknown error';\n  const code = errorData.code;\n\n  // Map status codes to specific error classes\n  switch (statusCode) {\n    case 401:\n      return new MorphAuthenticationError(message);\n\n    case 403:\n      if (code === 'profile_limit_exceeded' || message.toLowerCase().includes('limit')) {\n        return new MorphProfileLimitError(message, { requestId });\n      }\n      return new MorphAPIError(message, 'insufficient_permissions', statusCode, { requestId, rawResponse: responseText });\n\n    case 404:\n      if (message.toLowerCase().includes('profile')) {\n        return new MorphNotFoundError('Profile', undefined);\n      }\n      if (message.toLowerCase().includes('session')) {\n        return new MorphNotFoundError('Session', undefined);\n      }\n      return new MorphAPIError(message, 'resource_not_found', statusCode, { requestId, rawResponse: responseText });\n\n    case 429:\n      return new MorphRateLimitError(message, { requestId });\n\n    case 422:\n      return new MorphAPIError(message, 'validation_error', statusCode, { requestId, rawResponse: responseText });\n\n    case 500:\n    case 502:\n    case 503:\n    case 504:\n      return new MorphAPIError(message, 'service_unavailable', statusCode, { requestId, rawResponse: responseText });\n\n    default:\n      return new MorphAPIError(message, 'network_error', statusCode, { requestId, rawResponse: responseText });\n  }\n}\n","/**\n * Type definitions for browser profiles.\n *\n * All types use camelCase for SDK ergonomics.\n * API responses are normalized from snake_case to camelCase.\n */\n\n/**\n * A browser profile that stores login state (cookies, localStorage).\n *\n * @example\n * ```typescript\n * const profile = await morph.browser.profiles.getProfile('profile-id');\n * console.log(profile.cookieDomains); // ['linkedin.com', 'google.com']\n * ```\n */\nexport interface Profile {\n  /** Unique profile identifier (UUID) */\n  id: string;\n  /** Human-readable profile name */\n  name: string;\n  /** Repository ID this profile is associated with */\n  repoId: string;\n  /** List of domains with stored cookies */\n  cookieDomains?: string[];\n  /** ISO 8601 timestamp of last use */\n  lastUsedAt?: string;\n  /** ISO 8601 timestamp of creation */\n  createdAt: string;\n  /** ISO 8601 timestamp of last update */\n  updatedAt: string;\n}\n\n/**\n * Input for creating a new profile.\n *\n * @example\n * ```typescript\n * await morph.browser.profiles.createProfile({\n *   name: 'LinkedIn Production',\n *   repoId: 'owner/repo'\n * });\n * ```\n */\nexport interface CreateProfileInput {\n  /** Profile name (1-100 characters) */\n  name: string;\n  /** Repository ID - profiles are repo-specific */\n  repoId: string;\n}\n\n/**\n * Input for updating a profile.\n */\n// Intentionally no UpdateProfileInput: update means \"open a live session\"\n\n/**\n * Response for listing profiles.\n */\nexport interface ProfileListResponse {\n  profiles: Profile[];\n}\n\n/**\n * A browser session for profile setup.\n *\n * @example\n * ```typescript\n * const session = await morph.browser.profiles.startSession();\n * console.log('Sign in at:', session.debugUrl);\n * // After user signs in...\n * await morph.browser.profiles.saveSession(session.sessionId, profile.id);\n * ```\n */\nexport interface ProfileSession {\n  /** Unique session identifier */\n  sessionId: string;\n  /** Live session URL for viewing/interacting with the browser */\n  debugUrl: string;\n}\n\n/**\n * Profile setup handle returned by create/update.\n *\n * Provides a live URL for login and an explicit save() helper.\n */\nexport interface ProfileSetup {\n  profile: Profile;\n  session: ProfileSession;\n  save: () => Promise<Profile>;\n}\n/**\n * Input for starting a profile session.\n */\nexport interface ProfileSessionInput {\n  /** Optional profile ID to update an existing profile */\n  profileId?: string;\n}\n\n/**\n * Input for saving a profile session.\n */\nexport interface SaveProfileSessionInput {\n  /** The browser session ID to extract state from */\n  sessionId: string;\n  /** The profile ID to save state to */\n  profileId: string;\n}\n\n/**\n * Response for profile state URL.\n */\nexport interface ProfileStateResponse {\n  /** Profile ID */\n  profileId: string;\n  /** Presigned URL to download the profile state (expires in `expiresIn` seconds) */\n  stateUrl: string;\n  /** URL expiry time in seconds */\n  expiresIn: number;\n}\n\n/**\n * Repo summary for profile discovery.\n */\nexport interface RepoSummary {\n  repoId: string;\n  repoFullName?: string;\n  profileCount: number;\n}\n\n/**\n * Response for repo discovery.\n */\nexport interface RepoListResponse {\n  repos: RepoSummary[];\n}\n\n/**\n * Profile with convenience methods attached.\n *\n * @example\n * ```typescript\n * const profile = await morph.browser.profiles.getProfile('id');\n * const state = await profile.getState();\n * await profile.delete();\n * ```\n */\nexport interface ProfileWithMethods extends Profile {\n  /** Get presigned URL for profile state */\n  getState: () => Promise<ProfileStateResponse>;\n  /** Delete this profile */\n  delete: () => Promise<void>;\n}\n\n// ============================================================================\n// Internal API types (snake_case - matches backend response)\n// ============================================================================\n\n/** @internal API response format */\nexport interface APIProfile {\n  id: string;\n  name: string;\n  repo_id: string;\n  cookie_domains?: string[];\n  last_used_at?: string;\n  created_at: string;\n  updated_at: string;\n}\n\n/** @internal API response format */\nexport interface APIProfileSession {\n  session_id: string;\n  debug_url?: string;\n}\n\n/** @internal API response format */\nexport interface APIProfileStateResponse {\n  profile_id: string;\n  state_url: string;\n  expires_in: number;\n}\n\n// ============================================================================\n// Transformers\n// ============================================================================\n\n/**\n * Transform API profile response to SDK format.\n * @internal\n */\nexport function transformProfile(api: APIProfile): Profile {\n  return {\n    id: api.id,\n    name: api.name,\n    repoId: api.repo_id,\n    cookieDomains: api.cookie_domains,\n    lastUsedAt: api.last_used_at,\n    createdAt: api.created_at,\n    updatedAt: api.updated_at,\n  };\n}\n\n/**\n * Transform SDK input to API format.\n * @internal\n */\nexport function transformCreateInput(input: CreateProfileInput): { name: string; repo_id: string } {\n  return {\n    name: input.name,\n    repo_id: input.repoId,\n  };\n}\n\n/**\n * Transform API session response to SDK format.\n * @internal\n */\nexport function transformSession(api: APIProfileSession): ProfileSession {\n  return {\n    sessionId: api.session_id,\n    debugUrl: api.debug_url || '',\n  };\n}\n\n/**\n * Transform SDK save input to API format.\n * @internal\n */\nexport function transformSaveInput(input: SaveProfileSessionInput): { session_id: string; profile_id: string } {\n  return {\n    session_id: input.sessionId,\n    profile_id: input.profileId,\n  };\n}\n\n/**\n * Transform API state response to SDK format.\n * @internal\n */\nexport function transformStateResponse(api: APIProfileStateResponse): ProfileStateResponse {\n  return {\n    profileId: api.profile_id,\n    stateUrl: api.state_url,\n    expiresIn: api.expires_in,\n  };\n}\n","/**\n * ProfilesClient - Manage browser profiles for storing login state.\n *\n * @example\n * ```typescript\n * const morph = new MorphClient({ apiKey: '...' });\n *\n * // Create a profile + live setup session\n * const setup = await morph.browser.profiles.createProfile({\n *   name: 'LinkedIn',\n *   repoId: 'owner/repo'\n * });\n *\n * console.log('Sign in at:', setup.session.debugUrl);\n * // User logs in, then explicitly save\n * await setup.save();\n *\n * // Use profile in browser tasks\n * await morph.browser.execute({\n *   task: 'Check notifications',\n *   url: 'https://linkedin.com',\n *   profileId: profile.id\n * });\n * ```\n */\n\nimport { fetchWithRetry } from '../../utils/resilience.js';\nimport type { BrowserConfig } from '../types.js';\nimport {\n  MorphValidationError,\n  MorphAuthenticationError,\n  parseAPIError,\n} from '../errors.js';\nimport type {\n  Profile,\n  ProfileSetup,\n  ProfileWithMethods,\n  CreateProfileInput,\n  ProfileListResponse,\n  ProfileSession,\n  ProfileSessionInput,\n  SaveProfileSessionInput,\n  ProfileStateResponse,\n  RepoSummary,\n  RepoListResponse,\n  APIProfile,\n  APIProfileSession,\n  APIProfileStateResponse,\n} from './types.js';\nimport {\n  transformProfile,\n  transformCreateInput,\n  transformSession,\n  transformSaveInput,\n  transformStateResponse,\n} from './types.js';\n\nconst DEFAULT_API_URL = process.env.MORPH_ENVIRONMENT === 'DEV'\n  ? 'http://localhost:8000'\n  : 'https://browser.morphllm.com';\n\n/**\n * ProfilesClient class for managing browser profiles.\n *\n * Access via `morph.browser.profiles` on a MorphClient instance.\n */\nexport class ProfilesClient {\n  private config: BrowserConfig;\n\n  constructor(config: BrowserConfig) {\n    this.config = config;\n  }\n\n  /**\n   * Create a new browser profile and immediately start a live session.\n   *\n   * @param input - Profile creation parameters\n   * @returns Profile setup handle with live URL + save()\n   * @throws {MorphValidationError} If input validation fails\n   * @throws {MorphProfileLimitError} If profile limit is exceeded\n   * @throws {MorphAuthenticationError} If API key is missing or invalid\n   *\n   * @example\n   * ```typescript\n * const setup = await morph.browser.profiles.createProfile({\n *   name: 'LinkedIn Production',\n *   repoId: 'owner/repo'\n * });\n * console.log(setup.session.debugUrl);\n * await setup.save();\n   * ```\n   */\n  async createProfile(input: CreateProfileInput): Promise<ProfileSetup> {\n    return createProfile(input, this.config);\n  }\n\n  /**\n   * List all profiles for the authenticated user.\n   *\n   * @param repoId - Optional repository ID to filter by\n   * @returns Array of profiles\n   *\n   * @example\n   * ```typescript\n   * // List all profiles\n   * const allProfiles = await morph.browser.profiles.listProfiles();\n   *\n   * // List profiles for a specific repo\n   * const repoProfiles = await morph.browser.profiles.listProfiles('owner/repo');\n   * ```\n   */\n  async listProfiles(repoId?: string): Promise<Profile[]> {\n    return listProfiles(this.config, repoId);\n  }\n\n  /**\n   * Get a profile by ID with convenience methods.\n   *\n   * @param id - Profile ID\n   * @returns Profile with attached methods\n   * @throws {MorphNotFoundError} If profile is not found\n   *\n   * @example\n   * ```typescript\n   * const profile = await morph.browser.profiles.getProfile('profile-id');\n   * const state = await profile.getState();\n   * await profile.delete();\n   * ```\n   */\n  async getProfile(id: string): Promise<ProfileWithMethods> {\n    return getProfile(id, this.config);\n  }\n\n  /**\n   * Update a profile by opening a live session (no rename).\n   *\n   * @param id - Profile ID\n   * @returns Profile setup handle with live URL + save()\n   */\n  async updateProfile(id: string): Promise<ProfileSetup> {\n    return updateProfile(id, this.config);\n  }\n\n  /**\n   * Delete a profile.\n   *\n   * @param id - Profile ID\n   * @throws {MorphNotFoundError} If profile is not found\n   */\n  async deleteProfile(id: string): Promise<void> {\n    return deleteProfile(id, this.config);\n  }\n\n  /**\n   * Start a browser session for profile setup.\n   *\n   * Returns a live URL where the user can sign into accounts.\n   * After signing in, call `saveSession` to persist the state.\n   *\n   * @param input - Optional session parameters\n   * @returns Session with debug URL\n   *\n   * @example\n   * ```typescript\n   * const session = await morph.browser.profiles.startSession();\n   * console.log('Sign in at:', session.debugUrl);\n   * // Open debugUrl in browser, user signs in...\n   * await morph.browser.profiles.saveSession(session.sessionId, profile.id);\n   * ```\n   */\n  async startSession(input?: ProfileSessionInput): Promise<ProfileSession> {\n    return startProfileSession(this.config, input);\n  }\n\n  /**\n   * Save browser state from a session to a profile.\n   *\n   * Call this after the user is done signing into accounts.\n   * Extracts cookies, localStorage, and sessionStorage.\n   *\n   * @param sessionId - Browser session ID from startSession\n   * @param profileId - Profile ID to save state to\n   * @returns Updated profile with cookie domains\n   */\n  async saveSession(sessionId: string, profileId: string): Promise<Profile> {\n    return saveProfileSession({ sessionId, profileId }, this.config);\n  }\n\n  /**\n   * List available repo IDs (discovery).\n   *\n   * @returns Repo summaries with profile counts\n   */\n  async listRepos(): Promise<RepoSummary[]> {\n    return listRepos(this.config);\n  }\n\n  /**\n   * Get the presigned URL for a profile's state.\n   *\n   * Use this to download the raw state JSON for debugging\n   * or to restore state manually.\n   *\n   * @param profileId - Profile ID\n   * @returns State URL with expiry information\n   */\n  async getProfileState(profileId: string): Promise<ProfileStateResponse> {\n    return getProfileState(profileId, this.config);\n  }\n}\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\nfunction validateCreateInput(input: CreateProfileInput): void {\n  if (!input.name || typeof input.name !== 'string') {\n    throw new MorphValidationError('name is required', 'name');\n  }\n\n  const trimmedName = input.name.trim();\n  if (trimmedName.length === 0) {\n    throw new MorphValidationError('name cannot be empty', 'name');\n  }\n\n  if (trimmedName.length > 100) {\n    throw new MorphValidationError('name must be 100 characters or less', 'name');\n  }\n\n  if (!input.repoId || typeof input.repoId !== 'string') {\n    throw new MorphValidationError('repoId is required', 'repoId');\n  }\n\n  if (input.repoId.trim().length === 0) {\n    throw new MorphValidationError('repoId cannot be empty', 'repoId');\n  }\n}\n\nfunction validateId(id: string, fieldName: string): void {\n  if (!id || typeof id !== 'string') {\n    throw new MorphValidationError(`${fieldName} is required`, fieldName);\n  }\n\n  if (id.trim().length === 0) {\n    throw new MorphValidationError(`${fieldName} cannot be empty`, fieldName);\n  }\n}\n\n// ============================================================================\n// Standalone Functions\n// ============================================================================\n\n/**\n * Create a new browser profile.\n */\nexport async function createProfile(\n  input: CreateProfileInput,\n  config: BrowserConfig = {}\n): Promise<ProfileSetup> {\n  validateCreateInput(input);\n\n  const apiUrl = config.apiUrl || DEFAULT_API_URL;\n  const headers = buildHeaders(config);\n\n  const response = await fetchWithRetry(\n    `${apiUrl}/profiles`,\n    {\n      method: 'POST',\n      headers,\n      body: JSON.stringify(transformCreateInput(input)),\n    },\n    config.retryConfig\n  );\n\n  if (!response.ok) {\n    const errorText = await response.text().catch(() => response.statusText);\n    const requestId = response.headers.get('x-request-id') || undefined;\n    throw parseAPIError(response.status, errorText, requestId);\n  }\n\n  const apiProfile: APIProfile = await response.json();\n  const profile = transformProfile(apiProfile);\n  const session = await startProfileSession(config, { profileId: profile.id });\n  return buildProfileSetup(profile, session, config);\n}\n\n/**\n * List all profiles for the authenticated user.\n */\nexport async function listProfiles(\n  config: BrowserConfig = {},\n  repoId?: string\n): Promise<Profile[]> {\n  const apiUrl = config.apiUrl || DEFAULT_API_URL;\n  const headers = buildHeaders(config);\n\n  const url = repoId\n    ? `${apiUrl}/profiles?repo_id=${encodeURIComponent(repoId)}`\n    : `${apiUrl}/profiles`;\n\n  const response = await fetchWithRetry(\n    url,\n    { method: 'GET', headers },\n    config.retryConfig\n  );\n\n  if (!response.ok) {\n    const errorText = await response.text().catch(() => response.statusText);\n    const requestId = response.headers.get('x-request-id') || undefined;\n    throw parseAPIError(response.status, errorText, requestId);\n  }\n\n  const data: { profiles: APIProfile[] } = await response.json();\n  return data.profiles.map(transformProfile);\n}\n\n/**\n * Get a profile by ID with convenience methods.\n */\nexport async function getProfile(\n  id: string,\n  config: BrowserConfig = {}\n): Promise<ProfileWithMethods> {\n  validateId(id, 'id');\n\n  const apiUrl = config.apiUrl || DEFAULT_API_URL;\n  const headers = buildHeaders(config);\n\n  const response = await fetchWithRetry(\n    `${apiUrl}/profiles/${encodeURIComponent(id)}`,\n    { method: 'GET', headers },\n    config.retryConfig\n  );\n\n  if (!response.ok) {\n    const errorText = await response.text().catch(() => response.statusText);\n    const requestId = response.headers.get('x-request-id') || undefined;\n    throw parseAPIError(response.status, errorText, requestId);\n  }\n\n  const apiProfile: APIProfile = await response.json();\n  const profile = transformProfile(apiProfile);\n\n  // Attach convenience methods\n  return {\n    ...profile,\n    getState: () => getProfileState(id, config),\n    delete: () => deleteProfile(id, config),\n  };\n}\n\n/**\n * Update a profile.\n */\nexport async function updateProfile(\n  id: string,\n  config: BrowserConfig = {}\n): Promise<ProfileSetup> {\n  validateId(id, 'id');\n  const profile = await fetchProfile(id, config);\n  const session = await startProfileSession(config, { profileId: profile.id });\n  return buildProfileSetup(profile, session, config);\n}\n\n/**\n * Delete a profile.\n */\nexport async function deleteProfile(\n  id: string,\n  config: BrowserConfig = {}\n): Promise<void> {\n  validateId(id, 'id');\n\n  const apiUrl = config.apiUrl || DEFAULT_API_URL;\n  const headers = buildHeaders(config);\n\n  const response = await fetchWithRetry(\n    `${apiUrl}/profiles/${encodeURIComponent(id)}`,\n    { method: 'DELETE', headers },\n    config.retryConfig\n  );\n\n  if (!response.ok) {\n    const errorText = await response.text().catch(() => response.statusText);\n    const requestId = response.headers.get('x-request-id') || undefined;\n    throw parseAPIError(response.status, errorText, requestId);\n  }\n}\n\n/**\n * Start a browser session for profile setup.\n */\nexport async function startProfileSession(\n  config: BrowserConfig = {},\n  input?: ProfileSessionInput\n): Promise<ProfileSession> {\n  if (!config.apiKey) {\n    throw new MorphAuthenticationError();\n  }\n\n  const apiUrl = config.apiUrl || DEFAULT_API_URL;\n  const headers = buildHeaders(config);\n\n  // Transform input if provided\n  const body = input?.profileId\n    ? { profile_id: input.profileId }\n    : {};\n\n  const response = await fetchWithRetry(\n    `${apiUrl}/profiles/session/start`,\n    {\n      method: 'POST',\n      headers,\n      body: JSON.stringify(body),\n    },\n    config.retryConfig\n  );\n\n  if (!response.ok) {\n    const errorText = await response.text().catch(() => response.statusText);\n    const requestId = response.headers.get('x-request-id') || undefined;\n    throw parseAPIError(response.status, errorText, requestId);\n  }\n\n  const apiSession: APIProfileSession = await response.json();\n  return transformSession(apiSession);\n}\n\n/**\n * Save browser state from a session to a profile.\n */\nexport async function saveProfileSession(\n  input: SaveProfileSessionInput,\n  config: BrowserConfig = {}\n): Promise<Profile> {\n  validateId(input.sessionId, 'sessionId');\n  validateId(input.profileId, 'profileId');\n\n  const apiUrl = config.apiUrl || DEFAULT_API_URL;\n  const headers = buildHeaders(config);\n\n  const response = await fetchWithRetry(\n    `${apiUrl}/profiles/session/save`,\n    {\n      method: 'POST',\n      headers,\n      body: JSON.stringify(transformSaveInput(input)),\n    },\n    config.retryConfig\n  );\n\n  if (!response.ok) {\n    const errorText = await response.text().catch(() => response.statusText);\n    const requestId = response.headers.get('x-request-id') || undefined;\n    throw parseAPIError(response.status, errorText, requestId);\n  }\n\n  const apiProfile: APIProfile = await response.json();\n  return transformProfile(apiProfile);\n}\n\n/**\n * List repo IDs available to the authenticated user/org.\n */\nexport async function listRepos(config: BrowserConfig = {}): Promise<RepoSummary[]> {\n  const apiUrl = config.apiUrl || DEFAULT_API_URL;\n  const headers = buildHeaders(config);\n\n  const response = await fetchWithRetry(\n    `${apiUrl}/repos`,\n    { method: 'GET', headers },\n    config.retryConfig\n  );\n\n  if (!response.ok) {\n    const errorText = await response.text().catch(() => response.statusText);\n    const requestId = response.headers.get('x-request-id') || undefined;\n    throw parseAPIError(response.status, errorText, requestId);\n  }\n\n  const data = await response.json();\n  const repos = Array.isArray(data?.repos) ? data.repos : [];\n\n  return repos.map((repo: any) => ({\n    repoId: repo.repo_id,\n    repoFullName: repo.repo_full_name,\n    profileCount: repo.profile_count ?? 0,\n  })) satisfies RepoSummary[];\n}\n\n/**\n * Get the presigned URL for a profile's state.\n */\nexport async function getProfileState(\n  profileId: string,\n  config: BrowserConfig = {}\n): Promise<ProfileStateResponse> {\n  validateId(profileId, 'profileId');\n\n  const apiUrl = config.apiUrl || DEFAULT_API_URL;\n  const headers = buildHeaders(config);\n\n  const response = await fetchWithRetry(\n    `${apiUrl}/profiles/${encodeURIComponent(profileId)}/state`,\n    { method: 'GET', headers },\n    config.retryConfig\n  );\n\n  if (!response.ok) {\n    const errorText = await response.text().catch(() => response.statusText);\n    const requestId = response.headers.get('x-request-id') || undefined;\n    throw parseAPIError(response.status, errorText, requestId);\n  }\n\n  const apiState: APIProfileStateResponse = await response.json();\n  return transformStateResponse(apiState);\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction buildHeaders(config: BrowserConfig): Record<string, string> {\n  const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n  if (config.apiKey) {\n    headers['Authorization'] = `Bearer ${config.apiKey}`;\n  }\n  return headers;\n}\n\nasync function fetchProfile(id: string, config: BrowserConfig): Promise<Profile> {\n  const apiUrl = config.apiUrl || DEFAULT_API_URL;\n  const headers = buildHeaders(config);\n\n  const response = await fetchWithRetry(\n    `${apiUrl}/profiles/${encodeURIComponent(id)}`,\n    { method: 'GET', headers },\n    config.retryConfig\n  );\n\n  if (!response.ok) {\n    const errorText = await response.text().catch(() => response.statusText);\n    const requestId = response.headers.get('x-request-id') || undefined;\n    throw parseAPIError(response.status, errorText, requestId);\n  }\n\n  const apiProfile: APIProfile = await response.json();\n  return transformProfile(apiProfile);\n}\n\nfunction buildProfileSetup(profile: Profile, session: ProfileSession, config: BrowserConfig): ProfileSetup {\n  return {\n    profile,\n    session,\n    save: () => saveProfileSession({ sessionId: session.sessionId, profileId: profile.id }, config),\n  };\n}\n","/**\n * Single error mapper for the SDK transport.\n *\n * Consolidates the per-tool error handling that used to live in every client\n * (compact, reflex, github, …) into one place, preserving the actionable\n * 401/429 messaging. Reuses the existing `MorphError` type so callers that\n * `instanceof MorphError` keep working.\n */\nimport { MorphError } from '../tools/utils/resilience.js';\n\ninterface ApiErrorBody {\n  error?: { message?: string; code?: string; type?: string };\n  message?: string;\n}\n\n/**\n * Turn a non-OK `Response` into a `MorphError`, extracting the API's error\n * message when present and marking 429/503 as retryable.\n */\nexport async function toMorphError(response: Response): Promise<MorphError> {\n  let message = `Morph API request failed (${response.status})`;\n  let code = 'api_error';\n\n  try {\n    const body = (await response.json()) as ApiErrorBody;\n    message = body.error?.message ?? body.message ?? message;\n    code = body.error?.code ?? body.error?.type ?? code;\n  } catch {\n    // Non-JSON body — keep the status-based default message.\n  }\n\n  if (response.status === 401) code = 'authentication_error';\n  if (response.status === 429) code = 'rate_limit_exceeded';\n\n  const retryable = response.status === 429 || response.status === 503;\n  return new MorphError(message, code, response.status, retryable);\n}\n","/**\n * MorphAPIClient — the SDK transport.\n *\n * One place owns authentication, the Morph service hosts, default headers,\n * retries, timeouts, and error mapping. Every resource (FastApply, Compact,\n * Reflex, …) holds a reference to this client and delegates HTTP to it via\n * `get`/`post`/`delete`/`request`, exactly like the OpenAI SDK.\n *\n * This module is intentionally free of tool imports and Node built-ins so it\n * stays edge-safe (it is reachable from `@morphllm/morphsdk/edge` through the\n * Compact and model-router resources).\n */\nimport { fetchWithRetry, withTimeout, MorphError, type RetryConfig } from '../tools/utils/resilience.js';\nimport { logger } from '../logger.js';\nimport { SDK_VERSION } from '../version.js';\nimport { toMorphError } from './error.js';\n\n/** The Morph services the SDK talks to. */\nconst DEFAULT_BASE_URL = 'https://api.morphllm.com';\nconst DEFAULT_REPOS_URL = 'https://repos.morphllm.com';\nconst DEFAULT_BROWSER_URL = 'https://browser.morphllm.com';\nconst DEFAULT_TIMEOUT = 60_000;\n\nconst env = (name: string): string | undefined =>\n  typeof process !== 'undefined' ? process.env?.[name] : undefined;\n\nconst stripTrailingSlash = (url: string): string => url.replace(/\\/+$/, '');\n\nexport interface MorphAPIClientOptions {\n  /** Morph API key. Resolved against `MORPH_API_KEY` at request time if omitted. */\n  apiKey?: string;\n  /** Primary API host (default `https://api.morphllm.com`). */\n  baseURL?: string;\n  /** Code-storage host for codebase search and git (default `https://repos.morphllm.com`). */\n  reposURL?: string;\n  /** Browser-automation host (default `https://browser.morphllm.com`). */\n  browserURL?: string;\n  /** Default per-request timeout in ms (default 60s). Resources may override per call. */\n  timeout?: number;\n  /** Retry policy for transient failures. */\n  retryConfig?: RetryConfig;\n  /** Enable debug logging. */\n  debug?: boolean;\n}\n\n/** Per-request options accepted by `request`/`get`/`post`/`delete`. */\nexport interface RequestOptions {\n  /** JSON body; serialized with `JSON.stringify`. */\n  body?: unknown;\n  /** Query parameters; `undefined`/`null` values are dropped. */\n  query?: Record<string, string | number | boolean | undefined | null>;\n  /** Extra headers, merged over (and able to override) the defaults. */\n  headers?: Record<string, string>;\n  /** Override the timeout for this call. */\n  timeout?: number;\n  /** Hit a different host than the default (e.g. `this._client.reposURL`). */\n  baseURL?: string;\n  /** Return the raw `Response` of a successful (2xx) request instead of parsed JSON (for streaming). */\n  stream?: boolean;\n  /**\n   * Return the raw `Response` without throwing on non-2xx and without parsing.\n   * For resources that map errors into their own taxonomy (e.g. GitHub).\n   */\n  raw?: boolean;\n  /** Caller-supplied abort signal. */\n  signal?: AbortSignal;\n}\n\nexport class MorphAPIClient {\n  /** Explicit key as provided; resolved against env at request time. */\n  apiKey?: string;\n  baseURL: string;\n  reposURL: string;\n  browserURL: string;\n  /** Explicit default timeout (ms), if set. The request default is applied lazily so\n   * resources can read an undefined value and supply their own fallback. */\n  timeout?: number;\n  retryConfig?: RetryConfig;\n  debug: boolean;\n\n  constructor(options: MorphAPIClientOptions = {}) {\n    this.apiKey = options.apiKey;\n    this.baseURL = stripTrailingSlash(options.baseURL ?? DEFAULT_BASE_URL);\n    this.reposURL = stripTrailingSlash(options.reposURL ?? env('MORPH_SEARCH_URL') ?? DEFAULT_REPOS_URL);\n    this.browserURL = stripTrailingSlash(\n      options.browserURL ?? (env('MORPH_ENVIRONMENT') === 'DEV' ? 'http://localhost:8000' : DEFAULT_BROWSER_URL),\n    );\n    this.timeout = options.timeout;\n    this.retryConfig = options.retryConfig;\n    this.debug = options.debug ?? false;\n    if (this.debug) logger.enable();\n  }\n\n  /** The key actually used for requests: explicit, else `MORPH_API_KEY`. */\n  resolveApiKey(): string | undefined {\n    return this.apiKey ?? env('MORPH_API_KEY');\n  }\n\n  /** Headers shared with tools that bring their own HTTP client (FastApply/WarpGrep via the `openai` package). */\n  defaultHeaders(): Record<string, string> {\n    return { 'X-Morph-SDK-Version': SDK_VERSION };\n  }\n\n  buildURL(path: string, baseURL?: string): string {\n    if (/^https?:\\/\\//i.test(path)) return path;\n    const base = stripTrailingSlash(baseURL ?? this.baseURL);\n    return `${base}${path.startsWith('/') ? '' : '/'}${path}`;\n  }\n\n  private buildHeaders(apiKey: string, extra?: Record<string, string>): Record<string, string> {\n    return {\n      'Content-Type': 'application/json',\n      'X-Morph-SDK-Version': SDK_VERSION,\n      Authorization: `Bearer ${apiKey}`,\n      ...extra,\n    };\n  }\n\n  private applyQuery(url: string, query?: RequestOptions['query']): string {\n    if (!query) return url;\n    const params = new URLSearchParams();\n    for (const [key, value] of Object.entries(query)) {\n      if (value !== undefined && value !== null) params.set(key, String(value));\n    }\n    const qs = params.toString();\n    return qs ? `${url}${url.includes('?') ? '&' : '?'}${qs}` : url;\n  }\n\n  async request<T>(method: string, path: string, opts: RequestOptions = {}): Promise<T> {\n    const apiKey = this.resolveApiKey();\n    if (!apiKey) {\n      throw new MorphError(\n        'Morph API key not found. Set the MORPH_API_KEY environment variable or pass apiKey in config.',\n        'missing_api_key',\n        401,\n      );\n    }\n\n    const url = this.applyQuery(this.buildURL(path, opts.baseURL), opts.query);\n    const timeout = opts.timeout ?? this.timeout ?? DEFAULT_TIMEOUT;\n\n    const init: RequestInit = {\n      method,\n      headers: this.buildHeaders(apiKey, opts.headers),\n      ...(opts.body !== undefined ? { body: JSON.stringify(opts.body) } : {}),\n      ...(opts.signal ? { signal: opts.signal } : {}),\n    };\n\n    logger.debug('MorphAPIClient', 'request', { method, url });\n\n    const response = await withTimeout(\n      fetchWithRetry(url, init, this.retryConfig ?? {}),\n      timeout,\n      `Morph request to ${url} timed out after ${timeout}ms`,\n    );\n\n    if (opts.raw) return response as unknown as T;\n    if (!response.ok) throw await toMorphError(response);\n    if (opts.stream) return response as unknown as T;\n    if (response.status === 204) return undefined as T;\n\n    const text = await response.text();\n    return (text ? JSON.parse(text) : undefined) as T;\n  }\n\n  get<T>(path: string, opts?: RequestOptions): Promise<T> {\n    return this.request<T>('GET', path, opts);\n  }\n\n  post<T>(path: string, opts?: RequestOptions): Promise<T> {\n    return this.request<T>('POST', path, opts);\n  }\n\n  delete<T>(path: string, opts?: RequestOptions): Promise<T> {\n    return this.request<T>('DELETE', path, opts);\n  }\n}\n","/**\n * Base class for every API resource (FastApply, Compact, Reflex, …).\n *\n * Mirrors the OpenAI SDK's `APIResource`: a resource holds nothing but a\n * reference to the transport (`MorphAPIClient`) and delegates all HTTP to it.\n * Sub-resources receive the same client by reference, so configuration and the\n * fetch/retry/auth machinery live in exactly one place.\n */\nimport type { MorphAPIClient } from './client.js';\n\nexport abstract class APIResource {\n  protected _client: MorphAPIClient;\n\n  constructor(client: MorphAPIClient) {\n    this._client = client;\n  }\n}\n"],"mappings":"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","names":["MorphError"]}