What's Changed
- data(cameras): add Reolink CX410 + EmpireTech IPC-B54IR to the compat DB (closes #181, #182) by @badbread in #258
- chore(release): add pr-changelog.sh (per-PR bulleted change list) + document it by @badbread in #257
- perf(timeline): sargable start_ts bound on the intensity query — O(retention) → O(window) (#256) by @badbread in #259
- perf(timeline): stop the motion-strip refresh from stacking under load (#256) by @badbread in #260
- perf(timeline): batch the per-camera intensity fan-out into one request (#256) by @badbread in #264
- iOS/macOS: v0.1.0 parity — Home Assistant overlays, LPR client, audio, data-saver, live/playback UX by @badbread in #261
- fix(android): quality label no longer wraps 'AUTO' to two lines (#262) by @badbread in #265
- feat(android): on-video Home Assistant badges on live (#263) by @badbread in #266
- feat(desktop): draggable HA edit panel + Dot badges show their label (#255) by @badbread in #267
- feat(desktop): seamless carousel/hotspot camera switching — no black gap (#254) by @badbread in #268
- fix(desktop): per-camera intensity fallback when the server lacks the batch endpoint (#270) by @badbread in #271
- fix(desktop): gate post-open seeks on file-loaded — no-motion frame-step 4s jump (#186) by @badbread in #272
- fix(desktop): actually freeze a maximized carousel/hotspot slot (#269) by @badbread in #273
- feat(desktop): in-app Diagnostics — bounded log capture, verbose toggle, scrubbed export (#180) by @badbread in #274
- ci(release): macOS attach race + Windows zip sha256 (#253) by @badbread in #275
- fix(recorder): storage-migration same-file guard — never unlink the only copy (#276) by @badbread in #282
- fix(recorder): quarantine prune ages from entry time + exempts -rN collision losers (#277) by @badbread in #283
- fix(recorder): floor deficit credited only for moves off the floor filesystem (#278) by @badbread in #284
- fix(recorder): footage lifecycle covers disabled cameras — the retention ceiling is absolute (#279) by @badbread in #285
- fix(recorder): worker-lifetime storage cache — reconnects survive a DB outage (#280) by @badbread in #286
- chore(recorder): hygiene batch — h>0 guard, TZ invariant wording, audit invariants 30–33 (#281) by @badbread in #287
- fix(api): bound the filmstrip window so one request can't OOM the api by @badbread in #295
- fix(api): harden clip-media ffmpeg spawns and the Frigate proxy read by @badbread in #296
- fix(android): guard scopedUrl() at 4 unguarded call sites in PlaybackViewModel by @badbread in #306
- fix(android): lifecycle-gate HA-states poll and pause clip player on background by @badbread in #307
- fix(android): move snapshot JPEG compress + MediaStore I/O off the main thread by @badbread in #308
- fix(android): make Time.parseToMillis lenient instead of crashing on parse failure by @badbread in #309
- fix(android): let CenteredTimeline's pinch-zoom span clamp match the host's own range by @badbread in #310
- fix(android): close export Create button's double-submit window by @badbread in #311
- fix(android): map SSLHandshakeException to a specific message instead of the generic one by @badbread in #312
- fix(android): minor correctness cleanups (clip-player guard, stale comments) by @badbread in #313
- fix(api): cap total finished-export bytes so a burst can't fill the disk by @badbread in #314
- fix(api): serialize go2rtc reconcile against stream teardown (delete race) by @badbread in #315
- fix(desktop): harden diagnostics log scrubbing to redact URL credentials by @badbread in #324
- fix(desktop): key HA-placement tracking by surface, not camera id by @badbread in #325
- fix(api): media tokens carry the minter's real caps, not a hardcoded full set by @badbread in #326
- fix(desktop): bound wedged stream-swaps with a timeout + recover a missed first-frame race by @badbread in #327
- fix(desktop): restore from maximize when the maximized camera drops out of _shown by @badbread in #328
- fix(desktop): detach playback pane player disposal from the UI isolate by @badbread in #329
- fix(desktop): honor stream-override menu on the maximized live pane by @badbread in #331
- fix(desktop): guard disposed-mid-load players, detach error-path dispose by @badbread in #332
- fix(api): security hardening batch — log redaction, XSS, and export/events authz by @badbread in #333
- fix(desktop): funnel live-wall 401s into the re-auth prompt by @badbread in #334
- fix(desktop): carry camera identity with the pending player, not widget.camera by @badbread in #330
- fix(ios): clamp trun sample_count to prevent OOM on malformed fMP4 by @badbread in #345
- fix(ios): hop session-token clear to the main actor on a 401 by @badbread in #346
- fix(ios): stop the live stream controller when PiP closes after detaching by @badbread in #347
- fix(install): secrets-overlay project name, password escaping, env/TZ/DR hygiene by @badbread in #357
- docs: v0.1.1 presentation hygiene + release-process bump step by @badbread in #359
- docs(ops): remove the postgres container before the volume swap in DR recovery by @badbread in #360
- fix(android): v0.1.1 verification-pass polish (CancellationException + backoff clamp) by @badbread in #362
- fix(desktop): v0.1.1 verification-pass polish (6 fixes) by @badbread in #361
- fix(api): carry view_plates in media tokens so plate crops load (regression) by @badbread in #365
- fix(ios): within-segment seeks and failed media-token mints during playback by @badbread in #348
- fix(ios): downsample plate images before caching by @badbread in #349
- fix(ios): stream export downloads to disk instead of buffering in memory by @badbread in #350
- fix(ios): hop HEVC-retag totalSize write to the main actor by @badbread in #351
- fix(ios): don't discard a successful login on a transient /auth/me failure by @badbread in #352
- fix(ios): shield content on .inactive so the app-switcher snapshot can't leak it by @badbread in #353
- fix(desktop): chunk motion-intensity batch into <=64-camera requests by @badbread in #375
- fix(android): grey HA badges after 2 missed polls (client-side staleness) by @badbread in #376
- fix(ios): batch the timeline-intensity fan-out (429 storm at 100+ cameras) by @badbread in #377
- fix(api): v0.1.1 cross-boundary audit batch (clips total, live cap, plate-clip cap, long-GOP intensity) by @badbread in #374
- release: v0.1.1 (VERSION bump + CHANGELOG) by @badbread in #378
Full Changelog: v0.1.0...v0.1.1