diff --git a/docs/devlog/2026-04-09.md b/docs/devlog/2026-04-09.md new file mode 100644 index 0000000..3178d75 --- /dev/null +++ b/docs/devlog/2026-04-09.md @@ -0,0 +1,5 @@ +# 2026-04-09 + +| NNN | HH:MM | 작업 설명 | `커밋해시` | 상태 | +|---|---|---|---|---| +| 001 | 21:55 | Agent UI Tailwind/Native 마이그레이션 대응 (DOM 옵저버 구조 개편) | `HEAD` | ✅ | diff --git a/docs/devlog/entries/20260409-001.md b/docs/devlog/entries/20260409-001.md new file mode 100644 index 0000000..99a06b1 --- /dev/null +++ b/docs/devlog/entries/20260409-001.md @@ -0,0 +1,18 @@ +# Agent UI Tailwind/Native 마이그레이션 대응 (DOM 옵저버 구조 개편) + +- **시간**: 2026-04-09 19:40~21:55 +- **Commit**: `[임시해시]` +- **Vikunja**: 신규 생성 후 완료 처리 + +## 트러블슈팅 및 결정 사항 +최근 UI 업데이트 후 Discord 릴레이 신호(Run, Accept) 단절. +deep-inspect 덤프 분석 결과 Webview/Iframe 환경이 사라지고 Native DOM(VS Code 본문)에 напрямую 그려짐, 기존 시맨틱 클래스가 Tailwind로 변경. +1. 기존 `findPanel`이 패널을 못 찾자 `isBodyRoot` 모드로 스캔 +2. 과거에 추가된 CodeLens 방어 로직(`if (isVSCodeMainWindow && isBodyRoot && PATS[p].type !== 'diff_review') continue;`)에 의해 모든 버튼 스캔이 **버려지고 있었음**. + +**결정**: +엄격한 Panel Class Whitelist 기반 방어를 해제하고, 버튼이 `.monaco-editor` 내부에 있는 경우만 무시하도록 Blacklist 기반 방어로 선회. +UI 텍스트 글루잉(아이콘 통합) 대응 위해 패터닝 정규식을 `/^(?:Always\s*)?Run/i` 등으로 완화. + +## 미완료 +- 없음 diff --git a/extension/src/observer-script.ts b/extension/src/observer-script.ts index cf81472..450be87 100644 --- a/extension/src/observer-script.ts +++ b/extension/src/observer-script.ts @@ -273,16 +273,16 @@ export function generateApprovalObserverScript(_port: number): string { // ONLY positive triggers should initiate a pending request group. // Negative/secondary buttons (Deny, Reject, Dismiss) will be collected as siblings. var PATS=[ - {re:/^Run/i, type:'terminal_command'}, - {re:/^Accept all/i, type:'diff_review'}, - {re:/^Accept/i, type:'agent_step'}, - {re:/^(?:Always )?Allow/i, type:'permission'}, - {re:/^Approve/i, type:'agent_step'}, + {re:/^(?:Always\s*)?Run/i, type:'terminal_command'}, + {re:/^(?:Always\s*)?Accept all/i, type:'diff_review'}, + {re:/^(?:Always\s*)?Accept/i, type:'agent_step'}, + {re:/^(?:Always\s*)?Allow/i, type:'permission'}, + {re:/^(?:Always\s*)?Approve/i, type:'agent_step'}, {re:/^Retry/i, type:'error_recovery'}, ]; // ALL actionable button patterns (for grouping siblings in same container) - var ALL_ACTION_RE=[/^Run/i,/^Accept/i,/^Reject/i,/^(?:Always )?Allow/i,/^Deny/i,/^Approve/i,/^Cancel$/i,/^Retry$/i,/^Dismiss$/i,/^Stop$/i,/^Decline$/i]; + var ALL_ACTION_RE=[/^(?:Always\s*)?Run/i,/^(?:Always\s*)?Accept/i,/^Reject/i,/^(?:Always\s*)?Allow/i,/^Deny/i,/^(?:Always\s*)?Approve/i,/^Cancel$/i,/^Retry$/i,/^Dismiss$/i,/^Stop$/i,/^Decline$/i]; // Reject button patterns for finding the counterpart var REJECT_RE=[/^reject$/i,/^reject all$/i,/^cancel$/i,/^deny$/i,/^stop$/i,/^decline$/i,/^dismiss$/i]; @@ -372,6 +372,9 @@ export function generateApprovalObserverScript(_port: number): string { '.react-app-container', '[class*="agent-panel"]', '[class*="agentPanel"]', + '.chat-body', + '.interactive-session', + '[class*="sidebar"]', ]; for(var i=0;i