feat(hexclave): PR 2 — visible rebrand (Hexclave brand goes public)#1481
feat(hexclave): PR 2 — visible rebrand (Hexclave brand goes public)#1481BilalG1 wants to merge 16 commits into
Conversation
PR 2 of the Stack Auth → Hexclave rebrand (stacked on cl/hexclave-pr1). PR 1 shipped the invisible compatibility layer; this PR flips every user-visible surface to the Hexclave brand. Old wire identifiers (cookies, headers, Bearer prefix, JWT issuers) keep working indefinitely via PR 1's dual-accept; only customer-visible strings, package names, and DNS-bearing URLs change here. What changed (per RENAME-TO-HEXCLAVE.md "PR 2"): - **SDK base URLs** flipped to api.hexclave.com / r.hexclave.com (defaults in packages/template + downstream consumers). PR 1's hardcoded fallback table now matches against the Hexclave domain. - **Domain inventory sweep**: 16 *.stack-auth.com subdomains → *.hexclave.com across all production code, docs-mintlify, examples, READMEs, and contribu- tor guidance. github.com/hexclave/stack-auth → github.com/hexclave/hexclave in every package.json repository field, README link, and CHANGELOG asset URL. - **@deprecated JSDoc** on every Stack* public export (StackClientApp / ServerApp / AdminApp + their constructor/options/JSON types, StackHandler, StackProvider, StackTheme, useStackApp, defineStackConfig, StackConfig). Hexclave* aliases (from PR 1) are now canonical; the Stack* names render with IDE strikethrough. - **Runtime console.warn** added to packages/template (src/internal/ deprecation-warning.ts) — fires once-per-process when the SDK is loaded from a @stackframe/* artifact (detected via the existing STACK_COMPILE_TIME_CLIENT_PACKAGE_VERSION_SENTINEL build-time stamp). @hexclave/* mirror artifacts ship the same code; the package-name check short-circuits the warning there. - **Tier 3 data migrations**: idempotent 20260523000000_rename_internal_project_to_hexclave SQL migration that updates the internal Project displayName 'Stack Dashboard' → 'Hexclave Dashboard' and description 'Stack\'s admin dashboard' → 'Hexclave\'s admin dashboard' only if both still hold the pre-rebrand defaults (operator-renamed projects untouched, missing row no-ops). seed.ts default also flipped. getSharedEmailConfig("Stack Auth") → ("Hexclave"). - **Tier 4 brand strings (mechanical sweep)**: - Page + OpenAPI titles (Hexclave API / Dashboard / REST API / Webhooks API / Documentation) and the OpenAPI 'info.description' now documents X-Hexclave-* headers as canonical with a compat note on X-Stack-*. - StackAssertionError message text: 'an error in Stack.' → 'an error in Hexclave.' - Known-error message templates 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 (sent-with-hexclave.com sender domain), test-email-recipient default. - CHANGELOG title 'Stack Auth Changelog' → 'Hexclave Changelog'. - AGENTS.md: env var convention now HEXCLAVE_* / NEXT_PUBLIC_HEXCLAVE_* for Category A/B; legacy STACK_* explicitly noted as accepted via dual-read. - **CLI / init wizard**: - Dashboard setup snippets, init-stack templates, and 11 docs-mintlify pages teach 'npx @hexclave/cli@latest init' (was @stackframe/stack-cli). - apps/dashboard new-project onboarding-workflow generator flipped. - init-stack's STACK_*_INSTALL_PACKAGE_NAME_OVERRIDE defaults now @hexclave/* (env var overrides preserved). - Generated stack/client.ts and stack/server.ts now import from '@hexclave/stack' and reference HexclaveClientApp / HexclaveServerApp. - **docs-mintlify rewrite** (legacy ./docs intentionally untouched per scoping decision): - 78 MDX files swept: @stackframe/{react,stack,js,tanstack-start,...} → @hexclave/{react,stack,js,tanstack-start,...} in install snippets and code blocks. - Stack* SDK class names (StackClientApp, StackServerApp, StackHandler, StackProvider, StackTheme, useStackApp, defineStackConfig) → Hexclave* in all code examples. - 'Stack Auth' brand-string phrase → 'Hexclave' wherever it appears. - 'Stack REST API' / 'Stack Webhooks API' → 'Hexclave REST API' / 'Hexclave Webhooks API' in openapi/{server,admin,client,webhooks}.json. - **Generators flipped before regeneration**: - packages/stack-shared/src/helpers/init-prompt.ts - packages/stack-shared/src/ai/prompts.ts - apps/backend/src/lib/ai/prompts.ts - apps/backend/src/lib/ai/tools/create-email-{template,draft}.ts - apps/skills/src/app/route.ts (taught MCP tool name → ask_hexclave with compat note; CLI binary teach → 'hexclave') - docs-mintlify/snippets/home-prompt-island.jsx - packages/template/README.md + integrations/convex/component/README.md - generate-sdks then propagated to packages/{react,stack,js}. - **OpenAPI dual-documentation**: 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 (apps/backend/src/lib/email-rendering.tsx). 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**: scripts/rewrite-packages-to-hexclave.ts added — rewrites @stackframe/* → @hexclave/* in 9 publishable package.json files (read HEXCLAVE_VERSION env or --version flag), pins cross-deps to the shared @hexclave version, registers 'hexclave' bin alias alongside 'stack' for @hexclave/cli. .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); security@/team@stack-auth.com inbound mailboxes → @hexclave.com. - **Self-host docs**: docker network / container names in the bash examples flipped from 'stack-auth' / 'stack-auth-postgres' / 'stack- auth-clickhouse' to 'hexclave' / 'hexclave-postgres' / 'hexclave- clickhouse'; stack-auth.env filename → hexclave.env. The docker image tag stackauth/server:latest stays per the plan's locked decision. Carve-outs (deliberately untouched): - packages/template/src/lib/stack-app/url-targets.ts hosted-domain default '.built-with-stack-auth.com' — wire identifier baked into existing customer deploys, indefinite read-fallback. - apps/backend/src/lib/tokens.tsx JWT issuer dual-accept table — PR 1 intentional infrastructure. - 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. - Binary visual assets (logos, favicons, OG images, README screenshots) — out of scope for this PR. Tracked separately. Verification: - pnpm typecheck on packages/{template,stack-shared,react,stack,js} + apps/dashboard: all green. - pnpm lint on the same: all green. - Final grep for residual 'Stack Auth' / stack-auth.com / @stackframe/ stack-cli@latest references: zero outside intentional carve-outs. - 25 e2e test files updated in lockstep with known-error message changes. Known follow-ups (out of scope for this PR): - Backend tsc errors against Prisma-generated client / route-info JSON — pre-existing infra debt; needs codegen-prisma + codegen-route-info to run, which require a live DB. Unrelated to this diff. - @stackframe/stack-cli build-ordering bug — pre-existing per PR 1. - E2E snapshot regen across the full suite for the dual-emitted x-hexclave- * response headers (PR 1 follow-up; vitest -u in CI absorbs). - DNS setup for *.hexclave.com + sent-with-hexclave.com + SPF/DKIM/DMARC — ops work prerequisite to deploy. - Binary visual assets (logos, favicons, OG images). - @hexclave/cli first publish — CI workflow now exists; will fire on next main push once @hexclave npm scope is reserved with vars.HEXCLAVE_VERSION set. - Backend OpenAPI fumadocs regen — needs built stack-shared + a running backend; not required for this code-only diff.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
# Conflicts: # apps/e2e/tests/backend/endpoints/api/v1/internal/mcp.test.ts
5 parallel review agents flagged 19 concrete defects across the PR 2 diff. Triaged
and applied fixes for all clear bugs (skipping scope-explicit carve-outs).
Tests / wire-protocol consistency:
- apps/e2e/tests/backend/endpoints/api/v1/index.test.ts (7 lines): assertions
still said 'Welcome to the Stack API endpoint!' while the route emits the
Hexclave wording. Flipped to match the handler.
- apps/e2e/tests/backend/endpoints/api/v1/internal/mcp.test.ts: 'skill.stack-auth.com'
→ 'skill.hexclave.com' (matches mcp-handler.ts:26) and 'Stack Auth MCP Setup'
→ 'Hexclave MCP Setup' (matches setup-page.ts:275).
- docs-mintlify/openapi/{admin,client,server}.json: stale 'Welcome to the Stack
API endpoint!' example synced to the Hexclave wording.
- apps/backend/scripts/generate-openapi-fumadocs.ts: server description
hardcoded 'Stack REST API' while title was 'Hexclave REST API' — next regen
would have silently reverted the JSON files. Flipped to 'Hexclave REST API'.
Migration / SQL:
- apps/backend/prisma/migrations/20260523000000_*/migration.sql: header comment
promised 'only updates when BOTH fields hold the pre-rebrand defaults', but
the two sibling UPDATEs at the bottom mutated fields independently — they
silently rewrote the description on operator-renamed projects. Dropped the
sibling UPDATEs; kept the combined AND-guarded UPDATE that matches the
documented contract.
Mirror publish (workflow/script):
- scripts/rewrite-packages-to-hexclave.ts: pre-fix the script renamed
package.json but left dist/ verbatim, so published @hexclave/stack@1.0.0
declared a @hexclave/shared dependency while its bundled output still
did require('@stackframe/stack-shared/...') — MODULE_NOT_FOUND for any
user who installed only @hexclave/*. The same gap caused the deprecation
warning to fire from @hexclave/* artifacts (build-time sentinel still
carried '@stackframe/<pkg>@<v>'). Extended the script to also rewrite
cross-package require/import specifiers and the 'js @stackframe/<pkg>@<v>'
sentinel inside dist/ (text-only files), keyed on the same PACKAGE_NAME_MAP.
Smoke-tested locally: 380/1021 dist files patched in packages/stack,
144/355 in packages/js, 0 stale @stackframe/ references in main entrypoints.
- Fixed misleading comment in packages/template/src/index.ts that claimed the
script rewrote the build-time constant — it does now.
SDK runtime:
- packages/stack-shared/src/utils/urls.tsx: getHardcodedFallbackUrls had
flipped its only keys to api.hexclave.com, dropping fallbacks for customers
with explicit baseUrl: 'https://api.stack-auth.com'. Re-added both stack-auth
branches alongside the hexclave ones (deprecation-window dual-key).
- packages/template/src/internal/deprecation-warning.ts: wrapped console.warn
in a try/catch + console-availability guard. Some sandboxed worker runtimes
stub or omit console — a throw from this side-effect import would have
broken consuming bundles at SDK load time.
CLI / init-stack generated code:
- packages/init-stack/src/index.ts:writeStackAppFile: Next.js path generated
inconsistent identifiers — it imported HexclaveClientApp/HexclaveServerApp,
declared 'export const stackClientApp', then the server file did
'import { hexclaveClientApp } from "./client"' (broken — that name was
never exported). Layout writer + Convex auth-detection used hexclaveClientApp
everywhere. Aligned the Next.js path with the React path: HexclaveClientApp
class + hexclaveClientApp const + hexclave*App identifiers throughout
ensureStackAppImport / determineAuthCallExpression / addSetAuthToConvexClients.
- Convex instructions text mixed hexclaveClientApp / stackServerApp on the same
line — both renamed to hexclave*App for consistency.
- Existing-install heuristic ('!stackAppContent.includes("@stackframe/")')
would have thrown 'A file at the path … already exists' on any project
previously installed against @hexclave/* (no helpful 'already installed'
message). Accepts either prefix now.
- packages/init-stack/package.json description: 'The setup wizard for Stack' →
'The setup wizard for Hexclave'.
Dashboard + AI prompts:
- apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/(overview)/setup-page.tsx:
TanStack Start prompt said 'VITE_HEXCLAVE_PROJECT_ID' but the side-by-side
code snippet read VITE_STACK_PROJECT_ID. Synced to VITE_HEXCLAVE_PROJECT_ID.
- apps/dashboard/src/components/env-keys.tsx (ViteEnvKeys): now writes
VITE_HEXCLAVE_API_URL / VITE_HEXCLAVE_PROJECT_ID / HEXCLAVE_SECRET_SERVER_KEY,
matching the prompt + snippet (Vite doesn't apply SDK-level dual-read for
VITE_-prefixed names, so the env file must literally use the names the code
references).
- apps/skills/src/app/route.ts: parenthetical claim that 'the legacy ask_stack_auth
tool is still registered and works identically' contradicted reality —
mcp-handler.ts only registers ask_hexclave (the prior compat-feedback commit
removed the alias). Removed the false claim. The exec example used an
undefined 'hexclaveServerApp' binding while exec.ts binds 'stackServerApp' —
flipped the example.
- packages/stack-shared/src/helpers/init-prompt.ts + apps/backend/src/lib/ai/tools/docs.ts:
also referenced ask_stack_auth; updated to ask_hexclave.
- packages/stack-shared/src/helpers/init-prompt.ts: taught agents to grep for
'useHexclaveApp must be used within a HexclaveProvider' — the SDK still throws
'useStackApp must be used within a StackProvider' (wire-stable runtime
identifier). Updated the prompt to quote the actual throw with an inline
explanation.
Brand wording:
- packages/template/src/lib/stack-app/apps/implementations/common.ts (×3):
'Please copy your key from the Stack dashboard' → 'Hexclave dashboard' in
the three default-key throwErr messages.
Lint + typecheck pass on all packages I touched. Pre-existing dashboard
typecheck errors (TS18046 'unknown' / TS7006 'implicit any' from missing
generated/api-versions.json + prisma codegen) confirmed unchanged vs HEAD via
stash-then-rerun.
CI 'Check for uncommitted changes' caught these — `pnpm codegen-docs` (which reads PR 2's `apps/backend/src/app/api/latest/route.ts` X-Hexclave-* header schemas + the `info.description` blurb from `openapi.tsx`) hadn't been re-run since route.ts was updated. The regen adds 8 X-Hexclave-* header parameter blocks (Project-Id, Branch-Id, Access-Type, Access-Token, Refresh-Token, Publishable-Client-Key, Secret-Server-Key, Super-Secret-Admin-Key) before the existing X-Stack-* compat entries on every endpoint, and adds the 'all-headers-documented-as-canonical-X-Hexclave-*' note to info.description. Re-ran: pnpm --filter @stackframe/backend run codegen-docs.
There was a problem hiding this comment.
2 issues found across 371 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.
Fix all with cubic | Re-trigger cubic
Greptile SummaryThis PR performs the visible half of the Stack Auth → Hexclave rebrand across ~371 files: flipping SDK default base URLs, package names, page titles, error messages, email content, CLI snippets, docs, and OpenAPI specs to the Hexclave brand while keeping all pre-rebrand wire identifiers working via PR 1's compatibility layer.
Confidence Score: 3/5The brand-string sweep and compatibility wiring are well-executed, but the CI publish pipeline has a fallback that could permanently publish 9 npm packages with the wrong version on any The bulk of the change is mechanical text replacement with no logic impact. The migration is idempotent, the deprecation warning is safely isolated, and the email dual-alias is correct. The one concrete risk is in the new CI step:
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Push to main] --> B[Build @stackframe/* packages]
B --> C[pnpm publish -r\n@stackframe/* to npm]
C --> D[rewrite-packages-to-hexclave.ts\n--version=HEXCLAVE_VERSION or 1.0.0]
D --> E{vars.HEXCLAVE_VERSION set?}
E -->|Yes| F[Rename 9 package.json files\nto @hexclave/*\nRewrite dist/ artifacts]
E -->|No| G[Falls back to 1.0.0\nsilent accidental publish]
F --> H[pnpm publish -r\n@hexclave/* to npm]
G --> H
subgraph SDK Load
I[User imports @stackframe/stack] --> J[deprecation-warning.ts fires]
J --> K{clientVersion starts with js @stackframe/?}
K -->|Yes| L[console.warn once per process]
K -->|No| M[No-op - already @hexclave/*]
end
Prompt To Fix All With AIFix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
.github/workflows/npm-publish.yaml:56
**Silent publish with wrong version if `HEXCLAVE_VERSION` is unset**
When `vars.HEXCLAVE_VERSION` is not configured in the repository, this expression evaluates to the literal string `'1.0.0'` (GitHub Actions `||` treats an unset `vars.*` as `''`). The `--version=1.0.0` argument passes the regex guard in `getHexclaveVersion()`, so the script happily rewrites all 9 packages and then the next step publishes them as `@hexclave/*@1.0.0` to the public npm registry — a release that cannot be undone. This workflow triggers on every push to `main`, so if the repository variable isn't set before the branch lands, the accidental publish fires automatically.
### Issue 2 of 2
scripts/rewrite-packages-to-hexclave.ts:161
**Sourcemap files should be excluded from text replacement**
The pattern includes `.map` files (source maps). Sourcemaps are JSON blobs that embed original source file paths and, when `sourcesContent` is set, the full source text. A blanket `@stackframe/` → `@hexclave/` replacement inside source maps will corrupt the embedded file paths and source snippets, making the maps unusable for debugging production errors. The package-name references that actually need rewriting are in the `.js`/`.cjs` compiled output, not the maps.
```suggestion
if (!/\.(?:m?js|cjs|d\.m?ts|d\.cts|json|html|txt|md)$/.test(entry.name)) continue;
```
Reviews (1): Last reviewed commit: "chore(hexclave): regen openapi fumadocs ..." | Re-trigger Greptile |
Three additional review agents covered backend handlers + header-normalize shim, email pipeline + AI tools, and PR1-compat-surfaces-under-PR2. Six valid PR2 bugs surfaced; fixed below. Out-of-scope findings (PR1 cookie / cross-domain write-side regressions documented by agents) intentionally deferred — they predate this PR. Backend: - apps/backend/src/app/api/latest/integrations/idp.ts: the OIDC IDP audience was flipped from 'idp-jwk-audience.stack-auth.com' to '.hexclave.com'. The audience is NOT user-visible — it is a SHA-256 salt mixed into the per- audience signing key + kid (see packages/stack-shared/src/utils/jwt.tsx:103 ff). Flipping it rotates every OIDC IDP's JWK on deploy, invalidating every cached client JWKS and every outstanding signed token. Reverted to the legacy domain with a code comment explaining why this is a carve-out. - apps/backend/src/app/api/latest/(api-keys)/handlers.tsx: 'isCloudVersion' was true only when the API request URL hostname matched 'api.hexclave.com'. Cloud production serves from both hostnames during the cutover (legacy api.stack-auth.com is in PR1's tokens.tsx alias table + urls.tsx fallback set). Keys minted via the legacy hostname were getting the secret-scanning marker bit dropped, breaking GitHub's partner-program scanner detection for those keys. Now accepts either hostname. - apps/backend/src/lib/tokens.tsx: issuerHostAliases only covered the prod pair; dev hosts could not cross-validate (api.dev.stack-auth.com tokens couldn't be verified against the dev hexclave issuer and vice versa). Added the dev pair so staging/preview deployments crossing dev hosts work. SDK template: - packages/template/src/lib/stack-app/url-targets.ts: defaultHostedHandlerDomainSuffix was flipped to '.built-with-hexclave.com', but the PR description's 'Carve-outs' section explicitly promises '.built-with-stack-auth.com' as an indefinite read-fallback for existing customer deploys and OAuth callback URLs. Reverted with a code-level comment so future readers don't re-flip it. Dashboard: - apps/dashboard/src/components/vibe-coding/code-editor.tsx: Monaco's TypeScript layer declared only 'declare module "@stackframe/emails"'. New AI-generated email templates (whose prompts and defaults teach @hexclave/emails) showed 'Cannot find module' red squigglies in the in-app editor. Extracted the module body, declared both names. - apps/dashboard/src/components/commands/create-dashboard/dashboard-sandbox-host.tsx: AI prompts (create-dashboard) now reference 'hexclaveServerApp', but the sandbox iframe was injecting only 'window.stackServerApp'. New AI- generated dashboards would throw ReferenceError at runtime. Inject under both names — old saved dashboards continue to use stackServerApp, new AI- generated ones use hexclaveServerApp, both resolve to the same instance. Docs / AI prompts: - docs-mintlify/guides/getting-started/ai-integration.mdx (lines 20, 101): PR2's docs-mintlify sweep claimed 78 MDX files were touched, but missed two references to 'ask_stack_auth'. mcp-handler.ts only registers 'ask_hexclave' (the legacy alias was removed per PR-review feedback in PR1 commit b60a455). Customers following these docs would get tool-not- found. Flipped to 'ask_hexclave'. - apps/backend/src/lib/ai/prompts.ts: 3 section headers ('## WHAT TO CONSIDER STACK AUTH-RELATED', '## STACK AUTH HTTP API HEADERS', '## KEY STACK AUTH CONCEPTS') still said 'STACK AUTH'; body text was already Hexclave. Renamed for consistency. Also flipped the X-Stack-* header documentation examples to X-Hexclave-* (canonical per the OpenAPI doc), with a note that the legacy aliases still work. Lint, typecheck, and the targeted e2e tests (index.test.ts: 16 passed/5 todo, mcp.test.ts: 6 passed) all green against a locally-running backend.
Triaged 4 unresolved review threads on PR #1481; 3 were not yet handled (the 4th — cubic-dev-ai's IDP audience flag — was already addressed in the prior round-2 commit ad870ef). - apps/backend/src/app/page.tsx:9 (cubic-dev-ai P2): the link's URL was flipped to https://app.hexclave.com but its link text still said 'Stack's dashboard'. Half-rebranded. Flipped the text to 'Hexclave's dashboard' to match. - .github/workflows/npm-publish.yaml (greptile-apps P1): the mirror-publish step used '${{ vars.HEXCLAVE_VERSION || '1.0.0' }}'. GitHub Actions evaluates an unset 'vars.*' as empty string, so the literal '1.0.0' was the silent fallback. The first push to main after this lands — before the repo variable is intentionally configured — would publish @hexclave/*@1.0.0 to the public npm registry as an unrecoverable release. Replaced with an explicit gate step: if vars.HEXCLAVE_VERSION is unset, the rewrite + mirror-publish steps are skipped (silent no-op); if set, the value is used as-is with no fallback. - scripts/rewrite-packages-to-hexclave.ts:161 (greptile-apps P2): the text-rewrite extension allow-list included '.map'. Source maps embed original file paths and (when sourcesContent is set) the original source code — a blanket '@stackframe/' → '@hexclave/' substitution inside them corrupts the mappings and breaks production-error debugging. Dropped '.map' from the regex with a code comment explaining why. Lint + typecheck pass on backend (the only locally-affected package).
Special-case @stackframe/stack (the Next.js-specific SDK) in the mirror- publish step: instead of mirroring as @hexclave/stack, it now publishes as @hexclave/next. Mirrors how @hexclave/react and @hexclave/js identify the framework they target — 'next' is more descriptive than the legacy 'stack' when the only thing the package contains is the Next.js layer. Other 8 publishable mirrors (react/js/tanstack-start/shared/ui/sc/cli/ dashboard-ui-components) keep their existing names. Script change: - scripts/rewrite-packages-to-hexclave.ts: PACKAGE_NAME_MAP entry for @stackframe/stack updated. The dist-content rewriter already propagates this through every cross-package require/import specifier and the build-time package-version sentinel, so no other code change is needed inside the script. Consumer-facing sweep (26 source files): - docs-mintlify/migration.mdx and the package-mapping table inside it. - 17 other docs-mintlify MDX pages that teach `@hexclave/stack` imports. - packages/init-stack/src/index.ts — generator now writes `import … from "@hexclave/next"` in stack/server.ts, stack/client.ts, layout.tsx, and handler.tsx. - packages/stack-shared/src/ai/prompts.ts — code examples in the AI prompt's framework-specific guidance. - packages/stack-shared/src/helpers/init-prompt.ts — the agent setup prompt's package mapping + every example snippet. - packages/template/src/internal/deprecation-warning.ts — comment example. - RENAME-TO-HEXCLAVE.md plan doc updated for consistency. Verified: smoke-test of the rewrite script confirms '@stackframe/stack → @hexclave/next@1.0.0' with 208/540 dist files rewritten in packages/stack and 0 stale '@hexclave/stack' references left in the source tree. Lint + typecheck pass on dashboard, template, init-stack, stack-shared, and backend.
…c-mendel-5a2c25 # Conflicts: # .github/workflows/npm-publish.yaml # apps/backend/package.json # apps/dashboard/package.json # apps/dashboard/src/components/commands/create-dashboard/dashboard-sandbox-host.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/guides/getting-started/setup.mdx # docs-mintlify/guides/getting-started/user-fundamentals.mdx # docs-mintlify/index.mdx # docs-mintlify/snippets/home-prompt-island.jsx # 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 # packages/template/src/lib/stack-app/url-targets.ts
…shboard rename The internal project's displayName was renamed in seed.ts and via a migration, but 7 e2e tests still hardcoded 'Stack Dashboard' in inline snapshots and one .toBe() assertion. Updated each by hand to match the new 'Hexclave Dashboard' string the backend now emits in email from/subject and in the /projects API response.
…e-access-type message The INSUFFICIENT_ACCESS_TYPE known-error message was updated in this PR to lead with x-hexclave-access-type and mention x-stack-access-type as a compat alias. 25 e2e files were updated in lockstep but this snapshot was missed.
Drop the vars.HEXCLAVE_VERSION repo-var gating in favor of a hardcoded 1.0.0 cutover version. The repo-var approach added an ops step (set the var before publish) with no upside — `pnpm publish` skips versions already on npm, so re-runs are no-ops, and the one-shot publish is exactly what we want. PR 3 in the rebrand sequence will rename the source packages natively to @hexclave/* and delete this mirror flow entirely; until then, 1.0.0 is the locked cutover version.
Summary
Stacked on #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→ "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:
defaultBaseUrlanddefaultAnalyticsBaseUrlin common.ts →https://api.hexclave.com/https://r.hexclave.com. PR 1'sgetHardcodedFallbackUrlstable 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.comreference 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, the legacy./docs/folder, theunified-docs-widgetallowlist (deliberately accepts both during DNS transition), andurl-targets.tshosted-component default (baked into existing customer deploys).@deprecatedJSDoc on everyStack*public export (packages/template/src/lib/stack-app/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) — once-per-process when the SDK is loaded from a@stackframe/*artifact. Detection uses the existingSTACK_COMPILE_TIME_CLIENT_PACKAGE_VERSION_SENTINEL(rewritten at build time to e.g.js @stackframe/stack@2.8.92orjs @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— updates the internal ProjectdisplayName'Stack Dashboard' → 'Hexclave Dashboard' anddescriptiononly if both still hold the pre-rebrand defaults. Operator-renamed projects untouched, missing row no-ops, re-runs are no-ops.seed.tsdefault flipped.getSharedEmailConfig("Stack Auth")→("Hexclave").Tier 4 brand strings (mechanical sweep, ~340 files):
info.descriptiondocumentsX-Hexclave-*headers as canonical with compat note onX-Stack-*.HexclaveAssertionErrormessage text (errors.tsx:71) — "an error in Stack." → "an error in Hexclave."x-hexclave-*+ the newdocs.hexclave.comURL; legacyx-stack-*mentioned as compat aliases. 25 e2e test files updated in lockstep.sent-with-hexclave.com), test-email-recipient default.CHANGELOG.mdtitle → "Hexclave Changelog".AGENTS.mdenv var convention: new vars prefixHEXCLAVE_/NEXT_PUBLIC_HEXCLAVE_for Category A/B; legacySTACK_*explicitly noted as accepted via PR 1's dual-read.CLI / init wizard:
npx @hexclave/cli@latest init(was@stackframe/stack-cli). setup-page.tsx + link-existing-onboarding.STACK_*_INSTALL_PACKAGE_NAME_OVERRIDEdefaults flipped to@hexclave/*.stack/client.ts/stack/server.tsimport from@hexclave/nextand referenceHexclaveClientApp/HexclaveServerApp.StackAuthKeysdashboard component renamed toHexclaveKeys.docs-mintlify rewrite (legacy
./docs/intentionally untouched per scoping decision):@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}.jsontitles → 'Hexclave REST API' / 'Hexclave Webhooks API'.Generators flipped before regeneration:
packages/stack-shared/src/helpers/init-prompt.ts,/ai/prompts.ts,apps/backend/src/lib/ai/prompts.ts,apps/backend/src/lib/ai/tools/create-email-{template,draft}.ts,apps/skills/src/app/route.ts(taught MCP tool →ask_hexclavewith compat note; CLI binary teach →hexclave),docs-mintlify/snippets/home-prompt-island.jsx,packages/template/README.md+ integrations/convex/component/README.md.generate-sdkspropagated changes topackages/{react,stack,js}.OpenAPI dual-documentation:
apps/backend/src/app/api/latest/route.tsnow listsX-Hexclave-*headers as primary documented schemas withX-Stack-*duplicates marked.optional()(both accepted at runtime by PR 1's normalize-at-proxy shim).@stackframe/emailsvirtual module: dual-aliased to@hexclave/emailsat the bundler boundary (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— rewrites 9 publishable@stackframe/*→@hexclave/*package.jsonfiles (readsHEXCLAVE_VERSIONenv or--version=flag), pins cross-deps to the shared@hexclaveversion, registershexclavebin alongsidestackfor@hexclave/cli..github/workflows/npm-publish.yamlappended with rewrite-then-republish step.pnpm publishskips 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 fromhexclave.comreputation);security@/team@stack-auth.cominbound mailboxes →@hexclave.com.Self-host docs: docker network / container names in the bash examples flipped from
stack-authtohexclave(hexclave-postgres,hexclave-clickhouse,hexclave.env). The docker image tagstackauth/server:lateststays per the plan's locked decision.GitHub repo slug:
hexclave/stack-auth→hexclave/hexclavein everypackage.jsonrepositoryfield, README link, CHANGELOG raw-asset URL.Carve-outs (deliberately untouched)
apps/backend/src/lib/tokens.tsxJWT issuer dual-accept table — PR 1 intentional infrastructure, kept indefinitely../docs/folder — per scoping decision (onlydocs-mintlify/rewritten).unified-docs-widgethostname allowlist — accepts both.hexclave.com(canonical) and.stack-auth.com(transition window) for DNS rollout.url-targets.tshosted-domain default.built-with-stack-auth.com— wire identifier baked into existing customer deploys; indefinite read-fallback.Verification
pnpm typecheckonpackages/{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.jsonnot present in fresh worktrees withoutpnpm run codegen-prisma+ a live DB) and unrelated to this diff.pnpm linton the same 6 packages: all green.Stack Auth/stack-auth.com/@stackframe/stack-cli@latestreferences: zero outside the intentional carve-outs above.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)
api.hexclave.com+api1./api2.hexclave.com→ must point at the same backend that servesapi.stack-auth.com(or a backend that mirrors PR 1's dual-accept). The SDK's newdefaultBaseUrlishttps://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.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'swizard-congratsredirect, and the OAuth dashboard handoff.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.mcp.hexclave.com→ the MCP server endpoint that every taught agent integration (claude mcp add ...,cursor,codex,vscode) registers. Until this resolves, everynpx @hexclave/cli@latest initMCP-registration step fails.@hexclavenpm scope + set repo variableHEXCLAVE_VERSION→ the mirror-publish step in.github/workflows/npm-publish.yamlis gated on this variable. Without it, the entire taught onboarding commandnpx @hexclave/cli@latest init404s from the npm registry, and every README that says "install@hexclave/next" leads to install failure. Pick the initial version intentionally (1.0.0or 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)
r.hexclave.com→ the analytics beacondefaultAnalyticsBaseUrl. Silent failure if missing (analytics drops), but should land alongside Tier 1.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.hexclave.com→team@hexclave.comandsecurity@hexclave.commailboxes. The security disclosure mailbox is referenced in.github/SECURITY.md;team@hexclave.comis the actual recipient of internal feedback emails sent at runtime byapps/backend/src/lib/internal-feedback-emails.tsx. Today, every runtime feedback email bounces.skill.hexclave.com→ the canonical AI-agent skill fetch URL (the agent bootstrap pivot). Without it, the entire "agent downloadsSKILL.mdfrom a known URL" flow taught inpackages/stack-shared/src/helpers/init-prompt.tsfails.github.com/hexclave/hexclaveas a public repo (even as a redirect tohexclave/stack-auth) OR rewrite everypackage.json"repository"field + dashboard footer "view on GitHub" link to point athexclave/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
discord.hexclave.com→ Discord invite redirect, used in every README's chip and the dashboard footer.demo.hexclave.com→ "✨ Demo" badge in every npm package README. Broken-image badge on the package page.built-with-hexclave.com→ optional hosted-handler domain (the default reverted to.built-with-stack-auth.comin this PR's carve-outs, so this only matters for projects that manually flip).Other follow-ups (not deploy-blocking)
x-hexclave-*response headers (PR 1 follow-up;vitest -uin CI absorbs).docs-mintlify/openapi/are committed but regen runs in CI. Verify the workflow that does this still works against the post-PR2 source.codegen-prisma+codegen-route-infoto clear; pre-existing, unaffected by this PR.Test plan
vitest -uto absorb residual snapshot deltas, then committed back).@hexclave/cli init(once published) generateshexclave.config.tsand works against a fresh project.@stackframe/stackimport sees the once-per-processconsole.warnrecommending@hexclave/nexton SDK init.npx @hexclave/cli@latest initsnippet and thex-hexclave-publishable-client-keyAPI header in the curl example.pnpm run prisma migrateagainst a clean DB sets the internal project displayName to 'Hexclave Dashboard'.