Commit graph

318 commits

Author SHA1 Message Date
06a10e2df8 i18n: rename help language state to ui language 2026-05-24 12:11:54 +08:00
1f1c2398b6 tui: make command output scrollable 2026-05-24 11:55:26 +08:00
57bf3cfc67 commands: centralize interactive command catalog 2026-05-24 11:25:46 +08:00
8eb311e54b i18n: restore code-based language syntax 2026-05-24 11:09:17 +08:00
a693d281f8 ux: collapse help surface around manual 2026-05-24 10:17:25 +08:00
15aac7134f ci: preseed valgrind smoke host key 2026-05-24 09:22:10 +08:00
e78989c7ce release: prepare 1.0.1 2026-05-24 09:16:07 +08:00
782d21eaae docs: align development guide with modules 2026-05-24 09:01:00 +08:00
86e1ec8e32 i18n: tolerate whitespace in language parsing 2026-05-24 08:58:51 +08:00
1897a980d5 ci: harden valgrind smoke check 2026-05-24 08:55:34 +08:00
ddf1242b17 test: wait for connection limit readiness 2026-05-24 08:53:08 +08:00
84e26e3f74 test: wait for basic health readiness 2026-05-24 08:47:36 +08:00
998da4288f test: stabilize stress test runner 2026-05-24 08:42:39 +08:00
fa16beb7a6 test: stabilize anonymous access checks 2026-05-23 23:30:43 +08:00
cd170d3245 docs: refresh module quick reference 2026-05-23 22:12:22 +08:00
f39f07b205 ci: add local ci-test target 2026-05-23 22:10:28 +08:00
095491927a test: cover connection limit regressions 2026-05-23 21:38:27 +08:00
6d5c77b850 ci: make integration tests strict 2026-05-23 21:26:19 +08:00
6ec86eb016 i18n: localize idle timeout notice 2026-05-23 20:10:51 +08:00
73655d0e70 i18n: localize startup cli text 2026-05-23 20:08:18 +08:00
fd6cdbf627 i18n: localize exec guidance text 2026-05-23 20:03:31 +08:00
81c3f45864 support: move guide copy into text module 2026-05-23 19:55:44 +08:00
0cf8ac6759 i18n: centralize command guidance text 2026-05-23 19:45:53 +08:00
4fb531771b help: move bilingual help text into module 2026-05-23 19:41:38 +08:00
8009887be9 i18n: localize welcome screen 2026-05-23 19:33:21 +08:00
07e47e65c8 i18n: module system event messages 2026-05-23 19:30:11 +08:00
1d8fcea3fa i18n: localize title bar status 2026-05-23 19:21:01 +08:00
aca68824ac i18n: centralize command output text 2026-05-23 19:11:29 +08:00
9159586716 i18n: localize command usage errors 2026-05-23 18:36:44 +08:00
4c8ef99880 i18n: localize modal screen chrome 2026-05-23 18:32:26 +08:00
22ab85acef i18n: localize common command outputs 2026-05-23 18:29:30 +08:00
92123d208d i18n: localize help screen chrome 2026-05-23 18:25:30 +08:00
f535b928d1 i18n: localize command mode guidance 2026-05-23 18:17:53 +08:00
2e69283e5c i18n: add session language command 2026-05-23 18:10:54 +08:00
0c27976763 i18n: select interactive language from locale 2026-05-23 18:06:39 +08:00
39f7f1c7c4 packaging: document homebrew tap path 2026-05-23 17:57:19 +08:00
599cd690b8 packaging: document aur submission path 2026-05-23 17:56:40 +08:00
4c7b72e7a0 packaging: add debian package draft 2026-05-23 17:55:21 +08:00
2490262332 install: verify release binary checksums 2026-05-21 12:58:24 +08:00
7da33951b0 release: harden binary artifact workflow 2026-05-21 12:55:39 +08:00
d819fd5324 ci: run release preflight 2026-05-21 12:52:16 +08:00
a4748cd902 release: add local preflight checks 2026-05-21 12:51:10 +08:00
b4e714ed44 packaging: prepare package manager installs 2026-05-21 12:36:21 +08:00
36dbe8d549 tui: guide first-time users 2026-05-21 12:36:06 +08:00
69ddcd2d95 ssh: use non-deprecated host key generation api 2026-05-21 12:20:41 +08:00
169ba1a150 tui: preserve ansi styling when truncating output 2026-05-21 12:12:14 +08:00
67d21ad0e9 tui: improve history browsing and support guide 2026-05-21 11:57:59 +08:00
87d6572156 chat: whisper inbox with :inbox view + ✉ unread chip (UX-12)
Whispers used to flash on the recipient's terminal and disappear with
the next redraw.  No history, no record, no signal if you weren't
looking.

