Without an initial flush(), the JVM HttpServer buffers all
output until the first flush() in the 15-second keep-alive loop.
Clients with shorter timeouts (e.g. 10 s) abort before receiving
any data.
Add a flush() call directly after creating ServerSentEventSender,
before the wait loop, so the HTTP 200 response and headers reach the
client immediately upon connection.
Adds regression test SseInitialFlushTest that verifies at least one
byte arrives within 2 seconds of connecting to GET /api/v1/events.
When filling or updating a V2 group, profile keys were copied from
DecryptedGroup.members into the local profile store but not from
requestingMembers. Admins who never had a prior session with a user in
the join queue then lacked profile keys and could not decrypt profiles
(e.g. for listContacts).
Also process DecryptedRequestingMember entries the same way as full
members, using DecryptedMember / DecryptedRequestingMember types so the
lib module does not require a direct protobuf dependency.
Made-with: Cursor
Adds a read-only query returning the most recent rate-limit state
observed from send results. Callers can check whether the account is
currently rate-limited, how long until retry, and whether a captcha
challenge is required — without having to trigger a send and inspect
the response, and without having to reconstruct state themselves.
Useful for:
- Admin UIs that want to display current rate-limit state on load
- Monitoring/alerting (poll for active rate limits)
- Clients that restart and would otherwise lose tracked state
The status is tracked in-memory on the Manager: updated whenever a
SendMessageResult reports a rate-limit failure, cleared after a
successful captcha submission, and auto-expires when the retry-after
window elapses (getRateLimitStatus returns active=false once the
current time is past expiresAtEpochSeconds).
JSON-RPC response shape:
{
"active": bool,
"proofRequired": bool,
"retryAfterSeconds": long, // omitted if not active
"challengeToken": string, // omitted unless proofRequired
"expiresAtEpochSeconds": long // omitted if not active
}
D-Bus is not updated to expose this state; DbusManagerImpl returns
inactive as a stub since D-Bus clients already observe rate-limit state
via send results.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add distinct JSON-RPC error code for captcha rejection
Previously submitRateLimitChallenge mapped CaptchaRejectedException to
the generic USER_ERROR code (-1), making it indistinguishable from any
other user error (bad params, unknown command, etc.).
Introduce CaptchaRejectedErrorException and wire it to a new error code
(-6 / CAPTCHA_REJECTED_ERROR) throughout the JSON-RPC layer. Callers can
now reliably distinguish a rejected captcha token (user must obtain a
fresh token) from a network failure (transient, worth retrying) or a
generic argument error.
The CLI exit code for this path becomes 6, consistent with the existing
per-error-type exit code convention.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add exit code 6 to man page
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>