Skip to content

feat: real-time file tracking via post-file-edit hook#637

Open
khaong wants to merge 12 commits intomainfrom
refactoring-transcript-reads
Open

feat: real-time file tracking via post-file-edit hook#637
khaong wants to merge 12 commits intomainfrom
refactoring-transcript-reads

Conversation

@khaong
Copy link
Contributor

@khaong khaong commented Mar 6, 2026

Summary

  • Adds real-time file tracking via a post-file-edit hook, eliminating the need for transcript parsing to determine which files an agent touched
  • Introduces an append-only tracking file (.git/entire-sessions/<session-id>.files) that records file paths as agents edit them
  • Wires Claude Code's PostToolUse[Write] and PostToolUse[Edit] hooks to fire the new event
  • resolveFilesTouched now merges the tracking file with state.FilesTouched, falling back to transcript extraction only when both are empty

This is Phase 1 of the transcript parsing replacement plan. Other agents (Gemini CLI, Factory AI Droid, OpenCode, Copilot CLI) will be wired in follow-up PRs.

Architecture

Agent fires Write/Edit tool
  → PostToolUse hook fires `entire hooks <agent> post-file-edit`
    → parseFileEdit extracts file_path from tool_input
      → DispatchLifecycleEvent routes FileEdit event
        → handleLifecycleFileEdit normalizes path, appends to .files

