manzanas

Controla simuladores de iOS desde Claude Code, Cursor o Codex mediante la etiqueta de accesibilidad en lugar de coordenadas de captura de pantalla y toque, con concesiones y un grupo de instancias precalentadas para que múltiples agentes puedan compartir un Mac.

Documentación

manzanas

Release npm CI AllMCPs Verified

Un daemon para Mac que orquesta flotas de simuladores iOS para agentes multiagente: arrendamientos, acciones, streaming, estado determinista y un diario de ejecución exportable para agentes de IA (y humanos) que comparten simuladores.

La historia del 90%: arrienda un simulador, ejecuta un spec YAML, obtén evidencia. Todo lo demás —flotas, teléfonos físicos, mirroring— es un capítulo opcional que puedes ignorar hasta que lo necesites.

https://github.com/user-attachments/assets/983b0548-df1a-41a3-812c-f0f39cfaa01c

1 orquestador, 7 agentes Codex, 7 simuladores en 3 Macs; los arrendamientos evitan que nadie se estorbe. Tiempo real, sin ediciones.

manzanasd se ejecuta en cada host Mac y posee todo lo que tiene estado: el registro de simuladores, la tabla de arrendamientos, el pool cálido, los backends de acciones, los streamers, las imágenes doradas y el diario de ejecución. Los clientes (CLI manzanas, fachada MCP, SDKs) son ligeros y multiplataforma, hablando un protocolo JSON versionado sobre HTTP + WebSocket.

Sitio web: manzanas.dapsdev.dev (fuente en site/).

Inicio rápido en cinco minutos

Sin banderas que leer, sin configuración que escribir. Cuatro capas, comienza en la que coincida con tu máquina:

0. Una línea (macOS/Linux): npx

npx manzanasd-client@latest doctor   # downloads the release binary and runs the setup diagnosis

El wrapper npm obtiene el binario manzanasd/manzanas correcto para tu plataforma al instalar, y luego envía cada comando a él. Úsalo como CLI, o apunta la configuración MCP de tu agente a manzanas mcp.

1. En cualquier lugar (sin Mac): modo mock

make build                      # writes bin/manzanasd, bin/manzanas, bin/manzanas-broker
./bin/manzanasd --mock          # full daemon + fake fleet + mock action backend

En otra terminal, ejecuta todo el ciclo arrendamiento → arranque → acción → evidencia como una sola ejecución YAML declarativa:

# hello.yaml, drives the mock login screen (docs/mock.md)
name: hello
target:
  labels: [ios26]
steps:
  - action: type_into_element
    with: {id: username, text: agent}
  - action: type_into_element
    with: {id: password, text: pw}
  - action: tap_element
    with: {label: "Sign In"}
  - action: wait_for_element
    with: {label: "Welcome, agent!", timeout_ms: 5000}
./bin/manzanas run hello.yaml -o evidence.md
cat evidence.md                 # PR-ready markdown evidence of every step

Ese es el producto: un spec, un comando, un rastro de evidencia registrado. El mismo spec se ejecuta sin cambios contra simuladores reales y contra teléfonos físicos, porque cada objetivo habla la misma API de acciones.

2. En un Mac con Xcode: simuladores reales

brew tap baribarigood/tap https://github.com/BariBariGood/homebrew-tap
brew trust baribarigood/tap      # Homebrew >= 6 requires trusting third-party taps
brew install manzanasd            # daemon (+ pulls in the manzanas CLI)
brew services start manzanasd     # launchd service on port 7433
manzanas doctor                   # one-shot setup diagnosis; every failure names its fix

manzanasd necesita cero banderas para un daemon de un solo Mac funcional: valores predeterminados sensatos para el diario, la biblioteca de plantillas y el mapa de elementos; simuladores enumerados desde simctl; dispositivos físicos y el mirror desactivados hasta que optes por ellos. El mismo manzanas run spec.yaml ahora impulsa simuladores reales. Guía paso a paso (arrendamiento, toque, captura de pantalla, liberación manual): docs/quickstart.md.

manzanas targets                                        # list simulators
manzanas lease acquire --labels ios26 --agent me --wait # claim one
manzanas tap 200 400 --lease lse_...                    # drive it
manzanas mcp                                            # or hand the tools to an agent

3. Capítulos opcionales (probablemente aún no los necesitas)

Por qué

Los agentes que manejan simuladores sobre SSH crudo + herramientas CLI se estorban entre sí y pagan costos fijos enormes. manzanasd elimina ambos, con números medidos (M3 Pro, macOS 26.5, Xcode 26.5; reproduce con make bench):

  • Arrendamientos, no bloqueos: reclamos exclusivos con límite TTL y colas FIFO; ningún agente maneja jamás el mismo simulador.
  • Pool cálido park/thaw: los simuladores inactivos se pausan con SIGSTOP (un árbol estacionado no es programable, ~0 CPU de host inactiva sin importar lo que hagan los daemons del simulador) y se reanudan al otorgar el arrendamiento: ~0.28 s de arrendamiento a vivo vs ~7 s para un arranque en frío (~29 s en el primer arranque). El thaw en sí es un SIGCONT con PID en caché y toma menos de un milisegundo.
  • Acciones cálidas: un helper residente por simulador hace un toque de extremo a extremo en ~36 ms vs ~950 ms en frío (spawn de AXe por acción), ~3 s en frío en Intel.
  • Estado determinista: instantáneas, fixtures, auto-reset por arrendamiento e imágenes doradas que generan simuladores reducidos en segundos (~0.75 GB vs ~5 GB estándar, vía simslim), así un Mac ejecuta una docena de simuladores.
  • Evidencia: cada operación mutante bajo un arrendamiento se registra, con artefactos direccionados por contenido y una exportación Markdown lista para PR.
ArrendamientosReclamos exclusivos con límite TTL, etiquetas, colas FIFO, auto-reset, pausa/reanudación para entrega humana
Pool cálidoSimuladores park/thaw (SIGSTOP): ~0.28 s de arrendamiento a vivo, ~0 CPU inactiva
AccionesToques/deslizamientos/escritura en frío (AXe) + cálidos (helper residente), tap_element compuestos con un DSL de predicados estructurados, compuestos de desplazamiento de listas (scroll_until/scroll_collect), plantillas de píxeles (save_template/tap_template), lotes
VerificaciónPostcondiciones assert_text/assert_template, toques verificados por píxel opcionales, asentamiento de píxeles wait_for_stable, veredictos de ejecución + detección de deriva en reproducción
EjecucionesEjecuciones YAML de una llamada: arrendamiento → arranque → app → pasos → evidencia → liberación (docs/runs.md)
AuditoríaComprobaciones de UI deterministas (objetivos de toque, recorte, alineación, espaciado, área segura, etiquetas faltantes) → hallazgos + captura anotada en el diario
StreamingFan-out MJPEG, página /view en navegador, tramas WS
VideoGrabaciones simctl por arrendamiento que llegan al diario
EstadoInstantáneas, fixtures, auto-reset por arrendamiento, imágenes doradas
DiarioEvidencia de solo anexión por ejecución, artefactos, export.md, exportación de spec reproducible
PanelPanel web de solo lectura en /dash: flota, arrendamientos, multivista, navegador de diario
Doctormanzanas doctor: diagnóstico de host de una sola pasada, cada comprobación fallida lleva su corrección
DispositivosiPhones físicos vía devicectl + WebDriverAgent, o iPhone Mirroring para apps hostiles a XCTest
Flotamanzanas-broker federan N Macs detrás de un solo endpoint
ClientesCLI manzanas, herramientas MCP sobre stdio, wrapper npm, GitHub Action
Live MJPEG view of a leased simulator at /viewBuilt-in fleet dashboard at /dash
la página MJPEG en vivo /view del navegadorel panel de flota /dash integrado

MCP (Claude Code, Cursor, Codex)

manzanas mcp sirve todo el conjunto de herramientas sobre el Model Context Protocol (stdio), para que cualquier agente compatible con MCP pueda arrendar y manejar simuladores, con liberación automática de arrendamientos por sesión y errores de herramienta autodescriptivos. Configuraciones de cliente listas para pegar y solución de problemas: docs/mcp.md.

claude mcp add manzanas -e MANZANASD_ADDR=mac-host:7433 -- /path/to/manzanas mcp

Arquitectura

┌ Linux / CI / anywhere ────────────┐        ┌ each Mac host ─────────────────────────────┐
│ manzanas (thin client, Go)         │   WS   │ manzanasd (Go daemon)  :7433                │
│  - CLI: lease/tap/observe/...     │◄──────►│  registry ── warm pool (park/thaw, gates)  │
│  - MCP facade (stdio)             │  HTTP  │  leases (TTL, labels, FIFO, auto-reset)    │
│  - eval harness (manzanas-eval)    │        │  actions ── cold AXe / warm simbridge      │
├───────────────────────────────────┤        │  streams (MJPEG fan-out, browser view)     │
│ manzanas-broker  :7440             │        │  state (snapshots, fixtures, golden images)│
│  fleet-wide placement: leases are │───────►│  journal (evidence, artifacts, export.md)  │
│  scheduled across N daemons, then │ probe/ └────────────────────────────────────────────┘
│  clients talk to the owning       │ lease         × one daemon per Mac in the fleet
│  daemon directly (host_addr)      │
└───────────────────────────────────┘

Un núcleo de orquestación, transportes como backends ligeros: el mismo spec YAML, arrendamientos, diario y pipeline de evidencia se ejecutan contra simuladores (AXe/simctl), iPhones físicos (WebDriverAgent) y apps hostiles a XCTest (iPhone Mirroring). Lo que manzanas no es —un framework genérico de automatización OCR, una herramienta de botting de apps— está escrito en docs/non-goals.md, junto con por qué el repositorio sigue siendo un solo repositorio.

Documentación

Empieza aquí (la ruta del 90%):

  • docs/quickstart.md, de cero a una ejecución exitosa en un Mac: instalar → doctor → arrendamiento → toque → captura → ejecución YAML.
  • docs/runs.md, la ejecución YAML de una llamada: esquema, veredictos, detección de deriva, grabar → reproducir.
  • docs/mock.md, el daemon completo en cualquier lugar (Linux/CI), sin necesidad de Mac.
  • docs/journal.md, el rastro de evidencia: formato del diario de ejecución, artefactos, exportación Markdown, exportación de spec reproducible.
  • docs/mcp.md, entregar las herramientas a un agente (Claude Code, Cursor, Codex).
  • docs/troubleshooting.md, manzanas doctor primero, luego síntomas → causas → correcciones.

Profundizando (léelo cuando llegues al subsistema):

  • proto/PROTOCOL.md, el protocolo wire v0: objetivos, arrendamientos, acciones, flujos, estado, diario, ejecuciones, superficie WS. Las tablas en §5 son la lista autoritativa de tipos de acción y cargas útiles.
  • docs/architecture.md, componentes, contratos de interfaz y el límite del producto.
  • docs/agent-qa.md, una sesión de QA de agente de extremo a extremo trabajada, además de manejar apps animadas (React Native).
  • docs/resolver-ladder.md, cómo funciona la resolución de elementos: peldaños map/ax/ocr/template, procedencia, escalamiento.
  • docs/elementmap.md, el mapa de elementos aprendido (resolución de ruta rápida entre ejecuciones).
  • docs/templates.md, la biblioteca de plantillas de píxeles (save_template / tap_template / assert_template).
  • docs/warm-pool.md, pool cálido park/thaw, watchdog de huella, compuertas de seguridad del host.
  • docs/actions-warm.md, rutas de acción cálidas vs frías; el helper residente simbridge.
  • docs/state.md, instantáneas, fixtures, auto-reset por arrendamiento, cuarentena.
  • docs/images.md, imágenes doradas: reduce una vez, sella N simuladores en segundos.
  • docs/streaming.md, streaming MJPEG y la página de vista en navegador.
  • docs/dashboard.md, el panel web integrado de solo lectura en /dash.
  • docs/recording.md, captura de video por arrendamiento en el diario.
  • docs/eval.md, el harness de benchmark de determinismo impulsado por escenarios.
  • clients/README.md, inicios rápidos de CLI manzanas + MCP; clients/npm/; GitHub Action en action/.

Probablemente aún no necesitas estos (superficies opcionales; cada página abre con para quién es):

  • docs/non-goals.md, el límite del producto: qué es manzanas, qué deliberadamente no es, y el único candidato futuro de división.
  • docs/devices.md, iPhones físicos como objetivos arrendables (devicectl + WebDriverAgent), y la referencia del backend de mirror.
  • docs/mirror-onboarding.md, la ruta de configuración guiada para manejar apps hostiles a XCTest mediante iPhone Mirroring.
  • docs/broker.md, federación multi-Mac.
  • docs/fleet.md, operar una flota multi-Mac (topología, Tailscale, operaciones día 2).
  • docs/install.md, instalación launchd, lanzamientos, fórmula Homebrew.

La flota física en la que esto se ejecuta (máquinas, bloqueos, caché de compilación) es específica del sitio; docs/fleet.md cubre la parte del daemon.

Estado

Todo lo anterior está implementado y ejecutándose en la flota: arrendamientos + colas (incl. pausa/reanudación), pool cálido con compuertas de seguridad, backends de acciones en frío (AXe) + cálido (simbridge), acciones compuestas/lote/assert, la escalera de resolución con mapa de elementos y plantillas de píxeles, ejecuciones YAML de una llamada con veredictos y detección de deriva, streaming MJPEG, captura de video, instantáneas/fixtures/auto-reset, imágenes doradas, diario, panel, doctor, soporte de dispositivos físicos (WDA + mirror), broker, harness de eval, CLI + MCP. Verifica con go build ./... && go vet ./... && go test ./... (seguro para Linux; las rutas de simctl están simuladas).

Licencia

Apache-2.0, ver LICENSE. Los lanzamientos hasta e incluyendo v0.6.0 (y sus etiquetas existentes) se publicaron bajo MIT y siguen siendo MIT; los lanzamientos posteriores son Apache-2.0.