Skip to content
Docs

Command palette

Jump to a page or view, or find a todo by name.

Changelog

Changelog

New features, architectural changes and improvements to the template.

MarkdownRSS

Release notes are curated from repository history. Dates reflect integration into the main branch; grouped entries are not semantic-version tags. Each entry links to its implementation and current developer guide.

Better Auth 1.7.16 security fix and dependency round

Better Auth 1.7.16 closes a critical account takeover through the Expo authorization proxy, the iPhone Duo tab bar becomes a rail, and the dependency round brings Effect 4.1, Takumi 2.19, oRPC beta.48 and Expo SDK 58 patches.

Better Auth moves to 1.7.16. Its expo() plugin, which the template registers for the native app, exposed an authorization proxy that signed a value taken from the request with the application secret (GHSA-4wq4-2ppv-q3hg, critical): anyone who knew an account's email address could forge a verification link and sign in as that user. The same release stops an organization admin from inviting an owner through a role name with extra whitespace (GHSA-c85h-5mrr-mgx4). The other ten advisories of that release need plugins or options the template does not use. The release was under two days old, so its exact versions sit in minimumReleaseAgeExclude until 2026-11-05 21:24 UTC. A project created from the template that has been deployed should upgrade and then rotate BETTER_AUTH_SECRET; with users and two-factor enabled, pass the new secret in secrets and keep the old one as BETTER_AUTH_SECRET, so stored TOTP secrets still decrypt.

On iPhone Duo, built with the iOS 27.1 SDK, the native tabs become a vertical rail beside the content when the device is folded or open in landscape. Screens read the rail from the side safe-area insets and stop reserving space for a bottom bar, the bar is no longer cleared twice when the safe area already reaches it, and the app imports NativeTabs from the stable expo-router/native-tabs path.

The dependency round moves Expo to the SDK 58.0.22 patches, Effect to 4.1.2 (the ADR-0006 fault gate gives the same result as 4.0.6), Takumi to 2.19.0 with a new OG_VERSION, oRPC to 2.0.0-beta.48, TanStack AI to 1.0.1, wrangler to 4.156.1 and a set of patch releases. The Worker is 78 KiB gzip larger.

Sources: Better Auth 1.7.16, Expo patches, iPhone Duo rail, Effect 4.1.2, Takumi 2.19.

Invitations are not a mail relay

Invitation emails carry a fixed subject and attributed, link-free user text; only verified owners and admins may send, with daily caps and a rate limit; Reply-To and one product name for every email.

Organization invitations could be used as an open relay: any signed-in account could create an Organization and make the app mail any address, with the Organization name as the subject. The subject is now a constant built from the product name, and the inviter's and Organization's names appear in the body as attributed plain text (Name (verified address) invited you to join the organization "…"), HTML-escaped, length-capped and with link-shaped tokens defanged so no client auto-links them. Every template applies the same treatment to names, and the security notice prints a readable UTC timestamp (Email, commit e951425).

Sending now requires a verified inviter email even when AUTH_SKIP_EMAIL_VERIFICATION is true, and is limited to 20 invitations per inviter and 50 per Organization per rolling day, 50 pending invitations per Organization, and 10 invite-member requests per 10 minutes per client IP. The default owner, admin and member roles are written down in the plugin configuration. Refusals are typed codes translated in en, de and fr (Authentication and Organizations, commit 88e8671). The web invite dialog and the mobile invite group show the verify-your-email state with a button that sends the verification email (commit b9e63fd).

EMAIL_REPLY_TO sets a Reply-To on every message through the Worker binding, Cloudflare REST and Resend, and the product name every email prints comes from EMAIL_FROM's display name; the hard-coded fallback is gone. The email guide documents the SPF, DKIM and DMARC records the sending domain needs for either provider (commit 8f90bc5).

MCP Apps widget, approval status and plugin marketplaces

The todo widget runs the MCP Apps handshake so Claude and ChatGPT render it, agents can read the outcome of an approval and follow an absolute link to it, the server announces instructions and annotations, and the agent plugin installs from Claude Code, Codex, Cursor and Grok with production URLs.

The todo_list widget now renders in hosts that follow the MCP Apps specification. The view performs the ui/initialize → ui/notifications/initialized handshake the specification requires before a host may send tool data, then renders ui/notifications/tool-result; it keeps reading window.openai.toolOutput for ChatGPT builds that still inject it. There is one resource, ui://widget/todos/v2 with text/html;profile=mcp-app and an explicit empty CSP; openai/outputTemplate is the ChatGPT alias of _meta.ui.resourceUri and points at the same URI, so the text/html+skybridge duplicate is gone. A jsdom harness plays the host side in the test suite.

The MCP server says what it is. initialize names it after the OAuth issuer host instead of the template, returns instructions that summarize the approval flow, and declares listChanged: false for tools, resources and prompts, since a server built per request never notifies. Every tool sets all four annotations (reads are read-only and idempotent; nothing is destructive or open-world) and write tools publish the approval envelope as their outputSchema.

Agents can follow an approval to its end. A write call returns an absolute approvalUrl, /integrations?approval=<id> on the deployment that served it, which opens Integrations on that record. The new read-only approval_status tool reports whether the user executed (with the stored result), denied or let the request expire; the catalog has sixteen tools. The OAuth provider offers the email scope so UserInfo returns email and email_verified, and /.well-known/openai-apps-challenge serves the OPENAI_APPS_CHALLENGE_TOKEN Worker var during an OpenAI plugin review (404 while unset).

The agent plugin package is installable again. The Cursor and Grok marketplaces pointed at a folder that had been renamed, every manifest used the workers.dev origin instead of the production domain, and plugin.json carried a top-level logo the Agent Plugins 1.0.0 schema rejects. Listing copy and logo moved under extensions["com.openai"].interface, mcp.json declares the OAuth client, and new .claude-plugin/marketplace.json and .agents/plugins/marketplace.json files make it installable from Claude Code, the ChatGPT desktop app and Codex. The connection guide describes ChatGPT's current path, chatgpt.com/plugins → + → Add custom MCP server.

Sources: widget and server, approval status, challenge route and email scope, plugin marketplaces.

Earlier releases

Edit on GitHubDocumentation is in English.