Skip to content

feat(hexclave): PR 2 — visible rebrand (Hexclave brand goes public)#1481

Open
BilalG1 wants to merge 16 commits into
cl/hexclave-pr1from
cl/romantic-mendel-5a2c25
Open

feat(hexclave): PR 2 — visible rebrand (Hexclave brand goes public)#1481
BilalG1 wants to merge 16 commits into
cl/hexclave-pr1from
cl/romantic-mendel-5a2c25

Conversation

@BilalG1
Copy link
Copy Markdown
Collaborator

@BilalG1 BilalG1 commented May 23, 2026

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: defaultBaseUrl and defaultAnalyticsBaseUrl in common.tshttps://api.hexclave.com / https://r.hexclave.com. PR 1's getHardcodedFallbackUrls table now keys on the Hexclave domain.

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

  • @deprecated JSDoc on every Stack* public export (packages/template/src/lib/stack-app/index.ts + packages/template/src/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 existing STACK_COMPILE_TIME_CLIENT_PACKAGE_VERSION_SENTINEL (rewritten at build time to e.g. js @stackframe/stack@2.8.92 or js @hexclave/next@1.0.0); @hexclave/* mirror artifacts short-circuit the warning.

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

  • Tier 4 brand strings (mechanical sweep, ~340 files):

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

    • Every dashboard setup snippet, init-stack template, and docs-mintlify page teaches npx @hexclave/cli@latest init (was @stackframe/stack-cli). setup-page.tsx + link-existing-onboarding.
    • init-stack STACK_*_INSTALL_PACKAGE_NAME_OVERRIDE defaults flipped to @hexclave/*.
    • Generated stack/client.ts / stack/server.ts import from @hexclave/next and reference HexclaveClientApp / HexclaveServerApp.
    • Internal StackAuthKeys dashboard component renamed to HexclaveKeys.
  • docs-mintlify rewrite (legacy ./docs/ intentionally untouched per scoping decision):

    • 78 MDX files swept. @stackframe/{react,stack,js,tanstack-start,...}@hexclave/{react,stack,js,...} in install snippets and code blocks; Stack* SDK class names → Hexclave* in all code examples; 'Stack Auth' brand phrase → 'Hexclave'.
    • openapi/{server,admin,client,webhooks}.json titles → 'Hexclave REST API' / 'Hexclave Webhooks API'.
  • Generators flipped before regeneration:

  • 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 (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.json files (reads HEXCLAVE_VERSION env or --version= flag), pins cross-deps to the shared @hexclave version, registers hexclave bin alongside stack for @hexclave/cli.
    • .github/workflows/npm-publish.yaml appended with rewrite-then-republish step. pnpm publish skips already-on-npm versions so reruns are safe.
  • Sender email domain: noreply@stackframe.conoreply@sent-with-hexclave.com (the dedicated transactional-sender domain split per the plan, to isolate bulk deliverability from hexclave.com reputation); security@ / team@stack-auth.com inbound mailboxes → @hexclave.com.

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

  • GitHub repo slug: hexclave/stack-authhexclave/hexclave in every package.json repository field, README link, CHANGELOG raw-asset URL.

Carve-outs (deliberately untouched)

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

Verification

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

Deploy blockers (ops sequencing before this rebrand goes live)

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

Suggested ordering, hardest blockers first:

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

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

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

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

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

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

Other follow-ups (not deploy-blocking)

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

Test plan

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

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.
@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 23, 2026 10:51pm
stack-auth-mcp Ready Ready Preview, Comment May 23, 2026 10:51pm
stack-auth-skills Ready Ready Preview, Comment May 23, 2026 10:51pm
stack-backend Ready Ready Preview, Comment May 23, 2026 10:51pm
stack-dashboard Ready Ready Preview, Comment May 23, 2026 10:51pm
stack-demo Ready Ready Preview, Comment May 23, 2026 10:51pm
stack-docs Ready Ready Preview, Comment May 23, 2026 10:51pm
stack-preview-backend Ready Ready Preview, Comment May 23, 2026 10:51pm
stack-preview-dashboard Ready Ready Preview, Comment May 23, 2026 10:51pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 23, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 62360919-6cd7-44c3-ab1b-71e91cb5f847

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/romantic-mendel-5a2c25

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.

BilalG1 and others added 2 commits May 23, 2026 10:24
# 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.
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:

X-Hexclave-* request headers are not converted to X-Stack-* headers because proxy middleware was not configured

Fix on Vercel

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.

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

Comment thread apps/backend/src/app/api/latest/integrations/idp.ts Outdated
Comment thread apps/backend/src/app/page.tsx Outdated
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 23, 2026

Greptile Summary

This 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.

  • SDK & URLs: defaultBaseUrl/defaultAnalyticsBaseUrl in common.ts now point to api.hexclave.com/r.hexclave.com; getHardcodedFallbackUrls gains matching Hexclave entries; @deprecated JSDoc added to every Stack* public export with Hexclave* as canonical.
  • Deprecation warning: New deprecation-warning.ts emits a once-per-process console.warn when the SDK loads from a @stackframe/* artifact, using the build-time version sentinel for detection and Symbol.for dedup to avoid console spam.
  • Mirror publish pipeline: New scripts/rewrite-packages-to-hexclave.ts rewrites 9 package.json files and their dist/ artifacts in-place; the vars.HEXCLAVE_VERSION || '1.0.0' fallback in the workflow will silently default to version 1.0.0 if the repository variable is not configured before a push lands on main.

Confidence Score: 3/5

The 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 main push before the repository variable is configured.

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: vars.HEXCLAVE_VERSION || '1.0.0' will use 1.0.0 silently when the variable is absent, and the downstream pnpm publish fires on every main push — npm publishes are permanent and cannot be fully retracted.

.github/workflows/npm-publish.yaml — the HEXCLAVE_VERSION fallback needs to be removed or replaced with an explicit failure step to prevent an accidental publish with the wrong version.

Important Files Changed

Filename Overview
.github/workflows/npm-publish.yaml Appends Hexclave mirror-publish steps; the `vars.HEXCLAVE_VERSION
scripts/rewrite-packages-to-hexclave.ts New script that rewrites 9 @stackframe/* package.json files and their dist artifacts to @hexclave/*; logic is sound but the .map sourcemap extension is included in the rewrite sweep unnecessarily.
apps/backend/prisma/migrations/20260523000000_rename_internal_project_to_hexclave/migration.sql Idempotent UPDATE that renames the internal project display name to 'Hexclave Dashboard' only when both fields still hold the pre-rebrand defaults; clean and safe.
packages/template/src/internal/deprecation-warning.ts New file: once-per-process console.warn triggered when SDK is loaded from a @stackframe/* artifact; uses Symbol.for dedup and a try/catch for sandbox-safe execution.
packages/template/src/lib/stack-app/apps/implementations/common.ts Flips defaultBaseUrl/defaultAnalyticsBaseUrl to hexclave.com endpoints and updates user-facing error messages; backward compat env var names (STACK_*) intentionally retained.
packages/stack-shared/src/utils/urls.tsx Prepends hexclave.com fallback URL entries ahead of the existing stack-auth.com entries in getHardcodedFallbackUrls; backward compat block for legacy stack-auth.com base URLs is preserved.
apps/backend/src/lib/email-rendering.tsx Dual-aliases @hexclave/emails alongside @stackframe/emails in the bundler's externalPackages map so stored templates using either import name continue to render.

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
Loading
Prompt To Fix All With AI
Fix 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

Comment thread .github/workflows/npm-publish.yaml Outdated
Comment thread scripts/rewrite-packages-to-hexclave.ts Outdated
BilalG1 added 2 commits May 23, 2026 11:37
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.
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