# Pascal Editor Integration ## Current Shape The app now exposes a first-phase Pascal Editor workspace at `/pascal-editor`. It is intentionally iframe-based so Pascal can be self-hosted as a standalone Next app without forcing its unpublished `@pascal-app/nodes` workspace package into the main application dependency graph. The wrapper route is protected by the host application's existing login system. Unauthenticated users are redirected to `/login?callbackUrl=/pascal-editor`. The embedded Pascal app is self-hosted and does not use Pascal's official hosted sign-in flow. The page resolves the editor source in this order: 1. `NEXT_PUBLIC_PASCAL_EDITOR_URL` 2. `PASCAL_EDITOR_URL` 3. `/vendor/pascal-editor/index.html` when that file exists 4. `http://localhost:3002` when that self-hosted Pascal service is reachable in local development If none is available, the page shows an explicit configuration state instead of loading a broken iframe. ## Why Iframe First `@pascal-app/core`, `@pascal-app/viewer`, and `@pascal-app/editor` are published on npm, but the official standalone app still depends on `@pascal-app/nodes` from its monorepo workspace. That package registers the built-in node definitions used by walls, doors, windows, levels, roofs, stairs, and other editable building elements. Until it is published or vendored, a pure npm-based native React integration would be incomplete. ## Deployment Options ### Local Self-Hosted Dev Service Run Pascal Editor as a local standalone service: ```bash pnpm pascal:dev ``` The helper clones `pascalorg/editor` into the ignored `.pascal-editor/` directory on first run, installs its dependencies, and starts `apps/editor` on `http://localhost:3002`. Then open: ```text http://localhost:3000/pascal-editor ``` The host app auto-detects `http://localhost:3002` in development, so no env var is required for the default local setup. ### Same-Origin Static Bundle Build Pascal Editor as a static bundle and place it here: ```text public/vendor/pascal-editor/index.html ``` Then leave `NEXT_PUBLIC_PASCAL_EDITOR_URL` empty or set it explicitly: ```env NEXT_PUBLIC_PASCAL_EDITOR_URL=/vendor/pascal-editor/index.html ``` ### Separate Pascal Service Run Pascal Editor as its own service, then set: ```env NEXT_PUBLIC_PASCAL_EDITOR_URL=https://pascal-editor.example.com ``` `next.config.ts` reads this value and allows that origin in `frame-src` so the iframe is not blocked by our Content Security Policy. `PASCAL_EDITOR_URL` is also supported for server-side configuration. The final iframe URL is visible to the browser either way, so do not place secrets in it. The integration no longer falls back to `editor.pascal.app`, because the official hosted app can require Pascal sign-in for create, fork, and save actions. Use a local or self-hosted Pascal service for an auth-independent POC. Keep any separately deployed Pascal service behind the same private network, reverse proxy, or SSO boundary if direct access to that service must also be restricted. ### Same-domain authenticated service The production integration can expose Pascal below `/pascal-service` while the service itself only listens on a loopback port. Configure: ```env PASCAL_EDITOR_URL=/pascal-service/scenes PASCAL_PROXY_SECRET=replace_with_a_long_random_value ``` Nginx must use `auth_request` against `/api/internal/pascal/access`, strip any client-supplied Pascal identity or secret headers, and inject the authenticated `X-Pascal-User-Id` into the upstream request. The Pascal scene store uses that id as `ownerId`, so scene listing and every scene mutation remain user-scoped. The reviewed configuration is kept in `deploy/nginx/pascal-service.conf.template`; render its secret placeholder and include it inside the main HTTPS `server` block. The private Pascal service points its OpenAI-compatible model base URL to `/api/internal/pascal-agent/v1` on this application and authenticates with `PASCAL_PROXY_SECRET`. That gateway resolves the current enabled Agent model and provider from system settings on every request. OpenAI-compatible `openai`, `custom`, `alibaba`, and `zhipu` providers work without copying their API keys into the Pascal service. ## Next Step After the iframe POC is stable, the native integration path is: 1. Pin a Pascal upstream commit. 2. Vendor or workspace-link `packages/nodes` as `@pascal-app/nodes`. 3. Add Pascal packages to `transpilePackages`. 4. Upgrade `three` to the Pascal-compatible `^0.184` line and retest existing 3D/CAD surfaces. 5. Wire `Editor` `onLoad` / `onSave` to our project storage APIs.