Skip to content
wodencafePublic

About

No description, website, or topics provided.

Resources

Stars

20 stars

Watchers

2 watching

Forks

Latest commit

 

History

1,849 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

IRCafe

IRCafe is a Java 25 desktop chat client with a Swing UI and a Spring Boot backend, supporting IRC, Quassel Core, and Matrix backends.

Screenshot_20260301_164811
* Light Theme

Screenshot_20260301_164951
* Dark Theme

Quick start

./gradlew bootRun

This launches the Swing app and loads runtime config from ${XDG_CONFIG_HOME}/ircafe/ircafe.yml (or ~/.config/ircafe/ircafe.yml).

Features

Core IRC

  • Multi-server connections with add/edit/manage server dialogs.
  • TLS and SASL (AUTO, PLAIN, SCRAM-SHA-256, SCRAM-SHA-1, EXTERNAL, ECDSA-NIST256P-CHALLENGE).
  • Auto-reconnect with backoff + jitter, plus heartbeat timeout detection.
  • Global SOCKS5 proxy plus per-server proxy override (auth, remote DNS, connect/read timeouts, proxy test).
  • Auto-join channels or PM targets and per-server perform-on-connect commands.
  • Native IRC flood protection in Preferences > Network > Flood protection is enabled by default for new and existing configurations. Ordinary commands share a two-command burst allowance per connection, starting full and rebuilding one credit every 2000 ms, capped at two. Once the allowance is spent, further commands wait for credit to rebuild, without a warm-up penalty. Auto-joins start five seconds after registration (and NickServ identification when required), run in the background, and stop on disconnect. Both timings are configurable. Uncheck "Enable outgoing rate limiting" to completely bypass command pacing; the separate auto-join startup delay still applies (set it to zero to join immediately). Changes apply on reconnect. Protocol negotiation, keepalives, and QUIT remain immediate.
  • Rich slash command support for connection/session control, channel/user ops, invite workflows, monitor, ignore/soft-ignore, CTCP, DCC, CHATHISTORY, filters, and raw IRC.

Matrix Backend

  • Matrix transport backend with homeserver probe + token-authenticated connect flow.
  • Room and DM messaging, room joins/leaves, room directory/listing, and sync-based timeline ingestion.
  • Matrix-backed compose features mapped into IRCafe flows, including reply/react/edit/redact, typing, read markers, and history navigation.
  • Matrix support is active and tested, but full slash-command parity with IRC is still in progress.

IRCv3 and Bouncer Support

  • Capability negotiation with per-capability runtime toggles.
  • IRCv3 capability negotiation includes message-tags, server-time, echo-message, standard-replies, labeled-response, batch, draft/read-marker, draft/multiline, draft/chathistory, and draft/message-redaction, alongside znc.in/playback.
  • Replies (+reply), reactions (+draft/react, +draft/unreact), and typing (+typing) use client-only tags over message-tags; these tag names are not requested as capabilities. Message editing remains experimental and is excluded from capability negotiation.
  • See the IRCv3 review evidence guide for protocol checks and reproducible screenshots.
  • See the IRCv3 specification comparison for supported protocol names, coverage, and known conformance gaps.
  • Partial IRCv3 sts support: secure-connection policy learning and persistence with later TLS/port upgrades; immediate plaintext-to-TLS upgrade is not implemented.
  • Message reply/reaction/edit/redaction flows in chat UI and command layer.
  • Typing indicators (send + receive) and read-marker updates.
  • ZNC and soju network discovery with ephemeral server entries, per-network auto-connect preferences, and optional save of discovered entries to the main server list.

Chat UX

  • Docked chat workspaces with per-buffer state.
  • Multiple buffers can be open on screen simultaneously.
  • Unread + highlight counters in the server tree.
  • Presence folding (join/part/quit/nick condensation).
  • Transcript context menu actions (reply, react, redact, inspect, must be enabled on the server).
  • Find-in-transcript support, load-older controls, and history context actions.
  • Command history, nick completion, and alias expansion.
  • Nick context menu actions for query/whois/ctcp, moderation, DCC, and ignore toggles.
  • CTCP request routing options and configurable CTCP auto-replies (VERSION, PING, TIME).

