Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

OpenPhysics org scripts

Utilities for reading structure/repos.json and operating on OpenPhysics repositories. These scripts are intended for local use and for AI agents working in the monorepo checkout.

Prerequisites

  • jq
  • gh for GitHub sync commands
  • Node.js + npm install (in the repo root) for the screenshot and thumbnail scripts — installs Playwright and sharp

Quick reference

Script Purpose
parse-repos.sh Core parser/CLI for repos.json
list-repos.sh Human-friendly listing wrapper
check-repos-catalog.sh Validate repos.json against structure/repos.schema.json + fleet invariants
check-uncataloged.sh Detect org repos on GitHub that are missing from repos.json (catches un-onboarded repos)
clone-fleet.sh Clone/update every catalog repo into the workspace as a sibling
fleet Run a git command across every local checkout (fleet push, fleet status -s, …)
fleet-exec.sh Run a command across many repos and open one PR each
../doc/fleet-git.md Cheat sheet: everyday git across local checkouts (pull/push/status all)
sync-github-metadata.sh Push description + website to GitHub
sync-github-settings.sh Check/apply GitHub repo settings baseline (security + feature flags)
../doc/github-repo-settings.md Documented GitHub settings baseline for sims
create-sim.sh Bootstrap a new sim from SceneryStackTemplate (rename + N screens; --onboard applies the full baseline incl. GitHub settings; --existing adopts a repo already on GitHub; --pr / --shared-model)
sync-claude-settings.sh Roll the scenerystack Claude Code plugin out to sim repos' .claude/settings.json
lib/repos.sh Bash helper functions for other scripts
check-repo-compliance.sh README/CI/structure compliance (bootstrap, i18n, memory-leak suite, KeyboardHelp, githooks, …)
check-skills.sh Validate the skills/ collection and its README index (Baton self-check)
check-node-version.sh Assert fleet Node major agrees across workflows; with sibling checkouts, also engines.node / @types/node
sync-dependabot.sh Copy Dependabot configs from config/ to catalog npm/pip repos (see structure/repos.json)
generate-pages-index.sh Build docs/index.html simulation landing page
make-thumbnails.mjs Downscale screenshots/*.png to docs/assets/*.webp with sharp
generate-screenshots.sh Capture each sim's screen to <sim>/assets/screenshot.png
screenshot.mjs Playwright driver behind generate-screenshots.sh
../.github/workflows/refresh-screenshots.yml Weekly/manual Pages thumbnail refresh → PR

parse-repos.sh

Primary entry point for agents. Reads structure/repos.json and adds computed fields:

  • githubHomepage — normalized Pages URL (https://openphysics.github.io/{name})
  • localPath — sibling directory in the workspace checkout
  • localExists — whether that directory is present locally
# All repository names
scripts/parse-repos.sh names

# Simulation repos only
scripts/parse-repos.sh names --simulation

# Full JSON with computed fields
scripts/parse-repos.sh list --format json --simulation

# One repo
scripts/parse-repos.sh get DopplerEffect

# Local checkout paths for sims that exist on disk
scripts/parse-repos.sh paths --simulation --require-local

# Run a command per repo (env: REPO_NAME, REPO_DISPLAY_NAME, REPO_LINEAGE, REPO_HOMEPAGE, REPO_PATH, ...)
scripts/parse-repos.sh for-each --simulation -- \
  echo "$REPO_NAME ($REPO_LINEAGE) -> $REPO_HOMEPAGE"

# Catalog summary
scripts/parse-repos.sh summary

Filters:

  • --type simulation|template|config|hardware-interface|tool
  • --status active|template|draft|wip|archived
  • --lineage original|phet|naap
  • --simulation / --no-simulation

clone-fleet.sh

Populate the workspace from the catalog: clone every selected repo as a sibling directory beside Baton. repos.json is the single source of truth — there are no submodules, so a repo appears here the moment it is added to the catalog. Re-runnable and safe: repos already on disk are skipped unless --update is given (which git pull --ff-onlys them).

The thin OpenPhysics superproject's bootstrap.sh clones Baton and then calls this; run it directly once you already have Baton.

# Clone whatever is missing into the workspace
scripts/clone-fleet.sh

# Only the simulations, and fast-forward any already present
scripts/clone-fleet.sh --simulation --update

# Preview the plan, change nothing (HTTPS instead of SSH)
scripts/clone-fleet.sh --dry-run --https

Reuses the same catalog filters as parse-repos.sh (--simulation, --type, --status, --lineage, --only NAME, --skip NAME). Clones over SSH by default; --https for token/anonymous use.

fleet

Run any git command across every catalog repo already checked out locally:

# put on PATH once (if ~/.local/bin is already there)
ln -sfn ~/OpenPhysics/Baton/scripts/fleet ~/.local/bin/fleet

fleet push
fleet pull --ff-only
fleet status -s
fleet --simulation log -1 --oneline

Same catalog filters as parse-repos.sh. Full cheat sheet: doc/fleet-git.md.

fleet-exec.sh

Fan a change out across the org: clone each selected repo, run a command in it, and — with --apply — push a branch and open one PR per repo. Dry-run by default (prints a diffstat per repo and opens nothing). Reuses the same catalog filters as parse-repos.sh.

# Preview bumping a dependency across every simulation (no PRs):
scripts/fleet-exec.sh --simulation -- npm pkg set dependencies.scenerystack=^3.1.0

# Apply a Biome autofix across all sims and open one PR each:
scripts/fleet-exec.sh --simulation --apply --install \
  --branch chore/biome-fix --title "chore: biome autofix" -- npm run fix

Key options: --apply (push + open PRs), --install (npm install before the command, needed for lint/build codemods), --branch, --title, --label, --skip NAME, --keep.

Pushing and opening PRs needs a token with write access to the target repos — your local gh auth, or an org PAT / GitHub App token as GH_TOKEN. The default GITHUB_TOKEN only reaches the repo running a workflow, so the fleet-exec.yml dispatch wrapper reads a FLEET_PAT secret for apply=true.

sync-github-metadata.sh

Updates GitHub Description and Website from repos.json:

scripts/sync-github-metadata.sh --dry-run
scripts/sync-github-metadata.sh
scripts/sync-github-metadata.sh --repo SceneryStackTemplate

Note: GitHub does not expose API toggles for Deployments / Packages in the About sidebar. Descriptions longer than 350 characters are truncated with a warning (GitHub’s API limit).

sync-github-settings.sh

Check or apply the canonical GitHub repository settings baseline (config/github-repo-baseline.json): wiki/Projects off, Dependabot alerts + security updates, secret scanning + push protection, private vulnerability reporting, and Pages build_type=workflow. Full write-up: ../doc/github-repo-settings.md.

scripts/sync-github-settings.sh --check                 # sims + template; exit 1 on drift
scripts/sync-github-settings.sh --apply --repo MyNewSim # fix one repo
scripts/sync-github-settings.sh --apply --all           # every catalog repo
scripts/sync-github-settings.sh --apply --dry-run       # show planned fixes

Use this after creating a new sim (GitHub defaults diverge from the fleet) instead of inspecting a mature sim by hand.

sync-claude-settings.sh

Roll the scenerystack Claude Code plugin out to the SceneryStack repos by merging the canonical keys from config/claude-settings.json into each repo's .claude/settings.json. It only adds/updates extraKnownMarketplaces.openphysics and enabledPlugins["scenerystack@openphysics"] — existing keys in a repo's settings are preserved. Targets every catalog repo whose framework is SceneryStack. Writes files only; commit/push (or fan out as PRs via fleet-exec.sh) is left to you.

scripts/sync-claude-settings.sh --dry-run     # show what would change, write nothing
scripts/sync-claude-settings.sh               # merge into each sibling repo
scripts/sync-claude-settings.sh DopplerEffect # limit to named repo(s)

Self-check scripts

Run by baton-selfcheck.yml on every PR or main push that touches skills/, .claude-plugin/, scripts/, or Baton's own .github/workflows/.github/actions, and runnable locally:

scripts/check-skills.sh         # every skills/<name>/SKILL.md is well-formed and indexed in skills/README.md
scripts/check-node-version.sh   # all setup-node workflows declare the same Node version

Adding a simulation

End-to-end checklist (create repo → repos.json → screenshot → WebP → regenerate docs/index.html): ../doc/add-simulation.md.

create-sim.sh --onboard does the whole thing in one shot — catalog row, screenshot + WebP + Pages index, and the GitHub settings/metadata/Dependabot/Claude baseline.

Adopting a repo that already exists on GitHub

If the repo was created some other way and just needs fleet onboarding, pass --existing (skip the template/rename/scaffold dance):

scripts/create-sim.sh --existing --repo HeatTransfer --name "Heat Transfer" --onboard

Catching un-onboarded repos

A repo can exist on GitHub but never make it into repos.json, which makes it invisible to every fleet tool. This check diffs the live org against the catalog (run by baton-selfcheck on PRs touching scripts//structure/):

scripts/check-uncataloged.sh

check-uncataloged.sh

Lists repos under the GitHub org that are missing from structure/repos.json, so a forgotten onboarding can't stay hidden. Intentional non-members (the superproject itself, the textbook bundle) are kept in an in-script allowlist, extendable via UNCATALOGED_ALLOWLIST or structure/uncataloged-allowlist.txt. Requires gh (authed) and jq; exits 1 if any uncataloged repo is found.

generate-screenshots.sh

Captures a screenshot of every SceneryStack simulation into <sim>/assets/screenshot.png. It serves each sim's built dist/ and renders the requested screen with the sim's own ScreenshotGenerator (the same code path as the in-app camera button), so the result is a clean PNG at the sim's nominal layout — not a raw viewport grab. Multi-screen sims are forced onto a single screen with ?screens=N, so the capture is that screen's play area rather than the home-screen selector.

# One-time setup: install Playwright (declared in this repo's package.json)
npm install
# If Chromium is not already cached: npx playwright install chromium

# Capture every sim's first screen (reuses dist/ if already built)
npm run screenshots
# or directly:
scripts/generate-screenshots.sh

# Force a rebuild first, capture a specific screen, or limit to some sims
scripts/generate-screenshots.sh --build
scripts/generate-screenshots.sh --screen 2 Resonance OscillationsAndChaos

Options: --build (force npm run build), --screen N (default 1), --width/--height (default 1154×753, matching existing assets). Trailing positional arguments limit the run to the named sims.

screenshot.mjs is the underlying Playwright driver and can be run on a single dist directory:

node scripts/screenshot.mjs --dist ../DopplerEffect/dist --out /tmp/shot.png --screen 1

It discovers a usable Chromium automatically (Playwright's bundled build, the newest cached build, or a system Chromium); override with PLAYWRIGHT_CHROMIUM_EXECUTABLE.

Bash helpers

Source from other scripts:

source "$(dirname "$0")/lib/repos.sh"
repos_simulation_names | while read -r sim; do
  echo "$sim"
done

Or call the CLI directly:

scripts/parse-repos.sh names --simulation

Workspace layout

Scripts assume the orchestration Baton repo lives beside member repos:

OpenPhysics/
  Baton/            ← this repo
  DopplerEffect/
  SceneryStackTemplate/
  ...

If your checkout differs, set OPENPHYSICS_WORKSPACE or pass --catalog /path/to/repos.json.