mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-30 21:01:54 +08:00
433d4dcc96
2041 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
433d4dcc96
|
Upgrade TypeScript from 5.9.3 to 6.0.3 (#1644) | ||
|
|
845487adee
|
fix: allow Google/GitHub/Microsoft OAuth in RDE onboarding (#1640) | ||
|
|
88eae6fbf1 | chore: update package versions | ||
|
|
b69f9f0eeb | Various UX/AX improvements | ||
|
|
38ae913fc9
|
Rename STACK_* env vars to HEXCLAVE_* in env templates, with legacy dual-read (#1588)
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
Completes the env-var side of the Hexclave rebrand: every
`STACK_*`-prefixed variable (including `NEXT_PUBLIC_STACK_*` and
`VITE_STACK_*`) is renamed to `HEXCLAVE_*` across all checked-in `.env`,
`.env.development`, and `.env.example` files (30 files, ~135 keys).
Legacy `STACK_*` names keep working everywhere via dual-read, so
**existing deployments, `.env.local` files, and self-hosted setups need
no immediate migration**.
## How legacy names keep working
- **Server code** already resolves `HEXCLAVE_*` first with `STACK_*`
fallback via `getEnvVariable`. Direct `process.env.STACK_X` readers fed
by the renamed files (prisma seed, e2e tests/helpers, internal-tool
scripts, examples, `prisma.config.ts`) now read `HEXCLAVE_X || STACK_X`.
- **Client code** (Next.js build-time inlining) uses literal dual-read
expressions; the dashboard's `_inlineEnvVars` already had them.
- **Docker/self-hosting**: `docker/server/entrypoint.sh` (shared by the
server and local-emulator images) gets a generic two-way
`HEXCLAVE_`↔`STACK_` env mirror — runs at startup and again before
sentinel replacement — replacing the previous URL-trio-only mirror.
Operators can use either prefix.
## The empty-placeholder trap (`||` vs `??`)
The checked-in templates define empty placeholders (`HEXCLAVE_X=#
comment` parses to `""` via dotenv). With `?? `-based fallbacks, that
empty string would silently shadow a real value under the legacy name —
including legacy vars set in Vercel/CI env at build time, since the
tracked `.env` is present during builds. All fallback chains therefore
treat empty-as-unset (`||`):
- `getEnvVariable` and `getProcessEnv` in `packages/shared`
- the dashboard/docs/example literal dual-reads
- the generated SDK env getters (via
`packages/template/scripts/generate-env.ts`; the generated
`src/generated/env.ts` files are gitignored and regenerate at build)
## Other notable changes
- Tests that override env now set the canonical `HEXCLAVE_*` name (it
wins over `STACK_*`): e2e `cross-domain-auth`, backend
`internal-feedback-emails` in-source test.
- e2e `helpers.ts` port-prefix expansion loop also matches the
`HEXCLAVE_` prefixes.
- `docker/local-emulator/generate-env-development.mjs` reads source keys
canonically (legacy fallback) and emits canonical keys; regenerated
output matches.
- `rotate-secrets.sh` falls back to
`HEXCLAVE_DATABASE_CONNECTION_STRING`.
- Docs code snippets (`docs/code-examples`) renamed outright to
canonical names, consistent with #1571.
- OAuth callback `console.warn` in `packages/template/src/lib/auth.ts`
now says Hexclave.
## Migration note for the team
Local `.env.local` files with legacy `STACK_*` overrides keep working
**unless** the override targets a var that `.env.development` now sets
to a real (non-empty) `HEXCLAVE_*` value — the canonical name wins over
file precedence. Rename those keys in your `.env.local` once.
## Verification
- `typecheck` + `lint` pass on every touched package (shared, backend,
dashboard, e2e, internal-tool, cli, docs, template). Pre-existing
failures on dev (`admin-app-impl.ts` typecheck, dashboard metrics-page
errors) are unchanged (identical error counts with/without this change).
- `getEnvVariable`/`getProcessEnv` fallback semantics smoke-tested
directly (empty-HEXCLAVE → legacy fallback, HEXCLAVE wins when set,
defaults intact).
- `internal-feedback-emails` in-source vitest passes; emulator env
generator `--check` passes; `bash -n` on touched shell scripts.
- Two independent review agents audited the diff for correctness bugs
and coverage gaps; all confirmed findings are fixed in the third commit.
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Renamed all `STACK_*` env vars (including
`NEXT_PUBLIC_STACK_*`/`VITE_STACK_*`) to `HEXCLAVE_*` across env
templates and code, with dual‑read that treats empty as unset, detects
conflicts, ignores post‑build sentinels, and falls back to legacy names.
All GitHub Actions now use `HEXCLAVE_*`; local‑emulator e2e is fixed by
setting `NEXT_PUBLIC_HEXCLAVE_IS_LOCAL_EMULATOR` in CI.
- **Refactors**
- Added conflict‑aware dual‑read helpers (prefer `HEXCLAVE_*`,
empty‑as‑unset, ignore post‑build sentinels, preserve empty passthrough)
and used them across `packages/shared` (resolver + tests),
`apps/dashboard` inline/public envs (with tests), `apps/backend` Prisma
config/seed and vitest (accept both prefixes), `packages/cli`
(API/Dashboard URLs, project ID, `HEXCLAVE_EMULATOR_HOME`; tests),
Docker (`entrypoint.sh` mirroring + `rotate-secrets.sh` DB URL),
docs/components (`docs/src/lib/env.ts`), and examples; hosted/Vite apps
now error if both spellings differ.
- Port‑prefix expansion includes `HEXCLAVE_*`; backend tests use a new
helper to resolve DB connection strings; Prisma prefers
`HEXCLAVE_DATABASE_CONNECTION_STRING` with legacy fallback.
- Generated SDK env getters use plain `HEXCLAVE_*` || `STACK_*` (no
conflict throw); dashboard inline resolver preserves empty/sentinel
passthrough to avoid build failures; docs/examples include dual‑read
utilities.
- Tests now stub canonical `HEXCLAVE_*` flags (e.g., plan limits, bot
challenge, OAuth tokens, hosted handler) to avoid shadowing/conflict
with committed defaults.
- **Migration**
- No immediate action; legacy `STACK_*` names still work.
- If both names are set with different values, builds/scripts error. Set
only `HEXCLAVE_*` or make both equal.
- SDK consumers won’t see conflict throws; update env names to
`HEXCLAVE_*` over time.
<sup>Written for commit
|
||
|
|
d064b20290 | chore: update package versions | ||
|
|
a9d77bbf63
|
feat: show info note when Reject action is selected in signup rule editor (#1633) | ||
|
|
1b5e79fab3
|
fix: changelog endpoint returns 502 silently without Sentry logging (#1618) | ||
|
|
c32b668076 | chore: update package versions | ||
|
|
4689ffb575 | Internal tools sidebar item | ||
|
|
ec7c7a8598 | Dormant toggle | ||
|
|
caec1ea567
|
Inject HEXCLAVE_* env vars in dev environment (#1627)
## Problem
`envVarsForProject` in the dev-environment manager only emits the legacy
`STACK_*` env var names. The rest of the CLI was migrated to the
`HEXCLAVE_*` brand as canonical, keeping `STACK_*` only as a fallback:
- `init` scaffolds `.env` with `NEXT_PUBLIC_HEXCLAVE_PROJECT_ID`,
`NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY`,
`HEXCLAVE_SECRET_SERVER_KEY`
- `resolveProjectId` reads `HEXCLAVE_PROJECT_ID` first, then
`STACK_PROJECT_ID` (commented as "legacy")
- `doctor` lists the `HEXCLAVE_*` names first
So `hexclave dev` injects a different set of names than the CLI
otherwise expects/generates.
## Change
`envVarsForProject` now emits both brands (`HEXCLAVE_*` and `STACK_*`)
across the public framework prefixes (`NEXT_PUBLIC_`, `VITE_`,
`EXPO_PUBLIC_`), built from a single source list.
- All previously-emitted `STACK_*` keys are unchanged (no regression).
- The secret server key is still only emitted as
`HEXCLAVE_SECRET_SERVER_KEY` / `STACK_SECRET_SERVER_KEY` — never under a
public, client-readable prefix.
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Updated the dev environment to emit both `HEXCLAVE_*` and legacy
`STACK_*` env vars so `hexclave dev` matches the rest of the CLI and
avoids name mismatches. Secret keys remain non-public.
- **Bug Fixes**
- Emit both brands for `PROJECT_ID`, `PUBLISHABLE_CLIENT_KEY`, and
`API_URL` under ``, `NEXT_PUBLIC_`, `VITE_`, `EXPO_PUBLIC_`.
- Only emit `HEXCLAVE_SECRET_SERVER_KEY` / `STACK_SECRET_SERVER_KEY`
(never with public prefixes).
- Keep existing `STACK_*` outputs unchanged for backward compatibility.
<sup>Written for commit
|
||
|
|
969bf03c5a
|
perf(platform-analytics): cut ClickHouse query peak memory (#1632)
## What
Performance pass on the internal **platform-analytics** route. All 17
ClickHouse queries fire in a single `Promise.all` on the shared
`stackframe` admin user, which is subject to a **9 GB per-user** memory
cap — so the worst case is the *sum* of per-query peaks, not the max.
Benchmarked at 10k projects / 1M users / 50M events (power-law, top
project ≈100k users), the sum of peaks was ~6.7 GiB. This PR brings it
down to ~3.8 GiB.
## Changes
**ClickHouse — `sipHash64(user_id)` as the distinct key** (exact,
verified byte-identical):
| query | peak mem | Δ |
|---|---|---|
| `dauSeries` | 949 → 373 MiB | −61% |
| `mauProjects` | 715 → 313 MiB | −56% |
| `activeByProject` | 635 → 374 MiB | −41% |
| `sparkByProject` | 1165 → 809 MiB | −31% |
A 64-bit hash has negligible collision probability over 1M users; the
benchmark confirmed identical output. (Same trick already used in the
internal-metrics MAU query.)
**ClickHouse — sample the activity split**
(`new`/`retained`/`reactivated`):
The split was the single heaviest query (~1.3 GiB) — its cost is a
window function over ~25.8M `(user, day)` rows plus an all-history scan,
which `sipHash` alone barely helped (−7%). It now uses **consistent
1-in-4 user sampling** (same `cityHash64(user_id) % 4` bucket applied to
both subqueries so each sampled user's full activity sequence is
preserved; counts scaled ×4):
- **317 MiB (−78%)** peak memory, **~0.4% mean error** (max 1.4% on the
smallest day) vs the exact result.
This is an **approximation** — the dashboard "Growth quality" chart now
notes it (`subtitle: "… · sampled estimate (~0.4%)"`).
`ACTIVITY_SPLIT_SAMPLE` is a single constant in the route; set it to `1`
to go back to exact.
## What I tried that did NOT make the cut (documented in the harnesses)
- `country` — peak memory is dominated by the per-user `argMax(country,
event_at)` payload, not the key, so hashing does nothing. Left
exact/unchanged.
- PG `authMethods` / `email` — with the production composite PK indexes
the original plans are already best; correlated-subquery / anti-join
rewrites were far worse. No PG query changes in this PR.
## Benchmark harnesses (added)
- `apps/backend/scripts/benchmark-platform-analytics.ts` — full-route
baseline (per-query time/memory/rows).
- `apps/backend/scripts/optimize-platform-analytics.ts` — sipHash & PG
variant comparison with byte-equality checks.
- `apps/backend/scripts/optimize-split.ts` — exact vs sampled split
variants with accuracy measurement.
They seed isolated `bench_pa` databases (server-side, auto-cleaned) and
read `system.query_log` / `EXPLAIN (ANALYZE, BUFFERS)`. Run e.g.:
`pnpm --filter @hexclave/backend run with-env:dev tsx
scripts/optimize-split.ts`
## Testing
- Backend `typecheck` passes. (Dashboard has pre-existing typecheck
errors on the base branch in unrelated files — auth-methods,
team-analytics, user-emails, RDE config — not touched here.)
- All exact rewrites verified byte-identical to the originals by the
harnesses; the sampled split measured at ~0.4% mean error.
Numbers are local warm-cache (relative shape, not production latency).
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Cuts worst-case ClickHouse memory for the internal platform analytics
route by switching to hashed distinct keys and sampling the heaviest
query. On a 10k projects / 1M users / 50M events benchmark, the sum of
per-query peaks drops from ~6.7 GiB to ~3.8 GiB with exact results (or
~0.4% error on the sampled chart).
- **Performance**
- Use sipHash64(user_id) as the distinct key in uniqExact/uniqExactIf
for DAU series, MAU/projects, active-by-project, and sparkline. Exact
results (verified). Peak memory down 31–61% per query.
- Sample the new/retained/reactivated split at 1-in-4 users (consistent
`cityHash64` bucket across subqueries, counts ×4). Peak memory ~−78%
(~1.3 GiB → ~0.3 GiB) with ~0.4% mean error. Toggle via
`ACTIVITY_SPLIT_SAMPLE` (set to 4; set to 1 for exact). Dashboard
subtitle now notes “sampled estimate (~0.4%).”
- Added local harnesses to seed isolated data and measure
time/memory/equality:
`apps/backend/scripts/internal-analytics/benchmark-platform-analytics.ts`,
`optimize-platform-analytics.ts`, `optimize-split.ts`.
<sup>Written for commit
|
||
|
|
25b0414d59
|
add platform analytics route to the dashboard (#1626)
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/hexclave/hexclave/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Add platform-wide analytics to the internal dashboard with a secure
backend route and a new page to visualize cross-project metrics. Only
available when viewing the `internal` project and gated by platform
admin access.
- **New Features**
- Backend: add `/api/latest/internal/platform-analytics` aggregating
metrics across all projects via ClickHouse; protected by
`ensurePlatformAdmin`.
- Dashboard: add `/projects/[projectId]/platform-analytics` page with
charts; sidebar entry appears only when `projectId === "internal"`.
- **Bug Fixes**
- Correctness: add `branch_id` filters to all event queries and project
aggregates; exclude the `internal` project from ClickHouse aggregates;
validate MRR quantity.
- Metrics/UI: feature adoption uses `total_projects` from the API and
clamps both chart and label to 0–100%; remove unreachable
`revenue_growth` sort key.
- Safety/Tests: use `Map` for country aggregation; add unit tests for
`ensurePlatformAdmin`/`isPlatformAdmin`; switch tests to inline
snapshots and document the `as-any` cast.
<sup>Written for commit
|
||
|
|
63d0eeefe9
|
fix(dashboard,backend): impersonation without logout + fix OAuth routing (#1617)
## Summary
Two fixes:
**1. Impersonation no longer requires logout** — The generated JS
snippet now clears all auth cookie variants (`hexclave-refresh-{pid}*`,
`stack-refresh-{pid}*`, access tokens) and sets the token in the
structured `hexclave-refresh-{pid}--default` format the SDK reads first.
Previously the snippet only set the legacy cookie, which was ignored
when a structured cookie already existed.
**2. Fix OAuth + other deeply nested API routes returning 404 in dev** —
Moved the API 404 handler from file-based
`api/[...notFoundPath]/route.ts` into the middleware (`proxy.tsx`). The
catch-all at the `api/` level was shadowing dynamic routes 7+ segments
deep (e.g. `auth/oauth/authorize/[provider_id]`) in Turbopack dev mode
(Next.js 16.2.7). The middleware already has `routes` + `SmartRouter`,
so it checks for a match before rewriting and returns the custom 404
directly when nothing matches.
Link to Devin session:
https://app.devin.ai/sessions/d9dcb2d203aa4a6ea36c8cdd2a4a42c2
Requested by: @mantrakp04
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Updated the user impersonation dialog to explicitly state that the
pasted console snippet will replace your current session with the
impersonated user’s session.
* **Refactor**
* Standardized the impersonation console snippet generation to use a
shared token-based approach, including proper expiration handling.
* **Bug Fixes**
* Improved reliability of the impersonation flow by failing when the
required refresh token is unavailable, preventing incomplete snippet
generation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: mantra <mantra@stack-auth.com>
|
||
|
|
75e497f3ec
|
[codex] Add skill context to Ask Hexclave (#1605)
## Summary
- Fetches the canonical Hexclave skill from `https://skill.hexclave.com`
when the backend AI route is invoked through MCP `ask_hexclave`
- Appends that skill content to the spawned docs agent's system context
before generation
- Adds focused tests for non-Ask-Hexclave no-op behavior, successful
skill embedding, and loud fetch failure
## Why
The public MCP server exposes the skill as a separate resource/prompt,
but the backend docs agent spawned by `ask_hexclave` only saw the user's
question. That meant clients had to correctly load the skill themselves,
and the server-side answer quality could miss the canonical
setup/context.
## Validation
- `pnpm -C apps/backend exec eslint
'src/app/api/latest/ai/query/[mode]/route.ts'
src/lib/ai/mcp-skill-context.ts src/lib/ai/mcp-skill-context.test.ts`
- `pnpm exec vitest run
apps/backend/src/lib/ai/mcp-skill-context.test.ts --config /dev/null
--environment node`
- `pnpm exec tsc --noEmit --target es2022 --module esnext
--moduleResolution bundler --lib es2022,dom --types vitest
apps/backend/src/lib/ai/mcp-skill-context.ts
apps/backend/src/lib/ai/mcp-skill-context.test.ts`
## Notes
- Normal backend Vitest/typecheck are blocked in this fresh worktree
because generated/built `@hexclave/shared/dist/*` files are missing, and
repo instructions say not to run package builds from the agent.
- Full backend lint also reports an unrelated pre-existing error in
`apps/backend/scripts/run-bulldozer-studio.ts`.
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Adds full Hexclave docs to `ask_hexclave` requests by fetching
https://docs.hexclave.com/llms-full.txt and appending them to the docs
agent system prompt. Includes a 5‑minute cache and 5s timeout, and skips
docs tools when `ask_hexclave` is used.
- **New Features**
- Added `getMcpSkillContextPrompt` to fetch and inject docs for
`ask_hexclave`; no‑op otherwise.
- Integrated in `route.ts` to append context before tool selection and
pass `mcpToolName` to `getTools`.
- Reliability: 5‑minute TTL cache, 5s timeout, and error handling; tests
cover success, no‑op, errors, timeouts, null/undefined, and cache hits.
- **Refactors**
- Switched source to `https://docs.hexclave.com/llms-full.txt`.
- Removed `docs-mintlify/llms-full.txt` and related generator code.
- Cache TTL now uses `performance.now()` for accurate expiry.
<sup>Written for commit
|
||
|
|
2220e89939
|
[codex] fix clickmap wildcard origin launch (#1606)
## Summary
Fixes the Clickmaps launcher for projects that use wildcard trusted
domains.
## What changed
- Split trusted domains into concrete launchable origins and wildcard
patterns.
- Stop rendering wildcard domains like `https://**.stack-auth.com` as
one-click clickmap targets, which previously became percent-encoded
origins such as `https://%2A%2A.stack-auth.com`.
- Keep an exact-origin launcher available so users can paste the real
page origin, for example `https://app.dev.stack-auth.com`.
- Add an informational alert explaining that wildcard domains need a
concrete origin.
- Add regression tests for wildcard filtering and HTTP(S)-only origin
normalization.
## Root cause
The dashboard used `new URL(baseUrl).origin` on wildcard trusted
domains. The URL parser percent-encodes `*`, so
`https://**.stack-auth.com` turned into `https://%2A%2A.stack-auth.com`.
The overlay token was then minted for an origin that is not the real
page origin, causing the overlay to reject the token.
## Validation
- `pnpm test run
'apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/analytics/clickmaps/clickmap-origins.test.ts'`
- `pnpm -C apps/dashboard exec eslint
'src/app/(main)/(protected)/projects/[projectId]/analytics/clickmaps/clickmap-origins.ts'
'src/app/(main)/(protected)/projects/[projectId]/analytics/clickmaps/clickmap-origins.test.ts'
'src/app/(main)/(protected)/projects/[projectId]/analytics/clickmaps/page-client.tsx'`
- `git diff --check`
Not run: full dashboard typecheck, because this checkout is missing
built package outputs such as `@hexclave/shared/dist` and repo
instructions say not to build packages from the agent.
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes the Clickmaps launcher for projects with wildcard trusted domains
by removing wildcard entries from one‑click targets and requiring an
exact HTTP(S) origin. Prevents percent-encoded origins and token
mismatches.
- **Bug Fixes**
- Split trusted domains into concrete origins vs wildcard patterns;
filter wildcards from launch targets and sort with shared stringCompare.
- Normalize HTTP(S) origins and reject wildcard or non-HTTP(S) input
when launching.
- Replace localhost-only input with an “Exact page origin” field and
place the “Show clickmap” button inline with the input.
- Add an inline hint under the origin input explaining wildcards need a
concrete origin; refine the empty-state copy for wildcard scenarios.
- Add tests for wildcard filtering, origin option generation, and origin
normalization.
<sup>Written for commit
|
||
|
|
681f10522a
|
Hide sub-apps from dashboard onboarding wizard (#1619)
## Summary
Sub-apps (apps with a `parentAppId`, e.g. clickmaps, session-replays,
fraud-protection) were showing up in the project onboarding
app-selection step. They shouldn't — they're automatically enabled when
their parent app is enabled.
```diff
- export const ONBOARDING_APP_IDS = ALL_APP_IDS.filter((appId) => ALL_APPS[appId].stage !== "alpha");
+ export const ONBOARDING_APP_IDS = ALL_APP_IDS.filter((appId) => ALL_APPS[appId].stage !== "alpha" && getParentAppId(appId) == null);
```
Link to Devin session:
https://app.devin.ai/sessions/9f88b9641eea41d0ab6a46f3554fd9cd
Requested by: @Developing-Gamer
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Hide sub-apps in the project onboarding app selection so only top-level
apps are shown. This prevents users from toggling features that are
auto-enabled by their parent apps.
- **Bug Fixes**
- Filtered `ONBOARDING_APP_IDS` to exclude apps with a parent via
`getParentAppId` (still skips `alpha` apps).
- Added a test to ensure sub-apps never appear in the selection list.
<sup>Written for commit
|
||
|
|
81068977ff
|
fix: update AI model selection matrix and custom dashboard generation (#1615)
## What
Refresh the AI model selection matrix and fix a few issues in custom
dashboard generation.
### Models (`apps/backend/src/lib/ai/models.ts`)
- Replace deprecated/placeholder model IDs with current ones:
- `smart/slow` authenticated → `openai/gpt-5.5` (was
`x-ai/grok-build-0.1`)
- `smart/fast` → `google/gemini-3.5-flash`
- `smartest` unauthenticated tiers → `z-ai/glm-5.2` /
`google/gemini-3.5-flash` (was `deepseek/deepseek-v4-flash`)
- `dumb` unauthenticated tiers → `nvidia/nemotron-3-super-120b-a12b`
### Email template rewrite
- Forward `x-stack-*` / `x-hexclave-*` headers from the caller through
the template-source rewrite route so the inner AI call
(`/ai/query/generate`) is authenticated and resolves to the
**authenticated** model tier instead of falling back to the
unauthenticated one.
- Lower rewrite quality to `dumb` / `slow` (sufficient for this task,
cheaper/faster).
### Custom dashboard
- Speed up generation: `smart`/**fast** instead of `smart`/slow (both
`create-dashboard-preview.tsx` and `chat-adapters.ts`).
- Pin `@babel/standalone` to `7.29.7` in the sandbox host (avoid
surprise breakage from `latest`).
- Disable analytics in generated dashboards.
### Misc
- Bump MCP RPC timeout 15s → 45s (`apps/skills/src/mcp-wrapper.ts`).
## Testing
- `pnpm typecheck` ✅
- `pnpm lint` ✅
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Refreshes the model selection matrix, forwards auth headers so template
rewrites use authenticated tiers, and speeds up custom dashboard
generation with a more stable sandbox.
- **Refactors**
- Update model IDs: `openai/gpt-5.5`, `google/gemini-3.5-flash`,
`z-ai/glm-5.2`, `nvidia/nemotron-3-super-120b-a12b`.
- Use `openai/gpt-5.5` for authenticated fast routes.
- Forward `x-stack-*` / `x-hexclave-*` headers; build via Map to avoid
prototype-pollution; inner generate call uses the authenticated tier.
- Lower email template rewrite quality to `dumb`/`slow`.
- Switch dashboard generation to `smart`/`fast` in
`create-dashboard-preview.tsx` and `chat-adapters.ts`.
- Disable analytics in generated dashboards.
- Bump MCP RPC timeout from 15s to 45s.
- **Dependencies**
- Pin `@babel/standalone` to `7.29.7` in the sandbox host.
<sup>Written for commit
|
||
|
|
d88e77c67b | User ID filter for email outbox | ||
|
|
70d90494bc | chore: update package versions | ||
|
|
9dad929447
|
fix: stale include-by-default price doesnt crash page (#1621)
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
### Summary of Changes
Some stale data in bulldozer causes a price validation error which
causes a 500. We let it fail softly
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes 500s in payments views by handling legacy product snapshots with
`prices: "include-by-default"` and other invalid price shapes. Stale
data now degrades gracefully, and we capture diagnostics instead of
crashing.
- **Bug Fixes**
- Normalize snapshot prices in `productToInlineProduct`: treat
`"include-by-default"` as `{}` and fall back to `{}` for any non-object;
capture errors for diagnostics.
- `productToInlineProduct` now accepts context (`productId`,
`customerType`, `customerId`); updated products and validate-code routes
to pass it.
- Added tests to verify price normalization and prevent response
validation failures.
<sup>Written for commit
|
||
|
|
4beba4942b | Speed up team creation | ||
|
|
c7036da485
|
feat: add Emails tab to User Detail page (#1616) | ||
|
|
cc68e36260 | Make UserButton render a glyph again when user is not signed in | ||
|
|
2cf2552803 | chore: update package versions | ||
|
|
ec0008d515 |
Aggressively deprecate app.urls.xyz & update docs to avoid it
Closes #1587 |
||
|
|
c50f1e64ed
|
Add 6/12/26 changelog entry (#1589) | ||
|
|
4546615713
|
feat: add custom OIDC provider support (team plan+ only) (#1594) | ||
|
|
010c114c49
|
fix: disable source maps in RDE dashboard build (#1611) | ||
|
|
7955ef2450 | chore: update package versions | ||
|
|
13e901f1bd | chore: update package versions | ||
|
|
fbb84b9e62 | Update reminders to tell AI to prefer /ask endpoint | ||
|
|
689b05fdaa | Make it clear there are more SDK packages | ||
|
|
c7ef9e9461
|
Dashboard Bar chart UI fix (#1602)
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
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/hexclave/hexclave/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes the page views bar hover highlight in the analytics chart by
replacing the clip-path overlay with per-bar `Cell` opacity. This
removes flicker and highlights only the hovered bar.
- **Bug Fixes**
- Removed `page-views-highlight-clip` and the extra hover `Bar`.
- Use `Cell` per bar to set `fillOpacity` (0.5 on hover, 0.18 otherwise;
0 when hidden).
- Keeps a single `Bar`, reducing DOM and avoiding clipping/offset
issues.
<sup>Written for commit
|
||
|
|
cf6a49d89c
|
Dashboard sidebar animation fix (#1601)
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/hexclave/hexclave/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes the project sidebar animation flicker by always applying
overflow-hidden to the animated container and only toggling h-0 when
collapsed. Expanding and collapsing sections now animate smoothly
without content popping.
<sup>Written for commit
|
||
|
|
ef27c98492 | Fix Apple OAuth behavior | ||
|
|
eabbc05a49 |
chore: update package versions
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
|
||
|
|
eeccf877e5 | Use Hexclave whenever possible | ||
|
|
47b9a3a431 | chore: update package versions | ||
|
|
5be2160021
|
fix: clearer error when changing email to one already used for auth (#1569) | ||
|
|
72456d3748
|
Update Next.js to latest minor/patch versions (#1592) | ||
|
|
e07c509f81 | chore: update package versions | ||
|
|
e93b7520c4
|
feat(analytics): add route analytics heatmaps (#1520)
## Summary Adds route analytics heatmaps, stacked on top of `codex/analytics-overview-filters` (#1496). - Heatmap API routes (`/analytics/heatmap`, internal heatmap + heatmap-token endpoints) - Signed heatmap token signing/verification lib + tests - Dashboard heatmaps page (client + route) - Dev-tool + event-tracker support for heatmap capture - ClickHouse migration support ## Demo https://app.devin.ai/attachments/49cd6a96-8962-46d9-b8fb-145746cc6dee/rec-c80ec66f-21a3-49fb-bfae-19195ce7b930-edited.mp4 ## Notes Base branch is `codex/analytics-overview-filters` so the diff shows only the heatmap changes. Will retarget to `dev` once the base PR lands. Link to Devin session: https://app.devin.ai/sessions/16f8adac29b948b38280c85418617fea Requested by: @mantrakp04 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Added clickmap overlay to analytics dashboard, enabling visual click heatmap analysis on live websites. * Enhanced analytics metrics with hourly breakdowns, bounce rates, and top regions/browsers/devices filtering. * **Bug Fixes** * Improved click event tracking accuracy and dead-click detection. * Fixed overlay z-index stacking for better visibility. * **Style** * Updated dashboard card padding and navigation button styling for consistency. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: mantra <mantra@stack-auth.com> Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
f38c9d85e7
|
Replace writeConfigObject with AI-aware updateConfigObject (#1537)
## Summary
Replaces `writeConfigObject` (destructive overwrite) with
`updateConfigObject` — an async, AI-aware updater that preserves
user-authored config structure (imports, external file references,
helpers).
**Dual-path approach:**
- **Fast path** (deterministic, no AI): plain static literal configs →
`override()` + in-memory validation + atomic write
- **Agent path** (custom structure): configs with `import x from
"./file.txt" with { type: "text" }` etc. → Claude agent edits the
external files in place, then validates
**Safety guarantees:**
- Snapshot/restore: config + all relative imports are captured before
the agent runs; rolled back on any failure
- In-memory validation on fast path (never write unvalidated bytes)
- Semantic check when config is evaluable; no-op detection + structural
check when it isn't
- Path traversal guard on imports (rejects `../` escapes)
- Agent isolation: `settingSources: []`, `strictMcpConfig: true`,
`CLAUDE_CODE_DISABLE_AUTO_MEMORY`, no Bash tool
- `scheduleSync` only fires after a successful update
- Bounded 120s timeout on agent runs (configurable via env var)
CI failures are preexisting on `dev`
(`ERR_PNPM_LOCKFILE_CONFIG_MISMATCH` from overrides move without
lockfile regen); this branch has zero lockfile changes vs dev.
Link to Devin session:
https://app.devin.ai/sessions/cc7409a357bc472ea19fbed065f1229f
Requested by: @mantrakp04
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Introduced partial configuration update functionality with validation
and automatic rollback on failures.
* Enhanced configuration management with support for more complex file
structures and external references.
* **Chores**
* Added Claude Agent SDK dependency for configuration update operations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Documentation
Docs for this feature were added in this branch:
- **New page**
`docs-mintlify/guides/going-further/local-development.mdx` — covers
`stack dev`, the development-environment flow, and how dashboard edits
are written back to the local config file (structure-preserving fast
path vs. assistant path, external `import … with { type: "text" }`
templates, validation + rollback). Added to `docs.json` nav; also fixes
the previously-broken `/guides/going-further/local-development` links
from `index.mdx` and `self-host.mdx`.
- **`docs-mintlify/guides/going-further/cli.mdx`** — added a `stack dev`
("Run a development environment") section.
- **Skill-site AI prompts** — filled in the `config-docs` and
`dashboard-instructions` placeholders under
`packages/stack-shared/src/ai/unified-prompts/skill-site-prompt-parts/`,
and added a structure-preserving note to the setup prompt.
- **`CHANGELOG.md`** — user-facing entry.
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: mantra <mantra@stack-auth.com>
|
||
|
|
3c89bb8c19
|
Hosted components redesigned (#1573)
## Summary Redesigns the hosted components app (`apps/hosted-components`) with a new Tailwind-based UI: rebuilt auth pages (sign-in, sign-up, magic link, forgot/reset password, MFA, email verification, team invitation, CLI auth confirm) and a full hosted Account Settings suite (profile, emails & auth, notifications, active sessions, API keys, payments, teams), with dark mode support. Also fixes found along the way: form error clearing in forgot-password/password-reset, `runAsynchronouslyWithAlert` for the notifications switch, a `CopyButton` DOM prop leak, a bogus mobile-session icon check, and imports the app stylesheet in the root route so the app's Tailwind styles actually apply. ## Before / after screenshots Captured on the local dev setup (`internal` project). Onboarding is not shown since it redirects without standalone UI in this setup. <details> <summary><b>Sign in</b></summary> | | Before | After | |---|---|---| | Light |  |  | | Dark |  |  | </details> <details> <summary><b>Sign up</b></summary> | | Before | After | |---|---|---| | Light |  |  | | Dark |  |  | </details> <details> <summary><b>Forgot password</b></summary> | | Before | After | |---|---|---| | Light |  |  | | Dark |  |  | </details> <details> <summary><b>Password reset</b></summary> | | Before | After | |---|---|---| | Light |  |  | | Dark |  |  | </details> <details> <summary><b>Email verification</b></summary> | | Before | After | |---|---|---| | Light |  |  | | Dark |  |  | </details> <details> <summary><b>MFA</b></summary> | | Before | After | |---|---|---| | Light |  |  | | Dark |  |  | </details> <details> <summary><b>Error</b></summary> | | Before | After | |---|---|---| | Light |  |  | | Dark |  |  | </details> <details> <summary><b>Team invitation</b></summary> | | Before | After | |---|---|---| | Light |  |  | | Dark |  |  | </details> <details> <summary><b>CLI auth confirm</b></summary> | | Before | After | |---|---|---| | Light |  |  | | Dark |  |  | </details> <details> <summary><b>Account settings — Profile</b></summary> | | Before | After | |---|---|---| | Light |  |  | | Dark |  |  | </details> <details> <summary><b>Account settings — Notifications</b></summary> | | Before | After | |---|---|---| | Light |  |  | | Dark |  |  | </details> <details> <summary><b>Account settings — Active sessions</b></summary> | | Before | After | |---|---|---| | Light |  |  | | Dark |  |  | </details> <details> <summary><b>Account settings — API keys</b></summary> | | Before | After | |---|---|---| | Light |  |  | | Dark |  |  | </details> <details> <summary><b>Account settings — Payments</b></summary> | | Before | After | |---|---|---| | Light |  |  | | Dark |  |  | </details> <details> <summary><b>Account settings — Emails & auth</b></summary> | | Before | After | |---|---|---| | Light |  |  | | Dark |  |  | </details> Link to Devin session: https://app.devin.ai/sessions/1d2380aa55694f2fb12ed96e200a32ad Requested by: @Developing-Gamer --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: armaan <armaan@stack-auth.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
7063aa2df7 | chore: update package versions | ||
|
|
6de253633f | chore: update package versions | ||
|
|
9b767cc35e
|
Implement loading state for purchase page and enhance styling (#1586)
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/hexclave/hexclave/blob/dev/CONTRIBUTING.md
-->
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Adds a skeleton loading state for the purchase flow and scopes
background styles to stop the first-paint flash across purchase views.
Improves perceived performance and keeps light/dark backgrounds
consistent.
- **New Features**
- Added skeleton `loading.tsx` for `/purchase/[code]` with responsive
placeholders.
- **Bug Fixes**
- Scoped `body` background with `:has([data-hexclave-purchase-page])`
for light/dark, and disabled `body::before` to prevent flash.
- Applied `data-hexclave-purchase-page` to the purchase page (including
invalid-code state) and return page to activate the scoped styles.
<sup>Written for commit
|
||
|
|
5eedb484e1 | chore: update package versions |