client-core: SSE framing, REST client and event stream

Adds sse.rs (a pure port of Sse.kt's frame parser), api.rs (a Transport
trait plus a ureq-backed implementation and an ApiClient covering the
session lifecycle: list/read, message/unqueue/answer,
interrupt/stop/start, title/cwd/model/permission-mode/notify,
command/compact, delete, and a transcript page), and event_stream.rs
(follow_session_events, mirroring EventStream.kt's reset/event split).

ureq rather than reqwest: server/ already depends on it for its own
outbound HTTPS, this stays blocking like Api.kt's HttpURLConnection
calls with no async runtime to carry, and its own PEM cert support
means no extra rustls/rustls-pemfile dependency to pin. Network I/O
sits behind Transport so ApiClient and follow_session_events are
tested with fakes, no server involved.

Not yet covered, tracked in CLIENT_CORE.md: setups, the file explorer,
usage, models, and attachments/import.

cargo test (78 passed), clippy --all-targets and fmt clean.

Co-Authored-By: Claude Sonnet <noreply@anthropic.com>
This commit is contained in:
irisandClaude Sonnet committed 2026-09-04 22:57:50 -04:00
1 parent 26163b25b2
commit e8dbcaa7db
6 files changed
+809 -17

No files matched your search

-6
View File
@@ -27,12 +27,6 @@ serde_json = { version = "1", features = ["float_roundtrip"] }
# no need of an async runtime, and RUST.md's brief for this port is
# "lightweight" throughout.
ureq = { version = "3", features = ["json"] }
# Verifying the server's pinned self-signed leaf against the CA `wg-app-link`
# mints, the same way `ServerConfig.kt`'s `applyPinnedTls` does. rustls
# rather than native-tls because ureq is already rustls-backed here and the
# rest of this project's TLS goes through rustls too.
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12"] }
rustls-pemfile = "2"
[dev-dependencies]
tempfile = "3"