Metadata-Version: 2.4
Name: kubectl-ai-explain
Version: 0.1.0
Summary: Diagnose failing Kubernetes pods with an LLM — root cause + suggested fix, right in your terminal.
Author-email: Jay Tank <tankjai24@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/jay-tank/kubectl-ai-explain
Project-URL: Repository, https://github.com/jay-tank/kubectl-ai-explain
Project-URL: Issues, https://github.com/jay-tank/kubectl-ai-explain/issues
Keywords: kubernetes,kubectl,devops,ai,llm,sre,troubleshooting,kubectl-plugin
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: System :: Systems Administration
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: rich>=13.0
Provides-Extra: claude
Requires-Dist: anthropic>=0.40; extra == "claude"
Provides-Extra: openai
Requires-Dist: openai>=1.0; extra == "openai"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Dynamic: license-file

<div align="center">

# 🔍 kubectl-ai-explain

**Diagnose a failing Kubernetes pod with an LLM — get a plain-English root cause and suggested fix, right in your terminal.**

[![Python](https://img.shields.io/badge/Python-3.9%2B-3776AB?logo=python&logoColor=white)](https://www.python.org)
[![kubectl plugin](https://img.shields.io/badge/kubectl-plugin-326CE5?logo=kubernetes&logoColor=white)](https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/)
[![Providers](https://img.shields.io/badge/LLM-Claude%20%7C%20OpenAI%20%7C%20Ollama-8A2BE2)](docs/PROVIDERS.md)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)

</div>

---

## The problem

A pod is stuck in `CrashLoopBackOff`. So you run `kubectl describe pod …`, then `kubectl logs … --previous`, then `kubectl get events …`, then squint at the exit code and piece together what went wrong. Every time.

`kubectl-ai-explain` does that legwork for you:

```console
$ kubectl ai-explain checkout-api-6b9c7d -n prod

❌ Summary: The container is crashing on startup because it can't reach the database.
🔎 Likely cause (high confidence): DB_HOST is unset, so the app exits with code 1 before serving traffic.

📋 Evidence:
  • Container state is CrashLoopBackOff, exit code 1, 7 restarts
  • Logs: "SQLSTATE[HY000] [2002] Connection refused"

🔧 Suggested fixes:
  $ kubectl set env deployment/checkout-api DB_HOST=mysql-service
  $ kubectl rollout status deployment/checkout-api
```

## ✨ Features

- 🩺 **One command** - gathers the pod's status, events, and recent logs, and explains the failure.
- 🔌 **Provider-agnostic** - Claude (default), OpenAI, or a **local model via Ollama** (no API key, fully private).
- 🔒 **Secret-aware** - best-effort redaction of passwords/tokens/keys before anything is sent to an LLM, plus a `--dry-run` to see exactly what would be sent.
- 🧩 **Native kubectl plugin** - invoke as `kubectl ai-explain <pod>`.
- 📤 **Scriptable** - `--json` for machine-readable output.
- 🚫 **Read-only** - it suggests fix commands; it never runs them.

## 📦 Installation

**From source** (works today):

```bash
git clone https://github.com/jay-tank/kubectl-ai-explain.git
cd kubectl-ai-explain
pipx install .            # recommended — lands on PATH as a kubectl plugin
#   …or:  pip install --user .
```

Install a provider SDK for whichever backend you'll use (Ollama and the built-in
`mock` need none):

```bash
pip install --user '.[claude]'    # Anthropic Claude
pip install --user '.[openai]'    # OpenAI
```

> 📦 A published PyPI release (`pipx install kubectl-ai-explain`) is planned — until then, install from source as above.

Because the executable is named `kubectl-ai-explain`, `kubectl` auto-discovers it:

```bash
kubectl ai-explain --help     # works as a plugin
kubectl plugin list           # should list kubectl-ai-explain
```

## ⚡ Quick start

```bash
# Default provider is Claude — set your key (see PROVIDERS.md), then:
export ANTHROPIC_API_KEY=...          # your key, your environment
kubectl ai-explain my-pod -n prod

# No API key? Run a local model with Ollama:
kubectl ai-explain my-pod --provider ollama

# Just want to see what would be sent to the LLM (no call made)?
kubectl ai-explain my-pod --dry-run
```

## 🔧 Usage

```
kubectl ai-explain <pod> [options]

  -n, --namespace     Namespace (default: default)
      --container     Limit to a single container
      --context       kubectl context to use
      --tail          Log lines per container (default: 50)
      --provider      claude | openai | ollama | mock   (default: claude)
      --model         Model override (or $AI_EXPLAIN_MODEL)
      --json          Machine-readable JSON output
      --no-color      Disable colored output
      --dry-run       Print the redacted prompt and exit (no LLM call)
```

Full guide: [`docs/USAGE.md`](docs/USAGE.md) · provider setup: [`docs/PROVIDERS.md`](docs/PROVIDERS.md).

## 🔒 Privacy

To explain a failure, the tool sends the pod's **status, events, and recent log tail** to your chosen LLM. Before sending, it **redacts** common secret patterns (passwords, tokens, AWS keys, bearer tokens). Two extra guards:

- **`--dry-run`** prints the exact, redacted payload so you can review it first.
- **`--provider ollama`** keeps everything **on your machine** — nothing leaves your network.

Redaction is best-effort, not a guarantee — for sensitive clusters, prefer Ollama. See [`docs/PROVIDERS.md`](docs/PROVIDERS.md#privacy).

## 🧠 How it works

```
kubectl ai-explain <pod>
   └─ collector   → kubectl get pod -o json | get events | logs --previous
   └─ prompt      → distilled, secret-redacted, token-bounded context
   └─ provider    → claude | openai | ollama | mock   (pluggable)
   └─ render      → terminal report  (or --json)
```

## 🤝 Contributing

Contributions welcome — see [`CONTRIBUTING.md`](CONTRIBUTING.md). Run the tests with:

```bash
pip install -e '.[dev]' && pytest
```

## 📄 License

MIT — see [`LICENSE`](LICENSE).

---

<div align="center">
<sub>Saved you a <code>CrashLoopBackOff</code> rabbit hole? A ⭐ helps others find it.</sub>
</div>
