A Write CREATE rendered its completed tool_call_update as the model-facing
result TEXT (`<path>…</path>…Created file`), which — because an ACP
tool_call_update.content REPLACES the call's content — clobbered the
new-file diff the pending call installed. So Zed showed the diff, then
replaced it with raw XML-ish text; only overwrite/edit looked right
(their result re-sends a diff).
write's presentResult now ALWAYS returns a diff card for a successful
write: the applied contextual hunk from `meta` when there is one
(overwrite), else an args-derived whole-file diff (`oldText: null`) for a
create or an unchanged-content overwrite. This matches claude-agent-acp,
where the create diff rides on the update and no result text replaces it.
An error still falls through to generic rendering so its message shows.
edit is unchanged (it always has a hunk; no whole-file fallback).
Re-recorded fs-write / fs-write-overwrite goldens; the create's completed
update is now a {type:'diff'} block, not the XML result text.
fs/ - filesystem capability family
The filesystem stack: a provider seam (text IO + atomic mutation with an optional version guard), a local implementation, a policy gate plugin (observed-state + read-before-edit + version-guarded write/edit), and the model-facing file tools + executor. All product packages.
| Package | Role | ctx key |
|---|---|---|
fs/ |
Provider seam: text IO + atomic mutation primitives (optional version guard); owns the fs/* policy events |
ctx.fs |
fs-local/ |
Local-filesystem FileSystem implementation |
(registers ctx.fs) |
fs-policy/ |
Policy gate plugin: observed-state + read-before-edit + version-guarded write/edit, via the fs/* event gate |
(no service — fs/* listeners) |
tool-fs/ |
Model-facing read/write/edit tools AND the executor (reads via ctx.fs, owns read windowing, dispatches fs/*) |
(registers on ctx.tools) |
The interface lives at fs/fs/. A sandboxed, remote, or project-scoped filesystem backend can replace fs-local without touching the seam, the policy gate, or the model-facing tool schemas. The policy (fs-policy/) is a plugin that participates only through the fs/* event gate, not a service the tool injects — so dropping it gracefully loses the policy and leaves the unconstrained bare provider rather than breaking the tool. A deployment that loads tool-fs/ is expected to also load it.