A browser notepad whose defining promise is that nothing you type is ever lost.
Multiple notes, saved continuously to IndexedDB, with a version history you can step back through. No account, no server, no build step — open the page and write.
Part of the OFCode "Quick" family, alongside Quick Web Notepad (its single-pad predecessor) and the Quick screenshot-to-clipboard extensions.
Implemented and under active review. All planned v1 modules (db.js,
store.js, i18n.js, and the UI layer) are written; the codebase has been
through several review-and-fix passes.
Two-way Google Drive sync — the intended v2 feature — is implemented on the
feature/drive-sync branch (sync-engine.js, sync.js, and the v2 protocol
in drive-sync.js); see "Sync" below for the model. The OAuth client id is
already configured, so the feature is live on that branch — but it has not yet
been exercised against real Drive on two real devices, and main still ships
the old one-way backup UI.
Genuinely outstanding, not yet done:
-
A two-device end-to-end run against real Drive — phone and desktop editing the same note, going offline, resolving a conflict, and a fresh browser pulling an existing library. The merge engine is unit-tested and the store paths are tested, but no test talks to Drive itself, so this is the one gap between "the tests pass" and "sync works".
-
Merging
feature/drive-syncintomain. Until then the deployed site keeps the v1 one-way backup UI ("Back up to Drive" / "Restore from Drive"). The first sync after a merge reads any existingheldnote-backup.jsononce as its baseline, so nothing already in Drive is stranded. -
DNS and hosting configuration for
heldnote.app— the A/AAAA andwwwCNAME records, the GitHub Pages custom-domain setting, "Enforce HTTPS", and a post-propagation smoke test all require registrar/hosting access this repository's automation does not have. -
Real-browser latency measurement.
constants.js's byte-budget values (MAX_NOTE_SIZE_BYTES,PER_NOTE_HISTORY_BYTE_BUDGET,GLOBAL_HISTORY_BYTE_BUDGET) are provisional placeholders, not measured numbers.tests/measure-latency.htmlexists to gather real p50/p95/p99/max draft-write timings and realnavigator.storage.estimate()figures on actual hardware; that measurement has not been run, and the constants have not been updated from it yet. -
Manual QA on real devices/browsers, none of which is possible from an automated environment: killing the tab mid-sentence and confirming recovery; typing continuously for a minute without pausing; and the three distinct Safari modes (ordinary tab, installed Home Screen/Dock app, Private Browsing) the design document calls out separately.
This is tracked in more detail in a process ledger at
.superpowers/sdd/2026-08-06-heldnote-v1-implementation/progress.md, which
is implementation-history bookkeeping, not user-facing documentation — this
section is the place that status should actually be found.
- Canonical design spec:
docs/superpowers/specs/2026-08-05-quick-keep-notepad-design.md - Planning artifacts:
.claude/artifacts/
- Multiple notes with search (title and body), pinning, and a trash you can restore from or permanently delete
- Two-layer persistence: a per-keystroke draft, plus periodic committed snapshots you can preview and restore
- Version history per note, with timestamped restore
- JSON export (full backup, downloaded as a file) and import, either as copies with fresh ids or as a full destructive replace (with an explicit warning and an offered safety export first)
- Two-way Google Drive sync across devices, with per-field merging and the
losing side of a conflict preserved in history (branch
feature/drive-sync; see "Sync") - Turkish and English UI, following the browser's language
- An honest status bar: the durable save state and the browser's storage retention state are always shown as two separate facts, never merged into one "Saved" light — including a standing notice on Safari, which this app cannot promise durability on
The editor is a plain textarea by design, with find & replace, word wrap, zoom, a light/dark theme toggle, copy, and .txt download built around it. Syntax highlighting with line numbers is deliberately not implemented, and is not a scope commitment.
Drive sync is two-way, not a backup: every device pulls, merges, and pushes one
file (heldnote-sync.json) in Drive's app-private appDataFolder. There is no
server, and no account beyond the user's own Google sign-in. The rules that
matter:
- Ordering never trusts the wall clock. Every synchronized mutation carries
a hybrid logical clock stamp
{w, c, d}— non-decreasing wall time, a per-device counter, and the device id. Two devices comparing stamps reach the same answer, with no ties, and a device with a wrong clock cannot win permanently. - Notes merge field by field, not as whole records. Text, title, pinned and lifecycle (trashed or live) each carry their own stamp, compared against a stored merge base. Renaming a note on the phone while editing its body on the desktop merges cleanly instead of one edit erasing the other.
- A real text conflict never loses text. The higher stamp becomes the live
text; the losing text is written into that note's version history as a
sync-conflictversion, protected from pruning for seven days. Conflicts resolve silently — there is no dialog to answer. - Deletion travels as a tombstone, written in the same IndexedDB transaction that purges the note, so a purge propagates instead of the note resurrecting from the other device. A purge that races an edit does not destroy it: the note lands in Trash carrying the edited text. Absence of a note is never read as deletion.
- Typing during a sync is safe. Each note carries a fence — its draft revision plus a mutation counter — and a note touched between merge-computation and merge-apply is skipped that round and merged on the next one.
- The upload is guarded by Drive's
headRevisionId. If another device wrote in the meantime, the cycle restarts from download and re-merges. A fresh or empty device pulls before it is ever allowed to upload, and a sync file written by a newer app version aborts the cycle rather than being overwritten by an older client. - A pre-existing one-way
heldnote-backup.jsonis read once as the initial remote baseline and then left alone. Manual JSON export and import are unchanged, and never carry sync metadata between devices.
Sync runs on load, on returning to the tab, after edits (30s debounce, at most once per five minutes), on "Sync now", and when the network comes back. In memory-fallback mode, when IndexedDB is unavailable, sync is disabled and says so rather than reporting a false success.
tests.html is the browser test runner; open it directly to watch the suite in
a real browser. For a headless run:
npm install --no-save playwright-core@1.49.1 # Node 18; drop the pin on Node 20+
node scripts/run-tests.mjsIt serves the repository over localhost, runs tests.html in system Chromium,
prints the harness summary, and exits non-zero on any failure.
tests/measure-latency.html is separate and manual: it exists to gather the
real-hardware numbers the byte budgets still need.
Working material is deliberately not shipped. docs/ (the design spec, the
sync contract, and the review records behind it), .claude/, .superpowers/
and logs/ are gitignored and live only on the development machine. The
product is the files at the repository root, plus tests/ and scripts/.
Canonical production origin: https://heldnote.app
The code side of this (CNAME file, manifest.webmanifest, this section) is
in place. The DNS and hosting configuration itself — pointing the domain at
GitHub Pages, enabling HTTPS, and verifying it — is a pending manual step;
see "Status" above.
www.heldnote.appredirects to the apex domain (once DNS is configured).- All user data is persisted locally via IndexedDB; no data migration is required if the origin changes, but any such change is an explicit export/import migration decision, never a silent move.
- Release smoke test: Before each production deploy, open
https://heldnote.appin a private/incognito window to verify the app loads and can access the local database (this confirms no silent breakage in storage access or IndexedDB permission changes).
Writing straight to disk, tags and folders, markdown preview, sharing, and
encryption. Google Drive sync was the intended v2 and is now implemented on
feature/drive-sync — see "Sync".
All rights reserved — see LICENSE. The source is published to be read and
reviewed, not relicensed.