Commit Graph

3432 Commits

Author SHA1 Message Date
Konstantin Wohlwend
3e53da8fce OAuth improvements 2026-06-25 14:40:15 -07:00
github-actions[bot]
c749cf2b62 chore: update package versions 2026-06-25 19:11:40 +00:00
Konstantin Wohlwend
36f9913a55 Update clean script to include nex-development-environment folder 2026-06-25 11:01:44 -07:00
Armaan Jain
81723c3d55
Usage page performance improvements (#1650)
<!--

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
Speed up the Usage page by aggregating metered usage across owned
projects/tenancies with fewer queries and new indexes. Adds E2E tests to
verify team-owned rollups and calendar‑month windows.

- **Performance**
- Added concurrent indexes for `EmailOutbox(tenancyId,
startedSendingAt)` and `SessionReplay(tenancyId, startedAt)`; updated
Prisma schema.
- Group tenancies by (DB client, schema) and run one SQL per group that
counts both emails and session replays; uses `mapWithConcurrency` from
`@hexclave/shared` (concurrency 4, aborts on first error).
- Added helpers `getOwnedProjectAndTenancyIdsForBillingTeam` and
`getNonAnonymousUserCountForTenancies`; made `mapWithConcurrency`
null‑safe with bounds checks.

- **Tests**
- Added E2E tests for the internal plan-usage endpoint covering
team-owned rollups, calendar‑month boundaries, and zero‑usage cases.
- Added unit tests for ownership scope resolution and non‑anonymous user
counting.

<sup>Written for commit 5d6098006c.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1650?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->

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

* **Performance Improvements**
* Improved plan usage rollups by aggregating metered emails and session
replays together across an owned scope.
* Added database indexes to speed up time-window metering lookups for
email outbox and session replays.
* **Tests**
* Extended unit tests for billing-team entitlement aggregation and
non-anonymous user counting.
* Added end-to-end coverage for the internal plan-usage endpoint,
including seeded scenarios and period validation.
* **Refactor**
* Reworked entitlement and usage calculations to reuse shared logic for
more consistent results.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: armaan <armaan@stack-auth.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-06-24 12:25:20 -07:00
Konstantin Wohlwend
6883d83ad1 Fix overlay warning 2026-06-24 11:25:58 -07:00
Konsti Wohlwend
d57bba3a06
fix: remove email-outbox dashboard page (#1662) 2026-06-24 11:10:24 -07:00
Aman Ganapathy
0c8f5e33ed
feat(payments): quick-ack + idempotent webhooks (#1664)
### Context
Stripe recommends acking webhook events ASAP with a 200. Stripe also
recommends employing event idempotency on your end. By responding
quickly, you prevent stripe from thinking the webhook failed and
retrying the event. Retrying the event in the past used to be
responsible for people getting multiple payment receipt emails. Note
that even in the case where an event processing genuinely fails, we have
a new table to let us recover from it.

Currently, recovery will be manual, but since it will be logged to
sentry we will be notified.


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Quick-ack Stripe webhooks with 200 and add atomic idempotency to stop
duplicate processing and emails. Events are persisted and processed in
the background with clear status and error tracking.

- **New Features**
- Persist each webhook in `StripeWebhookEvent` keyed by `event.id` with
full `payload` and `stripeAccountId` for recovery.
- Return 200 immediately; process in the background and track status as
`PENDING`, `PROCESSED`, or `FAILED`.
- Single-flight claim deduplicates redeliveries while `PENDING` and
after `PROCESSED`; only `FAILED` events reprocess on redelivery.
- Store `lastError` on failures; unknown webhook types ack with 200 and
are handled asynchronously.
- Webhook response includes `deduplicated: true` when a redelivery is
skipped.

- **Migration**
- Run Prisma migrations to create the `StripeWebhookEvent` table, enum,
and unique index on `stripeEventId`.

<sup>Written for commit 59456a36e8.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1664?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->

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

* **New Features**
* Added persistent, idempotent Stripe webhook handling with event-level
deduplication keyed by the webhook event id.
* Webhooks are acknowledged immediately and processed asynchronously,
with automatic retry capability for failed events.
* **Bug Fixes**
* Reduced duplicate side effects from redeliveries (including preventing
repeated receipt emails) by ensuring only one successful processing per
event.
* **Tests**
* Updated and expanded integration and end-to-end coverage for
asynchronous processing, deduplication, and failure recovery behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-24 09:30:38 -07:00
github-actions[bot]
09c9df410a 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
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-06-24 01:55:58 +00:00
Konsti Wohlwend
bf265abf88
refactor: move esbuild utils from stack-shared to shared-backend (#1653)
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
2026-06-23 16:23:04 -07:00
Konsti Wohlwend
ed48ab3bd7
feat: add "View usage" button to analytics limit banner and rename Usage page (#1660) 2026-06-23 16:20:34 -07:00
Konsti Wohlwend
a6c46db72c
perf: prefetch email theme previews during earlier onboarding steps (#1655) 2026-06-23 15:46:03 -07:00
Konsti Wohlwend
59f6e53f7e
chore: upgrade deprecated dependencies (#1654) 2026-06-23 15:44:37 -07:00
Konstantin Wohlwend
012098e1a9 Change Quick Sign Up email address 2026-06-23 13:23:17 -07:00
Konstantin Wohlwend
812716dae2 Better migration 2026-06-23 13:07:27 -07:00
github-actions[bot]
781dde9a78 chore: update package versions 2026-06-23 20:06:39 +00:00
Konsti Wohlwend
a559531080
feat: implement preview project pool for instant project creation (#1649) 2026-06-23 12:55:26 -07:00
Konsti Wohlwend
7b0f430975
fix: suppress React 19 script warning in SsrScript (#1648) 2026-06-23 12:16:14 -07:00
Konsti Wohlwend
a2889fc044
fix: chunk SessionRecorder flush to stay under server 1MB body limit (#1647) 2026-06-23 12:04:46 -07:00
github-actions[bot]
cb7ea302c7 chore: update package versions 2026-06-23 18:48:44 +00:00
Konstantin Wohlwend
8820b39b37 Stop using app.urls everywhere 2026-06-23 11:22:44 -07:00
Armaan Jain
0132ec151a
Project onboarding speedup (#1596)
Speeds up project onboarding by consolidating API calls and adding
prefetching:

- Single PATCH endpoint for saving onboarding status + state together
- Background config save on welcome step (with proper retry/error
handling)
- Prefetch email themes and Stripe info for upcoming steps
- Suspense-based skeleton loaders instead of full-page spinners
- Extracted shared types and lightweight step components

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

* **New Features**
* Unified onboarding progress saving for the new project flow,
persisting status plus optional onboarding state in a single update
path.
* **Improvements**
* Onboarding wizard now derives status/state from owned project data and
removes extra internal fetching/loading gates.
* Added skeleton/Suspense loading for email theme and payments steps,
with more reliable “final config”/completion sequencing.
* Admin project data now includes onboarding state; Stripe account info
uses cached retrieval.
* Backend avoids source-of-truth override changes during metadata-only
updates.
* **Tests**
* Updated onboarding wizard tests and added end-to-end coverage for
updating onboarding status/state together.
* **Documentation**
  * Added the “clickmaps” app icon to docs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

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>
2026-06-23 10:59:38 -07:00
Mantra
28b559b7a0
fix: resolve MODULE_NOT_FOUND for claude-agent-sdk cli.js in RDE config updates (#1639) 2026-06-23 10:53:37 -07:00
Armaan Jain
80ba110e78
Usage page in settings (#1595)
## Summary

Adds a Usage page under Project Settings showing the owner team's plan,
billing period, and resource consumption (dashboard admins, auth users,
emails, analytics events, session replays) with progress bars and an
upgrade CTA.

Backend aggregates usage across the team via `sumTenancyUsage`
(parallelized with `Promise.all`) and serves it through `GET
/internal/plan-usage`. Shared types in `@hexclave/shared` define the
contract consumed by the SDK and dashboard.

## Screenshots

![Usage page — light
mode](https://app.devin.ai/api/presigned_proxy?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcmdfaWQiOiJvcmdfaGwzT2d1STVWMXBYcTUwUCIsInVzZXJfaWQiOm51bGwsImJ1Y2tldF9uYW1lIjoiZGV2aW5hdHRhY2htZW50cyIsImJ1Y2tldF9rZXkiOiJhdHRhY2htZW50c19wcml2YXRlL29yZ19obDNPZ3VJNVYxcFhxNTBQLzE2ZTAyM2NkLTQzZjgtNDkyZS1hNDFkLTVmZjc1ZDg5NTQ3MSIsImlhdCI6MTc4MTU1MzY4OSwiZXhwIjoxNzgyMTU4NDg5LCJmaWxlbmFtZSI6InNjcmVlbnNob3RfZWE1YWU3YTJkNWQwNGM2NmFmYmM4NTY0YjQ2OTMxMDMucG5nIn0.O5H-gvyZ5an3wM7-CRcuyb6uFgg86cSftnAKnWh57VA)

Link to Devin session:
https://app.devin.ai/sessions/1bc3344126a442adb4f29ae373d346be
Requested by: @Developing-Gamer

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

## Summary by CodeRabbit

* **New Features**
* Added Usage page in project settings displaying comprehensive plan
usage metrics including dashboard seats, authentication users, emails
sent, analytics events, and session replays
* Shows current usage against plan limits with visual progress
indicators
* Displays upgrade recommendations when plan limits are exceeded with
one-click upgrade functionality
  * Added Usage menu item to project settings navigation

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

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>
2026-06-23 10:32:07 -07:00
Armaan Jain
bd511a6255
fix(sdk): bypass urls proxy in internal SDK methods for hosted components (#1641) 2026-06-23 10:30:54 -07:00
github-actions[bot]
163e7be002 chore: update package versions 2026-06-23 17:26:08 +00:00
Konstantin Wohlwend
95e2c2c786 Fix bug with local dashboard stopping file watch 2026-06-23 00:04:22 -07:00
Konstantin Wohlwend
501e8571e6 Fix test dir directory to not track files 2026-06-22 23:47:00 -07:00
Konstantin Wohlwend
a93f2561d8 Update OpenAPI schema 2026-06-22 23:45:40 -07:00
Konstantin Wohlwend
0908170e52 Config errors are now more obvious 2026-06-22 23:42:17 -07:00
Konsti Wohlwend
5b9fd1695f
fix: return 409 instead of 500 when signing up with duplicate email (#1637) 2026-06-22 17:29:08 -07:00
Konsti Wohlwend
433d4dcc96
Upgrade TypeScript from 5.9.3 to 6.0.3 (#1644) 2026-06-22 17:18:15 -07:00
Konsti Wohlwend
591554c3b1
Silently ignore network errors in EventTracker and SessionRecorder flush (#1638) 2026-06-22 16:12:54 -07:00
Konsti Wohlwend
845487adee
fix: allow Google/GitHub/Microsoft OAuth in RDE onboarding (#1640) 2026-06-22 16:11:24 -07:00
Konsti Wohlwend
a66d94bb43
feat: devtool indicator - rename Quick Sign In → Quick Sign Up, remove email input (#1643) 2026-06-22 16:10:57 -07:00
github-actions[bot]
88eae6fbf1 chore: update package versions 2026-06-22 23:00:06 +00:00
Konstantin Wohlwend
b69f9f0eeb Various UX/AX improvements 2026-06-22 15:54:09 -07:00
BilalG1
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 7539fb9fbf.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1588?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->

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

* **Chores**
* Migrated environment variable names from the legacy `STACK_*` prefix
to the new `HEXCLAVE_*` prefix across backend, dashboard, tooling,
Docker, and examples.
* Updated environment/config resolution to prefer `HEXCLAVE_*`, treat
empty strings as unset, and detect conflicts when both `STACK_*` and
`HEXCLAVE_*` are set to different values.
* Updated local emulator, server startup, and env-generation workflows
to use the new names (with legacy fallback where applicable).
* **Documentation**
  * Updated docs and code examples to reference `HEXCLAVE_*` variables.
* **Tests**
* Refreshed unit and e2e coverage to validate dual-read behavior,
conflict detection, and empty-value handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-19 18:58:53 -07:00
Konstantin Wohlwend
b7f145e2db Update docs-json.generated.ts 2026-06-19 17:21:38 -07:00
Konsti Wohlwend
229de02e17
Add 6/19/26 changelog entry (#1629) 2026-06-19 17:20:19 -07:00
Konsti Wohlwend
7aec27d978
feat: add Hexclave analytics to Mintlify docs (#1635) 2026-06-19 17:12:46 -07:00
github-actions[bot]
d064b20290 chore: update package versions 2026-06-20 00:10:09 +00:00
Konstantin Wohlwend
b8fd39f552 Delete docs.json redirects 2026-06-19 17:08:43 -07:00
Konsti Wohlwend
e3202a331c
feat: devtool indicator auto-visibility based on NODE_ENV (#1624)
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
2026-06-19 16:47:02 -07:00
Konsti Wohlwend
a9d77bbf63
feat: show info note when Reject action is selected in signup rule editor (#1633) 2026-06-19 16:46:05 -07:00
Konsti Wohlwend
1b5e79fab3
fix: changelog endpoint returns 502 silently without Sentry logging (#1618) 2026-06-19 15:52:56 -07:00
github-actions[bot]
c32b668076 chore: update package versions 2026-06-19 21:42:14 +00:00
Konstantin Wohlwend
4689ffb575 Internal tools sidebar item 2026-06-19 14:06:19 -07:00
Konstantin Wohlwend
ec7c7a8598 Dormant toggle 2026-06-19 13:58:43 -07:00
BilalG1
0e1d98b5d0
fix(cli): fall back to installed CLI when npx auto-update fails (#1612)
## Problem

`hexclave dev` re-execs itself through `npx <pkg>@latest`
(`maybeReexecToLatest`) so users always get the latest dashboard without
reinstalling. But when that npx run **fails**, it exits nonzero and we
did `process.exit(result.code)` — killing `hexclave dev` even though a
perfectly good CLI was already installed locally.

This surfaced on **Replit**, where a user running `hexclave dev` got:

```
npm notice Access denied: Your download has been blocked by the Socket Security Policy.
Reason: AI-detected potential malware.
npm error code ECOMPROMISED
npm error Lock compromised
```

Diagnosis: the user's `pnpm` is aliased to `sfw pnpm` (**Socket
Firewall**), and Replit enforces an org-level Socket Security Policy.
Socket **blocks the `@hexclave/cli@latest` download** (false-positive
"AI-detected malware", almost certainly the bundled minified dashboard).
The interrupted download breaks npx's reify while it holds its cache
lock, which npm reports as `Lock compromised`. The lock message is a
*downstream symptom*; the real failure is the blocked download.

The same class of failure (blocked download, npm error, lock contention,
offline) all share one shape: **npx exits nonzero before our CLI ever
runs**, and today that takes down `hexclave dev`.

## Fix

Use a **startup-marker handshake** to distinguish the two cases:

- The parent passes a temp marker path to the npx child via
`STACK_CLI_REEXEC_MARKER`.
- The re-exec'd child touches the marker the instant it starts
(`signalReexecStartedIfChild`).
- After the child exits (`decidePostReexec`):
- exited 0, or nonzero **with** the marker present → our CLI ran;
**propagate** the exit code (real command result).
- nonzero **without** the marker, or npx not spawnable → our CLI never
ran; **fall back** to the installed CLI instead of failing `hexclave
dev`.

The marker only needs file create/exists (robust on sandboxed/networked
filesystems). If the marker can't be created, we preserve the old
always-propagate behavior, so there's no spurious-fallback risk.

`decidePostReexec` and `signalReexecStartedIfChild` are pure and
unit-tested.

## Verification

- `pnpm test run src/lib/self-update.test.ts` → 23 passing (added cases
for the fallback decision and the marker handshake).
- `pnpm typecheck` / `pnpm lint` → clean.
- End-to-end: forced a real npx failure (unreachable registry → npx
exits nonzero before our CLI runs) and confirmed `hexclave dev` now logs
`Auto-update skipped: …; continuing with the installed CLI.` and
proceeds into the installed dev path instead of dying.

## Notes / follow-ups (not in this PR)

- Workaround for affected users today: `STACK_CLI_NO_AUTO_UPDATE=1` (or
`--no-auto-update`) skips the npx download entirely.
- Worth reporting the Socket false-positive to socket.dev to allowlist
`@hexclave/cli`, and reconsidering shipping a ~165 MB minified dashboard
inside the npm tarball (it's what trips AI-malware heuristics and slows
cold installs).

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Prevent `hexclave dev` from exiting when `npx @latest` auto-update fails
by falling back to the installed CLI. Signal-based aborts now propagate
as a nonzero exit (never NaN), so Ctrl-C doesn’t relaunch dev.

- **Bug Fixes**
- Fall back to the installed CLI when `npx <pkg>@latest` fails before
the CLI starts (firewalls, offline, npm lock errors). Do not fall back
when the child is killed by a signal; propagate 128+signum with a safe
nonzero fallback if the signum is unknown.
- Startup-marker handshake: parent sets `REEXEC_MARKER_ENV`
(`HEXCLAVE_CLI_REEXEC_MARKER`); child touches it on start;
`decidePostReexec` chooses propagate vs fallback. If the marker can’t be
created, keep the old always-propagate behavior.
- Scrub the marker env from user commands using the exported constant,
covering both Windows and POSIX spawn paths.

<sup>Written for commit cb2635f2ae.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1612?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->

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

## Release Notes

* **Bug Fixes**
* Updated the `dev` command to prevent internal re-exec environment
details from being inherited by user commands.
* Improved self-update re-exec fallback logic to better detect whether
the CLI actually started, with more reliable exit-code and signal
handling.
* **Tests**
* Added deterministic test coverage for the post-re-exec decision path
and signal/exit propagation scenarios, including early `npx` failures.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-19 13:17:07 -07:00
BilalG1
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 2aef5d4b1a.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1627?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->



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

## Summary by CodeRabbit

* **Refactor**
* Improved internal environment variable generation architecture for
enhanced maintainability and multi-framework support.

---

**Note:** This release contains internal code improvements with no
changes to user-facing functionality.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-19 13:08:41 -07:00