Appearance and Preferences

  • Theme system with FlatLaf, DarkLaf, curated IntelliJ themes, optional full IntelliJ pack list, and live preview.
  • Accent overrides, chat palette controls (timestamp/system/mention), mention strength, and chat font family/size controls.
  • FlatLaf tweak controls for density and corner radius, plus optional global UI font override.
  • Preferences tabs for appearance, startup, tray/notifications, chat, CTCP replies, IRCv3, embeds/previews, history/storage, notifications, commands, diagnostics, filters, network, and user lookups.

Monitor

  • Persistent per-server monitor nick list with /monitor and /mon, plus a dedicated monitor panel.
  • Automatic monitor resync on connect; ISON fallback polling when MONITOR is unavailable.

Filtering and Ignore

  • Hard ignore and soft ignore lists (with CTCP behavior toggles).
  • WeeChat-style render-time filters with:
    • Scope matching
    • Direction/kind/source/tag/text matching
    • Global defaults and per-scope overrides
  • Filter placeholders/hints with collapse behavior and history-batch controls.

Logging and History

  • Optional embedded HSQLDB logging with Flyway-managed schema.
  • Remote-only history mode when DB logging is disabled.
  • Logging controls for PM logging, soft-ignored line logging, and retention.
  • History loading integrates local DB data with IRCv3 CHATHISTORY and ZNC playback remote fill.
  • Duplicate suppression in storage paths (message-id and exact-match checks where applicable).
  • Per-server Log Viewer node with async search/export (off-EDT), sortable columns, and configurable column visibility.
  • Log Viewer filters: nick, message text, hostmask, channel, date range, and protocol/server-event suppression controls.

Interceptors

  • Per-server interceptor system with a dedicated Interceptors tree group.
  • Multiple interceptor definitions, each with:
    • Server scope (this server or any server)
    • Channel include/exclude rules (All, None, Like, Glob, Regex)
    • Trigger rules by event type plus message/nick/hostmask matching
  • Action pipeline per interceptor:
    • Status bar notification
    • Desktop toast
    • Sound (built-in or custom file)
    • External script execution
  • Captured hits table and per-server hit counts shown in the tree.

Notifications

  • System tray integration (close-to-tray, minimize-to-tray, start minimized).
  • Desktop notifications for highlights, private messages, and connection state.
  • Notification sound selection (built-in and custom).
  • Event-driven notification rules (kicks, bans, invites, modes, joins/parts, PM/notice/CTCP, topic changes, netsplit, etc.).
  • Rule actions can route to toast, status bar, sound, notifications node, script, and optional Pushy forwarding.
  • Rule cooldown plus toast dedupe/rate-limiting behavior to reduce spam.
  • A number of built-in sounds to choose from, or customize with your own.

Media and Previews

  • Optional inline image embedding for direct image links (png, jpg, gif, webp).
  • Optional animated GIF playback.
  • Link previews (OpenGraph/oEmbed + dedicated resolvers for sites such as Wikipedia, YouTube, Slashdot, IMDb, Rotten Tomatoes, X, Instagram, Imgur, GitHub, Reddit, Mastodon, and major news pages).

DCC

  • DCC chat/file workflows (/dcc ..., /dccmsg) plus a DCC Transfers panel with action hints and quick follow-up actions.

Utility Panels

  • Channel List node for /list results with filtering and double-click join.
  • User command alias editor with HexChat commands.conf import.
  • Monitor and Notifications nodes per server for quick operational actions.
  • Runtime diagnostics surfaces under Application (Unhandled Errors, AssertJ Swing, jHiccup, Inbound Dedup, JFR, Spring, Terminal), including bounded event feeds plus clear/export actions.

Optional first-launch setup

New profiles are offered a short wizard for an IRC server/nickname, an existing account's SASL login, and channels to join when connecting. Every page has Skip this step, and Skip setup is available throughout. Closing the wizard or pressing Escape also skips setup entirely. Skipping the server page keeps the default connection; skipping account or channels leaves those choices empty.

Choices are saved only with Save and finish (or by skipping the final page). Skipping setup entirely discards all wizard edits and preserves the default settings. IRCafe stays disconnected after the wizard so you can choose when to connect. Settings can be changed later in Servers.

