gpui: Make deactivate_window panic when the window is not active - #6
Closed
butvinm wants to merge 77 commits into
Closed
gpui: Make deactivate_window panic when the window is not active#6butvinm wants to merge 77 commits into
butvinm wants to merge 77 commits into
Conversation
butvinm
force-pushed
the
guard-vacuous-deactivation
branch
from
August 5, 2026 00:38
48e0346 to
2a1fb35
Compare
butvinm
force-pushed
the
guard-vacuous-deactivation
branch
from
August 8, 2026 23:58
2a1fb35 to
27b3b55
Compare
…s#62367) # Objective The `gpui::img` element always overrides the `aspect_ratio` field, so if you have an image element that applies its own `.aspect_ratio()` it just gets wiped out. ## Solution Only apply the aspect ratio default if one is not already set. ## Testing It's a very minor change but I did add a small test to ensure it actually gets overridden. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase This came from an issue where vertical images inside an element (square in this case, as you'd see in an image gallery) do not behave correctly with `object_fit` values of `ObjectFit::Contain` or `ObjectFit::ScaleDown`. This was simply because despite the image element having a fixed square size (`img().size(px(200.))`), the aspect ratio would be forced to the ratio of the image itself, so vertical images weren't being properly fitted into their containers. Minimal repro for that issue: https://github.com/zaknesler/gpui-object-fit So with this change, you can set `.aspect_square()` and the object fit will behave as you'd expect: <img width="1237" height="986" alt="image" src="https://github.com/user-attachments/assets/5b1045a8-bd71-4b77-8bbd-c3b12112bcb0" /> --- Release Notes: - gpui: Fix image element's aspect ratio overriding existing value
…ck (zed-industries#61187) Follow-up to zed-industries#59838, implementing what was discussed at the end of zed-industries#59829: cmd-click navigation now respects `lsp_results_location` when go-to-definition falls back to find-all-references (invited in zed-industries#59829 (comment): "It would! Feel free to hook that up if you'd like to!"). ## Problem Cmd-clicking a symbol's definition falls back to find-all-references, but the results always open in a multibuffer even with `"lsp_results_location": "picker"`. The hover-link click path calls the editor navigation methods directly, so the action handlers registered by `lsp_locations` never get a chance to intercept. ## Solution - `handle_click_hovered_link`'s fallback now dispatches the `FindAllReferences` action (with `open_results_in: None`, deferring to the global setting) instead of calling the method, so the `lsp_locations` handler can intercept it, or propagate to the editor's built-in handler when the setting is `multi_buffer`, preserving today's behavior exactly. - The plain cmd-click arm of `cmd_click_reveal_task` now runs the definition query via `go_to_definition_of_kind` (no internal references fallback) instead of `go_to_definition`, so the click path has a single fallback decision point: the dispatching one. Without this, the method's baked-in fallback opened a multibuffer before the dispatch could run. - `go_to_definition_of_kind` visibility widened to `pub(crate)` for the call from `hover_links.rs`. Shift/alt click variants (type definition, splits) are untouched. Keyboard invocations were already intercepted and are unchanged. ## Testing - New test `test_cmd_click_fallback_honors_lsp_results_location` in `lsp_locations`, following the module's existing test patterns: fake LSP returning no definition and two references, `lsp_results_location: picker`, simulated cmd-click at the cursor's pixel position, asserts the picker opens. The test fails without this change. - `cargo nextest run -p lsp_locations`: 6/6. - `cargo nextest run -p editor -E 'test(hover) or test(fallback) or test(go_to_definition) or test(references)'`: 54/54. - `cargo fmt` and `./script/clippy` clean. - Verified manually in a release build: with the setting on, cmd-clicking a definition opens the picker; with it off, behavior is unchanged. Per the contributing guidelines' note on AI assistance: this change was developed with heavy AI assistance (Claude Code). I have reviewed and understand the full diff and the reasoning behind each hunk, and I'm the one answering review feedback. Release Notes: - Fixed cmd-click go-to-definition falling back to a references multibuffer even when `lsp_results_location` is set to `picker`.
Release Notes: - N/A
We added one more custom repository role that a Guild member can hold, therefore we need the labeler to accept it. Release Notes: - N/A
…closed (zed-industries#61467)" (zed-industries#62399) This reverts commit 6297c88. --- fixes zed-industries#62286 fixes zed-industries#62095 zed-industries#61467 fixed its intended bug, but at the same time introduced an issue where running tasks that would cause new tasks to be terminated immediately. zed-industries#62322 tried to fix that forward, but was unsuccessful. In the mean-time I am going to revert the original PR. We can try to re-land the original bugfix in a future PR. Release Notes: - N/A
Recommends GPT-5.6 Sol for both OpenAI BYOK and OpenAI subscription. Also unifies the naming so that we use the same OpenAI model names for the Zed/OpenAI BYOK and OpenAI subscription providers. Release Notes: - N/A
Now, this is one of these beautiful cases where GitHubs API ist just so pleasant to work with: Because PRs are treated as issues, assigning an assignee to a PR suddenly requires issue write permissions, despite the issue in question being a PR. Not having that permission resulted in some missing assignees on zed zippy bumps and failures of the workflows as seen in https://github.com/zed-industries/zed/actions/runs/31339736929/job/93311493258. In comparison, labelling PRs requires PR write permissions as seen in zed-industries#61525 🤡 Beautiful API and a pleasure to work with, 10/10 would recommend. Release Notes: - N/A
…stries#62294) # Objective Ensure that, when users undo project panel operations, we don't trash files with unsaved edits as that could lead to data loss, as outlined [here](zed-industries#62243 (comment)). Closes zed-industries#62243 ## Solution Update `UndoManager::trash` to require confirmation before moving files to the trash. For files with unsaved edits, users can save, discard, or cancel the operation while clean files receive a standard trash confirmation, same as shown when trashing a file through the Project Panel. This helps avoid the issue where, if an user undoes a file creation for a file that has unsaved edits and then quits Zed, the edits that were saved in memory, as well as the Project Panel history, will now be gone and there's no way to recover the data. Batch operations have also been updated to now show a single confirmation before making filesystem changes, preventing partial execution when cancelled and warning about unsaved edits. Lastly, the trash/delete prompt building has been refactored in order for the Project Panel and Undo Manager to share the same wording, file-list truncation, and unsaved-change warnings. ## Testing Tested both manually as well as added the following tests: * `project_panel::tests::undo::undo_create_cancel_trash` * `project_panel::tests::undo::undo_create_dirty_file` * `project_panel::tests::undo::cancel_partial_trash_batch` * `project_panel::tests::undo::batch_trash_warns_about_unsaved_changes` ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [ ] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase The screen recording below shows the trash confirmation dialog on both a clean and dirty files, on both undo and redo flows. https://github.com/user-attachments/assets/0f9b96f5-0357-4e3f-8ec2-141486942c89 --- Release Notes: - Fixed issue with undoing or redoing project panel operations that could lead to a file with unsaved edits being trashed without confirmation.
# Objective Zed's Markdown parser accepts tilde-fenced code blocks, but Mermaid extraction only strips backtick fences. As a result, a block like this is parsed as Mermaid while the fence itself is still passed to the renderer: ```markdown ~~~mermaid graph TD; ~~~ ``` ## Solution Teach the Markdown code-block helpers to recognize triple-tilde fences alongside triple-backtick fences. The change stays in the existing parsing path, so Mermaid rendering does not need a separate special case. A regression test covers extraction from a tilde-fenced Mermaid block. ## Testing - `cargo fmt --all -- --check` - `cargo test -p markdown` (138 tests) - `./script/clippy -p markdown` - `cargo build -p zed` - Opened a `~~~mermaid` block in the built Zed Dev app on macOS and verified that Markdown Preview renders the diagram ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Fixed Mermaid diagrams in Markdown previews when they use triple-tilde fences. --------- Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Closes zed-industries#61208 Before, Zed showed no toasts on startup when tasks.json contained malformed entries, also if there were two top-level arrays, the last one was silently discarded without any toasts too. The PR fixes both. Release Notes: - Fixed error toast not showing for malformed tasks.json
> “Smart quotes” are the ideal form of quotation marks and apostrophes, and are commonly curly or sloped. "Dumb quotes," or straight quotes, are a vestigial constraint from typewriters when using one key for two different marks helped save space on a keyboard. Also helps us be consistent. I’m going to make a PR to our marketing site to fix these issues as well, to bring further consistency to our copy (docs / marketing / otherwise). Starting with v0.5.0 and up, [`smart-punctuation`](https://github.com/rust-lang/mdBook/blob/6bf7fadc295a862f1f4b2f2d4a9c4c0b1e998dff/CHANGELOG.md#config-changes) is enabled by default, so we just need this temporarily. Good read: https://smartquotesforsmartpeople.com/ --- Release Notes: - N/A
While working on the project search on type PR and testing it, uncovered this bug and split off into a separate commit Release Notes: - N/A
…ed-industries#61871) GPUI's input-latency histograms only sample frames that were preceded by input, so a window that janks while animating or while streaming content (agent panel output, terminal scrollback) never shows up in the fleet's latency reports. Hang detection catches outright stalls, but frames that are merely late — stutters in the 30–100ms range during animation — currently aren't visible anywhere. This adds a `frame-duration-histogram` feature to GPUI with a per-window tracker recording two histograms: the duration of every `Window::draw`, and the interval between consecutively presented frames while the window is animating (a next-frame callback was already scheduled at the previous present, so frames are being produced back-to-back and a stretched interval means frames were missed). Intervals are only recorded for active windows, since inactive windows are deliberately throttled to a lower frame rate, and re-presents of unchanged frames (e.g. sustaining the display's refresh rate during high-rate input) are excluded. Zed enables the feature and reports both histograms every five minutes as a "Frame Duration Report" telemetry event alongside the existing "Latency Report", bucketed at roughly the 120Hz/60Hz/30Hz frame budgets so dropped-frame rates can be aggregated across the fleet. Release Notes: - Added frame rendering performance to the diagnostics Zed collects when telemetry is enabled, to help find and fix stutters and dropped frames.
The hosted-model reference now includes Claude Opus 5. This closes the gap between the public documentation and the models that `cloud` currently offers to Zed Pro and Zed Business customers. The pricing table lists the provider price and Zed price for input, output, cache-write, and cache-read tokens. The context-window table lists the current 1M-token hosted limit. This change does not alter model access or billing behavior. Testing performed: - `cd docs && npx prettier --check src/account/zed-hosted-models.md` - `cd docs && mdbook build` Release Notes: - N/A
…62352) # Objective When developing remotely, when I close the uncommitted changes tab, I need some time to load before I can copy the path. Or have to switch to the project panel to find the specific file. All of this is annoying, so I added a copy path action to the git panel's context menu and key bindings consistent with the project panel. ## Solution Already described in the Objective section. ## Testing I wrote a unit test and tested it manually. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase <img width="411" height="535" alt="showcase" src="https://github.com/user-attachments/assets/a17e7633-eb92-4737-aa30-958fe58bb99f" /> <img width="717" height="427" alt="showcase" src="https://github.com/user-attachments/assets/d067e892-17de-4527-ac20-16cad6f38015" /> --- Release Notes: - Added "Copy Path" and "Copy Relative Path" actions to the Git Panel's context menu
# Objective - Make Git Panel grouping sections collapsible so users can hide sections they are not currently interested in. - Support collapsible sections when grouping changes by tracking and by staging. - Provide a clear visual indicator showing whether each section is expanded or collapsed. ## Solution - Added per-section collapsed state to the Git Panel. - Made grouping headers clickable to toggle their section between expanded and collapsed. - Added chevron indicators that point down when expanded and right when collapsed. - Applied the behavior to both flat and tree views. - Kept the stage/unstage checkbox independent from the header collapse interaction. - Ensured a previously collapsed Tracked section does not hide files after switching to Group by None. ## Testing - Ran `rustfmt --edition 2024 crates/git_ui/src/git_panel.rs --check`. - Ran `cargo check -p git_ui`. - Ran `cargo test -p git_ui`: - 129 tests passed - 0 tests failed - Ran `git diff --check`. - Attempted `./script/clippy -p git_ui` twice. It produced no lint diagnostics but did not finish compiling the release, all-targets, all-features dependency graph within the available timeout. - Manually verify by selecting both grouping modes in the Git Panel and clicking each section header in flat and tree views. Confirm that: - The section contents are hidden and restored. - The chevron updates to reflect the current state. - Clicking the stage/unstage checkbox does not collapse the section. - Switching to Group by None does not leave tracked files hidden. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase https://github.com/user-attachments/assets/77ec4c88-4a6d-4e49-ac9f-ddbf80e724ca --- Release Notes: - Improved Git Panel organization by allowing grouped change sections to be collapsed
Show a modal when invoking the stash action to allow users to provide an optional custom message for the stash entry. Closes zed-industries#62430 # Image <img width="1622" height="1106" alt="Screenshot 2026-08-10 at 9 14 00 PM" src="https://github.com/user-attachments/assets/0d26dac2-919d-4bb1-b6a7-433ceff18955" /> <img width="1622" height="1106" alt="Screenshot 2026-08-10 at 9 14 11 PM" src="https://github.com/user-attachments/assets/896b68ff-999f-4ec9-a6a4-e0e7a6867286" /> # Objective Zed's stash action runs `git stash push --quiet --include-untracked --` with no `-m`, so every stash is labelled with git's auto-generated `WIP on <branch>: <sha> <subject>`. That text describes the commit you were sitting on, not what you stashed — so two stashes taken from the same commit are indistinguishable. This undercuts the stash picker (`git::ViewStash`), which lists entries as `#<index>: <message>` and fuzzy-searches over exactly that string. The search box already exists; there is just nothing meaningful to search, because every candidate is a variation of the same auto-generated line. ## Solution `git::StashAll` now opens a single-line modal ("Optionally provide a stash message") before stashing. - Confirming with text passes `--message <text>` to `git stash push`. - Confirming with the field empty omits the flag entirely, keeping git's default description — so the prompt is a one-keystroke pass-through and existing muscle memory still works. - Cancelling aborts the stash, so the prompt doubles as a confirmation step. Implementation: - `StashMessageModal` (`Editor::single_line`) in `git_panel.rs`, toggled from `GitPanel::stash_all`. `menu::Confirm` trims the input and maps empty to `None`. - `message: Option<String>` threaded through `Repository::stash_all` → `stash_entries` → `GitRepository::stash_paths`. The flag is appended before the `--` separator so a message is never parsed as a pathspec. - New `message` field on the `Stash` proto message, so remote and collab projects behave identically. One non-obvious detail: the modal is opened via `cx.defer_in` rather than inline. `git::StashAll` is registered on the workspace (`git_ui.rs`) as well as on the panel element, and `Workspace::register_action` dispatches while `Workspace` is leased — so opening the modal inline re-enters that update and hits GPUI's `double_lease_panic`. This only reproduces when focus is *outside* the Git Panel, which makes it easy to miss. `Option<String>` rather than `String` is deliberate: `--message ""` produces a blank stash description, which is strictly worse than git's default. ## Testing Manually verified the modal in a local build on macOS: the prompt appears on `git::StashAll`, accepts a message, and the named entry shows up in the stash picker. Also verified at the git level by replaying the exact argument vector `stash_paths` builds against a scratch repo with mixed staged / unstaged / untracked changes: | Case | Result | |---|---| | `stash push --quiet --include-untracked --message "my named stash" -- <paths>` | `stash@{0}: my named stash`; worktree clean, untracked file included | | same, without `--message` | `stash@{0}: <sha> <subject>` — git's default text | | `--message "x" --` with no paths (clean repo) | exit 0, no stash created — the empty pathspec does **not** stash everything | `cargo fmt --check` clean, `./script/clippy -p git -p fs -p project -p git_ui` passes with `--deny warnings`, and the existing suites pass (`cargo test -p project -p git_ui`, 436 tests). Worth a reviewer's attention: trigger `git::StashAll` with focus in the **editor** rather than the Git Panel. That routes through the workspace action registration and is the case the `cx.defer_in` deferral exists to keep from panicking. No new automated tests — the behavior is testable with the existing `git_panel.rs` harness (`init_test`, `GitPanel::new`) if reviewers would prefer coverage over a manual check. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments — n/a, no unsafe added - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior — no new tests; see Testing - [x] Performance impact has been considered and is acceptable — one extra process argument; no new work on any hot path --- Release Notes: - Added an optional stash message prompt when stashing changes ` --------- Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com>
…es#62356) # Objective Helix uses tab/shift-tab to navigate code action menus. Currently, this will indent the code instead of navigating within the menu. ## Solution Add keymaps. ## Testing I tested it manually. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Added support for using `tab` and `shift-tab` to navigate the code actions menu in Helix mode
…ies#62466) OpenAI reasoning summaries are streamed as multiple indexed parts, and each new reasoning output item starts its indexes at zero. The Responses event mapper previously treated those indexes as global, so adjacent reasoning items could be concatenated without whitespace, producing text such as `**First item****Second item**`. Track the current summary part by both its item ID and summary index, and emit a separator whenever that pair changes. Text delta events now retain their summary index as a fallback when a separate part-added event is absent, while sharing the same boundary handling to avoid duplicate separators. Testing performed: - `cargo check -p open_ai` - `cargo nextest run -p open_ai` - `cargo fmt -p open_ai -- --check` - `./script/clippy -p open_ai` Release Notes: - Fixed missing separators between OpenAI reasoning summaries.
# Objective I noticed that in workspace symbol search, the function's symbol kind has become `Trait`. ## Solution Add `to_proto` and a macro to define the mapping instead of `as i32`. ## Testing Updated the test. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Fixed `SymbolKind` mapping to LSP protocol values
Spotted ``` The package `block v0.1.6` currently triggers the following future incompatibility lints: > warning: static of uninhabited type > --> .../block-0.1.6/src/lib.rs:64:5 > | > 64 | static _NSConcreteStackBlock: Class; > | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > | > = note: uninhabited statics cannot be initialized, and any access would be an immediate error > = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! > = note: for more information, see issue #74840 <rust-lang/rust#74840> The package `proc-macro-error2 v2.0.1` currently triggers the following future incompatibility lints: > warning[E0365]: extern crate `proc_macro` is private and cannot be re-exported > --> .../proc-macro-error2-2.0.1/src/lib.rs:494:13 > | > 494 | pub use proc_macro; > | ^^^^^^^^^^ > | > = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! > = note: for more information, see issue #127909 <rust-lang/rust#127909> > help: consider making the `extern crate` item publicly accessible > | > 277 | pub extern crate proc_macro; > | +++ ``` warnings recently. The former is impossible to fix quickly as needs a migration to `objc2`, but the latter is easily fixed by a version bump, ergo this PR. Release Notes: - N/A
# Objective - Stop language-server update checks from waiting forever. **Note:** I tried to find any existing issue but no luck. ## Solution - Set one time limit for the full response body. If the GitHub, for example, release request stops responding, return an error. Do not let it block language-server update checks without limit. ## Testing - Did you test these changes? If so, how? 1. This is a flaky issue, reproducing it is not that trivial. 2. The easiest way I found is just restarting Zed until you get the notification in the status bar `Checking for updates <language_server_naem>` - Are there any parts that need more testing? No - How can other people (reviewers) test your changes? Is there anything specific they need to know? See above. - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? - macOS - Linux ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase <img width="2624" height="2260" alt="CleanShot 2026-08-03 at 20 29 11@2x" src="https://github.com/user-attachments/assets/83e2781c-15bc-4924-be33-88c26f20387d" /> --- Release Notes: - Fixed language servers update checks
…ndustries#62325) Since zed-industries#60772, a worktree's ignore rules are also applied to the directories above its root. Because of this, an `info/exclude` pattern naming one of those parent directories marks it as ignored, and with it the whole worktree below. Stop the walk at the repository containing the worktree root. Also skip exclude rules for paths outside the work directory they are anchored at, as `.gitignore` and global gitignore rules already do. Release Notes: - Fixed a worktree being reported as entirely ignored when its repository's `info/exclude` named one of the worktree's parent directories
…industries#62477) Release Notes: - Make GPT-5.6 Sol default for OpenAI subscribed Signed-off-by: Neel <neel@zed.dev>
## What `docs/.conventions/brand-voice/SKILL.md` declares: ```yaml name: brand-writer ``` while sitting in a directory called `brand-voice`. The Agent Skills specification requires the two to be identical: > The required `name` field: … **Must match the parent directory name** > — <https://agentskills.io/specification#name-field> So this skill fails `skills-ref validate` today. ## Which side is wrong The directory — and this repository settles it three separate ways, with no outside context needed. **1. The sibling copy already uses the matching name.** `.factory/skills/brand-writer/` holds the same four files (`SKILL.md`, `rubric.md`, `taboo-phrases.md`, `voice-examples.md`) under `brand-writer`. **2. `crates/agent_skills/README.md` documents the skill system using this exact skill, and the name it documents is `brand-writer`:** ``` line 107: <name>brand-writer</name> line 149: the model … calls `skill { name: "brand-writer" }` line 151: when the user types `/brand-writer` line 158: <skill_content name="brand-writer"> ``` That name is load-bearing — it is what the skill tool invokes and what the slash command types. The directory name is referenced twice, both inside `docs/.conventions/CONVENTIONS.md`. **3. Six of the repository's seven skills already match their directory:** | skill | matches? | | --- | --- | | `.agents/skills/gpui-test` | ✅ | | `.agents/skills/lint-creator` | ✅ | | `.agents/skills/zed-cherry-pick` | ✅ | | `.factory/skills/brand-writer` | ✅ | | `.factory/skills/humanizer` | ✅ | | `crates/agent_skills/builtin/create-skill` | ✅ | | **`docs/.conventions/brand-voice`** | ❌ the only one | ## The change The frontmatter is untouched. Only the directory moves, plus the two references to it: - `docs/.conventions/brand-voice/` → `docs/.conventions/brand-writer/` (4 files, pure rename) - `CONVENTIONS.md:5` — `[brand-voice/](./brand-voice/)` → `[brand-writer/](./brand-writer/)` - `CONVENTIONS.md:368` — `` `brand-voice/rubric.md` `` → `` `brand-writer/rubric.md` `` `git grep brand-voice` returns nothing afterwards. If you would rather keep the directory name and rename the field to `brand-voice`, that is a one-line change instead and I am happy to switch it — but it would give the two copies of one skill two different names, and it would diverge from the name `crates/agent_skills/README.md` documents. ## One thing I noticed but did not touch The two copies have drifted. `.factory/skills/brand-writer/SKILL.md` is 279 lines and includes a *"Phase 4: Humanizer Pass"* section; `docs/.conventions/`'s copy is 265 lines, lacks that section, and renumbers Validation from Phase 5 to Phase 4. That is a separate question about which copy is canonical, so it is left alone here. --- Found with [AgentCompass](https://github.com/YoavLax/agent-compass), an offline static analyzer for AI-agent repo readiness. Verified by hand against the spec before opening. Release Notes: - N/A
# Objective - Fixes zed-industries#62238 - Properly escapes paths in the sftp PUT line ## Solution - 10-line wrapper function that escapes paths as sftp expects. Namely: paths in quotes with `\\` and `"` escaped. ## Testing - Did you test these changes? If so, how? `cargo check` - Are there any parts that need more testing? Up to you, this is a simple change and I dont think sftp with default install paths ever worked on MacOS - How can other people (reviewers) test your changes? Is there anything specific they need to know? Just connect to a remote on OSX and see if the logs had an sftp upload failure in there - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Fix remote uploads over sftp where the paths contain spaces --------- Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
…ed-industries#62502) ChatGPT subscription models currently report the short-context billing thresholds (272k or 372k tokens) as their maximum context windows. Those thresholds matter when Zed is paying metered API costs, but subscription requests are billed directly by OpenAI. This updates the subscribed models to report the full context windows supported by the corresponding public API models: 1.05M tokens for GPT-5.4, GPT-5.5, and GPT-5.6, and 400k tokens for GPT-5.4 Mini. It also reports the 128k output limit so context accounting reserves capacity for the response. Request serialization is unchanged; the unsupported `max_output_tokens` parameter is still omitted from requests to the Codex backend. Release Notes: - Improved context window usage for GPT models accessed through a ChatGPT subscription.
…ries#61796) # Objective A column's filter popover grays out values that would leave zero rows given other active filters. That check only looked at columns filtered _before_ the one being viewed, so reopening a filter on a column filtered earlier than another still-active one showed a value as available with count `0` — selectable, but guaranteed to empty the table. Separately, values already checked when they became blocked lost their checkmark and couldn't be unchecked from the popover (matches IntelliJ's reference behavior of always keeping values checkable with an honest count, never fully disabled). ## Solution - Availability now reuses the same `rows_passing_other_filters` set already used for counts (every other active column's filter, own filter excluded) instead of the old order-dependent cascade over `activation_order`. Removed `activation_order` entirely — now dead code. - `Unavailable` carries `is_applied`, same as `Available`. Hidden-and-applied rows stay checked and toggleable (to uncheck); only hidden-and-unapplied rows stay disabled. - Filter popover footer no longer disappears when a filter's count drops to `0` (`has_active_filters` instead of `selected_rows == 0`). ## Testing Fixture: ```csv A,C 1,red 2,red 1,blue 1,blue ``` Rendered as: <img width="381" height="165" alt="image" src="https://github.com/user-attachments/assets/fc12d1d3-26e6-4f8e-97f0-5522f67e70ea" /> Manual: apply filters: - C=red,blue - A=2 reopening C's popover shows the blocked `blue` value grayed with count `0`, stays checked and uncheckable. ## Demo | Before (counds not updated) | After (counts reflect reality) | | --- | --- | | <img width="631" height="190" alt="image" src="https://github.com/user-attachments/assets/df433449-826d-4f7e-8c35-d3779911b7fa" /> | <img width="615" height="217" alt="image" src="https://github.com/user-attachments/assets/ce067fb9-3fd5-4d2a-9689-8defc587f617" /> | Release Notes: - Fixed CSV preview column filters showing incorrect availability/counts depending on which filter was applied first
…ies#62587) Dropped entities are released only inside an update's effect flush, and releases cascade: one flush drops the entities whose handles are gone, their drops release further handles and can queue foreground work, and a later flush collects those. `BenchAppContext` callers that only pump the executor between iterations therefore saw torn-down state linger in the entity map until some woken task happened to run an update — in a downstream benchmark this looked like a per-iteration leak of the whole app graph (~35 MB per iteration), releasing on an apparently timer-bound schedule. This adds `BenchAppContext::settle`, which alternates draining queued work with GPUI update cycles until the dispatcher reports idle, mirroring the update cadence production gets for free from frames and input events. `bench_batched_task` now settles before each iteration's setup (outside the timed interval), so the previous iteration's state is fully released and cannot accumulate across a measurement. A new `ThreadedDispatcher::is_idle` predicate backs the loop's termination and is covered by a unit test. Release Notes: - N/A
While our extension ecosystem grows more and more, we simultaneously are also enforcing more and more policies to have a better experience for our users and ensure extensions meet a minimum standard. However, at the same time, it has become increasingly difficult for extension authors to keep track of what we enforce onto extensions and what specific rules apply to their extension. Thus, this PR splits out the publishing guidelines out of the `Developing Extensions` page in an effort to make it easier to go through our requirements and make it harder to miss those. This also paves the way for more detailed publishing prerequisites, so that both authors can more quickly see what applies to their extension as well as reviewers having easier ways to point authors to what they are missing. Release Notes: - N/A --------- Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
…ries#61769) # Objective - There was no way to copy a cell's or a column header's text out of the CSV preview table (at all). ## Solution - Right-clicking a table cell now copies its full content to the clipboard; the cell tooltip shows the content plus a "Right click to copy content" hint. - Right-clicking a column header name copies the column name to the clipboard, with the same tooltip pattern ("Right click to copy column name"). ## Testing - Right-click a cell: content is copied, tooltip shows the hint. - Right-click a column header: column name is copied, tooltip shows the hint. ## Demo <img width="994" height="241" alt="image" src="https://github.com/user-attachments/assets/827a0356-e152-4bfd-84ea-5745e638f13c" /> ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Added copy-to-clipboard on right-click for CSV preview cells and column headers
…ed-industries#61997) # Objective Fixes zed-industries#60192 Closes zed-industries#62308 `editor: align selection` lines cursors up by their buffer column, and that column counts bytes. If a multi-byte character sits before the cursor, the byte column is larger than the position the cursor is actually drawn at, so the row gets padded with the wrong number of spaces. The issue reports it with `←` (3 bytes) and `π` (2 bytes): ``` a ← 1 # one bc ← π # two ``` Put a cursor on each `#`, run the action, and the result is still misaligned: ``` a ← 1 # one bc ← π # two ``` This is not the columnar selection bug fixed in zed-industries#57097. That one was `select_columns` in `selection.rs`, where the output is a selection range. This one is `align_selections` in `editor.rs`, where the output is inserted spaces, so the same byte-column assumption was left behind in a second place, and fixing it here needs a rounding step that the first fix did not. ## Solution Measure each cursor by its x offset in the laid-out display row (`DisplaySnapshot::x_for_display_point`), take the target for a column as the furthest x across the rows, then turn the difference into whole spaces by dividing by the advance width of `' '`. The offset that carries into later columns becomes an x offset instead of a column count. The display map has already expanded tabs by the time the row is laid out, so a leading tab now counts as its expanded width instead of as a single byte. Two things I would look at first in review: - The division rounds instead of truncating. The x offsets are built by repeated float addition, so a gap that should be exactly three spaces can arrive as 2.9999998, and truncating inserts two. - The function returns early if the space advance is missing or zero. Dividing by zero gives `inf`, which saturates to a huge `u32` and then tries to allocate that many spaces. I did not add any public items and did not touch `selection.rs`. ## Testing `cargo test -p editor align` on Windows: 6 passed, 0 failed. That is the new test plus the two existing `align_selections` tests, which I did not change and which still pass. `test_align_selections_with_multibyte_chars` covers the repro from the issue, a second column whose offset has to carry past a multi-byte character in the first, a leading tab, a non-BMP character, and a case where multi-byte characters sit after the cursors and nothing should move. I also checked that the test catches the bug rather than just passing: reverting the change in `editor.rs` and keeping the test makes it fail on the repro, inserting four spaces where three are right. Putting the change back makes it pass. The two older align tests pass either way, since they are pure ASCII. What I have not covered: - Wide CJK characters, combining marks, and ZWJ clusters. These should be right by construction, since the code measures advances rather than counting characters, but I have no tests for them. The headless text system behind `gpui::test` gives every BMP character the same advance, so a test there would assert the test double's behavior rather than the real renderer's. - Proportional fonts. Aligning with inserted spaces cannot be exact when glyph widths vary. The code rounds to the nearest whole space. - Soft-wrapped rows. I measure x from the start of the wrapped row but still group cursors by buffer row, so two cursors on one buffer row that sit either side of a wrap boundary get measured from different origins, and the carried offset crosses that boundary as if they shared one. The old byte-column code did not have that particular failure. I left it alone because fixing it is a different change, but I would rather flag it than have you find it. - I work on Windows and have no macOS machine. The arithmetic is platform independent, so I do not expect a difference, but I have not checked. To try it: paste the two lines from the issue, put a cursor on each `#` with `editor: select next`, then run `editor: align selection`. The two `#` should line up. ## Self-Review Checklist: - [ ] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Fixed `editor: align selections` misaligning rows and Vim `ctrl-d` / `ctrl-u` / `ctrl-f` leaving the cursor behind on lines with multi-byte characters or tabs. --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev>
According to the docs these fields can be null: https://platform.claude.com/docs/en/api/models/list#model_info.max_input_tokens https://platform.claude.com/docs/en/api/models/list#model_info.max_tokens Instead of failing the whole request, we filter those models out since we can't handle models without knowing their context window size. Seems like ClaudeCode follows the same approach. Release Notes: - N/A
Another discovery during search-on-type work. Follow-up to zed-industries#19298 and zed-industries#19846 With the `"soft_wrap": "editor_width"`, I should have no text contents overflowing the editor width. Before (scrollbar shown incorrectly): <img width="2032" height="1162" alt="before" src="https://github.com/user-attachments/assets/8b89ba6d-f98b-4ea0-89f2-8a22e968c438" /> After: <img width="2032" height="1162" alt="after" src="https://github.com/user-attachments/assets/93f62c2b-4981-48ae-aebd-8b0021348787" /> Release Notes: - Fixed invisible symbol replacement width calculation
…62577) # Objective DeepSeek has released the GA version of its V4 Pro model, and added a new low reasoning effort level for both V4 Flash and V4 Pro. We need to update Zed's DeepSeek provider to sync with this update. Reference: https://api-docs.deepseek.com/updates/ ## Solution Added a new Low reasoning effort level for DeepSeek models. ## Testing Built and ran locally. Screenshots with this change are attached in the Showcase section. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase After this change: <img width="639" height="169" alt="flash" src="https://github.com/user-attachments/assets/5521f6fe-ced9-4842-8783-24c532bf66f6" /> <img width="640" height="181" alt="pro" src="https://github.com/user-attachments/assets/0293d4a2-03f8-41e1-8a3e-31efce9dea17" /> --- Release Notes: - Added support for low reasoning effort for DeepSeek V4 Flash and V4 Pro
) Closes zed-industries#21054 ## Summary • make the JetBrains base keymap use subword motions for `Alt+Left/Right` and `Shift+Alt+Left/Right` in editors • keep Zed's default keymaps and the underlying `word`/`subword` primitives unchanged • document word vs. subword navigation in the key bindings docs • document the JetBrains default in the IntelliJ, WebStorm, PyCharm, and RustRover migration guides ## Testing • `./script/check-keymaps` • `cargo fmt --all -- --check` • `./script/clippy -p editor` • `cd docs && pnpm dlx prettier@3.5.0 src/key-bindings.md src/migrate/intellij.md src/migrate/webstorm.md src/migrate/pycharm.md src/migrate/rustrover.md --check` Related to zed-industries#12816 and zed-industries#34090, but does not actually address the configurable word separators or broader subword semantics. Intentionally scoped to JetBrains keymap defaults & docs. Release Notes: - Improved JetBrains keymap behavior by adding CamelHump-style subword navigation in editors. --------- Co-authored-by: Tom Houlé <tom@tomhoule.com> Co-authored-by: Antonio Scandurra <me@as-cii.com>
Confirming an inline rename after deleting the entire symbol name or entering only whitespace currently submits an invalid rename request to the language server. This can remove the symbol text instead of leaving the source unchanged. Treat empty and whitespace-only replacements as successful no-ops after dismissing the inline rename UI. Returning a completed task also consumes the confirmation action, preventing Enter from propagating back into the editor. Non-blank rename behavior remains unchanged. The regression test covers both empty and whitespace-only rename fields, verifying that no LSP rename request is sent and the original buffer remains intact. Release Notes: - editor: Fixed confirming a blank symbol LSP-rename modifying the source code
# Objective The MVP version of CSV preview is ready. However it's trivial to extend it to TSV & other formats. ## Solution This PR does exactly that - switching from CSV only to any tabular data (TSV/CSV/PSV/SSV). 1. added `tsv`/`psv`/`ssv` support 2. renamed action/eye button & crate 3. added `.psv`/`.ssv` types to use database icon (similar to `csv`/`tsv`) 2. Added `Table` svg icon (was previously missing) so preview is not longer using book icon (from markdown preview). > NOTE: Crate renaming will be done separately (as it's mechanical work & I don't want to mix it with logic changes) ## Testing Opened csv/tsv/psv/ssv files in peview ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase PSV/SSV file formats icon | Before | After | | --- | --- | | <img width="141" height="136" alt="image" src="https://github.com/user-attachments/assets/ff5ec1a2-10e3-4363-a467-d535c7f621c0" /> | <img width="143" height="135" alt="image" src="https://github.com/user-attachments/assets/f4a85276-beee-4d3e-bc59-319c4fc8812c" /> | Change namespace for actions (`csv` -> `tabular data`) | Before | After | | --- | --- | | <img width="551" height="150" alt="image" src="https://github.com/user-attachments/assets/f7b79a7f-b300-4d14-8565-b42b3bcb11c4" /> | <img width="558" height="152" alt="image" src="https://github.com/user-attachments/assets/be9dcc54-51a4-4736-9539-172fecabdf6d" /> | Update parser & detection logic to support preview for TSV/PSV/SSV | Before | After | | --- | --- | | <img width="470" height="287" alt="image" src="https://github.com/user-attachments/assets/d0222bd1-91a7-46e0-b4da-76be0642bf51" /> | <img width="541" height="275" alt="image" src="https://github.com/user-attachments/assets/3c4d237a-4956-46ad-b7d6-3a8782b41888" /> | Introduce table svg icon | Before | After | | --- | --- | | <img width="349" height="66" alt="image" src="https://github.com/user-attachments/assets/bd7999ef-516f-43d1-a0e6-50055c1c3bed" /> | <img width="331" height="50" alt="image" src="https://github.com/user-attachments/assets/fc534921-0c15-421c-b046-8c5967178d24" /> | --- Release Notes: - N/A or Added/Fixed/Improved ...
…stries#62496) GPUI currently splits performance instrumentation across several Cargo features and runtime controls. Task profiling, frame-duration histograms, input-latency histograms, and benchmark frame timing therefore follow separate code paths despite measuring related parts of the same UI work. This PR consolidates those systems under the `profiler` Cargo feature. The `bench` feature now enables `profiler`, aggregate frame and input-latency histograms remain active whenever profiling is compiled in, and `set_trace_enabled` controls whether individual task timings and per-frame draw and presentation records are retained. The change also introduces a single per-window profiler that owns the begin and end state for input dispatch, drawing, and presentation, and routes window action-handler timing through the existing aggregate action tracker. Draw and presentation records reuse the same timestamps and computed intervals as the aggregate histograms, avoiding duplicate clock reads. Benchmark trace scopes are reference-counted so overlapping measurements cannot disable tracing while another measurement still needs it. This does not change hang detection directly. It establishes the common profiling foundation needed to correlate slow or delayed frames with actions and foreground or background tasks. Better attribution should make it easier to find and prevent responsiveness regressions. Release Notes: - N/A --------- Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Extract parts of `platform_macos` to `gpui_apple` to be used as a shared crate between `gpui_macos` and a future `gpui_ios` for iOS/iPadOS apps. Release Notes: - N/A
Closes zed-industries#42583 Adds more tooltip entries and `editor::BlameRevision`, `editor::BlamePreviousRevision` actions to use. Started to highlight gutter blame entries that belong to currently annotated commit. https://github.com/user-attachments/assets/ba754e0b-6431-407c-8d79-2f8b0324fde1 Release Notes: - Supported blaming parent revisions
…2651) ChatGPT subscription model availability is determined by the authenticated Codex backend and can vary by account. The provider currently exposes a bundled static list and defaults to GPT-5.6 Sol, so users can be offered a model that their ChatGPT account subsequently rejects. This change fetches the account-scoped Codex model catalog after loading stored credentials and after sign-in. Requests use the existing OAuth token, ChatGPT account ID, Zed originator, and the Zed client version. Picker-visible models are ordered by the server's priority, and the returned metadata drives model names, context windows, image support, reasoning levels, and Fast Mode support. The bundled list remains available before discovery and when discovery fails. A failed refresh preserves the last usable catalog and surfaces the failure in provider settings, while generation checks prevent a response for an older account or request from replacing newer state. Model discovery uses the same five-second timeout as Codex so a stalled catalog endpoint cannot indefinitely delay authentication. Zed's language model provider now derives its provided, default, recommended, and fast models from that resolved catalog. Testing performed: - `cargo nextest run -p openai_subscribed` - `cargo nextest run -p language_models` - `./script/clippy -p openai_subscribed -p language_models --lib` - `cargo fmt --all -- --check` - `git diff --check` Release Notes: - Fixed ChatGPT subscription accounts offering models that are not available to them.
…es#62652) OpenAI-compatible providers currently cannot reuse Zed's OpenAI Chat Completions transport unless they also adopt the exact OpenAI request and response types. OpenRouter therefore maintained its own copy of request construction, authentication, status handling, response reading, and server-sent event framing. This change extracts that mechanical transport into two provider-neutral functions in `open_ai`: one for streaming requests and one for non-streaming requests. They accept any serializable request envelope, preserve custom headers and provider names, return untyped JSON for provider-specific decoding, and retain typed failures for serialization, request construction, HTTP transport, response reading, and deserialization. The existing OpenAI entry points remain as compatibility wrappers, so existing callers keep the same API and behavior. The abstraction deliberately stops at the wire boundary. OpenRouter continues to own its request and response schemas, attribution headers, routing controls, cache placement, and API-specific error interpretation. It now adapts the shared framed stream into those OpenRouter types instead of implementing a second HTTP and server-sent event stack. Moving OpenRouter onto the shared path also requires the ordinary Chat Completions schema and event mapper to preserve compatible metadata that OpenRouter already emits. This includes structured reasoning details needed for replay, fragmented reasoning accumulation, prompt-cache read and write usage, and thought signatures attached to tool calls. The stream exposes `[DONE]` explicitly rather than treating it as indistinguishable from an unexpected end of the response body. OpenRouter's routing session identifier is hashed before transmission so Zed's internal thread identifier is not exposed. The diff is larger than the extracted transport alone because the shared API is additive, the compatibility metadata must be represented in the common wire types and event mapper, and the provider-specific adapter remains intentionally independent. Roughly four hundred added lines are focused transport, metadata, error-classification, attribution, caching, and privacy tests. The provider-level OpenRouter implementation becomes smaller while preserving its existing behavior. Testing performed: - `cargo test -p open_ai` - `cargo test -p open_router` - `cargo nextest run -p language_models open_router` - `cargo check -p edit_prediction -p edit_prediction_cli` - `cargo fmt --all -- --check` - `./script/clippy -p open_ai -p open_router -p language_models -p edit_prediction_cli` - `cargo machete` Release Notes: - Improved OpenRouter reasoning continuity and request privacy. --------- Co-authored-by: Eric Holk <eric@zed.dev>
…ustries#62259) Some context behind this change: I’ve been meaning to look into this because I kept running into this crash when working on [other](zed-industries#61040) fixes. Everything worked fine in dev builds, right up until you tried to create a new Agent Thread using an ACP adapter. The crash reports in this instance were throwing me off: I was seeing different things each time. So, I had Fable look into this. It did so by binary-searching the minimum thread stack on which a probe replicating Zed’s exact handler chain can dispatch one message. Full methodology, probe source, and raw numbers can be found in [this gist](https://gist.github.com/yeskunall/2ac2b00f51389d9388d607974f6f8a04). The results of the probe are as follows: | SDK | Minimum stack (dev profile) | vs. 512 KiB GCD budget | |---|---|---| | 1.3.0 | 409,600–413,696 B | fit, ~100 KiB headroom | | 2.0.0 | 507,904–512,000 B | entire budget before runtime overhead | The oversized frames are monomorphized into `agent_servers`, not the SDK crate -- a `[profile.dev.package]` opt-level override on `agent-client-protocol` does **not** fix this (see gist), and optimized builds collapse the frames entirely, which is why only dev builds crashed. It found that the real signature is `fault_address == stack_pointer` on a `com.apple.root.default-qos` thread inside the ACP dispatch specialization, which I then had it verify across six local `.ips` reports. It seems in zed-industries#61570, we pushed the dispatch chain past the GCD budget, explained further below: `AcpConnection::stdio` polled the ACP client connection future via `background_spawn`, which on macOS executes runnables on [GCD’s](https://developer.apple.com/documentation/DISPATCH) global-queue workers. Those threads have kernel-fixed, unconfigurable [512 KiB stacks](https://github.com/apple-oss-distributions/libpthread/blob/42d026df5b07825070f60134b980a1ec2552dfee/kern/kern_internal.h#L154). In unoptimized builds, the SDK’s chained-handler dispatch needs **~0.5 MiB of stack per inbound message** (again, see linked gist), so the first message overflows the guard page and takes the process down. Therefore, this 512 KiB constraint is **macOS-only**. Linux doesn’t use GCD -- GPUI [spawns its own `std::thread` workers](https://github.com/zed-industries/zed/blob/82878540b5410b288a2c92cb9ee5675533e4d807/crates/gpui_linux/src/linux/dispatcher.rs#L39) ([2 MiB Rust default](https://github.com/rust-lang/rust/blob/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/sys/thread/unix.rs#L26)). Windows uses [the OS thread pool](https://github.com/zed-industries/zed/blob/82878540b5410b288a2c92cb9ee5675533e4d807/crates/gpui_windows/src/dispatcher.rs#L68), which [inherits the executable’s stack reserve](https://github.com/MicrosoftDocs/sdk-api/blob/4502fff176b3b56beddb6a63c9f980377b11ba9b/sdk-api-src/content/threadpoolapiset/nf-threadpoolapiset-setthreadpoolstackinformation.md?plain=1#L58) -- [1 MB linker default](https://github.com/MicrosoftDocs/win32/blob/2eb6588c6703d31599285bbb06563c3d41b57590/desktop-src/ProcThread/thread-stack-size.md?plain=1#L17), but Zed already bumps it to 8 MiB in [crates/zed/build.rs:88](https://github.com/zed-industries/zed/blob/82878540b5410b288a2c92cb9ee5675533e4d807/crates/zed/build.rs#L88) (see [TODO comment](https://github.com/zed-industries/zed/blob/82878540b5410b288a2c92cb9ee5675533e4d807/crates/zed/build.rs#L87)). --- Release Notes: - N/A
# Objective Project search sends one candidate per file to its worker pool, and each one carried an owned `Snapshot`. Every field of `Snapshot` is cheap to clone except `always_included_entries`, a `Vec<Arc<RelPath>>` holding one entry per always-included file. With a broad file_scan_inclusions such as **/*, that vector holds an entry per file in the project, so cloning it once per file made search O(files²). Partially addresses zed-industries#38799 (still needs to fix the huge memory usage and the occasional stutters) . ## Solution Share the snapshot behind an `Arc` instead, the consumer only reads `id()`, `abs_path()` and `root_name()`, so nothing needs an owned copy. ## Testing Using the [linux kernel repo](https://github.com/torvalds/linux), i searched for `vmx_l1d_should_flush ` and `netif_rx` and its at least 60x faster on 5950x. with `file_scan_inclusions: ["**/*"]` Release Notes: - Fixed project search being very slow on projects that set a broad `file_scan_inclusions`
…ies#62665) # Objective - prevent branch name overflow in git details pane - Fixes zed-industries#62526 ## Solution - set min width - add tooltip for readability ## Testing - manual testing ## Self-Review Checklist: - [X] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [X] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [ ] Performance impact has been considered and is acceptable ## Showcase ### before - <img width="670" height="205" alt="image" src="https://github.com/user-attachments/assets/26716b50-6f09-40c1-bec5-d78bd913d4ec" /> - No tooltip ### After - <img width="499" height="203" alt="image" src="https://github.com/user-attachments/assets/3eee21e8-f9e8-4c30-a21d-0c23bf25c9de" /> - Tooltip: <img width="609" height="364" alt="image" src="https://github.com/user-attachments/assets/822d784d-889e-4d26-b8e6-de46f8206569" /> --- Release Notes: - N/A or Added/Fixed/Improved ...
Follow-up to zed-industries#46337, same fix as zed-industries#48280. `title_bar` tests enable `remote/test-support`, which adds `RemoteConnectionOptions::Mock`. But without `recent_projects/test-support`, the match arms for that variant aren't compiled, causing a non-exhaustive match error when testing the crate in isolation: ``` error[E0004]: non-exhaustive patterns: `&RemoteConnectionOptions::Mock(_)` not covered --> crates/remote_connection/src/remote_connection.rs:233:76 ``` CI doesn't catch this because `collab` and `sidebar` enable `recent_projects/test-support` during workspace-wide tests. Adding `remote_connection/test-support` instead isn't enough — that just moves the same error into `recent_projects`. `recent_projects/test-support` covers both. Release Notes: - N/A
…2685) Follow-up to zed-industries#62658 The problematic field is not needed at all in the snapshot, as can be constructed before starting the scanner — moreover, the field had accumulated more and more paths between rescans, leaking memory. Now, we spend more time traversing the entire tree between rescans, but that happens for rescans only which should be relatively rare? Release Notes: - N/A
…tem (zed-industries#62602) Closes zed-industries#59001 Saving a notebook wrote the file with `project.fs().atomic_write(abs_path, ...)`. `Project::fs()` is always the client's own filesystem, so for a remote project the remote path was resolved against the local machine: on Windows the drive letter got prepended and the atomic-write temp file used a backslash, producing `C:/data/project/src_example\.tmpPuzw3d3` and `os error 3`. The same thing fails on macOS/Linux clients with `os error 2`. Both `save` and `save_as` now go through the project's buffer machinery instead: open the buffer for the notebook's `ProjectPath`, set its text to the serialized notebook, then `save_buffer` / `save_buffer_as`. Writes are routed over the remote connection for remote projects, and the open buffer stays in sync locally. `save_as` also updates the item's project path and entry id, since `save_buffer_as` moves the buffer to the new path and otherwise the next save would write back to the old file. Added a test that edits a cell, saves, and checks that the notebook buffer held by the project reflects the saved file. It fails against the old implementation. Release Notes: - N/A --------- Co-authored-by: Finn Evers <finn.evers@outlook.de>
…ed-industries#61923) ## Objective Right-clicking a buffer header in a multibuffer showed a context menu whose item spacing did not match other context menus. The menu is drawn via a deferred draw, which inherits the editor's text style stack, so its line height followed `buffer_line_height` instead of the default UI line height. This is the same root cause as zed-industries#24504, which zed-industries#25172 fixed for the editor's mouse context menu and completion popovers. The buffer header menu was a remaining call site. ## Solution `ContextMenu` now applies the default (`comfortable`) line height itself in `render`, next to its existing rem size and font family normalization, so menus render the same regardless of where they are opened from. This fixes the all workarounds and the need for them too: the workaround in `layout_mouse_context_menu` is removed, and the buffer header ends up needing no changes at all. The completions and code actions popovers keep their override in `element.rs`: they are not `ui::ContextMenu`s and compute their sizes with eager `window.line_height()` reads while being built, so styling on the elements they return cannot cover them. Migrating them could be a follow-up. ## Testing - `cargo check --workspace` passes, `./script/clippy` on the touched crates passes. - Manual: set `"buffer_line_height": "standard"` (or any extreme custom value to see it better), open a multibuffer (e.g. project search), right-click a buffer header, and compare the menu with another context menu (e.g. a tab's) — spacing matches. The editor's mouse context menu, which lost its own override, renders as before, and with default settings there is no visual change anywhere. - Tested on macOS, change is platform-independent styling. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior (visual styling fix; menu text styles have no existing test coverage) - [x] Performance impact has been considered and is acceptable ## Showcase Regular context menu: <img width="425" height="164" alt="A context menu elsewhere in the app, showing normal item spacing" src="https://github.com/user-attachments/assets/1fc13981-b394-444f-883a-ce3ef462c386" /> Before: <img width="425" height="164" alt="Buffer header context menu before the fix, with tighter item spacing following the custom buffer_line_height" src="https://github.com/user-attachments/assets/9774076c-7e0c-41dd-b54f-53de58b24336" /> After: <img width="425" height="164" alt="Buffer header context menu after the fix, with item spacing matching other context menus" src="https://github.com/user-attachments/assets/ae76e37c-8e39-474c-8a5e-e229e69173fb" /> --- Release Notes: - Fixed the file header context menu in multibuffers not matching other context menus' spacing when a custom `buffer_line_height` is set. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Local benchmark shows this speeds it up by at least 30% and is definitely more reasonable to have like this than compared to iterating over a list for every given char. Release Notes: - N/A
…stries#62711) `ThreadView::regenerate` does `thread.rewind()` which de-focused the message editor mid-flight causing the zoomed panel to disappear. * workspace: Keep zoomed panels open when window focus is lost Commit adds a test + tweaks a default, generic, fallback to be more lenient: instead of focusing the workspace (and hiding all panels right away), try to fall back to whatever panel open * gpui: Restore focus to nearest surviving ancestor when focus is lost Commit tries to push it down to a library level and add a way to fall back to closest ancestor that's still visible with the focus instead. Release Notes: - Fixed the zoomed agent panel closing unexpectedly on rewind
The early return made the call a silent no-op, so a test could deactivate a window that was never active and then assert behaviour it had not exercised. Every existing caller already activates first.
butvinm
force-pushed
the
guard-vacuous-deactivation
branch
from
August 16, 2026 20:42
27b3b55 to
73ecb97
Compare
Owner
Author
|
Closing: purely preventive. With the assert live, all 1662 tests across editor, workspace, agent_ui and project_panel pass, so no current test deactivates an inactive window - every caller activates first, usually via |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TestAppContext::deactivate_windowsilently does nothing when the window is not the active one:A test that deactivates an inactive window then asserts behaviour it never exercised, and passes. Nothing signals that the call was skipped.
Assert instead of skipping. A no-op deactivation is never what the caller wanted, so failing with an explanatory message turns a silently-vacuous test into an immediate, self-describing failure - including for tests written later, which per-test assertions would not cover.
Every existing caller already activates first, usually via
Workspace::test_new(crates/workspace/src/workspace.rs:7911). Verified across every crate that callsdeactivate_window:editorworkspaceagent_uiproject_panel1058 tests, zero failures.
Release Notes: