Skip to content

Repository files navigation

why

Find out why things are on your computer.

$ why protobuf
protobuf 35.1
Location
  /opt/homebrew/Cellar/protobuf/35.1 (likely)
Required by
  onnx [Homebrew]
  openai-whisper [Homebrew]
  openvino [Homebrew]
  pytorch [Homebrew]
  qt [Homebrew]
  qtgrpc [Homebrew]
Safe to remove?
  No — 6 installed packages depend on it.

No brew uses, no dpkg -S, no lsof, no /proc spelunking. Just ask.

$ why python
python
Resolves to
  /opt/homebrew/bin/python3.13
$ why 8080
Port 8080
Listening
  node (PID 48192)
Started by
  node server.js
$ why ~/.cache/huggingface
~/.cache/huggingface
Likely belongs to
  huggingface_hub (possible)

why is an evidence engine, not an AI assistant. Every line it prints traces back to something concrete on your machine — a PATH lookup, a package manager's own metadata, /proc, sysinfo. When it isn't sure, it says so ("possible", "likely") instead of guessing with confidence.

Works on macOS and Linux, without a daemon, account, network connection, LLM, root access, or config file. Normal queries finish in well under 200ms.

What it understands

Query What it explains
why python / why command python Which executable PATH actually resolves to, its symlink chain, and what it shadows
why protobuf / why package protobuf Which package manager installed it, its dependencies, and what would break if you removed it
why 8080 / why port 8080 What's listening on a port and the process chain that started it
why 48392 / why process 48392 A running process's command line, working directory, and parent chain
why ~/.cache/huggingface / why file ~/.cache/huggingface A conservative guess at who owns a file or directory, and whether it looks safe to clean up
why ollama / why service ollama A launchd/systemd service's executable, config file, and running process

Ambiguous input (why 8080 could be a port or a PID) isn't guessed — why checks which candidates actually exist and only asks you to disambiguate when more than one real match is found.

Package managers: Homebrew, Cargo, npm/pnpm, pip/pipx, apt/dpkg. Service managers: launchd, systemd.

Add --json for machine-readable output (stable schema_version), or --verbose to see the evidence behind every conclusion.

Install

Requires Rust 1.85+ and ~/.cargo/bin on your PATH.

cargo install why

Verify:

why --help
Build from source — for development or unreleased changes
git clone https://github.com/cesarferreira/why.git
cd why
cargo install --path . --locked
# or
make install-release

Debug install (faster compile, larger binary):

make install

Run without installing:

make build-release
./target/release/why

Development

Common tasks via the Makefile:

make              # check + build + test
make build        # debug build
make build-release
make install      # install debug binary
make install-release
make run ARGS="python"
make check        # cargo check + clippy
make fmt          # format
make lint         # fmt check + clippy
make test
make clean

Performance breakdown for any query:

WHY_TRACE=1 why protobuf

Releasing (requires cargo-release and git-cliff):

make release                  # default minor bump
make release LEVEL=patch      # patch bump
make release LEVEL=major      # major bump

The pre-release hook regenerates CHANGELOG.md with git-cliff from your conventional-commit history (grouped into Features, Bug Fixes, etc. per cliff.toml) and commits it alongside the version bump. Pushing the resulting v* tag triggers the release workflow, which builds the multi-platform binaries and publishes a GitHub Release whose notes are generated by git-cliff from the same config.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages