Skip to content

MarceloLuvian/pulseboot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pulseboot

License MIT macOS Cero dependencias 698 tests

Una TUI + CLI de macOS, sin instalar nada, para detectar y gestionar el modo recuperacion/DFU de dispositivos iOS conectados por USB. Alternativa propia, abierta y auditable a herramientas como ReiBoot.

Cero dependencias de verdad. Solo el Python 3 que ya trae macOS (/usr/bin/python3) mas ctypes para hablar con los frameworks del sistema. Sin pip, sin Homebrew, sin binarios de terceros. Clonas y corres.

Honesto con lo que puede y no puede hacer. La matriz de capacidades marca cada funcion con su estado real. Nada se etiqueta como "funciona" hasta validarlo.


Demo

La TUI interactiva usa un layout multipanel inspirado en lazydocker. Seleccionas el dispositivo en la lista y el menu de acciones aparece a la derecha; te mueves con las flechas y ejecutas con Enter (sin memorizar teclas sueltas).

Pulseboot: menu de acciones de la TUI en accion

Los datos mostrados (UDID, dispositivo) son de ejemplo.

Vista estatica del layout:

 Pulseboot                                              v0.1.0  2026-07-01
┌─────────────────────┬──────────────────────────────────────────────────┐
│ ESTADO              │  Acciones   Detalle   Guia   Bitacora   Diagnostico│
│ usbmux: disponible  ├──────────────────────────────────────────────────┤
│ iokit:  disponible  │ ACCIONES — iPhone 15 Pro (Normal)                 │
├─────────────────────┤                                                  │
│ DISPOSITIVOS        │  > Entrar a modo recuperacion                    │
│                     │    Diagnostico del dispositivo                   │
│ > [iPhone 15 Pro]NRM│    Copiar UDID al portapapeles                   │
│                     │    Abrir guia                                    │
│                     │    Olvidar dispositivo                           │
│                     │    Refrescar lista de dispositivos               │
│                     │                                                  │
│                     │  [Arriba/Abajo] mover  [Enter] ejecutar  [Esc]   │
└─────────────────────┴──────────────────────────────────────────────────┘
 [Enter] acciones  [d] guia  [c] UDID  [l] idioma  [r] refrescar  [?]  [q]
 Listo - 1 dispositivo detectado.

Codigo de color: verde = Normal, amarillo = Recovery, rojo = DFU, magenta = WTF/PortDFU, blanco = Desconocido. Degrada a monocromo automaticamente cuando la terminal no soporta color.


Por que Pulseboot

La mayoria de las herramientas que gestionan el modo recuperacion de iOS te obligan a instalar un runtime, un gestor de paquetes o un binario cerrado. Pulseboot no.

  • Cero dependencias. Solo el Python 3 que trae macOS (/usr/bin/python3) mas ctypes para hablar con los frameworks del sistema (IOKit y CoreFoundation). Sin pip, sin Homebrew, sin libimobiledevice, sin paquetes de terceros.
  • Nada que instalar. Clona o descarga; corre python3 recovery.py. Listo.
  • Totalmente auditable. Todo es Python legible y la implementacion del protocolo (usbmux, lockdown + TLS, transferencias de control por IOKit) esta documentada contra fuentes primarias.
  • TUI nativa interactiva (estilo lazydocker, curses puro) con menu de acciones, y una CLI estable para scripting; ambas sobre los mismos casos de uso.
  • Honesto con sus capacidades. La matriz de abajo marca cada funcion con su estado real; nada se declara "funcional" sin validarlo contra hardware.
  • Bilingue. Espanol (es-MX, por defecto) e ingles (EN), seleccionable en vivo.

Requisitos

  • macOS (usa el socket de usbmuxd y los frameworks IOKit/CoreFoundation).
  • Python 3.9 o superior del sistema (/usr/bin/python3). No necesitas Python de Homebrew (aunque tambien sirve).
  • Un dispositivo iOS (iPhone o iPad) conectado por USB.
  • Para entrar a modo recuperacion: el dispositivo debe haber sido emparejado y haber aceptado "Confiar" en este Mac antes. Pulseboot lee el pair record existente que administra usbmuxd; no crea emparejamientos nuevos.
  • No requiere root para detectar. Abrir el dispositivo por IOKit (salir de recovery) puede requerir que ninguna otra app (Finder, Apple Configurator) lo tenga tomado.

Instalar y ejecutar

# Clona o descarga el repositorio, luego:
python3 recovery.py         # inicia la TUI interactiva
python3 recovery.py --help  # muestra la ayuda de la CLI y sale

Tambien puedes dar doble clic a Pulseboot.command en Finder para arrancar sin abrir la terminal.

Uso por CLI

Salida de ejemplo de --status en la CLI

python3 recovery.py --status                         # lista de dispositivos, legible
python3 recovery.py --status --json                  # lista en JSON
python3 recovery.py --status --no-tui                # fuerza CLI, sin TUI
python3 recovery.py --watch                          # monitoreo en vivo (Ctrl-C para salir)
python3 recovery.py --watch --json                   # eventos en vivo, una linea JSON por evento
python3 recovery.py --enter                          # entra a recovery (un dispositivo)
python3 recovery.py --enter --udid <UDID>            # entra a recovery en un dispositivo especifico
python3 recovery.py --exit                           # intenta salir de recovery/DFU (best-effort)
python3 recovery.py --exit  --udid <UDID>            # salir de recovery/DFU en un dispositivo especifico
python3 recovery.py --diagnose                       # diagnostico de solo lectura
python3 recovery.py --diagnose --json                # diagnostico en JSON (campos numericos crudos)
python3 recovery.py --lang en --status               # salida en ingles
python3 recovery.py --lang es --status               # salida en espanol (por defecto)

