stillship

Most active software this week.

Fresh release data calculated from Stillship's tracked changelogs.

Swcv1.16.18 ↗2026-10-11
SupabaseStatus page moves to incident.io Oct 8, 2026 Improvement status.supabase.com now runs on incident.io's status page. The URL is unchanged. Email subscribers were resubscribed automatically. If you subscribed through SMS, Slack, webhook, or RSS, those subscriptions did not carry over. Resubscribe at status.supabase.com . The new platform supports only Email, RSS, and Slack, so SMS and webhook notifications are no longer available. Email subscribers can now subscribe to the specific Products and Regions that matter most to them, so they only hear about incidents that affect them. Website Scoped personal access tokens are now generally available Oct 6, 2026 New Feature Scoped personal access tokens (PATs) are now available to everyone. You can limit a token to specific projects or organizations and grant only the permissions it needs. You pick a token's access when you create it # On your access tokens page , choose: Resources: selected projects in one organization, or all projects in selected organizations. Permissions: read or read-write per capability, such as projects, database, auth, or storage. Expiry: a preset or a custom date up to one year out. A review step shows the access you're granting and a risk level. You see the token value only when you create it. You can't change a token's access later. To change it, delete the token and create a new one. A token never has more access than you do. Every request checks your current role. When you lose access, so does the token. Scoped tokens work with the Management API, MCP server, and CLI # Management API: all /v1 and /v2 endpoints. A 403 lists the permissions the token lacks in a missing_permissions array. Supabase MCP server: each tool checks the token's permissions. The token's detail view in the dashboard lists the tools it can call. Supabase CLI: pass the token with supabase login --token or set SUPABASE_ACCESS_TOKEN . The browser flow for supabase login still creates an account-level token. supabase whoami doesn't work with project- or organization-scoped tokens. Some access needs a specific permission. Revealing secret API keys needs API Key Secrets. SQL runs read-only unless the token has Database read-write. The personal access tokens docs map each permission to its endpoints and MCP tools. Your existing tokens keep working # We aren't revoking anything. Every existing token works until it expires or you delete it. You can still create an account-level token with "Create legacy token". A leaked scoped token exposes far less. GitHub secret scanning detects both kinds. Replace your account-level tokens with scoped ones # Swap each account-level token for a scoped token that has only the access its integration needs. If you're missing a permission or the form doesn't fit your workflow, tell us in the GitHub Discussion for this entry. Platform Security CLI AI Organization invites support the No access role Oct 5, 2026 Improvement Admins on Team and Enterprise plans can now invite organization members with the No access role directly from the invite flow and can switch an existing member to it. Previously, the lowest available organization role was Read-only, which still granted visibility into every project in the organization. With No access, new members start with no project access; admins grant access to individual projects as needed. No access can only be assigned at the organization level, not per project, so project access is still layered on top of it one project at a time. Members with the No access role now also show up in the organization's member list - they were previously filtered out. See Access control for the full set of organization and project roles. Platform Studio Security 2026 2026 Deprecation Framework adapters in @supabase/server are deprecated ↗2026-12-01
CloudflareIntroducing Clef: Cloudflare's first open-source decision models, now on Workers AI Workers AI Meet @cf/cloudflare/clef and @cf/cloudflare/clef-flash , the first models trained by the Cloudflare Workers AI team, available on Workers AI today. Clef is a decision model, in the same family as Typesafe's Jev ↗︎ . Instead of generating text, it reads an input state and a set of typed questions, then returns a probability for every allowed answer. Your agent gets a structured decision it can act on immediately, for example: route the ticket, block the request, or escalate to a human. There is no free-form output to parse and no reasoning tokens to wait for. Both models are hosted on Workers AI as Clef and Clef-flash . We are also open-sourcing the weights under the Apache 2.0 license on Hugging Face: Clef ↗︎ and Clef-flash ↗︎ . Read the launch blog post ↗︎ for the full story, including how we trained them. We are also launching a reinforcement learning (RL) fine-tuning service to help you tune Clef for your own workloads. Sign up to work with us as a design partner ↗︎ . Built for the hot path Clef is designed to be fast so decisions come back in milliseconds. Across our 43 benchmark runs, we achieved speeds where Clef is 2.5x faster than Jev at the median, and Clef-flash 13x faster. Latency Clef Clef-flash Jev Median 209.3 ms 38.8 ms 524.1 ms p95 238.6 ms 122.4 ms 536.0 ms Hosting on Workers AI adds to that speed. Requests run on GPUs across Cloudflare's network, running close to your users, so the network round trip stays short. You can put Clef directly in the request path of your agent, then hand off to an LLM on Workers AI to take action. Leading the benchmarks Across 10 decision benchmarks, a Clef model scores highest on 7, ahead of Jev and other open decision models. A few highlights: Benchmark Clef Clef-flash Jev BFCL (case exact) 98.47 98.76 95.75 BANKING77 (macro-F1) 94.20 90.93 79.74 CLINC150+OOS (macro-F1) 97.43 66.77 89.27 Home appliances (case exact) 82.95 97.73 52.27 On Typesafe's own workflow evals, Clef beats Jev in 3 of 4 areas: invoice processing, customer service, and security incidents. The full results are on the Hugging Face model card ↗︎ . Drop-in compatible with Jev Model Size Best for Context window @cf/cloudflare/clef 27B Highest-precision decisions 64K tokens @cf/cloudflare/clef-flash 9B Latency-critical, hot-path decisions 64K tokens Clef follows the System One API, so you can switch an existing Jev integration to Clef by changing the endpoint and model. Ask up to 64 questions per request, in three types: noul : A yes/no question. Returns the probability that the answer is yes. choice : Pick one option from a set you define. Returns the chosen option, a probability per option, and a confidence value. score : Rate against an ordered rubric. Returns a probability-weighted score and a probability per level. const response = await env. AI . run ( "@cf/cloudflare/clef" , { model: "clef" , state: "Checkout has been failing for every customer for the last hour." , questions: { urgent: { type: "noul" , instructions: "Is this support request urgent?" , }, team: { type: "choice" , instructions: "Which team should handle this request?" , criteria: { billing: "Payments, invoices, and refunds" , technical: "Outages, errors, and configuration" , sales: "Plans and upgrades" , }, }, }, }); // response.answers.urgent.noul -> probability the request is urgent // response.answers.team.choice -> highest-probability team const response = await env. AI . run ( "@cf/cloudflare/clef" , { model: "clef" , state: "Checkout has been failing for every customer for the last hour." , questions: { urgent: { type: "noul" , instructions: "Is this support request urgent?" , }, team: { type: "choice" , instructions: "Which team should handle this request?" , criteria: { billing: "Payments, invoices, and refunds" , technical: "Outages, errors, and configuration" , sales: "Plans and upgrades" , }, }, }, }); // response.answers.urgent.noul -> probability the request is urgent // response.answers.team.choice -> highest-probability team What you can build with decision models Support triage : Decide whether a ticket is urgent and which team owns it, then route it without a human in the loop. Threat intelligence : Classify a website by category. Paired with Browser Run , Clef fetched, rendered, and classified a domain in 2.2 seconds, compared to 4.7 seconds for gpt-oss-120b in the same workflow. Trust and safety : Score user submissions against your own policy rubric and act on the probability. Agent guardrails : Let an agent check "should I take this action?" in tens of milliseconds before calling a tool. Visual classification : Pass up to four images alongside the state. Unlike text-only decision models, Clef has a vision encoder. Get started Use Clef through the Workers AI binding ( env.AI.run() ) or the REST API at /ai/run . You can also use AI Gateway with these endpoints. For more information, refer to the Clef model page , the Clef-flash model page , and pricing . Oct 1, 2026 The best way to do MCP auth just got better: Workers OAuth Provider goes v1, with a new split API and full support for MCP 2026-07-28 Agents Workers @cloudflare/workers-oauth-provider ↗︎ is now v1, with a new split API. One Worker acts as the authorization server: it signs users in and issues tokens. Your MCP server acts as the resource server, and can run in another Worker. It validates each token with the authorization server over a Service Binding , without crossing the public Internet. It supports the MCP 2026-07-28 authorization specification ↗︎ , including Client ID Metadata Documents ↗︎ and issuer identification ↗︎ . It still works with older clients, including those using Dynamic Client Registration ↗︎ . insufficientScope() gives you step-up authorization ↗︎ in one line. The authorization server and the resource server can run in different Workers ↗︎ with different WAF and rate limiting rules. One authorization server can issue tokens for many MCP servers ↗︎ . A migration skill ↗︎ ships in the npm package so a coding agent can perform the upgrade. The split API import { OAuthAuthorizationServer, OAuthResourceServer, insufficientScope, } from "@cloudflare/workers-oauth-provider" ; import { WorkerEntrypoint } from "cloudflare:workers" ; // auth-server Worker: signs users in and issues tokens for both MCP servers. const authorizationServer = new OAuthAuthorizationServer ({ issuer: "https://auth.example.com" , resources: [ "https://calendar.example.com/mcp" , "https://drive.example.com/mcp" , ], scopesSupported: [ "calendar:read" , "calendar:write" , "offline_access" ], clientIdMetadataDocumentEnabled: true , }); export class AuthServer extends WorkerEntrypoint { fetch ( request ) { if ( new URL (request.url).pathname === "/authorize" ) { return showConsent (request, this .env); } return authorizationServer. fetch (request, this .env, this .ctx); } validateToken ( resource , token ) { return authorizationServer. validateToken (resource, token, this .env); } } // calendar MCP Worker: checks tokens with AuthServer over a Service Binding. export const calendar = new OAuthResourceServer ({ resourceMetadata: { resource: "https://calendar.example.com/mcp" , authorization_servers: [ "https://auth.example.com" ], }, requiredScopes: [ "calendar:read" ], validateToken : ( env ) => env. AUTH_SERVER .validateToken, handler: { fetch ( request , env , ctx ) { if ( request.method === "POST" && ! ctx.auth.scope. includes ( "calendar:write" ) ) { return insufficientScope (ctx.auth, [ "calendar:read" , "calendar:write" ]); } return handleMcp (request, ctx.props); }, }, }); import { OAuthAuthorizationServer, OAuthResourceServer, insufficientScope, } from "@cloudflare/workers-oauth-provider" ; import { WorkerEntrypoint } from "cloudflare:workers" ; // auth-server Worker: signs users in and issues tokens for both MCP servers. const authorizationServer = new OAuthAuthorizationServer < Env >({ issuer: "https://auth.example.com" , resources: [ "https://calendar.example.com/mcp" , "https://drive.example.com/mcp" , ], scopesSupported: [ "calendar:read" , "calendar:write" , "offline_access" ], clientIdMetadataDocumentEnabled: true , }); export class AuthServer extends WorkerEntrypoint < Env > { fetch ( request : Request ) { if ( new URL (request.url).pathname === "/authorize" ) { return showConsent (request, this .env); } return authorizationServer. fetch (request, this .env, this .ctx); } validateToken ( resource : string , token : string ) { return authorizationServer. validateToken (resource, token, this .env); } } // calendar MCP Worker: checks tokens with AuthServer over a Service Binding. export const calendar = new OAuthResourceServer < Env , AuthProps >({ resourceMetadata: { resource: "https://calendar.example.com/mcp" , authorization_servers: [ "https://auth.example.com" ], }, requiredScopes: [ "calendar:read" ], validateToken : ( env ) => env. AUTH_SERVER .validateToken, handler: { fetch ( request , env , ctx ) { if ( request.method === "POST" && ! ctx.auth.scope. includes ( "calendar:write" ) ) { return insufficientScope (ctx.auth, [ "calendar:read" , "calendar:write" ]); } return handleMcp (request, ctx.props); }, }, }); In the example, env.AUTH_SERVER.validateToken is that Service Binding call. The calendar Worker needs no KV namespace of its own. { "name" : "calendar-mcp" , "main" : "src/index.ts" , // Set this to today's date "compatibility_date" : "2026-10-01" , "services" : [ { "binding" : "AUTH_SERVER" , "service" : "auth-server" , "entrypoint" : "AuthServer" , }, ], } name = "calendar-mcp" main = "src/index.ts" # Set this to today's date compatibility_date = "2026-10-01" [[ services ]] binding = "AUTH_SERVER" service = "auth-server" entrypoint = "AuthServer" OAuthResourceServer publishes the RFC 9728 ↗︎ protected resource metadata that MCP clients use to find your authorization server. It answers requests without a token with a 401 challenge that points to that metadata. It also rejects tokens issued for any other resource. You can still use OAuthProvider as both the authorization server and the MCP server. For most 0.x deployments, the only required change is to add resourceMetadata: { resource } . Other updates and helpers Consent page ↗︎ and upstream sign-in ↗︎ helpers implement the MCP confused deputy protections. Sliding refresh token expiry ↗︎ with refreshTokenIdleTTL . Resumable KV cleanup ↗︎ with purgeExpiredData() . An internal reason ↗︎ on every error passed to onError . Upgrade with the migration skill if (!customElements.get("nb-pm-restore")) { customElements.define( "nb-pm-restore", class extends HTMLElement { connectedCallback() { const card = this.closest("[data-nb-pm]"); if (!card) return; let saved; try { saved = sessionStorage.getItem("ui-pm-tab"); } catch { return; } if (!saved) return; const tabs = card.querySelectorAll("[data-nb-pm-tab]"); let idx = -1; tabs.forEach(function (t, i) { if (t.textContent.trim() === saved) idx = i; }); if (idx npm yarn pnpm bun npm i @cloudflare/workers-oauth-provider@latest yarn add @cloudflare/workers-oauth-provider@latest pnpm add @cloudflare/workers-oauth-provider@latest bun add @cloudflare/workers-oauth-provider@latest Point your coding agent at node_modules/@cloudflare/workers-oauth-provider/skills/migrate-to-1.0/SKILL.md , or follow the migration guide ↗︎ . For both Workers in full, refer to the split Workers example ↗︎ . Oct 1, 2026 AI Search is generally available ↗2026-11-01

Older →