{"repo":"NousResearch/hermes-agent","public_id":"14082","display_label":"Session title display and resume UX fixes","summary":"Multiple issues and PRs address truncated session titles in the /resume command, including display length limits, prefix matching, and a related security scoping concern for session endpoints.","subsystem":"hermes_cli","counts":{"members":7,"open_issues":0,"open_issues_distinct":0,"open_prs":1,"closed_issues":2,"merged_prs":1,"attempt_prs":4},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":31710,"merged_at":"2026-05-24T23:13:23+00:00"},"resolution":{"state":"partially_resolved","by":"pr-31710"},"freshness":{"state":"verified","last_verified_at":"2026-05-24T23:13:23+00:00","is_stale":false},"grouping":{"backbone":"STRUCTURAL_PARTIAL","link_density":0.2552380952380952},"fix_edges":[{"issue_number":14082,"pr_number":31710,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true,"pr_merged_at":"2026-05-24T23:13:23+00:00"}],"members":[{"kind":"issue","number":14082,"title":"/resume fails on title match because display truncates titles to 30 chars","url":null,"state":"closed"},{"kind":"issue","number":15537,"title":"[Feishu] /resume shows session titles but requires session IDs — UX mismatch","url":null,"state":"closed"},{"kind":"pr","number":14098,"title":"fix(cli): show full titles in /resume session list","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#31710","number":31710},{"kind":"pr","value":"#14082","number":14082}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":14133,"title":"fix(cli): show full titles in /resume list instead of silently truncating","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#14098","number":14098}],"category":"duplicate_of","implication":"duplicate"},"merged":false},{"kind":"pr","number":14411,"title":"fix(resume): accept unique truncated title prefixes","url":null,"state":"closed","close_reason":{"refs":[{"kind":"commit","value":"6c44d537cc207628e13901ae8d3a65f2c437364f","number":0},{"kind":"pr","value":"#31710","number":31710},{"kind":"pr","value":"#14082","number":14082}],"category":"implemented_elsewhere","implication":"superseded"},"merged":false},{"kind":"pr","number":15373,"title":"fix(cli): increase session list title display from 30 to 50 chars (#14082)","url":null,"state":"open","close_reason":{"refs":[{"kind":"pr","value":"#14098","number":14098},{"kind":"pr","value":"#14082","number":14082},{"kind":"pr","value":"#14133","number":14133},{"kind":"pr","value":"#14411","number":14411}],"category":"duplicate_of","implication":"duplicate"},"merged":false},{"kind":"pr","number":31710,"title":"fix(cli): show full session titles in /resume list (#14082)","url":null,"state":"merged","close_reason":{"category":"merged"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["cli.py","tests/cli/test_cli_init.py"],"fix_hunks":[{"file":"cli.py","hunks":["@@ -6175,7 +6175,7 @@ def _show_recent_sessions(self, *, reason: str = \"history\", limit: int = 10) ->\n         print(f\"  {'Title':<32} {'Preview':<40} {'Last Active':<13} {'ID'}\")\n         print(f\"  {'─' * 32} {'─' * 40} {'─' * 13} {'─' * 24}\")\n         for session in sessions:\n-            title = (session.get(\"title\") or \"—\")[:30]\n+            title = session.get(\"title\") or \"—\"\n             preview = (session.get(\"preview\") or \"\")[:38]\n             last_active = _relative_time(session.get(\"last_active\"))\n             print(f\"  {title:<32} {preview:<40} {last_active:<13} {session['id']}\")"]},{"file":"tests/cli/test_cli_init.py","hunks":["@@ -360,6 +360,34 @@ def test_resume_updates_hermes_session_id_env_and_context(self, tmp_path):\n             os.environ.pop(\"HERMES_SESSION_ID\", None)\n             _VAR_MAP[\"HERMES_SESSION_ID\"].set(_UNSET)\n \n+    def test_resume_list_shows_full_long_titles(self, capsys):\n+        \"\"\"Long session titles render in full in the /resume table — not\n+        truncated to 30 chars (fixes #14082).\"\"\"\n+        cli = _make_cli()\n+        cli.session_id = \"current\"\n+        cli._session_db = MagicMock()\n+        long_title = \"Salvage BytePlus Volcengine PR With Fixes\"\n+        cli._session_db.list_sessions_rich.return_value = [\n+            {\n+                \"id\": \"current\",\n+                \"title\": \"Current\",\n+                \"preview\": \"Current preview\",\n+                \"last_active\": 0,\n+            },\n+            {\n+                \"id\": \"20260401_201329_d85961\",\n+                \"title\": long_title,\n+                \"preview\": \"fix byteplus pr and resume\",\n+                \"last_active\": 0,\n+            },\n+        ]\n+\n+        cli._handle_resume_command(\"/resume\")\n+        output = capsys.readouterr().out\n+\n+        assert long_title in output\n+        assert \"20260401_201329_d85961\" in output\n+\n     def test_sessions_command_no_args_lists_recent_sessions(self, capsys):\n         \"\"\"/sessions with no args prints the recent-sessions table (TUI parity).\n \n"]}]}],"trust":{"default_tier":"verified","includes_suggested":false}}