Skip to content

Commit d90b345

Browse files
committed
Merge branch 'dev' into codex/tanstack-start-integration
2 parents 35d2c35 + 647883c commit d90b345

92 files changed

Lines changed: 2499 additions & 1576 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/CLAUDE-KNOWLEDGE.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ A: Check the error location:
217217
- Callback endpoint (400 error) - Validation failed during callback
218218
- Token endpoint (400 error) - Validation failed during token exchange
219219

220+
### Q: How should connected-account OAuth access-token refresh errors be classified?
221+
A: In `apps/backend/src/oauth/providers/base.tsx`, invalid/revoked refresh-token provider errors such as `invalid_grant` return `Result.error({ type: "invalid-refresh-token", ... })` so `access-token-helpers.tsx` can invalidate that stored refresh token and try another. Transient provider/network failures such as openid-client `RPError: outgoing request timed out after 3500ms` return `Result.error({ type: "temporarily-unavailable", cause })`; the connected-account helper converts that to `OAuthProviderTemporarilyUnavailable` without invalidating the refresh token. Expected refresh outcomes should be represented in the provider return type instead of thrown as known/status errors. Refresh requests use a 6s openid-client HTTP timeout and retry transient failures once. If a retry sees `invalid_grant` after an ambiguous transient failure, keep treating it as temporarily unavailable rather than invalidating the refresh token, because the first request may have reached the provider and rotated the token before our client timed out. Sentry should capture non-revocation refresh issues (temporary provider failure, invalid client, unexpected) with provider id/class, attempts, retry count, ambiguity state, final cause, and all provider errors seen during attempts; normal revoked/expired refresh tokens should not be reported.
222+
220223
## Git and Development Workflow
221224

222225
### Q: How should you format git commit messages in this project?
@@ -394,3 +397,12 @@ A: The environment override endpoint validates the new environment override agai
394397

395398
## Q: Why can `pnpm run dev` fail with `ERR_MODULE_NOT_FOUND` for `@stackframe/stack/dist/esm/index.js` during OpenAPI docs generation?
396399
A: Root `dev` starts the OpenAPI docs watcher at the same time as package `dev` watchers. If a package `dev` script removes `dist` before `tsdown --watch` recreates it, the docs generator can import `apps/backend/src/stack.tsx` while `@stackframe/stack`'s ESM entrypoint is temporarily missing. Package watch scripts should update `dist` in place, and eager generators should wait for package imports to resolve before running.
400+
401+
## Q: How do SDK source tests replace the compile-time client version sentinel?
402+
A: `packages/template/vitest.config.ts` installs a Vite transform plugin for Vitest that replaces `STACK_COMPILE_TIME_CLIENT_PACKAGE_VERSION_SENTINEL` with `js <package-name>@<version>` from the local package.json. Keep the plugin in `packages/template` so `pnpm pre`/`scripts/generate-sdks.ts` propagates it to `packages/js`, `packages/react`, and `packages/stack`; otherwise tests importing `common.ts` throw `Client version was not replaced` before test collection.
403+
404+
## Q: How does the Mintlify apps sidebar filter stay in sync with theme changes?
405+
A: `docs-mintlify/apps-sidebar-filter.js` injects the Apps filter with inline styles, so the MutationObserver must reapply `applySidebarAppsFilterTheme` when an existing input is found. Theme detection should handle both `html.dark` and `data-theme="dark"` signals.
406+
407+
## Q: How should `StackAssertionError` preserve an underlying thrown error?
408+
A: Pass the underlying error as the `cause` property in the second argument. The `StackAssertionError` constructor only forwards `cause` into `ErrorOptions`, so storing a caught error under an `error` property captures it as ordinary metadata instead of preserving the error cause chain.

.github/workflows/db-migration-backwards-compatibility.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,16 @@ jobs:
169169
wait-for: 30s
170170
log-output-if: true
171171

172+
- name: Start stack-mcp in background
173+
uses: JarvusInnovations/background-action@v1.0.7
174+
with:
175+
run: pnpm run start:mcp --log-order=stream &
176+
wait-on: |
177+
http://localhost:8144/health
178+
tail: true
179+
wait-for: 30s
180+
log-output-if: true
181+
172182
- name: Start stack-dashboard in background
173183
uses: JarvusInnovations/background-action@v1.0.7
174184
with:
@@ -366,6 +376,16 @@ jobs:
366376
wait-for: 30s
367377
log-output-if: true
368378

379+
- name: Start stack-mcp in background
380+
uses: JarvusInnovations/background-action@v1.0.7
381+
with:
382+
run: pnpm run start:mcp --log-order=stream &
383+
wait-on: |
384+
http://localhost:8144/health
385+
tail: true
386+
wait-for: 30s
387+
log-output-if: true
388+
369389
- name: Start stack-dashboard in background
370390
uses: JarvusInnovations/background-action@v1.0.7
371391
with:

.github/workflows/e2e-api-tests-local-emulator.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@ jobs:
119119
tail: true
120120
wait-for: 30s
121121
log-output-if: true
122+
- name: Start stack-mcp in background
123+
uses: JarvusInnovations/background-action@v1.0.7
124+
with:
125+
run: pnpm run start:mcp --log-order=stream &
126+
wait-on: |
127+
http://localhost:8144/health
128+
tail: true
129+
wait-for: 30s
130+
log-output-if: true
122131

