Link all threads on a worktree to the archived record, not just the last

Richard Feldman created

When the last thread on a worktree triggers archival, all threads
associated with that worktree (including previously archived ones)
are linked to the archived worktree record. This way any of them
can trigger a restore when unarchived, not just the last one.

Change summary

crates/agent_ui/src/thread_metadata_store.rs |  8 ++++++
crates/sidebar/src/sidebar.rs                | 28 +++++++++++++++++----
2 files changed, 30 insertions(+), 6 deletions(-)

Detailed changes

crates/agent_ui/src/thread_metadata_store.rs 🔗

@@ -241,6 +241,14 @@ impl ThreadMetadataStore {
         self.entries().filter(|t| t.archived)
     }
 
+    /// Returns all session IDs for the given path list, including archived threads.
+    pub fn all_session_ids_for_path(
+        &self,
+        path_list: &PathList,
+    ) -> impl Iterator<Item = &acp::SessionId> + '_ {
+        self.threads_by_paths.get(path_list).into_iter().flatten()
+    }
+
     /// Returns all threads for the given path list, excluding archived threads.
     pub fn entries_for_path(
         &self,

crates/sidebar/src/sidebar.rs 🔗

@@ -3317,12 +3317,28 @@ impl Sidebar {
 
             match create_result {
                 Ok(id) => {
-                    // Link the current thread to the archived worktree record.
-                    let link_result = store
-                        .update(cx, |store, cx| {
-                            store.link_thread_to_archived_worktree(session_id.0.to_string(), id, cx)
-                        })
-                        .await;
+                    // Link all threads on this worktree (including
+                    // previously archived ones) to the archived
+                    // worktree record so any of them can trigger a
+                    // restore later.
+                    let session_ids: Vec<String> = store.update(cx, |store, _cx| {
+                        store
+                            .all_session_ids_for_path(&folder_paths)
+                            .map(|s| s.0.to_string())
+                            .collect()
+                    });
+                    let mut link_result: anyhow::Result<()> = Ok(());
+                    for sid in session_ids {
+                        let result = store
+                            .update(cx, |store, cx| {
+                                store.link_thread_to_archived_worktree(sid, id, cx)
+                            })
+                            .await;
+                        if let Err(err) = result {
+                            link_result = Err(err);
+                            break;
+                        }
+                    }
 
                     if let Err(err) = link_result {
                         log::error!("Failed to link thread to archived worktree: {err}");