Dependency-free Canvas2D editor in the Sprites tab (EDIT button): pencil/eraser/picker/fill/pan, zoom & pan, undo/redo, grid overlay, load existing, export 500x333 PNG. Reuses the existing sprite upload endpoint — no new server route.
2. Receiver management overhaul
Per-receiver health: server tracks state (connecting/connected/down), message count, last-seen; new GET /api/admin/receiver-status and POST /api/admin/test-receivers.
Receivers tab redesign: live Active Receivers panel with colored indicators (green=receiving, yellow=connected/no data, red=unreachable), a clear select → SAVE & APPLY → auto-test flow, and selectable scan results (USE SELECTED RECEIVERS).
Interface scan selector: scan a chosen interface/subnet instead of every local subnet; oversized subnets (e.g. a docker /16) are disabled in the UI and rejected server-side.
3. Critical fix — server crash on receiver restart
Receiver tasks were awaited in main()'s top-level asyncio.gather; restarting receivers cancelled them and the CancelledError killed the whole server process. Receiver tasks now run independently and are cancelled/awaited with return_exceptions=True.
Also: cache-bust admin assets (?v=) so updates load without a manual hard-refresh.
Two areas of work, verified end-to-end against a live receiver.
## 1. In-app pixel editor for sprites (closes #5)
Dependency-free Canvas2D editor in the Sprites tab (EDIT button): pencil/eraser/picker/fill/pan, zoom & pan, undo/redo, grid overlay, load existing, export 500x333 PNG. Reuses the existing sprite upload endpoint — no new server route.
## 2. Receiver management overhaul
- **Per-receiver health**: server tracks state (connecting/connected/down), message count, last-seen; new `GET /api/admin/receiver-status` and `POST /api/admin/test-receivers`.
- **Receivers tab redesign**: live Active Receivers panel with colored indicators (green=receiving, yellow=connected/no data, red=unreachable), a clear select → SAVE & APPLY → auto-test flow, and selectable scan results (USE SELECTED RECEIVERS).
- **Interface scan selector**: scan a chosen interface/subnet instead of every local subnet; oversized subnets (e.g. a docker /16) are disabled in the UI and rejected server-side.
## 3. Critical fix — server crash on receiver restart
Receiver tasks were awaited in `main()`'s top-level `asyncio.gather`; restarting receivers cancelled them and the `CancelledError` killed the whole server process. Receiver tasks now run independently and are cancelled/awaited with `return_exceptions=True`.
Also: cache-bust admin assets (`?v=`) so updates load without a manual hard-refresh.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Build a dependency-free Canvas2D pixel editor integrated into the admin
Sprites tab. Each sprite card gains an EDIT button that opens a full-screen
editor for the sprite at its native 500x333 resolution.
Tools: pencil (1-8px brush, Bresenham interpolation), eraser, color picker
(palette + native input + pick-from-canvas), fill bucket (flood fill), pan.
Features: cursor-centered zoom, space-drag pan, undo/redo (snapshot per
stroke), pixel grid overlay, transparency checkerboard, load existing sprite,
and keyboard shortcuts (B/E/I/F, Space, +/-/0, Ctrl+Z/Y, G, Esc).
Export reuses the existing POST /api/admin/sprites/{type} upload endpoint via
srcCanvas.toBlob, so no server changes are required.
Closes#5
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Receiver management improvements for the admin Receivers tab:
- Per-receiver health: server now tracks each connection's state
(connecting/connected/down), message count, and last-message time, exposed
via new GET /api/admin/receiver-status and POST /api/admin/test-receivers.
- Receivers tab redesign: live "Active Receivers" panel with colored
indicators (green=receiving, yellow=connected/no data, red=unreachable),
a clear select -> SAVE & APPLY -> auto-test flow, and selectable scan
results with a "USE SELECTED RECEIVERS" action.
- Network scan interface selector: scan a chosen interface/subnet instead of
every local subnet. Oversized subnets (>/20, e.g. a docker /16) are disabled
in the UI and rejected server-side, eliminating slow/hanging scans.
Critical fix — server crash on receiver restart:
- Receiver connection tasks were awaited inside main()'s top-level
asyncio.gather. Restarting receivers cancels those tasks, and the resulting
CancelledError propagated into the gather and killed the whole server
process (every action after a restart then failed). Receiver tasks now run
as independent background tasks; restart cancels and awaits them with
return_exceptions=True so cancellation can never tear down the server.
Also cache-bust admin.css/admin.js/pixel-editor.js (?v=) so updated assets
load without a manual hard-refresh, and surface a clear message instead of a
silent "Loading…" when the status endpoint is unavailable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
allen
changed title from Add in-app pixel editor for sprites in admin UI to Admin: in-app sprite pixel editor + receiver health UX & restart-crash fix2026-06-09 12:50:17 -07:00
allen
merged commit 3e7cc11e08 into main2026-06-09 12:50:34 -07:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Two areas of work, verified end-to-end against a live receiver.
1. In-app pixel editor for sprites (closes #5)
Dependency-free Canvas2D editor in the Sprites tab (EDIT button): pencil/eraser/picker/fill/pan, zoom & pan, undo/redo, grid overlay, load existing, export 500x333 PNG. Reuses the existing sprite upload endpoint — no new server route.
2. Receiver management overhaul
GET /api/admin/receiver-statusandPOST /api/admin/test-receivers.3. Critical fix — server crash on receiver restart
Receiver tasks were awaited in
main()'s top-levelasyncio.gather; restarting receivers cancelled them and theCancelledErrorkilled the whole server process. Receiver tasks now run independently and are cancelled/awaited withreturn_exceptions=True.Also: cache-bust admin assets (
?v=) so updates load without a manual hard-refresh.🤖 Generated with Claude Code
Build a dependency-free Canvas2D pixel editor integrated into the admin Sprites tab. Each sprite card gains an EDIT button that opens a full-screen editor for the sprite at its native 500x333 resolution. Tools: pencil (1-8px brush, Bresenham interpolation), eraser, color picker (palette + native input + pick-from-canvas), fill bucket (flood fill), pan. Features: cursor-centered zoom, space-drag pan, undo/redo (snapshot per stroke), pixel grid overlay, transparency checkerboard, load existing sprite, and keyboard shortcuts (B/E/I/F, Space, +/-/0, Ctrl+Z/Y, G, Esc). Export reuses the existing POST /api/admin/sprites/{type} upload endpoint via srcCanvas.toBlob, so no server changes are required. Closes #5 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Add in-app pixel editor for sprites in admin UIto Admin: in-app sprite pixel editor + receiver health UX & restart-crash fix