Enhanced code review and frontend validation with intelligent triggers: Code Review Agent Enhancement: - Added Sequential Thinking MCP integration for complex issues - Triggers on 2+ rejections or 3+ critical issues - New escalation format with root cause analysis - Comprehensive solution strategies with trade-off evaluation - Educational feedback to break rejection cycles - Files: .claude/agents/code-review.md (+308 lines) - Docs: CODE_REVIEW_ST_ENHANCEMENT.md, CODE_REVIEW_ST_TESTING.md Frontend Design Skill Enhancement: - Automatic invocation for ANY UI change - Comprehensive validation checklist (200+ checkpoints) - 8 validation categories (visual, interactive, responsive, a11y, etc.) - 3 validation levels (quick, standard, comprehensive) - Integration with code review workflow - Files: .claude/skills/frontend-design/SKILL.md (+120 lines) - Docs: UI_VALIDATION_CHECKLIST.md (462 lines), AUTOMATIC_VALIDATION_ENHANCEMENT.md (587 lines) Settings Optimization: - Repaired .claude/settings.local.json (fixed m365 pattern) - Reduced permissions from 49 to 33 (33% reduction) - Removed duplicates, sorted alphabetically - Created SETTINGS_PERMISSIONS.md documentation Checkpoint Command Enhancement: - Dual checkpoint system (git + database) - Saves session context to API for cross-machine recall - Includes git metadata in database context - Files: .claude/commands/checkpoint.md (+139 lines) Decision Rationale: - Sequential Thinking MCP breaks rejection cycles by identifying root causes - Automatic frontend validation catches UI issues before code review - Dual checkpoints enable complete project memory across machines - Settings optimization improves maintainability Total: 1,200+ lines of documentation and enhancements Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
320 lines
12 KiB
Plaintext
320 lines
12 KiB
Plaintext
1→# GuruRMM Tray Icon Implementation Plan
|
|
2→
|
|
3→## Overview
|
|
4→
|
|
5→Add a system tray application for the GuruRMM agent that provides user visibility and interaction, with all features controlled by admin policy from the server.
|
|
6→
|
|
7→## Architecture
|
|
8→
|
|
9→```
|
|
10→┌─────────────────┐ Policy ┌─────────────────┐
|
|
11→│ RMM Server │ ──────────────► │ Agent Service │
|
|
12→│ (WebSocket) │ │ (Background) │
|
|
13→└─────────────────┘ └────────┬────────┘
|
|
14→ │ IPC
|
|
15→ │ (Named Pipe)
|
|
16→ ▼
|
|
17→ ┌─────────────────┐
|
|
18→ │ Tray App │
|
|
19→ │ (User Session) │
|
|
20→ └─────────────────┘
|
|
21→```
|
|
22→
|
|
23→**Key Points:**
|
|
24→- Agent service runs as SYSTEM, always running
|
|
25→- Tray app runs in user session, started by service if policy enables it
|
|
26→- IPC via Windows Named Pipe for status/commands
|
|
27→- Policy controls everything: visibility, menu items, allowed actions
|
|
28→
|
|
29→---
|
|
30→
|
|
31→## Phase 1: IPC Infrastructure
|
|
32→
|
|
33→### 1.1 Add Named Pipe Server to Agent Service
|
|
34→
|
|
35→**File:** `agent/src/ipc.rs` (new)
|
|
36→
|
|
37→```rust
|
|
38→// Named pipe: \\.\pipe\gururmm-agent
|
|
39→// Protocol: JSON messages over pipe
|
|
40→
|
|
41→pub enum IpcRequest {
|
|
42→ GetStatus, // Get current agent status
|
|
43→ GetPolicy, // Get current tray policy
|
|
44→ ForceCheckin, // Trigger immediate metrics send
|
|
45→ StopAgent, // Stop the agent service (if allowed)
|
|
46→ Subscribe, // Subscribe to status updates
|
|
47→}
|
|
48→
|
|
49→pub enum IpcResponse {
|
|
50→ Status(AgentStatus),
|
|
51→ Policy(TrayPolicy),
|
|
52→ Ok,
|
|
53→ Error(String),
|
|
54→ Denied(String), // Action not allowed by policy
|
|
55→}
|
|
56→
|
|
57→pub struct AgentStatus {
|
|
58→ pub connected: bool,
|
|
59→ pub last_checkin: Option<DateTime<Utc>>,
|
|
60→ pub server_url: String,
|
|
61→ pub agent_version: String,
|
|
62→ pub device_id: String,
|
|
63→ pub hostname: String,
|
|
64→}
|
|
65→```
|
|
66→
|
|
67→### 1.2 Tray Policy Structure
|
|
68→
|
|
69→**Add to server → agent protocol:**
|
|
70→
|
|
71→```rust
|
|
72→pub struct TrayPolicy {
|
|
73→ pub enabled: bool, // Show tray icon at all
|
|
74→ pub show_status: bool, // Show connection status
|
|
75→ pub show_info: bool, // Show agent info in menu
|
|
76→ pub allow_force_checkin: bool, // Allow manual check-in
|
|
77→ pub allow_view_logs: bool, // Allow opening log file
|
|
78→ pub allow_open_dashboard: bool, // Allow opening web dashboard
|
|
79→ pub allow_stop_agent: bool, // Allow stopping the agent
|
|
80→ pub dashboard_url: Option<String>,
|
|
81→ pub custom_icon: Option<String>, // Base64 encoded custom icon
|
|
82→ pub tooltip_text: Option<String>,
|
|
83→}
|
|
84→```
|
|
85→
|
|
86→---
|
|
87→
|
|
88→## Phase 2: Tray Application (Windows)
|
|
89→
|
|
90→### 2.1 New Crate Structure
|
|
91→
|
|
92→```
|
|
93→gururmm/
|
|
94→├── agent/ # Existing agent service
|
|
95→│ └── src/
|
|
96→│ ├── main.rs
|
|
97→│ ├── ipc.rs # NEW: IPC server
|
|
98→│ └── ...
|
|
99→└── tray/ # NEW: Tray application
|
|
100→ ├── Cargo.toml
|
|
101→ └── src/
|
|
102→ ├── main.rs # Entry point, IPC client
|
|
103→ ├── tray.rs # Windows tray icon management
|
|
104→ ├── menu.rs # Dynamic menu building
|
|
105→ └── ipc.rs # Named pipe client
|
|
106→```
|
|
107→
|
|
108→### 2.2 Tray Crate Dependencies
|
|
109→
|
|
110→```toml
|
|
111→[package]
|
|
112→name = "gururmm-tray"
|
|
113→version = "0.1.0"
|
|
114→
|
|
115→[dependencies]
|
|
116→tray-icon = "0.14" # Cross-platform tray (uses winit)
|
|
117→winit = "0.29" # Window event loop
|
|
118→image = "0.24" # Icon loading
|
|
119→serde = { version = "1", features = ["derive"] }
|
|
120→serde_json = "1"
|
|
121→tokio = { version = "1", features = ["net", "io-util", "sync"] }
|
|
122→anyhow = "1"
|
|
123→tracing = "0.1"
|
|
124→tracing-subscriber = "0.3"
|
|
125→
|
|
126→[target.'cfg(windows)'.dependencies]
|
|
127→windows = { version = "0.58", features = [
|
|
128→ "Win32_System_Pipes",
|
|
129→ "Win32_Foundation",
|
|
130→]}
|
|
131→
|
|
132→[profile.release]
|
|
133→opt-level = "z"
|
|
134→lto = true
|
|
135→strip = true
|
|
136→```
|
|
137→
|
|
138→### 2.3 Tray Icon States
|
|
139→
|
|
140→| State | Icon | Tooltip |
|
|
141→|-------|------|---------|
|
|
142→| Connected | Green circle | "GuruRMM - Connected" |
|
|
143→| Disconnected | Yellow circle | "GuruRMM - Reconnecting..." |
|
|
144→| Error | Red circle | "GuruRMM - Error: {message}" |
|
|
145→| Disabled | Gray circle | "GuruRMM - Disabled by policy" |
|
|
146→
|
|
147→### 2.4 Menu Structure (Policy-Controlled)
|
|
148→
|
|
149→```
|
|
150→GuruRMM Agent v1.0.0
|
|
151→─────────────────────
|
|
152→✓ Connected to rmm-api.example.com
|
|
153→ Last check-in: 2 minutes ago
|
|
154→ Device: WORKSTATION-01
|
|
155→─────────────────────
|
|
156→ Force Check-in [if allow_force_checkin]
|
|
157→ View Logs [if allow_view_logs]
|
|
158→ Open Dashboard [if allow_open_dashboard]
|
|
159→─────────────────────
|
|
160→ Stop Agent [if allow_stop_agent]
|
|
161→ Exit Tray [always, hides tray only]
|
|
162→```
|
|
163→
|
|
164→---
|
|
165→
|
|
166→## Phase 3: Agent Service Changes
|
|
167→
|
|
168→### 3.1 Tray Launcher
|
|
169→
|
|
170→Agent service launches tray app for each logged-in user session:
|
|
171→
|
|
172→**File:** `agent/src/tray_launcher.rs` (new)
|
|
173→
|
|
174→```rust
|
|
175→// On Windows:
|
|
176→// 1. Enumerate user sessions (WTSEnumerateSessions)
|
|
177→// 2. For active sessions, launch tray in user context
|
|
178→// 3. Monitor for new logons, launch tray
|
|
179→// 4. If policy disables tray, terminate tray processes
|
|
180→```
|
|
181→
|
|
182→### 3.2 Policy Handler
|
|
183→
|
|
184→When server sends policy update:
|
|
185→
|
|
186→```rust
|
|
187→// In transport handler:
|
|
188→ServerMessage::PolicyUpdate(policy) => {
|
|
189→ // Store policy
|
|
190→ self.policy.write().await = policy;
|
|
191→
|
|
192→ // Update tray processes
|
|
193→ if policy.tray.enabled {
|
|
194→ self.tray_launcher.ensure_running().await;
|
|
195→ } else {
|
|
196→ self.tray_launcher.terminate_all().await;
|
|
197→ }
|
|
198→
|
|
199→ // Notify connected tray apps of policy change
|
|
200→ self.ipc_server.broadcast_policy(&policy.tray).await;
|
|
201→}
|
|
202→```
|
|
203→
|
|
204→---
|
|
205→
|
|
206→## Phase 4: Server-Side Policy
|
|
207→
|
|
208→### 4.1 Database Schema Addition
|
|
209→
|
|
210→```sql
|
|
211→ALTER TABLE sites ADD COLUMN tray_policy JSONB DEFAULT '{
|
|
212→ "enabled": true,
|
|
213→ "show_status": true,
|
|
214→ "show_info": true,
|
|
215→ "allow_force_checkin": true,
|
|
216→ "allow_view_logs": true,
|
|
217→ "allow_open_dashboard": true,
|
|
218→ "allow_stop_agent": false,
|
|
219→ "dashboard_url": null,
|
|
220→ "custom_icon": null,
|
|
221→ "tooltip_text": null
|
|
222→}';
|
|
223→```
|
|
224→
|
|
225→### 4.2 Dashboard UI
|
|
226→
|
|
227→Add to Site Settings page:
|
|
228→- Toggle: "Show system tray icon"
|
|
229→- Checkboxes for each menu option
|
|
230→- Custom icon upload
|
|
231→- Custom tooltip text
|
|
232→
|
|
233→---
|
|
234→
|
|
235→## Implementation Order
|
|
236→
|
|
237→### Step 1: IPC Infrastructure (Agent Side)
|
|
238→1. Create `agent/src/ipc.rs` with named pipe server
|
|
239→2. Add IPC task to agent main loop
|
|
240→3. Define message protocol (GetStatus, GetPolicy, etc.)
|
|
241→4. Test with simple client
|
|
242→
|
|
243→### Step 2: Tray Application (Windows)
|
|
244→1. Create `tray/` crate with Cargo.toml
|
|
245→2. Implement IPC client connecting to agent
|
|
246→3. Create basic tray icon with `tray-icon` crate
|
|
247→4. Build dynamic menu from policy
|
|
248→5. Handle menu actions → IPC requests
|
|
249→
|
|
250→### Step 3: Tray Launcher (Agent Side)
|
|
251→1. Add session enumeration (WTSEnumerateSessions)
|
|
252→2. Launch tray in user context (CreateProcessAsUser)
|
|
253→3. Monitor for logon/logoff events
|
|
254→4. Handle policy enable/disable
|
|
255→
|
|
256→### Step 4: Server Integration
|
|
257→1. Add tray_policy to server data model
|
|
258→2. Add policy to site settings API
|
|
259→3. Send policy to agent on connect
|
|
260→4. Add dashboard UI for policy management
|
|
261→
|
|
262→### Step 5: Polish
|
|
263→1. Icon assets (green/yellow/red/gray)
|
|
264→2. Installer updates (include tray binary)
|
|
265→3. Documentation
|
|
266→
|
|
267→---
|
|
268→
|
|
269→## Files to Create/Modify
|
|
270→
|
|
271→### New Files
|
|
272→| File | Purpose |
|
|
273→|------|---------|
|
|
274→| `agent/src/ipc.rs` | Named pipe IPC server |
|
|
275→| `agent/src/tray_launcher.rs` | Launch tray in user sessions |
|
|
276→| `tray/Cargo.toml` | Tray app crate config |
|
|
277→| `tray/src/main.rs` | Tray app entry point |
|
|
278→| `tray/src/tray.rs` | Tray icon management |
|
|
279→| `tray/src/menu.rs` | Dynamic menu building |
|
|
280→| `tray/src/ipc.rs` | Named pipe client |
|
|
281→| `assets/icons/` | Tray icon images |
|
|
282→
|
|
283→### Modified Files
|
|
284→| File | Changes |
|
|
285→|------|---------|
|
|
286→| `agent/src/main.rs` | Add IPC server task, tray launcher |
|
|
287→| `agent/src/transport/mod.rs` | Add TrayPolicy to protocol |
|
|
288→| `agent/Cargo.toml` | Add windows crate for session APIs |
|
|
289→| `server/src/models/` | Add tray_policy to site model |
|
|
290→| `dashboard/src/` | Add tray policy UI to site settings |
|
|
291→
|
|
292→---
|
|
293→
|
|
294→## Future: Mac/Linux Support
|
|
295→
|
|
296→### macOS
|
|
297→- Menu bar icon via same `tray-icon` crate
|
|
298→- IPC via Unix domain socket instead of named pipe
|
|
299→- Launch via launchd user agent
|
|
300→
|
|
301→### Linux
|
|
302→- System tray via `tray-icon` (uses libappindicator/StatusNotifierItem)
|
|
303→- IPC via Unix domain socket
|
|
304→- Launch via XDG autostart or systemd user service
|
|
305→- Note: GNOME requires extension for tray icons
|
|
306→
|
|
307→---
|
|
308→
|
|
309→## Security Considerations
|
|
310→
|
|
311→1. **IPC Authentication**: Tray must prove it's running in a valid user session
|
|
312→2. **Policy Enforcement**: Agent validates actions against policy, not tray
|
|
313→3. **Stop Agent**: Requires admin policy AND user confirmation dialog
|
|
314→4. **Named Pipe ACL**: Restrict pipe access to authenticated users
|
|
315→
|
|
|
|
<system-reminder>
|
|
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
|
|
</system-reminder>
|