dimension_linear always failed with '<unknown>.AddDimLinear' on the COM
backend — pywin32's dynamic dispatch error for a method that does not
exist: the AutoCAD ActiveX API has no AddDimLinear. AddDimRotated takes
the same arguments (XLine1Point, XLine2Point, DimLineLocation,
RotationAngle), so the call site only changes the method name.
Adds a mocked regression test asserting AddDimRotated is called with
the exact point/rotation arguments and AddDimLinear never is.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.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).
New COM-only Entity Query tool that reads AutoCAD's implied ("pickfirst")
selection set and returns the selected entity handles + EntityInfo, so the AI
can scope work (e.g. dimension_auto) to exactly what the user picked in the
viewport instead of the whole drawing. Resolves#1 — the layer-juggling
workaround is no longer needed.
- backends/base.py: abstract selection_get() returning a status dict
- backends/com_backend.py: reads ActiveDocument.PickfirstSelectionSet, surfaces
the PICKFIRST sysvar, handles the empty-selection case
- backends/ezdxf_backend.py: headless stub (ok=False, empty handles, same shape)
- server.py: @mcp.tool registration (readOnlyHint), SECTION 5 3 -> 4 tools
- README + CHANGELOG + pyproject: 110 -> 111 tools, v1.1.0 -> v1.1.1
Verified live on AutoCAD 2027 (COM): selection_get correctly returned the
user's grip selection across two distinct picks; 318 tests pass, ruff-clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Audit-driven fixes across the dual backend, the premium workflow, and the
engineering layer. 318 tests, ruff-clean.
Quality gate (the moat):
- drawing_finalize now runs the premium ISO-128 critique in addition to the
8-step validator; leftover construction, non-ISO lineweights, untrimmed
corners, duplicates and dim overlap block the gate (strict_critique fails on
warnings too).
- dim_overlap critique no longer a no-op (dim reference point + bbox fallback);
dim/construction layers resolve from the active layer set (iso13567 too).
Stability / correctness:
- view_screenshot & drawing_export_pdf render headless via Agg (no more
worker-thread SIGSEGV).
- gear tooth profile no longer self-overlaps at high tooth counts; section view
no longer duplicates bore lines; validator keyway heuristic fixed.
- ezdxf aligned/angular dim API, full-circle polar array duplicate already
covered by Sprint 1; this bundle adds save-format-from-extension,
entity_offset side selection, ARC length, properties parity (bounding_box /
rotation / char_height), mtext rotation.
COM robustness (mocked-COM tested):
- CoUninitialize on teardown; transaction commit/rollback try/finally + UNDO via
the CMDACTIVE guard; system_run_lisp guard + USERS1 value capture;
set_variable type coercion; HWND via Application.HWND; BlockInfo.description.
Security:
- HTTP remote-bind guard fires on every launch path (incl. `fastmcp run`);
StaticTokenVerifier wired into FastMCP; AutoLISP allowlist bypass-vector tests.
Hygiene: linetype-on-demand in _apply_attrs, honest view_zoom returns, snap-on-arc
sweep handling, point_tangent acos clamp, dynamic tool_groups / tool count,
word-boundary SPUR/HELICAL, undo-stack locking.
Deferred: R22 (undo/transaction stack isolation) lands with the I1 refiner (1.2),
which depends on it.
New concrete base methods (backend-agnostic, use entity_get + pure math):
- AutoCADBackend.point_intersection: LINE-LINE, LINE-CIRCLE, CIRCLE-CIRCLE
with ref_x/ref_y disambiguation for multiple candidates.
- AutoCADBackend.point_tangent: external-point-to-circle tangent touch-point
with ref_x/ref_y for side selection; correct perpendicularity formula
(T-F)⊥(T-C) via cos(θ-α)=-r/d.
Registered as MCP tools: point_intersection, point_tangent.
13 new tests in tests/test_meta_tools_geometry.py.
226 tests total.
Three production-blocking defects + two legal/infra gaps from the recon pass.
R1 (CRITICAL): the 8 premium meta-tools (drawing_plan, drawing_critique,
point_from_snap, construction_xline, construction_clear, drawing_apply_iso_layers,
dimension_auto, entity_select_smart) raised NotImplementedError on the COM
backend — i.e. the entire "non-negotiable" premium workflow crashed on the
DEFAULT Windows backend. Lifted all eight to AutoCADBackend as concrete,
backend-agnostic implementations built on the shared abstract primitives +
the identical EntityInfo.properties contract, so both backends inherit them.
The only backend-specific piece left is the new `_create_xline` primitive
(XLINE has no cross-backend entity_create_* equivalent). Removes ~285 lines of
ezdxf-only duplication; the existing meta-tool test suite now covers shared code.
R2 (CRITICAL): layer_create/layer_modify/entity_set_properties used
int(lineweight), truncating every millimetre lineweight (0.50, 0.25, 0.18, 0.13)
to 0 — silently wiping the whole ISO 128 discipline, because engineering/layers.py
passes mm-floats while the MCP boundary passes hundredths-ints. Added
normalize_lineweight() to reconcile both conventions to ezdxf/COM hundredths and
wired it into all six call sites.
R3 (HIGH): _check_iso128 was a permanent no-op (everything was 0 from R2, so the
`lw <= 0: continue` guard skipped all layers). Fixed by R2; additionally exclude
CONSTRUCTION-class layers (intentionally sub-ISO 0.05mm scratch weight) to avoid
a new false positive, and corrected the misleading "normalises to mm" comment.
Also: add MIT LICENSE (referenced by CLAUDE.md but missing — legal gap) and
restore .github/workflows/ci.yml (lint kept non-blocking until the repo-wide
ruff cleanup; the test job is the real gate).
Verified: 182 passed / 2 xfailed; functional check confirms lineweights now
store as hundredths (GEOMETRY=50) and the ISO critique correctly flags a 0.40mm
layer while passing a clean ISO drawing.
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.
Introduces an engineering/ package that lets MCP clients produce production-
quality technical drawings without LLM-improvised geometry. Adds 7 new MCP
tools, an 8-step pre-completion validator, and an automatic linetype + layer
bootstrap on drawing_new so CENTER/HIDDEN/PHANTOM and standard mechanical
layers (GEOMETRY, DIM, HATCH, TEXT, TITLEBLOCK, ...) are always available.
- engineering/gear.py: pure-Python involute math, 40+ points/flank, helical
+ spur front views, deterministic section A-A (no helix lines in section).
- engineering/keyway.py: DIN 6885 keyway table + parametric keyed bore /
side-section drawers.
- engineering/titleblock.py: ISO 7200 A3 (420x297 mm) title block; title
text is written verbatim to the title cell.
- engineering/validator.py: DrawingValidator with 8 checks (real DIMENSION
entities, no hidden orphans, linetypes loaded, bore + keyway in both
views when expected, title consistency e.g. forbid 'HELICAL SPUR GEAR'
when helix_angle truthy, saved-to-disk + file-on-disk, screenshot
exported, dwg path returned).
- backends/ezdxf_backend.py: AutoCAD-only linetype fallback (HIDDEN,
BORDER families) so ezdxf doc gets correct patterns when linetype_load
is called for names ezdxf.tools.standards does not ship.
- backends/base.py: concrete helpers set_layer_active / ensure_linetypes.
- server.py: Section 12 with 7 engineering tools, drawing_new(bootstrap=
True), and an ENGINEERING WORKFLOW block in the MCP instructions string.
- 30 new tests covering gear math, DIN6885 lookup, ISO A3 layout, title
verbatim, and every validator check. Tool count 89 -> 96.