🇪🇸 Español | 🇬🇧 English
TUI de recuperación y formateo de bajo nivel de discos para macOS, escrita en
Rust (ratatui + crossterm). Pensada para el caso de un disco externo
(p. ej. un Toshiba de 320GB con sectores lentos/dañados) que Disk
Utility.app tarda mucho o se queda colgado intentando montarlo o
verificarlo antes de mostrarlo.
⚠️ Esta herramienta formatea y borra discos a bajo nivel. Formatear (GPT/MBR) y el "wipe rápido" son operaciones irreversibles: se pierden todos los datos del disco elegido. Úsala con cuidado y verifica siempre el identificador del disco antes de confirmar.
Disk Utility (y el diskutil "amigable" que usa Finder) intenta montar y a
veces verificar el sistema de archivos existente antes de mostrar el disco.
Si el disco tiene sectores defectuosos o una tabla de particiones dañada,
esa verificación puede tardar minutos o colgarse. DiskRecovery en cambio:
- Enumera discos con
diskutil list -plist(solo lista identificadores, no monta nada). - Pide los metadatos de cada disco con
diskutil info -plist <id>(fabricante, tamaño, bus, esquema de particiones) sin forzar montaje. - Identifica automáticamente con una insignia
★ TOSHIBA 320GBcualquier disco cuyo nombre de medio contenga "TOSHIBA" y cuyo tamaño esté en el rango de 300–340 GB (los fabricantes redondean el tamaño distinto a como lo hace macOS).
- Lista de discos con flechas ↑/↓, mostrando identificador, fabricante, tamaño, bus (USB/SATA/...) y esquema de particiones actual.
- El disco de arranque del sistema queda siempre oculto (no puede seleccionarse ni borrarse por accidente).
- Formatear como GPT o MBR, eligiendo sistema de archivos (ExFAT, MS-DOS FAT32, o Mac OS Extended Journaled solo para GPT).
- Wipe rápido: pone a cero los primeros ~40MB (MBR protector + cabecera
GPT primaria + tabla de particiones) y los últimos ~8MB (cabecera GPT de
respaldo) del disco, usando
ddsobre el dispositivo crudo (/dev/rdiskN). Esto invalida la tabla de particiones y hace que el disco vuelva a aparecer como "sin inicializar", sin necesidad de reescribir los 320GB completos. - Chequeo SMART (solo lectura, no modifica el disco): combina
diskutil info <id>(que ya incluyeSMART Status: Verified/Failing/Not Supported) consmartctl -a /dev/<id>si tienes instalado smartmontools (brew install smartmontools), para ver atributos detallados comoReallocated_Sector_Ct(sectores ya reasignados) oCurrent_Pending_Sector(sectores sospechosos pendientes de reasignar). Al ser de solo lectura, esta acción no pide confirmación ni identificador del disco: se ejecuta al pulsar Enter sobre ella. - Barrido completo (
Barrido completo (fuerza reasignación de sectores dañados)): pone a cero el disco entero, sector por sector, usando el mismo mecanismo del wipe rápido pero sin limitarse a cabecera/cola. Forzar una escritura en cada sector hace que, si el firmware del disco encuentra uno que no puede escribir de forma fiable, lo reasigne automáticamente a un sector de repuesto (el "G-list"), si el disco todavía tiene repuestos disponibles. Esto no es una reparación física ni funciona si ya se agotó la reserva de repuestos o el fallo es mecánico (cabezal, motor); en esos casos ninguna herramienta de software puede arreglarlo. Es una operación larga (proporcional al tamaño completo del disco, no solo ~48MB como el wipe rápido) e igual de irreversible, así que pasa por la misma pantalla de confirmación con el identificador del disco. Recomendado: correr un chequeo SMART antes y después para compararReallocated_Sector_Cty confirmar si de verdad se reasignó algo. - Confirmación obligatoria: antes de ejecutar cualquier acción
destructiva hay que teclear exactamente el identificador del disco
(ej.
disk4), no un simple sí/no. - Modo simulación (
--dry-run): recorre toda la interfaz y muestra exactamente qué comandos ejecutaría, sin tocar ningún disco real. Ideal para practicar antes de usarlo en modo real. - Progreso en tiempo real durante la ejecución:
- Wipe rápido: barra de progreso con porcentaje real (bytes
escritos / bytes totales, calculado escribiendo los ceros nosotros
mismos en vez de delegar en
dd), velocidad en MB/s y ETA estimado. - Formatear (GPT/MBR):
diskutilno expone un porcentaje paraeraseDisk, así que se muestra un spinner con tiempo transcurrido y la etapa actual ("Paso 1/2: Desmontando" → "Paso 2/2: Formateando"). - En ambos casos: si pasan más de 5 segundos sin ninguna novedad de progreso, aparece un aviso de posible estancamiento (útil justamente para un disco con sectores dañados: la barra se detiene exactamente donde el disco empieza a fallar).
- Al terminar, la pantalla de resultado muestra la duración total de la operación.
- Importante sobre el 100%: en el wipe rápido, llegar al 100% solo
significa que todos los bytes de ceros ya se escribieron (
write); después de eso la app llama afsyncpara confirmar que el disco los recibió de verdad. En un disco con sectores dañados, esefsyncfinal es el que puede colgarse (mismo tipo de bloqueo a nivel de kernel que undiskutil unmountDiskcolgado). Por eso puedes ver la barra en 100% y el aviso de estancamiento a la vez: no es una contradicción, es el disco fallando justo en la confirmación final. Si eso ocurre, el proceso puede quedar en estadoU(uninterruptible sleep) — nikill -9lo mata hasta que el disco responda o lo desconectes físicamente por USB.
- Wipe rápido: barra de progreso con porcentaje real (bytes
escritos / bytes totales, calculado escribiendo los ceros nosotros
mismos en vez de delegar en
- macOS (usa
diskutil,ddy/dev/rdiskN, específicos de macOS/BSD). - Rust (edición 2021 o superior).
- Privilegios de administrador (
sudo) para el modo real: escribir en/dev/rdiskNy ejecutardiskutil eraseDisksobre discos internos requiere root.
Descarga el .zip más reciente desde la página de
Releases, descomprímelo y abre DiskRecovery.app. Como no
está firmado con una cuenta de desarrollador de Apple, la primera vez
Gatekeeper mostrará un aviso de "desarrollador no identificado": haz clic
derecho sobre la app → Abrir, o ejecuta:
xattr -d com.apple.quarantine DiskRecovery.appEl .app abre una ventana de Terminal y ejecuta la TUI dentro (es una
herramienta de terminal, no una GUI nativa).
cargo build --releaseEl binario queda en target/release/diskrecovery.
Explorar la interfaz sin riesgo (no ejecuta ningún comando real):
./target/release/diskrecovery --dry-runUso real (formatear / hacer wipe de verdad):
sudo ./target/release/diskrecovery| Tecla | Acción |
|---|---|
| ↑ / ↓ | Mover selección |
| Enter | Elegir / confirmar |
| Esc | Volver a la pantalla anterior |
| r | Refrescar la lista de discos (pantalla de lista) |
| q | Salir (deshabilitado mientras escribes una confirmación) |
- Selecciona el disco en la lista (busca la insignia
★ TOSHIBA 320GBsi es el disco que Disk Utility tarda en mostrar). - Elige una acción:
Chequeo SMART,Formatear como GPT,Formatear como MBR,Wipe rápidooBarrido completo. - Si formateas, elige el sistema de archivos.
- Lee la pantalla de advertencia y teclea el identificador del disco
(ej.
disk4) exactamente como se muestra, luego Enter. - Espera a que termine y revisa el resultado (éxito/error con la salida del comando).
cargo testMás de 70 pruebas cubren, sin tocar hardware real (usando un
MockExecutor en memoria en lugar de diskutil/dd, y un TestBackend
de ratatui en memoria en lugar de una terminal real):
- Parseo de las salidas
plistdediskutil list/diskutil info. - Detección del disco Toshiba de 320GB por nombre + tamaño.
- Construcción exacta de los argumentos de
diskutil eraseDiskpara cada combinación de esquema (GPT/MBR) y sistema de archivos. - Cálculo del plan de "wipe rápido" (qué rangos de bytes se ponen a cero), incluyendo el caso límite de discos muy pequeños.
- Que el "wipe rápido" solo ponga a cero cabecera y cola de un archivo de prueba (dejando intacta la zona intermedia), y que el progreso reportado sea monótonamente creciente hasta llegar al 100%.
- Que el reloj de duración/estancamiento (
executing_started_at,last_progress_at) se inicialice al confirmar una acción y se congele al terminar (éxito o error). - Que el disco de arranque del sistema nunca aparezca en la lista seleccionable.
- Que la confirmación exija el identificador exacto del disco (no acepta mayúsculas/minúsculas distintas ni texto parcial).
- La máquina de estados completa de la interfaz (navegación, menús, confirmación, ejecución) usando el executor simulado.
- El renderizado de cada pantalla (lista, menú, opciones de formato,
confirmación, ejecución determinada/indeterminada, resultado, error
fatal) sobre un
TestBackenden memoria, verificando que no hace panic y que muestra el texto esperado.
src/disk.rs— modelo de datos de un disco y parseo deplist.src/executor.rs— abstracciónDiskExecutor(trait) con una implementación real (RealExecutor, ejecutadiskutil/dd) y una simulada para pruebas (testing::MockExecutor); construcción pura de argumentos de comando y del plan de wipe rápido.src/safety.rs— guardas de seguridad (disco de arranque protegido, verificación de la frase de confirmación).src/app.rs— máquina de estados de la aplicación (pantallas, navegación, transiciones), independiente de la terminal.src/ui.rs— renderizado conratatuide cada pantalla.src/main.rs— cableado: terminal (crossterm), bucle de eventos, hilos para no bloquear la interfaz durante operaciones largas, CLI (--dry-run).
Ver .claude/skills/ para guías detalladas de arquitectura, testing,
seguridad, i18n, diseño de la TUI y distribución, pensadas para escalar el
proyecto manteniendo estos mismos principios.
./scripts/build-macos-app.shGenera dist/DiskRecovery.app y dist/DiskRecovery-<versión>-macos.zip,
listo para adjuntar a un GitHub Release. Ver
.claude/skills/release-distribution/SKILL.md para más detalle.
Este proyecto es software libre y de código abierto (FOSS), licenciado bajo MIT (ver LICENSE). Los issues y pull requests son bienvenidos. Antes de mandar un cambio:
cargo testen verde.cargo clippy --all-targetssin warnings nuevos.- Si el cambio afecta texto visible o funcionalidad, actualiza ambos
README (
README.mden inglés yREADME.es.mden español).
MIT © 2026 Wonder Diaz.
Esta herramienta escribe directamente en dispositivos de bloque. Un uso incorrecto (elegir el disco equivocado) puede destruir datos de forma permanente e irrecuperable. Verifica siempre el identificador, el fabricante y el tamaño en la pantalla de confirmación antes de teclear el identificador y pulsar Enter.