- Fix LogStreamPanel event listener cleanup with synchronous unlisten
- Fix eventBus async-unsafe unsubscribe with proper error handling
- Fix KubernetesPage infinite loading by resetting state on section change
- Add ErrorBoundary component with reset capability
- Add Badge component with multiple variants
- Add ResourceDetailsDrawer for slide-out details panel
- Add useFavorites hook with localStorage persistence
- Add useKeyboardShortcuts hook for declarative shortcuts
- Add comprehensive test coverage for all new components/hooks
- Add keyboard shortcuts documentation to README
- Wrap KubernetesPage with ErrorBoundary for crash recovery
- Install react-window for virtual scrolling support
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
## kubectl credentials still failing after --context fix
Root cause: both extract_context() (kube.rs) and upload_kubeconfig() (shell.rs)
ignored the kubeconfig's current-context field and always picked contexts[0] from
the contexts array. If a kubeconfig has multiple contexts and current-context
points to entry N>0, we silently used the wrong context — one that may have empty
or expired credentials — causing the 401 "the server has asked for the client to
provide credentials" error on every kubectl call.
Fixes:
- extract_context(): read current-context field first; fall back to contexts[0]
only when current-context is absent or empty.
- extract_current_context_name(): new helper in kubeconfig.rs using the same
line-scanner approach as parse_kubeconfig_contexts (no extra dependencies).
- upload_kubeconfig(): use current-context to select the matching context entry
when storing context name in kubeconfig_files; falls back to first entry.
NOTE: existing kubeconfig rows in the database have the old (wrong) context
stored. Re-uploading kubeconfig files after deploying this build will fix them.
## Cluster dropdown still showing UUID
Root cause: SelectValue rendered ctx.value (the raw UUID passed to SelectItem's
value prop) instead of the display label (SelectItem's children). The custom
Select component had no mechanism to mirror a selected item's children into the
trigger area.
Fix: Select now builds a value→label Map by walking the children tree at render
time (collectLabels). The map is memoised on children. SelectValue reads the
display label from the map; if found, shows the label; otherwise falls back to
the raw value so existing behaviour is preserved for callers that don't need it.
1. kubectl credentials error (41 places in kube.rs)
Every kubectl invocation used .env("KUBERNETES_CONTEXT", context) which
is not a real kubectl environment variable — kubectl silently ignores it
and falls back to whatever current-context is set in the kubeconfig YAML.
If that context has expired or wrong credentials the auth failure occurs.
Replaced all 41 instances with .arg("--context").arg(context) so kubectl
always uses the correct context from the stored kubeconfig.
2. Cluster name still showed UUID (two causes)
a) Hotbar read from kubernetesStore.clusters (ClusterInfo[]) which is never
populated by the kubeconfig-based flow — always empty, so selectedCluster
was always undefined. Removed the Zustand cluster lookup from Hotbar and
added a clusterName prop passed from KubernetesPage.tsx (selectedConfig?.name).
b) ClusterOverview fell back to showing raw clusterId UUID when clusterName
was undefined. Changed subtitle to render conditionally so UUID never shows.
3. Bell dialog had no way to close
Custom DialogContent had no X button and no backdrop-click handler.
Added X close button (top-right) and backdrop-click-to-close.
4. Hotbar icons invisible in dark mode
variant="ghost" only styles hover state with no baseline text color.
Added className="text-foreground" to all icon-only ghost buttons.
Implement three authentication methods for Confluence, ServiceNow, and Azure DevOps:
1. **OAuth2** - Traditional OAuth flow for enterprise SSO environments
2. **Embedded Browser** - Webview-based login that captures session cookies/tokens
- Solves VPN constraints: users authenticate off-VPN via web UI
- Extracted credentials work on-VPN for API calls
- Based on confluence-publisher agent pattern
3. **Manual Token** - Direct API token/PAT input as fallback
**Changes:**
- Add webview_auth.rs module for embedded browser authentication
- Implement authenticate_with_webview and extract_cookies_from_webview commands
- Implement save_manual_token command with validation
- Add AuthMethod enum to support all three modes
- Add RadioGroup UI component for mode selection
- Complete rewrite of Integrations settings page with mode-specific UI
- Add secondary button variant for UI consistency
**VPN-friendly design:**
Users can authenticate via webview when off-VPN (web UI accessible), then use extracted cookies for API calls when on-VPN (API requires VPN). Addresses enterprise SSO limitations where OAuth app registration is blocked.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Color inheritance was not propagating on macOS WebKit causing dropdown
text to be invisible. Items only appeared when hovered due to
hover:text-accent-foreground being the only color set.