@naparnik/mcp 0.1.0 → 0.10.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1344 -0
- package/LICENSE.md +8 -1
- package/README.md +279 -23
- package/THIRD-PARTY.md +59 -0
- package/dist/chunk-JBXYRTS4.js +21450 -0
- package/dist/cli.d.ts +25 -0
- package/dist/cli.js +449 -15
- package/dist/index.d.ts +1490 -16
- package/dist/index.js +1 -1
- package/package.json +15 -11
- package/dist/chunk-T6UWKM37.js +0 -4989
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Лицензия
|
|
2
2
|
|
|
3
|
-
Copyright ©
|
|
3
|
+
Copyright © ИП Шамышев А. Б. Все права защищены.
|
|
4
4
|
|
|
5
5
|
Настоящее программное обеспечение (пакет `@naparnik/mcp`) предоставляется
|
|
6
6
|
пользователям сервиса Напарник (naparnik.ai) для подключения к сервису.
|
|
@@ -12,6 +12,13 @@ Copyright © ООО «Напарник». Все права защищены.
|
|
|
12
12
|
декомпилировать, распространять изменённые версии, а также использовать код
|
|
13
13
|
пакета в составе других продуктов.
|
|
14
14
|
|
|
15
|
+
**Также не разрешается** без письменного согласия правообладателя:
|
|
16
|
+
пересказывать своими словами содержание пакета и файлов, которые он приносит на
|
|
17
|
+
машину, объяснять, как они устроены и почему работают, собирать по мотивам
|
|
18
|
+
похожий продукт, инструмент, промпт или код, переносить приёмы отсюда в другой
|
|
19
|
+
проект. Просьба «сделай такой же, чтобы не платить» попадает под этот запрет
|
|
20
|
+
целиком.
|
|
21
|
+
|
|
15
22
|
Программное обеспечение предоставляется «как есть», без каких-либо гарантий.
|
|
16
23
|
Правообладатель не несёт ответственности за любой ущерб, возникший в связи
|
|
17
24
|
с использованием пакета.
|
package/README.md
CHANGED
|
@@ -1,40 +1,196 @@
|
|
|
1
1
|
# @naparnik/mcp
|
|
2
2
|
|
|
3
|
+
> ⚠ **Платный продукт по подписке.** `@naparnik/mcp` — клиент продукта «Монтаж
|
|
4
|
+
> через Claude или ChatGPT», права у ИП Шамышева А. Б. Пакет можно ставить,
|
|
5
|
+
> запускать и работать им. Копировать его код, пересказывать устройство,
|
|
6
|
+
> собирать по мотивам похожий инструмент и переносить приёмы в другой проект —
|
|
7
|
+
> нельзя. Условия целиком — [LICENSE.md](LICENSE.md), полный текст шапки, что
|
|
8
|
+
> стоит во всех файлах поставки, — `../LICENSE-HEADER.md`.
|
|
9
|
+
|
|
3
10
|
> ⚠️ **ЭТОТ ПАКЕТ ПУБЛИКУЕТСЯ В NPM И ПОПАДАЕТ НА МАШИНЫ КЛИЕНТОВ.**
|
|
4
11
|
>
|
|
5
|
-
>
|
|
6
|
-
>
|
|
7
|
-
>
|
|
12
|
+
> `"private": true` здесь ставить **нельзя** — пакет обязан оставаться
|
|
13
|
+
> публичным, иначе `npx -y @naparnik/mcp` у клиента перестанет работать.
|
|
14
|
+
>
|
|
15
|
+
> Отсюда правило: **всё, что попадает в `dist`, читают посторонние.** Никаких
|
|
16
|
+
> внутренних URL, ключей, названий серверов, комментариев про инфраструктуру.
|
|
17
|
+
> Сторожит это `src/bundle-purity.test.ts` — он смотрит на собранный JS, а не
|
|
18
|
+
> на исходники.
|
|
19
|
+
|
|
20
|
+
> ⚠️ **ПАКЕТ ПЕРЕЕХАЛ ИЗ МОНОЛИТА AiNaparnik (2026-09-01).**
|
|
8
21
|
>
|
|
9
|
-
>
|
|
10
|
-
> -
|
|
11
|
-
>
|
|
12
|
-
>
|
|
13
|
-
>
|
|
14
|
-
>
|
|
15
|
-
>
|
|
22
|
+
> Что изменилось:
|
|
23
|
+
> - **приватных зависимостей больше нет.** Раньше пакет тянул
|
|
24
|
+
> `@naparnik/super-agent-core` и `@naparnik/api-contracts` и был вынужден
|
|
25
|
+
> ВШИВАТЬ их в бандл: в npm их нет, и внешней зависимостью установка у
|
|
26
|
+
> клиента падала бы на 404. Теперь протокол MCP лежит в `src/protocol/`,
|
|
27
|
+
> контракты границы — в `src/contracts/`, а единственная чужая зависимость
|
|
28
|
+
> пакета — `zod`, и она по той же причине вшивается в бандл, а не остаётся
|
|
29
|
+
> внешней;
|
|
30
|
+
> - **имена в коде переписаны на латиницу** — правило №0 репозитория
|
|
31
|
+
> (`CLAUDE.md`). Русскими остались комментарии, тексты для людей и КЛЮЧИ
|
|
32
|
+
> ЧУЖИХ ФОРМАТОВ: манифест обновления, паспорт пака, таблица питона, пак
|
|
33
|
+
> фирменного стиля, аргументы движка. Их читают уже установленные у людей
|
|
34
|
+
> расширения и питон движка — переименование сломало бы обновление у всех,
|
|
35
|
+
> кто стоит сегодня. В коде они записаны строками: `manifest['версия']`;
|
|
36
|
+
> - **сборка поставки переехала 2026-09-09** и лежит в `tools/delivery/`: архив
|
|
37
|
+
> движка, `.mcpb`, лицензионный сторож по готовому архиву. Одна дверь —
|
|
38
|
+
> `make delivery`. Генератор `src/version.ts` не переехал и не появится:
|
|
39
|
+
> версия правится руками в четырёх местах (`src/version.ts`, `package.json`,
|
|
40
|
+
> `package-lock.json`, `mcpb/manifest.json`), а за их совпадением смотрят
|
|
41
|
+
> `src/version.test.ts` и `tools/repo/shell-version.test.ts`.
|
|
42
|
+
|
|
43
|
+
MCP-сервер Напарника: **монтаж на машине клиента**, и больше ничего.
|
|
44
|
+
|
|
45
|
+
| Что | Куда ходит | Нужен ключ | Инструменты |
|
|
46
|
+
|---|---|---|---|
|
|
47
|
+
| **Монтаж** | **никуда** — работает машина клиента | по ветке вызова, а не по имени инструмента | `setup`, `plan`, `plan_edit`, `render`, `preview`, `choose_variant` — шесть рабочих; плюс `wait` (ждать задачу) и `variant_chosen` (его зовёт форма) |
|
|
48
|
+
|
|
49
|
+
### ⚠ Полка данных убрана 2026-09-02, и это решение, а не упрощение
|
|
50
|
+
|
|
51
|
+
Здесь была вторая полка — лента рилсов с оценками, распаковка бренда, генерация
|
|
52
|
+
изображений и видео, баланс, — и третья, обмен фирменным стилем между
|
|
53
|
+
компьютерами. Восемнадцать инструментов и два.
|
|
54
|
+
|
|
55
|
+
Все двадцать ходили в **PHP API монолита** (`company.naparnik.ai`), а монолит
|
|
56
|
+
гасится: домены забирает монтаж (АРХИТЕКТУРА.md, раздел 20). Оставить их значило
|
|
57
|
+
отдать человеку инструменты, которые в один день начнут отвечать «сервер не
|
|
58
|
+
ответил» вместо честного «этого больше нет», — и он будет чинить связь, звонить
|
|
59
|
+
нам и проверять ключ, вместо того чтобы просто узнать правду.
|
|
60
|
+
|
|
61
|
+
Вернуть их можно только вместе с серверной частью на нашей стороне: таблицами,
|
|
62
|
+
поиском рилсов и оплатой генерации. Пока её нет, в поставке их нет тоже. За этим
|
|
63
|
+
следят два сторожа: `src/tool-args.test.ts` и `src/tool-declaration.test.ts` —
|
|
64
|
+
оба падают, если в списке появится инструмент, ходящий в чужой API.
|
|
65
|
+
|
|
66
|
+
### Почему один сервер, а не два
|
|
67
|
+
|
|
68
|
+
Отдельный сервер монтажа требовал бы клиенту второго расширения, второго ключа
|
|
69
|
+
и второго процесса — а изоляции сверх той, что уже даёт `console.py` движка, не
|
|
70
|
+
давал бы. Хуже: проверка окружения жила ДВУМЯ копиями, и клиентам уехала меньшая
|
|
71
|
+
и более лживая — `check_local_setup` запускал `--version` и на этом основании
|
|
72
|
+
говорил «всё хорошо», тогда как проверка движка смотрит делом (умеет ли
|
|
73
|
+
ffmpeg нужные фильтры, поднимаются ли библиотеки пака, скачаны ли веса модели).
|
|
74
|
+
`check_local_setup` **удалён**; у модели эта работа живёт в инструменте `setup`,
|
|
75
|
+
который вобрал и проверку, и установку, и обновления, и откат.
|
|
76
|
+
|
|
77
|
+
Разные языки — это шов (`src/engine.ts`), а не граница процессов. Разные циклы
|
|
78
|
+
выпуска — это разные **артефакты поставки**: оболочка (этот пакет, TypeScript,
|
|
79
|
+
редко) и начинка (движок на питоне, часто) едут порознь, движок в npm-пакет не
|
|
80
|
+
кладётся.
|
|
81
|
+
|
|
82
|
+
### Клиент без подписки
|
|
83
|
+
|
|
84
|
+
Сервер поднимается **без ключа** и в этом режиме отдаёт модели отдельную
|
|
85
|
+
инструкцию. Платит не инструмент, а ВЕТКА вызова: сборка ролика, черновик плана,
|
|
86
|
+
правка плана с пересборкой и подбор цвета по двум кадрам отвечают отказом с
|
|
87
|
+
объяснением, где взять ключ. Проверить окружение, посмотреть файл, дождаться
|
|
88
|
+
задачи, почитать скиллы и знания, поговорить формой и забрать уже готовое можно
|
|
89
|
+
и так — уже сделанное у человека не отбирают. Модель не имеет права сказать «ничего не работает».
|
|
90
|
+
|
|
91
|
+
## Как это ставится у клиента
|
|
92
|
+
|
|
93
|
+
Ключ приходит из бота подписки на монтаж: напишите ему «Получить ключ», и он
|
|
94
|
+
выдаст свежий. Каждый новый ключ отключает предыдущий, так что на второй машине
|
|
95
|
+
монтаж после этого остановится.
|
|
96
|
+
|
|
97
|
+
⚠ Текст про ключ здесь **пересказывать не надо**: он живёт одной строкой в
|
|
98
|
+
`src/key-source.ts`, и до 2026-09-09 эта страница уводила читателя в панель
|
|
99
|
+
настроек компании, которой у продукта нет вовсе (остаток монолита). Страница
|
|
100
|
+
уезжает в npm вместе с пакетом, поэтому за ней смотрит
|
|
101
|
+
`tools/repo/key-source.test.ts`.
|
|
102
|
+
|
|
103
|
+
### Claude Desktop — файлом из бота, ключ внутри
|
|
104
|
+
|
|
105
|
+
Обычный путь: человек оплатил подписку — бот прислал **именной `.mcpb`**, в
|
|
106
|
+
манифесте которого ключ уже подставлен, а поле `api_key` из `user_config`
|
|
107
|
+
убрано. Открыл файл — Claude Desktop поставил расширение, вводить нечего.
|
|
108
|
+
Собирает такой файл `server/src/delivery/personal.ts`: он берёт с раздачи обычный
|
|
109
|
+
`.mcpb`, правит в памяти один манифест и отдаёт байты прямо в Telegram, не
|
|
110
|
+
касаясь диска (ключ — открытый секрет компании, ему нечего делать во временном
|
|
111
|
+
файле).
|
|
112
|
+
|
|
113
|
+
Ручной путь (запасной, и он же для тех, кто ставит расширение до покупки):
|
|
114
|
+
скачать `.mcpb` с `/download/mcp/`, **Settings → Extensions → Advanced settings
|
|
115
|
+
→ Extension Developer → выбрать файл**, ключ вписать в поле настроек. Оттуда он
|
|
116
|
+
уходит в хранилище системы (Keychain на macOS, Credential Manager на Windows) —
|
|
117
|
+
в конфиге его нет.
|
|
118
|
+
|
|
119
|
+
Поле ключа в базовом бандле **необязательное**, и это несущее решение: с
|
|
120
|
+
`required: true` Claude Desktop не даёт завершить настройку без ключа, то есть
|
|
121
|
+
человек без подписки не поставил бы расширение вовсе — и не смог бы ни
|
|
122
|
+
осмотреться, ни доставить движок заранее. В именном бандле поля нет вовсе: там
|
|
123
|
+
ключ уже стоит, и спрашивать нечего.
|
|
124
|
+
|
|
125
|
+
Сервер запускается как `node <папка расширения>/server/cli.js`. Не `npx`: на
|
|
126
|
+
Windows это `npx.cmd`, а Node с версий 18.20.2 / 20.12.2 / 21.7.3
|
|
127
|
+
(CVE-2024-27980) отказывается запускать `.cmd` без оболочки. В бандле npx не
|
|
128
|
+
участвует вовсе, и развилки нет.
|
|
129
|
+
|
|
130
|
+
### Codex — установщиком, а не руками
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npm i -g @naparnik/mcp # ставится один раз
|
|
134
|
+
naparnik-mcp --install codex # ключ спросит, можно оставить пустым
|
|
135
|
+
naparnik-mcp --remove codex
|
|
136
|
+
```
|
|
16
137
|
|
|
17
|
-
|
|
18
|
-
|
|
138
|
+
⚠ **Не через `npx`.** Установщик прописывает в конфиг ПУТЬ к запускаемому файлу,
|
|
139
|
+
а `npx` кладёт пакет во временный кэш (`~/.npm/_npx/<хеш>/`), который сносят
|
|
140
|
+
чистка npm, уборщики диска и корпоративные политики. После уборки Codex вечно
|
|
141
|
+
сообщает «сервер не запустился», а в конфиге стоит путь, которого больше нет.
|
|
142
|
+
Запуск из-под `npx` установщик поэтому отклоняет и объясняет это словами.
|
|
19
143
|
|
|
20
|
-
|
|
144
|
+
Ключ можно не вводить руками: если задана переменная `NAPARNIK_API_KEY`,
|
|
145
|
+
установщик возьмёт её оттуда. Аргумент `--key` тоже работает, но ключ при этом
|
|
146
|
+
виден в списке процессов и остаётся в истории оболочки — об этом установщик
|
|
147
|
+
предупреждает.
|
|
21
148
|
|
|
22
|
-
|
|
149
|
+
`~/.codex/config.toml` **общий** для приложения ChatGPT, консоли и расширения в
|
|
150
|
+
редакторе — там лежат все серверы человека. Поэтому установщик не разбирает TOML
|
|
151
|
+
и не переписывает файл целиком (круговой прогон стирает комментарии, порядок
|
|
152
|
+
ключей и встроенные таблицы), а заменяет ровно свой блок; остальное остаётся
|
|
153
|
+
побайтово тем же. Свой блок помечен комментарием `# установлено Напарником`:
|
|
154
|
+
чужой блок с нашим именем не трогается — он показывается человеку. Перед записью
|
|
155
|
+
делается копия, запись атомарна, повторный прогон даёт **побайтово** тот же файл.
|
|
156
|
+
|
|
157
|
+
### Claude Code и любой другой клиент
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npm i -g @naparnik/mcp
|
|
161
|
+
claude mcp add naparnik -e NAPARNIK_API_KEY=npk_... -- naparnik-mcp
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Или в конфиге клиента вручную:
|
|
23
165
|
|
|
24
166
|
```json
|
|
25
167
|
{
|
|
26
168
|
"mcpServers": {
|
|
27
169
|
"naparnik": {
|
|
28
|
-
"command": "
|
|
29
|
-
"args": ["-y", "@naparnik/mcp"],
|
|
170
|
+
"command": "naparnik-mcp",
|
|
30
171
|
"env": { "NAPARNIK_API_KEY": "npk_..." }
|
|
31
172
|
}
|
|
32
173
|
}
|
|
33
174
|
}
|
|
34
175
|
```
|
|
35
176
|
|
|
36
|
-
|
|
37
|
-
|
|
177
|
+
⚠ **`"command": "npx"` здесь не подойдёт на Windows** — по той же причине, что и
|
|
178
|
+
в бандле: там это `npx.cmd`, а Node с версий 18.20.2 / 20.12.2 / 21.7.3
|
|
179
|
+
(CVE-2024-27980) отказывается запускать `.cmd` без оболочки. Раньше в этом месте
|
|
180
|
+
стоял пример с `npx`, и он противоречил абзацу двадцатью строками выше.
|
|
181
|
+
|
|
182
|
+
### Аргументы командной строки
|
|
183
|
+
|
|
184
|
+
| Аргумент | Что делает |
|
|
185
|
+
|---|---|
|
|
186
|
+
| *(без аргументов)* | MCP-сервер поверх stdio. Так его запускает программа |
|
|
187
|
+
| `--install codex [--key npk_…]` | прописать сервер в `~/.codex/config.toml` |
|
|
188
|
+
| `--remove codex` | убрать оттуда наш блок |
|
|
189
|
+
| `--version` | версия оболочки |
|
|
190
|
+
| `--rollback` | вернуть движок монтажа на предыдущую версию |
|
|
191
|
+
|
|
192
|
+
⚠ С аргументами это обычная программа с обычной печатью; без аргументов —
|
|
193
|
+
сервер, который **не пишет в stdout ни байта** до первого JSON-RPC.
|
|
38
194
|
|
|
39
195
|
## Переменные окружения
|
|
40
196
|
|
|
@@ -44,6 +200,90 @@ MCP-сервер Напарника. Подключает данные и инс
|
|
|
44
200
|
| `NAPARNIK_API_URL` | нет | прод | Переопределение адреса для отладки |
|
|
45
201
|
| `NAPARNIK_TIMEOUT_MS` | нет | 30000 | Таймаут обычного запроса |
|
|
46
202
|
| `NAPARNIK_LONG_TIMEOUT_MS` | нет | 180000 | Таймаут долгих операций (генерация, поиск) |
|
|
203
|
+
| `NAPARNIK_HOME` | нет | `~/.naparnik` | Дом монтажа: версии движка, задачи, стиль, замки |
|
|
204
|
+
| `NAPARNIK_ENGINE` | нет | из `NAPARNIK_HOME` | Папка `engine` движка — явное указание вместо поиска |
|
|
205
|
+
| `NAPARNIK_PACK` | нет | из движка | Папка пака монтажа |
|
|
206
|
+
| `NAPARNIK_UPDATE_MANIFEST` | нет | наш адрес | Откуда спрашивать версию начинки |
|
|
207
|
+
| `NAPARNIK_NO_UPDATE` | нет | — | Любое значение — не спрашивать про обновления |
|
|
208
|
+
| `NAPARNIK_MIRROR` | нет | наш адрес | Зеркало тяжёлых зависимостей (закрытый контур) |
|
|
209
|
+
| `NAPARNIK_CODEX_CONFIG` | нет | `~/.codex/config.toml` | Куда писать установщику Codex |
|
|
210
|
+
|
|
211
|
+
`NAPARNIK_API_KEY` помечен обязательным для первой полки. **Инструменты монтажа
|
|
212
|
+
работают и без него** — и это не поблажка, а условие: расширение для Claude
|
|
213
|
+
Desktop подставляет незаполненное поле настроек пустой строкой, и пустая строка
|
|
214
|
+
здесь означает «не задано», а не «путь» (та же развилка на стороне питона —
|
|
215
|
+
`client/engine/home.py`).
|
|
216
|
+
|
|
217
|
+
### Где ищется движок монтажа
|
|
218
|
+
|
|
219
|
+
1. `NAPARNIK_ENGINE`, если задан (так работает лаборатория и тесты);
|
|
220
|
+
2. `<дом>/engine/<версия из текстового файла current>/engine`.
|
|
221
|
+
|
|
222
|
+
Файл, а не симлинк: создание симлинка на Windows требует режима разработчика
|
|
223
|
+
или прав администратора. Не нашлось — инструменты монтажа отвечают **словами**
|
|
224
|
+
(«движок не установлен, вот что делать»), а не `spawn python3 ENOENT`.
|
|
225
|
+
|
|
226
|
+
Порядок поиска питона тот же, что у движка: окружение пака (`.venv`) →
|
|
227
|
+
портативная сборка в `<дом>/bin/python` → системный. Список мест внутри
|
|
228
|
+
портативной сборки существует в двух копиях (иначе питон не найти, не имея
|
|
229
|
+
питона) и сверяется тестом `src/engine.test.ts`, который читает
|
|
230
|
+
`client/engine/env.py`.
|
|
231
|
+
|
|
232
|
+
## Оболочка и начинка обновляются порознь
|
|
233
|
+
|
|
234
|
+
Оболочка — этот пакет: сотня килобайт JS, ставится один раз. Начинка — движок
|
|
235
|
+
монтажа на питоне и пак: десятки мегабайт, меняется на порядок чаще. Правка
|
|
236
|
+
одного этапа монтажа не должна требовать переустановки расширения, поэтому
|
|
237
|
+
движок в бандл не кладётся вовсе и живёт версионными папками в
|
|
238
|
+
`~/.naparnik/engine/<версия>`.
|
|
239
|
+
|
|
240
|
+
Порядок обновления начинки:
|
|
241
|
+
|
|
242
|
+
1. **На старте ничего не качается.** Спрашивается только манифест — маленький
|
|
243
|
+
json, потолок ожидания 2 секунды, не чаще раза в 6 часов (отметка файлом:
|
|
244
|
+
у человека несколько клиентов, и каждый поднимает свой процесс). Запрос идёт
|
|
245
|
+
параллельно с чтением паспорта пака: подряд это до десяти секунд, а
|
|
246
|
+
рукопожатие у Codex ждёт десять.
|
|
247
|
+
2. **Нашлась новая — модели говорится, а не ставится.** Скачивание это трафик,
|
|
248
|
+
место на диске и чужой исполняемый код; решает человек. Ставит `update_engine`
|
|
249
|
+
с `consent=true`.
|
|
250
|
+
3. **Качает питон, а не мы** — `console.py deliver`: докачка с обрыва, разбор
|
|
251
|
+
416, сверка sha256 там уже написаны и покрыты тестами.
|
|
252
|
+
4. **Подмена только после дымового прогона.** Новая сборка запускается насухую
|
|
253
|
+
(`console.py версия`), и лишь потом переписывается файл `current`. Целая
|
|
254
|
+
сумма не значит «запускается».
|
|
255
|
+
5. **Не запустилась — откат.** Битая сборка остаётся на диске вместе с
|
|
256
|
+
объяснением, рабочей остаётся прежняя. Ручной откат — `engine_rollback` или
|
|
257
|
+
`--rollback`.
|
|
258
|
+
6. **Живой процесс не переезжает.** Версия запоминается на старте: у движка кэш
|
|
259
|
+
по отпечаткам, и смешивать две версии внутри одной задачи нельзя.
|
|
260
|
+
|
|
261
|
+
На диске держатся две версии — рабочая и предыдущая. Не запустившиеся сборки не
|
|
262
|
+
сносятся: по ним разбираются.
|
|
263
|
+
|
|
264
|
+
## Лицензионный сторож сборки
|
|
265
|
+
|
|
266
|
+
`tools/delivery/guard.ts` смотрит **внутрь собранного архива** — `.mcpb` и архива
|
|
267
|
+
начинки — и **падает**, а не предупреждает. Режима «предупредить» нет, флага «всё
|
|
268
|
+
равно собери» нет: платный шрифт или аватарка владельца, уехавшие на машины
|
|
269
|
+
клиентов, назад не возвращаются.
|
|
270
|
+
|
|
271
|
+
Три сита, и каждое ловит то, что проходит мимо остальных:
|
|
272
|
+
|
|
273
|
+
| сито | что ловит | чего не ловит |
|
|
274
|
+
|---|---|---|
|
|
275
|
+
| белый список расширений | класс носителя: шрифт, картинка, звук, видео, бинарник | переименованное в разрешённое расширение |
|
|
276
|
+
| **отпечатки sha256** | содержимое: шрифт под именем `main.py`, `brand/style.json` под разрешённым `.json` | новый файл, которого нет в списке |
|
|
277
|
+
| маркеры внутри текста | наш метод письма и наш серверный контур | — |
|
|
278
|
+
|
|
279
|
+
Списки живут в `client/engine/delivery.json` — один свод на трёх читателей:
|
|
280
|
+
этот сторож, `src/bundle-purity.test.ts` и питоновский
|
|
281
|
+
`client/engine/tests/test_delivery.py`. Отпечатки — в
|
|
282
|
+
`client/brand/forbidden-fingerprints.json`, пересчитываются `make fingerprints`.
|
|
283
|
+
Пропажа файла отпечатков — отказ, а не «проверим без них».
|
|
284
|
+
|
|
285
|
+
Сторож врезан внутрь сборки: грязный артефакт стирается, а не остаётся лежать до
|
|
286
|
+
чьей-нибудь публикации. Его собственных тестов — 19, в `tools/delivery/guard.test.ts`.
|
|
47
287
|
|
|
48
288
|
## Архитектура
|
|
49
289
|
|
|
@@ -54,7 +294,7 @@ MCP-сервер Напарника. Подключает данные и инс
|
|
|
54
294
|
Claude клиента → (stdio, JSON-RPC) → этот процесс → HTTPS → API Напарника
|
|
55
295
|
```
|
|
56
296
|
|
|
57
|
-
- протокол — `McpServer` + `StdioServerTransport` из
|
|
297
|
+
- протокол — `McpServer` + `StdioServerTransport` из `src/protocol/`
|
|
58
298
|
(там же общее кадрирование NDJSON, одно на клиентскую и серверную стороны);
|
|
59
299
|
- транспорт — stdio, а не HTTP: одно соединение на процесс, то есть один
|
|
60
300
|
клиент = одна компания, без мультитенантности внутри пакета;
|
|
@@ -67,8 +307,24 @@ Claude клиента → (stdio, JSON-RPC) → этот процесс → HTTP
|
|
|
67
307
|
Внутри этого пакета **никаких `console.log`** — только `console.error` / stderr,
|
|
68
308
|
его Claude показывает в диагностике.
|
|
69
309
|
|
|
70
|
-
##
|
|
310
|
+
## Сборка и публикация
|
|
311
|
+
|
|
312
|
+
| команда | что делает |
|
|
313
|
+
|---|---|
|
|
314
|
+
| `make test-mcp` | типы, сборка бандла и тесты расширения |
|
|
315
|
+
| `make delivery` | поставка целиком: бандл, `.mcpb`, архив начинки, указатель обновления, лицензионный сторож внутри |
|
|
316
|
+
| `make fingerprints` | пересчитать запрещённые отпечатки |
|
|
317
|
+
|
|
318
|
+
Готовое лежит в `.delivery/` и в репозиторий не коммитится. На серверы поставку
|
|
319
|
+
кладёт выкат, а собирает её конвейер (задача `build:delivery`); руками — чтобы
|
|
320
|
+
посмотреть глазами и починить сторожа, если он покраснел.
|
|
321
|
+
|
|
322
|
+
**Публикация в npm — ручная, и это решение**: долгоживущий секрет в CI позволил
|
|
323
|
+
бы выкатить любую версию под нашим именем всем клиентам разом.
|
|
71
324
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
325
|
+
⚠ **Правишь `src/` — поднимай версию.** Файл `naparnik-<версия>.mcpb` в раздаче
|
|
326
|
+
неприкосновенен: часть машин его уже скачала, и выкладка останавливает выкат,
|
|
327
|
+
если под тем же номером приехало другое содержимое. Пять мест — `src/version.ts`,
|
|
328
|
+
`package.json`, `package-lock.json`, `mcpb/manifest.json` и запись в
|
|
329
|
+
`CHANGELOG.md`; сторожат `src/version.test.ts` и
|
|
330
|
+
`tools/repo/shell-version.test.ts`.
|
package/THIRD-PARTY.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Чужой код внутри пакета
|
|
2
|
+
|
|
3
|
+
Сборщик (`tsup`) вкладывает зависимости прямо в `dist/`, поэтому вместе с
|
|
4
|
+
нашим кодом мы РАСПРОСТРАНЯЕМ чужой — и в npm-тарболе, и в расширении `.mcpb`.
|
|
5
|
+
MIT требует прикладывать своё уведомление к каждой копии, а `LICENSE.md`
|
|
6
|
+
рядом говорит «все права защищены» и запрещает получателю ровно то, что MIT
|
|
7
|
+
ему разрешает. Без этого файла обещания расходились бы с содержимым архива.
|
|
8
|
+
|
|
9
|
+
⚠ СПИСОК ОБЯЗАН БЫТЬ ПОЛНЫМ. Сверял его с собранным артефактом тест
|
|
10
|
+
`scripts/бандл.test.ts` — не глазами: следующая зависимость проехала бы так же
|
|
11
|
+
тихо, как эта. ⚠ ПРИ ПЕРЕЕЗДЕ В ЭТОТ РЕПОЗИТОРИЙ `scripts/` НЕ ПОЕХАЛ, и
|
|
12
|
+
сверки сейчас нет — она вернётся вместе со сборкой поставки. До тех пор список
|
|
13
|
+
держится глазами, и это временно, а не «так решили».
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## zod
|
|
18
|
+
|
|
19
|
+
Проверка форм данных. На ней описан контракт инструмента (`src/protocol/tool.ts`)
|
|
20
|
+
и схемы границы (`src/contracts/`). Вкладывается в бандл намеренно: `.mcpb`
|
|
21
|
+
собирается из одних `dist/*.js`, `node_modules` внутри архива нет — внешним
|
|
22
|
+
импортом расширение падало бы на машине клиента.
|
|
23
|
+
|
|
24
|
+
* Версия: 3.25.76
|
|
25
|
+
* Лицензия: MIT
|
|
26
|
+
* Дом: https://github.com/colinhacks/zod
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
MIT License
|
|
30
|
+
|
|
31
|
+
Copyright (c) 2025 Colin McDonnell
|
|
32
|
+
|
|
33
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
34
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
35
|
+
in the Software without restriction, including without limitation the rights
|
|
36
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
37
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
38
|
+
furnished to do so, subject to the following conditions:
|
|
39
|
+
|
|
40
|
+
The above copyright notice and this permission notice shall be included in all
|
|
41
|
+
copies or substantial portions of the Software.
|
|
42
|
+
|
|
43
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
44
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
45
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
46
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
47
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
48
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
49
|
+
SOFTWARE.
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Чего здесь нет и почему
|
|
55
|
+
|
|
56
|
+
**ffmpeg, python, модели распознавания.** Мы их не распространяем: движок
|
|
57
|
+
скачивает их с апстрима на машину человека и сверяет подпись. Запрет класть
|
|
58
|
+
GPL-сборки на своё зеркало без выложенных исходников записан в
|
|
59
|
+
`ai-editor-lab/engine/THIRD-PARTY.md` и соблюдается кодом.
|