Commit Graph

227 Commits

Author SHA1 Message Date
mikhail 31b933e1cc Ответ надписи — габарит глифов; запись на диск создаёт каталог
ksConvertTextToCurve ВОЗВРАЩАЕТ ссылку на кривые, и только по ней ksGetObjGabaritRect
даёт габарит букв: по текстовой ссылке это ячейка строки (Arial h=10 «HH» — 23.75 против
19.97 у глифов, второе совпадает с выдавленным телом). Агент вписывает надпись в поле
по габариту, поэтому в ответе теперь оба числа.

OutputPath.Prepare создаёт каталог назначения и делает путь абсолютным (document_save,
export_step, снимок): КОМПАС в несуществующую папку молча не пишет, а диагностика при
этом винила занятое имя файла — чинили не ту причину. Причины разведены.
2026-07-31 16:36:01 +03:00
mikhail 461e731857 Дерево построения: имя у каждой операции, скругление пакетом по точкам
Имя (name) прокидывается до создания объекта: API5 — ksEntity.name перед Create(),
API7-пути (примитив, отверстие, булева, рез, перенос грани) — IModelObject.Name перед
Update(). Читается назад через ksFeature.name, который только на чтение. Без имени
дерево состоит из «Эскиз:1» и «Элемент выдавливания:3».

fillet_edge/chamfer_edge принимают список точек: на теле с сотнями рёбер list_edges
неподъёмен, а выбор по точке брал одно ребро — четыре угла давали четыре операции.
Ненайденные рёбра перечисляются ВСЕ сразу, модель при этом не мутируется.
2026-07-31 16:35:44 +03:00
mikhail 814c9cf7b1 Субагент cad-engineer: прогон CAD-задачи с чистым контекстом
Отладочный механизм: субагент строит модель ТОЛЬКО инструментами MCP и по навыкам,
без подсказок вызывающего, а затем сдаёт протокол — вызовы, затыки, цитаты из навыка,
чего не хватило в каталоге. Пишущих инструментов у него нет намеренно: нехватка
возвращается находкой, а не самодельным обходом. Проектный, в плагин не входит.
2026-07-31 16:35:30 +03:00
mikhail d0c9d8ca3f Навыки и README: два пути формообразования, надписи, проверенные факты
kompas-3d: раздел «Два пути формообразования — выбирай по форме, а не по
привычке» (призматика и карманы примитивами, текст и кривые эскизами) и
раздел про надписи с числами, снятыми на практике: height задаёт высоту
ПРОПИСНОЙ, а не габарит строки; разрыв между advance-длиной и габаритом
глифов зависит от шрифта (1-2 % у наборных, 7-9 % у скриптовых) — прежние
формулировки были выведены из одного замера и оказались неверны.

Там же — почему тонкая стенка по многоконтурному эскизу не строится поверх
пересекаемого тела (разложено экспериментом: число тел, происхождение тела
и chooseType ни при чём) и как скруглять рельефный текст: по одному ребру
строится, пакетом по всем 203 — нет.

CLAUDE.md и kompas-mcp-dev: спайк-проект под кейс допустим для проверки
теории, но итоговая деталь всегда строится инструментами MCP — раннер
обходит тот самый слой, который мы проверяем.
2026-07-31 14:51:29 +03:00
mikhail 4f4dd082d9 Документы и диагностика: имя детали, честное сохранение, причина ошибки
set_part_info задаёт наименование и обозначение детали: без него в дереве
стоит безликая «Деталь», и она же уходит в штамп чертежа и в спецификацию.
describe_model показывает наименование в шапке, а безымянную деталь помечает
явно. Имя файла этого не заменяет — это разные свойства.

document_save рапортовал «Сохранено», ничего не записав: SaveAs возвращает
void и молча отказывает, если файл с этим именем уже открыт в КОМПАС другим
документом. Теперь путь и наличие файла проверяются после записи, а Save
сверяет флаг Changed. Освободить занятое имя нечем не было — document_close
получил режим all.

Текст исключения доходил до клиента только у McpException, всё остальное
подменялось на «An error occurred invoking». То есть подсказки в наших
сообщениях агент не видел вовсе. Фильтр CallTool в Program.cs возвращает
IsError с реальной причиной (ToolErrorText разворачивает AggregateException
и склеивает вложенные причины). Там же — регистрация PrimitiveService.
2026-07-31 14:51:12 +03:00
mikhail a4cc755fb4 Формообразование: надписи в эскизе, тонкая стенка, тела по размерам
Три способа получить форму там, где раньше был только замкнутый контур
из отрезков и дуг.

1. Примитив эскиза type=text: ksTextEx + ksConvertTextToCurve. Пока текст
   остаётся текстом, это оформление, и операция его не видит; после
   конвертации глифы становятся обычным сечением. Ответ возвращает
   фактическую длину строки — иначе ширину шрифта до выдавливания не узнать.

2. extrude(thinThickness, thinSide): контур трактуется как стенка заданной
   толщины. outward по замкнутому контуру даёт кайму-эквидистанту вокруг
   него — так надпись получает подложку без 2D-эквидистанты.
   Толщину при dtReverse КОМПАС читает из reverseThickness: положить её в
   normalThickness значит молча получить СПЛОШНОЕ сечение вместо рамки.

3. Инструмент primitive: элементарные тела API7 (block, cylinder, sphere,
   cone) с result=new|union|subtract|intersect. Карман и паз строятся
   вычитанием тела, без эскиза и выреза. Update() возвращает TRUE даже
   когда вычитание прошло мимо тела, поэтому сервис сверяет объём до и
   после и откатывает операцию, если ничего не изменилось.
2026-07-31 14:50:56 +03:00
mikhail dfe5636290 Dev-скрипт сборки: .Count падал на единственном держателе bin
Get-BlockingProcess возвращает скаляр, когда bin занят ровно одним процессом
MCP, и .Count под Set-StrictMode роняет скрипт вместо диагностики. Та же
ловушка, что описана для лаунчера, — теперь результат заворачивается в @().
2026-07-31 14:50:38 +03:00
mikhail 4e3d367637 Каталог инструментов сжат под агента: 84 → 56
ci / build (push) Successful in 28s
Инструменты были нарезаны по способу вызова, а не по смыслу: четыре отверстия,
двойники *_index, одиннадцать sketch_add_*. Агент платил за это дважды — 40 КБ
описаний в каждой сессии и лишние round-trip'ы, а каждый вызов это ещё и шанс
сбиться. Теперь инструмент называет ОПЕРАЦИЮ, вариант задаётся параметром,
объект выбирается индексом или точкой одним и тем же инструментом.

Проверка построения приходит сама. Каждая мутирующая операция дописывает к ответу
итог validate_part (AutoValidation): Create()/Update()==true не значит успех, а
правило навыка «проверяй после каждого шага» удваивало число вызовов. Выключается
через set_auto_validate или KOMPAS_MCP_AUTOVALIDATE=0 — сбой самой проверки уходит
в примечание и никогда не превращает удачную операцию в ошибку.

Эскиз: 16 инструментов → 3. sketch_create(plane|faceIndex|x,y,z, entities[],
autoClose) строит контур целиком; пакет выполняется за ОДИН заход на STA-поток
(PartModeler.AddEntitiesAsync), ошибка называет позицию примитива в списке.

Слияния: hole(type=simple|counterbore|countersink|conic), extrude/revolve(mode),
pattern(kind), mirror (без featureIds — всё тело), document_save(path?),
set_variable как upsert (разведочный вызов «есть ли такая» больше не нужен),
list_faces/list_edges(index?) вместо отдельных describe_*, get_part_info и
get_bounding_box — в describe_model(sections), где незапрошенные разделы вообще
не читаются из модели.

Селектор index|point: fillet_edge/chamfer_edge принимают edgeIndices списком —
одна операция дерева на все рёбра; для операций API7, умеющих только точку,
индекс переводится в точку через ModelInspectionService.FaceCenterPointAsync
(середина параметрической области грани).

Схема слитого инструмента не запрещает неверную комбинацию полей — это делает
валидация, и её сообщение называет type и недостающий параметр.

Тесты: 291 unit (+41) и 136 integration (+5), интеграционные — на живом КОМПАС.
Новые проверяют ровно рискованные места: точка-из-индекса лежит на грани и по ней
создаётся эскиз, мульти-ребёрное скругление даёт один узел дерева и убыль объёма,
upsert создаёт и затем меняет переменную с формулой, пакет сообщает позицию сбоя.
PluginSkillsTests теперь падает, если в публикуемом навыке всплывёт слитое имя.
2026-07-31 11:52:30 +03:00
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