Saltar al contenido

Crear paneles

Referencia de panel.json

Cada campo de panel.json, las reglas con las que se revisa, los ids y nombres que se rechazan, y los límites de un paquete.

El paquete

Un paquete es una carpeta, o un zip una vez publicado, con panel.json en la raíz. Lleva todo el comportamiento del panel como archivos web y nada que se ejecute en la computadora. Solo son obligatorios panel.json y las páginas que nombra; el resto es lo que carguen tus páginas.

pomodoro-plus/
pomodoro-plus/
  panel.json
  index.html
  extras.html
  app.js
  app.css
  assets/
    bell.webp
    inter.woff2
  icon.svg
  README.md
  • index.html es la página que abre el panel (con cualquier nombre, el que diga contributes.panel.entry).
  • extras.html es opcional: la página que muestra Extras al abrir su fila.
  • README.md es para quien lea el paquete. Deska no lo muestra.

Un panel.json completo

panel.jsonjson
{
  "schema": 1,
  "id": "pomodoro-plus",
  "name": "Pomodoro Plus",
  "version": "1.2.0",
  "description": "A focus timer with breaks and a daily count.",
  "author": "pasho",
  "icon": "icon.svg",
  "color": "#e66b4f",
  "category": "productivity",
  "permissions": ["notify"],
  "network": ["api.example.com"],
  "sdk": 1,
  "contributes": {
    "panel": { "entry": "index.html", "scope": "workspace", "size": { "width": 360, "height": 280 } },
    "extras": { "title": "Pomodoro Plus", "view": "extras.html" }
  }
}

Deska lee cada campo cuando cargas la carpeta, y deska.dev los vuelve a leer todos cuando publicas. Todos los problemas se reportan juntos, para que corrijas el manifiesto de una sola vez.

Campos

CampoObligatorioRegla
schemaSí1. Un número mayor se rechaza con “This package needs a newer Deska.”
idSíDe 3 a 40 letras minúsculas, dígitos y guiones, empezando y terminando con una letra o un dígito. Consulta El id.
nameSíHasta 40 caracteres.
versionSíSemver, como 1.2.0 o 1.2.0-beta.1, hasta 64 caracteres. Consulta Versiones.
descriptionSíUna línea, hasta 140 caracteres.
authorSíEl nombre que la gente ve como autor, hasta 40 caracteres.
iconNoLa ruta de un .svg, .png o .webp dentro del paquete. La Biblioteca de paneles lo dibuja en la tarjeta del panel.
colorNo#rrggbb, como #e66b4f. Se guarda en minúsculas.
categoryNoproductivity, media, dev, ambient u other, el valor por defecto.
permissionsNoUna lista de notify, open-url y clipboard-write. Uno desconocido rechaza el paquete; uno repetido se guarda una vez.
networkNoHasta 20 nombres de host a los que el panel puede conectarse por https. Consulta Sitios.
embedsNoHasta 10 nombres de host cuyas páginas el panel puede mostrar a través de Deska. Necesita "sdk": 2. Consulta Páginas de otros sitios.
signedInEmbedsNotrue pide que las páginas de embeds mantengan la sesión de la persona en esos sitios, en una sesión propia del panel. Necesita embeds. Consulta Mantener la sesión.
sdkNoLa versión del SDK para la que se escribió el panel: 1, el valor por defecto cuando falta, o 2 para embeds. Una mayor que la que entiende esta versión de Deska se rechaza igual que schema.
contributesSíDónde aparece el panel, con al menos panel. Consulta Lugares.

Cualquier otro campo de primer nivel rechaza el paquete, así que un error de tipeo como permission nunca pasa en silencio. Los textos se recortan en los extremos, y name, description, author y el título de Extras no pueden tener caracteres de control, de ancho cero o bidireccionales, ni la mitad de un carácter sin su otra mitad. Los emoji completos están bien.

El id

El id nombra al panel en todas partes: la carpeta donde se desempaca en cada computadora, su almacenamiento, su ficha y su página en deska.dev. La primera versión publicada lo reserva para tu cuenta, y solo esa cuenta puede publicar más versiones con él.

Deska rechaza un id que no se pueda usar en todos los sistemas donde corre:

  • Un nombre que Windows reserva para un dispositivo: con, prn, aux, nul, de com0 a com9 y de lpt0 a lpt9.
  • constructor.

Al publicar, deska.dev también rechaza los ids que se leerían como propios de Deska. Una carpeta cargada con uno de ellos sigue funcionando mientras construyes:

  • Cualquier id que empiece con dev- (el nombre que Deska usa para las carpetas cargadas) o con deska-.
  • Deska y Dex (deska, dex, ask-dex), los agentes de programación y sus creadores (claude, codex, cursor, opencode, antigravity, gemini, openai, anthropic y similares).
  • Los paneles incluidos y sus tarjetas de la Biblioteca de paneles, como terminal, browser, editor, todo, pomodoro, music, youtube, spotify o sticky-note.
  • Los lugares de Deska y palabras que suenan oficiales: extras, library, community, settings, official, sdk, api, admin, y apply, una página de deska.dev bajo /panels.
ConsejoElige un id descriptivo de dos palabras, como focus-timer o team-clocks. Aparece en la dirección del panel en deska.dev y no cambia una vez publicado.

Nombres que se leen como Deska

Cada panel de la comunidad dice que lo hizo alguien que no es Deska, así que su name, su author y el title de Extras no pueden hacerse pasar por Deska. Al publicar, deska.dev rechaza uno que contenga la palabra “Dex”, o una palabra que empiece con “Deska”, y nombra cada campo que hay que cambiar.

  • Las palabras se leen como las lee una persona: con mayúsculas o minúsculas, con acentos, con letras parecidas de otros alfabetos, letras de ancho completo o estilizadas, dígitos en lugar de letras (3, 4 y 5 por e, a y s) y letras separadas una por una.
  • Cuenta una parte de una palabra en camelCase: “DexTimer” y “MyDeska” se rechazan, “DeskApp” pasa.
  • Dex nunca cuenta al final de una palabra, así que MangaDex, Rolodex, Dexter y Codex pasan.
  • Un autor puede llamarse Dex, mientras Dex no sea todo su nombre.

Versiones

version es semver: tres números enteros sin ceros a la izquierda, y una preversión opcional después de un guion (1.4.0, 2.0.0-rc.1). No se aceptan metadatos de compilación después de un signo más.

  • Una versión publicada nunca cambia. Para cambiar algo, sube la versión.
  • Cada versión nueva debe ser mayor que la anterior. Los números se comparan como números de cualquier largo, y una preversión va antes que su versión final: 1.2.0-beta.2 va antes que 1.2.0.
  • Mientras construyes, la versión no se compara con nada: una carpeta cargada no tiene una versión publicada.

Permisos

Sin ningún permiso, un panel puede dibujar, guardar sus propios datos, seguir el tema, saber si se ve, poner su título y, si declara una, llenar su fila de Extras. Pide solo lo que usas: la gente lee la lista antes de instalar.

PermisoQué permiteLa gente ve
notifydeska.notify: un aviso en Deska, con el nombre del panel, como máximo uno cada diez segundos.Enviar notificaciones
open-urldeska.openUrl: un enlace https en el navegador, desde un clic en el panel. Deska le pregunta a la persona la primera vez para cada sitio.Abrir enlaces
clipboard-writedeska.clipboard.write y deska.clipboard.writeImage: texto, o una imagen PNG o JPEG, al portapapeles, desde un clic en el panel. Sin él, los propios comandos de copiar de la página tampoco hacen nada.Copiar al portapapeles

Cada versión pide sus propios permisos. A quien instaló una anterior se le vuelve a preguntar antes de una actualización que pida más. No existe un permiso para leer el portapapeles, los archivos, el micrófono, la cámara ni la ubicación. Guardar archivos con deska.files y guardar uno con deska.files.save no necesitan ninguno: los archivos son del propio panel, y el diálogo de guardar es el consentimiento de la persona.

