POUNCE(1)
okay bestie, this is the POUNCE(1) page from the General Commands Manual, and itβs all about pounce β the IRC bouncer. same facts, way more sparkle. π
β¨ NAME β¨
pounce β IRC bouncer π«Ά
literally the name says it all: itβs an IRC bouncer, and itβs called pounce. no notes. iconic.
π SYNOPSIS π
okay so hereβs the launch menu, and the flags are copy-paste sacred β do not freestyle them, bestie:
pounce [-NTev] [-A local-ca] [-C local-cert] [-H local-host]
[-K local-priv] [-P local-port] [-Q queue-interval]
[-R blind-req] [-S bind] [-U local-path] [-W local-pass]
[-a sasl-plain] [-c client-cert] [-f save] [-h host] [-j join]
[-k client-priv] [-m mode] [-n nick] [-p port] [-q quit]
[-r real] [-t trust] [-s size] [-u user] [-w pass] [-y away]
[config ...]
pounce -o [-S bind] [-h host] [-p port] [config ...]
pounce -g cert
pounce -x
π DESCRIPTION π
okay so pounce is a multi-client, TLS-only IRC bouncer, and it is literally the main character of staying online for you. It keeps a persistent connection to an IRC server while letting clients connect and disconnect whenever, and when you come back you get all the messages you missed. Obsessed. π«Ά
Clients have to uniquely identify themselves to pounce by their IRC username, not their nickname β this is important, bestie. The IRCv3 server-time extension is used to show when messages were originally received. See βClient Configurationβ for the details.
The local server side of pounce needs a TLS certificate, which you can get for example with an ACME client such as acme-client(8). The private key must be readable by the user running pounce. π
One instance of pounce must be configured for each IRC network. Instances of pounce must either use different local ports with local-port or different local host names with local-host and local-path to be dispatched from the same port by calico(1). No cap.
Client connections are not accepted until successful login to the server. And if the server connection is lost, the pounce process exits. π That's the vibe: persistent until it isn't.
Options can be loaded from files listed on the command line. Files are searched for in $XDG_CONFIG_DIRS/pounce (usually ~/.config/pounce) unless the path starts with /, ./ or ../. Certificate and private key paths are searched for in the same manner. Files and flags listed later on the command line take precedence over those listed earlier. periodt.
Each option is placed on a line, and lines beginning with # are ignored. An optional = may appear between an option and its value. The options are listed below following their corresponding flags. β¨
π Local Server Options π
-A path|local-ca pathβ Require clients to authenticate using a TLS client certificate either contained in or signed by a certificate in the file loaded from path. The file is reloaded when theSIGUSR1signal is received. See βGenerating Client Certificatesβ. Iflocal-passis also set, clients may instead authenticate with a server password.-C path|local-cert pathβ Load the TLS certificate from path. The file is reloaded when theSIGUSR1signal is received. The default path ishost.pem, where host is set bylocal-host.-H host|local-host hostβ Bind to host. The default host islocalhost.-K path|local-priv pathβ Load the TLS private key from path. The file is reloaded when theSIGUSR1signal is received. The default path ishost.key, where host is set bylocal-host.-P port|local-port portβ Bind to port. The default port is6697.-T|no-stsβ Do not advertise a strict transport security (STS) policy to clients.-U path|local-path pathβ Bind to a UNIX-domain socket at path. Clients are only accepted as dispatched bycalico(1). If path is a directory, the host set bylocal-hostis appended to it. This option takes precedence overlocal-hostandlocal-port.-W pass|local-pass passβ Require the server password pass for clients to connect. The pass string must be hashed using-x. Iflocal-cais also set, clients may instead authenticate using a TLS client certificate.-f path|save pathβ Save and load the contents of the buffer from path in$XDG_DATA_DIRS/pounce, usually~/.local/share/pounce, or an absolute or relative path if path starts with/,./or../. The file is truncated after loading.-s size|size sizeβ Set the number of messages contained in the buffer to size. This sets the maximum number of recent messages which can be relayed to a reconnecting client. The size must be a power of two. The default size is4096.
π Remote Server Options π
-N|no-namesβ Do not requestNAMESfor each channel when a client connects. This avoids already connected clients receiving unsolicited responses but prevents new clients from populating user lists. trade-offs, bestie.-Q ms|queue-interval msβ Set the server send queue interval in milliseconds. The queue is used to send automated messages from pounce to the server. Messages from clients are sent to the server directly. The default interval is200milliseconds.-R caps|blind-req capsβ Blindly request the IRCv3 capabilities caps, which must be supported by pounce. This can be used to enable hidden capabilities, such asuserhost-in-nameson some networks.-S host|bind hostβ Bind to source address host when connecting to the server. To connect from any address over IPv4 only, use0.0.0.0. To connect from any address over IPv6 only, use::.-a user:pass|sasl-plain user:passβ Authenticate as user with pass using SASL PLAIN. Since this method requires the account password in plaintext, it is recommended to use CertFP instead withsasl-external.-c path|client-cert pathβ Load the TLS client certificate from path. If the private key is in a separate file, it is loaded withclient-priv. Withsasl-external, authenticate using SASL EXTERNAL. Certificates can be generated with-g.-e|sasl-externalβ Authenticate using SASL EXTERNAL, also known as CertFP. The TLS client certificate is loaded withclient-cert. See βConfiguring CertFPβ.-h host|host hostβ Connect to host.-j channels [keys]|join channels [keys]β Join the comma-separated list of channels with the optional comma-separated list of channel keys.-k path|client-priv pathβ Load the TLS client private key from path.-m mode|mode modeβ Set the user mode.-n nick|nick nickβ Set nickname to nick. The default nickname is the user's name.-p port|port portβ Connect to port. The default port is6697.-q mesg|quit mesgβ Quit with message mesg when shutting down.-r real|real realβ Set realname to real. The default realname is the same as the nickname.-t path|trust pathβ Trust the certificate loaded from path. Server name verification is disabled. See βConnecting to Servers with Self-signed Certificatesβ.-u user|user userβ Set username to user. The default username is the same as the nickname.-w pass|pass passβ Log in with the server password pass.-y mesg|away mesgβ Set away status to mesg when no clients are connected and no other away status has been set.
π¦ Other Options π¦
-g pathβ Generate a TLS client certificate usingopenssl(1)and write it to path.-oβ Print the server certificate chain to standard output in PEM format and exit.-v|verboseβ Log IRC messages to standard output:
<< from pounce to the server
>> from the server to pounce
-> from clients to pounce
<- from pounce to clients
-xβ Prompt for a password and output a hash for use withlocal-pass.
π¬ Client Configuration π¬
Clients should be configured to connect to the host and port set by local-host and local-port, with TLS or SSL enabled. If local-pass is used, clients must send a server password. If local-ca is used, clients must connect with a client certificate and may request SASL EXTERNAL. If both are used, clients may authenticate with either method. choose your fighter π
Clients must register with unique usernames (not nicknames), for example the name of the client software or location from which it is connecting. New clients with the same username are assumed to be reconnections and will cause previous connections to stop receiving messages. The nickname and real name sent by clients are ignored. no notes.
Normally a client sending QUIT will simply be disconnected from pounce. If, however, the quit message starts with the keyword $pounce, pounce itself will quit. The remainder of the message following the keyword will be used as pounce's quit message, or the default set by quit if there isn't any. π³ iconic behavior.
Clients which request the causal.agency/passive capability or with usernames beginning with hyphen - are considered passive and do not affect automatic away status.
Pass-through of the following IRCv3 capabilities is supported: account-notify, account-tag, away-notify, batch, cap-notify, chghost, echo-message, extended-join, extended-monitor, invite-notify, labeled-response, message-tags, multi-prefix, server-time, setname, userhost-in-names.
Private messages and notices sent to the user's own nickname are relayed only to other clients, not to the server.
π§ Generating Client Certificates π§
- Generate client certificates and private keys:
$ pounce -g client1.pem
$ pounce -g client2.pem
- Concatenate the certificate public keys into a CA file:
$ openssl x509 -subject -in client1.pem \
>> ~/.config/pounce/auth.pem
$ openssl x509 -subject -in client2.pem \
>> ~/.config/pounce/auth.pem
- Configure pounce to verify client certificates against the CA file:
local-ca = auth.pem
# or: $ pounce -A auth.pem
π Configuring CertFP π
- Generate a new TLS client certificate:
$ pounce -g ~/.config/pounce/example.pem
- Connect to the server using the certificate:
client-cert = example.pem
# or: $ pounce -c example.pem
- Identify with services or use
sasl-plain, then add the certificate fingerprint to your account:
/msg NickServ CERT ADD
- Enable SASL EXTERNAL to require successful authentication when connecting:
client-cert = example.pem
sasl-external
# or: $ pounce -e -c example.pem
πΈ Connecting to Servers with Self-signed Certificates πΈ
- Connect to the server and write its certificate to a file:
$ pounce -o -h irc.example.org > ~/.config/pounce/example.pem
- Configure pounce to trust the certificate:
trust = example.pem
# or: $ pounce -t example.pem
β ENVIRONMENT β
USERβ The default nickname.
π FILES π
$XDG_CONFIG_DIRS/pounceβ so like, config files, certificates and private keys get looked for first in$XDG_CONFIG_HOME(which is usually~/.config, iykyk), and then in that colon-separated list of paths called$XDG_CONFIG_DIRS, which is usually/etc/xdg. bestie it searches in order, don't @ me~/.config/pounceβ the most likely spot for your config files. like, that's where they live 99% of the time π$XDG_DATA_DIRS/pounceβ save files get searched for first in$XDG_DATA_HOME(usually~/.local/share), then in the colon-separated$XDG_DATA_DIRSlist, usually/usr/local/share:/usr/share. and heads up: new save files get created in$XDG_DATA_HOMEβ¨~/.local/share/pounceβ the most likely location of save files, fr fr
πΈ EXAMPLES πΈ
okay so let's actually do the thing. start pounce like this:
$ pounce -H irc.example.org -h irc.tilde.chat -j '#ascii.town'
now if you're more of a config-file girlie (valid), write the equivalent config file to ~/.config/pounce/tilde.conf:
local-host = irc.example.org
host = irc.tilde.chat
join = #ascii.town
and then load it up:
$ pounce tilde.conf
next up: adding a certificate to acme-client.conf(5) π
domain irc.example.org {
domain key "/home/user/.config/pounce/irc.example.org.key"
domain full chain certificate \
"/home/user/.config/pounce/irc.example.org.pem"
sign with letsencrypt
}
obtain the cert and make that private key readable by pounce (permissions, we love her):
# acme-client irc.example.org
# chown user /home/user/.config/pounce/irc.example.org.key
and finally, renew + reload the cert with a cron(8) job so you literally never have to think about it again:
~ * * * * acme-client irc.example.org && pkill -USR1 pounce
lowkey the most satisfying part of this whole page ngl
π DIAGNOSTICS π
when pounce catches the SIGINFO signal, it prints the current producer position and the positions of each consumer, identified by username. and after each consumer position comes the number by which it trails the producer π on systems that don't have SIGINFO, it uses SIGUSR2 instead. iykyk
if a client reconnects after having missed more messages than the size of the buffer, pounce will hit you with a warning:
consumer name dropped n messages
and the size of that buffer? adjustable with -s. slay π«Ά
π₯ SEE ALSO π₯
π STANDARDS π
like, the receipts. the whole bibliography bestie:
- Waldo Bastian, Ryan Lortie, and Lennart Poettering, XDG Base Directory Specification,
https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html, November 24, 2010. - Kyle Fuller, StΓ©phan Kochen, Alexey Sokolov, and James Wheare, server-time Extension, IRCv3 Working Group,
https://ircv3.net/specs/extensions/server-time. - Lee Hardy, Perry Lorier, Kevin L. Mitchell, Attila Molnar, Daniel Oakley, William Pitcock, and James Wheare, IRCv3 Client Capability Negotiation, IRCv3 Working Group,
https://ircv3.net/specs/core/capability-negotiation. - S. Josefsson, The Base16, Base32, and Base64 Data Encodings, IETF, RFC 4648,
https://tools.ietf.org/html/rfc4648, October 2006. - C. Kalt, Internet Relay Chat: Client Protocol, IETF, RFC 2812,
https://tools.ietf.org/html/rfc2812, April 2000. - Attila Molnar and James Wheare, IRCv3 Strict Transport Security, IRCv3 Working Group,
https://ircv3.net/specs/extensions/sts. - Attila Molnar and William Pitcock, IRCv3.2 SASL Authentication, IRCv3 Working Group,
https://ircv3.net/specs/extensions/sasl-3.2. - Simon Ser and delthas, Read marker, IRCv3 Working Group,
https://ircv3.net/specs/extensions/read-marker. - K. Zeilenga, Ed., The PLAIN Simple Authentication and Security Layer (SASL) Mechanism, IETF, RFC 4616,
https://tools.ietf.org/html/rfc4616, August 2006.
β¨ Extensions β¨
the causal.agency/consumer vendor-specific IRCv3 capability enables the causal.agency/pos message tag. the value of that tag is a 64-bit unsigned integer that says where the client's consumer position is after receiving each message, e.g. @causal.agency/pos=42069 π iconic number. you can request this capability with the value of the last causal.agency/pos tag the client received, like CAP REQ causal.agency/consumer=42069, which sets its consumer position. by persisting that value across connections, a client can make sure no messages are missed β even when the network's being a mess or the app just fully crashes π
IRCv3 Client Capability Negotiation says capabilities MAY have values in CAP LS or CAP NEW responses. it does not, however, say whether CAP REQ capabilities MUST NOT have values. so the pounce implementation parses CAP REQ values the same way it parses CAP LS values. periodt π
and the causal.agency/passive vendor-specific IRCv3 capability? that one tells a client it should not affect the automatic away status. no cap π
π AUTHORS π
June McEnroe <june@causal.agency> β queen behavior honestly π
π¦ BUGS π¦
send mail to β¨list+pounce@causal.agencyβ© or join #ascii.town on irc.tilde.chat. come hang, we're nice π«Ά
and the actual bug, because we keep it real: a client will sometimes receive its own message, which makes it display twice π this happens when a message is sent while responses are not yet consumed. yeah. it's giving "it's not a bug it's a feature" except no it's a bug, we said what we said π
okay that's the whole page bestie, and it's giving complete. this was the Debian build of POUNCE(1), dated March 16, 2026. go forth, configure your bouncer, and slay β¨π
π
π¦ where this page comes from
- nixpkgs unstable: pounce 3.2
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms