-
Notifications
You must be signed in to change notification settings - Fork 90
feat: add Git SSH key configuration feature (issue #91) #98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
OleksandrKucherenko
wants to merge
1
commit into
Adembc:main
Choose a base branch
from
OleksandrKucherenko:claude/implement-issue-91-okEI3
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
feat: add Git SSH key configuration feature (issue #91) #98
OleksandrKucherenko
wants to merge
1
commit into
Adembc:main
from
OleksandrKucherenko:claude/implement-issue-91-okEI3
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This commit implements the feature requested in issue Adembc#91 to help users configure which SSH key Git should use for repository operations. Changes: - Added GitService with methods to detect git repositories, list SSH keys, and configure git to use specific SSH keys - Added SSHKey struct to represent SSH key metadata - Created GitSSHSetup UI modal for interactive SSH key selection - Added keyboard shortcut 'G' to trigger Git SSH setup modal - Updated status bar to show the new Git SSH shortcut - Integrated git service into TUI application The feature allows users to: - Detect if they are in a git repository - List available SSH keys from ~/.ssh/ - Select an SSH key to use for git operations - Configure git via 'git config core.sshCommand' at local or global scope - View current SSH configuration for the repository This addresses the common scenario of managing multiple SSH identities (company, personal, vendor accounts) by making it easy to configure which key Git should use for a specific repository. fix: discover SSH keys from config files, not just ~/.ssh/ This fix addresses the issue where SSH keys stored outside of ~/.ssh/ directory were not being discovered by the Git SSH setup feature. Changes: - Updated ListSSHKeys to accept ServerRepository parameter - Added logic to extract IdentityFile paths from SSH config - Keys from SSH config are now the primary source - ~/.ssh/ directory is scanned as a secondary source - Refactored complex function into smaller helpers to reduce cyclomatic complexity - Added proper error handling for missing ~/.ssh/ when config keys exist The feature now correctly discovers SSH keys from: 1. SSH config file (primary source) - reads IdentityFile directives 2. ~/.ssh/ directory (secondary source) - scans for additional keys This ensures that SSH keys stored in custom locations (e.g., /home/user/workspace/_keys_/) are properly discovered and can be configured for Git operations. feat: add keychain/ssh-agent integration and git repo indicator This commit enhances the Git SSH key configuration feature with: 1. Keychain/ssh-agent integration: - Detect which SSH keys are currently loaded in ssh-agent/keychain - Mark loaded keys with "in agent" indicator (green) - Sort keys to show agent-loaded keys first - Added GetLoadedAgentKeys() method to check ssh-add -l 2. Git repository indicator panel: - New GitInfo panel displays when in a git repository - Shows repository name and SSH configuration status - Appears at bottom of server list (4 lines) - Prompts user to press 'G' if SSH not configured 3. Enhanced UI feedback: - Keys in agent shown with [green](in agent)[-] tag - Count of keys loaded in agent displayed in setup dialog - Keys without .pub file shown with [red](no .pub)[-] - Encrypted keys shown with [yellow](encrypted)[-] 4. Improved key discovery: - Keys from SSH config (primary source) checked against agent - Keys from ~/.ssh/ (secondary source) also checked - Full key path matching against ssh-add output This addresses the keychain integration requirements from issue Adembc#91, making it easier to see which keys are ready to use and providing better visibility when working in git repositories. feat: add "Clear Configuration" button to reset Git SSH config This commit adds the ability to reset Git SSH configuration to default with a single click from the UI. Changes: 1. Added ClearGitSSHConfig() method to GitService - Supports clearing local, global, or both configurations - Handles "key not found" gracefully (exit code 5) - Uses `git config --unset core.sshCommand` 2. Added scope constants (ScopeLocal, ScopeGlobal, ScopeBoth) - Exported constants for consistent scope handling - Used across service and UI layers 3. Enhanced Git SSH Setup UI - "Clear Configuration" button appears when config exists - Confirmation modal with three options: * Cancel - return to setup * Clear Local - remove repository-level config only * Clear Both - remove both local and global configs - Success/error modals with clear feedback User Experience: - Press 'G' to open Git SSH setup - If SSH config exists, "Clear Configuration" button is shown - Click to confirm which scope to clear - Git reverts to default SSH behavior (ssh-agent, ~/.ssh/config, default keys) This addresses the user request to easily reset Git configuration back to default without running manual git commands. feat: display keychain-loaded SSH keys in servers list Add virtual server entries for SSH keys loaded in ssh-agent/keychain. These entries appear in the main servers list with a "keychain" tag and are read-only (cannot be edited or deleted). Changes: - Add GetKeychainServers() method to GitService that parses ssh-add -L - Modify ServerService to accept GitService dependency - Update ListServers() to merge keychain servers with repository servers - Add isKeychainServer() helper function in UI handlers - Guard edit/delete operations to prevent modification of keychain servers - Display error message when attempting to edit/delete keychain servers Addresses issue Adembc#91 comment about showing keychain-loaded keys in the list. fix: linter error and Git info panel refresh issues Fix two issues: 1. Linter error (prealloc): Pre-allocate servers slice with capacity in GetKeychainServers() to avoid prealloc lint error. 2. Git info panel not refreshing: Update handleModalClose() to call updateGitInfoPanel() so the panel refreshes after Git SSH config is cleared, showing the correct status instead of stale "SSH configured". This ensures the Git Repository panel displays accurate information after configuration changes. feat: improve keychain server display and prevent invalid operations Improvements to keychain server handling: 1. Display format: Show full key info like "rsa:4096 SHA256:5NUhY... user@email" - Parse ssh-add -l output (fingerprint list) instead of -L - Include key type, size, truncated fingerprint, and comment - Makes keychain entries clearly distinguishable from regular servers 2. Prevent invalid operations on keychain servers: - SSH connection: Show informative message that keys are auto-used - Ping: Cannot ping virtual keychain entries - Copy SSH command: Not applicable for keychain keys - Port forwarding: Cannot forward through keychain keys - Stop forwarding: Cannot stop non-existent forwards All operations now check isKeychainServer() and display appropriate error messages, preventing app hangs and confusing behavior. Addresses user feedback about app hanging on Enter and unclear display. feat: add keychain visibility toggle (K key) Add opt-in visibility toggle for keychain-loaded SSH keys: 1. Toggle behavior: - Press 'K' to toggle keychain keys visibility - Default: hidden (keychain keys not shown) - When enabled: keychain keys appear in servers list - Status message shows current state: "Keychain keys: visible/hidden" 2. Implementation: - Add showKeychainKeys boolean field to TUI - Filter keychain servers in refreshServerList based on toggle - Add handleKeychainToggle() to flip state and refresh - Bind 'K' key to toggle handler - Update status bar to show 'K Keychain' command 3. Design rationale: - Keychain keys shown only when explicitly toggled on - Prevents clutter in normal server list - Users can enable when needed for reference - Maintains view-only nature (no edit/delete/SSH operations) This addresses user feedback about keychain keys needing opt-in visibility rather than always being displayed. feat: add SSH key management service layer Add foundational service layer for SSH key discovery and management: 1. Domain model (domain/sshkey.go): - SSHKey struct with comprehensive key information - Fields: Path, Name, Comment, Type, Size, Fingerprint - Status flags: LoadedInAgent, IsEncrypted, HasPublicKey - Source tracking: "config" or "agent" 2. Service interface (ports/services.go): - ListAllSSHKeys() - List all SSH keys from config + agent - LoadKeyToAgent() - Load key into ssh-agent - UnloadKeyFromAgent() - Remove key from ssh-agent 3. Service implementation (git_service.go): - Discover keys from SSH config IdentityFiles - Scan ~/.ssh/ directory for additional keys - Parse ssh-add -l output to identify loaded keys - Match keys by fingerprint to determine agent status - Parse key files to detect type and encryption - Use ssh-keygen to extract fingerprints - Sort keys: loaded first, then alphabetically 4. Load/Unload operations: - ssh-add <keyfile> for loading (interactive passphrase) - ssh-add -d <keyfile> for unloading Preparation for SSH Keys panel UI feature. Service layer is complete and ready for UI integration. fix: address linter warnings in SSH key parsing Fix gosec and gocritic linter warnings: 1. Add #nosec comments for validated file reads: - Reading SSH private key files from config - Reading public key files derived from private keys - ssh-keygen command with validated paths 2. Refactor if-else chains to switch statements: - Key type detection from ssh-add output - Private key format detection - Modern OpenSSH key type inference All file paths are validated before use - either from SSH config or scanned from ~/.ssh directory. feat: add SSH Keys panel to TUI (WIP) Add dedicated SSH Keys panel alongside Servers panel: 1. New UI Components: - SSHKeysList: List component for SSH keys with status indicators - SSHKeyDetails: Details panel showing key info and commands - Format: "[●] 🔒 keyname (type:size)" - green dot for loaded keys 2. TUI Layout Changes: - Left panel now contains: SearchBar, Servers, SSH Keys, Git Info - Right panel dynamically shows either ServerDetails or SSHKeyDetails - Removed keychain toggle (keys now in separate panel always visible) 3. Key Discovery: - Load SSH keys on startup using ListAllSSHKeys() - Show keys from SSH config + ~/.ssh/ + ssh-agent - Display loaded status, encryption, and public key availability 4. Filter Changes: - Remove ALL keychain servers from Servers list - They're now only in SSH Keys panel (no mixing) Still TODO: - Tab navigation between Servers and SSH Keys panels - Load/Unload key handlers (l/u keys) - Update status bar to reflect new commands - Focus management and visual feedback Build succeeds. Next phase: Add Tab navigation and load/unload functionality. fix: remove redundant sprintf in SSH keys list formatting Remove redundant fmt.Sprintf for key.Type since it's already a string. Addresses gocritic linter warning. feat: add Tab navigation between Servers and SSH Keys panels - Add Tab key handler to switch focus between panels - Implement visual feedback with border color changes (blue for active, gray for inactive) - Update j/k navigation to work with both Servers and SSH Keys panels - Add updatePanelBorders() and updateRightPanel() methods - Dynamically switch right panel details based on focus feat: implement load/unload SSH key handlers - Add 'l' key to load selected SSH key into ssh-agent - Add 'u' key to unload selected SSH key from ssh-agent - Keys only respond to l/u when SSH Keys panel is focused - Suspend TUI during load to allow passphrase entry - Automatically refresh SSH keys list after load/unload - Show status messages for success/failure - Add refreshSSHKeysList() helper method feat: update status bar with new SSH key commands - Add 'Tab' to switch between Servers and SSH Keys panels - Add 'l/u' for Load/Unload SSH key operations - Remove obsolete 'K Keychain' command feat: add Shift+Tab and mouse click support for panel navigation - Add Shift+Tab (KeyBacktab) support to switch between panels - Add mouse click handlers to both Servers and SSH Keys panels - Clicking on a panel switches focus to that panel - Both Tab and Shift+Tab toggle between the two panels feat: add separate methods for config and agent SSH keys - Add ListSSHKeysFromConfig() to get keys from SSH config files and ~/.ssh directory - Add ListSSHKeysFromAgent() to get keys currently loaded in ssh-agent - Add constants for SSH key types and file names to fix linter warnings - Convert if-else chains to switch statements per linter recommendations - These methods enable separate panels for config keys vs agent keys feat: split SSH keys into separate Config and Agent panels - Rename sshKeysList to sshConfigKeysList for config-based keys - Add sshAgentKeysList for keys loaded in ssh-agent - Update TUI to support 3 panels: Servers, SSH Keys (Config), SSH Agent - Tab/Shift+Tab cycle through all 3 panels (0→1→2→0) - Update navigation (j/k) to work with all panels - Update mouse click handlers for all 3 panels - Update load/unload handlers to get key from correct panel - Refresh both key lists separately after load/unload - Right panel shows server details for panel 0, key details for panels 1-2 - Border colors highlight active panel feat: consolidate to 2-panel layout and add SSH key details to server panel - Remove SSH Keys (Config) panel, keeping only Servers and SSH Agent panels - Update panel navigation to support 2-panel layout (Tab/Shift+Tab cycling) - Remove GetKeychainServers() and all keychain virtual server code - Enhance server details to show SSH key information (path, type, size, status, commands) - Update ServerDetails to fetch and display key details for configured identity files This simplifies the UI by consolidating SSH key information directly into the server details panel, eliminating the need for a separate config keys panel. fix: use fingerprint-based removal for unloading SSH keys from agent - Change UnloadKeyFromAgent to accept fingerprint instead of keyPath - Use `ssh-add -d -E sha256 <fingerprint>` for reliable key removal - Keys loaded in ssh-agent may not have the original file path available - Strip SHA256:/MD5: prefix from fingerprint before passing to ssh-add - Update handler to pass key.Fingerprint instead of key.Path This fixes the "Failed to unload key: exit status 1" error that occurred when trying to remove keys from ssh-agent using file paths. fix: load/unload ssh-add logic feat(ui): display push remote URL in git info panel - Add GetPushRemoteURL service method to retrieve remote name and URL - Prefer "origin" remote, falling back to first available push remote - Update git info display to show formatted remote URL on first line - Add visual highlighting for remote name and URL - Enhance panel focus with selected background color changes feat(ssh): add key comment editing functionality Implement ability to edit SSH key comments directly from the UI using the Shift+C key binding. This allows users to update key comments stored in public key files without manual command-line operations. The feature includes: - New modal dialog for editing key comments with validation - Integration with GitService for comment updates via ssh-keygen - Automatic handling of file permissions for read-only keys - Support for both server keys and agent-loaded keys - Visual feedback showing the comment field in details panels This resolves issue Adembc#91 by providing a complete UI workflow for managing SSH key metadata. fix(ui): resolve thread safety issues in SSH key loading handlers - Remove unnecessary goroutines from handleLoadKey and handleLoadServerKey - Suspend is blocking, allowing synchronous execution without UI freezing - Fix potential race conditions by executing UI updates on main thread - Add tilde expansion in getSSHKeyForServer to match identity files with home directory paths - Update status bar help text to include comment editing shortcut fix(ssh): handle encrypted key passphrase prompts when editing comments - Add TUI suspension for encrypted SSH keys to allow passphrase input - Connect stdin/stdout/stderr to ssh-keygen command for interactive prompts - Improve encryption detection by checking for "bcrypt" cipher indicator - Propagate encryption and public key status when merging agent keys - Update help text formatting in server details view - Change warning icon for missing public keys
cdc8b4f to
fa46cf7
Compare
Author
|
@Adembc please review and approve |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Implement comprehensive SSH key management (issue #91) with a new 2-panel UI design, ssh-agent integration, and per-repository Git SSH configuration.
New Features
SSH Key Management Panel
2-Panel Layout
Git SSH Integration
Key Discovery
This addresses the common scenario of managing multiple SSH identities (company, personal, vendor accounts) by making it easy to configure which key Git should use for a specific repository. By controlling which SSH key is loaded into ssh-agent we also can control which SSH key will be used for git repository commits/push, in addition to hardcoded fix of the repository.