- Add AG Native DOM path: #conversation + .leading-relaxed.select-text - Keep Cascade path: [data-testid=conversation-view] + [data-step-index] - Register #632 in known-issues.md (SDK+DOM both blocked for AG Native) - Bump version 0.5.50 → 0.5.51 - Add DOM analysis helper scripts
84 lines
3.2 KiB
Python
84 lines
3.2 KiB
Python
"""Search AG Native DOM dump for chat content and buttons."""
|
|
import json, os
|
|
|
|
fpath = os.path.join(os.path.expanduser('~'), '.gemini', 'antigravity', 'bridge', 'dump_html_5.json')
|
|
with open(fpath, 'r', encoding='utf-8-sig') as f:
|
|
data = json.load(f)
|
|
|
|
body = data.get('body', data.get('bodyTree', {}))
|
|
qi = data.get('quickInfo', {})
|
|
|
|
# Show all buttons
|
|
print('=== BUTTONS ===')
|
|
for b in qi.get('buttons', []):
|
|
print(f' [{b["tag"]}] "{b["text"][:60]}" visible={b["visible"]} cls={b.get("cls","")[:80]}')
|
|
|
|
# Data attrs
|
|
print('\n=== DATA ATTRS ===')
|
|
for attr in qi.get('dataAttrs', []):
|
|
print(f' {attr}')
|
|
|
|
# Recursive search for nodes by text
|
|
def find_nodes_by_text(node, target, path='', results=None, depth=0):
|
|
if results is None: results = []
|
|
if not isinstance(node, dict): return results
|
|
tag = node.get('tag','')
|
|
cls = node.get('cls','')
|
|
text = node.get('text','')
|
|
children = node.get('children', [])
|
|
cur = f'{path}/{tag}'
|
|
if target.lower() in text.lower():
|
|
results.append({'path': cur, 'depth': depth, 'cls': cls[:80], 'text': text[:80], 'children': len(children)})
|
|
for c in children:
|
|
find_nodes_by_text(c, target, cur, results, depth+1)
|
|
return results
|
|
|
|
print('\n=== NODES containing "Always run" ===')
|
|
matches = find_nodes_by_text(body, 'Always run')
|
|
for m in matches:
|
|
print(f' depth={m["depth"]} cls="{m["cls"]}" text="{m["text"]}" children={m["children"]}')
|
|
|
|
print('\n=== NODES containing "Always" ===')
|
|
matches = find_nodes_by_text(body, 'Always')
|
|
for m in matches:
|
|
print(f' depth={m["depth"]} cls="{m["cls"]}" text="{m["text"]}" children={m["children"]}')
|
|
|
|
# Find ALL text nodes with > 30 chars
|
|
def find_all_text(node, results=None, depth=0, path=''):
|
|
if results is None: results = []
|
|
if not isinstance(node, dict): return results
|
|
tag = node.get('tag','')
|
|
cls = node.get('cls','')
|
|
text = node.get('text','')
|
|
children = node.get('children', [])
|
|
if text and len(text) > 30:
|
|
results.append({'depth': depth, 'tag': tag, 'cls': cls[:80], 'text': text[:100], 'path': f'{path}/{tag}'})
|
|
for c in children:
|
|
find_all_text(c, results, depth+1, f'{path}/{tag}')
|
|
return results
|
|
|
|
print('\n=== LONG TEXT NODES (>30 chars) ===')
|
|
texts = find_all_text(body)
|
|
texts.sort(key=lambda x: len(x['text']), reverse=True)
|
|
for t in texts[:25]:
|
|
print(f' d={t["depth"]} [{t["tag"]}] cls="{t["cls"][:50]}" len={len(t["text"])} "{t["text"][:80]}"')
|
|
|
|
# Find nodes with many children (structural containers)
|
|
def find_containers(node, results=None, depth=0, path=''):
|
|
if results is None: results = []
|
|
if not isinstance(node, dict): return results
|
|
tag = node.get('tag','')
|
|
cls = node.get('cls','')
|
|
children = node.get('children', [])
|
|
if len(children) > 5:
|
|
results.append({'depth': depth, 'tag': tag, 'cls': cls[:100], 'children': len(children), 'path': f'{path}/{tag}'})
|
|
for c in children:
|
|
find_containers(c, results, depth+1, f'{path}/{tag}')
|
|
return results
|
|
|
|
print('\n=== CONTAINERS (>5 children) ===')
|
|
conts = find_containers(body)
|
|
conts.sort(key=lambda x: x['children'], reverse=True)
|
|
for c in conts[:20]:
|
|
print(f' d={c["depth"]} [{c["tag"]}] children={c["children"]} cls="{c["cls"][:70]}"')
|