Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wIRC
A native Android IRC client: mIRC colors, timestamps, OP powers (kick/ban/op), Ctrl+K/B/I formatting shortcuts, saved servers with on-connect identify commands, and every channel and private message opening as its own independently-styled window (1px black border, adjustable background transparency, black/white text toggle).
What's built so far (MVP)
- Raw socket IRC connection (
irc/IrcConnection.kt) with auto-reconnect/backoff, optional TLS, auto-join on connect. - Full mIRC control-code parser (
irc/MircColorParser.kt) — colors, bold, underline, reverse, reset — rendered as a ComposeAnnotatedString. - Protocol line parser (
irc/IrcLineParser.kt) for PRIVMSG/JOIN/PART/KICK/MODE/ TOPIC/NOTICE/QUIT/NAMES. ConnectionManager— app-wide singleton so every open window reads from the same shared state (messages, user list) regardless of which window is active.IrcConnectionService— foreground service that keeps the socket(s) alive when the app is backgrounded (Android kills background network connections aggressively without this).ChannelScreen— the actual window UI: scrollback with mIRC colors + per-line timestamps, input bar, long-press a nick for a Kick/Ban/Op/De-op menu, and a settings panel (gear icon) with the transparency slider and text color toggle.ChannelWindowActivity— one instance per channel. UsesdocumentLaunchMode="always"+resizeableActivity="true"in the manifest andFLAG_ACTIVITY_NEW_DOCUMENTon launch, which is the standard way an app can offer real independent, draggable/resizable OS-level windows on devices that support freeform multi-window (large tablets, Samsung DeX, etc).MainActivity/MainScreen— the main window. Lists saved servers as cards (Connect / Edit / Delete), and per-connected-server a box to join + open a channel window. "+ Add Server" opensServerEditDialogwith host, port, TLS, nick, auto-join channels, and a multi-line "on-connect / identify commands" field — e.g.PRIVMSG NickServ :IDENTIFY hunter2— sent automatically right after registration on every connect, before auto-join.ServerRepository— persists the saved server list (including on-connect commands) toservers.jsonin app-private storage, so it survives app restarts. This is the "file that saves that information" you asked for.- Private messages:
ConnectionManagernow keys PMs by the other person's nick (not our own), and emits anewQueryBuffersevent the first time a PM from someone new arrives.IrcConnectionServicelistens for that and auto-launches aChannelWindowActivityfor it — so a PM pops its own window the same way tapping a channel does, no different from every other window in the app. - Ctrl+K / Ctrl+B / Ctrl+I: hardware-keyboard shortcuts wired into the input
field in
ChannelScreen.kt. Ctrl+B/I insert the raw bold (\u0002) / italic (\u001D) toggle control chars at the cursor. Ctrl+K opens a 16-swatch mIRC color picker dialog (foreground, then optional background) and inserts the real\u0003FG,BGwire code — same bytes mIRC/HexChat send.
Known limitations / what's still rough
- "Minimize" isn't an app feature — on devices with freeform multi-window
(large tablets, Samsung DeX, etc.) the OS itself draws minimize/maximize/
close chrome around any
resizeableActivity="true"window. BothMainActivityandChannelWindowActivityare marked resizable so they get that treatment automatically; there's no button to build on the app side. - No SASL handshake yet —
ServerConfighassaslUser/saslPassfields butIrcConnectiononly sendsCAP REQ :sasland stops there. The "on-connect commands" field is the current way to identify (it just sends a plainPRIVMSG NickServ :IDENTIFY ...after registration, which works fine on Rizon/most networks even without real SASL). - Multi-window is best-effort, same as before — genuinely dependent on device/OEM support for freeform windowing. This is a platform limitation, not something the app can force.
- No notifications for mentions when a window isn't focused yet.
- Channel list per server isn't persisted — only the server configs
(including identify commands) are saved; which channels you had open resets
each app restart. Worth adding to
ServerRepositorynext if it bugs you.
Building — Claude Code / PowerShell, no Android Studio
This project lives at C:\wallpapers\wIRC. Since you're picking this up
with Claude Code the same way as Cart & Dagger: it needs the Android SDK
command-line tools + Gradle, same setup you've already got at
C:\Users\admin\AppData\Local\Android\Sdk.
From PowerShell, in C:\wallpapers\wIRC:
cd C:\wallpapers\wIRC
# One-time: point Gradle at your existing SDK install
$env:ANDROID_HOME = "C:\Users\admin\AppData\Local\Android\Sdk"
"sdk.dir=C:\\Users\\admin\\AppData\\Local\\Android\\Sdk" | Out-File -Encoding ascii local.properties
# Generate the Gradle wrapper jar (not shipped in this zip — it's a binary)
# Requires a local Gradle install once, just to bootstrap the wrapper:
gradle wrapper --gradle-version 8.9
# Build
.\gradlew.bat assembleDebug
The debug APK lands at C:\wallpapers\wIRC\app\build\outputs\apk\debug\app-debug.apk.
From there, install it the same way you've been doing for Cart & Dagger —
adb install, or transfer it over your own hosting and install directly on
the tablet/phone.
If Claude Code hits a missing gradle command for that one-time wrapper
bootstrap, the SDK's cmdline-tools don't include Gradle itself — grab it
separately (choco install gradle if you use Chocolatey, or download the
binary distribution and add it to PATH) just for that first gradle wrapper
call; every build after that uses .\gradlew.bat and doesn't need a system
Gradle install anymore.
Transferring to tablet/phone
Once you've got an APK (built on the laptop in Android Studio, or later directly on-device via Claude Code in Termux/proot once that's sorted out):
- Simplest:
adb install app-debug.apkif the device is plugged in / on the same network with ADB over Wi-Fi enabled. - Or just copy the APK over via your own file transfer (your hosting, a shared folder, whatever you'd normally use) and install it directly on the device — you'll need "install unknown apps" allowed for whichever app you use to open the APK file.
Suggested next steps
- Wire up persistence for server/channel lists (Room or DataStore) so
MainActivityremembers your setup between launches. - Finish SASL PLAIN auth in
IrcConnection. - Add a notification path for mentions when a channel window isn't focused.
- Decide on nick auto-complete / tab-complete in the input bar.