Sitios

network lista los hosts a los que el panel puede conectarse, y puede llegar a esos y a ningún otro: fetch, imágenes, fuentes, audio y video vienen del paquete o de estos hosts, por https. Un panel con la lista vacía no puede conectarse a internet.

  • Un nombre de host simple, en minúsculas y con al menos un punto: api.example.com. Sin esquema, ruta, puerto, comodines ni direcciones IP.
  • Solo nombres exactos. example.com no cubre api.example.com; lista cada host. Si un servicio usa muchos hosts, lista los que usa, como hace Net Radio con seis réplicas de streaming.
  • Como máximo 20. Un host repetido se guarda una vez.

La gente ve cada host en la página del panel. La pregunta antes de instalar también los nombra, o los primeros cinco y cuántos más cuando son siete o más. Una actualización que agrega un host nombra cada host nuevo.

Páginas de otros sitios

embeds lista los hosts cuyas páginas el panel puede mostrar, como un reproductor de video o un mapa. El panel nunca las enmarca por su cuenta: se lo pide a Deska con deska.embed, y Deska dibuja un marco propio sobre el panel. Consulta el sandbox para ver qué permite ese marco.

panel.jsonjson
{
  "embeds": ["www.youtube-nocookie.com"],
  "sdk": 2
}
  • Las mismas reglas de host que network: un nombre de host simple, en minúsculas y exacto, sin esquema, ruta, puerto, comodines ni direcciones IP.
  • Como máximo 10. Un host repetido se guarda una vez.
  • Nunca los sitios de Deska, ni un host de inicio de sesión o de pago, con todos los hosts que cuelgan de ellos: deska.dev, clerk.com, accounts.google.com, appleid.apple.com, login.microsoftonline.com, github.com, gitlab.com, stripe.com, paypal.com y algunos más. Una copia enmarcada de una página de inicio de sesión es como se roban contraseñas.
  • Un paquete que declara embeds necesita "sdk": 2.
  • embeds no cubre network: lista un host en los dos cuando el panel también le hace pedidos.

La gente ve estos hosts en la página del panel, y la pregunta antes de instalar dice que el panel mostrará páginas de ellos. Una actualización que agrega un host vuelve a preguntar. Publicar una versión con embeds necesita una cuenta que Deska aprobó para publicar.

Instalada desde la Library, una versión muestra estas páginas solo cuando Deska revisó y aprobó exactamente esa versión. Cada versión nueva espera su propia aprobación, y Deska puede retirar una aprobación. Una carpeta que cargas en Build a panel las muestra mientras la construyes.

Mantener la sesión

Las páginas de otros sitios corren sin sesión por defecto. Un panel que necesita lo que la persona ve en un sitio, como su calendario, pone "signedInEmbeds": true: sus páginas mantienen entonces la sesión de la persona en esos sitios, en una sesión propia de este panel, separada de la app, de los paneles de navegador y de cualquier otro panel. Necesita hosts en embeds, y solo tiene efecto cuando Deska verificó exactamente esa versión para eso; hasta entonces, o si Deska la aprueba sin sesión, las páginas se muestran sin sesión. La página del panel dice que lo pide.

Deska también puede bloquear un sitio para todos los paneles a la vez. Una computadora deja de conectarse a él y de mostrarlo en su siguiente revisión, diga lo que diga panel.json, y una versión que lo nombra en network o embeds no se puede publicar.

Lugares

contributes.panel

Obligatorio: el panel en el escritorio.

  • entry: la ruta de una página .html del paquete.
  • scope: workspace, el valor por defecto, permite que un proyecto tenga todas las copias que la persona agregue. global mantiene una por proyecto: agregarlo otra vez trae al frente la que ya está abierta. Úsalo para algo que nunca debería correr dos veces, como una radio.
  • size: opcional, el tamaño con el que abre un panel nuevo, con width y height enteros de 120 a 4000.

contributes.extras

Opcional: una fila en el popover Extras.

  • title: el nombre de la fila, hasta 40 caracteres.
  • view: opcional, una página .html que se abre dentro del popover. Sin ella, el popover muestra la página de entrada del panel.

Las claves desconocidas dentro de contributes se ignoran con una advertencia, así que un lugar que aprenda una versión más nueva de Deska nunca deja a una anterior sin tu panel. Consulta Extras para ver qué muestra la fila.

Límites del paquete

  • Un paquete pesa como máximo 5 MB comprimido, y se desempaca en 20 MB y 500 archivos como máximo.
  • Tipos de archivo: html, js, mjs, css, json, svg, png, jpg, jpeg, webp, gif, woff2, md y txt. Cualquier otro rechaza el paquete, incluidos wasm, mp3 y ttf.
  • Las rutas son relativas y de 200 caracteres como máximo, sin .., sin segmentos vacíos ni ., sin barra invertida y nada dentro de __deska/, donde vive el SDK.
  • Cada nombre debe poder escribirse en Windows: ninguno de : * ? " < > |, ningún nombre que termine en punto o espacio, ningún nombre de dispositivo como con.html o com1.js, y no dos rutas que solo difieran en mayúsculas.
  • Solo archivos normales: los enlaces simbólicos y archivos especiales se rechazan.
  • __MACOSX/ y los archivos ocultos como .DS_Store o .git se omiten, no se rechazan. Un zip hecho de la carpeta misma (pomodoro-plus/panel.json) se lee como si se hubiera hecho desde dentro.
  • Cada página y el ícono que nombra panel.json deben estar en el paquete.
ConsejoEl audio y el video quedan fuera de los tipos a propósito: transmítelos desde un host que declares (Net Radio, Window View) o genera el sonido en la página (Noise Machine).

Lo que dicen las revisiones

Deska lista cada problema en la página de la carpeta cargada en Crear un panel, los primeros cincuenta y cuántos más hay. Los mensajes están en inglés aunque la app esté en español; estos son los más comunes:

MensajeSolución
Unknown field "…".Quita o renombra el campo; solo se leen los campos de arriba.
"id" is 3 to 40 lowercase letters, digits and dashes…Pásalo a minúsculas y cambia espacios o guiones bajos por guiones.
"id" cannot be "…". Pick another.El id es un nombre de dispositivo o constructor.
"version" must be a semver version such as 1.0.0.Usa tres números: 0.1.0.
"…" is N characters; the limit is M.Acorta el nombre, la descripción, el autor o el título de Extras.
"…" holds invisible or control characters.Vuelve a escribir el texto; un nombre pegado puede traer un espacio de ancho cero.
"…" is not a host name (no scheme, port, wildcard or IP address).Escribe api.example.com, no https://api.example.com/v1.
Unknown permission "…". Known: notify, open-url, clipboard-write.Revisa cómo está escrito.
"contributes.panel.entry" must point at an .html page.Apúntalo a una página, como index.html.
… is named in panel.json but is not in the package.Agrega el archivo o corrige la ruta; las rutas distinguen mayúsculas.
…: this kind of file is not allowed in a package.Quítalo, o conviértelo a un tipo permitido.
A package holds at most 500 files; this one has N.Carga la carpeta donde está panel.json, no la raíz de un proyecto.
… cannot be shown inside a panel: it is a sign-in, payment or Deska page.Quita el host de embeds; nunca se permite.
A package with "embeds" needs "sdk": 2 or later.Agrega "sdk": 2 a panel.json.
"signedInEmbeds" needs hosts under "embeds".Lista los sitios en embeds, o quita signedInEmbeds.
Deska blocked … for every panel, so a package may not reach it or show its pages.Quita el host de network y de embeds.
This package needs a newer Deska.Pon schema en 1 y sdk en 1, o en 2 con embeds, o actualiza Deska.