Commit Graph

219 Commits

Author SHA1 Message Date
mikhail cb43b84249 Dev-лаунчер: сервер запускается из теневой копии сборки
Пока MCP-сервер работал прямо из src\...\bin, он держал открытым kompas-mcp.exe
и Kompas.Mcp.Core.dll — dotnet build падал с MSB3027 от каждой живой сессии.
Лаунчер копирует сборку в %LOCALAPPDATA%\kompas-mcp\dev\<отпечаток> и запускает
её оттуда, поэтому bin свободен всегда.

- tools/dev/KompasMcpDev.psm1 — отпечаток каталога сборки, теневая копия через
  атомарный Directory.Move, уборка старых копий мимо занятых живым процессом,
  сессионный mutex на одновременный старт нескольких сессий;
- tools/dev/launch-dev-mcp.ps1 — точка входа для .mcp.json, инвариант «в stdout
  до старта сервера не уходит ни байта»;
- tools/dev/rebuild-mcp.ps1 — -Check компилирует мимо bin (~2 с при живом
  сервере), обычный режим отказывается заранее и называет блокирующие PID;
- tools/tests/DevLauncher.Tests.ps1 — Pester на все три файла.

Раздел «The rebuild cycle» в CLAUDE.md (2c56511) уже описывал эту схему.
2026-07-31 11:51:59 +03:00
mikhail 2c56511a7a CLAUDE.md: зафиксирован рабочий режим — CAD-задачи как полигон
ci / build (push) Successful in 32s
Три канала обратной связи (патч в src, новый общий тул, правка навыков),
правило «навыки отлаживаются как код» с source of truth в plugin/skills,
запрет утечки внутреннего в публикуемые навыки и ловушка с залоченным
kompas-mcp.exe при пересборке.
2026-07-31 11:18:26 +03:00
mikhail 6700b26bee CLAUDE.md разгружен: тяжёлые справочники вынесены в навык kompas-mcp-dev
ci / build (push) Successful in 29s
Корневой CLAUDE.md грузится в каждую сессию, но большая его часть нужна только
при доработке сервера. 37 476 → 12 203 символов (~6 300 токенов на сессию).

Перенесено в .claude/skills/kompas-mcp-dev/reference/:
- com-implementation-facts.md — проверенные COM-цепочки («Key implementation facts»);
- plugin-and-release.md — устройство plugin/, ветка dist, релиз, CI, обновление RAG-базы.

Релизная кухня положена в навык, а не в plugin/CLAUDE.md: plugin/ раздаётся
пользователям, внутренностям сборки там не место. В корневом файле оставлены два
правила, которые нельзя откладывать до загрузки навыка — обязательный бамп версии
в plugin.json и UTF-8 с BOM для PowerShell плагина.

Удалено как выводимое из репозитория: раскладка каталогов, стек и счётчики тестов,
список режимов sync-agent-assets.ps1, перечень содержимого каталога SDK.

Секция «Navigating the SDK base» удалена как дубль §«Порядок поиска» из определения
агента kompas-sdk-research — вдобавок она описывала инструменты, доступные только
субагенту. Уникальная процедура обновления базы перенесена в навык.
2026-07-31 09:55:30 +03:00
mikhail d78ba750a8 @
ci / build (push) Successful in 29s
Документация переписана под состояние без каталога docs/

Каталог docs/ удалён в b022a91, но CLAUDE.md и README ссылались на
ARCHITECTURE.md, TODO.md, OPEN_QUESTIONS.md, IMPLEMENTATION_PLAN.md и
presentation.html — все ссылки были битыми.

- CLAUDE.md: явно зафиксировано, что прозаическая документация — только он и
  README, docs/ воссоздавать не нужно; бэклог (чертёж: базы/допуски/привязка,
  сопряжения сверх coincidence и distance) и известный подводный камень с
  направлением по нормали грани перенесены из удалённых TODO/OPEN_QUESTIONS
- убран субагент docs-maintainer: он удалён вместе с docs/, доки правятся руками
- ссылка на спеку по параметрическим эскизам заменена на память
- README: структура репозитория приведена к реальной, добавлены --version,
  run-ps-tests.ps1 и оговорка про .slnx на SDK 8
