Skip to content

[FEAT] --diff-base flag: scope all analysis commands to changed files only #157

Description

@Wolfvin

Background

CodeLens currently scans the full repo on every invocation. In CI environments (PR checks, pre-merge gates), this means re-analyzing hundreds of unchanged files on every commit — wasting time and producing noise from pre-existing findings that are irrelevant to the current change.

Strix (a dynamic pentest agent) solves this with a --scope-mode diff + --diff-base pattern that limits analysis to changed files only. The same approach applies cleanly to CodeLens's static model.

Goal

Add a --diff-base <ref> global flag (and optionally --diff-base HEAD~1 as a shortcut) that pre-filters the file list for any analysis command to only files changed relative to the given ref.

# Only scan files changed vs main
codelens check . --diff-base main
codelens taint . --diff-base main
codelens vuln-scan . --diff-base origin/HEAD
codelens scan . --diff-base HEAD~1

Implementation

This is a pre-filter layer, not new analysis logic:

  1. When --diff-base <ref> is provided, run:
    subprocess.run(['git', 'diff', '--name-only', ref, 'HEAD'], capture_output=True)
  2. Parse the output into a set of changed file paths
  3. Pass this set as an allowlist to the existing file discovery layer — unchanged files are skipped before any parsing/analysis begins
  4. If the diff is empty (no changed files), exit early with a clear message

The filter should live in a shared DiffScope utility class used by all commands, so it's a single implementation point rather than per-command.

Definition of Done

  • --diff-base <ref> flag accepted by all analysis commands (check, scan, taint, vuln-scan, dead-code, secrets, complexity, circular)
  • git diff --name-only output used as file allowlist before file discovery
  • Empty diff → early exit with message No changed files relative to <ref>
  • Invalid ref → clear error, non-zero exit
  • --diff-base documented in --help output for each affected command
  • SKILL.md updated: CI usage example with --diff-base
  • sync_command_count.py --apply run (count unchanged — this is a flag, not a new command)

Source of Truth

  • Existing file discovery logic: scripts/codelens.py + individual command files in scripts/commands/
  • DiffScope utility: new module, scripts/utils/diff_scope.py (suggested location)
  • Strix reference: strix/core/scope.py in https://github.com/usestrix/strix (public repo — read for inspiration, do not copy)

CI use case

- name: CodeLens diff check
  run: python scripts/codelens.py check . --diff-base origin/main --format sarif > codelens.sarif

This replaces a full-repo scan on every PR with a targeted scan of only what changed — the primary use case this flag enables.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions