@stina/extension-api 0.19.1 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runtime.ts","../src/messages.ts"],"sourcesContent":["/**\n * Extension Runtime - Runs inside the worker\n *\n * This module handles communication with the Extension Host and provides\n * the ExtensionContext to the extension's activate function.\n */\n\nimport type {\n ExtensionContext,\n ExtensionModule,\n Disposable,\n NetworkAPI,\n SettingsAPI,\n ProvidersAPI,\n ToolsAPI,\n ActionsAPI,\n EventsAPI,\n SchedulerAPI,\n SchedulerJobRequest,\n SchedulerFirePayload,\n UserAPI,\n UserProfile,\n ChatAPI,\n ChatInstructionMessage,\n DatabaseAPI,\n StorageAPI,\n LogAPI,\n AIProvider,\n Tool,\n Action,\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n} from './types.js'\n\nimport type {\n HostToWorkerMessage,\n WorkerToHostMessage,\n RequestMessage,\n PendingRequest,\n} from './messages.js'\n\nimport { generateMessageId } from './messages.js'\n\n// ============================================================================\n// Environment Detection and Message Port\n// ============================================================================\n\n/**\n * Detect if we're in Node.js Worker Thread or Web Worker\n * and get the appropriate message port\n */\ninterface MessagePort {\n postMessage(message: WorkerToHostMessage): void\n onMessage(handler: (message: HostToWorkerMessage) => void): void\n}\n\nfunction getMessagePort(): MessagePort {\n // Check if we're in Node.js Worker Thread\n if (typeof process !== 'undefined' && process.versions?.node) {\n // Node.js Worker Thread - import parentPort dynamically\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { parentPort } = require('node:worker_threads')\n return {\n postMessage: (message) => parentPort?.postMessage(message),\n onMessage: (handler) => parentPort?.on('message', handler),\n }\n }\n\n // Web Worker - use self\n return {\n postMessage: (message) => self.postMessage(message),\n onMessage: (handler) => {\n self.addEventListener('message', (event: MessageEvent<HostToWorkerMessage>) => {\n handler(event.data)\n })\n },\n }\n}\n\nconst messagePort = getMessagePort()\n\n// ============================================================================\n// Global State\n// ============================================================================\n\nlet extensionModule: ExtensionModule | null = null\nlet extensionDisposable: Disposable | null = null\nlet extensionContext: ExtensionContext | null = null\n\nconst pendingRequests = new Map<string, PendingRequest>()\nconst registeredProviders = new Map<string, AIProvider>()\nconst registeredTools = new Map<string, Tool>()\nconst registeredActions = new Map<string, Action>()\nconst settingsCallbacks: Array<(key: string, value: unknown) => void> = []\nconst schedulerCallbacks: Array<(payload: SchedulerFirePayload) => void | Promise<void>> = []\n\n/**\n * Tracking for streaming fetch requests.\n * Each request stores incoming chunks and signals when new data arrives.\n */\ninterface StreamingFetchRequest {\n chunks: string[]\n done: boolean\n error?: string\n resolve?: () => void\n}\nconst streamingFetchRequests = new Map<string, StreamingFetchRequest>()\n\nconst REQUEST_TIMEOUT = 30000 // 30 seconds\n\n// ============================================================================\n// Message Handling\n// ============================================================================\n\n/**\n * Send a message to the host\n */\nfunction postMessage(message: WorkerToHostMessage): void {\n messagePort.postMessage(message)\n}\n\n/**\n * Send a request to the host and wait for response\n */\nasync function sendRequest<T>(method: RequestMessage['method'], payload: unknown): Promise<T> {\n const id = generateMessageId()\n\n return new Promise<T>((resolve, reject) => {\n const timeout = setTimeout(() => {\n pendingRequests.delete(id)\n reject(new Error(`Request ${method} timed out`))\n }, REQUEST_TIMEOUT)\n\n pendingRequests.set(id, { resolve: resolve as (value: unknown) => void, reject, timeout })\n\n postMessage({\n type: 'request',\n id,\n method,\n payload,\n })\n })\n}\n\n/**\n * Handle messages from the host\n */\nasync function handleHostMessage(message: HostToWorkerMessage): Promise<void> {\n switch (message.type) {\n case 'activate':\n await handleActivate(message.payload)\n break\n\n case 'deactivate':\n await handleDeactivate()\n break\n\n case 'settings-changed':\n handleSettingsChanged(message.payload.key, message.payload.value)\n break\n\n case 'scheduler-fire':\n await handleSchedulerFire(message.payload)\n break\n\n case 'provider-chat-request':\n await handleProviderChatRequest(message.id, message.payload)\n break\n\n case 'provider-models-request':\n await handleProviderModelsRequest(message.id, message.payload)\n break\n\n case 'tool-execute-request':\n await handleToolExecuteRequest(message.id, message.payload)\n break\n\n case 'action-execute-request':\n await handleActionExecuteRequest(message.id, message.payload)\n break\n\n case 'response':\n handleResponse(message.payload)\n break\n\n case 'streaming-fetch-chunk':\n handleStreamingFetchChunk(message.payload)\n break\n }\n}\n\n/**\n * Handle incoming streaming fetch chunks from the host\n */\nfunction handleStreamingFetchChunk(payload: {\n requestId: string\n chunk: string\n done: boolean\n error?: string\n}): void {\n const request = streamingFetchRequests.get(payload.requestId)\n if (!request) return\n\n if (payload.error) {\n request.error = payload.error\n request.done = true\n } else if (payload.chunk) {\n request.chunks.push(payload.chunk)\n }\n\n if (payload.done) {\n request.done = true\n }\n\n // Signal that new data is available\n if (request.resolve) {\n const resolve = request.resolve\n request.resolve = undefined\n resolve()\n }\n\n // Send acknowledgment for backpressure control\n postMessage({\n type: 'streaming-fetch-ack',\n payload: { requestId: payload.requestId },\n })\n}\n\nfunction handleResponse(payload: { requestId: string; success: boolean; data?: unknown; error?: string }): void {\n const pending = pendingRequests.get(payload.requestId)\n if (!pending) return\n\n clearTimeout(pending.timeout)\n pendingRequests.delete(payload.requestId)\n\n if (payload.success) {\n pending.resolve(payload.data)\n } else {\n pending.reject(new Error(payload.error || 'Unknown error'))\n }\n}\n\n// ============================================================================\n// Activation / Deactivation\n// ============================================================================\n\nasync function handleActivate(payload: {\n extensionId: string\n extensionVersion: string\n storagePath: string\n permissions: string[]\n settings: Record<string, unknown>\n}): Promise<void> {\n const { extensionId, extensionVersion, storagePath, permissions } = payload\n\n // Build the context based on permissions\n extensionContext = buildContext(extensionId, extensionVersion, storagePath, permissions)\n\n // Import and activate the extension\n try {\n // The actual extension code should be bundled and available\n // This is called after the extension code has been loaded into the worker\n if (extensionModule?.activate) {\n const result = await extensionModule.activate(extensionContext)\n if (result && 'dispose' in result) {\n extensionDisposable = result\n }\n }\n } catch (error) {\n extensionContext.log.error('Failed to activate extension', {\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n}\n\nasync function handleDeactivate(): Promise<void> {\n try {\n if (extensionModule?.deactivate) {\n await extensionModule.deactivate()\n }\n if (extensionDisposable) {\n extensionDisposable.dispose()\n }\n } catch (error) {\n console.error('Error during deactivation:', error)\n } finally {\n extensionModule = null\n extensionDisposable = null\n extensionContext = null\n registeredProviders.clear()\n registeredTools.clear()\n registeredActions.clear()\n settingsCallbacks.length = 0\n schedulerCallbacks.length = 0\n }\n}\n\nfunction handleSettingsChanged(key: string, value: unknown): void {\n for (const callback of settingsCallbacks) {\n try {\n callback(key, value)\n } catch (error) {\n console.error('Error in settings change callback:', error)\n }\n }\n}\n\nasync function handleSchedulerFire(payload: SchedulerFirePayload): Promise<void> {\n // Set the userId in context if this is a user-scoped job\n if (extensionContext && payload.userId) {\n ;(extensionContext as { userId?: string }).userId = payload.userId\n }\n\n // Run callbacks concurrently to avoid blocking\n const results = await Promise.allSettled(\n schedulerCallbacks.map((callback) => callback(payload)),\n )\n\n // Log any errors\n results.forEach((result, index) => {\n if (result.status === 'rejected') {\n console.error(`Error in scheduler callback ${index}:`, result.reason)\n }\n })\n\n // Reset userId after all callbacks have completed\n if (extensionContext) {\n ;(extensionContext as { userId?: string }).userId = undefined\n }\n}\n\n// ============================================================================\n// Provider / Tool Requests\n// ============================================================================\n\nasync function handleProviderChatRequest(\n requestId: string,\n payload: { providerId: string; messages: ChatMessage[]; options: ChatOptions }\n): Promise<void> {\n const provider = registeredProviders.get(payload.providerId)\n if (!provider) {\n postMessage({\n type: 'request',\n id: generateMessageId(),\n method: 'network.fetch', // Dummy, we need a proper error response\n payload: { error: `Provider ${payload.providerId} not found` },\n })\n return\n }\n\n try {\n const generator = provider.chat(payload.messages, payload.options)\n let sawDone = false\n let sawError = false\n\n for await (const event of generator) {\n if (event.type === 'done') {\n sawDone = true\n } else if (event.type === 'error') {\n sawError = true\n }\n postMessage({\n type: 'stream-event',\n payload: { requestId, event },\n })\n }\n\n if (!sawDone && !sawError) {\n postMessage({\n type: 'stream-event',\n payload: {\n requestId,\n event: { type: 'done' },\n },\n })\n }\n } catch (error) {\n postMessage({\n type: 'stream-event',\n payload: {\n requestId,\n event: {\n type: 'error',\n message: error instanceof Error ? error.message : String(error),\n },\n },\n })\n }\n}\n\nasync function handleProviderModelsRequest(\n requestId: string,\n payload: { providerId: string; options?: GetModelsOptions }\n): Promise<void> {\n const provider = registeredProviders.get(payload.providerId)\n if (!provider) {\n // Send error response\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models: [],\n error: `Provider ${payload.providerId} not found`,\n },\n })\n return\n }\n\n try {\n // Pass options to getModels so provider can use settings (e.g., URL for Ollama)\n const models = await provider.getModels(payload.options)\n // Send response with models\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models,\n },\n })\n } catch (error) {\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models: [],\n error: error instanceof Error ? error.message : String(error),\n },\n })\n }\n}\n\nasync function handleToolExecuteRequest(\n requestId: string,\n payload: { toolId: string; params: Record<string, unknown>; userId?: string }\n): Promise<void> {\n const tool = registeredTools.get(payload.toolId)\n if (!tool) {\n // Send error response\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result: { success: false, error: `Tool ${payload.toolId} not found` },\n error: `Tool ${payload.toolId} not found`,\n },\n })\n return\n }\n\n try {\n // Update the extension context with the userId if provided\n if (extensionContext && payload.userId) {\n // Create a new context with the userId for this execution\n ;(extensionContext as { userId?: string }).userId = payload.userId\n }\n\n const result = await tool.execute(payload.params)\n\n // Reset userId after execution\n if (extensionContext) {\n ;(extensionContext as { userId?: string }).userId = undefined\n }\n\n // Send response with result\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result,\n },\n })\n } catch (error) {\n // Reset userId on error\n if (extensionContext) {\n ;(extensionContext as { userId?: string }).userId = undefined\n }\n\n const errorMessage = error instanceof Error ? error.message : String(error)\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result: { success: false, error: errorMessage },\n error: errorMessage,\n },\n })\n }\n}\n\nasync function handleActionExecuteRequest(\n requestId: string,\n payload: { actionId: string; params: Record<string, unknown>; userId?: string }\n): Promise<void> {\n const action = registeredActions.get(payload.actionId)\n if (!action) {\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result: { success: false, error: `Action ${payload.actionId} not found` },\n error: `Action ${payload.actionId} not found`,\n },\n })\n return\n }\n\n try {\n // Update the extension context with the userId if provided\n if (extensionContext && payload.userId) {\n ;(extensionContext as { userId?: string }).userId = payload.userId\n }\n\n const result = await action.execute(payload.params)\n\n // Reset userId after execution\n if (extensionContext) {\n ;(extensionContext as { userId?: string }).userId = undefined\n }\n\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result,\n },\n })\n } catch (error) {\n // Reset userId on error\n if (extensionContext) {\n ;(extensionContext as { userId?: string }).userId = undefined\n }\n\n const errorMessage = error instanceof Error ? error.message : String(error)\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result: { success: false, error: errorMessage },\n error: errorMessage,\n },\n })\n }\n}\n\n// ============================================================================\n// Context Building\n// ============================================================================\n\nfunction buildContext(\n extensionId: string,\n extensionVersion: string,\n storagePath: string,\n permissions: string[]\n): ExtensionContext {\n const hasPermission = (perm: string): boolean => {\n return permissions.some((p) => {\n if (p === perm) return true\n if (p.endsWith(':*') && perm.startsWith(p.slice(0, -1))) return true\n return false\n })\n }\n\n const log: LogAPI = {\n debug: (message, data) => postMessage({ type: 'log', payload: { level: 'debug', message, data } }),\n info: (message, data) => postMessage({ type: 'log', payload: { level: 'info', message, data } }),\n warn: (message, data) => postMessage({ type: 'log', payload: { level: 'warn', message, data } }),\n error: (message, data) => postMessage({ type: 'log', payload: { level: 'error', message, data } }),\n }\n\n const context: ExtensionContext = {\n extension: {\n id: extensionId,\n version: extensionVersion,\n storagePath,\n },\n log,\n }\n\n // Add network API if permitted\n if (permissions.some((p) => p.startsWith('network:'))) {\n const networkApi: NetworkAPI = {\n async fetch(url: string, options?: RequestInit): Promise<Response> {\n const result = await sendRequest<{ status: number; statusText: string; headers: Record<string, string>; body: string }>('network.fetch', { url, options })\n return new Response(result.body, {\n status: result.status,\n statusText: result.statusText,\n headers: result.headers,\n })\n },\n\n async *fetchStream(url: string, options?: RequestInit): AsyncGenerator<string, void, unknown> {\n const requestId = generateMessageId()\n\n // Set up streaming request tracking\n const request: StreamingFetchRequest = {\n chunks: [],\n done: false,\n }\n streamingFetchRequests.set(requestId, request)\n\n // Send the streaming fetch request to the host\n postMessage({\n type: 'request',\n id: requestId,\n method: 'network.fetch-stream',\n payload: { url, options, requestId },\n })\n\n try {\n // Yield chunks as they arrive\n while (!request.done) {\n // Wait for new data\n await new Promise<void>((resolve) => {\n const resolver = () => {\n // Clear the stored resolver before resolving to avoid\n // stale callbacks being invoked for a new wait iteration.\n if (request.resolve === resolver) {\n request.resolve = undefined\n }\n resolve()\n }\n\n request.resolve = resolver\n\n // Check if we already have data or completion\n if (request.chunks.length > 0 || request.done) {\n resolver()\n }\n })\n\n // Check for errors first, before yielding any chunks\n if (request.error) {\n throw new Error(request.error)\n }\n\n // Yield all available chunks\n while (request.chunks.length > 0) {\n yield request.chunks.shift()!\n }\n }\n } finally {\n streamingFetchRequests.delete(requestId)\n }\n },\n }\n ;(context as { network: NetworkAPI }).network = networkApi\n }\n\n // Add settings API if permitted\n if (hasPermission('settings.register')) {\n const settingsApi: SettingsAPI = {\n async getAll<T extends Record<string, unknown>>(): Promise<T> {\n return sendRequest<T>('settings.getAll', {})\n },\n async get<T>(key: string): Promise<T | undefined> {\n return sendRequest<T | undefined>('settings.get', { key })\n },\n async set(key: string, value: unknown): Promise<void> {\n return sendRequest<void>('settings.set', { key, value })\n },\n onChange(callback: (key: string, value: unknown) => void): Disposable {\n settingsCallbacks.push(callback)\n return {\n dispose: () => {\n const index = settingsCallbacks.indexOf(callback)\n if (index >= 0) settingsCallbacks.splice(index, 1)\n },\n }\n },\n }\n ;(context as { settings: SettingsAPI }).settings = settingsApi\n }\n\n // Add providers API if permitted\n if (hasPermission('provider.register')) {\n const providersApi: ProvidersAPI = {\n register(provider: AIProvider): Disposable {\n registeredProviders.set(provider.id, provider)\n postMessage({\n type: 'provider-registered',\n payload: { id: provider.id, name: provider.name },\n })\n return {\n dispose: () => {\n registeredProviders.delete(provider.id)\n },\n }\n },\n }\n ;(context as { providers: ProvidersAPI }).providers = providersApi\n }\n\n // Add tools API if permitted\n if (hasPermission('tools.register')) {\n const toolsApi: ToolsAPI = {\n register(tool: Tool): Disposable {\n registeredTools.set(tool.id, tool)\n postMessage({\n type: 'tool-registered',\n payload: {\n id: tool.id,\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n },\n })\n return {\n dispose: () => {\n registeredTools.delete(tool.id)\n },\n }\n },\n }\n ;(context as { tools: ToolsAPI }).tools = toolsApi\n }\n\n // Add actions API if permitted\n if (hasPermission('actions.register')) {\n const actionsApi: ActionsAPI = {\n register(action: Action): Disposable {\n registeredActions.set(action.id, action)\n postMessage({\n type: 'action-registered',\n payload: {\n id: action.id,\n },\n })\n return {\n dispose: () => {\n registeredActions.delete(action.id)\n },\n }\n },\n }\n ;(context as { actions: ActionsAPI }).actions = actionsApi\n }\n\n // Add events API if permitted\n if (hasPermission('events.emit')) {\n const eventsApi: EventsAPI = {\n async emit(name: string, payload?: Record<string, unknown>): Promise<void> {\n await sendRequest<void>('events.emit', { name, payload })\n },\n }\n ;(context as { events: EventsAPI }).events = eventsApi\n }\n\n // Add scheduler API if permitted\n if (hasPermission('scheduler.register')) {\n const schedulerApi: SchedulerAPI = {\n async schedule(job: SchedulerJobRequest): Promise<void> {\n // Automatically include userId from context if not explicitly set\n const userId = (extensionContext as { userId?: string }).userId\n const jobWithUser = userId && !job.userId ? { ...job, userId } : job\n await sendRequest<void>('scheduler.schedule', { job: jobWithUser })\n },\n async cancel(jobId: string): Promise<void> {\n await sendRequest<void>('scheduler.cancel', { jobId })\n },\n onFire(callback: (payload: SchedulerFirePayload) => void): Disposable {\n schedulerCallbacks.push(callback)\n return {\n dispose: () => {\n const index = schedulerCallbacks.indexOf(callback)\n if (index >= 0) schedulerCallbacks.splice(index, 1)\n },\n }\n },\n }\n ;(context as { scheduler: SchedulerAPI }).scheduler = schedulerApi\n }\n\n // Add user profile API if permitted\n if (hasPermission('user.profile.read')) {\n const userApi: UserAPI = {\n async getProfile(): Promise<UserProfile> {\n return sendRequest<UserProfile>('user.getProfile', {})\n },\n }\n ;(context as { user: UserAPI }).user = userApi\n }\n\n // Add chat API if permitted\n if (hasPermission('chat.message.write')) {\n const chatApi: ChatAPI = {\n async appendInstruction(message: ChatInstructionMessage): Promise<void> {\n const contextUserId = (extensionContext as { userId?: string }).userId\n await sendRequest<void>('chat.appendInstruction', {\n ...message,\n userId: message.userId ?? contextUserId,\n })\n },\n }\n ;(context as { chat: ChatAPI }).chat = chatApi\n }\n\n // Add database API if permitted\n if (hasPermission('database.own')) {\n const databaseApi: DatabaseAPI = {\n async execute<T = unknown>(sql: string, params?: unknown[]): Promise<T[]> {\n return sendRequest<T[]>('database.execute', { sql, params })\n },\n }\n ;(context as { database: DatabaseAPI }).database = databaseApi\n }\n\n // Add storage API if permitted\n if (hasPermission('storage.local')) {\n const storageApi: StorageAPI = {\n // Global/extension-scoped storage\n async get<T>(key: string): Promise<T | undefined> {\n return sendRequest<T | undefined>('storage.get', { key })\n },\n async set(key: string, value: unknown): Promise<void> {\n return sendRequest<void>('storage.set', { key, value })\n },\n async delete(key: string): Promise<void> {\n return sendRequest<void>('storage.delete', { key })\n },\n async keys(): Promise<string[]> {\n return sendRequest<string[]>('storage.keys', {})\n },\n // User-scoped storage\n async getForUser<T>(userId: string, key: string): Promise<T | undefined> {\n return sendRequest<T | undefined>('storage.getForUser', { userId, key })\n },\n async setForUser(userId: string, key: string, value: unknown): Promise<void> {\n return sendRequest<void>('storage.setForUser', { userId, key, value })\n },\n async deleteForUser(userId: string, key: string): Promise<void> {\n return sendRequest<void>('storage.deleteForUser', { userId, key })\n },\n async keysForUser(userId: string): Promise<string[]> {\n return sendRequest<string[]>('storage.keysForUser', { userId })\n },\n }\n ;(context as { storage: StorageAPI }).storage = storageApi\n }\n\n return context\n}\n\n// ============================================================================\n// Initialization\n// ============================================================================\n\n/**\n * Initialize the extension runtime\n * This should be called by the extension's entry point\n */\nexport function initializeExtension(module: ExtensionModule): void {\n extensionModule = module\n\n // Set up message listener using the appropriate message port\n messagePort.onMessage(async (message: HostToWorkerMessage) => {\n try {\n await handleHostMessage(message)\n } catch (error) {\n console.error('Error handling message:', error)\n }\n })\n\n // Signal that we're ready\n postMessage({ type: 'ready' })\n}\n\n// Re-export types for extensions to use\nexport type {\n ExtensionContext,\n ExtensionModule,\n Disposable,\n AIProvider,\n Tool,\n ToolDefinition,\n ToolResult,\n ToolCall,\n Action,\n ActionResult,\n ModelInfo,\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n} from './types.js'\n","/**\n * Message protocol between Extension Host and Extension Workers\n */\n\nimport type {\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n ToolResult,\n ActionResult,\n ModelInfo,\n SchedulerFirePayload,\n} from './types.js'\n\n// ============================================================================\n// Host → Worker Messages\n// ============================================================================\n\nexport type HostToWorkerMessage =\n | ActivateMessage\n | DeactivateMessage\n | SettingsChangedMessage\n | SchedulerFireMessage\n | ProviderChatRequestMessage\n | ProviderModelsRequestMessage\n | ToolExecuteRequestMessage\n | ActionExecuteRequestMessage\n | ResponseMessage\n | StreamingFetchChunkMessage\n\nexport interface ActivateMessage {\n type: 'activate'\n id: string\n payload: {\n extensionId: string\n extensionVersion: string\n storagePath: string\n permissions: string[]\n settings: Record<string, unknown>\n }\n}\n\nexport interface DeactivateMessage {\n type: 'deactivate'\n id: string\n}\n\nexport interface SettingsChangedMessage {\n type: 'settings-changed'\n id: string\n payload: {\n key: string\n value: unknown\n }\n}\n\nexport interface SchedulerFireMessage {\n type: 'scheduler-fire'\n id: string\n payload: SchedulerFirePayload\n}\n\nexport interface ProviderChatRequestMessage {\n type: 'provider-chat-request'\n id: string\n payload: {\n providerId: string\n messages: ChatMessage[]\n options: ChatOptions\n }\n}\n\nexport interface ProviderModelsRequestMessage {\n type: 'provider-models-request'\n id: string\n payload: {\n providerId: string\n options?: GetModelsOptions\n }\n}\n\nexport interface ToolExecuteRequestMessage {\n type: 'tool-execute-request'\n id: string\n payload: {\n toolId: string\n params: Record<string, unknown>\n /** User ID if the tool is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ActionExecuteRequestMessage {\n type: 'action-execute-request'\n id: string\n payload: {\n actionId: string\n params: Record<string, unknown>\n /** User ID if the action is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ResponseMessage {\n type: 'response'\n id: string\n payload: {\n requestId: string\n success: boolean\n data?: unknown\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker with streaming fetch data chunks.\n * Used for streaming network responses (e.g., NDJSON streams from Ollama).\n */\nexport interface StreamingFetchChunkMessage {\n type: 'streaming-fetch-chunk'\n id: string\n payload: {\n requestId: string\n chunk: string\n done: boolean\n error?: string\n }\n}\n\n// ============================================================================\n// Worker → Host Messages\n// ============================================================================\n\nexport type WorkerToHostMessage =\n | ReadyMessage\n | RequestMessage\n | ProviderRegisteredMessage\n | ToolRegisteredMessage\n | ActionRegisteredMessage\n | StreamEventMessage\n | LogMessage\n | ProviderModelsResponseMessage\n | ToolExecuteResponseMessage\n | ActionExecuteResponseMessage\n | StreamingFetchAckMessage\n\nexport interface ReadyMessage {\n type: 'ready'\n}\n\n/**\n * Message sent from worker to host to acknowledge receipt of a streaming fetch chunk.\n * This enables backpressure control to prevent unbounded memory growth.\n */\nexport interface StreamingFetchAckMessage {\n type: 'streaming-fetch-ack'\n payload: {\n requestId: string\n }\n}\n\nexport interface RequestMessage {\n type: 'request'\n id: string\n method: RequestMethod\n payload: unknown\n}\n\nexport type RequestMethod =\n | 'network.fetch'\n | 'network.fetch-stream'\n | 'settings.getAll'\n | 'settings.get'\n | 'settings.set'\n | 'user.getProfile'\n | 'events.emit'\n | 'scheduler.schedule'\n | 'scheduler.cancel'\n | 'chat.appendInstruction'\n | 'database.execute'\n | 'storage.get'\n | 'storage.set'\n | 'storage.delete'\n | 'storage.keys'\n | 'storage.getForUser'\n | 'storage.setForUser'\n | 'storage.deleteForUser'\n | 'storage.keysForUser'\n\nexport interface ProviderRegisteredMessage {\n type: 'provider-registered'\n payload: {\n id: string\n name: string\n }\n}\n\nexport interface ToolRegisteredMessage {\n type: 'tool-registered'\n payload: {\n id: string\n name: string\n description: string\n parameters?: Record<string, unknown>\n }\n}\n\nexport interface ActionRegisteredMessage {\n type: 'action-registered'\n payload: {\n id: string\n }\n}\n\nexport interface StreamEventMessage {\n type: 'stream-event'\n payload: {\n requestId: string\n event: StreamEvent\n }\n}\n\nexport interface ProviderModelsResponseMessage {\n type: 'provider-models-response'\n payload: {\n requestId: string\n models: ModelInfo[]\n error?: string\n }\n}\n\nexport interface ToolExecuteResponseMessage {\n type: 'tool-execute-response'\n payload: {\n requestId: string\n result: ToolResult\n error?: string\n }\n}\n\nexport interface ActionExecuteResponseMessage {\n type: 'action-execute-response'\n payload: {\n requestId: string\n result: ActionResult\n error?: string\n }\n}\n\nexport interface LogMessage {\n type: 'log'\n payload: {\n level: 'debug' | 'info' | 'warn' | 'error'\n message: string\n data?: Record<string, unknown>\n }\n}\n\n// ============================================================================\n// Utility Types\n// ============================================================================\n\nexport interface PendingRequest<T = unknown> {\n resolve: (value: T) => void\n reject: (error: Error) => void\n timeout: ReturnType<typeof setTimeout>\n}\n\n/**\n * Generate a unique message ID\n */\nexport function generateMessageId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`\n}\n"],"mappings":"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","names":["module"]}
1
+ {"version":3,"sources":["../src/runtime.ts","../src/messages.ts"],"sourcesContent":["/**\n * Extension Runtime - Runs inside the worker\n *\n * This module handles communication with the Extension Host and provides\n * the ExtensionContext to the extension's activate function.\n */\n\nimport type {\n ExecutionContext,\n ExtensionContext,\n ExtensionModule,\n Disposable,\n NetworkAPI,\n SettingsAPI,\n ProvidersAPI,\n ToolsAPI,\n ActionsAPI,\n EventsAPI,\n SchedulerAPI,\n SchedulerJobRequest,\n SchedulerFirePayload,\n UserAPI,\n UserProfile,\n ChatAPI,\n ChatInstructionMessage,\n DatabaseAPI,\n StorageAPI,\n LogAPI,\n AIProvider,\n Tool,\n Action,\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n} from './types.js'\n\nimport type {\n HostToWorkerMessage,\n WorkerToHostMessage,\n RequestMessage,\n PendingRequest,\n} from './messages.js'\n\nimport { generateMessageId } from './messages.js'\n\n// ============================================================================\n// Environment Detection and Message Port\n// ============================================================================\n\n/**\n * Detect if we're in Node.js Worker Thread or Web Worker\n * and get the appropriate message port\n */\ninterface MessagePort {\n postMessage(message: WorkerToHostMessage): void\n onMessage(handler: (message: HostToWorkerMessage) => void): void\n}\n\nfunction getMessagePort(): MessagePort {\n // Check if we're in Node.js Worker Thread\n if (typeof process !== 'undefined' && process.versions?.node) {\n // Node.js Worker Thread - import parentPort dynamically\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { parentPort } = require('node:worker_threads')\n return {\n postMessage: (message) => parentPort?.postMessage(message),\n onMessage: (handler) => parentPort?.on('message', handler),\n }\n }\n\n // Web Worker - use self\n return {\n postMessage: (message) => self.postMessage(message),\n onMessage: (handler) => {\n self.addEventListener('message', (event: MessageEvent<HostToWorkerMessage>) => {\n handler(event.data)\n })\n },\n }\n}\n\nconst messagePort = getMessagePort()\n\n// ============================================================================\n// Global State\n// ============================================================================\n\nlet extensionModule: ExtensionModule | null = null\nlet extensionDisposable: Disposable | null = null\nlet extensionContext: ExtensionContext | null = null\n\nconst pendingRequests = new Map<string, PendingRequest>()\nconst registeredProviders = new Map<string, AIProvider>()\nconst registeredTools = new Map<string, Tool>()\nconst registeredActions = new Map<string, Action>()\nconst settingsCallbacks: Array<(key: string, value: unknown) => void> = []\nconst schedulerCallbacks: Array<(payload: SchedulerFirePayload, context: ExecutionContext) => void | Promise<void>> = []\n\n/**\n * Tracking for streaming fetch requests.\n * Each request stores incoming chunks and signals when new data arrives.\n */\ninterface StreamingFetchRequest {\n chunks: string[]\n done: boolean\n error?: string\n resolve?: () => void\n}\nconst streamingFetchRequests = new Map<string, StreamingFetchRequest>()\n\nconst REQUEST_TIMEOUT = 30000 // 30 seconds\n\n// ============================================================================\n// Message Handling\n// ============================================================================\n\n/**\n * Send a message to the host\n */\nfunction postMessage(message: WorkerToHostMessage): void {\n messagePort.postMessage(message)\n}\n\n/**\n * Send a request to the host and wait for response\n */\nasync function sendRequest<T>(method: RequestMessage['method'], payload: unknown): Promise<T> {\n const id = generateMessageId()\n\n return new Promise<T>((resolve, reject) => {\n const timeout = setTimeout(() => {\n pendingRequests.delete(id)\n reject(new Error(`Request ${method} timed out`))\n }, REQUEST_TIMEOUT)\n\n pendingRequests.set(id, { resolve: resolve as (value: unknown) => void, reject, timeout })\n\n postMessage({\n type: 'request',\n id,\n method,\n payload,\n })\n })\n}\n\n/**\n * Handle messages from the host\n */\nasync function handleHostMessage(message: HostToWorkerMessage): Promise<void> {\n switch (message.type) {\n case 'activate':\n await handleActivate(message.payload)\n break\n\n case 'deactivate':\n await handleDeactivate()\n break\n\n case 'settings-changed':\n handleSettingsChanged(message.payload.key, message.payload.value)\n break\n\n case 'scheduler-fire':\n await handleSchedulerFire(message.payload)\n break\n\n case 'provider-chat-request':\n await handleProviderChatRequest(message.id, message.payload)\n break\n\n case 'provider-models-request':\n await handleProviderModelsRequest(message.id, message.payload)\n break\n\n case 'tool-execute-request':\n await handleToolExecuteRequest(message.id, message.payload)\n break\n\n case 'action-execute-request':\n await handleActionExecuteRequest(message.id, message.payload)\n break\n\n case 'response':\n handleResponse(message.payload)\n break\n\n case 'streaming-fetch-chunk':\n handleStreamingFetchChunk(message.payload)\n break\n }\n}\n\n/**\n * Handle incoming streaming fetch chunks from the host\n */\nfunction handleStreamingFetchChunk(payload: {\n requestId: string\n chunk: string\n done: boolean\n error?: string\n}): void {\n const request = streamingFetchRequests.get(payload.requestId)\n if (!request) return\n\n if (payload.error) {\n request.error = payload.error\n request.done = true\n } else if (payload.chunk) {\n request.chunks.push(payload.chunk)\n }\n\n if (payload.done) {\n request.done = true\n }\n\n // Signal that new data is available\n if (request.resolve) {\n const resolve = request.resolve\n request.resolve = undefined\n resolve()\n }\n\n // Send acknowledgment for backpressure control\n postMessage({\n type: 'streaming-fetch-ack',\n payload: { requestId: payload.requestId },\n })\n}\n\nfunction handleResponse(payload: { requestId: string; success: boolean; data?: unknown; error?: string }): void {\n const pending = pendingRequests.get(payload.requestId)\n if (!pending) return\n\n clearTimeout(pending.timeout)\n pendingRequests.delete(payload.requestId)\n\n if (payload.success) {\n pending.resolve(payload.data)\n } else {\n pending.reject(new Error(payload.error || 'Unknown error'))\n }\n}\n\n// ============================================================================\n// Activation / Deactivation\n// ============================================================================\n\nasync function handleActivate(payload: {\n extensionId: string\n extensionVersion: string\n storagePath: string\n permissions: string[]\n settings: Record<string, unknown>\n}): Promise<void> {\n const { extensionId, extensionVersion, storagePath, permissions } = payload\n\n // Build the context based on permissions\n extensionContext = buildContext(extensionId, extensionVersion, storagePath, permissions)\n\n // Import and activate the extension\n try {\n // The actual extension code should be bundled and available\n // This is called after the extension code has been loaded into the worker\n if (extensionModule?.activate) {\n const result = await extensionModule.activate(extensionContext)\n if (result && 'dispose' in result) {\n extensionDisposable = result\n }\n }\n } catch (error) {\n extensionContext.log.error('Failed to activate extension', {\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n}\n\nasync function handleDeactivate(): Promise<void> {\n try {\n if (extensionModule?.deactivate) {\n await extensionModule.deactivate()\n }\n if (extensionDisposable) {\n extensionDisposable.dispose()\n }\n } catch (error) {\n console.error('Error during deactivation:', error)\n } finally {\n extensionModule = null\n extensionDisposable = null\n extensionContext = null\n registeredProviders.clear()\n registeredTools.clear()\n registeredActions.clear()\n settingsCallbacks.length = 0\n schedulerCallbacks.length = 0\n }\n}\n\nfunction handleSettingsChanged(key: string, value: unknown): void {\n for (const callback of settingsCallbacks) {\n try {\n callback(key, value)\n } catch (error) {\n console.error('Error in settings change callback:', error)\n }\n }\n}\n\nasync function handleSchedulerFire(payload: SchedulerFirePayload): Promise<void> {\n // Create request-scoped execution context\n const execContext: ExecutionContext = {\n userId: payload.userId,\n extension: {\n id: extensionContext!.extension.id,\n version: extensionContext!.extension.version,\n storagePath: extensionContext!.extension.storagePath,\n },\n }\n\n // Run callbacks concurrently to avoid blocking\n const results = await Promise.allSettled(\n schedulerCallbacks.map((callback) => callback(payload, execContext)),\n )\n\n // Log any errors\n results.forEach((result, index) => {\n if (result.status === 'rejected') {\n console.error(`Error in scheduler callback ${index}:`, result.reason)\n }\n })\n}\n\n// ============================================================================\n// Provider / Tool Requests\n// ============================================================================\n\nasync function handleProviderChatRequest(\n requestId: string,\n payload: { providerId: string; messages: ChatMessage[]; options: ChatOptions }\n): Promise<void> {\n const provider = registeredProviders.get(payload.providerId)\n if (!provider) {\n postMessage({\n type: 'request',\n id: generateMessageId(),\n method: 'network.fetch', // Dummy, we need a proper error response\n payload: { error: `Provider ${payload.providerId} not found` },\n })\n return\n }\n\n try {\n const generator = provider.chat(payload.messages, payload.options)\n let sawDone = false\n let sawError = false\n\n for await (const event of generator) {\n if (event.type === 'done') {\n sawDone = true\n } else if (event.type === 'error') {\n sawError = true\n }\n postMessage({\n type: 'stream-event',\n payload: { requestId, event },\n })\n }\n\n if (!sawDone && !sawError) {\n postMessage({\n type: 'stream-event',\n payload: {\n requestId,\n event: { type: 'done' },\n },\n })\n }\n } catch (error) {\n postMessage({\n type: 'stream-event',\n payload: {\n requestId,\n event: {\n type: 'error',\n message: error instanceof Error ? error.message : String(error),\n },\n },\n })\n }\n}\n\nasync function handleProviderModelsRequest(\n requestId: string,\n payload: { providerId: string; options?: GetModelsOptions }\n): Promise<void> {\n const provider = registeredProviders.get(payload.providerId)\n if (!provider) {\n // Send error response\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models: [],\n error: `Provider ${payload.providerId} not found`,\n },\n })\n return\n }\n\n try {\n // Pass options to getModels so provider can use settings (e.g., URL for Ollama)\n const models = await provider.getModels(payload.options)\n // Send response with models\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models,\n },\n })\n } catch (error) {\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models: [],\n error: error instanceof Error ? error.message : String(error),\n },\n })\n }\n}\n\nasync function handleToolExecuteRequest(\n requestId: string,\n payload: { toolId: string; params: Record<string, unknown>; userId?: string }\n): Promise<void> {\n const tool = registeredTools.get(payload.toolId)\n if (!tool) {\n // Send error response\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result: { success: false, error: `Tool ${payload.toolId} not found` },\n error: `Tool ${payload.toolId} not found`,\n },\n })\n return\n }\n\n try {\n // Create request-scoped execution context\n const execContext: ExecutionContext = {\n userId: payload.userId,\n extension: {\n id: extensionContext!.extension.id,\n version: extensionContext!.extension.version,\n storagePath: extensionContext!.extension.storagePath,\n },\n }\n\n const result = await tool.execute(payload.params, execContext)\n\n // Send response with result\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result,\n },\n })\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result: { success: false, error: errorMessage },\n error: errorMessage,\n },\n })\n }\n}\n\nasync function handleActionExecuteRequest(\n requestId: string,\n payload: { actionId: string; params: Record<string, unknown>; userId?: string }\n): Promise<void> {\n const action = registeredActions.get(payload.actionId)\n if (!action) {\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result: { success: false, error: `Action ${payload.actionId} not found` },\n error: `Action ${payload.actionId} not found`,\n },\n })\n return\n }\n\n try {\n // Create request-scoped execution context\n const execContext: ExecutionContext = {\n userId: payload.userId,\n extension: {\n id: extensionContext!.extension.id,\n version: extensionContext!.extension.version,\n storagePath: extensionContext!.extension.storagePath,\n },\n }\n\n const result = await action.execute(payload.params, execContext)\n\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result,\n },\n })\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result: { success: false, error: errorMessage },\n error: errorMessage,\n },\n })\n }\n}\n\n// ============================================================================\n// Context Building\n// ============================================================================\n\nfunction buildContext(\n extensionId: string,\n extensionVersion: string,\n storagePath: string,\n permissions: string[]\n): ExtensionContext {\n const hasPermission = (perm: string): boolean => {\n return permissions.some((p) => {\n if (p === perm) return true\n if (p.endsWith(':*') && perm.startsWith(p.slice(0, -1))) return true\n return false\n })\n }\n\n const log: LogAPI = {\n debug: (message, data) => postMessage({ type: 'log', payload: { level: 'debug', message, data } }),\n info: (message, data) => postMessage({ type: 'log', payload: { level: 'info', message, data } }),\n warn: (message, data) => postMessage({ type: 'log', payload: { level: 'warn', message, data } }),\n error: (message, data) => postMessage({ type: 'log', payload: { level: 'error', message, data } }),\n }\n\n const context: ExtensionContext = {\n extension: {\n id: extensionId,\n version: extensionVersion,\n storagePath,\n },\n log,\n }\n\n // Add network API if permitted\n if (permissions.some((p) => p.startsWith('network:'))) {\n const networkApi: NetworkAPI = {\n async fetch(url: string, options?: RequestInit): Promise<Response> {\n const result = await sendRequest<{ status: number; statusText: string; headers: Record<string, string>; body: string }>('network.fetch', { url, options })\n return new Response(result.body, {\n status: result.status,\n statusText: result.statusText,\n headers: result.headers,\n })\n },\n\n async *fetchStream(url: string, options?: RequestInit): AsyncGenerator<string, void, unknown> {\n const requestId = generateMessageId()\n\n // Set up streaming request tracking\n const request: StreamingFetchRequest = {\n chunks: [],\n done: false,\n }\n streamingFetchRequests.set(requestId, request)\n\n // Send the streaming fetch request to the host\n postMessage({\n type: 'request',\n id: requestId,\n method: 'network.fetch-stream',\n payload: { url, options, requestId },\n })\n\n try {\n // Yield chunks as they arrive\n while (!request.done) {\n // Wait for new data\n await new Promise<void>((resolve) => {\n const resolver = () => {\n // Clear the stored resolver before resolving to avoid\n // stale callbacks being invoked for a new wait iteration.\n if (request.resolve === resolver) {\n request.resolve = undefined\n }\n resolve()\n }\n\n request.resolve = resolver\n\n // Check if we already have data or completion\n if (request.chunks.length > 0 || request.done) {\n resolver()\n }\n })\n\n // Check for errors first, before yielding any chunks\n if (request.error) {\n throw new Error(request.error)\n }\n\n // Yield all available chunks\n while (request.chunks.length > 0) {\n yield request.chunks.shift()!\n }\n }\n } finally {\n streamingFetchRequests.delete(requestId)\n }\n },\n }\n ;(context as { network: NetworkAPI }).network = networkApi\n }\n\n // Add settings API if permitted\n if (hasPermission('settings.register')) {\n const settingsApi: SettingsAPI = {\n async getAll<T extends Record<string, unknown>>(): Promise<T> {\n return sendRequest<T>('settings.getAll', {})\n },\n async get<T>(key: string): Promise<T | undefined> {\n return sendRequest<T | undefined>('settings.get', { key })\n },\n async set(key: string, value: unknown): Promise<void> {\n return sendRequest<void>('settings.set', { key, value })\n },\n onChange(callback: (key: string, value: unknown) => void): Disposable {\n settingsCallbacks.push(callback)\n return {\n dispose: () => {\n const index = settingsCallbacks.indexOf(callback)\n if (index >= 0) settingsCallbacks.splice(index, 1)\n },\n }\n },\n }\n ;(context as { settings: SettingsAPI }).settings = settingsApi\n }\n\n // Add providers API if permitted\n if (hasPermission('provider.register')) {\n const providersApi: ProvidersAPI = {\n register(provider: AIProvider): Disposable {\n registeredProviders.set(provider.id, provider)\n postMessage({\n type: 'provider-registered',\n payload: { id: provider.id, name: provider.name },\n })\n return {\n dispose: () => {\n registeredProviders.delete(provider.id)\n },\n }\n },\n }\n ;(context as { providers: ProvidersAPI }).providers = providersApi\n }\n\n // Add tools API if permitted\n if (hasPermission('tools.register')) {\n const toolsApi: ToolsAPI = {\n register(tool: Tool): Disposable {\n registeredTools.set(tool.id, tool)\n postMessage({\n type: 'tool-registered',\n payload: {\n id: tool.id,\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n },\n })\n return {\n dispose: () => {\n registeredTools.delete(tool.id)\n },\n }\n },\n }\n ;(context as { tools: ToolsAPI }).tools = toolsApi\n }\n\n // Add actions API if permitted\n if (hasPermission('actions.register')) {\n const actionsApi: ActionsAPI = {\n register(action: Action): Disposable {\n registeredActions.set(action.id, action)\n postMessage({\n type: 'action-registered',\n payload: {\n id: action.id,\n },\n })\n return {\n dispose: () => {\n registeredActions.delete(action.id)\n },\n }\n },\n }\n ;(context as { actions: ActionsAPI }).actions = actionsApi\n }\n\n // Add events API if permitted\n if (hasPermission('events.emit')) {\n const eventsApi: EventsAPI = {\n async emit(name: string, payload?: Record<string, unknown>): Promise<void> {\n await sendRequest<void>('events.emit', { name, payload })\n },\n }\n ;(context as { events: EventsAPI }).events = eventsApi\n }\n\n // Add scheduler API if permitted\n if (hasPermission('scheduler.register')) {\n const schedulerApi: SchedulerAPI = {\n async schedule(job: SchedulerJobRequest): Promise<void> {\n // Extensions must explicitly set job.userId if they want user-scoped jobs\n // Use context.userId from the ExecutionContext in tool/action execute\n await sendRequest<void>('scheduler.schedule', { job })\n },\n async cancel(jobId: string): Promise<void> {\n await sendRequest<void>('scheduler.cancel', { jobId })\n },\n onFire(callback: (payload: SchedulerFirePayload, context: ExecutionContext) => void): Disposable {\n schedulerCallbacks.push(callback)\n return {\n dispose: () => {\n const index = schedulerCallbacks.indexOf(callback)\n if (index >= 0) schedulerCallbacks.splice(index, 1)\n },\n }\n },\n }\n ;(context as { scheduler: SchedulerAPI }).scheduler = schedulerApi\n }\n\n // Add user profile API if permitted\n if (hasPermission('user.profile.read')) {\n const userApi: UserAPI = {\n async getProfile(): Promise<UserProfile> {\n return sendRequest<UserProfile>('user.getProfile', {})\n },\n }\n ;(context as { user: UserAPI }).user = userApi\n }\n\n // Add chat API if permitted\n if (hasPermission('chat.message.write')) {\n const chatApi: ChatAPI = {\n async appendInstruction(message: ChatInstructionMessage): Promise<void> {\n // Extensions must explicitly set message.userId if they want user-scoped messages\n // Use context.userId from the ExecutionContext in tool/action execute\n await sendRequest<void>('chat.appendInstruction', message)\n },\n }\n ;(context as { chat: ChatAPI }).chat = chatApi\n }\n\n // Add database API if permitted\n if (hasPermission('database.own')) {\n const databaseApi: DatabaseAPI = {\n async execute<T = unknown>(sql: string, params?: unknown[]): Promise<T[]> {\n return sendRequest<T[]>('database.execute', { sql, params })\n },\n }\n ;(context as { database: DatabaseAPI }).database = databaseApi\n }\n\n // Add storage API if permitted\n if (hasPermission('storage.local')) {\n const storageApi: StorageAPI = {\n // Global/extension-scoped storage\n async get<T>(key: string): Promise<T | undefined> {\n return sendRequest<T | undefined>('storage.get', { key })\n },\n async set(key: string, value: unknown): Promise<void> {\n return sendRequest<void>('storage.set', { key, value })\n },\n async delete(key: string): Promise<void> {\n return sendRequest<void>('storage.delete', { key })\n },\n async keys(): Promise<string[]> {\n return sendRequest<string[]>('storage.keys', {})\n },\n // User-scoped storage\n async getForUser<T>(userId: string, key: string): Promise<T | undefined> {\n return sendRequest<T | undefined>('storage.getForUser', { userId, key })\n },\n async setForUser(userId: string, key: string, value: unknown): Promise<void> {\n return sendRequest<void>('storage.setForUser', { userId, key, value })\n },\n async deleteForUser(userId: string, key: string): Promise<void> {\n return sendRequest<void>('storage.deleteForUser', { userId, key })\n },\n async keysForUser(userId: string): Promise<string[]> {\n return sendRequest<string[]>('storage.keysForUser', { userId })\n },\n }\n ;(context as { storage: StorageAPI }).storage = storageApi\n }\n\n return context\n}\n\n// ============================================================================\n// Initialization\n// ============================================================================\n\n/**\n * Initialize the extension runtime\n * This should be called by the extension's entry point\n */\nexport function initializeExtension(module: ExtensionModule): void {\n extensionModule = module\n\n // Set up message listener using the appropriate message port\n messagePort.onMessage(async (message: HostToWorkerMessage) => {\n try {\n await handleHostMessage(message)\n } catch (error) {\n console.error('Error handling message:', error)\n }\n })\n\n // Signal that we're ready\n postMessage({ type: 'ready' })\n}\n\n// Re-export types for extensions to use\nexport type {\n ExecutionContext,\n ExtensionContext,\n ExtensionModule,\n Disposable,\n AIProvider,\n Tool,\n ToolDefinition,\n ToolResult,\n ToolCall,\n Action,\n ActionResult,\n ModelInfo,\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n} from './types.js'\n","/**\n * Message protocol between Extension Host and Extension Workers\n */\n\nimport type {\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n ToolResult,\n ActionResult,\n ModelInfo,\n SchedulerFirePayload,\n} from './types.js'\n\n// ============================================================================\n// Host → Worker Messages\n// ============================================================================\n\nexport type HostToWorkerMessage =\n | ActivateMessage\n | DeactivateMessage\n | SettingsChangedMessage\n | SchedulerFireMessage\n | ProviderChatRequestMessage\n | ProviderModelsRequestMessage\n | ToolExecuteRequestMessage\n | ActionExecuteRequestMessage\n | ResponseMessage\n | StreamingFetchChunkMessage\n\nexport interface ActivateMessage {\n type: 'activate'\n id: string\n payload: {\n extensionId: string\n extensionVersion: string\n storagePath: string\n permissions: string[]\n settings: Record<string, unknown>\n }\n}\n\nexport interface DeactivateMessage {\n type: 'deactivate'\n id: string\n}\n\nexport interface SettingsChangedMessage {\n type: 'settings-changed'\n id: string\n payload: {\n key: string\n value: unknown\n }\n}\n\nexport interface SchedulerFireMessage {\n type: 'scheduler-fire'\n id: string\n payload: SchedulerFirePayload\n}\n\nexport interface ProviderChatRequestMessage {\n type: 'provider-chat-request'\n id: string\n payload: {\n providerId: string\n messages: ChatMessage[]\n options: ChatOptions\n }\n}\n\nexport interface ProviderModelsRequestMessage {\n type: 'provider-models-request'\n id: string\n payload: {\n providerId: string\n options?: GetModelsOptions\n }\n}\n\nexport interface ToolExecuteRequestMessage {\n type: 'tool-execute-request'\n id: string\n payload: {\n toolId: string\n params: Record<string, unknown>\n /** User ID if the tool is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ActionExecuteRequestMessage {\n type: 'action-execute-request'\n id: string\n payload: {\n actionId: string\n params: Record<string, unknown>\n /** User ID if the action is executed in a user context */\n userId?: string\n }\n}\n\nexport interface ResponseMessage {\n type: 'response'\n id: string\n payload: {\n requestId: string\n success: boolean\n data?: unknown\n error?: string\n }\n}\n\n/**\n * Message sent from host to worker with streaming fetch data chunks.\n * Used for streaming network responses (e.g., NDJSON streams from Ollama).\n */\nexport interface StreamingFetchChunkMessage {\n type: 'streaming-fetch-chunk'\n id: string\n payload: {\n requestId: string\n chunk: string\n done: boolean\n error?: string\n }\n}\n\n// ============================================================================\n// Worker → Host Messages\n// ============================================================================\n\nexport type WorkerToHostMessage =\n | ReadyMessage\n | RequestMessage\n | ProviderRegisteredMessage\n | ToolRegisteredMessage\n | ActionRegisteredMessage\n | StreamEventMessage\n | LogMessage\n | ProviderModelsResponseMessage\n | ToolExecuteResponseMessage\n | ActionExecuteResponseMessage\n | StreamingFetchAckMessage\n\nexport interface ReadyMessage {\n type: 'ready'\n}\n\n/**\n * Message sent from worker to host to acknowledge receipt of a streaming fetch chunk.\n * This enables backpressure control to prevent unbounded memory growth.\n */\nexport interface StreamingFetchAckMessage {\n type: 'streaming-fetch-ack'\n payload: {\n requestId: string\n }\n}\n\nexport interface RequestMessage {\n type: 'request'\n id: string\n method: RequestMethod\n payload: unknown\n}\n\nexport type RequestMethod =\n | 'network.fetch'\n | 'network.fetch-stream'\n | 'settings.getAll'\n | 'settings.get'\n | 'settings.set'\n | 'user.getProfile'\n | 'events.emit'\n | 'scheduler.schedule'\n | 'scheduler.cancel'\n | 'chat.appendInstruction'\n | 'database.execute'\n | 'storage.get'\n | 'storage.set'\n | 'storage.delete'\n | 'storage.keys'\n | 'storage.getForUser'\n | 'storage.setForUser'\n | 'storage.deleteForUser'\n | 'storage.keysForUser'\n\nexport interface ProviderRegisteredMessage {\n type: 'provider-registered'\n payload: {\n id: string\n name: string\n }\n}\n\nexport interface ToolRegisteredMessage {\n type: 'tool-registered'\n payload: {\n id: string\n name: string\n description: string\n parameters?: Record<string, unknown>\n }\n}\n\nexport interface ActionRegisteredMessage {\n type: 'action-registered'\n payload: {\n id: string\n }\n}\n\nexport interface StreamEventMessage {\n type: 'stream-event'\n payload: {\n requestId: string\n event: StreamEvent\n }\n}\n\nexport interface ProviderModelsResponseMessage {\n type: 'provider-models-response'\n payload: {\n requestId: string\n models: ModelInfo[]\n error?: string\n }\n}\n\nexport interface ToolExecuteResponseMessage {\n type: 'tool-execute-response'\n payload: {\n requestId: string\n result: ToolResult\n error?: string\n }\n}\n\nexport interface ActionExecuteResponseMessage {\n type: 'action-execute-response'\n payload: {\n requestId: string\n result: ActionResult\n error?: string\n }\n}\n\nexport interface LogMessage {\n type: 'log'\n payload: {\n level: 'debug' | 'info' | 'warn' | 'error'\n message: string\n data?: Record<string, unknown>\n }\n}\n\n// ============================================================================\n// Utility Types\n// ============================================================================\n\nexport interface PendingRequest<T = unknown> {\n resolve: (value: T) => void\n reject: (error: Error) => void\n timeout: ReturnType<typeof setTimeout>\n}\n\n/**\n * Generate a unique message ID\n */\nexport function generateMessageId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACgRO,SAAS,oBAA4B;AAC1C,SAAO,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AACjE;;;ADxNA,SAAS,iBAA8B;AAErC,MAAI,OAAO,YAAY,eAAe,QAAQ,UAAU,MAAM;AAG5D,UAAM,EAAE,WAAW,IAAI,QAAQ,gBAAqB;AACpD,WAAO;AAAA,MACL,aAAa,CAAC,YAAY,YAAY,YAAY,OAAO;AAAA,MACzD,WAAW,CAAC,YAAY,YAAY,GAAG,WAAW,OAAO;AAAA,IAC3D;AAAA,EACF;AAGA,SAAO;AAAA,IACL,aAAa,CAAC,YAAY,KAAK,YAAY,OAAO;AAAA,IAClD,WAAW,CAAC,YAAY;AACtB,WAAK,iBAAiB,WAAW,CAAC,UAA6C;AAC7E,gBAAQ,MAAM,IAAI;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,IAAM,cAAc,eAAe;AAMnC,IAAI,kBAA0C;AAC9C,IAAI,sBAAyC;AAC7C,IAAI,mBAA4C;AAEhD,IAAM,kBAAkB,oBAAI,IAA4B;AACxD,IAAM,sBAAsB,oBAAI,IAAwB;AACxD,IAAM,kBAAkB,oBAAI,IAAkB;AAC9C,IAAM,oBAAoB,oBAAI,IAAoB;AAClD,IAAM,oBAAkE,CAAC;AACzE,IAAM,qBAAgH,CAAC;AAYvH,IAAM,yBAAyB,oBAAI,IAAmC;AAEtE,IAAM,kBAAkB;AASxB,SAAS,YAAY,SAAoC;AACvD,cAAY,YAAY,OAAO;AACjC;AAKA,eAAe,YAAe,QAAkC,SAA8B;AAC5F,QAAM,KAAK,kBAAkB;AAE7B,SAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AACzC,UAAM,UAAU,WAAW,MAAM;AAC/B,sBAAgB,OAAO,EAAE;AACzB,aAAO,IAAI,MAAM,WAAW,MAAM,YAAY,CAAC;AAAA,IACjD,GAAG,eAAe;AAElB,oBAAgB,IAAI,IAAI,EAAE,SAA8C,QAAQ,QAAQ,CAAC;AAEzF,gBAAY;AAAA,MACV,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;AAKA,eAAe,kBAAkB,SAA6C;AAC5E,UAAQ,QAAQ,MAAM;AAAA,IACpB,KAAK;AACH,YAAM,eAAe,QAAQ,OAAO;AACpC;AAAA,IAEF,KAAK;AACH,YAAM,iBAAiB;AACvB;AAAA,IAEF,KAAK;AACH,4BAAsB,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,KAAK;AAChE;AAAA,IAEF,KAAK;AACH,YAAM,oBAAoB,QAAQ,OAAO;AACzC;AAAA,IAEF,KAAK;AACH,YAAM,0BAA0B,QAAQ,IAAI,QAAQ,OAAO;AAC3D;AAAA,IAEF,KAAK;AACH,YAAM,4BAA4B,QAAQ,IAAI,QAAQ,OAAO;AAC7D;AAAA,IAEF,KAAK;AACH,YAAM,yBAAyB,QAAQ,IAAI,QAAQ,OAAO;AAC1D;AAAA,IAEF,KAAK;AACH,YAAM,2BAA2B,QAAQ,IAAI,QAAQ,OAAO;AAC5D;AAAA,IAEF,KAAK;AACH,qBAAe,QAAQ,OAAO;AAC9B;AAAA,IAEF,KAAK;AACH,gCAA0B,QAAQ,OAAO;AACzC;AAAA,EACJ;AACF;AAKA,SAAS,0BAA0B,SAK1B;AACP,QAAM,UAAU,uBAAuB,IAAI,QAAQ,SAAS;AAC5D,MAAI,CAAC,QAAS;AAEd,MAAI,QAAQ,OAAO;AACjB,YAAQ,QAAQ,QAAQ;AACxB,YAAQ,OAAO;AAAA,EACjB,WAAW,QAAQ,OAAO;AACxB,YAAQ,OAAO,KAAK,QAAQ,KAAK;AAAA,EACnC;AAEA,MAAI,QAAQ,MAAM;AAChB,YAAQ,OAAO;AAAA,EACjB;AAGA,MAAI,QAAQ,SAAS;AACnB,UAAM,UAAU,QAAQ;AACxB,YAAQ,UAAU;AAClB,YAAQ;AAAA,EACV;AAGA,cAAY;AAAA,IACV,MAAM;AAAA,IACN,SAAS,EAAE,WAAW,QAAQ,UAAU;AAAA,EAC1C,CAAC;AACH;AAEA,SAAS,eAAe,SAAwF;AAC9G,QAAM,UAAU,gBAAgB,IAAI,QAAQ,SAAS;AACrD,MAAI,CAAC,QAAS;AAEd,eAAa,QAAQ,OAAO;AAC5B,kBAAgB,OAAO,QAAQ,SAAS;AAExC,MAAI,QAAQ,SAAS;AACnB,YAAQ,QAAQ,QAAQ,IAAI;AAAA,EAC9B,OAAO;AACL,YAAQ,OAAO,IAAI,MAAM,QAAQ,SAAS,eAAe,CAAC;AAAA,EAC5D;AACF;AAMA,eAAe,eAAe,SAMZ;AAChB,QAAM,EAAE,aAAa,kBAAkB,aAAa,YAAY,IAAI;AAGpE,qBAAmB,aAAa,aAAa,kBAAkB,aAAa,WAAW;AAGvF,MAAI;AAGF,QAAI,iBAAiB,UAAU;AAC7B,YAAM,SAAS,MAAM,gBAAgB,SAAS,gBAAgB;AAC9D,UAAI,UAAU,aAAa,QAAQ;AACjC,8BAAsB;AAAA,MACxB;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,qBAAiB,IAAI,MAAM,gCAAgC;AAAA,MACzD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IAC9D,CAAC;AACD,UAAM;AAAA,EACR;AACF;AAEA,eAAe,mBAAkC;AAC/C,MAAI;AACF,QAAI,iBAAiB,YAAY;AAC/B,YAAM,gBAAgB,WAAW;AAAA,IACnC;AACA,QAAI,qBAAqB;AACvB,0BAAoB,QAAQ;AAAA,IAC9B;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,8BAA8B,KAAK;AAAA,EACnD,UAAE;AACA,sBAAkB;AAClB,0BAAsB;AACtB,uBAAmB;AACnB,wBAAoB,MAAM;AAC1B,oBAAgB,MAAM;AACtB,sBAAkB,MAAM;AACxB,sBAAkB,SAAS;AAC3B,uBAAmB,SAAS;AAAA,EAC9B;AACF;AAEA,SAAS,sBAAsB,KAAa,OAAsB;AAChE,aAAW,YAAY,mBAAmB;AACxC,QAAI;AACF,eAAS,KAAK,KAAK;AAAA,IACrB,SAAS,OAAO;AACd,cAAQ,MAAM,sCAAsC,KAAK;AAAA,IAC3D;AAAA,EACF;AACF;AAEA,eAAe,oBAAoB,SAA8C;AAE/E,QAAM,cAAgC;AAAA,IACpC,QAAQ,QAAQ;AAAA,IAChB,WAAW;AAAA,MACT,IAAI,iBAAkB,UAAU;AAAA,MAChC,SAAS,iBAAkB,UAAU;AAAA,MACrC,aAAa,iBAAkB,UAAU;AAAA,IAC3C;AAAA,EACF;AAGA,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,mBAAmB,IAAI,CAAC,aAAa,SAAS,SAAS,WAAW,CAAC;AAAA,EACrE;AAGA,UAAQ,QAAQ,CAAC,QAAQ,UAAU;AACjC,QAAI,OAAO,WAAW,YAAY;AAChC,cAAQ,MAAM,+BAA+B,KAAK,KAAK,OAAO,MAAM;AAAA,IACtE;AAAA,EACF,CAAC;AACH;AAMA,eAAe,0BACb,WACA,SACe;AACf,QAAM,WAAW,oBAAoB,IAAI,QAAQ,UAAU;AAC3D,MAAI,CAAC,UAAU;AACb,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,IAAI,kBAAkB;AAAA,MACtB,QAAQ;AAAA;AAAA,MACR,SAAS,EAAE,OAAO,YAAY,QAAQ,UAAU,aAAa;AAAA,IAC/D,CAAC;AACD;AAAA,EACF;AAEA,MAAI;AACF,UAAM,YAAY,SAAS,KAAK,QAAQ,UAAU,QAAQ,OAAO;AACjE,QAAI,UAAU;AACd,QAAI,WAAW;AAEf,qBAAiB,SAAS,WAAW;AACnC,UAAI,MAAM,SAAS,QAAQ;AACzB,kBAAU;AAAA,MACZ,WAAW,MAAM,SAAS,SAAS;AACjC,mBAAW;AAAA,MACb;AACA,kBAAY;AAAA,QACV,MAAM;AAAA,QACN,SAAS,EAAE,WAAW,MAAM;AAAA,MAC9B,CAAC;AAAA,IACH;AAEA,QAAI,CAAC,WAAW,CAAC,UAAU;AACzB,kBAAY;AAAA,QACV,MAAM;AAAA,QACN,SAAS;AAAA,UACP;AAAA,UACA,OAAO,EAAE,MAAM,OAAO;AAAA,QACxB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,OAAO;AACd,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAChE;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,eAAe,4BACb,WACA,SACe;AACf,QAAM,WAAW,oBAAoB,IAAI,QAAQ,UAAU;AAC3D,MAAI,CAAC,UAAU;AAEb,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA,QAAQ,CAAC;AAAA,QACT,OAAO,YAAY,QAAQ,UAAU;AAAA,MACvC;AAAA,IACF,CAAC;AACD;AAAA,EACF;AAEA,MAAI;AAEF,UAAM,SAAS,MAAM,SAAS,UAAU,QAAQ,OAAO;AAEvD,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,SAAS,OAAO;AACd,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA,QAAQ,CAAC;AAAA,QACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAC9D;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,eAAe,yBACb,WACA,SACe;AACf,QAAM,OAAO,gBAAgB,IAAI,QAAQ,MAAM;AAC/C,MAAI,CAAC,MAAM;AAET,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA,QAAQ,EAAE,SAAS,OAAO,OAAO,QAAQ,QAAQ,MAAM,aAAa;AAAA,QACpE,OAAO,QAAQ,QAAQ,MAAM;AAAA,MAC/B;AAAA,IACF,CAAC;AACD;AAAA,EACF;AAEA,MAAI;AAEF,UAAM,cAAgC;AAAA,MACpC,QAAQ,QAAQ;AAAA,MAChB,WAAW;AAAA,QACT,IAAI,iBAAkB,UAAU;AAAA,QAChC,SAAS,iBAAkB,UAAU;AAAA,QACrC,aAAa,iBAAkB,UAAU;AAAA,MAC3C;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,KAAK,QAAQ,QAAQ,QAAQ,WAAW;AAG7D,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA,QAAQ,EAAE,SAAS,OAAO,OAAO,aAAa;AAAA,QAC9C,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,eAAe,2BACb,WACA,SACe;AACf,QAAM,SAAS,kBAAkB,IAAI,QAAQ,QAAQ;AACrD,MAAI,CAAC,QAAQ;AACX,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA,QAAQ,EAAE,SAAS,OAAO,OAAO,UAAU,QAAQ,QAAQ,aAAa;AAAA,QACxE,OAAO,UAAU,QAAQ,QAAQ;AAAA,MACnC;AAAA,IACF,CAAC;AACD;AAAA,EACF;AAEA,MAAI;AAEF,UAAM,cAAgC;AAAA,MACpC,QAAQ,QAAQ;AAAA,MAChB,WAAW;AAAA,QACT,IAAI,iBAAkB,UAAU;AAAA,QAChC,SAAS,iBAAkB,UAAU;AAAA,QACrC,aAAa,iBAAkB,UAAU;AAAA,MAC3C;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,OAAO,QAAQ,QAAQ,QAAQ,WAAW;AAE/D,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA,QAAQ,EAAE,SAAS,OAAO,OAAO,aAAa;AAAA,QAC9C,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAMA,SAAS,aACP,aACA,kBACA,aACA,aACkB;AAClB,QAAM,gBAAgB,CAAC,SAA0B;AAC/C,WAAO,YAAY,KAAK,CAAC,MAAM;AAC7B,UAAI,MAAM,KAAM,QAAO;AACvB,UAAI,EAAE,SAAS,IAAI,KAAK,KAAK,WAAW,EAAE,MAAM,GAAG,EAAE,CAAC,EAAG,QAAO;AAChE,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,QAAM,MAAc;AAAA,IAClB,OAAO,CAAC,SAAS,SAAS,YAAY,EAAE,MAAM,OAAO,SAAS,EAAE,OAAO,SAAS,SAAS,KAAK,EAAE,CAAC;AAAA,IACjG,MAAM,CAAC,SAAS,SAAS,YAAY,EAAE,MAAM,OAAO,SAAS,EAAE,OAAO,QAAQ,SAAS,KAAK,EAAE,CAAC;AAAA,IAC/F,MAAM,CAAC,SAAS,SAAS,YAAY,EAAE,MAAM,OAAO,SAAS,EAAE,OAAO,QAAQ,SAAS,KAAK,EAAE,CAAC;AAAA,IAC/F,OAAO,CAAC,SAAS,SAAS,YAAY,EAAE,MAAM,OAAO,SAAS,EAAE,OAAO,SAAS,SAAS,KAAK,EAAE,CAAC;AAAA,EACnG;AAEA,QAAM,UAA4B;AAAA,IAChC,WAAW;AAAA,MACT,IAAI;AAAA,MACJ,SAAS;AAAA,MACT;AAAA,IACF;AAAA,IACA;AAAA,EACF;AAGA,MAAI,YAAY,KAAK,CAAC,MAAM,EAAE,WAAW,UAAU,CAAC,GAAG;AACrD,UAAM,aAAyB;AAAA,MAC7B,MAAM,MAAM,KAAa,SAA0C;AACjE,cAAM,SAAS,MAAM,YAAmG,iBAAiB,EAAE,KAAK,QAAQ,CAAC;AACzJ,eAAO,IAAI,SAAS,OAAO,MAAM;AAAA,UAC/B,QAAQ,OAAO;AAAA,UACf,YAAY,OAAO;AAAA,UACnB,SAAS,OAAO;AAAA,QAClB,CAAC;AAAA,MACH;AAAA,MAEA,OAAO,YAAY,KAAa,SAA8D;AAC5F,cAAM,YAAY,kBAAkB;AAGpC,cAAM,UAAiC;AAAA,UACrC,QAAQ,CAAC;AAAA,UACT,MAAM;AAAA,QACR;AACA,+BAAuB,IAAI,WAAW,OAAO;AAG7C,oBAAY;AAAA,UACV,MAAM;AAAA,UACN,IAAI;AAAA,UACJ,QAAQ;AAAA,UACR,SAAS,EAAE,KAAK,SAAS,UAAU;AAAA,QACrC,CAAC;AAED,YAAI;AAEF,iBAAO,CAAC,QAAQ,MAAM;AAEpB,kBAAM,IAAI,QAAc,CAAC,YAAY;AACnC,oBAAM,WAAW,MAAM;AAGrB,oBAAI,QAAQ,YAAY,UAAU;AAChC,0BAAQ,UAAU;AAAA,gBACpB;AACA,wBAAQ;AAAA,cACV;AAEA,sBAAQ,UAAU;AAGlB,kBAAI,QAAQ,OAAO,SAAS,KAAK,QAAQ,MAAM;AAC7C,yBAAS;AAAA,cACX;AAAA,YACF,CAAC;AAGD,gBAAI,QAAQ,OAAO;AACjB,oBAAM,IAAI,MAAM,QAAQ,KAAK;AAAA,YAC/B;AAGA,mBAAO,QAAQ,OAAO,SAAS,GAAG;AAChC,oBAAM,QAAQ,OAAO,MAAM;AAAA,YAC7B;AAAA,UACF;AAAA,QACF,UAAE;AACA,iCAAuB,OAAO,SAAS;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AACC,IAAC,QAAoC,UAAU;AAAA,EAClD;AAGA,MAAI,cAAc,mBAAmB,GAAG;AACtC,UAAM,cAA2B;AAAA,MAC/B,MAAM,SAAwD;AAC5D,eAAO,YAAe,mBAAmB,CAAC,CAAC;AAAA,MAC7C;AAAA,MACA,MAAM,IAAO,KAAqC;AAChD,eAAO,YAA2B,gBAAgB,EAAE,IAAI,CAAC;AAAA,MAC3D;AAAA,MACA,MAAM,IAAI,KAAa,OAA+B;AACpD,eAAO,YAAkB,gBAAgB,EAAE,KAAK,MAAM,CAAC;AAAA,MACzD;AAAA,MACA,SAAS,UAA6D;AACpE,0BAAkB,KAAK,QAAQ;AAC/B,eAAO;AAAA,UACL,SAAS,MAAM;AACb,kBAAM,QAAQ,kBAAkB,QAAQ,QAAQ;AAChD,gBAAI,SAAS,EAAG,mBAAkB,OAAO,OAAO,CAAC;AAAA,UACnD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACC,IAAC,QAAsC,WAAW;AAAA,EACrD;AAGA,MAAI,cAAc,mBAAmB,GAAG;AACtC,UAAM,eAA6B;AAAA,MACjC,SAAS,UAAkC;AACzC,4BAAoB,IAAI,SAAS,IAAI,QAAQ;AAC7C,oBAAY;AAAA,UACV,MAAM;AAAA,UACN,SAAS,EAAE,IAAI,SAAS,IAAI,MAAM,SAAS,KAAK;AAAA,QAClD,CAAC;AACD,eAAO;AAAA,UACL,SAAS,MAAM;AACb,gCAAoB,OAAO,SAAS,EAAE;AAAA,UACxC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACC,IAAC,QAAwC,YAAY;AAAA,EACxD;AAGA,MAAI,cAAc,gBAAgB,GAAG;AACnC,UAAM,WAAqB;AAAA,MACzB,SAAS,MAAwB;AAC/B,wBAAgB,IAAI,KAAK,IAAI,IAAI;AACjC,oBAAY;AAAA,UACV,MAAM;AAAA,UACN,SAAS;AAAA,YACP,IAAI,KAAK;AAAA,YACT,MAAM,KAAK;AAAA,YACX,aAAa,KAAK;AAAA,YAClB,YAAY,KAAK;AAAA,UACnB;AAAA,QACF,CAAC;AACD,eAAO;AAAA,UACL,SAAS,MAAM;AACb,4BAAgB,OAAO,KAAK,EAAE;AAAA,UAChC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACC,IAAC,QAAgC,QAAQ;AAAA,EAC5C;AAGA,MAAI,cAAc,kBAAkB,GAAG;AACrC,UAAM,aAAyB;AAAA,MAC7B,SAAS,QAA4B;AACnC,0BAAkB,IAAI,OAAO,IAAI,MAAM;AACvC,oBAAY;AAAA,UACV,MAAM;AAAA,UACN,SAAS;AAAA,YACP,IAAI,OAAO;AAAA,UACb;AAAA,QACF,CAAC;AACD,eAAO;AAAA,UACL,SAAS,MAAM;AACb,8BAAkB,OAAO,OAAO,EAAE;AAAA,UACpC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACC,IAAC,QAAoC,UAAU;AAAA,EAClD;AAGA,MAAI,cAAc,aAAa,GAAG;AAChC,UAAM,YAAuB;AAAA,MAC3B,MAAM,KAAK,MAAc,SAAkD;AACzE,cAAM,YAAkB,eAAe,EAAE,MAAM,QAAQ,CAAC;AAAA,MAC1D;AAAA,IACF;AACC,IAAC,QAAkC,SAAS;AAAA,EAC/C;AAGA,MAAI,cAAc,oBAAoB,GAAG;AACvC,UAAM,eAA6B;AAAA,MACjC,MAAM,SAAS,KAAyC;AAGtD,cAAM,YAAkB,sBAAsB,EAAE,IAAI,CAAC;AAAA,MACvD;AAAA,MACA,MAAM,OAAO,OAA8B;AACzC,cAAM,YAAkB,oBAAoB,EAAE,MAAM,CAAC;AAAA,MACvD;AAAA,MACA,OAAO,UAA0F;AAC/F,2BAAmB,KAAK,QAAQ;AAChC,eAAO;AAAA,UACL,SAAS,MAAM;AACb,kBAAM,QAAQ,mBAAmB,QAAQ,QAAQ;AACjD,gBAAI,SAAS,EAAG,oBAAmB,OAAO,OAAO,CAAC;AAAA,UACpD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACC,IAAC,QAAwC,YAAY;AAAA,EACxD;AAGA,MAAI,cAAc,mBAAmB,GAAG;AACtC,UAAM,UAAmB;AAAA,MACvB,MAAM,aAAmC;AACvC,eAAO,YAAyB,mBAAmB,CAAC,CAAC;AAAA,MACvD;AAAA,IACF;AACC,IAAC,QAA8B,OAAO;AAAA,EACzC;AAGA,MAAI,cAAc,oBAAoB,GAAG;AACvC,UAAM,UAAmB;AAAA,MACvB,MAAM,kBAAkB,SAAgD;AAGtE,cAAM,YAAkB,0BAA0B,OAAO;AAAA,MAC3D;AAAA,IACF;AACC,IAAC,QAA8B,OAAO;AAAA,EACzC;AAGA,MAAI,cAAc,cAAc,GAAG;AACjC,UAAM,cAA2B;AAAA,MAC/B,MAAM,QAAqB,KAAa,QAAkC;AACxE,eAAO,YAAiB,oBAAoB,EAAE,KAAK,OAAO,CAAC;AAAA,MAC7D;AAAA,IACF;AACC,IAAC,QAAsC,WAAW;AAAA,EACrD;AAGA,MAAI,cAAc,eAAe,GAAG;AAClC,UAAM,aAAyB;AAAA;AAAA,MAE7B,MAAM,IAAO,KAAqC;AAChD,eAAO,YAA2B,eAAe,EAAE,IAAI,CAAC;AAAA,MAC1D;AAAA,MACA,MAAM,IAAI,KAAa,OAA+B;AACpD,eAAO,YAAkB,eAAe,EAAE,KAAK,MAAM,CAAC;AAAA,MACxD;AAAA,MACA,MAAM,OAAO,KAA4B;AACvC,eAAO,YAAkB,kBAAkB,EAAE,IAAI,CAAC;AAAA,MACpD;AAAA,MACA,MAAM,OAA0B;AAC9B,eAAO,YAAsB,gBAAgB,CAAC,CAAC;AAAA,MACjD;AAAA;AAAA,MAEA,MAAM,WAAc,QAAgB,KAAqC;AACvE,eAAO,YAA2B,sBAAsB,EAAE,QAAQ,IAAI,CAAC;AAAA,MACzE;AAAA,MACA,MAAM,WAAW,QAAgB,KAAa,OAA+B;AAC3E,eAAO,YAAkB,sBAAsB,EAAE,QAAQ,KAAK,MAAM,CAAC;AAAA,MACvE;AAAA,MACA,MAAM,cAAc,QAAgB,KAA4B;AAC9D,eAAO,YAAkB,yBAAyB,EAAE,QAAQ,IAAI,CAAC;AAAA,MACnE;AAAA,MACA,MAAM,YAAY,QAAmC;AACnD,eAAO,YAAsB,uBAAuB,EAAE,OAAO,CAAC;AAAA,MAChE;AAAA,IACF;AACC,IAAC,QAAoC,UAAU;AAAA,EAClD;AAEA,SAAO;AACT;AAUO,SAAS,oBAAoBA,SAA+B;AACjE,oBAAkBA;AAGlB,cAAY,UAAU,OAAO,YAAiC;AAC5D,QAAI;AACF,YAAM,kBAAkB,OAAO;AAAA,IACjC,SAAS,OAAO;AACd,cAAQ,MAAM,2BAA2B,KAAK;AAAA,IAChD;AAAA,EACF,CAAC;AAGD,cAAY,EAAE,MAAM,QAAQ,CAAC;AAC/B;","names":["module"]}
@@ -1,5 +1,5 @@
1
- import { ab as ExtensionModule } from './types-CvfONPis.cjs';
2
- export { a7 as AIProvider, aa as Action, A as ActionResult, C as ChatMessage, a as ChatOptions, O as Disposable, K as ExtensionContext, G as GetModelsOptions, M as ModelInfo, b as StreamEvent, a9 as Tool, a8 as ToolCall, v as ToolDefinition, T as ToolResult } from './types-CvfONPis.cjs';
1
+ import { a3 as ExtensionModule } from './types.tools-BQrCW_wq.cjs';
2
+ export { $ as AIProvider, a2 as Action, A as ActionResult, C as ChatMessage, a as ChatOptions, D as Disposable, aB as ExecutionContext, B as ExtensionContext, G as GetModelsOptions, M as ModelInfo, b as StreamEvent, a1 as Tool, a0 as ToolCall, t as ToolDefinition, T as ToolResult } from './types.tools-BQrCW_wq.cjs';
3
3
 
4
4
  /**
5
5
  * Extension Runtime - Runs inside the worker
package/dist/runtime.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { ab as ExtensionModule } from './types-CvfONPis.js';
2
- export { a7 as AIProvider, aa as Action, A as ActionResult, C as ChatMessage, a as ChatOptions, O as Disposable, K as ExtensionContext, G as GetModelsOptions, M as ModelInfo, b as StreamEvent, a9 as Tool, a8 as ToolCall, v as ToolDefinition, T as ToolResult } from './types-CvfONPis.js';
1
+ import { a3 as ExtensionModule } from './types.tools-BQrCW_wq.js';
2
+ export { $ as AIProvider, a2 as Action, A as ActionResult, C as ChatMessage, a as ChatOptions, D as Disposable, aB as ExecutionContext, B as ExtensionContext, G as GetModelsOptions, M as ModelInfo, b as StreamEvent, a1 as Tool, a0 as ToolCall, t as ToolDefinition, T as ToolResult } from './types.tools-BQrCW_wq.js';
3
3
 
4
4
  /**
5
5
  * Extension Runtime - Runs inside the worker
package/dist/runtime.js CHANGED
@@ -167,22 +167,22 @@ function handleSettingsChanged(key, value) {
167
167
  }
168
168
  }
169
169
  async function handleSchedulerFire(payload) {
170
- if (extensionContext && payload.userId) {
171
- ;
172
- extensionContext.userId = payload.userId;
173
- }
170
+ const execContext = {
171
+ userId: payload.userId,
172
+ extension: {
173
+ id: extensionContext.extension.id,
174
+ version: extensionContext.extension.version,
175
+ storagePath: extensionContext.extension.storagePath
176
+ }
177
+ };
174
178
  const results = await Promise.allSettled(
175
- schedulerCallbacks.map((callback) => callback(payload))
179
+ schedulerCallbacks.map((callback) => callback(payload, execContext))
176
180
  );
177
181
  results.forEach((result, index) => {
178
182
  if (result.status === "rejected") {
179
183
  console.error(`Error in scheduler callback ${index}:`, result.reason);
180
184
  }
181
185
  });
182
- if (extensionContext) {
183
- ;
184
- extensionContext.userId = void 0;
185
- }
186
186
  }
187
187
  async function handleProviderChatRequest(requestId, payload) {
188
188
  const provider = registeredProviders.get(payload.providerId);
@@ -280,15 +280,15 @@ async function handleToolExecuteRequest(requestId, payload) {
280
280
  return;
281
281
  }
282
282
  try {
283
- if (extensionContext && payload.userId) {
284
- ;
285
- extensionContext.userId = payload.userId;
286
- }
287
- const result = await tool.execute(payload.params);
288
- if (extensionContext) {
289
- ;
290
- extensionContext.userId = void 0;
291
- }
283
+ const execContext = {
284
+ userId: payload.userId,
285
+ extension: {
286
+ id: extensionContext.extension.id,
287
+ version: extensionContext.extension.version,
288
+ storagePath: extensionContext.extension.storagePath
289
+ }
290
+ };
291
+ const result = await tool.execute(payload.params, execContext);
292
292
  postMessage({
293
293
  type: "tool-execute-response",
294
294
  payload: {
@@ -297,10 +297,6 @@ async function handleToolExecuteRequest(requestId, payload) {
297
297
  }
298
298
  });
299
299
  } catch (error) {
300
- if (extensionContext) {
301
- ;
302
- extensionContext.userId = void 0;
303
- }
304
300
  const errorMessage = error instanceof Error ? error.message : String(error);
305
301
  postMessage({
306
302
  type: "tool-execute-response",
@@ -326,15 +322,15 @@ async function handleActionExecuteRequest(requestId, payload) {
326
322
  return;
327
323
  }
328
324
  try {
329
- if (extensionContext && payload.userId) {
330
- ;
331
- extensionContext.userId = payload.userId;
332
- }
333
- const result = await action.execute(payload.params);
334
- if (extensionContext) {
335
- ;
336
- extensionContext.userId = void 0;
337
- }
325
+ const execContext = {
326
+ userId: payload.userId,
327
+ extension: {
328
+ id: extensionContext.extension.id,
329
+ version: extensionContext.extension.version,
330
+ storagePath: extensionContext.extension.storagePath
331
+ }
332
+ };
333
+ const result = await action.execute(payload.params, execContext);
338
334
  postMessage({
339
335
  type: "action-execute-response",
340
336
  payload: {
@@ -343,10 +339,6 @@ async function handleActionExecuteRequest(requestId, payload) {
343
339
  }
344
340
  });
345
341
  } catch (error) {
346
- if (extensionContext) {
347
- ;
348
- extensionContext.userId = void 0;
349
- }
350
342
  const errorMessage = error instanceof Error ? error.message : String(error);
351
343
  postMessage({
352
344
  type: "action-execute-response",
@@ -523,9 +515,7 @@ function buildContext(extensionId, extensionVersion, storagePath, permissions) {
523
515
  if (hasPermission("scheduler.register")) {
524
516
  const schedulerApi = {
525
517
  async schedule(job) {
526
- const userId = extensionContext.userId;
527
- const jobWithUser = userId && !job.userId ? { ...job, userId } : job;
528
- await sendRequest("scheduler.schedule", { job: jobWithUser });
518
+ await sendRequest("scheduler.schedule", { job });
529
519
  },
530
520
  async cancel(jobId) {
531
521
  await sendRequest("scheduler.cancel", { jobId });
@@ -553,11 +543,7 @@ function buildContext(extensionId, extensionVersion, storagePath, permissions) {
553
543
  if (hasPermission("chat.message.write")) {
554
544
  const chatApi = {
555
545
  async appendInstruction(message) {
556
- const contextUserId = extensionContext.userId;
557
- await sendRequest("chat.appendInstruction", {
558
- ...message,
559
- userId: message.userId ?? contextUserId
560
- });
546
+ await sendRequest("chat.appendInstruction", message);
561
547
  }
562
548
  };
563
549
  context.chat = chatApi;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["/**\n * Extension Runtime - Runs inside the worker\n *\n * This module handles communication with the Extension Host and provides\n * the ExtensionContext to the extension's activate function.\n */\n\nimport type {\n ExtensionContext,\n ExtensionModule,\n Disposable,\n NetworkAPI,\n SettingsAPI,\n ProvidersAPI,\n ToolsAPI,\n ActionsAPI,\n EventsAPI,\n SchedulerAPI,\n SchedulerJobRequest,\n SchedulerFirePayload,\n UserAPI,\n UserProfile,\n ChatAPI,\n ChatInstructionMessage,\n DatabaseAPI,\n StorageAPI,\n LogAPI,\n AIProvider,\n Tool,\n Action,\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n} from './types.js'\n\nimport type {\n HostToWorkerMessage,\n WorkerToHostMessage,\n RequestMessage,\n PendingRequest,\n} from './messages.js'\n\nimport { generateMessageId } from './messages.js'\n\n// ============================================================================\n// Environment Detection and Message Port\n// ============================================================================\n\n/**\n * Detect if we're in Node.js Worker Thread or Web Worker\n * and get the appropriate message port\n */\ninterface MessagePort {\n postMessage(message: WorkerToHostMessage): void\n onMessage(handler: (message: HostToWorkerMessage) => void): void\n}\n\nfunction getMessagePort(): MessagePort {\n // Check if we're in Node.js Worker Thread\n if (typeof process !== 'undefined' && process.versions?.node) {\n // Node.js Worker Thread - import parentPort dynamically\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { parentPort } = require('node:worker_threads')\n return {\n postMessage: (message) => parentPort?.postMessage(message),\n onMessage: (handler) => parentPort?.on('message', handler),\n }\n }\n\n // Web Worker - use self\n return {\n postMessage: (message) => self.postMessage(message),\n onMessage: (handler) => {\n self.addEventListener('message', (event: MessageEvent<HostToWorkerMessage>) => {\n handler(event.data)\n })\n },\n }\n}\n\nconst messagePort = getMessagePort()\n\n// ============================================================================\n// Global State\n// ============================================================================\n\nlet extensionModule: ExtensionModule | null = null\nlet extensionDisposable: Disposable | null = null\nlet extensionContext: ExtensionContext | null = null\n\nconst pendingRequests = new Map<string, PendingRequest>()\nconst registeredProviders = new Map<string, AIProvider>()\nconst registeredTools = new Map<string, Tool>()\nconst registeredActions = new Map<string, Action>()\nconst settingsCallbacks: Array<(key: string, value: unknown) => void> = []\nconst schedulerCallbacks: Array<(payload: SchedulerFirePayload) => void | Promise<void>> = []\n\n/**\n * Tracking for streaming fetch requests.\n * Each request stores incoming chunks and signals when new data arrives.\n */\ninterface StreamingFetchRequest {\n chunks: string[]\n done: boolean\n error?: string\n resolve?: () => void\n}\nconst streamingFetchRequests = new Map<string, StreamingFetchRequest>()\n\nconst REQUEST_TIMEOUT = 30000 // 30 seconds\n\n// ============================================================================\n// Message Handling\n// ============================================================================\n\n/**\n * Send a message to the host\n */\nfunction postMessage(message: WorkerToHostMessage): void {\n messagePort.postMessage(message)\n}\n\n/**\n * Send a request to the host and wait for response\n */\nasync function sendRequest<T>(method: RequestMessage['method'], payload: unknown): Promise<T> {\n const id = generateMessageId()\n\n return new Promise<T>((resolve, reject) => {\n const timeout = setTimeout(() => {\n pendingRequests.delete(id)\n reject(new Error(`Request ${method} timed out`))\n }, REQUEST_TIMEOUT)\n\n pendingRequests.set(id, { resolve: resolve as (value: unknown) => void, reject, timeout })\n\n postMessage({\n type: 'request',\n id,\n method,\n payload,\n })\n })\n}\n\n/**\n * Handle messages from the host\n */\nasync function handleHostMessage(message: HostToWorkerMessage): Promise<void> {\n switch (message.type) {\n case 'activate':\n await handleActivate(message.payload)\n break\n\n case 'deactivate':\n await handleDeactivate()\n break\n\n case 'settings-changed':\n handleSettingsChanged(message.payload.key, message.payload.value)\n break\n\n case 'scheduler-fire':\n await handleSchedulerFire(message.payload)\n break\n\n case 'provider-chat-request':\n await handleProviderChatRequest(message.id, message.payload)\n break\n\n case 'provider-models-request':\n await handleProviderModelsRequest(message.id, message.payload)\n break\n\n case 'tool-execute-request':\n await handleToolExecuteRequest(message.id, message.payload)\n break\n\n case 'action-execute-request':\n await handleActionExecuteRequest(message.id, message.payload)\n break\n\n case 'response':\n handleResponse(message.payload)\n break\n\n case 'streaming-fetch-chunk':\n handleStreamingFetchChunk(message.payload)\n break\n }\n}\n\n/**\n * Handle incoming streaming fetch chunks from the host\n */\nfunction handleStreamingFetchChunk(payload: {\n requestId: string\n chunk: string\n done: boolean\n error?: string\n}): void {\n const request = streamingFetchRequests.get(payload.requestId)\n if (!request) return\n\n if (payload.error) {\n request.error = payload.error\n request.done = true\n } else if (payload.chunk) {\n request.chunks.push(payload.chunk)\n }\n\n if (payload.done) {\n request.done = true\n }\n\n // Signal that new data is available\n if (request.resolve) {\n const resolve = request.resolve\n request.resolve = undefined\n resolve()\n }\n\n // Send acknowledgment for backpressure control\n postMessage({\n type: 'streaming-fetch-ack',\n payload: { requestId: payload.requestId },\n })\n}\n\nfunction handleResponse(payload: { requestId: string; success: boolean; data?: unknown; error?: string }): void {\n const pending = pendingRequests.get(payload.requestId)\n if (!pending) return\n\n clearTimeout(pending.timeout)\n pendingRequests.delete(payload.requestId)\n\n if (payload.success) {\n pending.resolve(payload.data)\n } else {\n pending.reject(new Error(payload.error || 'Unknown error'))\n }\n}\n\n// ============================================================================\n// Activation / Deactivation\n// ============================================================================\n\nasync function handleActivate(payload: {\n extensionId: string\n extensionVersion: string\n storagePath: string\n permissions: string[]\n settings: Record<string, unknown>\n}): Promise<void> {\n const { extensionId, extensionVersion, storagePath, permissions } = payload\n\n // Build the context based on permissions\n extensionContext = buildContext(extensionId, extensionVersion, storagePath, permissions)\n\n // Import and activate the extension\n try {\n // The actual extension code should be bundled and available\n // This is called after the extension code has been loaded into the worker\n if (extensionModule?.activate) {\n const result = await extensionModule.activate(extensionContext)\n if (result && 'dispose' in result) {\n extensionDisposable = result\n }\n }\n } catch (error) {\n extensionContext.log.error('Failed to activate extension', {\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n}\n\nasync function handleDeactivate(): Promise<void> {\n try {\n if (extensionModule?.deactivate) {\n await extensionModule.deactivate()\n }\n if (extensionDisposable) {\n extensionDisposable.dispose()\n }\n } catch (error) {\n console.error('Error during deactivation:', error)\n } finally {\n extensionModule = null\n extensionDisposable = null\n extensionContext = null\n registeredProviders.clear()\n registeredTools.clear()\n registeredActions.clear()\n settingsCallbacks.length = 0\n schedulerCallbacks.length = 0\n }\n}\n\nfunction handleSettingsChanged(key: string, value: unknown): void {\n for (const callback of settingsCallbacks) {\n try {\n callback(key, value)\n } catch (error) {\n console.error('Error in settings change callback:', error)\n }\n }\n}\n\nasync function handleSchedulerFire(payload: SchedulerFirePayload): Promise<void> {\n // Set the userId in context if this is a user-scoped job\n if (extensionContext && payload.userId) {\n ;(extensionContext as { userId?: string }).userId = payload.userId\n }\n\n // Run callbacks concurrently to avoid blocking\n const results = await Promise.allSettled(\n schedulerCallbacks.map((callback) => callback(payload)),\n )\n\n // Log any errors\n results.forEach((result, index) => {\n if (result.status === 'rejected') {\n console.error(`Error in scheduler callback ${index}:`, result.reason)\n }\n })\n\n // Reset userId after all callbacks have completed\n if (extensionContext) {\n ;(extensionContext as { userId?: string }).userId = undefined\n }\n}\n\n// ============================================================================\n// Provider / Tool Requests\n// ============================================================================\n\nasync function handleProviderChatRequest(\n requestId: string,\n payload: { providerId: string; messages: ChatMessage[]; options: ChatOptions }\n): Promise<void> {\n const provider = registeredProviders.get(payload.providerId)\n if (!provider) {\n postMessage({\n type: 'request',\n id: generateMessageId(),\n method: 'network.fetch', // Dummy, we need a proper error response\n payload: { error: `Provider ${payload.providerId} not found` },\n })\n return\n }\n\n try {\n const generator = provider.chat(payload.messages, payload.options)\n let sawDone = false\n let sawError = false\n\n for await (const event of generator) {\n if (event.type === 'done') {\n sawDone = true\n } else if (event.type === 'error') {\n sawError = true\n }\n postMessage({\n type: 'stream-event',\n payload: { requestId, event },\n })\n }\n\n if (!sawDone && !sawError) {\n postMessage({\n type: 'stream-event',\n payload: {\n requestId,\n event: { type: 'done' },\n },\n })\n }\n } catch (error) {\n postMessage({\n type: 'stream-event',\n payload: {\n requestId,\n event: {\n type: 'error',\n message: error instanceof Error ? error.message : String(error),\n },\n },\n })\n }\n}\n\nasync function handleProviderModelsRequest(\n requestId: string,\n payload: { providerId: string; options?: GetModelsOptions }\n): Promise<void> {\n const provider = registeredProviders.get(payload.providerId)\n if (!provider) {\n // Send error response\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models: [],\n error: `Provider ${payload.providerId} not found`,\n },\n })\n return\n }\n\n try {\n // Pass options to getModels so provider can use settings (e.g., URL for Ollama)\n const models = await provider.getModels(payload.options)\n // Send response with models\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models,\n },\n })\n } catch (error) {\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models: [],\n error: error instanceof Error ? error.message : String(error),\n },\n })\n }\n}\n\nasync function handleToolExecuteRequest(\n requestId: string,\n payload: { toolId: string; params: Record<string, unknown>; userId?: string }\n): Promise<void> {\n const tool = registeredTools.get(payload.toolId)\n if (!tool) {\n // Send error response\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result: { success: false, error: `Tool ${payload.toolId} not found` },\n error: `Tool ${payload.toolId} not found`,\n },\n })\n return\n }\n\n try {\n // Update the extension context with the userId if provided\n if (extensionContext && payload.userId) {\n // Create a new context with the userId for this execution\n ;(extensionContext as { userId?: string }).userId = payload.userId\n }\n\n const result = await tool.execute(payload.params)\n\n // Reset userId after execution\n if (extensionContext) {\n ;(extensionContext as { userId?: string }).userId = undefined\n }\n\n // Send response with result\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result,\n },\n })\n } catch (error) {\n // Reset userId on error\n if (extensionContext) {\n ;(extensionContext as { userId?: string }).userId = undefined\n }\n\n const errorMessage = error instanceof Error ? error.message : String(error)\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result: { success: false, error: errorMessage },\n error: errorMessage,\n },\n })\n }\n}\n\nasync function handleActionExecuteRequest(\n requestId: string,\n payload: { actionId: string; params: Record<string, unknown>; userId?: string }\n): Promise<void> {\n const action = registeredActions.get(payload.actionId)\n if (!action) {\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result: { success: false, error: `Action ${payload.actionId} not found` },\n error: `Action ${payload.actionId} not found`,\n },\n })\n return\n }\n\n try {\n // Update the extension context with the userId if provided\n if (extensionContext && payload.userId) {\n ;(extensionContext as { userId?: string }).userId = payload.userId\n }\n\n const result = await action.execute(payload.params)\n\n // Reset userId after execution\n if (extensionContext) {\n ;(extensionContext as { userId?: string }).userId = undefined\n }\n\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result,\n },\n })\n } catch (error) {\n // Reset userId on error\n if (extensionContext) {\n ;(extensionContext as { userId?: string }).userId = undefined\n }\n\n const errorMessage = error instanceof Error ? error.message : String(error)\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result: { success: false, error: errorMessage },\n error: errorMessage,\n },\n })\n }\n}\n\n// ============================================================================\n// Context Building\n// ============================================================================\n\nfunction buildContext(\n extensionId: string,\n extensionVersion: string,\n storagePath: string,\n permissions: string[]\n): ExtensionContext {\n const hasPermission = (perm: string): boolean => {\n return permissions.some((p) => {\n if (p === perm) return true\n if (p.endsWith(':*') && perm.startsWith(p.slice(0, -1))) return true\n return false\n })\n }\n\n const log: LogAPI = {\n debug: (message, data) => postMessage({ type: 'log', payload: { level: 'debug', message, data } }),\n info: (message, data) => postMessage({ type: 'log', payload: { level: 'info', message, data } }),\n warn: (message, data) => postMessage({ type: 'log', payload: { level: 'warn', message, data } }),\n error: (message, data) => postMessage({ type: 'log', payload: { level: 'error', message, data } }),\n }\n\n const context: ExtensionContext = {\n extension: {\n id: extensionId,\n version: extensionVersion,\n storagePath,\n },\n log,\n }\n\n // Add network API if permitted\n if (permissions.some((p) => p.startsWith('network:'))) {\n const networkApi: NetworkAPI = {\n async fetch(url: string, options?: RequestInit): Promise<Response> {\n const result = await sendRequest<{ status: number; statusText: string; headers: Record<string, string>; body: string }>('network.fetch', { url, options })\n return new Response(result.body, {\n status: result.status,\n statusText: result.statusText,\n headers: result.headers,\n })\n },\n\n async *fetchStream(url: string, options?: RequestInit): AsyncGenerator<string, void, unknown> {\n const requestId = generateMessageId()\n\n // Set up streaming request tracking\n const request: StreamingFetchRequest = {\n chunks: [],\n done: false,\n }\n streamingFetchRequests.set(requestId, request)\n\n // Send the streaming fetch request to the host\n postMessage({\n type: 'request',\n id: requestId,\n method: 'network.fetch-stream',\n payload: { url, options, requestId },\n })\n\n try {\n // Yield chunks as they arrive\n while (!request.done) {\n // Wait for new data\n await new Promise<void>((resolve) => {\n const resolver = () => {\n // Clear the stored resolver before resolving to avoid\n // stale callbacks being invoked for a new wait iteration.\n if (request.resolve === resolver) {\n request.resolve = undefined\n }\n resolve()\n }\n\n request.resolve = resolver\n\n // Check if we already have data or completion\n if (request.chunks.length > 0 || request.done) {\n resolver()\n }\n })\n\n // Check for errors first, before yielding any chunks\n if (request.error) {\n throw new Error(request.error)\n }\n\n // Yield all available chunks\n while (request.chunks.length > 0) {\n yield request.chunks.shift()!\n }\n }\n } finally {\n streamingFetchRequests.delete(requestId)\n }\n },\n }\n ;(context as { network: NetworkAPI }).network = networkApi\n }\n\n // Add settings API if permitted\n if (hasPermission('settings.register')) {\n const settingsApi: SettingsAPI = {\n async getAll<T extends Record<string, unknown>>(): Promise<T> {\n return sendRequest<T>('settings.getAll', {})\n },\n async get<T>(key: string): Promise<T | undefined> {\n return sendRequest<T | undefined>('settings.get', { key })\n },\n async set(key: string, value: unknown): Promise<void> {\n return sendRequest<void>('settings.set', { key, value })\n },\n onChange(callback: (key: string, value: unknown) => void): Disposable {\n settingsCallbacks.push(callback)\n return {\n dispose: () => {\n const index = settingsCallbacks.indexOf(callback)\n if (index >= 0) settingsCallbacks.splice(index, 1)\n },\n }\n },\n }\n ;(context as { settings: SettingsAPI }).settings = settingsApi\n }\n\n // Add providers API if permitted\n if (hasPermission('provider.register')) {\n const providersApi: ProvidersAPI = {\n register(provider: AIProvider): Disposable {\n registeredProviders.set(provider.id, provider)\n postMessage({\n type: 'provider-registered',\n payload: { id: provider.id, name: provider.name },\n })\n return {\n dispose: () => {\n registeredProviders.delete(provider.id)\n },\n }\n },\n }\n ;(context as { providers: ProvidersAPI }).providers = providersApi\n }\n\n // Add tools API if permitted\n if (hasPermission('tools.register')) {\n const toolsApi: ToolsAPI = {\n register(tool: Tool): Disposable {\n registeredTools.set(tool.id, tool)\n postMessage({\n type: 'tool-registered',\n payload: {\n id: tool.id,\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n },\n })\n return {\n dispose: () => {\n registeredTools.delete(tool.id)\n },\n }\n },\n }\n ;(context as { tools: ToolsAPI }).tools = toolsApi\n }\n\n // Add actions API if permitted\n if (hasPermission('actions.register')) {\n const actionsApi: ActionsAPI = {\n register(action: Action): Disposable {\n registeredActions.set(action.id, action)\n postMessage({\n type: 'action-registered',\n payload: {\n id: action.id,\n },\n })\n return {\n dispose: () => {\n registeredActions.delete(action.id)\n },\n }\n },\n }\n ;(context as { actions: ActionsAPI }).actions = actionsApi\n }\n\n // Add events API if permitted\n if (hasPermission('events.emit')) {\n const eventsApi: EventsAPI = {\n async emit(name: string, payload?: Record<string, unknown>): Promise<void> {\n await sendRequest<void>('events.emit', { name, payload })\n },\n }\n ;(context as { events: EventsAPI }).events = eventsApi\n }\n\n // Add scheduler API if permitted\n if (hasPermission('scheduler.register')) {\n const schedulerApi: SchedulerAPI = {\n async schedule(job: SchedulerJobRequest): Promise<void> {\n // Automatically include userId from context if not explicitly set\n const userId = (extensionContext as { userId?: string }).userId\n const jobWithUser = userId && !job.userId ? { ...job, userId } : job\n await sendRequest<void>('scheduler.schedule', { job: jobWithUser })\n },\n async cancel(jobId: string): Promise<void> {\n await sendRequest<void>('scheduler.cancel', { jobId })\n },\n onFire(callback: (payload: SchedulerFirePayload) => void): Disposable {\n schedulerCallbacks.push(callback)\n return {\n dispose: () => {\n const index = schedulerCallbacks.indexOf(callback)\n if (index >= 0) schedulerCallbacks.splice(index, 1)\n },\n }\n },\n }\n ;(context as { scheduler: SchedulerAPI }).scheduler = schedulerApi\n }\n\n // Add user profile API if permitted\n if (hasPermission('user.profile.read')) {\n const userApi: UserAPI = {\n async getProfile(): Promise<UserProfile> {\n return sendRequest<UserProfile>('user.getProfile', {})\n },\n }\n ;(context as { user: UserAPI }).user = userApi\n }\n\n // Add chat API if permitted\n if (hasPermission('chat.message.write')) {\n const chatApi: ChatAPI = {\n async appendInstruction(message: ChatInstructionMessage): Promise<void> {\n const contextUserId = (extensionContext as { userId?: string }).userId\n await sendRequest<void>('chat.appendInstruction', {\n ...message,\n userId: message.userId ?? contextUserId,\n })\n },\n }\n ;(context as { chat: ChatAPI }).chat = chatApi\n }\n\n // Add database API if permitted\n if (hasPermission('database.own')) {\n const databaseApi: DatabaseAPI = {\n async execute<T = unknown>(sql: string, params?: unknown[]): Promise<T[]> {\n return sendRequest<T[]>('database.execute', { sql, params })\n },\n }\n ;(context as { database: DatabaseAPI }).database = databaseApi\n }\n\n // Add storage API if permitted\n if (hasPermission('storage.local')) {\n const storageApi: StorageAPI = {\n // Global/extension-scoped storage\n async get<T>(key: string): Promise<T | undefined> {\n return sendRequest<T | undefined>('storage.get', { key })\n },\n async set(key: string, value: unknown): Promise<void> {\n return sendRequest<void>('storage.set', { key, value })\n },\n async delete(key: string): Promise<void> {\n return sendRequest<void>('storage.delete', { key })\n },\n async keys(): Promise<string[]> {\n return sendRequest<string[]>('storage.keys', {})\n },\n // User-scoped storage\n async getForUser<T>(userId: string, key: string): Promise<T | undefined> {\n return sendRequest<T | undefined>('storage.getForUser', { userId, key })\n },\n async setForUser(userId: string, key: string, value: unknown): Promise<void> {\n return sendRequest<void>('storage.setForUser', { userId, key, value })\n },\n async deleteForUser(userId: string, key: string): Promise<void> {\n return sendRequest<void>('storage.deleteForUser', { userId, key })\n },\n async keysForUser(userId: string): Promise<string[]> {\n return sendRequest<string[]>('storage.keysForUser', { userId })\n },\n }\n ;(context as { storage: StorageAPI }).storage = storageApi\n }\n\n return context\n}\n\n// ============================================================================\n// Initialization\n// ============================================================================\n\n/**\n * Initialize the extension runtime\n * This should be called by the extension's entry point\n */\nexport function initializeExtension(module: ExtensionModule): void {\n extensionModule = module\n\n // Set up message listener using the appropriate message port\n messagePort.onMessage(async (message: HostToWorkerMessage) => {\n try {\n await handleHostMessage(message)\n } catch (error) {\n console.error('Error handling message:', error)\n }\n })\n\n // Signal that we're ready\n postMessage({ type: 'ready' })\n}\n\n// Re-export types for extensions to use\nexport type {\n ExtensionContext,\n ExtensionModule,\n Disposable,\n AIProvider,\n Tool,\n ToolDefinition,\n ToolResult,\n ToolCall,\n Action,\n ActionResult,\n ModelInfo,\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n} from './types.js'\n"],"mappings":";;;;;;AAyDA,SAAS,iBAA8B;AAErC,MAAI,OAAO,YAAY,eAAe,QAAQ,UAAU,MAAM;AAG5D,UAAM,EAAE,WAAW,IAAI,UAAQ,gBAAqB;AACpD,WAAO;AAAA,MACL,aAAa,CAAC,YAAY,YAAY,YAAY,OAAO;AAAA,MACzD,WAAW,CAAC,YAAY,YAAY,GAAG,WAAW,OAAO;AAAA,IAC3D;AAAA,EACF;AAGA,SAAO;AAAA,IACL,aAAa,CAAC,YAAY,KAAK,YAAY,OAAO;AAAA,IAClD,WAAW,CAAC,YAAY;AACtB,WAAK,iBAAiB,WAAW,CAAC,UAA6C;AAC7E,gBAAQ,MAAM,IAAI;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,IAAM,cAAc,eAAe;AAMnC,IAAI,kBAA0C;AAC9C,IAAI,sBAAyC;AAC7C,IAAI,mBAA4C;AAEhD,IAAM,kBAAkB,oBAAI,IAA4B;AACxD,IAAM,sBAAsB,oBAAI,IAAwB;AACxD,IAAM,kBAAkB,oBAAI,IAAkB;AAC9C,IAAM,oBAAoB,oBAAI,IAAoB;AAClD,IAAM,oBAAkE,CAAC;AACzE,IAAM,qBAAqF,CAAC;AAY5F,IAAM,yBAAyB,oBAAI,IAAmC;AAEtE,IAAM,kBAAkB;AASxB,SAAS,YAAY,SAAoC;AACvD,cAAY,YAAY,OAAO;AACjC;AAKA,eAAe,YAAe,QAAkC,SAA8B;AAC5F,QAAM,KAAK,kBAAkB;AAE7B,SAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AACzC,UAAM,UAAU,WAAW,MAAM;AAC/B,sBAAgB,OAAO,EAAE;AACzB,aAAO,IAAI,MAAM,WAAW,MAAM,YAAY,CAAC;AAAA,IACjD,GAAG,eAAe;AAElB,oBAAgB,IAAI,IAAI,EAAE,SAA8C,QAAQ,QAAQ,CAAC;AAEzF,gBAAY;AAAA,MACV,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;AAKA,eAAe,kBAAkB,SAA6C;AAC5E,UAAQ,QAAQ,MAAM;AAAA,IACpB,KAAK;AACH,YAAM,eAAe,QAAQ,OAAO;AACpC;AAAA,IAEF,KAAK;AACH,YAAM,iBAAiB;AACvB;AAAA,IAEF,KAAK;AACH,4BAAsB,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,KAAK;AAChE;AAAA,IAEF,KAAK;AACH,YAAM,oBAAoB,QAAQ,OAAO;AACzC;AAAA,IAEF,KAAK;AACH,YAAM,0BAA0B,QAAQ,IAAI,QAAQ,OAAO;AAC3D;AAAA,IAEF,KAAK;AACH,YAAM,4BAA4B,QAAQ,IAAI,QAAQ,OAAO;AAC7D;AAAA,IAEF,KAAK;AACH,YAAM,yBAAyB,QAAQ,IAAI,QAAQ,OAAO;AAC1D;AAAA,IAEF,KAAK;AACH,YAAM,2BAA2B,QAAQ,IAAI,QAAQ,OAAO;AAC5D;AAAA,IAEF,KAAK;AACH,qBAAe,QAAQ,OAAO;AAC9B;AAAA,IAEF,KAAK;AACH,gCAA0B,QAAQ,OAAO;AACzC;AAAA,EACJ;AACF;AAKA,SAAS,0BAA0B,SAK1B;AACP,QAAM,UAAU,uBAAuB,IAAI,QAAQ,SAAS;AAC5D,MAAI,CAAC,QAAS;AAEd,MAAI,QAAQ,OAAO;AACjB,YAAQ,QAAQ,QAAQ;AACxB,YAAQ,OAAO;AAAA,EACjB,WAAW,QAAQ,OAAO;AACxB,YAAQ,OAAO,KAAK,QAAQ,KAAK;AAAA,EACnC;AAEA,MAAI,QAAQ,MAAM;AAChB,YAAQ,OAAO;AAAA,EACjB;AAGA,MAAI,QAAQ,SAAS;AACnB,UAAM,UAAU,QAAQ;AACxB,YAAQ,UAAU;AAClB,YAAQ;AAAA,EACV;AAGA,cAAY;AAAA,IACV,MAAM;AAAA,IACN,SAAS,EAAE,WAAW,QAAQ,UAAU;AAAA,EAC1C,CAAC;AACH;AAEA,SAAS,eAAe,SAAwF;AAC9G,QAAM,UAAU,gBAAgB,IAAI,QAAQ,SAAS;AACrD,MAAI,CAAC,QAAS;AAEd,eAAa,QAAQ,OAAO;AAC5B,kBAAgB,OAAO,QAAQ,SAAS;AAExC,MAAI,QAAQ,SAAS;AACnB,YAAQ,QAAQ,QAAQ,IAAI;AAAA,EAC9B,OAAO;AACL,YAAQ,OAAO,IAAI,MAAM,QAAQ,SAAS,eAAe,CAAC;AAAA,EAC5D;AACF;AAMA,eAAe,eAAe,SAMZ;AAChB,QAAM,EAAE,aAAa,kBAAkB,aAAa,YAAY,IAAI;AAGpE,qBAAmB,aAAa,aAAa,kBAAkB,aAAa,WAAW;AAGvF,MAAI;AAGF,QAAI,iBAAiB,UAAU;AAC7B,YAAM,SAAS,MAAM,gBAAgB,SAAS,gBAAgB;AAC9D,UAAI,UAAU,aAAa,QAAQ;AACjC,8BAAsB;AAAA,MACxB;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,qBAAiB,IAAI,MAAM,gCAAgC;AAAA,MACzD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IAC9D,CAAC;AACD,UAAM;AAAA,EACR;AACF;AAEA,eAAe,mBAAkC;AAC/C,MAAI;AACF,QAAI,iBAAiB,YAAY;AAC/B,YAAM,gBAAgB,WAAW;AAAA,IACnC;AACA,QAAI,qBAAqB;AACvB,0BAAoB,QAAQ;AAAA,IAC9B;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,8BAA8B,KAAK;AAAA,EACnD,UAAE;AACA,sBAAkB;AAClB,0BAAsB;AACtB,uBAAmB;AACnB,wBAAoB,MAAM;AAC1B,oBAAgB,MAAM;AACtB,sBAAkB,MAAM;AACxB,sBAAkB,SAAS;AAC3B,uBAAmB,SAAS;AAAA,EAC9B;AACF;AAEA,SAAS,sBAAsB,KAAa,OAAsB;AAChE,aAAW,YAAY,mBAAmB;AACxC,QAAI;AACF,eAAS,KAAK,KAAK;AAAA,IACrB,SAAS,OAAO;AACd,cAAQ,MAAM,sCAAsC,KAAK;AAAA,IAC3D;AAAA,EACF;AACF;AAEA,eAAe,oBAAoB,SAA8C;AAE/E,MAAI,oBAAoB,QAAQ,QAAQ;AACtC;AAAC,IAAC,iBAAyC,SAAS,QAAQ;AAAA,EAC9D;AAGA,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,mBAAmB,IAAI,CAAC,aAAa,SAAS,OAAO,CAAC;AAAA,EACxD;AAGA,UAAQ,QAAQ,CAAC,QAAQ,UAAU;AACjC,QAAI,OAAO,WAAW,YAAY;AAChC,cAAQ,MAAM,+BAA+B,KAAK,KAAK,OAAO,MAAM;AAAA,IACtE;AAAA,EACF,CAAC;AAGD,MAAI,kBAAkB;AACpB;AAAC,IAAC,iBAAyC,SAAS;AAAA,EACtD;AACF;AAMA,eAAe,0BACb,WACA,SACe;AACf,QAAM,WAAW,oBAAoB,IAAI,QAAQ,UAAU;AAC3D,MAAI,CAAC,UAAU;AACb,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,IAAI,kBAAkB;AAAA,MACtB,QAAQ;AAAA;AAAA,MACR,SAAS,EAAE,OAAO,YAAY,QAAQ,UAAU,aAAa;AAAA,IAC/D,CAAC;AACD;AAAA,EACF;AAEA,MAAI;AACF,UAAM,YAAY,SAAS,KAAK,QAAQ,UAAU,QAAQ,OAAO;AACjE,QAAI,UAAU;AACd,QAAI,WAAW;AAEf,qBAAiB,SAAS,WAAW;AACnC,UAAI,MAAM,SAAS,QAAQ;AACzB,kBAAU;AAAA,MACZ,WAAW,MAAM,SAAS,SAAS;AACjC,mBAAW;AAAA,MACb;AACA,kBAAY;AAAA,QACV,MAAM;AAAA,QACN,SAAS,EAAE,WAAW,MAAM;AAAA,MAC9B,CAAC;AAAA,IACH;AAEA,QAAI,CAAC,WAAW,CAAC,UAAU;AACzB,kBAAY;AAAA,QACV,MAAM;AAAA,QACN,SAAS;AAAA,UACP;AAAA,UACA,OAAO,EAAE,MAAM,OAAO;AAAA,QACxB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,SAAS,OAAO;AACd,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAChE;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,eAAe,4BACb,WACA,SACe;AACf,QAAM,WAAW,oBAAoB,IAAI,QAAQ,UAAU;AAC3D,MAAI,CAAC,UAAU;AAEb,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA,QAAQ,CAAC;AAAA,QACT,OAAO,YAAY,QAAQ,UAAU;AAAA,MACvC;AAAA,IACF,CAAC;AACD;AAAA,EACF;AAEA,MAAI;AAEF,UAAM,SAAS,MAAM,SAAS,UAAU,QAAQ,OAAO;AAEvD,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,SAAS,OAAO;AACd,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA,QAAQ,CAAC;AAAA,QACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAC9D;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,eAAe,yBACb,WACA,SACe;AACf,QAAM,OAAO,gBAAgB,IAAI,QAAQ,MAAM;AAC/C,MAAI,CAAC,MAAM;AAET,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA,QAAQ,EAAE,SAAS,OAAO,OAAO,QAAQ,QAAQ,MAAM,aAAa;AAAA,QACpE,OAAO,QAAQ,QAAQ,MAAM;AAAA,MAC/B;AAAA,IACF,CAAC;AACD;AAAA,EACF;AAEA,MAAI;AAEF,QAAI,oBAAoB,QAAQ,QAAQ;AAEtC;AAAC,MAAC,iBAAyC,SAAS,QAAQ;AAAA,IAC9D;AAEA,UAAM,SAAS,MAAM,KAAK,QAAQ,QAAQ,MAAM;AAGhD,QAAI,kBAAkB;AACpB;AAAC,MAAC,iBAAyC,SAAS;AAAA,IACtD;AAGA,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,SAAS,OAAO;AAEd,QAAI,kBAAkB;AACpB;AAAC,MAAC,iBAAyC,SAAS;AAAA,IACtD;AAEA,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA,QAAQ,EAAE,SAAS,OAAO,OAAO,aAAa;AAAA,QAC9C,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,eAAe,2BACb,WACA,SACe;AACf,QAAM,SAAS,kBAAkB,IAAI,QAAQ,QAAQ;AACrD,MAAI,CAAC,QAAQ;AACX,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA,QAAQ,EAAE,SAAS,OAAO,OAAO,UAAU,QAAQ,QAAQ,aAAa;AAAA,QACxE,OAAO,UAAU,QAAQ,QAAQ;AAAA,MACnC;AAAA,IACF,CAAC;AACD;AAAA,EACF;AAEA,MAAI;AAEF,QAAI,oBAAoB,QAAQ,QAAQ;AACtC;AAAC,MAAC,iBAAyC,SAAS,QAAQ;AAAA,IAC9D;AAEA,UAAM,SAAS,MAAM,OAAO,QAAQ,QAAQ,MAAM;AAGlD,QAAI,kBAAkB;AACpB;AAAC,MAAC,iBAAyC,SAAS;AAAA,IACtD;AAEA,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,SAAS,OAAO;AAEd,QAAI,kBAAkB;AACpB;AAAC,MAAC,iBAAyC,SAAS;AAAA,IACtD;AAEA,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,gBAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,QACP;AAAA,QACA,QAAQ,EAAE,SAAS,OAAO,OAAO,aAAa;AAAA,QAC9C,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAMA,SAAS,aACP,aACA,kBACA,aACA,aACkB;AAClB,QAAM,gBAAgB,CAAC,SAA0B;AAC/C,WAAO,YAAY,KAAK,CAAC,MAAM;AAC7B,UAAI,MAAM,KAAM,QAAO;AACvB,UAAI,EAAE,SAAS,IAAI,KAAK,KAAK,WAAW,EAAE,MAAM,GAAG,EAAE,CAAC,EAAG,QAAO;AAChE,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,QAAM,MAAc;AAAA,IAClB,OAAO,CAAC,SAAS,SAAS,YAAY,EAAE,MAAM,OAAO,SAAS,EAAE,OAAO,SAAS,SAAS,KAAK,EAAE,CAAC;AAAA,IACjG,MAAM,CAAC,SAAS,SAAS,YAAY,EAAE,MAAM,OAAO,SAAS,EAAE,OAAO,QAAQ,SAAS,KAAK,EAAE,CAAC;AAAA,IAC/F,MAAM,CAAC,SAAS,SAAS,YAAY,EAAE,MAAM,OAAO,SAAS,EAAE,OAAO,QAAQ,SAAS,KAAK,EAAE,CAAC;AAAA,IAC/F,OAAO,CAAC,SAAS,SAAS,YAAY,EAAE,MAAM,OAAO,SAAS,EAAE,OAAO,SAAS,SAAS,KAAK,EAAE,CAAC;AAAA,EACnG;AAEA,QAAM,UAA4B;AAAA,IAChC,WAAW;AAAA,MACT,IAAI;AAAA,MACJ,SAAS;AAAA,MACT;AAAA,IACF;AAAA,IACA;AAAA,EACF;AAGA,MAAI,YAAY,KAAK,CAAC,MAAM,EAAE,WAAW,UAAU,CAAC,GAAG;AACrD,UAAM,aAAyB;AAAA,MAC7B,MAAM,MAAM,KAAa,SAA0C;AACjE,cAAM,SAAS,MAAM,YAAmG,iBAAiB,EAAE,KAAK,QAAQ,CAAC;AACzJ,eAAO,IAAI,SAAS,OAAO,MAAM;AAAA,UAC/B,QAAQ,OAAO;AAAA,UACf,YAAY,OAAO;AAAA,UACnB,SAAS,OAAO;AAAA,QAClB,CAAC;AAAA,MACH;AAAA,MAEA,OAAO,YAAY,KAAa,SAA8D;AAC5F,cAAM,YAAY,kBAAkB;AAGpC,cAAM,UAAiC;AAAA,UACrC,QAAQ,CAAC;AAAA,UACT,MAAM;AAAA,QACR;AACA,+BAAuB,IAAI,WAAW,OAAO;AAG7C,oBAAY;AAAA,UACV,MAAM;AAAA,UACN,IAAI;AAAA,UACJ,QAAQ;AAAA,UACR,SAAS,EAAE,KAAK,SAAS,UAAU;AAAA,QACrC,CAAC;AAED,YAAI;AAEF,iBAAO,CAAC,QAAQ,MAAM;AAEpB,kBAAM,IAAI,QAAc,CAAC,YAAY;AACnC,oBAAM,WAAW,MAAM;AAGrB,oBAAI,QAAQ,YAAY,UAAU;AAChC,0BAAQ,UAAU;AAAA,gBACpB;AACA,wBAAQ;AAAA,cACV;AAEA,sBAAQ,UAAU;AAGlB,kBAAI,QAAQ,OAAO,SAAS,KAAK,QAAQ,MAAM;AAC7C,yBAAS;AAAA,cACX;AAAA,YACF,CAAC;AAGD,gBAAI,QAAQ,OAAO;AACjB,oBAAM,IAAI,MAAM,QAAQ,KAAK;AAAA,YAC/B;AAGA,mBAAO,QAAQ,OAAO,SAAS,GAAG;AAChC,oBAAM,QAAQ,OAAO,MAAM;AAAA,YAC7B;AAAA,UACF;AAAA,QACF,UAAE;AACA,iCAAuB,OAAO,SAAS;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AACC,IAAC,QAAoC,UAAU;AAAA,EAClD;AAGA,MAAI,cAAc,mBAAmB,GAAG;AACtC,UAAM,cAA2B;AAAA,MAC/B,MAAM,SAAwD;AAC5D,eAAO,YAAe,mBAAmB,CAAC,CAAC;AAAA,MAC7C;AAAA,MACA,MAAM,IAAO,KAAqC;AAChD,eAAO,YAA2B,gBAAgB,EAAE,IAAI,CAAC;AAAA,MAC3D;AAAA,MACA,MAAM,IAAI,KAAa,OAA+B;AACpD,eAAO,YAAkB,gBAAgB,EAAE,KAAK,MAAM,CAAC;AAAA,MACzD;AAAA,MACA,SAAS,UAA6D;AACpE,0BAAkB,KAAK,QAAQ;AAC/B,eAAO;AAAA,UACL,SAAS,MAAM;AACb,kBAAM,QAAQ,kBAAkB,QAAQ,QAAQ;AAChD,gBAAI,SAAS,EAAG,mBAAkB,OAAO,OAAO,CAAC;AAAA,UACnD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACC,IAAC,QAAsC,WAAW;AAAA,EACrD;AAGA,MAAI,cAAc,mBAAmB,GAAG;AACtC,UAAM,eAA6B;AAAA,MACjC,SAAS,UAAkC;AACzC,4BAAoB,IAAI,SAAS,IAAI,QAAQ;AAC7C,oBAAY;AAAA,UACV,MAAM;AAAA,UACN,SAAS,EAAE,IAAI,SAAS,IAAI,MAAM,SAAS,KAAK;AAAA,QAClD,CAAC;AACD,eAAO;AAAA,UACL,SAAS,MAAM;AACb,gCAAoB,OAAO,SAAS,EAAE;AAAA,UACxC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACC,IAAC,QAAwC,YAAY;AAAA,EACxD;AAGA,MAAI,cAAc,gBAAgB,GAAG;AACnC,UAAM,WAAqB;AAAA,MACzB,SAAS,MAAwB;AAC/B,wBAAgB,IAAI,KAAK,IAAI,IAAI;AACjC,oBAAY;AAAA,UACV,MAAM;AAAA,UACN,SAAS;AAAA,YACP,IAAI,KAAK;AAAA,YACT,MAAM,KAAK;AAAA,YACX,aAAa,KAAK;AAAA,YAClB,YAAY,KAAK;AAAA,UACnB;AAAA,QACF,CAAC;AACD,eAAO;AAAA,UACL,SAAS,MAAM;AACb,4BAAgB,OAAO,KAAK,EAAE;AAAA,UAChC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACC,IAAC,QAAgC,QAAQ;AAAA,EAC5C;AAGA,MAAI,cAAc,kBAAkB,GAAG;AACrC,UAAM,aAAyB;AAAA,MAC7B,SAAS,QAA4B;AACnC,0BAAkB,IAAI,OAAO,IAAI,MAAM;AACvC,oBAAY;AAAA,UACV,MAAM;AAAA,UACN,SAAS;AAAA,YACP,IAAI,OAAO;AAAA,UACb;AAAA,QACF,CAAC;AACD,eAAO;AAAA,UACL,SAAS,MAAM;AACb,8BAAkB,OAAO,OAAO,EAAE;AAAA,UACpC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACC,IAAC,QAAoC,UAAU;AAAA,EAClD;AAGA,MAAI,cAAc,aAAa,GAAG;AAChC,UAAM,YAAuB;AAAA,MAC3B,MAAM,KAAK,MAAc,SAAkD;AACzE,cAAM,YAAkB,eAAe,EAAE,MAAM,QAAQ,CAAC;AAAA,MAC1D;AAAA,IACF;AACC,IAAC,QAAkC,SAAS;AAAA,EAC/C;AAGA,MAAI,cAAc,oBAAoB,GAAG;AACvC,UAAM,eAA6B;AAAA,MACjC,MAAM,SAAS,KAAyC;AAEtD,cAAM,SAAU,iBAAyC;AACzD,cAAM,cAAc,UAAU,CAAC,IAAI,SAAS,EAAE,GAAG,KAAK,OAAO,IAAI;AACjE,cAAM,YAAkB,sBAAsB,EAAE,KAAK,YAAY,CAAC;AAAA,MACpE;AAAA,MACA,MAAM,OAAO,OAA8B;AACzC,cAAM,YAAkB,oBAAoB,EAAE,MAAM,CAAC;AAAA,MACvD;AAAA,MACA,OAAO,UAA+D;AACpE,2BAAmB,KAAK,QAAQ;AAChC,eAAO;AAAA,UACL,SAAS,MAAM;AACb,kBAAM,QAAQ,mBAAmB,QAAQ,QAAQ;AACjD,gBAAI,SAAS,EAAG,oBAAmB,OAAO,OAAO,CAAC;AAAA,UACpD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACC,IAAC,QAAwC,YAAY;AAAA,EACxD;AAGA,MAAI,cAAc,mBAAmB,GAAG;AACtC,UAAM,UAAmB;AAAA,MACvB,MAAM,aAAmC;AACvC,eAAO,YAAyB,mBAAmB,CAAC,CAAC;AAAA,MACvD;AAAA,IACF;AACC,IAAC,QAA8B,OAAO;AAAA,EACzC;AAGA,MAAI,cAAc,oBAAoB,GAAG;AACvC,UAAM,UAAmB;AAAA,MACvB,MAAM,kBAAkB,SAAgD;AACtE,cAAM,gBAAiB,iBAAyC;AAChE,cAAM,YAAkB,0BAA0B;AAAA,UAChD,GAAG;AAAA,UACH,QAAQ,QAAQ,UAAU;AAAA,QAC5B,CAAC;AAAA,MACH;AAAA,IACF;AACC,IAAC,QAA8B,OAAO;AAAA,EACzC;AAGA,MAAI,cAAc,cAAc,GAAG;AACjC,UAAM,cAA2B;AAAA,MAC/B,MAAM,QAAqB,KAAa,QAAkC;AACxE,eAAO,YAAiB,oBAAoB,EAAE,KAAK,OAAO,CAAC;AAAA,MAC7D;AAAA,IACF;AACC,IAAC,QAAsC,WAAW;AAAA,EACrD;AAGA,MAAI,cAAc,eAAe,GAAG;AAClC,UAAM,aAAyB;AAAA;AAAA,MAE7B,MAAM,IAAO,KAAqC;AAChD,eAAO,YAA2B,eAAe,EAAE,IAAI,CAAC;AAAA,MAC1D;AAAA,MACA,MAAM,IAAI,KAAa,OAA+B;AACpD,eAAO,YAAkB,eAAe,EAAE,KAAK,MAAM,CAAC;AAAA,MACxD;AAAA,MACA,MAAM,OAAO,KAA4B;AACvC,eAAO,YAAkB,kBAAkB,EAAE,IAAI,CAAC;AAAA,MACpD;AAAA,MACA,MAAM,OAA0B;AAC9B,eAAO,YAAsB,gBAAgB,CAAC,CAAC;AAAA,MACjD;AAAA;AAAA,MAEA,MAAM,WAAc,QAAgB,KAAqC;AACvE,eAAO,YAA2B,sBAAsB,EAAE,QAAQ,IAAI,CAAC;AAAA,MACzE;AAAA,MACA,MAAM,WAAW,QAAgB,KAAa,OAA+B;AAC3E,eAAO,YAAkB,sBAAsB,EAAE,QAAQ,KAAK,MAAM,CAAC;AAAA,MACvE;AAAA,MACA,MAAM,cAAc,QAAgB,KAA4B;AAC9D,eAAO,YAAkB,yBAAyB,EAAE,QAAQ,IAAI,CAAC;AAAA,MACnE;AAAA,MACA,MAAM,YAAY,QAAmC;AACnD,eAAO,YAAsB,uBAAuB,EAAE,OAAO,CAAC;AAAA,MAChE;AAAA,IACF;AACC,IAAC,QAAoC,UAAU;AAAA,EAClD;AAEA,SAAO;AACT;AAUO,SAAS,oBAAoB,QAA+B;AACjE,oBAAkB;AAGlB,cAAY,UAAU,OAAO,YAAiC;AAC5D,QAAI;AACF,YAAM,kBAAkB,OAAO;AAAA,IACjC,SAAS,OAAO;AACd,cAAQ,MAAM,2BAA2B,KAAK;AAAA,IAChD;AAAA,EACF,CAAC;AAGD,cAAY,EAAE,MAAM,QAAQ,CAAC;AAC/B;","names":[]}
1
+ {"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["/**\n * Extension Runtime - Runs inside the worker\n *\n * This module handles communication with the Extension Host and provides\n * the ExtensionContext to the extension's activate function.\n */\n\nimport type {\n ExecutionContext,\n ExtensionContext,\n ExtensionModule,\n Disposable,\n NetworkAPI,\n SettingsAPI,\n ProvidersAPI,\n ToolsAPI,\n ActionsAPI,\n EventsAPI,\n SchedulerAPI,\n SchedulerJobRequest,\n SchedulerFirePayload,\n UserAPI,\n UserProfile,\n ChatAPI,\n ChatInstructionMessage,\n DatabaseAPI,\n StorageAPI,\n LogAPI,\n AIProvider,\n Tool,\n Action,\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n} from './types.js'\n\nimport type {\n HostToWorkerMessage,\n WorkerToHostMessage,\n RequestMessage,\n PendingRequest,\n} from './messages.js'\n\nimport { generateMessageId } from './messages.js'\n\n// ============================================================================\n// Environment Detection and Message Port\n// ============================================================================\n\n/**\n * Detect if we're in Node.js Worker Thread or Web Worker\n * and get the appropriate message port\n */\ninterface MessagePort {\n postMessage(message: WorkerToHostMessage): void\n onMessage(handler: (message: HostToWorkerMessage) => void): void\n}\n\nfunction getMessagePort(): MessagePort {\n // Check if we're in Node.js Worker Thread\n if (typeof process !== 'undefined' && process.versions?.node) {\n // Node.js Worker Thread - import parentPort dynamically\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { parentPort } = require('node:worker_threads')\n return {\n postMessage: (message) => parentPort?.postMessage(message),\n onMessage: (handler) => parentPort?.on('message', handler),\n }\n }\n\n // Web Worker - use self\n return {\n postMessage: (message) => self.postMessage(message),\n onMessage: (handler) => {\n self.addEventListener('message', (event: MessageEvent<HostToWorkerMessage>) => {\n handler(event.data)\n })\n },\n }\n}\n\nconst messagePort = getMessagePort()\n\n// ============================================================================\n// Global State\n// ============================================================================\n\nlet extensionModule: ExtensionModule | null = null\nlet extensionDisposable: Disposable | null = null\nlet extensionContext: ExtensionContext | null = null\n\nconst pendingRequests = new Map<string, PendingRequest>()\nconst registeredProviders = new Map<string, AIProvider>()\nconst registeredTools = new Map<string, Tool>()\nconst registeredActions = new Map<string, Action>()\nconst settingsCallbacks: Array<(key: string, value: unknown) => void> = []\nconst schedulerCallbacks: Array<(payload: SchedulerFirePayload, context: ExecutionContext) => void | Promise<void>> = []\n\n/**\n * Tracking for streaming fetch requests.\n * Each request stores incoming chunks and signals when new data arrives.\n */\ninterface StreamingFetchRequest {\n chunks: string[]\n done: boolean\n error?: string\n resolve?: () => void\n}\nconst streamingFetchRequests = new Map<string, StreamingFetchRequest>()\n\nconst REQUEST_TIMEOUT = 30000 // 30 seconds\n\n// ============================================================================\n// Message Handling\n// ============================================================================\n\n/**\n * Send a message to the host\n */\nfunction postMessage(message: WorkerToHostMessage): void {\n messagePort.postMessage(message)\n}\n\n/**\n * Send a request to the host and wait for response\n */\nasync function sendRequest<T>(method: RequestMessage['method'], payload: unknown): Promise<T> {\n const id = generateMessageId()\n\n return new Promise<T>((resolve, reject) => {\n const timeout = setTimeout(() => {\n pendingRequests.delete(id)\n reject(new Error(`Request ${method} timed out`))\n }, REQUEST_TIMEOUT)\n\n pendingRequests.set(id, { resolve: resolve as (value: unknown) => void, reject, timeout })\n\n postMessage({\n type: 'request',\n id,\n method,\n payload,\n })\n })\n}\n\n/**\n * Handle messages from the host\n */\nasync function handleHostMessage(message: HostToWorkerMessage): Promise<void> {\n switch (message.type) {\n case 'activate':\n await handleActivate(message.payload)\n break\n\n case 'deactivate':\n await handleDeactivate()\n break\n\n case 'settings-changed':\n handleSettingsChanged(message.payload.key, message.payload.value)\n break\n\n case 'scheduler-fire':\n await handleSchedulerFire(message.payload)\n break\n\n case 'provider-chat-request':\n await handleProviderChatRequest(message.id, message.payload)\n break\n\n case 'provider-models-request':\n await handleProviderModelsRequest(message.id, message.payload)\n break\n\n case 'tool-execute-request':\n await handleToolExecuteRequest(message.id, message.payload)\n break\n\n case 'action-execute-request':\n await handleActionExecuteRequest(message.id, message.payload)\n break\n\n case 'response':\n handleResponse(message.payload)\n break\n\n case 'streaming-fetch-chunk':\n handleStreamingFetchChunk(message.payload)\n break\n }\n}\n\n/**\n * Handle incoming streaming fetch chunks from the host\n */\nfunction handleStreamingFetchChunk(payload: {\n requestId: string\n chunk: string\n done: boolean\n error?: string\n}): void {\n const request = streamingFetchRequests.get(payload.requestId)\n if (!request) return\n\n if (payload.error) {\n request.error = payload.error\n request.done = true\n } else if (payload.chunk) {\n request.chunks.push(payload.chunk)\n }\n\n if (payload.done) {\n request.done = true\n }\n\n // Signal that new data is available\n if (request.resolve) {\n const resolve = request.resolve\n request.resolve = undefined\n resolve()\n }\n\n // Send acknowledgment for backpressure control\n postMessage({\n type: 'streaming-fetch-ack',\n payload: { requestId: payload.requestId },\n })\n}\n\nfunction handleResponse(payload: { requestId: string; success: boolean; data?: unknown; error?: string }): void {\n const pending = pendingRequests.get(payload.requestId)\n if (!pending) return\n\n clearTimeout(pending.timeout)\n pendingRequests.delete(payload.requestId)\n\n if (payload.success) {\n pending.resolve(payload.data)\n } else {\n pending.reject(new Error(payload.error || 'Unknown error'))\n }\n}\n\n// ============================================================================\n// Activation / Deactivation\n// ============================================================================\n\nasync function handleActivate(payload: {\n extensionId: string\n extensionVersion: string\n storagePath: string\n permissions: string[]\n settings: Record<string, unknown>\n}): Promise<void> {\n const { extensionId, extensionVersion, storagePath, permissions } = payload\n\n // Build the context based on permissions\n extensionContext = buildContext(extensionId, extensionVersion, storagePath, permissions)\n\n // Import and activate the extension\n try {\n // The actual extension code should be bundled and available\n // This is called after the extension code has been loaded into the worker\n if (extensionModule?.activate) {\n const result = await extensionModule.activate(extensionContext)\n if (result && 'dispose' in result) {\n extensionDisposable = result\n }\n }\n } catch (error) {\n extensionContext.log.error('Failed to activate extension', {\n error: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n}\n\nasync function handleDeactivate(): Promise<void> {\n try {\n if (extensionModule?.deactivate) {\n await extensionModule.deactivate()\n }\n if (extensionDisposable) {\n extensionDisposable.dispose()\n }\n } catch (error) {\n console.error('Error during deactivation:', error)\n } finally {\n extensionModule = null\n extensionDisposable = null\n extensionContext = null\n registeredProviders.clear()\n registeredTools.clear()\n registeredActions.clear()\n settingsCallbacks.length = 0\n schedulerCallbacks.length = 0\n }\n}\n\nfunction handleSettingsChanged(key: string, value: unknown): void {\n for (const callback of settingsCallbacks) {\n try {\n callback(key, value)\n } catch (error) {\n console.error('Error in settings change callback:', error)\n }\n }\n}\n\nasync function handleSchedulerFire(payload: SchedulerFirePayload): Promise<void> {\n // Create request-scoped execution context\n const execContext: ExecutionContext = {\n userId: payload.userId,\n extension: {\n id: extensionContext!.extension.id,\n version: extensionContext!.extension.version,\n storagePath: extensionContext!.extension.storagePath,\n },\n }\n\n // Run callbacks concurrently to avoid blocking\n const results = await Promise.allSettled(\n schedulerCallbacks.map((callback) => callback(payload, execContext)),\n )\n\n // Log any errors\n results.forEach((result, index) => {\n if (result.status === 'rejected') {\n console.error(`Error in scheduler callback ${index}:`, result.reason)\n }\n })\n}\n\n// ============================================================================\n// Provider / Tool Requests\n// ============================================================================\n\nasync function handleProviderChatRequest(\n requestId: string,\n payload: { providerId: string; messages: ChatMessage[]; options: ChatOptions }\n): Promise<void> {\n const provider = registeredProviders.get(payload.providerId)\n if (!provider) {\n postMessage({\n type: 'request',\n id: generateMessageId(),\n method: 'network.fetch', // Dummy, we need a proper error response\n payload: { error: `Provider ${payload.providerId} not found` },\n })\n return\n }\n\n try {\n const generator = provider.chat(payload.messages, payload.options)\n let sawDone = false\n let sawError = false\n\n for await (const event of generator) {\n if (event.type === 'done') {\n sawDone = true\n } else if (event.type === 'error') {\n sawError = true\n }\n postMessage({\n type: 'stream-event',\n payload: { requestId, event },\n })\n }\n\n if (!sawDone && !sawError) {\n postMessage({\n type: 'stream-event',\n payload: {\n requestId,\n event: { type: 'done' },\n },\n })\n }\n } catch (error) {\n postMessage({\n type: 'stream-event',\n payload: {\n requestId,\n event: {\n type: 'error',\n message: error instanceof Error ? error.message : String(error),\n },\n },\n })\n }\n}\n\nasync function handleProviderModelsRequest(\n requestId: string,\n payload: { providerId: string; options?: GetModelsOptions }\n): Promise<void> {\n const provider = registeredProviders.get(payload.providerId)\n if (!provider) {\n // Send error response\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models: [],\n error: `Provider ${payload.providerId} not found`,\n },\n })\n return\n }\n\n try {\n // Pass options to getModels so provider can use settings (e.g., URL for Ollama)\n const models = await provider.getModels(payload.options)\n // Send response with models\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models,\n },\n })\n } catch (error) {\n postMessage({\n type: 'provider-models-response',\n payload: {\n requestId,\n models: [],\n error: error instanceof Error ? error.message : String(error),\n },\n })\n }\n}\n\nasync function handleToolExecuteRequest(\n requestId: string,\n payload: { toolId: string; params: Record<string, unknown>; userId?: string }\n): Promise<void> {\n const tool = registeredTools.get(payload.toolId)\n if (!tool) {\n // Send error response\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result: { success: false, error: `Tool ${payload.toolId} not found` },\n error: `Tool ${payload.toolId} not found`,\n },\n })\n return\n }\n\n try {\n // Create request-scoped execution context\n const execContext: ExecutionContext = {\n userId: payload.userId,\n extension: {\n id: extensionContext!.extension.id,\n version: extensionContext!.extension.version,\n storagePath: extensionContext!.extension.storagePath,\n },\n }\n\n const result = await tool.execute(payload.params, execContext)\n\n // Send response with result\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result,\n },\n })\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n postMessage({\n type: 'tool-execute-response',\n payload: {\n requestId,\n result: { success: false, error: errorMessage },\n error: errorMessage,\n },\n })\n }\n}\n\nasync function handleActionExecuteRequest(\n requestId: string,\n payload: { actionId: string; params: Record<string, unknown>; userId?: string }\n): Promise<void> {\n const action = registeredActions.get(payload.actionId)\n if (!action) {\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result: { success: false, error: `Action ${payload.actionId} not found` },\n error: `Action ${payload.actionId} not found`,\n },\n })\n return\n }\n\n try {\n // Create request-scoped execution context\n const execContext: ExecutionContext = {\n userId: payload.userId,\n extension: {\n id: extensionContext!.extension.id,\n version: extensionContext!.extension.version,\n storagePath: extensionContext!.extension.storagePath,\n },\n }\n\n const result = await action.execute(payload.params, execContext)\n\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result,\n },\n })\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n postMessage({\n type: 'action-execute-response',\n payload: {\n requestId,\n result: { success: false, error: errorMessage },\n error: errorMessage,\n },\n })\n }\n}\n\n// ============================================================================\n// Context Building\n// ============================================================================\n\nfunction buildContext(\n extensionId: string,\n extensionVersion: string,\n storagePath: string,\n permissions: string[]\n): ExtensionContext {\n const hasPermission = (perm: string): boolean => {\n return permissions.some((p) => {\n if (p === perm) return true\n if (p.endsWith(':*') && perm.startsWith(p.slice(0, -1))) return true\n return false\n })\n }\n\n const log: LogAPI = {\n debug: (message, data) => postMessage({ type: 'log', payload: { level: 'debug', message, data } }),\n info: (message, data) => postMessage({ type: 'log', payload: { level: 'info', message, data } }),\n warn: (message, data) => postMessage({ type: 'log', payload: { level: 'warn', message, data } }),\n error: (message, data) => postMessage({ type: 'log', payload: { level: 'error', message, data } }),\n }\n\n const context: ExtensionContext = {\n extension: {\n id: extensionId,\n version: extensionVersion,\n storagePath,\n },\n log,\n }\n\n // Add network API if permitted\n if (permissions.some((p) => p.startsWith('network:'))) {\n const networkApi: NetworkAPI = {\n async fetch(url: string, options?: RequestInit): Promise<Response> {\n const result = await sendRequest<{ status: number; statusText: string; headers: Record<string, string>; body: string }>('network.fetch', { url, options })\n return new Response(result.body, {\n status: result.status,\n statusText: result.statusText,\n headers: result.headers,\n })\n },\n\n async *fetchStream(url: string, options?: RequestInit): AsyncGenerator<string, void, unknown> {\n const requestId = generateMessageId()\n\n // Set up streaming request tracking\n const request: StreamingFetchRequest = {\n chunks: [],\n done: false,\n }\n streamingFetchRequests.set(requestId, request)\n\n // Send the streaming fetch request to the host\n postMessage({\n type: 'request',\n id: requestId,\n method: 'network.fetch-stream',\n payload: { url, options, requestId },\n })\n\n try {\n // Yield chunks as they arrive\n while (!request.done) {\n // Wait for new data\n await new Promise<void>((resolve) => {\n const resolver = () => {\n // Clear the stored resolver before resolving to avoid\n // stale callbacks being invoked for a new wait iteration.\n if (request.resolve === resolver) {\n request.resolve = undefined\n }\n resolve()\n }\n\n request.resolve = resolver\n\n // Check if we already have data or completion\n if (request.chunks.length > 0 || request.done) {\n resolver()\n }\n })\n\n // Check for errors first, before yielding any chunks\n if (request.error) {\n throw new Error(request.error)\n }\n\n // Yield all available chunks\n while (request.chunks.length > 0) {\n yield request.chunks.shift()!\n }\n }\n } finally {\n streamingFetchRequests.delete(requestId)\n }\n },\n }\n ;(context as { network: NetworkAPI }).network = networkApi\n }\n\n // Add settings API if permitted\n if (hasPermission('settings.register')) {\n const settingsApi: SettingsAPI = {\n async getAll<T extends Record<string, unknown>>(): Promise<T> {\n return sendRequest<T>('settings.getAll', {})\n },\n async get<T>(key: string): Promise<T | undefined> {\n return sendRequest<T | undefined>('settings.get', { key })\n },\n async set(key: string, value: unknown): Promise<void> {\n return sendRequest<void>('settings.set', { key, value })\n },\n onChange(callback: (key: string, value: unknown) => void): Disposable {\n settingsCallbacks.push(callback)\n return {\n dispose: () => {\n const index = settingsCallbacks.indexOf(callback)\n if (index >= 0) settingsCallbacks.splice(index, 1)\n },\n }\n },\n }\n ;(context as { settings: SettingsAPI }).settings = settingsApi\n }\n\n // Add providers API if permitted\n if (hasPermission('provider.register')) {\n const providersApi: ProvidersAPI = {\n register(provider: AIProvider): Disposable {\n registeredProviders.set(provider.id, provider)\n postMessage({\n type: 'provider-registered',\n payload: { id: provider.id, name: provider.name },\n })\n return {\n dispose: () => {\n registeredProviders.delete(provider.id)\n },\n }\n },\n }\n ;(context as { providers: ProvidersAPI }).providers = providersApi\n }\n\n // Add tools API if permitted\n if (hasPermission('tools.register')) {\n const toolsApi: ToolsAPI = {\n register(tool: Tool): Disposable {\n registeredTools.set(tool.id, tool)\n postMessage({\n type: 'tool-registered',\n payload: {\n id: tool.id,\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n },\n })\n return {\n dispose: () => {\n registeredTools.delete(tool.id)\n },\n }\n },\n }\n ;(context as { tools: ToolsAPI }).tools = toolsApi\n }\n\n // Add actions API if permitted\n if (hasPermission('actions.register')) {\n const actionsApi: ActionsAPI = {\n register(action: Action): Disposable {\n registeredActions.set(action.id, action)\n postMessage({\n type: 'action-registered',\n payload: {\n id: action.id,\n },\n })\n return {\n dispose: () => {\n registeredActions.delete(action.id)\n },\n }\n },\n }\n ;(context as { actions: ActionsAPI }).actions = actionsApi\n }\n\n // Add events API if permitted\n if (hasPermission('events.emit')) {\n const eventsApi: EventsAPI = {\n async emit(name: string, payload?: Record<string, unknown>): Promise<void> {\n await sendRequest<void>('events.emit', { name, payload })\n },\n }\n ;(context as { events: EventsAPI }).events = eventsApi\n }\n\n // Add scheduler API if permitted\n if (hasPermission('scheduler.register')) {\n const schedulerApi: SchedulerAPI = {\n async schedule(job: SchedulerJobRequest): Promise<void> {\n // Extensions must explicitly set job.userId if they want user-scoped jobs\n // Use context.userId from the ExecutionContext in tool/action execute\n await sendRequest<void>('scheduler.schedule', { job })\n },\n async cancel(jobId: string): Promise<void> {\n await sendRequest<void>('scheduler.cancel', { jobId })\n },\n onFire(callback: (payload: SchedulerFirePayload, context: ExecutionContext) => void): Disposable {\n schedulerCallbacks.push(callback)\n return {\n dispose: () => {\n const index = schedulerCallbacks.indexOf(callback)\n if (index >= 0) schedulerCallbacks.splice(index, 1)\n },\n }\n },\n }\n ;(context as { scheduler: SchedulerAPI }).scheduler = schedulerApi\n }\n\n // Add user profile API if permitted\n if (hasPermission('user.profile.read')) {\n const userApi: UserAPI = {\n async getProfile(): Promise<UserProfile> {\n return sendRequest<UserProfile>('user.getProfile', {})\n },\n }\n ;(context as { user: UserAPI }).user = userApi\n }\n\n // Add chat API if permitted\n if (hasPermission('chat.message.write')) {\n const chatApi: ChatAPI = {\n async appendInstruction(message: ChatInstructionMessage): Promise<void> {\n // Extensions must explicitly set message.userId if they want user-scoped messages\n // Use context.userId from the ExecutionContext in tool/action execute\n await sendRequest<void>('chat.appendInstruction', message)\n },\n }\n ;(context as { chat: ChatAPI }).chat = chatApi\n }\n\n // Add database API if permitted\n if (hasPermission('database.own')) {\n const databaseApi: DatabaseAPI = {\n async execute<T = unknown>(sql: string, params?: unknown[]): Promise<T[]> {\n return sendRequest<T[]>('database.execute', { sql, params })\n },\n }\n ;(context as { database: DatabaseAPI }).database = databaseApi\n }\n\n // Add storage API if permitted\n if (hasPermission('storage.local')) {\n const storageApi: StorageAPI = {\n // Global/extension-scoped storage\n async get<T>(key: string): Promise<T | undefined> {\n return sendRequest<T | undefined>('storage.get', { key })\n },\n async set(key: string, value: unknown): Promise<void> {\n return sendRequest<void>('storage.set', { key, value })\n },\n async delete(key: string): Promise<void> {\n return sendRequest<void>('storage.delete', { key })\n },\n async keys(): Promise<string[]> {\n return sendRequest<string[]>('storage.keys', {})\n },\n // User-scoped storage\n async getForUser<T>(userId: string, key: string): Promise<T | undefined> {\n return sendRequest<T | undefined>('storage.getForUser', { userId, key })\n },\n async setForUser(userId: string, key: string, value: unknown): Promise<void> {\n return sendRequest<void>('storage.setForUser', { userId, key, value })\n },\n async deleteForUser(userId: string, key: string): Promise<void> {\n return sendRequest<void>('storage.deleteForUser', { userId, key })\n },\n async keysForUser(userId: string): Promise<string[]> {\n return sendRequest<string[]>('storage.keysForUser', { userId })\n },\n }\n ;(context as { storage: StorageAPI }).storage = storageApi\n }\n\n return context\n}\n\n// ============================================================================\n// Initialization\n// ============================================================================\n\n/**\n * Initialize the extension runtime\n * This should be called by the extension's entry point\n */\nexport function initializeExtension(module: ExtensionModule): void {\n extensionModule = module\n\n // Set up message listener using the appropriate message port\n messagePort.onMessage(async (message: HostToWorkerMessage) => {\n try {\n await handleHostMessage(message)\n } catch (error) {\n console.error('Error handling message:', error)\n }\n })\n\n // Signal that we're ready\n postMessage({ type: 'ready' })\n}\n\n// Re-export types for extensions to use\nexport type {\n ExecutionContext,\n ExtensionContext,\n ExtensionModule,\n Disposable,\n AIProvider,\n Tool,\n ToolDefinition,\n ToolResult,\n ToolCall,\n Action,\n ActionResult,\n ModelInfo,\n ChatMessage,\n ChatOptions,\n GetModelsOptions,\n StreamEvent,\n} from './types.js'\n"],"mappings":"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","names":[]}