At checkpoint time, resolveFilesTouched merges:

  1. state.FilesTouched (from previous turns' SaveStep)
  2. Tracking file (from current turn's real-time hook)
  3. Falls back to transcript extraction only when both are empty

Changes

New event type & handler:

  • FileEdit event type in agent/event.go
  • handleLifecycleFileEdit in lifecycle.go — normalizes to repo-relative paths, fail-open

Session package:

  • AppendFileTouched — O_APPEND write, one path per line
  • ReadFilesTouched — deduplicated, sorted read
  • ClearFilesTouched — cleanup after condensation
  • Newline validation to prevent line injection

Strategy integration:

  • resolveFilesTouched merges tracking file + state, falls back to transcript
  • Cleanup at condensation and carry-forward points

Claude Code wiring:

  • PostToolUse[Write] and PostToolUse[Edit] matchers in hooks
  • parseFileEdit extracts file_path from tool_input JSON

Test plan

  • Unit tests: 8 new tests (session state, event type, Claude Code parsing, strategy merge)
  • Integration test: end-to-end file tracking through hook binary
  • All 43 E2E canary tests pass
  • mise run fmt && mise run lint && mise run test:ci clean

🤖 Generated with Claude Code

khaong and others added 7 commits March 6, 2026 21:41
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 1536d1523eec
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 50f1205aa19a
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 1065c97cae2c
Update resolveFilesTouched to merge state.FilesTouched AND the tracking
file (.git/entire-sessions/<session-id>.files), falling back to
transcript extraction only when both sources are empty. Results are
deduplicated and sorted.

Add cleanup of the tracking file at two points:
- After condensation (state.FilesTouched = nil)
- After carry-forward (state.FilesTouched = remainingFiles)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: c169ccec299e
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 9bfea85f075f
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 1c855fb06961
Prevent line injection in the append-only tracking file by rejecting
paths containing \n or \r characters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 4c0ce7ae83d3
Copilot AI review requested due to automatic review settings March 6, 2026 11:27
@cursor
Copy link

cursor bot commented Mar 6, 2026

PR Summary

Medium Risk
Medium risk because it adds a new lifecycle event path and persistent on-disk tracking in .git/entire-sessions, and updates checkpoint file-resolution logic; failures are largely fail-open but could impact file attribution/carry-forward behavior.

Overview
Real-time file edit tracking is added via a new Claude Code hook post-file-edit, wired to PostToolUse[Write] and PostToolUse[Edit] during hook installation.

This introduces a new lifecycle EventType (FileEdit) parsed from tool_input.file_path and dispatched through the generic lifecycle router; the handler normalizes absolute paths to repo-relative and appends them to a per-session tracking file at .git/entire-sessions/<session-id>.files.

The session StateStore now supports append/read/clear operations for this tracking file (with dedupe/sort and newline validation), and ManualCommitStrategy.resolveFilesTouched merges tracked paths with state.FilesTouched, clearing the tracking file during condensation/carry-forward. Tests are expanded with new unit coverage and an end-to-end integration test for file tracking.

Written by Cursor Bugbot for commit 83f1882. Configure here.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces Phase 1 of a transcript parsing replacement plan by adding real-time file tracking via a post-file-edit hook. Instead of relying solely on transcript parsing to determine which files an agent edited, agent file edits are now tracked in real-time using an append-only .files tracking file stored alongside session state in .git/entire-sessions/.

Changes:

  • Adds FileEdit event type and FilePath field to the agent event system, with Claude Code's PostToolUse[Write] and PostToolUse[Edit] hooks wired to fire the new event
  • Introduces AppendFileTouched, ReadFilesTouched, and ClearFilesTouched methods on StateStore for append-only file tracking with deduplication, newline injection prevention, and idempotent cleanup
  • Updates resolveFilesTouched to merge state-based and tracking-file-based file lists, falling back to transcript extraction only when both are empty, with cleanup at condensation and carry-forward points

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
cmd/entire/cli/agent/event.go Adds FileEdit event type and FilePath field to the Event struct
cmd/entire/cli/agent/claudecode/lifecycle.go Adds parseFileEdit method and registers HookNamePostFileEdit in hook names
cmd/entire/cli/agent/claudecode/lifecycle_test.go Tests for parseFileEdit and AllHookTypes coverage
cmd/entire/cli/agent/claudecode/hooks.go Registers PostToolUse[Write] and PostToolUse[Edit] hook matchers during installation
cmd/entire/cli/agent/claudecode/hooks_test.go Verifies Write and Edit hook matchers are installed alongside existing hooks
cmd/entire/cli/hook_registry.go Classifies post-file-edit as a "tool" hook type
cmd/entire/cli/lifecycle.go Adds handleLifecycleFileEdit with fail-open, lightweight file tracking
cmd/entire/cli/session/state.go Implements AppendFileTouched, ReadFilesTouched, ClearFilesTouched on StateStore
cmd/entire/cli/session/state_test.go Comprehensive unit tests for file tracking storage including security and edge cases
cmd/entire/cli/strategy/manual_commit_hooks.go Merges tracking file data in resolveFilesTouched, clears tracking at condensation/carry-forward
cmd/entire/cli/strategy/manual_commit_test.go Tests for tracking file read and merge behavior in resolveFilesTouched
cmd/entire/cli/integration_test/hooks.go Adds SimulatePostFileEdit test helper
cmd/entire/cli/integration_test/file_tracking_test.go End-to-end integration test for file tracking through hook binary
cmd/entire/cli/integration_test/agent_test.go Updates expected hook count from 7 to 9

khaong and others added 3 commits March 6, 2026 22:40
- Add Debug/Warn logging at silent error suppression points in
  parseFileEdit, handleLifecycleFileEdit, and resolveFilesTouched
- Extract clearFilesTracking helper to deduplicate cleanup pattern
- Simplify merge loop in resolveFilesTouched using append
- Use ReadFilesTouched in integration test instead of manual dedup
- Add test for parseFileEdit with malformed tool_input JSON

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: d7ebe011b701
@khaong
Copy link
Contributor Author

khaong commented Mar 6, 2026

bugbot run

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

khaong and others added 2 commits March 6, 2026 22:59
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 35db4ea2bbf4
@khaong khaong marked this pull request as ready for review March 6, 2026 12:15
@khaong khaong requested a review from a team as a code owner March 6, 2026 12:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants