diff --git a/CHECKPOINT-encryption.md b/CHECKPOINT-encryption.md index f957c83..633fa80 100644 --- a/CHECKPOINT-encryption.md +++ b/CHECKPOINT-encryption.md @@ -69,12 +69,53 @@ - Live confirmation of the backfill rename: pair/keep a fresh Amber account with no kind-0, publish kind-0 from Amber, confirm the Keynctr row renames itself within ~5 min without restarting the app. -- Step 4 permissions UI follow-ups, Step 5 KDF, Step 7 rename/hygiene - (unchanged from previous checkpoint). -- `package.json` `homepage` still points at github.com/avi/Keynctr (Step 7). +- Step 4 permissions UI follow-ups (interactive grant editing in the approval + modal) — the only buildable step left. +- Live pass: KDF migration on a real unlock + second-Amber account switching. --- +# Checkpoint — Step 7 rename/hygiene + Forgejo push restored (2026-09-30) + +## Where things are +- Project: `/home/avi/Projects/Keynctr`, branch `master` @ **`7891ccc`** + ("docs: Step 7 rename/hygiene pass"). Previous: `c553dd5` (KDF upgrade + m=64MiB/t=3 + transparent migration, Sep 30), `5e91914` (launcher), theme + commits, identity backfill. +- **Forgejo push unblocked**: token supplied per-use via + `git -c http.extraHeader="Authorization: Bearer " push origin master` + (token supplied in chat, NOT stored anywhere — revoke when convenient). + `a6182e3..c553dd5` pushed; remote master verified == local. Token is + single-use-per-invocation; re-ask for it next push unless the user stores one. +- Step 7 done in `7891ccc`: `frontend/package.json` homepage -> + `https://git.atitlan.io/avi/Keynctr`; README retitled Keynctr, all + `[YOUR_FORGEJO_INSTANCE_URL]`/`/` placeholders resolved, clone + dir + packaged binary name fixed (`keynectr`), data-dir default + `~/.local/share/keynectr` (code auto-migrates the legacy dir), stale test + counts refreshed (cargo 225 unit + 6 e2e; npm 139 tests / 19 files), project + layout updated (audit/bunker/feed/updates, signer/ dir, Feed + SignerMode + screens). PRODUCT.md data-dir corrected. +- `tests/tmp_kdf_probe.rs` (throwaway probe) deleted; not part of the suite. +- Release binary rebuilt from c553dd5 (Sep 30 11:23). + +## Verified +- `cargo test`: 225 unit + 6 e2e, 0 failed. `cargo clippy --all-targets`: 0. + `cargo fmt --check`: clean. Frontend: 139/19 vitest green, typecheck, lint, + format:check clean (docs-only commit; no code touched). +- Push verified by `git ls-remote` readback (remote master == c553dd5 at push). + +## How to resume +- GUI: `cd ~/Projects/Keynctr/frontend && npx vite --port 5173` then + `NOSTR_GUI_DEV_URL=http://localhost:5173 KEYNCTR_ENABLE_GPU=1 npx electron .` +- Push: token needed per use (`http.extraHeader` form above), or user stores + one / registers the SSH key. + +## Outstanding / next steps +- Live pass (user): KDF migration on a real unlock; second-Amber switch + + backfill rename confirmation; publish kind-0 to primal/damus. +- Step 4 remainder: interactive grant editing in the approval modal. +- No CI workflow yet — `.forgejo/workflows/ci.yml` badge stays commented. + # Checkpoint — permissions UI + updater fix + Workshop theme (2026-09-27 night) ## Where things are diff --git a/PRODUCT.md b/PRODUCT.md index daae4dd..1ea1447 100644 --- a/PRODUCT.md +++ b/PRODUCT.md @@ -19,7 +19,7 @@ Nostr Keynctr (Nostr Feed Manager) pairs a hardened Rust core with an Electron + ## Operating Context Workflows: create/switch/delete/undo profiles, compose (Write/Preview, character count, up to 3 link previews, image pick → nostr.build upload with NIP-92 imeta), publish with per-relay receipts, feed aggregation (all vs. My contacts, 24h window), relay add/remove/enable/disable/test, NIP-05 assignment, secret reveal after unlock, vault backup, lock/unlock. -Environments: Linux desktop (Electron 33), Rust release backend (`target/release/keynectr serve` via stdio), Vite dev server optionally via `NOSTR_GUI_DEV_URL`. Data directory `~/.local/share/nost-feed-manager` (override `XDG_DATA_HOME`), vault `profiles_vault.json` (migrated from legacy Python CLI with timestamped backup), settings file alongside. +Environments: Linux desktop (Electron 33), Rust release backend (`target/release/keynectr serve` via stdio), Vite dev server optionally via `NOSTR_GUI_DEV_URL`. Data directory `~/.local/share/keynectr` (auto-migrated from the legacy `nost-feed-manager` dir; override `XDG_DATA_HOME`), vault `profiles_vault.json` (migrated from legacy Python CLI with timestamped backup), settings file alongside. Rituals: single-click Approve/Reject for NIP-46 requests; explicit `window.confirm` for delete; 5s themed undo bar; publish confirmation toggle; per-relay status dots. diff --git a/README.md b/README.md index 8e28086..c95ce8c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Nostr Feed Manager +# Keynctr > A friendly Linux desktop app for managing Nostr profiles, publishing notes, and acting as a > **NIP-46 remote signer** — your private keys stay under your control: encrypted in a local @@ -13,18 +13,17 @@ -> **Hosting note:** this project is hosted on **Forgejo**. Throughout this document, -> replace `[YOUR_FORGEJO_INSTANCE_URL]` with your instance's base URL (e.g. `https://codeberg.org`) -> and `/` with the actual repository path. +> **Hosting note:** this project is hosted on **Forgejo** at +> [`https://git.atitlan.io/avi/Keynctr`](https://git.atitlan.io/avi/Keynctr). --- ## 📖 Introduction -Nostr Feed Manager pairs a hardened **Rust core** (the same engine behind the original CLI) with a +Keynctr pairs a hardened **Rust core** (the same engine behind the original CLI) with a polished **Electron + React** desktop interface. All Nostr work — key generation, event signing, relay communication, encryption — happens inside the Rust backend. The GUI talks to it over a secure JSON-lines IPC channel and **never sees your secret keys**. @@ -135,8 +134,8 @@ No Docker, database, or account setup is required. ### 1. Clone and build ```sh -git clone [YOUR_FORGEJO_INSTANCE_URL]//.git -cd nost-feed-manager +git clone https://git.atitlan.io/avi/Keynctr.git +cd Keynctr # Build the Rust backend (release) cargo build --release @@ -167,7 +166,7 @@ directly, but you can export these from your shell or source an `.env` before la | --- | --- | --- | | `NFM_PASSWORD` | Vault password for non-interactive CLI use (create / publish / show-secret) | _prompt_ | | `NOSTR_GUI_DEV_URL` | Renderer dev-server URL for hot reload (development only) | — | -| `XDG_DATA_HOME` | Override the data directory | `~/.local/share/nost-feed-manager` | +| `XDG_DATA_HOME` | Override the data directory | `~/.local/share/keynectr` | **`.env.example`** — copy to `.env` and adjust: @@ -180,7 +179,7 @@ NFM_PASSWORD= # Renderer dev-server URL for hot reload (development only) NOSTR_GUI_DEV_URL=http://localhost:5173 -# Override the data directory (defaults to ~/.local/share/nost-feed-manager) +# Override the data directory (defaults to ~/.local/share/keynectr) XDG_DATA_HOME= ``` @@ -194,13 +193,13 @@ cd frontend npm run dist # builds renderer + backend and runs electron-builder ``` -The unpacked app lands in `frontend/release/linux-unpacked/`; run it with `./nost-feed-manager`. +The unpacked app lands in `frontend/release/linux-unpacked/`; run it with `./keynectr`. ## 🧑‍💻 Usage guide ### Desktop app -Tabs cover **Compose**, **Home**, **Profiles**, **Relays**, **Settings**, and **Signer**. Connect +Tabs cover **Compose**, **Home**, **Feed**, **Profiles**, **Relays**, **Settings**, and **Signer**. Connect a relay by entering its `wss://` URL, then compose a note, attach an image, and publish to see a per-relay report. @@ -288,11 +287,11 @@ npm run dev NOSTR_GUI_DEV_URL=http://localhost:5173 npm start ``` -### Verify (all green — `cargo 75`, `npm 71`, clippy/fmt/typecheck/lint/format clean) +### Verify (all green — `cargo 225 + 6 e2e`, `npm 139`, clippy/fmt/typecheck/lint/format clean) ```sh # Rust -cargo test # 75 unit tests +cargo test # 225 unit tests (+ 6 e2e in tests/) cargo fmt --check # rustfmt cargo clippy --all-targets @@ -301,7 +300,7 @@ cd frontend npm run typecheck # TypeScript (renderer + electron) npm run lint # ESLint npm run format:check # Prettier -npm test # Vitest (jsdom) — 71 tests across 13 files +npm test # Vitest (jsdom) — 139 tests across 19 files ``` The test suites exercise the real IPC protocol against a fake backend, so features are tested at @@ -312,22 +311,29 @@ the protocol boundary rather than in isolation. ``` src/ Rust library + CLI + IPC server app.rs app state, vault password/unlock lifecycle + audit.rs key-export audit log (fail-closed) + bunker.rs NIP-46 bunker (signer server) mode crypto.rs Argon2id derivation + AES-256-GCM encryption errors.rs structured AppError + feed.rs feed aggregation (all / contacts, 24h window) ipc.rs JSON-lines serve() loop and request/reply envelope main.rs CLI entry point - profiles.rs profile create/list/select, secret recovery + profiles.rs profile create/list/select, secret recovery, auto-naming publish.rs note publishing with receipts, images and imeta tags relays.rs default relays, validation, connection tests settings.rs theme and preferences - signer.rs NIP-46 remote signer + approval gate + updates.rs no-restart self-updater uploads.rs NIP-98 auth for image-host uploads vault.rs vault storage (plaintext or password-encrypted) + signer/ external NIP-46 signer client + backend.rs signer backend dispatch (embedded / external) + nip46_client.rs NIP-46 client: pairing, sessions, park/switch + permissions.rs per-remote per-kind permission grants frontend/ electron/ Electron main + preload (backend spawn, dialogs, clipboard) src/ - screens/ Compose, Home, Profiles, Relays, Settings, Signer - lib/ types, api bridge, media helpers + screens/ Compose, Home, Feed, Profiles, Relays, Settings, Signer, SignerMode + lib/ types, api bridge, media helpers, theme tokens state/ React context (AppProvider) test/ Vitest suite over a fake backend package.json scripts + electron-builder config @@ -341,7 +347,7 @@ respectful and constructive; everyone is expected to follow the ### Reporting bugs -Open an issue on the [issue tracker]([YOUR_FORGEJO_INSTANCE_URL]///issues) and include: +Open an issue on the [issue tracker](https://git.atitlan.io/avi/Keynctr/issues) and include: - A clear title and description of expected vs. actual behavior - Steps to reproduce diff --git a/frontend/package.json b/frontend/package.json index e30ede6..df590de 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,7 +7,7 @@ "name": "Keynectr", "email": "maintainers@keynectr.local" }, - "homepage": "https://github.com/avi/Keynctr", + "homepage": "https://git.atitlan.io/avi/Keynctr", "private": true, "main": "dist-electron/main.js", "scripts": {