Skip to content

Development

Mark Rogers edited this page Oct 18, 2026 · 2 revisions

How the repository is laid out, how to test a change, and how a release is made. The rules for agents working in the repository are in AGENTS.md; session notes, the handoff and the research are under ai-docs.

Layout

Path What
skills/polywright/scripts/pw.py The command-line tool: standard-library Python 3.9 or newer, one JSON object per command
skills/polywright/scripts/pw_bpy.py Its Blender half, run inside Blender (or a Python with the bpy module); never run by hand
skills/polywright/references/targets.json The budgets pw.py check reads, each with its source
skills/*/ The seven skills and their companion files (The skills)
tests/ check_skills.py, test_pw.py, test_recipes.py, run_evals.py and fixtures
scripts/budget.py The size budget
ai-docs/ Handoff, log, decisions, research notes, and the wiki's verification program and output

Testing a change

From the repository root:

python tests/check_skills.py
python tests/test_pw.py
python tests/test_recipes.py
python scripts/budget.py
  • check_skills.py: frontmatter, the 1,024-character description limit, the companion files, the manifests, relative links, and guards against home-folder paths, the owner's own paths and AI attribution. It also fails when pw.py's VERSION differs from .claude-plugin/plugin.json (since 0.1.2).
  • test_pw.py: geometry, file formats, the manifest, an offline place, the ComfyUI workflow converter, and Blender-backed inspect, render, convert, printable, union and the bpy runner. The Blender tests skip when no Blender is found.
  • test_recipes.py: runs every # recipe: block in skills/polywright-blender/references/bpy-recipes.md in Blender and requires its [pw] ok line.
  • budget.py: what every session loads (the seven descriptions) and the installed size, against green, yellow and red limits. Red fails CI.

Point the tests at a Blender with POLYWRIGHT_BLENDER=<path to blender>, or at a Python 3.13 with the bpy wheel with POLYWRIGHT_BPY_PYTHON=<python>.

CI

.github/workflows/tests.yml runs on every push to main and every pull request:

Job Runs
structure Linux, macOS and Windows, Python 3.9 and 3.14: check_skills.py and test_pw.py (Blender parts skip)
blender Linux, Python 3.13 with bpy 5.2.2 from PyPI and Mesa's software EGL: test_pw.py with Blender and every recipe
budget budget.py

The Mesa packages are there because GitHub's Linux runners have no GPU: without them Blender stops rendering with "Couldn't open libEGL.so.1".

Testing the skills themselves

Each skill's evals/evals.json holds trigger cases, decoys, an action case and an outcome case. Since 0.2.0, tests/run_evals.py runs them (standard library only; it needs the claude command and spends API credit):

python tests/run_evals.py --kinds trigger --runs 3 --out evals-out
python tests/run_evals.py --skills polywright-print --ids action-1 --runs 1 --out evals-out
python tests/run_evals.py --kinds outcome --baseline --out evals-out
  • Every run is a fresh headless session (claude -p) in a throwaway copy of the repository, with this checkout loaded through --plugin-dir and any installed polywright switched off, so the descriptions under test are the ones on disk. --baseline loads no polywright at all.
  • Grading uses evidence in the trace, never the final message's claims. A trigger passes when the trace has a Skill call naming the skill, and a decoy when it has none. An action case passes when a tool call's input matches its evidence. An outcome case matches a regex against the answer.
  • Trigger runs cannot run commands or write files: a decoy that loaded another skill once started a real 12-minute GPU job.
  • It writes the stream-json trace per run to OUT/<skill>/<id>-r<n>.jsonl and a summary to OUT/results.json.
  • On Windows, claude is a .cmd shim, so it is started through shutil.which("claude"): the bare name fails to launch and every case looks like a miss.

The run of 2026-10-17 (trigger and decoy cases, three runs each) passed 80 of 87 for about $29. The four weak cases were fixed (a case that named a missing drawing, two descriptions) and passed 24 of 24 on a rerun. Action and outcome cases and baselines are still owed. Each skill's TESTS.md logs the runs.

Releasing

  1. Bump version in .claude-plugin/plugin.json and VERSION in pw.py together, and add the section to CHANGELOG.md.
  2. Merge to main through a pull request with CI green.
  3. Push a tag vX.Y.Z. .github/workflows/release.yml checks the tag against plugin.json, runs the structure checks and the budget, zips skills/ with the README, LICENSE and SECURITY.md, and publishes the GitHub release with that zip.
  4. Update this wiki: rerun ai-docs/notes/2026-10-17-wiki-verify.py <version> and compare its output with the saved one; the procedure is in the wiki note in ai-docs/notes.

Clone this wiki locally