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 2 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedToo many files! This PR contains 300 files, which is 150 over the limit of 150. To get a review, narrow the scope: ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (300)
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 |
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 |
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).
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)
94872de to
d4f6f58
Compare
…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.
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'.