Apps · the app layer

Real apps,
complete loops.

A platform is only as convincing as the apps that ship on it. Micro OS includes a vocabulary trainer with a real review schedule, a settings surface wired to host APIs, and the smallest possible state demo.

momoCounterSettings8 launcher slots

momo · a vocabulary trainer

Not a mockup: a multi-user study app with a per-word Ebbinghaus schedule and a four-step review loop.

momo / study dashboard
momo dashboard: today's words, new-word goal, streak and start button
momoWeb Player · 800 × 480

momo is written in the same restricted TypeScript as everything else. It keeps its state in kv, its per-user configuration in config, its audio and dictionary calls behind host APIs, and its layout on a static UI tree.

The study flow reveals one layer at a time. A wrong answer at stages 0–2 advances to the next hint without changing the memory stage; a wrong answer at stage 3 demotes the word and puts it back in the round immediately.

Persistence is the point.
The schedule survives a page reload on the Web, an app switch on macOS and a reboot on the ESP32. That is the difference between a demo and an app.
StageScreenWhat you see
0 · ListenHear the word, no spelling shown认识 / 不认识
1 · SpellThe word plus an IPA hint认识 / 不认识
2 · ClozeAn example sentence with the word removed认识 / 不认识
3 · DefineWord, sentence, definition and translationGrade and advance

Nine intervals

Each word advances independently through a fixed schedule:

5 min30 min12 h1 day2 days4 days7 days15 days30 days

No global "day N" counter. Every word carries its own last timestamp and stage, so a missed day only makes that word due.

Five local users

One install, up to five profiles. Every KV and config key is namespaced (u2:–u5:; the default user keeps the legacy unprefixed keys). Switching users stops audio, clears the current study session, and discards late sync responses from the previous account.

The active profile is shown in the OS app bar through os.setTitle, and the last active user is restored on launch.

Maimemo sync

On macOS, the sync tab imports the active account's real today_items queue through the native HTTP bridge, then enriches words with definitions and example sentences through net.lookupWords.

The token is per user. Sync is serialized: a second tap while a request is in flight only reports that a sync is already running, so a late response cannot overwrite another user's namespace.

Counter & Settings

The smallest state demo, and a settings surface wired to real host capabilities.

counter / studio
Counter Studio with Add, Reset and Double buttons and a battery control
CounterState · bind · input · switch
settings / network
Settings app showing a Wi-Fi network list and connect controls
SettingsRoot tabs · host APIs

Counter

Arithmetic, conditionals, a text input, a switch, a progress bar and three buttons. It is the end-to-end test app: compile, load, click twice, assert Count: 2 — through the native renderer and through Chromium.

Settings

Six root tabs: Network, Display, Sound, Security, System, About. Brightness, Wi-Fi scan/connect, speech rate and storage status are wired to host APIs; anything the OS does not expose yet is a dimmed "coming soon" row, not a dead control.

Install without reflashing

Compiled apps are data. Drop them on the card; the launcher picks them up on the next Home boot.

/sdcard
└── apps
    ├── notes.mbc
    ├── timer.mbc
    └── studio.mbc

On the Web and macOS hosts the card is simulated; on the device it is the removable TF card. Built-in apps always win an id collision, malformed images are skipped, and there are eight slots total including the built-ins.

Policy

  • Scan happens before every Home boot once the card was mounted at startup.
  • A card inserted later needs a reboot to be recognized.
  • No card: storage.available() is false and /apps is ignored.
  • No installer UI, no signature check, no marketplace in this slice.

The language is the contract

An allow-list, not a dialect. The compiler says no early, with a source location.

Allowed

  • const / let, numbers, strings, booleans, null
  • Arithmetic, comparisons, template literals
  • if / else, while, arrow handlers and bindings
  • state, bind, ui.mount and the widget catalog
  • Declared host calls: kv, config, storage, net, audio, clock, json, device, os

Rejected

  • JSX, classes, general functions, async / await, promises
  • Exceptions, runtime imports, arbitrary objects or arrays
  • Spread, destructuring, computed properties
  • Browser / Node globals and dynamic UI creation
  • Any host call outside the manifest (MTS002)