mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-19 21:00:40 +08:00
dfe7d5fee4
652 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e131ef0e53 |
Merge remote-tracking branch 'origin/dev' into fix/config-parsing-rde-error
# Conflicts: # docs-mintlify/guides/getting-started/setup.mdx # docs-mintlify/snippets/home-prompt-island.jsx |
||
|
|
b246e4ab65
|
Consistency and design changes light mode (#1500)
# PR #1500 Visual Writeup Visual assets hosted in [this gist](https://gist.github.com/b0c1d3d072a71e30b65380f8b2cf53a1). - Base: `dev` - Head: `Consistency-and-design-changes-light-mode` - Dashboard dev server: `http://localhost:8101` - Viewport: `1920x1200` - Screenshots: `74` referenced (`18` surfaces x `2` themes x `before/after`, plus the attached Conversations create-dialog pair) - Red outlines appear only on **after** screenshots to mark the changed surface. ## Summary This PR refreshes light-mode consistency across dashboard surfaces and adds a dashboard-only Account Settings implementation. The screenshots below compare the base branch against the PR branch for every changed dashboard route/surface included in the scope. ## Screenshot Matrix ### Account Settings - Profile Dashboard-only profile page redesign against the previous Stack handler page. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Account Settings - Emails & Auth Email, password, passkey, OTP, and MFA settings shell. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Account Settings - Notifications Notification preferences styling. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Account Settings - Active Sessions Active session table and action styling. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Account Settings - Payments Billing surface and account/team billing selector. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Account Settings - Settings Sign out and account deletion settings. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Account Settings - Team Team profile, members, and leave-team sections. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Account Settings - Create Team Team creation form. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Analytics Queries Touched analytics query page surface. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Analytics Tables Analytics table/query controls and data-grid surface. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Auth Methods Authentication method configuration surface. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Conversations Support conversation UI surface. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | #### Conversations - Create Dialog Attached screenshots for the create conversation dialog. | Theme | Before | After | | --- | --- | --- | | Light |  |  | ### Domains Trusted domains alert/card styling. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Email Sent Sent email and reputation card styling. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Launch Checklist Launch checklist page surface. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Payment Products Products/items payment page surface. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Session Replays Session replay page layout. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Sign-up Rules Sign-up rules page surface. | Theme | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Added comprehensive account settings dashboard with profile management, email and authentication settings, active sessions monitoring, API key generation and management, payment methods, notification preferences, and team creation/management. * Introduced user profile image editing with circular cropping and compression. * Added multi-factor authentication (MFA) setup via TOTP QR codes. * Enabled team-based API key management and team member invitations. * **Design Improvements** * Refined UI styling across analytics, forms, and dialogs for better visual hierarchy. * Enhanced dark mode support throughout dashboard components. * Improved responsive layouts and spacing on dashboard pages. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
b0cfeb5fb9
|
Payments checkout page redesign (#1536)
## Summary This PR redesigns the payments checkout experience around a cleaner split-panel purchase flow, clearer pricing selection, and more focused terminal states for successful and invalid purchase links. The new UI reduces visual noise, makes the selected plan and total amount easier to scan, and keeps test-mode bypass behavior explicit without overwhelming the checkout form. ## Visual Review ### Checkout Flow | Before | After | | --- | --- | | : address review feedback on config load + import detection
- config-file: capture the raw jiti error for diagnostics instead of attaching it as `cause`. The dashboard error formatter (errorToNiceString -> nicify) renders `Error.cause` recursively, which would leak the underlying framework stack back into the user-facing message. - config-rendering: add `@hexclave/tanstack-start` to CONFIG_IMPORT_PACKAGES so projects that only depend on it render `@hexclave/tanstack-start/config` instead of falling back to `@hexclave/js/config` (a missing-module TS error). |
||
|
|
bc45117777
|
Support local dashboard in remote SSH and GH Codespaces (#1538) | ||
|
|
6a01e2507a |
fix(rde): graceful config load errors + lightweight /config import path
The local dashboard evaluates a project's hexclave.config.ts in a plain Node
context via jiti. When a config imported a value (e.g. defineStackConfig) from a
framework package like @stackframe/stack / @hexclave/next, jiti executed the
whole SDK (React, server-only, Next internals) and threw, surfacing only as
"Failed to register development environment session (500)".
- Catch jiti load failures in readConfigFile and rethrow a helpful message that
points at the lightweight import path.
- Add a side-effect-free `./config` subpath to the framework packages
(@hexclave/{js,next,react,tanstack-start}/config) that re-exports
defineHexclaveConfig/defineStackConfig + the HexclaveConfig type from
@hexclave/shared/config, with no framework runtime. Users directly depend on
these packages, so the subpath resolves under pnpm strict mode (unlike the
transitive @hexclave/shared/config).
- Point the setup prompt, hand-written docs (docs-mintlify), and the renderer
that auto-writes config files at the new `<pkg>/config` path. Legacy
@stackframe/* packages predate the subpath, so they keep their root import.
Existing config files that import from a package root are upgraded to the
/config path on their next dashboard/CLI sync.
|
||
|
|
3c19e173e0 | Fix tooltip error | ||
|
|
c14a9dd3d0
|
feat(hexclave): PR 5 — internal symbol/path/package renames + brand strings (#1547)
## 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
|
||
|
|
65362f3efb
|
fix(dashboard): prevent blank email preview when switching themes (#1514)
## Problem
When switching themes in the email drafts/template editor, the preview
occasionally shows the loading spinner and then goes completely blank.
## Cause
`EmailPreview` remounts its preview subtree (and thus the `<iframe>`)
via a `key` on `EmailPreviewErrorBoundary` whenever the inputs that
affect the rendered output change. That key was built from the
template/theme TSX source + edit mode, but **omitted `themeId`**.
Switching only the selected theme changes `themeId` without changing the
source, so the key stayed the same. React then reused the existing
`<iframe>` element and merely mutated its `srcDoc` attribute in place.
Replacing `srcDoc` on a live sandboxed iframe is intermittently not
repainted by the browser, leaving a blank preview after the loading
state.
The old key also concatenated values without a separator, which could
collide.
## Fix
Include `themeId` (and `templateId` / `editableSource`) in the remount
key and build it with a collision-safe serialization. A theme switch now
remounts the preview subtree, so a fresh iframe is mounted and loads its
`srcDoc` reliably instead of mutating it in place. This also resets
stale error-boundary state when moving from a broken theme to a working
one.
Single-line, behavior-preserving change.
Link to Devin session:
https://app.devin.ai/sessions/b269b97b40db4015a8770f77a13c10ea
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes a blank email preview when switching themes in the dashboard
editor by remounting the preview iframe. The preview now reliably
updates on theme changes and resets stale error state.
- **Bug Fixes**
- Updated `EmailPreviewErrorBoundary` key to include `themeId`,
`templateId`, `editableSource`, `editMode`, and debounced theme/template
TSX sources, serialized with JSON and joined with a null delimiter.
- Remounts the iframe on theme switch instead of mutating `srcDoc`,
preventing intermittent blank renders.
<sup>Written for commit
|
||
|
|
7c5034fae6
|
[Fix]: Can now switch subscriptions/ create checkout urls even when stripeAccountId is null with test mode (#1519)
### Context Remote/Local emulator allow one to set up payments configs without being provisioned stripe connected accounts. Previously, even if the user had test mode toggled, they couldn't create checkout urls or switch subscriptions. Now, they can thanks to the refactor. ### Out of scope The switch route still needs to be reworked for when we want to consider stripe-test mode or test mode - stripe switches. For now we should be good |
||
|
|
5835db6b54 | Update missing docs redirects | ||
|
|
501ae9fe61
|
PR 4: Rename Stack -> Hexclave: examples config module, app-internal symbols, crypto docs (#1534)
## What
Continues the **Stack Auth → Hexclave** rename for a set of safe,
internal-only surfaces. This intentionally avoids public-contract names.
### Changes
- **Examples** — renamed the user-facing config module
`stack.ts`/`stack.tsx` (and the `convex` / `lovable` `stack/`
directories) to `hexclave`, and updated every importer across
`.ts`/`.tsx`/`.jsx`. The public `app/handler/[...stack]/` route segment
is left unchanged.
- **apps/{dashboard,backend,internal-tool}** — renamed app-local
SDK-init symbols `stackClientApp → hexclaveClientApp` and
`getStackServerApp → getHexclaveServerApp`, and the dashboard
`StackCompanion` component → `HexclaveCompanion` (incl.
`useStackCompanion`, context types). The public
`StackClientApp`/`StackServerApp` SDK classes are **unchanged**.
- **packages/stack-shared** — added comments to the crypto / JWT / vault
`stack-*` literals documenting that they must **not** be renamed (key
derivation / JWKS / KMS-alias stability). The literals are
byte-identical.
### Deliberately excluded
- **`STACK_*` → `HEXCLAVE_*` env-var rename** — `HEXCLAVE_*` already
resolves via the dual-read layers (SDK env, dashboard `_inlineEnvVars`,
`getEnvVariable`). The remaining holdout is the docker post-build
sentinel path, which the codebase authors explicitly deferred and which
is tightly coupled to `entrypoint.sh` + untestable here. A blind rename
there risks silently breaking self-host/emulator bootstrap for ~zero
functional gain.
- **All public-contract names** — SDK class names, env vars, HTTP
headers (`x-stack-*`), and the `/handler` route convention.
## Verification
- `pnpm lint` — **29/29 passing**.
- `pnpm typecheck` — **28/29 passing**; the only failure is
`@hexclave/docs` (pre-existing missing fumadocs `.source` codegen,
untouched by this PR).
- Two rounds of adversarial multi-agent review; findings fixed:
string-literal collateral from the symbol sweep (CLI test fixtures + an
AI-prompt template) reverted, and a missed `.jsx` importer in
`examples/cjs-test` corrected.
## Notes
- Based on a `dev` snapshot from when the branch was cut (a couple
commits behind tip); the diff contains only the changes above.
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Complete the internal “Stack” → “Hexclave” rename across examples,
app-local code, config tooling, and setup docs, and standardize env
output to HEXCLAVE_* with correct default API URL handling. Public SDK
classes, handler routes, and legacy env names keep working.
- **Refactors**
- Examples/config: `stack.*` files and `stack/` dirs →
`hexclave.*`/`hexclave/`; imports updated; keep `app/handler/[...stack]`
route.
- Apps: backend/dashboard/internal-tool now use `getHexclaveServerApp`
and `hexclaveClientApp`; dashboard `StackCompanion` →
`HexclaveCompanion`. Public `StackClientApp`/`StackServerApp` unchanged.
- Env/setup: Next.js and CLI generators write HEXCLAVE_* and omit API
URL when using https://api.stack-auth.com; CLI `doctor` and auth
resolution prefer HEXCLAVE_* (e.g. `HEXCLAVE_SECRET_SERVER_KEY`,
`HEXCLAVE_PROJECT_ID`) with `STACK_*` fallback.
- Config tooling: `stack-config-file` → `hexclave-config-file`, emitting
`HexclaveConfig`; imports updated across backend/dashboard/tooling.
- Shared/docs: added “do not rename” notes for crypto/JWT/vault
`stack-*` literals; regenerated setup prompt/docs to use
`hexclave.config.ts`, `hexclave dev`, and `src/hexclave/`.
- Tests: updated snapshots/assertions to expect `HexclaveConfig` and
HEXCLAVE_* env names.
- **Migration**
- No action required. SDK and CLI read both HEXCLAVE_* and STACK_*.
<sup>Written for commit
|
||
|
|
7d5adeb06e
|
fix(email): DNSimple zone teardown, managed-domain apply flow (#1527)
## Summary
Three related fixes, surfaced while investigating a production error on
managed email onboarding.
### 1. DNSimple managed-email zone deletion (the reported production
error)
`deleteDnsimpleZoneByName` issued `DELETE /v2/{account}/zones/{zone}`,
but **DNSimple's v2 API has no DELETE endpoint for zones**. Zones are
created here by creating a *domain* (`POST /domains`), so the symmetric
teardown is `DELETE /domains/{name}`, which also removes the hosted
zone. The old call returned a non-OK status, throwing:
> `HexclaveAssertionError: DNSimple returned non-OK status when deleting
managed email zone`
on every managed-domain deletion (the Resend domain was already deleted
by then, so the request 500s and the DNSimple zone leaks). Now deletes
the owning domain.
### 2. `applyManagedEmailProvider` left configs in an invalid state
The apply early-returned on `domain.status === "applied"` **without
rewriting config**. If the config had since drifted (e.g. the user
switched to a shared/other provider and back), re-applying never
restored `password`/`senderName`, so the *rendered* config was invalid
and **every `GET /internal/projects` 500'd** with `Result admin
validation failed in CRUD handler` (dashboard then loops/refreshes). Now
it only short-circuits when the config actually uses the domain
(`isManagedEmailDomainInUseForTenancy`); otherwise it re-provisions and
writes the full valid config.
### 3. Email-settings dashboard: managed domain now uses the staged save
flow
Clicking "Use this domain" fired an immediate API call and only
refreshed the domains *list* — never the project config the UI derives
"active" from — so nothing visibly changed and it appeared not to
persist. Applying a managed domain now matches the other providers:
selecting a domain stages a draft and shows the standard **"Unsaved
changes → Save"** card; **Save** calls `applyManagedEmailProvider`
(which owns the full config write) and then refreshes the reactive
config cache so the UI flips to **Active**.
### 4. Build unblock: `@stackframe/stack-shared` → `@hexclave/shared`
The `@hexclave/*` rename (#1482) missed `createGlobal`'s import in two
template providers, and PR 3 deleted the compat alias — so `pnpm
build:packages` couldn't resolve
`@stackframe/stack-shared/dist/utils/globals` when building the
dashboard. Fixed in the template (generated SDKs follow). *(Independent
of the email fixes, but required to build the branch.)*
## Files
- `apps/backend/src/lib/managed-email-onboarding.tsx` — DNSimple domain
delete + apply re-provision-on-drift
- `apps/dashboard/.../email-settings/domain-settings.tsx` — staged
managed-domain apply
-
`packages/template/src/providers/{stack-context,translation-provider-client}.tsx`
— globals import rename
## Testing
- `tsc --noEmit` and `eslint` clean on `@hexclave/backend` and
`@hexclave/dashboard`.
- `pnpm build:packages` + `pnpm codegen` succeed; dashboard
email-settings route compiles and serves `200`.
- Reproduced the 500 loop locally, root-caused it to a partial managed
config override, and reset the affected project's `emails.server`
override to recover.
## Notes
- Applying a managed domain still calls the API once (to mint the scoped
Resend sending key) — that call now happens on **Save** rather than on
click.
- The older `apps/dashboard/.../emails/page-client.tsx` has the same
immediate-apply pattern; left untouched pending confirmation that screen
is still in use.
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes managed email onboarding: deletes DNSimple domains correctly,
restores a valid managed config on re-apply, and moves managed-domain
apply to a staged Save that waits for the domain list and shows
selection state. Also updates imports to `@hexclave/shared` to unblock
builds.
- **Bug Fixes**
- DNSimple teardown: use DELETE `/domains/{name}` (zones have no
DELETE). Stops errors and zone leaks when removing managed domains.
- `applyManagedEmailProvider`: only short-circuits when the rendered
config already uses the domain; otherwise re-provisions and writes the
full managed config to prevent invalid renders and 500s.
- Dashboard: managed domain selection now stages a draft; Save calls
`applyManagedEmailProvider`, refreshes the config cache, and the UI
updates. Shows “Selected — save to apply,” supports deselecting,
requires a selection, and disables Save until the domains list finishes
loading.
- **Dependencies**
- Renamed globals import from `@stackframe/stack-shared` to
`@hexclave/shared` to restore `pnpm build:packages`.
<sup>Written for commit
|
||
|
|
bfd15f07d1
|
Improve development environment loopback error message (#1526) | ||
|
|
9fa3a19920
|
Fix Docker builds for pnpm v11 (#1532) | ||
|
|
1af0071233 | Metrics page improvement | ||
|
|
2e1bfecb5f | Fix types | ||
|
|
f9d081da09 | Upgrade pnpm to v11.5.0 | ||
|
|
d1d96fdcc4 | Update light mode logo | ||
|
|
97bb65cc33 | Fix config overrides for RDEs | ||
|
|
011d7d751d
|
Fix stale e2e CLI + RDE config tests (emulator removal & hexclave rename) (#1528)
## What
Fixes the 9 failing tests in the E2E (Local Emulator) job — 2 test
files, both stale after recent refactors that renamed source but missed
the tests.
### `apps/e2e/tests/general/cli.test.ts` (6 failures)
The `stack emulator` command was removed in #1522 (which also reworded
its auth errors from "local emulator" → "development environment"), but
the e2e tests were never updated:
- Updated two error-string assertions:
- `"Local emulator publishable client key not found"` → `"Development
environment publishable client key not found"`
- `"Cannot reach local emulator"` → `"Cannot reach development
environment"`
- Removed the dead `"Stack CLI — Emulator"` describe block (4 tests for
the deleted `emulator pull/start/stop/list-releases` subcommands) and
the now-unused `CLI_SRC_BIN` const.
###
`apps/dashboard/src/lib/remote-development-environment/config-file.test.ts`
(3 failures)
Leftover `@stackframe/*` names from the `@hexclave` rename:
- Fixture imports `@stackframe/stack-shared/config` →
`@hexclave/shared/config` (the `defineStackConfig` /
`defineHexclaveConfig` cases were failing with `Cannot find module`).
- Rendered-config snapshot type import `@stackframe/js` →
`@hexclave/js`.
## Verification
- `config-file.test.ts`: **7 passed**.
- `cli.test.ts` against a live local backend: **69 passed / 4 skipped /
0 failed** (the 4 skips are environment-gated `it.runIf`/`it.skip`, not
failures).
- Reproduced both CLI error paths against the built CLI binary to
confirm the new strings match exactly.
- `lint` ✓ and `typecheck` ✓ for `@hexclave/e2e-tests` and
`@hexclave/dashboard`.
Only test files are changed — no production code.
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes 9 failing E2E tests by updating CLI error messages and RDE config
test imports after the emulator command removal and the `@hexclave`
rename. Removes obsolete emulator CLI tests; no production code changed.
- **Bug Fixes**
- CLI: updated two error-string assertions to use “Development
environment …” wording.
- CLI: removed the obsolete “Stack CLI — Emulator” test block and the
unused `CLI_SRC_BIN`.
- Dashboard RDE config tests: replaced `@stackframe/stack-shared/config`
with `@hexclave/shared/config`.
- Snapshot import: `@stackframe/js` → `@hexclave/js`.
<sup>Written for commit
|
||
|
|
66242c9e63 | Mark @stackframe packages as deprecated | ||
|
|
609579abab
|
feat(hexclave): PR 3 — native @hexclave/* source rename + delete dual-publish wiring (#1482)
Some checks failed
all-good: Did all the other checks pass? / all-good (push) Has been cancelled
Ensure Prisma migrations are in sync with the schema / check_prisma_migrations (22.x) (push) Has been cancelled
DB migration compat / Check if migrations changed (push) Has been cancelled
Docker Server Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Server Build and Run / docker (push) Has been cancelled
Runs E2E API Tests (Local Emulator) / E2E Tests (Local Emulator, Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (mock, 22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (prod, 22.x) (push) Has been cancelled
Runs E2E API Tests with custom port prefix / build (22.x) (push) Has been cancelled
Runs E2E Fallback Tests / E2E Fallback Tests (Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Lint & build / lint_and_build (24) (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
DB migration compat / Back-compat — Current branch migrations with ${{ needs.check-migrations-changed.outputs.base_branch }} branch code (push) Has been cancelled
DB migration compat / Forward-compat — Current branch code with ${{ needs.check-migrations-changed.outputs.base_branch }} branch migrations (push) Has been cancelled
DB migration compat / No migration changes (skipped) (push) Has been cancelled
|
||
|
|
1ba69eb1fb | More tests for jiti RDE | ||
|
|
70486596f0 | Use jiti for RDE config parsing | ||
|
|
bd61184bdc
|
Add LLM metadata endpoints (#1499) | ||
|
|
fa2baa829d
|
feat(oauth): per-provider customCallbackUrl for redirect_uri (#1512)
## Summary
Replaces the request-host-header-derived OAuth `redirect_uri` with a
config-driven `customCallbackUrl` field on each environment-level OAuth
provider.
Resolution of the `redirect_uri` we send to providers (and that
customers register in their provider app config):
- **Shared providers** → always the stack-auth-branded callback, so
Stack's shared OAuth apps keep working. `customCallbackUrl` is
schema-forbidden when `isShared` is true.
- **Custom + `customCallbackUrl` set** → the configured URL verbatim.
- **Custom without it (legacy)** → the stack-auth-branded callback, so
providers registered before this field are unaffected.
- **New custom providers set up in the dashboard** → the env-aware
hexclave-branded callback (prod → `api.hexclave.com`, dev/staging →
siblings, self-host/localhost → `NEXT_PUBLIC_STACK_API_URL` unchanged).
## Details
- **Schema** (`schema.ts`, `schema-fields.ts`): optional
`customCallbackUrl` after `clientSecret`, with a `.when('isShared')`
rule rejecting any value for shared providers; added to the provider
default factory.
- **Shared host helper** (`utils/cloud-hosts.tsx`, new):
`CLOUD_HOST_PAIRS` moved into stack-shared with `getCloudApiUrlSiblings`
/ `getStackAuthApiBaseUrl` / `getHexclaveApiBaseUrl`;
`request-api-url.ts` re-exports it so the JWT `iss` logic is untouched.
- **Runtime** (`oauth/index.tsx` + all 13 provider `create()`s):
`getProvider` resolves the full `redirect_uri` from config instead of
the request host; providers now take `redirectUri` instead of `apiUrl`.
The JWT `iss` path still uses the request host.
- **Dashboard** (`page-client.tsx`, `providers.tsx`,
`oauth-callback-url.ts` new): brand-new custom providers get the
hexclave callback; existing providers keep whatever they had (edits
never silently move a registered redirect URL); the displayed Redirect
URL mirrors backend resolution.
- **Docs** (`migration.mdx`): existing `api.stack-auth.com` callbacks
keep working; only recreated providers use the hexclave URL.
## Notes / scope decisions
- **Dashboard-only injection**: SDK/CLI/legacy-config-created custom
providers fall back to the stack-auth callback (they don't auto-get the
hexclave URL).
- **shared → standard** conversions keep the stack-auth fallback rather
than flipping to hexclave (the safe path that never breaks a registered
redirect).
## Test plan
- [x] `typecheck` + `lint` green across stack-shared, backend,
dashboard, e2e
- [x] cloud-hosts unit tests, schema tests, schema fuzzer pass
- [x] e2e: shared-provider `customCallbackUrl` rejected (400);
standard-provider `customCallbackUrl` accepted and round-trips
- [ ] e2e OAuth authorize/callback flow (needs running stack) — reasoned
unaffected since localhost isn't a cloud host, so the redirect base
stays localhost as before
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Adds a per-provider `customCallbackUrl` for OAuth `redirect_uri`,
removing the request-host dependency and making redirects predictable.
Shared providers always use the Stack-branded callback; new or converted
custom providers default to the Hexclave-branded callback. Existing
callbacks keep working; no changes needed unless you recreate or convert
a provider.
- **New Features**
- Added `customCallbackUrl` on provider configs (URL-validated;
forbidden when `isShared` is true).
- `getProvider` now resolves a config-driven `redirectUri`; providers
take `redirectUri` instead of `apiUrl` (pure resolver with in-source +
e2e tests to lock legacy behavior).
- Introduced `@stackframe/stack-shared` `utils/cloud-hosts.tsx` and
dashboard helpers to show the resolved Redirect URL and set the Hexclave
callback for new providers and when converting shared → standard.
- **Bug Fixes**
- OAuth callback now handles legitimate cross-host flows by recording
the authorize host and skipping the host-scoped CSRF cookie when
authorize and callback hosts differ, relying on server-side state and
PKCE.
<sup>Written for commit
|
||
|
|
244e7e79f2
|
Add captureWarning for warnings (#1506) | ||
|
|
c753ab2831
|
fix(dashboard): show Stack Auth logo on left of rebrand modal (#1495)
## Summary
The Stack Auth → Hexclave rebrand modal added in
[#1493](https://github.com/hexclave/stack-auth/pull/1493) rendered the
**Hexclave** logo on both sides of its illustration instead of *Stack
Auth → Hexclave*.
## Root cause
[\`hexclave-rebrand-modal.tsx\`](https://github.com/hexclave/stack-auth/blob/dev/apps/dashboard/src/components/hexclave-rebrand-modal.tsx)
referenced \`/logo.svg\` and \`/logo-bright.svg\` for the left-hand
"Stack Auth" mark. But the visible-rebrand flip in
[#1481](https://github.com/hexclave/stack-auth/pull/1481) replaced those
files in \`apps/dashboard/public/\` with the Hexclave benzene mark — so
post-merge, both \`<Image>\` slots resolved to the Hexclave logo.
## Fix
- Restored the **pre-rebrand Stack Auth SVGs** (lifted from
\`57ff5d3ce~1\`, the commit before the brand-flip) under dedicated
filenames so they can't get clobbered the next time \`/logo.svg\` is
updated:
- \`apps/dashboard/public/stack-auth-logo.svg\` — black mark, light
theme
- \`apps/dashboard/public/stack-auth-logo-bright.svg\` — white mark,
dark theme
- Pointed the modal's left-hand \`<Image>\` pair at the new paths and
left a comment explaining why we don't share \`/logo.svg\` (so the next
person doesn't try to consolidate it back).
The originals on \`origin/dev\` (\`/logo.svg\`, \`/logo-bright.svg\` =
Hexclave) are untouched.
## Verification
- \`pnpm --filter @stackframe/dashboard lint\` — clean.
- Diff of
[hexclave-rebrand-modal.tsx](https://github.com/hexclave/stack-auth/blob/fix-stack-logo-in-modal/apps/dashboard/src/components/hexclave-rebrand-modal.tsx)
is two \`src=\` swaps plus a comment; the dismissal logic, gates, and
storage key are untouched.
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes the rebrand modal to show the Stack Auth logo on the left instead
of rendering Hexclave on both sides. Restores pre-rebrand assets as
`stack-auth-logo.svg` and `stack-auth-logo-bright.svg` and updates the
modal to use them for light/dark themes.
<sup>Written for commit
|
||
|
|
57ff5d3ce9
|
feat(hexclave): PR 2 — visible rebrand (Hexclave brand goes public) (#1481)
Some checks failed
all-good: Did all the other checks pass? / all-good (push) Has been cancelled
Ensure Prisma migrations are in sync with the schema / check_prisma_migrations (22.x) (push) Has been cancelled
DB migration compat / Check if migrations changed (push) Has been cancelled
Docker Server Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Server Build and Run / docker (push) Has been cancelled
Runs E2E API Tests (Local Emulator) / E2E Tests (Local Emulator, Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (mock, 22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (prod, 22.x) (push) Has been cancelled
Runs E2E API Tests with custom port prefix / build (22.x) (push) Has been cancelled
Runs E2E Fallback Tests / E2E Fallback Tests (Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Lint & build / lint_and_build (24) (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
DB migration compat / Back-compat — Current branch migrations with ${{ needs.check-migrations-changed.outputs.base_branch }} branch code (push) Has been cancelled
DB migration compat / Forward-compat — Current branch code with ${{ needs.check-migrations-changed.outputs.base_branch }} branch migrations (push) Has been cancelled
DB migration compat / No migration changes (skipped) (push) Has been cancelled
## Summary **Stacked on [#1475](https://github.com/hexclave/stack-auth/pull/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`](./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.ts](packages/template/src/lib/stack-app/apps/implementations/common.ts:127) → `https://api.hexclave.com` / `https://r.hexclave.com`. PR 1's [`getHardcodedFallbackUrls`](packages/stack-shared/src/utils/urls.tsx:199) 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](apps/backend/src/lib/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/lib/stack-app/index.ts) + [packages/template/src/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](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`](apps/backend/prisma/migrations/20260523000000_rename_internal_project_to_hexclave/migration.sql) — 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`](apps/backend/prisma/seed.ts:87) 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](packages/stack-shared/src/utils/errors.tsx:71)) — "an error in Stack." → "an error in Hexclave." - Known-error message templates ([known-errors.tsx](packages/stack-shared/src/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](apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/(overview)/setup-page.tsx) + [link-existing-onboarding](apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx). - [init-stack](packages/init-stack/src/index.ts:634) `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**: - [`packages/stack-shared/src/helpers/init-prompt.ts`](packages/stack-shared/src/helpers/init-prompt.ts), [`/ai/prompts.ts`](packages/stack-shared/src/ai/prompts.ts), [`apps/backend/src/lib/ai/prompts.ts`](apps/backend/src/lib/ai/prompts.ts), [`apps/backend/src/lib/ai/tools/create-email-{template,draft}.ts`](apps/backend/src/lib/ai/tools/create-email-template.ts), [`apps/skills/src/app/route.ts`](apps/skills/src/app/route.ts) (taught MCP tool → `ask_hexclave` with compat note; CLI binary teach → `hexclave`), [`docs-mintlify/snippets/home-prompt-island.jsx`](docs-mintlify/snippets/home-prompt-island.jsx), [`packages/template/README.md`](packages/template/README.md) + integrations/convex/component/README.md. - `generate-sdks` propagated changes to `packages/{react,stack,js}`. - **OpenAPI dual-documentation**: [`apps/backend/src/app/api/latest/route.ts`](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](apps/backend/src/lib/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`](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`](.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, 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-auth` → `hexclave/hexclave` in every `package.json` `repository` field, README link, CHANGELOG raw-asset URL. ## Carve-outs (deliberately untouched) - **[`apps/backend/src/lib/tokens.tsx`](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) 6. **DNS for `r.hexclave.com`** → the analytics beacon `defaultAnalyticsBaseUrl`. Silent failure if missing (analytics drops), but should land alongside Tier 1. 7. **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. 8. **MX + SPF / DMARC for `hexclave.com`** → `team@hexclave.com` and `security@hexclave.com` mailboxes. The security disclosure mailbox is referenced in [`.github/SECURITY.md`](.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`](apps/backend/src/lib/internal-feedback-emails.tsx). Today, every runtime feedback email bounces. 9. **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`](packages/stack-shared/src/helpers/init-prompt.ts) fails. 10. **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 11. **DNS for `discord.hexclave.com`** → Discord invite redirect, used in every README's chip and the dashboard footer. 12. **DNS for `demo.hexclave.com`** → "✨ Demo" badge in every npm package README. Broken-image badge on the package page. 13. **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'. --------- Co-authored-by: Konstantin Wohlwend <n2d4xc@gmail.com> |
||
|
|
a27e4d9bb5
|
Small onboarding fixes (#1489)
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/hexclave/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Improves onboarding and analytics visuals. Adds clear Stripe setup
actions (Connect or Do Later) with safe redirects and precise
loading/disabled states, and fixes a stuck dashboard reload after
linking an existing project.
- **New Features**
- Payments onboarding: separate Connect/Do Later actions with per-button
loading and mutual disabling.
- US-only: “Do Later” creates a deferred Stripe account before finishing
onboarding.
- Secure redirect: enforce HTTPS on Connect and navigate via
window.location.href.
- Refresh Stripe account cache after `setupPayments()` to avoid stale
data on return.
- Analytics: smoother pie hover transitions, fading center label,
optional `showDateRange`; dashboard donut hides date range and adjusts
radii; revenue hover chart uses split bars for rounded tops and an avg
line.
- Tests cover deferred/unsupported payments setup and button loading
isolation.
- **Bug Fixes**
- After linking an existing config, use a full page navigation to the
project to prevent the dashboard from getting stuck on initial load.
<sup>Written for commit
|
||
|
|
d30962bf66 | Fix GH tokens refresh & devtool tabs | ||
|
|
f7e389809e
|
feat(hexclave): PR 1 — wire compatibility layer (invisible) (#1475)
Some checks failed
all-good: Did all the other checks pass? / all-good (push) Has been cancelled
Ensure Prisma migrations are in sync with the schema / check_prisma_migrations (22.x) (push) Has been cancelled
DB migration compat / Check if migrations changed (push) Has been cancelled
Docker Server Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Server Build and Run / docker (push) Has been cancelled
Runs E2E API Tests (Local Emulator) / E2E Tests (Local Emulator, Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (mock, 22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (prod, 22.x) (push) Has been cancelled
Runs E2E API Tests with custom port prefix / build (22.x) (push) Has been cancelled
Runs E2E Fallback Tests / E2E Fallback Tests (Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Lint & build / lint_and_build (24) (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
DB migration compat / Back-compat — Current branch migrations with ${{ needs.check-migrations-changed.outputs.base_branch }} branch code (push) Has been cancelled
DB migration compat / Forward-compat — Current branch code with ${{ needs.check-migrations-changed.outputs.base_branch }} branch migrations (push) Has been cancelled
DB migration compat / No migration changes (skipped) (push) Has been cancelled
## Summary
**Stacked on #1468** (`docs/hexclave-rename-plan` — the plan doc). Diff
vs that base = the actual PR 1 code.
This is **PR 1 of the Hexclave rebrand: the invisible compatibility
layer**. Everything is additive. Old SDKs, old wire identifiers, and old
env var names keep working unchanged. The backend dual-accepts and
dual-emits; new SDK code emits `x-hexclave-*` headers and the
`hexclave_` Bearer prefix; cookies dual-write; env vars dual-read across
every category. **No user-visible rebranding lands here** — that's PR 2.
See [`RENAME-TO-HEXCLAVE.md`](./RENAME-TO-HEXCLAVE.md) → *"PR 1
implementation guide"* for the full per-work-area spec, file pointers,
and chosen approach.
## What's implemented (all 14 PR-1 work-areas)
- **SDK export aliases** — `Hexclave*` aliases for the user-facing
`Stack*` exports added in `packages/template`; codegen propagates them
to `@stackframe/{js,stack,react,tanstack-start}`. React-only aliases
correctly excluded from `@stackframe/js`. (`e60550a2`)
- **JWT issuer dual-accept** — `decodeAccessToken` accepts both
`api.stack-auth.com` and `api.hexclave.com` issuers. Signing unchanged.
(`fc781def`)
- **Request-header dual-accept** — backend + dashboard proxies normalize
`x-hexclave-*` → `x-stack-*` at the existing empty proxy hook (so
`smart-request.tsx` and every route schema keep working unchanged); CORS
allowlists extended via a derive-once helper. (`2a056eac`)
- **MCP `ask_hexclave`** — registered alongside `ask_stack_auth` via a
shared helper; `ask_stack_auth` behavior byte-identical. (`30ffd604`)
- **Dev-tool** — DOM ids + header emit switched.
`window.HexclaveDevTool` exposed alongside `window.StackDevTool`.
(`32131ea7`)
- **The big consolidated commit** (`7fed864a`):
- **Env vars** — central `getEnvVariable` prefix-transform (HEXCLAVE
first, STACK fallback); dashboard + template client env files dual-read;
`turbo.json` globalEnv; `NEXT_PUBLIC_STACK_PORT_PREFIX` renamed outright
across ~82 files including docker.
- **Cookies** — dual-write/dual-read auth (`stack-access`/`-refresh-*`
and custom-domain variants), OAuth-state
(`stack-oauth-{inner,outer}-*`), and low-risk cookies (`stack-is-https`,
`stack-last-seen-changelog-version`). Bypass sites patched (backend
OAuth callback, dashboard remote-dev auth route, impersonation snippets,
snapshot serializer).
- **Bearer prefix** — SDK token parser accepts both `stackauth_` and
`hexclave_`; emits `hexclave_`. Discovery correction: this is purely
SDK-internal — the backend never parses it.
- **Response headers** — backend dual-emits
`x-hexclave-{request-id,actual-status,known-error}`; SDKs dual-read (new
first, stack fallback).
- **SDK request-header emit switch** —
`client/server/admin-interface.ts` + dashboard `api-headers.ts` +
`internal-project-headers.ts` + `feedback-form.tsx` switched to
`x-hexclave-*`. Plus `stack_response_mode` query param.
- **Storage keys** — dev-tool / cli-auth / oauth-button / docs keys
renamed (straight); `stack:session-replay:v1` dual-read so in-progress
recordings survive SDK upgrades; `stack_mfa_attempt_code` dual-read.
- **Query params** — cross-domain params dual-emit/dual-accept via
shared helpers; backend `oauth/authorize` accepts
`hexclave_response_mode` and `stack_response_mode`; `stack-init-id`
renamed.
- **`Symbol.for`** — app-internals symbol gets a parallel
`Symbol.for("Hexclave--app-internals")` getter on each attach site (no
read-site churn — old symbol still attached). 3 file-private symbols
renamed outright.
- **Config discovery** — prefer `hexclave.config.ts`, fall back to
`stack.config.ts` at every discovery site (CLI / dashboard / backend /
local-emulator); `init` writes the new filename; CLI credentials path
migrates.
- **Internal renames** — `StackAssertionError`,
`StackClient/Server/AdminInterface` renamed outright (no alias, per the
"internal-only → rename" rule). ~264 files touched.
- **Review-pass fixes** (`21217fbe`) — three real bugs found by parallel
review agents and fixed:
- `snapshot-serializer.ts` was interpolating the whole
`keyedCookieNamePrefixes` array (`${arr}`) — adding a second prefix
would have corrupted **every** OAuth-cookie snapshot, not just new ones.
- **Docker port-prefix producer/consumer mismatch** —
`entrypoint.sh`/`run-emulator.sh`/cloud-init `user-data` were still
producing `NEXT_PUBLIC_STACK_PORT_PREFIX` while the dashboard sentinel +
consumers had been renamed; silent self-host regression (custom port
prefix would be ignored).
- **Missing `hexclave-oauth-inner-*` dual-write** in the OAuth authorize
route — callback's fallback masked it but the dual-write was specified
by the plan.
- Plus: `mcp.test.ts` tool-list assertions updated to include
`ask_hexclave`; two dashboard header-emit sites switched to
`x-hexclave-*` for consistency.
- **E2E snapshot serializer follow-up** (`4b16cc5d`) —
`x-hexclave-request-id` added to the hidden-headers list (mirroring
`x-stack-request-id` treatment), and 2 sample inline snapshots
regenerated in `projects.test.ts` to include the new dual-emitted
headers.
## Verification
- **`pnpm typecheck`** — clean (the fresh-worktree `@/.source` / Prisma
codegen gap in `stack-docs` is pre-existing and unrelated).
- **`pnpm lint`** — 29/29 packages green.
- **`pnpm exec turbo run build --filter=./packages/*`** — 13/13 packages
build (including `@stackframe/stack-cli` once the dashboard standalone
is present).
- **Live E2E** against a running backend on `cl/hexclave-pr1`:
- `pnpm test run
apps/e2e/tests/backend/endpoints/api/v1/internal/mcp.test.ts` — **6/6
pass** (verifies the new `ask_hexclave` tool — the hand-written inline
snapshot matched actual MCP server output).
- `pnpm test run
apps/e2e/tests/backend/endpoints/api/v1/internal/projects.test.ts` —
**11/11 pass** (verifies wire dual-accept + dual-emit end-to-end; the
snapshot serializer fix was found and applied during this check).
A four-agent parallel **review pass** also audited the full diff for
logic/runtime bugs across the work-areas (wire headers + JWT, cookies +
bearer + symbols, env vars, query params + config + MCP + aliases). All
in-slice review verdicts were ✓ except the three bugs listed above,
which are now fixed.
## Known follow-ups (out of scope for this PR)
- **E2E snapshots across the rest of the suite** — backend now
dual-emits `x-hexclave-{known-error,actual-status}` alongside
`x-stack-*`, which legitimately appears in inline snapshots throughout
`apps/e2e`. Two were regenerated here as a sample; the rest should regen
with `vitest -u` in CI.
- **Docker shell env vars beyond `PORT_PREFIX`** — `entrypoint.sh` still
reads `STACK_*` env vars directly (the JS-side `getEnvVariable`
transform doesn't help the shell). JS consumers dual-read so it works in
practice; full shell-level dual-read is a deeper self-host follow-up.
- **`@stackframe/stack-cli` build ordering** — pre-existing; needs
`build:rde-standalone` first. Not affected by this PR.
## Test plan
- [ ] CI runs full e2e suite (with `vitest -u` to absorb dual-emit
snapshot deltas, then committed back)
- [ ] Spot-check: an old SDK build (emitting only `x-stack-*`) still
authenticates against the new backend
- [ ] Spot-check: a new SDK (emitting `x-hexclave-*` / `Bearer
hexclave_*`) still authenticates against an old backend during deploy
ordering
- [ ] Manual: `npx @stackframe/stack-cli@latest init` (new onboarding
entrypoint) generates `hexclave.config.ts`
- [ ] Manual: existing `stack.config.ts`-only project still resolves (no
migration required)
---------
Co-authored-by: bilal <bilal@stack-auth.com>
|
||
|
|
10df9b2b7b
|
Fix dashboard sandbox compile errors and switch smart model to Grok (#1476)
## Summary - Forward Babel/JSX compile errors, runtime throws, and unhandled rejections from the AI dashboard sandbox iframe to the parent composer via `postMessage`, so users see actionable errors instead of a blank preview - Compile AI-generated dashboard source explicitly with `Babel.transform` + try/catch (stored in `text/plain` to avoid Babel's auto-handler swallowing parse errors) and add `crossorigin="anonymous"` on the Babel script for readable cross-origin error messages - Switch authenticated smart-tier model from `moonshotai/kimi-k2.6:nitro` to `x-ai/grok-build-0.1` ## Test plan - [ ] Generate a dashboard with valid AI code and confirm the preview still renders - [ ] Generate a dashboard with invalid JSX and confirm the composer shows the compile error (not a blank iframe) - [ ] Trigger a runtime error in generated dashboard code and confirm it reaches the parent error boundary - [ ] Verify authenticated smart-tier requests route to `x-ai/grok-build-0.1` Made with [Cursor](https://cursor.com) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Embedded dashboards now show a clear “Dashboard failed to compile” message on compilation errors instead of a blank iframe. * Dashboard runtime errors and unhandled promise rejections are captured earlier and forwarded to the parent for improved visibility. * **Updates** * The authenticated AI model used for the "smart" quality has been changed, affecting model selection for authenticated requests. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/hexclave/stack-auth/pull/1476?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
9b1851dd54
|
Managed email domain deletion and Cloudflare DNS import UX (#1442)
## Summary - Add an admin-only delete endpoint and SDK method to remove managed email domains, with Resend/DNSimple cleanup and a guard against deleting domains currently in use for sending. - Add dashboard UI to remove unused managed domains (with confirmation) and improve the DNS setup step with Cloudflare detection, zone file download, and import instructions. - Add E2E coverage for delete auth, success, in-use rejection, post-switch deletion, and 404 cases. ## Test plan - [ ] Run `pnpm test run managed-email-onboarding` - [ ] In dashboard email settings, add a managed domain and verify Cloudflare hint appears when NS records point to Cloudflare - [ ] Remove an unused managed domain and confirm it disappears from the list - [ ] Verify active (in-use) managed domains cannot be deleted until email provider is switched away Made with [Cursor](https://cursor.com) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Delete managed email domains from the dashboard with a confirmation flow and success notification * Cloudflare-aware domain setup: detection banner, quick links to Cloudflare DNS, downloadable zone file, and import instructions * Admin API and admin-app method to perform managed-domain deletion * **Bug Fixes** * Deletion blocked with a clear error when a domain is actively used for sending * **Tests** * Added end-to-end coverage for managed-domain delete scenarios (success, in-use conflict, auth rejection, and 404) * **Style** * Data grid layout adjusted to prevent unintended full-height stretching across various tables <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/hexclave/stack-auth/pull/1442?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
7e70b11d80
|
Fix onboarding shared OAuth provider persistence (#1477) | ||
|
|
99f07e9516 |
Trust hosted domains
Some checks failed
all-good: Did all the other checks pass? / all-good (push) Has been cancelled
Ensure Prisma migrations are in sync with the schema / check_prisma_migrations (22.x) (push) Has been cancelled
Docker Server Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Server Build and Run / docker (push) Has been cancelled
Runs E2E API Tests (Local Emulator) / E2E Tests (Local Emulator, Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (mock, 22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (prod, 22.x) (push) Has been cancelled
Runs E2E API Tests with custom port prefix / build (22.x) (push) Has been cancelled
Runs E2E Fallback Tests / E2E Fallback Tests (Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Lint & build / lint_and_build (24) (push) Has been cancelled
Publish npm packages / publish (push) Has been cancelled
Publish Swift SDK to prerelease repo / publish (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
|
||
|
|
9fc7332ead
|
Restore sign-up setting descriptions (#1469) | ||
|
|
e42ec65c88
|
Payments app design fixes (#1375)
<!-- Make sure you've read the CONTRIBUTING.md guidelines: https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md --> ## Summary This PR brings the Payments dashboard surfaces in line with the shared design system: product creation, product-line / included-item dialogs, auth-method toggles, payments empty states, and related layout polish. Dialogs migrate from raw shadcn `Dialog` to `DesignDialog` with consistent headers, footers, inputs, and selector dropdowns. **Base:** `dev` → **Head:** `Payments-app-design-fixes` **Scope:** 31 files, ~+1.4k / −1.3k lines **Captured on:** local dev server (`internal` project), signed in as `admin@example.com` ## Screenshots Captured from `http://localhost:8101` (viewport: **1920×1200** standard, **2560×1440** widescreen). Assets hosted in [this gist](https://gist.github.com/mantrakp04/ca3483d2b66b8e28f0872488df573ccf). > Red outlines on the **after** shots mark the new or changed UI introduced by this PR. ### Create Product — payments form redesign | | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | Widescreen: | | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Product Lines onboarding — vertical centering fix | | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Create Product Line dialog — `DesignDialog` migration | | Before | After | | --- | --- | --- | | Light | *(legacy shadcn dialog on `dev` — open via Product Line → Create new)* |  | | Dark | |  | ### Auth Methods — toggle row accessibility | | Before | After | | --- | --- | --- | | Light |  |  | | Dark |  |  | ### Other migrated surfaces (after only) | Page | Light | Dark | | --- | --- | --- | | Payments settings |  |  | | Sign-up rules |  |  | | Projects list (Create Project button) |  |  | | Playground / DesignDialog |  |  | | Included Item dialog |  |  | ### Scroll behaviour — Sign-up Rules | | Light | Dark | | --- | --- | --- | | Scroll |  |  | ## What's new - **`DesignDialog`** extended with `customHeader`, `noBodyPadding`, and section `className` hooks; Playground updated to showcase them. - **Payments dialogs** (`CreateProductLineDialog`, `IncludedItemDialog`, price edit, item dialog) migrated to design-system components. - **Create Product** page uses `DesignButton`, `DesignInput`, `DesignSelectorDropdown`, and refreshed header actions. - **Auth Methods** toggle rows use semantic `<Label htmlFor>` instead of click-capture divs. - **Payments layout** empty-state card centers correctly; product-lines onboarding slideshow vertically centers. - **Backend** seed invariant for Growth product price; removed unused import in product switch route. ## Notes for reviewers - Dialog migrations preserve validation + async error handling (`runAsynchronouslyWithAlert` where applicable). - Included-item dialog uses a sentinel value for “Create new item” to avoid colliding with real item IDs. - `packages/stack` / `packages/js` are untouched; template + dashboard-ui-components carry SDK-facing dialog changes. ## Test plan - [x] Visual capture on `internal` project (`admin@example.com`) — light/dark, standard + widescreen - [ ] Create product flow: customer type → product line dropdown → create line dialog - [ ] Add included item dialog from create/edit product - [ ] Auth Methods toggles (label click + switch) - [ ] Payments product-lines onboarding slideshow at varied viewport heights - [ ] `pnpm typecheck` / `pnpm lint` / targeted E2E if API surface changed --------- Co-authored-by: nams1570 <amanganapathy@gmail.com> Co-authored-by: mantrakp04 <mantrakp@gmail.com> Co-authored-by: Mantra <87142457+mantrakp04@users.noreply.github.com> |
||
|
|
be2ad595ad
|
fix: checkout flow for 0 dollar subscription (#1465)
### Context There was a small bug via dashboard checkout flow where it would fail on trying to create a checkout flow for a free product subscription because no client secret is generated for a 0 dollar subscription. ### Summary of Changes The flow should be fine now. There's special carve out logic for it. That being said, users attempting to mimic a free plan grant are encouraged to follow the `ensureFreePlan` pattern. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Free subscription selections now bypass Stripe payment processing, streamlining checkout for zero-cost offerings. * Purchase return flow now properly recognizes and activates free subscriptions without requiring payment confirmation. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/hexclave/stack-auth/pull/1465?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
3b2e991c78
|
Fix browser compatibility: guard requestIdleCallback and startViewTransition (#1464) | ||
|
|
b8fc04bdbd
|
feat: link Stack Auth projects to GitHub and push config from the dashboard (#1450)
End-to-end flow for managing Stack Auth config via GitHub: link a repo
during onboarding, edit settings in the dashboard, and have the change
committed to your repo + synced back via a GitHub Actions workflow.

## What this adds
- **CLI** — `stack config push --source github --source-repo
--source-path --source-workflow-path`. Records the source on the config
row so the dashboard knows where the file lives. Reads `GITHUB_SHA` /
`GITHUB_REF_NAME` for commit + branch.
- **Onboarding "Link existing project"** — searchable repo/branch
comboboxes, auto-detects candidate `stack.config.{ts,js}` paths, writes
`STACK_AUTH_PROJECT_ID` + `STACK_AUTH_SECRET_SERVER_KEY` secrets, and
commits a generated workflow YAML that re-runs `stack config push` on
every change to the config file.
- **Dashboard "Push to GitHub" dialog** — replaces the prior TODO
buttons. Pre-flights `repo`+`workflow` scopes on the user's GitHub
connection; if missing, the button flips to "Reconnect with GitHub". On
push, commits the dashboard's edit straight to the linked repo/branch
via the Contents API (with `cache: "no-store"` to dodge GitHub's 60s GET
cache so consecutive pushes don't 409). Suspense boundary scoped to the
dialog body so opening it doesn't blank the dashboard.
- **Project settings** — surface the linked workflow file as a clickable
GitHub link when the source carries `workflow_path`.
## Test plan
- `pnpm lint` (29/29) ✓
- `pnpm typecheck` (29/29) ✓
- `pnpm --filter @stackframe/stack-cli test` (111/111) ✓
- Dashboard vitest on the three relevant files
(`link-existing-onboarding-workflow`, `github-api`,
`github-config-push`) — 37/37 ✓
- Live end-to-end: `BilalG1/lex-lookup` linked to a local dev project;
passkey toggled, push committed `0bb958bd`
([commit](
|
||
|
|
002692e519
|
Compress oversized images client-side in AI chat (#1456) | ||
|
|
0e85b05c3d
|
[Fix]: Payments App Sundry Fixes (#1455)
### Summary of Changes
You can now edit items on a product view.
The "Make free" button is less obtuse, and it clearly tells you what
it's going to do.
Additionally, we found out while working on this PR that you cannot
create a `paymentIntent` on stripe that is < 0.5$. So, you can't create
an OTP for a "free" product. We add safeguards to protect against that.
Also, 0 dollar subscriptions don't create a subscription invoice.
Additionally, the old code relied on being able to fetch the stripe
client secret, which would be null for a 0 dollar subscription so we
create a carve out.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Better free-product checkout handling: $0 subscriptions return an
empty success response without a payment client secret; non-free
subscriptions include client secret when needed.
* UI: “Make free” flow, “Free · {amount}” with price ID, per-price
checkout error indicators/tooltips, and an alert for products with
invalid prices.
* Client- and server-side Stripe one-time minimum checks.
* **Bug Fixes**
* Included-item dialog now resets form state when opened to avoid stale
values.
* **Documentation**
* OpenAPI: clarified client_secret may be omitted when no customer
confirmation is required.
* **Tests**
* Added end-to-end tests covering $0 purchase-session flows.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/hexclave/stack-auth/pull/1455?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
|
||
|
|
01aacd2dd4
|
fix(dashboard): repair and polish the GitHub link-existing project flow (#1441)
Rework of the **new-project → Link Existing Config** flow on the dashboard, plus the published `stack-cli` it depends on. The starting point on `dev` had the link-existing flow effectively broken end-to-end (the generated GitHub workflow could never authenticate, and the GitHub-account selection UI dead-ended in several states). This PR fixes the blockers, polishes the local-CLI path, and adds a searchable repo/branch picker. --- ## What was broken | Severity | Issue | Fixed in | |---|---|---| | 🔴 | Generated workflow omitted the required `--cloud-project-id` flag → every run failed at Commander before the action ran. | `d0e6ad15f`, `55ff7e319` | | 🔴 | Workflow exported `STACK_PROJECT_ID` env var the CLI never read. | `55ff7e319` (CLI now reads it; workflow drops the explicit flag) | | 🔴 | `pnpx` isn't on `ubuntu-latest` → step failed with `command not found`. | `65789a1ac` | | 🔴 | "No connected GitHub account found" alert with **no Connect button**. | `d0e6ad15f` | | 🟠 | "Connect new" used `getOrLinkConnectedAccount` (get-or-link) → silently returned the existing account instead of starting a fresh OAuth flow. | `d0e6ad15f` | | 🟠 | `workflow_dispatch` 404s on non-default branches; threw before advancing to the logs step even though the push-triggered run worked. | `d0e6ad15f` | | 🟠 | Config-path suggestions prepended `./`, which breaks GitHub's `on.push.paths` filter — ongoing config edits never re-triggered the workflow. | `d0e6ad15f` | | 🟡 | Account selector briefly showed the numeric `providerAccountId` before the GitHub `/user` fetch populated the username. | `de9ec1923` | | 🟡 | Repository / branch dropdowns capped at 100 entries with no search. | `7550eaacb` | ## What changed ### Dashboard — Link Existing Config flow - **Local CLI step rebuild** (`ed25eabf9`, `ebb090e5b`): split into separate "Sign in" and "Push config" code blocks using the shared `CodeBlock` component (copy button built-in), added a `npx / pnpx / bunx` runner pill toggle (default `npx`), moved `--config-file <path>` to the end of the push command so users can copy everything up to the placeholder, trimmed redundant helper text. - **GitHub OAuth states** (`d0e6ad15f`, `de9ec1923`): empty-state "Connect GitHub account" button; "Connect new" now uses `linkConnectedAccount` so it actually starts OAuth; loading row instead of `providerAccountId` flash. - **Searchable repo + branch combobox** (`7550eaacb`, `5ce1b6bd9`): new `RemoteSearchCombobox` (Popover + cmdk, same pattern as `data-table/faceted-filter`), debounced GitHub `/search/repositories` and `/git/matching-refs/heads/{prefix}` calls so users with > 100 repos/branches can find any of them. Branch "Refresh" button removed — branches auto-load on repo select. - **Workflow generator** (`d0e6ad15f`, `65789a1ac`): config paths normalised (strip leading `./`); workflow uses `actions/setup-node@v4` + `npx --yes`; `workflow_dispatch` failure is now best-effort (the workflow-file commit's push event triggers the run on any branch). ### Stack CLI - `STACK_PROJECT_ID` env-var fallback for `--cloud-project-id` (`55ff7e319`). Both `config push` and `config pull` are affected; explicit flag still wins. New `resolveProjectId` helper in `lib/auth.ts` with 5 unit tests (`auth.test.ts`). ### Misc - `2faffb662` drops an unused `useTransition` wrapper around a `setProjectStatuses` Map insert in the new-project flow. --- ## Release ordering note The generated workflow's `run:` line **no longer passes `--cloud-project-id`** — the CLI reads `STACK_PROJECT_ID` from env instead. This means a workflow generated by this branch only works against a `@stackframe/stack-cli` published with the env-var fallback from `55ff7e319`. The CLI and dashboard ship from the same monorepo so this should be a non-issue in the normal release cadence, but worth confirming the CLI publishes alongside the dashboard deploy. Existing workflows already committed in user repos still have the explicit flag and continue to work unchanged. ## Validation - `pnpm --filter @stackframe/dashboard run typecheck` ✅ - `pnpm --filter @stackframe/dashboard run lint` ✅ - `pnpm --filter @stackframe/stack-cli run typecheck` ✅ - `pnpm --filter @stackframe/stack-cli run lint` ✅ - `pnpm --filter @stackframe/stack-cli test` ✅ (14 tests; 5 new for `resolveProjectId`) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Searchable repository and branch selection UI for GitHub onboarding * New remote search combobox component for selecting repos/branches * Selectable CLI package runner and dynamic command display during onboarding * **Improvements** * CLI accepts STACK_PROJECT_ID env var; cloud project flag is optional * Workflow generation normalizes/validates config paths, sets up Node.js v20, and uses npx; onboarding dispatch is non-fatal * Hardened repository loading to avoid stale async updates * **Tests** * Added tests covering project ID resolution logic <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/hexclave/stack-auth/pull/1441?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
20b7921b93
|
Fix theme toggle in browsers without View Transitions (#1453)
<!-- Make sure you've read the CONTRIBUTING.md guidelines: https://github.com/hexclave/stack-auth/blob/dev/CONTRIBUTING.md --> Fixes the dashboard theme toggle in browsers that do not support `document.startViewTransition` by falling back to an immediate theme change. Link to Devin session: https://app.devin.ai/sessions/c1f1deed2f1c4d42979df2ee949cf74d Requested by: @madster456 --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
055304d3fd
|
Onboarding app redesign (#1370)
# Onboarding app redesign Rolls out a unified dashboard visual language centered on `DesignCard` groupings, a new canonical `DesignDialog`, and an inline live-preview pattern. Touches the project listing, project overview, auth methods, design language, onboarding, and sign-up rules surfaces. Reusable primitives (`DesignCard`, `DesignDialog`, `MethodToggleRow`) replace one-off layouts, and the project card now leads with **total users + 30-day signups** instead of a weekly-users tile. **Base:** `dev` → **Head:** `onboarding-app-redesign` > Red outlines on the "after" shots highlight the UI that changed in this PR. Empty outlines = layout/chrome change with no data delta. --- ## Flagship: Project listing (`/projects`) Project cards swap the weekly-users widget for a `ProjectUsersMetric` (total user count + 30-day signups sparkline). Hover lifts the card; the metrics row is now part of the card body instead of a footer strip. | | Light | Dark | |--------|-------|------| | Before |  |  | | After |  |  | ## Flagship: Auth methods (`/projects/[id]/auth-methods`) Full restructure: the horizontal `SettingCard` strips are replaced by stacked `DesignCard` sections (Sign-in methods · Sign-up policies · User deletion), with a sticky **live sign-in preview** column on the right. Provider rows become `MethodToggleRow`s with inline configure actions. | | Light | Dark | |--------|-------|------| | Before |  |  | | After |  |  | ## Flagship: Project overview (`/projects/[id]`) Line + donut charts migrate to the shared `AnalyticsChart` component. Referrers list gains a max-height + scroll affordance so it no longer pushes neighbouring tiles off-screen. | | Light | Dark | |--------|-------|------| | Before |  |  | | After |  |  | ## Other migrated surfaces | Surface | Before (dark) | After (dark) | What changed | |---------|---------------|--------------|--------------| | `/projects/[id]/onboarding` |  |  | Email-verification toggle adopts the new `MethodToggleRow` + confirmation `DesignDialog` variant | | `/projects/[id]/sign-up-rules` |  |  | Rule builder rewrapped in `DesignCard`/`DesignAlert`/`DesignButton` primitives | | `/projects/[id]/design-language` |  |  | Adds a `DesignDialog` showcase section so consumers can see the canonical modal styling | | `/playground` |  |  | New `dialog` playground entry exercising the size/variant/icon-chip permutations | Light-mode counterparts for the long-tail surfaces are in the [companion gist](https://gist.github.com/mantrakp04/ff6b32969cb08510860e94be7d67dbf7). --- ## What's new - **`DesignDialog`** (`packages/dashboard-ui-components/src/components/dialog.tsx`) — canonical modal with configurable size/variant, optional icon chip, and split header/body/footer regions. Replaces ad-hoc `Dialog` + `DialogContent` usage across the dashboard. - **`MethodToggleRow`** — shared row primitive used by auth-methods and onboarding for "thing with a toggle and an inline configure CTA". - **`ProjectUsersMetric`** — total users + 30-day signups sparkline; powers the new project card metric and reuses the `projects-weekly-users` backend route renamed to `projects-metrics`. - **`action-dialog`** gains `keepOpenOnOutsideInteraction` and `contentClassName` props so variant chrome can ride along through the existing helper. - Backend: new internal `projects-metrics` route + test; `seed-dummy-data.ts` updated to populate the new metric. ## Notes for reviewers - Reusable primitives (`DesignCard`, `DesignDialog`, `MethodToggleRow`) live in `packages/dashboard-ui-components` — please flag any inline duplications you spot. - The auth-methods live-preview only renders at `lg+`. Below that breakpoint the page falls back to the stacked card layout. - The OAuth provider config dialogs adopt the new pill toggle for **Shared keys / Custom OAuth credentials**; the underlying form fields are unchanged. ## Test plan - [ ] `/projects` — verify the metric tile renders both empty-state and populated (Demo Project has 584 users seeded) - [ ] `/projects/[id]/auth-methods` — toggle each method on/off, confirm live preview updates in real time - [ ] `/projects/[id]/auth-methods` — open a provider dialog, switch between Shared / Custom keys, verify form state preserved - [ ] `/projects/[id]/onboarding` — toggle email verification, confirm the confirmation dialog variant - [ ] `/projects/[id]/sign-up-rules` — verify rule builder still saves correctly under the new chrome - [ ] Mobile/`md` breakpoint — auth-methods falls back to stacked layout, no overflow - [ ] Dark mode parity on every flagship surface <sub>Visuals captured via local dev server (`localhost:8101`) on `admin@example.com` seeded account. Red outlines mark new/changed UI on the "after" pass.</sub> --------- Co-authored-by: mantrakp04 <mantrakp@gmail.com> Co-authored-by: Mantra <87142457+mantrakp04@users.noreply.github.com> |
||
|
|
20b029fd81 | Fix build | ||
|
|
2c620aa208
|
Show enabled alpha apps in sidebar and app store (#1449) | ||
|
|
512099ed23
|
Speed up dummy-project seeding (preview create-project ~15s → ~1.3s) (#1437)
## Summary The internal `preview/create-project` endpoint was taking ~15s because `seedDummyProject` created its dummy users one at a time through the full `usersCrudHandlers.adminCreate` CRUD pipeline (one DB transaction + config render per user, ~86 users). This reworks the seeding path to use bulk inserts. End-to-end, the endpoint's server-side handler time drops from **~15,100ms → ~1,300ms** (~11× faster). ## Seeding changes (`seed-dummy-data.ts`) - **`seedDummyUsers` — bulk insert.** Build every row (`ProjectUser`, `ContactChannel`, `AuthMethod`, `ProjectUserOAuthAccount`, `OAuthAuthMethod`, default permissions) up front with pre-generated UUIDs, then insert via one `createMany` per table inside a single transaction — replacing ~86 sequential `adminCreate` transactions. Named-user team memberships are bulk-inserted the same way (`TeamMember` + `TeamMemberDirectPermission`). Idempotency is preserved with a single up-front email lookup, so re-runs against an existing project still skip existing users. - **Native `randomUUID`.** The seed paths now use `node:crypto`'s `randomUUID()` instead of stack-shared's `generateUuid()`. The browser-safe polyfill calls `crypto.getRandomValues` ~31× per UUID (once per template char, each with a fresh `Uint8Array(1)`); generating thousands of seed UUIDs made that ~800ms of pure CPU in the activity-event build alone. - **`seedBulkSignupsAndActivity`.** Skip the redundant back-date `UPDATE` for freshly-inserted users (`createMany` already writes correct `createdAt`/`signedUpAt`), and flush ClickHouse events in larger, parallel batches. - **`seedDummyProject`.** Run `seedBulkSignupsAndActivity` concurrently with the lighter remaining steps, and fold `seedDummyTransactions` into the emails/activity/replays `Promise.all`. - Removed the now-unused `syncSeedUserOauthProviders` helper. The bulk path produces the same rows as the CRUD-handler path (verified row-count equality during development). Webhooks / soft-limit checks are intentionally not fired for seed data, consistent with the rest of the seed. ## Also in this PR — preview-mode 404 fix (`preview-project-redirect.tsx`) While testing the above, the dashboard 404'd right after a preview project was created. In preview mode the `/projects` page renders `PreviewProjectRedirect`, which `POST`s `/internal/preview/create-project` and then `router.push()`es to `/projects/<new-id>` — but it never refreshed the client-side owned-projects cache, so the `[projectId]` route's `useAdminApp()` read a stale list, failed to find the just-created project, and called `notFound()`. Fixed by refreshing the owned-projects cache before navigating, matching what the normal create-project flow in `page-client.tsx` already does. (Pre-existing bug, not caused by the seeding change — but it surfaces the seeding path, so it's bundled here.) ## Testing `pnpm typecheck` and `pnpm lint` pass for both backend and dashboard. The preview endpoint was exercised repeatedly during development (HTTP 200, projects created and populated correctly). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Performance** * Much faster bulk user and event seeding via larger, parallelized batches and optimized backfilling. * **Refactor** * Dummy data seeding redesigned to be idempotent, deterministic, and bulk-oriented; seeding tasks now overlap where safe. * **Bug Fixes** * Preview project flow validates client capabilities and refreshes the local project list to avoid stale navigation. * Auto-login guarded to run only once to prevent duplicate sign-ins. * **UI/UX** * Walkthrough steps and sidebar behavior improved; walkthrough labels and search keywords updated. * **Chore** * CLI identity command now resolves session authentication more reliably. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/hexclave/stack-auth/pull/1437?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> |