Skip to content

Commit e5b1642

Browse files
feat: target Blender 5.2 LTS and witness NodesModifier input writes
* feat: target Blender 5.2 LTS and witness NodesModifier input writes CI was blind to the 5.2 removal of dict assignment on Geometry Nodes modifiers because no example asserted the write. Teach both sides of the split and fail the check if the value does not land. Signed-off-by: fOuttaMyPaint <TMhospitalitystrategies@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com> * ci: remove the 5.2 smoke canary after the red run The 5.2 job downloaded blender-5.2.1-linux-x64.tar.xz, printed Blender 5.2.1 LTS, then exited 1 on the injected canary. The matrix leg executes. Signed-off-by: fOuttaMyPaint <TMhospitalitystrategies@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com> * fix: set VSE render size before 5.2 COLOR strips bake width/height 5.2 COLOR strips get readonly width/height from the scene resolution at new_effect. Creating at factory 1920 then rendering 96 made 0.36-scaled cells cover the frame so the mosaic pixel check sampled amber instead of crimson. Signed-off-by: fOuttaMyPaint <TMhospitalitystrategies@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com> --------- Signed-off-by: fOuttaMyPaint <TMhospitalitystrategies@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent a47218e commit e5b1642

115 files changed

Lines changed: 1418 additions & 170 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.cursor-plugin/plugin.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"examples/gltf-export-roundtrip",
7676
"examples/gltf-skin-roundtrip",
7777
"examples/gn-instance-grid",
78+
"examples/gn-modifier-inputs",
7879
"examples/gn-sdf-remesh",
7980
"examples/gp-lineart-contour",
8081
"examples/grease-pencil-rosette",

‎.github/workflows/blender-smoke.yml‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
name: Blender Smoke Test
22

33
# Executes the snippets' and skills' headline examples inside REAL Blender, headless,
4-
# on the current stable (5.1.x) and the active LTS (4.5.x), and fails on any error or
4+
# on the current stable (5.2.x LTS) and the fallback LTS (4.5.x) on every PR,
5+
# plus 5.1.x on the weekly cron, and fails on any error or
56
# empty-output assertion. py_compile (in validate.yml) cannot catch API-level regressions
67
# like the EEVEE-id inversion, the slotted-actions boundary, the driver TypeError, or the
78
# dead SDF link -- this gate runs the code so those surface in CI, not in users' files.
@@ -24,13 +25,11 @@ jobs:
2425
smoke:
2526
name: Blender ${{ matrix.series }} smoke
2627
runs-on: ubuntu-latest
27-
timeout-minutes: 30
28+
timeout-minutes: 45
2829
strategy:
2930
fail-fast: false
3031
matrix:
31-
include:
32-
- series: "5.1" # current stable
33-
- series: "4.5" # active LTS
32+
series: ${{ github.event_name == 'schedule' && fromJSON('["5.2","5.1","4.5"]') || fromJSON('["5.2","4.5"]') }}
3433
steps:
3534
- uses: actions/checkout@v7
3635

@@ -214,6 +213,15 @@ jobs:
214213
xvfb-run -a "$BLENDER" --background \
215214
--python examples/gn-instance-grid/gn_instance_grid.py --
216215
216+
- name: Shipped example - GN modifier inputs (5.1 dict vs 5.2 RNA)
217+
run: |
218+
set -euo pipefail
219+
# Frame-independent check only (no render): one GN tree, three modifier
220+
# copies; writes Scale 1/2/3 via version-appropriate path; asserts
221+
# readback and evaluated Z-extent match. Exits non-zero on failure.
222+
xvfb-run -a "$BLENDER" --background \
223+
--python examples/gn-modifier-inputs/gn_modifier_inputs.py --
224+
217225
- name: Shipped example - shape-key blend (data API + evaluated mesh)
218226
run: |
219227
set -euo pipefail

‎AGENTS.md‎

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ repeats the other.
1414
## Repository overview
1515

1616
Skills, rules, snippets, starter templates, and runnable smoke-gated examples
17-
for Blender Python development. The repo targets **Blender 5.1** (current
18-
stable) with a **Blender 4.5 LTS** fallback. There is no MCP server. It ships
17+
for Blender Python development. The repo targets **Blender 5.2 LTS** (current
18+
stable) with a **Blender 4.5 LTS** fallback. **Blender 5.1** is prior stable. There is no MCP server. It ships
1919
a `.cursor-plugin/plugin.json` manifest so the ecosystem drift checker
2020
classifies it as a `cursor-plugin`. This is content the AI loads when the user
2121
asks Blender questions or works on Blender add-ons in Cursor or Claude Code.
2222

