Track F starts here; the three group branches are cut from this commit.
- engineering/arch/model.py: Wall, Opening, Stair and Room as frozen
dataclasses, and every refusal of spec 4 before anything is drawn, by path
(walls[2].thickness): finite positive numbers, an axis of at least two
distinct points with no zero-length segment, an arc segment refused by name
rather than approximated, an opening on an unknown wall, past its wall,
across an axis vertex or overlapping another (both ids named), an unknown
material, and a typed room area - areas are measured, never typed. The
plan travels as ACADMCP_ARCH XDATA; an opening's door/window kind and a
stair's straight/l/u kind ride beside the payload kind as opening_kind /
stair_kind, because one key cannot hold both.
- engineering/arch/layers.py: the arch set - thirteen ISO 13567-style layers
with ISO 128 lineweights only (0.05 mm on the construction scratch layer,
as every set in this repository) - and ARCH_ROLE_LAYER, the one place a
role becomes a layer. Registered in engineering/layers.py last, which is
what keeps the engineering.layers <-> engineering.arch import cycle closed.
- engineering/arch/materials.py: eight wall materials, one pattern each,
every row citing its source: ANSI31 for brick (ISO 128-50 general hatching,
acadiso.pat's own "Iron, Brick, Stone masonry"), AAC as ANSI31 at twice the
spacing (a repository convention, and it says so), AR-CONC / AR-SAND as
AutoCAD patterns, and the JIS A 0150 RC / stone / wood symbols. Reinforced
concrete cannot be ANSI31 and AR-CONC in one HATCH, so it takes the one
symbol that names it. Periods on a 1:50 sheet are recomputed from ezdxf's
own pattern definitions by the tests. normalise_material is the one reading
of a material name, shared by the model and wall_hatch, so the model never
refuses "Reinforced Concrete" that the hatch table resolves.
- engineering/arch/lang.py: EN / TR vocabulary, D/W and K/P tag prefixes, and
the decimal comma for lang="tr" (24,50 m2).
- draw_prims(role_layer=) and the XDATA codec's app_id= / kinds=: both
generalised with the mechanical defaults, and the mechanical suite passes
unchanged against them - that is the regression gate.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
The four track-B/G branches are merged; this is the integration that makes the
25 new tools one surface instead of four.
- engineering/mech/critique.py: the six focuses of spec 13, dispatched the way
the P&ID ones are. One index per critique run, shared through run_critique's
context, so six focuses cost one read of the drawing; a drawing with no
ACADMCP_MECH payload yields nothing at all, which is what keeps focus=None
cheap for a P&ID sheet or a plain DXF. Each focus has a positive and a
negative fixture.
Two narrowings are in the module docstring rather than hidden:
mech_view_misaligned checks the projection axis and not the quadrant,
because the pinned payload carries no projection angle to check it against,
and mech_duplicate_dimension catches two dimensions in the same place rather
than a semantic restatement, because no engine exposes what a dimension
measured.
- The index reads what the tools actually write, not only the plan's fixture
shape. mech_part_draw anchors its part payload on a POINT (layer MECH) and
lists every drawn view under "views"; the plan's index read INSERT/CIRCLE
only and one "view" per payload, so it was silent on every part the server
draws. It now reads POINT too, expands "views" into one entry per drawn view
(the section check looks in the section's own WCS box, the alignment check
compares frame_bbox centres), and pages entity_list instead of one call.
Test: a part drawn by draw_part + add_view is read and passes all six; the
same part with its hatch erased is reported.
- Live type names, measured on AutoCAD 2026 (2026-09-23, scratch document,
closed): ObjectName AcDbBlockReference -> BLOCKREFERENCE, AcDbRotatedDimension
-> ROTATEDDIMENSION, AcDbAlignedDimension -> ALIGNEDDIMENSION, AcDbPoint ->
POINT with GetBoundingBox = the point. The index reads BLOCKREFERENCE as an
INSERT and any *DIMENSION as a dimension; a wrapper test reports the ezdxf
entities under exactly those measured names.
- mech_thread_unrepresented uses the view engine's own MINOR_RATIO, and checks
the thin line ISO 6410 draws: the minor diameter of an external thread, the
major of an internal one.
- mech_bom_balloon_mismatch: identical parts share one balloon (ISO 6433
balloons a parts-list row), so a second M12x60 is covered by the first one's
balloon instead of reported.
- TOOL_PACK_NAMES has "mech" (the 14 tools of SECTIONS 21-23). SECTION 24
stays core: a frame, a title block, a parts list and an xref are universal
drafting, not a vertical. Lean gains five and reaches 60 (54 with
TOOL_PACKS=core).
- _GROUP_TAG_PRIORITY gains sheet directly after mech; the mech group label
becomes "mechanical". SECTION 24's last four tools (xref_attach,
xref_manage, image_attach, drawing_export_dwg) now carry the sheet tag, so
group, pack and SECTION are one list: 229 tools in 25 groups, and
engineering/blocks/entity_creation/drawing return to their pre-SECTION-24
sizes.
- Ten golden tuning cases, two of them Turkish (with the diacritic spellings
added to the alias records next to the ASCII-folded ones). The shared
AutoCAD command set needed no change: the merge had already resolved TABLE,
REVCLOUD, SECTIONPLANE, INSERT, ARRAY and SAVEAS, and nothing is stale.
- Inventory regenerated, the frozen group-size snapshot retaken from the live
registry, and the README release-snapshot / pack / lean figures taken from
scripts/check_doc_numbers.py rather than typed.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
ruff format was never run repo-wide; CI now enforces 'ruff format --check', so normalize every module once. No behavior changes.
Co-authored-by: Cursor <cursoragent@cursor.com>
Adds production-grade engineering features and tools: 2D GD&T (feature control frames + datum features) via engineering/gdt.py, ISO‑129 dimension tolerance support (engineering/tolerances.py) and an ezdxf/COM plumbing for toleranced dims, a scalar drawing score + invalidity ratio (engineering/scoring.py) wired into drawing_finalize, in-place entity editors (entity_edit_text/entity_edit_geometry), and a friendly drawing_settings facade. Includes server tool wiring, COM/ezdxf backend implementations, datum-consistency critique, many unit tests, README/CLAUDE/CHANGELOG updates, and a version bump to 1.2.0. Also corrects COM backend capability label (entities_2d).
Introduce the autocad-mcp-premium skill with workflow docs, examples, and references (.claude/skills/autocad-mcp-premium/*). Add PlanSpec/critique plumbing and engineering helpers (engineering/plan_spec.py, engineering/critique.py) plus tests and a smoke script. Extend backend API (backends/base.py) with corner operations and premium meta-tools (trim/extend/fillet/chamfer, drawing_plan, drawing_critique, point_from_snap, construction_xline/clear, drawing_apply_iso_layers, dimension_auto, entity_select_smart) and implement COM backend corner ops (backends/com_backend.py) with placeholders for meta-tools. Update CLAUDE.md to document the premium drawing rules and standard workflow. Misc: add examples, references, and tests for premium features, and minor server/backend adjustments.