Skip to main content
Glama

Curupira

by drzln
runtime.ts8.02 kB
/** * Runtime domain wrapper for Chrome DevTools Protocol * * Provides typed access to Runtime domain methods with proper error handling */ import type { ChromeClient } from '../client.js' import type { Runtime, CDPSession } from '@curupira/shared/types/cdp.js' import { remoteObjectToValue, valueToCallArgument } from '@curupira/shared/utils' import { logger } from '../../config/logger.js' export class RuntimeDomain { constructor( private client: ChromeClient, private sessionId: string ) {} /** * Enable the Runtime domain */ async enable(): Promise<void> { await this.client.send('Runtime.enable', {}, this.sessionId) } /** * Disable the Runtime domain */ async disable(): Promise<void> { await this.client.send('Runtime.disable', {}, this.sessionId) } /** * Evaluate expression in the global scope */ async evaluate<T = unknown>( expression: string, options: { awaitPromise?: boolean returnByValue?: boolean generatePreview?: boolean silent?: boolean contextId?: number timeout?: number } = {} ): Promise<{ value?: T; error?: Error }> { try { const result = await this.client.send<{ result: Runtime.RemoteObject exceptionDetails?: Runtime.ExceptionDetails }>('Runtime.evaluate', { expression, awaitPromise: options.awaitPromise ?? true, returnByValue: options.returnByValue ?? true, generatePreview: options.generatePreview ?? false, silent: options.silent ?? false, contextId: options.contextId, timeout: options.timeout }, this.sessionId) if (result.exceptionDetails) { return { error: new Error( result.exceptionDetails.text || result.exceptionDetails.exception?.description || 'Evaluation failed' ) } } return { value: remoteObjectToValue(result.result) as T } } catch (error) { logger.error('Runtime.evaluate failed', { expression, error }) return { error: error as Error } } } /** * Call a function with given declaration */ async callFunctionOn<T = unknown>( objectId: string, functionDeclaration: string, args: unknown[] = [], options: { returnByValue?: boolean generatePreview?: boolean awaitPromise?: boolean } = {} ): Promise<{ value?: T; error?: Error }> { try { const result = await this.client.send<{ result: Runtime.RemoteObject exceptionDetails?: Runtime.ExceptionDetails }>('Runtime.callFunctionOn', { objectId, functionDeclaration, arguments: args.map(valueToCallArgument), returnByValue: options.returnByValue ?? true, generatePreview: options.generatePreview ?? false, awaitPromise: options.awaitPromise ?? true }, this.sessionId) if (result.exceptionDetails) { return { error: new Error( result.exceptionDetails.text || 'Function call failed' ) } } return { value: remoteObjectToValue(result.result) as T } } catch (error) { logger.error('Runtime.callFunctionOn failed', { objectId, error }) return { error: error as Error } } } /** * Get properties of an object */ async getProperties( objectId: string, options: { ownProperties?: boolean accessorPropertiesOnly?: boolean generatePreview?: boolean } = {} ): Promise<Runtime.PropertyDescriptor[]> { try { const result = await this.client.send<{ result: Runtime.PropertyDescriptor[] internalProperties?: Runtime.InternalPropertyDescriptor[] privateProperties?: Runtime.PrivatePropertyDescriptor[] }>('Runtime.getProperties', { objectId, ownProperties: options.ownProperties ?? true, accessorPropertiesOnly: options.accessorPropertiesOnly ?? false, generatePreview: options.generatePreview ?? true }, this.sessionId) return result.result } catch (error) { logger.error('Runtime.getProperties failed', { objectId, error }) return [] } } /** * Release an object */ async releaseObject(objectId: string): Promise<void> { try { await this.client.send('Runtime.releaseObject', { objectId }, this.sessionId) } catch (error) { logger.error('Runtime.releaseObject failed', { objectId, error }) } } /** * Release a group of objects */ async releaseObjectGroup(objectGroup: string): Promise<void> { try { await this.client.send('Runtime.releaseObjectGroup', { objectGroup }, this.sessionId) } catch (error) { logger.error('Runtime.releaseObjectGroup failed', { objectGroup, error }) } } /** * Get execution contexts */ async getExecutionContexts(): Promise<Runtime.ExecutionContextDescription[]> { try { // Enable Runtime to get contexts await this.enable() // Get current contexts via evaluate const result = await this.evaluate<Runtime.ExecutionContextDescription[]>( `Array.from(window.__CDP_CONTEXTS__ || [])` ) return result.value || [] } catch (error) { logger.error('Failed to get execution contexts', error) return [] } } /** * Compile script without executing */ async compileScript( expression: string, sourceURL: string, persistScript = false ): Promise<{ scriptId?: string; error?: Runtime.ExceptionDetails }> { try { const result = await this.client.send<{ scriptId?: string exceptionDetails?: Runtime.ExceptionDetails }>('Runtime.compileScript', { expression, sourceURL, persistScript }, this.sessionId) return { scriptId: result.scriptId, error: result.exceptionDetails } } catch (error) { logger.error('Runtime.compileScript failed', { sourceURL, error }) return {} } } /** * Run previously compiled script */ async runScript( scriptId: string, options: { executionContextId?: number objectGroup?: string silent?: boolean awaitPromise?: boolean } = {} ): Promise<{ value?: unknown; error?: Error }> { try { const result = await this.client.send<{ result: Runtime.RemoteObject exceptionDetails?: Runtime.ExceptionDetails }>('Runtime.runScript', { scriptId, ...options }, this.sessionId) if (result.exceptionDetails) { return { error: new Error(result.exceptionDetails.text || 'Script execution failed') } } return { value: remoteObjectToValue(result.result) } } catch (error) { logger.error('Runtime.runScript failed', { scriptId, error }) return { error: error as Error } } } /** * Set up console API event listener */ onConsoleAPICalled( handler: (params: Runtime.ConsoleAPICalledEvent) => void ): void { this.client.onSessionEvent(this.sessionId, 'Runtime.consoleAPICalled', handler) } /** * Set up exception thrown event listener */ onExceptionThrown( handler: (params: Runtime.ExceptionThrownEvent) => void ): void { this.client.onSessionEvent(this.sessionId, 'Runtime.exceptionThrown', handler) } /** * Set up execution context created event listener */ onExecutionContextCreated( handler: (params: { context: Runtime.ExecutionContextDescription }) => void ): void { this.client.onSessionEvent(this.sessionId, 'Runtime.executionContextCreated', handler) } /** * Set up execution context destroyed event listener */ onExecutionContextDestroyed( handler: (params: { executionContextId: number }) => void ): void { this.client.onSessionEvent(this.sessionId, 'Runtime.executionContextDestroyed', handler) } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/drzln/curupira'

If you have feedback or need assistance with the MCP directory API, please join our Discord server