diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json new file mode 100644 index 0000000..4921b1a --- /dev/null +++ b/.claude-plugin/marketplace.json @@ -0,0 +1,19 @@ +{ + "name": "kompas-plugin", + "owner": { + "name": "Shahovalov Mikhail", + "email": "miha.shahovalov@gmail.com" + }, + "metadata": { + "description": "КОМПАС-3D в Claude Code: MCP-сервер для деталей, сборок, чертежей и STEP плюс методика работы с ними." + }, + "plugins": [ + { + "name": "kompas", + "source": "./plugin", + "description": "Управление КОМПАС-3D из Claude Code: 85 MCP-инструментов (детали, эскизы, формообразующие операции, массивы, отверстия, сборки и сопряжения, 2D-чертежи, STEP/STL, осмотр модели) и два навыка — построение (kompas-3d) и проектирование под FDM-печать (kompas-fdm-design).", + "category": "productivity", + "keywords": ["cad", "kompas", "3d", "step", "mcp", "fdm"] + } + ] +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..df32316 --- /dev/null +++ b/LICENSE @@ -0,0 +1,30 @@ +MIT License + +Copyright (c) 2026 Shahovalov Mikhail + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--- + +Лицензия распространяется на содержимое этого репозитория: MCP-сервер `kompas-mcp`, +навыки, команды и скрипты плагина. + +Она НЕ распространяется на interop-сборки КОМПАС-3D (`KompasAPI7.dll`, `Kompas6API5.dll`, +`Kompas6Constants.dll`, `Kompas6Constants3D.dll`) — они принадлежат АО «АСКОН» и в поставку +плагина не входят: сервер берёт их из установленного на машине КОМПАС-3D. diff --git a/README.md b/README.md index 074447c..bce900a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,65 @@ # КОМПАС-3D в Claude Code -Репозиторий поставки плагина `kompas`. Содержимое появляется с первым релизом — -его публикует workflow из репозитория с исходниками. +Каталог плагинов с одним плагином — **`kompas`**. Он даёт Claude Code управление +[КОМПАС-3D](https://ascon.ru/products/7/) (АСКОН) через MCP-сервер: детали, эскизы, +формообразующие операции, массивы и зеркало, отверстия, сборки с сопряжениями, 2D-чертежи, +STEP/STL, осмотр и измерение модели — плюс два навыка с методикой построения. + +Это репозиторий поставки: здесь лежит собранный сервер и материалы плагина. Исходники сервера +не публикуются. + +## Что нужно до установки + +- **Windows x64** — сервер является COM-клиентом КОМПАС и работает только на той же машине; +- **установленный КОМПАС-3D** (проверено на v24 Home) **с компонентом SDK**. Interop-сборки + принадлежат АСКОН, в поставку не входят и берутся из установки + (`SDK\Samples\CSharp.zip`, каталог `Common`); при первом запуске они распаковываются + в `%LOCALAPPDATA%\kompas-mcp\interop\<ключ>`. Если SDK не установлен, укажите каталог + с этими сборками в переменной окружения `KOMPAS_INTEROP_DIR`; +- **[.NET Runtime](https://dotnet.microsoft.com/download/dotnet) 8 или новее, x64** — сервер + поставляется framework-dependent (2,3 МБ вместо 34), поэтому рантайм берётся с машины. + Проверить: `dotnet --list-runtimes` должен показать `Microsoft.NETCore.App 8.x` или новее; +- чекаут и рабочие файлы — вне синхронизируемых папок OneDrive. + +Запускать КОМПАС заранее не нужно: сервер присоединится к открытому окну, а если его нет — +запустит экземпляр сам. + +## Установка + +``` +/plugin marketplace add https://git.shahovalov.ru/mikhail/kompas-plugin.git +/plugin install kompas@kompas-plugin +/kompas:doctor +``` + +`/kompas:doctor` — диагностика: версия сервера, установлен ли КОМПАС, на месте ли interop-сборки, +проходит ли соединение. С неё стоит начинать разбор любой неполадки. + +## Обновление + +``` +/plugin marketplace update kompas-plugin +/plugin update kompas@kompas-plugin +``` + +Если после обновления инструменты остались прежними — `/reload-plugins`. + +## Что внутри + +| | | +|---|---| +| **MCP-сервер `kompas`** | 85 инструментов: документы, эскизы, выдавливание/вращение/по сечениям/по траектории, оболочка, рёбра, уклон, скругления и фаски, массивы и зеркало, отверстия, булевы операции, прямое редактирование B-rep, переменные и параметризация, сборки и сопряжения, 2D-чертежи (виды, размеры, обозначения, тех. требования), STEP/STL, осмотр (`describe_model`, `list_faces`, `list_edges`, `measure`) | +| **Навык `kompas-3d`** | методика построения: порядок работы, выбор подхода, проверенные приёмы и ловушки | +| **Навык `kompas-fdm-design`** | проектирование под FDM/FFF-печать: нависания, толщины стенок, зазоры и посадки, ориентация, бобышки и защёлки | +| **Команда `/kompas:doctor`** | диагностика установки | +| **Справка `help`** | инструмент `help(topic=…)` — статьи по механике и ловушкам, прямо в сессии | + +## Другие агентские харнессы + +Тот же сервер подключается к Codex и opencode — сниппеты конфигурации лежат в +`plugin/adapters/{codex,opencode}/`. + +## Лицензия + +MIT — см. [LICENSE](LICENSE). На interop-сборки КОМПАС-3D (© АО «АСКОН») лицензия не +распространяется: они в поставку не входят. diff --git a/plugin/.claude-plugin/plugin.json b/plugin/.claude-plugin/plugin.json new file mode 100644 index 0000000..5d90d1c --- /dev/null +++ b/plugin/.claude-plugin/plugin.json @@ -0,0 +1,19 @@ +{ + "name": "kompas", + "displayName": "КОМПАС-3D", + "version": "0.1.0", + "description": "Управление КОМПАС-3D из Claude Code: детали, сборки, чертежи, STEP — через MCP-сервер", + "author": { + "name": "Shahovalov Mikhail", + "email": "miha.shahovalov@gmail.com" + }, + "homepage": "https://git.shahovalov.ru/mikhail/kompas3d-mcp", + "repository": "https://git.shahovalov.ru/mikhail/kompas3d-mcp", + "keywords": [ + "cad", + "kompas", + "3d", + "step", + "mcp" + ] +} diff --git a/plugin/.mcp.json b/plugin/.mcp.json new file mode 100644 index 0000000..12b0e37 --- /dev/null +++ b/plugin/.mcp.json @@ -0,0 +1,9 @@ +{ + "mcpServers": { + "kompas": { + "command": "powershell", + "args": ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", + "-File", "${CLAUDE_PLUGIN_ROOT}/scripts/launch-kompas-mcp.ps1"] + } + } +} diff --git a/plugin/README.md b/plugin/README.md new file mode 100644 index 0000000..4f17192 --- /dev/null +++ b/plugin/README.md @@ -0,0 +1,60 @@ +# Плагин `kompas` — КОМПАС-3D в Claude Code + +Даёт Claude Code инструменты управления КОМПАС-3D (детали, сборки, чертежи, STEP) и методику работы +с ними: навыки `kompas:kompas-3d` и `kompas:kompas-fdm-design`. + +## Предпосылки + +- Windows x64; +- установленный КОМПАС-3D (проверено на v24 Home) — сервер является COM-клиентом, а не автономным + CAD-движком, и работает только на той же машине. Запускать заранее не нужно: сервер присоединится + к открытому окну, а если его нет — запустит экземпляр сам; +- КОМПАС установлен **вместе с компонентом SDK**: interop-сборки принадлежат АСКОН, в поставку + сервера не входят и берутся из установки (`SDK\Samples\CSharp.zip`, каталог `Common`). При первом + запуске они распаковываются в `%LOCALAPPDATA%\kompas-mcp\interop\<ключ>`; если SDK не установлен, + укажите каталог с этими сборками в переменной окружения `KOMPAS_INTEROP_DIR`; +- [**.NET Runtime**](https://dotnet.microsoft.com/download/dotnet) **8 или новее, x64** — сервер + поставляется framework-dependent, рантайм берётся с машины. Проверка: `dotnet --list-runtimes` + показывает `Microsoft.NETCore.App 8.x` или новее; +- чекаут репозитория и рабочие файлы — вне синхронизируемых папок OneDrive. + +## Установка + +``` +/plugin marketplace add https://git.shahovalov.ru/mikhail/kompas-plugin.git +/plugin install kompas@kompas-plugin +/kompas:doctor +``` + +Сервер (`bin/kompas-mcp.exe`) едет вместе с плагином — отдельно скачивать и устанавливать нечего. +`/kompas:doctor` проверяет версию, наличие .NET и КОМПАС, interop-сборки и соединение. + +## Обновление + +``` +/plugin marketplace update kompas-plugin +/plugin update kompas@kompas-plugin +``` + +Если инструменты остались прежними — `/reload-plugins`. + +## Разработка сервера + +Переменная окружения `KOMPAS_MCP_EXE` подменяет поставленный бинарь своим: + +```powershell +$env:KOMPAS_MCP_EXE = "<путь>\kompas-mcp.exe" +``` + +Тогда лаунчер `scripts/launch-kompas-mcp.ps1` не смотрит в `bin/` плагина. + +## Другие харнессы (Codex, opencode) + +Тот же лаунчер подключается и к другим агентским харнессам — см. `adapters/codex/` и +`adapters/opencode/`. Это сниппеты конфигурации и инструкция, а не отдельные дистрибутивы: +контент (навыки, лаунчер) не размножается, новый харнесс стоит README + сниппета. + +## Прочее + +Каталог `%LOCALAPPDATA%\kompas-mcp` (распакованные interop-сборки, при разработке — временные +файлы) не очищается при обновлении и удалении плагина — удаляется вручную. diff --git a/plugin/adapters/codex/README.md b/plugin/adapters/codex/README.md new file mode 100644 index 0000000..b32f8b3 --- /dev/null +++ b/plugin/adapters/codex/README.md @@ -0,0 +1,20 @@ +# Подключение к Codex + +Codex не знает ни маркетплейсов, ни `${CLAUDE_PLUGIN_ROOT}`, поэтому подключение делается по пути +к каталогу плагина. + +1. Склонировать `https://git.shahovalov.ru/mikhail/kompas-plugin.git` — сервер лежит внутри, + в `plugin/bin/`, собирать ничего не нужно (требуется .NET Runtime 8+ x64). +2. Вставить `config.snippet.toml` в `~/.codex/config.toml`, заменив `` на абсолютный путь + к каталогу `plugin/` клона. Лаунчер `scripts/launch-kompas-mcp.ps1` — тот же, что у плагина + Claude Code. +3. Навыки: скопировать `plugin/skills/{kompas-3d,kompas-fdm-design}` в каталог навыков своего + агента (для Codex это `.agents/skills/`). + +Формат сниппета (`[mcp_servers.<имя>]` с ключами `command`/`args`) проверен вживую — +`codex mcp add kompas -- powershell ...` генерирует именно такую секцию (Codex CLI 0.145.0). + +Свой собранный сервер подставляется переменной окружения `KOMPAS_MCP_EXE` — она перекрывает +`plugin/bin/kompas-mcp.exe`. + +Это сниппет и инструкция, а не дистрибутив: полноценный плагин Codex — отдельная веха. diff --git a/plugin/adapters/codex/config.snippet.toml b/plugin/adapters/codex/config.snippet.toml new file mode 100644 index 0000000..69169fe --- /dev/null +++ b/plugin/adapters/codex/config.snippet.toml @@ -0,0 +1,5 @@ +# Вставить в ~/.codex/config.toml. — путь к каталогу plugin/ этого репозитория. +[mcp_servers.kompas] +command = "powershell" +args = ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", + "-File", "/scripts/launch-kompas-mcp.ps1"] diff --git a/plugin/adapters/opencode/README.md b/plugin/adapters/opencode/README.md new file mode 100644 index 0000000..f2e50da --- /dev/null +++ b/plugin/adapters/opencode/README.md @@ -0,0 +1,17 @@ +# Подключение к opencode + +1. Склонировать `https://git.shahovalov.ru/mikhail/kompas-plugin.git` — сервер лежит внутри, + в `plugin/bin/` (требуется .NET Runtime 8+ x64). +2. Слить `opencode.json` со своим конфигом opencode, заменив `` на абсолютный путь к + каталогу `plugin/` клона. Используется тот же лаунчер `scripts/launch-kompas-mcp.ps1`. +3. Навыки: скопировать `plugin/skills/{kompas-3d,kompas-fdm-design}` в каталог навыков агента + (`.agents/skills/`). + +Формат `opencode.json` — под MCP-сервер типа `local` команда со всеми аргументами лежит одним +массивом строк в поле `command` (сверено со схемой `https://opencode.ai/config.json`, +`$defs.McpLocalConfig`), отдельного поля `args` в этой схеме нет. + +Свой собранный сервер подставляется переменной окружения `KOMPAS_MCP_EXE` — она перекрывает +`plugin/bin/kompas-mcp.exe`. + +Это сниппет и инструкция, а не дистрибутив. diff --git a/plugin/adapters/opencode/opencode.json b/plugin/adapters/opencode/opencode.json new file mode 100644 index 0000000..a581cb4 --- /dev/null +++ b/plugin/adapters/opencode/opencode.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "kompas": { + "type": "local", + "command": ["powershell", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", + "-File", "/scripts/launch-kompas-mcp.ps1"], + "enabled": true + } + } +} diff --git a/plugin/bin/Kompas.Mcp.Core.dll b/plugin/bin/Kompas.Mcp.Core.dll new file mode 100644 index 0000000..f7703b5 Binary files /dev/null and b/plugin/bin/Kompas.Mcp.Core.dll differ diff --git a/plugin/bin/Kompas.Mcp.Core.pdb b/plugin/bin/Kompas.Mcp.Core.pdb new file mode 100644 index 0000000..d608c40 Binary files /dev/null and b/plugin/bin/Kompas.Mcp.Core.pdb differ diff --git a/plugin/bin/Microsoft.Extensions.AI.Abstractions.dll b/plugin/bin/Microsoft.Extensions.AI.Abstractions.dll new file mode 100755 index 0000000..16ce049 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.AI.Abstractions.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Caching.Abstractions.dll b/plugin/bin/Microsoft.Extensions.Caching.Abstractions.dll new file mode 100755 index 0000000..dbd79c6 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Caching.Abstractions.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Configuration.Abstractions.dll b/plugin/bin/Microsoft.Extensions.Configuration.Abstractions.dll new file mode 100755 index 0000000..c68a7c8 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Configuration.Abstractions.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Configuration.Binder.dll b/plugin/bin/Microsoft.Extensions.Configuration.Binder.dll new file mode 100755 index 0000000..557d6d9 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Configuration.Binder.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Configuration.CommandLine.dll b/plugin/bin/Microsoft.Extensions.Configuration.CommandLine.dll new file mode 100755 index 0000000..2aa287c Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Configuration.CommandLine.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Configuration.EnvironmentVariables.dll b/plugin/bin/Microsoft.Extensions.Configuration.EnvironmentVariables.dll new file mode 100755 index 0000000..09657dd Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Configuration.EnvironmentVariables.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Configuration.FileExtensions.dll b/plugin/bin/Microsoft.Extensions.Configuration.FileExtensions.dll new file mode 100755 index 0000000..19d8f5c Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Configuration.FileExtensions.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Configuration.Json.dll b/plugin/bin/Microsoft.Extensions.Configuration.Json.dll new file mode 100755 index 0000000..9e50db0 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Configuration.Json.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Configuration.UserSecrets.dll b/plugin/bin/Microsoft.Extensions.Configuration.UserSecrets.dll new file mode 100755 index 0000000..66ff0e8 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Configuration.UserSecrets.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Configuration.dll b/plugin/bin/Microsoft.Extensions.Configuration.dll new file mode 100755 index 0000000..d3e5c22 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Configuration.dll differ diff --git a/plugin/bin/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/plugin/bin/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100755 index 0000000..6c1251e Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/plugin/bin/Microsoft.Extensions.DependencyInjection.dll b/plugin/bin/Microsoft.Extensions.DependencyInjection.dll new file mode 100755 index 0000000..bd71a2b Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Diagnostics.Abstractions.dll b/plugin/bin/Microsoft.Extensions.Diagnostics.Abstractions.dll new file mode 100755 index 0000000..49b1920 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Diagnostics.Abstractions.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Diagnostics.dll b/plugin/bin/Microsoft.Extensions.Diagnostics.dll new file mode 100755 index 0000000..a425b2b Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Diagnostics.dll differ diff --git a/plugin/bin/Microsoft.Extensions.FileProviders.Abstractions.dll b/plugin/bin/Microsoft.Extensions.FileProviders.Abstractions.dll new file mode 100755 index 0000000..93ea32f Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.FileProviders.Abstractions.dll differ diff --git a/plugin/bin/Microsoft.Extensions.FileProviders.Physical.dll b/plugin/bin/Microsoft.Extensions.FileProviders.Physical.dll new file mode 100755 index 0000000..6fb7f47 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.FileProviders.Physical.dll differ diff --git a/plugin/bin/Microsoft.Extensions.FileSystemGlobbing.dll b/plugin/bin/Microsoft.Extensions.FileSystemGlobbing.dll new file mode 100755 index 0000000..e590735 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.FileSystemGlobbing.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Hosting.Abstractions.dll b/plugin/bin/Microsoft.Extensions.Hosting.Abstractions.dll new file mode 100755 index 0000000..3a32588 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Hosting.Abstractions.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Hosting.dll b/plugin/bin/Microsoft.Extensions.Hosting.dll new file mode 100755 index 0000000..7935736 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Hosting.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Logging.Abstractions.dll b/plugin/bin/Microsoft.Extensions.Logging.Abstractions.dll new file mode 100755 index 0000000..1c9bc3d Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Logging.Abstractions.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Logging.Configuration.dll b/plugin/bin/Microsoft.Extensions.Logging.Configuration.dll new file mode 100755 index 0000000..7a759d7 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Logging.Configuration.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Logging.Console.dll b/plugin/bin/Microsoft.Extensions.Logging.Console.dll new file mode 100755 index 0000000..524378b Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Logging.Console.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Logging.Debug.dll b/plugin/bin/Microsoft.Extensions.Logging.Debug.dll new file mode 100755 index 0000000..9928863 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Logging.Debug.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Logging.EventLog.dll b/plugin/bin/Microsoft.Extensions.Logging.EventLog.dll new file mode 100755 index 0000000..1751950 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Logging.EventLog.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Logging.EventSource.dll b/plugin/bin/Microsoft.Extensions.Logging.EventSource.dll new file mode 100755 index 0000000..f97190c Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Logging.EventSource.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Logging.dll b/plugin/bin/Microsoft.Extensions.Logging.dll new file mode 100755 index 0000000..35905b6 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Logging.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Options.ConfigurationExtensions.dll b/plugin/bin/Microsoft.Extensions.Options.ConfigurationExtensions.dll new file mode 100755 index 0000000..cbb29a1 Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Options.ConfigurationExtensions.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Options.dll b/plugin/bin/Microsoft.Extensions.Options.dll new file mode 100755 index 0000000..80cdeba Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Options.dll differ diff --git a/plugin/bin/Microsoft.Extensions.Primitives.dll b/plugin/bin/Microsoft.Extensions.Primitives.dll new file mode 100755 index 0000000..469523a Binary files /dev/null and b/plugin/bin/Microsoft.Extensions.Primitives.dll differ diff --git a/plugin/bin/ModelContextProtocol.Core.dll b/plugin/bin/ModelContextProtocol.Core.dll new file mode 100755 index 0000000..4da3793 Binary files /dev/null and b/plugin/bin/ModelContextProtocol.Core.dll differ diff --git a/plugin/bin/ModelContextProtocol.dll b/plugin/bin/ModelContextProtocol.dll new file mode 100755 index 0000000..e2c9639 Binary files /dev/null and b/plugin/bin/ModelContextProtocol.dll differ diff --git a/plugin/bin/System.Diagnostics.DiagnosticSource.dll b/plugin/bin/System.Diagnostics.DiagnosticSource.dll new file mode 100755 index 0000000..a168f6b Binary files /dev/null and b/plugin/bin/System.Diagnostics.DiagnosticSource.dll differ diff --git a/plugin/bin/System.Diagnostics.EventLog.Messages.dll b/plugin/bin/System.Diagnostics.EventLog.Messages.dll new file mode 100755 index 0000000..414fd1f Binary files /dev/null and b/plugin/bin/System.Diagnostics.EventLog.Messages.dll differ diff --git a/plugin/bin/System.Diagnostics.EventLog.dll b/plugin/bin/System.Diagnostics.EventLog.dll new file mode 100755 index 0000000..6281e73 Binary files /dev/null and b/plugin/bin/System.Diagnostics.EventLog.dll differ diff --git a/plugin/bin/System.IO.Pipelines.dll b/plugin/bin/System.IO.Pipelines.dll new file mode 100755 index 0000000..cdeaa77 Binary files /dev/null and b/plugin/bin/System.IO.Pipelines.dll differ diff --git a/plugin/bin/System.Net.ServerSentEvents.dll b/plugin/bin/System.Net.ServerSentEvents.dll new file mode 100755 index 0000000..7b5bb8b Binary files /dev/null and b/plugin/bin/System.Net.ServerSentEvents.dll differ diff --git a/plugin/bin/System.Text.Encodings.Web.dll b/plugin/bin/System.Text.Encodings.Web.dll new file mode 100755 index 0000000..a768717 Binary files /dev/null and b/plugin/bin/System.Text.Encodings.Web.dll differ diff --git a/plugin/bin/System.Text.Json.dll b/plugin/bin/System.Text.Json.dll new file mode 100755 index 0000000..955a959 Binary files /dev/null and b/plugin/bin/System.Text.Json.dll differ diff --git a/plugin/bin/kompas-mcp.deps.json b/plugin/bin/kompas-mcp.deps.json new file mode 100644 index 0000000..ac27e5d --- /dev/null +++ b/plugin/bin/kompas-mcp.deps.json @@ -0,0 +1,770 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v8.0/win-x64", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v8.0": {}, + ".NETCoreApp,Version=v8.0/win-x64": { + "kompas-mcp/0.1.0": { + "dependencies": { + "Kompas.Mcp.Core": "0.1.0", + "Microsoft.Extensions.Hosting": "8.0.1", + "ModelContextProtocol": "2.0.0" + }, + "runtime": { + "kompas-mcp.dll": {} + } + }, + "Microsoft.Extensions.AI.Abstractions/10.8.3": { + "dependencies": { + "System.Text.Json": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.AI.Abstractions.dll": { + "assemblyVersion": "10.8.0.0", + "fileVersion": "10.800.326.37702" + } + } + }, + "Microsoft.Extensions.Caching.Abstractions/10.0.10": { + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Caching.Abstractions.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.1026.32716" + } + } + }, + "Microsoft.Extensions.Configuration/8.0.0": { + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.10", + "Microsoft.Extensions.Primitives": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Configuration.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.23.53103" + } + } + }, + "Microsoft.Extensions.Configuration.Abstractions/10.0.10": { + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Configuration.Abstractions.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.1026.32716" + } + } + }, + "Microsoft.Extensions.Configuration.Binder/8.0.2": { + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.724.31311" + } + } + }, + "Microsoft.Extensions.Configuration.CommandLine/8.0.0": { + "dependencies": { + "Microsoft.Extensions.Configuration": "8.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Configuration.CommandLine.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.23.53103" + } + } + }, + "Microsoft.Extensions.Configuration.EnvironmentVariables/8.0.0": { + "dependencies": { + "Microsoft.Extensions.Configuration": "8.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Configuration.EnvironmentVariables.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.23.53103" + } + } + }, + "Microsoft.Extensions.Configuration.FileExtensions/8.0.1": { + "dependencies": { + "Microsoft.Extensions.Configuration": "8.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.10", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.10", + "Microsoft.Extensions.FileProviders.Physical": "8.0.0", + "Microsoft.Extensions.Primitives": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Configuration.FileExtensions.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.724.31311" + } + } + }, + "Microsoft.Extensions.Configuration.Json/8.0.1": { + "dependencies": { + "Microsoft.Extensions.Configuration": "8.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.10", + "Microsoft.Extensions.Configuration.FileExtensions": "8.0.1", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Configuration.Json.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1024.46610" + } + } + }, + "Microsoft.Extensions.Configuration.UserSecrets/8.0.1": { + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.10", + "Microsoft.Extensions.Configuration.Json": "8.0.1", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.10", + "Microsoft.Extensions.FileProviders.Physical": "8.0.0" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Configuration.UserSecrets.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1024.46610" + } + } + }, + "Microsoft.Extensions.DependencyInjection/8.0.1": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1024.46610" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/10.0.10": { + "runtime": { + "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.1026.32716" + } + } + }, + "Microsoft.Extensions.Diagnostics/8.0.1": { + "dependencies": { + "Microsoft.Extensions.Configuration": "8.0.0", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.10", + "Microsoft.Extensions.Options.ConfigurationExtensions": "8.0.0" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Diagnostics.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1024.46610" + } + } + }, + "Microsoft.Extensions.Diagnostics.Abstractions/10.0.10": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10", + "Microsoft.Extensions.Options": "10.0.10", + "System.Diagnostics.DiagnosticSource": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Diagnostics.Abstractions.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.1026.32716" + } + } + }, + "Microsoft.Extensions.FileProviders.Abstractions/10.0.10": { + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.FileProviders.Abstractions.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.1026.32716" + } + } + }, + "Microsoft.Extensions.FileProviders.Physical/8.0.0": { + "dependencies": { + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.10", + "Microsoft.Extensions.FileSystemGlobbing": "8.0.0", + "Microsoft.Extensions.Primitives": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.FileProviders.Physical.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.23.53103" + } + } + }, + "Microsoft.Extensions.FileSystemGlobbing/8.0.0": { + "runtime": { + "lib/net8.0/Microsoft.Extensions.FileSystemGlobbing.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.23.53103" + } + } + }, + "Microsoft.Extensions.Hosting/8.0.1": { + "dependencies": { + "Microsoft.Extensions.Configuration": "8.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.10", + "Microsoft.Extensions.Configuration.Binder": "8.0.2", + "Microsoft.Extensions.Configuration.CommandLine": "8.0.0", + "Microsoft.Extensions.Configuration.EnvironmentVariables": "8.0.0", + "Microsoft.Extensions.Configuration.FileExtensions": "8.0.1", + "Microsoft.Extensions.Configuration.Json": "8.0.1", + "Microsoft.Extensions.Configuration.UserSecrets": "8.0.1", + "Microsoft.Extensions.DependencyInjection": "8.0.1", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10", + "Microsoft.Extensions.Diagnostics": "8.0.1", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.10", + "Microsoft.Extensions.FileProviders.Physical": "8.0.0", + "Microsoft.Extensions.Hosting.Abstractions": "10.0.10", + "Microsoft.Extensions.Logging": "8.0.1", + "Microsoft.Extensions.Logging.Abstractions": "10.0.10", + "Microsoft.Extensions.Logging.Configuration": "8.0.1", + "Microsoft.Extensions.Logging.Console": "8.0.1", + "Microsoft.Extensions.Logging.Debug": "8.0.1", + "Microsoft.Extensions.Logging.EventLog": "8.0.1", + "Microsoft.Extensions.Logging.EventSource": "8.0.1", + "Microsoft.Extensions.Options": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Hosting.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1024.46610" + } + } + }, + "Microsoft.Extensions.Hosting.Abstractions/10.0.10": { + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.10", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.10", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.10", + "Microsoft.Extensions.Logging.Abstractions": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Hosting.Abstractions.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.1026.32716" + } + } + }, + "Microsoft.Extensions.Logging/8.0.1": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "8.0.1", + "Microsoft.Extensions.Logging.Abstractions": "10.0.10", + "Microsoft.Extensions.Options": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Logging.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1024.46610" + } + } + }, + "Microsoft.Extensions.Logging.Abstractions/10.0.10": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10", + "System.Diagnostics.DiagnosticSource": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.1026.32716" + } + } + }, + "Microsoft.Extensions.Logging.Configuration/8.0.1": { + "dependencies": { + "Microsoft.Extensions.Configuration": "8.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.10", + "Microsoft.Extensions.Configuration.Binder": "8.0.2", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10", + "Microsoft.Extensions.Logging": "8.0.1", + "Microsoft.Extensions.Logging.Abstractions": "10.0.10", + "Microsoft.Extensions.Options": "10.0.10", + "Microsoft.Extensions.Options.ConfigurationExtensions": "8.0.0" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Logging.Configuration.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1024.46610" + } + } + }, + "Microsoft.Extensions.Logging.Console/8.0.1": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10", + "Microsoft.Extensions.Logging": "8.0.1", + "Microsoft.Extensions.Logging.Abstractions": "10.0.10", + "Microsoft.Extensions.Logging.Configuration": "8.0.1", + "Microsoft.Extensions.Options": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Logging.Console.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1024.46610" + } + } + }, + "Microsoft.Extensions.Logging.Debug/8.0.1": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10", + "Microsoft.Extensions.Logging": "8.0.1", + "Microsoft.Extensions.Logging.Abstractions": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Logging.Debug.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1024.46610" + } + } + }, + "Microsoft.Extensions.Logging.EventLog/8.0.1": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10", + "Microsoft.Extensions.Logging": "8.0.1", + "Microsoft.Extensions.Logging.Abstractions": "10.0.10", + "Microsoft.Extensions.Options": "10.0.10", + "System.Diagnostics.EventLog": "8.0.1" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Logging.EventLog.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1024.46610" + } + } + }, + "Microsoft.Extensions.Logging.EventSource/8.0.1": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10", + "Microsoft.Extensions.Logging": "8.0.1", + "Microsoft.Extensions.Logging.Abstractions": "10.0.10", + "Microsoft.Extensions.Options": "10.0.10", + "Microsoft.Extensions.Primitives": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Logging.EventSource.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1024.46610" + } + } + }, + "Microsoft.Extensions.Options/10.0.10": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10", + "Microsoft.Extensions.Primitives": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Options.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.1026.32716" + } + } + }, + "Microsoft.Extensions.Options.ConfigurationExtensions/8.0.0": { + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.10", + "Microsoft.Extensions.Configuration.Binder": "8.0.2", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10", + "Microsoft.Extensions.Options": "10.0.10", + "Microsoft.Extensions.Primitives": "10.0.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.23.53103" + } + } + }, + "Microsoft.Extensions.Primitives/10.0.10": { + "runtime": { + "lib/net8.0/Microsoft.Extensions.Primitives.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.1026.32716" + } + } + }, + "ModelContextProtocol/2.0.0": { + "dependencies": { + "Microsoft.Extensions.Caching.Abstractions": "10.0.10", + "Microsoft.Extensions.Hosting.Abstractions": "10.0.10", + "ModelContextProtocol.Core": "2.0.0" + }, + "runtime": { + "lib/net8.0/ModelContextProtocol.dll": { + "assemblyVersion": "2.0.0.0", + "fileVersion": "2.0.0.0" + } + } + }, + "ModelContextProtocol.Core/2.0.0": { + "dependencies": { + "Microsoft.Extensions.AI.Abstractions": "10.8.3", + "Microsoft.Extensions.Logging.Abstractions": "10.0.10", + "System.IO.Pipelines": "10.0.10", + "System.Net.ServerSentEvents": "10.0.10" + }, + "runtime": { + "lib/net8.0/ModelContextProtocol.Core.dll": { + "assemblyVersion": "2.0.0.0", + "fileVersion": "2.0.0.0" + } + } + }, + "System.Diagnostics.DiagnosticSource/10.0.10": { + "runtime": { + "lib/net8.0/System.Diagnostics.DiagnosticSource.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.1026.32716" + } + } + }, + "System.Diagnostics.EventLog/8.0.1": { + "runtime": { + "runtimes/win/lib/net8.0/System.Diagnostics.EventLog.Messages.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1024.46610" + }, + "runtimes/win/lib/net8.0/System.Diagnostics.EventLog.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1024.46610" + } + } + }, + "System.IO.Pipelines/10.0.10": { + "runtime": { + "lib/net8.0/System.IO.Pipelines.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.1026.32716" + } + } + }, + "System.Net.ServerSentEvents/10.0.10": { + "runtime": { + "lib/net8.0/System.Net.ServerSentEvents.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.1026.32716" + } + } + }, + "System.Text.Encodings.Web/10.0.10": { + "runtime": { + "lib/net8.0/System.Text.Encodings.Web.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.1026.32716" + } + } + }, + "System.Text.Json/10.0.10": { + "dependencies": { + "System.IO.Pipelines": "10.0.10", + "System.Text.Encodings.Web": "10.0.10" + }, + "runtime": { + "lib/net8.0/System.Text.Json.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "10.0.1026.32716" + } + } + }, + "Kompas.Mcp.Core/0.1.0": { + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "10.0.10" + }, + "runtime": { + "Kompas.Mcp.Core.dll": { + "assemblyVersion": "0.1.0", + "fileVersion": "0.1.0.0" + } + } + } + } + }, + "libraries": { + "kompas-mcp/0.1.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.Extensions.AI.Abstractions/10.8.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-K0B05oApxmviWalNHPMBBcRC7erKiDATz3ENNR/jqTR9JwIwLRefgDhj2jCRwL1aca99pXUe0qyQC73/xIuZig==", + "path": "microsoft.extensions.ai.abstractions/10.8.3", + "hashPath": "microsoft.extensions.ai.abstractions.10.8.3.nupkg.sha512" + }, + "Microsoft.Extensions.Caching.Abstractions/10.0.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4ZFBNE+jzR+CrWWlhOesnmywCW7pYKT0dxyAQRdL11yJwxe4jvcAu31eorFtEkoFeCDcUTeNssgPv2yaRRptaQ==", + "path": "microsoft.extensions.caching.abstractions/10.0.10", + "hashPath": "microsoft.extensions.caching.abstractions.10.0.10.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-0J/9YNXTMWSZP2p2+nvl8p71zpSwokZXZuJW+VjdErkegAnFdO1XlqtA62SJtgVYHdKu3uPxJHcMR/r35HwFBA==", + "path": "microsoft.extensions.configuration/8.0.0", + "hashPath": "microsoft.extensions.configuration.8.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.Abstractions/10.0.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-5Vnd2I75DmZCVEjSynIdJ/0EGafgnLQwgR3t2C2/fkjx/nRG+cLwxLLdInoHeCEpkD5K4Ov/g9ZCRYrl4TRsaA==", + "path": "microsoft.extensions.configuration.abstractions/10.0.10", + "hashPath": "microsoft.extensions.configuration.abstractions.10.0.10.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.Binder/8.0.2": { + "type": "package", + "serviceable": true, + "sha512": "sha512-7IQhGK+wjyGrNsPBjJcZwWAr+Wf6D4+TwOptUt77bWtgNkiV8tDEbhFS+dDamtQFZ2X7kWG9m71iZQRj2x3zgQ==", + "path": "microsoft.extensions.configuration.binder/8.0.2", + "hashPath": "microsoft.extensions.configuration.binder.8.0.2.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.CommandLine/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-NZuZMz3Q8Z780nKX3ifV1fE7lS+6pynDHK71OfU4OZ1ItgvDOhyOC7E6z+JMZrAj63zRpwbdldYFk499t3+1dQ==", + "path": "microsoft.extensions.configuration.commandline/8.0.0", + "hashPath": "microsoft.extensions.configuration.commandline.8.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.EnvironmentVariables/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-plvZ0ZIpq+97gdPNNvhwvrEZ92kNml9hd1pe3idMA7svR0PztdzVLkoWLcRFgySYXUJc3kSM3Xw3mNFMo/bxRA==", + "path": "microsoft.extensions.configuration.environmentvariables/8.0.0", + "hashPath": "microsoft.extensions.configuration.environmentvariables.8.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.FileExtensions/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-EJzSNO9oaAXnTdtdNO6npPRsIIeZCBSNmdQ091VDO7fBiOtJAAeEq6dtrVXIi3ZyjC5XRSAtVvF8SzcneRHqKQ==", + "path": "microsoft.extensions.configuration.fileextensions/8.0.1", + "hashPath": "microsoft.extensions.configuration.fileextensions.8.0.1.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.Json/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-L89DLNuimOghjV3tLx0ArFDwVEJD6+uGB3BMCMX01kaLzXkaXHb2021xOMl2QOxUxbdePKUZsUY7n2UUkycjRg==", + "path": "microsoft.extensions.configuration.json/8.0.1", + "hashPath": "microsoft.extensions.configuration.json.8.0.1.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.UserSecrets/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-7tYqdPPpAK+3jO9d5LTuCK2VxrEdf85Ol4trUr6ds4jclBecadWZ/RyPCbNjfbN5iGTfUnD/h65TOQuqQv2c+A==", + "path": "microsoft.extensions.configuration.usersecrets/8.0.1", + "hashPath": "microsoft.extensions.configuration.usersecrets.8.0.1.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-BmANAnR5Xd4Oqw7yQ75xOAYODybZQRzdeNucg7kS5wWKd2PNnMdYtJ2Vciy0QLylRmv42DGl5+AFL9izA6F1Rw==", + "path": "microsoft.extensions.dependencyinjection/8.0.1", + "hashPath": "microsoft.extensions.dependencyinjection.8.0.1.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/10.0.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-z/2xXlFw2aLGjHyEm6E0tQ+In6VfzQzTrtArbQ2c0TQE16ZbyDCMGPvaUT9I0s8rgy9sRWlU2P9waW37qV04qA==", + "path": "microsoft.extensions.dependencyinjection.abstractions/10.0.10", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.10.0.10.nupkg.sha512" + }, + "Microsoft.Extensions.Diagnostics/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-doVPCUUCY7c6LhBsEfiy3W1bvS7Mi6LkfQMS8nlC22jZWNxBv8VO8bdfeyvpYFst6Kxqk7HBC6lytmEoBssvSQ==", + "path": "microsoft.extensions.diagnostics/8.0.1", + "hashPath": "microsoft.extensions.diagnostics.8.0.1.nupkg.sha512" + }, + "Microsoft.Extensions.Diagnostics.Abstractions/10.0.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-9uWiKpeOVac355STyChWR/pliFX/5CeLqChW9kKsaxyDH4EUTZxMkT4Jwp/J/peLm0GBFmSX5c0WCse3yCnq1Q==", + "path": "microsoft.extensions.diagnostics.abstractions/10.0.10", + "hashPath": "microsoft.extensions.diagnostics.abstractions.10.0.10.nupkg.sha512" + }, + "Microsoft.Extensions.FileProviders.Abstractions/10.0.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-c5zqFCY9DiIpMovLd7/d/CTiEtrMOuQ639dhv3PABtKQIKNQikSHwQt8+N679uii9q+B55lgK28Uv64FOwEu8w==", + "path": "microsoft.extensions.fileproviders.abstractions/10.0.10", + "hashPath": "microsoft.extensions.fileproviders.abstractions.10.0.10.nupkg.sha512" + }, + "Microsoft.Extensions.FileProviders.Physical/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-UboiXxpPUpwulHvIAVE36Knq0VSHaAmfrFkegLyBZeaADuKezJ/AIXYAW8F5GBlGk/VaibN2k/Zn1ca8YAfVdA==", + "path": "microsoft.extensions.fileproviders.physical/8.0.0", + "hashPath": "microsoft.extensions.fileproviders.physical.8.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.FileSystemGlobbing/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-OK+670i7esqlQrPjdIKRbsyMCe9g5kSLpRRQGSr4Q58AOYEe/hCnfLZprh7viNisSUUQZmMrbbuDaIrP+V1ebQ==", + "path": "microsoft.extensions.filesystemglobbing/8.0.0", + "hashPath": "microsoft.extensions.filesystemglobbing.8.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Hosting/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-bP9EEkHBEfjgYiG8nUaXqMk/ujwJrffOkNPP7onpRMO8R+OUSESSP4xHkCAXgYZ1COP2Q9lXlU5gkMFh20gRuw==", + "path": "microsoft.extensions.hosting/8.0.1", + "hashPath": "microsoft.extensions.hosting.8.0.1.nupkg.sha512" + }, + "Microsoft.Extensions.Hosting.Abstractions/10.0.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-5LugpYGHk+mkn0a8IZgcyfBca8PCTAU9RQFoMrTdtOOidq88M2SI5f3px6ugnzgxC+eTkvYYJi8pzlUnG5xdAQ==", + "path": "microsoft.extensions.hosting.abstractions/10.0.10", + "hashPath": "microsoft.extensions.hosting.abstractions.10.0.10.nupkg.sha512" + }, + "Microsoft.Extensions.Logging/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4x+pzsQEbqxhNf1QYRr5TDkLP9UsLT3A6MdRKDDEgrW7h1ljiEPgTNhKYUhNCCAaVpQECVQ+onA91PTPnIp6Lw==", + "path": "microsoft.extensions.logging/8.0.1", + "hashPath": "microsoft.extensions.logging.8.0.1.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.Abstractions/10.0.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-zkFxGYUvdxAvIKTyXHrmW+Sux53D4SezD9dMyZ6hrwwzPQJNuwCRy1f5W7AvYTqacEGhWF2XderRQG1OvbV8og==", + "path": "microsoft.extensions.logging.abstractions/10.0.10", + "hashPath": "microsoft.extensions.logging.abstractions.10.0.10.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.Configuration/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-QWwTrsgOnJMmn+XUslm8D2H1n3PkP/u/v52FODtyBc/k4W9r3i2vcXXeeX/upnzllJYRRbrzVzT0OclfNJtBJA==", + "path": "microsoft.extensions.logging.configuration/8.0.1", + "hashPath": "microsoft.extensions.logging.configuration.8.0.1.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.Console/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-uzcg/5U2eLyn5LIKlERkdSxw6VPC1yydnOSQiRRWGBGN3kphq3iL4emORzrojScDmxRhv49gp5BI8U3Dz7y4iA==", + "path": "microsoft.extensions.logging.console/8.0.1", + "hashPath": "microsoft.extensions.logging.console.8.0.1.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.Debug/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-B8hqNuYudC2RB+L/DI33uO4rf5by41fZVdcVL2oZj0UyoAZqnwTwYHp1KafoH4nkl1/23piNeybFFASaV2HkFg==", + "path": "microsoft.extensions.logging.debug/8.0.1", + "hashPath": "microsoft.extensions.logging.debug.8.0.1.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.EventLog/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ZD1m4GXoxcZeDJIq8qePKj+QAWeQNO/OG8skvrOG8RQfxLp9MAKRoliTc27xanoNUzeqvX5HhS/I7c0BvwAYUg==", + "path": "microsoft.extensions.logging.eventlog/8.0.1", + "hashPath": "microsoft.extensions.logging.eventlog.8.0.1.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.EventSource/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-YMXMAla6B6sEf/SnfZYTty633Ool3AH7KOw2LOaaEqwSo2piK4f7HMtzyc3CNiipDnq1fsUSuG5Oc7ZzpVy8WQ==", + "path": "microsoft.extensions.logging.eventsource/8.0.1", + "hashPath": "microsoft.extensions.logging.eventsource.8.0.1.nupkg.sha512" + }, + "Microsoft.Extensions.Options/10.0.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-srnhnk7nE8krBiIXp71LvBmKBtraBONWSRzdjJgRv1Ko9Mp8IVNqv4vIS9hGeVteBig8aQkva9ZG+sC+o5sVcA==", + "path": "microsoft.extensions.options/10.0.10", + "hashPath": "microsoft.extensions.options.10.0.10.nupkg.sha512" + }, + "Microsoft.Extensions.Options.ConfigurationExtensions/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-0f4DMRqEd50zQh+UyJc+/HiBsZ3vhAQALgdkcQEalSH1L2isdC7Yj54M3cyo5e+BeO5fcBQ7Dxly8XiBBcvRgw==", + "path": "microsoft.extensions.options.configurationextensions/8.0.0", + "hashPath": "microsoft.extensions.options.configurationextensions.8.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Primitives/10.0.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-5wu/GrYVd8mG2DVUw3vFJzF+O336TyTGg/Kmcgw9bfwYhCoFiV5lR5QeEmKecJyrW4W54nMfD3p3589E8a7czQ==", + "path": "microsoft.extensions.primitives/10.0.10", + "hashPath": "microsoft.extensions.primitives.10.0.10.nupkg.sha512" + }, + "ModelContextProtocol/2.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-X/KDNZDP9Zgs7YXXxxpKiDMWWPXYrs764lVgc6vEM4pCg87bYz4VaceeiKW91XDTGgUvIbmRYXgWqyNpV32xRg==", + "path": "modelcontextprotocol/2.0.0", + "hashPath": "modelcontextprotocol.2.0.0.nupkg.sha512" + }, + "ModelContextProtocol.Core/2.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-piFR0HtA/2Oc1tgk96EE5Tye6qA2sg3WGRAXBhUqo/BWikdEYEs2UuqtmwLrQZJUge1nUOPgGHYsb15VIBK8iw==", + "path": "modelcontextprotocol.core/2.0.0", + "hashPath": "modelcontextprotocol.core.2.0.0.nupkg.sha512" + }, + "System.Diagnostics.DiagnosticSource/10.0.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-cjtKi6ERMYWp6b9UTVPcwDT29PjKDtlM3W9OwnWL5abRsI8ku42Q2wqZoLIIXJnT/XF2s2CjuK8Nl4a3mmTxQQ==", + "path": "system.diagnostics.diagnosticsource/10.0.10", + "hashPath": "system.diagnostics.diagnosticsource.10.0.10.nupkg.sha512" + }, + "System.Diagnostics.EventLog/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-n1ZP7NM2Gkn/MgD8+eOT5MulMj6wfeQMNS2Pizvq5GHCZfjlFMXV2irQlQmJhwA2VABC57M0auudO89Iu2uRLg==", + "path": "system.diagnostics.eventlog/8.0.1", + "hashPath": "system.diagnostics.eventlog.8.0.1.nupkg.sha512" + }, + "System.IO.Pipelines/10.0.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-7WX0W96y3dpQdYG4sEGdh38g3/0lOD4/dKbn2rRVOVzKhzoZUn2gKNIKaFeKWs8RCbpFfmmEWsRhSy95hMpvqA==", + "path": "system.io.pipelines/10.0.10", + "hashPath": "system.io.pipelines.10.0.10.nupkg.sha512" + }, + "System.Net.ServerSentEvents/10.0.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-1m3dGOl5YI9VhOE+MPCSII+WXZcyYVr5D/UbBifOUxkrx2npczhWjdl0PYZ1tMGygVce1mIfUDhdM1LBiEQFNw==", + "path": "system.net.serversentevents/10.0.10", + "hashPath": "system.net.serversentevents.10.0.10.nupkg.sha512" + }, + "System.Text.Encodings.Web/10.0.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-o16m2YpDN/pjHsnxf9pTGwkpcuvjW8v1/wGUwJtM1c3QZUKm7ZEO/eYRJg7iIx6GxS2Zv9lAMHpiQwHDdgqauA==", + "path": "system.text.encodings.web/10.0.10", + "hashPath": "system.text.encodings.web.10.0.10.nupkg.sha512" + }, + "System.Text.Json/10.0.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-bmsO6UdYtBdtn32zYXfsh7KlyTIzV/3V9hdT9RIb4pXKgYOsNxXR+VbWigNwBtNFVGYGm6Hwmqw5a+/IWFd36Q==", + "path": "system.text.json/10.0.10", + "hashPath": "system.text.json.10.0.10.nupkg.sha512" + }, + "Kompas.Mcp.Core/0.1.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/plugin/bin/kompas-mcp.dll b/plugin/bin/kompas-mcp.dll new file mode 100644 index 0000000..dd47290 Binary files /dev/null and b/plugin/bin/kompas-mcp.dll differ diff --git a/plugin/bin/kompas-mcp.exe b/plugin/bin/kompas-mcp.exe new file mode 100755 index 0000000..c82b843 Binary files /dev/null and b/plugin/bin/kompas-mcp.exe differ diff --git a/plugin/bin/kompas-mcp.pdb b/plugin/bin/kompas-mcp.pdb new file mode 100644 index 0000000..08f8c8d Binary files /dev/null and b/plugin/bin/kompas-mcp.pdb differ diff --git a/plugin/bin/kompas-mcp.runtimeconfig.json b/plugin/bin/kompas-mcp.runtimeconfig.json new file mode 100644 index 0000000..8e02282 --- /dev/null +++ b/plugin/bin/kompas-mcp.runtimeconfig.json @@ -0,0 +1,14 @@ +{ + "runtimeOptions": { + "tfm": "net8.0", + "rollForward": "LatestMajor", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "8.0.0" + }, + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false + } + } +} \ No newline at end of file diff --git a/plugin/commands/doctor.md b/plugin/commands/doctor.md new file mode 100644 index 0000000..27e659f --- /dev/null +++ b/plugin/commands/doctor.md @@ -0,0 +1,66 @@ +--- +description: "Диагностика установки плагина КОМПАС-3D: версия сервера, .NET, interop, соединение с КОМПАС" +--- + +Проверь установку плагина `kompas` по шагам и дай отчёт на русском. На каждый неуспешный пункт +назови конкретное действие, которое пользователь может сделать сам (без доступа к исходникам +проекта). Не переходи к следующему пункту, если текущий выявил фатальную проблему — сразу +переходи к отчёту с найденной причиной. + +1. **Ожидаемая версия.** Прочитай `${CLAUDE_PLUGIN_ROOT}/.claude-plugin/plugin.json` — поле + `version`. Это версия, которую Claude Code считает установленной; сервер едет в том же дереве + плагина, отдельной установки и кеша у него нет. + +2. **Локальная сборка вместо поставки.** Проверь переменную окружения `KOMPAS_MCP_EXE` + (в PowerShell: `$env:KOMPAS_MCP_EXE`). Если она задана — это режим разработки: используется + указанный в ней бинарь, а не поставленный с плагином. Проверь, что файл по этому пути + существует; не существует — попроси пользователя пересобрать проект или снять переменную. + +3. **Сервер на месте и запускается.** Если `KOMPAS_MCP_EXE` не задана, бинарь лежит в + `${CLAUDE_PLUGIN_ROOT}/bin/kompas-mcp.exe`. Проверь, что файл есть, и выполни + `& "<путь>\kompas-mcp.exe" --version` — команда печатает версию и сразу выходит, КОМПАС при + этом не запускается. Разбирай результат так: + - файла нет — установка повреждена: `/plugin update kompas@kompas-plugin`, при необходимости + переустановить плагин; + - команда не запустилась и в ошибке упомянут .NET / `hostfxr` / «framework» — на машине нет + нужного рантайма (см. пункт 4); + - версия не совпала с `plugin.json` — обновление применилось наполовину: + `/plugin update kompas@kompas-plugin`, затем `/reload-plugins`. + +4. **.NET Runtime.** Сервер поставляется framework-dependent, поэтому рантайм нужен на машине: + `dotnet --list-runtimes` должен показать строку `Microsoft.NETCore.App 8.<любая>` или новее + (x64). Ни одной подходящей строки или самой команды `dotnet` нет — это и есть причина сбоя + пункта 3: попроси пользователя поставить .NET Runtime 8 или новее с + https://dotnet.microsoft.com/download/dotnet (нужен именно x64; Desktop Runtime не обязателен). + +5. **КОМПАС-3D установлен и, возможно, уже запущен.** Сервер подключается к КОМПАС лениво — не при + старте MCP-сервера, а при первом вызове инструмента. Проверь двумя командами: + `Get-Process KOMPAS* -ErrorAction SilentlyContinue` (запущен ли сейчас) и + `Get-ChildItem 'HKLM:\SOFTWARE\Classes\KOMPAS.Application.5' -ErrorAction SilentlyContinue` + (зарегистрирован ли COM-класс, то есть установлен ли КОМПАС вообще). Запущен — сервер + присоединится к нему; не запущен, но зарегистрирован — попробует запустить новый экземпляр сам; + не зарегистрирован — это и есть причина сбоя: попроси пользователя установить КОМПАС-3D. + +6. **Interop-сборки КОМПАС.** Сервер их не поставляет (они принадлежат АСКОН) и берёт из установки + КОМПАС: `<каталог установки>\SDK\Samples\CSharp.zip`, каталог `Common` внутри архива, + распаковка — в `%LOCALAPPDATA%\kompas-mcp\interop\<ключ>`. Проверь наличие архива: + `Test-Path ((Get-ItemProperty "HKLM:\SOFTWARE\Classes\CLSID\$((Get-ItemProperty 'HKLM:\SOFTWARE\Classes\KOMPAS.Application.5\CLSID').'(default)')\LocalServer32").'(default)'.Trim('"') | Split-Path | Split-Path | Join-Path -ChildPath 'SDK\Samples\CSharp.zip')`. + Архива нет — КОМПАС установлен без компонента SDK: попроси пользователя доустановить SDK либо + задать переменную окружения `KOMPAS_INTEROP_DIR` с каталогом, где лежат `KompasAPI7.dll`, + `Kompas6API5.dll`, `Kompas6Constants.dll`, `Kompas6Constants3D.dll`. Если переменная + `KOMPAS_INTEROP_DIR` уже задана — проверь, что эти четыре файла в указанном каталоге есть. + +7. **Проверка соединения инструментами MCP.** Вызови инструмент `kompas_connect` — он либо + присоединится к уже запущенному КОМПАС, либо запустит новый и покажет окно, и вернёт версию и + редакцию. Если вызов упал с ошибкой — приложи её текст к отчёту дословно (обычно это означает, + что КОМПАС не установлен, лицензия не активирована, или предыдущий процесс КОМПАС завис — + попроси пользователя проверить лицензию и вручную закрыть зависшие процессы КОМПАС через + Диспетчер задач). Затем вызови `kompas_status`, чтобы явно зафиксировать итоговое состояние + подключения в отчёте — учти, что сам по себе `kompas_status` не пытается подключиться, а + только читает текущее состояние сессии, поэтому он осмыслен только после `kompas_connect`. + Отдельный случай: если `kompas_status` вернул сообщение про interop-сборки — это диагноз + пункта 6, а не проблема соединения. + +8. **Итог.** Собери отчёт: версия плагина, источник бинаря (поставка или `KOMPAS_MCP_EXE`), путь до + него, версия найденного .NET Runtime, результат `kompas_connect`/`kompas_status`, и — если + что-то не сошлось — какое из действий выше нужно предпринять пользователю. diff --git a/plugin/scripts/launch-kompas-mcp.ps1 b/plugin/scripts/launch-kompas-mcp.ps1 new file mode 100644 index 0000000..62e1777 --- /dev/null +++ b/plugin/scripts/launch-kompas-mcp.ps1 @@ -0,0 +1,47 @@ +#requires -Version 5.1 +# Точка входа MCP-сервера КОМПАС-3D. +# ИНВАРИАНТ: до запуска сервера в stdout не уходит ни байта — stdout занят JSON-RPC. +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' +$ProgressPreference = 'SilentlyContinue' + +$exe = $null +try { + if (-not [string]::IsNullOrWhiteSpace($env:KOMPAS_MCP_EXE)) { + # Режим разработки: сервер собран локально, дерево плагина не трогаем. + $exe = $env:KOMPAS_MCP_EXE + } + else { + # Сервер едет в самом плагине (framework-dependent, ~6,6 МБ на диске): скачивать + # и сверять контрольные суммы нечего — git уже доставил файл вместе с навыками. + $exe = Join-Path (Split-Path -Parent $PSScriptRoot) 'bin\kompas-mcp.exe' + } + + # -PathType Leaf: без него путь к существующему каталогу молча проходит проверку, + # а падает уже голый вызов "& $exe" сырым CommandNotFoundException в обход catch ниже. + if (-not (Test-Path -LiteralPath $exe -PathType Leaf)) { + throw "не найден сервер: $exe" + } +} +catch { + [Console]::Error.WriteLine("kompas-mcp launcher: $($_.Exception.Message)") + exit 1 +} + +try { + # Сплаттинг @args во внешний процесс: пустые строки-аргументы теряются (особенность + # PowerShell) — для MCP-клиента безвредно, он серверу аргументов не передаёт. + & $exe @args + $serverExit = $LASTEXITCODE +} +catch { + # Сбой самого запуска (битый бинарь, недостающая зависимость, отказ в доступе) — + # не путать с ненулевым кодом возврата уже запущенного сервера, это не exception. + # Самая частая причина здесь — отсутствующий .NET Runtime: сервер поставляется + # framework-dependent, и без рантайма apphost падает именно тут. + [Console]::Error.WriteLine("kompas-mcp launcher: не удалось запустить сервер: $($_.Exception.Message)") + [Console]::Error.WriteLine("kompas-mcp launcher: если .NET Runtime не установлен — https://dotnet.microsoft.com/download/dotnet (нужен .NET 8 или новее, x64)") + exit 1 +} + +exit $serverExit diff --git a/plugin/skills/kompas-3d/SKILL.md b/plugin/skills/kompas-3d/SKILL.md new file mode 100644 index 0000000..036c659 --- /dev/null +++ b/plugin/skills/kompas-3d/SKILL.md @@ -0,0 +1,563 @@ +--- +name: kompas-3d +description: > + Методика работы с КОМПАС-3D через MCP-сервер плагина: построение и + модификация деталей, импорт/экспорт STEP, работа со сборками, осмотр геометрии + снимками и запросами. Используй ВСЕГДА, когда задача — что-то СДЕЛАТЬ в КОМПАС + через MCP-инструменты (создать/править деталь, импортировать STEP, разобрать + сборку, померить, отрендерить, экспортировать). Здесь — playbook'и и эвристики, + проверенные на практике. Триггеры: «построй деталь в КОМПАС», «импортируй STEP», + «что в этой сборке», «нарасти/измени деталь», «экспортируй STEP», «сделай снимок модели». +--- + +# kompas-3d — методика управления КОМПАС-3D через MCP + +MCP-сервер даёт **общие** операции КОМПАС (эскизы, формообразующие, осмотр, обмен), этот навык — +**методику**: в каком порядке их применять, как выбирать геометрию, чем проверять результат и какие +подводные камни обходить. Коротко: **MCP = чем делать, навык = как делать.** Подробности вызова — +варианты операций, обязательные поля, типы примитивов эскиза и их параметры — живут в описаниях +самих инструментов: контракт сервера подробен, читай его, а не восстанавливай по памяти. + +## Когда применять + +Любая задача «сделать что-то В КОМПАС» через MCP: создать/править деталь, эскизы и операции, +импорт/экспорт обменных форматов, разбор сборки, измерения, снимки. + +## Два правила прежде всего + +**1. «Зрение» — структурное, не по картинке.** «Увидеть» деталь = **`describe_model`** — паспорт +одним запросом и ЕДИНСТВЕННЫЙ инструмент осмотра: разделы `box | mass | bodies | topology | tree | +variables | errors | components` (`sections` сужает и ответ, и объём чтения модели). Углубляться — +`list_faces(index=N)` / `list_edges` (отбор `type` + координатное окно — им адресуют то, что не +выбрать по одному: весь нижний контур под фаску) / `measure`. **`model_snapshot` +бери только** для визуально-пространственных вопросов, на которые паспорт не отвечает (общая +форма, ориентация, правдоподобность, «куда смотрит грань»): снимок дорог по контексту и менее +точен, чем числа. + +**2. Ответ мутирующей операции — это ТРИ проверки, читай все.** Любая операция может «пройти» +(`Create()==true`), оставив деталь в ошибке, поэтому каждая мутирующая операция сама дописывает +к ответу итог проверки построения и сводку состояния «Тел: N, объём V мм³»: + +- **«⚠ N операц. в ошибке»** (напр. `et3dError54`) — деталь невалидна: не продолжай и не + экспортируй, исправь или переделай другим методом. «Построение чистое» = порядок. +- **«Тел: 2»** там, где ждёшь одно тело, — деталь распалась: касание объединением не считается + (см. «Надписи»). Смотри на число ТЕЛ, а не граней: объединение сливает компланарные грани, + и счётчик граней законно остаётся прежним. +- **Объём сверяй с прикидкой** «площадь контура × высота». Так ловятся молча не применившаяся + тонкая стенка (прирост как у сплошного сечения), вычитание мимо цели и операция «не туда» — + габарит и снимок этого не покажут. + +Отдельный `describe_model(sections=errors,bodies,mass)` после каждого шага не нужен. Он +возвращается, когда авто-проверку выключили (`set_auto_validate(false)` на тяжёлой модели, где +проверка каждого шага тормозит): тогда `describe_model(sections=errors,bodies,mass)` вручную перед выдачей: одного +`errors` мало — распад детали на два тела показывает только раздел `bodies`. + +## Справочник сервера: `help` + +Подробности инструментов — маршруты, порядок вызовов, ловушки — лежат в самом сервере и достаются +по требованию, а не занимают контекст заранее: + +- `help()` — оглавление тем (дёшево, одна строка на тему); +- `help(topic="…")` — статья целиком; +- `help(query="…")` — поиск словами с цитатами; +- `help(tool="extrude")` — что известно про конкретный инструмент. + +**Зови его, когда инструмент повёл себя не так, как ты ожидал, и когда тема названа в тексте +ошибки.** Ссылки вида `help(topic="…")` по этому файлу — не украшение: там лежит то, что здесь +намеренно не повторяется. Справочник описывает ЭТОТ сервер; справка по COM API КОМПАС — отдельная +история и в работе через MCP не нужна. + +## Инструменты: индекс групп + +Актуальный перечень с описаниями параметров отдаёт сам MCP-сервер — здесь только карта: + +- *Система/документы:* `kompas_connect` (shared|private|attach), `kompas_set_visible`, + `kompas_status`, `set_auto_validate`, `set_operation_log`; `document_create|open|save|close`, + `document_active` (тип, путь, есть ли несохранённые изменения, «только чтение», материал детали), + `document_list` (все открытые документы — им проверяют, что имя файла занято другим документом + и что несохранённого не осталось), `set_part_info`, `set_part_material`. +- *Эскиз:* `sketch_create` (основание: `plane`+`offset` | `faceIndex` | точка; геометрия — списком + `entities` **или** файлом `entitiesFile`), `sketch_add`, `sketch_close`; `measure_text` — замер + надписи без построения; `fragment_create` — тот же список примитивов, но в самостоятельный + файл-фрагмент (*.frw); `fragment_place` — положить готовый фрагмент в чертёж. +- *Формообразующие:* `primitive`, `extrude`, `revolve`, `fillet_edge`, `chamfer_edge`, `shell`, + `rib`, `sweep`, `loft`, `draft`, `hole`, `pattern`, `mirror`, `feature_delete`, `rebuild`. +- *Прямое редактирование (в т.ч. импортированная B-rep):* `move_face`, `split_solid_by_plane`, + `move_body`, `boolean_union`. +- *Переменные:* `set_variable`, `list_parameters`, `link_parameter`, `delete_variable` + (сами переменные показывает `describe_model(sections=variables)`). +- *Обмен:* `import_model` (3D: step, iges, sat, xt, stl, c3d, jt, obj + родные форматы чужих САПР), + `import_drawing` (плоский .dxf/.dwg), `export_model` (`format=auto` по расширению: `.step` — + точная геометрия в другую САПР, `.stl` — сетка в слайсер). +- *Сборка:* `assembly_add_component` (положение + поворот `rx/ry/rz`), `assembly_add_mate` + (семь типов, `orientation`), `assembly_fix_component`, `assembly_delete`, + `assembly_check_interference` (не налезли ли детали друг на друга — больше это не видно нигде), + `assembly_transform_point` (`to=world|local` — точка между ЛСК компонента и СК сборки). +- *2D-чертёж:* `drawing_create_standard_views` (`views[]`, `mainOrientation`, `hiddenLines`), + `drawing_add_view` / `drawing_move_view` / `drawing_delete_view` / `drawing_get_view_info` + (компоновка листа и паспорт вида), `drawing_add_section_view` (РАЗРЕЗ или СЕЧЕНИЕ: линия разреза + на базовом виде и производный вид по ней — одним вызовом), `drawing_add_sheet`, + `drawing_set_sheet_format`, + `drawing_fill_title_block`, + `drawing_add_linear|diametral|radial|angular_dimension` (у всех — `tolerance`/`prefix`/`suffix`/ + `textOverride`; у Ø и R — ещё `objectKind`/`objectIndex`, прямой адрес окружности или дуги), + `drawing_add_axis`, `drawing_add_rough|text|leader`, + `drawing_set_unspecified_rough`, `drawing_set_technical_requirements`, `drawing_delete_object`, + `drawing_move_object` (сдвинуть поставленное), `drawing_project_point` (точка модели → координаты + вида), `drawing_export_image` (посмотреть + глазами). Обратное чтение — `drawing_get_title_block` и `drawing_get_technical_requirements`: + технические требования ПЕРЕЗАПИСЫВАЮТСЯ целиком, поэтому правку одного пункта начинают с чтения + текущего текста. Методика — §«Чертёж». +- *Осмотр:* `describe_model` (разделы `box|mass|bodies|topology|tree|variables|errors|components|mates` — + габарит, МЦХ, тела, топология, дерево построения, переменные, операции в ошибке, состав сборки, + сопряжения), `measure`, `model_snapshot`; адресация объектов — `list_faces` / `list_edges`. + Для 2D-документов — свой: `list_drawing_objects` (что лежит в чертеже/фрагменте). + +Три сквозных свойства контракта: **размерный параметр принимает число ИЛИ выражение** (имя +переменной/формулу — параметр сразу становится ведомым); **объект выбирается индексом** (надёжно) +или точкой (запасной путь — если выбирал точкой, ответ подскажет, что выбралось); **списковые +параметры** (`entities[]`, `edgeIndices[]`, `points[]`, `faceIndices[]`, `variables[]`, `links[]`) — +весь пакет одним вызовом: прямоугольник с четырьмя отверстиями — ОДИН `sketch_create`, скругление +восьми рёбер — ОДИН `fillet_edge`, крепёжная картина из шести отверстий — ОДИН `hole(points=[…])`, +наращивание двух торцов — ОДИН `move_face(faceIndices=[…])`; каждый лишний вызов — лишний шанс +сбиться. Пакет НЕ транзакционен: отказ называет позицию элемента в списке, а сделанное до него +остаётся — повторяй вызов с оставшимися, а не с начала. Если инструмента под задачу нет — собирай +результат из имеющихся общих операций. + +## Два пути формообразования — выбирай по форме, а не по привычке + +«Эскиз → выдавливание» — не единственный способ. `primitive` строит тело сразу по размерам, и это +короче и надёжнее там, где форма призматическая: + +| Форма | Чем строить | +|---|---| +| Плита, брусок, бобышка, штифт, цилиндрическая стойка | `primitive(kind=block\|cylinder)` — один вызов вместо «эскиз + выдавливание» | +| Прямоугольный карман, паз, срез угла | `primitive(..., result=subtract)` — вычитание тела вместо `extrude(mode=cut)` по эскизу | +| Скруглённые углы призмы | `primitive` + `fillet_edge` по рёбрам (скругление после, а не дуги в эскизе) | +| Текст, кривые, произвольный контур, переменное сечение | ТОЛЬКО эскиз: `sketch_create(entities=[…])` + `extrude`/`revolve`/`loft`/`sweep` | +| Тонкая стенка, ободок по контуру | эскиз + `extrude(thinThickness, thinSide)` | + +Их **сочетают в одной детали**: корпусные объёмы — примитивами, сложные контуры — эскизами. + +- **Ось цилиндра и конуса задаётся параметром, а не системой координат детали:** + `primitive(kind="cylinder", axis="X"|"Y"|"Z")`. Точка `x,y,z` остаётся центром основания в + мировых координатах, высота растёт вдоль выбранной оси. Не перепроектируй деталь ради того, + чтобы её ось совпала с Z (у `block` и `sphere` параметра нет: у блока ось задают размеры + `length/width/height`, у сферы оси нет). + +- **Тонкую стенку по сложному контуру строй ДО того, как появится тело, которое она пересечёт.** + `extrude(thinThickness=…)` по многоконтурному эскизу (надпись — десяток замкнутых контуров с + «дырками») отказывает, если стенка пересекает уже построенное тело; простой прямоугольный контур + проходит и с пересечением. Ошибка сервера называет причину, но порядок планируй заранее: на + шильдике «плашка → буквы → кайма» падает, а «буквы → кайма → плашка `primitive(union)` → карман + `primitive(subtract)`» проходит — примитивам пересечение безразлично. +- **Скругления делай, пока рёбер мало** — сразу после примитивов их видно в `list_edges` наперечёт. + Если рёбер уже сотни, бери их ПО ТОЧКАМ: `fillet_edge(radius, points=[…])` по углам известных + координат — одна операция на все; точки без ребра ошибка перечислит разом. +- **Скругление не построится там, где ребро «съедено» соседним элементом** (угол плашки под каймой + букв). Это нормальный ответ геометрии, а не ошибка вызова: проверь снимком, виден ли угол снаружи. +- **`result=new` даёт ОТДЕЛЬНОЕ тело**, `subtract` мимо цели сервер ловит сам — и то и другое + видно по сводке «Тел/объём» в ответе; при распаде зови `boolean_union`. + +## Базовый цикл (эскиз → операция → осмотр) + +Опорный сценарий построения, проверен end-to-end: + +1. `kompas_connect` (+ `kompas_set_visible true`). **Работаешь не один — бери свой экземпляр:** + `kompas_connect(instance="private")` (см. «Когда КОМПАС общий»). +2. `document_create(type="part", name="…")` — наименование даём сразу, здесь оно ничего не стоит. +3. **Запиши замысел переменными** до первого эскиза (см. «Параметризация») и связывай каждый + размер, взятый из паспорта, при построении — иначе переменная останется числом в списке. +4. `sketch_create(plane="XOY", entities=[…])` — весь контур одним вызовом. +5. `extrude` / `revolve` → прочитай итог проверки и сводку прямо в ответе (правило 2). +6. Осмотр — структурно: `describe_model` (нужен кусок — `sections="box,mass"`). +7. Итерация «на грани»: `list_faces` → `sketch_create(faceIndex=N, entities=[…])` → операция. +8. **Задай материал, если смотришь на массу** — `set_part_material`: у нового документа стоит + сталь 7.86, и МЦХ печатной детали завышена вшестеро; плотности ходовых материалов перечислены + в описании инструмента. +9. **Проверь, что деталь названа** (шаг 2 или `set_part_info`) — безликая «Деталь» уедет в штамп + чертежа и спецификацию; имя файла при сохранении этого не заменяет. + +**Называй каждую операцию** — `name` есть у всех: «Контур плашки», «Рельеф букв OldMan», «Карман +под площадку». Дерево из «Эскиз:1, Элемент выдавливания:3» нечитаемо ни человеку, ни тебе самому +через сотню вызовов. + +## Параметризация: сначала переменные, потом геометрия + +**В новом документе первым делом опиши будущую модель переменными — до первого эскиза.** Пока +деталь пуста, компоновка стоит одного вызова на размер; после десятка операций та же мысль стоит +пересборки. Набор переменных — это план построения числами и паспорт, по которому человек поймёт +модель, не разбирая дерево. + +- **Заводи переменной то, что было РЕШЕНИЕМ**: габариты из ТЗ, толщины, зазоры, отступы, кегли, + радиусы. Выводимое задавай формулой (`plate_L = badge_L - 2*edge_gap`) — правка ведущего размера + пересчитает зависимые сама. Позиции, подобранные замером, оставляй числами: связь — обещание, + что правка переменной даст осмысленный результат, а на позиционных числах она чаще ломает деталь. +- **Размер передавай выражением прямо в операцию** (`extrude(depth="badge_T")`) — параметр сразу + становится ведомым, внутреннее имя параметра («Расстояние 1») знать не нужно. Переменная должна + существовать ДО операции — потому паспорт и заводят первым. Задним числом и для параметров, + которых нет среди аргументов инструмента (углы уклона, второе направление), — `link_parameter`. +- **Промахи сервер ловит сам:** ссылка на несуществующее имя — отказ с перечнем виновных (и в + выражениях операций, и в `set_variable`; регистр значим), функции в формулах — предупреждение + (тригонометрия в радианах, разделитель аргументов «;», непонятая запись = молчаливый 0). + Твоя часть — **сверить вычисленные значения из ответа со своей прикидкой**. +- **`note` обязателен** и пишется по-русски, со смыслом и единицей; `(ТЗ)` метит числа, + зафиксированные пользователем. **Что замерил — верни в переменную** (фактический кегль, прирост + каймы), иначе паспорт разойдётся с моделью и станет дезинформацией. Переосмысливать можно всё, + кроме помеченного `(ТЗ)`. +- **После связывания правка паспорта перестраивает деталь** (проверено: `set_variable(badge_T=4)` → + габарит по Z 3.00 → 4.00, объём 5154.5 → 5861.5 мм³). Это и есть параметрическая модель, + а не комментарий к ней. +- **Сверка и уборка в конце:** `describe_model(sections=variables)` помечает «⚠ ничего не ведёт» — это либо забытая + связь, либо мусор; разбери оба. `delete_variable(unused=true)` — только ПОСЛЕ `link_parameter` + на всё, что должно вести геометрию: вычистка не отличает мусор от несвязанного размера из ТЗ. + +## Надписи, логотипы и рельеф + +Надпись — примитив `type=text` в эскизе; все поля (шрифт, кегль, `widthFactor`, выравнивание +`align`/`vAlign`) описаны в схеме `entities`. Она сразу переводится в кривые, поэтому выдавливается +как обычный контур: гравировка — `extrude(mode="cut")`, выпуклые буквы — `mode="boss"`. + +- **Ответ даёт габарит ГЛИФОВ и ширину ячейки — позиционируй по глифам.** Ячейка шире на 1–2 % у + наборных шрифтов (Zilla Slab, Bevan) и на 7–9 % у скриптовых (Lobster, Pacifico). +- **Кегль калибруй `measure_text`** — он ничего не строит. Пробу, которую всё же пришлось + построить, убирает `feature_delete`; отдельный черновой документ для этого не нужен. +- **`height` — высота ПРОПИСНОЙ, а не габарит строки** (Zilla Slab, height=10: «HH» → 9.97 мм, + «Hy» → 13.24 мм, выносной уходит на −3.27) — закладывай выносные отдельно. Прочие тонкости полей + (`widthFactor`, `align`, `vAlign`) — `help(topic="sketch-text")`. +- **Подложка под надпись — тем же эскизом тонкой стенкой:** один хендл эскиза можно передать в + несколько операций — сплошное выдавливание на высоту подложки + `extrude(thinThickness, + thinSide="outward")` дают силуэт с равномерной каймой. Стенку проверяй по объёму из сводки: + не применившаяся толщина молча даёт сплошное сечение при том же габарите. +- **Надпись и плашка обязаны ПЕРЕКРЫВАТЬСЯ** — по размерам чертежа блоки обычно только касаются, + а касание объединением не считается. Приём: кайму/полосу плашки сделать выше самой плашки на + 1–1.5 мм с той стороны, где стоит надпись. Распад видно по «Тел: 2» в ответе операции — не тяни + проверку до конца построения. +- **Рельеф = разница глубин от одной плоскости** (основание 2 мм + буквы 3 мм = выступ 1 мм); + не строй буквы «на грани основания» — из одного эскиза на базовой плоскости получается и то и + другое, и рельеф не зависит от порядка операций. +- **Шрифт должен быть установлен в системе** — неизвестное имя КОМПАС молча подменяет; сервер + предупреждает об этом в ответе `sketch_create`/`measure_text` — не игнорируй. + +**Логотип, которого нет в шрифте, приходит готовым вектором (SVG).** Переводи его в примитивы +эскиза сам — `line` и `arc3points`, а не ломаной: контур из сотен звеньев даёт деталь в сотни +граней, и фаска по такому низу не строится. Кубические Безье режь пополам, пока дуга по трём +точкам не ляжет в допуск. Четыре вещи, каждая из которых стоила захода: + +- **Ось Y в SVG смотрит вниз** — без инверсии контур встаёт вверх ногами, и это видно только на снимке. +- **Дуги задавай тремя точками** (`arc3points`): концы заданы явно, соседние примитивы стыкуются + точно. Перед постройкой проверь цепочку — конец примитива против начала следующего, разрыв 0. +- **Чисти мелочь под масштаб детали — параметром `minSegment`.** SVG рисуют в своём габарите (сотня + условных единиц), и его скругления после масштабирования превращаются в дуги по 0.02–0.5 мм; + замыкающий `z` часто даёт ещё и сегмент нулевой длины. `chamfer_edge` по такому набору отвечает + «катет больше длины N из M рёбер» — и это правда. Передай `sketch_create(minSegment=катет)` (тот же + параметр есть у `sketch_update` и `fragment_create`), и та же фаска пройдёт с первой попытки; + отчёт о выброшенном читай, а не пролистывай — `help(topic="contour-cleanup")`. + +**Порядок для фаски по контуру логотипа — только такой, и он неочевиден:** + +1. **чистка** порогом ≈ будущего катета (`minSegment`); +2. **замер ЧИЩЕНОГО силуэта** — `sketch_measure_thickness(entitiesFile, minSegment=тот же порог)`; +3. **катет по узкому месту** чищеного силуэта: `c ≤ (узкое_место − 2·w)/2`, где `w` — ширина нити. + +Менять шаги местами нельзя: **чистка СУЖАЕТ узкое место**. Она заменяет скругление острым углом — +в выпуклом углу это добавляет материал (габарит подрастает), а в вогнутом срезает его, и именно +вогнутые углы образуют перемычки между штрихами. Замер обводки логотипа шириной 105 мм: +узкое место 1.98 → 1.82 мм, порог распада лицевой грани 0.99 → 0.91. Катет, подобранный по +нечищеному контуру, после чистки перестаёт проходить свой же критерий. + +- **Ширину штриха и узкое место меряй инструментом, а не глазом** — `sketch_measure_thickness` + ничего не строит и документа не требует, поэтому зовётся ДО эскиза + (`help(topic="silhouette-thickness")`). От этих чисел зависит, останется ли что-то от рисунка + после фаски и напечатается ли он вообще; шаг растра в ответе — точность округления катета. + +Контур, который переживёт конкретную деталь (логотип, шаблон, профиль), клади во фрагмент — +`fragment_create(path, entities)` тем же списком примитивов. Активный документ он не подменяет, +поэтому фрагмент можно снять посреди построения детали; габарит в ответе снят с самого документа — +сверяй его с задуманным. + +**Точная подгонка и отделка — в [reference/text-and-relief.md](reference/text-and-relief.md); +прочитай его, как только доходишь до точной компоновки надписи или отделки рельефа:** подбор кегля +под заданную ширину за одну пробу, ступени `widthFactor`/`height`, приросты каймы на острых +терминалах (t/sin(θ/2)) и её роль в стыковке блоков, разрядка пробелами, кайма вокруг прямоугольной +плашки, карманы `primitive(subtract)` рядом с буквами, скругления и фаски рельефа на сотнях рёбер. + +## Внешний контур: не диктуй координаты, если фигуру нельзя описать формулой + +Три маршрута, и выбор между ними механический — не по вкусу, а по происхождению геометрии. + +| Откуда фигура | Чем строить | +|---|---| +| **Вычисляется**: пластины, рёбра, сетка отверстий | `sketch_create(entities[])` — прямо в вызове, размеры вяжи переменными | +| **Срисована**: логотип, шаблон, кулачок, профиль | внешний вектор → JSON → `sketch_create(entitiesFile=…)` | +| **Пришла в CAD-формате**: файл от смежника | `import_drawing` (.dxf/.dwg) → фрагмент → `fragment_place` | + +**Обводка занимает сотни примитивов, и переписывать их в тело вызова незачем.** У `sketch_create`, +`sketch_add` и `fragment_create` есть `entitiesFile` — путь к JSON того же формата, что `entities`; +сервер читает файл сам. Замер на эмблеме Volvo: SVG в 1.5 КБ даёт 96 примитивов (50 отрезков + +46 дуг) и 9.5 КБ JSON; через `entitiesFile` это один вызов на одну строку аргументов, а эскиз +строится за один заход. Оба параметра можно задать вместе — сначала `entities`, следом файл: +так к готовому контуру дописывают рамку или ось, не трогая файл. + +Что проверить **до** постройки, а не после: габарит в ответе (`fragment_create` печатает +фактический — сверь с задуманным) и вложенные контуры. Правил заливки у эскиза КОМПАС нет: любой +вложенный контур он режет как отверстие, даже там, где вектор заливал материал. Конвертер такие +места называет заранее — на них смотри до выдавливания, иначе дыры обнаружатся на снимке. + +## Фрагмент — переиспользуемый чертёж, а не сечение + +Эскиз живёт внутри дерева построения и вне его не существует; фрагмент (*.frw) — самостоятельный +файл, который переживает деталь. `fragment_create` его пишет, `fragment_place` кладёт в активный +чертёж или другой фрагмент, а `mode` решает, чем он там станет — и это разные объекты, а не +оттенки одного: + +- **`reference`** — вставка-ссылка: содержимым владеет файл, правка файла меняет все документы, куда + он вставлен. Ради этого фрагменты и заводят: одна заготовка на десять чертежей. +- **`copy`** — копия внутри документа, живёт своей жизнью; файл потом можно удалить. +- **`local`** — вставка, переиспользуемая только внутри этого документа. +- **`explode`** — россыпь обычных примитивов: правится по одному, но связи с файлом уже нет. + +`angle` (градусы), `scale` и `mirror` задают размещение; зеркалить можно только вставку — у россыпи +отражать нечего. **Зеркало отражает относительно вертикали через точку вставки**, поэтому контур +уходит в другую сторону от неё: вставка в x=220 после `mirror` занимает 160…220, а не 220…280. + +Проверять результат — `list_drawing_objects`: он показывает состав по типам, габарит и все вставки +с их файлами. Вставка, чей файл потерялся, рисуется пустым местом — в списке она помечена +недействительной, и это единственный способ отличить её от удавшейся, не глядя на экран. + +## Сборка: собрать своё + +Плейбук: **создать → вставить → ЗАФИКСИРОВАТЬ базовую → сопрячь → rebuild → проверить.** +Разбор чужой сборки — следующий раздел, здесь про сборку с нуля. + +1. **Детали сначала сохрани в файлы.** Компонент вставляется ссылкой на `.m3d`/`.a3d`, поэтому + несохранённую деталь вставить нельзя. +2. **`document_create assembly` → `assembly_add_component(filePath, x, y, z, rx, ry, rz)`.** Углы — в + градусах, вокруг СОБСТВЕННЫХ осей компонента и по очереди X→Y→Z: второй угол считается уже от + повёрнутого положения. Пока задан один угол, разницы с мировыми осями нет. +3. **Зафиксируй базовую деталь СРАЗУ: `assembly_fix_component(componentIndex=0, fixedState=true)`.** КОМПАС не закрепляет + никого сам, включая первый компонент, и решатель двигает того, кого сочтёт нужным — в том числе + основание, вокруг которого ты собираешь всё остальное. Это самая частая причина «сопряжение + верное, а сборка расползлась». +4. **Сопрягай:** `assembly_add_mate(mateType, …)` — семь типов, адресация гранью и смысл + `orientation` в `help(topic="assembly-mates")`. Что решаешь ты, а не справочник: + - **Грань адресуй индексом, а не координатами:** `list_faces(component=N)` → пара + `faceIndex`+`componentIndex`. Точки на бумаге считать не нужно, и сервер сам проверит, что + грань принадлежит этому компоненту. + - **Сторону зазора у `distance` задаёт ВЫБОР ПАРЫ ГРАНЕЙ, и от стартового положения она не + зависит.** «Closest» — не «ближайшее»: при сонаправленных нормалях объект 1 садится со стороны + −n относительно объекта 2 (замерено двойным прогоном). Практическое правило: бери пару граней, + которые смотрят ДРУГ НА ДРУГА. Вышло зеркально — меняй грань, а не `orientation`. + - **Первое сопряжение вешай на зафиксированную деталь.** Пока в цепочке нет ни одного + закреплённого звена, решатель волен двигать любое; связка «каждый новый компонент — к уже + стоящему на месте» разваливается вдвое реже, чем связка «все ко всем». +5. **`rebuild`,** если авто-валидация написала «ℹ Требуется перестроение». Это НЕ ошибка построения: + так помечает себя свежий компонент или только что наложенная связь. Бросать работу здесь не надо + — правило «не продолжай при ⚠» касается строки со знаком ⚠, а не этой. + **Исключение из правила «⚠ = стоп».** После КАЖДОГО сопряжения авто-валидация пишет + «⚠ N операц. в ошибке: „Сопряжения“ (код 0: ошибки нет)». Это то же «требуется перестроение», + только под знаком ⚠: код 0 и имя операции «Сопряжения» означают, что ломаться нечему. Делай + `rebuild` и иди дальше. Настоящая беда со связью видна не здесь, а в + `describe_model(sections=mates)` — по пометке `valid:false`. +6. **Проверь:** + - `describe_model(sections=components)` — origin, поворот ЧИСЛАМИ (`rx/ry/rz` в градусах, та же + семантика, что у вставки) и «зафиксирован/свободен» у каждого: этим и видно, КОГО и НА СКОЛЬКО + подвинул решатель; + - `describe_model(sections=mates)` — что с чем связано, с каким значением и не выродилось ли. + Это ключевой детектор: `assembly_add_mate` может ответить успехом, а связь окажется + вырожденной; + - `measure(kind1=face, index1=…, componentIndex1=…, kind2=face, index2=…, componentIndex2=…)` — + зазор между деталями напрямую, без арифметики по габаритам; + - `assembly_check_interference(componentIndex1, componentIndex2)` — **не налезли ли детали друг + на друга.** Проверяй все пары, которые должны идти впритирку. + +**Неудачную связь не нужно пересобирать с нуля:** `assembly_delete(target="mate"|"component", index)` +снимает сопряжение или компонент вместе с опирающимися на него связями. Индексы после удаления +сдвигаются — иди от больших к меньшим и перечитывай `describe_model(sections=mates)`. + +**Пересечение деталей не видно НИГДЕ, кроме `assembly_check_interference`.** Сборка складывается из +готовых тел, и КОМПАС их не вычитает: две детали могут занимать общий объём, а сопряжения при этом +останутся `valid`, раздел `errors` — пустым, объём экспорта — простой суммой компонентов. `measure` +тоже не спасает: нулевой зазор одинаково означает и касание, и взаимопроникновение. Проверяй все +пары, которые должны идти впритирку. + +**«Тела: 0» в сборке означает не «пусто», а «спрошено не то»:** тела принадлежат компонентам +(`describe_model(component=N, …)`), а `box` и `mass` без `component` честно дают габарит и МЦХ сборки +целиком. Про разные системы координат внутри паспорта компонента — +`help(topic="model-inspection")`; про локальные координаты граней и `pointOnFace` — +`help(topic="face-addressing")`. + +## Чертёж: оформить деталь по ГОСТ + +Чертёж строится не так, как деталь: **авто-валидации здесь нет**. Правило трёх проверок из §«Базовый +цикл» в 2D не работает — операция не отчитывается «построилось верно», потому что верность тут не +про геометрию, а про место на листе. Проверять приходится самому, и способ ровно один: посмотреть. + +**Порядок, который окупается:** + +1. **Деталь строится в чертёжной ориентации.** Набор видов задаётся ОТ модели: `mainOrientation` + выбирает, какую ориентацию модели показывает главный вид, но саму ориентацию модели он не + вращает. Если самая информативная проекция детали — не одна из шести стандартных, чертежа по + ГОСТ не выйдет; планируешь чертёж — строй эскизы так, чтобы главный вид попадал на плоскость + с наибольшей информацией. +2. **`drawing_set_sheet_format`** (формат до видов — иначе виды придётся двигать), при + необходимости `drawing_add_sheet` для второго листа. +3. **`drawing_create_standard_views(views=[…], mainOrientation=…, hiddenLines=…)`** — бери ровно те + проекции, которые нужны: лишний вид — лишнее место и лишний повод ошибиться видом. **Главный вид + входит в набор сам**: перечисленные коды — это проекции ОТНОСИТЕЛЬНО него, поэтому `views=["top"]` + даёт ДВА вида (главный и сверху). Ответ возвращает НОМЕРА видов, и дальше всё адресуется ими. +4. **Координаты — замером, а не формулой.** `drawing_get_view_info(viewNumber)` отдаёт паспорт вида + одним вызовом: положение на листе, масштаб, габарит и — главное — локальную СК: куда попадает + начало координат модели и куда смотрят её оси +X/+Y/+Z в координатах вида (нулевой орт = ось + проекции, вдоль неё вид смотрит). Этого хватает, чтобы пересчитывать точки модели в вид + арифметикой; отдельные точки переводит `drawing_project_point(x, y, z, viewNumber)`. + Выводить оси из головы не надо и вредно: у КОМПАС «спереди» показывает плоскость XY детали, а + «сверху» — X и **минус Z**, и **знаки инверсии зависят от `mainOrientation`** — формула, + выведенная на одном чертеже, на соседнем врёт. +5. **Разрез — до размеров, а не после.** Внутреннюю геометрию (зенковка, ступенчатое отверстие, + паз, глубокая расточка, полость) показывай разрезом, а не невидимыми линиями: по штриховой линии + нельзя ни поставить нормальный размер, ни разобрать форму. `drawing_add_section_view` — см. + §«Разрез» ниже. Размеры внутренней геометрии ставятся УЖЕ НА РАЗРЕЗЕ, поэтому строить его надо + раньше простановки, иначе размеры придётся переносить. +6. **Размеры**, `drawing_add_axis` (осевые и центровые), шероховатость, выноски, техтребования, + штамп. **Осевые сначала посмотри, потом добивай**: ассоциативные виды приходят со СВОИМИ + центровыми и осевыми, которые КОМПАС ставит сам, и `drawing_add_axis` вслепую даёт дубли поверх + существующих. Сначала `list_drawing_objects(kind="axis"|"centreMarker", viewNumber=…)`. +7. **`drawing_export_image`** — посмотреть глазами. Пока картинки не было, чертёж не сдан. + +### Разрез + +`drawing_add_section_view` делает всё сразу: проводит линию разреза на базовом виде и строит по ней +производный вид со штриховкой. Механика, ступенчатый разрез и встроенная проверка честности — +`help(topic="drawing-sections")`; здесь только решения, которые принимаешь ты: + +- **Разрез или `hiddenLines`.** Разрез — когда внутреннее нужно ИЗМЕРИТЬ или показать форму: + зенковка и цековка, ступенчатое или резьбовое отверстие, паз, канавка, глубокая расточка, тонкая + стенка полой детали. Невидимые линии — только намёк на то, что уже показано где-то ещё; размер к + штриховой линии не привязывают. +- **Веди линию с запасом за габарит** (плита 60 мм → от −40 до +40): линия по самому краю режет не + всю деталь. Координаты — в ЛСК БАЗОВОГО вида, её даёт `drawing_get_view_info`. +- **Строй разрез, когда модель готова**: после правки детали перестраивается только ПЕРВЫЙ разрез + базового вида. Модель всё же изменилась — снеси разрезы и построй заново. +- Сам разрез дальше — обычный вид: размеры и обозначения ставятся на него по его номеру. + +**Промах простановки лечится, а не остаётся навсегда.** Отката (undo) у чертежа нет, но +`list_drawing_objects` показывает обозначения с индексами, `drawing_delete_object` убирает одно, а +`drawing_move_object` его СДВИГАЕТ — слипшиеся тексты соседних размеров лечат именно сдвигом, а не +заменой размера на выноску. Так же правится и компоновка: `drawing_move_view` переставляет вид со +всеми обозначениями, `drawing_add_view` доносит недостающую проекцию, `drawing_delete_view` убирает +лишнюю. Пересоздавать документ ради компоновки не нужно. Подробности адресации и порядок удаления — +`help(topic="drawing-fixing")`. + +**Три вещи, на которых чертёж молча выходит неверным** — держи их в голове, детали в справочнике: + +- `viewNumber=0` — это НЕ главный вид, а координаты ЛИСТА; знак, поставленный «на главном виде» с + нулём, уезжает за границы формата (`help(topic="drawing-views")`); +- ассоциативны только диаметральный и радиальный размеры; линейный и угловой меряют координаты, и + «60» останется, когда деталь станет 70 — после правки модели перепроверяй их сам + (`help(topic="drawing-dimensions")`); +- допуск, не легший в размер, виден только по пустому read-back в ответе — техтребования его не + заменят (`help(topic="drawing-dimension-text")`). + +Ещё две ловушки, о которых узнаёшь только столкнувшись: штамп частично ведёт МОДЕЛЬ, а не чертёж +(`help(topic="drawing-title-block")`), и у цилиндрической грани нет «координат оси» — её +восстанавливают и проверяют сходимостью площадей (`help(topic="cylinder-axis")`). + +**Чего нет.** Выносного элемента (увеличенный фрагмент), МЕСТНОГО разреза внутри вида, местного +вида и вида с разрывом. Ассоциативного ЛИНЕЙНОГО размера нет и не будет: в API у него нет привязки к геометрии +ни под каким именем (проверено QI, поздним связыванием и размером с обрывом). Экспорта в PDF/DXF +тоже нет — наружу уходит растр (`drawing_export_image`) и STEP. + +## Работа с импортом / сборками + +Конвейер «импорт → разбор → извлечение детали → осмотр → модификация → экспорт»: + +1. **`import_model`** — `type` задаёт документ: `assembly` (по умолчанию) или `part`. + Формат берётся из расширения; `.prt` и `.asm` носят несколько САПР сразу — там задавай `format` + явно. Нужна отдельная деталь файлом — включай `createComponentFiles`: без него импорт не пишет + на диск ничего, кроме открытого документа. + Плоский чертёж (.dxf/.dwg) читает не он, а `import_drawing`. +2. **Разбор:** `describe_model(sections=components)` (у каждого компонента — origin, поворот, + фиксация) и `describe_model(sections=mates)`, если сборка пришла со связями; грани компонента — + `list_faces(component=N)`. Извлечённую деталь открывай самостоятельным документом. + Гашение видимости компонента на снимок **не влияет** — изоляция так не делается. +3. **Осмотр — структурно** (`describe_model`: какая ось «высота», МЦХ, топология). Снимок + `model_snapshot(view=…)` — ракурс выбирай по плоскости детали (плоскую смотри сверху или + спереди, не в изометрии); один и тот же `view` даёт воспроизводимый кадр «до/после». + **Пары ракурсов противоположны по оси:** `front` смотрит из +Z, `rear` — из −Z, так же + `top`/`bottom` и `left`/`right`. Следствие, которое нужно чаще всего: деталь, лежащая на столе + гранью Z=0 (эскиз на XOY, выдавливание вперёд), видна столу как **`rear`**, а `front` покажет + зеркальную картинку. Читаемость надписи или логотипа доказывают снимком с нужной стороны, а не + рассуждением. +4. **Модификация «тупой» B-rep** (итог — в ответе каждой операции): простой случай — `move_face`; + вставка N мм в призматическую ножку — `split_solid_by_plane` → `move_body` → `move_face` (мост) + → `boolean_union` (шаги пронумерованы в описаниях самих инструментов; цепочка проверена + end-to-end: проставка 39.45 → 41.45 мм, построение чистое). +5. **Перед выдачей:** последняя операция «Построение чистое» → `export_model` (STEP для обмена, + STL для печати). + +## Эвристики и подводные камни + +- **Правила 1 и 2 действуют всегда:** осмотр структурный; «⚠ N операц. в ошибке» — в STEP/печать + не брать. +- **Направление операции** (`extrude(forward)`, знак `distance` у `move_face`): на выбранной грани + зависит от ориентации её нормали — реши ДО построения, прочитав нормаль в `list_faces(index=N)` + (или по снимку), а после сверь сводку объёма в ответе. +- **Эскизы и операции адресуются ХЕНДЛАМИ из ответов** — `sk_7c1e5aa3f1_1_2`, `op_7c1e5aa3f1_1_5`. + Не сочиняй их и не передавай числа: числовая адресация не поддерживается, а сервер объяснит формат + отказом. Хендл живёт только в текущей сессии построения: смена активного документа + (create/open/close) и перезапуск сервера делают прежние хендлы **мёртвыми**, и они отказывают с + указанием причины — не молча, как раньше делали числовые id. Потерял хендл — читай + `describe_model(sections=tree)` и строй заново; сохраняйся перед долгими паузами. + Хендл — это НЕ индекс: `faceIndex`/`edgeIndices` из `list_faces`/`list_edges` и параметр + `feature` у `link_parameter`/`list_parameters` (имя или индекс узла дерева) остаются числовыми. + `primitive` и `hole` тоже возвращают хендл (у `hole` — по одному на КАЖДОЕ отверстие серии), + так что примитив и отверстие можно удалить `feature_delete` и размножить `pattern`/`mirror`. + Если ответ вместо хендла говорит «выдать не удалось» — операция построена, но адресовать её + нечем: переставить её потом можно только пересборкой. +- **Единицы — мм** (геометрия) и **кг** (масса). Локальные координаты эскиза ≠ мировые координаты + модели. +- **Одинаковая ошибка у ВСЕХ инструментов — это транспорт, а не КОМПАС.** «Unable to connect…», + таймаут или пустой ответ на `kompas_connect`, `kompas_status` и `describe_model` одновременно + означают, что до MCP-сервера не дошёл ни один байт: перебирать инструменты и «пробовать ещё раз» + бесполезно. Один-два подтверждающих вызова — и сдавай задачу как заблокированную, назвав, что + именно не отвечает. Отдельный признак того же — сообщение без имени инструмента и без слова + «КОМПАС»: наши ошибки всегда называют операцию и причину. + +## Когда КОМПАС общий + +По умолчанию (`instance="shared"`) сервер работает в том же экземпляре КОМПАС, что человек и другие +агенты, а **активный документ там один на всех**. Два симптома, которые легко принять за свою +ошибку: операция ушла в чужую деталь (кто-то создал документ — активность переехала), либо твой +документ исчез, потому что сосед вызвал `document_close(all=true)` — тот закрывает ВСЁ и без +сохранения. + +- **Строишь параллельно с кем-то — `instance="private"`** при первом `kompas_connect` (потом режим + не сменить). Свой экземпляр: активный документ только твой, окно скрыто (`kompas_set_visible true` + покажет). +- **`shared` оставляй**, когда работа идёт на глазах у человека и ты единственный агент. +- **Один файл в двух экземплярах не открыть** — второй получит его только на чтение: работу делите + по файлам, а не по вкладкам. + +## Открытые вопросы / границы + +- **Параметрика работает через параметры ОПЕРАЦИЙ, а не размеры эскиза** — сдвинуть контур + переменной нельзя, только пересобрать эскиз. Планируй членение так, чтобы изменяемое задавалось + параметром операции (глубина, радиус, габарит примитива), а не координатами в эскизе. +- **2D покрыт вместе с разрезом и сечением.** Есть виды (с выбором набора, ориентации главного и + невидимых линий), разрез/сечение, листы, штамп, размеры с допусками, осевые, обозначения, + техтребования, удаление и сдвиг объекта, вывод в растр — методика в §«Чертёж». Нет выносного + элемента, местного разреза внутри вида, местного вида и вида с разрывом. +- **Разрез не переживает правку модели, если он не первый на своём базовом виде.** Замерено: + обновляется только ПЕРВЫЙ, остальные молча остаются со старой геометрией, и ни одно перестроение + этого не чинит. Порядок один: сначала модель, потом разрезы. +- **Вставку фрагмента правят только целиком** (заново `fragment_place`). Экспорт наружу — растр и + STEP; DXF/DWG и PDF не пишутся. +- **SVG сервер не читает** — и не будет: разбор путей, деление кривых Безье на дуги и разбор + вложенности контуров живут во внешнем конвертере, а серверу достаётся готовый список примитивов. + +## Связанное + +- Проверка окружения (КОМПАС установлен, сервер запускается, подключение живое): команда **`/kompas:doctor`**. +- Установка, требования и настройка сервера: README плагина. +- Правила проектирования под FDM/FFF-печать: навык **`kompas-fdm-design`**. diff --git a/plugin/skills/kompas-3d/reference/text-and-relief.md b/plugin/skills/kompas-3d/reference/text-and-relief.md new file mode 100644 index 0000000..13e92cf --- /dev/null +++ b/plugin/skills/kompas-3d/reference/text-and-relief.md @@ -0,0 +1,117 @@ +# Надписи и рельеф — точная подгонка и отделка + +Дополнение к разделу «Надписи, логотипы и рельеф» SKILL.md. Здесь — замеры и приёмы для точной +компоновки надписи (подгонка кегля и ширины, поведение каймы, стыковка блоков) и отделки рельефа. +Все числа получены пробами на конкретных начертаниях (Lobster, Bevan, Zilla Slab): это порядок +величины и форма зависимости, а не константы — свои значения перезамеряй на своём шрифте, +`widthFactor` и `thinThickness`. + +## Подгонка ширины и кегля + +- **`widthFactor` меняет пропорцию крупно, `height` — точно.** Замер (Lobster «OldMan», h=17): + wf 1.00 → 71.84 мм, wf 1.25 → 92.83 (+29 %) — то есть это настоящий масштаб ширины, и без него + скриптовый шрифт в вытянутое поле не вписать. Но КОМПАС **квантует его ступенями**: wf 1.25, + 1.26, 1.27, 1.28 дают ячейку 100.64 и ширину 92.83…93.14 (+0.3 %), а на 1.29 ячейка прыгает на + 103.34 и ширина сразу 95.49 (+2.5 %). Отсюда правило: пропорцию задаёшь `widthFactor`, точную + ширину добираешь `height` — подгонка через wf топчется на ступени. +- **`height` двигает ширину плавно, а высоту — ступенями.** Замер (Lobster «OldMan», wf 1.18): + h 17.00 → глифы 85.37 × **17.07**; h 16.94 → 85.11 × **17.07** (ширина отозвалась, высота нет); + h 16.50 → 82.90 × 16.54; h 15.50 → 77.95 × 15.60. Значит подгонять ширину кеглем можно, но + **вертикаль по нему не считается**: после пересчёта перечитай фактический габарит из ответа и + привязывай верх/низ блока ТОЧКОЙ ВСТАВКИ, а не кеглем. +- **Кегль под заданный габарит считается за ОДНУ пробу, а не подбирается.** При фиксированном + `widthFactor` прирост каймы Δ (сумма по обеим сторонам) от кегля не зависит — фигура подобна. + Значит: построил пробу с любым `height₀`, замерил ширину глифов `W₀` и суммарный прирост Δ, + дальше `height = height₀ · (W_цель − Δ) / W₀` — и целевой габарит получается с первого раза. + **Δ бери только из СВОЕЙ пробы — на том же шрифте, `widthFactor` и `thinThickness`.** Числа из + этого файла (Lobster: Δ=4.62 при t=1.5/wf 1.29; Δ=4.93 при t=1.6/wf 1.18; Δ=2.92 при t=0.9/wf 1.33) + приведены как порядок величины, а не как константа: подставив чужое Δ, промахнёшься на проценты + по ширине — а именно её ты и подгоняешь. +- **Шаг второй, без которого формула обманывает: проверь ВЫСОТУ, которая из неё вышла.** Кегль + подобран по ширине, но вместе с ним задалась и высота блока букв — а от неё зависит, дотянется ли + кайма до плашки. Считай до построения: `низ каймы = низ глифов − t`, и он обязан зайти на плашку. + Замер (Lobster «OldMan», целевая ширина 90, кайма t=1.5): при `wf 1.29` формула даёт ровно + 90.00 по X и глифы высотой 15.2 → низ каймы 11.77 против верха плашки 10.5, **разрыв 1.27 мм**, + деталь распалась бы на два тела; при `wf 1.18` — глифы 17.07 → низ каймы 9.93, **перекрытие + 0.57 мм**, одно тело. Отсюда рабочее правило: **`widthFactor` — ручка не пропорции, а стыковки.** + При фиксированной целевой ширине больший `wf` даёт более низкий блок букв, и вертикаль + проигрывается: сначала подбери `wf` так, чтобы высота блока перекрыла плашку, и только потом + добирай точную ширину кеглем. + +## Кайма (тонкая стенка вокруг букв) + +- **Кайма на острых терминалах шире `thinThickness` — и по каждой стороне по-своему.** Стенка + `outward` обходит контур с миттером: на остром окончании глифа габарит растёт **на сторону** на + `t / sin(θ/2)`, а не на `t` (Lobster: слева +0.90 при t=0.9, справа +1.70 — терминал «n»). + Величина принадлежит не шрифту, а КОНКРЕТНОМУ начертанию и толщине стенки, поэтому у каждого + числа держи в уме пару (t, wf): Lobster «OldMan» при t=0.9 дал слева +0.90 / справа +1.70 при + wf 1.18 и +0.90 / +2.09 при wf 1.40; при t=1.5 — +1.50 / +3.12. Общее в них одно: **сбоку + прирост равен t, а на остром терминале — t/sin(θ/2)**, и переносить абсолютные числа между + вариантами нельзя — перезамеряй после смены `widthFactor` или `thinThickness`. +- **По вертикали кайма прибавляет ровно 2·t.** Сверху и снизу глифов миттера нет (касательные + ровные), поэтому высота блока = высота глифов + 2·t считается точно, без пробы; замером это + подтверждается на всех вариантах (t=0.9 → +1.80). Мерить нужно только ширину. +- **`align`/`vAlign` центруют ГЛИФЫ, а кайма несимметрична — значит центр надо считать.** Просьба + «поставить надпись по центру поля 90 мм» через `align="center", x=45` даёт силуэт, съехавший на + полразницы приростов: у Lobster при t=1.5 слева +1.50, справа +3.12. Целься не в центр поля, а в + тот X, при котором СИЛУЭТ ляжет в поле: `x = (Δ_лев + (L − Δ_прав)) / 2`. Замер: (1.50 + 90 − + 3.12)/2 = 44.19 → глифы 1.50…86.88, силуэт с каймой ровно 0…90.00. То же и по вертикали, только + там прирост симметричен (t сверху и снизу), поэтому `vAlign="top"` в `верх поля − t` попадает без + поправки. +- **Толщина каймы — ещё и параметр стыковки блоков.** Кайма опускает силуэт надписи ниже её + глифов на `t`, и именно это перекрытие с плашкой держит деталь одним телом. Считай так: низ + каймы = низ глифов − t, и он должен зайти на плашку хотя бы на несколько десятых. Проверка — + сводка «Тел:» в ответе самого `primitive(union)`. +- **Кайма вокруг ПРЯМОУГОЛЬНОЙ плашки — вторым примитивом, а не тонкой стенкой.** Стенка обходит + контуры эскиза, а плашка по playbook'у строится `primitive`, и каймы у неё не появится. Клади под + неё второй блок на `2·t` больше и на высоту подложки (85 × 13.5 × 2 под плашкой 82 × 10.5 × 3) — + получается тот же кант. Сводить прямоугольник в один эскиз с буквами не надо: контуры пересекутся, + и эскиз станет невалидным. + +## Разрядка (трекинг) + +- **Разрядки (трекинга) у примитива нет — её набирают пробелами.** Ширину пробела для конкретного + шрифта и кегля вычисляют двумя пробами: «EDITION» → 38.38 мм, «E D I T I O N» → 47.11 мм, + значит пробел 1.455 мм (Bevan, cap 5.5). + +## Отделка рельефа и соседняя геометрия + +- **Пакетом по контуру рельефа не строится СКРУГЛЕНИЕ — ни сверху, ни на малом радиусе; фаска + строится по обоим контурам.** Скругление: на Zilla Slab «AB» (203 ребра) одиночное верхнее ребро + берёт R0.1 и R0.2, а `fillet_edge` сразу по всем отказывает при обоих радиусах — соседние + скругления конфликтуют; уменьшение радиуса не спасает (Lobster, 135 верхних рёбер: отказ и при + R0.3, и при R0.15). Фаска: `chamfer_edge(edgeIndices=[…])` проходит с первой попытки и по низу + (0.3 на 59 и на 120 рёбрах), и по ВЕРХУ рельефа (0.2 на 135 рёбрах букв, отдельно 0.2 на 133 + рёбрах канта плашки с надписью) — прямые, NURBS, дуги и огрызки 0.03 мм вперемешку. Значит + притупление кромок по всему силуэту, хоть снизу против «слоновьей ноги», хоть сверху по + требованию чертежа, — это ОДНА операция, и делается она фаской. Рёбра берутся окном: + `list_edges(minZ=-0.01, maxZ=0.01)` — низ, `list_edges(minZ=h-0.01, maxZ=h+0.01)` — верх (сузить + до нужной части силуэта помогает `minY`/`maxY`). **Порядок «сначала скругления углов, потом фаска» + работает** — дуги от R0.5 фаске не мешают. В отборе встречается тип `other` (у сложных кривых) — + он тоже принимается параметром `type`. +- **Отказ фаски на НЕЧИЩЕНОМ контуре — не повод уменьшать катет: попробуй УВЕЛИЧИТЬ.** Успех + немонотонен по размеру. На контуре логотипа (54 ребра низа, острые клинья между элементами) + `chamfer_edge` отказывает при 0.4, 0.5, 0.6 и 0.7 и проходит при **0.8** — проверено подряд, + с `rebuild` между попытками и на неизменных индексах рёбер. Похоже, малый катет оставляет в остром + клине вырожденный «нос», который КОМПАС сшить не может, а большой срезает остриё целиком. + **Но это верно ТОЛЬКО пока контур не почищен**, и полагаться на такой подбор не нужно: правильное + лечение — `minSegment` (см. SKILL.md §«Надписи, логотипы и рельеф»), а не перебор катета. + Замер на том же логотипе: почищенный порогом 0.5 контур (34 примитива) фаску **0.5 принимает**, + а эталонные **0.8 отвергает** — рабочий диапазон катета сдвигается ВНИЗ вместе с узким местом + (1.98 → 1.82 мм). После чистки совет «попробуй увеличить» уже вреден. + Прежняя формулировка добавляла «исключение самых коротких рёбер картину не меняет, то есть дело + не в них» — вывод неверен: исключённое из `edgeIndices` ребро остаётся в теле, и это не то же + самое, что убрать сегмент из контура. Убранный из контура — меняет. +- **`primitive(subtract)` режет ВСЁ, что попало в его габарит — включая уже построенные буквы.** + Сверять надо **глифы, а не кайму**, и только те, что дотягиваются до кармана ПО ВЫСОТЕ: карман + обычно вычитается от z основания вверх (например от 2 до 3), а кайма ростом всего 2 мм в этот + слой не попадает — она может сколько угодно перекрывать плашку в плане, и именно это перекрытие + держит деталь одним телом. Опасны буквы: они идут на всю высоту 3 мм, поэтому их нижняя кромка + по Y должна быть выше верхней кромки кармана. Проверка постфактум — **точное равенство убыли + объёма** расчётному (79 × 7.5 × 1.0 = 592.5 против фактических 592.5 мм³): объём приходит в + сводке ответа самой операции, любое касание соседней геометрии сразу ломает равенство, а + габарит и снимок его не покажут. +- **Углы вокруг надписи — одним `fillet_edge(points=[…])`.** На теле с сотнями рёбер список из + `list_edges` неподъёмен, но точки углов известны из построения: передай их списком, и все рёбра + уйдут в ОДНУ операцию дерева. Если ребра в части точек нет (типичный случай — угол «съеден» + каймой букв), ошибка перечислит ВСЕ такие точки сразу: убери их и повтори одним вызовом. diff --git a/plugin/skills/kompas-fdm-design/SKILL.md b/plugin/skills/kompas-fdm-design/SKILL.md new file mode 100644 index 0000000..c2ba55e --- /dev/null +++ b/plugin/skills/kompas-fdm-design/SKILL.md @@ -0,0 +1,121 @@ +--- +name: kompas-fdm-design +description: > + Методика проектирования деталей под FDM/FFF 3D-печать в КОМПАС-3D через MCP-сервер плагина: + правила DFM (нависания и угол θ_max, толщины стенок n·w, отверстия и teardrop, + посадки/зазоры, ориентация под прочность, elephant foot, бобышки/инсёрты/защёлки) ПЛЮС + лёгкая самопроверка геометрии инструментами осмотра. Используй, когда задача — спроектировать + или ДОВЕСТИ деталь, чтобы она хорошо ПЕЧАТАЛАСЬ на FDM. Триггеры: «сделай деталь + печатнопригодной / под FDM», «спроектируй … под печать», «напечатается ли без поддержек?», + «подбери зазоры для печатной посадки», «как ориентировать деталь под печать», «почему деталь + плохо печатается / где будут нависания», «доведи деталь под FDM». Строит через навык kompas-3d. + НЕ для: механики построения через MCP (это kompas-3d); слайсинга/нарезки/g-code (вне границ). +--- + +# kompas-fdm-design — проектирование деталей под FDM-печать + +## Что это (и чем НЕ является) + +Методический слой **поверх** навыка `kompas-3d`. Отвечает на вопрос **«как спроектировать, чтобы +напечаталось на FDM»**, а не «чем строить». + +- **`kompas-3d`** = *чем и как строить* через MCP (эскиз→операция→осмотр→проверка построения). Этот + навык **опирается** на него для механики. +- Этот навык = *какие правила геометрии* соблюдать, чтобы FDM-печать удалась. +- **Слайсинг — вне границ.** Навык не нарезает и не оценивает g-code. + +## Когда применять / когда НЕ применять + +**Применять:** «сделай печатнопригодным / под FDM», «спроектируй … под печать», «напечатается без +поддержек?», «подбери зазоры печатной посадки», «как ориентировать под печать», «почему плохо +печатается», «доведи деталь под печать». + +**НЕ применять:** чистая механика построения (→ `kompas-3d`); слайсинг/нарезка/g-code (вне границ). + +## Калибровка (выполни первым шагом) + +Все правила масштабируются от трёх параметров (часть значений — абсолютные эмпирические мм, +помечены «калибровать тестом»): + +- **`w` = ширина линии ≈ диаметр сопла.** Дефолт: сопло 0.4 → `w ≈ 0.4–0.45 мм`. → стенки `n·w`. +- **`h` = высота слоя.** Дефолт `h ≈ 0.5·сопло` (0.2 мм); структурная печать 0.2–0.25. +- **`θ_max` = предельный угол самонесущей поверхности ОТ ВЕРТИКАЛИ.** `θ_max ≈ arctan(w/2h)` + (≈45° при `w`=0.4, `h`=0.2). **Дефолт 45°** (PLA, хороший обдув); **40°** для PETG/ABS + (эмпирическая поправка на провис, не вывод формулы) или для толстого слоя (`h≥0.3` → формула + даёт ~34°). Нависания, teardrop, фаски, зенковки берут угол из `θ_max`. +- **Материал** (PLA / PETG / ABS) — модификатор зазоров/мостов/коробления/`θ_max`. См. + `references/fdm-rules.md`. + +Если сопло/слой/материал не заданы — прими дефолты (сопло 0.4, `h`=0.2, PLA) и скажи об этом. + +## Два правила (соблюдай всегда) + +**1. Ориентация печати — первое проектное решение.** +- **Спроси у пользователя** (если не задано): главное направление рабочей нагрузки и + косметические/критичные грани. **Путь нагрузки из геометрии не выводится** — его задаёт задача. +- Реши постановку на стол (ось Z = рост слоёв). От неё зависит: где нависания; куда смотрят + отверстия (вертикальные → компенсация Ø; горизонтальные → teardrop); путь нагрузки (**держи в + XY**; Z-сжатие можно, Z-растяжение/срез — нет); плоскости сопряжения (на XY-гранях); «лесенка» на + наклонных функциональных поверхностях; если поддержки неизбежны — чтобы опорные грани были + некритичными/скрытыми. +- Зафиксируй ориентацию и проектируй под неё. + +**2. Чек-лист печатнопригодности перед выдачей** (ниже). Сначала **валидность построения** (её +дописывает к ответу каждая операция, см. `kompas-3d`; вручную — `describe_model(sections=errors,bodies,mass)`), затем +**FDM-чек-лист** (деталь *печатнопригодна*) — разные проверки. **Гео-аудит +эвристический и не доказывает печатнопригодность** (не ловит путь нагрузки/анизотропию). + +## Рабочий цикл + +1. **Калибровка**: сопло→`w`; слой→`h`→`θ_max`; материал→поправки. +2. **Ориентация** (правило 1): опрос (нагрузка/косметика) → постановка, ось слоёв, сопряжения, + «лесенка», поддержки. +3. **Правила эскиза/операции** (строй через `kompas-3d`): стенки `n·w`; нависания → скос под + `θ_max`; горизонтальные отверстия → teardrop; вертикальные → компенсация Ø; фаска у основания; + зазоры посадок (со знаком); заходные фаски; мин. элементы/текст; бобышки/инсёрты/защёлки. + Числа — в `references/fdm-rules.md`. +4. **Гео-аудит** (`references/geometry-audit.md`) — инструментами осмотра. +5. **Предусловия экспорта**: единое тело/манифолд (`boolean_union` при необходимости) → + построение чистое. +6. **Чек-лист** → экспорт **через `export_model`**: слайсеру нужен `.stl` + (`export_model(path="…​.stl")` — двоичная сетка), а `.step` остаётся для передачи модели в САПР. + +## Чек-лист печатнопригодности + +- [ ] Направление нагрузки и косметические грани **получены от пользователя**; ориентация + зафиксирована; нагрузка в XY (или Z только на сжатие); сопряжения на XY-гранях. +- [ ] Стенки кратны `w` (≥2·w; несущие ≥3·w, т.е. 3 периметра); нет «не кратных `w`» (кроме + функциональных). +- [ ] Нет 90°-полок; нависания ≤`θ_max` или заменены скосами; мосты в пределах пролёта по короткой + стороне (числа — `references/fdm-rules.md`); внутренним поддержкам — доступ. +- [ ] Горизонтальные отверстия — teardrop/D (геометрия из `θ_max`); вертикальные — компенсация Ø; + глухие — дно ≥2–3 мм. +- [ ] Фаска у основания (elephant foot); внутренние углы ≥R0.5; опорная площадка есть. +- [ ] Посадки по таблице со **знаком** (натяг — вычесть); допуск ±0.2 **НЕ** прибавлен к зазору; + заходные фаски на сопряжениях. +- [ ] Мин. элементы/текст ≥ порогов; аспект тонких выступов ≤4–5×. +- [ ] Бобышки/инсёрты (бор отверстия ≤ OD инсёрта, ставить с Z-грани)/резьба/защёлки (изгиб в XY) по правилам. +- [ ] Полости — дренаж/вент; критичные поверхности не под «лесенкой»/поддержкой. +- [ ] Предусловия экспорта: единое тело/манифолд; построение чистое. + +## Гео-аудит (кратко) + +Лёгкая самопроверка построенной модели **существующими** инструментами осмотра MCP: +`describe_model` / `list_faces` / `list_faces(index=N)` (нависания по нормалям нижних граней; цилиндры с +горизонтальной осью → нужен teardrop), `describe_model(sections="box")` (как ось слоёв соотносится с габаритом), +`measure` (номиналы/зазоры), `describe_model(sections="bodies")` + чистое построение (единое тело). **Границы и методика — +`references/geometry-audit.md`.** Аудит эвристический; истинная мин. толщина стенки и полный детект +криволинейных нависаний не решаются — это **не приговор и не доказательство печатнопригодности**. + +**Просвет канала и толщину перемычки спрашивают, а не считают.** `measure(kind1="body", index1=0, +kind2="body", index2=1)` даёт минимальное расстояние между телами целиком — не нужно угадывать, какие +именно стенки сближаются. Ответ включает координаты двух ближайших точек, то есть показывает, *где* +узко. Сравнивайте с 2·w (два прохода сопла): канал уже этого не пропечатается, а найти его арифметикой +по эскизу — значит найти его случайно. То же для двух конкретных стенок: `kind=face` с индексом из +`list_faces` или с точкой на грани (`x1,y1,z1`). + +## Связанное + +- Полный численный свод DFM: [`references/fdm-rules.md`](references/fdm-rules.md). +- Рецепты самопроверки и границы: [`references/geometry-audit.md`](references/geometry-audit.md). +- Механика построения через MCP: навык **`kompas-3d`**. diff --git a/plugin/skills/kompas-fdm-design/references/fdm-rules.md b/plugin/skills/kompas-fdm-design/references/fdm-rules.md new file mode 100644 index 0000000..523a967 --- /dev/null +++ b/plugin/skills/kompas-fdm-design/references/fdm-rules.md @@ -0,0 +1,179 @@ +# Свод правил DFM для FDM-печати + +> Выверено 3 ревью (pi/glm-5.1, pi/kimi-k2.6, Codex). Числа для `w≈0.4–0.45`, `h≈0.2` (сопло 0.4). +> **Зазоры — на сторону (радиальные)**; диаметральный = 2×. **Угол нависания — от вертикали** +> (вертикаль=0°, горизонталь=90°); самонесущие — ≤ `θ_max`. Параметры `w`/`h`/`θ_max` — см. +> SKILL.md → «Калибровка». Ссылки «§N» ниже — на разделы этого файла. + +## 1. Стенки и оболочки +- Толщина стенки = **`n · w`**. Мин. конструктивная — **2·w (~0.8 мм)**; несущая — **≥3·w**. +- **Маппинг стенка→периметры:** нужно `N` периметров ⇒ стенка **≥ `N·w`** (при `w`=0.45: 3 → 1.35, + 4 → 1.8, 5 → 2.25 мм). +- **Не задавай толщину стенки, не кратную `w`** (напр. 0.6 при `w`=0.45): слайсер оставит зазор + или переэкструдирует. Прыгай на следующий кратный. +- **Caveat:** `n·w` — для конструктивных стенок; внешняя функциональная величина (флексура, + тепловой барьер, посадочный размер) важнее кратности. +- Одиночная стенка `1·w` — только декоративная. Узкий сквозной прорез — **≥2·w (~0.8 мм)**. + +## 2. Нависания, полки, мосты (разделять!) +- **Самонесущие — поверхности ≤ `θ_max` от вертикали.** Зона 45–60° (т.е. **выше** `θ_max`=45° при + дефолте) — ещё печатается, но с падением качества; **> `θ_max` существенно — поддержки** → + избегать редизайном. +- **90°-полка (консоль, опора с одной стороны) НЕ печатается ни на какой длине** (миф «≤6 мм» + неверен — провисает с первого слоя). Любую горизонтальную полку: **скос под `θ_max`**, либо + **превратить в мост** (две опоры), либо поддержка. +- **Мост (bridge) — пролёт между двумя опорами на одной высоте.** При достаточном обдуве, `h≈0.2`, + консервативно (для ненастроенного слайсера): **PLA ~15–25 мм, PETG ~10–15 мм, ABS ~12–18 мм**. + Длинные прямоугольные проёмы **ориентировать так, чтобы мост шёл по короткой стороне**; концы — + на сплошных опорах. +- Нижнюю функциональную поверхность моста — припуск **0.2–0.3 мм** на провис. *Граница:* величину + провиса из CAD не предсказать (обдув/скорость — настройки печати). +- **Внутренние/потолочные нависания хуже наружных** — потолок пазов аркой/шевроном, не плоским + пролётом > 2 мм. +- **Доступ к поддержкам:** окно во внутренней полости **≥8–10 мм**. + +## 3. Отверстия +- **Вертикальные (ось ∥ Z)** печатаются уже номинала → **увеличить диаметр модели** (радиус на + половину): **+0.2 мм (Ø<4)**, **+0.2–0.3 мм (Ø 4–10)**, **+0.1–0.2 мм (Ø>10)**; калибровать, + критичные — рассверливать. +- **Горизонтальные (ось в XY)** → **teardrop** или **D-отверстие** (плоский верх). Мин. Ø **2 мм**. + Круглая часть тоже печатается уже → **+0.1–0.2 мм** к её Ø. +- **Геометрия teardrop:** боковины касательны окружности под углом `θ_max` к вертикали (с двух + сторон), сходятся в вершине на вертикальной оси. Высота вершины над центром = **`r / sin θ_max`**; + включённый угол при вершине = **`2·θ_max`**. При `θ_max`=45° → `r/sin45° = √2·r ≈ 1.414·r` над + центром (= **0.414·r над верхом окружности**), угол 90°. Низ — оставшаяся дуга окружности. +- **Глухое отверстие:** дно = внутренний мост → **толщина дна ≥2–3 мм** или купольное/ + вентилируемое. Сквозные предпочтительнее. +- **Отступ от края** — через остаточную перемычку: стенка между отверстием и краем **≥2–3·w** + (лёгкая нагрузка) / больше под крепёж. + +## 4. Посадки и зазоры (печатная деталь ↔ печатная деталь) +Зазор **на сторону** (радиальный); диаметральный = 2× значения: + +| Посадка | Зазор/сторону | Примечание | +|---|---|---| +| Натяг (press) | **−0.05…0 мм** (вычесть из номинала!) | короткий, PLA; иначе snap-fit (§14) | +| Переходная/плотная | 0.05–0.15 мм | | +| Скользящая | 0.15–0.20 мм | PLA↔PLA; контакт ≥20 мм → 0.20; PETG +0.05 | +| Свободная | 0.25–0.35 мм | >0.35/сторону — уже очень слабо | + +- **Знак:** «натяг» = **отрицательный** зазор → вычесть из номинала (вал +/отверстие −). + Положительное число в строке press — ошибка прочтения. +- **ABS↔ABS:** +0.05/сторону. **PETG:** прессовые со временем «расслабляются». +- **Допуск точности (НЕ прибавлять к посадкам):** общий разброс FDM — **XY ±0.2 мм** (±0.1 + калибровано), **Z хуже**. Это точность изготовления, не добавка к зазору. + +## 5. Первый слой / стол +- **Elephant foot** — от притирки первого слоя (низкий Z-offset/переэкструзия; НЕ от высоты слоя). + Фаска по нижним рёбрам: **0.3 × 45° (калибровано)** / **0.5–1.0 × 45° (слабая калибровка)**. +- Внутренние углы у основания — **скругление ≥R0.5**. +- **Опорная площадка:** без «лезвийных» оснований; контакт хотя бы ~3 периметра. Высокие тонкие + детали — **интегральный фланец 1–2 мм** (предпочтительнее brim). + +## 6. Ориентация и прочность +- **Z (межслойная) прочность от XY:** PLA ~40–55%, PETG ~35–50%, **ABS ~20–35% (выброс)**. Несущую + нагрузку — в **XY (вдоль слоёв)**. +- **Z-сжатие допустимо** (слои в сжатии не расслаиваются); избегать **Z-растяжения и Z-среза**. +- Изгиб: слои в растяжении/сжатии, не на срез по линии слоя. +- Z-нагрузка неизбежна → **увеличить несущее сечение** ~×2 относительно XY-расчёта. +- Плоскости сопряжения — на **XY-гранях**, не на Z-боковинах. + +## 7. Минимальные элементы и текст +- Выступ/штифт/ребро — **≥1·w (≥0.5 мм)**; паз/щель — **≥2·w (~0.8 мм)**. +- **Аспект тонких выступов:** высота ≤ ~4–5× базовой ширины; выше — конусность/раскос/редизайн. +- **Выпуклый** текст: штрих **≥0.5 мм**, высота **≥2·h (~0.4 мм)**, sans-serif bold. +- **Гравированный** текст: штрих **≥2·w (~0.8–0.9 мм)** (нужно ≥2 периметра; 0.6 мм не влезает), + глубина **≥2·h (~0.4 мм)**. (pt не используем — геометрия в мм.) + +## 8. «Лесенка» (staircase) — критерий ориентации +- Наклонные/криволинейные поверхности дают ступени: глубина ≈ **`h / tan(α)`** (α — угол от + **горизонтали**; не путать с `θ_max`, который от вертикали). Пример: α=30°, `h`=0.2 → ~0.35 мм. +- Критичные (скользящие/уплотняющие/оптические) поверхности **ориентировать вертикально или + горизонтально**. Это вход в правило ориентации (SKILL.md, правило 1). +- Большой плоский **верх** без опоры коробит («подушка») — внутренние рёбра каждые ~15–20 мм или + достаточная толщина верха. + +## 9. Бобышки, инсёрты, резьба +- **Саморез/винтонарезной** пилот (M3): ~Ø2.5 PLA / Ø2.6 PETG / Ø2.7 ABS; заход ≥3 мм. +- **Термоинсёрт латунный** (M3): бор **по даташиту** (типично ~Ø4.0, ±0.05); **`Ø_bore = OD_инсёрта − (0…0.1) мм`** (≤ OD, лёгкий натяг под расплав — НЕ больше OD); стенка бобышки **≥2 мм**; глубина = длина инсёрта + 0.5 мм; **ставить с верхней (Z) грани** (не в боковину). +- **Бобышка под винт:** OD ≥ 2–3× Ø винта; не делать массивный сплошной объём (карман/оболочка). +- **Сквозное под металлический болт:** радиальный зазор 0.2–0.3 → **+0.4–0.6 мм к номиналу** болта. +- **Резьба:** не моделировать ~½ толщины стенки** сам даёт + нависание > `θ_max` → тогда фаска/ступень. +- **Внутренние углы — всегда скругление ≥R0.5**. + +## 11. Зенковки / цековки +- **Цековка (counterbore)** — большим Ø/полостью **вверх** (дно по телу, не мостом); глубина +0.3 мм. +- **Зенковка (countersink):** конус **вверх**; включённый угол **≤90°** → стенки ≤45° от вертикали + печатается; **>90°** → стенки-нависание → поддержка или замена цилиндрической цековкой. + +## 12. Заходные фаски (assembly relief) +- На штифтах, отверстиях, инсёртах, защёлках, «ласточкиных хвостах» — **заходная фаска** (≈0.5–1 мм + × 45° или ≈ половина зазора) против задиров при сборке. + +## 13. Разбиение детали и сборка из печатных частей +- Конфликт «прочная ориентация vs бесподдержечность», или крупная/коробящаяся деталь → **разбить** + на части с самоустанавливающимися стыками (печатные штифты/шпонки/замки), склейка; стыки на + XY-гранях. Зазор стыка — по §4. + +## 14. Защёлки (snap-fit) / живой шарнир +- Консольная защёлка: толщина балки **≈1.0–2.0 мм** (функциональный размер, не привязан к кратности + `w`; тоньше ~1 мм — хрупко), зацеп/возврат **0.3–0.8 мм**, длина/толщина **≥5:1** (до 10:1), + **скругление в основании ≥R0.5**. +- **Направление слоёв:** балка гнётся **в плоскости XY** (слои перпендикулярны изгибу), **не + поперёк Z** (расслоится с первого нажатия). +- **Живой шарнир** — только PLA/PP-подобные, перемычка **0.3–0.5 мм**; PETG/ABS не годятся. + +## 15. Коробление (геометрия) +- Большие плоскости (>80×80, особенно ABS): скругления углов R3–5 + рёбра/решётка снизу. +- Радиус внешних углов: R2 (ABS) / R1 (PLA/PETG). +- Длинные тонкие пролёты (>60 мм, <2 мм) — рёбра/косынки каждые 30–40 мм; высота ребра ≤5× базы. +- Избегать сплошных кубов/плит → карман/оболочка + рёбра. Усадка: PLA ~0.3%, PETG ~0.5%, ABS ~0.8%. +- Симметрия геометрии уравновешивает усадку. +- *«Мышиные уши» (Ø8–10 мм по углам)* — **крайняя мера адгезии** (по сути brim-геометрия); + предпочтительно интегральный фланец/скругления углов. +- *Граница:* стол/корпус/обдув для ABS — настройки печати, вне навыка; здесь только геометрия. + +## 16. Полые детали и гигиена модели +- **Полости:** дренаж Ø3–5 мм у **низшей** точки + вент у **высшей**. +- Допуски/зазоры — **в геометрию** (слайсер читает модель буквально). +- Раздельные тела — зазор ≥0.2 мм (общая CAD-гигиена; перед выдачей объединять — рабочий цикл, + шаг 5 в SKILL.md). diff --git a/plugin/skills/kompas-fdm-design/references/geometry-audit.md b/plugin/skills/kompas-fdm-design/references/geometry-audit.md new file mode 100644 index 0000000..1a63497 --- /dev/null +++ b/plugin/skills/kompas-fdm-design/references/geometry-audit.md @@ -0,0 +1,33 @@ +# Гео-аудит модели под FDM — что проверяемо инструментами осмотра + +Лёгкая самопроверка построенной модели **существующими** инструментами осмотра MCP. Запускать на +шаге 4 рабочего цикла (см. SKILL.md), перед чек-листом и экспортом. + +## Что проверяемо + +| Проверка | Как | Статус | +|---|---|---| +| Нависания (приближённо) | `list_faces`, затем `list_faces(index=N)`: для **нижних** граней угол поверхности от вертикали; > `θ_max` → флаг | ✅ плоские; ⚠️ криволинейные грубо | +| Ориентация (геом. прокси) | `describe_model(sections="box")`: как ось слоёв соотносится с габаритом | ⚠️ длинная ось ≠ путь нагрузки | +| Горизонтальные круглые отверстия | `list_faces(index=N)`: цилиндр с горизонтальной осью → «нужен teardrop» | ✅ | +| Номиналы / зазоры / габариты | `measure` между гранями; `describe_model(sections="box")` | ✅ | +| Тело / манифолд перед выдачей | `describe_model(sections="bodies")` (одно тело?), итог проверки построения в ответе операции | ✅ | + +## Граница честности + +- **Угол нависания** мерить в **той же конвенции, что fdm-rules.md** (от вертикали; нижняя грань с + поверхностью > `θ_max` от вертикали = нависание) — не путать с углом нормали от горизонтали. +- **Путь нагрузки агент НЕ выводит из габарита** — берёт из задачи/опроса (правило 1). Длинная ось + ≠ несущая. +- **Истинная мин. толщина стенки и полный детект криволинейных нависаний — не решаются** (нет + thickness/overhang-солвера). +- **Аудит эвристический и НЕ доказывает печатнопригодность** (не ловит анизотропию/путь нагрузки). + Вывод — список флагов для решения, не «приговор». Слайсер навык не зовёт намеренно. + +## Как применять в цикле + +1. После построения, убедившись что оно чистое, — пройти таблицу выше сверху вниз. +2. Каждый флаг — сверить с соответствующим правилом `fdm-rules.md` и решить: исправить геометрию + или принять осознанно. +3. Путь нагрузки и косметические грани взять из ответа пользователя (правило 1), не из габарита. +4. Затем — чек-лист печатнопригодности (SKILL.md) → экспорт через `export_model` (`.stl` в слайсер). diff --git a/release.json b/release.json new file mode 100644 index 0000000..65f3a51 --- /dev/null +++ b/release.json @@ -0,0 +1,6 @@ +{ + "version": "0.1.0", + "tag": "v0.1.0", + "sourceSha": "c7b0387a24cfeae3f19c052eb16d29dcc8030e31", + "built": "2026-08-06T21:03:33Z" +}