Skip to content

FE-1500: add Preview quick simulation and compact timeline - #9361

Open
kube wants to merge 4 commits into
codex/fe-1500-viewerfrom
codex/fe-1500-viewer-simulation
Open

FE-1500: add Preview quick simulation and compact timeline#9361
kube wants to merge 4 commits into
codex/fe-1500-viewerfrom
codex/fe-1500-viewer-simulation

Conversation

@kube

@kube kube commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

Before this PR, PetrinautPreview showed a static marking. Running a scenario needed the full editor with its language server, because the simulation provider lowered scenario code through the language client alone.

PetrinautPreview gains an optional Quick Simulation mode. The host passes precompiled HIR artifacts and bounded run settings; the preview gains scenario configuration, compact playback controls, and a timeline that expands above the playback bar while frames exist. No language tooling is mounted.

9360.mp4

Links

Changes

Simulation provider

  • SimulationProvider accepts a compiler and an initialConfiguration

    SimulationCompiler is the compilation surface without an LSP: requestHirArtifacts and requestScenarioHir.
    requestScenarioHir takes the ad-hoc synthesis context and the scenario id a host with precompiled artifacts keys its lookup by.

  • useScenarioHir takes an options object

    requestScenarioHir and adHocContext.
    The provider injects the preview compiler; the settings panel and the experiments drawer keep the language client default.

  • requireScenario resolves missing or stale selections to the model's first scenario

    The selection normalizes back through controlled navigation. The full editor keeps its "No scenario" flow.

  • PlaybackProvider accepts an initialSpeed

Preview

  • quickSimulation prop on PetrinautPreview

    hirArtifacts, scenarioHirById, dt, maxTime, allowedPlaybackSpeeds, defaultPlaybackSpeed, parameterBounds, workerFactory.
    Artifacts are validated against the model before mounting and served through a compiler adapter.

  • Playback bar is a flat bordered box, square, opaque, without shadow

    It hugs its controls until frames arrive, then widens and expands upward into the timeline, and collapses on reset.
    Animation follows the animations preference and prefers-reduced-motion.
    At widths down to the 177px oEmbed minimum the control row scrolls horizontally.

  • SimulationTimeline extracted from the editor's timeline chart with a showLegend prop

    The editor keeps its legend, the preview hides it.

Known issues

  • validatePreviewQuickSimulation throws during render when artifacts do not match the model

    Hosts regenerate artifacts with the model and may add an error boundary.

Test coverage

  • quick-simulation.test.ts:

    Validation, playback-option resolution, compiler adapter.

  • react/simulation/provider.test.ts:

    requireScenario policy.

  • preview-quick-simulation-controls.test.tsx:

    Timeline expansion and rAF-driven playback.

  • react/playback/provider.test.tsx, navigation-adapter.test.ts:

    Initial speed cases and mode pinning.

How to test

  • Render <PetrinautPreview quickSimulation={...} /> with artifacts from yarn workspace @apps/petrinaut-website examples:generate
  • Quick Simulation > pick a scenario, adjust a parameter
  • Play

    Expect playback to advance and the timeline to expand

  • Playback settings

    Expect speeds limited to the allow-list

  • Reset

    Expect timeline collapsed

@vercel

vercel Bot commented Aug 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
hash Ready Ready Preview Sep 4, 2026 9:27am UTC
petrinaut Ready Ready Preview Sep 4, 2026 9:27am UTC
petrinaut-docs Ready Ready Preview Sep 4, 2026 9:27am UTC
1 Skipped Deployment
Project Deployment Actions Updated
hashdotdesign-tokens Ignored Ignored Preview Sep 4, 2026 9:27am UTC

Request Review

@cursor

cursor Bot commented Aug 26, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches shared simulation/playback providers and scenario selection normalization; preview misconfiguration throws at render, but the full editor path keeps prior defaults.

Overview
PetrinautPreview can opt into Quick Simulation via a new quickSimulation prop: the host supplies precompiled net and per-scenario HIR, fixed dt/maxTime, optional playback speed limits, and parameter bounds. The embed runs scenarios without Monaco/LSP by mounting SimulationProvider with a SimulationCompiler adapter and requireScenario (no “no scenario”; invalid selections normalize to the first scenario).

The preview adds a header Quick Simulation popover (shared scenario controls), a bottom playback bar (reused editor SimulationControls), and an expandable timeline (SimulationTimeline extracted with optional showLegend) that opens when frames exist and collapses on reset.

Simulation stack changes: injectable compiler and initialConfiguration on SimulationProvider; useScenarioHir accepts an options object and passes scenarioId into lowering; PlaybackProvider / PetrinautCanvasProvider honor initialPlaybackSpeed; preview navigation can pin simulate mode. Public @hashintel/petrinaut/preview and react exports document the new types/providers; preview docs describe the feature.

Reviewed by Cursor Bugbot for commit cf9e73c. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions github-actions Bot added area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team labels Aug 26, 2026
Comment thread libs/@hashintel/petrinaut/src/react/simulation/provider.tsx
Comment thread libs/@hashintel/petrinaut/src/ui/preview/petrinaut-preview.tsx
@kube
kube force-pushed the codex/fe-1500-viewer-simulation branch from f40fdea to 1498756 Compare August 27, 2026 01:23
@kube
kube force-pushed the codex/fe-1500-viewer-simulation branch from 1498756 to c9ddd26 Compare August 27, 2026 01:47
@kube
kube force-pushed the codex/fe-1500-viewer-simulation branch from c9ddd26 to 33257bc Compare August 27, 2026 02:33
@kube
kube force-pushed the codex/fe-1500-viewer-simulation branch from 33257bc to 7b6cd41 Compare August 28, 2026 03:04
@kube
kube force-pushed the codex/fe-1500-viewer-simulation branch from 99f5b63 to 98f28e3 Compare August 30, 2026 17:09
@kube
kube force-pushed the codex/fe-1500-viewer-simulation branch from 98f28e3 to 8f66f47 Compare August 30, 2026 17:24
@kube
kube force-pushed the codex/fe-1500-viewer-simulation branch from 8f66f47 to f217c44 Compare August 31, 2026 01:03
@kube
kube force-pushed the codex/fe-1500-viewer-simulation branch from f217c44 to 305c7b5 Compare August 31, 2026 02:14
@semgrep-code-hashintel

Copy link
Copy Markdown

Semgrep found 3 detect-replaceall-sanitization findings:

Detected a call to replaceAll() in an attempt to HTML escape the string value .replaceAll("&", "&amp;") .replaceAll('"', "&quot;") .replaceAll("'", "&#39;") .replaceAll("<", "&lt;"). Manually sanitizing input through a manually built list can be circumvented in many situations, and it's better to use a well known sanitization library such as sanitize-html or DOMPurify.

Semgrep found 1 regex_dos finding:

  • apps/petrinaut-website/src/main/app/brunch-demo/brunch-endpoint.ts

Ensure that the regex used to compare with user supplied input is safe from regular expression denial of service.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Preflight validation does not detect mismatched HIR artifacts as documented, and required-scenario normalization lacks integration coverage.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds optional precompiled Quick Simulation support to the embedded Petrinaut preview.

Changes:

  • Adds scenario configuration, playback controls, and compact timeline.
  • Introduces compiler injection, required-scenario normalization, and initial playback speed.
  • Adds tests, user documentation, and a package changeset.
File summaries
File Description
.changeset/petrinaut-preview-quick-simulation.md Records the publishable feature.
libs/@hashintel/petrinaut/docs/preview.md Documents Quick Simulation.
src/react/index.ts Exports simulation APIs.
src/react/petrinaut-provider-layers.tsx Threads initial playback speed.
src/react/playback/provider.tsx Initializes configured playback speed.
src/react/playback/provider.test.tsx Tests initial speed.
src/react/simulation/provider.tsx Adds compiler injection and scenario policy.
src/react/simulation/provider.test.ts Tests scenario selection helper.
src/react/simulation/use-scenario-hir.ts Supports injected HIR requests.
src/ui/preview/index.ts Exports Quick Simulation type.
src/ui/preview/navigation-adapter.ts Pins preview navigation mode.
src/ui/preview/navigation-adapter.test.ts Tests simulation mode pinning.
src/ui/preview/petrinaut-preview.tsx Composes Quick Simulation providers and UI.
src/ui/preview/preview-quick-simulation-controls.tsx Adds compact controls and timeline.
src/ui/preview/preview-quick-simulation-controls.test.tsx Tests timeline expansion.
src/ui/preview/quick-simulation.ts Defines validation and compiler adapter.
src/ui/preview/quick-simulation.test.ts Tests Quick Simulation helpers.
src/ui/views/Editor/panels/BottomPanel/subviews/simulation-timeline/content.tsx Extracts reusable timeline content.
src/ui/views/Editor/panels/BottomPanel/subviews/simulation-timeline/main.tsx Uses extracted timeline.
src/ui/views/Editor/panels/SimulateView/experiments/experiment-scenario-run.tsx Adopts the HIR options API.
Review details
  • Files reviewed: 20/20 changed files
  • Comments generated: 3
  • Review effort level: Balanced

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +72 to +75
export const validatePreviewQuickSimulation = (
definition: Pick<SDCPN, "scenarios">,
quickSimulation: Pick<PetrinautPreviewQuickSimulation, "scenarioHirById">,
): void => {
Comment on lines 703 to +707
useEffect(() => {
if (
const shouldNormalizeRequiredScenario =
requireScenario &&
effectiveSelectedScenarioId !== null &&
requestedScenarioId !== effectiveSelectedScenarioId;
import { ActiveNetContext } from "../../react/state/active-net-context";
import { UserSettingsContext } from "../../react/state/user-settings-context";
import { SimulationControls } from "../views/Editor/components/BottomBar/simulation-controls";
import { SimulationTimeline } from "../views/Editor/panels/BottomPanel/subviews/simulation-timeline/content";

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c5d89e5. Configure here.

Comment thread libs/@hashintel/petrinaut/src/ui/preview/petrinaut-preview.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

2 participants