- kompas-mcp-dev: справка SDK описана как RAG-база kompas-sdk вместо
  несуществующего docs/Kompas3D_SDK/, добавлен порядок работ по новому
  инструменту, команды проверки и границы CI

Счётчики сверены по коду: 84 инструмента, 250 unit + 131 integration, 41 Pester.
@
2026-07-31 09:38:19 +03:00
mikhail 37dc0fed36 Диагностика отсутствующего интеропа и документация к его поиску
ci / build (push) Successful in 34s
Продолжение 4d4e114 (сборки КОМПАС убраны из поставки).

- kompas_status проверяет интероп до обращения к сессии и отдаёт причину текстом:
  иначе MCP SDK показывает агенту только «An error occurred invoking …»
- провайдер сносит негодный остаток кеша перед Move: повтор после оборванной
  распаковки падал IOException вместо внятного сообщения
- README/plugin/README/doctor/CLAUDE.md: требование компонента SDK,
  KOMPAS_INTEROP_DIR, кеш в %LOCALAPPDATA%, счётчики тестов 381 (250 unit)
2026-07-31 09:29:01 +03:00
mikhail 4d4e11425e Убраны интероп-сборки из поставки сервера, добавлен KompasInteropLoader 2026-07-31 09:14:53 +03:00
mikhail b022a91dd9 Удалены устаревшие документы суперспособностей (specs/plans) и вспомогательные доки проекта
ci / build (push) Successful in 37s
2026-07-31 09:02:45 +03:00
mikhail f904daaad2 docs: синхронизировать документацию с упаковкой в плагин Claude Code
ci / build (push) Successful in 44s
2026-07-31 08:48:41 +03:00
mikhail 7afd046a09 test: метка Requires=Windows для STA-диспетчера, CI исключает её
ci / build (push) Successful in 29s
2026-07-31 08:29:43 +03:00
mikhail e56132de33 Уборка брошенных временных каталогов установки сервера
ci / build (push) Failing after 27s
finally в Install-KompasMcpServer спасает только от штатного throw/return.
После принудительного убийства процесса посреди установки каталог
.tmp\<guid> оставался навсегда — по ~70 МБ на оборванный запуск, сервер
публикуется self-contained.

Remove-KompasMcpStaleTemp удаляет подкаталоги .tmp старше суток. Возраст
считается как максимум LastWriteTimeUtc по всему поддереву: пока сосед
льёт байты в один и тот же server.zip, время записи самого каталога не
меняется, и по нему можно было бы снести живую установку.

Вызов стоит в начале Install-KompasMcpServer, до раннего выхода по
Test-KompasMcpInstall — иначе мусор от оборванных попыток лежал бы до
следующего релиза. Если каталога .tmp нет, всё сводится к одному
Test-Path.

Функция не бросает исключений и не пишет в success stream: запуск
сервера важнее мусора, а stdout занят JSON-RPC.
2026-07-31 08:26:38 +03:00
mikhail 5b1af4ab39 merge: режим -Remove у sync-agent-assets для снятия junction'ов перед checkout
ci / build (push) Failing after 27s
2026-07-31 08:25:58 +03:00
mikhail e3228abb26 feat(tools): режим -Remove у sync-agent-assets — снятие junction'ов перед checkout
При переключении на ветку или коммит без plugin/skills junction'ы навыков
повисают битыми, и git checkout падает на середине: часть рабочего дерева
уже удалена, а HEAD остаётся на прежней ветке.

Remove-AgentSkillLink удаляет сам reparse point через Directory.Delete
(без -Recurse), поэтому в target не заходит и содержимое plugin/skills не
трогает. Junction опознаётся по атрибуту ReparsePoint, а не по резолву
target — иначе режим не работал бы ровно в том случае, ради которого сделан.
Настоящий каталог не удаляется, а возвращает Skipped.

Режимы скрипта разведены parameter set'ами: -Remove -Check вместе теперь
дают ошибку разбора параметров вместо тихого выигрыша одного из ключей.

Покрыто пятью кейсами в tools/tests/AgentAssets.Tests.ps1 (включая junction
с исчезнувшим источником); порядок действий и восстановление после падения
чекаута описаны в CLAUDE.md.
2026-07-31 08:24:26 +03:00
mikhail c79176e7fc ci: указывать проекты явно — SDK 8 не понимает формат решения .slnx
ci / build (push) Failing after 32s
2026-07-31 08:20:38 +03:00
mikhail 5c74a6f0ab Добавлена поддержка комментариев (note) у переменных модели + разведка v25
ci / build (push) Failing after 20s
2026-07-31 08:16:31 +03:00
mikhail e7f8c0db9f merge: справка SDK вынесена в отдельный репозиторий и RAG
ci / build (push) Failing after 19s
База docs/Kompas3D_SDK/ (2465 статей) переехала в приватный kompas-sdk-docs
и проиндексирована в RAG на CT 127; субагент kompas-sdk-research переведён
на MCP-инструменты сервера kompas-sdk.
2026-07-31 08:11:12 +03:00
mikhail e72aa46cc1 docs: результаты приёмки RAG-справки и фикс реранкера
Спек дополнен фактами прогона: 2465 документов / 13 755 точек, проверка
grep/search/фильтров, живой прогон CI с инкрементальной переиндексацией.
Отдельно зафиксирована находка — реранк падал 400 на длинных чанках
(слот 1024 токена против обрезки в 2000 символов); починено в rag-node.
2026-07-31 03:27:15 +03:00
mikhail 55045184e2 ci: разрешить равную версию в release.yml только для ретрая того же коммита
Гейт «версия не должна уменьшаться» отвергал и равную версию безусловно, что
делало невозможным повторный прогон на том же теге (Task 10 Step 4 плана).
Теперь сравнение version+sourceSha читается из plugin/server.lock.json ветки
dist: равная версия проходит дальше только если sourceSha из dist совпадает с
текущим github.sha (ретрай уже опубликованного релиза — ниже по пайплайну он
и так идемпотентен: upsert релиза/ассета, повторная сверка sha256, force-push
dist тем же содержимым). Другой sourceSha при той же версии — попытка
подменить уже опубликованный релиз другим кодом — отвергается с явным
сообщением, какой коммит уже занимает эту версию. Меньшая версия отвергается
как и раньше.
2026-07-31 02:55:39 +03:00
mikhail e2fe197fbb ci: сборочный и релизный workflow для Gitea Actions (Task 9-10)
ci.yml: сборка + unit-тесты на Linux-раннере (EnableWindowsTargeting), плюс
проверка согласованности plugin/.claude-plugin/plugin.json и
plugin/server.lock.json (версии совпадают; для опубликованного релиза —
sha256 непустой и 64 hex).

release.yml: на тег vX.Y.Z — публикация self-contained win-x64,
идемпотентный upsert релиза/ассета через Gitea API, сверка SHA256
опубликованного ассета перед обновлением, и force-push ветки dist поверх
коммита с тегом (server.lock.json + plugin.json). Отличия от черновика в
плане: устойчивый разбор "версия не должна уменьшаться" (не полагается на
особенность jq на пустом stdin), явные HTTP-коды вместо curl -f для
различения "релиза нет" от прочих ошибок API, persist-credentials: false
на checkout, чтобы не конфликтовать с собственным токеном на пуше.

Не прогонялось на раннере — раннер ещё не готов (отдельная работа).
2026-07-31 02:53:26 +03:00
mikhail 58eba795cf fix(plugin): PSObject.Properties индексатор вместо .Name на пустой коллекции
server.lock.json вида "{}" (валидный JSON, ноль ключей) — реальный вход
(placeholder до заполнения релизным пайплайном), но под
Set-StrictMode -Version Latest член-перечисление .PSObject.Properties.Name
бросает PropertyNotFoundException, когда коллекция .Properties пуста, — Read-
KompasMcpLock падала сырым .NET-трейсом вместо дружественного сообщения.
Тесты этого не ловили: любой объект хотя бы с одним свойством (даже без
version) уже не задевает пустую коллекцию.

Фикс: PSObject.Properties['имя'] (индексатор) вместо .Properties.Name
-contains — он возвращает $null и не бросает независимо от того, пуста
коллекция или нет. Применено ко всем трём проверкам (version/url/sha256).
Отдельно исключён случай $lock -eq $null (JSON "null" и пустой файл
разбираются в $null, а $null.PSObject тоже бросает под StrictMode).

Добавлены тесты: лок "{}", лок "null", лок "" (пустая JSON-строка вместо
объекта) — все дают сообщение с именем файла, а не .NET-трейс. Известные
пробелы покрытия (IOException-гонка вокруг Directory.Move,
AbandonedMutexException) зафиксированы комментарием в тестовом файле — не
автотестируются осознанно (нужен настоящий межпроцессный тайминг).
2026-07-31 02:43:13 +03:00
mikhail 2fb212bb14 fix(plugin): жёсткий разбор пути к серверу и обёртка запуска в лаунчере
- Test-Path -PathType Leaf: путь-каталог в KOMPAS_MCP_EXE больше не проходит
  проверку молча — раньше падение случалось на голом & $exe сырым
  CommandNotFoundException в обход диагностической обёртки.
- запуск сервера (& $exe @args) обёрнут в try/catch: сбой самого запуска
  (битый бинарь, недостающая зависимость, отказ в доступе) теперь тоже даёт
  чистое сообщение 'kompas-mcp launcher: ...' и код 1, а не сырой трейс;
  ненулевой код возврата уже запущенного сервера по-прежнему пробрасывается как есть.
- тесты: три новых сценария (каталог вместо файла, ноль байт в stdout на
  пути отказа, повреждённый exe) + первый тест переписан на побайтовую
  проверку stdout через Start-Process без фильтрации пустых строк.
2026-07-31 02:39:37 +03:00
mikhail 0ed211fe16 fix(plugin): mutex AbandonedMutexException, валидация server.lock.json, тесты гонки
Три предметных замечания ревью качества:
- Resolve-KompasMcpExecutable: WaitOne() перенесён в try/finally, отдельно
  ловится AbandonedMutexException (владелец умер посреди установки — владение
  переходит к нам, это не ошибка); ReleaseMutex вызывается только если mutex
  реально захвачен, иначе он бросает SynchronizationLockException и маскирует
  первопричину. Добавлен -Downloader passthrough для тестируемости.
- Read-KompasMcpLock: разбор JSON обёрнут в try/catch с сообщением, называющим
  файл; наличие полей version/url/sha256 проверяется через
  PSObject.Properties.Name (обращение к отсутствующему свойству под
  Set-StrictMode -Version Latest бросает PropertyNotFoundException); sha256
  валидируется на 64 hex-символа.
- Добавлены тесты на конкурентную логику: Resolve-KompasMcpExecutable
  (повторный вызов не скачивает), гонка "сосед выиграл" (целевой каталог уже
  содержит годную/негодную установку) в Install-KompasMcpServer, счастливый
  путь и все новые ветки валидации в Read-KompasMcpLock.

Мелочи: & $Downloader ... | Out-Null (внедряемый загрузчик не должен писать
в success stream); уточнён комментарий Test-KompasMcpInstall — оно намеренно
трактует любую ошибку чтения маркера (не только битый JSON, но и блокировку
антивирусом) как "установка негодная".

AbandonedMutexException-ветка вручную воспроизведена и проверена: процесс-
владелец mutex убит, пока другой процесс уже блокирован в WaitOne() —
тот получает AbandonedMutexException и корректно продолжает работу.
2026-07-31 02:34:41 +03:00
mikhail f0fc85de03 docs: конкретные команды в шаге 5 doctor и предупреждение о предрелизных тегах 2026-07-31 02:29:06 +03:00
mikhail 09f17fae16 docs(plugin): README и адаптеры под Codex/opencode 2026-07-31 02:28:20 +03:00
mikhail 30197b34c7 feat(plugin): команда /kompas:doctor 2026-07-31 02:20:42 +03:00
mikhail 7c4d7b2c3e feat(host): флаг --version для сверки установленного бинаря 2026-07-31 02:17:28 +03:00
mikhail 297015f4af docs: справка SDK вынесена в отдельный репозиторий и RAG
MD-база docs/Kompas3D_SDK/ (2465 статей, 10.4 МБ) переехала в приватный
kompas-sdk-docs и проиндексирована в RAG на CT 127. Доступ — MCP-сервер
kompas-sdk (порт 8092); субагент kompas-sdk-research переведён с Grep/Read
на его инструменты и теперь ищет по базе, которой в репозитории нет.

Порядок поиска в инструкции агента: grep_knowledge для точных имён,
search_knowledge с фильтрами type/tags для задачных вопросов,
get_chunk_context вместо get_document (геометрия.md весит 261 КБ).

Обновление при новой версии КОМПАС — update_sdk_docs.ps1 в репозитории
доков: zip справки → генератор → diff → тег → push → переиндексация
через Gitea Actions. Спек и фактические результаты —
docs/superpowers/specs/2026-07-31-sdk-docs-rag-migration-design.md.
2026-07-31 02:16:11 +03:00
mikhail c65a890df9 docs(plugin): исправить обоснование сессионного mutex без Global\
Прежний комментарий утверждал, что Global\ требует отдельной привилегии —
ревью опровергло это эмпирически (мьютекс создался без ошибок под тем же
непривилегированным пользователем). Настоящая причина: плагин ставится на
чужие незнакомые машины, где политика безопасности может отличаться, и отказ
Global\ был бы фатальным для запуска сервера, тогда как остаточный риск
сессионного mutex (лишняя повторная загрузка при параллельных сессиях)
ограничен и не портит установку.
2026-07-31 02:14:15 +03:00
mikhail f1f2d05c96 fix(gitignore): якорить правило .mcp.json к корню — plugin/.mcp.json должен отслеживаться 2026-07-31 02:13:24 +03:00
mikhail ad0f5463c5 feat(plugin): точка входа лаунчера и объявление MCP-сервера 2026-07-31 02:12:02 +03:00
mikhail 1049a9b01a feat(plugin): bootstrap-модуль установки сервера с проверкой SHA256 2026-07-31 02:03:34 +03:00
mikhail 62fbc3742b fix(tools): UTF-8 BOM для PowerShell 5.1, безопасный AllowCopy, доп. тесты
- AgentAssets.psm1 и sync-agent-assets.ps1 пересохранены в UTF-8 с BOM:
  powershell.exe читает файлы без BOM в системной ANSI-кодировке и ломает
  парсинг на кириллических строковых литералах (pwsh 7 работал за счёт
  автодетекта и маскировал баг).
- Copy-Item в ветке -AllowCopy получил -ErrorAction Stop: без него ошибка
  копирования писалась как non-terminating и функция возвращала 'Copied'
  при частично скопированном каталоге, если вызывающий не выставил
  $ErrorActionPreference='Stop' сам.
- Test-AgentSkillLink сравнивает пути через
  [string]::Equals(...,OrdinalIgnoreCase) явно, а не через регистронезависимый -eq.
- Добавлены тесты: отсутствующий SourcePath, перелинковка на другой
  источник (старый target остаётся нетронутым) и AllowCopy-регрессия
  (мок Copy-Item с [CmdletBinding()], чтобы корректно эмулировать
  ErrorAction реального cmdlet).
2026-07-31 01:58:06 +03:00
mikhail 97e95d5f44 feat(tools): раскладка навыков junction'ами из plugin/skills 2026-07-31 01:36:42 +03:00
mikhail 4a6dbd1497 refactor(skills): пользовательская редакция навыков в plugin/skills, dev-материал в kompas-mcp-dev 2026-07-31 01:21:21 +03:00
mikhail 4b72f36fc9 test(plugin): вынести правило релизного лока в хелпер с theory-покрытием
Освобождает JsonDocument в Read(), покрывает IsReleasedLockValid синтетическими
JSON-кейсами (без релиза / валидный релиз / пустой url / некорректный sha256),
приводит имена тестов к конвенции Method_condition_result проекта.
2026-07-31 01:14:06 +03:00
mikhail febcb664a5 feat(plugin): скелет плагина kompas и тест согласованности манифеста 2026-07-31 01:06:23 +03:00
mikhail ad85ebf478 docs: план реализации плагина kompas (11 задач, TDD) 2026-07-31 01:02:57 +03:00
mikhail 7cc4ee7447 docs: ревизия спека плагина по ревью Codex (канал dist, контракт лаунчера, редакция навыков) 2026-07-31 00:52:52 +03:00
mikhail 63bd9db5f3 docs: спек упаковки в плагин Claude Code и публикации через Gitea 2026-07-31 00:37:26 +03:00
mikhail 4e119afdba docs: замкнуть жизненные циклы CAD-каталога 2026-07-17 02:15:32 +03:00
mikhail b188e1904f docs: уточнить статусы и приоритеты CAD-каталога 2026-07-17 01:57:53 +03:00
mikhail c0d855c171 docs: добавить каталог внешнего CAD-контракта 2026-07-17 01:39:39 +03:00
mikhail 8e56af61b3 docs: спроектировать каталог внешнего CAD-контракта 2026-07-17 01:18:10 +03:00
mikhail 69d037c875 chore: настроить Codex-агент поиска SDK 2026-07-17 01:12:53 +03:00
mikhail 6aa05b1adb docs: спроектировать Codex-агент поиска SDK 2026-07-17 01:06:25 +03:00
mikhail 7cb44a073e docs: handoff — инкремент 9 (выноска) завершён; далее — базы/допуски формы
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 00:34:18 +03:00
mikhail 16406a34be Merge feat/drawing-leader: линия-выноска с текстом (инкремент 9)
drawing_add_leader через ISymbols2DContainer.Leaders + IBranchs. 83 инструмента,
331 тест зелёный. Ревью: Codex + pi/glm-5.1 + pi/kimi-k2.6.
2026-05-28 00:33:33 +03:00
mikhail 5d51b9e1af docs: выноска — TODO, README, ARCHITECTURE, OPEN_QUESTIONS, presentation, CLAUDE.md
Инкремент 9. 83 инструмента, 331 тест. + заметка о ревью реализации в спеке
(Codex + pi/glm-5.1 + pi/kimi-k2.6).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 00:33:33 +03:00
mikhail beaa220510 review(drawing): правки по ревью реализации (Codex + pi/glm-5.1 + pi/kimi-k2.6)
- проверка возврата AddBranchByPoint/SetBranchTextPosition (bool) — ранняя диагностика
  вместо позднего RPC_E_SERVERFAULT (Codex, glm)
- RU-алиасы в сообщении ShelfDirections.Parse и в описании инструмента (glm, kimi)
- интеграционный тест направления полки параметризован Right/Left/Up/Down — покрывает
  всю поверхность ToKompas на реальном COM (glm, kimi)
- отклонено (обоснование): unit ToKompas (граница проекта), e2e tool-обёртки (тонкая),
  angleDeg (нет Angle у ILeader), default text у AddText (вне объёма)

331 тест зелёный, сборка Release чистая.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 00:28:04 +03:00
mikhail f89ad951ae feat(drawing): линия-выноска с текстом (drawing_add_leader)
Выноска на виде через API7 ISymbols2DContainer.Leaders. Стрелка указывает в (x,y),
текст на полке у (textX,textY). shelfDirection: auto|right|left|up|down.

- DrawingService.AddLeaderAsync + GetViewLeaderCountAsync
- ShelfDirection (enum + Parse/ToKompas), переиспользует DrawingAnnotationResult
- 13 unit + 7 интеграционных тестов (всего 328 зелёных), сборка Release чистая

КЛЮЧ (спайк): новая выноска имеет 0 ответвлений — сначала (IBranchs)bl.AddBranchByPoint(0,x,y)
(остриё), ИНАЧЕ КОМПАС падает RPC_E_SERVERFAULT; затем SetBranchTextPosition (полка),
(ILeader)bl.TextOnShelf.Str (текст), Update. Ревью спека Codex+pi/glm-5.1+pi/kimi-k2.6 учтено
(QI as?? throw, read-back ?? empty, RequireDistinctPoints, RU-алиасы, критический порядок).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 00:18:08 +03:00
mikhail 08191db25c docs: handoff — инкремент 8 (формат листа) завершён; ревью-гейт = Codex + pi/glm-5.1 + pi/kimi-k2.6
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 23:35:22 +03:00