kaven-utils
v6.2.0
Published
Utilities for Node.js.
Maintainers
Readme
Kaven-Utils
Installation
# npm
npm i kaven-utils --save
# yarn
yarn add kaven-utils
# pnpm
pnpm i kaven-utilsDocumentation
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 generatedrun
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 localhostproxy
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 --> destinationProxy usage
ku proxy [dirOrFile] [--mkdir]- If
dirOrFileis a directory (or omitted, defaulting to the current directory), the command loadskaven-proxy.configfrom that directory. When the file does not exist, a working default config is generated and started. - If
dirOrFileis a file, that config file is loaded directly. --mkdircreatesdirOrFileas 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_CLIENTSfilters by the remote socket address, whileCLIENT_VALID_SERVERSfilters 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 --> destinationUsage
ku relay-proxy [dirOrFile] [--mkdir]- If
dirOrFileis a directory (or omitted, defaulting to the current directory), the command looks forkaven-relay-proxy.configinside it. If the file does not exist, a working default is generated for you to edit. - If
dirOrFileis a file, that config file is loaded directly. --mkdircreatesdirOrFilewhen it does not exist.- The process handles
SIGINTandSIGTERMby 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
IDon each dialer (e.g."intranet","db") and list the ones a listener may use in itsTARGET_ID_LIST(e.g.["intranet"]). With noTARGET_ID_LIST, the listener binds to the first peer that joins — fine for a single-dialer setup.Treat
IDas 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 localSERVER.
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 --> destinationClient 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:latestdocker
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 passwordwhere
ku wherePrints 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.jsonminify-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.cssupdate-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