npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

kaven-utils

v6.2.0

Published

Utilities for Node.js.

Readme

Kaven-Utils

Installation

# npm
npm i kaven-utils --save

# yarn
yarn add kaven-utils

# pnpm
pnpm i kaven-utils

Documentation

Kaven-Utils

Commands

Both installed executable names are equivalent:

kaven-utils <command>
ku <command>

Use ku help [command] or ku <command> --help for command-specific help. Use ku --help to list commands and ku -v or ku --version to print the installed version.

| Command | Aliases | Description | | ------- | ------- | ----------- | | copy [destination] [sourceFiles...] | cp | Copy files or directories. | | remove <file> [otherFiles...] | rm, delete | Remove files or directories. | | remove-files <dir> <ext> [otherExtensions...] | remove_files, rm-files, rm_files, delete-files, delete_files | Remove files with selected extensions below a directory. | | run <command> [otherCommands...] | — | Run commands concurrently or sequentially. | | gen-cert | gen_cert | Generate SSL/TLS certificates. | | proxy [dirOrFile] | — | Start the configurable local HTTP proxy. | | relay-proxy [dirOrFile] | — | Start a relay server, proxy client, or fixed TCP forwarder. | | ip | — | Print the current network's external IP address. | | ci | — | Publish generated documentation to a documentation repository. | | docker <server> [command] | — | List images and tags in a Docker registry. | | where | — | Print the path of the running CLI script. | | minify [file] [otherFiles...] | — | Minify JavaScript files. | | minify-css [file] [otherFiles...] | — | Minify CSS files. | | update-pug-resource-version [dir] | uprv | Add or update a version query parameter in Pug resource URLs. |

copy

ku copy [destination] [sourceFiles...]
ku copy --config <config>

Copies all sourceFiles into destination. The -c, --config <config> option loads advanced copy entries from a JSON file. A command may use the config and positional source files together.

{
    "override": false,
    "entries": [
        {
            "src": "./package.json",
            "dest": "./backup/package.json",
            "override": true
        },
        {
            "src": ["./src", "./README.md"],
            "dest": "./backup"
        }
    ]
}

Each entry's override value takes precedence over the top-level value. A string src copies to the exact dest; an array copies its items into the destination directory.

remove

ku remove <file> [otherFiles...]
ku remove --recursive <file> [otherFiles...]

Removes each supplied path. Without -r, --recursive, files and empty directories can be removed. Use --recursive to remove non-empty directories and their contents.

remove-files

ku remove-files <dir> <ext> [otherExtensions...]

Recursively removes files matching one or more extensions under dir.

| Option | Description | | ------ | ----------- | | --caseSensitive | Match extensions with case sensitivity. | | --ignore [ignoreFolderNames...] | Skip folders with the supplied names. | | --ignoreFolderNames [ignoreFolderNames...] | Alias of --ignore. |

ku remove-files ./dist .map .ts --ignore node_modules generated

run

ku run <command> [otherCommands...]

Runs the supplied commands concurrently by default. Quote commands that contain spaces or shell operators.

| Option | Description | | ------ | ----------- | | -s, --sequential | Wait for each command to finish before starting the next. | | -e, --encoding <encoding> | Decode output with an iconv-lite encoding. | | --spawn | Use spawn instead of exec. | | --shell [shell] | Enable a shell or provide the shell executable. | | --win32commands <win32commands...> | On Windows, replace the positional commands with this command list. |

ku run "pnpm run lint" "pnpm run build"
ku run --sequential "pnpm run lint" "pnpm run test"

gen-cert

ku gen-cert [options]

Generates a CA, server certificate, and client certificate, then writes their metadata to cert.json in the output directory. It also creates a distributable client/ directory containing only caCert, serverCert, clientCert, and clientKey; copy this directory to client machines instead of copying the complete server output directory.

| Option | Description | | ------ | ----------- | | --dir [dir] | Output directory. Defaults to ./generated. | | --bits [bits] | Certificate key size in bits. | | --days [days] | Certificate validity period in days. | | --cn [cn] | Certificate subject common name. | | --openssl [openssl] | Path to the OpenSSL executable. | | --verbose | Enable detailed logging. |

ku gen-cert --dir ./certificates --bits 2048 --days 365 --cn localhost

proxy

Run an HTTP/HTTPS forward proxy over an encrypted TLS connection. It is useful when a local application should send proxy traffic through another machine before reaching the destination.

The command has two roles, which may run in one process or on separate machines:

| Role | What it does | | ---- | ------------ | | server | Accepts TLS connections from proxy clients, reads the requested host:port, and connects to that destination. | | client | Listens locally as an HTTP proxy and tunnels each request to the TLS server. It supports regular HTTP requests and HTTPS CONNECT tunnels. |

flowchart LR
    app["Browser / app"]
    client["Local proxy client<br/>127.0.0.1:8765"]
    server["Proxy server<br/>public host"]
    destination["Destination<br/>host:port"]

    app --> client
    client ==>|TLS on port 8558| server
    server --> destination

Proxy usage

ku proxy [dirOrFile] [--mkdir]
  • If dirOrFile is a directory (or omitted, defaulting to the current directory), the command loads kaven-proxy.config from that directory. When the file does not exist, a working default config is generated and started.
  • If dirOrFile is a file, that config file is loaded directly.
  • --mkdir creates dirOrFile as a directory when the path does not exist.
  • Relative certificate paths are resolved from the config file's directory.

Config file (kaven-proxy.config)

At least one of SERVER or CLIENT must be true.

| Field | Description | | ----- | ----------- | | SERVER | Start the TLS proxy server in this process. | | SERVER_HOST | Address the TLS server binds to. The generated default is 0.0.0.0. | | SERVER_PORT | Port the TLS server binds to. The generated default is 8558. | | SERVER_CERT_GENERATE_DIR | Directory in which certificates are generated when they do not exist. The generated default is ./generated. | | SERVER_CERT_JSON_FILE | Certificate metadata file loaded by the server. The generated default is ./generated/cert.json. | | SERVER_VALID_CLIENTS | Optional allowlist of client remote IP addresses. An empty array allows every address that completes the TLS connection. | | CLIENT | Start the local HTTP proxy client in this process. | | CLIENT_CONNECT_HOST | TLS proxy server hostname or IP address. The generated default is 127.0.0.1. | | CLIENT_CONNECT_PORT | TLS proxy server port. The generated default is 8558. | | CLIENT_HTTP_HOST | Address the local HTTP proxy binds to. The generated default is 127.0.0.1. | | CLIENT_HTTP_PORT | Port the local HTTP proxy binds to. The generated default is 8765. | | CLIENT_CERT_JSON_FILE | Client certificate metadata containing caCert, serverCert, clientCert, and clientKey. A safe bundle is generated in SERVER_CERT_GENERATE_DIR/client/. The generated all-in-one default reuses ./generated/cert.json. | | CLIENT_VALID_SERVERS | Optional allowlist of TLS server hostnames. An empty array accepts any hostname whose certificate is trusted by the configured CA. | | CLIENT_CHECK_CERT_CN | Reserved config field. It is present in the schema but is not currently applied by StartProxy. |

Generated all-in-one config

Running ku proxy in a directory without kaven-proxy.config creates and starts this default:

{
    "SERVER": true,
    "SERVER_HOST": "0.0.0.0",
    "SERVER_PORT": 8558,
    "SERVER_CERT_GENERATE_DIR": "./generated",
    "SERVER_CERT_JSON_FILE": "./generated/cert.json",
    "SERVER_VALID_CLIENTS": [],
    "CLIENT": true,
    "CLIENT_CONNECT_HOST": "127.0.0.1",
    "CLIENT_CONNECT_PORT": 8558,
    "CLIENT_HTTP_HOST": "127.0.0.1",
    "CLIENT_HTTP_PORT": 8765,
    "CLIENT_CERT_JSON_FILE": "./generated/cert.json",
    "CLIENT_CHECK_CERT_CN": false,
    "CLIENT_VALID_SERVERS": []
}

The server generates the CA, server certificate, and client certificate on first run and saves their metadata to generated/cert.json; certificate generation requires OpenSSL. Configure an application to use 127.0.0.1:8765 as its HTTP and HTTPS proxy.

Separate server and client machines

On the publicly reachable server, use:

{
    "SERVER": true,
    "SERVER_HOST": "0.0.0.0",
    "SERVER_PORT": 8558,
    "SERVER_CERT_GENERATE_DIR": "./generated",
    "SERVER_CERT_JSON_FILE": "./generated/cert.json",
    "SERVER_VALID_CLIENTS": [],
    "CLIENT": false
}

Start it with:

ku proxy ./

