12 KiB
nirc-rs — Patch Summary
This file summarizes the patch batches applied to nirc-rs, newest first.
0.10.2 — BitChat Module Withdrawn
Date: 2026-07-29
The BitChat protocol module and all of its integrations have been removed
from the codebase. See NOTICES.md for the full rationale.
Why
The BitChat project (Jack Dorsey's recently-announced P2P messaging protocol) is the subject of active litigation in the Indian courts. The legal status of the protocol specification, the reference implementation, and downstream reimplementations is currently unclear. Pending clarity, we have removed the module entirely rather than ship an encumbered protocol backend.
Files Changed
- Deleted:
src/protocols/bitchat.rs src/protocols/mod.rs— removedpub mod bitchat;and re-exportssrc/core/protocol.rs— removedProtocolType::BitChatvariant and all of its match arms intag(),label(),badge(),naim_color(); updated the four protocol unit testssrc/core/command.rs— removedBitChatPeers,BitChatDm,BitChatSendFilecommand variants; removed the"bitchat" | "p2p"parser arm and the"bitchat" => ProtocolType::BitChatFromStr arm; removed the"bitchat" | "bc" | "p2p"arm from/xferprotocol lookupsrc/engine/dispatcher.rs— removedProtocolCommand::BitChatvariant; removedconnect_bitchat()method; removed BitChat dispatch arms inMsg,Me,Say,quit_for, and the explicitBitChatPeers/BitChatDm/BitChatSendFilehandler block; removed BitChat from the connect dispatch and the tag-map lookup tablesrc/tui/menubar.rs— removed the "Connect → BitChat…" menu entrysrc/tui/chat_view.rs— removed BitChat from the protocol color lookup tables (both dim-color and NaimColor)src/tui/winlist.rs— removed BitChat from the badge char and badge color lookup tables; updated the module-level docsrc/core/history.rs— removed the"P2P" => BitChattag mapping (old history files with this tag will be silently reassigned to Status)src/logging/mod.rs— removed BitChat fromsanitize_servermatch; updated the testsrc/transfer/engine.rs— updated the integration test to useProtocolType::Adcinstead ofProtocolType::BitChatsrc/core/app.rs— updated thenext_tab_by_priority_mixes_protocols_freelytest to useProtocolType::Adcinstead ofProtocolType::BitChatsrc/config/mod.rs— updated the BitChat server-entries doc section to note the removalsrc/engine/crypto.rs— updated the module-level doc to note that the Noise primitive is now only used by ADC (was previously shared with BitChat)src/main.rs— renamed_p2p_keypair→_noise_keypair(still generated, since ADC uses it); removed the BitChat help text and replaced with a media-commands help section + a BitChat-removed note; removed theCommand::BitChatPeers | BitChatDm | BitChatSendFiledispatch armCargo.toml— bumped version to 0.10.2; removedlibp2pdependency (BitChat was the only consumer); removed"p2p"from the keywords listNOTICES.md— new file, contains the full rationale and re-evaluation criteria for the BitChat withdrawalREADME.md,STATUS.md,TODO.md,QUICKSTART.md/quickstart.md,man/man1/nirc.1,completions/nirc.{bash,zsh,fish},packaging/PKGBUILD,packaging/nirc.spec,packaging/debian/DEBIAN/control,BLOG_POST.md— updated to reflect the removal and point atNOTICES.md
User Impact
- Existing configs: Any
[[servers]]entry withprotocol = "bitchat"will be silently ignored at load time. You do not need to edit your config file, but you may remove the entries to clean it up. - Existing history files: Per-tab scrollback files tagged
P2P:<name>will fail to match any known protocol on load and will be silently assigned to the Status tab. The files themselves are not deleted; you can read them with a text editor if you need to recover the content. - No data loss: Your IRC / Matrix / ADC / Discord / Stout / Spacebar / Nerimity history, configs, and credentials are unaffected.
Re-evaluation Criteria
We will re-evaluate restoring the BitChat module when all of the following are true:
- The India courts case has reached a final judgement (not an interim order), OR the parties have publicly settled and the settlement terms are clear about downstream-implementation rights.
- The BitChat reference implementation's license is unambiguous and permits third-party reimplementations.
- There is at least one independent legal opinion (not from a party to the litigation) concluding that shipping a clean-room reimplementation of the protocol is safe.
Until then, the module will remain withdrawn.
0.10.1 — IRC Fixes, Throttle, Rotation Revert, URLs/Media, Bandwidth Monitor, Line Wrap
Date: 2026-07-28
This patch batch addresses the user-reported issues with nirc-rs 0.10.0 and adds several requested features. The changes are organized into five phases.
Phase 1: IRC Protocol Fixes (src/protocols/irc.rs, src/main.rs)
- CTCP spec compliance — Outgoing CTCP requests now use
PRIVMSG(wasNOTICE). Per the IRCv3 CTCP spec, requests must be PRIVMSG; only replies use NOTICE. This was why/ctcp <nick> VERSIONwas silently ignored by strict servers. - Self-targeted CTCP visible —
/ctcp mynick VERSIONnow displays the request in the relevant tab. Previously the entire CTCP block was skipped when the sender was the local nick, silently swallowing self-targeted queries. /awaytracking — Addedis_awayandaway_messagefields toConnState. The/away [msg]command optimistically marks the local state and posts a confirmation notice. Added explicit handlers forRPL_NOWAWAY(306) andRPL_UNAWAY(305) instead of letting them fall through to the generic numeric dump.- IRCv3
away-notifyhandler — Added a dedicatedAWAYcommand handler that caches the away reason per nick instate.nick_awayand posts a notice. Previously theaway-notifycapability was negotiated but the incoming AWAY messages fell into the "Unhandled command" path. /whohardening —RPL_WHOREPLY(352) now correctly splits the trailing field into hopcount and realname (per RFC 1459), displays the here/away flag (H/G) from the flags field, marks self-entries with(you), and has an explicitRPL_ENDOFWHO(315) terminator handler. This addresses the historical/who <self>crash./melocal echo (src/main.rs) — Actions are now echoed locally in the active tab immediately, so the user sees their action even on servers that don't echo own PRIVMSGs (bouncers, mock servers, etc.)./noticelocal echo (src/main.rs) — Same local-echo treatment for sent notices.
Phase 2: Input Rate Throttle + Channel Rotation Revert
- New module:
src/core/throttle.rs—InputThrottlestruct with sliding-window rate limiting and per-send line cap. ReturnsAllow { lines_sent }orReject { lines_sent, dropped, reason }. 7 unit tests. src/main.rs— Wired the throttle into theSendMessagepath. Input is split on newlines (paste guard), capped at 4 lines per submission, and rate-limited to 8 lines per 3 seconds. Rejected lines produce a single warning notice per burst (subsequent rejections are silent to avoid flooding the user's tab).src/core/app.rs— Revertednext_tab_by_priorityandprev_tab_by_priorityto static insertion-order cycling. The previous activity-tier-based reordering made Ctrl-N feel non-deterministic. Updated 4 existing tests to reflect the new behaviour.
Phase 3: URL Detection + Inline Photo + External Video
- New module:
src/tui/media.rs— URL detection (detect_urls), media classification (classify_url: image/video/other by extension), external launching (open_external: xdg-open / open / start with http-scheme safety check), inline-image protocol detection (detect_image_protocol: Kitty / iTerm2 / Sixel / None), and atry_render_inline_imagestub that gracefully returnsUnsupportedfor now. 20+ unit tests. src/tui/chat_view.rs—render_bodynow scans each text segment for URLs and renders them underlined in cyan. This is the foundation for the inline-photo and external-video features.src/core/command.rs— AddedCommand::Url,Command::Video,Command::Imagevariants and parsers (/url,/video,/imagecommands).src/main.rs— Added handlers for the new commands inhandle_user_command./imageattempts inline rendering and falls back to external open if the terminal doesn't support it.
Phase 4: Top-Right Bandwidth Monitor
src/transfer/mod.rs— AddedTransferSummarystruct andTransferManager::summary()method. The summary samples each active transfer'sbytes_transferredagainst the previous frame's sample to compute instantaneous bytes/sec. Tracks the top transfer by bandwidth (most active file). Rate-sampling state is cleaned up when transfers complete.src/tui/input_bar.rs—render_top_status_bar_naimandrender_top_status_barnow accept anOption<&TransferSummary>parameter. When transfers are active, the staticnirclabel in the top-right is replaced with↓rate ↑rate filename %. Falls back tonircwhen no transfers are active.src/main.rs— Callstransfer_manager.summary()once per frame and passes the result to the top status bar renderer.
Phase 5: Line Wrapping Fix
src/tui/chat_view.rs— Addedwrap_text(text, max_cols)helper that breaks on word boundaries when possible and falls back to hard character breaks for words longer than the available width (e.g. long URLs). TheChatView::rendermethod now wraps each body line to fit the available width instead of truncating at the right margin. 5 unit tests.
New Commands
/url <url>— open a URL in the OS default browser (xdg-open / open / start)/video <url>— launch a video URL in the OS default video player/image <url>— attempt inline image rendering; falls back to/urlif the terminal doesn't support inline images
Configuration
The throttle limits are currently hardcoded in src/core/throttle.rs:
MAX_LINES_PER_SEND = 4— max lines per single input submissionMAX_LINES_PER_WINDOW = 8— max lines per sliding windowWINDOW_SECS = 3— sliding window duration in seconds
These will be exposed as config options in a future release (see TODO.md).
What's NOT in These Patches (Deferred)
Per user direction, the following are deferred to follow-up sessions:
- Matrix protocol production hardening — Most complex of the group, gets its own session.
- Stout / Spacebar / Nerimity full builds — These are currently true
stubs whose
run_*()functions just log placeholder notices. Building them out to "production ready" is multiple full protocol implementations, each comparable in scope to the Discord backend. - Real inline image rendering — The
try_render_inline_image()function is a stub returningUnsupported. The graceful-fallback path (text placeholder + external open) is wired up, so this is a pure feature add with no risk to existing functionality. See TODO.md for the implementation outline. - Configurable throttle limits — Currently hardcoded; will be exposed
via
config.tomlin a future release.