diff --git a/.claude/skills/kompas-3d/SKILL.md b/.claude/skills/kompas-3d/SKILL.md
new file mode 100644
index 0000000..cdd2af5
--- /dev/null
+++ b/.claude/skills/kompas-3d/SKILL.md
@@ -0,0 +1,110 @@
+---
+name: kompas-3d
+description: >
+ Методика работы с КОМПАС-3D через MCP-сервер этого проекта: построение и
+ модификация деталей, импорт/экспорт STEP, работа со сборками, осмотр геометрии
+ снимками и запросами. Используй ВСЕГДА, когда задача — что-то СДЕЛАТЬ в КОМПАС
+ через MCP-инструменты (создать/править деталь, импортировать STEP, разобрать
+ сборку, померить, отрендерить, экспортировать). Здесь — playbook'и и эвристики,
+ выработанные в usecases/. Триггеры: «построй деталь в КОМПАС», «импортируй STEP»,
+ «что в этой сборке», «нарасти/измени деталь», «экспортируй STEP», «сделай снимок модели».
+ НЕ для поиска по справке SDK — это навык kompas-sdk-research.
+---
+
+# kompas-3d — методика управления КОМПАС-3D через MCP
+
+## Два слоя (важно не смешивать)
+
+- **MCP-сервер** (`src/Kompas.Mcp.Host`) — *инструмент*. Он **транслирует возможности COM API/SDK
+ КОМПАС** в MCP-инструменты. Инструменты делаются **общими** (по возможностям SDK), а не под
+ конкретную задачу. Расширяя MCP, добавляй универсальную операцию (например `import_step`,
+ `list_components`, `export_step`, «переместить грань», «рассечь тело»), а не «сделать вот эту деталь».
+- **Этот навык** — *методика*. Как из общих инструментов собрать решение: порядок шагов,
+ выбор геометрии, проверка результата, обход подводных камней. Подходы вырабатываются в
+ **`usecases/`** и поднимаются сюда.
+
+Итог: **MCP = чем делать, навык = как делать.** Новый приём сначала обкатывается кейсом, потом
+обобщается: инструмент → в MCP, метод → в этот навык.
+
+## Когда применять
+
+Любая задача «сделать что-то В КОМПАС» через MCP: создать/править деталь, эскизы и операции,
+импорт/экспорт обменных форматов, разбор сборки, измерения, снимки. Для поиска сигнатур/констант
+в справке — отдельный навык `kompas-sdk-research`. Для правки документации — `docs-delegate`.
+
+## Инструменты MCP
+
+**Реализованы (v2+, 35 инструментов):** `kompas_connect`, `kompas_set_visible`, `kompas_status`;
+`document_create|open|save|save_as|close|active`; `sketch_create`, `sketch_create_on_face[_index]`,
+`sketch_add_line|circle|rectangle|axis`, `sketch_close`; `extrude_boss|cut`, `revolve_boss|cut`,
+`fillet_edge[_index]`, `chamfer_edge[_index]`, `rebuild`; **`move_face`** (прямое редактирование: сдвинуть грань на N мм);
+`get_part_info`, `get_bounding_box`, `list_faces`, `list_edges`, `list_components`;
+`import_step`, `export_step`; `model_snapshot`.
+
+**Планируются (трансляция SDK, по мере кейсов):** рассечение/перемещение тела как инструменты
+(`SplitSolids`/`BodyRepositions` — механика есть, продуктизация не закончена), `list_bodies`,
+массивы/паттерны, переменные/свойства.
+
+> Если нужного инструмента ещё нет — не хардкодь обход под кейс. Заведи кейс в `usecases/`,
+> докажи механику (тест или минимальный прогон в usecases/), затем продуктизируй как
+> **общий** инструмент MCP (с тестами, TDD) и опиши приём здесь.
+
+## Базовый цикл (эскиз → операция → осмотр)
+
+Опорный сценарий построения, проверен end-to-end (см. `usecases/0001`):
+
+1. `kompas_connect` (+ `kompas_set_visible true`, чтобы снимки были осмысленны).
+2. `document_create part`.
+3. `sketch_create XOY` → `sketch_add_*` → `sketch_close`.
+4. `extrude_boss`/`revolve_boss`/…
+5. **Осмотр:** `model_snapshot` (увидеть) + `get_part_info`/`get_bounding_box` (сверить числами).
+6. Итерация «на грани»: `model_snapshot` → `list_faces` → `sketch_create_on_face_index` → операция.
+
+## Работа с импортом / сборками (выработано в usecases/0002)
+
+Конвейер «импорт → разбор → извлечение детали → осмотр → модификация → экспорт»:
+
+1. **Импорт STEP** в новый документ (под капотом: встроенный конвертер по коду формата
+ `ksConverterFromSTEP`, затем `ConvertFromAdditionFormat`). Тип документа выбирается по
+ содержимому: сборка → `.a3d`, одиночное тело → деталь.
+2. **Разбор сборки**: перечислить компоненты (имя, обозначение, габарит, файл) — обход `TopPart → Parts`.
+3. **Извлечение отдельной детали**: при импорте включать «создавать файлы компонентов», тогда
+ компоненты пишутся как отдельные `.m3d` рядом; открывать деталь самостоятельным документом
+ (`OpenSourceDocument`). Гашение видимости компонента на снимок **не влияет** — изоляция так не делается.
+4. **Осмотр детали**: габарит по осям (какая ось — «высота»), `list_faces`/`list_edges`, стандартные
+ проекции (`#Спереди/#Сверху/#Слева/#Справа/#Изометрия`) + `model_snapshot` для каждой.
+5. **Модификация**: на «тупой» импортированной B-rep работает `move_face` — сдвинуть грань на +N мм
+ (наружу, добавить материал) или −N мм (внутрь). Рассечение/раздвижка тела — механика есть,
+ отдельных инструментов пока нет (см. ниже).
+6. **Экспорт STEP**: `ConvertToAdditionFormat` (есть AP203/AP214/AP242).
+
+Точные COM-приёмы и сигнатуры — в авто-памяти `kompas-step-and-assembly-api` и в `usecases/0002/case.md`.
+
+## Эвристики и подводные камни
+
+- **Решай по снимку.** После каждой формообразующей операции делай `model_snapshot` и проверяй
+ визуально; числами — `get_part_info`/`get_bounding_box`.
+- **Грань/ребро по индексу надёжнее, чем по точке.** Сначала `list_faces`/`list_edges`, затем
+ `*_on_face_index` / `*_edge_index`. По точке (`SelectByPoint`) — только когда индекс не подходит.
+- **Направление операции.** `extrude_boss(..., forward)` может уйти «не туда» в зависимости от
+ нормали выбранной грани — проверь снимком, при необходимости инвертируй `forward`.
+- **МЦХ.** Объём/масса меняющейся геометрии бери через `get_part_info` (под капотом API5
+ `CalcMassInertiaProperties`); перед чтением после правок — `rebuild`.
+- **id эскизов/операций** недействительны после смены активного документа (create/open/close).
+- **Единицы — мм** (геометрия) и кг (масса). Локальные координаты эскиза ≠ мировые координаты модели.
+
+## Открытые вопросы / границы
+
+- **Перемещение грани (`move_face`) — реализовано.** Работает на импортированной B-rep через
+ `IPart7.FindObjectsByPoint` + `FaceMover`. Проверено: top_spacer 39.45→41.45 мм.
+- **Рассечение/перемещение тела** (`SplitSolids`/`BodyRepositions`) — механика задокументирована,
+ отдельными MCP-инструментами не оформлена. Возможная следующая опция.
+- Сборки/паттерны/переменные в MCP пока не реализованы.
+
+## Связанное
+
+- Инструменты и их реализация: `src/Kompas.Mcp.Host/Tools/*`, `src/Kompas.Mcp.Core/*`.
+- Кейсы (полигон подходов): `usecases/` (см. `usecases/README.md`).
+- Поиск по справке SDK: навык **kompas-sdk-research**.
+- Правка документации проекта: навык **docs-delegate**.
+- Память: `kompas-step-and-assembly-api` (проверенные COM-приёмы импорта/экспорта/обхода).
diff --git a/CLAUDE.md b/CLAUDE.md
index eab37b4..5409199 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -31,14 +31,14 @@ The index lives at `docs/kompas_sdk_index.tsv` (`filenametitleexcerpt`
## Current state
-**v1 + v2 implemented and working** (full sketch→feature→inspect loop validated end-to-end). Stack:
+**v1 + v2 + STEP/assembly + direct B-rep edit + structural model inspection implemented and working** (full sketch→feature→inspect→STEP round-trip + move_face + describe_model validated end-to-end). Stack:
**.NET 8 (`net8.0-windows`, x64), C#**, MCP via the official `ModelContextProtocol` SDK over **stdio**.
-**31 MCP tools, 19 tests green.** v2 added: sketch-on-face (by point and by index), revolve (boss/cut +
-sketch axis), fillet/chamfer (edge-by-point and by index), and Query tools `get_part_info` (МЦХ),
-`get_bounding_box`, `list_faces`, `list_edges`.
+**43 MCP tools, 60 tests green.** v2 added: sketch-on-face (by point and by index), revolve (boss/cut + sketch axis), fillet/chamfer (edge-by-point and by index), and Query tools `get_part_info` (МЦХ), `get_bounding_box`, `list_faces`, `list_edges`. After v2: `import_step`, `export_step` (`ConversionService`, `ConversionTools`), `list_components` (assembly traversal via `TopPart → IParts7`). `move_face` (`FaceEditService`, `EditTools`) — direct B-rep face editing. Latest: **structural model inspection** — `describe_model`, `list_features`, `list_bodies`, `list_variables`, `describe_face`, `describe_edge`, `measure` (`ModelInspectionService`, `InspectionTools`). `describe_model` is the preferred first call over `model_snapshot` (no token cost for image context; gives feature tree, bodies, variables, topology summary, МЦХ).
See [`README.md`](README.md) and [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md); design decisions/caveats in
[`docs/OPEN_QUESTIONS.md`](docs/OPEN_QUESTIONS.md).
+Principle: **MCP = translating SDK capabilities into general tools** (not task-specific). On top of MCP — skill **`.claude/skills/kompas-3d/`** with a methodology (playbooks, heuristics, validated in `usecases/`). Layout: `usecases/` (in .gitignore) is the proving ground; proven techniques are promoted to the skill.
+
Layout: `src/Kompas.Mcp.Core` (COM layer), `src/Kompas.Mcp.Host` (MCP stdio server + tools),
`tests/Kompas.Mcp.Tests` (unit + integration), `libs/kompas-interop/*.dll` (vendored КОМПАС interop
assemblies from SDK `Samples/Common`, referenced via `Directory.Build.props` → `KompasInteropDir`).
@@ -56,9 +56,15 @@ Key implementation facts (don't relearn):
- 3D is built via **API5 `ksPart`** (`NewEntity(o3d_sketch/o3d_bossExtrusion/o3d_bossRotated/o3d_fillet/o3d_chamfer/...)`, `ksBossExtrusionDefinition`/`ksCutExtrusionDefinition`/`ksBossRotatedDefinition`/`ksFilletDefinition`/`ksChamferDefinition`); cut-through holes use `dtBoth` + `etThroughAll`. API7 is used for app/documents.
- **Face/edge selection**: `ksPart.EntityCollection(o3d_face|o3d_edge)` → `SelectByPoint(x,y,z)` (world mm) filters to objects through the point, then `GetByIndex(0)`; or by stable index from `list_faces`/`list_edges`. `ksFaceDefinition.IsPlanar/IsCylinder/...` + `GetArea(ST_MIX_MM)` classify faces. `ksEdgeDefinition.IsLineSeg/IsCircle/IsArc/...` + `GetLength()` classify/measure edges. Sketch axis = line with system style **3** (осевая). Fillet/chamfer by edge index via `fillet_edge_index`/`chamfer_edge_index` (more reliable than by-point).
- **МЦХ / mass props**: use **API5 `ksPart.CalcMassInertiaProperties(ST_MIX_MM|ST_MIX_KG)`** → `ksMassInertiaParam` (`v`/`m`/`F`/`xc`/`yc`/`zc`), computed on demand. **Do NOT** use API7 `IMassInertiaParam7.Calculate()` — its `Actual` flag sticks after the first calc and won't refresh on API5 geometry changes (stale volume). Bounding box: `ksPart.GetGabarit(full:false, ...)`.
-- **Snapshot**: `ksDocument3D.SaveAsToRasterFormat(file, ksRasterFormatParam)` renders to a temp file (the in-memory `resultArrayBytes` stays empty when a filename is given); read bytes back. Return to MCP via `ImageContentBlock.FromBytes(bytes, mime)` — **not** `Data = bytes` (Data holds base64 bytes).
+- **Snapshot**: `ksDocument3D.SaveAsToRasterFormat(file, ksRasterFormatParam)` renders to a temp file (the in-memory `resultArrayBytes` stays empty when a filename is given); read bytes back. Return to MCP via `ImageContentBlock.FromBytes(bytes, mime)` — **not** `Data = bytes` (Data holds base64 bytes). Use `model_snapshot` only for visually-spatial questions; **prefer `describe_model` first**.
- Logs go to **stderr** (stdout is the MCP channel). Integration tests reuse one КОМПАС via `KompasFixture`; artifacts land in gitignored `.scratch/`.
-- Not yet done (next): patterns/arrays, `list_bodies`, variables/properties (`IVariable7`), 2D drawing, assemblies, a proper in-process MCP-client test. Known caveat: boss/cut direction on a selected face depends on face-normal orientation (`forward` may need flipping — agent picks via snapshot). See `docs/OPEN_QUESTIONS.md` → «Ревью v2».
+- **Structural model inspection** (`ModelInspectionService`, `InspectionTools`): `describe_model` — one-call structural "passport" (bounding box + МЦХ + bodies + topology summary + feature tree + variables); preferred over snapshot. `list_features` — feature tree with params (depth/radius/legs). `list_bodies` — list solid/surface bodies with face count. `list_variables` — model variables (name/expression/value, external/info flags). `describe_face` — drill-down by index (type, area, normal, radius, edge count). `describe_edge` — drill-down by index (type, length, adjacent faces, vertices). `measure` — distance/angle between two objects (face|edge|vertex by index, unit `ST_MIX_MM`).
+- **Feature tree API** (don't relearn): read via API5 `ksPart.GetFeature()` → `(ksFeature).SubFeatureCollection(true,false)` → `ksFeatureCollection`. Cast `(ksFeature)part` does NOT work (RCW QI returns null) — must use `GetFeature()`. `ksFeature.type` returns only coarse `o3d_entity` and does NOT distinguish operations; precise type and params come from `ksFeature.GetObject()` → `ksEntity.GetDefinition()` and matching definition type (`ksBossExtrusionDefinition.GetSideParam`, `ksFilletDefinition.radius`, `ksChamferDefinition.GetChamferParam`, …). Node name ("Элемент выдавливания:1", "Скругление:1") is localized by КОМПАС itself.
+- **STEP import/export, `list_components`, `move_face`, and full inspection layer are done.** Not yet done: body split/reposition as MCP tools (SplitSolids/BodyRepositions — driveable but not yet implemented); patterns/arrays, 2D drawing, assembly building. Known caveat: boss/cut direction on a selected face depends on face-normal orientation (`forward` may need flipping — agent picks via snapshot or `describe_face` normal). See `docs/OPEN_QUESTIONS.md` → «Ревью v2».
+- **"STEP import without history"** detected structurally: `bodyCount > 0 && no formative features && features.Count <= bodyCount+1` (only origin + body). STEP with edits (move_face: "Смещённая плоскость", "Разрезать", "Переместить грани", "Булева операция") — that already has history.
+- **Topology/measure API**: `ksFaceDefinition.EdgeCollection` / `GetCylinderParam` / `GetSurface().GetNormal` + `normalOrientation`; `ksEdgeDefinition.GetAdjacentFace(bool)` / `GetVertex(bool)` → `ksVertexDefinition.GetPoint`; bodies via `ksPart.BodyCollection()` → `ksBody` (`IsSolid` / `FaceCollection`); variables via `ksPart.VariableCollection()` → `ksVariable`; measurements via `ksPart.GetMeasurer()` → `ksMeasurer` (`SetObject1/2`, `unit=ST_MIX_MM`, `Calc`, `distance`/`MinDistance`/`angle` in degrees / `IsAngleValid`).
+- **STEP import COM pattern** (verified): `IApplication.get_Converter((object)(int)ksConverterFromSTEP=-3)` (pass format code, not DLL path) → `IConverter.ConverterParameters(cmd)` → set `IAdditionConvertParameters.Format=ksConverterFromSTEP` → `IKompasDocument3D1.ConvertFromAdditionFormat(path, prm)`. Export: `ConvertToAdditionFormat` with format codes for AP203/AP214/AP242. Param co-classes (AdditionConvertParameters etc.) are NOT CoCreatable — only via converter factories. Assembly traversal: `IKompasDocument3D.TopPart → IPart7.Parts (IParts7)`. Extract component: `prm.NeedCreateComponentsFiles=true` (writes .m3d files next to STEP) + `IPart7.OpenSourceDocument`.
+- **Direct B-rep face editing (`move_face`)** (verified on top_spacer, 39.45→41.45 mm height): API7 face object retrieved via `IPart7.FindObjectsByPoint(x,y,z,true)` → cast to `KompasAPI7.IFace`; containers acquired at runtime via COM-QI: `(ISurfaceContainer)part`, `(IModelContainer)part`; `FaceMover` (SetFaces + Offset + Direction + Update) moves the face. distance>0 = outward (add material), <0 = inward. Works on both parametric and imported B-rep geometry. Full split-reposition workflow (SplitSolids/BodyRepositions) is driveable but not yet exposed as tools.
## КОМПАС-3D API architecture (the critical context)
diff --git a/KompasMcp.slnx b/KompasMcp.slnx
index a3a10ac..3c7191b 100644
--- a/KompasMcp.slnx
+++ b/KompasMcp.slnx
@@ -1,6 +1,5 @@
-
diff --git a/README.md b/README.md
index 694e123..798e884 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,12 @@
Сервер — это COM-клиент КОМПАС-3D: он подключается к установленному КОМПАС и предоставляет
LLM набор инструментов для создания документов, построения 3D-деталей (эскиз → выдавливание),
-а также **снимок модели** (агент «видит» результат и строит пошагово).
+импорта/экспорта STEP, работы со сборками, структурного осмотра модели (`describe_model` — дерево
+операций, тела, переменные, топология одним вызовом) и снимка модели (агент «видит» результат).
+
+Принцип: **MCP транслирует возможности SDK КОМПАС в общие инструменты** (не под конкретную задачу).
+Поверх MCP — навык **`.claude/skills/kompas-3d/`** с методикой работы (playbook'и, эвристики,
+обкатанные в `usecases/`).
> Подробности: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) · план — [docs/IMPLEMENTATION_PLAN.md](docs/IMPLEMENTATION_PLAN.md)
> · спорные вопросы — [docs/OPEN_QUESTIONS.md](docs/OPEN_QUESTIONS.md) · обзор — [docs/presentation.html](docs/presentation.html)
@@ -34,21 +39,28 @@ src/Kompas.Mcp.Host/bin/Release/net8.0-windows/kompas-mcp.exe
}
```
-## Инструменты (v1)
+## Инструменты (43 инструмента)
| Группа | Инструменты |
|---|---|
| System | `kompas_connect`, `kompas_status`, `kompas_set_visible` |
| Documents | `document_create`, `document_open`, `document_save`, `document_save_as`, `document_close`, `document_active` |
-| Sketch | `sketch_create`, `sketch_add_line`, `sketch_add_circle`, `sketch_add_rectangle`, `sketch_close` |
+| Sketch | `sketch_create`, `sketch_create_on_face`, `sketch_create_on_face_index`, `sketch_add_line`, `sketch_add_circle`, `sketch_add_rectangle`, `sketch_add_axis`, `sketch_close` |
| Features | `extrude_boss`, `extrude_cut`, `revolve_boss`, `revolve_cut`, `fillet_edge`, `chamfer_edge`, `fillet_edge_index`, `chamfer_edge_index`, `rebuild` |
-| Vision | `model_snapshot` (PNG-снимок активной модели) |
-| Query | `get_part_info`, `get_bounding_box`, `list_faces`, `list_edges` |
+| Edit | `move_face` (прямое редактирование: сдвинуть грань на N мм вдоль нормали) |
+| Inspection | `describe_model`, `list_features`, `list_bodies`, `list_variables`, `describe_face`, `describe_edge`, `measure` |
+| Vision | `model_snapshot` (PNG-снимок; fallback — сначала `describe_model`) |
+| Query | `get_part_info`, `get_bounding_box`, `list_faces`, `list_edges`, `list_components` |
+| Conversion | `import_step`, `export_step` |
+| Validation | `validate_part` |
### Типовой сценарий
`kompas_connect` → `document_create part` → `sketch_create XOY` → `sketch_add_circle` →
-`sketch_close` → `extrude_boss` → `model_snapshot` → (повтор для следующих элементов).
+`sketch_close` → `extrude_boss` → `describe_model` → (повтор для следующих элементов).
+
+> `describe_model` предпочтителен перед `model_snapshot`: отдаёт структурный «паспорт» детали
+> (дерево операций, тела, переменные, топологию, МЦХ) без расхода токенов на изображение.
> ⚠️ Вызовы зависимых инструментов выполняйте **последовательно** (дождавшись ответа):
> сессия построения хранит эскизы по `id`, а сервер обрабатывает запросы конкурентно.
@@ -56,12 +68,13 @@ src/Kompas.Mcp.Host/bin/Release/net8.0-windows/kompas-mcp.exe
## Структура
```
-src/Kompas.Mcp.Core/ COM-слой: STA-диспетчер, подключение, документы, эскизы/операции, снимок
+src/Kompas.Mcp.Core/ COM-слой: STA-диспетчер, подключение, документы, эскизы/операции, конвертация, снимок, инспекция модели
src/Kompas.Mcp.Host/ MCP-сервер (stdio) + определения инструментов
-tests/Kompas.Mcp.Tests/ unit (диспетчер) + integration (требуют КОМПАС)
+tests/Kompas.Mcp.Tests/ 60 тестов: unit + integration (integration требуют КОМПАС)
libs/kompas-interop/ вендорские interop-сборки КОМПАС (из SDK Samples/Common)
docs/ архитектура, план, презентация, навигатор по справке SDK
-.claude/skills/ навыки: docs-delegate, kompas-sdk-research (+ kdoc.py — навигатор справки SDK)
+usecases/ полигон обкатки подходов (в .gitignore); приёмы поднимаются в навык kompas-3d
+.claude/skills/ навыки: docs-delegate, kompas-sdk-research (+ kdoc.py), kompas-3d (методика)
```
## Тесты
@@ -76,7 +89,8 @@ dotnet test --filter "Category=Integration" # только integration
- **STA-поток** (`KompasDispatcher`) владеет всеми COM-вызовами — КОМПАС однопоточный STA.
- Подключение через API5 `KompasObject` (`KOMPAS.Application.5`) → API7 `IApplication` (`ksGetApplication7`).
-- 3D строится через API5 `ksPart` (эскизы, выдавливание); снимок — `ksDocument3D.SaveAsToRasterFormat`.
+- 3D строится через API5 `ksPart` (эскизы, выдавливание, вращение, скругление/фаска); снимок — `ksDocument3D.SaveAsToRasterFormat`. Прямое редактирование импортированной B-rep (`move_face`) — через API7 `IPart7.FindObjectsByPoint` + `FaceMover`. Структурный осмотр (`describe_model` и др.) — через `ModelInspectionService` (дерево операций via `ksPart.GetFeature()`, тела via `BodyCollection()`, переменные via `VariableCollection()`, измерения via `ksMeasurer`).
+- STEP импорт/экспорт — `IKompasDocument3D1.ConvertFromAdditionFormat`/`ConvertToAdditionFormat` через встроенный конвертер.
- MCP — официальный C# SDK `ModelContextProtocol`, транспорт stdio, логи в stderr.
## Лицензирование
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
index ecff77f..d8d2a85 100644
--- a/docs/ARCHITECTURE.md
+++ b/docs/ARCHITECTURE.md
@@ -1,8 +1,7 @@
# Архитектура MCP-сервера КОМПАС-3D (предлагаемый вариант)
-> Статус: **черновик / предлагаемый вариант**, открыт к правкам.
-> Назначение: зафиксировать выбор стека и целевую архитектуру решения до начала
-> реализации. Сопутствующий контекст по COM API КОМПАС — в [`../CLAUDE.md`](../CLAUDE.md).
+> Статус: **реализовано и работает** (v1+v2+STEP/assembly+direct-edit+inspection). Актуализировано по коду.
+> Сопутствующий контекст по COM API КОМПАС — в [`../CLAUDE.md`](../CLAUDE.md).
> Имена интерфейсов и перечислений сверены со справкой SDK через `.claude/skills/kompas-sdk-research/kdoc.py` (навык `kompas-sdk-research`).
---
@@ -108,21 +107,21 @@ MCP client ──stdio──> Host (поток-пул, async)
## 4. Слои решения
-В v1 — логические слои (папки/проекты одного solution `KompasMcp.sln`):
+Проекты solution `KompasMcp.slnx` (спайк-проекты ConnectSpike/ReconSpike удалены; их механика покрыта тестами):
-| Слой | Ответственность |
+| Проект | Ответственность |
|---|---|
-| **Kompas.Mcp.Host** | Точка входа. Сборка MCP-сервера (stdio), DI, логи в stderr, старт и владение STA-потоком, graceful shutdown. |
-| **Kompas.Mcp.Tools** | Определения MCP-инструментов по категориям (System / Documents / Sketch / Features / Query). **Тонкий слой**: валидация аргументов → постановка задачи на STA-поток → форматирование результата/ошибки в MCP-ответ. |
-| **Kompas.Mcp.Core** (`KompasSession`) | COM-слой. Менеджер соединения, менеджер документов, построитель эскизов, построитель операций, помощники выборки граней/плоскостей. Безопасные типизированные методы, null-проверки, трансляция ошибок. Здесь живут все паттерны работы с API5/API7. |
-| **Kompas.Mcp.Interop** | Interop-сборки из `.tlb` + маппинг «дружелюбная строка ↔ перечисление» (`DocumentTypeEnum`, `Obj3dType`, `ksEndTypeEnum`, `ksDirectionTypeEnum`). |
+| **Kompas.Mcp.Host** | Точка входа. Сборка MCP-сервера (stdio), DI (в т.ч. `ConversionService`), логи в stderr, старт и владение STA-потоком, graceful shutdown. Определения инструментов по категориям (System / Documents / Sketch / Features / Query / Conversion). **Тонкий слой**: валидация аргументов → постановка задачи на STA-поток → форматирование результата/ошибки в MCP-ответ. |
+| **Kompas.Mcp.Core** | COM-слой. Менеджер соединения, менеджер документов, построитель эскизов и операций, `ConversionService` (STEP импорт/экспорт), `QueryService` (МЦХ, грани, рёбра, компоненты), `ModelInspectionService` (дерево операций, тела, переменные, drill-down, измерения), снимок. Все паттерны API5/API7 живут здесь. |
+| **Kompas.Mcp.Tests** | Юнит (без COM) + интеграционные (требуют КОМПАС). 60 тестов. |
-Принцип: **только `Core` и `Interop` знают про COM**. `Tools` оперируют доменными
-DTO и вызывают `Core`; `Host` не содержит бизнес-логики.
+Принцип: **только `Core` знает про COM**. `Host`/Tools оперируют доменными DTO и вызывают `Core`; `Host` не содержит бизнес-логики.
+
+Архитектурный принцип: **MCP транслирует возможности SDK КОМПАС в общие инструменты** (не под конкретную задачу). Методический слой поверх MCP — навык `.claude/skills/kompas-3d/` (playbook'и, эвристики). Полигон отработки подходов — `usecases/` (в .gitignore).
---
-## 5. Карта инструментов v1
+## 5. Карта инструментов (43 инструмента)
Сгруппированы вокруг центрального цикла «эскиз ↔ операция». Имена — `snake_case`.
@@ -147,14 +146,37 @@ DTO и вызывают `Core`; `Host` не содержит бизнес-лог
- `revolve_boss` / `revolve_cut` — угол.
- `rebuild` — перестроить деталь.
-**Selection / Query**
-- `select_face_by_point` — выбрать грань точкой (для следующего эскиза).
-- `list_bodies`, `list_faces_planes` — перечислить тела/грани и плоскости.
-- `get_part_info` — МЦХ/габариты (`IMassInertiaParam7`).
+**Edit** (прямое редактирование)
+- `move_face` — сдвинуть грань по мировой точке (x,y,z, мм) на distance мм вдоль нормали; distance>0 — наружу (добавить материал), <0 — внутрь. Работает на импортированной B-rep. Реализовано через API7 `IPart7.FindObjectsByPoint` + `FaceMover`; контейнеры `ISurfaceContainer`/`IModelContainer` получаются COM-QI от `IPart7` в рантайме. Проверено: top_spacer 39.45→41.45 мм.
-**Vision — визуальная обратная связь («зрение агента»)**
+**Selection / Query**
+- `get_part_info` — МЦХ через API5 `ksPart.CalcMassInertiaProperties(ST_MIX_MM|ST_MIX_KG)`.
+- `get_bounding_box` — габарит (`ksPart.GetGabarit`).
+- `list_faces` / `list_edges` — перечислить грани и рёбра детали с классификацией и мерами.
+- `list_components` — перечислить компоненты верхнего уровня сборки (индекс, имя, обозначение, признак детали, габарит) через `TopPart → IParts7`.
+
+**Conversion** (`ConversionTools.cs`, `ConversionService.cs`)
+- `import_step` — импорт .step/.stp в новый документ через встроенный конвертер КОМПАС (код `ksConverterFromSTEP=-3`); параметры `type` (assembly|part), `createComponentFiles`.
+- `export_step` — экспорт активного 3D-документа в STEP; `format` = auto|ap203|ap214|ap242.
+
+**Inspection — структурный осмотр модели (приоритетный над снимком)**
+- `describe_model` — структурный «паспорт» детали одним вызовом: габарит, МЦХ, тела, сводка топологии (грани/рёбра по типам), дерево построения с параметрами, переменные. **Предпочитать перед `model_snapshot`** — не тратит токены изображения.
+- `list_features` — дерево построения с параметрами (глубина/радиус/катеты), имена узлов локализованы КОМПАС.
+- `list_bodies` — тела детали: тип (твёрдое/поверхность) и число граней.
+- `list_variables` — переменные модели (имя/выражение/значение, флаги external/информационная).
+- `describe_face` — drill-down грани по индексу: тип, площадь, нормаль, радиус, число рёбер.
+- `describe_edge` — drill-down ребра по индексу: тип, длина, смежные грани, концевые вершины.
+- `measure` — расстояние и угол между двумя объектами (face|edge|vertex по индексам), единица `ST_MIX_MM`.
+
+Реализовано через `ModelInspectionService` (`src/Kompas.Mcp.Core/Query/ModelInspectionService.cs`),
+рендер текста — `InspectionText` (`InspectionText.cs`, юнит-тестируем без COM).
+Ключевые API-паттерны: `ksPart.GetFeature()` → `ksFeatureCollection` (дерево); `BodyCollection()` → `ksBody`; `VariableCollection()` → `ksVariable`; `GetMeasurer()` → `ksMeasurer`.
+«Импорт STEP без истории» определяется структурно: `bodyCount > 0 && нет формообразующих операций && features.Count <= bodyCount+1`.
+
+**Vision — визуальная обратная связь (fallback)**
- `model_snapshot` — отрендерить активный 3D-документ в PNG и вернуть **как image-контент MCP**,
- чтобы мультимодальный агент *увидел* промежуточный результат и контролировал построение пошагово.
+ чтобы мультимодальный агент *увидел* промежуточный результат. Использовать для визуально-пространственных
+ вопросов, когда структурный осмотр (`describe_model`) недостаточен.
- `set_view` — задать ориентацию вида (`iso` / `front` / `top` / `right` / …), zoom-to-fit и режим
отображения (`ShadedWireframe`) перед снимком — иначе снимок берётся со случайного текущего ракурса.
@@ -282,24 +304,24 @@ dotnet build -c Release -r win-x64 # сборка
---
-## 10. Дорожная карта (после v1)
+## 10. Дорожная карта
-1. Операции: `fillet` / `chamfer` / `shell` / `rib` / `loft` / `sweep`; массивы
- (`ILinearPattern`, `ICircularPattern`).
-2. Параметры и свойства: `IVariable7` / `IVariableTable`, `IPropertyMng` / `IPropertyKeeper`.
-3. Полноценное 2D-черчение: виды, линии/дуги/окружности, размеры (`ILinearDimension`, …),
- штриховки, тексты.
-4. Спецификации (`ISpecification`), сборки и сопряжения (`IAssemblyDocument`).
-5. Конвертеры/экспорт (STEP и др.) через `IApplication.Converter`.
+**Реализовано (v1+v2+STEP/assembly+direct-edit+inspection):** документы, эскизы, выдавливание/вырез, вращение, скругление/фаска, снимок; `get_part_info`, `get_bounding_box`, `list_faces`, `list_edges`; `import_step`, `export_step`, `list_components`; **`move_face`** (прямое редактирование грани, работает на импортированной B-rep); **`describe_model`, `list_features`, `list_bodies`, `list_variables`, `describe_face`, `describe_edge`, `measure`** (структурный осмотр модели).
+
+**Следующие приоритеты:**
+1. Рассечение/перемещение тела как MCP-инструменты (`SplitSolids`/`BodyRepositions`) — механика есть, продуктизация не закончена.
+2. Массивы (`ILinearPattern`, `ICircularPattern`).
+3. Свойства документа: `IPropertyMng` / `IPropertyKeeper`.
+4. Полноценное 2D-черчение: виды, линии/дуги/окружности, размеры (`ILinearDimension`, …), штриховки, тексты.
+5. Спецификации (`ISpecification`), построение сборок и сопряжения.
6. Транспорт **HTTP/SSE** — как опция для удалённых клиентов.
---
## 11. Открытые вопросы
-- **Один проект vs solution из 4 проектов** в v1 (склоняемся к одному solution, слои — папками,
- выделять проекты по мере роста).
-- **Embed Interop Types vs генерируемые interop-сборки** (`tlbimp`) — проверить на реальных
- `.tlb` v24, выбрать по совместимости типов и размеру.
-- **Стратегия именования инструментов** — подтвердить `snake_case` с группами-префиксами
- (`document_*`, `sketch_*`, …).
+- **Прямое редактирование B-rep, перемещение грани**: решено — `move_face` (`FaceEditService`) работает через `IPart7.FindObjectsByPoint` + `FaceMover`; проверено на импортированной B-rep. Рассечение/перемещение тела (`SplitSolids`/`BodyRepositions`) — механика есть, инструменты не реализованы (потенциальная следующая опция).
+- **Дерево операций, тела, переменные, геометрические запросы**: решено — `ModelInspectionService` + `InspectionTools` (7 инструментов); юнит-тестируемый рендер через `InspectionText`.
+- **Утечки транзитных RCW** в `PartModeler` (унаследованный паттерн): `EntityCollection`, `GetTopPart()` не освобождаются, накапливаются за длинную сессию.
+- **Насос сообщений / CancellationToken**: `CancellationToken` не прерывает идущий COM-вызов; зависший модальный диалог КОМПАС блокирует всю очередь.
+- **Embed Interop Types vs вендорские interop-сборки**: выбраны вендорские DLL из SDK `Samples/Common`; менять не планируется.
diff --git a/docs/OPEN_QUESTIONS.md b/docs/OPEN_QUESTIONS.md
index c1fb224..31e2d62 100644
--- a/docs/OPEN_QUESTIONS.md
+++ b/docs/OPEN_QUESTIONS.md
@@ -112,3 +112,32 @@ stateful-сессии? Пока полагаемся на последовате
`SnapshotService` рендерит во временный файл и читает байты обратно (надёжно проверено на v24 Home).
**На проработку:** пустое имя файла + `returnResultAsArrayBytes=true` для чистого in-memory —
не проверено; текущий путь через temp-файл работает.
+
+### ✅ STEP импорт/экспорт и list_components — реализованы
+`import_step`, `export_step` (`ConversionService`, `ConversionTools`), `list_components` (`QueryService.ListComponentsAsync`) добавлены в v2+.
+Проверенные COM-приёмы:
+- Импорт: `IApplication.get_Converter((object)(int)ksConverterFromSTEP=-3)` (код формата, не путь к DLL) → `IConverter.ConverterParameters(cmd)` → `IAdditionConvertParameters.Format=ksConverterFromSTEP` → `IKompasDocument3D1.ConvertFromAdditionFormat(path, prm)`.
+- Экспорт: `ConvertToAdditionFormat` с форматами AP203/AP214/AP242 (`StepFormat` enum в `Core/Conversion/StepFormat.cs`).
+- Param-коклассы (AdditionConvertParameters) — **не** CoCreatable, только через фабрики.
+- Обход сборки: `IKompasDocument3D.TopPart → IPart7.Parts (IParts7)`.
+- Извлечение детали: `prm.NeedCreateComponentsFiles=true` + `IPart7.OpenSourceDocument`.
+
+### ✅ Прямое редактирование импортированной B-rep — move_face реализован
+**Решено.** Перемещение грани продуктизировано как инструмент `move_face` / сервис `FaceEditService` (`src/Kompas.Mcp.Core/Editing/FaceEditService.cs`). Зарегистрирован в DI (`Program.cs`); интеграционный тест — `Integration/FaceEditTests.cs`.
+
+Проверенный паттерн:
+- Объект грани берётся через **`IPart7.FindObjectsByPoint(x, y, z, true)`** → результат приводится к `KompasAPI7.IFace`. Не требует `EntityCollection`/`SelectByPoint` через API5.
+- Контейнеры операций не создаются отдельно: `(ISurfaceContainer)part` и `(IModelContainer)part` — COM-QI от `IPart7` в рантайме.
+- `FaceMover`: `SetFaces(faces)` + `Offset(distance)` + `Direction(true/false = наружу/внутрь)` + `Update()`.
+- Работает как на параметрической геометрии, так и на импортированной B-rep (проверено: деталь top_spacer, высота 39.45 → 41.45 мм).
+
+Полный «рассечь→раздвинуть→объединить» (`SplitSolids`/`BodyRepositions`) — механика есть и драйвится, но отдельными MCP-инструментами не оформлена (возможная будущая опция).
+
+### ✅ Структурный осмотр модели — инспекция реализована
+**Решено.** 7 инструментов (`InspectionTools.cs`, `ModelInspectionService.cs`, `InspectionText.cs`):
+- `describe_model` — структурный «паспорт» детали: габарит, МЦХ, тела, сводка топологии, дерево операций с параметрами, переменные. **Предпочтителен перед `model_snapshot`**.
+- `list_features` / `list_bodies` / `list_variables` — детальные срезы.
+- `describe_face` / `describe_edge` — drill-down по индексу.
+- `measure` — расстояние/угол между объектами (`ksMeasurer`).
+
+Ключевые паттерны: дерево — `ksPart.GetFeature()` → `SubFeatureCollection(true,false)`; тела — `BodyCollection()` → `ksBody`; переменные — `VariableCollection()` → `ksVariable`. Детект «импорт без истории»: `bodyCount>0 && нет формообразующих операций && features.Count<=bodyCount+1`. Итог: **43 инструмента, 60 тестов.**
diff --git a/docs/presentation.html b/docs/presentation.html
index 9d51ab9..7df81cd 100644
--- a/docs/presentation.html
+++ b/docs/presentation.html
@@ -125,7 +125,7 @@
- Статус: v2 работает — цикл эскиз→операции→снимок через MCP (31 инструмент)
+ Статус: v3 работает — эскиз→операции→STEP→сборка→move_face→структурный осмотр (43 инструмента)
КОМПАС-3D MCP-сервер управление CAD языком LLM
MCP-сервер, который превращает операции КОМПАС-3D — создание документов,
эскизы, 3D-операции, параметры — в инструменты для языковой модели. Под капотом —
@@ -173,24 +173,36 @@
Выдавливание и вырез, вращение, перестроение. Управление направлением, глубиной и
типом окончания (ksEndTypeEnum).
+
+
🔍
+
Структурный осмотр
+
describe_model — паспорт детали (МЦХ, тела, дерево, переменные) одним вызовом.
+ describe_face · describe_edge · measure.
+ Предпочтительнее снимка — без расхода токенов изображения.
+
🎯
Выборка и запросы
-
Выбор грани точкой для следующего эскиза, перечисление тел и граней,
- массово-центровочные характеристики детали.
+
Перечисление граней, рёбер и компонентов сборки с классификацией; МЦХ, габарит.
+ list_faces · list_edges · list_components.
+
+
+
📦
+
STEP импорт / экспорт
+
Импорт .step/.stp в новый документ (деталь или сборка, создание файлов компонентов);
+ экспорт в AP203/AP214/AP242 через встроенный конвертер КОМПАС.
+
+
+
✂️
+
Прямое редактирование
+
move_face: сдвинуть грань на N мм вдоль нормали (наружу или внутрь).
+ Работает на импортированной B-rep через FaceMover API7.
👁️
Зрение агента
-
Рендер модели в PNG прямо в память (resultArrayBytes) и возврат как
- image-контент MCP — агент видит результат и строит пошагово. Плюс set_view:
- ориентация и zoom-to-fit перед снимком.
-
-
-
🛟
-
Escape-hatch
-
Прямой вызов команд КОМПАС через ExecuteKompasCommand для того,
- что ещё не обёрнуто в типизированные инструменты.
+
Рендер модели в PNG через временный файл и возврат как image-контент MCP — агент видит
+ результат. Fallback после describe_model для визуально-пространственных вопросов.
@@ -246,8 +258,8 @@
впереди.
-
Общий прогрессv2: грань · вращение · скругление/фаска · габариты · список граней/рёбер · 19 тестов