Completion or dismissal is remembered in the user's runtime config. Existing profiles, including upgrades from versions without this wizard, do not see it. The wizard works with all distribution formats, including the Windows MSI and ZIP.

Requirements

  • Java 25 for local run/build tasks (./gradlew bootRun, ./gradlew test, ./gradlew jpackage, java -jar ...).
  • GNU Make + Docker only if using the optional Makefile Docker shortcuts.
  • Flatpak + flatpak-builder only if building Flatpak bundles on Linux.
  • Windows + WiX Toolset on PATH only if building the Windows MSI installer.
  • Linux + fakeroot, dpkg-dev, and rpm only if building both native Linux packages.
  • Linux + curl and file only if building a single-file AppImage (the build downloads pinned packaging tools).

Project layout

  • Entry point: src/main/java/cafe/woden/ircclient/IrcSwingApp.java
  • src/main/java/cafe/woden/ircclient/ui: Swing UI, docking, dialogs, rendering, tray integration.
  • src/main/java/cafe/woden/ircclient/app: orchestration, mediator flow, command dispatch, notifications.
  • src/main/java/cafe/woden/ircclient/irc: IRC/Matrix/Quassel protocol integrations and capability handling.
  • src/main/java/cafe/woden/ircclient/config: runtime config models, property binding, registries.
  • src/main/java/cafe/woden/ircclient/logging: log persistence, history ingestion, log viewer services.
  • src/main/java/cafe/woden/ircclient/net: TLS/proxy bootstrapping and lightweight HTTP utilities.
  • src/test/java/cafe/woden/ircclient: unit + integration + architecture tests.
  • src/functionalTest/java/cafe/woden/ircclient: Swing functional tests (*FunctionalTest).

Makefile shortcuts (optional)

The repository includes a root Makefile with convenience commands that call Gradle directly.

make help
make build
make test
make check

If you prefer a Make-first workflow, these cover most tasks:

Workflow Make Gradle equivalent
Run app from source make bootrun ./gradlew bootRun
Build runnable jar make jar ./gradlew bootJar
Fast local feedback make quick-check ./gradlew quickCheck
Run lint checks make lint ./gradlew lint
Run unit/non-functional tests make test ./gradlew test
Run integration tests make integration-test ./gradlew integrationTest
Run architecture guardrails make architecture-test ./gradlew architectureTest
Find architecture refactoring candidates make architecture-report ./gradlew architectureReport
Run Swing functional tests make functional-test ./gradlew functionalTest
Verify UI changes make verify-ui-change ./gradlew verifyUiChange
Verify Spring changes make verify-spring-change ./gradlew verifySpringChange
Verify architecture changes make verify-architecture-change ./gradlew verifyArchitectureChange
Run strict analysis make strict-analysis ./gradlew strictAnalysis
Generate coverage report make coverage-report ./gradlew coverageReport
Build app image make jpackage ./gradlew jpackage
Run full verification make check ./gradlew check

Run any Gradle task(s) via:

make gradle TASKS="bootRun"
make gradle TASKS="integrationTest --tests 'cafe.woden.ircclient.irc.QuasselCoreContainerIntegrationTest'"

Build/test in Docker (no local JDK install required):

make docker-image
make docker-build
make docker-check
make docker-gradle TASKS="test"
# Also available: make docker-lint, make docker-integration-test, make docker-architecture-test, make docker-functional-test

Notes:

  • Local Make targets default GRADLE_USER_HOME to ./.gradle-local (override with LOCAL_GRADLE_USER_HOME=/path).
  • Docker shortcuts run ./gradlew inside a local image built from versioned Dockerfile.build.
  • Dockerfile.build pins eclipse-temurin:25-jdk by digest for reproducible toolchain resolution.
  • Docker targets auto-build the image if missing (override with DOCKER_IMAGE=... if needed).
  • A persistent repo-local cache directory (./.gradle-docker) is used for Docker Gradle cache reuse between runs.

Run from source

From the project root:

./gradlew bootRun
# or:
make bootrun

This launches the Swing UI.

Build a runnable jar

