71 lines
4.7 KiB
Markdown
71 lines
4.7 KiB
Markdown
# carrier
|
|
|
|
A minimalist desktop client for [Smol Mail](../smolmail): one compact window — the list above, the article below — built on [fumi-core](../fumi), the reference CLI's own library, with a [Relm4](https://relm4.org) (GTK4) UI built from libadwaita's own widgets, so it follows the user's theme and accent colour. One 32-byte seed is the only secret; mail stays sealed at rest and opens on demand.
|
|
|
|
## What it does
|
|
|
|
- Create or restore an identity from a seed, shown once at creation time.
|
|
- Pin a server's key — paste the operator's, or connect and pin what it presents — then register a username or recall an existing address.
|
|
- Fetch (with cancel), read, reply and send sealed mail; the inbox, the requests tier and sent copies each keep their own folder.
|
|
- Composes closed by any sidebar trip are stashed as drafts — kept beside the store, reopened from a folder that appears only once one exists; Cancel is the only way to throw one away.
|
|
- Custom `Key: value` frontmatter rows when writing: one line per header under the subject, validated against the frontmatter rules — the client's own fields (subject, reply-to, in-reply-to, accept) can't be shadowed, and rows survive a stash as part of the draft. Received mail shows the sender's own fields in the message detail, between the meta line and the body; replying to such a mail asks whether to carry copies of the fields into the reply, where they stay editable.
|
|
- Accept or block a requester when their mail carried a self-certifying reply address; accept tokens attach to accepted contacts automatically.
|
|
- Contacts with verified/tofu marks and smol:// import; your own identity opens in the same detail view, its address in the header bar with a QR share beside it, key, fingerprint and URI below.
|
|
- Key rotation with a confirm-first step, server pin management, a network timeout, gsmol backup export/import that never contains the seed, and a factory reset that erases the local files and returns to onboarding.
|
|
|
|
## Layout
|
|
|
|
```
|
|
src/main.rs config directory, demo seeding, launch
|
|
src/app.rs state and update; blocking calls run on the worker pool
|
|
src/view.rs the Relm4 component: widgets, the op adapter, the re-render
|
|
src/ops.rs fumi-core calls, key/read-mark files, and the offline tests
|
|
```
|
|
|
|
## State
|
|
|
|
Everything lives under `$XDG_CONFIG_HOME/carrier` (default `~/.config/carrier`): `carrier.key` is the master seed, written 0600; `carrier.db` is fumi-core's sealed store; `read.txt` is carrier's own read marks, one hex id per line.
|
|
|
|
## Run and verify
|
|
|
|
```
|
|
devbox run run # build release and launch
|
|
devbox run check # fmt --check, build, tests
|
|
devbox run test # tests only
|
|
```
|
|
|
|
The tests run offline against an in-memory store: seed and key parsing, a sealed envelope listed and opened end to end, contact import, a full backup round-trip, pin labels and the date formatter. `scripts/devbox-libs.sh` puts the GUI stack's runtime libraries (wayland, xkbcommon, EGL, vulkan) on the library path inside the devbox shell — they are dlopened, so nothing that links the binary can provide them.
|
|
|
|
## Status
|
|
|
|
Work in progress: the UI is unexercised against a live server — the store, crypto and address paths are covered by tests, the network flows (register, fetch, send, rotate) are wired to fumi-core's operations but only smoke-tested as far as launching the window.
|
|
|
|
## Packaging
|
|
|
|
`devbox run package` builds and installs the app as a Flatpak from
|
|
`com.randogoth.carrier.json` — the binary, the desktop file, the metainfo and
|
|
the icon all come from the repo, and the tooling (`flatpak`, `flatpak-builder`,
|
|
`appstreamcli`) lives in the devbox environment. The flatpak runtime is the one
|
|
dependency outside devbox; install it once:
|
|
|
|
flatpak install --user flathub org.gnome.Sdk//51 org.freedesktop.Sdk.Extension.rust-stable//26.08
|
|
|
|
The result is installed into the user flatpak and runs as
|
|
`flatpak run com.randogoth.carrier`. Inside the sandbox the app keeps its
|
|
config under `~/.var/app/com.randogoth.carrier/config/carrier`, so a flatpak
|
|
install starts with a fresh identity rather than the dev build's account.
|
|
|
|
### Windows
|
|
|
|
Install MSYS2 (`winget install MSYS2.MSYS2`), open the **MSYS2 MINGW64**
|
|
shell, and run the one-command script from the carrier checkout:
|
|
|
|
git clone ssh://git@code.randogoth.com:2222/randogoth/carrier.git
|
|
cd carrier && windows/setup.sh
|
|
|
|
`windows/setup.sh` installs the GTK and Rust stack into MSYS2, clones fumi
|
|
next to carrier if it is missing, builds, and bundles carrier.exe with the
|
|
GTK runtime into `dist/` and a zip — the complete Windows distribution. The
|
|
app keeps its config in `%APPDATA%\carrier`. If MSYS2 updates its core
|
|
mid-run the shell may close; rerun the script and it continues. Cloning
|
|
over SSH needs the key in `~/.ssh` inside the MSYS2 home.
|