Move SetupLogger() to a standalone function called before config.Load()
so the logger is available from the very start. Replace all fmt.Printf
calls in config.go with slog calls. Redirect banner and endpoint info
to stderr, keeping stdout clean for structured log output (JSON/text).
Fixes#5
Passwords containing @, #, :, ?, /, %, &, space and other special
characters broke URL parsing, causing streams to not be detected.
Replaced fmt.Sprintf string concatenation with url.URL struct for
building RTSP/HTTP URLs. Credentials in userinfo are now handled via
url.UserPassword() which encodes special chars automatically.
Split replacePlaceholders into two phases:
- Phase 1: safe placeholders (channel, width, IP, port)
- Phase 2: credential placeholders with context-aware encoding:
- Query string: url.Values.Set + Encode (auto percent-encoding)
- Path segments: url.PathEscape
Normal passwords (letters, digits, -._~) produce identical URLs
as before -- encoding is a no-op for safe characters.
Fixes#10
SecretStore.Add now registers both plain text and URL-encoded forms
of the password. Fixes cases where passwords with special characters
(e.g. @, #, :) appear percent-encoded in URLs but were not matched
by the masking handler.
Add a secret-masking slog.Handler that automatically replaces registered
passwords with "***" in all log output. Secrets are registered per-scan
when a discovery request arrives and unregistered when it completes.
This approach masks credentials everywhere they appear in logs — URL
userinfo, query parameters, path segments, and Go HTTP error messages —
without modifying any business logic in scanner, builder, tester, or
ONVIF components. API responses are unaffected and still return full
URLs with credentials for frontend use.
- Remove GitHub Actions workflows (ci.yml, docker.yml, release.yml)
- Remove GoReleaser configuration
- Remove RELEASE.md (replaced by /release_strix skill)
- Add HA options.json support in config.go (reads /data/options.json)
- Add Version field to Config, pass real version to health endpoint
- Change Version from const to var, inject via ldflags at build time
- Add ARG VERSION to Dockerfile for build-time version injection
- Reset webui/package.json version to 0.0.0 (not used functionally)
- Clear probe fields on back navigation in frontend
- Add /release_strix and /release_strix_dev skills
- Add ProbeAPI client (js/api/probe.js)
- Add reusable modal component (js/ui/modal.js) with overlay, animations
- Call GET /api/v1/probe after Check Address click
- Auto-fill Camera Model with vendor from ARP/OUI lookup
- Show modal on unreachable device with Change IP / Continue Anyway buttons
- Add modal CSS styles matching existing dark theme
- Add HTTPProber: parallel HEAD+GET on ports 80/8080, extracts Server header
- Reduce mDNS timeout from 1s to 100ms using context wrapper around
mdns.Query (HomeKit devices respond in 2-10ms, no need to wait 1s)
- Add Trassir (F0:23:B9) and ZOSI (00:05:FE) to camera OUI database
- Probe response time improved from ~1s to ~110ms for reachable devices
Fast (~1-3s) endpoint that gathers network info about a device
before full stream discovery. Runs ping first, then parallel probes.
Features:
- Ping with ICMP + TCP fallback (works without root)
- Reverse DNS hostname lookup
- ARP table MAC address + OUI vendor identification (2403 entries, 51 camera vendors)
- mDNS HomeKit detection (camera/doorbell, paired status)
- Extensible Prober interface for adding new probe types
- 3-second overall timeout, parallel execution
Response includes "type" field:
- "unreachable" - device not responding
- "standard" - normal IP camera (RTSP/HTTP/ONVIF flow)
- "homekit" - Apple HomeKit camera (PIN pairing flow)
Add padding to overcome aiohttp 64KB buffer in HA Supervisor.
Problem:
- HA Supervisor uses aiohttp with 64KB StreamResponse buffer
- Small SSE events (~200-500 bytes) were buffered until connection closed
- Users saw all streams appear at once instead of real-time updates
Solution:
- Detect Ingress mode via X-Ingress-Path header
- Add 64KB SSE comment padding to fill proxy buffers
- Increase progress interval to 3 sec in Ingress mode (reduce traffic)
- Normal mode (Docker/direct) unchanged - works exactly as before
Traffic impact:
- Normal mode: ~17KB per scan (unchanged)
- Ingress mode: ~2-3MB per scan (acceptable for real-time updates)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Split discovered streams into Recommended (FFMPEG, ONVIF) and Alternative groups
- Add Main/Sub/Other classification within Recommended based on resolution:
- Main: streams with width >= 720px (after clustering analysis)
- Sub: streams with width < 720px or lower cluster
- Other: streams without resolution info
- Implement smart auto-collapse based on selection mode:
- Main selection: shows Recommended/Main, collapses rest
- Sub selection: shows Recommended/Sub, collapses rest
- Falls back to showing all if target category is empty
- Add collapsible groups/subgroups with chevron toggles
- User manual expand/collapse preserved until mode change
- Add stream count badges to all group headers
- Add buildRtspPath() helper method to conditionally append ?mp4
- Only BUBBLE stream types get ?mp4 suffix for proper recording
- Other stream types (RTSP, ONVIF, JPEG, etc.) remain unchanged
- Handles both single and dual-stream configurations correctly
- Update docker run command to use --network host
- Update docker-compose.yml to use network_mode: host
- Update docker-compose.full.yml to use network_mode: host
- Remove port mappings as they are not needed with host network
- Fixed channel numbering for Hikvision-style cameras (reported by @sergbond_com)
- Added universal [CHANNEL+1] placeholder support
- Supports both 0-based and 1-based channel numbering
- Updated 14 camera brands with universal patterns
- Fixed brand+model search matching
- Removed invalid test data from database
- Removed entry with embedded credentials and IP address
- Entry contained: rtsp://huntertech:Superuser01!@10.0.55.11:554
- This was likely test data that accidentally got committed
- Model "Bullet-4K" entry removed from database
- Added 5 new URL patterns with [CHANNEL] placeholder
- Supports channels 0-255 for multi-camera DVR/NVR systems
- Patterns include /Streaming/Channels/[CHANNEL]01, [CHANNEL]02
- ISAPI format support with dynamic channels
- All existing hardcoded patterns preserved for compatibility
Problem:
- WriteTimeout was 30 seconds
- Progress only sent when values changed
- Long ffprobe tests (7-8s each) could cause 30+ seconds without writes
- Result: "curl: (18) transfer closed with outstanding read data remaining"
Solution:
- Increase WriteTimeout from 30s to 5 minutes
- Send progress every 1 second (instead of 3 seconds)
- Always send progress, even if values unchanged
- Guarantees write every second, preventing timeout
Changes:
- internal/config/config.go: WriteTimeout 30s → 5min
- internal/camera/discovery/scanner.go:
- Progress ticker 3s → 1s
- Remove "only if changed" check
- Always send progress to keep connection alive
Testing:
- HiWatch camera with 591 streams: Previously timed out at ~338/591
- Should now complete all 591 streams without timeout
- Add tooltips for all 7 stream types: FFMPEG, ONVIF, MJPEG, HLS, BUBBLE, JPEG, HTTP_VIDEO
- Each tooltip explains protocol features, use cases, and compatibility
- Add BUBBLE protocol icon and detailed description (XMEye/DVRIP cameras)
- Update mock streams to show one example of each type
- Remove unused mock-data.js file to reduce confusion
- Add CSS styles for stream type info icons
- Add informational tooltips to all configuration fields
- Reorder tabs: Frigate first, then Go2RTC, then URL
- Hide Copy/Download buttons on Frigate tab until config is generated
- Auto-fill username field with "admin" as default value
- Smart pre-fill network address based on server IP (first 3 octets)
- Add tooltips for Main Stream, Sub Stream, and all buttons
- Improve user guidance throughout the configuration flow
Добавлены информационные тултипы для всех полей формы настройки камеры с подробными описаниями, примерами использования и рекомендациями. Улучшает пользовательский опыт и помогает пользователям правильно заполнить форму.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace carousel navigation with scrollable vertical list
- Remove statistics counters (Tested/Found/Remaining)
- Add collapsible stream details with expand/collapse toggle
- Show stream URL preview in header, full URL in details
- Position URL below stream type badge for better readability
- Add new StreamList component replacing StreamCarousel
- Update CSS with improved layout and hover effects
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Restored stats block (Tested, Found, Remaining) that was accidentally
removed when adding mock mode functionality. This fixes JavaScript
errors where main.js tried to update non-existent DOM elements.
- Add mock API classes for camera search and stream discovery
- Add mock mode toggle via ?mock=true URL parameter
- Add visual mock mode indicator badge
- Add dev-server.sh script for local development
- Mock data includes 10 diverse streams (FFMPEG, ONVIF, JPEG, MJPEG, HLS, HTTP_VIDEO)
- Add mock data module with simulated camera search and stream discovery
- Enable mock mode via ?mock=true URL parameter
- Show MOCK MODE indicator when enabled
- Remove statistics cards from discovery screen, keep only progress bar
- Mock mode works independently from Go backend for easier UI testing