Commit Graph

1958 Commits

Author SHA1 Message Date
rcourtman a6283db5b1 Polish: Consistent notifications in PBS setup and scripts 2025-12-23 12:12:34 +00:00
rcourtman 96c8ed4342 Polish: Standardize manual setup notifications 2025-12-23 12:12:10 +00:00
rcourtman fd2f3911a5 Polish: Consistent notifications in Quick Setup 2025-12-23 12:11:54 +00:00
rcourtman 888678cb86 Polish: Fix agent command generation logic in NodeModal 2025-12-23 12:11:08 +00:00
rcourtman 8e4e2d4af2 Polish: Usage of NodesAPI in NodeModal 2025-12-23 12:10:43 +00:00
rcourtman c8f4705c5c Polish: Standardize agent command API usage 2025-12-23 12:09:57 +00:00
rcourtman 280be81ee9 Polish: Consistent API usage in UnifiedAgents 2025-12-23 12:06:43 +00:00
rcourtman c7870da57f Polish: Fix remaining window.showToast in UnifiedAgents loop 2025-12-23 12:03:49 +00:00
rcourtman 37c42be85f Polish: refactor UnifiedAgents to use notificationStore 2025-12-23 12:00:43 +00:00
rcourtman 2dbd32a16b Refine v5 release: UI consistency and logging cleanup 2025-12-23 11:58:23 +00:00
rcourtman 62ac999466 feat(ui): Use inline copy buttons in agent setup for consistency. Related to #874 2025-12-23 10:32:47 +00:00
rcourtman 145403b068 fix: Update tier display name test for Pro Intelligence rename 2025-12-23 10:11:45 +00:00
rcourtman 15f0ef779b ux: Add step numbers to agent setup flow. Related to #872
- Step 1: Generate API token (with blue circle)
- Step 2: Installation commands (with green circle when unlocked)
- Shows locked preview of Step 2 before token generation, making it clear
  that installation commands will appear after generating a token
- Addresses user feedback about the unclear agent creation flow
2025-12-23 09:44:28 +00:00
rcourtman 4846b19877 fix: Correct misleading 'button above' text in node setup. Related to #873
The copy button is visually positioned to the right of the code block,
not above it. Changed to 'Click the copy button' for clarity.
2025-12-23 09:41:38 +00:00
rcourtman 7570c4810f feat: Add Connection URL override for agent installation. Related to #874 2025-12-23 09:40:01 +00:00
rcourtman cb3444dd9b fix: Prevent re-migration of deleted env-based API tokens
When a user deletes an API token that was migrated from .env, track
the hash in a suppression list to prevent it from being re-migrated
on the next restart.

Changes:
- Add SuppressedEnvMigrations field to Config
- Add env_token_suppressions.json persistence
- Check suppression list during env token migration
- Record suppressed hash when deleting "Migrated from .env" tokens
- Update RemoveAPIToken to return the removed record

Related to #871
2025-12-23 05:10:47 +00:00
rcourtman 45016430b7 feat(license): rename premium tier to Pro Intelligence 2025-12-23 00:30:55 +00:00
rcourtman 77db408114 feat(ai): add finding validation layer to reduce patrol noise
- Add validateAIFindings() that cross-checks AI findings against actual metrics
- Filter out low-confidence findings (CPU <50%, memory <60%, disk <70%)
- Always allow critical findings, backup issues, and reliability findings through
- Update AI system prompt with stricter thresholds and explicit noise examples
- Add 'before creating a finding' checklist for AI (the 3am test)
- Update AI.md docs with clear value proposition and expectations
- Add comprehensive tests for the validation layer

This ensures paying users get immediate value without noise.
2025-12-22 23:28:09 +00:00
rcourtman b65f42acb5 chore: AI patrol and baseline improvements
- Enhanced patrol finding display in Alerts.tsx
- Improved baseline store with better error handling
- Added clean thinking test coverage
- Updated patrol logic for better finding management
2025-12-22 23:12:11 +00:00
rcourtman c2c352a004 feat: add PBS datastores to unified Storage view (#869)
PBS datastores are now displayed in the Storage overview alongside PVE
storage. Each PBS datastore is converted to a Storage entry with:
- type: 'pbs'
- content: 'backup'
- shared: true
- active: based on PBS instance status

This provides a complete picture of all storage resources in one view
while keeping detailed PBS info in the dedicated PBS section.

Closes #869
2025-12-22 22:12:04 +00:00
rcourtman e4732af0f5 fix: use configured Guest URLs for PVE/PBS/PMG navigation (#870)
- Fix PVE nodes: buildNodeUrl in ProxmoxNodesSection.tsx now prioritizes
  guestURL over host (was ignoring guestURL entirely)
- Add PBS support: GuestURL field added to PBSInstance config, model,
  and API handlers
- Add PMG support: GuestURL field added to PMGInstance config, model,
  and API handlers
- Update NodeSummaryTable to use guestURL for PBS nodes
- Frontend types updated for PBS/PMG guestURL support

The Guest URL setting in node configuration now works correctly across
all node types. When set, it takes priority over the Host URL when
clicking on node names to navigate to the Proxmox/PBS/PMG web UI.

Closes #870
2025-12-22 22:05:25 +00:00
rcourtman 7664e941b0 fix: default mock mode to false 2025-12-22 21:47:07 +00:00
rcourtman 758a58bbd3 chore: gitignore .gemini/ folder 2025-12-22 21:46:18 +00:00
rcourtman c9115efeb8 fix: prevent demo findings from being persisted to disk 2025-12-22 21:45:07 +00:00
rcourtman 5b997b8f2e Add clean separation between mock and real AI findings
- Add IsMockResource() helper to detect mock data resources by naming patterns
- Filter out heuristic findings from mock resources when PULSE_MOCK_MODE is off
- Mock findings still appear when demo mode is enabled
- Ensures users don't see mock data findings in production
2025-12-22 20:23:15 +00:00
rcourtman c04b60c550 Fix demo mode detection to use PULSE_MOCK_MODE env var
The AI demo/mock findings were using a non-existent MOCK_ENABLED
env var. Changed to PULSE_MOCK_MODE which is the actual env var
used by the mock data system.
2025-12-22 20:09:56 +00:00
rcourtman 11cdc5d279 fix(ci): restore arm64 Docker builds in publish workflow
The staging images in preflight are intentionally amd64-only for speed,
but the publish workflow was just copying them instead of building
multi-arch. Now builds linux/amd64,linux/arm64 from source at publish.

Related to #868
2025-12-22 20:03:39 +00:00
rcourtman 828b092ea4 Unify AI patrol system: add Kubernetes analysis, enhance Docker/Podman detection
- Add AnalyzeKubernetes to PatrolConfig and enable by default
- Add analyzeKubernetesCluster() for K8s heuristic analysis
  - Detect offline clusters, nodes not ready, CrashLoopBackOff pods
  - Detect failed/pending pods and unavailable deployments
- Add K8s clusters to LLM context in buildInfrastructureSummary()
- Add kubernetes_cluster as valid resource type in AI prompt

- Enhance analyzeDockerHost() for Docker/Podman
  - Podman-aware messaging based on runtime
  - Add unhealthy container detection (health checks)
  - Add exited container with error detection
  - Add high CPU detection (>90%)
  - Add stale host detection (10+ minutes)
  - Tiered severity for restarts (>10 = critical)

- Add 20 new tests for K8s and Docker analysis
2025-12-22 18:03:46 +00:00
rcourtman 16bd9970e9 feat: add CLI commands for mock mode management
New commands:
  pulse mock enable   - Enable mock mode
  pulse mock disable  - Disable mock mode
  pulse mock status   - Show current status

Makes it easy to toggle between mock and real data without
manually editing config files.
2025-12-22 17:26:57 +00:00
rcourtman b75728922c feat: add demo AI findings for mock mode
When MOCK_ENABLED=true, Pulse now injects realistic AI patrol
findings to showcase the AI features without requiring actual
LLM API calls. This enables the demo instance to demonstrate:

- Critical/warning/info findings with realistic content
- Patrol run history
- Actionable recommendations

Also includes refinements to dismissal logic from earlier work:
- Only 'not_an_issue' creates permanent suppression
- 'expected_behavior' and 'will_fix_later' just acknowledge
2025-12-22 17:16:26 +00:00
rcourtman 25be1ff5d9 feat: make Docker host names clickable in container table
When a Docker host has a custom URL configured (e.g., Portainer link),
the host name in the container table's group headers is now a clickable
link that opens the URL in a new tab. A link icon appears next to the
host name to indicate it's clickable.

Related to #860
2025-12-22 15:05:34 +00:00
rcourtman 8d0ca16124 docs: update AI.md with v5 patrol and finding management features
- Added finding management section (resolve, dismiss, suppress)
- Documented patrol service and severity levels
- Added AI-assisted remediation capabilities
- Added Ollama tool/function calling support note
- Added new troubleshooting tips for findings persistence
2025-12-22 14:43:56 +00:00
rcourtman f67e7b3e97 fix: clean up debug logging and fix flaky encryption test
1. Fixed TestNewConfigPersistenceFailsWhenEncryptedDataPresentWithoutKey
   - Test was picking up real encryption key from /etc/pulse during migration
   - Now temporarily moves system key during test for proper isolation
   - Uses t.Cleanup to ensure key is restored even on failure

2. Cleaned up console.log statements in production code
   - Dashboard.tsx: replaced console.log with logger.debug for metadata events
   - CompleteStep.tsx: removed verbose agent detection debug logs

These changes reduce log noise in production while maintaining debug
capability in development mode.
2025-12-22 14:35:48 +00:00
rcourtman 28ac86c8ab fix: reduce WebSocket reconnection log noise in host agent
Addresses #866 - agents were logging 'WebSocket connection failed' warnings
even during normal reconnection scenarios (server restart, network blip, etc).

Changes:
- Normal close errors (1000, 1001, connection reset) now log at Debug level
- Only log Warning after 3+ consecutive failures
- Changed 'Connecting to Pulse' from Info to Debug to reduce noise
- Successful connections still log at Info level

The WebSocket is only used for AI command execution, not metrics, so
transient disconnections don't affect monitoring functionality.
2025-12-22 14:11:23 +00:00
rcourtman 59a4843f20 fix: persist finding dismissal state across restarts
User feedback fields (DismissedReason, UserNote, TimesRaised, Suppressed, Source)
were not being saved to disk, causing 'expected behavior' dismissals to be lost
after Pulse restarted.

- Add missing fields to AIFindingRecord in persistence.go
- Update FindingsPersistenceAdapter to save/load these fields
- Add comprehensive tests for dismissal persistence round-trip

Fixes issue where Frigate storage warning kept reappearing despite being
marked as expected behavior.
2025-12-22 11:18:43 +00:00
rcourtman 2c95961feb fix: Add missing guest filtering props to ThresholdsTable tests 2025-12-22 10:26:53 +00:00
rcourtman 0837c46f5a test: Add unit tests for guest tag filtering 2025-12-22 10:24:39 +00:00
rcourtman 71d0401c80 feat: Add guest filtering by tag and name prefix via Alert Configuration. Resolves #863 2025-12-22 10:03:12 +00:00
rcourtman c9fc827f4c fix: Prevent buffering and log actionable error for host agent 403s. Related to discussion #845 2025-12-22 09:51:27 +00:00
rcourtman fc300de328 fix: Prevent ignored container inputs from removing trailing newlines. Related to #865 2025-12-22 09:48:40 +00:00
rcourtman a0580db62d fix: exclude watch from patrol status summary
Since watch/info findings are filtered from the UI and never shown
to users, don't include them in the patrol run status summary.
This makes the summary consistent with what users actually see.
2025-12-21 23:31:21 +00:00
rcourtman 78c3434061 fix: include VMID in AI context to prevent incorrect references
The LLM was confusing VMIDs because they weren't included in the
context. Now the formatted context shows:

  ### Container: ollama (VMID 200) on minipc

This prevents the AI from referencing the wrong VMID when generating
findings and recommendations.
2025-12-21 23:13:47 +00:00
rcourtman 8ee315eee4 perf: skip initial patrol if one ran recently
When the service restarts, it now checks if a patrol ran within the
last hour. If so, it skips the initial patrol to avoid wasting API
tokens during development/maintenance when the service is restarted
frequently.

The scheduled patrol runs (every 6 hours) are not affected.
2025-12-21 23:03:41 +00:00
rcourtman 9c58bfa127 perf: reduce MetricSamples from 100 to 24 points
100 samples was causing 326k+ input tokens which is expensive.
24 samples (hourly resolution) still provides good pattern visibility
while significantly reducing token cost.

Estimated reduction: ~75% fewer metric tokens.
2025-12-21 22:56:19 +00:00
rcourtman c85814345d feat: surface AI patrol errors as findings
When AI patrol fails due to API issues like insufficient balance, invalid
API key, or rate limiting, we now create a finding that appears in the
AI Insights tab. This makes the issue visible to users rather than hidden
in logs.

The finding includes:
- Clear description of the issue (e.g., 'Insufficient API credits')
- Recommendation for how to fix it
- Evidence showing the actual error message
2025-12-21 22:45:29 +00:00
rcourtman 901f04a7b2 fix: don't show 'All healthy' when patrol run had errors
When a patrol run encounters errors (e.g., LLM call failed), don't
display 'All healthy' in the summary as that's misleading - the
analysis didn't complete properly.

Now shows 'Analysis incomplete (N errors)' instead, which correctly
explains why the status badge shows red/error.
2025-12-21 22:35:39 +00:00
rcourtman c15f260280 feat: increase MetricSamples to 100 points (~15 min resolution)
Modern LLMs have 100k+ token contexts. 100 samples over 24h gives
~15 minute resolution while adding minimal token overhead.

This lets the LLM see fine-grained patterns, short spikes, and
accurately distinguish anomalies from normal behavior.
2025-12-21 22:25:54 +00:00
rcourtman d23f1c78de fix: increase MetricSamples to 24 points for hourly resolution
12 samples was too coarse (2-hour intervals could miss spikes).
24 samples gives ~hourly resolution while still being compact.
2025-12-21 22:24:02 +00:00
rcourtman 5877ce00c3 fix: use 24h window for MetricSamples (matches in-memory retention)
The in-memory MetricsHistory only retains 24 hours of data, not 7 days.
Changed computeGuestMetricSamples to use trendWindow24h instead of
trendWindow7d, and reduced sample count from 24 to 12 points.

This ensures the LLM actually receives metric samples in the context,
which wasn't happening before because the 7-day query returned empty data.
2025-12-21 22:19:40 +00:00
rcourtman f6b1414ed6 debug: add logging to verify MetricSamples population for LLM context 2025-12-21 22:14:54 +00:00