Referencia de flags:

Flag Descripcion
--status Imprime la lista de dispositivos conectados. Codigo 0 si hay exito.
--json Formatea la salida de --status o --diagnose como JSON.
--watch Monitorea cambios en vivo (conectado/desconectado/cambio de modo). Combinable con --json y --udid. Termina con Ctrl-C.
--enter Entra a modo recuperacion. Requiere dispositivo emparejado. Lo reinicia.
--exit Intenta salir de recovery o DFU. Best-effort; puede no lograrlo. Reinicia el dispositivo.
--udid UDID Selecciona un dispositivo por UDID cuando hay varios conectados.
--no-tui Fuerza modo CLI; sin otra accion, imprime la ayuda.
--lang {es,en} Idioma de la interfaz: es (espanol, por defecto) o en (ingles).
--diagnose Muestra diagnostico de solo lectura. Combinable con --json y --udid.
--verbose, -v Muestra mensajes de depuracion en stderr (sin secretos).
-h, --help Muestra la ayuda y sale.

Codigos de salida (contrato publico estable):

Codigo Significado
0 Exito.
1 Error (fallo la deteccion, no se pudo entrar a recovery, o error inesperado de la TUI).
2 Se intento salir de recovery/DFU pero no se pudo confirmar (best-effort fallido).
130 Interrumpido por el usuario (Ctrl-C).

Estructura del JSON de --status (ilustrativa):

{
  "devices": [
    {
      "mode": "Normal",
      "udid": "00008110-001A2B3C4D5E001A",
      "serial": "00008110-001A2B3C4D5E001A",
      "product_id": 4776,
      "location_id": 336592896,
      "device_id": 1,
      "source": "usbmux",
      "dfu_variant": null,
      "product_type": "iPhone15,2",
      "product_name": "iPhone 14 Pro",
      "paired": true
    }
  ],
  "sources": {
    "usbmux": true,
    "iokit": true
  }
}

Los valores de mode son estables: "Normal", "Recovery", "DFU", "Unknown". dfu_variant distingue subtipos de DFU ("DFU", "WTF", "PortDFU") sin romper scripts que solo miran mode. Todos los campos nuevos son aditivos. El JSON de --diagnose expone valores numericos crudos (battery_level, is_charging, storage_used_bytes, storage_total_bytes) utiles para consumo por scripts.

Atajos de la TUI

Tecla Accion
Arriba / Abajo, j / k Navegar la lista de dispositivos
Enter Abrir el menu de acciones del dispositivo seleccionado
Tab Alternar foco entre la lista y el panel de detalle
Izquierda / Derecha Cambiar de pestana (Acciones / Detalle / Guia / Bitacora / Diagnostico)
e Entrar a recovery (dispositivo en modo Normal; pide confirmacion)
x Intentar salir de recovery o DFU (best-effort; pide confirmacion)
d Abrir la guia de botones DFU del dispositivo
c Copiar el UDID al portapapeles
o Olvidar dispositivo (lo quita de la vista; reversible con r)
r Refrescar / re-detectar dispositivos
l Cambiar idioma (espanol / ingles)
? Abrir / cerrar la ayuda
q Salir
Ctrl-C Salir (codigo 130)

El mouse funciona cuando la terminal lo soporta. La TUI es 100% operable solo con teclado cuando el mouse no esta disponible.


Arquitectura

Pulseboot sigue Clean Architecture (puertos y adaptadores). Las dependencias apuntan solo hacia adentro:

Domain  <--  Application  <--  Infrastructure
                          <--  Presentation
pulseboot/
    domain/          Entidades, enums, reglas puras, constantes de hardware
    application/     Puertos (typing.Protocol) y casos de uso
    infrastructure/  Adaptadores: usbmux, lockdown+TLS, IOKit (ctypes), portapapeles
    presentation/    CLI (argparse) y TUI (curses); sin logica de negocio
    main.py          Composition root; unico lugar donde se cablean las capas
recovery.py          Entrypoint delgado (delega a pulseboot/main.py)
tests/               Pruebas unitarias (con fakes, sin hardware)

La CLI y la TUI son vistas paralelas sobre los mismos casos de uso. Ninguna contiene logica de negocio; ninguna toca USB ni abre sockets directamente. Las pruebas unitarias corren sin hardware, con adaptadores falsos, usando solo unittest de la libreria estandar:

python3 -m unittest discover -s tests -p "test_*.py"

Estrella al proyecto

Si te sirvio Pulseboot, dejale una estrella y no olvides seguirnos 👇

Siguenos en Instagram @lomejordeia


Licencia

MIT — usalo y modificalo libre. Ver LICENSE.

Copyright (c) 2026 Marcelo Luvian.

About

TUI + CLI de macOS, sin dependencias, para detectar y gestionar el modo recovery/DFU de iOS. Sin instalar nada, open-source y honesto.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages