Skip to content

feat: /undo command — remove last turn from the conversation - #957

Draft
Betterlol wants to merge 1 commit into
moonbitlang:mainfrom
Betterlol:feat/command/undo
Draft

feat: /undo command — remove last turn from the conversation#957
Betterlol wants to merge 1 commit into
moonbitlang:mainfrom
Betterlol:feat/command/undo

Conversation

@Betterlol

Copy link
Copy Markdown
Contributor

Summary

Adds /undo [count] to the TUI, letting the user remove the last N events from the durable session and rebuild the transcript.

Changes

Protocol layer (protocol/)

  • Command::Undo(count~ : Int = 1) — wire format: {"command":"undo"} or {"command":"undo","count":N}
  • Event::SessionUndone(events_removed~ : Int){"event":"session_undone","events_removed":N}
  • Round-trip covered by the emit/parse test suite

Session model (agent_session/)

  • Session::remove_last(count) — returns new session with last N events removed (immutable, uses @vector slicing)

Serve engine (cmd/openseek/serve.mbt)

  • Undo dispatched in the serve loop: checks idle state, calls session.remove_last(count) + store.create(modified)
  • Rejects with command_error when work is in flight or no durable session

TUI (cmd/tui/)

  • /undo [count] slash command (default count=1, rejects oneshot mode)
  • Ui::replace_transcript — scrollback-level rebuild for transcript rollback
  • EngineSessionUndone — untagged message that survives stale-run guard, triggers session reload + transcript rebuild

Desktop (desktop/)

  • Exhaustive decode matches updated for the new event variant

Verification

  • moon check: clean (native + js)
  • moon fmt --check: clean
  • moon test: protocol 16, cmd/tui 83, agent_session 35, tui all pass
  • moon info: regenerated .mbti files

Protocol layer:
- Command::Undo(count) — removes N events from the durable session
- Event::SessionUndone(events_removed) — engine confirms the removal
- Wire format: {"command":"undo","count":N} / {"event":"session_undone","events_removed":N}

Session model:
- Session::remove_last(count) — returns new session with last N events removed

Serve engine:
- Undo dispatch: checks idle state, calls session.remove_last + store.create
- Rejects with command_error when work is in flight or no durable session

TUI:
- /undo [count] slash command (default count=1)
- Ui::replace_transcript — scrollback-level rebuild for transcript rollback
- EngineSessionUndone — untagged message that survives stale-run guard
- Only available in Serve mode (oneshot rejected)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant