You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
L1 path + expandable L2 audit is on main. L2 still paints the whole detail as one teal_text mono block. This issue is paint, not a new emit shape: old side on an EMBER background, new side on a TEAL background. No per-line - / + prefixes (that was the previous ask; dropped).
Do not revive #685’s other choices (cap-before-redact, JS .length as “bytes”, untested execute path, delete-has_detail for all tools).
Current behavior (baseline on main)
Layer
What happens now
Emit
appendStrReplaceDiff in lib/agent/tools.ts — redact then cap 4096 UTF-8 bytes/side, structural -old_string / +new_string headers. Content lines that equal a header get a leading space.
itemLabel hides host name · running… / name · ok / name · failed; error briefs with a path still show.
Paint
paintToolRun dumps it.detail in one textLayout with palette.teal_text (native/harness/src/ui/toolrun.zig). No side boxes.
Desired UX
Expanded str_replace L2 is two stacked bands under the status line:
Side
Background
Text
old (removed)
palette.ember_surface (or ember_bg)
palette.ember_text
new (added)
palette.teal_surface (or teal_bg)
palette.teal_text
Status line stays uncolored chrome (path + replacements + bytes) — still the L1 brief source. salientToolBits ignores the body.
No- / + line prefixes and no need to change the emit to unified-diff. Keep -old_string / +new_string as parse sentinels (do not paint those header lines, or paint them as muted labels).
Empty new_string (delete): old band still shows; new band is an empty TEAL strip so the operator sees “nothing added.”
replace_all still one pair.
Other tools’ L2 unchanged (still one teal_text block).
EMBER is danger-only in the palette contract. Removal is the destructive side — use surface/bg + text, not ember_accent (that stays the ✗ glyph). No freehand hex.
Implementation sketch (not locked)
Wasm (native/harness/src/ui/toolrun.zig, maybe a pure split in rich/toolrun.zig): when name == str_replace and detail has the two headers, split status / old / new. Paint old in an EMBER-filled box, new in a TEAL-filled box. Mono face stays.
Summary
Follow-up to #684 / plan #665 (source #368).
L1 path + expandable L2 audit is on
main. L2 still paints the whole detail as oneteal_textmono block. This issue is paint, not a new emit shape: old side on an EMBER background, new side on a TEAL background. No per-line-/+prefixes (that was the previous ask; dropped).Do not revive #685’s other choices (cap-before-redact, JS
.lengthas “bytes”, untested execute path, delete-has_detailfor all tools).Current behavior (baseline on
main)appendStrReplaceDiffinlib/agent/tools.ts— redact then cap 4096 UTF-8 bytes/side, structural-old_string/+new_stringheaders. Content lines that equal a header get a leading space.buildStrReplacePreviewinlib/agent/agentStream.ts— positional header parse + per-side window 20/6.itemLabelhides hostname · running…/name · ok/name · failed; error briefs with a path still show.paintToolRundumpsit.detailin onetextLayoutwithpalette.teal_text(native/harness/src/ui/toolrun.zig). No side boxes.Desired UX
Expanded
str_replaceL2 is two stacked bands under the status line:palette.ember_surface(orember_bg)palette.ember_textpalette.teal_surface(orteal_bg)palette.teal_textsalientToolBitsignores the body.-/+line prefixes and no need to change the emit to unified-diff. Keep-old_string/+new_stringas parse sentinels (do not paint those header lines, or paint them as muted labels).new_string(delete): old band still shows; new band is an empty TEAL strip so the operator sees “nothing added.”replace_allstill one pair.teal_textblock).EMBER is danger-only in the palette contract. Removal is the destructive side — use surface/bg + text, not
ember_accent(that stays the ✗ glyph). No freehand hex.Implementation sketch (not locked)
native/harness/src/ui/toolrun.zig, maybe a pure split inrich/toolrun.zig): whenname == str_replaceand detail has the two headers, split status / old / new. Paint old in an EMBER-filled box, new in a TEAL-filled box. Mono face stays.tools.ts+buildStrReplacePreviewas shipped in feat(agent): show str_replace path + expandable old→new diff #684 unless paint needs a tighter sentinel. Do not switch to per-line-/+.+new_string, empty new).zig build test-richon the runner. No protocol bump.docs/harness-limits.mdTwo-level expand row — L2str_replaceis two palette bands, not a unified-diff dump.Non-goals
-/+prefixes (explicitly not this issue)write_filediffsstr_replacematch semantics.lengthas bytes · painting host status fallbacks on L1 · freehand hex / non-palette colorsAcceptance
str_replaceL2 paints old on EMBER surface, new on TEAL surface-/+prefixes added-old_string/+new_stringdump (hidden or muted labels)docs/harness-limits.mdmatchesRelated
c9f4684, plan #665