- **Works without JavaScript** — note editing, search, theming, and the login form are plain HTML; the menus, mobile tabs, and live preview are the JS-dependent parts
Root notes (no folder) keep the plain `uuid.md` format. Folders exist only when they contain at least one note — there is no separate folder metadata to manage.
**Creating a folder:** click `+ New Folder` in the sidebar (or File → New Folder in the menu), type a name, and the app creates a new note in that folder and opens it.
**Filtering:** click a folder name in the sidebar to see only that folder's notes. Click **All Notes** to see everything grouped by folder. When a folder is active, the **+ New Note** button creates notes in that folder.
**Validation:** folder names reject path traversal (`..`), shell metacharacters (`;`, `|`, `&`, `$`, backtick, parens, angle brackets), control characters, leading dots, and names over 100 characters. Invalid names show a red flash message at the top of the page.
**First launch:** the server prints a QR code to your terminal and waits for a 6-digit code. Scan it with any TOTP authenticator (FreeOTP, Aegis, Bitwarden, Google Authenticator, …), or type the Base32 secret by hand if you would rather not scan. Only after a valid code is the secret committed to `.totp_secret` in the project root with mode `0600` — and only then does the port start listening.
Enrollment deliberately happens in the terminal rather than on a web page. There is no `/setup` route to reach: an HTTP-reachable setup endpoint would let anyone who can reach the port before you finish claim the device.
**Every launch after that:** you land on `/login` and need a current code. Sessions last one hour and live only in memory, so restarting the server invalidates them.
**Lost your authenticator?** Delete the secret and restart:
```bash
rm .totp_secret
```
There is no recovery-code fallback by design — that file is the only thing holding the secret, and it stays on your machine.
The proxy strips the prefix, so the app still sees ordinary paths and adds the prefix back when generating links, form actions, and redirects. The session cookie's `Path` is scoped to the prefix, so the token is not sent to sibling apps on the same host.
## Command Line Options
```
Usage: eternalibre-notes [OPTIONS]
Options:
--host <HOST> Host address to bind to [default: 0.0.0.0]
-p, --port <PORT> Port to listen on [default: 3000]