mirror of
https://github.com/Twigpine/zero.git
synced 2026-11-11 23:40:28 -10:00
* feat(tui): let the permission prompt take free-text feedback inline "No, and tell Zero what to do differently" now opens an inline input on the permission card instead of silently cancelling: type an instruction, Enter sends it, Esc returns to the option list. The text is delivered as a Deny decision whose Reason is the typed instruction, so the agent surfaces it via deniedPermissionResult as the tool result and the model adjusts in the SAME turn — where the old cancel returned an error and aborted the run. Empty input + Enter falls back to a plain cancel (the prior meaning). No agent-side change: PermissionDecision.Reason already carries free text to the model. The UI mirrors the ask_user "type your own answer" pattern — the feedback field reuses the shared composer input and the card renders it in the transcript body. Also: a focused permission prompt now suppresses the composer (and idle hints/plan panel), keeping only the status line, exactly like the ask_user modal. Its keys are inert anyway, so a "describe a task for zero…" box below the card was misleading — and in feedback mode the shared input would otherwise echo in two places. Tests cover open / submit-as-Deny-with-text / empty-cancels / Esc-returns, the composer suppression in both modes, and that the feedback text renders exactly once. * fix(tui): preserve the composer draft across permission feedback (#780 review) anand + CodeRabbit (Major): entering feedback mode cleared the shared composer input via SetValue(""), and neither submit nor cancel restored it — so a user with a half-typed or queued next-turn message who chose "tell Zero what to do differently" lost that draft. Snapshot the composer value into pendingPermissionPrompt.savedDraft when feedback mode opens, and restore it on BOTH exits (submit and Esc-cancel). Only the feedback text is consumed, delivered via the decision Reason. Adds regression tests for both paths; mutation-verified against the SetValue("") regression. * fix(tui): guard permission-feedback backspace and clicks (#780 review) Vasanthdev2004 review, all on the permission path: 1. Real bug: Backspace on an empty feedback field dropped a staged attachment. The keyBackspace case runs before the typing branch and, on an empty composer (feedback mode clears it), fell to removeLastAttachment — silently dropping a staged image/doc that savedDraft does not restore. Route Backspace to the shared input while typing so it is a plain edit of the feedback text. 2. Defence-in-depth: the mouse click resolver in handleTranscriptSelectionMouse resolved a clicked permission option (Allow included) with no typing check. It is safe today only because renderFocusedPermissionPrompt returns nil clickable offsets in feedback mode — a single early-return in a function other PRs also edit. Add an explicit !typing guard on the click path so the safety is stated, not emergent. 3. Test hardening (also raised by CodeRabbit): assert len(got) == 1 before indexing got[0] in the draft-preservation test, so a regression fails cleanly instead of panicking. Tests: TestPermissionFeedbackBackspaceKeepsStagedAttachment (mutation-verified against the missing guard) and TestPermissionFeedbackRendersNoClickableOptionsWhileTyping. --------- Co-authored-by: KRATOS <[email protected]>