Commit Graph

3214 Commits

Author SHA1 Message Date
Bilal Godil
0902a7e579 feat(dashboard): scope rebrand modal dismissal by user.id
Switches the localStorage key from the global
"hexclave-rebrand-modal-dismissed" to a per-user
"hexclave-rebrand-modal-dismissed:<user.id>".

Rationale: a shared browser (e.g. a work machine where two teammates
each log into their own dashboard account) was previously hiding the
announcement from teammate B as soon as teammate A dismissed it. Now
each account tracks its own dismissal independently. The trade-off —
the same human switching between their personal and work accounts will
see the modal once per account — is acceptable: each account is a
distinct identity, and a one-time brand notice per account is fine.

Storage key is computed as `${STORAGE_KEY_PREFIX}${user.id}` only when
`user` is non-null; both the useEffect read path and the dismiss write
path null-check `storageKey` defensively even though the existing gates
(`isPreRebrandUser`, `if (!isPreRebrandUser) return null`) already
ensure neither runs without a user.

No migration shim — the old global key was only ever written in local
dev/test before this PR ships, so no production data is being orphaned.
2026-05-26 16:05:47 -07:00
Bilal Godil
1c4d3a6bd7 feat(dashboard): skip rebrand modal in dev/preview environments
Adds an explicit short-circuit at the top of HexclaveRebrandModal that
returns no modal when any of the three NEXT_PUBLIC_STACK_IS_* dev flags
is true — local emulator, remote development environment, or preview.

These surfaces either auto-create throwaway users (preview) or seed a
fixture admin (emulator/RDE). The rebrand notice would be friction for
developers logging into local dev and meaningless for preview visitors
who never used "Stack Auth" in the first place. Coincidentally these
users are also filtered out today by signedUpAt < REBRAND_CUTOFF (fresh
preview signups happen after the cutoff; a freshly-seeded emulator admin
also signs up post-cutoff), but the explicit env-flag guard is more
defensive — it stays correct if the cutoff is ever bumped forward for a
test.

Same three flags the protected layout already gates on
(apps/dashboard/src/app/(main)/(protected)/layout-client.tsx:15-17).
2026-05-26 15:48:17 -07:00
Bilal Godil
b90998c8da feat(dashboard): add one-time Stack Auth → Hexclave rebrand modal
Announces the rebrand to authenticated dashboard users whose
signedUpAt predates 2026-05-27 UTC (the rebrand cutoff). Brand-new
users signing up after the cutoff already land on Hexclave-branded
surfaces and don't see the modal.

- Modal lives in the protected dashboard layout via
  apps/dashboard/src/app/(main)/(protected)/layout-client.tsx so it
  surfaces on any logged-in route once per browser.
- Gated on useUser({ or: "return-null" }) + signedUpAt < cutoff, so
  it never triggers a sign-in redirect for guests and never shows for
  post-rebrand signups.
- Dismissal (button, X, overlay, Escape) routes through onOpenChange
  and writes "hexclave-rebrand-modal-dismissed" to localStorage so it
  never re-appears for that browser.
- Illustration uses the existing Stack Auth logo (logo.svg /
  logo-bright.svg for dark mode) and the Hexclave benzene mark saved
  to public/hexclave-icon.svg.
- Copy links app.hexclave.com and docs.hexclave.com/migration.

