Skip to content

Conversation

@kube
Copy link
Collaborator

@kube kube commented Jan 10, 2026

Kapture 2026-01-10 at 03.19.33.mp4 (uploaded via Graphite)

🌟 What is the purpose of this PR?

  • Stop the Simulation once it reaches the state where no transition can be enabled.
  • Show notification in middle of viewport to say that Simulation is complete.

    This involves a new NotificationContext.
    I did not use ArkUI Toast because it would have been on top of Sentry button.
    We can easily change the display of notifications later.

  • Fixes sideEffects import for Sentry instrument import (which relies on side-effects)
  • Removes showing the transition firing on first frame

    This is a hackish fix, but in any we will need the simulator to be reworked to address this kind of issue properly

  • Add same favicon than @hashintel/hash-frontend
  • More padding in Transition panel under the Lambda mode selector
  • Show tooltip explaining why readonly when simulation is running

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • does not modify any publishable blocks or libraries, or modifications do not need publishing

📜 Does this require a change to the docs?

The changes in this PR:

  • are internal and do not require a docs change

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • do not affect the execution graph

❓ How to test this?

Use latest Petrinaut deployment

@github-actions github-actions bot added area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team labels Jan 10, 2026
Copy link
Collaborator Author

kube commented Jan 10, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@kube kube changed the title Add favicon H-5676: Stop Simulation when complete Jan 10, 2026
@kube kube marked this pull request as ready for review January 10, 2026 02:31
@cursor
Copy link

cursor bot commented Jan 10, 2026

PR Summary

Implements terminal-state detection and UX around simulation completion, plus small fixes.

  • Simulation completion: New checkTransitionEnablement determines deadlock; computeNextFrame returns transitionFired; simulation-store.step() sets state to "Complete" when no transitions can enable
  • User notification: Adds NotificationsProvider/useNotifications; SimulationProvider announces "Simulation complete"; Panda keyframes (fadeIn/fadeOut) for entry/exit
  • Controls & timeline: Play button shows check icon and is disabled on "Complete"; timeline tab visible for "Running"/"Paused"/"Complete"
  • Read-only clarity: New DisabledTooltip with UI_MESSAGES.READ_ONLY_MODE wraps form controls across properties panels
  • Sentry import fix: Switch demo entry to import "./sentry/instrument" and mark demo files as sideEffects in package.json
  • Demo/UI polish: Add favicon; spacing tweak under lambda mode selector; avoid showing transition as fired on first frame; adjust example dynamics/parameter defaults
  • Tests: Add unit tests for transition enablement and update compute-next-frame tests

Written by Cursor Bugbot for commit 1de1582. This will update automatically on new commits. Configure here.

@graphite-app graphite-app bot requested a review from a team January 10, 2026 02:31
@augmentcode
Copy link

augmentcode bot commented Jan 10, 2026

🤖 Augment PR Summary

Summary: This PR adds “simulation complete” handling to Petrinaut by detecting terminal (deadlock) markings and updating the UI accordingly.

Changes:

  • Introduces structural transition-enablement checking (`checkTransitionEnablement`) with accompanying tests.
  • Extends `computeNextFrame` to return both the updated simulation and a `transitionFired` flag, and updates tests to match.
  • Updates the simulation store to mark the run as Complete when no transition fired and no transitions are structurally enabled.
  • Adds a lightweight notifications system (context + provider) and emits a centered “Simulation complete” notification on completion.
  • Improves UX around completion/read-only states (disable play when complete, keep timeline visible, add readonly tooltip, minor panel spacing tweaks).
  • Demo-site tweaks: fix Sentry instrument side-effect import behavior and add favicons.

Technical Notes: Terminal detection is based on token-count structural enablement (not lambda evaluation), and completion notification is triggered via a Zustand subscription.

🤖 Was this summary useful? React with 👍 or 👎

Copy link

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

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

Review completed. 2 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

return children;
}

return <Tooltip content={message}>{children}</Tooltip>;
Copy link

Choose a reason for hiding this comment

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

Tooltip uses ArkTooltip.Trigger asChild, and disabled form controls (e.g. <input disabled>) typically don’t emit pointer events—so this wrapper may not actually show the tooltip when disabled is true. Worth verifying the tooltip appears in the readonly/simulation mode UX.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎

notif.id === id ? { ...notif, exiting: true } : notif,
),
);
}, duration - 200);
Copy link

Choose a reason for hiding this comment

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

setTimeout(..., duration - 200) can go negative if a caller passes a short duration, which can cause the “exiting” state to flip immediately and make the animation behave oddly. It may be worth guarding against very small durations.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎

@kube kube changed the title H-5676: Stop Simulation when complete H-5676, H-5929: Stop Simulation when complete + UX Tweaks + Sentry side-effect import fix Jan 10, 2026
Comment on lines 63 to 85
const notify = useCallback((options: NotifyOptions) => {
const id = nextIdRef.current++;
const duration = options.duration ?? DEFAULT_DURATION;

setNotifications((prev) => [
...prev,
{ id, message: options.message, exiting: false },
]);

// Start exit animation before removing
setTimeout(() => {
setNotifications((prev) =>
prev.map((notif) =>
notif.id === id ? { ...notif, exiting: true } : notif,
),
);
}, duration - 200);

// Remove after exit animation completes
setTimeout(() => {
setNotifications((prev) => prev.filter((notif) => notif.id !== id));
}, duration);
}, []);
Copy link
Contributor

Choose a reason for hiding this comment

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

Memory leak potential: setTimeout callbacks are not cleaned up if the component unmounts or if multiple notifications with the same ID are created rapidly. The timeouts continue to execute and call setNotifications on an unmounted component, which will cause React warnings and potential memory leaks.

Fix: Store timeout IDs in a ref and clear them in a cleanup function:

const timeoutsRef = useRef<Map<number, NodeJS.Timeout[]>>(new Map());

const notify = useCallback((options: NotifyOptions) => {
  const id = nextIdRef.current++;
  const duration = options.duration ?? DEFAULT_DURATION;

  setNotifications((prev) => [
    ...prev,
    { id, message: options.message, exiting: false },
  ]);

  const exitTimeout = setTimeout(() => {
    setNotifications((prev) =>
      prev.map((notif) =>
        notif.id === id ? { ...notif, exiting: true } : notif,
      ),
    );
  }, duration - 200);

  const removeTimeout = setTimeout(() => {
    setNotifications((prev) => prev.filter((notif) => notif.id !== id));
    timeoutsRef.current.delete(id);
  }, duration);

  timeoutsRef.current.set(id, [exitTimeout, removeTimeout]);
}, []);

useEffect(() => {
  return () => {
    timeoutsRef.current.forEach((timeouts) => {
      timeouts.forEach(clearTimeout);
    });
  };
}, []);

Spotted by Graphite Agent

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

@CiaranMn CiaranMn enabled auto-merge January 10, 2026 15:29
@CiaranMn CiaranMn added this pull request to the merge queue Jan 10, 2026
Merged via the queue into main with commit b8e1a87 Jan 10, 2026
42 checks passed
@CiaranMn CiaranMn deleted the cf/h-5676-show-a-message-when-no-transitions-are-fireable branch January 10, 2026 15:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

3 participants