From c5bf8b04079c086fa75d0f2d16030fbc9e865192 Mon Sep 17 00:00:00 2001
From: th
Date: Sun, 12 Apr 2026 18:00:06 +0200
Subject: [PATCH] docs: update all READMEs for v1.1.0
Add Electron desktop app section, document all 8 plugins, update
features list (assets, super-buckets, find/replace, arrow nav, PDF
upload), fix relay docs (chat shipped, not future), add missing API
endpoints, correct electron data storage paths and php-bin fetch info.
Co-Authored-By: Claude Opus 4.6 (1M context)
---
README.md | 61 +++++++++++++++++++++++++++++++++-----
electron/README.md | 9 ++++--
electron/php-bin/README.md | 18 +++++------
relay/README.md | 27 +++++++++--------
4 files changed, 84 insertions(+), 31 deletions(-)
diff --git a/README.md b/README.md
index 7eba899..8c2a891 100644
--- a/README.md
+++ b/README.md
@@ -110,10 +110,23 @@ hyprcrd/
│ │ └── vendor/ # marked.js, DOMPurify
│ ├── plugins/ # Optional, drop-in plugin folders
│ │ ├── canvas/ # ASCII art canvas editor
+│ │ ├── chat/ # Encrypted relay chat
+│ │ ├── collab-buckets/ # Collaborative bucket sync
+│ │ ├── email/ # Email overlay
+│ │ ├── gitea/ # Gitea issue integration
+│ │ ├── logseq-import/ # Logseq markdown importer
+│ │ ├── slideshow/ # Presentation mode
│ │ └── tests/ # UI + state test runner
│ └── uploads/ # User media (writable)
-├── relay/ # Relay service (mobile inbox + card sharing)
-│ ├── index.php # Single-file API + Mobile UI
+├── electron/ # Electron desktop app wrapper
+│ ├── main.js # Spawns PHP, creates BrowserWindow
+│ ├── router.php # PHP built-in server router
+│ ├── fetch-php.sh # Downloads static PHP binaries
+│ └── php-bin/ # Platform-specific PHP binaries
+├── relay/ # Relay service (multi-tenant messaging + collab)
+│ ├── index.php # Entry point + API dispatch
+│ ├── inc/ # Backend modules (bootstrap, crypto, auth, routes)
+│ ├── ui/ # Frontend (layout.php, style.css, app.js)
│ ├── .htaccess # URL rewriting + data protection
│ ├── Dockerfile
│ └── dist.sh # Build relay distribution ZIP
@@ -128,7 +141,7 @@ hyprcrd/
- **Tags** written as `#tagname` or hierarchical `#parent/child` in card body, extracted automatically
- **Markdown** with `[[Card Title]]` wiki-links, ```` ```gallery ```` image galleries, ```` ```tree ```` list views, ```` ```ascii ```` art canvas (via canvas plugin)
- **Search** combining text and `#tag` filters (e.g. `#project meeting notes`)
-- **Image gallery** with orphan detection and fullscreen viewer
+- **Assets gallery** (images, audio, PDFs) with orphan detection and fullscreen viewer
- **Split view** showing tag-related and content-related cards
- **Import/Export** as JSON+media ZIP or Obsidian/Logseq-compatible markdown vault
- **Drag & drop** card reordering and grouping
@@ -141,7 +154,14 @@ hyprcrd/
- **Notification banner** for upcoming events, birthdays, overdue tasks
- **Board split view** with side-by-side preview
- **Superview** compact multi-column list with hover cards
-- **Keyboard shortcuts**: `Ctrl+K` search, `F1` help, `Shift+scroll` zoom, arrow keys in autocomplete
+- **Super-buckets** — nest buckets one level deep with a dropdown for children
+- **Card groups** — drag-to-group, join multiple cards, dissolve
+- **Context menu** — color, tags, copy text, mark done, join cards, make ticket (gitea)
+- **Find & replace** — in-card (Ctrl+H) and across all cards (Ctrl+Shift+H via search)
+- **Arrow key navigation** on the board with Enter to open
+- **PDF upload** in the editor toolbar
+- **Keyboard shortcuts**: `Ctrl+K` search, `F1` help, `?` shortcut reference, arrow keys, 1–9 bucket switch
+- **Electron desktop app** — standalone AppImage/DMG/NSIS with bundled PHP, no server needed
## Plugins
@@ -150,7 +170,13 @@ hyprcrd has a drop-in plugin system. A plugin is just a folder under `public/plu
### Bundled plugins
- **`canvas/`** — ASCII art canvas editor. Adds a toolbar button + ` ```ascii ` fenced block. Draw with brush, line, rectangle, ellipse, fill, and text tools using a monospace character grid.
-- **`tests/`** — UI + state test runner (40+ test files). Loaded only when `?test` is in the URL or `Ctrl+Shift+T` is pressed, so production users pay no cost for it.
+- **`chat/`** — Encrypted chat between relay tenants. Footer flyout with delivery + read receipts.
+- **`collab-buckets/`** — Collaborative buckets shared between relay tenants with exclusive card locking and E2E encrypted sync.
+- **`email/`** — Email overlay (toggled with `M` key).
+- **`gitea/`** — Gitea integration: create issues from cards, link to repos.
+- **`slideshow/`** — Slideshow presentation mode for cards with `slide-image` blocks.
+- **`logseq-import/`** — Import Logseq markdown journals and pages.
+- **`tests/`** — UI + state test runner (40+ test files). Loaded only when `Ctrl+Shift+Alt+T` is pressed, so production users pay no cost for it.
### Plugin layout
@@ -417,9 +443,8 @@ Starts hyprcrd on `http://localhost:8088` and the relay on `http://localhost:808
master key lives outside the DB in a chmod-600 file
- **24-hour ephemeral**: messages and attachments auto-delete after a
day. Cards extracted in hyprcrd are the long-term store
-- **Future: end-to-end encrypted chat** between tenants is planned and
- will require per-pair key exchange — see `relay/README.md` for the
- roadmap
+- **Encrypted chat**: tenant-to-tenant chat with delivery + read receipts
+ (via chat plugin). Per-pair E2E key exchange is on the roadmap
### Relay Security
@@ -451,6 +476,26 @@ your next visit. You'll need to:
The old `relay_key` was bcrypt-hashed and cannot be recovered, so all
client secrets need to be reissued.
+## Electron Desktop App
+
+hyprcrd can run as a standalone desktop app via Electron — no web server needed.
+
+```bash
+cd electron
+./fetch-php.sh # download static PHP binary (~20MB)
+npm install
+npm start # dev mode
+npm run dist # build AppImage / DMG / NSIS
+```
+
+The app bundles a static PHP binary per platform and stores user data (database + uploads) outside the app bundle:
+
+- **Linux**: `~/.config/hyprcrd/data/`
+- **macOS**: `~/Library/Application Support/hyprcrd/data/`
+- **Windows**: `%APPDATA%/hyprcrd/data/`
+
+See [`electron/README.md`](electron/README.md) for details.
+
## Rebuilding Tailwind CSS
After changing Tailwind utility classes in HTML or JS files:
diff --git a/electron/README.md b/electron/README.md
index 174ed0c..be7d481 100644
--- a/electron/README.md
+++ b/electron/README.md
@@ -10,8 +10,13 @@ per platform so users don't need PHP installed.
3. A `BrowserWindow` loads `http://127.0.0.1:/`
4. On quit, the PHP process is killed cleanly
-Data is stored in `data/hyprcrd.db` (SQLite), relative to the project root
-(dev) or inside the app's `resources/` directory (packaged).
+User data (database + uploads) is stored **outside** the app bundle so it
+survives updates:
+
+- **Dev**: `electron/appdata/`
+- **Linux**: `~/.config/hyprcrd/data/`
+- **macOS**: `~/Library/Application Support/hyprcrd/data/`
+- **Windows**: `%APPDATA%/hyprcrd/data/`
## Development
diff --git a/electron/php-bin/README.md b/electron/php-bin/README.md
index 6c745b4..1c8ffb7 100644
--- a/electron/php-bin/README.md
+++ b/electron/php-bin/README.md
@@ -6,17 +6,17 @@ installation.
## Download
-Get static builds from https://github.com/crazywhalecc/static-php-cli/releases
-(look for `php-8.3-*-cli` assets). Required extensions: pdo_sqlite, zip, session.
+Get static builds from https://dl.static-php.dev/static-php-cli/common/
+(look for `php-8.3.*-cli-*` files). Required extensions: pdo_sqlite, zip, session.
linux/php — x86_64 Linux ELF binary
- darwin/php — macOS universal binary (arm64 + x86_64)
- win32/php.exe — Windows PE binary
+ darwin/php — macOS aarch64 binary
+ win32/php.exe — Windows PE binary (not available from static-php-cli; use windows.php.net)
-## Quick fetch (Linux example)
+## Quick fetch
- curl -L -o linux/php \
- "https://dl.static-php.dev/static-php-cli/common/php-8.3.23-cli-linux-x86_64.tar.gz" \
- && tar -xzf linux/php -C linux/ && rm linux/php.tar.gz
+Use the included script from the `electron/` directory:
-Make sure the binary is executable: `chmod +x linux/php`
+ ./fetch-php.sh
+
+This auto-detects the latest PHP 8.3 version and downloads Linux + macOS binaries.
diff --git a/relay/README.md b/relay/README.md
index 360594f..d4b44db 100644
--- a/relay/README.md
+++ b/relay/README.md
@@ -2,9 +2,8 @@
A self-hosted **multi-tenant** message relay for hyprcrd. Multiple users
share one relay instance; each one has their own login, their own client
-encryption secret, and their own inbox. Cards (and in the future:
-encrypted chat messages) can be sent **between tenants** on the same
-relay.
+encryption secret, and their own inbox. Cards and encrypted chat
+messages can be sent **between tenants** on the same relay.
The relay is a single-file PHP app — drop the directory into any PHP
webspace and it works.
@@ -55,9 +54,9 @@ The admin only ever touches secrets #1 and #3. The user only ever touches secret
The relay **does** see plaintext briefly during the cross-tenant hop
(steps 2–3 and 5–6). This is the same trust model as email: you trust
-the relay operator. **Strict end-to-end encryption** for the planned
-chat feature is on the roadmap and will require a per-pair key exchange
-(Curve25519/ECDH) — this is documented as future work in `index.php`.
+the relay operator. Chat between tenants is shipped (via the chat
+plugin with delivery + read receipts). **Strict end-to-end encryption**
+with per-pair key exchange (Curve25519/ECDH) is on the roadmap.
For at-rest data, all sensitive values are encrypted with the master
key, so a stolen DB without the master key file gives an attacker
@@ -155,7 +154,7 @@ incoming messages.
### 6. Send a card to another tenant
-(currently in the relay UI; hyprcrd-side recipient picker is coming)
+(in the relay UI compose tab)
In the relay UI **compose** tab:
- Pick a recipient from the dropdown (defaults to yourself)
@@ -166,8 +165,7 @@ The recipient will see it on their next hyprcrd poll, materialized as a
card in their board.
You can also right-click a card in hyprcrd and pick **push to relay** —
-this currently sends to your own inbox; recipient picker on the hyprcrd
-side is on the TODO.
+this sends to your own inbox (or pick a recipient in the relay UI).
## Data lifetime
@@ -226,6 +224,10 @@ All endpoints under `/api/`. JSON in/out.
| GET | `/api/me` | — | Current tenant info |
| GET | `/api/tenants` | — | List of all usernames (for recipient picker) |
| POST | `/api/messages` | `{title, body, recipient?}` | UI compose path: server encrypts with inter-tenant key |
+| GET | `/api/messages/inbox` | — | Read own inbox messages (decrypted for display) |
+| DELETE | `/api/messages/{id}` | — | Delete a message from own inbox |
+| GET | `/api/chat/sent` | — | Sent chat messages with delivery/read status |
+| POST | `/api/chat/seen` | `{ids: [...]}` | Mark chat messages as seen (read receipts) |
### Admin only (session + `is_admin`)
@@ -302,8 +304,7 @@ use the same code path.
- A compromised relay machine = compromised messages. Use HTTPS, keep
PHP up to date, restrict shell access.
-**Future work for stronger guarantees** (planned for the encrypted chat
-feature):
+**Future work for stronger guarantees** (roadmap for strict E2E):
- Per-tenant Curve25519 key pair stored in the DB (public key plus
master-key-encrypted private key, or even private key never on the
server)
@@ -522,7 +523,9 @@ relay/
│ └── routes/
│ ├── public.php # /api/status, /setup, /login, /logout, /me
│ ├── admin.php # /api/users CRUD, /api/tenants directory
-│ └── messages.php # /api/messages, /api/attachments, cross-tenant routing
+│ ├── messages.php # /api/messages, /api/attachments, cross-tenant routing
+│ ├── chat.php # /api/chat/sent, /api/chat/seen (read receipts)
+│ └── collab-buckets.php # /api/collab-buckets CRUD + card sync
├── ui/
│ ├── layout.php # HTML shell + view containers
│ ├── style.css # all CSS (including responsive media queries)
|