Commit Graph

2098 Commits

Author SHA1 Message Date
rcourtman 90f152e8ba fix(storage): correct column priority types and setup pre-push hook
- Fix Storage.tsx using number priorities instead of string literals
- Move husky configuration to repository root for proper git hook support
- Add package.json/lock.json to root (un-ignore in .gitignore)
- Configure pre-push hook to run type-check before push
2025-12-26 12:21:37 +00:00
rcourtman 6502092087 fix: Add --disk-exclude support to install script
Users can now pass disk exclusion patterns during agent installation:

  curl ... | bash -s -- --disk-exclude '/mnt/*' --url ... --token ...

The flag is repeatable for multiple exclusion patterns.

Related to #896
2025-12-26 12:11:18 +00:00
rcourtman cf15c035ea fix(storage): add toggleable flag to column definitions
The columns weren't appearing in the ColumnPicker because they
were missing the 'toggleable: true' property.
2025-12-26 11:57:29 +00:00
rcourtman e13605d2f3 fix: Allow clearing AI findings when AI is disabled
Users who accumulated AI findings before the patrol-without-AI bug was
fixed (24c4bb0b) could not dismiss them because the AI Insights tab
and Clear All button were only visible when patrol was enabled.

Now the AI Insights tab and Clear All button are visible whenever there
are findings to clear, even if AI/patrol is not enabled.

Related to #885
2025-12-26 11:43:34 +00:00
rcourtman c89ec7bc50 ci: add pre-push hook to prevent TypeScript CI failures
Adds husky with a pre-push hook that runs type-check before allowing
pushes. This catches the TypeScript errors locally that were causing
repeated CI failures and email spam.

Skip with: git push --no-verify
2025-12-26 11:37:37 +00:00
rcourtman 1185294174 refactor(dashboard): merge Needs Backup into Problems filter
- Removed redundant 'Needs Backup' toggle from filter bar
- Problems filter already includes backup issues (stale, critical, never)
- Reduces UI clutter while preserving functionality
- Also includes user's lint fixes for Backups tests
2025-12-26 11:13:41 +00:00
rcourtman 89d861fe92 fix(frontend): resolve TypeScript errors causing CI failures
- Remove unused setUseRelativeTime in UnifiedBackups.tsx (TS6133)
- Remove unused testing-library imports in PBSEnhancementBanner.test.ts (TS6133)
- Fix type comparison in test by using union type instead of 'as const' (TS2367)
2025-12-26 11:06:42 +00:00
rcourtman 7ecd07834e refactor(dashboard): smart Reset button matches pattern
Reset button now only shows when filters are active,
consistent with Backups and Storage pages.
2025-12-26 11:03:01 +00:00
rcourtman b4c9785aa7 refactor(storage): match filter bar to Backups pattern
- Full-width search bar on its own row
- Smart Reset button (only shows when filters active)
- Simplified sort options dropdown
- Consistent flex-wrap layout with gap-x-2 gap-y-2

Maintains consistency across Proxmox pages.
2025-12-26 10:53:11 +00:00
rcourtman 9a0a39d3c1 refactor(backups): simplify filter bar layout
- Made search bar full-width and prominent
- Removed redundant Status Filter (can use search)
- Removed redundant Type Filter (overlaps with Source)
- Removed Time Format toggle (rarely used)
- Integrated ColumnPicker inline with filter groups
- Layout now matches Dashboard/Overview pattern

Reduces filter controls from ~10 groups to 5 for cleaner UX.
2025-12-26 10:40:41 +00:00
rcourtman 5ed2a70d2e feat(backups): add column visibility toggle with Comment column
- Add useColumnVisibility hook to Backups table
- Add ColumnPicker component for toggling columns
- Add Comment column for PBS backups (hidden by default)
- Owner, Size, Storage, Verified columns now toggleable
- Column visibility persisted to localStorage

