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
8 changes: 4 additions & 4 deletions tools/agent-guard/src/agent_guard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ class Segment:
"""One simple command from a (possibly compound) shell line.

``argv`` has leading ``NAME=value`` env assignments stripped into ``env``;
``raw`` is the original text of the segment (used for substring scans that
survive heredocs, e.g. the Co-Authored-By trailer).
``raw`` is a reconstruction of this segment's own tokens only (used for
substring scans that survive heredocs, e.g. the Co-Authored-By trailer).
"""

def __init__(self, tokens: list[str], raw: str) -> None:
Expand Down Expand Up @@ -164,12 +164,12 @@ def split_segments(command: str) -> list[Segment]:
for tok in tokens:
if tok in SHELL_OPERATORS:
if current:
segments.append(Segment(current, command))
segments.append(Segment(current, shlex.join(current)))
current = []
else:
current.append(tok)
if current:
segments.append(Segment(current, command))
segments.append(Segment(current, shlex.join(current)))
return segments


Expand Down
7 changes: 7 additions & 0 deletions tools/agent-guard/tests/test_guards.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,13 @@ def test_compound_command_guarded():
assert dispatch('cd /tmp && git commit -m "x\nCo-Authored-By: a"') is not None


def test_compound_command_other_segment_not_denied():
# The phrase lives in an unrelated earlier segment, not in the commit's
# own message, so the commit segment must not inherit it.
command = 'echo "note: never add a Co-Authored-By: trailer" && git commit -m "clean fix"'
assert dispatch(command) is None


def test_malformed_command_allows():
assert dispatch('gh pr comment 5 --body "oops') is None

Expand Down