Why did that change???

When your coding agent inevitably makes a change you didn't expect or ask for, why-diff shows the request it was working on, the tool call during which the edit appeared, and the patch.

Install with Homebrew
$ brew install prsuyal/tap/why-diff
Use your agent of choiceIntegration details
  • Codex
  • Claude Code
  • Cursor
  • Gemini CLI
  • Copilot CLI

Codex is verified end to end; the other integrations in v0.2.0 are experimental.

Reviewing an agent's changes

01 / 03

The diff

02 / 03

The command

03 / 03

The result

demosession-policy.yaml — demo
◇ session-policy.yaml ×
demo › deploy › session-policy.yaml
1password_reset:
2- revoke_existing_sessions: false
2+ revoke_existing_sessions: true
3- audit_event: enabled
3+ audit_event: disabled
4refresh_tokens:
5- ttl: 30m
5+ ttl: 30d
6 rotate_on_use: true
TERMINALzsh
Gitsession-policy.yaml · Ln 3

Editor mockup. Terminal output comes from a local test run using scripted Codex hooks.

01 / 03

The diff

deploy/session-policy.yaml
1password_reset:
2- revoke_existing_sessions: false
2+ revoke_existing_sessions: true
3- audit_event: enabled
3+ audit_event: disabled
4refresh_tokens:
5- ttl: 30m
5+ ttl: 30d
6 rotate_on_use: true
02 / 03

The command

TERMINAL zsh
~/demo %why-diff why deploy/session-policy.yaml:3
03 / 03

The result

TERMINAL zsh
~/demo %why-diff why deploy/session-policy.yaml:3
deploy/session-policy.yaml:3 changed while Bash — sh scripts/render-session-policy.sh ran.Request: Revoke existing sessions after a password reset Patch:diff --git a/deploy/session-policy.yaml b/deploy/session-policy.yamlindex 805c9bf..8527d36 100644--- a/deploy/session-policy.yaml+++ b/deploy/session-policy.yaml@@ -1,6 +1,6 @@ password_reset:-  revoke_existing_sessions: false-  audit_event: enabled+  revoke_existing_sessions: true+  audit_event: disabled refresh_tokens:-  ttl: 30m+  ttl: 30d   rotate_on_use: true Tests: `go test ./...` failed before and passed afterward. Session: demo-sessionEvidence IDs:- Tool started:   01M3FCMG0TFDA9T7HXCDGKMMPD- Tool completed: 01M3FCMG2X1HPTSWBXCVKS7X6A- Before tree:    7db0cc58b0b1be07609cf3bbb62afc44b91edca8- After tree:     f375c6e7f797702ecf67c467c3f9f1f80e7ba4a6- Test failed:    01M3FCMFSVGY5RT4KAHGKC0C7M (tool_response.exit_code=1)- Test passed:    01M3FCMGEDSYHA0EG5FGPD665F (tool_response.exit_code=0) 

Editor mockup. Terminal output comes from a local test run using scripted Codex hooks.

How why-diff records and finds changes

why-diff records the Codex session

Codex sends your prompts, tool calls, and results through hooks, and why-diff stores them in this repository.

Compare Git snapshots

Snapshots around a tool call can show edits made by a script, even if the agent later undoes them.

Look up a changed file or even a specific line

REQUESTRevoke existing sessions
TOOLrender-session-policy.sh
PATCHaudit_event: enabled → disabled
TESTSfailed → passed
01why-diff init [ --global]

Add Codex hooks for this repository or all Git repositories.

02why-diff sessions

List captured sessions.

03why-diff show [session]

Read a session's prompts, tool calls, and results.

04why-diff diff [session]

See file changes captured during a session.

05why-diff why <file[:line]>

See the request, tool call, and patch for a changed file or line.

06why-diff doctor

Check hook setup and report capture problems.

Install why-diff

Quick install script

$ curl -fsSL https://raw.githubusercontent.com/prsuyal/why-diff/main/scripts/install.sh | sh

Downloads the release archive and verifies its SHA-256 checksum.

After installing

Enable the Codex hooks

All Git repositories
$ why-diff init --global
A specific repository
$ why-diff init

Review and trust the hooks in Codex, then start a new session. Setup instructions