Add firmware config view/download to device pages#13
Conversation
docs/superpowers/specs/2026-07-09-yaml-view-download-design.md Approved design: a parallel `config` map in devices.json (the factory config where a repo has one, else the main per-variant yaml), a collapsible view/download block in step 1 that follows the variant selection, a render-epoch refactor of device.js's three async staleness guards, and validator plus data-driven Playwright coverage. Live fetch from GitHub raw, so no new deploy surface. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
docs/superpowers/plans/2026-07-09-yaml-view-download.md Six TDD tasks: validator config check, registry population (8 devices; temp-1/plt-1 deferred pending revision decision), render-epoch refactor, the config view/download block, config tests, and verification/PR. Includes the real per-variant config URL map probed from the product repos. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit adds a new check_config_shape() function to validate the optional config map structure, ensuring all config URLs are https and reachable. The reachability check is integrated into main() to HEAD-test every config URL. Unit tests verify shape validation works offline and covers all error conditions. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Replace the three ad-hoc "want" comparisons in renderInstall and renderReleaseNotes with a single per-renderDevice epoch counter that increments on every channel/variant change. Async renders capture their epoch at the start and bail if it no longer matches, giving one consistent staleness guard instead of three separate ones. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
WalkthroughAdds optional per-device ESPHome YAML URLs, validates their structure and reachability, and exposes selected configurations in the device UI with safe rendering, GitHub links, downloads, stale-request protection, styling, and Playwright coverage. ChangesDevice YAML configuration
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant DevicePage
participant DeviceRegistry
participant RawGitHub
participant Browser
DevicePage->>DeviceRegistry: read selected variant config URL
DevicePage->>RawGitHub: fetch YAML configuration
RawGitHub-->>DevicePage: return YAML text
DevicePage->>Browser: render YAML and GitHub link
Browser->>DevicePage: request configuration download
DevicePage->>Browser: download YAML with derived filename
Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
What does this change?
Closes #3. Adds a "view / download the firmware config" section to each device page, so users can rebuild or reflash a device from its ESPHome YAML and have it onboard like a factory unit (following the wiki setup steps). This is the reflash/rebuild path, distinct from #4's ESPHome Dashboard "adopt and customize" note.
Feature
raw.githubusercontent.comand rendered viatextContent(escaped). It offers a Download .yaml (Blob, with the real filename) and a View on GitHub link derived from the raw URL.Which config per device
_Factory.yamlwhere a repo has one (MSR-1, MSR-2, MTR-1, AIR-1), else the main per-variant config (R_PRO-1 W/ETH, CAST-1 W/ETH, PUMP-1, BTN-1, TEMP-1_R2, PLT-1). All 10 devices are mapped.Registry & validator
configmap indevices.jsonmirroringfirmware(channel → variant → raw YAML URL). Additive; firmware values untouched.scripts/validate_registry.pynow shape-checks and HEAD-checks everyconfigURL, so a broken config link fails CI like a broken manifest. Guarded against a malformed (null/non-dict) config. Offline unit tests added.Refactor
js/views/device.js's three ad-hoc async staleness guards into one render-epoch counter (also covers the new config fetch), so a stale fetch can never overwrite the current selection.Deploy
pages.ymlcp-list is unchanged.Note: the battery products TEMP-1B / PLT-1B aren't in
devices.jsonas installable devices — a separate registry-completeness item, out of scope here.Checklist
cd tests && npx playwright test) (18 passed, 1 intentional skip)cplist in.github/workflows/pages.yml(n/a: no new runtime files; the config is fetched live)devices.jsonchanged:python scripts/validate_registry.pypasses (Registry OK — manifests + all config URLs return 200)🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes