From 501ae9fe61c56c85322b4eab25fe50340b3c1b44 Mon Sep 17 00:00:00 2001 From: BilalG1 Date: Wed, 3 Jun 2026 12:09:20 -0700 Subject: [PATCH] PR 4: Rename Stack -> Hexclave: examples config module, app-internal symbols, crypto docs (#1534) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What Continues the **Stack Auth → Hexclave** rename for a set of safe, internal-only surfaces. This intentionally avoids public-contract names. ### Changes - **Examples** — renamed the user-facing config module `stack.ts`/`stack.tsx` (and the `convex` / `lovable` `stack/` directories) to `hexclave`, and updated every importer across `.ts`/`.tsx`/`.jsx`. The public `app/handler/[...stack]/` route segment is left unchanged. - **apps/{dashboard,backend,internal-tool}** — renamed app-local SDK-init symbols `stackClientApp → hexclaveClientApp` and `getStackServerApp → getHexclaveServerApp`, and the dashboard `StackCompanion` component → `HexclaveCompanion` (incl. `useStackCompanion`, context types). The public `StackClientApp`/`StackServerApp` SDK classes are **unchanged**. - **packages/stack-shared** — added comments to the crypto / JWT / vault `stack-*` literals documenting that they must **not** be renamed (key derivation / JWKS / KMS-alias stability). The literals are byte-identical. ### Deliberately excluded - **`STACK_*` → `HEXCLAVE_*` env-var rename** — `HEXCLAVE_*` already resolves via the dual-read layers (SDK env, dashboard `_inlineEnvVars`, `getEnvVariable`). The remaining holdout is the docker post-build sentinel path, which the codebase authors explicitly deferred and which is tightly coupled to `entrypoint.sh` + untestable here. A blind rename there risks silently breaking self-host/emulator bootstrap for ~zero functional gain. - **All public-contract names** — SDK class names, env vars, HTTP headers (`x-stack-*`), and the `/handler` route convention. ## Verification - `pnpm lint` — **29/29 passing**. - `pnpm typecheck` — **28/29 passing**; the only failure is `@hexclave/docs` (pre-existing missing fumadocs `.source` codegen, untouched by this PR). - Two rounds of adversarial multi-agent review; findings fixed: string-literal collateral from the symbol sweep (CLI test fixtures + an AI-prompt template) reverted, and a missed `.jsx` importer in `examples/cjs-test` corrected. ## Notes - Based on a `dev` snapshot from when the branch was cut (a couple commits behind tip); the diff contains only the changes above. --- ## Summary by cubic Complete the internal “Stack” → “Hexclave” rename across examples, app-local code, config tooling, and setup docs, and standardize env output to HEXCLAVE_* with correct default API URL handling. Public SDK classes, handler routes, and legacy env names keep working. - **Refactors** - Examples/config: `stack.*` files and `stack/` dirs → `hexclave.*`/`hexclave/`; imports updated; keep `app/handler/[...stack]` route. - Apps: backend/dashboard/internal-tool now use `getHexclaveServerApp` and `hexclaveClientApp`; dashboard `StackCompanion` → `HexclaveCompanion`. Public `StackClientApp`/`StackServerApp` unchanged. - Env/setup: Next.js and CLI generators write HEXCLAVE_* and omit API URL when using https://api.stack-auth.com; CLI `doctor` and auth resolution prefer HEXCLAVE_* (e.g. `HEXCLAVE_SECRET_SERVER_KEY`, `HEXCLAVE_PROJECT_ID`) with `STACK_*` fallback. - Config tooling: `stack-config-file` → `hexclave-config-file`, emitting `HexclaveConfig`; imports updated across backend/dashboard/tooling. - Shared/docs: added “do not rename” notes for crypto/JWT/vault `stack-*` literals; regenerated setup prompt/docs to use `hexclave.config.ts`, `hexclave dev`, and `src/hexclave/`. - Tests: updated snapshots/assertions to expect `HexclaveConfig` and HEXCLAVE_* env names. - **Migration** - No action required. SDK and CLI read both HEXCLAVE_* and STACK_*. Written for commit 8a891b4f6cd880a523851e654455ca352982f80b. Summary will update on new commits. Review in cubic ## Summary by CodeRabbit * **Refactor** * Renamed internal app/client/server instances and companion/provider components to the new product name across backend, dashboard, examples, and tooling; imports updated accordingly. * Updated generated environment variable names and CLI init/doctor outputs to prefer the new product prefix. * **Documentation** * Added clarifying notes about vault/encryption and JWT/key labels to avoid breaking existing encrypted data. --- .../latest/analytics/events/batch/route.tsx | 4 +- .../latest/internal/analytics/query/route.ts | 4 +- .../latest/internal/send-test-email/route.tsx | 4 +- .../latest/session-replays/batch/route.tsx | 4 +- apps/backend/src/lib/email-queue-step.tsx | 4 +- apps/backend/src/lib/events.tsx | 4 +- apps/backend/src/lib/local-emulator.test.ts | 4 +- apps/backend/src/lib/local-emulator.ts | 2 +- apps/backend/src/stack.tsx | 2 +- .../(outside-dashboard)/projects/actions.ts | 2 +- .../projects/[projectId]/sidebar-layout.tsx | 4 +- .../integrations/featurebase/sso/page.tsx | 4 +- .../integrations/oauth-confirm-page.tsx | 4 +- apps/dashboard/src/app/layout-client.tsx | 4 +- apps/dashboard/src/components/env-keys.tsx | 12 +- .../src/components/stack-companion.tsx | 18 +- .../src/lib/github-config-push.test.ts | 56 +++--- apps/dashboard/src/lib/github-config-push.ts | 2 +- .../config-file.test.ts | 4 +- apps/dashboard/src/lib/version-check.ts | 2 +- apps/dashboard/src/stack/client.tsx | 2 +- apps/dashboard/src/stack/server.tsx | 6 +- .../v1/internal/config-local-emulator.test.ts | 4 +- apps/e2e/tests/general/cli.test.ts | 20 +- apps/internal-tool/src/app/layout.tsx | 4 +- apps/internal-tool/src/stack.ts | 2 +- .../guides/getting-started/setup.mdx | 190 +++++++++--------- docs-mintlify/llms-full.txt | 56 +++--- docs-mintlify/snippets/home-prompt-island.jsx | 2 +- .../cjs-test/app/handler/[...stack]/page.jsx | 2 +- examples/cjs-test/app/layout.tsx | 2 +- examples/cjs-test/{stack.tsx => hexclave.tsx} | 0 .../convex/app/handler/[...stack]/page.tsx | 2 +- examples/convex/app/layout.tsx | 2 +- examples/convex/app/server/page.tsx | 2 +- examples/convex/app/user-info.ts | 2 +- .../components/ConvexClientProvider.tsx | 2 +- examples/convex/convex/myActions.ts | 2 +- examples/convex/convex/myFunctions.ts | 4 +- .../convex/{stack => hexclave}/client.tsx | 0 .../convex/{stack => hexclave}/server.tsx | 0 .../demo/src/app/apikey-demo/api/route.ts | 2 +- examples/demo/src/app/fallback-test/page.tsx | 2 +- .../demo/src/app/handler/[...stack]/page.tsx | 2 +- examples/demo/src/app/layout.tsx | 2 +- .../payments-demo/api/config-check/route.ts | 2 +- .../api/create-checkout-url/route.ts | 2 +- .../api/send-test-email/route.ts | 2 +- examples/demo/src/app/protected/page.tsx | 2 +- examples/demo/src/app/spotify-server/page.tsx | 2 +- examples/demo/src/{stack.tsx => hexclave.tsx} | 0 .../src/app/handler/[...stack]/page.tsx | 2 +- examples/docs-examples/src/app/layout.tsx | 2 +- .../src/{stack.tsx => hexclave.tsx} | 0 .../e-commerce/src/app/edit-shop/page.tsx | 2 +- .../src/app/handler/[...stack]/page.tsx | 2 +- examples/e-commerce/src/app/layout.tsx | 2 +- examples/e-commerce/src/app/page.tsx | 2 +- .../src/{stack.tsx => hexclave.tsx} | 0 examples/js-example/{stack.ts => hexclave.ts} | 0 examples/js-example/index-script.ts | 2 +- examples/js-example/oauth-script.ts | 2 +- examples/js-example/otp-sign-in-script.ts | 2 +- .../js-example/password-sign-in-script.ts | 2 +- .../js-example/password-sign-up-script.ts | 2 +- examples/lovable-react-18-example/src/App.tsx | 2 +- .../src/{stack => hexclave}/client.ts | 0 .../src/app/handler/[...stack]/page.tsx | 2 +- examples/middleware/src/app/layout.tsx | 2 +- examples/middleware/src/app/page.tsx | 2 +- .../middleware/src/app/protected/page.tsx | 2 +- .../src/{stack.tsx => hexclave.tsx} | 0 examples/middleware/src/middleware.tsx | 2 +- examples/react-example/src/App.tsx | 2 +- .../src/{stack.ts => hexclave.ts} | 0 .../supabase/app/handler/[...stack]/page.tsx | 2 +- examples/supabase/app/layout.tsx | 2 +- examples/supabase/{stack.tsx => hexclave.tsx} | 0 examples/supabase/utils/actions.ts | 2 +- .../src/{stack.ts => hexclave.ts} | 0 .../tanstack-start-demo/src/routes/__root.tsx | 2 +- packages/stack-cli/src/commands/doctor.ts | 19 +- packages/stack-cli/src/commands/init.ts | 6 +- packages/stack-cli/src/lib/auth.test.ts | 6 +- packages/stack-cli/src/lib/auth.ts | 11 +- .../ai-setup-prompt.ts | 58 +++--- packages/stack-shared/src/config-rendering.ts | 14 +- .../src/helpers/vault/client-side.ts | 3 + .../src/helpers/vault/server-side.ts | 5 + ...config-file.ts => hexclave-config-file.ts} | 4 +- packages/stack-shared/src/utils/crypto.tsx | 6 + packages/stack-shared/src/utils/jwt.tsx | 3 + 92 files changed, 335 insertions(+), 312 deletions(-) rename examples/cjs-test/{stack.tsx => hexclave.tsx} (100%) rename examples/convex/{stack => hexclave}/client.tsx (100%) rename examples/convex/{stack => hexclave}/server.tsx (100%) rename examples/demo/src/{stack.tsx => hexclave.tsx} (100%) rename examples/docs-examples/src/{stack.tsx => hexclave.tsx} (100%) rename examples/e-commerce/src/{stack.tsx => hexclave.tsx} (100%) rename examples/js-example/{stack.ts => hexclave.ts} (100%) rename examples/lovable-react-18-example/src/{stack => hexclave}/client.ts (100%) rename examples/middleware/src/{stack.tsx => hexclave.tsx} (100%) rename examples/react-example/src/{stack.ts => hexclave.ts} (100%) rename examples/supabase/{stack.tsx => hexclave.tsx} (100%) rename examples/tanstack-start-demo/src/{stack.ts => hexclave.ts} (100%) rename packages/stack-shared/src/{stack-config-file.ts => hexclave-config-file.ts} (96%) diff --git a/apps/backend/src/app/api/latest/analytics/events/batch/route.tsx b/apps/backend/src/app/api/latest/analytics/events/batch/route.tsx index c94df8204..79e6c9013 100644 --- a/apps/backend/src/app/api/latest/analytics/events/batch/route.tsx +++ b/apps/backend/src/app/api/latest/analytics/events/batch/route.tsx @@ -1,7 +1,7 @@ import { getClickhouseAdminClient } from "@/lib/clickhouse"; import { arePlanLimitsEnforced, getBillingTeamId } from "@/lib/plan-entitlements"; import { findRecentSessionReplay } from "@/lib/session-replays"; -import { getStackServerApp } from "@/stack"; +import { getHexclaveServerApp } from "@/stack"; import { getPrismaClientForTenancy } from "@/prisma-client"; import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler"; import { KnownErrors } from "@hexclave/shared"; @@ -118,7 +118,7 @@ export const POST = createSmartRouteHandler({ const refreshTokenId = auth.refreshTokenId; const tenancyId = auth.tenancy.id; - const app = getStackServerApp(); + const app = getHexclaveServerApp(); const billingTeamId = getBillingTeamId(auth.tenancy.project); if (billingTeamId != null && arePlanLimitsEnforced()) { diff --git a/apps/backend/src/app/api/latest/internal/analytics/query/route.ts b/apps/backend/src/app/api/latest/internal/analytics/query/route.ts index 941fb4d12..0908d9112 100644 --- a/apps/backend/src/app/api/latest/internal/analytics/query/route.ts +++ b/apps/backend/src/app/api/latest/internal/analytics/query/route.ts @@ -2,7 +2,7 @@ import { getClickhouseExternalClient } from "@/lib/clickhouse"; import { getSafeClickhouseErrorMessage } from "@/lib/clickhouse-errors"; import { arePlanLimitsEnforced, getBillingTeamId } from "@/lib/plan-entitlements"; import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler"; -import { getStackServerApp } from "@/stack"; +import { getHexclaveServerApp } from "@/stack"; import { KnownErrors } from "@hexclave/shared"; import { ITEM_IDS, PLAN_LIMITS } from "@hexclave/shared/dist/plans"; import { adaptSchema, adminAuthTypeSchema, jsonSchema, yupBoolean, yupMixed, yupNumber, yupObject, yupRecord, yupString } from "@hexclave/shared/dist/schema-fields"; @@ -43,7 +43,7 @@ export const POST = createSmartRouteHandler({ let effectiveTimeoutMs = body.timeout_ms; const billingTeamId = getBillingTeamId(auth.tenancy.project); if (billingTeamId != null && arePlanLimitsEnforced()) { - const app = getStackServerApp(); + const app = getHexclaveServerApp(); const timeoutItem = await app.getItem({ itemId: ITEM_IDS.analyticsTimeoutSeconds, teamId: billingTeamId }); // clickHouse treats max_execution_time=0 as // "unlimited", so a customer with zero timeout entitlement (no active diff --git a/apps/backend/src/app/api/latest/internal/send-test-email/route.tsx b/apps/backend/src/app/api/latest/internal/send-test-email/route.tsx index 08d4bbccd..b036065a3 100644 --- a/apps/backend/src/app/api/latest/internal/send-test-email/route.tsx +++ b/apps/backend/src/app/api/latest/internal/send-test-email/route.tsx @@ -1,7 +1,7 @@ import { isSecureEmailPort, lowLevelSendEmailDirectWithoutRetries } from "@/lib/emails-low-level"; import { arePlanLimitsEnforced, getBillingTeamId } from "@/lib/plan-entitlements"; import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler"; -import { getStackServerApp } from "@/stack"; +import { getHexclaveServerApp } from "@/stack"; import { KnownErrors } from "@hexclave/shared"; import { ITEM_IDS } from "@hexclave/shared/dist/plans"; import * as schemaFields from "@hexclave/shared/dist/schema-fields"; @@ -51,7 +51,7 @@ export const POST = createSmartRouteHandler({ const billingTeamId = getBillingTeamId(auth.tenancy.project); const emailItem = billingTeamId == null || !arePlanLimitsEnforced() ? null - : await getStackServerApp().getItem({ itemId: ITEM_IDS.emailsPerMonth, teamId: billingTeamId }); + : await getHexclaveServerApp().getItem({ itemId: ITEM_IDS.emailsPerMonth, teamId: billingTeamId }); if (emailItem != null && billingTeamId != null) { const isDebited = await emailItem.tryDecreaseQuantity(1); if (!isDebited) { diff --git a/apps/backend/src/app/api/latest/session-replays/batch/route.tsx b/apps/backend/src/app/api/latest/session-replays/batch/route.tsx index 9f6c39268..0ec2f9b2d 100644 --- a/apps/backend/src/app/api/latest/session-replays/batch/route.tsx +++ b/apps/backend/src/app/api/latest/session-replays/batch/route.tsx @@ -4,7 +4,7 @@ import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler"; import { Prisma } from "@/generated/prisma/client"; import { arePlanLimitsEnforced, getBillingTeamId } from "@/lib/plan-entitlements"; import { findRecentSessionReplay } from "@/lib/session-replays"; -import { getStackServerApp } from "@/stack"; +import { getHexclaveServerApp } from "@/stack"; import { KnownErrors } from "@hexclave/shared"; import { ITEM_IDS } from "@hexclave/shared/dist/plans"; import { adaptSchema, clientOrHigherAuthTypeSchema, yupArray, yupMixed, yupNumber, yupObject, yupString } from "@hexclave/shared/dist/schema-fields"; @@ -109,7 +109,7 @@ export const POST = createSmartRouteHandler({ const prisma = await getPrismaClientForTenancy(auth.tenancy); const recentSession = await findRecentSessionReplay(prisma, { tenancyId, refreshTokenId }); - const app = getStackServerApp(); + const app = getHexclaveServerApp(); const isNewSession = recentSession == null; const billingTeamId = getBillingTeamId(auth.tenancy.project); diff --git a/apps/backend/src/lib/email-queue-step.tsx b/apps/backend/src/lib/email-queue-step.tsx index 38f8026fb..81e7f4639 100644 --- a/apps/backend/src/lib/email-queue-step.tsx +++ b/apps/backend/src/lib/email-queue-step.tsx @@ -4,7 +4,7 @@ import { getEmailThemeForThemeId, renderEmailsForTenancyBatched } from "@/lib/em import { EmailOutboxRecipient, getEmailConfig, } from "@/lib/emails"; import { generateUnsubscribeLink, getNotificationCategoryById, hasNotificationEnabled, listNotificationCategories } from "@/lib/notification-categories"; import { arePlanLimitsEnforced, getBillingTeamId } from "@/lib/plan-entitlements"; -import { getStackServerApp } from "@/stack"; +import { getHexclaveServerApp } from "@/stack"; import { ITEM_IDS } from "@hexclave/shared/dist/plans"; import { getTenancy, Tenancy } from "@/lib/tenancies"; import { getPrismaClientForTenancy, globalPrismaClient, PrismaClientTransaction } from "@/prisma-client"; @@ -695,7 +695,7 @@ async function processSingleEmail(context: TenancyProcessingContext, row: EmailO } if (context.billingTeamId != null && row.sendRetries === 0 && arePlanLimitsEnforced()) { - const app = getStackServerApp(); + const app = getHexclaveServerApp(); const emailItem = await app.getItem({ itemId: ITEM_IDS.emailsPerMonth, teamId: context.billingTeamId }); const isDebited = await emailItem.tryDecreaseQuantity(1); if (!isDebited) { diff --git a/apps/backend/src/lib/events.tsx b/apps/backend/src/lib/events.tsx index 22e2d1cd1..45e67d58a 100644 --- a/apps/backend/src/lib/events.tsx +++ b/apps/backend/src/lib/events.tsx @@ -1,7 +1,7 @@ import withPostHog from "@/analytics"; import { arePlanLimitsEnforced } from "@/lib/plan-entitlements"; import { globalPrismaClient } from "@/prisma-client"; -import { getStackServerApp } from "@/stack"; +import { getHexclaveServerApp } from "@/stack"; import { runAsynchronouslyAndWaitUntil } from "@/utils/background-tasks"; import { ITEM_IDS } from "@hexclave/shared/dist/plans"; import { urlSchema, yupBoolean, yupMixed, yupNumber, yupObject, yupString } from "@hexclave/shared/dist/schema-fields"; @@ -278,7 +278,7 @@ export async function logEvent( const billingTeamId = options.billingTeamId; if (billingTeamId != null && arePlanLimitsEnforced()) { - const app = getStackServerApp(); + const app = getHexclaveServerApp(); const eventsItem = await app.getItem({ itemId: ITEM_IDS.analyticsEvents, teamId: billingTeamId }); const isDebited = await eventsItem.tryDecreaseQuantity(1); if (!isDebited) { diff --git a/apps/backend/src/lib/local-emulator.test.ts b/apps/backend/src/lib/local-emulator.test.ts index a4e9f0550..594528bdc 100644 --- a/apps/backend/src/lib/local-emulator.test.ts +++ b/apps/backend/src/lib/local-emulator.test.ts @@ -96,7 +96,7 @@ describe("local emulator config", () => { await writeConfigToFile(absoluteFilePath, { auth: { allowLocalhost: true } }); await expect(fs.readFile(mountedFilePath, "utf-8")).resolves.toBe( - `import type { StackConfig } from "@hexclave/js";\n\nexport const config: StackConfig = {\n "auth": {\n "allowLocalhost": true\n }\n};\n` + `import type { HexclaveConfig } from "@hexclave/js";\n\nexport const config: HexclaveConfig = {\n "auth": {\n "allowLocalhost": true\n }\n};\n` ); }); @@ -132,7 +132,7 @@ describe("local emulator config", () => { allowLocalhost: true, }, }); - await expect(fs.readFile(mountedFilePath, "utf-8")).resolves.toContain(`import type { StackConfig }`); + await expect(fs.readFile(mountedFilePath, "utf-8")).resolves.toContain(`import type { HexclaveConfig }`); }); it("fails loudly when the QEMU host mount root is configured but unavailable", async () => { diff --git a/apps/backend/src/lib/local-emulator.ts b/apps/backend/src/lib/local-emulator.ts index 9e7009290..b7bb3ea52 100644 --- a/apps/backend/src/lib/local-emulator.ts +++ b/apps/backend/src/lib/local-emulator.ts @@ -1,7 +1,7 @@ import { globalPrismaClient } from "@/prisma-client"; import { showOnboardingStackConfigValue } from "@hexclave/shared/dist/config-authoring"; import { detectImportPackageFromDir, renderConfigFileContent } from "@hexclave/shared/dist/config-rendering"; -import { parseStackConfigFileContent } from "@hexclave/shared/dist/stack-config-file"; +import { parseStackConfigFileContent } from "@hexclave/shared/dist/hexclave-config-file"; import { isValidConfig } from "@hexclave/shared/dist/config/format"; import { LOCAL_EMULATOR_ADMIN_EMAIL, LOCAL_EMULATOR_ADMIN_PASSWORD } from "@hexclave/shared/dist/local-emulator"; import { getEnvVariable } from "@hexclave/shared/dist/utils/env"; diff --git a/apps/backend/src/stack.tsx b/apps/backend/src/stack.tsx index 5364906b2..e66869f3d 100644 --- a/apps/backend/src/stack.tsx +++ b/apps/backend/src/stack.tsx @@ -1,7 +1,7 @@ import { StackServerApp } from '@hexclave/next'; import { getEnvVariable } from '@hexclave/shared/dist/utils/env'; -export function getStackServerApp() { +export function getHexclaveServerApp() { // Fail fast if the backend self-URL env var is missing — without it the SDK // would silently inherit `defaultBaseUrl` (https://api.stack-auth.com), which // is almost never what we want for backend self-calls. diff --git a/apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/actions.ts b/apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/actions.ts index 02df30736..a9b01ce8b 100644 --- a/apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/actions.ts +++ b/apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/actions.ts @@ -5,7 +5,7 @@ async function getServerApp() { if (isRemoteDevelopmentEnvironmentEnabled()) { throw new Error("Team invitation management is not available in the remote development environment dashboard."); } - return (await import("@/stack/server")).getStackServerApp(); + return (await import("@/stack/server")).getHexclaveServerApp(); } export async function revokeInvitation(teamId: string, invitationId: string) { diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx index 0ee5681cf..1dab02572 100644 --- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx +++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx @@ -4,7 +4,7 @@ import { CmdKSearch, CmdKTrigger } from "@/components/cmdk-search"; import { Link } from "@/components/link"; import { Logo } from "@/components/logo"; import { ProjectSwitcher } from "@/components/project-switcher"; -import { StackCompanion } from "@/components/stack-companion"; +import { HexclaveCompanion } from "@/components/stack-companion"; import ThemeToggle from "@/components/theme-toggle"; import { Button, @@ -769,7 +769,7 @@ export default function SidebarLayout(props: { children?: React.ReactNode }) { {/* Stack Companion - overlay with reserved content gutter */}
- +
diff --git a/apps/dashboard/src/app/(main)/integrations/featurebase/sso/page.tsx b/apps/dashboard/src/app/(main)/integrations/featurebase/sso/page.tsx index 8d1944694..6dce866e3 100644 --- a/apps/dashboard/src/app/(main)/integrations/featurebase/sso/page.tsx +++ b/apps/dashboard/src/app/(main)/integrations/featurebase/sso/page.tsx @@ -1,4 +1,4 @@ -import { getStackServerApp } from "@/stack/server"; +import { getHexclaveServerApp } from "@/stack/server"; import { getEnvVariable } from "@hexclave/shared/dist/utils/env"; import { getOrCreateFeaturebaseUser } from "@hexclave/shared/dist/utils/featurebase"; import { urlString } from "@hexclave/shared/dist/utils/urls"; @@ -21,7 +21,7 @@ export default async function FeaturebaseSSO({ return
Missing return_to parameter. Please go back and try again.
; } - const user = await getStackServerApp().getUser(); + const user = await getHexclaveServerApp().getUser(); if (!user) { redirect(urlString`/handler/sign-in?after_auth_return_to=${urlString`/integrations/featurebase/sso?return_to=${returnTo}`}`); } diff --git a/apps/dashboard/src/app/(main)/integrations/oauth-confirm-page.tsx b/apps/dashboard/src/app/(main)/integrations/oauth-confirm-page.tsx index b8915b1ed..508aa07f2 100644 --- a/apps/dashboard/src/app/(main)/integrations/oauth-confirm-page.tsx +++ b/apps/dashboard/src/app/(main)/integrations/oauth-confirm-page.tsx @@ -1,4 +1,4 @@ -import { getStackServerApp } from "@/stack/server"; +import { getHexclaveServerApp } from "@/stack/server"; import { getEnvVariable } from "@hexclave/shared/dist/utils/env"; import { HexclaveAssertionError } from "@hexclave/shared/dist/utils/errors"; import { redirect } from "next/navigation"; @@ -18,7 +18,7 @@ export default async function IntegrationConfirmPage(props: { const onContinue = async (options: { projectId: string, projectName?: string }) => { "use server"; - const user = await getStackServerApp().getUser(); + const user = await getHexclaveServerApp().getUser(); if (!user) { return { error: "unauthorized" }; } diff --git a/apps/dashboard/src/app/layout-client.tsx b/apps/dashboard/src/app/layout-client.tsx index e2ad42aeb..f224c709a 100644 --- a/apps/dashboard/src/app/layout-client.tsx +++ b/apps/dashboard/src/app/layout-client.tsx @@ -6,7 +6,7 @@ import { SiteLoadingIndicatorDisplay } from "@/components/site-loading-indicator import { Toaster } from "@/components/ui"; import { VersionAlerter } from "@/components/version-alerter"; import { getPublicEnvVar } from "@/lib/env"; -import { stackClientApp } from "@/stack/client"; +import { hexclaveClientApp } from "@/stack/client"; import { StackProvider, StackTheme } from "@hexclave/next"; import { runAsynchronouslyWithAlert } from "@hexclave/shared/dist/utils/promises"; import React, { useSyncExternalStore } from "react"; @@ -184,7 +184,7 @@ export function LayoutClient(props: { }) { return ( <> - ["lang"]}> + ["lang"]}> diff --git a/apps/dashboard/src/components/env-keys.tsx b/apps/dashboard/src/components/env-keys.tsx index bd861a94c..2a2c3931f 100644 --- a/apps/dashboard/src/components/env-keys.tsx +++ b/apps/dashboard/src/components/env-keys.tsx @@ -8,11 +8,11 @@ function getEnvFileContent(props: { superSecretAdminKey?: string, }) { const envFileContent = Object.entries({ - NEXT_PUBLIC_STACK_API_URL: getPublicEnvVar('NEXT_PUBLIC_STACK_API_URL') === "https://api.hexclave.com" ? undefined : getPublicEnvVar('NEXT_PUBLIC_STACK_API_URL'), - NEXT_PUBLIC_STACK_PROJECT_ID: props.projectId, - NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY: props.publishableClientKey, - STACK_SECRET_SERVER_KEY: props.secretServerKey, - STACK_SUPER_SECRET_ADMIN_KEY: props.superSecretAdminKey, + NEXT_PUBLIC_HEXCLAVE_API_URL: getPublicEnvVar('NEXT_PUBLIC_STACK_API_URL') === "https://api.stack-auth.com" ? undefined : getPublicEnvVar('NEXT_PUBLIC_STACK_API_URL'), + NEXT_PUBLIC_HEXCLAVE_PROJECT_ID: props.projectId, + NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY: props.publishableClientKey, + HEXCLAVE_SECRET_SERVER_KEY: props.secretServerKey, + HEXCLAVE_SUPER_SECRET_ADMIN_KEY: props.superSecretAdminKey, }) .filter(([k, v]) => v) .map(([k, v]) => `${k}=${v}`) @@ -133,7 +133,7 @@ export function ViteEnvKeys(props: { secretServerKey?: string, }) { const envFileContent = Object.entries({ - VITE_HEXCLAVE_API_URL: getPublicEnvVar('NEXT_PUBLIC_STACK_API_URL') === "https://api.hexclave.com" ? undefined : getPublicEnvVar('NEXT_PUBLIC_STACK_API_URL'), + VITE_HEXCLAVE_API_URL: getPublicEnvVar('NEXT_PUBLIC_STACK_API_URL') === "https://api.stack-auth.com" ? undefined : getPublicEnvVar('NEXT_PUBLIC_STACK_API_URL'), VITE_HEXCLAVE_PROJECT_ID: props.projectId, HEXCLAVE_SECRET_SERVER_KEY: props.secretServerKey, }) diff --git a/apps/dashboard/src/components/stack-companion.tsx b/apps/dashboard/src/components/stack-companion.tsx index de601c1ad..dca0a8f23 100644 --- a/apps/dashboard/src/components/stack-companion.tsx +++ b/apps/dashboard/src/components/stack-companion.tsx @@ -105,22 +105,22 @@ const CLOSE_THRESHOLD = 100; const SPLIT_SCREEN_BREAKPOINT = 1000; // Context for sharing companion state with layout -type StackCompanionContextType = { +type HexclaveCompanionContextType = { drawerWidth: number, isSplitScreenMode: boolean, }; -const StackCompanionContext = createContext({ +const HexclaveCompanionContext = createContext({ drawerWidth: 0, isSplitScreenMode: false, }); -export function useStackCompanion() { - return useContext(StackCompanionContext); +export function useHexclaveCompanion() { + return useContext(HexclaveCompanionContext); } -export function StackCompanion({ className, glassBg = false }: { className?: string, glassBg?: boolean }) { +export function HexclaveCompanion({ className, glassBg = false }: { className?: string, glassBg?: boolean }) { const [activeItem, setActiveItem] = useState(null); const [mounted, setMounted] = useState(false); const [versionCheckResult, setVersionCheckResult] = useState(null); @@ -524,7 +524,7 @@ export function StackCompanion({ className, glassBg = false }: { className?: str if (isSplitScreenMode) { return ( - +