## Summary
Add a typed SDK v2 tool-content append path. `ToolCallContentChunk`
appends one complete item; `ToolCallUpdate.content` still replaces the
collection. No wire handler or protocol selection is added.
- Target exact/historical tool IDs without rebuilding the existing
snapshot. New IDs create minimal records with reported fields unset;
this is a lenient client policy.
- Reuse item preparation and registered terminal placeholders. Preserve
existing render entities, native diff ownership, tool
status/permissions/metadata/locations/raw values, and normal raw-output
fallback behavior.
- Emit updates for the actual row; only new rows use the existing
streaming-flush boundary.
- Retain item/body metadata. Delivery-scoped chunk `_meta` is not
promoted into aggregate state or stored as a separate history, matching
message chunks.
## Review guide
Production code is unchanged by the cleanup:
- [Append and fallback
refresh](a15b15ecc1/crates/acp_thread/src/acp_thread.rs (L1574)).
- [Shared single-item
preparation](a15b15ecc1/crates/acp_thread/src/acp_thread.rs (L2949)).
- [Exact-ID append and first-seen
defaults](a15b15ecc1/crates/acp_thread/src/acp_thread.rs (L5332)).
Coverage is now three focused regressions, reduced from seven and
approximately **1,000 → 300 test lines**:
1.
[Ordering/targeting](a15b15ecc1/crates/acp_thread/src/acp_thread.rs (L13068)):
historical ID, append vs replacement, clear/raw fallback, defaults,
metadata isolation, original Markdown, and row events.
2.
[Preservation](a15b15ecc1/crates/acp_thread/src/acp_thread.rs (L13180)):
real permission waiter, reported state, native diff identity, and
unrelated buffered text/new-row flush.
3. [UI
integration](a15b15ecc1/crates/agent_ui/src/conversation_view.rs (L10077)):
an existing expanded search automatically refreshes after older-tool
append, while row/entity identity and the later tool remain unchanged.
Broad content-variant, full diff-editor, and repeated render/search
matrices remain covered by existing tests rather than being repeated
here. Fixtures use SDK builders; no helper framework was added.
## Validation
- Full suites: **240 core**, **496 UI** (serial).
- Two core regressions: **100 seeds**; UI regression: **20 seeds**.
- Six-package `./script/clippy`, formatting and `git diff --check`
passed.
- Production text was verified byte-for-byte unchanged by this test-only
cleanup.
## Suggested .rules additions
GPUI testing guidance: `VisualTestContext::debug_bounds` needs a static
selector. Reuse allocated fixture selectors for runtime IDs; do not
borrow temporary `&format!(...)` strings.
Release Notes:
- N/A
Also... we're hiring! Check out our jobs page for open roles.
Licensing
Zed source code is licensed primarily under GPL-3.0-or-later, with Apache-2.0 components where marked.
License information for third party dependencies must be correctly provided for CI to pass.
We use cargo-about to automatically comply with open source licenses. If CI is failing, check the following:
Is it showing a no license specified error for a crate you've created? If so, add publish = false under [package] in your crate's Cargo.toml.
Is the error failed to satisfy license requirements for a dependency? If so, first determine what license the project has and whether this system is sufficient to comply with this license's requirements. If you're unsure, ask a lawyer. Once you've verified that this system is acceptable add the license's SPDX identifier to the accepted array in script/licenses/zed-licenses.toml.
Is cargo-about unable to find the license for a dependency? If so, add a clarification field at the end of script/licenses/zed-licenses.toml, as specified in the cargo-about book.
Sponsorship
Zed is developed by Zed Industries, Inc., a for-profit company.
If you’d like to financially support the project, you can do so via GitHub Sponsors.
Sponsorships go directly to Zed Industries and are used as general company revenue.
There are no perks or entitlements associated with sponsorship.