PBS backups with comments now show the comment when the column
is enabled via the Columns picker.
2025-12-26 10:30:45 +00:00
rcourtman c0b5149360 docs(pbs): add Password Setup method for Docker PBS users 2025-12-26 10:12:49 +00:00
rcourtman 3dbe5104c8 feat(pbs): turnkey PBS setup with password auth
When adding a PBS node with username/password credentials, Pulse now
automatically:
1. Connects to PBS using the provided credentials
2. Creates a 'pulse-monitor@pbs' user with Audit permissions
3. Generates an API token
4. Stores the token instead of the password

This enables one-click PBS setup for Docker/containerized deployments
where you can't easily run the agent installer. Simply enter root@pam
credentials in the UI and Pulse handles the rest.

Falls back to password auth if token creation fails (e.g., old PBS
version or permission issues).
2025-12-26 10:12:04 +00:00
rcourtman 727019a794 feat(pbs): add API-based token creation for turnkey PBS setup
- Added PBS client methods: CreateUser, SetUserACL, CreateUserToken
- Added SetupMonitoringAccess() turnkey method that creates user + token
- Updated handleSecureAutoRegister to use PBS API for token creation
- Enables one-click PBS setup for Docker/containerized deployments

When users provide PBS root credentials, Pulse can now create the
monitoring user and API token remotely via the PBS API, eliminating
the need to SSH/exec into the container manually.
2025-12-26 10:08:41 +00:00
rcourtman 0ffbe16876 test: add unit tests for PBS enhancement banner and data source indicator
- Tests hasPBSViaPassthrough detection logic
- Tests hasDirectPBS detection logic
- Tests showPBSEnhancementBanner combined logic (4 scenarios)
- Tests localStorage persistence for banner dismissal
- Tests 'via PVE' indicator logic for PBS backups

All 13 tests passing.
2025-12-26 09:53:29 +00:00
rcourtman 46959aec59 fix: Host Agent toggle visual state not updating after click
The toggle button in Alerts > Thresholds > Host Agents was working
functionally (alerts were actually disabled) but the visual state wasn't
updating. This was because the hostAgentsWithOverrides memo was missing
the 'disabled' field in its returned Resource objects.

Related to #893
2025-12-26 09:51:53 +00:00
rcourtman 9b7b787652 docs: add comprehensive PBS integration guide
- Created new PBS.md with setup instructions for direct PBS connection
- Explains difference between direct PBS API vs PVE passthrough
- Documents three setup methods: agent install, one-click script, manual
- Includes permissions reference and troubleshooting section
- Added link in docs/README.md under Monitoring & Agents
2025-12-26 09:45:42 +00:00
rcourtman 0134bf88a2 feat: Add copy uninstall button to Managed Agents table
Users can now copy the uninstall command from the Actions column of any
registered agent, without needing to start the token creation flow.

Related to #914
2025-12-26 09:43:01 +00:00
rcourtman 91c4935dd4 chore: set mock mode default to false 2025-12-26 00:22:12 +00:00
rcourtman 2da135c0ec fix: increase PBS storage content timeout to 60s
PBS storage content queries with encrypted backups can take 10-20+ seconds
to enumerate. The previous 30s timeout was causing intermittent failures
when polling backup data from PBS storage configured in PVE.

This increases the timeout to 60s to accommodate slow PBS backends while
still preventing indefinite hangs on unavailable NFS/network storage.
2025-12-26 00:21:17 +00:00
rcourtman bb6922ef58 fix: Resolve TypeScript build errors
- Remove unused imports (formatPercent, MetricText) from multiple components
- Remove unused variables (memPercent, memUsageLabel)
- Fix ResourceTable.tsx type error by adding proper tuple typing
- Add handleRemoveKubernetesCluster function for proper type safety
- Fix Kubernetes cluster remove button to use correct handler
2025-12-26 00:06:49 +00:00
rcourtman 4859d60348 fix: Remove Alpine from LXC template options
Alpine uses apk/OpenRC instead of apt/systemd, which the Pulse
LXC installation flow requires. This prevents failed installations.

- Remove Alpine download option from advanced mode
- Add note that Pulse requires Debian-based templates
- Add validation when user selects from template list to catch
  Alpine/Gentoo/Arch/Void and fall back to Debian 12 with warning

Related to #915
2025-12-25 23:58:24 +00:00
rcourtman 5f1850fad9 feat: Display environment variables for Docker containers
- Add Env field to Container struct in pkg/agents/docker/report.go
- Extract env vars from inspect.Config.Env in Docker agent
- Mask sensitive values (password, secret, key, token, etc.) with ***
- Display env vars in container drawer with green badges (amber for masked)
- Add tests for maskSensitiveEnvVars function

Related to #916
2025-12-25 23:52:57 +00:00
rcourtman 078c6a12e9 feat(mobile): improve table layouts for remaining pages
- Add horizontal scrolling to Hosts table with 900px min-width
- Add horizontal scrolling to Ceph tables with 700/650px min-widths
- Tighten padding on Storage tables for compact mobile display
- Add min-width to DiskList table for physical disks
- Add min-width to Settings tables (PVE, PBS, PMG, Agents)
- Add horizontal scroll container to Alerts patrol run table
- Hide scrollbars across all scrollable tables for cleaner UI
2025-12-25 23:07:49 +00:00
rcourtman 4083df1f47 feat(mobile): optimize tables for mobile devices
- Implement horizontal scrolling for key tables (Dashboard, Storage, Backups, Docker, Node Summary).
- Ensure consistent column widths (140px fixed on desktop, 60px min on mobile) for metric columns (CPU, Memory, Disk).
- Switch Backups view from card to scrollable table for consistency.
- Reduce shell padding on mobile.
- Update ResourceTable (Alerts) with dedicated mobile view.
- Refine column visibility logic.
2025-12-25 22:32:56 +00:00
rcourtman 337c4e1fec feat: improve Pro feature UI gating and error handling
- AISettings: Add Pro badge & disabled state for Autonomous Mode toggle
- APIClient: Parse JSON error responses for better user-facing messages
- Supports new 402 Payment Required responses from license-gated endpoints
2025-12-25 21:29:46 +00:00
rcourtman 3790c63e95 fix: require Pro license for auto-fix and autonomous mode
- patrol.go: Auto-fix now requires both config flag AND ai_autofix license
- service.go: IsAutonomous() checks for ai_autofix license before enabling
- ai_handlers.go: API returns 402 if enabling auto-fix/autonomous without license
2025-12-25 21:26:46 +00:00
rcourtman 5bbec72f70 feat: add power consumption monitoring (Intel RAPL + AMD Energy)
- Add power.go with Intel RAPL and AMD energy driver support
- Read CPU package, core, and DRAM power consumption in watts
- Sample energy counters over 100ms interval to calculate power
- Add PowerWatts field to Sensors struct for API reporting
- Integrate power collection into host agent sensor gathering
- Add comprehensive tests for power collection module

Supports Intel CPUs (Sandy Bridge+) via RAPL and AMD Ryzen/EPYC
via the amd_energy kernel module.

Closes community-scripts/ProxmoxVE#9575
2025-12-25 21:14:12 +00:00
rcourtman 79bd56d040 fix: URL edit popover now respects viewport boundaries. Related to #912
- Added viewport boundary detection using visualViewport API (iOS-friendly)
- Popover flips above the button when there isn't enough space below
- Ensures popover stays within horizontal viewport bounds
2025-12-25 20:47:28 +00:00
rcourtman 780a9b6506 fix: ThresholdsTable now uses Guest URL for node navigation. Related to #870 2025-12-25 20:39:53 +00:00
rcourtman fea03d21e1 docs: add social preview image for GitHub 2025-12-25 20:24:45 +00:00
rcourtman dfc15e5142 chore: add Ko-fi to funding options 2025-12-25 20:23:00 +00:00
rcourtman 919f7fbdde docs: improve README with stars badge, updated tagline, and evergreen headers 2025-12-25 20:19:30 +00:00
rcourtman 773f16bc47 docs: update dashboard screenshot to match landing page 2025-12-25 20:17:39 +00:00
rcourtman e1c6d9c932 feat: Collect and display all lm-sensors data (fans, DDR5, etc.)
Extended lm-sensors parsing to capture all sensor readings:
- Fan speeds (RPM) from SuperIO chips like NCT6687
- Additional temperatures (DDR5/RAM, motherboard, etc.)
- All sensors not already captured as CPU/NVMe/GPU

Updated frontend tooltip to display fans and additional sensors
in separate sections with formatted names.

Closes discussion #911
2025-12-25 19:08:03 +00:00
rcourtman 1e3c71c0ae fix: Remove hardcoded sudo from agent install commands
On Proxmox VE and many minimal Linux systems, sudo is not installed
when logged in as root. The install script already checks for root
privileges and exits with a message if not root.

Updated command templates to use 'bash -s --' instead of 'sudo bash -s --'
and added notes clarifying users should run as root (via sudo or su -).

Related to #909
2025-12-25 18:56:54 +00:00
rcourtman f983329357 docs: Add disk exclusion and S.M.A.R.T. documentation
- Document --disk-exclude flag and PULSE_DISK_EXCLUDE env var
- Document pattern types (exact, prefix, contains)
- Document S.M.A.R.T. requirements (smartmontools package)
- Add --enable-commands to configuration table
2025-12-25 12:20:07 +00:00
rcourtman 223e784a92 feat: Add disk exclusion filter for host agent. Closes #896
Users can now exclude specific mount points from disk monitoring:
- Via CLI: --disk-exclude /mnt/backup --disk-exclude '/media/*'
- Via env: PULSE_DISK_EXCLUDE=/mnt/backup,*pbs*

Patterns support:
- Exact paths: /mnt/backup
- Prefix patterns: /mnt/ext*
- Contains patterns: *pbs*

This addresses the common case where external disks or
PBS datastores are being monitored but shouldn't be.
2025-12-25 12:04:40 +00:00
rcourtman 69eb78741b test: Add unit tests for smartctl package
- Test disk type detection (NVMe, SAS, SATA)
- Test WWN formatting
- Test struct creation and JSON parsing
- Test NVMe temperature fallback location
2025-12-25 11:55:37 +00:00
rcourtman 39e5d42305 feat: Hide AI buttons when AI is not configured. Closes #905
- InvestigateProblemsButton now checks aiChatStore.enabled
- InvestigateAlertButton returns null when AI is not enabled
- This provides cleaner UX for users who don't use AI features
2025-12-25 11:50:06 +00:00
rcourtman e1b3af7ca0 feat: Agent collects S.M.A.R.T. disk data via smartctl. Related to #907
- Add smartctl package to collect disk temperature and health data
- Add SMART field to agent Sensors struct
- Host agent now runs smartctl to collect disk temps when available
- Backend processes agent SMART data for temperature display
- Graceful fallback when smartctl not installed
2025-12-25 11:37:53 +00:00
rcourtman ea0fafd5c8 fix: Use LinkedNodeID for temperature matching to fix duplicate hostname bug
When two Proxmox nodes have the same hostname (e.g., 'px1' on different IPs),
the getHostAgentTemperature function was matching by hostname alone, causing
both nodes to show temperature from whichever host agent appeared first.

The fix:
- Added getHostAgentTemperatureByID that first tries matching by LinkedNodeID
  (the unique node ID) before falling back to hostname matching
- Updated the caller to pass modelNode.ID for precise matching
- Maintains backwards compatibility for setups where linking hasn't occurred

