FE-1523: Import and export Petrinaut files as YAML - #9379
Conversation
Nets and optimization manifests now load from YAML as well as JSON, detected from the content rather than the file name. The editor's export menu and the core serializer default to YAML, which writes multi-line code fields as block scalars; JSON export remains available. The CLI's JSON-lines protocol and stdin sources are unchanged.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Externalize js-yaml in the core build like the other runtime dependencies, and drop skipInvalid so a value YAML cannot represent throws instead of being dropped silently. Export the codec's result type, deduplicate the CLI's ImportResult unwrapping, anchor the visual-info test assertions to line starts, and match the docs list to the menu order.
PR SummaryMedium Risk Overview
The editor Export menu lists YAML/JSON (with/without visual info); import accepts Docs and Python binding docstrings describe YAML as the editor default. Reviewed by Cursor Bugbot for commit b4b620d. Bugbot is set up for automated code reviews on this repo. Configure here. |
…order Both formats now open with version, meta, and title, followed by the net sections ordered so each references only sections above it by id: parameters, types, differentialEquations, subnets, places, componentInstances, transitions, metrics, scenarios. Subnet keys are ordered the same way. Compile-time checks fail when SDCPN or Subnet gains a field without an export position, so new fields cannot be dropped from exports silently. Import accepts any key order.
A hand-written file can declare version: 1 without the meta.generator boilerplate. Exports keep writing meta so older importers, which require it on versioned files, still accept new exports.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9379 +/- ##
==========================================
- Coverage 60.74% 60.66% -0.09%
==========================================
Files 1440 1439 -1
Lines 143458 143120 -338
Branches 6662 6654 -8
==========================================
- Hits 87141 86817 -324
+ Misses 55225 55212 -13
+ Partials 1092 1091 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
🌟 What is the purpose of this PR?
Petrinaut saves and loads nets as JSON, where multi-line code fields (transition kernels, lambdas, metrics) serialize as single lines with
\nescapes. Exports now default to YAML, and every import path — the editor, the CLI's--modeland--optimizationfiles, and the Python bindings that forward paths to the CLI — accepts YAML and JSON interchangeably, detected from the content. Existing JSON files load unchanged, and JSON export stays available in the Export menu.The same field of the SIR example, before and after:
The document opens with format metadata, then the sections in dependency order (the Probabilistic Satellite Launcher example):
An optimization manifest (the CLI's
--optimizationinput) reads the same way — the checked-in supply-chain fixture, with most of the embedded model and all but one binding elided.scenario.idandobjective.metricIdrefer to the scenario and metric insidemodel.definition:🔗 Related links
🔍 What does this change?
@hashintel/petrinaut-coregainsfile-format/document-text.ts.parseDocumentTexttriesJSON.parsefirst, so JSON documents keep their exact semantics, and falls back tojs-yamlwithCORE_SCHEMA, soon/yesstay strings and timestamps stay strings.serializeDocumentencodes either format; its YAML output writes multi-line strings as literal block scalars, never folds long lines, and writes repeated objects in full instead of anchor/alias references.parseSDCPNDocument(text)is the text-level counterpart toparseSDCPNFile(data), andserializeSDCPNtakes aformatoption that defaults to"yaml". A consumer that re-parsesserializeSDCPNoutput withJSON.parsemust now passformat: "json"..yaml,.yml, and.json. Actual mode's Export Net follows the YAML default.subnetsandcomponentInstances, absent from that example, come afterdifferentialEquationsandplacesrespectively. Subnet keys are ordered the same way, a compile-time check fails whenSDCPNgains a field without an export position, and import accepts any key order.meta, so a hand-written file can declareversion: 1without generator boilerplate. Exports keep writingmeta.generator: older importers require it on versioned files, so removing it would make new exports unreadable there.Pre-Merge Checklist 🚀
🚢 Has this modified a publishable library?
This PR:
Patch changesets for
@hashintel/petrinaut-coreand@hashintel/petrinaut.📜 Does this require a change to the docs?
The changes in this PR:
🕸️ Does this require a change to the Turbo Graph?
The changes in this PR:
🛡 What tests cover this?
document-text.test.tscovers format detection, JSON-first parsing, error selection, core-schema scalars, block scalars, and the throw on values YAML cannot represent.serialize-sdcpn.test.tsround-trips serialize → parse in both formats, with and without visual info.❓ How to test this?
yarn workspace @hashintel/petrinaut devand load an example net..jsonexport; both load.node libs/@hashintel/petrinaut-cli/dist/cli.js serve --model <file>.yaml --stdioanswers{"id":1,"method":"metadata"}.🤖 Generated with Claude Code