Skip to content
Open
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: 8 additions & 2 deletions src/pepper_cli/claude_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,14 @@ def _accept_scope(self, frame: api_client.FeedFrame) -> None:
raise self._ended(
"the cursor file belongs to a different watch", stop.code
) from stop
if self.self_id is None:
self.self_id = seen.agent_person_id
elif not _same_id(self.self_id, seen.agent_person_id):
raise self._ended(
f"--self {sanitize_line(self.self_id)} does not match the scoped agent "
f"person id {sanitize_line(seen.agent_person_id)}",
2,
)
self.bound = seen
self.allowed_rooms.add(seen.room_id)
if not _same_id(seen.room_id, seen.requested_room_id):
Expand All @@ -809,8 +817,6 @@ def _accept_scope(self, frame: api_client.FeedFrame) -> None:
f"following {seen.room_id}.",
soft_wrap=True,
)
if self.self_id is None:
self.self_id = seen.agent_person_id
elif not (
_same_id(seen.room_id, self.bound.room_id)
and _same_id(seen.topic_id, self.bound.topic_id)
Expand Down
34 changes: 34 additions & 0 deletions tests/test_claude_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,40 @@ def test_self_given_at_start_is_the_self_id_and_an_unknown_one_is_omitted(monkey
assert "self_id" not in unknown.notifications[0]["meta"]


def test_self_matching_the_scope_drops_the_agents_own_post(monkeypatch, tmp_path):
cursor_file = _scoped_cursor_file(tmp_path / "cursor", 3)
fake = _Fake(_CONNECTED + _scope() + _event(4, author=_AGENT) + _cursor(5))

result = run_channel(
monkeypatch,
fake,
["--room", _ROOM, "--self", _AGENT, "--cursor-file", str(cursor_file)],
)

assert result.notifications == []
assert not [r for r in fake.requests if r.url.path.endswith("/messages")]
assert json.loads(cursor_file.read_text())["cursor"] == 5


def test_a_scoped_self_that_does_not_match_the_scope_ends_the_channel(monkeypatch):
fake = _Fake(_CONNECTED + _scope() + _event(7))

result = run_channel(
monkeypatch,
fake,
["--room", _ROOM, "--self", _BOB],
script=_ended,
)

(note,) = result.notifications
assert note["meta"] == {"kind": "ended"}
assert "--self" in note["content"]
assert _BOB in note["content"]
assert _AGENT in note["content"]
assert result.code == 2
assert not [r for r in fake.requests if r.url.path.endswith("/messages")]


def test_an_unreadable_message_still_carries_the_self_id():
_, meta = claude_channel.message_event(
info=claude_channel.TopicInfo(_ROOM, "Kitchen", "Dinner"),
Expand Down
Loading