After the first run, copy only the server's generated generated/client/ directory to the client machine. It contains a sanitized cert.json and the four required certificate files. Do not copy the parent generated directory, because it contains the CA and server private keys.

On the client machine, use:

{
    "SERVER": false,
    "CLIENT": true,
    "CLIENT_CONNECT_HOST": "proxy.example.com",
    "CLIENT_CONNECT_PORT": 8558,
    "CLIENT_HTTP_HOST": "127.0.0.1",
    "CLIENT_HTTP_PORT": 8765,
    "CLIENT_CERT_JSON_FILE": "./generated/cert.json",
    "CLIENT_CHECK_CERT_CN": false,
    "CLIENT_VALID_SERVERS": ["proxy.example.com"]
}

Then run:

ku proxy ./

Allow inbound TCP traffic to 8558 on the server, but keep the client listener bound to 127.0.0.1 unless other devices must use it. If the local listener is exposed on a network interface, anyone who can reach it may be able to use the proxy.

TLS and request flow

  • The client-to-server connection is encrypted with TLS.
  • The local application-to-client connection is a normal HTTP proxy connection. HTTPS payloads remain encrypted because they use CONNECT.
  • The server-to-destination connection uses the protocol requested by the application. End-to-end payload encryption therefore depends on the destination using HTTPS or another secure protocol.
  • The server requests a client certificate and the client loads its certificate and CA from CLIENT_CERT_JSON_FILE.
  • SERVER_VALID_CLIENTS filters by the remote socket address, while CLIENT_VALID_SERVERS filters the hostname used to connect to the server.
  • The proxy server can connect to arbitrary destinations requested by an accepted client. Run it only on a trusted host and restrict network access to its listening port.

relay-proxy

Tunnel TCP connections (or full HTTP-proxy traffic) between two machines through a relay server. It is useful when the two ends cannot reach each other directly but both can reach a third, publicly accessible host.

There are three roles, each run as a separate relay-proxy process on a separate machine:

| Role | What it does | | ------ | -------------- | | server | The relay. Accepts connections from both clients and forwards messages between them. Runs on a host reachable by both peers. | | proxy-origin | Listens locally as an HTTP, SOCKS4, or SOCKS5 proxy. Each requested connection is sent through the relay to a proxy target. | | proxy-target | Dials the destination requested through the selected proxy protocol and returns its traffic through the relay. It has no fixed destination. |

flowchart LR
    app["Browser / app"]
    origin["PC A: proxy-origin"]
    relay["PC C: relay server<br/>publicly reachable"]
    target["PC B: proxy-target<br/>dials on demand"]
    destination["Requested host:port<br/>for example, 127.0.0.1:80"]

    app --> origin
    origin <--> relay
    relay <--> target
    target --> destination

Usage

ku relay-proxy [dirOrFile] [--mkdir]
  • If dirOrFile is a directory (or omitted, defaulting to the current directory), the command looks for kaven-relay-proxy.config inside it. If the file does not exist, a working default is generated for you to edit.
  • If dirOrFile is a file, that config file is loaded directly.
  • --mkdir creates dirOrFile when it does not exist.
  • The process handles SIGINT and SIGTERM by stopping the relay cleanly.

Config file (kaven-relay-proxy.config)

The config has a SERVER block and a CLIENTS array. Each client entry is a proxy listener, proxy dialer, raw forwarding listener, or raw forwarding dialer.

The top-level fields are:

| Field | Description | | ------- | ------------- | | SERVER | true to start the relay server in this process. | | SERVER_HOST | Host the relay server binds to (default 0.0.0.0). | | SERVER_PORT | Port the relay server binds to (e.g. 8558). 0 picks a free port. | | SERVER_TLS | true (default) to accept TLS connections, encrypting the relay transport. Certificates are auto-generated into SERVER_CERT_DIR on first run (requires openssl). Set false for plain TCP. | | SERVER_CERT_DIR | Directory for auto-generated TLS certificates (default ./generated). | | SERVER_CERT_FILE | Path to a cert.json holding the CA/server/client certs (default ./generated/cert.json). Auto-generated when missing. | | CLIENT | true (default) to honor the CLIENTS array. false ignores it (server-only). | | CLIENTS | Array of client entries (see below). |

Each CLIENTS entry supports:

| Field | Description | | ------- | ------------- | | TYPE | "proxy-origin" (HTTP/SOCKS proxy listener), "proxy-target" (dials the destination requested by each proxy connection), "forward-listen" (raw TCP listener), or "forward-dial" (fixed raw TCP dialer). See Port forwarding. | | ENABLE | false to disable this entry. Defaults to true; every enabled entry is started in CLIENTS order. | | CONNECT_TO_HOST | Relay server address this client connects to. Omit to use the local server. | | CONNECT_TO_PORT | Relay server port this client connects to. Omit to use the local server. | | CONNECT_TO_TLS | true to connect to the relay server over TLS. Must match the server's SERVER_TLS. | | CERT_FILE | Path to a client-specific cert.json holding caCert, serverCert, clientCert, and clientKey. The CA validates the chain and the server certificate is pinned. Reused automatically when the server runs in the same process. Never distribute caKey or serverKey to clients. | | TCP_HOLE_PUNCH | true to try an encrypted direct TCP transport to the selected peer. Any failure automatically uses the relay server. Defaults to false. | | TCP_HOLE_PUNCH_TIMEOUT | Maximum direct-path setup time in milliseconds. Defaults to 3000. | | LOCAL_PROXY_HOST | (proxy-origin only) Host the local proxy listener binds to (default 127.0.0.1). | | LOCAL_PROXY_PORT | (proxy-origin only) Port the local proxy listener binds to. Connect your browser/app here. | | LOCAL_PROXY_TYPE_LIST | (proxy-origin only) Array of protocols accepted on the same listener: "http", "socks4", and/or "socks5". Defaults to all three. | | TARGET_ID_LIST | Names of the dialer clients this listener may tunnel to (see ID below). When empty/omitted, the listener binds to the first peer that joins. | | ID | A stable logical name a dialer advertises so listeners with a matching TARGET_ID_LIST can select it. A newer connection using the same ID replaces the older session. | | LISTEN_HOST | (forward-listen only) Host the raw forwarding listener binds to. | | LISTEN_PORT | (forward-listen only) Port the forward listener binds to. 0 selects a free port. | | DIAL_HOST | (forward-dial only) Fixed destination host. Defaults to 127.0.0.1. | | DIAL_PORT | (forward-dial only) Fixed destination port. Required when enabled. |

Dialer selection: when a relay has more than one dialer connected, a listener picks its dialer by name. Set ID on each dialer (e.g. "intranet", "db") and list the ones a listener may use in its TARGET_ID_LIST (e.g. ["intranet"]). With no TARGET_ID_LIST, the listener binds to the first peer that joins — fine for a single-dialer setup.

Treat ID as unique per logical dialer, but reuse it when moving that same dialer configuration to another PC. The new connection takes ownership of the ID immediately, even if the server has not detected the old PC's stale TCP session yet.

Optional direct TCP transport

Set TCP_HOLE_PUNCH: true on both matching listener and dialer entries to try TCP simultaneous-open before starting the local listener. The relay server coordinates the attempt using each probe connection's observed public IP address and port.

When both peers have the same server-observed public IP address, they also exchange temporary LAN listener endpoints through the authenticated relay. The peers try both LAN connection directions before continuing with the public TCP simultaneous-open attempt. This avoids relying on NAT loopback support when both clients are on the same LAN. Matching public addresses are treated only as a hint: if VLANs, client isolation, firewalls, or carrier-grade NAT prevent the LAN connection, the public attempt and relay fallback still run.

{
    "TYPE": "forward-listen",
    "TCP_HOLE_PUNCH": true,
    "TCP_HOLE_PUNCH_TIMEOUT": 3000,
    "TARGET_ID_LIST": ["db"]
}
{
    "TYPE": "forward-dial",
    "TCP_HOLE_PUNCH": true,
    "TCP_HOLE_PUNCH_TIMEOUT": 3000,
    "ID": "db"
}

The direct stream is authenticated and encrypted with a one-time key exchanged through the relay connection. If rendezvous, NAT traversal, direct authentication, or the setup timeout fails, tunnel traffic continues through the relay server without configuration changes. TCP hole punching depends on the operating systems, firewalls, and NAT mapping/filtering behavior, so it cannot be guaranteed. The relay server and both clients must run a version that supports direct-path rendezvous.

Tunnel traffic uses a versioned hybrid wire protocol. Connection control messages remain JSON, while data frames carry raw bytes in a compact binary header without Base64 conversion. Per-connection credit flow control and socket drain handling use a 1 MiB window and 256 KiB maximum data frames, bounding queued data while keeping multiple frames in flight. Relay servers and clients must use the same build because this unreleased protocol does not include a compatibility mode.

The relay is designed for a private, trusted deployment. Every client that can authenticate to the relay server can discover and request tunnels to other connected clients; it is not a multi-tenant authorization boundary. Keep TLS enabled, protect the generated client certificate, restrict access to the relay port, and do not share one relay server with untrusted users. Pending hole-punch rendezvous attempts are time-limited and globally bounded.

At least one of SERVER, an enabled listener, or an enabled dialer must be present.

Typical setup — two clients and one server on three machines

Assume the relay server runs on relay.example.com. PC B can reach intranet destinations that PC A cannot. You want to access them from PC A through a local HTTP proxy on 127.0.0.1:18080.

1. PC C — the relay server (publicly reachable, port 8558)

kaven-relay-proxy.config:

{
    "SERVER": true,
    "SERVER_HOST": "0.0.0.0",
    "SERVER_PORT": 8558,
    "SERVER_TLS": true,
    "SERVER_CERT_DIR": "./generated",
    "SERVER_CERT_FILE": "./generated/cert.json",
    "CLIENT": false
}
ku relay-proxy ./

2. PC B — the proxy target (dials each requested destination)

Copy PC C's entire generated/ directory (containing cert.json + the .pem files) to this machine first.

kaven-relay-proxy.config:

{
    "SERVER": false,
    "CLIENT": true,
    "CLIENTS": [
        {
            "TYPE": "proxy-target",
            "CONNECT_TO_HOST": "relay.example.com",
            "CONNECT_TO_PORT": 8558,
            "CONNECT_TO_TLS": true,
            "CERT_FILE": "./generated/cert.json",
            "ID": "intranet"
        }
    ]
}
ku relay-proxy ./

3. PC A — the proxy origin (local HTTP proxy for the browser)

Copy PC C's entire generated/ directory here too.

kaven-relay-proxy.config:

{
    "SERVER": false,
    "CLIENT": true,
    "CLIENTS": [
        {
            "TYPE": "proxy-origin",
            "CONNECT_TO_HOST": "relay.example.com",
            "CONNECT_TO_PORT": 8558,
            "CONNECT_TO_TLS": true,
            "CERT_FILE": "./generated/cert.json",
            "LOCAL_PROXY_HOST": "127.0.0.1",
            "LOCAL_PROXY_PORT": 18080,
            "LOCAL_PROXY_TYPE_LIST": ["http"],
            "TARGET_ID_LIST": ["intranet"]
        }
    ]
}
ku relay-proxy ./

Then set the browser/system HTTP proxy on PC A to 127.0.0.1:18080. Browsing to http://intranet/ is tunneled through the relay to PC B, which resolves and dials intranet:80 from its network.

A single process can run both a proxy origin and proxy target (useful for testing). When CONNECT_TO_* is omitted, the client connects to the local SERVER.

SOCKS4 and SOCKS5

Set LOCAL_PROXY_TYPE_LIST on a proxy-origin to choose the protocols accepted by its listener. HTTP, SOCKS4, and SOCKS5 clients can share the same host and port; the listener detects the protocol for each connection. The paired proxy-target does not need a protocol setting because the origin sends the requested destination through the relay.

{
    "SERVER": false,
    "CLIENT": true,
    "CLIENTS": [
        {
            "TYPE": "proxy-origin",
            "CONNECT_TO_HOST": "relay.example.com",
            "CONNECT_TO_PORT": 8558,
            "CONNECT_TO_TLS": true,
            "CERT_FILE": "./generated/cert.json",
            "LOCAL_PROXY_HOST": "127.0.0.1",
            "LOCAL_PROXY_PORT": 1080,
            "LOCAL_PROXY_TYPE_LIST": ["http", "socks4", "socks5"],
            "TARGET_ID_LIST": ["intranet"]
        }
    ]
}

Configure HTTP, SOCKS4, or SOCKS5 applications to use 127.0.0.1:1080. Remove protocols from LOCAL_PROXY_TYPE_LIST when they should not be accepted.

  • SOCKS4 supports CONNECT with IPv4 addresses and SOCKS4a domain names.
  • SOCKS5 supports CONNECT with IPv4, IPv6, and domain-name destinations.
  • SOCKS5 currently supports the no-authentication method only.
  • SOCKS BIND, UDP ASSOCIATE, and username/password authentication are not supported.

Port forwarding (forward-listen / forward-dial)

