feat(automation): select op — target entities by handle/type/layer

Add a select op that sets the document selection (by hex handles from
query, or by type/layer, or clear). Selection drives modify commands, so
an agent can query → select → run("ERASE") to act on specific entities.
Completes the modify half of the act/observe loop. ocs.py gains select().

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-06-17 21:27:26 +03:00
1 parent 6d29b8458c
commit c78bc62056
3 files changed
+65

No files matched your search

+10
View File
@@ -20,8 +20,18 @@ can act → observe → act.
| `{"op":"run","cmd":"LAYER Walls"}` | `{"ok":true,"cmd":...,"entities":N,"added":D}` |
| `{"op":"entities"}` | `{"ok":true,"total":N,"by_type":{"Line":42,...}}` |
| `{"op":"query","type":"Line","layer":"Walls"}` | per-entity `{handle,type,layer,…geometry}` (filters + `limit` optional) |
| `{"op":"select","handles":["2B"]}` | set the selection (by `handles`, `type`, or `layer`; `clear` to deselect) → `{"ok":true,"selected":N}` |
| `{"op":"save","path":"out.dwg"}` | `{"ok":true,"saved":"out.dwg"}` (path optional once opened/saved) |
Selection drives modify commands — `select` the targets (e.g. the handles a
`query` returned), then `run("ERASE")`:
```python
ocs.select(type="Line"); ocs.run("ERASE") # erase every line
ids = [e["handle"] for e in ocs.query(layer="Walls")["entities"]]
ocs.select(handles=ids); ocs.run("ERASE")
```
Every response has `"ok"`; failures carry `"error"`. `run` drives Open CAD
Studio's **own** command system — no separate bindings to maintain — so its
coverage grows with the app.
+13
View File
@@ -79,6 +79,19 @@ class Ocs:
"""List entities (handle, type, layer, geometry), optionally filtered."""
return self._send(op="query", type=type, layer=layer, limit=limit)
def select(
self,
handles: Optional[list[str]] = None,
type: Optional[str] = None,
layer: Optional[str] = None,
clear: bool = False,
) -> dict[str, Any]:
"""Set the selection by handle, type, or layer (a following selection
command like ``run("ERASE")`` then acts on it). `clear=True` deselects."""
return self._send(
op="select", handles=handles, type=type, layer=layer, clear=clear
)
def save(self, path: Optional[str] = None) -> dict[str, Any]:
"""Write the document (defaults to the opened/last-saved path)."""
return self._send(op="save", path=path)