- Default enableDocker to false in UI to prevent unintended Docker
agent activation on host-only installs (Related to #766)
- Deploy agent scripts and binaries during web UI upgrades, not just
the main binary (Related to #760)
- Apply symlink resolution fix to standalone docker agent self-update
to prevent cross-device rename failures (Related to #737)
- Add content hash check to config watcher polling path to match fsnotify
behavior, preventing unnecessary restarts when .env is touched but
content unchanged (Related to #748)
- Change settings sidebar to expanded by default and persist user
preference using usePersistentSignal (Related to #764)
Remove ~900 lines of unused code identified by static analysis:
Go:
- internal/logging: Remove 10 unused functions (InitFromConfig, New,
FromContext, WithLogger, etc.) that were built but never integrated
- cmd/pulse-sensor-proxy: Remove 7 dead validation functions for a
removed command execution feature
- internal/metrics: Remove 8 unused notification metric functions and
10 Prometheus metrics that were never wired up
Frontend:
- Delete ActivationBanner.tsx stub component
- Remove unused exports: stopMetricsSampler, getSamplerStatus,
formatSpeedCompact, parseMetricKey, getResourceAlerts
Mark intentionally unused parameters with underscore to:
- Silence unparam warnings for legitimate unused parameters
- Keep function signatures intact for API compatibility
- Remove unused req from serveChecksum helper
- Replace custom maxInt64 helper with Go 1.21+ builtin max()
- Mark unused cfg parameter in newAdaptiveIntervalSelector
- Remove test for deleted helper function
- Use container.Summary instead of types.Container
- Use swarmtypes.ServiceListOptions instead of types.ServiceListOptions
- Use swarmtypes.TaskListOptions instead of types.TaskListOptions
These types were deprecated in favor of package-specific types.
- Merge variable declaration with assignment (S1021)
- Use unconditional strings.TrimPrefix (S1017)
- Remove unnecessary nil checks around range (S1031)
- Remove unnecessary fmt.Sprintf (S1039)
- Use copy() instead of manual loop (S1001)
- Use time.Until instead of t.Sub(time.Now()) (S1024)
- Use buf.String() instead of string(buf.Bytes()) (S1030)
- Fix SA4006 unused value issues in ssh.go, validation.go, generator.go
- Replace deprecated ioutil with io/os in config.go
- Replace deprecated tar.TypeRegA with tar.TypeReg
- Remove deprecated rand.Seed calls (auto-seeded in Go 1.20+)
- Fix always-true nil check in main.go
- Fix impossible nil comparison in tempproxy/client.go
- Add nil check for config in monitor.New()
Remove ChartData, Dataset, ConfigImportResponse, ConfigExportResponse,
InstallScriptResponse, ErrorResponse, and SuccessResponse types that
were defined but never used in the codebase.
Remove 121 lines of unused store methods:
- CSRFTokenStore: Stop, ExtendCSRFToken
- SessionStore: Stop, ExtendSession, GetSession
- RecoveryTokenStore: Stop, save, GetActiveTokenCount, ValidateRecoveryToken
These methods were part of a standard store pattern but never wired up
to the application lifecycle. The constant-time validation variant is
used instead of the timing-vulnerable ValidateRecoveryToken.
- Use defer for tempCancel() to ensure context is always cancelled
- Remove redundant shouldCollect variable that was always true
- Fix indentation after removing the unnecessary conditional block
Shows shield icon next to guest name when backup is stale or missing:
- Yellow shield: backup 24-72 hours old
- Red shield: backup older than 72 hours
- Gray shield: no backup found
Fresh backups (<24h) show no indicator to keep the UI clean.
Templates are excluded from backup status display.
When the agent binary is symlinked (e.g., from /opt/pulse/bin to
/usr/local/bin), the self-update would fail with "invalid cross-device
link" because os.Rename() doesn't work across filesystems.
Now resolves symlinks before update and creates the temp file in the
same directory as the real binary.
Related to #737
- Test ID generation (uniqueness, format)
- Test JSON response writing (various types, headers)
- Test boolean parsing (truthy/falsy values)
- Test environment variable trimming
- Test data directory resolution
- Test large payload handling
- Test encrypt/decrypt round-trip (various data types)
- Test string encryption (base64 output)
- Test key persistence across manager instances
- Test key file permissions (0600)
- Test decryption of invalid/corrupted data
- Test encryption uniqueness (random nonce)
- Test orphaned data protection
- Test large data encryption (1MB)
- Test API token generation (uniqueness, format)
- Test API token hashing (SHA3-256, deterministic)
- Test constant-time token comparison
- Test token hash detection
- Test password hashing (bcrypt, salted)
- Test password verification
- Test password complexity validation
- Verify bcrypt cost and minimum password length constants
Podman can return unstable or empty daemon IDs across API calls. When
the agent fetched info.ID on every report cycle, this could cause the
agent identity to change mid-session, triggering "token already in use"
errors on the server.
Cache the daemon ID at initialization and use it consistently for all
reports.
Related to #740
The unified agent handlers were using r.config.AppRoot which pointed
to /app, but scripts are in /opt/pulse/scripts. Updated to match the
pattern used by other script handlers - check /opt/pulse/scripts first,
then fall back to project root for dev environment.
Also added no-cache headers to prevent stale scripts being served.