Open
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
2 Skipped Deployments
|
Collaborator
Author
This stack of pull requests is managed by Graphite. Learn more about stacking. |
3a765f9 to
e8797e1
Compare
bee92fd to
0594dc7
Compare
0594dc7 to
c2d33b0
Compare
c77c244 to
d3af22f
Compare
4 tasks
Renames the "Initial state" place property to "Default starting place" and swaps the header switch for a ds-components Checkbox rendered to the left of the section label. Adds a `renderHeaderLeading` prop to `Section` to support leading header actions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewords the hint to convey that the place should have an initial marking defined to run the net, and notes it will be pre-selected in new scenarios. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wires Monaco editor diagnostics and inline identifier/name validation into the scenario form: single-line CodeEditor gains a `hasError` red border plus focus/blur callbacks so errors don't flash while typing, and the form highlights invalid scenario-parameter identifiers. Refines the Initial State section: places display a color dot next to their name, the two switches are grouped distinctly, and the section now shows an empty-state message pointing users to the "Default starting place" flag when no places are marked and "Show all" is off. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a 480px max-width (and consistent gap) to the parameter row in simulation-settings so the label and input don't drift far apart when the bottom panel is wide. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add missing `type: "standard"` on InputArc literals in code-editor stories to satisfy the discriminated-union schema. - Widen scenario code return type to `unknown` so the null/object guard in compile-scenario is not flagged as unnecessary. - Disable `no-unsafe-assignment` where `expect.any(Object)` is used. - Suppress `no-use-before-define` where `initialize` references late-defined refs via a render-time closure. - Replace the now-unused `react-hooks/exhaustive-deps` disable on the simulation-timeline useMemo with a plain explanatory comment. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tanstack/react-form → @tanstack/react-store pulls in the pure-CJS
use-sync-external-store, whose `require("react")` calls were surviving
rolldown's lib build (react is external) as a runtime require helper
that throws in the browser. Externalising use-sync-external-store and
its subpaths pushes the CJS→ESM interop to the consumer's bundler,
which handles it via pre-bundling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3a23cdd to
75f9df5
Compare
6475016 to
9b08ebd
Compare
The per-planet scenarios previously let users tweak
`gravity_force`/`planet_radius`, which are actually planet-defining
constants — not meaningful to adjust at experiment time. They also
hardcoded the launch distance (80) and rate (1) inside the transition
kernel.
Rework so each scenario hardcodes the planet-defining constants
(`gravitational_constant`, `planet_radius`) as parameter overrides,
and exposes three user-tweakable scenario parameters that flow
through newly-added SDCPN parameters into the code:
- `altitude` → SDCPN `altitude` → kernel distance
(planet_radius + altitude)
- `rate` → SDCPN `launch_rate` → Lambda rate
- `velocity` → SDCPN `initial_velocity`→ kernel satellite velocity
The Lambda now returns `parameters.launch_rate`, and the
TransitionKernel computes the spawn position from
`planet_radius + altitude` and the initial velocity mean from
`initial_velocity` (with a 10% Gaussian spread).
Note: an "altitude deviation" scenario parameter was considered but
skipped — combining two distributions (angle + altitude) into a
single coordinate field isn't expressible with the current
`Distribution.map` API without breaking simulator determinism.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- altitude → satellite_initial_altitude - rate → launch_rate - velocity → satellite_initial_velocity launch_rate is now listed first in each scenario so it appears at the top of the scenario-parameters UI. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The previous rename commit only updated Moon Orbit's parameterOverrides (the replace pattern matched a comment that only existed there). Earth, Mars, and Solar orbit were still forwarding from the old scenario.altitude / scenario.rate / scenario.velocity identifiers, which no longer exist — causing those scenarios to fail to compile. Point them at the renamed scenario params. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The existing sandbox shadowed `Function` via a local `var`, which only
prevents identifier lookup. An attacker could still reach the real
Function constructor via any literal's `.constructor.constructor`
chain (e.g. `({}).constructor.constructor("return this")()`), because
property access bypasses the shadowed identifier and `createSafeObject`
only hardens the `parameters`/`scenario` arguments — not freshly-made
literals inside the expression body.
Add a `runSandboxed` helper that, for the duration of a synchronous
evaluation, replaces the `.constructor` getter on every built-in
prototype a literal can reach (Object, Array, Function, String,
Number, Boolean) with one that throws. Descriptors are restored in
`finally` so the patch is invisible to surrounding code (JS is
single-threaded — no microtasks run until we've reverted).
Apply the sandbox to both `evaluateExpression` and the code-mode
initial-state block, and cover the bypass with tests that confirm
(a) the literal-constructor walk is blocked and (b) prototype state
is restored after evaluation.
The proper fix remains moving scenario evaluation to a Worker/iframe
realm; this is defense-in-depth for the same-realm case.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a "Default Production" scenario with three user-tweakable params: - raw_material (integer) - machines_count (integer) - initial_machine_damage (ratio) RawMaterial is uncolored, so its initial count could be set via a per-place expression — but AvailableMachines is colored (type Machine with `machine_damage_ratio`) and per-place mode only accepts static number[][] for colored places. Using code-mode initialState lets the scenario dynamically generate N machines each with the chosen damage ratio from a single expression. The places RawMaterial and AvailableMachines already had `showAsInitialState: true`, so they're pre-selected in the scenario form — no further net changes required. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
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.
Reviewed by Cursor Bugbot for commit 82406f1. Configure here.
The simulation-settings Select for choosing a scenario was the only
control in the panel that stayed interactive during Running/Paused
state — all other inputs (parameter Switch/Slider/NumberInputs, time
step, ODE solver) already took `disabled={isSimulationActive}`. Wire
the same flag into the scenario picker so it can't swap scenarios
mid-run.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
15 tasks
Users typing "My Variable" or "myVariable" into the scenario parameter identifier field previously saw a validation error until they manually fixed the casing. Add a `snakify` helper (camelCase/PascalCase split, lowercase, non-alphanumerics → single underscore, trim underscores) and call it from the Input's `onBlur`. Empty/invalid inputs collapse to `""` so the existing "cannot be empty" validation still fires. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Kapture.2026-04-15.at.00.36.31.mp4
🌟 What is the purpose of this PR?
Adds basic Scenario support to Petrinaut. A Scenario is a reusable initial configuration (parameter overrides + initial token state) that can be selected before running a simulation.
This is a first pass — future work should harmonize the type system across Color dimensions, Net Parameters, and Scenario Parameters, which all share similar structure but are currently modeled independently.
At a high level, this PR introduces: scenario CRUD (create/edit/save), an expression-based LSP for scenario fields (with type-checking, completions, hover), a scenario compiler that evaluates expressions into concrete simulation state, and the UI to select and configure scenarios before running.
🔗 Related links
🔍 What does this change?
Scenario data model
Scenariotype with scenario parameters, parameter overrides, and initial state (discriminated union:per_placewithstring | number[][]orcodewithstring)ScenarioParameterwith types: real, integer, boolean, ratioScenario form & drawers
LSP integration
temp/scenario/initialize,didChange,killprotocol messagesscenarioobject for accessing scenario parameters in expressionsScenario compiler (
compile-scenario.ts)new Function()evaluation (strict mode, prototype-less frozen objects, shadowed globals)Simulation integration
SimulationContextgainsselectedScenarioId,scenarioParameterValues,compiledScenarioResultparameterValuesandinitialMarkingin contextinitialize()reads from effective (scenario-overridden) refsaddScenario,updateScenario,removeScenario) bypass simulate-mode read-only guardSimulation Settings
UI polish
forwardsto avoid transform stacking context)Examples
population(int) +infected_ratio(ratio) params, expression-derived initial stateOther
🛡 What tests cover this?
compile-scenario.test.ts: 25 tests covering expression evaluation, scenario parameters, Math functions, ternaries, rounding, error handling, sandboxing (prototype chain, globals), and colored place data❓ How to test this?