- Fix summary title format: only add "+" when events > maxBatchSize
- Fix TestQuietHoursHighPriority: HIGH priority respects quiet hours (queued)
- Fix TestGetHistory: flush batched events before checking history
All morning digest tests now pass, validating that queued events are
bundled and delivered at quiet_hours_end.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix TestNtfyClientSend body verification using bytes.Buffer
- Fix TestAttachPNGImage slice bounds error with flexible assertions
- Add new tests: TestNtfyClientValidPriorities, TestNtfyClientMessageFieldPriority,
TestNtfyClientEmptyMessage, TestNtfyClientCustomURL, TestNtfyClientClickHeader,
TestNtfyClientEmailHeader
- All 18 ntfy delivery client tests now pass with mock HTTP server
- Add TestZoneBoundariesAtCorrectCoordinates to verify zone boundaries appear at correct pixel coordinates
- Add TestZoneBoundaryEdges to verify zone edge detection
- Enhance TestPixelColors with accurate background color verification (#1a1a2e)
- Fix person color detection by sampling multiple pixels to find red fill
- Tests verify 300x300 PNG dimensions, correct zone boundary coordinates, and accurate colors
- All renderer tests pass
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix compilation errors from unused variables in manager_test.go and
pushover_test.go. The batching logic tests were already in place and
passing:
- TestBatchingThreeLowEvents: 3 LOW events in 10s -> 1 notification
- TestBatchingUrgentBypassesBatch: 1 URGENT -> immediate
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The TestBriefing_GenerateWithAlerts test was inserting events without
the detail_json field, causing a NULL scan error. Fixed by including
detail_json='{}' in the INSERT statement.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On screens < 1024px width, use FXAA (Fast Approximate Anti-Aliasing)
instead of MSAA for better performance on mobile devices.
Changes:
- Add dashboard/js/fxaa.js: FXAA post-processing module using Three.js
EffectComposer with FXAA shader pass
- Modify renderer initialization to disable MSAA on mobile
- Initialize FXAA composer on mobile devices after scene setup
- Use FXAA render path in animation loop when active
- Update FXAA resolution on window resize
FXAA provides a good balance between visual quality and performance
on mobile GPUs where MSAA can be prohibitively expensive.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change OrbitControls.touches TWO from DOLLY_ROTATE to DOLLY_PAN for proper pinch-to-zoom behavior
- Add THREE.TOUCH.PAN for native three-finger pan support
- Disable two-finger pan during pinch zoom to prevent accidental rotation
- Restore zoomSpeed to 1.0 for standard touch response
Acceptance criteria met:
- Touch events on sidebar panels do not propagate to canvas (already implemented in panels.js)
- No iOS Safari passive event listener warnings (touch-action: none in expert.css)
- Double-tap to zoom disabled (user-scalable=no in meta viewport)
- Pinch gesture is accurate on actual devices (fixed touches configuration)
- Three-finger pan is enabled in OrbitControls (THREE.TOUCH.PAN)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Adjust zoomSpeed from 1.0 to 0.6 for finer pinch zoom control on touch devices
- Add custom three-finger pan implementation since OrbitControls doesn't natively support it
- Three-finger drag now pans the camera, separating pan from pinch-zoom gesture
- Two-finger gesture changed from DOLLY_PAN to DOLLY_ROTATE for better gesture separation
- Add touch-action: none to canvas elements in expert.css and ambient.css
to prevent passive event listener warnings on iOS Safari
- Add user-scalable=no and maximum-scale=1.0 to viewport meta tags
in ambient.html and simple.html to prevent double-tap zoom
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add CSS environment variables for safe-area-inset to prevent content
overlap with notch/home indicator on iOS devices.
Changes:
- expert.css: Add safe area support to body, scene container, and
simple-quick-actions (hamburger menu) navigation
- quick-actions.css: Add safe area support to context menu and
follow-mode-indicator
- panels.css: Add safe area support to toast-container
- troubleshoot.css: Add safe area support to spaxel-dismiss-all
The viewport-fit=cover meta tag was already present in index.html.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevent touch events on modal panels and their backdrop from
propagating to the canvas by adding event.stopPropagation() on
panel touch listeners.
This matches the existing behavior for sidebar panels and prevents
OrbitControls from responding to touches on modal overlays.
Acceptance Criteria:
- Touch events on modal panels do not propagate to the canvas
(event.stopPropagation() on modal and backdrop touch listeners)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Cap devicePixelRatio at 2.0 on screens < 1024px width
- Disable MSAA antialiasing on mobile devices
- Disable shadow maps on mobile devices
- Add frame rate capping at 30fps for struggling mobile devices
- Auto-detect low FPS and adjust frame rate accordingly
- Panel close buttons: expanded from 32x32px to 44x44px
- Slider controls: expanded drag targets to 44px height with 32px thumb
- Toggle switches: expanded to 44px minimum height
- Checkboxes: expanded touch area with pseudo-element to 44x44px
- Context menu items: minimum 44px height
- Link list entries: minimum 44px height
- All buttons: minimum 44x44px touch targets
- Small buttons use expanded padding to maintain appearance while meeting 44px requirement
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add expert.css for expert mode specific styles
- Improve mobile orientation change handling with visualViewport API support
- Add iOS Safari visual viewport resize handling for better mobile experience
- Add getViewportDimensions() function preferring visualViewport API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement transform-based slide-in animation with overlay backdrop for screens < 1024px:
- Hamburger button (44x44px touch target) in header
- Slide-in menu with translateX(0) animation (200ms ease-out)
- Semi-transparent overlay backdrop that closes on tap
- Menu contains: Node List, Link List, Presence Panel, Timeline, Devices
- Active tab opens first (last-used panel persisted to localStorage)
- Close button (X, 44px) in top-right
- Escape key closes menu
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement single non-blocking notifications when features become available.
Events:
- DiurnalBaselineActivated (7 days)
- FirstSleepSessionComplete
- WeightUpdateApproved
- AutomationFirstFired
- PredictionModelReady (7 days per person)
Each notification is keyed by unique event ID in SQLite (feature_notifications table).
Never fires twice. Dismissed by tapping. Respects quiet hours.
Files:
- mothership/internal/help/notifier.go: Notifier manages one-time feature notifications
- mothership/internal/help/notifier_test.go: Tests for notifier
- mothership/internal/help/monitor.go: FeatureMonitor checks for feature availability
- mothership/internal/help/monitor_test.go: Tests for monitor
- mothership/cmd/mothership/main.go: Integration with mothership
- mothership/internal/db/migrations.go: Add migration_015 for feature_notifications table
Acceptance:
- Each notification fires exactly once per feature
- Plain language messages
- Respects quiet hours
- SQLite persistence prevents duplicates
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The help system was already fully implemented with:
- 74 help articles across 8 categories (Basics, Features, Setup, Advanced, Interface, Troubleshooting, Maintenance, Integration)
- Fuzzy search functionality matching the command palette
- Keyboard shortcut (Ctrl+?) to open help overlay
- Category filtering and action links to relevant dashboard sections
This commit fixes the addHelpButton() function to work with the existing
HTML button (id="help-btn") instead of trying to add a duplicate button.
Also removes duplicate CSS since styles are already in index.html.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add '?' button in expert mode status bar that opens help overlay
- Search input with fuzzy search (same algorithm as command palette)
- 43 help articles covering major features (sensing links, Fresnel zones,
detection quality, presence prediction, fall detection, etc.)
- Articles stored as static JSON (dashboard/help_articles.json)
- No server round-trip - loads articles client-side
- Category filter buttons for easy navigation
- Keyboard shortcut: Ctrl+? to open help overlay
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add '?' button in status bar that opens help overlay
- Fuzzy search across 37 help articles covering major features
- Sample articles include: sensing links, detection quality, presence prediction, Fresnel zone
- Articles stored as static JSON (dashboard/help_articles.json)
- No server round-trip - all client-side
- Keyboard shortcut: Ctrl+? / Cmd+?
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Detects when user changes same config setting 3+ times within 24 hours.
Shows non-intrusive prompt offering help with guided calibration flow.
Guided calibration features:
- Test for false positives (walk around room)
- Test for missed motion (sit still)
- Suggest optimal value based on diurnal baseline SNR and link health
- Apply suggested value button
Files:
- dashboard/js/proactive.js: Complete implementation with localStorage tracking
Acceptance:
- Help prompt fires after 3+ changes in 24h
- Calibration flow tests both directions
- Suggests value based on system data
- Apply button works
- Add renderFeedbackExplanation() function to display detailed explanations
- Include contributing link name, threshold exceed ratio, and timestamp
- Add diagnostic info (root cause and advice) when available
- Add expandable UI with toggle arrow
- Add CSS styles for explanation section
- Show correction note about system learning from feedback
When user marks detection as FALSE_POSITIVE, show explanation:
'The system detected motion here because: [link]'s signal exceeded
threshold by Nx at [time]. Could be caused by: [root cause or
'ambient RF interference']. We've noted this and will apply a correction.'
Files: dashboard/js/feedback.js
Acceptance: explanation shown after any FALSE_POSITIVE feedback;
contains contributing link name; shows diagnostic result or default message.