{
  "schema": 1,
  "product": "miblo",
  "version": "1.25.0",
  "date": "2026-10-08",
  "notes": "# Miblo 1.25.0\n\n## A tela do seu app no Miblo (Screen SDK)\n\n- **An App screen of your own.** The Miblo gets a new screen in its rotation, **App**, that a program designs: a **card** (a title and up to four things: a big number, a ring, a bar, a line of text, a tiny chart, in Miblo's colours and fonts), a **frame** (a whole 240x240 image: send a PNG or raw pixels and Miblo converts it, no other software needed), or both: a **layer**, the card drawn over the frame. Upload a designed background once, then change only the number: no flash is written. `miblo mode app` pins it; \"needs you\" and every Miblo alert still come first, and the program's name is always on it.\n- **In the SDK.** `@miblo/status` and `miblo-status` get `screen.card()`, `screen.frame()`, `screen.layer()`, `screen.show()`, `screen.peek()` and `screen.clear()`; the examples include a steps app with a sample background. The routes are under `/sdk/v1/screen` (docs/status-api.md \"Screen\").\n- **Careful with the flash.** A frame slot can be written once every 10 s and 100 times a day, checked on the computer before anything is sent; a photo too detailed for 64 colours is refused with its size. A typical designed background is about 5 KB.\n- **Peek:** an app can bring its screen to the front for up to 10 s when something matters, once every 10 minutes.\n- **Many apps, one Miblo:** every app has its own screen and the App screen moves from one to the next every 15 s (`miblo apps rotation <seconds>`, 0 to show only the pinned one); `screen.show()` pins yours. Frame slots belong to the app that wrote them.\n\n## Apps\n\n- **Two official apps to start:** **Processador** (is the machine choking, and by what?) and **Bitcoin e Cripto** (did it move? the price in your currency, and a peek on a 5 % move). Turn one on with `miblo apps enable processador`. They are plain Status API programs (`miblo-apps`), the same door any developer uses.\n- **Your own program, the same way:** `miblo apps add \"<command>\"` (from your own terminal), then `miblo apps enable|disable|show|logs|remove <id>`; Miblo starts it with the token, restarts it if it stops, and keeps its output.\n- **An enabled app keeps the Miblo alive:** while one is on, Miblo's background service stays up, and `miblo apps enable` starts it when needed; the Miblo app calls `miblo apps start` at launch.\n- **On the phone too:** the phone gets the App screen now and the list of apps (state, settings, whether one needs setting up).\n- **Settings without files:** an app declares what it needs (`app.declare()`), reads it with `app.settings.get()` and hears changes with `onChange()`; it can ask you (`settings.request()`), and the Miblo app shows the form, your phone reminds you and the Miblo says \"Configure no app Miblo\". `miblo apps config <id> key=value` sets them from the terminal. Values stay on your computer.\n- **Screen packages from miblo.ai:** `miblo apps install <id>` applies a card, settings and frames package signed with Miblo's apps key (its own key, not the release key; refused when not signed); `miblo apps remove` takes it off. `miblo screen status|clear` shows or clears the App screen.\n\n## Novidades no aparelho (firmware)\n\n- **The App screen.** A new screen in the Miblo's rotation that a program designs: a card (a title and up to four items: a big number, a ring, a bar, a line of text, a tiny chart, or two of them side by side) drawn with the Limits screen's fonts, ring and bar; a frame (a full 240x240 picture kept in the Miblo's flash, up to four); or the card over a frame. Only what changed is redrawn: a number that changes every minute never touches the flash.\n- **Where it shows.** With an App screen set, it takes its turn in the rotation next to Overview (and Limits, when the rotation is on), for as long as **Settings → Screen → App screen for (s)** says (10 s by default; 0 keeps it out of the rotation). Pin it with **Screen: App** in the settings or `miblo mode app`. A program may bring it to the front for up to 10 seconds (a peek), at most once every 10 minutes.\n- **Miblo comes first.** Alerts, \"needs you\", setup and codes always draw over the App screen; a session waiting for you shows the Overview's attention view even when the App screen is pinned. The program's name is always on the App screen, and a card can never use Miblo's own alert phrases.\n- **Care with the flash.** A frame slot can be written once every 10 seconds and 100 times a day; the count survives a restart. A damaged or incomplete frame is deleted, never drawn.\n- **In the Miblo app too.** The same screen code (WebAssembly) draws the cards in the desktop app and on the phone, pixel for pixel as the gadget.\n\n## Miblo Apps na loja (miblo.ai/apps)\n\n- **A store for apps.** miblo.ai/apps lists the official apps and the community's: search, categories (Meu computador, Dinheiro, Dia a dia, Notícias e dev, Esporte), a preview of each screen and what an app asks you to configure. **Ativar no meu Miblo** opens the Miblo app on that app (`miblo://apps/enable/<id>`); a community screen package installs with `miblo apps install <id>`.\n- **Submit yours.** A signed-in member submits an app (name, promise, category, icon, screenshots, the program's link, a card and up to four frames as PNG); the owner reviews it in the admin, and every approved package is re-encoded and signed by miblo.ai with the apps key before anyone can install it. Revisions go through the same review; a report hides an app at once (at most two per member per day) until it is reviewed.\n- **The Miblo app 1.7.0** gets the **Apps** tab: the gallery with live previews, a switch per app, its settings underneath, \"Show now\", the log, and a setup card when an app asks for something.\n\n## Fixes / Segurança\n\n- Cards: the plugin refuses the gadget's alert phrases and the raw 1 KB limit exactly as the firmware does (shared fixtures).\n- Apps: child programs get only `MIBLO_TOKEN`, `MIBLO_PORT`, `MIBLO_APP_ID` and a short allowlist of the environment, never the shell's keys; an app exits with the bridge that started it; an offline gadget no longer holds a program's requests; the peek limit is per screen with a global bucket; at most 64 screens; package downloads are capped while streaming and https-only; hostile JSON in a package cannot crash the CLI before the signature check; app logs are capped.\n- PNG: the converter refuses images over 2048x2048 from the header and bounds every chunk; a decompression bomb costs about 130 ms and nothing more.\n- App packages are signed with their own key (`APP_PACKAGE_KEYS`), separate from the release key.\n- Store: a member's reports hide at most two apps a day; a moderator cannot restore what the owner hid; hidden apps are not described in page heads; names lose invisible and bidi characters; media is cached for a day, not a year.",
  "assets": [
    {
      "name": "miblo-geekmagic_ultra-1.25.0.bin",
      "kind": "firmware",
      "board": "geekmagic_ultra",
      "path": "firmware/1.25.0/miblo-geekmagic_ultra-1.25.0.bin",
      "size": 916544,
      "sha256": "a3e137e14cc43c8de2f640ea482b44d2131a34d8f6c26c9452957aa24593effb"
    },
    {
      "name": "miblo-loader-geekmagic_ultra-1.25.0.bin",
      "kind": "loader",
      "board": "geekmagic_ultra",
      "path": "firmware/1.25.0/miblo-loader-geekmagic_ultra-1.25.0.bin",
      "size": 313184,
      "sha256": "c58c3cd87afdfefa30d4cbceeab0bffddaf310e9c4a5d524731a51857565ff59"
    },
    {
      "name": "miblo-plugin-1.25.0.zip",
      "kind": "plugin",
      "path": "plugin/miblo-plugin-1.25.0.zip",
      "size": 557878,
      "sha256": "b2de7c043e02d102696a09eb3391f3fcd9393f34bee17569702feaf80487a10a"
    },
    {
      "name": "Install-Miblo-macOS.zip",
      "kind": "installer",
      "path": "installers/1.25.0/Install-Miblo-macOS.zip",
      "size": 20277,
      "sha256": "cd1833be683ffd1984bce8f982c29cdd2dd0b503eacf8f8d4f323879f3ec491c"
    },
    {
      "name": "install.ps1",
      "kind": "installer",
      "path": "installers/1.25.0/install.ps1",
      "size": 69303,
      "sha256": "b00f0f39b8cc06fa880e524e44198309f17c34087898f05699038ee5c59fcac8"
    },
    {
      "name": "install.sh",
      "kind": "installer",
      "path": "installers/1.25.0/install.sh",
      "size": 64586,
      "sha256": "f67ef6555a36661a9a46947ea1cb0f8c21c1ade89965ed51a24e60da185717e7"
    }
  ]
}
