Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
fd4e570
chore(bench): add macos 27 beta webkit bench results
Sep 12, 2026
74a1492
fix(bench): a bare vendor word names no machine either
Exoridus Sep 12, 2026
e73f6ab
build(hooks): let the pre-push gate scope match what the push changes
Exoridus Sep 12, 2026
12bc712
bench: publish the macOS reference run under the machine's CPU-derive…
Sep 12, 2026
f784dc4
bench: publish fx-blur as a cross-arm row and fix what kept it out
Exoridus Sep 12, 2026
b512306
bench: print the run summary as a table, and make the README a guide
Exoridus Sep 12, 2026
958a850
bench: one definition of which archetypes an arm covers, and a border…
Exoridus Sep 12, 2026
ef25056
style(bench): format the phaser adapter
Exoridus Sep 12, 2026
d345efa
bench: measure the reference run on this machine, and let a drawless …
Exoridus Sep 12, 2026
b0e4913
site: name the UI-layout scenario on the benchmarks page
Exoridus Sep 12, 2026
4e5ab44
bench: publish the macOS reference run under the machine's CPU-derive…
Sep 12, 2026
218ad72
bench: add the ui-layout-update arms and stop the catalog dropping a …
Exoridus Sep 12, 2026
28850ae
site(home): offer the latest release beside the install command
Exoridus Sep 12, 2026
50f8d12
release: summarize a changelog entry and fold the rest, and ship a st…
Exoridus Sep 12, 2026
dbfcf7d
docs: one line per changelog entry, long-line prose, subject-only com…
Exoridus Sep 12, 2026
3c58b4d
bench: re-measure the macOS reference run on the current arms
Sep 12, 2026
51dd433
bench: re-measure the macOS reference run on the current arms
Sep 12, 2026
866883b
docs(changelog): render the 0.17.0 section one line per entry
Exoridus Sep 12, 2026
9359925
docs(changelog): render the 0.16.x sections one line per entry
Exoridus Sep 12, 2026
f9df7f9
fix(site): stop publishing an unmeasured comparison as a zero time
Exoridus Sep 12, 2026
3835e95
fix(site): close out the benchmark page and make its markers readable
Exoridus Sep 12, 2026
252b1fa
feat(site): read the benchmark scenarios as one card per domain on a …
Exoridus Sep 12, 2026
3377e23
feat(physics): let a joint take its two bodies out of collision
Exoridus Sep 12, 2026
154f58f
fix(physics): keep joints, bodies and CCD in step with connected-body…
Exoridus Sep 12, 2026
a3ea50c
test(physics): prove the CCD filter and drop the id-reuse claim
Exoridus Sep 12, 2026
241629e
feat(site): compose the benchmark card for a phone and layer the ligh…
Exoridus Sep 12, 2026
e5b930d
fix(physics): hold a revolute chain with the live sub-step geometry a…
Exoridus Sep 12, 2026
f9a92d1
feat(site): pair the benchmark cards editorially and rank the arms of…
Exoridus Sep 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@ jobs:
--repo "${GITHUB_REPOSITORY}" \
--out ".release/release-notes.md"

# A second copy under a version-less name. GitHub serves the assets of the
# newest release at /releases/latest/download/<asset-name>, which is a
# permanent direct-download URL only for a name that does not move with
# the version - so the site can link the archive itself instead of the
# release page. The versioned name stays: it is what a downloaded file
# should be called once it is on disk.
- name: Add the version-less Full ZIP alias
run: cp ".release/exojs-${TARGET_TAG}-full.zip" .release/exojs-full.zip

- name: Create GitHub release with Full ZIP
uses: softprops/action-gh-release@v3
with:
Expand All @@ -170,5 +179,6 @@ jobs:
files: |
.release/exojs-${{ env.TARGET_TAG }}-full.zip
.release/exojs-${{ env.TARGET_TAG }}-full.zip.sha256
.release/exojs-full.zip
.release/artifacts/checksums.sha256
.release/artifacts/release-manifest.json
74 changes: 48 additions & 26 deletions .husky/pre-push
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
#!/usr/bin/env sh
# Pre-push verification.
#
# Branch pushes: `verify:quick` — the static CI-parity gates: typecheck (core
# Branch pushes: first `scripts/ci/push-scope.ts`, which answers how much of
# the below the pushed range needs. A range that changes no
# tracked file verifies nothing; one carrying published
# benchmark data alone runs only `verify:bench-results`, the
# single gate that opens those files. Anything else - including
# a range whose scope cannot be determined - takes the full
# path:
#
# `verify:quick` — the static CI-parity gates: typecheck (core
# + guides + examples + extension packages), lint:all,
# format:check, docs:api:check and the site gates. Then the test
# lanes the pushed range actually requires, chosen from
Expand Down Expand Up @@ -53,20 +61,6 @@ while read local_ref local_sha remote_ref remote_sha; do
esac
done

# verify:quick includes `typecheck:site` and `full-bundle:exports:check`, which
# read the PUBLISHED entry points (package.json `exports` → dist/) rather than
# src/. A dist that is missing fails them with a wall of ts(2307) "Cannot find
# module 'exojs'"; one that merely lags the sources - the state every local
# edit leaves behind - fails the freshness gate inside the site group, after
# the typecheck and lint groups have already run. Either way the push is lost,
# the build runs by hand, and everything runs again. So the build runs here
# instead, exactly when the source stamp says it is due and never otherwise: a
# clean tree pays one hash walk.
if [ "$is_branch_push" = "1" ]; then
echo "[pre-push] checking dist against the sources"
node scripts/check-dist-fresh.ts --rebuild || exit 1
fi

if [ "$is_tag_push" = "1" ]; then
echo "[pre-push] tag push detected - checking the tagged commit is releasable"
git fetch --quiet origin main || exit 1
Expand All @@ -76,24 +70,52 @@ if [ "$is_tag_push" = "1" ]; then
fi

if [ "$is_branch_push" = "1" ]; then
echo "[pre-push] running verify:quick (static CI-parity gates)"
npm run verify:quick || exit 1

# Range for lane selection. A branch with no remote tracking ref yet has no
# base to diff against, so fall back to the merge base with origin/HEAD
# (the remote's default branch, whichever one that is) — and to running
# (the remote's default branch, whichever one that is) - and to running
# every lane if even that is unavailable, because a push whose scope cannot
# be determined must not be validated partially.
lane_base="$push_base_sha"
if [ -z "$lane_base" ] && [ -n "$push_head_sha" ]; then
lane_base=$(git merge-base "$push_head_sha" origin/HEAD 2>/dev/null || true)
fi

if [ -n "$lane_base" ]; then
echo "[pre-push] running the test lanes this push requires"
npm run lanes -- --run --tests-only --base "$lane_base" || exit 1
else
echo "[pre-push] no base commit to scope lanes against — running every lane"
npm run lanes -- --run --tests-only --all || exit 1
fi
# How much of the above the range actually needs. `full` for anything
# `push-scope.ts` does not positively recognise, including an undeterminable
# range, so a narrower answer is always a deliberate one.
scope=$(node scripts/ci/push-scope.ts "$lane_base" "$push_head_sha")

case "$scope" in
none)
echo "[pre-push] the pushed range changes no tracked file - nothing to verify"
;;
data)
echo "[pre-push] published benchmark data only - running its own gate"
npm run verify:bench-results || exit 1
;;
*)
# verify:quick includes `typecheck:site` and `full-bundle:exports:check`, which
# read the PUBLISHED entry points (package.json `exports` → dist/) rather than
# src/. A dist that is missing fails them with a wall of ts(2307) "Cannot find
# module 'exojs'"; one that merely lags the sources - the state every local
# edit leaves behind - fails the freshness gate inside the site group, after
# the typecheck and lint groups have already run. Either way the push is lost,
# the build runs by hand, and everything runs again. So the build runs here
# instead, exactly when the source stamp says it is due and never otherwise: a
# clean tree pays one hash walk.
echo "[pre-push] checking dist against the sources"
node scripts/check-dist-fresh.ts --rebuild || exit 1

echo "[pre-push] running verify:quick (static CI-parity gates)"
npm run verify:quick || exit 1

if [ -n "$lane_base" ]; then
echo "[pre-push] running the test lanes this push requires"
npm run lanes -- --run --tests-only --base "$lane_base" || exit 1
else
echo "[pre-push] no base commit to scope lanes against - running every lane"
npm run lanes -- --run --tests-only --all || exit 1
fi
;;
esac
fi
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Use `CONTRIBUTING.md` when a task touches repository conventions such as imports
package boundaries, distribution, build constants, or public API conventions.
Read package-local documentation when working inside that package.

Prose is written in long lines: pull request descriptions, guides, `docs/`, READMEs, commit bodies. Break a line at the end of a paragraph or where the break carries meaning, never at a column width. Commits are their Conventional Commits subject (with `!` for a breaking change); the detail goes into the pull request description, which the changelog links to and does not copy.

`.workspace/` is private working context, not repository authority. Plans,
research, reviews, and temporary design artifacts belong there by default.
Agents may use relevant files there as context, but they are not part of the
Expand Down
Loading
Loading