Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,18 @@ final class PairingApprovalWindow {
}

/// Show the pairing approval prompt for a specific device.
/// If a window is already showing, it is closed first (one prompt at a time).
/// Closing the previous window sends a deny for the superseded request.
/// If a window is already showing for a different request, it is closed first
/// (one prompt at a time) and a deny is sent for the superseded request.
/// If the same pairingRequestId is delivered again (daemon retry/rebroadcast),
/// the existing prompt is kept as-is — no deny is sent.
func show(pairingRequestId: String, deviceName: String) {
// Same request ID redelivered (retry/rebroadcast) — keep current prompt.
if pairingRequestId == currentPairingRequestId, window != nil {
return
Comment on lines +26 to +27

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Refresh same-ID prompt when device identity changes

This early return can cause approvals to be applied to a different device than the one shown in the prompt: beginRequest rewrites hashedDeviceId and deviceName for an existing pairingRequestId on each retry (assistant/src/daemon/pairing-store.ts, lines 115-116), while this window now ignores same-ID rebroadcasts and keeps stale UI state. In the scenario where two devices (or one device with changed identity fields) reuse the same QR while the prompt is open, the user approves based on old text but the daemon approves the latest stored device for that ID.

Useful? React with 👍 / 👎.

}

// Close any existing prompt before showing a new one.
// This will send a deny for the previous request if unanswered.
// This will send a deny for the previous (different) request if unanswered.
close()

let view = PairingApprovalView(deviceName: deviceName) { [weak self] decision in
Expand Down