diff --git a/.agents/references/architecture.md b/.agents/references/architecture.md index 3433055..3c660a6 100644 --- a/.agents/references/architecture.md +++ b/.agents/references/architecture.md @@ -45,7 +45,7 @@ gravity_control/ ├── bridge.py # 파일 기반 IPC (레거시 fallback) (479줄) ├── watcher.py # Brain 디렉토리 변경 감시 (290줄) ├── parser.py # Markdown → Discord 변환 (245줄) -├── collector.py # 원격 파일→HTTP 릴레이 (Phase 2 삭제 예정) (517줄) +├── collector.py # 원격 파일→HTTP 릴레이 (⚠️ DEPRECATED — WS Hub 사용) (523줄) │ ├── ── Extension 측 (TypeScript) ── ├── extension/src/ @@ -252,11 +252,16 @@ Extension(step-probe.ts) → 새 step 텍스트 감지 ``` AG Engine → 파일 수정 → Extension(step-probe.ts) → edit_step_indices + modified_files 메타데이터 수집 - → writePendingApproval (step_type="diff_review") + → writePendingApproval (step_type="diff_review", 8초 지연) → Discord (Accept all / Reject all 버튼) - → 응답 → acknowledgeCodeActionStep RPC + → 응답 → handleDiffReviewResponse() + → openReviewChanges → 파일별 포커스 → agentAcceptAllInFile VS Code 커맨드 ``` +> [!IMPORTANT] +> diff_review는 **VS Code 커맨드만 유효**합니다. RPC 방식(AcknowledgeCascadeCodeEdit 등)은 모두 실패 확정. +> 상세 경위는 known-issues-archive.md의 "Diff Review 관련" 섹션을 참조하세요. + --- ## 5. 통신 프로토콜 @@ -292,7 +297,7 @@ AG Engine → 파일 수정 → Extension(step-probe.ts) |------|---------|-------------|------| | `local` | ✅ (brain 감시) | ❌ | 로컬 개발 (Extension과 같은 PC) | | `gateway` | ❌ | ✅ (port 8585) | 서버 배포 (WS Hub + Gateway) | -| `remote` | ✅ | ❌ | 원격 브릿지 (레거시 Collector) | +| `remote` | ✅ | ❌ | ⚠️ **DEPRECATED** — 레거시 Collector (WS Hub 사용 권장) | --- diff --git a/.agents/references/conventions.md b/.agents/references/conventions.md index 673a41c..6cc1e7b 100644 --- a/.agents/references/conventions.md +++ b/.agents/references/conventions.md @@ -89,3 +89,37 @@ Extension 모듈 분리 시 사용하는 패턴: | Extension | `logToFile(msg)` → bridge/log/ | `[HH:MM:SS] message` + `[WS]` prefix | | Hub | `[HUB]` prefix | `[HUB] Auth OK: {conn_id} project={project}` | | Gateway | `[GATEWAY]` prefix | `[GATEWAY] HTTP API started on {host}:{port}` | + +## WS / File Bridge 상호 배타 패턴 + +> [!IMPORTANT] +> WS Hub과 파일 bridge는 **항상 상호 배타적**이어야 합니다. +> 양쪽에 동시에 쓰면 이중 전달 버그가 발생합니다. (known-issues-archive 참조) + +**Extension (TypeScript):** +```typescript +// ✅ 올바른 패턴 +if (ctx.wsBridge?.isConnected()) { + ctx.wsBridge.sendPending(data); + return; // ← 반드시 return으로 파일 쓰기 건너뛰기 +} +// File fallback +fs.writeFileSync(pendingPath, JSON.stringify(data)); +``` + +**Bot (Python):** +```python +# ✅ 올바른 패턴 +if self.hub: + await self.hub.send_response(...) +else: + bridge.write_response(...) +``` + +**금지 패턴:** +```python +# ❌ 이중 쓰기 — 절대 금지 +if self.hub: + await self.hub.send_response(...) +bridge.write_response(...) # ← Hub 성공해도 파일에도 씀 → 이중 처리 +``` diff --git a/.agents/references/known-issues-archive.md b/.agents/references/known-issues-archive.md new file mode 100644 index 0000000..5fbd1be --- /dev/null +++ b/.agents/references/known-issues-archive.md @@ -0,0 +1,581 @@ +# Known Issues — Archive + +> **해결 완료된 이슈 아카이브입니다.** +> 현재 활성 이슈는 [`known-issues.md`](file:///c:/Users/Variet-Worker/Desktop/gravity_control/.agents/references/known-issues.md)를 참조하세요. +> 비슷한 문제가 재발할 때 이 문서에서 과거 해결 방법을 검색하세요. + +--- + +## 포맷 + +```markdown +### [날짜] [키워드] — 한줄 요약 +- **증상**: 무엇이 잘못되었는가 +- **원인**: 근본 원인 +- **해결**: 올바른 해결 방법 +- **주의**: 재발 방지를 위한 교훈 +``` + +--- + +## 승인 전략 결정 체인 (2026-03-08~09 전체 요약) + +> **이 섹션은 2026-03-08~09 전체 세션의 시행착오를 요약합니다.** +> **이미 거부된 접근을 다시 시도하지 마세요.** + +### ❌ 시도 후 거부된 접근 (재시도 금지) + +| # | 접근 | 결과 | 거부 사유 | +|---|------|------|-----------| +| 1 | LS RPC `HandleCascadeUserInteraction` | `socket hang up` | AG 빌드에서 핸들러 미구현 | +| 2 | LS RPC `ResolveOutstandingSteps` | CANCEL 동작 (승인이 아님) | 명칭과 달리 step을 취소함 | +| 3 | VS Code 7개 승인 명령 (`terminalCommand.run` 등) | `command not found` | AG 런타임에 미등록 | +| 4 | 키보드 시뮬레이션 (`type {Enter}`) | 빈 메시지 전송 | Chat input에 캡처됨 | +| 5 | `sendChatActionMessage` / `executeCascadeAction` | 미등록 | 119개 명령에 없음 | +| 6 | pywinauto (OS 레벨) | 사용자 결정 폐기 | 크로스플랫폼 불가, 창 겹침 문제 | +| 7 | CDP (Chrome DevTools Protocol) | **사용자 명시적 거부** | 비표준, `--remote-debugging-port` 필요 | +| 8 | Renderer v1 DOM Click (flat scan) | Run 버튼 미발견 | webview iframe 격리 | + +### 🔑 핵심 전제 +- Run/Accept 버튼은 **`vscode-webview://` origin의 격리된 iframe** 안에 있음 +- 외부 workbench DOM에서 `querySelector`로 접근 **불가** (cross-origin) +- `.executeJavaScript()`가 **유일한 표준 관통 경로** (Electron API) +- AG 패치 후 **반드시 풀 프로세스 재시작** 필요 (Reload Window 불충분) +- **양쪽 HTML (workbench.html + workbench-jetski-agent.html) 모두 inline 패치** 필수 +- HTML 패치 변경 시 **`%APPDATA%\Antigravity\CachedData` 삭제 필수** (V8 바이트코드 캐시 무효화) +- **CSP `script-src`에 `'unsafe-inline'` 패치 필수** (없으면 인라인 스크립트 무조건 차단) + +--- + +## Renderer / HTML 패치 관련 (2026-03-08~09) + +### [2026-03-08] Antigravity Renderer Injection — Electron 캐시 차단 +- **증상**: workbench.html, workbench-jetski-agent.html에 ``** 방식으로 HTML에 직접 삽입 +- **주의**: `ag-bridge-ports.json`도 같은 이유로 XHR 로딩 불가. 모든 렌더러 스크립트/데이터는 HTML 인라인으로 전달해야 함 + +### [2026-03-08] Renderer 포트 디스커버리 — ag-bridge-ports.json XHR 실패 +- **증상**: `[GB Observer] Port discovery timeout after 2min` — 렌더러가 bridge 포트를 찾지 못함 +- **원인**: 렌더러 스크립트가 `./ag-bridge-ports.json`을 동기 XHR로 읽으려 하나, `vscode-file://` 프로토콜이 `.json` 파일 서빙 거부 +- **해결**: (1) 프로젝트명 해시 기반 **결정론적 포트** 사용 (`gravity_control→34332`), (2) 스크립트 생성 시 포트를 `HARDCODED_PORT=${port}`로 직접 삽입 +- **주의**: `server.listen(0)` 랜덤 포트 → 매 재시작마다 변경되어 렌더러와 불일치. 결정론적 포트는 `EADDRINUSE` 시 랜덤 폴백 필요 + +### [2026-03-08] GetCascadeTrajectorySteps — cascadeId 파라미터 발견 +- **증상**: `GetCascadeTrajectorySteps`에 `trajectoryId` 파라미터 → 500 "trajectory not found" +- **원인**: 파라미터명이 `trajectoryId`가 아니라 **`cascadeId`**. 값은 `GetAllCascadeTrajectories.trajectorySummaries`의 맵 키(세션 ID) +- **해결**: `{ cascadeId: sessionId }`로 호출 → 전체 step 배열 반환 성공 +- **주의**: `latestToolCallStep` 필드는 `GetAllCascadeTrajectories` 응답에 **존재하지 않음** (KI 오류) + +### [2026-03-08] Step 구조 — CORTEX_STEP_STATUS_WAITING 즉시 감지 +- **증상**: stall-based 감지(100초)가 너무 느림 +- **원인**: 이제 `GetCascadeTrajectorySteps`로 최신 step의 status를 직접 확인 가능 +- **해결**: stall 5초 후 step probe → `CORTEX_STEP_STATUS_WAITING` 확인 → 즉시 pending 생성 +- **Step 구조**: `{type: "CORTEX_STEP_TYPE_RUN_COMMAND", status: "CORTEX_STEP_STATUS_WAITING", metadata: {toolCall: {name, argumentsJson}}, runCommand, requestedInteraction}` +- **주의**: 775-step 하드 리밋은 여전히 존재. 긴 세션에서는 fallback(40초) 사용 + +### [2026-03-08] Extension 재설치 안전성 — 자동 패치 메커니즘 +- **증상**: Antigravity 삭제 후 재설치 시 렌더러 스크립트가 동작 안 함 +- **원인**: 재설치 시 HTML/product.json이 원본으로 리셋됨 +- **해결**: Extension의 `setupApprovalObserver()`가 **자동으로** 모든 패치를 수행 +- **주의**: 패치 후 반드시 **Antigravity 풀 재시작** 필요 (Reload Window 불가) + +### [2026-03-08] Response 파일 Race Condition — DOM Observer 승인 실패 +- **증상**: Discord에서 승인 → `[RESPONSE] renderer-handled approval` 로그 출력 → 실제 버튼 클릭 안 됨 +- **원인**: `processResponseFile` (파일 감시자)이 response 파일을 즉시 삭제 → renderer의 `pollResponse`가 HTTP `GET /response/:rid`로 조회 시 파일 이미 없음 +- **해결**: DOM observer 소스일 때는 response 파일을 삭제하지 않도록 수정. HTTP endpoint가 renderer에게 서빙한 후 삭제 +- **주의**: non-DOM (stall/step_probe relay)는 watcher에서 삭제해도 됨 + +### [2026-03-08] Renderer 스크립트 소스 혼동 — 3곳의 코드 +- **증상**: `extension.ts`에 BTN-DUMP 추가 → Reload 2번 → 콘솔에 안 나옴 +- **원인**: renderer 코드가 **3곳**에 존재: (1) `extension.ts`의 `generateApprovalObserverScript()` (소스), (2) `ag-sdk-variet-gravity-bridge.js` (배포됨, Reload시 소스에서 재생성), (3) `workbench-jetski-agent.html` inline (HTML, JS파일과 중복로드 방지됨) +- **해결**: 항상 `extension.ts`의 `generateApprovalObserverScript()` 함수를 수정 → 컴파일 → 배포 → Reload +- **주의**: HTML inline은 JS파일이 먼저 로드되어 `window.__agSDK` 가드에 의해 실행 안 됨. 실제 실행되는 것은 JS파일 경로의 스크립트 + +--- + +## 승인 / RPC 관련 (2026-03-09) + +### [2026-03-09] VS Code Accept — SDK 승인 명령이 AG에 미등록 +- **증상**: Discord 승인 → `antigravity.terminalCommand.run` 등 7개 명령 → 모두 `command not found` +- **원인**: SDK(command-bridge.ts)에 정의된 7개 승인 명령이 현재 AG 빌드에 **등록되어 있지 않음** +- **해결**: Renderer DOM Click 구현 → v3 `deepFindButtons()` 업그레이드 +- **주의**: `agentPanel.focus`도 미등록, `agentSidePanel.focus`만 존재 + +### [2026-03-09] Renderer DOM — webview iframe 격리 확인 + v3 deep traversal +- **증상**: Renderer trigger-click이 `document.querySelectorAll('button')`으로 버튼 검색 → Run 버튼 미발견 +- **원인**: Run/Accept 버튼은 AG 채팅 webview iframe (`vscode-webview://` origin) 안에 렌더링 +- **해결**: Renderer v3 `deepFindButtons()` 구현 (iframe contentDocument + webview.executeJavaScript + shadow DOM) +- **주의**: CDP(Chrome DevTools Protocol)는 **사용자 결정에 의해 명시적으로 거부됨** + +### [2026-03-09] Deep Inspect HTTP Endpoint — curl로 DOM 분석 트리거 +- **증상**: AG DevTools 콘솔에 붙여넣기 불가 (Chromium 보안 정책) +- **원인**: Electron 렌더러 DevTools에서 `allow pasting`이 SyntaxError 발생 +- **해결**: Extension HTTP bridge에 `/deep-inspect` 엔드포인트 추가 +- **주의**: 시작 3초 후 자동 실행 + curl로 재트리거 가능 + +### [2026-03-09] workbench.html inline 스크립트 미삽입 — jetski만 패치한 버그 +- **증상**: AG 재시작 후 `/deep-inspect` timeout — renderer v3 스크립트 미로딩 +- **원인**: `setupApprovalObserver()`가 `workbench-jetski-agent.html`에만 inline 삽입 +- **해결**: HTML 패치 로직을 **양쪽 모두 inline** 삽입으로 변경 +- **주의**: **항상 양쪽 HTML을 동일하게 패치** + +### [2026-03-09] V8 CachedData — 체크섬 정상이어도 스크립트 미실행 +- **증상**: HTML 패치 + product.json 체크섬 일치 → 그런데도 renderer 스크립트 미실행 +- **원인**: V8 바이트코드 캐시가 `vscode-file://` 프로토콜에도 적용 +- **해결**: `%APPDATA%\Antigravity\CachedData\*` 전체 삭제 후 AG 풀 재시작 +- **주의**: **HTML 패치 변경 시마다 CachedData 삭제 필수** + +### [2026-03-09] CSP script-src — 인라인 스크립트 무조건 차단 +- **증상**: HTML 패치 ✅, 체크섬 ✅, CachedData 삭제 ✅ — 그런데도 renderer 미실행 +- **원인**: CSP `script-src`에 `'unsafe-inline'` 없음 +- **해결**: CSP `script-src`에 `'unsafe-inline'` 추가 +- **주의**: `style-src`에는 `'unsafe-inline'`이 있어 스타일은 동작 → 스크립트만 차단되는 것이 함정 + +### [2026-03-09] 중복 승인 요청 — DOM scan + Step probe 동시 발동 +- **증상**: Discord에 같은 명령에 대해 승인 요청이 2개 도착 +- **원인**: DOM Observer + Step probe가 동일 step에 대해 2개 파일 생성 +- **해결**: `writePendingApproval()`에 15초 dedup 윈도우 추가 +- **주의**: DOM scan은 제거 불가 — step probe가 감지 못하는 UI 버튼 존재 + +### [2026-03-09] Step probe reject → ResolveOutstandingSteps가 AI 작업 취소 +- **증상**: Discord에서 거부 클릭 → AI의 현재 step뿐 아니라 진행 중인 작업 전체가 중단 +- **원인**: step probe 경로의 `tryApprovalStrategies(approved=false)` → `ResolveOutstandingSteps` RPC 호출 +- **해결**: step probe 경로에서 reject 시 `tryApprovalStrategies` 호출 제거 +- **주의**: `ResolveOutstandingSteps`는 이름과 달리 "해결"이 아닌 "취소". 승인에 **절대 사용 금지** + +### [2026-03-09] Pending 파일 무한 누적 — write_response 후 미삭제 +- **증상**: `bridge/pending/` 디렉토리에 79개 이상의 .json 파일 누적 +- **원인**: `write_response()`가 pending 파일을 삭제하지 않음 +- **해결**: pending 파일 삭제 + 5분 age filter + 시작 시 cleanup +- **주의**: 봇 재시작 시 자동 정리 + +### [2026-03-09] Discord 승인 "Run" 표시 — DOM/step_probe 타이밍 불일치 +- **증상**: Discord에 상세 명령어 대신 "Run"만 표시 +- **원인**: DOM observer가 "Run" pending 생성 → 봇이 3초 후 전송 → step_probe MERGE가 10초 후 완료 +- **해결**: step_probe가 기존 DOM pending에 MERGE + 봇에서 짧은 명령어 대기 +- **주의**: MERGE 타이밍은 최소 10초 + +### [2026-03-09] DOM observer false positive — Proceed/Continue/Open 버튼 오감지 +- **증상**: 작업 전환 시 승인 요청 없는데도 Discord에 승인 요청 도착 +- **원인**: DOM observer가 AG UI의 PathsToReview 버튼을 승인 버튼으로 오인 +- **해결**: FALSE_POSITIVE_RE 필터 추가 + sessionStalled 조건 +- **주의**: 렌더러 인라인 스크립트는 VSIX 빌드 필요 + +### [2026-03-09] Discord ApprovalView timeout — 5분 후 버튼 무응답 +- **증상**: 시간이 지난 후 Discord 승인 버튼 클릭해도 반응 없음 +- **원인**: Discord.py View의 기본 timeout이 300초 +- **해결**: timeout을 1800초로 증가 +- **주의**: Discord View timeout은 서버 재시작 후만 적용 + +--- + +## 멀티 프로젝트 / Pending 관련 (2026-03-10) + +### [2026-03-10] DOM Observer 승인 ENOENT — response 파일 Race Condition +- **증상**: Discord에서 ✅승인 → `ENOENT: response/xxx.json` 에러 +- **원인**: `processResponseFile()`이 response 파일 즉시 삭제 → renderer 조회 실패 +- **해결**: DOM observer 경로에서 response 파일을 삭제하지 않고 HTTP handler가 서빙 후 삭제 +- **주의**: DOM observer와 step_probe 두 경로가 독립적 + +### [2026-03-10] Allow Once + Allow This Conversation — 별개 pending으로 분리되는 문제 +- **증상**: 파일 접근 시 Discord에 2개 별도 메시지로 도착 +- **원인**: renderer `scan()`이 한 사이클에 한 버튼만 처리 +- **해결**: `findButtonContainer()` + `collectSiblingButtons()`로 그룹화, `buttons` 배열 전송 +- **주의**: `buttons` 배열이 없는 legacy pending은 기존 2버튼(✅승인/❌거부)으로 표시 + +### [2026-03-10] step_probe verbosity — argumentsJson 미포함 +- **증상**: Discord 승인 메시지에 파라미터 이름만 표시, 값 없음 +- **원인**: `GetCascadeTrajectorySteps` 기본 verbosity에서 `argumentsJson` 빈 문자열 +- **해결**: `verbosity: 1` (DEBUG) 추가 +- **주의**: verbosity 0=NORMAL (키만), 1=DEBUG (값 포함) + +### [2026-03-10] 파일 권한 응답 — "unexpected user interaction type: not file permission" +- **증상**: `.agents` 디렉토리 접근 시 에러 +- **원인**: 봇이 file_permission pending에 잘못된 interaction type 전송 +- **해결**: step_type별 올바른 RPC 라우팅 +- **주의**: file_permission과 run_command가 동시에 대기 시 올바른 RPC 라우팅 필수 + +### [2026-03-10] active_project.lock — 멀티 프로젝트 동시 사용 차단 +- **증상**: 여러 AG 프로젝트 실행 시 첫 번째만 bridge 연결 +- **원인**: `active_project.lock` 파일이 단일 프로젝트만 허용 +- **해결**: lock 메커니즘 완전 제거, `project_name` 필터 기반으로 전환 +- **주의**: bridge 격리는 `project_name` 필드 기반 filtering으로 충분 + +### [2026-03-10] step_probe file_permission — 3-button 미주입 +- **증상**: Discord에 3개 선택지 대신 2개만 표시 +- **원인**: `writePendingApproval()`이 buttons 배열 미주입 +- **해결**: `step_type === 'file_permission'`일 때 자동 3-button 배열 주입 +- **주의**: DOM observer 경로는 기존 command 텍스트 기반 감지 유지 + +### [2026-03-10] GetAllCascadeTrajectories — 크로스 윈도우 세션 가로채기 +- **증상**: Deriva AG에서 대화 시작 → gravity_control 채널에 Deriva 내용이 릴레이 +- **원인**: `GetAllCascadeTrajectories`가 모든 인스턴스의 세션 반환 +- **해결**: `workspaces[0].workspaceFolderAbsoluteUri` 비교하여 자기 workspace 세션만 처리 +- **주의**: workspace URI normalize 필수 (protocol strip, %3A decode, 슬래시 통일, lowercase) + +### [2026-03-10] 크로스 프로젝트 Response Watcher 우회 +- **증상**: Deriva 세션 승인 시도가 gravity_control에서 실패 +- **원인**: pending 파일 삭제 후 response watcher가 project_name 체크 건너뜀 +- **해결**: response JSON의 project_name으로 fallback 필터 +- **주의**: response 데이터 자체에 project_name 필수 + +### [2026-03-10] file_permission — write 도구 3-button 미주입 +- **증상**: `replace_file_content` 등 파일 수정 시 Discord에 2개만 표시 +- **원인**: step_probe의 file_permission 도구 리스트에 write 도구 누락 +- **해결**: write 도구를 file_permission 리스트에 추가 +- **주의**: AG가 파일 접근 권한을 요청하는 모든 도구는 이 리스트에 포함필요 + +### [2026-03-10] bestSession IDLE 고착 — RUNNING 세션 못 잡는 버그 +- **증상**: 새 대화 시작 → bridge가 구 IDLE 세션만 추적 +- **원인**: `bestSession` 선택이 `lastModifiedTime`만 비교 +- **해결**: RUNNING 세션이 IDLE보다 항상 우선 +- **주의**: Reload Window로도 해결되지만 근본적으로는 RUNNING 우선 로직 필요 + +### [2026-03-10] Bot IDLE 채널 자동 생성 — 불필요한 Discord 채널 증식 +- **증상**: 봇 시작 시 모든 등록된 프로젝트의 채널을 자동 생성 +- **원인**: `pending_approval_scanner`가 매 사이클마다 채널 생성 +- **해결**: 자동 채널 생성 루프 제거, on-demand 생성 +- **주의**: `_get_channel()`은 이미 on-demand 생성 로직 포함 + +### [2026-03-10] Reload Window 후 세션 stale +- **증상**: Reload Window 후 세션이 IDLE/구 stepCount로 고정 +- **원인**: LS 프로세스는 유지되어 trajectory tracker 캐시 미갱신 +- **해결**: AG 완전 종료 → 재실행 (Full restart) +- **주의**: Extension 코드 변경 후 배포 시 Full restart 권장 + +### [2026-03-10] start_bot.bat — Windows Store Python 스텁 우선 실행 +- **증상**: `start_bot.bat` 실행 시 스텁이 먼저 실행 +- **원인**: `where python`이 Windows Store의 Python 스텁을 먼저 찾음 +- **해결**: conda 경로를 우선 확인 +- **주의**: Windows 10/11에서 App Aliases의 python.exe가 PATH에 기본 포함 + +### [2026-03-10] VSIX 빌드 — SDK JS 파일 미포함 (require 실패) +- **증상**: Extension 활성화 후 `SDK not initialized` +- **원인**: TypeScript 컴파일러가 `.js` 파일을 `out/`에 복사하지 않음 +- **해결**: `compile` 스크립트에 복사 단계 추가 (`src/sdk/` → `out/sdk/`) +- **주의**: VSIX 패키징은 `out/sdk/`를 포함함. 문제는 빌드 단계 복사 누락 + +### [2026-03-10] SDK _findLSProcess — 대소문자 구분 workspace hint 매칭 실패 +- **증상**: variet-agent AG에서 Discord에 신호 미도달 +- **원인**: SDK가 workspace hint를 대소문자 구분으로 비교 +- **해결**: `fixLSConnection()` 함수로 대소문자 무시 비교 + 재연결 +- **주의**: 각 AG 창마다 별도 LS 프로세스 존재 (workspace_id로 구분) + +--- + +## 환경변수 / 설정 관련 (2026-03-11) + +### [2026-03-11] config.py BRAIN_PATH — `.env` 빈 문자열 → CWD 해석 버그 +- **증상**: 봇이 Extension의 snapshot/pending을 전혀 읽지 못함 +- **원인**: `.env`에 `BRAIN_PATH=` (빈 값)이면 빈 문자열 반환 +- **해결**: `os.getenv("BRAIN_PATH") or default` 패턴 +- **주의**: `os.getenv(key, default)`는 빈 값이라도 default 미사용 + +### [2026-03-11] Extension DEDUP MERGE — 크로스 프로젝트 pending 오염 +- **증상**: `#ag-lifetimepd` 채널에 variet_agent의 승인 요청 표시 +- **원인**: DEDUP 로직이 `project_name`을 체크하지 않음 +- **해결**: 3곳 dedup 조건에 `project_name` 가드 추가 +- **주의**: 모든 Extension 인스턴스가 동일한 `bridge/pending/` 디렉토리 공유 + +### [2026-03-11] Collector 동기 HTTP — aiohttp 전환 +- **증상**: Collector가 이벤트 루프 전체 블로킹 +- **원인**: `urllib.request.urlopen()` 사용 (blocking I/O) +- **해결**: `aiohttp.ClientSession` 기반 비동기 전환 +- **주의**: `import aiohttp`는 lazy + +--- + +## Rate Limit / 무한 루프 관련 (2026-03-12) + +### [2026-03-12] RemoteTransport 429 무한 루프 — Extension 크래시 + AG 먹통 +- **증상**: `429 Rate limited` 로그가 초당 수십 건 무한 반복 +- **원인**: 3가지 복합 (백오프 없음 + 개별 HTTP 요청 + 공격적 rate limit) +- **해결**: 지수 백오프 + `Retry-After` 지원 + rate limit 완화 +- **주의**: AG 먹통은 봇 자체가 유발한 문제 + +### [2026-03-12] workbench.html 0-byte 파괴 — AG 새 창 먹통 +- **증상**: AG 새 창 열면 화면 먹통 +- **원인**: 3개 Extension 인스턴스가 동시에 workbench.html 읽기/쓰기 → 0 bytes로 덮어쓰기 +- **해결**: pre-patch backup(.orig) + 구조 검증 + 자동 복원 +- **주의**: 멀티 윈도우 환경에서 HTML 패치 race condition은 파일 잠금 없이 완전 해결 불가 + +### [2026-03-12] workbench.html 크로스 복원 — CSS 미로딩으로 레이아웃 깨짐 +- **증상**: 아이콘은 보이지만 레이아웃 완전 깨짐 +- **원인**: workbench.html을 jetski HTML에서 복원할 때 CSS 교체 누락 +- **해결**: 파일별 `requiredMarker` 검증 + `.orig` 백업 + 자동 복원 +- **주의**: **workbench.html과 workbench-jetski-agent.html은 교환 불가능** + +### [2026-03-12] Collector 단일 프로젝트 폴링 — 멀티 프로젝트 command 전달 불가 +- **증상**: Deriva AG IDE에 명령 전달되지 않음 +- **원인**: Collector가 단일 프로젝트만 폴링 +- **해결**: `_discover_local_projects()`로 모든 프로젝트 폴링 +- **주의**: `/api/commands/all` 엔드포인트는 크로스 PC 명령 오염을 유발 + +### [2026-03-12] RemoteTransport backing off 무한 반복 +- **증상**: IDLE 시 `backing off 1s` 경고가 영구 반복 +- **원인**: 3가지 구조적 결함 (즉시 리셋 + 불필요 요청 + asyncio burst) +- **해결**: 연속 5회 성공 후 절반 감소 + adaptive 간격 + 루프 stagger +- **주의**: `_reset_backoff()` 즉시 리셋 패턴은 다중 소비자 환경에서 **절대 사용 금지** + +--- + +## DEDUP / 크로스 세션 관련 (2026-03-15) + +### [2026-03-15] DEDUP step_index 크로스 세션 충돌 — 승인 신호 누락 +- **증상**: WAITING step 감지 → pending 미생성 → 10분+ 대기 +- **원인**: DEDUP 로직이 `conversation_id`를 비교하지 않음 +- **해결**: DEDUP 조건에 `conversation_id` 가드 추가 +- **주의**: `project_name` 가드만으로는 불충분 — 같은 Extension이 여러 세션을 볼 수 있음 + +### [2026-03-15] Discord Gateway MESSAGE_CREATE 중복 — embed 이중 전송 +- **증상**: Discord 명령 시 동일 embed가 2개 전송 +- **원인**: Discord Gateway가 WebSocket 불안정 시 이벤트 중복 전달 +- **해결**: `on_message`에 `_processed_message_ids` dedup 추가 +- **주의**: Gateway reconnection, RESUME 실패 시 발생 빈도 증가 + +### [2026-03-15] HTML 패치 멀티 인스턴스 race condition — 화면 파괴 +- **증상**: Extension 패치 후 AG 재시작 시 전체 화면 날아감 +- **원인**: 2+ Extension 인스턴스가 동시에 같은 HTML에 readFileSync/writeFileSync +- **해결**: `.patch-lock` 파일 기반 cross-instance lock 추가 +- **주의**: Lock은 "방지", .orig 백업은 "복구". 둘 다 유지 + +### [2026-03-15] 로컬 승인 ↔ Discord 승인 교차 race condition +- **증상**: AG에서 직접 Run 클릭 후 Discord 승인 요청이 "완료됨" 표시 안 됨 +- **원인**: auto_resolve가 Discord에 알림 없음 + processResponseFile 상태 미체크 +- **해결**: writeChatSnapshot 추가 + 상태 확인 후 skip + _approval_messages dict +- **주의**: processResponseFile L2534의 리셋이 핵심 gate + +### [2026-03-15] 크로스 프로젝트 DEDUP MERGE — Deriva→gravity_control 오염 +- **증상**: Deriva의 데이터가 gravity_control pending에 MERGE됨 +- **원인**: MERGE 조건에 `project_name` 가드 없음 +- **해결**: MERGE 조건에 `project_name` 추가 +- **주의**: `bridge/pending/` 디렉토리는 모든 Extension 인스턴스가 공유 + +### [2026-03-15] Double-Fire Auto-Approve — AI 세션 중단 +- **증상**: auto-approve ON 시 AI 세션이 간헐적으로 중단 +- **원인**: Extension auto-approve 경로 + Bot auto-approve 경로 동시 실행 → 2번 RPC +- **해결**: Extension auto-approve 경로 제거. Bot만 담당 +- **주의**: 단일 경로 원칙 유지 + +### [2026-03-15] DOM Observer "Deny" False Positive — Auto-approve 세션 크래시 +- **증상**: auto-approve ON 시 "Deny" command가 자동 승인됨 → 세션 크래시 +- **원인**: DOM observer가 Deny를 독립 pending으로 생성. default 분기로 잘못된 RPC 전송 +- **해결**: FALSE_POSITIVE_RE에 Deny/Allow Once 등 추가 + reject-word 차단 가드 +- **주의**: VSIX 빌드 → AG 풀 재시작 필요 + +### [2026-03-15] PATS 배열 Deny 트리거 — 근본 수정 +- **증상**: Deny가 주 트리거로 사용됨 +- **원인**: PATS 배열에 Deny 패턴 포함 +- **해결**: PATS에서 거절/보조 버튼 제거. 긍정 버튼만 그룹 트리거 +- **주의**: PATS = "그룹 생성 트리거", ALL_ACTION_RE = "형제 수집 패턴" + +### [2026-03-15] Auto-Resolved 채팅 폭주 — 루프 내 writeChatSnapshot +- **증상**: "✅ AG에서 직접 승인됨" 메시지가 반복 전송 +- **원인**: 루프 내부에서 매 파일마다 writeChatSnapshot 호출 +- **해결**: 루프 바깥에서 1회 + conversation_id 조건 추가 +- **주의**: 외부 시스템에 메시지 보낼 때는 반드시 루프 바깥에서 집계 후 1회 발송 + +### [2026-03-15] projectName=default 승인 오발 +- **증상**: workspace 없는 AG 창이 다른 프로젝트의 WAITING을 감지 +- **원인**: `detectProjectName()`이 workspace 없으면 "default" 반환 +- **해결**: `projectName === 'default'`이면 pending 생성/auto-approve 억제 +- **주의**: Empty Window에서는 bridge 기능을 최소화 + +### [2026-03-15] 이전 분석 오판(False Positive) — 교훈 +- **증상**: P0/P1으로 보고한 문제들이 이미 방어되고 있었음 +- **원인**: 로컬 코드 스니펫만 보고 판단 +- **해결**: 전체 Flow 추적으로 교차 검증 +- **주의**: **코드 감사 시 반드시 producer→transport→consumer→side effects 전체 경로를 추적** + +--- + +## processResponseFile 상태 관리 (2026-03-16) + +### [2026-03-16] processResponseFile 상태 리셋 — 무한 루프 vs auto_resolve 회귀 +- **증상**: Discord 승인 후 같은 step에 대해 pending이 반복 생성 → 무한 auto-approve 루프 +- **원인**: processResponseFile이 무조건 리셋 → step_probe가 같은 WAITING step을 새 step으로 착각 +- **해결**: `sawRunningAfterPending = true`만 설정. lastPendingStepIndex와 stallProbed 유지 +- **주의**: **processResponseFile의 상태 리셋은 sawRunningAfterPending = true만 설정**. `docs/approval-flow.md` 참조 + +### [2026-03-16] recentPendingSteps 메모리 dedup +- **증상**: pending 파일 삭제 → 같은 step_index로 새 pending 생성 +- **원인**: writePendingApproval()의 dedup이 파일 존재 여부에만 의존 +- **해결**: `recentPendingSteps` Map (TTL 60초) 추가 +- **주의**: DOM observer HTTP 경로는 이 메모리 dedup 미적용 + +### [2026-03-16] 멀티 프로젝트 동시 신호 정지 — Scanner O(N) Discord API 병목 +- **증상**: 여러 프로젝트 동시 pending → 모든 프로젝트 신호 전달 정지 +- **원인**: scanner가 1 tick에 모든 pending 순차 처리 → Discord 429 rate limit +- **해결**: `discord.utils.get(guild.channels)` 캐시 + per-tick cap (5건) +- **주의**: `guild.channels`는 discord.py 내부 캐시 + +--- + +## Diff Review 관련 (2026-03-16) + +### [2026-03-16] step_type 매핑 버그 — write_to_file이 file_permission으로 잘못 매핑 +- **증상**: 코드 편집 승인 시 잘못된 RPC 전송 +- **원인**: 쓰기 도구가 읽기 도구와 함께 `file_permission`으로 매핑 +- **해결**: 읽기/쓰기 도구 분리, 쓰기는 `code_edit` step_type 사용 +- **주의**: AG는 대부분 파일 쓰기에 WAITING 안 만듦 + +### [2026-03-16] diff_review isDirty 실패 — AG diff는 VS Code dirty 아님 +- **증상**: Accept 클릭 → `isDirty` 문서 0개 → 효과 없음 +- **원인**: AG stacked code review는 VS Code `isDirty`와 무관 +- **해결**: `AcknowledgeCascadeCodeEdit` RPC → fallback으로 VS Code 커맨드 +- **주의**: diff_review pending에 `modified_files`와 `edit_step_indices` 필수 + +### [2026-03-16] diff_review pending 순서 — AI 응답보다 먼저 Discord 도착 +- **증상**: diff_review 버튼이 먼저, AI 응답 텍스트가 나중 +- **원인**: pending_approval_scanner가 chat_snapshot_scanner보다 먼저 fire +- **해결**: diff_review pending 생성을 `setTimeout(8000)`으로 지연 +- **주의**: 8초는 전체 전파 경로 고려 + +### [2026-03-16] diff_review AcknowledgeCascadeCodeEdit steps=[] — Collector pending 삭제 race +- **증상**: Accept all 클릭 → RPC SUCCESS → diff review 바 안 사라짐 +- **원인**: Collector가 pending 파일 즉시 삭제 → Extension이 메타데이터 못 읽음 +- **해결**: `diffReviewMetadata` 인메모리 Map 추가 +- **주의**: Extension Reload 시 소실되지만 새 diff_review는 정상 동작 + +### [2026-03-16] AcknowledgeCascadeCodeEdit SUCCESS → diff review bar 미해제 — 잘못된 RPC 메서드명 +- **증상**: RPC SUCCESS 반환 → diff review bar 여전히 표시 +- **원인**: RPC 메서드명 자체가 틀렸음 (`AcknowledgeCascadeCodeEdit` → 실제는 `acknowledgeCodeActionStep`) +- **해결**: `agentAcceptAllInFile` / `agentRejectAllInFile` VS Code 커맨드 사용 +- **주의**: AG의 RPC는 잘못된 메서드명도 에러 없이 `{}` 반환. **RPC `{}`는 실패로 간주해야 함** + +### [2026-03-16] diff_review RPC 3개 전략 모두 dead-end +- **증상**: 3개 RPC 전략 모두 실패 +- **원인**: (1) submitCodeAcknowledgement 미등록, (2) acknowledgeCodeActionStep 404, (3) AcknowledgeCascadeCodeEdit no-op +- **해결**: VS Code 커맨드 기반 (`agentAcceptAllInFile` / `agentRejectAllInFile`) +- **주의**: **diff_review를 RPC로 해결하려는 시도 모두 실패 확정. VS Code 커맨드 기반만 유효** + +### [2026-03-16] AG 소스 역분석 — diff review 내부 동작 체인 +- **증상**: Accept all / Reject all 내부 동작을 재현해야 함 +- **원인**: AG 공식 API/문서 없음 +- **해결**: AG 설치 경로의 JS 소스에서 역분석 +- **주의**: minified JS에서 변수명은 버전마다 변경됨 + +### [2026-03-16] diff_review 이중 승인 요청 — DOM observer가 Accept/Reject 버튼 캡처 +- **증상**: diff_review 외에 별도 "Accept"/"Reject" pending 도착 +- **원인**: `openReviewChanges` 커맨드가 diff UI 패널 → DOM observer 감지 +- **해결**: FALSE_POSITIVE_RE에 Accept/Reject all 추가 +- **주의**: diff review bar 버튼은 전용 시스템에서 처리 + +### [2026-03-16] diff_review가 brain/ artifact에도 트리거 +- **증상**: task.md만 수정해도 "코드 리뷰" pending 생성 +- **원인**: diff_review 감지 로직이 모든 수정 파일 추적 +- **해결**: `.gemini/antigravity/brain/` 경로 파일 필터링하여 제외 +- **주의**: 코드 파일 + brain artifact 혼합 시 코드 파일만 diff_review + +--- + +## WS Hub 전환 관련 (2026-03-16~17) + +### [2026-03-16] !auto 이중 메시지 — Extension echo + Bot embed +- **증상**: `!auto` 토글 시 메시지 2개 표시 +- **원인**: Bot embed + Extension writeChatSnapshot echo +- **해결**: Extension의 `!auto` handler에서 writeChatSnapshot echo 제거 +- **주의**: Bot 재시작 시 auto_approve_projects 초기화 → 수동 모드 복귀 + +### [2026-03-16] 병렬 WAITING step 누락 — step_probe break문 +- **증상**: 병렬 tool call 시 1개만 승인 요청 도착 +- **원인**: step_probe 루프에서 `break`문이 첫 번째 WAITING 후 종료 +- **해결**: `break` 제거, 모든 WAITING step에 pending 생성 +- **주의**: 중복 방지는 `recentPendingSteps` Map이 처리 + +### [2026-03-16] Bot chat_snapshot 전송 로깅 부재 +- **증상**: 전송 성공/실패를 Bot 로그에서 확인 불가 +- **원인**: `channel.send()` 성공 후 INFO 로그 없음 +- **해결**: 전송 성공/실패 로그 추가 +- **주의**: `_get_channel()` 실패 시 WARNING은 이전에도 있었음 + +### [2026-03-16] 크로스 프로젝트 이벤트 폭주 — Watcher/Collector 무필터 +- **증상**: /start 시 타 프로젝트 알림 유입 +- **원인**: watcher.py가 brain/ 전체를 감시 +- **해결**: `_is_my_session()` 필터 + 이벤트 전달 필터 추가 +- **주의**: 미등록 세션은 allow-through 방식 + +### [2026-03-16] pending 파일 139개 누적 — 정리 로직 부재 +- **증상**: bridge/pending/에 139개 파일 누적 +- **원인**: auto_resolved/expired 파일을 아무도 삭제 안 함 +- **해결**: Collector에서 auto_resolved/expired 전달 후 삭제 + 10분 자동 삭제 +- **주의**: startup_pending은 정리 대상에서 제외 + +### [2026-03-17] NPM WebSocket 프록시 — Upgrade 헤더 미전달 +- **증상**: `wss://ag.variet.net/ws` 연결 시 HTTP 400 +- **원인**: Nginx Proxy Manager에 WebSocket Support 미활성화 +- **해결**: NPM 대시보드에서 Websockets Support 체크 +- **주의**: 새 프록시 호스트 생성 시 반드시 확인 + +### [2026-03-17] WS auth_fail 무한 재연결 — _cleanup() close 이벤트 +- **증상**: Auth failed 후 60초마다 재연결 반복 +- **원인**: `_cleanup()`이 ws.close() → close 이벤트 → _scheduleReconnect() 체인 +- **해결**: `this.shouldReconnect = false`를 `_cleanup()` 이전에 설정 +- **주의**: `_cleanup()`은 이벤트 핸들러를 트리거하므로 상태 변경은 반드시 호출 전에 + +### [2026-03-17] initStepProbe workspaceUri 누락 — 세션 감지 완전 불능 +- **증상**: POLL alive만 출력, SESSION-FILTER/SNAPSHOT 없음 +- **원인**: `initStepProbe()` 호출 시 필수 필드 미전달 + `as` 캐스트가 런타임 검증 없음 +- **해결**: `workspaceUri`, `diffReviewMetadata: new Map()` 추가 +- **주의**: TypeScript `as` 캐스트는 런타임 검증 없음 + +### [2026-03-17] WS 명령어 에코 릴레이 — Discord 메시지 2번 표시 +- **증상**: Discord 메시지 입력 → 같은 메시지가 다시 표시 +- **원인**: handleWSCommand에서 `recentDiscordSentTexts`에 마킹 안 함 +- **해결**: `recentDiscordSentTexts.set()` 추가 +- **주의**: 파일 기반 경로에는 이미 마킹 있었음 + +### [2026-03-17] writeRegistration 이중 쓰기 — WS 전송 후 파일도 작성 +- **증상**: WS 상태에서도 register/ 파일 생성 +- **원인**: WS 전송 후 `return` 없이 파일 쓰기 실행 +- **해결**: WS 전송 후 `return` 추가 +- **주의**: 새 WS 전송 함수 추가 시 file fallback과 상호 배타적 `return` 확인 diff --git a/.agents/references/known-issues.md b/.agents/references/known-issues.md index 38f5f29..c834ff8 100644 --- a/.agents/references/known-issues.md +++ b/.agents/references/known-issues.md @@ -4,12 +4,14 @@ > 디버깅이나 구현 전에 **반드시** 이 파일을 확인하세요. > 세션 종료 시 새로 발견된 이슈를 이 파일에 추가합니다. +> [!TIP] +> 해결 완료된 과거 이슈는 [`known-issues-archive.md`](file:///c:/Users/Variet-Worker/Desktop/gravity_control/.agents/references/known-issues-archive.md)에 보관되어 있습니다. +> 비슷한 문제가 재발하면 archive에서 검색하세요. + --- ## 포맷 -각 항목은 아래 형식을 따릅니다: - ```markdown ### [날짜] [키워드] — 한줄 요약 - **증상**: 무엇이 잘못되었는가 @@ -22,24 +24,6 @@ ## 공통 이슈 -### [2026-03-17] Hub pending_owners 생명주기 — WS 재연결 시 승인 응답 소실 -- **증상**: Discord에서 승인 클릭해도 AG Extension에서 아무 동작 안함 (이중 메시지 전달 이후 특히 발생) -- **원인**: `hub.py _disconnect()` 에서 Extension 연결이 끊기면 `pending_owners[rid]`를 **삭제**함. Extension이 재연결하면 새 conn_id 할당되지만, 기존 pending의 owner 정보는 이미 삭제됨. `send_response_to_pending_owner()`가 owner를 찾지 못해 `False` 반환. File bridge fallback은 Docker 컨테이너 볼륨에 파일 작성하므로 Extension 접근 불가. -- **해결**: (1) `_disconnect`에서 삭제 대신 같은 project 다른 연결로 재할당, (2) `_register_connection`에서 orphaned pending_owners를 새 conn_id로 재할당, (3) `send_response_to_pending_owner`에 같은 project 활성 연결 fallback 추가 -- **주의**: Gateway 모드에서 file bridge fallback은 **완전히 무용** — Docker 볼륨에 파일 작성하지만 Extension은 로컬 bridge/ 감시. **WS 라우팅 실패 시 file bridge에 의존하지 말 것**. - -### [2026-03-17] diff_review Accept All WS 경로 regression (v0.4.5 fix) -- **증상**: Discord에서 Accept all 클릭해도 AG에서 반응 없음 -- **원인**: v0.4.0 WS 전환 시 `onResponse` 핸들러에 `diff_review` step_type 분기가 누락됨. `processResponseFile` (파일 경로)에만 diff_review 로직이 있었고, WS `onResponse`는 무조건 `tryApprovalStrategies()`만 호출. `tryApprovalStrategies`는 diff_review를 처리하지 않음 -- **해결**: `step-probe.ts`에 `handleDiffReviewResponse()` export 함수 추출. `extension.ts` `onResponse`에서 `stepType === 'diff_review'`일 때 이 함수 호출 -- **주의**: **WS 경로 추가 시 file-bridge 경로의 모든 분기를 반드시 포팅할 것**. step_type별 분기(diff_review, file_permission 등)가 누락되기 쉬움 - -### [2026-03-17] _auto_approve_via_hub 이중 쓰기 (v0.4.5 fix) -- **증상**: auto-approve 시 Extension에 응답이 2번 도착 -- **원인**: `bot.py:_auto_approve_via_hub()` L1095-1100에서 Hub WS 전송 후 `return` 없이 file bridge에도 씀 -- **해결**: `if self.hub:` → WS 전송 + `else:` → file bridge. if/else 구조로 변경 -- **주의**: Hub WS와 file bridge는 **항상 상호 배타적**이어야 함. `return`이 아닌 `if/else` 사용 권장 - ### [2026-03-08] PowerShell curl — Invoke-WebRequest 충돌 - **증상**: `curl` 명령이 예상과 다른 응답 형식을 반환 - **원인**: PowerShell에서 `curl`은 `Invoke-WebRequest`의 별칭 @@ -48,690 +32,81 @@ ### [2026-03-08] PowerShell npm — 실행 정책 오류 - **증상**: `npm run` 명령이 `실행 정책` 관련 오류로 실패 -- **원인**: PowerShell 스크립트 실행 정책이 제한적으로 설정됨 +- **원인**: PowerShell 스크립트 실행 정책이 제한적 - **해결**: `cmd /c npm run dev` 형식으로 cmd를 통해 실행 - **주의**: npm 관련 명령은 항상 `cmd /c` 접두어 사용 권장 --- -## 프로젝트별 이슈 +## 미해결 이슈 -> 아래에 프로젝트 특화 이슈를 추가하세요. - -### [2026-03-08] Antigravity Renderer Injection — Electron 캐시 차단 -- **증상**: workbench.html, workbench-jetski-agent.html에 ``** 방식으로 HTML에 직접 삽입 -- **주의**: `ag-bridge-ports.json`도 같은 이유로 XHR 로딩 불가. 모든 렌더러 스크립트/데이터는 HTML 인라인으로 전달해야 함 - -### [2026-03-08] Renderer 포트 디스커버리 — ag-bridge-ports.json XHR 실패 -- **증상**: `[GB Observer] Port discovery timeout after 2min` — 렌더러가 bridge 포트를 찾지 못함 -- **원인**: 렌더러 스크립트가 `./ag-bridge-ports.json`을 동기 XHR로 읽으려 하나, `vscode-file://` 프로토콜이 `.json` 파일 서빙 거부 -- **해결**: (1) 프로젝트명 해시 기반 **결정론적 포트** 사용 (`gravity_control→34332`), (2) 스크립트 생성 시 포트를 `HARDCODED_PORT=${port}`로 직접 삽입 -- **주의**: `server.listen(0)` 랜덤 포트 → 매 재시작마다 변경되어 렌더러와 불일치. 결정론적 포트는 `EADDRINUSE` 시 랜덤 폴백 필요 - -### [2026-03-08] Extension 컴파일 경로 != 설치 경로 -- **증상**: `npm run compile` 후 Extension 동작이 변하지 않음 -- **원인**: `npm run compile`은 `extension/out/extension.js`에만 빌드. Antigravity는 `~/.antigravity/extensions/variet.gravity-bridge-X.X.X/out/extension.js`에서 로드 -- **해결**: 컴파일 후 반드시 설치 경로로 수동 복사하거나, `vsce package` → VSIX 재설치 -- **주의**: `extension/out/` ≠ 실행 경로. 항상 설치 경로 확인 필요 - -### [2026-03-08] Electron 메인 프로세스 체크섬 캐시 — Reload Window 불충분 -- **증상**: product.json 체크섬 업데이트 + HTML 패치 후 `Reload Window` → 패치 미적용 -- **원인**: Electron 메인 프로세스가 시작 시 product.json 체크섬을 메모리에 캐시. `Reload Window`는 렌더러만 재시작하므로 캐시된 구 체크섬 사용 -- **해결**: Antigravity를 **완전 종료 후 재시작** 필요 (File → Exit 후 재실행) -- **주의**: `Reload Window` ≠ 앱 재시작. 체크섬 변경 시 항상 풀 재시작 필요 - -### [2026-03-08] Renderer 동기 XHR — Electron 보안 정책 차단 -- **증상**: `tryPing()` 함수가 동기 `XMLHttpRequest`로 HTTP bridge에 연결 시도 → 타임아웃 -- **원인**: Electron 렌더러 프로세스에서 동기 XHR이 보안 정책에 의해 차단됨 -- **해결**: `fetch()` + `AbortSignal.timeout(2000)` 비동기 방식으로 교체 (`tryPingAsync`) -- **주의**: `async/await` 사용 불가 (ES5 환경). `.then()` 체이닝으로 구현 - -### [2026-03-08] DOM Observer — Run 버튼 감지 불가 (webview iframe 격리) -- **증상**: Allow Once/Allow This Conversation는 감지되나 Run/Accept 버튼은 감지 안 됨 -- **원인**: Trust/permission 버튼은 워크벤치 외부 DOM에 렌더링, Run/Accept는 **Antigravity 채팅 webview iframe** 내부의 별도 DOM에 렌더링. 렌더러 스크립트의 `document.querySelector()`는 iframe 내부 접근 불가 -- **해결**: Run 버튼은 DOM Observer가 아닌 **`latestToolCallStep` RPC 기반** 즉시 감지로 대체 -- **주의**: webview iframe에 스크립트 주입은 Electron `executeJavaScript()`로 가능하나, 현재 RPC 방식이 더 안정적 - -### [2026-03-08] Accept all/Reject all 리뷰 바 — agent 패널 밖 DOM -- **증상**: 코드 변경 리뷰 바(Accept all/Reject all)가 DOM Observer에 감지 안 됨 -- **원인**: `scan()` 함수가 `findPanel()` (`.antigravity-agent-side-panel` 등) 내부만 검색. 리뷰 바는 에디터/notification 영역에 렌더링되어 패널 밖에 있음 -- **해결**: `scan()` 검색 범위를 `document.body` 전체로 확장, `Accept all` / `Reject all` 패턴 추가 -- **주의**: 패널+body 이중 검색 시 dedupe 필요 (같은 버튼이 두 번 잡힐 수 있음) - -### [2026-03-08] GetCascadeTrajectorySteps — cascadeId 파라미터 발견 -- **증상**: `GetCascadeTrajectorySteps`에 `trajectoryId` 파라미터 → 500 "trajectory not found" -- **원인**: 파라미터명이 `trajectoryId`가 아니라 **`cascadeId`**. 값은 `GetAllCascadeTrajectories.trajectorySummaries`의 맵 키(세션 ID) -- **해결**: `{ cascadeId: sessionId }`로 호출 → 전체 step 배열 반환 성공 -- **주의**: `latestToolCallStep` 필드는 `GetAllCascadeTrajectories` 응답에 **존재하지 않음** (KI 오류) - -### [2026-03-08] Step 구조 — CORTEX_STEP_STATUS_WAITING 즉시 감지 -- **증상**: stall-based 감지(100초)가 너무 느림 -- **원인**: 이제 `GetCascadeTrajectorySteps`로 최신 step의 status를 직접 확인 가능 -- **해결**: stall 5초 후 step probe → `CORTEX_STEP_STATUS_WAITING` 확인 → 즉시 pending 생성 -- **Step 구조**: `{type: "CORTEX_STEP_TYPE_RUN_COMMAND", status: "CORTEX_STEP_STATUS_WAITING", metadata: {toolCall: {name, argumentsJson}}, runCommand, requestedInteraction}` -- **주의**: 775-step 하드 리밋은 여전히 존재. 긴 세션에서는 fallback(40초) 사용 - -### [2026-03-08] Extension 재설치 안전성 — 자동 패치 메커니즘 -- **증상**: Antigravity 삭제 후 재설치 시 렌더러 스크립트가 동작 안 함 -- **원인**: 재설치 시 HTML/product.json이 원본으로 리셋됨 -- **해결**: Extension의 `setupApprovalObserver()`가 **자동으로** 모든 패치를 수행: - 1. `workbench.html` + `workbench-jetski-agent.html` 인라인 스크립트 삽입 - 2. `product.json` SHA256 체크섬 자동 업데이트 - 3. HTTP bridge 서버 시작 + 결정론적 포트 -- **주의**: 패치 후 반드시 **Antigravity 풀 재시작** 필요 (Reload Window 불가). Extension VSIX만 설치하면 수동 패치 불필요 - -### [2026-03-08] Response 파일 Race Condition — DOM Observer 승인 실패 -- **증상**: Discord에서 승인 → `[RESPONSE] renderer-handled approval` 로그 출력 → 실제 버튼 클릭 안 됨 -- **원인**: `processResponseFile` (파일 감시자)이 response 파일을 즉시 삭제 → renderer의 `pollResponse`가 HTTP `GET /response/:rid`로 조회 시 파일 이미 없음 -- **해결**: DOM observer 소스일 때는 response 파일을 삭제하지 않도록 수정. HTTP endpoint가 renderer에게 서빙한 후 삭제 -- **주의**: non-DOM (stall/step_probe relay)는 watcher에서 삭제해도 됨 - -### [2026-03-08] Renderer 스크립트 소스 혼동 — 3곳의 코드 -- **증상**: `extension.ts`에 BTN-DUMP 추가 → Reload 2번 → 콘솔에 안 나옴 -- **원인**: renderer 코드가 **3곳**에 존재: (1) `extension.ts`의 `generateApprovalObserverScript()` (소스), (2) `ag-sdk-variet-gravity-bridge.js` (배포됨, Reload시 소스에서 재생성), (3) `workbench-jetski-agent.html` inline (HTML, JS파일과 중복로드 방지됨). 직접 JS파일 패치는 Reload시 소스에서 재생성되어 **덮어씌워짐** -- **해결**: 항상 `extension.ts`의 `generateApprovalObserverScript()` 함수를 수정 → 컴파일 → 배포 → Reload -- **주의**: HTML inline은 JS파일이 먼저 로드되어 `window.__agSDK` 가드에 의해 실행 안 됨. 실제 실행되는 것은 JS파일 경로의 스크립트 - -### [2026-03-09] VS Code Accept — SDK 승인 명령이 AG에 미등록 -- **증상**: Discord 승인 → `antigravity.terminalCommand.run` 등 7개 명령 → 모두 `command not found` -- **원인**: SDK(command-bridge.ts)에 정의된 7개 승인 명령이 현재 AG 빌드에 **등록되어 있지 않음**. 활성 시 72개, 세션 중 119개로 동적 등록되지만 승인 관련 명령은 없음 -- **검증**: - - `HandleCascadeUserInteraction` RPC 3 variants → 모두 `socket hang up` - - `ResolveOutstandingSteps` → `run state not found` (500 에러, 실제로는 CANCEL 동작) - - `sendChatActionMessage`, `executeCascadeAction` → 119개 명령 중 미등록 - - 존재하는 approval-like 명령: `agentAcceptAllInFile` (코드 diff), `agentAcceptFocusedHunk` (hunk), `acceptCompletion` (자동완성) — 터미널 승인과 무관 -- **해결**: ~~Renderer DOM Click 구현됨 (미검증)~~ → **v1 검증 실패: webview iframe 격리 확인**. v3 `deepFindButtons()`로 업그레이드 (iframe contentDocument + webview.executeJavaScript + shadow DOM). AG 완전 재시작 후 DOM-DUMP로 접근 가능 여부 확인 필요 -- **주의**: `agentPanel.focus`도 미등록, `agentSidePanel.focus`만 존재 - -### [2026-03-09] Renderer DOM — webview iframe 격리 확인 + v3 deep traversal -- **증상**: Renderer trigger-click이 `document.querySelectorAll('button')`으로 버튼 검색 → Run 버튼 미발견. 감지된 것은 외부 DOM의 trust-level 버튼(`RunAlt+?`)뿐 -- **원인**: Run/Accept 버튼은 AG 채팅 webview iframe (`vscode-webview://` origin) 안에 렌더링. 외부 workbench DOM (`vscode-file://` origin)에서 cross-origin으로 접근 불가 -- **해결**: Renderer v3 `deepFindButtons()` 구현: - 1. Main document 검색 (기존) - 2. `iframe.contentDocument` 접근 시도 (same-origin이면 성공) - 3. `.executeJavaScript()` 접근 시도 (Electron API) - 4. Shadow DOM 재귀 탐색 - → **미검증** (AG 재시작 후 DOM-DUMP 결과 필요) -- **주의**: CDP(Chrome DevTools Protocol)는 **사용자 결정에 의해 명시적으로 거부됨** (`--remote-debugging-port` 필요, 비표준 접근). 표준 DOM API/Electron API 범위 내에서만 해결할 것 - -### [2026-03-09] Deep Inspect HTTP Endpoint — curl로 DOM 분석 트리거 -- **증상**: AG DevTools 콘솔에 붙여넣기 불가 (Chromium 보안 정책) -- **원인**: Electron 렌더러 DevTools에서 `allow pasting`이 SyntaxError 발생 (`Unexpected identifier 'pasting'`) -- **해결**: Extension HTTP bridge에 `/deep-inspect` 엔드포인트 추가. `curl.exe http://127.0.0.1:34332/deep-inspect`로 bridge→renderer→재귀 DOM 분석→결과 JSON 반환. 결과는 `~/.gemini/antigravity/bridge/deep-inspect-result.json`에도 저장됨 -- **주의**: 시작 3초 후 자동 실행 + curl로 재트리거 가능. renderer가 2초마다 `/deep-inspect-trigger` 폴링 - ---- - -### [2026-03-09] workbench.html inline 스크립트 미삽입 — jetski만 패치한 버그 -- **증상**: AG 재시작 후 `/deep-inspect` timeout — renderer v3 스크립트 미로딩 -- **원인**: `setupApprovalObserver()`가 `workbench-jetski-agent.html`에만 inline 삽입하고, `workbench.html`에는 외부 `