Skip to content

Add read-only git_blame and git_show tools#198

Open
ayobamiseun wants to merge 1 commit into
andrewyng:mainfrom
ayobamiseun:feat/git-blame-show
Open

Add read-only git_blame and git_show tools#198
ayobamiseun wants to merge 1 commit into
andrewyng:mainfrom
ayobamiseun:feat/git-blame-show

Conversation

@ayobamiseun

Copy link
Copy Markdown

What

Adds git_blame and git_show to the read-only git toolkit in coworker/tools/git.py, whose module docstring already frames the purpose ("see how a file came to be the way it is before changing it") — blame and show complete the natural loop: git_log (which commits) → git_blame (who last touched this line, in which commit) → git_show (what that commit actually changed).

  • git_blame(path, start_line?, end_line?) → per-line {line, hash, author, date, content}, parsed from --line-porcelain. Whole-file blame is capped at 300 lines with a note pointing at the range parameters.
  • git_show(ref=HEAD, path?) → the commit's message, diffstat, and patch, capped at 8000 chars with a note pointing at path scoping.

Both follow the git_log template exactly: schema dict, ToolMetadata(category="git", risk_level="low", requires_approval=False), __coworker_schema__. The subprocess runner is factored out and shared; git_log's behavior and error strings are unchanged. Commit/push stay excluded per the module's existing contract — they route through run_shell and its approval gate.

Security note: a ref is model input landing on a subprocess argv. git_show rejects anything that doesn't look like a ref — a leading - would be parsed as a git option (--output writes arbitrary files), and whitespace/metachars are refused. Paths are always passed after --, as git_log already does. There's a test asserting the injection refusal.

Wiring (no new surface)

The git capability builder already returns everything from git_tools(), so the new tools reach exactly the personas/agents that had git before (Code, and the read-only Explore subagent) — no catalog, persona, or permission changes beyond:

  • tests/test_catalog.py: the Phase-0 exact-toolset equivalence set extended with the two names.
  • The git capability description now says "(status, diff, log, blame, show)".

Tests

Six new tests in tests/test_code_tools.py following the existing git_log fixtures: two-author repo → blame attributes each line to the right author/commit; range scoping; error paths (no repo, missing file, empty path); show returns subject + patch + diffstat; relative refs (HEAD~1) with path scoping; and option-injection refusal.

Verification

$ .venv/bin/python -m pytest tests/test_code_tools.py -q
20 passed

$ .venv/bin/python -m pytest tests -q
895 passed, 1 skipped

No UI change (tools surface through the existing tool-approval cards), so no screenshots.

tools/git.py shipped only git_log, and its docstring frames the gap: the
agent should understand how code evolved before changing it. Blame answers
'who last touched this line and in which commit'; show answers 'what did
that commit actually change'. Together with log they close the loop:
log -> blame -> show, all read-only.

Both follow the git_log template exactly (schema dict, ToolMetadata with
category=git / risk_level=low, __coworker_schema__), and the shared
subprocess runner is factored out with git_log's behavior unchanged.
Output is bounded: blame caps at 300 lines with a note pointing at
start_line/end_line, show caps at 8000 chars with a note pointing at
'path'. Commit/push stay excluded per the module's contract — they route
through run_shell and its approval gate.

Since a ref is model input on a subprocess argv, git_show rejects refs
that don't look like refs (leading '-' would be parsed as a git option —
e.g. --output writes files; whitespace/metachars are refused too). Paths
are always passed after '--' as git_log already does.

The catalog's exact-toolset test (Phase 0 equivalence) is extended with
the two new names; the git capability description now lists blame/show.
Full backend suite: 895 passed, 1 skipped.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant