Files
gravity_control/docs/approach-history.md

14 KiB

Antigravity Chat Relay — 접근 히스토리

최종 업데이트: 2026-03-07 20:38 KST
목표: Discord ↔ Antigravity IDE 양방향 대화 릴레이


📊 현재 상태 요약

방향 상태 방법
Discord → Antigravity 동작 sendPromptToAgentPanel 명령어
Antigravity → Discord ⚠️ 부분 getDiagnostics.summary (영어 제목만)
실제 AI 텍스트 릴레이 미해결 모든 RPC 차단됨

Phase 1: Discord → Antigravity (채팅 전송) — 해결

시도 1: 채팅 입력 시뮬레이션

  • vscode.commands.executeCommand('workbench.action.chat.open') + 클립보드 붙여넣기
  • 결과: 채팅 패널은 열리지만 텍스트 입력 안 됨
  • 커밋: b42475c, 35f39ab, 5780896, 7f81528

시도 2: sendTextToChat API

  • antigravity.sendTextToChat 명령어 사용
  • 결과: 명령어 존재하지만 동작 안 함 (파라미터 불일치)
  • 커밋: e4eb756, c688812, 180dba1, ae0fd78

시도 3: 전체 명령어 열거 → sendPromptToAgentPanel 발견

  • vscode.commands.getCommands(true) → 171개 명령어 덤프
  • antigravity.sendPromptToAgentPanel 발견 → 직접 AI 에이전트에 텍스트 전송
  • 결과: 성공! Discord 메시지 → AI 에이전트 직접 전달
  • 커밋: 8d5e59c

핵심 교훈: 문서화되지 않은 내부 API는 전체 열거 후 시도해야 함


Phase 2: Antigravity → Discord (AI 응답 릴레이) — 미해결

시도 1: 파일 변경 감시 (task.md 등)

  • Brain 디렉토리의 task.md, walkthrough.md 변경 감시
  • 결과: 이 파일들은 AI 대화 텍스트가 아님! artifact(계획서, 보고서)만 저장됨
  • 사용자 피드백: "md파일은 참고일뿐. 실제 AI가 대답한 것이 전달되어야"
  • 커밋: befa5d7

시도 2: getManagerTrace / getWorkbenchTrace 명령어

  • antigravity.getManagerTrace, antigravity.getWorkbenchTrace 실행
  • 결과: 양쪽 모두 undefined 반환
  • 커밋: 150967d

시도 3: getDiagnosticsrecentTrajectories 발견 → LS ConnectRPC 시도

  • getDiagnostics → 대형 JSON (LS PID, CSRF 토큰, recentTrajectories 포함)
  • 발견: LS 프로세스(language_server_windows_x64.exe) PID=7856, CSRF 토큰, 포트 3274
  • 커밋: 952883d

시도 4: ConnectRPC GetTrajectoryDescriptions (잘못된 메서드명)

  • exa.language_server_pb.LanguageServerService/GetTrajectoryDescriptions
  • 결과: HTTP 404 — 메서드명이 잘못됨
  • 커밋: 91b3a7e

시도 5: HTTPS 프로토콜 문제 → HTTP임을 발견

  • LS가 HTTPS를 요구한다고 오인 → "Client sent HTTP to HTTPS server" 에러
  • 실제로는 HTTP 포트 3274
  • 결과: 프로토콜 수정 후 연결 성공 (Heartbeat OK)
  • 커밋: f2ed431

시도 6: Go 바이너리 분석 → 정확한 RPC 메서드명 추출

  • Python으로 language_server_windows_x64.exe에서 100+ RPC 메서드 추출
  • 발견:
    • Heartbeat ← 연결 확인 (200 OK)
    • GetUserTrajectoryDescriptions ← trajectory 목록 (데이터 반환)
    • GetCascadeTrajectorySteps ← 대화 단계 (아래 참조)
  • 커밋: be6fae7, e4b98af

시도 7: GetCascadeTrajectorySteps + trajectoryId (from GetUserTrajectoryDescriptions)

  • GetUserTrajectoryDescriptions{trajectoryId: "9807a8ec...", current: true} 반환
  • GetCascadeTrajectorySteps({trajectoryId: "9807a8ec..."}) 호출
  • 결과: "trajectory not found" — workspace-level ID이지 conversation ID가 아님!
  • 커밋: b6adeff

시도 8: 5가지 RPC 메서드+필드 조합 시도

  1. GetCascadeTrajectorySteps({trajectoryId}) trajectory not found
  2. GetCascadeTrajectory({trajectoryId}) trajectory not found
  3. GetCascadeTrajectorySteps({cascadeId}) trajectory not found
  4. GetCascadeTrajectory({cascadeId}) trajectory not found
  5. GetUserTrajectory({trajectoryId}) not_found
  • 결론: GetUserTrajectoryDescriptionstrajectoryId로는 단계 데이터를 가져올 수 없음
  • 커밋: dfc76a9

⚠️ 시도 9: getDiagnostics.recentTrajectoriesgoogleAgentId + lastStepIndex

  • getDiagnosticsrecentTrajectories에 cascade-level googleAgentId, lastStepIndex, summary 존재
  • 결과:
    • lastStepIndex 변화 감지 가능 (step 42 → 48 등)
    • summary 추출 가능 (하지만 영어 대화 제목뿐 "Greeting User")
    • 실제 AI 응답 텍스트는 없음
  • 커밋: 0c96645

시도 10: latest trajectory만 추적 → 새 대화 놓침

  • trajectories[length-1] 하나만 추적
  • 결과: 새 대화의 step 변화를 놓침
  • 수정: 모든 trajectory 추적으로 변경
  • 커밋: 41f90b3

⚠️ 시도 11: 새 대화 감지 → summary 릴레이 성공

  • 새 trajectory 출현 (step > 0) 감지 → summary를 Discord에 전달
  • 결과: Discord에서 메시지 수신! 하지만 "Greeting User" (영어 제목)
  • 사용자 피드백: "대화창은 한글인데 돌아온건 영어야"
  • 커밋: 7415ab7

시도 12: LoadTrajectory + 기존 RPC (googleAgentId 키로 재시도)

  1. LoadTrajectory({trajectoryId}) internal: failed to load trajectory
  2. LoadTrajectory({googleAgentId}) internal: failed to load trajectory
  3. GetCascadeTrajectory({googleAgentId}) trajectory not found
  4. GetCascadeTrajectorySteps({googleAgentId}) trajectory not found
  • 결론: 모든 trajectory/cascade RPC가 외부 호출자에게 차단됨
  • 커밋: b0c2f86

시도 13: Brain 디렉토리에서 대화 텍스트 검색

  • 짧은 대화 (e8238b5e)의 brain 폴더 → 빈 폴더 (파일 없음)
  • .system_generated/logs/ → 존재하지 않음 (모든 대화)
  • .system_generated/click_feedback/ → 브라우저 스크린샷만
  • 결론: Brain 디렉토리에는 AI 대화 텍스트가 저장되지 않음

시도 14: getDiagnostics.extensionLogs에서 AI 텍스트 추출

  • extensionLogs에서 notify_user 패턴, content 블록, 한국어 텍스트 검색
  • 결과: 실패 — summary fallback 트리거됨, extensionLogs에 AI 응답 텍스트 없음
  • 커밋: 0d90b25

🔑 확인된 사실

동작하는 것

항목 상태 비고
sendPromptToAgentPanel Discord → AI 전달 완벽 동작
LS Heartbeat (port 3274) ConnectRPC 연결 확인
GetUserTrajectoryDescriptions workspace-level trajectory 목록 반환
getDiagnostics.recentTrajectories cascade-level 메타데이터 (googleAgentId, summary, lastStepIndex)
Step count 변화 감지 lastStepIndex diff로 새 응답 감지
Summary를 Discord에 전달 영어 대화 제목만 (실제 AI 텍스트 아님)

동작하지 않는 것 (차단됨)

