Releases: QuackbackIO/quackback
Releases · QuackbackIO/quackback
v0.6.8
v0.6.7
v0.6.6
New Features
- Markdown rendering for changelogs and posts - Content created via the rich text editor, MCP, or API now stores markdown alongside TipTap JSON. The server auto-derives contentJson from markdown when only plain text is provided, ensuring consistent rendering everywhere
- Redesigned public changelog - The changelog page now displays a full-article feed with a date sidebar, rendered rich content, and linked feature cards, similar to a blog layout
Bug Fixes
- Fix list item spacing in rendered content - Ordered and unordered lists no longer have excessive whitespace between items. Fixed by unwrapping single-paragraph list items in the HTML renderer
- Remove unsigned cookie from widget identify endpoint - Cleaned up the widget identify endpoint to use only the signed cookie for authentication
- Strip markdown in admin changelog previews - Admin changelog list no longer shows raw markdown syntax in content previews
Improvements
- Refactor service layer into focused modules - Large service files (posts, comments, changelog, settings, users, segments, roadmaps) split into smaller, focused modules for better maintainability
v0.6.5
New Features
- Cascade delete linked integration issues - When deleting a post that has linked issues in external platforms, the delete dialog now shows each linked issue with a checkbox to archive/close it. Supports Linear, GitHub, Jira, GitLab, ClickUp, Asana, Shortcut, Azure DevOps, Trello, Notion, and Monday. Integration icons and human-friendly issue identifiers (e.g. QUA-24, #142) are shown in the dialog
- Per-integration on-delete behavior config - Each integration's settings page now has an "On post delete" option to control whether linked issues are archived/closed by default
Bug Fixes
- Fix dark theme flicker on admin pages - Admin pages no longer flash white on load in dark mode. Theme is now read from a server-side cookie instead of client-side detection
- Remove static vote count from integration syncs - Vote count was included in synced issue descriptions but never updated after creation, showing a misleading frozen value. Removed from all integration message builders (Linear, GitHub, Jira, GitLab, ClickUp, Asana, Shortcut, Azure DevOps, Zapier)
v0.6.4
Performance
- MCP search response trimming - Search results now return 200-char excerpts instead of full content, extract just the summary string instead of the full summaryJson object, and use compact JSON encoding for list responses - reducing payload from ~170KB to ~40KB per 100-post page
- Database column selection for post lists - listInboxPosts now excludes unused heavy columns (embedding at ~12KB/row, searchVector, widgetMetadata, and pipeline metadata), reducing DB transfer from ~1.4MB to ~200KB per 100-post query
- Exclude internal fields from all post queries - getPostWithDetails and listPostsForExport now use explicit column selection, preventing ~12KB of embedding data per row from being transferred on detail, admin, and export paths
Bug Fixes
- Portal post edit view matches read-only view - Empty paragraphs in the TipTap editor now collapse to match the static prose rendering, fixing the excessive vertical spacing visible in edit mode. Edit title input also matches the normal h1 sizing
- Fix MCP OAuth posts showing 'Unknown' author - OAuth JWT was missing name and email claims, causing all MCP-created posts to show "Unknown" as the author. Users need to re-authenticate for the fix to take effect
v0.6.3
Performance
- Dragonfly caching for hot paths - Tenant settings, integration event mappings, and active webhooks are now cached in Dragonfly with 5-minute TTL and write-through invalidation, eliminating redundant DB queries on every page load and event dispatch
- Slack channel cache migrated to shared helpers - Unified caching pattern across all cached resources
Improvements
- Robust cache failure logging - Cache helpers log warnings on failure instead of silently swallowing errors, improving production debuggability
- S3 deletion failure logging - Previously silent catch blocks in logo/favicon/header logo operations now log warnings with the affected S3 key
- Better embedding error context - OpenAI embedding failures now include pipeline step and post ID for easier triage
- Reduced log noise - Removed ~25 noisy read-path console.log entries from domain services (settings, statuses, posts, comments, roadmaps, subscriptions, notifications, webhooks) that fired on every request
v0.6.2
Improvements
- Private comments - Notes are now consolidated as private comments with MCP
isPrivatesupport - Event system completeness - Added missing event types and improved private comment UX
- Slack channel listing - Improved Slack channel listing and incoming feedback UX
Bug Fixes
- Fix widget vote/reaction highlights after SSO identify - Vote and reaction highlights now persist correctly after SSO identify in the widget
- Fix vote and reaction highlights after page reload - Highlights no longer reset when the page is reloaded
- Fix Canny importer issues - Fixed soft-delete filtering and publishedAt preservation
Chores
- Upgrade to Vite 8 and @vitejs/plugin-react 6
- Update all dependencies to latest compatible versions
- Type safety improvements
- CI: run build before typecheck to generate route tree
v0.6.1
New Features
- API extensions and Canny adapter - New API-to-API import pipeline with a Canny adapter for migrating feedback, votes, comments, and users from Canny to Quackback.
Bug Fixes
- Fix OAuth token exchange 500 for MCP clients - The token endpoint consumed the request body to inspect the
resourceparameter but only reconstructed it whenresourcewas missing. MCP clients like Claude Code that includeresourcein the token exchange hit a 500 because Better Auth received an empty body. The request is now always reconstructed after reading. - Fix consent page redirect - Added
data.urlfallback for OAuth consent redirect URL resolution, fixing cases where the redirect field name varied.
Database
- OAuth schema migration - Added
require_pkcecolumn tooauth_clientandauth_timecolumn tooauth_refresh_tokenfor Better Auth compatibility.
v0.6.0
New Features
- Anonymous voting - Users can upvote posts without signing in. Controlled by a per-workspace feature flag (enabled by default). IP-based rate limiting prevents abuse by counting anonymous sessions per IP.
- Anonymous posting - Users can submit feedback without an account. Controlled by a workspace feature flag (disabled by default). Anonymous sessions are created lazily via Better Auth's anonymous plugin.
- Anonymous commenting - Users can comment on posts without signing in. Controlled by a workspace feature flag (disabled by default).
- Workspace permissions page - New admin settings page under Settings > Permissions to toggle anonymous voting, posting, and commenting per workspace.
- Widget post detail view - Full post detail with voting, comments, threaded replies, status badge, author name, and relative timestamps inside the embedded widget.
- Widget SDK event system - Host apps can subscribe to widget events (vote, post:created, comment:created, identify) via Quackback('on', eventName, handler). Supports on/off commands and returns unsubscribe functions.
- Widget metadata - Host apps can attach key-value metadata to widget sessions via Quackback('metadata', { key: value }). Metadata is stored on posts created through the widget.
- One-time token session transfer - Widget sessions can be transferred to the portal via secure one-time tokens, so users clicking "View full discussion" arrive already authenticated.
Improvements
- Server-side feature flag enforcement - All three anonymous feature flags are now enforced server-side in toggleVoteFn, createPublicPostFn, and createCommentFn. Previously voting and posting were only gated on the client.
- Widget auth UX - When anonymous features are disabled, vote/comment/post buttons remain fully interactive. Clicking opens the portal (widget) or login dialog (portal) instead of appearing disabled.
- Widget identify requirement - The widget trigger button is now only shown after identify() is called, preventing interaction before the host app establishes an identity.
- Anonymous display names - Anonymous users receive auto-generated friendly display names (e.g. "Blue Falcon") instead of showing raw email addresses.
- Bearer token auth for widget - Widget iframe uses Authorization: Bearer headers instead of cookies for cross-origin compatibility.
- Rate limit hardening - Anonymous vote rate limiting now counts sessions per IP instead of active vote rows, preventing vote/unvote toggle bypass.
- Widget scroll behavior - Post detail view scrolls to top when navigating between posts.
- Memoized widget context - WidgetAuthContext value is memoized to prevent unnecessary consumer re-renders.
- Dofollow powered-by backlinks - "Powered by Quackback" links in the widget and feedback board are now dofollow for SEO value.
Bug Fixes
- Anonymous posting feature flag was dead code - The anonymousPosting check in createPublicPostFn was inside a branch that was never reached because anonymous users always have a principal record. Moved the check to run unconditionally.
- Anonymous voting had no server-side check - toggleVoteFn had zero feature flag enforcement. Any user with an anonymous session could vote regardless of the setting.
- Widget user state not cleared on anonymous switch - Switching from an identified session to anonymous via identify({ anonymous: true }) did not reset isIdentified, causing the widget to continue treating the user as signed in.
- SDK listeners not cleared on destroy - Calling Quackback('destroy') did not clear event listeners, causing memory leaks on re-initialization.
v0.5.1
New Features
- Vote removal for admins - Admins can remove any vote (direct or proxy) from the voters modal on a post. Hover over a voter row to reveal the remove button.
- Proxy vote MCP tool - AI agents can add votes on behalf of users via the new proxy_vote tool (22 to 23 MCP tools total).
- Proxy vote DELETE endpoint - Remove proxy votes via the REST API at DELETE /api/v1/posts/:id/vote with OpenAPI docs.
Improvements
- Widget SDK simplification - Icon-only trigger button replaces the old text button. Removed buttonText option for a cleaner, more compact widget launcher.
- Widget shell redesign - Added close button to the home screen and simplified the panel layout.
- Widget settings overhaul - Two-column layout with live preview panel, dark syntax-highlighted code blocks, pill selectors for placement and board, and copy-to-clipboard embed snippets.
- MCP setup guide overhaul - Interactive client selector with SVG icons for Claude Code, Cursor, VS Code, Windsurf, and Claude Desktop. Dark code panels with syntax highlighting, OAuth/API key variant toggle, and tools badge summary.
- API Keys settings redesign - Replaced static docs card with an interactive Quick Start guide showing multi-language code examples (curl, JavaScript, Python, Go, PHP) with syntax highlighting, base URL copy, and API resources summary.
- Webhooks settings redesign - Replaced static docs card with an interactive signature verification guide showing HMAC-SHA256 verification code in 5 frameworks (Node.js, Python, Ruby, Go, PHP), webhook headers reference, and event badges.
- Signal embedding improvement - Embedding format now matches post structure for better similarity matching.
- Admin UI polish - Unified border opacity and card styling across all admin list views. Redesigned notifications and getting started pages.