The Windows installer was only shipping mss as a screen-capture
backend, so EngineRegistry.get_available_engines() reported just
['mss', 'camera', 'demo'] on installed builds. Picture sources
configured to use bettercam/dxcam/wgc were rejected at the
test/ws handshake with HTTP 403 (close-before-accept on
"Engine '<x>' not available").
Add the three Windows screen-capture wheels to WIN_DEPS so the
installer build matches a 'pip install -e .' dev environment.
- build-common.sh: remove zeroconf/_services from the strip list.
zeroconf's compiled Cython _listener.pyd imports from _services
internally, so stripping it broke `import zeroconf` at runtime with
ModuleNotFoundError — same class of bug as the numpy.linalg strip.
- build-common.sh: add smoke_test_imports() that imports every top-level
dependency against the stripped site-packages. Catches "we stripped
something that was actually needed" regressions at build time instead
of on a user's machine after install.
- build-dist.sh: wire smoke test into the Linux flow (runs real imports).
- build-dist-windows.sh: cross-build can't load win_amd64 .pyd files with
the host python, so instead verify that the known-required submodule
dirs (numpy.linalg/lib/matrixlib/ma, zeroconf._services) exist after
cleanup. Fails loud if any future strip-rule removes them.
- build-common.sh: detect_version() normalizes non-PEP440 labels (e.g. 'dev',
'nightly') to 0.0.0.dev0 so stamping pyproject.toml doesn't break pip install.
- build-common.sh: split .py deletion out of cleanup_site_packages into a new
compile_and_strip_sources() that runs 'compileall -b' FIRST, then removes
sources. compileall now fails loud instead of silently no-op'ing.
- build-dist.sh: add missing compile_and_strip_sources call on Linux site-packages
(previous tarballs shipped empty packages with no .py and no .pyc).
- build-dist-windows.sh: reorder so compile_and_strip_sources runs right after
cleanup_site_packages, not after .py files have already been deleted.
- installer.nsi: RMDir /r payload dirs (python/, app/, scripts/) and delete
LedGrab.bat at the top of SecCore before File /r. NSIS File /r MERGES into
existing dirs, so upgrades left half-old/half-new state that surfaced as
'version mismatch' or duplicate-package ImportErrors. data/ and logs/ remain
untouched to preserve user config.
- Create utils/image_codec.py with cv2-based image helpers
- Replace PIL usage across all routes, filters, and engines with cv2
- Move Pillow from core deps to [tray] optional in pyproject.toml
- Extract shared build logic into build-common.sh (detect_version, cleanup, etc.)
- Strip unused NumPy/PIL/zeroconf/debug files in build scripts
release.yml: add fallback for existing releases on tag re-push.
installer.nsi: add .onInit file lock check, use LaunchApp function
instead of RUN_PARAMETERS to fix NSIS quoting bug.
build-dist.ps1: copy start-hidden.vbs to dist scripts/.
start-hidden.vbs: embedded Python fallback for installed/dev envs.
Update ci-cd.md with version detection, NSIS best practices, local
build testing, Gitea vs GitHub differences, troubleshooting.
Update frontend.md with full entity type checklist and common pitfalls.
Add compileall step to build-dist-windows.sh that generates .pyc files
for both app source and site-packages. Saves ~100-200ms on startup by
skipping parse/compile on first import.
- Replace winsdk (~35MB) with winrt packages (~2.5MB) for OS notification
listener. API is identical, 93% size reduction.
- Replace wmi (~3-5MB) with ctypes for monitor names (EnumDisplayDevicesW)
and camera names (SetupAPI). Zero external dependency.
- Migrate cv2.resize/imencode/LUT to Pillow/numpy in 5 files (filters,
preview helpers, kc_target_processor). OpenCV only needed for camera
and video stream now.
- Fix DefWindowProcW ctypes overflow on 64-bit Python (pre-existing bug
in platform_detector display power listener).
- Fix openLightbox import in streams-capture-templates.ts (was using
broken window cast instead of direct import).
- Add mandatory data migration policy to CLAUDE.md after silent data
loss incident from storage file rename without migration.
Strip unnecessary files from site-packages:
- Remove pip, setuptools, pythonwin (not needed at runtime)
- OpenCV: remove unused extra modules and data
- numpy: remove tests, f2py, typing stubs
- Remove all .dist-info directories and .pyi type stubs
- Remove winsdk type stubs
- Replace 7z with msiextract (msitools) to extract tkinter from
python.org's individual MSI packages (tcltk.msi + lib.msi)
- Fix build step numbering to /9
- Docker job continues on login failure (registry may not be enabled)
- Show makensis output for debugging
- Replace nuget approach (doesn't contain tkinter) with extracting
from the official Python amd64.exe installer using 7z
- Remove MUI_ICON/MUI_UNICON (no .ico file available, use NSIS default)
- Add p7zip-full to CI dependencies
- installer.nsi: per-user install to AppData, Start Menu shortcuts,
optional desktop shortcut and autostart, clean uninstall (preserves
data/), Add/Remove Programs registration
- build-dist-windows.sh: runs makensis after ZIP if available
- release.yml: install nsis in CI, upload both ZIP and setup.exe
- Fix Docker registry login (sed -E for https:// stripping)
Download _tkinter.pyd, tkinter package, and Tcl/Tk DLLs from the
official Python nuget package and copy them into the embedded Python
directory. This enables the screen overlay visualization during
calibration in the portable build.
- Move startup banner into main.py so it shows the actual configured
port instead of a hardcoded 8080 in the launcher scripts
- Wrap tkinter import in try/except so embedded Python (which lacks
tkinter) logs a warning instead of crashing the overlay thread
Windows: install-autostart.bat (Startup folder shortcut),
uninstall-autostart.bat. Linux: install-service.sh (systemd unit),
uninstall-service.sh.
Both launchers now use python -m wled_controller.main so port is
read from config/env instead of being hardcoded to 8080.
Windows embedded Python ignores PYTHONPATH when a ._pth file exists.
Add ../app/src to the ._pth so wled_controller is importable.
Fixes ModuleNotFoundError on portable builds.
Replace Windows runner requirement with cross-compilation:
download Windows embedded Python + win_amd64 wheels from PyPI,
package into the same ZIP structure as build-dist.ps1.
All 4 release jobs now run on ubuntu-latest.