141 lines
5.1 KiB
Markdown
141 lines
5.1 KiB
Markdown
# Pascal Editor Integration
|
|
|
|
## Current Shape
|
|
|
|
The app exposes a Pascal Editor workspace at `/pascal-editor`. Its customized
|
|
source is versioned with the main repository under `services/pascal-editor`,
|
|
while it remains an independently built Next app embedded through an iframe.
|
|
This keeps Pascal's Bun workspace and `@pascal-app/nodes` dependency graph out
|
|
of the host application's pnpm 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 standalone app also depends on its monorepo workspace packages.
|
|
Keeping the complete Pascal source tree below `services/pascal-editor` preserves
|
|
the built-in walls, doors, windows, levels, roofs, stairs, MCP tools, and our AI
|
|
Agent customization without coupling the host build to those packages.
|
|
|
|
## Deployment Options
|
|
|
|
### Local Self-Hosted Dev Service
|
|
|
|
Run Pascal Editor as a local standalone service:
|
|
|
|
```bash
|
|
pnpm pascal:dev
|
|
```
|
|
|
|
The helper uses `services/pascal-editor`, installs its dependencies when needed,
|
|
and starts `apps/editor` on `http://localhost:3002`. Set `PASCAL_EDITOR_DIR` only
|
|
when deliberately testing a different Pascal checkout.
|
|
|
|
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`. On every request, that gateway resolves the enabled
|
|
model explicitly marked as `multimodalModel` and its provider from system
|
|
settings. It does not fall back to the Agent Auto model. OpenAI-compatible
|
|
`openai`, `custom`, `alibaba`, and `zhipu` providers work without copying their
|
|
API keys into the Pascal service.
|
|
|
|
For repeatable deployment and upgrades on additional servers, use
|
|
`scripts/deploy-pascal-production.sh`. The complete defaults, override
|
|
variables, health check, real-model smoke test, and rollback behavior are
|
|
documented in `docs/pascal-production-deployment.md`.
|
|
|
|
## Source Maintenance
|
|
|
|
`services/pascal-editor` was imported with Git subtree so its upstream history
|
|
can still be refreshed deliberately. Apply and test upstream updates in a
|
|
dedicated branch before merging them with our localization, host authentication,
|
|
scene storage, and AI Agent changes:
|
|
|
|
```bash
|
|
git subtree pull \
|
|
--prefix=services/pascal-editor \
|
|
https://github.com/pascalorg/editor.git main \
|
|
--squash
|
|
```
|
|
|
|
Production servers do not run this command. They only pull the reviewed main
|
|
repository and let `pnpm pascal:deploy` sync the vendored source into the
|
|
isolated runtime directory.
|