lua-cli 3.17.1 → 3.17.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-exports.d.ts +8 -8
- package/dist/api-exports.js.map +1 -1
- package/dist/index.js +213 -241
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/template/lua.skill.yaml +10 -4
- package/template/package.json +1 -1
package/dist/api-exports.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/interfaces/baskets.ts","../src/config/constants.ts","../src/errors/auth.error.ts","../src/api/http.client.ts","../src/api/auth.api.service.ts","../src/services/auth.ts","../src/config/compile.constants.ts","../../shared-types/dist/index.mjs","../src/compiler/types.ts","../src/api/skills.api.service.ts","../src/utils/artifact-loader.ts","../src/api/backup.api.service.ts","../src/utils/bundle-upload.ts","../src/utils/semver.ts","../src/primitives/base.handler.ts","../src/primitives/skill.handler.ts","../src/utils/files.ts","../src/utils/version-check.ts","../src/utils/package-root.ts","../src/services/analytics.ts","../src/utils/write-info.ts","../src/utils/hints.ts","../src/utils/cli.ts","../src/utils/command-utils.ts","../src/api/credentials.ts","../src/instances/product.instance.ts","../src/instances/product.pagination.instance.ts","../src/instances/product.search.instance.ts","../src/api/products.api.service.ts","../src/instances/basket.instance.ts","../src/instances/order.instance.ts","../src/api/order.api.service.ts","../src/api/basket.api.service.ts","../src/instances/user.instance.ts","../src/api/user.data.api.service.ts","../src/instances/data.entry.instance.ts","../src/api/custom.data.api.service.ts","../src/api/webhook.api.service.ts","../src/instances/job.instance.ts","../src/api/job.api.service.ts","../src/api/ai.api.service.ts","../src/api/agents.api.service.ts","../src/api/whatsapp-templates.api.service.ts","../src/api/cdn.api.service.ts","../src/api/developer.api.service.ts","../src/api/voice.api.service.ts","../src/api/device.api.service.ts","../src/api/lazy-instances.ts","../src/types/tool-validation.ts","../src/types/skill.ts","../src/types/voice.ts","../src/api-exports.ts","../src/interfaces/orders.ts"],"sourcesContent":["/**\n * Basket Interfaces\n * Shopping basket management and operations\n */\n\n/**\n * Basket status enumeration.\n * Represents the lifecycle states of a shopping basket.\n */\nexport enum BasketStatus {\n /** Basket is active and can be modified */\n ACTIVE = 'active',\n /** Basket has been checked out (converted to order) */\n CHECKED_OUT = 'checked_out',\n /** Basket was abandoned by the user */\n ABANDONED = 'abandoned',\n /** Basket has expired (TTL exceeded) */\n EXPIRED = 'expired',\n}\n\n/**\n * Item in a basket.\n * Represents a single product or service in the basket.\n */\nexport interface BasketItem {\n id: string;\n price: number;\n quantity: number;\n SKU?: string;\n addedAt?: string;\n [key: string]: any; // Allow additional properties (e.g., color, size)\n}\n\n/**\n * Basket data container.\n * Contains the actual basket contents and metadata.\n */\nexport interface BasketData {\n currency: string;\n metadata?: any;\n items: BasketItem[];\n createdAt: string;\n}\n\n/**\n * Common basket properties.\n * Calculated/derived properties maintained by the system.\n */\nexport interface BasketCommon {\n status: BasketStatus;\n totalAmount: string | number;\n itemCount: number;\n}\n\n/**\n * Complete basket entity.\n * Full basket object as stored in the database.\n */\nexport interface Basket {\n id: string;\n userId: string;\n agentId: string;\n data: BasketData;\n common: BasketCommon;\n createdAt: string;\n updatedAt: string;\n __v: number;\n}\n\n/**\n * Request to create a new basket.\n */\nexport interface CreateBasketRequest {\n currency: string;\n metadata?: any;\n}\n\n/**\n * Request to add an item to a basket.\n */\nexport interface AddItemToBasketRequest {\n id: string;\n price: number;\n quantity: number;\n [key: string]: any; // Allow additional properties\n}\n","/**\n * Global constants for the CLI\n */\n\nimport { join } from 'path';\nimport { homedir } from 'os';\n\n// =============================================================================\n// PATHS\n// =============================================================================\n\n/**\n * CLI config directory (~/.lua-cli)\n */\nexport const CLI_CONFIG_DIR = join(homedir(), '.lua-cli');\n\n/**\n * Version check cache file\n */\nexport const VERSION_CHECK_FILE = join(CLI_CONFIG_DIR, 'version-check.json');\n\n/**\n * Telemetry config file\n */\nexport const TELEMETRY_FILE = join(CLI_CONFIG_DIR, 'telemetry.json');\n\n/**\n * Versioning-mode (and future TTL) cache file (~/.lua-cli/cache.json).\n * All per-user CLI caches live here alongside version-check.json,\n * telemetry.json, and credentials.\n */\nexport const CLI_CACHE_FILE = join(CLI_CONFIG_DIR, 'cache.json');\n\n// =============================================================================\n// API URLS\n// =============================================================================\n\n/**\n * Base URLs for the API, Auth, and Chat\n */\nexport const BASE_URLS = {\n API: process.env.LUA_API_URL || 'https://api.heylua.ai',\n AUTH: process.env.LUA_AUTH_URL || 'https://auth.heylua.ai',\n CHAT: process.env.LUA_API_URL || 'https://api.heylua.ai',\n WEBHOOK: 'https://webhook.heylua.ai',\n CDN: 'https://cdn.heylua.ai',\n};\n\n// =============================================================================\n// AUTH CONSTANTS\n// =============================================================================\n\n/**\n * Credentials file path for storing the API key (~/.lua-cli/credentials).\n * Written by `lua auth configure`, read by getToken().\n * Owner-only permissions (0600) are applied on write.\n */\nexport const CREDENTIALS_FILE = join(CLI_CONFIG_DIR, 'credentials');\n\n// =============================================================================\n// INIT CONSTANTS\n// =============================================================================\n\n/**\n * Agent type names to search for (in order of preference)\n */\nexport const PREFERRED_AGENT_TYPES = ['Base Agent', 'baseAgent', 'base'] as const;\n\n// =============================================================================\n// SANDBOX STORAGE CONSTANTS\n// =============================================================================\n\n/**\n * Sandbox ID storage file path (~/.lua-cli/sandbox.json).\n * Stores transient sandbox skill/preprocessor/postprocessor IDs for local dev.\n */\nexport const SANDBOX_STORAGE_FILE = join(CLI_CONFIG_DIR, 'sandbox.json');\n\n/**\n * Git remote auth storage file path (~/.lua-cli/auth.json). Stores per-provider\n * tokens and metadata for `lua git auth <provider>`.\n */\nexport const AUTH_STORAGE_FILE = join(CLI_CONFIG_DIR, 'auth.json');\n\n// =============================================================================\n// ANALYTICS CONSTANTS\n// =============================================================================\n\n/**\n * PostHog project API key (public, safe to embed — like a client-side key)\n */\nexport const POSTHOG_API_KEY = 'phc_W7Qsquwlflshmdkm2hWSqRpXuxGbVFo7LEX8H9HrSjC';\n\n/**\n * PostHog ingestion host\n */\nexport const POSTHOG_HOST = 'https://us.i.posthog.com';\n","/**\n * Authentication Error\n * Thrown when API requests fail with 401 Unauthorized status\n */\n\n/**\n * Why a 401 happened. The CLI prints different guidance for each:\n * - `invalid_credentials`: API key is missing/invalid/expired → suggest `lua auth configure`.\n * - `no_agent_access`: API key is fine, but the user does not have access to the\n * agentId in the request → suggest checking `lua.skill.yaml`'s `agent.agentId`.\n * - `unknown`: 401 with no parseable body (treat conservatively as credentials).\n */\nexport type AuthErrorReason = 'invalid_credentials' | 'no_agent_access' | 'unknown';\n\nexport class AuthenticationError extends Error {\n public readonly statusCode: number = 401;\n public readonly isAuthenticationError: boolean = true;\n public readonly reason: AuthErrorReason;\n public readonly serverMessage?: string;\n /**\n * If true, the error message already contains complete remediation steps\n * and `withErrorHandling` should not append its own hint block. Use this\n * when the throw site has more context about the right fix than the\n * generic per-reason hints (e.g. `getToken()` listing all three ways to\n * configure a key — keychain, env var, .env file).\n */\n public readonly suppressDefaultRemediation: boolean;\n\n constructor(\n message: string = 'Invalid API key',\n reason: AuthErrorReason = 'unknown',\n serverMessage?: string,\n suppressDefaultRemediation: boolean = false\n ) {\n super(message);\n this.name = 'AuthenticationError';\n this.reason = reason;\n this.serverMessage = serverMessage;\n this.suppressDefaultRemediation = suppressDefaultRemediation;\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, AuthenticationError);\n }\n }\n\n /**\n * Checks if an error is an AuthenticationError\n * @param error - The error to check\n * @returns True if the error is an AuthenticationError\n */\n static isAuthenticationError(error: unknown): error is AuthenticationError {\n return (\n error instanceof AuthenticationError ||\n (error instanceof Error && 'isAuthenticationError' in error && (error as any).isAuthenticationError === true)\n );\n }\n}\n","import { randomUUID } from 'crypto';\nimport { ApiResponse } from '../interfaces/common.js';\nimport { AuthenticationError } from '../errors/auth.error.js';\n\n/**\n * Generic HTTP client with common error handling\n * Provides a base class for all API service classes with standardized HTTP methods\n */\nexport abstract class HttpClient {\n /**\n * Creates an instance of HttpClient\n * @param baseUrl - The base URL for all API requests\n */\n constructor(protected baseUrl: string) {}\n\n /**\n * Makes an HTTP request with standardized error handling\n * @param url - The full URL to request\n * @param options - Fetch API request options\n * @returns Promise resolving to an ApiResponse with typed data\n * @private\n */\n private async request<T>(url: string, options: RequestInit = {}): Promise<ApiResponse<T>> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 30000);\n try {\n const response = await fetch(url, {\n ...options,\n signal: controller.signal,\n headers: {\n 'Content-Type': 'application/json',\n ...options.headers,\n },\n });\n\n clearTimeout(timeoutId);\n\n // Check if response is ok (status 200-299)\n if (!response.ok) {\n // Try to parse error body as JSON. We need the body for 401s too so\n // we can distinguish \"API key is bad\" from \"API key is fine but the\n // user doesn't own this agent\" — which produce identical 401 status\n // codes but very different remedies (BAC-202).\n let errorData: Record<string, any>;\n try {\n errorData = (await response.json()) as Record<string, any>;\n } catch (jsonError) {\n errorData = {};\n }\n\n if (response.status === 401) {\n const serverMessage = typeof errorData.message === 'string' ? errorData.message : undefined;\n // Detect ownership rejections from lua-api's AdminService. The\n // function throws several variants — `User is not an admin`,\n // `…not an admin of the agent`, `…of the organization` — so match\n // the common stem rather than the longer suffixes.\n if (serverMessage && /not an admin/i.test(serverMessage)) {\n throw new AuthenticationError(\n `Access denied for this agent: ${serverMessage}`,\n 'no_agent_access',\n serverMessage\n );\n }\n // Standard credential failures: bare NestJS `UnauthorizedException()`\n // (body becomes `{ message: 'Unauthorized' }`), empty/non-JSON\n // bodies, and explicit \"invalid/expired/missing token/key\" messages\n // from auth.middleware. Use the canonical \"your API key may be\n // invalid or expired\" message in all of these cases — it's more\n // actionable than echoing \"Unauthorized\" back to the user, and\n // matches the wrapper's `lua auth configure` hint.\n const isExplicitCredential =\n !!serverMessage && /(invalid|expired|missing|no)\\s+(api[\\s_-]?key|token|credential)/i.test(serverMessage);\n const isBareAuthRejection = !serverMessage || /^unauthorized$/i.test(serverMessage);\n if (isExplicitCredential || isBareAuthRejection) {\n throw new AuthenticationError(\n 'Authentication failed. Your API key may be invalid or expired.',\n 'invalid_credentials',\n serverMessage\n );\n }\n // Anything else — e.g. account suspended, billing lapsed, future\n // 401 variants — surface the server message as-is and classify as\n // 'unknown' so we don't misdirect users to `lua auth configure`\n // for a problem that isn't their credentials.\n throw new AuthenticationError(`Authentication failed: ${serverMessage}`, 'unknown', serverMessage);\n }\n\n if (response.status === 403) {\n const detail = errorData.message || 'You do not have permission to access this resource.';\n throw new Error(\n `Access denied (403): ${detail}\\nCheck that your API key has access to this agent/organization.`\n );\n }\n\n return {\n success: false,\n error: {\n message: errorData.message || `HTTP ${response.status}: ${response.statusText}`,\n statusCode: response.status,\n error: errorData.error,\n ...errorData,\n },\n };\n }\n\n // Try to parse JSON response\n let data: any;\n try {\n data = await response.json();\n } catch (jsonError) {\n data = {};\n }\n\n // If the response already has the ApiResponse structure, return it\n if (typeof data === 'object' && data !== null && 'success' in data) {\n return data;\n }\n\n // Otherwise, wrap the data in a successful ApiResponse\n return {\n success: true,\n data,\n };\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (AuthenticationError.isAuthenticationError(error)) {\n throw error;\n }\n\n // 403 errors are thrown as regular Errors — re-throw them (not retryable)\n if (error instanceof Error && error.message.startsWith('Access denied (403)')) {\n throw error;\n }\n\n // AbortError from timeout — treat as network error (retryable)\n if (error instanceof DOMException && error.name === 'AbortError') {\n return {\n success: false,\n error: {\n message: 'Request timeout (30s)',\n statusCode: 0,\n },\n };\n }\n\n // Handle network errors, timeouts, etc.\n return {\n success: false,\n error: {\n message: error instanceof Error ? error.message : 'Network request failed',\n statusCode: 0, // Use 0 to indicate network/connection error\n },\n };\n }\n }\n\n /**\n * Checks if an HTTP status code is retryable\n * @param statusCode - The HTTP status code (0 for network errors)\n * @returns True if the request should be retried\n * @private\n */\n private isRetryableStatus(statusCode: number): boolean {\n // Retry: network errors (0), 429 Too Many Requests, 500-504 server errors\n return statusCode === 0 || statusCode === 429 || (statusCode >= 500 && statusCode <= 504);\n }\n\n /**\n * Calculates exponential backoff with full jitter (AWS best practice)\n * @param attempt - The retry attempt number (0-based)\n * @param baseMs - Base delay in milliseconds\n * @param maxMs - Maximum delay cap in milliseconds\n * @returns Delay in milliseconds with random jitter\n * @private\n */\n private calculateBackoff(attempt: number, baseMs = 1000, maxMs = 15000): number {\n const exponential = Math.min(maxMs, baseMs * Math.pow(2, attempt));\n return Math.max(100, Math.random() * exponential); // Full jitter, 100ms floor\n }\n\n /**\n * Wraps request with retry logic for transient failures\n * @param url - The full URL to request\n * @param options - Fetch API request options\n * @param maxRetries - Maximum number of retry attempts (default 3)\n * @returns Promise resolving to an ApiResponse with typed data\n * @private\n */\n private async retryableRequest<T>(url: string, options: RequestInit = {}, maxRetries = 3): Promise<ApiResponse<T>> {\n // Add idempotency key for POST requests\n if (options.method === 'POST') {\n const headers = (options.headers as Record<string, string>) || {};\n if (!headers['X-Idempotency-Key']) {\n headers['X-Idempotency-Key'] = randomUUID();\n options = { ...options, headers: { ...options.headers, ...headers } };\n }\n }\n\n let lastResult: ApiResponse<T> | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const result = await this.request<T>(url, options);\n\n // Success or non-retryable error — return immediately\n // If there's no error object, treat as non-retryable (e.g. API returning { success: false } on 200)\n if (result.success || !result.error || !this.isRetryableStatus(result.error.statusCode || 0)) {\n return result;\n }\n\n lastResult = result;\n } catch (error) {\n // AuthenticationError and 403 errors are thrown, not returned\n // These should NOT be retried — re-throw immediately\n throw error;\n }\n\n // Wait before retry (but not after the last attempt)\n if (attempt < maxRetries) {\n const backoff = this.calculateBackoff(attempt);\n await new Promise((resolve) => setTimeout(resolve, backoff));\n }\n }\n\n return lastResult!;\n }\n\n /**\n * Performs an HTTP GET request\n * @param url - The relative URL path to request (will be appended to baseUrl)\n * @param headers - Optional HTTP headers to include in the request\n * @returns Promise resolving to an ApiResponse with typed data\n * @protected\n */\n protected async httpGet<T>(url: string, headers?: Record<string, string>): Promise<ApiResponse<T>> {\n return this.retryableRequest<T>(this.baseUrl + url, { method: 'GET', headers });\n }\n\n /**\n * Performs an HTTP POST request\n * @param url - The relative URL path to request (will be appended to baseUrl)\n * @param data - Optional request body data (will be JSON stringified)\n * @param headers - Optional HTTP headers to include in the request\n * @returns Promise resolving to an ApiResponse with typed data\n * @protected\n */\n protected async httpPost<T>(url: string, data?: any, headers?: Record<string, string>): Promise<ApiResponse<T>> {\n return this.retryableRequest<T>(this.baseUrl + url, {\n method: 'POST',\n body: data ? JSON.stringify(data) : undefined,\n headers,\n });\n }\n\n /**\n * Performs an HTTP PUT request\n * @param url - The relative URL path to request (will be appended to baseUrl)\n * @param data - Optional request body data (will be JSON stringified)\n * @param headers - Optional HTTP headers to include in the request\n * @returns Promise resolving to an ApiResponse with typed data\n * @protected\n */\n protected async httpPut<T>(url: string, data?: any, headers?: Record<string, string>): Promise<ApiResponse<T>> {\n return this.retryableRequest<T>(this.baseUrl + url, {\n method: 'PUT',\n body: data ? JSON.stringify(data) : undefined,\n headers,\n });\n }\n\n /**\n * Performs an HTTP DELETE request\n * @param url - The relative URL path to request (will be appended to baseUrl)\n * @param headers - Optional HTTP headers to include in the request\n * @returns Promise resolving to an ApiResponse with typed data\n * @protected\n */\n protected async httpDelete<T>(url: string, headers?: Record<string, string>): Promise<ApiResponse<T>> {\n return this.retryableRequest<T>(this.baseUrl + url, { method: 'DELETE', headers });\n }\n\n /**\n * Performs an HTTP PATCH request\n * @param url - The relative URL path to request (will be appended to baseUrl)\n * @param data - Optional request body data (will be JSON stringified)\n * @param headers - Optional HTTP headers to include in the request\n * @returns Promise resolving to an ApiResponse with typed data\n * @protected\n */\n protected async httpPatch<T>(url: string, data?: any, headers?: Record<string, string>): Promise<ApiResponse<T>> {\n return this.retryableRequest<T>(this.baseUrl + url, {\n method: 'PATCH',\n body: data ? JSON.stringify(data) : undefined,\n headers,\n });\n }\n}\n","import { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport { UserData } from '../interfaces/admin.js';\n\n/**\n * Authentication API calls\n */\nexport default class AuthApi extends HttpClient {\n /**\n * Creates an instance of AuthApi\n * @param baseUrl - The base URL for the API\n */\n constructor(baseUrl: string) {\n super(baseUrl);\n }\n\n /**\n * Validates an API key and retrieves associated user data\n * @param apiKey - The API key to validate\n * @returns Promise resolving to an ApiResponse containing UserData if the key is valid\n * @throws Error if the API key is invalid or the request fails\n */\n async checkApiKey(apiKey: string): Promise<ApiResponse<UserData>> {\n return this.httpGet<UserData>(`/admin`, {\n Authorization: `Bearer ${apiKey}`,\n });\n }\n\n /**\n * Sends a one-time password (OTP) to the specified email address\n * @param email - The email address to send the OTP to\n * @returns Promise resolving to an ApiResponse with a success message\n * @throws Error if the email is invalid or the request fails\n */\n async sendOtp(email: string): Promise<ApiResponse<{ message: string }>> {\n return this.httpPost<{ message: string }>(`/otp`, { email, type: 'email' });\n }\n\n /**\n * Verifies the OTP sent to the user's email and returns a sign-in token\n * @param email - The email address the OTP was sent to\n * @param otp - The one-time password received via email\n * @returns Promise resolving to an ApiResponse containing a signInToken for authentication\n * @throws Error if the OTP is invalid, expired, or the request fails\n */\n async verifyOtp(email: string, otp: string): Promise<ApiResponse<{ signInToken: string }>> {\n return this.httpPost<{ signInToken: string }>(`/otp/verify`, { email, pin: otp, type: 'email' });\n }\n\n /**\n * Exchanges a sign-in token for an API key\n * @param signInToken - The temporary sign-in token obtained from OTP verification\n * @returns Promise resolving to an ApiResponse containing the API key\n * @throws Error if the sign-in token is invalid or the request fails\n */\n async getApiKey(signInToken: string): Promise<ApiResponse<{ apiKey: string }>> {\n return this.httpPost<{ apiKey: string }>(`/profile/apiKey`, undefined, {\n Authorization: `Bearer ${signInToken}`,\n });\n }\n}\n","/**\n * Authentication Service\n * Handles all authentication operations including API key management and OTP flows\n */\n\nimport 'dotenv/config';\nimport { readFileSync, writeFileSync, mkdirSync, unlinkSync } from 'fs';\nimport { dirname } from 'path';\nimport { UserData } from '../interfaces/admin.js';\nimport AuthApi from '../api/auth.api.service.js';\nimport { BASE_URLS, CREDENTIALS_FILE } from '../config/constants.js';\nimport { AuthenticationError } from '../errors/auth.error.js';\n\n// ============================================================================\n// TOKEN RESOLUTION\n// ============================================================================\n\n/**\n * Retrieves the API key from the following sources in priority order:\n * 1. LUA_API_KEY environment variable (CI/CD, Docker, manual export)\n * — this also covers .env files, since dotenv/config (imported above)\n * loads them into process.env before this function is called.\n * 2. ~/.lua-cli/credentials file (written by `lua auth configure`)\n *\n * Throws AuthenticationError with clear instructions if no key is found.\n */\nexport function getToken(): string {\n // Priority 1: Environment variable (also catches .env values loaded by dotenv)\n if (process.env.LUA_API_KEY) {\n return process.env.LUA_API_KEY;\n }\n\n // Priority 2: Credentials file (written by `lua auth configure`)\n try {\n const token = readFileSync(CREDENTIALS_FILE, 'utf8').trim();\n if (token) return token;\n } catch {\n // File doesn't exist or is not readable — fall through to error\n }\n\n // Embed full remediation in the message and tell withErrorHandling not to\n // append its generic credential hint — the three options below are richer\n // than the wrapper's default for this specific case (no key at all).\n throw new AuthenticationError(\n 'No API key found.\\n' +\n '\\n' +\n ' Authenticate using one of these methods:\\n' +\n '\\n' +\n ' ➜ lua auth configure\\n' +\n ' ➜ export LUA_API_KEY=\"your-api-key-here\"\\n' +\n ' ➜ Add LUA_API_KEY=... to a .env file\\n' +\n '\\n' +\n ' 🔑 Get your API key at https://admin.heylua.ai',\n 'invalid_credentials',\n undefined,\n true\n );\n}\n\n/**\n * Returns the API key if present, or null if missing — never throws.\n *\n * Mirrors {@link getToken}'s priority order (env var, then credentials file)\n * but is safe to call from diagnostic / \"doctor\" code paths where authentication\n * is optional (e.g. `lua status`).\n */\nexport function loadApiKey(): string | null {\n if (process.env.LUA_API_KEY) {\n return process.env.LUA_API_KEY;\n }\n try {\n const token = readFileSync(CREDENTIALS_FILE, 'utf8').trim();\n return token || null;\n } catch {\n return null;\n }\n}\n\n// ============================================================================\n// CREDENTIALS FILE OPERATIONS (Local Storage)\n// ============================================================================\n\n/**\n * Saves API key to ~/.lua-cli/credentials with owner-only permissions (0600).\n * Called by `lua auth configure` after successful server validation.\n *\n * @param apiKey - The API key to store\n */\nexport function saveApiKey(apiKey: string): void {\n mkdirSync(dirname(CREDENTIALS_FILE), { recursive: true });\n writeFileSync(CREDENTIALS_FILE, apiKey, { mode: 0o600 });\n}\n\n/**\n * Deletes the credentials file.\n * Called by `lua auth logout`.\n *\n * @returns true if deleted successfully, false if not found or deletion failed\n */\nexport function deleteApiKey(): boolean {\n try {\n unlinkSync(CREDENTIALS_FILE);\n return true;\n } catch {\n return false;\n }\n}\n\n// ============================================================================\n// API OPERATIONS (Server Authentication)\n// ============================================================================\n\n/**\n * Validates an API key with the server and retrieves user data.\n *\n * @param apiKey - The API key to validate\n * @returns Promise resolving to user data including admin info and organizations\n * @throws AuthenticationError if the API key is invalid\n */\nexport async function checkApiKey(apiKey: string): Promise<UserData> {\n const authApi = new AuthApi(BASE_URLS.API);\n const result = await authApi.checkApiKey(apiKey);\n\n if (!result.success) {\n throw new AuthenticationError('Invalid API key');\n }\n\n return result.data!;\n}\n\n// ============================================================================\n// EMAIL OTP AUTHENTICATION FLOW\n// ============================================================================\n\n/**\n * Requests an OTP (One-Time Password) to be sent to the specified email.\n * The OTP will be valid for a limited time and can be used once.\n *\n * @param email - Email address to send OTP to\n * @returns Promise resolving to true if OTP sent successfully, false otherwise\n */\nexport async function requestEmailOTP(email: string): Promise<boolean> {\n try {\n const authApi = new AuthApi(BASE_URLS.AUTH);\n const result = await authApi.sendOtp(email);\n return result.success;\n } catch (error) {\n console.error('❌ Error requesting OTP:', error);\n return false;\n }\n}\n\n/**\n * Verifies an OTP code and retrieves a sign-in token.\n * The sign-in token can be used to generate an API key.\n *\n * @param email - Email address the OTP was sent to\n * @param pin - The OTP code received via email\n * @returns Promise resolving to sign-in token or null if verification failed\n */\nexport async function verifyOTPAndGetToken(email: string, pin: string): Promise<string | null> {\n try {\n const authApi = new AuthApi(BASE_URLS.AUTH);\n const result = await authApi.verifyOtp(email, pin);\n return result.success ? result.data!.signInToken : null;\n } catch (error) {\n console.error('❌ Error verifying OTP:', error);\n return null;\n }\n}\n\n/**\n * Generates a permanent API key using a sign-in token.\n * The sign-in token is obtained from successful OTP verification.\n *\n * @param signInToken - Token obtained from OTP verification\n * @returns Promise resolving to API key or null if generation failed\n */\nexport async function generateApiKey(signInToken: string): Promise<string | null> {\n try {\n const authApi = new AuthApi(BASE_URLS.AUTH);\n const result = await authApi.getApiKey(signInToken);\n return result.success ? result.data!.apiKey : null;\n } catch (error) {\n console.error('❌ Error generating API key:', error);\n return null;\n }\n}\n","/**\n * Constants for the compile command\n */\n\n// =============================================================================\n// PRIMITIVE SHIMS\n//\n// Passthrough shims for lua-cli primitives (define* functions and Lua* classes).\n// Used in two places:\n// - compiler/utils/ast-helpers.ts: fed to ts-evaluator so it can resolve\n// expressions like `defineTool({name: 'foo'})` at compile time\n// - utils/sandbox.ts: injected into the VM context so bundled code that\n// still references these names at runtime gets a no-op passthrough\n//\n// The define* functions return their config as-is.\n// The Lua* classes assign config properties to `this`.\n// =============================================================================\n\nclass PassthroughPrimitive {\n constructor(config: any) {\n Object.assign(this, config);\n }\n}\nconst passthroughDefine = (config: any) => config;\n\n/**\n * Map of all lua-cli primitive shims.\n * Single source of truth — add new primitives here.\n */\nexport const PRIMITIVE_SHIMS = {\n // Class-based constructors\n LuaTool: PassthroughPrimitive,\n LuaSkill: PassthroughPrimitive,\n LuaJob: PassthroughPrimitive,\n LuaWebhook: PassthroughPrimitive,\n PreProcessor: PassthroughPrimitive,\n LuaPreprocessor: PassthroughPrimitive,\n PostProcessor: PassthroughPrimitive,\n LuaPostprocessor: PassthroughPrimitive,\n LuaMCPServer: PassthroughPrimitive,\n // Function-based define patterns\n defineTool: passthroughDefine,\n defineSkill: passthroughDefine,\n defineJob: passthroughDefine,\n defineWebhook: passthroughDefine,\n definePreProcessor: passthroughDefine,\n definePostProcessor: passthroughDefine,\n defineMCPServer: passthroughDefine,\n};\n\n// =============================================================================\n// DIRECTORIES & FILES\n// =============================================================================\n\n/**\n * Directory names used during compilation\n */\nexport const COMPILE_DIRS = {\n DIST: 'dist',\n DIST_V2: 'dist-v2',\n LUA: '.lua',\n TOOLS: 'tools',\n} as const;\n\n/**\n * File names used during compilation\n */\nexport const COMPILE_FILES = {\n DEPLOYMENT_JSON: 'deployment.json',\n DEPLOY_JSON: 'deploy.json',\n MANIFEST_JSON: 'manifest.json',\n INDEX_TS: 'index.ts',\n INDEX_JS: 'index.js',\n PACKAGE_JSON: 'package.json',\n TSCONFIG_JSON: 'tsconfig.json',\n LUA_SKILL_YAML: 'lua.skill.yaml',\n} as const;\n\n/**\n * Default values for skill metadata\n */\nexport const SKILL_DEFAULTS = {\n NAME: 'lua-skill',\n VERSION: '1.0.0',\n DESCRIPTION: '',\n CONTEXT: '',\n} as const;\n\n/**\n * JSON formatting options\n */\nexport const JSON_FORMAT = {\n INDENT: 2,\n} as const;\n\n/**\n * YAML formatting options\n */\nexport const YAML_FORMAT = {\n INDENT: 2,\n LINE_WIDTH: -1,\n NO_REFS: true,\n} as const;\n","var __defProp = Object.defineProperty;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\n\n// src/persona-text.type.ts\nfunction isPersonaTextObject(value) {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) return false;\n const obj = value;\n for (const k of Object.keys(obj)) {\n if (k !== \"base\" && k !== \"voice\" && k !== \"text\") return false;\n if (obj[k] !== void 0 && typeof obj[k] !== \"string\") return false;\n }\n return true;\n}\n__name(isPersonaTextObject, \"isPersonaTextObject\");\nfunction flattenPersonaText(input, isVoice = false) {\n if (input == null) return \"\";\n if (typeof input === \"string\") return input;\n const parts = [];\n if (input.base) parts.push(input.base);\n const channelText = isVoice ? input.voice : input.text;\n if (channelText) parts.push(channelText);\n return parts.join(\"\\n\\n\");\n}\n__name(flattenPersonaText, \"flattenPersonaText\");\nfunction flattenPersonaTextAll(input) {\n if (input == null) return \"\";\n if (typeof input === \"string\") return input;\n const parts = [];\n if (input.base) parts.push(input.base);\n if (input.voice) parts.push(input.voice);\n if (input.text) parts.push(input.text);\n return parts.join(\"\\n\\n\");\n}\n__name(flattenPersonaTextAll, \"flattenPersonaTextAll\");\nfunction hasPersonaTextContent(input) {\n if (input == null) return false;\n if (typeof input === \"string\") return input.trim().length > 0;\n return Boolean(input.base?.trim() || input.voice?.trim() || input.text?.trim());\n}\n__name(hasPersonaTextContent, \"hasPersonaTextContent\");\nfunction personaToLiteral(persona) {\n const formatValue = /* @__PURE__ */ __name((v) => {\n if (v.includes(\"\\n\")) {\n return \"`\" + v.replace(/\\\\/g, \"\\\\\\\\\").replace(/`/g, \"\\\\`\").replace(/\\$/g, \"\\\\$\") + \"`\";\n }\n return '\"' + v.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"') + '\"';\n }, \"formatValue\");\n if (typeof persona === \"string\") return formatValue(persona);\n const parts = [];\n if (persona.base !== void 0) parts.push(`base: ${formatValue(persona.base)}`);\n if (persona.voice !== void 0) parts.push(`voice: ${formatValue(persona.voice)}`);\n if (persona.text !== void 0) parts.push(`text: ${formatValue(persona.text)}`);\n return `{ ${parts.join(\", \")} }`;\n}\n__name(personaToLiteral, \"personaToLiteral\");\n\n// src/unstructured-types.ts\nvar UNSTRUCTURED_SUPPORTED_MEDIA_TYPES = /* @__PURE__ */ new Set([\n // PDF\n \"application/pdf\",\n // Word processing (.doc, .docx, .dot, .dotm, .zabw)\n \"application/msword\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.template\",\n \"application/vnd.oasis.opendocument.text\",\n \"application/rtf\",\n \"text/rtf\",\n \"application/x-abiword\",\n // Spreadsheets (.xls, .xlsx, .fods, .csv, .tsv, .dbf, .et, .mw)\n \"application/vnd.ms-excel\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n \"application/vnd.oasis.opendocument.spreadsheet\",\n \"text/csv\",\n \"text/tab-separated-values\",\n \"application/dbase\",\n \"application/x-et\",\n // Presentations (.ppt, .pptx, .pptm, .pot)\n \"application/vnd.ms-powerpoint\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n \"application/vnd.openxmlformats-officedocument.presentationml.template\",\n // Images — OCR (.bmp, .heic, .jpeg, .jpg, .png, .prn, .tiff)\n \"image/jpeg\",\n \"image/jpg\",\n \"image/png\",\n \"image/tiff\",\n \"image/bmp\",\n \"image/heic\",\n // Email (.eml, .msg, .p7s)\n \"message/rfc822\",\n \"application/vnd.ms-outlook\",\n \"application/pkcs7-signature\",\n // Web/Markup (.htm, .html, .md, .rst, .xml, .org)\n \"text/html\",\n \"text/markdown\",\n \"text/x-rst\",\n \"text/x-org\",\n \"application/xml\",\n \"text/xml\",\n // Text (.txt)\n \"text/plain\",\n // eBook (.epub)\n \"application/epub+zip\",\n // Other (.hwp, .json, .cwk, .mcw, .dif, .sxg)\n \"application/json\",\n \"application/x-hwp\",\n \"application/clarisworks\",\n \"application/x-dif\",\n \"application/vnd.sun.xml.writer.global\"\n]);\n\n// src/ai-generate.utils.ts\nfunction aiGenerateInputFromSimplified(prompt, content) {\n if (content === void 0) {\n return {\n prompt\n };\n }\n return {\n system: prompt,\n messages: [\n {\n role: \"user\",\n content\n }\n ]\n };\n}\n__name(aiGenerateInputFromSimplified, \"aiGenerateInputFromSimplified\");\n\n// src/chat-history.types.ts\nfunction removeNavigateBlock(input) {\n return input.replace(/::: navigate[\\s\\S]*?:::/g, \"\").trim();\n}\n__name(removeNavigateBlock, \"removeNavigateBlock\");\nfunction transformChatHistoryContentParts(parts) {\n const content = [];\n for (const rawPart of parts ?? []) {\n const part = rawPart;\n if (part?.type !== \"text\" && part?.type !== \"file\") continue;\n if (part.type === \"text\" && typeof part.text === \"string\") {\n const rawText = part.text || \"\";\n if (rawText.includes(\"::: hide\")) continue;\n const audioMatch = rawText.match(/::: audio\\s*!\\[(.*?)\\]\\((.*?)\\)\\s*:::/);\n const videoMatch = rawText.match(/::: video\\s*!\\[(.*?)\\]\\((.*?)\\)\\s*:::/);\n if (audioMatch) {\n content.push({\n type: \"audio\",\n data: audioMatch[2],\n mediaType: audioMatch[1]\n });\n } else if (videoMatch) {\n content.push({\n type: \"video\",\n video: videoMatch[2],\n mediaType: videoMatch[1]\n });\n } else {\n let text = rawText.replace(/\\\\\\\\\\\\n/g, \"\\n\");\n text = removeNavigateBlock(text);\n content.push({\n type: \"text\",\n text\n });\n }\n } else if (part.type === \"file\") {\n const mediaType = part.mimeType || \"\";\n if (mediaType.startsWith(\"image/\")) {\n content.push({\n type: \"image\",\n image: part.data,\n mediaType\n });\n } else if (mediaType.startsWith(\"video/\")) {\n content.push({\n type: \"video\",\n video: part.data,\n mediaType\n });\n } else if (mediaType.startsWith(\"audio/\")) {\n content.push({\n type: \"audio\",\n data: part.data,\n mediaType\n });\n } else {\n content.push({\n type: \"file\",\n data: part.data,\n mediaType\n });\n }\n }\n }\n return content;\n}\n__name(transformChatHistoryContentParts, \"transformChatHistoryContentParts\");\n\n// src/sandbox-contract.ts\nvar REQUIRED_PRIMITIVE_SHIMS = [\n // Class-based\n \"LuaTool\",\n \"LuaSkill\",\n \"LuaJob\",\n \"LuaWebhook\",\n \"PreProcessor\",\n \"LuaPreprocessor\",\n \"PostProcessor\",\n \"LuaPostprocessor\",\n \"LuaMCPServer\",\n // Function-based\n \"defineTool\",\n \"defineSkill\",\n \"defineJob\",\n \"defineWebhook\",\n \"definePreProcessor\",\n \"definePostProcessor\",\n \"defineMCPServer\"\n];\nvar REQUIRED_PLATFORM_APIS = {\n User: [\n \"get\",\n \"getChatHistory\"\n ],\n Products: [\n \"get\",\n \"create\",\n \"delete\",\n \"search\",\n \"getById\"\n ],\n Baskets: [\n \"create\",\n \"get\",\n \"addItem\",\n \"removeItem\",\n \"clear\",\n \"updateStatus\",\n \"updateMetadata\",\n \"placeOrder\",\n \"getById\"\n ],\n Orders: [\n \"create\",\n \"updateStatus\",\n \"updateData\",\n \"get\",\n \"getById\"\n ],\n Data: [\n \"create\",\n \"get\",\n \"getEntry\",\n \"update\",\n \"search\",\n \"delete\"\n ],\n Jobs: [\n \"create\",\n \"getJob\",\n \"getAll\"\n ],\n AI: [\n \"generate\"\n ],\n Voice: [\n \"call\"\n ],\n // Lowercase alias so devs can write `this.voice.call(...)` from a top-level\n // execute body — at the script's top scope `this === globalThis`. Functionally\n // identical to `Voice` (same closure), so any drift between the two would be a\n // bug.\n voice: [\n \"call\"\n ],\n CDN: [\n \"upload\",\n \"get\"\n ]\n};\nvar REQUIRED_NESTED_APIS = {\n Templates: {\n whatsapp: [\n \"list\",\n \"get\",\n \"send\"\n ]\n },\n Lua: {\n request: [\n \"channel\"\n ]\n }\n};\nvar REQUIRED_ENUMS = {\n BasketStatus: [\n \"ACTIVE\",\n \"CHECKED_OUT\",\n \"ABANDONED\",\n \"EXPIRED\"\n ],\n OrderStatus: [\n \"PENDING\",\n \"CONFIRMED\",\n \"FULFILLED\",\n \"CANCELLED\"\n ]\n};\nvar REQUIRED_UTILITIES = [\n \"env\"\n];\n\n// src/client-tools.types.ts\nvar CLIENT_TOOL_PREFIX = \"client__\";\nvar CLIENT_TOOLS_MAX = 20;\n\n// src/persona-defaults.ts\nvar AGENT_NAME_TOKEN = \"[Your Agent Name]\";\nvar DEFAULT_PERSONA_GUIDE = `# ${AGENT_NAME_TOKEN} - Persona\n\nThis is a starting template to help you think about your agent's persona.\nUse it as-is, rearrange it, or replace it entirely with your own format \\u2014 whatever works best for your use case.\nThe sections below are suggestions, not requirements.\n\n## Identity & Role\nWho is your agent? What's their name and core purpose?\n- Give it a name and a clear one-line role\n- e.g. a customer support rep, a shopping assistant, an internal ops copilot, a scheduling bot\n\n## Business Context\nWhat company, product, or service does the agent represent? What does the business do?\n- Describe the business in a sentence or two so the agent understands the world it operates in\n- Include industry, value proposition, and anything the agent should \"know\" about the brand\n\n## Tone & Communication Style\nHow should the agent sound?\n- Formal or casual? Concise or detailed? Empathetic or matter-of-fact?\n- Should it match a specific brand voice or adapt to the user's tone?\n- Any language or cultural considerations (e.g. greetings, local expressions)?\n\n## Target Audience\nWho will the agent be talking to?\n- Describe the typical user: consumers, business customers, internal team members, etc.\n- What do they usually need help with? What matters most to them?\n\n## Capabilities\nWhat can the agent help with? List the main things it should handle.\n- e.g. answering product questions, placing orders, looking up account info, scheduling meetings\n- Be specific \\u2014 this shapes which skills and tools the agent will use\n\n## Boundaries\nWhat should the agent NOT do? When should it escalate to a human?\n- e.g. cannot process refunds, should not give medical/legal advice\n- Define when to hand off: frustrated user, request outside scope, sensitive data\n\n## Guidelines\nAny rules for how the agent behaves?\n- Response length limits (e.g. keep messages under 300 words)\n- Formatting preferences (e.g. use bullet points, avoid jargon)\n- Things to always or never do (e.g. always confirm before changes, never share internal IDs)\n\n---\nFeel free to add, remove, or rename sections. Your persona can be a single paragraph or a detailed playbook \\u2014 whatever gives your agent the context it needs.\n`;\nfunction buildDefaultPersona(agentName) {\n return DEFAULT_PERSONA_GUIDE.replace(AGENT_NAME_TOKEN, () => agentName || \"My Agent\");\n}\n__name(buildDefaultPersona, \"buildDefaultPersona\");\n\n// src/vm-execution-log.types.ts\nvar AGENT_LOG_SOURCES = [\n \"skill\",\n \"job\",\n \"webhook\",\n \"preprocessor\",\n \"postprocessor\",\n \"user_message\",\n \"agent_response\",\n \"agent_error\",\n \"runtime\",\n \"mcp\",\n \"rag\",\n \"device\",\n \"device-trigger\"\n];\n\n// src/luavoice.ts\nimport { z } from \"zod\";\nvar VoiceNameSchema = z.string().regex(/^[a-zA-Z0-9_-]+$/, \"Voice name must contain only alphanumeric characters, underscores, or hyphens\").min(1).max(64);\nvar PluginProviderSchema = z.enum([\n \"deepgram\",\n \"elevenlabs\"\n]);\nvar RealtimeProviderSchema = z.enum([\n \"openai\",\n \"google\",\n \"xai\"\n]);\nvar PluginClassSchema = z.enum([\n \"LLM\",\n \"STT\",\n \"STTv2\",\n \"TTS\"\n]);\nvar ModelDescriptorSchema = z.string().min(1).max(200);\nvar InferenceModelSchema = z.object({\n kind: z.literal(\"inference\"),\n /** Provider-prefixed model id (e.g. `'openai/gpt-5.2-chat-latest'`). */\n model: ModelDescriptorSchema,\n /**\n * TTS-only — provider voice id. Inference's TTS API takes voice\n * separately from model; LLM and STT ignore this field.\n */\n voice: z.string().min(1).max(200).optional(),\n /**\n * Additional Inference extras forwarded as constructor options. Loose\n * record by design — LiveKit's Inference surface evolves faster than\n * we want to chase, and we don't gate dev productivity on schema\n * updates here.\n */\n options: z.record(z.string(), z.unknown()).optional()\n});\nvar PluginModelSchema = z.object({\n kind: z.literal(\"plugin\"),\n provider: PluginProviderSchema,\n class: PluginClassSchema,\n /**\n * Forwarded verbatim to the plugin constructor (e.g. `new deepgram.STT(options)`).\n * Loose record because each provider's option surface is its own\n * schema, evolving independently. The factory passes these through\n * to the LiveKit plugin which is the source of truth for shape.\n */\n options: z.record(z.string(), z.unknown())\n});\nvar RealtimeModelSchema = z.object({\n kind: z.literal(\"realtime\"),\n provider: RealtimeProviderSchema,\n /**\n * Forwarded verbatim to `<provider>.realtime.RealtimeModel(options)`.\n * Each provider has its own surface (voice id, modalities, turn\n * detection, etc.). Loose record so devs can pass any option the\n * underlying plugin accepts without a schema chase.\n */\n options: z.record(z.string(), z.unknown())\n});\nvar LuaVoiceModelSchema = z.discriminatedUnion(\"kind\", [\n InferenceModelSchema,\n PluginModelSchema,\n RealtimeModelSchema\n]);\nvar TurnDetectionSchema = z.enum([\n \"multilingual\",\n \"english\",\n \"vad\",\n \"stt\",\n \"manual\"\n]);\nvar InterruptionSchema = z.object({\n enabled: z.boolean().optional(),\n mode: z.enum([\n \"adaptive\",\n \"vad\"\n ]).optional(),\n falseInterruptionTimeout: z.number().min(0).optional(),\n resumeFalseInterruption: z.boolean().optional(),\n minDelay: z.number().min(0).optional(),\n maxDelay: z.number().min(0).optional()\n}).superRefine((val, ctx) => {\n if (typeof val.minDelay === \"number\" && typeof val.maxDelay === \"number\" && val.minDelay > val.maxDelay) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `interruption.minDelay (${val.minDelay}) must be \\u2264 maxDelay (${val.maxDelay})`,\n path: [\n \"minDelay\"\n ]\n });\n }\n});\nvar BuiltinAudioClipSchema = z.enum([\n \"office-ambience\",\n \"keyboard-typing\",\n \"keyboard-typing-2\"\n]);\nvar AudioConfigSchema = z.object({\n source: BuiltinAudioClipSchema,\n volume: z.number().min(0).max(1).optional(),\n probability: z.number().min(0).max(1).optional()\n});\nvar BackgroundAudioEntrySchema = z.union([\n BuiltinAudioClipSchema,\n AudioConfigSchema,\n z.array(AudioConfigSchema)\n]);\nvar BackgroundAudioSchema = z.object({\n // Looping ambient sound played throughout the session. Common: 'office-ambience'.\n ambient: BackgroundAudioEntrySchema.optional(),\n // Sound played while the agent is in the thinking state (between user\n // turn end and TTS playback start). Common: 'keyboard-typing'.\n thinking: BackgroundAudioEntrySchema.optional()\n});\nvar LuaVoiceConfigInnerSchema = z.object({\n name: VoiceNameSchema.optional(),\n // The runtime brain. Three accepted shapes via the discriminated union:\n // - `kind: 'inference'` — LiveKit Inference (string descriptor route)\n // - `kind: 'plugin'` — direct provider plugin (Lua-held credits)\n // - `kind: 'realtime'` — speech-to-speech model in the LLM slot\n // STT and TTS are required for cascaded LLMs, optional for realtime\n // (full mode skips both; half-cascade keeps `tts`). Enforced by the\n // refine on the outer `LuaVoiceConfigSchema`.\n llm: LuaVoiceModelSchema,\n stt: LuaVoiceModelSchema.optional(),\n tts: LuaVoiceModelSchema.optional(),\n // Voice activity detection. 'silero' is the only supported value\n // today; declared as a string so future engines (e.g. WebRTC VAD)\n // don't require a schema change.\n vad: z.string().optional(),\n // Silero VAD tuning. All four knobs map 1:1 to the values\n // `silero.VAD.load(...)` accepts. Useful when the default\n // thresholds clip the start of speech on quiet callers, or when\n // the default endpointing fires too eagerly mid-thought. Omit any\n // field to take the SDK default.\n vadOptions: z.object({\n // Milliseconds of speech that must accumulate before a turn starts. SDK default: 50ms.\n minSpeechDuration: z.number().min(0).max(5e3).optional(),\n // Milliseconds of silence required to end a turn. SDK default: 550ms.\n minSilenceDuration: z.number().min(0).max(5e3).optional(),\n // Milliseconds of audio captured BEFORE the detected speech start —\n // forwarded into STT so the first phoneme isn't lost. SDK default: 500ms.\n prefixPaddingDuration: z.number().min(0).max(2e3).optional(),\n // 0-1; lower means more sensitive to speech onset (more\n // false-positives), higher means more conservative.\n activationThreshold: z.number().min(0).max(1).optional()\n }).strict().optional(),\n turnDetection: TurnDetectionSchema.optional(),\n // Spoken at session start via LiveKit's `session.generateReply` from\n // the agent's onEnter. Empty string treated as no greeting.\n greeting: z.string().optional(),\n // LiveKit AgentSession knobs.\n maxToolSteps: z.number().int().min(1).max(20).optional(),\n userAwayTimeout: z.number().min(0).optional(),\n preemptiveGeneration: z.boolean().optional(),\n interruption: InterruptionSchema.optional(),\n // BCP-47 language code or 'multi' for multilingual transcription.\n // Applies to both Inference STT and the deepgram plugin.\n sttLanguage: z.string().optional(),\n // Krisp BVC noise cancellation. Opt-in (default off) because LiveKit\n // bills it separately and not all channels need PSTN-grade suppression.\n krispEnabled: z.boolean().optional(),\n // Background audio — ambient + thinking sounds layered on the agent's\n // output. Each entry is a built-in clip name or a per-clip config; arrays\n // become probabilistic mixes (worker picks one per ambient loop / thinking\n // event). LiveKit's `BackgroundAudioPlayer` consumes the same shape.\n backgroundAudio: BackgroundAudioSchema.optional(),\n // Output speech volume (0-100). Applied as a per-frame multiplier in the\n // worker's compiled `ttsNode` override. Defaults to no adjustment when\n // omitted — letting the TTS provider's native level pass through.\n volume: z.number().int().min(0).max(100).optional(),\n // Word-boundary text replacements applied before TTS synthesis. The map\n // key is matched case-insensitively as a whole word; the value is the\n // spoken-form replacement. Provider-side SSML still works on top of this\n // — pronunciations is for the simple cases (e.g. `'API' → 'A P I'`,\n // `'kubectl' → 'kube control'`). Only effective on the cascaded path —\n // realtime models bypass `ttsNode` entirely.\n pronunciations: z.record(z.string(), z.string()).optional(),\n // When true, the worker writes `session.history` to `Data.set('call:<sessionId>')`\n // after the call ends. Read it back from a job/webhook with\n // `Data.get('call:<sessionId>')` to drive post-call analytics, follow-ups,\n // or QA workflows. Defaults to false — most calls don't need to keep\n // a transcript copy.\n persistTranscript: z.boolean().optional(),\n // Spoken acknowledgement played when a tool call fails. When a tool\n // throws, times out, or returns an unsupported result, the adapter calls\n // `session.say(text)` once per failed call before surfacing the error\n // to the LLM as a ToolError — fills the 2–3s gap before the LLM's own\n // recovery response. Persona-specific (keep it short and on-brand);\n // absent → no spoken fallback (the LLM's recovery is the only signal).\n onToolFailureSay: z.string().min(1).max(200).optional()\n});\nvar LuaVoiceConfigSchema = LuaVoiceConfigInnerSchema.superRefine((cfg, ctx) => {\n const isRealtime = cfg.llm.kind === \"realtime\";\n if (!isRealtime) {\n if (!cfg.stt) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\n \"stt\"\n ],\n message: \"stt is required when llm is not a realtime model\"\n });\n }\n if (!cfg.tts) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\n \"tts\"\n ],\n message: \"tts is required when llm is not a realtime model\"\n });\n }\n } else {\n if (cfg.stt) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\n \"stt\"\n ],\n message: \"stt cannot be set with a realtime llm \\u2014 realtime models handle audio input directly. Drop the stt field for full realtime, or use a cascaded llm if you need a separate STT.\"\n });\n }\n if (cfg.pronunciations && Object.keys(cfg.pronunciations).length > 0 && !cfg.tts) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\n \"pronunciations\"\n ],\n message: \"pronunciations require a TTS step; pair with a `tts` config (half-cascade mode) or drop the field for full realtime.\"\n });\n }\n }\n});\nvar LuaVoiceRefSchema = z.object({\n voiceId: z.string().min(1),\n version: z.string().optional()\n});\n\n// src/event-catalog.ts\nvar EventType = /* @__PURE__ */ (function(EventType2) {\n EventType2[\"AGENT_CREATED\"] = \"agent.created\";\n EventType2[\"CHANNEL_ADDED\"] = \"channel.added\";\n EventType2[\"MESSAGE_RECEIVED\"] = \"message.received\";\n EventType2[\"INQUIRY_CREATED\"] = \"inquiry.created\";\n EventType2[\"USER_LOGIN\"] = \"user.login\";\n EventType2[\"CREDIT_UPDATED\"] = \"credit.updated\";\n EventType2[\"CREDIT_PURCHASED\"] = \"credit.purchased\";\n EventType2[\"CREDIT_THRESHOLD_50\"] = \"credit.threshold.50\";\n EventType2[\"CREDIT_THRESHOLD_20\"] = \"credit.threshold.20\";\n EventType2[\"CREDIT_THRESHOLD_0\"] = \"credit.threshold.0\";\n EventType2[\"MESSAGE_SENT\"] = \"message.sent\";\n EventType2[\"MESSAGE_DELIVERED\"] = \"message.delivered\";\n EventType2[\"MESSAGE_READ\"] = \"message.read\";\n EventType2[\"MESSAGE_FAILED\"] = \"message.failed\";\n EventType2[\"MESSAGE_PLAYED\"] = \"message.played\";\n return EventType2;\n})({});\nexport {\n AGENT_LOG_SOURCES,\n CLIENT_TOOLS_MAX,\n CLIENT_TOOL_PREFIX,\n EventType,\n LuaVoiceConfigSchema,\n LuaVoiceModelSchema,\n LuaVoiceRefSchema,\n PluginProviderSchema,\n REQUIRED_ENUMS,\n REQUIRED_NESTED_APIS,\n REQUIRED_PLATFORM_APIS,\n REQUIRED_PRIMITIVE_SHIMS,\n REQUIRED_UTILITIES,\n RealtimeProviderSchema,\n UNSTRUCTURED_SUPPORTED_MEDIA_TYPES,\n aiGenerateInputFromSimplified,\n buildDefaultPersona,\n flattenPersonaText,\n flattenPersonaTextAll,\n hasPersonaTextContent,\n isPersonaTextObject,\n personaToLiteral,\n removeNavigateBlock,\n transformChatHistoryContentParts\n};\n","/**\n * Compilation Types\n *\n * All types related to the compilation process, plugins, and output manifest.\n * Uses discriminated unions for type-safe primitive handling.\n */\n\nimport type { GovernanceConfig, PersonaText, SkillContextText } from '@lua/shared-types';\nimport type { LuaVoiceModel } from '@lua/shared-types';\n\n// =============================================================================\n// COMPILER OPTIONS\n// =============================================================================\n\nexport interface CompilerOptions {\n /** Root directory of the project */\n rootDir: string;\n /** Output directory for artifacts */\n outDir: string;\n /** Enable source maps */\n sourceMaps?: boolean;\n /** Minify output */\n minify?: boolean;\n /** Enable debug mode (extra verbose logging, preserve temps) */\n debug?: boolean;\n /** Enable verbose output (show each primitive as it compiles) */\n verbose?: boolean;\n /** Skip validation warnings (still show errors) */\n quietWarnings?: boolean;\n /** Add runtime validation wrapper to artifacts (default: true) */\n runtimeValidation?: boolean;\n}\n\n// =============================================================================\n// COMPILATION RESULT\n// =============================================================================\n\nexport interface CompilationResult {\n success: boolean;\n manifest: CompilationManifest;\n errors: CompilationError[];\n warnings: CompilationWarning[];\n stats: CompilationStats;\n}\n\n/** Base for compilation messages (errors and warnings) */\ninterface CompilationMessageBase {\n primitive?: string;\n kind?: string;\n file: string;\n line?: number;\n message: string;\n}\n\nexport interface CompilationError extends CompilationMessageBase {\n column?: number;\n suggestion?: string;\n}\n\nexport interface CompilationWarning extends CompilationMessageBase {}\n\nexport interface CompilationStats {\n totalPrimitives: number;\n byKind: Record<string, number>;\n totalSize: number;\n duration: number;\n}\n\n// =============================================================================\n// SHARED PRIMITIVE IDENTITY\n// =============================================================================\n\n/** Core identity fields shared by all primitive representations */\ninterface PrimitiveIdentity {\n /** Primitive type (tool, job, webhook, etc.) */\n kind: string;\n /** Name from the definition */\n name: string;\n /** Description from the definition */\n description: string;\n /** Path to the source file */\n sourcePath: string;\n}\n\n// =============================================================================\n// PATTERN TYPES\n// =============================================================================\n\n/**\n * Pattern for primitive authoring shape.\n *\n * 'function' — `defineX({ ... })`\n * 'class' — `new LuaX({ ... })` (config-via-instantiation)\n * 'class-definition' — `class MyX extends LuaX { ... }` (subclass-with-field-override)\n */\nexport type DefinitionPattern = 'class' | 'function' | 'class-definition';\n\n// =============================================================================\n// PRIMITIVE METADATA\n// =============================================================================\n\n/** Base metadata fields that all primitives share */\nexport interface BaseMetadataFields {\n pattern?: string;\n}\n\n/** Common fields extracted by extractCommonFields() helper (excludes 'kind' which plugins add) */\nexport interface CommonExtractedFields extends Omit<PrimitiveIdentity, 'kind'> {\n exportName: string;\n isDefaultExport: boolean;\n line: number;\n column: number;\n}\n\n/** Metadata extracted from source code during scanning */\nexport interface PrimitiveMetadata<T extends BaseMetadataFields = BaseMetadataFields> extends PrimitiveIdentity {\n /** The export name in the source file (or 'default' for default exports) */\n exportName: string;\n /** Whether this primitive uses `export default` syntax */\n isDefaultExport: boolean;\n /** Line number in source (for error messages) */\n line?: number;\n /** Column number in source */\n column?: number;\n /** Type-specific metadata (typed per plugin) */\n metadata: T;\n}\n\n// =============================================================================\n// TYPED METADATA FIELDS (per primitive kind)\n// =============================================================================\n\nexport interface ToolMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n className?: string;\n hasInputSchema: boolean;\n hasCondition?: boolean;\n hasExecute?: boolean;\n}\n\nexport interface SkillMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n /** Tool variable/class names from the source (e.g., ['myTool', 'MyToolClass']) */\n toolRefs: string[];\n /**\n * Absolute source-file path where each tool ref was resolved by the\n * reference resolver, keyed by `className`. Populated when the ref\n * came through the resolver (which follows re-export barrels,\n * wildcard exports, path aliases) so the tool-resolution step can\n * skip a fresh — and simpler — `findImportSource` walk that doesn't\n * traverse those shapes. Absent entries fall back to the legacy\n * single-file import scan.\n *\n * Not emitted to the manifest — consumed by `resolveReferences()`\n * inside the compiler process only.\n */\n toolRefSourcePaths?: Record<string, string>;\n context?: SkillContextText;\n}\n\nexport interface JobMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n scheduleType?: string;\n scheduleExpression?: string;\n scheduleSeconds?: number;\n scheduleExecuteAt?: string;\n scheduleTimezone?: string;\n hasExecute?: boolean;\n hasTimeout?: boolean;\n hasRetry?: boolean;\n timeoutValue?: number;\n retryConfig?: { maxAttempts?: number; backoffSeconds?: number };\n}\n\nexport interface WebhookMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n hasExecute?: boolean;\n hasQuerySchema?: boolean;\n hasHeaderSchema?: boolean;\n hasBodySchema?: boolean;\n}\n\n/** Shared metadata for pre/post processors */\nexport interface ProcessorMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n hasExecute?: boolean;\n isAsync?: boolean;\n /** Execution priority (lower runs first; default 100). Read by lua-core's `ProcessorService`. */\n priority?: number;\n}\n\nexport type PreProcessorMetadataFields = ProcessorMetadataFields;\nexport type PostProcessorMetadataFields = ProcessorMetadataFields;\n\nexport interface MCPServerMetadataFields extends BaseMetadataFields {\n transport: 'stdio' | 'sse' | 'streamable-http';\n url?: string;\n hasUrlResolver?: boolean;\n hasHeadersResolver?: boolean;\n urlResolverSource?: string;\n headersResolverSource?: string;\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n config?: Record<string, unknown>;\n}\n\nexport interface DeviceTriggerMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n hasExecute?: boolean;\n hasPayloadSchema?: boolean;\n}\n\nexport interface DeviceMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n group?: string;\n}\n\nexport interface VoiceMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n /** Normalized discriminated union — `kind: 'inference' | 'plugin'`. */\n llm?: LuaVoiceModel;\n stt?: LuaVoiceModel;\n tts?: LuaVoiceModel;\n vad?: string;\n /** Silero VAD tuning forwarded to `silero.VAD.load(...)` on the worker. */\n vadOptions?: {\n minSpeechDuration?: number;\n minSilenceDuration?: number;\n prefixPaddingDuration?: number;\n activationThreshold?: number;\n };\n turnDetection?: string;\n greeting?: string;\n maxToolSteps?: number;\n userAwayTimeout?: number;\n preemptiveGeneration?: boolean;\n sttLanguage?: string;\n hasInterruption?: boolean;\n hasOnEnter?: boolean;\n hasOnUserTurnCompleted?: boolean;\n hasOnExit?: boolean;\n hasTools?: boolean;\n krispEnabled?: boolean;\n /** Background ambient + thinking sounds. Worker maps clip-name strings to BuiltinAudioClip. */\n backgroundAudio?: { ambient?: unknown; thinking?: unknown };\n /** Output volume 0-100. Applied per-frame in the compiled `ttsNode` override. */\n volume?: number;\n /** Pre-TTS word-boundary text replacements. Case-insensitive. */\n pronunciations?: Record<string, string>;\n /** Persist `session.history` to `Data['call:<sessionId>']` after the call ends. */\n persistTranscript?: boolean;\n /** Spoken phrase played once per failed tool call before the LLM's recovery response. */\n onToolFailureSay?: string;\n /**\n * LiveKit AgentSession `interruption` block. Captured as an object so\n * mode / falseInterruptionTimeout / minDelay / maxDelay actually reach\n * the worker — pre-fix only the boolean `hasInterruption` flag survived\n * the compiler→wire trip and the schema's defaults silently won.\n */\n interruption?: {\n enabled?: boolean;\n mode?: 'adaptive' | 'vad';\n falseInterruptionTimeout?: number;\n resumeFalseInterruption?: boolean;\n minDelay?: number;\n maxDelay?: number;\n };\n}\n\nexport interface AgentMetadataFields extends BaseMetadataFields {\n /** The agent's persona/system prompt */\n persona: PersonaText;\n /** Static model string (e.g., 'openai/gpt-4o') */\n model?: string;\n /** Whether the model property is a resolver function (bundled inside the artifact) */\n hasModelResolver?: boolean;\n /** Per-call sampling settings (temperature, topP, maxOutputTokens, …). Passthrough to Mastra. */\n modelSettings?: Record<string, unknown>;\n /** Per-agent message batching/debounce configuration */\n batching?: {\n firstMessageDelayMs?: number;\n debounceWindowMs?: number;\n maxBatchMessages?: number;\n serializeProcessing?: boolean;\n };\n /** Governance policy configuration */\n governance?: GovernanceConfig;\n /**\n * Identifiers the agent's `voices` array points at, in order. Resolved\n * to real LuaVoice names at manifest build time using `allPrimitives`.\n */\n voiceRefNames?: string[];\n /**\n * Resolver-discovered source file for each identifier in `voiceRefNames`.\n * Keyed by identifier (the local binding in the agent file). Mirrors\n * `SkillMetadataFields.toolRefSourcePaths` and lets `resolveVoiceRefs`\n * match against the voice primitive's `sourcePath` — necessary when the\n * voice is `export default new LuaVoice(...)`, where the local binding\n * (`mattVoice`) matches neither `exportName` (`default`) nor `name`\n * (`matt-line`). Stripped before persistence (absolute build-machine\n * paths must not land in deliverables — see `sanitizeForPersistence`).\n */\n voiceRefSourcePaths?: Record<string, string>;\n}\n\n// =============================================================================\n// TYPED METADATA ALIASES\n// =============================================================================\n\nexport type ToolMetadata = PrimitiveMetadata<ToolMetadataFields>;\nexport type SkillMetadata = PrimitiveMetadata<SkillMetadataFields>;\nexport type JobMetadata = PrimitiveMetadata<JobMetadataFields>;\nexport type WebhookMetadata = PrimitiveMetadata<WebhookMetadataFields>;\nexport type PreProcessorMetadata = PrimitiveMetadata<PreProcessorMetadataFields>;\nexport type PostProcessorMetadata = PrimitiveMetadata<PostProcessorMetadataFields>;\nexport type MCPServerMetadata = PrimitiveMetadata<MCPServerMetadataFields>;\nexport type DeviceTriggerMetadata = PrimitiveMetadata<DeviceTriggerMetadataFields>;\nexport type DeviceMetadata = PrimitiveMetadata<DeviceMetadataFields>;\nexport type AgentMetadata = PrimitiveMetadata<AgentMetadataFields>;\nexport type VoiceMetadata = PrimitiveMetadata<VoiceMetadataFields>;\n\n// =============================================================================\n// VALIDATION\n// =============================================================================\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationMessage[];\n warnings: ValidationMessage[];\n}\n\nexport interface ValidationMessage {\n message: string;\n line?: number;\n column?: number;\n suggestion?: string;\n docsUrl?: string;\n}\n\n// =============================================================================\n// SCHEMAS\n// =============================================================================\n\nexport interface JSONSchema {\n type?: string | string[];\n properties?: Record<string, JSONSchema>;\n required?: string[];\n items?: JSONSchema;\n enum?: unknown[];\n const?: unknown;\n description?: string;\n default?: unknown;\n minimum?: number;\n maximum?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n format?: string;\n additionalProperties?: boolean | JSONSchema;\n oneOf?: JSONSchema[];\n anyOf?: JSONSchema[];\n allOf?: JSONSchema[];\n $ref?: string;\n}\n\nexport interface SchemaSet {\n input?: JSONSchema;\n output?: JSONSchema;\n query?: JSONSchema;\n headers?: JSONSchema;\n body?: JSONSchema;\n [key: string]: JSONSchema | undefined;\n}\n\n// =============================================================================\n// BUNDLED ARTIFACT\n// =============================================================================\n\nexport interface BundledArtifact {\n code: string;\n sourceMap: string;\n originalSource: string;\n size: number;\n hash: string;\n}\n\n// =============================================================================\n// COMPILED PRIMITIVE\n// =============================================================================\n\nexport interface CompiledPrimitive extends PrimitiveMetadata {\n artifact: BundledArtifact;\n schemas?: SchemaSet;\n}\n\n// =============================================================================\n// PROJECT FILES\n// =============================================================================\n\nexport interface ProjectFile {\n /**\n * Path used both as the backup key and the on-disk restore location.\n *\n * For in-project files: path relative to `rootDir` (e.g. `src/index.ts`).\n * For external files (BAC-69): path relative to the workspace root\n * (e.g. `packages/shared/utils.ts`). These are also marked with\n * `external: true` so the restore step materializes them under\n * `.lua/external/<relativePath>` instead of escaping the project dir.\n */\n relativePath: string;\n hash: string;\n size: number;\n type: 'source' | 'config' | 'other';\n /**\n * Set to `true` for files that live outside `rootDir` but inside the\n * containing workspace (monorepo sibling packages). The compiler still\n * backs them up — otherwise `lua init --from-server` can't rebuild the\n * agent — but the restore step treats them specially so the contents\n * don't escape the project directory.\n *\n * Omitted (undefined) for in-project files to keep backup manifests\n * stable for non-monorepo agents.\n */\n external?: boolean;\n}\n\n// =============================================================================\n// COMPILER CONSTANTS\n// =============================================================================\n\n/** Manifest format version. Referenced by entry points, manifests, and minimal manifests. */\nexport const COMPILER_VERSION = '2.0.0';\n\n/** esbuild compilation target. Referenced by bundler and MCP resolver bundler. */\nexport const ESBUILD_TARGET = 'node18';\n\n// =============================================================================\n// MANIFEST PRIMITIVES\n// =============================================================================\n\nexport enum PrimitiveKind {\n TOOL = 'tool',\n SKILL = 'skill',\n JOB = 'job',\n WEBHOOK = 'webhook',\n PREPROCESSOR = 'preprocessor',\n POSTPROCESSOR = 'postprocessor',\n MCP_SERVER = 'mcp-server',\n AGENT = 'agent',\n DEVICE = 'device',\n DEVICE_TRIGGER = 'device-trigger',\n VOICE = 'voice',\n}\n\ninterface ManifestPrimitiveBase extends PrimitiveIdentity {\n /** Path to the compiled artifact */\n path: string;\n /** Content hash for cache invalidation */\n hash: string;\n}\n\nexport interface ManifestTool extends ManifestPrimitiveBase {\n kind: PrimitiveKind.TOOL;\n schemas?: { input?: JSONSchema; output?: JSONSchema };\n hasCondition?: boolean;\n}\n\nexport interface ManifestSkill extends ManifestPrimitiveBase {\n kind: PrimitiveKind.SKILL;\n context?: PersonaText;\n tools: string[];\n}\n\nexport interface ManifestJob extends ManifestPrimitiveBase {\n kind: PrimitiveKind.JOB;\n schedule?: { type: string; expression?: string; seconds?: number; executeAt?: string; timezone?: string };\n timeout?: number;\n retry?: { maxAttempts?: number; backoffSeconds?: number };\n metadata?: Record<string, unknown>;\n}\n\nexport interface ManifestWebhook extends ManifestPrimitiveBase {\n kind: PrimitiveKind.WEBHOOK;\n schemas?: { query?: JSONSchema; headers?: JSONSchema; body?: JSONSchema };\n}\n\nexport interface ManifestPreProcessor extends ManifestPrimitiveBase {\n kind: PrimitiveKind.PREPROCESSOR;\n isAsync?: boolean;\n /** Execution priority (lower runs first; default 100). Surfaces source-declared priority on push. */\n priority?: number;\n}\n\nexport interface ManifestPostProcessor extends ManifestPrimitiveBase {\n kind: PrimitiveKind.POSTPROCESSOR;\n /** Execution priority (lower runs first; default 100). Surfaces source-declared priority on push. */\n priority?: number;\n}\n\nexport interface ManifestMCPServer extends ManifestPrimitiveBase {\n kind: PrimitiveKind.MCP_SERVER;\n config?: Record<string, unknown>;\n /** Whether the url property is a resolver function (bundled in artifact) */\n hasUrlResolver?: boolean;\n /** Whether the headers property is a resolver function (bundled in artifact) */\n hasHeadersResolver?: boolean;\n}\n\nexport interface ManifestAgent extends ManifestPrimitiveBase {\n kind: PrimitiveKind.AGENT;\n persona: PersonaText;\n /** Static model string (e.g., 'openai/gpt-4o') */\n model?: string;\n /** Whether the model property is a resolver function (bundled in artifact) */\n hasModelResolver?: boolean;\n /** Per-call sampling settings (temperature, topP, maxOutputTokens, …). Passthrough to Mastra. */\n modelSettings?: Record<string, unknown>;\n /** Per-agent message batching/debounce configuration */\n batching?: {\n firstMessageDelayMs?: number;\n debounceWindowMs?: number;\n maxBatchMessages?: number;\n serializeProcessing?: boolean;\n };\n /** Governance policy configuration */\n governance?: GovernanceConfig;\n /**\n * Voices linked to this agent, in `voices: [...]` order. Each entry is a\n * primitive name; resolved to a server `voiceId` at push time. Each\n * channel picks which one fires via `channelConfig.<kind>.voiceId`.\n */\n voiceRefs?: { name: string }[];\n}\n\nexport interface ManifestDeviceTrigger extends ManifestPrimitiveBase {\n kind: PrimitiveKind.DEVICE_TRIGGER;\n schemas?: { payload?: JSONSchema };\n}\n\nexport interface ManifestDevice extends ManifestPrimitiveBase {\n kind: PrimitiveKind.DEVICE;\n group?: string;\n}\n\nexport interface ManifestVoice extends ManifestPrimitiveBase {\n kind: PrimitiveKind.VOICE;\n /** Normalized discriminated union — Inference (descriptor route) or direct plugin. */\n llm: LuaVoiceModel;\n // Optional for realtime LLMs: full mode skips both, half-cascade keeps only `tts`.\n stt?: LuaVoiceModel;\n tts?: LuaVoiceModel;\n vad?: string;\n /** Silero VAD tuning forwarded to `silero.VAD.load(...)` on the worker. */\n vadOptions?: {\n minSpeechDuration?: number;\n minSilenceDuration?: number;\n prefixPaddingDuration?: number;\n activationThreshold?: number;\n };\n turnDetection?: string;\n greeting?: string;\n maxToolSteps?: number;\n userAwayTimeout?: number;\n preemptiveGeneration?: boolean;\n sttLanguage?: string;\n /** Whether the LuaVoice declares an `interruption` config block. */\n hasInterruption?: boolean;\n /** Presence flags for lifecycle hooks declared on the LuaVoice. */\n hasOnEnter?: boolean;\n hasOnUserTurnCompleted?: boolean;\n hasOnExit?: boolean;\n /** Whether the LuaVoice declares voice-only tools (in addition to skill tools). */\n hasTools?: boolean;\n /** Krisp telephony BVC noise cancellation (opt-in). Resolver flips this on the wire response. */\n krispEnabled?: boolean;\n /** Ambient + thinking sounds. Worker resolves clip-name strings → BuiltinAudioClip. */\n backgroundAudio?: { ambient?: unknown; thinking?: unknown };\n /** Output volume 0-100. Applied per-frame in the compiled `ttsNode` override. */\n volume?: number;\n /** Pre-TTS word-boundary text replacements. Case-insensitive. */\n pronunciations?: Record<string, string>;\n /** When true, the worker writes `session.history` to `Data['call:<sessionId>']` on close. */\n persistTranscript?: boolean;\n /** Spoken phrase played once per failed tool call before the LLM's recovery response. */\n onToolFailureSay?: string;\n /** AgentSession interruption knobs — `mode`, `falseInterruptionTimeout`, etc. */\n interruption?: {\n enabled?: boolean;\n mode?: 'adaptive' | 'vad';\n falseInterruptionTimeout?: number;\n resumeFalseInterruption?: boolean;\n minDelay?: number;\n maxDelay?: number;\n };\n}\n\nexport type ManifestPrimitive =\n | ManifestTool\n | ManifestSkill\n | ManifestJob\n | ManifestWebhook\n | ManifestPreProcessor\n | ManifestPostProcessor\n | ManifestMCPServer\n | ManifestAgent\n | ManifestDevice\n | ManifestDeviceTrigger\n | ManifestVoice;\n\n// =============================================================================\n// COMPILATION MANIFEST\n// =============================================================================\n\nexport interface CompilationManifest {\n version: string;\n compiledAt: string;\n primitives: ManifestPrimitive[];\n projectFiles: ProjectFile[];\n config: { packageJson?: string; tsconfigJson?: string; luaSkillYaml?: string };\n}\n","import { DevVersionResponse, UpdateDevVersionResponse } from '../interfaces/dev.js';\nimport { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport {\n GetSkillsResponse,\n DeleteSkillResponse,\n CreateSkillRequest,\n CreateSkillResponse,\n PushSkillVersionRequest,\n GetSkillVersionsResponse,\n} from '../interfaces/skills.js';\nimport type {\n AttachSkillSourcePayload as AttachSkillSourceRequest,\n AttachSkillSourceResponse,\n} from '@lua/shared-source-sync';\n\n/**\n * Skill API calls\n */\nexport default class SkillApi extends HttpClient {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of SkillApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Retrieves all skills for the agent\n * @returns Promise resolving to an ApiResponse containing an array of skills with their versions and tools\n * @throws Error if the API request fails or the agent is not found\n */\n async getSkills(): Promise<ApiResponse<GetSkillsResponse>> {\n return this.httpGet<GetSkillsResponse>(`/developer/skills/${this.agentId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Creates a new skill for the agent\n * @param skillData - The skill data including name, description, and optional context\n * @returns Promise resolving to an ApiResponse containing the created skill details\n * @throws Error if the skill creation fails or validation errors occur\n */\n async createSkill(skillData: CreateSkillRequest): Promise<ApiResponse<CreateSkillResponse>> {\n return this.httpPost<CreateSkillResponse>(`/developer/skills/${this.agentId}`, skillData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Pushes a new version of a skill to production\n * @param skillId - The unique identifier of the skill\n * @param versionData - The version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the created version details\n * @throws Error if the skill is not found or the push operation fails\n */\n async pushSkill(skillId: string, versionData: PushSkillVersionRequest): Promise<ApiResponse<DevVersionResponse>> {\n return this.httpPost<DevVersionResponse>(`/developer/skills/${this.agentId}/${skillId}/version`, versionData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Pushes a new development/sandbox version of a skill for testing\n * @param skillId - The unique identifier of the skill\n * @param versionData - The version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the development version details\n * @throws Error if the skill is not found or the push operation fails\n */\n async pushDevSkill(skillId: string, versionData: PushSkillVersionRequest): Promise<ApiResponse<DevVersionResponse>> {\n return this.httpPost<DevVersionResponse>(\n `/developer/skills/${this.agentId}/${skillId}/version/sandbox`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Updates an existing development/sandbox version of a skill\n * @param skillId - The unique identifier of the skill\n * @param sandboxVersionId - The unique identifier of the sandbox version to update\n * @param versionData - The updated version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the updated version details\n * @throws Error if the skill or version is not found or the update fails\n */\n async updateDevSkill(\n skillId: string,\n sandboxVersionId: string,\n versionData: PushSkillVersionRequest\n ): Promise<ApiResponse<UpdateDevVersionResponse>> {\n return this.httpPut<UpdateDevVersionResponse>(\n `/developer/skills/${this.agentId}/${skillId}/version/sandbox/${sandboxVersionId}`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Retrieves all versions of a specific skill\n * @param skillId - The unique identifier of the skill\n * @returns Promise resolving to an ApiResponse containing an array of skill versions\n * @throws Error if the skill is not found or the request fails\n */\n async getSkillVersions(skillId: string): Promise<ApiResponse<GetSkillVersionsResponse>> {\n return this.httpGet<GetSkillVersionsResponse>(`/developer/skills/${this.agentId}/${skillId}/versions`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Publishes a specific version of a skill to production\n * @param skillId - The unique identifier of the skill\n * @param version - The version identifier to publish\n * @returns Promise resolving to an ApiResponse containing publication confirmation details\n * @throws Error if the skill or version is not found or the publish operation fails\n */\n async publishSkillVersion(\n skillId: string,\n version: string\n ): Promise<ApiResponse<{ message: string; skillId: string; activeVersionId: string; publishedAt: string }>> {\n return this.httpPut<{ message: string; skillId: string; activeVersionId: string; publishedAt: string }>(\n `/developer/skills/${this.agentId}/${skillId}/${version}/publish`,\n undefined,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Deletes a skill and all its versions, or deactivates it if it has versions\n * @param skillId - The unique identifier of the skill to delete\n * @returns Promise resolving to an ApiResponse with deletion status\n * - If deleted is true: skill was successfully deleted\n * - If deleted is false and deactivated is true: skill has versions and was deactivated instead\n * @throws Error if the skill is not found or the delete operation fails\n */\n async deleteSkill(skillId: string): Promise<ApiResponse<DeleteSkillResponse>> {\n return this.httpDelete<DeleteSkillResponse>(`/developer/skills/${this.agentId}/${skillId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Attach TS source + workspace archive to a skill version. Powers\n * `lua push --include-source` so the admin Builder UI can render the\n * source without waiting for the next UI-driven build.\n */\n async attachSkillSource(\n skillId: string,\n version: string,\n body: AttachSkillSourceRequest\n ): Promise<ApiResponse<AttachSkillSourceResponse>> {\n return this.httpPut<AttachSkillSourceResponse>(\n `/developer/skills/${this.agentId}/${skillId}/version/${encodeURIComponent(version)}/source`,\n body,\n { Authorization: `Bearer ${this.apiKey}` }\n );\n }\n}\n\nexport type { AttachSkillSourceRequest, AttachSkillSourceResponse };\n","/**\n * Artifact Loader Utilities\n *\n * Utilities for loading compilation artifacts from the new compiler output (dist-v2/).\n * Used by push, test, and dev commands.\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport zlib from 'zlib';\nimport type { PersonaText } from '@lua/shared-types';\nimport type { CompilationManifest, ManifestPrimitive, ManifestAgent } from '../compiler/types.js';\nimport { PrimitiveKind } from '../compiler/types.js';\nimport { COMPILE_DIRS, COMPILE_FILES } from '../config/compile.constants.js';\n\n// =============================================================================\n// MANIFEST LOADING\n// =============================================================================\n\n/**\n * Load the compilation manifest from dist-v2/manifest.json.\n *\n * @param projectPath - Path to the project root (defaults to cwd)\n * @returns The compilation manifest\n * @throws Error if manifest not found or invalid\n */\nexport function loadManifest(projectPath: string = process.cwd()): CompilationManifest {\n const manifestPath = path.join(projectPath, COMPILE_DIRS.DIST_V2, COMPILE_FILES.MANIFEST_JSON);\n\n if (!fs.existsSync(manifestPath)) {\n throw new Error(\n `Manifest not found at ${manifestPath}. ` + `Run \"lua compile\" first to generate the compilation output.`\n );\n }\n\n try {\n const content = fs.readFileSync(manifestPath, 'utf-8');\n return JSON.parse(content);\n } catch (error: any) {\n throw new Error(`Failed to parse manifest: ${error.message}`);\n }\n}\n\n/**\n * Check if the compilation output exists.\n *\n * @param projectPath - Path to the project root\n * @returns true if dist-v2/manifest.json exists\n */\nexport function hasCompilationOutput(projectPath: string = process.cwd()): boolean {\n const manifestPath = path.join(projectPath, COMPILE_DIRS.DIST_V2, COMPILE_FILES.MANIFEST_JSON);\n return fs.existsSync(manifestPath);\n}\n\n// =============================================================================\n// ARTIFACT LOADING\n// =============================================================================\n\n/**\n * Load a primitive artifact (bundled JS code) from disk.\n *\n * @param primitive - The primitive from the manifest\n * @param projectPath - Path to the project root\n * @returns The artifact code as a string\n */\nexport function loadArtifact(primitive: ManifestPrimitive, projectPath: string = process.cwd()): string {\n const artifactPath = path.join(projectPath, COMPILE_DIRS.DIST_V2, primitive.path);\n\n if (!fs.existsSync(artifactPath)) {\n throw new Error(`Artifact not found: ${artifactPath}`);\n }\n\n return fs.readFileSync(artifactPath, 'utf-8');\n}\n\n/**\n * Load a primitive artifact and its metadata JSON.\n *\n * @param primitive - The primitive from the manifest\n * @param projectPath - Path to the project root\n * @returns Object with code and metadata\n */\nexport function loadArtifactWithMetadata(\n primitive: ManifestPrimitive,\n projectPath: string = process.cwd()\n): { code: string; metadata: Record<string, any> } {\n const code = loadArtifact(primitive, projectPath);\n\n // Load metadata JSON (same name but .json extension)\n const metadataPath = path.join(\n projectPath,\n COMPILE_DIRS.DIST_V2,\n path.join(path.dirname(primitive.path), path.basename(primitive.path, '.js') + '.json')\n );\n\n let metadata = {};\n if (fs.existsSync(metadataPath)) {\n metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf-8'));\n }\n\n return { code, metadata };\n}\n\n/**\n * Load source map for a primitive (if it exists).\n *\n * @param primitive - The primitive from the manifest\n * @param projectPath - Path to the project root\n * @returns The source map string or null if not found\n */\nexport function loadSourceMap(primitive: ManifestPrimitive, projectPath: string = process.cwd()): string | null {\n const sourceMapPath = path.join(projectPath, COMPILE_DIRS.DIST_V2, primitive.path + '.map');\n\n if (!fs.existsSync(sourceMapPath)) {\n return null;\n }\n\n return fs.readFileSync(sourceMapPath, 'utf-8');\n}\n\n// =============================================================================\n// COMPRESSION (for push)\n// =============================================================================\n\n/**\n * Compress code for pushing to server.\n * Uses gzip + base64 encoding (matches server expectation).\n *\n * @param code - The artifact code to compress\n * @returns Base64-encoded gzipped code\n */\nexport function compressForPush(code: string): string {\n const compressed = zlib.gzipSync(Buffer.from(code, 'utf-8'));\n return compressed.toString('base64');\n}\n\n/**\n * Compress code for presigned S3 upload.\n * Returns raw gzip bytes (no base64 encoding).\n * Used with hashBundle and ensureBundlesUploaded for content-addressed upload.\n *\n * @param code - The artifact code to compress\n * @returns Raw gzipped bytes as Buffer\n */\nexport function compressForPushRaw(code: string): Buffer {\n return zlib.gzipSync(Buffer.from(code, 'utf-8'));\n}\n\n/**\n * Decompress code from server format.\n *\n * @param compressed - Base64-encoded gzipped code\n * @returns The decompressed code\n */\nexport function decompressFromServer(compressed: string): string {\n const buffer = Buffer.from(compressed, 'base64');\n const decompressed = zlib.gunzipSync(buffer);\n return decompressed.toString('utf-8');\n}\n\n// =============================================================================\n// SOURCE TS LOADING (for canonical-source attach)\n// =============================================================================\n\n/**\n * Forward-compat marker for the source-archive layout. Must stay in lockstep\n * with `ARCHIVE_SCHEMA_VERSION` in lua-claude-builder's\n * `canonical-source.archive.ts` — that constant is what the Builder reads when\n * deciding whether it understands an archive.\n */\nexport const SOURCE_ARCHIVE_SCHEMA_VERSION = 1;\n\n/** Maximum byte size of an individual file we'll archive — protects against accidentally archiving large blobs. Matches the Builder's MAX_FILE_BYTES guard. */\nconst MAX_SOURCE_FILE_BYTES = 256 * 1024;\n\n/**\n * Read a tool's original TS source file from disk, given its `sourcePath`\n * field on the manifest entry. Returns `null` when the file is missing or\n * unreadable so the caller can omit `tools[].source` rather than fail the\n * whole push — the server already treats absent source as \"not attached\"\n * (back-compat with older CLI clients).\n */\nexport function loadOriginalSource(sourcePath: string | undefined, projectPath: string = process.cwd()): string | null {\n if (!sourcePath) return null;\n try {\n const abs = path.isAbsolute(sourcePath) ? sourcePath : path.join(projectPath, sourcePath);\n if (!fs.existsSync(abs)) return null;\n const size = fs.statSync(abs).size;\n if (size > MAX_SOURCE_FILE_BYTES) return null;\n return fs.readFileSync(abs, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/**\n * Normalize a tool's `sourcePath` into a relative-to-project, posix-style key\n * suitable for a `sourceArchive` map. Idempotent for already-relative paths;\n * falls back to the bare `sourcePath` if normalization can't make it relative\n * (e.g. on a different drive on Windows). The archive consumer\n * (`canonical-source.archive.writeArchiveToWorkspace`) rejects any key\n * containing `..`, so we strip those defensively.\n */\nexport function normalizeEntryFile(sourcePath: string | undefined, projectPath: string = process.cwd()): string | null {\n if (!sourcePath) return null;\n let rel: string;\n if (path.isAbsolute(sourcePath)) {\n rel = path.relative(projectPath, sourcePath);\n } else {\n rel = sourcePath;\n }\n if (rel.startsWith('..') || rel.includes(`..${path.sep}`)) return null;\n return rel.split(path.sep).join('/');\n}\n\n/**\n * Build a sourceArchive payload (gzip(JSON.stringify({relPath: contents})) →\n * base64) from a list of `{ entryFile, source }` pairs. Format matches\n * `canonical-source.archive.decodeWorkspaceArchive` on the Builder side.\n *\n * Returns `null` when the file map is empty so the caller can omit the\n * `sourceArchive` field entirely (vs. shipping an archive that decodes to an\n * empty workspace, which the Builder treats identically but adds payload\n * weight for nothing).\n */\nexport function buildSourceArchive(files: Array<{ entryFile: string; source: string }>): string | null {\n if (files.length === 0) return null;\n const map: Record<string, string> = {};\n for (const { entryFile, source } of files) {\n if (entryFile.includes('..')) continue;\n map[entryFile] = source;\n }\n if (Object.keys(map).length === 0) return null;\n const json = JSON.stringify(map);\n const gz = zlib.gzipSync(Buffer.from(json, 'utf-8'));\n return gz.toString('base64');\n}\n\n// =============================================================================\n// PRIMITIVE FILTERING\n// =============================================================================\n\n/**\n * Get primitives of a specific kind from the manifest.\n *\n * @param manifest - The compilation manifest\n * @param kind - The primitive kind to filter by\n * @returns Array of primitives matching the kind\n */\nexport function getPrimitivesByKind<T extends ManifestPrimitive>(\n manifest: CompilationManifest,\n kind: PrimitiveKind\n): T[] {\n return manifest.primitives.filter((p) => p.kind === kind) as T[];\n}\n\n/**\n * Find a primitive by name and kind.\n *\n * @param manifest - The compilation manifest\n * @param name - The primitive name\n * @param kind - Optional kind to filter by\n * @returns The primitive or undefined\n */\nexport function findPrimitive<T extends ManifestPrimitive>(\n manifest: CompilationManifest,\n name: string,\n kind?: T['kind']\n): T | undefined {\n return manifest.primitives.find((p) => {\n if (kind && p.kind !== kind) return false;\n return p.name === name;\n }) as T | undefined;\n}\n\n// =============================================================================\n// SINGLE PRIMITIVE LOOKUP\n// =============================================================================\n\n/**\n * Find the first primitive of a given kind from the manifest.\n * Generic version — works for any primitive kind.\n */\nexport function getFirstPrimitiveByKind<T extends ManifestPrimitive>(\n kind: PrimitiveKind,\n projectPath: string = process.cwd()\n): T | null {\n if (!hasCompilationOutput(projectPath)) return null;\n const manifest = loadManifest(projectPath);\n return (manifest.primitives.find((p) => p.kind === kind) as T) ?? null;\n}\n\n// =============================================================================\n// AGENT CONVENIENCE (delegates to generic lookup)\n// =============================================================================\n\nexport function getAgentName(projectPath: string = process.cwd()): string | null {\n return getFirstPrimitiveByKind<ManifestAgent>(PrimitiveKind.AGENT, projectPath)?.name ?? null;\n}\n\nexport function getAgentPersona(projectPath: string = process.cwd()): PersonaText | null {\n return getFirstPrimitiveByKind<ManifestAgent>(PrimitiveKind.AGENT, projectPath)?.persona ?? null;\n}\n\nexport function getAgentModel(projectPath: string = process.cwd()): string | null {\n return getFirstPrimitiveByKind<ManifestAgent>(PrimitiveKind.AGENT, projectPath)?.model ?? null;\n}\n\nexport function getAgentGovernance(projectPath: string = process.cwd()): ManifestAgent['governance'] | null {\n return getFirstPrimitiveByKind<ManifestAgent>(PrimitiveKind.AGENT, projectPath)?.governance ?? null;\n}\n\n// =============================================================================\n// BATCH LOADING\n// =============================================================================\n\n/**\n * Load all artifacts of a specific kind.\n *\n * @param manifest - The compilation manifest\n * @param kind - The primitive kind\n * @param projectPath - Path to the project root\n * @returns Array of { primitive, code } objects\n */\nexport function loadAllArtifactsOfKind(\n manifest: CompilationManifest,\n kind: PrimitiveKind,\n projectPath: string = process.cwd()\n): Array<{ primitive: ManifestPrimitive; code: string }> {\n return getPrimitivesByKind(manifest, kind).map((primitive) => ({\n primitive,\n code: loadArtifact(primitive, projectPath),\n }));\n}\n","/**\n * Backup API Service\n *\n * Handles all backup-related API calls using S3 blob storage.\n * Content is stored in S3, keyed by content hash for deduplication.\n */\n\nimport { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport {\n BackupMetadata,\n BackupManifest,\n BackupExistsResponse,\n CheckBlobsRequest,\n CheckBlobsResponse,\n SaveManifestRequest,\n GetBlobUrlsRequest,\n GetBlobUrlsResponse,\n} from '../interfaces/backup.js';\n\nexport interface BackupVersionSummary {\n version: number;\n createdAt: string;\n createdBy: string;\n triggeredBy?: string;\n projectHash: string;\n}\n\nexport interface BackupVersionsResponse {\n versions: BackupVersionSummary[];\n}\n\n/**\n * Backup API client for project source backup operations\n */\nexport class BackupApi extends HttpClient {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of BackupApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n // ===========================================================================\n // BLOB OPERATIONS (S3)\n // ===========================================================================\n\n /**\n * Check which blobs exist in S3.\n * Called first to determine which files need to be uploaded.\n *\n * @param hashes - Array of content hashes to check\n * @returns Promise resolving to missing/existing hash lists\n */\n async checkBlobsExist(hashes: string[]): Promise<ApiResponse<CheckBlobsResponse>> {\n const data: CheckBlobsRequest = { hashes };\n return this.httpPost<CheckBlobsResponse>(`/developer/agents/${this.agentId}/backup/check-blobs`, data, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Get presigned URLs for downloading blobs from S3.\n * Used by download to fetch files in parallel directly from S3.\n *\n * @param hashes - Array of content hashes to get URLs for\n * @returns Promise resolving to map of hash -> presigned URL\n */\n async getBlobUrls(hashes: string[]): Promise<ApiResponse<GetBlobUrlsResponse>> {\n const data: GetBlobUrlsRequest = { hashes };\n return this.httpPost<GetBlobUrlsResponse>(`/developer/agents/${this.agentId}/backup/blob-urls`, data, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Get presigned URLs for uploading blobs directly to S3.\n * Used by push to upload files in parallel directly to S3, bypassing the server.\n *\n * @param hashes - Array of content hashes to get upload URLs for\n * @returns Promise resolving to map of hash -> presigned upload URL\n */\n async getBlobUploadUrls(hashes: string[]): Promise<ApiResponse<GetBlobUrlsResponse>> {\n const data: GetBlobUrlsRequest = { hashes };\n return this.httpPost<GetBlobUrlsResponse>(`/developer/agents/${this.agentId}/backup/blob-upload-urls`, data, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n // ===========================================================================\n // MANIFEST OPERATIONS (MongoDB)\n // ===========================================================================\n\n /**\n * Save backup manifest after blobs are uploaded.\n * Final step in the backup flow.\n *\n * @param data - Manifest data with file references\n * @returns Promise resolving to backup metadata\n */\n async saveManifest(data: SaveManifestRequest): Promise<ApiResponse<BackupMetadata>> {\n return this.httpPost<BackupMetadata>(`/developer/agents/${this.agentId}/backup/manifest`, data, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Get backup metadata without file list.\n * Used to check if backup exists and get basic info.\n *\n * @returns Promise resolving to backup metadata\n */\n async getBackupMetadata(): Promise<ApiResponse<BackupMetadata>> {\n return this.httpGet<BackupMetadata>(`/developer/agents/${this.agentId}/backup`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Get backup manifest with file list.\n * Use getBlobUrls to get download URLs for the content.\n *\n * @returns Promise resolving to backup manifest with file refs\n */\n async getBackupManifest(): Promise<ApiResponse<BackupManifest>> {\n return this.httpGet<BackupManifest>(`/developer/agents/${this.agentId}/backup/manifest`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Check if backup with given hash exists.\n * Allows skipping upload if backup is already up-to-date.\n *\n * @param hash - Project hash to check\n * @returns Promise resolving to existence check result\n */\n async checkBackupExists(hash: string): Promise<ApiResponse<BackupExistsResponse>> {\n return this.httpGet<BackupExistsResponse>(`/developer/agents/${this.agentId}/backup/check/${hash}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Get the list of backup versions for this agent.\n *\n * @param all - If true, lifts the server-side 50-version cap\n * @returns Promise resolving to the list of version summaries (newest first)\n */\n async getBackupVersions(all = false): Promise<ApiResponse<BackupVersionsResponse>> {\n const qs = all ? '?all=true' : '';\n return this.httpGet<BackupVersionsResponse>(`/developer/agents/${this.agentId}/backup/versions${qs}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n}\n\n// Named re-export for backward-compat consumers that do `import BackupApi from ...`\nexport default BackupApi;\n","/**\n * Bundle Upload Utilities\n *\n * Handles hashing, existence checking, and S3 presigned upload for primitive code bundles.\n * Enables content-addressed deduplication and delta uploads.\n */\n\nimport crypto from 'crypto';\nimport BackupApi from '../api/backup.api.service.js';\nimport { BASE_URLS } from '../config/constants.js';\n\n/**\n * Computes SHA256 hash over raw gzipped bytes.\n *\n * @param rawGzip - Raw gzipped bundle bytes (Buffer from compressForPushRaw)\n * @returns SHA256 hex digest\n */\nexport function hashBundle(rawGzip: Buffer): string {\n return crypto.createHash('sha256').update(rawGzip).digest('hex');\n}\n\n/**\n * Telemetry stats returned by `ensureBundlesUploaded` so call sites can\n * report delta-upload hit rate (existed in S3 vs newly uploaded) without\n * having to re-derive the partition.\n */\nexport interface BundleUploadStats {\n /** Total distinct hashes the push asked about. */\n total: number;\n /** Hashes the server confirmed already existed in S3 (no PUT issued). */\n alreadyExisted: number;\n /** Hashes that required an actual PUT to S3. */\n uploaded: number;\n}\n\n/**\n * Ensures all bundles are uploaded to S3 via presigned URLs.\n * Handles the full flow:\n * 1. Call /developer/agents/{agentId}/backup/blob-upload-urls to mint URLs\n * 2. Call /developer/agents/{agentId}/backup/check-blobs to determine missing/existing partition\n * 3. For each missing hash, PUT raw gzip bytes to presigned URL\n * 4. Resolve on success; throw with hash + status on any PUT failure\n *\n * @param apiKey - API key for authentication\n * @param agentId - Agent ID for the presigned URL endpoint\n * @param bundles - Map of hash → raw gzip Buffer bytes\n * @returns Stats covering total / alreadyExisted / uploaded for telemetry\n * @throws Error with hash and status if any PUT fails\n */\nexport async function ensureBundlesUploaded(\n apiKey: string,\n agentId: string,\n bundles: Map<string, Buffer>\n): Promise<BundleUploadStats> {\n // Empty map — nothing to upload\n if (bundles.size === 0) {\n return { total: 0, alreadyExisted: 0, uploaded: 0 };\n }\n\n const api = new BackupApi(BASE_URLS.API, apiKey, agentId);\n const hashes = Array.from(bundles.keys());\n\n // Step 1: Get presigned URLs\n const urlResponse = await api.getBlobUploadUrls(hashes);\n\n if (!urlResponse.success) {\n throw new Error(`Failed to get presigned upload URLs: ${urlResponse.error?.message}`);\n }\n\n const uploadUrls = urlResponse.data!.urls;\n\n // Step 2: Check which blobs already exist in S3\n const existsResponse = await api.checkBlobsExist(hashes);\n\n if (!existsResponse.success) {\n throw new Error(`Failed to check blob existence: ${existsResponse.error?.message}`);\n }\n\n const missing = existsResponse.data!.missing;\n\n // Step 3: Upload missing bundles with bounded parallelism via a worker-pool\n // (queue + N workers). Avoids the polling latency of a busy-wait semaphore\n // and stops as soon as the queue is drained.\n const concurrencyLimit = 8;\n const queue = [...missing];\n\n const uploadOne = async (hash: string): Promise<void> => {\n const url = uploadUrls[hash];\n if (!url) {\n throw new Error(`No presigned URL provided for hash ${hash}`);\n }\n const rawGzip = bundles.get(hash);\n if (!rawGzip) {\n throw new Error(`Bundle buffer not found for hash ${hash}`);\n }\n const response = await fetch(url, {\n method: 'PUT',\n body: rawGzip,\n headers: { 'Content-Type': 'application/octet-stream' },\n });\n if (!response.ok) {\n throw new Error(`S3 PUT failed for hash ${hash}: ${response.status} ${response.statusText}`);\n }\n };\n\n const workers = Array.from({ length: Math.min(concurrencyLimit, queue.length) }, async () => {\n while (queue.length > 0) {\n const hash = queue.shift();\n if (hash !== undefined) {\n await uploadOne(hash);\n }\n }\n });\n\n await Promise.all(workers);\n\n return {\n total: hashes.length,\n alreadyExisted: hashes.length - missing.length,\n uploaded: missing.length,\n };\n}\n","/**\n * Semantic Versioning Utilities\n */\n\n/**\n * Parses a semantic version string into its components.\n * Supports standard semver (X.Y.Z) and pre-release tags (X.Y.Z-tag).\n *\n * @param version The version string to parse\n * @returns Object containing major, minor, patch, and preRelease components\n */\nexport function parseVersion(version: string) {\n const [versionPart, preReleasePart] = version.split('-');\n const [major, minor, patch] = versionPart.split('.').map(Number);\n const preRelease = preReleasePart ? preReleasePart.split('+')[0] : null;\n\n return {\n major: isNaN(major) ? 0 : major,\n minor: isNaN(minor) ? 0 : minor,\n patch: isNaN(patch) ? 0 : patch,\n preRelease,\n };\n}\n\n/**\n * Compares two semantic version strings.\n *\n * @param version1 First version string\n * @param version2 Second version string\n * @returns number:\n * - negative if version1 < version2\n * - positive if version1 > version2\n * - 0 if version1 === version2\n */\nexport function compareVersions(version1: string, version2: string): number {\n const v1 = parseVersion(version1);\n const v2 = parseVersion(version2);\n\n // Compare major.minor.patch first\n if (v1.major !== v2.major) return v1.major - v2.major;\n if (v1.minor !== v2.minor) return v1.minor - v2.minor;\n if (v1.patch !== v2.patch) return v1.patch - v2.patch;\n\n // If major.minor.patch are equal, compare pre-release identifiers\n // A version without a pre-release tag is always greater than one with a tag\n if (v1.preRelease && !v2.preRelease) return -1; // pre-release is lower than release\n if (!v1.preRelease && v2.preRelease) return 1; // release is higher than pre-release\n if (!v1.preRelease && !v2.preRelease) return 0; // both are releases\n\n // Both have pre-release identifiers, compare them\n const preReleaseOrder = ['alpha', 'beta', 'rc', 'preview', 'dev'];\n\n const getPreReleaseType = (preRelease: string) => {\n // Extract the type part (e.g., \"alpha\" from \"alpha.1\")\n const type = preRelease.toLowerCase().split('.')[0].replace(/[0-9]/g, '');\n const index = preReleaseOrder.indexOf(type);\n return index === -1 ? preReleaseOrder.length : index; // Unknown types go to end\n };\n\n const type1 = getPreReleaseType(v1.preRelease!);\n const type2 = getPreReleaseType(v2.preRelease!);\n\n if (type1 !== type2) return type1 - type2;\n\n // Same pre-release type, compare the full pre-release string lexicographically\n // or try to compare numeric parts if they exist (e.g., alpha.1 vs alpha.2)\n const getPreReleaseNum = (preRelease: string) => {\n const parts = preRelease.split('.');\n const num = parts.length > 1 ? parseInt(parts[parts.length - 1], 10) : -1;\n return isNaN(num) ? -1 : num;\n };\n\n const num1 = getPreReleaseNum(v1.preRelease!);\n const num2 = getPreReleaseNum(v2.preRelease!);\n\n if (num1 !== -1 && num2 !== -1 && num1 !== num2) {\n return num1 - num2;\n }\n\n return v1.preRelease!.localeCompare(v2.preRelease!);\n}\n\n/**\n * Increments the patch version automatically (e.g., 1.0.0 → 1.0.1).\n * Preserves pre-release tag if present.\n *\n * @param version - Current version string (or undefined/null for first version)\n * @returns Incremented version string\n */\nexport function incrementPatchVersion(version: string | undefined | null): string {\n // Handle undefined/null version - return default starting version\n if (!version) {\n return '0.0.1';\n }\n\n const parsed = parseVersion(version);\n const newPatch = parsed.patch + 1;\n const preRelease = parsed.preRelease ? `-${parsed.preRelease}` : '';\n\n return `${parsed.major}.${parsed.minor}.${newPatch}${preRelease}`;\n}\n\n/**\n * Returns the higher of two semantic version strings.\n */\nexport function maxSemver(a: string, b: string): string {\n return compareVersions(a, b) >= 0 ? a : b;\n}\n","/**\n * Base Primitive Handler\n *\n * Abstract base class providing common implementation for primitive handlers.\n * Subclasses implement primitive-specific logic (API calls, active checks, etc.)\n *\n * YAML types come from yaml.types.ts (YamlConfigSkill, YamlConfigWebhook, etc.)\n * Server types come from interfaces/ (Skill, Webhook, Job, etc.)\n */\n\nimport { PrimitiveKind, CompilationManifest, ManifestPrimitive } from '../compiler/types.js';\nimport { YamlConfig } from '../types/yaml.types.js';\nimport { readYamlConfig, writeYamlConfig } from '../utils/files.js';\nimport { SKILL_DEFAULTS } from '../config/compile.constants.js';\nimport {\n findPrimitive,\n loadArtifact,\n compressForPush,\n compressForPushRaw,\n getPrimitivesByKind,\n} from '../utils/artifact-loader.js';\nimport { hashBundle } from '../utils/bundle-upload.js';\nimport { maxSemver } from '../utils/semver.js';\nimport { AuthenticationError } from '../errors/auth.error.js';\nimport type {\n VersionedPrimitiveHandler,\n PrimitiveHandler,\n SyncResult,\n ServerSyncData,\n YamlPrimitiveConfig,\n} from './types.js';\n\n/** Default version for new primitives */\nexport const DEFAULT_VERSION = SKILL_DEFAULTS.VERSION;\n\n// =============================================================================\n// BASE VERSIONED HANDLER\n// =============================================================================\n\n/**\n * Abstract base class for versioned primitive handlers.\n *\n * T = the YAML item type (from yaml.types.ts, e.g. YamlConfigSkill).\n * Must have at least { name: string; version: string; [idField]: string }.\n */\nexport abstract class BaseVersionedHandler<\n T extends { name: string; version: string },\n TPushData = Record<string, unknown>,\n> implements VersionedPrimitiveHandler<T> {\n abstract readonly kind: PrimitiveKind;\n abstract readonly displayName: string;\n abstract readonly displayNamePlural: string;\n abstract readonly deleteCommand: string;\n abstract readonly yamlConfig: YamlPrimitiveConfig;\n\n protected abstract getApi(apiKey: string, agentId: string): unknown;\n protected abstract fetchFromServer(api: unknown): Promise<any[] | null>;\n /**\n * Strip a YAML item to only the canonical fields: name, version, [idField].\n * Override if your YAML type has additional fields.\n */\n cleanItem(item: T): T {\n return {\n name: item.name || '',\n version: item.version || DEFAULT_VERSION,\n [this.yamlConfig.idField]: this.getItemId(item) || '',\n } as T;\n }\n\n /**\n * Whether a server entity is considered active (for orphan detection).\n * Default: true. Override for primitives with active/status fields.\n */\n isActive(_serverItem: any): boolean {\n return true;\n }\n\n /**\n * Get the active version string from a server entity.\n * Default: finds version with isActive === true. Override for different field names.\n */\n getActiveVersion(serverItem: any): string | null {\n const active = serverItem.versions?.find((v: any) => v.isActive === true);\n return active?.version ?? null;\n }\n\n protected getServerItemName(item: any): string {\n return item.name || 'unknown';\n }\n\n protected shouldConsiderForOrphan(_item: any): boolean {\n return true;\n }\n\n // ===========================================================================\n // SERVER SYNC\n // ===========================================================================\n\n /**\n * Fetches server items and merges with local YAML for interactive delete/trigger prompts.\n * Local items take priority for shared IDs; server-only orphans are appended as minimal\n * cleanItem objects. On server failure, returns local items only with an empty orphan set.\n */\n async fetchMergedForInteraction(\n apiKey: string,\n agentId: string,\n config: YamlConfig\n ): Promise<{ merged: T[]; orphanIds: Set<string>; serverFailed: boolean }> {\n const serverData = await this.fetchServerState(apiKey, agentId);\n const localItems = this.getFromYaml(config);\n\n if (!serverData.serverItems) {\n return { merged: localItems, orphanIds: new Set<string>(), serverFailed: true };\n }\n\n const serverItems = serverData.serverItems;\n const orphanIds = new Set(\n serverItems.filter((s) => !localItems.some((l) => this.getItemId(l) === s.id)).map((s) => s.id as string)\n );\n\n const merged = serverItems.map((s) => {\n const local = localItems.find((l) => this.getItemId(l) === s.id);\n if (local) return local;\n return this.cleanItem({\n name: s.name,\n version: this.getActiveVersion(s) ?? '',\n [this.yamlConfig.idField]: s.id,\n } as unknown as T);\n });\n\n return { merged, orphanIds, serverFailed: false };\n }\n\n /** Phase 1 of parallel sync: fetch server state (HTTP only, no YAML writes) */\n async fetchServerState(apiKey: string, agentId: string): Promise<ServerSyncData> {\n try {\n const api = this.getApi(apiKey, agentId);\n const serverItems = await this.fetchFromServer(api);\n return { serverItems };\n } catch (error) {\n if (AuthenticationError.isAuthenticationError(error)) throw error;\n return { serverItems: null, fetchError: error instanceof Error ? error.message : String(error) };\n }\n }\n\n /**\n * Phase 2 of parallel sync: apply fetched data to YAML.\n * Optionally creates missing primitives on server if apiKey+agentId provided.\n */\n async applySyncToYaml(\n serverData: ServerSyncData,\n config: YamlConfig | null,\n manifest?: CompilationManifest,\n apiCredentials?: { apiKey: string; agentId: string }\n ): Promise<SyncResult> {\n const messages: string[] = [];\n let yamlUpdated = false;\n let orphanedCount = 0;\n\n try {\n if (!serverData.serverItems) {\n if (serverData.fetchError) {\n console.error(`❌ Error syncing server ${this.displayNamePlural}: ${serverData.fetchError}`);\n } else {\n console.warn(`⚠️ Could not retrieve server ${this.displayNamePlural}. Skipping sync.`);\n }\n return { messages, yamlUpdated, orphanedCount };\n }\n\n const yamlItems = this.getFromYaml(config);\n const { yamlById, yamlByName, serverByName } = this.buildMaps(serverData.serverItems, yamlItems);\n\n // Part 1: Detect orphaned items\n const orphans = serverData.serverItems.filter((item) => {\n const id = item.id as string;\n const name = item.name as string;\n return !yamlById.has(id) && !yamlByName.has(name) && this.isActive(item) && this.shouldConsiderForOrphan(item);\n });\n\n if (orphans.length > 0) {\n // Stub server-only primitives into YAML so `lua sync` can classify them\n // as `missing-locally` and resolve them via backup restore.\n const idField = this.yamlConfig.idField;\n const stubs = orphans.map((item) =>\n this.cleanItem({\n name: item.name,\n version: this.getActiveVersion(item) || DEFAULT_VERSION,\n [idField]: item.id || '',\n } as unknown as T)\n );\n\n yamlItems.push(...stubs);\n yamlUpdated = true;\n\n const flagName = `--${this.displayName.toLowerCase().replace(/\\s+/g, '-')}-name`;\n console.log(`\\n⚠️ Found ${this.displayNamePlural} on server not in your local code:`);\n for (const item of orphans) {\n const msg = ` - ${this.getServerItemName(item)}`;\n messages.push(msg);\n console.log(msg);\n }\n console.log(` Added to lua.skill.yaml as server-only entries.`);\n console.log(` To remove from server: ${this.deleteCommand} ${flagName} <name>`);\n console.log(` To restore source from backup: lua sync --accept\\n`);\n orphanedCount = orphans.length;\n }\n\n // Part 2: Sync IDs and versions from server → YAML\n const { items: updatedItems, changed, msgs } = this.syncFromServer(yamlItems, serverByName);\n messages.push(...msgs);\n\n if (changed) {\n yamlUpdated = true;\n console.log(`✅ YAML ${this.displayNamePlural} synced with server`);\n }\n\n if (yamlUpdated) {\n this.updateYaml(updatedItems, config);\n }\n\n // Part 3: Create primitives that don't exist on server (if manifest + credentials provided)\n if (manifest && apiCredentials) {\n const api = this.getApi(apiCredentials.apiKey, apiCredentials.agentId);\n const { created, updated: creationUpdated } = await this.createMissingOnServer(api, manifest);\n if (created.length > 0) {\n messages.push(...created.map((name) => `Created \"${name}\" on server`));\n yamlUpdated = yamlUpdated || creationUpdated;\n }\n }\n\n if (orphans.length === 0 && !changed) {\n console.log(`✅ Server ${this.displayNamePlural} and YAML are fully in sync`);\n }\n } catch (error) {\n console.error(`❌ Error syncing server ${this.displayNamePlural}:`, error);\n }\n\n return { messages, yamlUpdated, orphanedCount };\n }\n\n async syncWithServer(\n apiKey: string,\n agentId: string,\n config: YamlConfig | null,\n manifest?: CompilationManifest\n ): Promise<SyncResult> {\n const serverData = await this.fetchServerState(apiKey, agentId);\n return this.applySyncToYaml(serverData, config, manifest, { apiKey, agentId });\n }\n\n // ===========================================================================\n // CREATE ON SERVER\n // ===========================================================================\n\n /**\n * Create a primitive on the server. Subclasses must implement this.\n * @param api - The API instance\n * @param primitive - The manifest primitive with name, description, and type-specific fields\n * @returns The server-assigned ID for the created primitive, or null on failure.\n */\n protected abstract createOnServer(api: unknown, primitive: ManifestPrimitive): Promise<string | null>;\n\n /**\n * Create primitives that have empty IDs in YAML.\n * Called internally by syncWithServer when manifest is provided.\n */\n private async createMissingOnServer(\n api: unknown,\n manifest: CompilationManifest\n ): Promise<{ created: string[]; updated: boolean }> {\n const created: string[] = [];\n let updated = false;\n\n const config = readYamlConfig();\n const items = this.getFromYaml(config);\n const itemsWithoutId = items.filter((item) => !this.getItemId(item));\n\n if (itemsWithoutId.length === 0) {\n return { created, updated };\n }\n\n console.log(`\\n🔧 Creating ${itemsWithoutId.length} new ${this.displayNamePlural} on server...`);\n\n for (const item of itemsWithoutId) {\n // Find the primitive in the manifest to get description and other metadata\n const manifestPrimitive = findPrimitive(manifest, item.name, this.kind);\n if (!manifestPrimitive) {\n console.error(` ❌ \"${item.name}\" not found in manifest - cannot create`);\n continue;\n }\n\n try {\n const newId = await this.createOnServer(api, manifestPrimitive);\n if (newId) {\n // Update the item with the new ID\n const updatedConfig = readYamlConfig();\n const updatedItems = this.getFromYaml(updatedConfig);\n const idx = updatedItems.findIndex((i) => i.name === item.name);\n if (idx >= 0) {\n (updatedItems[idx] as Record<string, unknown>)[this.yamlConfig.idField] = newId;\n this.updateYaml(updatedItems, updatedConfig);\n updated = true;\n }\n console.log(` ✅ Created \"${item.name}\" (ID: ${newId})`);\n created.push(item.name);\n } else {\n console.error(` ❌ Failed to create \"${item.name}\" - no ID returned`);\n }\n } catch (error) {\n console.error(` ❌ Failed to create \"${item.name}\": ${error instanceof Error ? error.message : error}`);\n }\n }\n\n if (created.length > 0) {\n console.log(`✅ Created ${created.length} ${this.displayNamePlural} on server`);\n }\n\n return { created, updated };\n }\n\n // ===========================================================================\n // YAML OPERATIONS\n // ===========================================================================\n\n updateYaml(items: T[], config: YamlConfig | null): void {\n const updatedConfig = {\n ...(config || {}),\n [this.yamlConfig.yamlKey]: items.map((item) => this.cleanItem(item)),\n };\n writeYamlConfig(updatedConfig);\n }\n\n getFromYaml(config: YamlConfig | null): T[] {\n if (!config) return [];\n const items = config[this.yamlConfig.yamlKey];\n return (Array.isArray(items) ? items : []) as unknown as T[];\n }\n\n syncYamlWithManifest(manifest: CompilationManifest, config: YamlConfig | null): void {\n const manifestNames = manifest.primitives.filter((p) => p.kind === this.kind).map((p) => p.name);\n\n if (manifestNames.length === 0) return;\n\n const existing = this.getFromYaml(config);\n const idField = this.yamlConfig.idField;\n\n // Keep existing items still in manifest, add new ones\n const kept = existing.filter((item) => manifestNames.includes(item.name)).map((item) => this.cleanItem(item));\n\n for (const name of manifestNames) {\n if (!kept.some((item) => item.name === name)) {\n kept.push(this.cleanItem({ name, version: DEFAULT_VERSION, [idField]: '' } as T));\n }\n }\n\n this.updateYaml(kept, config);\n }\n\n updateVersionInYaml(name: string, newVersion: string, options?: { silent?: boolean }): void {\n try {\n const config = readYamlConfig();\n if (!config) {\n if (options?.silent) return;\n throw new Error('lua.skill.yaml not found');\n }\n\n const items = this.getFromYaml(config);\n const item = items.find((i) => i.name === name);\n\n if (!item) {\n if (options?.silent) return;\n throw new Error(`${this.displayName} \"${name}\" not found in configuration`);\n }\n\n item.version = newVersion;\n this.updateYaml(items, config);\n } catch (error) {\n if (options?.silent) {\n console.warn(`⚠️ Could not update ${this.displayName} version in YAML:`, error);\n return;\n }\n throw error;\n }\n }\n\n // ===========================================================================\n // PUSH\n // ===========================================================================\n\n prepareForPush(\n manifest: CompilationManifest,\n name: string,\n projectPath: string = process.cwd(),\n bundleAccumulator?: Map<string, Buffer>\n ): Record<string, unknown> | null {\n const primitive = findPrimitive(manifest, name, this.kind);\n if (!primitive) return null;\n\n const code = loadArtifact(primitive, projectPath);\n\n // BAC-196: when a bundle accumulator is provided, hash the raw gzip and\n // emit `codeS3Hash` instead of inline `code`. The push command will\n // upload all accumulated bundles via presigned PUT before POSTing the\n // version metadata. When no accumulator is provided (legacy callers),\n // fall back to the inline gzip+base64 `code` path.\n if (bundleAccumulator) {\n const rawGzip = compressForPushRaw(code);\n const codeS3Hash = hashBundle(rawGzip);\n bundleAccumulator.set(codeS3Hash, rawGzip);\n return this.buildPushData(primitive, undefined, codeS3Hash);\n }\n\n const compressedCode = compressForPush(code);\n return this.buildPushData(primitive, compressedCode);\n }\n\n protected buildPushData(\n primitive: ManifestPrimitive,\n compressedCode: string | undefined,\n codeS3Hash?: string\n ): Record<string, unknown> {\n return {\n name: primitive.name,\n description: primitive.description,\n ...(codeS3Hash ? { codeS3Hash } : { code: compressedCode }),\n };\n }\n\n /**\n * Push a new version to the server.\n * Each handler implements the type-specific API call.\n */\n abstract pushToServer(\n apiKey: string,\n agentId: string,\n entityId: string,\n pushData: TPushData\n ): Promise<{ success: boolean; error?: string }>;\n\n /**\n * Deploy/publish a version on the server.\n * Each handler implements the type-specific API call.\n */\n abstract publishVersion(\n apiKey: string,\n agentId: string,\n entityId: string,\n version: string\n ): Promise<{ success: boolean; error?: string }>;\n\n /**\n * Get the highest version string from the server for conflict avoidance.\n */\n async getHighestServerVersion(apiKey: string, agentId: string, entityId: string): Promise<string | null> {\n // Go through fetchServerState (not fetchFromServer directly) so handler\n // overrides apply — DeviceHandler / DeviceTriggerHandler override\n // fetchServerState to silently degrade on auth/network errors because\n // the Device Gateway is feature-gated. Calling fetchFromServer directly\n // would bypass that override and re-throw auth errors as fatal, blocking\n // `lua push all` entirely for agents without device-gateway access.\n const { serverItems } = await this.fetchServerState(apiKey, agentId);\n if (!serverItems) return null;\n\n // Find the entity by ID\n const entity = serverItems.find((item: any) => item.id === entityId);\n if (!entity?.versions || !Array.isArray(entity.versions)) return null;\n\n // Exclude sandbox versions — they live in the same versions[] array\n // as production versions and would otherwise leak into production\n // auto-bump (e.g. `1.0.21-sandbox` → next push tagged `1.0.22-sandbox`).\n const versions: string[] = entity.versions\n .map((v: any) => v.version)\n .filter((v: any): v is string => typeof v === 'string' && !v.includes('-sandbox'));\n\n if (versions.length === 0) return null;\n\n return versions.reduce((highest, v) => maxSemver(highest, v), '0.0.0');\n }\n\n /**\n * Fetch all server items once, extract highest version for each entity ID.\n * More efficient than calling getHighestServerVersion() per entity.\n */\n async batchGetHighestVersions(\n apiKey: string,\n agentId: string,\n entityIds: string[]\n ): Promise<Map<string, string | null>> {\n const result = new Map<string, string | null>();\n\n // See getHighestServerVersion for the rationale on routing through\n // fetchServerState rather than calling fetchFromServer directly.\n const { serverItems } = await this.fetchServerState(apiKey, agentId);\n if (!serverItems) {\n entityIds.forEach((id) => result.set(id, null));\n return result;\n }\n\n for (const entityId of entityIds) {\n const entity = serverItems.find((item: any) => item.id === entityId);\n if (!entity?.versions || !Array.isArray(entity.versions)) {\n result.set(entityId, null);\n continue;\n }\n // Exclude sandbox versions — see getHighestServerVersion for rationale.\n const versions: string[] = entity.versions\n .map((v: any) => v.version)\n .filter((v: any): v is string => typeof v === 'string' && !v.includes('-sandbox'));\n result.set(entityId, versions.length > 0 ? versions.reduce((h, v) => maxSemver(h, v), '0.0.0') : null);\n }\n\n return result;\n }\n\n // ===========================================================================\n // INTERNAL\n // ===========================================================================\n\n /** Get the server ID from a YAML item using the configured idField. */\n protected getItemId(item: T): string {\n return ((item as Record<string, unknown>)[this.yamlConfig.idField] as string) || '';\n }\n\n protected buildMaps(\n serverItems: any[],\n yamlItems: T[]\n ): {\n yamlById: Map<string, T>;\n yamlByName: Map<string, T>;\n serverByName: Map<string, any>;\n } {\n const yamlById = new Map<string, T>();\n const yamlByName = new Map<string, T>();\n\n for (const item of yamlItems) {\n const id = this.getItemId(item);\n if (id) yamlById.set(id, item);\n yamlByName.set(item.name, item);\n }\n\n const serverByName = new Map<string, any>();\n for (const item of serverItems) {\n serverByName.set(item.name, item);\n }\n\n return { yamlById, yamlByName, serverByName };\n }\n\n /**\n * For each YAML item, match to server by name, populate missing IDs, update versions.\n */\n protected syncFromServer(\n yamlItems: T[],\n serverByName: Map<string, any>\n ): { items: T[]; changed: boolean; msgs: string[] } {\n const msgs: string[] = [];\n let changed = false;\n const idField = this.yamlConfig.idField;\n\n const items = yamlItems.map((item) => {\n const serverItem = serverByName.get(item.name);\n if (!serverItem) return item;\n\n let updated = { ...item };\n\n // Populate missing server ID\n if (!this.getItemId(item) && serverItem.id) {\n const msg = `🔗 Linked \"${item.name}\" ${this.displayName} to server (ID: ${serverItem.id})`;\n msgs.push(msg);\n console.log(msg);\n changed = true;\n updated = { ...updated, [idField]: serverItem.id };\n }\n\n // Update version if server has a newer active one\n const versions = serverItem.versions as unknown[];\n if (Array.isArray(versions) && versions.length > 0) {\n const activeVersion = this.getActiveVersion(serverItem);\n const currentVersion = item.version;\n\n if (activeVersion && activeVersion !== currentVersion) {\n const msg = `📝 Updated \"${item.name}\" ${this.displayName} version: ${currentVersion} → ${activeVersion}`;\n msgs.push(msg);\n console.log(msg);\n changed = true;\n updated = { ...updated, version: activeVersion };\n }\n }\n\n return updated;\n });\n\n return { items, changed, msgs };\n }\n}\n\n// =============================================================================\n// BASE NON-VERSIONED HANDLER\n// =============================================================================\n\n/**\n * Result returned by upsertOnServer. Handlers create-or-update in a single call,\n * so the server-assigned id flows back here.\n */\nexport interface UpsertResult {\n success: boolean;\n id?: string;\n active?: boolean;\n error?: string;\n}\n\n/**\n * Aggregate result of pushing every bundled item in one go.\n */\nexport interface PushAllResult {\n pushed: string[];\n failed: Array<{ name: string; error: string }>;\n activated: string[];\n}\n\n/**\n * For primitives without versions (e.g., MCP servers).\n *\n * Two generic parameters:\n * T — shape of items stored in lua.skill.yaml (see yaml.types.ts)\n * B — shape of items pushed to the server (bundled from the manifest).\n * Defaults to T for handlers where the YAML and push payloads match.\n */\nexport abstract class BaseNonVersionedHandler<\n T extends { name: string },\n B extends { name: string } = T,\n> implements PrimitiveHandler<T> {\n abstract readonly kind: PrimitiveKind;\n abstract readonly displayName: string;\n abstract readonly displayNamePlural: string;\n abstract readonly deleteCommand: string;\n abstract readonly yamlConfig: YamlPrimitiveConfig;\n\n protected abstract getApi(apiKey: string, agentId: string): unknown;\n protected abstract fetchFromServer(api: unknown): Promise<any[] | null>;\n abstract cleanItem(item: T): T;\n protected abstract isActive(item: any): boolean;\n\n /**\n * Load bundled items from the compilation manifest, ready to push.\n * Each item must have a `name`; other fields are handler-specific.\n */\n abstract loadBundledItems(projectPath?: string): B[];\n\n /**\n * Create-or-update a single item on the server. Returns the server-assigned\n * id. Implementations SHOULD call persistItemId after a successful upsert\n * so the id is tracked locally from the first push.\n */\n abstract upsertOnServer(apiKey: string, agentId: string, item: B): Promise<UpsertResult>;\n\n /**\n * Optional hook run after a successful upsert when autoDeploy is set.\n * Default: no-op. Handlers override for post-upsert actions (e.g. MCP\n * activation). Return true if the action fired and succeeded.\n */\n protected async postUpsert(_item: B, _upsert: UpsertResult, _apiKey: string, _agentId: string): Promise<boolean> {\n return false;\n }\n\n protected getServerItemName(item: any): string {\n return item.name || 'unknown';\n }\n\n /** Phase 1 of parallel sync: fetch server state (HTTP only, no YAML writes) */\n async fetchServerState(apiKey: string, agentId: string): Promise<ServerSyncData> {\n try {\n const api = this.getApi(apiKey, agentId);\n const serverItems = await this.fetchFromServer(api);\n return { serverItems };\n } catch (error) {\n if (AuthenticationError.isAuthenticationError(error)) throw error;\n return { serverItems: null, fetchError: error instanceof Error ? error.message : String(error) };\n }\n }\n\n /** Phase 2 of parallel sync: apply fetched data to YAML (orphan detection only for non-versioned) */\n async applySyncToYaml(\n serverData: ServerSyncData,\n config: YamlConfig | null,\n manifest?: CompilationManifest\n ): Promise<SyncResult> {\n const messages: string[] = [];\n let yamlUpdated = false;\n let orphanedCount = 0;\n\n try {\n if (!serverData.serverItems) {\n if (serverData.fetchError) {\n console.error(`❌ Error syncing server ${this.displayNamePlural}: ${serverData.fetchError}`);\n } else {\n console.warn(`⚠️ Could not retrieve server ${this.displayNamePlural}. Skipping sync.`);\n }\n return { messages, yamlUpdated, orphanedCount };\n }\n\n const yamlItems = this.getFromYaml(config);\n const idField = this.yamlConfig.idField;\n\n const getId = (item: T) => ((item as Record<string, unknown>)[idField] as string) || '';\n const yamlById = new Map(yamlItems.filter((i) => getId(i)).map((i) => [getId(i), i]));\n const yamlByName = new Map(yamlItems.map((i) => [i.name, i]));\n\n // Names present in the current compilation manifest are considered \"in local code\"\n // even if they haven't been pushed yet (and therefore have no YAML entry).\n // This prevents newly compiled MCP servers from being flagged as orphans.\n const manifestNames = manifest\n ? new Set(getPrimitivesByKind(manifest, this.kind).map((p: any) => p.name as string))\n : new Set<string>();\n\n const orphans = serverData.serverItems.filter((item) => {\n const id = item.id as string;\n const name = item.name as string;\n return !yamlById.has(id) && !yamlByName.has(name) && !manifestNames.has(name) && this.isActive(item);\n });\n\n if (orphans.length > 0) {\n // See BaseVersionedHandler.applySyncToYaml for rationale.\n const stubs = orphans.map((item) =>\n this.cleanItem({\n name: item.name,\n [idField]: item.id || '',\n } as unknown as T)\n );\n this.updateYaml([...yamlItems, ...stubs], config);\n yamlUpdated = true;\n\n const flagName = `--${this.displayName.toLowerCase().replace(/\\s+/g, '-')}-name`;\n console.log(`\\n⚠️ Found ${this.displayNamePlural} on server not in your local code:`);\n for (const item of orphans) {\n const msg = ` - ${this.getServerItemName(item)}`;\n messages.push(msg);\n console.log(msg);\n }\n console.log(` Added to lua.skill.yaml as server-only entries.`);\n console.log(` To remove from server: ${this.deleteCommand} ${flagName} <name>`);\n console.log(` To restore source from backup: lua sync --accept\\n`);\n orphanedCount = orphans.length;\n } else {\n console.log(`✅ Server ${this.displayNamePlural} and YAML are fully in sync`);\n }\n } catch (error) {\n console.error(`❌ Error syncing server ${this.displayNamePlural}:`, error);\n }\n\n return { messages, yamlUpdated, orphanedCount };\n }\n\n async syncWithServer(\n apiKey: string,\n agentId: string,\n config: YamlConfig | null,\n manifest?: CompilationManifest\n ): Promise<SyncResult> {\n const serverData = await this.fetchServerState(apiKey, agentId);\n return this.applySyncToYaml(serverData, config, manifest);\n }\n\n updateYaml(items: T[], config: YamlConfig | null): void {\n const updatedConfig = {\n ...(config || {}),\n [this.yamlConfig.yamlKey]: items.map((item) => this.cleanItem(item)),\n };\n writeYamlConfig(updatedConfig);\n }\n\n getFromYaml(config: YamlConfig | null): T[] {\n if (!config) return [];\n const items = config[this.yamlConfig.yamlKey];\n return (Array.isArray(items) ? items : []) as unknown as T[];\n }\n\n prepareForPush(_manifest: CompilationManifest, _name: string, _projectPath?: string): Record<string, unknown> | null {\n return null;\n }\n\n /**\n * Write a server-assigned id back into lua.skill.yaml for the given item,\n * using the handler's configured idField. Creates a new YAML entry if none\n * exists yet (first-push case).\n */\n persistItemId(name: string, id: string): void {\n const config = readYamlConfig();\n const items = this.getFromYaml(config);\n const idField = this.yamlConfig.idField;\n const existing = items.find((i) => i.name === name);\n if (existing) {\n (existing as Record<string, unknown>)[idField] = id;\n } else {\n items.push({ name, [idField]: id } as unknown as T);\n }\n this.updateYaml(items, config);\n }\n\n /**\n * Push the given bundled items to the server:\n * 1. Upsert each on the server (create or update by name).\n * 2. persistItemId is expected to run inside upsertOnServer so the\n * server-assigned id is tracked locally from the first push.\n * 3. When autoDeploy is set, run the postUpsert hook per successfully\n * pushed item.\n *\n * Caller passes in pre-loaded items (loadBundledItems) so push.ts can\n * decide what to print up front without reading the manifest twice.\n *\n * Error semantics: upsert failures add the item to `failed`; postUpsert\n * failures don't — the push itself already succeeded, only the follow-up\n * step (e.g. activation) failed. Activation errors surface via a warn\n * so they're visible without polluting the failed[] list.\n *\n * Upsert-by-name is idempotent, so a mid-loop crash self-heals on the next\n * run — ids flow back on subsequent calls for anything not yet persisted.\n */\n async pushAll(\n items: B[],\n apiKey: string,\n agentId: string,\n options: { autoDeploy?: boolean } = {}\n ): Promise<PushAllResult> {\n const result: PushAllResult = { pushed: [], failed: [], activated: [] };\n if (items.length === 0) return result;\n\n for (const item of items) {\n let upsert: UpsertResult;\n try {\n upsert = await this.upsertOnServer(apiKey, agentId, item);\n } catch (error) {\n result.failed.push({\n name: item.name,\n error: error instanceof Error ? error.message : String(error),\n });\n continue;\n }\n\n if (!upsert.success) {\n result.failed.push({ name: item.name, error: upsert.error || 'unknown error' });\n continue;\n }\n result.pushed.push(item.name);\n\n if (!options.autoDeploy) continue;\n\n try {\n const activated = await this.postUpsert(item, upsert, apiKey, agentId);\n if (activated) result.activated.push(item.name);\n } catch (error) {\n // postUpsert failure doesn't invalidate the push — the server has\n // the new config, only the follow-up step failed. Warn for\n // visibility without adding the item to failed[] (which would\n // imply the push itself failed).\n console.warn(\n `⚠️ ${item.name} pushed but post-upsert action failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n return result;\n }\n}\n","/**\n * Skill Handler\n *\n * Skills have special behavior:\n * - Custom syncYamlWithManifest (logs success message)\n * - Orphan detection only considers CLI-sourced skills\n * - Uses 'active' field on versions (not 'isActive')\n * - Custom prepareForPush with tools array\n */\n\nimport { hasPersonaTextContent } from '@lua/shared-types';\nimport {\n PrimitiveKind,\n CompilationManifest,\n ManifestPrimitive,\n ManifestSkill,\n ManifestTool,\n} from '../compiler/types.js';\nimport { YamlConfig, YamlConfigSkill } from '../types/yaml.types.js';\nimport { BASE_URLS } from '../config/constants.js';\nimport SkillApi from '../api/skills.api.service.js';\nimport type { PushSkillVersionRequest } from '../interfaces/skills.js';\nimport { BaseVersionedHandler } from './base.handler.js';\nimport {\n findPrimitive,\n loadArtifact,\n compressForPush,\n loadOriginalSource,\n normalizeEntryFile,\n buildSourceArchive,\n compressForPushRaw,\n SOURCE_ARCHIVE_SCHEMA_VERSION,\n} from '../utils/artifact-loader.js';\nimport { hashBundle } from '../utils/bundle-upload.js';\n\nimport { readYamlConfig, writeYamlConfig } from '../utils/files.js';\nimport type { YamlPrimitiveConfig, SyncResult } from './types.js';\n\nexport class SkillHandler extends BaseVersionedHandler<YamlConfigSkill, PushSkillVersionRequest> {\n readonly kind = PrimitiveKind.SKILL;\n readonly displayName = 'skill';\n readonly displayNamePlural = 'skills';\n readonly deleteCommand = 'lua skills delete';\n readonly yamlConfig: YamlPrimitiveConfig = {\n yamlKey: 'skills',\n idField: 'skillId',\n };\n\n protected getApi(apiKey: string, agentId: string): SkillApi {\n return new SkillApi(BASE_URLS.API, apiKey, agentId);\n }\n\n protected async fetchFromServer(api: SkillApi): Promise<any[] | null> {\n const response = await api.getSkills();\n if (!response.success || !response.data?.skills) return null;\n return response.data.skills;\n }\n\n protected async createOnServer(api: SkillApi, primitive: ManifestPrimitive): Promise<string | null> {\n const skill = primitive as ManifestSkill;\n // Omit context entirely when there's no real content — the API field is\n // optional and @IsPersonaText() rejects empty strings / empty objects to\n // match the SDK push gate. Use the same hasPersonaTextContent predicate\n // so this stays in lockstep with server-side validation.\n const response = await api.createSkill({\n name: skill.name,\n description: skill.description || `A Lua skill for ${skill.name}`,\n ...(hasPersonaTextContent(skill.context) ? { context: skill.context } : {}),\n });\n if (!response.success || !response.data?.id) return null;\n return response.data.id;\n }\n\n isActive(serverItem: any): boolean {\n return serverItem.active !== false;\n }\n\n /**\n * Skills use 'active' field on versions (not 'isActive').\n */\n getActiveVersion(serverItem: any): string | null {\n const active = serverItem.versions?.find((v: any) => v.active === true);\n return active?.version ?? null;\n }\n\n protected shouldConsiderForOrphan(serverItem: any): boolean {\n return serverItem.source === 'cli' || !serverItem.source;\n }\n\n // ===========================================================================\n // YAML — override to handle legacy single-skill format\n // ===========================================================================\n\n getFromYaml(config: YamlConfig | null): YamlConfigSkill[] {\n if (!config) return [];\n\n if (config.skills && Array.isArray(config.skills) && config.skills.length > 0) {\n return config.skills.map((skill) => ({\n name: skill.name || '',\n version: skill.version || '',\n skillId: skill.skillId || '',\n }));\n }\n\n if (config.skill) {\n const legacy = config.skill;\n return [\n {\n name: legacy.name || 'unnamed-skill',\n version: legacy.version || '',\n skillId: legacy.skillId || '',\n },\n ];\n }\n\n return [];\n }\n\n updateVersionInYaml(name: string, newVersion: string, options?: { silent?: boolean }): void {\n try {\n const config = readYamlConfig();\n if (!config) {\n if (options?.silent) return;\n throw new Error('lua.skill.yaml not found');\n }\n\n let updated = false;\n\n if (config.skills && Array.isArray(config.skills)) {\n const skill = config.skills.find((s: YamlConfigSkill) => s.name === name);\n if (skill) {\n skill.version = newVersion;\n updated = true;\n }\n }\n\n if (!updated && config.skill) {\n const legacy = config.skill;\n if (legacy.name === name || name === 'unnamed-skill') {\n legacy.version = newVersion;\n updated = true;\n }\n }\n\n if (!updated) {\n if (options?.silent) return;\n throw new Error(`Skill \"${name}\" not found in configuration`);\n }\n\n writeYamlConfig(config);\n } catch (error) {\n if (options?.silent) {\n console.warn(`⚠️ Could not update skill version in YAML:`, error);\n return;\n }\n throw error;\n }\n }\n\n syncYamlWithManifest(manifest: CompilationManifest, config: YamlConfig | null): void {\n super.syncYamlWithManifest(manifest, config);\n if (manifest.primitives.some((p) => p.kind === this.kind)) {\n console.log('✅ YAML synced with manifest');\n }\n }\n\n // ===========================================================================\n // PUSH — custom to include tools array\n // ===========================================================================\n\n async pushToServer(apiKey: string, agentId: string, entityId: string, pushData: PushSkillVersionRequest) {\n const api = this.getApi(apiKey, agentId);\n const response = await api.pushSkill(entityId, { ...pushData, skillId: entityId });\n return { success: response.success, error: response.error?.message };\n }\n\n async publishVersion(apiKey: string, agentId: string, entityId: string, version: string) {\n const api = this.getApi(apiKey, agentId);\n const response = await api.publishSkillVersion(entityId, version);\n return { success: response.success, error: response.error?.message };\n }\n\n prepareForPush(\n manifest: CompilationManifest,\n name: string,\n projectPath: string = process.cwd(),\n bundleAccumulator?: Map<string, Buffer>\n ): Record<string, unknown> | null {\n const skill = findPrimitive<ManifestSkill>(manifest, name, PrimitiveKind.SKILL);\n if (!skill) return null;\n\n // Track per-tool source so we can also build a skill-level `sourceArchive`\n // alongside the per-tool `source` fields. Both formats are accepted by the\n // canonical-source store; per-tool source unlocks the Builder UI's\n // tool-level edit, the archive unlocks workspace hydration on the\n // conversational Builder side. Shipping both is cheap and matches the\n // server schema (`tools[].source` + `sourceArchive` are both optional).\n const archiveEntries: Array<{ entryFile: string; source: string }> = [];\n\n const tools = (skill.tools || [])\n .map((toolName: string) => {\n const tool = findPrimitive<ManifestTool>(manifest, toolName, PrimitiveKind.TOOL);\n if (!tool) return null;\n\n const code = loadArtifact(tool, projectPath);\n\n let toolData: Record<string, unknown>;\n\n // BAC-196: when an accumulator is supplied, emit `codeS3Hash` and\n // queue raw gzip for presigned upload. Otherwise use inline path.\n if (bundleAccumulator) {\n const rawGzip = compressForPushRaw(code);\n const codeS3Hash = hashBundle(rawGzip);\n bundleAccumulator.set(codeS3Hash, rawGzip);\n\n toolData = {\n name: tool.name,\n description: tool.description,\n inputSchema: tool.schemas?.input || undefined,\n codeS3Hash,\n };\n if (tool.hasCondition) {\n // Condition shares the same compiled artifact, so same hash works.\n toolData.condition = codeS3Hash;\n }\n } else {\n const compressedCode = compressForPush(code);\n toolData = {\n name: tool.name,\n description: tool.description,\n inputSchema: tool.schemas?.input || undefined,\n code: compressedCode,\n };\n if (tool.hasCondition) {\n toolData.condition = compressedCode;\n }\n }\n\n // Attach original TS source. Best-effort: when sourcePath is missing or\n // the file is unreadable, `loadOriginalSource` returns null and we omit\n // both fields. The server treats absent source as \"not attached\" — same\n // behaviour as older CLI clients that never sent it. Source metadata is\n // independent of bundle delivery mode (inline `code` vs `codeS3Hash`),\n // so it applies to both BAC-196 and inline paths.\n const source = loadOriginalSource(tool.sourcePath, projectPath);\n const entryFile = normalizeEntryFile(tool.sourcePath, projectPath);\n if (source && entryFile) {\n toolData.source = source;\n toolData.entryFile = entryFile;\n archiveEntries.push({ entryFile, source });\n }\n\n return toolData;\n })\n .filter(Boolean);\n\n const sourceArchive = buildSourceArchive(archiveEntries);\n\n return {\n name: skill.name,\n description: skill.description,\n // Same gate as createOnServer — server validator rejects empty content.\n ...(hasPersonaTextContent(skill.context) ? { context: skill.context } : {}),\n tools,\n ...(sourceArchive\n ? {\n sourceArchive,\n archiveSchemaVersion: SOURCE_ARCHIVE_SCHEMA_VERSION,\n }\n : {}),\n };\n }\n}\n\nexport const skillHandler = new SkillHandler();\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport pkg from 'js-yaml';\nconst { load, dump } = pkg;\nimport { COMPILE_FILES, YAML_FORMAT } from '../config/compile.constants.js';\nimport { YamlConfig } from '../types/yaml.types.js';\nimport { skillHandler } from '../primitives/skill.handler.js';\n\n// =============================================================================\n// CONFIG VALIDATION\n// =============================================================================\n\n/**\n * Validates that configuration has required fields.\n * Acts as a type guard - after calling this, TypeScript knows config is not null.\n *\n * @param config - Skill configuration\n * @throws Error if configuration is invalid\n */\nexport function validateSkillConfig(config: YamlConfig | null): asserts config is YamlConfig {\n if (!config) {\n throw new Error('No lua.skill.yaml found. Please run this command from a skill directory.');\n }\n\n if (!config.agent?.agentId) {\n throw new Error('Missing agentId in skill configuration');\n }\n\n // If skills are defined, they must have skillIds (i.e. been compiled and pushed)\n const skills = skillHandler.getFromYaml(config);\n if (skills.length > 0 && !skills.some((s) => s.skillId)) {\n throw new Error('Skills are missing skillId. Please compile and push your skill first.');\n }\n}\n\n/**\n * Copies template files to target directory.\n *\n * @param templateDir - Source template directory\n * @param targetDir - Target directory to copy to\n * @param includeExamples - Whether to include the examples/ directory (default: false)\n * @param skipSrcDir - Whether to skip the src/ directory (for backup restoration, default: false)\n */\nexport function copyTemplateFiles(\n templateDir: string,\n targetDir: string,\n includeExamples: boolean = false,\n skipSrcDir: boolean = false\n): void {\n const files = fs.readdirSync(templateDir);\n\n for (const file of files) {\n // Skip node_modules and package-lock.json to avoid circular dependencies\n if (file === 'node_modules' || file === 'package-lock.json') {\n continue;\n }\n\n // Skip examples/ by default (user can include with --with-examples flag)\n if (file === 'examples' && !includeExamples) {\n continue;\n }\n\n // Skip src/ directory if sources were restored from backup\n if (file === 'src' && skipSrcDir) {\n continue;\n }\n\n const srcPath = path.join(templateDir, file);\n const destPath = path.join(targetDir, file);\n\n if (fs.statSync(srcPath).isDirectory()) {\n fs.mkdirSync(destPath, { recursive: true });\n copyTemplateFiles(srcPath, destPath, includeExamples, skipSrcDir);\n } else if (file === 'package.json') {\n // Special handling for package.json to update lua-cli version\n updatePackageJson(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n}\n\nfunction updatePackageJson(srcPath: string, destPath: string): void {\n const templatePackageJson = JSON.parse(fs.readFileSync(srcPath, 'utf8'));\n fs.writeFileSync(destPath, JSON.stringify(templatePackageJson, null, 2) + '\\n');\n}\n\n/**\n * Reads the lua.skill.yaml configuration file from the current working directory.\n *\n * @returns The parsed YAML config or null if file doesn't exist\n */\nexport function readYamlConfig(): YamlConfig | null {\n const yamlPath = path.join(process.cwd(), COMPILE_FILES.LUA_SKILL_YAML);\n\n if (!fs.existsSync(yamlPath)) {\n return null;\n }\n\n const yamlContent = fs.readFileSync(yamlPath, 'utf8');\n return load(yamlContent) as YamlConfig;\n}\n\n/**\n * Update only the agent information in an existing YAML file\n */\nexport function updateYamlAgent(agentId: string, orgId: string): void {\n const config = readYamlConfig();\n\n if (!config) {\n throw new Error('lua.skill.yaml not found');\n }\n\n // Update agent information\n config.agent = config.agent || {};\n config.agent.agentId = agentId;\n config.agent.orgId = orgId;\n\n writeYamlConfig(config);\n}\n\n/**\n * Ensures a given entry is present in the project's .gitignore file.\n * If .gitignore doesn't exist, creates it. If the entry already exists, does nothing.\n * Inserts the entry right after a reference line (e.g. \"dist/\" -> \"dist-v2/\" after it).\n *\n * @param rootDir - Project root directory\n * @param entry - The gitignore entry to ensure (e.g. \"dist-v2/\")\n * @param afterEntry - Optional entry after which to insert (falls back to appending)\n */\nexport function ensureGitignored(rootDir: string, entry: string, afterEntry?: string): void {\n const gitignorePath = path.join(rootDir, '.gitignore');\n\n if (!fs.existsSync(gitignorePath)) {\n fs.writeFileSync(gitignorePath, `${entry}\\n`);\n return;\n }\n\n const content = fs.readFileSync(gitignorePath, 'utf8');\n const lines = content.split('\\n');\n\n // Already present\n if (lines.some((line) => line.trim() === entry)) {\n return;\n }\n\n // Try to insert after the reference entry\n if (afterEntry) {\n const idx = lines.findIndex((line) => line.trim() === afterEntry);\n if (idx !== -1) {\n lines.splice(idx + 1, 0, entry);\n fs.writeFileSync(gitignorePath, lines.join('\\n'));\n return;\n }\n }\n\n // Fallback: append to end\n const trimmed = content.endsWith('\\n') ? content : content + '\\n';\n fs.writeFileSync(gitignorePath, trimmed + entry + '\\n');\n}\n\n/**\n * Checks if .env file exists in the current working directory.\n *\n * @returns True if .env file exists\n */\nexport function hasEnvFile(): boolean {\n return fs.existsSync(path.join(process.cwd(), '.env'));\n}\n\n/**\n * Writes a YAML config file with consistent formatting.\n * Uses yamlKeySorter by default for consistent key ordering.\n *\n * @param config - The configuration object to write\n * @param filePath - Optional custom file path (defaults to lua.skill.yaml in cwd)\n * @param options - Optional YAML dump options\n */\nexport function writeYamlConfig(\n config: YamlConfig,\n filePath?: string,\n options?: {\n sortKeys?: boolean | ((a: string, b: string) => number) | false;\n replacer?: (key: string, value: any) => any;\n }\n): void {\n const yamlPath = filePath || path.join(process.cwd(), COMPILE_FILES.LUA_SKILL_YAML);\n\n // Use yamlKeySorter by default unless explicitly disabled with false\n const sortKeys = options?.sortKeys === false ? false : (options?.sortKeys ?? yamlKeySorter);\n\n const yamlContent = dump(config, {\n indent: YAML_FORMAT.INDENT,\n lineWidth: YAML_FORMAT.LINE_WIDTH,\n noRefs: YAML_FORMAT.NO_REFS,\n sortKeys,\n replacer:\n options?.replacer ||\n ((key: string, value: any) => {\n // Replace undefined values with empty strings by default\n return value === undefined ? '' : value;\n }),\n });\n\n fs.writeFileSync(yamlPath, yamlContent);\n}\n\n/**\n * Standard YAML key sort order for lua.skill.yaml\n */\nexport const YAML_KEY_ORDER = [\n 'agent',\n 'skills',\n 'webhooks',\n 'jobs',\n 'preprocessors',\n 'postprocessors',\n 'mcpServers',\n 'skill',\n];\n\n/**\n * Sort function for YAML keys to maintain consistent ordering\n */\nexport function yamlKeySorter(a: string, b: string): number {\n const aIndex = YAML_KEY_ORDER.indexOf(a);\n const bIndex = YAML_KEY_ORDER.indexOf(b);\n if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;\n if (aIndex !== -1) return -1;\n if (bIndex !== -1) return 1;\n return a.localeCompare(b);\n}\n","/**\n * Version Check Utilities\n * Checks npm registry for the latest lua-cli version and caches the result.\n * Used by the update command (LUA-123) and the outdated version warning (LUA-124).\n */\n\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\nimport { compareVersions, parseVersion } from './semver.js';\nimport { CLI_CONFIG_DIR, VERSION_CHECK_FILE } from '../config/constants.js';\nconst CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours\nconst NPM_REGISTRY_BASE = 'https://registry.npmjs.org/lua-cli';\nconst FETCH_TIMEOUT_MS = 3000;\n\n/**\n * Get the npm registry URL for the appropriate dist-tag.\n * If currentVersion has a pre-release tag (e.g. \"alpha\"), use that dist-tag.\n * Otherwise use \"latest\" (stable releases).\n */\nfunction getRegistryUrl(currentVersion: string): string {\n const { preRelease } = parseVersion(currentVersion);\n if (preRelease) {\n // Extract tag name from pre-release (e.g. \"alpha.9\" → \"alpha\", \"beta.1\" → \"beta\")\n const tag = preRelease.split('.')[0].replace(/[0-9]/g, '');\n if (tag) return `${NPM_REGISTRY_BASE}/${tag}`;\n }\n return `${NPM_REGISTRY_BASE}/latest`;\n}\n\ninterface VersionCheckCache {\n latestVersion: string;\n checkedAt: number;\n}\n\n/**\n * Read cached version check result.\n * Returns null if cache is missing, corrupt, or expired.\n */\nexport function getCachedVersionCheck(): VersionCheckCache | null {\n try {\n if (!existsSync(VERSION_CHECK_FILE)) return null;\n const raw = readFileSync(VERSION_CHECK_FILE, 'utf8');\n const cache: VersionCheckCache = JSON.parse(raw);\n if (Date.now() - cache.checkedAt > CHECK_INTERVAL_MS) return null;\n return cache;\n } catch {\n return null;\n }\n}\n\n/**\n * Save version check result to cache file.\n */\nexport function saveCachedVersionCheck(latestVersion: string): void {\n try {\n if (!existsSync(CLI_CONFIG_DIR)) {\n mkdirSync(CLI_CONFIG_DIR, { recursive: true });\n }\n writeFileSync(VERSION_CHECK_FILE, JSON.stringify({ latestVersion, checkedAt: Date.now() }), 'utf8');\n } catch {\n // Silently ignore write failures (permissions, disk full, etc.)\n }\n}\n\n/**\n * Fetch the latest version from npm registry.\n * Uses the dist-tag matching the current version's pre-release channel (e.g. \"alpha\").\n * Returns null on any failure (network, timeout, parse error).\n */\nexport async function fetchLatestVersion(currentVersion?: string): Promise<string | null> {\n try {\n const url = getRegistryUrl(currentVersion ?? '0.0.0');\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n const response = await fetch(url, { signal: controller.signal });\n clearTimeout(timeout);\n if (!response.ok) return null;\n const data = (await response.json()) as { version?: string };\n return data.version ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if an update is available. Uses 24h cache to avoid hitting npm on every run.\n */\nexport async function isUpdateAvailable(\n currentVersion: string\n): Promise<{ available: boolean; latest: string | null }> {\n const cached = getCachedVersionCheck();\n if (cached) {\n return {\n available: compareVersions(currentVersion, cached.latestVersion) < 0,\n latest: cached.latestVersion,\n };\n }\n\n const latest = await fetchLatestVersion(currentVersion);\n if (!latest) return { available: false, latest: null };\n\n saveCachedVersionCheck(latest);\n return {\n available: compareVersions(currentVersion, latest) < 0,\n latest,\n };\n}\n\n/**\n * Print a boxed update warning to stderr (so piped --json stdout is not corrupted).\n */\nexport function printUpdateWarning(currentVersion: string, latestVersion: string): void {\n const msg = `Update available: ${currentVersion} → ${latestVersion}`;\n const tip = 'Run `lua update` to install the latest version';\n const width = Math.max(msg.length, tip.length) + 6;\n const pad = (s: string) => s + ' '.repeat(width - s.length);\n\n console.error('');\n console.error(` ╭${'─'.repeat(width)}╮`);\n console.error(` │${' '.repeat(width)}│`);\n console.error(` │${pad(' ' + msg)}│`);\n console.error(` │${pad(' ' + tip)}│`);\n console.error(` │${' '.repeat(width)}│`);\n console.error(` ╰${'─'.repeat(width)}╯`);\n console.error('');\n}\n","/**\n * Resolves lua-cli's package root by walking up from `import.meta.url` until\n * it finds a `package.json` with `\"name\": \"lua-cli\"`.\n *\n * Works identically in three modes:\n * - jest/tsc (src/): walks up from src/utils/package-root.ts\n * - bundled dist (esm): walks up from dist/<entry>.js\n * - end-user install: walks up from node_modules/lua-cli/dist/<entry>.js\n *\n * This is the single source of truth for \"where is lua-cli on disk.\" All\n * package-relative resources (version, template/, vendored zod bundle) go\n * through here instead of inlining `__dirname/../../<thing>` walks at call\n * sites — those break when the bundler flattens the dist structure.\n */\n\nimport { readFileSync, existsSync } from 'fs';\nimport { fileURLToPath, pathToFileURL } from 'url';\nimport { dirname, join } from 'path';\n\nlet cachedRoot: string | null = null;\nlet cachedPkg: { name: string; version: string; [k: string]: unknown } | null = null;\n\nfunction locate(): { root: string; pkg: typeof cachedPkg } {\n if (cachedRoot && cachedPkg) return { root: cachedRoot, pkg: cachedPkg };\n\n let dir = dirname(fileURLToPath(import.meta.url));\n while (true) {\n const candidate = join(dir, 'package.json');\n if (existsSync(candidate)) {\n try {\n const parsed = JSON.parse(readFileSync(candidate, 'utf8'));\n if (parsed?.name === 'lua-cli') {\n cachedRoot = dir;\n cachedPkg = parsed;\n return { root: dir, pkg: parsed };\n }\n } catch {\n // Malformed package.json — keep walking.\n }\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error('Could not locate lua-cli package root from ' + fileURLToPath(import.meta.url));\n}\n\nexport function getPackageRoot(): string {\n return locate().root;\n}\n\nexport function getPackageJson(): { name: string; version: string; [k: string]: unknown } {\n return locate().pkg!;\n}\n\nexport function getCliVersion(): string {\n try {\n return locate().pkg!.version;\n } catch {\n return '0.0.0';\n }\n}\n\nexport function getTemplateDir(): string {\n return join(getPackageRoot(), 'template');\n}\n\nexport function getZodRuntimeUrl(): URL {\n // Vendored zod bundle lives at dist/zod-runtime.mjs in published installs.\n // Emitted by scripts/build-vendor.mjs. Use pathToFileURL (not raw string\n // concat) so the resulting URL is valid on Windows, where path.join\n // returns backslash-separated paths.\n return pathToFileURL(join(getPackageRoot(), 'dist', 'zod-runtime.mjs'));\n}\n","/**\n * Analytics Service\n * Non-blocking PostHog telemetry for CLI usage tracking.\n *\n * Opt-out: Set LUA_TELEMETRY=false env var, or run `lua telemetry off`.\n * All tracking is anonymous (hashed API key or machine UUID).\n * Analytics never blocks commands or throws errors to the user.\n */\n\nimport { PostHog } from 'posthog-node';\nimport crypto from 'crypto';\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\nimport { platform, release, arch } from 'os';\nimport { POSTHOG_API_KEY, POSTHOG_HOST, TELEMETRY_FILE, CLI_CONFIG_DIR } from '../config/constants.js';\nimport { getToken, checkApiKey } from '../services/auth.js';\nimport { readYamlConfig } from '../utils/files.js';\n\ninterface TelemetryConfig {\n enabled: boolean;\n anonymousId: string;\n noticeShown: boolean;\n identifiedApiKeyHash?: string;\n identifiedEmail?: string;\n identifiedName?: string;\n}\n\nlet client: PostHog | null = null;\nlet sessionConfig: TelemetryConfig | null = null;\nlet sessionDistinctId: string | null = null;\nlet sessionContext: { apiKey?: string; orgId?: string; agentId?: string } = {};\n\n// =============================================================================\n// Opt-out Logic\n// =============================================================================\n\nfunction isTelemetryDisabled(): boolean {\n const envVal = process.env.LUA_TELEMETRY;\n if (envVal !== undefined) {\n return ['false', '0', 'off', 'no'].includes(envVal.toLowerCase());\n }\n\n const config = loadTelemetryConfig();\n return !config.enabled;\n}\n\nfunction loadTelemetryConfig(): TelemetryConfig {\n if (sessionConfig) return sessionConfig;\n\n try {\n if (existsSync(TELEMETRY_FILE)) {\n sessionConfig = JSON.parse(readFileSync(TELEMETRY_FILE, 'utf8'));\n return sessionConfig!;\n }\n } catch {\n // Corrupt file — regenerate\n }\n\n sessionConfig = {\n enabled: true,\n anonymousId: crypto.randomUUID(),\n noticeShown: false,\n };\n saveTelemetryConfig(sessionConfig);\n return sessionConfig;\n}\n\nfunction saveTelemetryConfig(config: TelemetryConfig): void {\n try {\n if (!existsSync(CLI_CONFIG_DIR)) {\n mkdirSync(CLI_CONFIG_DIR, { recursive: true });\n }\n writeFileSync(TELEMETRY_FILE, JSON.stringify(config, null, 2), 'utf8');\n } catch {\n // Silently ignore write failures\n }\n}\n\n// =============================================================================\n// Distinct ID\n// =============================================================================\n\nfunction getDistinctId(apiKey?: string | null): string {\n if (sessionDistinctId && !apiKey) return sessionDistinctId;\n\n if (apiKey) {\n sessionDistinctId = crypto.createHash('sha256').update(apiKey).digest('hex').substring(0, 16);\n } else {\n const config = loadTelemetryConfig();\n sessionDistinctId = `anon_${config.anonymousId}`;\n }\n\n return sessionDistinctId;\n}\n\n// =============================================================================\n// PostHog Client Lifecycle\n// =============================================================================\n\nfunction getClient(): PostHog | null {\n if (isTelemetryDisabled()) return null;\n\n if (!client) {\n const apiKey = process.env.LUA_POSTHOG_KEY || POSTHOG_API_KEY;\n if (!apiKey) return null;\n\n client = new PostHog(apiKey, {\n host: POSTHOG_HOST,\n flushAt: 1,\n flushInterval: 0,\n });\n }\n\n return client;\n}\n\n// =============================================================================\n// Public API\n// =============================================================================\n\n/**\n * Show first-run telemetry notice (once per install).\n */\nexport function showTelemetryNoticeIfNeeded(): void {\n if (isTelemetryDisabled()) return;\n\n const config = loadTelemetryConfig();\n if (config.noticeShown) return;\n\n console.error('');\n console.error(' Lua CLI collects usage data to improve the developer experience.');\n console.error(' To opt out, run: lua telemetry off');\n console.error(' Or set: LUA_TELEMETRY=false');\n console.error('');\n\n config.noticeShown = true;\n saveTelemetryConfig(config);\n}\n\n/**\n * Opportunistically load API key and yaml config to enrich analytics context.\n * Called from withErrorHandling before every command. Never throws.\n */\nexport async function enrichAnalyticsContext(): Promise<void> {\n if (isTelemetryDisabled()) return;\n try {\n let apiKey: string | null = null;\n try {\n apiKey = getToken();\n } catch {\n /* no key — enrich without identity */\n }\n if (apiKey) {\n // Check if transitioning from anonymous to authenticated\n const previousDistinctId = sessionDistinctId;\n const wasAnonymous = previousDistinctId?.startsWith('anon_');\n\n sessionContext.apiKey = apiKey;\n\n // Link anonymous → authenticated identity in PostHog (once per session)\n if (wasAnonymous) {\n const newDistinctId = getDistinctId(apiKey);\n const ph = getClient();\n if (ph && previousDistinctId) {\n ph.alias({ distinctId: newDistinctId, alias: previousDistinctId });\n }\n }\n\n // Identify user in PostHog with person properties (cached to avoid network call)\n const currentHash = getDistinctId(apiKey);\n const telemetryConfig = loadTelemetryConfig();\n\n if (telemetryConfig.identifiedApiKeyHash === currentHash) {\n // Cached — identify with stored data (no network call)\n const ph = getClient();\n if (ph) {\n ph.identify({\n distinctId: currentHash,\n properties: {\n email: telemetryConfig.identifiedEmail || null,\n name: telemetryConfig.identifiedName || null,\n os: platform(),\n },\n });\n }\n } else {\n // New API key or first time — fetch user data and cache\n try {\n const userData = await checkApiKey(apiKey);\n if (userData) {\n telemetryConfig.identifiedApiKeyHash = currentHash;\n telemetryConfig.identifiedEmail = userData.email;\n telemetryConfig.identifiedName = userData.fullName;\n saveTelemetryConfig(telemetryConfig);\n\n const ph = getClient();\n if (ph) {\n ph.identify({\n distinctId: currentHash,\n properties: {\n email: userData.email || null,\n name: userData.fullName || null,\n os: platform(),\n },\n });\n }\n }\n } catch {\n // Best-effort — don't block commands\n }\n }\n }\n\n const config = readYamlConfig();\n if (config?.agent?.agentId) {\n sessionContext.agentId = config.agent.agentId;\n }\n if (config?.agent?.orgId) {\n sessionContext.orgId = config.agent.orgId;\n }\n } catch {\n // Best-effort — never block the command\n }\n}\n\n/**\n * Track a command execution event. Fire-and-forget, never throws.\n */\nexport function trackCommand(params: {\n commandName: string;\n success: boolean;\n durationMs: number;\n cliVersion: string;\n error?: string;\n properties?: Record<string, any>;\n}): void {\n try {\n const ph = getClient();\n if (!ph) return;\n\n const distinctId = getDistinctId(sessionContext.apiKey);\n\n ph.capture({\n distinctId,\n event: 'cli_command_executed',\n properties: {\n command: params.commandName,\n success: params.success,\n duration_ms: params.durationMs,\n cli_version: params.cliVersion,\n error_message: params.error?.substring(0, 200) || null,\n os: platform(),\n os_version: release(),\n arch: arch(),\n node_version: process.version,\n ci_mode: !!process.env.CI || !process.stdin.isTTY,\n org_id: sessionContext.orgId || null,\n agent_id: sessionContext.agentId || null,\n ...params.properties,\n },\n });\n } catch {\n // Never throw from analytics\n }\n}\n\n/**\n * Track a specific named event with properties. Fire-and-forget, never throws.\n * Use for per-command events (e.g., 'cli_push_completed', 'cli_compile_completed').\n * Auto-enriched with distinct ID, OS, CLI version, and session context.\n */\nexport function trackEvent(eventName: string, properties?: Record<string, any>): void {\n try {\n const ph = getClient();\n if (!ph) return;\n\n const distinctId = getDistinctId(sessionContext.apiKey);\n\n ph.capture({\n distinctId,\n event: eventName,\n properties: {\n os: platform(),\n os_version: release(),\n arch: arch(),\n node_version: process.version,\n ci_mode: !!process.env.CI || !process.stdin.isTTY,\n org_id: sessionContext.orgId || null,\n agent_id: sessionContext.agentId || null,\n ...properties,\n },\n });\n } catch {\n // Never throw from analytics\n }\n}\n\n/**\n * Set telemetry enabled/disabled and persist.\n */\nexport function setTelemetryEnabled(enabled: boolean): void {\n const config = loadTelemetryConfig();\n config.enabled = enabled;\n saveTelemetryConfig(config);\n}\n\n/**\n * Get current telemetry status.\n */\nexport function getTelemetryStatus(): { enabled: boolean; envOverride: boolean } {\n const envVal = process.env.LUA_TELEMETRY;\n const envOverride = envVal !== undefined;\n return {\n enabled: !isTelemetryDisabled(),\n envOverride,\n };\n}\n\n/**\n * Clears cached identity data from telemetry.json.\n * Called during re-authentication to ensure stale user data\n * is not carried over from a previous account.\n */\nexport function clearIdentityCache(): void {\n try {\n const config = loadTelemetryConfig();\n delete config.identifiedApiKeyHash;\n delete config.identifiedEmail;\n delete config.identifiedName;\n saveTelemetryConfig(config);\n // Also clear the in-memory session cache so enrichAnalyticsContext re-fetches\n sessionDistinctId = null;\n } catch {\n // Best-effort — never block auth flows\n }\n}\n\n/**\n * Gracefully shutdown PostHog client.\n * Has a 1-second hard timeout to prevent blocking exit.\n */\nexport async function shutdownAnalytics(): Promise<void> {\n if (!client) return;\n\n try {\n await Promise.race([client.shutdown(), new Promise((resolve) => setTimeout(resolve, 1000).unref())]);\n } catch {\n // Silently ignore shutdown errors\n } finally {\n client = null;\n }\n}\n","/**\n * Pure stdout writer (extracted so {@link ./hints.ts} stays importable in\n * tests — `cli.ts` itself uses `import.meta.url` which ts-jest can't compile).\n *\n * Mirrors the existing `writeInfo` from `./cli.ts`: clears the current\n * progress line via `\\r\\x1b[K` and writes `<message>\\n`.\n */\nexport function writeInfo(message: string): void {\n process.stdout.write('\\r\\x1b[K' + message + '\\n');\n}\n","/**\n * Post-action hint primitives (LUA-180).\n *\n * Pure module (no `import.meta.url`, no analytics) so it's directly testable\n * via ts-jest. {@link ./cli.ts} re-exports these for back-compat with\n * existing call sites.\n *\n * The goal: every push/deploy/chat/sync/compile/test surface ends with a\n * one-line hint at the optimal next command — primarily `lua logs --type X`.\n * Users (especially LLM builders running `lua chat -m \"test\"`) should never\n * have to guess what to run next.\n */\n\nimport { writeInfo } from './write-info.js';\n\n/**\n * Returns true when post-action hints should be silently suppressed.\n * Honors the `LUA_NO_HINTS` env var (any truthy value disables hints).\n *\n * Used by both {@link writeTip}/{@link writeNextStep} and the\n * `withErrorHandling` `onError` hook so users can opt out of all hint noise\n * with a single env var.\n */\nexport function hintsDisabled(): boolean {\n const v = process.env.LUA_NO_HINTS;\n return v === '1' || v === 'true' || v === 'yes';\n}\n\n/**\n * Render a free-form tip line. Format: `✨ Tip: <message>`.\n *\n * Honors {@link hintsDisabled} (LUA_NO_HINTS=1 silently no-ops). For tips\n * that point at a specific follow-up command, prefer {@link writeNextStep}\n * which renders the command in backticks with a consistent verb.\n */\nexport function writeTip(message: string): void {\n if (hintsDisabled()) return;\n writeInfo(`✨ Tip: ${message}`);\n}\n\n/**\n * Options for {@link writeNextStep}.\n */\nexport interface NextStepOptions {\n /**\n * The follow-up command to surface, e.g. `\"lua logs --type skill --limit 10\"`.\n * Rendered in backticks.\n */\n command: string;\n /**\n * Optional rationale appended after the command. A trailing period is added\n * automatically if missing, e.g.\n * rationale: \"to inspect runtime behavior\"\n * → `✨ Tip: run \\`<cmd>\\` to inspect runtime behavior.`\n */\n rationale?: string;\n /**\n * Controls icon and label.\n * - `success` (default) → `✨ Tip: run \\`<cmd>\\` ...`\n * - `error` → `💡 Diagnose: run \\`<cmd>\\` ...`\n * - `partial` → `⚠️ Diagnose: run \\`<cmd>\\` ...`\n */\n when?: 'success' | 'error' | 'partial';\n}\n\n/**\n * Render a \"what to do next\" hint pointing at a specific CLI command.\n * Used after every push/deploy/chat/sync/compile/test action to make\n * the optimal next command obvious to users and AI builders.\n *\n * Honors {@link hintsDisabled} (LUA_NO_HINTS=1 silently no-ops).\n */\nexport function writeNextStep(opts: NextStepOptions): void {\n if (hintsDisabled()) return;\n const when = opts.when ?? 'success';\n const icon = when === 'error' ? '💡' : when === 'partial' ? '⚠️ ' : '✨';\n const label = when === 'success' ? 'Tip' : 'Diagnose';\n const rationale = opts.rationale?.trim();\n const tail = rationale ? ` ${rationale}${/[.!?]$/.test(rationale) ? '' : '.'}` : '';\n writeInfo(`${icon} ${label}: run \\`${opts.command}\\`${tail}`);\n}\n\nexport interface HintBlockLine {\n label: string;\n command: string;\n}\n\n/**\n * Render a multi-line contextual hint block.\n * Used when the optimal next action involves a sequence of commands or\n * when a single-line hint would be too narrow (e.g., deploy-then-test).\n *\n * Output format:\n * ✨ <headline>\n * <label> <command>\n * <label> <command>\n */\nexport function writeHintBlock(opts: {\n headline: string;\n lines: HintBlockLine[];\n when?: 'success' | 'error' | 'partial';\n}): void {\n if (hintsDisabled()) return;\n const validLines = opts.lines.filter((l) => l.command && l.command.trim().length > 0);\n const when = opts.when ?? 'success';\n const icon = when === 'error' ? '💡' : when === 'partial' ? '⚠️ ' : '✨';\n if (validLines.length === 0) {\n writeInfo(`${icon} ${opts.headline}`);\n return;\n }\n writeInfo(`${icon} ${opts.headline}`);\n const maxLabelLen = Math.max(...validLines.map((l) => l.label.length));\n for (const { label, command } of validLines) {\n writeInfo(` ${label.padEnd(maxLabelLen)} \\`${command}\\``);\n }\n}\n","/**\n * Centralized CLI utilities for consistent error handling and output management\n */\n\nimport { AuthenticationError } from '../errors/auth.error.js';\nimport { isUpdateAvailable, printUpdateWarning } from './version-check.js';\nimport { getCliVersion } from './package-root.js';\nimport {\n trackCommand,\n shutdownAnalytics,\n showTelemetryNoticeIfNeeded,\n enrichAnalyticsContext,\n} from '../services/analytics.js';\nimport { hintsDisabled, writeTip, writeNextStep, writeHintBlock } from './hints.js';\nimport type { NextStepOptions, HintBlockLine } from './hints.js';\n\n// Re-export hint primitives so existing call sites can keep importing from\n// `utils/cli.js`. The implementations live in `utils/hints.ts` (a pure\n// module) so they're testable without the `import.meta.url` machinery\n// below.\nexport { hintsDisabled, writeTip, writeNextStep, writeHintBlock };\nexport type { NextStepOptions, HintBlockLine };\n\n/**\n * Global state for CI mode\n * When true, interactive prompts will throw errors instead of silently returning null\n */\nlet isCiMode = false;\n\n/**\n * Set CI mode flag\n */\nexport function setCiMode(enabled: boolean): void {\n isCiMode = enabled;\n}\n\n/**\n * Check if CI mode is enabled\n */\nexport function isCiModeEnabled(): boolean {\n return isCiMode;\n}\n\n/**\n * Await the background version check and print a warning if outdated.\n * Silently catches any errors from the check itself.\n */\nasync function showUpdateWarningIfNeeded(\n versionCheckPromise: Promise<{ available: boolean; latest: string | null } | null>\n): Promise<void> {\n try {\n const result = await versionCheckPromise;\n if (result?.available && result.latest) {\n printUpdateWarning(getCliVersion(), result.latest);\n }\n } catch {\n // Silently ignore version check failures\n }\n}\n\n/**\n * Options for {@link withErrorHandling}.\n */\nexport interface WithErrorHandlingOptions {\n /**\n * Optional hint provider invoked once when the command throws a generic\n * (non-auth, non-Ctrl+C) error. The returned string is rendered as\n * `💡 <hint>` on stderr, immediately after the standard\n * `❌ Error during <command>:` line. Used by command authors to suggest\n * a contextual `lua logs` command. Return `null` to skip.\n *\n * Errors thrown inside the hint provider are swallowed so a buggy\n * provider never replaces the original error in the UX.\n */\n onError?: (err: Error) => string | null | undefined;\n}\n\n/**\n * Wraps a command function with standardized error handling\n * Handles SIGINT (Ctrl+C) gracefully and provides consistent error messages.\n * Also runs a background version check and warns if an update is available.\n *\n * @param opts.onError Optional hint provider; see {@link WithErrorHandlingOptions}.\n */\nexport async function withErrorHandling<T>(\n commandFn: () => Promise<T>,\n commandName: string,\n opts?: WithErrorHandlingOptions\n): Promise<T> {\n showTelemetryNoticeIfNeeded();\n await enrichAnalyticsContext();\n const startTime = Date.now();\n\n // Start version check in background (non-blocking, runs in parallel with command)\n // Skip for the 'update' command (it handles version checking itself)\n const versionCheckPromise =\n commandName !== 'update' ? isUpdateAvailable(getCliVersion()).catch(() => null) : Promise.resolve(null);\n\n try {\n const result = await commandFn();\n\n trackCommand({\n commandName,\n success: true,\n durationMs: Date.now() - startTime,\n cliVersion: getCliVersion(),\n });\n\n await showUpdateWarningIfNeeded(versionCheckPromise);\n await shutdownAnalytics();\n return result;\n } catch (error: any) {\n if (error.name === 'ExitPromptError') {\n trackCommand({\n commandName,\n success: true,\n durationMs: Date.now() - startTime,\n cliVersion: getCliVersion(),\n properties: { cancelled: true },\n });\n await shutdownAnalytics();\n process.exit(0);\n }\n\n trackCommand({\n commandName,\n success: false,\n durationMs: Date.now() - startTime,\n cliVersion: getCliVersion(),\n error: error.message,\n properties: { is_auth_error: AuthenticationError.isAuthenticationError(error) },\n });\n\n if (AuthenticationError.isAuthenticationError(error)) {\n console.error(`\\n❌ ${error.message}`);\n // Tailor the remediation hint to the actual reason — see BAC-202.\n // The same 401 status can mean either \"your key is bad\" or \"your key\n // is fine but you don't own the agentId in lua.skill.yaml\". Sending\n // users to `lua auth configure` for the second case is a dead end.\n // Throw sites with richer context (e.g. getToken() listing all three\n // ways to provide a key) set suppressDefaultRemediation to keep the\n // CLI from printing a duplicate, less specific hint after their\n // already-formatted message.\n if (!error.suppressDefaultRemediation) {\n if (error.reason === 'no_agent_access') {\n console.error(\n '\\n Your API key is valid, but it does not have access to the agentId\\n' +\n ' configured in lua.skill.yaml. This usually means:\\n' +\n '\\n' +\n ' • The agentId belongs to a different account or organization\\n' +\n ' • The agent was deleted, transferred, or you lost access to it\\n' +\n \" • You're using a lua.skill.yaml copied from another project\\n\" +\n '\\n' +\n ' Check the configured agent and switch if needed:\\n' +\n '\\n' +\n ' ➜ lua agents (list agents you have access to)\\n' +\n ' ➜ lua init (re-select the agent for this project)\\n'\n );\n } else {\n console.error(\n '\\n Re-authenticate or check your API key:\\n' +\n '\\n' +\n ' ➜ lua auth configure\\n' +\n ' ➜ https://admin.heylua.ai\\n'\n );\n }\n } else {\n // Add a trailing newline for visual parity with the branches above.\n console.error('');\n }\n await showUpdateWarningIfNeeded(versionCheckPromise);\n await shutdownAnalytics();\n process.exit(1);\n }\n\n console.error(`❌ Error during ${commandName}:`, error.message);\n\n if (opts?.onError && !hintsDisabled()) {\n try {\n const hint = opts.onError(error);\n if (hint) {\n console.error(`💡 ${hint}`);\n }\n } catch {\n // Buggy hint provider must never replace the real error.\n }\n }\n\n await showUpdateWarningIfNeeded(versionCheckPromise);\n await shutdownAnalytics();\n throw new Error(`Error during ${commandName}: ${error.message}`);\n }\n}\n\n/**\n * Clears the specified number of lines from the terminal\n * Used to clean up inquirer prompt output ONLY\n * Should NOT be used to clear user input commands\n */\nexport function clearPromptLines(count: number = 1): void {\n for (let i = 0; i < count; i++) {\n process.stdout.write('\\x1b[1A\\x1b[2K'); // Move up 1 line and clear it\n }\n}\n\n/**\n * Writes a progress message that overwrites the current line\n * Uses carriage return to replace previous progress messages\n */\nexport function writeProgress(message: string): void {\n // Clear current line and write message (no newline - will be overwritten)\n process.stdout.write('\\r\\x1b[K' + message);\n}\n\n/**\n * Writes a final success message that will remain visible\n * Clears the progress line first, then writes the message with newline\n */\nexport function writeSuccess(message: string): void {\n // Clear any progress message, write message, and ensure newline\n process.stdout.write('\\r\\x1b[K' + message + '\\n');\n}\n\n/**\n * Writes an error message\n * Clears the progress line first, then writes the error with newline\n */\nexport function writeError(message: string): void {\n // Clear any progress message, write error, and ensure newline\n process.stderr.write('\\r\\x1b[K' + message + '\\n');\n}\n\n// `writeInfo` is exported from `./write-info.ts` and re-exported below so\n// existing callers can keep importing from `utils/cli.js`.\nexport { writeInfo } from './write-info.js';\n","/**\n * Command Utilities\n * Shared utilities for command initialization and common operations\n */\n\nimport { getToken, checkApiKey } from '../services/auth.js';\nimport { readYamlConfig } from './files.js';\nimport { writeProgress } from './cli.js';\nimport { YamlConfig } from '../types/yaml.types.js';\n\n/**\n * Context returned by initializeCommand for use in command handlers\n */\nexport interface CommandContext {\n config: YamlConfig;\n agentId: string;\n orgId: string;\n apiKey: string;\n userData?: any;\n}\n\n/**\n * Loads and returns the API key.\n * Does NOT validate with server — the first actual API call will validate\n * (HttpClient throws AuthenticationError on 401, caught by withErrorHandling).\n *\n * @returns The API key\n * @throws AuthenticationError if no API key found\n */\nexport function requireAuth(): string {\n return getToken();\n}\n\n/**\n * Loads and returns the API key.\n * Does NOT validate with server — lazy validation on first API call.\n *\n * @returns The API key\n * @throws AuthenticationError if no API key found\n */\nexport function requireAuthOrExit(showProgress: boolean = true): string {\n const apiKey = getToken();\n if (showProgress) {\n writeProgress('✅ Authenticated');\n }\n return apiKey;\n}\n\n/**\n * Full command initialization - validates config + loads auth, returns context.\n * Auth is lazy by default — set validateAuth: true when you need userData.\n *\n * @param options - Optional configuration\n * @param options.showProgress - Whether to show progress messages (default: true)\n * @param options.validateAuth - Validate API key with server and fetch userData (default: false)\n * @returns Command context with config, agentId, apiKey, and optionally userData\n */\nexport async function initializeCommand(\n options: {\n showProgress?: boolean;\n validateAuth?: boolean;\n } = {}\n): Promise<CommandContext> {\n const { showProgress = true, validateAuth = false } = options;\n\n // Validate config exists\n const config = readYamlConfig();\n if (!config) {\n throw new Error('No lua.skill.yaml found. Please run this command from a skill directory.');\n }\n\n // Validate agent config\n if (!config.agent?.agentId) {\n throw new Error(\"Missing agentId in skill configuration. Please run 'lua init' first.\");\n }\n\n // Validate org config\n if (!config.agent?.orgId) {\n throw new Error(\"Missing orgId in skill configuration. Please run 'lua init' first.\");\n }\n\n // Load API key (throws AuthenticationError if missing)\n const apiKey = getToken();\n\n let userData: any = undefined;\n if (validateAuth) {\n userData = await checkApiKey(apiKey);\n }\n\n if (showProgress) {\n writeProgress('✅ Authenticated');\n }\n\n return {\n config,\n agentId: config.agent.agentId,\n orgId: config.agent.orgId,\n apiKey,\n userData,\n };\n}\n","/**\n * API Credentials Management\n * Handles loading and caching of API credentials for skill execution\n */\n\nimport { requireAuth } from '../utils/command-utils.js';\nimport { readYamlConfig } from '../utils/files.js';\n\n/**\n * API credentials structure\n */\nexport interface ApiCredentials {\n apiKey: string;\n agentId: string;\n}\n\n/**\n * Cached credentials to avoid repeated file/keychain access\n */\nlet cachedCredentials: ApiCredentials | null = null;\n\n/**\n * Gets API credentials from keystore and configuration.\n * Results are cached for subsequent calls.\n *\n * @returns API key and agent ID\n * @throws Error if credentials are not found or incomplete\n */\nexport async function getCredentials(): Promise<ApiCredentials> {\n // Return cached credentials if available\n if (cachedCredentials) {\n return cachedCredentials;\n }\n\n // Load and validate API key from keystore\n const apiKey = await requireAuth();\n\n // Load agent ID from YAML file\n const config = readYamlConfig();\n if (!config?.agent?.agentId) {\n throw new Error('No agent ID found in lua.skill.yaml. Please run \"lua init\" first.');\n }\n\n // Cache and return credentials\n cachedCredentials = {\n apiKey,\n agentId: config.agent.agentId,\n };\n\n return cachedCredentials;\n}\n\n/**\n * Clears the cached credentials.\n * Useful for testing or when credentials change.\n */\nexport function clearCredentialsCache(): void {\n cachedCredentials = null;\n}\n","import { Product } from '../interfaces/product.js';\nimport ProductAPI from '../api/products.api.service.js';\n\n/**\n * Product instance class providing a fluent API for managing individual products\n * Provides methods for updating and deleting products\n * Supports direct property access (e.g., product.name) instead of product.data.name\n */\nexport default class ProductInstance {\n data: Product;\n private productAPI!: ProductAPI; // Use definite assignment assertion\n\n // Index signature to allow dynamic property access\n [key: string]: any;\n\n /**\n * Creates a new ProductInstance with proxy support for direct property access\n * @param api - The ProductAPI instance for making API calls\n * @param product - The product data from the API\n * @returns Proxied instance that allows direct access to product properties\n */\n constructor(api: any, product: Product) {\n // Ensure data is always an object, never null or undefined\n this.data = product && typeof product === 'object' ? product : ({} as Product);\n\n // Make productAPI non-enumerable so it doesn't show up in console.log\n Object.defineProperty(this, 'productAPI', {\n value: api,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n\n // Return a proxy that allows direct property access\n return new Proxy(this, {\n get(target, prop, receiver) {\n // If the property exists on the instance itself, return it\n if (prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n // Otherwise, try to get it from the data object (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return target.data[prop];\n }\n return undefined;\n },\n set(target, prop, value, receiver) {\n // Reserved properties that should be set on the instance itself\n const reservedProps = ['data', 'productAPI', 'update', 'delete', 'toJSON'];\n if (typeof prop === 'string' && reservedProps.includes(prop)) {\n return Reflect.set(target, prop, value, receiver);\n }\n // All other properties get set on the data object\n if (typeof prop === 'string') {\n // Initialize data object if it doesn't exist\n if (!target.data || typeof target.data !== 'object') {\n target.data = {} as Product;\n }\n target.data[prop] = value;\n return true;\n }\n return false;\n },\n has(target, prop) {\n // Check if property exists on instance or in data (with null check)\n if (prop in target) {\n return true;\n }\n if (typeof prop === 'string' && target.data && typeof target.data === 'object') {\n return prop in target.data;\n }\n return false;\n },\n ownKeys(target) {\n // Return both instance keys and data keys (with null check)\n const instanceKeys = Reflect.ownKeys(target);\n const dataKeys = target.data && typeof target.data === 'object' ? Object.keys(target.data) : [];\n return [...new Set([...instanceKeys, ...dataKeys])];\n },\n getOwnPropertyDescriptor(target, prop) {\n // First check if it's an instance property\n const instanceDesc = Reflect.getOwnPropertyDescriptor(target, prop);\n if (instanceDesc) {\n return instanceDesc;\n }\n // Then check if it's a data property (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: target.data[prop],\n };\n }\n return undefined;\n },\n });\n }\n\n /**\n * Custom toJSON method to control what gets serialized when logging\n * @returns Serialized product data\n */\n toJSON(): Record<string, any> {\n return this.data;\n }\n\n /**\n * Custom inspect method for Node.js console.log\n * @returns Formatted product data for console output\n */\n [Symbol.for('nodejs.util.inspect.custom')](): Record<string, any> {\n return this.data;\n }\n\n /**\n * Updates the product's data\n * @param data - The product fields to update (partial update supported)\n * @returns Promise resolving to the updated Product\n * @throws Error if the update fails or the product is not found\n */\n async update(data: Record<string, any>): Promise<Product> {\n const response = await this.productAPI.update(data, this.data.id);\n if (response.updated) {\n this.data = response.product;\n return this.data;\n } else {\n throw new Error('Failed to update product');\n }\n }\n\n /**\n * Deletes the product from the catalog\n * @returns Promise resolving to an empty Product object if deletion was successful\n * @throws Error if the deletion fails or the product is not found\n */\n async delete(): Promise<Product> {\n const response = await this.productAPI.delete(this.data.id);\n if (response.deleted) {\n this.data = {} as Product;\n }\n return this.data;\n }\n\n /**\n * Saves the product's data\n * @returns Promise resolving to true if saving was successful\n * @throws Error if the save operation fails\n */\n async save(): Promise<boolean> {\n try {\n await this.productAPI.update(this.data, this.data.id);\n return true;\n } catch (error) {\n throw new Error('Failed to save product data');\n }\n }\n}\n","import { Product, ProductsResponse } from '../interfaces/product.js';\nimport ProductInstance from './product.instance.js';\n\n/**\n * Product pagination instance class providing a fluent API for paginated product results\n * Provides methods for navigating through pages of products\n * Supports array methods like map, filter, forEach for direct iteration\n */\nexport default class ProductPaginationInstance {\n products: ProductInstance[];\n pagination: {\n currentPage: number;\n totalPages: number;\n totalCount: number;\n limit: number;\n hasNextPage: boolean;\n hasPrevPage: boolean;\n nextPage: number | null;\n prevPage: number | null;\n };\n private productAPI!: any; // Use definite assignment assertion\n\n /**\n * Creates a new ProductPaginationInstance\n * @param api - The ProductAPI instance for making API calls\n * @param results - The paginated product results from the API\n */\n constructor(api: any, results: ProductsResponse) {\n // Ensure products array is always initialized, with null checks\n const productsData = results?.data;\n this.products = (Array.isArray(productsData) ? productsData : []).map(\n (product) => new ProductInstance(api, product)\n );\n\n // Ensure pagination is always initialized with safe defaults\n this.pagination = results?.pagination || {\n currentPage: 1,\n totalPages: 1,\n totalCount: 0,\n limit: 10,\n hasNextPage: false,\n hasPrevPage: false,\n nextPage: null,\n prevPage: null,\n };\n\n // Make productAPI non-enumerable so it doesn't show up in console.log\n Object.defineProperty(this, 'productAPI', {\n value: api,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n }\n\n /**\n * Returns the number of products in the current page\n */\n get length(): number {\n return this.products.length;\n }\n\n /**\n * Maps over the products array\n * @param callback - Function to execute for each product\n * @returns Array of mapped results\n */\n map<T>(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => T): T[] {\n return this.products.map(callback);\n }\n\n /**\n * Filters the products array\n * @param callback - Function to test each product\n * @returns Array of products that pass the test\n */\n filter(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): ProductInstance[] {\n return this.products.filter(callback);\n }\n\n /**\n * Executes a function for each product\n * @param callback - Function to execute for each product\n */\n forEach(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => void): void {\n this.products.forEach(callback);\n }\n\n /**\n * Finds the first product that satisfies the test\n * @param callback - Function to test each product\n * @returns The first product that passes the test, or undefined\n */\n find(\n callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean\n ): ProductInstance | undefined {\n return this.products.find(callback);\n }\n\n /**\n * Finds the index of the first product that satisfies the test\n * @param callback - Function to test each product\n * @returns The index of the first product that passes the test, or -1\n */\n findIndex(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): number {\n return this.products.findIndex(callback);\n }\n\n /**\n * Checks if some products satisfy the test\n * @param callback - Function to test each product\n * @returns true if at least one product passes the test\n */\n some(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): boolean {\n return this.products.some(callback);\n }\n\n /**\n * Checks if all products satisfy the test\n * @param callback - Function to test each product\n * @returns true if all products pass the test\n */\n every(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): boolean {\n return this.products.every(callback);\n }\n\n /**\n * Reduces the products array to a single value\n * @param callback - Function to execute on each product\n * @param initialValue - Initial value for the accumulator\n * @returns The final accumulated value\n */\n reduce<T>(\n callback: (accumulator: T, product: ProductInstance, index: number, array: ProductInstance[]) => T,\n initialValue: T\n ): T {\n return this.products.reduce(callback, initialValue);\n }\n\n /**\n * Makes the instance iterable\n * @returns Iterator for the products array\n */\n [Symbol.iterator](): Iterator<ProductInstance> {\n return this.products[Symbol.iterator]();\n }\n\n /**\n * Custom toJSON method to control what gets serialized when logging\n * @returns Serialized products and pagination data\n */\n toJSON(): Record<string, any> {\n return {\n products: this.products,\n pagination: this.pagination,\n };\n }\n\n /**\n * Custom inspect method for Node.js console.log\n * @returns Formatted products and pagination data for console output\n */\n [Symbol.for('nodejs.util.inspect.custom')](): Record<string, any> {\n return {\n products: this.products,\n pagination: this.pagination,\n };\n }\n\n /**\n * Fetches the next page of products\n * @returns Promise resolving to a new ProductPaginationInstance for the next page\n * @throws Error if there is no next page available\n */\n async nextPage(): Promise<ProductPaginationInstance> {\n if (!this.pagination.nextPage) {\n throw new Error('No next page');\n }\n return await this.productAPI.get(this.pagination.nextPage, this.pagination.limit);\n }\n\n /**\n * Fetches the previous page of products\n * @returns Promise resolving to a new ProductPaginationInstance for the previous page\n * @throws Error if there is no previous page available\n */\n async prevPage(): Promise<ProductPaginationInstance> {\n if (!this.pagination.prevPage) {\n throw new Error('No previous page');\n }\n return await this.productAPI.get(this.pagination.prevPage, this.pagination.limit);\n }\n}\n","import { SearchProductsResponse } from '../interfaces/product.js';\nimport { ProductAPI } from '../types/index.js';\nimport ProductInstance from './product.instance.js';\n\n/**\n * Product search instance class providing a fluent API for product search results\n * Contains an array of ProductInstance objects matching the search query\n * Supports array methods like map, filter, forEach for direct iteration\n */\nexport default class ProductSearchInstance {\n products: ProductInstance[];\n private productAPI!: ProductAPI; // Use definite assignment assertion\n\n /**\n * Creates a new ProductSearchInstance\n * @param api - The ProductAPI instance for making API calls\n * @param results - The product search results from the API\n */\n constructor(api: ProductAPI, results: SearchProductsResponse) {\n // Ensure products array is always initialized, with null checks\n const productsData = results?.data;\n this.products = (Array.isArray(productsData) ? productsData : []).map(\n (product) => new ProductInstance(api, product)\n );\n\n // Make productAPI non-enumerable so it doesn't show up in console.log\n Object.defineProperty(this, 'productAPI', {\n value: api,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n }\n\n /**\n * Returns the number of products in the search results\n */\n get length(): number {\n return this.products.length;\n }\n\n /**\n * Maps over the products array\n * @param callback - Function to execute for each product\n * @returns Array of mapped results\n */\n map<T>(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => T): T[] {\n return this.products.map(callback);\n }\n\n /**\n * Filters the products array\n * @param callback - Function to test each product\n * @returns Array of products that pass the test\n */\n filter(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): ProductInstance[] {\n return this.products.filter(callback);\n }\n\n /**\n * Executes a function for each product\n * @param callback - Function to execute for each product\n */\n forEach(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => void): void {\n this.products.forEach(callback);\n }\n\n /**\n * Finds the first product that satisfies the test\n * @param callback - Function to test each product\n * @returns The first product that passes the test, or undefined\n */\n find(\n callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean\n ): ProductInstance | undefined {\n return this.products.find(callback);\n }\n\n /**\n * Finds the index of the first product that satisfies the test\n * @param callback - Function to test each product\n * @returns The index of the first product that passes the test, or -1\n */\n findIndex(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): number {\n return this.products.findIndex(callback);\n }\n\n /**\n * Checks if some products satisfy the test\n * @param callback - Function to test each product\n * @returns true if at least one product passes the test\n */\n some(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): boolean {\n return this.products.some(callback);\n }\n\n /**\n * Checks if all products satisfy the test\n * @param callback - Function to test each product\n * @returns true if all products pass the test\n */\n every(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): boolean {\n return this.products.every(callback);\n }\n\n /**\n * Reduces the products array to a single value\n * @param callback - Function to execute on each product\n * @param initialValue - Initial value for the accumulator\n * @returns The final accumulated value\n */\n reduce<T>(\n callback: (accumulator: T, product: ProductInstance, index: number, array: ProductInstance[]) => T,\n initialValue: T\n ): T {\n return this.products.reduce(callback, initialValue);\n }\n\n /**\n * Makes the instance iterable\n * @returns Iterator for the products array\n */\n [Symbol.iterator](): Iterator<ProductInstance> {\n return this.products[Symbol.iterator]();\n }\n\n /**\n * Custom toJSON method to control what gets serialized when logging\n * @returns Serialized search results with product data\n */\n toJSON(): Record<string, any> {\n return {\n products: this.products,\n };\n }\n\n /**\n * Custom inspect method for Node.js console.log\n * @returns Formatted search results for console output\n */\n [Symbol.for('nodejs.util.inspect.custom')](): Record<string, any> {\n return {\n products: this.products,\n };\n }\n}\n","import { ProductsResponse, ProductFilterOptions } from '../interfaces/product.js';\nimport { HttpClient } from './http.client.js';\nimport { ProductAPI } from '../types/index.js';\nimport { Product } from '../interfaces/product.js';\nimport { CreateProductResponse } from '../interfaces/product.js';\nimport { UpdateProductResponse } from '../interfaces/product.js';\nimport { DeleteProductResponse } from '../interfaces/product.js';\nimport { SearchProductsResponse } from '../interfaces/product.js';\nimport ProductInstance from '../instances/product.instance.js';\nimport ProductPaginationInstance from '../instances/product.pagination.instance.js';\nimport ProductSearchInstance from '../instances/product.search.instance.js';\n/**\n * Product API calls\n */\nexport default class ProductApi extends HttpClient implements ProductAPI {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of ProductApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Retrieves products for an agent with pagination and optional filtering.\n * Supports both legacy (page, limit) and new (options object) signatures.\n *\n * @example\n * // Legacy: Get products with pagination\n * await products.get(1, 10);\n *\n * // New: Get products with options object\n * await products.get({ page: 2, limit: 20 });\n *\n * // New: Filter products by category\n * await products.get({ filter: { category: \"Electronics\" } });\n *\n * // New: Filter with MongoDB operators\n * await products.get({ filter: { price: { $lte: 100 }, inStock: true } });\n */\n async get(page?: number, limit?: number): Promise<ProductPaginationInstance>;\n async get(options?: ProductFilterOptions): Promise<ProductPaginationInstance>;\n async get(pageOrOptions?: number | ProductFilterOptions, limitArg?: number): Promise<ProductPaginationInstance> {\n let page: number;\n let limit: number;\n let filter: Record<string, any> | undefined;\n\n // Check if first argument is a number (legacy signature) or an object (new signature)\n if (typeof pageOrOptions === 'number') {\n page = pageOrOptions;\n limit = limitArg ?? 10;\n } else {\n page = pageOrOptions?.page ?? 1;\n limit = pageOrOptions?.limit ?? 10;\n filter = pageOrOptions?.filter;\n }\n\n const queryParams = new URLSearchParams();\n queryParams.append('page', page.toString());\n queryParams.append('limit', limit.toString());\n if (filter) {\n queryParams.append('filter', JSON.stringify(filter));\n }\n\n const response = await this.httpGet<ProductsResponse>(\n `/developer/agents/${this.agentId}/products?${queryParams.toString()}`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success) {\n return new ProductPaginationInstance(this, response as ProductsResponse);\n }\n throw new Error(response.error?.message || 'Failed to get products');\n }\n\n /**\n * Retrieves a single product by its unique identifier\n * @param productId - The unique identifier of the product to retrieve\n * @returns Promise resolving to a ProductInstance representing the product\n * @throws Error if the product is not found or the request fails\n */\n async getById(productId: string): Promise<ProductInstance> {\n const response = await this.httpGet<Product>(`/developer/agents/${this.agentId}/products/${productId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return new ProductInstance(this, response.data);\n }\n throw new Error(response.error?.message || 'Failed to get product');\n }\n\n /**\n * Creates a new product in the agent's catalog\n * @param productData - The product data including name, description, price, images, and metadata\n * @returns Promise resolving to a ProductInstance representing the created product\n * @throws Error if the product creation fails or validation errors occur\n */\n async create(productData: Product): Promise<ProductInstance> {\n const response = await this.httpPost<CreateProductResponse>(\n `/developer/agents/${this.agentId}/products`,\n productData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return new ProductInstance(this, response.data.product);\n }\n throw new Error(response.error?.message || 'Failed to create product');\n }\n\n /**\n * Updates an existing product's information\n * @param productData - The product data fields to update (partial update supported)\n * @param productId - The unique identifier of the product to update\n * @returns Promise resolving to an UpdateProductResponse with the updated product details\n * @throws Error if the product is not found or the update fails\n */\n async update(productData: Record<string, any>, productId: string): Promise<UpdateProductResponse> {\n const response = await this.httpPut<UpdateProductResponse>(\n `/developer/agents/${this.agentId}/products`,\n { ...productData, id: productId },\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to update product');\n }\n\n /**\n * Deletes a product from the agent's catalog\n * @param productId - The unique identifier of the product to delete\n * @returns Promise resolving to a DeleteProductResponse confirming deletion\n * @throws Error if the product is not found or the deletion fails\n */\n async delete(productId: string): Promise<DeleteProductResponse> {\n const response = await this.httpDelete<DeleteProductResponse>(\n `/developer/agents/${this.agentId}/products/${productId}`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to delete product');\n }\n\n /**\n * Performs semantic search on products using a text query\n * @param searchQuery - The search text to find matching products\n * @param limit - The maximum number of products to return (default: 5)\n * @returns Promise resolving to a ProductSearchInstance containing search results\n * @throws Error if the search fails or the API request is unsuccessful\n */\n async search(searchQuery: string, limit: number = 5): Promise<ProductSearchInstance> {\n const response = await this.httpGet<SearchProductsResponse>(\n `/developer/agents/${this.agentId}/products/search?searchQuery=${encodeURIComponent(searchQuery)}&limit=${limit}`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success) {\n return new ProductSearchInstance(this, response as unknown as SearchProductsResponse);\n }\n throw new Error(response.error?.message || 'Failed to search products');\n }\n}\n","import { Basket, BasketCommon, BasketData, BasketItem, BasketStatus } from '../interfaces/baskets.js';\nimport { BasketAPI } from '../types/index.js';\nimport OrderInstance from './order.instance.js';\n\n/**\n * Basket instance class providing a fluent API for managing user baskets\n * Provides methods for adding/removing items, updating metadata, and placing orders\n * Supports direct property access (e.g., basket.items) for accessing data and common properties\n */\nexport default class BasketInstance {\n private id: string;\n private userId: string;\n private agentId: string;\n private data: BasketData;\n private common: BasketCommon;\n metadata: any;\n totalAmount: string | number;\n itemCount: number;\n status: BasketStatus;\n private basketAPI!: BasketAPI; // Use definite assignment assertion\n\n // Index signature to allow dynamic property access\n [key: string]: any;\n\n /**\n * Creates a new BasketInstance with proxy support for direct property access\n * @param api - The BasketAPI instance for making API calls\n * @param basket - The basket data from the API\n * @returns Proxied instance that allows direct access to data and common properties\n */\n constructor(api: BasketAPI, basket: Basket) {\n // Ensure data and common are always objects, never null or undefined\n this.data = basket.data && typeof basket.data === 'object' ? basket.data : ({} as BasketData);\n this.common = basket.common && typeof basket.common === 'object' ? basket.common : ({} as BasketCommon);\n this.id = basket.id;\n this.userId = basket.userId;\n this.agentId = basket.agentId;\n this.metadata = basket.data?.metadata || {};\n this.totalAmount = basket.common?.totalAmount || 0;\n this.itemCount = basket.common?.itemCount || 0;\n this.status = basket.common?.status || BasketStatus.ACTIVE;\n // Make basketAPI non-enumerable so it doesn't show up in console.log\n Object.defineProperty(this, 'basketAPI', {\n value: api,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n\n // Return a proxy that allows direct property access\n return new Proxy(this, {\n get(target, prop, receiver) {\n // If the property exists on the instance itself, return it\n if (prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n // Check data object (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return (target.data as any)[prop];\n }\n // Check common object (with null check)\n if (typeof prop === 'string' && target.common && typeof target.common === 'object' && prop in target.common) {\n return (target.common as any)[prop];\n }\n return undefined;\n },\n set(target, prop, value, receiver) {\n // Reserved properties that should be set on the instance itself\n const reservedProps = [\n 'id',\n 'userId',\n 'agentId',\n 'data',\n 'common',\n 'metadata',\n 'totalAmount',\n 'itemCount',\n 'status',\n 'basketAPI',\n 'updateMetadata',\n 'updateStatus',\n 'addItem',\n 'removeItem',\n 'clear',\n 'placeOrder',\n 'toJSON',\n ];\n if (typeof prop === 'string' && reservedProps.includes(prop)) {\n return Reflect.set(target, prop, value, receiver);\n }\n // Check if property exists in data or common, otherwise default to data\n if (typeof prop === 'string') {\n // Initialize objects if they don't exist\n if (!target.data || typeof target.data !== 'object') {\n target.data = {} as BasketData;\n }\n if (!target.common || typeof target.common !== 'object') {\n target.common = {} as BasketCommon;\n }\n if (prop in target.common) {\n (target.common as any)[prop] = value;\n } else {\n (target.data as any)[prop] = value;\n }\n return true;\n }\n return false;\n },\n has(target, prop) {\n // Check if property exists on instance, in data, or in common (with null checks)\n if (prop in target) {\n return true;\n }\n if (typeof prop === 'string') {\n if (target.data && typeof target.data === 'object' && prop in target.data) {\n return true;\n }\n if (target.common && typeof target.common === 'object' && prop in target.common) {\n return true;\n }\n }\n return false;\n },\n ownKeys(target) {\n // Return instance keys, data keys, and common keys (with null checks)\n const instanceKeys = Reflect.ownKeys(target);\n const dataKeys = target.data && typeof target.data === 'object' ? Object.keys(target.data) : [];\n const commonKeys = target.common && typeof target.common === 'object' ? Object.keys(target.common) : [];\n return [...new Set([...instanceKeys, ...dataKeys, ...commonKeys])];\n },\n getOwnPropertyDescriptor(target, prop) {\n // First check if it's an instance property\n const instanceDesc = Reflect.getOwnPropertyDescriptor(target, prop);\n if (instanceDesc) {\n return instanceDesc;\n }\n // Then check data properties (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: (target.data as any)[prop],\n };\n }\n // Then check common properties (with null check)\n if (typeof prop === 'string' && target.common && typeof target.common === 'object' && prop in target.common) {\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: (target.common as any)[prop],\n };\n }\n return undefined;\n },\n });\n }\n\n /**\n * Custom toJSON method to control what gets serialized when logging\n * @returns Serialized basket data combining data and common fields\n */\n toJSON(): Record<string, any> {\n return {\n ...this.data,\n ...this.common,\n id: this.id,\n };\n }\n\n /**\n * Custom inspect method for Node.js console.log\n * @returns Formatted basket data for console output\n */\n [Symbol.for('nodejs.util.inspect.custom')](): Record<string, any> {\n return {\n ...this.data,\n ...this.common,\n id: this.id,\n };\n }\n\n /**\n * Updates the basket's metadata\n * @param metadata - The metadata object to merge with existing metadata\n * @returns Promise resolving to the updated basket data\n * @throws Error if the metadata update fails\n */\n async updateMetadata(metadata: any): Promise<any> {\n await this.basketAPI.updateMetadata(this.id, metadata);\n this.data.metadata = { ...this.data.metadata, ...metadata };\n return { ...this.data, ...this.common };\n }\n\n /**\n * Updates the basket's status\n * @param status - The new basket status to set\n * @returns Promise resolving to the updated basket data\n * @throws Error if the status update fails\n */\n async updateStatus(status: BasketStatus): Promise<any> {\n await this.basketAPI.updateStatus(this.id, status);\n this.common.status = status;\n return { ...this.data, ...this.common };\n }\n\n /**\n * Updates the basket instance with new data from the API\n * @param basket - The updated basket data from the API\n * @returns The combined basket data and common fields\n * @private\n */\n private updateBasket(basket: Basket): any {\n this.data = basket.data;\n this.common = basket.common;\n this.id = basket.id;\n this.userId = basket.userId;\n this.agentId = basket.agentId;\n this.metadata = basket.data.metadata;\n this.totalAmount = basket.common.totalAmount;\n this.itemCount = basket.common.itemCount;\n this.status = basket.common.status;\n return { ...this.data, ...this.common };\n }\n\n /**\n * Adds an item to the basket\n * @param item - The basket item to add (must include productId and quantity)\n * @returns Promise resolving to the updated basket data\n * @throws Error if the item cannot be added\n */\n async addItem(item: BasketItem): Promise<any> {\n const basket = await this.basketAPI.addItem(this.id, item);\n return this.updateBasket(basket);\n }\n\n /**\n * Removes an item from the basket\n * @param itemId - The unique identifier of the item to remove\n * @returns Promise resolving to the updated basket data\n * @throws Error if the item cannot be removed or is not found\n */\n async removeItem(itemId: string): Promise<any> {\n const basket = await this.basketAPI.removeItem(this.id, itemId);\n return this.updateBasket(basket);\n }\n\n /**\n * Clears all items from the basket\n * @returns Promise resolving to the updated empty basket data\n * @throws Error if the clear operation fails\n */\n async clear(): Promise<any> {\n const basket = await this.basketAPI.clear(this.id);\n return this.updateBasket(basket);\n }\n\n /**\n * Places an order from the basket contents\n * @param data - Additional order data (shipping info, payment details, etc.)\n * @returns Promise resolving to an OrderInstance representing the created order\n * @throws Error if the order creation fails\n */\n async placeOrder(data: Record<string, any>): Promise<OrderInstance> {\n const order = await this.basketAPI.placeOrder(data, this.id);\n await this.updateStatus(BasketStatus.CHECKED_OUT);\n return order;\n }\n}\n","import OrderApi from '../api/order.api.service.js';\nimport { OrderResponse, OrderData, OrderCommon, OrderStatus } from '../interfaces/orders.js';\n\n/**\n * Order instance class providing a fluent API for managing orders\n * Provides methods for updating order status and order data\n * Supports direct property access (e.g., order.shippingAddress) for accessing data and common properties\n */\nexport default class OrderInstance {\n private data: OrderData;\n private common: OrderCommon;\n private id: string;\n private userId: string;\n private agentId: string;\n private orderId: string;\n private orderAPI!: OrderApi; // Use definite assignment assertion\n\n // Index signature to allow dynamic property access\n [key: string]: any;\n\n /**\n * Creates a new OrderInstance with proxy support for direct property access\n * @param api - The OrderApi instance for making API calls\n * @param order - The order response data from the API\n * @returns Proxied instance that allows direct access to data and common properties\n */\n constructor(api: OrderApi, order: OrderResponse) {\n // Ensure data and common are always objects, never null or undefined\n this.data = order.data && typeof order.data === 'object' ? order.data : ({} as OrderData);\n this.common = order.common && typeof order.common === 'object' ? order.common : ({} as OrderCommon);\n this.id = order.id;\n this.userId = order.userId;\n this.agentId = order.agentId;\n this.orderId = order.orderId;\n // Make orderAPI non-enumerable so it doesn't show up in console.log\n Object.defineProperty(this, 'orderAPI', {\n value: api,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n\n // Return a proxy that allows direct property access\n return new Proxy(this, {\n get(target, prop, receiver) {\n // If the property exists on the instance itself, return it\n if (prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n // Check data object (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return (target.data as any)[prop];\n }\n // Check common object (with null check)\n if (typeof prop === 'string' && target.common && typeof target.common === 'object' && prop in target.common) {\n return (target.common as any)[prop];\n }\n return undefined;\n },\n set(target, prop, value, receiver) {\n // Reserved properties that should be set on the instance itself\n const reservedProps = [\n 'data',\n 'common',\n 'id',\n 'userId',\n 'agentId',\n 'orderId',\n 'orderAPI',\n 'updateStatus',\n 'update',\n 'toJSON',\n ];\n if (typeof prop === 'string' && reservedProps.includes(prop)) {\n return Reflect.set(target, prop, value, receiver);\n }\n // Check if property exists in data or common, otherwise default to data\n if (typeof prop === 'string') {\n // Initialize objects if they don't exist\n if (!target.data || typeof target.data !== 'object') {\n target.data = {} as OrderData;\n }\n if (!target.common || typeof target.common !== 'object') {\n target.common = {} as OrderCommon;\n }\n if (prop in target.common) {\n (target.common as any)[prop] = value;\n } else {\n (target.data as any)[prop] = value;\n }\n return true;\n }\n return false;\n },\n has(target, prop) {\n // Check if property exists on instance, in data, or in common (with null checks)\n if (prop in target) {\n return true;\n }\n if (typeof prop === 'string') {\n if (target.data && typeof target.data === 'object' && prop in target.data) {\n return true;\n }\n if (target.common && typeof target.common === 'object' && prop in target.common) {\n return true;\n }\n }\n return false;\n },\n ownKeys(target) {\n // Return instance keys, data keys, and common keys (with null checks)\n const instanceKeys = Reflect.ownKeys(target);\n const dataKeys = target.data && typeof target.data === 'object' ? Object.keys(target.data) : [];\n const commonKeys = target.common && typeof target.common === 'object' ? Object.keys(target.common) : [];\n return [...new Set([...instanceKeys, ...dataKeys, ...commonKeys])];\n },\n getOwnPropertyDescriptor(target, prop) {\n // First check if it's an instance property\n const instanceDesc = Reflect.getOwnPropertyDescriptor(target, prop);\n if (instanceDesc) {\n return instanceDesc;\n }\n // Then check data properties (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: (target.data as any)[prop],\n };\n }\n // Then check common properties (with null check)\n if (typeof prop === 'string' && target.common && typeof target.common === 'object' && prop in target.common) {\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: (target.common as any)[prop],\n };\n }\n return undefined;\n },\n });\n }\n\n /**\n * Custom toJSON method to control what gets serialized when logging\n * @returns Serialized order data combining data and common fields\n */\n toJSON(): Record<string, any> {\n return {\n ...this.data,\n ...this.common,\n id: this.id,\n };\n }\n\n /**\n * Custom inspect method for Node.js console.log\n * @returns Formatted order data for console output\n */\n [Symbol.for('nodejs.util.inspect.custom')](): Record<string, any> {\n return {\n ...this.data,\n ...this.common,\n id: this.id,\n };\n }\n\n /**\n * Updates the order's status\n * @param status - The new order status (e.g., 'pending', 'processing', 'shipped', 'delivered', 'cancelled')\n * @returns Promise resolving to the updated order data\n * @throws Error if the status update fails\n */\n async updateStatus(status: OrderStatus): Promise<any> {\n const response = await this.orderAPI.updateStatus(status, this.id);\n this.common = response.common;\n return {\n ...this.data,\n ...this.common,\n id: this.id,\n };\n }\n\n /**\n * Updates the order's data\n * @param data - The data fields to update (e.g., shipping info, notes, metadata)\n * @returns Promise resolving to the updated order data\n * @throws Error if the data update fails\n */\n async update(data: Record<string, any>): Promise<any> {\n const response = await this.orderAPI.updateData(data, this.id);\n this.data = response.data;\n this.common = response.common;\n return {\n ...this.data,\n ...this.common,\n id: this.id,\n };\n }\n\n /**\n * Saves the order's data\n * @returns Promise resolving to true if saving was successful\n * @throws Error if the save operation fails\n */\n async save(): Promise<boolean> {\n try {\n await this.orderAPI.updateData(this.data, this.id);\n return true;\n } catch (error) {\n throw new Error('Failed to save order data');\n }\n }\n}\n","import { OrderAPI } from '../types/index.js';\nimport { HttpClient } from './http.client.js';\nimport { CreateOrderRequest, OrderResponse, OrderStatus } from '../interfaces/orders.js';\nimport OrderInstance from '../instances/order.instance.js';\n\nexport default class OrderApi extends HttpClient implements OrderAPI {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of OrderApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Creates a new order from a basket\n * @param orderData - The order creation request data containing basketId and additional order information\n * @returns Promise resolving to an OrderInstance representing the created order\n * @throws Error if the basket is not found or the order creation fails\n */\n async create(orderData: CreateOrderRequest): Promise<OrderInstance> {\n const response = await this.httpPost<OrderResponse>(`/developer/agents/${this.agentId}/order`, orderData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return new OrderInstance(this, response.data);\n }\n throw new Error(response.error?.message || 'Failed to create order');\n }\n\n /**\n * Updates the status of an existing order\n * @param status - The new order status (e.g., 'pending', 'processing', 'shipped', 'delivered', 'cancelled')\n * @param orderId - The unique identifier of the order to update\n * @returns Promise resolving to the updated OrderResponse\n * @throws Error if the order is not found or the status update fails\n */\n async updateStatus(status: OrderStatus, orderId: string): Promise<OrderResponse> {\n const response = await this.httpPut<OrderResponse>(\n `/developer/agents/${this.agentId}/order/${orderId}/${status}`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to update order status');\n }\n\n /**\n * Updates the data associated with an order\n * @param data - The data object containing fields to update (e.g., shipping info, notes, metadata)\n * @param orderId - The unique identifier of the order to update\n * @returns Promise resolving to the updated OrderResponse\n * @throws Error if the order is not found or the data update fails\n */\n async updateData(data: Record<string, any>, orderId: string): Promise<OrderResponse> {\n const response = await this.httpPut<OrderResponse>(`/developer/agents/${this.agentId}/order/${orderId}`, data, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to update order data');\n }\n\n /**\n * Retrieves all user orders with optional status filtering\n * @param status - Optional order status to filter by (e.g., 'pending', 'processing', 'shipped', 'delivered', 'cancelled')\n * @returns Promise resolving to an array of OrderInstance objects\n * @throws Error if the request fails or orders cannot be retrieved\n */\n async get(status?: OrderStatus): Promise<OrderInstance[]> {\n const statusParam = status ? `?status=${status}` : '';\n const response = await this.httpGet<OrderResponse[]>(`/developer/agents/${this.agentId}/order/user${statusParam}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return response.data.map((order) => new OrderInstance(this, order));\n }\n throw new Error(response.error?.message || 'Failed to get user orders');\n }\n\n /**\n * Retrieves a single order by its unique identifier\n * @param orderId - The unique identifier of the order to retrieve\n * @returns Promise resolving to an OrderInstance representing the order\n * @throws Error if the order is not found or the request fails\n */\n async getById(orderId: string): Promise<OrderInstance> {\n const response = await this.httpGet<OrderResponse>(`/developer/agents/${this.agentId}/order/${orderId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return new OrderInstance(this, response.data);\n }\n throw new Error(response.error?.message || 'Failed to get order');\n }\n}\n","import BasketInstance from '../instances/basket.instance.js';\nimport { HttpClient } from './http.client.js';\nimport OrderInstance from '../instances/order.instance.js';\nimport { BasketStatus, CreateBasketRequest, AddItemToBasketRequest, Basket } from '../interfaces/baskets.js';\nimport { OrderResponse } from '../interfaces/orders.js';\nimport { BasketAPI } from '../types/index.js';\nimport OrderApi from './order.api.service.js';\n\nexport default class BasketApi extends HttpClient implements BasketAPI {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of BasketApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Creates a new user basket\n * @param basketData - The basket creation request data containing user ID and optional metadata\n * @returns Promise resolving to a BasketInstance representing the created basket\n * @throws Error if the basket creation fails or the API request is unsuccessful\n */\n async create(basketData: CreateBasketRequest): Promise<BasketInstance> {\n const response = await this.httpPost<Basket>(`/developer/agents/${this.agentId}/basket`, basketData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return new BasketInstance(this, response.data);\n }\n throw new Error(response.error?.message || 'Failed to create basket');\n }\n\n /**\n * Retrieves all user baskets with optional status filtering\n * @param status - Optional basket status to filter by (e.g., 'active', 'completed', 'abandoned')\n * @returns Promise resolving to an array of BasketInstance objects\n * @throws Error if the request fails or baskets cannot be retrieved\n */\n async get(status?: BasketStatus): Promise<BasketInstance[]> {\n const statusParam = status ? `?status=${status}` : '';\n const response = await this.httpGet<Basket[]>(`/developer/agents/${this.agentId}/basket/user${statusParam}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n\n if (response.success && response.data) {\n return response.data.map((basket: Basket) => new BasketInstance(this, basket));\n }\n throw new Error(response.error?.message || 'Failed to get user baskets');\n }\n\n /**\n * Retrieves a single basket by its unique identifier\n * @param basketId - The unique identifier of the basket to retrieve\n * @returns Promise resolving to a BasketInstance representing the basket\n * @throws Error if the basket is not found or the request fails\n */\n async getById(basketId: string): Promise<BasketInstance> {\n const response = await this.httpGet<Basket>(`/developer/agents/${this.agentId}/basket/${basketId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return new BasketInstance(this, response.data as Basket);\n }\n throw new Error(response.error?.message || 'Failed to get basket');\n }\n\n /**\n * Adds an item to a specific basket\n * @param basketId - The unique identifier of the basket\n * @param itemData - The item data including product ID, quantity, and optional metadata\n * @returns Promise resolving to the updated Basket object\n * @throws Error if the basket is not found or the item cannot be added\n */\n async addItem(basketId: string, itemData: AddItemToBasketRequest): Promise<Basket> {\n const response = await this.httpPost<Basket>(\n `/developer/agents/${this.agentId}/basket/${basketId}/item`,\n itemData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to add item to basket');\n }\n\n /**\n * Removes a specific item from a basket\n * @param basketId - The unique identifier of the basket\n * @param itemId - The unique identifier of the item to remove\n * @returns Promise resolving to the updated Basket object\n * @throws Error if the basket or item is not found or the removal fails\n */\n async removeItem(basketId: string, itemId: string): Promise<Basket> {\n const response = await this.httpDelete<Basket>(\n `/developer/agents/${this.agentId}/basket/${basketId}/item/${itemId}`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to remove item from basket');\n }\n\n /**\n * Clears all items from a basket\n * @param basketId - The unique identifier of the basket to clear\n * @returns Promise resolving to the updated empty Basket object\n * @throws Error if the basket is not found or the clear operation fails\n */\n async clear(basketId: string): Promise<Basket> {\n const response = await this.httpDelete<Basket>(`/developer/agents/${this.agentId}/basket/${basketId}/clear`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to clear basket');\n }\n\n /**\n * Updates the status of a basket\n * @param basketId - The unique identifier of the basket\n * @param status - The new status to set for the basket\n * @returns Promise resolving to the updated BasketStatus\n * @throws Error if the basket is not found or the status update fails\n */\n async updateStatus(basketId: string, status: BasketStatus): Promise<BasketStatus> {\n const response = await this.httpPut<Basket>(\n `/developer/agents/${this.agentId}/basket/${basketId}/${status}`,\n undefined,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success) {\n return status;\n }\n throw new Error(response.error?.message || 'Failed to update basket status');\n }\n\n /**\n * Updates the metadata of a basket\n * @param basketId - The unique identifier of the basket\n * @param metadata - The metadata object to update or merge with existing metadata\n * @returns Promise resolving to the updated metadata\n * @throws Error if the basket is not found or the metadata update fails\n */\n async updateMetadata(basketId: string, metadata: Record<string, any>): Promise<Record<string, any>> {\n const response = await this.httpPut<Basket>(\n `/developer/agents/${this.agentId}/basket/${basketId}/metadata`,\n metadata,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success) {\n return metadata;\n }\n throw new Error(response.error?.message || 'Failed to update basket metadata');\n }\n\n /**\n * Creates an order from a basket\n * @param data - Additional order data (shipping info, payment details, etc.)\n * @param basketId - The unique identifier of the basket to convert to an order\n * @returns Promise resolving to an OrderInstance representing the created order\n * @throws Error if the basket is not found or the order creation fails\n */\n async placeOrder(data: Record<string, any>, basketId: string): Promise<OrderInstance> {\n const response = await this.httpPost<OrderResponse>(\n `/developer/agents/${this.agentId}/order`,\n { basketId, data },\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n const orderApi = new OrderApi(this.baseUrl, this.apiKey, this.agentId);\n return new OrderInstance(orderApi, response.data);\n }\n throw new Error(response.error?.message || 'Failed to create order');\n }\n}\n","import { Message } from '../interfaces/message.js';\nimport { UserDataAPI } from '../types/index.js';\nimport { ImmutableUserProfile, UserAgentData } from '../interfaces/user.js';\nimport type { ChatHistoryMessage } from '@lua/shared-types';\n\n/**\n * User data instance class providing a fluent API for managing user data\n * Provides methods for updating and clearing data\n * Supports direct property access (e.g., user.name) instead of user.data.name\n */\nexport default class UserDataInstance {\n data: UserAgentData;\n private userAPI!: UserDataAPI; // Use definite assignment assertion\n _luaProfile!: ImmutableUserProfile; // Immutable Lua user profile\n\n // Index signature to allow dynamic property access\n [key: string]: any;\n\n /**\n * Creates a new UserDataInstance with proxy support for direct property access\n * @param api - The UserDataAPI instance for making API calls\n * @param data - The user data from the API\n * @param profile - The immutable user profile data\n * @returns Proxied instance that allows direct access to data properties\n */\n constructor(api: UserDataAPI, data: any, profile?: ImmutableUserProfile) {\n // Ensure data is always an object, never null or undefined\n this.data = data && typeof data === 'object' ? data : {};\n\n // Make userAPI non-enumerable so it doesn't show up in console.log\n Object.defineProperty(this, 'userAPI', {\n value: api,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n\n // Make _luaProfile non-enumerable and immutable\n Object.defineProperty(this, '_luaProfile', {\n get() {\n return (\n profile || {\n userId: '',\n fullName: '',\n mobileNumbers: [],\n emailAddresses: [],\n }\n );\n },\n set(_) {\n // silently ignore any attempts to modify\n },\n enumerable: false,\n configurable: false,\n });\n\n // Return a proxy that allows direct property access\n return new Proxy(this, {\n get(target, prop, receiver) {\n // If the property exists on the instance itself, return it\n if (prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n // Otherwise, try to get it from the data object (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return target.data[prop];\n }\n return undefined;\n },\n set(target, prop, value, receiver) {\n // Reserved properties that should be set on the instance itself\n const reservedProps = ['data', 'userAPI', 'update', 'clear', 'toJSON', '_luaProfile'];\n if (typeof prop === 'string' && reservedProps.includes(prop)) {\n return Reflect.set(target, prop, value, receiver);\n }\n // All other properties get set on the data object\n if (typeof prop === 'string') {\n // Initialize data object if it doesn't exist\n if (!target.data || typeof target.data !== 'object') {\n target.data = {};\n }\n target.data[prop] = value;\n return true;\n }\n return false;\n },\n has(target, prop) {\n // Check if property exists on instance or in data (with null check)\n if (prop in target) {\n return true;\n }\n if (typeof prop === 'string' && target.data && typeof target.data === 'object') {\n return prop in target.data;\n }\n return false;\n },\n ownKeys(target) {\n // Return both instance keys and data keys (with null check)\n const instanceKeys = Reflect.ownKeys(target);\n const dataKeys = target.data && typeof target.data === 'object' ? Object.keys(target.data) : [];\n return [...new Set([...instanceKeys, ...dataKeys])];\n },\n getOwnPropertyDescriptor(target, prop) {\n // First check if it's an instance property\n const instanceDesc = Reflect.getOwnPropertyDescriptor(target, prop);\n if (instanceDesc) {\n return instanceDesc;\n }\n // Then check if it's a data property (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: target.data[prop],\n };\n }\n return undefined;\n },\n });\n }\n\n /**\n * Custom toJSON method to control what gets serialized when logging\n * @returns Serialized user data\n */\n toJSON(): Record<string, any> {\n return this.data;\n }\n\n /**\n * Custom inspect method for Node.js console.log\n * @returns Formatted user data for console output\n */\n [Symbol.for('nodejs.util.inspect.custom')](): Record<string, any> {\n return this.data;\n }\n\n /**\n * Updates the user's data\n * @param data - The data fields to update or add to user data\n * @returns Promise resolving to the updated user data\n * @throws Error if the update fails\n */\n async update(data: Record<string, any>): Promise<any> {\n try {\n const response = await this.userAPI.update(data);\n this.data = response;\n return this.data;\n } catch (error) {\n throw new Error('Failed to update user data');\n }\n }\n\n /**\n * Clears all user data for the current user\n * @returns Promise resolving to true if clearing was successful\n * @throws Error if the clear operation fails\n */\n async clear(): Promise<boolean> {\n try {\n await this.userAPI.clear();\n return true;\n } catch (error) {\n throw new Error('Failed to clear user data');\n }\n }\n\n /**\n * Saves the user's data\n * @returns Promise resolving to true if saving was successful\n * @throws Error if the save operation fails\n */\n async save(): Promise<boolean> {\n try {\n await this.userAPI.update(this.data);\n return true;\n } catch (error) {\n throw new Error('Failed to save user data');\n }\n }\n\n /**\n * Sends a message to a specific user conversation for the agent\n * @param messages - An array of messages to send (can be text, image, or file types)\n * @returns Promise resolving to the response data from the server\n * @throws Error if the message sending fails or the request is unsuccessful\n */\n async send(messages: Message[]): Promise<any> {\n try {\n await this.userAPI.sendMessage(messages);\n return true;\n } catch (error) {\n throw new Error('Failed to send message');\n }\n }\n\n //get chat history\n async getChatHistory(): Promise<ChatHistoryMessage[]> {\n try {\n return await this.userAPI.getChatHistory();\n } catch (error) {\n throw new Error('Failed to get chat history');\n }\n }\n}\n","import { HttpClient } from './http.client.js';\nimport UserDataInstance from '../instances/user.instance.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport { Message } from '../interfaces/message.js';\nimport { UserDataAPI } from '../types/index.js';\nimport { ChatHistoryMessage } from '../interfaces/chat.js';\nimport {\n UserLookupOptions,\n ProfileResponse,\n UserDataResponse,\n AdminUserResponse,\n SendMessageResponse,\n} from '../interfaces/user.js';\nimport { getDeveloperInstance } from './lazy-instances.js';\n\n// User Data API calls\nexport default class UserDataApi extends HttpClient implements UserDataAPI {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of UserDataApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Retrieves user data by userId, email, or phone.\n * @param identifier - Optional userId string or lookup options object\n * @returns Promise resolving to a UserDataInstance, or null if not found (for email/phone lookup)\n * @throws Error if the user data cannot be retrieved or the request fails\n */\n async get(identifier?: string | UserLookupOptions): Promise<UserDataInstance | null> {\n let userId: string | undefined;\n\n // Handle object-based lookup (email or phone)\n if (identifier && typeof identifier === 'object') {\n const profile = await this.resolveUserProfile(identifier);\n if (!profile) return null;\n userId = profile.id;\n } else {\n userId = identifier;\n }\n\n let url = `/developer/user/data/agent/${this.agentId}`;\n if (userId) {\n url += `/user/${userId}`;\n }\n const response = await this.httpGet<UserDataResponse>(url, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (!response.success) {\n throw new Error(response.error?.message || 'Failed to get user data');\n }\n\n // Extract profile data and remove from response\n const profile = response.data?._luaProfile;\n const { _luaProfile, ...data } = response.data || {};\n\n return new UserDataInstance(this, data, profile);\n }\n\n /**\n * Resolves email or phone to user profile via DeveloperApi\n * @param options - Lookup options containing email or phone\n * @returns Promise resolving to ProfileResponse or null if not found\n */\n private async resolveUserProfile(options: UserLookupOptions): Promise<ProfileResponse | null> {\n try {\n const developerApi = await getDeveloperInstance();\n\n if (options.email) {\n const response = await developerApi.getUserProfileByEmail(options.email);\n return response.success ? (response.data ?? null) : null;\n }\n if (options.phone) {\n const response = await developerApi.getUserProfileByPhone(options.phone);\n return response.success ? (response.data ?? null) : null;\n }\n } catch (error: any) {\n // Return null for 404, rethrow other errors\n if (error.message?.includes('404') || error.message?.includes('not found')) {\n return null;\n }\n throw error;\n }\n return null;\n }\n\n /**\n * Updates the current user's data for the specific agent\n * @param data - The data object containing fields to update or add to user data\n * @returns Promise resolving to the updated user data\n * @throws Error if the update fails or the request is unsuccessful\n */\n async update(data: Record<string, any>): Promise<Record<string, any>> {\n const response = await this.httpPut<UserDataResponse>(`/developer/user/data/agent/${this.agentId}`, data, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (!response.success) {\n throw new Error(response.error?.message || 'Failed to update user data');\n }\n\n // Extract profile if present and remove from response\n const { _luaProfile, ...cleanData } = response.data || {};\n\n return cleanData;\n }\n\n /**\n * Clears all user data for the current user and specific agent\n * @returns Promise resolving to an empty object upon successful deletion\n * @throws Error if the clear operation fails or the request is unsuccessful\n */\n async clear(): Promise<Record<string, never>> {\n const response = await this.httpDelete<{ success: boolean }>(`/developer/user/data/agent/${this.agentId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (!response.success) {\n throw new Error(response.error?.message || 'Failed to clear user data');\n }\n return {};\n }\n\n /**\n * Sends a message to a specific user conversation for the agent\n * @param messages - An array of messages to send (can be text, image, or file types)\n * @returns Promise resolving to the response data from the server\n * @throws Error if the message sending fails or the request is unsuccessful\n */\n async sendMessage(messages: Message[]): Promise<SendMessageResponse> {\n const user = await this.getAdminUser();\n const response = await this.httpPost<SendMessageResponse>(\n `/admin/agents/${this.agentId}/conversations/${user.uid}`,\n { messages },\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (!response.success) {\n throw new Error(response.error?.message || 'Failed to send message');\n }\n return response.data!;\n }\n\n /**\n * Gets the admin user for the specific agent\n * @returns Promise resolving to the admin user data\n * @throws Error if the admin user cannot be retrieved or the request is unsuccessful\n */\n async getAdminUser(): Promise<AdminUserResponse> {\n const response = await this.httpGet<AdminUserResponse>(`/admin`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (!response.success) {\n throw new Error(response.error?.message || 'Failed to get admin user');\n }\n return response.data!;\n }\n\n /**\n * Gets the chat history for the current user and agent\n * @returns Promise resolving to an array of chat messages\n * @throws Error if the chat history cannot be retrieved or the request is unsuccessful\n *\n * @example\n * ```typescript\n * const history = await User.getChatHistory();\n * // Returns: [{ role: 'user', content: [...], createdAt: '...' }, ...]\n * ```\n */\n async getChatHistory(): Promise<ChatHistoryMessage[]> {\n const response = await this.httpGet<ChatHistoryMessage[]>(`/chat/history/${this.agentId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (!response.success) {\n throw new Error(response.error?.message || 'Failed to get chat history');\n }\n return response.data || [];\n }\n}\n","import { Product } from '../interfaces/product.js';\nimport { UserData } from '../interfaces/admin.js';\nimport { CustomDataAPI, UserDataAPI } from '../types/index.js';\nimport { CreateCustomDataResponse } from '../interfaces/custom.data.js';\n\n/**\n * Data entry instance class providing a fluent API for managing custom data entries\n * Provides methods for updating and deleting individual data entries\n * Supports direct property access (e.g., entry.fieldName) for accessing data properties\n */\nexport default class DataEntryInstance {\n data: Record<string, any>;\n id: string;\n collectionName: string;\n score?: number;\n private customDataAPI!: CustomDataAPI; // Use definite assignment assertion\n\n // Index signature to allow dynamic property access\n [key: string]: any;\n\n /**\n * Creates a new DataEntryInstance with proxy support for direct property access\n * @param api - The CustomDataAPI instance for making API calls\n * @param entry - The custom data entry response from the API\n * @param collectionName - The name of the collection this entry belongs to\n * @returns Proxied instance that allows direct access to data properties\n */\n constructor(api: CustomDataAPI, entry: CreateCustomDataResponse, collectionName: string) {\n // Ensure data is always an object, never null or undefined\n this.data = entry.data && typeof entry.data === 'object' ? entry.data : {};\n this.id = entry.id;\n this.collectionName = collectionName;\n this.score = entry.score;\n // Make userAPI non-enumerable so it doesn't show up in console.log\n Object.defineProperty(this, 'customDataAPI', {\n value: api,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n\n // Return a proxy that allows direct property access\n return new Proxy(this, {\n get(target, prop, receiver) {\n // If the property exists on the instance itself, return it\n if (prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n // Otherwise, try to get it from the data object (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return target.data[prop];\n }\n return undefined;\n },\n set(target, prop, value, receiver) {\n // Reserved properties that should be set on the instance itself\n const reservedProps = ['data', 'id', 'collectionName', 'score', 'customDataAPI', 'update', 'delete', 'toJSON'];\n if (typeof prop === 'string' && reservedProps.includes(prop)) {\n return Reflect.set(target, prop, value, receiver);\n }\n // All other properties get set on the data object\n if (typeof prop === 'string') {\n // Initialize data object if it doesn't exist\n if (!target.data || typeof target.data !== 'object') {\n target.data = {};\n }\n target.data[prop] = value;\n return true;\n }\n return false;\n },\n has(target, prop) {\n // Check if property exists on instance or in data (with null check)\n if (prop in target) {\n return true;\n }\n if (typeof prop === 'string' && target.data && typeof target.data === 'object') {\n return prop in target.data;\n }\n return false;\n },\n ownKeys(target) {\n // Return both instance keys and data keys (with null check)\n const instanceKeys = Reflect.ownKeys(target);\n const dataKeys = target.data && typeof target.data === 'object' ? Object.keys(target.data) : [];\n return [...new Set([...instanceKeys, ...dataKeys])];\n },\n getOwnPropertyDescriptor(target, prop) {\n // First check if it's an instance property\n const instanceDesc = Reflect.getOwnPropertyDescriptor(target, prop);\n if (instanceDesc) {\n return instanceDesc;\n }\n // Then check if it's a data property (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: target.data[prop],\n };\n }\n return undefined;\n },\n });\n }\n\n /**\n * Custom toJSON method to control what gets serialized when logging\n * @returns Serialized data entry including score if available\n */\n toJSON(): Record<string, any> {\n return {\n ...this.data,\n score: this.score,\n id: this.id,\n collectionName: this.collectionName,\n };\n }\n\n /**\n * Custom inspect method for Node.js console.log\n * @returns Formatted data entry for console output\n */\n [Symbol.for('nodejs.util.inspect.custom')](): Record<string, any> {\n return {\n ...this.data,\n score: this.score,\n id: this.id,\n collectionName: this.collectionName,\n };\n }\n\n /**\n * Updates the custom data entry\n * @param data - The data fields to update (partial update supported)\n * @param searchText - Optional new search text for semantic search indexing\n * @returns Promise resolving to the updated data\n * @throws Error if the update fails\n */\n async update(data: Record<string, any>, searchText?: string): Promise<Record<string, any>> {\n try {\n await this.customDataAPI.update(this.collectionName, this.id, data, searchText);\n this.data = { ...this.data, ...data };\n return this.data;\n } catch (error) {\n throw new Error('Failed to update custom data entry');\n }\n }\n\n /**\n * Deletes the custom data entry\n * @returns Promise resolving to true if deletion was successful\n * @throws Error if the deletion fails\n */\n async delete(): Promise<boolean> {\n try {\n await this.customDataAPI.delete(this.collectionName, this.id);\n return true;\n } catch (error) {\n throw new Error('Failed to delete custom data entry');\n }\n }\n\n /**\n * Saves the data entry\n * @param searchText - Optional search text for vector search indexing\n * @returns Promise resolving to true if saving was successful\n * @throws Error if the save operation fails\n */\n async save(searchText?: string): Promise<boolean> {\n try {\n await this.customDataAPI.update(this.collectionName, this.id, this.data, searchText);\n return true;\n } catch (error) {\n throw new Error('Failed to save data entry');\n }\n }\n}\n","import { HttpClient } from './http.client.js';\nimport { CustomDataAPI } from '../types/index.js';\nimport {\n CreateCustomDataResponse,\n GetCustomDataResponse,\n CustomDataEntry,\n UpdateCustomDataResponse,\n SearchCustomDataResponse,\n DeleteCustomDataResponse,\n} from '../interfaces/custom.data.js';\nimport DataEntryInstance from '../instances/data.entry.instance.js';\n\n// Custom Data API calls\nexport default class CustomDataApi extends HttpClient implements CustomDataAPI {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of CustomDataApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Creates a new custom data entry in a specified collection\n * @param collectionName - The name of the collection to create the entry in\n * @param data - The data object to store in the entry\n * @param searchText - Optional text to be used for semantic search indexing\n * @returns Promise resolving to a DataEntryInstance representing the created entry\n * @throws Error if the entry creation fails or the API request is unsuccessful\n */\n async create(collectionName: string, data: Record<string, any>, searchText?: string): Promise<DataEntryInstance> {\n const response = await this.httpPost<CreateCustomDataResponse>(\n `/developer/agents/${this.agentId}/custom-data/${collectionName}`,\n { data, searchText },\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return new DataEntryInstance(this, response.data, collectionName);\n }\n throw new Error(response.error?.message || 'Failed to create custom data entry');\n }\n\n /**\n * Retrieves custom data entries from a collection with optional filtering and pagination\n * @param collectionName - The name of the collection to query\n * @param filter - Optional filter object to apply to the query (JSON-serializable)\n * @param page - The page number for pagination (default: 1)\n * @param limit - The number of entries per page (default: 10)\n * @returns Promise resolving to a GetCustomDataResponse containing the entries and pagination info\n * @throws Error if the query fails or the API request is unsuccessful\n */\n async get(\n collectionName: string,\n filter?: Record<string, any>,\n page: number = 1,\n limit: number = 10\n ): Promise<GetCustomDataResponse> {\n let url = `/developer/agents/${this.agentId}/custom-data/${collectionName}?page=${page}&limit=${limit}`;\n\n if (filter) {\n const encodedFilter = encodeURIComponent(JSON.stringify(filter));\n url += `&filter=${encodedFilter}`;\n }\n\n const response = await this.httpGet<GetCustomDataResponse>(url, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to get custom data entries');\n }\n\n /**\n * Retrieves a single custom data entry by its ID\n * @param collectionName - The name of the collection containing the entry\n * @param entryId - The unique identifier of the entry to retrieve\n * @returns Promise resolving to a DataEntryInstance representing the entry\n * @throws Error if the entry is not found or the API request is unsuccessful\n */\n async getEntry(collectionName: string, entryId: string): Promise<DataEntryInstance> {\n const response = await this.httpGet<CreateCustomDataResponse>(\n `/developer/agents/${this.agentId}/custom-data/${collectionName}/${entryId}`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return new DataEntryInstance(this, response.data, collectionName);\n }\n throw new Error(response.error?.message || 'Failed to get custom data entry');\n }\n\n /**\n * Updates an existing custom data entry\n * @param collectionName - The name of the collection containing the entry\n * @param entryId - The unique identifier of the entry to update\n * @param data - The data object to update\n * @param searchText - Optional text to be used for semantic search indexing\n * @returns Promise resolving to an UpdateCustomDataResponse with the updated entry details\n * @throws Error if the entry is not found or the update fails\n */\n async update(\n collectionName: string,\n entryId: string,\n data: Record<string, any>,\n searchText?: string\n ): Promise<UpdateCustomDataResponse> {\n const response = await this.httpPut<UpdateCustomDataResponse>(\n `/developer/agents/${this.agentId}/custom-data/${collectionName}/${entryId}`,\n { data, searchText },\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to update custom data entry');\n }\n\n /**\n * Performs semantic search on custom data entries using text similarity\n * @param collectionName - The name of the collection to search within\n * @param searchText - The text query to search for\n * @param limit - Maximum number of results to return (default: 10)\n * @param scoreThreshold - Minimum similarity score threshold 0-1 (default: 0.6)\n * @returns Promise resolving to an array of DataEntryInstance objects matching the search\n * @throws Error if the search fails or the API request is unsuccessful\n */\n async search(\n collectionName: string,\n searchText: string,\n limit: number = 10,\n scoreThreshold: number = 0.6\n ): Promise<DataEntryInstance[]> {\n const url = `/developer/agents/${this.agentId}/custom-data/${collectionName}/search?searchText=${encodeURIComponent(searchText)}&limit=${limit}&scoreThreshold=${scoreThreshold}`;\n\n const response = await this.httpGet<SearchCustomDataResponse>(url, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return response.data.data.map((entry) => new DataEntryInstance(this, entry, collectionName));\n }\n throw new Error(response.error?.message || 'Failed to search custom data entries');\n }\n\n /**\n * Deletes a custom data entry from a collection\n * @param collectionName - The name of the collection containing the entry\n * @param entryId - The unique identifier of the entry to delete\n * @returns Promise resolving to a DeleteCustomDataResponse confirming deletion\n * @throws Error if the entry is not found or the deletion fails\n */\n async delete(collectionName: string, entryId: string): Promise<DeleteCustomDataResponse> {\n const response = await this.httpDelete<DeleteCustomDataResponse>(\n `/developer/agents/${this.agentId}/custom-data/${collectionName}/${entryId}`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to delete custom data entry');\n }\n}\n","import { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport {\n CreateWebhookDTO,\n PushWebhookVersionDTO,\n UpdateWebhookDTO,\n UpdateWebhookVersionDTO,\n} from '../interfaces/webhooks.js';\n\n/**\n * Webhook API Response Types\n */\nexport interface WebhookVersion {\n version: string;\n webhookId: string;\n createdAt: string | number;\n isActive?: boolean;\n}\n\nexport interface GetWebhooksResponse {\n webhooks: Array<{\n id: string;\n name: string;\n description?: string;\n public: boolean;\n active: boolean;\n eventSubscriptions: string[];\n createdAt: string;\n updatedAt: string;\n versions: WebhookVersion[];\n activeVersionId?: string;\n }>;\n}\n\nexport interface CreateWebhookResponse {\n id: string;\n name: string;\n description?: string;\n agentId: string;\n}\n\nexport interface WebhookVersionResponse {\n versionId: string;\n webhookId: string;\n version: string;\n createdAt: string;\n}\n\nexport interface UpdateWebhookVersionResponse {\n versionId: string;\n webhookId: string;\n version: string;\n updatedAt: string;\n}\n\nexport interface UpdateWebhookResponse {\n id: string;\n name: string;\n description?: string;\n eventSubscriptions: string[];\n updatedAt: string;\n}\n\nexport interface DeleteWebhookResponse {\n deleted: boolean;\n deactivated?: boolean;\n message: string;\n}\n\n/**\n * Webhook API Service\n * Handles all webhook-related API calls\n */\nexport default class WebhookApi extends HttpClient {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of WebhookApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Retrieves all webhooks for the agent\n * @returns Promise resolving to an ApiResponse containing an array of webhooks with their versions\n * @throws Error if the API request fails or the agent is not found\n */\n async getWebhooks(): Promise<ApiResponse<GetWebhooksResponse>> {\n return this.httpGet<GetWebhooksResponse>(`/developer/webhooks/${this.agentId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Creates a new webhook for the agent\n * @param webhookData - The webhook data including name and description\n * @returns Promise resolving to an ApiResponse containing the created webhook details\n * @throws Error if the webhook creation fails or validation errors occur\n */\n async createWebhook(webhookData: CreateWebhookDTO): Promise<ApiResponse<CreateWebhookResponse>> {\n return this.httpPost<CreateWebhookResponse>(`/developer/webhooks/${this.agentId}`, webhookData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async updateWebhook(webhookId: string, data: UpdateWebhookDTO): Promise<ApiResponse<UpdateWebhookResponse>> {\n return this.httpPatch<UpdateWebhookResponse>(`/developer/webhooks/${this.agentId}/${webhookId}`, data, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Pushes a new version of a webhook to production\n * @param webhookId - The unique identifier of the webhook\n * @param versionData - The version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the created version details\n * @throws Error if the webhook is not found or the push operation fails\n */\n async pushWebhook(\n webhookId: string,\n versionData: PushWebhookVersionDTO\n ): Promise<ApiResponse<WebhookVersionResponse>> {\n return this.httpPost<WebhookVersionResponse>(\n `/developer/webhooks/${this.agentId}/${webhookId}/version`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Pushes a new development/sandbox version of a webhook for testing\n * @param webhookId - The unique identifier of the webhook\n * @param versionData - The version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the development version details\n * @throws Error if the webhook is not found or the push operation fails\n */\n async pushDevWebhook(\n webhookId: string,\n versionData: PushWebhookVersionDTO\n ): Promise<ApiResponse<WebhookVersionResponse>> {\n return this.httpPost<WebhookVersionResponse>(\n `/developer/webhooks/${this.agentId}/${webhookId}/version/sandbox`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Updates an existing development/sandbox version of a webhook\n * @param webhookId - The unique identifier of the webhook\n * @param sandboxVersionId - The unique identifier of the sandbox version to update\n * @param versionData - The updated version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the updated version details\n * @throws Error if the webhook or version is not found or the update fails\n */\n async updateDevWebhook(\n webhookId: string,\n sandboxVersionId: string,\n versionData: UpdateWebhookVersionDTO\n ): Promise<ApiResponse<UpdateWebhookVersionResponse>> {\n return this.httpPut<UpdateWebhookVersionResponse>(\n `/developer/webhooks/${this.agentId}/${webhookId}/version/sandbox/${sandboxVersionId}`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Retrieves all versions of a specific webhook\n * @param webhookId - The unique identifier of the webhook\n * @returns Promise resolving to an ApiResponse containing an array of webhook versions\n * @throws Error if the webhook is not found or the request fails\n */\n async getWebhookVersions(\n webhookId: string\n ): Promise<ApiResponse<{ versions: WebhookVersion[]; activeVersionId?: string }>> {\n return this.httpGet<{ versions: WebhookVersion[]; activeVersionId?: string }>(\n `/developer/webhooks/${this.agentId}/${webhookId}/versions`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Publishes a specific version of a webhook to production\n * @param webhookId - The unique identifier of the webhook\n * @param version - The version identifier to publish\n * @returns Promise resolving to an ApiResponse containing publication confirmation details\n * @throws Error if the webhook or version is not found or the publish operation fails\n */\n async publishWebhookVersion(\n webhookId: string,\n version: string\n ): Promise<ApiResponse<{ message: string; webhookId: string; activeVersionId: string; publishedAt: string }>> {\n return this.httpPost<{ message: string; webhookId: string; activeVersionId: string; publishedAt: string }>(\n `/developer/webhooks/${this.agentId}/${webhookId}/${version}/publish`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Activates a webhook (enables it to receive requests)\n * @param webhookId - The unique identifier of the webhook to activate\n * @returns Promise resolving to an ApiResponse with activation status\n * @throws Error if the webhook is not found or the operation fails\n */\n async activateWebhook(webhookId: string): Promise<ApiResponse<{ message: string; active: boolean }>> {\n return this.httpPost<{ message: string; active: boolean }>(\n `/developer/webhooks/${this.agentId}/${webhookId}/activate`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Deactivates a webhook (stops it from receiving requests)\n * @param webhookId - The unique identifier of the webhook to deactivate\n * @returns Promise resolving to an ApiResponse with deactivation status\n * @throws Error if the webhook is not found or the operation fails\n */\n async deactivateWebhook(webhookId: string): Promise<ApiResponse<{ message: string; active: boolean }>> {\n return this.httpPost<{ message: string; active: boolean }>(\n `/developer/webhooks/${this.agentId}/${webhookId}/deactivate`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Deletes a webhook and all its versions, or deactivates it if it has versions\n * @param webhookId - The unique identifier of the webhook to delete\n * @returns Promise resolving to an ApiResponse with deletion status\n * - If deleted is true: webhook was successfully deleted\n * - If deleted is false and deactivated is true: webhook has versions and was deactivated instead\n * @throws Error if the webhook is not found or the delete operation fails\n */\n async deleteWebhook(webhookId: string): Promise<ApiResponse<DeleteWebhookResponse>> {\n return this.httpDelete<DeleteWebhookResponse>(`/developer/webhooks/${this.agentId}/${webhookId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n}\n","/**\n * Job Instance\n * Provides a convenient interface for interacting with a job\n */\n\nimport JobApi from '../api/job.api.service.js';\nimport UserDataInstance from './user.instance.js';\nimport { UserDataAPI } from '../types/index.js';\nimport UserDataApi from '../api/user.data.api.service.js';\nimport { BASE_URLS } from '../config/constants.js';\nimport { Job, JobVersion, JobExecution } from '../interfaces/jobs.js';\n\n/**\n * Job Instance class.\n * Represents a single job with helper methods for common operations.\n *\n * This class provides:\n * - Direct property access to job data via Proxy\n * - Helper methods for job operations (delete, updateMetadata)\n * - Metadata access and modification\n *\n * @example\n * ```typescript\n * const job = await Jobs.create({\n * name: 'my-job',\n * schedule: { type: 'once', executeAt: new Date() },\n * execute: async (job) => {\n * // Access metadata\n * console.log(job.metadata);\n *\n * // Update metadata\n * await job.updateMetadata({ processed: true });\n *\n * // Delete job when done\n * await job.delete();\n * }\n * });\n * ```\n */\nexport class JobInstance {\n private jobApi: JobApi;\n private _data: Job;\n public readonly id: string;\n public readonly name: string;\n /** The active version of the job (if one exists) */\n public readonly activeVersion?: JobVersion;\n public metadata: Record<string, any>;\n private userApi?: UserDataAPI;\n\n constructor(jobApi: JobApi, jobData: Job) {\n this.jobApi = jobApi;\n this._data = jobData;\n this.id = jobData.id;\n this.name = jobData.name;\n this.activeVersion = jobData.activeVersion;\n this.metadata = jobData.metadata || {};\n if (jobData.userId && jobData.agentId) {\n this.userApi = new UserDataApi(BASE_URLS.API, jobApi.apiKey, jobApi.agentId);\n }\n }\n\n /**\n * Gets the full job data.\n */\n get data(): Job {\n return this._data;\n }\n\n /**\n * Updates the job's metadata.\n *\n * @param metadata - The new metadata to set\n * @returns Promise resolving when update is complete\n *\n * @example\n * ```typescript\n * await job.updateMetadata({\n * lastProcessed: new Date().toISOString(),\n * status: 'completed'\n * });\n * ```\n */\n async updateMetadata(metadata: Record<string, any>): Promise<void> {\n this.metadata = { ...this.metadata, ...metadata };\n\n const result = await this.jobApi.updateMetadata(this.id, this.metadata);\n\n if (!result.success) {\n throw new Error(result.error?.message || 'Failed to update job metadata');\n }\n }\n\n /**\n * Deletes the job from the backend (or deactivates if it has versions).\n *\n * @returns Promise resolving when deletion is complete\n *\n * @example\n * ```typescript\n * // Delete a one-time job after it completes\n * await job.delete();\n * ```\n */\n async delete(): Promise<void> {\n const result = await this.jobApi.deleteJob(this.id);\n\n if (!result.success) {\n throw new Error(result.error?.message || 'Failed to delete job');\n }\n }\n\n /**\n * Gets the user data associated with this job's agent.\n * Provides access to user information and custom data storage.\n *\n * @returns Promise resolving to UserDataInstance with user information\n *\n * @example\n * ```typescript\n * const user = await job.user();\n * console.log('User email:', user.email);\n * console.log('User data:', user.data);\n * ```\n */\n async user(): Promise<UserDataInstance> {\n if (!this.userApi) {\n throw new Error('User API not initialized');\n }\n return await this.userApi.get();\n }\n\n /**\n * Manually triggers the job execution (ignores schedule).\n * Uses activeVersion by default.\n *\n * @param versionId - Optional version to execute (defaults to activeVersion)\n * @returns Promise resolving to execution result\n *\n * @example\n * ```typescript\n * const result = await job.trigger();\n * console.log('Execution result:', result);\n * ```\n */\n async trigger(versionId?: string): Promise<JobExecution> {\n const result = await this.jobApi.triggerJob(this.id, versionId || this.activeVersion?.id);\n\n if (!result.success || !result.data) {\n throw new Error(result.error?.message || 'Failed to trigger job');\n }\n\n return result.data;\n }\n\n /**\n * Activates the job, enabling it to run on schedule.\n *\n * @returns Promise resolving to updated JobInstance\n *\n * @example\n * ```typescript\n * await job.activate();\n * console.log('Job is now active');\n * ```\n */\n async activate(): Promise<JobInstance> {\n const result = await this.jobApi.activateJob(this.id);\n\n if (!result.success || !result.data) {\n throw new Error(result.error?.message || 'Failed to activate job');\n }\n\n this._data = result.data;\n return this;\n }\n\n /**\n * Deactivates the job, preventing it from running on schedule.\n *\n * @returns Promise resolving to updated JobInstance\n *\n * @example\n * ```typescript\n * await job.deactivate();\n * console.log('Job is now inactive');\n * ```\n */\n async deactivate(): Promise<JobInstance> {\n const result = await this.jobApi.deactivateJob(this.id);\n\n if (!result.success || !result.data) {\n throw new Error(result.error?.message || 'Failed to deactivate job');\n }\n\n this._data = result.data;\n return this;\n }\n\n /**\n * Converts the job instance to JSON.\n */\n toJSON(): Job {\n return {\n ...this._data,\n id: this.id,\n name: this.name,\n activeVersion: this.activeVersion,\n metadata: this.metadata,\n };\n }\n}\n","import { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport {\n CreateJobDTO,\n Job,\n JobVersion,\n JobExecution,\n PushJobVersionDTO,\n UpdateJobVersionDTO,\n GetJobsResponseData,\n GetJobExecutionsResponseData,\n DeleteJobResponseData,\n UpdateJobMetadataResponseData,\n} from '../interfaces/jobs.js';\nimport { JobInstance } from '../instances/job.instance.js';\n\n/**\n * Job API Service\n * Handles all job-related API calls\n */\nexport default class JobApi extends HttpClient {\n public apiKey: string;\n public agentId: string;\n\n /**\n * Creates an instance of JobApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Retrieves all jobs for the agent\n * @returns Promise resolving to an ApiResponse containing an array of jobs with their versions\n * @throws Error if the API request fails or the agent is not found\n */\n async getJobs(options: { includeDynamic?: boolean } = {}): Promise<ApiResponse<GetJobsResponseData>> {\n const queryParams = new URLSearchParams();\n if (options.includeDynamic) {\n queryParams.append('includeDynamic', 'true');\n }\n\n const url = `/developer/jobs/${this.agentId}?${queryParams.toString()}`;\n\n return this.httpGet<GetJobsResponseData>(url, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Retrieves all jobs for the agent as JobInstance array\n * @param options - Optional configuration\n * @param options.includeDynamic - Include dynamically created jobs (default: false)\n * @returns Promise resolving to an array of JobInstance\n * @throws Error if the API request fails\n */\n async getAll(options: { includeDynamic?: boolean } = {}): Promise<JobInstance[]> {\n const response = await this.getJobs(options);\n if (response.success && response.data?.jobs) {\n return response.data.jobs.map((job) => new JobInstance(this, job));\n }\n throw new Error(response.error?.message || 'Failed to get all jobs');\n }\n\n /**\n * Retrieves a job by its unique identifier\n * @param jobId - The unique identifier of the job to retrieve\n * @returns Promise resolving to an JobInstance representing the job\n * @throws Error if the job is not found or the request fails\n */\n async getJob(jobId: string): Promise<JobInstance> {\n const response = await this.httpGet<Job>(`/developer/jobs/${this.agentId}/${jobId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return new JobInstance(this, response.data);\n }\n throw new Error(response.error?.message || 'Failed to get job');\n }\n\n /**\n * Creates a new job for the agent.\n * Optionally creates initial version and activates the job in one call.\n *\n * @param jobData - The job data including name, description, schedule, and optional version\n * @param jobData.version - If provided, creates first version automatically\n * @param jobData.activate - If true, activates the job immediately\n * @returns Promise resolving to an ApiResponse containing the full job with versions\n * @throws Error if the job creation fails or validation errors occur\n */\n async createJob(jobData: CreateJobDTO): Promise<ApiResponse<Job>> {\n return this.httpPost<Job>(`/developer/jobs/${this.agentId}`, jobData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Creates a new job for the agent and returns a JobInstance.\n * Supports automatic version creation and activation.\n *\n * @param jobData - The job data including name, description, schedule, and optional version\n * @param jobData.version - If provided, creates first version automatically\n * @param jobData.activate - If true, activates the job immediately\n * @returns Promise resolving to a JobInstance containing the created job details\n * @throws Error if the job creation fails or validation errors occur\n */\n async createJobInstance(jobData: CreateJobDTO): Promise<JobInstance> {\n const response = await this.httpPost<Job>(`/developer/jobs/${this.agentId}`, jobData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return new JobInstance(this, response.data);\n }\n throw new Error(response.error?.message || 'Failed to create job');\n }\n\n /**\n * Pushes a new version of a job to production\n * @param jobId - The unique identifier of the job\n * @param versionData - The version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the full job version\n * @throws Error if the job is not found or the push operation fails\n */\n async pushJob(jobId: string, versionData: PushJobVersionDTO): Promise<ApiResponse<JobVersion>> {\n return this.httpPost<JobVersion>(`/developer/jobs/${this.agentId}/${jobId}/version`, versionData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Pushes a new development/sandbox version of a job for testing\n * @param jobId - The unique identifier of the job\n * @param versionData - The version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the full job version\n * @throws Error if the job is not found or the push operation fails\n */\n async pushDevJob(jobId: string, versionData: PushJobVersionDTO): Promise<ApiResponse<JobVersion>> {\n return this.httpPost<JobVersion>(`/developer/jobs/${this.agentId}/${jobId}/version/sandbox`, versionData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Updates an existing development/sandbox version of a job\n * @param jobId - The unique identifier of the job\n * @param sandboxVersionId - The unique identifier of the sandbox version to update\n * @param versionData - The updated version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the full updated job version\n * @throws Error if the job or version is not found or the update fails\n */\n async updateDevJob(\n jobId: string,\n sandboxVersionId: string,\n versionData: UpdateJobVersionDTO\n ): Promise<ApiResponse<JobVersion>> {\n return this.httpPut<JobVersion>(\n `/developer/jobs/${this.agentId}/${jobId}/version/sandbox/${sandboxVersionId}`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Retrieves all versions of a specific job\n * @param jobId - The unique identifier of the job\n * @returns Promise resolving to an ApiResponse containing an array of job versions\n * @throws Error if the job is not found or the request fails\n */\n async getJobVersions(jobId: string): Promise<ApiResponse<JobVersion[]>> {\n return this.httpGet<JobVersion[]>(`/developer/jobs/${this.agentId}/${jobId}/versions`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Publishes a specific version of a job to production\n * @param jobId - The unique identifier of the job\n * @param version - The version identifier to publish\n * @returns Promise resolving to an ApiResponse containing the full updated job\n * @throws Error if the job or version is not found or the publish operation fails\n */\n async publishJobVersion(jobId: string, version: string): Promise<ApiResponse<Job>> {\n return this.httpPost<Job>(\n `/developer/jobs/${this.agentId}/${jobId}/${version}/publish`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Deletes a job and all its versions, or deactivates it if it has versions\n * @param jobId - The unique identifier of the job to delete\n * @returns Promise resolving to an ApiResponse with deletion status\n * - If deleted is true: job was successfully deleted\n * - If deleted is false and deactivated is true: job has versions and was deactivated instead\n * @throws Error if the job is not found or the delete operation fails\n */\n async deleteJob(jobId: string): Promise<ApiResponse<DeleteJobResponseData>> {\n return this.httpDelete<DeleteJobResponseData>(`/developer/jobs/${this.agentId}/${jobId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Activates a job (enables it to run on schedule)\n * @param jobId - The unique identifier of the job to activate\n * @returns Promise resolving to an ApiResponse with the full updated job\n * @throws Error if the job is not found or the operation fails\n */\n async activateJob(jobId: string): Promise<ApiResponse<Job>> {\n return this.httpPost<Job>(\n `/developer/jobs/${this.agentId}/${jobId}/activate`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Deactivates a job (disables it from running)\n * @param jobId - The unique identifier of the job to deactivate\n * @returns Promise resolving to an ApiResponse with the full updated job\n * @throws Error if the job is not found or the operation fails\n */\n async deactivateJob(jobId: string): Promise<ApiResponse<Job>> {\n return this.httpPost<Job>(\n `/developer/jobs/${this.agentId}/${jobId}/deactivate`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Manually triggers a job execution (ignores schedule)\n * @param jobId - The unique identifier of the job to trigger\n * @param versionId - The version identifier to execute (optional, defaults to activeVersionId)\n * @returns Promise resolving to an ApiResponse with the execution record\n * @throws Error if the job is not found or the operation fails\n */\n async triggerJob(jobId: string, versionId?: string): Promise<ApiResponse<JobExecution>> {\n const body = versionId ? { versionId } : {};\n return this.httpPost<JobExecution>(`/developer/jobs/${this.agentId}/${jobId}/trigger`, body, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Retrieves execution history for a job\n * @param jobId - The unique identifier of the job\n * @param limit - Maximum number of executions to return (default: 50)\n * @returns Promise resolving to an ApiResponse with execution history\n * @throws Error if the job is not found or the request fails\n */\n async getJobExecutions(jobId: string, limit: number = 50): Promise<ApiResponse<GetJobExecutionsResponseData>> {\n return this.httpGet<GetJobExecutionsResponseData>(\n `/developer/jobs/${this.agentId}/${jobId}/executions?limit=${limit}`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Updates the metadata of a job\n * @param jobId - The unique identifier of the job\n * @param metadata - The metadata object to update or merge with existing metadata\n * @returns Promise resolving to the updated metadata\n * @throws Error if the job is not found or the metadata update fails\n */\n async updateMetadata(\n jobId: string,\n metadata: Record<string, any>\n ): Promise<ApiResponse<UpdateJobMetadataResponseData>> {\n return this.httpPut<UpdateJobMetadataResponseData>(`/developer/jobs/${this.agentId}/${jobId}/metadata`, metadata, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n}\n","import { aiGenerateInputFromSimplified, type AiGenerateInput, type AiGenerateOutput } from '@lua/shared-types';\nimport type { UserContent } from 'ai';\nimport { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\n\nexport const aiGenerateSimplifiedToBody = aiGenerateInputFromSimplified;\n\n/**\n * Proxies isolated AI generation to lua-api (server-side Gemini + usage).\n */\nexport default class AiApiService extends HttpClient {\n constructor(\n baseUrl: string,\n private readonly apiKey: string,\n private readonly agentId: string\n ) {\n super(baseUrl);\n }\n\n async generate(body: AiGenerateInput): Promise<ApiResponse<AiGenerateOutput>> {\n return this.httpPost<AiGenerateOutput>(`/developer/ai/${this.agentId}/generate`, body, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Handles the simplified-vs-full-options branching for `AI.generate`.\n * Returns plain text for the simplified overload, full output for the options overload.\n */\n async generateForSandbox(\n promptOrOptions: string | AiGenerateInput,\n content?: UserContent\n ): Promise<string | AiGenerateOutput> {\n if (typeof promptOrOptions === 'string') {\n const result = await this.generate(aiGenerateInputFromSimplified(promptOrOptions, content));\n if (!result.success) {\n throw new Error(result.error?.message || 'AI generation failed');\n }\n return result.data?.text ?? '';\n }\n const result = await this.generate(promptOrOptions);\n if (!result.success) {\n throw new Error(result.error?.message || 'AI generation failed');\n }\n if (!result.data) {\n throw new Error('AI generation failed: empty response');\n }\n return result.data;\n }\n}\n","import type { AgentInvocationInput, AgentInvocationOutput } from '@lua/shared-types';\nimport { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\n\n/**\n * Wire body for POST `/chat/generate/:agentId` — mirrors the subset of\n * `ChatMessageDto` that lua-core accepts.\n */\ninterface ChatGenerateBody {\n messages: Array<{ type: 'text'; text: string } | Record<string, unknown>>;\n navigate: boolean;\n systemPrompt?: string;\n runtimeContext?: string;\n threadId?: string;\n}\n\n/**\n * Thin wrapper around `POST /chat/generate/:agentId` used by the lua-cli\n * sandbox's `Agents.invoke`. Mirrors the HTTP pattern `lua chat` already uses\n * — no new endpoint on lua-api / lua-core is required.\n */\nexport default class AgentsApiService extends HttpClient {\n constructor(\n baseUrl: string,\n private readonly apiKey: string\n ) {\n super(baseUrl);\n }\n\n async invoke(targetAgentId: string, body: AgentInvocationInput): Promise<ApiResponse<AgentInvocationOutput>> {\n const channel = body.channel ?? 'agent-invocation';\n const query = new URLSearchParams({ channel });\n if (body.identifier) query.set('identifier', body.identifier);\n const chatBody = this.toChatGenerateBody(body);\n return this.httpPost<AgentInvocationOutput>(`/chat/generate/${targetAgentId}?${query.toString()}`, chatBody, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Sandbox overload: mirrors the `AI.generate` pattern where the simplified\n * `(prompt)` call returns plain text and the `(input)` call returns the\n * full structured output.\n */\n async invokeForSandbox(\n targetAgentId: string,\n promptOrInput: string | AgentInvocationInput\n ): Promise<string | AgentInvocationOutput> {\n const input: AgentInvocationInput = typeof promptOrInput === 'string' ? { prompt: promptOrInput } : promptOrInput;\n\n const result = await this.invoke(targetAgentId, input);\n if (!result.success) {\n throw new Error(result.error?.message || 'Agent invocation failed');\n }\n if (!result.data) {\n throw new Error('Agent invocation failed: empty response');\n }\n\n return typeof promptOrInput === 'string' ? (result.data.text ?? '') : result.data;\n }\n\n private toChatGenerateBody(body: AgentInvocationInput): ChatGenerateBody {\n const messages = body.messages\n ? (body.messages as ChatGenerateBody['messages'])\n : [{ type: 'text' as const, text: body.prompt ?? '' }];\n\n return {\n messages,\n navigate: false,\n ...(body.systemPrompt !== undefined ? { systemPrompt: body.systemPrompt } : {}),\n ...(body.runtimeContext !== undefined ? { runtimeContext: body.runtimeContext } : {}),\n ...(body.threadId !== undefined ? { threadId: body.threadId } : {}),\n };\n }\n}\n","import { HttpClient } from './http.client.js';\nimport { WhatsAppTemplatesAPI } from '../types/index.js';\nimport {\n WhatsAppTemplate,\n PaginatedTemplatesResponse,\n ListTemplatesOptions,\n SendTemplateData,\n SendTemplateResponse,\n} from '../interfaces/whatsapp-templates.js';\n\n/**\n * WhatsApp Templates API Service\n * Handles WhatsApp template operations\n */\nexport default class WhatsAppTemplatesApiService extends HttpClient implements WhatsAppTemplatesAPI {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of WhatsAppTemplatesApiService\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Lists WhatsApp templates for a channel with optional pagination and search\n * @param channelId - The WhatsApp channel identifier\n * @param options - Optional pagination and search options\n * @returns Promise resolving to paginated templates response\n */\n async list(channelId: string, options?: ListTemplatesOptions): Promise<PaginatedTemplatesResponse> {\n const page = options?.page ?? 1;\n const limit = options?.limit ?? 10;\n const search = options?.search;\n\n let url = `/admin/agents/${this.agentId}/channels/${channelId}/whatsapp-templates?page=${page}&limit=${limit}`;\n\n if (search) {\n url += `&search=${encodeURIComponent(search)}`;\n }\n\n const response = await this.httpGet<PaginatedTemplatesResponse>(url, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n\n if (response.success) {\n return response.data as PaginatedTemplatesResponse;\n }\n throw new Error(response.error?.message || 'Failed to list templates');\n }\n\n /**\n * Gets a specific WhatsApp template by ID\n * @param channelId - The WhatsApp channel identifier\n * @param templateId - The template identifier\n * @returns Promise resolving to the template\n */\n async get(channelId: string, templateId: string): Promise<WhatsAppTemplate> {\n const url = `/admin/agents/${this.agentId}/channels/${channelId}/whatsapp-templates/${templateId}`;\n\n const response = await this.httpGet<WhatsAppTemplate>(url, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n\n if (response.success) {\n return response.data as WhatsAppTemplate;\n }\n throw new Error(response.error?.message || 'Failed to get template');\n }\n\n /**\n * Sends a WhatsApp template message to one or more phone numbers\n * @param channelId - The WhatsApp channel identifier\n * @param templateId - The template identifier\n * @param data - Send data including phone numbers and template values\n * @returns Promise resolving to the send response with results and errors\n */\n async send(channelId: string, templateId: string, data: SendTemplateData): Promise<SendTemplateResponse> {\n const url = `/admin/agents/${this.agentId}/channels/${channelId}/whatsapp-templates/${templateId}/trigger`;\n\n // Transform to API format (phoneNumbers -> phone_numbers)\n const body = {\n phone_numbers: data.phoneNumbers,\n values: data.values,\n };\n\n const response = await this.httpPost<SendTemplateResponse>(url, body, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n\n if (response.success) {\n return response.data as SendTemplateResponse;\n }\n throw new Error(response.error?.message || 'Failed to send template');\n }\n}\n","/**\n * CDN API Service\n * Handles file upload and retrieval from the Lua CDN\n */\n\nimport { CdnAPI } from '../types/api-contracts.js';\nimport { CdnUploadResponse } from '../interfaces/cdn.js';\n\nexport default class CdnApi implements CdnAPI {\n private baseUrl: string;\n private apiKey: string;\n\n constructor(baseUrl: string, apiKey: string) {\n this.baseUrl = baseUrl;\n this.apiKey = apiKey;\n }\n\n /**\n * Uploads a file to the CDN\n * @param file - The file to upload\n * @returns Promise resolving to the file ID\n */\n async upload(file: File): Promise<string> {\n const formData = new FormData();\n formData.append('file', file, file.name);\n\n const response = await fetch(`${this.baseUrl}/upload`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${this.apiKey}` },\n body: formData,\n });\n\n if (!response.ok) {\n const error = (await response.json().catch(() => ({}))) as Record<string, any>;\n throw new Error(error.message || `Upload failed: ${response.status}`);\n }\n\n const data = (await response.json()) as CdnUploadResponse;\n return data.fileId;\n }\n\n /**\n * Fetches a file from the CDN by its ID\n */\n async get(fileId: string): Promise<File> {\n const response = await fetch(`${this.baseUrl}/${fileId}`);\n\n if (!response.ok) {\n throw new Error(`File not found: ${response.status}`);\n }\n\n const contentType = response.headers.get('content-type') || 'application/octet-stream';\n const contentDisposition = response.headers.get('content-disposition') || '';\n const filenameMatch = contentDisposition.match(/filename=\"?([^\"]+)\"?/);\n const filename = filenameMatch?.[1] || fileId;\n\n const blob = await response.blob();\n return new File([blob], filename, { type: contentType });\n }\n}\n","import { HttpClient } from './http.client.js';\nimport { ApiResponse, MCPServerResponse, CreateMCPServerRequest, UpdateMCPServerRequest } from '../interfaces/index.js';\nimport { ProfileResponse } from '../interfaces/user.js';\n\n/**\n * Environment variables response structure from the API\n * The actual environment variables are nested in the 'data' property\n */\ninterface EnvironmentVariablesResponse {\n data: Record<string, string>;\n _id?: string;\n agentId?: string;\n createdAt?: string;\n updatedAt?: string;\n __v?: number;\n}\n\n/**\n * Developer API calls for agent management and configuration\n */\nexport default class DeveloperApi extends HttpClient {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of DeveloperApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Retrieves all environment variables for the agent in production\n * The response includes metadata (_id, agentId, timestamps) and the actual env vars in the 'data' property\n * @returns Promise resolving to an ApiResponse containing environment variables and metadata\n * @throws Error if the API request fails or the agent is not found\n */\n async getEnvironmentVariables(): Promise<ApiResponse<EnvironmentVariablesResponse>> {\n return this.httpGet<EnvironmentVariablesResponse>(`/developer/agents/${this.agentId}/env`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Updates all environment variables for the agent in production\n * This operation replaces all existing environment variables with the provided set\n * @param envData - Object containing environment variable key-value pairs\n * @returns Promise resolving to an ApiResponse with the updated environment variables and metadata\n * @throws Error if the API request fails or the agent is not found\n */\n async updateEnvironmentVariables(\n envData: Record<string, string>\n ): Promise<ApiResponse<EnvironmentVariablesResponse>> {\n return this.httpPost<EnvironmentVariablesResponse>(`/developer/agents/${this.agentId}/env`, envData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Deletes a specific environment variable by key\n * @param key - The environment variable key to delete\n * @returns Promise resolving to an ApiResponse with confirmation\n * @throws Error if the API request fails, the agent is not found, or the key doesn't exist\n */\n async deleteEnvironmentVariable(key: string): Promise<ApiResponse<{ message: string; key: string }>> {\n return this.httpDelete<{ message: string; key: string }>(`/developer/agents/${this.agentId}/env/${key}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Retrieves all MCP server configurations for the agent\n * @returns Promise resolving to an ApiResponse containing MCP server configurations\n */\n async getMCPServers(): Promise<ApiResponse<MCPServerResponse[]>> {\n return this.httpGet<MCPServerResponse[]>(`/developer/agents/${this.agentId}/mcp-servers`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Retrieves only active MCP server configurations for the agent\n * @returns Promise resolving to an ApiResponse containing active MCP server configurations\n */\n async getActiveMCPServers(): Promise<ApiResponse<MCPServerResponse[]>> {\n return this.httpGet<MCPServerResponse[]>(`/developer/agents/${this.agentId}/mcp-servers/active`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Gets a single MCP server by ID\n * @param mcpServerId - The ID of the MCP server\n * @returns Promise resolving to an ApiResponse with the MCP server\n */\n async getMCPServer(mcpServerId: string): Promise<ApiResponse<MCPServerResponse>> {\n return this.httpGet<MCPServerResponse>(`/developer/agents/${this.agentId}/mcp-servers/${mcpServerId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Creates a new MCP server\n * @param mcpServerData - The MCP server configuration\n * @returns Promise resolving to an ApiResponse with the created MCP server\n */\n async createMCPServer(mcpServerData: CreateMCPServerRequest): Promise<ApiResponse<MCPServerResponse>> {\n return this.httpPost<MCPServerResponse>(`/developer/agents/${this.agentId}/mcp-servers`, mcpServerData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Updates an existing MCP server\n * @param mcpServerId - The ID of the MCP server to update\n * @param mcpServerData - The updated MCP server configuration\n * @returns Promise resolving to an ApiResponse with the updated MCP server\n */\n async updateMCPServer(\n mcpServerId: string,\n mcpServerData: UpdateMCPServerRequest\n ): Promise<ApiResponse<MCPServerResponse>> {\n return this.httpPut<MCPServerResponse>(\n `/developer/agents/${this.agentId}/mcp-servers/${mcpServerId}`,\n mcpServerData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Deletes an MCP server\n * @param mcpServerId - The ID of the MCP server to delete\n * @returns Promise resolving to an ApiResponse with confirmation\n */\n async deleteMCPServer(mcpServerId: string): Promise<ApiResponse<void>> {\n return this.httpDelete<void>(`/developer/agents/${this.agentId}/mcp-servers/${mcpServerId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Activates an MCP server\n * @param mcpServerId - The ID of the MCP server to activate\n * @returns Promise resolving to an ApiResponse with the activated MCP server\n */\n async activateMCPServer(mcpServerId: string): Promise<ApiResponse<MCPServerResponse>> {\n return this.httpPut<MCPServerResponse>(\n `/developer/agents/${this.agentId}/mcp-servers/${mcpServerId}/activate`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Deactivates an MCP server\n * @param mcpServerId - The ID of the MCP server to deactivate\n * @returns Promise resolving to an ApiResponse with the deactivated MCP server\n */\n async deactivateMCPServer(mcpServerId: string): Promise<ApiResponse<MCPServerResponse>> {\n return this.httpPut<MCPServerResponse>(\n `/developer/agents/${this.agentId}/mcp-servers/${mcpServerId}/deactivate`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Creates or updates an MCP server by name (upsert)\n * @param mcpServerData - The MCP server configuration\n * @returns Promise resolving to an ApiResponse with the created/updated MCP server\n */\n async upsertMCPServer(mcpServerData: CreateMCPServerRequest): Promise<ApiResponse<MCPServerResponse>> {\n return this.httpPost<MCPServerResponse>(`/developer/agents/${this.agentId}/mcp-servers/upsert`, mcpServerData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Gets a user profile by email address\n * @param email - The email address to look up\n * @returns Promise resolving to an ApiResponse containing the profile, or null if not found\n */\n async getUserProfileByEmail(email: string): Promise<ApiResponse<ProfileResponse>> {\n return this.httpGet<ProfileResponse>(`/developer/user/profile/email/${encodeURIComponent(email)}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Gets a user profile by phone number\n * @param phone - The phone number to look up (with or without + prefix)\n * @returns Promise resolving to an ApiResponse containing the profile, or null if not found\n */\n async getUserProfileByPhone(phone: string): Promise<ApiResponse<ProfileResponse>> {\n const normalizedPhone = phone.replace(/^\\+/, '');\n return this.httpGet<ProfileResponse>(`/developer/user/profile/phone/${normalizedPhone}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n}\n","import type { VoiceDispatchInput, VoiceDispatchOutput } from '@lua/shared-types';\nimport { DevVersionResponse } from '../interfaces/dev.js';\nimport { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport {\n GetVoicesResponse,\n DeleteVoiceResponse,\n CreateVoiceRequest,\n CreateVoiceResponse,\n PushVoiceVersionRequest,\n GetVoiceVersionsResponse,\n} from '../interfaces/voices.js';\n\n/**\n * Voice API client — CRUD + version management for code-defined LuaVoice\n * agents on the developer API.\n */\nexport default class VoiceApi extends HttpClient {\n private apiKey: string;\n private agentId: string;\n\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n async getVoices(): Promise<ApiResponse<GetVoicesResponse>> {\n return this.httpGet<GetVoicesResponse>(`/developer/voice-agents/${this.agentId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async createVoice(voiceData: CreateVoiceRequest): Promise<ApiResponse<CreateVoiceResponse>> {\n return this.httpPost<CreateVoiceResponse>(`/developer/voice-agents/${this.agentId}`, voiceData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async pushVoice(voiceId: string, versionData: PushVoiceVersionRequest): Promise<ApiResponse<DevVersionResponse>> {\n return this.httpPost<DevVersionResponse>(\n `/developer/voice-agents/${this.agentId}/${voiceId}/version`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async getVoiceVersions(voiceId: string): Promise<ApiResponse<GetVoiceVersionsResponse>> {\n return this.httpGet<GetVoiceVersionsResponse>(`/developer/voice-agents/${this.agentId}/${voiceId}/versions`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async publishVoiceVersion(\n voiceId: string,\n version: string\n ): Promise<ApiResponse<{ message: string; voiceId: string; activeVersionId: string; publishedAt: string }>> {\n return this.httpPut<{ message: string; voiceId: string; activeVersionId: string; publishedAt: string }>(\n `/developer/voice-agents/${this.agentId}/${voiceId}/${version}/publish`,\n undefined,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async deleteVoice(voiceId: string): Promise<ApiResponse<DeleteVoiceResponse>> {\n return this.httpDelete<DeleteVoiceResponse>(`/developer/voice-agents/${this.agentId}/${voiceId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Place an outbound voice call. Wraps `POST /developer/voice-agents/:agentId/dispatch`\n * — body validated server-side (target, voice ownership, quota), then\n * forwarded to the lua-livekit worker which allocates the room and dials.\n */\n async dispatch(input: VoiceDispatchInput): Promise<ApiResponse<VoiceDispatchOutput>> {\n return this.httpPost<VoiceDispatchOutput>(`/developer/voice-agents/${this.agentId}/dispatch`, input, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Sandbox helper: throws on non-success and returns the unwrapped output.\n * Mirrors the shape `AgentsApiService.invokeForSandbox` exposes so the\n * `Voice` namespace in `api-exports.ts` stays a one-liner.\n */\n async dispatchForSandbox(input: VoiceDispatchInput): Promise<VoiceDispatchOutput> {\n const result = await this.dispatch(input);\n if (!result.success) {\n throw new Error(result.error?.message || 'Voice dispatch failed');\n }\n if (!result.data) {\n throw new Error('Voice dispatch failed: empty response');\n }\n return result.data;\n }\n}\n","import { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport type { CreateDeviceRequest, DeviceResponse, PushDeviceVersionDTO } from '../interfaces/devices.js';\n\n/**\n * Device API Response Types\n */\nexport interface DeviceVersion {\n version: string;\n deviceId: string;\n createdAt: string | number;\n isActive?: boolean;\n}\n\nexport interface GetDevicesResponse {\n devices: DeviceResponse[];\n}\n\nexport interface CreateDeviceResponse {\n id: string;\n name: string;\n description?: string;\n agentId: string;\n}\n\nexport interface PushDeviceVersionResponse {\n versionId: string;\n deviceId: string;\n version: string;\n createdAt: string;\n}\n\n/**\n * Device API Service\n * Handles all device-related API calls (CRUD, versioning, commands)\n */\nexport default class DeviceApi extends HttpClient {\n private apiKey: string;\n private agentId: string;\n\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n async getDevices(): Promise<ApiResponse<GetDevicesResponse>> {\n return this.httpGet<GetDevicesResponse>(`/developer/devices/${this.agentId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async createDevice(deviceData: CreateDeviceRequest): Promise<ApiResponse<CreateDeviceResponse>> {\n return this.httpPost<CreateDeviceResponse>(`/developer/devices/${this.agentId}`, deviceData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async pushDevice(\n deviceId: string,\n versionData: PushDeviceVersionDTO\n ): Promise<ApiResponse<PushDeviceVersionResponse>> {\n return this.httpPost<PushDeviceVersionResponse>(\n `/developer/devices/${this.agentId}/${deviceId}/version`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async pushDevDevice(\n deviceId: string,\n versionData: PushDeviceVersionDTO\n ): Promise<ApiResponse<PushDeviceVersionResponse>> {\n return this.httpPost<PushDeviceVersionResponse>(\n `/developer/devices/${this.agentId}/${deviceId}/version/sandbox`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async getDeviceVersions(\n deviceId: string\n ): Promise<ApiResponse<{ versions: DeviceVersion[]; activeVersionId?: string }>> {\n return this.httpGet<{ versions: DeviceVersion[]; activeVersionId?: string }>(\n `/developer/devices/${this.agentId}/${deviceId}/versions`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async publishDeviceVersion(\n deviceId: string,\n version: string\n ): Promise<ApiResponse<{ message: string; deviceId: string; activeVersionId: string; publishedAt: string }>> {\n return this.httpPost<{ message: string; deviceId: string; activeVersionId: string; publishedAt: string }>(\n `/developer/devices/${this.agentId}/${deviceId}/${version}/publish`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async deleteDevice(deviceId: string): Promise<ApiResponse<{ deleted: boolean; message: string }>> {\n return this.httpDelete<{ deleted: boolean; message: string }>(`/developer/devices/${this.agentId}/${deviceId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async sendCommand(deviceName: string, command: string, payload: any, timeout?: number): Promise<ApiResponse<any>> {\n return this.httpPost<any>(\n `/developer/devices/${this.agentId}/${deviceName}/command`,\n {\n command,\n payload,\n timeout: timeout || 30000,\n },\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async getDeviceStatus(deviceName: string): Promise<ApiResponse<{ status: string }>> {\n return this.httpGet<{ status: string }>(`/developer/devices/${this.agentId}/${deviceName}/status`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async enableDevice(deviceName: string): Promise<ApiResponse<any>> {\n return this.httpPatch<any>(\n `/developer/devices/${this.agentId}/${deviceName}/enable`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async disableDevice(deviceName: string): Promise<ApiResponse<any>> {\n return this.httpPatch<any>(\n `/developer/devices/${this.agentId}/${deviceName}/disable`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n}\n","/**\n * Lazy-Loaded API Instances\n * Provides singleton instances of API services with lazy initialization\n */\n\nimport { BASE_URLS } from '../config/constants.js';\nimport { getCredentials } from './credentials.js';\nimport ProductApiService from './products.api.service.js';\nimport BasketApiService from './basket.api.service.js';\nimport OrderApiService from './order.api.service.js';\nimport UserDataApiService from './user.data.api.service.js';\nimport CustomDataApiService from './custom.data.api.service.js';\nimport WebhookApi from './webhook.api.service.js';\nimport JobApi from './job.api.service.js';\nimport AiApiService from './ai.api.service.js';\nimport AgentsApiService from './agents.api.service.js';\nimport WhatsAppTemplatesApiService from './whatsapp-templates.api.service.js';\nimport CdnApi from './cdn.api.service.js';\nimport DeveloperApi from './developer.api.service.js';\nimport VoiceApi from './voice.api.service.js';\nimport { JobInstance } from '../instances/job.instance.js';\n\n/**\n * Singleton instances (lazy-loaded)\n */\nlet _userInstance: UserDataApiService | null = null;\nlet _dataInstance: CustomDataApiService | null = null;\nlet _productsInstance: ProductApiService | null = null;\nlet _basketsInstance: BasketApiService | null = null;\nlet _orderInstance: OrderApiService | null = null;\nlet _webhookInstance: WebhookApi | null = null;\nlet _jobInstance: JobApi | null = null;\nlet _aiInstance: AiApiService | null = null;\nlet _agentsInstance: AgentsApiService | null = null;\nlet _whatsAppTemplatesInstance: WhatsAppTemplatesApiService | null = null;\nlet _cdnInstance: CdnApi | null = null;\nlet _developerInstance: DeveloperApi | null = null;\nlet _voiceInstance: VoiceApi | null = null;\n\n/**\n * Gets or creates User Data API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns UserDataApiService instance\n */\nexport async function getUserInstance(): Promise<UserDataApiService> {\n if (!_userInstance) {\n const creds = await getCredentials();\n _userInstance = new UserDataApiService(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _userInstance;\n}\n\n/**\n * Gets or creates Custom Data API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns CustomDataApiService instance\n */\nexport async function getDataInstance(): Promise<CustomDataApiService> {\n if (!_dataInstance) {\n const creds = await getCredentials();\n _dataInstance = new CustomDataApiService(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _dataInstance;\n}\n\n/**\n * Gets or creates Products API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns ProductApiService instance\n */\nexport async function getProductsInstance(): Promise<ProductApiService> {\n if (!_productsInstance) {\n const creds = await getCredentials();\n _productsInstance = new ProductApiService(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _productsInstance;\n}\n\n/**\n * Gets or creates Baskets API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns BasketApiService instance\n */\nexport async function getBasketsInstance(): Promise<BasketApiService> {\n if (!_basketsInstance) {\n const creds = await getCredentials();\n _basketsInstance = new BasketApiService(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _basketsInstance;\n}\n\n/**\n * Gets or creates Orders API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns OrderApiService instance\n */\nexport async function getOrderInstance(): Promise<OrderApiService> {\n if (!_orderInstance) {\n const creds = await getCredentials();\n _orderInstance = new OrderApiService(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _orderInstance;\n}\n\n/**\n * Gets or creates Webhook API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns WebhookApi instance\n */\nexport async function getWebhookInstance(): Promise<WebhookApi> {\n if (!_webhookInstance) {\n const creds = await getCredentials();\n _webhookInstance = new WebhookApi(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _webhookInstance;\n}\n\n/**\n * Gets or creates Job API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns JobApi instance\n */\nexport async function getJobInstance(): Promise<JobApi> {\n if (!_jobInstance) {\n const creds = await getCredentials();\n _jobInstance = new JobApi(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _jobInstance;\n}\n\n/**\n * Gets or creates AI API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns AiApiService instance\n */\nexport async function getAiInstance(): Promise<AiApiService> {\n if (!_aiInstance) {\n const creds = await getCredentials();\n _aiInstance = new AiApiService(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _aiInstance;\n}\n\n/**\n * Gets or creates Agents API instance (for VM `Agents.invoke`).\n * Instance is created once and reused for subsequent calls.\n *\n * @returns AgentsApiService instance\n */\nexport async function getAgentsInstance(): Promise<AgentsApiService> {\n if (!_agentsInstance) {\n const creds = await getCredentials();\n _agentsInstance = new AgentsApiService(BASE_URLS.API, creds.apiKey);\n }\n return _agentsInstance;\n}\n\n/**\n * Gets or creates Templates API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns WhatsAppTemplatesApiService instance\n */\nexport async function getWhatsAppTemplatesInstance(): Promise<WhatsAppTemplatesApiService> {\n if (!_whatsAppTemplatesInstance) {\n const creds = await getCredentials();\n _whatsAppTemplatesInstance = new WhatsAppTemplatesApiService(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _whatsAppTemplatesInstance;\n}\n\n/**\n * Gets or creates CDN API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns CdnApi instance\n */\nexport async function getCdnInstance(): Promise<CdnApi> {\n if (!_cdnInstance) {\n const creds = await getCredentials();\n _cdnInstance = new CdnApi(BASE_URLS.CDN, creds.apiKey);\n }\n return _cdnInstance;\n}\n\n/**\n * Gets or creates Device API instance.\n */\nlet _deviceInstance: any = null;\nexport async function getDeviceInstance(): Promise<any> {\n if (!_deviceInstance) {\n const { default: DeviceApi } = await import('./device.api.service.js');\n const creds = await getCredentials();\n _deviceInstance = new DeviceApi(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _deviceInstance;\n}\n\n/**\n * Gets or creates Developer API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns DeveloperApi instance\n */\nexport async function getDeveloperInstance(): Promise<DeveloperApi> {\n if (!_developerInstance) {\n const creds = await getCredentials();\n _developerInstance = new DeveloperApi(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _developerInstance;\n}\n\n/**\n * Gets or creates Voice API instance (for sandbox `Voice.call` outbound dispatch).\n * Instance is created once and reused for subsequent calls.\n *\n * @returns VoiceApi instance\n */\nexport async function getVoiceInstance(): Promise<VoiceApi> {\n if (!_voiceInstance) {\n const creds = await getCredentials();\n _voiceInstance = new VoiceApi(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _voiceInstance;\n}\n\n/**\n * Clears all cached API instances.\n * Useful for testing or when credentials change.\n */\nexport function clearAllInstances(): void {\n _userInstance = null;\n _dataInstance = null;\n _productsInstance = null;\n _basketsInstance = null;\n _orderInstance = null;\n _webhookInstance = null;\n _jobInstance = null;\n _aiInstance = null;\n _agentsInstance = null;\n _whatsAppTemplatesInstance = null;\n _cdnInstance = null;\n _developerInstance = null;\n _voiceInstance = null;\n}\n","/**\n * Tool Validation Utilities\n * Validates tool names and other tool-related constraints\n */\n\n/**\n * Validates that a tool name contains only alphanumeric characters, hyphens, and underscores.\n * No spaces or other special characters are allowed.\n *\n * This restriction ensures tool names:\n * - Are compatible with all systems\n * - Can be used in URLs and file paths\n * - Are easy to reference in code\n *\n * Valid examples: \"my-tool\", \"calculate_sum\", \"getTodo123\"\n * Invalid examples: \"my tool\", \"calc@sum\", \"get.todo\"\n *\n * @param name - Tool name to validate\n * @returns True if name is valid, false otherwise\n */\nexport function validateToolName(name: string): boolean {\n const validNameRegex = /^[a-zA-Z0-9_-]+$/;\n return validNameRegex.test(name);\n}\n\n/**\n * Asserts that a tool name is valid, throwing an error if not.\n * Use this when adding tools to ensure names are valid.\n *\n * @param name - Tool name to validate\n * @throws Error if tool name is invalid\n *\n * @example\n * ```typescript\n * assertValidToolName('my-tool'); // OK\n * assertValidToolName('my tool'); // Throws error\n * ```\n */\nexport function assertValidToolName(name: string): void {\n if (!validateToolName(name)) {\n throw new Error(\n `Invalid tool name \"${name}\". Tool names can only contain alphanumeric characters, ` +\n `hyphens (-), and underscores (_). No spaces or other special characters are allowed.`\n );\n }\n}\n","/**\n * Lua Skill System\n * Core types and classes for building Lua AI skills\n */\n\nimport { ZodType } from 'zod';\nimport { assertValidToolName } from './tool-validation.js';\nimport UserDataInstance from '../instances/user.instance.js';\nimport { JobInstance } from '../instances/job.instance.js';\nimport type { LuaRequest } from '../interfaces/lua.js';\nimport type { PersonaText, SkillContextText } from '@lua/shared-types';\n// Type-only — voice.ts imports the ToolFlag enum from this file, so a\n// value-level import here would create a cycle.\nimport type { LuaVoice } from './voice.js';\n\n/**\n * Safe environment variable access function.\n * Gets injected at runtime with skill-specific environment variables.\n *\n * Checks process environment variables (.env file)\n *\n * @param key - The environment variable key to retrieve\n * @returns The environment variable value or undefined if not found\n *\n * @example\n * ```typescript\n * const baseUrl = env('BASE_URL');\n * const apiKey = env('API_KEY');\n * ```\n */\nexport const env = (key: string): string | undefined => {\n if (process.env[key]) {\n return process.env[key];\n }\n\n return undefined;\n};\n\n/**\n * Lua Tool interface.\n * Defines the structure of a tool that can be added to a LuaSkill.\n *\n * @template TInput - Zod schema type for input validation\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n * import { LuaTool } from 'lua-cli';\n *\n * const weatherTool: LuaTool = {\n * name: 'get_weather',\n * description: 'Gets current weather for a city',\n * inputSchema: z.object({\n * city: z.string(),\n * units: z.enum(['metric', 'imperial']).optional()\n * }),\n * execute: async (input) => {\n * // Fetch weather data...\n * return { temperature: 72, condition: 'sunny' };\n * }\n * };\n * ```\n *\n * @example\n * ```typescript\n * // Tool with condition - only available to premium users\n * class PremiumSearchTool implements LuaTool {\n * name = \"premium_search\";\n * description = \"Advanced search for premium users\";\n * inputSchema = z.object({ query: z.string() });\n *\n * // Condition runs before tool is offered to LLM\n * condition = async () => {\n * const user = await User.get();\n * return user.data?.isPremium === true;\n * };\n *\n * execute = async (input) => { ... };\n * }\n * ```\n */\n/**\n * Tool-level flags mirrored from LiveKit's `ToolFlag`. Used by `LuaTool.voice.flags`\n * to control tool availability + interruption semantics during a voice session.\n * Defined here (not voice.ts) so LuaTool's voice metadata stays self-contained\n * with no risk of circular imports.\n */\nexport enum ToolFlag {\n NONE = 'none',\n /** Tool is hidden from the LLM during the first turn after onEnter. */\n IGNORE_ON_ENTER = 'ignore_on_enter',\n /** User speech does not interrupt the agent while this tool is executing. */\n DISALLOW_INTERRUPTION = 'disallow_interruption',\n}\n\n/**\n * Per-call context passed to a `LuaTool.execute` running inside a voice\n * session. Imported here (rather than in `voice.ts`) to break a circular\n * import — `LuaVoiceTool` extends `LuaTool` and would otherwise loop.\n *\n * The chat path (lua-core's vm-execution) doesn't pass a second arg, so\n * `ctx` is `undefined` for chat. The voice path passes `{ toolCallId,\n * voice: { say } }`. Tools that want to act differently inside a voice\n * call check for `ctx?.voice` and use the typed surface.\n */\nexport interface LuaToolCtx {\n /** LiveKit's tool-call id (voice only). */\n toolCallId?: string;\n /** Voice-runtime delegates. Only set when the tool runs over voice. */\n voice?: {\n say(text: string): Promise<void>;\n };\n}\n\nexport interface LuaTool<TInput extends ZodType = ZodType> {\n /** Unique tool name (alphanumeric, hyphens, underscores only) */\n name: string;\n /** Description of what the tool does */\n description: string;\n /** Zod schema for input validation */\n inputSchema: TInput;\n /**\n * Async function that executes the tool logic.\n *\n * `ctx` is `undefined` when the tool runs from the chat path (lua-core's\n * vm-execution doesn't pass a second arg today). When the tool runs\n * inside a voice session, `ctx` carries the voice runtime's delegates\n * (`ctx.voice.say(...)` to emit a spoken acknowledgement, plus the\n * `toolCallId` LiveKit assigned). Tools that want to bridge both modes\n * read `ctx?.voice` and branch.\n */\n execute: (input: any, ctx?: LuaToolCtx) => Promise<any>;\n /** Optional async function that determines if the tool should be available */\n condition?: () => Promise<boolean>;\n /**\n * Optional voice-only metadata. When present, the lua-livekit worker\n * applies these flags to the wrapped LiveKit `llm.tool()` registration.\n * Tools without this field work in chat and voice unchanged.\n */\n voice?: { flags?: ToolFlag[] };\n}\n\n/**\n * Lua Skill configuration.\n * Used to initialize a new LuaSkill instance.\n */\nexport interface LuaSkillConfig {\n /** Skill name (required; used as the server-side identifier). */\n name: string;\n /** Short description of the skill (1-2 sentences) */\n description: string;\n /** Detailed context for how the agent should use the tools */\n context: SkillContextText;\n /** Optional array of tools to add during construction */\n tools?: LuaTool<any>[];\n}\n\n/**\n * Lua Skill class.\n * Main class for building AI skills with tools.\n *\n * A skill is a collection of tools that the AI agent can use to accomplish tasks.\n * Tools are functions with validated inputs and well-defined outputs.\n *\n * @example\n * ```typescript\n * import { LuaSkill } from 'lua-cli';\n *\n * const skill = new LuaSkill({\n * name: 'weather-skill',\n * description: \"Weather and calculator utilities\",\n * context: \"This skill provides weather information and math operations. \" +\n * \"Use get_weather for current conditions and calculator for arithmetic.\",\n * tools: [weatherTool, calculatorTool]\n * });\n *\n * // Or add tools after construction\n * skill.addTool(anotherTool);\n * ```\n */\nexport class LuaSkill {\n private readonly tools: LuaTool<any>[] = [];\n private readonly name: string;\n private readonly description: string;\n private readonly context: SkillContextText;\n\n /**\n * Creates a new LuaSkill instance.\n *\n * @param config - Configuration object containing skill metadata\n * @param config.name - Skill name (required; non-empty string)\n * @param config.description - Short description of what the skill does (1-2 sentences)\n * @param config.context - Detailed explanation of how the agent should use the tools\n * @param config.tools - Optional array of tools to add immediately\n */\n constructor(config: LuaSkillConfig) {\n if (!config.name || !config.name.trim()) {\n throw new Error('LuaSkill requires a non-empty `name` (used as the server-side identifier).');\n }\n this.name = config.name;\n this.description = config.description;\n this.context = config.context;\n\n if (typeof this.context === 'object') {\n if (!this.context.base && !this.context.voice && !this.context.text) {\n throw new Error('Skill context object must have at least one of: base, voice, text');\n }\n }\n\n // Add tools from constructor if provided\n if (config.tools) {\n this.addTools(config.tools);\n }\n }\n\n getContext(): SkillContextText {\n return this.context;\n }\n\n /**\n * Adds a single tool to the skill.\n * Tool name is validated before being added.\n *\n * @param tool - Tool to add\n * @throws Error if tool name is invalid\n */\n addTool<TInput extends ZodType>(tool: LuaTool<TInput>): void {\n assertValidToolName(tool.name);\n this.tools.push(tool);\n }\n\n /**\n * Adds multiple tools to the skill.\n * All tool names are validated before being added.\n *\n * @param tools - Array of tools to add\n * @throws Error if any tool name is invalid\n */\n addTools(tools: LuaTool<any>[]): void {\n // Validate all tool names before adding them\n for (const tool of tools) {\n assertValidToolName(tool.name);\n }\n this.tools.push(...tools);\n }\n\n /**\n * Executes a tool by name with provided input.\n * Input is validated against the tool's Zod schema.\n *\n * @param input - Input object containing tool name and parameters\n * @param input.tool - Name of the tool to execute\n * @returns Promise resolving to tool execution result\n * @throws Error if tool not found or input validation fails\n */\n async run(input: Record<string, any>) {\n const tool = this.tools.find((tool) => tool.name === input.tool);\n if (!tool) {\n throw new Error(`Tool ${input.tool} not found`);\n }\n\n // Validate input against the tool's schema\n const validatedInput = tool.inputSchema.parse(input);\n return tool.execute(validatedInput);\n }\n}\n\n/**\n * Job schedule configuration\n * Supports either cron-style recurring schedules or one-time execution\n */\nexport type JobSchedule =\n | { type: 'cron'; expression: string; timezone?: string }\n | { type: 'once'; executeAt: Date | string }\n | { type: 'interval'; seconds: number };\n\n/**\n * Lua Job configuration.\n * Used to initialize a new LuaJob instance.\n */\nexport interface LuaJobConfig {\n /** Job name (required; used as the server-side identifier). */\n name: string;\n /** Short description of the job (1-2 sentences) */\n description: string;\n /** Schedule configuration - cron, once, or interval */\n schedule: JobSchedule;\n /**\n * Function that executes the job logic.\n * Receives metadata as parameter for accessing job configuration.\n */\n execute: (job: JobInstance) => Promise<any>;\n /** Optional timeout in seconds (default: 300) */\n timeout?: number;\n /** Optional retry configuration */\n retry?: {\n maxAttempts: number;\n backoffSeconds?: number;\n };\n /**\n * Optional metadata for the job.\n * Can store any custom data (tags, config, context, etc.)\n * Sent to server and accessible during execution.\n */\n metadata?: Record<string, any>;\n}\n\n/**\n * Lua Job class.\n * Main class for building scheduled jobs (cron jobs, one-time tasks, intervals).\n *\n * A job is a scheduled task that executes at specific times or intervals.\n * Jobs can run once, on a recurring schedule (cron), or at fixed intervals.\n *\n * @example\n * ```typescript\n * import { LuaJob } from 'lua-cli';\n *\n * // Daily cleanup job at 2 AM\n * const dailyCleanup = new LuaJob({\n * name: 'daily-cleanup',\n * description: \"Daily database cleanup job\",\n * schedule: {\n * type: 'cron',\n * expression: '0 2 * * *', // 2 AM every day\n * timezone: 'America/New_York'\n * },\n * timeout: 600, // 10 minutes\n * retry: {\n * maxAttempts: 3,\n * backoffSeconds: 60\n * },\n * execute: async () => {\n * // Cleanup logic\n * console.log('Running cleanup...');\n * return { recordsDeleted: 150 };\n * }\n * });\n *\n * // One-time job\n * const sendWelcome = new LuaJob({\n * name: 'send-welcome',\n * description: \"Send welcome email to new users\",\n * schedule: {\n * type: 'once',\n * executeAt: new Date('2025-12-31T10:00:00Z')\n * },\n * execute: async () => {\n * console.log('Sending welcome emails...');\n * return { emailsSent: 100 };\n * }\n * });\n *\n * // Interval-based job (every 5 minutes)\n * const healthCheck = new LuaJob({\n * name: 'health-check',\n * description: \"System health check\",\n * schedule: {\n * type: 'interval',\n * seconds: 300 // 5 minutes\n * },\n * execute: async () => {\n * return { status: 'healthy' };\n * }\n * });\n * ```\n */\nexport class LuaJob {\n private readonly name: string;\n private readonly description: string;\n private readonly schedule: JobSchedule;\n private readonly timeout: number;\n private readonly retry?: {\n maxAttempts: number;\n backoffSeconds?: number;\n };\n private readonly metadata?: Record<string, any>;\n private readonly executeFunction: (job: JobInstance) => Promise<any>;\n\n /**\n * Creates a new LuaJob instance.\n *\n * @param config - Configuration object containing job metadata\n * @param config.name - Job name (required; non-empty string)\n * @param config.description - Short description of what the job does (1-2 sentences)\n * @param config.schedule - Schedule configuration (cron, once, or interval)\n * @param config.timeout - Optional timeout in seconds (default: 300)\n * @param config.retry - Optional retry configuration\n * @param config.metadata - Optional metadata for the job\n * @param config.execute - Function that processes the job (receives job instance as parameter)\n */\n constructor(config: LuaJobConfig) {\n if (!config.name || !config.name.trim()) {\n throw new Error('LuaJob requires a non-empty `name` (used as the server-side identifier).');\n }\n this.name = config.name;\n this.description = config.description;\n this.schedule = config.schedule;\n this.timeout = config.timeout || 300;\n this.retry = config.retry;\n this.metadata = config.metadata;\n this.executeFunction = config.execute;\n }\n\n /**\n * Gets the job name.\n */\n getName(): string {\n return this.name;\n }\n\n /**\n * Gets the job description.\n */\n getDescription(): string {\n return this.description;\n }\n\n /**\n * Gets the job schedule.\n */\n getSchedule(): JobSchedule {\n return this.schedule;\n }\n\n /**\n * Gets the job timeout in seconds.\n */\n getTimeout(): number {\n return this.timeout;\n }\n\n /**\n * Gets the retry configuration.\n */\n getRetry(): { maxAttempts: number; backoffSeconds?: number } | undefined {\n return this.retry;\n }\n\n /**\n * Gets the job metadata.\n */\n getMetadata(): Record<string, any> | undefined {\n return this.metadata;\n }\n\n /**\n * Executes the job with the provided job instance.\n * @param job - Job instance with metadata and context\n * @returns Promise resolving to job execution result\n */\n async execute(job: JobInstance): Promise<any> {\n return this.executeFunction(job);\n }\n}\n\n/**\n * Event payload delivered to webhook execute functions.\n */\nexport interface LuaWebhookEvent {\n /** Parsed query parameters */\n query?: Record<string, any>;\n /** Request headers */\n headers?: Record<string, any>;\n /** Request body (JSON or raw data) */\n body?: any;\n /** ISO timestamp when the webhook was received */\n timestamp: string;\n}\n\n/**\n * Lua Webhook configuration.\n * Used to initialize a new LuaWebhook instance.\n */\nexport interface LuaWebhookConfig {\n /** Webhook name (required; used as the server-side identifier). */\n name: string;\n /** Short description of the webhook (1-2 sentences) */\n description: string;\n /** Optional Zod schema for query parameter validation */\n querySchema?: ZodType;\n /** Optional Zod schema for header validation */\n headerSchema?: ZodType;\n /** Optional Zod schema for body validation */\n bodySchema?: ZodType;\n /** Function that executes the webhook logic */\n execute: (event: LuaWebhookEvent) => Promise<any>;\n}\n\n/**\n * Lua Webhook class.\n * Main class for building webhooks with validated inputs.\n *\n * A webhook is an HTTP endpoint that can receive requests with validated\n * query parameters, headers, and body. The execute function processes the\n * validated input and returns a response.\n *\n * @example\n * ```typescript\n * import { LuaWebhook } from 'lua-cli';\n * import { z } from 'zod';\n *\n * const webhook = new LuaWebhook({\n * name: 'user-created',\n * description: \"Webhook that handles user creation events\",\n * querySchema: z.object({\n * source: z.string().optional()\n * }),\n * headerSchema: z.object({\n * 'x-api-key': z.string(),\n * 'content-type': z.string().optional()\n * }),\n * bodySchema: z.object({\n * userId: z.string(),\n * email: z.string().email(),\n * name: z.string()\n * }),\n * execute: async (event) => {\n * const { query, headers, body } = event;\n * // Process the webhook...\n * console.log('New user:', body.email);\n * return { success: true, userId: body.userId };\n * }\n * });\n *\n * // Execute the webhook with validated inputs\n * const result = await webhook.execute(\n * { source: 'mobile' },\n * { 'x-api-key': 'secret-key' },\n * { userId: '123', email: 'user@example.com', name: 'John' }\n * );\n * ```\n */\nexport class LuaWebhook {\n private readonly name: string;\n private readonly description: string;\n private readonly querySchema?: ZodType;\n private readonly headerSchema?: ZodType;\n private readonly bodySchema?: ZodType;\n private readonly executeFunction: (event: LuaWebhookEvent) => Promise<any>;\n\n /**\n * Creates a new LuaWebhook instance.\n *\n * @param config - Configuration object containing webhook metadata\n * @param config.name - Webhook name (required; non-empty string)\n * @param config.description - Short description of what the webhook does (1-2 sentences)\n * @param config.querySchema - Optional Zod schema for query parameter validation\n * @param config.headerSchema - Optional Zod schema for header validation\n * @param config.bodySchema - Optional Zod schema for body validation\n * @param config.execute - Function that processes the webhook request\n */\n constructor(config: LuaWebhookConfig) {\n if (!config.name || !config.name.trim()) {\n throw new Error('LuaWebhook requires a non-empty `name` (used as the server-side identifier).');\n }\n this.name = config.name;\n this.description = config.description;\n this.querySchema = config.querySchema;\n this.headerSchema = config.headerSchema;\n this.bodySchema = config.bodySchema;\n this.executeFunction = config.execute;\n }\n\n /**\n * Gets the webhook name.\n */\n getName(): string {\n return this.name;\n }\n\n /**\n * Gets the webhook description.\n */\n getDescription(): string {\n return this.description;\n }\n\n /**\n * Executes the webhook with validated input.\n * Validates query parameters, headers, and body against their respective schemas\n * before executing the webhook function.\n *\n * @param query - Query parameters object\n * @param headers - Headers object\n * @param body - Request body\n * @returns Promise resolving to webhook execution result\n * @throws Error if validation fails for any input\n *\n * @example\n * ```typescript\n * const result = await webhook.execute(\n * { limit: '10' },\n * { 'x-api-key': 'secret' },\n * { data: 'value' }\n * );\n * ```\n */\n async execute(query?: Record<string, any>, headers?: Record<string, any>, body?: any): Promise<any> {\n let validatedQuery = query;\n let validatedHeaders = headers;\n let validatedBody = body;\n\n // Validate query parameters if schema is provided\n if (this.querySchema) {\n try {\n validatedQuery = this.querySchema.parse(query || {}) as Record<string, any>;\n } catch (error) {\n throw new Error(`Query parameter validation failed: ${error}`);\n }\n }\n\n // Validate headers if schema is provided\n if (this.headerSchema) {\n try {\n validatedHeaders = this.headerSchema.parse(headers || {}) as Record<string, any>;\n } catch (error) {\n throw new Error(`Header validation failed: ${error}`);\n }\n }\n\n // Validate body if schema is provided\n if (this.bodySchema) {\n try {\n validatedBody = this.bodySchema.parse(body);\n } catch (error) {\n throw new Error(`Body validation failed: ${error}`);\n }\n }\n\n const event: LuaWebhookEvent = {\n query: validatedQuery || {},\n headers: validatedHeaders || {},\n body: validatedBody,\n timestamp: new Date().toISOString(),\n };\n\n return this.executeFunction(event);\n }\n}\n\n// ============================================================================\n// PREPROCESSOR\n// ============================================================================\n\nexport type PreProcessorAction = 'proceed' | 'block';\n\nexport type PreProcessorBlockResponse = {\n /** Stop processing immediately */\n action: 'block';\n /** Message to show to the user */\n response: string;\n /** Optional metadata */\n metadata?: Record<string, any>;\n};\n\nexport type PreProcessorProceedResponse = {\n /** Proceed to next preprocessor or agent */\n action: 'proceed';\n /** Optional modified message (if not provided, uses original/current message) */\n modifiedMessage?: import('../interfaces/chat.js').ChatMessage[];\n /** Optional metadata to pass along */\n metadata?: Record<string, any>;\n};\n\n/**\n * Result returned by the preprocessor\n */\nexport type PreProcessorResult = PreProcessorBlockResponse | PreProcessorProceedResponse;\n\n/**\n * PreProcessor configuration.\n */\nexport interface PreProcessorConfig {\n /** PreProcessor name (required; used as the server-side identifier). */\n name: string;\n /** Short description of the preprocessor */\n description: string;\n /**\n * Async flag - indicates if processor should run in background on server:\n * - true: Run asynchronously (non-blocking, for slow operations like API calls)\n * - false: Run synchronously (blocking, for fast operations like text filtering)\n * Default: false (synchronous)\n */\n async?: boolean;\n /**\n * Execution priority (lower runs first).\n * Default: 100\n */\n priority?: number;\n /**\n * Function that processes messages before sending to agent.\n */\n execute: (\n user: UserDataInstance,\n messages: import('../interfaces/chat.js').ChatMessage[],\n channel: string\n ) => Promise<PreProcessorResult>;\n}\n\n/**\n * PreProcessor class.\n * Processes user messages before they reach the agent.\n * Can handle rich content (text, images, files).\n *\n * @example\n * ```typescript\n * const contentFilter = new PreProcessor({\n * name: 'content-filter',\n * description: 'Filters and processes message content',\n * priority: 10,\n * execute: async (user, messages, channel) => {\n * // Check for spam\n * const hasSpam = messages.some(msg =>\n * msg.type === 'text' && msg.text.includes('spam')\n * );\n *\n * if (hasSpam) {\n * return {\n * action: 'block',\n * response: \"Message blocked due to spam content\"\n * };\n * }\n *\n * // Return messages to proceed\n * return { action: 'proceed' };\n * }\n * });\n * ```\n */\nexport class PreProcessor {\n private readonly name: string;\n private readonly description: string;\n private readonly asyncMode: boolean;\n private readonly priority: number;\n private readonly executeFunction: (\n user: UserDataInstance,\n messages: import('../interfaces/chat.js').ChatMessage[],\n channel: string\n ) => Promise<PreProcessorResult>;\n\n constructor(config: PreProcessorConfig) {\n if (!config.name || !config.name.trim()) {\n throw new Error('PreProcessor requires a non-empty `name` (used as the server-side identifier).');\n }\n this.name = config.name;\n this.description = config.description;\n this.asyncMode = config.async ?? false; // Default to synchronous\n this.priority = config.priority ?? 100;\n this.executeFunction = config.execute;\n }\n\n getName(): string {\n return this.name;\n }\n\n getDescription(): string {\n return this.description;\n }\n\n getAsync(): boolean {\n return this.asyncMode;\n }\n\n getPriority(): number {\n return this.priority;\n }\n\n async execute(\n user: UserDataInstance,\n messages: import('../interfaces/chat.js').ChatMessage[],\n channel: string\n ): Promise<PreProcessorResult> {\n return this.executeFunction(user, messages, channel);\n }\n}\n\n// ============================================================================\n// POSTPROCESSOR\n// ============================================================================\n\n/**\n * PostProcessor response type.\n * The execute function must return an object with the modified response.\n */\nexport interface PostProcessorResponse {\n modifiedResponse: string;\n}\n\n/**\n * PostProcessor configuration.\n */\nexport interface PostProcessorConfig {\n /** PostProcessor name (required; used as the server-side identifier). */\n name: string;\n /** Short description of the postprocessor */\n description: string;\n /**\n * Execution priority (lower runs first).\n * Default: 100\n */\n priority?: number;\n /**\n * Function that processes the agent's response before sending to user.\n * MUST return { modifiedResponse: string } - the formatted response text.\n */\n execute: (\n user: UserDataInstance,\n message: string,\n response: string,\n channel: string\n ) => Promise<PostProcessorResponse>;\n}\n\n/**\n * PostProcessor class.\n * Processes agent responses before they reach the user.\n *\n * @example\n * ```typescript\n * const responseFormatter = new PostProcessor({\n * name: 'response-formatter',\n * description: 'Formats responses with branding',\n * execute: async (user, message, response, channel) => {\n * return { modifiedResponse: response + '\\n\\n---\\nPowered by Acme Corp' };\n * }\n * });\n * ```\n */\nexport class PostProcessor {\n private readonly name: string;\n private readonly description: string;\n private readonly priority: number;\n private readonly executeFunction: (\n user: UserDataInstance,\n message: string,\n response: string,\n channel: string\n ) => Promise<PostProcessorResponse>;\n\n constructor(config: PostProcessorConfig) {\n if (!config.name || !config.name.trim()) {\n throw new Error('PostProcessor requires a non-empty `name` (used as the server-side identifier).');\n }\n this.name = config.name;\n this.description = config.description;\n this.priority = config.priority ?? 100;\n this.executeFunction = config.execute;\n }\n\n getName(): string {\n return this.name;\n }\n\n getDescription(): string {\n return this.description;\n }\n\n getPriority(): number {\n return this.priority;\n }\n\n async execute(\n user: UserDataInstance,\n message: string,\n response: string,\n channel: string\n ): Promise<PostProcessorResponse> {\n return this.executeFunction(user, message, response, channel);\n }\n}\n\n// ============================================================================\n// MCP SERVER - Model Context Protocol Server Configuration\n// ============================================================================\n\n/**\n * MCP Server transport type - determines how to connect to the server.\n *\n * - 'streamable-http': Modern MCP standard (recommended) - single endpoint for bidirectional communication\n * - 'sse': Legacy Server-Sent Events transport - for older MCP servers\n *\n * Note: 'stdio' transport is not supported yet.\n */\nexport type MCPTransport = 'sse' | 'streamable-http';\n\n/**\n * Base configuration for all MCP servers.\n */\nexport interface MCPServerBaseConfig {\n /** Unique identifier for this MCP server */\n name: string;\n /** Optional timeout in milliseconds (default: 60000) */\n timeout?: number;\n}\n\n/**\n * Function type for resolving environment variables at runtime.\n * Use env() inside to access agent environment variables.\n *\n * @example\n * ```typescript\n * env: () => ({\n * API_KEY: env(\"MY_API_KEY\"),\n * DEBUG: \"true\"\n * })\n * ```\n */\nexport type EnvResolverFunction = () => Record<string, string>;\n\n/**\n * Function type for resolving headers at runtime.\n * Use env() inside to access agent environment variables.\n *\n * @example\n * ```typescript\n * headers: () => ({\n * 'Authorization': `Bearer ${env(\"API_TOKEN\")}`\n * })\n * ```\n */\nexport type HeadersResolverFunction = () => Record<string, string>;\n\n/**\n * Function type for resolving URL at runtime.\n * Use env() inside to access agent environment variables.\n *\n * @example\n * ```typescript\n * url: () => env(\"MCP_SERVER_URL\") || \"https://default.example.com/mcp\"\n * ```\n */\nexport type UrlResolverFunction = () => string;\n\n/**\n * Configuration for SSE-based MCP servers (legacy remote endpoints)\n *\n * Use this for older MCP servers that don't support Streamable HTTP.\n * For new integrations, prefer MCPStreamableHttpServerConfig.\n */\nexport interface MCPSSEServerConfig extends MCPServerBaseConfig {\n transport: 'sse';\n /**\n * URL of the MCP server endpoint.\n * Can be a static string or a function that returns the URL at runtime.\n *\n * @example\n * // Static\n * url: \"https://api.example.com/mcp\"\n *\n * // Function (evaluated at runtime)\n * url: () => env(\"MCP_SERVER_URL\")\n */\n url: string | UrlResolverFunction;\n /**\n * Optional headers to send with requests.\n * Can be a static object or a function that returns headers at runtime.\n * Use a function to access env() for dynamic resolution from agent env vars.\n *\n * @example\n * // Static (NOT recommended for secrets)\n * headers: { 'X-Custom': 'value' }\n *\n * // Function (evaluated at runtime - recommended for auth)\n * headers: () => ({\n * 'Authorization': `Bearer ${env(\"API_TOKEN\")}`\n * })\n */\n headers?: Record<string, string> | HeadersResolverFunction;\n}\n\n/**\n * Configuration for Streamable HTTP MCP servers (modern standard - RECOMMENDED)\n *\n * This is the recommended transport for new MCP server integrations.\n * Streamable HTTP is the modern MCP standard (spec 2025-03-26) that provides:\n * - Single endpoint for bidirectional communication\n * - Session management via Mcp-Session-Id header\n * - Resumability via SSE event IDs\n *\n * @example\n * ```typescript\n * const docsServer = new LuaMCPServer({\n * name: 'docs',\n * transport: 'streamable-http',\n * url: 'https://mcp.example.com/mcp',\n * headers: () => ({\n * 'Authorization': `Bearer ${env(\"MCP_API_TOKEN\")}`\n * })\n * });\n * ```\n */\nexport interface MCPStreamableHttpServerConfig extends MCPServerBaseConfig {\n transport: 'streamable-http';\n /**\n * URL of the MCP server endpoint.\n * Can be a static string or a function that returns the URL at runtime.\n *\n * @example\n * // Static\n * url: \"https://api.example.com/mcp\"\n *\n * // Function (evaluated at runtime)\n * url: () => env(\"MCP_SERVER_URL\")\n */\n url: string | UrlResolverFunction;\n /**\n * Optional headers to send with requests.\n * Can be a static object or a function that returns headers at runtime.\n * Use a function to access env() for dynamic resolution from agent env vars.\n *\n * @example\n * // Static (NOT recommended for secrets)\n * headers: { 'X-Custom': 'value' }\n *\n * // Function (evaluated at runtime - recommended for auth)\n * headers: () => ({\n * 'Authorization': `Bearer ${env(\"API_TOKEN\")}`\n * })\n */\n headers?: Record<string, string> | HeadersResolverFunction;\n}\n\n/**\n * Union type for all MCP server configurations.\n *\n * Note: stdio transport is not supported yet.\n * Use 'streamable-http' (recommended) or 'sse' (legacy) instead.\n */\nexport type LuaMCPServerConfig = MCPSSEServerConfig | MCPStreamableHttpServerConfig;\n\n/**\n * LuaMCPServer class.\n * Defines an MCP (Model Context Protocol) server connection.\n *\n * MCP servers provide tools that can be used by your agent at runtime.\n * Connect to remote MCP servers via Streamable HTTP (recommended) or SSE (legacy).\n *\n * Environment variables can be provided as static values or as functions that\n * resolve at runtime using the env() API (consistent with tool execute functions).\n *\n * @example\n * ```typescript\n * import { LuaMCPServer, env } from 'lua-cli';\n *\n * // Remote MCP server via Streamable HTTP (recommended)\n * const docsServer = new LuaMCPServer({\n * name: 'docs',\n * transport: 'streamable-http',\n * url: 'https://mcp.example.com/mcp',\n * headers: () => ({\n * 'Authorization': `Bearer ${env(\"MCP_API_TOKEN\")}`\n * })\n * });\n *\n * // Remote MCP server via SSE (legacy)\n * const legacyServer = new LuaMCPServer({\n * name: 'legacy-api',\n * transport: 'sse',\n * url: 'https://old-mcp.example.com/sse',\n * headers: () => ({\n * 'Authorization': `Bearer ${env(\"API_KEY\")}`\n * })\n * });\n * ```\n */\nexport class LuaMCPServer {\n private readonly config: LuaMCPServerConfig;\n\n constructor(config: LuaMCPServerConfig) {\n if (!config.name) {\n throw new Error('MCP server name is required');\n }\n // Reject stdio transport (not supported yet) with helpful error message\n if ((config as any).transport === 'stdio') {\n throw new Error(\n `stdio transport is not supported yet. ` +\n `Please use 'streamable-http' (recommended) or 'sse' transport instead. ` +\n `See https://docs.heylua.ai/overview/mcp-servers for migration guide.`\n );\n }\n if ((config.transport === 'sse' || config.transport === 'streamable-http') && !config.url) {\n throw new Error(`URL is required for ${config.transport} transport`);\n }\n this.config = config;\n }\n\n getName(): string {\n return this.config.name;\n }\n\n getTransport(): MCPTransport {\n return this.config.transport;\n }\n\n getTimeout(): number | undefined {\n return this.config.timeout;\n }\n\n getConfig(): LuaMCPServerConfig {\n return this.config;\n }\n\n /**\n * Returns the server configuration in a format suitable for serialization.\n * Environment variable references (${env.VAR_NAME}) are preserved for runtime resolution.\n */\n toJSON(): Record<string, any> {\n const base: Record<string, any> = {\n name: this.config.name,\n transport: this.config.transport,\n };\n\n if (this.config.timeout) {\n base.timeout = this.config.timeout;\n }\n\n // Both sse and streamable-http transports use the same fields\n base.url = this.config.url;\n if (this.config.headers) {\n base.headers = this.config.headers;\n }\n\n return base;\n }\n}\n\n// ============================================================================\n// LUA AGENT - Unified Agent Configuration\n// ============================================================================\n\n/**\n * LuaAgent configuration interface.\n * Provides a simplified, unified way to configure an agent with all its components.\n *\n * This is the recommended approach for defining your agent. Instead of exporting\n * individual skills, jobs, webhooks, etc., you export a single LuaAgent object\n * that contains everything.\n */\n\n/**\n * Per-agent message batching/debounce configuration.\n * Overrides platform-wide env var defaults for this specific agent.\n * Any field left undefined falls back to the env var, then to the hardcoded default.\n *\n * @example\n * ```typescript\n * export default new LuaAgent({\n * name: 'my-agent',\n * persona: '...',\n * batching: {\n * firstMessageDelayMs: 200, // hold first message 200ms to allow batch formation\n * debounceWindowMs: 1500, // extend window 1.5s per new message while in-flight\n * maxBatchMessages: 5,\n * }\n * });\n * ```\n */\nimport type { AgentModelSettings, BatchingConfig, GovernanceConfig } from '@lua/shared-types';\n\n/**\n * Validates obviously-wrong values on a user-supplied `modelSettings` block.\n * Provider-specific range checks (e.g. presencePenalty bounds) are left to\n * the provider — we only catch the unambiguously-broken cases here so the\n * CLI fails fast instead of waiting for a runtime provider error.\n */\nfunction validateModelSettings(settings: AgentModelSettings): void {\n const finiteNumberKeys = [\n 'temperature',\n 'topP',\n 'topK',\n 'maxOutputTokens',\n 'presencePenalty',\n 'frequencyPenalty',\n 'seed',\n ] as const;\n for (const key of finiteNumberKeys) {\n const value = settings[key];\n if (value !== undefined && (typeof value !== 'number' || !Number.isFinite(value))) {\n throw new Error(`Agent modelSettings.${key} must be a finite number`);\n }\n }\n if (settings.temperature !== undefined && (settings.temperature < 0 || settings.temperature > 2)) {\n throw new Error('Agent modelSettings.temperature must be between 0 and 2');\n }\n if (settings.topP !== undefined && (settings.topP < 0 || settings.topP > 1)) {\n throw new Error('Agent modelSettings.topP must be between 0 and 1');\n }\n if (settings.maxOutputTokens !== undefined && settings.maxOutputTokens < 1) {\n throw new Error('Agent modelSettings.maxOutputTokens must be >= 1');\n }\n if (settings.stopSequences !== undefined) {\n // Verify both the array shape AND every element is a string — the compiler's\n // `shapeModelSettings` silently drops arrays with non-string elements, so a\n // permissive constructor check produces confusing \"my stop sequences\n // disappeared\" behavior at push time.\n if (!Array.isArray(settings.stopSequences) || !settings.stopSequences.every((v) => typeof v === 'string')) {\n throw new Error('Agent modelSettings.stopSequences must be a string array');\n }\n }\n}\n\n/**\n * Type for the agent's model property.\n *\n * Can be either:\n * - A static `'provider/model'` string (e.g., `'openai/gpt-4o'`)\n * - A resolver function that receives `LuaRequest` and returns a model string.\n * The function runs in the full sandbox with access to all APIs (User, Baskets, etc.)\n *\n * @example\n * ```typescript\n * // Static model\n * model: 'openai/gpt-4o'\n *\n * // Dynamic model based on channel\n * model: async (request) => {\n * if (request.channel === 'whatsapp') return 'openai/gpt-4o-mini';\n * return 'openai/gpt-4o';\n * }\n * ```\n */\nexport type LuaAgentModel = string | ((request: LuaRequest) => string | Promise<string>);\n\nexport interface LuaAgentConfig {\n /** Agent name (used for identification) */\n name: string;\n /** Agent persona - defines the agent's behavior and personality */\n persona: PersonaText;\n /** LLM model to use — 'provider/model' string or resolver function */\n model?: LuaAgentModel;\n /**\n * Per-call sampling settings (temperature, topP, maxOutputTokens, etc.).\n * Passed straight through to Mastra / AI SDK on every `chat/stream` and\n * `chat/generate`. Undefined leaves provider defaults in place.\n *\n * @example\n * modelSettings: { temperature: 0.2, maxOutputTokens: 4096 }\n */\n modelSettings?: AgentModelSettings;\n /** Array of skills (each with tools) */\n skills?: LuaSkill[];\n /** Array of webhooks */\n webhooks?: LuaWebhook[];\n /** Array of scheduled jobs */\n jobs?: LuaJob[];\n /** Array of preprocessors (run before messages reach the agent) */\n preProcessors?: PreProcessor[];\n /** Array of postprocessors (run after agent generates responses) */\n postProcessors?: PostProcessor[];\n /** Array of MCP servers (Model Context Protocol) for external tool integrations */\n mcpServers?: LuaMCPServer[];\n /** Array of devices (external hardware that the agent can send commands to and receive triggers from) */\n devices?: LuaDevice[];\n /** Standalone device triggers — agent-side logic that any device can fire */\n deviceTriggers?: LuaDeviceTrigger[];\n /**\n * Voices the agent can use. Each channel picks which one fires via\n * `channelConfig.<kind>.voiceId`; absent binding falls back to the\n * first entry. For the simple \"one voice for everything\" case, pass a\n * single-element array — `voices: [supportVoice]`.\n */\n voices?: LuaVoice[];\n /** Per-agent message batching/debounce configuration. Overrides platform env var defaults. */\n batching?: BatchingConfig;\n /** Governance policy configuration. When set, tool calls, preprocessors, and postprocessors are governed. */\n governance?: GovernanceConfig;\n}\n\n/**\n * LuaAgent class.\n * Unified agent configuration that consolidates skills, webhooks, jobs, and processors.\n *\n * This is the simplest way to define an agent. Instead of exporting multiple separate\n * components, you create one LuaAgent that contains everything.\n *\n * @example\n * ```typescript\n * import { LuaAgent, LuaSkill, LuaJob, LuaWebhook } from 'lua-cli';\n *\n * // Define your skills, jobs, webhooks in separate files\n * import { userSkill } from './skills/user-skill';\n * import { healthCheckJob } from './jobs/health-check';\n * import { webhookHandler } from './webhooks/handler';\n *\n * // Create a single agent configuration\n * export const agent = new LuaAgent({\n * name: 'my-assistant',\n * persona: 'You are a helpful AI assistant that can manage users and products.',\n * skills: [userSkill],\n * jobs: [healthCheckJob],\n * webhooks: [webhookHandler],\n * preProcessors: [],\n * postProcessors: []\n * });\n * ```\n */\nexport class LuaAgent {\n private readonly name: string;\n private readonly persona: PersonaText;\n private readonly model?: LuaAgentModel;\n private readonly modelSettings?: AgentModelSettings;\n private readonly skills: LuaSkill[];\n private readonly webhooks: LuaWebhook[];\n private readonly jobs: LuaJob[];\n private readonly preProcessors: PreProcessor[];\n private readonly postProcessors: PostProcessor[];\n private readonly mcpServers: LuaMCPServer[];\n private readonly devices: LuaDevice[];\n private readonly deviceTriggers: LuaDeviceTrigger[];\n private readonly voices?: LuaVoice[];\n private readonly batching?: BatchingConfig;\n private readonly governance?: LuaAgentConfig['governance'];\n\n /**\n * Creates a new LuaAgent instance.\n *\n * @param config - Agent configuration\n * @param config.name - Agent name\n * @param config.persona - Agent persona (behavior and personality)\n * @param config.model - Optional LLM model ('provider/model' string or resolver function)\n * @param config.skills - Optional array of skills\n * @param config.webhooks - Optional array of webhooks\n * @param config.jobs - Optional array of jobs\n * @param config.preProcessors - Optional array of preprocessors\n * @param config.postProcessors - Optional array of postprocessors\n * @param config.mcpServers - Optional array of MCP servers\n * @param config.devices - Optional array of devices (external hardware)\n * @param config.batching - Optional per-agent batching/debounce configuration\n */\n constructor(config: LuaAgentConfig) {\n this.name = config.name;\n this.persona = config.persona;\n this.model = config.model;\n if (config.modelSettings !== undefined) {\n validateModelSettings(config.modelSettings);\n }\n this.modelSettings = config.modelSettings;\n\n if (typeof this.persona === 'object') {\n if (!this.persona.base && !this.persona.voice && !this.persona.text) {\n throw new Error('Agent persona object must have at least one of: base, voice, text');\n }\n }\n\n this.skills = config.skills || [];\n this.webhooks = config.webhooks || [];\n this.jobs = config.jobs || [];\n this.preProcessors = config.preProcessors || [];\n this.postProcessors = config.postProcessors || [];\n this.mcpServers = config.mcpServers || [];\n this.devices = config.devices || [];\n this.deviceTriggers = config.deviceTriggers || [];\n this.voices = config.voices;\n this.batching = config.batching;\n this.governance = config.governance;\n }\n\n getName(): string {\n return this.name;\n }\n\n getPersona(): PersonaText {\n return this.persona;\n }\n\n getModel(): LuaAgentModel | undefined {\n return this.model;\n }\n\n getModelSettings(): AgentModelSettings | undefined {\n return this.modelSettings;\n }\n\n getSkills(): LuaSkill[] {\n return this.skills;\n }\n\n getWebhooks(): LuaWebhook[] {\n return this.webhooks;\n }\n\n getJobs(): LuaJob[] {\n return this.jobs;\n }\n\n getPreProcessors(): PreProcessor[] {\n return this.preProcessors;\n }\n\n getPostProcessors(): PostProcessor[] {\n return this.postProcessors;\n }\n\n getMCPServers(): LuaMCPServer[] {\n return this.mcpServers;\n }\n\n getBatching(): BatchingConfig | undefined {\n return this.batching;\n }\n\n getDevices(): LuaDevice[] {\n return this.devices;\n }\n\n getVoices(): LuaVoice[] | undefined {\n return this.voices;\n }\n}\n\n// =============================================================================\n// DEVICE\n// =============================================================================\n\n/** Configuration for a single device command (agent → device) */\nexport interface DeviceCommandConfig {\n /** Description of what this command does */\n description: string;\n /** Zod schema for command input validation */\n inputSchema?: ZodType;\n /** Retry configuration for failed commands */\n retry?: { maxAttempts: number; backoffMs: number };\n /** Timeout in milliseconds (default: 30000) */\n timeoutMs?: number;\n}\n\n/** Configuration for a single device trigger (device → agent) */\nexport interface DeviceTriggerConfig {\n /** Description of when this trigger fires */\n description: string;\n /** Zod schema for trigger payload validation */\n payloadSchema?: ZodType;\n /**\n * Handler that runs on lua-core when the device fires this trigger.\n * Has full access to agent context (can call agent.chat(), use tools, etc.)\n */\n execute?: (payload: any, context: { agent: any; device: any; trigger: any }) => Promise<any>;\n}\n\n/**\n * Configuration for defining a device that an agent can communicate with.\n *\n * @example\n * ```typescript\n * import { defineDevice } from 'lua-cli';\n * import { z } from 'zod';\n *\n * export const printer = defineDevice({\n * name: 'label-printer',\n * description: 'Thermal label printer on Raspberry Pi',\n * group: 'printers',\n * commands: {\n * print: {\n * description: 'Print a label',\n * inputSchema: z.object({ text: z.string(), copies: z.number().default(1) }),\n * retry: { maxAttempts: 3, backoffMs: 1000 },\n * timeoutMs: 30000,\n * },\n * status: {\n * description: 'Get printer status',\n * timeoutMs: 5000,\n * },\n * },\n * triggers: {\n * paper_low: {\n * description: 'Fired when paper level drops below threshold',\n * payloadSchema: z.object({ level: z.number(), threshold: z.number() }),\n * execute: async (payload, { agent }) => {\n * await agent.chat(\\`Printer paper low: \\${payload.level}%\\`);\n * },\n * },\n * },\n * });\n * ```\n */\nexport interface LuaDeviceConfig {\n /** Unique device name (lowercase, hyphens, e.g., 'label-printer') */\n name: string;\n /** Description of the device */\n description?: string;\n /** Optional group name for fan-out commands (e.g., 'printers') */\n group?: string;\n /** Commands the agent can send to the device */\n commands?: Record<string, DeviceCommandConfig>;\n /** Triggers the device can fire to the agent */\n triggers?: Record<string, DeviceTriggerConfig>;\n}\n\n/**\n * LuaDevice class — represents an external device that an agent can communicate with.\n *\n * Used in two ways:\n * - Class-based: `export default new LuaDevice({ ... })`\n * - Function-based: `export const myDevice = defineDevice({ ... })` (preferred)\n */\nexport class LuaDevice {\n readonly name: string;\n readonly description: string;\n readonly group?: string;\n readonly commands: Record<string, DeviceCommandConfig>;\n readonly triggers: Record<string, DeviceTriggerConfig>;\n\n constructor(config: LuaDeviceConfig) {\n this.name = config.name;\n this.description = config.description || '';\n this.group = config.group;\n this.commands = config.commands || {};\n this.triggers = config.triggers || {};\n }\n}\n\n// =============================================================================\n// DEVICE TRIGGER (standalone primitive)\n// =============================================================================\n\n/**\n * Configuration for a standalone device trigger primitive.\n *\n * Device triggers represent events fired from a device to an agent.\n * Unlike triggers defined inline within a `defineDevice()`, standalone\n * device triggers are first-class primitives that can be compiled,\n * versioned, and pushed independently.\n *\n * @example\n * ```typescript\n * import { defineDeviceTrigger } from 'lua-cli';\n * import { z } from 'zod';\n *\n * export const paperLow = defineDeviceTrigger({\n * name: 'paper-low',\n * description: 'Fired when printer paper drops below threshold',\n * payloadSchema: z.object({ level: z.number() }),\n * execute: async (payload, { agent, device }) => {\n * await agent.chat(`Printer ${device.name} paper low: ${payload.level}%`);\n * },\n * });\n * ```\n */\nexport interface LuaDeviceTriggerConfig {\n /** Trigger name (lowercase, hyphens, e.g., 'paper-low') */\n name: string;\n /** Description of when this trigger fires */\n description?: string;\n /** Zod schema for trigger payload validation */\n payloadSchema?: ZodType;\n /** Function that executes when the trigger fires */\n execute: (payload: any, context: { agent: any; device: { name: string } }) => Promise<any>;\n}\n\n/**\n * Lua Device Trigger class.\n *\n * Standalone device trigger primitive. Can be used with either:\n * - Class-based: `export default new LuaDeviceTrigger({ ... })`\n * - Function-based: `export const myTrigger = defineDeviceTrigger({ ... })` (preferred)\n */\nexport class LuaDeviceTrigger {\n readonly name: string;\n readonly description: string;\n readonly payloadSchema?: ZodType;\n readonly execute: (payload: any, context: { agent: any; device: { name: string } }) => Promise<any>;\n\n constructor(public config: LuaDeviceTriggerConfig) {\n this.name = config.name;\n this.description = config.description || '';\n this.payloadSchema = config.payloadSchema;\n this.execute = config.execute;\n }\n}\n","/**\n * LuaVoice — code-defined voice agents wrapping the LiveKit Agents framework.\n *\n * Data fields (llm/stt/tts/vad/turnDetection/...) validate against\n * `LuaVoiceConfigSchema` from `@lua/shared-types`. Function-bearing fields\n * (tools, onEnter, onUserTurnCompleted, onExit) live only in this TypeScript\n * surface — the compiler detects them via AST and emits presence flags in\n * the manifest; the worker reads the artifact bundle for the executable\n * implementations.\n */\n\nimport type { ZodType } from 'zod';\nimport type { LuaVoiceConfig as LuaVoiceDataConfig } from '@lua/shared-types';\nimport { ToolFlag, type LuaTool } from './skill.js';\n\n/**\n * User-facing input type for `llm` / `stt` / `tts` on a LuaVoice. Accepts:\n * - a string descriptor like `'cartesia/sonic-3:9626…'` — routed through Inference.\n * - an instance of a LiveKit Agents plugin class such as `new deepgram.STT({...})` —\n * routed through the corresponding direct plugin.\n * - a struct `{ model, voice }` — sugar for the Inference TTS form.\n *\n * The compiler ASTs the source file and normalizes whichever shape it finds\n * to the discriminated union the wire schema expects (`@lua/shared-types`).\n * The constructor below stores the raw input as-is — the runtime classes\n * never execute as part of the push pipeline.\n */\nexport type LuaVoiceModelInput = string | object;\n\n// Re-export so devs can `import { ToolFlag } from 'lua-cli'` alongside LuaVoice.\nexport { ToolFlag };\n\n/**\n * Context passed to LuaVoice lifecycle hooks at runtime.\n */\nexport interface LuaVoiceHookContext {\n sessionId: string;\n channel: { kind: string; alias?: string };\n caller?: { phoneNumber?: string; userId?: string; isAnonymous?: boolean };\n duration?: number;\n session: {\n userdata: Record<string, unknown>;\n history: unknown[];\n say(text: string): Promise<void>;\n generateReply(opts?: { instructions?: string }): unknown;\n };\n}\n\n/**\n * Per-turn context passed to onUserTurnCompleted. The canonical RAG injection\n * point — call `addMessage` to seed context, then the LLM is invoked.\n */\nexport interface LuaVoiceTurnContext {\n items: unknown[];\n addMessage(message: { role: 'system' | 'user' | 'assistant'; content: string }): void;\n}\n\n/**\n * Voice tool ctx — extends the base `LuaToolCtx` (from `skill.ts`) with\n * voice-runtime-only delegates. The base ctx is what a `LuaTool` sees as\n * its second `execute` arg whether it runs over chat or voice; this\n * extension just adds the Phase-5 fields (currently optional + experimental).\n *\n * `say()` is wired today and delegates to the active LiveKit `voice.AgentSession`.\n * `disallowInterruptions()` and `handoff()` are optional placeholders for\n * Phase 5 (BAC-213, the LuaVoice handoffs + test framework ticket).\n * Marked optional both because they aren't implemented yet AND so this\n * type stays structurally compatible with `LuaToolCtx` — that\n * compatibility is what lets a `LuaVoiceTool` (which extends `LuaTool`)\n * present `(ctx?: LuaVoiceToolCtx)` while satisfying the parent's\n * `(ctx?: LuaToolCtx)` signature.\n */\nexport interface LuaVoiceToolCtx {\n toolCallId?: string;\n voice?: {\n say(text: string): Promise<void>;\n /**\n * Transfer the live caller to a human at `msisdn`. Two mechanisms:\n *\n * - `'refer'` (default): SIP REFER on the caller's inbound leg.\n * Cheap (one billed leg) but depends on the inbound carrier\n * accepting REFER end-to-end — many European mobile carriers\n * strip it. Use when the carrier is known to support REFER.\n *\n * - `'bridge'`: dial the human as a second SIP participant into\n * the same room, keeping the caller attached. Two billed legs\n * but always works regardless of carrier REFER support. Use for\n * high-stakes transfers (sales, escalation) where reliability\n * matters more than per-minute cost.\n *\n * `announce` is spoken via `session.say(...)` before the transfer\n * fires (e.g. \"Transferring you to our sales team — one moment\").\n *\n * @example\n * ```typescript\n * await ctx.voice?.transferToHuman('+32477123456', {\n * mode: 'bridge',\n * announce: 'Transferring you to our sales team — one moment.',\n * });\n * ```\n */\n transferToHuman?(msisdn: string, opts?: { mode?: 'bridge' | 'refer'; announce?: string }): Promise<void>;\n /**\n * End the live call. When `announce` is set, the agent speaks it and\n * waits for playout before closing the session — useful for a sign-off\n * like \"Thanks for calling, goodbye.\" Without `announce`, the session\n * closes immediately (any in-flight TTS finishes via the SDK's\n * graceful `close()`).\n *\n * @example\n * ```typescript\n * await ctx.voice?.endCall({ announce: 'Thanks for calling. Goodbye.' });\n * ```\n */\n endCall?(opts?: { announce?: string }): Promise<void>;\n /**\n * @experimental Reserved for Phase 5 (BAC-213). Optional because\n * unimplemented — the actual \"lock the assistant's current\n * utterance against barge-in\" plumbing lands with the broader\n * turn-handling work.\n */\n disallowInterruptions?(): void;\n /**\n * @experimental Reserved for Phase 5 (BAC-213). Optional because\n * unimplemented — handoffs require `chatCtx.copy(exclude_instructions=True)`\n * + `update_agent` plumbing that's part of the multi-LuaVoice flow ticket.\n */\n handoff?(otherVoiceName: string, opts?: { context?: Record<string, unknown> }): unknown;\n };\n}\n\n/**\n * Voice-only tool — for tools that only make sense inside a call (handoffs,\n * hold-music toggles, transfer-to-human, etc.). Skill tools are still available\n * to voice agents; LuaVoiceTool is for the call-only ones.\n */\nexport interface LuaVoiceToolConfig<TInput extends ZodType = ZodType> {\n name: string;\n description: string;\n inputSchema: TInput;\n execute: (input: any, ctx?: LuaVoiceToolCtx) => Promise<any>;\n condition?: () => Promise<boolean>;\n flags?: ToolFlag[];\n}\n\nexport class LuaVoiceTool<TInput extends ZodType = ZodType> implements LuaTool<TInput> {\n readonly name: string;\n readonly description: string;\n readonly inputSchema: TInput;\n readonly execute: (input: any, ctx?: LuaVoiceToolCtx) => Promise<any>;\n readonly condition?: () => Promise<boolean>;\n readonly voice?: { flags?: ToolFlag[] };\n\n constructor(config: LuaVoiceToolConfig<TInput>) {\n this.name = config.name;\n this.description = config.description;\n this.inputSchema = config.inputSchema;\n this.execute = config.execute;\n this.condition = config.condition;\n if (config.flags && config.flags.length > 0) {\n this.voice = { flags: config.flags };\n }\n }\n}\n\n/**\n * Full LuaVoice config — data fields (validated by zod in shared-types)\n * plus function-bearing fields (detected by the compiler via AST).\n */\n/**\n * LuaVoice config — uses loose input types for `llm` / `stt` / `tts` so devs can\n * pass either a string descriptor or a plugin class instance. The wire schema\n * (validated server-side) is the discriminated union in `@lua/shared-types`;\n * the compiler is what bridges the two.\n */\nexport interface LuaVoiceConfig extends Omit<LuaVoiceDataConfig, 'llm' | 'stt' | 'tts'> {\n llm: LuaVoiceModelInput;\n stt: LuaVoiceModelInput;\n tts: LuaVoiceModelInput;\n /** Optional human-readable description (surfaced in manifest + admin listings). */\n description?: string;\n /** Voice-only tools, in addition to skills attached to the owning agent. */\n tools?: Array<LuaTool<any> | LuaVoiceTool<any>>;\n /**\n * Fired after the session connects to the room and before the greeting.\n * Use to hydrate `session.userdata` from `User`/`Data`, set up state, etc.\n */\n onEnter?: (ctx: LuaVoiceHookContext) => Promise<void>;\n /**\n * Fired after the user finishes a turn, before the LLM is invoked. Canonical\n * RAG injection point — `turnCtx.addMessage(...)` adds context the LLM sees.\n */\n onUserTurnCompleted?: (turnCtx: LuaVoiceTurnContext, message: { content: string }) => Promise<void>;\n /**\n * Fired when the session is closing. Use for transcript persistence or\n * outcome reporting.\n */\n onExit?: (ctx: LuaVoiceHookContext) => Promise<void>;\n}\n\n/**\n * Code-defined voice agent. Pushed via `lua push`, attached to channels through\n * the owning `LuaAgent.voice` field. Auto-dispatched into LiveKit rooms when a\n * channel bound to that agent receives a voice event.\n *\n * @example\n * ```typescript\n * import { LuaVoice } from 'lua-cli';\n *\n * export default new LuaVoice({\n * name: 'support-line',\n * llm: 'openai/gpt-5.2-chat-latest',\n * stt: 'deepgram/nova-3',\n * tts: { model: 'cartesia/sonic-3', voice: '9626c31c-bec5-4cca-baa8-f8ba9e84c8bc' },\n * vad: 'silero',\n * turnDetection: 'multilingual',\n * greeting: 'Hi, how can I help today?',\n * maxToolSteps: 3,\n * interruption: { mode: 'adaptive', falseInterruptionTimeout: 2.0 },\n *\n * onEnter: async (ctx) => {\n * if (ctx.caller?.phoneNumber) {\n * const user = await User.get({ phone: ctx.caller.phoneNumber });\n * ctx.session.userdata = { user, returning: !!user };\n * }\n * },\n *\n * onUserTurnCompleted: async (turnCtx, message) => {\n * const docs = await Data.search('kb', message.content, 3);\n * for (const doc of docs) turnCtx.addMessage({ role: 'system', content: doc.text });\n * },\n * });\n * ```\n */\nexport class LuaVoice {\n readonly name: string;\n readonly description?: string;\n readonly llm: LuaVoiceModelInput;\n readonly stt: LuaVoiceModelInput;\n readonly tts: LuaVoiceModelInput;\n readonly vad: LuaVoiceDataConfig['vad'];\n readonly vadOptions: LuaVoiceDataConfig['vadOptions'];\n readonly turnDetection: LuaVoiceDataConfig['turnDetection'];\n readonly greeting: LuaVoiceDataConfig['greeting'];\n readonly maxToolSteps: LuaVoiceDataConfig['maxToolSteps'];\n readonly userAwayTimeout: LuaVoiceDataConfig['userAwayTimeout'];\n readonly preemptiveGeneration: LuaVoiceDataConfig['preemptiveGeneration'];\n readonly interruption: LuaVoiceDataConfig['interruption'];\n readonly sttLanguage: LuaVoiceDataConfig['sttLanguage'];\n\n readonly tools: ReadonlyArray<LuaTool<any> | LuaVoiceTool<any>>;\n readonly onEnter?: LuaVoiceConfig['onEnter'];\n readonly onUserTurnCompleted?: LuaVoiceConfig['onUserTurnCompleted'];\n readonly onExit?: LuaVoiceConfig['onExit'];\n\n constructor(config: LuaVoiceConfig) {\n // No `?? 'unnamed-voice'` fallback — the server-side schema requires\n // a non-empty name (zod `min(1)`), so a missing name would explode at\n // push time anyway. Throw early here so the dev sees the failure\n // during local compile rather than as an opaque server-side\n // validation error after `lua push`.\n if (!config.name || !config.name.trim()) {\n throw new Error('LuaVoice requires a non-empty `name` (used as the server-side identifier).');\n }\n this.name = config.name;\n this.description = config.description;\n this.llm = config.llm;\n this.stt = config.stt;\n this.tts = config.tts;\n this.vad = config.vad;\n this.vadOptions = config.vadOptions;\n this.turnDetection = config.turnDetection;\n this.greeting = config.greeting;\n this.maxToolSteps = config.maxToolSteps;\n this.userAwayTimeout = config.userAwayTimeout;\n this.preemptiveGeneration = config.preemptiveGeneration;\n this.interruption = config.interruption;\n this.sttLanguage = config.sttLanguage;\n this.tools = Object.freeze([...(config.tools ?? [])]);\n this.onEnter = config.onEnter;\n this.onUserTurnCompleted = config.onUserTurnCompleted;\n this.onExit = config.onExit;\n }\n}\n\n/**\n * Function-style LuaVoice definition. Equivalent to `new LuaVoice(config)`,\n * detected by the compiler via the `defineVoice(...)` AST pattern.\n *\n * @example\n * ```typescript\n * import { defineVoice } from 'lua-cli';\n * export default defineVoice({ name: 'support-line', ... });\n * ```\n */\nexport function defineVoice(config: LuaVoiceConfig): LuaVoice {\n return new LuaVoice(config);\n}\n","/**\n * Lua Skill API Exports\n *\n * Public API surface for LuaSkill tools.\n * This module provides simplified interfaces to Lua platform APIs\n * for use within skill implementations.\n *\n * Available APIs:\n * - User: User data management\n * - Data: Custom data collections (vector search, CRUD)\n * - Products: Product catalog management\n * - Baskets: Shopping basket operations\n * - Orders: Order management\n *\n * Usage in skills:\n * ```typescript\n * import { User, Data, Products, Baskets, Orders } from 'lua-cli';\n *\n * // Get user data\n * const user = await User.get();\n *\n * // Create custom data entry\n * await Data.create('customers', { name: 'John' });\n *\n * // Search products\n * const products = await Products.search('laptop');\n * ```\n */\n\nimport {\n LuaSkill,\n LuaWebhook,\n LuaJob,\n PreProcessor,\n PostProcessor,\n LuaAgent,\n LuaMCPServer,\n LuaDevice,\n LuaDeviceTrigger,\n ToolFlag,\n env,\n} from './types/skill.js';\nimport type {\n LuaTool,\n LuaWebhookConfig,\n LuaJobConfig,\n JobSchedule,\n PreProcessorConfig,\n PreProcessorAction,\n PreProcessorResult,\n PreProcessorBlockResponse,\n PreProcessorProceedResponse,\n PostProcessorConfig,\n PostProcessorResponse,\n LuaAgentConfig,\n LuaAgentModel,\n LuaMCPServerConfig,\n MCPSSEServerConfig,\n MCPStreamableHttpServerConfig,\n MCPTransport,\n MCPServerBaseConfig,\n LuaDeviceConfig,\n DeviceCommandConfig,\n DeviceTriggerConfig,\n LuaDeviceTriggerConfig,\n} from './types/skill.js';\nimport { LuaVoice, LuaVoiceTool, defineVoice } from './types/voice.js';\nimport type {\n LuaVoiceConfig,\n LuaVoiceToolConfig,\n LuaVoiceToolCtx,\n LuaVoiceHookContext,\n LuaVoiceTurnContext,\n} from './types/voice.js';\nimport type { PersonaText } from '@lua/shared-types';\nimport { BasketStatus } from './interfaces/baskets.js';\nimport type { Basket } from './interfaces/baskets.js';\nimport { OrderStatus } from './interfaces/orders.js';\nimport type { OrderResponse } from './interfaces/orders.js';\nimport type {\n ChatHistoryMessage,\n ChatHistoryContent,\n ChatMessage,\n TextMessage,\n ImageMessage,\n FileMessage,\n PreProcessorOverride,\n PostProcessorOverride,\n} from './interfaces/chat.js';\nimport {\n getUserInstance,\n getDataInstance,\n getProductsInstance,\n getBasketsInstance,\n getOrderInstance,\n getWebhookInstance,\n getJobInstance,\n getWhatsAppTemplatesInstance,\n getCdnInstance,\n} from './api/lazy-instances.js';\nimport { JobInstance } from './instances/job.instance.js';\nimport { compressForPush } from './utils/artifact-loader.js';\nimport { BASE_URLS } from './config/constants.js';\nimport type { DeleteProductResponse, Product, ProductFilterOptions } from './interfaces/product.js';\nimport ProductInstance from './instances/product.instance.js';\nimport ProductPaginationInstance from './instances/product.pagination.instance.js';\nimport ProductSearchInstance from './instances/product.search.instance.js';\nimport DataEntryInstance from './instances/data.entry.instance.js';\nimport type {\n DeleteCustomDataResponse,\n GetCustomDataResponse,\n SearchCustomDataResponse,\n UpdateCustomDataResponse,\n} from './interfaces/custom.data.js';\nimport UserDataInstance from './instances/user.instance.js';\nimport BasketInstance from './instances/basket.instance.js';\nimport OrderInstance from './instances/order.instance.js';\nimport type {\n WhatsAppTemplate,\n PaginatedTemplatesResponse,\n ListTemplatesOptions,\n SendTemplateData,\n SendTemplateResponse,\n} from './interfaces/whatsapp-templates.js';\nimport type { UserLookupOptions, ProfileResponse } from './interfaces/user.js';\n\nexport const User = {\n /**\n * Retrieves user data by userId, email, or phone.\n *\n * @param identifier - Optional userId string or lookup options\n * @returns Promise resolving to user data, or null if not found (for email/phone lookup)\n *\n * @example\n * // Get current user (in tools with conversation context)\n * const user = await User.get();\n *\n * // Get user by userId (required in webhooks/jobs)\n * const user = await User.get('user_123');\n *\n * // Get user by email\n * const user = await User.get({ email: 'customer@example.com' });\n *\n * // Get user by phone\n * const user = await User.get({ phone: '+1234567890' });\n */\n async get(identifier?: string | UserLookupOptions): Promise<UserDataInstance | null> {\n const instance = await getUserInstance();\n return instance.get(identifier);\n },\n\n /**\n * Gets the chat history for the current user.\n *\n * @returns Promise resolving to array of chat messages\n *\n * @example\n * ```typescript\n * const history = await User.getChatHistory();\n * // Returns: [\n * // { role: 'user', content: [{type: 'text', text: 'hello'}], createdAt: '...', id: '...', threadId: '...' },\n * // { role: 'assistant', content: [{type: 'text', text: 'hi'}], createdAt: '...', id: '...', threadId: '...' }\n * // ]\n * ```\n */\n async getChatHistory(): Promise<import('./interfaces/chat.js').ChatHistoryMessage[]> {\n const instance = await getUserInstance();\n return instance.getChatHistory();\n },\n};\n\n// ============================================================================\n// CUSTOM DATA API\n// ============================================================================\n\n/**\n * Custom Data API\n * Store and retrieve custom data with vector search capabilities\n */\nexport const Data = {\n /**\n * Creates a new entry in a custom data collection.\n *\n * @param collectionName - Name of the collection\n * @param data - Data to store\n * @param searchText - Optional text for vector search indexing\n * @returns Promise resolving to created entry\n */\n async create(collectionName: string, data: Record<string, any>, searchText?: string): Promise<DataEntryInstance> {\n const instance = await getDataInstance();\n return instance.create(collectionName, data, searchText);\n },\n\n /**\n * Retrieves entries from a collection with optional filtering and pagination.\n *\n * @param collectionName - Name of the collection\n * @param filter - Optional filter criteria\n * @param page - Page number (default: 1)\n * @param limit - Items per page (default: 10)\n * @returns Promise resolving to array of entries\n */\n async get(collectionName: string, filter?: any, page?: number, limit?: number): Promise<GetCustomDataResponse> {\n const instance = await getDataInstance();\n return instance.get(collectionName, filter, page, limit);\n },\n\n /**\n * Retrieves a specific entry by ID.\n *\n * @param collectionName - Name of the collection\n * @param entryId - ID of the entry\n * @returns Promise resolving to entry data\n */\n async getEntry(collectionName: string, entryId: string): Promise<DataEntryInstance> {\n const instance = await getDataInstance();\n return instance.getEntry(collectionName, entryId);\n },\n\n /**\n * Updates an existing entry.\n *\n * @param collectionName - Name of the collection\n * @param entryId - ID of the entry to update\n * @param data - Updated data fields to merge with existing entry\n * @param searchText - Optional new search text for vector search indexing\n * @returns Promise resolving to update response\n */\n async update(\n collectionName: string,\n entryId: string,\n data: Record<string, any>,\n searchText?: string\n ): Promise<UpdateCustomDataResponse> {\n const instance = await getDataInstance();\n return instance.update(collectionName, entryId, data, searchText);\n },\n\n /**\n * Performs vector search on a collection.\n *\n * @param collectionName - Name of the collection\n * @param searchText - Text to search for\n * @param limit - Maximum results to return\n * @param scoreThreshold - Minimum similarity score (0-1)\n * @returns Promise resolving to search results\n */\n async search(\n collectionName: string,\n searchText: string,\n limit?: number,\n scoreThreshold?: number\n ): Promise<DataEntryInstance[]> {\n const instance = await getDataInstance();\n return instance.search(collectionName, searchText, limit, scoreThreshold);\n },\n\n /**\n * Deletes an entry from a collection.\n *\n * @param collectionName - Name of the collection\n * @param entryId - ID of the entry to delete\n * @returns Promise resolving when deletion is complete\n */\n async delete(collectionName: string, entryId: string): Promise<DeleteCustomDataResponse> {\n const instance = await getDataInstance();\n return instance.delete(collectionName, entryId);\n },\n};\n\n// ============================================================================\n// PRODUCTS API\n// ============================================================================\n\n/**\n * Products API\n * Manage product catalog\n */\nexport const Products = {\n /**\n * Retrieves products with pagination and optional filtering.\n * Supports both legacy (page, limit) and new (options object) signatures.\n *\n * @returns Promise resolving to product list\n *\n * @example\n * // Legacy: Get products with pagination\n * await Products.get(1, 10);\n *\n * // New: Get products with options object\n * await Products.get({ page: 2, limit: 20 });\n *\n * // New: Filter products by category\n * await Products.get({ filter: { category: \"Electronics\" } });\n *\n * // New: Filter with MongoDB operators\n * await Products.get({ filter: { price: { $lte: 100 }, inStock: true } });\n */\n async get(pageOrOptions?: number | ProductFilterOptions, limit?: number): Promise<ProductPaginationInstance> {\n const instance = await getProductsInstance();\n if (typeof pageOrOptions === 'number') {\n return instance.get(pageOrOptions, limit);\n }\n return instance.get(pageOrOptions);\n },\n\n /**\n * Creates a new product.\n *\n * @param product - Product data\n * @returns Promise resolving to created product\n */\n async create(product: Product): Promise<ProductInstance> {\n const instance = await getProductsInstance();\n return instance.create(product);\n },\n\n /**\n * Deletes a product.\n *\n * @param id - Product ID\n * @returns Promise resolving when deletion is complete\n */\n async delete(id: string): Promise<DeleteProductResponse> {\n const instance = await getProductsInstance();\n return instance.delete(id);\n },\n\n /**\n * Searches products by query string.\n *\n * @param query - Search query\n * @returns Promise resolving to search results\n */\n async search(query: string): Promise<ProductSearchInstance> {\n const instance = await getProductsInstance();\n return instance.search(query);\n },\n\n /**\n * Retrieves a specific product by ID.\n *\n * @param id - Product ID\n * @returns Promise resolving to product data\n */\n async getById(id: string): Promise<ProductInstance> {\n const instance = await getProductsInstance();\n return instance.getById(id);\n },\n};\n\n// ============================================================================\n// BASKETS API\n// ============================================================================\n\n/**\n * Baskets API\n * Manage shopping baskets\n */\nexport const Baskets = {\n /**\n * Creates a new basket.\n *\n * @param basketData - Basket initialization data\n * @returns Promise resolving to created basket\n */\n async create(basketData: any): Promise<BasketInstance> {\n const instance = await getBasketsInstance();\n return instance.create(basketData);\n },\n\n /**\n * Retrieves baskets, optionally filtered by status.\n *\n * @param status - Optional basket status filter\n * @returns Promise resolving to basket list\n */\n async get(status?: any): Promise<BasketInstance[]> {\n const instance = await getBasketsInstance();\n return instance.get(status);\n },\n\n /**\n * Adds an item to a basket.\n *\n * @param basketId - Basket ID\n * @param itemData - Item data to add\n * @returns Promise resolving to updated basket\n */\n async addItem(basketId: string, itemData: any): Promise<Basket> {\n const instance = await getBasketsInstance();\n return instance.addItem(basketId, itemData);\n },\n\n /**\n * Removes an item from a basket.\n *\n * @param basketId - Basket ID\n * @param itemId - Item ID to remove\n * @returns Promise resolving to updated basket\n */\n async removeItem(basketId: string, itemId: string): Promise<Basket> {\n const instance = await getBasketsInstance();\n return instance.removeItem(basketId, itemId);\n },\n\n /**\n * Clears all items from a basket.\n *\n * @param basketId - Basket ID\n * @returns Promise resolving to cleared basket\n */\n async clear(basketId: string): Promise<Basket> {\n const instance = await getBasketsInstance();\n return instance.clear(basketId);\n },\n\n /**\n * Updates basket status.\n *\n * @param basketId - Basket ID\n * @param status - New basket status\n * @returns Promise resolving to updated basket\n */\n async updateStatus(basketId: string, status: any): Promise<BasketStatus> {\n const instance = await getBasketsInstance();\n return instance.updateStatus(basketId, status);\n },\n\n /**\n * Updates basket metadata.\n *\n * @param basketId - Basket ID\n * @param metadata - Metadata to update\n * @returns Promise resolving to the updated metadata\n */\n async updateMetadata(basketId: string, metadata: Record<string, any>): Promise<Record<string, any>> {\n const instance = await getBasketsInstance();\n return instance.updateMetadata(basketId, metadata);\n },\n\n /**\n * Converts basket to order.\n *\n * @param data - Order data\n * @param basketId - Basket ID to convert\n * @returns Promise resolving to created order\n */\n async placeOrder(data: Record<string, any>, basketId: string): Promise<OrderInstance> {\n const instance = await getBasketsInstance();\n return instance.placeOrder(data, basketId);\n },\n\n /**\n * Retrieves a specific basket by ID.\n *\n * @param basketId - Basket ID\n * @returns Promise resolving to basket data\n */\n async getById(basketId: string): Promise<BasketInstance> {\n const instance = await getBasketsInstance();\n return instance.getById(basketId);\n },\n};\n\n// ============================================================================\n// ORDERS API\n// ============================================================================\n\n/**\n * Orders API\n * Manage orders\n */\nexport const Orders = {\n /**\n * Creates a new order.\n *\n * @param orderData - Order data\n * @returns Promise resolving to created order\n */\n async create(orderData: any): Promise<OrderInstance> {\n const instance = await getOrderInstance();\n return instance.create(orderData);\n },\n\n /**\n * Updates order status.\n *\n * @param status - New order status\n * @param orderId - Order ID\n * @returns Promise resolving to updated order\n */\n async updateStatus(status: any, orderId: string): Promise<OrderResponse> {\n const instance = await getOrderInstance();\n return instance.updateStatus(status, orderId);\n },\n\n /**\n * Updates order data.\n *\n * @param data - Data to update\n * @param orderId - Order ID\n * @returns Promise resolving to updated order\n */\n async updateData(data: Record<string, any>, orderId: string): Promise<OrderResponse> {\n const instance = await getOrderInstance();\n return instance.updateData(data, orderId);\n },\n\n /**\n * Retrieves orders, optionally filtered by status.\n *\n * @param status - Optional order status filter\n * @returns Promise resolving to order list\n */\n async get(status?: any): Promise<OrderInstance[]> {\n const instance = await getOrderInstance();\n return instance.get(status);\n },\n\n /**\n * Retrieves a specific order by ID.\n *\n * @param orderId - Order ID\n * @returns Promise resolving to order data\n */\n async getById(orderId: string): Promise<OrderInstance> {\n const instance = await getOrderInstance();\n return instance.getById(orderId);\n },\n};\n\n// ============================================================================\n// JOBS API\n// ============================================================================\n\n/**\n * Jobs API\n * Manage and trigger scheduled jobs from within your tools\n */\nexport const Jobs = {\n /**\n * Creates a new job dynamically from within a tool.\n * This allows tools to schedule one-time or recurring jobs programmatically.\n *\n * **What this does:**\n * The server handles everything in ONE API call:\n * 1. Creates the job\n * 2. Creates version 1.0.0 with your execute function\n * 3. Optionally activates the job (if activate: true)\n * 4. Returns a JobInstance for manipulation\n *\n * @param config - Job configuration\n * @param config.name - Unique job name\n * @param config.description - Job description\n * @param config.schedule - Schedule configuration (cron, once, or interval)\n * @param config.execute - Async function to execute\n * @param config.timeout - Optional timeout in seconds\n * @param config.retry - Optional retry configuration\n * @param config.metadata - Optional metadata\n * @returns Promise resolving to JobInstance (already created, versioned, and activated)\n *\n * @example\n * ```typescript\n * // Create a one-time job to check basket in 3 hours\n * const job = await Jobs.create({\n * name: `check-basket-${basketId}`,\n * description: 'Check if basket was abandoned',\n * schedule: {\n * type: 'once',\n * executeAt: new Date(Date.now() + 3 * 60 * 60 * 1000)\n * },\n * metadata: {\n * basketId: basketId,\n * checkType: 'abandoned-cart'\n * },\n * execute: async (job, user) => {\n * // Access user context and metadata\n * console.log('Checking basket for user:', user.name);\n * console.log('Basket ID from metadata:', metadata?.basketId);\n *\n * const basket = await Baskets.getById(metadata.basketId);\n * if (basket.status === 'active') {\n * // Send reminder\n * }\n * return { checked: true };\n * }\n * });\n * // Job is now created, versioned as 1.0.0, and activated!\n * console.log(`Job ${job.jobId} is active: ${job.active}`);\n * ```\n */\n async create(config: {\n name: string;\n description?: string;\n schedule: any;\n execute: (job: JobInstance) => Promise<any>;\n timeout?: number;\n retry?: { maxAttempts: number; backoffSeconds?: number };\n metadata?: Record<string, any>;\n /** Auto-activate the job after creation (default: true) */\n activate?: boolean;\n }): Promise<JobInstance> {\n const instance = await getJobInstance();\n\n // Convert the execute function to a string\n const executeString = config.execute.toString();\n\n console.log('Creating Job');\n // Create the job with initial version and activation in one call\n return await instance.createJobInstance({\n dynamic: true,\n name: config.name,\n description: config.description,\n schedule: config.schedule,\n timeout: config.timeout,\n retry: config.retry,\n metadata: config.metadata,\n // Include initial version data for automatic version creation\n version: {\n version: '1.0.0',\n description: config.description,\n code: compressForPush(executeString),\n timeout: config.timeout,\n retry: config.retry,\n metadata: config.metadata,\n },\n // Activate immediately\n activate: config.activate ?? true,\n });\n },\n /**\n * Retrieves a job by its unique identifier\n * @param jobId - The unique identifier of the job to retrieve\n * @returns Promise resolving to an JobInstance representing the job\n * @throws Error if the job is not found or the request fails\n */\n async getJob(jobId: string): Promise<JobInstance> {\n const instance = await getJobInstance();\n return instance.getJob(jobId);\n },\n\n /**\n * Retrieves all jobs for the current agent\n * @param options - Optional configuration\n * @param options.includeDynamic - Include dynamically created jobs (default: false)\n * @returns Promise resolving to an array of JobInstance\n *\n * @example\n * ```typescript\n * // Get all jobs including dynamically created ones\n * const jobs = await Jobs.getAll({ includeDynamic: true });\n * for (const job of jobs) {\n * console.log(job.name, job.data.active ? 'active' : 'inactive');\n * }\n * ```\n */\n async getAll(options: { includeDynamic?: boolean } = {}): Promise<JobInstance[]> {\n const instance = await getJobInstance();\n return instance.getAll(options);\n },\n};\n\n// ============================================================================\n// AI GENERATION API\n// ============================================================================\n\n/**\n * AI API — isolated text generation (Vercel AI SDK–aligned); proxied to the API — not the agent chat pipeline.\n * See [`generateText`](https://ai-sdk.dev/docs/reference/ai-sdk-core/generate-text).\n */\nexport interface AiApi {\n /**\n * Generate text with a user prompt and optional content. Returns plain text.\n *\n * Single-arg: `prompt` is the user prompt.\n * Two-arg: `prompt` is the system instruction, `content` is user message content\n * (AI SDK `UserContent` — a string or array of multimodal parts).\n *\n * @example\n * ```typescript\n * const text = await AI.generate('Summarize the latest AI news.');\n * const text2 = await AI.generate(\n * 'You are a helpful assistant.',\n * [{ type: 'text', text: 'Hello!' }]\n * );\n * ```\n */\n generate(prompt: string, content?: import('ai').UserContent): Promise<string>;\n\n /**\n * Generate text with full options — a serializable subset of `generateText`\n * (`model`, `system`, `prompt`, `messages`, `temperature`, `maxOutputTokens`).\n * Returns the full AI SDK–aligned result including `text`, `finishReason`, `usage`,\n * `sources` (Google Search grounding), `reasoning`, `warnings`, and more.\n *\n * @example\n * ```typescript\n * const { text, finishReason, usage, sources } = await AI.generate({\n * system: 'You are concise.',\n * prompt: 'Say hi.',\n * });\n * ```\n */\n generate(options: import('@lua/shared-types').AiGenerateInput): Promise<import('@lua/shared-types').AiGenerateOutput>;\n}\n\nexport const AI: AiApi = {\n async generate(\n promptOrOptions: string | import('@lua/shared-types').AiGenerateInput,\n content?: import('ai').UserContent\n ): Promise<any> {\n const { getAiInstance } = await import('./api/lazy-instances.js');\n const ai = await getAiInstance();\n return ai.generateForSandbox(promptOrOptions, content);\n },\n};\n\n// ============================================================================\n// AGENT INVOCATION API\n// ============================================================================\n\n/**\n * Agents API — invoke another agent from inside your skill/tool/job/webhook/\n * processor code.\n */\nexport interface AgentsApi {\n /**\n * Invoke a target agent with a plain prompt. Returns the assistant's text.\n *\n * @example\n * ```typescript\n * const summary = await Agents.invoke('salesAgent', 'summarize the last order');\n * ```\n */\n invoke(targetAgentId: string, prompt: string): Promise<string>;\n\n /**\n * Invoke a target agent with full options. Returns the structured\n * {@link AgentInvocationOutput} including `text`, `threadId`, `finishReason`,\n * `usage`, and `toolsUsed`.\n *\n * @example\n * ```typescript\n * const result = await Agents.invoke('salesAgent', {\n * prompt: 'Draft a reply to the latest order',\n * threadId: 'order-123',\n * systemPrompt: 'Be concise.',\n * });\n * console.log(result.text, result.usage);\n * ```\n */\n invoke(\n targetAgentId: string,\n input: import('@lua/shared-types').AgentInvocationInput\n ): Promise<import('@lua/shared-types').AgentInvocationOutput>;\n}\n\nexport const Agents: AgentsApi = {\n async invoke(\n targetAgentId: string,\n promptOrInput: string | import('@lua/shared-types').AgentInvocationInput\n ): Promise<any> {\n const { getAgentsInstance } = await import('./api/lazy-instances.js');\n const agents = await getAgentsInstance();\n return agents.invokeForSandbox(targetAgentId, promptOrInput);\n },\n};\n\n// ============================================================================\n// VOICE API\n// ============================================================================\n\n/**\n * Voice API — place outbound voice calls from inside a job, webhook, or\n * skill tool. The platform allocates a LiveKit room, dials the target,\n * seeds the LuaVoice with the dev's `context`, and returns a session id\n * the dev can use to read the transcript later (when the LuaVoice has\n * `persistTranscript: true`).\n */\nexport interface VoiceApi {\n /**\n * Place an outbound voice call.\n *\n * @example\n * ```typescript\n * // Recovery flow — call abandoned-cart user with order context\n * await Voice.call({\n * to: '+15551234567',\n * voice: 'support-line',\n * context: { reason: 'recovery', orderId: 'O-123' },\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Web flow — return a join URL the dev's frontend opens\n * const { joinUrl, sessionId } = await Voice.call({\n * to: { kind: 'web', returnToken: true },\n * context: { customer: 'Acme Co' },\n * });\n * ```\n */\n call(input: import('@lua/shared-types').VoiceDispatchInput): Promise<import('@lua/shared-types').VoiceDispatchOutput>;\n}\n\nexport const Voice: VoiceApi = {\n async call(\n input: import('@lua/shared-types').VoiceDispatchInput\n ): Promise<import('@lua/shared-types').VoiceDispatchOutput> {\n const { getVoiceInstance } = await import('./api/lazy-instances.js');\n const voice = await getVoiceInstance();\n return voice.dispatchForSandbox(input);\n },\n};\n\n// ============================================================================\n// TEMPLATES API\n// ============================================================================\n\n/**\n * Templates API\n *\n * Manage templates across different channel types.\n * Use the appropriate namespace for your template type:\n *\n * - `Templates.whatsapp` - WhatsApp Business templates\n *\n * @example\n * ```typescript\n * // List WhatsApp templates\n * const result = await Templates.whatsapp.list(channelId);\n *\n * // Send a WhatsApp template\n * await Templates.whatsapp.send(channelId, templateId, {\n * phoneNumbers: ['+447551166594'],\n * values: { body: { name: 'John' } }\n * });\n * ```\n */\nexport const Templates = {\n /**\n * WhatsApp Templates\n *\n * Pre-approved message formats for WhatsApp Business Accounts.\n * Required for initiating conversations outside the 24-hour messaging window.\n */\n whatsapp: {\n /**\n * Lists WhatsApp templates for a channel with optional pagination and search.\n *\n * @param channelId - The WhatsApp channel identifier\n * @param options - Optional pagination and search options\n * @returns Promise resolving to paginated templates response\n *\n * @example\n * ```typescript\n * const result = await Templates.whatsapp.list(channelId);\n * const filtered = await Templates.whatsapp.list(channelId, { search: 'order' });\n * const paginated = await Templates.whatsapp.list(channelId, { page: 2, limit: 20 });\n * ```\n */\n async list(channelId: string, options?: ListTemplatesOptions): Promise<PaginatedTemplatesResponse> {\n const instance = await getWhatsAppTemplatesInstance();\n return instance.list(channelId, options);\n },\n\n /**\n * Gets a specific WhatsApp template by ID.\n *\n * @param channelId - The WhatsApp channel identifier\n * @param templateId - The template identifier\n * @returns Promise resolving to the template\n *\n * @example\n * ```typescript\n * const template = await Templates.whatsapp.get(channelId, 'template_123');\n * ```\n */\n async get(channelId: string, templateId: string): Promise<WhatsAppTemplate> {\n const instance = await getWhatsAppTemplatesInstance();\n return instance.get(channelId, templateId);\n },\n\n /**\n * Sends a WhatsApp template message to one or more phone numbers.\n *\n * @param channelId - The WhatsApp channel identifier\n * @param templateId - The template identifier\n * @param data - Send data including phone numbers and template values\n * @returns Promise resolving to the send response with results and errors\n *\n * @example\n * ```typescript\n * const result = await Templates.whatsapp.send(channelId, 'template_123', {\n * phoneNumbers: ['+447551166594'],\n * values: {\n * body: { first_name: 'John', order_number: '12345' }\n * }\n * });\n * ```\n */\n async send(channelId: string, templateId: string, data: SendTemplateData): Promise<SendTemplateResponse> {\n const instance = await getWhatsAppTemplatesInstance();\n return instance.send(channelId, templateId, data);\n },\n },\n};\n\n// ============================================================================\n// CDN API\n// ============================================================================\n\n/**\n * CDN API\n * Upload and retrieve files from the Lua CDN\n */\nexport const CDN = {\n /**\n * Uploads a file to the CDN.\n *\n * @param file - The File object to upload\n * @returns Promise resolving to the file ID\n *\n * @example\n * ```typescript\n * import { CDN } from 'lua-cli';\n * import { readFileSync } from 'fs';\n *\n * const buffer = readFileSync('image.png');\n * const file = new File([buffer], 'image.png', { type: 'image/png' });\n * const fileId = await CDN.upload(file);\n * console.log('Uploaded file ID:', fileId);\n * ```\n */\n async upload(file: File): Promise<string> {\n const instance = await getCdnInstance();\n return instance.upload(file);\n },\n\n /**\n * Retrieves a file from the CDN by its ID.\n *\n * @param fileId - The unique identifier of the file\n * @returns Promise resolving to a File object\n *\n * @example\n * ```typescript\n * import { CDN, AI } from 'lua-cli';\n *\n * const file = await CDN.get('abc123-def456');\n * console.log(file.name, file.type, file.size);\n *\n * // Use with AI API for image analysis\n * const buffer = Buffer.from(await file.arrayBuffer());\n * const response = await AI.generate(\n * 'You are an image analysis expert.',\n * [\n * { type: 'text', text: 'What do you see in this image?' },\n * { type: 'image', image: buffer, mediaType: file.type }\n * ]\n * );\n * ```\n */\n async get(fileId: string): Promise<File> {\n const instance = await getCdnInstance();\n return instance.get(fileId);\n },\n};\n\n// ============================================================================\n// LUA RUNTIME API\n// ============================================================================\n\nimport { Channel, LuaRuntime } from './interfaces/lua.js';\n\n/**\n * Lua Runtime API\n * Access request-level runtime information in your tools, conditions, and processors.\n *\n * @example\n * ```typescript\n * import { Lua } from 'lua-cli';\n *\n * // Access the current channel\n * const channel = Lua.request.channel;\n *\n * if (channel === 'whatsapp') {\n * // WhatsApp-specific logic\n * }\n *\n * // Access raw webhook payload (for webhook-based channels)\n * if (Lua.request.webhook) {\n * const payload = Lua.request.webhook.payload;\n * }\n * ```\n */\nexport const Lua: LuaRuntime = {\n request: {\n channel: 'unknown' as Channel,\n webhook: undefined,\n },\n};\n\n// ============================================================================\n// EXPORTS\n// ============================================================================\n\n// ============================================================================\n// DEVICE DEFINITION FUNCTION\n// ============================================================================\n\n/**\n * Define a device that an agent can communicate with.\n *\n * Devices support bidirectional communication:\n * - **commands**: Agent → Device (each becomes a tool the agent can call)\n * - **triggers**: Device → Agent (each has an execute handler that runs on the server)\n *\n * @example\n * ```typescript\n * import { defineDevice } from 'lua-cli';\n * import { z } from 'zod';\n *\n * export const printer = defineDevice({\n * name: 'label-printer',\n * description: 'Thermal label printer on Raspberry Pi',\n * group: 'printers',\n * commands: {\n * print: {\n * description: 'Print a label',\n * inputSchema: z.object({ text: z.string(), copies: z.number().default(1) }),\n * timeoutMs: 30000,\n * },\n * },\n * triggers: {\n * paper_low: {\n * description: 'Fired when paper level drops below threshold',\n * payloadSchema: z.object({ level: z.number() }),\n * execute: async (payload, { agent }) => {\n * await agent.chat(\\`Printer paper low: \\${payload.level}%\\`);\n * },\n * },\n * },\n * });\n * ```\n */\nexport function defineDevice(config: LuaDeviceConfig): LuaDevice {\n return new LuaDevice(config);\n}\n\n/**\n * Define a standalone device trigger primitive.\n *\n * Device triggers represent events fired from a device to an agent.\n * Each trigger is a first-class primitive that is compiled, versioned,\n * and pushed independently.\n *\n * @example\n * ```typescript\n * import { defineDeviceTrigger } from 'lua-cli';\n * import { z } from 'zod';\n *\n * export const paperLow = defineDeviceTrigger({\n * name: 'paper-low',\n * description: 'Fired when printer paper drops below threshold',\n * payloadSchema: z.object({ level: z.number() }),\n * execute: async (payload, { agent, device }) => {\n * await agent.chat(\\`Printer \\${device.name} paper low: \\${payload.level}%\\`);\n * },\n * });\n * ```\n */\nexport function defineDeviceTrigger(config: LuaDeviceTriggerConfig): LuaDeviceTrigger {\n return new LuaDeviceTrigger(config);\n}\n\n// Export skill classes and utilities (runtime values: classes / enums / functions / consts)\nexport {\n LuaSkill,\n LuaWebhook,\n LuaJob,\n PreProcessor,\n PreProcessor as LuaPreprocessor,\n PostProcessor,\n PostProcessor as LuaPostprocessor,\n LuaAgent,\n LuaMCPServer,\n LuaDevice,\n LuaDeviceTrigger,\n LuaVoice,\n LuaVoiceTool,\n defineVoice,\n ToolFlag,\n BasketStatus,\n OrderStatus,\n env,\n};\n\n// Export skill / agent / mcp / device / voice config types\nexport type {\n LuaTool,\n LuaWebhookConfig,\n LuaJobConfig,\n JobSchedule,\n PreProcessorConfig,\n PreProcessorAction,\n PreProcessorResult,\n PreProcessorBlockResponse,\n PreProcessorProceedResponse,\n PostProcessorConfig,\n PostProcessorResponse,\n LuaAgentConfig,\n LuaAgentModel,\n LuaMCPServerConfig,\n MCPSSEServerConfig,\n MCPStreamableHttpServerConfig,\n MCPTransport,\n MCPServerBaseConfig,\n LuaDeviceConfig,\n DeviceCommandConfig,\n DeviceTriggerConfig,\n LuaDeviceTriggerConfig,\n LuaVoiceConfig,\n LuaVoiceToolConfig,\n LuaVoiceToolCtx,\n LuaVoiceHookContext,\n LuaVoiceTurnContext,\n PersonaText,\n};\n\n// Export instance classes\nexport { JobInstance, UserDataInstance, DataEntryInstance, ProductInstance, BasketInstance, OrderInstance };\n\n// Export chat interfaces\nexport type {\n ChatHistoryMessage,\n ChatHistoryContent,\n ChatMessage,\n TextMessage,\n ImageMessage,\n FileMessage,\n PreProcessorOverride,\n PostProcessorOverride,\n};\n\n// Export template interfaces\nexport type {\n WhatsAppTemplate,\n PaginatedTemplatesResponse,\n ListTemplatesOptions,\n SendTemplateData,\n SendTemplateResponse,\n WhatsAppTemplateCategory,\n WhatsAppTemplateStatus,\n WhatsAppTemplateComponent,\n SendTemplateValues,\n} from './interfaces/whatsapp-templates.js';\n\n// Export Lua runtime types\nexport type { Channel, LuaRuntime, LuaRequest, WebhookRequest } from './interfaces/lua.js';\n\n// Export user lookup types\nexport type { UserLookupOptions, ProfileResponse } from './interfaces/user.js';\n","/**\n * Order Interfaces\n * Order management and fulfillment\n */\n\nimport { BasketItem } from './baskets.js';\n\n/**\n * Order status enumeration.\n * Represents the lifecycle states of an order.\n */\nexport enum OrderStatus {\n /** Order created but not yet confirmed */\n PENDING = 'pending',\n /** Order confirmed and being processed */\n CONFIRMED = 'confirmed',\n /** Order completed and delivered */\n FULFILLED = 'fulfilled',\n /** Order cancelled */\n CANCELLED = 'cancelled',\n}\n\n/**\n * Order data container.\n * Contains the order details, items, and metadata.\n */\nexport interface OrderData {\n currency: string;\n items: BasketItem[];\n createdAt: string;\n basketId: string;\n orderDate: string;\n orderId: string;\n [key: string]: any; // Allow additional custom properties\n}\n\n/**\n * Common order properties.\n * Calculated/derived properties maintained by the system.\n */\nexport interface OrderCommon {\n status: 'pending' | 'confirmed' | 'fulfilled' | 'cancelled';\n totalAmount: string | number;\n currency: string;\n itemCount: number;\n}\n\n/**\n * Complete order entity.\n * Full order object as stored in the database.\n */\nexport interface OrderResponse {\n id: string;\n userId: string;\n agentId: string;\n orderId: string;\n data: OrderData;\n common: OrderCommon;\n createdAt: string;\n updatedAt: string;\n __v: number;\n}\n\n/**\n * Request to create a new order.\n * Typically created from a basket.\n */\nexport interface CreateOrderRequest {\n basketId: string;\n data: {\n [key: string]: any; // Allow any custom properties\n };\n}\n"],"mappings":"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","names":["BasketStatus","join","homedir","CLI_CONFIG_DIR","VERSION_CHECK_FILE","TELEMETRY_FILE","CLI_CACHE_FILE","BASE_URLS","CREDENTIALS_FILE","SANDBOX_STORAGE_FILE","AUTH_STORAGE_FILE","API","process","env","LUA_API_URL","AUTH","LUA_AUTH_URL","CHAT","WEBHOOK","CDN","AuthenticationError","Error","statusCode","isAuthenticationError","reason","serverMessage","suppressDefaultRemediation","message","name","captureStackTrace","error","randomUUID","HttpClient","baseUrl","request","url","options","controller","AbortController","timeoutId","setTimeout","abort","response","fetch","signal","headers","clearTimeout","ok","errorData","json","jsonError","status","serverMessage","message","undefined","test","AuthenticationError","isExplicitCredential","isBareAuthRejection","detail","Error","success","error","statusText","statusCode","data","isAuthenticationError","startsWith","DOMException","name","isRetryableStatus","calculateBackoff","attempt","baseMs","maxMs","exponential","Math","min","pow","max","random","retryableRequest","maxRetries","method","lastResult","result","backoff","Promise","resolve","httpGet","httpPost","body","JSON","stringify","httpPut","httpDelete","httpPatch","readFileSync","writeFileSync","mkdirSync","unlinkSync","getToken","process","env","LUA_API_KEY","token","CREDENTIALS_FILE","trim","AuthenticationError","undefined","COMPILE_DIRS","COMPILE_FILES","SKILL_DEFAULTS","YAML_FORMAT","DIST","DIST_V2","LUA","TOOLS","DEPLOYMENT_JSON","DEPLOY_JSON","MANIFEST_JSON","INDEX_TS","INDEX_JS","PACKAGE_JSON","TSCONFIG_JSON","LUA_SKILL_YAML","NAME","VERSION","DESCRIPTION","CONTEXT","INDENT","LINE_WIDTH","NO_REFS","__name","__defProp","PrimitiveKind","SkillApi","HttpClient","apiKey","agentId","baseUrl","getSkills","httpGet","Authorization","createSkill","skillData","httpPost","pushSkill","skillId","versionData","pushDevSkill","updateDevSkill","sandboxVersionId","httpPut","getSkillVersions","publishSkillVersion","version","undefined","deleteSkill","httpDelete","attachSkillSource","body","encodeURIComponent","fs","path","zlib","loadArtifact","primitive","projectPath","process","cwd","artifactPath","join","COMPILE_DIRS","DIST_V2","existsSync","Error","readFileSync","compressForPush","code","compressed","gzipSync","Buffer","from","toString","compressForPushRaw","loadOriginalSource","sourcePath","abs","isAbsolute","size","statSync","MAX_SOURCE_FILE_BYTES","normalizeEntryFile","rel","relative","startsWith","includes","sep","split","buildSourceArchive","files","length","map","entryFile","source","Object","keys","json","JSON","stringify","gz","findPrimitive","manifest","name","kind","primitives","find","p","SOURCE_ARCHIVE_SCHEMA_VERSION","crypto","hashBundle","rawGzip","createHash","update","digest","parseVersion","version","versionPart","preReleasePart","split","major","minor","patch","map","Number","preRelease","isNaN","compareVersions","version1","version2","v1","v2","preReleaseOrder","getPreReleaseType","type","toLowerCase","replace","index","indexOf","length","type1","type2","getPreReleaseNum","parts","num","parseInt","num1","num2","localeCompare","maxSemver","a","b","DEFAULT_VERSION","BaseVersionedHandler","SKILL_DEFAULTS","VERSION","cleanItem","item","name","version","yamlConfig","idField","getItemId","isActive","_serverItem","getActiveVersion","serverItem","active","versions","find","v","getServerItemName","shouldConsiderForOrphan","_item","fetchMergedForInteraction","apiKey","agentId","config","serverData","fetchServerState","localItems","getFromYaml","serverItems","merged","orphanIds","Set","serverFailed","filter","s","some","l","id","map","local","api","getApi","fetchFromServer","error","AuthenticationError","isAuthenticationError","fetchError","Error","message","String","applySyncToYaml","manifest","apiCredentials","messages","yamlUpdated","orphanedCount","console","displayNamePlural","warn","yamlItems","yamlById","yamlByName","serverByName","buildMaps","orphans","has","length","stubs","push","flagName","displayName","toLowerCase","replace","log","msg","deleteCommand","items","updatedItems","changed","msgs","syncFromServer","updateYaml","created","updated","creationUpdated","createMissingOnServer","syncWithServer","readYamlConfig","itemsWithoutId","manifestPrimitive","findPrimitive","kind","newId","createOnServer","updatedConfig","idx","findIndex","i","yamlKey","writeYamlConfig","Array","isArray","syncYamlWithManifest","manifestNames","primitives","p","existing","kept","includes","updateVersionInYaml","newVersion","options","silent","prepareForPush","projectPath","process","cwd","bundleAccumulator","primitive","code","loadArtifact","rawGzip","compressForPushRaw","codeS3Hash","hashBundle","set","buildPushData","undefined","compressedCode","compressForPush","description","getHighestServerVersion","entityId","entity","reduce","highest","maxSemver","batchGetHighestVersions","entityIds","result","Map","forEach","h","get","activeVersion","currentVersion","SkillHandler","skillHandler","BaseVersionedHandler","kind","PrimitiveKind","SKILL","displayName","displayNamePlural","deleteCommand","yamlConfig","yamlKey","idField","getApi","apiKey","agentId","SkillApi","BASE_URLS","API","fetchFromServer","api","response","getSkills","success","data","skills","createOnServer","primitive","skill","createSkill","name","description","hasPersonaTextContent","context","id","isActive","serverItem","active","getActiveVersion","versions","find","v","version","shouldConsiderForOrphan","source","getFromYaml","config","Array","isArray","length","map","skillId","legacy","updateVersionInYaml","newVersion","options","readYamlConfig","silent","Error","updated","s","writeYamlConfig","error","console","warn","syncYamlWithManifest","manifest","primitives","some","p","log","pushToServer","entityId","pushData","pushSkill","message","publishVersion","publishSkillVersion","prepareForPush","projectPath","process","cwd","bundleAccumulator","findPrimitive","archiveEntries","tools","toolName","tool","TOOL","code","loadArtifact","toolData","rawGzip","compressForPushRaw","codeS3Hash","hashBundle","set","inputSchema","schemas","input","undefined","hasCondition","condition","compressedCode","compressForPush","loadOriginalSource","sourcePath","entryFile","normalizeEntryFile","push","filter","Boolean","sourceArchive","buildSourceArchive","archiveSchemaVersion","SOURCE_ARCHIVE_SCHEMA_VERSION","fs","path","pkg","readYamlConfig","yamlPath","join","process","cwd","COMPILE_FILES","LUA_SKILL_YAML","existsSync","yamlContent","readFileSync","load","writeYamlConfig","config","filePath","options","sortKeys","yamlKeySorter","dump","indent","YAML_FORMAT","INDENT","lineWidth","LINE_WIDTH","noRefs","NO_REFS","replacer","key","value","undefined","writeFileSync","a","b","aIndex","YAML_KEY_ORDER","indexOf","bIndex","localeCompare","CHECK_INTERVAL_MS","PostHog","requireAuth","getToken","getCredentials","cachedCredentials","apiKey","requireAuth","config","readYamlConfig","agent","agentId","Error","ProductInstance","data","productAPI","api","product","Object","defineProperty","value","writable","enumerable","configurable","Proxy","get","target","prop","receiver","Reflect","undefined","set","reservedProps","includes","has","ownKeys","instanceKeys","dataKeys","keys","Set","getOwnPropertyDescriptor","instanceDesc","toJSON","Symbol","for","update","response","id","updated","Error","delete","deleted","save","error","ProductPaginationInstance","products","pagination","productAPI","api","results","productsData","data","Array","isArray","map","product","ProductInstance","currentPage","totalPages","totalCount","limit","hasNextPage","hasPrevPage","nextPage","prevPage","Object","defineProperty","value","writable","enumerable","configurable","length","callback","filter","forEach","find","findIndex","some","every","reduce","initialValue","Symbol","iterator","toJSON","for","Error","get","ProductSearchInstance","products","productAPI","api","results","productsData","data","Array","isArray","map","product","ProductInstance","Object","defineProperty","value","writable","enumerable","configurable","length","callback","filter","forEach","find","findIndex","some","every","reduce","initialValue","Symbol","iterator","toJSON","for","ProductApi","HttpClient","apiKey","agentId","baseUrl","get","pageOrOptions","limitArg","page","limit","filter","queryParams","URLSearchParams","append","toString","JSON","stringify","response","httpGet","Authorization","success","ProductPaginationInstance","Error","error","message","getById","productId","data","ProductInstance","create","productData","httpPost","product","update","httpPut","id","delete","httpDelete","search","searchQuery","encodeURIComponent","ProductSearchInstance","BasketInstance","id","userId","agentId","data","common","metadata","totalAmount","itemCount","status","basketAPI","api","basket","BasketStatus","ACTIVE","Object","defineProperty","value","writable","enumerable","configurable","Proxy","get","target","prop","receiver","Reflect","undefined","set","reservedProps","includes","has","ownKeys","instanceKeys","dataKeys","keys","commonKeys","Set","getOwnPropertyDescriptor","instanceDesc","toJSON","Symbol","for","updateMetadata","updateStatus","updateBasket","addItem","item","removeItem","itemId","clear","placeOrder","order","CHECKED_OUT","OrderInstance","data","common","id","userId","agentId","orderId","orderAPI","api","order","Object","defineProperty","value","writable","enumerable","configurable","Proxy","get","target","prop","receiver","Reflect","undefined","set","reservedProps","includes","has","ownKeys","instanceKeys","dataKeys","keys","commonKeys","Set","getOwnPropertyDescriptor","instanceDesc","toJSON","Symbol","for","updateStatus","status","response","update","updateData","save","error","Error","OrderApi","HttpClient","apiKey","agentId","baseUrl","create","orderData","response","httpPost","Authorization","success","data","OrderInstance","Error","error","message","updateStatus","status","orderId","httpPut","updateData","get","statusParam","httpGet","map","order","getById","BasketApi","HttpClient","apiKey","agentId","baseUrl","create","basketData","response","httpPost","Authorization","success","data","BasketInstance","Error","error","message","get","status","statusParam","httpGet","map","basket","getById","basketId","addItem","itemData","removeItem","itemId","httpDelete","clear","updateStatus","httpPut","undefined","updateMetadata","metadata","placeOrder","orderApi","OrderApi","OrderInstance","UserDataInstance","data","userAPI","_luaProfile","api","profile","Object","defineProperty","value","writable","enumerable","configurable","get","userId","fullName","mobileNumbers","emailAddresses","set","_","Proxy","target","prop","receiver","Reflect","undefined","reservedProps","includes","has","ownKeys","instanceKeys","dataKeys","keys","Set","getOwnPropertyDescriptor","instanceDesc","toJSON","Symbol","for","update","response","error","Error","clear","save","send","messages","sendMessage","getChatHistory","UserDataApi","HttpClient","apiKey","agentId","baseUrl","get","identifier","userId","profile","resolveUserProfile","id","url","response","httpGet","Authorization","success","Error","error","message","data","_luaProfile","UserDataInstance","options","developerApi","getDeveloperInstance","email","getUserProfileByEmail","phone","getUserProfileByPhone","includes","update","httpPut","cleanData","clear","httpDelete","sendMessage","messages","user","getAdminUser","httpPost","uid","getChatHistory","DataEntryInstance","data","id","collectionName","score","customDataAPI","api","entry","Object","defineProperty","value","writable","enumerable","configurable","Proxy","get","target","prop","receiver","Reflect","undefined","set","reservedProps","includes","has","ownKeys","instanceKeys","dataKeys","keys","Set","getOwnPropertyDescriptor","instanceDesc","toJSON","Symbol","for","update","searchText","error","Error","delete","save","CustomDataApi","HttpClient","apiKey","agentId","baseUrl","create","collectionName","data","searchText","response","httpPost","Authorization","success","DataEntryInstance","Error","error","message","get","filter","page","limit","url","encodedFilter","encodeURIComponent","JSON","stringify","httpGet","getEntry","entryId","update","httpPut","search","scoreThreshold","map","entry","delete","httpDelete","WebhookApi","HttpClient","apiKey","agentId","baseUrl","getWebhooks","httpGet","Authorization","createWebhook","webhookData","httpPost","updateWebhook","webhookId","data","httpPatch","pushWebhook","versionData","pushDevWebhook","updateDevWebhook","sandboxVersionId","httpPut","getWebhookVersions","publishWebhookVersion","version","activateWebhook","deactivateWebhook","deleteWebhook","httpDelete","JobInstance","jobApi","_data","id","name","activeVersion","metadata","userApi","jobData","userId","agentId","UserDataApi","BASE_URLS","API","apiKey","data","updateMetadata","result","success","Error","error","message","delete","deleteJob","user","get","trigger","versionId","triggerJob","activate","activateJob","deactivate","deactivateJob","toJSON","JobApi","HttpClient","apiKey","agentId","baseUrl","getJobs","options","queryParams","URLSearchParams","includeDynamic","append","url","toString","httpGet","Authorization","getAll","response","success","data","jobs","map","job","JobInstance","Error","error","message","getJob","jobId","createJob","jobData","httpPost","createJobInstance","pushJob","versionData","pushDevJob","updateDevJob","sandboxVersionId","httpPut","getJobVersions","publishJobVersion","version","deleteJob","httpDelete","activateJob","deactivateJob","triggerJob","versionId","body","getJobExecutions","limit","updateMetadata","metadata","AiApiService","HttpClient","baseUrl","apiKey","agentId","generate","body","httpPost","Authorization","generateForSandbox","promptOrOptions","content","result","aiGenerateInputFromSimplified","success","Error","error","message","data","text","AgentsApiService","HttpClient","baseUrl","apiKey","invoke","targetAgentId","body","channel","query","URLSearchParams","identifier","set","chatBody","toChatGenerateBody","httpPost","toString","Authorization","invokeForSandbox","promptOrInput","input","prompt","result","success","Error","error","message","data","text","messages","type","navigate","systemPrompt","undefined","runtimeContext","threadId","WhatsAppTemplatesApiService","HttpClient","apiKey","agentId","baseUrl","list","channelId","options","page","limit","search","url","encodeURIComponent","response","httpGet","Authorization","success","data","Error","error","message","get","templateId","send","body","phone_numbers","phoneNumbers","values","httpPost","CdnApi","baseUrl","apiKey","upload","file","formData","FormData","append","name","response","fetch","method","headers","Authorization","body","ok","error","json","catch","Error","message","status","data","fileId","get","contentType","contentDisposition","filenameMatch","match","filename","blob","File","type","DeveloperApi","HttpClient","apiKey","agentId","baseUrl","getEnvironmentVariables","httpGet","Authorization","updateEnvironmentVariables","envData","httpPost","deleteEnvironmentVariable","key","httpDelete","getMCPServers","getActiveMCPServers","getMCPServer","mcpServerId","createMCPServer","mcpServerData","updateMCPServer","httpPut","deleteMCPServer","activateMCPServer","deactivateMCPServer","upsertMCPServer","getUserProfileByEmail","email","encodeURIComponent","getUserProfileByPhone","phone","normalizedPhone","replace","VoiceApi","HttpClient","apiKey","agentId","baseUrl","getVoices","httpGet","Authorization","createVoice","voiceData","httpPost","pushVoice","voiceId","versionData","getVoiceVersions","publishVoiceVersion","version","httpPut","undefined","deleteVoice","httpDelete","dispatch","input","dispatchForSandbox","result","success","Error","error","message","data","DeviceApi","HttpClient","apiKey","agentId","baseUrl","getDevices","httpGet","Authorization","createDevice","deviceData","httpPost","pushDevice","deviceId","versionData","pushDevDevice","getDeviceVersions","publishDeviceVersion","version","deleteDevice","httpDelete","sendCommand","deviceName","command","payload","timeout","getDeviceStatus","enableDevice","httpPatch","disableDevice","getUserInstance","_userInstance","creds","getCredentials","UserDataApiService","BASE_URLS","API","apiKey","agentId","getDataInstance","_dataInstance","CustomDataApiService","getProductsInstance","_productsInstance","ProductApiService","getBasketsInstance","_basketsInstance","BasketApiService","getOrderInstance","_orderInstance","OrderApiService","getWebhookInstance","_webhookInstance","WebhookApi","getJobInstance","_jobInstance","JobApi","getAiInstance","_aiInstance","AiApiService","getAgentsInstance","_agentsInstance","AgentsApiService","getWhatsAppTemplatesInstance","_whatsAppTemplatesInstance","WhatsAppTemplatesApiService","getCdnInstance","_cdnInstance","CdnApi","CDN","getDeviceInstance","_deviceInstance","default","DeviceApi","getDeveloperInstance","_developerInstance","DeveloperApi","getVoiceInstance","_voiceInstance","VoiceApi","clearAllInstances","validateToolName","name","validNameRegex","test","assertValidToolName","Error","env","key","process","undefined","ToolFlag","LuaSkill","tools","name","description","context","config","trim","Error","base","voice","text","addTools","getContext","addTool","tool","assertValidToolName","push","run","input","find","validatedInput","inputSchema","parse","execute","LuaJob","schedule","timeout","retry","metadata","executeFunction","getName","getDescription","getSchedule","getTimeout","getRetry","getMetadata","job","LuaWebhook","querySchema","headerSchema","bodySchema","query","headers","body","validatedQuery","validatedHeaders","validatedBody","error","event","timestamp","Date","toISOString","PreProcessor","asyncMode","priority","async","getAsync","getPriority","user","messages","channel","PostProcessor","message","response","LuaMCPServer","transport","url","getTransport","getConfig","toJSON","validateModelSettings","settings","finiteNumberKeys","value","Number","isFinite","temperature","topP","maxOutputTokens","stopSequences","Array","isArray","every","v","LuaAgent","persona","model","modelSettings","skills","webhooks","jobs","preProcessors","postProcessors","mcpServers","devices","deviceTriggers","voices","batching","governance","getPersona","getModel","getModelSettings","getSkills","getWebhooks","getJobs","getPreProcessors","getPostProcessors","getMCPServers","getBatching","getDevices","getVoices","LuaDevice","group","commands","triggers","LuaDeviceTrigger","payloadSchema","LuaVoiceTool","name","description","inputSchema","execute","condition","voice","config","flags","length","LuaVoice","llm","stt","tts","vad","vadOptions","turnDetection","greeting","maxToolSteps","userAwayTimeout","preemptiveGeneration","interruption","sttLanguage","tools","onEnter","onUserTurnCompleted","onExit","trim","Error","Object","freeze","defineVoice","OrderStatus","User","get","identifier","instance","getUserInstance","getChatHistory","Data","create","collectionName","data","searchText","getDataInstance","filter","page","limit","getEntry","entryId","update","search","scoreThreshold","delete","Products","pageOrOptions","getProductsInstance","product","id","query","getById","Baskets","basketData","getBasketsInstance","status","addItem","basketId","itemData","removeItem","itemId","clear","updateStatus","updateMetadata","metadata","placeOrder","Orders","orderData","getOrderInstance","orderId","updateData","Jobs","config","getJobInstance","executeString","execute","toString","console","log","createJobInstance","dynamic","name","description","schedule","timeout","retry","version","code","compressForPush","activate","getJob","jobId","getAll","options","AI","generate","promptOrOptions","content","getAiInstance","ai","generateForSandbox","Agents","invoke","targetAgentId","promptOrInput","getAgentsInstance","agents","invokeForSandbox","Voice","call","input","getVoiceInstance","voice","dispatchForSandbox","Templates","whatsapp","list","channelId","getWhatsAppTemplatesInstance","templateId","send","CDN","upload","file","getCdnInstance","fileId","Lua","request","channel","webhook","undefined","defineDevice","LuaDevice","defineDeviceTrigger","LuaDeviceTrigger"]}
|
|
1
|
+
{"version":3,"sources":["../src/interfaces/baskets.ts","../src/config/constants.ts","../src/errors/auth.error.ts","../src/api/http.client.ts","../src/api/auth.api.service.ts","../src/services/auth.ts","../src/config/compile.constants.ts","../../shared-types/dist/index.mjs","../src/compiler/types.ts","../src/api/skills.api.service.ts","../src/utils/artifact-loader.ts","../src/api/backup.api.service.ts","../src/utils/bundle-upload.ts","../src/utils/semver.ts","../src/primitives/base.handler.ts","../src/primitives/skill.handler.ts","../src/utils/files.ts","../src/utils/version-check.ts","../src/utils/package-root.ts","../src/services/analytics.ts","../src/utils/write-info.ts","../src/utils/hints.ts","../src/utils/cli.ts","../src/utils/command-utils.ts","../src/api/credentials.ts","../src/instances/product.instance.ts","../src/instances/product.pagination.instance.ts","../src/instances/product.search.instance.ts","../src/api/products.api.service.ts","../src/instances/basket.instance.ts","../src/instances/order.instance.ts","../src/api/order.api.service.ts","../src/api/basket.api.service.ts","../src/instances/user.instance.ts","../src/api/user.data.api.service.ts","../src/instances/data.entry.instance.ts","../src/api/custom.data.api.service.ts","../src/api/webhook.api.service.ts","../src/instances/job.instance.ts","../src/api/job.api.service.ts","../src/api/ai.api.service.ts","../src/api/agents.api.service.ts","../src/api/whatsapp-templates.api.service.ts","../src/api/cdn.api.service.ts","../src/api/developer.api.service.ts","../src/api/voice.api.service.ts","../src/api/device.api.service.ts","../src/api/lazy-instances.ts","../src/types/tool-validation.ts","../src/types/skill.ts","../src/types/voice.ts","../src/api-exports.ts","../src/interfaces/orders.ts"],"sourcesContent":["/**\n * Basket Interfaces\n * Shopping basket management and operations\n */\n\n/**\n * Basket status enumeration.\n * Represents the lifecycle states of a shopping basket.\n */\nexport enum BasketStatus {\n /** Basket is active and can be modified */\n ACTIVE = 'active',\n /** Basket has been checked out (converted to order) */\n CHECKED_OUT = 'checked_out',\n /** Basket was abandoned by the user */\n ABANDONED = 'abandoned',\n /** Basket has expired (TTL exceeded) */\n EXPIRED = 'expired',\n}\n\n/**\n * Item in a basket.\n * Represents a single product or service in the basket.\n */\nexport interface BasketItem {\n id: string;\n price: number;\n quantity: number;\n SKU?: string;\n addedAt?: string;\n [key: string]: any; // Allow additional properties (e.g., color, size)\n}\n\n/**\n * Basket data container.\n * Contains the actual basket contents and metadata.\n */\nexport interface BasketData {\n currency: string;\n metadata?: any;\n items: BasketItem[];\n createdAt: string;\n}\n\n/**\n * Common basket properties.\n * Calculated/derived properties maintained by the system.\n */\nexport interface BasketCommon {\n status: BasketStatus;\n totalAmount: string | number;\n itemCount: number;\n}\n\n/**\n * Complete basket entity.\n * Full basket object as stored in the database.\n */\nexport interface Basket {\n id: string;\n userId: string;\n agentId: string;\n data: BasketData;\n common: BasketCommon;\n createdAt: string;\n updatedAt: string;\n __v: number;\n}\n\n/**\n * Request to create a new basket.\n */\nexport interface CreateBasketRequest {\n currency: string;\n metadata?: any;\n}\n\n/**\n * Request to add an item to a basket.\n */\nexport interface AddItemToBasketRequest {\n id: string;\n price: number;\n quantity: number;\n [key: string]: any; // Allow additional properties\n}\n","/**\n * Global constants for the CLI\n */\n\nimport { join } from 'path';\nimport { homedir } from 'os';\n\n// =============================================================================\n// PATHS\n// =============================================================================\n\n/**\n * CLI config directory (~/.lua-cli)\n */\nexport const CLI_CONFIG_DIR = join(homedir(), '.lua-cli');\n\n/**\n * Version check cache file\n */\nexport const VERSION_CHECK_FILE = join(CLI_CONFIG_DIR, 'version-check.json');\n\n/**\n * Telemetry config file\n */\nexport const TELEMETRY_FILE = join(CLI_CONFIG_DIR, 'telemetry.json');\n\n/**\n * Versioning-mode (and future TTL) cache file (~/.lua-cli/cache.json).\n * All per-user CLI caches live here alongside version-check.json,\n * telemetry.json, and credentials.\n */\nexport const CLI_CACHE_FILE = join(CLI_CONFIG_DIR, 'cache.json');\n\n// =============================================================================\n// API URLS\n// =============================================================================\n\n/**\n * Base URLs for the API, Auth, and Chat\n */\nexport const BASE_URLS = {\n API: process.env.LUA_API_URL || 'https://api.heylua.ai',\n AUTH: process.env.LUA_AUTH_URL || 'https://auth.heylua.ai',\n CHAT: process.env.LUA_API_URL || 'https://api.heylua.ai',\n WEBHOOK: 'https://webhook.heylua.ai',\n CDN: 'https://cdn.heylua.ai',\n};\n\n// =============================================================================\n// AUTH CONSTANTS\n// =============================================================================\n\n/**\n * Credentials file path for storing the API key (~/.lua-cli/credentials).\n * Written by `lua auth configure`, read by getToken().\n * Owner-only permissions (0600) are applied on write.\n */\nexport const CREDENTIALS_FILE = join(CLI_CONFIG_DIR, 'credentials');\n\n// =============================================================================\n// INIT CONSTANTS\n// =============================================================================\n\n/**\n * Agent type names to search for (in order of preference)\n */\nexport const PREFERRED_AGENT_TYPES = ['Base Agent', 'baseAgent', 'base'] as const;\n\n// =============================================================================\n// SANDBOX STORAGE CONSTANTS\n// =============================================================================\n\n/**\n * Sandbox ID storage file path (~/.lua-cli/sandbox.json).\n * Stores transient sandbox skill/preprocessor/postprocessor IDs for local dev.\n */\nexport const SANDBOX_STORAGE_FILE = join(CLI_CONFIG_DIR, 'sandbox.json');\n\n/**\n * Git remote auth storage file path (~/.lua-cli/auth.json). Stores per-provider\n * tokens and metadata for `lua git auth <provider>`.\n */\nexport const AUTH_STORAGE_FILE = join(CLI_CONFIG_DIR, 'auth.json');\n\n// =============================================================================\n// ANALYTICS CONSTANTS\n// =============================================================================\n\n/**\n * PostHog project API key (public, safe to embed — like a client-side key)\n */\nexport const POSTHOG_API_KEY = 'phc_W7Qsquwlflshmdkm2hWSqRpXuxGbVFo7LEX8H9HrSjC';\n\n/**\n * PostHog ingestion host\n */\nexport const POSTHOG_HOST = 'https://us.i.posthog.com';\n","/**\n * Authentication Error\n * Thrown when API requests fail with 401 Unauthorized status\n */\n\n/**\n * Why a 401 happened. The CLI prints different guidance for each:\n * - `invalid_credentials`: API key is missing/invalid/expired → suggest `lua auth configure`.\n * - `no_agent_access`: API key is fine, but the user does not have access to the\n * agentId in the request → suggest checking `lua.skill.yaml`'s `agent.agentId`.\n * - `unknown`: 401 with no parseable body (treat conservatively as credentials).\n */\nexport type AuthErrorReason = 'invalid_credentials' | 'no_agent_access' | 'unknown';\n\nexport class AuthenticationError extends Error {\n public readonly statusCode: number = 401;\n public readonly isAuthenticationError: boolean = true;\n public readonly reason: AuthErrorReason;\n public readonly serverMessage?: string;\n /**\n * If true, the error message already contains complete remediation steps\n * and `withErrorHandling` should not append its own hint block. Use this\n * when the throw site has more context about the right fix than the\n * generic per-reason hints (e.g. `getToken()` listing all three ways to\n * configure a key — keychain, env var, .env file).\n */\n public readonly suppressDefaultRemediation: boolean;\n\n constructor(\n message: string = 'Invalid API key',\n reason: AuthErrorReason = 'unknown',\n serverMessage?: string,\n suppressDefaultRemediation: boolean = false\n ) {\n super(message);\n this.name = 'AuthenticationError';\n this.reason = reason;\n this.serverMessage = serverMessage;\n this.suppressDefaultRemediation = suppressDefaultRemediation;\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, AuthenticationError);\n }\n }\n\n /**\n * Checks if an error is an AuthenticationError\n * @param error - The error to check\n * @returns True if the error is an AuthenticationError\n */\n static isAuthenticationError(error: unknown): error is AuthenticationError {\n return (\n error instanceof AuthenticationError ||\n (error instanceof Error && 'isAuthenticationError' in error && (error as any).isAuthenticationError === true)\n );\n }\n}\n","import { randomUUID } from 'crypto';\nimport { ApiResponse } from '../interfaces/common.js';\nimport { AuthenticationError } from '../errors/auth.error.js';\n\n/**\n * Generic HTTP client with common error handling\n * Provides a base class for all API service classes with standardized HTTP methods\n */\nexport abstract class HttpClient {\n /**\n * Creates an instance of HttpClient\n * @param baseUrl - The base URL for all API requests\n */\n constructor(protected baseUrl: string) {}\n\n /**\n * Makes an HTTP request with standardized error handling\n * @param url - The full URL to request\n * @param options - Fetch API request options\n * @returns Promise resolving to an ApiResponse with typed data\n * @private\n */\n private async request<T>(url: string, options: RequestInit = {}): Promise<ApiResponse<T>> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 30000);\n try {\n const response = await fetch(url, {\n ...options,\n signal: controller.signal,\n headers: {\n 'Content-Type': 'application/json',\n ...options.headers,\n },\n });\n\n clearTimeout(timeoutId);\n\n // Check if response is ok (status 200-299)\n if (!response.ok) {\n // Try to parse error body as JSON. We need the body for 401s too so\n // we can distinguish \"API key is bad\" from \"API key is fine but the\n // user doesn't own this agent\" — which produce identical 401 status\n // codes but very different remedies (BAC-202).\n let errorData: Record<string, any>;\n try {\n errorData = (await response.json()) as Record<string, any>;\n } catch (jsonError) {\n errorData = {};\n }\n\n if (response.status === 401) {\n const serverMessage = typeof errorData.message === 'string' ? errorData.message : undefined;\n // Detect ownership rejections from lua-api's AdminService. The\n // function throws several variants — `User is not an admin`,\n // `…not an admin of the agent`, `…of the organization` — so match\n // the common stem rather than the longer suffixes.\n if (serverMessage && /not an admin/i.test(serverMessage)) {\n throw new AuthenticationError(\n `Access denied for this agent: ${serverMessage}`,\n 'no_agent_access',\n serverMessage\n );\n }\n // Standard credential failures: bare NestJS `UnauthorizedException()`\n // (body becomes `{ message: 'Unauthorized' }`), empty/non-JSON\n // bodies, and explicit \"invalid/expired/missing token/key\" messages\n // from auth.middleware. Use the canonical \"your API key may be\n // invalid or expired\" message in all of these cases — it's more\n // actionable than echoing \"Unauthorized\" back to the user, and\n // matches the wrapper's `lua auth configure` hint.\n const isExplicitCredential =\n !!serverMessage && /(invalid|expired|missing|no)\\s+(api[\\s_-]?key|token|credential)/i.test(serverMessage);\n const isBareAuthRejection = !serverMessage || /^unauthorized$/i.test(serverMessage);\n if (isExplicitCredential || isBareAuthRejection) {\n throw new AuthenticationError(\n 'Authentication failed. Your API key may be invalid or expired.',\n 'invalid_credentials',\n serverMessage\n );\n }\n // Anything else — e.g. account suspended, billing lapsed, future\n // 401 variants — surface the server message as-is and classify as\n // 'unknown' so we don't misdirect users to `lua auth configure`\n // for a problem that isn't their credentials.\n throw new AuthenticationError(`Authentication failed: ${serverMessage}`, 'unknown', serverMessage);\n }\n\n if (response.status === 403) {\n const detail = errorData.message || 'You do not have permission to access this resource.';\n throw new Error(\n `Access denied (403): ${detail}\\nCheck that your API key has access to this agent/organization.`\n );\n }\n\n return {\n success: false,\n error: {\n message: errorData.message || `HTTP ${response.status}: ${response.statusText}`,\n statusCode: response.status,\n error: errorData.error,\n ...errorData,\n },\n };\n }\n\n // Try to parse JSON response\n let data: any;\n try {\n data = await response.json();\n } catch (jsonError) {\n data = {};\n }\n\n // If the response already has the ApiResponse structure, return it\n if (typeof data === 'object' && data !== null && 'success' in data) {\n return data;\n }\n\n // Otherwise, wrap the data in a successful ApiResponse\n return {\n success: true,\n data,\n };\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (AuthenticationError.isAuthenticationError(error)) {\n throw error;\n }\n\n // 403 errors are thrown as regular Errors — re-throw them (not retryable)\n if (error instanceof Error && error.message.startsWith('Access denied (403)')) {\n throw error;\n }\n\n // AbortError from timeout — treat as network error (retryable)\n if (error instanceof DOMException && error.name === 'AbortError') {\n return {\n success: false,\n error: {\n message: 'Request timeout (30s)',\n statusCode: 0,\n },\n };\n }\n\n // Handle network errors, timeouts, etc.\n return {\n success: false,\n error: {\n message: error instanceof Error ? error.message : 'Network request failed',\n statusCode: 0, // Use 0 to indicate network/connection error\n },\n };\n }\n }\n\n /**\n * Checks if an HTTP status code is retryable\n * @param statusCode - The HTTP status code (0 for network errors)\n * @returns True if the request should be retried\n * @private\n */\n private isRetryableStatus(statusCode: number): boolean {\n // Retry: network errors (0), 429 Too Many Requests, 500-504 server errors\n return statusCode === 0 || statusCode === 429 || (statusCode >= 500 && statusCode <= 504);\n }\n\n /**\n * Calculates exponential backoff with full jitter (AWS best practice)\n * @param attempt - The retry attempt number (0-based)\n * @param baseMs - Base delay in milliseconds\n * @param maxMs - Maximum delay cap in milliseconds\n * @returns Delay in milliseconds with random jitter\n * @private\n */\n private calculateBackoff(attempt: number, baseMs = 1000, maxMs = 15000): number {\n const exponential = Math.min(maxMs, baseMs * Math.pow(2, attempt));\n return Math.max(100, Math.random() * exponential); // Full jitter, 100ms floor\n }\n\n /**\n * Wraps request with retry logic for transient failures\n * @param url - The full URL to request\n * @param options - Fetch API request options\n * @param maxRetries - Maximum number of retry attempts (default 3)\n * @returns Promise resolving to an ApiResponse with typed data\n * @private\n */\n private async retryableRequest<T>(url: string, options: RequestInit = {}, maxRetries = 3): Promise<ApiResponse<T>> {\n // Add idempotency key for POST requests\n if (options.method === 'POST') {\n const headers = (options.headers as Record<string, string>) || {};\n if (!headers['X-Idempotency-Key']) {\n headers['X-Idempotency-Key'] = randomUUID();\n options = { ...options, headers: { ...options.headers, ...headers } };\n }\n }\n\n let lastResult: ApiResponse<T> | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const result = await this.request<T>(url, options);\n\n // Success or non-retryable error — return immediately\n // If there's no error object, treat as non-retryable (e.g. API returning { success: false } on 200)\n if (result.success || !result.error || !this.isRetryableStatus(result.error.statusCode || 0)) {\n return result;\n }\n\n lastResult = result;\n } catch (error) {\n // AuthenticationError and 403 errors are thrown, not returned\n // These should NOT be retried — re-throw immediately\n throw error;\n }\n\n // Wait before retry (but not after the last attempt)\n if (attempt < maxRetries) {\n const backoff = this.calculateBackoff(attempt);\n await new Promise((resolve) => setTimeout(resolve, backoff));\n }\n }\n\n return lastResult!;\n }\n\n /**\n * Performs an HTTP GET request\n * @param url - The relative URL path to request (will be appended to baseUrl)\n * @param headers - Optional HTTP headers to include in the request\n * @returns Promise resolving to an ApiResponse with typed data\n * @protected\n */\n protected async httpGet<T>(url: string, headers?: Record<string, string>): Promise<ApiResponse<T>> {\n return this.retryableRequest<T>(this.baseUrl + url, { method: 'GET', headers });\n }\n\n /**\n * Performs an HTTP POST request\n * @param url - The relative URL path to request (will be appended to baseUrl)\n * @param data - Optional request body data (will be JSON stringified)\n * @param headers - Optional HTTP headers to include in the request\n * @returns Promise resolving to an ApiResponse with typed data\n * @protected\n */\n protected async httpPost<T>(url: string, data?: any, headers?: Record<string, string>): Promise<ApiResponse<T>> {\n return this.retryableRequest<T>(this.baseUrl + url, {\n method: 'POST',\n body: data ? JSON.stringify(data) : undefined,\n headers,\n });\n }\n\n /**\n * Performs an HTTP PUT request\n * @param url - The relative URL path to request (will be appended to baseUrl)\n * @param data - Optional request body data (will be JSON stringified)\n * @param headers - Optional HTTP headers to include in the request\n * @returns Promise resolving to an ApiResponse with typed data\n * @protected\n */\n protected async httpPut<T>(url: string, data?: any, headers?: Record<string, string>): Promise<ApiResponse<T>> {\n return this.retryableRequest<T>(this.baseUrl + url, {\n method: 'PUT',\n body: data ? JSON.stringify(data) : undefined,\n headers,\n });\n }\n\n /**\n * Performs an HTTP DELETE request\n * @param url - The relative URL path to request (will be appended to baseUrl)\n * @param headers - Optional HTTP headers to include in the request\n * @returns Promise resolving to an ApiResponse with typed data\n * @protected\n */\n protected async httpDelete<T>(url: string, headers?: Record<string, string>): Promise<ApiResponse<T>> {\n return this.retryableRequest<T>(this.baseUrl + url, { method: 'DELETE', headers });\n }\n\n /**\n * Performs an HTTP PATCH request\n * @param url - The relative URL path to request (will be appended to baseUrl)\n * @param data - Optional request body data (will be JSON stringified)\n * @param headers - Optional HTTP headers to include in the request\n * @returns Promise resolving to an ApiResponse with typed data\n * @protected\n */\n protected async httpPatch<T>(url: string, data?: any, headers?: Record<string, string>): Promise<ApiResponse<T>> {\n return this.retryableRequest<T>(this.baseUrl + url, {\n method: 'PATCH',\n body: data ? JSON.stringify(data) : undefined,\n headers,\n });\n }\n}\n","import { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport { UserData } from '../interfaces/admin.js';\n\n/**\n * Authentication API calls\n */\nexport default class AuthApi extends HttpClient {\n /**\n * Creates an instance of AuthApi\n * @param baseUrl - The base URL for the API\n */\n constructor(baseUrl: string) {\n super(baseUrl);\n }\n\n /**\n * Validates an API key and retrieves associated user data\n * @param apiKey - The API key to validate\n * @returns Promise resolving to an ApiResponse containing UserData if the key is valid\n * @throws Error if the API key is invalid or the request fails\n */\n async checkApiKey(apiKey: string): Promise<ApiResponse<UserData>> {\n return this.httpGet<UserData>(`/admin`, {\n Authorization: `Bearer ${apiKey}`,\n });\n }\n\n /**\n * Sends a one-time password (OTP) to the specified email address\n * @param email - The email address to send the OTP to\n * @returns Promise resolving to an ApiResponse with a success message\n * @throws Error if the email is invalid or the request fails\n */\n async sendOtp(email: string): Promise<ApiResponse<{ message: string }>> {\n return this.httpPost<{ message: string }>(`/otp`, { email, type: 'email' });\n }\n\n /**\n * Verifies the OTP sent to the user's email and returns a sign-in token\n * @param email - The email address the OTP was sent to\n * @param otp - The one-time password received via email\n * @returns Promise resolving to an ApiResponse containing a signInToken for authentication\n * @throws Error if the OTP is invalid, expired, or the request fails\n */\n async verifyOtp(email: string, otp: string): Promise<ApiResponse<{ signInToken: string }>> {\n return this.httpPost<{ signInToken: string }>(`/otp/verify`, { email, pin: otp, type: 'email' });\n }\n\n /**\n * Exchanges a sign-in token for an API key\n * @param signInToken - The temporary sign-in token obtained from OTP verification\n * @returns Promise resolving to an ApiResponse containing the API key\n * @throws Error if the sign-in token is invalid or the request fails\n */\n async getApiKey(signInToken: string): Promise<ApiResponse<{ apiKey: string }>> {\n return this.httpPost<{ apiKey: string }>(`/profile/apiKey`, undefined, {\n Authorization: `Bearer ${signInToken}`,\n });\n }\n}\n","/**\n * Authentication Service\n * Handles all authentication operations including API key management and OTP flows\n */\n\nimport 'dotenv/config';\nimport { readFileSync, writeFileSync, mkdirSync, unlinkSync } from 'fs';\nimport { dirname } from 'path';\nimport { UserData } from '../interfaces/admin.js';\nimport AuthApi from '../api/auth.api.service.js';\nimport { BASE_URLS, CREDENTIALS_FILE } from '../config/constants.js';\nimport { AuthenticationError } from '../errors/auth.error.js';\n\n// ============================================================================\n// TOKEN RESOLUTION\n// ============================================================================\n\n/**\n * Retrieves the API key from the following sources in priority order:\n * 1. LUA_API_KEY environment variable (CI/CD, Docker, manual export)\n * — this also covers .env files, since dotenv/config (imported above)\n * loads them into process.env before this function is called.\n * 2. ~/.lua-cli/credentials file (written by `lua auth configure`)\n *\n * Throws AuthenticationError with clear instructions if no key is found.\n */\nexport function getToken(): string {\n // Priority 1: Environment variable (also catches .env values loaded by dotenv)\n if (process.env.LUA_API_KEY) {\n return process.env.LUA_API_KEY;\n }\n\n // Priority 2: Credentials file (written by `lua auth configure`)\n try {\n const token = readFileSync(CREDENTIALS_FILE, 'utf8').trim();\n if (token) return token;\n } catch {\n // File doesn't exist or is not readable — fall through to error\n }\n\n // Embed full remediation in the message and tell withErrorHandling not to\n // append its generic credential hint — the three options below are richer\n // than the wrapper's default for this specific case (no key at all).\n throw new AuthenticationError(\n 'No API key found.\\n' +\n '\\n' +\n ' Authenticate using one of these methods:\\n' +\n '\\n' +\n ' ➜ lua auth configure\\n' +\n ' ➜ export LUA_API_KEY=\"your-api-key-here\"\\n' +\n ' ➜ Add LUA_API_KEY=... to a .env file\\n' +\n '\\n' +\n ' 🔑 Get your API key at https://admin.heylua.ai',\n 'invalid_credentials',\n undefined,\n true\n );\n}\n\n/**\n * Returns the API key if present, or null if missing — never throws.\n *\n * Mirrors {@link getToken}'s priority order (env var, then credentials file)\n * but is safe to call from diagnostic / \"doctor\" code paths where authentication\n * is optional (e.g. `lua status`).\n */\nexport function loadApiKey(): string | null {\n if (process.env.LUA_API_KEY) {\n return process.env.LUA_API_KEY;\n }\n try {\n const token = readFileSync(CREDENTIALS_FILE, 'utf8').trim();\n return token || null;\n } catch {\n return null;\n }\n}\n\n// ============================================================================\n// CREDENTIALS FILE OPERATIONS (Local Storage)\n// ============================================================================\n\n/**\n * Saves API key to ~/.lua-cli/credentials with owner-only permissions (0600).\n * Called by `lua auth configure` after successful server validation.\n *\n * @param apiKey - The API key to store\n */\nexport function saveApiKey(apiKey: string): void {\n mkdirSync(dirname(CREDENTIALS_FILE), { recursive: true });\n writeFileSync(CREDENTIALS_FILE, apiKey, { mode: 0o600 });\n}\n\n/**\n * Deletes the credentials file.\n * Called by `lua auth logout`.\n *\n * @returns true if deleted successfully, false if not found or deletion failed\n */\nexport function deleteApiKey(): boolean {\n try {\n unlinkSync(CREDENTIALS_FILE);\n return true;\n } catch {\n return false;\n }\n}\n\n// ============================================================================\n// API OPERATIONS (Server Authentication)\n// ============================================================================\n\n/**\n * Validates an API key with the server and retrieves user data.\n *\n * @param apiKey - The API key to validate\n * @returns Promise resolving to user data including admin info and organizations\n * @throws AuthenticationError if the API key is invalid\n */\nexport async function checkApiKey(apiKey: string): Promise<UserData> {\n const authApi = new AuthApi(BASE_URLS.API);\n const result = await authApi.checkApiKey(apiKey);\n\n if (!result.success) {\n throw new AuthenticationError('Invalid API key');\n }\n\n return result.data!;\n}\n\n// ============================================================================\n// EMAIL OTP AUTHENTICATION FLOW\n// ============================================================================\n\n/**\n * Requests an OTP (One-Time Password) to be sent to the specified email.\n * The OTP will be valid for a limited time and can be used once.\n *\n * @param email - Email address to send OTP to\n * @returns Promise resolving to true if OTP sent successfully, false otherwise\n */\nexport async function requestEmailOTP(email: string): Promise<boolean> {\n try {\n const authApi = new AuthApi(BASE_URLS.AUTH);\n const result = await authApi.sendOtp(email);\n return result.success;\n } catch (error) {\n console.error('❌ Error requesting OTP:', error);\n return false;\n }\n}\n\n/**\n * Verifies an OTP code and retrieves a sign-in token.\n * The sign-in token can be used to generate an API key.\n *\n * @param email - Email address the OTP was sent to\n * @param pin - The OTP code received via email\n * @returns Promise resolving to sign-in token or null if verification failed\n */\nexport async function verifyOTPAndGetToken(email: string, pin: string): Promise<string | null> {\n try {\n const authApi = new AuthApi(BASE_URLS.AUTH);\n const result = await authApi.verifyOtp(email, pin);\n return result.success ? result.data!.signInToken : null;\n } catch (error) {\n console.error('❌ Error verifying OTP:', error);\n return null;\n }\n}\n\n/**\n * Generates a permanent API key using a sign-in token.\n * The sign-in token is obtained from successful OTP verification.\n *\n * @param signInToken - Token obtained from OTP verification\n * @returns Promise resolving to API key or null if generation failed\n */\nexport async function generateApiKey(signInToken: string): Promise<string | null> {\n try {\n const authApi = new AuthApi(BASE_URLS.AUTH);\n const result = await authApi.getApiKey(signInToken);\n return result.success ? result.data!.apiKey : null;\n } catch (error) {\n console.error('❌ Error generating API key:', error);\n return null;\n }\n}\n","/**\n * Constants for the compile command\n */\n\n// =============================================================================\n// PRIMITIVE SHIMS\n//\n// Passthrough shims for lua-cli primitives (define* functions and Lua* classes).\n// Used in two places:\n// - compiler/utils/ast-helpers.ts: fed to ts-evaluator so it can resolve\n// expressions like `defineTool({name: 'foo'})` at compile time\n// - utils/sandbox.ts: injected into the VM context so bundled code that\n// still references these names at runtime gets a no-op passthrough\n//\n// The define* functions return their config as-is.\n// The Lua* classes assign config properties to `this`.\n// =============================================================================\n\nclass PassthroughPrimitive {\n constructor(config: any) {\n Object.assign(this, config);\n }\n}\nconst passthroughDefine = (config: any) => config;\n\n/**\n * Map of all lua-cli primitive shims.\n * Single source of truth — add new primitives here.\n */\nexport const PRIMITIVE_SHIMS = {\n // Class-based constructors\n LuaTool: PassthroughPrimitive,\n LuaSkill: PassthroughPrimitive,\n LuaJob: PassthroughPrimitive,\n LuaWebhook: PassthroughPrimitive,\n PreProcessor: PassthroughPrimitive,\n LuaPreprocessor: PassthroughPrimitive,\n PostProcessor: PassthroughPrimitive,\n LuaPostprocessor: PassthroughPrimitive,\n LuaMCPServer: PassthroughPrimitive,\n // Function-based define patterns\n defineTool: passthroughDefine,\n defineSkill: passthroughDefine,\n defineJob: passthroughDefine,\n defineWebhook: passthroughDefine,\n definePreProcessor: passthroughDefine,\n definePostProcessor: passthroughDefine,\n defineMCPServer: passthroughDefine,\n};\n\n// =============================================================================\n// DIRECTORIES & FILES\n// =============================================================================\n\n/**\n * Directory names used during compilation\n */\nexport const COMPILE_DIRS = {\n DIST: 'dist',\n DIST_V2: 'dist-v2',\n LUA: '.lua',\n TOOLS: 'tools',\n} as const;\n\n/**\n * File names used during compilation\n */\nexport const COMPILE_FILES = {\n DEPLOYMENT_JSON: 'deployment.json',\n DEPLOY_JSON: 'deploy.json',\n MANIFEST_JSON: 'manifest.json',\n INDEX_TS: 'index.ts',\n INDEX_JS: 'index.js',\n PACKAGE_JSON: 'package.json',\n TSCONFIG_JSON: 'tsconfig.json',\n LUA_SKILL_YAML: 'lua.skill.yaml',\n} as const;\n\n/**\n * Default values for skill metadata\n */\nexport const SKILL_DEFAULTS = {\n NAME: 'lua-skill',\n VERSION: '1.0.0',\n DESCRIPTION: '',\n CONTEXT: '',\n} as const;\n\n/**\n * JSON formatting options\n */\nexport const JSON_FORMAT = {\n INDENT: 2,\n} as const;\n\n/**\n * YAML formatting options\n */\nexport const YAML_FORMAT = {\n INDENT: 2,\n LINE_WIDTH: -1,\n NO_REFS: true,\n} as const;\n","var __defProp = Object.defineProperty;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\n\n// src/persona-text.type.ts\nfunction isPersonaTextObject(value) {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) return false;\n const obj = value;\n for (const k of Object.keys(obj)) {\n if (k !== \"base\" && k !== \"voice\" && k !== \"text\") return false;\n if (obj[k] !== void 0 && typeof obj[k] !== \"string\") return false;\n }\n return true;\n}\n__name(isPersonaTextObject, \"isPersonaTextObject\");\nfunction flattenPersonaText(input, isVoice = false) {\n if (input == null) return \"\";\n if (typeof input === \"string\") return input;\n const parts = [];\n if (input.base) parts.push(input.base);\n const channelText = isVoice ? input.voice : input.text;\n if (channelText) parts.push(channelText);\n return parts.join(\"\\n\\n\");\n}\n__name(flattenPersonaText, \"flattenPersonaText\");\nfunction flattenPersonaTextAll(input) {\n if (input == null) return \"\";\n if (typeof input === \"string\") return input;\n const parts = [];\n if (input.base) parts.push(input.base);\n if (input.voice) parts.push(input.voice);\n if (input.text) parts.push(input.text);\n return parts.join(\"\\n\\n\");\n}\n__name(flattenPersonaTextAll, \"flattenPersonaTextAll\");\nfunction hasPersonaTextContent(input) {\n if (input == null) return false;\n if (typeof input === \"string\") return input.trim().length > 0;\n return Boolean(input.base?.trim() || input.voice?.trim() || input.text?.trim());\n}\n__name(hasPersonaTextContent, \"hasPersonaTextContent\");\nfunction personaToLiteral(persona) {\n const formatValue = /* @__PURE__ */ __name((v) => {\n if (v.includes(\"\\n\")) {\n return \"`\" + v.replace(/\\\\/g, \"\\\\\\\\\").replace(/`/g, \"\\\\`\").replace(/\\$/g, \"\\\\$\") + \"`\";\n }\n return '\"' + v.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"') + '\"';\n }, \"formatValue\");\n if (typeof persona === \"string\") return formatValue(persona);\n const parts = [];\n if (persona.base !== void 0) parts.push(`base: ${formatValue(persona.base)}`);\n if (persona.voice !== void 0) parts.push(`voice: ${formatValue(persona.voice)}`);\n if (persona.text !== void 0) parts.push(`text: ${formatValue(persona.text)}`);\n return `{ ${parts.join(\", \")} }`;\n}\n__name(personaToLiteral, \"personaToLiteral\");\n\n// src/unstructured-types.ts\nvar UNSTRUCTURED_SUPPORTED_MEDIA_TYPES = /* @__PURE__ */ new Set([\n // PDF\n \"application/pdf\",\n // Word processing (.doc, .docx, .dot, .dotm, .zabw)\n \"application/msword\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.template\",\n \"application/vnd.oasis.opendocument.text\",\n \"application/rtf\",\n \"text/rtf\",\n \"application/x-abiword\",\n // Spreadsheets (.xls, .xlsx, .fods, .csv, .tsv, .dbf, .et, .mw)\n \"application/vnd.ms-excel\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n \"application/vnd.oasis.opendocument.spreadsheet\",\n \"text/csv\",\n \"text/tab-separated-values\",\n \"application/dbase\",\n \"application/x-et\",\n // Presentations (.ppt, .pptx, .pptm, .pot)\n \"application/vnd.ms-powerpoint\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n \"application/vnd.openxmlformats-officedocument.presentationml.template\",\n // Images — OCR (.bmp, .heic, .jpeg, .jpg, .png, .prn, .tiff)\n \"image/jpeg\",\n \"image/jpg\",\n \"image/png\",\n \"image/tiff\",\n \"image/bmp\",\n \"image/heic\",\n // Email (.eml, .msg, .p7s)\n \"message/rfc822\",\n \"application/vnd.ms-outlook\",\n \"application/pkcs7-signature\",\n // Web/Markup (.htm, .html, .md, .rst, .xml, .org)\n \"text/html\",\n \"text/markdown\",\n \"text/x-rst\",\n \"text/x-org\",\n \"application/xml\",\n \"text/xml\",\n // Text (.txt)\n \"text/plain\",\n // eBook (.epub)\n \"application/epub+zip\",\n // Other (.hwp, .json, .cwk, .mcw, .dif, .sxg)\n \"application/json\",\n \"application/x-hwp\",\n \"application/clarisworks\",\n \"application/x-dif\",\n \"application/vnd.sun.xml.writer.global\"\n]);\n\n// src/ai-generate.utils.ts\nfunction aiGenerateInputFromSimplified(prompt, content) {\n if (content === void 0) {\n return {\n prompt\n };\n }\n return {\n system: prompt,\n messages: [\n {\n role: \"user\",\n content\n }\n ]\n };\n}\n__name(aiGenerateInputFromSimplified, \"aiGenerateInputFromSimplified\");\n\n// src/chat-history.types.ts\nfunction removeNavigateBlock(input) {\n return input.replace(/::: navigate[\\s\\S]*?:::/g, \"\").trim();\n}\n__name(removeNavigateBlock, \"removeNavigateBlock\");\nfunction transformChatHistoryContentParts(parts) {\n const content = [];\n for (const rawPart of parts ?? []) {\n const part = rawPart;\n if (part?.type !== \"text\" && part?.type !== \"file\") continue;\n if (part.type === \"text\" && typeof part.text === \"string\") {\n const rawText = part.text || \"\";\n if (rawText.includes(\"::: hide\")) continue;\n const audioMatch = rawText.match(/::: audio\\s*!\\[(.*?)\\]\\((.*?)\\)\\s*:::/);\n const videoMatch = rawText.match(/::: video\\s*!\\[(.*?)\\]\\((.*?)\\)\\s*:::/);\n if (audioMatch) {\n content.push({\n type: \"audio\",\n data: audioMatch[2],\n mediaType: audioMatch[1]\n });\n } else if (videoMatch) {\n content.push({\n type: \"video\",\n video: videoMatch[2],\n mediaType: videoMatch[1]\n });\n } else {\n let text = rawText.replace(/\\\\\\\\\\\\n/g, \"\\n\");\n text = removeNavigateBlock(text);\n content.push({\n type: \"text\",\n text\n });\n }\n } else if (part.type === \"file\") {\n const mediaType = part.mimeType || \"\";\n if (mediaType.startsWith(\"image/\")) {\n content.push({\n type: \"image\",\n image: part.data,\n mediaType\n });\n } else if (mediaType.startsWith(\"video/\")) {\n content.push({\n type: \"video\",\n video: part.data,\n mediaType\n });\n } else if (mediaType.startsWith(\"audio/\")) {\n content.push({\n type: \"audio\",\n data: part.data,\n mediaType\n });\n } else {\n content.push({\n type: \"file\",\n data: part.data,\n mediaType\n });\n }\n }\n }\n return content;\n}\n__name(transformChatHistoryContentParts, \"transformChatHistoryContentParts\");\n\n// src/sandbox-contract.ts\nvar REQUIRED_PRIMITIVE_SHIMS = [\n // Class-based\n \"LuaTool\",\n \"LuaSkill\",\n \"LuaJob\",\n \"LuaWebhook\",\n \"PreProcessor\",\n \"LuaPreprocessor\",\n \"PostProcessor\",\n \"LuaPostprocessor\",\n \"LuaMCPServer\",\n // Function-based\n \"defineTool\",\n \"defineSkill\",\n \"defineJob\",\n \"defineWebhook\",\n \"definePreProcessor\",\n \"definePostProcessor\",\n \"defineMCPServer\"\n];\nvar REQUIRED_PLATFORM_APIS = {\n User: [\n \"get\",\n \"getChatHistory\"\n ],\n Products: [\n \"get\",\n \"create\",\n \"delete\",\n \"search\",\n \"getById\"\n ],\n Baskets: [\n \"create\",\n \"get\",\n \"addItem\",\n \"removeItem\",\n \"clear\",\n \"updateStatus\",\n \"updateMetadata\",\n \"placeOrder\",\n \"getById\"\n ],\n Orders: [\n \"create\",\n \"updateStatus\",\n \"updateData\",\n \"get\",\n \"getById\"\n ],\n Data: [\n \"create\",\n \"get\",\n \"getEntry\",\n \"update\",\n \"search\",\n \"delete\"\n ],\n Jobs: [\n \"create\",\n \"getJob\",\n \"getAll\"\n ],\n AI: [\n \"generate\"\n ],\n Voice: [\n \"call\"\n ],\n // Lowercase alias so devs can write `this.voice.call(...)` from a top-level\n // execute body — at the script's top scope `this === globalThis`. Functionally\n // identical to `Voice` (same closure), so any drift between the two would be a\n // bug.\n voice: [\n \"call\"\n ],\n CDN: [\n \"upload\",\n \"get\"\n ]\n};\nvar REQUIRED_NESTED_APIS = {\n Templates: {\n whatsapp: [\n \"list\",\n \"get\",\n \"send\"\n ]\n },\n Lua: {\n request: [\n \"channel\"\n ]\n }\n};\nvar REQUIRED_ENUMS = {\n BasketStatus: [\n \"ACTIVE\",\n \"CHECKED_OUT\",\n \"ABANDONED\",\n \"EXPIRED\"\n ],\n OrderStatus: [\n \"PENDING\",\n \"CONFIRMED\",\n \"FULFILLED\",\n \"CANCELLED\"\n ]\n};\nvar REQUIRED_UTILITIES = [\n \"env\"\n];\n\n// src/client-tools.types.ts\nvar CLIENT_TOOL_PREFIX = \"client__\";\nvar CLIENT_TOOLS_MAX = 20;\n\n// src/persona-defaults.ts\nvar AGENT_NAME_TOKEN = \"[Your Agent Name]\";\nvar DEFAULT_PERSONA_GUIDE = `# ${AGENT_NAME_TOKEN} - Persona\n\nThis is a starting template to help you think about your agent's persona.\nUse it as-is, rearrange it, or replace it entirely with your own format \\u2014 whatever works best for your use case.\nThe sections below are suggestions, not requirements.\n\n## Identity & Role\nWho is your agent? What's their name and core purpose?\n- Give it a name and a clear one-line role\n- e.g. a customer support rep, a shopping assistant, an internal ops copilot, a scheduling bot\n\n## Business Context\nWhat company, product, or service does the agent represent? What does the business do?\n- Describe the business in a sentence or two so the agent understands the world it operates in\n- Include industry, value proposition, and anything the agent should \"know\" about the brand\n\n## Tone & Communication Style\nHow should the agent sound?\n- Formal or casual? Concise or detailed? Empathetic or matter-of-fact?\n- Should it match a specific brand voice or adapt to the user's tone?\n- Any language or cultural considerations (e.g. greetings, local expressions)?\n\n## Target Audience\nWho will the agent be talking to?\n- Describe the typical user: consumers, business customers, internal team members, etc.\n- What do they usually need help with? What matters most to them?\n\n## Capabilities\nWhat can the agent help with? List the main things it should handle.\n- e.g. answering product questions, placing orders, looking up account info, scheduling meetings\n- Be specific \\u2014 this shapes which skills and tools the agent will use\n\n## Boundaries\nWhat should the agent NOT do? When should it escalate to a human?\n- e.g. cannot process refunds, should not give medical/legal advice\n- Define when to hand off: frustrated user, request outside scope, sensitive data\n\n## Guidelines\nAny rules for how the agent behaves?\n- Response length limits (e.g. keep messages under 300 words)\n- Formatting preferences (e.g. use bullet points, avoid jargon)\n- Things to always or never do (e.g. always confirm before changes, never share internal IDs)\n\n---\nFeel free to add, remove, or rename sections. Your persona can be a single paragraph or a detailed playbook \\u2014 whatever gives your agent the context it needs.\n`;\nfunction buildDefaultPersona(agentName) {\n return DEFAULT_PERSONA_GUIDE.replace(AGENT_NAME_TOKEN, () => agentName || \"My Agent\");\n}\n__name(buildDefaultPersona, \"buildDefaultPersona\");\n\n// src/vm-execution-log.types.ts\nvar AGENT_LOG_SOURCES = [\n \"skill\",\n \"job\",\n \"webhook\",\n \"preprocessor\",\n \"postprocessor\",\n \"user_message\",\n \"agent_response\",\n \"agent_error\",\n \"runtime\",\n \"mcp\",\n \"rag\",\n \"device\",\n \"device-trigger\"\n];\n\n// src/luavoice.ts\nimport { z } from \"zod\";\nvar VoiceNameSchema = z.string().regex(/^[a-zA-Z0-9_-]+$/, \"Voice name must contain only alphanumeric characters, underscores, or hyphens\").min(1).max(64);\nvar PluginProviderSchema = z.enum([\n \"deepgram\",\n \"elevenlabs\"\n]);\nvar RealtimeProviderSchema = z.enum([\n \"openai\",\n \"google\",\n \"xai\"\n]);\nvar PluginClassSchema = z.enum([\n \"LLM\",\n \"STT\",\n \"STTv2\",\n \"TTS\"\n]);\nvar ModelDescriptorSchema = z.string().min(1).max(200);\nvar InferenceModelSchema = z.object({\n kind: z.literal(\"inference\"),\n /** Provider-prefixed model id (e.g. `'openai/gpt-5.2-chat-latest'`). */\n model: ModelDescriptorSchema,\n /**\n * TTS-only — provider voice id. Inference's TTS API takes voice\n * separately from model; LLM and STT ignore this field.\n */\n voice: z.string().min(1).max(200).optional(),\n /**\n * Additional Inference extras forwarded as constructor options. Loose\n * record by design — LiveKit's Inference surface evolves faster than\n * we want to chase, and we don't gate dev productivity on schema\n * updates here.\n */\n options: z.record(z.string(), z.unknown()).optional()\n});\nvar PluginModelSchema = z.object({\n kind: z.literal(\"plugin\"),\n provider: PluginProviderSchema,\n class: PluginClassSchema,\n /**\n * Forwarded verbatim to the plugin constructor (e.g. `new deepgram.STT(options)`).\n * Loose record because each provider's option surface is its own\n * schema, evolving independently. The factory passes these through\n * to the LiveKit plugin which is the source of truth for shape.\n */\n options: z.record(z.string(), z.unknown())\n});\nvar RealtimeModelSchema = z.object({\n kind: z.literal(\"realtime\"),\n provider: RealtimeProviderSchema,\n /**\n * Forwarded verbatim to `<provider>.realtime.RealtimeModel(options)`.\n * Each provider has its own surface (voice id, modalities, turn\n * detection, etc.). Loose record so devs can pass any option the\n * underlying plugin accepts without a schema chase.\n */\n options: z.record(z.string(), z.unknown())\n});\nvar LuaVoiceModelSchema = z.discriminatedUnion(\"kind\", [\n InferenceModelSchema,\n PluginModelSchema,\n RealtimeModelSchema\n]);\nvar TurnDetectionSchema = z.enum([\n \"multilingual\",\n \"english\",\n \"vad\",\n \"stt\",\n \"manual\"\n]);\nvar InterruptionSchema = z.object({\n enabled: z.boolean().optional(),\n mode: z.enum([\n \"adaptive\",\n \"vad\"\n ]).optional(),\n falseInterruptionTimeout: z.number().min(0).optional(),\n resumeFalseInterruption: z.boolean().optional(),\n minDelay: z.number().min(0).optional(),\n maxDelay: z.number().min(0).optional()\n}).superRefine((val, ctx) => {\n if (typeof val.minDelay === \"number\" && typeof val.maxDelay === \"number\" && val.minDelay > val.maxDelay) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `interruption.minDelay (${val.minDelay}) must be \\u2264 maxDelay (${val.maxDelay})`,\n path: [\n \"minDelay\"\n ]\n });\n }\n});\nvar BuiltinAudioClipSchema = z.enum([\n \"office-ambience\",\n \"keyboard-typing\",\n \"keyboard-typing-2\"\n]);\nvar AudioConfigSchema = z.object({\n source: BuiltinAudioClipSchema,\n volume: z.number().min(0).max(1).optional(),\n probability: z.number().min(0).max(1).optional()\n});\nvar BackgroundAudioEntrySchema = z.union([\n BuiltinAudioClipSchema,\n AudioConfigSchema,\n z.array(AudioConfigSchema)\n]);\nvar BackgroundAudioSchema = z.object({\n // Looping ambient sound played throughout the session. Common: 'office-ambience'.\n ambient: BackgroundAudioEntrySchema.optional(),\n // Sound played while the agent is in the thinking state (between user\n // turn end and TTS playback start). Common: 'keyboard-typing'.\n thinking: BackgroundAudioEntrySchema.optional()\n});\nvar LuaVoiceConfigInnerSchema = z.object({\n name: VoiceNameSchema.optional(),\n // The runtime brain. Three accepted shapes via the discriminated union:\n // - `kind: 'inference'` — LiveKit Inference (string descriptor route)\n // - `kind: 'plugin'` — direct provider plugin (Lua-held credits)\n // - `kind: 'realtime'` — speech-to-speech model in the LLM slot\n // STT and TTS are required for cascaded LLMs, optional for realtime\n // (full mode skips both; half-cascade keeps `tts`). Enforced by the\n // refine on the outer `LuaVoiceConfigSchema`.\n llm: LuaVoiceModelSchema,\n stt: LuaVoiceModelSchema.optional(),\n tts: LuaVoiceModelSchema.optional(),\n // Voice activity detection. 'silero' is the only supported value\n // today; declared as a string so future engines (e.g. WebRTC VAD)\n // don't require a schema change.\n vad: z.string().optional(),\n // Silero VAD tuning. All four knobs map 1:1 to the values\n // `silero.VAD.load(...)` accepts. Useful when the default\n // thresholds clip the start of speech on quiet callers, or when\n // the default endpointing fires too eagerly mid-thought. Omit any\n // field to take the SDK default.\n vadOptions: z.object({\n // Milliseconds of speech that must accumulate before a turn starts. SDK default: 50ms.\n minSpeechDuration: z.number().min(0).max(5e3).optional(),\n // Milliseconds of silence required to end a turn. SDK default: 550ms.\n minSilenceDuration: z.number().min(0).max(5e3).optional(),\n // Milliseconds of audio captured BEFORE the detected speech start —\n // forwarded into STT so the first phoneme isn't lost. SDK default: 500ms.\n prefixPaddingDuration: z.number().min(0).max(2e3).optional(),\n // 0-1; lower means more sensitive to speech onset (more\n // false-positives), higher means more conservative.\n activationThreshold: z.number().min(0).max(1).optional()\n }).strict().optional(),\n turnDetection: TurnDetectionSchema.optional(),\n // Spoken at session start via LiveKit's `session.generateReply` from\n // the agent's onEnter. Empty string treated as no greeting.\n greeting: z.string().optional(),\n // LiveKit AgentSession knobs.\n maxToolSteps: z.number().int().min(1).max(20).optional(),\n userAwayTimeout: z.number().min(0).optional(),\n preemptiveGeneration: z.boolean().optional(),\n interruption: InterruptionSchema.optional(),\n // BCP-47 language code or 'multi' for multilingual transcription.\n // Applies to both Inference STT and the deepgram plugin.\n sttLanguage: z.string().optional(),\n // Krisp BVC noise cancellation. Opt-in (default off) because LiveKit\n // bills it separately and not all channels need PSTN-grade suppression.\n krispEnabled: z.boolean().optional(),\n // Background audio — ambient + thinking sounds layered on the agent's\n // output. Each entry is a built-in clip name or a per-clip config; arrays\n // become probabilistic mixes (worker picks one per ambient loop / thinking\n // event). LiveKit's `BackgroundAudioPlayer` consumes the same shape.\n backgroundAudio: BackgroundAudioSchema.optional(),\n // Output speech volume (0-100). Applied as a per-frame multiplier in the\n // worker's compiled `ttsNode` override. Defaults to no adjustment when\n // omitted — letting the TTS provider's native level pass through.\n volume: z.number().int().min(0).max(100).optional(),\n // Word-boundary text replacements applied before TTS synthesis. The map\n // key is matched case-insensitively as a whole word; the value is the\n // spoken-form replacement. Provider-side SSML still works on top of this\n // — pronunciations is for the simple cases (e.g. `'API' → 'A P I'`,\n // `'kubectl' → 'kube control'`). Only effective on the cascaded path —\n // realtime models bypass `ttsNode` entirely.\n pronunciations: z.record(z.string(), z.string()).optional(),\n // When true, the worker writes `session.history` to `Data.set('call:<sessionId>')`\n // after the call ends. Read it back from a job/webhook with\n // `Data.get('call:<sessionId>')` to drive post-call analytics, follow-ups,\n // or QA workflows. Defaults to false — most calls don't need to keep\n // a transcript copy.\n persistTranscript: z.boolean().optional(),\n // Spoken acknowledgement played when a tool call fails. When a tool\n // throws, times out, or returns an unsupported result, the adapter calls\n // `session.say(text)` once per failed call before surfacing the error\n // to the LLM as a ToolError — fills the 2–3s gap before the LLM's own\n // recovery response. Persona-specific (keep it short and on-brand);\n // absent → no spoken fallback (the LLM's recovery is the only signal).\n onToolFailureSay: z.string().min(1).max(200).optional()\n});\nvar LuaVoiceConfigSchema = LuaVoiceConfigInnerSchema.superRefine((cfg, ctx) => {\n const isRealtime = cfg.llm.kind === \"realtime\";\n if (!isRealtime) {\n if (!cfg.stt) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\n \"stt\"\n ],\n message: \"stt is required when llm is not a realtime model\"\n });\n }\n if (!cfg.tts) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\n \"tts\"\n ],\n message: \"tts is required when llm is not a realtime model\"\n });\n }\n } else {\n if (cfg.stt) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\n \"stt\"\n ],\n message: \"stt cannot be set with a realtime llm \\u2014 realtime models handle audio input directly. Drop the stt field for full realtime, or use a cascaded llm if you need a separate STT.\"\n });\n }\n if (cfg.pronunciations && Object.keys(cfg.pronunciations).length > 0 && !cfg.tts) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\n \"pronunciations\"\n ],\n message: \"pronunciations require a TTS step; pair with a `tts` config (half-cascade mode) or drop the field for full realtime.\"\n });\n }\n }\n});\nvar LuaVoiceRefSchema = z.object({\n voiceId: z.string().min(1),\n version: z.string().optional()\n});\n\n// src/event-catalog.ts\nvar EventType = /* @__PURE__ */ (function(EventType2) {\n EventType2[\"AGENT_CREATED\"] = \"agent.created\";\n EventType2[\"CHANNEL_ADDED\"] = \"channel.added\";\n EventType2[\"MESSAGE_RECEIVED\"] = \"message.received\";\n EventType2[\"INQUIRY_CREATED\"] = \"inquiry.created\";\n EventType2[\"USER_LOGIN\"] = \"user.login\";\n EventType2[\"CREDIT_UPDATED\"] = \"credit.updated\";\n EventType2[\"CREDIT_PURCHASED\"] = \"credit.purchased\";\n EventType2[\"CREDIT_THRESHOLD_50\"] = \"credit.threshold.50\";\n EventType2[\"CREDIT_THRESHOLD_20\"] = \"credit.threshold.20\";\n EventType2[\"CREDIT_THRESHOLD_0\"] = \"credit.threshold.0\";\n EventType2[\"MESSAGE_SENT\"] = \"message.sent\";\n EventType2[\"MESSAGE_DELIVERED\"] = \"message.delivered\";\n EventType2[\"MESSAGE_READ\"] = \"message.read\";\n EventType2[\"MESSAGE_FAILED\"] = \"message.failed\";\n EventType2[\"MESSAGE_PLAYED\"] = \"message.played\";\n return EventType2;\n})({});\nexport {\n AGENT_LOG_SOURCES,\n CLIENT_TOOLS_MAX,\n CLIENT_TOOL_PREFIX,\n EventType,\n LuaVoiceConfigSchema,\n LuaVoiceModelSchema,\n LuaVoiceRefSchema,\n PluginProviderSchema,\n REQUIRED_ENUMS,\n REQUIRED_NESTED_APIS,\n REQUIRED_PLATFORM_APIS,\n REQUIRED_PRIMITIVE_SHIMS,\n REQUIRED_UTILITIES,\n RealtimeProviderSchema,\n UNSTRUCTURED_SUPPORTED_MEDIA_TYPES,\n aiGenerateInputFromSimplified,\n buildDefaultPersona,\n flattenPersonaText,\n flattenPersonaTextAll,\n hasPersonaTextContent,\n isPersonaTextObject,\n personaToLiteral,\n removeNavigateBlock,\n transformChatHistoryContentParts\n};\n","/**\n * Compilation Types\n *\n * All types related to the compilation process, plugins, and output manifest.\n * Uses discriminated unions for type-safe primitive handling.\n */\n\nimport type { GovernanceConfig, PersonaText, SkillContextText } from '@lua/shared-types';\nimport type { LuaVoiceModel } from '@lua/shared-types';\n\n// =============================================================================\n// COMPILER OPTIONS\n// =============================================================================\n\nexport interface CompilerOptions {\n /** Root directory of the project */\n rootDir: string;\n /** Output directory for artifacts */\n outDir: string;\n /** Enable source maps */\n sourceMaps?: boolean;\n /** Minify output */\n minify?: boolean;\n /** Enable debug mode (extra verbose logging, preserve temps) */\n debug?: boolean;\n /** Enable verbose output (show each primitive as it compiles) */\n verbose?: boolean;\n /** Skip validation warnings (still show errors) */\n quietWarnings?: boolean;\n /** Add runtime validation wrapper to artifacts (default: true) */\n runtimeValidation?: boolean;\n}\n\n// =============================================================================\n// COMPILATION RESULT\n// =============================================================================\n\nexport interface CompilationResult {\n success: boolean;\n manifest: CompilationManifest;\n errors: CompilationError[];\n warnings: CompilationWarning[];\n stats: CompilationStats;\n}\n\n/** Base for compilation messages (errors and warnings) */\ninterface CompilationMessageBase {\n primitive?: string;\n kind?: string;\n file: string;\n line?: number;\n message: string;\n}\n\nexport interface CompilationError extends CompilationMessageBase {\n column?: number;\n suggestion?: string;\n}\n\nexport interface CompilationWarning extends CompilationMessageBase {}\n\nexport interface CompilationStats {\n totalPrimitives: number;\n byKind: Record<string, number>;\n totalSize: number;\n duration: number;\n}\n\n// =============================================================================\n// SHARED PRIMITIVE IDENTITY\n// =============================================================================\n\n/** Core identity fields shared by all primitive representations */\ninterface PrimitiveIdentity {\n /** Primitive type (tool, job, webhook, etc.) */\n kind: string;\n /** Name from the definition */\n name: string;\n /** Description from the definition */\n description: string;\n /** Path to the source file */\n sourcePath: string;\n}\n\n// =============================================================================\n// PATTERN TYPES\n// =============================================================================\n\n/**\n * Pattern for primitive authoring shape.\n *\n * 'function' — `defineX({ ... })`\n * 'class' — `new LuaX({ ... })` (config-via-instantiation)\n * 'class-definition' — `class MyX extends LuaX { ... }` (subclass-with-field-override)\n */\nexport type DefinitionPattern = 'class' | 'function' | 'class-definition';\n\n// =============================================================================\n// PRIMITIVE METADATA\n// =============================================================================\n\n/** Base metadata fields that all primitives share */\nexport interface BaseMetadataFields {\n pattern?: string;\n}\n\n/** Common fields extracted by extractCommonFields() helper (excludes 'kind' which plugins add) */\nexport interface CommonExtractedFields extends Omit<PrimitiveIdentity, 'kind'> {\n exportName: string;\n isDefaultExport: boolean;\n line: number;\n column: number;\n}\n\n/** Metadata extracted from source code during scanning */\nexport interface PrimitiveMetadata<T extends BaseMetadataFields = BaseMetadataFields> extends PrimitiveIdentity {\n /** The export name in the source file (or 'default' for default exports) */\n exportName: string;\n /** Whether this primitive uses `export default` syntax */\n isDefaultExport: boolean;\n /** Line number in source (for error messages) */\n line?: number;\n /** Column number in source */\n column?: number;\n /** Type-specific metadata (typed per plugin) */\n metadata: T;\n}\n\n// =============================================================================\n// TYPED METADATA FIELDS (per primitive kind)\n// =============================================================================\n\nexport interface ToolMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n className?: string;\n hasInputSchema: boolean;\n hasCondition?: boolean;\n hasExecute?: boolean;\n}\n\nexport interface SkillMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n /** Tool variable/class names from the source (e.g., ['myTool', 'MyToolClass']) */\n toolRefs: string[];\n /**\n * Absolute source-file path where each tool ref was resolved by the\n * reference resolver, keyed by `className`. Populated when the ref\n * came through the resolver (which follows re-export barrels,\n * wildcard exports, path aliases) so the tool-resolution step can\n * skip a fresh — and simpler — `findImportSource` walk that doesn't\n * traverse those shapes. Absent entries fall back to the legacy\n * single-file import scan.\n *\n * Not emitted to the manifest — consumed by `resolveReferences()`\n * inside the compiler process only.\n */\n toolRefSourcePaths?: Record<string, string>;\n context?: SkillContextText;\n}\n\nexport interface JobMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n scheduleType?: string;\n scheduleExpression?: string;\n scheduleSeconds?: number;\n scheduleExecuteAt?: string;\n scheduleTimezone?: string;\n hasExecute?: boolean;\n hasTimeout?: boolean;\n hasRetry?: boolean;\n timeoutValue?: number;\n retryConfig?: { maxAttempts?: number; backoffSeconds?: number };\n}\n\nexport interface WebhookMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n hasExecute?: boolean;\n hasQuerySchema?: boolean;\n hasHeaderSchema?: boolean;\n hasBodySchema?: boolean;\n}\n\n/** Shared metadata for pre/post processors */\nexport interface ProcessorMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n hasExecute?: boolean;\n isAsync?: boolean;\n /** Execution priority (lower runs first; default 100). Read by lua-core's `ProcessorService`. */\n priority?: number;\n}\n\nexport type PreProcessorMetadataFields = ProcessorMetadataFields;\nexport type PostProcessorMetadataFields = ProcessorMetadataFields;\n\nexport interface MCPServerMetadataFields extends BaseMetadataFields {\n transport: 'stdio' | 'sse' | 'streamable-http';\n url?: string;\n hasUrlResolver?: boolean;\n hasHeadersResolver?: boolean;\n urlResolverSource?: string;\n headersResolverSource?: string;\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n config?: Record<string, unknown>;\n}\n\nexport interface DeviceTriggerMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n hasExecute?: boolean;\n hasPayloadSchema?: boolean;\n}\n\nexport interface DeviceMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n group?: string;\n}\n\nexport interface VoiceMetadataFields extends BaseMetadataFields {\n pattern: DefinitionPattern;\n /** Normalized discriminated union — `kind: 'inference' | 'plugin'`. */\n llm?: LuaVoiceModel;\n stt?: LuaVoiceModel;\n tts?: LuaVoiceModel;\n vad?: string;\n /** Silero VAD tuning forwarded to `silero.VAD.load(...)` on the worker. */\n vadOptions?: {\n minSpeechDuration?: number;\n minSilenceDuration?: number;\n prefixPaddingDuration?: number;\n activationThreshold?: number;\n };\n turnDetection?: string;\n greeting?: string;\n maxToolSteps?: number;\n userAwayTimeout?: number;\n preemptiveGeneration?: boolean;\n sttLanguage?: string;\n hasInterruption?: boolean;\n hasOnEnter?: boolean;\n hasOnUserTurnCompleted?: boolean;\n hasOnExit?: boolean;\n hasTools?: boolean;\n krispEnabled?: boolean;\n /** Background ambient + thinking sounds. Worker maps clip-name strings to BuiltinAudioClip. */\n backgroundAudio?: { ambient?: unknown; thinking?: unknown };\n /** Output volume 0-100. Applied per-frame in the compiled `ttsNode` override. */\n volume?: number;\n /** Pre-TTS word-boundary text replacements. Case-insensitive. */\n pronunciations?: Record<string, string>;\n /** Persist `session.history` to `Data['call:<sessionId>']` after the call ends. */\n persistTranscript?: boolean;\n /** Spoken phrase played once per failed tool call before the LLM's recovery response. */\n onToolFailureSay?: string;\n /**\n * LiveKit AgentSession `interruption` block. Captured as an object so\n * mode / falseInterruptionTimeout / minDelay / maxDelay actually reach\n * the worker — pre-fix only the boolean `hasInterruption` flag survived\n * the compiler→wire trip and the schema's defaults silently won.\n */\n interruption?: {\n enabled?: boolean;\n mode?: 'adaptive' | 'vad';\n falseInterruptionTimeout?: number;\n resumeFalseInterruption?: boolean;\n minDelay?: number;\n maxDelay?: number;\n };\n}\n\nexport interface AgentMetadataFields extends BaseMetadataFields {\n /** The agent's persona/system prompt */\n persona: PersonaText;\n /** Static model string (e.g., 'openai/gpt-4o') */\n model?: string;\n /** Whether the model property is a resolver function (bundled inside the artifact) */\n hasModelResolver?: boolean;\n /** Per-call sampling settings (temperature, topP, maxOutputTokens, …). Passthrough to Mastra. */\n modelSettings?: Record<string, unknown>;\n /** Per-agent message batching/debounce configuration */\n batching?: {\n firstMessageDelayMs?: number;\n debounceWindowMs?: number;\n maxBatchMessages?: number;\n serializeProcessing?: boolean;\n };\n /** Governance policy configuration */\n governance?: GovernanceConfig;\n /**\n * Identifiers the agent's `voices` array points at, in order. Resolved\n * to real LuaVoice names at manifest build time using `allPrimitives`.\n */\n voiceRefNames?: string[];\n /**\n * Resolver-discovered source file for each identifier in `voiceRefNames`.\n * Keyed by identifier (the local binding in the agent file). Mirrors\n * `SkillMetadataFields.toolRefSourcePaths` and lets `resolveVoiceRefs`\n * match against the voice primitive's `sourcePath` — necessary when the\n * voice is `export default new LuaVoice(...)`, where the local binding\n * (`mattVoice`) matches neither `exportName` (`default`) nor `name`\n * (`matt-line`). Stripped before persistence (absolute build-machine\n * paths must not land in deliverables — see `sanitizeForPersistence`).\n */\n voiceRefSourcePaths?: Record<string, string>;\n}\n\n// =============================================================================\n// TYPED METADATA ALIASES\n// =============================================================================\n\nexport type ToolMetadata = PrimitiveMetadata<ToolMetadataFields>;\nexport type SkillMetadata = PrimitiveMetadata<SkillMetadataFields>;\nexport type JobMetadata = PrimitiveMetadata<JobMetadataFields>;\nexport type WebhookMetadata = PrimitiveMetadata<WebhookMetadataFields>;\nexport type PreProcessorMetadata = PrimitiveMetadata<PreProcessorMetadataFields>;\nexport type PostProcessorMetadata = PrimitiveMetadata<PostProcessorMetadataFields>;\nexport type MCPServerMetadata = PrimitiveMetadata<MCPServerMetadataFields>;\nexport type DeviceTriggerMetadata = PrimitiveMetadata<DeviceTriggerMetadataFields>;\nexport type DeviceMetadata = PrimitiveMetadata<DeviceMetadataFields>;\nexport type AgentMetadata = PrimitiveMetadata<AgentMetadataFields>;\nexport type VoiceMetadata = PrimitiveMetadata<VoiceMetadataFields>;\n\n// =============================================================================\n// VALIDATION\n// =============================================================================\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationMessage[];\n warnings: ValidationMessage[];\n}\n\nexport interface ValidationMessage {\n message: string;\n line?: number;\n column?: number;\n suggestion?: string;\n docsUrl?: string;\n}\n\n// =============================================================================\n// SCHEMAS\n// =============================================================================\n\nexport interface JSONSchema {\n type?: string | string[];\n properties?: Record<string, JSONSchema>;\n required?: string[];\n items?: JSONSchema;\n enum?: unknown[];\n const?: unknown;\n description?: string;\n default?: unknown;\n minimum?: number;\n maximum?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n format?: string;\n additionalProperties?: boolean | JSONSchema;\n oneOf?: JSONSchema[];\n anyOf?: JSONSchema[];\n allOf?: JSONSchema[];\n $ref?: string;\n}\n\nexport interface SchemaSet {\n input?: JSONSchema;\n output?: JSONSchema;\n query?: JSONSchema;\n headers?: JSONSchema;\n body?: JSONSchema;\n [key: string]: JSONSchema | undefined;\n}\n\n// =============================================================================\n// BUNDLED ARTIFACT\n// =============================================================================\n\nexport interface BundledArtifact {\n code: string;\n sourceMap: string;\n originalSource: string;\n size: number;\n hash: string;\n}\n\n// =============================================================================\n// COMPILED PRIMITIVE\n// =============================================================================\n\nexport interface CompiledPrimitive extends PrimitiveMetadata {\n artifact: BundledArtifact;\n schemas?: SchemaSet;\n}\n\n// =============================================================================\n// PROJECT FILES\n// =============================================================================\n\nexport interface ProjectFile {\n /**\n * Path used both as the backup key and the on-disk restore location.\n *\n * For in-project files: path relative to `rootDir` (e.g. `src/index.ts`).\n * For external files (BAC-69): path relative to the workspace root\n * (e.g. `packages/shared/utils.ts`). These are also marked with\n * `external: true` so the restore step materializes them under\n * `.lua/external/<relativePath>` instead of escaping the project dir.\n */\n relativePath: string;\n hash: string;\n size: number;\n type: 'source' | 'config' | 'other';\n /**\n * Set to `true` for files that live outside `rootDir` but inside the\n * containing workspace (monorepo sibling packages). The compiler still\n * backs them up — otherwise `lua init --from-server` can't rebuild the\n * agent — but the restore step treats them specially so the contents\n * don't escape the project directory.\n *\n * Omitted (undefined) for in-project files to keep backup manifests\n * stable for non-monorepo agents.\n */\n external?: boolean;\n}\n\n// =============================================================================\n// COMPILER CONSTANTS\n// =============================================================================\n\n/** Manifest format version. Referenced by entry points, manifests, and minimal manifests. */\nexport const COMPILER_VERSION = '2.0.0';\n\n/** esbuild compilation target. Referenced by bundler and MCP resolver bundler. */\nexport const ESBUILD_TARGET = 'node18';\n\n// =============================================================================\n// MANIFEST PRIMITIVES\n// =============================================================================\n\nexport enum PrimitiveKind {\n TOOL = 'tool',\n SKILL = 'skill',\n JOB = 'job',\n WEBHOOK = 'webhook',\n PREPROCESSOR = 'preprocessor',\n POSTPROCESSOR = 'postprocessor',\n MCP_SERVER = 'mcp-server',\n AGENT = 'agent',\n DEVICE = 'device',\n DEVICE_TRIGGER = 'device-trigger',\n VOICE = 'voice',\n}\n\ninterface ManifestPrimitiveBase extends PrimitiveIdentity {\n /** Path to the compiled artifact */\n path: string;\n /** Content hash for cache invalidation */\n hash: string;\n}\n\nexport interface ManifestTool extends ManifestPrimitiveBase {\n kind: PrimitiveKind.TOOL;\n schemas?: { input?: JSONSchema; output?: JSONSchema };\n hasCondition?: boolean;\n}\n\nexport interface ManifestSkill extends ManifestPrimitiveBase {\n kind: PrimitiveKind.SKILL;\n context?: PersonaText;\n tools: string[];\n}\n\nexport interface ManifestJob extends ManifestPrimitiveBase {\n kind: PrimitiveKind.JOB;\n schedule?: { type: string; expression?: string; seconds?: number; executeAt?: string; timezone?: string };\n timeout?: number;\n retry?: { maxAttempts?: number; backoffSeconds?: number };\n metadata?: Record<string, unknown>;\n}\n\nexport interface ManifestWebhook extends ManifestPrimitiveBase {\n kind: PrimitiveKind.WEBHOOK;\n schemas?: { query?: JSONSchema; headers?: JSONSchema; body?: JSONSchema };\n}\n\nexport interface ManifestPreProcessor extends ManifestPrimitiveBase {\n kind: PrimitiveKind.PREPROCESSOR;\n isAsync?: boolean;\n /** Execution priority (lower runs first; default 100). Surfaces source-declared priority on push. */\n priority?: number;\n}\n\nexport interface ManifestPostProcessor extends ManifestPrimitiveBase {\n kind: PrimitiveKind.POSTPROCESSOR;\n /** Execution priority (lower runs first; default 100). Surfaces source-declared priority on push. */\n priority?: number;\n}\n\nexport interface ManifestMCPServer extends ManifestPrimitiveBase {\n kind: PrimitiveKind.MCP_SERVER;\n config?: Record<string, unknown>;\n /** Whether the url property is a resolver function (bundled in artifact) */\n hasUrlResolver?: boolean;\n /** Whether the headers property is a resolver function (bundled in artifact) */\n hasHeadersResolver?: boolean;\n}\n\nexport interface ManifestAgent extends ManifestPrimitiveBase {\n kind: PrimitiveKind.AGENT;\n persona: PersonaText;\n /** Static model string (e.g., 'openai/gpt-4o') */\n model?: string;\n /** Whether the model property is a resolver function (bundled in artifact) */\n hasModelResolver?: boolean;\n /** Per-call sampling settings (temperature, topP, maxOutputTokens, …). Passthrough to Mastra. */\n modelSettings?: Record<string, unknown>;\n /** Per-agent message batching/debounce configuration */\n batching?: {\n firstMessageDelayMs?: number;\n debounceWindowMs?: number;\n maxBatchMessages?: number;\n serializeProcessing?: boolean;\n };\n /** Governance policy configuration */\n governance?: GovernanceConfig;\n /**\n * Voices linked to this agent, in `voices: [...]` order. Each entry is a\n * primitive name; resolved to a server `voiceId` at push time. Each\n * channel picks which one fires via `channelConfig.<kind>.voiceId`.\n */\n voiceRefs?: { name: string }[];\n}\n\nexport interface ManifestDeviceTrigger extends ManifestPrimitiveBase {\n kind: PrimitiveKind.DEVICE_TRIGGER;\n schemas?: { payload?: JSONSchema };\n}\n\nexport interface ManifestDevice extends ManifestPrimitiveBase {\n kind: PrimitiveKind.DEVICE;\n group?: string;\n}\n\nexport interface ManifestVoice extends ManifestPrimitiveBase {\n kind: PrimitiveKind.VOICE;\n /** Normalized discriminated union — Inference (descriptor route) or direct plugin. */\n llm: LuaVoiceModel;\n // Optional for realtime LLMs: full mode skips both, half-cascade keeps only `tts`.\n stt?: LuaVoiceModel;\n tts?: LuaVoiceModel;\n vad?: string;\n /** Silero VAD tuning forwarded to `silero.VAD.load(...)` on the worker. */\n vadOptions?: {\n minSpeechDuration?: number;\n minSilenceDuration?: number;\n prefixPaddingDuration?: number;\n activationThreshold?: number;\n };\n turnDetection?: string;\n greeting?: string;\n maxToolSteps?: number;\n userAwayTimeout?: number;\n preemptiveGeneration?: boolean;\n sttLanguage?: string;\n /** Whether the LuaVoice declares an `interruption` config block. */\n hasInterruption?: boolean;\n /** Presence flags for lifecycle hooks declared on the LuaVoice. */\n hasOnEnter?: boolean;\n hasOnUserTurnCompleted?: boolean;\n hasOnExit?: boolean;\n /** Whether the LuaVoice declares voice-only tools (in addition to skill tools). */\n hasTools?: boolean;\n /** Krisp telephony BVC noise cancellation (opt-in). Resolver flips this on the wire response. */\n krispEnabled?: boolean;\n /** Ambient + thinking sounds. Worker resolves clip-name strings → BuiltinAudioClip. */\n backgroundAudio?: { ambient?: unknown; thinking?: unknown };\n /** Output volume 0-100. Applied per-frame in the compiled `ttsNode` override. */\n volume?: number;\n /** Pre-TTS word-boundary text replacements. Case-insensitive. */\n pronunciations?: Record<string, string>;\n /** When true, the worker writes `session.history` to `Data['call:<sessionId>']` on close. */\n persistTranscript?: boolean;\n /** Spoken phrase played once per failed tool call before the LLM's recovery response. */\n onToolFailureSay?: string;\n /** AgentSession interruption knobs — `mode`, `falseInterruptionTimeout`, etc. */\n interruption?: {\n enabled?: boolean;\n mode?: 'adaptive' | 'vad';\n falseInterruptionTimeout?: number;\n resumeFalseInterruption?: boolean;\n minDelay?: number;\n maxDelay?: number;\n };\n}\n\nexport type ManifestPrimitive =\n | ManifestTool\n | ManifestSkill\n | ManifestJob\n | ManifestWebhook\n | ManifestPreProcessor\n | ManifestPostProcessor\n | ManifestMCPServer\n | ManifestAgent\n | ManifestDevice\n | ManifestDeviceTrigger\n | ManifestVoice;\n\n// =============================================================================\n// COMPILATION MANIFEST\n// =============================================================================\n\nexport interface CompilationManifest {\n version: string;\n compiledAt: string;\n primitives: ManifestPrimitive[];\n projectFiles: ProjectFile[];\n config: { packageJson?: string; tsconfigJson?: string; luaSkillYaml?: string };\n}\n","import { DevVersionResponse, UpdateDevVersionResponse } from '../interfaces/dev.js';\nimport { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport {\n GetSkillsResponse,\n DeleteSkillResponse,\n CreateSkillRequest,\n CreateSkillResponse,\n PushSkillVersionRequest,\n GetSkillVersionsResponse,\n} from '../interfaces/skills.js';\nimport type {\n AttachSkillSourcePayload as AttachSkillSourceRequest,\n AttachSkillSourceResponse,\n} from '@lua/shared-source-sync';\n\n/**\n * Skill API calls\n */\nexport default class SkillApi extends HttpClient {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of SkillApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Retrieves all skills for the agent\n * @returns Promise resolving to an ApiResponse containing an array of skills with their versions and tools\n * @throws Error if the API request fails or the agent is not found\n */\n async getSkills(): Promise<ApiResponse<GetSkillsResponse>> {\n return this.httpGet<GetSkillsResponse>(`/developer/skills/${this.agentId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Creates a new skill for the agent\n * @param skillData - The skill data including name, description, and optional context\n * @returns Promise resolving to an ApiResponse containing the created skill details\n * @throws Error if the skill creation fails or validation errors occur\n */\n async createSkill(skillData: CreateSkillRequest): Promise<ApiResponse<CreateSkillResponse>> {\n return this.httpPost<CreateSkillResponse>(`/developer/skills/${this.agentId}`, skillData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Pushes a new version of a skill to production\n * @param skillId - The unique identifier of the skill\n * @param versionData - The version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the created version details\n * @throws Error if the skill is not found or the push operation fails\n */\n async pushSkill(skillId: string, versionData: PushSkillVersionRequest): Promise<ApiResponse<DevVersionResponse>> {\n return this.httpPost<DevVersionResponse>(`/developer/skills/${this.agentId}/${skillId}/version`, versionData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Pushes a new development/sandbox version of a skill for testing\n * @param skillId - The unique identifier of the skill\n * @param versionData - The version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the development version details\n * @throws Error if the skill is not found or the push operation fails\n */\n async pushDevSkill(skillId: string, versionData: PushSkillVersionRequest): Promise<ApiResponse<DevVersionResponse>> {\n return this.httpPost<DevVersionResponse>(\n `/developer/skills/${this.agentId}/${skillId}/version/sandbox`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Updates an existing development/sandbox version of a skill\n * @param skillId - The unique identifier of the skill\n * @param sandboxVersionId - The unique identifier of the sandbox version to update\n * @param versionData - The updated version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the updated version details\n * @throws Error if the skill or version is not found or the update fails\n */\n async updateDevSkill(\n skillId: string,\n sandboxVersionId: string,\n versionData: PushSkillVersionRequest\n ): Promise<ApiResponse<UpdateDevVersionResponse>> {\n return this.httpPut<UpdateDevVersionResponse>(\n `/developer/skills/${this.agentId}/${skillId}/version/sandbox/${sandboxVersionId}`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Retrieves all versions of a specific skill\n * @param skillId - The unique identifier of the skill\n * @returns Promise resolving to an ApiResponse containing an array of skill versions\n * @throws Error if the skill is not found or the request fails\n */\n async getSkillVersions(skillId: string): Promise<ApiResponse<GetSkillVersionsResponse>> {\n return this.httpGet<GetSkillVersionsResponse>(`/developer/skills/${this.agentId}/${skillId}/versions`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Publishes a specific version of a skill to production\n * @param skillId - The unique identifier of the skill\n * @param version - The version identifier to publish\n * @returns Promise resolving to an ApiResponse containing publication confirmation details\n * @throws Error if the skill or version is not found or the publish operation fails\n */\n async publishSkillVersion(\n skillId: string,\n version: string\n ): Promise<ApiResponse<{ message: string; skillId: string; activeVersionId: string; publishedAt: string }>> {\n return this.httpPut<{ message: string; skillId: string; activeVersionId: string; publishedAt: string }>(\n `/developer/skills/${this.agentId}/${skillId}/${version}/publish`,\n undefined,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Deletes a skill and all its versions, or deactivates it if it has versions\n * @param skillId - The unique identifier of the skill to delete\n * @returns Promise resolving to an ApiResponse with deletion status\n * - If deleted is true: skill was successfully deleted\n * - If deleted is false and deactivated is true: skill has versions and was deactivated instead\n * @throws Error if the skill is not found or the delete operation fails\n */\n async deleteSkill(skillId: string): Promise<ApiResponse<DeleteSkillResponse>> {\n return this.httpDelete<DeleteSkillResponse>(`/developer/skills/${this.agentId}/${skillId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Attach TS source + workspace archive to a skill version. Powers\n * `lua push --include-source` so the admin Builder UI can render the\n * source without waiting for the next UI-driven build.\n */\n async attachSkillSource(\n skillId: string,\n version: string,\n body: AttachSkillSourceRequest\n ): Promise<ApiResponse<AttachSkillSourceResponse>> {\n return this.httpPut<AttachSkillSourceResponse>(\n `/developer/skills/${this.agentId}/${skillId}/version/${encodeURIComponent(version)}/source`,\n body,\n { Authorization: `Bearer ${this.apiKey}` }\n );\n }\n}\n\nexport type { AttachSkillSourceRequest, AttachSkillSourceResponse };\n","/**\n * Artifact Loader Utilities\n *\n * Utilities for loading compilation artifacts from the new compiler output (dist-v2/).\n * Used by push, test, and dev commands.\n */\n\nimport fs from 'fs';\nimport path from 'path';\nimport zlib from 'zlib';\nimport type { PersonaText } from '@lua/shared-types';\nimport type { CompilationManifest, ManifestPrimitive, ManifestAgent } from '../compiler/types.js';\nimport { PrimitiveKind } from '../compiler/types.js';\nimport { COMPILE_DIRS, COMPILE_FILES } from '../config/compile.constants.js';\n\n// =============================================================================\n// MANIFEST LOADING\n// =============================================================================\n\n/**\n * Load the compilation manifest from dist-v2/manifest.json.\n *\n * @param projectPath - Path to the project root (defaults to cwd)\n * @returns The compilation manifest\n * @throws Error if manifest not found or invalid\n */\nexport function loadManifest(projectPath: string = process.cwd()): CompilationManifest {\n const manifestPath = path.join(projectPath, COMPILE_DIRS.DIST_V2, COMPILE_FILES.MANIFEST_JSON);\n\n if (!fs.existsSync(manifestPath)) {\n throw new Error(\n `Manifest not found at ${manifestPath}. ` + `Run \"lua compile\" first to generate the compilation output.`\n );\n }\n\n try {\n const content = fs.readFileSync(manifestPath, 'utf-8');\n return JSON.parse(content);\n } catch (error: any) {\n throw new Error(`Failed to parse manifest: ${error.message}`);\n }\n}\n\n/**\n * Check if the compilation output exists.\n *\n * @param projectPath - Path to the project root\n * @returns true if dist-v2/manifest.json exists\n */\nexport function hasCompilationOutput(projectPath: string = process.cwd()): boolean {\n const manifestPath = path.join(projectPath, COMPILE_DIRS.DIST_V2, COMPILE_FILES.MANIFEST_JSON);\n return fs.existsSync(manifestPath);\n}\n\n// =============================================================================\n// ARTIFACT LOADING\n// =============================================================================\n\n/**\n * Load a primitive artifact (bundled JS code) from disk.\n *\n * @param primitive - The primitive from the manifest\n * @param projectPath - Path to the project root\n * @returns The artifact code as a string\n */\nexport function loadArtifact(primitive: ManifestPrimitive, projectPath: string = process.cwd()): string {\n const artifactPath = path.join(projectPath, COMPILE_DIRS.DIST_V2, primitive.path);\n\n if (!fs.existsSync(artifactPath)) {\n throw new Error(`Artifact not found: ${artifactPath}`);\n }\n\n return fs.readFileSync(artifactPath, 'utf-8');\n}\n\n/**\n * Load a primitive artifact and its metadata JSON.\n *\n * @param primitive - The primitive from the manifest\n * @param projectPath - Path to the project root\n * @returns Object with code and metadata\n */\nexport function loadArtifactWithMetadata(\n primitive: ManifestPrimitive,\n projectPath: string = process.cwd()\n): { code: string; metadata: Record<string, any> } {\n const code = loadArtifact(primitive, projectPath);\n\n // Load metadata JSON (same name but .json extension)\n const metadataPath = path.join(\n projectPath,\n COMPILE_DIRS.DIST_V2,\n path.join(path.dirname(primitive.path), path.basename(primitive.path, '.js') + '.json')\n );\n\n let metadata = {};\n if (fs.existsSync(metadataPath)) {\n metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf-8'));\n }\n\n return { code, metadata };\n}\n\n/**\n * Load source map for a primitive (if it exists).\n *\n * @param primitive - The primitive from the manifest\n * @param projectPath - Path to the project root\n * @returns The source map string or null if not found\n */\nexport function loadSourceMap(primitive: ManifestPrimitive, projectPath: string = process.cwd()): string | null {\n const sourceMapPath = path.join(projectPath, COMPILE_DIRS.DIST_V2, primitive.path + '.map');\n\n if (!fs.existsSync(sourceMapPath)) {\n return null;\n }\n\n return fs.readFileSync(sourceMapPath, 'utf-8');\n}\n\n// =============================================================================\n// COMPRESSION (for push)\n// =============================================================================\n\n/**\n * Compress code for pushing to server.\n * Uses gzip + base64 encoding (matches server expectation).\n *\n * @param code - The artifact code to compress\n * @returns Base64-encoded gzipped code\n */\nexport function compressForPush(code: string): string {\n const compressed = zlib.gzipSync(Buffer.from(code, 'utf-8'));\n return compressed.toString('base64');\n}\n\n/**\n * Compress code for presigned S3 upload.\n * Returns raw gzip bytes (no base64 encoding).\n * Used with hashBundle and ensureBundlesUploaded for content-addressed upload.\n *\n * @param code - The artifact code to compress\n * @returns Raw gzipped bytes as Buffer\n */\nexport function compressForPushRaw(code: string): Buffer {\n return zlib.gzipSync(Buffer.from(code, 'utf-8'));\n}\n\n/**\n * Decompress code from server format.\n *\n * @param compressed - Base64-encoded gzipped code\n * @returns The decompressed code\n */\nexport function decompressFromServer(compressed: string): string {\n const buffer = Buffer.from(compressed, 'base64');\n const decompressed = zlib.gunzipSync(buffer);\n return decompressed.toString('utf-8');\n}\n\n// =============================================================================\n// SOURCE TS LOADING (for canonical-source attach)\n// =============================================================================\n\n/**\n * Forward-compat marker for the source-archive layout. Must stay in lockstep\n * with `ARCHIVE_SCHEMA_VERSION` in lua-claude-builder's\n * `canonical-source.archive.ts` — that constant is what the Builder reads when\n * deciding whether it understands an archive.\n */\nexport const SOURCE_ARCHIVE_SCHEMA_VERSION = 1;\n\n/** Maximum byte size of an individual file we'll archive — protects against accidentally archiving large blobs. Matches the Builder's MAX_FILE_BYTES guard. */\nconst MAX_SOURCE_FILE_BYTES = 256 * 1024;\n\n/**\n * Read a tool's original TS source file from disk, given its `sourcePath`\n * field on the manifest entry. Returns `null` when the file is missing or\n * unreadable so the caller can omit `tools[].source` rather than fail the\n * whole push — the server already treats absent source as \"not attached\"\n * (back-compat with older CLI clients).\n */\nexport function loadOriginalSource(sourcePath: string | undefined, projectPath: string = process.cwd()): string | null {\n if (!sourcePath) return null;\n try {\n const abs = path.isAbsolute(sourcePath) ? sourcePath : path.join(projectPath, sourcePath);\n if (!fs.existsSync(abs)) return null;\n const size = fs.statSync(abs).size;\n if (size > MAX_SOURCE_FILE_BYTES) return null;\n return fs.readFileSync(abs, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/**\n * Normalize a tool's `sourcePath` into a relative-to-project, posix-style key\n * suitable for a `sourceArchive` map. Idempotent for already-relative paths;\n * falls back to the bare `sourcePath` if normalization can't make it relative\n * (e.g. on a different drive on Windows). The archive consumer\n * (`canonical-source.archive.writeArchiveToWorkspace`) rejects any key\n * containing `..`, so we strip those defensively.\n */\nexport function normalizeEntryFile(sourcePath: string | undefined, projectPath: string = process.cwd()): string | null {\n if (!sourcePath) return null;\n let rel: string;\n if (path.isAbsolute(sourcePath)) {\n rel = path.relative(projectPath, sourcePath);\n } else {\n rel = sourcePath;\n }\n if (rel.startsWith('..') || rel.includes(`..${path.sep}`)) return null;\n return rel.split(path.sep).join('/');\n}\n\n/**\n * Build a sourceArchive payload (gzip(JSON.stringify({relPath: contents})) →\n * base64) from a list of `{ entryFile, source }` pairs. Format matches\n * `canonical-source.archive.decodeWorkspaceArchive` on the Builder side.\n *\n * Returns `null` when the file map is empty so the caller can omit the\n * `sourceArchive` field entirely (vs. shipping an archive that decodes to an\n * empty workspace, which the Builder treats identically but adds payload\n * weight for nothing).\n */\nexport function buildSourceArchive(files: Array<{ entryFile: string; source: string }>): string | null {\n if (files.length === 0) return null;\n const map: Record<string, string> = {};\n for (const { entryFile, source } of files) {\n if (entryFile.includes('..')) continue;\n map[entryFile] = source;\n }\n if (Object.keys(map).length === 0) return null;\n const json = JSON.stringify(map);\n const gz = zlib.gzipSync(Buffer.from(json, 'utf-8'));\n return gz.toString('base64');\n}\n\n// =============================================================================\n// PRIMITIVE FILTERING\n// =============================================================================\n\n/**\n * Get primitives of a specific kind from the manifest.\n *\n * @param manifest - The compilation manifest\n * @param kind - The primitive kind to filter by\n * @returns Array of primitives matching the kind\n */\nexport function getPrimitivesByKind<T extends ManifestPrimitive>(\n manifest: CompilationManifest,\n kind: PrimitiveKind\n): T[] {\n return manifest.primitives.filter((p) => p.kind === kind) as T[];\n}\n\n/**\n * Find a primitive by name and kind.\n *\n * @param manifest - The compilation manifest\n * @param name - The primitive name\n * @param kind - Optional kind to filter by\n * @returns The primitive or undefined\n */\nexport function findPrimitive<T extends ManifestPrimitive>(\n manifest: CompilationManifest,\n name: string,\n kind?: T['kind']\n): T | undefined {\n return manifest.primitives.find((p) => {\n if (kind && p.kind !== kind) return false;\n return p.name === name;\n }) as T | undefined;\n}\n\n// =============================================================================\n// SINGLE PRIMITIVE LOOKUP\n// =============================================================================\n\n/**\n * Find the first primitive of a given kind from the manifest.\n * Generic version — works for any primitive kind.\n */\nexport function getFirstPrimitiveByKind<T extends ManifestPrimitive>(\n kind: PrimitiveKind,\n projectPath: string = process.cwd()\n): T | null {\n if (!hasCompilationOutput(projectPath)) return null;\n const manifest = loadManifest(projectPath);\n return (manifest.primitives.find((p) => p.kind === kind) as T) ?? null;\n}\n\n// =============================================================================\n// AGENT CONVENIENCE (delegates to generic lookup)\n// =============================================================================\n\nexport function getAgentName(projectPath: string = process.cwd()): string | null {\n return getFirstPrimitiveByKind<ManifestAgent>(PrimitiveKind.AGENT, projectPath)?.name ?? null;\n}\n\nexport function getAgentPersona(projectPath: string = process.cwd()): PersonaText | null {\n return getFirstPrimitiveByKind<ManifestAgent>(PrimitiveKind.AGENT, projectPath)?.persona ?? null;\n}\n\nexport function getAgentModel(projectPath: string = process.cwd()): string | null {\n return getFirstPrimitiveByKind<ManifestAgent>(PrimitiveKind.AGENT, projectPath)?.model ?? null;\n}\n\nexport function getAgentGovernance(projectPath: string = process.cwd()): ManifestAgent['governance'] | null {\n return getFirstPrimitiveByKind<ManifestAgent>(PrimitiveKind.AGENT, projectPath)?.governance ?? null;\n}\n\n// =============================================================================\n// BATCH LOADING\n// =============================================================================\n\n/**\n * Load all artifacts of a specific kind.\n *\n * @param manifest - The compilation manifest\n * @param kind - The primitive kind\n * @param projectPath - Path to the project root\n * @returns Array of { primitive, code } objects\n */\nexport function loadAllArtifactsOfKind(\n manifest: CompilationManifest,\n kind: PrimitiveKind,\n projectPath: string = process.cwd()\n): Array<{ primitive: ManifestPrimitive; code: string }> {\n return getPrimitivesByKind(manifest, kind).map((primitive) => ({\n primitive,\n code: loadArtifact(primitive, projectPath),\n }));\n}\n","/**\n * Backup API Service\n *\n * Handles all backup-related API calls using S3 blob storage.\n * Content is stored in S3, keyed by content hash for deduplication.\n */\n\nimport { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport {\n BackupMetadata,\n BackupManifest,\n BackupExistsResponse,\n CheckBlobsRequest,\n CheckBlobsResponse,\n SaveManifestRequest,\n GetBlobUrlsRequest,\n GetBlobUrlsResponse,\n} from '../interfaces/backup.js';\n\nexport interface BackupVersionSummary {\n version: number;\n createdAt: string;\n createdBy: string;\n triggeredBy?: string;\n projectHash: string;\n}\n\nexport interface BackupVersionsResponse {\n versions: BackupVersionSummary[];\n}\n\n/**\n * Backup API client for project source backup operations\n */\nexport class BackupApi extends HttpClient {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of BackupApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n // ===========================================================================\n // BLOB OPERATIONS (S3)\n // ===========================================================================\n\n /**\n * Check which blobs exist in S3.\n * Called first to determine which files need to be uploaded.\n *\n * @param hashes - Array of content hashes to check\n * @returns Promise resolving to missing/existing hash lists\n */\n async checkBlobsExist(hashes: string[]): Promise<ApiResponse<CheckBlobsResponse>> {\n const data: CheckBlobsRequest = { hashes };\n return this.httpPost<CheckBlobsResponse>(`/developer/agents/${this.agentId}/backup/check-blobs`, data, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Get presigned URLs for downloading blobs from S3.\n * Used by download to fetch files in parallel directly from S3.\n *\n * @param hashes - Array of content hashes to get URLs for\n * @returns Promise resolving to map of hash -> presigned URL\n */\n async getBlobUrls(hashes: string[]): Promise<ApiResponse<GetBlobUrlsResponse>> {\n const data: GetBlobUrlsRequest = { hashes };\n return this.httpPost<GetBlobUrlsResponse>(`/developer/agents/${this.agentId}/backup/blob-urls`, data, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Get presigned URLs for uploading blobs directly to S3.\n * Used by push to upload files in parallel directly to S3, bypassing the server.\n *\n * @param hashes - Array of content hashes to get upload URLs for\n * @returns Promise resolving to map of hash -> presigned upload URL\n */\n async getBlobUploadUrls(hashes: string[]): Promise<ApiResponse<GetBlobUrlsResponse>> {\n const data: GetBlobUrlsRequest = { hashes };\n return this.httpPost<GetBlobUrlsResponse>(`/developer/agents/${this.agentId}/backup/blob-upload-urls`, data, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n // ===========================================================================\n // MANIFEST OPERATIONS (MongoDB)\n // ===========================================================================\n\n /**\n * Save backup manifest after blobs are uploaded.\n * Final step in the backup flow.\n *\n * @param data - Manifest data with file references\n * @returns Promise resolving to backup metadata\n */\n async saveManifest(data: SaveManifestRequest): Promise<ApiResponse<BackupMetadata>> {\n return this.httpPost<BackupMetadata>(`/developer/agents/${this.agentId}/backup/manifest`, data, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Get backup metadata without file list.\n * Used to check if backup exists and get basic info.\n *\n * @returns Promise resolving to backup metadata\n */\n async getBackupMetadata(): Promise<ApiResponse<BackupMetadata>> {\n return this.httpGet<BackupMetadata>(`/developer/agents/${this.agentId}/backup`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Get backup manifest with file list.\n * Use getBlobUrls to get download URLs for the content.\n *\n * @returns Promise resolving to backup manifest with file refs\n */\n async getBackupManifest(): Promise<ApiResponse<BackupManifest>> {\n return this.httpGet<BackupManifest>(`/developer/agents/${this.agentId}/backup/manifest`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Check if backup with given hash exists.\n * Allows skipping upload if backup is already up-to-date.\n *\n * @param hash - Project hash to check\n * @returns Promise resolving to existence check result\n */\n async checkBackupExists(hash: string): Promise<ApiResponse<BackupExistsResponse>> {\n return this.httpGet<BackupExistsResponse>(`/developer/agents/${this.agentId}/backup/check/${hash}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Get the list of backup versions for this agent.\n *\n * @param all - If true, lifts the server-side 50-version cap\n * @returns Promise resolving to the list of version summaries (newest first)\n */\n async getBackupVersions(all = false): Promise<ApiResponse<BackupVersionsResponse>> {\n const qs = all ? '?all=true' : '';\n return this.httpGet<BackupVersionsResponse>(`/developer/agents/${this.agentId}/backup/versions${qs}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n}\n\n// Named re-export for backward-compat consumers that do `import BackupApi from ...`\nexport default BackupApi;\n","/**\n * Bundle Upload Utilities\n *\n * Handles hashing, existence checking, and S3 presigned upload for primitive code bundles.\n * Enables content-addressed deduplication and delta uploads.\n */\n\nimport crypto from 'crypto';\nimport BackupApi from '../api/backup.api.service.js';\nimport { BASE_URLS } from '../config/constants.js';\n\n/**\n * Computes SHA256 hash over raw gzipped bytes.\n *\n * @param rawGzip - Raw gzipped bundle bytes (Buffer from compressForPushRaw)\n * @returns SHA256 hex digest\n */\nexport function hashBundle(rawGzip: Buffer): string {\n return crypto.createHash('sha256').update(rawGzip).digest('hex');\n}\n\n/**\n * Telemetry stats returned by `ensureBundlesUploaded` so call sites can\n * report delta-upload hit rate (existed in S3 vs newly uploaded) without\n * having to re-derive the partition.\n */\nexport interface BundleUploadStats {\n /** Total distinct hashes the push asked about. */\n total: number;\n /** Hashes the server confirmed already existed in S3 (no PUT issued). */\n alreadyExisted: number;\n /** Hashes that required an actual PUT to S3. */\n uploaded: number;\n}\n\n/**\n * Ensures all bundles are uploaded to S3 via presigned URLs.\n * Handles the full flow:\n * 1. Call /developer/agents/{agentId}/backup/blob-upload-urls to mint URLs\n * 2. Call /developer/agents/{agentId}/backup/check-blobs to determine missing/existing partition\n * 3. For each missing hash, PUT raw gzip bytes to presigned URL\n * 4. Resolve on success; throw with hash + status on any PUT failure\n *\n * @param apiKey - API key for authentication\n * @param agentId - Agent ID for the presigned URL endpoint\n * @param bundles - Map of hash → raw gzip Buffer bytes\n * @returns Stats covering total / alreadyExisted / uploaded for telemetry\n * @throws Error with hash and status if any PUT fails\n */\nexport async function ensureBundlesUploaded(\n apiKey: string,\n agentId: string,\n bundles: Map<string, Buffer>\n): Promise<BundleUploadStats> {\n // Empty map — nothing to upload\n if (bundles.size === 0) {\n return { total: 0, alreadyExisted: 0, uploaded: 0 };\n }\n\n const api = new BackupApi(BASE_URLS.API, apiKey, agentId);\n const hashes = Array.from(bundles.keys());\n\n // Step 1: Get presigned URLs\n const urlResponse = await api.getBlobUploadUrls(hashes);\n\n if (!urlResponse.success) {\n throw new Error(`Failed to get presigned upload URLs: ${urlResponse.error?.message}`);\n }\n\n const uploadUrls = urlResponse.data!.urls;\n\n // Step 2: Check which blobs already exist in S3\n const existsResponse = await api.checkBlobsExist(hashes);\n\n if (!existsResponse.success) {\n throw new Error(`Failed to check blob existence: ${existsResponse.error?.message}`);\n }\n\n const missing = existsResponse.data!.missing;\n\n // Step 3: Upload missing bundles with bounded parallelism via a worker-pool\n // (queue + N workers). Avoids the polling latency of a busy-wait semaphore\n // and stops as soon as the queue is drained.\n const concurrencyLimit = 8;\n const queue = [...missing];\n\n const uploadOne = async (hash: string): Promise<void> => {\n const url = uploadUrls[hash];\n if (!url) {\n throw new Error(`No presigned URL provided for hash ${hash}`);\n }\n const rawGzip = bundles.get(hash);\n if (!rawGzip) {\n throw new Error(`Bundle buffer not found for hash ${hash}`);\n }\n const response = await fetch(url, {\n method: 'PUT',\n body: rawGzip,\n headers: { 'Content-Type': 'application/octet-stream' },\n });\n if (!response.ok) {\n throw new Error(`S3 PUT failed for hash ${hash}: ${response.status} ${response.statusText}`);\n }\n };\n\n const workers = Array.from({ length: Math.min(concurrencyLimit, queue.length) }, async () => {\n while (queue.length > 0) {\n const hash = queue.shift();\n if (hash !== undefined) {\n await uploadOne(hash);\n }\n }\n });\n\n await Promise.all(workers);\n\n return {\n total: hashes.length,\n alreadyExisted: hashes.length - missing.length,\n uploaded: missing.length,\n };\n}\n","/**\n * Semantic Versioning Utilities\n */\n\n/**\n * Parses a semantic version string into its components.\n * Supports standard semver (X.Y.Z) and pre-release tags (X.Y.Z-tag).\n *\n * @param version The version string to parse\n * @returns Object containing major, minor, patch, and preRelease components\n */\nexport function parseVersion(version: string) {\n const [versionPart, preReleasePart] = version.split('-');\n const [major, minor, patch] = versionPart.split('.').map(Number);\n const preRelease = preReleasePart ? preReleasePart.split('+')[0] : null;\n\n return {\n major: isNaN(major) ? 0 : major,\n minor: isNaN(minor) ? 0 : minor,\n patch: isNaN(patch) ? 0 : patch,\n preRelease,\n };\n}\n\n/**\n * Compares two semantic version strings.\n *\n * @param version1 First version string\n * @param version2 Second version string\n * @returns number:\n * - negative if version1 < version2\n * - positive if version1 > version2\n * - 0 if version1 === version2\n */\nexport function compareVersions(version1: string, version2: string): number {\n const v1 = parseVersion(version1);\n const v2 = parseVersion(version2);\n\n // Compare major.minor.patch first\n if (v1.major !== v2.major) return v1.major - v2.major;\n if (v1.minor !== v2.minor) return v1.minor - v2.minor;\n if (v1.patch !== v2.patch) return v1.patch - v2.patch;\n\n // If major.minor.patch are equal, compare pre-release identifiers\n // A version without a pre-release tag is always greater than one with a tag\n if (v1.preRelease && !v2.preRelease) return -1; // pre-release is lower than release\n if (!v1.preRelease && v2.preRelease) return 1; // release is higher than pre-release\n if (!v1.preRelease && !v2.preRelease) return 0; // both are releases\n\n // Both have pre-release identifiers, compare them\n const preReleaseOrder = ['alpha', 'beta', 'rc', 'preview', 'dev'];\n\n const getPreReleaseType = (preRelease: string) => {\n // Extract the type part (e.g., \"alpha\" from \"alpha.1\")\n const type = preRelease.toLowerCase().split('.')[0].replace(/[0-9]/g, '');\n const index = preReleaseOrder.indexOf(type);\n return index === -1 ? preReleaseOrder.length : index; // Unknown types go to end\n };\n\n const type1 = getPreReleaseType(v1.preRelease!);\n const type2 = getPreReleaseType(v2.preRelease!);\n\n if (type1 !== type2) return type1 - type2;\n\n // Same pre-release type, compare the full pre-release string lexicographically\n // or try to compare numeric parts if they exist (e.g., alpha.1 vs alpha.2)\n const getPreReleaseNum = (preRelease: string) => {\n const parts = preRelease.split('.');\n const num = parts.length > 1 ? parseInt(parts[parts.length - 1], 10) : -1;\n return isNaN(num) ? -1 : num;\n };\n\n const num1 = getPreReleaseNum(v1.preRelease!);\n const num2 = getPreReleaseNum(v2.preRelease!);\n\n if (num1 !== -1 && num2 !== -1 && num1 !== num2) {\n return num1 - num2;\n }\n\n return v1.preRelease!.localeCompare(v2.preRelease!);\n}\n\n/**\n * Increments the patch version automatically (e.g., 1.0.0 → 1.0.1).\n * Preserves pre-release tag if present.\n *\n * @param version - Current version string (or undefined/null for first version)\n * @returns Incremented version string\n */\nexport function incrementPatchVersion(version: string | undefined | null): string {\n // Handle undefined/null version - return default starting version\n if (!version) {\n return '0.0.1';\n }\n\n const parsed = parseVersion(version);\n const newPatch = parsed.patch + 1;\n const preRelease = parsed.preRelease ? `-${parsed.preRelease}` : '';\n\n return `${parsed.major}.${parsed.minor}.${newPatch}${preRelease}`;\n}\n\n/**\n * Returns the higher of two semantic version strings.\n */\nexport function maxSemver(a: string, b: string): string {\n return compareVersions(a, b) >= 0 ? a : b;\n}\n","/**\n * Base Primitive Handler\n *\n * Abstract base class providing common implementation for primitive handlers.\n * Subclasses implement primitive-specific logic (API calls, active checks, etc.)\n *\n * YAML types come from yaml.types.ts (YamlConfigSkill, YamlConfigWebhook, etc.)\n * Server types come from interfaces/ (Skill, Webhook, Job, etc.)\n */\n\nimport { PrimitiveKind, CompilationManifest, ManifestPrimitive } from '../compiler/types.js';\nimport { YamlConfig } from '../types/yaml.types.js';\nimport { readYamlConfig, writeYamlConfig } from '../utils/files.js';\nimport { SKILL_DEFAULTS } from '../config/compile.constants.js';\nimport {\n findPrimitive,\n loadArtifact,\n compressForPush,\n compressForPushRaw,\n getPrimitivesByKind,\n} from '../utils/artifact-loader.js';\nimport { hashBundle } from '../utils/bundle-upload.js';\nimport { maxSemver } from '../utils/semver.js';\nimport { AuthenticationError } from '../errors/auth.error.js';\nimport type {\n VersionedPrimitiveHandler,\n PrimitiveHandler,\n SyncResult,\n ServerSyncData,\n YamlPrimitiveConfig,\n} from './types.js';\n\n/** Default version for new primitives */\nexport const DEFAULT_VERSION = SKILL_DEFAULTS.VERSION;\n\n// =============================================================================\n// BASE VERSIONED HANDLER\n// =============================================================================\n\n/**\n * Abstract base class for versioned primitive handlers.\n *\n * T = the YAML item type (from yaml.types.ts, e.g. YamlConfigSkill).\n * Must have at least { name: string; version: string; [idField]: string }.\n */\nexport abstract class BaseVersionedHandler<\n T extends { name: string; version: string },\n TPushData = Record<string, unknown>,\n> implements VersionedPrimitiveHandler<T> {\n abstract readonly kind: PrimitiveKind;\n abstract readonly displayName: string;\n abstract readonly displayNamePlural: string;\n abstract readonly deleteCommand: string;\n abstract readonly yamlConfig: YamlPrimitiveConfig;\n\n protected abstract getApi(apiKey: string, agentId: string): unknown;\n protected abstract fetchFromServer(api: unknown): Promise<any[] | null>;\n /**\n * Strip a YAML item to only the canonical fields: name, version, [idField].\n * Override if your YAML type has additional fields.\n */\n cleanItem(item: T): T {\n return {\n name: item.name || '',\n version: item.version || DEFAULT_VERSION,\n [this.yamlConfig.idField]: this.getItemId(item) || '',\n } as T;\n }\n\n /**\n * Whether a server entity is considered active (for orphan detection).\n * Default: true. Override for primitives with active/status fields.\n */\n isActive(_serverItem: any): boolean {\n return true;\n }\n\n /**\n * Get the active version string from a server entity.\n * Default: finds version with isActive === true. Override for different field names.\n */\n getActiveVersion(serverItem: any): string | null {\n const active = serverItem.versions?.find((v: any) => v.isActive === true);\n return active?.version ?? null;\n }\n\n protected getServerItemName(item: any): string {\n return item.name || 'unknown';\n }\n\n protected shouldConsiderForOrphan(_item: any): boolean {\n return true;\n }\n\n // ===========================================================================\n // SERVER SYNC\n // ===========================================================================\n\n /**\n * Fetches server items and merges with local YAML for interactive delete/trigger prompts.\n * Local items take priority for shared IDs; server-only orphans are appended as minimal\n * cleanItem objects. On server failure, returns local items only with an empty orphan set.\n */\n async fetchMergedForInteraction(\n apiKey: string,\n agentId: string,\n config: YamlConfig\n ): Promise<{ merged: T[]; orphanIds: Set<string>; serverFailed: boolean }> {\n const serverData = await this.fetchServerState(apiKey, agentId);\n const localItems = this.getFromYaml(config);\n\n if (!serverData.serverItems) {\n return { merged: localItems, orphanIds: new Set<string>(), serverFailed: true };\n }\n\n const serverItems = serverData.serverItems;\n const orphanIds = new Set(\n serverItems.filter((s) => !localItems.some((l) => this.getItemId(l) === s.id)).map((s) => s.id as string)\n );\n\n const merged = serverItems.map((s) => {\n const local = localItems.find((l) => this.getItemId(l) === s.id);\n if (local) return local;\n return this.cleanItem({\n name: s.name,\n version: this.getActiveVersion(s) ?? '',\n [this.yamlConfig.idField]: s.id,\n } as unknown as T);\n });\n\n return { merged, orphanIds, serverFailed: false };\n }\n\n /** Phase 1 of parallel sync: fetch server state (HTTP only, no YAML writes) */\n async fetchServerState(apiKey: string, agentId: string): Promise<ServerSyncData> {\n try {\n const api = this.getApi(apiKey, agentId);\n const serverItems = await this.fetchFromServer(api);\n return { serverItems };\n } catch (error) {\n if (AuthenticationError.isAuthenticationError(error)) throw error;\n return { serverItems: null, fetchError: error instanceof Error ? error.message : String(error) };\n }\n }\n\n /**\n * Phase 2 of parallel sync: apply fetched data to YAML.\n * Optionally creates missing primitives on server if apiKey+agentId provided.\n */\n async applySyncToYaml(\n serverData: ServerSyncData,\n config: YamlConfig | null,\n manifest?: CompilationManifest,\n apiCredentials?: { apiKey: string; agentId: string }\n ): Promise<SyncResult> {\n const messages: string[] = [];\n let yamlUpdated = false;\n let orphanedCount = 0;\n\n try {\n if (!serverData.serverItems) {\n if (serverData.fetchError) {\n console.error(`❌ Error syncing server ${this.displayNamePlural}: ${serverData.fetchError}`);\n } else {\n console.warn(`⚠️ Could not retrieve server ${this.displayNamePlural}. Skipping sync.`);\n }\n return { messages, yamlUpdated, orphanedCount };\n }\n\n const yamlItems = this.getFromYaml(config);\n const { yamlById, yamlByName, serverByName } = this.buildMaps(serverData.serverItems, yamlItems);\n\n // Part 1: Detect orphaned items\n const orphans = serverData.serverItems.filter((item) => {\n const id = item.id as string;\n const name = item.name as string;\n return !yamlById.has(id) && !yamlByName.has(name) && this.isActive(item) && this.shouldConsiderForOrphan(item);\n });\n\n if (orphans.length > 0) {\n // Stub server-only primitives into YAML so `lua sync` can classify them\n // as `missing-locally` and resolve them via backup restore.\n const idField = this.yamlConfig.idField;\n const stubs = orphans.map((item) =>\n this.cleanItem({\n name: item.name,\n version: this.getActiveVersion(item) || DEFAULT_VERSION,\n [idField]: item.id || '',\n } as unknown as T)\n );\n\n yamlItems.push(...stubs);\n yamlUpdated = true;\n\n const flagName = `--${this.displayName.toLowerCase().replace(/\\s+/g, '-')}-name`;\n console.log(`\\n⚠️ Found ${this.displayNamePlural} on server not in your local code:`);\n for (const item of orphans) {\n const msg = ` - ${this.getServerItemName(item)}`;\n messages.push(msg);\n console.log(msg);\n }\n console.log(` Added to lua.skill.yaml as server-only entries.`);\n console.log(` To remove from server: ${this.deleteCommand} ${flagName} <name>`);\n console.log(` To restore source from backup: lua sync --accept\\n`);\n orphanedCount = orphans.length;\n }\n\n // Part 2: Sync IDs and versions from server → YAML\n const { items: updatedItems, changed, msgs } = this.syncFromServer(yamlItems, serverByName);\n messages.push(...msgs);\n\n if (changed) {\n yamlUpdated = true;\n console.log(`✅ YAML ${this.displayNamePlural} synced with server`);\n }\n\n if (yamlUpdated) {\n this.updateYaml(updatedItems, config);\n }\n\n // Part 3: Create primitives that don't exist on server (if manifest + credentials provided)\n if (manifest && apiCredentials) {\n const api = this.getApi(apiCredentials.apiKey, apiCredentials.agentId);\n const { created, updated: creationUpdated } = await this.createMissingOnServer(api, manifest);\n if (created.length > 0) {\n messages.push(...created.map((name) => `Created \"${name}\" on server`));\n yamlUpdated = yamlUpdated || creationUpdated;\n }\n }\n\n if (orphans.length === 0 && !changed) {\n console.log(`✅ Server ${this.displayNamePlural} and YAML are fully in sync`);\n }\n } catch (error) {\n console.error(`❌ Error syncing server ${this.displayNamePlural}:`, error);\n }\n\n return { messages, yamlUpdated, orphanedCount };\n }\n\n async syncWithServer(\n apiKey: string,\n agentId: string,\n config: YamlConfig | null,\n manifest?: CompilationManifest\n ): Promise<SyncResult> {\n const serverData = await this.fetchServerState(apiKey, agentId);\n return this.applySyncToYaml(serverData, config, manifest, { apiKey, agentId });\n }\n\n // ===========================================================================\n // CREATE ON SERVER\n // ===========================================================================\n\n /**\n * Create a primitive on the server. Subclasses must implement this.\n * @param api - The API instance\n * @param primitive - The manifest primitive with name, description, and type-specific fields\n * @returns The server-assigned ID for the created primitive, or null on failure.\n */\n protected abstract createOnServer(api: unknown, primitive: ManifestPrimitive): Promise<string | null>;\n\n /**\n * Create primitives that have empty IDs in YAML.\n * Called internally by syncWithServer when manifest is provided.\n */\n private async createMissingOnServer(\n api: unknown,\n manifest: CompilationManifest\n ): Promise<{ created: string[]; updated: boolean }> {\n const created: string[] = [];\n let updated = false;\n\n const config = readYamlConfig();\n const items = this.getFromYaml(config);\n const itemsWithoutId = items.filter((item) => !this.getItemId(item));\n\n if (itemsWithoutId.length === 0) {\n return { created, updated };\n }\n\n console.log(`\\n🔧 Creating ${itemsWithoutId.length} new ${this.displayNamePlural} on server...`);\n\n for (const item of itemsWithoutId) {\n // Find the primitive in the manifest to get description and other metadata\n const manifestPrimitive = findPrimitive(manifest, item.name, this.kind);\n if (!manifestPrimitive) {\n console.error(` ❌ \"${item.name}\" not found in manifest - cannot create`);\n continue;\n }\n\n try {\n const newId = await this.createOnServer(api, manifestPrimitive);\n if (newId) {\n // Update the item with the new ID\n const updatedConfig = readYamlConfig();\n const updatedItems = this.getFromYaml(updatedConfig);\n const idx = updatedItems.findIndex((i) => i.name === item.name);\n if (idx >= 0) {\n (updatedItems[idx] as Record<string, unknown>)[this.yamlConfig.idField] = newId;\n this.updateYaml(updatedItems, updatedConfig);\n updated = true;\n }\n console.log(` ✅ Created \"${item.name}\" (ID: ${newId})`);\n created.push(item.name);\n } else {\n console.error(` ❌ Failed to create \"${item.name}\" - no ID returned`);\n }\n } catch (error) {\n console.error(` ❌ Failed to create \"${item.name}\": ${error instanceof Error ? error.message : error}`);\n }\n }\n\n if (created.length > 0) {\n console.log(`✅ Created ${created.length} ${this.displayNamePlural} on server`);\n }\n\n return { created, updated };\n }\n\n // ===========================================================================\n // YAML OPERATIONS\n // ===========================================================================\n\n updateYaml(items: T[], config: YamlConfig | null): void {\n const updatedConfig = {\n ...(config || {}),\n [this.yamlConfig.yamlKey]: items.map((item) => this.cleanItem(item)),\n };\n writeYamlConfig(updatedConfig);\n }\n\n getFromYaml(config: YamlConfig | null): T[] {\n if (!config) return [];\n const items = config[this.yamlConfig.yamlKey];\n return (Array.isArray(items) ? items : []) as unknown as T[];\n }\n\n syncYamlWithManifest(manifest: CompilationManifest, config: YamlConfig | null): void {\n const manifestNames = manifest.primitives.filter((p) => p.kind === this.kind).map((p) => p.name);\n\n if (manifestNames.length === 0) return;\n\n const existing = this.getFromYaml(config);\n const idField = this.yamlConfig.idField;\n\n // Keep existing items still in manifest, add new ones\n const kept = existing.filter((item) => manifestNames.includes(item.name)).map((item) => this.cleanItem(item));\n\n for (const name of manifestNames) {\n if (!kept.some((item) => item.name === name)) {\n kept.push(this.cleanItem({ name, version: DEFAULT_VERSION, [idField]: '' } as T));\n }\n }\n\n this.updateYaml(kept, config);\n }\n\n updateVersionInYaml(name: string, newVersion: string, options?: { silent?: boolean }): void {\n try {\n const config = readYamlConfig();\n if (!config) {\n if (options?.silent) return;\n throw new Error('lua.skill.yaml not found');\n }\n\n const items = this.getFromYaml(config);\n const item = items.find((i) => i.name === name);\n\n if (!item) {\n if (options?.silent) return;\n throw new Error(`${this.displayName} \"${name}\" not found in configuration`);\n }\n\n item.version = newVersion;\n this.updateYaml(items, config);\n } catch (error) {\n if (options?.silent) {\n console.warn(`⚠️ Could not update ${this.displayName} version in YAML:`, error);\n return;\n }\n throw error;\n }\n }\n\n // ===========================================================================\n // PUSH\n // ===========================================================================\n\n prepareForPush(\n manifest: CompilationManifest,\n name: string,\n projectPath: string = process.cwd(),\n bundleAccumulator?: Map<string, Buffer>\n ): Record<string, unknown> | null {\n const primitive = findPrimitive(manifest, name, this.kind);\n if (!primitive) return null;\n\n const code = loadArtifact(primitive, projectPath);\n\n // BAC-196: when a bundle accumulator is provided, hash the raw gzip and\n // emit `codeS3Hash` instead of inline `code`. The push command will\n // upload all accumulated bundles via presigned PUT before POSTing the\n // version metadata. When no accumulator is provided (legacy callers),\n // fall back to the inline gzip+base64 `code` path.\n if (bundleAccumulator) {\n const rawGzip = compressForPushRaw(code);\n const codeS3Hash = hashBundle(rawGzip);\n bundleAccumulator.set(codeS3Hash, rawGzip);\n return this.buildPushData(primitive, undefined, codeS3Hash);\n }\n\n const compressedCode = compressForPush(code);\n return this.buildPushData(primitive, compressedCode);\n }\n\n protected buildPushData(\n primitive: ManifestPrimitive,\n compressedCode: string | undefined,\n codeS3Hash?: string\n ): Record<string, unknown> {\n return {\n name: primitive.name,\n description: primitive.description,\n ...(codeS3Hash ? { codeS3Hash } : { code: compressedCode }),\n };\n }\n\n /**\n * Push a new version to the server.\n * Each handler implements the type-specific API call.\n */\n abstract pushToServer(\n apiKey: string,\n agentId: string,\n entityId: string,\n pushData: TPushData\n ): Promise<{ success: boolean; error?: string }>;\n\n /**\n * Deploy/publish a version on the server.\n * Each handler implements the type-specific API call.\n */\n abstract publishVersion(\n apiKey: string,\n agentId: string,\n entityId: string,\n version: string\n ): Promise<{ success: boolean; error?: string }>;\n\n /**\n * Get the highest version string from the server for conflict avoidance.\n */\n async getHighestServerVersion(apiKey: string, agentId: string, entityId: string): Promise<string | null> {\n // Go through fetchServerState (not fetchFromServer directly) so handler\n // overrides apply — DeviceHandler / DeviceTriggerHandler override\n // fetchServerState to silently degrade on auth/network errors because\n // the Device Gateway is feature-gated. Calling fetchFromServer directly\n // would bypass that override and re-throw auth errors as fatal, blocking\n // `lua push all` entirely for agents without device-gateway access.\n const { serverItems } = await this.fetchServerState(apiKey, agentId);\n if (!serverItems) return null;\n\n // Find the entity by ID\n const entity = serverItems.find((item: any) => item.id === entityId);\n if (!entity?.versions || !Array.isArray(entity.versions)) return null;\n\n // Exclude sandbox versions — they live in the same versions[] array\n // as production versions and would otherwise leak into production\n // auto-bump (e.g. `1.0.21-sandbox` → next push tagged `1.0.22-sandbox`).\n const versions: string[] = entity.versions\n .map((v: any) => v.version)\n .filter((v: any): v is string => typeof v === 'string' && !v.includes('-sandbox'));\n\n if (versions.length === 0) return null;\n\n return versions.reduce((highest, v) => maxSemver(highest, v), '0.0.0');\n }\n\n /**\n * Fetch all server items once, extract highest version for each entity ID.\n * More efficient than calling getHighestServerVersion() per entity.\n */\n async batchGetHighestVersions(\n apiKey: string,\n agentId: string,\n entityIds: string[]\n ): Promise<Map<string, string | null>> {\n const result = new Map<string, string | null>();\n\n // See getHighestServerVersion for the rationale on routing through\n // fetchServerState rather than calling fetchFromServer directly.\n const { serverItems } = await this.fetchServerState(apiKey, agentId);\n if (!serverItems) {\n entityIds.forEach((id) => result.set(id, null));\n return result;\n }\n\n for (const entityId of entityIds) {\n const entity = serverItems.find((item: any) => item.id === entityId);\n if (!entity?.versions || !Array.isArray(entity.versions)) {\n result.set(entityId, null);\n continue;\n }\n // Exclude sandbox versions — see getHighestServerVersion for rationale.\n const versions: string[] = entity.versions\n .map((v: any) => v.version)\n .filter((v: any): v is string => typeof v === 'string' && !v.includes('-sandbox'));\n result.set(entityId, versions.length > 0 ? versions.reduce((h, v) => maxSemver(h, v), '0.0.0') : null);\n }\n\n return result;\n }\n\n // ===========================================================================\n // INTERNAL\n // ===========================================================================\n\n /** Get the server ID from a YAML item using the configured idField. */\n protected getItemId(item: T): string {\n return ((item as Record<string, unknown>)[this.yamlConfig.idField] as string) || '';\n }\n\n protected buildMaps(\n serverItems: any[],\n yamlItems: T[]\n ): {\n yamlById: Map<string, T>;\n yamlByName: Map<string, T>;\n serverByName: Map<string, any>;\n } {\n const yamlById = new Map<string, T>();\n const yamlByName = new Map<string, T>();\n\n for (const item of yamlItems) {\n const id = this.getItemId(item);\n if (id) yamlById.set(id, item);\n yamlByName.set(item.name, item);\n }\n\n const serverByName = new Map<string, any>();\n for (const item of serverItems) {\n serverByName.set(item.name, item);\n }\n\n return { yamlById, yamlByName, serverByName };\n }\n\n /**\n * For each YAML item, match to server by name, populate missing IDs, update versions.\n */\n protected syncFromServer(\n yamlItems: T[],\n serverByName: Map<string, any>\n ): { items: T[]; changed: boolean; msgs: string[] } {\n const msgs: string[] = [];\n let changed = false;\n const idField = this.yamlConfig.idField;\n\n const items = yamlItems.map((item) => {\n const serverItem = serverByName.get(item.name);\n if (!serverItem) return item;\n\n let updated = { ...item };\n\n // Populate missing server ID\n if (!this.getItemId(item) && serverItem.id) {\n const msg = `🔗 Linked \"${item.name}\" ${this.displayName} to server (ID: ${serverItem.id})`;\n msgs.push(msg);\n console.log(msg);\n changed = true;\n updated = { ...updated, [idField]: serverItem.id };\n }\n\n // Update version if server has a newer active one\n const versions = serverItem.versions as unknown[];\n if (Array.isArray(versions) && versions.length > 0) {\n const activeVersion = this.getActiveVersion(serverItem);\n const currentVersion = item.version;\n\n if (activeVersion && activeVersion !== currentVersion) {\n const msg = `📝 Updated \"${item.name}\" ${this.displayName} version: ${currentVersion} → ${activeVersion}`;\n msgs.push(msg);\n console.log(msg);\n changed = true;\n updated = { ...updated, version: activeVersion };\n }\n }\n\n return updated;\n });\n\n return { items, changed, msgs };\n }\n}\n\n// =============================================================================\n// BASE NON-VERSIONED HANDLER\n// =============================================================================\n\n/**\n * Result returned by upsertOnServer. Handlers create-or-update in a single call,\n * so the server-assigned id flows back here.\n */\nexport interface UpsertResult {\n success: boolean;\n id?: string;\n active?: boolean;\n error?: string;\n}\n\n/**\n * Aggregate result of pushing every bundled item in one go.\n */\nexport interface PushAllResult {\n pushed: string[];\n failed: Array<{ name: string; error: string }>;\n activated: string[];\n}\n\n/**\n * For primitives without versions (e.g., MCP servers).\n *\n * Two generic parameters:\n * T — shape of items stored in lua.skill.yaml (see yaml.types.ts)\n * B — shape of items pushed to the server (bundled from the manifest).\n * Defaults to T for handlers where the YAML and push payloads match.\n */\nexport abstract class BaseNonVersionedHandler<\n T extends { name: string },\n B extends { name: string } = T,\n> implements PrimitiveHandler<T> {\n abstract readonly kind: PrimitiveKind;\n abstract readonly displayName: string;\n abstract readonly displayNamePlural: string;\n abstract readonly deleteCommand: string;\n abstract readonly yamlConfig: YamlPrimitiveConfig;\n\n protected abstract getApi(apiKey: string, agentId: string): unknown;\n protected abstract fetchFromServer(api: unknown): Promise<any[] | null>;\n abstract cleanItem(item: T): T;\n protected abstract isActive(item: any): boolean;\n\n /**\n * Load bundled items from the compilation manifest, ready to push.\n * Each item must have a `name`; other fields are handler-specific.\n */\n abstract loadBundledItems(projectPath?: string): B[];\n\n /**\n * Create-or-update a single item on the server. Returns the server-assigned\n * id. Implementations SHOULD call persistItemId after a successful upsert\n * so the id is tracked locally from the first push.\n */\n abstract upsertOnServer(apiKey: string, agentId: string, item: B): Promise<UpsertResult>;\n\n /**\n * Optional hook run after a successful upsert when autoDeploy is set.\n * Default: no-op. Handlers override for post-upsert actions (e.g. MCP\n * activation). Return true if the action fired and succeeded.\n */\n protected async postUpsert(_item: B, _upsert: UpsertResult, _apiKey: string, _agentId: string): Promise<boolean> {\n return false;\n }\n\n protected getServerItemName(item: any): string {\n return item.name || 'unknown';\n }\n\n /** Phase 1 of parallel sync: fetch server state (HTTP only, no YAML writes) */\n async fetchServerState(apiKey: string, agentId: string): Promise<ServerSyncData> {\n try {\n const api = this.getApi(apiKey, agentId);\n const serverItems = await this.fetchFromServer(api);\n return { serverItems };\n } catch (error) {\n if (AuthenticationError.isAuthenticationError(error)) throw error;\n return { serverItems: null, fetchError: error instanceof Error ? error.message : String(error) };\n }\n }\n\n /** Phase 2 of parallel sync: apply fetched data to YAML (orphan detection only for non-versioned) */\n async applySyncToYaml(\n serverData: ServerSyncData,\n config: YamlConfig | null,\n manifest?: CompilationManifest\n ): Promise<SyncResult> {\n const messages: string[] = [];\n let yamlUpdated = false;\n let orphanedCount = 0;\n\n try {\n if (!serverData.serverItems) {\n if (serverData.fetchError) {\n console.error(`❌ Error syncing server ${this.displayNamePlural}: ${serverData.fetchError}`);\n } else {\n console.warn(`⚠️ Could not retrieve server ${this.displayNamePlural}. Skipping sync.`);\n }\n return { messages, yamlUpdated, orphanedCount };\n }\n\n const yamlItems = this.getFromYaml(config);\n const idField = this.yamlConfig.idField;\n\n const getId = (item: T) => ((item as Record<string, unknown>)[idField] as string) || '';\n const yamlById = new Map(yamlItems.filter((i) => getId(i)).map((i) => [getId(i), i]));\n const yamlByName = new Map(yamlItems.map((i) => [i.name, i]));\n\n // Names present in the current compilation manifest are considered \"in local code\"\n // even if they haven't been pushed yet (and therefore have no YAML entry).\n // This prevents newly compiled MCP servers from being flagged as orphans.\n const manifestNames = manifest\n ? new Set(getPrimitivesByKind(manifest, this.kind).map((p: any) => p.name as string))\n : new Set<string>();\n\n const orphans = serverData.serverItems.filter((item) => {\n const id = item.id as string;\n const name = item.name as string;\n return !yamlById.has(id) && !yamlByName.has(name) && !manifestNames.has(name) && this.isActive(item);\n });\n\n if (orphans.length > 0) {\n // See BaseVersionedHandler.applySyncToYaml for rationale.\n const stubs = orphans.map((item) =>\n this.cleanItem({\n name: item.name,\n [idField]: item.id || '',\n } as unknown as T)\n );\n this.updateYaml([...yamlItems, ...stubs], config);\n yamlUpdated = true;\n\n const flagName = `--${this.displayName.toLowerCase().replace(/\\s+/g, '-')}-name`;\n console.log(`\\n⚠️ Found ${this.displayNamePlural} on server not in your local code:`);\n for (const item of orphans) {\n const msg = ` - ${this.getServerItemName(item)}`;\n messages.push(msg);\n console.log(msg);\n }\n console.log(` Added to lua.skill.yaml as server-only entries.`);\n console.log(` To remove from server: ${this.deleteCommand} ${flagName} <name>`);\n console.log(` To restore source from backup: lua sync --accept\\n`);\n orphanedCount = orphans.length;\n } else {\n console.log(`✅ Server ${this.displayNamePlural} and YAML are fully in sync`);\n }\n } catch (error) {\n console.error(`❌ Error syncing server ${this.displayNamePlural}:`, error);\n }\n\n return { messages, yamlUpdated, orphanedCount };\n }\n\n async syncWithServer(\n apiKey: string,\n agentId: string,\n config: YamlConfig | null,\n manifest?: CompilationManifest\n ): Promise<SyncResult> {\n const serverData = await this.fetchServerState(apiKey, agentId);\n return this.applySyncToYaml(serverData, config, manifest);\n }\n\n updateYaml(items: T[], config: YamlConfig | null): void {\n const updatedConfig = {\n ...(config || {}),\n [this.yamlConfig.yamlKey]: items.map((item) => this.cleanItem(item)),\n };\n writeYamlConfig(updatedConfig);\n }\n\n getFromYaml(config: YamlConfig | null): T[] {\n if (!config) return [];\n const items = config[this.yamlConfig.yamlKey];\n return (Array.isArray(items) ? items : []) as unknown as T[];\n }\n\n prepareForPush(_manifest: CompilationManifest, _name: string, _projectPath?: string): Record<string, unknown> | null {\n return null;\n }\n\n /**\n * Write a server-assigned id back into lua.skill.yaml for the given item,\n * using the handler's configured idField. Creates a new YAML entry if none\n * exists yet (first-push case).\n */\n persistItemId(name: string, id: string): void {\n const config = readYamlConfig();\n const items = this.getFromYaml(config);\n const idField = this.yamlConfig.idField;\n const existing = items.find((i) => i.name === name);\n if (existing) {\n (existing as Record<string, unknown>)[idField] = id;\n } else {\n items.push({ name, [idField]: id } as unknown as T);\n }\n this.updateYaml(items, config);\n }\n\n /**\n * Push the given bundled items to the server:\n * 1. Upsert each on the server (create or update by name).\n * 2. persistItemId is expected to run inside upsertOnServer so the\n * server-assigned id is tracked locally from the first push.\n * 3. When autoDeploy is set, run the postUpsert hook per successfully\n * pushed item.\n *\n * Caller passes in pre-loaded items (loadBundledItems) so push.ts can\n * decide what to print up front without reading the manifest twice.\n *\n * Error semantics: upsert failures add the item to `failed`; postUpsert\n * failures don't — the push itself already succeeded, only the follow-up\n * step (e.g. activation) failed. Activation errors surface via a warn\n * so they're visible without polluting the failed[] list.\n *\n * Upsert-by-name is idempotent, so a mid-loop crash self-heals on the next\n * run — ids flow back on subsequent calls for anything not yet persisted.\n */\n async pushAll(\n items: B[],\n apiKey: string,\n agentId: string,\n options: { autoDeploy?: boolean } = {}\n ): Promise<PushAllResult> {\n const result: PushAllResult = { pushed: [], failed: [], activated: [] };\n if (items.length === 0) return result;\n\n for (const item of items) {\n let upsert: UpsertResult;\n try {\n upsert = await this.upsertOnServer(apiKey, agentId, item);\n } catch (error) {\n result.failed.push({\n name: item.name,\n error: error instanceof Error ? error.message : String(error),\n });\n continue;\n }\n\n if (!upsert.success) {\n result.failed.push({ name: item.name, error: upsert.error || 'unknown error' });\n continue;\n }\n result.pushed.push(item.name);\n\n if (!options.autoDeploy) continue;\n\n try {\n const activated = await this.postUpsert(item, upsert, apiKey, agentId);\n if (activated) result.activated.push(item.name);\n } catch (error) {\n // postUpsert failure doesn't invalidate the push — the server has\n // the new config, only the follow-up step failed. Warn for\n // visibility without adding the item to failed[] (which would\n // imply the push itself failed).\n console.warn(\n `⚠️ ${item.name} pushed but post-upsert action failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n return result;\n }\n}\n","/**\n * Skill Handler\n *\n * Skills have special behavior:\n * - Custom syncYamlWithManifest (logs success message)\n * - Orphan detection only considers CLI-sourced skills\n * - Uses 'active' field on versions (not 'isActive')\n * - Custom prepareForPush with tools array\n */\n\nimport { hasPersonaTextContent } from '@lua/shared-types';\nimport {\n PrimitiveKind,\n CompilationManifest,\n ManifestPrimitive,\n ManifestSkill,\n ManifestTool,\n} from '../compiler/types.js';\nimport { YamlConfig, YamlConfigSkill } from '../types/yaml.types.js';\nimport { BASE_URLS } from '../config/constants.js';\nimport SkillApi from '../api/skills.api.service.js';\nimport type { PushSkillVersionRequest } from '../interfaces/skills.js';\nimport { BaseVersionedHandler } from './base.handler.js';\nimport {\n findPrimitive,\n loadArtifact,\n compressForPush,\n loadOriginalSource,\n normalizeEntryFile,\n buildSourceArchive,\n compressForPushRaw,\n SOURCE_ARCHIVE_SCHEMA_VERSION,\n} from '../utils/artifact-loader.js';\nimport { hashBundle } from '../utils/bundle-upload.js';\n\nimport { readYamlConfig, writeYamlConfig } from '../utils/files.js';\nimport type { YamlPrimitiveConfig, SyncResult } from './types.js';\n\nexport class SkillHandler extends BaseVersionedHandler<YamlConfigSkill, PushSkillVersionRequest> {\n readonly kind = PrimitiveKind.SKILL;\n readonly displayName = 'skill';\n readonly displayNamePlural = 'skills';\n readonly deleteCommand = 'lua skills delete';\n readonly yamlConfig: YamlPrimitiveConfig = {\n yamlKey: 'skills',\n idField: 'skillId',\n };\n\n protected getApi(apiKey: string, agentId: string): SkillApi {\n return new SkillApi(BASE_URLS.API, apiKey, agentId);\n }\n\n protected async fetchFromServer(api: SkillApi): Promise<any[] | null> {\n const response = await api.getSkills();\n if (!response.success || !response.data?.skills) return null;\n return response.data.skills;\n }\n\n protected async createOnServer(api: SkillApi, primitive: ManifestPrimitive): Promise<string | null> {\n const skill = primitive as ManifestSkill;\n // Omit context entirely when there's no real content — the API field is\n // optional and @IsPersonaText() rejects empty strings / empty objects to\n // match the SDK push gate. Use the same hasPersonaTextContent predicate\n // so this stays in lockstep with server-side validation.\n const response = await api.createSkill({\n name: skill.name,\n description: skill.description || `A Lua skill for ${skill.name}`,\n ...(hasPersonaTextContent(skill.context) ? { context: skill.context } : {}),\n });\n if (!response.success || !response.data?.id) return null;\n return response.data.id;\n }\n\n isActive(serverItem: any): boolean {\n return serverItem.active !== false;\n }\n\n /**\n * Skills use 'active' field on versions (not 'isActive').\n */\n getActiveVersion(serverItem: any): string | null {\n const active = serverItem.versions?.find((v: any) => v.active === true);\n return active?.version ?? null;\n }\n\n protected shouldConsiderForOrphan(serverItem: any): boolean {\n return serverItem.source === 'cli' || !serverItem.source;\n }\n\n // ===========================================================================\n // YAML — override to handle legacy single-skill format\n // ===========================================================================\n\n getFromYaml(config: YamlConfig | null): YamlConfigSkill[] {\n if (!config) return [];\n\n if (config.skills && Array.isArray(config.skills) && config.skills.length > 0) {\n return config.skills.map((skill) => ({\n name: skill.name || '',\n version: skill.version || '',\n skillId: skill.skillId || '',\n }));\n }\n\n if (config.skill) {\n const legacy = config.skill;\n return [\n {\n name: legacy.name || 'unnamed-skill',\n version: legacy.version || '',\n skillId: legacy.skillId || '',\n },\n ];\n }\n\n return [];\n }\n\n updateVersionInYaml(name: string, newVersion: string, options?: { silent?: boolean }): void {\n try {\n const config = readYamlConfig();\n if (!config) {\n if (options?.silent) return;\n throw new Error('lua.skill.yaml not found');\n }\n\n let updated = false;\n\n if (config.skills && Array.isArray(config.skills)) {\n const skill = config.skills.find((s: YamlConfigSkill) => s.name === name);\n if (skill) {\n skill.version = newVersion;\n updated = true;\n }\n }\n\n if (!updated && config.skill) {\n const legacy = config.skill;\n if (legacy.name === name || name === 'unnamed-skill') {\n legacy.version = newVersion;\n updated = true;\n }\n }\n\n if (!updated) {\n if (options?.silent) return;\n throw new Error(`Skill \"${name}\" not found in configuration`);\n }\n\n writeYamlConfig(config);\n } catch (error) {\n if (options?.silent) {\n console.warn(`⚠️ Could not update skill version in YAML:`, error);\n return;\n }\n throw error;\n }\n }\n\n syncYamlWithManifest(manifest: CompilationManifest, config: YamlConfig | null): void {\n super.syncYamlWithManifest(manifest, config);\n if (manifest.primitives.some((p) => p.kind === this.kind)) {\n console.log('✅ YAML synced with manifest');\n }\n }\n\n // ===========================================================================\n // PUSH — custom to include tools array\n // ===========================================================================\n\n async pushToServer(apiKey: string, agentId: string, entityId: string, pushData: PushSkillVersionRequest) {\n const api = this.getApi(apiKey, agentId);\n const response = await api.pushSkill(entityId, { ...pushData, skillId: entityId });\n return { success: response.success, error: response.error?.message };\n }\n\n async publishVersion(apiKey: string, agentId: string, entityId: string, version: string) {\n const api = this.getApi(apiKey, agentId);\n const response = await api.publishSkillVersion(entityId, version);\n return { success: response.success, error: response.error?.message };\n }\n\n prepareForPush(\n manifest: CompilationManifest,\n name: string,\n projectPath: string = process.cwd(),\n bundleAccumulator?: Map<string, Buffer>\n ): Record<string, unknown> | null {\n const skill = findPrimitive<ManifestSkill>(manifest, name, PrimitiveKind.SKILL);\n if (!skill) return null;\n\n // Track per-tool source so we can also build a skill-level `sourceArchive`\n // alongside the per-tool `source` fields. Both formats are accepted by the\n // canonical-source store; per-tool source unlocks the Builder UI's\n // tool-level edit, the archive unlocks workspace hydration on the\n // conversational Builder side. Shipping both is cheap and matches the\n // server schema (`tools[].source` + `sourceArchive` are both optional).\n const archiveEntries: Array<{ entryFile: string; source: string }> = [];\n\n const tools = (skill.tools || [])\n .map((toolName: string) => {\n const tool = findPrimitive<ManifestTool>(manifest, toolName, PrimitiveKind.TOOL);\n if (!tool) return null;\n\n const code = loadArtifact(tool, projectPath);\n\n let toolData: Record<string, unknown>;\n\n // BAC-196: when an accumulator is supplied, emit `codeS3Hash` and\n // queue raw gzip for presigned upload. Otherwise use inline path.\n if (bundleAccumulator) {\n const rawGzip = compressForPushRaw(code);\n const codeS3Hash = hashBundle(rawGzip);\n bundleAccumulator.set(codeS3Hash, rawGzip);\n\n toolData = {\n name: tool.name,\n description: tool.description,\n inputSchema: tool.schemas?.input || undefined,\n codeS3Hash,\n };\n if (tool.hasCondition) {\n // Condition shares the same compiled artifact, so same hash works.\n toolData.condition = codeS3Hash;\n }\n } else {\n const compressedCode = compressForPush(code);\n toolData = {\n name: tool.name,\n description: tool.description,\n inputSchema: tool.schemas?.input || undefined,\n code: compressedCode,\n };\n if (tool.hasCondition) {\n toolData.condition = compressedCode;\n }\n }\n\n // Attach original TS source. Best-effort: when sourcePath is missing or\n // the file is unreadable, `loadOriginalSource` returns null and we omit\n // both fields. The server treats absent source as \"not attached\" — same\n // behaviour as older CLI clients that never sent it. Source metadata is\n // independent of bundle delivery mode (inline `code` vs `codeS3Hash`),\n // so it applies to both BAC-196 and inline paths.\n const source = loadOriginalSource(tool.sourcePath, projectPath);\n const entryFile = normalizeEntryFile(tool.sourcePath, projectPath);\n if (source && entryFile) {\n toolData.source = source;\n toolData.entryFile = entryFile;\n archiveEntries.push({ entryFile, source });\n }\n\n return toolData;\n })\n .filter(Boolean);\n\n const sourceArchive = buildSourceArchive(archiveEntries);\n\n return {\n name: skill.name,\n description: skill.description,\n // Same gate as createOnServer — server validator rejects empty content.\n ...(hasPersonaTextContent(skill.context) ? { context: skill.context } : {}),\n tools,\n ...(sourceArchive\n ? {\n sourceArchive,\n archiveSchemaVersion: SOURCE_ARCHIVE_SCHEMA_VERSION,\n }\n : {}),\n };\n }\n}\n\nexport const skillHandler = new SkillHandler();\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport pkg from 'js-yaml';\nconst { load, dump } = pkg;\nimport { COMPILE_FILES, YAML_FORMAT } from '../config/compile.constants.js';\nimport { YamlConfig } from '../types/yaml.types.js';\nimport { skillHandler } from '../primitives/skill.handler.js';\n\n// =============================================================================\n// CONFIG VALIDATION\n// =============================================================================\n\n/**\n * Validates that configuration has required fields.\n * Acts as a type guard - after calling this, TypeScript knows config is not null.\n *\n * @param config - Skill configuration\n * @throws Error if configuration is invalid\n */\nexport function validateSkillConfig(config: YamlConfig | null): asserts config is YamlConfig {\n if (!config) {\n throw new Error('No lua.skill.yaml found. Please run this command from a skill directory.');\n }\n\n if (!config.agent?.agentId) {\n throw new Error('Missing agentId in skill configuration');\n }\n\n // If skills are defined, they must have skillIds (i.e. been compiled and pushed)\n const skills = skillHandler.getFromYaml(config);\n if (skills.length > 0 && !skills.some((s) => s.skillId)) {\n throw new Error('Skills are missing skillId. Please compile and push your skill first.');\n }\n}\n\n/**\n * Copies template files to target directory.\n *\n * @param templateDir - Source template directory\n * @param targetDir - Target directory to copy to\n * @param includeExamples - Whether to include the examples/ directory (default: false)\n * @param skipSrcDir - Whether to skip the src/ directory (for backup restoration, default: false)\n */\nexport function copyTemplateFiles(\n templateDir: string,\n targetDir: string,\n includeExamples: boolean = false,\n skipSrcDir: boolean = false\n): void {\n const files = fs.readdirSync(templateDir);\n\n for (const file of files) {\n // Skip node_modules and package-lock.json to avoid circular dependencies\n if (file === 'node_modules' || file === 'package-lock.json') {\n continue;\n }\n\n // Skip examples/ by default (user can include with --with-examples flag)\n if (file === 'examples' && !includeExamples) {\n continue;\n }\n\n // Skip src/ directory if sources were restored from backup\n if (file === 'src' && skipSrcDir) {\n continue;\n }\n\n const srcPath = path.join(templateDir, file);\n const destPath = path.join(targetDir, file);\n\n if (fs.statSync(srcPath).isDirectory()) {\n fs.mkdirSync(destPath, { recursive: true });\n copyTemplateFiles(srcPath, destPath, includeExamples, skipSrcDir);\n } else if (file === 'package.json') {\n // Special handling for package.json to update lua-cli version\n updatePackageJson(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n}\n\nfunction updatePackageJson(srcPath: string, destPath: string): void {\n const templatePackageJson = JSON.parse(fs.readFileSync(srcPath, 'utf8'));\n fs.writeFileSync(destPath, JSON.stringify(templatePackageJson, null, 2) + '\\n');\n}\n\n/**\n * Reads the lua.skill.yaml configuration file from the current working directory.\n *\n * @returns The parsed YAML config or null if file doesn't exist\n */\nexport function readYamlConfig(): YamlConfig | null {\n const yamlPath = path.join(process.cwd(), COMPILE_FILES.LUA_SKILL_YAML);\n\n if (!fs.existsSync(yamlPath)) {\n return null;\n }\n\n const yamlContent = fs.readFileSync(yamlPath, 'utf8');\n return load(yamlContent) as YamlConfig;\n}\n\n/**\n * Update only the agent information in an existing YAML file\n */\nexport function updateYamlAgent(agentId: string, orgId: string): void {\n const config = readYamlConfig();\n\n if (!config) {\n throw new Error('lua.skill.yaml not found');\n }\n\n // Update agent information\n config.agent = config.agent || {};\n config.agent.agentId = agentId;\n config.agent.orgId = orgId;\n\n writeYamlConfig(config);\n}\n\n/**\n * Ensures a given entry is present in the project's .gitignore file.\n * If .gitignore doesn't exist, creates it. If the entry already exists, does nothing.\n * Inserts the entry right after a reference line (e.g. \"dist/\" -> \"dist-v2/\" after it).\n *\n * @param rootDir - Project root directory\n * @param entry - The gitignore entry to ensure (e.g. \"dist-v2/\")\n * @param afterEntry - Optional entry after which to insert (falls back to appending)\n */\nexport function ensureGitignored(rootDir: string, entry: string, afterEntry?: string): void {\n const gitignorePath = path.join(rootDir, '.gitignore');\n\n if (!fs.existsSync(gitignorePath)) {\n fs.writeFileSync(gitignorePath, `${entry}\\n`);\n return;\n }\n\n const content = fs.readFileSync(gitignorePath, 'utf8');\n const lines = content.split('\\n');\n\n // Already present\n if (lines.some((line) => line.trim() === entry)) {\n return;\n }\n\n // Try to insert after the reference entry\n if (afterEntry) {\n const idx = lines.findIndex((line) => line.trim() === afterEntry);\n if (idx !== -1) {\n lines.splice(idx + 1, 0, entry);\n fs.writeFileSync(gitignorePath, lines.join('\\n'));\n return;\n }\n }\n\n // Fallback: append to end\n const trimmed = content.endsWith('\\n') ? content : content + '\\n';\n fs.writeFileSync(gitignorePath, trimmed + entry + '\\n');\n}\n\n/**\n * Checks if .env file exists in the current working directory.\n *\n * @returns True if .env file exists\n */\nexport function hasEnvFile(): boolean {\n return fs.existsSync(path.join(process.cwd(), '.env'));\n}\n\n/**\n * Writes a YAML config file with consistent formatting.\n * Uses yamlKeySorter by default for consistent key ordering.\n *\n * @param config - The configuration object to write\n * @param filePath - Optional custom file path (defaults to lua.skill.yaml in cwd)\n * @param options - Optional YAML dump options\n */\nexport function writeYamlConfig(\n config: YamlConfig,\n filePath?: string,\n options?: {\n sortKeys?: boolean | ((a: string, b: string) => number) | false;\n replacer?: (key: string, value: any) => any;\n }\n): void {\n const yamlPath = filePath || path.join(process.cwd(), COMPILE_FILES.LUA_SKILL_YAML);\n\n // Use yamlKeySorter by default unless explicitly disabled with false\n const sortKeys = options?.sortKeys === false ? false : (options?.sortKeys ?? yamlKeySorter);\n\n const yamlContent = dump(config, {\n indent: YAML_FORMAT.INDENT,\n lineWidth: YAML_FORMAT.LINE_WIDTH,\n noRefs: YAML_FORMAT.NO_REFS,\n sortKeys,\n replacer:\n options?.replacer ||\n ((key: string, value: any) => {\n // Replace undefined values with empty strings by default\n return value === undefined ? '' : value;\n }),\n });\n\n fs.writeFileSync(yamlPath, yamlContent);\n}\n\n/**\n * Standard YAML key sort order for lua.skill.yaml\n */\nexport const YAML_KEY_ORDER = [\n 'agent',\n 'skills',\n 'webhooks',\n 'jobs',\n 'preprocessors',\n 'postprocessors',\n 'mcpServers',\n 'skill',\n];\n\n/**\n * Sort function for YAML keys to maintain consistent ordering\n */\nexport function yamlKeySorter(a: string, b: string): number {\n const aIndex = YAML_KEY_ORDER.indexOf(a);\n const bIndex = YAML_KEY_ORDER.indexOf(b);\n if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;\n if (aIndex !== -1) return -1;\n if (bIndex !== -1) return 1;\n return a.localeCompare(b);\n}\n","/**\n * Version Check Utilities\n * Checks npm registry for the latest lua-cli version and caches the result.\n * Used by the update command (LUA-123) and the outdated version warning (LUA-124).\n */\n\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\nimport { compareVersions, parseVersion } from './semver.js';\nimport { CLI_CONFIG_DIR, VERSION_CHECK_FILE } from '../config/constants.js';\nconst CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours\nconst NPM_REGISTRY_BASE = 'https://registry.npmjs.org/lua-cli';\nconst FETCH_TIMEOUT_MS = 3000;\n\n/**\n * Get the npm registry URL for the appropriate dist-tag.\n * If currentVersion has a pre-release tag (e.g. \"alpha\"), use that dist-tag.\n * Otherwise use \"latest\" (stable releases).\n */\nfunction getRegistryUrl(currentVersion: string): string {\n const { preRelease } = parseVersion(currentVersion);\n if (preRelease) {\n // Extract tag name from pre-release (e.g. \"alpha.9\" → \"alpha\", \"beta.1\" → \"beta\")\n const tag = preRelease.split('.')[0].replace(/[0-9]/g, '');\n if (tag) return `${NPM_REGISTRY_BASE}/${tag}`;\n }\n return `${NPM_REGISTRY_BASE}/latest`;\n}\n\ninterface VersionCheckCache {\n latestVersion: string;\n checkedAt: number;\n}\n\n/**\n * Read cached version check result.\n * Returns null if cache is missing, corrupt, or expired.\n */\nexport function getCachedVersionCheck(): VersionCheckCache | null {\n try {\n if (!existsSync(VERSION_CHECK_FILE)) return null;\n const raw = readFileSync(VERSION_CHECK_FILE, 'utf8');\n const cache: VersionCheckCache = JSON.parse(raw);\n if (Date.now() - cache.checkedAt > CHECK_INTERVAL_MS) return null;\n return cache;\n } catch {\n return null;\n }\n}\n\n/**\n * Save version check result to cache file.\n */\nexport function saveCachedVersionCheck(latestVersion: string): void {\n try {\n if (!existsSync(CLI_CONFIG_DIR)) {\n mkdirSync(CLI_CONFIG_DIR, { recursive: true });\n }\n writeFileSync(VERSION_CHECK_FILE, JSON.stringify({ latestVersion, checkedAt: Date.now() }), 'utf8');\n } catch {\n // Silently ignore write failures (permissions, disk full, etc.)\n }\n}\n\n/**\n * Fetch the latest version from npm registry.\n * Uses the dist-tag matching the current version's pre-release channel (e.g. \"alpha\").\n * Returns null on any failure (network, timeout, parse error).\n */\nexport async function fetchLatestVersion(currentVersion?: string): Promise<string | null> {\n try {\n const url = getRegistryUrl(currentVersion ?? '0.0.0');\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n const response = await fetch(url, { signal: controller.signal });\n clearTimeout(timeout);\n if (!response.ok) return null;\n const data = (await response.json()) as { version?: string };\n return data.version ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if an update is available. Uses 24h cache to avoid hitting npm on every run.\n */\nexport async function isUpdateAvailable(\n currentVersion: string\n): Promise<{ available: boolean; latest: string | null }> {\n const cached = getCachedVersionCheck();\n if (cached) {\n return {\n available: compareVersions(currentVersion, cached.latestVersion) < 0,\n latest: cached.latestVersion,\n };\n }\n\n const latest = await fetchLatestVersion(currentVersion);\n if (!latest) return { available: false, latest: null };\n\n saveCachedVersionCheck(latest);\n return {\n available: compareVersions(currentVersion, latest) < 0,\n latest,\n };\n}\n\n/**\n * Print a boxed update warning to stderr (so piped --json stdout is not corrupted).\n */\nexport function printUpdateWarning(currentVersion: string, latestVersion: string): void {\n const msg = `Update available: ${currentVersion} → ${latestVersion}`;\n const tip = 'Run `lua update` to install the latest version';\n const width = Math.max(msg.length, tip.length) + 6;\n const pad = (s: string) => s + ' '.repeat(width - s.length);\n\n console.error('');\n console.error(` ╭${'─'.repeat(width)}╮`);\n console.error(` │${' '.repeat(width)}│`);\n console.error(` │${pad(' ' + msg)}│`);\n console.error(` │${pad(' ' + tip)}│`);\n console.error(` │${' '.repeat(width)}│`);\n console.error(` ╰${'─'.repeat(width)}╯`);\n console.error('');\n}\n","/**\n * Resolves lua-cli's package root by walking up from `import.meta.url` until\n * it finds a `package.json` with `\"name\": \"lua-cli\"`.\n *\n * Works identically in three modes:\n * - jest/tsc (src/): walks up from src/utils/package-root.ts\n * - bundled dist (esm): walks up from dist/<entry>.js\n * - end-user install: walks up from node_modules/lua-cli/dist/<entry>.js\n *\n * This is the single source of truth for \"where is lua-cli on disk.\" All\n * package-relative resources (version, template/, vendored zod bundle) go\n * through here instead of inlining `__dirname/../../<thing>` walks at call\n * sites — those break when the bundler flattens the dist structure.\n */\n\nimport { readFileSync, existsSync } from 'fs';\nimport { fileURLToPath, pathToFileURL } from 'url';\nimport { dirname, join } from 'path';\n\nlet cachedRoot: string | null = null;\nlet cachedPkg: { name: string; version: string; [k: string]: unknown } | null = null;\n\nfunction locate(): { root: string; pkg: typeof cachedPkg } {\n if (cachedRoot && cachedPkg) return { root: cachedRoot, pkg: cachedPkg };\n\n let dir = dirname(fileURLToPath(import.meta.url));\n while (true) {\n const candidate = join(dir, 'package.json');\n if (existsSync(candidate)) {\n try {\n const parsed = JSON.parse(readFileSync(candidate, 'utf8'));\n if (parsed?.name === 'lua-cli') {\n cachedRoot = dir;\n cachedPkg = parsed;\n return { root: dir, pkg: parsed };\n }\n } catch {\n // Malformed package.json — keep walking.\n }\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error('Could not locate lua-cli package root from ' + fileURLToPath(import.meta.url));\n}\n\nexport function getPackageRoot(): string {\n return locate().root;\n}\n\nexport function getPackageJson(): { name: string; version: string; [k: string]: unknown } {\n return locate().pkg!;\n}\n\nexport function getCliVersion(): string {\n try {\n return locate().pkg!.version;\n } catch {\n return '0.0.0';\n }\n}\n\nexport function getTemplateDir(): string {\n return join(getPackageRoot(), 'template');\n}\n\nexport function getZodRuntimeUrl(): URL {\n // Vendored zod bundle lives at dist/zod-runtime.mjs in published installs.\n // Emitted by scripts/build-vendor.mjs. Use pathToFileURL (not raw string\n // concat) so the resulting URL is valid on Windows, where path.join\n // returns backslash-separated paths.\n return pathToFileURL(join(getPackageRoot(), 'dist', 'zod-runtime.mjs'));\n}\n","/**\n * Analytics Service\n * Non-blocking PostHog telemetry for CLI usage tracking.\n *\n * Opt-out: Set LUA_TELEMETRY=false env var, or run `lua telemetry off`.\n * All tracking is anonymous (hashed API key or machine UUID).\n * Analytics never blocks commands or throws errors to the user.\n */\n\nimport { PostHog } from 'posthog-node';\nimport crypto from 'crypto';\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\nimport { platform, release, arch } from 'os';\nimport { POSTHOG_API_KEY, POSTHOG_HOST, TELEMETRY_FILE, CLI_CONFIG_DIR } from '../config/constants.js';\nimport { getToken, checkApiKey } from '../services/auth.js';\nimport { readYamlConfig } from '../utils/files.js';\n\ninterface TelemetryConfig {\n enabled: boolean;\n anonymousId: string;\n noticeShown: boolean;\n identifiedApiKeyHash?: string;\n identifiedEmail?: string;\n identifiedName?: string;\n}\n\nlet client: PostHog | null = null;\nlet sessionConfig: TelemetryConfig | null = null;\nlet sessionDistinctId: string | null = null;\nlet sessionContext: { apiKey?: string; orgId?: string; agentId?: string } = {};\n\n// =============================================================================\n// Opt-out Logic\n// =============================================================================\n\nfunction isTelemetryDisabled(): boolean {\n const envVal = process.env.LUA_TELEMETRY;\n if (envVal !== undefined) {\n return ['false', '0', 'off', 'no'].includes(envVal.toLowerCase());\n }\n\n const config = loadTelemetryConfig();\n return !config.enabled;\n}\n\nfunction loadTelemetryConfig(): TelemetryConfig {\n if (sessionConfig) return sessionConfig;\n\n try {\n if (existsSync(TELEMETRY_FILE)) {\n sessionConfig = JSON.parse(readFileSync(TELEMETRY_FILE, 'utf8'));\n return sessionConfig!;\n }\n } catch {\n // Corrupt file — regenerate\n }\n\n sessionConfig = {\n enabled: true,\n anonymousId: crypto.randomUUID(),\n noticeShown: false,\n };\n saveTelemetryConfig(sessionConfig);\n return sessionConfig;\n}\n\nfunction saveTelemetryConfig(config: TelemetryConfig): void {\n try {\n if (!existsSync(CLI_CONFIG_DIR)) {\n mkdirSync(CLI_CONFIG_DIR, { recursive: true });\n }\n writeFileSync(TELEMETRY_FILE, JSON.stringify(config, null, 2), 'utf8');\n } catch {\n // Silently ignore write failures\n }\n}\n\n// =============================================================================\n// Distinct ID\n// =============================================================================\n\nfunction getDistinctId(apiKey?: string | null): string {\n if (sessionDistinctId && !apiKey) return sessionDistinctId;\n\n if (apiKey) {\n sessionDistinctId = crypto.createHash('sha256').update(apiKey).digest('hex').substring(0, 16);\n } else {\n const config = loadTelemetryConfig();\n sessionDistinctId = `anon_${config.anonymousId}`;\n }\n\n return sessionDistinctId;\n}\n\n// =============================================================================\n// PostHog Client Lifecycle\n// =============================================================================\n\nfunction getClient(): PostHog | null {\n if (isTelemetryDisabled()) return null;\n\n if (!client) {\n const apiKey = process.env.LUA_POSTHOG_KEY || POSTHOG_API_KEY;\n if (!apiKey) return null;\n\n client = new PostHog(apiKey, {\n host: POSTHOG_HOST,\n flushAt: 1,\n flushInterval: 0,\n });\n }\n\n return client;\n}\n\n// =============================================================================\n// Public API\n// =============================================================================\n\n/**\n * Show first-run telemetry notice (once per install).\n */\nexport function showTelemetryNoticeIfNeeded(): void {\n if (isTelemetryDisabled()) return;\n\n const config = loadTelemetryConfig();\n if (config.noticeShown) return;\n\n console.error('');\n console.error(' Lua CLI collects usage data to improve the developer experience.');\n console.error(' To opt out, run: lua telemetry off');\n console.error(' Or set: LUA_TELEMETRY=false');\n console.error('');\n\n config.noticeShown = true;\n saveTelemetryConfig(config);\n}\n\n/**\n * Opportunistically load API key and yaml config to enrich analytics context.\n * Called from withErrorHandling before every command. Never throws.\n */\nexport async function enrichAnalyticsContext(): Promise<void> {\n if (isTelemetryDisabled()) return;\n try {\n let apiKey: string | null = null;\n try {\n apiKey = getToken();\n } catch {\n /* no key — enrich without identity */\n }\n if (apiKey) {\n // Check if transitioning from anonymous to authenticated\n const previousDistinctId = sessionDistinctId;\n const wasAnonymous = previousDistinctId?.startsWith('anon_');\n\n sessionContext.apiKey = apiKey;\n\n // Link anonymous → authenticated identity in PostHog (once per session)\n if (wasAnonymous) {\n const newDistinctId = getDistinctId(apiKey);\n const ph = getClient();\n if (ph && previousDistinctId) {\n ph.alias({ distinctId: newDistinctId, alias: previousDistinctId });\n }\n }\n\n // Identify user in PostHog with person properties (cached to avoid network call)\n const currentHash = getDistinctId(apiKey);\n const telemetryConfig = loadTelemetryConfig();\n\n if (telemetryConfig.identifiedApiKeyHash === currentHash) {\n // Cached — identify with stored data (no network call)\n const ph = getClient();\n if (ph) {\n ph.identify({\n distinctId: currentHash,\n properties: {\n email: telemetryConfig.identifiedEmail || null,\n name: telemetryConfig.identifiedName || null,\n os: platform(),\n },\n });\n }\n } else {\n // New API key or first time — fetch user data and cache\n try {\n const userData = await checkApiKey(apiKey);\n if (userData) {\n telemetryConfig.identifiedApiKeyHash = currentHash;\n telemetryConfig.identifiedEmail = userData.email;\n telemetryConfig.identifiedName = userData.fullName;\n saveTelemetryConfig(telemetryConfig);\n\n const ph = getClient();\n if (ph) {\n ph.identify({\n distinctId: currentHash,\n properties: {\n email: userData.email || null,\n name: userData.fullName || null,\n os: platform(),\n },\n });\n }\n }\n } catch {\n // Best-effort — don't block commands\n }\n }\n }\n\n const config = readYamlConfig();\n if (config?.agent?.agentId) {\n sessionContext.agentId = config.agent.agentId;\n }\n if (config?.agent?.orgId) {\n sessionContext.orgId = config.agent.orgId;\n }\n } catch {\n // Best-effort — never block the command\n }\n}\n\n/**\n * Track a command execution event. Fire-and-forget, never throws.\n */\nexport function trackCommand(params: {\n commandName: string;\n success: boolean;\n durationMs: number;\n cliVersion: string;\n error?: string;\n properties?: Record<string, any>;\n}): void {\n try {\n const ph = getClient();\n if (!ph) return;\n\n const distinctId = getDistinctId(sessionContext.apiKey);\n\n ph.capture({\n distinctId,\n event: 'cli_command_executed',\n properties: {\n command: params.commandName,\n success: params.success,\n duration_ms: params.durationMs,\n cli_version: params.cliVersion,\n error_message: params.error?.substring(0, 200) || null,\n os: platform(),\n os_version: release(),\n arch: arch(),\n node_version: process.version,\n ci_mode: !!process.env.CI || !process.stdin.isTTY,\n org_id: sessionContext.orgId || null,\n agent_id: sessionContext.agentId || null,\n ...params.properties,\n },\n });\n } catch {\n // Never throw from analytics\n }\n}\n\n/**\n * Track a specific named event with properties. Fire-and-forget, never throws.\n * Use for per-command events (e.g., 'cli_push_completed', 'cli_compile_completed').\n * Auto-enriched with distinct ID, OS, CLI version, and session context.\n */\nexport function trackEvent(eventName: string, properties?: Record<string, any>): void {\n try {\n const ph = getClient();\n if (!ph) return;\n\n const distinctId = getDistinctId(sessionContext.apiKey);\n\n ph.capture({\n distinctId,\n event: eventName,\n properties: {\n os: platform(),\n os_version: release(),\n arch: arch(),\n node_version: process.version,\n ci_mode: !!process.env.CI || !process.stdin.isTTY,\n org_id: sessionContext.orgId || null,\n agent_id: sessionContext.agentId || null,\n ...properties,\n },\n });\n } catch {\n // Never throw from analytics\n }\n}\n\n/**\n * Set telemetry enabled/disabled and persist.\n */\nexport function setTelemetryEnabled(enabled: boolean): void {\n const config = loadTelemetryConfig();\n config.enabled = enabled;\n saveTelemetryConfig(config);\n}\n\n/**\n * Get current telemetry status.\n */\nexport function getTelemetryStatus(): { enabled: boolean; envOverride: boolean } {\n const envVal = process.env.LUA_TELEMETRY;\n const envOverride = envVal !== undefined;\n return {\n enabled: !isTelemetryDisabled(),\n envOverride,\n };\n}\n\n/**\n * Clears cached identity data from telemetry.json.\n * Called during re-authentication to ensure stale user data\n * is not carried over from a previous account.\n */\nexport function clearIdentityCache(): void {\n try {\n const config = loadTelemetryConfig();\n delete config.identifiedApiKeyHash;\n delete config.identifiedEmail;\n delete config.identifiedName;\n saveTelemetryConfig(config);\n // Also clear the in-memory session cache so enrichAnalyticsContext re-fetches\n sessionDistinctId = null;\n } catch {\n // Best-effort — never block auth flows\n }\n}\n\n/**\n * Gracefully shutdown PostHog client.\n * Has a 1-second hard timeout to prevent blocking exit.\n */\nexport async function shutdownAnalytics(): Promise<void> {\n if (!client) return;\n\n try {\n await Promise.race([client.shutdown(), new Promise((resolve) => setTimeout(resolve, 1000).unref())]);\n } catch {\n // Silently ignore shutdown errors\n } finally {\n client = null;\n }\n}\n","/**\n * Pure stdout writer (extracted so {@link ./hints.ts} stays importable in\n * tests — `cli.ts` itself uses `import.meta.url` which ts-jest can't compile).\n *\n * Mirrors the existing `writeInfo` from `./cli.ts`: clears the current\n * progress line via `\\r\\x1b[K` and writes `<message>\\n`.\n */\nexport function writeInfo(message: string): void {\n process.stdout.write('\\r\\x1b[K' + message + '\\n');\n}\n","/**\n * Post-action hint primitives (LUA-180).\n *\n * Pure module (no `import.meta.url`, no analytics) so it's directly testable\n * via ts-jest. {@link ./cli.ts} re-exports these for back-compat with\n * existing call sites.\n *\n * The goal: every push/deploy/chat/sync/compile/test surface ends with a\n * one-line hint at the optimal next command — primarily `lua logs --type X`.\n * Users (especially LLM builders running `lua chat -m \"test\"`) should never\n * have to guess what to run next.\n */\n\nimport { writeInfo } from './write-info.js';\n\n/**\n * Returns true when post-action hints should be silently suppressed.\n * Honors the `LUA_NO_HINTS` env var (any truthy value disables hints).\n *\n * Used by both {@link writeTip}/{@link writeNextStep} and the\n * `withErrorHandling` `onError` hook so users can opt out of all hint noise\n * with a single env var.\n */\nexport function hintsDisabled(): boolean {\n const v = process.env.LUA_NO_HINTS;\n return v === '1' || v === 'true' || v === 'yes';\n}\n\n/**\n * Render a free-form tip line. Format: `✨ Tip: <message>`.\n *\n * Honors {@link hintsDisabled} (LUA_NO_HINTS=1 silently no-ops). For tips\n * that point at a specific follow-up command, prefer {@link writeNextStep}\n * which renders the command in backticks with a consistent verb.\n */\nexport function writeTip(message: string): void {\n if (hintsDisabled()) return;\n writeInfo(`✨ Tip: ${message}`);\n}\n\n/**\n * Options for {@link writeNextStep}.\n */\nexport interface NextStepOptions {\n /**\n * The follow-up command to surface, e.g. `\"lua logs --type skill --limit 10\"`.\n * Rendered in backticks.\n */\n command: string;\n /**\n * Optional rationale appended after the command. A trailing period is added\n * automatically if missing, e.g.\n * rationale: \"to inspect runtime behavior\"\n * → `✨ Tip: run \\`<cmd>\\` to inspect runtime behavior.`\n */\n rationale?: string;\n /**\n * Controls icon and label.\n * - `success` (default) → `✨ Tip: run \\`<cmd>\\` ...`\n * - `error` → `💡 Diagnose: run \\`<cmd>\\` ...`\n * - `partial` → `⚠️ Diagnose: run \\`<cmd>\\` ...`\n */\n when?: 'success' | 'error' | 'partial';\n}\n\n/**\n * Render a \"what to do next\" hint pointing at a specific CLI command.\n * Used after every push/deploy/chat/sync/compile/test action to make\n * the optimal next command obvious to users and AI builders.\n *\n * Honors {@link hintsDisabled} (LUA_NO_HINTS=1 silently no-ops).\n */\nexport function writeNextStep(opts: NextStepOptions): void {\n if (hintsDisabled()) return;\n const when = opts.when ?? 'success';\n const icon = when === 'error' ? '💡' : when === 'partial' ? '⚠️ ' : '✨';\n const label = when === 'success' ? 'Tip' : 'Diagnose';\n const rationale = opts.rationale?.trim();\n const tail = rationale ? ` ${rationale}${/[.!?]$/.test(rationale) ? '' : '.'}` : '';\n writeInfo(`${icon} ${label}: run \\`${opts.command}\\`${tail}`);\n}\n\nexport interface HintBlockLine {\n label: string;\n command: string;\n}\n\n/**\n * Render a multi-line contextual hint block.\n * Used when the optimal next action involves a sequence of commands or\n * when a single-line hint would be too narrow (e.g., deploy-then-test).\n *\n * Output format:\n * ✨ <headline>\n * <label> <command>\n * <label> <command>\n */\nexport function writeHintBlock(opts: {\n headline: string;\n lines: HintBlockLine[];\n when?: 'success' | 'error' | 'partial';\n}): void {\n if (hintsDisabled()) return;\n const validLines = opts.lines.filter((l) => l.command && l.command.trim().length > 0);\n const when = opts.when ?? 'success';\n const icon = when === 'error' ? '💡' : when === 'partial' ? '⚠️ ' : '✨';\n if (validLines.length === 0) {\n writeInfo(`${icon} ${opts.headline}`);\n return;\n }\n writeInfo(`${icon} ${opts.headline}`);\n const maxLabelLen = Math.max(...validLines.map((l) => l.label.length));\n for (const { label, command } of validLines) {\n writeInfo(` ${label.padEnd(maxLabelLen)} \\`${command}\\``);\n }\n}\n","/**\n * Centralized CLI utilities for consistent error handling and output management\n */\n\nimport { AuthenticationError } from '../errors/auth.error.js';\nimport { isUpdateAvailable, printUpdateWarning } from './version-check.js';\nimport { getCliVersion } from './package-root.js';\nimport {\n trackCommand,\n shutdownAnalytics,\n showTelemetryNoticeIfNeeded,\n enrichAnalyticsContext,\n} from '../services/analytics.js';\nimport { hintsDisabled, writeTip, writeNextStep, writeHintBlock } from './hints.js';\nimport type { NextStepOptions, HintBlockLine } from './hints.js';\n\n// Re-export hint primitives so existing call sites can keep importing from\n// `utils/cli.js`. The implementations live in `utils/hints.ts` (a pure\n// module) so they're testable without the `import.meta.url` machinery\n// below.\nexport { hintsDisabled, writeTip, writeNextStep, writeHintBlock };\nexport type { NextStepOptions, HintBlockLine };\n\n/**\n * Global state for CI mode\n * When true, interactive prompts will throw errors instead of silently returning null\n */\nlet isCiMode = false;\n\n/**\n * Set CI mode flag\n */\nexport function setCiMode(enabled: boolean): void {\n isCiMode = enabled;\n}\n\n/**\n * Check if CI mode is enabled\n */\nexport function isCiModeEnabled(): boolean {\n return isCiMode;\n}\n\n/**\n * Await the background version check and print a warning if outdated.\n * Silently catches any errors from the check itself.\n */\nasync function showUpdateWarningIfNeeded(\n versionCheckPromise: Promise<{ available: boolean; latest: string | null } | null>\n): Promise<void> {\n try {\n const result = await versionCheckPromise;\n if (result?.available && result.latest) {\n printUpdateWarning(getCliVersion(), result.latest);\n }\n } catch {\n // Silently ignore version check failures\n }\n}\n\n/**\n * Options for {@link withErrorHandling}.\n */\nexport interface WithErrorHandlingOptions {\n /**\n * Optional hint provider invoked once when the command throws a generic\n * (non-auth, non-Ctrl+C) error. The returned string is rendered as\n * `💡 <hint>` on stderr, immediately after the standard\n * `❌ Error during <command>:` line. Used by command authors to suggest\n * a contextual `lua logs` command. Return `null` to skip.\n *\n * Errors thrown inside the hint provider are swallowed so a buggy\n * provider never replaces the original error in the UX.\n */\n onError?: (err: Error) => string | null | undefined;\n}\n\n/**\n * Wraps a command function with standardized error handling\n * Handles SIGINT (Ctrl+C) gracefully and provides consistent error messages.\n * Also runs a background version check and warns if an update is available.\n *\n * @param opts.onError Optional hint provider; see {@link WithErrorHandlingOptions}.\n */\nexport async function withErrorHandling<T>(\n commandFn: () => Promise<T>,\n commandName: string,\n opts?: WithErrorHandlingOptions\n): Promise<T> {\n showTelemetryNoticeIfNeeded();\n await enrichAnalyticsContext();\n const startTime = Date.now();\n\n // Start version check in background (non-blocking, runs in parallel with command)\n // Skip for the 'update' command (it handles version checking itself)\n const versionCheckPromise =\n commandName !== 'update' ? isUpdateAvailable(getCliVersion()).catch(() => null) : Promise.resolve(null);\n\n try {\n const result = await commandFn();\n\n trackCommand({\n commandName,\n success: true,\n durationMs: Date.now() - startTime,\n cliVersion: getCliVersion(),\n });\n\n await showUpdateWarningIfNeeded(versionCheckPromise);\n await shutdownAnalytics();\n return result;\n } catch (error: any) {\n if (error.name === 'ExitPromptError') {\n trackCommand({\n commandName,\n success: true,\n durationMs: Date.now() - startTime,\n cliVersion: getCliVersion(),\n properties: { cancelled: true },\n });\n await shutdownAnalytics();\n process.exit(0);\n }\n\n trackCommand({\n commandName,\n success: false,\n durationMs: Date.now() - startTime,\n cliVersion: getCliVersion(),\n error: error.message,\n properties: { is_auth_error: AuthenticationError.isAuthenticationError(error) },\n });\n\n if (AuthenticationError.isAuthenticationError(error)) {\n console.error(`\\n❌ ${error.message}`);\n // Tailor the remediation hint to the actual reason — see BAC-202.\n // The same 401 status can mean either \"your key is bad\" or \"your key\n // is fine but you don't own the agentId in lua.skill.yaml\". Sending\n // users to `lua auth configure` for the second case is a dead end.\n // Throw sites with richer context (e.g. getToken() listing all three\n // ways to provide a key) set suppressDefaultRemediation to keep the\n // CLI from printing a duplicate, less specific hint after their\n // already-formatted message.\n if (!error.suppressDefaultRemediation) {\n if (error.reason === 'no_agent_access') {\n console.error(\n '\\n Your API key is valid, but it does not have access to the agentId\\n' +\n ' configured in lua.skill.yaml. This usually means:\\n' +\n '\\n' +\n ' • The agentId belongs to a different account or organization\\n' +\n ' • The agent was deleted, transferred, or you lost access to it\\n' +\n \" • You're using a lua.skill.yaml copied from another project\\n\" +\n '\\n' +\n ' Check the configured agent and switch if needed:\\n' +\n '\\n' +\n ' ➜ lua agents (list agents you have access to)\\n' +\n ' ➜ lua init (re-select the agent for this project)\\n'\n );\n } else {\n console.error(\n '\\n Re-authenticate or check your API key:\\n' +\n '\\n' +\n ' ➜ lua auth configure\\n' +\n ' ➜ https://admin.heylua.ai\\n'\n );\n }\n } else {\n // Add a trailing newline for visual parity with the branches above.\n console.error('');\n }\n await showUpdateWarningIfNeeded(versionCheckPromise);\n await shutdownAnalytics();\n process.exit(1);\n }\n\n console.error(`❌ Error during ${commandName}:`, error.message);\n\n if (opts?.onError && !hintsDisabled()) {\n try {\n const hint = opts.onError(error);\n if (hint) {\n console.error(`💡 ${hint}`);\n }\n } catch {\n // Buggy hint provider must never replace the real error.\n }\n }\n\n await showUpdateWarningIfNeeded(versionCheckPromise);\n await shutdownAnalytics();\n throw new Error(`Error during ${commandName}: ${error.message}`);\n }\n}\n\n/**\n * Clears the specified number of lines from the terminal\n * Used to clean up inquirer prompt output ONLY\n * Should NOT be used to clear user input commands\n */\nexport function clearPromptLines(count: number = 1): void {\n for (let i = 0; i < count; i++) {\n process.stdout.write('\\x1b[1A\\x1b[2K'); // Move up 1 line and clear it\n }\n}\n\n/**\n * Writes a progress message that overwrites the current line\n * Uses carriage return to replace previous progress messages\n */\nexport function writeProgress(message: string): void {\n // Clear current line and write message (no newline - will be overwritten)\n process.stdout.write('\\r\\x1b[K' + message);\n}\n\n/**\n * Writes a final success message that will remain visible\n * Clears the progress line first, then writes the message with newline\n */\nexport function writeSuccess(message: string): void {\n // Clear any progress message, write message, and ensure newline\n process.stdout.write('\\r\\x1b[K' + message + '\\n');\n}\n\n/**\n * Writes an error message\n * Clears the progress line first, then writes the error with newline\n */\nexport function writeError(message: string): void {\n // Clear any progress message, write error, and ensure newline\n process.stderr.write('\\r\\x1b[K' + message + '\\n');\n}\n\n// `writeInfo` is exported from `./write-info.ts` and re-exported below so\n// existing callers can keep importing from `utils/cli.js`.\nexport { writeInfo } from './write-info.js';\n","/**\n * Command Utilities\n * Shared utilities for command initialization and common operations\n */\n\nimport { getToken, checkApiKey } from '../services/auth.js';\nimport { readYamlConfig } from './files.js';\nimport { writeProgress } from './cli.js';\nimport { YamlConfig } from '../types/yaml.types.js';\n\n/**\n * Context returned by initializeCommand for use in command handlers\n */\nexport interface CommandContext {\n config: YamlConfig;\n agentId: string;\n orgId: string;\n apiKey: string;\n userData?: any;\n}\n\n/**\n * Loads and returns the API key.\n * Does NOT validate with server — the first actual API call will validate\n * (HttpClient throws AuthenticationError on 401, caught by withErrorHandling).\n *\n * @returns The API key\n * @throws AuthenticationError if no API key found\n */\nexport function requireAuth(): string {\n return getToken();\n}\n\n/**\n * Loads and returns the API key.\n * Does NOT validate with server — lazy validation on first API call.\n *\n * @returns The API key\n * @throws AuthenticationError if no API key found\n */\nexport function requireAuthOrExit(showProgress: boolean = true): string {\n const apiKey = getToken();\n if (showProgress) {\n writeProgress('✅ Authenticated');\n }\n return apiKey;\n}\n\n/**\n * Full command initialization - validates config + loads auth, returns context.\n * Auth is lazy by default — set validateAuth: true when you need userData.\n *\n * @param options - Optional configuration\n * @param options.showProgress - Whether to show progress messages (default: true)\n * @param options.validateAuth - Validate API key with server and fetch userData (default: false)\n * @returns Command context with config, agentId, apiKey, and optionally userData\n */\nexport async function initializeCommand(\n options: {\n showProgress?: boolean;\n validateAuth?: boolean;\n } = {}\n): Promise<CommandContext> {\n const { showProgress = true, validateAuth = false } = options;\n\n // Validate config exists\n const config = readYamlConfig();\n if (!config) {\n throw new Error('No lua.skill.yaml found. Please run this command from a skill directory.');\n }\n\n // Validate agent config\n if (!config.agent?.agentId) {\n throw new Error(\"Missing agentId in skill configuration. Please run 'lua init' first.\");\n }\n\n // Validate org config\n if (!config.agent?.orgId) {\n throw new Error(\"Missing orgId in skill configuration. Please run 'lua init' first.\");\n }\n\n // Load API key (throws AuthenticationError if missing)\n const apiKey = getToken();\n\n let userData: any = undefined;\n if (validateAuth) {\n userData = await checkApiKey(apiKey);\n }\n\n if (showProgress) {\n writeProgress('✅ Authenticated');\n }\n\n return {\n config,\n agentId: config.agent.agentId,\n orgId: config.agent.orgId,\n apiKey,\n userData,\n };\n}\n","/**\n * API Credentials Management\n * Handles loading and caching of API credentials for skill execution\n */\n\nimport { requireAuth } from '../utils/command-utils.js';\nimport { readYamlConfig } from '../utils/files.js';\n\n/**\n * API credentials structure\n */\nexport interface ApiCredentials {\n apiKey: string;\n agentId: string;\n}\n\n/**\n * Cached credentials to avoid repeated file/keychain access\n */\nlet cachedCredentials: ApiCredentials | null = null;\n\n/**\n * Gets API credentials from keystore and configuration.\n * Results are cached for subsequent calls.\n *\n * @returns API key and agent ID\n * @throws Error if credentials are not found or incomplete\n */\nexport async function getCredentials(): Promise<ApiCredentials> {\n // Return cached credentials if available\n if (cachedCredentials) {\n return cachedCredentials;\n }\n\n // Load and validate API key from keystore\n const apiKey = await requireAuth();\n\n // Load agent ID from YAML file\n const config = readYamlConfig();\n if (!config?.agent?.agentId) {\n throw new Error('No agent ID found in lua.skill.yaml. Please run \"lua init\" first.');\n }\n\n // Cache and return credentials\n cachedCredentials = {\n apiKey,\n agentId: config.agent.agentId,\n };\n\n return cachedCredentials;\n}\n\n/**\n * Clears the cached credentials.\n * Useful for testing or when credentials change.\n */\nexport function clearCredentialsCache(): void {\n cachedCredentials = null;\n}\n","import { Product } from '../interfaces/product.js';\nimport ProductAPI from '../api/products.api.service.js';\n\n/**\n * Product instance class providing a fluent API for managing individual products\n * Provides methods for updating and deleting products\n * Supports direct property access (e.g., product.name) instead of product.data.name\n */\nexport default class ProductInstance {\n data: Product;\n private productAPI!: ProductAPI; // Use definite assignment assertion\n\n // Index signature to allow dynamic property access\n [key: string]: any;\n\n /**\n * Creates a new ProductInstance with proxy support for direct property access\n * @param api - The ProductAPI instance for making API calls\n * @param product - The product data from the API\n * @returns Proxied instance that allows direct access to product properties\n */\n constructor(api: any, product: Product) {\n // Ensure data is always an object, never null or undefined\n this.data = product && typeof product === 'object' ? product : ({} as Product);\n\n // Make productAPI non-enumerable so it doesn't show up in console.log\n Object.defineProperty(this, 'productAPI', {\n value: api,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n\n // Return a proxy that allows direct property access\n return new Proxy(this, {\n get(target, prop, receiver) {\n // If the property exists on the instance itself, return it\n if (prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n // Otherwise, try to get it from the data object (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return target.data[prop];\n }\n return undefined;\n },\n set(target, prop, value, receiver) {\n // Reserved properties that should be set on the instance itself\n const reservedProps = ['data', 'productAPI', 'update', 'delete', 'toJSON'];\n if (typeof prop === 'string' && reservedProps.includes(prop)) {\n return Reflect.set(target, prop, value, receiver);\n }\n // All other properties get set on the data object\n if (typeof prop === 'string') {\n // Initialize data object if it doesn't exist\n if (!target.data || typeof target.data !== 'object') {\n target.data = {} as Product;\n }\n target.data[prop] = value;\n return true;\n }\n return false;\n },\n has(target, prop) {\n // Check if property exists on instance or in data (with null check)\n if (prop in target) {\n return true;\n }\n if (typeof prop === 'string' && target.data && typeof target.data === 'object') {\n return prop in target.data;\n }\n return false;\n },\n ownKeys(target) {\n // Return both instance keys and data keys (with null check)\n const instanceKeys = Reflect.ownKeys(target);\n const dataKeys = target.data && typeof target.data === 'object' ? Object.keys(target.data) : [];\n return [...new Set([...instanceKeys, ...dataKeys])];\n },\n getOwnPropertyDescriptor(target, prop) {\n // First check if it's an instance property\n const instanceDesc = Reflect.getOwnPropertyDescriptor(target, prop);\n if (instanceDesc) {\n return instanceDesc;\n }\n // Then check if it's a data property (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: target.data[prop],\n };\n }\n return undefined;\n },\n });\n }\n\n /**\n * Custom toJSON method to control what gets serialized when logging\n * @returns Serialized product data\n */\n toJSON(): Record<string, any> {\n return this.data;\n }\n\n /**\n * Custom inspect method for Node.js console.log\n * @returns Formatted product data for console output\n */\n [Symbol.for('nodejs.util.inspect.custom')](): Record<string, any> {\n return this.data;\n }\n\n /**\n * Updates the product's data\n * @param data - The product fields to update (partial update supported)\n * @returns Promise resolving to the updated Product\n * @throws Error if the update fails or the product is not found\n */\n async update(data: Record<string, any>): Promise<Product> {\n const response = await this.productAPI.update(data, this.data.id);\n if (response.updated) {\n this.data = response.product;\n return this.data;\n } else {\n throw new Error('Failed to update product');\n }\n }\n\n /**\n * Deletes the product from the catalog\n * @returns Promise resolving to an empty Product object if deletion was successful\n * @throws Error if the deletion fails or the product is not found\n */\n async delete(): Promise<Product> {\n const response = await this.productAPI.delete(this.data.id);\n if (response.deleted) {\n this.data = {} as Product;\n }\n return this.data;\n }\n\n /**\n * Saves the product's data\n * @returns Promise resolving to true if saving was successful\n * @throws Error if the save operation fails\n */\n async save(): Promise<boolean> {\n try {\n await this.productAPI.update(this.data, this.data.id);\n return true;\n } catch (error) {\n throw new Error('Failed to save product data');\n }\n }\n}\n","import { Product, ProductsResponse } from '../interfaces/product.js';\nimport ProductInstance from './product.instance.js';\n\n/**\n * Product pagination instance class providing a fluent API for paginated product results\n * Provides methods for navigating through pages of products\n * Supports array methods like map, filter, forEach for direct iteration\n */\nexport default class ProductPaginationInstance {\n products: ProductInstance[];\n pagination: {\n currentPage: number;\n totalPages: number;\n totalCount: number;\n limit: number;\n hasNextPage: boolean;\n hasPrevPage: boolean;\n nextPage: number | null;\n prevPage: number | null;\n };\n private productAPI!: any; // Use definite assignment assertion\n\n /**\n * Creates a new ProductPaginationInstance\n * @param api - The ProductAPI instance for making API calls\n * @param results - The paginated product results from the API\n */\n constructor(api: any, results: ProductsResponse) {\n // Ensure products array is always initialized, with null checks\n const productsData = results?.data;\n this.products = (Array.isArray(productsData) ? productsData : []).map(\n (product) => new ProductInstance(api, product)\n );\n\n // Ensure pagination is always initialized with safe defaults\n this.pagination = results?.pagination || {\n currentPage: 1,\n totalPages: 1,\n totalCount: 0,\n limit: 10,\n hasNextPage: false,\n hasPrevPage: false,\n nextPage: null,\n prevPage: null,\n };\n\n // Make productAPI non-enumerable so it doesn't show up in console.log\n Object.defineProperty(this, 'productAPI', {\n value: api,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n }\n\n /**\n * Returns the number of products in the current page\n */\n get length(): number {\n return this.products.length;\n }\n\n /**\n * Maps over the products array\n * @param callback - Function to execute for each product\n * @returns Array of mapped results\n */\n map<T>(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => T): T[] {\n return this.products.map(callback);\n }\n\n /**\n * Filters the products array\n * @param callback - Function to test each product\n * @returns Array of products that pass the test\n */\n filter(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): ProductInstance[] {\n return this.products.filter(callback);\n }\n\n /**\n * Executes a function for each product\n * @param callback - Function to execute for each product\n */\n forEach(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => void): void {\n this.products.forEach(callback);\n }\n\n /**\n * Finds the first product that satisfies the test\n * @param callback - Function to test each product\n * @returns The first product that passes the test, or undefined\n */\n find(\n callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean\n ): ProductInstance | undefined {\n return this.products.find(callback);\n }\n\n /**\n * Finds the index of the first product that satisfies the test\n * @param callback - Function to test each product\n * @returns The index of the first product that passes the test, or -1\n */\n findIndex(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): number {\n return this.products.findIndex(callback);\n }\n\n /**\n * Checks if some products satisfy the test\n * @param callback - Function to test each product\n * @returns true if at least one product passes the test\n */\n some(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): boolean {\n return this.products.some(callback);\n }\n\n /**\n * Checks if all products satisfy the test\n * @param callback - Function to test each product\n * @returns true if all products pass the test\n */\n every(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): boolean {\n return this.products.every(callback);\n }\n\n /**\n * Reduces the products array to a single value\n * @param callback - Function to execute on each product\n * @param initialValue - Initial value for the accumulator\n * @returns The final accumulated value\n */\n reduce<T>(\n callback: (accumulator: T, product: ProductInstance, index: number, array: ProductInstance[]) => T,\n initialValue: T\n ): T {\n return this.products.reduce(callback, initialValue);\n }\n\n /**\n * Makes the instance iterable\n * @returns Iterator for the products array\n */\n [Symbol.iterator](): Iterator<ProductInstance> {\n return this.products[Symbol.iterator]();\n }\n\n /**\n * Custom toJSON method to control what gets serialized when logging\n * @returns Serialized products and pagination data\n */\n toJSON(): Record<string, any> {\n return {\n products: this.products,\n pagination: this.pagination,\n };\n }\n\n /**\n * Custom inspect method for Node.js console.log\n * @returns Formatted products and pagination data for console output\n */\n [Symbol.for('nodejs.util.inspect.custom')](): Record<string, any> {\n return {\n products: this.products,\n pagination: this.pagination,\n };\n }\n\n /**\n * Fetches the next page of products\n * @returns Promise resolving to a new ProductPaginationInstance for the next page\n * @throws Error if there is no next page available\n */\n async nextPage(): Promise<ProductPaginationInstance> {\n if (!this.pagination.nextPage) {\n throw new Error('No next page');\n }\n return await this.productAPI.get(this.pagination.nextPage, this.pagination.limit);\n }\n\n /**\n * Fetches the previous page of products\n * @returns Promise resolving to a new ProductPaginationInstance for the previous page\n * @throws Error if there is no previous page available\n */\n async prevPage(): Promise<ProductPaginationInstance> {\n if (!this.pagination.prevPage) {\n throw new Error('No previous page');\n }\n return await this.productAPI.get(this.pagination.prevPage, this.pagination.limit);\n }\n}\n","import { SearchProductsResponse } from '../interfaces/product.js';\nimport { ProductAPI } from '../types/index.js';\nimport ProductInstance from './product.instance.js';\n\n/**\n * Product search instance class providing a fluent API for product search results\n * Contains an array of ProductInstance objects matching the search query\n * Supports array methods like map, filter, forEach for direct iteration\n */\nexport default class ProductSearchInstance {\n products: ProductInstance[];\n private productAPI!: ProductAPI; // Use definite assignment assertion\n\n /**\n * Creates a new ProductSearchInstance\n * @param api - The ProductAPI instance for making API calls\n * @param results - The product search results from the API\n */\n constructor(api: ProductAPI, results: SearchProductsResponse) {\n // Ensure products array is always initialized, with null checks\n const productsData = results?.data;\n this.products = (Array.isArray(productsData) ? productsData : []).map(\n (product) => new ProductInstance(api, product)\n );\n\n // Make productAPI non-enumerable so it doesn't show up in console.log\n Object.defineProperty(this, 'productAPI', {\n value: api,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n }\n\n /**\n * Returns the number of products in the search results\n */\n get length(): number {\n return this.products.length;\n }\n\n /**\n * Maps over the products array\n * @param callback - Function to execute for each product\n * @returns Array of mapped results\n */\n map<T>(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => T): T[] {\n return this.products.map(callback);\n }\n\n /**\n * Filters the products array\n * @param callback - Function to test each product\n * @returns Array of products that pass the test\n */\n filter(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): ProductInstance[] {\n return this.products.filter(callback);\n }\n\n /**\n * Executes a function for each product\n * @param callback - Function to execute for each product\n */\n forEach(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => void): void {\n this.products.forEach(callback);\n }\n\n /**\n * Finds the first product that satisfies the test\n * @param callback - Function to test each product\n * @returns The first product that passes the test, or undefined\n */\n find(\n callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean\n ): ProductInstance | undefined {\n return this.products.find(callback);\n }\n\n /**\n * Finds the index of the first product that satisfies the test\n * @param callback - Function to test each product\n * @returns The index of the first product that passes the test, or -1\n */\n findIndex(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): number {\n return this.products.findIndex(callback);\n }\n\n /**\n * Checks if some products satisfy the test\n * @param callback - Function to test each product\n * @returns true if at least one product passes the test\n */\n some(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): boolean {\n return this.products.some(callback);\n }\n\n /**\n * Checks if all products satisfy the test\n * @param callback - Function to test each product\n * @returns true if all products pass the test\n */\n every(callback: (product: ProductInstance, index: number, array: ProductInstance[]) => boolean): boolean {\n return this.products.every(callback);\n }\n\n /**\n * Reduces the products array to a single value\n * @param callback - Function to execute on each product\n * @param initialValue - Initial value for the accumulator\n * @returns The final accumulated value\n */\n reduce<T>(\n callback: (accumulator: T, product: ProductInstance, index: number, array: ProductInstance[]) => T,\n initialValue: T\n ): T {\n return this.products.reduce(callback, initialValue);\n }\n\n /**\n * Makes the instance iterable\n * @returns Iterator for the products array\n */\n [Symbol.iterator](): Iterator<ProductInstance> {\n return this.products[Symbol.iterator]();\n }\n\n /**\n * Custom toJSON method to control what gets serialized when logging\n * @returns Serialized search results with product data\n */\n toJSON(): Record<string, any> {\n return {\n products: this.products,\n };\n }\n\n /**\n * Custom inspect method for Node.js console.log\n * @returns Formatted search results for console output\n */\n [Symbol.for('nodejs.util.inspect.custom')](): Record<string, any> {\n return {\n products: this.products,\n };\n }\n}\n","import { ProductsResponse, ProductFilterOptions } from '../interfaces/product.js';\nimport { HttpClient } from './http.client.js';\nimport { ProductAPI } from '../types/index.js';\nimport { Product } from '../interfaces/product.js';\nimport { CreateProductResponse } from '../interfaces/product.js';\nimport { UpdateProductResponse } from '../interfaces/product.js';\nimport { DeleteProductResponse } from '../interfaces/product.js';\nimport { SearchProductsResponse } from '../interfaces/product.js';\nimport ProductInstance from '../instances/product.instance.js';\nimport ProductPaginationInstance from '../instances/product.pagination.instance.js';\nimport ProductSearchInstance from '../instances/product.search.instance.js';\n/**\n * Product API calls\n */\nexport default class ProductApi extends HttpClient implements ProductAPI {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of ProductApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Retrieves products for an agent with pagination and optional filtering.\n * Supports both legacy (page, limit) and new (options object) signatures.\n *\n * @example\n * // Legacy: Get products with pagination\n * await products.get(1, 10);\n *\n * // New: Get products with options object\n * await products.get({ page: 2, limit: 20 });\n *\n * // New: Filter products by category\n * await products.get({ filter: { category: \"Electronics\" } });\n *\n * // New: Filter with MongoDB operators\n * await products.get({ filter: { price: { $lte: 100 }, inStock: true } });\n */\n async get(page?: number, limit?: number): Promise<ProductPaginationInstance>;\n async get(options?: ProductFilterOptions): Promise<ProductPaginationInstance>;\n async get(pageOrOptions?: number | ProductFilterOptions, limitArg?: number): Promise<ProductPaginationInstance> {\n let page: number;\n let limit: number;\n let filter: Record<string, any> | undefined;\n\n // Check if first argument is a number (legacy signature) or an object (new signature)\n if (typeof pageOrOptions === 'number') {\n page = pageOrOptions;\n limit = limitArg ?? 10;\n } else {\n page = pageOrOptions?.page ?? 1;\n limit = pageOrOptions?.limit ?? 10;\n filter = pageOrOptions?.filter;\n }\n\n const queryParams = new URLSearchParams();\n queryParams.append('page', page.toString());\n queryParams.append('limit', limit.toString());\n if (filter) {\n queryParams.append('filter', JSON.stringify(filter));\n }\n\n const response = await this.httpGet<ProductsResponse>(\n `/developer/agents/${this.agentId}/products?${queryParams.toString()}`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success) {\n return new ProductPaginationInstance(this, response as ProductsResponse);\n }\n throw new Error(response.error?.message || 'Failed to get products');\n }\n\n /**\n * Retrieves a single product by its unique identifier\n * @param productId - The unique identifier of the product to retrieve\n * @returns Promise resolving to a ProductInstance representing the product\n * @throws Error if the product is not found or the request fails\n */\n async getById(productId: string): Promise<ProductInstance> {\n const response = await this.httpGet<Product>(`/developer/agents/${this.agentId}/products/${productId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return new ProductInstance(this, response.data);\n }\n throw new Error(response.error?.message || 'Failed to get product');\n }\n\n /**\n * Creates a new product in the agent's catalog\n * @param productData - The product data including name, description, price, images, and metadata\n * @returns Promise resolving to a ProductInstance representing the created product\n * @throws Error if the product creation fails or validation errors occur\n */\n async create(productData: Product): Promise<ProductInstance> {\n const response = await this.httpPost<CreateProductResponse>(\n `/developer/agents/${this.agentId}/products`,\n productData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return new ProductInstance(this, response.data.product);\n }\n throw new Error(response.error?.message || 'Failed to create product');\n }\n\n /**\n * Updates an existing product's information\n * @param productData - The product data fields to update (partial update supported)\n * @param productId - The unique identifier of the product to update\n * @returns Promise resolving to an UpdateProductResponse with the updated product details\n * @throws Error if the product is not found or the update fails\n */\n async update(productData: Record<string, any>, productId: string): Promise<UpdateProductResponse> {\n const response = await this.httpPut<UpdateProductResponse>(\n `/developer/agents/${this.agentId}/products`,\n { ...productData, id: productId },\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to update product');\n }\n\n /**\n * Deletes a product from the agent's catalog\n * @param productId - The unique identifier of the product to delete\n * @returns Promise resolving to a DeleteProductResponse confirming deletion\n * @throws Error if the product is not found or the deletion fails\n */\n async delete(productId: string): Promise<DeleteProductResponse> {\n const response = await this.httpDelete<DeleteProductResponse>(\n `/developer/agents/${this.agentId}/products/${productId}`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to delete product');\n }\n\n /**\n * Performs semantic search on products using a text query\n * @param searchQuery - The search text to find matching products\n * @param limit - The maximum number of products to return (default: 5)\n * @returns Promise resolving to a ProductSearchInstance containing search results\n * @throws Error if the search fails or the API request is unsuccessful\n */\n async search(searchQuery: string, limit: number = 5): Promise<ProductSearchInstance> {\n const response = await this.httpGet<SearchProductsResponse>(\n `/developer/agents/${this.agentId}/products/search?searchQuery=${encodeURIComponent(searchQuery)}&limit=${limit}`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success) {\n return new ProductSearchInstance(this, response as unknown as SearchProductsResponse);\n }\n throw new Error(response.error?.message || 'Failed to search products');\n }\n}\n","import { Basket, BasketCommon, BasketData, BasketItem, BasketStatus } from '../interfaces/baskets.js';\nimport { BasketAPI } from '../types/index.js';\nimport OrderInstance from './order.instance.js';\n\n/**\n * Basket instance class providing a fluent API for managing user baskets\n * Provides methods for adding/removing items, updating metadata, and placing orders\n * Supports direct property access (e.g., basket.items) for accessing data and common properties\n */\nexport default class BasketInstance {\n private id: string;\n private userId: string;\n private agentId: string;\n private data: BasketData;\n private common: BasketCommon;\n metadata: any;\n totalAmount: string | number;\n itemCount: number;\n status: BasketStatus;\n private basketAPI!: BasketAPI; // Use definite assignment assertion\n\n // Index signature to allow dynamic property access\n [key: string]: any;\n\n /**\n * Creates a new BasketInstance with proxy support for direct property access\n * @param api - The BasketAPI instance for making API calls\n * @param basket - The basket data from the API\n * @returns Proxied instance that allows direct access to data and common properties\n */\n constructor(api: BasketAPI, basket: Basket) {\n // Ensure data and common are always objects, never null or undefined\n this.data = basket.data && typeof basket.data === 'object' ? basket.data : ({} as BasketData);\n this.common = basket.common && typeof basket.common === 'object' ? basket.common : ({} as BasketCommon);\n this.id = basket.id;\n this.userId = basket.userId;\n this.agentId = basket.agentId;\n this.metadata = basket.data?.metadata || {};\n this.totalAmount = basket.common?.totalAmount || 0;\n this.itemCount = basket.common?.itemCount || 0;\n this.status = basket.common?.status || BasketStatus.ACTIVE;\n // Make basketAPI non-enumerable so it doesn't show up in console.log\n Object.defineProperty(this, 'basketAPI', {\n value: api,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n\n // Return a proxy that allows direct property access\n return new Proxy(this, {\n get(target, prop, receiver) {\n // If the property exists on the instance itself, return it\n if (prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n // Check data object (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return (target.data as any)[prop];\n }\n // Check common object (with null check)\n if (typeof prop === 'string' && target.common && typeof target.common === 'object' && prop in target.common) {\n return (target.common as any)[prop];\n }\n return undefined;\n },\n set(target, prop, value, receiver) {\n // Reserved properties that should be set on the instance itself\n const reservedProps = [\n 'id',\n 'userId',\n 'agentId',\n 'data',\n 'common',\n 'metadata',\n 'totalAmount',\n 'itemCount',\n 'status',\n 'basketAPI',\n 'updateMetadata',\n 'updateStatus',\n 'addItem',\n 'removeItem',\n 'clear',\n 'placeOrder',\n 'toJSON',\n ];\n if (typeof prop === 'string' && reservedProps.includes(prop)) {\n return Reflect.set(target, prop, value, receiver);\n }\n // Check if property exists in data or common, otherwise default to data\n if (typeof prop === 'string') {\n // Initialize objects if they don't exist\n if (!target.data || typeof target.data !== 'object') {\n target.data = {} as BasketData;\n }\n if (!target.common || typeof target.common !== 'object') {\n target.common = {} as BasketCommon;\n }\n if (prop in target.common) {\n (target.common as any)[prop] = value;\n } else {\n (target.data as any)[prop] = value;\n }\n return true;\n }\n return false;\n },\n has(target, prop) {\n // Check if property exists on instance, in data, or in common (with null checks)\n if (prop in target) {\n return true;\n }\n if (typeof prop === 'string') {\n if (target.data && typeof target.data === 'object' && prop in target.data) {\n return true;\n }\n if (target.common && typeof target.common === 'object' && prop in target.common) {\n return true;\n }\n }\n return false;\n },\n ownKeys(target) {\n // Return instance keys, data keys, and common keys (with null checks)\n const instanceKeys = Reflect.ownKeys(target);\n const dataKeys = target.data && typeof target.data === 'object' ? Object.keys(target.data) : [];\n const commonKeys = target.common && typeof target.common === 'object' ? Object.keys(target.common) : [];\n return [...new Set([...instanceKeys, ...dataKeys, ...commonKeys])];\n },\n getOwnPropertyDescriptor(target, prop) {\n // First check if it's an instance property\n const instanceDesc = Reflect.getOwnPropertyDescriptor(target, prop);\n if (instanceDesc) {\n return instanceDesc;\n }\n // Then check data properties (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: (target.data as any)[prop],\n };\n }\n // Then check common properties (with null check)\n if (typeof prop === 'string' && target.common && typeof target.common === 'object' && prop in target.common) {\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: (target.common as any)[prop],\n };\n }\n return undefined;\n },\n });\n }\n\n /**\n * Custom toJSON method to control what gets serialized when logging\n * @returns Serialized basket data combining data and common fields\n */\n toJSON(): Record<string, any> {\n return {\n ...this.data,\n ...this.common,\n id: this.id,\n };\n }\n\n /**\n * Custom inspect method for Node.js console.log\n * @returns Formatted basket data for console output\n */\n [Symbol.for('nodejs.util.inspect.custom')](): Record<string, any> {\n return {\n ...this.data,\n ...this.common,\n id: this.id,\n };\n }\n\n /**\n * Updates the basket's metadata\n * @param metadata - The metadata object to merge with existing metadata\n * @returns Promise resolving to the updated basket data\n * @throws Error if the metadata update fails\n */\n async updateMetadata(metadata: any): Promise<any> {\n await this.basketAPI.updateMetadata(this.id, metadata);\n this.data.metadata = { ...this.data.metadata, ...metadata };\n return { ...this.data, ...this.common };\n }\n\n /**\n * Updates the basket's status\n * @param status - The new basket status to set\n * @returns Promise resolving to the updated basket data\n * @throws Error if the status update fails\n */\n async updateStatus(status: BasketStatus): Promise<any> {\n await this.basketAPI.updateStatus(this.id, status);\n this.common.status = status;\n return { ...this.data, ...this.common };\n }\n\n /**\n * Updates the basket instance with new data from the API\n * @param basket - The updated basket data from the API\n * @returns The combined basket data and common fields\n * @private\n */\n private updateBasket(basket: Basket): any {\n this.data = basket.data;\n this.common = basket.common;\n this.id = basket.id;\n this.userId = basket.userId;\n this.agentId = basket.agentId;\n this.metadata = basket.data.metadata;\n this.totalAmount = basket.common.totalAmount;\n this.itemCount = basket.common.itemCount;\n this.status = basket.common.status;\n return { ...this.data, ...this.common };\n }\n\n /**\n * Adds an item to the basket\n * @param item - The basket item to add (must include productId and quantity)\n * @returns Promise resolving to the updated basket data\n * @throws Error if the item cannot be added\n */\n async addItem(item: BasketItem): Promise<any> {\n const basket = await this.basketAPI.addItem(this.id, item);\n return this.updateBasket(basket);\n }\n\n /**\n * Removes an item from the basket\n * @param itemId - The unique identifier of the item to remove\n * @returns Promise resolving to the updated basket data\n * @throws Error if the item cannot be removed or is not found\n */\n async removeItem(itemId: string): Promise<any> {\n const basket = await this.basketAPI.removeItem(this.id, itemId);\n return this.updateBasket(basket);\n }\n\n /**\n * Clears all items from the basket\n * @returns Promise resolving to the updated empty basket data\n * @throws Error if the clear operation fails\n */\n async clear(): Promise<any> {\n const basket = await this.basketAPI.clear(this.id);\n return this.updateBasket(basket);\n }\n\n /**\n * Places an order from the basket contents\n * @param data - Additional order data (shipping info, payment details, etc.)\n * @returns Promise resolving to an OrderInstance representing the created order\n * @throws Error if the order creation fails\n */\n async placeOrder(data: Record<string, any>): Promise<OrderInstance> {\n const order = await this.basketAPI.placeOrder(data, this.id);\n await this.updateStatus(BasketStatus.CHECKED_OUT);\n return order;\n }\n}\n","import OrderApi from '../api/order.api.service.js';\nimport { OrderResponse, OrderData, OrderCommon, OrderStatus } from '../interfaces/orders.js';\n\n/**\n * Order instance class providing a fluent API for managing orders\n * Provides methods for updating order status and order data\n * Supports direct property access (e.g., order.shippingAddress) for accessing data and common properties\n */\nexport default class OrderInstance {\n private data: OrderData;\n private common: OrderCommon;\n private id: string;\n private userId: string;\n private agentId: string;\n private orderId: string;\n private orderAPI!: OrderApi; // Use definite assignment assertion\n\n // Index signature to allow dynamic property access\n [key: string]: any;\n\n /**\n * Creates a new OrderInstance with proxy support for direct property access\n * @param api - The OrderApi instance for making API calls\n * @param order - The order response data from the API\n * @returns Proxied instance that allows direct access to data and common properties\n */\n constructor(api: OrderApi, order: OrderResponse) {\n // Ensure data and common are always objects, never null or undefined\n this.data = order.data && typeof order.data === 'object' ? order.data : ({} as OrderData);\n this.common = order.common && typeof order.common === 'object' ? order.common : ({} as OrderCommon);\n this.id = order.id;\n this.userId = order.userId;\n this.agentId = order.agentId;\n this.orderId = order.orderId;\n // Make orderAPI non-enumerable so it doesn't show up in console.log\n Object.defineProperty(this, 'orderAPI', {\n value: api,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n\n // Return a proxy that allows direct property access\n return new Proxy(this, {\n get(target, prop, receiver) {\n // If the property exists on the instance itself, return it\n if (prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n // Check data object (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return (target.data as any)[prop];\n }\n // Check common object (with null check)\n if (typeof prop === 'string' && target.common && typeof target.common === 'object' && prop in target.common) {\n return (target.common as any)[prop];\n }\n return undefined;\n },\n set(target, prop, value, receiver) {\n // Reserved properties that should be set on the instance itself\n const reservedProps = [\n 'data',\n 'common',\n 'id',\n 'userId',\n 'agentId',\n 'orderId',\n 'orderAPI',\n 'updateStatus',\n 'update',\n 'toJSON',\n ];\n if (typeof prop === 'string' && reservedProps.includes(prop)) {\n return Reflect.set(target, prop, value, receiver);\n }\n // Check if property exists in data or common, otherwise default to data\n if (typeof prop === 'string') {\n // Initialize objects if they don't exist\n if (!target.data || typeof target.data !== 'object') {\n target.data = {} as OrderData;\n }\n if (!target.common || typeof target.common !== 'object') {\n target.common = {} as OrderCommon;\n }\n if (prop in target.common) {\n (target.common as any)[prop] = value;\n } else {\n (target.data as any)[prop] = value;\n }\n return true;\n }\n return false;\n },\n has(target, prop) {\n // Check if property exists on instance, in data, or in common (with null checks)\n if (prop in target) {\n return true;\n }\n if (typeof prop === 'string') {\n if (target.data && typeof target.data === 'object' && prop in target.data) {\n return true;\n }\n if (target.common && typeof target.common === 'object' && prop in target.common) {\n return true;\n }\n }\n return false;\n },\n ownKeys(target) {\n // Return instance keys, data keys, and common keys (with null checks)\n const instanceKeys = Reflect.ownKeys(target);\n const dataKeys = target.data && typeof target.data === 'object' ? Object.keys(target.data) : [];\n const commonKeys = target.common && typeof target.common === 'object' ? Object.keys(target.common) : [];\n return [...new Set([...instanceKeys, ...dataKeys, ...commonKeys])];\n },\n getOwnPropertyDescriptor(target, prop) {\n // First check if it's an instance property\n const instanceDesc = Reflect.getOwnPropertyDescriptor(target, prop);\n if (instanceDesc) {\n return instanceDesc;\n }\n // Then check data properties (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: (target.data as any)[prop],\n };\n }\n // Then check common properties (with null check)\n if (typeof prop === 'string' && target.common && typeof target.common === 'object' && prop in target.common) {\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: (target.common as any)[prop],\n };\n }\n return undefined;\n },\n });\n }\n\n /**\n * Custom toJSON method to control what gets serialized when logging\n * @returns Serialized order data combining data and common fields\n */\n toJSON(): Record<string, any> {\n return {\n ...this.data,\n ...this.common,\n id: this.id,\n };\n }\n\n /**\n * Custom inspect method for Node.js console.log\n * @returns Formatted order data for console output\n */\n [Symbol.for('nodejs.util.inspect.custom')](): Record<string, any> {\n return {\n ...this.data,\n ...this.common,\n id: this.id,\n };\n }\n\n /**\n * Updates the order's status\n * @param status - The new order status (e.g., 'pending', 'processing', 'shipped', 'delivered', 'cancelled')\n * @returns Promise resolving to the updated order data\n * @throws Error if the status update fails\n */\n async updateStatus(status: OrderStatus): Promise<any> {\n const response = await this.orderAPI.updateStatus(status, this.id);\n this.common = response.common;\n return {\n ...this.data,\n ...this.common,\n id: this.id,\n };\n }\n\n /**\n * Updates the order's data\n * @param data - The data fields to update (e.g., shipping info, notes, metadata)\n * @returns Promise resolving to the updated order data\n * @throws Error if the data update fails\n */\n async update(data: Record<string, any>): Promise<any> {\n const response = await this.orderAPI.updateData(data, this.id);\n this.data = response.data;\n this.common = response.common;\n return {\n ...this.data,\n ...this.common,\n id: this.id,\n };\n }\n\n /**\n * Saves the order's data\n * @returns Promise resolving to true if saving was successful\n * @throws Error if the save operation fails\n */\n async save(): Promise<boolean> {\n try {\n await this.orderAPI.updateData(this.data, this.id);\n return true;\n } catch (error) {\n throw new Error('Failed to save order data');\n }\n }\n}\n","import { OrderAPI } from '../types/index.js';\nimport { HttpClient } from './http.client.js';\nimport { CreateOrderRequest, OrderResponse, OrderStatus } from '../interfaces/orders.js';\nimport OrderInstance from '../instances/order.instance.js';\n\nexport default class OrderApi extends HttpClient implements OrderAPI {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of OrderApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Creates a new order from a basket\n * @param orderData - The order creation request data containing basketId and additional order information\n * @returns Promise resolving to an OrderInstance representing the created order\n * @throws Error if the basket is not found or the order creation fails\n */\n async create(orderData: CreateOrderRequest): Promise<OrderInstance> {\n const response = await this.httpPost<OrderResponse>(`/developer/agents/${this.agentId}/order`, orderData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return new OrderInstance(this, response.data);\n }\n throw new Error(response.error?.message || 'Failed to create order');\n }\n\n /**\n * Updates the status of an existing order\n * @param status - The new order status (e.g., 'pending', 'processing', 'shipped', 'delivered', 'cancelled')\n * @param orderId - The unique identifier of the order to update\n * @returns Promise resolving to the updated OrderResponse\n * @throws Error if the order is not found or the status update fails\n */\n async updateStatus(status: OrderStatus, orderId: string): Promise<OrderResponse> {\n const response = await this.httpPut<OrderResponse>(\n `/developer/agents/${this.agentId}/order/${orderId}/${status}`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to update order status');\n }\n\n /**\n * Updates the data associated with an order\n * @param data - The data object containing fields to update (e.g., shipping info, notes, metadata)\n * @param orderId - The unique identifier of the order to update\n * @returns Promise resolving to the updated OrderResponse\n * @throws Error if the order is not found or the data update fails\n */\n async updateData(data: Record<string, any>, orderId: string): Promise<OrderResponse> {\n const response = await this.httpPut<OrderResponse>(`/developer/agents/${this.agentId}/order/${orderId}`, data, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to update order data');\n }\n\n /**\n * Retrieves all user orders with optional status filtering\n * @param status - Optional order status to filter by (e.g., 'pending', 'processing', 'shipped', 'delivered', 'cancelled')\n * @returns Promise resolving to an array of OrderInstance objects\n * @throws Error if the request fails or orders cannot be retrieved\n */\n async get(status?: OrderStatus): Promise<OrderInstance[]> {\n const statusParam = status ? `?status=${status}` : '';\n const response = await this.httpGet<OrderResponse[]>(`/developer/agents/${this.agentId}/order/user${statusParam}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return response.data.map((order) => new OrderInstance(this, order));\n }\n throw new Error(response.error?.message || 'Failed to get user orders');\n }\n\n /**\n * Retrieves a single order by its unique identifier\n * @param orderId - The unique identifier of the order to retrieve\n * @returns Promise resolving to an OrderInstance representing the order\n * @throws Error if the order is not found or the request fails\n */\n async getById(orderId: string): Promise<OrderInstance> {\n const response = await this.httpGet<OrderResponse>(`/developer/agents/${this.agentId}/order/${orderId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return new OrderInstance(this, response.data);\n }\n throw new Error(response.error?.message || 'Failed to get order');\n }\n}\n","import BasketInstance from '../instances/basket.instance.js';\nimport { HttpClient } from './http.client.js';\nimport OrderInstance from '../instances/order.instance.js';\nimport { BasketStatus, CreateBasketRequest, AddItemToBasketRequest, Basket } from '../interfaces/baskets.js';\nimport { OrderResponse } from '../interfaces/orders.js';\nimport { BasketAPI } from '../types/index.js';\nimport OrderApi from './order.api.service.js';\n\nexport default class BasketApi extends HttpClient implements BasketAPI {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of BasketApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Creates a new user basket\n * @param basketData - The basket creation request data containing user ID and optional metadata\n * @returns Promise resolving to a BasketInstance representing the created basket\n * @throws Error if the basket creation fails or the API request is unsuccessful\n */\n async create(basketData: CreateBasketRequest): Promise<BasketInstance> {\n const response = await this.httpPost<Basket>(`/developer/agents/${this.agentId}/basket`, basketData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return new BasketInstance(this, response.data);\n }\n throw new Error(response.error?.message || 'Failed to create basket');\n }\n\n /**\n * Retrieves all user baskets with optional status filtering\n * @param status - Optional basket status to filter by (e.g., 'active', 'completed', 'abandoned')\n * @returns Promise resolving to an array of BasketInstance objects\n * @throws Error if the request fails or baskets cannot be retrieved\n */\n async get(status?: BasketStatus): Promise<BasketInstance[]> {\n const statusParam = status ? `?status=${status}` : '';\n const response = await this.httpGet<Basket[]>(`/developer/agents/${this.agentId}/basket/user${statusParam}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n\n if (response.success && response.data) {\n return response.data.map((basket: Basket) => new BasketInstance(this, basket));\n }\n throw new Error(response.error?.message || 'Failed to get user baskets');\n }\n\n /**\n * Retrieves a single basket by its unique identifier\n * @param basketId - The unique identifier of the basket to retrieve\n * @returns Promise resolving to a BasketInstance representing the basket\n * @throws Error if the basket is not found or the request fails\n */\n async getById(basketId: string): Promise<BasketInstance> {\n const response = await this.httpGet<Basket>(`/developer/agents/${this.agentId}/basket/${basketId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return new BasketInstance(this, response.data as Basket);\n }\n throw new Error(response.error?.message || 'Failed to get basket');\n }\n\n /**\n * Adds an item to a specific basket\n * @param basketId - The unique identifier of the basket\n * @param itemData - The item data including product ID, quantity, and optional metadata\n * @returns Promise resolving to the updated Basket object\n * @throws Error if the basket is not found or the item cannot be added\n */\n async addItem(basketId: string, itemData: AddItemToBasketRequest): Promise<Basket> {\n const response = await this.httpPost<Basket>(\n `/developer/agents/${this.agentId}/basket/${basketId}/item`,\n itemData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to add item to basket');\n }\n\n /**\n * Removes a specific item from a basket\n * @param basketId - The unique identifier of the basket\n * @param itemId - The unique identifier of the item to remove\n * @returns Promise resolving to the updated Basket object\n * @throws Error if the basket or item is not found or the removal fails\n */\n async removeItem(basketId: string, itemId: string): Promise<Basket> {\n const response = await this.httpDelete<Basket>(\n `/developer/agents/${this.agentId}/basket/${basketId}/item/${itemId}`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to remove item from basket');\n }\n\n /**\n * Clears all items from a basket\n * @param basketId - The unique identifier of the basket to clear\n * @returns Promise resolving to the updated empty Basket object\n * @throws Error if the basket is not found or the clear operation fails\n */\n async clear(basketId: string): Promise<Basket> {\n const response = await this.httpDelete<Basket>(`/developer/agents/${this.agentId}/basket/${basketId}/clear`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to clear basket');\n }\n\n /**\n * Updates the status of a basket\n * @param basketId - The unique identifier of the basket\n * @param status - The new status to set for the basket\n * @returns Promise resolving to the updated BasketStatus\n * @throws Error if the basket is not found or the status update fails\n */\n async updateStatus(basketId: string, status: BasketStatus): Promise<BasketStatus> {\n const response = await this.httpPut<Basket>(\n `/developer/agents/${this.agentId}/basket/${basketId}/${status}`,\n undefined,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success) {\n return status;\n }\n throw new Error(response.error?.message || 'Failed to update basket status');\n }\n\n /**\n * Updates the metadata of a basket\n * @param basketId - The unique identifier of the basket\n * @param metadata - The metadata object to update or merge with existing metadata\n * @returns Promise resolving to the updated metadata\n * @throws Error if the basket is not found or the metadata update fails\n */\n async updateMetadata(basketId: string, metadata: Record<string, any>): Promise<Record<string, any>> {\n const response = await this.httpPut<Basket>(\n `/developer/agents/${this.agentId}/basket/${basketId}/metadata`,\n metadata,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success) {\n return metadata;\n }\n throw new Error(response.error?.message || 'Failed to update basket metadata');\n }\n\n /**\n * Creates an order from a basket\n * @param data - Additional order data (shipping info, payment details, etc.)\n * @param basketId - The unique identifier of the basket to convert to an order\n * @returns Promise resolving to an OrderInstance representing the created order\n * @throws Error if the basket is not found or the order creation fails\n */\n async placeOrder(data: Record<string, any>, basketId: string): Promise<OrderInstance> {\n const response = await this.httpPost<OrderResponse>(\n `/developer/agents/${this.agentId}/order`,\n { basketId, data },\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n const orderApi = new OrderApi(this.baseUrl, this.apiKey, this.agentId);\n return new OrderInstance(orderApi, response.data);\n }\n throw new Error(response.error?.message || 'Failed to create order');\n }\n}\n","import { Message } from '../interfaces/message.js';\nimport { UserDataAPI } from '../types/index.js';\nimport { ImmutableUserProfile, UserAgentData } from '../interfaces/user.js';\nimport type { ChatHistoryMessage } from '@lua/shared-types';\n\n/**\n * User data instance class providing a fluent API for managing user data\n * Provides methods for updating and clearing data\n * Supports direct property access (e.g., user.name) instead of user.data.name\n */\nexport default class UserDataInstance {\n data: UserAgentData;\n private userAPI!: UserDataAPI; // Use definite assignment assertion\n _luaProfile!: ImmutableUserProfile; // Immutable Lua user profile\n\n // Index signature to allow dynamic property access\n [key: string]: any;\n\n /**\n * Creates a new UserDataInstance with proxy support for direct property access\n * @param api - The UserDataAPI instance for making API calls\n * @param data - The user data from the API\n * @param profile - The immutable user profile data\n * @returns Proxied instance that allows direct access to data properties\n */\n constructor(api: UserDataAPI, data: any, profile?: ImmutableUserProfile) {\n // Ensure data is always an object, never null or undefined\n this.data = data && typeof data === 'object' ? data : {};\n\n // Make userAPI non-enumerable so it doesn't show up in console.log\n Object.defineProperty(this, 'userAPI', {\n value: api,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n\n // Make _luaProfile non-enumerable and immutable\n Object.defineProperty(this, '_luaProfile', {\n get() {\n return (\n profile || {\n userId: '',\n fullName: '',\n mobileNumbers: [],\n emailAddresses: [],\n }\n );\n },\n set(_) {\n // silently ignore any attempts to modify\n },\n enumerable: false,\n configurable: false,\n });\n\n // Return a proxy that allows direct property access\n return new Proxy(this, {\n get(target, prop, receiver) {\n // If the property exists on the instance itself, return it\n if (prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n // Otherwise, try to get it from the data object (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return target.data[prop];\n }\n return undefined;\n },\n set(target, prop, value, receiver) {\n // Reserved properties that should be set on the instance itself\n const reservedProps = ['data', 'userAPI', 'update', 'clear', 'toJSON', '_luaProfile'];\n if (typeof prop === 'string' && reservedProps.includes(prop)) {\n return Reflect.set(target, prop, value, receiver);\n }\n // All other properties get set on the data object\n if (typeof prop === 'string') {\n // Initialize data object if it doesn't exist\n if (!target.data || typeof target.data !== 'object') {\n target.data = {};\n }\n target.data[prop] = value;\n return true;\n }\n return false;\n },\n has(target, prop) {\n // Check if property exists on instance or in data (with null check)\n if (prop in target) {\n return true;\n }\n if (typeof prop === 'string' && target.data && typeof target.data === 'object') {\n return prop in target.data;\n }\n return false;\n },\n ownKeys(target) {\n // Return both instance keys and data keys (with null check)\n const instanceKeys = Reflect.ownKeys(target);\n const dataKeys = target.data && typeof target.data === 'object' ? Object.keys(target.data) : [];\n return [...new Set([...instanceKeys, ...dataKeys])];\n },\n getOwnPropertyDescriptor(target, prop) {\n // First check if it's an instance property\n const instanceDesc = Reflect.getOwnPropertyDescriptor(target, prop);\n if (instanceDesc) {\n return instanceDesc;\n }\n // Then check if it's a data property (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: target.data[prop],\n };\n }\n return undefined;\n },\n });\n }\n\n /**\n * Custom toJSON method to control what gets serialized when logging\n * @returns Serialized user data\n */\n toJSON(): Record<string, any> {\n return this.data;\n }\n\n /**\n * Custom inspect method for Node.js console.log\n * @returns Formatted user data for console output\n */\n [Symbol.for('nodejs.util.inspect.custom')](): Record<string, any> {\n return this.data;\n }\n\n /**\n * Updates the user's data\n * @param data - The data fields to update or add to user data\n * @returns Promise resolving to the updated user data\n * @throws Error if the update fails\n */\n async update(data: Record<string, any>): Promise<any> {\n try {\n const response = await this.userAPI.update(data);\n this.data = response;\n return this.data;\n } catch (error) {\n throw new Error('Failed to update user data');\n }\n }\n\n /**\n * Clears all user data for the current user\n * @returns Promise resolving to true if clearing was successful\n * @throws Error if the clear operation fails\n */\n async clear(): Promise<boolean> {\n try {\n await this.userAPI.clear();\n return true;\n } catch (error) {\n throw new Error('Failed to clear user data');\n }\n }\n\n /**\n * Saves the user's data\n * @returns Promise resolving to true if saving was successful\n * @throws Error if the save operation fails\n */\n async save(): Promise<boolean> {\n try {\n await this.userAPI.update(this.data);\n return true;\n } catch (error) {\n throw new Error('Failed to save user data');\n }\n }\n\n /**\n * Sends a message to a specific user conversation for the agent\n * @param messages - An array of messages to send (can be text, image, or file types)\n * @returns Promise resolving to the response data from the server\n * @throws Error if the message sending fails or the request is unsuccessful\n */\n async send(messages: Message[]): Promise<any> {\n try {\n await this.userAPI.sendMessage(messages);\n return true;\n } catch (error) {\n throw new Error('Failed to send message');\n }\n }\n\n //get chat history\n async getChatHistory(): Promise<ChatHistoryMessage[]> {\n try {\n return await this.userAPI.getChatHistory();\n } catch (error) {\n throw new Error('Failed to get chat history');\n }\n }\n}\n","import { HttpClient } from './http.client.js';\nimport UserDataInstance from '../instances/user.instance.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport { Message } from '../interfaces/message.js';\nimport { UserDataAPI } from '../types/index.js';\nimport { ChatHistoryMessage } from '../interfaces/chat.js';\nimport {\n UserLookupOptions,\n ProfileResponse,\n UserDataResponse,\n AdminUserResponse,\n SendMessageResponse,\n} from '../interfaces/user.js';\nimport { getDeveloperInstance } from './lazy-instances.js';\n\n// User Data API calls\nexport default class UserDataApi extends HttpClient implements UserDataAPI {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of UserDataApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Retrieves user data by userId, email, or phone.\n * @param identifier - Optional userId string or lookup options object\n * @returns Promise resolving to a UserDataInstance, or null if not found (for email/phone lookup)\n * @throws Error if the user data cannot be retrieved or the request fails\n */\n async get(identifier?: string | UserLookupOptions): Promise<UserDataInstance | null> {\n let userId: string | undefined;\n\n // Handle object-based lookup (email or phone)\n if (identifier && typeof identifier === 'object') {\n const profile = await this.resolveUserProfile(identifier);\n if (!profile) return null;\n userId = profile.id;\n } else {\n userId = identifier;\n }\n\n let url = `/developer/user/data/agent/${this.agentId}`;\n if (userId) {\n url += `/user/${userId}`;\n }\n const response = await this.httpGet<UserDataResponse>(url, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (!response.success) {\n throw new Error(response.error?.message || 'Failed to get user data');\n }\n\n // Extract profile data and remove from response\n const profile = response.data?._luaProfile;\n const { _luaProfile, ...data } = response.data || {};\n\n return new UserDataInstance(this, data, profile);\n }\n\n /**\n * Resolves email or phone to user profile via DeveloperApi\n * @param options - Lookup options containing email or phone\n * @returns Promise resolving to ProfileResponse or null if not found\n */\n private async resolveUserProfile(options: UserLookupOptions): Promise<ProfileResponse | null> {\n try {\n const developerApi = await getDeveloperInstance();\n\n if (options.email) {\n const response = await developerApi.getUserProfileByEmail(options.email);\n return response.success ? (response.data ?? null) : null;\n }\n if (options.phone) {\n const response = await developerApi.getUserProfileByPhone(options.phone);\n return response.success ? (response.data ?? null) : null;\n }\n } catch (error: any) {\n // Return null for 404, rethrow other errors\n if (error.message?.includes('404') || error.message?.includes('not found')) {\n return null;\n }\n throw error;\n }\n return null;\n }\n\n /**\n * Updates the current user's data for the specific agent\n * @param data - The data object containing fields to update or add to user data\n * @returns Promise resolving to the updated user data\n * @throws Error if the update fails or the request is unsuccessful\n */\n async update(data: Record<string, any>): Promise<Record<string, any>> {\n const response = await this.httpPut<UserDataResponse>(`/developer/user/data/agent/${this.agentId}`, data, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (!response.success) {\n throw new Error(response.error?.message || 'Failed to update user data');\n }\n\n // Extract profile if present and remove from response\n const { _luaProfile, ...cleanData } = response.data || {};\n\n return cleanData;\n }\n\n /**\n * Clears all user data for the current user and specific agent\n * @returns Promise resolving to an empty object upon successful deletion\n * @throws Error if the clear operation fails or the request is unsuccessful\n */\n async clear(): Promise<Record<string, never>> {\n const response = await this.httpDelete<{ success: boolean }>(`/developer/user/data/agent/${this.agentId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (!response.success) {\n throw new Error(response.error?.message || 'Failed to clear user data');\n }\n return {};\n }\n\n /**\n * Sends a message to a specific user conversation for the agent\n * @param messages - An array of messages to send (can be text, image, or file types)\n * @returns Promise resolving to the response data from the server\n * @throws Error if the message sending fails or the request is unsuccessful\n */\n async sendMessage(messages: Message[]): Promise<SendMessageResponse> {\n const user = await this.getAdminUser();\n const response = await this.httpPost<SendMessageResponse>(\n `/admin/agents/${this.agentId}/conversations/${user.uid}`,\n { messages },\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (!response.success) {\n throw new Error(response.error?.message || 'Failed to send message');\n }\n return response.data!;\n }\n\n /**\n * Gets the admin user for the specific agent\n * @returns Promise resolving to the admin user data\n * @throws Error if the admin user cannot be retrieved or the request is unsuccessful\n */\n async getAdminUser(): Promise<AdminUserResponse> {\n const response = await this.httpGet<AdminUserResponse>(`/admin`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (!response.success) {\n throw new Error(response.error?.message || 'Failed to get admin user');\n }\n return response.data!;\n }\n\n /**\n * Gets the chat history for the current user and agent\n * @returns Promise resolving to an array of chat messages\n * @throws Error if the chat history cannot be retrieved or the request is unsuccessful\n *\n * @example\n * ```typescript\n * const history = await User.getChatHistory();\n * // Returns: [{ role: 'user', content: [...], createdAt: '...' }, ...]\n * ```\n */\n async getChatHistory(): Promise<ChatHistoryMessage[]> {\n const response = await this.httpGet<ChatHistoryMessage[]>(`/chat/history/${this.agentId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (!response.success) {\n throw new Error(response.error?.message || 'Failed to get chat history');\n }\n return response.data || [];\n }\n}\n","import { Product } from '../interfaces/product.js';\nimport { UserData } from '../interfaces/admin.js';\nimport { CustomDataAPI, UserDataAPI } from '../types/index.js';\nimport { CreateCustomDataResponse } from '../interfaces/custom.data.js';\n\n/**\n * Data entry instance class providing a fluent API for managing custom data entries\n * Provides methods for updating and deleting individual data entries\n * Supports direct property access (e.g., entry.fieldName) for accessing data properties\n */\nexport default class DataEntryInstance {\n data: Record<string, any>;\n id: string;\n collectionName: string;\n score?: number;\n private customDataAPI!: CustomDataAPI; // Use definite assignment assertion\n\n // Index signature to allow dynamic property access\n [key: string]: any;\n\n /**\n * Creates a new DataEntryInstance with proxy support for direct property access\n * @param api - The CustomDataAPI instance for making API calls\n * @param entry - The custom data entry response from the API\n * @param collectionName - The name of the collection this entry belongs to\n * @returns Proxied instance that allows direct access to data properties\n */\n constructor(api: CustomDataAPI, entry: CreateCustomDataResponse, collectionName: string) {\n // Ensure data is always an object, never null or undefined\n this.data = entry.data && typeof entry.data === 'object' ? entry.data : {};\n this.id = entry.id;\n this.collectionName = collectionName;\n this.score = entry.score;\n // Make userAPI non-enumerable so it doesn't show up in console.log\n Object.defineProperty(this, 'customDataAPI', {\n value: api,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n\n // Return a proxy that allows direct property access\n return new Proxy(this, {\n get(target, prop, receiver) {\n // If the property exists on the instance itself, return it\n if (prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n // Otherwise, try to get it from the data object (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return target.data[prop];\n }\n return undefined;\n },\n set(target, prop, value, receiver) {\n // Reserved properties that should be set on the instance itself\n const reservedProps = ['data', 'id', 'collectionName', 'score', 'customDataAPI', 'update', 'delete', 'toJSON'];\n if (typeof prop === 'string' && reservedProps.includes(prop)) {\n return Reflect.set(target, prop, value, receiver);\n }\n // All other properties get set on the data object\n if (typeof prop === 'string') {\n // Initialize data object if it doesn't exist\n if (!target.data || typeof target.data !== 'object') {\n target.data = {};\n }\n target.data[prop] = value;\n return true;\n }\n return false;\n },\n has(target, prop) {\n // Check if property exists on instance or in data (with null check)\n if (prop in target) {\n return true;\n }\n if (typeof prop === 'string' && target.data && typeof target.data === 'object') {\n return prop in target.data;\n }\n return false;\n },\n ownKeys(target) {\n // Return both instance keys and data keys (with null check)\n const instanceKeys = Reflect.ownKeys(target);\n const dataKeys = target.data && typeof target.data === 'object' ? Object.keys(target.data) : [];\n return [...new Set([...instanceKeys, ...dataKeys])];\n },\n getOwnPropertyDescriptor(target, prop) {\n // First check if it's an instance property\n const instanceDesc = Reflect.getOwnPropertyDescriptor(target, prop);\n if (instanceDesc) {\n return instanceDesc;\n }\n // Then check if it's a data property (with null check)\n if (typeof prop === 'string' && target.data && typeof target.data === 'object' && prop in target.data) {\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: target.data[prop],\n };\n }\n return undefined;\n },\n });\n }\n\n /**\n * Custom toJSON method to control what gets serialized when logging\n * @returns Serialized data entry including score if available\n */\n toJSON(): Record<string, any> {\n return {\n ...this.data,\n score: this.score,\n id: this.id,\n collectionName: this.collectionName,\n };\n }\n\n /**\n * Custom inspect method for Node.js console.log\n * @returns Formatted data entry for console output\n */\n [Symbol.for('nodejs.util.inspect.custom')](): Record<string, any> {\n return {\n ...this.data,\n score: this.score,\n id: this.id,\n collectionName: this.collectionName,\n };\n }\n\n /**\n * Updates the custom data entry\n * @param data - The data fields to update (partial update supported)\n * @param searchText - Optional new search text for semantic search indexing\n * @returns Promise resolving to the updated data\n * @throws Error if the update fails\n */\n async update(data: Record<string, any>, searchText?: string): Promise<Record<string, any>> {\n try {\n await this.customDataAPI.update(this.collectionName, this.id, data, searchText);\n this.data = { ...this.data, ...data };\n return this.data;\n } catch (error) {\n throw new Error('Failed to update custom data entry');\n }\n }\n\n /**\n * Deletes the custom data entry\n * @returns Promise resolving to true if deletion was successful\n * @throws Error if the deletion fails\n */\n async delete(): Promise<boolean> {\n try {\n await this.customDataAPI.delete(this.collectionName, this.id);\n return true;\n } catch (error) {\n throw new Error('Failed to delete custom data entry');\n }\n }\n\n /**\n * Saves the data entry\n * @param searchText - Optional search text for vector search indexing\n * @returns Promise resolving to true if saving was successful\n * @throws Error if the save operation fails\n */\n async save(searchText?: string): Promise<boolean> {\n try {\n await this.customDataAPI.update(this.collectionName, this.id, this.data, searchText);\n return true;\n } catch (error) {\n throw new Error('Failed to save data entry');\n }\n }\n}\n","import { HttpClient } from './http.client.js';\nimport { CustomDataAPI } from '../types/index.js';\nimport {\n CreateCustomDataResponse,\n GetCustomDataResponse,\n CustomDataEntry,\n UpdateCustomDataResponse,\n SearchCustomDataResponse,\n DeleteCustomDataResponse,\n} from '../interfaces/custom.data.js';\nimport DataEntryInstance from '../instances/data.entry.instance.js';\n\n// Custom Data API calls\nexport default class CustomDataApi extends HttpClient implements CustomDataAPI {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of CustomDataApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Creates a new custom data entry in a specified collection\n * @param collectionName - The name of the collection to create the entry in\n * @param data - The data object to store in the entry\n * @param searchText - Optional text to be used for semantic search indexing\n * @returns Promise resolving to a DataEntryInstance representing the created entry\n * @throws Error if the entry creation fails or the API request is unsuccessful\n */\n async create(collectionName: string, data: Record<string, any>, searchText?: string): Promise<DataEntryInstance> {\n const response = await this.httpPost<CreateCustomDataResponse>(\n `/developer/agents/${this.agentId}/custom-data/${collectionName}`,\n { data, searchText },\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return new DataEntryInstance(this, response.data, collectionName);\n }\n throw new Error(response.error?.message || 'Failed to create custom data entry');\n }\n\n /**\n * Retrieves custom data entries from a collection with optional filtering and pagination\n * @param collectionName - The name of the collection to query\n * @param filter - Optional filter object to apply to the query (JSON-serializable)\n * @param page - The page number for pagination (default: 1)\n * @param limit - The number of entries per page (default: 10)\n * @returns Promise resolving to a GetCustomDataResponse containing the entries and pagination info\n * @throws Error if the query fails or the API request is unsuccessful\n */\n async get(\n collectionName: string,\n filter?: Record<string, any>,\n page: number = 1,\n limit: number = 10\n ): Promise<GetCustomDataResponse> {\n let url = `/developer/agents/${this.agentId}/custom-data/${collectionName}?page=${page}&limit=${limit}`;\n\n if (filter) {\n const encodedFilter = encodeURIComponent(JSON.stringify(filter));\n url += `&filter=${encodedFilter}`;\n }\n\n const response = await this.httpGet<GetCustomDataResponse>(url, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to get custom data entries');\n }\n\n /**\n * Retrieves a single custom data entry by its ID\n * @param collectionName - The name of the collection containing the entry\n * @param entryId - The unique identifier of the entry to retrieve\n * @returns Promise resolving to a DataEntryInstance representing the entry\n * @throws Error if the entry is not found or the API request is unsuccessful\n */\n async getEntry(collectionName: string, entryId: string): Promise<DataEntryInstance> {\n const response = await this.httpGet<CreateCustomDataResponse>(\n `/developer/agents/${this.agentId}/custom-data/${collectionName}/${entryId}`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return new DataEntryInstance(this, response.data, collectionName);\n }\n throw new Error(response.error?.message || 'Failed to get custom data entry');\n }\n\n /**\n * Updates an existing custom data entry\n * @param collectionName - The name of the collection containing the entry\n * @param entryId - The unique identifier of the entry to update\n * @param data - The data object to update\n * @param searchText - Optional text to be used for semantic search indexing\n * @returns Promise resolving to an UpdateCustomDataResponse with the updated entry details\n * @throws Error if the entry is not found or the update fails\n */\n async update(\n collectionName: string,\n entryId: string,\n data: Record<string, any>,\n searchText?: string\n ): Promise<UpdateCustomDataResponse> {\n const response = await this.httpPut<UpdateCustomDataResponse>(\n `/developer/agents/${this.agentId}/custom-data/${collectionName}/${entryId}`,\n { data, searchText },\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to update custom data entry');\n }\n\n /**\n * Performs semantic search on custom data entries using text similarity\n * @param collectionName - The name of the collection to search within\n * @param searchText - The text query to search for\n * @param limit - Maximum number of results to return (default: 10)\n * @param scoreThreshold - Minimum similarity score threshold 0-1 (default: 0.6)\n * @returns Promise resolving to an array of DataEntryInstance objects matching the search\n * @throws Error if the search fails or the API request is unsuccessful\n */\n async search(\n collectionName: string,\n searchText: string,\n limit: number = 10,\n scoreThreshold: number = 0.6\n ): Promise<DataEntryInstance[]> {\n const url = `/developer/agents/${this.agentId}/custom-data/${collectionName}/search?searchText=${encodeURIComponent(searchText)}&limit=${limit}&scoreThreshold=${scoreThreshold}`;\n\n const response = await this.httpGet<SearchCustomDataResponse>(url, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return response.data.data.map((entry) => new DataEntryInstance(this, entry, collectionName));\n }\n throw new Error(response.error?.message || 'Failed to search custom data entries');\n }\n\n /**\n * Deletes a custom data entry from a collection\n * @param collectionName - The name of the collection containing the entry\n * @param entryId - The unique identifier of the entry to delete\n * @returns Promise resolving to a DeleteCustomDataResponse confirming deletion\n * @throws Error if the entry is not found or the deletion fails\n */\n async delete(collectionName: string, entryId: string): Promise<DeleteCustomDataResponse> {\n const response = await this.httpDelete<DeleteCustomDataResponse>(\n `/developer/agents/${this.agentId}/custom-data/${collectionName}/${entryId}`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n if (response.success && response.data) {\n return response.data;\n }\n throw new Error(response.error?.message || 'Failed to delete custom data entry');\n }\n}\n","import { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport {\n CreateWebhookDTO,\n PushWebhookVersionDTO,\n UpdateWebhookDTO,\n UpdateWebhookVersionDTO,\n} from '../interfaces/webhooks.js';\n\n/**\n * Webhook API Response Types\n */\nexport interface WebhookVersion {\n version: string;\n webhookId: string;\n createdAt: string | number;\n isActive?: boolean;\n}\n\nexport interface GetWebhooksResponse {\n webhooks: Array<{\n id: string;\n name: string;\n description?: string;\n public: boolean;\n active: boolean;\n eventSubscriptions: string[];\n createdAt: string;\n updatedAt: string;\n versions: WebhookVersion[];\n activeVersionId?: string;\n }>;\n}\n\nexport interface CreateWebhookResponse {\n id: string;\n name: string;\n description?: string;\n agentId: string;\n}\n\nexport interface WebhookVersionResponse {\n versionId: string;\n webhookId: string;\n version: string;\n createdAt: string;\n}\n\nexport interface UpdateWebhookVersionResponse {\n versionId: string;\n webhookId: string;\n version: string;\n updatedAt: string;\n}\n\nexport interface UpdateWebhookResponse {\n id: string;\n name: string;\n description?: string;\n eventSubscriptions: string[];\n updatedAt: string;\n}\n\nexport interface DeleteWebhookResponse {\n deleted: boolean;\n deactivated?: boolean;\n message: string;\n}\n\n/**\n * Webhook API Service\n * Handles all webhook-related API calls\n */\nexport default class WebhookApi extends HttpClient {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of WebhookApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Retrieves all webhooks for the agent\n * @returns Promise resolving to an ApiResponse containing an array of webhooks with their versions\n * @throws Error if the API request fails or the agent is not found\n */\n async getWebhooks(): Promise<ApiResponse<GetWebhooksResponse>> {\n return this.httpGet<GetWebhooksResponse>(`/developer/webhooks/${this.agentId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Creates a new webhook for the agent\n * @param webhookData - The webhook data including name and description\n * @returns Promise resolving to an ApiResponse containing the created webhook details\n * @throws Error if the webhook creation fails or validation errors occur\n */\n async createWebhook(webhookData: CreateWebhookDTO): Promise<ApiResponse<CreateWebhookResponse>> {\n return this.httpPost<CreateWebhookResponse>(`/developer/webhooks/${this.agentId}`, webhookData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async updateWebhook(webhookId: string, data: UpdateWebhookDTO): Promise<ApiResponse<UpdateWebhookResponse>> {\n return this.httpPatch<UpdateWebhookResponse>(`/developer/webhooks/${this.agentId}/${webhookId}`, data, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Pushes a new version of a webhook to production\n * @param webhookId - The unique identifier of the webhook\n * @param versionData - The version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the created version details\n * @throws Error if the webhook is not found or the push operation fails\n */\n async pushWebhook(\n webhookId: string,\n versionData: PushWebhookVersionDTO\n ): Promise<ApiResponse<WebhookVersionResponse>> {\n return this.httpPost<WebhookVersionResponse>(\n `/developer/webhooks/${this.agentId}/${webhookId}/version`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Pushes a new development/sandbox version of a webhook for testing\n * @param webhookId - The unique identifier of the webhook\n * @param versionData - The version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the development version details\n * @throws Error if the webhook is not found or the push operation fails\n */\n async pushDevWebhook(\n webhookId: string,\n versionData: PushWebhookVersionDTO\n ): Promise<ApiResponse<WebhookVersionResponse>> {\n return this.httpPost<WebhookVersionResponse>(\n `/developer/webhooks/${this.agentId}/${webhookId}/version/sandbox`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Updates an existing development/sandbox version of a webhook\n * @param webhookId - The unique identifier of the webhook\n * @param sandboxVersionId - The unique identifier of the sandbox version to update\n * @param versionData - The updated version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the updated version details\n * @throws Error if the webhook or version is not found or the update fails\n */\n async updateDevWebhook(\n webhookId: string,\n sandboxVersionId: string,\n versionData: UpdateWebhookVersionDTO\n ): Promise<ApiResponse<UpdateWebhookVersionResponse>> {\n return this.httpPut<UpdateWebhookVersionResponse>(\n `/developer/webhooks/${this.agentId}/${webhookId}/version/sandbox/${sandboxVersionId}`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Retrieves all versions of a specific webhook\n * @param webhookId - The unique identifier of the webhook\n * @returns Promise resolving to an ApiResponse containing an array of webhook versions\n * @throws Error if the webhook is not found or the request fails\n */\n async getWebhookVersions(\n webhookId: string\n ): Promise<ApiResponse<{ versions: WebhookVersion[]; activeVersionId?: string }>> {\n return this.httpGet<{ versions: WebhookVersion[]; activeVersionId?: string }>(\n `/developer/webhooks/${this.agentId}/${webhookId}/versions`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Publishes a specific version of a webhook to production\n * @param webhookId - The unique identifier of the webhook\n * @param version - The version identifier to publish\n * @returns Promise resolving to an ApiResponse containing publication confirmation details\n * @throws Error if the webhook or version is not found or the publish operation fails\n */\n async publishWebhookVersion(\n webhookId: string,\n version: string\n ): Promise<ApiResponse<{ message: string; webhookId: string; activeVersionId: string; publishedAt: string }>> {\n return this.httpPost<{ message: string; webhookId: string; activeVersionId: string; publishedAt: string }>(\n `/developer/webhooks/${this.agentId}/${webhookId}/${version}/publish`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Activates a webhook (enables it to receive requests)\n * @param webhookId - The unique identifier of the webhook to activate\n * @returns Promise resolving to an ApiResponse with activation status\n * @throws Error if the webhook is not found or the operation fails\n */\n async activateWebhook(webhookId: string): Promise<ApiResponse<{ message: string; active: boolean }>> {\n return this.httpPost<{ message: string; active: boolean }>(\n `/developer/webhooks/${this.agentId}/${webhookId}/activate`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Deactivates a webhook (stops it from receiving requests)\n * @param webhookId - The unique identifier of the webhook to deactivate\n * @returns Promise resolving to an ApiResponse with deactivation status\n * @throws Error if the webhook is not found or the operation fails\n */\n async deactivateWebhook(webhookId: string): Promise<ApiResponse<{ message: string; active: boolean }>> {\n return this.httpPost<{ message: string; active: boolean }>(\n `/developer/webhooks/${this.agentId}/${webhookId}/deactivate`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Deletes a webhook and all its versions, or deactivates it if it has versions\n * @param webhookId - The unique identifier of the webhook to delete\n * @returns Promise resolving to an ApiResponse with deletion status\n * - If deleted is true: webhook was successfully deleted\n * - If deleted is false and deactivated is true: webhook has versions and was deactivated instead\n * @throws Error if the webhook is not found or the delete operation fails\n */\n async deleteWebhook(webhookId: string): Promise<ApiResponse<DeleteWebhookResponse>> {\n return this.httpDelete<DeleteWebhookResponse>(`/developer/webhooks/${this.agentId}/${webhookId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n}\n","/**\n * Job Instance\n * Provides a convenient interface for interacting with a job\n */\n\nimport JobApi from '../api/job.api.service.js';\nimport UserDataInstance from './user.instance.js';\nimport { UserDataAPI } from '../types/index.js';\nimport UserDataApi from '../api/user.data.api.service.js';\nimport { BASE_URLS } from '../config/constants.js';\nimport { Job, JobVersion, JobExecution } from '../interfaces/jobs.js';\n\n/**\n * Job Instance class.\n * Represents a single job with helper methods for common operations.\n *\n * This class provides:\n * - Direct property access to job data via Proxy\n * - Helper methods for job operations (delete, updateMetadata)\n * - Metadata access and modification\n *\n * @example\n * ```typescript\n * const job = await Jobs.create({\n * name: 'my-job',\n * schedule: { type: 'once', executeAt: new Date() },\n * execute: async (job) => {\n * // Access metadata\n * console.log(job.metadata);\n *\n * // Update metadata\n * await job.updateMetadata({ processed: true });\n *\n * // Delete job when done\n * await job.delete();\n * }\n * });\n * ```\n */\nexport class JobInstance {\n private jobApi: JobApi;\n private _data: Job;\n public readonly id: string;\n public readonly name: string;\n /** The active version of the job (if one exists) */\n public readonly activeVersion?: JobVersion;\n public metadata: Record<string, any>;\n private userApi?: UserDataAPI;\n\n constructor(jobApi: JobApi, jobData: Job) {\n this.jobApi = jobApi;\n this._data = jobData;\n this.id = jobData.id;\n this.name = jobData.name;\n this.activeVersion = jobData.activeVersion;\n this.metadata = jobData.metadata || {};\n if (jobData.userId && jobData.agentId) {\n this.userApi = new UserDataApi(BASE_URLS.API, jobApi.apiKey, jobApi.agentId);\n }\n }\n\n /**\n * Gets the full job data.\n */\n get data(): Job {\n return this._data;\n }\n\n /**\n * Updates the job's metadata.\n *\n * @param metadata - The new metadata to set\n * @returns Promise resolving when update is complete\n *\n * @example\n * ```typescript\n * await job.updateMetadata({\n * lastProcessed: new Date().toISOString(),\n * status: 'completed'\n * });\n * ```\n */\n async updateMetadata(metadata: Record<string, any>): Promise<void> {\n this.metadata = { ...this.metadata, ...metadata };\n\n const result = await this.jobApi.updateMetadata(this.id, this.metadata);\n\n if (!result.success) {\n throw new Error(result.error?.message || 'Failed to update job metadata');\n }\n }\n\n /**\n * Deletes the job from the backend (or deactivates if it has versions).\n *\n * @returns Promise resolving when deletion is complete\n *\n * @example\n * ```typescript\n * // Delete a one-time job after it completes\n * await job.delete();\n * ```\n */\n async delete(): Promise<void> {\n const result = await this.jobApi.deleteJob(this.id);\n\n if (!result.success) {\n throw new Error(result.error?.message || 'Failed to delete job');\n }\n }\n\n /**\n * Gets the user data associated with this job's agent.\n * Provides access to user information and custom data storage.\n *\n * @returns Promise resolving to UserDataInstance with user information\n *\n * @example\n * ```typescript\n * const user = await job.user();\n * console.log('User email:', user.email);\n * console.log('User data:', user.data);\n * ```\n */\n async user(): Promise<UserDataInstance> {\n if (!this.userApi) {\n throw new Error('User API not initialized');\n }\n return await this.userApi.get();\n }\n\n /**\n * Manually triggers the job execution (ignores schedule).\n * Uses activeVersion by default.\n *\n * @param versionId - Optional version to execute (defaults to activeVersion)\n * @returns Promise resolving to execution result\n *\n * @example\n * ```typescript\n * const result = await job.trigger();\n * console.log('Execution result:', result);\n * ```\n */\n async trigger(versionId?: string): Promise<JobExecution> {\n const result = await this.jobApi.triggerJob(this.id, versionId || this.activeVersion?.id);\n\n if (!result.success || !result.data) {\n throw new Error(result.error?.message || 'Failed to trigger job');\n }\n\n return result.data;\n }\n\n /**\n * Activates the job, enabling it to run on schedule.\n *\n * @returns Promise resolving to updated JobInstance\n *\n * @example\n * ```typescript\n * await job.activate();\n * console.log('Job is now active');\n * ```\n */\n async activate(): Promise<JobInstance> {\n const result = await this.jobApi.activateJob(this.id);\n\n if (!result.success || !result.data) {\n throw new Error(result.error?.message || 'Failed to activate job');\n }\n\n this._data = result.data;\n return this;\n }\n\n /**\n * Deactivates the job, preventing it from running on schedule.\n *\n * @returns Promise resolving to updated JobInstance\n *\n * @example\n * ```typescript\n * await job.deactivate();\n * console.log('Job is now inactive');\n * ```\n */\n async deactivate(): Promise<JobInstance> {\n const result = await this.jobApi.deactivateJob(this.id);\n\n if (!result.success || !result.data) {\n throw new Error(result.error?.message || 'Failed to deactivate job');\n }\n\n this._data = result.data;\n return this;\n }\n\n /**\n * Converts the job instance to JSON.\n */\n toJSON(): Job {\n return {\n ...this._data,\n id: this.id,\n name: this.name,\n activeVersion: this.activeVersion,\n metadata: this.metadata,\n };\n }\n}\n","import { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport {\n CreateJobDTO,\n Job,\n JobVersion,\n JobExecution,\n PushJobVersionDTO,\n UpdateJobVersionDTO,\n GetJobsResponseData,\n GetJobExecutionsResponseData,\n DeleteJobResponseData,\n UpdateJobMetadataResponseData,\n} from '../interfaces/jobs.js';\nimport { JobInstance } from '../instances/job.instance.js';\n\n/**\n * Job API Service\n * Handles all job-related API calls\n */\nexport default class JobApi extends HttpClient {\n public apiKey: string;\n public agentId: string;\n\n /**\n * Creates an instance of JobApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Retrieves all jobs for the agent\n * @returns Promise resolving to an ApiResponse containing an array of jobs with their versions\n * @throws Error if the API request fails or the agent is not found\n */\n async getJobs(options: { includeDynamic?: boolean } = {}): Promise<ApiResponse<GetJobsResponseData>> {\n const queryParams = new URLSearchParams();\n if (options.includeDynamic) {\n queryParams.append('includeDynamic', 'true');\n }\n\n const url = `/developer/jobs/${this.agentId}?${queryParams.toString()}`;\n\n return this.httpGet<GetJobsResponseData>(url, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Retrieves all jobs for the agent as JobInstance array\n * @param options - Optional configuration\n * @param options.includeDynamic - Include dynamically created jobs (default: false)\n * @returns Promise resolving to an array of JobInstance\n * @throws Error if the API request fails\n */\n async getAll(options: { includeDynamic?: boolean } = {}): Promise<JobInstance[]> {\n const response = await this.getJobs(options);\n if (response.success && response.data?.jobs) {\n return response.data.jobs.map((job) => new JobInstance(this, job));\n }\n throw new Error(response.error?.message || 'Failed to get all jobs');\n }\n\n /**\n * Retrieves a job by its unique identifier\n * @param jobId - The unique identifier of the job to retrieve\n * @returns Promise resolving to an JobInstance representing the job\n * @throws Error if the job is not found or the request fails\n */\n async getJob(jobId: string): Promise<JobInstance> {\n const response = await this.httpGet<Job>(`/developer/jobs/${this.agentId}/${jobId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return new JobInstance(this, response.data);\n }\n throw new Error(response.error?.message || 'Failed to get job');\n }\n\n /**\n * Creates a new job for the agent.\n * Optionally creates initial version and activates the job in one call.\n *\n * @param jobData - The job data including name, description, schedule, and optional version\n * @param jobData.version - If provided, creates first version automatically\n * @param jobData.activate - If true, activates the job immediately\n * @returns Promise resolving to an ApiResponse containing the full job with versions\n * @throws Error if the job creation fails or validation errors occur\n */\n async createJob(jobData: CreateJobDTO): Promise<ApiResponse<Job>> {\n return this.httpPost<Job>(`/developer/jobs/${this.agentId}`, jobData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Creates a new job for the agent and returns a JobInstance.\n * Supports automatic version creation and activation.\n *\n * @param jobData - The job data including name, description, schedule, and optional version\n * @param jobData.version - If provided, creates first version automatically\n * @param jobData.activate - If true, activates the job immediately\n * @returns Promise resolving to a JobInstance containing the created job details\n * @throws Error if the job creation fails or validation errors occur\n */\n async createJobInstance(jobData: CreateJobDTO): Promise<JobInstance> {\n const response = await this.httpPost<Job>(`/developer/jobs/${this.agentId}`, jobData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n if (response.success && response.data) {\n return new JobInstance(this, response.data);\n }\n throw new Error(response.error?.message || 'Failed to create job');\n }\n\n /**\n * Pushes a new version of a job to production\n * @param jobId - The unique identifier of the job\n * @param versionData - The version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the full job version\n * @throws Error if the job is not found or the push operation fails\n */\n async pushJob(jobId: string, versionData: PushJobVersionDTO): Promise<ApiResponse<JobVersion>> {\n return this.httpPost<JobVersion>(`/developer/jobs/${this.agentId}/${jobId}/version`, versionData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Pushes a new development/sandbox version of a job for testing\n * @param jobId - The unique identifier of the job\n * @param versionData - The version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the full job version\n * @throws Error if the job is not found or the push operation fails\n */\n async pushDevJob(jobId: string, versionData: PushJobVersionDTO): Promise<ApiResponse<JobVersion>> {\n return this.httpPost<JobVersion>(`/developer/jobs/${this.agentId}/${jobId}/version/sandbox`, versionData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Updates an existing development/sandbox version of a job\n * @param jobId - The unique identifier of the job\n * @param sandboxVersionId - The unique identifier of the sandbox version to update\n * @param versionData - The updated version data including code, configuration, and metadata\n * @returns Promise resolving to an ApiResponse containing the full updated job version\n * @throws Error if the job or version is not found or the update fails\n */\n async updateDevJob(\n jobId: string,\n sandboxVersionId: string,\n versionData: UpdateJobVersionDTO\n ): Promise<ApiResponse<JobVersion>> {\n return this.httpPut<JobVersion>(\n `/developer/jobs/${this.agentId}/${jobId}/version/sandbox/${sandboxVersionId}`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Retrieves all versions of a specific job\n * @param jobId - The unique identifier of the job\n * @returns Promise resolving to an ApiResponse containing an array of job versions\n * @throws Error if the job is not found or the request fails\n */\n async getJobVersions(jobId: string): Promise<ApiResponse<JobVersion[]>> {\n return this.httpGet<JobVersion[]>(`/developer/jobs/${this.agentId}/${jobId}/versions`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Publishes a specific version of a job to production\n * @param jobId - The unique identifier of the job\n * @param version - The version identifier to publish\n * @returns Promise resolving to an ApiResponse containing the full updated job\n * @throws Error if the job or version is not found or the publish operation fails\n */\n async publishJobVersion(jobId: string, version: string): Promise<ApiResponse<Job>> {\n return this.httpPost<Job>(\n `/developer/jobs/${this.agentId}/${jobId}/${version}/publish`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Deletes a job and all its versions, or deactivates it if it has versions\n * @param jobId - The unique identifier of the job to delete\n * @returns Promise resolving to an ApiResponse with deletion status\n * - If deleted is true: job was successfully deleted\n * - If deleted is false and deactivated is true: job has versions and was deactivated instead\n * @throws Error if the job is not found or the delete operation fails\n */\n async deleteJob(jobId: string): Promise<ApiResponse<DeleteJobResponseData>> {\n return this.httpDelete<DeleteJobResponseData>(`/developer/jobs/${this.agentId}/${jobId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Activates a job (enables it to run on schedule)\n * @param jobId - The unique identifier of the job to activate\n * @returns Promise resolving to an ApiResponse with the full updated job\n * @throws Error if the job is not found or the operation fails\n */\n async activateJob(jobId: string): Promise<ApiResponse<Job>> {\n return this.httpPost<Job>(\n `/developer/jobs/${this.agentId}/${jobId}/activate`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Deactivates a job (disables it from running)\n * @param jobId - The unique identifier of the job to deactivate\n * @returns Promise resolving to an ApiResponse with the full updated job\n * @throws Error if the job is not found or the operation fails\n */\n async deactivateJob(jobId: string): Promise<ApiResponse<Job>> {\n return this.httpPost<Job>(\n `/developer/jobs/${this.agentId}/${jobId}/deactivate`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Manually triggers a job execution (ignores schedule)\n * @param jobId - The unique identifier of the job to trigger\n * @param versionId - The version identifier to execute (optional, defaults to activeVersionId)\n * @returns Promise resolving to an ApiResponse with the execution record\n * @throws Error if the job is not found or the operation fails\n */\n async triggerJob(jobId: string, versionId?: string): Promise<ApiResponse<JobExecution>> {\n const body = versionId ? { versionId } : {};\n return this.httpPost<JobExecution>(`/developer/jobs/${this.agentId}/${jobId}/trigger`, body, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Retrieves execution history for a job\n * @param jobId - The unique identifier of the job\n * @param limit - Maximum number of executions to return (default: 50)\n * @returns Promise resolving to an ApiResponse with execution history\n * @throws Error if the job is not found or the request fails\n */\n async getJobExecutions(jobId: string, limit: number = 50): Promise<ApiResponse<GetJobExecutionsResponseData>> {\n return this.httpGet<GetJobExecutionsResponseData>(\n `/developer/jobs/${this.agentId}/${jobId}/executions?limit=${limit}`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Updates the metadata of a job\n * @param jobId - The unique identifier of the job\n * @param metadata - The metadata object to update or merge with existing metadata\n * @returns Promise resolving to the updated metadata\n * @throws Error if the job is not found or the metadata update fails\n */\n async updateMetadata(\n jobId: string,\n metadata: Record<string, any>\n ): Promise<ApiResponse<UpdateJobMetadataResponseData>> {\n return this.httpPut<UpdateJobMetadataResponseData>(`/developer/jobs/${this.agentId}/${jobId}/metadata`, metadata, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n}\n","import { aiGenerateInputFromSimplified, type AiGenerateInput, type AiGenerateOutput } from '@lua/shared-types';\nimport type { UserContent } from 'ai';\nimport { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\n\nexport const aiGenerateSimplifiedToBody = aiGenerateInputFromSimplified;\n\n/**\n * Proxies isolated AI generation to lua-api (server-side Gemini + usage).\n */\nexport default class AiApiService extends HttpClient {\n constructor(\n baseUrl: string,\n private readonly apiKey: string,\n private readonly agentId: string\n ) {\n super(baseUrl);\n }\n\n async generate(body: AiGenerateInput): Promise<ApiResponse<AiGenerateOutput>> {\n return this.httpPost<AiGenerateOutput>(`/developer/ai/${this.agentId}/generate`, body, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Handles the simplified-vs-full-options branching for `AI.generate`.\n * Returns plain text for the simplified overload, full output for the options overload.\n */\n async generateForSandbox(\n promptOrOptions: string | AiGenerateInput,\n content?: UserContent\n ): Promise<string | AiGenerateOutput> {\n if (typeof promptOrOptions === 'string') {\n const result = await this.generate(aiGenerateInputFromSimplified(promptOrOptions, content));\n if (!result.success) {\n throw new Error(result.error?.message || 'AI generation failed');\n }\n return result.data?.text ?? '';\n }\n const result = await this.generate(promptOrOptions);\n if (!result.success) {\n throw new Error(result.error?.message || 'AI generation failed');\n }\n if (!result.data) {\n throw new Error('AI generation failed: empty response');\n }\n return result.data;\n }\n}\n","import type { AgentInvocationInput, AgentInvocationOutput } from '@lua/shared-types';\nimport { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\n\n/**\n * Wire body for POST `/chat/generate/:agentId` — mirrors the subset of\n * `ChatMessageDto` that lua-core accepts.\n */\ninterface ChatGenerateBody {\n messages: Array<{ type: 'text'; text: string } | Record<string, unknown>>;\n navigate: boolean;\n systemPrompt?: string;\n runtimeContext?: string;\n threadId?: string;\n}\n\n/**\n * Thin wrapper around `POST /chat/generate/:agentId` used by the lua-cli\n * sandbox's `Agents.invoke`. Mirrors the HTTP pattern `lua chat` already uses\n * — no new endpoint on lua-api / lua-core is required.\n */\nexport default class AgentsApiService extends HttpClient {\n constructor(\n baseUrl: string,\n private readonly apiKey: string\n ) {\n super(baseUrl);\n }\n\n async invoke(targetAgentId: string, body: AgentInvocationInput): Promise<ApiResponse<AgentInvocationOutput>> {\n const channel = body.channel ?? 'agent-invocation';\n const query = new URLSearchParams({ channel });\n if (body.identifier) query.set('identifier', body.identifier);\n const chatBody = this.toChatGenerateBody(body);\n return this.httpPost<AgentInvocationOutput>(`/chat/generate/${targetAgentId}?${query.toString()}`, chatBody, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Sandbox overload: mirrors the `AI.generate` pattern where the simplified\n * `(prompt)` call returns plain text and the `(input)` call returns the\n * full structured output.\n */\n async invokeForSandbox(\n targetAgentId: string,\n promptOrInput: string | AgentInvocationInput\n ): Promise<string | AgentInvocationOutput> {\n const input: AgentInvocationInput = typeof promptOrInput === 'string' ? { prompt: promptOrInput } : promptOrInput;\n\n const result = await this.invoke(targetAgentId, input);\n if (!result.success) {\n throw new Error(result.error?.message || 'Agent invocation failed');\n }\n if (!result.data) {\n throw new Error('Agent invocation failed: empty response');\n }\n\n return typeof promptOrInput === 'string' ? (result.data.text ?? '') : result.data;\n }\n\n private toChatGenerateBody(body: AgentInvocationInput): ChatGenerateBody {\n const messages = body.messages\n ? (body.messages as ChatGenerateBody['messages'])\n : [{ type: 'text' as const, text: body.prompt ?? '' }];\n\n return {\n messages,\n navigate: false,\n ...(body.systemPrompt !== undefined ? { systemPrompt: body.systemPrompt } : {}),\n ...(body.runtimeContext !== undefined ? { runtimeContext: body.runtimeContext } : {}),\n ...(body.threadId !== undefined ? { threadId: body.threadId } : {}),\n };\n }\n}\n","import { HttpClient } from './http.client.js';\nimport { WhatsAppTemplatesAPI } from '../types/index.js';\nimport {\n WhatsAppTemplate,\n PaginatedTemplatesResponse,\n ListTemplatesOptions,\n SendTemplateData,\n SendTemplateResponse,\n} from '../interfaces/whatsapp-templates.js';\n\n/**\n * WhatsApp Templates API Service\n * Handles WhatsApp template operations\n */\nexport default class WhatsAppTemplatesApiService extends HttpClient implements WhatsAppTemplatesAPI {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of WhatsAppTemplatesApiService\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Lists WhatsApp templates for a channel with optional pagination and search\n * @param channelId - The WhatsApp channel identifier\n * @param options - Optional pagination and search options\n * @returns Promise resolving to paginated templates response\n */\n async list(channelId: string, options?: ListTemplatesOptions): Promise<PaginatedTemplatesResponse> {\n const page = options?.page ?? 1;\n const limit = options?.limit ?? 10;\n const search = options?.search;\n\n let url = `/admin/agents/${this.agentId}/channels/${channelId}/whatsapp-templates?page=${page}&limit=${limit}`;\n\n if (search) {\n url += `&search=${encodeURIComponent(search)}`;\n }\n\n const response = await this.httpGet<PaginatedTemplatesResponse>(url, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n\n if (response.success) {\n return response.data as PaginatedTemplatesResponse;\n }\n throw new Error(response.error?.message || 'Failed to list templates');\n }\n\n /**\n * Gets a specific WhatsApp template by ID\n * @param channelId - The WhatsApp channel identifier\n * @param templateId - The template identifier\n * @returns Promise resolving to the template\n */\n async get(channelId: string, templateId: string): Promise<WhatsAppTemplate> {\n const url = `/admin/agents/${this.agentId}/channels/${channelId}/whatsapp-templates/${templateId}`;\n\n const response = await this.httpGet<WhatsAppTemplate>(url, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n\n if (response.success) {\n return response.data as WhatsAppTemplate;\n }\n throw new Error(response.error?.message || 'Failed to get template');\n }\n\n /**\n * Sends a WhatsApp template message to one or more phone numbers\n * @param channelId - The WhatsApp channel identifier\n * @param templateId - The template identifier\n * @param data - Send data including phone numbers and template values\n * @returns Promise resolving to the send response with results and errors\n */\n async send(channelId: string, templateId: string, data: SendTemplateData): Promise<SendTemplateResponse> {\n const url = `/admin/agents/${this.agentId}/channels/${channelId}/whatsapp-templates/${templateId}/trigger`;\n\n // Transform to API format (phoneNumbers -> phone_numbers)\n const body = {\n phone_numbers: data.phoneNumbers,\n values: data.values,\n };\n\n const response = await this.httpPost<SendTemplateResponse>(url, body, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n\n if (response.success) {\n return response.data as SendTemplateResponse;\n }\n throw new Error(response.error?.message || 'Failed to send template');\n }\n}\n","/**\n * CDN API Service\n * Handles file upload and retrieval from the Lua CDN\n */\n\nimport { CdnAPI } from '../types/api-contracts.js';\nimport { CdnUploadResponse } from '../interfaces/cdn.js';\n\nexport default class CdnApi implements CdnAPI {\n private baseUrl: string;\n private apiKey: string;\n\n constructor(baseUrl: string, apiKey: string) {\n this.baseUrl = baseUrl;\n this.apiKey = apiKey;\n }\n\n /**\n * Uploads a file to the CDN\n * @param file - The file to upload\n * @returns Promise resolving to the file ID\n */\n async upload(file: File): Promise<string> {\n const formData = new FormData();\n formData.append('file', file, file.name);\n\n const response = await fetch(`${this.baseUrl}/upload`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${this.apiKey}` },\n body: formData,\n });\n\n if (!response.ok) {\n const error = (await response.json().catch(() => ({}))) as Record<string, any>;\n throw new Error(error.message || `Upload failed: ${response.status}`);\n }\n\n const data = (await response.json()) as CdnUploadResponse;\n return data.fileId;\n }\n\n /**\n * Fetches a file from the CDN by its ID\n */\n async get(fileId: string): Promise<File> {\n const response = await fetch(`${this.baseUrl}/${fileId}`);\n\n if (!response.ok) {\n throw new Error(`File not found: ${response.status}`);\n }\n\n const contentType = response.headers.get('content-type') || 'application/octet-stream';\n const contentDisposition = response.headers.get('content-disposition') || '';\n const filenameMatch = contentDisposition.match(/filename=\"?([^\"]+)\"?/);\n const filename = filenameMatch?.[1] || fileId;\n\n const blob = await response.blob();\n return new File([blob], filename, { type: contentType });\n }\n}\n","import { HttpClient } from './http.client.js';\nimport { ApiResponse, MCPServerResponse, CreateMCPServerRequest, UpdateMCPServerRequest } from '../interfaces/index.js';\nimport { ProfileResponse } from '../interfaces/user.js';\n\n/**\n * Environment variables response structure from the API\n * The actual environment variables are nested in the 'data' property\n */\ninterface EnvironmentVariablesResponse {\n data: Record<string, string>;\n _id?: string;\n agentId?: string;\n createdAt?: string;\n updatedAt?: string;\n __v?: number;\n}\n\n/**\n * Developer API calls for agent management and configuration\n */\nexport default class DeveloperApi extends HttpClient {\n private apiKey: string;\n private agentId: string;\n\n /**\n * Creates an instance of DeveloperApi\n * @param baseUrl - The base URL for the API\n * @param apiKey - The API key for authentication\n * @param agentId - The unique identifier of the agent\n */\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n /**\n * Retrieves all environment variables for the agent in production\n * The response includes metadata (_id, agentId, timestamps) and the actual env vars in the 'data' property\n * @returns Promise resolving to an ApiResponse containing environment variables and metadata\n * @throws Error if the API request fails or the agent is not found\n */\n async getEnvironmentVariables(): Promise<ApiResponse<EnvironmentVariablesResponse>> {\n return this.httpGet<EnvironmentVariablesResponse>(`/developer/agents/${this.agentId}/env`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Updates all environment variables for the agent in production\n * This operation replaces all existing environment variables with the provided set\n * @param envData - Object containing environment variable key-value pairs\n * @returns Promise resolving to an ApiResponse with the updated environment variables and metadata\n * @throws Error if the API request fails or the agent is not found\n */\n async updateEnvironmentVariables(\n envData: Record<string, string>\n ): Promise<ApiResponse<EnvironmentVariablesResponse>> {\n return this.httpPost<EnvironmentVariablesResponse>(`/developer/agents/${this.agentId}/env`, envData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Deletes a specific environment variable by key\n * @param key - The environment variable key to delete\n * @returns Promise resolving to an ApiResponse with confirmation\n * @throws Error if the API request fails, the agent is not found, or the key doesn't exist\n */\n async deleteEnvironmentVariable(key: string): Promise<ApiResponse<{ message: string; key: string }>> {\n return this.httpDelete<{ message: string; key: string }>(`/developer/agents/${this.agentId}/env/${key}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Retrieves all MCP server configurations for the agent\n * @returns Promise resolving to an ApiResponse containing MCP server configurations\n */\n async getMCPServers(): Promise<ApiResponse<MCPServerResponse[]>> {\n return this.httpGet<MCPServerResponse[]>(`/developer/agents/${this.agentId}/mcp-servers`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Retrieves only active MCP server configurations for the agent\n * @returns Promise resolving to an ApiResponse containing active MCP server configurations\n */\n async getActiveMCPServers(): Promise<ApiResponse<MCPServerResponse[]>> {\n return this.httpGet<MCPServerResponse[]>(`/developer/agents/${this.agentId}/mcp-servers/active`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Gets a single MCP server by ID\n * @param mcpServerId - The ID of the MCP server\n * @returns Promise resolving to an ApiResponse with the MCP server\n */\n async getMCPServer(mcpServerId: string): Promise<ApiResponse<MCPServerResponse>> {\n return this.httpGet<MCPServerResponse>(`/developer/agents/${this.agentId}/mcp-servers/${mcpServerId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Creates a new MCP server\n * @param mcpServerData - The MCP server configuration\n * @returns Promise resolving to an ApiResponse with the created MCP server\n */\n async createMCPServer(mcpServerData: CreateMCPServerRequest): Promise<ApiResponse<MCPServerResponse>> {\n return this.httpPost<MCPServerResponse>(`/developer/agents/${this.agentId}/mcp-servers`, mcpServerData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Updates an existing MCP server\n * @param mcpServerId - The ID of the MCP server to update\n * @param mcpServerData - The updated MCP server configuration\n * @returns Promise resolving to an ApiResponse with the updated MCP server\n */\n async updateMCPServer(\n mcpServerId: string,\n mcpServerData: UpdateMCPServerRequest\n ): Promise<ApiResponse<MCPServerResponse>> {\n return this.httpPut<MCPServerResponse>(\n `/developer/agents/${this.agentId}/mcp-servers/${mcpServerId}`,\n mcpServerData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Deletes an MCP server\n * @param mcpServerId - The ID of the MCP server to delete\n * @returns Promise resolving to an ApiResponse with confirmation\n */\n async deleteMCPServer(mcpServerId: string): Promise<ApiResponse<void>> {\n return this.httpDelete<void>(`/developer/agents/${this.agentId}/mcp-servers/${mcpServerId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Activates an MCP server\n * @param mcpServerId - The ID of the MCP server to activate\n * @returns Promise resolving to an ApiResponse with the activated MCP server\n */\n async activateMCPServer(mcpServerId: string): Promise<ApiResponse<MCPServerResponse>> {\n return this.httpPut<MCPServerResponse>(\n `/developer/agents/${this.agentId}/mcp-servers/${mcpServerId}/activate`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Deactivates an MCP server\n * @param mcpServerId - The ID of the MCP server to deactivate\n * @returns Promise resolving to an ApiResponse with the deactivated MCP server\n */\n async deactivateMCPServer(mcpServerId: string): Promise<ApiResponse<MCPServerResponse>> {\n return this.httpPut<MCPServerResponse>(\n `/developer/agents/${this.agentId}/mcp-servers/${mcpServerId}/deactivate`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n /**\n * Creates or updates an MCP server by name (upsert)\n * @param mcpServerData - The MCP server configuration\n * @returns Promise resolving to an ApiResponse with the created/updated MCP server\n */\n async upsertMCPServer(mcpServerData: CreateMCPServerRequest): Promise<ApiResponse<MCPServerResponse>> {\n return this.httpPost<MCPServerResponse>(`/developer/agents/${this.agentId}/mcp-servers/upsert`, mcpServerData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Gets a user profile by email address\n * @param email - The email address to look up\n * @returns Promise resolving to an ApiResponse containing the profile, or null if not found\n */\n async getUserProfileByEmail(email: string): Promise<ApiResponse<ProfileResponse>> {\n return this.httpGet<ProfileResponse>(`/developer/user/profile/email/${encodeURIComponent(email)}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Gets a user profile by phone number\n * @param phone - The phone number to look up (with or without + prefix)\n * @returns Promise resolving to an ApiResponse containing the profile, or null if not found\n */\n async getUserProfileByPhone(phone: string): Promise<ApiResponse<ProfileResponse>> {\n const normalizedPhone = phone.replace(/^\\+/, '');\n return this.httpGet<ProfileResponse>(`/developer/user/profile/phone/${normalizedPhone}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n}\n","import type { VoiceDispatchInput, VoiceDispatchOutput } from '@lua/shared-types';\nimport { DevVersionResponse } from '../interfaces/dev.js';\nimport { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport {\n GetVoicesResponse,\n DeleteVoiceResponse,\n CreateVoiceRequest,\n CreateVoiceResponse,\n PushVoiceVersionRequest,\n GetVoiceVersionsResponse,\n} from '../interfaces/voices.js';\n\n/**\n * Voice API client — CRUD + version management for code-defined LuaVoice\n * agents on the developer API.\n */\nexport default class VoiceApi extends HttpClient {\n private apiKey: string;\n private agentId: string;\n\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n async getVoices(): Promise<ApiResponse<GetVoicesResponse>> {\n return this.httpGet<GetVoicesResponse>(`/developer/voice-agents/${this.agentId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async createVoice(voiceData: CreateVoiceRequest): Promise<ApiResponse<CreateVoiceResponse>> {\n return this.httpPost<CreateVoiceResponse>(`/developer/voice-agents/${this.agentId}`, voiceData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async pushVoice(voiceId: string, versionData: PushVoiceVersionRequest): Promise<ApiResponse<DevVersionResponse>> {\n return this.httpPost<DevVersionResponse>(\n `/developer/voice-agents/${this.agentId}/${voiceId}/version`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async getVoiceVersions(voiceId: string): Promise<ApiResponse<GetVoiceVersionsResponse>> {\n return this.httpGet<GetVoiceVersionsResponse>(`/developer/voice-agents/${this.agentId}/${voiceId}/versions`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async publishVoiceVersion(\n voiceId: string,\n version: string\n ): Promise<ApiResponse<{ message: string; voiceId: string; activeVersionId: string; publishedAt: string }>> {\n return this.httpPut<{ message: string; voiceId: string; activeVersionId: string; publishedAt: string }>(\n `/developer/voice-agents/${this.agentId}/${voiceId}/${version}/publish`,\n undefined,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async deleteVoice(voiceId: string): Promise<ApiResponse<DeleteVoiceResponse>> {\n return this.httpDelete<DeleteVoiceResponse>(`/developer/voice-agents/${this.agentId}/${voiceId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Place an outbound voice call. Wraps `POST /developer/voice-agents/:agentId/dispatch`\n * — body validated server-side (target, voice ownership, quota), then\n * forwarded to the lua-livekit worker which allocates the room and dials.\n */\n async dispatch(input: VoiceDispatchInput): Promise<ApiResponse<VoiceDispatchOutput>> {\n return this.httpPost<VoiceDispatchOutput>(`/developer/voice-agents/${this.agentId}/dispatch`, input, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n /**\n * Sandbox helper: throws on non-success and returns the unwrapped output.\n * Mirrors the shape `AgentsApiService.invokeForSandbox` exposes so the\n * `Voice` namespace in `api-exports.ts` stays a one-liner.\n */\n async dispatchForSandbox(input: VoiceDispatchInput): Promise<VoiceDispatchOutput> {\n const result = await this.dispatch(input);\n if (!result.success) {\n throw new Error(result.error?.message || 'Voice dispatch failed');\n }\n if (!result.data) {\n throw new Error('Voice dispatch failed: empty response');\n }\n return result.data;\n }\n}\n","import { HttpClient } from './http.client.js';\nimport { ApiResponse } from '../interfaces/common.js';\nimport type { CreateDeviceRequest, DeviceResponse, PushDeviceVersionDTO } from '../interfaces/devices.js';\n\n/**\n * Device API Response Types\n */\nexport interface DeviceVersion {\n version: string;\n deviceId: string;\n createdAt: string | number;\n isActive?: boolean;\n}\n\nexport interface GetDevicesResponse {\n devices: DeviceResponse[];\n}\n\nexport interface CreateDeviceResponse {\n id: string;\n name: string;\n description?: string;\n agentId: string;\n}\n\nexport interface PushDeviceVersionResponse {\n versionId: string;\n deviceId: string;\n version: string;\n createdAt: string;\n}\n\n/**\n * Device API Service\n * Handles all device-related API calls (CRUD, versioning, commands)\n */\nexport default class DeviceApi extends HttpClient {\n private apiKey: string;\n private agentId: string;\n\n constructor(baseUrl: string, apiKey: string, agentId: string) {\n super(baseUrl);\n this.apiKey = apiKey;\n this.agentId = agentId;\n }\n\n async getDevices(): Promise<ApiResponse<GetDevicesResponse>> {\n return this.httpGet<GetDevicesResponse>(`/developer/devices/${this.agentId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async createDevice(deviceData: CreateDeviceRequest): Promise<ApiResponse<CreateDeviceResponse>> {\n return this.httpPost<CreateDeviceResponse>(`/developer/devices/${this.agentId}`, deviceData, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async pushDevice(\n deviceId: string,\n versionData: PushDeviceVersionDTO\n ): Promise<ApiResponse<PushDeviceVersionResponse>> {\n return this.httpPost<PushDeviceVersionResponse>(\n `/developer/devices/${this.agentId}/${deviceId}/version`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async pushDevDevice(\n deviceId: string,\n versionData: PushDeviceVersionDTO\n ): Promise<ApiResponse<PushDeviceVersionResponse>> {\n return this.httpPost<PushDeviceVersionResponse>(\n `/developer/devices/${this.agentId}/${deviceId}/version/sandbox`,\n versionData,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async getDeviceVersions(\n deviceId: string\n ): Promise<ApiResponse<{ versions: DeviceVersion[]; activeVersionId?: string }>> {\n return this.httpGet<{ versions: DeviceVersion[]; activeVersionId?: string }>(\n `/developer/devices/${this.agentId}/${deviceId}/versions`,\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async publishDeviceVersion(\n deviceId: string,\n version: string\n ): Promise<ApiResponse<{ message: string; deviceId: string; activeVersionId: string; publishedAt: string }>> {\n return this.httpPost<{ message: string; deviceId: string; activeVersionId: string; publishedAt: string }>(\n `/developer/devices/${this.agentId}/${deviceId}/${version}/publish`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async deleteDevice(deviceId: string): Promise<ApiResponse<{ deleted: boolean; message: string }>> {\n return this.httpDelete<{ deleted: boolean; message: string }>(`/developer/devices/${this.agentId}/${deviceId}`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async sendCommand(deviceName: string, command: string, payload: any, timeout?: number): Promise<ApiResponse<any>> {\n return this.httpPost<any>(\n `/developer/devices/${this.agentId}/${deviceName}/command`,\n {\n command,\n payload,\n timeout: timeout || 30000,\n },\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async getDeviceStatus(deviceName: string): Promise<ApiResponse<{ status: string }>> {\n return this.httpGet<{ status: string }>(`/developer/devices/${this.agentId}/${deviceName}/status`, {\n Authorization: `Bearer ${this.apiKey}`,\n });\n }\n\n async enableDevice(deviceName: string): Promise<ApiResponse<any>> {\n return this.httpPatch<any>(\n `/developer/devices/${this.agentId}/${deviceName}/enable`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n\n async disableDevice(deviceName: string): Promise<ApiResponse<any>> {\n return this.httpPatch<any>(\n `/developer/devices/${this.agentId}/${deviceName}/disable`,\n {},\n {\n Authorization: `Bearer ${this.apiKey}`,\n }\n );\n }\n}\n","/**\n * Lazy-Loaded API Instances\n * Provides singleton instances of API services with lazy initialization\n */\n\nimport { BASE_URLS } from '../config/constants.js';\nimport { getCredentials } from './credentials.js';\nimport ProductApiService from './products.api.service.js';\nimport BasketApiService from './basket.api.service.js';\nimport OrderApiService from './order.api.service.js';\nimport UserDataApiService from './user.data.api.service.js';\nimport CustomDataApiService from './custom.data.api.service.js';\nimport WebhookApi from './webhook.api.service.js';\nimport JobApi from './job.api.service.js';\nimport AiApiService from './ai.api.service.js';\nimport AgentsApiService from './agents.api.service.js';\nimport WhatsAppTemplatesApiService from './whatsapp-templates.api.service.js';\nimport CdnApi from './cdn.api.service.js';\nimport DeveloperApi from './developer.api.service.js';\nimport VoiceApi from './voice.api.service.js';\nimport { JobInstance } from '../instances/job.instance.js';\n\n/**\n * Singleton instances (lazy-loaded)\n */\nlet _userInstance: UserDataApiService | null = null;\nlet _dataInstance: CustomDataApiService | null = null;\nlet _productsInstance: ProductApiService | null = null;\nlet _basketsInstance: BasketApiService | null = null;\nlet _orderInstance: OrderApiService | null = null;\nlet _webhookInstance: WebhookApi | null = null;\nlet _jobInstance: JobApi | null = null;\nlet _aiInstance: AiApiService | null = null;\nlet _agentsInstance: AgentsApiService | null = null;\nlet _whatsAppTemplatesInstance: WhatsAppTemplatesApiService | null = null;\nlet _cdnInstance: CdnApi | null = null;\nlet _developerInstance: DeveloperApi | null = null;\nlet _voiceInstance: VoiceApi | null = null;\n\n/**\n * Gets or creates User Data API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns UserDataApiService instance\n */\nexport async function getUserInstance(): Promise<UserDataApiService> {\n if (!_userInstance) {\n const creds = await getCredentials();\n _userInstance = new UserDataApiService(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _userInstance;\n}\n\n/**\n * Gets or creates Custom Data API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns CustomDataApiService instance\n */\nexport async function getDataInstance(): Promise<CustomDataApiService> {\n if (!_dataInstance) {\n const creds = await getCredentials();\n _dataInstance = new CustomDataApiService(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _dataInstance;\n}\n\n/**\n * Gets or creates Products API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns ProductApiService instance\n */\nexport async function getProductsInstance(): Promise<ProductApiService> {\n if (!_productsInstance) {\n const creds = await getCredentials();\n _productsInstance = new ProductApiService(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _productsInstance;\n}\n\n/**\n * Gets or creates Baskets API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns BasketApiService instance\n */\nexport async function getBasketsInstance(): Promise<BasketApiService> {\n if (!_basketsInstance) {\n const creds = await getCredentials();\n _basketsInstance = new BasketApiService(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _basketsInstance;\n}\n\n/**\n * Gets or creates Orders API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns OrderApiService instance\n */\nexport async function getOrderInstance(): Promise<OrderApiService> {\n if (!_orderInstance) {\n const creds = await getCredentials();\n _orderInstance = new OrderApiService(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _orderInstance;\n}\n\n/**\n * Gets or creates Webhook API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns WebhookApi instance\n */\nexport async function getWebhookInstance(): Promise<WebhookApi> {\n if (!_webhookInstance) {\n const creds = await getCredentials();\n _webhookInstance = new WebhookApi(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _webhookInstance;\n}\n\n/**\n * Gets or creates Job API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns JobApi instance\n */\nexport async function getJobInstance(): Promise<JobApi> {\n if (!_jobInstance) {\n const creds = await getCredentials();\n _jobInstance = new JobApi(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _jobInstance;\n}\n\n/**\n * Gets or creates AI API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns AiApiService instance\n */\nexport async function getAiInstance(): Promise<AiApiService> {\n if (!_aiInstance) {\n const creds = await getCredentials();\n _aiInstance = new AiApiService(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _aiInstance;\n}\n\n/**\n * Gets or creates Agents API instance (for VM `Agents.invoke`).\n * Instance is created once and reused for subsequent calls.\n *\n * @returns AgentsApiService instance\n */\nexport async function getAgentsInstance(): Promise<AgentsApiService> {\n if (!_agentsInstance) {\n const creds = await getCredentials();\n _agentsInstance = new AgentsApiService(BASE_URLS.API, creds.apiKey);\n }\n return _agentsInstance;\n}\n\n/**\n * Gets or creates Templates API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns WhatsAppTemplatesApiService instance\n */\nexport async function getWhatsAppTemplatesInstance(): Promise<WhatsAppTemplatesApiService> {\n if (!_whatsAppTemplatesInstance) {\n const creds = await getCredentials();\n _whatsAppTemplatesInstance = new WhatsAppTemplatesApiService(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _whatsAppTemplatesInstance;\n}\n\n/**\n * Gets or creates CDN API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns CdnApi instance\n */\nexport async function getCdnInstance(): Promise<CdnApi> {\n if (!_cdnInstance) {\n const creds = await getCredentials();\n _cdnInstance = new CdnApi(BASE_URLS.CDN, creds.apiKey);\n }\n return _cdnInstance;\n}\n\n/**\n * Gets or creates Device API instance.\n */\nlet _deviceInstance: any = null;\nexport async function getDeviceInstance(): Promise<any> {\n if (!_deviceInstance) {\n const { default: DeviceApi } = await import('./device.api.service.js');\n const creds = await getCredentials();\n _deviceInstance = new DeviceApi(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _deviceInstance;\n}\n\n/**\n * Gets or creates Developer API instance.\n * Instance is created once and reused for subsequent calls.\n *\n * @returns DeveloperApi instance\n */\nexport async function getDeveloperInstance(): Promise<DeveloperApi> {\n if (!_developerInstance) {\n const creds = await getCredentials();\n _developerInstance = new DeveloperApi(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _developerInstance;\n}\n\n/**\n * Gets or creates Voice API instance (for sandbox `Voice.call` outbound dispatch).\n * Instance is created once and reused for subsequent calls.\n *\n * @returns VoiceApi instance\n */\nexport async function getVoiceInstance(): Promise<VoiceApi> {\n if (!_voiceInstance) {\n const creds = await getCredentials();\n _voiceInstance = new VoiceApi(BASE_URLS.API, creds.apiKey, creds.agentId);\n }\n return _voiceInstance;\n}\n\n/**\n * Clears all cached API instances.\n * Useful for testing or when credentials change.\n */\nexport function clearAllInstances(): void {\n _userInstance = null;\n _dataInstance = null;\n _productsInstance = null;\n _basketsInstance = null;\n _orderInstance = null;\n _webhookInstance = null;\n _jobInstance = null;\n _aiInstance = null;\n _agentsInstance = null;\n _whatsAppTemplatesInstance = null;\n _cdnInstance = null;\n _developerInstance = null;\n _voiceInstance = null;\n}\n","/**\n * Tool Validation Utilities\n * Validates tool names and other tool-related constraints\n */\n\n/**\n * Validates that a tool name contains only alphanumeric characters, hyphens, and underscores.\n * No spaces or other special characters are allowed.\n *\n * This restriction ensures tool names:\n * - Are compatible with all systems\n * - Can be used in URLs and file paths\n * - Are easy to reference in code\n *\n * Valid examples: \"my-tool\", \"calculate_sum\", \"getTodo123\"\n * Invalid examples: \"my tool\", \"calc@sum\", \"get.todo\"\n *\n * @param name - Tool name to validate\n * @returns True if name is valid, false otherwise\n */\nexport function validateToolName(name: string): boolean {\n const validNameRegex = /^[a-zA-Z0-9_-]+$/;\n return validNameRegex.test(name);\n}\n\n/**\n * Asserts that a tool name is valid, throwing an error if not.\n * Use this when adding tools to ensure names are valid.\n *\n * @param name - Tool name to validate\n * @throws Error if tool name is invalid\n *\n * @example\n * ```typescript\n * assertValidToolName('my-tool'); // OK\n * assertValidToolName('my tool'); // Throws error\n * ```\n */\nexport function assertValidToolName(name: string): void {\n if (!validateToolName(name)) {\n throw new Error(\n `Invalid tool name \"${name}\". Tool names can only contain alphanumeric characters, ` +\n `hyphens (-), and underscores (_). No spaces or other special characters are allowed.`\n );\n }\n}\n","/**\n * Lua Skill System\n * Core types and classes for building Lua AI skills\n */\n\nimport { ZodType } from 'zod';\nimport { assertValidToolName } from './tool-validation.js';\nimport UserDataInstance from '../instances/user.instance.js';\nimport { JobInstance } from '../instances/job.instance.js';\nimport type { LuaRequest } from '../interfaces/lua.js';\nimport type { PersonaText, SkillContextText } from '@lua/shared-types';\n// Type-only — voice.ts imports the ToolFlag enum from this file, so a\n// value-level import here would create a cycle.\nimport type { LuaVoice } from './voice.js';\n\n/**\n * Safe environment variable access function.\n * Gets injected at runtime with skill-specific environment variables.\n *\n * Checks process environment variables (.env file)\n *\n * @param key - The environment variable key to retrieve\n * @returns The environment variable value or undefined if not found\n *\n * @example\n * ```typescript\n * const baseUrl = env('BASE_URL');\n * const apiKey = env('API_KEY');\n * ```\n */\nexport const env = (key: string): string | undefined => {\n if (process.env[key]) {\n return process.env[key];\n }\n\n return undefined;\n};\n\n/**\n * Lua Tool interface.\n * Defines the structure of a tool that can be added to a LuaSkill.\n *\n * @template TInput - Zod schema type for input validation\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n * import { LuaTool } from 'lua-cli';\n *\n * const weatherTool: LuaTool = {\n * name: 'get_weather',\n * description: 'Gets current weather for a city',\n * inputSchema: z.object({\n * city: z.string(),\n * units: z.enum(['metric', 'imperial']).optional()\n * }),\n * execute: async (input) => {\n * // Fetch weather data...\n * return { temperature: 72, condition: 'sunny' };\n * }\n * };\n * ```\n *\n * @example\n * ```typescript\n * // Tool with condition - only available to premium users\n * class PremiumSearchTool implements LuaTool {\n * name = \"premium_search\";\n * description = \"Advanced search for premium users\";\n * inputSchema = z.object({ query: z.string() });\n *\n * // Condition runs before tool is offered to LLM\n * condition = async () => {\n * const user = await User.get();\n * return user.data?.isPremium === true;\n * };\n *\n * execute = async (input) => { ... };\n * }\n * ```\n */\n/**\n * Tool-level flags mirrored from LiveKit's `ToolFlag`. Used by `LuaTool.voice.flags`\n * to control tool availability + interruption semantics during a voice session.\n * Defined here (not voice.ts) so LuaTool's voice metadata stays self-contained\n * with no risk of circular imports.\n */\nexport enum ToolFlag {\n NONE = 'none',\n /** Tool is hidden from the LLM during the first turn after onEnter. */\n IGNORE_ON_ENTER = 'ignore_on_enter',\n /** User speech does not interrupt the agent while this tool is executing. */\n DISALLOW_INTERRUPTION = 'disallow_interruption',\n}\n\n/**\n * Per-call context passed to a `LuaTool.execute` running inside a voice\n * session. Imported here (rather than in `voice.ts`) to break a circular\n * import — `LuaVoiceTool` extends `LuaTool` and would otherwise loop.\n *\n * The chat path (lua-core's vm-execution) doesn't pass a second arg, so\n * `ctx` is `undefined` for chat. The voice path passes `{ toolCallId,\n * voice: { say } }`. Tools that want to act differently inside a voice\n * call check for `ctx?.voice` and use the typed surface.\n */\nexport interface LuaToolCtx {\n /** LiveKit's tool-call id (voice only). */\n toolCallId?: string;\n /** Voice-runtime delegates. Only set when the tool runs over voice. */\n voice?: {\n say(text: string): Promise<void>;\n };\n}\n\nexport interface LuaTool<TInput extends ZodType = ZodType> {\n /** Unique tool name (alphanumeric, hyphens, underscores only) */\n name: string;\n /** Description of what the tool does */\n description: string;\n /** Zod schema for input validation */\n inputSchema: TInput;\n /**\n * Async function that executes the tool logic.\n *\n * `ctx` is `undefined` when the tool runs from the chat path (lua-core's\n * vm-execution doesn't pass a second arg today). When the tool runs\n * inside a voice session, `ctx` carries the voice runtime's delegates\n * (`ctx.voice.say(...)` to emit a spoken acknowledgement, plus the\n * `toolCallId` LiveKit assigned). Tools that want to bridge both modes\n * read `ctx?.voice` and branch.\n */\n execute: (input: any, ctx?: LuaToolCtx) => Promise<any>;\n /** Optional async function that determines if the tool should be available */\n condition?: () => Promise<boolean>;\n /**\n * Optional voice-only metadata. When present, the lua-livekit worker\n * applies these flags to the wrapped LiveKit `llm.tool()` registration.\n * Tools without this field work in chat and voice unchanged.\n */\n voice?: { flags?: ToolFlag[] };\n}\n\n/**\n * Lua Skill configuration.\n * Used to initialize a new LuaSkill instance.\n */\nexport interface LuaSkillConfig {\n /** Skill name (required; used as the server-side identifier). */\n name: string;\n /** Short description of the skill (1-2 sentences) */\n description: string;\n /** Detailed context for how the agent should use the tools */\n context: SkillContextText;\n /** Optional array of tools to add during construction */\n tools?: LuaTool<any>[];\n}\n\n/**\n * Lua Skill class.\n * Main class for building AI skills with tools.\n *\n * A skill is a collection of tools that the AI agent can use to accomplish tasks.\n * Tools are functions with validated inputs and well-defined outputs.\n *\n * @example\n * ```typescript\n * import { LuaSkill } from 'lua-cli';\n *\n * const skill = new LuaSkill({\n * name: 'weather-skill',\n * description: \"Weather and calculator utilities\",\n * context: \"This skill provides weather information and math operations. \" +\n * \"Use get_weather for current conditions and calculator for arithmetic.\",\n * tools: [weatherTool, calculatorTool]\n * });\n *\n * // Or add tools after construction\n * skill.addTool(anotherTool);\n * ```\n */\nexport class LuaSkill {\n private readonly tools: LuaTool<any>[] = [];\n private readonly name: string;\n private readonly description: string;\n private readonly context: SkillContextText;\n\n /**\n * Creates a new LuaSkill instance.\n *\n * @param config - Configuration object containing skill metadata\n * @param config.name - Skill name (required; non-empty string)\n * @param config.description - Short description of what the skill does (1-2 sentences)\n * @param config.context - Detailed explanation of how the agent should use the tools\n * @param config.tools - Optional array of tools to add immediately\n */\n constructor(config: LuaSkillConfig) {\n if (!config.name || !config.name.trim()) {\n throw new Error('LuaSkill requires a non-empty `name` (used as the server-side identifier).');\n }\n this.name = config.name;\n this.description = config.description;\n this.context = config.context;\n\n if (typeof this.context === 'object') {\n if (!this.context.base && !this.context.voice && !this.context.text) {\n throw new Error('Skill context object must have at least one of: base, voice, text');\n }\n }\n\n // Add tools from constructor if provided\n if (config.tools) {\n this.addTools(config.tools);\n }\n }\n\n getContext(): SkillContextText {\n return this.context;\n }\n\n /**\n * Adds a single tool to the skill.\n * Tool name is validated before being added.\n *\n * @param tool - Tool to add\n * @throws Error if tool name is invalid\n */\n addTool<TInput extends ZodType>(tool: LuaTool<TInput>): void {\n assertValidToolName(tool.name);\n this.tools.push(tool);\n }\n\n /**\n * Adds multiple tools to the skill.\n * All tool names are validated before being added.\n *\n * @param tools - Array of tools to add\n * @throws Error if any tool name is invalid\n */\n addTools(tools: LuaTool<any>[]): void {\n // Validate all tool names before adding them\n for (const tool of tools) {\n assertValidToolName(tool.name);\n }\n this.tools.push(...tools);\n }\n\n /**\n * Executes a tool by name with provided input.\n * Input is validated against the tool's Zod schema.\n *\n * @param input - Input object containing tool name and parameters\n * @param input.tool - Name of the tool to execute\n * @returns Promise resolving to tool execution result\n * @throws Error if tool not found or input validation fails\n */\n async run(input: Record<string, any>) {\n const tool = this.tools.find((tool) => tool.name === input.tool);\n if (!tool) {\n throw new Error(`Tool ${input.tool} not found`);\n }\n\n // Validate input against the tool's schema\n const validatedInput = tool.inputSchema.parse(input);\n return tool.execute(validatedInput);\n }\n}\n\n/**\n * Job schedule configuration\n * Supports either cron-style recurring schedules or one-time execution\n */\nexport type JobSchedule =\n | { type: 'cron'; expression: string; timezone?: string }\n | { type: 'once'; executeAt: Date | string }\n | { type: 'interval'; seconds: number };\n\n/**\n * Lua Job configuration.\n * Used to initialize a new LuaJob instance.\n */\nexport interface LuaJobConfig {\n /** Job name (required; used as the server-side identifier). */\n name: string;\n /** Short description of the job (1-2 sentences) */\n description: string;\n /** Schedule configuration - cron, once, or interval */\n schedule: JobSchedule;\n /**\n * Function that executes the job logic.\n * Receives metadata as parameter for accessing job configuration.\n */\n execute: (job: JobInstance) => Promise<any>;\n /** Optional timeout in seconds (default: 300) */\n timeout?: number;\n /** Optional retry configuration */\n retry?: {\n maxAttempts: number;\n backoffSeconds?: number;\n };\n /**\n * Optional metadata for the job.\n * Can store any custom data (tags, config, context, etc.)\n * Sent to server and accessible during execution.\n */\n metadata?: Record<string, any>;\n}\n\n/**\n * Lua Job class.\n * Main class for building scheduled jobs (cron jobs, one-time tasks, intervals).\n *\n * A job is a scheduled task that executes at specific times or intervals.\n * Jobs can run once, on a recurring schedule (cron), or at fixed intervals.\n *\n * @example\n * ```typescript\n * import { LuaJob } from 'lua-cli';\n *\n * // Daily cleanup job at 2 AM\n * const dailyCleanup = new LuaJob({\n * name: 'daily-cleanup',\n * description: \"Daily database cleanup job\",\n * schedule: {\n * type: 'cron',\n * expression: '0 2 * * *', // 2 AM every day\n * timezone: 'America/New_York'\n * },\n * timeout: 600, // 10 minutes\n * retry: {\n * maxAttempts: 3,\n * backoffSeconds: 60\n * },\n * execute: async () => {\n * // Cleanup logic\n * console.log('Running cleanup...');\n * return { recordsDeleted: 150 };\n * }\n * });\n *\n * // One-time job\n * const sendWelcome = new LuaJob({\n * name: 'send-welcome',\n * description: \"Send welcome email to new users\",\n * schedule: {\n * type: 'once',\n * executeAt: new Date('2025-12-31T10:00:00Z')\n * },\n * execute: async () => {\n * console.log('Sending welcome emails...');\n * return { emailsSent: 100 };\n * }\n * });\n *\n * // Interval-based job (every 5 minutes)\n * const healthCheck = new LuaJob({\n * name: 'health-check',\n * description: \"System health check\",\n * schedule: {\n * type: 'interval',\n * seconds: 300 // 5 minutes\n * },\n * execute: async () => {\n * return { status: 'healthy' };\n * }\n * });\n * ```\n */\nexport class LuaJob {\n private readonly name: string;\n private readonly description: string;\n private readonly schedule: JobSchedule;\n private readonly timeout: number;\n private readonly retry?: {\n maxAttempts: number;\n backoffSeconds?: number;\n };\n private readonly metadata?: Record<string, any>;\n private readonly executeFunction: (job: JobInstance) => Promise<any>;\n\n /**\n * Creates a new LuaJob instance.\n *\n * @param config - Configuration object containing job metadata\n * @param config.name - Job name (required; non-empty string)\n * @param config.description - Short description of what the job does (1-2 sentences)\n * @param config.schedule - Schedule configuration (cron, once, or interval)\n * @param config.timeout - Optional timeout in seconds (default: 300)\n * @param config.retry - Optional retry configuration\n * @param config.metadata - Optional metadata for the job\n * @param config.execute - Function that processes the job (receives job instance as parameter)\n */\n constructor(config: LuaJobConfig) {\n if (!config.name || !config.name.trim()) {\n throw new Error('LuaJob requires a non-empty `name` (used as the server-side identifier).');\n }\n this.name = config.name;\n this.description = config.description;\n this.schedule = config.schedule;\n this.timeout = config.timeout || 300;\n this.retry = config.retry;\n this.metadata = config.metadata;\n this.executeFunction = config.execute;\n }\n\n /**\n * Gets the job name.\n */\n getName(): string {\n return this.name;\n }\n\n /**\n * Gets the job description.\n */\n getDescription(): string {\n return this.description;\n }\n\n /**\n * Gets the job schedule.\n */\n getSchedule(): JobSchedule {\n return this.schedule;\n }\n\n /**\n * Gets the job timeout in seconds.\n */\n getTimeout(): number {\n return this.timeout;\n }\n\n /**\n * Gets the retry configuration.\n */\n getRetry(): { maxAttempts: number; backoffSeconds?: number } | undefined {\n return this.retry;\n }\n\n /**\n * Gets the job metadata.\n */\n getMetadata(): Record<string, any> | undefined {\n return this.metadata;\n }\n\n /**\n * Executes the job with the provided job instance.\n * @param job - Job instance with metadata and context\n * @returns Promise resolving to job execution result\n */\n async execute(job: JobInstance): Promise<any> {\n return this.executeFunction(job);\n }\n}\n\n/**\n * Event payload delivered to webhook execute functions.\n */\nexport interface LuaWebhookEvent {\n /** Parsed query parameters */\n query?: Record<string, any>;\n /** Request headers */\n headers?: Record<string, any>;\n /** Request body (JSON or raw data) */\n body?: any;\n /** ISO timestamp when the webhook was received */\n timestamp: string;\n}\n\n/**\n * Lua Webhook configuration.\n * Used to initialize a new LuaWebhook instance.\n */\nexport interface LuaWebhookConfig {\n /** Webhook name (required; used as the server-side identifier). */\n name: string;\n /** Short description of the webhook (1-2 sentences) */\n description: string;\n /** Optional Zod schema for query parameter validation */\n querySchema?: ZodType;\n /** Optional Zod schema for header validation */\n headerSchema?: ZodType;\n /** Optional Zod schema for body validation */\n bodySchema?: ZodType;\n /** Function that executes the webhook logic */\n execute: (event: LuaWebhookEvent) => Promise<any>;\n}\n\n/**\n * Lua Webhook class.\n * Main class for building webhooks with validated inputs.\n *\n * A webhook is an HTTP endpoint that can receive requests with validated\n * query parameters, headers, and body. The execute function processes the\n * validated input and returns a response.\n *\n * @example\n * ```typescript\n * import { LuaWebhook } from 'lua-cli';\n * import { z } from 'zod';\n *\n * const webhook = new LuaWebhook({\n * name: 'user-created',\n * description: \"Webhook that handles user creation events\",\n * querySchema: z.object({\n * source: z.string().optional()\n * }),\n * headerSchema: z.object({\n * 'x-api-key': z.string(),\n * 'content-type': z.string().optional()\n * }),\n * bodySchema: z.object({\n * userId: z.string(),\n * email: z.string().email(),\n * name: z.string()\n * }),\n * execute: async (event) => {\n * const { query, headers, body } = event;\n * // Process the webhook...\n * console.log('New user:', body.email);\n * return { success: true, userId: body.userId };\n * }\n * });\n *\n * // Execute the webhook with validated inputs\n * const result = await webhook.execute(\n * { source: 'mobile' },\n * { 'x-api-key': 'secret-key' },\n * { userId: '123', email: 'user@example.com', name: 'John' }\n * );\n * ```\n */\nexport class LuaWebhook {\n private readonly name: string;\n private readonly description: string;\n private readonly querySchema?: ZodType;\n private readonly headerSchema?: ZodType;\n private readonly bodySchema?: ZodType;\n private readonly executeFunction: (event: LuaWebhookEvent) => Promise<any>;\n\n /**\n * Creates a new LuaWebhook instance.\n *\n * @param config - Configuration object containing webhook metadata\n * @param config.name - Webhook name (required; non-empty string)\n * @param config.description - Short description of what the webhook does (1-2 sentences)\n * @param config.querySchema - Optional Zod schema for query parameter validation\n * @param config.headerSchema - Optional Zod schema for header validation\n * @param config.bodySchema - Optional Zod schema for body validation\n * @param config.execute - Function that processes the webhook request\n */\n constructor(config: LuaWebhookConfig) {\n if (!config.name || !config.name.trim()) {\n throw new Error('LuaWebhook requires a non-empty `name` (used as the server-side identifier).');\n }\n this.name = config.name;\n this.description = config.description;\n this.querySchema = config.querySchema;\n this.headerSchema = config.headerSchema;\n this.bodySchema = config.bodySchema;\n this.executeFunction = config.execute;\n }\n\n /**\n * Gets the webhook name.\n */\n getName(): string {\n return this.name;\n }\n\n /**\n * Gets the webhook description.\n */\n getDescription(): string {\n return this.description;\n }\n\n /**\n * Executes the webhook with validated input.\n * Validates query parameters, headers, and body against their respective schemas\n * before executing the webhook function.\n *\n * @param query - Query parameters object\n * @param headers - Headers object\n * @param body - Request body\n * @returns Promise resolving to webhook execution result\n * @throws Error if validation fails for any input\n *\n * @example\n * ```typescript\n * const result = await webhook.execute(\n * { limit: '10' },\n * { 'x-api-key': 'secret' },\n * { data: 'value' }\n * );\n * ```\n */\n async execute(query?: Record<string, any>, headers?: Record<string, any>, body?: any): Promise<any> {\n let validatedQuery = query;\n let validatedHeaders = headers;\n let validatedBody = body;\n\n // Validate query parameters if schema is provided\n if (this.querySchema) {\n try {\n validatedQuery = this.querySchema.parse(query || {}) as Record<string, any>;\n } catch (error) {\n throw new Error(`Query parameter validation failed: ${error}`);\n }\n }\n\n // Validate headers if schema is provided\n if (this.headerSchema) {\n try {\n validatedHeaders = this.headerSchema.parse(headers || {}) as Record<string, any>;\n } catch (error) {\n throw new Error(`Header validation failed: ${error}`);\n }\n }\n\n // Validate body if schema is provided\n if (this.bodySchema) {\n try {\n validatedBody = this.bodySchema.parse(body);\n } catch (error) {\n throw new Error(`Body validation failed: ${error}`);\n }\n }\n\n const event: LuaWebhookEvent = {\n query: validatedQuery || {},\n headers: validatedHeaders || {},\n body: validatedBody,\n timestamp: new Date().toISOString(),\n };\n\n return this.executeFunction(event);\n }\n}\n\n// ============================================================================\n// PREPROCESSOR\n// ============================================================================\n\nexport type PreProcessorAction = 'proceed' | 'block';\n\nexport type PreProcessorBlockResponse = {\n /** Stop processing immediately */\n action: 'block';\n /** Message to show to the user */\n response: string;\n /** Optional metadata */\n metadata?: Record<string, any>;\n};\n\nexport type PreProcessorProceedResponse = {\n /** Proceed to next preprocessor or agent */\n action: 'proceed';\n /** Optional modified message (if not provided, uses original/current message) */\n modifiedMessage?: import('../interfaces/chat.js').ChatMessage[];\n /** Optional metadata to pass along */\n metadata?: Record<string, any>;\n};\n\n/**\n * Result returned by the preprocessor\n */\nexport type PreProcessorResult = PreProcessorBlockResponse | PreProcessorProceedResponse;\n\n/**\n * PreProcessor configuration.\n */\nexport interface PreProcessorConfig {\n /** PreProcessor name (required; used as the server-side identifier). */\n name: string;\n /** Short description of the preprocessor */\n description: string;\n /**\n * Async flag - indicates if processor should run in background on server:\n * - true: Run asynchronously (non-blocking, for slow operations like API calls)\n * - false: Run synchronously (blocking, for fast operations like text filtering)\n * Default: false (synchronous)\n */\n async?: boolean;\n /**\n * Execution priority (lower runs first).\n * Default: 100\n */\n priority?: number;\n /**\n * Function that processes messages before sending to agent.\n */\n execute: (\n user: UserDataInstance,\n messages: import('../interfaces/chat.js').ChatMessage[],\n channel: string\n ) => Promise<PreProcessorResult>;\n}\n\n/**\n * PreProcessor class.\n * Processes user messages before they reach the agent.\n * Can handle rich content (text, images, files).\n *\n * @example\n * ```typescript\n * const contentFilter = new PreProcessor({\n * name: 'content-filter',\n * description: 'Filters and processes message content',\n * priority: 10,\n * execute: async (user, messages, channel) => {\n * // Check for spam\n * const hasSpam = messages.some(msg =>\n * msg.type === 'text' && msg.text.includes('spam')\n * );\n *\n * if (hasSpam) {\n * return {\n * action: 'block',\n * response: \"Message blocked due to spam content\"\n * };\n * }\n *\n * // Return messages to proceed\n * return { action: 'proceed' };\n * }\n * });\n * ```\n */\nexport class PreProcessor {\n private readonly name: string;\n private readonly description: string;\n private readonly asyncMode: boolean;\n private readonly priority: number;\n private readonly executeFunction: (\n user: UserDataInstance,\n messages: import('../interfaces/chat.js').ChatMessage[],\n channel: string\n ) => Promise<PreProcessorResult>;\n\n constructor(config: PreProcessorConfig) {\n if (!config.name || !config.name.trim()) {\n throw new Error('PreProcessor requires a non-empty `name` (used as the server-side identifier).');\n }\n this.name = config.name;\n this.description = config.description;\n this.asyncMode = config.async ?? false; // Default to synchronous\n this.priority = config.priority ?? 100;\n this.executeFunction = config.execute;\n }\n\n getName(): string {\n return this.name;\n }\n\n getDescription(): string {\n return this.description;\n }\n\n getAsync(): boolean {\n return this.asyncMode;\n }\n\n getPriority(): number {\n return this.priority;\n }\n\n async execute(\n user: UserDataInstance,\n messages: import('../interfaces/chat.js').ChatMessage[],\n channel: string\n ): Promise<PreProcessorResult> {\n return this.executeFunction(user, messages, channel);\n }\n}\n\n// ============================================================================\n// POSTPROCESSOR\n// ============================================================================\n\n/**\n * PostProcessor response type.\n * The execute function must return an object with the modified response.\n */\nexport interface PostProcessorResponse {\n modifiedResponse: string;\n}\n\n/**\n * PostProcessor configuration.\n */\nexport interface PostProcessorConfig {\n /** PostProcessor name (required; used as the server-side identifier). */\n name: string;\n /** Short description of the postprocessor */\n description: string;\n /**\n * Execution priority (lower runs first).\n * Default: 100\n */\n priority?: number;\n /**\n * Function that processes the agent's response before sending to user.\n * MUST return { modifiedResponse: string } - the formatted response text.\n */\n execute: (\n user: UserDataInstance,\n message: string,\n response: string,\n channel: string\n ) => Promise<PostProcessorResponse>;\n}\n\n/**\n * PostProcessor class.\n * Processes agent responses before they reach the user.\n *\n * @example\n * ```typescript\n * const responseFormatter = new PostProcessor({\n * name: 'response-formatter',\n * description: 'Formats responses with branding',\n * execute: async (user, message, response, channel) => {\n * return { modifiedResponse: response + '\\n\\n---\\nPowered by Acme Corp' };\n * }\n * });\n * ```\n */\nexport class PostProcessor {\n private readonly name: string;\n private readonly description: string;\n private readonly priority: number;\n private readonly executeFunction: (\n user: UserDataInstance,\n message: string,\n response: string,\n channel: string\n ) => Promise<PostProcessorResponse>;\n\n constructor(config: PostProcessorConfig) {\n if (!config.name || !config.name.trim()) {\n throw new Error('PostProcessor requires a non-empty `name` (used as the server-side identifier).');\n }\n this.name = config.name;\n this.description = config.description;\n this.priority = config.priority ?? 100;\n this.executeFunction = config.execute;\n }\n\n getName(): string {\n return this.name;\n }\n\n getDescription(): string {\n return this.description;\n }\n\n getPriority(): number {\n return this.priority;\n }\n\n async execute(\n user: UserDataInstance,\n message: string,\n response: string,\n channel: string\n ): Promise<PostProcessorResponse> {\n return this.executeFunction(user, message, response, channel);\n }\n}\n\n// ============================================================================\n// MCP SERVER - Model Context Protocol Server Configuration\n// ============================================================================\n\n/**\n * MCP Server transport type - determines how to connect to the server.\n *\n * - 'streamable-http': Modern MCP standard (recommended) - single endpoint for bidirectional communication\n * - 'sse': Legacy Server-Sent Events transport - for older MCP servers\n *\n * Note: 'stdio' transport is not supported yet.\n */\nexport type MCPTransport = 'sse' | 'streamable-http';\n\n/**\n * Base configuration for all MCP servers.\n */\nexport interface MCPServerBaseConfig {\n /** Unique identifier for this MCP server */\n name: string;\n /** Optional timeout in milliseconds (default: 60000) */\n timeout?: number;\n}\n\n/**\n * Function type for resolving environment variables at runtime.\n * Use env() inside to access agent environment variables.\n *\n * @example\n * ```typescript\n * env: () => ({\n * API_KEY: env(\"MY_API_KEY\"),\n * DEBUG: \"true\"\n * })\n * ```\n */\nexport type EnvResolverFunction = () => Record<string, string>;\n\n/**\n * Function type for resolving headers at runtime.\n * Use env() inside to access agent environment variables.\n *\n * @example\n * ```typescript\n * headers: () => ({\n * 'Authorization': `Bearer ${env(\"API_TOKEN\")}`\n * })\n * ```\n */\nexport type HeadersResolverFunction = () => Record<string, string>;\n\n/**\n * Function type for resolving URL at runtime.\n * Use env() inside to access agent environment variables.\n *\n * @example\n * ```typescript\n * url: () => env(\"MCP_SERVER_URL\") || \"https://default.example.com/mcp\"\n * ```\n */\nexport type UrlResolverFunction = () => string;\n\n/**\n * Configuration for SSE-based MCP servers (legacy remote endpoints)\n *\n * Use this for older MCP servers that don't support Streamable HTTP.\n * For new integrations, prefer MCPStreamableHttpServerConfig.\n */\nexport interface MCPSSEServerConfig extends MCPServerBaseConfig {\n transport: 'sse';\n /**\n * URL of the MCP server endpoint.\n * Can be a static string or a function that returns the URL at runtime.\n *\n * @example\n * // Static\n * url: \"https://api.example.com/mcp\"\n *\n * // Function (evaluated at runtime)\n * url: () => env(\"MCP_SERVER_URL\")\n */\n url: string | UrlResolverFunction;\n /**\n * Optional headers to send with requests.\n * Can be a static object or a function that returns headers at runtime.\n * Use a function to access env() for dynamic resolution from agent env vars.\n *\n * @example\n * // Static (NOT recommended for secrets)\n * headers: { 'X-Custom': 'value' }\n *\n * // Function (evaluated at runtime - recommended for auth)\n * headers: () => ({\n * 'Authorization': `Bearer ${env(\"API_TOKEN\")}`\n * })\n */\n headers?: Record<string, string> | HeadersResolverFunction;\n}\n\n/**\n * Configuration for Streamable HTTP MCP servers (modern standard - RECOMMENDED)\n *\n * This is the recommended transport for new MCP server integrations.\n * Streamable HTTP is the modern MCP standard (spec 2025-03-26) that provides:\n * - Single endpoint for bidirectional communication\n * - Session management via Mcp-Session-Id header\n * - Resumability via SSE event IDs\n *\n * @example\n * ```typescript\n * const docsServer = new LuaMCPServer({\n * name: 'docs',\n * transport: 'streamable-http',\n * url: 'https://mcp.example.com/mcp',\n * headers: () => ({\n * 'Authorization': `Bearer ${env(\"MCP_API_TOKEN\")}`\n * })\n * });\n * ```\n */\nexport interface MCPStreamableHttpServerConfig extends MCPServerBaseConfig {\n transport: 'streamable-http';\n /**\n * URL of the MCP server endpoint.\n * Can be a static string or a function that returns the URL at runtime.\n *\n * @example\n * // Static\n * url: \"https://api.example.com/mcp\"\n *\n * // Function (evaluated at runtime)\n * url: () => env(\"MCP_SERVER_URL\")\n */\n url: string | UrlResolverFunction;\n /**\n * Optional headers to send with requests.\n * Can be a static object or a function that returns headers at runtime.\n * Use a function to access env() for dynamic resolution from agent env vars.\n *\n * @example\n * // Static (NOT recommended for secrets)\n * headers: { 'X-Custom': 'value' }\n *\n * // Function (evaluated at runtime - recommended for auth)\n * headers: () => ({\n * 'Authorization': `Bearer ${env(\"API_TOKEN\")}`\n * })\n */\n headers?: Record<string, string> | HeadersResolverFunction;\n}\n\n/**\n * Union type for all MCP server configurations.\n *\n * Note: stdio transport is not supported yet.\n * Use 'streamable-http' (recommended) or 'sse' (legacy) instead.\n */\nexport type LuaMCPServerConfig = MCPSSEServerConfig | MCPStreamableHttpServerConfig;\n\n/**\n * LuaMCPServer class.\n * Defines an MCP (Model Context Protocol) server connection.\n *\n * MCP servers provide tools that can be used by your agent at runtime.\n * Connect to remote MCP servers via Streamable HTTP (recommended) or SSE (legacy).\n *\n * Environment variables can be provided as static values or as functions that\n * resolve at runtime using the env() API (consistent with tool execute functions).\n *\n * @example\n * ```typescript\n * import { LuaMCPServer, env } from 'lua-cli';\n *\n * // Remote MCP server via Streamable HTTP (recommended)\n * const docsServer = new LuaMCPServer({\n * name: 'docs',\n * transport: 'streamable-http',\n * url: 'https://mcp.example.com/mcp',\n * headers: () => ({\n * 'Authorization': `Bearer ${env(\"MCP_API_TOKEN\")}`\n * })\n * });\n *\n * // Remote MCP server via SSE (legacy)\n * const legacyServer = new LuaMCPServer({\n * name: 'legacy-api',\n * transport: 'sse',\n * url: 'https://old-mcp.example.com/sse',\n * headers: () => ({\n * 'Authorization': `Bearer ${env(\"API_KEY\")}`\n * })\n * });\n * ```\n */\nexport class LuaMCPServer {\n private readonly config: LuaMCPServerConfig;\n\n constructor(config: LuaMCPServerConfig) {\n if (!config.name) {\n throw new Error('MCP server name is required');\n }\n // Reject stdio transport (not supported yet) with helpful error message\n if ((config as any).transport === 'stdio') {\n throw new Error(\n `stdio transport is not supported yet. ` +\n `Please use 'streamable-http' (recommended) or 'sse' transport instead. ` +\n `See https://docs.heylua.ai/overview/mcp-servers for migration guide.`\n );\n }\n if ((config.transport === 'sse' || config.transport === 'streamable-http') && !config.url) {\n throw new Error(`URL is required for ${config.transport} transport`);\n }\n this.config = config;\n }\n\n getName(): string {\n return this.config.name;\n }\n\n getTransport(): MCPTransport {\n return this.config.transport;\n }\n\n getTimeout(): number | undefined {\n return this.config.timeout;\n }\n\n getConfig(): LuaMCPServerConfig {\n return this.config;\n }\n\n /**\n * Returns the server configuration in a format suitable for serialization.\n * Environment variable references (${env.VAR_NAME}) are preserved for runtime resolution.\n */\n toJSON(): Record<string, any> {\n const base: Record<string, any> = {\n name: this.config.name,\n transport: this.config.transport,\n };\n\n if (this.config.timeout) {\n base.timeout = this.config.timeout;\n }\n\n // Both sse and streamable-http transports use the same fields\n base.url = this.config.url;\n if (this.config.headers) {\n base.headers = this.config.headers;\n }\n\n return base;\n }\n}\n\n// ============================================================================\n// LUA AGENT - Unified Agent Configuration\n// ============================================================================\n\n/**\n * LuaAgent configuration interface.\n * Provides a simplified, unified way to configure an agent with all its components.\n *\n * This is the recommended approach for defining your agent. Instead of exporting\n * individual skills, jobs, webhooks, etc., you export a single LuaAgent object\n * that contains everything.\n */\n\n/**\n * Per-agent message batching/debounce configuration.\n * Overrides platform-wide env var defaults for this specific agent.\n * Any field left undefined falls back to the env var, then to the hardcoded default.\n *\n * @example\n * ```typescript\n * export default new LuaAgent({\n * name: 'my-agent',\n * persona: '...',\n * batching: {\n * firstMessageDelayMs: 200, // hold first message 200ms to allow batch formation\n * debounceWindowMs: 1500, // extend window 1.5s per new message while in-flight\n * maxBatchMessages: 5,\n * }\n * });\n * ```\n */\nimport type { AgentModelSettings, BatchingConfig, GovernanceConfig } from '@lua/shared-types';\n\n/**\n * Validates obviously-wrong values on a user-supplied `modelSettings` block.\n * Provider-specific range checks (e.g. presencePenalty bounds) are left to\n * the provider — we only catch the unambiguously-broken cases here so the\n * CLI fails fast instead of waiting for a runtime provider error.\n */\nfunction validateModelSettings(settings: AgentModelSettings): void {\n const finiteNumberKeys = [\n 'temperature',\n 'topP',\n 'topK',\n 'maxOutputTokens',\n 'presencePenalty',\n 'frequencyPenalty',\n 'seed',\n ] as const;\n for (const key of finiteNumberKeys) {\n const value = settings[key];\n if (value !== undefined && (typeof value !== 'number' || !Number.isFinite(value))) {\n throw new Error(`Agent modelSettings.${key} must be a finite number`);\n }\n }\n if (settings.temperature !== undefined && (settings.temperature < 0 || settings.temperature > 2)) {\n throw new Error('Agent modelSettings.temperature must be between 0 and 2');\n }\n if (settings.topP !== undefined && (settings.topP < 0 || settings.topP > 1)) {\n throw new Error('Agent modelSettings.topP must be between 0 and 1');\n }\n if (settings.maxOutputTokens !== undefined && settings.maxOutputTokens < 1) {\n throw new Error('Agent modelSettings.maxOutputTokens must be >= 1');\n }\n if (settings.stopSequences !== undefined) {\n // Verify both the array shape AND every element is a string — the compiler's\n // `shapeModelSettings` silently drops arrays with non-string elements, so a\n // permissive constructor check produces confusing \"my stop sequences\n // disappeared\" behavior at push time.\n if (!Array.isArray(settings.stopSequences) || !settings.stopSequences.every((v) => typeof v === 'string')) {\n throw new Error('Agent modelSettings.stopSequences must be a string array');\n }\n }\n}\n\n/**\n * Type for the agent's model property.\n *\n * Can be either:\n * - A static `'provider/model'` string (e.g., `'openai/gpt-4o'`)\n * - A resolver function that receives `LuaRequest` and returns a model string.\n * The function runs in the full sandbox with access to all APIs (User, Baskets, etc.)\n *\n * @example\n * ```typescript\n * // Static model\n * model: 'openai/gpt-4o'\n *\n * // Dynamic model based on channel\n * model: async (request) => {\n * if (request.channel === 'whatsapp') return 'openai/gpt-4o-mini';\n * return 'openai/gpt-4o';\n * }\n * ```\n */\nexport type LuaAgentModel = string | ((request: LuaRequest) => string | Promise<string>);\n\nexport interface LuaAgentConfig {\n /** Agent name (used for identification) */\n name: string;\n /** Agent persona - defines the agent's behavior and personality */\n persona: PersonaText;\n /** LLM model to use — 'provider/model' string or resolver function */\n model?: LuaAgentModel;\n /**\n * Per-call sampling settings (temperature, topP, maxOutputTokens, etc.).\n * Passed straight through to Mastra / AI SDK on every `chat/stream` and\n * `chat/generate`. Undefined leaves provider defaults in place.\n *\n * @example\n * modelSettings: { temperature: 0.2, maxOutputTokens: 4096 }\n */\n modelSettings?: AgentModelSettings;\n /** Array of skills (each with tools) */\n skills?: LuaSkill[];\n /** Array of webhooks */\n webhooks?: LuaWebhook[];\n /** Array of scheduled jobs */\n jobs?: LuaJob[];\n /** Array of preprocessors (run before messages reach the agent) */\n preProcessors?: PreProcessor[];\n /** Array of postprocessors (run after agent generates responses) */\n postProcessors?: PostProcessor[];\n /** Array of MCP servers (Model Context Protocol) for external tool integrations */\n mcpServers?: LuaMCPServer[];\n /** Array of devices (external hardware that the agent can send commands to and receive triggers from) */\n devices?: LuaDevice[];\n /** Standalone device triggers — agent-side logic that any device can fire */\n deviceTriggers?: LuaDeviceTrigger[];\n /**\n * Voices the agent can use. Each channel picks which one fires via\n * `channelConfig.<kind>.voiceId`; absent binding falls back to the\n * first entry. For the simple \"one voice for everything\" case, pass a\n * single-element array — `voices: [supportVoice]`.\n */\n voices?: LuaVoice[];\n /** Per-agent message batching/debounce configuration. Overrides platform env var defaults. */\n batching?: BatchingConfig;\n /** Governance policy configuration. When set, tool calls, preprocessors, and postprocessors are governed. */\n governance?: GovernanceConfig;\n}\n\n/**\n * LuaAgent class.\n * Unified agent configuration that consolidates skills, webhooks, jobs, and processors.\n *\n * This is the simplest way to define an agent. Instead of exporting multiple separate\n * components, you create one LuaAgent that contains everything.\n *\n * @example\n * ```typescript\n * import { LuaAgent, LuaSkill, LuaJob, LuaWebhook } from 'lua-cli';\n *\n * // Define your skills, jobs, webhooks in separate files\n * import { userSkill } from './skills/user-skill';\n * import { healthCheckJob } from './jobs/health-check';\n * import { webhookHandler } from './webhooks/handler';\n *\n * // Create a single agent configuration\n * export const agent = new LuaAgent({\n * name: 'my-assistant',\n * persona: 'You are a helpful AI assistant that can manage users and products.',\n * skills: [userSkill],\n * jobs: [healthCheckJob],\n * webhooks: [webhookHandler],\n * preProcessors: [],\n * postProcessors: []\n * });\n * ```\n */\nexport class LuaAgent {\n private readonly name: string;\n private readonly persona: PersonaText;\n private readonly model?: LuaAgentModel;\n private readonly modelSettings?: AgentModelSettings;\n private readonly skills: LuaSkill[];\n private readonly webhooks: LuaWebhook[];\n private readonly jobs: LuaJob[];\n private readonly preProcessors: PreProcessor[];\n private readonly postProcessors: PostProcessor[];\n private readonly mcpServers: LuaMCPServer[];\n private readonly devices: LuaDevice[];\n private readonly deviceTriggers: LuaDeviceTrigger[];\n private readonly voices?: LuaVoice[];\n private readonly batching?: BatchingConfig;\n private readonly governance?: LuaAgentConfig['governance'];\n\n /**\n * Creates a new LuaAgent instance.\n *\n * @param config - Agent configuration\n * @param config.name - Agent name\n * @param config.persona - Agent persona (behavior and personality)\n * @param config.model - Optional LLM model ('provider/model' string or resolver function)\n * @param config.skills - Optional array of skills\n * @param config.webhooks - Optional array of webhooks\n * @param config.jobs - Optional array of jobs\n * @param config.preProcessors - Optional array of preprocessors\n * @param config.postProcessors - Optional array of postprocessors\n * @param config.mcpServers - Optional array of MCP servers\n * @param config.devices - Optional array of devices (external hardware)\n * @param config.batching - Optional per-agent batching/debounce configuration\n */\n constructor(config: LuaAgentConfig) {\n this.name = config.name;\n this.persona = config.persona;\n this.model = config.model;\n if (config.modelSettings !== undefined) {\n validateModelSettings(config.modelSettings);\n }\n this.modelSettings = config.modelSettings;\n\n if (typeof this.persona === 'object') {\n if (!this.persona.base && !this.persona.voice && !this.persona.text) {\n throw new Error('Agent persona object must have at least one of: base, voice, text');\n }\n }\n\n this.skills = config.skills || [];\n this.webhooks = config.webhooks || [];\n this.jobs = config.jobs || [];\n this.preProcessors = config.preProcessors || [];\n this.postProcessors = config.postProcessors || [];\n this.mcpServers = config.mcpServers || [];\n this.devices = config.devices || [];\n this.deviceTriggers = config.deviceTriggers || [];\n this.voices = config.voices;\n this.batching = config.batching;\n this.governance = config.governance;\n }\n\n getName(): string {\n return this.name;\n }\n\n getPersona(): PersonaText {\n return this.persona;\n }\n\n getModel(): LuaAgentModel | undefined {\n return this.model;\n }\n\n getModelSettings(): AgentModelSettings | undefined {\n return this.modelSettings;\n }\n\n getSkills(): LuaSkill[] {\n return this.skills;\n }\n\n getWebhooks(): LuaWebhook[] {\n return this.webhooks;\n }\n\n getJobs(): LuaJob[] {\n return this.jobs;\n }\n\n getPreProcessors(): PreProcessor[] {\n return this.preProcessors;\n }\n\n getPostProcessors(): PostProcessor[] {\n return this.postProcessors;\n }\n\n getMCPServers(): LuaMCPServer[] {\n return this.mcpServers;\n }\n\n getBatching(): BatchingConfig | undefined {\n return this.batching;\n }\n\n getDevices(): LuaDevice[] {\n return this.devices;\n }\n\n getVoices(): LuaVoice[] | undefined {\n return this.voices;\n }\n}\n\n// =============================================================================\n// DEVICE\n// =============================================================================\n\n/** Configuration for a single device command (agent → device) */\nexport interface DeviceCommandConfig {\n /** Description of what this command does */\n description: string;\n /** Zod schema for command input validation */\n inputSchema?: ZodType;\n /** Retry configuration for failed commands */\n retry?: { maxAttempts: number; backoffMs: number };\n /** Timeout in milliseconds (default: 30000) */\n timeoutMs?: number;\n}\n\n/** Configuration for a single device trigger (device → agent) */\nexport interface DeviceTriggerConfig {\n /** Description of when this trigger fires */\n description: string;\n /** Zod schema for trigger payload validation */\n payloadSchema?: ZodType;\n /**\n * Handler that runs on lua-core when the device fires this trigger.\n * Has full access to agent context (can call agent.chat(), use tools, etc.)\n */\n execute?: (payload: any, context: { agent: any; device: any; trigger: any }) => Promise<any>;\n}\n\n/**\n * Configuration for defining a device that an agent can communicate with.\n *\n * @example\n * ```typescript\n * import { defineDevice } from 'lua-cli';\n * import { z } from 'zod';\n *\n * export const printer = defineDevice({\n * name: 'label-printer',\n * description: 'Thermal label printer on Raspberry Pi',\n * group: 'printers',\n * commands: {\n * print: {\n * description: 'Print a label',\n * inputSchema: z.object({ text: z.string(), copies: z.number().default(1) }),\n * retry: { maxAttempts: 3, backoffMs: 1000 },\n * timeoutMs: 30000,\n * },\n * status: {\n * description: 'Get printer status',\n * timeoutMs: 5000,\n * },\n * },\n * triggers: {\n * paper_low: {\n * description: 'Fired when paper level drops below threshold',\n * payloadSchema: z.object({ level: z.number(), threshold: z.number() }),\n * execute: async (payload, { agent }) => {\n * await agent.chat(\\`Printer paper low: \\${payload.level}%\\`);\n * },\n * },\n * },\n * });\n * ```\n */\nexport interface LuaDeviceConfig {\n /** Unique device name (lowercase, hyphens, e.g., 'label-printer') */\n name: string;\n /** Description of the device */\n description?: string;\n /** Optional group name for fan-out commands (e.g., 'printers') */\n group?: string;\n /** Commands the agent can send to the device */\n commands?: Record<string, DeviceCommandConfig>;\n /** Triggers the device can fire to the agent */\n triggers?: Record<string, DeviceTriggerConfig>;\n}\n\n/**\n * LuaDevice class — represents an external device that an agent can communicate with.\n *\n * Used in two ways:\n * - Class-based: `export default new LuaDevice({ ... })`\n * - Function-based: `export const myDevice = defineDevice({ ... })` (preferred)\n */\nexport class LuaDevice {\n readonly name: string;\n readonly description: string;\n readonly group?: string;\n readonly commands: Record<string, DeviceCommandConfig>;\n readonly triggers: Record<string, DeviceTriggerConfig>;\n\n constructor(config: LuaDeviceConfig) {\n this.name = config.name;\n this.description = config.description || '';\n this.group = config.group;\n this.commands = config.commands || {};\n this.triggers = config.triggers || {};\n }\n}\n\n// =============================================================================\n// DEVICE TRIGGER (standalone primitive)\n// =============================================================================\n\n/**\n * Configuration for a standalone device trigger primitive.\n *\n * Device triggers represent events fired from a device to an agent.\n * Unlike triggers defined inline within a `defineDevice()`, standalone\n * device triggers are first-class primitives that can be compiled,\n * versioned, and pushed independently.\n *\n * @example\n * ```typescript\n * import { defineDeviceTrigger } from 'lua-cli';\n * import { z } from 'zod';\n *\n * export const paperLow = defineDeviceTrigger({\n * name: 'paper-low',\n * description: 'Fired when printer paper drops below threshold',\n * payloadSchema: z.object({ level: z.number() }),\n * execute: async (payload, { agent, device }) => {\n * await agent.chat(`Printer ${device.name} paper low: ${payload.level}%`);\n * },\n * });\n * ```\n */\nexport interface LuaDeviceTriggerConfig {\n /** Trigger name (lowercase, hyphens, e.g., 'paper-low') */\n name: string;\n /** Description of when this trigger fires */\n description?: string;\n /** Zod schema for trigger payload validation */\n payloadSchema?: ZodType;\n /** Function that executes when the trigger fires */\n execute: (payload: any, context: { agent: any; device: { name: string } }) => Promise<any>;\n}\n\n/**\n * Lua Device Trigger class.\n *\n * Standalone device trigger primitive. Can be used with either:\n * - Class-based: `export default new LuaDeviceTrigger({ ... })`\n * - Function-based: `export const myTrigger = defineDeviceTrigger({ ... })` (preferred)\n */\nexport class LuaDeviceTrigger {\n readonly name: string;\n readonly description: string;\n readonly payloadSchema?: ZodType;\n readonly execute: (payload: any, context: { agent: any; device: { name: string } }) => Promise<any>;\n\n constructor(public config: LuaDeviceTriggerConfig) {\n this.name = config.name;\n this.description = config.description || '';\n this.payloadSchema = config.payloadSchema;\n this.execute = config.execute;\n }\n}\n","/**\n * LuaVoice — code-defined voice agents wrapping the LiveKit Agents framework.\n *\n * Data fields (llm/stt/tts/vad/turnDetection/...) validate against\n * `LuaVoiceConfigSchema` from `@lua/shared-types`. Function-bearing fields\n * (tools, onEnter, onUserTurnCompleted, onExit) live only in this TypeScript\n * surface — the compiler detects them via AST and emits presence flags in\n * the manifest; the worker reads the artifact bundle for the executable\n * implementations.\n */\n\nimport type { ZodType } from 'zod';\nimport type { LuaVoiceConfig as LuaVoiceDataConfig } from '@lua/shared-types';\nimport { ToolFlag, type LuaTool } from './skill.js';\n\n/**\n * User-facing input type for `llm` / `stt` / `tts` on a LuaVoice. Accepts:\n * - a string descriptor like `'cartesia/sonic-3:9626…'` — routed through Inference.\n * - an instance of a LiveKit Agents plugin class such as `new deepgram.STT({...})` —\n * routed through the corresponding direct plugin.\n * - a struct `{ model, voice }` — sugar for the Inference TTS form.\n *\n * The compiler ASTs the source file and normalizes whichever shape it finds\n * to the discriminated union the wire schema expects (`@lua/shared-types`).\n * The constructor below stores the raw input as-is — the runtime classes\n * never execute as part of the push pipeline.\n */\nexport type LuaVoiceModelInput = string | object;\n\n// Re-export so devs can `import { ToolFlag } from 'lua-cli'` alongside LuaVoice.\nexport { ToolFlag };\n\n/**\n * Context passed to LuaVoice lifecycle hooks at runtime.\n */\nexport interface LuaVoiceHookContext {\n sessionId: string;\n channel: { kind: string; alias?: string };\n caller?: { phoneNumber?: string; userId?: string; isAnonymous?: boolean };\n duration?: number;\n session: {\n userdata: Record<string, unknown>;\n history: unknown[];\n say(text: string): Promise<void>;\n generateReply(opts?: { instructions?: string }): unknown;\n };\n}\n\n/**\n * Per-turn context passed to onUserTurnCompleted. The canonical RAG injection\n * point — call `addMessage` to seed context, then the LLM is invoked.\n */\nexport interface LuaVoiceTurnContext {\n items: unknown[];\n addMessage(message: { role: 'system' | 'user' | 'assistant'; content: string }): void;\n}\n\n/**\n * Voice tool ctx — extends the base `LuaToolCtx` (from `skill.ts`) with\n * voice-runtime-only delegates. The base ctx is what a `LuaTool` sees as\n * its second `execute` arg whether it runs over chat or voice; this\n * extension just adds the Phase-5 fields (currently optional + experimental).\n *\n * `say()` is wired today and delegates to the active LiveKit `voice.AgentSession`.\n * `disallowInterruptions()` and `handoff()` are optional placeholders for\n * Phase 5 (BAC-213, the LuaVoice handoffs + test framework ticket).\n * Marked optional both because they aren't implemented yet AND so this\n * type stays structurally compatible with `LuaToolCtx` — that\n * compatibility is what lets a `LuaVoiceTool` (which extends `LuaTool`)\n * present `(ctx?: LuaVoiceToolCtx)` while satisfying the parent's\n * `(ctx?: LuaToolCtx)` signature.\n */\nexport interface LuaVoiceToolCtx {\n toolCallId?: string;\n voice?: {\n say(text: string): Promise<void>;\n /**\n * Transfer the live caller to a human at `msisdn`. Two mechanisms:\n *\n * - `'refer'` (default): SIP REFER on the caller's inbound leg.\n * Cheap (one billed leg) but depends on the inbound carrier\n * accepting REFER end-to-end — many European mobile carriers\n * strip it. Use when the carrier is known to support REFER.\n *\n * - `'bridge'`: dial the human as a second SIP participant into\n * the same room, keeping the caller attached. Two billed legs\n * but always works regardless of carrier REFER support. Use for\n * high-stakes transfers (sales, escalation) where reliability\n * matters more than per-minute cost.\n *\n * `announce` is spoken via `session.say(...)` before the transfer\n * fires (e.g. \"Transferring you to our sales team — one moment\").\n *\n * @example\n * ```typescript\n * await ctx.voice?.transferToHuman('+32477123456', {\n * mode: 'bridge',\n * announce: 'Transferring you to our sales team — one moment.',\n * });\n * ```\n */\n transferToHuman?(msisdn: string, opts?: { mode?: 'bridge' | 'refer'; announce?: string }): Promise<void>;\n /**\n * End the live call. When `announce` is set, the agent speaks it and\n * waits for playout before closing the session — useful for a sign-off\n * like \"Thanks for calling, goodbye.\" Without `announce`, the session\n * closes immediately (any in-flight TTS finishes via the SDK's\n * graceful `close()`).\n *\n * @example\n * ```typescript\n * await ctx.voice?.endCall({ announce: 'Thanks for calling. Goodbye.' });\n * ```\n */\n endCall?(opts?: { announce?: string }): Promise<void>;\n /**\n * @experimental Reserved for Phase 5 (BAC-213). Optional because\n * unimplemented — the actual \"lock the assistant's current\n * utterance against barge-in\" plumbing lands with the broader\n * turn-handling work.\n */\n disallowInterruptions?(): void;\n /**\n * @experimental Reserved for Phase 5 (BAC-213). Optional because\n * unimplemented — handoffs require `chatCtx.copy(exclude_instructions=True)`\n * + `update_agent` plumbing that's part of the multi-LuaVoice flow ticket.\n */\n handoff?(otherVoiceName: string, opts?: { context?: Record<string, unknown> }): unknown;\n };\n}\n\n/**\n * Voice-only tool — for tools that only make sense inside a call (handoffs,\n * hold-music toggles, transfer-to-human, etc.). Skill tools are still available\n * to voice agents; LuaVoiceTool is for the call-only ones.\n */\nexport interface LuaVoiceToolConfig<TInput extends ZodType = ZodType> {\n name: string;\n description: string;\n inputSchema: TInput;\n execute: (input: any, ctx?: LuaVoiceToolCtx) => Promise<any>;\n condition?: () => Promise<boolean>;\n flags?: ToolFlag[];\n}\n\nexport class LuaVoiceTool<TInput extends ZodType = ZodType> implements LuaTool<TInput> {\n readonly name: string;\n readonly description: string;\n readonly inputSchema: TInput;\n readonly execute: (input: any, ctx?: LuaVoiceToolCtx) => Promise<any>;\n readonly condition?: () => Promise<boolean>;\n readonly voice?: { flags?: ToolFlag[] };\n\n constructor(config: LuaVoiceToolConfig<TInput>) {\n this.name = config.name;\n this.description = config.description;\n this.inputSchema = config.inputSchema;\n this.execute = config.execute;\n this.condition = config.condition;\n if (config.flags && config.flags.length > 0) {\n this.voice = { flags: config.flags };\n }\n }\n}\n\n/**\n * Full LuaVoice config — data fields (validated by zod in shared-types)\n * plus function-bearing fields (detected by the compiler via AST).\n */\n/**\n * LuaVoice config — uses loose input types for `llm` / `stt` / `tts` so devs can\n * pass either a string descriptor or a plugin class instance. The wire schema\n * (validated server-side) is the discriminated union in `@lua/shared-types`;\n * the compiler is what bridges the two.\n */\nexport interface LuaVoiceConfig extends Omit<LuaVoiceDataConfig, 'llm' | 'stt' | 'tts'> {\n llm: LuaVoiceModelInput;\n stt: LuaVoiceModelInput;\n tts: LuaVoiceModelInput;\n /** Optional human-readable description (surfaced in manifest + admin listings). */\n description?: string;\n /** Voice-only tools, in addition to skills attached to the owning agent. */\n tools?: Array<LuaTool<any> | LuaVoiceTool<any>>;\n /**\n * Fired after the session connects to the room and before the greeting.\n * Use to hydrate `session.userdata` from `User`/`Data`, set up state, etc.\n */\n onEnter?: (ctx: LuaVoiceHookContext) => Promise<void>;\n /**\n * Fired after the user finishes a turn, before the LLM is invoked. Canonical\n * RAG injection point — `turnCtx.addMessage(...)` adds context the LLM sees.\n */\n onUserTurnCompleted?: (turnCtx: LuaVoiceTurnContext, message: { content: string }) => Promise<void>;\n /**\n * Fired when the session is closing. Use for transcript persistence or\n * outcome reporting.\n */\n onExit?: (ctx: LuaVoiceHookContext) => Promise<void>;\n}\n\n/**\n * Code-defined voice agent. Pushed via `lua push`, attached to channels through\n * the owning `LuaAgent.voice` field. Auto-dispatched into LiveKit rooms when a\n * channel bound to that agent receives a voice event.\n *\n * @example\n * ```typescript\n * import { LuaVoice } from 'lua-cli';\n *\n * export default new LuaVoice({\n * name: 'support-line',\n * llm: 'openai/gpt-5.2-chat-latest',\n * stt: 'deepgram/nova-3',\n * tts: { model: 'cartesia/sonic-3', voice: '9626c31c-bec5-4cca-baa8-f8ba9e84c8bc' },\n * vad: 'silero',\n * turnDetection: 'multilingual',\n * greeting: 'Hi, how can I help today?',\n * maxToolSteps: 3,\n * interruption: { mode: 'adaptive', falseInterruptionTimeout: 2.0 },\n *\n * onEnter: async (ctx) => {\n * if (ctx.caller?.phoneNumber) {\n * const user = await User.get({ phone: ctx.caller.phoneNumber });\n * ctx.session.userdata = { user, returning: !!user };\n * }\n * },\n *\n * onUserTurnCompleted: async (turnCtx, message) => {\n * const docs = await Data.search('kb', message.content, 3);\n * for (const doc of docs) turnCtx.addMessage({ role: 'system', content: doc.text });\n * },\n * });\n * ```\n */\nexport class LuaVoice {\n readonly name: string;\n readonly description?: string;\n readonly llm: LuaVoiceModelInput;\n readonly stt: LuaVoiceModelInput;\n readonly tts: LuaVoiceModelInput;\n readonly vad: LuaVoiceDataConfig['vad'];\n readonly vadOptions: LuaVoiceDataConfig['vadOptions'];\n readonly turnDetection: LuaVoiceDataConfig['turnDetection'];\n readonly greeting: LuaVoiceDataConfig['greeting'];\n readonly maxToolSteps: LuaVoiceDataConfig['maxToolSteps'];\n readonly userAwayTimeout: LuaVoiceDataConfig['userAwayTimeout'];\n readonly preemptiveGeneration: LuaVoiceDataConfig['preemptiveGeneration'];\n readonly interruption: LuaVoiceDataConfig['interruption'];\n readonly sttLanguage: LuaVoiceDataConfig['sttLanguage'];\n\n readonly tools: ReadonlyArray<LuaTool<any> | LuaVoiceTool<any>>;\n readonly onEnter?: LuaVoiceConfig['onEnter'];\n readonly onUserTurnCompleted?: LuaVoiceConfig['onUserTurnCompleted'];\n readonly onExit?: LuaVoiceConfig['onExit'];\n\n constructor(config: LuaVoiceConfig) {\n // No `?? 'unnamed-voice'` fallback — the server-side schema requires\n // a non-empty name (zod `min(1)`), so a missing name would explode at\n // push time anyway. Throw early here so the dev sees the failure\n // during local compile rather than as an opaque server-side\n // validation error after `lua push`.\n if (!config.name || !config.name.trim()) {\n throw new Error('LuaVoice requires a non-empty `name` (used as the server-side identifier).');\n }\n this.name = config.name;\n this.description = config.description;\n this.llm = config.llm;\n this.stt = config.stt;\n this.tts = config.tts;\n this.vad = config.vad;\n this.vadOptions = config.vadOptions;\n this.turnDetection = config.turnDetection;\n this.greeting = config.greeting;\n this.maxToolSteps = config.maxToolSteps;\n this.userAwayTimeout = config.userAwayTimeout;\n this.preemptiveGeneration = config.preemptiveGeneration;\n this.interruption = config.interruption;\n this.sttLanguage = config.sttLanguage;\n this.tools = Object.freeze([...(config.tools ?? [])]);\n this.onEnter = config.onEnter;\n this.onUserTurnCompleted = config.onUserTurnCompleted;\n this.onExit = config.onExit;\n }\n}\n\n/**\n * Function-style LuaVoice definition. Equivalent to `new LuaVoice(config)`,\n * detected by the compiler via the `defineVoice(...)` AST pattern.\n *\n * @example\n * ```typescript\n * import { defineVoice } from 'lua-cli';\n * export default defineVoice({ name: 'support-line', ... });\n * ```\n */\nexport function defineVoice(config: LuaVoiceConfig): LuaVoice {\n return new LuaVoice(config);\n}\n","/**\n * Lua Skill API Exports\n *\n * Public API surface for LuaSkill tools.\n * This module provides simplified interfaces to Lua platform APIs\n * for use within skill implementations.\n *\n * Available APIs:\n * - User: User data management\n * - Data: Custom data collections (vector search, CRUD)\n * - Products: Product catalog management\n * - Baskets: Shopping basket operations\n * - Orders: Order management\n *\n * Usage in skills:\n * ```typescript\n * import { User, Data, Products, Baskets, Orders } from 'lua-cli';\n *\n * // Get user data\n * const user = await User.get();\n *\n * // Create custom data entry\n * await Data.create('customers', { name: 'John' });\n *\n * // Search products\n * const products = await Products.search('laptop');\n * ```\n */\n\nimport {\n LuaSkill,\n LuaWebhook,\n LuaJob,\n PreProcessor,\n PostProcessor,\n LuaAgent,\n LuaMCPServer,\n LuaDevice,\n LuaDeviceTrigger,\n ToolFlag,\n env,\n} from './types/skill.js';\nimport type {\n LuaTool,\n LuaWebhookConfig,\n LuaJobConfig,\n JobSchedule,\n PreProcessorConfig,\n PreProcessorAction,\n PreProcessorResult,\n PreProcessorBlockResponse,\n PreProcessorProceedResponse,\n PostProcessorConfig,\n PostProcessorResponse,\n LuaAgentConfig,\n LuaAgentModel,\n LuaMCPServerConfig,\n MCPSSEServerConfig,\n MCPStreamableHttpServerConfig,\n MCPTransport,\n MCPServerBaseConfig,\n LuaDeviceConfig,\n DeviceCommandConfig,\n DeviceTriggerConfig,\n LuaDeviceTriggerConfig,\n} from './types/skill.js';\nimport { LuaVoice, LuaVoiceTool, defineVoice } from './types/voice.js';\nimport type {\n LuaVoiceConfig,\n LuaVoiceToolConfig,\n LuaVoiceToolCtx,\n LuaVoiceHookContext,\n LuaVoiceTurnContext,\n} from './types/voice.js';\nimport type { PersonaText } from '@lua/shared-types';\nimport { BasketStatus } from './interfaces/baskets.js';\nimport type { Basket } from './interfaces/baskets.js';\nimport { OrderStatus } from './interfaces/orders.js';\nimport type { OrderResponse } from './interfaces/orders.js';\nimport type {\n ChatHistoryMessage,\n ChatHistoryContent,\n ChatMessage,\n TextMessage,\n ImageMessage,\n FileMessage,\n PreProcessorOverride,\n PostProcessorOverride,\n} from './interfaces/chat.js';\nimport {\n getUserInstance,\n getDataInstance,\n getProductsInstance,\n getBasketsInstance,\n getOrderInstance,\n getWebhookInstance,\n getJobInstance,\n getWhatsAppTemplatesInstance,\n getCdnInstance,\n} from './api/lazy-instances.js';\nimport { JobInstance } from './instances/job.instance.js';\nimport { compressForPush } from './utils/artifact-loader.js';\nimport { BASE_URLS } from './config/constants.js';\nimport type { DeleteProductResponse, Product, ProductFilterOptions } from './interfaces/product.js';\nimport ProductInstance from './instances/product.instance.js';\nimport ProductPaginationInstance from './instances/product.pagination.instance.js';\nimport ProductSearchInstance from './instances/product.search.instance.js';\nimport DataEntryInstance from './instances/data.entry.instance.js';\nimport type {\n DeleteCustomDataResponse,\n GetCustomDataResponse,\n SearchCustomDataResponse,\n UpdateCustomDataResponse,\n} from './interfaces/custom.data.js';\nimport UserDataInstance from './instances/user.instance.js';\nimport BasketInstance from './instances/basket.instance.js';\nimport OrderInstance from './instances/order.instance.js';\nimport type {\n WhatsAppTemplate,\n PaginatedTemplatesResponse,\n ListTemplatesOptions,\n SendTemplateData,\n SendTemplateResponse,\n} from './interfaces/whatsapp-templates.js';\nimport type { UserLookupOptions, ProfileResponse } from './interfaces/user.js';\n\nexport const User = {\n /**\n * Retrieves user data by userId, email, or phone.\n *\n * @param identifier - Optional userId string or lookup options\n * @returns Promise resolving to user data, or null if not found (for email/phone lookup)\n *\n * @example\n * // Get current user (in tools with conversation context)\n * const user = await User.get();\n *\n * // Get user by userId (required in webhooks/jobs)\n * const user = await User.get('user_123');\n *\n * // Get user by email\n * const user = await User.get({ email: 'customer@example.com' });\n *\n * // Get user by phone\n * const user = await User.get({ phone: '+1234567890' });\n */\n async get(identifier?: string | UserLookupOptions): Promise<UserDataInstance | null> {\n const instance = await getUserInstance();\n return instance.get(identifier);\n },\n\n /**\n * Gets the chat history for the current user.\n *\n * @returns Promise resolving to array of chat messages\n *\n * @example\n * ```typescript\n * const history = await User.getChatHistory();\n * // Returns: [\n * // { role: 'user', content: [{type: 'text', text: 'hello'}], createdAt: '...', id: '...', threadId: '...' },\n * // { role: 'assistant', content: [{type: 'text', text: 'hi'}], createdAt: '...', id: '...', threadId: '...' }\n * // ]\n * ```\n */\n async getChatHistory(): Promise<import('./interfaces/chat.js').ChatHistoryMessage[]> {\n const instance = await getUserInstance();\n return instance.getChatHistory();\n },\n};\n\n// ============================================================================\n// CUSTOM DATA API\n// ============================================================================\n\n/**\n * Custom Data API\n * Store and retrieve custom data with vector search capabilities\n */\nexport const Data = {\n /**\n * Creates a new entry in a custom data collection.\n *\n * @param collectionName - Name of the collection\n * @param data - Data to store\n * @param searchText - Optional text for vector search indexing\n * @returns Promise resolving to created entry\n */\n async create(collectionName: string, data: Record<string, any>, searchText?: string): Promise<DataEntryInstance> {\n const instance = await getDataInstance();\n return instance.create(collectionName, data, searchText);\n },\n\n /**\n * Retrieves entries from a collection with optional filtering and pagination.\n *\n * @param collectionName - Name of the collection\n * @param filter - Optional filter criteria\n * @param page - Page number (default: 1)\n * @param limit - Items per page (default: 10)\n * @returns Promise resolving to array of entries\n */\n async get(collectionName: string, filter?: any, page?: number, limit?: number): Promise<GetCustomDataResponse> {\n const instance = await getDataInstance();\n return instance.get(collectionName, filter, page, limit);\n },\n\n /**\n * Retrieves a specific entry by ID.\n *\n * @param collectionName - Name of the collection\n * @param entryId - ID of the entry\n * @returns Promise resolving to entry data\n */\n async getEntry(collectionName: string, entryId: string): Promise<DataEntryInstance> {\n const instance = await getDataInstance();\n return instance.getEntry(collectionName, entryId);\n },\n\n /**\n * Updates an existing entry.\n *\n * @param collectionName - Name of the collection\n * @param entryId - ID of the entry to update\n * @param data - Updated data fields to merge with existing entry\n * @param searchText - Optional new search text for vector search indexing\n * @returns Promise resolving to update response\n */\n async update(\n collectionName: string,\n entryId: string,\n data: Record<string, any>,\n searchText?: string\n ): Promise<UpdateCustomDataResponse> {\n const instance = await getDataInstance();\n return instance.update(collectionName, entryId, data, searchText);\n },\n\n /**\n * Performs vector search on a collection.\n *\n * @param collectionName - Name of the collection\n * @param searchText - Text to search for\n * @param limit - Maximum results to return\n * @param scoreThreshold - Minimum similarity score (0-1)\n * @returns Promise resolving to search results\n */\n async search(\n collectionName: string,\n searchText: string,\n limit?: number,\n scoreThreshold?: number\n ): Promise<DataEntryInstance[]> {\n const instance = await getDataInstance();\n return instance.search(collectionName, searchText, limit, scoreThreshold);\n },\n\n /**\n * Deletes an entry from a collection.\n *\n * @param collectionName - Name of the collection\n * @param entryId - ID of the entry to delete\n * @returns Promise resolving when deletion is complete\n */\n async delete(collectionName: string, entryId: string): Promise<DeleteCustomDataResponse> {\n const instance = await getDataInstance();\n return instance.delete(collectionName, entryId);\n },\n};\n\n// ============================================================================\n// PRODUCTS API\n// ============================================================================\n\n/**\n * Products API\n * Manage product catalog\n */\nexport const Products = {\n /**\n * Retrieves products with pagination and optional filtering.\n * Supports both legacy (page, limit) and new (options object) signatures.\n *\n * @returns Promise resolving to product list\n *\n * @example\n * // Legacy: Get products with pagination\n * await Products.get(1, 10);\n *\n * // New: Get products with options object\n * await Products.get({ page: 2, limit: 20 });\n *\n * // New: Filter products by category\n * await Products.get({ filter: { category: \"Electronics\" } });\n *\n * // New: Filter with MongoDB operators\n * await Products.get({ filter: { price: { $lte: 100 }, inStock: true } });\n */\n async get(pageOrOptions?: number | ProductFilterOptions, limit?: number): Promise<ProductPaginationInstance> {\n const instance = await getProductsInstance();\n if (typeof pageOrOptions === 'number') {\n return instance.get(pageOrOptions, limit);\n }\n return instance.get(pageOrOptions);\n },\n\n /**\n * Creates a new product.\n *\n * @param product - Product data\n * @returns Promise resolving to created product\n */\n async create(product: Product): Promise<ProductInstance> {\n const instance = await getProductsInstance();\n return instance.create(product);\n },\n\n /**\n * Deletes a product.\n *\n * @param id - Product ID\n * @returns Promise resolving when deletion is complete\n */\n async delete(id: string): Promise<DeleteProductResponse> {\n const instance = await getProductsInstance();\n return instance.delete(id);\n },\n\n /**\n * Searches products by query string.\n *\n * @param query - Search query\n * @returns Promise resolving to search results\n */\n async search(query: string): Promise<ProductSearchInstance> {\n const instance = await getProductsInstance();\n return instance.search(query);\n },\n\n /**\n * Retrieves a specific product by ID.\n *\n * @param id - Product ID\n * @returns Promise resolving to product data\n */\n async getById(id: string): Promise<ProductInstance> {\n const instance = await getProductsInstance();\n return instance.getById(id);\n },\n};\n\n// ============================================================================\n// BASKETS API\n// ============================================================================\n\n/**\n * Baskets API\n * Manage shopping baskets\n */\nexport const Baskets = {\n /**\n * Creates a new basket.\n *\n * @param basketData - Basket initialization data\n * @returns Promise resolving to created basket\n */\n async create(basketData: any): Promise<BasketInstance> {\n const instance = await getBasketsInstance();\n return instance.create(basketData);\n },\n\n /**\n * Retrieves baskets, optionally filtered by status.\n *\n * @param status - Optional basket status filter\n * @returns Promise resolving to basket list\n */\n async get(status?: any): Promise<BasketInstance[]> {\n const instance = await getBasketsInstance();\n return instance.get(status);\n },\n\n /**\n * Adds an item to a basket.\n *\n * @param basketId - Basket ID\n * @param itemData - Item data to add\n * @returns Promise resolving to updated basket\n */\n async addItem(basketId: string, itemData: any): Promise<Basket> {\n const instance = await getBasketsInstance();\n return instance.addItem(basketId, itemData);\n },\n\n /**\n * Removes an item from a basket.\n *\n * @param basketId - Basket ID\n * @param itemId - Item ID to remove\n * @returns Promise resolving to updated basket\n */\n async removeItem(basketId: string, itemId: string): Promise<Basket> {\n const instance = await getBasketsInstance();\n return instance.removeItem(basketId, itemId);\n },\n\n /**\n * Clears all items from a basket.\n *\n * @param basketId - Basket ID\n * @returns Promise resolving to cleared basket\n */\n async clear(basketId: string): Promise<Basket> {\n const instance = await getBasketsInstance();\n return instance.clear(basketId);\n },\n\n /**\n * Updates basket status.\n *\n * @param basketId - Basket ID\n * @param status - New basket status\n * @returns Promise resolving to updated basket\n */\n async updateStatus(basketId: string, status: any): Promise<BasketStatus> {\n const instance = await getBasketsInstance();\n return instance.updateStatus(basketId, status);\n },\n\n /**\n * Updates basket metadata.\n *\n * @param basketId - Basket ID\n * @param metadata - Metadata to update\n * @returns Promise resolving to the updated metadata\n */\n async updateMetadata(basketId: string, metadata: Record<string, any>): Promise<Record<string, any>> {\n const instance = await getBasketsInstance();\n return instance.updateMetadata(basketId, metadata);\n },\n\n /**\n * Converts basket to order.\n *\n * @param data - Order data\n * @param basketId - Basket ID to convert\n * @returns Promise resolving to created order\n */\n async placeOrder(data: Record<string, any>, basketId: string): Promise<OrderInstance> {\n const instance = await getBasketsInstance();\n return instance.placeOrder(data, basketId);\n },\n\n /**\n * Retrieves a specific basket by ID.\n *\n * @param basketId - Basket ID\n * @returns Promise resolving to basket data\n */\n async getById(basketId: string): Promise<BasketInstance> {\n const instance = await getBasketsInstance();\n return instance.getById(basketId);\n },\n};\n\n// ============================================================================\n// ORDERS API\n// ============================================================================\n\n/**\n * Orders API\n * Manage orders\n */\nexport const Orders = {\n /**\n * Creates a new order.\n *\n * @param orderData - Order data\n * @returns Promise resolving to created order\n */\n async create(orderData: any): Promise<OrderInstance> {\n const instance = await getOrderInstance();\n return instance.create(orderData);\n },\n\n /**\n * Updates order status.\n *\n * @param status - New order status\n * @param orderId - Order ID\n * @returns Promise resolving to updated order\n */\n async updateStatus(status: any, orderId: string): Promise<OrderResponse> {\n const instance = await getOrderInstance();\n return instance.updateStatus(status, orderId);\n },\n\n /**\n * Updates order data.\n *\n * @param data - Data to update\n * @param orderId - Order ID\n * @returns Promise resolving to updated order\n */\n async updateData(data: Record<string, any>, orderId: string): Promise<OrderResponse> {\n const instance = await getOrderInstance();\n return instance.updateData(data, orderId);\n },\n\n /**\n * Retrieves orders, optionally filtered by status.\n *\n * @param status - Optional order status filter\n * @returns Promise resolving to order list\n */\n async get(status?: any): Promise<OrderInstance[]> {\n const instance = await getOrderInstance();\n return instance.get(status);\n },\n\n /**\n * Retrieves a specific order by ID.\n *\n * @param orderId - Order ID\n * @returns Promise resolving to order data\n */\n async getById(orderId: string): Promise<OrderInstance> {\n const instance = await getOrderInstance();\n return instance.getById(orderId);\n },\n};\n\n// ============================================================================\n// JOBS API\n// ============================================================================\n\n/**\n * Jobs API\n * Manage and trigger scheduled jobs from within your tools\n */\nexport const Jobs = {\n /**\n * Creates a new job dynamically from within a tool.\n * This allows tools to schedule one-time or recurring jobs programmatically.\n *\n * **What this does:**\n * The server handles everything in ONE API call:\n * 1. Creates the job\n * 2. Creates version 1.0.0 with your execute function\n * 3. Optionally activates the job (if activate: true)\n * 4. Returns a JobInstance for manipulation\n *\n * @param config - Job configuration\n * @param config.name - Unique job name\n * @param config.description - Job description\n * @param config.schedule - Schedule configuration (cron, once, or interval)\n * @param config.execute - Async function to execute\n * @param config.timeout - Optional timeout in seconds\n * @param config.retry - Optional retry configuration\n * @param config.metadata - Optional metadata\n * @returns Promise resolving to JobInstance (already created, versioned, and activated)\n *\n * @example\n * ```typescript\n * // Create a one-time job to check basket in 3 hours\n * const job = await Jobs.create({\n * name: `check-basket-${basketId}`,\n * description: 'Check if basket was abandoned',\n * schedule: {\n * type: 'once',\n * executeAt: new Date(Date.now() + 3 * 60 * 60 * 1000)\n * },\n * metadata: {\n * basketId: basketId,\n * checkType: 'abandoned-cart'\n * },\n * execute: async (job, user) => {\n * // Access user context and metadata\n * console.log('Checking basket for user:', user.name);\n * console.log('Basket ID from metadata:', metadata?.basketId);\n *\n * const basket = await Baskets.getById(metadata.basketId);\n * if (basket.status === 'active') {\n * // Send reminder\n * }\n * return { checked: true };\n * }\n * });\n * // Job is now created, versioned as 1.0.0, and activated!\n * console.log(`Job ${job.jobId} is active: ${job.active}`);\n * ```\n */\n async create(config: {\n name: string;\n description?: string;\n schedule: any;\n execute: (job: JobInstance) => Promise<any>;\n timeout?: number;\n retry?: { maxAttempts: number; backoffSeconds?: number };\n metadata?: Record<string, any>;\n /** Auto-activate the job after creation (default: true) */\n activate?: boolean;\n }): Promise<JobInstance> {\n const instance = await getJobInstance();\n\n // Convert the execute function to a string\n const executeString = config.execute.toString();\n\n console.log('Creating Job');\n // Create the job with initial version and activation in one call\n return await instance.createJobInstance({\n dynamic: true,\n name: config.name,\n description: config.description,\n schedule: config.schedule,\n timeout: config.timeout,\n retry: config.retry,\n metadata: config.metadata,\n // Include initial version data for automatic version creation\n version: {\n version: '1.0.0',\n description: config.description,\n code: compressForPush(executeString),\n timeout: config.timeout,\n retry: config.retry,\n metadata: config.metadata,\n },\n // Activate immediately\n activate: config.activate ?? true,\n });\n },\n /**\n * Retrieves a job by its unique identifier\n * @param jobId - The unique identifier of the job to retrieve\n * @returns Promise resolving to an JobInstance representing the job\n * @throws Error if the job is not found or the request fails\n */\n async getJob(jobId: string): Promise<JobInstance> {\n const instance = await getJobInstance();\n return instance.getJob(jobId);\n },\n\n /**\n * Retrieves all jobs for the current agent\n * @param options - Optional configuration\n * @param options.includeDynamic - Include dynamically created jobs (default: false)\n * @returns Promise resolving to an array of JobInstance\n *\n * @example\n * ```typescript\n * // Get all jobs including dynamically created ones\n * const jobs = await Jobs.getAll({ includeDynamic: true });\n * for (const job of jobs) {\n * console.log(job.name, job.data.active ? 'active' : 'inactive');\n * }\n * ```\n */\n async getAll(options: { includeDynamic?: boolean } = {}): Promise<JobInstance[]> {\n const instance = await getJobInstance();\n return instance.getAll(options);\n },\n};\n\n// ============================================================================\n// AI GENERATION API\n// ============================================================================\n\n/**\n * AI API — isolated text generation (Vercel AI SDK–aligned); proxied to the API — not the agent chat pipeline.\n * See [`generateText`](https://ai-sdk.dev/docs/reference/ai-sdk-core/generate-text).\n */\nexport interface AiApi {\n /**\n * Generate text with a user prompt and optional content. Returns plain text.\n *\n * Single-arg: `prompt` is the user prompt.\n * Two-arg: `prompt` is the system instruction, `content` is user message content\n * (AI SDK `UserContent` — a string or array of multimodal parts).\n *\n * @example\n * ```typescript\n * const text = await AI.generate('Summarize the latest AI news.');\n * const text2 = await AI.generate(\n * 'You are a helpful assistant.',\n * [{ type: 'text', text: 'Hello!' }]\n * );\n * ```\n */\n generate(prompt: string, content?: import('ai').UserContent): Promise<string>;\n\n /**\n * Generate text with full options — a serializable subset of `generateText`\n * (`model`, `system`, `prompt`, `messages`, `temperature`, `maxOutputTokens`).\n * Returns the full AI SDK–aligned result including `text`, `finishReason`, `usage`,\n * `sources` (Google Search grounding), `reasoning`, `warnings`, and more.\n *\n * @example\n * ```typescript\n * const { text, finishReason, usage, sources } = await AI.generate({\n * system: 'You are concise.',\n * prompt: 'Say hi.',\n * });\n * ```\n */\n generate(options: import('@lua/shared-types').AiGenerateInput): Promise<import('@lua/shared-types').AiGenerateOutput>;\n}\n\nexport const AI: AiApi = {\n async generate(\n promptOrOptions: string | import('@lua/shared-types').AiGenerateInput,\n content?: import('ai').UserContent\n ): Promise<any> {\n const { getAiInstance } = await import('./api/lazy-instances.js');\n const ai = await getAiInstance();\n return ai.generateForSandbox(promptOrOptions, content);\n },\n};\n\n// ============================================================================\n// AGENT INVOCATION API\n// ============================================================================\n\n/**\n * Agents API — invoke another agent from inside your skill/tool/job/webhook/\n * processor code.\n */\nexport interface AgentsApi {\n /**\n * Invoke a target agent with a plain prompt. Returns the assistant's text.\n *\n * @example\n * ```typescript\n * const summary = await Agents.invoke('salesAgent', 'summarize the last order');\n * ```\n */\n invoke(targetAgentId: string, prompt: string): Promise<string>;\n\n /**\n * Invoke a target agent with full options. Returns the structured\n * {@link AgentInvocationOutput} including `text`, `threadId`, `finishReason`,\n * `usage`, and `toolsUsed`.\n *\n * @example\n * ```typescript\n * const result = await Agents.invoke('salesAgent', {\n * prompt: 'Draft a reply to the latest order',\n * threadId: 'order-123',\n * systemPrompt: 'Be concise.',\n * });\n * console.log(result.text, result.usage);\n * ```\n */\n invoke(\n targetAgentId: string,\n input: import('@lua/shared-types').AgentInvocationInput\n ): Promise<import('@lua/shared-types').AgentInvocationOutput>;\n}\n\nexport const Agents: AgentsApi = {\n async invoke(\n targetAgentId: string,\n promptOrInput: string | import('@lua/shared-types').AgentInvocationInput\n ): Promise<any> {\n const { getAgentsInstance } = await import('./api/lazy-instances.js');\n const agents = await getAgentsInstance();\n return agents.invokeForSandbox(targetAgentId, promptOrInput);\n },\n};\n\n// ============================================================================\n// VOICE API\n// ============================================================================\n\n/**\n * Voice API — place outbound voice calls from inside a job, webhook, or\n * skill tool. The platform allocates a LiveKit room, dials the target,\n * seeds the LuaVoice with the dev's `context`, and returns a session id\n * the dev can use to read the transcript later (when the LuaVoice has\n * `persistTranscript: true`).\n */\nexport interface VoiceApi {\n /**\n * Place an outbound voice call.\n *\n * @example\n * ```typescript\n * // Recovery flow — call abandoned-cart user with order context\n * await Voice.call({\n * to: '+15551234567',\n * voice: 'support-line',\n * context: { reason: 'recovery', orderId: 'O-123' },\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Web flow — return a join URL the dev's frontend opens\n * const { joinUrl, sessionId } = await Voice.call({\n * to: { kind: 'web', returnToken: true },\n * context: { customer: 'Acme Co' },\n * });\n * ```\n */\n call(input: import('@lua/shared-types').VoiceDispatchInput): Promise<import('@lua/shared-types').VoiceDispatchOutput>;\n}\n\nexport const Voice: VoiceApi = {\n async call(\n input: import('@lua/shared-types').VoiceDispatchInput\n ): Promise<import('@lua/shared-types').VoiceDispatchOutput> {\n const { getVoiceInstance } = await import('./api/lazy-instances.js');\n const voice = await getVoiceInstance();\n return voice.dispatchForSandbox(input);\n },\n};\n\n// ============================================================================\n// TEMPLATES API\n// ============================================================================\n\n/**\n * Templates API\n *\n * Manage templates across different channel types.\n * Use the appropriate namespace for your template type:\n *\n * - `Templates.whatsapp` - WhatsApp Business templates\n *\n * @example\n * ```typescript\n * // List WhatsApp templates\n * const result = await Templates.whatsapp.list(channelId);\n *\n * // Send a WhatsApp template\n * await Templates.whatsapp.send(channelId, templateId, {\n * phoneNumbers: ['+447551166594'],\n * values: { body: { name: 'John' } }\n * });\n * ```\n */\nexport const Templates = {\n /**\n * WhatsApp Templates\n *\n * Pre-approved message formats for WhatsApp Business Accounts.\n * Required for initiating conversations outside the 24-hour messaging window.\n */\n whatsapp: {\n /**\n * Lists WhatsApp templates for a channel with optional pagination and search.\n *\n * @param channelId - The WhatsApp channel identifier\n * @param options - Optional pagination and search options\n * @returns Promise resolving to paginated templates response\n *\n * @example\n * ```typescript\n * const result = await Templates.whatsapp.list(channelId);\n * const filtered = await Templates.whatsapp.list(channelId, { search: 'order' });\n * const paginated = await Templates.whatsapp.list(channelId, { page: 2, limit: 20 });\n * ```\n */\n async list(channelId: string, options?: ListTemplatesOptions): Promise<PaginatedTemplatesResponse> {\n const instance = await getWhatsAppTemplatesInstance();\n return instance.list(channelId, options);\n },\n\n /**\n * Gets a specific WhatsApp template by ID.\n *\n * @param channelId - The WhatsApp channel identifier\n * @param templateId - The template identifier\n * @returns Promise resolving to the template\n *\n * @example\n * ```typescript\n * const template = await Templates.whatsapp.get(channelId, 'template_123');\n * ```\n */\n async get(channelId: string, templateId: string): Promise<WhatsAppTemplate> {\n const instance = await getWhatsAppTemplatesInstance();\n return instance.get(channelId, templateId);\n },\n\n /**\n * Sends a WhatsApp template message to one or more phone numbers.\n *\n * @param channelId - The WhatsApp channel identifier\n * @param templateId - The template identifier\n * @param data - Send data including phone numbers and template values\n * @returns Promise resolving to the send response with results and errors\n *\n * @example\n * ```typescript\n * const result = await Templates.whatsapp.send(channelId, 'template_123', {\n * phoneNumbers: ['+447551166594'],\n * values: {\n * body: { first_name: 'John', order_number: '12345' }\n * }\n * });\n * ```\n */\n async send(channelId: string, templateId: string, data: SendTemplateData): Promise<SendTemplateResponse> {\n const instance = await getWhatsAppTemplatesInstance();\n return instance.send(channelId, templateId, data);\n },\n },\n};\n\n// ============================================================================\n// CDN API\n// ============================================================================\n\n/**\n * CDN API\n * Upload and retrieve files from the Lua CDN\n */\nexport const CDN = {\n /**\n * Uploads a file to the CDN.\n *\n * @param file - The File object to upload\n * @returns Promise resolving to the file ID\n *\n * @example\n * ```typescript\n * import { CDN } from 'lua-cli';\n * import { readFileSync } from 'fs';\n *\n * const buffer = readFileSync('image.png');\n * const file = new File([buffer], 'image.png', { type: 'image/png' });\n * const fileId = await CDN.upload(file);\n * console.log('Uploaded file ID:', fileId);\n * ```\n */\n async upload(file: File): Promise<string> {\n const instance = await getCdnInstance();\n return instance.upload(file);\n },\n\n /**\n * Retrieves a file from the CDN by its ID.\n *\n * @param fileId - The unique identifier of the file\n * @returns Promise resolving to a File object\n *\n * @example\n * ```typescript\n * import { CDN, AI } from 'lua-cli';\n *\n * const file = await CDN.get('abc123-def456');\n * console.log(file.name, file.type, file.size);\n *\n * // Use with AI API for image analysis\n * const buffer = Buffer.from(await file.arrayBuffer());\n * const response = await AI.generate(\n * 'You are an image analysis expert.',\n * [\n * { type: 'text', text: 'What do you see in this image?' },\n * { type: 'image', image: buffer, mediaType: file.type }\n * ]\n * );\n * ```\n */\n async get(fileId: string): Promise<File> {\n const instance = await getCdnInstance();\n return instance.get(fileId);\n },\n};\n\n// ============================================================================\n// LUA RUNTIME API\n// ============================================================================\n\nimport { Channel, LuaRuntime } from './interfaces/lua.js';\n\n/**\n * Lua Runtime API\n * Access request-level runtime information in your tools, conditions, and processors.\n *\n * @example\n * ```typescript\n * import { Lua } from 'lua-cli';\n *\n * // Access the current channel\n * const channel = Lua.request.channel;\n *\n * if (channel === 'whatsapp') {\n * // WhatsApp-specific logic\n * }\n *\n * // Access raw webhook payload (for webhook-based channels)\n * if (Lua.request.webhook) {\n * const payload = Lua.request.webhook.payload;\n * }\n * ```\n */\nexport const Lua: LuaRuntime = {\n request: {\n channel: 'unknown' as Channel,\n webhook: undefined,\n },\n};\n\n// ============================================================================\n// EXPORTS\n// ============================================================================\n\n// ============================================================================\n// DEVICE DEFINITION FUNCTION\n// ============================================================================\n\n/**\n * Define a device that an agent can communicate with.\n *\n * Devices support bidirectional communication:\n * - **commands**: Agent → Device (each becomes a tool the agent can call)\n * - **triggers**: Device → Agent (each has an execute handler that runs on the server)\n *\n * @example\n * ```typescript\n * import { defineDevice } from 'lua-cli';\n * import { z } from 'zod';\n *\n * export const printer = defineDevice({\n * name: 'label-printer',\n * description: 'Thermal label printer on Raspberry Pi',\n * group: 'printers',\n * commands: {\n * print: {\n * description: 'Print a label',\n * inputSchema: z.object({ text: z.string(), copies: z.number().default(1) }),\n * timeoutMs: 30000,\n * },\n * },\n * triggers: {\n * paper_low: {\n * description: 'Fired when paper level drops below threshold',\n * payloadSchema: z.object({ level: z.number() }),\n * execute: async (payload, { agent }) => {\n * await agent.chat(\\`Printer paper low: \\${payload.level}%\\`);\n * },\n * },\n * },\n * });\n * ```\n */\nexport function defineDevice(config: LuaDeviceConfig): LuaDevice {\n return new LuaDevice(config);\n}\n\n/**\n * Define a standalone device trigger primitive.\n *\n * Device triggers represent events fired from a device to an agent.\n * Each trigger is a first-class primitive that is compiled, versioned,\n * and pushed independently.\n *\n * @example\n * ```typescript\n * import { defineDeviceTrigger } from 'lua-cli';\n * import { z } from 'zod';\n *\n * export const paperLow = defineDeviceTrigger({\n * name: 'paper-low',\n * description: 'Fired when printer paper drops below threshold',\n * payloadSchema: z.object({ level: z.number() }),\n * execute: async (payload, { agent, device }) => {\n * await agent.chat(\\`Printer \\${device.name} paper low: \\${payload.level}%\\`);\n * },\n * });\n * ```\n */\nexport function defineDeviceTrigger(config: LuaDeviceTriggerConfig): LuaDeviceTrigger {\n return new LuaDeviceTrigger(config);\n}\n\n// Export skill classes and utilities (runtime values: classes / enums / functions / consts)\nexport {\n LuaSkill,\n LuaWebhook,\n LuaJob,\n PreProcessor,\n PreProcessor as LuaPreprocessor,\n PostProcessor,\n PostProcessor as LuaPostprocessor,\n LuaAgent,\n LuaMCPServer,\n LuaDevice,\n LuaDeviceTrigger,\n LuaVoice,\n LuaVoiceTool,\n defineVoice,\n ToolFlag,\n BasketStatus,\n OrderStatus,\n env,\n};\n\n// Export skill / agent / mcp / device / voice config types\nexport type {\n LuaTool,\n LuaWebhookConfig,\n LuaJobConfig,\n JobSchedule,\n PreProcessorConfig,\n PreProcessorAction,\n PreProcessorResult,\n PreProcessorBlockResponse,\n PreProcessorProceedResponse,\n PostProcessorConfig,\n PostProcessorResponse,\n LuaAgentConfig,\n LuaAgentModel,\n LuaMCPServerConfig,\n MCPSSEServerConfig,\n MCPStreamableHttpServerConfig,\n MCPTransport,\n MCPServerBaseConfig,\n LuaDeviceConfig,\n DeviceCommandConfig,\n DeviceTriggerConfig,\n LuaDeviceTriggerConfig,\n LuaVoiceConfig,\n LuaVoiceToolConfig,\n LuaVoiceToolCtx,\n LuaVoiceHookContext,\n LuaVoiceTurnContext,\n PersonaText,\n};\n\n// Export instance classes\nexport { JobInstance, UserDataInstance, DataEntryInstance, ProductInstance, BasketInstance, OrderInstance };\n\n// Export chat interfaces\nexport type {\n ChatHistoryMessage,\n ChatHistoryContent,\n ChatMessage,\n TextMessage,\n ImageMessage,\n FileMessage,\n PreProcessorOverride,\n PostProcessorOverride,\n};\n\n// Export template interfaces\nexport type {\n WhatsAppTemplate,\n PaginatedTemplatesResponse,\n ListTemplatesOptions,\n SendTemplateData,\n SendTemplateResponse,\n WhatsAppTemplateCategory,\n WhatsAppTemplateStatus,\n WhatsAppTemplateComponent,\n SendTemplateValues,\n} from './interfaces/whatsapp-templates.js';\n\n// Export Lua runtime types\nexport type { Channel, LuaRuntime, LuaRequest, WebhookRequest } from './interfaces/lua.js';\n\n// Export user lookup types\nexport type { UserLookupOptions, ProfileResponse } from './interfaces/user.js';\n\n// Re-export AI.generate wire types so customers can name them explicitly\n// (e.g. `const opts: AiGenerateInput = ...`). Inlined into the rolled .d.ts\n// via api-extractor `bundledPackages`.\nexport type {\n AiGenerateInput,\n AiGenerateOutput,\n AiGenerateStructuredOutput,\n AiGenerateJsonSchema,\n AiGenerateSource,\n AiGenerateToolCall,\n AiGenerateToolResult,\n} from '@lua/shared-types';\n\n// Re-export LuaAgent modelSettings type so customers can name it for\n// typed sampling-config variables.\nexport type { AgentModelSettings } from '@lua/shared-types';\n","/**\n * Order Interfaces\n * Order management and fulfillment\n */\n\nimport { BasketItem } from './baskets.js';\n\n/**\n * Order status enumeration.\n * Represents the lifecycle states of an order.\n */\nexport enum OrderStatus {\n /** Order created but not yet confirmed */\n PENDING = 'pending',\n /** Order confirmed and being processed */\n CONFIRMED = 'confirmed',\n /** Order completed and delivered */\n FULFILLED = 'fulfilled',\n /** Order cancelled */\n CANCELLED = 'cancelled',\n}\n\n/**\n * Order data container.\n * Contains the order details, items, and metadata.\n */\nexport interface OrderData {\n currency: string;\n items: BasketItem[];\n createdAt: string;\n basketId: string;\n orderDate: string;\n orderId: string;\n [key: string]: any; // Allow additional custom properties\n}\n\n/**\n * Common order properties.\n * Calculated/derived properties maintained by the system.\n */\nexport interface OrderCommon {\n status: 'pending' | 'confirmed' | 'fulfilled' | 'cancelled';\n totalAmount: string | number;\n currency: string;\n itemCount: number;\n}\n\n/**\n * Complete order entity.\n * Full order object as stored in the database.\n */\nexport interface OrderResponse {\n id: string;\n userId: string;\n agentId: string;\n orderId: string;\n data: OrderData;\n common: OrderCommon;\n createdAt: string;\n updatedAt: string;\n __v: number;\n}\n\n/**\n * Request to create a new order.\n * Typically created from a basket.\n */\nexport interface CreateOrderRequest {\n basketId: string;\n data: {\n [key: string]: any; // Allow any custom properties\n };\n}\n"],"mappings":"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","names":["BasketStatus","join","homedir","CLI_CONFIG_DIR","VERSION_CHECK_FILE","TELEMETRY_FILE","CLI_CACHE_FILE","BASE_URLS","CREDENTIALS_FILE","SANDBOX_STORAGE_FILE","AUTH_STORAGE_FILE","API","process","env","LUA_API_URL","AUTH","LUA_AUTH_URL","CHAT","WEBHOOK","CDN","AuthenticationError","Error","statusCode","isAuthenticationError","reason","serverMessage","suppressDefaultRemediation","message","name","captureStackTrace","error","randomUUID","HttpClient","baseUrl","request","url","options","controller","AbortController","timeoutId","setTimeout","abort","response","fetch","signal","headers","clearTimeout","ok","errorData","json","jsonError","status","serverMessage","message","undefined","test","AuthenticationError","isExplicitCredential","isBareAuthRejection","detail","Error","success","error","statusText","statusCode","data","isAuthenticationError","startsWith","DOMException","name","isRetryableStatus","calculateBackoff","attempt","baseMs","maxMs","exponential","Math","min","pow","max","random","retryableRequest","maxRetries","method","lastResult","result","backoff","Promise","resolve","httpGet","httpPost","body","JSON","stringify","httpPut","httpDelete","httpPatch","readFileSync","writeFileSync","mkdirSync","unlinkSync","getToken","process","env","LUA_API_KEY","token","CREDENTIALS_FILE","trim","AuthenticationError","undefined","COMPILE_DIRS","COMPILE_FILES","SKILL_DEFAULTS","YAML_FORMAT","DIST","DIST_V2","LUA","TOOLS","DEPLOYMENT_JSON","DEPLOY_JSON","MANIFEST_JSON","INDEX_TS","INDEX_JS","PACKAGE_JSON","TSCONFIG_JSON","LUA_SKILL_YAML","NAME","VERSION","DESCRIPTION","CONTEXT","INDENT","LINE_WIDTH","NO_REFS","__name","__defProp","PrimitiveKind","SkillApi","HttpClient","apiKey","agentId","baseUrl","getSkills","httpGet","Authorization","createSkill","skillData","httpPost","pushSkill","skillId","versionData","pushDevSkill","updateDevSkill","sandboxVersionId","httpPut","getSkillVersions","publishSkillVersion","version","undefined","deleteSkill","httpDelete","attachSkillSource","body","encodeURIComponent","fs","path","zlib","loadArtifact","primitive","projectPath","process","cwd","artifactPath","join","COMPILE_DIRS","DIST_V2","existsSync","Error","readFileSync","compressForPush","code","compressed","gzipSync","Buffer","from","toString","compressForPushRaw","loadOriginalSource","sourcePath","abs","isAbsolute","size","statSync","MAX_SOURCE_FILE_BYTES","normalizeEntryFile","rel","relative","startsWith","includes","sep","split","buildSourceArchive","files","length","map","entryFile","source","Object","keys","json","JSON","stringify","gz","findPrimitive","manifest","name","kind","primitives","find","p","SOURCE_ARCHIVE_SCHEMA_VERSION","crypto","hashBundle","rawGzip","createHash","update","digest","parseVersion","version","versionPart","preReleasePart","split","major","minor","patch","map","Number","preRelease","isNaN","compareVersions","version1","version2","v1","v2","preReleaseOrder","getPreReleaseType","type","toLowerCase","replace","index","indexOf","length","type1","type2","getPreReleaseNum","parts","num","parseInt","num1","num2","localeCompare","maxSemver","a","b","DEFAULT_VERSION","BaseVersionedHandler","SKILL_DEFAULTS","VERSION","cleanItem","item","name","version","yamlConfig","idField","getItemId","isActive","_serverItem","getActiveVersion","serverItem","active","versions","find","v","getServerItemName","shouldConsiderForOrphan","_item","fetchMergedForInteraction","apiKey","agentId","config","serverData","fetchServerState","localItems","getFromYaml","serverItems","merged","orphanIds","Set","serverFailed","filter","s","some","l","id","map","local","api","getApi","fetchFromServer","error","AuthenticationError","isAuthenticationError","fetchError","Error","message","String","applySyncToYaml","manifest","apiCredentials","messages","yamlUpdated","orphanedCount","console","displayNamePlural","warn","yamlItems","yamlById","yamlByName","serverByName","buildMaps","orphans","has","length","stubs","push","flagName","displayName","toLowerCase","replace","log","msg","deleteCommand","items","updatedItems","changed","msgs","syncFromServer","updateYaml","created","updated","creationUpdated","createMissingOnServer","syncWithServer","readYamlConfig","itemsWithoutId","manifestPrimitive","findPrimitive","kind","newId","createOnServer","updatedConfig","idx","findIndex","i","yamlKey","writeYamlConfig","Array","isArray","syncYamlWithManifest","manifestNames","primitives","p","existing","kept","includes","updateVersionInYaml","newVersion","options","silent","prepareForPush","projectPath","process","cwd","bundleAccumulator","primitive","code","loadArtifact","rawGzip","compressForPushRaw","codeS3Hash","hashBundle","set","buildPushData","undefined","compressedCode","compressForPush","description","getHighestServerVersion","entityId","entity","reduce","highest","maxSemver","batchGetHighestVersions","entityIds","result","Map","forEach","h","get","activeVersion","currentVersion","SkillHandler","skillHandler","BaseVersionedHandler","kind","PrimitiveKind","SKILL","displayName","displayNamePlural","deleteCommand","yamlConfig","yamlKey","idField","getApi","apiKey","agentId","SkillApi","BASE_URLS","API","fetchFromServer","api","response","getSkills","success","data","skills","createOnServer","primitive","skill","createSkill","name","description","hasPersonaTextContent","context","id","isActive","serverItem","active","getActiveVersion","versions","find","v","version","shouldConsiderForOrphan","source","getFromYaml","config","Array","isArray","length","map","skillId","legacy","updateVersionInYaml","newVersion","options","readYamlConfig","silent","Error","updated","s","writeYamlConfig","error","console","warn","syncYamlWithManifest","manifest","primitives","some","p","log","pushToServer","entityId","pushData","pushSkill","message","publishVersion","publishSkillVersion","prepareForPush","projectPath","process","cwd","bundleAccumulator","findPrimitive","archiveEntries","tools","toolName","tool","TOOL","code","loadArtifact","toolData","rawGzip","compressForPushRaw","codeS3Hash","hashBundle","set","inputSchema","schemas","input","undefined","hasCondition","condition","compressedCode","compressForPush","loadOriginalSource","sourcePath","entryFile","normalizeEntryFile","push","filter","Boolean","sourceArchive","buildSourceArchive","archiveSchemaVersion","SOURCE_ARCHIVE_SCHEMA_VERSION","fs","path","pkg","readYamlConfig","yamlPath","join","process","cwd","COMPILE_FILES","LUA_SKILL_YAML","existsSync","yamlContent","readFileSync","load","writeYamlConfig","config","filePath","options","sortKeys","yamlKeySorter","dump","indent","YAML_FORMAT","INDENT","lineWidth","LINE_WIDTH","noRefs","NO_REFS","replacer","key","value","undefined","writeFileSync","a","b","aIndex","YAML_KEY_ORDER","indexOf","bIndex","localeCompare","CHECK_INTERVAL_MS","PostHog","requireAuth","getToken","getCredentials","cachedCredentials","apiKey","requireAuth","config","readYamlConfig","agent","agentId","Error","ProductInstance","data","productAPI","api","product","Object","defineProperty","value","writable","enumerable","configurable","Proxy","get","target","prop","receiver","Reflect","undefined","set","reservedProps","includes","has","ownKeys","instanceKeys","dataKeys","keys","Set","getOwnPropertyDescriptor","instanceDesc","toJSON","Symbol","for","update","response","id","updated","Error","delete","deleted","save","error","ProductPaginationInstance","products","pagination","productAPI","api","results","productsData","data","Array","isArray","map","product","ProductInstance","currentPage","totalPages","totalCount","limit","hasNextPage","hasPrevPage","nextPage","prevPage","Object","defineProperty","value","writable","enumerable","configurable","length","callback","filter","forEach","find","findIndex","some","every","reduce","initialValue","Symbol","iterator","toJSON","for","Error","get","ProductSearchInstance","products","productAPI","api","results","productsData","data","Array","isArray","map","product","ProductInstance","Object","defineProperty","value","writable","enumerable","configurable","length","callback","filter","forEach","find","findIndex","some","every","reduce","initialValue","Symbol","iterator","toJSON","for","ProductApi","HttpClient","apiKey","agentId","baseUrl","get","pageOrOptions","limitArg","page","limit","filter","queryParams","URLSearchParams","append","toString","JSON","stringify","response","httpGet","Authorization","success","ProductPaginationInstance","Error","error","message","getById","productId","data","ProductInstance","create","productData","httpPost","product","update","httpPut","id","delete","httpDelete","search","searchQuery","encodeURIComponent","ProductSearchInstance","BasketInstance","id","userId","agentId","data","common","metadata","totalAmount","itemCount","status","basketAPI","api","basket","BasketStatus","ACTIVE","Object","defineProperty","value","writable","enumerable","configurable","Proxy","get","target","prop","receiver","Reflect","undefined","set","reservedProps","includes","has","ownKeys","instanceKeys","dataKeys","keys","commonKeys","Set","getOwnPropertyDescriptor","instanceDesc","toJSON","Symbol","for","updateMetadata","updateStatus","updateBasket","addItem","item","removeItem","itemId","clear","placeOrder","order","CHECKED_OUT","OrderInstance","data","common","id","userId","agentId","orderId","orderAPI","api","order","Object","defineProperty","value","writable","enumerable","configurable","Proxy","get","target","prop","receiver","Reflect","undefined","set","reservedProps","includes","has","ownKeys","instanceKeys","dataKeys","keys","commonKeys","Set","getOwnPropertyDescriptor","instanceDesc","toJSON","Symbol","for","updateStatus","status","response","update","updateData","save","error","Error","OrderApi","HttpClient","apiKey","agentId","baseUrl","create","orderData","response","httpPost","Authorization","success","data","OrderInstance","Error","error","message","updateStatus","status","orderId","httpPut","updateData","get","statusParam","httpGet","map","order","getById","BasketApi","HttpClient","apiKey","agentId","baseUrl","create","basketData","response","httpPost","Authorization","success","data","BasketInstance","Error","error","message","get","status","statusParam","httpGet","map","basket","getById","basketId","addItem","itemData","removeItem","itemId","httpDelete","clear","updateStatus","httpPut","undefined","updateMetadata","metadata","placeOrder","orderApi","OrderApi","OrderInstance","UserDataInstance","data","userAPI","_luaProfile","api","profile","Object","defineProperty","value","writable","enumerable","configurable","get","userId","fullName","mobileNumbers","emailAddresses","set","_","Proxy","target","prop","receiver","Reflect","undefined","reservedProps","includes","has","ownKeys","instanceKeys","dataKeys","keys","Set","getOwnPropertyDescriptor","instanceDesc","toJSON","Symbol","for","update","response","error","Error","clear","save","send","messages","sendMessage","getChatHistory","UserDataApi","HttpClient","apiKey","agentId","baseUrl","get","identifier","userId","profile","resolveUserProfile","id","url","response","httpGet","Authorization","success","Error","error","message","data","_luaProfile","UserDataInstance","options","developerApi","getDeveloperInstance","email","getUserProfileByEmail","phone","getUserProfileByPhone","includes","update","httpPut","cleanData","clear","httpDelete","sendMessage","messages","user","getAdminUser","httpPost","uid","getChatHistory","DataEntryInstance","data","id","collectionName","score","customDataAPI","api","entry","Object","defineProperty","value","writable","enumerable","configurable","Proxy","get","target","prop","receiver","Reflect","undefined","set","reservedProps","includes","has","ownKeys","instanceKeys","dataKeys","keys","Set","getOwnPropertyDescriptor","instanceDesc","toJSON","Symbol","for","update","searchText","error","Error","delete","save","CustomDataApi","HttpClient","apiKey","agentId","baseUrl","create","collectionName","data","searchText","response","httpPost","Authorization","success","DataEntryInstance","Error","error","message","get","filter","page","limit","url","encodedFilter","encodeURIComponent","JSON","stringify","httpGet","getEntry","entryId","update","httpPut","search","scoreThreshold","map","entry","delete","httpDelete","WebhookApi","HttpClient","apiKey","agentId","baseUrl","getWebhooks","httpGet","Authorization","createWebhook","webhookData","httpPost","updateWebhook","webhookId","data","httpPatch","pushWebhook","versionData","pushDevWebhook","updateDevWebhook","sandboxVersionId","httpPut","getWebhookVersions","publishWebhookVersion","version","activateWebhook","deactivateWebhook","deleteWebhook","httpDelete","JobInstance","jobApi","_data","id","name","activeVersion","metadata","userApi","jobData","userId","agentId","UserDataApi","BASE_URLS","API","apiKey","data","updateMetadata","result","success","Error","error","message","delete","deleteJob","user","get","trigger","versionId","triggerJob","activate","activateJob","deactivate","deactivateJob","toJSON","JobApi","HttpClient","apiKey","agentId","baseUrl","getJobs","options","queryParams","URLSearchParams","includeDynamic","append","url","toString","httpGet","Authorization","getAll","response","success","data","jobs","map","job","JobInstance","Error","error","message","getJob","jobId","createJob","jobData","httpPost","createJobInstance","pushJob","versionData","pushDevJob","updateDevJob","sandboxVersionId","httpPut","getJobVersions","publishJobVersion","version","deleteJob","httpDelete","activateJob","deactivateJob","triggerJob","versionId","body","getJobExecutions","limit","updateMetadata","metadata","AiApiService","HttpClient","baseUrl","apiKey","agentId","generate","body","httpPost","Authorization","generateForSandbox","promptOrOptions","content","result","aiGenerateInputFromSimplified","success","Error","error","message","data","text","AgentsApiService","HttpClient","baseUrl","apiKey","invoke","targetAgentId","body","channel","query","URLSearchParams","identifier","set","chatBody","toChatGenerateBody","httpPost","toString","Authorization","invokeForSandbox","promptOrInput","input","prompt","result","success","Error","error","message","data","text","messages","type","navigate","systemPrompt","undefined","runtimeContext","threadId","WhatsAppTemplatesApiService","HttpClient","apiKey","agentId","baseUrl","list","channelId","options","page","limit","search","url","encodeURIComponent","response","httpGet","Authorization","success","data","Error","error","message","get","templateId","send","body","phone_numbers","phoneNumbers","values","httpPost","CdnApi","baseUrl","apiKey","upload","file","formData","FormData","append","name","response","fetch","method","headers","Authorization","body","ok","error","json","catch","Error","message","status","data","fileId","get","contentType","contentDisposition","filenameMatch","match","filename","blob","File","type","DeveloperApi","HttpClient","apiKey","agentId","baseUrl","getEnvironmentVariables","httpGet","Authorization","updateEnvironmentVariables","envData","httpPost","deleteEnvironmentVariable","key","httpDelete","getMCPServers","getActiveMCPServers","getMCPServer","mcpServerId","createMCPServer","mcpServerData","updateMCPServer","httpPut","deleteMCPServer","activateMCPServer","deactivateMCPServer","upsertMCPServer","getUserProfileByEmail","email","encodeURIComponent","getUserProfileByPhone","phone","normalizedPhone","replace","VoiceApi","HttpClient","apiKey","agentId","baseUrl","getVoices","httpGet","Authorization","createVoice","voiceData","httpPost","pushVoice","voiceId","versionData","getVoiceVersions","publishVoiceVersion","version","httpPut","undefined","deleteVoice","httpDelete","dispatch","input","dispatchForSandbox","result","success","Error","error","message","data","DeviceApi","HttpClient","apiKey","agentId","baseUrl","getDevices","httpGet","Authorization","createDevice","deviceData","httpPost","pushDevice","deviceId","versionData","pushDevDevice","getDeviceVersions","publishDeviceVersion","version","deleteDevice","httpDelete","sendCommand","deviceName","command","payload","timeout","getDeviceStatus","enableDevice","httpPatch","disableDevice","getUserInstance","_userInstance","creds","getCredentials","UserDataApiService","BASE_URLS","API","apiKey","agentId","getDataInstance","_dataInstance","CustomDataApiService","getProductsInstance","_productsInstance","ProductApiService","getBasketsInstance","_basketsInstance","BasketApiService","getOrderInstance","_orderInstance","OrderApiService","getWebhookInstance","_webhookInstance","WebhookApi","getJobInstance","_jobInstance","JobApi","getAiInstance","_aiInstance","AiApiService","getAgentsInstance","_agentsInstance","AgentsApiService","getWhatsAppTemplatesInstance","_whatsAppTemplatesInstance","WhatsAppTemplatesApiService","getCdnInstance","_cdnInstance","CdnApi","CDN","getDeviceInstance","_deviceInstance","default","DeviceApi","getDeveloperInstance","_developerInstance","DeveloperApi","getVoiceInstance","_voiceInstance","VoiceApi","clearAllInstances","validateToolName","name","validNameRegex","test","assertValidToolName","Error","env","key","process","undefined","ToolFlag","LuaSkill","tools","name","description","context","config","trim","Error","base","voice","text","addTools","getContext","addTool","tool","assertValidToolName","push","run","input","find","validatedInput","inputSchema","parse","execute","LuaJob","schedule","timeout","retry","metadata","executeFunction","getName","getDescription","getSchedule","getTimeout","getRetry","getMetadata","job","LuaWebhook","querySchema","headerSchema","bodySchema","query","headers","body","validatedQuery","validatedHeaders","validatedBody","error","event","timestamp","Date","toISOString","PreProcessor","asyncMode","priority","async","getAsync","getPriority","user","messages","channel","PostProcessor","message","response","LuaMCPServer","transport","url","getTransport","getConfig","toJSON","validateModelSettings","settings","finiteNumberKeys","value","Number","isFinite","temperature","topP","maxOutputTokens","stopSequences","Array","isArray","every","v","LuaAgent","persona","model","modelSettings","skills","webhooks","jobs","preProcessors","postProcessors","mcpServers","devices","deviceTriggers","voices","batching","governance","getPersona","getModel","getModelSettings","getSkills","getWebhooks","getJobs","getPreProcessors","getPostProcessors","getMCPServers","getBatching","getDevices","getVoices","LuaDevice","group","commands","triggers","LuaDeviceTrigger","payloadSchema","LuaVoiceTool","name","description","inputSchema","execute","condition","voice","config","flags","length","LuaVoice","llm","stt","tts","vad","vadOptions","turnDetection","greeting","maxToolSteps","userAwayTimeout","preemptiveGeneration","interruption","sttLanguage","tools","onEnter","onUserTurnCompleted","onExit","trim","Error","Object","freeze","defineVoice","OrderStatus","User","get","identifier","instance","getUserInstance","getChatHistory","Data","create","collectionName","data","searchText","getDataInstance","filter","page","limit","getEntry","entryId","update","search","scoreThreshold","delete","Products","pageOrOptions","getProductsInstance","product","id","query","getById","Baskets","basketData","getBasketsInstance","status","addItem","basketId","itemData","removeItem","itemId","clear","updateStatus","updateMetadata","metadata","placeOrder","Orders","orderData","getOrderInstance","orderId","updateData","Jobs","config","getJobInstance","executeString","execute","toString","console","log","createJobInstance","dynamic","name","description","schedule","timeout","retry","version","code","compressForPush","activate","getJob","jobId","getAll","options","AI","generate","promptOrOptions","content","getAiInstance","ai","generateForSandbox","Agents","invoke","targetAgentId","promptOrInput","getAgentsInstance","agents","invokeForSandbox","Voice","call","input","getVoiceInstance","voice","dispatchForSandbox","Templates","whatsapp","list","channelId","getWhatsAppTemplatesInstance","templateId","send","CDN","upload","file","getCdnInstance","fileId","Lua","request","channel","webhook","undefined","defineDevice","LuaDevice","defineDeviceTrigger","LuaDeviceTrigger"]}
|