Files
deck_in_a_dash/watch
ml b94e76931a
build / build (push) Successful in 18s
Replace the watch app's menu UI with a single scrollable report page, add the config page
Report screen (ui_report_window.c, new): replaces the MenuLayer +
per-item drill-down windows (ui_menu_window.c/h, ui_card_window.c/h,
removed) with one continuously scrollable page mirroring the
interpreter's own text/HTML report - day significance, each transit's
narrative, the full Celtic Cross spread, and guidance last. Bigger/
bolder fonts throughout. Card images are a fixed 72px wide: a full-
display-width version was tried first but reliably crashes the real
PNG decoder ("PNG memory allocation failed") on actual hardware,
independent of the app's own heap or lazy-loading - 72px is the
hardware-verified ceiling.

Config page (pkjs/index.js): a self-contained `data:` URI settings form
for birth data/language/notification, submitting via AppMessage to the
existing app_message.c receiver. package.json needed
"capabilities": ["configurable"] for the Pebble mobile app to expose a
Settings entry for the sideloaded app at all - app_message.c's own
receiving logic was already correct. Added config_log() (config.c) to
confirm on-device, via APP_LOG, exactly which values a shown reading is
based on - both right after a config submission and at every app
launch.
2026-07-14 19:03:25 +02:00
..

Deck in a Dash - Pebble watch app

The actual watchapp: shows the same daily tarot + astrology reading as dist/run-interpreter.sh, computed entirely on-device (no companion app, no server - birth data, language, and notification settings are entered via a Pebble config page and persisted on-watch).

Layout

watch/
  package.json     Pebble app manifest (uuid, targetPlatforms, messageKeys, resources)
  wscript           waf build rules - see its own top-of-file comment for
                    why this app's C sources are NOT a plain src/c/**/*.c
                    glob (most of the actual logic lives in ../engine/src/,
                    shared byte-for-byte with the desktop deck-engine/
                    interpreter-cli binaries)
  src/c/            Watch-only C: UI, persisted config, on-device reading
                    orchestration, daily notification wakeup
  src/pkjs/         pkjs config webview (birth data/language/notification
                    settings) - a self-contained `data:` URI form, no
                    server
  resources/        Bitmap resources (card art, app icon) - resources/img/
                    is generated (gitignored), see below
  scripts/          Build-time codegen: gen_i18n_tables.py (translation
                    tables from ../engine/i18n/*.lang) and
                    gen_card_images.py (downsized card art from
                    ../res/img/*.jpeg) - both run automatically by
                    wscript on every `pebble build` (see its own comment
                    for why that stays cheap on repeat builds)

Building

Requires the Pebble SDK/tool (pebble CLI) and Pillow (pip install Pillow, used only by gen_card_images.py) - neither is part of this repo's own make/make test toolchain, which only builds the desktop deck-engine/interpreter-cli binaries. From this directory:

pebble build     # -> build/watch.pbw

The root Makefile's make watchapp target wraps this and copies the resulting .pbw into dist/, versioned the same way as make package - see the root CLAUDE.md's "Packaging" section.

Platform support

targetPlatforms deliberately excludes aplite (original Pebble / Pebble Steel). A Pebble app's entire code+data+bss footprint shares one 64KB region on basalt-class platforms, but only 24KB on aplite - and even this project's minimal skeleton (blank window + one reading_generate() call, no UI/config/persistence/notification code yet) already uses 19KB of it, leaving only ~5.5KB of headroom. That's not enough room for the multi-screen UI, on-watch config persistence, and wakeup-based daily notification this app still needs to add - basalt and newer (chalk/diorite/emery/flint/gabbro) all have comfortable 46-112KB of free heap for the same skeleton.