Skip to content
Documentation menu

Command reference

CLI

Options, filters, output modes, and exit codes for both binary names and all five subcommands.

Use this page when you know the command and need its exact syntax. For worked examples, see the CLI walkthrough and Scoped kills.

Binary names

BinaryUse
kickoutchiCanonical name. Matches the crate, the docs, and this site.
kickShort alias for daily CLI use. Identical behaviour.

Running either with no subcommand opens the TUI. --version reports kickoutchi under both names.

Global options

These work with or without a subcommand.

OptionDescription
--config FILEUse an alternate config file instead of the platform default.
--refresh-interval SECONDSOverride the configured refresh interval (1–3600). Out of range is a usage error (exit 2).

list

Print open ports and exit.

usage
kick list [OPTIONS]
OptionDescription
--port PORTOnly rows bound to this exact port.
--process TEXTOnly rows whose process name contains the text.
--filter TEXTTUI-style search text or structured filters (below).
--sort MODESort order (below). Defaults to your config’s default_sort.
--jsonPrint the legacy visible-row kickoutchi.list/1 array.
--snapshot-jsonPrint the complete, unfiltered kickoutchi.snapshot/1 observation instead.

An empty unfiltered list exits 0. An empty filtered result exits 3.

--snapshot-json ignores --port, --process, --filter, --sort, and hide_system_processes by design, and omits full command lines. See Structured output.

kill

Terminate the process owning a port or PID, after confirmation.

usage
kick kill <--pid PID[,PID...] | --port PORT[,PORT...]> [OPTIONS]

Pass PIDs or ports, not both. Repeat the flag or separate values with commas to kill up to 128 processes behind one confirmation and one summary. --tree and --group take one target.

OptionDescription
--pid PIDTerminate a specific PID. Repeatable, or comma-separated.
--port PORTTerminate the process that owns this port. Refuses ambiguous ports. Repeatable, or comma-separated.
--forceStronger force confirmation; Unix uses kill -9, while Windows delivery is hard termination either way.
--yesSkip eligible prompts. Never bypasses protected-process confirmation or fresh scoped-kill safety gates.
--treeTerminate the target’s whole descendant tree. Conflicts with --group.
--groupLinux/macOS only: terminate every visible member of the target’s POSIX process group. Conflicts with tree.

The equivalent command shown before confirmation is kill PID (terminate) or kill -9 PID (force) on Linux/macOS, and taskkill /F /PID PID on Windows.

After delivery, kill waits up to two seconds and reports separately whether each process exited and whether its confirmed ports are still visible. A batch’s exit code is the most serious outcome across its targets: 1, then 4, then 6, then 3.

Scoped kill confirmations use stronger words: tree, group, or force. The command preview is always re-collected fresh at execution time; stale previews are not trusted. --group is rejected on Windows, and Windows --tree uses Job Object containment with hard termination.

inspect

Show a process family without signalling anything.

usage
kick inspect <--pid PID | --port PORT>

Exactly one of --pid / --port is required.

OptionDescription
--pid PIDShow this PID’s ancestors, descendants, siblings, ports, and process group where supported.
--port PORTShow the family of the process that owns this port. Refuses ambiguity.

inspect --pid is read-only and can inspect a portless supervisor. inspect --port follows the same target-resolution rules as kill --port.

watch

Stream bounded socket changes until interrupted or the duration expires. Read-only.

usage
kick watch [OPTIONS]
OptionDescription
--tcp / --udpProtocol selection. Neither flag means both; --tcp --udp also means both.
--address ADDRESSMatch this literal normalized IP address across IPv6 scopes.
--scope-id IDNarrow an explicit IPv6 address to this nonzero interface index.
--port PORTMatch this exact nonzero port.
--filter TEXTPlain or structured full-state filters, including watch-only state:.
--interval DURPoll every 100ms..=60s. Default 1s.
--duration DURStop after 100ms..=7d instead of waiting for Ctrl-C.
--jsonEmit kickoutchi.watch_event/1 NDJSON to stdout; diagnostics stay on stderr.
--matched-onlyEmit only definite matches; drop events whose match is indeterminate.

Events are baseline, bind, release, replacement, and collection_gap. A failed initial collection exits 1; after a valid baseline, the third consecutive failure exits 1. Ctrl-C, duration expiry, and a closed consumer exit 0. Docker is never invoked in the polling loop.

why

Explain whether exact local endpoints are bindable now. Read-only apart from a temporary bind that is closed immediately.

usage
kick why <PORT> [OPTIONS]
OptionDescription
--tcpTCP only (the default), ordered before UDP in a matrix.
--udpUDP endpoints only.
--all-protocolsTCP then UDP.
--address ADDRESSOne literal local IP. No %zone syntax • use --scope-id.
--all-addresses127.0.0.1, 0.0.0.0, ::1, then ::. Does not enumerate interfaces.
--scope-id IDNonzero IPv6 interface index; requires one explicit IPv6 --address.
--ipv6-onlyRequire IPv6-only behaviour. Valid only when every address is IPv6.
--dual-stackRequire dual-stack behaviour. Mutually exclusive with --ipv6-only.
--reuse-addressEnable address reuse for the diagnostic bind.
--jsonPrint one kickoutchi.why/1 document instead of human evidence.

The default query probes TCP on 127.0.0.1, then ::1. The matrix is protocol-major and capped at eight endpoints. For a multi-endpoint query the aggregate exit code takes the worst result: 1, then 4, then 3, and 0 only when every endpoint proved bindable. See Watch & Why.

Filters

Used by list --filter, watch --filter, and the TUI search box. Multiple terms are combined with AND, and so are repeated fields. Bare words are matched as substrings across the visible fields.

FilterMatches
pid:18422Exact PID
port:3000Exact port
proto:tcp / proto:udpProtocol
scope:public / scope:local / scope:loopbackBind scope
protected:true / protected:falseProtected status
parent:nodeParent process name or PID (substring)
label:webConfigured endpoint label
address:127.0.0.1Parsed, normalized IP address • not a substring
scope_id:3Numeric IPv6 interface scope
family:ipv4 / family:ipv6Normalized address family
state:establishedwatch only • native socket state
filter examples
kick list --filter 3000
kick list --filter port:3000
kick list --filter 'label:web family:ipv4'
kick list --filter address:127.0.0.1
kick list --filter 'proto:tcp family:ipv6 parent:node'
kick watch --filter state:listen

address: matching parses the address rather than comparing text, so address:::1 and address:0:0:0:0:0:0:0:1 are the same query, and IPv4-mapped IPv6 addresses normalize to IPv4.

state: is reserved for watch. list and the TUI reject it rather than quietly treating it as plain search text. Accepted values:

state: values
listen bound closed syn_sent syn_received established fin_wait1 fin_wait2
close_wait closing last_ack time_wait delete_tcb new_syn_received unknown

Filter expressions are bounded to 256 UTF-8 bytes. An invalid structured value (e.g. port:not-a-port) is a usage error (exit 2).

In watch, an owner-dependent term must be satisfied by the same conceptual owner • two different owners cannot each satisfy half of one expression. When a needed owner or metadata fact is missing, the event is emitted as indeterminate instead of being silently dropped, unless you pass watch --matched-only.

Sort modes

port • pid • protocol • process • parent • scope

Sorting by scope lists public binds first, then local, then loopback. Rows missing the sort key sink to the bottom. In the TUI, s cycles through these in order.

JSON output

list --json emits an array of objects with this stable shape:

FieldType
protocol"tcp" | "udp"
local_addrstring
local_portnumber
state"listen" | "bound"
pidnumber | null
process_namestring | null
executable_pathstring | null
command_linestring | null
parent_pidnumber | null
parent_process_namestring | null
child_pidsnumber[] • always []
protectedboolean
platform"linux" | "macos" | "windows"
permission"full" | "partial"
labelstring | null

Missing metadata is null. An empty result is []. label is the only field added in 1.3.0; child_pids is a frozen 1.x compatibility field with no data behind it.

Three more contracts • kickoutchi.snapshot/1, kickoutchi.watch_event/1, and kickoutchi.why/1 • are documented in Structured output.

Exit codes

The script-facing contract • these numbers don’t drift.

CodeMeaning
0Command completed and its requested positive condition holds
1Operational or internal failure
2Invalid arguments
3No match, or a requested endpoint is unavailable
4Permissions prevented a reliable answer
5Kill cancelled
6Protected process needs confirmation

Config

Defaults for sort, refresh interval, protected processes, and endpoint labels live in a config file. See Configuration.