feat(blender): extension set live in the GUI; MCP acceptance 9/9, probe made safe-mode compliant

This commit is contained in:
vh
2026-09-28 15:08:22 -07:00
parent 056433555f
commit fd20183cbb
3 changed files with 62 additions and 21 deletions
+4 -4
View File
@@ -201,10 +201,10 @@ _As of 2026-09-27 ~0900 PT._
add-ons (`stacks/blender/extensions.lock`) built by `scripts/blender-extensions sync` into
`fv-ml1:/tank/blender-extensions/5.2/system` (LIVE), mounted read-only as the System repo;
`fleet_extensions.py` enables them (GUI startup timer; `blender-run --extensions`). Headless
acceptance 8/9 (CAD Sketcher sketching is GUI-only). **⚠ The stack deploy that wires the GUI
and the hook (`deploy-stack.sh fv-ml1 blender`) was DENIED by the permission classifier on
2026-09-28 and awaits Prime**; until it runs, `blender-run --extensions` fails cleanly (mount
error) and the MCP acceptance is not done. SurfacePsycho's eval() is patched to literal_eval.
acceptance 8/9 (CAD Sketcher sketching is GUI-only); **MCP 9/9 after Prime ran the deploy himself
(1505; the classifier had refused mine)**. SurfacePsycho's eval() is patched to literal_eval
(held under MCP). Open: agent-drawn CAD Sketcher geometry (its stateful ops want point picks),
and MeasureIt overlays not seen in MCP screenshots. GUI left DOWN.
### Zigbee2MQTT on esh-docker-vm (2026-09-27, Prime go-ahead; ha-dev request)
+36 -16
View File
@@ -70,11 +70,9 @@ def dims(o):
return "x".join(str(round(d * 1000, 3)) for d in world_extent(o)) + " mm (world)"
def run(name, fn):
try:
fn(name)
except Exception as ex:
report(name, False, "raised " + type(ex).__name__ + ": " + str(ex))
def raised(name, ex):
# repr, not type(ex).__name__: safe mode refuses dunder attributes.
report(name, False, "raised " + repr(ex)[:300])
# 1. 3D-Print Toolbox: clean non-manifold on a cube with one face deleted.
@@ -221,17 +219,39 @@ def t_cad_sketcher(name):
"sketch objects " + str(len(sketches)))
for n, f in (
("print3d_toolbox clean_non_manifold", t_print3d),
("bool_tool boolean_auto_difference", t_booltool),
("looptools circle", t_looptools),
("measureit addsegment", t_measureit),
("surfacepsycho bezier patch + STEP export", t_surfacepsycho),
("step_importer import_scene.step", t_step_import),
("ThreeMF_io export + import", t_threemf),
("CAD_Sketcher sketch + solve", t_cad_sketcher),
):
run(n, f)
# Each test is called by name: safe mode refuses calling a function held in a variable.
try:
t_print3d("print3d_toolbox clean_non_manifold")
except Exception as ex:
raised("print3d_toolbox clean_non_manifold", ex)
try:
t_booltool("bool_tool boolean_auto_difference")
except Exception as ex:
raised("bool_tool boolean_auto_difference", ex)
try:
t_looptools("looptools circle")
except Exception as ex:
raised("looptools circle", ex)
try:
t_measureit("measureit addsegment")
except Exception as ex:
raised("measureit addsegment", ex)
try:
t_surfacepsycho("surfacepsycho bezier patch + STEP export")
except Exception as ex:
raised("surfacepsycho bezier patch + STEP export", ex)
try:
t_step_import("step_importer import_scene.step")
except Exception as ex:
raised("step_importer import_scene.step", ex)
try:
t_threemf("ThreeMF_io export + import")
except Exception as ex:
raised("ThreeMF_io export + import", ex)
try:
t_cad_sketcher("CAD_Sketcher sketch + solve")
except Exception as ex:
raised("CAD_Sketcher sketch + solve", ex)
failed = [r[0] for r in results if not r[1]]
print("SUMMARY " + TAG + ": " + str(len(results) - len(failed)) + "/" + str(len(results)) + " passed")
+22 -1
View File
@@ -230,4 +230,25 @@ z = 0, area 399.999982 mm² against 400. Extruded 2 mm, it gave a valid 799.9999
real NURBS surface reaches the kernel, not triangles, and millimetres hold across the hop. That is
one run of a flat bilinear patch; curved and trimmed patches are untested.
**MCP (GUI) path:** pending the stack deploy that mounts the repo and hook into the GUI container.
**MCP (GUI) path, 2026-09-28 1506 (after Prime ran the deploy):** the hook log read
`enabled 8/8`, `hardened: surfacepsycho ... literal_eval`, `online access: False`. Through
`scripts/blender-mcp` → `execute_blender_code` under safe mode, the probe passed **9 of 9**,
including CAD Sketcher (a sketch on the XY origin plane, then a full solve), because the GUI has
the workspace tool that `-b` lacks. The eval patch held under MCP: the code payload was refused
(`ValueError: malformed node`) and the literal `{3, 5}` was accepted.
- **CAD Sketcher sketch, re-solved headless:** the MCP-made sketch was saved
(`cad-sketch-mcp.blend`), then `blender-run --cpu --extensions` opened it and
`view3d.slvs_solve(all=True)` returned FINISHED. Authoring is in the GUI; re-solving works in batch.
- **Not solved yet:** drawing CAD Sketcher geometry from code. `slvs_add_rectangle` with
`p1_fallback`/`p2_fallback` and `wait_for_input=False` raised
`'NoneType' object has no attribute 'co'`. Its drawing ops are stateful and expect point picks,
and its Python entity API is out of reach under safe mode. Sketches work; agent-drawn profiles
need more work.
- **Not confirmed:** MeasureIt overlays in `get_viewport_screenshot`. The segment was created and
`measureit.runopengl` returned FINISHED, but two screenshots (a top view with a 20 mm edge
dimension) showed no dimension.
- `blender-run --extensions` (the real wrapper, `--cpu`) ran the same probe at 8 of 9, the one
miss being CAD Sketcher for the headless reason above.
Safe-mode note for probe authors: safe mode refuses calling a function held in a variable and
any dunder attribute (`type(ex).__name__`). The probe calls each test by name and uses `repr(ex)`.