Skip to content

Hosted components#1229

Merged
BilalG1 merged 8 commits intodevfrom
hosted-components-page
Mar 10, 2026
Merged

Hosted components#1229
BilalG1 merged 8 commits intodevfrom
hosted-components-page

Conversation

@BilalG1
Copy link
Copy Markdown
Collaborator

@BilalG1 BilalG1 commented Mar 2, 2026

Summary by CodeRabbit

  • New Features
    • Added a new "Hosted Components" app with its own app shell, routing, auth-aware UI, a handler route, and a welcome page showing the signed-in user.
  • Chores
    • Added dev tooling and configuration for the new app (build, lint, typecheck, Vite/TS, package manifest) and updated dev env API URL.
  • Tests
    • Excluded the new app from the test workspace.
  • Bug Fixes
    • Suppressed noisy console errors for a specific internal sentinel and clarified related error messaging.

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
stack-backend Ready Ready Preview, Comment Mar 10, 2026 5:53pm
stack-dashboard Ready Ready Preview, Comment Mar 10, 2026 5:53pm
stack-demo Ready Ready Preview, Comment Mar 10, 2026 5:53pm
stack-docs Ready Ready Preview, Comment Mar 10, 2026 5:53pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 2, 2026

📝 Walkthrough

Walkthrough

Adds a new "Hosted Components" frontend app (Vite + React + TypeScript) with route definitions, client bootstrap, Stack client integration, dev tooling/config, a vitest exclusion, and a small console monkey-patch utility in shared utils.

Changes

Cohort / File(s) Summary
Dev Launchpad
apps/dev-launchpad/public/index.html
Inserted "Hosted Components" app entry (portSuffix "09", source "./apps/hosted-components") into the apps list between Docs and Inbucket.
App manifest & env
apps/hosted-components/package.json, apps/hosted-components/.env.development
Added new frontend package manifest and updated dev env: VITE_STACK_API_URL now uses template http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}02.
Tooling & config
apps/hosted-components/tsconfig.json, apps/hosted-components/.eslintrc.cjs, apps/hosted-components/vite.config.ts, vitest.workspace.ts
Added TS, ESLint and Vite configs for the new app (including custom Vite plugins and dev server port logic); excluded the app from workspace Vitest.
Client bootstrap & router
apps/hosted-components/src/client.tsx, apps/hosted-components/src/router.tsx, apps/hosted-components/src/routeTree.gen.ts
Added React hydration entry, a getRouter factory, and a generated TanStack route tree with type augmentations for routes (/ and /handler/$).
Routes & UI
apps/hosted-components/src/routes/__root.tsx, apps/hosted-components/src/routes/index.tsx, apps/hosted-components/src/routes/handler/$.tsx
Implemented root route (projectId parsing/validation, ErrorBoundary, RootDocument, Stack client instantiation and providers) plus index and handler file routes and their components.
Shared utils
packages/stack-shared/src/utils/monkey-patch.tsx, packages/stack-shared/src/utils/react.tsx
Added a console monkey-patch utility and integrated a sentinel property + ensureMonkeyPatch call into NoSuspenseBoundaryError to suppress specific console.error noise.

Sequence Diagram(s)

sequenceDiagram
  participant Browser as Browser
  participant Client as client.tsx
  participant Router as TanStack Router
  participant Root as __root Route
  participant Stack as StackClientApp

  Browser->>Client: load & hydrate
  Client->>Router: create/getRouter()
  Router->>Root: render RootComponent (route match)
  Root->>Stack: compute projectId & instantiate StackClientApp
  Root->>Stack: wrap app with StackProvider/StackTheme -> Outlet
  Router->>Client: render matched page (index / handler)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A tiny hop, a bundle spun anew,
Routes stitched gently where the handlers grew,
A sentinel hush to quiet the noise,
Hydrate, theme, and render tiny joys,
Little paws applaud this hosted view.