항목 에러 시도 횟수
GetCascadeTrajectorySteps trajectory not found 6+
GetCascadeTrajectory trajectory not found 4+
LoadTrajectory internal: failed to load 2
GetUserTrajectory not_found 1
Brain 디렉토리 대화 텍스트 파일 없음 1
getManagerTrace undefined 1
getWorkbenchTrace undefined 1

🔬 SDK / Extension.js 심층 분석 결과

extension.js (2.9MB minified) 정적 분석 (2026-03-07 20:50 KST)

핵심 아키텍처 발견

항목 발견
LS 통신 LanguageServerClient.getInstance().client.XXX() — raw HTTP가 아닌 내부 client 객체
채팅 패널 ChatPanelProvider 클래스 → WebView 관리
WebView 통신 sendActionToChatPanel() → LS → WebView
WebView → Host onDidReceiveMessage({type:'update', content:...})
내보내기 API 없음 — exports는 npm 라이브러리뿐
명령어 21개 등록, 대화 접근 명령어 없음

ChatActionType 열거형 (확인된 값)

액션 용도
toggleFocus 채팅 포커스 토글
openChatPanel 채팅 패널 열기
CodeBlockMention 코드 블록 멘션
FileMention 파일 멘션
setCascadeId cascade ID 설정
setApiKey API 키 설정
pollMcpServerStates MCP 서버 폴링
updateUserStatus 사용자 상태 업데이트
updateStateForCascadeFilesWithInIdeDiffs IDE diff 상태 업데이트

핵심 통신 경로 (확인됨)

Extension Host  →  LanguageServerClient.client  →  LS Process (ConnectRPC)
                            ↕
                    ChatPanelProvider  →  WebView (chat.js)
                            ↕
              onDidReceiveMessage / postMessage

⚠️ 우리의 raw HTTP 접근이 실패한 이유: LS Client와 raw HTTP는 다른 인증/세션 컨텍스트를 사용. LS Client는 Extension Host 프로세스 내에서 초기화되며, 자체 gRPC 채널을 가짐. Raw HTTP는 CSRF 토큰으로 인증하지만, trajectory 데이터 접근에는 추가 세션 컨텍스트 필요.


🚧 아직 시도하지 않은 접근법

1. StreamCascadeReactiveUpdates (서버 스트리밍 RPC)

  • ConnectRPC 서버-사이드 스트리밍 — 실시간 업데이트 구독
  • 단순 요청/응답이 아닌 SSE/chunked 방식 필요
  • 난이도: 높음 (스트리밍 프로토콜 구현 필요)

2. Antigravity WebView 메시지 인터셉트

  • 채팅 패널 WebView ↔ Extension Host 사이의 postMessage 후킹
  • VS Code API의 window.registerWebviewViewProvider 또는 WebView panel 접근
  • 난이도: 높음 (내부 WebView 참조 필요)

3. Extension Host 콘솔 출력 캡처

  • console.log 출력에서 AI 응답 텍스트 패턴 검색
  • OutputChannel이나 DevTools 콘솔에서 직접 캡처
  • 난이도: 중간

4. LS 네트워크 트래픽 스니핑

  • LS ↔ Extension Host 사이의 네트워크 트래픽 캡처
  • Wireshark/mitmproxy 등으로 실제 데이터 흐름 확인
  • 난이도: 중간 (디버깅 단계, 프로덕션 불가)

5. Antigravity 확장의 내부 API 직접 접근

  • vscode.extensions.getExtension('google.antigravity') → exports 탐색
  • 내부 lspClient 또는 대화 저장소에 직접 접근
  • 난이도: 중간 (exports가 노출되어 있다면)

6. IndexedDB / LevelDB 대화 저장소

  • VS Code는 IndexedDB(웹) 또는 LevelDB(네이티브)에 데이터 저장
  • %APPDATA%/Antigravity/ 하위의 DB 파일 직접 읽기
  • 난이도: 높음 (DB 스키마 역설계 필요)

7. workbench.action.chat.openEditSession 등 채팅 내보내기 명령

  • VS Code 내장 채팅 관련 명령어로 대화 내용 추출
  • 난이도: 낮음 (시도 안 해봄)