For fixed TCP port forwarding without HTTP-proxy parsing, use the forward-listen and forward-dial client types. Fixed destinations are supported only by forward-dial.

The generated default config includes a disabled forward-listen / forward-dial pair using the example below. Set ENABLE to true on both entries after adjusting the listen and destination addresses.

flowchart LR
    app["Application"]
    listener["forward-listen<br/>LISTEN_HOST:LISTEN_PORT"]
    relay["Relay server"]
    dialer["forward-dial"]
    destination["DIAL_HOST:DIAL_PORT"]

    app --> listener
    listener <--> relay
    relay <--> dialer
    dialer --> destination

Client A — forward-listen (binds a fixed local port):

{
    "SERVER": false,
    "CLIENTS": [
        {
            "TYPE": "forward-listen",
            "CONNECT_TO_HOST": "relay.example.com",
            "CONNECT_TO_PORT": 8558,
            "CONNECT_TO_TLS": true,
            "CERT_FILE": "./generated/cert.json",
            "LISTEN_HOST": "127.0.0.1",
            "LISTEN_PORT": 3306,
            "TARGET_ID_LIST": ["db"]
        }
    ]
}

Client B — forward-dial (connects to the destination service):

{
    "SERVER": false,
    "CLIENTS": [
        {
            "TYPE": "forward-dial",
            "CONNECT_TO_HOST": "relay.example.com",
            "CONNECT_TO_PORT": 8558,
            "CONNECT_TO_TLS": true,
            "CERT_FILE": "./generated/cert.json",
            "ID": "db",
            "DIAL_HOST": "10.0.0.5",
            "DIAL_PORT": 3306
        }
    ]
}

Now connecting to 127.0.0.1:3306 on Client A is tunneled through the relay to Client B, which dials 10.0.0.5:3306 and pipes the bytes back — a fixed port forward between the two clients. forward-listen never parses HTTP; every byte is forwarded verbatim.

TLS (encrypting the relay transport)

TLS is enabled by default: the relay-server ↔ client connections are encrypted (mirroring the proxy command's TLS mode). On first run the server auto-generates a CA, server, and client certificate set into SERVER_CERT_DIR and caches it in SERVER_CERT_FILE. Set SERVER_TLS: false (and CONNECT_TO_TLS: false on clients) to revert to plain TCP.

A complete TLS-enabled config looks like:

{
    "SERVER": true,
    "SERVER_HOST": "0.0.0.0",
    "SERVER_PORT": 8558,
    "SERVER_TLS": true,
    "SERVER_CERT_DIR": "./generated",
    "SERVER_CERT_FILE": "./generated/cert.json",
    "CLIENT": true,
    "CLIENTS": [
        {
            "TYPE": "proxy-origin",
            "CONNECT_TO_HOST": "relay.example.com",
            "CONNECT_TO_PORT": 8558,
            "CONNECT_TO_TLS": true,
            "LOCAL_PROXY_HOST": "127.0.0.1",
            "LOCAL_PROXY_PORT": 18080,
            "LOCAL_PROXY_TYPE_LIST": ["http"],
            "TARGET_ID_LIST": ["intranet"]
        }
    ]
}

On each client, set CONNECT_TO_TLS: true. When the server runs in the same process, the cert set is reused automatically and CERT_FILE can be omitted.

Certificates on a separate client machine: each TLS client must have these four files:

  • ca-cert.pem — public CA certificate used to validate the server chain.
  • server-cert.pem — public server certificate used for exact certificate pinning.
  • client-cert.pem — public client certificate presented to the server.
  • client-key.pem — private key for that client certificate; protect it like a password. Machines receiving the same generated bundle share one TLS client identity; generate separate client certificates when distinct identities are required.

Certificate generation creates a ready-to-copy bundle automatically at SERVER_CERT_DIR/client/. Copy that client directory—not the parent server certificate directory—to each client machine. Its generated cert.json has this structure, with paths relative to the metadata file:

{
    "caCert": "./ca-cert.pem",
    "serverCert": "./server-cert.pem",
    "clientCert": "./client-cert.pem",
    "clientKey": "./client-key.pem"
}

Do not copy ca-key.pem, server-key.pem, or fields such as caKey and serverKey to a client machine. Those private keys belong only on the relay server or secure certificate-authority host. Copying the server's entire generated directory would expose them.

The ku gen-cert command creates the same safe client/ bundle in its output directory.

Point each client's CERT_FILE at its client-specific cert.json:

{
    "SERVER": false,
    "CLIENT": true,
    "CLIENTS": [
        {
            "TYPE": "proxy-origin",
            "CONNECT_TO_HOST": "relay.example.com",
            "CONNECT_TO_PORT": 8558,
            "CONNECT_TO_TLS": true,
            "CERT_FILE": "./cert.json",
            "LOCAL_PROXY_HOST": "127.0.0.1",
            "LOCAL_PROXY_PORT": 18080,
            "LOCAL_PROXY_TYPE_LIST": ["http"],
            "TARGET_ID_LIST": ["intranet"]
        }
    ]
}

The client validates the CA chain and pins the exact serverCert. When the relay server certificate is renewed or replaced, update server-cert.pem on every client and restart the clients. Until it is updated, a client will reject the new server certificate even when it was issued by the same CA.

TLS encrypts only the relay-server ↔ client connections. The proxy origin's local listener and proxy target's destination connection are not affected; use HTTPS for end-to-end payload encryption.

Notes

  • The server forwards messages only between connected clients; it is not a general-purpose SOCKS/HTTP proxy itself.
  • All traffic between the clients flows through the server. For sensitive data, enable TLS (see above) and run the server on a trusted host.
  • Config-file-driven clients retry the initial relay connection indefinitely, reconnect automatically after an established connection is lost, and rediscover their configured target after either side reconnects. Existing forwarded connections close when transport is lost; new connections work after recovery.
  • An unavailable target does not terminate a long-running origin. The origin keeps its local listener active and rejects new connections until a matching target becomes available.
  • A dialer can serve multiple listener clients concurrently. Replies are routed using each tunneled connection's source client rather than a single cached listener ID.
  • Each process logs its role and bound addresses on startup.

ip

ku ip [--UPnP] [--verbose]

Prints the external IP address. By default it uses the standard external-IP lookup; --UPnP discovers the address through the local UPnP gateway. --verbose enables diagnostic logging.

ci

ku ci [--config <config>] [--variables <variables...>]

Runs the documentation publishing workflow. Without a config file, it uses:

| Setting | Default | | ------- | ------- | | sourceDocumentFileOrDirectory | ./docs | | sourceVersionFile | ./dist/package.json | | targetRootDirectory | ../Kaven-Documents | | targetDirectoryName | Name of the current directory | | updateReadmeFile | true | | gitCommit | true |

--config <config> merges a JSON config with these defaults. Relative paths are resolved from the config file's directory. --variables accepts space-separated key:value pairs and replaces the config's variables.

ku ci --config ./ci.json --variables version:6.1.7 channel:latest

docker

ku docker <server> [command] [options]

Connects to a Docker Registry API server. When command is omitted, it lists every image and its tags. The optional command argument is reserved and currently performs no action.

| Option | Description | | ------ | ----------- | | -u, --username <username> | Registry username. | | -p, --password <password> | Registry password. |

Authentication is used only when both username and password are supplied.

ku docker https://registry.example.com -u user -p password

where

ku where

Prints the absolute path of the CLI script currently being executed.

minify

ku minify [file] [otherFiles...]
ku minify --config <config>

Minifies JavaScript with Terser. The default configuration removes comments, uses ECMAScript 2015 output formatting, keeps source maps, updates sourceMappingURL, removes matching TypeScript declaration files, and excludes node_modules.

--config <config> loads a JSON config relative to the current directory. If the file does not exist, the command writes a starter config there and exits. When a config is loaded, its directory becomes the working directory for the minification operation.

ku minify ./dist/index.js ./dist/bin.js
ku minify --config ./minify.json

minify-css

ku minify-css [file] [otherFiles...]
ku minify-css --config <config>

Minifies CSS with cssnano and excludes node_modules by default. The config behavior matches minify: an existing JSON file is loaded, while a missing file is generated with starter settings and the command exits.

ku minify-css ./public/site.css ./public/theme.css

update-pug-resource-version

ku update-pug-resource-version [dir] [options]

Searches Pug files below dir and adds or updates a query parameter on resource URLs. The directory defaults to the current directory.

| Option | Description | | ------ | ----------- | | --name [name] | Query parameter name. Defaults to version. | | --version [version] | Query parameter value. Defaults to the current date in YYYYMMDD format. | | --verbose | Log the search directory, parameter name, and value. |

ku uprv ./views --name v --version 6.1.7 --verbose