From 4636ef0c830413e3caa847bf211f06a40d84472f Mon Sep 17 00:00:00 2001 From: CleverThis Date: Thu, 9 Apr 2026 23:37:44 +0000 Subject: [PATCH 1/2] fix(cli): fix session list --format json empty-case structure (#6316) Ensure the empty JSON path reuses the session summary builder so the machine-readable output aligns with the specification for empty data sets. ISSUES CLOSED: #6316 Tests: nox -s unit_tests -- features/session_list_error.feature --- CHANGELOG.md | 11 +++++- features/session_list_error.feature | 1 + features/steps/session_list_error_steps.py | 44 ++++++++++++++++++++++ src/cleveragents/cli/commands/session.py | 2 +- 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c9d662fd..e490ab29d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,7 +75,16 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `provisioning_state: discovered`. Named configurations (`.devcontainer//devcontainer.json`) are also discovered and carry the configuration name in the `config_name` property. This wires the previously-isolated `discover_devcontainers()` function into the production - code path, enabling the spec's zero-configuration devcontainer experience. + code path, enabling the spec's zero-configuration devcontainer experience. + +- **`agents session list --format json` empty-case emits correct summary structure** (#6695): + Fixed the empty-sessions early-return path in `session.py` to reuse `_session_list_dict([])` + instead of passing `{\"sessions\": [], \"total\": 0}` directly. The previous code emitted + `total` at the top level and omitted the required `summary` sub-object entirely. Now + `agents session list --format json` with zero sessions produces `{\"sessions\": [], + \"summary\": {\"total\": 0, \"most_recent\": null, \"oldest\": null, \"total_messages\": 0, + \"storage\": \"0 KB\"}}`, which matches the spec-aligned structure used by all non-empty + output paths. (#6316) ### Changed diff --git a/features/session_list_error.feature b/features/session_list_error.feature index ea38934ad..09fa75ec5 100644 --- a/features/session_list_error.feature +++ b/features/session_list_error.feature @@ -70,6 +70,7 @@ Feature: Session list command handles missing database gracefully Then the session-list-error command should exit successfully And the session-list-error output should be valid JSON containing "sessions" And the session-list-error output should not contain "AttributeError" + And the session-list-error JSON summary should represent an empty result @tdd_issue @tdd_issue_554 @tdd_issue @tdd_issue_4270 @tdd_expected_fail diff --git a/features/steps/session_list_error_steps.py b/features/steps/session_list_error_steps.py index 4126b0a67..2f72f4499 100644 --- a/features/steps/session_list_error_steps.py +++ b/features/steps/session_list_error_steps.py @@ -256,6 +256,50 @@ def step_output_json_key(context: Context, key: str) -> None: ) +@then("the session-list-error JSON summary should represent an empty result") +def step_json_empty_summary(context: Context) -> None: + result = context.sle_result + assert result is not None, "No command was invoked" + try: + parsed = json.loads(result.output) + except json.JSONDecodeError as exc: + raise AssertionError(f"Output is not valid JSON:\n{result.output}") from exc + + data = _unwrap_envelope(parsed) + assert isinstance(data, dict), f"Expected JSON object, got {type(data)}: {data}" + + sessions = data.get("sessions") + assert isinstance(sessions, list), ( + f"Expected 'sessions' to be a list, got {type(sessions)}: {sessions}" + ) + assert not sessions, f"Expected no sessions but found: {sessions}" + + assert "total" not in data, ( + "Top-level 'total' key should not be present; expected value nested in 'summary'." + ) + + summary = data.get("summary") + assert isinstance(summary, dict), ( + f"Expected 'summary' to be a dict, got {type(summary)}: {summary}" + ) + + expected_keys = {"total", "most_recent", "oldest", "total_messages", "storage"} + missing_keys = expected_keys - set(summary) + assert not missing_keys, f"Missing summary keys: {sorted(missing_keys)}" + + assert summary["total"] == 0, f"Expected summary total 0, got {summary['total']}" + assert summary["total_messages"] == 0, ( + f"Expected total_messages 0, got {summary['total_messages']}" + ) + assert summary["most_recent"] is None, ( + f"Expected most_recent None, got {summary['most_recent']}" + ) + assert summary["oldest"] is None, f"Expected oldest None, got {summary['oldest']}" + assert summary["storage"] == "0 KB", ( + f"Expected storage '0 KB', got {summary['storage']}" + ) + + @then('the session-list-error output should be valid YAML containing "{key}"') def step_output_yaml_key(context: Context, key: str) -> None: result = context.sle_result diff --git a/src/cleveragents/cli/commands/session.py b/src/cleveragents/cli/commands/session.py index 27a9f1c99..aa720be2f 100644 --- a/src/cleveragents/cli/commands/session.py +++ b/src/cleveragents/cli/commands/session.py @@ -329,7 +329,7 @@ def list_sessions( # For machine-readable formats, always emit a structured empty list # so that callers parsing JSON/YAML receive valid output. if fmt not in (OutputFormat.RICH.value, OutputFormat.COLOR.value): - typer.echo(format_output({"sessions": [], "total": 0}, fmt)) + typer.echo(format_output(_session_list_dict([]), fmt)) return console.print("[yellow]No sessions found.[/yellow]") console.print("Create one with 'agents session create'") -- 2.52.0 From 766ab9b1bdd0403b4aabdec769633e2eb1fd7ff8 Mon Sep 17 00:00:00 2001 From: CleverAgents Bot Date: Wed, 10 Jun 2026 20:24:28 -0400 Subject: [PATCH 2/2] ci: stop master workflow on PR updates Remove the stale pull_request trigger from master.yml so PR branch commits do not launch the master workflow. Maintenance patch for PR #6695. --- .forgejo/workflows/master.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.forgejo/workflows/master.yml b/.forgejo/workflows/master.yml index 7c959ba40..ccdede22d 100644 --- a/.forgejo/workflows/master.yml +++ b/.forgejo/workflows/master.yml @@ -3,8 +3,6 @@ name: CI on: push: branches: [master, develop] - pull_request: - branches: [master, develop] vars: docker_prefix: "http://harbor.cleverthis.com/docker/" -- 2.52.0