nirc-rs/CHANGES.md

239 lines
12 KiB
Markdown

# 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`** — removed `pub mod bitchat;` and re-exports
- **`src/core/protocol.rs`** — removed `ProtocolType::BitChat` variant and
all of its match arms in `tag()`, `label()`, `badge()`, `naim_color()`;
updated the four protocol unit tests
- **`src/core/command.rs`** — removed `BitChatPeers`, `BitChatDm`,
`BitChatSendFile` command variants; removed the `"bitchat" | "p2p"`
parser arm and the `"bitchat" => ProtocolType::BitChat` FromStr arm;
removed the `"bitchat" | "bc" | "p2p"` arm from `/xfer` protocol lookup
- **`src/engine/dispatcher.rs`** — removed `ProtocolCommand::BitChat`
variant; removed `connect_bitchat()` method; removed BitChat dispatch
arms in `Msg`, `Me`, `Say`, `quit_for`, and the explicit
`BitChatPeers`/`BitChatDm`/`BitChatSendFile` handler block; removed
BitChat from the connect dispatch and the tag-map lookup table
- **`src/tui/menubar.rs`** — removed the "Connect → BitChat…" menu entry
- **`src/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 doc
- **`src/core/history.rs`** — removed the `"P2P" => BitChat` tag mapping
(old history files with this tag will be silently reassigned to Status)
- **`src/logging/mod.rs`** — removed BitChat from `sanitize_server`
match; updated the test
- **`src/transfer/engine.rs`** — updated the integration test to use
`ProtocolType::Adc` instead of `ProtocolType::BitChat`
- **`src/core/app.rs`** — updated the
`next_tab_by_priority_mixes_protocols_freely` test to use
`ProtocolType::Adc` instead of `ProtocolType::BitChat`
- **`src/config/mod.rs`** — updated the BitChat server-entries doc
section to note the removal
- **`src/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 the `Command::BitChatPeers | BitChatDm | BitChatSendFile`
dispatch arm
- **`Cargo.toml`** — bumped version to 0.10.2; removed `libp2p`
dependency (BitChat was the only consumer); removed `"p2p"` from the
keywords list
- **`NOTICES.md`** — new file, contains the full rationale and
re-evaluation criteria for the BitChat withdrawal
- **`README.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 at `NOTICES.md`
### User Impact
- **Existing configs:** Any `[[servers]]` entry with
`protocol = "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:
1. 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.
2. The BitChat reference implementation's license is unambiguous and
permits third-party reimplementations.
3. 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`
(was `NOTICE`). Per the IRCv3 CTCP spec, requests must be PRIVMSG;
only replies use NOTICE. This was why `/ctcp <nick> VERSION` was
silently ignored by strict servers.
- **Self-targeted CTCP visible** — `/ctcp mynick VERSION` now 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.
- **`/away` tracking** — Added `is_away` and `away_message` fields to
`ConnState`. The `/away [msg]` command optimistically marks the local
state and posts a confirmation notice. Added explicit handlers for
`RPL_NOWAWAY` (306) and `RPL_UNAWAY` (305) instead of letting them
fall through to the generic numeric dump.
- **IRCv3 `away-notify` handler** — Added a dedicated `AWAY` command
handler that caches the away reason per nick in `state.nick_away` and
posts a notice. Previously the `away-notify` capability was negotiated
but the incoming AWAY messages fell into the "Unhandled command" path.
- **`/who` hardening** — `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 explicit `RPL_ENDOFWHO` (315) terminator
handler. This addresses the historical `/who <self>` crash.
- **`/me` local 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.).
- **`/notice` local 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`** — `InputThrottle` struct with
sliding-window rate limiting and per-send line cap. Returns
`Allow { lines_sent }` or `Reject { lines_sent, dropped, reason }`.
7 unit tests.
- **`src/main.rs`** — Wired the throttle into the `SendMessage` path.
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`** — Reverted `next_tab_by_priority` and
`prev_tab_by_priority` to 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 a
`try_render_inline_image` stub that gracefully returns `Unsupported`
for now. 20+ unit tests.
- **`src/tui/chat_view.rs`** — `render_body` now 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`** — Added `Command::Url`, `Command::Video`,
`Command::Image` variants and parsers (`/url`, `/video`, `/image`
commands).
- **`src/main.rs`** — Added handlers for the new commands in
`handle_user_command`. `/image` attempts 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`** — Added `TransferSummary` struct and
`TransferManager::summary()` method. The summary samples each active
transfer's `bytes_transferred` against 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_naim` and
`render_top_status_bar` now accept an `Option<&TransferSummary>`
parameter. When transfers are active, the static `nirc` label in the
top-right is replaced with `↓rate ↑rate filename %`. Falls back to
`nirc` when no transfers are active.
- **`src/main.rs`** — Calls `transfer_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`** — Added `wrap_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). The `ChatView::render` method 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 `/url` if
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 submission
- `MAX_LINES_PER_WINDOW = 8` — max lines per sliding window
- `WINDOW_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 returning `Unsupported`. 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.toml` in a future release.