Related to #891
2025-12-25 10:00:19 +00:00
rcourtman ce962a38c7 fix(#903): Add 2-minute timeout for pending config sync
If an agent doesn't confirm the config change within 2 minutes (e.g., offline),
the sync indicator is cleared and a warning notification is shown. This prevents
the spinner from spinning forever when agents are unreachable.

The toggle returns to showing the agent-reported state after timeout, allowing
users to retry the toggle if needed.
2025-12-25 08:19:43 +00:00
rcourtman f63a4c8ca2 fix(#903): Optimistic toggle with sync indicator for AI commands
The toggle now:
1. Immediately shows the desired state after clicking (optimistic update)
2. Displays a spinning sync icon while waiting for agent confirmation
3. Disables the toggle during sync to prevent double-clicks
4. Reverts to original state if the API call fails
5. Clears sync state once agent reports the expected value

This provides clear visual feedback about the async nature of remote config
without requiring users to understand the underlying polling mechanism.
2025-12-25 08:15:35 +00:00
rcourtman f4c426cbdf fix: Properly close command client WebSocket when disabling remotely
When the server disables command execution for an agent, we now properly
call Close() on the command client to tear down the WebSocket connection.
Previously we just set the pointer to nil which left the goroutine running
with an orphaned connection.
2025-12-25 08:09:42 +00:00
rcourtman a38c071644 feat(#903): Remote agent configuration for AI command execution
This implements full remote configuration for the AI command execution setting:

Backend:
- Add CommandsEnabled field to HostMetadata for persistent storage
- Add GetHostAgentConfig/UpdateHostAgentConfig methods to Monitor
- Add /api/agents/host/{id}/config endpoint (GET for agents, PATCH for UI)
- Server includes config in report response for immediate agent application
- Agent parses response and dynamically enables/disables command client

Frontend:
- Add 'AI Commands' toggle column in Managed Agents table
- Toggle immediately updates server config; agent applies on next heartbeat
- Add 'Enable AI command execution' checkbox in agent installer wizard
- Checkbox adds --enable-commands flag to generated install commands

This allows users to:
1. Enable at install time via checkbox in the wizard
2. Toggle remotely via the Managed Agents UI for existing agents
3. Agents apply changes automatically on their next report cycle
2025-12-25 08:07:28 +00:00
rcourtman ac2b765ca5 feat: Agent reports CommandsEnabled status to server. Related to #903
- Add CommandsEnabled field to AgentInfo in pkg/agents/host/report.go
- Agent now reports whether AI command execution is enabled
- Server stores and exposes this via Host model
- Frontend can now show which agents have commands enabled
- This provides visibility before implementing remote configuration
2025-12-25 07:55:22 +00:00
rcourtman 57d57de28c fix: Node disk column respects Trends view mode. Related to #904
The disk column for Proxmox nodes was always showing bars even when
Trends (sparklines) view mode was selected. Memory column was correctly
checking viewMode() but disk was not.

Added the same Show when={viewMode() === 'sparklines'} conditional
to the disk column rendering in NodeSummaryTable.
2025-12-25 05:08:34 +00:00
rcourtman c6125ae5d7 fix: Allow dismissing AI findings without Pro license. Related to #885
Users who accumulated AI patrol findings before the patrol-without-AI
bug was fixed (24c4bb0b) could not dismiss them because the dismiss and
resolve endpoints required a Pro license.

Changes:
- Remove Pro license requirement from /api/ai/patrol/dismiss endpoint
- Remove Pro license requirement from /api/ai/patrol/resolve endpoint
- Add ClearAll() method to FindingsStore for bulk clearing
- Add DELETE /api/ai/patrol/findings endpoint for clearing all findings
- Add "Clear All" button to AI Insights UI

Users can now dismiss or resolve any findings they can see, and admins
can clear all findings at once if needed.
2025-12-25 05:06:26 +00:00
rcourtman 08e9202b71 fix: Immediately broadcast backup/snapshot updates to frontend
Backup and snapshot polling runs asynchronously and could take 20-45 seconds to complete, but WebSocket broadcasts happened on a separate fixed-interval timer. This caused frontend to show stale data until a broadcast happened to coincide with completed polling - which could take hours.

Now broadcasts state immediately after backup/snapshot polling completes, ensuring users see changes within seconds.

Related to #895
2025-12-25 00:09:07 +00:00