UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

91 lines • 3.36 kB
/** * @license * Copyright 2026 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import { logger } from '../utils/logger.js'; const DEFAULT_DEBOUNCE_MS = 200; /** * Manages the bidirectional bridge between DevTools frontend comments * and the MCP server notification system. */ export class DevToolsCommentBridge { #onNotification; #debounceMs; #commentDebounceTimer; #attachedPages = new Set(); constructor(options) { this.#onNotification = options?.onNotification; this.#debounceMs = options?.debounceMs ?? DEFAULT_DEBOUNCE_MS; } isAttached(devtoolsPage) { return this.#attachedPages.has(devtoolsPage); } async attach(devtoolsPage) { if (this.#attachedPages.has(devtoolsPage)) { return; } this.#attachedPages.add(devtoolsPage); try { await devtoolsPage.exposeFunction('__onDevToolsCommentEvent', () => { this.#handleCommentEvent(); }); } catch (e) { logger?.('DevToolsCommentBridge: exposeFunction already bound or failed', e); } try { await devtoolsPage.evaluate(() => { window.__onDevToolsCommentListener = () => { window.__onDevToolsCommentEvent?.(); }; window.universe?.cd4aBridge?.addEventListener('CommentThreadsChanged', window.__onDevToolsCommentListener); window.universe?.cd4aBridge?.setAgentAttached(true); }); } catch (e) { logger?.('DevToolsCommentBridge: evaluate failed', e); } } async getComments(devtoolsPage) { return await devtoolsPage.evaluate(() => { window.universe?.cd4aBridge?.setAgentAttached(true); return window.universe?.cd4aBridge?.getCommentThreads() ?? []; }); } #handleCommentEvent() { if (this.#commentDebounceTimer) { clearTimeout(this.#commentDebounceTimer); } this.#commentDebounceTimer = setTimeout(() => { this.#onNotification?.('DevTools comment threads updated'); }, this.#debounceMs); } dispose() { if (this.#commentDebounceTimer) { clearTimeout(this.#commentDebounceTimer); this.#commentDebounceTimer = undefined; } for (const page of this.#attachedPages) { try { const result = page.evaluate(() => { if (window.__onDevToolsCommentListener) { window.universe?.cd4aBridge?.removeEventListener?.('CommentThreadsChanged', window.__onDevToolsCommentListener); delete window.__onDevToolsCommentListener; } window.universe?.cd4aBridge?.setAgentAttached(false); }); if (result && typeof result.catch === 'function') { void result.catch(e => { logger?.('DevToolsCommentBridge: failed to remove event listener', e); }); } } catch (e) { logger?.('DevToolsCommentBridge: failed to remove event listener', e); } } this.#attachedPages.clear(); } } //# sourceMappingURL=DevToolsCommentBridge.js.map