Commit graph

5066 commits

Author SHA1 Message Date
Anthony Eid
4f6d97b9de
gpui: Measure frame pacing against each window's refresh rate (#65351)
Frame and hang telemetry judged every frame against a fixed 24 ms
budget. That's too lax on 120–360 Hz displays and too strict at 30 Hz,
so the numbers couldn't be compared across users or catch regressions on
fast displays. This judges each frame against its window's display
refresh interval (from #65059), as measurement version 3.

**Frame timing.** A frame's work runs from the later of its frame signal
and its first invalidation until its submission to the platform begins,
on every platform, so time spent waiting for a late frame signal or
inside the submission doesn't count. A frame is late when its work
exceeds one refresh interval, but never less than 8.33 ms (one refresh
at 120 Hz), since frames rarely fit a single refresh on faster displays
yet; on displays whose refresh interval is unknown (X11, web) the budget
is 16.7 ms. Missed refreshes still count against the real interval.

**Frame Duration Report**, per window and refresh interval: on-time,
late, and unmeasured frame counts and missed refreshes, overall and for
frames that responded to input; work (as a percentage of the refresh
interval) and draw-time buckets, computed from hdrhistogram histograms;
GPU and CPU.

**Hang Incidents.** Threshold incidents (one event of 100 ms or more)
are unchanged. Budget incidents are split by trigger:
- `late_frame`: a presented frame over its budget, listing the events
that overlap that frame's work;
- `blocking_work`: in an interval with no measured frame, a single event
of at least the frame budget (16.7 ms in release builds), long enough to
delay a frame. Total foreground time across an interval no longer
counts, since gaps between short work don't block frames.

Draw contributors carry request-layout, prepaint, and paint times, and
any entity view phase whose own work (excluding nested views) takes 0.5
ms or more becomes a contributor named by its view type. Events also
report counts per trigger, incidents during active use (within a minute
of a key press, click, or scroll) with active seconds for rates per
active hour, stall buckets, and contributor totals summed across every
incident (`view:<type>:<phase>`, `action:…`, `task:…`).

**Verification.** With a synthetic render delay on a 240 Hz display,
on-time frames went from 99.9% at no delay to 0% at 6 ms. In a real Zed
on Linux at 360 Hz, scrolling a markdown preview with #63138's per-frame
code-block highlighting reintroduced roughly doubled missed refreshes
per frame (3.2 to 6.0) and attributed the extra time to
`MarkdownPreviewView`'s request-layout phase. Profiler overhead was
+2.3% of main-thread time in a 1,500-view GPUI stress test and about
0.3% in the Zed scroll run. Not yet verified: Windows, and input-driven
frames from real use. Time spent inside the platform submission (GPU,
compositor) isn't measured on any platform.

Release Notes:

- [GPUI] Improved frame and hang telemetry to measure frames against
each window's display refresh rate
2026-10-09 05:44:50 +00:00
Anthony Eid
95d35c6efd
gpui_apple: Share CoreText, Keychain, and thermal services (#65058)
This moves three pieces of macOS platform code into `gpui_apple` so the
upcoming iOS backend (#63068) can share them: the CoreText text system,
the Keychain credential helpers, and thermal-state reporting. macOS
behaves the same as before. Credential reads still return `None` when
nothing is stored or the prompt is canceled, deleting a missing
credential is still an error, and text rendering keeps font smoothing
and dilation. Along the way the Keychain and OpenType code switch from
hand-written FFI to the generated objc2 bindings, which also fixes an
over-release of temporary CoreText feature strings, and thermal
notifications now reach the main thread through a channel instead of a
raw-pointer `dispatch_async_f`. It also replaces the old `core-video`
crate with `objc2-core-video`, because `core-video` pulls in
`io-surface` and `cgl`, which link OpenGL and break iOS builds. That
changes GPUI's public surface API: `SurfaceSource`, `PaintSurface`, and
`Window::paint_surface` now take
`CFRetained<objc2_core_video::CVPixelBuffer>`, and LiveKit's video
frames follow suit. I tested this with the gpui, gpui_apple, and
gpui_macos test suites, including a new Metal test that renders a real
NV12 pixel buffer, plus checks of the `zed` and `remote_server` builds;
the iOS link was verified on the iOS branch. LiveKit playback and the
Keychain paths are only compile-checked, so a quick sign-in/sign-out on
macOS before relying on this is worth doing.

Release Notes:

- [GPUI] Added shared Apple CoreText text rendering, Keychain, and
thermal-state services in `gpui_apple`, and migrated `SurfaceSource`,
`PaintSurface`, and `Window::paint_surface` from `core-video`'s
`CVPixelBuffer` to `CFRetained<objc2_core_video::CVPixelBuffer>`
2026-10-09 05:35:20 +00:00
Ben Brandt
9ab0715969
agent_servers: Preserve initial ACP session updates (#65339)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_remote_server_linux_x86_64 (push) Blocked by required conditions
run_tests / check_remote_server_mac_aarch64 (push) Blocked by required conditions
run_tests / check_remote_server_windows_x86_64 (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
Upgrade ACP SDK and derive to the published **3.2.0** release and use
its prepared requests/cancellation handles to register new sessions
before processing their first updates.

Previously, `session/new` used an ordinary response future. A peer could
reply and immediately send an update before foreground session
registration, causing the update to be discarded as belonging to an
unknown session. The prepared ordered callback now delivers the result
to the creation task and waits for synchronous foreground registration
to be acknowledged before later inbound dispatch proceeds.

Caller abandonment explicitly requests RPC cancellation through the
SDK-owned handle without discarding eventual response handling. If an
abandoned caller receives a late successful session, Zed requests close
when the peer advertises support. Peer rejection, EOF, and abandonment
release the registration barrier; a failed creation does not terminate
an otherwise usable connection. Default mode/config work remains
asynchronous and is not awaited inside the barrier.

The callback does not retain `Rc<AcpConnection>` or await later traffic
on the same connection. Cancellation is request-scoped and cooperative,
not cancellation of already-completed RPCs or ongoing session work.

Client writes no longer hide already-captured agent stderr when startup
fails. A deterministic interleaving regression covers this
diagnostic-selection race without weakening the physical-process startup
assertion or adding retries. Caller-drop cancellation uses the existing
`util::defer` helper rather than a bespoke guard type.

Release Notes:

- Fixed initial ACP session updates being dropped and agent startup
diagnostics being lost.
2026-10-08 19:07:07 +00:00
Ben Brandt
b0048cde74
gpui_web: Avoid blocking Fetch response-body sends (#65334)
Replace the bounded `futures::mpsc` response-body channel with
`async-channel`, using the workspace's default-features-disabled
configuration. The browser Fetch pump runs on the main thread while
response bodies can be consumed by workers. `futures::mpsc` locks an
internal sender mutex during `poll_flush`; contention can attempt an
unsupported `Atomics.wait` on the browser main thread.

Release Notes:

- [GPUI] Fixed a browser crash when streaming Fetch response bodies to
background workers.
2026-10-08 13:15:32 +00:00
Ben Brandt
19c69782eb
Fix panic when EGL fails without reporting an error (#65329)
Pin `khronos-egl` to the Zed fork's defensive error-handling fix for
[FR-522](https://linear.app/zed-industries/issue/FR-522/zed-c82-called-optionunwrap-on-a-none-value).

An EGL call can fail while `eglGetError()` reports `EGL_SUCCESS`. The
binding currently unwraps the missing error, which caused the reported
panic during Wayland surface creation. The fork returns a distinct
`Error::Unreported` instead, preserves real EGL errors, and applies the
same rule consistently to failed-call wrappers.

- Fork commit:
[42214b3](42214b3634).
- Upstream PR:
[timothee-haudebourg/khronos-egl#37](https://github.com/timothee-haudebourg/khronos-egl/pull/37).
- This PR changes only `Cargo.toml` and `Cargo.lock`. Remove the
temporary fork patch once an upstream release includes the fix.

The new public error variant is source-breaking for exhaustive matches,
so the upstream PR explicitly leaves release/versioning to the
maintainer. This integration uses a controlled Git pin and has been
checked against the GLES downstream consumer.

Release Notes:

- [GPUI] Fixed a panic when EGL calls fail without reporting an error.
2026-10-08 12:10:16 +00:00
Ben Brandt
67b41bf976
Upgrade ACP SDK to 3.1.0 (#65274)
The temporary pin is the immutable commit
[`015845a19fc31752c02367567d3b8900a406f9da`](015845a19f),
under upstream review in
[smol-rs/async-task#108](https://github.com/smol-rs/async-task/pull/108).

- Upgrade `agent-client-protocol` and its derive crate from 2.2.0 to
3.1.0, consuming the SDK's exact schema 1.10.2 dependency.
- Explicitly enable `schemars`: SDK3 makes JSON Schema support optional,
while the existing native `spawn_agent` tool derives `JsonSchema` for an
input containing `acp::SessionId`.
- Pin the canonical task-waker fix. SDK3's direct transport polling
exposed inconsistent original/clone waker vtable identity in the
previous `async-task` revision, causing repeated readiness wakeups and
starving the inherited-stdout drain timeout. The upstream fix resolves
this without a Zed-specific wrapper or weakened assertions.

Release Notes:

- N/A
2026-10-08 10:34:25 +00:00
Sushank Mandal
cb73ee1d45
debugger_ui: Enable search in debugger terminal panel (#56863)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_remote_server_linux_x86_64 (push) Blocked by required conditions
run_tests / check_remote_server_mac_aarch64 (push) Blocked by required conditions
run_tests / check_remote_server_windows_x86_64 (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
When a debug session is running, pressing cmd-f (or using Edit → Find)
in the terminal panel had no effect. Three things were missing:

- The debugger panes never had a BufferSearchBar added to their toolbar,
so there was no search UI to deploy.
- SubView::as_searchable returned None for all item kinds, so even if a
search bar were present it could not find a search target.
- RunningState::render did not wrap its output with the pane search
action handlers, so buffer_search::Deploy was never handled.

Fix all three:
- Register BufferSearchBar on each debugger pane toolbar via the
PaneSearchBarCallbacks global (same pattern as terminal_panel).
- Implement SubView::as_searchable for Terminal kind, delegating to the
inner TerminalView which already implements SearchableItem.
- Wrap RunningState::render with wrap_div_with_search_actions so the
Deploy action reaches the active pane's toolbar.
- Add refresh_terminal_toolbars to re-fire toolbar.set_active_item when
the terminal entity is set, covering the case where the Terminal tab was
already active before the terminal was created. Only refreshes panes
where the Terminal subview is currently the active item.

Add a test that verifies the active debugger pane toolbar has a
BufferSearchBar after a session starts.

Self-Review Checklist:

- [ ] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

Fixes #38409

Release Notes:

- Fixed `cmd-f` search not working in the debugger terminal panel.

---------

Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
2026-10-07 22:26:00 +00:00
Kirill Bulatov
7ca96c2a58
Keep remote agent secrets out of launcher arguments (#65174)
Closes https://github.com/zed-industries/zed/issues/64511

Release Notes:

- Fixed remote agent secrets exposed in the launcher arguments
2026-10-07 15:35:34 +00:00
Kirill Bulatov
56303a3372
audio: Recover from notification output stream failures (#65158)
Closes https://github.com/zed-industries/zed/issues/64962

Update CPAL and rodio to remove the uninterruptible ALSA write retry
loop.
Discard failed output streams so subsequent notifications can reopen the
device.
Preserve recoverable underruns, cancel stale error handlers on teardown,
and keep existing output buffer defaults.

Release Notes:

- Fixed audio thread failing to properly stop on errors
2026-10-07 14:56:19 +00:00
zed-zippy[bot]
7262175465
Bump Zed to v1.25.0 (#65285)
Release Notes:

- N/A

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-10-07 14:29:29 +00:00
renovate[bot]
c31280f1b8
Update Rust crate rustls to v0.23.45 [SECURITY] (#65221)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [rustls](https://redirect.github.com/rustls/rustls) |
workspace.dependencies | patch | `0.23.40` → `0.23.45` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/15138) for more information.

---

### Rustls: TLS 1.3 handshake messages incorrectly accepted across
encryption level boundaries

[GHSA-2mjx-qc3c-rqvc](https://redirect.github.com/advisories/GHSA-2mjx-qc3c-rqvc)

<details>
<summary>More information</summary>

#### Details
Rustls accepted TLS 1.3 handshake messages sent at the wrong encryption
level when they followed a key-changing message in the same record. The
handshake transcript is still authenticated, so a network-position
attacker cannot use this to alter or complete a handshake; the practical
effect is that a peer could send handshake messages that should be
encrypted in plaintext without rustls rejecting the connection.

This issue affects rustls versions 0.23.13 through 0.23.44 inclusive.

##### Original report

##### Summary
Rustls (tested version 0.23.44, and it appears still an issue on latest
master though I have not tested this) accepts a TLS 1.3 server flight
where a plaintext EncryptedExtensions is packed into the same record as
the ServerHello.

This is very similar to Go's CVE-2025-61730 fixed in
5046bdf8a6

##### Details
It appears `Deframer::aligned` considers itself aligned as long as all
messages remaining in the buffer are complete. Rustls processes the
ServerHello, installs the handshake keys, then pulls the complete
(plaintext) EncryptedExtensions out of the buffer.

This is insufficient per RFC 8446 section 5.1's

> Handshake messages MUST NOT span key changes. Implementations MUST
verify that all messages immediately preceding a key change align with a
record boundary; if not, then they MUST terminate the connection with an
"unexpected_message" alert. Because the ClientHello, EndOfEarlyData,
ServerHello, Finished, and KeyUpdate messages can immediately precede a
key change, implementations MUST send these messages in alignment with a
record boundary.

##### Impact
An on path attacker can inject plaintext messages that are accepted.

##### Tool Use Disclosure
This was discovered by a new TLS/DTLS test suite currently under
construction. The specific testcase was inspired by the Go CVE. Other
tested implementations (Botan, OpenSSL, BoringSSL, Go, wolfSSL) reject
this protocol flow. Daybreak Blue reviewed the rustls code to identify
probable root cause.

#### Severity
- CVSS Score: 5.3 / 10 (Medium)
- Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N`

#### References
-
[https://github.com/rustls/rustls/security/advisories/GHSA-2mjx-qc3c-rqvc](https://redirect.github.com/rustls/rustls/security/advisories/GHSA-2mjx-qc3c-rqvc)
-
[5046bdf8a6)
-
[98456aea70)
-
[https://rustsec.org/advisories/RUSTSEC-2026-0285.html](https://rustsec.org/advisories/RUSTSEC-2026-0285.html)
-
[https://github.com/advisories/GHSA-2mjx-qc3c-rqvc](https://redirect.github.com/advisories/GHSA-2mjx-qc3c-rqvc)

This data is provided by the [GitHub Advisory
Database](https://redirect.github.com/advisories/GHSA-2mjx-qc3c-rqvc)
([CC-BY
4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).
</details>

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMzQuMSIsInVwZGF0ZWRJblZlciI6IjQ0LjEzNC4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-10-06 08:16:30 +00:00
Ben Brandt
9df33dea42
acp_thread: Share v2 session information (#65195)
Use SDK v2 session-information patches at the shared boundary and reuse
the existing `AgentSessionInfo` record for live session state. Based on
`main` after #65190 merged. **No new session/history store or v2 wire
handler; production connections still use v1.**

- Preserve title/timestamp omission, null, and value semantics through
one explicit v1 adapter. V1 absent/null optional metadata means no
update; supplied metadata, including an empty map, replaces the stored
map.
- Keep the existing UTC application timestamp representation. Ignore
invalid advisory timestamps without clearing a prior value or logging
the supplied value/parser error; apply the other valid fields.
- Emit title events only for actual title changes or removal of
provisional state. Timestamp/metadata changes notify entity observers
without manufacturing title events or local activity.
- Synchronize title UI/history with explicit clears while preserving
user overrides. Track the title buffer owner/revision rather than text
equality or focus alone, so programmatic updates do not echo to the
backend and explicit same-text user choices still persist.

**Intentional v1 behavior fix:** honor the schema's `title: null` clear
signal, which the old live handler ignored. A supplied title also
removes the provisional fallback. Native title-setter behavior and
opaque session identity are preserved.

## Review guide

- [Shared patch
application](29767ed988/crates/acp_thread/src/connection.rs (L413))
and [explicit v1
conversion](29767ed988/crates/acp_thread/src/connection.rs (L446)).
- [Live session update and event
boundary](29767ed988/crates/acp_thread/src/acp_thread.rs (L5109)).
- [Title synchronization revision
guard](29767ed988/crates/agent_ui/src/conversation_view/thread_view.rs (L2830))
and [owned synchronization
path](29767ed988/crates/agent_ui/src/conversation_view/thread_view.rs (L2838)).
- [Adapter/reducer
fixture](29767ed988/crates/acp_thread/src/connection.rs (L1399))
and [extended UI title
regression](29767ed988/crates/agent_ui/src/conversation_view.rs (L14254)).

## Follow-up review: updates received during load

Initialize the [header from saved user override, otherwise live
title/default](29767ed988/crates/agent_ui/src/conversation_view/thread_view.rs (L895)),
not the cached generated title. An agent can clear or replace the live
title before the view subscribes during load/resume; an identical later
patch correctly emits no event, so initial rendering must already match
canonical state.

The [controlled-load
regression](29767ed988/crates/agent_ui/src/conversation_view.rs (L5940))
holds the load response, drains early v1 notifications while no root
view exists and cached metadata still says "Old cached title", then
releases the response and separately asserts live/header/history state
and user override. It fails before the fix and passes after for early
clear, early replacement, and clear with a saved override. The existing
restored-command fixture is reused; no new production state or transport
handler..

Release Notes:

- Fixed ACP session title clearing and prevented programmatic title
updates from being saved as user renames.
2026-10-06 07:52:59 +00:00
Joseph T. Lyons
a1b71072e5
Remove nix version from Cargo.lock dependency reference (#65206)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_remote_server_linux_x86_64 (push) Blocked by required conditions
run_tests / check_remote_server_mac_aarch64 (push) Blocked by required conditions
run_tests / check_remote_server_windows_x86_64 (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
This PR makes Cargo happy, which keeps wanting to remove the redundant
nix version qualifier from Cargo.lock introduced in #65170.

Release Notes:

- N/A
2026-10-05 22:11:54 +00:00
Kirill Bulatov
285d975043
Improve Zed's startup time (#65170)
## First commit:

Avoid process enumeration during macOS startup
Read the real UID with getuid() instead of enumerating processes.
Keep the channel offsets, UID wrapping, and handshake unchanged.

Measurements (warm macOS launches):

- Time to presentation: median 525 ms -> 479 ms over 30 paired launches
(release-fast).

## Second commit: 

Reduce startup work and redraw before window reveal
Skip redundant settings recomputation, migration formatting, and
colour-scale construction.
Request a redraw of hidden macOS windows before revealing them.

Measurements (warm macOS launches):

- Startup work, time to selected presentation: paired median reductions
of 7.5 ms and 10.7 ms in two runs of 30 pairs.
- Window reveal, time to first captured text: paired median reduction of
18.4 ms over 30 pairs.

Release Notes:

- Slightly improved Zed's startup time in general case
- [GPUI] N/A
2026-10-05 20:30:23 +00:00
Kirill Bulatov
d544470d1d
Reduce the dependency footprint (#65176)
Follows-up https://github.com/zed-industries/zed/pull/64862 with similar
fixes:

* replaces a few dependencies that are almost not used, removes unused
dependencies
* removed unused features
* removes `test-support` dependencies from the regular tree
* cleans up build scripts

Despite the large diff, the changes are rather mechanical, split by
commits.
Result:
<img width="1172" height="77" alt="image"
src="https://github.com/user-attachments/assets/7d8aeb58-7cec-4246-8157-d07fc585f81f"
/>

Release Notes:

- N/A
- [GPUI] N/A
2026-10-05 12:44:26 +00:00
Finn Evers
533fe08cfb
language_core: Store path suffixes and modeline aliases as shared strings (#65128)
## Summary

This PR changes the path suffixes to be stored as SharedStrings instead.
With this as well as the toml crate bump here, we can save on some
clones.

Primarily though, this change is pulled out of
https://github.com/zed-industries/zed/pull/65047 where I want to change
the type again, and thus the changes here to `.into()` everything help
me to shrink the diff of the other PR.

Yet, in the meantime, this is a nice benefit to have that does improve
things a bit when cloning and allocating, thus splitting this out into
its own PR

Release Notes:

- N/A
2026-10-05 10:37:17 +00:00
Hamish Clark
c62f92d6aa
workspace: Fix cross-host workspace reuse (#64145)
# Objective

Prevent remote open requests from reusing a retained workspace connected
to a different host when both hosts contain the same absolute path.

A window can contain workspaces from multiple locations. Previously, the
window qualified for reuse when any retained workspace matched the
requested host, but path scoring subsequently considered every workspace
in that window. As a result, a workspace from another host could win.

This is a reworked and simplied version of the fix in
https://github.com/zed-industries/zed/pull/62561

## Solution

Filter each retained workspace by the requested location before scoring
its paths.

Workspace-location matching is centralized while preserving the existing
connection semantics:

- SSH matches by host, username, and port.
- WSL matches by distribution name because usernames are not
consistently populated.
- Docker matches by container ID.
- Mock connections match by ID.

## Testing

- Added a regression test with two distinct mock remote identities in
one window.
- Confirmed the regression test fails with the production fix stashed:
  - `a matching path on another remote must not satisfy the request`
- Confirmed the test passes with the fix:
- `cargo test -p recent_projects
test_find_existing_workspace_does_not_reuse_workspace_from_another_remote
--no-fail-fast`
- Confirmed the centralized remote identity tests pass:
  - `cargo test -p remote remote_identity --no-fail-fast`

## 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 remote paths sometimes reusing a workspace connected to a
different host.

Co-authored-by: Hamish <hamishc@users.noreply.github.com>
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
2026-10-05 09:49:47 +00:00
Oleksandr Kholiavko
3fec483014
tabular_data_preview: Single-cell focus and arrow navigation with reveal (1/8) (#64916)
## Overview

Part **1 of 8** in a series adding full keyboard/mouse navigation, cell
selection, multi-format clipboard copying, and keyboard-driven
sorting/filtering to `tabular_data_preview`.

Split into small, isolated PRs for review safety. The feature is gated
to debug/test builds (`cfg!(any(test, debug_assertions))`) until PR 6
(copying + context menus) to avoid exposing selection without copy
support.

---

### Full Series Roadmap

**1/8 (This PR):** Single-cell focus & arrow navigation with viewport
reveal
**2/8:** Range selection (`Shift+Arrows`), edge jumps
(`Cmd/Ctrl+Arrows`, `Home/End`), and page jumps (`PageUp/Down`)
**3/8:** Mouse selection, Shift+Click extension, and drag-to-select
**4/8:** Select All (`Cmd/Ctrl+A`) across datasets
**5/8:** Multi-format copy engine (TSV, CSV, Markdown, JSON Lines) &
`CopySelected`
**6/8:** Context menu, copy format settings, toasts, and release
enablement
**7/8:** Row selection via row gutter click/drag
**8/8:** Keyboard sorting (`Alt+S`), filter popover (`Alt+F`), and
filter clear (`Cmd/Ctrl+Alt+Backspace`)


NOTE, that all work is done & running on my machine end to end. The
split is just code review organization buerocracy.

<summary>
👇 Demo of fully ready feature👇 
</summary>
<details>


https://github.com/user-attachments/assets/696554f9-ca3e-4b74-83d1-948292668334



https://github.com/user-attachments/assets/5ef5f1f1-4f15-4b01-b825-de592d8a1972



https://github.com/user-attachments/assets/40c0e57f-da7a-440a-9ee6-48af8abe116e


</details>

---

### Changes in this PR (1/8)

1. **Data-Space Coordinates (`CellSelection`):** Coordinates anchor to
`DataCellId { row: DataRow, col: AnyColumn }` so selection survives
background sorting/filtering without shifting rows.
2. **Single-Cell Navigation (`tabular_data::MoveFocusedCell`):** Arrow
navigation (`Up`/`Down`/`Left`/`Right`), initializing focus at `(0, 0)`
on first movement.
3. **Viewport Auto-Scroll & Peek Cushion:** Auto-scrolls focused cells
with a 20px horizontal peek buffer and 1-row vertical context cushion.
4. **Focus & Outline:** Renders focused cell border
(`theme.colors().border_focused`) and binds `"context": "TableView"`.
5. **Debug Gating:** Hidden in release builds via
`is_selection_enabled()` until copying lands in PR 6.

---

Release Notes:

- N/A

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-10-03 01:03:39 +00:00
Cameron Mcloughlin
f37989fbdf
gpui: Cross-platform headless windowing API and linux impl (#64969)
Adds a cross-platform API for GPUI apps to switch between windowed and
headless modes.

Release Notes:

- N/A
- [GPUI]: N/A

---------

Co-authored-by: Antonio Scandurra <me@as-cii.com>
2026-10-02 16:04:33 +00:00
Finn Evers
9dd6993e2e
gpui_shared_string: Avoid intermediate string allocation when deserializing a SharedString (#65089)
## Summary

This PR improves how we deserialize SharedStrings. Since we moved to
`SmolStr` under the hood some time ago, which takes a string by `impl
AsRef<str>` in its constructor, we can get rid here of allocating a
string where possible in favor of using a stringvisitor during
deserialization. This provides us with some decent improvements.

## Testing

The benchmark results are the following:

| Case | `from_str` before | `from_str` after | Δ | 
|---|---:|---:|---:|
| short (≤23 B, inline) | 23.1 µs | 11.6 µs | −50% 
| short, escaped | 33.2 µs | 22.4 µs | −32% | 
| long (~66 B, heap) | 46.9 µs | 31.4 µs | −33% | 
| long, escaped | 307.6 µs | 267.6 µs | −13% | 

## Self-review

- [X] I've reviewed my diff for quality, security, reliability, and
performance.
- [-] UI changes follow the
[checklist](https://zed.dev/docs/development/ui-checklist).
- [-] Tests cover the new or changed behavior.

Release Notes:

- N/A
- [GPUI] Improved memory usage and performance when deserializing
SharedStrings.
2026-10-02 13:48:20 +00:00
Bennet Bo Fenner
309f91f564
copilot: Move enterprise URI to top-level setting (#65082)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / check_wasm (push) Blocked by required conditions
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / check_remote_server_linux_x86_64 (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_remote_server_mac_aarch64 (push) Blocked by required conditions
run_tests / check_remote_server_windows_x86_64 (push) Blocked by required conditions
This PR is moving the `enterprise` URI to a top level `copilot` settings
because it is used for both Edit Predictions and Copilot Chat.
Previously it was listed under `languages > copilot > enterprise_uri`

Release Notes:

- N/A
2026-10-02 11:22:04 +00:00
Anthony Eid
cd4fc8de4c
gpui: Journal platform frame requests and skipped frames (#64958)
## Summary

Pass captured platform frame request timing to `on_request_frame` and
emit foreground journal records. This PR provides timing data; it does
not classify platform waits or change latency histogram/reporting
policy.

`RequestFrameOptions` carries an optional captured time and a
native-callback/local-schedule source. A per-window atomic preserves the
earliest coalesced request timestamp and its matching source until
main-thread delivery. Journal records include window identity, captured
time when available, foreground handling time, and source. No request
IDs or second journal stream are introduced.

## Completed frame skips (retained for review)

Keep completed GPUI decisions not to render as sealing boundaries, with
no-render-needed, inactive-throttle, and thermal-throttle reasons. They
seal at foreground completion without satisfying or clearing pending
demand. Hang serialization uses `sealed_by: "frame_skipped"`.

Platform frame requests do not seal or count as foreground work.
Reentrant deferrals remain non-sealing raw diagnostic records with their
own window/time payload; they cannot be represented as completed skip
reasons or sealing skip boundaries. Raw point diagnostics are not copied
into snapshots. Hang qualification still uses foreground execution
durations and occupancy; infinite foreground hang detection remains
follow-up work.

The skip-sealing portion is intentionally retained for review and can be
split out if requested. The signal-to-present histogram, refresh
estimation, platform-wait filtering, and Frame Duration Report changes
are deferred. The complete prior checkpoint is preserved on
`platform-frame-latency-followup`; it is not a second PR yet.

## Platform sources

- **macOS:** CoreVideo’s supplied current host timestamp is converted to
an `Instant` using paired host-clock/local-clock samples, with
receipt-time fallback for invalid timestamps. Capture happens before
registry locking/coalescing; synchronous `displayLayer` and key-window
draws use call time. `WindowFrameSource::stop()` clears stale signals
after detaching the subscription.
- **Windows:** VSyncProvider time immediately after waiting, before
redraw invalidation. Compositor-paced waits are tagged `NativeCallback`;
failed or short waits followed by the existing fallback sleep are tagged
`LocalSchedule`. Coalescing retains the earliest timestamp and its
matching source together; hidden/minimized slots are cleared. Wait and
redraw behavior are unchanged.
- **Wayland:** compositor milliseconds converted against CLOCK_MONOTONIC
with wrapping subtraction and a 60-second plausibility bound;
receipt-time fallback. Demand pings retain enqueue time; retries retain
scheduled deadlines.
- **X11:** scheduled calloop refresh deadline; expose requests have no
captured time.
- **Web:** no captured timestamp yet, but requests are still journaled
with foreground handling time.

Captured-time option fields remain available regardless of the profiler
feature so independently featured backends share one API shape. Built-in
backends collect timestamps only with `gpui/profiler`: disabled capture
does not evaluate clock/conversion closures, the accumulator has no
timestamp storage or atomic operations, and callback delivery and actual
scheduling clocks remain unchanged.

Wayland's protocol does not guarantee the clock epoch. Windows fully
covered-window behavior and X11 compositor gating beyond the timer
remain limitations of these sources. Live compositor/display-off/lock
workflows remain unverified. Skip-boundary changes touch `journal.rs`
and `hang.rs`. This PR will merge before the parallel hang-watchdog
work; that follow-up PR will resolve its conflicts against these
changes.

## Verification

Latest feature-gating checks: the profiler-disabled capture regression
passed; enabled coalescing and window integration tests passed; macOS
and GPUI/Web Wasm compiled with profiling both disabled and enabled. An
optimized probe built from the shared implementation confirmed disabled
capture/accumulator paths contain no calls or atomic instructions.
Clippy, formatting, and whitespace checks passed. Latest-head CI passed
Linux, Windows, and macOS tests and Clippy, along with Wasm and style
checks.

Latest type/guard cleanup: seven focused journal, hang, and window tests
passed, along with the profiler-disabled GPUI library check, Clippy,
formatting, and whitespace checks. The consecutive profiler guards are
grouped without shortening the foreground-turn guard lifetime.

- Previous extracted checkpoint: `cargo test -p gpui --features profiler
--lib -- --test-threads=1`: **431 passed**.
- Focused TestPlatform tests exercise request/source emission and
pending demand surviving throttling, observing callback execution and
draw counts. No wall-clock sleeps are used by the new window tests.
- `corgi check -p gpui_macos --lib`: passed.
- `./script/clippy -p gpui -p gpui_macos -p input_latency_ui`: passed,
including repository hygiene checks.
- GPUI + Web Wasm check with profiler and repository CI
build-std/atomics flags: passed.
- Formatting and `git diff --check`: passed.

Corgi's parallel suite passed 436 of 437 tests but encountered the
previously observed hang-monitor shutdown channel timing failure. That
test passed in the serial Cargo suite and was not changed or disabled.

The preceding checkpoint passed Linux, Windows, macOS, and Wasm CI. CI
also passed on the current head, `3641f14ab0`. Local cross-target checks
remain constrained by missing Linux system libraries and Windows SDK
tooling on the macOS host.

## Suggested .rules additions

When manually driving platform frame requests in GPUI tests, account for
test-mode automatic draws during effect flushing. For throttle-routing
tests, configure a comfortably long throttle interval instead of relying
on wall-clock sleeps or short scheduling deadlines.

Release Notes:

- [GPUI] Added captured platform frame request timing and foreground
journal records, including sealing boundaries for completed decisions
not to render.
2026-10-01 19:52:10 +00:00
Finn Evers
06afd454ec
Remove leftover code from agent server extensions (#65031)
## Summary

This PR removes some leftover code from agent extensions that is no
longer in use.

Release Notes:

- N/A
2026-10-01 11:53:36 +00:00
Anthony Eid
40180d9c40
gpui_apple: Share dispatcher and Metal renderer with iOS (#64990)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_remote_server_linux_x86_64 (push) Blocked by required conditions
run_tests / check_remote_server_mac_aarch64 (push) Blocked by required conditions
run_tests / check_remote_server_windows_x86_64 (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
Prepares GPUI's shared Apple code for the upcoming iOS backend. macOS
behavior is unchanged except for the test-only screenshot path noted
below.

## Changes

- **Dispatcher:** moves `MacDispatcher` from `gpui_macos` into
`gpui_apple` as `AppleDispatcher`, and `MacActivity` as `AppleActivity`.
`is_main_thread` uses the typed `NSThread::isMainThread_class()` instead
of a raw `msg_send`. `gpui_macos` drops its now-unused `async-task`,
`libc`, and `mach2` dependencies.
- **Metal renderer:**
- Adds a safe `MetalRenderer::from_layer(&CAMetalLayer)` for layers
owned by a platform view (UIKit creates a view's backing layer itself).
Layer setup is shared with `new` through `configure_layer`.
- Removes `gpui_apple`'s dependencies on `cocoa` and `objc` 0.2. Layer
setters the `metal` crate doesn't bind now use typed `objc2-quartz-core`
methods; drawable sizing uses `CGSize`.
- iOS always uses shared storage, since managed storage doesn't exist
there (including in the simulator on Intel hosts). The atlas parameter
is renamed `supports_shared_storage` to reflect that.
- `render_scene_to_image` (tests and benchmarks only) now uses shared
storage on Apple Silicon, matching the atlas, and synchronizes whenever
the texture is managed. Intel Macs keep managed textures.
- **Surfaces:** `gpui`'s CoreVideo surface API (`gpui::surface`,
`SurfaceSource::Surface`, `Window::paint_surface`) is now available on
iOS as well as macOS, so the shared renderer no longer needs platform
stubs.
- **Build script:** chooses the Metal SDK from `CARGO_CFG_TARGET_OS` and
`CARGO_CFG_TARGET_ENV` (`macosx`, `iphoneos`, or `iphonesimulator`), so
`x86_64-apple-ios` builds use the simulator SDK. Other targets, such as
Mac Catalyst, fail with a clear error.
- **Cargo:** `gpui_apple` builds for macOS and iOS; `dispatch2` and
`objc2-quartz-core` become workspace dependencies.

## Verification

- `clippy` is clean and tests pass for `gpui`, `gpui_apple`,
`gpui_macos`, and `gpui_platform` on macOS; `gpui_macos` builds with
`runtime_shaders`.
- `cargo clippy -p gpui -p gpui_apple` is clean for
`aarch64-apple-ios-sim` and `x86_64-apple-ios`, including the Metal
shader build with the simulator SDK.
- Not verified at runtime on iOS; nothing on iOS uses these APIs until
the iOS backend lands.

Release Notes:

- [GPUI] Improved the shared Apple Metal renderer and dispatcher so they
can be used by an iOS backend, and made CoreVideo surfaces available on
iOS
2026-09-30 22:13:38 +00:00
Kirill Bulatov
8bbcd83968
Speed up project search over misclassified binary files (#64549)
Based on
https://github.com/zed-industries/zed/issues/38799#issuecomment-5758593194
finding.

Project search treated any NUL-free file as text, then read it whole,
ran chardetng over every byte (~34 MiB/s) and decoded it into a String
before searching. For raw assets (.yuv/.raw/.onnx/.glb/.tif in #38799)
that cost ~8 s and ~2.6× the file size in RAM per worker.

- Bound chardetng to a 1 MiB window starting at the first non-ASCII
byte.
- Stream-decode legacy/UTF-16 files in project search (`DecodingReader`)
instead of materializing them.
- Scan the single-line text pre-filter in 64 KiB blocks instead of
`read_line`.
- Run the control-byte check even without NULs; treat all high bytes as
text so legacy encodings (windows-1251, GBK, ...) stay text.
- Add magic numbers for TIFF, glTF, ELF, Mach-O, gzip/xz/zstd, SQLite,
HDF5, NumPy, safetensors, GGUF, fonts, media containers and others.
- Move the classifier into a `file_content` crate and use it for git
commit blobs too, replacing the separate NUL-only `is_binary_content`.

Measured on a 200 MiB NUL-free raw file: 8.5 s → ~1.5 s per file, no
whole-file allocation.

Release Notes:

- Improved project search speed and memory usage over misclassified
binary files
2026-09-30 17:39:08 +00:00
zed-zippy[bot]
e91af043a2
Bump Zed to v1.24.0 (#64991)
Release Notes:

- N/A

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Joseph T. Lyons <JosephTLyons@gmail.com>
2026-09-30 16:03:44 +00:00
Ben Brandt
e8c6c67fad
agent_servers: Decode v2 terminal notifications (#64985)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_remote_server_linux_x86_64 (push) Blocked by required conditions
run_tests / check_remote_server_mac_aarch64 (push) Blocked by required conditions
run_tests / check_remote_server_windows_x86_64 (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
Add a composable SDK v2 terminal-notification ingress component that
hands decoded updates to the existing shared terminal model.

- Decode output snapshots and each output chunk independently into raw
bytes, preserving split ANSI/UTF-8 sequences and arbitrary binary data.
Do not concatenate encoded chunks or introduce another output-history
store.
- Preserve omitted/null/value patch semantics and keep
notification-envelope, terminal, snapshot, exit, and chunk metadata in
their own scopes.
- Validate output before dispatch: malformed base64 or malformed
non-null snapshot shapes cannot apply sibling fields or create an unseen
terminal. Guard the SDK's malformed-output-to-`Undefined` normalization
explicitly.
- Sanitize SDK parse errors so warning logs do not echo complete
notification params.
- Claim only terminal updates/chunks. Forward other methods and update
kinds using the original untyped JSON, preserving unknown fields.
- Apply decoded updates only to a matching session, using the terminal
identity/replacement boundary from #64976.

## Review guide

1. [SDK handler and claiming/forwarding
boundary](b8578a587d/crates/agent_servers/src/acp.rs (L636-L674)):
terminal-only recognition, original-message fallthrough, and error
propagation.
2. [Decoded notification/application
types](b8578a587d/crates/agent_servers/src/acp/terminal_updates.rs (L8-L44))
and
[parser/decoder](b8578a587d/crates/agent_servers/src/acp/terminal_updates.rs (L47-L113)):
session isolation, byte decoding, tri-state fields, metadata scopes, and
sanitized errors.
3. [Real SDK-channel harness and
tests](b8578a587d/crates/agent_servers/src/acp.rs (L2627-L3190)):
actual v2 initialization, SDK-receive plus foreground-application
barriers, reference-first ordering, snapshot/append/replacement/clear,
atomic invalid-input rejection, and exact JSON forwarding.
4. [Decoder/parser
fixtures](b8578a587d/crates/agent_servers/src/acp/terminal_updates.rs (L115)):
absent/null/value, byte fidelity, independent chunks, and
private-payload error sanitization.

Release Notes:

- N/A
2026-09-30 14:31:57 +00:00
Danilo Leal
749a1df41d
Add announcement banner for Delta (#64963)
## Summary

This PR introduces an announcement banner for Delta that will be shown
in the next Zed release.

## Self-review

- [x] I've reviewed my diff for quality, security, reliability, and
performance.
- [x] UI changes follow the
[checklist](https://zed.dev/docs/development/ui-checklist).
- [x] Tests cover the new or changed behavior.

Release Notes:

- N/A
2026-09-30 12:03:51 +00:00
Ben Brandt
afecd6d719
node_runtime: Expose standalone system Node discovery (#64928)
Expose `SystemNode::discover` so callers can locate and validate Node
without also requiring npm or initializing Zed's cache. It accepts a
configured executable or an explicit search PATH, preserves the Node 22
minimum, and reports typed lookup, execution, and version errors with
guidance.

Zed's existing system runtime reuses the validation before its existing
npm setup. Configured overrides and PATH order remain authoritative.
Selected paths are made absolute without resolving symlinks, and
absolute executables remain usable after the process's working directory
is removed. Managed downloads and npm policy are unchanged.

Release Notes:

- N/A
2026-09-30 04:51:51 +00:00
Anthony Eid
0f9c923e67
Add a GPUI-owned hang monitor and make hang_telemetry a consumer (#64944)
## Summary

Zed and Delta each run their own hang-detection thread, thresholds,
batching and "Hang Incidents" wire schema; Delta's copy predates the
`hang_telemetry` extraction (#64874). This PR is the first step toward
one shared system that any GPUI app can use, and the place the upcoming
watchdog and stall classification will land once.

- **gpui:** adds `App::start_hang_monitor(HangMonitorConfig, on_poll)`.
GPUI spawns and owns a thread that polls the app's `HangDetector` every
`config.interval` and calls `on_poll` with a `HangMonitorPoll`
(incidents, first-present time, and whether it was an `Interval` or
`Flush` poll). When the app shuts down, GPUI requests a final `Flush`
poll without blocking and awaits it alongside the quit handlers, within
`SHUTDOWN_TIMEOUT`. Starting the monitor twice returns
`HangMonitorError::AlreadyStarted` (and debug-asserts); a thread spawn
failure returns `HangMonitorError::Spawn`. Not available on wasm.
- **`hang_telemetry`:** now a pure consumer of that API.
`HangTelemetry::new(startup, send_event).start(cx)` batches incidents
from polls and sends a batch every 30 minutes (including empty batches)
and on the shutdown flush. `with_incident_observer` receives each poll's
serialized incidents, for Delta's feedback-report hang list. The crate
owns no threads or quit handlers. Thresholds, the reporter and the wire
schema are unchanged.
- **Zed:** hang telemetry is `HangTelemetry::new(..).start(cx)` plus an
`on_app_quit` that flushes the telemetry queue. The legacy log and
task-trace loop keeps its own thread, renamed `HangLogging`. The unused
`spin` dependency is removed.

Behavior is unchanged except that the journal is first polled 1 s after
startup rather than 1.2 s (the 200 ms delay remains on the legacy log
loop it was written for).

Follow-ups: migrate Delta onto `hang_telemetry`; add the watchdog
(freeze detection, CPU-time stall classification) to the GPUI hang
monitor; share crash-report uploading in a separate PR.

## Testing

- New tests: `hang_monitor_polls_on_its_interval_and_on_flush`,
`app_flushes_its_hang_monitor_on_shutdown`,
`starting_the_hang_monitor_twice_is_rejected` (also run in release).
- `cargo test -p gpui --features profiler --lib -- profiler::` (58
passed), `cargo test -p hang_telemetry` (4 passed), `cargo check -p
zed`, wasm32 check of gpui, and `./script/clippy -p gpui -p
hang_telemetry -p zed` are clean.

Release Notes:

- [GPUI] Added `App::start_hang_monitor`, which polls the hang detector
on a GPUI-owned thread so hang detection keeps running while the
foreground is stalled, with a final flush on shutdown

---------

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Eric Holk <eric@zed.dev>
2026-09-29 20:19:48 +00:00
Anthony Eid
7232ba04ef
gpui: Drop foreground measurements that span an unnotified system suspend (#64891)
## Summary

Hang telemetry still reports foreground task polls lasting minutes to
hours, mostly on Windows. #64269 drops measurements interrupted by
sleep, but it relies on power notifications. Those are delivered on the
foreground thread, so when the system suspends mid-poll, the poll
finishes and is recorded *before* the notification is handled. On
Windows the notification can also be dropped. The Windows clock behind
`Instant` (QPC) keeps counting through sleep, so one missed ordering
becomes an hours-long "stall".

This change makes each measurement check a suspend clock, with no
dependence on notification ordering.

## How it works

- `system_suspended_time()` returns total time suspended since boot, as
the difference between a clock that counts suspended time and one that
doesn't. Every read is served from kernel-mapped memory, with no syscall
on the normal path:
  - **Linux/Android:** `CLOCK_BOOTTIME − CLOCK_MONOTONIC`
- **macOS:** `mach_continuous_time() − mach_absolute_time()`
(`<mach/mach_time.h>` documents the former as "like mach_absolute_time,
but advances during sleep"), converted with a cached
`mach_timebase_info`. Measured at ~4 ns per read on Apple silicon.
  - **Windows:** `QueryInterruptTime − QueryUnbiasedInterruptTime`
- **Other platforms:** `None`, which keeps the notification-only
behavior.
- `detect_suspend` runs at the start of each foreground turn (before the
turn's work takes its start time, so a suspend while idle never drops
later work) and wherever a measurement ends (task poll end,
`power_interrupted_since`, `frame_sample_is_valid`). If suspended time
grew by at least 50 ms (`MIN_DETECTED_SUSPEND`, above Windows'
up-to-15.6 ms tick jitter), it runs the same `interrupt_measurements`
routine a power notification runs:
- seals the open interval with a `PowerTransition` boundary, so earlier
small work can't add up to a budget incident across the suspend;
- sets `power_changed_at`, so any measurement that started before it is
dropped;
  - clears pending `dirty_at` for each window.
- Handling a power notification refreshes the stored reading, so a
notified suspend isn't counted twice.
- Measurements that span a suspend are dropped rather than corrected: on
Linux, process freeze and thaw around the suspend add seconds that no
clock excludes.

`MEASUREMENT_VERSION` stays at 2; it will be bumped once alongside the
planned schema changes.

Dependencies: `gpui` gains a direct `libc` dependency on Linux/Android
only (it was already in the build graph through 15+ dependencies at the
same version), and the `Win32_System_WindowsProgramming` feature of the
existing `windows` dependency. The macOS mach functions are declared in
a small `extern "C"` block because libc deprecates its mach bindings.

## Not covered

- Freezes where the system stays awake (debugger, SIGSTOP, cgroup
freezer) and genuinely blocked polls. A follow-up watchdog will classify
these.
- Hangs that never complete.

## Testing

- New tests: a poll spanning an un-notified suspend is dropped, a
boundary is emitted, and the pending frame is cleared; notified suspends
and sub-threshold jitter do not interrupt. Journals installed by tests
use a fake suspend clock, so a real suspend during a test run can't
affect results.
- `cargo test -p gpui --features profiler --lib -- profiler::`: 55
passed. `./script/clippy -p gpui --features profiler` and `cargo fmt`
are clean. `cargo check` passes for `x86_64-unknown-linux-gnu` and
`x86_64-pc-windows-msvc`.
- Manual test on macOS (Apple silicon, debug build) with a temporary
action that blocks the foreground executor for 60 s:
- Control, no sleep: a `Threshold` incident of ~10,000 ms is reported
for a 10 s block.
- Lid closed during the 60 s block: `pmset -g log` shows Clamshell Sleep
at 10:32:27 and wake at 10:34:01. The block ended at 10:34:17 (144 s
wall clock), the suspend clock detected 84.2 s suspended, and **no**
hang incident was reported for the block.
- Note: macOS delays sleep for up to 30 s while an
`NSWorkspaceWillSleepNotification` observer is blocked (`pmset` logged
`zed timed out(30000 ms)`), so on macOS only polls longer than ~30 s can
span a suspend. Windows and Linux are not yet manually tested.

Release Notes:

- [GPUI] Improved hang telemetry accuracy by dropping foreground
measurements that span a system suspend, even when the platform's sleep
notification arrives late or not at all
2026-09-29 16:23:47 +00:00
Quinn Shanahan
c87632ef44
Read remote shell config when creating a terminal shell (#61451)
# Objective

- Makes shell for remote configurable.
- fixes #35226 

## Solution

- Adds rpc so client can retrieve terminal settings from remote server
- Vibe coded with codex Sol, I did my best to review it and make sure
it's the minimal changes.
- Added terminal dependency to remote_server, rather than a larger
change (e.g. adding something to project to expose terminal shell
setting to remote_server)

## Testing

- Tested and works Windows client / linux remote server

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable


---

Release Notes:

- Added support for terminal.shell in remote sessions

---------

Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
2026-09-29 13:38:22 +00:00
Joep Joosten
12f79c0aeb
cloud_api_client: Use the platform TLS verifier for the cloud websocket (#63686)
# Objective

Fixes #63683

Behind a corporate TLS-inspecting proxy (e.g. Zscaler) whose root CA is
installed in the OS trust store, the Zed Cloud websocket fails
permanently with `invalid peer certificate: UnknownIssuer`, while every
other connection in Zed works.

`crates/cloud_api_client/src/websocket/native.rs` calls
`yawc::WebSocket::connect` without a TLS connector. yawc's default
connector trusts only the bundled `webpki-roots`, so it never consults
the platform trust store. Everything else in Zed (the reqwest HTTP
client and the collab websocket in `crates/client`) uses
`http_client_tls::tls_config()`, which is built on
`rustls-platform-verifier`.

## Solution

Pass a `tokio_rustls::TlsConnector` built from
`http_client_tls::tls_config()` to yawc via
`WebSocketBuilder::with_connector`, so the cloud websocket verifies
certificates exactly like the collab websocket does
(`client_async_tls_with_connector_and_config(...,
Some(Arc::new(http_client_tls::tls_config()).into()), ...)`).

`cloud_api_client` gains two non-wasm dependencies: `http_client_tls`
(workspace crate) and `tokio-rustls` (same `0.26` line yawc and `client`
already use, no default features).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01Ub1SNsrgWjTA6iAKanKfwt

## Testing

- `cargo check -p cloud_api_client` and `cargo fmt --check` on macOS
(arm64).
- Reproduced the bug and validated the approach with a standalone rustls
probe against `cloud.zed.dev` / `collab.zed.dev` from behind Zscaler:
- `webpki_roots::TLS_SERVER_ROOTS` only (yawc's default):
`InvalidCertificate(UnknownIssuer)` – identical to the error in the Zed
log
- `ClientConfig::with_platform_verifier()` (what `tls_config()`
returns): connects fine
- Reviewers behind a TLS-inspecting proxy can confirm by watching
`~/Library/Logs/Zed/Zed.log` for `cloud websocket connect failed:
invalid peer certificate: UnknownIssuer` before and after.
- I could not test on Windows or Linux, but the change only routes the
cloud websocket through the same `tls_config()` those platforms already
use for all other HTTPS traffic.

## 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:

- Fixed the Zed Cloud connection failing with `UnknownIssuer` behind
corporate TLS-inspecting proxies whose root CA is installed in the
system trust store.

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Finn Evers <finn@zed.dev>
2026-09-29 10:23:00 +00:00
Conrad Irwin
dd510f99e0
language_models_cloud: Classify LLM token failures as provider rejections (#64754)
`CloudLlmTokenProvider` returned `anyhow::Result`, and
`authenticated_llm_request` reported every failure, including failing to
mint an LLM token, as `LanguageModelCompletionError::HttpSend`. An
expired session (401) or a missing subscription (402) during token
minting therefore looked like a connectivity problem: the agent panel
showed a stream error, and retry logic treated it as transient.
Downstream consumers (Delta) had to dig typed errors back out of the
`anyhow` chain to recover the real cause.

This PR:

- Changes `CloudLlmTokenProvider::cached_token`/`refresh_token` to
return `Result<String, ClientApiError>`, and
`Client::{cached,refresh,clear_and_refresh}_llm_token` to match.
- Adds `LlmRequestError`, returned by `authenticated_llm_request`, which
separates token acquisition failures from building or sending the
request.
- Adds `LlmRequestError::into_completion_error`, which maps:
- `Unauthorized`/`NotSignedIn` to a Zed `Authentication` rejection (not
retried),
  - a token-endpoint 402 to the existing `PaymentRequired` rejection,
- other token-endpoint statuses by HTTP status (for example 403 to
`Permission`, 5xx to retryable `InternalServer`),
  - connection failures and send failures to `HttpSend`, as before.

In Zed, a token failure caused by an expired session now shows the agent
panel's authentication error instead of a stream error. Messages stay
neutral about whose credentials were rejected so callers can choose
wording from the category.

Release Notes:

- Improved the agent panel error shown when a Zed sign-in has expired.
2026-09-28 19:11:12 +00:00
Anthony Eid
3135cdf8dc
gpui: Add randomized element tree benchmarks and fix Linux benchmark leaks (#64842)
Adds a seeded, randomized element tree for benchmarking GPUI rendering,
and a Criterion suite that measures what one frame costs under each
class of change. Running it on Linux exposed thread leaks in the
benchmark harness and in the Linux dispatcher that made every
`#[gpui::bench]` binary slow down as it ran; those are fixed here too.

## Randomized element tree (`gpui::randomized_element_tree`, behind
`bench-support`)

A tree of elements and entities generated from a `StdRng`, with wide,
deep, mixed and narrow topologies, entity-backed elements, and
interaction handlers. It supports the mutations a UI goes through (child
color and bounds, root bounds, insert, leaf removal, reorder, recoloring
a share of the tree either localized to one entity subtree or spread
out) and counts what re-rendered, so benchmarks can assert the renderer
did the work. `RandomizedElementTreeBounds` describes a family of trees
(topologies, element-count and density ranges) and `sample(&mut rng)`
draws one.

## Benchmarks (`gpui_platform/benches/randomized_element_tree.rs`)

Groups, each measuring frames in which exactly one thing happens: full
refresh (`Window::refresh`), unchanged (a notified root), leaf style,
leaf bounds, root layout, insert-remove, reorder, and a changing-share
grid (0/1/5/25/100% localized, 5/25% spread).

- **Families:** `any`, `wide`, `tall`, `mixed` and `dense-entities`,
each with at least 5% entities. Each family is a `#[gpui::bench]` input
seeded through the `StdRng` support from #64843, so ids read
`RandomizedTree/<group>/tree/<family>/seed-<n>` and `SEED`/`ITERATIONS`
choose trees as they choose `#[gpui::test]` seeds. The family name is
mixed into the RNG so overlapping families don't draw the same tree at
the same seed.
- **Reports:** each tree is described once with the heap its window
holds after the first frame. The bench report adds instructions,
allocations and frame timings from `bench_metrics`, and a final summary
prints each group and family's geometric mean of time and allocations
per iteration across seeds.
- **Run time:** two seeds per family (one for the changing-share grid)
and a 0.5 s warm-up with a 1 s measurement: 105 benchmarks in about 4.5
minutes on Linux. `ITERATIONS=6`, `--warm-up-time` and
`--measurement-time` give a longer run.
- **Checks:** every measured loop asserts that the tree actually
re-rendered, so a faster frame that skipped the changed element fails
rather than passing as an improvement.

```
cargo bench -p gpui_platform --features bench-support --bench randomized_element_tree [-- FILTER]
```

## Linux fixes for `#[gpui::bench]` and the dispatcher

On Linux the full suite reached thousands of threads and took about 40
minutes, each benchmark slower than the last. Measured frame times are
unchanged by these fixes.

- **A platform per routine call.** `#[gpui::bench]` builds a context for
every Criterion routine call, and each built a whole
`gpui_platform::current_platform(true)` just to take its text system.
`gpui_platform::bench_text_system()` now builds it once per thread.
- **A GPU device per window.** `WgpuHeadlessRenderer::new` created a new
wgpu device each time, about 65 ms per call. `WgpuContext::new_headless`
now shares one device per process, held in a static that is never
dropped (wgpu's queue reads its own thread-locals on drop, so a
thread-local cache aborted on thread exit), and creates a new one if it
is lost. Device errors are tracked per device, so a renderer joining a
shared device observes only errors raised from then on.
- **Dispatcher threads outlived their platform.** Dropping a Linux
platform left all 21 threads running. Workers block in
`PriorityQueueReceiver::recv`, which checked for dropped senders only
before waiting, and dropping the last sender never signalled the
condition variable. It now wakes every waiter (acquiring the queue lock
first so no receiver misses the wake-up), `recv` re-checks after each
wake, and the timer thread's event loop stops when its channel closes. A
regression test fails on the old code and passes with the fix. The
editor builds one platform per process, so it isn't affected in
practice; benchmarks, visual tests, and
`gpui_platform::background_executor()` are.

## Validation

On Linux:
- Full suite: 105 benchmarks in 262 s, none failing, with the thread
count flat (about 63 to 68) and live heap between routine calls flat (6
to 8 MB). Before the fixes: about 40 minutes, 2,315 threads 20 s into a
group.
- One frame per iteration: window draws equal iterations exactly, and
each iteration renders the root once and every element once.
- `gpui` (437, run on one thread, since 4 profiler and `bench_context`
tests share global state and also fail in parallel on `main`) and
`gpui_linux` (42) tests pass; clippy and fmt are clean.

On `main`, every class of change costs about the same as a full refresh,
and the changing-share grid is flat from 1% to 100%, because any notify
re-renders the whole tree. That's the curve retained rendering should
bend.

Release Notes:

- [GPUI] Added randomized element tree benchmarks, and fixed Linux
platform threads not exiting when the platform is dropped and
`#[gpui::bench]` creating a platform and GPU device for every iteration

---------

Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
2026-09-28 16:17:17 +00:00
Ben Brandt
986828d157
acp_thread: Add shared tool-call state and diff previews (#64875)
Review Thread:
https://delta.dev/trunk/join/thread_01m2swv74pzp4c6xk46sh19fmk#s=pVggqzly

Normalize legacy ACP tool reports and SDK v2 tool patches into one
shared `ToolCall` model, preserving protocol source separately from
local decisions and rendered views.

- Retain reported kind/status, first-class name, metadata, and complete
tool-content sources, including unknown v2 values and envelope metadata.
- Keep authorization ownership and local outcomes separate from reported
status. Support omitted/null/value patches without changing legacy
permission-continuation behavior.
- Preserve the status-before-content-validation contract: invalid
presentation cannot roll back a terminal report or leave its permission
unresolved.
- Render supported v2 patches with read-only diff editors using `diffy`.
Preserve sparse hunk coordinates, multi-file structure,
additions/deletions, and original source without reading or modifying
workspace files. Accept standalone unified patches and unambiguous bare
hunks; retain explicit fallback and export text for unsupported input.
- Keep native live diffs separate from protocol snapshots, preserve
render identity on metadata-only updates, and align patch
expansion/search with visible authorization content.

This adds the shared model and presentation boundary; it does **not**
enable v2 transport negotiation or change prompt lifecycle. Existing
v1/native adapters continue to work. The existing
one-active-authorization-per-tool policy is unchanged.

Release Notes:

- N/A
2026-09-28 15:53:24 +00:00
Finn Evers
447f72e516
xtask: Add validation layer for GPUI commands (#64869)
## Summary

This PR adds a validation step to the GPUI publishing plan, ensuring
that crates there have proper licenses and that we do not face duplicate
crate names (this one is acutally currently violated but something to
fix separately).

Release Notes:

- N/A
2026-09-28 14:38:57 +00:00
Anthony Eid
1b572a2bd0
Extract hang telemetry into a reusable hang_telemetry crate (#64874)
Moves the "Hang Incidents" telemetry pipeline out of the `zed` binary
crate into a new `hang_telemetry` library crate, so other GPUI apps
(Delta) can depend on it instead of keeping a copy of the reporter.
Updating the telemetry schema in Zed then only requires bumping the Zed
dependency in those apps to get the same schema.

The crate owns everything that defines the data:

- `hang_threshold()` and `frame_budget()`, which decide what counts as
an incident
- `HangTelemetry`, which polls a `HangDetector` over the foreground
journal, serializes incidents relative to startup, and batches them
(largest 10 stalls, threshold/budget counts, stall p50/p95/max, 30
minute send interval)
- the event name and property shape, returned as a
`telemetry_events::FlexibleEvent`

Delivery stays with the app: Zed sends the event with
`telemetry::send_event`, while other apps route it through their own
telemetry pipeline. `crates/zed/src/reliability/hang_detection.rs` now
uses the crate; logging, task traces, and the dev hang actions are
unchanged, and the emitted event is identical to before.

Tests covering batching, counter/histogram resets, empty report windows,
and the exact wire shape live in the new crate.

Release Notes:

- N/A

---------

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-09-28 14:27:46 +00:00
Xin Zhao
98f75a23bc
Remove some unnecessary dependencies (#64862)
## Summary

Some dependencies were originally introduced for only a few specific
functions that can either be fulfilled by existing dependencies or
easily implemented in-tree. This PR removes or replaces them:

1. `json_dotpath`: Removed. We do not use the dot-path query feature;
standard methods in `serde_json` are sufficient for our use case.
2. `crossbeam`: Replaced with the more lightweight `crossbeam-queue`.
3. `take-until`: Removed. Calls to `take_until` are replaced with
`take_while_inclusive` from `itertools`, which is already widely used in
Zed.
4. `x11-clipboard`: Removed. It is deprecated and was only an unused
entry left in `Cargo.toml`.
5. `portable-pty`: Removed. We only used the `ExitStatus` transformation
logic from this crate, which has now been inlined into the Zed codebase.

Together, these changes reduce the total crate count from 1,727 to 1,717
during a Linux `cargo build`, slightly improving compile times.

## Testing

This is a refactoring PR with no functional changes. Existing tests were
run locally to ensure no regressions were introduced.

## Self-review

- [x] I've reviewed my diff for quality, security, reliability, and
performance.
- [ ] UI changes follow the
[checklist](https://zed.dev/docs/development/ui-checklist).
- [ ] Tests cover the new or changed behavior.

Release Notes:

- N/A
- [GPUI] N/A
2026-09-28 08:56:15 +00:00
Anthony Eid
e683fd7b46
gpui: Add bench_metrics for multi-metric Criterion benchmarks (#64753)
GPUI benchmarks measured only wall time, which is noisy enough on shared
CI runners that a regression must be large before Criterion flags it.
This PR adds a `bench_metrics` crate that records several metrics per
Criterion sample and reports them alongside Criterion's own analysis,
and wires GPUI's benchmark harness to it. Nothing in `bench_metrics`
depends on GPUI, so any Criterion benchmark in the workspace can adopt
it.

**What a benchmark now prints** (Linux, hardware counters available):

```
closed_inspector_grid/case/100-nodes-0-cycles
                        time:   [273.99 µs 274.78 µs 276.04 µs]
GPUI bench report (all observed iterations): closed_inspector_grid/case/100-nodes-0-cycles
  instructions per iteration: median 5.791 M instructions (min 5.788, max 5.880, samples 22)
  foreground instructions per iteration: median 5.791 M instructions (...)
  cycles per iteration: median 1.453 M cycles (...)
  branch misses per iteration: median 1.856 K branch misses (...)
  cache misses per iteration: median 123.008 cache misses (...)
  foreground context switches per iteration: median 0.000 context switches (...)
  page faults per iteration: median 0.000 page faults (...)
  IPC: median 3.996 (min 3.349, max 4.063, samples 22)
  foreground share of instructions: median 1.000 (...)
```

Criterion analyzes one metric (the *primary*; wall time by default) and
the rest are *secondaries* taken over the same iterations.
`BENCH_MEASUREMENT=instructions` makes process-wide retired instructions
the primary, and `BENCH_MEASUREMENT=foreground-instructions` the
benchmark thread's alone; both are near-deterministic, so a ~0.01%
interval is typical and small regressions are detectable, with wall time
demoted to the report. `BENCH_MEASUREMENT=wall-time` disables all
counters. Counters that can't be opened (no `CAP_PERFMON`, Docker
seccomp, VMs without a PMU, Intel Macs) are skipped with one note, so
`cargo bench` never fails by default; the instruction modes fail fast so
CI can't silently measure the wrong thing.

**Sources.** `HardwareCounter` is platform-neutral over per-OS backends.
On Linux it uses `perf_event_open`: counters are opened once per process
with `inherit` so every later thread is covered, read as deltas per
sample (~150 ns per counter), with hybrid-CPU encodings parsed from
sysfs and multiplexing scaled with a one-time warning. On Apple Silicon
it reads `proc_pid_rusage` and `thread_selfcounts`, which are
unprivileged, for instructions and cycles; branch and cache events need
`kperf` and stay Linux-only. `ResourceCounter` reads `getrusage` for
voluntary context switches on the foreground thread (the waits
instructions can't see) and minor page faults, with no privileges.

Foreground-thread instructions are counted separately from the process
total, so work shifting between GPUI's foreground and background threads
is visible even when the total is flat; with a headless renderer the gap
is driver-thread submission work (about 7% of a small Metal frame).

**Design.** `BenchMeasurement` type-erases the primary so
`#[gpui::bench]` functions and `BenchAppContext` need no type parameter;
`with_secondary`/`with_ratio` add metrics; `bench_group!` still
delegates to `criterion_group!`. Plain Criterion benches opt in with a
`config =` line and `MetricReport::iter` (documented in the gpui-bench
skill; wiring `rope` etc. is a follow-up). Reports are now emitted per
input for `inputs = ...` benchmarks, since per-iteration metrics blended
across inputs are meaningless. Criterion is bumped to 0.8.2, which also
randomizes stack alignment per sample.

**Verified** on Linux (hybrid Alder Lake) and an M-series Mac: every
mode on `inspector_render` and `editor_render`; counter denial via
seccomp on Linux; `bench_metrics` and `gpui` `bench_context` tests
including thread-scope inclusion/exclusion through real counters on both
platforms.

**Follow-ups:** counting-allocator metric (peak heap, allocations),
wiring non-GPUI benches, per-secondary baseline comparison.

Release Notes:

- [GPUI] Improved benchmarks to report retired instructions, cycles,
IPC, foreground-thread share, cache and branch misses, context switches,
and page faults per iteration alongside wall time, with
`BENCH_MEASUREMENT=instructions` or `=foreground-instructions` selecting
near-deterministic instruction counts as the Criterion-analyzed metric
for CI regression detection
2026-09-27 17:37:29 +00:00
Kirill Bulatov
4c841aaf1c
Remove unused features from dependencies (#64826)
Release Notes:

- N/A
2026-09-27 16:19:10 +00:00
Anthony Eid
e91b82c106
gpui_wgpu: Add Linux headless rendering (#64718)
## Summary

Add Linux WGPU headless rendering for GPUI tests and benchmarks without
creating a display surface or window.

- Extract a concrete `WgpuRendererCore` shared by the windowed and
headless wrappers, retaining production pipelines, atlas handling, and
frame encoding.
- Reuse an offscreen render target between same-size frames. Normal
rendering submits GPU work without screenshot readback; image capture
performs aligned readback and returns RGBA pixels.
- Reuse adapter ranking, including the `ZED_DEVICE_ID` preference.
Reject software adapters by default, with an explicit software-allowed
constructor for functional tests.
- Wire Linux platform selection through separate `bench-support` and
`test-support` features. Propagate initialization failures rather than
silently running a benchmark without a renderer.
- Preserve upstream atlas bind-group caching and window lifecycle
behavior.

This is a fresh implementation following discussion of #62341, not a
continuation of that PR. It does not include a Criterion upgrade,
hardware counters, benchmark CI, or GPU timing queries.

## Validation

After merging `origin/main` at `baee1ca6de`:

- `cargo test -p gpui_wgpu` — 38 tests passed.
- `cargo test -p gpui_wgpu --features test-support` — passed.
- `env -u DISPLAY -u WAYLAND_DISPLAY cargo test -p gpui_wgpu
headless_renderer` — passed.
- `cargo check -p gpui_platform --features bench-support` — passed.
- `cargo check -p gpui_platform --features 'test-support,wayland,x11'` —
passed.
- `cargo check -p gpui_wgpu --target wasm32-unknown-unknown` — passed.
- Formatting and diff checks passed.
- Verified the `gpui_wgpu` benchmark feature graph does not enable
`test-support`.

Windowed rendering and device recovery have compile coverage but have
not been manually exercised after the refactor. Headless timings
represent CPU rendering/submission, not display latency or
GPU-completion time.

## Suggested .rules additions

For `gpui_wgpu`: Tests requiring GPUI test contexts must be gated on
`test-support`, rather than enabling that feature unconditionally in a
dev dependency. Cargo unifies dev-dependency features into this crate's
benchmark targets.

Release Notes:

- [GPUI] Added headless renderer support for WGPU on Linux for
benchmarks and testing.
2026-09-25 17:49:48 +00:00
Mikayla Maki
975845875b
language_model: Make LanguageModel plain data served by its provider (#64750)
`LanguageModel` used to be a trait object. Each provider implemented it
on a private struct that bundled the model's metadata with the client,
credentials, rate limiter and a snapshot of its config, and consumers
held `Arc<dyn LanguageModel>` or a `ConfiguredModel { provider, model }`
pair.

This makes `LanguageModel` plain data: a `Clone + Debug + PartialEq`
struct with the same getters the trait had, held by value everywhere.
`ConfiguredModel` is gone. Providers serve requests themselves:
`LanguageModelProvider` gains `stream_completion` (plus the text/tool
helpers, `count_input_tokens`, `compact` and `api_key`), each taking
`&LanguageModel`. Senders look the provider up with
`LanguageModelRegistry::provider_for_model` when they send.

Every provider now has one lookup that decides which models it offers
and with what config. `provided_models` and the defaults are built from
it, and each request resolves the model's current config from it by id.
There are no per-model or per-request objects. A model the provider no
longer offers fails with a new, non-retried
`LanguageModelCompletionError::ModelUnavailable` instead of being served
from a stale snapshot.

This prepares for opening provider-side sessions over an append-only
message log. With models as plain data and requests on the provider, a
session can be one generic type rather than one per provider, and
deciding whether a session can be reused becomes a value comparison.

## Suggested reading order

1. `crates/language_model/src/language_model.rs` (the struct and
provider trait), `registry.rs`, and `fake_provider.rs`.
2. One representative provider:
`crates/language_models/src/provider/anthropic.rs`.
3. Providers that deviate: `bedrock.rs`, `llama_cpp.rs`,
`open_router.rs`, `crates/copilot_chat`, `crates/language_models_cloud`,
`crates/openai_subscribed`, `crates/x_ai_subscribed`.
4. Callers: `crates/agent/src/thread.rs`, then `agent_ui`, `git_ui`,
`sidebar`. Most of the remaining diff is tests.

## Behavior changes worth reviewing

- Rate limiting is one concurrency limit per model id, shared across the
app, with a limit of 16. Before, each model instance had its own limit
of 4.
- `Thread::refresh_model` re-selects a thread's model by id when its
provider reports a state change, so capability changes (for example a
llama.cpp model finishing loading) reach the thread.
- Bedrock resolves auth once per request for both Converse and Mantle,
off the foreground thread, with the SDK's default 5s credential load
timeout. Expiring credentials (SSO, STS, credential processes) are
cached until shortly before expiry and dropped on any auth change;
credentials without an expiry are re-read every request, so credential
files rewritten by external tools take effect immediately. Mantle
credential resolution now goes through Zed's HTTP client, like Converse.
- Bedrock honors `AWS_BEARER_TOKEN_BEDROCK`, then `AWS_BEARER_TOKEN`
(even if empty), over AWS credentials unless an API key is configured in
Zed, matching the SDK. This now applies to Mantle too, so users with
IAM/profile auth and one of these variables set must unset it (not empty
it) for Mantle to use IAM/profile.
- A Bedrock Mantle model with the same id as a Converse model replaces
it, so each id is offered and served once.
- OpenRouter and Vercel AI Gateway report default-model metadata from
the same lookup they serve requests from.
- A request for a model that has left a provider's list (for example
after signing out of Copilot or Zed) returns `ModelUnavailable`. Commit
message generation shows this as an error instead of doing nothing.

## Tests

`FakeLanguageModel` is gone. `FakeLanguageModelProvider` serves any
model id and owns every request sent to it; tests answer a request by
naming its model (`send_last_text(&model, ...)`, `send_text(&model,
&request, ...)`), so requests to different models can't be confused.

Tested: `agent` (753 tests), `language_model`, `language_models`,
`language_models_cloud`, `copilot_chat`, `openai_subscribed` and
`x_ai_subscribed`, plus `cargo check --workspace --tests`. The
`agent_ui`, `git_ui` and `sidebar` test binaries type-check but were not
run locally because of a linker issue in my environment; CI will cover
them. Providers have not yet been exercised against live services.

Release Notes:

- N/A
2026-09-25 17:08:34 +00:00
Max Brunsfeld
7fdb97cad5
cloud_api_client: Update yawc to 0.4.2 (#64728)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_remote_server_linux_x86_64 (push) Blocked by required conditions
run_tests / check_remote_server_mac_aarch64 (push) Blocked by required conditions
run_tests / check_remote_server_windows_x86_64 (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
Moves `cloud_api_client` off the `zed-industries/yawc` fork pin
(`71a452f`) to the upstream crates.io release, `yawc` 0.4.2.

The fork's only commit beyond upstream was an earlier version of a wasm
connect fix. Upstream shipped a more complete fix in 0.4.0
([infinitefield/yawc@f1c6317](f1c6317eff)):

- `connect` settles on the browser's `open`, `error`, or `close` event.
- The wasm `WebSocket` owns its event handlers instead of leaking them
with `Closure::forget`.
- `Drop` unregisters the handlers and calls `close()`, including when
the connect future is dropped mid-handshake.

That last point matters for the web Cloud client, which drops a pending
connect after 30 seconds. With the fork, the abandoned browser socket
kept handshaking indefinitely. Delta hit the same leak in its web client
and has already moved to 0.4.2.

The other changes between the fork and 0.4.2 are native-only: opt-in
HTTP/2 WebSockets, SOCKS5 proxy support, and a deflate decompression
fix. The APIs `cloud_api_client` uses are unchanged. The lock file also
picks up `send_wrapper` and bumps `hyper` to 1.11 and `h2` to 0.4.19,
which `yawc` 0.4.2 requires.

Checked with `cargo check -p cloud_api_client` for native and
`wasm32-unknown-unknown`.

Release Notes:

- N/A
2026-09-24 23:32:55 +00:00
Ansh Dawda
d528c665e1
Add JSONL and NDJSON support to tabular preview (#64471)
## Objective

Extend the existing tabular preview to support `.jsonl` and `.ndjson`
files, making it easier to compare fields across records.

Discussed in https://github.com/zed-industries/zed/discussions/62917.

## Solution

Parse each nonblank line as a JSON object and reuse the existing table
preview. Top-level keys become columns in first-seen order, with new
keys from later records appended to the right.

- Preserve JSON values, including large numbers, without numeric
conversion.
- Display nested objects and arrays as compact JSON.
- Keep missing fields, `null`, `"null"`, and empty strings distinct.
- Show invalid-record errors with source line numbers and recover after
edits.
- Preserve sorting and filters unless column names or order change.
- Add JSONL/NDJSON to the existing preview shortcuts and document the
behavior.

Also fix a crash found during CSV regression testing: deleting rows
could leave the renderer using an old row mapping against shorter data.
Clear the mapping and virtual list together before recomputing them.

The preview remains read-only, accepts object records only, and uses the
existing text-based sorting and full-file parsing behavior.

## Testing

- All 20 tests in `tabular_data_preview` passed.
- The multiline CSV deletion regression passed across 20 scheduler
seeds.
- `cargo fmt -p tabular_data_preview -- --check` passed.
- `./script/clippy -p tabular_data_preview` passed.
- `cargo build -p zed --bin zed` passed.
- `git diff --check` passed.
- Manual QA on macOS, including retesting the reported CSV crash.

Windows and Linux were not tested locally. Large-file performance has
not been benchmarked.

To try it, open a `.jsonl` or `.ndjson` file and run `tabular data: open
preview` or `tabular data: open preview to the side`.

## 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
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

<img width="2358" height="1576" alt="image"
src="https://github.com/user-attachments/assets/8f7e7725-5a5c-465d-aa0a-d61cbb22d04f"
/>

The example shows source-order columns, fields introduced by later
records, nested values, and the distinction between missing values,
nulls, and strings.

Release Notes:

- Added JSONL and NDJSON support to the tabular data preview.

---------

Co-authored-by: Anthony Eid <anthony@zed.dev>
2026-09-24 15:04:16 +00:00
Sudarsh
6990d3f678
git_ui: Fix missing language injections in historical file buffer (#64683)
Buffers built for the commit view (git history -> open excerpts) were
assigned a language without attaching the language registry, so injected
grammars (Markdown-Inline, fenced code block languages) could not be
resolved and their captures went unstyled.

Attach the registry before assigning the language, matching the pattern
in text_diff_view.rs, and add a regression test asserting that a buffer
built via build_buffer parses with Markdown-Inline layers.

Fixes #64577 

# Objective

- Describe the objective or issue this PR addresses.
- If you're fixing a specific issue, use "Fixes #X" for each issue as
[described in the GitHub
docs](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword).

## Solution

- Describe the solution used to achieve the objective above.

## Testing

- Did you test these changes? If so, how?
- Are there any parts that need more testing?
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- 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)
- [ x] Tests cover the new/changed behavior
- [x ] Performance impact has been considered and is acceptable

## Showcase

> This section is optional. If this PR does not include a visual change
or does not add a new user-facing feature, you can delete this section.

- Help others understand the result of this PR by showcasing your
awesome work!
- If this PR includes a visual change, consider adding a screenshot,
GIF, or video
- A before/after comparison is very useful for changes to existing
features!

While a showcase should aim to be brief and digestible, you can use a
toggleable section to save space on longer showcases:

<details>
  <summary>Click to view showcase</summary>

<img width="1170" height="831" alt="image"
src="https://github.com/user-attachments/assets/56d948b0-b9da-42ec-abb2-3b19a7b38948"
/>

</details>

---

Release Notes:

- Fixed syntax highlighting for Markdown emphasis, links, and code
blocks when viewing a file at a historical commit
2026-09-24 13:07:25 +00:00
Bennet Bo Fenner
7fc2cf9b84
opencode: Dynamic model fetching improvements (#64666)
Follow up to #64585

- Filter out deprecated models
- Cache model catalog on disk to reduce loading time
- Refresh models every hour
- Remove auth header when fetching models

All of this matches the behaviour of the OpenCode TUI

Release Notes:

- opencode: Hide deprecated models
- opencode: Improve performance when resolving models
2026-09-24 13:01:08 +00:00
Hao Lam
4c902c9db2
extensions_ui: Sync suggested extensions with the live registry (#63211)
Some checks are pending
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_remote_server_linux_x86_64 (push) Blocked by required conditions
run_tests / check_remote_server_mac_aarch64 (push) Blocked by required conditions
run_tests / check_remote_server_windows_x86_64 (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
# Objective

The suggested-extension prompt only fires for a hand-picked list of file
types. Many rows had drifted from what their extensions actually
register today (`toml` didn't know `uv.lock`, `dockerfile` ignored
Compose files, …), entries were no longer sorted by ID, and the table
had no tests locking its invariants.

## Solution

- Synced every existing row against its extension's current
`path_suffixes`.
- Added 15 popular languages: asciidoc, csv, env, gdscript, groovy, ini,
json5, julia, just, nginx, odin, perl, python-requirements, scala,
solidity.
- Re-sorted by ID.
- Excluded despite appearing in manifests: erb compounds and elixir
`html.eex` (dead keys under exact-match), haskell `x`, asciidoc `asc`
(PGP clash), env/ini generic words (`conf`, `local`, systemd units…),
gdscript `import`, ruby `Berksfile.lock` (JSON). `gradle`/`gradle.kts`
stay with the groovy/kotlin rows.
- Behavior change: git-firefly is no longer suggested for
`COMMIT_EDITMSG` etc., mirroring upstream's own manifest — only
`COMMIT_EDITMSG` has built-in core coverage.

## Testing

- New tests lock suffix uniqueness across the table, ID sortedness, and
representative lookups for every row — including dotfiles (`.envrc`,
`.gitattributes`) and name-over-extension priority (`uv.lock`,
`compose.yaml`, `nginx.conf`).
- All 69 extension IDs were verified against
[zed-industries/extensions](https://github.com/zed-industries/extensions);
every kept suffix appears in that extension's live language config.
- Best exercised by checking out this branch, uninstalling e.g. the
`csv` extension, and opening a `.csv` file.

## 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

<details>
  <summary>Showcase</summary>

Before: opening `hello.sol` shows nothing — Zed silently moves on.
After: *"Do you want to install the recommended 'solidity' extension for
'sol' files?"*

</details>

---

Release Notes:

- Added extension installation suggestions for many more languages when
opening unsupported files

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-09-23 20:50:24 +00:00
tidely
b89471c52d
gpui_apple: Remove block as a direct dependency (#64641)
# Objective

Get rid of instances of the `block` crate, as it will not compile in a
future version of Rust.

## Solution

Migrate an independent code block to the `objc2` crate family.

This is the last PR in this series, and we get to remove `block` as a
direct dependency!

## Testing

- Tested rendering on MacOS

Release Notes:

- N/A
- [GPUI] Removed `block` as a direct dependency
2026-09-23 16:14:14 +00:00
zed-zippy[bot]
f57e400a17
Bump Zed to v1.23.0 (#64663)
Release Notes:

- N/A

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-09-23 15:11:54 +00:00