| name | witr-process-inspector |
| description | CLI and TUI tool that explains why processes, services, and ports are running by tracing causality chains across supervisors, containers, and shells. |
| triggers | ["why is this process running","inspect running processes with witr","trace process causality","find what started a service","witr TUI dashboard","check what's listening on a port","use witr to debug running services","explain process chain with witr"] |
witr — Why Is This Running?
Skill by ara.so — Daily 2026 Skills collection.
witr is a Go CLI/TUI tool that answers "why is this running?" for any process, service, or port. Instead of leaving you to correlate ps, lsof, ss, systemctl, and docker ps manually, witr makes the causality chain explicit — showing where a running thing came from, how it was started, and what chain of supervisors/containers/shells is responsible.
Installation
Quickest (Unix)
curl -fsSL https://raw.githubusercontent.com/pranshuparmar/witr/main/install.sh | bash
Quickest (Windows PowerShell)
irm https://raw.githubusercontent.com/pranshuparmar/witr/main/install.ps1 | iex
Package Managers
brew install witr
conda install -c conda-forge witr
yay -S witr-bin
winget install -e --id PranshuParmar.witr
scoop install main/witr
sudo apk add --allow-untrusted ./witr-*.apk
go install github.com/pranshuparmar/witr/cmd/witr@latest
Key Commands & Flags
Basic Usage
witr <pid>
witr <name>
witr --port <port>
witr -p <port>
witr --interactive
witr -i
witr --all
witr -a
witr --json <pid>
witr --watch <pid>
witr -w <pid>
witr --verbose <pid>
witr -v <pid>
witr --user <username>
witr --version
Common Flag Reference
| Flag | Short | Description |
|---|
--port | -p | Inspect by port number |
--interactive | -i | Launch TUI dashboard |
--all | -a | Show all processes |
--json | | Output as JSON |
--watch | -w | Auto-refresh/follow |
--verbose | -v | Full metadata output |
--user | | Filter by OS user |
--version | | Print version |
Interactive TUI Mode
Launch the full dashboard:
witr -i
witr --interactive
TUI Keybindings:
| Key | Action |
|---|
↑ / ↓ | Navigate process list |
Enter | Expand process detail / causality chain |
f | Filter/search processes |
s | Sort by column |
r | Refresh |
j | Toggle JSON view |
q / Ctrl+C | Quit |
Example Outputs
Inspect a PID
witr 1234
PID: 1234
Name: node
Binary: /usr/local/bin/node
Started: 2026-03-18 09:12:44
User: ubuntu
Why is this running?
└─ Started by: npm (PID 1200)
└─ Started by: bash (PID 1180)
└─ Started by: sshd (PID 980)
└─ Started by: systemd (PID 1) [service: sshd.service]
Inspect by Port
witr --port 8080
Port: 8080 (TCP, LISTEN)
Process: python3 (PID 4512)
Binary: /usr/bin/python3
User: deploy
Why is this running?
└─ Started by: gunicorn (PID 4490)
└─ Started by: systemd (PID 1) [service: myapp.service]
Unit file: /etc/systemd/system/myapp.service
ExecStart: /usr/bin/gunicorn app:app --bind 0.0.0.0:8080
JSON Output (for scripting)
witr --json 4512
{
"pid": 4512,
"name": "python3",
"binary": "/usr/bin/python3",
"user": "deploy",
"started_at": "2026-03-18T09:00:00Z",
"causality_chain": [
{"pid": 4490, "name": "gunicorn", "type": "parent"},
{"pid": 1, "name": "systemd", "type": "supervisor", "service": "myapp.service"}
]
}
Watch/Follow a Process
witr --watch 4512
Common Patterns
Find Who Started a Port Listener
witr --port 5432
witr --json --port 5432 | jq '.causality_chain[-1].service'
Audit All Running Services
witr --all | less
witr --all --json > audit.json
Inspect a Docker/Container Process
witr <pid-of-containerized-process>
Use in a Shell Script
#!/usr/bin/env bash
if witr --json --port 8080 > /tmp/witr_out.json 2>/dev/null; then
SERVICE=$(jq -r '.causality_chain[-1].service // "unknown"' /tmp/witr_out.json)
echo "Port 8080 is owned by service: $SERVICE"
else
echo "Port 8080 is not in use"
fi
Filter Processes by User
witr --all --user www-data
Platform Support
| Platform | Architectures | Notes |
|---|
| Linux | amd64, arm64 | Full support |
| macOS | amd64, arm64 (Apple Silicon) | Full support |
| Windows | amd64 | Full support |
| FreeBSD | amd64, arm64 | Full support |
Go Integration (Embedding witr Logic)
If you want to use witr programmatically in a Go project:
go get github.com/pranshuparmar/witr
package main
import (
"fmt"
"github.com/pranshuparmar/witr/pkg/inspector"
)
func main() {
result, err := inspector.InspectPID(1234)
if err != nil {
panic(err)
}
fmt.Printf("Process: %s\n", result.Name)
for _, link := range result.CausalityChain {
fmt.Printf(" └─ %s (PID %d)\n", link.Name, link.PID)
}
}
result, err := inspector.InspectPort(8080, "tcp")
if err != nil {
panic(err)
}
fmt.Printf("Port 8080 owned by PID %d (%s)\n", result.PID, result.Name)
Troubleshooting
Permission Denied on Some PIDs
sudo witr <pid>
sudo witr --port 80
Binary Not Found After Install
export PATH="$PATH:/usr/local/bin"
export PATH="$PATH:$(go env GOPATH)/bin"
Port Not Found / No Output
ss -tlnp | grep <port>
netstat -an | grep <port>
witr --port <port>
TUI Not Rendering Correctly
export TERM=xterm-256color
witr --interactive
Process Exited Before Inspection
witr --watch <pid>
macOS: Requires Elevated Access for Some Processes
sudo witr <pid>
Quick Reference Card
witr <pid> # Why is PID X running?
witr <name> # Why is process "nginx" running?
witr -p <port> # What's on port 8080 and why?
witr -i # Interactive TUI dashboard
witr -a # Show all processes + causality
witr --json <pid> # Machine-readable output
witr -w <pid> # Watch/follow a process
witr -v <pid> # Verbose: full env + metadata
witr --user <user> # Filter by OS user