Move trampoline files (boot-hook, watcher, overlay) into trampoline/ subdirectory. Add upstream Luma v2.3.1 source at repo root with our additions: - Page::Ha (4th nav tab) with placeholder empty state - HA tab config schema and default entity mapping (ha-home/) - Nav keys renamed: "home" → "start", new "ha" tab between Apps and Settings - All state.rs/view.rs/main.rs/tests.rs updated for 4-tab navigation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
6.3 KiB
Luma agent context
Project
Luma is a native Rust/SDL2/OpenGL ES 2 launcher for rooted LG webOS TVs. Rust source is in
src/, original assets/translations in assets/, shared vector geometry in vector-geometry/,
the host SVG compiler in tools/vector-assets/, packaging/tooling in tools/, and desktop smoke
scripts in tests/. There is no React/JSX/browser application. Read development.md for details.
Use pnpm, Oxlint and Oxfmt for build tools; Cargo/rustfmt/Clippy for Rust. nix develop supplies
pinned Rust 1.93, ARMv7 std, Node 24, pnpm 10.34.5, SDL2, woff2 and Python/fontTools. The webOS
SDK is separate: pnpm sdk, then set WEBOS_NDK to .build/toolchain/arm-webos-linux-gnueabi_sdk-buildroot.
pnpm install --frozen-lockfile
pnpm format:check
pnpm check
pnpm test
pnpm assets
pnpm test:smoke
pnpm run package
pnpm check does not execute tests. pnpm test is workspace unit tests; smoke scripts render
desktop OpenGL and mock weather HTTP. Linux can use xvfb-run -a pnpm test:smoke. Tests must not
contact real weather APIs or a TV. Respect any user instruction to use manual TV verification
instead of running automated tests. Builds/lint may still be run. Do not claim hardware behavior
from desktop checks. Add a pnpm changeset file for release-worthy changes and leave version
bumps to the automated Version Packages PR. Its pnpm version:release command synchronizes
package.json, appinfo.json, the root Cargo.toml, the luma entry in Cargo.lock and README
IPK examples. Supporting Rust crates retain independent versions. pnpm version:check checks
consistency without writing files. Code or behavior changes should use semantic versioning:
patch for backward-compatible fixes, minor for backward-compatible features, and major for
breaking changes. Documentation-only or maintenance changes that do not need a release can omit
a changeset.
Build and identity
com.ecklf.luma is the native app's ID and luma its executable. Root appinfo.json is the
package metadata source. It installs separately from the former web app com.luma.launcher and
prototypes com.luma.launcher.native and com.luma.native, all excluded from app inventory. Preferences are local JSON
per installation; browser local storage and preferences from other IDs are not migrated.
ARM builds must use the NDK's gnueabi soft-float calling convention and explicit sysroot, with
isolated pkg-config. Preserve the Cortex-A9/VFP Rust flags and getauxval compatibility.
The SDK's SDL has dummy video: use checksum-pinned SDL-webOS with standard SDL ABI and a real
webOS/Wayland backend. Do not use rust-sdl2's generic bundled SDL or ship host libraries. Native
packages use Architecture: arm, preserve executable mode and include licenses/checksums/feed.
Runtime constraints
Keep input/rendering on the SDL thread and TV/HTTP work off it. Luna requests originate from the
native process, not luna-send-pub -a impersonation. Inventory failure must never substitute demo
data on TV. Explicit --test-extra-apps is a labeled manual preview applied only after successful
inventory reads, with separate preferences and no placeholder launch requests.
Pointer hover/down must not move a clicked control. Home favorites use one horizontal strip; remote focus/reordering reveals the whole selected card. Apps Up/Down follows six-column grid indices, including offscreen rows, so headers cannot steal mid-grid navigation. Back restores setting subpage parents and supports SDL-webOS Back. OK finishes move mode without launching.
Vector icon/logo assets are standalone SVGs compiled to .lvec at build time. Font outlines
are tessellated only as needed; text runs use bounded GPU caches, lazy CJK and no glyph bitmap
atlas. Text AA prefers MSAA of intact outlines, with a narrow fringe fallback; keep physical
origin/baseline snapping and logical 1920×1080 layout. --resolution 4k is experimental, not a
shipping-default claim. Profiles count presentations; ordinary --frames is event-loop iterations.
Weather uses ureq/rustls, fixed Open-Meteo origins, bounded replies/timeouts, no proxy/redirects, separate workers/cache and generation IDs. Cache Celsius and convert units without replacing it. Only configured/enabled/visible Home starts forecasts. Shared translations are bundled locally. Match the current native design without on-screen weather credits; attribution remains in docs.
Assets
SVG sources and fonts retain licenses in assets/. TV app artwork is resolved at runtime from
inventory/installed manifests by src/app_artwork.rs, with an embedded Node 8-compatible elevated
reader for jailed installations. Reads/decoding stay on its worker; GPU uploads stay on SDL.
Refresh invalidates cached results. No collected icon map or card-colour JSON is used or shipped.
Desktop previews use curated vectors and generic/category fallbacks. Do not add dumped TV images
or per-TV icon maps to the repository.
Do not replace vector logos with PNG exports.
Curated vectors use the exact app-ID allowlist in src/branding.rs, never title/substring matching.
Every logo in assets/logos/ must have a desktop demo app. pnpm test:brands renders the full
gallery to .build/brands-gallery.png; source restoration via pnpm assets:brands is optional.
CI and releases
.github/workflows/ci.yml is native-only: format/lint/workspace tests, asset generation and
mocked desktop rendering, SDK setup, ARM cross-build, actual IPK verification/checksum/feed,
artifacts and guarded publication. Keep existing published-version/draft/tag-commit checks.
.github/workflows/changeset-status.yml maintains an informational changeset status comment on
PRs, including forks, with semantic-version guidance for code changes. It skips the generated
version PR. Its pull_request_target jobs must not install dependencies or run code from the PR.
.github/workflows/release-pr.yml maintains the Changesets version PR and dispatches its CI
checks with the built-in token. Only a merged changeset-release/main PR with a version increase
can publish after the main-branch CI build passes. Ordinary PRs, other merges and manual CI runs
still build/check/package but do not publish. See development.md#releases for setup and retries.
Only create commits or PRs when explicitly requested. For PR descriptions follow the global
commands/pr.md format instructions.