Commit Graph

927 Commits

Author SHA1 Message Date
Bilal Godil
cf05a4c20b Merge remote-tracking branch 'origin/dev' into cl/hexclave-pr3
# 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
#	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.json
2026-05-28 14:50:32 -07:00
Konstantin Wohlwend
8b2bcbca69 Update repository URL back to github.com/hexclave/stack-auth
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-28 14:27:12 -07:00
Bilal Godil
56dd55d2ee Merge remote-tracking branch 'origin/dev' into cl/hexclave-pr3
# Conflicts:
#	apps/backend/src/app/api/latest/connected-accounts/[user_id]/[provider_id]/[provider_account_id]/access-token/crud.tsx
#	apps/backend/src/app/api/latest/connected-accounts/[user_id]/[provider_id]/access-token/crud.tsx
#	apps/backend/src/lib/request-api-url.ts
#	apps/backend/src/oauth/index.tsx
#	apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx
2026-05-28 14:02:52 -07:00
BilalG1
fa2baa829d
feat(oauth): per-provider customCallbackUrl for redirect_uri (#1512)
## Summary

Replaces the request-host-header-derived OAuth `redirect_uri` with a
config-driven `customCallbackUrl` field on each environment-level OAuth
provider.

Resolution of the `redirect_uri` we send to providers (and that
customers register in their provider app config):

- **Shared providers** → always the stack-auth-branded callback, so
Stack's shared OAuth apps keep working. `customCallbackUrl` is
schema-forbidden when `isShared` is true.
- **Custom + `customCallbackUrl` set** → the configured URL verbatim.
- **Custom without it (legacy)** → the stack-auth-branded callback, so
providers registered before this field are unaffected.
- **New custom providers set up in the dashboard** → the env-aware
hexclave-branded callback (prod → `api.hexclave.com`, dev/staging →
siblings, self-host/localhost → `NEXT_PUBLIC_STACK_API_URL` unchanged).

## Details

- **Schema** (`schema.ts`, `schema-fields.ts`): optional
`customCallbackUrl` after `clientSecret`, with a `.when('isShared')`
rule rejecting any value for shared providers; added to the provider
default factory.
- **Shared host helper** (`utils/cloud-hosts.tsx`, new):
`CLOUD_HOST_PAIRS` moved into stack-shared with `getCloudApiUrlSiblings`
/ `getStackAuthApiBaseUrl` / `getHexclaveApiBaseUrl`;
`request-api-url.ts` re-exports it so the JWT `iss` logic is untouched.
- **Runtime** (`oauth/index.tsx` + all 13 provider `create()`s):
`getProvider` resolves the full `redirect_uri` from config instead of
the request host; providers now take `redirectUri` instead of `apiUrl`.
The JWT `iss` path still uses the request host.
- **Dashboard** (`page-client.tsx`, `providers.tsx`,
`oauth-callback-url.ts` new): brand-new custom providers get the
hexclave callback; existing providers keep whatever they had (edits
never silently move a registered redirect URL); the displayed Redirect
URL mirrors backend resolution.
- **Docs** (`migration.mdx`): existing `api.stack-auth.com` callbacks
keep working; only recreated providers use the hexclave URL.

## Notes / scope decisions

- **Dashboard-only injection**: SDK/CLI/legacy-config-created custom
providers fall back to the stack-auth callback (they don't auto-get the
hexclave URL).
- **shared → standard** conversions keep the stack-auth fallback rather
than flipping to hexclave (the safe path that never breaks a registered
redirect).

## Test plan

- [x] `typecheck` + `lint` green across stack-shared, backend,
dashboard, e2e
- [x] cloud-hosts unit tests, schema tests, schema fuzzer pass
- [x] e2e: shared-provider `customCallbackUrl` rejected (400);
standard-provider `customCallbackUrl` accepted and round-trips
- [ ] e2e OAuth authorize/callback flow (needs running stack) — reasoned
unaffected since localhost isn't a cloud host, so the redirect base
stays localhost as before

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Adds a per-provider `customCallbackUrl` for OAuth `redirect_uri`,
removing the request-host dependency and making redirects predictable.
Shared providers always use the Stack-branded callback; new or converted
custom providers default to the Hexclave-branded callback. Existing
callbacks keep working; no changes needed unless you recreate or convert
a provider.

- **New Features**
- Added `customCallbackUrl` on provider configs (URL-validated;
forbidden when `isShared` is true).
- `getProvider` now resolves a config-driven `redirectUri`; providers
take `redirectUri` instead of `apiUrl` (pure resolver with in-source +
e2e tests to lock legacy behavior).
- Introduced `@stackframe/stack-shared` `utils/cloud-hosts.tsx` and
dashboard helpers to show the resolved Redirect URL and set the Hexclave
callback for new providers and when converting shared → standard.

- **Bug Fixes**
- OAuth callback now handles legitimate cross-host flows by recording
the authorize host and skipping the host-scoped CSRF cookie when
authorize and callback hosts differ, relying on server-side state and
PKCE.

<sup>Written for commit 32d95fcdcb.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/hexclave/stack-auth/pull/1512?utm_source=github">Review
in cubic</a>

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

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

* **New Features**
* Preserve and display custom OAuth callback/redirect URLs in the
dashboard; provider creation/edit flows respect existing custom URLs.
* Added cloud-host mapping and redirect-uri helpers to resolve branded
API callback bases.

* **Bug Fixes**
* Improved cross-host OAuth callback handling and CSRF validation for
reliable cross-host flows.

* **Tests**
* Added E2E and unit tests covering callback URL behavior and host
mapping.

* **Documentation**
* Updated migration guidance for callback URL changes and recreation
scenarios.

<!-- 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/1512?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-28 12:28:38 -07:00
Bilal Godil
9bfd0af8fe Merge remote-tracking branch 'origin/dev' into cl/hexclave-pr3
# Conflicts:
#	README.md
#	packages/template/src/lib/stack-app/apps/implementations/session-replay.ts
2026-05-27 15:57:38 -07:00
tembo[bot]
244e7e79f2
Add captureWarning for warnings (#1506) 2026-05-27 15:35:10 -07:00
BilalG1
c753ab2831
fix(dashboard): show Stack Auth logo on left of rebrand modal (#1495)
## Summary

The Stack Auth → Hexclave rebrand modal added in
[#1493](https://github.com/hexclave/stack-auth/pull/1493) rendered the
**Hexclave** logo on both sides of its illustration instead of *Stack
Auth → Hexclave*.

## Root cause


[\`hexclave-rebrand-modal.tsx\`](https://github.com/hexclave/stack-auth/blob/dev/apps/dashboard/src/components/hexclave-rebrand-modal.tsx)
referenced \`/logo.svg\` and \`/logo-bright.svg\` for the left-hand
"Stack Auth" mark. But the visible-rebrand flip in
[#1481](https://github.com/hexclave/stack-auth/pull/1481) replaced those
files in \`apps/dashboard/public/\` with the Hexclave benzene mark — so
post-merge, both \`<Image>\` slots resolved to the Hexclave logo.

## Fix

- Restored the **pre-rebrand Stack Auth SVGs** (lifted from
\`57ff5d3ce~1\`, the commit before the brand-flip) under dedicated
filenames so they can't get clobbered the next time \`/logo.svg\` is
updated:
- \`apps/dashboard/public/stack-auth-logo.svg\` — black mark, light
theme
- \`apps/dashboard/public/stack-auth-logo-bright.svg\` — white mark,
dark theme
- Pointed the modal's left-hand \`<Image>\` pair at the new paths and
left a comment explaining why we don't share \`/logo.svg\` (so the next
person doesn't try to consolidate it back).

The originals on \`origin/dev\` (\`/logo.svg\`, \`/logo-bright.svg\` =
Hexclave) are untouched.

## Verification

- \`pnpm --filter @stackframe/dashboard lint\` — clean.
- Diff of
[hexclave-rebrand-modal.tsx](https://github.com/hexclave/stack-auth/blob/fix-stack-logo-in-modal/apps/dashboard/src/components/hexclave-rebrand-modal.tsx)
is two \`src=\` swaps plus a comment; the dismissal logic, gates, and
storage key are untouched.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes the rebrand modal to show the Stack Auth logo on the left instead
of rendering Hexclave on both sides. Restores pre-rebrand assets as
`stack-auth-logo.svg` and `stack-auth-logo-bright.svg` and updates the
modal to use them for light/dark themes.

<sup>Written for commit f4ed26266c.
Summary will update on new commits. <a
href="https://cubic.dev/pr/hexclave/stack-auth/pull/1495?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

* **Style**
* Updated the rebrand modal illustration assets to display Stack Auth
branding correctly.

<!-- 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/1495?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-27 10:09:16 -07:00
BilalG1
57ff5d3ce9
feat(hexclave): PR 2 — visible rebrand (Hexclave brand goes public) (#1481)
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 [#1475](https://github.com/hexclave/stack-auth/pull/1475)**
(`cl/hexclave-pr1`, the invisible compatibility layer). Diff vs that
base = the actual PR 2 code.

This is **PR 2 of the Stack Auth → Hexclave rebrand: the visible flip**.
Old wire identifiers (cookies, request/response headers, Bearer prefix,
JWT issuers, MCP tool name) keep working indefinitely via PR 1's
dual-accept. This PR flips every user-visible surface — package names
taught in docs, SDK class names in code examples, dashboard setup
snippets, page titles, error messages, email content, CLI binary,
default base URLs, GitHub repo slug, contributor guidance — to the
Hexclave brand.

See [`RENAME-TO-HEXCLAVE.md`](./RENAME-TO-HEXCLAVE.md) → *"PR 2: Rebrand
to Hexclave (visible)"* for the full per-work-area spec.

## What's implemented (per the plan's PR 2 scope)

- **SDK base URLs** flipped: `defaultBaseUrl` and
`defaultAnalyticsBaseUrl` in
[common.ts](packages/template/src/lib/stack-app/apps/implementations/common.ts:127)
→ `https://api.hexclave.com` / `https://r.hexclave.com`. PR 1's
[`getHardcodedFallbackUrls`](packages/stack-shared/src/utils/urls.tsx:199)
table now keys on the Hexclave domain.

- **Domain inventory sweep** (16 subdomains from the plan): every
`api/app/docs/discord/demo/mcp/skill/feedback/test/preview/r/api2/api.staging/idp-jwk-audience/built-with.stack-auth.com`
reference in production code, docs-mintlify, examples, READMEs, and
contributor guidance flipped to `*.hexclave.com`. Carve-outs: PR 1's
intentional JWT issuer dual-accept table in
[tokens.tsx](apps/backend/src/lib/tokens.tsx), the legacy `./docs/`
folder, the `unified-docs-widget` allowlist (deliberately accepts both
during DNS transition), and `url-targets.ts` hosted-component default
(baked into existing customer deploys).

- **`@deprecated` JSDoc** on every `Stack*` public export
([packages/template/src/lib/stack-app/index.ts](packages/template/src/lib/stack-app/index.ts)
+ [packages/template/src/index.ts](packages/template/src/index.ts)) —
`StackClientApp`, `StackServerApp`, `StackAdminApp` + every
constructor/options/JSON type, `StackHandler`, `StackProvider`,
`StackTheme`, `useStackApp`, `defineStackConfig`, `StackConfig`.
Hexclave\* aliases are now canonical.

- **Runtime `console.warn`**
([packages/template/src/internal/deprecation-warning.ts](packages/template/src/internal/deprecation-warning.ts))
— once-per-process when the SDK is loaded from a `@stackframe/*`
artifact. Detection uses the existing
`STACK_COMPILE_TIME_CLIENT_PACKAGE_VERSION_SENTINEL` (rewritten at build
time to e.g. `js @stackframe/stack@2.8.92` or `js
@hexclave/next@1.0.0`); `@hexclave/*` mirror artifacts short-circuit the
warning.

- **Tier 3 data migration**: new idempotent SQL migration
[`20260523000000_rename_internal_project_to_hexclave`](apps/backend/prisma/migrations/20260523000000_rename_internal_project_to_hexclave/migration.sql)
— updates the internal Project `displayName` 'Stack Dashboard' →
'Hexclave Dashboard' and `description` only if both still hold the
pre-rebrand defaults. Operator-renamed projects untouched, missing row
no-ops, re-runs are no-ops. [`seed.ts`](apps/backend/prisma/seed.ts:87)
default flipped. `getSharedEmailConfig("Stack Auth")` → `("Hexclave")`.

- **Tier 4 brand strings** (mechanical sweep, ~340 files):
- Page + OpenAPI titles (Hexclave API / Dashboard / REST API / Webhooks
API / Documentation). OpenAPI `info.description` documents
`X-Hexclave-*` headers as canonical with compat note on `X-Stack-*`.
- `HexclaveAssertionError` message text
([errors.tsx:71](packages/stack-shared/src/utils/errors.tsx:71)) — "an
error in Stack." → "an error in Hexclave."
- Known-error message templates
([known-errors.tsx](packages/stack-shared/src/known-errors.tsx)) flipped
to lead with `x-hexclave-*` + the new `docs.hexclave.com` URL; legacy
`x-stack-*` mentioned as compat aliases. **25 e2e test files updated in
lockstep**.
- Email content: failed-emails-digest body, sendTestEmail recipient (now
`sent-with-hexclave.com`), test-email-recipient default.
  - `CHANGELOG.md` title → "Hexclave Changelog".
- `AGENTS.md` env var convention: new vars prefix `HEXCLAVE_` /
`NEXT_PUBLIC_HEXCLAVE_` for Category A/B; legacy `STACK_*` explicitly
noted as accepted via PR 1's dual-read.

- **CLI / init wizard**:
- Every dashboard setup snippet, init-stack template, and docs-mintlify
page teaches `npx @hexclave/cli@latest init` (was
`@stackframe/stack-cli`).
[setup-page.tsx](apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/(overview)/setup-page.tsx)
+
[link-existing-onboarding](apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx).
- [init-stack](packages/init-stack/src/index.ts:634)
`STACK_*_INSTALL_PACKAGE_NAME_OVERRIDE` defaults flipped to
`@hexclave/*`.
- Generated `stack/client.ts` / `stack/server.ts` import from
`@hexclave/next` and reference `HexclaveClientApp` /
`HexclaveServerApp`.
- Internal `StackAuthKeys` dashboard component renamed to
`HexclaveKeys`.

- **docs-mintlify rewrite** (legacy `./docs/` intentionally untouched
per scoping decision):
- **78 MDX files swept**.
`@stackframe/{react,stack,js,tanstack-start,...}` →
`@hexclave/{react,stack,js,...}` in install snippets and code blocks;
`Stack*` SDK class names → `Hexclave*` in all code examples; 'Stack
Auth' brand phrase → 'Hexclave'.
- `openapi/{server,admin,client,webhooks}.json` titles → 'Hexclave REST
API' / 'Hexclave Webhooks API'.

- **Generators flipped before regeneration**:
-
[`packages/stack-shared/src/helpers/init-prompt.ts`](packages/stack-shared/src/helpers/init-prompt.ts),
[`/ai/prompts.ts`](packages/stack-shared/src/ai/prompts.ts),
[`apps/backend/src/lib/ai/prompts.ts`](apps/backend/src/lib/ai/prompts.ts),
[`apps/backend/src/lib/ai/tools/create-email-{template,draft}.ts`](apps/backend/src/lib/ai/tools/create-email-template.ts),
[`apps/skills/src/app/route.ts`](apps/skills/src/app/route.ts) (taught
MCP tool → `ask_hexclave` with compat note; CLI binary teach →
`hexclave`),
[`docs-mintlify/snippets/home-prompt-island.jsx`](docs-mintlify/snippets/home-prompt-island.jsx),
[`packages/template/README.md`](packages/template/README.md) +
integrations/convex/component/README.md.
  - `generate-sdks` propagated changes to `packages/{react,stack,js}`.

- **OpenAPI dual-documentation**:
[`apps/backend/src/app/api/latest/route.ts`](apps/backend/src/app/api/latest/route.ts)
now lists `X-Hexclave-*` headers as primary documented schemas with
`X-Stack-*` duplicates marked `.optional()` (both accepted at runtime by
PR 1's normalize-at-proxy shim).

- **`@stackframe/emails` virtual module**: dual-aliased to
`@hexclave/emails` at the bundler boundary
([email-rendering.tsx:89](apps/backend/src/lib/email-rendering.tsx:89)).
Stored email templates continue to import from either name; new
AI-generated templates and the system prompt teach `@hexclave/emails`.

- **Tier 2 mirror-publish wiring** (new this PR, lays the groundwork for
`@hexclave/*` first publish):
-
[`scripts/rewrite-packages-to-hexclave.ts`](scripts/rewrite-packages-to-hexclave.ts)
— rewrites 9 publishable `@stackframe/*` → `@hexclave/*` `package.json`
files (reads `HEXCLAVE_VERSION` env or `--version=` flag), pins
cross-deps to the shared `@hexclave` version, registers `hexclave` bin
alongside `stack` for `@hexclave/cli`.
-
[`.github/workflows/npm-publish.yaml`](.github/workflows/npm-publish.yaml)
appended with rewrite-then-republish step. `pnpm publish` skips
already-on-npm versions so reruns are safe.

- **Sender email domain**: `noreply@stackframe.co` →
`noreply@sent-with-hexclave.com` (the dedicated transactional-sender
domain split per the plan, to isolate bulk deliverability from
`hexclave.com` reputation); `security@` / `team@stack-auth.com` inbound
mailboxes → `@hexclave.com`.

- **Self-host docs**: docker network / container names in the bash
examples flipped from `stack-auth` to `hexclave` (`hexclave-postgres`,
`hexclave-clickhouse`, `hexclave.env`). The docker image tag
`stackauth/server:latest` stays per the plan's locked decision.

- **GitHub repo slug**: `hexclave/stack-auth` → `hexclave/hexclave` in
every `package.json` `repository` field, README link, CHANGELOG
raw-asset URL.

## Carve-outs (deliberately untouched)

-
**[`apps/backend/src/lib/tokens.tsx`](apps/backend/src/lib/tokens.tsx)**
JWT issuer dual-accept table — PR 1 intentional infrastructure, kept
indefinitely.
- **Legacy `./docs/` folder** — per scoping decision (only
`docs-mintlify/` rewritten).
- **`unified-docs-widget` hostname allowlist** — accepts both
`.hexclave.com` (canonical) and `.stack-auth.com` (transition window)
for DNS rollout.
- **`url-targets.ts`** hosted-domain default
`.built-with-stack-auth.com` — wire identifier baked into existing
customer deploys; indefinite read-fallback.
- **Binary visual assets** (logos, favicons, OG images, README
screenshots) — out of scope for this PR. Need design work; tracked
separately.

## Verification

- **`pnpm typecheck`** on
`packages/{template,stack-shared,react,stack,js}` + `apps/dashboard`:
**all green**. The remaining backend / e-commerce-demo typecheck errors
are pre-existing (Prisma codegen output +
`./generated/api-versions.json` not present in fresh worktrees without
`pnpm run codegen-prisma` + a live DB) and unrelated to this diff.
- **`pnpm lint`** on the same 6 packages: all green.
- **Final grep** for residual `Stack Auth` / `stack-auth.com` /
`@stackframe/stack-cli@latest` references: zero outside the intentional
carve-outs above.
- **25 e2e test files updated in lockstep** with the known-error message
changes (asserted strings flipped to match the new x-hexclave-* +
compat-note messages).

## Deploy blockers (ops sequencing before this rebrand goes live)

This PR is code-complete, but the rebrand's visible surfaces (SDK
default URLs, dashboard links, npm READMEs, REST error messages, runtime
deprecation warning) all point at `*.hexclave.com` / `@hexclave/*`
resources that don't exist yet. None of these are fixable from a PR —
they're ops/registrar/npm work that has to be sequenced before merging
this to a release tag.

Suggested ordering, hardest blockers first:

### Tier 1 — required before customer-facing deploy (everything below
this line *will visibly break customers on day 1* if skipped)

1. **DNS + TLS for `api.hexclave.com` + `api1./api2.hexclave.com`** →
must point at the same backend that serves `api.stack-auth.com` (or a
backend that mirrors PR 1's dual-accept). The SDK's new `defaultBaseUrl`
is `https://api.hexclave.com`; every customer that relied on the old
default and upgrades to a post-PR2 SDK build sends API requests here.
Until this resolves, every default-config customer's API call NXDOMAINs.
2. **DNS for `app.hexclave.com`** → the dashboard. Referenced in the
SDK's default-error messages ("Please create a project on the Hexclave
dashboard at https://app.hexclave.com"), the init-stack flow's
`wizard-congrats` redirect, and the OAuth dashboard handoff.
3. **DNS for `docs.hexclave.com`** + Mintlify deploy → the SDK runtime
deprecation warning (`https://docs.hexclave.com/migration`), every
README, every "Learn more" link in the dashboard, and every REST API
error body (`/api/overview#authentication`) points here. The MDX is in
this PR; the docs build target needs DNS.
4. **DNS for `mcp.hexclave.com`** → the MCP server endpoint that every
taught agent integration (`claude mcp add ...`, `cursor`, `codex`,
`vscode`) registers. Until this resolves, every `npx
@hexclave/cli@latest init` MCP-registration step fails.
5. **Reserve the `@hexclave` npm scope + set repo variable
`HEXCLAVE_VERSION`** → the mirror-publish step in
`.github/workflows/npm-publish.yaml` is gated on this variable. Without
it, the entire taught onboarding command `npx @hexclave/cli@latest init`
404s from the npm registry, *and* every README that says "install
`@hexclave/next`" leads to install failure. Pick the initial version
intentionally (`1.0.0` or aligned to `@stackframe/stack`); don't accept
a silent default.

### Tier 2 — required before announcing the rebrand publicly (lookalike
or low-traffic surfaces, but visibly broken)

6. **DNS for `r.hexclave.com`** → the analytics beacon
`defaultAnalyticsBaseUrl`. Silent failure if missing (analytics drops),
but should land alongside Tier 1.
7. **Register `sent-with-hexclave.com` + full email auth (SPF / DKIM /
DMARC)** → the new default sender domain for shared-sender transactional
emails. Without it the dashboard "send test email" path emits bounces,
and shared-sender flows (`getSharedEmailConfig("Hexclave")`) deliver to
spam at best.
8. **MX + SPF / DMARC for `hexclave.com`** → `team@hexclave.com` and
`security@hexclave.com` mailboxes. The security disclosure mailbox is
referenced in [`.github/SECURITY.md`](.github/SECURITY.md);
`team@hexclave.com` is the actual recipient of internal feedback emails
sent at runtime by
[`apps/backend/src/lib/internal-feedback-emails.tsx`](apps/backend/src/lib/internal-feedback-emails.tsx).
Today, every runtime feedback email bounces.
9. **DNS for `skill.hexclave.com`** → the canonical AI-agent skill fetch
URL (the agent bootstrap pivot). Without it, the entire "agent downloads
`SKILL.md` from a known URL" flow taught in
[`packages/stack-shared/src/helpers/init-prompt.ts`](packages/stack-shared/src/helpers/init-prompt.ts)
fails.
10. **Create `github.com/hexclave/hexclave` as a public repo** (even as
a redirect to `hexclave/stack-auth`) **OR** rewrite every `package.json`
`"repository"` field + dashboard footer "view on GitHub" link to point
at `hexclave/stack-auth` (which already exists). Currently every npm
package page's "Repository" link is dead, and the dashboard's GitHub
button + dev-tool repo link are dead.

### Tier 3 — broken but low-visibility / low-traffic

11. **DNS for `discord.hexclave.com`** → Discord invite redirect, used
in every README's chip and the dashboard footer.
12. **DNS for `demo.hexclave.com`** → " Demo" badge in every npm
package README. Broken-image badge on the package page.
13. **DNS + TLS for `built-with-hexclave.com`** → optional
hosted-handler domain (the default reverted to
`.built-with-stack-auth.com` in this PR's carve-outs, so this only
matters for projects that manually flip).

## Other follow-ups (not deploy-blocking)

- **E2E snapshot regen across the full suite** for the dual-emitted
`x-hexclave-*` response headers (PR 1 follow-up; `vitest -u` in CI
absorbs).
- **Binary visual assets** — logos, favicons, OG images, README
screenshots; need design pass.
- **Backend OpenAPI fumadocs regen** in CI flow — the JSON files in
`docs-mintlify/openapi/` are committed but regen runs in CI. Verify the
workflow that does this still works against the post-PR2 source.
- **Backend typecheck infra debt** — needs `codegen-prisma` +
`codegen-route-info` to clear; pre-existing, unaffected by this PR.

## Test plan

- [ ] CI runs full e2e suite (with `vitest -u` to absorb residual
snapshot deltas, then committed back).
- [ ] Spot-check: new `@hexclave/cli init` (once published) generates
`hexclave.config.ts` and works against a fresh project.
- [ ] Spot-check: existing customer with `@stackframe/stack` import sees
the once-per-process `console.warn` recommending `@hexclave/next` on SDK
init.
- [ ] Manual: dashboard setup page renders the `npx @hexclave/cli@latest
init` snippet and the `x-hexclave-publishable-client-key` API header in
the curl example.
- [ ] Manual: a fresh `pnpm run prisma migrate` against a clean DB sets
the internal project displayName to 'Hexclave Dashboard'.

---------

Co-authored-by: Konstantin Wohlwend <n2d4xc@gmail.com>
2026-05-26 19:18:20 -07:00
Bilal Godil
50860459a5 fix(dashboard): update hexclave-rebrand-modal import to @hexclave/next
The rebrand modal was added on the rebrand-modal branch (PR #1493) and
still imported useUser from the pre-rename package name @stackframe/stack.
After this branch's source rename to @hexclave/*, that package no longer
exists in the workspace, causing the dashboard Turbopack build to fail
with 'Module not found: Can't resolve @stackframe/stack' and aborting the
E2E job.
2026-05-26 18:57:30 -07:00
BilalG1
28efd8b133
Merge branch 'cl/romantic-mendel-5a2c25' into cl/hexclave-pr3 2026-05-26 18:48:37 -07:00
BilalG1
394a15192b
Merge branch 'dev' into cl/romantic-mendel-5a2c25 2026-05-26 18:48:09 -07:00
BilalG1
0a85a49772
Merge branch 'cl/romantic-mendel-5a2c25' into cl/hexclave-pr3 2026-05-26 18:16:36 -07:00
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
Armaan Jain
a27e4d9bb5
Small onboarding fixes (#1489)
<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/hexclave/stack-auth/blob/dev/CONTRIBUTING.md

-->

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Improves onboarding and analytics visuals. Adds clear Stripe setup
actions (Connect or Do Later) with safe redirects and precise
loading/disabled states, and fixes a stuck dashboard reload after
linking an existing project.

- **New Features**
- Payments onboarding: separate Connect/Do Later actions with per-button
loading and mutual disabling.
- US-only: “Do Later” creates a deferred Stripe account before finishing
onboarding.
- Secure redirect: enforce HTTPS on Connect and navigate via
window.location.href.
- Refresh Stripe account cache after `setupPayments()` to avoid stale
data on return.
- Analytics: smoother pie hover transitions, fading center label,
optional `showDateRange`; dashboard donut hides date range and adjusts
radii; revenue hover chart uses split bars for rounded tops and an avg
line.
- Tests cover deferred/unsupported payments setup and button loading
isolation.

- **Bug Fixes**
- After linking an existing config, use a full page navigation to the
project to prevent the dashboard from getting stuck on initial load.

<sup>Written for commit c80034ad1f.
Summary will update on new commits. <a
href="https://cubic.dev/pr/hexclave/stack-auth/pull/1489?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

* **New Features**
* Option to defer payments setup during project onboarding;
connect/defer actions show targeted loading states.

* **Improvements**
* Linking existing projects now performs full navigation when
applicable.
* Charts: refined donut/pie sizing, smoother center fade animation,
optional date-range display, and improved color/stack rendering.
  * Payments setup now refreshes account info after setup.

* **Tests**
* Added tests covering payments deferral, connect flows, and UI/loading
behavior.

<!-- 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/1489?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-26 17:45:50 -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
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
github-actions[bot]
18df895842 chore: update package versions 2026-05-26 21:59:38 +00: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
github-actions[bot]
ad197de7fe chore: update package versions 2026-05-26 20:28:07 +00:00
Bilal Godil
46f5233bbb chore(hexclave): scrub references to deleted RENAME-TO-HEXCLAVE.md
9 source comments pointed at the planning doc removed in the prior commit.
Drop the 'See RENAME-TO-HEXCLAVE.md' sentence/parenthetical from each;
keep the surrounding substantive context intact (CORS allowlist derivation,
JWT issuer dual-acceptance rationale, OIDC opaque-identifier carve-out
explanation, Hexclave/Stack alias rationale).
2026-05-26 10:43:52 -07:00
Bilal Godil
1b54ee9628 Merge branch 'cl/romantic-mendel-5a2c25' into cl/hexclave-pr3
# Conflicts:
#	apps/backend/package.json
#	apps/dashboard/package.json
#	apps/dev-launchpad/package.json
#	apps/e2e/package.json
#	apps/hosted-components/package.json
#	apps/internal-tool/package.json
#	apps/mcp/package.json
#	apps/mock-oauth-server/package.json
#	apps/skills/package.json
#	docs-mintlify/package.json
#	docs/package.json
#	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
#	sdks/implementations/swift/package.json
#	sdks/spec/package.json
2026-05-26 10:15:27 -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
github-actions[bot]
bef9452c95 chore: update package versions 2026-05-26 03:44:50 +00: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
Bilal Godil
e8f71c1d19 fix(hexclave): address PR 3 multi-agent review findings
Six fixes from the four parallel reviewers on the rename PR:

1. **Backend .well-known/ routes** — the sweep's directory walker had a
   bug that skipped every dot-prefixed dir (intended to exclude .git /
   .turbo / etc.), which also caught Next.js .well-known/ route folders.
   Two route handlers under apps/backend/.well-known/ still imported
   @stackframe/stack-shared/dist/* — flipped to @hexclave/shared/dist/*.

2. **Legacy docs/ folder excluded from workspace** — docs/ is the legacy
   fumadocs site, no longer maintained (replaced by docs-mintlify/).
   Per user direction, kept on disk for migration reference but dropped
   from pnpm-workspace.yaml so it no longer gates install / typecheck /
   lint. This is the right call given the typecheck failures in
   docs/src/ from the sweep carve-out were never going to be fixed.

3. **Root package.json scripts** — removed every `--filter=@hexclave/docs`
   reference now that docs/ isn't in the workspace: build:docs (rerouted
   to @hexclave/docs-mintlify), dev / dev:tui / dev:docs (dropped the
   filter), and the dead 'fern' script (was @hexclave/docs-only).

4. **build:demo filter** — fixed pre-existing bug where the script
   filtered package name 'demo-app', but the package is
   '@hexclave/example-demo-app'. Never resolved before, fixed now.

5. **github-config-push.test.ts legacy fallback** — the sweep flipped the
   test 'preserves the existing @stackframe/* import package…' from
   @stackframe/react to @hexclave/react, which made it a duplicate of
   the test above it and eliminated all coverage of the legacy regex
   branch in detectImportPackage. Renamed the modified test to reflect
   what it now tests, and added a new parallel test that feeds an
   @stackframe/react import and asserts the legacy import is preserved
   on output. Both branches of the dual-name regex are now covered.

6. **examples/react-example version** — the only package the sweep
   missed for the 1.0.0 version reset (unscoped name 'react-example'
   wasn't in the rename map). Bumped 2.8.103 → 1.0.0 for consistency.

Verification on a clean install:
- `pnpm install --frozen-lockfile` — clean (only pre-existing
  @vercel/mcp-adapter bin warnings).
- `pnpm typecheck` — 28/28 tasks green across the whole workspace.
- `pnpm lint` — 28/28 tasks green.

Reviewers flagged but I did NOT change (out of scope or non-actionable):
- npm-publish.yaml GH Environment name still says 'hexclave/stack-auth'
  — env names are managed in repo settings, not in YAML; cosmetic.
- RENAME-TO-HEXCLAVE.md references the deleted rewrite script — it's
  a planning doc / historical record, leaving as-is.
- code-examples and migration.mdx user-facing references to
  @stackframe/* — these are documentation that teaches the rename, by
  design they mention both names.
2026-05-23 17:41:53 -07:00
Bilal Godil
7125a9eff4 feat(hexclave): rename @stackframe/* → @hexclave/* (PR 3)
Source rename across the monorepo. Every publishable package now ships
under its @hexclave/* name natively, no rewrite-at-publish indirection.

Workflow + tooling:
- Delete scripts/rewrite-packages-to-hexclave.ts (one-shot mirror).
- Remove the mirror-publish block from .github/workflows/npm-publish.yaml.
  The remaining `pnpm publish -r` step publishes @hexclave/* natively.
- Flip the auto-bump changeset target from @stackframe/stack to
  @hexclave/next so 'Update package versions on dev' keeps working.
- Delete packages/template/src/internal/deprecation-warning.ts and its
  imports — @hexclave/* never warns about itself, and after PR 3 no
  @stackframe/* artifact is ever built from source again.

Package renames (publishable):
  @stackframe/react              → @hexclave/react
  @stackframe/stack              → @hexclave/next
  @stackframe/js                 → @hexclave/js
  @stackframe/stack-shared       → @hexclave/shared
  @stackframe/stack-ui           → @hexclave/ui
  @stackframe/stack-sc           → @hexclave/sc
  @stackframe/stack-cli          → @hexclave/cli
  @stackframe/tanstack-start     → @hexclave/tanstack-start
  @stackframe/dashboard-ui-components → @hexclave/dashboard-ui-components

Internal monorepo packages (private, never published) also renamed for
brand consistency: backend, dashboard, docs, mcp, skills, e2e-tests,
example apps, the swift-sdk, the monorepo root, etc. Cost is mechanical;
payoff is no stray @stackframe/* names left under apps/, examples/, sdks/.

Carve-outs intentionally kept under their legacy names:
- @stackframe/emails — virtual module imported by customer-stored email
  templates; the renderer in apps/backend/src/lib/email-rendering.tsx
  dual-aliases both names to the same backing module indefinitely.
- @stackframe/template — internal codegen source, never published; per
  docs-mintlify/migration.mdx 'internal packages keep names'.
- @stackframe/init-stack — deprecated; now marked private: true so the
  last published version on npm continues to serve old install commands
  but the workspace stops publishing it.

Backward-compat detection (so projects still on the last @stackframe/*
release keep working):
- packages/stack-shared/src/config-rendering.ts — CONFIG_IMPORT_PACKAGES
  table includes both @hexclave/* (canonical, first match wins) and
  legacy @stackframe/* names. Function renamed
  detectStackframeImportPackage → detectConfigImportPackage.
- apps/dashboard/src/lib/github-config-push.ts — import detection regex
  now matches both @hexclave/<name> and @stackframe/<name>, hexclave
  preferred.

Versions: every renamed package reset to 1.0.0 in source. The repo's
existing 'bump versions before merging to main' flow will move them to
1.0.1 on the first publish run, so the dual-publish 1.0.0 from PR 2 is
not overwritten.

Other touch-ups discovered during sweep:
- Root package.json: 'fern' script filter was @stackframe/docs (legacy
  typo, never resolved) → @hexclave/docs.
- README.md contributor note: @stackframe/XYZ → @hexclave/XYZ.
- packages/stack-cli/package.json: register `hexclave` bin alongside
  the legacy `stack` bin so `npx @hexclave/cli init` works on the
  natively-published artifact (PR 1481's rewrite script did this at
  publish time; now it's in source).
- packages/template/package-template.json: per-platform names + version
  flipped to hexclave + 1.0.0 to stay in sync with generated package.json.
- docs/package.json (legacy fumadocs folder, otherwise carved out of the
  brand sweep): workspace deps and name updated minimally so `pnpm
  install` resolves — content (MDX) intentionally untouched per the
  PR 2 scoping decision.

Carve-out files (skipped entirely by the sweep, intentional history):
- docs-mintlify/migration.mdx — teaches the rename, references both.
- RENAME-TO-HEXCLAVE.md — planning doc, references both indefinitely.
- legacy docs/ folder — content untouched per PR 2 carve-out.

generate-sdks regenerated packages/{react,stack,js} from template.
pnpm-lock.yaml regenerated. Typecheck green on stack-shared, stack, js,
react. Dashboard typecheck has pre-existing 'X is of type unknown'
errors that need to be investigated separately (likely a local
node_modules build state issue, not source).
2026-05-23 17:41:53 -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
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
github-actions[bot]
957a33a651 chore: update package versions 2026-05-23 18:13:12 +00:00
github-actions[bot]
6a0ded1340 chore: update package versions 2026-05-23 16:45:36 +00:00
Mantra
9b1851dd54
Managed email domain deletion and Cloudflare DNS import UX (#1442)
## Summary
- Add an admin-only delete endpoint and SDK method to remove managed
email domains, with Resend/DNSimple cleanup and a guard against deleting
domains currently in use for sending.
- Add dashboard UI to remove unused managed domains (with confirmation)
and improve the DNS setup step with Cloudflare detection, zone file
download, and import instructions.
- Add E2E coverage for delete auth, success, in-use rejection,
post-switch deletion, and 404 cases.

## Test plan
- [ ] Run `pnpm test run managed-email-onboarding`
- [ ] In dashboard email settings, add a managed domain and verify
Cloudflare hint appears when NS records point to Cloudflare
- [ ] Remove an unused managed domain and confirm it disappears from the
list
- [ ] Verify active (in-use) managed domains cannot be deleted until
email provider is switched away


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

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

* **New Features**
* Delete managed email domains from the dashboard with a confirmation
flow and success notification
* Cloudflare-aware domain setup: detection banner, quick links to
Cloudflare DNS, downloadable zone file, and import instructions
  * Admin API and admin-app method to perform managed-domain deletion

* **Bug Fixes**
* Deletion blocked with a clear error when a domain is actively used for
sending

* **Tests**
* Added end-to-end coverage for managed-domain delete scenarios
(success, in-use conflict, auth rejection, and 404)

* **Style**
* Data grid layout adjusted to prevent unintended full-height stretching
across various tables

<!-- 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/1442?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 -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-23 09:22:29 -07:00
github-actions[bot]
01948e2313 chore: update package versions 2026-05-23 03:30:16 +00:00
github-actions[bot]
62aa8616d5 chore: update package versions 2026-05-23 03:25:52 +00:00
Konsti Wohlwend
b48902fcf2
docs: restart changelog with weekly updates (#1478) 2026-05-22 20:18:05 -07:00
github-actions[bot]
70999df64e chore: update package versions 2026-05-23 01:02:03 +00:00
Konsti Wohlwend
7e70b11d80
Fix onboarding shared OAuth provider persistence (#1477) 2026-05-22 17:54:11 -07:00
github-actions[bot]
9355c8665c chore: update package versions 2026-05-22 23:02:49 +00:00
github-actions[bot]
cd29811456 chore: update package versions 2026-05-22 22:58:20 +00:00
github-actions[bot]
0c6e135c30 chore: update package versions
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
2026-05-22 01:35:39 +00:00
Konstantin Wohlwend
99f07e9516 Trust hosted domains
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-21 18:23:23 -07:00
Konsti Wohlwend
9fc7332ead
Restore sign-up setting descriptions (#1469) 2026-05-21 17:58:24 -07:00
github-actions[bot]
d12968eb3d chore: update package versions 2026-05-22 00:46:34 +00:00
github-actions[bot]
03e7b61308 chore: update package versions 2026-05-21 23:29:36 +00:00
Konstantin Wohlwend
bf8d0ece28 chore: update package versions 2026-05-21 16:23:12 -07:00