Commit Graph

3222 Commits

Author SHA1 Message Date
BilalG1
401191615f
feat(dashboard): one-time Stack Auth → Hexclave rebrand modal (#1493)
## Summary

Adds a one-time informational modal that announces the **Stack Auth →
Hexclave** rebrand to existing logged-in dashboard users. Brand-new
users signing up after the cutoff already land on a fully
Hexclave-branded experience and don't see the modal — they have no
"Stack Auth" mental model to update.

Stacked on top of **PR #1481** (the visible-rebrand flip).

![Hexclave rebrand
modal](https://github.com/hexclave/stack-auth/raw/cl/hexclave-rebrand-modal/.github/assets/hexclave-rebrand-modal.png)

## What's in here

- **Component**:
[`apps/dashboard/src/components/hexclave-rebrand-modal.tsx`](https://github.com/hexclave/stack-auth/blob/cl/hexclave-rebrand-modal/apps/dashboard/src/components/hexclave-rebrand-modal.tsx)
— the modal itself plus the static `RebrandIllustration` (Stack Auth
mark → arrow → Hexclave benzene mark).
- **Mount**:
[`apps/dashboard/src/app/(main)/(protected)/layout-client.tsx`](https://github.com/hexclave/stack-auth/blob/cl/hexclave-rebrand-modal/apps/dashboard/src/app/(main)/(protected)/layout-client.tsx)
— single `<HexclaveRebrandModal />` inside `ConfigUpdateDialogProvider`
so it covers every authenticated dashboard route.
- **Asset**: `apps/dashboard/public/hexclave-icon.svg` — the
benzene-ring mark pulled from `https://hexclave.com/icon.svg` (the
canonical Hexclave brand mark). Stack Auth side uses the existing
`/logo.svg` + `/logo-bright.svg` (dark mode variant).

## Targeting

Three independent conditions must all hold for the modal to render:

1. **Logged-in user** — `useUser({ or: "return-null" })` opts out of the
sign-in redirect so guests are silently skipped.
2. **`user.signedUpAt < REBRAND_CUTOFF`** where `REBRAND_CUTOFF =
2026-05-27T00:00:00Z`. This is the cleanest "pre-rebrand user" signal —
more accurate than cookie inspection (the existing `stack-is-https` hint
cookie gets dual-written for new and returning users alike since
[`packages/template/src/lib/cookie.ts:201`](https://github.com/hexclave/stack-auth/blob/cl/hexclave-rebrand-modal/packages/template/src/lib/cookie.ts#L201),
so it can't distinguish), and it follows the same user across
browsers/devices.
3. **No `hexclave-rebrand-modal-dismissed=true` in localStorage**. Any
dismissal path (Got it button, X, overlay click, Escape) routes through
`onOpenChange` and writes this flag, so the modal never re-opens for
that browser.

## Behavior verification

End-to-end checked against a live dev dashboard:

-  Modal opens once on first authenticated dashboard view for a
pre-cutoff user.
-  `localStorage["hexclave-rebrand-modal-dismissed"]` flips to `"true"`
on any dismissal path.
-  Reload after dismissal: zero `[role=dialog]` elements rendered,
localStorage flag persists.
-  Not rendered for guests (no useUser → early `return null`, no
auth-redirect).
-  Not rendered for users with `signedUpAt >= REBRAND_CUTOFF`.
-  SSR-safe: hooks into `useEffect` to read storage post-hydration;
`try/catch` around storage access so private-mode / sandboxed iframes
degrade silently.
-  `pnpm --filter @stackframe/dashboard lint` clean.

## Notes

- **`pnpm typecheck`** was not run as part of this change because the
dashboard typecheck depends on `codegen-prisma` against a live DB
(pre-existing infra debt noted in PR #1481). Lint covers the type-shape
of the touched files via the project's strict TS-aware ESLint rules.
- **Migration link** points to
[`docs.hexclave.com/migration`](https://docs.hexclave.com/migration),
the same URL referenced from
[`packages/template/src/internal/deprecation-warning.ts:36`](https://github.com/hexclave/stack-auth/blob/cl/hexclave-rebrand-modal/packages/template/src/internal/deprecation-warning.ts#L36)
— single source of truth for the migration story.
- **No animation** by design — the modal is static; entry/exit uses the
existing Radix Dialog fade.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Adds a one-time modal in the dashboard to announce the Stack Auth →
Hexclave rebrand for pre-rebrand users. It shows once per account per
browser, inlines the import-rename step, links the migration guide, and
doesn’t show for new signups or in dev/preview environments.

- **New Features**
- Shows only for logged-in users with `signedUpAt <
'2026-05-27T00:00:00Z'`; guests, post-cutoff signups, and local
emulator/remote dev/preview never see it.
- Dismissal persists via
`localStorage["hexclave-rebrand-modal-dismissed:<user.id>"]="true"`; all
close paths set the flag.
- Mounted in the protected dashboard layout so it covers all
authenticated routes once per account per browser.
- Includes illustration (`/logo.svg` → arrow → `/hexclave-icon.svg`) and
links to app.hexclave.com and the migration guide; copy tells users to
rename `@stackframe/*` to `@hexclave/*` (`@stackframe/stack` →
`@hexclave/next`).

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

<!-- End of auto-generated description by cubic. -->
2026-05-26 18:16:25 -07:00
Bilal Godil
c8abb72286 feat(brand): regenerate favicons and OG image with Hexclave benzene mark
Three favicon.ico files and the dashboard's open-graph-image.png are
regenerated from the canonical Hexclave benzene-mark SVG committed in
the previous logo-swap commit (apps/dashboard/public/logo.svg).

Favicons (all three: dashboard, dev-launchpad, docs-mintlify) bundle
16x16, 32x32, and 48x48 PNG-encoded variants — 32bpp RGBA for crisp
rendering on retina + dark-mode tab strips. dev-launchpad's old icon
was a 4bpp 16x16 single-frame; it now matches the other two.

OG image is 1200x630 with a centered 360px gradient benzene mark on a
dark canvas with a subtle radial glow. No wordmark — Jersey 10 isn't
available at rasterize time and the mark alone reads cleanly on the
standard OG card preview area in Slack / Twitter / LinkedIn.

The dashboard layout's openGraph.images metadata points at
${apiUrl}/open-graph-image.png — the backend deploy needs to serve
this file from the same path so social previews actually resolve.
Tracked separately as ops work.
2026-05-26 17:12:31 -07:00
Bilal Godil
ebcef12129 feat(brand): swap Stack Auth logos for Hexclave benzene mark + wordmark
PR 1481 carved out binary visual assets pending design work, but we now
have the Hexclave brand mark from PR 1493 (the neon-gradient benzene
ring) and a full wordmark variant. Swap them in everywhere the dashboard,
docs site, and example demo rendered the Stack Auth logo.

Icon-only variant (PR 1493's hexclave-icon.svg, neon-gradient benzene
mark) replaces:
- apps/dashboard/public/logo.svg + logo-bright.svg
- examples/demo/public/logo.svg + logo-bright.svg

Full wordmark variant (benzene mark + 'Hexclave' text in Jersey 10)
replaces:
- apps/dashboard/public/logo-full.svg (black text — light mode)
- apps/dashboard/public/logo-full-bright.svg (white text — dark mode)
- docs-mintlify/images/logo-light.svg (black text)
- docs-mintlify/images/logo-dark.svg (white text)

The benzene mark uses a colored gradient that reads on both light and
dark backgrounds, so logo.svg and logo-bright.svg now share identical
content — the dark-mode SmartImage swap in logo.tsx is effectively a
no-op but the file pair is preserved to avoid touching the component
API. Same applies to examples/demo.

Also drop the 'dark:invert' className on examples/demo's <Image> — the
new gradient mark should not be color-inverted on dark backgrounds (it
already reads correctly on both).
2026-05-26 17:03:10 -07:00
Bilal Godil
8f6e3198a6 docs: rename build-a-saas-with-stack-auth tutorial slug to -hexclave
The MDX content was flipped to Hexclave in PR 1481, but the URL slug
itself (/guides/other/tutorials/build-a-saas-with-stack-auth) was still
public-facing. Rename the file and update the five internal links:

- docs.json navigation reference
- 3 in-MDX cross-links in build-a-team-based-app.mdx
- 2 in-MDX cross-links in ship-production-ready-auth.mdx
2026-05-26 17:00:42 -07:00
Bilal Godil
0006fae3a9 chore(examples): flip remaining Stack → Hexclave brand strings in example apps
PR 1481's sweep missed four user-visible spots in the examples/ tree:

- examples/demo: page title 'Stack Demo' + description 'using Stack...'
- examples/docs-examples: page title 'Stack Demo' + description 'using Stack...'
- examples/tanstack-start-demo: 'Stack TanStack Demo' link text in header
- examples/middleware: description 'A demo of Stack\'s middleware capabilities.'
  (title was already flipped; only the description was missed)
2026-05-26 17:00:08 -07:00
Bilal Godil
3716e54e2a fix(template): drop stray await on synchronous Result.or in _serverUserCache
Result.or returns T | U synchronously, so awaiting it tripped
@typescript-eslint/await-thenable and @typescript-eslint/return-await
in the generated packages/stack and packages/react SDKs.
2026-05-26 16:12:04 -07:00
Bilal Godil
c1b887abc2 Merge origin/dev into cl/romantic-mendel-5a2c25 2026-05-26 15:52:33 -07:00
github-actions[bot]
6a01c1bcc7 chore: update package versions 2026-05-26 22:26:55 +00:00
Konstantin Wohlwend
cbdcea2a78 Various small docs improvements
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-26 15:19:50 -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
github-actions[bot]
18df895842 chore: update package versions 2026-05-26 21:59:38 +00:00
Konstantin Wohlwend
4854e551a8 More small retry fixes 2026-05-26 14:48:19 -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