porthog-cli
v0.1.0
Published
See local TCP listeners, repositories and branches, and review dependency changes. Zero runtime package dependencies.
Maintainers
Readme
PortHog
Know what is listening. Know what changed.
PortHog shows local TCP listeners with their process, repository, and current Git branch. It also records project dependency baselines and explains changes after an update. One executable Python file. Two domain classes. Zero third-party runtime packages. MIT licensed.
Run it
Install through npm:
npm install --global [email protected]
porthog --depsOr run without a global install:
npx --yes [email protected] porthog --depsPython 3.9+ must already be installed as python3. npm distributes the CLI;
it does not install Python. The package has no npm dependencies or install
scripts. The npm package name is porthog-cli; the terminal command is porthog.
To run directly from a source checkout:
python3 porthog.py
python3 porthog.py --depsPython 3.9 or newer is required; use a maintained Python release when available.
macOS uses its system lsof; Linux uses /proc. Git provides repository and
branch information. Missing prerequisites are reported by porthog doctor.
Install from this source directory:
sh install.shThis copies one executable to ~/.local/bin/porthog. Add that directory to your
shell's PATH if needed. No pip, npm, virtual environment, sudo, or background
service is required. To choose a different destination:
sh install.sh --prefix /your/bin/directoryFind the port hog
porthog # current user's visible TCP listeners
porthog --port 3000 # who owns this port?
porthog --repo . # focus on this repository/directory
porthog --deps # include direct dependency counts
porthog watch # refresh every two seconds; Ctrl-C exits
porthog watch --interval 5
porthog list --json # full paths, numeric ports, stable schema
porthog doctorEvery visible TCP listener is included, because filtering by process name misses
custom development servers. Background applications therefore appear too. Use
--repo to focus. IPv4 and IPv6 addresses are shown separately. The branch is
the repository's current checkout at scan time, not proof of which revision
an already-running process loaded.
Make updates reviewable
From your project directory:
porthog deps
porthog snapshot # create .porthog-baseline.json
# Update your project using your normal package manager, then run its tests.
porthog check # compare against the saved baseline
porthog check --json # usable in scripts/CI
porthog snapshot --force # explicitly accept the new baselineYou can pass a project path to each command. Use snapshot --out FILE and
check --baseline FILE for a different baseline location. Existing baselines
are never overwritten without --force. Baselines belong to the absolute
project path where they were created; mismatched projects and unknown schemas
are rejected.
Dependency handling is offline inspection and change detection. PortHog does not install, upgrade, or execute project dependencies.
| Source | What PortHog reads |
| --- | --- |
| package.json | Direct runtime, dev, optional, and peer declarations |
| package-lock.json / npm-shrinkwrap.json | Direct locked versions for npm lock formats 1, 2, and 3 |
| requirements.txt | Python requirements, including exact pins and ranges |
| pyproject.toml | PEP 621 project dependencies when Python's built-in tomllib is available (3.11+) |
| Other recognized lockfiles | File fingerprints and explicit warnings when their versions cannot be parsed |
A changed lockfile is reported even if direct versions did not change, so transitive changes do not silently disappear. PortHog does not yet explain individual transitive dependency changes. It does not query package registries for outdated versions or vulnerabilities.
Version changes are labeled major, pre-1.0, review, or routine.
These labels prioritize review; they do not certify compatibility. A patch
release can still break your application. Git/URL dependencies, ambiguous
versions, declaration changes, and additions/removals need review.
Durable by design
- Small dependency surface: only Python's standard library at runtime.
- Explicit updates: PortHog never updates itself automatically.
- Recoverable shell install:
install.shvalidates and installs a replacement atomically; the previous executable is retained asporthog.previous. - Shell-install rollback:
sh install.sh --rollbackrestores the previous executable. Pass the same--prefixif you used a custom installation directory. - Versioned data: JSON output and baselines carry
schema_version: 1. Unknown baseline versions fail visibly rather than being guessed at. - No project execution: metadata is read from files; lifecycle scripts, dependency imports, and running servers are never invoked or probed.
- Bounded inspection: subprocess timeouts and manifest-size limits avoid waiting indefinitely on a broken project.
The installer backup and rollback apply only to install.sh installations.
For npm installations, explicitly install the desired version, for example
npm install --global [email protected]. npm does not create porthog.previous.
Choose one install method to avoid multiple porthog executables on your PATH.
These operations change the PortHog executable, not your project's dependencies;
use your package manager and version control to restore project dependencies.
A small cURL install
The installer accepts a release executable over HTTPS with a mandatory SHA-256 checksum. Once an actual release has been published, use its URL and digest:
sh install.sh --url "$PORTHOG_RELEASE_URL" --sha256 "$PORTHOG_RELEASE_SHA256"The download uses cURL, forbids redirects to plain HTTP, verifies the digest before execution, and validates the candidate before replacing the installed copy. Obtain both the installer and digest from a trusted release. A standalone HTTPS release URL for this installation method has not been configured.
SHA256SUMS records the hashes of this bundle's executable and installer.
Boundaries
macOS and Linux are supported backends. Windows is not implemented. Discovery is a best-effort snapshot: processes can exit, OS permissions can hide metadata, and a process may change its working directory. Repository/project association uses the listener's working directory and ancestors. Some launchers and service managers do not retain their project directory; those entries have unknown Git context rather than a guessed association.
Linux scans the current network namespace. Docker/VM-internal listeners and
repositories are not mapped to the host. Host-side published ports may appear
under their proxy process. UDP and Unix-domain sockets are outside v0.1.
--all-users includes other users where permissions allow; it does not elevate
privileges. PortHog does not stop or restart any process.
On Python 3.9/3.10, pyproject.toml can be fingerprinted but TOML dependency
parsing is unavailable; PortHog reports that limitation explicitly.
Dependency inspection targets one project directory. npm workspace graphs and
requirements -r/-c includes are not expanded in v0.1. deps explains this
limitation; baseline operations refuse incomplete coverage instead of reporting
a misleading clean check. Use a standalone project/flattened requirements file
for baselines. Lockfiles must be in the inspected project directory.
Automation contract
| Command/result | Exit status |
| --- | --- |
| Successful inspection, saved snapshot, or unchanged baseline | 0 |
| check detects dependency or fingerprint changes | 1 |
| Invalid input, unreadable supported manifest, invalid baseline, or missing required prerequisite in doctor | 2 |
| Interrupted command (except normal watch shutdown) | 130 |
list --json contains servers, warnings, schema_version, and
porthog_version. Each server has pid, process, host, port, cwd, repo,
branch, and project. Unknown metadata is JSON null. Discovery warnings
mean the snapshot may be incomplete, including an empty result.
Develop and contribute
python3 -m unittest discover -s tests -vThe production implementation is porthog.py: PortHog owns OS/process/Git
discovery; DependencyAudit owns manifest parsing, snapshots, and comparisons.
The CLI is a small set of presentation functions. install.sh owns installation
only. No build step is needed.
Tests exercise live socket discovery, detached Git states, npm lock formats, dependency changes, malformed baselines, and installation rollback. CI is configured for Linux and macOS across several Python releases. The configured CI matrix must run in your published repository before claiming full platform verification.
Keep dependencies at zero unless a concrete requirement justifies changing that contract. Add regression cases for new manifest formats. Preserve existing JSON fields within schema 1; introduce a new schema for incompatible changes. Before release, run tests, update the version and changelog, regenerate SHA256SUMS, and publish immutable versioned release artifacts with their checksums.