23-
The content base is 12 skills, 6 rules, 2 templates, 17 snippets, and 44
23+
The content base is 12 skills, 6 rules, 2 templates, 17 snippets, and 45
2424
examples (counts are CI-enforced against README.md and the manifest). The full
2525
inventory tables and per-item purposes live in `CLAUDE.md`. Example anatomy
2626
and authoring rules: copy `examples/bmesh-gear/`; the render look is specified
@@ -35,7 +35,7 @@ Blender-Developer-Tools/
3535
rules/<rule-name>.mdc # 6 rule files
3636
templates/<template-name>/ # 2 starter templates
3737
snippets/<snippet-name>.py # 17 standalone Python snippets
38-
examples/<name>/ # 40 runnable smoke-gated examples (+ gallery.json)
38+
examples/<name>/ # 45 runnable smoke-gated examples (+ gallery.json)
3939
examples/gallery_framing.py # shared Layer 1 framing measurement (render path only)
4040
scripts/build_gallery.py # generates docs/gallery/ (stdlib only)
4141
scripts/site/ # vendored landing-page build (build_site.py + template)
@@ -76,7 +76,7 @@ Blender-Developer-Tools/
7676
- **Smoke jobs do not re-run on the merge SHA.** `blender-smoke.yml` triggers
7777
on `pull_request` (plus a weekly schedule and manual dispatch) — there is no
7878
`push` trigger. The correct post-merge evidence for example changes is:
79-
both Blender smoke jobs (4.5 LTS and 5.1) passed on the PR head SHA that
79+
both Blender smoke jobs (5.2 LTS and 4.5 LTS) passed on the PR head SHA that
8080
became the sole squash-merged commit, with the actual binary versions
8181
confirmed in the job logs.
8282
- **Post-merge, verify green on `main`:** Release (`release.yml`), Validate
@@ -97,12 +97,13 @@ Blender-Developer-Tools/
9797

9898
## Blender version targeting
9999

100-
- Primary: **Blender 5.1.x** (current stable). All examples assume 5.1
100+
- Primary: **Blender 5.2 LTS** (current stable). All examples assume 5.2
101101
unless otherwise stated.
102+
- Prior stable: **Blender 5.1**. Skills document 5.1-only contracts where they
103+
still matter; weekly smoke keeps a 5.1 leg.
102104
- Fallback: **Blender 4.5 LTS**. Skills and the extension template note 4.5
103105
compatibility where it matters (slotted actions bridge, property delete,
104-
manifest fields).
105-
- Future: a 5.2 LTS sweep is planned for July 2026 (see `ROADMAP.md`).
106+
manifest fields, NodesModifier dict inputs).
106107

107108
When a 4.x and 5.x API genuinely diverge, skills must show both code paths,
108109
not just the 5.x one. The `slotted-actions-animation` skill is the load-bearing
@@ -155,8 +156,8 @@ way, and a one-paragraph rationale. 30 to 80 lines is the right size.
155156
and the manifest `version` must equal `VERSION`. The release pipeline owns
156157
the manifest `version` line (see `release.yml` below) — never hand-edit it.
157158
- `blender-smoke.yml` executes every shipped example (check-only, no render)
158-
plus snippet/template smoke tests inside REAL headless Blender, on both
159-
4.5 LTS and 5.1, on every PR and a weekly schedule. A new example is not
159+
plus snippet/template smoke tests inside REAL headless Blender, on
160+
5.2 LTS and 4.5 LTS for every PR (5.1 on the weekly cron). A new example is not
160161
shipped until it has a step here.
161162
- `drift-check.yml` consumes `Developer-Tools-Directory/.github/actions/
162163
drift-check@v1.15` to enforce ecosystem standards-version markers.
@@ -176,7 +177,8 @@ way, and a one-paragraph rationale. 30 to 80 lines is the right size.
176177

177178
## Where to look for canonical references
178179

179-
- Blender 5.1 Python API: https://docs.blender.org/api/current/
180+
- Blender 5.2 LTS Python API: https://docs.blender.org/api/current/
181+
- Blender 5.1 Python API: https://docs.blender.org/api/5.1/
180182
- Blender 4.5 LTS Python API: https://docs.blender.org/api/4.5/
181183
- Extensions Platform reference: https://docs.blender.org/manual/en/latest/advanced/extensions/index.html
182184
- Release notes (`developer.blender.org`): https://developer.blender.org/

‎CLAUDE.md‎

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
88

99
## Project Overview
1010

11-
The **Blender Developer Tools** repository is at **v0.46.1**. It packages skills, rules, snippets, starter templates, and runnable smoke-gated examples for Blender Python development with Cursor and Claude Code. Coverage targets **Blender 5.1** (current stable) with **Blender 4.5 LTS** fallback. There is no MCP server; content is consumed directly by the AI when working in Blender add-on or scripting projects.
11+
The **Blender Developer Tools** repository is at **v0.46.1**. It packages skills, rules, snippets, starter templates, and runnable smoke-gated examples for Blender Python development with Cursor and Claude Code. Coverage targets **Blender 5.2 LTS** (current stable) with **Blender 4.5 LTS** fallback. **Blender 5.1** is prior stable. There is no MCP server; content is consumed directly by the AI when working in Blender add-on or scripting projects.
1212

1313
**Version:** 0.46.1
1414
**License:** CC-BY-NC-ND-4.0
@@ -21,7 +21,7 @@ skills/<skill-name>/SKILL.md - AI workflow definitions, 12 total
2121
rules/<rule-name>.mdc - Anti-pattern rules, 6 total
2222
templates/<template-name>/ - Starter projects, 2 total
2323
snippets/<snippet-name>.py - Standalone code patterns, 17 total
24-
examples/<name>/ - Runnable smoke-gated examples, 44 total (+ gallery.json)
24+
examples/<name>/ - Runnable smoke-gated examples, 45 total (+ gallery.json)
2525
scripts/build_gallery.py - Regenerates docs/gallery/ from gallery.json (stdlib only)
2626
scripts/site/ - Vendored landing-page build (Jinja2)
2727
docs/gallery/ - Committed generated gallery pages + hero renders
@@ -82,11 +82,11 @@ v0.1.0: canonical object creation and deletion, depsgraph evaluated mesh, bmesh
8282

8383
v0.2.0: Principled BSDF material, driver-with-custom-function via `driver_namespace`, application handler registration, shader node group with cross-version `interface` API, `foreach_get` bulk vertex read, version-branch skeleton, and USD export with `evaluation_mode='RENDER'`.
8484

85-
## Examples (44)
85+
## Examples (45)
8686

8787
Runnable scripts at `examples/<name>/`, each asserting a real API contract with
8888
deterministic checks (exit non-zero on failure) and optionally rendering a still via
89-
`--output`. All of them run headless on Blender 4.5 LTS and 5.1 in `blender-smoke.yml`;
89+
`--output`. All of them run headless on Blender 5.2 LTS and 4.5 LTS in `blender-smoke.yml` (5.1 on the weekly cron);
9090
their renders ship in the site gallery at `docs/gallery/`. `examples/gallery.json` is the
9191
gallery's source of truth. When authoring a new one, copy the anatomy of
9292
`examples/bmesh-gear/` (script structure, README shape, dark-studio render recipe) and
@@ -100,8 +100,8 @@ cross-example import mechanism (see its docstring).
100100

101101
## Blender Runtime Discovery
102102

