Merge branch 'dev' into fix-agent-prompt-caching

This commit is contained in:
Mantra 2026-04-14 09:22:05 -07:00 committed by GitHub
commit 04f463543f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
37 changed files with 467 additions and 223 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/backend",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"private": true,
"type": "module",
@ -98,7 +98,7 @@
"jiti": "^2.6.1",
"jose": "^6.1.3",
"json-diff": "^1.0.6",
"next": "16.1.5",
"next": "16.2.2",
"nodemailer": "^6.9.10",
"oidc-provider": "^8.5.1",
"openid-client": "5.6.4",

View File

@ -1,4 +1,5 @@
import { sendSupportFeedbackEmail } from "@/lib/internal-feedback-emails";
import { isLocalEmulatorEnabled } from "@/lib/local-emulator";
import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler";
import { DEFAULT_BRANCH_ID, getSoleTenancyFromProjectBranch } from "@/lib/tenancies";
import { adaptSchema, emailSchema, yupBoolean, yupNumber, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields";
@ -45,7 +46,7 @@ export const POST = createSmartRouteHandler({
async handler({ auth, body }) {
// Forward to production in local emulator (same pattern as AI query endpoint)
const feedbackMode = getEnvVariable("STACK_FEEDBACK_MODE", "email");
if (feedbackMode === "FORWARD_TO_PRODUCTION") {
if (feedbackMode === "FORWARD_TO_PRODUCTION" && isLocalEmulatorEnabled()) {
const prodResponse = await fetch("https://api.stack-auth.com/api/latest/internal/feedback", {
method: "POST",
headers: { "content-type": "application/json", "accept-encoding": "identity" },

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/dashboard",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"private": true,
"scripts": {
@ -84,7 +84,7 @@
"input-otp": "^1.4.1",
"jose": "^6.1.3",
"lodash": "^4.17.21",
"next": "16.1.5",
"next": "16.2.2",
"next-themes": "^0.2.1",
"posthog-js": "^1.336.1",
"react": "19.2.3",

View File

@ -1630,9 +1630,9 @@ function Draggable(props: {
<div className="text-red-500 text-sm p-2 bg-red-500/10 font-mono whitespace-pre-wrap">
A runtime error occured while rendering this widget.<br />
<br />
{props.reset && <button className="text-blue-500 hover:underline" onClick={() => {
props.reset!();
}}>Reload widget</button>}<br />
<button className="text-blue-500 hover:underline" onClick={() => {
props.reset();
}}>Reload widget</button><br />
<br />
{errorToNiceString(props.error)}
</div>

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/dev-launchpad",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"private": true,
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/e2e-tests",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"private": true,
"type": "module",

View File

@ -1,32 +1,10 @@
import { randomUUID } from "crypto";
import { describe } from "vitest";
import { it } from "../../../../../helpers";
import { Auth, backendContext, createMailbox, niceBackendFetch, waitForOutboxEmailWithStatus } from "../../../../backend-helpers";
/**
* Probe the backend to detect whether it's forwarding feedback to production.
* Cached so we only make one probe request per test run.
*/
let cachedIsForwarding: boolean | null = null;
async function isForwardingToProduction(): Promise<boolean> {
if (cachedIsForwarding !== null) return cachedIsForwarding;
const probe = await niceBackendFetch("/api/v1/internal/feedback", {
method: "POST",
body: {
email: "probe@test.stack-auth.com",
message: "mode detection probe",
},
});
// When forwarding, production rejects and we get a non-200 with "forward" in the body
cachedIsForwarding = probe.status !== 200;
return cachedIsForwarding;
}
describe("POST /api/v1/internal/feedback", () => {
it("should send feedback from an authenticated user", async ({ expect }) => {
if (await isForwardingToProduction()) {
return; // forwarding mode — probe already verified endpoint is reachable
}
const senderEmail = backendContext.value.mailbox.emailAddress;
const signInResult = await Auth.Otp.signIn();
const recipientMailbox = createMailbox("team@stack-auth.com");
@ -67,18 +45,15 @@ describe("POST /api/v1/internal/feedback", () => {
});
it("should send feedback without authentication (dev tool)", async ({ expect }) => {
if (await isForwardingToProduction()) {
return;
}
const recipientMailbox = createMailbox("team@stack-auth.com");
const subject = "[Support] devtool-user@example.com";
const senderEmail = `devtool-user-${randomUUID()}@example.com`;
const subject = `[Support] ${senderEmail}`;
const response = await niceBackendFetch("/api/v1/internal/feedback", {
method: "POST",
body: {
name: "Dev Tool User",
email: "devtool-user@example.com",
email: senderEmail,
message: "Unauthenticated feedback from the dev tool.",
feedback_type: "feedback",
},
@ -102,22 +77,19 @@ describe("POST /api/v1/internal/feedback", () => {
const messages = await recipientMailbox.waitForMessagesWithSubject(subject);
expect(messages).toHaveLength(1);
expect(messages[0].body?.text).toContain("Dev Tool User");
expect(messages[0].body?.text).toContain("devtool-user@example.com");
expect(messages[0].body?.text).toContain(senderEmail);
expect(messages[0].body?.text).toContain("Unauthenticated feedback from the dev tool.");
});
it("should send bug reports with correct label", async ({ expect }) => {
if (await isForwardingToProduction()) {
return;
}
const recipientMailbox = createMailbox("team@stack-auth.com");
const subject = "[Bug Report] bug@example.com";
const reporterEmail = `bug-${randomUUID()}@example.com`;
const subject = `[Bug Report] ${reporterEmail}`;
const response = await niceBackendFetch("/api/v1/internal/feedback", {
method: "POST",
body: {
email: "bug@example.com",
email: reporterEmail,
message: "Something is broken.",
feedback_type: "bug",
},
@ -140,7 +112,7 @@ describe("POST /api/v1/internal/feedback", () => {
const messages = await recipientMailbox.waitForMessagesWithSubject(subject);
expect(messages).toHaveLength(1);
expect(messages[0].subject).toBe("[Bug Report] bug@example.com");
expect(messages[0].subject).toBe(subject);
});
it("should reject invalid payloads", async ({ expect }) => {

View File

@ -1,7 +1,7 @@
{
"name": "@stackframe/hosted-components",
"private": true,
"version": "2.8.82",
"version": "2.8.83",
"type": "module",
"scripts": {
"dev": "vite dev --port ${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}09",

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/mock-oauth-server",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"private": true,
"main": "index.js",

View File

@ -258,3 +258,9 @@ A: The app link wrapper in `docs-mintlify/snippets/docs-apps-home-grid.jsx` used
Q: How should the sidebar Apps filter behave when there are no matches?
A: In `docs-mintlify/snippets/docs-apps-home-grid.jsx`, track visible rows while filtering and show a small inline empty state (`No more results. Clear filter`) when query is non-empty and visible count is zero; wire `Clear filter` to reset the input, rerun filtering, and refocus the input.
Q: Why did internal feedback E2E tests expect 1 Inbucket message but get 2?
A: Inbucket persists mail across runs. `Mailbox.waitForMessagesWithSubject` waits until at least one match then returns **all** messages whose subject includes the string. Fixed subjects like `[Support] devtool-user@example.com` accumulate, so assertions should use a unique subject per run (e.g. `randomUUID()` in the sender email) or a baseline count before/after.
Q: Why does `@typescript-eslint/no-unnecessary-condition` fire on `props.reset` in Next.js `ErrorBoundary` `errorComponent`?
A: Nexts typings treat `reset` as always present on the error component props, so `props.reset &&` is redundant; render the reload control unconditionally and call `props.reset()` directly.

View File

@ -80,8 +80,6 @@ RUN cp -a /app/node_modules /pruned-node_modules && \
posthog-js@* \
@prisma+studio-core@* @prisma+dev@* @prisma+query-plan-executor@* \
convex@* @electric-sql+*@* \
# Duplicate Next.js copies (keep only one for next/headers.js resolution)
'next@16.1.5_@babel+core@7.29.0*' 'next@16.1.5_@babel+core@7.28.5*' \
next@14* @next+swc-*@14* \
# Native build binaries not needed at runtime
@esbuild+*@* esbuild@* @rolldown+*@* \

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/docs-mintlify",
"version": "2.8.82",
"version": "2.8.83",
"private": true,
"scripts": {
"dev": "mint dev --port ${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}04 --no-open",

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/stack-docs",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"description": "",
"main": "index.js",

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/example-cjs-test",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"private": true,
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/convex-example",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"private": true,
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/example-demo-app",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"description": "",
"private": true,

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/docs-examples",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"description": "",
"private": true,

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/e-commerce-demo",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"private": true,
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/js-example",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"private": true,
"description": "",

View File

@ -1,7 +1,7 @@
{
"name": "@stackframe/lovable-react-18-example",
"private": true,
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"type": "module",
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/example-middleware-demo",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"private": true,
"scripts": {

View File

@ -1,7 +1,7 @@
{
"name": "react-example",
"private": true,
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"type": "module",
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/example-supabase",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"private": true,
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/dashboard-ui-components",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/init-stack",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"description": "The setup wizard for Stack. https://stack-auth.com",
"main": "dist/index.mjs",

View File

@ -1,7 +1,7 @@
{
"//": "THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template (FOR package.json FILES, PLEASE EDIT package-template.json)",
"name": "@stackframe/js",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"sideEffects": false,
"main": "./dist/index.js",

View File

@ -1,7 +1,7 @@
{
"//": "THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template (FOR package.json FILES, PLEASE EDIT package-template.json)",
"name": "@stackframe/react",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"sideEffects": false,
"main": "./dist/index.js",

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/stack-cli",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"description": "The CLI for Stack Auth. https://stack-auth.com",
"main": "dist/index.js",

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/stack-sc",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"exports": {
"./force-react-server": {

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/stack-shared",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"scripts": {
"build": "rimraf dist && tsdown",

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/stack-ui",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",

View File

@ -1,7 +1,7 @@
{
"//": "THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template (FOR package.json FILES, PLEASE EDIT package-template.json)",
"name": "@stackframe/stack",
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"sideEffects": false,
"main": "./dist/index.js",

View File

@ -11,7 +11,7 @@
"//": "NEXT_LINE_PLATFORM template",
"private": true,
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"sideEffects": false,
"main": "./dist/index.js",

View File

@ -2,7 +2,7 @@
"//": "THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY, INSTEAD EDIT THE CORRESPONDING FILE IN packages/template (FOR package.json FILES, PLEASE EDIT package-template.json)",
"name": "@stackframe/template",
"private": true,
"version": "2.8.82",
"version": "2.8.83",
"repository": "https://github.com/stack-auth/stack-auth",
"sideEffects": false,
"main": "./dist/index.js",

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/swift-sdk",
"version": "2.8.82",
"version": "2.8.83",
"private": true,
"description": "Stack Auth Swift SDK",
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@stackframe/sdk-spec",
"version": "2.8.82",
"version": "2.8.83",
"private": true,
"description": "Stack Auth SDK specification files",
"scripts": {}