H-6456: Update hCore (2026-05)#134
Draft
judeallred wants to merge 155 commits intomainfrom
Draft
Conversation
Comment on lines
+26
to
+53
| name: Lint, Test & Build | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: "24" | ||
| cache: yarn | ||
| cache-dependency-path: apps/sim-core/yarn.lock | ||
|
|
||
| - name: Install dependencies | ||
| working-directory: apps/sim-core | ||
| run: yarn install --frozen-lockfile --ignore-scripts | ||
|
|
||
| - name: ESLint | ||
| run: npx eslint --quiet "src/**/*.{ts,tsx}" | ||
|
|
||
| - name: TypeScript | ||
| run: npx tsc --noEmit | ||
|
|
||
| - name: Unit tests | ||
| run: npx jest --forceExit --testPathIgnorePatterns "/node_modules/|/tests/e2e/" | ||
|
|
||
| - name: Production build | ||
| run: yarn build |
| // >>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:README.md | ||
| // Try it on https://regex101.com/r/aw03un/1 | ||
| const GIT_CONFLICT_MARKERS_REGEX = | ||
| /(^<<<<<<< \w+:\w+.+\s)((?:.|\s)*?)\s(=======\s)(^(?:.|\s)*?)(^>>>>>>> \w+:\w+.+\s)/gm; |
| // >>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:README.md | ||
| // Try it on https://regex101.com/r/aw03un/1 | ||
| const GIT_CONFLICT_MARKERS_REGEX = | ||
| /(^<<<<<<< \w+:\w+.+\s)((?:.|\s)*?)\s(=======\s)(^(?:.|\s)*?)(^>>>>>>> \w+:\w+.+\s)/gm; |
|
|
||
| export const yieldToBrowser = () => | ||
| new Promise<void>((resolve) => { | ||
| const uid = Math.random(); |
Comment on lines
+188
to
+201
| <div className="ProcessChart"> | ||
| <div className="ProcessChart__Header"> | ||
| <h3>Process Model Chart</h3> | ||
|
|
||
| <div className="ProcessChart__ChartSelect"> | ||
| {isDraft && <span className="ProcessChart__DraftLabel">DRAFT</span>} | ||
|
|
||
| <select | ||
| onChange={(event) => setProcessChart(event.target.value)} | ||
| value={processChartOption} | ||
| > | ||
| <option value={newProcessChartValue}>New process</option> | ||
| {chartFiles.map((file) => ( | ||
| <option key={file.path.name} value={file.path.name}> |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-authored-by: David @ HASH <6226576+nonparibus@users.noreply.github.com>
Co-authored-by: David @ HASH <6226576+nonparibus@users.noreply.github.com>
Co-authored-by: David @ HASH <6226576+nonparibus@users.noreply.github.com>
Co-authored-by: David @ HASH <6226576+nonparibus@users.noreply.github.com>
Co-authored-by: David @ HASH <6226576+nonparibus@users.noreply.github.com>
Co-authored-by: David @ HASH <6226576+nonparibus@users.noreply.github.com>
Co-authored-by: David @ HASH <6226576+nonparibus@users.noreply.github.com>
Co-authored-by: David @ HASH <6226576+nonparibus@users.noreply.github.com>
Co-authored-by: David @ HASH <6226576+nonparibus@users.noreply.github.com>
Co-authored-by: David @ HASH <6226576+nonparibus@users.noreply.github.com>
Co-authored-by: David @ HASH <6226576+nonparibus@users.noreply.github.com>
Co-authored-by: David @ HASH <6226576+nonparibus@users.noreply.github.com>
Co-authored-by: David @ HASH <6226576+nonparibus@users.noreply.github.com>
- This is so that environments with an empty 'localstorage' don't get a blank page. - Also hide the 'my projects' link to the /user page
- limits top-level folders to our approved list of src, data, views, dependencies - omits hidden "." files from the import - omits files of unsupported types (as enforced by the preexisting file parsing code) - strips empty top-level folders from the import
- The resource browser in the left panel - The 'cloud' options in the experiment dialog
Three root causes prevented these tests from passing: 1. Helper timeouts too short: stepSimulation/playSimulation/resetSimulation waited only 10s for WASM init; increased to 30s to match actual load times. 2. Missing Symbol.observable on stores: The analysis middleware uses RxJS fromStore() which requires Symbol.observable. Added the protocol to both appBridge and reduxCompat createStore, fixing the crash when clicking the Analysis tab. 3. No file persistence to localStorage: Edits in Monaco were never written back to localStorage, so changes were lost on refresh. Added debounced auto-persist in StoreSync that writes the current project + files to localStorage when filesState changes. Also implemented two stub persistence tests with real assertions: project-changes-persist-after-refresh now edits init.js and verifies the marker survives reload, and custom-project-loadable verifies the project has files loaded from localStorage. Made-with: Cursor
Made-with: Cursor
…ntity mutations Made-with: Cursor
…ection Made-with: Cursor
…tor patterns Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
… verified Made-with: Cursor
…tics Made-with: Cursor
…ce plan Made-with: Cursor
Major upgrade spanning 27 minor versions. Replace vite-plugin-monaco-editor-esm with Vite-native worker config. Fix breaking API changes (getModeId, cursorSmoothCaretAnimation, forceTokenization, addDynamicKeybinding). Enable bracket pair colorization, sticky scroll, inlay hints. All 78 E2E tests pass with zero console errors. Made-with: Cursor
Made-with: Cursor
Move example .zip files from apps/sim-core/example_projects/ into packages/core/public/example_projects/ so Vite serves them as static assets. Add a manifest.json describing all 13 examples. Architecture changes: - Delete builtinSimulations.ts (177-line inline data blob) - bootstrapQuery now fetches manifest.json to populate examples list - DefaultProject auto-imports the default example zip on first visit (instead of reading pre-seeded localStorage data) - Example projects menu items fetch+import zips on click instead of navigating to hardcoded routes - Extract parseZipToProject() and fetchAndParseProject() as reusable functions from the import hook - Add useImportProjectFromUrl hook for programmatic zip imports Also removes the redundant generated wildfires-regrowth.zip and updates E2E test helpers, ARCHITECTURE.md, and README.md. Made-with: Cursor
…intercept - Add --use-gl=angle --use-angle=swiftshader to Playwright Chromium config to fix WebGL context creation failures in headless mode - Add WebGL error strings to smoke test console error filter (pre-existing) - Rewrite example-projects.spec.ts to use Playwright route interception: intercepts manifest.json to set each example as default, so the normal auto-import flow tests each zip in isolation (avoids "Data missing for run" error from same-session project switching) - All 13 example projects pass: load, render viewer, and step simulation - Update TODO.md: add Phase 5b (example projects architecture), update test table, bump last-updated date to March 2026 E2E results: 75 passed, 3 flaky (pass on retry), 10 pre-existing failures Made-with: Cursor
- Restore wildfires-regrowth.zip from git history (was incorrectly deleted during the zip-based architecture migration) - Add wildfires-regrowth to manifest.json as the default example (matches original behavior where wildfires was the default simulation) - Move default flag from ant-foraging to wildfires-regrowth - Add E2E test verifying the File > Example projects menu lists all 14 examples from the manifest - All 15 example project tests pass (14 load+step + 1 menu verification) Made-with: Cursor
When switching projects, the simulator store resets simulationData to {}
before React unmounts ActivityHistorySingleRun/ExperimentGroup components.
useSyncExternalStore fires getSnapshot synchronously on the still-mounted
components, whose selectors threw on missing run data, triggering the
error boundary.
Fix: return null from stale-data selectors instead of throwing, and
render nothing while data is missing. All hooks remain unconditional
to satisfy React's rules of hooks.
Includes E2E test that reproduces the exact user flow (load example A,
switch to example B via File menu) and verifies no crash.
Made-with: Cursor
The root cause of 8/14 example project failures was in the WASM engine's initial state deserialization. `serde_wasm_bindgen::from_value` with `deserialize_struct` only iterated the 15 built-in field names, silently dropping custom properties like scatter_templates, strain, height_scaling. Switched to JSON-based `from_js_json` which correctly processes all keys. Additional fixes: - Add toError/extractErrorMessage utilities for robust WASM-JS error handling (eliminates "[object Object]" error messages) - Fix remove_agent crash when msg.data is undefined (remove_self behavior) - Improve middleware error extraction for non-Error runner errors - Harden JsCustomBehavior error paths against cascading WASM failures - E2E tests now run 5 simulation steps with real assertions instead of silently swallowing step failures Made-with: Cursor
Root cause: During the Redux-to-Context migration, Monaco model sync moved from store.subscribe() (synchronous during dispatch) to useEffect (runs after render). This meant models didn't exist when HashCoreEditorFile rendered, leaving the editor showing stale content from the previous project. Fix: Call syncModels synchronously during MonacoModelSync's render phase (guarded by a ref to skip redundant calls), restoring the timing guarantee that models exist before the editor tree renders. Also removes the _modelsVersion / MODELS_SYNCED band-aid that forced a second render cycle — the synchronous approach is both simpler and matches the original Redux behavior. Adds E2E test that loads two different examples and verifies the editor content updates. Made-with: Cursor
…tions promise-worker-transferable fires each message callback without awaiting the previous one, allowing concurrent WasmRequestHandler instances that share mutable RunnerState. When switching from a running simulation, the `initialize` handler would set `runner.simulationRunId` to the new ID before its first `await`, while a stale in-flight `getReadySteps` handler was still building its response. The stale response would carry the new ID with old step data, corrupting the new simulation's store entry and leaving the viewer with a mismatched step count (blank display). Two fixes applied: - Serialize worker message handling via a promise queue so handlers execute one at a time - Defer setting runner.simulationRunId until after async initialization completes, and clear accumulatedSteps early, so any concurrent handler capturing runner state sees the old ID (harmlessly discarded by the main thread) Made-with: Cursor
Audited fork/main (11273e1..91e2f46) vs modernization; cherry-picks conflict wholesale, so applied equivalents manually. Ported (by original fork/main commit intent): - 91e2f46, 7fb8761: ignore tsconfig.tsbuildinfo and .vercel under apps/sim-core - f9b4b7b: Help menu link to GitHub issue chooser + rel on docs link - 6eb3fdb: preview:core script (yarn ws:core start / vite preview) - 2e69841: engine-web and utils fmt use && and explicit --write/--check (cross-shell) - 110c4a3: Mapbox spelling in GeospatialMap placeholder copy Dismissed as superseded or incompatible with modernization: - b149727 OSS hCore import, 9bbae6c project creation, b3f9e0f/5e78ed0 auto-types/GraphQL paths (removed on modernization) - f2be7a2 Python libs under libs/ (out of sim-core scope; tree differs) - e7469eb Renovate (.github/ out of sim-core policy) - 09d1f25/f62782f Husky (no matching .config/husky prepare on current root) - 517f444 through 154ee9b Vite/webpack/eslint/tsconfig bulk (reimplemented on modernization) - 526ef58 Promise.resolve webworker shim (no matching pattern in tree) - 8da4a2e vercel.json (file absent on modernization branch) - 8688927 vite-env.d.ts (present elsewhere if needed) Co-authored-by: Cursor <cursoragent@cursor.com>
…ntain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.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.
Creating a draft PR based on my fork from https://github.com/judeallred/hashintel-labs.
I expect to have to do a fair bit of iteration to resolve the merge conflicts.