diff --git a/companion/codex_display/hook_events.py b/companion/codex_display/hook_events.py index 1528a5e..a02c81c 100644 --- a/companion/codex_display/hook_events.py +++ b/companion/codex_display/hook_events.py @@ -88,15 +88,23 @@ async def process_event(self, event: Dict[str, object]) -> None: ) else: existing = self._turns.get(key) - self._turns[key] = PendingTurn( - turn_id=turn_id, - transcript_path=path or ( - existing.transcript_path if existing is not None else None - ), - phase="pending_stop", - created_at=existing.created_at if existing is not None else now, - counted=existing.counted if existing is not None else False, + resolved_path = path or ( + existing.transcript_path if existing is not None else None ) + if resolved_path is None: + self._turns.pop(key, None) + else: + self._turns[key] = PendingTurn( + turn_id=turn_id, + transcript_path=resolved_path, + phase="pending_stop", + created_at=( + existing.created_at if existing is not None else now + ), + counted=( + existing.counted if existing is not None else False + ), + ) await self._on_change() async def reconcile(self, now: Optional[float] = None) -> None: diff --git a/companion/tests/test_hook_events.py b/companion/tests/test_hook_events.py index d980e09..9c76732 100644 --- a/companion/tests/test_hook_events.py +++ b/companion/tests/test_hook_events.py @@ -49,6 +49,18 @@ async def test_stop_waits_for_matching_task_complete(self): await self.tracker.reconcile() self.assertEqual(self.tracker.extra_count(set()), 0) + async def test_pathless_stop_clears_sidechat_immediately(self): + submit = self._event("UserPromptSubmit") + submit["transcript_path"] = None + await self.tracker.process_event(submit) + self.assertEqual(self.tracker.extra_count(set()), 1) + + stop = self._event("Stop") + stop["transcript_path"] = None + await self.tracker.process_event(stop) + + self.assertEqual(self.tracker.extra_count(set()), 0) + async def test_unconfirmed_submit_expires(self): tracker = HookActivityTracker( self.changed,