Documentation menu
CLI walkthrough
CLIHeadless commands for tables, JSON, filters, process inspection, and scoped termination.
Use a named subcommand to stay in the CLI. Commands never open the TUI. They print to stdout or stderr and return a stable code.
There are five subcommands on every platform: list, inspect, kill, watch, and why. Only
kill ever signals anything. Windows supports read-only inspect and CLI --tree; --group
stays Linux/macOS-only. Use whichever binary you like • kick is shorter.
Listing ports
The table is plain, whitespace-separated text with no box-drawing • so it stays friendly to
grep and awk. Withheld metadata shows as -. The LABEL column appears once you’ve configured
endpoint labels.
Human-readable endpoints retain IPv6 interface scope, for example [fe80::1%3]:5353, throughout
the list table, TUI, inspect, watch, Why, search, diagnostics, and kill confirmations.
%unavailable means the native collector could not report an interface index, which is expected
for IPv6 observations on Linux and macOS; it is not part of the literal address or an error. Legacy
list --json remains unchanged; versioned structured output carries scope separately.
Narrowing the list
kick list --port 3000
kick list --process node
kick list --filter scope:public
kick list --filter 'label:web family:ipv4'
kick list --sort pid--port PORT• only the rows bound to one exact port.--process TEXT• rows whose process name contains the text.--filter TEXT• TUI-style search text or structured filters (see filters).--sort MODE•port,pid,protocol,process,parent, orscope.
JSON for scripts
list --json prints a stable, documented shape • the field names and enum casing are a contract,
so it’s safe to parse.
[
{
"protocol": "tcp",
"local_addr": "127.0.0.1",
"local_port": 3000,
"state": "listen",
"pid": 18422,
"process_name": "node",
"executable_path": "/usr/bin/node",
"command_line": "node server.js",
"parent_pid": 18001,
"parent_process_name": "cursor-agent",
"child_pids": [],
"protected": false,
"platform": "linux",
"permission": "full",
"label": "web dev"
}
]
Missing metadata is null, never an empty string. An empty result is always [].
For the complete in-scope observation • every native TCP state, owner identity, completeness, and
evidence gap • use --snapshot-json instead:
kick list --snapshot-jsonSnapshot mode deliberately ignores --port, --process, --filter, --sort, and
hide_system_processes, and omits full command lines. See
Structured output.
Killing by port or PID
kill needs exactly one target • a --port or a --pid • and asks before it does anything.
kick kill --port 3000
kick kill --pid 18422
kick kill --port 3000 --yes
kick kill --pid 18422 --force--force• stronger force confirmation; Unix useskill -9, while Windows delivery is hard termination either way.--yes• skip the normal prompt for a target you already trust.
Inspecting a process family
inspect is the read-only way to choose the right root before a scoped kill. It shows ancestors,
descendants, siblings, command lines, ports, and suggested tree commands. Linux/macOS also show
process-group members and --group hints.
kick inspect --port 3000
kick inspect --pid 18422Tree and group scope
Normal kill still targets one PID. --tree adds descendant cleanup on Linux, macOS, and Windows;
--group is the Linux/macOS-only POSIX process-group scope:
kick kill --port 3000 --tree
kick kill --pid 18422 --tree
kick kill --pid 18422 --group--tree• terminate the target and its descendants. Typetreeto confirm, orforcewith--force.--group• terminate every visible member of the target’s POSIX process group. Typegroupto confirm, orforcewith--force.--treeand--groupconflict; pick one scope.- Windows rejects
--groupand does not expose TUIt/Ttree keys. Windows CLI--treeuses Job Object containment and hard termination.
See Scoped kills for the Unix freeze-first and Windows Job Object safety details.
Watching and explaining
Two read-only commands answer questions list can’t:
kick why 3000
kick why 3000 --all-protocols --all-addresses --json
kick watch --tcp --port 3000
kick watch --filter state:listen --duration 30s --jsonwhy PORT• takes one snapshot, then attempts the exact bind and closes it immediately. It tells occupied, permission denied, address unavailable, and unsupported apart, with the evidence behind each verdict.watch• polls full-state snapshots and streamsbaseline,bind,release,replacement, andcollection_gapevents, as terminal output or NDJSON.
Neither one signals a process or runs Docker. Full walkthrough: Watch & Why.
How the CLI behaves
- An empty unfiltered list is success (exit
0) • a quiet machine isn’t an error. - An empty filtered result is no-match (exit
3) • sokick list --port 3000 && echo busyworks as an occupancy probe. kill --portrefuses ambiguous ports • if two PIDs own one port, it lists the candidates and asks you to pick with--pidinstead of guessing.- A port with no readable owner exits
4(permission denied) rather than pretending it can act.
When a --port lookup finds no socket but a process mentions that port on its command line,
Kickoutchi prints a “possible related process” hint to stderr so JSON on stdout stays clean.
Next
Want the terse index of every flag, filter, and exit code? See the command reference. Parsing the output? See Structured output.