---
name: vela-quickapp-dev
description: Use when building VelaJS quick apps for Xiaomi watches.
---
# Xiaomi Vela watch development
## Workflow and evidence discipline
Use `aiot-toolkit`, not generic `hap-toolkit`, for Vela `.ux` projects. Read supplied project instructions and lockfiles. Build success and ZIP validation do NOT prove watch execution. Use systematic-debugging; do not repeatedly send speculative packages after failures. Never infer firmware corruption, certificate restrictions, or required bytecode solely from black-screen symptoms.
User uses AstroBox with Watch S4 41mm and requests minimal resource usage. Increment BOTH visible versionName and integer versionCode for each delivered fix. Preserve signing identity and package name for updates. Keep each delivered artifact at a distinct versioned path.
## Project
src/app.ux must wrap JavaScript in ``; bare JS in app.ux is not a valid substitute. Routes refer to paths relative to src; `pages/index` maps to `src/pages/index/index.ux`. Icon declared in manifest must exist. Typical manifest uses deviceTypeList [watch], minAPILevel 1, config.designWidth, router.entry/pages and display.backgroundColor. Do not confuse physical pixels, design width and DP. S4 41mm is 466x466 physical; set `config.designWidth` to 466 so 466px layout maps 1:1 to the screen. A designWidth of 480 (a common default) makes 466px elements render at ~97% — everything looks undersized/off-center and any ring is smaller than the real screen edge. This mismatch caused both the sundial's off-center sky disc and the snake's too-small bezel.
## Build
Use project's locked dependencies with npm ci and local npm scripts. `aiot build` and `aiot release` do NOT necessarily enable bytecode/protobuf; inspect effective options and archive. Explicit `--enable-jsc --enable-protobuf` produces .jsc/.style.bin/.template.bin. Release needs sign/private.pem and certificate.pem; preserve private keys, never share them. Official tooling includes development signing keys; do not imply they are Xiaomi production authorization.
## Confirmed observations and open bugs
- User's HyperBili circle RPK runs on their S4 41mm via AstroBox. Cached ~/hyperbili-s4.rpk. This establishes a working control, not compatibility of every S4-family package.
- NYAN builds through 0.9 failed to launch; changing designWidth, path, signing, bytecode and toolkit did NOT establish a cause. Claiming they were byte-for-byte equivalent to HyperBili was incorrect. Toolkit/Rspack version markers alone do not prove compatibility failures.
- Supplied ZIP: ~/Downloads/PairDrop_files_20260908_1846/xiaomi-vela-s4-hello-world.zip. Built under /tmp/hw with aiot-toolkit 2.0.5 + supplied lock (Rspack 1.7.12), plain signed release. User reports app stays open black with nonfunctional back-arrow gesture; not successful rendering.
- Concrete local reproduction: generated page WITHOUT `` calls its script initializer with `{}` and attempts access to undefined moduleOwn.data. In Node harness, import extracted page JS as .mjs, provide global $app_require$ stub, call default loader({}, {}, {}, exports, {}), then exports.entry({}): throws `Cannot read properties of undefined (reading 'data')`.
- Adding that script export makes the same probe pass. With aiot.__ce__ stub returning {type,props,children}, page.default.template({}) returns both intended text nodes. This is a compilation/initialization harness, NOT real Vela runtime or display validation. Hello Vela 1.1 (versionCode 2) delivered at ~/hellovela-release-1.1.rpk; USER CONFIRMED WORKING on Watch S4 41mm. No other source/layout/toolchain changes in this test. This establishes that plain-JS aiot-toolkit 2.0.5/Rspack 1.7.12 release packages work on this device; earlier blanket claims requiring JSC or older Rspack are disproven. Working page needs explicit script export in this compiler path. Calculator mockup continuation lives at ~/vela-calculator (same com.example.hellovela identity/signing, versionName 1.2/versionCode 3), preserving this working setup.
## Round-screen mockups
User's photo confirmed calculator v1.2 renders all keys, but user requested a layout more fitted to the circular display rather than a small rectangular keypad. Prefer wider middle rows and tapered top/bottom rows, larger labels and touch areas; check row bounds against the circular safe area numerically.
## TDD for watch apps (user-requested workflow)
When adding logic (not just mockups), write a Node test harness FIRST and watch it fail. Extract the `