{"id":51384728,"url":"https://github.com/creatornader/note-to-self","last_synced_at":"2026-07-03T19:09:11.126Z","repository":{"id":358388810,"uuid":"1178064323","full_name":"creatornader/note-to-self","owner":"creatornader","description":"Encrypted personal message queue: CLI-first, E2E encrypted, cross-device","archived":false,"fork":false,"pushed_at":"2026-06-20T11:25:08.000Z","size":620,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-20T13:19:38.751Z","etag":null,"topics":["age-encryption","cli","cloudflare-r2","encrypted","pwa","rust"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/creatornader.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-10T16:45:43.000Z","updated_at":"2026-06-20T11:25:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/creatornader/note-to-self","commit_stats":null,"previous_names":["creatornader/note-to-self"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/creatornader/note-to-self","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creatornader%2Fnote-to-self","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creatornader%2Fnote-to-self/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creatornader%2Fnote-to-self/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creatornader%2Fnote-to-self/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/creatornader","download_url":"https://codeload.github.com/creatornader/note-to-self/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creatornader%2Fnote-to-self/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35097946,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-03T02:00:05.635Z","response_time":110,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["age-encryption","cli","cloudflare-r2","encrypted","pwa","rust"],"created_at":"2026-07-03T19:09:10.364Z","updated_at":"2026-07-03T19:09:11.116Z","avatar_url":"https://github.com/creatornader.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Note to Self\n\nAn encrypted personal message queue you talk to from the terminal or your phone: push, peek, pop, ack, synced across your devices.\n\n## Why\n\n- Self-messaging with queue semantics (push/peek/pop/ack), not a notes app.\n- End-to-end encrypted by default using `age`. Storage never sees plaintext.\n- CLI-first. `nts push \"remember this\"` from any terminal.\n- Mobile reachable. Read and compose from a PWA on your phone.\n- No account. Just an age keypair and a storage bucket you own.\n\n## Example\n\n```sh\nnts init                       # generate keypair, write config\nnts push \"meeting at 3pm\"      # encrypt and queue a message\nnts peek                       # decrypt and show the latest unread\n```\n\nOther useful commands: `nts pop`, `nts list`, `nts search \"api key\"`, `nts sync`, `nts status`, `nts device add`.\n\n## Install\n\nPre-1.0. Build from source:\n\n```sh\ngit clone https://github.com/creatornader/note-to-self\ncd note-to-self\ncargo install --path .\nnts --help\n```\n\nRequires a recent stable Rust toolchain. The binary is named `nts`.\n\nThe PWA and Cloudflare Worker R2 proxy live under `web/`. Deploy your own by following `web/README.md`. After deploy, run `nts device add` to mint a bearer token and print the import bundle URL.\n\n## Status\n\n| Milestone | State |\n|-----------|-------|\n| M1: CLI with age encryption (local storage) | done |\n| M2: Cloudflare R2 sync with ETag locking | done |\n| M3: ntfy.sh push notifications | done |\n| M4a: PWA + Worker R2 proxy + CLI device management | done |\n| M4b: Hardening, audit, env-var secrets, tap-to-open | done |\n| M4b polish: inbox filters, QR import, WebAuthn, Web Push | in progress |\n| M5: Webhook ingestion | planned |\n| M6: File attachments | planned |\n| M7: Local search / optional Ollama | planned |\n\nTests: 91 unit + 42 integration (Rust), 152 unit + 2 e2e (PWA), 55 (Worker). Run with `cargo test`, `npm test --prefix web`, and `npm test --prefix web/worker`. CI runs all three on every push and pull request.\n\nMilestone boundaries are tagged on origin (`m4a-complete`, `m4b-complete`). `git checkout m4b-complete` returns the tree to that boundary.\n\n## Architecture\n\nMessages are encrypted client-side with `age` (X25519 + ChaCha20-Poly1305) and stored as opaque blobs in Cloudflare R2. An encrypted index drives queue operations, with ETag optimistic locking for cross-device sync. The mobile side is a Preact PWA using the `age-encryption` npm package and a Cloudflare Worker that proxies R2 with per-device bearer tokens. Notifications go through ntfy.sh and carry only a \"new note arrived\" signal: the message body is never sent to the notification service. See `docs/architecture.md` for the full design, security model, and rejected alternatives (Matrix, Memos plus encryption).\n\n## Security\n\n- Secrets (R2 keys, ntfy token, age identity) can be loaded from env vars seeded by 1Password at shell init. Plaintext `config.toml` / `identity.txt` fields remain readable for back-compat until M5. See the ADR in `docs/architecture.md`.\n- Passphrase-encrypted export bundles (`nts export --passphrase`) ship the identity to a new device without ever writing it to disk in cleartext.\n- Per-device bearer tokens for the Worker. Revoke with `nts device revoke`.\n- CI runs gitleaks, TruffleHog, typos, and pre-commit on push and pull request. OSV runs on the weekly schedule and manual dispatch. The root `osv-scanner.toml` contains the dated exception for the upstream `age` transitive `RUSTSEC-2026-0173` advisory.\n\n## Docs\n\n- `docs/architecture.md`: technical design, security model, tech stack.\n- `docs/roadmap.md`: milestone-by-milestone plan and current state.\n- `docs/research.md`: landscape research and competitive analysis.\n- `web/README.md`: PWA and Worker deploy guide.\n- `CLAUDE.md`: project overview, principles, and dev instructions.\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcreatornader%2Fnote-to-self","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcreatornader%2Fnote-to-self","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcreatornader%2Fnote-to-self/lists"}