Skip to content

DISCO-154: Add SDK Preview Command - #444

Draft
Philipp Koytek (philippkoytek) wants to merge 7 commits into
mainfrom
feature/DISCO-154-sdk-preview
Draft

Philipp Koytek (philippkoytek) wants to merge 7 commits into
mainfrom
feature/DISCO-154-sdk-preview

Conversation

@philippkoytek

@philippkoytek Philipp Koytek (philippkoytek) commented Oct 27, 2026 •

Copy link
Copy Markdown

Description

Adds content-cli sdk preview [--target http://localhost:4200] [--port 4300], a long-running local HTTPS proxy that serves a custom app's dev server to the Codespace Local preview (https://localhost:4300). Developers no longer configure HTTPS, CORS or a CSP meta tag on their own dev server, and the preview blocks what the published app blocks.

  • Proxy (preview-proxy.ts, Node built-ins only): listens on localhost only and forwards every request and WebSocket upgrade to --target. It strips the target's CSP, report-only CSP, X-Frame-Options and CORS headers, then sets the local preview headers. When the target is down it answers 502 with a readable message, logs one warning, and recovers when the target is back. A busy port gives a clear error.
  • Headers (preview-headers.ts): a verbatim copy of localPreviewHeaders() from ems-frontend (libs/common/fragments/sandbox/src/lib/policy.ts). That is the fragment gateway's sandbox policy with 'self' sources and frame-ancestors https://*.celonis.cloud http://localhost:*. A spec in ems-frontend pins the object and fails when the gateway policy drifts.
  • Inline scripts (preview-inline-scripts.ts): dev servers inject inline scripts the published build doesn't have (React Fast Refresh's preamble). For HTML responses the proxy adds 'sha256-…' hashes of each inline script to script-src, computed the way browsers parse them, and warns once per script that it only works locally.
  • Certificate (preview-certificate.ts): a self-signed localhost certificate (EC P-256; SANs localhost, 127.0.0.1, ::1) from selfsigned@5.5.0, the one new dependency. It is stored in ~/.celonis-content-cli-preview, reused, and regenerated when missing, corrupt or expiring. The system trust store is never touched.
  • Command (sdk-preview.service.ts, module.ts): beta, needs no profile, validates --target (an http(s) origin) and --port, prints the URL and what to do about the certificate, and stops on Ctrl+C. Docs are in docs/user-guide/sdk-commands.md and docs/command-graph.html.

Hot reload stays blocked (connect-src 'none') on purpose, to match production; developers reload the preview instead.

Relevant links

Screen.Recording.2026-10-27.at.17.43.54.mov

Checklist

  • I have self-reviewed this PR
  • I have tested the change and proved that it works in different scenarios: unit tests pass (701), the built CLI was run against a plain Node server and a React + Vite 8 app, and the React app renders through the proxy in headless Chromium. Verification in a tenant Codespace is still open.
  • I have updated docs if needed

Co-Authored-By: Claude noreply@anthropic.com
Includes-AI-Code: true

Co-Authored-By: Claude <noreply@anthropic.com>
Includes-AI-Code: true
Co-Authored-By: Claude <noreply@anthropic.com>
Includes-AI-Code: true
Co-Authored-By: Claude <noreply@anthropic.com>
Includes-AI-Code: true
Co-Authored-By: Claude <noreply@anthropic.com>
Includes-AI-Code: true
Co-Authored-By: Claude <noreply@anthropic.com>
Includes-AI-Code: true
…ine-scripts

The preview now blocks inline scripts by default, like published apps, and warns
about each one with a hint to pass --allow-inline-scripts.

Co-Authored-By: Claude <noreply@anthropic.com>
Includes-AI-Code: true
Co-Authored-By: Claude <noreply@anthropic.com>
Includes-AI-Code: true
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
1 New Major Issues (required ≤ 0)
1 New Blocker Issues (required ≤ 0)
2 New Critical Issues (required ≤ 0)
3 New Minor Issues (required ≤ 0)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

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.

1 participant