Commit Graph

200 Commits

Author SHA1 Message Date
BilalG1
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
2026-05-29 15:21:59 -07:00
Konsti Wohlwend
81de599605
Add background to README logo (#1523) 2026-05-29 14:05:58 -07:00
Konsti Wohlwend
7aafa8fd87
Fix Hexclave logo SVGs: convert wordmark text to outlined paths (#1517) 2026-05-28 17:53:56 -07:00
BilalG1
3d06e5e381
Rebuild README.md for the Hexclave rebrand (#1474)
## Summary

Rebuilds the project README from scratch for the Stack Auth → Hexclave
rebrand. The previous README was out of date. The README rewrite also
surfaced a few stale Stack-Auth references in adjacent docs, which are
fixed in the same PR.

### README

New structure:
- **Top section**: name, "The user infrastructure platform" tagline,
intro paragraph, links, and badges
- **Get started**: a single AI-agent setup prompt (`Read
skill.hexclave.com and help me setup hexclave in this project`)
- **What's included**: a catalog of the non-alpha apps (Authentication,
Teams, RBAC, API Keys, Payments, Emails, Analytics, Webhooks, Data
Vault, Launch Checklist), each with a logo, blurb, and screenshot
- **Contributing**: pointer to `CONTRIBUTING.md`, Discord, and the
security contact
- **Contributors**: restored at the bottom, now pointing at the correct
`hexclave/stack-auth` repo on contrib.rocks

Note: an explicit **SDKs** section was intentionally dropped for now —
the `@hexclave/next`, `@hexclave/react`, `@hexclave/js` packages aren't
yet published under that scope, and surfacing install instructions for
unpublished packages would just confuse landing users. The badges in the
header still call out the supported SDKs, and the setup prompt routes
users to docs. We'll add a dedicated SDKs section once the packages
exist.

### CONTRIBUTING.md & SECURITY.md

Both still referenced Stack Auth after the README rewrite. Updated:
- `CONTRIBUTING.md`: "Stack Auth" → "Hexclave", `discord.stack-auth.com`
→ `discord.hexclave.com`, `docs.stack-auth.com` → `docs.hexclave.com`,
`security@stack-auth.com` → `security@hexclave.com`
- `.github/SECURITY.md`: "Stack Auth" → "Hexclave",
`team@stack-auth.com` → `team@hexclave.com`, `security@stack-auth.com` →
`security@hexclave.com`

This keeps the disclosure flow consistent across the three docs.

### Markdown lint / a11y polish

- Added a `text` language tag to the bare fenced block under "Get
started" (markdownlint MD040)
- Added `alt=""` to the 10 inline heading logos (markdownlint MD045) —
empty alt is correct here because the heading text immediately to the
right already names the section, so the logo is decorative

## Open items

A few rebrand details still need confirmation; this PR assumes them and
uses them in copy:
- Domains assumed: `hexclave.com`, `docs.hexclave.com`,
`app.hexclave.com`, `discord.hexclave.com`, `security@hexclave.com`,
`team@hexclave.com`. Only `skill.hexclave.com` is confirmed.
- The `skill.hexclave.com` setup-prompt page needs to exist for the Get
started flow to work.
- License and Self-hosting sections were intentionally omitted; the
header badges were kept.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Documentation**
* Rebranded the project from "Stack Auth" to "Hexclave" with a new
streamlined README, hero section, and updated feature catalog
* Updated contribution guide with Hexclave-specific links, added Discord
coordination before starting work, and adjusted setup instructions
* Updated security policy and contact emails for vulnerability reporting
and consulting
* Refined table-of-contents workflow to target the contributing guide
only

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/hexclave/stack-auth/pull/1474?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: BilalG1 <BilalG1@users.noreply.github.com>
2026-05-27 09:51:07 -07:00
BilalG1
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>
2026-05-26 19:18:20 -07:00
BilalG1
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>
2026-05-23 17:24:55 -07:00
Konsti Wohlwend
6a8b45e6c5
fix: CI failures — Node 22, test timeouts, QEMU transaction timeout (#1479) 2026-05-22 20:24:13 -07:00
Konsti Wohlwend
1f0c27b644
fix: fix failing CI/CD on dev branch (#1473) 2026-05-22 16:25:57 -07:00
Konstantin Wohlwend
fe6f053e0e Update workflows 2026-05-21 16:22:04 -07:00
Konstantin Wohlwend
9794572cd6 Bump packages when pushing to main 2026-05-21 15:16:42 -07:00
Konsti Wohlwend
2e1a0d76e5
Pin all GitHub Actions to exact commit hashes (#1448) 2026-05-20 11:14:17 -07:00
Konstantin Wohlwend
d68631ea4f Update GitHub URL 2026-05-19 10:27:53 -07:00
BilalG1
024da3cacb
[Fix] freestyle-mock honors $PORT, drop server.listen string-patch (#1432)
## Summary

The multi-worker freestyle-mock rewrite
([#1430](https://github.com/hexclave/stack-auth/pull/1430)) hardcoded
`server.listen(8080)`, which collides with qstash inside the
local-emulator container. Supervisord sets `PORT=8180` for
freestyle-mock specifically to avoid this clash, but the new source
ignores `process.env.PORT`.

The local-emulator Dockerfile previously bridged this with a
`server.replace('server.listen(8080)', ...)` string-patch on the
embedded source. The new code is `server.listen(8080, () => { ... })` —
the literal `'server.listen(8080)'` substring no longer matches, so the
replace silently no-ops and freestyle-mock binds 8080. qstash then can't
start (`address already in use: 127.0.0.1:8080` → FATAL), the backend
(which depends on qstash) never comes up, and the emulator smoke test
times out.

Observed in [this
run](https://github.com/hexclave/stack-auth/actions/runs/25832479377):

```
smoke-test: FTL address already in use: 127.0.0.1:8080
smoke-test: WARN exited: qstash (exit status 1; not expected)
smoke-test: INFO gave up: qstash entered FATAL state, too many start retries too quickly
[603s] SMOKE TEST FAILED: backend /health?db=1 did not return 200 within 300s
```

## Changes

- `docker/dependencies/freestyle-mock/Dockerfile`: `server.listen(PORT)`
where `PORT = process.env.PORT || 8080`, plus the startup log reflects
the actual port.
- `docker/local-emulator/Dockerfile`: drop the now-redundant
string-replace for the listen call. The two remaining replaces
(`fs/promises` import + node_modules symlink) are unrelated and kept.

## Test plan

- [ ] QEMU emulator build workflow passes on this branch (smoke test
reaches healthy backend).
- [ ] Verify locally that supervisord's `PORT=8180` is honored by
freestyle-mock and qstash binds 8080 cleanly.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
  * Server listening port is now configurable via PORT (default 8080).
* Local emulator startup adjusted to better handle dependencies and
create a node_modules symlink for smoother local runs.
  * Seed/process transaction timeout increased to 90s for reliability.
* Local database statement timeout changed to 0 (no statement timeout).
* **CI**
  * Added step to enable and validate KVM access during emulator builds.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/hexclave/stack-auth/pull/1432)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-14 15:31:16 -07:00
Konstantin Wohlwend
e95ccdea8b Remove unused GitHub Action 2026-05-11 21:29:11 -07:00
Mantra
647883c7ac
Move MCP server into a standalone apps/mcp app (#1405)
## Summary

Splits the Stack Auth MCP server out of `apps/backend` and into a
dedicated Next.js app at `apps/mcp/`, served on port `:42` (suffixed via
`NEXT_PUBLIC_STACK_PORT_PREFIX`) and exposed in production at
`https://mcp.stack-auth.com/mcp`. The backend no longer carries the MCP
transport route; clients now point at the new host.

Base: `dev` → Head: `chore/move-mcp-to-a-sep-app`
Scope: 34 files, +1425 / −353

## What changed

- **New app** `apps/mcp/` — standalone Next.js + `@vercel/mcp-adapter`,
with:
- `src/app/api/internal/[transport]/route.ts` — MCP transport handler
(moved from backend)
- `src/app/mcp/route.ts`, `src/app/route.ts` — public landing + setup
page
  - `src/app/health/route.ts` — health check
  - `src/mcp-handler.ts`, `src/setup-page.ts`, `src/analytics.ts`
- **Backend** drops
`apps/backend/src/app/api/internal/[transport]/route.ts` (−105) — MCP
code is gone from the backend image.
- **Dashboard** install hint updated to point at
`https://mcp.stack-auth.com/mcp` (was `/`).
- **Dev launchpad** gets an MCP tile so the new service shows up
alongside the rest of the local stack.
- **CI** workflows (`db-migration-backwards-compatibility`,
`e2e-api-tests*`) start the MCP service in the background before running
tests.
- **Docs** (`docs-mintlify`, `docs/`) and `init-stack` / `init-prompt`
updated to reference the new URL.
- **E2E** `apps/e2e/tests/backend/endpoints/api/v1/internal/mcp.test.ts`
reworked to hit the new host; `helpers.ts` and env files gain an MCP
base-URL var.

## Visuals

### New `apps/mcp` setup page (`https://mcp.stack-auth.com/`)

The standalone app's root now serves a self-contained MCP setup guide
with per-client instructions (Cursor, VS Code, Codex, Claude Code,
Claude Desktop, Windsurf, ChatGPT, Gemini CLI):

![MCP setup
page](https://gist.githubusercontent.com/mantrakp04/892b45cb1b4e0d65d6c73a0c8771fe7d/raw/mcp-setup-page.png)

### Dev launchpad now lists the MCP service

New tile at port suffix `:42`, importance 2, alongside Backend /
Dashboard / Demo app:

![Dev launchpad with MCP
tile](https://gist.githubusercontent.com/mantrakp04/892b45cb1b4e0d65d6c73a0c8771fe7d/raw/launchpad-light-full.png)

## Notes for reviewers

- The MCP transport endpoint moved path: it was mounted under
`/api/internal/[transport]` in the backend; in the new app it's at the
same path but on the dedicated host. The public-facing URL is
`https://mcp.stack-auth.com/mcp`.
- `apps/mcp` ships its own PostHog analytics client (`src/analytics.ts`)
so the backend doesn't have to proxy events for it anymore.
- Port allocation: `${PORT_PREFIX}42` (default `8142` in dev). Picked to
fit the existing dev-launchpad importance-2 row.
- No DB migrations.

## Test plan

- [x] `apps/mcp` builds and `pnpm dev` serves on `:8142`
- [x] Dev launchpad renders the new MCP tile (screenshot above)
- [x] MCP setup page renders client tabs (screenshot above)
- [x] E2E `mcp.test.ts` updated to hit the new host
- [ ] CI green on `e2e-api-tests*` and
`db-migration-backwards-compatibility` workflows (they were touched to
start the MCP service)
- [ ] `init-stack` / `mcp.ts` install flow lands users on the new URL


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Standalone MCP app added with a public /mcp endpoint and health check.
  * MCP appears in the dev-launchpad apps list.

* **Documentation**
* MCP endpoint updated to https://mcp.stack-auth.com/mcp in all setup
guides and installer snippets.
* Setup page enhanced with detailed client install tabs and
instructions.

* **Chores**
  * MCP service integrated into CI/e2e workflows and local env configs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-07 15:22:44 -07:00
BilalG1
37ee5ec320
Fast-start local emulator via RAM snapshot + live secret rotation (#1340)
## Summary

`stack emulator start` now resumes a fully-warm VM snapshot instead of
cold-booting, bringing startup from 30–120s down to ~5–8s with
per-install secret rotation, or ~2.5s with rotation opt-out. The
snapshot is captured **locally on first `stack emulator pull`**, not
shipped from CI — QEMU migration state isn't portable across
accelerators (KVM/HVF/TCG) or `-cpu max` feature sets, so a CI-captured
snapshot couldn't resume reliably on arbitrary user hardware.

Also bundles a pile of CLI QoL fixes (progress bars, PR/run artifact
pulls, PR-build download, native-TS ISO writer replacing
`hdiutil`/`mkisofs`/`genisoimage` host dep, unit tests).

| Scenario | Before | After |
|---|---|---|
| Cold boot (no snapshot) | 30–120s | same, works as fallback |
| `stack emulator pull` (one-time, includes local snapshot capture) |
~30s download | ~30s download + ~1–3 min cold-boot capture |
| Snapshot resume, normal start | — | **~5–8s** |
| Snapshot resume, `EMULATOR_NO_ROTATION=1` | — | **~2.5s** |

Backend (`/health?db=1`) and dashboard (`/handler/sign-in`) return 200
on all paths. Two successive snapshot resumes produce different rotated
PCK/SSK/SAK/CRON_SECRET values per install.

## How it works

**Build (CI)** — `docker/local-emulator/qemu/build-image.sh`:

1. Cloud-init provisioning runs to completion (migrations, seed,
slim-image) producing `stack-emulator-<arch>.qcow2`.
2. Image is built with a topology compatible with later snapshot capture
(pinned SMP=4, phantom seed/bundle ISOs, STACKCFG runtime ISO mounted at
build time, qemu-guest-agent running, placeholder hex secrets baked in
under `STACK_EMULATOR_BUILD_SNAPSHOT=1`).
3. CI publishes **only the qcow2** — no `.savevm.zst` ships.

**Pull (user's machine)** —
`packages/stack-cli/src/commands/emulator.ts` + `run-emulator.sh
capture`:

1. `stack emulator pull` downloads the qcow2 with a progress bar (or
from a PR / workflow run via `--pr` / `--run`).
2. CLI invokes `run-emulator.sh capture`: cold-boots the qcow2 with a
matching device layout (phantom ISOs, fsdev, pcie-root-port, virtfs
detached — migration-incompatible), waits for backend+dashboard health,
then drives QMP: `stop` → set `mapped-ram` + `multifd` caps → `migrate
file:state.raw` → poll `query-migrate` → `quit`. Raw mapped-ram file is
zstd-compressed to `stack-emulator-<arch>.savevm.zst` in the images dir.
3. `--skip-snapshot` opts out (first `start` will then cold-boot).

**Runtime** — `run-emulator.sh start`:

1. Launch QEMU with `-incoming defer` when a `.savevm.zst` is present;
decompress on first use, keep the `.raw` cached for subsequent starts.
2. QMP: same `mapped-ram` + `multifd` caps → `migrate-incoming
file:<.raw>` → poll for `paused` → `cont`.
3. Generate fresh per-install secrets on the host; pipe them
base64-encoded through QGA `guest-exec input-data` →
`trigger-fast-rotate` in the guest → `docker exec -e … rotate-secrets`.
4. `rotate-secrets` in the container: validate keys (hex-only), targeted
`sed` on the placeholder PCK across built JS, `UPDATE ApiKeySet`,
`supervisorctl restart stack-app cron-jobs` (with
`stopasgroup`/`killasgroup` so the Node children actually die and
release their ports).
5. Poll backend+dashboard health; if anything fails, clean up and fall
back to cold boot transparently.

**Security model**: placeholder hex values are baked into the snapshot
(`00…ff` PCK, `00…ee` SSK, `00…dd` SAK, `00…cc` CRON_SECRET). They are
non-secret by construction. Real per-install secrets are generated at
each `emulator start` and never leave the host.

## CLI changes (`packages/stack-cli`)

- **`src/lib/iso.ts`** (new): native TypeScript ISO 9660 + Joliet
writer, replacing the host-side `hdiutil`/`mkisofs`/`genisoimage`
dependency for generating the STACKCFG runtime config disk. Unit tests
in `src/lib/iso.test.ts`.
- **`src/commands/emulator.ts`**:
- `pull`: streamed downloads with progress bar + ETA; `--pr <number>`
and `--run <id>` to pull from a PR build's CI artifacts (uses
`extract-zip` for the nested zip); `--skip-snapshot` to opt out of the
one-time local capture.
- `start` (existing, extended): auto-pulls AND auto-captures when no
image exists, so first-ever `start` is self-bootstrapping; emits
`STACK_EMULATOR_CLI_WROTE_ISO=1` so the shell helper skips its own ISO
regen (avoids the genisoimage host dep).
- `capture` (new, invoked by `pull` and the auto-pull path of `start`):
drives the local snapshot capture via `run-emulator.sh`.
- `status`, `stop`, `reset`, `list-releases`: preflight +
path-resolution tightening (`STACK_EMULATOR_HOME` → images/run dirs).
  - Unit tests in `src/commands/emulator.test.ts`.
- **`EMULATOR_NO_ROTATION=1`** env var skips the post-resume rotation
(intended for tests/CI where the placeholder secrets are fine — comes
with a loud warning).

## CI (`.github/workflows/qemu-emulator-build.yaml`)

- Builds **QEMU 10.2.2 from source** (cached), because
`mapped-ram`/`multifd` migration capabilities aren't available in the
distro's QEMU. Enables KVM on ubicloud runners so amd64 boots at
hardware speed.
- amd64 + arm64 both build on the same amd64 matrix
(`ubicloud-standard-8`); arm64 runs under cross-arch TCG (provisioning
only — boot/verify smoke test is amd64-only).
- Verification now runs through the CLI: `emulator start` → `emulator
status` → `emulator stop` against the freshly-built qcow2 (via
`STACK_EMULATOR_HOME` pointing at the workspace, so the CLI doesn't
silently auto-pull a prior release).
- Packages **only** the qcow2. No `.savevm.zst` upload / publish.
- Release notes updated.

## Key files

**Shell / guest:**
- `docker/local-emulator/qemu/build-image.sh` — snapshot-compatible
device topology + STACKCFG runtime ISO at build time
- `docker/local-emulator/qemu/run-emulator.sh` — `start`, `capture`,
`stop`, `reset`, `status`; `-incoming defer`, `.raw` cache, QGA-driven
rotation, cold-boot fallback
- `docker/local-emulator/qemu/common.sh` (new) — shared `qmp_session` +
`capture_vm_state` (factored out so build-image.sh and run-emulator.sh
share the capture path)
- `docker/local-emulator/qemu/cloud-init/emulator/user-data` —
placeholder secrets in snapshot mode, `wait-for-stack-ready`,
`trigger-fast-rotate`, qemu-guest-agent enabled
- `docker/local-emulator/rotate-secrets.sh` (new) — in-container
rotation (sed + UPDATE + supervisorctl)
- `docker/local-emulator/supervisord.conf` — `stopasgroup`/`killasgroup`
on `stack-app` and `cron-jobs`
- `docker/local-emulator/entrypoint.sh` — only mint CRON_SECRET if unset
(placeholder supplied in snapshot mode via --env-file)
- `docker/local-emulator/Dockerfile` — ships `rotate-secrets` to
`/usr/local/bin`
- `docker/server/entrypoint.sh` — source
`/run/stack-auth/rotated-secrets.env`; skip full-tree sentinel scan on
warm restarts via marker

**CLI:**
- `packages/stack-cli/src/lib/iso.ts` (new) + `iso.test.ts` (new)
- `packages/stack-cli/src/commands/emulator.ts` + `emulator.test.ts`
(new)
- `packages/stack-cli/vitest.config.ts` (new)

**CI:**
- `.github/workflows/qemu-emulator-build.yaml`

## Test plan

- [x] `docker/local-emulator/qemu/build-image.sh {amd64,arm64}` produces
`stack-emulator-<arch>.qcow2` with snapshot-compatible topology
- [x] `stack emulator pull` downloads qcow2 with progress, then captures
locally (~1–3 min) and writes `stack-emulator-<arch>.savevm.zst` in the
images dir
- [x] `stack emulator pull --skip-snapshot` stops after download
- [x] `stack emulator pull --pr <n>` / `--run <id>` pull from PR /
workflow run artifacts
- [x] `stack emulator start` on a fresh dir auto-pulls **and**
auto-captures, then starts; subsequent starts fast-resume in ~5–8s;
backend + dashboard return 200
- [x] `EMULATOR_NO_ROTATION=1 stack emulator start` completes in ~2.5s;
backend + dashboard return 200 with warning printed
- [x] Two consecutive `emulator start` invocations produce different PCK
values in the internal `ApiKeySet` row
- [x] `stack emulator status` / `stop` / `reset` resolve paths from
`STACK_EMULATOR_HOME`
- [x] Verified end-to-end on arm64 macOS under HVF (capture ~50s,
fast-resume ~6.5s)
- [x] `pnpm lint` and `pnpm typecheck` pass; stack-cli unit tests (iso +
emulator) pass
- [ ] CI green on this PR (qemu-emulator-build matrix, smoke test)
- [ ] `gh release download emulator-<branch>-latest` contains only
`stack-emulator-<arch>.qcow2` once this PR merges and publish runs

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Snapshot fast-start/resume with optional warm-snapshot assets, runtime
ISO generation, and a cached QEMU build to speed emulator setup.
* CLI: streamed artifact downloads with progress, improved release/asset
handling, stronger preflight checks, and start/status/stop emulator
commands.
* Automated secret rotation and ability to apply rotated secrets at
container startup; supervisor control socket enabled.

* **Bug Fixes**
* More robust start/stop/resume flows with automatic fallback to cold
boot and improved process-group shutdown behavior.

* **Tests**
  * New tests for CLI utilities and ISO image generation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-20 14:24:49 -07:00
aadesh18
5341371782
LLM MCP Flow (#1321)
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
Mirror main branch to main-mirror-for-wdb / lint_and_build (push) Has been cancelled
Publish npm packages / publish (push) Has been cancelled
Publish Swift SDK to prerelease repo / publish (push) Has been cancelled
Sync Main to Dev / sync-commits (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/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Automated AI QA review pipeline and human-verified knowledge base
consulted first
* Internal MCP review tool: call log viewer, conversation replay,
add/edit/publish Q&A, knowledge editor, and analytics
  * Docs search now preserves follow-up conversation context

* **Documentation**
  * Added “Ask DeepWiki” badge to README

* **Chores**
* Added local SpacetimeDB background service and internal-tool app
scaffolding
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: mantrakp04 <mantrakp@gmail.com>
Co-authored-by: Mantra <87142457+mantrakp04@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Konsti Wohlwend <n2d4xc@gmail.com>
2026-04-15 17:57:08 +00:00
Konstantin Wohlwend
c5436be6ac Skip setup tests on non-dev branches 2026-04-15 10:21:26 -07:00
BilalG1
88d3317b22
local emulator security and features fixes (#1247)
<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

* **New Features**
* Added Stripe, OAuth, and Freestyle mock services to the local emulator
* Introduced `emulator run` CLI command to execute applications with
emulator credentials automatically injected
  * Enhanced credential management for local development

* **Improvements**
  * Improved ARM64 QEMU emulation with cross-architecture support
  * Better error detection and logging during emulator provisioning
  * Added example middleware configuration with authentication support
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-14 15:36:24 -07:00
BilalG1
5399142db9
local emulator build improvements (#1330)
… V8 --jitless

2.6 GB to 1.3 GB final image

Flip arm64 matrix back to ubicloud-standard-8 so both arches share one
runner fleet. Cross-arch TCG on an amd64 host previously SIGTRAP'd in
migrations because V8's JIT emitted arm64 instructions that QEMU's
cross-arch translator mis-handled; pair the existing -cpu cortex-a72
fallback with NODE_OPTIONS=--jitless on the migration docker exec to
force V8 to stay on the interpreter. Does not affect amd64 migrations
(KVM, no TCG).

<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Optimized emulator images with binary stripping, compression, and
preservation of standalone runtime dependencies.
* Improved multi-architecture build matrix, added optional KVM
detection/fallback, and gated certain emulator runtime steps for arm64.
* Enhanced build scripts to generate and include env files and persist
richer logs and artifacts.

* **New Features**
* Centralized provision entrypoint to streamline install → migrations →
slimming sequence.

* **Tests**
  * Added a fast QEMU serial boot test for architecture validation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-13 19:21:02 -07:00
Konstantin Wohlwend
c46767f4e8 Retry setup tests on non-staging branches to prevent flakeyness 2026-04-13 14:32:49 -07:00
Mantra
bb277d33c9
Backend fallback (cloud run) (#1306)
- Added support for `@opentelemetry/sdk-node` in the backend.
- Updated various dependencies including AWS SDK and OpenTelemetry
packages.
- Implemented graceful shutdown handling for non-Vercel runtimes in
`prisma-client.tsx`.
- Enhanced AWS credentials retrieval to support GCP Workload Identity
Federation.
- Introduced a Dockerfile for Cloud Run deployment, optimizing the
backend build process.
- Updated `.gitignore` to include Terraform runtime files and secrets.

This commit improves the backend's observability and deployment
flexibility, particularly for Cloud Run environments.

<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* OpenTelemetry observability with dynamic provider selection per
deployment.
  * Cloud Run trusted-proxy support for accurate client IP handling.
  * Graceful shutdown that waits for in-flight background work.
* New background-task handling to improve async webhook/email delivery
reliability.
* AWS credential providers added (Vercel OIDC & GCP Workload Identity
Federation).
  * Dockerized backend image for Cloud Run / self-host deployments.

* **Chores**
  * Updated dependencies for OpenTelemetry and AWS SDK support.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Konstantin Wohlwend <n2d4xc@gmail.com>
2026-04-11 00:57:37 +00:00
Konstantin Wohlwend
71f96ee221 Remove restart-dev-and-test workflows 2026-04-10 15:16:50 -07:00
Konstantin Wohlwend
452690f6d7 Revert "Make restart-dev-and-test save backend logs"
This reverts commit 0ebca10091.
2026-04-10 15:15:54 -07:00
Konstantin Wohlwend
0ebca10091 Make restart-dev-and-test save backend logs 2026-04-10 10:57:11 -07:00
BilalG1
9e342da0f2
Fix cron jobs using dev env instead of test env in CI workflows (#1319)
The custom-base-port and db-migration-backwards-compatibility workflows
were running cron jobs with `with-env:dev` instead of `with-env:test`,
causing ClickHouse sync mismatches in verify-data-integrity.

<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Streamlined CI test workflows to standardize background cron job
startup for more consistent test runs.
* **Tests**
* Improved end-to-end test reliability by aligning background process
behavior across suites.
* **Bug Fixes**
* Enhanced data verification reliability by ensuring external database
sync before integrity checks and tightening comparison ordering for
certain records, reducing false mismatch detections.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-09 21:27:18 -07:00
Konsti Wohlwend
d6c067972d
Replace npx with pnpm exec (#1300) 2026-04-08 17:08:55 -07:00
Bilal Godil
e8428f57c0 pin node version to 24 to fix mintlify lint issue on lint-and-build gh action 2026-04-07 10:11:57 -07:00
Mantra
ce49eae155
emu with a q stuff (#1266)
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
Lint & build / lint_and_build (latest) (push) Has been cancelled
Dev Environment Test With Custom Base Port / restart-dev-and-test-with-custom-base-port (push) Has been cancelled
Dev Environment Test / restart-dev-and-test (push) Has been cancelled
Run setup tests with custom base port / setup-tests-with-custom-base-port (push) Has been cancelled
Run setup tests / setup-tests (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
commit 5d43722575b826a8ed8dbb6b828f48eae4bca02c
Author: mantrakp04 <mantrakp@gmail.com>
Date:   Wed Mar 18 12:27:01 2026 -0700

    Add QEMU emulator snapshot functionality and reset command

- Introduced a new `emulator-qemu:reset` command in package.json to
clear snapshots and force a fresh boot of the emulator.
- Enhanced the `run-emulator.sh` script to support saving and restoring
snapshots, significantly reducing restart time from ~62s to ~4s.
- Implemented logic to check for existing snapshots and restore them
during startup, improving the emulator's efficiency.
- Updated documentation in CLAUDE-KNOWLEDGE.md to explain the new
snapshot restore process and its benefits.

These changes enhance the QEMU emulator's performance and usability for
developers, providing a more efficient workflow during development.

commit 3877445bdd83cb8690da18c8520bf260d2795172
Author: mantrakp04 <mantrakp@gmail.com>
Date:   Wed Mar 18 11:55:18 2026 -0700

    Enhance QEMU emulator performance and configuration management

- Added optimizations to the QEMU emulator's app container startup
process, reducing startup time from ~92s to ~62s by using qcow2 backing
files and setting the working directory to /app.
- Updated the build-image.sh script to conditionally wait for background
processes, improving robustness.
- Modified the run-emulator.sh script to create the disk image using
qcow2 format instead of copying, enhancing efficiency.
- Adjusted the cloud-init user-data to set STACK_RUNTIME_WORK_DIR to
/app, streamlining file operations during container initialization.
- Improved the entrypoint script to avoid unnecessary file copying when
the working directory is set to /app.

These changes significantly enhance the performance and usability of the
QEMU emulator for developers.

commit e0b86d3f1d5c08e46d0d343bc632e2a8c5777845
Author: mantrakp04 <mantrakp@gmail.com>
Date:   Wed Mar 18 11:07:55 2026 -0700

Refactor local emulator configuration management and enhance Docker
setup

- Removed redundant comments and improved code clarity in the local
emulator's route handling.
- Streamlined the Dockerfile and docker-compose.yaml for better
readability and maintenance.
- Updated entrypoint and initialization scripts to enhance service
startup processes.
- Introduced a new common script for QEMU emulator to centralize
architecture detection and firmware handling.
- Enhanced error handling in the host file bridge for improved
robustness.
    - Removed obsolete country code utilities to clean up the codebase.

These changes significantly improve the local emulator's configuration
management and overall setup experience for developers.

commit 4fb0f93c6cc4f749a14acf0228c261e180875609
Author: mantrakp04 <mantrakp@gmail.com>
Date:   Wed Mar 18 10:24:53 2026 -0700

Implement local emulator file bridge for enhanced configuration
management

- Introduced a new host file bridge to facilitate reading and writing
configuration files between the local emulator and the host system.
- Refactored the local-emulator module to utilize the file bridge for
file operations, improving error handling and response validation.
- Added tests to ensure the file bridge functionality works as expected,
including handling of non-existent files and writing configurations.
- Updated the run-emulator script to start the file bridge
automatically, ensuring seamless integration during emulator startup.
- Enhanced documentation to reflect the new file bridge capabilities and
usage instructions.

These changes significantly improve the local emulator's ability to
manage configuration files, enhancing the development experience.

commit 3d18a7ce5bbf00a62a40a3f48f27856e79ecc62f
Author: mantrakp04 <mantrakp@gmail.com>
Date:   Tue Mar 17 22:36:46 2026 -0700

    Refactor QEMU local emulator setup and enhance app bundle handling

- Introduced a new script for packaging Docker images into a compressed
app bundle, improving the emulator's deployment process.
- Updated build-image.sh to create a runtime configuration ISO, ensuring
better management of environment settings.
- Enhanced cloud-init user-data scripts for both dev-server and deps
guests, streamlining service setup and configuration.
- Improved the run-emulator.sh script to facilitate better handling of
runtime configurations and dependencies.
- Adjusted the .gitignore to include .DS_Store and removed obsolete
entries, cleaning up the repository.

These changes significantly enhance the local emulator's functionality
and reliability for developers.

commit 8a35fb1ce79898d73e2259e256c11b6fd9b0a584
Author: mantrakp04 <mantrakp@gmail.com>
Date:   Tue Mar 17 21:52:24 2026 -0700

    Enhance local emulator functionality and configuration

- Updated package.json to improve the start-emulator command, providing
clearer dashboard and backend URLs.
- Added a new wait-until-emulator-is-ready command to ensure the
emulator is fully operational before proceeding.
- Refactored the local-emulator project route to streamline file
existence checks and default config creation.
- Enhanced user guidance in the dashboard for local Stack config file
handling.
- Updated tests to reflect changes in config file handling, ensuring
non-existent files are created with default settings.
- Improved Docker configurations for the local emulator, including new
environment variables and service dependencies.

These changes significantly enhance the local development experience and
emulator reliability.

commit 3910ed4bc40bbb37340c1c316c24c2826ba372bd
Author: mantrakp04 <mantrakp@gmail.com>
Date:   Tue Mar 17 19:59:36 2026 -0700

    Remove unused stash-0.patch file to clean up the repository.

commit 74146d974458037a7a9590120a524629a1a6a162
Author: mantrakp04 <mantrakp@gmail.com>
Date:   Tue Mar 17 19:58:46 2026 -0700

Enhance QEMU local emulator with app bundle support and runtime
configuration

- Introduced a new script to package the backend and dashboard assets
into a standalone app bundle for the QEMU emulator.
- Updated the build-image.sh script to create an ISO containing the app
bundle, ensuring the guest image includes the full runtime.
- Modified cloud-init user-data to handle the new app bundle and runtime
configuration, improving the setup process for local development.
- Enhanced the run-emulator.sh script to prepare and mount the runtime
configuration ISO, facilitating better environment management for the
emulator.
- Updated the user-data to include necessary environment variables for
the stack application, ensuring seamless integration during startup.

These changes significantly improve the local emulator's functionality
and ease of use for developers.

commit 9e865a1cf524398bc58f00e0836278775c4ae936
Author: mantrakp04 <mantrakp@gmail.com>
Date:   Tue Mar 17 16:50:45 2026 -0700

    Enhance local emulator setup with new services and configurations

- Added Docker support for a local emulator, integrating PostgreSQL,
Redis, Inbucket, Svix, ClickHouse, MinIO, and QStash.
- Introduced new scripts for managing the emulator lifecycle, including
build and run commands.
- Implemented cloud-init provisioning for automatic service setup on
first boot.
- Updated package.json with new commands for emulator management and
added dotenv-cli for environment variable management.
    - Added tests for OAuth authorization flow to return JSON responses.
    - Included configuration files for ClickHouse and user management.

This commit significantly improves the local development experience by
providing a comprehensive emulator environment.

<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

* **New Features**
* Introduced a local QEMU-based emulator for development with bundled
services (PostgreSQL, Redis, ClickHouse, MinIO, Inbucket, Svix, QStash).
* Added CLI commands to manage the emulator (start, stop, reset, status,
pull images).
  * Added emulator status dashboard to monitor service health.
  * Introduced new configuration system via `stack.config.ts`.

* **Tests**
  * Added configuration read/write tests for the emulator.
  * Added emulator CLI validation tests.

* **Documentation**
  * Added emulator setup and usage guide.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-04 00:33:52 +00:00
Konstantin Wohlwend
8c4951fc0a Only run setup wizard in E2E tests 2026-03-31 09:03:35 -07:00
Bilal Godil
a354590321 stack-cli npm publish 2026-03-13 09:26:12 -07:00
BilalG1
66adb4e50f
Local emulator base (#1233)
<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Provision local-emulator projects from a local config file and return
emulator credentials via a new internal endpoint.
* Dashboard: "Open config file" flow to open local projects and refresh
owned projects.

* **Changes**
* Branch config can prefer/read/write local files for emulator projects.
* Environment config updates/resets are blocked for local-emulator
projects.
* Dashboard UI shows read-only notices and disables project creation in
emulator mode.
* Added DB mapping and a standard env flag to identify local-emulator
projects.

* **Tests**
  * New E2E tests covering provisioning and config restrictions.

* **Chores**
* Removed legacy emulator docs and compose; added CI workflow for
local-emulator E2E runs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Konstantin Wohlwend <n2d4xc@gmail.com>
2026-03-10 15:15:06 -07:00
Konsti Wohlwend
8052a2be62
"Require publishable client key" toggle (#1158)
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 / 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
Lint & build / lint_and_build (latest) (push) Has been cancelled
Dev Environment Test With Custom Base Port / restart-dev-and-test-with-custom-base-port (push) Has been cancelled
Dev Environment Test / restart-dev-and-test (push) Has been cancelled
Run setup tests with custom base port / setup-tests-with-custom-base-port (push) Has been cancelled
Run setup tests / setup-tests (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/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **High Risk**
> Touches authentication and OAuth token/authorize flows and changes how
client requests are validated, so regressions could cause widespread
login/client-access failures. Also includes a data migration that alters
effective security posture for existing projects.
> 
> **Overview**
> Adds a **project-level toggle**
(`project.requirePublishableClientKey`) to control whether client
requests/OAuth flows must include a publishable client key, including a
DB migration that backfills existing projects to require it.
> 
> Backend auth now treats the publishable client key as *optional when
allowed*, introducing a public sentinel (`__stack_public_client__`) and
returning a new specific error
(`PUBLISHABLE_CLIENT_KEY_REQUIRED_FOR_PROJECT`) across smart request
auth + OAuth `authorize`/`callback`/`token` endpoints.
> 
> Dashboard and SDKs update key generation/display and request
construction to handle missing publishable keys, expose an advanced
toggle on the Project Keys page, and extend internal config overrides to
support a new `project` level; E2E/tests and schema fuzzing are expanded
accordingly, and CI adds a forward-compat migration check job when
back-compat fails.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5d06c08613. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Project-level config to require publishable client keys; migration
applied to existing projects.

* **Improvements**
* Auth flows now support optional publishable client keys with explicit
validation and a sentinel for keyless OAuth.
* Dashboard/UI and SDKs handle publishable keys as optional and
conditionally show/generate them.
  * Admin/client APIs extended to manage project-level overrides.

* **Bug Fixes**
  * Key validation behavior aligned with project config.

* **Tests**
* Expanded E2E and unit tests covering optional/required publishable-key
scenarios.

* **Documentation**
* Spec and knowledge docs updated to describe the sentinel and config
behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-19 10:23:16 -08:00
BilalG1
907a98320a
Clickhouse sync fixing (#1198)
<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->
2026-02-16 11:30:38 -08:00
BilalG1
d09a180dfe
clickhouse user sync (#1159)
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 migrations are backwards-compatible / 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 / 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
Lint & build / lint_and_build (latest) (push) Has been cancelled
Dev Environment Test With Custom Base Port / restart-dev-and-test-with-custom-base-port (push) Has been cancelled
Dev Environment Test / restart-dev-and-test (push) Has been cancelled
Run setup tests with custom base port / setup-tests-with-custom-base-port (push) Has been cancelled
Run setup tests / setup-tests (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
DB migrations are backwards-compatible / Test migrations with ${{ needs.check-migrations-changed.outputs.base_branch }} branch code (push) Has been cancelled
DB migrations are backwards-compatible / No migration changes (skipped) (push) Has been cancelled
<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Real-time AI search with project-scoped analytics and dynamic query
execution; streaming AI responses replace the placeholder flow.
* External DB sync adds ClickHouse support: users sync, sync metadata
tracking, tenancy-aware status, and per-mapping throttling.
* AI assistant UI shows expandable tool-invocation results and streams
via the real AI pipeline.

* **Chores**
* Dashboard dependencies and workspace exclusions updated; development
OpenAI env var added; editor config flag toggled.

* **Tests**
* E2E coverage extended to validate ClickHouse user sync and analytics
queries.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: aadesh18 <110230993+aadesh18@users.noreply.github.com>
Co-authored-by: Konsti Wohlwend <n2d4xc@gmail.com>
2026-02-12 16:52:20 -08:00
Konsti Wohlwend
adb14f1635
[Refactor] Improve CI Run Times by Reducing Test Flakiness and Speeding up Test Suite (#1166) 2026-02-10 19:43:10 -08:00
aadesh18
2055d98dea
External db sync (#1036)
<img width="1920" height="969" alt="Screenshot 2026-02-04 at 9 47 16 AM"
src="https://github.com/user-attachments/assets/d7d0cd04-0051-4fc4-b857-e6f87ee97a59"
/>

**This PR revolves around the following components**
1. Sequencer - sequences the updates in the internal db
2. Poller - polls for the latest updates to sync with the external db
3. Outgoing Request Handler - essentially a trigger that can make http
requests based on a change in the internal db
4. Sync Engine - syncs with the latest changes from the internal db to
the external db

**What has been done**
- Added a global sequence id for ProjectUser, ContactChannel and
DeletedRow.
- Added the deletedRow table to keep track of the rows that were deleted
across ProjectUser and ContactChannel.
- Added the OutgoingRequest table to keep track of the outgoing requests
- Added function for the sequencer to call to sequence updates
- Added a sequencer that sequences all the changes in the internal db
every 50 ms
- Added a poller that polls for the latest changes in the internal db
every 50 ms, and adds to a queue
- Added a Vercel cron that calls sequencer and poller every minute
- Added a queue that fulfills the outgoing requests by making http calls
(for external db sync, it calls the sync engine endpoint)
- Added a sync engine that uses the defined sql mapping query in the
user's schema to pull in the changes for the user, and sync them with
the external db
- Added tests to test out each functionality


**How to review this PR:**
1. Review the migrations (sequence id, deletedRow, triggers, backlog
sync) (all files created under the migrations folder)
2. Review sequencer
3. Review poller
4. Review the changes in schema
5. Review sync-engine (the function, and it's helper file)
6. Review the schema changes, and query mappings
7. Review the tests (basic, advanced and race, along with the helper
file)
8. Review the changes made in Dockerfile to support local testing using
the postgres docker

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Introduces a cron-driven external DB sync pipeline with global
sequencing, internal poller and webhook sync engine, new DB
tables/functions, config schema/mappings, and comprehensive e2e tests.
> 
> - **Database (Prisma/Migrations)**:
> - Add global sequence (`global_seq_id`) and
`sequenceId`/`shouldUpdateSequenceId` to `ProjectUser`,
`ContactChannel`, `DeletedRow` with partial indexes.
> - Create `DeletedRow` (capture deletes) and `OutgoingRequest` (queue)
tables; add unique/indexes.
> - Add triggers/functions: `log_deleted_row`,
`reset_sequence_id_on_update`, `backfill_null_sequence_ids`,
`enqueue_tenant_sync`.
> - **Backend/API**:
> - New internal routes: `GET
/api/latest/internal/external-db-sync/sequencer`, `GET /poller`, `POST
/sync-engine` (Upstash-verified) for sync orchestration.
> - Add cron wiring: `vercel.json` schedules and local
`scripts/run-cron-jobs.ts`; start in dev via `dev` script.
> - Tweak route handler (remove noisy logging) without behavior change.
> - **Sync Engine**:
> - Implement `src/lib/external-db-sync.ts` to read tenant mappings and
upsert to external Postgres (schema bootstrap, param checks,
sequencing).
> - Add default mappings `DEFAULT_DB_SYNC_MAPPINGS` and config schema
`dbSync.externalDatabases` in shared config.
> - **Testing/Infra**:
> - Add extensive e2e tests (basics, advanced, race conditions) for
sequencing, idempotency, deletes, pagination, multi-mapping, and
permissions.
> - Docker compose: add `external-db-test` Postgres for tests; e2e deps
for `pg` types.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3f2a8efcfb. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* External PostgreSQL sync: automatic, batched replication with
mappings, resume/idempotency, and on-demand enqueueing.

* **Admin UI**
* Real-time External DB Sync dashboard and status API showing
per-mapping backlog, sequencer/poller/sync-engine telemetry, and fusebox
controls.

* **Tests**
* Large e2e suite: basic, advanced, race, high-volume tests and test
utilities for external DB sync.

* **Chores**
* DB migrations, CI/workflow updates, background cron runner and
local/dev test support.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Konsti Wohlwend <n2d4xc@gmail.com>
Co-authored-by: Bilal Godil <bg2002@gmail.com>
2026-02-05 12:04:31 -08:00
Konsti Wohlwend
7a35751f8e
Sign up rules (#1138)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> **High Risk**
> Touches core sign-up/auth flows and user restriction semantics
(including new DB constraints) and introduces dynamic rule
evaluation/logging; misconfiguration or CEL/parser bugs could block
sign-ups or incorrectly restrict users.
> 
> **Overview**
> Introduces **CEL-based sign-up rules** (config-driven) that are
evaluated during password/OTP/OAuth sign-ups and anonymous upgrades;
matching rules can reject sign-ups or mark users as admin-restricted,
and triggers are logged for analytics.
> 
> Extends `ProjectUser` with `restrictedByAdmin` plus public/private
restriction details, updates restriction computation/filtering, and
exposes these fields via user CRUD (including validation + DB constraint
enforcing consistency when unrestricted).
> 
> Adds a new dashboard **Sign-up Rules** page with a visual condition
builder (CEL <-> visual tree), drag-reorder by priority, per-rule 48h
sparkline analytics via a new hidden internal endpoint, and adds
user-page UI to view/edit manual restrictions. Also refactors ClickHouse
client initialization to require env vars (removing
`isClickhouseConfigured` checks) and adjusts CI container startup wait
time.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2141e689e8c1b72303b805e9234f996010d0880. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Sign-up Rules: visual rule builder, in-project CRUD with drag-reorder,
per-rule analytics, backend evaluation, and admin UI.
* Admin user restrictions: dashboard controls, banners/status,
public/private admin details surfaced in user views.

* **APIs & Schema**
* Config and user schemas extended; new SignUpRejected error and sign-up
rule types added.

* **Tests**
* Extensive unit and E2E coverage for rules, parser, evaluator,
analytics, and restricted-user flows.

* **Docs**
  * Editorial guidance added to AGENTS.md.

* **Chores**
* DB statement timeout, updated clean script, minor dependency
additions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-03 11:08:24 -08:00
BilalG1
7b5cf4f042
fix analytics queries (#1141)
<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Improvements**
* Added automatic retry with stricter result validation and clearer
error handling for query profiling to improve reliability.

* **Chores**
* CI workflows updated to use larger runner instances (upgraded runner
size across relevant jobs).

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-29 10:21:58 -08:00
Konstantin Wohlwend
4c22b37fdf --no-bail for verify-data-integrity script 2026-01-28 13:53:28 -08:00
BilalG1
484c3a6332
clickhouse setup (#1032) 2026-01-28 09:12:33 -08:00
Aman Ganapathy
c8694c7ff5
[Fix] [Feat] Update OAuth Sign-In and Get Token Functions to Work (#1130)
### Summary of Changes

Previously, on the Swift SDK, the `signInWithOAuth` function wasn't
working. In this PR, we fix it by having the `getOAuthUrl` function to
actually redirect correctly. Note that to do so, we updated the
`validRedirectUrl` check on the backend to accept app native redirects
(from our new trusted url scheme). Another thing to note is that we
added functionality to the `TokenStore` abstraction to conditionally
refresh the access token that the user is trying to fetch if it is
expired/close to expiring if possible. `getOAuthUrl` will attempt to get
a valid access token, and thus will rely on our algorithm documented in
`utilities.md`.

The specs serve as the source of truth.

We go further and implement Apple Native sign in. To do so, we have it
hit a new route on the backend and verify the `jwtToken` retrieved by
the sdk against an Apple-provided set of `jwks`. We use jose to do so,
in line with the rest of the codebase.

We take this opportunity to refactor the oauth provider route owing to
the amount of duplicated logic. Additionally, to enable the apple sign
in, users will have to update the Apple authentication method modal on
the dashboard and add accepted bundle ids. These are identifiers for
projects, and we will check the `JWT` on the backend to make sure the
audience is set to an accepted bundleId.

We also update the Apple modal to be more informative.

### Using the new Features

To use the Apple native sign in, users will have to 1) sign up with an
apple developer account, 2) set up their bundleids for their projects by
connecting them to the apple developer account, 3) update the Stack-Auth
Authentication Methods dashboard apple modal with the relevant fields.
Then, trying to sign in with apple with our Swift SDK will use the apple
native sign in.

### UI Changes

Renamed the fields in the apple modal. Added a new field for bundle ids.
See below.


https://github.com/user-attachments/assets/0e760c0e-3198-4818-ac7f-4900d7a125bb



Co-authored-by: Konstantin Wohlwend <n2d4xc@gmail.com>
2026-01-28 02:17:27 +00:00
Konstantin Wohlwend
3bb31badcd Fix env_to_branch migration 2026-01-23 17:17:43 -08:00
Konstantin Wohlwend
70ead41121 Clean up branch config overrides after completion 2026-01-23 16:47:19 -08:00
Konstantin Wohlwend
15b5336258 More stringent db migration backwards compatibility check 2026-01-23 12:41:59 -08:00
Konstantin Wohlwend
f97ad9ac3f Remove Hello World workflow 2026-01-22 10:25:39 -08:00
Konstantin Wohlwend
20ac0bff8a Hello World workflow 2026-01-22 10:22:44 -08:00
Konstantin Wohlwend
2b98fd2617 Don't run Freestyle prod tests in parallel 2026-01-21 11:59:15 -08:00
Konstantin Wohlwend
7c85d36c56 npm publish action 2026-01-12 15:41:41 -08:00
Konstantin Wohlwend
20f435fb6d Delete Claude Code review 2026-01-11 17:39:59 -08:00