Skip to content

Sync 13.7.3 experience cs#1

Closed
DNR500 wants to merge 629 commits into
experience-csfrom
sync-13.7.3-experience-cs
Closed

Sync 13.7.3 experience cs#1
DNR500 wants to merge 629 commits into
experience-csfrom
sync-13.7.3-experience-cs

Conversation

@DNR500
Copy link
Copy Markdown

@DNR500 DNR500 commented May 20, 2026

Relates to issue: 1287

Resolves

Resolves part of #1287 (foundation work only). Product/library URL changes will come in a follow-up PR.

NOTE: CI on scratch has change a lot since the RPF build was last added so this may need some adjustment still

What this PR does

  • Syncs the RPF experience-cs fork with upstream Scratch 13.7.3
  • Restores build + publish for @RaspberryPiFoundation/scratch-gui
  • Publishes packages to GitHub Packages from experience-cs
  • Re-adds RPF packaging, CI publish flow, .npmrc, and webpack config
  • Adds notes for future fork maintenance

Why

Our fork was based on a very old Scratch version. I updated it to 13.7.3, restored automated package publishing, and ensured downstream apps have a maintained RPF package to depend on.

I chose to sync against the Scratch 13.7.3 release tag rather than develop so we avoid unintentionally pulling unreleased upstream changes into RPF builds.

Testing

No new tests in this PR (upstream sync + infrastructure changes only).

Validation

  • Existing CI passes:
    • lint
    • unit
    • integration
    • Playwright
  • After merge, confirm a new package version is published to GitHub Packages
npm run build -w @RaspberryPiFoundation/scratch-gui

Confirm that:

  • dist/scratch-gui.js is generated
  • dist/static/ is generated

Reviewer note

This PR is large because it includes the full upstream 13.7.3 sync history.

Main review focus should be:

  • merge strategy
  • CI publish setup
  • package naming/scoping
  • webpack publicPath

renovate Bot and others added 30 commits March 14, 2026 07:36
…ndation#476)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…vm-state-snapshot

test: add VM state snapshot integration test
…chfoundation#474)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
If the published commit-ish was built and tested before, reuse that
build rather than making a new build. This saves time, but more
importantly it reduces the possibility of introducing new issues
through a rebuild.
If there's some sort of complex emergency where publishing locally is
necessary, use `--ignore-scripts` to skip the `prepublishOnly`
protection.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…scratch-blocks-fixes

More Scratch Blocks fixes
…ate/dorny-paths-filter-4.x

chore(deps): update dorny/paths-filter action to v4
cwillisf and others added 22 commits April 20, 2026 21:50
Projects corrupted by the Blockly blockToDom serialization bug (878291)
contain inputs with shadow references that point to nonexistent blocks.
This causes a TypeError crash in moveBlock when a reporter is dragged
out of such an input, and perpetuates the corruption through save/load.

Three fixes:

1. Load-time repair in deserializeBlocks: after deserialization, scan
   all inputs for shadow references that point to block IDs not present
   in the project. Recreate the shadow block by finding a peer block of
   the same opcode with an intact shadow (peer lookup). Falls back to a
   text shadow if no peer is available. Only primitive shadow types are
   recreated — menu shadows are cleared to prevent crashes.

2. Defensive guard in moveBlock: when restoring a shadow after a block
   is disconnected, check that the shadow block actually exists before
   accessing it. If missing, clear the stale reference instead of
   crashing.

3. findPeerShadow helper: scans the blocks map for another block of
   the same opcode that has a working primitive shadow on the same
   input name, to use as a template for recreation.
The shadow repair pass calls findPeerShadow for every input that has a
broken or missing shadow. This is an O(n) scan per call, which becomes
O(n^2) for projects with many inputs that legitimately have no shadow
(e.g. statement inputs like SUBSTACK). Cache lookup results per
(opcode, inputName) pair so each combination is only scanned once.
…ursed-inputs-shadow-repair

fix(scratch-vm): repair broken shadow references from cursed inputs bug
…ate/pin-dependencies

