You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 5a56f5e
Browse filesBrowse the repository at this point in the historyBrowse files
feat(distribution): rules and skills for Codex, Copilot, Windsurf and Gemini CLI
README said any agent that reads files could use the pack, with nothing
behind it. scripts/build_claude_rules.py now also writes, from rules/*.mdc:
- agents/AGENTS.md, for agents that read AGENTS.md (Codex, Windsurf, Gemini
CLI, Copilot's coding agent);
- agents/copilot/blender-python.instructions.md, a Copilot path-scoped
instructions file with applyTo "**/*.py" (the rules' own scope).
Both ship in plugin-dist (DIRS gains agents/), and the dist build fails if
either is missing. Validate's existing --check covers staleness.
README Quick start gains an Other agents entry: clone plugin-dist, copy
skills into .agents/skills/, append the AGENTS.md export, and drop in the
Copilot file. Ran against a fresh dist build: 20 skills copied, 11 rule
sections appended, frontmatter intact. The landing install step matches.
The blender-rules skill description also names the two newest rules.
Closes#376
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: TM Hospitality Strategies <TMHospitalityStrategies@gmail.com>
Copy file name to clipboardExpand all lines: README.md
+13Lines changed: 13 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -78,6 +78,19 @@ Neither agent needs a clone of `main`: both install the slim `plugin-dist` build
78
78
`@plugin-dist` is a generated branch holding only what the plugin loads (about 0.3 MB, rebuilt on every release), so the add does not clone the gallery renders, showcase props and history on `main`. Adding the repo without `@plugin-dist` still works; the plugin itself installs from `plugin-dist` either way.
79
79
80
80
Claude Code does not read Cursor `.mdc` rules, so the plugin ships them as the `blender-rules` skill (generated from `rules/`), which Claude loads when it writes or reviews bpy code. No second clone is needed. To keep the rules in context all the time instead, add `@/path/to/Blender-Developer-Tools/claude/blender-rules.md` to your project's `CLAUDE.md` from a checkout. Without the plugin, copy `skills/*` and `claude/skills/*` into your project's `.claude/skills/`.
81
+
-**Other agents (Codex, GitHub Copilot, Windsurf, Gemini CLI)** — clone the same slim build once, then copy into each project:
`agents/AGENTS.md` and the Copilot file are generated from `rules/` by `scripts/build_claude_rules.py`, and CI fails if they fall out of date. The plugin-dist build fails if either file is missing. The layouts follow each agent's documented conventions; CI does not run the agents themselves.
<!-- Generated by scripts/build_claude_rules.py from rules/*.mdc. Do not edit. -->
4
+
5
+
Apply these when writing or reviewing Blender Python. Each rule links to the
6
+
full version with Wrong/Right examples.
7
+
8
+
## always-free-bmesh
9
+
10
+
Flag bmesh.new() calls without a paired bm.free() in a try/finally block. Blender frees an unreferenced BMesh only when its Python wrapper dies, which a traceback, global, closure or modal operator can delay for the whole session; an explicit free() in finally releases it deterministically.
11
+
12
+
Applies to: `**/*.py`. Full rule: [`rules/always-free-bmesh.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/always-free-bmesh.mdc).
13
+
14
+
## no-bgl
15
+
16
+
Flag `import bgl` and any `bgl.` call. The `bgl` OpenGL wrapper was deprecated in 3.x and is gone in Blender 5.x (`importlib.util.find_spec('bgl')` is `None` on 5.0, 5.1 and 5.2), so an add-on that imports it fails to register. Draw with the `gpu` module, `gpu.state` and `gpu_extras.batch` instead; see the gpu-drawing-and-overlays skill.
17
+
18
+
Applies to: `**/*.py`. Full rule: [`rules/no-bgl.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/no-bgl.mdc).
19
+
20
+
## no-removed-normals-api
21
+
22
+
Flag the mesh normals API removed in Blender 4.1 — `use_auto_smooth`, `auto_smooth_angle`, `calc_normals_split()`, `free_normals_split()`, `create_normals_split()`. Each raises AttributeError on 4.5 LTS and 5.x. Use `Mesh.set_sharp_from_angle`, `object.shade_auto_smooth`, and `Mesh.corner_normals` (always current) instead.
23
+
24
+
Applies to: `**/*.py`. Full rule: [`rules/no-removed-normals-api.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/no-removed-normals-api.mdc).
25
+
26
+
## no-unapplied-modifiers-on-export
27
+
28
+
Flag an export call on objects that still carry unapplied modifiers when the export arguments do not request evaluated geometry. The engine then receives the authored cage, not the modifier result.
29
+
30
+
Applies to: `**/*.py`. Full rule: [`rules/no-unapplied-modifiers-on-export.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/no-unapplied-modifiers-on-export.mdc).
31
+
32
+
## prefer-data-over-ops-in-loops
33
+
34
+
Flag bpy.ops.* calls inside iteration over many objects, meshes, or frames. Each bpy.ops call triggers a full depsgraph evaluation and UI redraw; loops slow down by orders of magnitude. Use bpy.data.* and bmesh instead.
35
+
36
+
Applies to: `**/*.py`. Full rule: [`rules/prefer-data-over-ops-in-loops.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/prefer-data-over-ops-in-loops.mdc).
37
+
38
+
## prefer-temp-override-over-context-copy
39
+
40
+
Flag uses of `bpy.context.copy()` to override context for an operator call. Passing a context dict to an operator was deprecated in Blender 3.2 and removed in 4.0, so it already fails on the 4.5 LTS fallback. Use `bpy.context.temp_override(**overrides)` as a context manager instead.
41
+
42
+
Applies to: `**/*.py`. Full rule: [`rules/prefer-temp-override-over-context-copy.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/prefer-temp-override-over-context-copy.mdc).
43
+
44
+
## target-extensions-platform-format
45
+
46
+
Flag new Blender add-ons that ship only a legacy bl_info dict without a blender_manifest.toml. New add-ons must use the Extensions Platform format. bl_info may appear alongside as a fallback for backward compatibility, but the manifest is the source of truth.
47
+
48
+
Applies to: `**/__init__.py`, `**/blender_manifest.toml`. Full rule: [`rules/target-extensions-platform-format.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/target-extensions-platform-format.mdc).
49
+
50
+
## type-annotate-props-and-defend-context
51
+
52
+
Flag two related anti-patterns. (1) bpy.props defined as class-level assignments instead of type annotations (deprecated since 2.8). (2) Code that touches bpy.context.active_object without guarding for None, or that assumes the active object is selected.
53
+
54
+
Applies to: `**/*.py`. Full rule: [`rules/type-annotate-props-and-defend-context.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/type-annotate-props-and-defend-context.mdc).
55
+
56
+
## use-correct-axis-rna-per-exporter
57
+
58
+
Flag export_scene.gltf calls that pass FBX axis_forward or axis_up, and export_scene.fbx calls that pass glTF export_yup. The two exporters do not share axis RNA.
59
+
60
+
Applies to: `**/*.py`. Full rule: [`rules/use-correct-axis-rna-per-exporter.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/use-correct-axis-rna-per-exporter.mdc).
61
+
62
+
## use-foreach-set-for-bulk-data
63
+
64
+
Flag Python loops that set vertex coordinates, normals, UVs, or other bulk per-element data one element at a time. For meshes of more than a few thousand elements, this is 100x to 1000x slower than `mesh.vertices.foreach_set("co", flat_array)`, which writes through to C-level storage in one pass.
65
+
66
+
Applies to: `**/*.py`. Full rule: [`rules/use-foreach-set-for-bulk-data.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/use-foreach-set-for-bulk-data.mdc).
67
+
68
+
## validate-imported-mesh-scale
69
+
70
+
Flag a glTF or FBX import followed by mesh operations with no transform_apply and no unit-scale check. Generated files often arrive with non-identity object scale or a non-meter scene scale; mesh edits then bake the wrong size.
71
+
72
+
Applies to: `**/*.py`. Full rule: [`rules/validate-imported-mesh-scale.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/validate-imported-mesh-scale.mdc).
<!-- Generated by scripts/build_claude_rules.py from rules/*.mdc. Do not edit. -->
8
+
9
+
Apply these when writing or reviewing Blender Python. Each rule links to the
10
+
full version with Wrong/Right examples.
11
+
12
+
## always-free-bmesh
13
+
14
+
Flag bmesh.new() calls without a paired bm.free() in a try/finally block. Blender frees an unreferenced BMesh only when its Python wrapper dies, which a traceback, global, closure or modal operator can delay for the whole session; an explicit free() in finally releases it deterministically.
15
+
16
+
Applies to: `**/*.py`. Full rule: [`rules/always-free-bmesh.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/always-free-bmesh.mdc).
17
+
18
+
## no-bgl
19
+
20
+
Flag `import bgl` and any `bgl.` call. The `bgl` OpenGL wrapper was deprecated in 3.x and is gone in Blender 5.x (`importlib.util.find_spec('bgl')` is `None` on 5.0, 5.1 and 5.2), so an add-on that imports it fails to register. Draw with the `gpu` module, `gpu.state` and `gpu_extras.batch` instead; see the gpu-drawing-and-overlays skill.
21
+
22
+
Applies to: `**/*.py`. Full rule: [`rules/no-bgl.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/no-bgl.mdc).
23
+
24
+
## no-removed-normals-api
25
+
26
+
Flag the mesh normals API removed in Blender 4.1 — `use_auto_smooth`, `auto_smooth_angle`, `calc_normals_split()`, `free_normals_split()`, `create_normals_split()`. Each raises AttributeError on 4.5 LTS and 5.x. Use `Mesh.set_sharp_from_angle`, `object.shade_auto_smooth`, and `Mesh.corner_normals` (always current) instead.
27
+
28
+
Applies to: `**/*.py`. Full rule: [`rules/no-removed-normals-api.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/no-removed-normals-api.mdc).
29
+
30
+
## no-unapplied-modifiers-on-export
31
+
32
+
Flag an export call on objects that still carry unapplied modifiers when the export arguments do not request evaluated geometry. The engine then receives the authored cage, not the modifier result.
33
+
34
+
Applies to: `**/*.py`. Full rule: [`rules/no-unapplied-modifiers-on-export.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/no-unapplied-modifiers-on-export.mdc).
35
+
36
+
## prefer-data-over-ops-in-loops
37
+
38
+
Flag bpy.ops.* calls inside iteration over many objects, meshes, or frames. Each bpy.ops call triggers a full depsgraph evaluation and UI redraw; loops slow down by orders of magnitude. Use bpy.data.* and bmesh instead.
39
+
40
+
Applies to: `**/*.py`. Full rule: [`rules/prefer-data-over-ops-in-loops.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/prefer-data-over-ops-in-loops.mdc).
41
+
42
+
## prefer-temp-override-over-context-copy
43
+
44
+
Flag uses of `bpy.context.copy()` to override context for an operator call. Passing a context dict to an operator was deprecated in Blender 3.2 and removed in 4.0, so it already fails on the 4.5 LTS fallback. Use `bpy.context.temp_override(**overrides)` as a context manager instead.
45
+
46
+
Applies to: `**/*.py`. Full rule: [`rules/prefer-temp-override-over-context-copy.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/prefer-temp-override-over-context-copy.mdc).
47
+
48
+
## target-extensions-platform-format
49
+
50
+
Flag new Blender add-ons that ship only a legacy bl_info dict without a blender_manifest.toml. New add-ons must use the Extensions Platform format. bl_info may appear alongside as a fallback for backward compatibility, but the manifest is the source of truth.
51
+
52
+
Applies to: `**/__init__.py`, `**/blender_manifest.toml`. Full rule: [`rules/target-extensions-platform-format.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/target-extensions-platform-format.mdc).
53
+
54
+
## type-annotate-props-and-defend-context
55
+
56
+
Flag two related anti-patterns. (1) bpy.props defined as class-level assignments instead of type annotations (deprecated since 2.8). (2) Code that touches bpy.context.active_object without guarding for None, or that assumes the active object is selected.
57
+
58
+
Applies to: `**/*.py`. Full rule: [`rules/type-annotate-props-and-defend-context.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/type-annotate-props-and-defend-context.mdc).
59
+
60
+
## use-correct-axis-rna-per-exporter
61
+
62
+
Flag export_scene.gltf calls that pass FBX axis_forward or axis_up, and export_scene.fbx calls that pass glTF export_yup. The two exporters do not share axis RNA.
63
+
64
+
Applies to: `**/*.py`. Full rule: [`rules/use-correct-axis-rna-per-exporter.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/use-correct-axis-rna-per-exporter.mdc).
65
+
66
+
## use-foreach-set-for-bulk-data
67
+
68
+
Flag Python loops that set vertex coordinates, normals, UVs, or other bulk per-element data one element at a time. For meshes of more than a few thousand elements, this is 100x to 1000x slower than `mesh.vertices.foreach_set("co", flat_array)`, which writes through to C-level storage in one pass.
69
+
70
+
Applies to: `**/*.py`. Full rule: [`rules/use-foreach-set-for-bulk-data.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/use-foreach-set-for-bulk-data.mdc).
71
+
72
+
## validate-imported-mesh-scale
73
+
74
+
Flag a glTF or FBX import followed by mesh operations with no transform_apply and no unit-scale check. Generated files often arrive with non-identity object scale or a non-meter scene scale; mesh edits then bake the wrong size.
75
+
76
+
Applies to: `**/*.py`. Full rule: [`rules/validate-imported-mesh-scale.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/validate-imported-mesh-scale.mdc).
Copy file name to clipboardExpand all lines: claude/skills/blender-rules/SKILL.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
---
2
2
name: blender-rules
3
-
description: Blender Python anti-pattern rules (bmesh leaks, bpy.ops in loops, deprecated context-copy overrides, bulk mesh writes, prop annotations and context guards, Extensions manifest, import scale, export modifiers, glTF/FBX axis RNA). Use when writing, reviewing or fixing any bpy / Blender add-on or script code.
3
+
description: Blender Python anti-pattern rules (bmesh leaks, bpy.ops in loops, deprecated context-copy overrides, bulk mesh writes, prop annotations and context guards, Extensions manifest, import scale, export modifiers, glTF/FBX axis RNA, the removed bgl module, the normals API removed in 4.1). Use when writing, reviewing or fixing any bpy / Blender add-on or script code.
description: Blender Python anti-pattern rules (bmesh leaks, bpy.ops in loops, deprecated context-copy overrides, bulk mesh writes, prop annotations and context guards, Extensions manifest, import scale, export modifiers, glTF/FBX axis RNA). Use when writing, reviewing or fixing any bpy / Blender add-on or script code.
45
+
description: Blender Python anti-pattern rules (bmesh leaks, bpy.ops in loops, deprecated context-copy overrides, bulk mesh writes, prop annotations and context guards, Extensions manifest, import scale, export modifiers, glTF/FBX axis RNA, the removed bgl module, the normals API removed in 4.1). Use when writing, reviewing or fixing any bpy / Blender add-on or script code.
0 commit comments