nandi/frqpublic Fork 0
2d4a3773cf9c03545f4c8b7088af9f3c74a4ed4a
Commits
Clone
git clone https://git.rickub.com/nandi/frq.git
git clone ssh://git@rickub.com/nandi/frq.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

README.md · 104 lines · 4.4 KBmarkdown Blame HistoryRaw
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago1# frq
2
3A **[freeq](https://github.com/codegod100/freeq)** client written in
4**[jolt](https://github.com/jolt-lang/jolt)**, as
5[glimmer](https://github.com/jolt-lang/glimmer) components painted by
6**[Vidya](https://tangled.org/nandi.uk/vidya)**/egui.
7
8It is a proof of concept port of [sleek](../sleek), which is the same client in
9Rust against egui directly. The screens are sleek's — connect, chats, chat,
10discover, settings, under a tab bar — but each is hiccup over glimmer's widget
11tags rather than immediate-mode drawing code, and state lives in ratoms instead
12of an `AppState` struct.
13
14```
Sign in with Bluesky OAuth, through freeq's broker 2d4a377 nandi 20d ago15src/frq/atproto.jolt handle → DID → PDS → session, and the SASL payloads
16src/frq/oauth.jolt the broker flow: login URL, loopback capture, /session
Sign in with a Bluesky identity 5192124 nandi 20d ago17src/frq/irc.jolt IRC over TLS or TCP: parser, reader thread, SASL, PRIVMSG
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago18src/frq/state.jolt the ratoms every screen reads, and `apply-msg!`
19src/frq/app.jolt the screens
20```
21
22## Running
23
24`libvidya` from Vidya's Rust/egui backend, then the app:
25
26```bash
27just lib
28just run
29```
30
31`just run` is `jolt -M:frq` with `LD_LIBRARY_PATH` pointed at the built
32library. It connects to `irc.freeq.at:6697` over TLS and joins `#test`. Untick
33TLS on the connect screen (or point it at `127.0.0.1`) for a local server's
34plain listener:
35
36```bash
37cargo run --release --bin freeq-server # in the freeq checkout
38```
39
Sign in with a Bluesky identity 5192124 nandi 20d ago40## Signing in
41
Sign in with Bluesky OAuth, through freeq's broker 2d4a377 nandi 20d ago42Three modes on the connect screen.
Sign in with a Bluesky identity 5192124 nandi 20d ago43
Sign in with Bluesky OAuth, through freeq's broker 2d4a377 nandi 20d ago44**Bluesky** (OAuth, the default way in) follows sleek's flow: frq binds a
45loopback port, puts it in `return_to`, and opens
46`auth.freeq.at/auth/login?handle=…`. The broker runs the OAuth dance with the
47PDS and redirects back to that port with the handoff in the URL *fragment*, so
48it never reaches a server as a query string. The page frq serves there has one
49job: POST the fragment back to itself. What comes back is a single-use SASL
50`web-token` and a durable `broker_token`; later connections mint a fresh token
51from the durable one at `/session` and skip the browser.
Sign in with a Bluesky identity 5192124 nandi 20d ago52
Sign in with Bluesky OAuth, through freeq's broker 2d4a377 nandi 20d ago53**App password** signs in without a browser, straight to the user's own PDS:
54`resolveHandle` → DID → PDS from the DID document → `createSession`. The
55password goes to that PDS and nowhere else, is never written to disk, and is
56dropped once the session exists.
Sign in with a Bluesky identity 5192124 nandi 20d ago57
Sign in with Bluesky OAuth, through freeq's broker 2d4a377 nandi 20d ago58Either way freeq sees only a token. The SASL mechanism is
59`ATPROTO-CHALLENGE` in both cases — `method: "web-token"`, which the server
60resolves through its own token store, or `method: "pds-session"` with the
61server's nonce echoed back so the token cannot be replayed elsewhere.
62
63A refused sign-in is reported and the connection carries on as a guest.
Sign in with a Bluesky identity 5192124 nandi 20d ago64
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago65## Android
66
67An APK with two shared libraries and no Java: `libvidya.so` (vidya's Rust/egui
68C ABI, which owns the event loop as the NativeActivity's own library) and
69`libjoltapp.so` (frq compiled to a Chez boot image). Both native halves come
70from the vidya checkout; only the boot image is frq's.
71
72```bash
73./android/build-apk.sh run # build, install, launch on a connected device
74./android/build-apk.sh log # logcat, filtered
75```
76
77Needs what vidya's Android build needs — SDK, NDK r29, and a cross-built Chez
78in `~/.cache/vidya-chez-android`.
79
80TLS does not work there: jolt reaches OpenSSL through the dynamic loader, and
81Android has no public `libssl` to load. The connect screen falls back to the
82plain `:6667` listener on its own, which is why the plain transport is the raw
83`socket`/`connect`/`send`/`recv` calls rather than jolt's `java.net.Socket`
84surface — that surface does not work on Android either, while the syscalls do.
85
86## What the PoC covers
87
88* TLS (`:6697`, via jolt.mvn-http's OpenSSL bindings) or plain TCP (`:6667`)
89* Guest connect (`NICK`/`USER`), `001` welcome, `PING`/`PONG` keepalive
90* Auto-joins `#test` on `irc.freeq.at`
91* Join channels, channel buffers with unread counts, send and receive `PRIVMSG`
92* Join/part notices, DMs bucketed under the sender's nick
93* Discover list, search over buffers, disconnect
94
95## Limits
96
97* **TLS and plain TCP only** — no WebSocket, no iroh. On Android, plain only.
Sign in with Bluesky OAuth, through freeq's broker 2d4a377 nandi 20d ago98* **No `did:key` signing, no credential gates, no E2EE.** Sign-in of either
99 kind needs TLS, so it is desktop-only — the Android build connects as a
100 guest.
101* **The broker token lives in memory.** Nothing is persisted, so a restart
102 means another trip through the browser.
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago103* **No scrollback trimming, avatars, reactions, threads, or calls.**
104* Message lists are keyed vboxes; glimmer-vidya has no `:listbox` yet.