diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 2d92cba9..d99c3046 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -6,7 +6,7 @@ "url": "https://github.com/TMHSDigital" }, "description": "Blender Python skills and rules for AI agents: correct bpy for Blender 5.2 LTS and 4.5 LTS (Slotted Actions, temp_override, Extensions, bmesh, Geometry Nodes, glTF/FBX export), backed by smoke-tested examples", - "homepage": "https://github.com/TMHSDigital/Blender-Developer-Tools", + "homepage": "https://tmhsdigital.github.io/Blender-Developer-Tools/", "repository": "https://github.com/TMHSDigital/Blender-Developer-Tools", "license": "CC-BY-NC-ND-4.0 AND MIT", "skills": [ diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json index ef5c0901..bedad9a7 100644 --- a/.cursor-plugin/marketplace.json +++ b/.cursor-plugin/marketplace.json @@ -4,13 +4,13 @@ "name": "TMHSDigital" }, "metadata": { - "description": "Blender Python skills and rules for Cursor: correct bpy for Blender 5.2 LTS and 4.5 LTS." + "description": "Blender Python skills and rules for AI agents in Cursor and Claude Code: correct bpy for Blender 5.2 LTS and 4.5 LTS." }, "plugins": [ { "name": "blender-developer-tools", "source": "./", - "description": "Cursor and Claude Code skills, rules, snippets, and templates for Blender Python add-on and scripting development" + "description": "Blender Python skills and rules for AI agents: correct bpy for Blender 5.2 LTS and 4.5 LTS (Slotted Actions, temp_override, Extensions, bmesh, Geometry Nodes, glTF/FBX export), backed by smoke-tested examples" } ] } diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json index bbb68092..1c96b632 100644 --- a/.cursor-plugin/plugin.json +++ b/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "blender-developer-tools", "displayName": "Blender Developer Tools", - "description": "Cursor and Claude Code skills, rules, snippets, and templates for Blender Python add-on and scripting development", + "description": "Blender Python skills and rules for AI agents: correct bpy for Blender 5.2 LTS and 4.5 LTS (Slotted Actions, temp_override, Extensions, bmesh, Geometry Nodes, glTF/FBX export), backed by smoke-tested examples", "version": "0.147.1", "author": { "name": "TMHSDigital" @@ -9,6 +9,7 @@ "homepage": "https://tmhsdigital.github.io/Blender-Developer-Tools/", "repository": "https://github.com/TMHSDigital/Blender-Developer-Tools", "license": "CC-BY-NC-ND-4.0 AND MIT", + "logo": "assets/favicon.svg", "keywords": [ "cursor-plugin", "claude-code", diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 679e0fbc..c6b8051e 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -5,4 +5,4 @@ contact_links: about: Report a security issue privately via GitHub Security Advisory. Do not open a public issue for vulnerabilities. - name: Roadmap / candidate pool url: https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/ROADMAP.md - about: Check ROADMAP.md before requesting new skills, snippets, or examples. Shipped items are struck through there. + about: Check ROADMAP.md before requesting new skills, snippets, or examples. Shipped items are removed from it; see CHANGELOG.md for what shipped. diff --git a/.github/scripts/release_notes.py b/.github/scripts/release_notes.py index fcb25e46..f5ef01d1 100644 --- a/.github/scripts/release_notes.py +++ b/.github/scripts/release_notes.py @@ -4,12 +4,19 @@ python .github/scripts/release_notes.py --since v0.142.3 --version 0.143.0 \ --notes "$RUNNER_TEMP/notes.md" --changelog CHANGELOG.md -Groups conventional-commit subjects (Features, Fixes, Other) with links to -each commit, skips the release bot's own "chore: bump version" commits, writes -the list to --notes (the GitHub release body) and, with --changelog, replaces -the version's "See release notes ... for details." placeholder that -release-doc-sync writes with the same list plus the link. Without this, every -CHANGELOG entry and release body said nothing about what shipped. +Splits the commits in two (#455): + +- **For agents and users**: commits that touched what the plugin ships + (skills/, rules/, snippets/, templates/, claude/), grouped Features, Fixes, + Other. This is what a plugin user gets from the update, so it leads. +- **Maintenance**: everything else (CI, tests, the site and gallery, + showcase pieces, examples, docs), in a collapsed
block. + +A release with no plugin change says so in one line above the collapsed +block. Skips the release bot's own "chore: bump version" commits, writes the +body to --notes (the GitHub release body) and, with --changelog, replaces the +version's "See release notes ... for details." placeholder that +release-doc-sync writes with the same body plus the link. """ from __future__ import annotations @@ -24,33 +31,63 @@ ("Fixes", re.compile(r"^fix(\(.+?\))?!?:", re.I)), ) SKIP = re.compile(r"^chore: bump version to ", re.I) +# What the plugin ships (scripts/build_plugin_dist.py DIRS): a change here is +# a change a plugin user receives. +USER_PATHS = ("skills/", "rules/", "snippets/", "templates/", "claude/") +NO_USER_CHANGES = ("No changes to the plugin content (skills, rules, snippets, templates) " + "in this release.") -def commits(since: str | None) -> list[tuple[str, str]]: +def commits(since: str | None) -> list[tuple[str, str, list[str]]]: + """(sha, subject, changed paths) per commit, newest first.""" rng = f"{since}..HEAD" if since else "HEAD" out = subprocess.run( - ["git", "log", rng, "--no-merges", "--format=%H%x09%s"], + ["git", "log", rng, "--no-merges", "--name-only", "--format=%x00%H%x09%s"], capture_output=True, text=True, check=True, ).stdout rows = [] - for line in out.splitlines(): - sha, _, subject = line.partition("\t") + for block in out.split("\0")[1:]: + head, _, files = block.partition("\n") + sha, _, subject = head.partition("\t") if subject and not SKIP.match(subject): - rows.append((sha, subject.strip())) + rows.append((sha, subject.strip(), [f for f in files.splitlines() if f.strip()])) return rows -def render(rows: list[tuple[str, str]]) -> str: - buckets: dict[str, list[str]] = {name: [] for name, _ in GROUPS} - buckets["Other"] = [] - for sha, subject in rows: - name = next((n for n, rx in GROUPS if rx.match(subject)), "Other") - buckets[name].append(f"- {subject} ([`{sha[:7]}`]({REPO_URL}/commit/{sha}))") +def is_user_facing(files: list[str]) -> bool: + return any(f.startswith(USER_PATHS) for f in files) + + +def _line(sha: str, subject: str) -> str: + return f"- {subject} ([`{sha[:7]}`]({REPO_URL}/commit/{sha}))" + + +def render(rows: list[tuple[str, str, list[str]]]) -> str: + if not rows: + return "No changes recorded." + user = [r for r in rows if is_user_facing(r[2])] + maint = [r for r in rows if not is_user_facing(r[2])] + parts = [] - for name, lines in buckets.items(): - if lines: - parts.append(f"### {name}\n\n" + "\n".join(lines)) - return "\n\n".join(parts) if parts else "No changes recorded." + if user: + buckets: dict[str, list[str]] = {name: [] for name, _ in GROUPS} + buckets["Other"] = [] + for sha, subject, _ in user: + name = next((n for n, rx in GROUPS if rx.match(subject)), "Other") + buckets[name].append(_line(sha, subject)) + groups = [f"**{name}**\n\n" + "\n".join(lines) for name, lines in buckets.items() if lines] + parts.append("### For agents and users\n\n" + "\n\n".join(groups)) + else: + parts.append(NO_USER_CHANGES) + if maint: + parts.append( + f"
\nMaintenance ({len(maint)} " + f"commit{'s' if len(maint) != 1 else ''}): CI, tests, site, examples, showcase, docs" + "\n\n" + + "\n".join(_line(sha, subject) for sha, subject, _ in maint) + + "\n\n
" + ) + return "\n\n".join(parts) def patch_changelog(path: str, version: str, body: str) -> bool: diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 48e1e174..47070ad8 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -13,6 +13,7 @@ on: paths: - "skills/**" - "rules/**" + - "snippets/**" # the landing's snippet list and What's new strip - "site.json" - ".cursor-plugin/plugin.json" - "assets/**" diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 6dac13fa..9353227c 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -239,6 +239,9 @@ jobs: print(f'Manifest verified at v{version}: {counts}') PYEOF + - name: Check both plugin manifests share description, homepage, license, keywords and logo + run: python3 tests/check_manifest_meta.py + validate-claude-packaging: name: Validate Claude Code packaging runs-on: ubuntu-latest diff --git a/AGENTS.md b/AGENTS.md index 31ef2995..f443612f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -21,8 +21,8 @@ classifies it as a `cursor-plugin`. This is content the AI loads when the user asks Blender questions or works on Blender add-ons in Cursor or Claude Code. The content base is 18 skills, 9 rules, 3 templates, 29 snippets, 66 -examples, and 76 showcase pieces (counts are CI-enforced against README.md) -and the manifest). The full inventory tables and per-item purposes live in +examples, and 76 showcase pieces (counts are CI-enforced across README.md, the agent docs, ROADMAP.md, +`site.json` and the site templates). The full inventory tables and per-item purposes live in `CLAUDE.md`. Example anatomy and authoring rules: copy `examples/bmesh-gear/`; showcase conventions: `showcase/README.md`. The render look is specified in `docs/VISUAL-STYLE.md`; the canonical run prompt is @@ -35,8 +35,8 @@ Blender-Developer-Tools/ skills//SKILL.md # 18 skill files rules/.mdc # 9 rule files templates// # 3 starter templates - snippets/.py # 27 standalone Python snippets - examples// # 64 runnable smoke-gated examples (+ gallery.json) + snippets/.py # 29 standalone Python snippets + examples// # 66 runnable smoke-gated examples (+ gallery.json) examples/gallery_framing.py # shared Layer 1 framing measurement (render path only) showcase// # budget-conformance props (sibling of examples/) showcase/gallery.json # this tree's gallery index; merged into docs/gallery/ @@ -177,6 +177,10 @@ way, and a one-paragraph rationale. 30 to 80 lines is the right size. and rule exists and every one on disk is listed, `marketplace.json` lists this plugin, and the manifest `version` must equal `VERSION`. The release pipeline owns the manifest `version` line (see `release.yml` below) — never hand-edit it. + `tests/check_manifest_meta.py` (same job) keeps the Cursor and Claude Code + manifests in step: one description, the site as `homepage`, one license + string (also the gallery footer's), the same keywords, and a Cursor `logo` + that the plugin-dist build ships. - `blender-smoke.yml` executes every shipped example (check-only, no render) plus snippet/template smoke tests inside REAL headless Blender, on 5.2 LTS and 4.5 LTS for every PR. 5.1 is weekly cron, the opt-in @@ -204,6 +208,20 @@ way, and a one-paragraph rationale. 30 to 80 lines is the right size. `.cursor-plugin/plugin.json`, `.claude-plugin/plugin.json` and `.claude-plugin/marketplace.json`, and force-pushes the slim plugin build to the `plugin-dist` branch. +- **Release notes and the commit-type policy.** `.github/scripts/release_notes.py` + writes the GitHub release body and the CHANGELOG entry in two parts: **For + agents and users** lists the commits that touched what the plugin ships + (`skills/`, `rules/`, `snippets/`, `templates/`, `claude/`), grouped + Features / Fixes / Other, and leads; everything else (CI, tests, the site + and gallery, examples, showcase, docs) goes in a collapsed **Maintenance** + `
` block. A release with no plugin change says so in one line above + that block. Every release emails watchers, so pick the commit type by who + receives the change: use `feat:`/`fix:` for changes to plugin content or + to what a user runs; use `ci:`, `test:`, `docs:`, `style:` or `chore:` (not + `fix(ci)`, `fix(tests)` or `fix(site)`) for maintenance, so it does not cut + a release on its own. Pages still deploys from those commits (`pages.yml` + runs on its own path filter), and the next release lists them under + Maintenance. `tests/test_release_notes.py` covers the split. - `label-sync.yml` creates any missing label and applies path-based labels to same-repo PRs. - `pages.yml` builds the landing page from the **locally vendored** template diff --git a/README.md b/README.md index b65017e1..3b1c1e2d 100644 --- a/README.md +++ b/README.md @@ -46,22 +46,20 @@ This repository ships **18 skills, 9 rules, 3 templates, 29 snippets, 66 examples, and 76 showcase pieces** for Blender Python development targeting Blender 5.2 LTS (current stable) with Blender 4.5 LTS fallback support. Blender 5.1 is prior stable. -The content is consumed by AI coding agents reading these files directly from a checkout — **there is no MCP server in this repository, and none is required**. Both agents install it as a plugin (see [Quick start](#quick-start)): Cursor loads the skills and applies `rules/*.mdc` wherever their scope globs match; Claude Code loads the skills and gets the rules through a generated `blender-rules` skill, since it does not read Cursor `.mdc` files. An agent picks a skill up when its description matches the task. Any agent that can read files in a workspace can use it the same way. There is no build step for the content — edit the Markdown and Python files directly. +The content is consumed by AI coding agents, installed as a plugin or read from a checkout — **there is no MCP server in this repository, and none is required**. Cursor and Claude Code both install it as a plugin (see [Quick start](#quick-start)): Cursor loads the skills and applies `rules/*.mdc` wherever their scope globs match; Claude Code loads the skills and gets the rules through a generated `blender-rules` skill, since it does not read Cursor `.mdc` files. An agent picks a skill up when its description matches the task. Any agent that can read files in a workspace can use it the same way. There is no build step for the content — edit the Markdown and Python files directly. | Layer | Role | | --- | --- | -| **Skills** | Guided workflows: scaffolding, operators, panels, properties, mesh and bmesh, headless batch, slotted actions, geometry nodes, procedural materials, depsgraph queries, drivers and handlers, `bl_info` migration, video sequencer, imported-mesh cleanup, engine export presets | +| **Skills** | Guided workflows: scaffolding, operators, panels, properties, mesh and bmesh, headless batch, slotted actions, geometry nodes, procedural materials, depsgraph queries, drivers and handlers, `bl_info` migration, video sequencer, imported-mesh cleanup, high-to-low baking, engine export presets, extension runtime and packaging, timers, modal operators and threading | | **Rules** | Guardrails for the most common AI mistakes: ops-in-loops, bmesh leaks, legacy `bl_info` only, prop assignments, deprecated context-copy override, per-element loops over bulk mesh data, import without scale check, export without evaluated geometry, mixed glTF/FBX axis RNA | | **Templates** | A working Extensions Platform add-on starter, a headless batch script starter, and a GLB-in engine-ready asset pipeline | -| **Snippets** | 27 small standalone Python files demonstrating canonical patterns | +| **Snippets** | 29 small standalone Python files demonstrating canonical patterns, 5 to 75 lines each | | **Examples** | Runnable headless scripts under [`examples/`](examples/). Each asserts an API contract and exits non-zero on failure. | | **Showcase** | Proof that the skills compose: each piece under [`showcase/`](showcase/) is one headless Python script that builds a game prop and runs the whole asset pipeline (cleanup, high-to-low bake, LODs, convex collider, engine export), asserting measured budgets on every LTS. Not API examples. Conventions: [`showcase/README.md`](showcase/README.md) | ## Quick start -```bash -git clone https://github.com/TMHSDigital/Blender-Developer-Tools.git -``` +Neither agent needs a clone of `main`: both install the slim `plugin-dist` build. Clone the full repository only to [run the examples or contribute](#run-the-examples-or-contribute). - **Cursor** — install it as a local plugin from the slim `plugin-dist` branch, then run **Developer: Reload Window**. **Customize** lists the 18 skills and 9 rules; the rules apply by glob scope and the agent loads a skill when its description matches the task. @@ -69,7 +67,7 @@ git clone https://github.com/TMHSDigital/Blender-Developer-Tools.git git clone --branch plugin-dist --single-branch https://github.com/TMHSDigital/Blender-Developer-Tools.git ~/.cursor/plugins/local/blender-developer-tools ``` - (On Windows the folder is `%USERPROFILE%\.cursor\plugins\local\`. Cursor skips symlinks that point outside that folder, so clone or copy rather than link.) Teams can import the repository as a team marketplace instead; it carries `.cursor-plugin/marketplace.json`. For one project only, copy `skills/*` into the project's `.cursor/skills/` and `rules/*.mdc` into `.cursor/rules/` from a checkout. Copying only the rules gives you no skills. + (On Windows the folder is `%USERPROFILE%\.cursor\plugins\local\`. Cursor skips symlinks that point outside that folder, so clone or copy rather than link.) Teams can import the repository as a team marketplace instead; it carries `.cursor-plugin/marketplace.json`. The plugin already applies the rules, so there is nothing to copy. Only to scope the pack to one project without the plugin, copy `skills/*` into that project's `.cursor/skills/` and `rules/*.mdc` into `.cursor/rules/` from a checkout; copying only the rules gives you no skills. - **Claude Code** — install as a plugin, then run `/skills` to see all 18 skills plus `blender-rules`: ```text @@ -80,6 +78,15 @@ git clone https://github.com/TMHSDigital/Blender-Developer-Tools.git `@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. 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/`. + +### Run the examples or contribute + +The examples, the showcase and the gallery live on `main` (about 30 MB with the renders), so clone it only to run them or to send a change: + +```bash +git clone https://github.com/TMHSDigital/Blender-Developer-Tools.git +``` + - **Get Blender** — download **5.2 LTS** (primary target) or **4.5 LTS** (supported fallback) from [blender.org/download/lts](https://www.blender.org/download/lts/); current stable lives at [blender.org/download](https://www.blender.org/download/). The `blender` command below is that binary — on macOS it is inside the app bundle at `/Applications/Blender.app/Contents/MacOS/Blender`. - **Run an example** — every example is a self-checking headless script (exit non-zero on failure, no GPU needed for the check): @@ -162,7 +169,7 @@ claude/ - generated Claude Code copies of the rules (blender-ru ## Using rules in Cursor -The `.mdc` files in `rules/` apply automatically when Cursor opens a Blender Python project, scoped by the `globs` in each rule's frontmatter. The nine rules are: +With the Cursor plugin installed, the `.mdc` files in `rules/` apply automatically when Cursor opens a Blender Python project, scoped by the `globs` in each rule's frontmatter. The nine rules are: - `prefer-data-over-ops-in-loops`: flags `bpy.ops.*` calls inside object iteration - `always-free-bmesh`: flags `bmesh.new()` without paired `bm.free()` in `try`/`finally` @@ -174,7 +181,7 @@ The `.mdc` files in `rules/` apply automatically when Cursor opens a Blender Pyt - `no-unapplied-modifiers-on-export`: flags export of objects with live modifiers when the export does not request evaluated geometry - `use-correct-axis-rna-per-exporter`: flags `export_scene.gltf` calls that pass FBX `axis_forward` / `axis_up`, and `export_scene.fbx` calls that pass glTF `export_yup` -Cursor: copy `rules/*.mdc` into `.cursor/rules/`. Claude Code: install the plugin (see [Quick start](#quick-start)); it ships the rules as the `blender-rules` skill. +Cursor: the plugin covers the rules (see [Quick start](#quick-start)); copying `rules/*.mdc` into a project's `.cursor/rules/` is only the per-project alternative without the plugin. Claude Code: the plugin ships the rules as the `blender-rules` skill. ## Using the templates diff --git a/ROADMAP.md b/ROADMAP.md index cf894237..9cdd7337 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -4,6 +4,20 @@ **Current:** v0.147.1 +## Next for agents + +The skill, rule and example work planned for what the plugin teaches, separate from the +showcase pool further down. Each item is an open issue; nothing here is pinned to a version. + +- **New skills:** `porting-to-blender-5`, one index of every 4.x to 5.x break the pack covers ([#466](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/466)); `gpu-drawing` plus a no-`bgl` rule, since `bgl` is gone in 5.x ([#465](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/465)); teach the API contracts that shipped examples prove but no skill covers yet, such as Grease Pencil v3, the 5.x compositor, constraints and image pixels ([#456](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/456)) +- **Skill corrections:** the full Principled BSDF v2 socket rename table in `procedural-materials-and-shaders` ([#382](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/382)) +- **New rules:** flag the mesh-normals APIs removed in 4.1 (`use_auto_smooth`, `calc_normals_split`, `free_normals_split`) ([#379](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/379)) +- **Examples for skills that have none:** check-only examples for `operators`, `ui-panels`, `addon-scaffolding` and `bl-info-migration` ([#378](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/378)); a skill-to-example index and one machine-readable examples manifest with version support ([#377](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/377)) +- **Verification:** run the shipped snippets and SKILL.md code blocks in CI instead of frozen copies ([#447](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/447)); a weekly, non-gating smoke run against Blender daily builds to catch API breaks before a release ([#457](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/457)) +- **More agents:** first-class support for Codex, Copilot, Windsurf and Gemini through `.agents/skills` and an AGENTS.md rules export ([#376](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/376)) + +## Themes + Themes are listed in order. Shipped themes note the release they landed in (for reference, not a commitment); upcoming themes are intentionally **not** pinned to a version number, so shipping another example or skill never forces a roadmap renumber. The release pipeline @@ -17,11 +31,13 @@ derives the actual version from conventional-commit types. | More examples (turntable, SDF remesh) | 12 | 6 | 2 | 17 | Shipped (v0.4.0) | | 5.2 LTS targeting, GN modifier inputs | 12 | 6 | 2 | 17 | Shipped | | VSE COLOR strip intrinsic size (undocumented 5.2) | 13 | 6 | 2 | 17 | Shipped | -| Skills: modal operators, USD pipelines, mathutils | — | — | — | — | Upcoming (the USD `evaluation_mode` example shipped; the skill has not) | +| Skills: USD pipelines, mathutils | — | — | — | — | Upcoming (the USD `evaluation_mode` example shipped; the skill has not. Modal operators shipped in `timers-modal-and-threading`) | | AI asset pipeline: post-generation cleanup | 14 | 8 | 2 | 21 | Shipped (v0.54.0) | | AI asset pipeline: engine export presets | 15 | 9 | 2 | 24 | Shipped | | AI asset pipeline: headless template | 15 | 9 | 3 | 24 | Shipped | | AI asset pipeline: high-to-low bake | 16 | 9 | 3 | 27 | Shipped | +| Extension runtime and packaging | 17 | 9 | 3 | 28 | Shipped (v0.146.0) | +| Timers, modal operators and threading | 18 | 9 | 3 | 29 | Shipped (v0.147.0) | | AI asset pipeline: live-session bridge (spike) | - | - | - | - | Upcoming | | Stable (1.0) | — | — | — | — | Upcoming; criteria below | @@ -121,7 +137,7 @@ Provider-agnostic GLB-in / engine-ready-out. This repo does not generate meshes. Not committed; open subjects only. Remove a subject when it ships (CLAUDE.md § Example-Run Process); what shipped, and when, is in the CHANGELOG and git history. -- Library rolling ladder (hooked top rollers riding a round rail, raked stiles, treads, floor wheels) as a game-prop showcase piece — the unbuilt half of the item above: a hook riding a round rail is a curved-on-curved contact that neither the trolley's flat backrests nor the yoke's hung ring exercise +- Library rolling ladder (hooked top rollers riding a round rail, raked stiles, treads, floor wheels) as a game-prop showcase piece — a hook riding a round rail is a curved-on-curved contact that neither the shipped `book-trolley`'s flat backrests nor the `wooden-yoke`'s hung ring exercise - Ox cart tongue or plough beam that hitches to the yoke's ring as a game-prop showcase piece — a hitch is a ring-on-hook contact the yoke's hung ring only tests against a fixed bar - Mooring bollard with a coiled rope as a game-prop showcase piece — rope turns laid as stacked helices around the barrel: each turn resting on the one below (not interpenetrating, not floating), measured turn-to-turn off the mesh - Tiered stone fountain as a game-prop showcase piece — concentric basins on a column: every basin coaxial, each upper basin's lip overhanging the one below by a stated band so the overflow line lands inside the next basin @@ -169,7 +185,6 @@ Not committed; open subjects only. Remove a subject when it ships (CLAUDE.md § - Tighten inverted smoke canaries: assert the expected `[FAIL]` marker text (`skipped on ... should run` / `missing post-exit sidecar`) alongside wrapper exit 1, so a canary that dies for the wrong reason does not satisfy the gate - Overlapping / mirrored UV islands as a *shipped* pathology (not lightmap `--falsify`): SAT hits matching a constructed overlap, then glTF TEXCOORD survival. Deferred — `lightmap-uv-channel` already owns the zero-overlap gate. - Vendor CC0 asset fixtures (Kenney, Quaternius, ambientCG only — no aggregators) as `.glb` not `.blend`, with per-fixture provenance records mirroring the Free-Game-Dev-Assets frontmatter schema. Permitted only where the assertion is an invariant over the fixture rather than a measurement of it. Deferred pending a decision on repo weight and CI fetch policy. -- `modal-operators` skill -- `invoke` returning `RUNNING_MODAL`, the `modal()` event handler, modal cancellation patterns - `usd-pipelines` skill -- USD export options, `evaluation_mode`, instancing, the USD vs glTF tradeoffs - `mathutils-patterns` skill -- `mathutils.Vector`, `Matrix`, `Quaternion`, common transforms, the `@` operator - Additional snippets for asset library scripting, EXR baking, multi-file extensions diff --git a/SECURITY.md b/SECURITY.md index 9c4bcbd8..c8f5cffa 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -37,8 +37,14 @@ backports. | Any earlier release | No | A confirmed fix lands on `main` and ships in the next release cut by -`release.yml`. Consumers pin by tag or track `main`; the remedy in both cases -is to move to the current release. Nothing older is patched in place. +`release.yml`. Most consumers install the plugin, which comes from the +`plugin-dist` branch: release.yml force-pushes that branch as a single orphan +commit on each release that changes plugin content, and the branch carries no +tags, so a plugin install cannot be pinned to an older release. The remedy is to +update the plugin (Claude Code: `/plugin marketplace update +blender-developer-tools`; Cursor local plugin: `git pull` in its folder). A +checkout of `main` pins by release tag (`vX.Y.Z`) or tracks `main`, and its +remedy is to move to the current release. Nothing older is patched in place. ## Response Timeline diff --git a/docs/gallery/anvil/index.html b/docs/gallery/anvil/index.html index 75891137..46d210f2 100644 --- a/docs/gallery/anvil/index.html +++ b/docs/gallery/anvil/index.html @@ -27,7 +27,7 @@ - + @@ -148,7 +148,7 @@

Wooden Barrel