Skip to content

feat(hexclave): PR 3 — native @hexclave/* source rename + delete dual-publish wiring#1482

Open
BilalG1 wants to merge 47 commits into
devfrom
cl/hexclave-pr3
Open

feat(hexclave): PR 3 — native @hexclave/* source rename + delete dual-publish wiring#1482
BilalG1 wants to merge 47 commits into
devfrom
cl/hexclave-pr3

Conversation

@BilalG1
Copy link
Copy Markdown
Collaborator

@BilalG1 BilalG1 commented May 23, 2026

Summary

Stacked on #1481 (cl/romantic-mendel-5a2c25, PR 2's visible rebrand). Diff vs that base = ~1000 files of mechanical source rename + deletion of the dual-publish indirection.

This is PR 3 of the Stack Auth → Hexclave rebrand: native source rename. PR 2 added the rewrite-at-publish-time mechanism that re-published every @stackframe/* artifact as a @hexclave/* mirror on each push to main. PR 3 makes Hexclave the canonical source identity — every publishable package is renamed in source, scripts/rewrite-packages-to-hexclave.ts is deleted, the workflow's mirror-publish block is gone, and the deprecation-warning runtime is removed (no @stackframe/* artifact is ever built from source again).

Cutover ordering

PR 3 is intentionally landed after the first publish triggered by PR 2's mirror flow:

  1. PR 2 merges → first push to main publishes @stackframe/*@<bumped> (carrying the deprecation warning) AND @hexclave/*@1.0.0 (the one-shot mirror, version hardcoded in PR 2's workflow).
  2. PR 3 merges → the existing Update package versions on dev pre-merge bump moves source from 1.0.01.0.1, so the first push to main after this lands publishes @hexclave/*@1.0.1 natively (no collision with PR 2's @hexclave/*@1.0.0).
  3. From then on, @stackframe/* is frozen at its final warning version on npm; only @hexclave/* is published.

What's implemented (per the plan's PR 3 scope)

Package renames

The 9 publishable packages, native source rename:

Old name New name
@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 (backend, dashboard, mcp, skills, e2e-tests, swift-sdk, all examples, the monorepo root, etc.) also renamed to @hexclave/* for brand consistency. All private, never published — cost is purely mechanical, payoff is no stray @stackframe/* names left in apps/, examples/, sdks/.

Deleted

  • scripts/rewrite-packages-to-hexclave.ts (~200 lines) — no longer needed; source packages publish natively.
  • packages/template/src/internal/deprecation-warning.ts + its import sites in packages/template/src/index.ts and generated SDKs (~60 lines) — no @stackframe/* artifact is ever built from source again, so the runtime warning has nothing to detect.
  • The mirror-publish block in .github/workflows/npm-publish.yaml (~30 lines): Checkout main for Hexclave mirror rewrite, Rewrite package names to @hexclave/*, Publish @hexclave/* mirror packages. The remaining Publish packages step publishes @hexclave/* natively.
  • The auto-bump's changeset target flipped from "@stackframe/stack": patch to "@hexclave/next": patch.

Versions reset to 1.0.0

Every renamed publishable package + the kept-name @stackframe/template + @stackframe/init-stack reset to 1.0.0. The existing Update package versions on dev pre-merge bump moves them to 1.0.1 on first run — that's the first natively-published Hexclave version, sequenced after PR 2's mirror-published 1.0.0.

Carve-outs (deliberately kept under their legacy names)

  • @stackframe/emails — virtual module imported by customer-stored email templates. The renderer at apps/backend/src/lib/email-rendering.tsx:89 dual-aliases both @stackframe/emails and @hexclave/emails to the same backing module — old stored templates keep rendering indefinitely. ~47 references in e2e test fixtures (embedded TSX-as-string) preserved as-is.
  • @stackframe/template — internal codegen source in packages/template/. Never published. Per docs-mintlify/migration.mdx, "internal packages keep names."
  • @stackframe/init-stack — deprecated; now private: true in packages/init-stack/package.json so the workspace stops publishing it. The last @stackframe/init-stack@<last> on npm continues to serve any stale npx @stackframe/init-stack@latest calls.

Backward-compat detection (so projects pinned to the last legacy release keep working)

Hexclave CLI bin alias

packages/stack-cli/package.json declares both hexclave and stack bins natively in source. PR 2's rewrite script added this at publish time; PR 3 bakes it in.

Legacy docs/ folder excluded from workspace

docs/ is the legacy fumadocs site, no longer maintained — replaced by docs-mintlify/. Dropped from pnpm-workspace.yaml so it no longer gates install / typecheck / lint. Folder kept on disk for migration reference. Root scripts that filtered @hexclave/docs (build:docs, dev, dev:tui, dev:docs, fern) rerouted to @hexclave/docs-mintlify or dropped.

Multi-agent diff review

Four parallel reviewers (package/deps integrity, source-level rename correctness, workflow/CI/scripts, e2e tests + fixtures) audited the diff. Six actionable findings, all addressed:

  1. Backend .well-known/ routes still on @stackframe/stack-shared/dist/* — original sweep's dir walker had a bug that skipped dot-prefixed dirs (intended to exclude .git/.turbo); also caught Next.js's .well-known/. Fixed.
  2. docs/src/ had 25 unresolved imports breaking @hexclave/docs typecheck — fixed by removing legacy docs/ from workspace per direction.
  3. github-config-push.test.ts legacy-fallback test was silently de-tested by the sweep — fixed by renaming the modified test and adding a new parallel case exercising the legacy regex branch.
  4. examples/react-example/package.json version still 2.8.103 (sweep missed unscoped name) — bumped to 1.0.0.
  5. Root build:demo filter targeted nonexistent demo-app (pre-existing bug) — fixed to @hexclave/example-demo-app....
  6. Stale --filter=@hexclave/docs references in root scripts after Backend design doc #2rerouted to @hexclave/docs-mintlify.

Verification

  • pnpm install --frozen-lockfile — clean.
  • pnpm typecheck28/28 tasks green across the whole workspace.
  • pnpm lint28/28 tasks green.
  • All four parallel reviewer findings addressed in commit 839d6fe86.

Diff stats

~1000 files, mostly mechanical. The non-mechanical surface fits in:

  • Workflow + rewrite-script deletions.
  • Two backward-compat detection sites (config-rendering, github-config-push).
  • Test coverage for the legacy fallback branch.
  • Legacy docs/ workspace removal.

Test plan

  • CI runs full lint + build + typecheck matrix green.
  • After PR 2 has published @hexclave/*@1.0.0 on first push to main, verify the pre-merge bump moves PR 3's source from 1.0.01.0.1.
  • On PR 3 merge to main: verify CI publishes @hexclave/*@1.0.1 natively (no rewrite step). Spot-check: npm view @hexclave/next@1.0.1.
  • Verify no @stackframe/*@<new> ever publishes again — the workflow's first Publish packages step is now the only one, and it publishes the renamed source.
  • Spot-check: npx @hexclave/cli@1.0.1 init works on the natively-published artifact (no longer depends on the rewrite script's dist-rewrite of cross-package require() specifiers).
  • Spot-check: a project on the last @stackframe/stack@<final> release with config importing import type { StackConfig } from "@stackframe/stack" — the dashboard's GitHub config-push flow preserves that legacy import on re-render (covered by the new test case).

Summary by cubic

Renamed all publishable packages to the @hexclave/* scope and removed the dual‑publish mirror so we build and publish natively as Hexclave. Updated imports, CI/workflows (including qemu), docs, and tests to match.

  • Refactors

    • Renamed all publishable packages to @hexclave/* and updated workspaces/imports; apps/backend is now @hexclave/backend.
    • Removed mirror‑publish flow and deleted scripts/rewrite-packages-to-hexclave.ts; auto‑bump now targets @hexclave/next.
    • Reset versions to 1.0.0 (first native publish is 1.0.1); carve‑outs kept: @stackframe/emails, @stackframe/template, @stackframe/init-stack (private).
    • Added hexclave CLI bin; switched CI/build filters (including qemu emulator build) to @hexclave/*.
    • Deleted the rebrand planning doc and scrubbed references; excluded legacy docs/ from the workspace.
  • Bug Fixes

    • Demo and route fixes: TanStack Start SSR noExternal regex /^@hexclave\//; fixed leftover @stackframe/* imports in Next.js .well-known/ routes; corrected demo build filters.
    • Updated links/identifiers and tests: docs footer GitHub link, README header/setup link and alt text, E2E clientApp.version sentinel (@hexclave/js), CLI doctor import regex, and legacy import fallback test.
    • Dashboard rebrand modal: switched import to @hexclave/next to fix Turbopack build.

Written for commit 0e8aa52. Summary will update on new commits. Review in cubic

@vercel
Copy link
Copy Markdown

vercel Bot commented May 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
stack-auth-hosted-components Ready Ready Preview, Comment May 27, 2026 2:31am
stack-auth-internal-tool Ready Ready Preview, Comment May 27, 2026 2:31am
stack-auth-mcp Ready Ready Preview, Comment May 27, 2026 2:31am
stack-auth-skills Ready Ready Preview, Comment May 27, 2026 2:31am
stack-backend Ready Ready Preview, Comment May 27, 2026 2:31am
stack-dashboard Ready Ready Preview, Comment May 27, 2026 2:31am
stack-demo Ready Ready Preview, Comment May 27, 2026 2:31am
stack-docs Error Error May 27, 2026 2:31am
stack-preview-backend Ready Ready Preview, Comment May 27, 2026 2:31am
stack-preview-dashboard Ready Ready Preview, Comment May 27, 2026 2:31am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 23, 2026

Important

Review skipped

Too many files!

This PR contains 300 files, which is 150 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 28e2ee52-0db1-4418-96d7-8e3073c15aa8

📥 Commits

Reviewing files that changed from the base of the PR and between 57ff5d3 and 0e8aa52.

📒 Files selected for processing (300)
  • .github/workflows/npm-publish.yaml
  • .github/workflows/qemu-emulator-build.yaml
  • README.md
  • RENAME-TO-HEXCLAVE.md
  • apps/backend/instrumentation-client.ts
  • apps/backend/package.json
  • apps/backend/prisma/seed.ts
  • apps/backend/scripts/backfill-internal-free-plans.ts
  • apps/backend/scripts/benchmark-internal-metrics.ts
  • apps/backend/scripts/clickhouse-migrations.ts
  • apps/backend/scripts/generate-migration-imports.ts
  • apps/backend/scripts/generate-openapi-fumadocs.ts
  • apps/backend/scripts/generate-private-sign-up-risk-engine.ts
  • apps/backend/scripts/regen-internal-subscriptions-to-latest.ts
  • apps/backend/scripts/run-bulldozer-studio.ts
  • apps/backend/scripts/run-cron-jobs.ts
  • apps/backend/scripts/run-email-queue.ts
  • apps/backend/scripts/verify-data-integrity/api.ts
  • apps/backend/scripts/verify-data-integrity/clickhouse-sync-verifier.ts
  • apps/backend/scripts/verify-data-integrity/index.ts
  • apps/backend/scripts/verify-data-integrity/payments-verifier.ts
  • apps/backend/scripts/verify-data-integrity/stripe-payout-integrity.ts
  • apps/backend/src/analytics.tsx
  • apps/backend/src/app/api/latest/(api-keys)/handlers.tsx
  • apps/backend/src/app/api/latest/ai/query/[mode]/route.ts
  • apps/backend/src/app/api/latest/analytics/events/batch/route.tsx
  • apps/backend/src/app/api/latest/auth/anonymous/sign-up/route.ts
  • apps/backend/src/app/api/latest/auth/cli/complete/route.tsx
  • apps/backend/src/app/api/latest/auth/cli/poll/route.tsx
  • apps/backend/src/app/api/latest/auth/cli/route.tsx
  • apps/backend/src/app/api/latest/auth/mfa/sign-in/verification-code-handler.tsx
  • apps/backend/src/app/api/latest/auth/oauth/authorize/[provider_id]/route.tsx
  • apps/backend/src/app/api/latest/auth/oauth/callback/[provider_id]/route.tsx
  • apps/backend/src/app/api/latest/auth/oauth/callback/apple/native/route.tsx
  • apps/backend/src/app/api/latest/auth/oauth/connected-accounts/[provider_id]/access-token/route.tsx
  • apps/backend/src/app/api/latest/auth/oauth/cross-domain/authorize/route.tsx
  • apps/backend/src/app/api/latest/auth/oauth/oauth-helpers.tsx
  • apps/backend/src/app/api/latest/auth/oauth/token/route.tsx
  • apps/backend/src/app/api/latest/auth/otp/send-sign-in-code/route.tsx
  • apps/backend/src/app/api/latest/auth/otp/sign-in/verification-code-handler.tsx
  • apps/backend/src/app/api/latest/auth/passkey/initiate-passkey-authentication/route.tsx
  • apps/backend/src/app/api/latest/auth/passkey/initiate-passkey-registration/route.tsx
  • apps/backend/src/app/api/latest/auth/passkey/register/verification-code-handler.tsx
  • apps/backend/src/app/api/latest/auth/passkey/sign-in/verification-code-handler.tsx
  • apps/backend/src/app/api/latest/auth/password/reset/verification-code-handler.tsx
  • apps/backend/src/app/api/latest/auth/password/send-reset-code/route.tsx
  • apps/backend/src/app/api/latest/auth/password/set/route.tsx
  • apps/backend/src/app/api/latest/auth/password/sign-in/route.tsx
  • apps/backend/src/app/api/latest/auth/password/sign-up/route.tsx
  • apps/backend/src/app/api/latest/auth/password/update/route.tsx
  • apps/backend/src/app/api/latest/auth/sessions/crud.tsx
  • apps/backend/src/app/api/latest/auth/sessions/current/refresh/route.tsx
  • apps/backend/src/app/api/latest/auth/sessions/current/route.tsx
  • apps/backend/src/app/api/latest/auth/sessions/route.tsx
  • apps/backend/src/app/api/latest/check-feature-support/route.tsx
  • apps/backend/src/app/api/latest/check-version/route.ts
  • 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/app/api/latest/connected-accounts/[user_id]/crud.tsx
  • apps/backend/src/app/api/latest/connected-accounts/access-token-helpers.tsx
  • apps/backend/src/app/api/latest/contact-channels/[user_id]/[contact_channel_id]/send-verification-code/route.tsx
  • apps/backend/src/app/api/latest/contact-channels/crud.tsx
  • apps/backend/src/app/api/latest/contact-channels/send-verification-code/route.tsx
  • apps/backend/src/app/api/latest/contact-channels/verify/verification-code-handler.tsx
  • apps/backend/src/app/api/latest/data-vault/stores/[id]/get/route.tsx
  • apps/backend/src/app/api/latest/data-vault/stores/[id]/set/route.tsx
  • apps/backend/src/app/api/latest/emails/capacity-boost/route.tsx
  • apps/backend/src/app/api/latest/emails/delivery-info/route.tsx
  • apps/backend/src/app/api/latest/emails/notification-preference/crud.tsx
  • apps/backend/src/app/api/latest/emails/outbox/crud.tsx
  • apps/backend/src/app/api/latest/emails/render-email/route.tsx
  • apps/backend/src/app/api/latest/emails/send-email/route.tsx
  • apps/backend/src/app/api/latest/emails/unsubscribe-link/route.tsx
  • apps/backend/src/app/api/latest/emails/unsubscribe-link/verification-handler.tsx
  • apps/backend/src/app/api/latest/integrations/ai-proxy/[[...path]]/route.ts
  • apps/backend/src/app/api/latest/integrations/credential-scanning/revoke/route.tsx
  • apps/backend/src/app/api/latest/integrations/custom/domains/crud.tsx
  • apps/backend/src/app/api/latest/integrations/custom/internal/confirm/route.tsx
  • apps/backend/src/app/api/latest/integrations/custom/oauth/authorize/route.tsx
  • apps/backend/src/app/api/latest/integrations/custom/oauth/idp/[[...route]]/route.tsx
  • apps/backend/src/app/api/latest/integrations/custom/oauth/route.tsx
  • apps/backend/src/app/api/latest/integrations/custom/oauth/token/route.tsx
  • apps/backend/src/app/api/latest/integrations/custom/projects/provision/route.tsx
  • apps/backend/src/app/api/latest/integrations/custom/projects/transfer/confirm/verification-code-handler.tsx
  • apps/backend/src/app/api/latest/integrations/custom/projects/transfer/route.tsx
  • apps/backend/src/app/api/latest/integrations/idp.ts
  • apps/backend/src/app/api/latest/integrations/neon/api-keys/crud.tsx
  • apps/backend/src/app/api/latest/integrations/neon/api-keys/route.tsx
  • apps/backend/src/app/api/latest/integrations/neon/domains/crud.tsx
  • apps/backend/src/app/api/latest/integrations/neon/internal/confirm/route.tsx
  • apps/backend/src/app/api/latest/integrations/neon/oauth-providers/crud.tsx
  • apps/backend/src/app/api/latest/integrations/neon/oauth/authorize/route.tsx
  • apps/backend/src/app/api/latest/integrations/neon/oauth/idp/[[...route]]/route.tsx
  • apps/backend/src/app/api/latest/integrations/neon/oauth/route.tsx
  • apps/backend/src/app/api/latest/integrations/neon/oauth/token/route.tsx
  • apps/backend/src/app/api/latest/integrations/neon/projects/connection/route.tsx
  • apps/backend/src/app/api/latest/integrations/neon/projects/provision/route.tsx
  • apps/backend/src/app/api/latest/integrations/neon/projects/transfer/confirm/verification-code-handler.tsx
  • apps/backend/src/app/api/latest/integrations/neon/projects/transfer/route.tsx
  • apps/backend/src/app/api/latest/integrations/neon/webhooks/route.tsx
  • apps/backend/src/app/api/latest/integrations/resend/webhooks/route.tsx
  • apps/backend/src/app/api/latest/integrations/stripe/webhooks/route.tsx
  • apps/backend/src/app/api/latest/internal/ai-chat/[threadId]/route.tsx
  • apps/backend/src/app/api/latest/internal/ai-conversations/[conversationId]/messages/route.tsx
  • apps/backend/src/app/api/latest/internal/ai-conversations/[conversationId]/route.tsx
  • apps/backend/src/app/api/latest/internal/ai-conversations/route.tsx
  • apps/backend/src/app/api/latest/internal/ai-conversations/utils.ts
  • apps/backend/src/app/api/latest/internal/analytics/query/route.ts
  • apps/backend/src/app/api/latest/internal/analytics/query/timing/route.ts
  • apps/backend/src/app/api/latest/internal/api-keys/crud.tsx
  • apps/backend/src/app/api/latest/internal/api-keys/route.tsx
  • apps/backend/src/app/api/latest/internal/backend-urls/route.tsx
  • apps/backend/src/app/api/latest/internal/changelog/route.tsx
  • apps/backend/src/app/api/latest/internal/component-versions/route.ts
  • apps/backend/src/app/api/latest/internal/config/override/[level]/reset-keys/route.tsx
  • apps/backend/src/app/api/latest/internal/config/override/[level]/route.tsx
  • apps/backend/src/app/api/latest/internal/config/route.tsx
  • apps/backend/src/app/api/latest/internal/config/source/route.tsx
  • apps/backend/src/app/api/latest/internal/conversations/[conversationId]/route.tsx
  • apps/backend/src/app/api/latest/internal/conversations/route.tsx
  • apps/backend/src/app/api/latest/internal/dogfood/support/conversations/[conversationId]/route.tsx
  • apps/backend/src/app/api/latest/internal/dogfood/support/conversations/route.tsx
  • apps/backend/src/app/api/latest/internal/email-drafts/[id]/route.tsx
  • apps/backend/src/app/api/latest/internal/email-drafts/route.tsx
  • apps/backend/src/app/api/latest/internal/email-queue-step/route.tsx
  • apps/backend/src/app/api/latest/internal/email-templates/[templateId]/route.tsx
  • apps/backend/src/app/api/latest/internal/email-templates/route.tsx
  • apps/backend/src/app/api/latest/internal/email-themes/[id]/route.tsx
  • apps/backend/src/app/api/latest/internal/email-themes/cud.tsx
  • apps/backend/src/app/api/latest/internal/email-themes/route.tsx
  • apps/backend/src/app/api/latest/internal/emails/crud.tsx
  • apps/backend/src/app/api/latest/internal/emails/managed-onboarding/apply/route.tsx
  • apps/backend/src/app/api/latest/internal/emails/managed-onboarding/check/route.tsx
  • apps/backend/src/app/api/latest/internal/emails/managed-onboarding/delete/route.tsx
  • apps/backend/src/app/api/latest/internal/emails/managed-onboarding/list/route.tsx
  • apps/backend/src/app/api/latest/internal/emails/managed-onboarding/setup/route.tsx
  • apps/backend/src/app/api/latest/internal/external-db-sync/fusebox/route.ts
  • apps/backend/src/app/api/latest/internal/external-db-sync/poller/route.ts
  • apps/backend/src/app/api/latest/internal/external-db-sync/sequencer/route.ts
  • apps/backend/src/app/api/latest/internal/external-db-sync/status/route.ts
  • apps/backend/src/app/api/latest/internal/external-db-sync/sync-engine/route.tsx
  • apps/backend/src/app/api/latest/internal/failed-emails-digest/route.ts
  • apps/backend/src/app/api/latest/internal/feature-requests/[featureRequestId]/upvote/route.tsx
  • apps/backend/src/app/api/latest/internal/feature-requests/route.tsx
  • apps/backend/src/app/api/latest/internal/feedback/route.tsx
  • apps/backend/src/app/api/latest/internal/init-script-callback/route.tsx
  • apps/backend/src/app/api/latest/internal/local-emulator/project/route.tsx
  • apps/backend/src/app/api/latest/internal/mcp-review/add-manual/route.ts
  • apps/backend/src/app/api/latest/internal/mcp-review/delete/route.ts
  • apps/backend/src/app/api/latest/internal/mcp-review/mark-reviewed/route.ts
  • apps/backend/src/app/api/latest/internal/mcp-review/update-correction/route.ts
  • apps/backend/src/app/api/latest/internal/metrics/route.tsx
  • apps/backend/src/app/api/latest/internal/metrics/user-counts/route.tsx
  • apps/backend/src/app/api/latest/internal/onboarding/preview-affected-users/route.tsx
  • apps/backend/src/app/api/latest/internal/payments/method-configs/route.ts
  • apps/backend/src/app/api/latest/internal/payments/setup/route.ts
  • apps/backend/src/app/api/latest/internal/payments/stripe-widgets/account-session/route.ts
  • apps/backend/src/app/api/latest/internal/payments/stripe/account-info/route.ts
  • apps/backend/src/app/api/latest/internal/payments/test-mode-purchase-session/route.tsx
  • apps/backend/src/app/api/latest/internal/payments/transactions/refund/route.tsx
  • apps/backend/src/app/api/latest/internal/payments/transactions/route.tsx
  • apps/backend/src/app/api/latest/internal/preview/create-project/route.tsx
  • apps/backend/src/app/api/latest/internal/projects-metrics/route.tsx
  • apps/backend/src/app/api/latest/internal/projects/crud.tsx
  • apps/backend/src/app/api/latest/internal/projects/current/crud.tsx
  • apps/backend/src/app/api/latest/internal/projects/transfer/route.tsx
  • apps/backend/src/app/api/latest/internal/rewrite-template-source/route.tsx
  • apps/backend/src/app/api/latest/internal/send-sign-in-invitation/route.tsx
  • apps/backend/src/app/api/latest/internal/send-test-email/route.tsx
  • apps/backend/src/app/api/latest/internal/send-test-webhook/route.tsx
  • apps/backend/src/app/api/latest/internal/session-replays/[session_replay_id]/chunks/[chunk_id]/events/route.tsx
  • apps/backend/src/app/api/latest/internal/session-replays/[session_replay_id]/chunks/route.tsx
  • apps/backend/src/app/api/latest/internal/session-replays/[session_replay_id]/events/route.tsx
  • apps/backend/src/app/api/latest/internal/session-replays/[session_replay_id]/route.tsx
  • apps/backend/src/app/api/latest/internal/session-replays/route.tsx
  • apps/backend/src/app/api/latest/internal/sign-up-rules-stats/route.tsx
  • apps/backend/src/app/api/latest/internal/sign-up-rules-test/route.tsx
  • apps/backend/src/app/api/latest/internal/user-activity/route.tsx
  • apps/backend/src/app/api/latest/migration-tests/route.tsx
  • apps/backend/src/app/api/latest/migration-tests/smart-route-handler/route.tsx
  • apps/backend/src/app/api/latest/oauth-providers/crud.tsx
  • apps/backend/src/app/api/latest/payments/billing/[customer_type]/[customer_id]/route.ts
  • apps/backend/src/app/api/latest/payments/invoices/[customer_type]/[customer_id]/route.ts
  • apps/backend/src/app/api/latest/payments/items/[customer_type]/[customer_id]/[item_id]/route.ts
  • apps/backend/src/app/api/latest/payments/items/[customer_type]/[customer_id]/[item_id]/update-quantity/route.ts
  • apps/backend/src/app/api/latest/payments/payment-method/[customer_type]/[customer_id]/set-default/route.ts
  • apps/backend/src/app/api/latest/payments/payment-method/[customer_type]/[customer_id]/setup-intent/route.ts
  • apps/backend/src/app/api/latest/payments/products/[customer_type]/[customer_id]/[product_id]/route.ts
  • apps/backend/src/app/api/latest/payments/products/[customer_type]/[customer_id]/route.ts
  • apps/backend/src/app/api/latest/payments/products/[customer_type]/[customer_id]/switch/route.ts
  • apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts
  • apps/backend/src/app/api/latest/payments/purchases/purchase-session/route.tsx
  • apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts
  • apps/backend/src/app/api/latest/payments/purchases/verification-code-handler.tsx
  • apps/backend/src/app/api/latest/permission-definitions-pagination.ts
  • apps/backend/src/app/api/latest/project-permission-definitions/crud.tsx
  • apps/backend/src/app/api/latest/project-permissions/crud.tsx
  • apps/backend/src/app/api/latest/projects-anonymous-users/[project_id]/.well-known/[...route].ts
  • apps/backend/src/app/api/latest/projects/[project_id]/.well-known/jwks.json/route.ts
  • apps/backend/src/app/api/latest/projects/current/crud.tsx
  • apps/backend/src/app/api/latest/route.ts
  • apps/backend/src/app/api/latest/session-replays/batch/route.tsx
  • apps/backend/src/app/api/latest/team-invitations/[id]/accept/route.tsx
  • apps/backend/src/app/api/latest/team-invitations/accept/verification-code-handler.tsx
  • apps/backend/src/app/api/latest/team-invitations/crud.tsx
  • apps/backend/src/app/api/latest/team-invitations/send-code/route.tsx
  • apps/backend/src/app/api/latest/team-member-profiles/crud.tsx
  • apps/backend/src/app/api/latest/team-memberships/crud.tsx
  • apps/backend/src/app/api/latest/team-permission-definitions/crud.tsx
  • apps/backend/src/app/api/latest/team-permissions/crud.tsx
  • apps/backend/src/app/api/latest/teams/crud.tsx
  • apps/backend/src/app/api/latest/users/crud.tsx
  • apps/backend/src/app/api/latest/webhooks/svix-token/route.tsx
  • apps/backend/src/app/api/migrations/v2beta2/migration-tests/smart-route-handler/route.ts
  • apps/backend/src/app/api/migrations/v2beta3/migration-tests/smart-route-handler/route.ts
  • apps/backend/src/app/api/migrations/v2beta4/migration-tests/smart-route-handler/route.ts
  • apps/backend/src/app/api/migrations/v2beta5/payments/purchases/create-purchase-url/route.ts
  • apps/backend/src/app/dev-stats/api/route.tsx
  • apps/backend/src/app/dev-stats/page.tsx
  • apps/backend/src/app/global-error.tsx
  • apps/backend/src/app/health/email/route.tsx
  • apps/backend/src/app/health/error-handler-debug/endpoint/route.tsx
  • apps/backend/src/app/health/error-handler-debug/page.tsx
  • apps/backend/src/app/health/route.tsx
  • apps/backend/src/app/page.tsx
  • apps/backend/src/auto-migrations/index.tsx
  • apps/backend/src/auto-migrations/utils.tsx
  • apps/backend/src/instrumentation.ts
  • apps/backend/src/lib/ai/mcp-logger.ts
  • apps/backend/src/lib/ai/models.ts
  • apps/backend/src/lib/ai/qa-reviewer.ts
  • apps/backend/src/lib/ai/schema.ts
  • apps/backend/src/lib/ai/tools/docs.ts
  • apps/backend/src/lib/ai/verified-qa.ts
  • apps/backend/src/lib/bulldozer/db/bulldozer-sort-helpers-sql.ts
  • apps/backend/src/lib/bulldozer/db/index.fuzz.test.ts
  • apps/backend/src/lib/bulldozer/db/index.perf.test.ts
  • apps/backend/src/lib/bulldozer/db/index.test.ts
  • apps/backend/src/lib/bulldozer/db/index.ts
  • apps/backend/src/lib/bulldozer/db/row-change-trigger-dispatch.ts
  • apps/backend/src/lib/bulldozer/db/tables/concat-table.ts
  • apps/backend/src/lib/bulldozer/db/tables/filter-table.ts
  • apps/backend/src/lib/bulldozer/db/tables/map-table.ts
  • apps/backend/src/lib/bulldozer/db/utilities.ts
  • apps/backend/src/lib/cache.tsx
  • apps/backend/src/lib/cel-evaluator.ts
  • apps/backend/src/lib/clickhouse-errors.ts
  • apps/backend/src/lib/clickhouse.tsx
  • apps/backend/src/lib/config.tsx
  • apps/backend/src/lib/contact-channel.tsx
  • apps/backend/src/lib/conversation-types.ts
  • apps/backend/src/lib/conversations-api.ts
  • apps/backend/src/lib/conversations.tsx
  • apps/backend/src/lib/dev-perf-stats.tsx
  • apps/backend/src/lib/dev-request-stats.tsx
  • apps/backend/src/lib/development-environment.ts
  • apps/backend/src/lib/email-delivery-stats.tsx
  • apps/backend/src/lib/email-queue-step.tsx
  • apps/backend/src/lib/email-rendering.tsx
  • apps/backend/src/lib/email-template-rewrite.ts
  • apps/backend/src/lib/emailable.tsx
  • apps/backend/src/lib/emails-low-level.tsx
  • apps/backend/src/lib/emails.tsx
  • apps/backend/src/lib/end-users.tsx
  • apps/backend/src/lib/events.tsx
  • apps/backend/src/lib/external-db-sync-queue.ts
  • apps/backend/src/lib/external-db-sync.ts
  • apps/backend/src/lib/featurebase.tsx
  • apps/backend/src/lib/internal-api-keys.tsx
  • apps/backend/src/lib/internal-feedback-emails.tsx
  • apps/backend/src/lib/js-execution.tsx
  • apps/backend/src/lib/local-emulator.test.ts
  • apps/backend/src/lib/local-emulator.ts
  • apps/backend/src/lib/managed-email-domains.tsx
  • apps/backend/src/lib/managed-email-onboarding.tsx
  • apps/backend/src/lib/metrics-activity-split.ts
  • apps/backend/src/lib/notification-categories.ts
  • apps/backend/src/lib/oauth.tsx
  • apps/backend/src/lib/openapi.tsx
  • apps/backend/src/lib/payments.test.tsx
  • apps/backend/src/lib/payments.tsx
  • apps/backend/src/lib/payments/ensure-free-plan.test.ts
  • apps/backend/src/lib/payments/ensure-free-plan.ts
  • apps/backend/src/lib/payments/platform-fees.ts
  • apps/backend/src/lib/permissions.tsx
  • apps/backend/src/lib/plan-entitlements.test.ts
  • apps/backend/src/lib/plan-entitlements.ts
  • apps/backend/src/lib/preview-mode.ts
  • apps/backend/src/lib/product-versions.tsx
  • apps/backend/src/lib/projects.tsx
  • apps/backend/src/lib/redirect-urls.tsx
  • apps/backend/src/lib/request-checks.tsx
  • apps/backend/src/lib/risk-scores.tsx
  • apps/backend/src/lib/seed-dummy-data.test.ts
  • apps/backend/src/lib/seed-dummy-data.ts
  • apps/backend/src/lib/sign-up-context.ts
  • apps/backend/src/lib/sign-up-rules.ts
  • apps/backend/src/lib/stripe-proxy.tsx
  • apps/backend/src/lib/stripe.tsx
  • apps/backend/src/lib/telegram.tsx

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cl/hexclave-pr3

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1005 files

Partial review: This PR has more than 50 files, so cubic reviewed the highest-priority files first. During the trial, paid plans get a higher file limit.
You can try an ultrareview to bypass the file limit, comment @cubic-dev-ai ultrareview. Learn more.

Re-trigger cubic

Copy link
Copy Markdown

@vercel vercel Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Suggestions:

  1. SSR noExternal configuration still references old @stackframe/* package names instead of @hexclave/* after rebrand
  1. Default email template strings import from @stackframe/emails instead of @hexclave/emails after the rebrand

Fix on Vercel

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: 94872de
(kept locally at backup/cl-romantic-mendel-5a2c25-pre-rebase)
@BilalG1 BilalG1 force-pushed the cl/romantic-mendel-5a2c25 branch from 94872de to d4f6f58 Compare May 24, 2026 00:35
BilalG1 added 4 commits May 23, 2026 17:41
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).
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.
Three small fixes from the parallel reviewers on PR 3:

1. **tanstack-start-demo vite SSR regex** — examples/tanstack-start-demo/
   vite.config.ts:76 had `noExternal: [/^@StackFrame\//, ...]`. The
   regex was missed by the source rename sweep because it's a regex
   pattern, not a string literal. After the rename no @stackframe/*
   package exists in the workspace, so the regex matched nothing and
   workspace deps (`@hexclave/tanstack-start`, `@hexclave/shared`,
   `@hexclave/ui`) stopped being inlined for SSR. Without inlining,
   the Nitro server hits ERR_REQUIRE_ESM on first request because the
   CJS bundles import ESM-only transitive deps (jose, oauth4webapi).
   Flipped to /^@hexclave\// to match the renamed packages.

2. **docs.json footer GitHub link** — pointed at hexclave/stack (404,
   no such repo). The navbar at line 34 already uses hexclave/hexclave
   per the plan, so aligned the footer to match.

3. **README cleanups**:
   - Alt text 'Stack Logo' → 'Hexclave Logo' on the header image.
   - Removed broken /docs/next prefix on the setup-guide link (the
     actual docs structure is /getting-started/setup, no /docs/next).
   - contrib.rocks image now points at hexclave/hexclave (was the old
     stack-auth/stack URL).

What I did NOT touch (out of PR 3 scope, surfaced separately for a
follow-up doc-pedagogy PR):

- 14+ docs-mintlify pages teaching STACK_* env vars instead of
  HEXCLAVE_* (works via dual-read, but contradicts migration.mdx's
  'new code should use HEXCLAVE_*' recommendation).
- REST API code samples teaching X-Stack-* headers instead of
  X-Hexclave-* (works via dual-accept proxy).
- docs-mintlify/sdk/objects/stack-app.mdx broken in-page anchors
  (#stackclientapp etc. — body headings renamed in PR 2 but
  anchor IDs weren't updated).
- MCP server name inconsistency (`stack-auth` in init-prompt.ts vs
  `hexclave` in dashboard setup-page).
- The `ask_stack_auth` MCP tool was removed despite
  RENAME-TO-HEXCLAVE.md saying it should stay registered as a
  compat alias indefinitely.
- AI prompts (apps/backend/src/lib/ai/prompts.ts, apps/skills/) still
  teach legacy header / env-var names in generated code examples.

All of those are PR 2 pedagogy carry-over, not introduced by this PR,
and work functionally via the dual-read/dual-accept compat layers PR
1 + PR 2 put in place. They're documentation polish, not bugs that
block PR 3 shipping.
apps/e2e/tests/js/auth-like.test.ts:68 asserts clientApp.version matches
`^js @stackframe/js@…`, but the build-time sentinel is stamped from
packages/js/package.json's `name` field (configs/tsdown/plugins.ts:10),
which PR 3 renamed @stackframe/js → @hexclave/js. Post-rename the
sentinel is `js @hexclave/js@1.0.0` (or 1.0.1 after auto-bump), so the
old regex fails.

Caught by a follow-up reviewer pass — the published-artifact sentinel
is the most direct observable that's affected by a source-name rename,
and this is the one e2e test that asserts on it directly.
…ertionError 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.
Copy link
Copy Markdown

@vercel vercel Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Suggestions:

  1. Multiple stale imports from @stackframe/stack-shared instead of @hexclave/shared in docs app
  1. Documentation code examples still reference outdated @StackFrame package names instead of @hexclave, misleading users about correct packages to install

Fix on Vercel

@BilalG1 BilalG1 requested a review from N2D4 May 24, 2026 00:56
@BilalG1 BilalG1 assigned N2D4 and unassigned BilalG1 May 24, 2026
Copy link
Copy Markdown

@vercel vercel Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Suggestion:

Next.js statically analyzes instrumentation.ts for Edge Runtime and includes manager.ts in the bundle, causing build failure when manager.ts imports Node.js modules (crypto, fs)

Fix on Vercel

BilalG1 added 2 commits May 26, 2026 16:12
…erCache

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.
BilalG1 added 6 commits May 26, 2026 17:00
…mple 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)
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
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).
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.
## 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 92c07f2.
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. -->
BilalG1 added 5 commits May 26, 2026 18:34
…cl/hexclave-pr3

# Conflicts:
#	.github/workflows/npm-publish.yaml
Removes the data migration that renamed the internal Project row's
displayName/description from 'Stack Dashboard' to 'Hexclave Dashboard'.
Fresh installs still get the new name via seed.ts; existing deployments
will keep the old strings until renamed by hand or in a later PR.
BilalG1 added 2 commits May 26, 2026 18:57
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.
# Conflicts:
#	README.md
#	RENAME-TO-HEXCLAVE.md
#	apps/backend/package.json
#	apps/backend/src/app/api/latest/integrations/idp.ts
#	apps/dashboard/package.json
#	apps/dashboard/src/components/hexclave-rebrand-modal.tsx
#	apps/dashboard/src/lib/apps-frontend.tsx
#	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/docs.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
#	examples/tanstack-start-demo/src/routes/index.tsx
#	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-cli/src/commands/fix.ts
#	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
#	packages/template/src/index.ts
#	packages/template/src/lib/stack-app/apps/implementations/common.ts
#	packages/template/src/lib/stack-app/index.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants