Skip to content

Commit 613bde9

Browse files
emerybergerclaude
andcommitted
Add agent mode for AI coding agents with recency-aware coverage
This adds a comprehensive agent-oriented coverage mode designed for AI coding agents to identify relevant code areas: - New CLI flags: --agent-mode, --track-hits, --track-timestamps, --trace-execution, --detail, --git-baseline, --history-file, --show-trends - Hit counts and timestamps for each line/branch - Execution sequence tracking with recency scores - Git integration for change tracking (modified_since_baseline, covered_since_modification signals) - Code structure extraction (classes, functions, methods with rollup) - Session history for trend analysis (heating/cooling detection) - Thread-safe implementation with proper locking - 23 new tests for agent mode functionality Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 3b243fc commit 613bde9

File tree

8 files changed

+2120
-12
lines changed

8 files changed

+2120
-12
lines changed

src/slipcover/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,19 @@
22
from .slipcover import Slipcover, merge_coverage, print_coverage, print_xml
33
from .importer import FileMatcher, ImportManager, wrap_pytest
44
from .fuzz import wrap_function
5+
from .agent import (
6+
LineMetrics, BranchMetrics, FileMetrics, AgentMetrics,
7+
FunctionInfo, ClassInfo, CodeStructure,
8+
SequenceCounter, ExecutionTrail, extract_structure,
9+
compute_structure_coverage, structure_to_dict
10+
)
11+
from .git_utils import (
12+
GitLineInfo, GitFileInfo, GitTracker,
13+
get_git_head, is_git_dirty, get_git_blame,
14+
get_modified_lines_since, get_uncommitted_lines
15+
)
16+
from .session_history import (
17+
SessionCoverage, SessionHistory, SessionTracker,
18+
LineTrend, load_history, save_history,
19+
compute_trends, create_session_from_coverage
20+
)

src/slipcover/__main__.py

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,38 @@ def wrapper(*pargs, **kwargs):
4343
return wrapper
4444

4545

46-
def get_coverage(sci):
46+
def get_coverage(sci, agent_mode=False, detail='modified', git_baseline=None,
47+
include_git=True, history_file=None, show_trends=False):
4748
"""Combines this process' coverage with that of any previously forked children and xdist workers."""
4849
global input_tmpfiles, output_tmpfile
4950

50-
cov = sci.get_coverage()
51+
if agent_mode:
52+
cov = sci.get_agent_coverage(
53+
detail=detail,
54+
git_baseline=git_baseline,
55+
include_git=include_git
56+
)
57+
58+
# Add trend analysis if requested
59+
if show_trends and history_file:
60+
try:
61+
from .session_history import (
62+
SessionTracker, create_session_from_coverage, trends_to_dict
63+
)
64+
tracker = SessionTracker(history_file)
65+
session_id = cov.get('meta', {}).get('session_id', 'unknown')
66+
67+
# Compute and add trends
68+
trends = tracker.get_trends(cov, session_id)
69+
cov['trends'] = trends_to_dict(trends)
70+
71+
# Record this session for future trend analysis
72+
session = create_session_from_coverage(cov, session_id)
73+
tracker.record_session(session)
74+
except Exception:
75+
pass # Trend analysis is optional
76+
else:
77+
cov = sci.get_coverage()
5178

5279
# Merge coverage from forked children (pytest-forked)
5380
if input_tmpfiles:
@@ -181,6 +208,26 @@ def main():
181208
help="threshold for de-instrumentation (if not immediate)")
182209
ap.add_argument('--missing-width', type=int, default=80, metavar="WIDTH", help="maximum width for `missing' column")
183210

211+
# Agent mode options for AI coding agents
212+
ap.add_argument('--agent-mode', action='store_true',
213+
help="enable agent-oriented output with extended metrics")
214+
ap.add_argument('--track-hits', action='store_true',
215+
help="track hit counts per line/branch")
216+
ap.add_argument('--track-timestamps', action='store_true',
217+
help="track first/last execution timestamps")
218+
ap.add_argument('--trace-execution', action='store_true',
219+
help="track full execution sequence (enables hit tracking)")
220+
ap.add_argument('--detail', choices=['summary', 'modified', 'full'], default='modified',
221+
help="level of detail for agent mode output (default: modified)")
222+
ap.add_argument('--git-baseline', type=str, default=None,
223+
help="git ref to compare against for modified lines (default: HEAD~1)")
224+
ap.add_argument('--no-git', action='store_true',
225+
help="disable git integration in agent mode")
226+
ap.add_argument('--history-file', type=str, default=None,
227+
help="path to session history file for trend analysis")
228+
ap.add_argument('--show-trends', action='store_true',
229+
help="include trend analysis in agent mode output")
230+
184231
# intended for slipcover development only
185232
ap.add_argument('--silent', action='store_true', help=argparse.SUPPRESS)
186233
ap.add_argument('--dis', action='store_true', help=argparse.SUPPRESS)
@@ -228,7 +275,11 @@ def main():
228275

229276
sci = sc.Slipcover(immediate=args.immediate,
230277
d_miss_threshold=args.threshold, branch=args.branch,
231-
disassemble=args.dis, source=args.source)
278+
disassemble=args.dis, source=args.source,
279+
agent_mode=args.agent_mode,
280+
track_hits=args.track_hits,
281+
track_timestamps=args.track_timestamps,
282+
trace_execution=args.trace_execution)
232283

233284

234285
if not args.dont_wrap_pytest:
@@ -263,7 +314,15 @@ def printit(coverage, outfile):
263314
missing_width=args.missing_width)
264315

265316
if not args.silent:
266-
coverage = get_coverage(sci)
317+
coverage = get_coverage(
318+
sci,
319+
agent_mode=args.agent_mode,
320+
detail=args.detail,
321+
git_baseline=args.git_baseline,
322+
include_git=not args.no_git,
323+
history_file=args.history_file,
324+
show_trends=args.show_trends
325+
)
267326
if args.out:
268327
with open(args.out, "w") as outfile:
269328
printit(coverage, outfile)

0 commit comments

Comments
 (0)