> **Foundation PRs:** #53732, #53733, #53734 — These three draft PRs contain the base refactors (retained workspaces, agent panel overlay split, ThreadId introduction) that this PR builds on. ## Goal Remove `DraftId` and merge `draft_threads` + `background_threads` into a single `retained_threads: HashMap<ThreadId, Entity<ConversationView>>` in `AgentPanel`. A draft is just a thread that hasn't sent its first message — no separate identity or storage needed. ## Changes ### agent_panel.rs - Remove `DraftId` / `DraftIdCounter` / the `Global` impl - Merge the two maps into `retained_threads` - Add `thread_id: ThreadId` field to `BaseView::AgentThread` - Rename methods: `create_draft` → `create_thread`, `activate_draft` → `activate_retained_thread`, `remove_draft` → `remove_thread`, etc. - Replace `clear_active_thread` with `show_or_create_empty_draft` - Update `update_thread_work_dirs` to sync `ThreadMetadataStore` paths when worktrees change - Keep `load_agent_thread(...)` cleanup so activating a real thread removes empty retained drafts ### sidebar.rs - Remove `active_entry` derivation from `rebuild_contents` (was racing with deferred effects) - Add `sync_active_entry_from_panel` called from event handlers instead - Simplify `ActiveEntry` — remove `ThreadActivation` struct, make `session_id` optional - Move `seen_thread_ids` to global scope (was per-group, causing duplicate thread entries) - Remove dead code: `clear_draft`, `render_draft_thread` - Generalize `pending_remote_thread_activation` into `pending_thread_activation` so all persisted-thread activations suppress fallback draft reconciliation - Set the activation guard before local persisted-thread activation switches workspaces - Make `reconcile_groups(...)` bail while a persisted-thread activation is in flight - On `ActiveViewChanged`, clear empty group drafts as soon as a pending persisted-thread activation resolves ### thread_metadata_store.rs - Make `ThreadMetadata.title` an `Option<SharedString>` with `display_title()` fallback - Add `update_worktree_paths` for batched path updates when project worktrees change ### Other crates - Update all `ThreadMetadata` construction sites and title display sites across `agent_ui` and `sidebar` ## Fallback draft invariant This PR now tightens the retained-thread invariant around fallback drafts vs real thread activation/restoration: - Fallback drafts are always empty - User-created drafts worth preserving are non-empty - While a persisted thread is being activated/restored/loaded, sidebar reconciliation must not create an empty fallback draft for that target group/workspace - Once the real thread becomes active, empty fallback drafts in that target group are removed This is enforced by the sidebar-side activation guard plus existing `AgentPanel` empty-draft cleanup after real-thread load. ## Tests Added and/or kept focused sidebar regression coverage for: - `test_confirm_on_historical_thread_in_new_project_group_opens_real_thread` - `test_unarchive_into_inactive_existing_workspace_does_not_leave_active_draft` - `test_unarchive_after_removing_parent_project_group_restores_real_thread` - `test_pending_thread_activation_suppresses_reconcile_draft_creation` Focused test runs: - `cargo test -p sidebar activate_archived_thread -- --nocapture` - `cargo test -p sidebar unarchive -- --nocapture` - `cargo test -p sidebar archive_last_thread_on_linked_worktree -- --nocapture` - `cargo test -p sidebar test_confirm_on_historical_thread_in_new_project_group_opens_real_thread -- --nocapture` - `cargo test -p sidebar test_unarchive_into_inactive_existing_workspace_does_not_leave_active_draft -- --nocapture` - `cargo test -p sidebar test_unarchive_after_removing_parent_project_group_restores_real_thread -- --nocapture` - `cargo test -p sidebar test_pending_thread_activation_suppresses_reconcile_draft_creation -- --nocapture` ## Test fix Fixed flaky `test_backfill_sets_kvp_flag` — added per-App `AppDatabase` isolation in `setup_backfill_test` so backfill tests no longer share a static in-memory DB. Release Notes: - N/A --------- Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com> Co-authored-by: Mikayla Maki <mikayla@zed.dev>
Zed
Welcome to Zed, a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.
Installation
On macOS, Linux, and Windows you can download Zed directly or install Zed via your local package manager (macOS/Linux/Windows).
Other platforms are not yet available:
- Web (tracking issue)
Developing Zed
Contributing
See CONTRIBUTING.md for ways you can contribute to Zed.
Also... we're hiring! Check out our jobs page for open roles.
Licensing
License information for third party dependencies must be correctly provided for CI to pass.
We use cargo-about to automatically comply with open source licenses. If CI is failing, check the following:
- Is it showing a
no license specifiederror for a crate you've created? If so, addpublish = falseunder[package]in your crate's Cargo.toml. - Is the error
failed to satisfy license requirementsfor a dependency? If so, first determine what license the project has and whether this system is sufficient to comply with this license's requirements. If you're unsure, ask a lawyer. Once you've verified that this system is acceptable add the license's SPDX identifier to theacceptedarray inscript/licenses/zed-licenses.toml. - Is
cargo-aboutunable to find the license for a dependency? If so, add a clarification field at the end ofscript/licenses/zed-licenses.toml, as specified in the cargo-about book.
Sponsorship
Zed is developed by Zed Industries, Inc., a for-profit company.
If you’d like to financially support the project, you can do so via GitHub Sponsors. Sponsorships go directly to Zed Industries and are used as general company revenue. There are no perks or entitlements associated with sponsorship.