How pranshuparmar/witr works
1. What this repo is
- witr is a cross-platform Go CLI and terminal UI that explains “why is this running?” by tracing a running thing back to the process, service, container, shell, or scheduler responsible for it.
2. Entry points and startup
- The executable starts in main.go / cmd/witr/main.go, which hand off to the app layer in internal/app.
- The app layer parses flags, decides between one-shot output vs interactive TUI, and routes the request into the analysis pipeline.
3. Shared domain model
- pkg/model is the stable data contract between all subsystems.
- It defines the normalized objects the rest of the repo works with: Process, Container, Source, Target, Result, Socket, Net, Lock, Resource, and file-context metadata.
- This keeps OS-specific collection code separate from output and UI rendering.
4. Target resolution layer
- internal/target turns user input into concrete lookup targets.
- It resolves names, PIDs, ports, files, and container references into the canonical target set the analyzer can process.
- This is the boundary between “user intent” and “system facts.”
5. Process and system introspection layer
- internal/proc is the largest subsystem and contains the OS adapters for process discovery, ancestry, command lines, environments, open files, sockets, locks, resource usage, and boot/runtime details.
- It is heavily split by platform: Linux leans on /proc, macOS on ps/lsof/sysctl and libproc, Windows on Win32 APIs, and FreeBSD on procstat/ps/lsof.
- This layer also includes container/runtime detection helpers and wrappers for Docker-like runtimes and system services.
6. Source attribution / “why” classification
- internal/source interprets the collected facts and decides what primary system explains the process’s existence.
- It covers supervisors and launch mechanisms such as systemd, launchd, cron, shells, SSH sessions, container runtimes, Windows services, and BSD rc-style sources.
- The output deliberately chooses one primary source while still allowing warnings and secondary context.
7. Analysis pipeline
- internal/pipeline/analyze.go is the central orchestrator that combines targets, process facts, source attribution, and warnings into final results.
- This is where the repo’s causal model is assembled: “target → PID(s) → ancestry → source → context → warnings.”
8. Output rendering subsystem
- internal/output renders the same result model into multiple presentations: standard narrative text, short form, tree view, JSON, environment-only output, warnings-only output, and Docker/container-specific formatting.
- It includes color handling, sanitization, and safe writing so sensitive or malformed content is controlled before reaching the terminal.
- This subsystem is intentionally decoupled from collection logic so the same analysis can serve CLI, scripting, and TUI use cases.
9. Interactive TUI
- internal/tui provides the dashboard mode with tabs for processes, ports, containers, and locks.
- It reuses the same underlying data model as the CLI, but adds live navigation, filtering, selection, and process actions such as signal/renice on Unix-like systems.
- The TUI is a view/update/action layer over the same analysis and proc data, not a separate code path.
10. Platform-specific boundaries and external dependencies
- Platform behavior is isolated using build tags throughout internal/proc, internal/source, internal/target, internal/output, and internal/tui.
- The main external boundary is the host operating system and its native APIs or command-line tools; container lookup may also depend on runtime CLIs such as Docker, Podman, nerdctl, crictl, or FreeBSD jail tooling being available on PATH.
- internal/launchd and internal/tools/docgen are support subsystems for macOS plist parsing and documentation generation, while the .github, goreleaser, and install scripts support release/distribution rather than runtime behavior.
Main entry points: analyze.go Analyze · result.go Model · app.go App · detect.go Detect
Components 19
Entry
CLI startup and versioning
Core
Targeting, analysis, and shared domain model
- App · Parses flags and selects execution mode
internal/app/app.go - Targeting · Resolves names, PIDs, ports, files, and containers
internal/target/resolve.go - Analyze · Builds final explanation from targets and facts
internal/pipeline/analyze.go - Model · Shared normalized result and fact types
pkg/model/result.go
Proc
OS and runtime introspection
- Processes · Process discovery, ancestry, command lines, env, and files
internal/proc/process_linux.go - Runtime · Container and jail runtime detection
internal/proc/runtime_dockerlike.go - System I/O · Sockets, locks, resources, and open files
internal/proc/net_linux.go - Boot & Users · Boot time, sessions, and user context
internal/proc/boot_linux.go
Source
Why-this-runs attribution
- Detect · Chooses the primary explanation source
internal/source/detect.go - Supervisors · Systemd, launchd, cron, shell, SSH, and services
internal/source/supervisor.go - Containers · Container and runtime-based attribution
internal/source/container.go - Network · Port and socket-based attribution
internal/source/network.go
Presentation
CLI and TUI rendering
Connections 24
- Main → Witr cmd: delegates · Top-level entry hands off to command bootstrap
- Witr cmd → App: starts · Bootstraps the application layer
- App → Targeting: resolves · Turns user input into canonical targets
- App → Analyze: analyzes · Runs the causal analysis pipeline
- App → Output: renders · Sends results to the selected output format
- App → TUI: interactive mode · Switches to dashboard mode when requested
- Analyze → Model: produces · Assembles the shared result model
- Analyze → Processes: queries · Collects process and ancestry facts
- Analyze → Runtime: checks · Looks for container and runtime context
- Analyze → System I/O: collects · Uses sockets, locks, files, and resource data
- Analyze → Detect: classifies · Chooses the primary explanation source
- Processes → Model: normalizes · Maps OS-specific facts into shared types
- Runtime → Model: normalizes · Feeds container/runtime facts into shared types
- System I/O → Model: normalizes · Feeds I/O and resource facts into shared types
- Boot & Users → Processes: supports · Provides host boot and user context
- Detect → Supervisors: uses · Delegates to supervisor and launch source classifiers
- Detect → Containers: uses · Delegates to container attribution
- Detect → Network: uses · Delegates to port and socket attribution
- Detect → Model: emits · Writes source and warning context into the result model
- Output → Model: reads · Renders the shared result contract in multiple formats
- TUI → Model: reads · Uses the same underlying data model as CLI output
- Launchd → Supervisors: supports · Used by macOS launchd attribution paths
- Docgen → Output: documents · Generates CLI documentation from command behavior
- Version → App: configures · Provides version metadata to the application