From 4a0950e1cadbc31297cb13f4ab9b12d63a1b2dcd Mon Sep 17 00:00:00 2001 From: Sulthan Zaki Date: Tue, 28 Jul 2026 17:50:39 +0700 Subject: [PATCH] feat: bindmount userscript and point Violentmonkey at the backend Co-Authored-By: Claude Opus 5 --- AGENTS.md | 2 ++ CLAUDE.md | 2 ++ DEPLOY.md | 37 +++++++++++++++++++++++++++++++ docker-compose.yml | 7 ++++++ userscript/manga-bookmark.user.js | 2 ++ 5 files changed, 50 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 1d4003b..fedf19f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -72,6 +72,8 @@ Bromite userscript (isolated world, per-site adapters, localStorage cache) (gates browser UI; unset disables it), `LATEST_CHAPTER_POLL_ENABLED`/`_COOLDOWN`/`_INTERVAL`/`_BATCH`/`_STAGGER` (background latest-chapter poller; defaults on, `1h`/`10m`/`14`/`20s`). + `USERSCRIPT_PATH` (file served at `/u/{token}/manga-bookmark.user.js`, + default `/userscript/manga-bookmark.user.js`, supplied by a bindmount). ### Userscript structure (single IIFE, `manga-bookmark.user.js`) diff --git a/CLAUDE.md b/CLAUDE.md index 99c7a4c..0d1f491 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -72,6 +72,8 @@ Bromite userscript (isolated world, per-site adapters, localStorage cache) (gates the browser UI; unset disables it), `LATEST_CHAPTER_POLL_ENABLED`/`_COOLDOWN`/`_INTERVAL`/`_BATCH`/`_STAGGER` (background latest-chapter poller; defaults on, `1h`/`10m`/`14`/`20s`). + `USERSCRIPT_PATH` (file served at `/u/{token}/manga-bookmark.user.js`, + default `/userscript/manga-bookmark.user.js`, supplied by a bindmount). ### Userscript structure (single IIFE, `manga-bookmark.user.js`) diff --git a/DEPLOY.md b/DEPLOY.md index 98fbe78..d698cc7 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -218,3 +218,40 @@ SQLite data persists in the named volume `bookmarks-data` across rebuilds. | `compose ... config` errors about `API_TOKEN` | Run compose from the dir with `.env`, or export the vars. | Backend config reference and endpoint list: see `README.md`. + +--- + +## Installing / updating the userscript + +The backend serves the script itself, so Violentmonkey can auto-update it. + +Install once, on the phone (Cromite + Violentmonkey): + +``` +https://manga-api./u//manga-bookmark.user.js +``` + +Open that URL in Cromite; Violentmonkey offers to install it. The token is in +the path because Violentmonkey's update poll sends no `Authorization` header, +and the script embeds `API_TOKEN` in plain text — an open URL would leak it. A +wrong token answers 404. + +Updating, without a redeploy: + +```bash +vi userscript/manga-bookmark.user.js # on the VPS, in this checkout +``` + +`./userscript` is bindmounted read-only into the container and read fresh on +every request, so the edit is live immediately. The served `@version` is derived +from the file's mtime (`YYYY.MM.DD.HHMM`, UTC), not from the `@version` in the +file, so any edit outranks the installed copy and Violentmonkey pulls it on its +next check. The `@version` in the repo is a human marker only. + +Updating via redeploy: `git pull` overwrites the file with the committed +version, which is the intended behaviour — a deploy always ships the repo's +script. Note that `git pull` sets mtime to checkout time, so even a rollback +serves a *higher* version and is adopted. + +If the mount is missing, the endpoint answers 404 and logs it; bookmark sync is +unaffected. diff --git a/docker-compose.yml b/docker-compose.yml index dacce1d..c8adc6b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,6 +20,8 @@ services: PORT: "8080" # Gates the browser UI. Unset means the web routes are not served at all. WEB_PASSWORD: ${WEB_PASSWORD:-} + # Path inside the container; matches the bindmount above. + USERSCRIPT_PATH: ${USERSCRIPT_PATH:-/userscript/manga-bookmark.user.js} # Latest-chapter poller. LATEST_CHAPTER_POLL_ENABLED=0 in .env is the kill # switch; it only takes effect because these are listed here. LATEST_CHAPTER_POLL_ENABLED: ${LATEST_CHAPTER_POLL_ENABLED:-1} @@ -29,6 +31,11 @@ services: LATEST_CHAPTER_POLL_STAGGER: ${LATEST_CHAPTER_POLL_STAGGER:-20s} volumes: - bookmarks-data:/data + # The userscript is served from here, read fresh on every request. Editing + # the file in this checkout takes effect on the next Violentmonkey poll — + # no rebuild, no restart. `git pull` restores the committed version, which + # is why a redeploy always ships the repo's script. + - ./userscript:/userscript:ro # Bound to loopback only: the proxy (or curl during smoke test) reaches it, # the public internet does not. ports: diff --git a/userscript/manga-bookmark.user.js b/userscript/manga-bookmark.user.js index d598fcb..f074f57 100644 --- a/userscript/manga-bookmark.user.js +++ b/userscript/manga-bookmark.user.js @@ -4,6 +4,8 @@ // @version 1.5.0 // @description Track read progress on Asura & Demonic and sync to a self-hosted backend. Bromite-compatible (no GM_* APIs). // @author you +// @downloadURL https://manga-api.violetcrown.my.id/u/40d79969b5442f90df4fe306a092c7c50e7b4a7a98099f98cc398f4fb374b1df/manga-bookmark.user.js +// @updateURL https://manga-api.violetcrown.my.id/u/40d79969b5442f90df4fe306a092c7c50e7b4a7a98099f98cc398f4fb374b1df/manga-bookmark.user.js // @match https://asuracomic.net/* // @match https://asurascans.com/* // @match https://demonicscans.org/*