docs: ревизия спека плагина по ревью Codex (канал dist, контракт лаунчера, редакция навыков)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Спек: упаковка kompas3d-mcp в плагин Claude Code и публикация через Gitea
|
||||
|
||||
Дата: 2026-07-31 · Статус: согласовано, к реализации
|
||||
Дата: 2026-07-31 · Статус: согласовано, ревизия 2 (после ревью Codex)
|
||||
|
||||
## 1. Цель
|
||||
|
||||
@@ -22,14 +22,25 @@ README сразу рассчитаны на постороннего, но вы
|
||||
`obsidian-autodoc`).
|
||||
- `home-repo-cc` — **приватный** (Gitea API отдаёт 404 без токена). `kompas3d-mcp` — **публичный**,
|
||||
релизы включены.
|
||||
- Marketplace поддерживает source-тип **`git-subdir`** (`{url, path, ref?, sha?}`, разрежённый клон) —
|
||||
плагин может физически жить в подкаталоге другого репозитория.
|
||||
- Плагин объявляет MCP-серверы через `.mcp.json` в своём корне; в путях доступна переменная
|
||||
`${CLAUDE_PLUGIN_ROOT}`. Плагин копируется в кеш `~/.claude/plugins/cache` при установке.
|
||||
- Marketplace поддерживает source-тип **`git-subdir`** (`{url, path, ref?, sha?}`, разрежённый клон).
|
||||
- Плагин объявляет MCP-серверы через `.mcp.json` в своём корне; в путях доступна
|
||||
`${CLAUDE_PLUGIN_ROOT}`. Плагин копируется в кеш `~/.claude/plugins/cache`; **версия из
|
||||
`plugin.json` служит ключом кеша** — при совпадении версии `/plugin update` и автообновление
|
||||
плагин пропускают.
|
||||
- `/plugin marketplace update` обновляет **каталог**, а не установленный плагин; плагин обновляется
|
||||
`/plugin update`.
|
||||
- **Фоновое автообновление каталога отключает git-credential-helper**, поэтому для приватного
|
||||
HTTPS-каталога фоновый `git pull` не аутентифицируется и Claude Code уходит в ре-клон (который
|
||||
может отваливаться по 120-секундному таймауту). SSH-ремоуты этим не затронуты.
|
||||
- `.agents/skills/` в этом репозитории — побайтово идентичная копия `.claude/skills/` (untracked):
|
||||
дублирование навыков между харнессами уже началось вручную.
|
||||
- Навык `kompas-3d` **устарел и не самодостаточен**: заявляет 46 инструментов (в CLAUDE.md — 83),
|
||||
ссылается на `usecases/`, `src/`, субагентов `kompas-sdk-research` и `docs-maintainer`, которых в
|
||||
плагине не будет.
|
||||
- Сервер: `net8.0-windows`, x64, вендорские interop-DLL АСКОН в `libs/kompas-interop` (4.4 МБ,
|
||||
в репозитории). Ни WinForms, ни WPF не используются.
|
||||
в репозитории, `Private=true` → копируются в вывод publish). Ни WinForms, ни WPF не используются.
|
||||
- Отдельного `LICENSE` в репозитории нет; README говорит лишь «распространяются согласно условиям
|
||||
АСКОН».
|
||||
|
||||
## 3. Принятые решения
|
||||
|
||||
@@ -41,6 +52,8 @@ README сразу рассчитаны на постороннего, но вы
|
||||
| Каталог | остаётся приватным `home-repo-cc`, доступ знакомым выдаётся в Gitea |
|
||||
| Раскладка | плагин лежит в `kompas3d-mcp/plugin/`, каталог ссылается через `git-subdir` |
|
||||
| Имя плагина | `kompas` |
|
||||
| Канал дистрибуции | ветка **`dist`**, а не `main` (см. §6) |
|
||||
| Навыки | публикуется **пользовательская редакция**; материал по разработке сервера выносится (см. §5) |
|
||||
|
||||
`kompas`, а не `kompas-3d`: пространство имён даёт `/kompas:doctor`, навыки становятся
|
||||
`kompas:kompas-3d` / `kompas:kompas-fdm-design`, и это совпадает с именем MCP-сервера (`mcp__kompas__*`).
|
||||
@@ -54,7 +67,7 @@ README сразу рассчитаны на постороннего, но вы
|
||||
kompas3d-mcp/
|
||||
plugin/ ← весь плагин, единственный источник истины навыков
|
||||
.claude-plugin/plugin.json
|
||||
skills/kompas-3d/SKILL.md
|
||||
skills/kompas-3d/SKILL.md ← пользовательская редакция
|
||||
skills/kompas-fdm-design/{SKILL.md,references/}
|
||||
commands/doctor.md → /kompas:doctor
|
||||
.mcp.json
|
||||
@@ -62,6 +75,7 @@ kompas3d-mcp/
|
||||
server.lock.json
|
||||
README.md
|
||||
adapters/{codex,opencode}/
|
||||
.claude/skills/kompas-mcp-dev/ ← материал по разработке сервера (не публикуется)
|
||||
tools/sync-agent-assets.ps1
|
||||
.gitea/workflows/{ci.yml,release.yml}
|
||||
```
|
||||
@@ -69,82 +83,152 @@ kompas3d-mcp/
|
||||
`plugin/.claude-plugin/plugin.json`: `name: "kompas"`, `displayName`, `description`, `version`
|
||||
(семвер, поднимается релизным коммитом), `author`, `homepage`, `repository`, `license`, `keywords`.
|
||||
|
||||
## 5. Источник истины навыков
|
||||
## 5. Навыки: пользовательская редакция и источник истины
|
||||
|
||||
Навыки хранятся **только** в `plugin/skills/`. `tools/sync-agent-assets.ps1` создаёт на них junction'ы
|
||||
из `.claude/skills/<name>` и `.agents/skills/<name>` (на Windows junction создаётся без прав
|
||||
администратора); если junction создать не удалось — копирует и печатает предупреждение. Обе целевые
|
||||
папки добавляются в `.gitignore`, прежние копии удаляются из индекса.
|
||||
Публиковать нынешний `kompas-3d` нельзя: он написан для работы **внутри этого репозитория**.
|
||||
Перед первым релизом навык разделяется:
|
||||
|
||||
Смысл: сегодняшний дрейф между `.claude` и `.agents` устраняется структурно. Для локальной работы в
|
||||
этом репозитории плагин **не устанавливается** — иначе навыки задвоятся (плагинная копия + junction).
|
||||
- `plugin/skills/kompas-3d/SKILL.md` — **пользовательская редакция**: только методика построения
|
||||
через MCP-инструменты. Убираются ссылки на `usecases/`, `src/`, субагентов и предписание
|
||||
«заведи кейс и продуктизируй инструмент»; список инструментов приводится в соответствие с
|
||||
фактическим (сверять по `README.md` §«Инструменты», не по памяти).
|
||||
- `.claude/skills/kompas-mcp-dev/SKILL.md` — всё вынутое (полигон `usecases/`, продуктизация
|
||||
инструментов, субагенты). Это **перевалочный пункт**: доводка принадлежит отложенной работе по
|
||||
рабочему циклу репозитория, здесь только сохраняем материал, не теряя его.
|
||||
|
||||
## 6. Лаунчер и версионирование сервера
|
||||
`kompas-fdm-design` переносится как есть (он опирается на `kompas-3d` и `export_step`, внешних
|
||||
ссылок на репозиторий не содержит) — проверить это отдельным чтением перед переносом.
|
||||
|
||||
`plugin/server.lock.json` — пин ровно одной версии:
|
||||
Навыки хранятся **только** в `plugin/skills/`. `tools/sync-agent-assets.ps1` создаёт junction'ы
|
||||
`.claude/skills/<name>` и `.agents/skills/<name>` → `plugin/skills/<name>`:
|
||||
|
||||
- junction на Windows создаётся без прав администратора и может указывать на другой локальный том;
|
||||
- **если junction создать не удалось — скрипт завершается ошибкой**, а не молча копирует: иначе
|
||||
«единственный источник истины» превращается в две расходящиеся копии. Копия допустима только
|
||||
явным флагом `-AllowCopy`, и тогда `sync -Check` обязан сверять хеши;
|
||||
- `.gitignore` пополняется **точечными путями** (`/.claude/skills/kompas-3d/`,
|
||||
`/.claude/skills/kompas-fdm-design/`, те же в `.agents/`), а не каталогами целиком: git видит
|
||||
junction как обычный каталог и без ignore проиндексирует содержимое повторно;
|
||||
- скрипт никогда не удаляет рекурсивно то, что не является созданным им junction'ом; удаление
|
||||
делается без следования в target;
|
||||
- при чекауте внутри OneDrive-дерева поведение не гарантируется — README рекомендует держать
|
||||
репозиторий вне синхронизируемой папки.
|
||||
|
||||
Для локальной работы в этом репозитории плагин **не устанавливается** — иначе навыки задвоятся.
|
||||
|
||||
## 6. Канал дистрибуции: ветка `dist`
|
||||
|
||||
Каталог **не** может ссылаться на `main`: релиз собирается из отмеченного тегом коммита A, а
|
||||
бот-коммит с обновлённым `plugin.json` попадёт в текущую голову `main` (уже коммит B). Пользователь
|
||||
получил бы содержимое `plugin/` из B под версией, чей бинарь собран из A.
|
||||
|
||||
Решение: релизный workflow формирует ветку **`dist`** — коммит **строго поверх отмеченного тегом
|
||||
коммита**, добавляющий только `server.lock.json` и `version` в `plugin.json`. Каталог ссылается на
|
||||
`ref: "dist"`. `main` остаётся веткой разработки, релизных коммитов в неё нет.
|
||||
|
||||
`server.lock.json` фиксирует и происхождение сборки:
|
||||
|
||||
```json
|
||||
{ "version": "1.0.0",
|
||||
"sourceSha": "63bd9db…",
|
||||
"url": "https://git.shahovalov.ru/mikhail/kompas3d-mcp/releases/download/v1.0.0/kompas-mcp-1.0.0-win-x64.zip",
|
||||
"sha256": "…" }
|
||||
```
|
||||
|
||||
## 7. Лаунчер
|
||||
|
||||
`plugin/.mcp.json`:
|
||||
|
||||
```json
|
||||
{ "mcpServers": { "kompas": {
|
||||
"command": "powershell",
|
||||
"args": ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File",
|
||||
"args": ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File",
|
||||
"${CLAUDE_PLUGIN_ROOT}/scripts/launch-kompas-mcp.ps1"] } } }
|
||||
```
|
||||
|
||||
Алгоритм `launch-kompas-mcp.ps1`:
|
||||
|
||||
1. Задан `KOMPAS_MCP_EXE` → использовать его (цикл разработки: локальная сборка вместо релиза).
|
||||
2. Иначе целевой путь `%LOCALAPPDATA%\kompas-mcp\<version>\kompas-mcp.exe`; существует → запуск.
|
||||
3. Отсутствует → скачать ассет во временный каталог, посчитать SHA256; **несовпадение — отказ с
|
||||
ненулевым кодом, скачанный файл не запускается**; распаковать во временный каталог и атомарно
|
||||
переименовать в целевой (устойчиво к параллельному старту двух сессий).
|
||||
4. `& $exe @args`; stdio наследуется дочерним процессом; код возврата пробрасывается.
|
||||
1. `$ErrorActionPreference='Stop'`, `$ProgressPreference='SilentlyContinue'`; весь скрипт обёрнут в
|
||||
`try/catch`, где `catch` пишет причину в stderr и делает `exit 1`.
|
||||
2. Задан `KOMPAS_MCP_EXE` → использовать его (цикл разработки: локальная сборка вместо релиза).
|
||||
3. Иначе целевой каталог `%LOCALAPPDATA%\kompas-mcp\<version>`; установка считается годной, только
|
||||
если рядом лежит **маркер** `install.json` с совпадающими `version` / `sha256` / `sourceSha`
|
||||
и присутствуют все обязательные файлы. Одного `Test-Path kompas-mcp.exe` недостаточно —
|
||||
иначе повреждённая или оборванная установка запускается молча.
|
||||
4. Установка отсутствует → захватить именованный mutex по версии; после захвата **повторно
|
||||
проверить** установку (гонку мог выиграть сосед). Скачать во временный каталог
|
||||
`%LOCALAPPDATA%\kompas-mcp\.tmp\<guid>` — тот же том, иначе переименование каталога не атомарно;
|
||||
посчитать SHA256; **несовпадение — отказ с ненулевым кодом, скачанное не запускается**;
|
||||
распаковать, проверить состав, записать маркер, переименовать в целевой каталог. Ошибка
|
||||
`destination exists` трактуется как успех соседа. Временный каталог удаляется в `finally`.
|
||||
5. Запуск и проброс кода — точным шаблоном:
|
||||
|
||||
**Инвариант:** скрипт не пишет в stdout ни байта (stdout — канал JSON-RPC). Всё — в stderr;
|
||||
`Write-Host` запрещён.
|
||||
```powershell
|
||||
& $exe @args
|
||||
$serverExit = $LASTEXITCODE
|
||||
exit $serverExit
|
||||
```
|
||||
|
||||
Публикуется **self-contained win-x64**: другу не нужен установленный .NET 8 Runtime, требуется только
|
||||
КОМПАС. Цена — ~70 МБ на ассет. Старые версии остаются в кеше рядом — откат сводится к правке
|
||||
`server.lock.json`.
|
||||
`powershell -File` возвращает 0, если скрипт не сделал `exit` явно, — без этого падение сервера
|
||||
останется невидимым.
|
||||
|
||||
## 7. Команда `/kompas:doctor`
|
||||
**Инвариант stdout:** bootstrap-часть не производит **ни одной** строки в success stream (stdout —
|
||||
канал JSON-RPC). Запрещён не только `Write-Host`: результаты `Get-Item`, `New-Item`,
|
||||
`ConvertFrom-Json`, `Get-FileHash`, `Expand-Archive` присваиваются или подавляются
|
||||
(`| Out-Null`); диагностика — только `[Console]::Error.WriteLine()`.
|
||||
|
||||
Командный промт (`plugin/commands/doctor.md`), проводящий агента по проверкам с конкретным действием
|
||||
на каждый отказ:
|
||||
Артефакт: **self-contained win-x64**, плоская структура ZIP (EXE в корне архива, без `publish/`),
|
||||
обязательный состав фиксируется списком в спеке реализации. Другу не нужен .NET 8 Runtime, нужен
|
||||
только КОМПАС. Цена — ~70 МБ на ассет.
|
||||
|
||||
1. `server.lock.json` — какая версия ожидается;
|
||||
2. наличие `%LOCALAPPDATA%\kompas-mcp\<version>\kompas-mcp.exe` (и `KOMPAS_MCP_EXE`, если задан);
|
||||
3. запущен ли процесс КОМПАС;
|
||||
4. отвечает ли инструмент `kompas_status`;
|
||||
5. итоговый отчёт.
|
||||
Мелкая задача в сервер: флаг `--version`, печатающий версию в stdout и выходящий, — даёт `doctor`
|
||||
сверку установленного бинаря с локом.
|
||||
|
||||
## 8. CI (Gitea Actions в `kompas3d-mcp`)
|
||||
## 8. Команда `/kompas:doctor`
|
||||
|
||||
**`ci.yml`** — push/PR в `main`: `dotnet build -c Release` + `dotnet test --filter Category=Unit`.
|
||||
Командный промт (`plugin/commands/doctor.md`) с конкретным действием на каждый отказ:
|
||||
|
||||
1. ожидаемая версия из `server.lock.json`;
|
||||
2. маркер `install.json` в `%LOCALAPPDATA%\kompas-mcp\<version>`: совпадают ли `version`/`sha256`;
|
||||
3. `kompas-mcp.exe --version` против лока (когда флаг появится);
|
||||
4. переопределение `KOMPAS_MCP_EXE`, если задано;
|
||||
5. запущен ли процесс КОМПАС;
|
||||
6. отвечает ли инструмент `kompas_status`;
|
||||
7. итоговый отчёт.
|
||||
|
||||
## 9. CI (Gitea Actions в `kompas3d-mcp`)
|
||||
|
||||
**`ci.yml`** — push/PR в `main`: `dotnet build -c Release` + `dotnet test --filter Category=Unit`;
|
||||
дополнительно проверка согласованности `plugin/server.lock.json` и `plugin/.claude-plugin/plugin.json`
|
||||
(версии совпадают, `sha256` непустой).
|
||||
|
||||
**Интеграционные тесты в CI не выполняются никогда** — им нужен запущенный КОМПАС с GUI и лицензией.
|
||||
Это граница, а не задача на будущее; фиксируется в README и в workflow комментарием.
|
||||
Это граница, а не задача на будущее.
|
||||
|
||||
**`release.yml`** — на тег `v*`:
|
||||
**`release.yml`** — на тег строго по шаблону `^v\d+\.\d+\.\d+$`, с `concurrency`-группой на весь
|
||||
workflow (параллельные релизы сериализуются):
|
||||
|
||||
1. `dotnet publish -c Release -r win-x64 --self-contained` → zip → sha256;
|
||||
2. создание релиза и загрузка ассета через Gitea API (`curl` + `secrets.GITEA_TOKEN`);
|
||||
3. бот-коммит в `main` с пометкой `[skip ci]`: обновить `plugin/server.lock.json`
|
||||
(version/url/sha256) и `version` в `plugin/.claude-plugin/plugin.json`.
|
||||
1. `dotnet publish src/Kompas.Mcp.Host/Kompas.Mcp.Host.csproj -c Release -r win-x64
|
||||
--self-contained true -p:EnableWindowsTargeting=true -o <dir>` → zip → sha256;
|
||||
2. проверка состава архива и того, что EXE — PE x64;
|
||||
3. **upsert** релиза и ассета через Gitea API (`curl` + `secrets.GITEA_TOKEN`): повторный запуск на
|
||||
том же теге не должен падать на «уже существует»; при совпадении SHA256 загрузка пропускается;
|
||||
4. скачать ассет по итоговому публичному URL и **повторно сверить SHA256** — только после этого
|
||||
публиковать указатель;
|
||||
5. отказ, если версия тега не больше версии в текущей `dist`;
|
||||
6. сформировать коммит в ветку `dist` поверх отмеченного тегом коммита: `server.lock.json`
|
||||
(version/sourceSha/url/sha256) и `version` в `plugin.json`.
|
||||
|
||||
Требования к раннеру (готовится в отдельной сессии «LXC для Gitea runner»): .NET 8 SDK, доступ к
|
||||
nuget.org, `curl` и `git`, токен Gitea с правами на релизы и запись в репозиторий. Если раннер
|
||||
Linux — сборка с `-p:EnableWindowsTargeting=true` (ожидается, что проект соберётся: WinForms/WPF не
|
||||
используются; **подлежит проверке первым же прогоном**, при неудаче — Windows-раннер).
|
||||
nuget.org, `curl` и `git`, токен Gitea с правами на релизы и запись в репозиторий.
|
||||
|
||||
## 9. Каталог и установка
|
||||
Cross-publish с Linux ожидаемо работает (`EnableWindowsTargeting` подтягивает Windows targeting/runtime
|
||||
packs; interop подключены как обычные ссылки, `ole32`/`oleaut32` разрешаются только в рантайме), но
|
||||
Microsoft рекомендует финальный релиз собирать на Windows, поэтому **перед объявлением релиза годным
|
||||
выполняется ручной smoke-run на Windows** (см. §12). Первым прогоном отдельно проверить, что
|
||||
`HintPath` с обратными слешами из `Directory.Build.props` разрешается на Unix.
|
||||
|
||||
## 10. Каталог и установка
|
||||
|
||||
В `home-repo-cc/.claude-plugin/marketplace.json` добавляется одна запись, один раз:
|
||||
|
||||
@@ -152,23 +236,35 @@ Linux — сборка с `-p:EnableWindowsTargeting=true` (ожидается,
|
||||
{ "name": "kompas",
|
||||
"source": { "source": "git-subdir",
|
||||
"url": "https://git.shahovalov.ru/mikhail/kompas3d-mcp.git",
|
||||
"path": "plugin", "ref": "main" },
|
||||
"path": "plugin", "ref": "dist" },
|
||||
"description": "КОМПАС-3D через MCP: построение деталей, сборки, чертежи, STEP",
|
||||
"category": "cad" }
|
||||
```
|
||||
|
||||
`ref: main`, а не тег: версия для Claude Code берётся из `plugin.json.version`, поднятого релизным
|
||||
коммитом, поэтому обновления доезжают через `/plugin marketplace update` сами и каталог руками больше
|
||||
не правится. Каталог приватный, плагин тянется из публичного репозитория — знакомому нужен доступ
|
||||
только к каталогу.
|
||||
Каталог приватный, плагин тянется из публичного репозитория — знакомому нужен доступ только к каталогу.
|
||||
|
||||
Путь пользователя: доступ в Gitea → `/plugin marketplace add https://git.shahovalov.ru/mikhail/home-repo-cc.git`
|
||||
→ `/plugin install kompas@home-repo-cc` → `/kompas:doctor`.
|
||||
Установка: доступ в Gitea → `/plugin marketplace add …/home-repo-cc.git` →
|
||||
`/plugin install kompas@home-repo-cc` → `/kompas:doctor`.
|
||||
|
||||
Обновление — **три шага, документируются явно**: `/plugin marketplace update home-repo-cc` →
|
||||
`/plugin update kompas@home-repo-cc` → при необходимости `/reload-plugins`. Полагаться на фоновое
|
||||
автообновление для приватного HTTPS-каталога нельзя (credential-helper в фоне отключён). Знакомым
|
||||
рекомендуется **SSH-ремоут каталога** (фоновые pull'ы аутентифицируются ключом из `ssh-agent`); при
|
||||
HTTPS — выставить `CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE=1`, чтобы неудачный фоновый pull
|
||||
не сносил клон.
|
||||
|
||||
Предпосылки в `plugin/README.md`: Windows x64; установленный и **запущенный** КОМПАС-3D (проверено на
|
||||
v24 Home); работа только на одной машине с КОМПАС (сервер — COM-клиент, не автономный CAD-движок).
|
||||
v24 Home); работа только на машине с КОМПАС (сервер — COM-клиент, не автономный CAD-движок);
|
||||
репозиторий/чекаут вне OneDrive-дерева.
|
||||
|
||||
## 10. Задел под Codex и opencode
|
||||
Жизненный цикл кеша (документируется, чтобы не пугало): Claude Code хранит каждую версию плагина в
|
||||
отдельном каталоге и держит осиротевшую примерно 14 дней; активная сессия продолжает работать со
|
||||
старым `CLAUDE_PLUGIN_ROOT` до `/reload-plugins`, поэтому старая и новая сессии могут одновременно
|
||||
поднять серверы разных версий из разных каталогов `%LOCALAPPDATA%\kompas-mcp\<version>`. Сам
|
||||
`%LOCALAPPDATA%\kompas-mcp` **не очищается** ни при обновлении, ни при удалении плагина — чистка
|
||||
вручную.
|
||||
|
||||
## 11. Задел под Codex и opencode
|
||||
|
||||
Ни Codex, ни opencode не знают ни `${CLAUDE_PLUGIN_ROOT}`, ни маркетплейсов: для них модель —
|
||||
клон репозитория и абсолютный путь. Задел выражается не декларацией, а тем, что контент не копируется:
|
||||
@@ -179,29 +275,51 @@ v24 Home); работа только на одной машине с КОМПА
|
||||
- лаунчер параметризуется только `server.lock.json`, навыки лежат в одном месте — новый харнесс стоит
|
||||
README и сниппета, а не форка контента.
|
||||
|
||||
Граница явная: это сниппеты и инструкция, а не дистрибутивы. Полноценные плагины Codex/opencode —
|
||||
отдельная веха, когда у них стабилизируется формат пакета.
|
||||
Граница явная: это сниппеты и инструкция, а не дистрибутивы.
|
||||
|
||||
## 11. Риски и открытые вопросы
|
||||
## 12. Риски и открытые вопросы
|
||||
|
||||
- **Приватный каталог** требует у знакомого аккаунта в Gitea и настроенного git-credential-helper;
|
||||
что Claude Code корректно клонирует приватный marketplace по https — проверить на живом человеке.
|
||||
- **Скачивание исполняемого файла** закрыто sha256-пином в репозитории; при несовпадении — отказ.
|
||||
- **Лицензионный статус interop-DLL АСКОН** при публичности плагина и self-contained-сборки —
|
||||
открытый вопрос, требует отдельного решения до выхода за круг знакомых.
|
||||
- **Рекурсия CI**: бот-коммит релиза помечается `[skip ci]`; проверить, что раннер это уважает.
|
||||
- **Сборка `net8.0-windows` на Linux-раннере** — ожидаемо работает с `EnableWindowsTargeting`,
|
||||
но не проверена.
|
||||
- **Расход диска**: каждая версия сервера ~70 МБ в `%LOCALAPPDATA%`; очистка старых версий — вручную.
|
||||
- **Право на редистрибуцию interop-DLL АСКОН — блокирующий вопрос до первого релиза**, а не до
|
||||
публичности: self-contained ассет уже раздаётся знакомым. Если право не подтверждается, interop в
|
||||
ассет не включается, и лаунчер должен брать разрешённые сборки из локальной установки SDK — это
|
||||
меняет модель дистрибуции, поэтому выясняется первым делом.
|
||||
- **Приватный каталог** требует у знакомого аккаунта в Gitea и настроенных кредов; фоновое
|
||||
автообновление по HTTPS ненадёжно (см. §10) — проверить на живом человеке.
|
||||
- **Скачивание исполняемого файла** закрыто sha256-пином в репозитории и повторной сверкой после
|
||||
публикации.
|
||||
- **Сборка `net8.0-windows` на Linux-раннере** не проверена; страховка — ручной Windows smoke-run
|
||||
перед объявлением релиза годным, при провале — Windows-раннер.
|
||||
- **Расход диска**: каждая версия сервера ~70 МБ в `%LOCALAPPDATA%`, чистка вручную.
|
||||
- Ревью Codex сняло пункт про «рекурсию CI»: `release.yml` висит только на теге, бот-коммит его не
|
||||
запускает; на `[skip ci]` полагаться не нужно.
|
||||
|
||||
## 12. Критерии приёмки
|
||||
## 13. Критерии приёмки
|
||||
|
||||
1. `tools/sync-agent-assets.ps1` отрабатывает на чистом клоне: навыки видны и в Claude Code, и в
|
||||
`.agents/skills`, при этом файлы физически существуют в одном месте.
|
||||
2. Тег `v*` даёт релиз в Gitea с ассетом и обновлённые `server.lock.json` / `plugin.json` в `main`.
|
||||
3. На машине без предустановленного сервера: `/plugin install kompas@home-repo-cc` → первый запуск
|
||||
скачивает бинарь, `/kompas:doctor` зелёный.
|
||||
4. Порча sha256 в `server.lock.json` приводит к отказу запуска с внятным сообщением в stderr.
|
||||
5. Ручная проверка канала: лаунчер получает `initialize` на stdin и отдаёт корректный JSON-RPC-ответ,
|
||||
в stdout нет посторонних строк.
|
||||
6. По playbook'у навыка `kompas:kompas-3d` строится деталь на свежей установке.
|
||||
1. `tools/sync-agent-assets.ps1` на чистом клоне: навыки видны и в Claude Code, и в `.agents/skills`,
|
||||
файлы физически существуют в одном месте; при невозможности junction — внятная ошибка, не копия.
|
||||
2. `git status` чист после sync: содержимое junction'ов не попадает в индекс.
|
||||
3. Тег `v*` даёт релиз с ассетом и коммит в `dist` с согласованными `server.lock.json` / `plugin.json`;
|
||||
повторный запуск на том же теге проходит без падения.
|
||||
4. Холодная установка: `/plugin install kompas@home-repo-cc` → первый запуск качает бинарь →
|
||||
`/kompas:doctor` зелёный.
|
||||
5. Две параллельные холодные установки (две сессии одновременно) обе стартуют успешно, каталог
|
||||
версии не повреждён.
|
||||
6. Обрыв загрузки и порча `sha256` в локе приводят к отказу с внятным сообщением в stderr и
|
||||
отсутствию целевого каталога; повторный запуск восстанавливается.
|
||||
7. Ненулевой код выхода сервера доходит до Claude Code (сервер не выглядит «успешно завершившимся»).
|
||||
8. Канал: лаунчер получает `initialize` на stdin и отдаёт корректный JSON-RPC-ответ; проверяются
|
||||
Unicode-содержимое, крупный ответ, поведение при EOF/shutdown, отсутствие осиротевшего
|
||||
`kompas-mcp.exe`; в stdout нет посторонних строк.
|
||||
9. Обновление во время активной старой сессии: старая сессия продолжает работать, новая поднимает
|
||||
новую версию.
|
||||
10. Windows smoke-run бинаря, собранного на Linux-раннере, перед объявлением релиза годным.
|
||||
11. По playbook'у навыка `kompas:kompas-3d` строится деталь на свежей установке — навык не
|
||||
ссылается на отсутствующие в плагине ресурсы.
|
||||
|
||||
## 14. Что из ревью отклонено
|
||||
|
||||
- **Защита от двух параллельных тегов через CAS/rebase-push и строгую монотонность semver в общем
|
||||
виде.** У репозитория один мейнтейнер; достаточно `concurrency`-группы, шаблона тега и отказа при
|
||||
неувеличивающейся версии. Полная машинерия — цена без сценария.
|
||||
- **Обязательный Windows smoke-run как автоматический гейт релиза.** Windows-раннера нет и он не
|
||||
планируется; заменён ручным пунктом приёмки (§13.10).
|
||||
|
||||
Reference in New Issue
Block a user