Diagnose CI failures instantly — extract signal lines and explain them in plain English
Project description
CI logs are noisy. A failed GitHub Actions run gives you hundreds of lines of downloading, copying, grouping, and progress output — and somewhere buried in it is the 3 lines that actually matter.
ci-why strips the noise, extracts the signal lines with context, and optionally asks Claude to explain the root cause and give you concrete fix steps.
No CI platform lock-in. Works on any log you can pipe or point at a file.
Install
pip install ci-why
Or with pipx (recommended for CLI tools — keeps it isolated):
pipx install ci-why
Usage
# From a log file
ci-why build.log
# Pipe directly from GitHub CLI
gh run view --log | ci-why -
# Pattern analysis only — no API call
ci-why build.log --no-ai
# Just the raw extracted failure lines (great for piping)
ci-why build.log --raw
# More context lines around each failure
ci-why build.log --context 5
# Scan only the last N lines (for huge logs)
ci-why build.log --max-lines 10000
AI explanation
Set your Anthropic API key to get plain-English root cause analysis and fix steps:
export ANTHROPIC_API_KEY=sk-ant-...
ci-why build.log
Without the key, ci-why still works — it shows the extracted failure lines using pattern matching only. The AI explanation is additive, not required.
What it recognises
ci-why detects failure signals across Python, Node, Go, Rust, and generic CI output:
| Signal | Examples |
|---|---|
| Test failures | FAIL, AssertionError, Jest ●, pytest FAILED |
| Errors & tracebacks | Traceback (most recent call last), panic:, fatal error |
| Exit codes | Process completed with exit code 1 |
| Missing modules | ModuleNotFoundError, Cannot find module |
| Build errors | Build failed, SyntaxError, compilation error |
| Dependency errors | npm ERR!, yarn error, pip error, ERESOLVE |
| Network / timeout | Connection refused, ECONNREFUSED, timed out |
| Lint / type errors | ESLint, mypy, ruff, TypeScript TS2345: |
| Permission errors | Permission denied, EACCES |
Noise filtered out: download progress, [debug] lines, file copy progress, GHA group markers, already-installed notices.
All options
Arguments:
SOURCE CI log file path, or '-' to read from stdin.
Options:
--no-ai Skip AI explanation; show pattern matches only.
--raw Print extracted failure lines as plain text and exit.
-c, --context Lines of context around each failure (default: 2, max: 10).
--max-lines Truncate log to this many lines before scanning (default: 50000).
--help Show this message and exit.
Examples
GitHub Actions log via CLI:
gh run view 1234567890 --log | ci-why -
GitLab CI — download job log and analyse:
curl -H "PRIVATE-TOKEN: $GITLAB_TOKEN" \
"https://gitlab.com/api/v4/projects/123/jobs/456/trace" | ci-why -
Save just the failure lines to a file:
ci-why build.log --raw > failures.txt
Use in a script — exit code reflects whether failures were found:
ci-why build.log --no-ai --raw || echo "Failures detected"
Where to install / publish this tool
| Platform | Command | Notes |
|---|---|---|
| PyPI | pip install ci-why |
Primary distribution |
| pipx | pipx install ci-why |
Best for CLI tools — isolated environment |
| Homebrew (tap) | brew install gitwingo/tap/ci-why |
macOS/Linux users who avoid pip |
| GitHub Releases | Single .py file download |
Zero-install option |
| npm wrapper | npm install -g ci-why |
Reaches frontend/Node developers |
Recommended publishing order: PyPI → pipx (works automatically) → Homebrew tap after traction → npm wrapper if Node developer adoption is strong.
Development
git clone https://github.com/gitwingo/ci-why
cd ci-why
pip install -e .
Support
If sniff-schema has been useful to you, consider supporting its development:
Connect
- GitHub: @gitwingo
- Reddit: u/gitwingo
- X / Twitter: @gitwingo
License
MIT © gitwingo
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ci_why-0.1.0.tar.gz.
File metadata
- Download URL: ci_why-0.1.0.tar.gz
- Upload date:
- Size: 101.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f474f9a28fbdae15b8302006060c3890fa79f2423dff79f7c11a1b104fc4ac1
|
|
| MD5 |
dfdf9307527631be20edd44a2b0808b2
|
|
| BLAKE2b-256 |
58eee5b138e619c670a5fd2d5dbec915f24087541c1c14ac2f3ed56042d2a918
|
Provenance
The following attestation bundles were made for ci_why-0.1.0.tar.gz:
Publisher:
publish.yml on gitwingo/ci-why
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ci_why-0.1.0.tar.gz -
Subject digest:
3f474f9a28fbdae15b8302006060c3890fa79f2423dff79f7c11a1b104fc4ac1 - Sigstore transparency entry: 1432078077
- Sigstore integration time:
-
Permalink:
gitwingo/ci-why@d524370505cc10961f813525e04508cab27ff99b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/gitwingo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d524370505cc10961f813525e04508cab27ff99b -
Trigger Event:
release
-
Statement type:
File details
Details for the file ci_why-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ci_why-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b51e18cfdb84c99c901a366883b95864eeafe302a702ace2c5b7e4d760e861b5
|
|
| MD5 |
e132a919162c001af94781fc2baecdd2
|
|
| BLAKE2b-256 |
7547fedbb8bdddfedf19fd3a6db46373b3972b3ab95899a268e090908ed77762
|
Provenance
The following attestation bundles were made for ci_why-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on gitwingo/ci-why
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ci_why-0.1.0-py3-none-any.whl -
Subject digest:
b51e18cfdb84c99c901a366883b95864eeafe302a702ace2c5b7e4d760e861b5 - Sigstore transparency entry: 1432078566
- Sigstore integration time:
-
Permalink:
gitwingo/ci-why@d524370505cc10961f813525e04508cab27ff99b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/gitwingo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d524370505cc10961f813525e04508cab27ff99b -
Trigger Event:
release
-
Statement type: