Skip to content

Releases: ninepointlabs/omostrich

Omostrich 0.3.3

Choose a tag to compare

@ninepointlabs ninepointlabs released this 27 Oct 13:47
453211b

What's fixed

  • The daemon no longer crashes when desktop notifications can't run. If notify-send is missing or fails, the failure is logged once (error code only) and the signer keeps running.
  • "Always allow" for signing now covers one event kind, not all of them. The button reads, for example, "Always allow sign kind 4 (DM)", and Authorized apps lists each app's grants per kind.
  • Encrypt and decrypt prompts show who's on the other end. Each request shows the peer (a shortened npub, marked "(you)" for yourself) and whether you're encrypting to or decrypting from them. Encrypt requests also show a short plaintext preview. A kind 4 sign shows its recipient, and DM ciphertext is no longer previewed. None of this is logged.
  • Smaller fixes
    • Kind 14 and kind 1059 sign requests show a warning and can only be approved once, never remembered.
    • get_public_key is answered without a prompt only for an app that connected this run or is remembered. Anyone else gets a prompt.
    • Gift-wrap (kind 1059) notifications look back 2 days, and unlocking no longer fires a burst of old ones.

Upgrading from 0.3.2 or earlier

Old blanket sign_event grants meant "sign any kind", and there's no way to tell which kind you meant, so they're removed on the first start after the upgrade. The app and its other grants stay, daemon.log names each affected app, and the app asks again once for each kind it needs.

Install / update

cd ~/Projects/omostrich
git pull
npm ci
./install-daemon.sh
./install-plugin.sh
systemctl --user restart omostrich   # the running daemon keeps the old code until restarted

Full Changelog: v0.3.2...v0.3.3

Omostrich 0.3.2

Choose a tag to compare

@ninepointlabs ninepointlabs released this 27 Oct 13:33
b71cf7e

What's fixed

  • The cached profile picture is now stripped to pixels only. 0.3.1 limited the picture's download size and pixel dimensions, but the cached file could still carry compressed metadata chunks (such as PNG zTXt/iTXt/iCCP). Qt and libpng expand those while reading the header, so a small hostile picture could push the panel to several GB of memory. The daemon now rewrites the downloaded picture to an allowlist of the parts needed to draw it, with no re-encoding and no new dependency. Reported in marketplace review #12494.
    • PNG: keeps IHDR, PLTE, tRNS, gAMA, cHRM, sRGB, IDAT and IEND, and drops every other ancillary chunk. An unknown critical chunk is refused.
    • JPEG: keeps the coding segments, JFIF and Adobe, and drops COM, EXIF, ICC, XMP and Photoshop data.
    • GIF: keeps the first frame only, with no comment or application extensions.
    • WebP: keeps the image data (plus alpha) and drops ICC, EXIF, XMP and unknown chunks. Animated WebP is refused, so the placeholder shows.
    • Bytes after the end of the image are dropped for every format.
  • A picture cached by 0.3.1 is ignored on startup and fetched again, so the cache only ever holds the stripped copy.

Install / update

cd ~/Projects/omostrich
git pull
npm ci
./install-daemon.sh
./install-plugin.sh
systemctl --user restart omostrich   # the running daemon keeps the old code until restarted

Full Changelog: v0.3.1...v0.3.2

Omostrich 0.3.1

Choose a tag to compare

@ninepointlabs ninepointlabs released this 22 Oct 14:27
4875658

What's fixed

  • The profile picture is now loaded safely. The panel no longer hands the URL from your Nostr profile to Qt. Instead, while unlocked, the daemon downloads it with limits:
    • a 10 s timeout and a 1 MB cap
    • PNG, JPEG, GIF or WebP only, checked by both content type and file signature
    • at most 2048×2048 pixels
    • It keeps a local copy in ~/.local/share/omostrich/, and the panel shows that copy at a small decode size. A picture that fails a check shows the placeholder (the reason is in daemon.log). Reported in marketplace review #12494.
  • Attachment previews show your local file, not the uploaded Blossom URL. The Blossom server's reply is capped at 64 KB, and every image in the panel has a bounded decode size.

Install / update

cd ~/Projects/omostrich
git pull
npm ci
./install-daemon.sh
./install-plugin.sh
systemctl --user restart omostrich   # the running daemon keeps the old code until restarted

Full Changelog: v0.3.0...v0.3.1

Omostrich 0.3.0

Choose a tag to compare

@ninepointlabs ninepointlabs released this 21 Oct 14:29

What's new

  • Log in from a phone by QR code. Under Remote signing, QR (next to Copy) shows your bunker:// connection string as a QR code. Scan it from a phone app such as Amethyst (login with a bunker / remote signer).
    • The string is public (your public key and NIP-46 relays, no secret).
    • The app's connect request then shows up for approval like any other.
  • Connect apps that show their own QR code (nostrconnect://). Scan QR reads the app's code with your laptop camera; Paste code takes a copied nostrconnect:// string.
    • The daemon checks the code and answers the app on the relays it names, which completes the login. The app is added to Authorized apps under its own name, and the daemon keeps listening on its relays after every unlock until you revoke it.
    • The camera preview is mirrored and draws a guide box. Hold the code inside the box, about 25–35 cm away. Frames are enlarged and sharpened before decoding, because laptop webcams are fixed-focus and these codes are dense.
    • Frames go straight to the decoder and are never saved. The camera turns off when a code is read, when you cancel or close the preview, or after two minutes.
    • Reading a phone's code with the laptop camera can still be unreliable; the bunker QR above is the dependable direction.
  • Approve all / Deny all. When several NIP-46 requests are waiting (Amethyst signs a burst of events right after login), settle every request on screen at once, each just this once. A request that arrives after you click still waits for its own answer.
  • Better NIP-46 logging. daemon.log now records each request's method (such as sign_event) and whether the reply was ok or which error it carried. Never request content or what was sent back.
  • Fixes
    • Always allow no longer overwrites an app's saved relays or name.
    • A request delivered twice is handled once.
  • The About page's privacy statement covers camera use, the relays a scanned app names, and the new log details.

New requirements

  • qrencode for the bunker QR.
  • ffmpeg (includes ffplay) and zbar for Scan QR.

Everything else works without them:

sudo pacman -S qrencode ffmpeg zbar

Install / update

cd ~/Projects/omostrich
git pull
npm ci
./install-daemon.sh
./install-plugin.sh
systemctl --user restart omostrich   # the running daemon keeps the old code until restarted

Full Changelog: v0.2.1...v0.3.0

Omostrich 0.2.1

Choose a tag to compare

@ninepointlabs ninepointlabs released this 18 Oct 03:25

What's new

  • Control from your tailnet, with a token. When Tailscale is up, the signer daemon also listens on TCP port 4737 on this computer's Tailscale address, for your own devices such as a phone.
    • The first line a client sends must be {"auth": "<token>"}, using the token in ~/.local/state/omarchy/omostrich/tcp-token. The file is created on first start and is readable only by you.
    • Until a client authenticates, nothing is run. A wrong token, any command, more than 4 KB or 10 seconds of silence closes the connection.
    • With the token, a device can do everything the local socket can, including signing and posting while unlocked, so treat the token like a password.
    • To issue a new token, delete the file and run systemctl --user restart omostrich.
  • NIP-46 requests are heard on every bunker relay. The daemon now listens on your NIP-46 relays as well as your posting relays. Before, a request sent through a bunker relay that wasn't also a posting relay was never heard.
  • NIP-46 requests are logged: the sender (first 16 characters of the public key) and the relay, never the content.
  • The About page's privacy statement describes the tailnet listener, the token and the new log lines.

Local clients (omostrich-ctl, the MCP server, the bar panel) use the Unix socket and need no changes.

Install / update

cd ~/Projects/omostrich
git pull
npm ci
./install-daemon.sh
./install-plugin.sh
systemctl --user restart omostrich   # the running daemon keeps the old code until restarted

Full Changelog: v0.2.0...v0.2.1

Omostrich 0.2.0

Choose a tag to compare

@ninepointlabs ninepointlabs released this 17 Oct 23:03
4d2af6c

First tagged release of Omostrich: a local Nostr signer and note composer for Omarchy. Unlock your locally encrypted key from the bar, post notes, and approve NIP-46 signing requests from other Nostr apps.

About screen

Open it with the info button at the top right of the panel header. Back or Esc returns. It works while the vault is locked and never talks to the daemon.

It shows the version, Made by Nine Point Labs, the created date, the MIT license (with the full text), support at help@ninepointlabs.com (Email and Copy buttons), a privacy statement and the Quickshell and Qt versions.

Privacy, in short:

  • Your key: encrypted in a local vault readable only by you, decrypted only in the daemon's memory while unlocked, and never sent anywhere.
  • Relays: only after unlock, the daemon connects to the relays you configure and to NDK's default relay-list relays.
  • Public posts: notes you publish are public.
  • Log: the daemon log records each signature and post, never the key or passphrase.

The full statement on the About page names every host.

Also: the copyright holder and plugin author are now "Nine Point Labs", and install-plugin.sh now also deploys *.js and LICENSE.

Install / update

git clone https://github.com/ninepointlabs/omostrich ~/Projects/omostrich
cd ~/Projects/omostrich
npm ci
./install-daemon.sh
./install-plugin.sh