Changed MetricBar type prop from conditional (value > 80 ? 'danger' : 'primary')
to semantic types ('cpu', 'memory', 'disk') for better maintainability and
consistency with the component's design system.
This allows MetricBar to handle threshold logic internally based on metric
type, rather than duplicating threshold conditions at each call site.
The checksum URL was incorrectly constructed by appending .sha256
to the entire download URL including query parameters, resulting in:
/download/pulse-host-agent?platform=linux&arch=amd64.sha256
This caused .sha256 to be part of the arch parameter, which prevented
the checksum endpoint from being reached correctly.
Fixed to construct checksum URL with .sha256 as part of the path:
/download/pulse-host-agent.sha256?platform=linux&arch=amd64
Tested on Proxmox VE host (delly):
- Installation: ✓ Binary downloaded and installed successfully
- Service: ✓ systemd service created, enabled, and started
- Validation: ✓ Service running and attempting to report
- Logs: ✓ JSON logs writing to /var/log/pulse/host-agent.log
- Uninstallation: ✓ Complete cleanup (binary, service, logs)
- Colors: ✓ ANSI colored output working properly
Note: Checksum validation gracefully handled when endpoint
unavailable (server doesn't provide checksums yet)
API Enhancements:
- Add SHA256 checksum endpoint for binary downloads
- Computes checksum on-the-fly when .sha256 suffix is requested
- Example: /download/pulse-host-agent?platform=linux&arch=amd64.sha256
- Enables installer scripts to verify binary integrity
- Add /uninstall-host-agent.sh endpoint for Linux/macOS uninstall script
- Add endpoint to public paths (no auth required)
Checksum Implementation:
- New serveChecksum() function computes SHA256 hash using crypto/sha256
- Returns plain text checksum in hex format
- Supports all binary download endpoints
- Zero performance impact (only computed when requested)
Install Script Updates:
- Add --force/-f flag to skip all interactive prompts
- URL/token prompts skipped with --force
- Reinstall confirmation skipped with --force
- Checksum mismatch still aborts (security first)
- Force mode auto-accepts updates and reinstalls
- Usage: ./install-host-agent.sh --url $URL --token $TOKEN --force
Security Notes:
- Checksum verification protects against:
- Corrupted downloads due to network issues
- Man-in-the-middle binary tampering
- Storage corruption on server
- Force mode maintains security by aborting on checksum mismatch
- No bypass for security-critical validations
These improvements enable:
- Automated deployments (--force flag)
- Binary integrity verification (checksums)
- Better security posture (tamper detection)
- Standardized uninstall process (endpoint)
The /api/version endpoint already exists and returns version info
for update checks (no changes needed).
Major improvements to the host agent installation experience:
Installation Enhancements:
- Add interactive mode with prompts for URL/token if not provided
- Add colored output with ANSI codes (✓ ℹ ⚠ ✗) matching Windows style
- Add professional header/footer with bordered sections
- Display masked configuration before installation
- Add version detection and update notifications
- Add reinstall confirmation for existing installations
Security Improvements:
- Store tokens in macOS Keychain instead of plaintext plist
- Create wrapper script to read token from Keychain at runtime
- Add SHA256 checksum verification for downloaded binaries
- Set restrictive permissions (chmod 600) on service configs
- Graceful fallback if Keychain access denied
Validation & Verification:
- Wait 10 seconds and verify service is running
- Query /api/hosts endpoint to confirm agent registered
- Verify hostname appears in Pulse server
- Provide detailed troubleshooting if validation fails
Error Handling:
- Comprehensive error messages with actionable guidance
- Platform-specific install instructions for missing dependencies
- 4-step troubleshooting guide for download failures
- Build-from-source fallback instructions
- Service failure diagnostics with log viewing commands
Logging Improvements:
- Use persistent log directories (no more /tmp)
- macOS: ~/Library/Logs/Pulse/host-agent.log
- Linux: /var/log/pulse/host-agent.log
- Automatically create log directories
Post-Install:
- Display service management commands (start/stop/restart/logs)
- Show installed file locations
- Provide uninstall instructions
- Link to Pulse dashboard
Uninstall Script:
- New dedicated uninstall script with colored output
- Comprehensive cleanup (service, binary, logs, Keychain)
- Platform detection and appropriate cleanup steps
- Remove macOS Keychain entries and wrapper scripts
- Remove temporary logs from old /tmp location
- Retry logic for file locking issues
Progress Indicators:
- Better download progress with curl --progress-bar
- Clear status messages for each installation step
- Visual feedback throughout installation
These changes bring the macOS/Linux installation experience to parity
with Windows and add several features that exceed Windows quality:
- API endpoint verification (Windows doesn't have)
- Checksum verification (Windows doesn't have)
- macOS Keychain integration (more secure than Windows config)
- Update detection (Windows doesn't have)
Windows Host Agent Enhancements:
- Implement native Windows service support using golang.org/x/sys/windows/svc
- Add Windows Event Log integration for troubleshooting
- Create professional PowerShell installation/uninstallation scripts
- Add process termination and retry logic to handle Windows file locking
- Register uninstall endpoint at /uninstall-host-agent.ps1
Host Agent UI Improvements:
- Add expandable drawer to Hosts page (click row to view details)
- Display system info, network interfaces, disks, and temperatures in cards
- Replace status badges with subtle colored indicators
- Remove redundant master-detail sidebar layout
- Add search filtering for hosts
Technical Details:
- service_windows.go: Windows service lifecycle management with graceful shutdown
- service_stub.go: Cross-platform compatibility for non-Windows builds
- install-host-agent.ps1: Full Windows installation with validation
- uninstall-host-agent.ps1: Clean removal with process termination and retries
- HostsOverview.tsx: Expandable row pattern matching Docker/Proxmox pages
Files Added:
- cmd/pulse-host-agent/service_windows.go
- cmd/pulse-host-agent/service_stub.go
- scripts/install-host-agent.ps1
- scripts/uninstall-host-agent.ps1
- frontend-modern/src/components/Hosts/HostsOverview.tsx
- frontend-modern/src/components/Hosts/HostsFilter.tsx
The Windows service now starts reliably with automatic restart on failure,
and the uninstall script handles file locking gracefully without requiring reboots.
- Add double-checks in global click handlers to prevent race conditions
- Add isCurrentlyMounted flag to prevent cleanup during re-renders
- Remove onBlur handler that was causing premature editor closure
- Simplify conditional logic in click handlers
These changes improve the robustness of the inline editor when
websocket updates occur during editing sessions.
The AnimatedMetric wrapper was causing distracting slide-up/slide-down
animations on every websocket update. While visually interesting, the
high-frequency updates made the dashboard feel too busy. Replaced with
direct value display while maintaining color-coded speed indicators.
Critical fixes to prevent the inline URL editor from closing during API updates:
1. Implement stable guest store with reconcile:
- Use createStore with reconcile() to maintain stable object references
- Key function ensures each guest keeps same proxy instance across updates
- Prevents <For> loop from remounting rows during websocket updates
2. Allow switching between guest editors:
- Mark guest name spans with data-guest-name-editable attribute
- Click handler allows clicking another guest name to switch editors
- Prevents click consumption when opening a different guest's editor
This ensures the inline editor stays open and preserves user input even when
websocket updates arrive, while still allowing seamless switching between
editing different guests.
Redesigned guest URL management from a bulky settings table to streamlined
inline editing directly on the dashboard:
Features:
- Single-click guest name to edit custom URL
- Text cursor indicates editability
- Inline editor with save (✓) and delete (✕) buttons
- Auto-focus and text selection on edit start
- Tag badges hidden during editing to maximize input space
- Click-away closes editor without activating underlying elements
Technical improvements:
- Global editing state prevents multiple simultaneous edits
- Smart click capture intercepts mousedown/click events when editor is open
- Prevents accidental row expansion or other actions during editing
- Delete button (✕) removes URL and icon entirely
- Escape key closes without saving
- Enter key saves and closes
Restructure the API token management interface with a focus on
information density and modern design patterns:
- Replace large card layouts with compact table view for token list
- Add visual statistics cards for total, scoped, and wildcard tokens
- Implement toggle button controls instead of checkboxes for scope selection
- Streamline token creation form with collapsible custom scopes
- Improve visual hierarchy with SectionHeader and ApiIcon components
- Add gradient backgrounds and refined spacing throughout
- Maintain accessibility while reducing overall page footprint
The new design presents all critical information at a glance while
preserving functionality and reducing visual clutter.
Adds polished gradient banner headers to all configuration pages:
- System > General, Network, Updates, Backups
- Security > Authentication (updated from gray to blue/indigo gradient)
- API Access
Resource management pages (PVE, PBS, Docker, etc.) intentionally left
without banners to keep focus on node tables and operational content.
Introduces granular permission scopes for API tokens (docker:report, docker:manage, host-agent:report, monitoring:read/write, settings:read/write) allowing tokens to be restricted to minimum required access. Legacy tokens default to full access until scopes are explicitly configured.
Adds standalone host agent for monitoring Linux, macOS, and Windows servers outside Proxmox/Docker estates. New Servers workspace in UI displays uptime, OS metadata, and capacity metrics from enrolled agents.
Includes comprehensive token management UI overhaul with scope presets, inline editing, and visual scope indicators.
Fixes build failure caused by unescaped apostrophes in single-quoted
strings. The Vite/Babel parser was failing on "You'll" and "you'll"
in ActivationModal.tsx, preventing successful frontend builds.
Replace harsh/technical language with clearer, more positive messaging:
BEFORE → AFTER:
- "No alert violations detected during observation yet" → "All systems healthy — no alerts triggered"
- "Monitoring is live; notifications will start after..." → "Monitoring is active. Review your settings..."
- "24h observation ending" → "24-hour setup period ending soon"
- "Review alerts before activating" → "Ready to activate notifications"
- "breached thresholds" → "triggered"
- "violations" → "alerts"
Key improvements:
- Removed jargon: "observation window", "during observation"
- Removed ominous language: "yet", harsh "violations"
- More conversational: "You'll receive" vs "will dispatch to configured destinations"
- Positive framing: "All systems healthy" vs absence-focused language
- Clearer actions: "turning on alerts" vs "enabling notifications"
- Enthusiastic success messages: "Notifications activated!" with exclamation
Affected components:
- ActivationBanner.tsx: 4 text improvements
- ActivationModal.tsx: 5 text improvements
Impact: Better first-run UX, less intimidating language, clearer call-to-action
Source builds use commit hashes (main-c147fa1) not semantic versions
(v4.23.0), so update checks would always fail or show misleading
"Update Available" banners.
Changes:
- Add IsSourceBuild flag to VersionInfo struct
- Detect source builds via BUILD_FROM_SOURCE marker file
- Skip update check for source builds (like Docker)
- Update frontend to show "Built from source" message
- Disable manual update check button for source builds
- Return "source" deployment type for source builds
Backend:
- internal/updates/version.go: Add isSourceBuildEnvironment() detection
- internal/updates/manager.go: Skip check with appropriate message
- internal/api/types.go: Add isSourceBuild to API response
- internal/api/router.go: Include isSourceBuild in version endpoint
Frontend:
- src/api/updates.ts: Add isSourceBuild to VersionInfo type
- src/stores/updates.ts: Don't poll for updates on source builds
- src/components/Settings/Settings.tsx: Show "Built from source" message
Fixes the confusing "Update Available" banner for users who explicitly
chose --source to get latest main branch code.
Co-authored-by: Codex AI
Adds freshness metadata tracking for all monitored instances:
- StalenessTracker with per-instance last success/error/mutation timestamps
- Change hash detection using SHA1 for detecting data mutations
- Normalized staleness scoring (0-1 scale) based on age vs maxStale
- Integration with PollMetrics for authoritative last-success data
- Wired into all poll functions (PVE/PBS/PMG) via UpdateSuccess/UpdateError
- Connected to scheduler as StalenessSource implementation
Task 4 of 10 complete. Ready for adaptive interval logic.
Discovery Fixes:
- Always update cache even when scan finds no servers (prevents stale data)
- Remove automatic re-add of deleted nodes to discovery (was causing confusion)
- Optimize Docker subnet scanning from 762 IPs to 254 IPs (3x faster)
- Add getHostSubnetFromGateway() to detect host network from container
Frontend Type Fixes:
- Fix ThresholdsTable editScope type errors
- Fix SnapshotAlertConfig index signature
- Remove unused variable in Settings.tsx
These changes make discovery faster, more reliable, and fix the issue where
deleted nodes would persist in the discovery cache or immediately reappear.
- Add instant-display tooltip on temperature column showing min-max range
- Color-code min/max temperatures individually (green/yellow/red)
- Remove unused NodeCard.tsx component from codebase
- Keep table row height consistent by using tooltip instead of inline display
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Track minimum and maximum CPU temperatures since monitoring started.
This provides better insight into temperature trends and cooling
adequacy over time.
Changes:
- Backend: Add CPUMin, CPUMaxRecord, MinRecorded, MaxRecorded fields
to Temperature model
- Backend: Implement min/max tracking logic in monitoring cycle that
preserves values across polling cycles
- Backend: Initialize min/max on first reading, update on extremes
- Frontend: Update Temperature TypeScript interface with new fields
- Frontend: Display min/max range in NodeCard tooltip (e.g., "52°C
(48-67°C since monitoring started)")
- Frontend: Rebuild dist assets
Temperature display now shows:
- Current temperature with color coding (green/yellow/red)
- Tooltip with full min-max range and context
- Min/max tracked in-memory (resets on Pulse restart)
Example tooltip: "CPU: 52°C (48-67°C since monitoring started)"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements automatic temperature monitoring setup for standalone
Proxmox/Pimox nodes without manual SSH key configuration.
Changes:
- Add /api/system/proxy-public-key endpoint to expose proxy's SSH public key
- Setup script now detects standalone nodes (non-cluster)
- Auto-fetches and installs proxy SSH key with forced commands
- Add Raspberry Pi temperature support via cpu_thermal and /sys/class/thermal
- Enhance setup script with better error handling for lm-sensors installation
- Add RPi detection to skip lm-sensors and use native thermal interface
Security:
- Public key endpoint is safe (public keys are meant to be public)
- All installed keys use forced command="sensors -j" with full restrictions
- No shell access, port forwarding, or other SSH features enabled
Implements automated cleanup workflow when nodes are deleted from Pulse, removing all monitoring footprint from the host. Changes include a new RPC handler in the sensor proxy for cleanup requests, enhanced node deletion modal with detailed cleanup explanations, and improved SSH key management with proper tagging for atomic updates.
Improvements to pulse-sensor-proxy:
- Fix cluster discovery to use pvecm status for IP addresses instead of node names
- Add standalone node support for non-clustered Proxmox hosts
- Enhanced SSH key push with detailed logging, success/failure tracking, and error reporting
- Add --pulse-server flag to installer for custom Pulse URLs
- Configure www-data group membership for Proxmox IPC access
UI and API cleanup:
- Remove unused "Ensure cluster keys" button from Settings
- Remove /api/diagnostics/temperature-proxy/ensure-cluster-keys endpoint
- Remove EnsureClusterKeys method from tempproxy client
The setup script already handles SSH key distribution during initial configuration,
making the manual refresh button redundant.