feat(ssh): prefill default private key#2200
Conversation
Greptile SummaryThis PR auto-fills the private key path field in the SSH connection modal by detecting the first readable default OpenSSH identity file (
Confidence Score: 4/5Safe to merge after adding an The main process logic and hook are solid. The only defect is in the modal: the async src/renderer/lib/components/add-ssh-conn-modal.tsx — the prefill
|
| Filename | Overview |
|---|---|
| src/main/core/ssh/controller.ts | Adds getDefaultPrivateKeyPath helper that iterates over OpenSSH default key filenames in priority order, checks readability with R_OK, and exposes the result via RPC. |
| src/renderer/lib/components/add-ssh-conn-modal.tsx | Adds prefill logic via a useEffect and handleAuthTypeChange; the effect lacks an isEditing guard, so it can silently overwrite the private-key field when editing a key-auth connection that has no saved path. |
| src/renderer/lib/hooks/use-ssh-config-hosts.ts | Adds useDefaultPrivateKeyPath hook with staleTime: Infinity, correctly avoiding unnecessary refetches for a filesystem value that is stable during a session. |
| src/renderer/lib/stores/ssh-connection-store.ts | Thin RPC delegation — adds getDefaultPrivateKeyPath() that forwards to rpc.ssh.getDefaultPrivateKeyPath(). |
Sequence Diagram
sequenceDiagram
participant Modal as AddSshConnModal
participant Hook as useDefaultPrivateKeyPath
participant Store as SshConnectionStore
participant RPC as rpc.ssh
participant Main as controller.ts (main)
participant FS as Filesystem (~/.ssh)
Modal->>Hook: mount / query
Hook->>Store: getDefaultPrivateKeyPath()
Store->>RPC: rpc.ssh.getDefaultPrivateKeyPath()
RPC->>Main: getDefaultPrivateKeyPath()
loop id_ed25519 → id_ecdsa → id_rsa → id_dsa
Main->>FS: "access(~/.ssh/<name>, R_OK)"
alt readable
FS-->>Main: ok
Main-->>RPC: "~/.ssh/<name>"
else not found / unreadable
FS-->>Main: error (continue)
end
end
Main-->>RPC: null (none found)
RPC-->>Store: "string | null"
Store-->>Hook: "string | null"
Hook-->>Modal: defaultPrivateKeyPathQuery.data
alt "authType === 'key' and privateKeyPath empty"
Modal->>Modal: setFieldValue('privateKeyPath', path)
end
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
src/renderer/lib/components/add-ssh-conn-modal.tsx:188-196
**Effect silently modifies `privateKeyPath` in edit mode**
When editing an existing connection that has `authType: 'key'` and no saved `privateKeyPath` (e.g. the field was left blank and persisted as `undefined`), the form initialises with `privateKeyPath: ''`. Once `defaultPrivateKeyPathQuery` resolves, every guard passes and the effect injects the default path — changing the connection's credentials without any user action. Adding `if (isEditing) return;` at the top of the effect prevents this. The `handleAuthTypeChange` path is fine because it only fires on an explicit user gesture.
Reviews (2): Last reviewed commit: "fix(ssh): refine default key prefill" | Re-trigger Greptile
summary