fix(cdp): fix sendMessage selector escape bug + polling JSON comparison

This commit is contained in:
2026-03-07 21:27:51 +09:00
parent 507324f78e
commit 6ed5b33caa

View File

@@ -282,7 +282,8 @@ class CDPClient {
/**
* Antigravity 채팅 입력창에 메시지를 전송
*
* Antigravity는 textarea가 아닌 contenteditable div를 사용함
* 단일 Runtime.evaluate로 요소 찾기 + 텍스트 입력 수행
* (2단계 분리 시 셀렉터 이스케이프 손실 버그 방지)
*/
async sendMessage(text) {
if (!this.connected || !this.client) {
@@ -290,11 +291,10 @@ class CDPClient {
}
try {
// 1) contenteditable 입력창 찾기 및 포커스
const { result: focusResult } = await this.client.Runtime.evaluate({
const safeText = JSON.stringify(text);
const { result } = await this.client.Runtime.evaluate({
expression: `
(function() {
// Antigravity 입력창 셀렉터 (우선순위 순)
const selectors = [
'#antigravity\\\\.agentSidePanelInputBox [contenteditable="true"][role="textbox"]',
'.antigravity-agent-side-panel [contenteditable="true"][role="textbox"]',
@@ -302,47 +302,34 @@ class CDPClient {
'[contenteditable="true"][role="textbox"]',
];
let el = null;
for (const sel of selectors) {
const el = document.querySelector(sel);
if (el) {
el.focus();
return { found: true, sel: sel };
el = document.querySelector(sel);
if (el) break;
}
}
return { found: false };
})()
`,
returnByValue: true,
});
if (!focusResult.value?.found) {
return { success: false, error: '채팅 입력창을 찾을 수 없습니다' };
}
// 2) 텍스트 입력 (contenteditable용 — execCommand 방식)
await this.client.Runtime.evaluate({
expression: `
(function() {
const el = document.querySelector('${focusResult.value.sel}');
if (!el) return;
if (!el) return { success: false, error: 'input not found' };
el.focus();
// 기존 내용 선택 후 삭제
const selection = window.getSelection();
const range = document.createRange();
range.selectNodeContents(el);
selection.removeAllRanges();
selection.addRange(range);
// 텍스트 삽입 (React/Preact 호환)
document.execCommand('insertText', false, ${JSON.stringify(text)});
document.execCommand('insertText', false, ${safeText});
return { success: true, text: el.textContent.substring(0, 50) };
})()
`,
returnByValue: true,
});
// 3) Enter 키 전송
if (!result.value?.success) {
return { success: false, error: result.value?.error || '입력 실패' };
}
// Enter 키 전송
await this.client.Input.dispatchKeyEvent({
type: 'keyDown',
key: 'Enter',
@@ -358,7 +345,7 @@ class CDPClient {
windowsVirtualKeyCode: 13,
});
console.log(`[CDP] 메시지 전송: "${text.substring(0, 50)}..."`);
console.log(`[CDP] 메시지 전송: "${text.substring(0, 50)}"`);
return { success: true };
} catch (err) {
console.error('[CDP] 메시지 전송 오류:', err.message);
@@ -378,11 +365,12 @@ class CDPClient {
return;
}
const html = await this.scrapeChatDOM();
if (html && html !== this.lastChatHTML) {
this.lastChatHTML = html;
const messages = await this.scrapeChatDOM();
const hash = JSON.stringify(messages);
if (messages && messages.length > 0 && hash !== this.lastChatHTML) {
this.lastChatHTML = hash;
if (this.onChatUpdate) {
this.onChatUpdate(html);
this.onChatUpdate(messages);
}
}
}, intervalMs);