Repository navigation
Releases: KingPin/Garrul
Releases · KingPin/Garrul
Release list
v2.41.0 — full Clef for spam checks and a bring-your-own-key decisions provider
Highlights:
- feat(spam): new
spam_ai_modelsetting (admin Settings page or env) picksclef-flash(default, unchanged) or fullclefforSPAM_PROVIDER=workers-ai. - feat(spam): new
SPAM_PROVIDER=decisionssends the spam question to any OpenAI-style/decisionsendpoint with your own key (OpenRouter's alpha route by default). New env vars:SPAM_DECISIONS_API_KEY(secret),SPAM_DECISIONS_URL(optional, must behttps://),SPAM_DECISIONS_MODEL(also thespam_decisions_modeladmin setting). It sharesspam_ai_thresholdwith workers-ai. - feat(admin): the dashboard spam summary flags a decisions provider with no key.
Notes:
- Drop-in upgrade: no migrations. All new env vars are optional; existing providers behave as before.
- With
decisions, comment text leaves Cloudflare (no email, IP or user agent). Update your privacy policy; seedocs/compliance/subprocessors.mdanddocs/ANTISPAM.md.
v2.40.2 — wrangler 4.156.0 clears the undici advisories
Drop-in patch. No new env vars, no migrations, no Worker code change.
chore:
wrangler4.156.0, which pullsundici7.30.1 and clears four undici advisories (GHSA-4w7w-5xrc-9h26, GHSA-2m5v-pch6-74hx, GHSA-qrxm-fqhp-jwvm, GHSA-9fm3-97px-rjf6). These affect the local deploy tooling only, not the Worker bundle. Runnpm ciafter upgrading so your checkout picks it up (#218).
If you skipped v2.40.1, read its notes too: it fixes the Confirm and Unsubscribe buttons on the emailed subscription pages.
v2.40.1 — subscription confirm and unsubscribe buttons work again
Drop-in patch. No new env vars, no migrations.
fix:
- The Confirm and Unsubscribe buttons on the emailed subscription pages work again. A
no-referrerpolicy made browsers sendOrigin: null, so the CSRF check refused every click witherr.origin.forbidden(#214, #215). Thanks to @gdecaso for tracking this down and sending the fix in #215. - The per-address pending cap (5 unconfirmed subscriptions) now counts only the last 7 days and skips cancelled rows. Before, five never-confirmed requests locked an address out of email subscriptions for good (#216).
- A confirm link stops working once its subscription is cancelled, instead of showing "you're subscribed" again. Malformed confirm tokens are refused without a D1 read (#216).
chore: dev-dependency and CodeQL action bumps.
v2.40.0 — opt-in widget padding and a minified Worker
Highlights:
- feat(widget): new opt-in
--garrul-paddingtheming var adds inner padding to the widget (single length only, e.g.16px). The name field and form options now sit inside the composer card. - chore(wrangler):
wrangler.example.tomlnow setsminify = true(about a third smaller upload, no behavior change).npm run upgradedoes not sync wrangler.toml keys — add the line to your ownwrangler.tomlby hand. - fix(seed-demo):
npm run seed-demore-runs cleanly; it clears comment child rows before re-seeding.
Notes:
- Drop-in upgrade: no new env vars, no migrations.
- If you serve from a custom domain, set
workers_dev = false(andpreview_urls = false) inwrangler.tomlso theworkers.devhostname is not public.
v2.39.0 — a static iframe shell and fewer D1 reads and KV writes
Highlights:
- Static iframe shell:
/embed/?slug=<slug>is served by Workers Static Assets, so an iframe pageview no longer runs the Worker for the shell./embed/<slug>is unchanged. - Fewer D1 reads and KV writes: page vote/reaction totals are stored on write (no per-pageview counting), new admin-list indexes, sessions read once per request and refreshed at half-life,
/feed/:slugand/c/:idedge-cached for 5 minutes. Anonymous comment posts no longer write KV (Workers AI verdict cache removed). - Cost visibility:
/admin/usagecounts D1 rows read/written (not queries) and adds a Workers AI neurons panel; each anti-spam control on/admin/settingsstates its per-comment cost. - Siteverify, Akismet and Workers AI calls now time out (5 s / 3 s / 5 s).
Notes for operators:
- Run
npm run upgrade(migrations 0031, 0032), then run once:npx wrangler d1 execute DB --remote --file src/db/post-deploy/0032_page_engagement_totals.sql. It recounts vote/reaction totals the old Worker changed between migrate and deploy. It is idempotent. Upgrades from this release on run it automatically. - To use the static shell, point iframe embeds at
/embed/?slug=…. Its CSP comes from top-levelALLOWED_ORIGINSinwrangler.tomlat build time, so redeploy after changing it. WithENV = "dev",[env.*]tables or noALLOWED_ORIGINS, the Worker serves that URL instead. - Dashboard figures can trail a moderation action by up to a minute; the queue stays live.
v2.38.0 — Clef-flash spam scoring and fewer billed requests
Highlights:
- Workers AI spam checks now use Cloudflare's Clef-flash decision model and score each comment. New optional
SPAM_AI_THRESHOLD(1–100, default 70) sets the queue cut-off; also editable on /admin/settings. - Fewer billed requests:
/embed.jscan be served from Workers Static Assets via a new[assets]block (npm run upgradeprints it), and the form-timing token is minted on first composer focus instead of at mount. - Less KV and D1 load: settings use a 60 s per-isolate memo instead of a KV cache, reply notifications fan out in one query, and thread paging seeks on new indexes.
Notes for operators:
- Run
npm run migrate— migration 0030 adds paging and retention indexes. - To take
/embed.jsoff the Worker quota, add[assets]on one line anddirectory = "./public"on the next at the end ofwrangler.toml. Keep it below the top-level keys (name,main,routes,workers_dev): in TOML a key below a table header belongs to that table. Add it beforenpm run upgradeso the upgrade's deploy picks it up; if you add it later, runnpm run deploy. Without it nothing breaks. - Sign-out, token exchange and OAuth callback are now rate-limited. docs/ANTISPAM.md has an optional Cloudflare WAF rule for the sign-out route.
- Settings edits can take up to 60 s to reach every isolate.
v2.37.0 — replies stay visible under removed comments and a spam-thread action
Highlights:
- Replies survive a removed parent. Marking a comment spam, holding it for moderation, or a moderator delete no longer hides its approved replies. The parent renders as an anonymous "[removed by a moderator]" placeholder; a hidden comment with no visible replies renders nothing (#189).
- Spam thread. The admin comment detail page has a Spam thread action that marks a comment and every reply below it spam in one atomic step, up to 100 comments. Each changed row gets a
thread.spamaudit entry withprev_status, so it can be undone. Onecomment.spamwebhook fires, for the root only. - Queue reply hint. Spam and pending rows show "↳ N direct replies".
fix:
- Replies to a spam comment, or to someone else's pending comment, are refused like a missing parent.
- Admin bulk moderation runs a fixed number of D1 queries and no longer 404s or hits the bind-parameter cap on large selections. Bulk delete now records the removal as a moderator delete.
- New log events:
comment.requarantinedwhen an edit sends an approved comment back to pending;comments.page_truncatedalso fires on the 4,000-row scan cap (scan_limit).
No new env vars, endpoints or migrations. Drop-in upgrade.
v2.36.1 — clearer GitHub sign-in failures and safe slugs for odd import links
fix:
- Sign-in (GitHub 429). GitHub blocks the token exchange from some Cloudflare Workers egress addresses with HTTP 429. The Worker now retries a few times; if every try is blocked, the popup says so and suggests signing in again. Thanks @adbertram (#187).
- Sign-in (all providers). A failed sign-in popup now stays open so readers can see it, instead of closing after 250 ms. Other providers' 429s are not retried, return 503, and forward their
Retry-After. Logs carrystatusandretry_afteronoauth.token. - Import. A thread link the read API would reject (percent-encoding, characters outside
a-z 0-9 _ - . /, over 200 characters) now gets a stable synthetic slug instead of an unreachable page. The import plan counts these asfallback_slugs. Earlier imports may have stranded such pages; AGENTS-OPERATE.md has the SQL to find and move them (#186, #117).
No new env vars, endpoints or migrations.
v2.36.0 — Arabic locale with right-to-left support
Highlights
- Arabic (
ar) locale, Garrul's first right-to-left language. The widget sets its direction from the locale. Select it withdata-lang="ar"; an Arabic<html lang>alone still selects English until a native speaker reviews the machine-seeded translation.
Notes for operators
- Drop-in upgrade. No new env vars, secrets, bindings or migrations.
- Dependency updates:
hono4.13.13,marked18.1.0,wrangler4.149.0. Thewranglerbump moves the dev-onlysharpto 0.35.5 (GHSA-wq5f-xc86-pv6w); it never reached the Worker runtime. marked18.1.0 rejects link destinations with unbalanced parentheses. Existing stored comments are unchanged; the renderer version is not bumped.
v2.35.0 — npm run upgrade shows notes for every release since your version
Highlights
npm run upgradenow prints the notes for every release since your installed version, not just the target's. The newest three releases show in full; older ones show as one title line each (up to 20). The section is capped at 100 lines, with a link to the releases page for anything cut off.- If GitHub refuses the releases list (for example, the unauthenticated rate limit), the target's own notes still print, with a note that earlier releases could not load.
Notes for operators
- Drop-in upgrade. No new env vars, secrets, bindings or migrations.
- The upgrade now makes one extra GitHub API request (the releases list). Set
GITHUB_TOKENif you hit the 60/hour unauthenticated limit.