103-
- Local Blender binaries: check `.scratch/` at the repo root **first** — some machines have no system Blender install, and a prior agent run downloads official releases there (e.g. `.scratch/5.1/blender-5.1.x-.../blender[.exe]`). Then check system installs. Do not probe blindly; locate the binary, run it, and state the **exact binary path and the version the binary itself reports** in every report.
104-
- **5.1 is the local check version. 4.5 LTS is exercised by CI when unavailable locally.** 4.4 is not a substitute for 4.5 and must never be reported as 4.5.
103+
- Local Blender binaries: check `.scratch/` at the repo root **first** — some machines have no system Blender install, and a prior agent run downloads official releases there (e.g. `.scratch/5.2/blender-5.2.x-.../blender[.exe]`). Then check system installs. Do not probe blindly; locate the binary, run it, and state the **exact binary path and the version the binary itself reports** in every report.
104+
- **5.2 LTS is the local check version. 4.5 LTS is exercised by CI when unavailable locally.** 4.4 is not a substitute for 4.5 and must never be reported as 4.5.
105105
- **CI floats within each series:** `blender-smoke.yml` resolves the highest published point release at run time (`sort -V | tail -1` on the download listing), so a local 4.5.x may lag CI — its 4.5 job ran 4.5.12 LTS on PR #107 while local `.scratch/` held 4.5.11. Either way, state the exact version the binary reports.
106106
- If `.scratch/` lacks a needed version, download an official release from download.blender.org into it. `.scratch` is gitignored.
107107
- In scripts, version-branch on the `bpy.app.version` tuple, never on `bpy.app.version_string` — it reads e.g. `"4.5.11 LTS"`, not bare semver.
@@ -127,7 +127,7 @@ Stage with **explicit paths only** — never `git add -A` or `git add .`. Cursor
127127
- **Asset-sheet gate (asset-type examples — game props/kits):** composite the hero asset rendered alone (neutral three-quarter view, plain studio lighting, no staging tricks, no labels, no comparison props) beside the pinned asset-quality reference set — currently `collision-hull-proxy`, `custom-normals-shade`, `vertex-weight-limit`, `lod-decimate-chain` — rendered the same way; commit under `docs/gallery/asset-sheets/`, link it in the PR body, and report a verdict. The asset ships only if it is not identifiable as the least-designed object in that lineup — a strong scene can carry a weak model; this gate removes the scene. **This list is the canonical home of the reference set** — update it here when a new asset outclasses a member. The measurable floors behind the gate (naming, material variation, edge treatment) live in `examples/gallery_asset_quality.py` — render path only, same call pattern as `gallery_framing`, exit 11 on violation — with the calibration table and dropped-floor evidence in `docs/VISUAL-STYLE.md` § Asset quality.
128128
- **Falsification:** every check must be proven to fail once — break the contract, observe the non-zero exit, restore — with the probe and the measured error reported in the PR body. An assertion that cannot fail witnesses nothing.
129129
- **After gallery regeneration** (`python scripts/build_gallery.py`), read the **generated HTML** character by character — the `<img alt>` text and witnesses callouts in `docs/gallery/index.html` and `docs/gallery/<name>/index.html` — not just `examples/gallery.json`. Precedent: the `teaches.split(".")[0]` bug truncated 14/21 card alts at dotted API paths like `bmesh.ops` while the source JSON looked fine (fixed in PR #68).
130-
- **Playwright gallery captures:** gallery `<img>` tags lazy-load, so force them first (`document.querySelectorAll('img').forEach(i => i.loading = 'eager')`, then wait). **Scroll the target card into view and take a viewport capture** — `scrollIntoView({block:'center', behavior:'instant'})`, short wait, `browser_take_screenshot` with `fullPage` omitted. A `fullPage` capture is NOT a workaround: on a tall gallery page it renders every card image blank even when the images are verified loaded (`complete === true`, `naturalWidth === 1280`, `opacity === 1`) — measured on the 44-card grid at 1425x4516. Verify load state via `browser_evaluate` rather than trusting the pixels.
130+
- **Playwright gallery captures:** gallery `<img>` tags lazy-load, so force them first (`document.querySelectorAll('img').forEach(i => i.loading = 'eager')`, then wait). **Scroll the target card into view and take a viewport capture** — `scrollIntoView({block:'center', behavior:'instant'})`, short wait, `browser_take_screenshot` with `fullPage` omitted. A `fullPage` capture is NOT a workaround: on a tall gallery page it renders every card image blank even when the images are verified loaded (`complete === true`, `naturalWidth === 1280`, `opacity === 1`) — measured on the 45-card grid at 1425x4516. Verify load state via `browser_evaluate` rather than trusting the pixels.
131131

132132
## Example-Run Process
133133

@@ -149,7 +149,7 @@ The AI consumes content via:
149149

150150
## Key Conventions
151151

152-
- **Blender versions**: 5.1 primary, 4.5 LTS fallback. Skills must show both code paths when 4.x and 5.x APIs diverge.
152+
- **Blender versions**: 5.2 LTS primary, 5.1 prior stable, 4.5 LTS fallback. Skills must show both code paths when 4.x and 5.x APIs diverge, and the 5.1-vs-5.2 NodesModifier input split.
153153
- **Properties as annotations**: `my_prop: bpy.props.FloatProperty(...)` (correct), not `my_prop = bpy.props.FloatProperty(...)` (deprecated).
154154
- **bmesh memory**: every `bmesh.new()` must be paired with `bm.free()` in a `try`/`finally`.
155155
- **No `bpy.ops` in tight loops**: use `bpy.data.*` and `bmesh` for bulk work.
@@ -160,7 +160,8 @@ The AI consumes content via:
160160

161161
| Area | URL |
162162
| --- | --- |
163-
| Python API (5.1) | https://docs.blender.org/api/current/ |
163+
| Python API (5.2 LTS) | https://docs.blender.org/api/current/ |
164+
| Python API (5.1) | https://docs.blender.org/api/5.1/ |
164165
| Python API (4.5 LTS) | https://docs.blender.org/api/4.5/ |
165166
| Extensions Platform | https://docs.blender.org/manual/en/latest/advanced/extensions/index.html |
166167
| Release notes | https://developer.blender.org/ |

‎CONTRIBUTING.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ templates/
8888

8989
## Blender Version Targeting
9090

91-
Content targets **Blender 5.1** as primary, with **Blender 4.5 LTS** as fallback. When the API differs, branch on `bpy.app.version` and document both paths. Example:
91+
Content targets **Blender 5.2 LTS** as primary, **Blender 5.1** as prior stable, and **Blender 4.5 LTS** as fallback. When the API differs, branch on `bpy.app.version` and document both paths. Example:
9292

9393
```python
9494
if bpy.app.version >= (5, 0, 0):

0 commit comments

Comments
 (0)