123132
- name: Start stack-dashboard in background
124133
uses: JarvusInnovations/background-action@v1.0.7

.github/workflows/e2e-api-tests.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,15 @@ jobs:
125125
tail: true
126126
wait-for: 30s
127127
log-output-if: true
128+
- name: Start stack-mcp in background
129+
uses: JarvusInnovations/background-action@v1.0.7
130+
with:
131+
run: pnpm run start:mcp --log-order=stream &
132+
wait-on: |
133+
http://localhost:8144/health
134+
tail: true
135+
wait-for: 30s
136+
log-output-if: true
128137
- name: Start stack-dashboard in background
129138
uses: JarvusInnovations/background-action@v1.0.7
130139
with:

.github/workflows/e2e-custom-base-port-api-tests.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,15 @@ jobs:
118118
tail: true
119119
wait-for: 30s
120120
log-output-if: true
121+
- name: Start stack-mcp in background
122+
uses: JarvusInnovations/background-action@v1.0.7
123+
with:
124+
run: pnpm run start:mcp --log-order=stream &
125+
wait-on: |
126+
http://localhost:6744/health
127+
tail: true
128+
wait-for: 30s
129+
log-output-if: true
121130
- name: Start stack-dashboard in background
122131
uses: JarvusInnovations/background-action@v1.0.7
123132
with:

apps/backend/.env

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ STACK_SPOTIFY_CLIENT_SECRET=# client secret
3434

3535
STACK_ALLOW_SHARED_OAUTH_ACCESS_TOKENS=# allow shared oauth provider to also use connected account access token, this should only be used for development and testing
3636

37+
STACK_DISABLE_PLAN_LIMITS=# set to "true" to bypass enforcement of Stack Auth's own internal-tenancy plan limits (analytics_events, session_replays, emails_per_month, dashboard_admins seat cap, auth_users soft cap, analytics_timeout_seconds). Default unset/false preserves enforcement. Intended as a temporary cutover safety net while the plan-limits infrastructure rolls out — customer projects' own item APIs are unaffected by this flag.
38+
3739
# Email
3840
# For local development, you can spin up a local SMTP server like inbucket
3941
STACK_EMAIL_HOST=# for local inbucket: 127.0.0.1

apps/backend/.env.development

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ STACK_SPOTIFY_CLIENT_SECRET=MOCK
4343

4444
STACK_ALLOW_SHARED_OAUTH_ACCESS_TOKENS=true
4545

46+
# Default to enforcing plan limits in local dev so behavior matches prod.
47+
# Flip to "true" to bypass every Stack-Auth-internal plan-limit enforcement
48+
# site (e.g. session_replays, analytics_events, emails_per_month). See
49+
# apps/backend/src/lib/plan-entitlements.ts:arePlanLimitsEnforced.
50+
STACK_DISABLE_PLAN_LIMITS=false
51+
4652
STACK_DATABASE_CONNECTION_STRING=postgres://postgres:PASSWORD-PLACEHOLDER--uqfEC1hmmv@localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}28/stackframe
4753
STACK_DATABASE_REPLICA_CONNECTION_STRING=postgres://postgres:PASSWORD-PLACEHOLDER--uqfEC1hmmv@localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}34/stackframe
4854
STACK_DATABASE_REPLICATION_WAIT_STRATEGY=pg-stat-replication

apps/backend/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@stackframe/backend",
33
"version": "2.8.88",
4-
"repository": "https://github.com/stack-auth/stack-auth",
4+
"repository": "https://github.com/hexclave/stack-auth",
55
"private": true,
66
"type": "module",
77
"scripts": {
@@ -87,7 +87,6 @@
8787
"@stackframe/stack-shared": "workspace:*",
8888
"@upstash/qstash": "^2.8.2",
8989
"@vercel/functions": "^2.0.0",
90-
"@vercel/mcp-adapter": "^1.0.0",
9190
"@vercel/otel": "^1.10.4",
9291
"@vercel/sandbox": "^1.2.0",
9392
"ai": "^6.0.0",

apps/backend/prisma/migrations/20260420000000_add_project_onboarding_state/tests/default-and-updates.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ export const postMigration = async (sql: Sql, ctx: Awaited<ReturnType<typeof pre
3434
`;
3535

3636
const updatedRows = await sql`
37-
SELECT "onboardingState"
37+
SELECT "onboardingState"::text AS "onboardingState"
3838
FROM "Project"
3939
WHERE "id" = ${ctx.projectId}
4040
`;
4141
expect(updatedRows).toHaveLength(1);
42-
expect(updatedRows[0].onboardingState).toMatchInlineSnapshot(`
42+
expect(JSON.parse(updatedRows[0].onboardingState)).toMatchInlineSnapshot(`
4343
{
4444
"selected_apps": [
4545
"authentication",

apps/backend/src/app/api/internal/[transport]/route.ts

Lines changed: 0 additions & 105 deletions
This file was deleted.

0 commit comments

Comments
 (0)