Screenshot: .github/assets/hexclave-rebrand-modal.png
2026-05-26 15:37:45 -07:00
Bilal Godil
663cb5534c docs: flip shared-sender example to sent-with-hexclave.com
The legacy docs/ folder still referenced noreply@stackframe.co for the
shared email provider — flip to match the new sender domain set up
on Resend as the dedicated transactional-sender domain. Aligns with
the dashboard + docs-mintlify references that were already flipped.
2026-05-26 15:06:40 -07:00
Konstantin Wohlwend
d15bf68a2b Keep using r.stack-auth.com for analytics despite the rebrand 2026-05-26 14:20:17 -07:00
Bilal Godil
0fced48e50 Merge origin/dev into cl/romantic-mendel-5a2c25
Resolve conflicts in init-prompt.ts (take dev's unified-prompt structure,
keep Hexclave branding), and rebrand the auto-merged ai-setup-prompt.ts
sweep (CLI Python template names, MCP server name/URL/tool, StackConfig
type, x-hexclave-* header teach). Regenerated docs-mintlify setup files.
2026-05-26 14:15:33 -07:00
Konstantin Wohlwend
7dd764324a Update CLI to use unified setup prompt 2026-05-26 14:00:11 -07:00
Konsti Wohlwend
018ecd1107
Fix client interface 4xx retry handling (#1492) 2026-05-26 13:48:33 -07:00
Bilal Godil
f69694387b Merge remote-tracking branch 'origin/dev' into cl/romantic-mendel-5a2c25 2026-05-26 13:45:30 -07:00
Bilal Godil
d59cc378e8 Merge remote-tracking branch 'origin/dev' into cl/romantic-mendel-5a2c25 2026-05-26 13:40:42 -07:00
github-actions[bot]
5f3dc6d9ee chore: update package versions 2026-05-26 20:37:35 +00:00
Konsti Wohlwend
a06c9331f9
Fix skills app CI typecheck (#1490) 2026-05-26 13:32:09 -07:00
Konstantin Wohlwend
c13853702c Remove GitHub OAuth provider error noise 2026-05-26 13:31:16 -07:00
github-actions[bot]
ad197de7fe chore: update package versions 2026-05-26 20:28:07 +00:00
Bilal Godil
dff79c4be8 fix(hexclave): rewrite-packages — fix sentinel version bump
The bare-name sweep was mutating the sentinel string
('js @stackframe/js@2.8.105') into 'js @hexclave/js@2.8.105' before
the sentinel-specific regex (built from oldName) had a chance to
match, silently leaving the version stuck at the old @stackframe
version on published @hexclave/* artifacts. Reorder so the sentinel
rewrite runs first; the name sweep that follows can't touch the
rewritten sentinel because it no longer contains any @stackframe/*
substrings.
2026-05-26 13:22:06 -07:00
Konstantin Wohlwend
7a2561dd7e Fix OAuth sign-in 2026-05-26 13:14:15 -07:00
Bilal Godil
2e8b9517fe Merge remote-tracking branch 'origin/dev' into cl/romantic-mendel-5a2c25 2026-05-26 13:03:11 -07:00
Bilal Godil
29b214bae9 Merge remote-tracking branch 'origin/dev' into cl/romantic-mendel-5a2c25
# Conflicts:
#	docs-mintlify/guides/getting-started/setup.mdx
#	docs-mintlify/snippets/home-prompt-island.jsx
2026-05-26 13:01:51 -07:00
Bilal Godil
bf772b7db1 Merge remote-tracking branch 'origin/dev' into cl/romantic-mendel-5a2c25
# Conflicts:
#	apps/skills/src/app/route.ts
#	packages/stack-shared/src/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.ts
#	packages/stack-shared/src/interface/page-component-versions.ts
2026-05-26 13:01:26 -07:00
BilalG1
a4ae7edecd
fix(ci): repair two pre-existing test failures on dev (#1488)
Both failures are pre-existing on `dev` (confirmed by checking the most
recent dev run
[26434368271](https://github.com/hexclave/stack-auth/actions/runs/26434368271)
— same two annotations, same line numbers). Neither is caused by an open
PR.

## Failure 1 — \`apps/backend/src/lib/redirect-urls.test.tsx:75\`

\`\`\`
AssertionError: expected false to be true
\`\`\`

The \`withHostedHandlerEnv\` helper set/cleared only the
\`STACK_*\`-prefixed env vars. CI's
[e2e-custom-base-port-api-tests.yaml:21](.github/workflows/e2e-custom-base-port-api-tests.yaml#L21)
sets only the \`HEXCLAVE_*\`-prefixed sibling
(\`NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX=67\`), and the dual-read shim in
[packages/stack-shared/src/utils/env.tsx#L53-L55](packages/stack-shared/src/utils/env.tsx#L53-L55)
prefers \`HEXCLAVE_*\` over \`STACK_*\`:

\`\`\`ts
const hexclaveName = getHexclaveEnvVarName(name);
let value = (hexclaveName ? process.env[hexclaveName] : undefined) ??
process.env[name];
\`\`\`

So \`getEnvVariable(\"NEXT_PUBLIC_STACK_PORT_PREFIX\", \"81\")\`
returned \`\"67\"\` instead of the test's \`\"92\"\`, the template
resolved to port \`6709\` instead of \`9209\`, and the assertion at line
75 failed.

**Fix:** mirror every \`STACK_*\` key managed by the helper to its
\`HEXCLAVE_*\` sibling. The dual-read then resolves to the
test-controlled value regardless of which key it checks first.

## Failure 2 —
\`apps/backend/prisma/migrations/20260526060000_nullable_oauth_access_token_expires_at/tests/nullable-expires-at.ts:58\`

\`\`\`
PostgresError: null value in column \"updatedAt\" of relation
\"OAuthAccessToken\" violates not-null constraint
\`\`\`

The migration test's raw INSERT omits \`\"updatedAt\"\`. The Prisma
model declares \`updatedAt DateTime @updatedAt\` with no
\`@default(now())\`, so the DB column is \`NOT NULL\` with no default —
Prisma populates it at the ORM layer on insert, but this test bypasses
Prisma via \`postgres.js\`.

**Fix:** add the \`\"updatedAt\"\` column to the INSERT, set to
\`NOW()\`, with a comment noting why raw SQL must set it explicitly.

## Verification

- **Failure 1, before fix:** ran \`NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX=67
pnpm test run apps/backend/src/lib/redirect-urls.test.tsx\` locally →
reproduces the exact line-75 assertion failure from CI.
- **Failure 1, after fix:** same command → 33/33 pass.
- **Failure 2:** local reproduction requires the migration-test postgres
harness; the fix is one column matching how every other raw SQL insert
in this repo handles \`@updatedAt\` fields. CI on this branch will
confirm.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes two failing tests on dev CI by aligning env var handling in
redirect URL tests and by setting the missing updatedAt in a migration
test. Restores green CI with no runtime changes.

- **Bug Fixes**
- Redirect URL tests: `withHostedHandlerEnv` now mirrors `STACK_*`
values to their `HEXCLAVE_*` siblings and restores both, so
`getEnvVariable` reads the test-controlled values even when CI sets only
`HEXCLAVE_*` (e.g. `NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX`).
- Migration test: the raw insert into `OAuthAccessToken` now sets
`"updatedAt" = NOW()` since `Prisma`’s `@updatedAt` isn’t applied when
using `postgres.js` and the column is NOT NULL.

<sup>Written for commit 75c8e4343e.
Summary will update on new commits. <a
href="https://cubic.dev/pr/hexclave/stack-auth/pull/1488?utm_source=github">Review
in cubic</a></sup>

<!-- End of auto-generated description by cubic. -->
2026-05-26 12:59:44 -07:00
Konstantin Wohlwend
4d6a37aced Fix generated files 2026-05-26 12:55:34 -07:00
Konstantin Wohlwend
c94bf484c8 Fix CI/CD 2026-05-26 12:54:55 -07:00
Konstantin Wohlwend
f702724d53 Fix CI/CD 2026-05-26 12:52:30 -07:00
Konstantin Wohlwend
e02ff07515 Fix docs base URL 2026-05-26 12:46:43 -07:00
Konstantin Wohlwend
2f3e5d0d5a Update LLM documentation 2026-05-26 12:42:00 -07:00
Bilal Godil
b401e6f04a Merge remote-tracking branch 'origin/dev' into cl/romantic-mendel-5a2c25
# Conflicts:
#	docs-mintlify/guides/getting-started/ai-integration.mdx
#	docs-mintlify/guides/going-further/local-development.mdx
#	docs-mintlify/guides/going-further/local-emulator.mdx
#	docs-mintlify/guides/other/showcase.mdx
2026-05-26 12:36:44 -07:00
Konstantin Wohlwend
c276a825a8 Update docs to remove outdated info 2026-05-26 11:39:51 -07:00
Konstantin Wohlwend
c5a49d6721 Fix legacy cookie mixing 2026-05-26 11:08:35 -07:00
Bilal Godil
4de242c126 fix(hexclave): update redirect-urls snapshot for shortened HexclaveAssertionError suffix
Companion to ff44d4ec3 — that commit shortened the disclaimer from
'...error in Hexclave (formerly Stack Auth).' to '...error in Hexclave.'
and updated the url-targets test snapshots, but missed the matching
inline snapshot in apps/backend/src/lib/redirect-urls.test.tsx. The test
suite passes after the update (33/33).
2026-05-26 10:35:26 -07:00
Bilal Godil
d358f42dd0 ci(hexclave): scope mirror publish to @hexclave/* packages
Filter `pnpm publish -r` to only the rewritten @hexclave/* packages in
the mirror step, removing the reliance on pnpm's skip-existing-versions
behavior for the unchanged @stackframe/* packages still in the workspace
at that point.

Addresses greptile P1 finding on PR #1481.
2026-05-26 10:25:58 -07:00
Bilal Godil
5f8175a53b Merge remote-tracking branch 'origin/dev' into cl/romantic-mendel-5a2c25
# Conflicts:
#	apps/backend/package.json
#	apps/dashboard/package.json
#	apps/dev-launchpad/package.json
#	apps/e2e/package.json
#	apps/mcp/package.json
#	apps/mock-oauth-server/package.json
#	apps/skills/package.json
#	docs-mintlify/index.mdx
#	examples/cjs-test/package.json
#	examples/convex/package.json
#	examples/demo/package.json
#	examples/docs-examples/package.json
#	examples/e-commerce/package.json
#	examples/js-example/package.json
#	examples/lovable-react-18-example/package.json
#	examples/middleware/package.json
#	examples/react-example/package.json
#	examples/supabase/package.json
#	examples/tanstack-start-demo/package.json
#	packages/dashboard-ui-components/package.json
#	packages/init-stack/package.json
#	packages/js/package.json
#	packages/react/package.json
#	packages/stack-cli/package.json
#	packages/stack-sc/package.json
#	packages/stack-shared/package.json
#	packages/stack-ui/package.json
#	packages/stack/package.json
#	packages/tanstack-start/package.json
#	packages/template/package-template.json
#	packages/template/package.json
#	skills/stack-auth/SKILL.md
2026-05-26 10:12:25 -07:00
Konstantin Wohlwend
fae8d2dfab Longer refresh token expiries for OAuth providers that don't return one 2026-05-25 22:35:22 -07:00
github-actions[bot]
bef9452c95 chore: update package versions 2026-05-26 03:44:50 +00:00
Konsti Wohlwend
c8954ad172
Fix bundled dashboard symlinks in stack-cli (#1485) 2026-05-25 19:08:17 -07:00
aadesh18
2ab43e9021
fix(skills): repair SKILL.md YAML frontmatter parse error (#1487)
## What

The `description` field in `skills/stack-auth/SKILL.md` failed to parse
as YAML, surfacing on GitHub as:

> Error in user YAML: (<unknown>): mapping values are not allowed in
this context at line 2 column 338

## Why

The `description` was an **unquoted** YAML scalar containing a
colon-space sequence:

> …live, canonical instructions for every Stack Auth surface, including
the CLI**: **how to model users…

In YAML, `: ` inside an unquoted scalar is parsed as a key/value
mapping, which is illegal mid-value — hence *"mapping values are not
allowed in this context."*

## Fix

Wrapped the `description` value in **single** quotes. Single quotes (not
double) because the string already contains embedded double quotes
(`"stack auth"`, `"skill"`) but no apostrophes, so no escaping is
needed.

Verified the frontmatter now parses cleanly — all 9 keys (`name`,
`description`, `version`, `author`, `tags`, `testingTypes`,
`frameworks`, `languages`, `domains`) load via `yaml.safe_load`.

## Notes

- One-line change, content of the description is unchanged.
- The unrelated `@stackframe/dashboard` typecheck failure on this branch
comes from a stale generated `.next/dev/types/routes.d.ts` build
artifact and is not touched by this PR.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes YAML frontmatter parsing in skills/stack-auth/SKILL.md by quoting
the description, removing the “mapping values are not allowed in this
context” error. Wrapped the description in single quotes to prevent the
`CLI: how...` colon-space from being parsed as a mapping.

<sup>Written for commit b8866bd93a.
Summary will update on new commits. <a
href="https://cubic.dev/pr/hexclave/stack-auth/pull/1487?utm_source=github">Review
in cubic</a></sup>

<!-- End of auto-generated description by cubic. -->



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
  * Updated formatting in skill documentation to improve consistency.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/hexclave/stack-auth/pull/1487?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-25 18:28:10 -07:00
github-actions[bot]
ed54832671 chore: update package versions 2026-05-26 00:59:48 +00:00
Konstantin Wohlwend
d30962bf66 Fix GH tokens refresh & devtool tabs 2026-05-25 17:50:09 -07:00
Konsti Wohlwend
bb109a5cbc
Fix docs overview setup prompt card (#1484) 2026-05-25 17:31:34 -07:00
Konstantin Wohlwend
89cc824fa6 Fix docs sidebar icons 2026-05-25 10:59:34 -07:00
Bilal Godil
ff44d4ec33 fix(hexclave): update url-targets snapshots for shortened HexclaveAssertionError suffix
The HexclaveAssertionError disclaimer was simplified from
"...error in Hexclave (formerly Stack Auth)." to "...error in Hexclave."
but the inline snapshots in url-targets and redirect-urls tests still
expected the longer text. Updates the template source-of-truth; SDK
mirrors regenerate via the preinstall generate-sdks hook.
2026-05-23 17:50:05 -07:00
Bilal Godil
d4f6f58735 feat(hexclave): PR 2 — visible rebrand to Hexclave
Rebased onto dev after PR 1475 (cl/hexclave-pr1) was squash-merged.
Squashes the original 46-commit branch (including PR1-duplicate commits
that arrived via cherry-picks/merges) into a single commit containing
only PR2's net delta over dev.

Original PR 1481 head: 94872de407873a1cabd4085deb21b69afe8d7699
(kept locally at backup/cl-romantic-mendel-5a2c25-pre-rebase)
2026-05-23 17:35:08 -07:00
BilalG1
f7e389809e
feat(hexclave): PR 1 — wire compatibility layer (invisible) (#1475)
Some checks failed
all-good: Did all the other checks pass? / all-good (push) Has been cancelled
Ensure Prisma migrations are in sync with the schema / check_prisma_migrations (22.x) (push) Has been cancelled
DB migration compat / Check if migrations changed (push) Has been cancelled
Docker Server Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Server Build and Run / docker (push) Has been cancelled
Runs E2E API Tests (Local Emulator) / E2E Tests (Local Emulator, Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (mock, 22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (prod, 22.x) (push) Has been cancelled
Runs E2E API Tests with custom port prefix / build (22.x) (push) Has been cancelled
Runs E2E Fallback Tests / E2E Fallback Tests (Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Lint & build / lint_and_build (24) (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
DB migration compat / Back-compat — Current branch migrations with ${{ needs.check-migrations-changed.outputs.base_branch }} branch code (push) Has been cancelled
DB migration compat / Forward-compat — Current branch code with ${{ needs.check-migrations-changed.outputs.base_branch }} branch migrations (push) Has been cancelled
DB migration compat / No migration changes (skipped) (push) Has been cancelled
## Summary

**Stacked on #1468** (`docs/hexclave-rename-plan` — the plan doc). Diff
vs that base = the actual PR 1 code.

This is **PR 1 of the Hexclave rebrand: the invisible compatibility
layer**. Everything is additive. Old SDKs, old wire identifiers, and old
env var names keep working unchanged. The backend dual-accepts and
dual-emits; new SDK code emits `x-hexclave-*` headers and the
`hexclave_` Bearer prefix; cookies dual-write; env vars dual-read across
every category. **No user-visible rebranding lands here** — that's PR 2.

See [`RENAME-TO-HEXCLAVE.md`](./RENAME-TO-HEXCLAVE.md) → *"PR 1
implementation guide"* for the full per-work-area spec, file pointers,
and chosen approach.

## What's implemented (all 14 PR-1 work-areas)

- **SDK export aliases** — `Hexclave*` aliases for the user-facing
`Stack*` exports added in `packages/template`; codegen propagates them
to `@stackframe/{js,stack,react,tanstack-start}`. React-only aliases
correctly excluded from `@stackframe/js`. (`e60550a2`)
- **JWT issuer dual-accept** — `decodeAccessToken` accepts both
`api.stack-auth.com` and `api.hexclave.com` issuers. Signing unchanged.
(`fc781def`)
- **Request-header dual-accept** — backend + dashboard proxies normalize
`x-hexclave-*` → `x-stack-*` at the existing empty proxy hook (so
`smart-request.tsx` and every route schema keep working unchanged); CORS
allowlists extended via a derive-once helper. (`2a056eac`)
- **MCP `ask_hexclave`** — registered alongside `ask_stack_auth` via a
shared helper; `ask_stack_auth` behavior byte-identical. (`30ffd604`)
- **Dev-tool** — DOM ids + header emit switched.
`window.HexclaveDevTool` exposed alongside `window.StackDevTool`.
(`32131ea7`)
- **The big consolidated commit** (`7fed864a`):
- **Env vars** — central `getEnvVariable` prefix-transform (HEXCLAVE
first, STACK fallback); dashboard + template client env files dual-read;
`turbo.json` globalEnv; `NEXT_PUBLIC_STACK_PORT_PREFIX` renamed outright
across ~82 files including docker.
- **Cookies** — dual-write/dual-read auth (`stack-access`/`-refresh-*`
and custom-domain variants), OAuth-state
(`stack-oauth-{inner,outer}-*`), and low-risk cookies (`stack-is-https`,
`stack-last-seen-changelog-version`). Bypass sites patched (backend
OAuth callback, dashboard remote-dev auth route, impersonation snippets,
snapshot serializer).
- **Bearer prefix** — SDK token parser accepts both `stackauth_` and
`hexclave_`; emits `hexclave_`. Discovery correction: this is purely
SDK-internal — the backend never parses it.
- **Response headers** — backend dual-emits
`x-hexclave-{request-id,actual-status,known-error}`; SDKs dual-read (new
first, stack fallback).
- **SDK request-header emit switch** —
`client/server/admin-interface.ts` + dashboard `api-headers.ts` +
`internal-project-headers.ts` + `feedback-form.tsx` switched to
`x-hexclave-*`. Plus `stack_response_mode` query param.
- **Storage keys** — dev-tool / cli-auth / oauth-button / docs keys
renamed (straight); `stack:session-replay:v1` dual-read so in-progress
recordings survive SDK upgrades; `stack_mfa_attempt_code` dual-read.
- **Query params** — cross-domain params dual-emit/dual-accept via
shared helpers; backend `oauth/authorize` accepts
`hexclave_response_mode` and `stack_response_mode`; `stack-init-id`
renamed.
- **`Symbol.for`** — app-internals symbol gets a parallel
`Symbol.for("Hexclave--app-internals")` getter on each attach site (no
read-site churn — old symbol still attached). 3 file-private symbols
renamed outright.
- **Config discovery** — prefer `hexclave.config.ts`, fall back to
`stack.config.ts` at every discovery site (CLI / dashboard / backend /
local-emulator); `init` writes the new filename; CLI credentials path
migrates.
- **Internal renames** — `StackAssertionError`,
`StackClient/Server/AdminInterface` renamed outright (no alias, per the
"internal-only → rename" rule). ~264 files touched.
- **Review-pass fixes** (`21217fbe`) — three real bugs found by parallel
review agents and fixed:
- `snapshot-serializer.ts` was interpolating the whole
`keyedCookieNamePrefixes` array (`${arr}`) — adding a second prefix
would have corrupted **every** OAuth-cookie snapshot, not just new ones.
- **Docker port-prefix producer/consumer mismatch** —
`entrypoint.sh`/`run-emulator.sh`/cloud-init `user-data` were still
producing `NEXT_PUBLIC_STACK_PORT_PREFIX` while the dashboard sentinel +
consumers had been renamed; silent self-host regression (custom port
prefix would be ignored).
- **Missing `hexclave-oauth-inner-*` dual-write** in the OAuth authorize
route — callback's fallback masked it but the dual-write was specified
by the plan.
- Plus: `mcp.test.ts` tool-list assertions updated to include
`ask_hexclave`; two dashboard header-emit sites switched to
`x-hexclave-*` for consistency.
- **E2E snapshot serializer follow-up** (`4b16cc5d`) —
`x-hexclave-request-id` added to the hidden-headers list (mirroring
`x-stack-request-id` treatment), and 2 sample inline snapshots
regenerated in `projects.test.ts` to include the new dual-emitted
headers.

## Verification

- **`pnpm typecheck`** — clean (the fresh-worktree `@/.source` / Prisma
codegen gap in `stack-docs` is pre-existing and unrelated).
- **`pnpm lint`** — 29/29 packages green.
- **`pnpm exec turbo run build --filter=./packages/*`** — 13/13 packages
build (including `@stackframe/stack-cli` once the dashboard standalone
is present).
- **Live E2E** against a running backend on `cl/hexclave-pr1`:
- `pnpm test run
apps/e2e/tests/backend/endpoints/api/v1/internal/mcp.test.ts` — **6/6
pass** (verifies the new `ask_hexclave` tool — the hand-written inline
snapshot matched actual MCP server output).
- `pnpm test run
apps/e2e/tests/backend/endpoints/api/v1/internal/projects.test.ts` —
**11/11 pass** (verifies wire dual-accept + dual-emit end-to-end; the
snapshot serializer fix was found and applied during this check).

A four-agent parallel **review pass** also audited the full diff for
logic/runtime bugs across the work-areas (wire headers + JWT, cookies +
bearer + symbols, env vars, query params + config + MCP + aliases). All
in-slice review verdicts were ✓ except the three bugs listed above,
which are now fixed.

## Known follow-ups (out of scope for this PR)

- **E2E snapshots across the rest of the suite** — backend now
dual-emits `x-hexclave-{known-error,actual-status}` alongside
`x-stack-*`, which legitimately appears in inline snapshots throughout
`apps/e2e`. Two were regenerated here as a sample; the rest should regen
with `vitest -u` in CI.
- **Docker shell env vars beyond `PORT_PREFIX`** — `entrypoint.sh` still
reads `STACK_*` env vars directly (the JS-side `getEnvVariable`
transform doesn't help the shell). JS consumers dual-read so it works in
practice; full shell-level dual-read is a deeper self-host follow-up.
- **`@stackframe/stack-cli` build ordering** — pre-existing; needs
`build:rde-standalone` first. Not affected by this PR.

## Test plan

- [ ] CI runs full e2e suite (with `vitest -u` to absorb dual-emit
snapshot deltas, then committed back)
- [ ] Spot-check: an old SDK build (emitting only `x-stack-*`) still
authenticates against the new backend
- [ ] Spot-check: a new SDK (emitting `x-hexclave-*` / `Bearer
hexclave_*`) still authenticates against an old backend during deploy
ordering
- [ ] Manual: `npx @stackframe/stack-cli@latest init` (new onboarding
entrypoint) generates `hexclave.config.ts`
- [ ] Manual: existing `stack.config.ts`-only project still resolves (no
migration required)

---------

Co-authored-by: bilal <bilal@stack-auth.com>
2026-05-23 17:24:55 -07:00
Konstantin Wohlwend
1044144091 More test fixes 2026-05-23 13:55:15 -07:00
Mantra
10df9b2b7b
Fix dashboard sandbox compile errors and switch smart model to Grok (#1476)
## Summary
- Forward Babel/JSX compile errors, runtime throws, and unhandled
rejections from the AI dashboard sandbox iframe to the parent composer
via `postMessage`, so users see actionable errors instead of a blank
preview
- Compile AI-generated dashboard source explicitly with
`Babel.transform` + try/catch (stored in `text/plain` to avoid Babel's
auto-handler swallowing parse errors) and add `crossorigin="anonymous"`
on the Babel script for readable cross-origin error messages
- Switch authenticated smart-tier model from
`moonshotai/kimi-k2.6:nitro` to `x-ai/grok-build-0.1`

## Test plan
- [ ] Generate a dashboard with valid AI code and confirm the preview
still renders
- [ ] Generate a dashboard with invalid JSX and confirm the composer
shows the compile error (not a blank iframe)
- [ ] Trigger a runtime error in generated dashboard code and confirm it
reaches the parent error boundary
- [ ] Verify authenticated smart-tier requests route to
`x-ai/grok-build-0.1`


Made with [Cursor](https://cursor.com)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Embedded dashboards now show a clear “Dashboard failed to compile”
message on compilation errors instead of a blank iframe.
* Dashboard runtime errors and unhandled promise rejections are captured
earlier and forwarded to the parent for improved visibility.

* **Updates**
* The authenticated AI model used for the "smart" quality has been
changed, affecting model selection for authenticated requests.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/hexclave/stack-auth/pull/1476?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-23 12:34:37 -07:00
Konstantin Wohlwend
725f2da886 Fix tests 2026-05-23 12:29:20 -07:00
Konstantin Wohlwend
281701e99d Fix CI 2026-05-23 11:17:51 -07:00
github-actions[bot]
957a33a651 chore: update package versions 2026-05-23 18:13:12 +00:00
Konstantin Wohlwend
866e618a20 Fix CI/CD
Some checks failed
all-good: Did all the other checks pass? / all-good (push) Has been cancelled
Ensure Prisma migrations are in sync with the schema / check_prisma_migrations (22.x) (push) Has been cancelled
Docker Server Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Server Build and Run / docker (push) Has been cancelled
Runs E2E API Tests (Local Emulator) / E2E Tests (Local Emulator, Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (mock, 22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (prod, 22.x) (push) Has been cancelled
Runs E2E API Tests with custom port prefix / build (22.x) (push) Has been cancelled
Runs E2E Fallback Tests / E2E Fallback Tests (Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Lint & build / lint_and_build (24) (push) Has been cancelled
Publish npm packages / publish (push) Has been cancelled
Publish Swift SDK to prerelease repo / publish (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
2026-05-23 10:48:41 -07:00
Konstantin Wohlwend
d4663fbe7d Capture more errors on failures 2026-05-23 10:34:55 -07:00
github-actions[bot]
6a0ded1340 chore: update package versions 2026-05-23 16:45:36 +00:00