The Problem

Developers frequently need to locate, inspect, and terminate stray network listeners—especially when juggling local services, Kubernetes port‑forwards, or Cloudflare tunnels. Manually hunting PIDs, handling cross‑platform quirks, and keeping UI feedback in sync is error‑prone and time‑consuming.

What This Does

Port‑Killer provides a native UI for macOS (Swift) and Windows (C#) plus a lightweight Linux CLI. The CLI entry point is platforms/linux/src/main.py; it loads configuration (config.py), discovers ports via scanner.py, and delegates actions to service modules (services/clipboard.py, services/cloudflare.py, services/k8s.py). On macOS the UI layer lives under platforms/macos/Sources/, with PortKillerApp.swift bootstrapping the app and wiring view models (e.g., PortForwardManager.swift) to the core Rust library (portkiller-core/src/lib.rs). The Windows solution is a WPF app anchored at platforms/windows/PortKiller/App.xaml.cs.

How It Is Wired

  1. Linux CLI – Execution starts in platforms/linux/src/main.py. - Imports config, scanner, and UI helpers (ui/tray.py, ui/window.py). - main() calls scanner.scan_ports() (defined in scanner.py) which returns a list of PortInfo objects. - Selected actions invoke service functions: services/k8s.start_forward(), services/cloudflare.list_tunnels(), or services/clipboard.copy(). - UI updates are sent through the tray or window modules, which each import up to seven other UI helpers (e.g., ui/tray.py imports dialog, styles, and window).
  1. macOS App – The binary entry point is PortKillerApp.swift. - Instantiates AppState (multiple extensions add auto‑refresh, favorites, etc.). - AppState holds references to manager classes (PortForwardManager, KubernetesDiscoveryManager, NamedTunnelManager). - Each manager calls into the Rust core via the portkiller-core crate (src/lib.rs). The Rust library exposes a C‑ABI bridge used by Swift through generated headers. - UI views (Views/*) observe manager publishers; the most connected view is Views/CloudflareTunnels/NamedTunnelDetailView.swift (57 levels of nesting reported).
  1. Windows AppApp.xaml.cs creates the main window, loads XAML resources, and calls into the same service layer (services/*.cs) that mirrors the Linux Python logic.

No circular import cycles were detected; the highest fan‑in module is platforms/linux/src/config.py (imports from four other modules, no outward imports).

How To Use It

# Clone the repo
git clone https://github.com/moses-y/port-killer
cd port-killer

# Linux – install Python deps (no lockfile, see health notes)
pip install -r requirements.txt   # requirements.txt not present; install manually if needed

# Run the CLI
python platforms/linux/src/main.py   # starts scanner and UI tray

# macOS – build the app
cd platforms/macos
swift build -c release            # uses Package.swift; produces a .app bundle

# Windows – open the solution
start platforms/windows/PortKiller.sln   # build in Visual Studio 2022

Configuration lives in platforms/linux/src/config.py (Python dict) and in the macOS Swift AppState extensions. No environment variables are required out of the box.

Real‑World Use

A backend engineer runs the CLI on a CI worker to ensure no stray ports remain after integration tests:

python platforms/linux/src/main.py --kill --filter "port==8080"

The command scans, matches the test server’s port, and issues a graceful then forced termination, preventing port‑collision failures in subsequent pipeline stages.

Code Health & Issues

Static analysis findings (30 high, 75 medium, 0 low):

  • Broad exception handling (2 files): platforms/linux/src/services/cloudflare.py, platforms/linux/src/ui/dialogs.py.
  • Deep nesting (57 occurrences): e.g., platforms/macos/Sources/Views/CloudflareTunnels/NamedTunnelDetailView.swift.
  • Duplicated code blocks (repeated 99 × 6‑line fragments across ~40 files).

Code‑health audit (9 findings):

  • HIGH – Pin GitHub Actions to commit SHA (.github/workflows/*).
  • HIGH – Release workflow pushes directly to main (.github/workflows/release.yml).
  • MEDIUM – No least‑privilege GITHUB_TOKEN permissions (.github/workflows/ci-linux.yml).
  • MEDIUM – No Dependabot/Renovate configuration.
  • MEDIUM – No dependency‑vulnerability gate in CI.
  • MEDIUM – Checkout step keeps credentials; should set persist-credentials: false.
  • MEDIUM – Test coverage low (5 tests vs. 195 source files).
  • LOW – No job timeouts in CI workflows.
  • LOW – Missing repo convention files (.editorconfig, formatter config, etc.).

Additional hygiene notes: CI present, licence MIT, no lockfile for package.json, no Dockerfile, no committed secrets.

The Bottom Line

Port‑Killer delivers a functional cross‑platform port‑management UI with a solid core written in Rust, but the codebase suffers from deep nesting, duplicated logic, and limited test coverage. The CI pipeline needs hardening (pinned actions, proper token scopes, dependency scanning). It is suitable for teams that can invest in refactoring and CI improvements while gaining immediate UI‑driven port control.