name: updating-yoga description: Updates the Facebook Yoga layout library to a new version — bumps sources.yoga + the lockstep pin, rebuilds the WASM module (which regenerates YGEnums.mts from the C++ header), and AI-assists the wrapAssembly.mts re-port when upstream's JS layer changed. Use for Yoga version bumps, Flexbox/layout fixes, or periodic yoga maintenance. user-invocable: true allowed-tools: Bash(pnpm:), Bash(npm:), Bash(git:), Bash(node:), Bash(rg:), Bash(grep:), Bash(find:), Bash(ls:), Bash(cat:), Bash(head:), Bash(tail:), Bash(wc:), Bash(diff:*), Read, Edit, Glob, Grep---
updating-yoga
Update the Yoga layout library to latest stable version.
- Version source:
packages/yoga-layout-builder/package.jsonundersources.yoga - Source: Cloned from GitHub (not submodule) during build
- Cache bumps:
yoga-layout - Downstream: Rebuild downstream consumers (e.g. opentui-builder, node:smol-tui) to pick up the new yoga-sync.mjs
Build Architecture
Produces the official yoga-layout npm API via WASM:
- Uses official
embind.cpp,Node.cpp,Config.cppbindings from upstream - Wraps with
wrapAssembly.mtsforYoga.Node.create(),node.free(), etc. - Sync wrapper generation uses AST-based transforms (acorn + MagicString)
Two wrapper surfaces, two maintenance models
src/wrapper/ has two files with DIFFERENT upkeep on a yoga bump:
YGEnums.mts— GENERATED, zero manual work. The build (scripts/source-cloned/shared/generate-enums.mts, run fromclone-source.mts) regenerates it fromupstream/yoga/yoga/YGEnums.hon every build. The header and theembind.cppthe WASM compiles from are the same pinned submodule checkout, so enum values can never drift from the binary's ABI. Never hand-edit it; never diff it during an update. A bump regenerates it automatically and the build re-stamps its@ yoga <ver>header.wrapAssembly.mts— manual 1:1 re-port of FB's own JS layer. Carries behavioral logic we deliberately do not reinvent: string-unit setters ("100%"/"auto"), measure/dirtied callback marshalling, and the JS-GC ↔ yoga-manual-alloc memory reconciliation (Node.create/free/freeRecursive,Config.free). Carries aLock-step from upstream: yoga/javascript/src/wrapAssembly.ts @ yoga <ver>marker (build re-stamps the version). On a bump where upstreamwrapAssembly.tsCHANGED, it needs a behavioral re-port — step 5.
Process
- Validate: Clean working directory, detect CI mode
- Fetch latest: Query GitHub API for latest stable release and commit SHA
- Check: If already at latest, report and exit
- Update package.json: Edit
sources.yoga(version, ref); update theyogarow'spinned_sha/pinned_tagin.config/lockstep.json. - Reconcile the behavioral wrapper. YGEnums needs nothing (the build
regenerates it). For
wrapAssembly.mts: diff upstreamwrapAssembly.tsbetween the OLD and NEW yoga tags; if it changed, re-port the behavioral delta with the fleet locked-down agent + bump the lockstepforked_at_sha. Full recipe (diff command,ai/spawn+AI_PROFILE.editcall, smoke-test feedback loop, human-review gate): see reference.md → "Wrapper Files Sync". - Build/test (skip in CI):
pnpm run clean && pnpm run build --force && pnpm testinpackages/yoga-layout-builder, then test ink integration. The build regeneratesYGEnums.mts; if it changed, that's the new yoga's enums — commit it. - Bump cache: Increment
yoga-layoutin.github/cache-versions.json - Commit: Include package.json, lockstep.json, cache-versions.json, the regenerated
YGEnums.mts, and any re-portedwrapAssembly.mts. - Report