mirror of
https://github.com/screentinker/screentinker.git
synced 2026-08-13 22:03:13 -06:00
A BrightSign could see things the page cannot ask for — the uptime, the wired IP, the video mode in force, which volume it booted from, whether a staged package applied — and it printed all of it to a serial console. On a panel on a wall that is the same as reporting nothing. The cost was concrete and recent. A single bad string literal stopped the host script compiling; the only evidence anywhere was one line on a cable, and from the server the display looked identical to one that had never started. Diagnosing it needed someone physically present with a serial adapter. Every other player reports its own failures. Three hops, each thin: the host posts, the bridge carries, the player emits on the channels it already uses (device:log, device:event, and the telemetry the heartbeat has carried for releases). The pre-widget phase is the part that matters and the part that was hardest to reach — the storage probe, a pending package being applied, the video mode being set, all happen before there is a page to talk to. Those lines accumulate in a buffer and flush the moment the widget exists, so the boot story arrives even though it happened before anyone could listen. BrightScript has no global store here (no GetGlobalAA), so the buffer is threaded explicitly; losing the boot entirely was the worse option. Two things become incidents rather than console lines: the watchdog rebuilding a wedged widget, which is the most important thing a player does unattended and previously healed in silence — a panel rebuilding itself every two minutes looked exactly like a healthy one — and a load-error, which now names the resource that failed. Both use event types the server actually accepts; an invented one is dropped silently and would have been just as invisible. Host telemetry merges into the existing snapshot rather than opening a channel, and the host's numbers win where they overlap: navigator.storage.estimate() describes the widget's cache quota, not the disk, so a panel can report gigabytes free while the volume holding them is full. Two API traps caught in my own new code before it shipped, both the same shape as the ones being fixed: Str() applied to a value already documented as a String (it is for numbers, and would abort the event loop while reporting a diagnostic), and Stri() handed a float from an inline division. The checker now pins the first. Verified on the XT245: boots clean, plays, online. The bridge and player halves are served BY the server, so they take effect on the next deploy. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL |
||
|---|---|---|
| .. | ||
| config | ||
| db | ||
| lib | ||
| middleware | ||
| player | ||
| routes | ||
| scripts | ||
| services | ||
| test | ||
| ws | ||
| .gitignore | ||
| config.js | ||
| package-lock.json | ||
| package.json | ||
| server.js | ||
| smoke-ui.js | ||
| version.js | ||