← Librarylibrary

Claude Code

1 saved item in this collection.

snippet

Skip repeat reads of an unchanged file in a Claude Code mod

The core of reread-guard. A Read of the same file and range is denied while its size and mtime are unchanged; an immediate retry still goes through, because Claude Code can clear old tool results from context. The full mod also scopes this per subagent and resets on /compact and /clear.

typescript
import type { Register } from 'claude-code'

export const register: Register = on => {
  const seen = new Map<string, { size: number; mtimeMs: number }>()
  const skippedOnce = new Set<string>()

  on('tool.call', { tool: 'Read' }, async ($, e, next) => {
    const stat = await $.fs.stat(e.file_path, { resolve: true }).catch(() => undefined)
    if (!stat || stat.kind !== 'file') return next(e)

    const key = [e.file_path.toLowerCase(), e.offset ?? '', e.limit ?? ''].join('|')
    const before = seen.get(key)
    const unchanged = before?.size === stat.size && before?.mtimeMs === stat.mtimeMs

    if (unchanged && !skippedOnce.has(key)) {
      skippedOnce.add(key)
      // Short on purpose: the model reads it.
      return { deny: 'File unchanged since you read it; use that copy. If it is gone from context, retry the same Read.' }
    }

    skippedOnce.delete(key)
    seen.set(key, { size: stat.size, mtimeMs: stat.mtimeMs })
    const ran = await next(e)
    if (ran.deny !== undefined || ran.isError === true) seen.delete(key)
    return ran
  })
}
typescriptClaude CodeToken usage