Files
gravity_control/extension/scratch/verify_v096.js
Variet Worker bd5a7ca8b9 fix(observer): v32 터미널 프롬프트 조기감지 — JUNK/PROMPT 필터 전에 명령어 추출 (v0.5.97)
근본원인: code 요소의 textContent '❯ project > command'가 PowerShell 키워드
(return, function, const)를 포함할 수 있어 JUNK_CODE_RE에 잘못 걸림.
v32: ❯ 마커로 시작하는 code 텍스트는 JUNK/PROMPT 전에 명령어 직접 추출.
14/14 E2E 테스트 통과.
2026-04-19 19:55:44 +09:00

123 lines
4.4 KiB
JavaScript

const {generateApprovalObserverScript} = require('../out/observer-script');
let s = generateApprovalObserverScript(18080);
// 1. SYNTAX CHECK
try { new Function(s); console.log('[1] SYNTAX: OK'); } catch(e) { console.log('[1] SYNTAX ERROR:', e.message); process.exit(1); }
// 2. v30 block exists
let v30Start = s.indexOf('// v30:');
let v30End = s.indexOf('// v23:', v30Start);
console.log('[2] v30 block:', v30Start > 0 && v30End > v30Start ? 'OK' : 'MISSING');
// 3. Key features present
console.log('[3] rcCands:', s.indexOf('rcCands') > 0 ? 'OK' : 'MISSING');
console.log('[4] content_copy filter:', s.indexOf('content_copy|content_paste') > 0 ? 'OK' : 'MISSING');
console.log('[5] sort by length:', s.indexOf('.sort(') > 0 ? 'OK' : 'MISSING');
console.log('[6] icon strip replace:', (s.match(/content_copy/g)||[]).length >= 2 ? 'OK (filter+strip)' : 'CHECK');
// 4. Simulate exact DOM from BTN-DOM-DUMP + CONTEXT logs
let promptRe = /[\u003e\u00bb\u276f]\s+(.+)/;
let stripRe = /\s*(content_copy|content_paste|play_arrow|check_circle|keyboard_arrow[_a-z]*)\s*$/;
let iconFilterRe = /^(content_copy|content_paste|play_arrow|check_circle|chevron_|keyboard_arrow|more_horiz|more_vert|expand_|alternate_email|arrow_drop)/;
let btnFilterRe = /^(Always|Run|Allow|Cancel|Deny|keyboard_arrow)/i;
function simulate(name, siblings) {
console.log('\n=== ' + name + ' ===');
let rcFound = false;
for (let sib of siblings) {
if (sib === 'Running command' || (sib.indexOf('Running command') !== -1 && sib.length < 30)) {
rcFound = true;
break;
}
}
if (!rcFound) { console.log(' RC header NOT FOUND'); return null; }
let cands = [];
for (let sib of siblings) {
if (sib === 'Running command') continue;
if (sib.length < 5) continue;
if (iconFilterRe.test(sib)) { console.log(' SKIP icon: "' + sib.substring(0,30) + '"'); continue; }
if (btnFilterRe.test(sib)) { console.log(' SKIP btn: "' + sib.substring(0,30) + '"'); continue; }
if (sib.indexOf('Always run') !== -1 && sib.indexOf('Cancel') !== -1) { console.log(' SKIP btn-bar: "' + sib.substring(0,30) + '"'); continue; }
cands.push(sib);
}
cands.sort((a,b) => b.length - a.length);
console.log(' Candidates: ' + cands.length);
for (let i = 0; i < cands.length; i++) {
console.log(' [' + i + '] len=' + cands[i].length + ': "' + cands[i].substring(0,80) + '"');
}
for (let cand of cands) {
let m = promptRe.exec(cand);
if (m && m[1].trim().length > 3) {
let cmdV = m[1].trim().replace(stripRe, '').trim();
if (cmdV.length < 3) continue;
console.log(' RESULT: "' + cmdV + '"');
return cmdV;
}
if (cand.length > 10 && /[\u276f\u003e]/.test(cand)) {
let raw = cand.replace(stripRe, '').trim();
console.log(' RESULT (raw): "' + raw + '"');
return raw;
}
}
console.log(' RESULT: NO MATCH');
return null;
}
// Case 1: From BTN-DOM-DUMP (3 siblings, command + content_copy icon)
simulate('Case1: Normal command with icon', [
'Running command',
'\u276f gravity_control > Start-Sleep 12; $logFile content_copy',
'Always run keyboard_arrow_up Cancel'
]);
// Case 2: content_copy as standalone sibling
simulate('Case2: Icon as separate div', [
'Running command',
'content_copy',
'\u276f gravity_control > npm run compile',
'Always run Cancel'
]);
// Case 3: No icon appended
simulate('Case3: Clean command', [
'Running command',
'\u276f gravity_control > git add -A; git commit -m "test"',
'Always run Cancel'
]);
// Case 4: Very long command
simulate('Case4: Long command', [
'Running command',
'\u276f gravity_control > Select-String -Path "$env:USERPROFILE\\.gemini\\antigravity\\bridge\\extension.log" -Pattern "CONTEXT" content_copy',
'Always run keyboard_arrow_up Cancel'
]);
// Case 5: Prompt only (no command yet)
simulate('Case5: Prompt only', [
'Running command',
'\u276f gravity_control > ',
'Always run Cancel'
]);
// Case 6: Multiple icon texts
simulate('Case6: Multiple icons', [
'Running command',
'play_arrow',
'content_copy',
'\u276f gravity_control > dir content_copy',
'Always run Cancel'
]);
// Case 7: Observed log pattern - "content_copy" was cmdV
// This means the regex matched on just "content_copy" with a > before it
// Possible: the sibling text is "> content_copy" (very short prompt)
simulate('Case7: Short prompt with icon only', [
'Running command',
'> content_copy',
'Always run Cancel'
]);
console.log('\n=== ALL TESTS COMPLETE ===');