📝 핵심 교훈

  1. trajectoryId ≠ 대화 ID: GetUserTrajectoryDescriptionstrajectoryId는 workspace-level, getDiagnosticsgoogleAgentId는 cascade-level — 둘 다 RPC 단계 데이터 접근에 실패
  2. LS는 외부 HTTP 호출 차단: Heartbeat, GetUserTrajectoryDescriptions는 동작하지만, 실제 대화 데이터를 반환하는 모든 RPC는 차단됨
  3. Brain 디렉토리 = artifacts만: 실제 AI 대화 텍스트는 brain에 저장되지 않음
  4. summary = 영어 대화 제목: getDiagnostics.recentTrajectories.summary는 AI가 자동 생성한 제목이지 실제 응답이 아님
  5. 반복 실수: 같은 RPC를 다른 필드명으로 반복 시도 (trajectoryId, cascadeId, googleAgentId, conversationId → 모두 실패)

🎯 체계적 시도 계획 (우선순위순)

아래 각 접근법을 순서대로 시도. 각 시도는 별도 프로브 코드로, 결과 로그 확인 후 다음 단계 진행.

Trial A: Extension API exports 탐색 (난이도: 낮음)

방법: vscode.extensions.getExtension('google.antigravity').exports 탐색
SDK 분석 결과: exports는 npm 라이브러리만 (63개). 유용한 API 없을 것으로 예상
그래도 시도하는 이유: 런타임에서만 노출되는 API가 있을 수 있음 (minified 코드에서 못 찾은 것)
상태: 🔄 프로브 코드 빌드 완료, 설치 대기 중


Trial B: sendChatActionMessage 명령어 활용 (난이도: 중, 새로 발견)

방법: antigravity.sendChatActionMessage 명령어로 SendActionToChatPanelRequest JSON 전달
SDK 분석 근거: extension.js에서 registerCommand(i.SEND_CHAT_ACTION_MESSAGE, async e => { ... sendActionToChatPanel(e) }) 확인
프로브 코드:

// SendActionToChatPanelRequest JSON 구조로 호출
await vscode.commands.executeCommand('antigravity.sendChatActionMessage', 
  JSON.stringify({ actionType: 'toggleFocus', payload: [] })
);

성공 기준: 채팅 패널 상태 변경이나 데이터 반환
기대: 직접적인 대화 텍스트 접근보다는 채팅 패널 제어에 가까움


Trial C: VS Code Chat History API (난이도: 낮음)

방법: chat 관련 내보내기/히스토리 명령어 탐색
프로브 코드: chat export/history/conversation 명령어 필터링 (Trial A 프로브에 포함)
상태: 🔄 Trial A와 함께 프로브 중


Trial D: StreamCascadeReactiveUpdates (난이도: 높음, 기대확률: 높)

방법: ConnectRPC 서버-사이드 스트리밍으로 실시간 업데이트 구독

프로브 코드:

// ConnectRPC streaming: POST + Transfer-Encoding: chunked
// 또는 SSE endpoint
const streamRes = await fetch(`http://127.0.0.1:3274/exa.language_server_pb.LanguageServerService/StreamCascadeReactiveUpdates`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/connect+proto', 'x-codeium-csrf-token': csrfToken },
  body: Buffer.from([0, 0, 0, 0, 0]) // empty protobuf message
});
// Read streaming response chunks

성공 기준: 스트림에서 AI 응답 텍스트가 실시간으로 수신됨

실패 시: Trial E 진행


Trial E: Electron IPC / DevTools Protocol 인터셉트 (난이도: 높음, 기대확률: 높)

방법: Electron의 IPC 또는 Chrome DevTools Protocol로 WebView 메시지 캡처

프로브 코드:

// DevTools Protocol로 WebView의 console.log/network 캡처
// 또는 Electron의 webContents.getAllWebContents()로 채팅 패널 접근

성공 기준: WebView ↔ Extension Host 사이 메시지에서 AI 텍스트 추출

실패 시: 완전히 다른 아키텍처 접근 필요 (예: 화면 OCR, Accessibility API 등)