## Stack Auth → Hexclave rename — PR 5 (internal symbols, paths,
packages, brand strings)
PR 5 finishes the **internal / non-wire** half of the Stack→Hexclave
rename. It only touches things where nothing outside the repo depends on
the exact name: internal symbols, file/dir names, the
`@stackframe/template` package, and residual brand strings. Plan +
progress are in `HEXCLAVE-RENAME-PR5-PLAN.md`.
Every step was verified green (`pnpm typecheck` + `pnpm lint`, 28/28)
and committed as its own checkpoint, then a fan-out of review agents
audited all commits and the findings were fixed.
### What changed
- **Internal symbols** (`@hexclave/shared`, `packages/template`, apps):
`stack*`/`Stack*` → `hexclave*`/`Hexclave*` — incl.
`stackGlobalsSymbol`, the `_Stack*AppImpl` classes,
`stackAppInternalsSymbol`, `StackContext`, `getStackStripe`, etc. The
`stack*App` local-variable convention
(`stackServerApp`/`stackClientApp`/…) was renamed across 175
source/example/doc files.
- **File renames**: `hexclave-handler/provider/context.tsx`,
`backend/hexclave.tsx`, `internal-tool/hexclave.ts`,
`hexclave-app-internals.ts`.
- **Directory renames**: `lib/hexclave-app`, `hexclave-companion`,
`[...hexclave]` route segment, `skills/hexclave`,
`dashboard/src/hexclave`, and the package dirs
**`packages/{next,shared,ui,sc,cli}`** (dropping the `stack-` prefix to
match the `@hexclave/*` npm names).
- **Packages**: `@stackframe/template` → `@hexclave/template`; **deleted
`packages/init-stack`** (onboarding lives in `@hexclave/cli init`; the
published npm package is untouched).
- **Brand strings**: reworded `Stack Auth`/`Stack dashboard` prose in
code + docs-mintlify, renamed `hexclave-app.mdx`/`use-hexclave-app.mdx`
with redirects, regenerated OpenAPI, updated coupled e2e assertions;
`doctor`/`init` now prefer `hexclave.config.ts`.
### Intentionally kept (verified, not oversights)
Wire/compat identifiers (`x-stack-*` headers, `stack-*` cookies,
`STACK_*` env names, `*.stack-auth.com`, `stackauth_`, `ask_stack_auth`,
query params), public `Stack*` SDK aliases, crypto/JWT/vault
domain-separation tags, `*-brand-sentinel`s, the
`Symbol.for("StackAuth--…")` string, `_stack_sync_metadata`, Postgres
`stackframe` / docker image names, the `stack-auth-logo*.svg` (used by
the rebrand modal), and `migration.mdx` / "formerly known as Stack Auth"
notes. False positives (Phosphor `StackIcon`/`StackSimple`, `TanStack`,
`OrbStack`, `stackable`/`Stacked` charts) left alone.
### Review pass
Six review agents audited all commits. Found + fixed one real bug — a
build script (`bundle-type-definitions.ts`) hardcoded the old
`lib/stack-app` glob path (not an import, so typecheck/lint were blind),
silently emptying the dashboard AI type bundle — plus stale comments, a
dead CI env var, and stale `.gitignore`/`.dockerignore` entries.
Cross-cutting audit confirmed **zero wire-compat identifiers were
accidentally renamed**.
### ⚠️ Verification note
`typecheck` + `lint` are fully green locally. The **e2e suite was not
run** (needs a live backend+DB), so the brand-string assertion +
OpenAPI-regen changes are verified by grep/codegen only — please let CI
exercise e2e to confirm.
### Base-branch note
This branch was forked from the local-only `cl/friendly-lewin-72293f`
(not on origin, no separate PR), so this PR against `dev` also carries
that branch's ~11 preceding Hexclave-rename commits (config-file rename,
env-var dual-read, AI setup-prompt rebrand). If those should land
separately, re-parent before merge.
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Finishes the internal Stack Auth → Hexclave rename and cleans up
remaining stragglers, including dev-tool and prompt copy. All changes
are internal-only; public/wire APIs remain unchanged. Re-merged `dev`
and resolved the payments create-purchase-url conflict.
- **Refactors**
- Internal symbols: stack*/Stack* → hexclave*/Hexclave* (e.g.,
`getHexclaveServerApp` via `@/hexclave`, `getHexclaveStripe`,
`hexclaveAppInternalsSymbol`, `hexclaveSchemaInfo`, Prisma
`__hexclave_*`, `data-hexclave-handler-page`, Stripe mock
`hexclavePortPrefix`).
- Files/dirs: moved to `lib/hexclave-app`; handler route
`[...hexclave]`; backend entry `src/hexclave.tsx`; dashboard internals
`hexclave-app-internals`; companion `hexclave-companion`; dropped
`stack-` prefix across package dirs
(`packages/{shared,ui,sc,cli,next}`); workflows/emulator paths now
`packages/cli`; Quetzal codegen env at `packages/next/.env.local`.
- Packages/docs: `@stackframe/template` → `@hexclave/template`; removed
`packages/init-stack`; regenerated OpenAPI and updated docs
slugs/redirects for hexclave-app/use-hexclave-app.
- Brand strings/prompts: reworded remaining “Stack” dashboard strings to
Hexclave; updated dev-tool copy and prompts; `doctor/init` now prefer
`hexclave.config.ts`. Kept all wire-compat identifiers and public
aliases (`x-stack-*`, `stack-*` cookies, `STACK_*` env,
`*.stack-auth.com`, `Stack*` SDK names).
- Rebased/merged onto latest `dev`: retained `@hexclave/template`, kept
`src` in published files, refreshed setup-prompt imports and docs JSON,
adopted 1.0.5 version bumps, and re-merged `dev` again (resolved
`create-purchase-url` with `getHexclaveStripe`).
- **Bug Fixes**
- Restored dashboard AI type bundle by pointing the glob to
`packages/template/src/lib/hexclave-app`.
- Addressed rename leftovers: updated lingering `@/stack` imports and
CSS selector, fixed schema/meta and port-prefix expansions, and aligned
emulator commands to `packages/cli`.
- CI/build: removed a dead env var and stale ignore entries; fixed
Docker by renaming `STACK_SKIP_TEMPLATE_GENERATION` →
`HEXCLAVE_SKIP_TEMPLATE_GENERATION`.
<sup>Written for commit
|
||
|---|---|---|
| .. | ||
| db-sync-mappings.ts | ||
| format.ts | ||
| migrate-catalogs-to-product-lines.ts | ||
| README.md | ||
| schema-fuzzer.test.ts | ||
| schema.ts | ||
Some notes on configs
The language in this file is very technical, if you're struggling, put it into ChatGPT and see if it can help you (with the usual hallucination disclaimer).
Generic format vs. Hexclave
The config format is generally usable and not specific to Hexclave.
All the logic required for generic usage of the config format are in format/. The other files in this folder are specific to Hexclave's usage of it.
Terminology
Generic config format:
- Config: Any config, as described in stack-info
- Normalized config: A config without
nullfields and dot notation
Hexclave: There are four levels, project, branch, environment, organization.
- Base config: The defaults that come with Hexclave
$Levelconfig override: Overrides that are applied to the base config (in the following order: project -> branch -> environment -> organization)$Levelincomplete config: The base config after some overrides have been applied$Levelrendered config: An incomplete config with those fields removed that can be overridden by a future override, deeply merged into the defaults and sanitized (usingapply{$Level}DefaultsAndSanitize), and then normalized- Complete config: The organization rendered config.
$Levelconfig override override: An override that overrides the$Levelconfig override. This is most often used eg. in the REST API to let users make changes to the branch-level config, without overwriting the entire branch-level config override. Note that, since config overrides (unlike configs) distinguish betweennulland a property missing (undefined), it is currently not possible to say "this property in the config override should be unset" (setting a property tonullin the override override will simply also set it tonullin the override). In the future, we'll have to think about how we handle this, probably with a sentinel value.$Levelconfig: Could refer to any of the above, depending on the context; if it's not clear, specify it.
Examples
Base config:
{
organizations: {},
createTeamOnSignUp: false,
sourceOfTruthConnectionString: null
}
Project config override:
{
sourceOfTruthConnectionString: 'postgresql://...',
}
Project incomplete config:
// note: `organizations` and `createTeamOnSignUp` may be overridden by branch, environment, or organization configs! They are not final
{
organizations: {},
createTeamOnSignUp: false,
sourceOfTruthConnectionString: 'postgresql://...',
}
Project rendered config:
// since `organizations` and `createTeamOnSignUp` may change later, they are not included in the rendered config
{
sourceOfTruthConnectionString: 'postgresql://...',
}
Branch config override:
{
organizations: {
'my-org': {
name: 'My Org',
}
}
}
Branch incomplete config:
{
organizations: {
'my-org': {
name: 'My Org',
}
},
createTeamOnSignUp: true,
sourceOfTruthConnectionString: 'postgresql://...',
}
Branch rendered config:
// as above, `organizations` and `createTeamOnSignUp` are not included in the rendered config, as they may change later
{
sourceOfTruthConnectionString: 'postgresql://...',
}
Environment config override:
// no change from branch config
{}
Environment incomplete config:
// no change from branch config
{
organizations: {
'my-org': {
name: 'My Org',
}
},
createTeamOnSignUp: true,
sourceOfTruthConnectionString: 'postgresql://...',
}
Environment rendered config:
// organizations can no longer change after this point, so they are included in the rendered config
{
organizations: {
'my-org': {
name: 'My Org',
}
},
createTeamOnSignUp: true,
sourceOfTruthConnectionString: 'postgresql://...',
}
Organization config override:
{
createTeamOnSignUp: true,
}
Organization incomplete config = organization rendered config = complete config:
{
createTeamOnSignUp: true,
sourceOfTruthConnectionString: 'postgresql://...',
}