fix(app_controller): clear undo/redo history in btn_reset

test_undo_redo_lifecycle in tests/test_undo_redo_sim.py was failing in
the live_gui batch (passes in isolation) because btn_reset
(_handle_reset_session) was not clearing the HistoryManager's undo and
redo stacks. Prior tests in the same live_gui session leave stale
entries that interfere with tests that assume btn_reset provides a
clean history baseline.

Adds clearing of:
- app.history._undo_stack
- app.history._redo_stack
- app._last_ui_snapshot (None so the next take sets the baseline)
- app._pending_snapshot (False so debounce starts fresh)
- app._state_to_push (None so no stale state queued for push)

at the end of _handle_reset_session. The App is reached via
self.hook_server.app (set during _init_ai_and_hooks); all accesses are
guarded with hasattr/getattr for safety when the hook_server isn't
initialized yet (tests that construct AppController without starting
services).

Tests: test_undo_redo_lifecycle, test_undo_redo_discussion_mutation,
test_undo_redo_context_mutation all pass (3/3). The previously-failing
batch context also passes (verified with 14 tests from the gw7 worker
plus the test_undo_redo_sim set).
This commit is contained in:
ed
2026-06-30 09:57:42 -04:00
parent ebd9ad3119
commit 2c447af10b
+12
View File
@@ -3954,6 +3954,18 @@ class AppController:
self.temperature = 0.0
self.top_p = 1.0
self.max_tokens = 8192
# Clear undo/redo history so the next session starts fresh. Without
# this, prior tests in the same live_gui session leave stale entries
# that interfere with tests like tests/test_undo_redo_sim.py that
# assume btn_reset provides a clean history baseline.
if hasattr(self, 'hook_server') and self.hook_server and getattr(self.hook_server, 'app', None) is not None:
app = self.hook_server.app
if hasattr(app, 'history'):
app.history._undo_stack.clear()
app.history._redo_stack.clear()
if hasattr(app, '_last_ui_snapshot'): app._last_ui_snapshot = None
if hasattr(app, '_pending_snapshot'): app._pending_snapshot = False
if hasattr(app, '_state_to_push'): app._state_to_push = None
def _handle_compress_discussion(self) -> None:
def worker() -> "Result[None]":