Now whispers are stored per-recipient in a bounded inbox (16 slots,
FIFO eviction):

  typedef struct { time_t timestamp; char from[]; char content[]; } whisper_t;
  whisper_t whisper_inbox[16];
  int       whisper_inbox_count;
  _Atomic int unread_whispers;

Sender side (:msg / :w):
  - resolves target as before
  - pushes the whisper into target->whisper_inbox under target->io_lock
    (so two simultaneous senders to the same recipient don't tear the
    ring)
  - bumps target->unread_whispers atomically
  - sends a single \a bell + triggers redraw_pending
  - no longer writes whisper text directly to the channel (which used
    to get clobbered by the next redraw)

Recipient side:
  - new :inbox command in COMMAND mode prints the snapshot under
    io_lock, in M7 chat-list style:

      悄悄话 · whispers  · 3
        05-17 13:42  alice: 一会儿要不要喝咖啡
        ...

  - viewing :inbox resets unread_whispers to 0

Title bar (extends UX-11):
  - bright magenta "✉ N" chip alongside the yellow "★ N" mention chip
  - same priority / degradation rules as ★

Whispers remain private — they're never broadcast to the room and
never persisted to messages.log.  The inbox lives only in client_t,
so disconnecting drops it.
2026-05-17 14:35:16 +08:00
ddcecbea81 tui: persistent @mention unread counter in title bar (UX-11)
The bell + brief yellow highlight on the chat line meant that if you
weren't looking at the screen the moment someone @-mentioned you, you
had no way to know.

Now the title bar carries a sticky chip:

    tester · 在线 3 · NORMAL  ★ 2                ? 帮助

- bright yellow "★ N" appears whenever client->unread_mentions > 0
- count is bumped atomically in notify_mentions() for each target
- cleared automatically when the user returns to attention:
  * pressing 'i' in NORMAL to re-enter INSERT mode
  * pressing 'G' in NORMAL to jump to the live tail
- never dropped by the narrow-terminal degradation (UX-6) unless
  every other optional chip has already been shed — it's the highest
  priority signal in the bar

Counter is _Atomic int so the cross-thread bump in notify_mentions
doesn't tear against the local thread's reads / resets.
2026-05-17 14:27:46 +08:00
70718482f3 docs: troubleshooting section for "Connection closed by remote host" (UX-10)
The original UX-10 was "give the client a readable reason on
disconnect" — turns out the libssh server API doesn't let us send
SSH_MSG_USERAUTH_BANNER, ssh_set_banner is GET-only on the linked
versions (0.9.6 on oss, 0.10.6 on ali), and pre-auth rejections
(max_connections / ratelimit / firewall) happen before any SSH
exchange the client could parse.

The realistic improvement is documentation: README now has a
troubleshooting table mapping the generic close to the actual cause
and how to verify (journalctl) + fix.  Also documents the idle
timeout disconnect for completeness.

Server-side stderr already prints rejection reason with the
offending IP, so journalctl gives the admin enough to debug.
2026-05-17 14:24:35 +08:00