Personalización avanzada con JSON
Restier puede leer un único fichero JSON opcional al iniciar. Sirve para anular de forma local valores concretos del temporizador y textos de recordatorio; no es un sistema de complementos y no ejecuta código ni instala recursos.
Antes de empezar
Para cambiar solo un valor, crea advanced-customization.json en la ruta de datos de tu sistema, añade schemaVersion: 1 y reinicia Restier:
{
"schemaVersion": 1,
"timers": {
"workDurationMinutes": 50
}
}
Puedes descargar el ejemplo completo y válido de esquema v1 en advanced-customization.example.json. Usa ese archivo como punto de partida; no añadas campos que no estén documentados.
Ubicación y ciclo de vida
El nombre del fichero es siempre advanced-customization.json. Restier lo busca únicamente en el directorio de datos de aplicación elegido por Tauri:
| Sistema operativo | Ruta |
|---|---|
| macOS | ~/Library/Application Support/app.restier.restier/advanced-customization.json |
| Windows | %APPDATA%\app.restier.restier\advanced-customization.json |
| Linux | ${XDG_DATA_HOME:-$HOME/.local/share}/app.restier.restier/advanced-customization.json |
Crea el directorio padre si hace falta y reinicia Restier. El fichero se lee una sola vez durante el inicio y se convierte en una instantánea inmutable para esa ejecución. Editarlo o borrarlo mientras Restier está abierto no produce efecto alguno. Restier nunca escribe, repara, vigila ni migra este fichero.
Para volver a los ajustes normales y a los textos incluidos, borra el fichero y reinicia Restier.
Forma del esquema v1
El objeto raíz debe contener el entero schemaVersion: 1. Las secciones timers y copy son opcionales. Se rechazan los campos desconocidos en todos los niveles y un único valor inválido rechaza todo el fichero: no existe instalación parcial.
{
"schemaVersion": 1,
"timers": {},
"copy": {
"default": {},
"locales": {
"es-ES": {}
}
}
}
Solo se aceptan los bloques de idioma en-US y es-ES en copy.locales.
Anulaciones de temporizador
Los diez campos son opcionales e introducen enteros dentro de estos intervalos inclusivos:
| Campo JSON | Unidad | Intervalo |
|---|---|---|
workDurationMinutes | minutos | 1–720 |
shortBreakMinutes | minutos | 1–120 |
longBreakMinutes | minutos | 1–240 |
breaksUntilLong | descansos | 1–24 |
postureReminderMinutes | minutos | 1–240 |
postureFlashDurationMs | milisegundos | 50–10.000 |
preBreakWarningSeconds | segundos | 1–600 |
lightBreakSnoozeDurationMinutes | minutos | 1–120 |
wellnessNudgeFrequencyMinutes | minutos | 5–180 |
wellnessNudgeAutoDismissSeconds | segundos | 5–60 |
Un campo omitido conserva el ajuste base correspondiente. Una anulación afecta solo a su comportamiento equivalente: por ejemplo, lightBreakSnoozeDurationMinutes no modifica los botones de posponer 1 o 5 minutos.
Los ajustes persistentes y get_settings continúan mostrando los valores base del usuario. El planificador y las analíticas derivadas de la configuración del temporizador usan los valores efectivos. Si anulas un campo, los cambios posteriores que hagas en su ajuste base desde la interfaz se ignoran hasta que quites el fichero y reinicies Restier.
Textos de recordatorio
Usa identificadores semánticos públicos, no claves internas del renderizador. El registro completo es:
| ID semántico | Marcador permitido | Consumidores |
|---|---|---|
posture.label | Ninguno | Postura AppKit de macOS; postura Win32 de Windows; webview de postura de Linux. |
break.short.title | Ninguno | Webview completo/ligero; ligero nativo de macOS; adaptador de título previo de Windows/Linux. |
break.long.title | Ninguno | Webview completo/ligero; ligero nativo de macOS; adaptador de título previo de Windows/Linux. |
break.short.badge | Ninguno | Webview ligero/completo; ligero nativo de macOS; adaptador de distintivo previo de Windows/Linux. |
break.long.badge | Ninguno | Webview ligero/completo; ligero nativo de macOS; adaptador de distintivo previo de Windows/Linux. |
prebreak.short.message | Exactamente un {mmss} | Solo AppKit de aviso previo de macOS. |
prebreak.long.message | Exactamente un {mmss} | Solo AppKit de aviso previo de macOS. |
action.skip | Ninguno | Aviso previo, pantalla completa y ligero; solo etiqueta. |
action.postpone1 | Ninguno | Aviso previo y pantalla completa; solo etiqueta. |
action.postpone5 | Ninguno | Aviso previo y pantalla completa; solo etiqueta. |
action.lightSnooze | Ninguno | Webview ligero de Windows/Linux y ligero nativo de macOS; solo etiqueta. |
Utiliza copy.default para un texto independiente del idioma y copy.locales.en-US o copy.locales.es-ES para un texto localizado. Para cada ID, Restier resuelve el valor en este orden:
- anulación del idioma seleccionado;
- anulación
default; - texto integrado del idioma seleccionado;
- texto integrado en
en-US; - alternativa semántica incorporada.
Reglas de las plantillas
Los textos son cadenas escalares sin procesar de 1 a 240 valores escalares Unicode y no se normalizan. Por ello, formas combinadas visualmente similares pueden contar de manera diferente. Solo se permiten nombres de marcador ASCII en minúscula, como {mmss}; las llaves deben estar equilibradas y los marcadores deben coincidir exactamente con el ID semántico.
Restier rechaza controles C0/C1, DEL, saltos de línea, tabulaciones, controles bidireccionales (U+202A–U+202E, U+2066–U+2069, U+200E, U+200F, U+061C), además de < y >. Los renderizadores muestran texto: un valor que parezca una URL, Markdown, CSS o un script sigue siendo texto literal inerte, no contenido interpretado ni un formato rechazado solo por parecerlo. Aun así, se aplican los límites y caracteres prohibidos anteriores, y no se admite una cuenta atrás preformateada.
El valor {mmss} lo inserta en tiempo de renderizado la cuenta atrás del aviso previo de macOS. Las superficies previas de Windows y Linux usan título, distintivo y su temporizador separado; nunca consumen los campos de mensaje.
Ejemplo completo
El siguiente JSON es válido para el esquema v1:
{
"schemaVersion": 1,
"timers": {
"workDurationMinutes": 50,
"shortBreakMinutes": 5,
"longBreakMinutes": 20,
"breaksUntilLong": 4,
"postureReminderMinutes": 45,
"postureFlashDurationMs": 1500,
"preBreakWarningSeconds": 30,
"lightBreakSnoozeDurationMinutes": 10,
"wellnessNudgeFrequencyMinutes": 30,
"wellnessNudgeAutoDismissSeconds": 15
},
"copy": {
"default": {
"posture.label": "Revisa tu postura",
"break.short.title": "Descanso corto",
"break.long.title": "Descanso largo",
"break.short.badge": "Corto",
"break.long.badge": "Largo",
"prebreak.short.message": "Descanso corto en {mmss}",
"prebreak.long.message": "Descanso largo en {mmss}",
"action.skip": "Saltar",
"action.postpone1": "Aplazar 1 min",
"action.postpone5": "Aplazar 5 min",
"action.lightSnooze": "Posponer"
},
"locales": {
"es-ES": {
"break.short.title": "Descanso corto",
"break.long.title": "Descanso largo"
}
}
}
}
Recuperación y diagnóstico
El fichero debe ser regular, no puede ser un enlace simbólico y no puede superar 65.536 bytes. Si falta, no se puede leer, es demasiado grande, no es seguro, está mal formado, tiene una versión no admitida o no supera la validación, Restier falla de forma segura para la anulación: sigue usando los ajustes base y los textos integrados, sin escribir nada.
Los diagnósticos de inicio están redactados y se limitan al estado, versión del esquema, bytes leídos y número de anulaciones de temporizador y texto. Los estados posibles son not_found, loaded, invalid_envelope, unsupported_version, invalid_v1, io_error y unsafe_file_type; un fichero demasiado grande usa io_error con el código file_too_large. Un fallo emite como máximo una advertencia y nunca registra ruta, nombre de usuario, JSON sin procesar, texto personalizado, temporizaciones efectivas ni el bloque de idioma seleccionado.
Las analíticas del planificador reflejan valores efectivos; las analíticas que leen directamente los ajustes persistentes siguen reflejando valores base.
Límite de seguridad
La entrada no puede añadir comandos, capacidades, ventanas, eventos, procesos, complementos, conexiones de red, inclusiones de ficheros, rutas, interpolación de entorno, código ni idiomas nuevos. El cargador revisa los metadatos antes de abrir y comprueba que el descriptor adquirido sea regular cuando la plataforma expone esa información.
Una sustitución entre la comprobación de metadatos y la apertura realizada por el mismo usuario —incluidas carreras TOCTOU o una FIFO insertada después de la comprobación— queda fuera de este modelo de amenazas. No se ofrece una garantía más fuerte.
Si algo no se aplica
- Confirma que el nombre y la ruta son exactos.
- Comprueba que el JSON usa
schemaVersion: 1y no tiene campos desconocidos. - Revisa intervalos, marcadores y caracteres prohibidos.
- Cierra y vuelve a abrir Restier: el fichero no se recarga en caliente.
- Si quieres recuperar el comportamiento estándar, borra el fichero y reinicia.
Para los valores que se configuran normalmente desde la interfaz, consulta la Referencia de ajustes.