notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit 44233ecf9f1df49d19b76b95f2429b3b98183e34
parent 4c05d075ac1c0e6a7d51afd2e57760e3960f1784
Author: William Casarin <jb55@jb55.com>
Date:   Wed, 18 Feb 2026 10:04:09 -0800

refactor: unify permission publish data into PermissionPublish struct

Extract a shared PermissionPublish struct to replace the duplicated
{perm_id, allowed, message} fields across PermissionResponseResult,
UiActionResult, KeyActionResult, SendActionResult, and
PendingPermResponse. Handlers now return Option<PermissionPublish>,
making it impossible to forget relay publishing for new prompt types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Diffstat:
Mcrates/notedeck_dave/src/lib.rs | 45++++++++-------------------------------------
Mcrates/notedeck_dave/src/ui/mod.rs | 130++++++++++++-------------------------------------------------------------------
Mcrates/notedeck_dave/src/update.rs | 31+++++++++++++------------------
3 files changed, 40 insertions(+), 166 deletions(-)

diff --git a/crates/notedeck_dave/src/lib.rs b/crates/notedeck_dave/src/lib.rs @@ -137,7 +137,7 @@ pub struct Dave { session_state_sub: Option<nostrdb::Subscription>, /// Permission responses queued for relay publishing (from remote sessions). /// Built and published in the update loop where AppContext is available. - pending_perm_responses: Vec<PendingPermResponse>, + pending_perm_responses: Vec<PermissionPublish>, /// Sessions pending deletion state event publication. /// Populated in delete_session(), drained in the update loop where AppContext is available. pending_deletions: Vec<DeletedSessionInfo>, @@ -145,12 +145,7 @@ pub struct Dave { hostname: String, } -/// A permission response queued for relay publishing. -struct PendingPermResponse { - perm_id: uuid::Uuid, - allowed: bool, - message: Option<String>, -} +use update::PermissionPublish; /// Info captured from a session before deletion, for publishing a "deleted" state event. struct DeletedSessionInfo { @@ -1759,16 +1754,8 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr KeyActionResult::SetAutoSteal(new_state) => { self.auto_steal_focus = new_state; } - KeyActionResult::PublishPermissionResponse { - perm_id, - allowed, - message, - } => { - self.pending_perm_responses.push(PendingPermResponse { - perm_id, - allowed, - message, - }); + KeyActionResult::PublishPermissionResponse(publish) => { + self.pending_perm_responses.push(publish); } KeyActionResult::None => {} } @@ -1780,16 +1767,8 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr SendActionResult::SendMessage => { self.handle_user_send(ctx, ui); } - SendActionResult::NeedsRelayPublish { - perm_id, - allowed, - message, - } => { - self.pending_perm_responses.push(PendingPermResponse { - perm_id, - allowed, - message, - }); + SendActionResult::NeedsRelayPublish(publish) => { + self.pending_perm_responses.push(publish); } SendActionResult::Handled => {} } @@ -1815,16 +1794,8 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr self.handle_send_action(ctx, ui); None } - UiActionResult::PublishPermissionResponse { - perm_id, - allowed, - message, - } => { - self.pending_perm_responses.push(PendingPermResponse { - perm_id, - allowed, - message, - }); + UiActionResult::PublishPermissionResponse(publish) => { + self.pending_perm_responses.push(publish); None } UiActionResult::Handled => None, diff --git a/crates/notedeck_dave/src/ui/mod.rs b/crates/notedeck_dave/src/ui/mod.rs @@ -432,12 +432,8 @@ pub enum KeyActionResult { CloneAgent, DeleteSession(SessionId), SetAutoSteal(bool), - /// Permission response needs relay publishing (remote session). - PublishPermissionResponse { - perm_id: uuid::Uuid, - allowed: bool, - message: Option<String>, - }, + /// Permission response needs relay publishing. + PublishPermissionResponse(update::PermissionPublish), } /// Handle a keybinding action. @@ -465,17 +461,8 @@ pub fn handle_key_action( if let Some(session) = session_manager.get_active_mut() { session.focus_requested = true; } - if let update::PermissionResponseResult::NeedsRelayPublish { - perm_id, - allowed, - message, - } = result - { - return KeyActionResult::PublishPermissionResponse { - perm_id, - allowed, - message, - }; + if let Some(publish) = result { + return KeyActionResult::PublishPermissionResponse(publish); } } KeyActionResult::None @@ -492,17 +479,8 @@ pub fn handle_key_action( if let Some(session) = session_manager.get_active_mut() { session.focus_requested = true; } - if let update::PermissionResponseResult::NeedsRelayPublish { - perm_id, - allowed, - message, - } = result - { - return KeyActionResult::PublishPermissionResponse { - perm_id, - allowed, - message, - }; + if let Some(publish) = result { + return KeyActionResult::PublishPermissionResponse(publish); } } KeyActionResult::None @@ -591,12 +569,8 @@ pub enum SendActionResult { Handled, /// Normal send - caller should send the user message SendMessage, - /// Permission response needs relay publishing (remote session). - NeedsRelayPublish { - perm_id: uuid::Uuid, - allowed: bool, - message: Option<String>, - }, + /// Permission response needs relay publishing. + NeedsRelayPublish(update::PermissionPublish), } /// Handle the Send action, including tentative permission states. @@ -630,17 +604,8 @@ pub fn handle_send_action( request_id, PermissionResponse::Allow { message }, ); - if let update::PermissionResponseResult::NeedsRelayPublish { - perm_id, - allowed, - message, - } = result - { - return SendActionResult::NeedsRelayPublish { - perm_id, - allowed, - message, - }; + if let Some(publish) = result { + return SendActionResult::NeedsRelayPublish(publish); } } SendActionResult::Handled @@ -660,17 +625,8 @@ pub fn handle_send_action( request_id, PermissionResponse::Deny { reason }, ); - if let update::PermissionResponseResult::NeedsRelayPublish { - perm_id, - allowed, - message, - } = result - { - return SendActionResult::NeedsRelayPublish { - perm_id, - allowed, - message, - }; + if let Some(publish) = result { + return SendActionResult::NeedsRelayPublish(publish); } } SendActionResult::Handled @@ -687,12 +643,8 @@ pub enum UiActionResult { SendAction, /// Return an AppAction AppAction(notedeck::AppAction), - /// Permission response needs relay publishing (remote session). - PublishPermissionResponse { - perm_id: uuid::Uuid, - allowed: bool, - message: Option<String>, - }, + /// Permission response needs relay publishing. + PublishPermissionResponse(update::PermissionPublish), } /// Handle a UI action from DaveUi. @@ -725,23 +677,8 @@ pub fn handle_ui_action( DaveAction::PermissionResponse { request_id, response, - } => { - let result = update::handle_permission_response(session_manager, request_id, response); - if let update::PermissionResponseResult::NeedsRelayPublish { - perm_id, - allowed, - message, - } = result - { - UiActionResult::PublishPermissionResponse { - perm_id, - allowed, - message, - } - } else { - UiActionResult::Handled - } - } + } => update::handle_permission_response(session_manager, request_id, response) + .map_or(UiActionResult::Handled, UiActionResult::PublishPermissionResponse), DaveAction::Interrupt => { update::execute_interrupt(session_manager, backend, ctx); UiActionResult::Handled @@ -757,24 +694,8 @@ pub fn handle_ui_action( DaveAction::QuestionResponse { request_id, answers, - } => { - let result = - update::handle_question_response(session_manager, request_id, answers); - if let update::PermissionResponseResult::NeedsRelayPublish { - perm_id, - allowed, - message, - } = result - { - UiActionResult::PublishPermissionResponse { - perm_id, - allowed, - message, - } - } else { - UiActionResult::Handled - } - } + } => update::handle_question_response(session_manager, request_id, answers) + .map_or(UiActionResult::Handled, UiActionResult::PublishPermissionResponse), DaveAction::ExitPlanMode { request_id, approved, @@ -795,20 +716,7 @@ pub fn handle_ui_action( }, ) }; - if let update::PermissionResponseResult::NeedsRelayPublish { - perm_id, - allowed, - message, - } = result - { - UiActionResult::PublishPermissionResponse { - perm_id, - allowed, - message, - } - } else { - UiActionResult::Handled - } + result.map_or(UiActionResult::Handled, UiActionResult::PublishPermissionResponse) } } } diff --git a/crates/notedeck_dave/src/update.rs b/crates/notedeck_dave/src/update.rs @@ -185,16 +185,11 @@ pub fn has_pending_exit_plan_mode(session_manager: &SessionManager) -> bool { pending_permission_tool_name(session_manager) == Some("ExitPlanMode") } -/// Result of handling a permission response. -pub enum PermissionResponseResult { - /// Handled locally (oneshot sent to Claude process). - Local, - /// Needs relay publishing (remote session, no local process). - NeedsRelayPublish { - perm_id: uuid::Uuid, - allowed: bool, - message: Option<String>, - }, +/// Data needed to publish a permission response to relays. +pub struct PermissionPublish { + pub perm_id: uuid::Uuid, + pub allowed: bool, + pub message: Option<String>, } /// Handle a permission response (from UI button or keybinding). @@ -202,9 +197,9 @@ pub fn handle_permission_response( session_manager: &mut SessionManager, request_id: uuid::Uuid, response: PermissionResponse, -) -> PermissionResponseResult { +) -> Option<PermissionPublish> { let Some(session) = session_manager.get_active_mut() else { - return PermissionResponseResult::Local; + return None; }; let is_remote = session.is_remote(); @@ -264,11 +259,11 @@ pub fn handle_permission_response( } } - PermissionResponseResult::NeedsRelayPublish { + Some(PermissionPublish { perm_id: request_id, allowed, message, - } + }) } /// Handle a user's response to an AskUserQuestion tool call. @@ -276,9 +271,9 @@ pub fn handle_question_response( session_manager: &mut SessionManager, request_id: uuid::Uuid, answers: Vec<QuestionAnswer>, -) -> PermissionResponseResult { +) -> Option<PermissionPublish> { let Some(session) = session_manager.get_active_mut() else { - return PermissionResponseResult::Local; + return None; }; let is_remote = session.is_remote(); @@ -401,11 +396,11 @@ pub fn handle_question_response( } } - PermissionResponseResult::NeedsRelayPublish { + Some(PermissionPublish { perm_id: request_id, allowed: true, message: Some(formatted_response), - } + }) } // =============================================================================