Commit Graph

3328 Commits

Author SHA1 Message Date
github-actions[bot]
5eedb484e1 chore: update package versions 2026-06-12 21:09:46 +00:00
Konstantin Wohlwend
18dd48f3f7 Fix verification code handler revoke order 2026-06-12 13:29:25 -07:00
Aman Ganapathy
21c5198255
chore(cli-auth): publishable key no longer required for cli auth (#1590)
<!-- This is an auto-generated description by cubic. -->
## Summary by cubic
CLI authentication no longer requires a publishable client key. Login
works with only a project ID; pass `publishable_client_key` only if the
project has `requirePublishableClientKey` enabled.

- **New Features**
- In `stack-auth-cli-template.py`, `publishable_client_key` is optional;
requests send `x-hexclave-project-id` and `x-hexclave-access-type:
client`, and include `x-hexclave-publishable-client-key` only when
provided.
- Updated docs and generated prompts to remove the key from examples and
explain when it’s needed.

- **Migration**
- No changes required; existing calls that pass `publishable_client_key`
still work.
- You can remove the argument from `prompt_cli_login(...)` unless your
project requires it.

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

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1590?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. -->
2026-06-12 10:12:27 -07:00
BilalG1
64eeedce9f
Fix dev CI: docker prune missing template + cross-domain test failures (#1582)
Unbreaks the test workflows that have been red on every dev push since
June 4. All root causes trace to direct pushes whose own CI runs already
failed (`8b78587da`, `c60016226`, `59daf1321`).

> Note: this PR originally also fixed the "Docker Server Build and Push"
workflow (missing `@hexclave/template` in the Dockerfiles' `turbo prune`
scope), but dev picked up the identical fix via 59daf1321 while this was
open, so the Dockerfile changes dropped out after merging dev back in.

## 1. E2E cross-domain spies — broken since `c60016226` (June 4)

`c60016226` renamed `_getCurrentRefreshTokenIdIfSignedIn` →
`_fetchCurrentRefreshTokenIdIfSignedIn` in the SDK and template unit
tests, but missed the eight `vi.spyOn` calls in
`apps/e2e/tests/js/cross-domain-auth.test.ts`. `vi.spyOn` throws on
missing properties → all 8 tests failed with
`_getCurrentRefreshTokenIdIfSignedIn does not exist`.

**Fix:** rename the spies.

## 2. signOut test timeout in all 5 SDK packages — broken since
`c60016226` (June 4)

The refresh-cookie test added in the same commit writes to a cookie
token store, which queues a background trusted-parent-domain lookup.
That lookup fetches the unreachable test `baseUrl` with retries while
holding `storeLock`'s read lock (via `AsyncStore.setAsync`), so the
later signOut test deadlocks on `storeLock.withWriteLock` inside
`_signOut` and hits the 5s vitest timeout (passes in isolation, fails
when the file runs in order).

**Fix:** stub `_getTrustedParentDomain` in the cookie test so the queued
task settles immediately.

## 3. "does not await pending auth resolutions" — premise broken by
`8b78587da` (June 4), masked by the spy rename

`8b78587da` added `nonHostedHandlerNames`, making `afterSignIn` resolve
to a local URL instead of the hosted domain. The test redirected to
`afterSignIn` from a callback page expecting the nested cross-domain
auth params path to run — but the redirect became same-origin, so
`_fetchCurrentRefreshTokenIdIfSignedIn` is (correctly) never called.
This was invisible until fix 1 above unmasked it.

**Fix:** redirect to `accountSettings` (still hosted, so still
cross-origin), preserving the test's intent: the session lookup during
nested-param construction must not await pending auth resolutions.

## 4. internal-metrics e2e snapshots — broken on dev by `59daf1321`

The analytics overview filters PR reshaped the metrics endpoint response
(added `bounce_rate`, daily/hourly breakdown arrays,
`top_browsers`/`devices`/`operating_systems`/`regions`; slimmed the
zero-filled daily fallback arrays) and updated the backend unit-test
snapshots, but left the e2e snapshots stale — its own dev run fails
these two tests identically.

**Fix:** update `__snapshots__/internal-metrics.test.ts.snap`,
reconstructed from the CI diff with every context line verified against
the old snapshot, and the new fields cross-checked against the route
change in 59daf1321.

## Verification

- `client-app-impl.cross-domain.test.ts`: 7/7 in `packages/template` and
the regenerated `packages/js` copy (signOut: 5s timeout → 10ms).
- `tests/js/cross-domain-auth.test.ts`: 18/18 locally (fully mocked, no
backend needed).
- Lint + typecheck pass for the touched packages.
- The metrics snapshot can only be fully confirmed by CI (needs the live
backend).

## Out of scope

"Run setup tests with custom base port" also intermittently fails
unrelated test files at exactly 60s under runner load (last green May
5), and the local-emulator run had one `payments/switch-plans` flake —
pre-existing flakiness not addressed here.
2026-06-11 17:37:11 -07:00
BilalG1
f4c13db079
fix(sdk): stop nested cross-domain auth from restarting the redirect chain on the hosted domain (#1581)
## What users see

Setting up a new project with hosted components, clicking **Sign in**
sometimes throws the browser into a redirect ping-pong between the app
and the hosted components site — anywhere from 5 to 9+ cross-domain
redirects — before the sign-in page finally renders. Reproduced live
against production:

![redirect loop
demo](https://gist.githubusercontent.com/BilalG1/888feed849ef0bc1f73c4609bfd71662/raw/redirect-loop.gif)

Captured redirect chain from that recording (one line per navigation, ~1
per second):

```
localhost:3000/                                      ← click "Sign in"
HOSTED  /handler/sign-in?...nested_refresh_token_id  ← start session handoff
localhost:3000/?redirect_uri=...&state=S1            ← bounce: "prove the session"
HOSTED  /handler/sign-in?...&code=...                ← code delivered... then RESTART ↩
localhost:3000/?redirect_uri=...&state=S2            ← bounce again (fresh state!)
HOSTED  /handler/sign-in?...&code=...                ← code delivered... RESTART ↩
localhost:3000/?redirect_uri=...&state=S3            ← again
HOSTED  /handler/sign-in?...&code=...                ← again
localhost:3000/?redirect_uri=...&state=S4            ← again
HOSTED  /handler/sign-in?...&code=...                ← exchange finally wins the race
HOSTED  /handler/sign-in (clean URL)                 ← sign-in form renders
```

The designed handshake is only 3 cross-domain redirects. Everything past
that is one bug restarting the chain over and over.

## The bug

When a page on the hosted domain loads with a one-time `code`, the
`StackClientApp` constructor schedules **two** async startup flows
back-to-back:

1. `callOAuthCallback` — which **synchronously strips `code` + `state`
from the URL** (`history.replaceState`) before starting its network
token exchange, and
2. `_maybeHandleNestedCrossDomainAuth` — which has a guard for exactly
this situation ("a real OAuth callback wins"), implemented as *"is
`code`+`state` in the URL?"*

Flow 1 runs first. By the time flow 2 reads `window.location`, the
params it's guarding on are already gone — so it concludes no OAuth
callback is happening, sees the (un-stripped) nested handoff marker, and
bounces back to the app domain to request a *new* code, cancelling the
in-flight exchange:

```mermaid
sequenceDiagram
    participant A as Your app (a.com)
    participant B as Hosted sign-in (b.com)
    A->>B: 1. go to sign-in ("I have session X")
    B->>A: 2. "prove it" (state, code_challenge)
    A->>B: 3. one-time code for session X
    Note over B: callOAuthCallback strips code+state from URL,<br/>starts token exchange (network)
    Note over B: nested handler runs next, checks URL for code+state…<br/>already gone → guard defeated 
    B->>A: 2'. "prove it" AGAIN (fresh state) — exchange cancelled
    A->>B: 3'. another one-time code
    Note over B: …loop repeats until the exchange happens to<br/>finish before the re-bounce navigation commits
```

Whether each cycle escapes is a coin flip between two competing
navigations (the exchange's success redirect vs. the handler's
re-bounce), which is why the loop count varies run to run and the issue
reproduces so inconsistently.

## The fix

Capture the URL once, at construction time — before anything can mutate
it — and let the nested handler consult that snapshot in addition to the
live URL:

- The constructor now captures `new URL(window.location.href)` when
scheduling the nested-auth resolution and passes it in.
- `_maybeHandleNestedCrossDomainAuth(urlAtConstructionTime?)` stands
down if **either** the live URL **or** the construction-time URL carries
`code` + `state`.

A stripped callback still counts as a callback, so the handler no longer
re-bounces while the exchange is in flight. Every other path is
unchanged: the handler still reads all of its working params from the
live URL (the strip never touches the nested params), hop-1/hop-2 pages
have no `code` in either snapshot, and ordinary social-login callbacks
never had this race (the component-driven flow strips long after the
handler has run).

Note this fix removes the *restarts*. The remaining 3-redirect baseline
for signed-out users is a separate design issue (the analytics-created
anonymous session triggering the handoff at all) and is intentionally
out of scope here.

## Tests

- New: `does not re-bounce nested cross-domain auth after the OAuth
callback consumed code+state from the URL` — pins both guards
(mutation-tested: reverting either fix line fails it).
- New: `passes the construction-time URL to the nested cross-domain auth
handler` — pins the eager capture; fails if the URL is read lazily at
handler run time.
- Full cross-domain suite passes (the `signOut` timeout in that file is
a pre-existing flake on `dev`, reproducible without this change).


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes a race in nested cross-domain auth that caused repeated redirects
between the app and the hosted sign-in. We now snapshot the URL at
construction so OAuth callbacks are respected even after `code` and
`state` are stripped.

- **Bug Fixes**
- Capture `window.location` at construction and pass it to
`_maybeHandleNestedCrossDomainAuth`.
- Handler stands down if `code` and `state` exist in the live or
captured URL.
- Stops the redirect ping‑pong; the 3‑redirect baseline remains
unchanged.
- Keeps reading nested params from the live URL; no other paths changed.
  - Adds tests to pin the race and the construction‑time URL behavior.

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

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

* **Bug Fixes**
* Improved cross-domain OAuth authentication handling to prevent
unnecessary redirects after OAuth callback processing.

* **Tests**
* Added test coverage for nested cross-domain OAuth authentication
scenarios.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-11 17:37:05 -07:00
Armaan Jain
a092be6dc3
Payments minor navigation and UI bugs fixed (#1585)
<!--

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

-->


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes product creation navigation and the quantity selector layout in
Payments. Links now resolve to the correct project route and the
quantity control no longer squishes or wraps.

- **Bug Fixes**
- Use admin app `projectId` and a shared `getCreateProductHref` helper
to build product creation URLs, preserving `productLineId` and
`customerType` when present.
- Prevent quantity selector buttons from shrinking and wrap the input in
a fixed-width container to keep the control stable in tight layouts.

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

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

<!-- End of auto-generated description by cubic. -->
2026-06-11 11:38:00 -07:00
Mantra
74c888fed7
chore(mcp/docs): canonicalize HEXCLAVE_ env vars in docs + raise ask_hexclave step limit & timeout (#1571)
## Summary

Follow-up from analyzing the dogfooding report on the `ask_hexclave` MCP
tool. Two root causes were confirmed against source:

1. **The "`STACK_` vs `HEXCLAVE_` env var hallucination" wasn't a
hallucination** — it's an incomplete Stack Auth → Hexclave rebrand. The
SDK resolves both prefixes (`packages/js/src/generated/env.ts`), with
`HEXCLAVE_*` canonical and `STACK_*` a legacy fallback, but several
docs/examples still showed the old `STACK_*` names. That inconsistency
is what misled agents into thinking `HEXCLAVE_*` was made up.
2. **`ask_hexclave` timeouts** — the tool proxies to a `quality:
"smart"` agentic docs-search loop. The agent step budget (50) and the
120s timeouts were too tight; broad/multi-part questions blew the budget
(reproduced 3× while investigating).

## Changes

### Docs: canonicalize client SDK auth env vars to `HEXCLAVE_*`
Converted `PROJECT_ID`, `PUBLISHABLE_CLIENT_KEY`, `SECRET_SERVER_KEY`,
`API_URL` (+ `NEXT_PUBLIC_` / `VITE_` forms) from `STACK_*` →
`HEXCLAVE_*` in app-setup docs + the package template:

-
`docs-mintlify/guides/integrations/{convex,tanstack-start,vercel}/overview.mdx`
- `docs-mintlify/guides/going-further/local-vs-cloud-dashboard.mdx`
- `docs-mintlify/guides/apps/analytics/overview.mdx`
- `docs-mintlify/guides/other/tutorials/ship-production-ready-auth.mdx`
- `docs-mintlify/sdk/objects/hexclave-app.mdx`
- `packages/template/src/integrations/convex/component/README.md` (the
tracked source of the generated `@hexclave/js` + `@hexclave/next` copies
— the generated copies are git-ignored)

**Deliberately left untouched** — read literally by the backend/CLI (no
`HEXCLAVE_` alias) or user-defined: `STACK_CLICKHOUSE_*`,
`STACK_DATABASE_*`, `STACK_OPENROUTER_*`, `STACK_CLI_*`, `STACK_SEED_*`,
`STACK_WEBHOOK_SECRET`, `STACK_DATA_VAULT_SECRET`, and the `x-stack-*`
HTTP headers. So `self-host.mdx`, `cli.mdx`, `jwts.mdx`, `webhooks`, and
`data-vault` docs are intentionally unchanged.

### Reliability: raise `ask_hexclave` step limit + timeout
- `apps/backend/src/app/api/latest/ai/query/[mode]/route.ts`:
docs/search agent step limit **50 → 75** (+50%); AI generation abort
**120s → 180s**
- `apps/mcp/src/mcp-handler.ts`: MCP function `maxDuration` **120 →
180** (kept ≥ backend timeout so the proxy doesn't die before the
backend finishes)

## Notes
- Also includes a small pre-existing `run pnpm fml` commit (regenerated
docs snippets / `llms-full.txt`).
- The step/timeout bumps address the *symptom*. The durable reliability
fix is streaming/keepalive on the MCP proxy so the client never idles
out mid-query — proposed as a follow-up.
- **Not** included: the separate `sendEmail` doc-vs-SDK drift (docs
declare `Promise<Result<void, KnownErrors>>` in
`sdk/objects/hexclave-app.mdx`, but the SDK returns `Promise<void>` and
throws). That's a docs *correctness* bug deserving its own PR.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Canonicalized auth env vars in docs/templates to `HEXCLAVE_*`, raised
docs/search step limits and timeouts, and clarified `HexclaveApp`
defaults. MCP tool and server instructions now require loading the
`skill` resource before queries.

- **Bug Fixes**
- Docs: Use `HEXCLAVE_PROJECT_ID`, `HEXCLAVE_PUBLISHABLE_CLIENT_KEY`,
`HEXCLAVE_SECRET_SERVER_KEY`, and optional `HEXCLAVE_API_URL` across
guides/templates (Vercel, Convex, TanStack Start, analytics). In SDK
docs, `secretServerKey` defaults to `HEXCLAVE_SECRET_SERVER_KEY`, and
client defaults use `NEXT_PUBLIC_HEXCLAVE_*`. Backend-only `STACK_*`
vars (`STACK_CLICKHOUSE_*`, `STACK_DATABASE_*`, `STACK_OPENROUTER_*`,
CLI/data-vault/webhook headers) unchanged.
- Reliability: Increase docs/search step limit 50→75 and timeouts
120s→180s; set MCP `maxDuration` to 180s; use `performance.now()` for
duration logging. MCP instructions updated to require loading the
`skill` resource before using tools.

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

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1571?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://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 & Reliability**
* Increased AI operation timeouts and step limits for certain prompts;
improved generate-mode duration measurement for more accurate logging.
* **Documentation**
* Replaced Stack-branded environment variable names with Hexclave
equivalents across guides and examples.
* Clarified that hexclave dev injects required environment variables
automatically.
  * Added guidance on configuring custom authentication redirect URLs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-11 10:53:53 -07:00
Konstantin Wohlwend
be01ae733e Improved PKCE support 2026-06-11 10:28:14 -07:00
github-actions[bot]
1999ad8be3 chore: update package versions 2026-06-11 17:19:24 +00:00
Konsti Wohlwend
4608564fc3
Increase SMTP password max length from 70 to 256 (#1579) 2026-06-11 09:53:18 -07:00
Mantra
59daf1321c
[codex] Add analytics overview filters (#1496)
## Summary

Adds richer analytics overview metrics and filterable dashboard
breakdowns.

- adds hourly overview series for the 1-day range
- adds country, referrer, browser, OS, and device filters to internal
metrics
- adds bounce rate, session duration, top countries, top browsers, top
operating systems, and device breakdowns
- updates the overview dashboard with filter chips, top-list cards,
animated metric states, and 1-day hourly chart support
- captures user agent on page-view analytics events, with a server-side
fallback for older clients

## Validation

Attempted targeted tests:

`pnpm test run
apps/backend/src/app/api/latest/internal/metrics/route.test.ts
'apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/(overview)/analytics-chart-mode.test.ts'`

This did not reach Vitest in the temporary split worktree because
`node_modules` is not installed there and the repo pre-step failed at
`pnpm exec tsx ./scripts/generate-sdks.ts`.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Adds analytics overview filters with optional date‑range bounds and
1‑day hourly charts, plus smoother, accessible animations across charts
and top lists. Improves correctness and stability with deterministic
caching, normalized inputs, client‑only user‑agent capture, and
globe/layout fixes.

- **New Features**
- Filterable analytics overview (country, referrer, browser, OS, device)
with normalized inputs and optional `since`/`until`; API/admin/dashboard
accept `AnalyticsOverviewFilters` with deterministic cache keys.
- 1‑day hourly charts (page views, visitors) and a metric mode toggle
(DAU, Visitors, Revenue); animated top‑lists and sparklines powered by
`motion` with reduced‑motion support.
- UI: filter chips/menu, clearer tooltips (incl. user metric cards),
optional interactive globe with dynamic camera distance; exported
`TooltipPortal` from `@hexclave/ui`.

- **Refactors & Bug Fixes**
- Event ingest: client sends `user_agent`; removed server‑side fallback;
added user‑agent filter‑fragment builder and tests.
- Metrics correctness: aligned hourly bounds to start of UTC hour;
derived 1‑day revenue total from daily series; resilient chart x‑axis
formatting; country filter options use analytics `top_regions`;
fixed‑'en' locale for top‑lists; added date‑range parsing/validation for
filters.
- UI/runtime: smoother pill/tab slider animations with guards for
missing Web APIs; added `containedHeight` to `PageLayout` and wired into
sidebar/session replays; globe disables zoom when non‑interactive.
- Misc: instrumentation runs only in Node (`process.env.NEXT_RUNTIME ===
"nodejs"`); analytics/overview page redirects with URL‑encoded
`projectId`; Docker: include `@hexclave/template` in `turbo prune` to
fix CI builds.

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

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1496?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://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**
* Analytics filters (country, referrer, browser, OS, device); hourly
signup and active-user series; expanded hourly/daily analytics payloads
and top-lists UI.
* Chart metric modes (DAU, Visitors, Revenue), optional page-views
series, interactive globe support, animated Top Lists, and sparkline
animations.

* **Improvements**
* Better user-agent capture/normalization for batched events and
page-view tracking; reduced-motion aware animations; enhanced tooltips
and UI slider/tab indicators.
  * Added motion library dependency.

* **Tests**
  * New unit tests for analytics filters and chart metric mode behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: mantra <mantra@stack-auth.com>
2026-06-10 17:50:35 -07:00
Armaan Jain
4479758a68
Ask mcp endpoint on skill (#1570)
<!--

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
Expose MCP tools on the skills site as HTTP endpoints. Adds an MCP
wrapper that maps query params to JSON-RPC with CORS and stricter
validation; HEAD now validates routes and matches GET behavior.

- New Features
  - Dynamic GET/HEAD/OPTIONS route at `/[toolName]` in the skills app.
- MCP wrapper: resolves tool aliases, builds/validates args from query,
proxies to the MCP endpoint with timeout, sets CORS + no-store headers,
maps MCP/HTTP errors, and rejects malformed routes/params; utilities for
endpoint URL resolution from env or sibling host and listing available
route names.
- Tests/config: Vitest setup for `apps/skills`; coverage for HEAD
short-circuit and 404s, route resolution, argument coercion, and invalid
query cases.

- Bug Fixes
- HEAD delegates to the shared handler and returns 404 for unknown tool
routes.
  - IPv6 localhost detection accepts bracketed `[::1]` in URL hostnames.

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

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1570?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://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 dynamic HTTP endpoints for MCP tools with GET/HEAD/OPTIONS
handling, tool discovery, route resolution, argument mapping/coercion,
and standardized text/error responses.

* **Tests**
* Added/expanded unit tests for route resolution, argument coercion,
endpoint derivation, response handling, HEAD behavior, and route-listing
snapshots.

* **Documentation**
* Clarified that hexclave dev injects required environment variables and
added guidance on updating auth SDK URLs to avoid redirect issues.
<!-- 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-11 04:21:50 +05:30
Madison
49442cab4b
[Fix] remove support button from user page (#1568)
Remove the support button from user profile pages. 

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Removed the Support button from user profile pages to simplify actions
and avoid navigating to conversations from this view. Also removed
unused code: the `urlString` import and `useRouter`.

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

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

* **Bug Fixes**
* Removed the "Support" action button from user management actions in
the user details page. The remaining user actions such as impersonate,
restrict, and delete remain available.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-10 17:14:35 -05:00
Konsti Wohlwend
e15ea932f1
Bump submodules (#1577) 2026-06-10 13:53:13 -07:00
Aman Ganapathy
35e144e25c
feat(emails): disable unavailable email server options for local (#1576)
### Context
When working with local install, we can't send emails with resend keys/
managed domain/ custom smtp as of yet.
So, we disable those buttons and indicate to the user what's going on.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Disables unsupported email server options when running the dashboard
locally. Only the `shared` provider is selectable; others are disabled
with a clear tooltip.

- **New Features**
- In local development, disables Resend, Managed Domain, and Custom
SMTP; only `shared` remains enabled.
- Shows tooltip: "These email server options are not supported when
running dashboard locally." and applies disabled, non-interactive styles
without changing the card layout.

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

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

* **Bug Fixes**
* Email provider selection UI now disables non-shared providers when the
dashboard is running in a local development/emulator environment, and
shows explanatory tooltips on the disabled provider cards. A
shared-environment tooltip string was added to clarify which option is
supported locally, improving clarity when configuring email settings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-10 13:22:01 -07:00
BilalG1
7f99f15b42
fix(rde): graceful config load errors + lightweight /config import path (#1557)
## Problem

A user hit `Failed to register development environment session (500)`
when running the RDE (`hexclave dev` / `stack dev`). Removing
`defineStackConfig` from their `stack.config.ts` made it go away.

**Root cause:** the local dashboard evaluates the project's config file
in a plain Node context via `jiti`
([config-file.ts](apps/dashboard/src/lib/remote-development-environment/config-file.ts)).
When the config imports a *value* (e.g. `defineStackConfig`) from a
framework package like `@stackframe/stack` / `@hexclave/next`, jiti
executes the entire SDK — React, `server-only`, Next internals — which
throws in that context. The exception propagated as a bare 500. Dropping
`defineStackConfig` removed the value import, so jiti no longer loaded
the framework.

## Changes

**1. Graceful error (Fix 3)**
`readConfigFile` now wraps the `jiti.import` in try/catch and rethrows a
message pointing at the lightweight import path, instead of a raw 500.

**2. Lightweight `/config` subpath (Fix 1)**
Added a side-effect-free `./config` entrypoint to the framework packages
— `@hexclave/{js,next,react,tanstack-start}/config` — that re-exports
`defineHexclaveConfig` / `defineStackConfig` + the `HexclaveConfig` type
from `@hexclave/shared/config`, with **no framework runtime**. Source of
truth:
[`packages/template/src/config.ts`](packages/template/src/config.ts) +
the export in
[`package-template.json`](packages/template/package-template.json),
propagated to the generated packages via `generate-sdks`.

> Why per-package and not `@hexclave/shared/config`: `@hexclave/shared`
is only a *transitive* dependency from a user's perspective, so
importing from it fails under pnpm strict mode. Users depend on the
framework package directly, so `@hexclave/next/config` always resolves.
This was confirmed empirically — the previous tests that imported
`@hexclave/shared/config` were red.

**3. Docs / prompts / renderer aligned to the new path**
-
[`ai-setup-prompt.ts`](packages/shared/src/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.ts)
+ regenerated `docs-mintlify` (setup.mdx, llms-full.txt, snippets).
- Hand-written
[`hexclave-config.mdx`](docs-mintlify/guides/going-further/hexclave-config.mdx)
and
[`local-vs-cloud-dashboard.mdx`](docs-mintlify/guides/going-further/local-vs-cloud-dashboard.mdx).
(`docs/**` left untouched — legacy.)
- `renderConfigFileContent` (the config file the dashboard/CLI
auto-writes) now emits `import type { HexclaveConfig } from
"<pkg>/config"`. Legacy `@stackframe/*` packages predate the subpath, so
they keep their root import (guarded).

## Behavioral note

Existing config files that import from a package root get their import
line upgraded to `/config` on their next dashboard/CLI sync — a
one-time, harmless rewrite that migrates them onto the safe path. The
github-config-push idempotence test was updated to use the current
`/config` format so it still genuinely verifies "no spurious commit."

## Testing

- 43 unit tests pass across `config-file`, `github-config-push`,
`config-rendering`, `config-authoring`, `local-emulator`. The two
previously-red RDE `define*` tests now pass through jiti via
`@hexclave/next/config` (the real code path), and were made
resolution-stable by rooting their temp dir at the test file instead of
`process.cwd()`.
- Typecheck green on all source-changed packages (shared, cli, js, next,
react, tanstack-start). Lint clean.
- ⚠️ The two e2e suites (`cli.test.ts`, `config-local-emulator.test.ts`)
need backend+DB infra; their snapshot updates are mechanical and
**confirmable only in CI**.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Prevents 500s when loading `hexclave.config.ts` by adding a lightweight
`<pkg>/config` entrypoint and showing a clear, actionable error without
leaking framework stacks. Import detection, rendering, CLI, tests, and
docs now default to `/config` (including `@hexclave/tanstack-start`) so
configs load in plain Node contexts.

- **New Features**
- Added `/config` subpaths in `@hexclave/js`, `@hexclave/next`,
`@hexclave/react`, `@hexclave/tanstack-start` (and template)
re-exporting `defineHexclaveConfig`, `defineStackConfig`, and
`HexclaveConfig` with no framework runtime.
- Renderer, CLI, and docs import `HexclaveConfig` from `<pkg>/config`;
legacy `@stackframe/*` keep root imports. Existing config files
auto-upgrade on next dashboard/CLI sync.

- **Bug Fixes**
- Wrapped `jiti` config load with try/catch; capture raw error for
diagnostics and show a concise message pointing to `<pkg>/config` (no
nested framework stack traces).
- Import detection accepts optional `/config` suffix; renderer always
appends `/config` for Hexclave packages and recognizes
`@hexclave/tanstack-start`.
- Tests stabilized by scoping temp dirs to the test file; CLI error
example now references `HexclaveConfig` from `<pkg>/config` for Hexclave
packages.

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

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1557?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://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 lightweight "/config" subpath exports across SDK packages to
enable side-effect-free config authoring in plain Node contexts.

* **Documentation**
* Updated guides and snippets to recommend importing config types and
helpers from the "/config" entrypoint and added example usage.

* **Bug Fixes**
* Improved error messaging when dynamic config imports fail, with
guidance to use the "/config" entrypoint.

* **Tests**
* Adjusted tests and snapshots to expect normalized "/config" import
paths.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-10 11:40:19 -07:00
Armaan Jain
88ef2ce85f
Hosted Components Accounts Navigation bug (#1565)
<!--

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

-->

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes and hardens hosted components navigation. Restores Accounts tab
behavior without full-page reloads by using a validated, async navigate
adapter and migrating to `Hexclave*` components.

- **Bug Fixes**
- Replaced `redirectMethod` with `useHostedComponentsNavigate` to route
`#...` via `hash` and others via `href`, allowing only trusted targets
via `isRelative`/`validateRedirectUrl` with `trustedDomains:
[window.location.origin]`.
- Runs redirects with `runAsynchronously` from `@hexclave/shared` to
avoid race conditions.

- **Refactors**
- Migrated from `StackClientApp`/`StackProvider`/`StackTheme` to
`HexclaveClientApp`/`HexclaveProvider`/`HexclaveTheme` in
`@hexclave/react`.
- Regenerated Mintlify docs/snippets to use Hexclave naming and clarify
the Auth SDK `urls` option and `hexclave dev` env var injection.

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

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

* **Bug Fixes**
* Improved client-side navigation handling: allow hash navigation and
enforce/trust-check redirect targets to prevent unsafe external
navigation.

* **Refactor**
* Switched UI runtime to Hexclave-specific app, provider, and theme
components for consistent theming and behavior.

* **Documentation**
* Clarified setup: `hexclave dev` now auto-injects required environment
variables.
* Updated guidance for configuring auth/redirect URLs to ensure correct
post-auth navigation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-10 23:44:38 +05:30
BilalG1
76fc62e98b
fix(rde): stop the RDE dashboard blanking on every access-token refresh (#1566)
## Problem

In the Remote Development Environment (`hexclave dev`), the dashboard
suspends and goes **blank for a moment every ~30–60 seconds**, then
repopulates. It never happens on a plain `pnpm dev` dashboard.

## Root cause

The RDE auth gate
([`remote-development-environment-auth-gate.tsx`](../blob/dev/apps/dashboard/src/app/remote-development-environment-auth-gate.tsx))
keeps the browser signed in by re-installing a freshly minted
**access-token-only** session (`signInWithTokens({ accessToken,
refreshToken: "" })`) on a timer (capped by
`RDE_ACCESS_TOKEN_MAX_AGE_MS`).

`InternalSession.calculateSessionKey` keyed access-only sessions by the
**access-token string**:

```ts
} else if (ofTokens.accessToken) {
  return `access-${ofTokens.accessToken}`;   // 👈 changes on every refresh
}
```

So each refresh = a new key = a brand-new `InternalSession` object.
Every session-scoped cache (`useUser` / `useConfig` / `useTeams` /
`useOwnedProjects`, via `createCacheBySession`) is keyed by the
**session object**, so a new object means a cold cache → pending promise
→ `React.use()` suspends → the whole tree falls back to its (empty)
Suspense boundary.

It only *shows* in RDE because the backend is remote: the post-swap
refetch has real network latency, so the blank is visible for hundreds
of ms. On localhost the same swap is a sub-frame flicker. (A background
`refresh()`/write-only is stale-preserving and does **not** suspend —
only a new session dependency does.)

## Fix

Two changes in the SDK source (`packages/shared` + `packages/template`;
the `js`/`next`/`react`/`tanstack-start` copies are generated):

1. **Stable key for access-only sessions.** Key by the token's
`refresh_token_id` (decoded from the JWT) instead of the raw token
string. Every access token minted for the same session shares that id,
so the session identity — and therefore every cache — stays stable
across refreshes. Falls back to the raw token if the JWT can't be
decoded. Refresh-keyed and not-logged-in paths are untouched.

2. **In-place token update.** New
`InternalSession.updateAccessToken(token)`, called from
`_signInToAccountWithTokens`, pushes the fresh token into the reused
session object instead of constructing a new one (no-op when the session
is invalid / the token is unchanged / null).

Net effect: re-minting the RDE access token reuses the same
`InternalSession`, caches stay warm, nothing suspends, no blank.

## Why this is safe

- Session reuse is scoped **per token store** —
`_sessionsByTokenStoreAndSessionKey` is a `WeakMap` keyed by the
token-store object first, then the session key — so server-side
per-request sessions remain isolated regardless of how coarse the key
is. No cross-user/cross-session mixup.
- `refresh_token_id` is a per-session UUID; the coarser key only merges
*the same session's* successive access tokens, which is the intent.
- This keying convention matches the existing `refresh-${refreshToken}`
path (key by the unique token value).

## Testing

- **Reproduced live** via a temporary harness driven through a real
browser: forcing the session-identity swap triggered the exact
cold-cache refetch storm (`useUser`/`useTeams`/`useOwnedProjects`
refetching) that produces the blank.
- **Unit-verified** the new behavior against the built `shared` dist:
two access tokens sharing a `refresh_token_id` → same session key;
different ids → different keys; opaque token → fallback; refresh-keyed
unchanged; `updateAccessToken` swaps the token in place and is a correct
no-op when invalid/unchanged/null.
- **Typecheck + lint clean** across `shared`, `template`, `next`,
`react`, `tanstack-start`, and the dashboard.
- Reviewed by independent passes for correctness, security/blast-radius,
and simplification — no actionable findings.

## How to verify in the real RDE path

Set `RDE_ACCESS_TOKEN_MAX_AGE_MS` to e.g. `5000` in the auth gate and
run `hexclave dev`: before this change the dashboard blanks every few
seconds; after, it stays populated.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Stops the RDE dashboard from going blank every 30–60s by keeping session
identity stable during access‑token refreshes. Session-scoped caches
stay warm, so the UI no longer suspends.

- **Bug Fixes**
- Key access-only sessions by the JWT `refresh_token_id` (stable across
re‑mints); fall back to the raw token if undecodable. Implemented in
`packages/shared`; tests in `packages/shared/src/sessions.test.ts`.
- Add `InternalSession.updateAccessToken()` and use it in
`_signInToAccountWithTokens` to update the token in place only when the
incoming pair resolves to the same `sessionKey` (rejects
foreign/null/unchanged/undecodable; covers access‑only and
refresh‑backed sessions). Prefetch the current user via
`runAsynchronously` in write‑only mode. Implemented in `packages/shared`
and `packages/template`.

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

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1566?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://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**
* Improved session stability and token management to enhance
authentication reliability.
* Strengthened session validation to prevent stale token-related issues.

* **Tests**
* Added comprehensive test coverage for session and token handling
mechanisms.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-10 11:13:33 -07:00
BilalG1
0fb0e2d10d
docs(skill): document analytics: { enabled: false } opt-out (#1562)
## What

Documents the `analytics: { enabled: false }` client-app option across
the skill site and docs, so users/agents know how to opt out of
SDK-managed analytics.

Passing `analytics: { enabled: false }` to `HexclaveClientApp`:
- stops the SDK from auto-capturing `$page-view` / `$click` events, and
- silences the `ANALYTICS_NOT_ENABLED` console warning the SDK logs
every flush when it sends events to a project that hasn't enabled the
Analytics app (disabled by default on new projects).

## Why

On a new project, analytics is off by default but the client event
tracker still auto-starts, so every end-user browser logs a recurring
`ANALYTICS_NOT_ENABLED` warning. This is a docs-only change telling
people how to turn capture off; it does **not** change SDK behavior.

## Changes

Hand-edited:
-
`packages/shared/src/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.ts`
— adds a one-line `<Note>` to the client-app setup step (this is the
skill.hexclave.com source).
- `docs-mintlify/guides/apps/analytics/overview.mdx` — new "Disabling
Analytics Capture in the SDK" section.
- `docs-mintlify/sdk/objects/hexclave-app.mdx` — documents the
`analytics` constructor param.

Auto-generated from the prompt (`pnpm run generate-setup-prompt-docs`):
- `docs-mintlify/guides/getting-started/setup.mdx`,
`docs-mintlify/llms-full.txt`,
`docs-mintlify/snippets/home-prompt-island.jsx`

## Notes

- Phrased as an opt-out hint, not baked into the default snippet (so
analytics stays on-by-default for new setups).
- Independent of #1561 (projectId/`import.meta.env`); branched off `dev`
with no overlap.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Documented `analytics: { enabled: false }` for `HexclaveClientApp`
across the setup guides, analytics overview, and SDK reference to let
teams opt out of SDK-managed analytics. This disables
`$page-view`/`$click` capture and silences the `ANALYTICS_NOT_ENABLED`
console warning on projects without the Analytics app.

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

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

* **Documentation**
* Added guidance for disabling SDK analytics capture via analytics: {
enabled: false }.
* Clarified that the SDK auto-captures page-view and click analytics by
default in setup guides.
* Noted that disabling analytics suppresses the ANALYTICS_NOT_ENABLED
console warning.
* Updated SDK reference docs to include the optional analytics
configuration in client app setup.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-10 11:13:19 -07:00
github-actions[bot]
3132de1cae chore: update package versions 2026-06-10 18:10:23 +00:00
Konstantin Wohlwend
dbb397dcbc Home URL should be non-hosted 2026-06-08 18:23:57 -07:00
Konstantin Wohlwend
48f498b416 Update reminders with info on urls option 2026-06-08 12:33:56 -07:00
github-actions[bot]
96273a9d65 chore: update package versions 2026-06-08 18:18:54 +00:00
Konstantin Wohlwend
9b4c1957dd Add extra hint on envvars to the local setup 2026-06-08 11:10:40 -07:00
github-actions[bot]
4fdd2b3831 chore: update package versions 2026-06-08 17:36:50 +00:00
Konstantin Wohlwend
60202f2b09 Fix build 2026-06-08 10:29:42 -07:00
Konstantin Wohlwend
3e2f0f9558 Fix infinite loop bug in TanStack Start demo
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-05 17:20:36 -07:00
github-actions[bot]
468a221379 chore: update package versions 2026-06-06 00:07:24 +00:00
Konstantin Wohlwend
8b6961eed7 Update changelog 2026-06-05 17:04:29 -07:00
Konsti Wohlwend
0cb11ae6cf
Add "For AI agents" section to README (#1563) 2026-06-05 17:01:13 -07:00
github-actions[bot]
461b9acd68 chore: update package versions 2026-06-05 23:54:49 +00:00
Konstantin Wohlwend
10f8348b51 Fix Vite environment variables 2026-06-05 16:42:11 -07:00
Konsti Wohlwend
0c07b4b44e Show browser alert for missing Hexclave project ID 2026-06-05 12:29:12 -07:00
Armaan Jain
b246e4ab65
Consistency and design changes light mode (#1500)
# PR #1500 Visual Writeup


Visual assets hosted in [this
gist](https://gist.github.com/b0c1d3d072a71e30b65380f8b2cf53a1).

- Base: `dev`
- Head: `Consistency-and-design-changes-light-mode`
- Dashboard dev server: `http://localhost:8101`
- Viewport: `1920x1200`
- Screenshots: `74` referenced (`18` surfaces x `2` themes x
`before/after`, plus the attached Conversations create-dialog pair)
- Red outlines appear only on **after** screenshots to mark the changed
surface.

## Summary

This PR refreshes light-mode consistency across dashboard surfaces and
adds a dashboard-only Account Settings implementation. The screenshots
below compare the base branch against the PR branch for every changed
dashboard route/surface included in the scope.

## Screenshot Matrix

### Account Settings - Profile

Dashboard-only profile page redesign against the previous Stack handler
page.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![account-profile-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-profile-before-light.png)
|
![account-profile-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-profile-after-light.png)
|
| Dark |
![account-profile-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-profile-before-dark.png)
|
![account-profile-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-profile-after-dark.png)
|

### Account Settings - Emails & Auth

Email, password, passkey, OTP, and MFA settings shell.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![account-emails-auth-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-emails-auth-before-light.png)
|
![account-emails-auth-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-emails-auth-after-light.png)
|
| Dark |
![account-emails-auth-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-emails-auth-before-dark.png)
|
![account-emails-auth-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-emails-auth-after-dark.png)
|

### Account Settings - Notifications

Notification preferences styling.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![account-notifications-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-notifications-before-light.png)
|
![account-notifications-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-notifications-after-light.png)
|
| Dark |
![account-notifications-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-notifications-before-dark.png)
|
![account-notifications-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-notifications-after-dark.png)
|

### Account Settings - Active Sessions

Active session table and action styling.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![account-sessions-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-sessions-before-light.png)
|
![account-sessions-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-sessions-after-light.png)
|
| Dark |
![account-sessions-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-sessions-before-dark.png)
|
![account-sessions-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-sessions-after-dark.png)
|

### Account Settings - Payments

Billing surface and account/team billing selector.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![account-payments-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-payments-before-light.png)
|
![account-payments-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-payments-after-light.png)
|
| Dark |
![account-payments-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-payments-before-dark.png)
|
![account-payments-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-payments-after-dark.png)
|

### Account Settings - Settings

Sign out and account deletion settings.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![account-settings-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-settings-before-light.png)
|
![account-settings-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-settings-after-light.png)
|
| Dark |
![account-settings-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-settings-before-dark.png)
|
![account-settings-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-settings-after-dark.png)
|

### Account Settings - Team

Team profile, members, and leave-team sections.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![account-team-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-team-before-light.png)
|
![account-team-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-team-after-light.png)
|
| Dark |
![account-team-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-team-before-dark.png)
|
![account-team-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-team-after-dark.png)
|

### Account Settings - Create Team

Team creation form.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![account-team-create-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-team-create-before-light.png)
|
![account-team-create-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-team-create-after-light.png)
|
| Dark |
![account-team-create-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-team-create-before-dark.png)
|
![account-team-create-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/account-team-create-after-dark.png)
|

### Analytics Queries

Touched analytics query page surface.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![analytics-queries-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/analytics-queries-before-light.png)
|
![analytics-queries-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/analytics-queries-after-light.png)
|
| Dark |
![analytics-queries-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/analytics-queries-before-dark.png)
|
![analytics-queries-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/analytics-queries-after-dark.png)
|

### Analytics Tables

Analytics table/query controls and data-grid surface.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![analytics-tables-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/analytics-tables-before-light.png)
|
![analytics-tables-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/analytics-tables-after-light.png)
|
| Dark |
![analytics-tables-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/analytics-tables-before-dark.png)
|
![analytics-tables-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/analytics-tables-after-dark.png)
|

### Auth Methods

Authentication method configuration surface.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![auth-methods-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/auth-methods-before-light.png)
|
![auth-methods-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/auth-methods-after-light.png)
|
| Dark |
![auth-methods-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/auth-methods-before-dark.png)
|
![auth-methods-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/auth-methods-after-dark.png)
|

### Conversations

Support conversation UI surface.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![conversations-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/conversations-before-light.png)
|
![conversations-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/conversations-after-light.png)
|
| Dark |
![conversations-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/conversations-before-dark.png)
|
![conversations-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/conversations-after-dark.png)
|

#### Conversations - Create Dialog

Attached screenshots for the create conversation dialog.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![conversations-dialog-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/conversations-dialog-before-light.png)
|
![conversations-dialog-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/conversations-dialog-after-light.png)
|

### Domains

Trusted domains alert/card styling.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![domains-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/domains-before-light.png)
|
![domains-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/domains-after-light.png)
|
| Dark |
![domains-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/domains-before-dark.png)
|
![domains-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/domains-after-dark.png)
|

### Email Sent

Sent email and reputation card styling.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![email-sent-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/email-sent-before-light.png)
|
![email-sent-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/email-sent-after-light.png)
|
| Dark |
![email-sent-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/email-sent-before-dark.png)
|
![email-sent-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/email-sent-after-dark.png)
|

### Launch Checklist

Launch checklist page surface.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![launch-checklist-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/launch-checklist-before-light.png)
|
![launch-checklist-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/launch-checklist-after-light.png)
|
| Dark |
![launch-checklist-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/launch-checklist-before-dark.png)
|
![launch-checklist-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/launch-checklist-after-dark.png)
|

### Payment Products

Products/items payment page surface.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![payments-products-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/payments-products-before-light.png)
|
![payments-products-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/payments-products-after-light.png)
|
| Dark |
![payments-products-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/payments-products-before-dark.png)
|
![payments-products-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/payments-products-after-dark.png)
|

### Session Replays

Session replay page layout.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![session-replays-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/session-replays-before-light.png)
|
![session-replays-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/session-replays-after-light.png)
|
| Dark |
![session-replays-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/session-replays-before-dark.png)
|
![session-replays-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/session-replays-after-dark.png)
|

### Sign-up Rules

Sign-up rules page surface.

| Theme | Before | After |
| --- | --- | --- |
| Light |
![sign-up-rules-before-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/sign-up-rules-before-light.png)
|
![sign-up-rules-after-light.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/sign-up-rules-after-light.png)
|
| Dark |
![sign-up-rules-before-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/sign-up-rules-before-dark.png)
|
![sign-up-rules-after-dark.png](https://gist.githubusercontent.com/Developing-Gamer/b0c1d3d072a71e30b65380f8b2cf53a1/raw/sign-up-rules-after-dark.png)
|


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

## Summary by CodeRabbit

## Release Notes

* **New Features**
* Added comprehensive account settings dashboard with profile
management, email and authentication settings, active sessions
monitoring, API key generation and management, payment methods,
notification preferences, and team creation/management.
* Introduced user profile image editing with circular cropping and
compression.
  * Added multi-factor authentication (MFA) setup via TOTP QR codes.
  * Enabled team-based API key management and team member invitations.

* **Design Improvements**
* Refined UI styling across analytics, forms, and dialogs for better
visual hierarchy.
  * Enhanced dark mode support throughout dashboard components.
  * Improved responsive layouts and spacing on dashboard pages.

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

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-05 10:57:13 -07:00
Armaan Jain
b0cfeb5fb9
Payments checkout page redesign (#1536)
## Summary

This PR redesigns the payments checkout experience around a cleaner
split-panel purchase flow, clearer pricing selection, and more focused
terminal states for successful and invalid purchase links.

The new UI reduces visual noise, makes the selected plan and total
amount easier to scan, and keeps test-mode bypass behavior explicit
without overwhelming the checkout form.

## Visual Review

### Checkout Flow

| Before | After |
| --- | --- |
| ![Checkout before, dark
yearly](cc77e112e8/checkout-after-dark-yearly.png)
| ![Checkout after, dark
yearly](73d059fec2/checkout-before-dark-yearly.png)
|
| ![Checkout before, dark
one-time](ddb9530961/checkout-after-dark-onetime.png)
| ![Checkout after, dark
one-time](1628aee6dc/checkout-before-dark-onetime.png)
|
| ![Checkout before,
light](47ed5f6c35/checkout-after-light.png)
| ![Checkout after,
light](3b2956ef85/checkout-before-light.png)
|

### Purchase Result States

| Before | After |
| --- | --- |
| ![Success
before](a1a7a9123f/success-after-dark.png)
| ![Success
after](7cc59b1031/success-before-dark.png)
|
| ![Invalid code
before](0bb0854811/invalid-code-after-dark.png)
| ![Invalid code
after](442c33fecf/invalid-code-before-dark.png)
|

## What's Changed

- Introduces a more focused checkout layout with clearer plan selection,
pricing, quantity controls, and total amount display.
- Improves test-mode purchase handling with a dedicated bypass action
that is visually separate from the pricing controls.
- Polishes purchase result screens so success and invalid-code states
feel intentional and consistent with the checkout surface.
- Improves supporting dashboard flows for checkout URL creation and
product included-item handling.

## Notes For Reviewers

- The screenshots above are the supplied before/after captures for the
main changed surfaces.
- The checkout screenshots cover dark mode, light mode, recurring
pricing, and one-time pricing.
- The result-state screenshots cover both successful test purchases and
invalid/expired purchase codes.

## Test Plan

- Verified checkout UI in dark and light mode.
- Verified yearly and one-time price selection display.
- Verified test-mode purchase completion state.
- Verified invalid purchase-code state.
- Ran dashboard lint locally.



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

* **New Features**
* Redesigned purchase flow with dedicated price options and quantity
selector
  * New payment UI cards and a Payments Not Enabled card
* Create checkout URL dialog and inline "Create Item" action for
products

* **Improvements**
* Clearer subscription interval and price labeling; improved free-price
detection
  * Return and checkout pages restyled to design system components
* Select dropdown positioning/height and trigger accessibility improved

* **Bug Fixes**
* Safer item display and validation/error messaging during purchase
flows
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-05 10:08:33 -07:00
BilalG1
1cbbd5a4e2
fix(ai-prompt): show <html>/<body> shell in Next.js layout setup example (#1558)
## Problem

A user setting up Hexclave in a new Next.js project with a coding agent
hit:

> **HexclaveTheme error:** Cannot render a `<style>` outside the main
document without knowing its precedence and a unique href key...

The agent eventually fixed it by moving
`HexclaveProvider`/`HexclaveTheme` from *wrapping* the `<html>` tag to
*inside* it.

## Root cause

The Next.js `layout.tsx` example in the setup prompt
([`ai-setup-prompt.ts`](packages/shared/src/ai/unified-prompts/skill-site-prompt-parts/ai-setup-prompt.ts))
returned **just** the providers, with no `<html>`/`<body>`:

```tsx
export default function RootLayout({ children }) {
  return (
    <HexclaveProvider app={hexclaveServerApp}>
      <HexclaveTheme>{children}</HexclaveTheme>
    </HexclaveProvider>
  );
}
```

But a Next.js root layout is [**required** to render `<html>` and
`<body>`](https://nextjs.org/docs/app/api-reference/file-conventions/layout).
When an agent reconciles this incomplete snippet with an existing
layout, the snippet shows the providers as the outermost element — so it
wraps the existing `<html>` with them. That puts `HexclaveTheme`'s
hoisted `<style>` outside the document, which React refuses to render →
the error above.

Every other framework example in the prompt is complete (the TanStack
Start one explicitly separates the `<html>`/`<body>` shell from the
providers); only the Next.js one was ambiguous.

## Fix

- Show the full document shell with the providers nested **inside
`<body>`**.
- Add an explicit note: the root layout must render `<html>`/`<body>`,
and the providers must go inside `<body>` — do not wrap `<html>`.
- Drop the unused `Suspense` import (Suspense is covered in the separate
boundary step; per the Next.js docs you should not add `<head>`
manually, so the example stays minimal).
- Regenerated `setup.mdx`, `llms-full.txt`, and the agent-reminder
snippets from the prompt source.

This source feeds the CLI `init` prompt, `skill.hexclave.com`
(`llms-full.txt`), and the generated docs, so the fix propagates
everywhere.

## Verification

- `turbo run typecheck` — `@hexclave/shared` and all other packages
pass. (3 pre-existing failures in
`dashboard`/`example-demo-app`/`internal-tool` are stale `.next`
validators referencing the old `[...stack]` route name, unrelated to
this change.)
- `turbo run lint` — `@hexclave/shared` and `@hexclave/docs-mintlify`
pass.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes the Next.js layout example in the setup prompt to include the
required <html>/<body> shell and place
`HexclaveProvider`/`HexclaveTheme` inside `<body>`, preventing the React
style-outside-document error. Also makes the warning before the example
a clear, complete sentence that leads into the correct setup.

- **Bug Fixes**
- Updated Next.js example in `ai-setup-prompt.ts` to render
`<html>`/`<body>` and nest providers inside `<body>`; added a clear “do
not wrap `<html>`” note.
- Reworded the warning before the example to end as a full sentence and
introduce the correct snippet.
  - Removed unused `Suspense` import.
- Regenerated `docs-mintlify/guides/getting-started/setup.mdx`,
`docs-mintlify/llms-full.txt`, and snippets (home prompt island, agent
reminders) to propagate the change.

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

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

* **Documentation**
* Updated React/Next.js setup instructions to clarify proper HTML
structure configuration and component provider placement for improved
compatibility.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Konsti Wohlwend <n2d4xc@gmail.com>
2026-06-05 10:07:59 -07:00
Konstantin Wohlwend
c60016226b Fix nested cross-domain OAuth edge case 2026-06-04 18:26:44 -07:00
Konstantin Wohlwend
8b78587dac Fix handler sign out 2026-06-04 17:59:00 -07:00
Konstantin Wohlwend
1d8babb0e1 Better UX around hosted component errors 2026-06-04 17:27:04 -07:00
github-actions[bot]
5cb50721bd chore: update package versions 2026-06-05 00:16:17 +00:00
Konstantin Wohlwend
4789af4674 Remove unnecessary whitespace 2026-06-04 17:01:23 -07:00
Konstantin Wohlwend
ad1a08dc04 Add title to README.md 2026-06-04 16:57:58 -07:00
Konsti Wohlwend
bc45117777
Support local dashboard in remote SSH and GH Codespaces (#1538) 2026-06-04 16:36:17 -07:00
Konsti Wohlwend
14d04be0ba
Clarify that product prices are decimal strings, not cent integers (#1554) 2026-06-04 16:21:47 -07:00
Konstantin Wohlwend
c3b043ef1e Log project ID with every request 2026-06-04 15:57:55 -07:00
Konstantin Wohlwend
c80b087316 Self-wrap TooltipProvider 2026-06-04 11:19:41 -07:00
Konstantin Wohlwend
3c19e173e0 Fix tooltip error 2026-06-04 11:01:56 -07:00
Konstantin Wohlwend
229d7ae187 Update pre-push.md 2026-06-04 10:44:39 -07:00
Konstantin Wohlwend
1ccea63a3c Update reminders to be returned verbatim 2026-06-04 10:24:19 -07:00
BilalG1
41942fcfc1
feat(cli): auto-update RDE dashboard via npx re-exec on stack dev (#1521)
## What & why

Re-running `stack dev` / `hexclave dev` now picks up the **latest
published dashboard without reinstalling the CLI**.

In the RDE, the dashboard is a Next.js standalone build **bundled into
the `@hexclave/cli` npm tarball** — so a dashboard change only reaches a
user when they get a newer CLI *version*. This PR closes that gap for
the recommended `stack dev` flow.

## How it works

1. **npx self-re-exec** — at the top of the `dev` action, the CLI checks
npm for a newer `@hexclave/cli`. If found, it re-execs `npx --yes -p
@hexclave/cli@<latest> stack dev <your args>` (with a loop guard) and
exits with the child's code. The running code — and the dashboard
bundled in that tarball — is now the latest; the user's installed
devDependency is untouched. npx caches per version, so steady-state runs
are fast.

2. **Dashboard version handshake** (the necessary second half) — `stack
dev` keeps a **detached background dashboard** alive across runs and
reuses it by default, which would otherwise silently defeat the update.
The now-latest process compares the running dashboard's version
(persisted in dev-env state) against its own and **kills + restarts**
the stale one (SIGTERM → wait → SIGKILL) so the new dashboard actually
binds `:26700`. Equal/older/unknown versions are reused exactly as
before.

## Safety / opt-outs

- Skipped for the re-exec'd child (`STACK_CLI_SKIP_AUTO_UPDATE`, loop
guard), when the user opts out (`STACK_CLI_NO_AUTO_UPDATE` /
`--no-auto-update`), and in CI (`CI`).
- Registry lookup is TTL-cached in dev-env state with a short timeout
and is **offline-safe** — any failure (no network, no npx) falls through
to the installed CLI.
- `isVersionNewer` never downgrades and returns false for unparseable
versions.

## Changes

- **`packages/stack-cli/src/lib/self-update.ts`** (new) —
`maybeReexecToLatest()`, `resolveLatestVersion()`, `isVersionNewer()`,
`buildNpxInvocation()`.
- **`packages/stack-cli/src/commands/dev.ts`** — re-exec wiring,
`killLocalDashboard()`, version handshake, `--no-auto-update` flag,
version stamp on the recorded dashboard process.
- **`packages/stack-cli/src/lib/dev-env-state.ts`** —
`localDashboard.version` + `cliUpdateCheck` cache helpers.
- Tests: new `self-update.test.ts` + additions to
`dev-env-state.test.ts`.

## Verification

- `pnpm --filter @hexclave/cli run lint` 
- `pnpm --filter @hexclave/cli run typecheck` 
- `pnpm --filter @hexclave/cli run test`  (132 passed)

## Prerequisite

Relies on `@hexclave/cli` being published to npm with the `latest`
dist-tag tracking releases — otherwise the check is a no-op (which is
safe).

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
`hexclave dev` now re-execs via `npx` to run the latest `@hexclave/cli`,
so the bundled RDE dashboard stays current without reinstalling. It
reuses the running dashboard and only restarts it when the current CLI
is strictly newer.

- **New Features**
- Auto-update: always re-execs `npx --yes --min-release-age=0 -p
@hexclave/cli@latest hexclave dev ...`; runs in CI; opt out with
`--no-auto-update` or `STACK_CLI_NO_AUTO_UPDATE=1`.
- Per-port dashboard version handshake: records the CLI version per port
and restarts only when strictly newer; otherwise reuses it (respects
`NEXT_PUBLIC_HEXCLAVE_LOCAL_DASHBOARD_PORT`).

- **Bug Fixes**
- Safer restarts: after SIGTERM, wait for the port to free instead of
pid probes; bail on ESRCH/EPERM; only SIGKILL if the port still answers.
- Robust execution: ship a single `hexclave` bin (fixes `pnpx`/`pnpm
dlx`), forward SIGINT/SIGTERM to children, validate per-port dashboard
state, update help/messages to `hexclave`, and make Windows re-exec
reliable (`npx.cmd` with shell and argv quoting).

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

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1521?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://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**
* CLI can auto-check and re-exec to a pinned newer release (opt-out:
--no-auto-update).
* Local dashboard startup is version-aware and only restarts when the
CLI is strictly newer.
  * Improved child-process signal forwarding for cleaner shutdowns.

* **Tests**
* Expanded unit tests covering dev workflow, self-update, package
metadata, persistence, and dashboard lifecycle.

* **Bug Fixes**
  * Updated user-facing CLI messaging to use "hexclave" command names.

* **Chores**
  * Removed legacy docs workspace entry.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Konstantin Wohlwend <n2d4xc@gmail.com>
2026-06-04 09:01:00 -07:00