kage

command module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 27, 2026 License: BSD-2-Clause, GPL-3.0 Imports: 47 Imported by: 0

README

kage

A terminal (TUI) XMPP client written in Go, built on Bubble Tea.

Features

  • Multi-account XMPP chat with a persistent background daemon (keeps you connected/notified while the TUI isn't running)
  • End-to-end encryption: OMEMO (v1/v2) and GPG, selectable per chat
  • Encrypted local message history (SQLite, optional password-derived key)
  • Voice/video calls (Jingle signaling, WebRTC via pion) and screen sharing
  • File transfer/attachments, message editing, replies, reactions, read receipts
  • Message Archive Management (MAM) history sync, carbons, chat states
  • Mouse support, themeable UI (Tokyo Night by default), configurable keybinds
  • System tray icon and desktop notifications

Install

Requires Go 1.26+.

go install github.com/jim-ww/kage@latest

Or try it with Nix:

nix run github:jim-ww/kage

Or add it to your flake inputs:

inputs.kage.url = "github:jim-ww/kage";
# environment.systemPackages = [ inputs.kage.packages.${system}.default ];

Usage

kage                  # launch the TUI (opens the add-account form on first run)
kage export           # export accounts/data
kage import           # import accounts/data
kage daemon           # manage the background service
kage --config <path>  # use a specific config file
kage --debug          # debug logging to <config dir>/kage/debug.log

Configuration

kage reads a YAML config (see config.example.yaml for every option, fully commented) from the default OS config directory unless --config is given. At minimum you need one account:

accounts:
  - jid: user@example.com
    password_cmd: pass show xmpp/user

Passwords (account and local storage) resolve in order: OS keyring → password_cmd → plaintext password.

Optional dependencies

  • mpv — playing video (video calls)
  • wf-recorder — screen sharing in calls
  • libnotify — desktop notifications
  • wl-clipboard / xclip — pasting images into chat

Support the project

If kage is useful to you, consider a small donation.

Monero (XMR)

83YGRqP8uHed6NeegZQeX9ccCxbzoRHHEEi7pTwk4aqdJZEVXXA6NWtetnsEM2v33zFBBt3Rp6DNhU9qhJEGPspU14yN8t7

License

GPL-3.0. Free to use, study, share, and modify — provided you keep the same freedoms for others.

Documentation

Overview

Jingle <-> SDP translation. This is deliberately in package main rather than in call/ or xmpp/: it's the only code that has to know both pion's SDP shapes and the XEP-0166/0167/0176/0320 XML structs, and neither of those packages may import the other (call stays decoupled from xmpp, same rule ui/crypto follow).

Only what an audio-only, rtcp-mux'd, trickle-ICE WebRTC call needs is translated today, but the content/SSRC plumbing is generalized to handle multiple m-lines (e.g. a future video content) so a second content doesn't require rewriting this file again. jingleContentsFromSDP/ sdpFromJingleContents are reused as-is for ICE restart's transport-replace/ -accept (see callsession.go's attemptICERestart/applyTransportReplace) - same offer/answer shapes, just with fresh ICE credentials.

Directories

Path Synopsis
Package call is the (not yet wired up) audio-call package: Opus encode/decode, mic/speaker I/O, and a pion/webrtc peer connection for a single audio-only Jingle call.
Package call is the (not yet wired up) audio-call package: Opus encode/decode, mic/speaker I/O, and a pion/webrtc peer connection for a single audio-only Jingle call.
Package crypto defines the e2ee seam kage's messaging path is built against.
Package crypto defines the e2ee seam kage's messaging path is built against.
aesgcm
Package aesgcm implements XEP-0454 (OMEMO Media Sharing) file encryption using AES-256-GCM for end-to-end encrypted file sharing via HTTP Upload.
Package aesgcm implements XEP-0454 (OMEMO Media Sharing) file encryption using AES-256-GCM for end-to-end encrypted file sharing via HTTP Upload.
gpg
Package gpg implements crypto.Encrypter by shelling out to the system gpg binary, reusing the user's existing keyring and gpg-agent for passphrases.
Package gpg implements crypto.Encrypter by shelling out to the system gpg binary, reusing the user's existing keyring and gpg-agent for passphrases.
localstore
Package localstore provides fast, purely local at-rest encryption for message history: AES-256-GCM under a key derived from a password via Argon2id.
Package localstore provides fast, purely local at-rest encryption for message history: AES-256-GCM under a key derived from a password via Argon2id.
omemo
Package omemo implements omemo.Store (github.com/jim-ww/omemo-go) backed by kage's shared sqlite database, one Store per (account, protocol) — the upstream Store interface is single-device/single-account by design, and an account speaking both OMEMO protocols maintains two separate Store instances (see account.go's setupOmemo).
Package omemo implements omemo.Store (github.com/jim-ww/omemo-go) backed by kage's shared sqlite database, one Store per (account, protocol) — the upstream Store interface is single-device/single-account by design, and an account speaking both OMEMO protocols maintains two separate Store instances (see account.go's setupOmemo).
Package daemon implements kage's background service: the one process per user session that owns every configured account's XMPP connection, storage, and decryption (GPG/OMEMO).
Package daemon implements kage's background service: the one process per user session that owns every configured account's XMPP connection, storage, and decryption (GPG/OMEMO).
Package ipc is the wire protocol between the kage TUI (a thin client) and the kage background daemon (--background mode), which owns all XMPP connections, storage, and decryption.
Package ipc is the wire protocol between the kage TUI (a thin client) and the kage background daemon (--background mode), which owns all XMPP connections, storage, and decryption.
ui
filepicker
Package filepicker provides a file picker component for Bubble Tea applications.
Package filepicker provides a file picker component for Bubble Tea applications.
Package version holds kage's build version, set via -ldflags -X at build time (see flake.nix).
Package version holds kage's build version, set via -ldflags -X at build time (see flake.nix).
Package xmpp wraps mellium.im/xmpp into a per-account client: dial/auth, roster fetch, sending messages, and listening for incoming stanzas.
Package xmpp wraps mellium.im/xmpp into a per-account client: dial/auth, roster fetch, sending messages, and listening for incoming stanzas.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL