Initial commit: navegator - Chrome CDP automation for LLMs
Add complete navegator system for stealthy browser automation: - CDP client with WebSocket communication - Browser API with navigation, storage, network, runtime - Stealth flags and anti-detection scripts - Persistent profile support - Examples and comprehensive documentation Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,384 @@
|
||||
# Instrucciones para Claude - Navegator
|
||||
|
||||
## Descripción del Proyecto
|
||||
|
||||
**Navegator** es un sistema en Go que permite controlar Chrome/Chromium mediante Chrome DevTools Protocol (CDP) directo, diseñado específicamente para automatización sigilosa con LLMs.
|
||||
|
||||
### Propósito
|
||||
Proporcionar a los agentes LLM capacidades completas de control de navegador web con:
|
||||
- Mínima detección de automatización (stealth flags optimizadas)
|
||||
- Perfiles persistentes y reutilizables
|
||||
- API completa de CDP (navegación, cookies, storage, network, JavaScript)
|
||||
- Comunicación WebSocket directa sin abstracciones pesadas
|
||||
|
||||
### Casos de Uso
|
||||
- Web scraping sigiloso
|
||||
- Automatización de formularios y flujos web
|
||||
- Testing end-to-end
|
||||
- Recopilación de datos
|
||||
- Interacción con aplicaciones web complejas
|
||||
|
||||
## Stack Tecnológico
|
||||
|
||||
### Lenguajes y Runtime
|
||||
- **Go 1.21+**: Lenguaje principal
|
||||
- **JavaScript**: Para evaluación en contexto de páginas web
|
||||
|
||||
### Dependencias Externas
|
||||
- **gorilla/websocket**: Comunicación WebSocket con CDP
|
||||
- **Chrome/Chromium**: Navegador requerido en el sistema
|
||||
|
||||
### Protocolos
|
||||
- **Chrome DevTools Protocol (CDP)**: Comunicación con Chrome via WebSocket
|
||||
- **WebSocket**: Transporte para CDP
|
||||
|
||||
## Estructura del Proyecto
|
||||
|
||||
```
|
||||
navegator/
|
||||
├── pkg/
|
||||
│ ├── cdp/
|
||||
│ │ └── client.go # Cliente CDP de bajo nivel (WebSocket)
|
||||
│ ├── browser/
|
||||
│ │ ├── browser.go # Gestión de instancia de Chrome
|
||||
│ │ ├── navigation.go # Navigate, Click, Type, Screenshot
|
||||
│ │ ├── storage.go # Cookies, LocalStorage, SessionStorage
|
||||
│ │ ├── network.go # Interceptación, headers, cache
|
||||
│ │ └── runtime.go # Evaluación JavaScript, bindings
|
||||
│ └── stealth/
|
||||
│ └── flags.go # Configuración de flags anti-detección
|
||||
├── examples/
|
||||
│ ├── basic.go # Ejemplo básico de uso
|
||||
│ └── advanced.go # Ejemplos de capacidades avanzadas
|
||||
├── docs/
|
||||
│ └── STEALTH_FLAGS.md # Documentación completa de flags
|
||||
├── .claude/
|
||||
│ └── CLAUDE.md # Este archivo
|
||||
├── go.mod # Módulo Go
|
||||
├── go.sum # Checksums de dependencias
|
||||
└── README.md # Documentación principal
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
### Código Go
|
||||
|
||||
#### Estilo
|
||||
- **gofmt**: Todo el código debe estar formateado con gofmt
|
||||
- **Nombres**: CamelCase para exports, camelCase para privados
|
||||
- **Comentarios**: Todos los exports deben tener comentarios godoc
|
||||
|
||||
#### Patrones
|
||||
- **Context**: Todos los métodos que hacen I/O reciben `context.Context`
|
||||
- **Errores**: Usar `fmt.Errorf` con `%w` para wrap de errores
|
||||
- **Configuración**: Structs de configuración con funciones `Default*()`
|
||||
- **Recursos**: Siempre proveer método `Close()` y usar `defer`
|
||||
|
||||
#### Ejemplo
|
||||
```go
|
||||
// Navigate navega a una URL.
|
||||
func (b *Browser) Navigate(ctx context.Context, url string, opts *NavigateOptions) error {
|
||||
if opts == nil {
|
||||
opts = DefaultNavigateOptions()
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Estructura de Código
|
||||
|
||||
#### Organización
|
||||
- **pkg/**: Código de biblioteca reutilizable
|
||||
- **examples/**: Código ejecutable de ejemplo
|
||||
- **docs/**: Documentación técnica
|
||||
|
||||
#### Capas
|
||||
1. **CDP**: Bajo nivel, solo manejo de protocolo WebSocket
|
||||
2. **Browser**: Alto nivel, API amigable para usuarios
|
||||
3. **Stealth**: Configuración específica para evasión
|
||||
|
||||
### Git
|
||||
|
||||
#### Branches
|
||||
- `master`: Rama principal estable
|
||||
- Feature branches: `feature/<nombre>`
|
||||
- Bugfix branches: `bugfix/<nombre>`
|
||||
|
||||
#### Commits
|
||||
- Mensajes en imperativo: "Add feature" no "Added feature"
|
||||
- Scope claro: "pkg/browser: add screenshot support"
|
||||
- Commits pequeños y atómicos
|
||||
|
||||
#### Ejemplo
|
||||
```
|
||||
pkg/browser: add full-page screenshot support
|
||||
|
||||
- Modify Screenshot() to accept fullPage parameter
|
||||
- Update captureScreenshot CDP params
|
||||
- Add example to advanced.go
|
||||
```
|
||||
|
||||
## Comandos Importantes
|
||||
|
||||
| Comando | Descripción |
|
||||
|---------|-------------|
|
||||
| `go mod download` | Descargar dependencias |
|
||||
| `go build -o nav examples/basic.go` | Compilar ejemplo básico |
|
||||
| `go run examples/basic.go` | Ejecutar ejemplo básico |
|
||||
| `go run examples/advanced.go` | Ejecutar ejemplos avanzados |
|
||||
| `go test ./...` | Ejecutar tests (cuando existan) |
|
||||
| `gofmt -w .` | Formatear todo el código |
|
||||
| `go mod tidy` | Limpiar go.mod |
|
||||
|
||||
## Arquitectura CDP
|
||||
|
||||
### Flujo de Comunicación
|
||||
|
||||
```
|
||||
Go App → WebSocket → Chrome CDP Endpoint
|
||||
↓
|
||||
Browser API (navegator/pkg/browser)
|
||||
↓
|
||||
CDP Client (navegator/pkg/cdp)
|
||||
↓
|
||||
WebSocket Connection
|
||||
↓
|
||||
Chrome/Chromium
|
||||
```
|
||||
|
||||
### Patrón Request/Response
|
||||
|
||||
```go
|
||||
// Enviar comando CDP
|
||||
req := Request{
|
||||
ID: 1,
|
||||
Method: "Page.navigate",
|
||||
Params: map[string]interface{}{"url": "https://example.com"},
|
||||
}
|
||||
|
||||
// Respuesta CDP
|
||||
resp := Response{
|
||||
ID: 1,
|
||||
Result: {...},
|
||||
}
|
||||
```
|
||||
|
||||
### Eventos CDP
|
||||
|
||||
```go
|
||||
// Chrome envía eventos asíncronos
|
||||
event := Event{
|
||||
Method: "Page.loadEventFired",
|
||||
Params: {...},
|
||||
}
|
||||
|
||||
// Se manejan via callbacks registrados
|
||||
client.On("Page.loadEventFired", handler)
|
||||
```
|
||||
|
||||
## Stealth - Configuración Anti-Detección
|
||||
|
||||
### Flags Críticas (SIEMPRE)
|
||||
|
||||
```go
|
||||
"--disable-blink-features=AutomationControlled" // Elimina navigator.webdriver
|
||||
"--exclude-switches=enable-automation" // Evita flag automation
|
||||
```
|
||||
|
||||
### Flags Contextuales
|
||||
|
||||
```go
|
||||
"--headless=new" // Modo headless (si se necesita)
|
||||
"--no-sandbox" // SOLO Docker/VMs (peligroso)
|
||||
"--disable-web-security" // SOLO testing (peligroso)
|
||||
```
|
||||
|
||||
### JavaScript Anti-Detección
|
||||
|
||||
Se inyecta automáticamente via `Page.addScriptToEvaluateOnNewDocument`:
|
||||
- Sobrescribe `navigator.webdriver`
|
||||
- Mock de `window.chrome`
|
||||
- Ajusta `navigator.plugins`, `languages`, etc.
|
||||
|
||||
Ver `pkg/stealth/flags.go` → `GetAntiDetectionScript()`
|
||||
|
||||
## Perfiles Persistentes
|
||||
|
||||
### Ubicación
|
||||
`~/.navegator/profiles/<nombre>/`
|
||||
|
||||
### Contenido
|
||||
- **Cookies**: Persistentes entre ejecuciones
|
||||
- **LocalStorage/SessionStorage**: Datos de aplicaciones
|
||||
- **Historial**: Navegación previa
|
||||
- **Extensiones**: Si se agregan
|
||||
- **DevToolsActivePort**: Puerto CDP activo
|
||||
|
||||
### Uso
|
||||
```go
|
||||
config := browser.DefaultConfig()
|
||||
config.ProfileName = "agent-session-1" // Reutilizable
|
||||
b, _ := browser.Launch(ctx, config)
|
||||
```
|
||||
|
||||
## API Principal - Browser
|
||||
|
||||
### Navegación
|
||||
```go
|
||||
Navigate(ctx, url, opts) // Navega a URL
|
||||
Reload(ctx) // Recarga página
|
||||
GoBack(ctx) // Historial atrás
|
||||
GoForward(ctx) // Historial adelante
|
||||
Click(ctx, selector) // Click en elemento
|
||||
Type(ctx, selector, text, opts) // Escribe texto
|
||||
WaitForSelector(ctx, sel, timeout) // Espera elemento
|
||||
Screenshot(ctx, fullPage) // Captura pantalla
|
||||
GetHTML(ctx, selector) // Obtiene HTML
|
||||
GetText(ctx, selector) // Obtiene texto
|
||||
```
|
||||
|
||||
### Cookies & Storage
|
||||
```go
|
||||
GetCookies(ctx, urls...) // Lee cookies
|
||||
SetCookie(ctx, cookie) // Establece cookie
|
||||
ClearCookies(ctx) // Limpia cookies
|
||||
GetLocalStorage(ctx) // Lee localStorage
|
||||
SetLocalStorage(ctx, key, value) // Escribe localStorage
|
||||
ClearLocalStorage(ctx) // Limpia localStorage
|
||||
// Similar para SessionStorage
|
||||
```
|
||||
|
||||
### Network
|
||||
```go
|
||||
EnableNetworkInterception(ctx) // Habilita interceptación
|
||||
BlockURLs(ctx, patterns...) // Bloquea URLs
|
||||
BlockResourceTypes(ctx, types...) // Bloquea recursos
|
||||
ModifyHeaders(ctx, headers) // Modifica headers
|
||||
SetExtraHTTPHeaders(ctx, headers) // Headers extra
|
||||
SetUserAgent(ctx, ua) // User-Agent
|
||||
EmulateNetworkConditions(ctx, ...) // Throttling
|
||||
```
|
||||
|
||||
### JavaScript
|
||||
```go
|
||||
Evaluate(ctx, script) // Ejecuta JS sync
|
||||
EvaluateAsync(ctx, script) // Ejecuta JS async
|
||||
CallFunction(ctx, fn, args...) // Llama función con args
|
||||
AddBinding(ctx, name, callback) // Expone Go a JS
|
||||
OnConsole(handler) // Monitor console.log
|
||||
WaitForFunction(ctx, fn, interval) // Espera condición JS
|
||||
```
|
||||
|
||||
## Restricciones y Mejores Prácticas
|
||||
|
||||
### NO HACER
|
||||
|
||||
❌ **NO usar `--no-sandbox` en producción**
|
||||
- Solo en Docker/containers confiables
|
||||
- Riesgo de seguridad crítico
|
||||
|
||||
❌ **NO usar `--disable-web-security` fuera de testing**
|
||||
- Desactiva CORS y otras protecciones
|
||||
- Solo para desarrollo local
|
||||
|
||||
❌ **NO ejecutar JavaScript no confiable**
|
||||
- Usar `Evaluate()` solo con código controlado
|
||||
- Validar inputs de usuarios
|
||||
|
||||
❌ **NO olvidar cerrar el navegador**
|
||||
```go
|
||||
b, _ := browser.Launch(ctx, config)
|
||||
defer b.Close() // SIEMPRE
|
||||
```
|
||||
|
||||
❌ **NO usar selectores frágiles**
|
||||
- Preferir IDs, data-attributes
|
||||
- Evitar nth-child, posiciones absolutas
|
||||
|
||||
### SÍ HACER
|
||||
|
||||
✅ **Usar perfiles persistentes para sesiones**
|
||||
```go
|
||||
config.ProfileName = "user-session-123"
|
||||
```
|
||||
|
||||
✅ **Manejar timeouts adecuadamente**
|
||||
```go
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
```
|
||||
|
||||
✅ **Verificar errores siempre**
|
||||
```go
|
||||
if err := b.Navigate(ctx, url, nil); err != nil {
|
||||
log.Printf("Error: %v", err)
|
||||
}
|
||||
```
|
||||
|
||||
✅ **Usar flags stealth apropiadas al contexto**
|
||||
```go
|
||||
config.StealthFlags.Headless = true // Servidor
|
||||
config.StealthFlags.Headless = false // Desktop/visible
|
||||
```
|
||||
|
||||
✅ **Documentar configuración específica**
|
||||
```go
|
||||
// UserAgent debe coincidir con versión de Chrome instalada
|
||||
config.StealthFlags.UserAgent = "Mozilla/5.0 ..."
|
||||
```
|
||||
|
||||
## Para LLMs - Instrucciones Específicas
|
||||
|
||||
### Al Crear Nuevas Capacidades
|
||||
|
||||
1. **Buscar en CDP docs primero**: https://chromedevtools.github.io/devtools-protocol/
|
||||
2. **Agregar método en browser package**: `pkg/browser/*.go`
|
||||
3. **Documentar con godoc**: Comentario claro del propósito
|
||||
4. **Manejar errores**: Wrap con `fmt.Errorf(..., %w, err)`
|
||||
5. **Agregar ejemplo**: En `examples/advanced.go`
|
||||
|
||||
### Al Modificar Flags Stealth
|
||||
|
||||
1. **Consultar STEALTH_FLAGS.md**: `docs/STEALTH_FLAGS.md`
|
||||
2. **Comentar flags peligrosas**: `--no-sandbox`, `--disable-web-security`
|
||||
3. **Actualizar script anti-detección**: Si es necesario en `pkg/stealth/flags.go`
|
||||
4. **Testear detección**: Usar sitios como https://bot.sannysoft.com/
|
||||
|
||||
### Al Extender CDP Client
|
||||
|
||||
1. **Mantener bajo nivel**: Solo protocolo WebSocket
|
||||
2. **No agregar lógica de negocio**: Eso va en `pkg/browser`
|
||||
3. **Manejar eventos correctamente**: Usar goroutines con `go handler()`
|
||||
4. **Thread-safety**: Usar `sync.Mutex` donde sea necesario
|
||||
|
||||
### Debugging
|
||||
|
||||
```go
|
||||
// Activar logging
|
||||
config.StealthFlags.EnableLogging = true
|
||||
|
||||
// Ver puerto CDP
|
||||
log.Println(b.DebugURL()) // http://127.0.0.1:<port>
|
||||
|
||||
// Abrir en navegador regular para inspeccionar
|
||||
```
|
||||
|
||||
## Referencias Clave
|
||||
|
||||
- **CDP Protocol**: https://chromedevtools.github.io/devtools-protocol/
|
||||
- **Chrome Flags**: https://peter.sh/experiments/chromium-command-line-switches/
|
||||
- **Puppeteer Stealth**: https://github.com/berstend/puppeteer-extra/tree/master/packages/puppeteer-extra-plugin-stealth
|
||||
- **Bot Detection**: https://bot.sannysoft.com/
|
||||
|
||||
## Próximos Pasos (TODOs)
|
||||
|
||||
- [ ] Agregar tests unitarios
|
||||
- [ ] Implementar pool de navegadores
|
||||
- [ ] Soporte para múltiples targets/tabs
|
||||
- [ ] Gestión de extensiones de Chrome
|
||||
- [ ] Proxy support
|
||||
- [ ] Screenshots de elementos específicos
|
||||
- [ ] PDF generation
|
||||
- [ ] Geolocation mocking
|
||||
- [ ] Permissions API
|
||||
- [ ] Service Workers interception
|
||||
Reference in New Issue
Block a user