nandi/freeqsay-nimpublic Fork 0
fa53aa288dd6ab20305f4fe99766c45c6492dbda
Commits
Clone
git clone https://git.rickub.com/nandi/freeqsay-nim.git
git clone ssh://git@rickub.com/nandi/freeqsay-nim.git

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

README.md · 79 lines · 2.4 KBmarkdown Blame HistoryRaw
freeqsay: Nim port of the Clojure implementation fa53aa2 nandi 9h ago1# freeqsay
2
3Cowsay with your FreeqWorld face. Written in Nim — a port of the
4[Clojure/Jolt implementation](https://gitlab.com/nandithebull/freeqsay), which
5is itself a port of the original TypeScript.
6
7```bash
8freeqsay <handle> <message>
9```
10
11Resolves a Bluesky handle → DID, derives the deterministic `avatar-v1` character,
12and prints a cowsay balloon above truecolor ANSI art.
13
14## Usage
15
16```bash
17freeqsay jay.bsky.team hello from the timeline
18freeqsay @pfrazee.com "ships free software"
19echo "piped in" | freeqsay jay.bsky.team
20
21# wrap width, thought bubble, scale
22freeqsay someone.bsky.social -W 20 short lines
23freeqsay jay.bsky.team --think hmm
24freeqsay jay.bsky.team --scale 3 big face says hi
25
26# raw DID (no network)
27freeqsay did:plc:ewvi7nmzuoqusbcablsm7c4h offline ok
28```
29
30Without a built binary, run it straight from the source tree:
31
32```bash
33nim r -d:ssl src/freeqsay.nim jay.bsky.team hello world
34```
35
36## Library
37
38```nim
39import freeqsay
40
41echo freeqsay("jay.bsky.team", "hello").output
42```
43
44Modules: `freeqsay/say` (balloon + face), `freeqsay/avatar` (traits and the
4516×24 sprite), `freeqsay/ansi` (truecolor half-block rendering), `freeqsay/png`
46(RGBA → PNG), `freeqsay/resolve` (handle → DID), `freeqsay/balloon`,
47`freeqsay/sha256` (SHA-256 / HMAC / HKDF). Importing `freeqsay` re-exports all
48of them.
49
50## Development
51
52```bash
53just build # optimized binary → ./freeqsay
54just test # test suite
55just run <handle> <message> # run from source, no build
56just shot <handle> <message> # gapless termshot png
57just --list # everything else
58```
59
60`nimble build` and `nimble test` work too. `-d:ssl` is set in `config.nims`,
61since handle resolution goes over HTTPS through the stdlib client.
62
63Everything but the HTTP call and JSON parsing is pure Nim with no dependencies:
64SHA-256, HMAC and HKDF live in `freeqsay/sha256`, and the PNG encoder writes
65stored deflate blocks.
66
67## How it works
68
69```
70handle → resolveHandle → did
71did → HKDF-SHA256(avatar-v1) → traits → 16×24 sprite → ANSI
72message → cowsay balloon
73```
74
75`fixtures/avatar-conformance.json` pins the cross-implementation contract:
76canonical seed, traits, and a sprite hash over all four facings. The suite
77replays it, so this port derives byte-identical characters to the Clojure and
78TypeScript implementations — including the sfc32 PRNG, reproduced on `uint32`
79lanes so trait selection matches the JavaScript original bit for bit.