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:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user