Skip to content

Repository files navigation

kirk.png

Kirk

Another IRC client & UI, because Irssi is great but painful to script. gawel/irc3 works, but its design flaws are limiting and hard to work around. jaraco/irc is weirdly over-engineered while making seemingly simple things very hard.

This is a minimalistic, portable, yet almost complete rfc2812 implementation (~900 LOC client, ~500 LOC UI), which I should have written years ago, instead of fighting above tools.

UI features

  • Irssi inspired UI (powered by blessed♥️)
  • Colorized nicks
  • MIRC color/formatting
  • Tabbed layout (ARROW_LEFT, ARROW_RIGHT)
  • Scrollable buffers (PAGE_UP, PAGE_DOWN)
  • Multi-server enabled (switch through with /switch)

Client features

  • Fully asyncio
  • Implements the majority of rfc2812
  • Symmetric E2E encryption with cryptography.Fernet(Kirk exclusive feature)
  • In-band DH key exchange (/handshake <nick>) with mnemonic fingerprint verification
  • Auto-join
  • Auth support (NickServ or SASL)
  • CTCP support
  • DCC support
  • SSL support
  • Super easy to extend and adapt!
  • Select IRCv3 support

Demo

Super simple IRC bot ollama_chatbot.py that reacts to private messages. Uses a locally running ollama LLM.

demo.gif

Running it

By default, Kirk will look into the user's home directory for a startup config file. This is just a convenience. Most settings can also be reached via CLI. See kirk --help for more info.

Start UI (ad-hoc with uvx)

uvx --from git+https://github.com/tfranzel/kirk kirk --host irc.libera.chat --nick NosySpock

Start UI (after package install)

python -m kirk.run --host irc.libera.chat --nick NosySpock

Non-exhaustive example for config file ~/.kirk.toml

[kirk]
# save buffer history on exit and load on startpersistence = false# Custom IrcClient class that Kirk should use instead, as 'path/to/file.py:ClassName'.# Relative paths resolve against this config file's directory, not the CWD.# client_class = "clients/my_client.py:MyClient"
[[kirk.client]]
host = "irc.libera.chat"nick = "NosySpock"auto_join = [
"#testchannel",
]
ssl = true# Optional: authenticate after connecting.auth = "sasl_plain"password = "YOURPASSWORD"# Symmentric encrpytion with peer. Both need the same key# Key generation: base64.urlsafe_b64encode(os.urandom(32))keys.CpnKirk25 = "R3k4JBrPet51XYzkD64KNeuOljzANxBT6yIHZT-yY7w="# Use "console" with headless and "file" or "none" for Kirklog_mode = "none"# another server
[[kirk.client]]
# ...

Running it manually

importasynciofromkirk.clientimportIrcClientfromkirk.kirkimportKirkasyncdefmain() ->None:
loop=asyncio.get_running_loop()
client=IrcClient(
host="irc.libera.chat",
nick="NosySpock",
)
kirk=Kirk([client], loop)
# UI is select()-based, so run in a separate thread_=loop.run_in_executor(None, kirk.run)
# start the actual clientawaitasyncio.gather(client.run())
if__name__=="__main__":
asyncio.run(main(), debug=False)

About

Minimalistic, extensible and almost complete IRC client and UI

Resources

Stars

2 stars

Watchers

1 watching

Forks

Contributors

Languages