fix(deps): pin dependencies
When Blockly respawns a shadow (e.g. after uncovering a duplicated
input), the create event arrives with topLevel:true because
appendInternal creates the block before connecting it. A shadow in
_scripts causes "Workspace Update Error" on sprite switch because
toXML serializes it as a root <shadow> element that Blockly cannot
load. This test currently fails — the fix follows in the next commit.
createBlock added any block with topLevel:true to _scripts without
checking the shadow flag. moveBlock already had this guard, but
createBlock did not. Add the same check so that shadow blocks created
via Blockly's respawnShadow_ (which fires a create event with
topLevel:true before connecting the shadow) cannot pollute _scripts.
…hadow-topLevel-scripts

Fix/shadow top level scripts
Pasting blocks from the backpack (no source target) and importing
sprites both rely on `Target.fixUpVariableReferences` to reconcile
variable references against the project. Two gaps caused references
to dangle: `shareBlocksToTarget` only ran reconciliation when called
with a source target, and `fixUpVariableReferences` walked variable
and list references but not broadcast references.

`fixUpVariableReferences` now includes broadcasts via
`getAllVariableAndListReferences(null, true)` and is safe to run on
the stage; the local-vs-global rename branches that don't apply to
the global scope are guarded with `!this.isStage`.
`shareBlocksToTarget` calls it after creating the new blocks when no
source target was provided.

Refs scratchfoundation#533
…ackpack-missing-definitions

fix(scratch-vm): create missing variable and broadcast definitions on import
… load

Projects saved while affected by the missing-definitions bug carry
dangling variable, list, or broadcast references that point at ids
not defined anywhere in the project. PR scratchfoundation#554 stops new occurrences
but doesn't repair already-saved projects, because installTargets
skips reconciliation when wholeProject=true.

Extracts a new public method `Target.reconcileVariableReferences`
that runs only the missing-definitions phase of
`fixUpVariableReferences`: walk every variable / list / broadcast
reference; for each id not found anywhere, look up by name and type
on the stage and either remap to an existing global or create a
fresh one. The disambiguation phases of `fixUpVariableReferences`
(rename sprite-local that name-collides with a stage global, rename
unreferenced colliding locals) are left in `fixUpVariableReferences`
itself, which now delegates the repair phase to the new helper.
This separation matters because running the rename branches on
clean projects would rename legitimately-existing local-vs-global
name collisions, which has been a valid Scratch configuration since
forever.

`installTargets` now calls `reconcileVariableReferences` on every
target during whole-project load, so corrupted projects self-heal
on next open. Logs a warning per definition created or remapped so
the repair surfaces in dev tools and in telemetry. Quiet on clean
loads.

Refs scratchfoundation#533
When two dangling references in one project share an original name and
type and the name has to be bumped (because some other target already
owns that name), the second reference must remap to the stage variable
the first reference created rather than create a second variable. A
Scratcher who pasted scripts referencing what they called the same
name almost certainly meant one variable.

Tracks created stage variables by their original (pre-bump) name+type
within the reconciliation pass and remaps subsequent same-name dangling
references to the earlier-created variable. Also pushes the fresh name
into the cached name list so unusedName accounts for it on later calls.
…onciliation

When whole-project load reconciles every target in turn, an earlier target's
pass can create a stage variable with a bumped name. A later target with a
block referencing the same id by lookup would otherwise keep its original
displayed name, leaving the same variable rendered with different names in
different sprites' blocks.

In `reconcileVariableReferences`, when `lookupVariableById` succeeds, queue
a name update if the field's displayed value doesn't match the resolved
variable's current name. The existing `conflictNamesToReplace` pass applies
the update.
Adds two Tap tests for the list-reference path through
reconcileVariableReferences (creation on stage and remap to an existing
same-name stage list), filling a coverage gap noted in review.

Reword the warning emitted when reconciliation only normalizes a stale
displayed name; the previous wording said "dangling reference" but in
that branch the id resolves to a real variable.
…oad-time-missing-definitions-repair

fix(scratch-vm): repair missing variable and broadcast definitions on project load
@DNR500 DNR500 self-assigned this May 20, 2026
@DNR500 DNR500 marked this pull request as draft May 21, 2026 09:04
@DNR500 DNR500 force-pushed the sync-13.7.3-experience-cs branch from 174ef4a to 5d0dde7 Compare May 21, 2026 10:00
@DNR500 DNR500 closed this May 21, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators May 21, 2026
@DNR500 DNR500 deleted the sync-13.7.3-experience-cs branch May 21, 2026 15:25
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants