239 lines
12 KiB
Markdown
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.
|