./gradlew bootJar
# or:
make jar
java -jar build/libs/*.jar

Release verification

The Release (jpackage + flatpak) workflow verifies the exact tagged commit before building or publishing release assets. Its verification job runs the same five checks as CI, with the version from the tag:

./gradlew --no-daemon lint test integrationTest architectureTest functionalTest -Pversion=<release-version>

The checks use CI's headless mode; dialog-dependent functional tests are skipped. If verification fails, times out, or is cancelled, the JAR and platform packaging jobs cannot publish a release. Available test and analysis reports are uploaded to the workflow's release-verification-<attempt> artifact, including on failure, and retained for seven days.

Manual workflow runs on branches skip the release checks and produce development artifacts without publishing a GitHub release. Manual runs on tags use the same verification gate as tag pushes.

Release notes

Pushing a v* tag runs the Release (jpackage + flatpak) workflow and publishes a GitHub release with automatically generated notes. GitHub selects the previous release as the comparison base and includes merged pull requests, contributors, and a Full Changelog comparison link. The JAR publishing step generates the notes first; subsequent platform package uploads preserve that release body. Manual workflow runs on branches upload build artifacts without publishing a release.

Notes use PR titles, so give pull requests descriptive titles. The categories in .github/release.yml use the existing enhancement, bug, and documentation labels; unlabeled PRs appear under Other changes. Direct commits are visible through the full comparison link rather than individual release-note bullets. Notes live on the GitHub release page; there is no generated CHANGELOG.md committed back to the repository.

This applies to new releases after the workflow change is included in the tagged commit. To add notes to an existing release, edit it on GitHub, select the previous tag, click Generate release notes, review the result, and save it.

Build an app image (jpackage)

./gradlew jpackage
# or:
make jpackage

Output is written under build/dist/ using the platform's app-image layout. This is a directory bundle; use jpackageAppImage below for a single .AppImage file.

On Linux, the generated app image also includes:

  • IRCafe.desktop
  • install.sh
  • uninstall.sh

You can customize the Linux desktop launcher install prefix used in generated desktop entries:

./gradlew jpackage -PappInstallDir=/opt/IRCafe

To install just the desktop entry for the current user on Linux:

./gradlew installLinuxDesktopEntry

Build a Windows MSI installer

On Windows, install JDK 25 and WiX Toolset (CI uses WiX 3.14). For WiX 3, add its bin directory, containing candle.exe and light.exe, to PATH. Then run in PowerShell:

.\gradlew.bat clean jpackageMsi

The build uses IRCafe's Git-derived project version automatically. Tagged release CI supplies the release tag's version; use -Pversion=<release-version> only when explicitly building a particular release locally. Output is build/installer/IRCafe-<version>.msi; the portable app image remains in build/dist/IRCafe/. The MSI bundles Java, so users do not need to install a JRE. It installs for all users (requires administrator approval), offers a destination directory chooser and shortcut options, and supports removal through Windows Settings. A fixed upgrade UUID lets newer release versions replace an existing installation. Windows Installer versions must be numeric major.minor.patch, with major/minor at most 255 and patch at most 65535. Snapshot/prerelease suffixes are stripped; builds sharing the same numeric version are not distinct upgrades.

MSIs must be built on Windows; jpackage does not cross-compile installers. Tagged releases publish ircafe-<version>-windows-x64.msi alongside the portable ZIP. The Manual Test Build workflow's windows target also uploads both formats. Both workflows run an install/uninstall smoke test on the Windows runner before uploading the MSI. The installer is currently unsigned.

Build Linux DEB and RPM packages

On Linux, install JDK 25 and the native packaging tools. For Ubuntu/Debian:

sudo apt-get install fakeroot dpkg-dev rpm
./gradlew clean jpackageLinux

Use jpackageDeb or jpackageRpm to build just one format. Packages are written to build/installer/deb/ and build/installer/rpm/; the portable app image remains in build/dist/IRCafe/. Each package bundles Java, installs under /opt/ircafe, and adds an application-menu entry. Installation and removal use the system package manager; user configuration and history stay in the user's profile. The optional first-launch setup wizard works the same way as in other distribution formats.

For example, install a downloaded package with one of:

sudo apt install ./ircafe-VERSION-linux-x64.deb
sudo dnf install ./ircafe-VERSION-linux-x64.rpm

Newer packages upgrade the existing ircafe package. Remove it with sudo apt remove ircafe or sudo dnf remove ircafe. These downloads do not configure an update repository; install a newer downloaded package to upgrade.

The package version comes from the same Git-derived project version as the other native installers. Snapshot/prerelease suffixes are stripped. The package revision defaults to 1 and can be overridden with -PlinuxPackageRelease=<revision>; builds with the same numeric version and revision are not distinct upgrades. DEB maintainer metadata can be overridden with -PlinuxDebMaintainer=<email>. Native packages must be built on Linux for the target architecture.

Tagged releases attach .deb and .rpm files alongside the portable archives for both linux-x64 and linux-arm64. The Manual Test Build workflow's linux target uploads these formats plus AppImage for x64. CI builds on Ubuntu 24.04 and checks installation, upgrade, GUI startup with the bundled runtime, and removal in disposable Ubuntu 24.04 and Fedora 43 containers before uploading the packages. Other distributions and older releases have not been verified.

To reproduce the package checks, run bash packaging/linux/build-native-packages.sh from the repository root. It builds revision 0 fixtures in build/installer-test/, followed by revision 1 packages. Run bash packaging/linux/test-native-package.sh CURRENT_PACKAGE PREVIOUS_PACKAGE as root only inside a disposable container, with the packages mounted read-only; the script installs system dependencies and creates a test user. The Linux steps in .github/workflows/release-jpackage.yml show the complete container commands.

Build a single-file AppImage (Linux)

./gradlew jpackageAppImage

This wraps the bundled Java runtime and application in an executable AppImage. Output is build/installer/appimage/IRCafe-<version>-<architecture>.AppImage, using the existing Git-derived numeric packaging version and the build machine's x86_64 or aarch64 architecture. Build on Linux with Temurin JDK 25 (as in CI) and the curl and file utilities; distro-provided JDKs can introduce additional system-library dependencies. The build downloads version-pinned, SHA-256-verified appimagetool and runtime releases into build/appimage/tools/; it does not require FUSE or root privileges.

To run a downloaded release:

chmod +x ircafe-VERSION-linux-x64.AppImage
./ircafe-VERSION-linux-x64.AppImage

No separate Java installation or package-manager installation is needed. The host still needs a graphical desktop and its usual X11, fontconfig, and ALSA libraries. Configuration and history use the same user profile as other IRCafe distributions, including the optional first-launch setup wizard. Replace the file to upgrade; removing it leaves your profile intact. Menu integration depends on the desktop's AppImage integration tools.

If FUSE is unavailable, run with --appimage-extract-and-run. This extracts to a temporary directory for that run and requires additional free disk space.

Release CI builds AppImages for x64 and ARM64 and attaches them to GitHub releases. The manual linux target also uploads an x64 AppImage. Before upload, both workflows test extraction, desktop metadata, the bundled runtime, and launching the actual file from a path containing spaces in disposable Ubuntu 24.04 and Fedora 43 containers. Those tests use extract-and-run mode because containers lack /dev/fuse; FUSE mounting and desktop integration are not exercised by CI. The test script is packaging/appimage/test-appimage.sh and is intended only for disposable containers. Older distributions have not been verified.

Build a Flatpak bundle (Linux)

Install tooling (example for Debian/Ubuntu):

sudo apt-get update
sudo apt-get install -y flatpak flatpak-builder
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo

Build the app image and Flatpak repo/bundle:

./gradlew jpackage generateFlatpakMetainfo
flatpak-builder --force-clean --repo=build/flatpak/repo --default-branch=stable --install-deps-from=flathub build/flatpak/workdir packaging/flatpak/cafe.woden.IRCafe.yml
flatpak build-bundle build/flatpak/repo build/dist/ircafe.flatpak cafe.woden.IRCafe stable --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo

On tagged GitHub releases, CI now publishes ircafe-<version>-linux-x64.flatpak as a release asset.

Developer workflow

Common local checks:

./gradlew quickCheck
./gradlew lint
./gradlew test
./gradlew check

One-time contributor setup:

./scripts/setup-git-hooks.sh

This enables the repo's commit-msg hook for Conventional Commit validation.

Targeted suites:

# Spring/context integration tests from src/test (classes ending with IntegrationTest)
./gradlew integrationTest

# Modulith/jMolecules/ArchUnit guardrails
./gradlew architectureTest

# Advisory refactoring candidates, with Markdown/JSON reports
./gradlew architectureReport

# Swing UI functional tests from src/functionalTest (classes ending with FunctionalTest)
./gradlew functionalTest

See architecture report tooling for the rules, thresholds, baseline comparison, and interpretation limits.

Functional tests default to headless mode, which skips tests requiring a dialog. Use -PfunctionalTestHeadless=false with a display to exercise those interactions. For example, the optional setup wizard can be verified on Linux with:

xvfb-run -a ./gradlew :functionalTest -PfunctionalTestHeadless=false --tests '*FirstRunSetupDialogFunctionalTest'

Quassel support integration matrix:

  • QuasselCoreRealServerIntegrationTest: validate against an already-running Quassel Core.
  • QuasselCoreContainerIntegrationTest: validate containerized Quassel bootstrap/connect/sync.
  • QuasselCoreContainerNetworkE2eIntegrationTest: validate Quassel + real ircd network flow.
  • All Quassel integration tests are opt-in and gated by quassel.it.* properties.

Real Quassel Core integration (opt-in):

# Validates live Quassel Core connect/auth/sync, lag probe heartbeat, disconnect, reconnect.
# Requires a reachable Quassel Core and credentials.
QUASSEL_IT_LOGIN=alice QUASSEL_IT_PASSWORD=secret \
./gradlew :integrationTest --tests 'cafe.woden.ircclient.irc.quassel.QuasselCoreRealServerIntegrationTest' \
  -Dquassel.it.enabled=true \
  -Dquassel.it.host=127.0.0.1 \
  -Dquassel.it.port=4242 \
  -Dquassel.it.login=alice \
  -Dquassel.it.password=secret

Optional knobs (env vars or -D properties): quassel.it.server-id, quassel.it.tls, quassel.it.nick, quassel.it.real-name.

Containerized Quassel Core integration via Testcontainers (also opt-in):

# Starts Quassel Core in Docker and validates setup/connect/sync/heartbeat/reconnect.
./gradlew :integrationTest --tests 'cafe.woden.ircclient.irc.quassel.QuasselCoreContainerIntegrationTest' \
  -Dquassel.it.container.enabled=true

Optional knobs: quassel.it.container.image, quassel.it.container.login, quassel.it.container.password, quassel.it.container.startup-timeout-seconds. Default image is pinned to linuxserver/quassel-core:0.14.0 for amd64 compatibility.

Expanded Quassel E2E (Quassel Core + local ngIRCd, with a second IRC server for network isolation):

# Validates network creation/connection, inbound and outbound messages/notices/actions,
# backlog selector boundaries, ordering, stable IDs/timestamps after reconnect,
# routing between networks with matching channel/nick names, automatic recovery,
# native read-marker sync across clients/reconnects, and network edit/removal persistence.
./gradlew :integrationTest --tests 'cafe.woden.ircclient.irc.quassel.QuasselCoreContainerNetworkE2eIntegrationTest' \
  -Dquassel.it.container.e2e.enabled=true

Transcript overlap and network isolation can also be checked without Docker or a display:

./gradlew :functionalTest --tests 'cafe.woden.ircclient.ui.chat.QuasselHistoryTranscriptFunctionalTest'

Optional knobs: quassel.it.container.e2e.quassel-image, quassel.it.container.e2e.irc-image, quassel.it.container.e2e.channel, quassel.it.container.e2e.message, quassel.it.container.e2e.login, quassel.it.container.e2e.password. When enabled with Docker available, these tests require successful runtime network creation and round trips; missing network creation fails the suite.

Direct IRC backend E2E (Pircbotx + local ngIRCd, no Quassel):

# Validates direct IRC backend connect/ready/join/inbound+outbound messages/reconnect.
./gradlew integrationTest --tests 'cafe.woden.ircclient.irc.PircbotxContainerNetworkE2eIntegrationTest' \
  -Dirc.it.container.e2e.enabled=true

Optional knobs: irc.it.container.e2e.irc-image, irc.it.container.e2e.channel, irc.it.container.e2e.bot-message, irc.it.container.e2e.app-message, irc.it.container.e2e.nick, irc.it.container.e2e.login.

Matrix Synapse container integration (opt-in):

# Starts a local Synapse container and validates probe/whoami/send/sync/history flows.
./gradlew integrationTest --tests 'cafe.woden.ircclient.irc.matrix.MatrixSynapseContainerIntegrationTest' \
  -Dmatrix.it.container.enabled=true

Optional knobs (property/env): matrix.it.container.image / MATRIX_IT_CONTAINER_IMAGE, matrix.it.container.server-name / MATRIX_IT_CONTAINER_SERVER_NAME, matrix.it.container.http-port / MATRIX_IT_CONTAINER_HTTP_PORT, matrix.it.container.startup-timeout-seconds / MATRIX_IT_CONTAINER_STARTUP_TIMEOUT_SECONDS, matrix.it.container.registration-secret / MATRIX_IT_CONTAINER_REGISTRATION_SECRET.

When to run which tests:

  • Spring Modulith/jMolecules/ArchUnit or module-boundary refactors: ./gradlew architectureTest test
  • Spring wiring/integration changes (new beans, events, transactional boundaries): ./gradlew integrationTest
  • Swing UI behavior changes (dialogs, tree interactions, panel flows, rendering): ./gradlew functionalTest test
  • Non-UI feature work: ./gradlew test
  • Pre-merge on larger changes: ./gradlew check plus relevant targeted suites above

Shortcut aliases:

./gradlew quickCheck
./gradlew verifyUiChange
./gradlew verifySpringChange
./gradlew verifyArchitectureChange
./gradlew verifyRefactor

Auto-fix workflow (Error Prone auto-corrects first, then Spotless formatting):

./gradlew spotlessApply
# Run Error Prone auto-corrects, then Spotless lint check
./gradlew spotlessLint
# Optional: override which Error Prone patch checks are applied
./gradlew spotlessApply -PerrorPronePatchChecks=CheckReturnValue,ReturnValueIgnored

Additional verification/reporting tasks:

./gradlew mutationTest
./gradlew pitest
./gradlew themeValidate
./gradlew strictAnalysis
./gradlew coverageReport
./gradlew jacocoTestReport
./gradlew jacocoIntegrationTestReport
./gradlew jacocoFunctionalTestReport
./gradlew dependencyCheckAnalyze
./gradlew cyclonedxBom
./gradlew taskTree --task check
./gradlew jmh

Command discovery

  • /help shows the main command groups (including backend-specific helpers).
  • /help dcc shows DCC chat/file commands.
  • /help chathistory, /help markread, and /help upload show focused usage for those flows.
  • /help edit, /help redact, and /help delete show IRCv3 compose mutation command help.
  • Quassel-specific workflows: /quasselsetup and /quasselnet ....
  • /filter help shows local filter command usage.
  • /monitor help shows monitor command usage.

Configuration

Runtime configuration (preferred)

When running IRCafe (from source or as a packaged jar), edit the runtime config file (loaded on startup and overrides the defaults in application.yml):

  • Default path: ${XDG_CONFIG_HOME}/ircafe/ircafe.yml when XDG_CONFIG_HOME is set.
  • Otherwise falls back to: ~/.config/ircafe/ircafe.yml (i.e. ${user.home}/.config/ircafe/ircafe.yml)

To use a different location, set ircafe.runtime-config (environment variable: IRCAFE_RUNTIME_CONFIG) or pass it on the command line:

IRCAFE_RUNTIME_CONFIG=/path/to/ircafe.yml java -jar build/libs/ircafe-*.jar
# or:
java -jar build/libs/ircafe-*.jar --ircafe.runtime-config=/path/to/ircafe.yml

Server definitions (IRC, Quassel Core, Matrix) use the irc.servers section.

IRC example:

irc:
    servers:
    - id: "libera"
      host: "irc.libera.chat"
      port: 6697
      tls: true

      # Optional: IRC PASS / server password (commonly needed for bouncers like ZNC)
      # ZNC examples: "username:password" or "username/network:password"
      serverPassword: "${IRCAFE_SERVER_PASSWORD:}"

      nick: "${IRCAFE_NICK:IRCafeUser}"
      login: "${IRCAFE_IDENT:ircafe}"
      realName: "${IRCAFE_REALNAME:IRCafe User}"

      sasl:
        enabled: false
        username: "${IRCAFE_SASL_USERNAME:}"
        password: "${IRCAFE_SASL_PASSWORD:}"
        mechanism: "PLAIN"

      autoJoin:
        - "#irclient"

Matrix example:

irc:
    servers:
    - id: "matrix-main"
      backend: "matrix"
      # Host can be a plain host or a full base URL (for example with a path prefix).
      host: "https://matrix.example.org"
      port: 443
      tls: true

      # Matrix access token (preferred here). IRCafe also falls back to sasl.password if this is blank.
      serverPassword: "${IRCAFE_MATRIX_ACCESS_TOKEN:}"

      # Optional local display identity used by IRCafe UI defaults.
      nick: "@ircafe:example.org"
      login: "ircafe"
      realName: "IRCafe Matrix"

      # Optional auto-join targets (room id or alias).
      autoJoin:
        - "!someroom:example.org"
        - "#ircafe:example.org"

You can also override UI behavior under the ircafe.ui prefix. For inline image previews (direct image links in chat), this is disabled by default:

ircafe:
  ui:
    imageEmbedsEnabled: false

You can toggle this at runtime from the GUI: Settings -> Preferences… -> Inline images.

Other runtime settings (theme and appearance tweaks, tray/notifications, CTCP replies, IRCv3 capability toggles, STS cache entries, monitor nick lists, filters, command aliases, interceptors, notification rules, logging preferences, and more) are persisted to the runtime config file as you change them in the UI.

Environment variables

The default application.yml uses these environment variables:

  • IRCAFE_NICK (defaults to IRCafeUser)
  • IRCAFE_IDENT (defaults to ircafe)
  • IRCAFE_REALNAME (defaults to IRCafe User)
  • IRCAFE_CTCP_VERSION (defaults to IRCafe)
  • IRCAFE_SERVER_PASSWORD (no default) — IRC PASS / server password (useful for ZNC: username:password or username/network:password)
  • IRCAFE_SASL_USERNAME (no default)
  • IRCAFE_SASL_PASSWORD (no default)

You can set them for a single run:

IRCAFE_NICK=myNick ./gradlew bootRun

Or export them in your shell:

export IRCAFE_NICK=myNick
export IRCAFE_IDENT=myIdent
export IRCAFE_REALNAME="My IRC Client"

To enable SASL, set irc.servers[].sasl.enabled: true in your config and set IRCAFE_SASL_USERNAME and IRCAFE_SASL_PASSWORD.

Data locations

  • Runtime config and UI state default to ${XDG_CONFIG_HOME}/ircafe/ircafe.yml when XDG_CONFIG_HOME is set, otherwise ~/.config/ircafe/ircafe.yml.
  • With logging enabled (default ircafe.logging.hsqldb.nextToRuntimeConfig: true), HSQLDB files (for example ircafe-chatlog.*) are stored next to the runtime config file.
  • Linux uninstall.sh removes the installed app image and desktop entry, but does not remove user config/history data.

Security notes

  • Keep irc.client.tls.trustAllCertificates: false unless you are intentionally testing with self-signed certs in a trusted environment.
  • For an IRC server, ZNC/other bouncer, or Quassel Core with a self-signed certificate, enable Allow self-signed and insecure certificates on the Connection tab of Add/Edit Server. This persists as irc.servers[].trustAllCertificates (default false) and skips certificate validation for that server's TLS connections, including SOCKS connections and discovered bouncer networks. The existing global trust-all setting still applies when enabled.
  • Interceptor and notification rule script actions execute local scripts. Only use scripts and paths you trust.

Platform notes

  • System tray and desktop notification behavior depends on OS/session support.
  • Linux supports D-Bus notification actions when enabled (ircafe.ui.tray.linuxDbusActionsEnabled: true).
  • Linux app-image builds include desktop/install helper files; other platforms keep standard app-image packaging.

Contributing

  • Commit messages follow Conventional Commits: <type>(<scope>): <subject>.
  • Local hooks are configured by ./scripts/setup-git-hooks.sh; CI validates the same rules.
  • Allowed types: feat, fix, refactor, perf, test, docs, build, ci, chore, style, revert.

Project support

Please feel free to file an issue, or get in touch on Libera.Chat channel #ircafe

License

GPL-3.0. See LICENSE.

About

No description, website, or topics provided.

Resources

Stars

20 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages