feat: add @runtimed/notebook-preview package#730
Conversation
Extracts shared output components into a new publishable package: - Add packages/components/ with output renderers (Markdown, JSON, ANSI, etc.) - Move shared-with-iframe components to the new package - Update src/ imports to use @runtimed/components - Update iframe-outputs to import from @runtimed/components - Update Dockerfiles to include components package - Fix eslint ignores for nested dist folders The @runtimed/components package provides React components for rendering notebook cell outputs, designed to be shared between the main app and sandboxed iframe outputs. Co-authored-by: Cursor <cursoragent@cursor.com>
7f3d003 to
f576ce2
Compare
Extracts shared output components into a new publishable package: - Add packages/components/ with output renderers (Markdown, JSON, ANSI, etc.) - Move shared-with-iframe components to the new package - Update src/ imports to use @runtimed/components - Update iframe-outputs to import from @runtimed/components - Update Dockerfiles to include components package - Fix eslint ignores for nested dist folders The @runtimed/components package provides React components for rendering notebook cell outputs, designed to be shared between the main app and sandboxed iframe outputs. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
f576ce2 to
c978cc2
Compare
health is already exported because it's a public file
| input: { | ||
| index: resolve(__dirname, "index.html"), | ||
| react: resolve(__dirname, "react.html"), | ||
| health: resolve(__dirname, "demo.html"), |
There was a problem hiding this comment.
Vite config entry key mismatches source filename
Medium Severity
The Rollup input entry uses health as the key but points to demo.html. In Vite/Rollup multi-page builds, the key determines the output filename, so the "Output Types Demo" page will be built as health.html instead of demo.html. This also conflicts with public/health.html (the actual health check page) which gets copied to dist during build. The key should be demo to match the source file.
| const json = | ||
| typeof event.data.json === "string" | ||
| ? JSON.parse(event.data.json) | ||
| : event.data.json; |
There was a problem hiding this comment.
Missing try-catch around JSON.parse can crash iframe
Medium Severity
The JSON.parse(event.data.json) call in the message handler lacks error handling. If a parent window sends malformed JSON via postMessage, this will throw a SyntaxError and crash the notebook preview iframe. Other components in the codebase (like SingleOutput.tsx) properly wrap JSON.parse in try-catch blocks with graceful fallbacks.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| .catch(() => {}); | ||
| import("@runtimed/components") | ||
| .then((m) => m.AiToolResultOutput) | ||
| .catch(() => {}); |
There was a problem hiding this comment.
Prefetch calls no longer trigger lazy chunk loading
Medium Severity
The prefetch strategy was rewritten to call import("@runtimed/components").then((m) => m.MarkdownRenderer) repeatedly for each component. Previously, each import() targeted a separate module file, triggering individual chunk loads. Now all calls import the same barrel file, and accessing the export (e.g., .MarkdownRenderer) just returns the already-loaded reference — it doesn't trigger loading of the lazily-imported sub-chunks used by React.lazy() inside SingleOutput and RichOutputContent. The prefetching of heavy component chunks is effectively broken.
|
See PR #731 |


Summary
@runtimed/notebook-previewpackage for rendering static notebook previews@runtimed/componentspackage with output renderers/react.htmland/index.htmlfor testingTest plan
pnpm devand verify dev server starts correctlypnpm checkdocker build -f Dockerfile.iframe-outputs .Made with Cursor
Note
Medium Risk
Moderate risk due to introducing new workspace packages and rewiring build/deploy paths (CI, Docker, iframe builds) plus refactoring runtime output rendering imports; failures would surface as build breaks or missing/incorrect output rendering.
Overview
Introduces a new workspace package,
@runtimed/components, that packages the notebook output renderers (including iframe comms +IframeOutput/IframeReactApp), shared UI primitives, Tailwind styles, and demo pages for reuse across apps.Adds
@runtimed/notebook-preview, a standalone Vite app that receives a Jupyter notebook JSON viapostMessage, converts it to@runtimed/schemaOutputData, and renders inputs/outputs using@runtimed/components(plus a separate output-types demo entrypoint).Migrates the main web app and tests off the old
shared-with-iframein-repo components to import from@runtimed/components, adds a new/demo/outputsroute, and updates iframe CSS sources accordingly; also tightens iframe message listener cleanup and adjusts JSON view + ANSI rendering for bundler compatibility.Updates CI and Dockerfiles to ensure workspace builds/install succeed (explicitly building
@runtimed/components, copying its manifests into images, and stripping it from the sync image where unused), expands ESLint ignore globs, and updates the lockfile for the new packages/deps.Written by Cursor Bugbot for commit 98bdffa. This will update automatically on new commits. Configure here.