Skip to content

feat: add @runtimed/notebook-preview package#730

Closed
markmiro wants to merge 38 commits intomainfrom
notebook-preview-package
Closed

feat: add @runtimed/notebook-preview package#730
markmiro wants to merge 38 commits intomainfrom
notebook-preview-package

Conversation

@markmiro
Copy link
Copy Markdown
Contributor

@markmiro markmiro commented Feb 2, 2026

Summary

  • Adds new @runtimed/notebook-preview package for rendering static notebook previews
  • Builds on @runtimed/components package with output renderers
  • Includes demo pages at /react.html and /index.html for testing
  • Fixes iframe height calculation and various Docker build issues

Test plan

  • Run pnpm dev and verify dev server starts correctly
  • Navigate to notebook-preview demo pages and verify rendering
  • Verify output components render correctly (text, markdown, JSON, images)
  • Run type checking: pnpm check
  • Test Docker builds: docker 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 via postMessage, converts it to @runtimed/schema OutputData, 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-iframe in-repo components to import from @runtimed/components, adds a new /demo/outputs route, 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.

Comment thread src/components/notebook/cell/MarkdownCell.tsx
@markmiro markmiro changed the title feat: add notebook-preview package for static notebook rendering feat: add @runtimed/notebook-preview package Feb 2, 2026
markmiro and others added 14 commits February 2, 2026 11:04
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>
markmiro and others added 4 commits February 2, 2026 11:53
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>
Comment thread packages/notebook-preview/vite.config.ts Outdated
Comment thread packages/components/tsdown.config.ts
Comment thread Dockerfile.web
input: {
index: resolve(__dirname, "index.html"),
react: resolve(__dirname, "react.html"),
health: resolve(__dirname, "demo.html"),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.

Fix in Cursor Fix in Web

const json =
typeof event.data.json === "string"
? JSON.parse(event.data.json)
: event.data.json;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.

Fix in Cursor Fix in Web

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

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.

Comment thread src/util/prefetch.ts
.catch(() => {});
import("@runtimed/components")
.then((m) => m.AiToolResultOutput)
.catch(() => {});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.

Fix in Cursor Fix in Web

@markmiro markmiro closed this Feb 6, 2026
@markmiro
Copy link
Copy Markdown
Contributor Author

markmiro commented Feb 6, 2026

See PR #731

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