[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71S0T5QS1HV2ZCTWVZZ98KJ":3,"skill-same:01M71S0T5QS1HV2ZCTWVZZ98KJ":46},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":20,"linkOnly":21,"markdownContent":22,"markdownBody":22,"frontMatter":23,"refName":24,"commitSha":25,"skillDirectory":26,"forksCount":27,"repositoryHtmlUrl":28,"repositoryHomepageUrl":6,"ownerHtmlUrl":29,"ownerBlogUrl":30,"ownerDescription":6,"updatedAt":31,"install":32,"resources":45},"01M71S0T5QS1HV2ZCTWVZZ98KJ","b123d-edit",null,"pzfreo\u002Fbuild123d-mcp","pzfreo","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1773202?v=4","01M71S0HXPCECNMYJD3RJ6QKE5","Paul Fremantle","01M71S0HYR5GR026NQN2V9P3NQ",151,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fpzfreo\u002Fbuild123d-mcp\u002Fblob\u002Fmain\u002Fsrc\u002Fbuild123d_mcp\u002Fskills\u002Fb123d-edit\u002FSKILL.md",[],[18,19],"edit","b123d edit","2026-11-10 13:02:02",false,"# Edit Existing build123d Geometry (b123d-edit)\n\nUse this skill when the task is to change an existing build123d model or script:\n\"make this bracket 5 mm taller\", \"move the holes inward\", \"add a counterbore\",\n\"remove this rib\", \"make it fit this mating part\", or \"repair the code so the\nintended edit remains parametric\".\n\nThe goal is not to sculpt the final B-rep. The goal is to make an explicit,\nreviewable code edit that preserves design intent, then prove the changed model\nis valid and the intended delta happened.\n\n## Step 0 - Establish the Baseline\n\nBefore editing, capture what exists.\n\n1. Read the source script or recover the session code with `script()`.\n2. Run the current model in the MCP session with `execute()`.\n3. Register the edited target with `show(part, \"baseline\")` or a meaningful name.\n4. Capture numeric evidence:\n\n   ```python\n   print(measure(part))\n   ```\n\n5. Run the MCP `validate()` tool on the registered baseline. For tasks whose\n   deliverable is an exported STEP, use `bank_candidate()` with the real output\n   path and `snapshot_name=\"valid_baseline\"`. It writes privately, runs the\n   written-and-reimported gate, and promotes both the file and snapshot only on\n   PASS. For other CAD formats, export the unchanged baseline to a safe\n   throwaway path and read the export gate result. For script-only work, a\n   successful rebuild plus `validate()` is the baseline proof unless the task\n   later requires a file export.\n6. If the baseline fails the relevant proof (`validate()` for script-only work;\n   `validate()` plus the throwaway export gate for exported-solid work), stop\n   and switch to `build123d:\u002F\u002Fskill\u002Frepair`. Until a repaired baseline passes\n   that same proof, the only geometry-changing operations allowed are minimal\n   baseline fixups. Do not move, cut, extend, remove, or replace the requested\n   target feature while the baseline is still invalid. Do not combine a feature\n   edit with geometry repair unless the requested edit is the repair.\n7. After the baseline passes the relevant proof, save a snapshot such as\n   `save_snapshot(\"valid_baseline\")` if `bank_candidate()` did not already do\n   so. Only then begin the requested feature or parameter edit.\n\nFor file-based work, keep the source of truth in the Python file. The MCP\nsession is the proving ground, not the only copy of the edit.\n\n## Step 1 - Translate the Request Into Code Intent\n\nClassify the edit before changing code:\n\n- **Parameter edit**: dimensions, radii, offsets, thickness, counts, or angles.\n  Prefer changing named parameters over replacing literals deep inside geometry.\n- **Feature edit**: add\u002Fremove\u002Fmove a hole, boss, rib, pocket, fillet, chamfer,\n  counterbore, or pattern. Prefer editing the feature construction block.\n- **Assembly\u002Fedit-in-context**: move or resize one part relative to another.\n  Use the MCP `compare()` tool with `kind=\"fit\"` or `kind=\"align\"` and named\n  objects to verify fit. Inside `execute()`, the lower-level Python helpers\n  `clearance(a, b)` and `align_check(a, b)` remain available for branching in\n  code.\n- **Validity edit**: change construction so the output remains manifold.\n  Use `validate()`, `locate_gate_defects()`, `find_bored_bosses()`,\n  `repair_advice()`, and the repair skill only for diagnostics and patterns.\n  `find_bored_bosses()` is useful before lengthening any boss that carries\n  a bore: it reports candidate bore axes, cap faces, split\n  caps, and construction warnings. `repair_advice()` is especially useful when\n  the intended edit is generic but topology-sensitive, such as extending a\n  bored boss, moving an annular shoulder, or fixing an export-roundtrip sliver\n  after a boolean.\n\nIf the requested edit is ambiguous, ask for the missing design intent before\nguessing: which face, which hole pattern, which mating clearance, or which\ndimension should be held constant.\n\n## Step 2 - Find the Right Code to Change\n\nEdit the highest-level expression that owns the feature.\n\nGood targets:\n\n- named parameters at the top of the script\n- helper functions such as `make_plate(width, height, thickness)`\n- one feature block, for example the loop that creates a bolt pattern\n- one transform, for example `Location((x, y, z))` for a moved subpart\n\nAvoid:\n\n- editing generated STEP\u002FSTL output instead of the source code\n- replacing a parametric feature with a one-off imported solid\n- applying broad OCP healing for a requested design change\n- changing unrelated dimensions because they make the gate pass\n\nUse `measure()` face inventory, `find_holes()`, `find_hole_patterns()`,\n`find_bosses()`, `find_bored_bosses()`, and `find_countersinks()` to identify\nthe feature in code. For spatial edits, render with labels or use\n`render_view(highlights=...)` to confirm the face\u002Fedge index before changing\nconstruction.\n\nFor an imported B-rep with no feature history, call `recognise_features()`\nwithout `families` once for the compact shared inventory, then request only the\nlikely family, for example `families=\"holes\"` or `families=\"blends\"`. Each\nreturned `@feature[...]` handle can be resolved inside `execute()` with\n`recognition_faces(handle)` for all constituent faces, or\n`recognition_faces(handle, role=\"defining\")` for the minimum recognition\nevidence. The default caller-coordinate records agree with the imported model;\nuse `coordinate_frame=\"part\"` only when a part-relative frame is useful. Handles\nare run-local and deliberately fail after their named source geometry is\nreplaced, so recognise again after an edit. Empty families are explicit misses,\nnot permission to substitute a nearby feature. Pockets, channels, blind slots and\npassages are all reported as `section_recesses`; a record whose `record_type`\nis `SectionRecessRefusal` means a recess was detected but its geometry was not\nproved, so do not reconstruct from it.\n\nFor an edit described by kind, axis, side or starting size, use\n`find_candidates(kind=\"hole\", qualifiers='{\"axis\":\"Z\",\"side\":\"+X\"}',\nstated_value=6)` before selecting a handle. It reports all recognised instances\nunder the literal axes and every proper rotation of the request frame\n(grouped by the candidates each selects) and flags an unmatched stated\nvalue. `interface_features()` suggests flat faces with hole openings and their\nhandles; identify the actual mating interface before editing. For a plain\nthrough hole with one cylindrical wall, `edit_feature(handle, diameter=8,\nprotected_refs='[...]')` predicts and measures its change and rejects an edit\nthat moves another recognised hole or the outer envelope. It refuses complex\nhole stacks; use the manual workflow below for those.\n\n## Step 3 - Make One Explicit Edit\n\nMake a small source edit, then run the complete model.\n\nFor a parameter edit:\n\n```python\n# Before\nplate_thickness = 6.0\n\n# After\nplate_thickness = 8.0\n```\n\nFor a feature move, keep the relationship visible:\n\n```python\nhole_offset_x = old_hole_offset_x - 2.5\nholes = [Pos(x, y) * Circle(hole_radius) for x, y in hole_centers]\n```\n\nFor a fit edit, name the clearance and target:\n\n```python\ntarget_clearance = 0.4\npin_radius = bore_radius - target_clearance \u002F 2\n```\n\nDo not stack several speculative edits. If the first edit fails, restore the\nsnapshot or revert the source hunk before trying the next approach.\n\n## Step 4 - Prove the Delta\n\nAfter each edit, verify both validity and intent.\n\nUse this minimum loop:\n\n```python\nshow(part, \"edited\")\nprint(measure(part))\n```\n\nThen run the MCP `validate(\"edited\")` tool. For handoff or final STEP output,\nrun `bank_candidate(\"edited.step\", object_name=\"edited\", snapshot_name=\"final\")`\nso the written STEP replaces the safe floor only after its gate passes. Use\n`export()` for diagnostic writes or non-STEP formats.\n\nThen choose the evidence that matches the edit:\n\n- envelope changed: compare `measure()[\"bbox\"]`\n- volume changed: compare `measure()[\"volume\"]`\n- hole changed: run `find_holes()` or `find_hole_patterns()`\n- counterbore changed: run `find_countersinks()`\n- fit changed: run `compare(a=\"a\", b=\"b\", kind=\"fit\")` or\n  `compare(a=\"a\", b=\"b\", kind=\"align\", axis=\"Z\", mode=\"flush\")`\n- source-level edit may be brittle: run `design_audit()`\n- shape should otherwise match a baseline: run\n  `compare(a=\"before\", b=\"edited\", kind=\"shape\")`\n\nFor imported B-reps, `compare(kind=\"shape\")` can have noisy mesh localisation\nafter a valid defeature or analytic face extension. Do not throw away a clean\nvalidated candidate solely because compare reports spread regions. First prove\nthe exact delta directly: no added material when only removal was requested, the\ndelta bounding box sits on the intended feature, the target faces are gone or\nchanged as requested, and protected feature counts\u002Fdimensions are unchanged. If\nthat evidence is clean, keep the validated defeatured result instead of replacing\nit with a raw boolean that preserves old face partitioning but creates extra\nseam faces.\n\nFor mesh-derived solids imported from 3MF or reconstructed from tessellated data,\nadd these checks to the loop:\n\n- Record the baseline solid count and gate result before editing. Faceted input can\n  contain inherited seams or near-coincident shells that only separate when a\n  boolean forces OCC to rebuild topology.\n- Do not place a cutter boundary exactly on the face being moved. Extend it a small,\n  scale-appropriate distance into open space, then verify that the result contains\n  no zero-thickness fragments. Treat `0.05 mm` as an observed example, not a\n  universal tolerance.\n- After every boolean, assert the intended solid count. If an unintended microscopic\n  gap appears, diagnose it before considering a tolerant fuse; choose any fuse\n  tolerance from the measured gap and verify protected dimensions afterwards.\n- Analytic recognisers can legitimately return zero on faceted cylinders. Confirm\n  whether the faces are analytic before interpreting an empty `find_holes()` or\n  `find_bosses()` result as absence of the feature.\n- Mesh booleans and before\u002Fafter intersections can be unstable on dirty inputs.\n  Cross-check the result's direct dimensions, solid count, and fit properties. For\n  collision tests near facet noise, compare against an unchanged control and sweep\n  a small allowance rather than trusting one absolute overlap volume.\n\nThe gate inside `bank_candidate()` is final because it checks the written and\nre-imported STEP without overwriting an existing good output on failure. A\n`validate()` pass in memory is useful but not the final acceptance proof. If the\nedited shape fails this gate, call `repair_advice(error_text=..., goal=...)`\nbefore improvising OCP surgery. Use the returned recipe as a checklist for a\nvisible `execute()` implementation, not as permission to make an opaque B-rep\nmutation.\n\n## Step 5 - Keep Regression Evidence\n\nBefore finishing, report:\n\n- what source location changed\n- which design intent was preserved\n- before\u002Fafter dimensions or feature records\n- validation\u002Fexport result\n- any known tradeoff or unverified requirement\n\nIf a change fixes a bug, add a focused test or a small reproduction script when\nthe repository has a test harness. The test should assert the user-visible\ngeometry or gate result, not just that the script runs.\n\n## Common Edit Patterns\n\n### Resize Without Moving the Reference Face\n\nWhen increasing thickness or height, decide which face stays fixed. For a part\nwhose bottom stays on Z=0, shift the solid or sketch origin so the added material\ngoes only upward.\n\n```python\nheight = 18.0\npart = Pos(0, 0, height \u002F 2) * Box(width, depth, height)\n```\n\n### Move a Hole Pattern\n\nKeep the pattern generator intact and edit its center\u002Fspacing.\n\n```python\npattern_center = (new_x, new_y)\nhole_centers = [\n    (pattern_center[0] + dx, pattern_center[1] + dy)\n    for dx, dy in offsets\n]\n```\n\nVerify with `find_hole_patterns()` or by printing sorted hole locations.\n\n### Add Clearance\n\nModel clearance as a named parameter. Do not hide it in a radius literal.\n\n```python\nclearance_diametral = 0.5\nbore_radius = shaft_radius + clearance_diametral \u002F 2\n```\n\nVerify with `compare(a=\"shaft\", b=\"bore_part\", kind=\"fit\")` or a measured section.\n\n### Remove a Feature\n\nPrefer removing the feature's construction block over adding material back with\na compensating boolean. If you must patch a removed cut, prove the final face and\nvolume match the intended design, then export-gate the result.\n\nFor imported fillet or chamfer removal, treat the job as defeaturing when the\nrounded faces are explicit analytic patches. Identify the exact torus, cone, or\nsmall blend faces, remove those faces, and let adjacent cylinders\u002Fplanes extend\nor merge. A valid defeatured result with fewer\u002Fcleaner faces is usually preferable\nto a topology-preserving cutter that leaves extra cylindrical bands or seam faces.\nAccept the defeature only after the written export gate passes and the delta\nproof shows the removed material is localized to the requested fillet\u002Fchamfer.\n\n### Topology-Sensitive Edits\n\nFor edits that often create open shells, duplicate internal faces, or disjoint\nsolids, ask the MCP for a recipe before trying variants:\n\n```text\nrepair_advice(\n  error_text=\"\u003Cvalidate\u002Fexport failure text>\",\n  goal=\"lengthen the flanged boss and its through bore by 8mm\",\n  context=\"\u003Clocate_gate_defects or compare(a='before', b='candidate', kind='shape') notes>\"\n)\n```\n\nTypical matches include split bored-boss extension, export-roundtrip sliver\ncleanup, mesh-fragile face repatching, and self-touch boolean redesign. The\nresult should guide explicit build123d\u002FOCP code in `execute()`.\n\nBefore extending a bored boss, run `find_bored_bosses()` on the baseline. If it\nreports `is_split_cap=true` or multiple `cap_faces`, do not extrude one cap face:\nconstruct a full extension sleeve\u002Fprofile from the measured bore axis and\nopening plane, then re-cut the bore continuously through old plus new material.\nReject candidates that fill the bore, create a second bore segment, or leave\nmore than one solid.\n\n### Preserve Editability\n\nIf a requested edit forces many coordinated numeric changes, hoist them into\nnamed parameters and derived expressions. Run `design_audit()` when the model\nwill likely be edited again.\n",{},"main","49023cd809092daa10dea0e9648a87006591d1f1","src\u002Fbuild123d_mcp\u002Fskills\u002Fb123d-edit",20,"https:\u002F\u002Fgithub.com\u002Fpzfreo\u002Fbuild123d-mcp","https:\u002F\u002Fgithub.com\u002Fpzfreo","http:\u002F\u002Fpzf.fremantle.org","2026-11-13 17:07:52",{"source":7,"skillName":5,"commands":33,"prompt":43,"zipAvailable":44},[34,37,40],{"tool":35,"command":36},"npx","npx skills add pzfreo\u002Fbuild123d-mcp --skill b123d-edit",{"tool":38,"command":39},"bunx","bunx skills add pzfreo\u002Fbuild123d-mcp --skill b123d-edit",{"tool":41,"command":42},"pnpm","pnpm dlx skills add pzfreo\u002Fbuild123d-mcp --skill b123d-edit","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fpzfreo\u002Fbuild123d-mcp\u002Fblob\u002Fmain\u002Fsrc\u002Fbuild123d_mcp\u002Fskills\u002Fb123d-edit\u002FSKILL.md",true,[],[47,55,63,76],{"skillNo":48,"name":49,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":50,"categories":51,"keywords":52,"publishedAt":20},"01M71S113XAE1RPP5B4TZJJCGW","b123d-repair","https:\u002F\u002Fgithub.com\u002Fpzfreo\u002Fbuild123d-mcp\u002Fblob\u002Fmain\u002Fsrc\u002Fbuild123d_mcp\u002Fskills\u002Fb123d-repair\u002FSKILL.md",[],[53,54],"repair","b123d repair",{"skillNo":56,"name":57,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":58,"categories":59,"keywords":60,"publishedAt":20},"01M71S0XRPYA245TMQSFZ0FQ9V","b123d-modeling","https:\u002F\u002Fgithub.com\u002Fpzfreo\u002Fbuild123d-mcp\u002Fblob\u002Fmain\u002Fsrc\u002Fbuild123d_mcp\u002Fskills\u002Fb123d-modeling\u002FSKILL.md",[],[61,62],"modeling","b123d modeling",{"skillNo":64,"name":65,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":66,"categories":67,"keywords":73,"publishedAt":20},"01M71S0PAQB3ZRZWZBSDF4JXBW","b123d-drawing","https:\u002F\u002Fgithub.com\u002Fpzfreo\u002Fbuild123d-mcp\u002Fblob\u002Fmain\u002Fsrc\u002Fbuild123d_mcp\u002Fskills\u002Fb123d-drawing\u002FSKILL.md",[68],{"categoryNo":69,"categoryName":70,"taxonomyType":71,"taxonomyTypeDesc":72},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[74,75],"drawing","b123d drawing",{"skillNo":77,"name":65,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":78,"categories":79,"keywords":80,"publishedAt":20},"01M71S0MW5PWTPJ7MHYYVARWB0","https:\u002F\u002Fgithub.com\u002Fpzfreo\u002Fbuild123d-mcp\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fb123d-drawing\u002FSKILL.md",[],[74,75]]