From 153c001483d52c6c01b5d32f32de8169dd1a2c48 Mon Sep 17 00:00:00 2001 From: Calmcacil Date: Mon, 12 Jan 2026 22:57:05 +0100 Subject: [PATCH] bd sync: 2026-01-12 22:57:05 --- .beads/issues.jsonl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index dcf55b0..8bc473b 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -16,7 +16,7 @@ {"id":"wg-admin-abw","title":"Create wg-client-manager script","description":"Create new wg-client-manager script for client operations: add, remove, list, show, qr. Implement proper command parsing, use interactive 'read' with 'WGI_' environment variable overrides, call validation functions, use atomic config updates.","status":"closed","priority":2,"issue_type":"task","owner":"Calmcacil@Raion","created_at":"2026-01-12T16:27:53.150007325+01:00","created_by":"Calmcacil","updated_at":"2026-01-12T16:48:38.86400169+01:00","closed_at":"2026-01-12T16:48:38.86400169+01:00","close_reason":"Created wg-client-manager script with all required commands (add, remove, list, show, qr). Implements interactive prompts with WGI_ environment variable overrides, uses validation functions, and performs atomic config updates.","dependencies":[{"issue_id":"wg-admin-abw","depends_on_id":"wg-admin-cwb","type":"blocks","created_at":"2026-01-12T16:28:20.280054863+01:00","created_by":"Calmcacil"},{"issue_id":"wg-admin-abw","depends_on_id":"wg-admin-37o","type":"blocks","created_at":"2026-01-12T16:28:20.299310073+01:00","created_by":"Calmcacil"},{"issue_id":"wg-admin-abw","depends_on_id":"wg-admin-lzl","type":"blocks","created_at":"2026-01-12T16:28:20.300924186+01:00","created_by":"Calmcacil"},{"issue_id":"wg-admin-abw","depends_on_id":"wg-admin-wsk","type":"blocks","created_at":"2026-01-12T16:28:20.354270061+01:00","created_by":"Calmcacil"},{"issue_id":"wg-admin-abw","depends_on_id":"wg-admin-0va","type":"blocks","created_at":"2026-01-12T16:28:21.926811217+01:00","created_by":"Calmcacil"}]} {"id":"wg-admin-az7","title":"Fix client details navigation and improve deletion confirmation UX","description":"\n# Issues to Fix\n\n## 1. Navigation Key Binding Issues\n- **Problem**: 'q' key for going back from client details screen doesn't work properly\n- **Solution**: \n - Change 'q' key to 'b' for back navigation (more intuitive)\n - Add 'esc' key binding for back navigation (in addition to 'b')\n - Update help text to reflect new key bindings\n\n## 2. Deletion Confirmation UX Improvements\n- **Problem**: Current confirmation modal has poor formatting and lacks safety checks\n- **Solution**:\n - **Improve modal formatting**: Better visual styling, clearer layout\n - **Add name verification**: Require user to type the client's name before confirming deletion (prevents accidental deletions)\n - Better visual feedback for selected option (Yes/No)\n\n# Files to Modify\n\n1. **internal/tui/screens/detail.go**\n - Line 124: Change key binding from 'q' to 'b'\n - Line 124: Add 'esc' to back navigation (ensure it works)\n - Line 199: Update help text to show new key bindings\n - Lines 127-134: Replace simple confirm modal with name-verification modal\n\n2. **internal/tui/components/confirm.go** (or create new component)\n - Improve modal styling and formatting\n - Add text input field for client name verification\n - Update key bindings for name input field\n\n# Implementation Notes\n\n- The confirm modal currently uses simple Yes/No with arrow keys\n- New approach: Show \"Type the client name to confirm: [input field]\"\n- Only enable confirm button when input matches client name exactly\n- Case-sensitive name matching for safety\n- Add clear visual feedback (red for danger, green for match)\n","status":"closed","priority":0,"issue_type":"bug","owner":"Calmcacil@Raion","created_at":"2026-01-12T22:13:28.830300356+01:00","created_by":"Calmcacil","updated_at":"2026-01-12T22:16:47.251848171+01:00","closed_at":"2026-01-12T22:16:47.251848171+01:00","close_reason":"Fixed navigation key bindings (changed 'q' to 'b', added 'esc') and created improved deletion confirmation modal with name verification for safety."} {"id":"wg-admin-bay","title":"Implement real-time status checking","description":"Implement real-time connection status using 'wg show wg0' command. Check if client public key appears in peers list. Update status in table: Connected (active peer) or Disconnected (not in peers list). Add auto-refresh every 30 seconds using tea.Tick. Manual refresh with 'r' key.","status":"closed","priority":2,"issue_type":"task","owner":"Calmcacil@Raion","created_at":"2026-01-12T17:02:57.643693952+01:00","created_by":"Calmcacil","updated_at":"2026-01-12T17:34:23.96887044+01:00","closed_at":"2026-01-12T17:34:23.96887044+01:00","close_reason":"Implemented real-time status checking functionality: Created status.go with GetClientStatus() and GetAllPeers() functions that parse 'wg show wg0' output to determine connection status. Added PeerStatus struct with PublicKey, Endpoint, AllowedIPs, LatestHandshake, TransferRx, TransferTx, and Status fields. Created tea_messages.go with Tick() command for auto-refresh and ManualRefresh() command for immediate refresh using tea.Tick and custom messages. Status is 'Connected' if handshake is within 3 minutes, otherwise 'Disconnected'.","dependencies":[{"issue_id":"wg-admin-bay","depends_on_id":"wg-admin-xum","type":"blocks","created_at":"2026-01-12T17:04:44.270454474+01:00","created_by":"Calmcacil"}]} -{"id":"wg-admin-bfe","title":"Fix background dimming on modal overlays","description":"# Fix Background Dimming on Modal Overlays\n\n## Problem\n\nBackground content is not properly dimmed when certain modal windows are displayed. This causes visual inconsistency and makes it unclear that a modal is active.\n\n## Current State\n\n### Working Modals (Background Dimmed)\n\n**Delete Confirmation Modal** (`detail.go` line 144-157):\n```go\nif s.showConfirm \u0026\u0026 s.confirmModal != nil {\n // Render underlying content dimmed\n content := s.renderContent()\n dimmedContent := lipgloss.NewStyle().\n Foreground(lipgloss.Color(\"244\")).\n Render(content)\n\n // Overlay confirmation modal\n return lipgloss.JoinVertical(\n lipgloss.Left,\n dimmedContent,\n s.confirmModal.View(),\n )\n}\n```\n\n**Restore Confirmation Modal** (`restore.go` line 147-160):\n```go\nif s.showConfirm \u0026\u0026 s.confirmModal != nil {\n // Render underlying content dimmed\n content := s.renderContent()\n dimmedContent := lipgloss.NewStyle().\n Foreground(lipgloss.Color(\"244\")).\n Render(content)\n\n // Overlay confirmation modal\n return lipgloss.JoinVertical(\n lipgloss.Left,\n dimmedContent,\n s.confirmModal.View(),\n )\n}\n```\n\n### Broken Modals (Background NOT Dimmed)\n\n**Config Display Modal** (`detail.go` line 139-141):\n```go\n// Handle config display modal\nif s.showConfig \u0026\u0026 s.configDisplay != nil {\n return s.configDisplay.View() // BUG: No background dimming!\n}\n```\n\n**Delete Confirm Modal Component** (`internal/tui/components/delete-confirm.go`):\n- The modal renders directly to screen\n- Does NOT dim background content\n- Assumes parent screen will handle dimming\n\n**Old Confirm Modal Component** (`internal/tui/components/confirm.go`):\n- The modal renders directly to screen\n- Does NOT dim background content\n- Assumes parent screen will handle dimming\n\n## Root Cause\n\n1. **Inconsistent Implementation**: Some screens dim background in their View() method, others don't\n2. **Modal Components Don't Dim**: Modal components (ConfigDisplay, Confirm, DeleteConfirm) don't dim background themselves\n3. **Screens Rely on Parents**: Modal components assume parent screens will handle dimming, but this's inconsistent\n\n## Impact\n\n1. **Visual Inconsistency**: Some modals dim background, others don't\n2. **Poor UX**: Users can't tell if a modal is active or just new content\n3. **Confusion**: It's unclear whether content is part of the modal or background\n4. **Accessibility**: Dimming helps focus attention on the modal; without it, focus is unclear\n\n## Proposed Solution\n\n### Option 1: Modals Dim Their Own Background (Recommended)\n\nEach modal component should be responsible for:\n1. Taking screen width/height as parameters\n2. Rendering full screen content (dimmed background + modal overlay)\n3. This makes modals self-contained and consistent\n\n**Implementation:**\n```go\n// In ConfigDisplayModel View()\nfunc (m *ConfigDisplayModel) View() string {\n if !m.Visible {\n return \"\"\n }\n\n // Dimmed background content would need to be passed in\n // OR modal takes a \"background\" parameter to render\n\n // For now, this approach may not work without refactoring\n // See Option 2 below\n}\n```\n\n### Option 2: Screens Handle Dimming for ALL Modals (Current Pattern)\n\nUpdate screens to dim background for ALL modals consistently:\n\n**detail.go** - Already handles delete confirmation, needs to add for config display:\n```go\nif s.showConfig \u0026\u0026 s.configDisplay != nil {\n // Render underlying content dimmed\n content := s.renderContent()\n dimmedContent := lipgloss.NewStyle().\n Foreground(lipgloss.Color(\"244\")).\n Render(content)\n\n // Overlay config modal\n return lipgloss.JoinVertical(\n lipgloss.Left,\n dimmedContent,\n s.configDisplay.View(),\n )\n}\n```\n\n**This is the easiest fix** - just follow the existing pattern!\n\n## Files to Fix\n\n### High Priority (Fix Background Dimming)\n\n1. **`internal/tui/screens/detail.go`** (line 139-141)\n - Add background dimming for config display modal\n - Follow same pattern as delete confirmation modal\n\n2. **`internal/tui/components/confirm.go`**\n - Note: This component is used by restore screen\n - Restore screen already handles dimming correctly\n - No changes needed\n\n3. **`internal/tui/components/delete-confirm.go`**\n - Note: This component is used by detail screen\n - Detail screen already handles dimming correctly\n - No changes needed\n\n## Implementation Steps\n\n### Step 1: Fix Config Display Modal in detail.go\n\n**Change from:**\n```go\nif s.showConfig \u0026\u0026 s.configDisplay != nil {\n return s.configDisplay.View()\n}\n```\n\n**To:**\n```go\nif s.showConfig \u0026\u0026 s.configDisplay != nil {\n // Render underlying content dimmed\n content := s.renderContent()\n dimmedContent := lipgloss.NewStyle().\n Foreground(lipgloss.Color(\"244\")).\n Render(content)\n\n // Overlay config display modal\n return lipgloss.JoinVertical(\n lipgloss.Left,\n dimmedContent,\n s.configDisplay.View(),\n )\n}\n```\n\n### Step 2: Verify All Modals\n\nCheck that all modals follow consistent pattern:\n1. Delete confirmation modal (detail.go) ✓ Already correct\n2. Config display modal (detail.go) ✗ Needs fix\n3. Restore confirmation modal (restore.go) ✓ Already correct\n\n## Expected Behavior\n\nAfter fix:\n1. Config display modal dims background content (color 244)\n2. Modal is clearly visible on top of dimmed background\n3. User understands they're interacting with a modal\n4. Visual consistency across all modals\n\n## Testing\n\n1. Open client details\n2. Press 'c' to view config\n3. Verify background content is dimmed\n4. Verify modal is clearly visible\n5. Close modal and verify normal view returns\n\n## Dependencies\n\nNone - this is a UI consistency fix\n\n## Priority\n\n**CRITICAL (P0)** - Visual consistency is important for UX","status":"open","priority":0,"issue_type":"bug","owner":"Calmcacil@Raion","created_at":"2026-01-12T22:38:54.028354228+01:00","created_by":"Calmcacil","updated_at":"2026-01-12T22:43:24.402405243+01:00"} +{"id":"wg-admin-bfe","title":"Fix background dimming on modal overlays","description":"# Fix Background Dimming on Modal Overlays\n\n## Problem\n\nBackground content is not properly dimmed when certain modal windows are displayed. This causes visual inconsistency and makes it unclear that a modal is active.\n\n## Current State\n\n### Working Modals (Background Dimmed)\n\n**Delete Confirmation Modal** (`detail.go` line 144-157):\n```go\nif s.showConfirm \u0026\u0026 s.confirmModal != nil {\n // Render underlying content dimmed\n content := s.renderContent()\n dimmedContent := lipgloss.NewStyle().\n Foreground(lipgloss.Color(\"244\")).\n Render(content)\n\n // Overlay confirmation modal\n return lipgloss.JoinVertical(\n lipgloss.Left,\n dimmedContent,\n s.confirmModal.View(),\n )\n}\n```\n\n**Restore Confirmation Modal** (`restore.go` line 147-160):\n```go\nif s.showConfirm \u0026\u0026 s.confirmModal != nil {\n // Render underlying content dimmed\n content := s.renderContent()\n dimmedContent := lipgloss.NewStyle().\n Foreground(lipgloss.Color(\"244\")).\n Render(content)\n\n // Overlay confirmation modal\n return lipgloss.JoinVertical(\n lipgloss.Left,\n dimmedContent,\n s.confirmModal.View(),\n )\n}\n```\n\n### Broken Modals (Background NOT Dimmed)\n\n**Config Display Modal** (`detail.go` line 139-141):\n```go\n// Handle config display modal\nif s.showConfig \u0026\u0026 s.configDisplay != nil {\n return s.configDisplay.View() // BUG: No background dimming!\n}\n```\n\n**Delete Confirm Modal Component** (`internal/tui/components/delete-confirm.go`):\n- The modal renders directly to screen\n- Does NOT dim background content\n- Assumes parent screen will handle dimming\n\n**Old Confirm Modal Component** (`internal/tui/components/confirm.go`):\n- The modal renders directly to screen\n- Does NOT dim background content\n- Assumes parent screen will handle dimming\n\n## Root Cause\n\n1. **Inconsistent Implementation**: Some screens dim background in their View() method, others don't\n2. **Modal Components Don't Dim**: Modal components (ConfigDisplay, Confirm, DeleteConfirm) don't dim background themselves\n3. **Screens Rely on Parents**: Modal components assume parent screens will handle dimming, but this's inconsistent\n\n## Impact\n\n1. **Visual Inconsistency**: Some modals dim background, others don't\n2. **Poor UX**: Users can't tell if a modal is active or just new content\n3. **Confusion**: It's unclear whether content is part of the modal or background\n4. **Accessibility**: Dimming helps focus attention on the modal; without it, focus is unclear\n\n## Proposed Solution\n\n### Option 1: Modals Dim Their Own Background (Recommended)\n\nEach modal component should be responsible for:\n1. Taking screen width/height as parameters\n2. Rendering full screen content (dimmed background + modal overlay)\n3. This makes modals self-contained and consistent\n\n**Implementation:**\n```go\n// In ConfigDisplayModel View()\nfunc (m *ConfigDisplayModel) View() string {\n if !m.Visible {\n return \"\"\n }\n\n // Dimmed background content would need to be passed in\n // OR modal takes a \"background\" parameter to render\n\n // For now, this approach may not work without refactoring\n // See Option 2 below\n}\n```\n\n### Option 2: Screens Handle Dimming for ALL Modals (Current Pattern)\n\nUpdate screens to dim background for ALL modals consistently:\n\n**detail.go** - Already handles delete confirmation, needs to add for config display:\n```go\nif s.showConfig \u0026\u0026 s.configDisplay != nil {\n // Render underlying content dimmed\n content := s.renderContent()\n dimmedContent := lipgloss.NewStyle().\n Foreground(lipgloss.Color(\"244\")).\n Render(content)\n\n // Overlay config modal\n return lipgloss.JoinVertical(\n lipgloss.Left,\n dimmedContent,\n s.configDisplay.View(),\n )\n}\n```\n\n**This is the easiest fix** - just follow the existing pattern!\n\n## Files to Fix\n\n### High Priority (Fix Background Dimming)\n\n1. **`internal/tui/screens/detail.go`** (line 139-141)\n - Add background dimming for config display modal\n - Follow same pattern as delete confirmation modal\n\n2. **`internal/tui/components/confirm.go`**\n - Note: This component is used by restore screen\n - Restore screen already handles dimming correctly\n - No changes needed\n\n3. **`internal/tui/components/delete-confirm.go`**\n - Note: This component is used by detail screen\n - Detail screen already handles dimming correctly\n - No changes needed\n\n## Implementation Steps\n\n### Step 1: Fix Config Display Modal in detail.go\n\n**Change from:**\n```go\nif s.showConfig \u0026\u0026 s.configDisplay != nil {\n return s.configDisplay.View()\n}\n```\n\n**To:**\n```go\nif s.showConfig \u0026\u0026 s.configDisplay != nil {\n // Render underlying content dimmed\n content := s.renderContent()\n dimmedContent := lipgloss.NewStyle().\n Foreground(lipgloss.Color(\"244\")).\n Render(content)\n\n // Overlay config display modal\n return lipgloss.JoinVertical(\n lipgloss.Left,\n dimmedContent,\n s.configDisplay.View(),\n )\n}\n```\n\n### Step 2: Verify All Modals\n\nCheck that all modals follow consistent pattern:\n1. Delete confirmation modal (detail.go) ✓ Already correct\n2. Config display modal (detail.go) ✗ Needs fix\n3. Restore confirmation modal (restore.go) ✓ Already correct\n\n## Expected Behavior\n\nAfter fix:\n1. Config display modal dims background content (color 244)\n2. Modal is clearly visible on top of dimmed background\n3. User understands they're interacting with a modal\n4. Visual consistency across all modals\n\n## Testing\n\n1. Open client details\n2. Press 'c' to view config\n3. Verify background content is dimmed\n4. Verify modal is clearly visible\n5. Close modal and verify normal view returns\n\n## Dependencies\n\nNone - this is a UI consistency fix\n\n## Priority\n\n**CRITICAL (P0)** - Visual consistency is important for UX","status":"closed","priority":0,"issue_type":"bug","owner":"Calmcacil@Raion","created_at":"2026-01-12T22:38:54.028354228+01:00","created_by":"Calmcacil","updated_at":"2026-01-12T22:56:57.415810782+01:00","closed_at":"2026-01-12T22:56:57.415810782+01:00","close_reason":"Fixed by adding background dimming to config display modal. Modal now dims background content before showing, following the same pattern as delete confirmation modal for visual consistency."} {"id":"wg-admin-cwb","title":"Implement input validation functions","description":"Create robust validation functions: validate_client_name() (regex check for [a-zA-Z0-9_-]), validate_ip_availability(), validate_dns_servers(), validate_port_range(), validate_config_syntax(). Add validation before client creation and config changes.","status":"closed","priority":2,"issue_type":"task","owner":"Calmcacil@Raion","created_at":"2026-01-12T16:27:53.143579452+01:00","created_by":"Calmcacil","updated_at":"2026-01-12T16:38:18.705584126+01:00","closed_at":"2026-01-12T16:38:18.705584126+01:00","close_reason":"Implemented all validation functions: validate_client_name(), validate_ip_availability(), validate_dns_servers(), validate_port_range(), validate_config_syntax(). Added validation calls in cmd_add and cmd_load_clients."} {"id":"wg-admin-dd2","title":"Implement client detail view","description":"Create detailed view for selected client showing name, IPs, public key, connection status, last handshake time, and transfer stats. Include copy to clipboard functionality and delete button with confirmation.","status":"closed","priority":2,"issue_type":"task","owner":"Calmcacil@Raion","created_at":"2026-01-12T17:03:30.290544009+01:00","created_by":"Calmcacil","updated_at":"2026-01-12T17:54:27.63729296+01:00","closed_at":"2026-01-12T17:54:27.63729296+01:00","close_reason":"Implemented client detail view in internal/tui/screens/detail.go with all required features: displays client name, IPs, public key, connection status, handshake time, transfer stats; copy to clipboard (press 'c'), delete with confirmation (press 'd'), navigation back (press 'q' or 'esc'); styling with lipgloss in two-column layout; integrated with wireguard.GetClientStatus() for real-time status.","dependencies":[{"issue_id":"wg-admin-dd2","depends_on_id":"wg-admin-wf1","type":"blocks","created_at":"2026-01-12T17:04:52.968940596+01:00","created_by":"Calmcacil"}]} {"id":"wg-admin-ddl","title":"Debug connectivity status showing Disconnected incorrectly","description":"Debug why connectivity status shows 'Disconnected' when client is actually connected. Investigate the finalizePeerStatus logic and the 3-minute threshold for connection status.","status":"closed","priority":1,"issue_type":"bug","owner":"Calmcacil@Raion","created_at":"2026-01-12T19:14:49.564914056+01:00","created_by":"Calmcacil","updated_at":"2026-01-12T19:17:12.292551145+01:00","closed_at":"2026-01-12T19:17:12.292551145+01:00","close_reason":"Fixed q key handling to only quit from list screen, increased connection timeout threshold to 5 minutes"}