kompas 0.1.0 (из c7b0387a24cfeae3f19c052eb16d29dcc8030e31)

This commit is contained in:
gitea-actions
2026-08-06 21:03:33 +00:00
parent 2b4def3479
commit 39ee6cb155
63 changed files with 2169 additions and 2 deletions
+19
View File
@@ -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"]
}
]
}
+30
View File
@@ -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.
+63 -2
View File
@@ -1,4 +1,65 @@
# КОМПАС-3D в Claude Code # КОМПАС-3D в Claude Code
Репозиторий поставки плагина `kompas`. Содержимое появляется с первым релизом — Каталог плагинов с одним плагином — **`kompas`**. Он даёт Claude Code управление
его публикует workflow из репозитория с исходниками. [КОМПАС-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 (© АО «АСКОН») лицензия не
распространяется: они в поставку не входят.
+19
View File
@@ -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"
]
}
+9
View File
@@ -0,0 +1,9 @@
{
"mcpServers": {
"kompas": {
"command": "powershell",
"args": ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass",
"-File", "${CLAUDE_PLUGIN_ROOT}/scripts/launch-kompas-mcp.ps1"]
}
}
}
+60
View File
@@ -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-сборки, при разработке — временные
файлы) не очищается при обновлении и удалении плагина — удаляется вручную.
+20
View File
@@ -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>` на абсолютный путь
к каталогу `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 — отдельная веха.
@@ -0,0 +1,5 @@
# Вставить в ~/.codex/config.toml. <PLUGIN> — путь к каталогу plugin/ этого репозитория.
[mcp_servers.kompas]
command = "powershell"
args = ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass",
"-File", "<PLUGIN>/scripts/launch-kompas-mcp.ps1"]
+17
View File
@@ -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>` на абсолютный путь к
каталогу `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`.
Это сниппет и инструкция, а не дистрибутив.
+11
View File
@@ -0,0 +1,11 @@
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"kompas": {
"type": "local",
"command": ["powershell", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass",
"-File", "<PLUGIN>/scripts/launch-kompas-mcp.ps1"],
"enabled": true
}
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
+770
View File
@@ -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": ""
}
}
}
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+14
View File
@@ -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
}
}
}
+66
View File
@@ -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`, и — если
что-то не сошлось — какое из действий выше нужно предпринять пользователю.
+47
View File
@@ -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
+563
View File
@@ -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) и на 79 % у скриптовых (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`**.
@@ -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` неподъёмен, но точки углов известны из построения: передай их списком, и все рёбра
уйдут в ОДНУ операцию дерева. Если ребра в части точек нет (типичный случай — угол «съеден»
каймой букв), ошибка перечислит ВСЕ такие точки сразу: убери их и повтори одним вызовом.
+121
View File
@@ -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.40.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`**.
@@ -0,0 +1,179 @@
# Свод правил DFM для FDM-печати
> Выверено 3 ревью (pi/glm-5.1, pi/kimi-k2.6, Codex). Числа для `w≈0.40.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 ~1525 мм, PETG ~1015 мм, ABS ~1218 мм**.
Длинные прямоугольные проёмы **ориентировать так, чтобы мост шёл по короткой стороне**; концы —
на сплошных опорах.
- Нижнюю функциональную поверхность моста — припуск **0.20.3 мм** на провис. *Граница:* величину
провиса из CAD не предсказать (обдув/скорость — настройки печати).
- **Внутренние/потолочные нависания хуже наружных** — потолок пазов аркой/шевроном, не плоским
пролётом > 2 мм.
- **Доступ к поддержкам:** окно во внутренней полости **≥810 мм**.
## 3. Отверстия
- **Вертикальные (ось ∥ Z)** печатаются уже номинала → **увеличить диаметр модели** (радиус на
половину): **+0.2 мм (Ø<4)**, **+0.20.3 мм (Ø 410)**, **+0.10.2 мм (Ø>10)**; калибровать,
критичные — рассверливать.
- **Горизонтальные (ось в XY)** → **teardrop** или **D-отверстие** (плоский верх). Мин. Ø **2 мм**.
Круглая часть тоже печатается уже → **+0.10.2 мм** к её Ø.
- **Геометрия teardrop:** боковины касательны окружности под углом `θ_max` к вертикали (с двух
сторон), сходятся в вершине на вертикальной оси. Высота вершины над центром = **`r / sin θ_max`**;
включённый угол при вершине = **`2·θ_max`**. При `θ_max`=45° → `r/sin45° = √2·r ≈ 1.414·r` над
центром (= **0.414·r над верхом окружности**), угол 90°. Низ — оставшаяся дуга окружности.
- **Глухое отверстие:** дно = внутренний мост → **толщина дна ≥2–3 мм** или купольное/
вентилируемое. Сквозные предпочтительнее.
- **Отступ от края** — через остаточную перемычку: стенка между отверстием и краем **≥23·w**
(лёгкая нагрузка) / больше под крепёж.
## 4. Посадки и зазоры (печатная деталь ↔ печатная деталь)
Зазор **на сторону** (радиальный); диаметральный = 2× значения:
| Посадка | Зазор/сторону | Примечание |
|---|---|---|
| Натяг (press) | **−0.05…0 мм** (вычесть из номинала!) | короткий, PLA; иначе snap-fit (§14) |
| Переходная/плотная | 0.05–0.15 мм | |
| Скользящая | 0.150.20 мм | PLA↔PLA; контакт ≥20 мм → 0.20; PETG +0.05 |
| Свободная | 0.250.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.51.0 × 45° (слабая калибровка)**.
- Внутренние углы у основания — **скругление ≥R0.5**.
- **Опорная площадка:** без «лезвийных» оснований; контакт хотя бы ~3 периметра. Высокие тонкие
детали — **интегральный фланец 1–2 мм** (предпочтительнее brim).
## 6. Ориентация и прочность
- **Z (межслойная) прочность от XY:** PLA ~4055%, PETG ~3550%, **ABS ~2035% (выброс)**. Несущую
нагрузку — в **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.80.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 мм к номиналу** болта.
- **Резьба:** не моделировать <M6 → инсёрты/саморезы. Если моделировать: **≥M6, ось вертикальная**,
зазор +0.1–0.2 мм, профиль крупный/трапецеидальный (не мелкий ISO — вершины-нависания).
## 10. Фаски vs скругления
- **Нижние (у стола) рёбра — фаска** (скругление = нулевой контакт + EF).
- **Косметическое лицо кладут НА СТОЛ**: первый слой на стекле/PEI даёт поверхность лучше любого
верхнего слоя (там видны швы и «лесенка»). Тогда деталь и моделируют в этой ориентации — лицом
к XOY, — а несимметричный рисунок (логотип, текст) **зеркалят**: на лицевую грань смотрят
со стороны −Z. Проверка — снимок со стороны лица (`model_snapshot(view=rear)` для эскиза на XOY).
- **Фаска по лицевому контуру — это ещё и размер первого слоя.** При 45° она сжимает силуэт лица
на катет `c` по всему периметру, поэтому её потолок задаёт не эстетика, а то, что останется:
`ширина_штриха − 2c ≥ 2·w`. У широкого рисунка (штрих ~10 мм) ограничением становится толщина
детали — держите `c ≤ ⅓·T`, иначе плашка читается пирамидой. У мелкого (штрих ~1 мм) фаска почти
невозможна: 0.15 мм уже съедает половину первого слоя.
- **Считайте по САМОМУ УЗКОМУ месту рисунка, а не по типичному штриху.** У знака с клиньями и
перемычками (логотипы, вензеля) минимум вдвое-впятеро меньше медианы. Мерить это глазом по эскизу
нельзя и незачем: `sketch_measure_thickness(entitiesFile, minSegment)` возвращает наибольшую
вписанную окружность, узкое место с координатами и таблицу «офсет `c` → на сколько кусков
распалось лицо» — ничего не строя.
- **Узкое место зависит от СОСТОЯНИЯ контура, поэтому порядок такой: чистка → замер чищеного →
катет.** Замеры на обводке логотипа шириной 105 мм (штрих по наибольшей вписанной 11.5 мм):
| контур | узкое место | лицо распадается при |
|---|---|---|
| исходный, 54 примитива | 1.98 мм | c = 0.99 |
| чищеный порогом 0.5, 34 примитива | **1.82 мм** | **c = 0.91** |
Чистка (`minSegment`) заменяет скругления острыми углами: в выпуклом углу это добавляет материал,
в вогнутом — срезает, а перемычки между штрихами образованы как раз вогнутыми углами. То есть
операция, которую делают РАДИ фаски, уменьшает допустимый катет. Мерьте после неё.
- **Норматив катета — `c = stroke_min/2 w`**, где `stroke_min` — узкое место, `w` — ширина нити.
Он и есть решение неравенства `ширина 2c ≥ 2w`. На том же логотипе: `1.82/2 0.4 = 0.51`,
и в узком месте остаётся ровно 0.80 мм — два прохода сопла.
**Осторожно с «эталонными» значениями из прошлых работ:** принятая когда-то на этом логотипе
фаска 0.8 собственному правилу НЕ удовлетворяет (`1.82 1.6 = 0.22 мм` против нужных 0.8; даже
по нечищеному контуру `1.98 1.6 = 0.38`). Она оставляет в узком месте одну нить экструзии —
тело там сплошное, рвётся косметика лицевой грани, а это как раз та поверхность, ради которой
деталь и кладут лицом на стол.
- **Верхние рёбра — скругление** (R0.5–2.0); **но** радиус **> ~½ толщины стенки** сам даёт
нависание > `θ_max` → тогда фаска/ступень.
- **Внутренние углы — всегда скругление ≥R0.5**.
## 11. Зенковки / цековки
- **Цековка (counterbore)** — большим Ø/полостью **вверх** (дно по телу, не мостом); глубина +0.3 мм.
- **Зенковка (countersink):** конус **вверх**; включённый угол **≤90°** → стенки ≤45° от вертикали
печатается; **>90°** → стенки-нависание → поддержка или замена цилиндрической цековкой.
## 12. Заходные фаски (assembly relief)
- На штифтах, отверстиях, инсёртах, защёлках, «ласточкиных хвостах» — **заходная фаска** (≈0.51 мм
× 45° или ≈ половина зазора) против задиров при сборке.
## 13. Разбиение детали и сборка из печатных частей
- Конфликт «прочная ориентация vs бесподдержечность», или крупная/коробящаяся деталь → **разбить**
на части с самоустанавливающимися стыками (печатные штифты/шпонки/замки), склейка; стыки на
XY-гранях. Зазор стыка — по §4.
## 14. Защёлки (snap-fit) / живой шарнир
- Консольная защёлка: толщина балки **≈1.0–2.0 мм** (функциональный размер, не привязан к кратности
`w`; тоньше ~1 мм — хрупко), зацеп/возврат **0.30.8 мм**, длина/толщина **≥5:1** (до 10:1),
**скругление в основании ≥R0.5**.
- **Направление слоёв:** балка гнётся **в плоскости XY** (слои перпендикулярны изгибу), **не
поперёк Z** (расслоится с первого нажатия).
- **Живой шарнир** — только PLA/PP-подобные, перемычка **0.30.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).
@@ -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` в слайсер).
+6
View File
@@ -0,0 +1,6 @@
{
"version": "0.1.0",
"tag": "v0.1.0",
"sourceSha": "c7b0387a24cfeae3f19c052eb16d29dcc8030e31",
"built": "2026-08-06T21:03:33Z"
}