chore: initial skeleton + KOMPAS connection spike (S1/S2)

Зафиксирован фундамент проекта MCP-сервера КОМПАС-3D:

- docs/: ARCHITECTURE.md, IMPLEMENTATION_PLAN.md, presentation.html
- tools/kdoc.py: навигатор по справке SDK
- libs/kompas-interop/: вендорские interop-сборки КОМПАС из SDK
- src/Kompas.Mcp.ConnectSpike: net8.0-windows консоль, доказывает
  работу COM-интеропа и attach/launch подключения к КОМПАС
  (IApplication, версия 24.0)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-25 23:28:29 +03:00
commit 3a98afc67f
17 changed files with 1297 additions and 0 deletions
+115
View File
@@ -0,0 +1,115 @@
# План реализации MCP-сервера КОМПАС-3D
> Документ описывает, **как** строить сервер. Что строим и почему — в
> [`ARCHITECTURE.md`](ARCHITECTURE.md). Прогресс отражается в
> [`presentation.html`](presentation.html) (TODO).
## Принцип
**«Ходячий скелет» + спайки на риски.** Сначала сквозной тонкий срез
(подключение → снимок), который проходит через все слои и доказывает, что связка
COM ↔ STA ↔ MCP работает. Затем наращиваем инструменты, и **каждый шаг построения сразу
проверяем визуально** (`model_snapshot`) — это и есть целевой UX «строю под контролем».
## Окружение (проверено 2026-05-25)
| | Факт | Следствие для плана |
|---|---|---|
| .NET SDK | **10.0.108** (отдельного .NET 8 SDK нет; рантайм 8 есть) | таргет **`net8.0-windows`** (LTS), собирается SDK 10 |
| ProgID КОМПАС | **`KOMPAS.Application.7`** и **`KOMPAS.Application.5`** зарегистрированы; `KOMPASLT.*` **отсутствует** | подключаться напрямую к API7 через `KOMPAS.Application.7`; LT — только запасной |
| Процесс | КОМПАС не запущен | спайк подключения должен уметь **launch**, не только attach |
| SDK | `C:\Program Files\ASCON\KOMPAS-3D v24 Home\SDK` (`lib\*.tlb`) | источник interop |
**Прерэквизит разработчика:** установленный КОМПАС v24 + возможность его запускать.
---
## Спайки (делать первыми — снимают главные неизвестные)
| # | Риск / вопрос | Критерий успеха |
|---|---|---|
| **S1** | Генерация COM-interop из `.tlb` в SDK-проекте | `net8.0-windows` проект с `<COMReference>` на `kAPI7.tlb`, `kAPI5.tlb`, `ksConstants.tlb`, `ksConstants3D.tlb` собирается; типы `IApplication`, `KompasObject` доступны. Запасной путь — `tlbimp`/ручные interop-сборки |
| **S2** | Подключение по ProgID | консольная проба: attach (`Marshal.GetActiveObject`) → при отказе launch (`Activator.CreateInstance(Type.GetTypeFromProgID("KOMPAS.Application.7"))`); получить `IApplication`, `Visible=true`, прочитать версию |
| **S3** | STA-поток + насос сообщений + async MCP | выделенный STA-поток выполняет COM-вызовы из пула задач без `RPC_E_WRONGTHREAD`; насос сообщений не вешает процесс |
| **S4** | Рендер модели в растр на v24 Home | `ksDocument3D.RasterFormatParam()``resultArrayBytes` отдаёт корректные PNG-байты открытого 3D-документа |
Спайки — выбрасываемый код в `spikes/`; выводы переносятся в `Core`.
---
## Фазы
### Фаза 0 — Каркас репозитория
- `git init`, `.gitignore` (.NET + `bin/`, `obj/`; **не** игнорировать `docs/`).
- `KompasMcp.sln`; проекты `Kompas.Mcp.Host`, `Kompas.Mcp.Core`, `Kompas.Mcp.Interop`, `Kompas.Mcp.Tools`
(в v1 допустимо начать одним проектом, разнося по папкам).
- `Directory.Build.props`: `TargetFramework=net8.0-windows`, `Platforms=x64`, `Nullable=enable`, `LangVersion=latest`.
- Пакеты: `ModelContextProtocol`, `Microsoft.Extensions.Hosting`.
- **Готово:** `dotnet build -c Release` проходит; пустой stdio-хост стартует.
### Фаза 1 — Interop + маппинг констант
- `<COMReference>` на типобиблиотеки (итог S1). Зафиксировать стратегию (embed vs сборки).
- `Kompas.Mcp.Interop`: хелперы «строка ↔ enum» — `DocumentTypeEnum` (part=4, assembly=5, drawing=1, fragment=2),
`Obj3dType`, `ksEndTypeEnum`, `ksDirectionTypeEnum`, базовые плоскости (`o3d_planeXOY/XOZ/YOZ`).
- **Готово:** unit-тесты маппинга (без COM) зелёные.
### Фаза 2 — STA-диспетчер
- `KompasThread`: выделенный STA-поток, очередь задач (`Channel`/`BlockingCollection`),
`Task<T> InvokeAsync(Func<T>)`, насос сообщений + периодический `PumpWaitingMessages` (итог S3).
- **Готово:** интеграционный тест — параллельные `InvokeAsync` исполняются строго на одном STA-потоке.
### Фаза 3 — Connection + вертикальный срез (MCP)
- `KompasSession`: resolve ProgID (`KOMPAS.Application.7``.5`+`ksGetApplication7()``KOMPASLT.*`),
attach/launch, `Visible`, версия/редакция, освобождение COM, `Quit` только если запускали мы.
- Хост: stdio-сервер, **логи в stderr**, регистрация инструментов через DI.
- Инструменты `System`: `kompas_connect`, `kompas_status`, `kompas_set_visible`.
- **Готово (веха «скелет»):** из MCP Inspector вызвать `kompas_connect` → КОМПАС стартует и виден; `kompas_status` отвечает.
### Фаза 4 — Documents
- `document_create` (part/assembly/drawing/fragment), `document_open`, `document_save`, `document_close`, `document_active`.
- **Готово:** создать деталь, сохранить `.m3d`, закрыть, открыть заново.
### Фаза 5 — Vision (раннее — делает всё дальнейшее проверяемым)
- `set_view` (ориентация iso/front/top/right, zoom-to-fit, `ShadedWireframe`), `model_snapshot`
(`RasterFormatParam.resultArrayBytes` → image-контент MCP) — итог S4.
- **Готово:** `model_snapshot` возвращает PNG открытой детали; агент видит изображение в ответе инструмента.
### Фаза 6 — Sketch
- `sketch_create` (плоскость или грань), `sketch_add_line|circle|arc|rectangle`, `sketch_close`
(`NewEntity(o3d_sketch)``SetPlane``BeginEdit`/примитивы/`EndEdit`, гарантированный `EndEdit` в `finally`).
- **Готово:** построить эскиз-окружность на XOY и увидеть его на снимке.
### Фаза 7 — Features
- `extrude_boss`/`extrude_cut` (depth, direction, endType), `revolve_boss`/`revolve_cut`, `rebuild`.
- **Готово (целевой демо-сценарий):** окружность → `extrude_boss` (цилиндр) → `model_snapshot`
выбрать грань → эскиз → `extrude_cut` (отверстие) → `model_snapshot`. Полный цикл со зрением.
### Фаза 8 — Query / Selection
- `select_face_by_point`, `list_bodies`, `list_faces_planes`, `get_part_info` (МЦХ/габариты).
- **Готово:** агент может выбрать грань для следующего эскиза по координатам.
### Фаза 9 — Качество и поставка
- Unit-тесты (маппинг, валидация, форматирование); интеграционные (`[Trait("Category","Integration")]`, гейтятся).
- Трансляция ошибок COM (`ksGetLastError`/`IApplication.KompasError`) в структурированные MCP-ошибки.
- Сборка `kompas-mcp.exe` (`dotnet publish -c Release -r win-x64`), регистрация stdio-сервера в конфиге клиента.
- Escape-hatch `run_kompas_command` (опц.).
---
## Порядок и зависимости
```
S1,S2 ─► Фаза 0 ─► Фаза 1 ─► Фаза 2 ─► Фаза 3 (скелет) ─► Фаза 4 ─► Фаза 5 (зрение)
Фаза 6 ─► Фаза 7 ─► Фаза 8 ─► Фаза 9
S3 ─► Фаза 2 S4 ─► Фаза 5
```
Критический риск — **S1/S3** (interop + STA). Если `<COMReference>` не заработает на v24 `.tlb`
переход на сгенерированные `tlbimp` interop-сборки. Все спайки до Фазы 3.
## Definition of Done для v1
Агент через MCP: подключается к КОМПАС → создаёт деталь → строит эскиз → выдавливает →
делает снимок → видит результат → выбирает грань → повторяет → сохраняет `.m3d`.
Сервер собирается в один `.exe` и регистрируется в клиенте по stdio.