fix(cli): blank user turn no longer crashes foreign session discovery

_first_user_line indexed splitlines()[0] on a whitespace-only user message
(image-only / tool-only turn) and raised IndexError, which aborted the whole
CLI picker and the desktop session.foreign.list RPC. partition("\n") yields
"" for blank text and the loop moves on to the first real user line.
Reported first in #92290.
This commit is contained in:
Teknium
2026-09-06 03:55:29 -07:00
parent fe49acb670
commit f3400ce745
2 changed files with 18 additions and 1 deletions

View File

@@ -108,7 +108,7 @@ def _message_turn(message: Any) -> Optional[Tuple[str, str]]:
def _first_user_line(turns: List[Tuple[str, str]]) -> Optional[str]:
for role, text in turns:
if role == "user" and (line := text.strip().splitlines()[0].strip()):
if role == "user" and (line := text.strip().partition("\n")[0].strip()):
return line[:_TITLE_MAX * 2]
return None

View File

@@ -258,3 +258,20 @@ def test_leading_assistant_gets_single_stub(tmp_path):
_assert_alternating(parsed["turns"])
assert len(parsed["turns"]) == 2
assert parsed["turns"][0]["role"] == "user"
def test_whitespace_only_user_turn_does_not_break_discovery(tmp_path):
"""A blank user message (image-only / tool-only turn) must not crash listing; the title
comes from the first non-blank user line and the blank turn is dropped."""
project = tmp_path / ".claude" / "projects" / "p"
project.mkdir(parents=True)
f = project / "blank.jsonl"
lines = [
{"type": "user", "sessionId": "w", "message": {"role": "user", "content": " \n "}},
{"type": "assistant", "sessionId": "w", "message": {"role": "assistant", "content": "hi"}},
{"type": "user", "sessionId": "w", "message": {"role": "user", "content": "real question"}},
]
f.write_text("\n".join(json.dumps(line) for line in lines) + "\n", encoding="utf-8")
listed = _list_sessions("claude", project.parent)
assert [s.title_guess for s in listed] == ["real question"]
assert listed[0].turn_count == 3 # leading assistant reply gets the user stub