Skip to content

tui: playbook undo (C-x u) never reaches the daemon, then every later keystroke is silently dropped #1088

Description

@edwin-zvs

Every Playbook edit in the TUI is streamed to the daemon by handle_playbook_key, which snapshots the buffer before the key and flushes the resulting anchored diff afterwards:

let before = self.playbook_popup.as_ref().map(|popup| popup.buffer.clone());
// ... dispatch ...
if let Some(before) = before {
    self.flush_playbook_live_edit(before).await;
}

(crates/cli/src/app/editor.rs ~lines 652 / 822 @ ad47152)

C-x u does not go through that path. It is a global KeyAction, and its handler calls the mutation directly:

UndoPlaybook => {
    self.undo_playbook_edit();
}

(crates/cli/src/app.rs ~line 12705 @ ad47152)

So the undo mutates the local buffer and is never sent. The buffers diverge — and they stay diverged, because the next keystroke's anchored diff is computed against a before the daemon never received. Its old_string no longer exists server-side, playbook.edit fails with old_string not found in the current playbook, and the failure is swallowed (#1089). Every keystroke after that fails the same way.

Repro

  1. Open a Playbook in the TUI on a session whose document is in sync.
  2. Type abc. Confirm the daemon has it (construct playbook get, or playbook.get over IPC).
  3. Press C-x u.
  4. Type Z.

Observed, against a daemon at v109:

step daemon TUI
type abc v109 - build the thing …abc …abc
C-x u v109 …abc …ab
type Z v109 …abc (unchanged) …abZ

From step 3 on, the document the agent and the web UI see is frozen. The only indication is the * modified chip in the pane title. C-x C-s recovers correctly (playbook merged with agent edits (version 42)), but nothing points the user at it.

The web UI's C-x u does sync — this is TUI-only.

Expected

Undo is an edit like any other and must reach the daemon.

Acceptance criteria

  • C-x u in the Playbook publishes the resulting document to the daemon, so agents and other clients see it.
  • After an undo, subsequent typing continues to sync (no silent divergence).
  • C-/ (the in-editor alias, editor.rs ~line 763) and C-x u behave identically.
  • Regression test: undo followed by a keystroke leaves client and daemon documents equal.

Found during a hands-on UX audit of the Playbook in the TUI and web UI.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions