Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/serena/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,15 @@ def activate(client: str) -> None:
@click.command("cleanup", help="Set this as hook at session end all hook data for the current session")
@_client_option
def cleanup(client: str) -> None:
SessionEndCleanupHook(HookClient(client)).execute()
hook_client = HookClient(client)
try:
SessionEndCleanupHook(hook_client).execute()
except Exception as exc:
if hook_client != HookClient.CODEX:
raise
click.echo(f"Serena cleanup failed: {exc}", err=True)
if hook_client == HookClient.CODEX:
click.echo(json.dumps({"continue": True}))

@staticmethod
@click.command(
Expand Down
21 changes: 21 additions & 0 deletions test/serena/test_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,27 @@ def test_cleanup_command(self, tmp_path: Path):
assert result.exit_code == 0
assert not session_dir.exists()

def test_codex_cleanup_emits_valid_stop_hook_json(self, tmp_path: Path):
runner = CliRunner()
stdin_json = json.dumps({"session_id": "codex-cleanup"})
with patch("serena.hooks.serena_home_dir", str(tmp_path)):
result = runner.invoke(hook_commands, ["cleanup", "--client", "codex"], input=stdin_json)

assert result.exit_code == 0
assert json.loads(result.stdout) == {"continue": True}

def test_codex_cleanup_without_session_id_still_emits_valid_json(self):
runner = CliRunner()
result = runner.invoke(
hook_commands,
["cleanup", "--client", "codex"],
input=json.dumps({"stop_hook_active": False}),
)

assert result.exit_code == 0
assert json.loads(result.stdout) == {"continue": True}
assert "Session ID is required" in result.stderr

def test_remind_command(self, tmp_path: Path):
"""Invoke the remind command enough times to trigger a deny."""
runner = CliRunner()
Expand Down
Loading