{"_id":"@burakboduroglu/nors","_rev":"4-a2f786347f3c6cdb0a3d0b722a8b022d","name":"@burakboduroglu/nors","dist-tags":{"latest":"0.1.4"},"versions":{"0.1.0":{"name":"@burakboduroglu/nors","version":"0.1.0","keywords":["notes","ops-notes","pocketbase","self-hosted","dashboard","mermaid","no-telemetry"],"author":{"name":"Burak Boduroğlu"},"license":"MIT","_id":"@burakboduroglu/nors@0.1.0","maintainers":[{"name":"burakboduroglu","email":"burakboduroglu0@gmail.com"}],"homepage":"https://github.com/burakboduroglu/nors#readme","bugs":{"url":"https://github.com/burakboduroglu/nors/issues"},"bin":{"nors":"bin/nors.js"},"dist":{"shasum":"20efc8299f00958079cca70abe3e12635732b005","tarball":"https://registry.npmjs.org/@burakboduroglu/nors/-/nors-0.1.0.tgz","fileCount":103,"integrity":"sha512-OAGzFrcDeqT3hXS7tK8mnsLb1ozGg5xyWtPeo6zA7I7nPcjRPBp1JygJy3wEBkd7iE4yJC/EVVh6uk73PegTWQ==","signatures":[{"sig":"MEUCIFH9pF71MGZ5giEm2dNkgw14/3z+YlpyKSH0yBShhGIqAiEAtYfJfcc8WbTYnXlb6b4otWCagrlZOvU5iGmkVSlHaFs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3470345},"type":"module","engines":{"node":">=18"},"gitHead":"483f4eb3742e7273e70324330c7324bd48f6fe54","scripts":{"dev":"bun --cwd web dev","build":"bun --cwd web build","prepack":"bun --cwd web build","preview":"bun --cwd web preview","import-seeds":"bun scripts/import-seeds.ts"},"_npmUser":{"name":"burakboduroglu","email":"burakboduroglu0@gmail.com"},"repository":{"url":"git+https://github.com/burakboduroglu/nors.git","type":"git"},"_npmVersion":"11.19.0","description":"Personal ops notes dashboard on PocketBase — Norse-named, Solid UI at /nors/","directories":{},"_nodeVersion":"26.8.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/nors_0.1.0_1788972524287_0.1975976484900328","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@burakboduroglu/nors","version":"0.1.2","keywords":["notes","ops-notes","pocketbase","self-hosted","dashboard","mermaid","no-telemetry"],"author":{"name":"Burak Boduroğlu"},"license":"MIT","_id":"@burakboduroglu/nors@0.1.2","maintainers":[{"name":"burakboduroglu","email":"burakboduroglu0@gmail.com"}],"homepage":"https://github.com/burakboduroglu/nors#readme","bugs":{"url":"https://github.com/burakboduroglu/nors/issues"},"bin":{"nors":"bin/nors.js"},"dist":{"shasum":"1862ed124baf126728bc59a7c9a9e805e5ef6478","tarball":"https://registry.npmjs.org/@burakboduroglu/nors/-/nors-0.1.2.tgz","fileCount":104,"integrity":"sha512-BRtojRrxStfrrOoRe3B+yy5PCZ8Ar5EWs2hSHCxAu0A6fhItmDJeN7MELEg/bscDCSlV1An9AxpvjOPwupE0Mw==","signatures":[{"sig":"MEQCIHqffiwlvOHO4/+mDHRkTfaUkqLHaJwUOqrHxisS8YM+AiAbF64ZUdKdPINzbqeuBg0rl+cw5MuJ8QaRKV8PTMsEJQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3483017},"type":"module","engines":{"node":">=18"},"gitHead":"f6bbf4c3d22522dccd6dec4462db274c76b95517","scripts":{"dev":"bun --cwd web dev","build":"bun --cwd web build","prepack":"bun --cwd web build","preview":"bun --cwd web preview","import-seeds":"bun scripts/import-seeds.ts"},"_npmUser":{"name":"burakboduroglu","email":"burakboduroglu0@gmail.com"},"repository":{"url":"git+https://github.com/burakboduroglu/nors.git","type":"git"},"_npmVersion":"11.19.0","description":"Personal ops notes dashboard on PocketBase — Norse-named, Solid UI at /nors/","directories":{},"_nodeVersion":"26.8.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/nors_0.1.2_1788980743369_0.8030697160741431","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@burakboduroglu/nors","version":"0.1.3","keywords":["notes","ops-notes","pocketbase","self-hosted","dashboard","mermaid","no-telemetry"],"author":{"name":"Burak Boduroğlu"},"license":"MIT","_id":"@burakboduroglu/nors@0.1.3","maintainers":[{"name":"burakboduroglu","email":"burakboduroglu0@gmail.com"}],"homepage":"https://github.com/burakboduroglu/nors#readme","bugs":{"url":"https://github.com/burakboduroglu/nors/issues"},"bin":{"nors":"bin/nors.js"},"dist":{"shasum":"92cdc9dc94668aaab8afeda41397fe99255ee759","tarball":"https://registry.npmjs.org/@burakboduroglu/nors/-/nors-0.1.3.tgz","fileCount":104,"integrity":"sha512-Ixn/q3jZZq5I41BHK7d1PrssVa85BKXPxVSpqbLOQtrr0yOxOFjmzOFIeeDHIS+mJlngeRelf0MyLUpa1Nl16A==","signatures":[{"sig":"MEUCIDLMuZRfw0tXtGdN0MHFYpDicGoJHqfAltkmdwE+AnLFAiEA/C0ZFXOe7G3xxYxPWag2baEGHhxT6LpH/fQnbRbsjiM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3489262},"type":"module","engines":{"node":">=18"},"gitHead":"f1e4f98a2ea639df37824b78a9399ae78c94219d","scripts":{"dev":"bun --cwd web dev","build":"bun --cwd web build","prepack":"bun --cwd web build","preview":"bun --cwd web preview","import-seeds":"bun scripts/import-seeds.ts"},"_npmUser":{"name":"burakboduroglu","email":"burakboduroglu0@gmail.com"},"repository":{"url":"git+https://github.com/burakboduroglu/nors.git","type":"git"},"_npmVersion":"11.19.0","description":"Personal ops notes dashboard on PocketBase — Norse-named, Solid UI at /nors/","directories":{},"_nodeVersion":"26.8.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/nors_0.1.3_1789019005453_0.373908296573112","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"_id":"@burakboduroglu/nors@0.1.4","bin":{"nors":"bin/nors.js"},"bugs":{"url":"https://github.com/burakboduroglu/nors/issues"},"dist":{"shasum":"d30517bf54233fee7850c716af110a1f5d8b8dd2","tarball":"https://registry.npmjs.org/@burakboduroglu/nors/-/nors-0.1.4.tgz","fileCount":104,"integrity":"sha512-nCZS/UD83lT11HD+34xlcvrxlKHNC+NyFmimAgvno/1Ny+3ozO6s5xwSUrUNtRGPMHL3GbN2BIzwnW+s7pyAuA==","signatures":[{"sig":"MEQCIG4jY0ti17RBrdhiU3KkeVPbdr8hqaPye2MXNMjwGlXRAiBHgW1PkgzMIXVYN+xVo1NlvdTnT7OLmtcVlRkWYRJ8Sg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCDQXO7nWN32a4/oXe3bUMMttJ5wdQMO8FuKAFfAdLaMAIgYrrqlKtjcwO54BToWVRlxuhsVQ0llSoWyQXGul9b8CQ="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@burakboduroglu%2fnors@0.1.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":3523657},"name":"@burakboduroglu/nors","type":"module","author":{"name":"Burak Boduroğlu"},"engines":{"node":">=18"},"gitHead":"57af1adfe884644d743c386142a8fadf96873dbb","license":"MIT","scripts":{"dev":"bun --cwd web dev","build":"bun --cwd web build","prepack":"bun --cwd web build","preview":"bun --cwd web preview","import-seeds":"bun scripts/import-seeds.ts"},"version":"0.1.4","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ed397124-aa62-4929-b47e-46ad5ab4a376"}},"homepage":"https://github.com/burakboduroglu/nors#readme","keywords":["notes","ops-notes","pocketbase","self-hosted","dashboard","mermaid","no-telemetry"],"repository":{"url":"git+https://github.com/burakboduroglu/nors.git","type":"git"},"_npmVersion":"12.1.0","description":"Personal ops notes dashboard on PocketBase — Norse-named, Solid UI at /nors/","directories":{},"maintainers":[{"name":"burakboduroglu","email":"burakboduroglu0@gmail.com"}],"_nodeVersion":"24.21.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nors_0.1.4_1790535439554_0.628080410356699"}}},"time":{"created":"2026-09-09T16:48:44.113Z","modified":"2026-09-27T18:57:19.977Z","0.1.0":"2026-09-09T16:48:44.429Z","0.1.2":"2026-09-09T19:05:43.602Z","0.1.3":"2026-09-10T05:43:25.669Z","0.1.4":"2026-09-27T18:57:19.676Z"},"bugs":{"url":"https://github.com/burakboduroglu/nors/issues"},"author":{"name":"Burak Boduroğlu"},"license":"MIT","homepage":"https://github.com/burakboduroglu/nors#readme","keywords":["notes","ops-notes","pocketbase","self-hosted","dashboard","mermaid","no-telemetry"],"repository":{"url":"git+https://github.com/burakboduroglu/nors.git","type":"git"},"description":"Personal ops notes dashboard on PocketBase — Norse-named, Solid UI at /nors/","maintainers":[{"name":"burakboduroglu","email":"burakboduroglu0@gmail.com"}],"readme":"![Nors mark](assets/nors-mark-32.png)\n\n# Nors\n\n**Personal ops notes that ride a PocketBase instance you already run.**\n\n[![License](https://img.shields.io/github/license/burakboduroglu/nors?style=flat-square)](LICENSE)\n[![npm](https://img.shields.io/npm/v/@burakboduroglu/nors?style=flat-square&color=000)](https://www.npmjs.com/package/@burakboduroglu/nors)\n![Self-hosted](https://img.shields.io/badge/self--hosted-only-000?style=flat-square)\n![No telemetry](https://img.shields.io/badge/telemetry-none-000?style=flat-square)\n![No Docker](https://img.shields.io/badge/Docker-not_required-000?style=flat-square&logo=docker)\n![Bun](https://img.shields.io/badge/Bun-runtime-000?style=flat-square&logo=bun)\n\n---\n\nNors is not an application you deploy. It is one migration and one static\npage, copied into a PocketBase directory you already have. The database,\nauth, HTTP server and backups are already running — a dedicated notes app\nwould duplicate all of them.\n\n![Nors dashboard — note cards with kind tabs](assets/screenshot-dash.png)\n\n## What it is\n\nNotes live as cards on a dashboard, filed under four kinds: Diagram, Runbook,\nReference, Scratch. An agent drafts in markdown, you publish from the panel —\npaste a blob, fix the title, pick a kind, done. Bodies render as markdown and\nMermaid fences become diagrams in the reader.\n\nWriting stays minimal on purpose: title, kind, pinned, body. The slug grows\nout of the title and the summary out of the first clean body line, so there\nis nothing else to fill in.\n\n## Highlights\n\n|     | Feature | How it works |\n| --- | ------- | ------------ |\n| 🧩 | **No infrastructure of its own** | Files copied into an existing PocketBase. No container, no second database, no extra port. |\n| 📝 | **Write four things, nothing else** | Title, kind, pinned, body. Slug and summary derive themselves. |\n| 📊 | **Diagrams without a plugin** | Mermaid loads only on pages that hold a fence; everything else never downloads it. |\n| ↔️ | **Order by dragging** | Native HTML5 drag-and-drop renumbers `sort`; pinned cards stay first by construction. No DnD library. |\n| 📥 | **Seeds are upserts** | `bun run import-seeds` matches by slug — re-running updates instead of duplicating. |\n| 🛡️ | **Unsaved work asks first** | Leaving the editor with edits pops a guard instead of silently dropping the draft. |\n| 📵 | **No telemetry** | Zero outbound requests. The page talks to your PocketBase and nothing else. |\n\n![Nors reader — CLI shelf note with rendered Mermaid diagrams](assets/screenshot-reader.png)\n\n## Footprint\n\nMeasured with `du`:\n\n| | |\n| --- | --- |\n| Installed files | **3.6 MB** — migration 4 KB, page the rest |\n| First visit | **~138 KB** — entry JS ~121 KB (gzip ~41 KB, including the DOMPurify sanitiser), CSS ~17 KB |\n| The other 3.4 MB | Mermaid diagram chunks, fetched only when a reader page holds a fence |\n| Database growth | one `nors_notes` row per note, inside the existing `pb_data` |\n| Extra processes | none |\n| Extra ports | none |\n\nIf PocketBase is already running, the marginal cost of Nors is the file sizes.\n\n## Install\n\nInstall into a PocketBase directory with the packaged CLI:\n\n```bash\nbunx @burakboduroglu/nors install /path/to/pocketbase\n```\n\nThis copies the migration and built page; it never touches `pb_data`. Then\nrestart PocketBase so the migration runs. **If it was already running, stop it\nbefore copying and start it afterwards** — PocketBase watches its directories\nand can race a service manager doing the same.\n\nFor a source checkout and remote host, the `deploy/` installer performs the\nstop → copy → start sequence. The page is not committed, so build it first:\n\n```bash\nbun --cwd web install && bun run build\nscp -r pb_migrations pb_hooks pb_public deploy/install.sh host:/tmp/nors-stage/\nssh host\nsudo /tmp/nors-stage/install.sh /tmp/nors-stage\n```\n\nThe page is served at `/nors/`. Gate `/nors` and\n`/api/collections/nors_notes` in Cloudflare Access the way `/subs/` is gated\n(see `deploy/access-caddy.md`). Then load the three seed notes through the API:\n\n```bash\nNORS_PB_URL=https://your.host NORS_PB_EMAIL=... NORS_PB_PASSWORD=... \\\n  bun run import-seeds\n```\n\n## How it works\n\n```\nbrowser ──▶ /nors/                            static page, superuser login\nbrowser ──▶ /api/collections/nors_notes/*      superuser only, CRUD + reorder\nGlance  ──▶ 127.0.0.1:8090/api/nors/summary    counts + recent titles\nagent   ──▶ drafts markdown ──▶ editor ──▶ publish\n```\n\nRoutes are hashes: `#/` dashboard, `#/n/<slug>` reader,\n`#/edit/<slug|$new>` editor. `/nors/?new=1` is the stable external entry point\nfor a new note; it consumes the query and opens the `$new` editor route.\n\n## Security\n\nThe `nors_notes` collection has null API rules, which in PocketBase means\nsuperuser only. The dashboard holds a superuser token in localStorage — anyone\nwith the browser profile has the keys, documented rather than hidden. There is\nno audit log and no second user; this is a single-operator surface behind\nCloudflare Access, not a multi-user app.\n\nThe Glance summary hook has no PocketBase authentication because Glance reads\nit over loopback. The public reverse proxy must return `404` for the exact\n`/api/nors/summary` path; `deploy/patch-caddy-nors-summary.py` installs that\nguard. Do not expose this endpoint publicly: it includes recent note titles.\n\n## What it deliberately does not do\n\nNo in-app LLM calls. No public notes or team sharing. No wiki search, tag\ngraph, or version history UI. No reminders. It does not replace a vault or a\nknowledge base — it is the live dashboard above them.\n\n## Stack\n\nPocketBase for storage, auth and HTTP. SolidJS + Vite UI compiled to static\nfiles under `pb_public/nors/`. `marked` for markdown, Mermaid on demand, no\nCSS library, no UI server. Bun as the package manager.\n\n## Develop the UI\n\nSource lives in `web/`. The shipped page is built output — `pb_public/nors/`\nis not committed; `prepack` builds it into the npm tarball, and a `v*` tag push\npublishes through `.github/workflows/release.yml`.\n\n```bash\nbun --cwd web install\nbun run build      # root script — emits pb_public/nors/\nbun run dev        # local UI; /api proxied to :8090 (NORS_PB_PORT to move it)\n```\n\nAgainst a tunneled production box: `ssh -N -L 8090:127.0.0.1:8090 host`,\nthen `bun run dev` — the browser stays on localhost, so neither CORS nor\nCloudflare Access is in the path.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","readmeFilename":"README.md"}