feat(selection): add selection_get — read live viewport pickfirst selection (#1)
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>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
5583730a79
commit
dfb21a734a
@@ -1141,7 +1141,7 @@ async def entity_set_properties(
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ── SECTION 5: Entity Query (3 tools) ───────────────────────────────────────
|
||||
# ── SECTION 5: Entity Query (4 tools) ───────────────────────────────────────
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@mcp.tool(
|
||||
@@ -1207,6 +1207,42 @@ async def entity_delete_many(
|
||||
return {"ok": True, "deleted": deleted, "errors": errors}
|
||||
|
||||
|
||||
@mcp.tool(
|
||||
annotations={"title": "Get Viewport Selection", "readOnlyHint": True},
|
||||
tags={"entity", "query"},
|
||||
)
|
||||
async def selection_get(ctx: Context = None) -> dict:
|
||||
"""Read the entities the user pre-selected in the AutoCAD viewport (COM backend only).
|
||||
|
||||
Returns the implied "pickfirst" selection — the entities highlighted with
|
||||
grips before invoking the AI — so work can be scoped to exactly those
|
||||
entities instead of the whole drawing. Typical use::
|
||||
|
||||
sel = selection_get()
|
||||
dimension_auto(sel["handles"], style="chain")
|
||||
|
||||
Result keys:
|
||||
ok — True on the COM backend (even for an empty selection)
|
||||
count — number of selected entities
|
||||
handles — list of entity handles (hex strings) to act on
|
||||
entities — full per-entity info (type, layer, color, ...)
|
||||
pickfirst — state of the PICKFIRST sysvar (None if unknown)
|
||||
message — guidance when nothing is selected
|
||||
|
||||
On the ezdxf headless backend there is no viewport, so this returns
|
||||
ok=False with an empty handles list.
|
||||
"""
|
||||
result = await _backend(ctx).selection_get()
|
||||
if result.get("ok"):
|
||||
await ctx.info(f"Viewport selection: {result.get('count', 0)} entit(y/ies)")
|
||||
else:
|
||||
await ctx.warning(result.get("error", "selection_get returned not-ok"))
|
||||
# The backend places EntityInfo dataclasses under "entities"; serialize them.
|
||||
result = dict(result)
|
||||
result["entities"] = [_dc(e) for e in result.get("entities", [])]
|
||||
return result
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ── SECTION 6: Layer Management (12 tools) ──────────────────────────────────
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user