Skip to content

H-5780: Remove petrinaut-old and fix Petrinaut CSS scoping for HASH embedding#8369

Draft
kube wants to merge 6 commits intomainfrom
cf/h-5780-remove-petrinaut-old-package-from-hash-monorepo
Draft

H-5780: Remove petrinaut-old and fix Petrinaut CSS scoping for HASH embedding#8369
kube wants to merge 6 commits intomainfrom
cf/h-5780-remove-petrinaut-old-package-from-hash-monorepo

Conversation

@kube
Copy link
Collaborator

@kube kube commented Feb 8, 2026

🌟 What is the purpose of this PR?

Remove the legacy @hashintel/petrinaut-old package from the monorepo and fix CSS scoping issues when embedding the new @hashintel/petrinaut library inside Hash frontend.

🔗 Related links

🚫 Blocked by

Nothing

🔍 What does this change?

1. Remove @hashintel/petrinaut-old

  • Deletes the entire libs/@hashintel/petrinaut-old/ directory (the legacy Petrinaut implementation)
  • Removes it from workspace configuration and yarn.lock

2. Integrate new Petrinaut into Hash frontend

  • Updates apps/hash-frontend to import @hashintel/petrinaut instead of petrinaut-old
  • Adds convert-net-formats.ts for data format conversion between Hash entities and Petrinaut's SDCPN format
  • Refactors use-process-save-and-load.tsx to work with the new Petrinaut API
  • Adds Node.js stubs (node-noop.ts, os.ts) for browser compatibility in the lib build

3. Fix Petrinaut panel positioning and worker URL

  • Fixes panel positioning in the library build (position: fixedposition: absolute)
  • Fixes Web Worker URL resolution for the library build context

4. Fix CSS scoping for HASH embedding (⚠️ important)

Two PandaCSS scoping issues were fixed in panda.config.ts:

Problem A — Color tokens not on .petrinaut-root:
The @hashintel/ds-theme preset defines light/dark conditions as :root &, .light &, .... PandaCSS generated color tokens on :where(:root,.light,[data-theme=light]) instead of .petrinaut-root, so color CSS variables were undefined when embedded in Hash.

Fix: Override conditions to scope to .petrinaut-root:

conditions: {
  extend: {
    light: ".petrinaut-root &",
    dark: ".dark .petrinaut-root &, [data-theme='dark'] .petrinaut-root &",
  },
},

Problem B — CSS @layer vs unlayered global reset:
Hash applies an unlayered global CSS reset (* { padding: 0; margin: 0; box-sizing: border-box; }) via MUI CssBaseline and globals.scss. PandaCSS wraps all its output in CSS @layer blocks (e.g. @layer utilities { .p_4 { padding: ... } }).

Per the CSS cascade specification, unlayered CSS always beats layered CSS, regardless of selector specificity. This means Hash's * { padding: 0 } overrides Petrinaut's .p_4 { padding: var(--spacing-4) } even though a class selector normally beats the universal selector.

Fix: Enable PandaCSS's polyfill: true option. This uses @csstools/postcss-cascade-layers to transform @layer wrappers into specificity-based equivalents (:not(#\#) chains), making the output unlayered. Normal CSS specificity then applies, and .p_4:not(#\#):not(#\#):not(#\#) (specificity 3,1,0) correctly beats * (specificity 0,0,0).

Note: This polyfill approach may not be the final solution — ideally, Hash's global reset would itself be wrapped in a CSS layer, or scoped to exclude embedded components. But for now, the polyfill ensures Petrinaut's styles work correctly in the Hash context. The CSS size increases by ~14 kB uncompressed (~0.6 kB gzipped) due to the specificity wrappers.

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

⚠️ Known issues

  • The CSS @layer polyfill is a workaround for Hash's unlayered global reset overriding Petrinaut's layered utilities. A cleaner long-term solution would be to wrap Hash's global CSS in a layer, but that is a broader change.
  • The :not(#\#) specificity boosts add ~14 kB to the uncompressed CSS (~0.6 kB gzipped).

🐾 Next steps

  • Consider wrapping Hash's global CSS reset in a CSS @layer so embedded components using @layer work correctly without polyfills
  • Evaluate dark mode support when Hash implements theme switching

🛡 What tests cover this?

  • Manual verification that built dist/main.css contains all CSS variables on .petrinaut-root and utilities are not wrapped in @layer blocks

❓ How to test this?

  1. Checkout the branch
  2. Run turbo run build --filter '@hashintel/petrinaut' --force
  3. Inspect libs/@hashintel/petrinaut/dist/main.css:
    • Color tokens (--colors-gray-10, etc.) should be on .petrinaut-root, NOT on :where(:root,...)
    • Utility classes should have :not(#\#) specificity boosts (e.g. .p_4:not(#\#):not(#\#):not(#\#))
    • No @layer utilities { ... } blocks should remain (only the empty declaration @layer reset,base,tokens,recipes,utilities;)
  4. Run the Hash frontend (yarn dev) and navigate to a process page — Petrinaut should render with correct padding, margins, and colors

📹 Demo

N/A — CSS scoping fix, no visual change from standalone Petrinaut (it now looks correct when embedded)

@vercel
Copy link

vercel bot commented Feb 8, 2026

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

Project Deployment Actions Updated (UTC)
hash Ready Ready Preview, Comment Feb 8, 2026 7:43pm
petrinaut Ready Ready Preview Feb 8, 2026 7:43pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
hashdotdesign Ignored Ignored Preview Feb 8, 2026 7:43pm
hashdotdesign-tokens Ignored Ignored Preview Feb 8, 2026 7:43pm

@github-actions github-actions bot added area/deps Relates to third-party dependencies (area) area/apps > hash* Affects HASH (a `hash-*` app) 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 area/apps type/legal Owned by the @legal team labels Feb 8, 2026
Copy link
Collaborator Author

kube commented Feb 8, 2026

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

@kube kube changed the title First draft of integration of new Petrinaut into Hash H-5780: Remove petrinaut-old and fix Petrinaut CSS scoping for HASH embedding Feb 8, 2026
kube and others added 6 commits February 8, 2026 20:25
The migration to @hashintel/petrinaut is complete — nothing depends on
the old package anymore. Remove it entirely and clean up the changeset
ignore list.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Switch panels from `position: fixed` to `position: absolute` so they
stay contained within petrinaut-root when embedded in Hash. Add
`position: relative` to `.petrinaut-root` as the positioning anchor.

Enable `base: "./"` and add a `generateBundle` plugin to simplify
Vite's worker URL output from `"" + new URL(...).href` to a clean
`new URL("assets/...", import.meta.url)`.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Override light/dark conditions so color tokens land on .petrinaut-root
instead of :where(:root,...). Enable CSS @layer polyfill so utilities
are not overridden by HASH's unlayered global reset (* { padding: 0 }).

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add CSS resets (fontWeight, textAlign, textTransform, letterSpacing)
to tooltip content so it doesn't inherit styles from ancestor elements
like section titles and field labels.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
The last MUI usage (tooltip) was replaced with Ark UI and native SVG,
so the dependency and its ESLint import restriction are no longer needed.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/apps > hash* Affects HASH (a `hash-*` app) area/apps area/deps Relates to third-party dependencies (area) 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 type/legal Owned by the @legal team

Development

Successfully merging this pull request may close these issues.

1 participant