🚥 Pre-merge checks | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description contains only the repository contribution template without any actual description, context, or rationale for the changes. Provide a meaningful description explaining what the hosted components app is, why it was created, and how it integrates with the existing codebase.
Docstring Coverage ⚠️ Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Hosted components' is vague and generic, describing what was added but lacking specificity about the change's nature, scope, or purpose. Clarify the title to indicate the specific change, e.g., 'Add hosted components app' or 'Create hosted components page application'.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch hosted-components-page

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@BilalG1 BilalG1 requested a review from N2D4 March 2, 2026 17:52
@BilalG1 BilalG1 assigned N2D4 and unassigned BilalG1 Mar 2, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 2, 2026

Greptile Summary

Adds a new hosted-components app using TanStack Start framework to provide hosted authentication UI accessible via project-specific subdomains (e.g., projectId.built-with-stack-auth.com). The app extracts the project ID from the subdomain, validates it as a UUID, and initializes Stack authentication with appropriate routing.

Key changes:

  • New React app with TanStack Start and Router for server-side rendering
  • Root component handles project ID extraction and validation from subdomain
  • Authentication routes at /handler/* for sign-in/sign-up flows
  • Protected index route displaying authenticated user information
  • Integrated with dev launchpad for local testing

Minor issue:

  • Missing clean script in package.json per project conventions

Confidence Score: 5/5

  • Safe to merge - well-structured new app with only minor style convention issue
  • Clean implementation of a new hosted components app with proper project structure, TypeScript configuration, and security practices. Redirect URLs are hardcoded (no injection risks), project ID validation is in place, and the code follows React best practices. The only issue is a missing clean script in package.json which is a non-blocking style convention
  • No files require special attention

Important Files Changed

Filename Overview
apps/hosted-components/package.json Added package configuration for new hosted-components app with TanStack Start dependencies, but missing clean script required by project conventions
apps/hosted-components/src/routes/__root.tsx Implemented root component with project ID extraction from subdomain, Stack authentication setup, and error handling
apps/hosted-components/src/routes/index.tsx Landing page showing authenticated user information with protected route
apps/hosted-components/vite.config.ts Standard Vite configuration with TanStack Start plugin and SPA mode enabled

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User visits subdomain] --> B{Extract project ID from subdomain}
    B --> C{Project ID exists?}
    C -->|No| D[Show 'Invalid URL' error]
    C -->|Yes| E{Valid UUID format?}
    E -->|No| F[Show 'Invalid project ID' error]
    E -->|Yes| G[Initialize StackClientApp]
    G --> H{User route}
    H -->|/handler/*| I[StackHandler component<br/>Sign-in/Sign-up flows]
    H -->|/| J{User authenticated?}
    J -->|No| K[Redirect to sign-in]
    J -->|Yes| L[Show welcome page<br/>with UserButton]
Loading

Last reviewed commit: 07b9be1

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

13 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
apps/hosted-components/src/routes/__root.tsx (1)

115-117: Render an explicit loading state instead of a blank screen.

Line [116] returns an empty fragment while initialization is in progress; use a visible loading UI so state transitions are explicit.

Based on learnings: "When building frontend code, always carefully deal with loading and error states. Be very explicit with these."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/hosted-components/src/routes/__root.tsx` around lines 115 - 117, The
early return for projectId (if (projectId === undefined) return <></>;) shows a
blank screen; replace it with an explicit loading UI so users see progress. In
the if (projectId === undefined) branch in __root.tsx, return a visible loading
state (for example a <Loading /> component or a simple accessible element like a
div with role="status" and a spinner/text) instead of an empty fragment,
ensuring any existing Loading component or CSS spinner is used for consistency
with the app.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/hosted-components/package.json`:
- Line 7: The dev script in package.json sets Vite to port 8109 ("dev": "vite
dev --port ${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}09") which conflicts with the
app’s expected 8105; update the dev script to default to 8105 instead (adjust
the NEXT_PUBLIC_STACK_PORT_PREFIX fallback or the appended digits) so the "dev"
npm script, the Vite server, and the local URL guidance in src/routes/__root.tsx
all use port 8105 consistently.

In `@apps/hosted-components/src/routes/__root.tsx`:
- Around line 97-113: Replace the type bypass and non-null assertion: create a
properly typed adapter for redirectMethod that calls the React Router
useNavigate hook (e.g., a small function that captures const navigate =
useNavigate(); and returns a function (to: string) => void) and pass that
adapter to new StackClientApp instead of `useNavigate as any`; and replace the
`stackApp!` usage with a defensive null-coalescing pattern (e.g., `stackApp ??
throwErr('stackApp was unexpectedly null despite validation checks')` or an
explicit guard that throws) so the code is type-safe and fails with an explicit
error if stackApp is null.

---

Nitpick comments:
In `@apps/hosted-components/src/routes/__root.tsx`:
- Around line 115-117: The early return for projectId (if (projectId ===
undefined) return <></>;) shows a blank screen; replace it with an explicit
loading UI so users see progress. In the if (projectId === undefined) branch in
__root.tsx, return a visible loading state (for example a <Loading /> component
or a simple accessible element like a div with role="status" and a spinner/text)
instead of an empty fragment, ensuring any existing Loading component or CSS
spinner is used for consistency with the app.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1232132 and 07b9be1.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (12)
  • apps/dev-launchpad/public/index.html
  • apps/hosted-components/.env.development
  • apps/hosted-components/.eslintrc.cjs
  • apps/hosted-components/package.json
  • apps/hosted-components/src/client.tsx
  • apps/hosted-components/src/routeTree.gen.ts
  • apps/hosted-components/src/router.tsx
  • apps/hosted-components/src/routes/__root.tsx
  • apps/hosted-components/src/routes/handler/$.tsx
  • apps/hosted-components/src/routes/index.tsx
  • apps/hosted-components/tsconfig.json
  • apps/hosted-components/vite.config.ts

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you also create a vercel project for this? domain built-with-stack-auth.com is on cloudflare

@github-actions github-actions bot assigned BilalG1 and unassigned N2D4 Mar 10, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
apps/hosted-components/package.json (1)

7-7: ⚠️ Potential issue | 🟠 Major

Use the same default port as the rest of this app.

This still defaults Vite to 8109, while apps/hosted-components/src/routes/__root.tsx points users to <projectId>.localhost:8105. The default dev flow and the in-app guidance will disagree until these match.

Proposed fix
-    "dev": "vite dev --port ${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}09",
+    "dev": "vite dev --port ${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}05",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/hosted-components/package.json` at line 7, The dev script in
package.json currently defaults Vite to port 8109 via "dev": "vite dev --port
${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}09"; change the default to match the rest of
the app (8105) by updating the dev script to use the same fallback prefix so
Vite will start on 8105 when NEXT_PUBLIC_STACK_PORT_PREFIX is not set; edit the
"dev" script entry (symbol: "dev") and adjust the fallback port expression
(symbol: NEXT_PUBLIC_STACK_PORT_PREFIX) so the resolved default is 8105 instead
of 8109.
🧹 Nitpick comments (1)
apps/hosted-components/src/routes/__root.tsx (1)

14-24: Guard getProjectId() against SSR callers.

This route module is loaded on the server too, and getProjectId() is exported. Any future SSR/test caller will crash on window. Make the browser-only assumption explicit inside the helper.

Suggested change
 export function getProjectId(): string | null {
+  if (typeof window === "undefined") {
+    return null;
+  }
+
   // Extract from subdomain: <projectId>.built-with-stack-auth.com
   // Also works with <projectId>.localhost for local dev
   const hostname = window.location.hostname;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/hosted-components/src/routes/__root.tsx` around lines 14 - 24,
getProjectId() currently assumes a browser environment and directly accesses
window, which will crash during SSR/testing; update the function to first guard
for non-browser callers by checking typeof window === "undefined" (and/or typeof
window.location === "undefined") and returning null in that case, then continue
with the existing hostname parsing logic (hostname.split and parts[0]) when
running in the browser so server-side imports won't throw.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/hosted-components/package.json`:
- Around line 7-15: The dev script in hosted-components fails because
`@stackframe/react`'s dist files aren't guaranteed to exist; update the task
wiring so hosted-components' dev depends on the package build: add a dependsOn
entry (e.g., dependsOn: ["^build"]) to the hosted-components "dev" task in
turbo.json so the workspace runs the dependent package build first, or
alternatively add a Vite alias in hosted-components' Vite config to resolve
"@stackframe/react" directly to its source (src) to avoid needing dist files
during dev.

In `@apps/hosted-components/src/routes/__root.tsx`:
- Around line 89-93: The initial state for projectId is incorrectly bootstrapped
to the string "internal", causing the app to create a StackClientApp for the
internal project before the real hostname is known; change the initialization so
projectId starts as undefined (or null) instead of "internal", keep the existing
useEffect that calls getProjectId() and setProjectId(), and ensure any code that
constructs/bootstraps StackClientApp (or reads projectId) guards against
undefined and only creates the client after projectId is set to the real value.

In `@apps/hosted-components/src/routes/index.tsx`:
- Around line 6-10: The pendingComponent render lacks accessible status
announcement for screen readers; update the pendingComponent function to include
an accessible status (e.g., role="status" or aria-live="polite") and provide
visible or visually-hidden text such as "Loading, please wait" so assistive tech
is informed during auth loading/redirect; keep the existing spinner for visual
users and add the announcement text inside the same wrapper (or as a
screen-reader-only element) to ensure both visual and non-visual users receive
feedback.

---

Duplicate comments:
In `@apps/hosted-components/package.json`:
- Line 7: The dev script in package.json currently defaults Vite to port 8109
via "dev": "vite dev --port ${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}09"; change the
default to match the rest of the app (8105) by updating the dev script to use
the same fallback prefix so Vite will start on 8105 when
NEXT_PUBLIC_STACK_PORT_PREFIX is not set; edit the "dev" script entry (symbol:
"dev") and adjust the fallback port expression (symbol:
NEXT_PUBLIC_STACK_PORT_PREFIX) so the resolved default is 8105 instead of 8109.

---

Nitpick comments:
In `@apps/hosted-components/src/routes/__root.tsx`:
- Around line 14-24: getProjectId() currently assumes a browser environment and
directly accesses window, which will crash during SSR/testing; update the
function to first guard for non-browser callers by checking typeof window ===
"undefined" (and/or typeof window.location === "undefined") and returning null
in that case, then continue with the existing hostname parsing logic
(hostname.split and parts[0]) when running in the browser so server-side imports
won't throw.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 02535b65-2167-4f30-a751-ce9a02098417

📥 Commits

Reviewing files that changed from the base of the PR and between 201bb24 and a813ca7.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • apps/hosted-components/.env.development
  • apps/hosted-components/package.json
  • apps/hosted-components/src/routes/__root.tsx
  • apps/hosted-components/src/routes/index.tsx
  • apps/hosted-components/vite.config.ts
  • packages/stack-shared/src/utils/monkey-patch.tsx
  • packages/stack-shared/src/utils/react.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/hosted-components/.env.development
  • apps/hosted-components/vite.config.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/hosted-components/vite.config.ts (2)

72-75: Validate the port prefix instead of relying on ||.

|| "81" treats '' as unset, and a malformed prefix still flows into Number(...) as NaN. Since this is config input, prefer nullish handling plus an explicit validation error.

Suggested diff
+const portPrefix = process.env.NEXT_PUBLIC_STACK_PORT_PREFIX
+if (portPrefix !== undefined && !/^\d+$/.test(portPrefix)) {
+  throw new Error('NEXT_PUBLIC_STACK_PORT_PREFIX must contain only digits')
+}
+
 export default defineConfig({
   server: {
-    port: Number((process.env.NEXT_PUBLIC_STACK_PORT_PREFIX || "81") + "09"),
+    port: Number(`${portPrefix ?? '81'}09`),
   },

As per coding guidelines, "Unless very clearly equivalent from types, prefer explicit null/undefinedness checks over boolean checks" and "Fail early, fail loud. Fail fast with an error instead of silently continuing."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/hosted-components/vite.config.ts` around lines 72 - 75, Replace the
fragile port computation in defineConfig's server.port by explicitly reading
process.env.NEXT_PUBLIC_STACK_PORT_PREFIX, applying nullish coalescing (not ||),
validating that the prefix is non-empty and matches the expected digit pattern
(e.g., /^\d+$/), then construct the port (prefix + "09"), parse it to a number
and throw a clear Error if the prefix is missing or the resulting Number is
NaN/invalid; update the symbol references NEXT_PUBLIC_STACK_PORT_PREFIX and
server.port in vite.config.ts so the config fails fast on bad input rather than
producing NaN.

42-55: Use performance.now() for the timeout clock.

This loop is measuring elapsed time with wall-clock time, so clock adjustments can skew the timeout. performance.now() is the safer timer here.

Suggested diff
   async function waitForFile(filePath: string, timeoutMs = 60_000): Promise<void> {
     if (fs.existsSync(filePath)) return
-    const start = Date.now()
+    const start = performance.now()
     return new Promise((resolve, reject) => {
       const interval = setInterval(() => {
         if (fs.existsSync(filePath)) {
           clearInterval(interval)
           resolve()
-        } else if (Date.now() - start > timeoutMs) {
+        } else if (performance.now() - start > timeoutMs) {
           clearInterval(interval)
           reject(new Error(`Timed out waiting for ${filePath} to exist`))
         }
       }, 500)
     })

As per coding guidelines, "Don't use Date.now() for measuring elapsed (real) time, instead use performance.now()".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/hosted-components/vite.config.ts` around lines 42 - 55, In waitForFile,
replace the Date.now() wall-clock timing with a monotonic timer: set const start
= performance.now() and in the interval check use (performance.now() - start >
timeoutMs) to detect timeout; if your Node runtime may not expose global
performance, import it via const { performance } = require('perf_hooks') or an
equivalent ESM import at the top of the file, and ensure timeoutMs remains
milliseconds (performance.now() is also in ms).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/hosted-components/src/routes/__root.tsx`:
- Line 95: isValidProjectId uses a loose UUID regex that can accept values
rejected by the StackClientApp constructor; update the validation to the
stricter UUID v1-8 + variant pattern used by StackClientApp so the same IDs are
accepted/rejected. Replace the current regex in isValidProjectId with one that
enforces the version char as [1-8] and the variant nibble as [089ab] (i.e.,
match the same pattern used by StackClientApp), so invalid projectId values
produce the intended FullPageError instead of a constructor exception.

---

Nitpick comments:
In `@apps/hosted-components/vite.config.ts`:
- Around line 72-75: Replace the fragile port computation in defineConfig's
server.port by explicitly reading process.env.NEXT_PUBLIC_STACK_PORT_PREFIX,
applying nullish coalescing (not ||), validating that the prefix is non-empty
and matches the expected digit pattern (e.g., /^\d+$/), then construct the port
(prefix + "09"), parse it to a number and throw a clear Error if the prefix is
missing or the resulting Number is NaN/invalid; update the symbol references
NEXT_PUBLIC_STACK_PORT_PREFIX and server.port in vite.config.ts so the config
fails fast on bad input rather than producing NaN.
- Around line 42-55: In waitForFile, replace the Date.now() wall-clock timing
with a monotonic timer: set const start = performance.now() and in the interval
check use (performance.now() - start > timeoutMs) to detect timeout; if your
Node runtime may not expose global performance, import it via const {
performance } = require('perf_hooks') or an equivalent ESM import at the top of
the file, and ensure timeoutMs remains milliseconds (performance.now() is also
in ms).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f5913baa-8149-4a18-80fe-cb1d7e589522

📥 Commits

Reviewing files that changed from the base of the PR and between a813ca7 and 2c1caad.

📒 Files selected for processing (4)
  • apps/hosted-components/.env.development
  • apps/hosted-components/src/routes/__root.tsx
  • apps/hosted-components/src/routes/handler/$.tsx
  • apps/hosted-components/vite.config.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/hosted-components/src/routes/handler/$.tsx

@BilalG1 BilalG1 merged commit a64055c into dev Mar 10, 2026
31 checks passed
@BilalG1 BilalG1 deleted the hosted-components-page branch March 10, 2026 18:29
mantrakp04 pushed a commit that referenced this pull request Mar 10, 2026
<!--

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

-->


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

* **New Features**
* Added a new "Hosted Components" app with its own app shell, routing,
auth-aware UI, a handler route, and a welcome page showing the signed-in
user.
* **Chores**
* Added dev tooling and configuration for the new app (build, lint,
typecheck, Vite/TS, package manifest) and updated dev env API URL.
* **Tests**
  * Excluded the new app from the test workspace.
* **Bug Fixes**
* Suppressed noisy console errors for a specific internal sentinel and
clarified related error messaging.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Konstantin Wohlwend <n2d4xc@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants