← Back to Kontasks
WebSocket Broadcast Enhancement Plan
Design for additional broadcasts, notification dropdown, and force-logout feature
Output
🔔 WebSocket Broadcast Enhancement Plan
Current State
We have admin:* broadcasts working. The status indicator in the navbar shows connection status. Now we expand this into a full notification system.
Proposed New Broadcast Types
| Event | Channel | Payload | Action |
|---|---|---|---|
| ● User Login | admin:login |
username, timestamp, IP | Toast notification |
| ● User Logout | admin:logout |
username, timestamp | Toast notification |
| ● Service Restart | admin:restart |
service, reason, user | Toast + history |
| ● Kontask Created | kontask:created |
id, title, targetUser | Link to kontask |
| ● Kontask Completed | kontask:completed |
id, title, status | Link to kontask |
| ● Force Logout | admin:force_logout |
reason, exceptUsers[] | Redirect to /login |
| ● Session Killed | session:killed |
sessionId, reason | Update UI |
📥 Notification Dropdown UI
Click the bell/indicator to show a dropdown with last 5 notifications:
Notifications
Clear all
📋
New kontask: "Review image crops"
2 min ago · View →
👤
sarah logged in
5 min ago
🔄
konsole restarted
15 min ago
🚨 Force Logout Feature
Admin-only broadcast that immediately logs out all non-admin users:
// MCP Tool Call
konui_force_logout
{
"reason": "Security update - please log in again",
"exceptRoles": ["admin"] // optional
}
Client behavior:
- Non-admin users: Clear token, redirect to
/login?reason=forced - Admin users: See toast "X users logged out" but stay logged in
- Show reason message on login page
Implementation Phases
Phase 1
Notification dropdown UI + localStorage history
Phase 2
Login/logout broadcasts from auth endpoints
Phase 3
Kontask created/completed broadcasts
Phase 4
Force logout MCP tool + client handler
Phase 5
Service restart broadcasts
📍 Architecture Note
All broadcasts go through konui/src/websocket.ts via broadcast(channel, payload). Client handlers in websocket-client.ts will need channel-specific logic.
What's Next?
Choose where to start:
Quick Actions
Original Request
No layout configured
Details
Type
General
Status
Completed
Scope
vibetools
Tags
websocketuinotificationsauth
Created
8 Jan 2026, 10:07 am
Updated
8 Jan 2026, 10:08 am
Timing
⏱️ 53.6s
0 tools
● TTFE 0%
● Thinking 100%
● Tools 0%
Created By
claude
Raw Data
{
"id": "49851380-f72d-4dad-863f-9580f3dd1a49",
"type": "general",
"status": "completed",
"title": "WebSocket Broadcast Enhancement Plan",
"description": "Design for additional broadcasts, notification dropdown, and force-logout feature",
"context": {
"output": "<div style=\"background:#1e1e1e;color:#e0e0e0;padding:20px;border-radius:8px;font-family:'Segoe UI',sans-serif;\">\n<h2 style=\"color:#fff;margin:0 0 16px 0;\">🔔 WebSocket Broadcast Enhancement Plan</h2>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#3b82f6;margin:0 0 12px 0;\">Current State</h3>\n<p style=\"margin:0;color:#9ca3af;\">We have <code style=\"background:#1e1e1e;padding:2px 6px;border-radius:4px;\">admin:*</code> broadcasts working. The status indicator in the navbar shows connection status. Now we expand this into a full notification system.</p>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#22c55e;margin:0 0 12px 0;\">Proposed New Broadcast Types</h3>\n<table style=\"width:100%;border-collapse:collapse;\">\n<tr style=\"border-bottom:1px solid #4b5563;\">\n<th style=\"text-align:left;padding:8px;color:#fff;\">Event</th>\n<th style=\"text-align:left;padding:8px;color:#fff;\">Channel</th>\n<th style=\"text-align:left;padding:8px;color:#fff;\">Payload</th>\n<th style=\"text-align:left;padding:8px;color:#fff;\">Action</th>\n</tr>\n<tr style=\"border-bottom:1px solid #3b3b3b;\">\n<td style=\"padding:8px;\"><span style=\"color:#22c55e;\">●</span> User Login</td>\n<td style=\"padding:8px;\"><code style=\"background:#1e1e1e;padding:2px 6px;border-radius:4px;\">admin:login</code></td>\n<td style=\"padding:8px;color:#9ca3af;\">username, timestamp, IP</td>\n<td style=\"padding:8px;color:#9ca3af;\">Toast notification</td>\n</tr>\n<tr style=\"border-bottom:1px solid #3b3b3b;\">\n<td style=\"padding:8px;\"><span style=\"color:#f59e0b;\">●</span> User Logout</td>\n<td style=\"padding:8px;\"><code style=\"background:#1e1e1e;padding:2px 6px;border-radius:4px;\">admin:logout</code></td>\n<td style=\"padding:8px;color:#9ca3af;\">username, timestamp</td>\n<td style=\"padding:8px;color:#9ca3af;\">Toast notification</td>\n</tr>\n<tr style=\"border-bottom:1px solid #3b3b3b;\">\n<td style=\"padding:8px;\"><span style=\"color:#8b5cf6;\">●</span> Service Restart</td>\n<td style=\"padding:8px;\"><code style=\"background:#1e1e1e;padding:2px 6px;border-radius:4px;\">admin:restart</code></td>\n<td style=\"padding:8px;color:#9ca3af;\">service, reason, user</td>\n<td style=\"padding:8px;color:#9ca3af;\">Toast + history</td>\n</tr>\n<tr style=\"border-bottom:1px solid #3b3b3b;\">\n<td style=\"padding:8px;\"><span style=\"color:#06b6d4;\">●</span> Kontask Created</td>\n<td style=\"padding:8px;\"><code style=\"background:#1e1e1e;padding:2px 6px;border-radius:4px;\">kontask:created</code></td>\n<td style=\"padding:8px;color:#9ca3af;\">id, title, targetUser</td>\n<td style=\"padding:8px;color:#9ca3af;\">Link to kontask</td>\n</tr>\n<tr style=\"border-bottom:1px solid #3b3b3b;\">\n<td style=\"padding:8px;\"><span style=\"color:#ec4899;\">●</span> Kontask Completed</td>\n<td style=\"padding:8px;\"><code style=\"background:#1e1e1e;padding:2px 6px;border-radius:4px;\">kontask:completed</code></td>\n<td style=\"padding:8px;color:#9ca3af;\">id, title, status</td>\n<td style=\"padding:8px;color:#9ca3af;\">Link to kontask</td>\n</tr>\n<tr style=\"border-bottom:1px solid #3b3b3b;\">\n<td style=\"padding:8px;\"><span style=\"color:#ef4444;\">●</span> Force Logout</td>\n<td style=\"padding:8px;\"><code style=\"background:#1e1e1e;padding:2px 6px;border-radius:4px;\">admin:force_logout</code></td>\n<td style=\"padding:8px;color:#9ca3af;\">reason, exceptUsers[]</td>\n<td style=\"padding:8px;color:#9ca3af;\"><strong>Redirect to /login</strong></td>\n</tr>\n<tr>\n<td style=\"padding:8px;\"><span style=\"color:#f43f5e;\">●</span> Session Killed</td>\n<td style=\"padding:8px;\"><code style=\"background:#1e1e1e;padding:2px 6px;border-radius:4px;\">session:killed</code></td>\n<td style=\"padding:8px;color:#9ca3af;\">sessionId, reason</td>\n<td style=\"padding:8px;color:#9ca3af;\">Update UI</td>\n</tr>\n</table>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#f59e0b;margin:0 0 12px 0;\">📥 Notification Dropdown UI</h3>\n<p style=\"color:#9ca3af;margin:0 0 12px 0;\">Click the bell/indicator to show a dropdown with last 5 notifications:</p>\n<div style=\"background:#1e1e1e;padding:12px;border-radius:6px;border:1px solid #4b5563;max-width:320px;\">\n<div style=\"display:flex;justify-content:space-between;border-bottom:1px solid #3b3b3b;padding-bottom:8px;margin-bottom:8px;\">\n<span style=\"color:#fff;font-weight:600;\">Notifications</span>\n<span style=\"color:#3b82f6;font-size:0.85rem;cursor:pointer;\">Clear all</span>\n</div>\n<div style=\"border-bottom:1px solid #3b3b3b;padding:8px 0;\">\n<div style=\"display:flex;gap:8px;align-items:flex-start;\">\n<span style=\"color:#06b6d4;\">📋</span>\n<div>\n<div style=\"color:#e0e0e0;font-size:0.9rem;\">New kontask: \"Review image crops\"</div>\n<div style=\"color:#6b7280;font-size:0.75rem;\">2 min ago · <span style=\"color:#3b82f6;cursor:pointer;\">View →</span></div>\n</div>\n</div>\n</div>\n<div style=\"border-bottom:1px solid #3b3b3b;padding:8px 0;\">\n<div style=\"display:flex;gap:8px;align-items:flex-start;\">\n<span style=\"color:#22c55e;\">👤</span>\n<div>\n<div style=\"color:#e0e0e0;font-size:0.9rem;\">sarah logged in</div>\n<div style=\"color:#6b7280;font-size:0.75rem;\">5 min ago</div>\n</div>\n</div>\n</div>\n<div style=\"padding:8px 0;\">\n<div style=\"display:flex;gap:8px;align-items:flex-start;\">\n<span style=\"color:#8b5cf6;\">🔄</span>\n<div>\n<div style=\"color:#e0e0e0;font-size:0.9rem;\">konsole restarted</div>\n<div style=\"color:#6b7280;font-size:0.75rem;\">15 min ago</div>\n</div>\n</div>\n</div>\n</div>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#ef4444;margin:0 0 12px 0;\">🚨 Force Logout Feature</h3>\n<p style=\"color:#9ca3af;margin:0 0 12px 0;\">Admin-only broadcast that immediately logs out all non-admin users:</p>\n\n<div style=\"background:#1e1e1e;padding:12px;border-radius:6px;margin-bottom:12px;\">\n<div style=\"color:#7f848e;font-size:0.85rem;margin-bottom:4px;\">// MCP Tool Call</div>\n<pre style=\"margin:0;color:#e5c07b;\">konui_force_logout</pre>\n<pre style=\"margin:4px 0 0 0;color:#98c379;\">{\n \"reason\": \"Security update - please log in again\",\n \"exceptRoles\": [\"admin\"] // optional\n}</pre>\n</div>\n\n<p style=\"color:#9ca3af;margin:0;\"><strong>Client behavior:</strong></p>\n<ul style=\"color:#9ca3af;margin:8px 0 0 0;padding-left:20px;\">\n<li>Non-admin users: Clear token, redirect to <code style=\"background:#1e1e1e;padding:2px 6px;border-radius:4px;\">/login?reason=forced</code></li>\n<li>Admin users: See toast \"X users logged out\" but stay logged in</li>\n<li>Show reason message on login page</li>\n</ul>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#fff;margin:0 0 12px 0;\">Implementation Phases</h3>\n<div style=\"display:flex;flex-direction:column;gap:8px;\">\n<div style=\"display:flex;gap:12px;align-items:center;\">\n<span style=\"background:#22c55e;color:#000;padding:2px 8px;border-radius:4px;font-size:0.8rem;font-weight:600;\">Phase 1</span>\n<span style=\"color:#e0e0e0;\">Notification dropdown UI + localStorage history</span>\n</div>\n<div style=\"display:flex;gap:12px;align-items:center;\">\n<span style=\"background:#3b82f6;color:#fff;padding:2px 8px;border-radius:4px;font-size:0.8rem;font-weight:600;\">Phase 2</span>\n<span style=\"color:#e0e0e0;\">Login/logout broadcasts from auth endpoints</span>\n</div>\n<div style=\"display:flex;gap:12px;align-items:center;\">\n<span style=\"background:#8b5cf6;color:#fff;padding:2px 8px;border-radius:4px;font-size:0.8rem;font-weight:600;\">Phase 3</span>\n<span style=\"color:#e0e0e0;\">Kontask created/completed broadcasts</span>\n</div>\n<div style=\"display:flex;gap:12px;align-items:center;\">\n<span style=\"background:#ef4444;color:#fff;padding:2px 8px;border-radius:4px;font-size:0.8rem;font-weight:600;\">Phase 4</span>\n<span style=\"color:#e0e0e0;\">Force logout MCP tool + client handler</span>\n</div>\n<div style=\"display:flex;gap:12px;align-items:center;\">\n<span style=\"background:#f59e0b;color:#000;padding:2px 8px;border-radius:4px;font-size:0.8rem;font-weight:600;\">Phase 5</span>\n<span style=\"color:#e0e0e0;\">Service restart broadcasts</span>\n</div>\n</div>\n</div>\n\n<div style=\"background:#1e3a5f;border:1px solid #3b82f6;padding:16px;border-radius:6px;\">\n<h4 style=\"color:#fff;margin:0 0 8px 0;\">📍 Architecture Note</h4>\n<p style=\"color:#9ca3af;margin:0;\">All broadcasts go through <code style=\"background:#1e1e1e;padding:2px 6px;border-radius:4px;\">konui/src/websocket.ts</code> via <code style=\"background:#1e1e1e;padding:2px 6px;border-radius:4px;\">broadcast(channel, payload)</code>. Client handlers in <code style=\"background:#1e1e1e;padding:2px 6px;border-radius:4px;\">websocket-client.ts</code> will need channel-specific logic.</p>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-top:16px;\">\n<h4 style=\"margin:0 0 8px 0;color:#fff;\">What's Next?</h4>\n<p style=\"color:#9ca3af;margin:0;\">Choose where to start:</p>\n</div>\n</div>",
"choices": [
{
"label": "Start Phase 1",
"value": "Implement the notification dropdown UI with localStorage history for the last 5 notifications. Make the bell/indicator clickable.",
"primary": true
},
{
"label": "Start Phase 4",
"value": "Implement the force logout feature first - add the konui_force_logout MCP tool and client-side handler that logs out non-admin users",
"primary": false
},
{
"label": "Full implementation",
"value": "Implement all 5 phases of the WebSocket broadcast enhancement - notification dropdown, login/logout broadcasts, kontask broadcasts, force logout tool, and service restart broadcasts",
"primary": false
}
],
"requestedAt": "2026-01-08T05:30:00.000Z",
"requestId": "c1adc8c7-d719-402c-8caf-b592dbea09aa",
"turnTiming": {
"totalMs": 53563,
"ttfeMs": 109,
"thinkingMs": 53451,
"toolExecutionMs": 0,
"toolCallCount": 0,
"thinkingPct": 100,
"toolsPct": 0,
"ttfePct": 0
}
},
"createdBy": "claude",
"createdAt": "2026-01-08T00:07:56.873Z",
"updatedAt": "2026-01-08T00:08:01.278Z",
"requestId": "c1adc8c7-d719-402c-8caf-b592dbea09aa",
"scope": "vibetools",
"tags": [
"websocket",
"ui",
"notifications",
"auth"
],
"targetUser": "claude"
}