Skip to content

Releases: KingPin/Garrul

v2.41.0 — full Clef for spam checks and a bring-your-own-key decisions provider

Choose a tag to compare

@github-actions github-actions released this 31 Oct 03:02
25f81a1

Highlights:

  • feat(spam): new spam_ai_model setting (admin Settings page or env) picks clef-flash (default, unchanged) or full clef for SPAM_PROVIDER=workers-ai.
  • feat(spam): new SPAM_PROVIDER=decisions sends the spam question to any OpenAI-style /decisions endpoint with your own key (OpenRouter's alpha route by default). New env vars: SPAM_DECISIONS_API_KEY (secret), SPAM_DECISIONS_URL (optional, must be https://), SPAM_DECISIONS_MODEL (also the spam_decisions_model admin setting). It shares spam_ai_threshold with 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; see docs/compliance/subprocessors.md and docs/ANTISPAM.md.

v2.40.2 — wrangler 4.156.0 clears the undici advisories

Choose a tag to compare

@github-actions github-actions released this 30 Oct 18:34

Drop-in patch. No new env vars, no migrations, no Worker code change.

chore:

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

Choose a tag to compare

@github-actions github-actions released this 30 Oct 18:26

Drop-in patch. No new env vars, no migrations.

fix:

  • The Confirm and Unsubscribe buttons on the emailed subscription pages work again. A no-referrer policy made browsers send Origin: null, so the CSRF check refused every click with err.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

Choose a tag to compare

@github-actions github-actions released this 21 Oct 16:09

Highlights:

  • feat(widget): new opt-in --garrul-padding theming 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.toml now sets minify = true (about a third smaller upload, no behavior change). npm run upgrade does not sync wrangler.toml keys — add the line to your own wrangler.toml by hand.
  • fix(seed-demo): npm run seed-demo re-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 (and preview_urls = false) in wrangler.toml so the workers.dev hostname is not public.

v2.39.0 — a static iframe shell and fewer D1 reads and KV writes

Choose a tag to compare

@github-actions github-actions released this 21 Oct 03:40
d69ec37

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/:slug and /c/:id edge-cached for 5 minutes. Anonymous comment posts no longer write KV (Workers AI verdict cache removed).
  • Cost visibility: /admin/usage counts D1 rows read/written (not queries) and adds a Workers AI neurons panel; each anti-spam control on /admin/settings states 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-level ALLOWED_ORIGINS in wrangler.toml at build time, so redeploy after changing it. With ENV = "dev", [env.*] tables or no ALLOWED_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

Choose a tag to compare

@github-actions github-actions released this 19 Oct 16:16
8bbbe91

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.js can be served from Workers Static Assets via a new [assets] block (npm run upgrade prints 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.js off the Worker quota, add [assets] on one line and directory = "./public" on the next at the end of wrangler.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 before npm run upgrade so the upgrade's deploy picks it up; if you add it later, run npm 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

Choose a tag to compare

@github-actions github-actions released this 16 Oct 19:14

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.spam audit entry with prev_status, so it can be undone. One comment.spam webhook 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.requarantined when an edit sends an approved comment back to pending; comments.page_truncated also 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

Choose a tag to compare

@github-actions github-actions released this 15 Oct 02:27
9ff9634

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 carry status and retry_after on oauth.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 as fallback_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

Choose a tag to compare

@github-actions github-actions released this 12 Oct 00:10

Highlights

  • Arabic (ar) locale, Garrul's first right-to-left language. The widget sets its direction from the locale. Select it with data-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: hono 4.13.13, marked 18.1.0, wrangler 4.149.0. The wrangler bump moves the dev-only sharp to 0.35.5 (GHSA-wq5f-xc86-pv6w); it never reached the Worker runtime.
  • marked 18.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

Choose a tag to compare

@github-actions github-actions released this 06 Oct 19:07

Highlights

  • npm run upgrade now 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_TOKEN if you hit the 60/hour unauthenticated limit.