Add AutoCAD MCP premium skill and backend APIs
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.
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
"""Premium drawing planning + critique data models.
|
||||
|
||||
PlanSpec is committed up-front by the LLM via `drawing_plan(...)` before any
|
||||
geometry is created; CritiqueFocus is a closed enum to keep
|
||||
`drawing_critique(...)` scope from drifting.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Literal
|
||||
|
||||
SheetSize = Literal["A4", "A3", "A2", "A1", "A0"]
|
||||
LayerSetId = Literal["iso13567", "mech", "pid"]
|
||||
DimStyle = Literal["chain", "baseline", "ordinate", "mixed"]
|
||||
CritiqueFocus = Literal[
|
||||
"iso128",
|
||||
"layer_color",
|
||||
"dim_overlap",
|
||||
"untrimmed_corner",
|
||||
"duplicate_entities",
|
||||
"construction_left",
|
||||
]
|
||||
SnapType = Literal["end", "mid", "center", "quad", "int", "perp", "near"]
|
||||
|
||||
ALL_CRITIQUE_FOCUSES: tuple[CritiqueFocus, ...] = (
|
||||
"iso128",
|
||||
"layer_color",
|
||||
"dim_overlap",
|
||||
"untrimmed_corner",
|
||||
"duplicate_entities",
|
||||
"construction_left",
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class PlanSpec:
|
||||
"""Drawing intent committed before geometry creation.
|
||||
|
||||
Returned by `drawing_plan(...)` and replayed by `drawing_critique(...)` to
|
||||
verify the finished drawing matches the original intent.
|
||||
"""
|
||||
|
||||
intent: str
|
||||
sheet_size: SheetSize
|
||||
scale: float
|
||||
layer_set_id: LayerSetId
|
||||
view_count: int = 1
|
||||
dim_style: DimStyle = "chain"
|
||||
notes: list[str] = field(default_factory=list)
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
"intent": self.intent,
|
||||
"sheet_size": self.sheet_size,
|
||||
"scale": self.scale,
|
||||
"layer_set_id": self.layer_set_id,
|
||||
"view_count": self.view_count,
|
||||
"dim_style": self.dim_style,
|
||||
"notes": list(self.notes),
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class Issue:
|
||||
"""One problem reported by `drawing_critique(...)`."""
|
||||
|
||||
severity: Literal["error", "warning", "info"]
|
||||
focus: CritiqueFocus
|
||||
message: str
|
||||
handles: list[str] = field(default_factory=list)
|
||||
detail: dict = field(default_factory=dict)
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
"severity": self.severity,
|
||||
"focus": self.focus,
|
||||
"message": self.message,
|
||||
"handles": list(self.handles),
|
||||
"detail": self.detail,
|
||||
}
|
||||
|
||||
|
||||
# ISO 128 lineweight set (mm). Any lineweight outside this set is flagged.
|
||||
ISO_128_LINEWEIGHTS_MM: tuple[float, ...] = (
|
||||
0.13, 0.18, 0.25, 0.35, 0.50, 0.70, 1.00, 1.40, 2.00,
|
||||
)
|
||||
Reference in New Issue
Block a user