Skip to content
Merged
Show file tree
Hide file tree
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
16 changes: 0 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions RECAPS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,58 @@ Running log of completed work sessions, newest first. Each entry summarizes a co

---

## 2026-05-24

### PR #41 + workspace surgical rip of AutoWatch / ScreenShare / video-track plumbing
- Opened PR #41 (`rip-collab-livekit`) covering the 6 commits from the 2026-05-23 session that unwired `collab_ui`, `notifications`, `title_bar`, `file_finder`, and `git_ui` from the paddleboard binary. Net -1,549 lines across 20 files.
- **Workspace surgical rip (commit `7835e92d5b`):** With `collab_ui` unlinked from the binary, the workspace.rs screen-sharing surface was now self-contained. Removed:
- `AutoWatch` enum + impl, `auto_watch` field on `Workspace`, all auto-watch methods (`toggle_auto_watch`, `handle_auto_watch_video_tracks_changed`, `handle_auto_watch_local_share_stopped`, `next_watched_peer`, `auto_watch_state`).
- `open_shared_screen`, `shared_screen_for_peer` methods.
- `ScreenShare` action from the `collab` namespace actions macro.
- `is_sharing_screen`, `create_shared_screen`, `peer_ids_with_video_tracks` from the `AnyActiveCall` trait definition.
- `RemoteVideoTracksChanged`, `LocalScreenShareStarted`, `LocalScreenShareStopped` variants from `ActiveCallEvent`.
- Matching trait impl methods and event-mapping arms in `crates/call/src/call_impl/mod.rs` (~110 LOC including the `create_shared_screen` impl with its livekit `RemoteVideoTrackView` construction).
- `AutoWatchFeatureFlag` from `crates/feature_flags/src/flags.rs` (only consumer was the already-unlinked `collab_ui`).
- Cleaned unused imports (`AnyView`, `Pane`, `SharedScreen`) from call_impl.
- **Intentionally preserved:** `shared_screen.rs` module and its `pub use` re-export in workspace.rs (harmless, and removing it is a separate concern). The `follower_states` / leader-following protocol, `WorkspaceStore`'s follow/update_followers handlers, `call::init` wiring, and the `collab`/`livekit`/`call` crates themselves — all still have intra-workspace or cross-crate consumers. The `pub use livekit_client::{RemoteVideoTrack, ...}` re-exports in call_impl stayed (no external consumers, but they're re-exports from a crate we haven't ripped yet).
- **Verified:** `cargo check -p paddleboard -p call -p workspace -p feature_flags` clean. `./script/clippy -p paddleboard -p call -p workspace -p feature_flags` (release, all targets, deny warnings) clean. Net -279 lines across 3 files.
- **Open follow-ups:**
- **Follower protocol rip.** `follower_states`, `last_leaders_by_pane`, `leader_updates_tx`, `_apply_leader_updates`, the entire leader/follower negotiation (`start_following`, `follow_next_collaborator`, `unfollow`, `leader_updated`, `update_followers`, etc.), `WorkspaceStore`'s `handle_follow`/`handle_update_followers` request handlers. This is the heaviest remaining workspace.rs surgery (~500+ LOC).
- **`call::init` unwiring.** Still wired at boot in `main.rs` and `zed.rs`. Prerequisite: rip the follower protocol first (it calls `GlobalAnyActiveCall::try_global`).
- **`collab_ui` crate deletion.** Directory + workspace member entry — trivial once the above are done.
- **`collab` / `livekit_*` / `call` crate deletion.** Biggest swing, deferred until the protocol is fully excised from workspace.
- **`shared_screen.rs` module removal.** Can be done any time after `create_shared_screen` is gone from call_impl (already done this session) — just needs the `pub mod` + `pub use` lines dropped from workspace.rs.
- **Namespace allowlist tuning.** `zed.rs` keybind validation still expects `collab_panel` / `channel_modal` / `collab` namespaces — tied to action-definition deletions.

---

## 2026-05-23

### Unwire collab_ui from the paddleboard binary
- Continuation of the `rip-collab-livekit` branch. Previous commits stripped per-surface consumers (`title_bar`, `file_finder`, `notifications`, `git_ui`); this session targeted the next layer: the `collab_ui` crate itself. Resumed from a session that had been cut off mid-flight — only artifact in the worktree was a one-line stale doc-comment removal in `workspace.rs:8150` referring to `call::RemoteParticipant`.
- **Initial plan was wrong, course-corrected.** First attempt was "surgical inside workspace.rs only" — strip `AutoWatch` / `open_shared_screen` / `shared_screen_for_peer` / `ScreenShare` action / `LocalScreenShare*` & `RemoteVideoTracksChanged` event arms + the matching `AnyActiveCall` trait methods. Audit revealed those all still have live external consumers in `collab_ui::collab_panel` (3 sites: `auto_watch_state()`, `toggle_auto_watch`, `open_shared_screen`) plus the `collab/tests/integration/auto_watch_tests.rs` and `following_tests.rs` test files. And `collab_ui::init` was still being called at boot from `paddleboard/src/main.rs:783` and `crates/paddleboard/src/zed.rs:5514`, with `CollabPanel::load` registering the panel in `paddleboard/src/zed.rs:736`. So `workspace.rs` looked dead but actually had compile-time consumers ghost-pinning it. Re-scoped to unwire `collab_ui` first; the workspace surgery becomes truly self-contained in a follow-up.
- **What landed (commit `ef44a0298c`):**
- Dropped `collab_ui.workspace = true` from `crates/paddleboard/Cargo.toml`.
- `main.rs`: removed `use collab_ui::channel_view::ChannelView;`, the `collab_ui::init(&app_state, cx);` boot line, and the entire ~60-line `if !request.open_channel_notes.is_empty() || request.join_channel.is_some() { ... }` block that handled zed:// channel URLs via `workspace::join_channel` and `ChannelView::open`. Simplified the trailing `else if let Some(task) = task` to `if let Some(task) = task`.
- `zed.rs`: removed `collab_ui::collab_panel::CollabPanel::load(...)` from `initialize_panels` (and its `channels_panel` slot in the `futures::join!`), the `ToggleFocus` `register_action` block at line 1199, and the test-bootstrap `collab_ui::init(&app_state, cx);` at line 5514.
- `zed/app_menus.rs`: dropped `use collab_ui::collab_panel;` and the `MenuItem::action("Collab Panel", collab_panel::ToggleFocus)` entry in View.
- `zed/open_listener.rs`: dropped the `ZedLink` / `parse_zed_link` import, the `open_channel_notes` and `join_channel` fields on `OpenRequest` (and their checks in `is_focus_app_only`), and the whole `else if let Some(zed_link) = parse_zed_link(&url, cx)` URL arm. zed:// channel URLs now fall through to the existing "unhandled url" log.
- Cleaned two `notifications::init(...)` calls in `main.rs:782` and `zed.rs:5498` that were already broken (function was deleted in commit `9099e043e4`) — apparently nothing built end-to-end since that commit landed, or the failures were ignored.
- Bonus cleanup: removed `maybe` from the `use util::{ResultExt, TryFutureExt, maybe};` import (no longer used) and then `TryFutureExt` (also unused after the channel block went).
- Kept the stale doc-comment removal in `workspace.rs:8150` rolled into the same commit since it points at the same surface being torn out.
- **Intentionally preserved:**
- The `collab_ui` crate itself stays in the workspace tree. It already had pre-existing compile errors (unresolved `notifications::Notification*` imports from the prior NotificationStore deletion, missing `title_bar::collab` after the title-bar strip, and four `u64` deref errors); none of those are my problem to fix here. Crate-level deletion is the natural next step after the workspace.rs surgery, not before.
- Workspace's `AnyActiveCall` trait, `GlobalAnyActiveCall`, `ActiveCallEvent` enum, `RemoteCollaborator` struct, the entire `follower_states` + leader-following protocol, `WorkspaceStore`'s `handle_follow` / `handle_update_followers` request handlers, the `join_channel` / `join_channel_internal` / `get_any_active_multi_workspace` flow, `prepare_to_close`'s "leave the call" prompt, and the namespace allowlist entries for `channel_modal` / `collab_panel` / `collab` in `zed.rs` keybind validation. All of these still have either intra-`workspace.rs` consumers or live `call` / `channel` crate consumers (`call::init` is still wired at boot at `main.rs:781` and `zed.rs:5497`). Leaving them costs nothing and gives the next commit a coherent rip target.
- `parse_zed_link` import in `main.rs` — still used at line 2005 by `parse_url_arg` to test which CLI args are URL-shaped.
- **Verified:** `cargo check -p paddleboard` clean (only inactive-code diagnostics from cross-platform `#[cfg]` blocks, no errors). `./script/clippy -p paddleboard` (release, all targets, deny warnings) clean — no warnings, `cargo-machete` happy. Did not run the full workspace check (`cargo check --workspace` would still fail on `collab_ui` and `collab` test files, which are now expected and unblocking).
- **Open follow-ups:**
- **workspace.rs surgical rip is now possible.** With `collab_ui` un-linked, `AutoWatch` / `auto_watch_state` / `toggle_auto_watch` / `open_shared_screen` / `shared_screen_for_peer` / `next_watched_peer` / `handle_auto_watch_*` / `ScreenShare` action / `LocalScreenShare*` & `RemoteVideoTracksChanged` event variants + the 3 trait methods only they used (`create_shared_screen`, `peer_ids_with_video_tracks`, `is_sharing_screen`) can come out in one commit. The matching `impl AnyActiveCall for ActiveCallEntity` methods in `crates/call/src/call_impl/mod.rs:67+` need to be trimmed in lockstep to keep that crate building.
- **collab_ui crate deletion.** The crate is unreferenced; ripping the directory + its workspace member entry is a tight follow-up after the workspace.rs cut.
- **collab / livekit / call crate deletion.** Bigger swing — `call::init` is still wired and `WorkspaceStore`'s `update_followers` calls `GlobalAnyActiveCall::try_global`. Order: rip workspace's follower protocol → rip `call` crate → rip `livekit` deps → rip `collab` tests.
- **Namespace allowlist tuning.** `zed.rs:5259/5263` keybind validation still expects `channel_modal` and `collab_panel` namespaces. Removing them when those actions stop being declared is a one-line touch but tied to the action-definition deletions in `workspace.rs`.

---

## 2026-05-22

### Auto-update: stop pointing remaining zed.dev surfaces at Zed
Expand Down
117 changes: 4 additions & 113 deletions crates/call/src/call_impl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ use client::{ChannelId, Client, TypedEnvelope, User, UserStore, PADDLEBOARD_ALWA
use collections::HashSet;
use futures::{Future, FutureExt, channel::oneshot, future::Shared};
use gpui::{
AnyView, App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, Subscription, Task,
TaskExt, WeakEntity, Window,
App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, Subscription, Task, TaskExt,
WeakEntity, Window,
};
use postage::watch;
use project::Project;
use room::Event;
use settings::Settings;
use std::sync::Arc;
use workspace::{
ActiveCallEvent, AnyActiveCall, GlobalAnyActiveCall, MultiWorkspace, MultiWorkspaceEvent, Pane,
RemoteCollaborator, SharedScreen, Workspace,
ActiveCallEvent, AnyActiveCall, GlobalAnyActiveCall, MultiWorkspace, MultiWorkspaceEvent,
RemoteCollaborator, Workspace,
};

pub use livekit_client::{RemoteVideoTrack, RemoteVideoTrackView, RemoteVideoTrackViewEvent};
Expand Down Expand Up @@ -112,13 +112,6 @@ impl AnyActiveCall for ActiveCallEntity {
.map_or(false, |room| room.read(cx).is_sharing_project())
}

fn is_sharing_screen(&self, cx: &App) -> bool {
self.0
.read(cx)
.room()
.map_or(false, |room| room.read(cx).is_sharing_screen())
}

fn has_remote_participants(&self, cx: &App) -> bool {
self.0.read(cx).room().map_or(false, |room| {
!room.read(cx).remote_participants().is_empty()
Expand Down Expand Up @@ -211,17 +204,6 @@ impl AnyActiveCall for ActiveCallEntity {
participant_id: *participant_id,
})
}
room::Event::RemoteVideoTracksChanged { participant_id } => {
Some(ActiveCallEvent::RemoteVideoTracksChanged {
participant_id: *participant_id,
})
}
room::Event::LocalScreenShareStarted => {
Some(ActiveCallEvent::LocalScreenShareStarted)
}
room::Event::LocalScreenShareStopped => {
Some(ActiveCallEvent::LocalScreenShareStopped)
}
_ => None,
};
if let Some(event) = mapped {
Expand All @@ -231,97 +213,6 @@ impl AnyActiveCall for ActiveCallEntity {
)
}

fn create_shared_screen(
&self,
peer_id: client::proto::PeerId,
pane: &Entity<Pane>,
window: &mut Window,
cx: &mut App,
) -> Option<Entity<workspace::SharedScreen>> {
let room = self.0.read(cx).room()?.clone();
let participant = room.read(cx).remote_participant_for_peer_id(peer_id)?;
let track = participant.video_tracks.values().next()?.clone();
let user = participant.user.clone();

for item in pane.read(cx).items_of_type::<SharedScreen>() {
if item.read(cx).peer_id == peer_id {
return Some(item);
}
}

Some(cx.new(|cx: &mut Context<SharedScreen>| {
let my_sid = track.sid();
cx.subscribe(
&room,
move |_: &mut SharedScreen,
_: Entity<Room>,
ev: &room::Event,
cx: &mut Context<SharedScreen>| {
if let room::Event::RemoteVideoTrackUnsubscribed { sid } = ev
&& *sid == my_sid
{
cx.emit(workspace::shared_screen::Event::Close);
}
},
)
.detach();

cx.observe_release(
&room,
|_: &mut SharedScreen, _: &mut Room, cx: &mut Context<SharedScreen>| {
cx.emit(workspace::shared_screen::Event::Close);
},
)
.detach();

let view = cx.new(|cx| RemoteVideoTrackView::new(track.clone(), window, cx));
cx.subscribe(
&view,
|_: &mut SharedScreen,
_: Entity<RemoteVideoTrackView>,
ev: &RemoteVideoTrackViewEvent,
cx: &mut Context<SharedScreen>| match ev {
RemoteVideoTrackViewEvent::Close => {
cx.emit(workspace::shared_screen::Event::Close);
}
},
)
.detach();

pub(super) fn clone_remote_video_track_view(
view: &AnyView,
window: &mut Window,
cx: &mut App,
) -> AnyView {
let view = view
.clone()
.downcast::<RemoteVideoTrackView>()
.expect("SharedScreen view must be a RemoteVideoTrackView");
let cloned = view.update(cx, |view, cx| view.clone(window, cx));
AnyView::from(cloned)
}

SharedScreen::new(
peer_id,
user,
AnyView::from(view),
clone_remote_video_track_view,
cx,
)
}))
}

fn peer_ids_with_video_tracks(&self, cx: &App) -> Vec<proto::PeerId> {
let Some(room) = self.0.read(cx).room() else {
return Vec::new();
};
room.read(cx)
.remote_participants()
.values()
.filter(|p| p.has_video_tracks())
.map(|p| p.peer_id)
.collect()
}
}

pub struct OneAtATime {
Expand Down
8 changes: 0 additions & 8 deletions crates/feature_flags/src/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,6 @@ impl FeatureFlag for AgentThreadWorktreeLabelFlag {
}
register_feature_flag!(AgentThreadWorktreeLabelFlag);

pub struct AutoWatchFeatureFlag;

impl FeatureFlag for AutoWatchFeatureFlag {
const NAME: &'static str = "auto-watch-screens";
type Value = PresenceFlag;
}
register_feature_flag!(AutoWatchFeatureFlag);

pub struct SkillsFeatureFlag;

impl FeatureFlag for SkillsFeatureFlag {
Expand Down
3 changes: 0 additions & 3 deletions crates/file_finder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,10 @@ doctest = false

[dependencies]
anyhow.workspace = true
channel.workspace = true
client.workspace = true
collections.workspace = true
editor.workspace = true
file_icons.workspace = true
futures.workspace = true
fuzzy.workspace = true
fuzzy_nucleo.workspace = true
gpui.workspace = true
language.workspace = true
Expand Down
Loading
Loading