Compare commits
4 Commits
2eb1fbb6b7
...
e4f674ec9f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4f674ec9f | ||
|
|
47c0602427 | ||
|
|
75762964e3 | ||
|
|
d2023321bd |
@@ -27,8 +27,26 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### [2026-04-08] [Discord Bot] Channel Deletion Cache Desync
|
||||||
|
- **증상**: 봇이 켜져 있는 상태에서 Discord 채널(g-project-name)을 삭제하면, 봇이 삭제를 인지하지 못하고 새 채널을 생성하지 않으며 메시지도 증발함.
|
||||||
|
- **원인**: ot.py의 self.project_channels 딕셔너리에 채널 객체가 캐시되어 있어, API 호출 없이 캐시된(삭제된) 채널로 메시지를 보내려 시도하다 404 에러 발생 후 실패함.
|
||||||
|
- **해결**: 채널 맵핑이 꼬였을 때는 **Python 봇(Docker 컨테이너)을 재시작**하여 캐시를 초기화하고 채널 목록을 새로 갱신하게 함.
|
||||||
|
- **주의**: 채널 관리는 캐시에 의존하기 때문에 강제로 Discord UI에서 채널을 지웠을 때는 반드시 봇을 재구동해야 함.
|
||||||
|
|
||||||
|
### [2026-04-08] [Extension] Multiple Workspace LS Cross-Connection
|
||||||
|
- **증상**: ariet-llm 창에서 켰으나 gravity_control의 백그라운드 구동 중인 LS에 연결되어 자기 자신 창의 신호를 잡지 못함.
|
||||||
|
- **원인**: 여러 VS Code 창을 띄웠을 때 어떤 창에서는 Antigravity 패널을 누르지 않아 전용 LS가 시작되지 않음. ixLSConnection()이 자기 몫의 LS를 찾지 못하고 fallback으로 기존에 떠 있던 다른 창의 LS에 연결됨.
|
||||||
|
- **해결**: 대상 창에서 Developer: Reload Window 실행 후 **사이드바의 로컬 Antigravity 챗봇 패널을 한 번 열어** 자신의 LS 프로세스를 띄운 뒤에 Gravity Bridge를 Start함.
|
||||||
|
- **주의**: LS는 자동으로 시작되지 않고 사용자가 채팅 패널을 한 번 클릭/활성화해야만 Spawn 됨.
|
||||||
|
|
||||||
## 🔴 Active/Recent Issues
|
## 🔴 Active/Recent Issues
|
||||||
|
|
||||||
|
### [2026-04-09] [Extension] Agent UI Native Migration & CodeLens False Positive Filter
|
||||||
|
- **증상**: UI Tailwind/Native 마이그레이션 적용 후, Discord 브릿지로 신호가 전혀 전송되지 않음
|
||||||
|
- **원인**: Agent 패널이 탭/에디터 본문에 직접 렌더링되면서, 기존 오작동 방지 로직(`if (b.closest('.monaco-editor'))`)에 패널 전체 버튼이 포착되어 무시됨
|
||||||
|
- **해결**: 너무 광범위한 `.monaco-editor` 방어를 해제하고, 코드 렌즈 고유 컨테이너인 `.codelens-decoration` 내부일 경우에만 무시하도록 핀포인트 수정
|
||||||
|
- **주의**: DOM 옵저버 필터 조건 작성 시 래퍼 클래스는 UI 디자인 개편(Native, Editor Tab 등 위치 변경)에 매우 취약함. 가장 구체적인 내부 노드 클래스나 타겟 고유 속성을 통해 필터링할 것
|
||||||
|
|
||||||
### [2026-03-31] [step-probe] GetAllCascadeTrajectories 10-Item Hard Limit (Signal Drop)
|
### [2026-03-31] [step-probe] GetAllCascadeTrajectories 10-Item Hard Limit (Signal Drop)
|
||||||
- **증상**: `guitar_score` 등에서 활성화된 세션의 디스코드 승인 신호를 "계속해서" 잡지 못함. (WS 60초 타임아웃보다 더 치명적으로 신호가 아예 가지 않음)
|
- **증상**: `guitar_score` 등에서 활성화된 세션의 디스코드 승인 신호를 "계속해서" 잡지 못함. (WS 60초 타임아웃보다 더 치명적으로 신호가 아예 가지 않음)
|
||||||
- **원인**: Extension이 활성 세션을 찾기 위해 호출하는 `GetAllCascadeTrajectories` LS API가 `{}`(빈 인자)로 호출될 때, 기본적으로 **10개의 세션만 반환하는 하드 리밋(Pagination Limit)**이 걸려있음. 이로 인해 작업 내역이 누적되면 수많은 최신/진행 중 세션들이 10개 목록에서 밀려나 누락됨. 익스텐션은 세션이 없다고 판단해 강제로 `IDLE` 모드에 진입하며, 승인 대기열(WAITING) 자체를 검사하지 않게 됨.
|
- **원인**: Extension이 활성 세션을 찾기 위해 호출하는 `GetAllCascadeTrajectories` LS API가 `{}`(빈 인자)로 호출될 때, 기본적으로 **10개의 세션만 반환하는 하드 리밋(Pagination Limit)**이 걸려있음. 이로 인해 작업 내역이 누적되면 수많은 최신/진행 중 세션들이 10개 목록에서 밀려나 누락됨. 익스텐션은 세션이 없다고 판단해 강제로 `IDLE` 모드에 진입하며, 승인 대기열(WAITING) 자체를 검사하지 않게 됨.
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
# 2026-04-08
|
# 2026-04-08
|
||||||
|
|
||||||
| NNN | HH:MM | 작업 설명 | `커밋해시` | 상태 |
|
| NNN | HH:MM | 작업 설명 | `커밋해시` | 상태 |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| 004 | 14:00 | SafeToAutoRun 알림 누락 복구 (v0.5.18) | `8f2a1b3` | ✅ |
|
| 004 | 14:00 | SafeToAutoRun 알림 누락 복구 (v0.5.18) | `8f2a1b3` | ✅ |
|
||||||
| 005 | 16:30 | SafeToAutoRun pending skip으로 인한 데드락 원인 파악 및 롤백 | `13f13ee` | ✅ |
|
| 005 | 16:30 | SafeToAutoRun pending skip으로 인한 데드락 원인 파악 및 롤백 | `13f13ee` | ✅ |
|
||||||
| 006 | 07:30 | SafeToAutoRun 데드락 완전 해결을 위한 Agnostic Bridge 도입 및 프리징 방어 (v0.5.20) | `임시해시` | ✅ |
|
| 006 | 07:30 | SafeToAutoRun 데드락 완전 해결을 위한 Agnostic Bridge 도입 및 프리징 방어 (v0.5.20) | `임시해시` | ✅ |
|
||||||
|
| 007 | 17:57 | Gravity Bridge 안정화: 중복 알림(SafeToAutoRun) 제거 설계 확정 및 Discord 봇 캐시/로컬 LS 크로스매칭 증상 디버깅 완료 | \-\ | ✅ |
|
||||||
|
|||||||
6
docs/devlog/2026-04-09.md
Normal file
6
docs/devlog/2026-04-09.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# 2026-04-09
|
||||||
|
|
||||||
|
| NNN | HH:MM | 작업 설명 | `커밋해시` | 상태 |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| 001 | 21:55 | Agent UI Tailwind/Native 마이그레이션 대응 (DOM 옵저버 구조 개편) | `HEAD` | ✅ |
|
||||||
|
| 002 | 22:30 | Agent UI 버튼 무시 버그 긴급수정 (CodeLens 필터교정) | `HEAD` | ✅ |
|
||||||
18
docs/devlog/entries/20260408-007.md
Normal file
18
docs/devlog/entries/20260408-007.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Gravity Bridge 알림 최적화 및 연동 디버깅 완료
|
||||||
|
|
||||||
|
- **시간**: 2026-04-08 17:00~17:55
|
||||||
|
- **Commit**: `pending`
|
||||||
|
- **Vikunja**: 대상 작업 맵핑 예정
|
||||||
|
|
||||||
|
## 결정 사항
|
||||||
|
- `SafeToAutoRun` 시 `step-probe.ts`에서 날리던 **"⚡ 자동 실행됨"** 알림은 과감하게 완전히 제거하였습니다. 파이썬 봇이 이미 "🤖 자동 승인됨" Embed를 송출하고 있으므로 디자인 철학(익스텐션은 중립적인 릴레이 역할만 수행하고, 비즈니스 판정 알림은 중앙 봇이 담당)에 부합합니다.
|
||||||
|
- `extension.ts`의 `writeChatSnapshot` 의존성을 줄여 트래픽 낭비와 중복 노이즈를 해소했습니다.
|
||||||
|
|
||||||
|
## 핵심 디버깅 (Troubleshooting)
|
||||||
|
- **`variet-llm` 프로젝트 연동 실패 이슈:**
|
||||||
|
1. `variet-llm` 창을 열었으나 채팅 패널을 열지 않아 안티그래비티 전용 언어 서버(LS)가 띄워져 있지 않은 상태에서 브릿지를 켬. 브릿지가 엉뚱하게 `gravity_control` LS에 바인딩 됨.
|
||||||
|
2. 사용자가 Discord에서 `variet-llm` 채널을 삭제해 버렸는데, 파이썬 봇(`bot.py`)은 캐시를 가지고 있어서 자신이 파괴된 채널을 대상으로 계속 통신을 시도하며 새 채널을 파지 않음 (HTTP 404).
|
||||||
|
3. 로컬 윈도우 재시작 및 도커(`docker-compose restart`) 컨테이너 재가동을 통해 **봇 프로세스 캐시 초기화** → 채널 자동 재생성, 완벽 디버깅에 성공했습니다.
|
||||||
|
|
||||||
|
## 미완료
|
||||||
|
- 없음. 모두 성공적으로 동작 중.
|
||||||
18
docs/devlog/entries/20260409-001.md
Normal file
18
docs/devlog/entries/20260409-001.md
Normal file
@@ -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` 등으로 완화.
|
||||||
|
|
||||||
|
## 미완료
|
||||||
|
- 없음
|
||||||
15
docs/devlog/entries/20260409-002.md
Normal file
15
docs/devlog/entries/20260409-002.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Agent UI 버튼 무시(Discard) 버그 핫픽스
|
||||||
|
|
||||||
|
- **시간**: 2026-04-09 22:10~22:35
|
||||||
|
- **Commit**: `pending`
|
||||||
|
- **Vikunja**: 새로 생성 후 완료 예정
|
||||||
|
|
||||||
|
## 트러블슈팅 및 결정 사항
|
||||||
|
- **이슈**: Native UI 마이그레이션 직후 버튼을 눌러도 브릿지로 신호가 전혀 가지 않는 버그 접수
|
||||||
|
- **원인 분석**:
|
||||||
|
1. `extension.log` 확인 결과 `[HTTP] pending` 자체가 생성되지 않음 (브릿지 자체에 도달하지 않음).
|
||||||
|
2. DOM observer가 수집한 버튼이 `b.closest('.monaco-editor')` 필터 조건에 무조건 걸려서 버려지는 것이었음. Native 전환 후 채팅창이 에디터 탭 내부에 렌더링되면서 `.monaco-editor` 내부 자식이 됨.
|
||||||
|
- **결정**: 기존의 `b.closest('.monaco-editor')` 방어 로직을 폐기하고 실제 CodeLens 버튼 고유의 클래스 `.codelens-decoration`를 명시하도록 변경하여 구조 변화에 강건해지도록 개선 완료. `0.5.22` VSIX 재배포.
|
||||||
|
|
||||||
|
## 미완료
|
||||||
|
- 없음 (검증은 유저 몫으로 인계)
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "gravity-bridge",
|
"name": "gravity-bridge",
|
||||||
"displayName": "Gravity Bridge",
|
"displayName": "Gravity Bridge",
|
||||||
"description": "Antigravity ↔ Discord 브리지 연동 확장",
|
"description": "Antigravity ↔ Discord 브리지 연동 확장",
|
||||||
"version": "0.5.20",
|
"version": "0.5.22",
|
||||||
"publisher": "variet",
|
"publisher": "variet",
|
||||||
"engines": {
|
"engines": {
|
||||||
"vscode": "^1.100.0"
|
"vscode": "^1.100.0"
|
||||||
|
|||||||
@@ -273,16 +273,16 @@ export function generateApprovalObserverScript(_port: number): string {
|
|||||||
// ONLY positive triggers should initiate a pending request group.
|
// ONLY positive triggers should initiate a pending request group.
|
||||||
// Negative/secondary buttons (Deny, Reject, Dismiss) will be collected as siblings.
|
// Negative/secondary buttons (Deny, Reject, Dismiss) will be collected as siblings.
|
||||||
var PATS=[
|
var PATS=[
|
||||||
{re:/^Run/i, type:'terminal_command'},
|
{re:/^(?:Always\s*)?Run/i, type:'terminal_command'},
|
||||||
{re:/^Accept all/i, type:'diff_review'},
|
{re:/^(?:Always\s*)?Accept all/i, type:'diff_review'},
|
||||||
{re:/^Accept/i, type:'agent_step'},
|
{re:/^(?:Always\s*)?Accept/i, type:'agent_step'},
|
||||||
{re:/^(?:Always )?Allow/i, type:'permission'},
|
{re:/^(?:Always\s*)?Allow/i, type:'permission'},
|
||||||
{re:/^Approve/i, type:'agent_step'},
|
{re:/^(?:Always\s*)?Approve/i, type:'agent_step'},
|
||||||
{re:/^Retry/i, type:'error_recovery'},
|
{re:/^Retry/i, type:'error_recovery'},
|
||||||
];
|
];
|
||||||
|
|
||||||
// ALL actionable button patterns (for grouping siblings in same container)
|
// 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
|
// 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];
|
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',
|
'.react-app-container',
|
||||||
'[class*="agent-panel"]',
|
'[class*="agent-panel"]',
|
||||||
'[class*="agentPanel"]',
|
'[class*="agentPanel"]',
|
||||||
|
'.chat-body',
|
||||||
|
'.interactive-session',
|
||||||
|
'[class*="sidebar"]',
|
||||||
];
|
];
|
||||||
for(var i=0;i<selectors.length;i++){
|
for(var i=0;i<selectors.length;i++){
|
||||||
var el=document.querySelector(selectors[i]);
|
var el=document.querySelector(selectors[i]);
|
||||||
@@ -419,9 +422,9 @@ export function generateApprovalObserverScript(_port: number): string {
|
|||||||
var matchedType=null;
|
var matchedType=null;
|
||||||
for(var p=0;p<PATS.length;p++){
|
for(var p=0;p<PATS.length;p++){
|
||||||
if(PATS[p].re.test(txt)){
|
if(PATS[p].re.test(txt)){
|
||||||
// STRUCTURAL CONSTRAINT: If we are scanning the main VS Code Editor body, reject Agent/Terminal buttons
|
// STRUCTURAL CONSTRAINT: To prevent freezing on CodeLens 'Run' or 'Accept' false positives within editor files,
|
||||||
// to prevent freezing on CodeLens 'Run' or 'Accept' false positives.
|
// ignore these if found inside a CodeLens container.
|
||||||
if (isVSCodeMainWindow && isBodyRoot && PATS[p].type !== 'diff_review' && PATS[p].type !== 'permission') {
|
if (b.closest('.codelens-decoration') && PATS[p].type !== 'diff_review' && PATS[p].type !== 'permission') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Prevent duplicates if already scanned via panel root
|
// Prevent duplicates if already scanned via panel root
|
||||||
@@ -651,7 +654,7 @@ export function generateApprovalObserverScript(_port: number): string {
|
|||||||
if(!d.action)return;
|
if(!d.action)return;
|
||||||
log('🔔 TRIGGER-CLICK received: action='+d.action);
|
log('🔔 TRIGGER-CLICK received: action='+d.action);
|
||||||
|
|
||||||
var approveRe=[/^Run/i,/^Accept/i,/^Accept all/i,/^(?:Always )?Allow/i,/^Approve/i,/^Continue$/i,/^Proceed$/i,/^Retry$/i];
|
var approveRe=[/^(?:Always\s*)?Run/i,/^(?:Always\s*)?Accept/i,/^(?:Always\s*)?Accept all/i,/^(?:Always\s*)?Allow/i,/^(?:Always\s*)?Approve/i,/^Continue$/i,/^Proceed$/i,/^Retry$/i];
|
||||||
var rejectRe=[/^Reject/i,/^Cancel$/i,/^Deny$/i,/^Stop$/i,/^Decline$/i,/^Dismiss$/i];
|
var rejectRe=[/^Reject/i,/^Cancel$/i,/^Deny$/i,/^Stop$/i,/^Decline$/i,/^Dismiss$/i];
|
||||||
var patterns=(d.action==='approve')?approveRe:rejectRe;
|
var patterns=(d.action==='approve')?approveRe:rejectRe;
|
||||||
var emoji=(d.action==='approve')?'✅':'❌';
|
var emoji=(d.action==='approve')?'✅':'❌';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* Step Probe Module - SDK polling, response handling, approval strategies.
|
* Step Probe Module - SDK polling, response handling, approval strategies.
|
||||||
* All shared state accessed through BridgeContext.
|
* All shared state accessed through BridgeContext.
|
||||||
* Extracted from extension.ts.
|
* Extracted from extension.ts.
|
||||||
@@ -591,10 +591,6 @@ function setupMonitor() {
|
|||||||
source: 'step_probe',
|
source: 'step_probe',
|
||||||
safe_to_auto_run: isSafeToAutoRun,
|
safe_to_auto_run: isSafeToAutoRun,
|
||||||
});
|
});
|
||||||
if (isSafeToAutoRun) {
|
|
||||||
const truncatedCmd = command.length > 500 ? command.substring(0, 500) + '\n...(이하 생략)' : command;
|
|
||||||
ctx.writeChatSnapshot(`⚡ **자동 실행됨** (step ${si})\n\n\`\`\`\n${truncatedCmd}\n\`\`\``);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// NOTE: no break — process ALL parallel WAITING steps
|
// NOTE: no break — process ALL parallel WAITING steps
|
||||||
@@ -667,10 +663,6 @@ function setupMonitor() {
|
|||||||
source: 'step_probe_utf8_offset',
|
source: 'step_probe_utf8_offset',
|
||||||
safe_to_auto_run: isSafeToAutoRun,
|
safe_to_auto_run: isSafeToAutoRun,
|
||||||
});
|
});
|
||||||
if (isSafeToAutoRun) {
|
|
||||||
const truncatedCmd = command.length > 500 ? command.substring(0, 500) + '\n...(이하 생략)' : command;
|
|
||||||
ctx.writeChatSnapshot(`⚡ **자동 실행됨** (step ${actualIndex})\n\n\`\`\`\n${truncatedCmd}\n\`\`\``);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// NOTE: no break — process ALL parallel WAITING steps
|
// NOTE: no break — process ALL parallel WAITING steps
|
||||||
|
|||||||
1
inspect-dump.json
Normal file
1
inspect-dump.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"status":"timeout","message":"Renderer did not respond in 10s. Is the v3 script loaded?"}
|
||||||
50
scratch_parse.py
Normal file
50
scratch_parse.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(r'C:\Users\Variet-Worker\.gemini\antigravity\bridge\deep-inspect-result.json', 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
|
||||||
|
# Print first 50 buttons from nodes
|
||||||
|
count = 0
|
||||||
|
print('=== First 100 Buttons in DOM Nodes ===')
|
||||||
|
for node in data.get('nodes', []):
|
||||||
|
label = node.get('label', 'unknown')
|
||||||
|
btns = node.get('buttons', [])
|
||||||
|
if btns:
|
||||||
|
print(f'\n[Node] {label}')
|
||||||
|
for b in btns:
|
||||||
|
t = b.get('text', '').replace('\n', ' ').strip()
|
||||||
|
hidden = b.get("hidden")
|
||||||
|
cls = b.get("class")
|
||||||
|
if t:
|
||||||
|
print(f' - "{t[:50]}" (Hidden: {hidden}, Class: {cls[:30]})')
|
||||||
|
count += 1
|
||||||
|
if count > 100:
|
||||||
|
break
|
||||||
|
if count > 100:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Print first 50 buttons from webviews
|
||||||
|
count = 0
|
||||||
|
print('\n=== First 100 Buttons in Webviews ===')
|
||||||
|
for probe in data.get('webviewProbes', []):
|
||||||
|
if probe.get('success'):
|
||||||
|
pd = probe.get('data', {})
|
||||||
|
btns = pd.get('buttons', [])
|
||||||
|
label = pd.get('title', 'Unknown Title') + f" (URL: {pd.get('url', 'Unknown URL')})"
|
||||||
|
if btns:
|
||||||
|
print(f'\n[WebviewProbe {probe.get("index")}] {label}')
|
||||||
|
for b in btns:
|
||||||
|
t = b.get('text', '').replace('\n', ' ').strip()
|
||||||
|
hidden = b.get("hidden")
|
||||||
|
cls = b.get("class")
|
||||||
|
if t:
|
||||||
|
print(f' - "{t[:50]}" (Hidden: {hidden}, Class: {cls[:30]})')
|
||||||
|
count += 1
|
||||||
|
if count > 100:
|
||||||
|
break
|
||||||
|
if count > 100:
|
||||||
|
break
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Error reading JSON: {e}')
|
||||||
27
scratch_parse2.py
Normal file
27
scratch_parse2.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(r'C:\Users\Variet-Worker\.gemini\antigravity\bridge\deep-inspect-result.json', 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
|
||||||
|
print(f"Total Nodes: {len(data.get('nodes', []))}")
|
||||||
|
for node in data.get('nodes', []):
|
||||||
|
label = node.get('label', 'unknown')
|
||||||
|
iframes = node.get('iframes', [])
|
||||||
|
webviews = node.get('webviews', [])
|
||||||
|
buttons = node.get('buttons', [])
|
||||||
|
print(f"[Node] {label}")
|
||||||
|
print(f" URL: {node.get('url', '')[:50]}")
|
||||||
|
print(f" Total Elements: {node.get('totalElements', 0)}")
|
||||||
|
print(f" Buttons count: {len(buttons)}")
|
||||||
|
print(f" Iframes count: {len(iframes)}")
|
||||||
|
print(f" Webviews count: {len(webviews)}")
|
||||||
|
if iframes:
|
||||||
|
for iframe in iframes:
|
||||||
|
print(f" - iframe[{iframe.get('index')}]: accessible={iframe.get('accessible')} src={iframe.get('src', '')[:50]}")
|
||||||
|
if webviews:
|
||||||
|
for w in webviews:
|
||||||
|
print(f" - webview[{w.get('index')}]: src={w.get('src', '')[:50]}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Error reading JSON: {e}')
|
||||||
20
scratch_parse3.py
Normal file
20
scratch_parse3.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(r'C:\Users\Variet-Worker\.gemini\antigravity\bridge\deep-inspect-result.json', 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
|
||||||
|
print("SEARCHING FOR CHAT TEXT IN DUMP...")
|
||||||
|
found = False
|
||||||
|
with open(r'C:\Users\Variet-Worker\.gemini\antigravity\bridge\deep-inspect-result.json', 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
|
raw_text = f.read()
|
||||||
|
if '스스로 만들고 스스로' in raw_text:
|
||||||
|
print("YES! The chat text IS in the raw JSON dump!")
|
||||||
|
found = True
|
||||||
|
elif 'Variet' in raw_text:
|
||||||
|
print("Found Variet in dump.")
|
||||||
|
else:
|
||||||
|
print("Chat text not found in raw dump.")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Error reading JSON: {e}')
|
||||||
18
scratch_parse4.py
Normal file
18
scratch_parse4.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(r'C:\Users\Variet-Worker\.gemini\antigravity\bridge\deep-inspect-result.json', 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
|
||||||
|
for node in data.get('nodes', []):
|
||||||
|
label = node.get('label', 'unknown')
|
||||||
|
btns = node.get('buttons', [])
|
||||||
|
print(f"\n[Node] {label} (Total btns: {len(btns)})")
|
||||||
|
for i, b in enumerate(btns):
|
||||||
|
t = b.get('text', '').replace('\n', ' ').strip()
|
||||||
|
hidden = b.get("hidden")
|
||||||
|
cls = b.get("class")
|
||||||
|
print(f" {i:3d}: \"{t[:50]}\" (Hidden: {hidden}, Class: {cls[:30]})")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Error reading JSON: {e}')
|
||||||
18
trigger_capture.py
Normal file
18
trigger_capture.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import urllib.request, time
|
||||||
|
|
||||||
|
print("Waiting 3 seconds for UI to render...")
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
name = 'gravity_control'
|
||||||
|
h = 0
|
||||||
|
for c in name:
|
||||||
|
h = ((h << 5) - h + ord(c)) & 0xFFFFFFFF
|
||||||
|
if h > 0x7FFFFFFF: h -= 0x100000000
|
||||||
|
port = 10000 + (abs(h) % 50000)
|
||||||
|
|
||||||
|
print(f"Triggering deep-inspect on port {port}...")
|
||||||
|
try:
|
||||||
|
urllib.request.urlopen(urllib.request.Request(f'http://127.0.0.1:{port}/deep-inspect'), timeout=12)
|
||||||
|
print("Trigger signal sent successfully")
|
||||||
|
except Exception as e:
|
||||||
|
print("Trigger failed:", e)
|
||||||
Reference in New Issue
Block a user