@maxisoft/instantcms-mcp 1.2.3
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/LICENSE +21 -0
- package/README.md +308 -0
- package/dist/__tests__/artifact-tool.test.js +196 -0
- package/dist/__tests__/db-tool.test.js +152 -0
- package/dist/__tests__/define-tool.test.js +106 -0
- package/dist/__tests__/find-tool.test.js +185 -0
- package/dist/__tests__/get-component-api.test.js +144 -0
- package/dist/__tests__/hardening.test.js +73 -0
- package/dist/__tests__/hooks-tool.test.js +173 -0
- package/dist/__tests__/mcp-integration-extra.test.js +166 -0
- package/dist/__tests__/mcp-integration.test.js +53 -0
- package/dist/__tests__/pagination.test.js +114 -0
- package/dist/__tests__/performance-baseline.test.js +56 -0
- package/dist/__tests__/project-patch.test.js +144 -0
- package/dist/__tests__/project-source.test.js +44 -0
- package/dist/__tests__/project-workflows-extra.test.js +165 -0
- package/dist/__tests__/project-workflows.test.js +51 -0
- package/dist/__tests__/scaffold-addon-roundtrip.test.js +287 -0
- package/dist/__tests__/serialization.test.js +170 -0
- package/dist/__tests__/source-knowledge-parsers.test.js +42 -0
- package/dist/__tests__/template-development.test.js +78 -0
- package/dist/__tests__/template-productivity.test.js +87 -0
- package/dist/__tests__/tools.test.js +2143 -0
- package/dist/data/components.js +2818 -0
- package/dist/data/controllers-map.js +7571 -0
- package/dist/data/core-api.js +9356 -0
- package/dist/data/database-schema.js +4555 -0
- package/dist/data/events-map.js +1339 -0
- package/dist/data/fields-map.js +3692 -0
- package/dist/data/hooks.js +2257 -0
- package/dist/data/js-api.js +123 -0
- package/dist/data/libs-api.js +264 -0
- package/dist/data/routes-map.js +203 -0
- package/dist/data/schemas-validation.js +255 -0
- package/dist/data/schemas.js +1404 -0
- package/dist/data/traits-map.js +1004 -0
- package/dist/data/version-profiles.js +41 -0
- package/dist/data/widgets-map.js +131 -0
- package/dist/data/wysiwyg-map.js +486 -0
- package/dist/generated/components-source.js +14748 -0
- package/dist/generated/hooks-source.js +3399 -0
- package/dist/generated/knowledge-meta.js +101 -0
- package/dist/index.js +13 -0
- package/dist/registry/database-tools.js +112 -0
- package/dist/registry/extension-tools.js +473 -0
- package/dist/registry/generator-tools.js +506 -0
- package/dist/registry/knowledge-tools.js +441 -0
- package/dist/registry/language-tools.js +99 -0
- package/dist/registry/meta-tools.js +152 -0
- package/dist/registry/project-tools.js +48 -0
- package/dist/registry/resources.js +98 -0
- package/dist/registry/source-tools.js +211 -0
- package/dist/registry/template-development-tools.js +79 -0
- package/dist/server.js +32 -0
- package/dist/tools/addon-tool.js +1437 -0
- package/dist/tools/admin-partial-tool.js +498 -0
- package/dist/tools/api-tool.js +294 -0
- package/dist/tools/artifact-tool.js +95 -0
- package/dist/tools/cache-tool.js +360 -0
- package/dist/tools/component-tool.js +415 -0
- package/dist/tools/controllers-tool.js +125 -0
- package/dist/tools/cron-tool.js +197 -0
- package/dist/tools/crud-tool.js +659 -0
- package/dist/tools/db-tool.js +198 -0
- package/dist/tools/email-tool.js +222 -0
- package/dist/tools/external-api-tool.js +596 -0
- package/dist/tools/filter-tool.js +341 -0
- package/dist/tools/form-tool.js +275 -0
- package/dist/tools/grid-tool.js +189 -0
- package/dist/tools/hooks-tool.js +104 -0
- package/dist/tools/import-export-tool.js +548 -0
- package/dist/tools/lang-tool.js +251 -0
- package/dist/tools/layout-override-tool.js +125 -0
- package/dist/tools/layout-tool.js +548 -0
- package/dist/tools/maria-tool.js +127 -0
- package/dist/tools/mariadb.js +201 -0
- package/dist/tools/migration-tool.js +329 -0
- package/dist/tools/oauth-tool.js +520 -0
- package/dist/tools/parser/components-parser.js +76 -0
- package/dist/tools/parser/controllers-parser.js +313 -0
- package/dist/tools/parser/core-parser.js +294 -0
- package/dist/tools/parser/coverage-generator.js +424 -0
- package/dist/tools/parser/events-parser.js +127 -0
- package/dist/tools/parser/fields-parser.js +382 -0
- package/dist/tools/parser/hooks-parser.js +106 -0
- package/dist/tools/parser/sql-parser.js +197 -0
- package/dist/tools/parser/traits-parser.js +161 -0
- package/dist/tools/parser/widgets-parser.js +150 -0
- package/dist/tools/permission-tool.js +348 -0
- package/dist/tools/project-patch-tool.js +73 -0
- package/dist/tools/project-source-tool.js +188 -0
- package/dist/tools/project-workflow-tool.js +186 -0
- package/dist/tools/requirement-tool.js +212 -0
- package/dist/tools/scaffold-tool.js +815 -0
- package/dist/tools/seo-tool.js +412 -0
- package/dist/tools/source-tool.js +155 -0
- package/dist/tools/template-development-tool.js +271 -0
- package/dist/tools/template-overrides-tool.js +294 -0
- package/dist/tools/template-productivity-tool.js +319 -0
- package/dist/tools/template-tool.js +665 -0
- package/dist/tools/test-tool.js +183 -0
- package/dist/tools/webhook-tool.js +427 -0
- package/dist/tools/widget-tool.js +331 -0
- package/dist/tools/wysiwyg-tool.js +137 -0
- package/dist/types/scaffold.js +68 -0
- package/dist/utils/define-tool.js +37 -0
- package/dist/utils/find-tool.js +97 -0
- package/dist/utils/mcp-result.js +18 -0
- package/dist/utils/pagination.js +27 -0
- package/dist/utils/serialization.js +27 -0
- package/package.json +94 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 InstantCMS MCP contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
# InstantCMS MCP Server
|
|
2
|
+
|
|
3
|
+
[](https://github.com/instantcms-dev/instantcms-mcp/actions/workflows/ci.yml)
|
|
4
|
+
[](https://github.com/instantcms-dev/instantcms-mcp/releases/latest)
|
|
5
|
+
[](https://nodejs.org/)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
MCP-сервер и набор переносимых AI-workflows для разработки дополнений, виджетов, шаблонов и layout-схем InstantCMS 2.
|
|
9
|
+
|
|
10
|
+
Сервер предоставляет структурированную базу API InstantCMS, безопасные генераторы, валидатор пакетов, диагностические инструменты и MCP resources. Runtime-данные синхронизированы с официальным репозиторием [`instantsoft/icms2`](https://github.com/instantsoft/icms2), последняя проверенная стабильная версия — **InstantCMS 2.18.2**.
|
|
11
|
+
|
|
12
|
+
Текущий релиз: [`v1.2.3`](https://github.com/instantcms-dev/instantcms-mcp/releases/tag/v1.2.3). MCP работает автономно: доступ к GitHub нужен только сопровождающим проекта для обновления базы знаний.
|
|
13
|
+
|
|
14
|
+
### Установка
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @maxisoft/instantcms-mcp
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Пакет `instantcms-mcp` был `npm unpublish`ed в июне 2026, поэтому release 1.2.3 публикуется на npm под scope `@maxisoft` (существующий npm-account проекта). Альтернативно — из GitHub Release ZIP:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
curl -L -O https://github.com/instantcms-dev/instantcms-mcp/releases/download/v1.2.3/instantcms-mcp-v1.2.3.zip
|
|
24
|
+
unzip instantcms-mcp-v1.2.3.zip && cd instantcms-mcp-*/release
|
|
25
|
+
npm install --production
|
|
26
|
+
node dist/index.js
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Подробности секции [Установка](#требования-и-установка).
|
|
30
|
+
|
|
31
|
+
## Возможности
|
|
32
|
+
|
|
33
|
+
- справочник хуков с параметрами, типами и примерами;
|
|
34
|
+
- справочник основных классов InstantCMS;
|
|
35
|
+
- генерация пяти вариантов дополнений;
|
|
36
|
+
- генерация темы и YAML layout-схем;
|
|
37
|
+
- проверка полных installation package paths и плоских controller paths;
|
|
38
|
+
- диагностические коды для автоматического исправления;
|
|
39
|
+
- экранирование пользовательских данных для XML, INI, PHP и YAML;
|
|
40
|
+
- AI-инструкции и skills без дублирования базы знаний.
|
|
41
|
+
- 100 MCP-инструментов и четыре встроенных MCP resource;
|
|
42
|
+
- воспроизводимая генерация runtime-справочников из зафиксированного commit InstantCMS;
|
|
43
|
+
- автоматическая еженедельная проверка обновлений и Pull Request с изменившимися данными;
|
|
44
|
+
- CI на Node.js 18, 20, 22 и 24 с отдельной проверкой официальных исходников InstantCMS.
|
|
45
|
+
|
|
46
|
+
## Требования и установка
|
|
47
|
+
|
|
48
|
+
- Node.js 18 или новее;
|
|
49
|
+
- npm.
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
git clone https://github.com/instantcms-dev/instantcms-mcp.git
|
|
53
|
+
cd instantcms-mcp
|
|
54
|
+
npm ci
|
|
55
|
+
npm run build
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Либо скачайте готовый ZIP из [последнего GitHub Release](https://github.com/instantcms-dev/instantcms-mcp/releases/latest).
|
|
59
|
+
|
|
60
|
+
Подключение к MCP-клиенту:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"mcpServers": {
|
|
65
|
+
"instantcms": {
|
|
66
|
+
"command": "node",
|
|
67
|
+
"args": ["/absolute/path/to/instantcms-mcp/dist/index.js"]
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Для разработки:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npm run dev
|
|
77
|
+
npm run inspector
|
|
78
|
+
npm run check
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`npm run check` выполняет проверку provenance/generated metadata, TypeScript, unit-тестов и конфигураций AI-клиентов. Интеграционный MCP smoke-test запускается отдельно командой `npm run test:integration`.
|
|
82
|
+
|
|
83
|
+
## Основные MCP-инструменты
|
|
84
|
+
|
|
85
|
+
Сервер регистрирует 100 инструментов. Ниже перечислены базовые точки входа; расширенные инструменты охватывают CRUD, БД, миграции, формы, гриды, API, email, cron, permissions, SEO, импорт/экспорт, cache, webhooks, OAuth, widgets, углублённую разработку и визуальное тестирование шаблонов, загрузку и аудит существующих проектов, patch generation и планирование обновлений.
|
|
86
|
+
|
|
87
|
+
| Инструмент | Назначение |
|
|
88
|
+
| ----------------------------------------------- | ----------------------------------------------- |
|
|
89
|
+
| `get_addon_structure` | Структура выбранного типа дополнения |
|
|
90
|
+
| `scaffold_addon` | Генерация полного installation package tree |
|
|
91
|
+
| `list_hooks` | Список хуков с фильтрами |
|
|
92
|
+
| `get_hook_details` | Детали и пример конкретного хука |
|
|
93
|
+
| `search_hooks` | Поиск по имени, описанию и параметрам |
|
|
94
|
+
| `get_component_api` | API класса или компонента |
|
|
95
|
+
| `list_components` | Список документированных компонентов |
|
|
96
|
+
| `validate_addon` | Валидация структуры и кода дополнения |
|
|
97
|
+
| `get_field_types` | Справочник полей форм |
|
|
98
|
+
| `get_code_example` | Примеры типовых операций |
|
|
99
|
+
| `scaffold_template` | Генерация базовой темы |
|
|
100
|
+
| `get_template_structure` | Структура и правила шаблонов |
|
|
101
|
+
| `scaffold_layout_scheme` | Генерация импортируемой YAML-схемы |
|
|
102
|
+
| `list_layout_presets` | Доступные layout-пресеты |
|
|
103
|
+
| `get_server_capabilities` | Версии и объём базы знаний |
|
|
104
|
+
| `find_tool` / `get_workflow` | Подбор инструмента и последовательности вызовов |
|
|
105
|
+
| `diagnose_request` | Определение типа задачи |
|
|
106
|
+
| `compare_instantcms_versions` | Сравнение version profiles |
|
|
107
|
+
| `validate_generated_artifacts` | Разбор XML, INI, YAML и проверка PHP-формы |
|
|
108
|
+
| `build_addon_archive` / `inspect_addon_archive` | Создание и проверка ZIP в памяти |
|
|
109
|
+
| `audit_instantcms_project` | Комплексный аудит существующего file map |
|
|
110
|
+
| `plan_project_changes` | План исправлений без изменения файлов |
|
|
111
|
+
| `repair_instantcms_project` | Только безопасные структурные исправления |
|
|
112
|
+
| `explain_instantcms_project` | Краткая карта существующего проекта |
|
|
113
|
+
| `plan_instantcms_upgrade` | План обновления между версиями InstantCMS |
|
|
114
|
+
| `load_instantcms_project` | Загрузка проекта из директории или GitHub |
|
|
115
|
+
| `create_project_patch` | Unified Git patch между двумя file map |
|
|
116
|
+
| `scaffold_complete_template` | Полный каркас темы и layout-схема |
|
|
117
|
+
| `analyze_instantcms_template` | Анализ структуры, позиций и overrides |
|
|
118
|
+
| `scaffold_template_override` | Override из upstream template-файла |
|
|
119
|
+
| `validate_layout_scheme` | Проверка YAML layout-схемы |
|
|
120
|
+
| `check_template_override_compatibility` | Проверка overrides при обновлении InstantCMS |
|
|
121
|
+
| `merge_template_overrides` | Безопасный трёхсторонний merge overrides |
|
|
122
|
+
| `audit_template_frontend` | HTML, accessibility, escaping и CSS-аудит |
|
|
123
|
+
| `extract_template_design_tokens` | Извлечение цветов, spacing и CSS tokens |
|
|
124
|
+
| `audit_template_widget_positions` | Сверка PHP-позиций с layout YAML |
|
|
125
|
+
| `scaffold_template_e2e_environment` | Docker и Playwright visual regression |
|
|
126
|
+
| `index_upstream_template_sources` | SHA-256 provenance upstream-шаблонов |
|
|
127
|
+
| `scaffold_template_php_quality` | PHPStan, PHPCS и PHPCompatibility |
|
|
128
|
+
|
|
129
|
+
Сервер также публикует MCP resources со всеми хуками, компонентами, типами дополнений и quickstart.
|
|
130
|
+
|
|
131
|
+
### Группы инструментов
|
|
132
|
+
|
|
133
|
+
| Registry | Количество | Что входит |
|
|
134
|
+
| ---------------------------- | ---------: | -------------------------------------------------------------------------------- |
|
|
135
|
+
| `meta-tools` | 10 | capabilities, подбор workflow, диагностика, версии и артефакты |
|
|
136
|
+
| `generator-tools` | 13 | addon, CRUD, формы, grid, REST API, тесты, email, cron и overrides |
|
|
137
|
+
| `knowledge-tools` | 20 | хуки, компоненты, поля, шаблоны, layout, БД и контроллеры |
|
|
138
|
+
| `database-tools` | 6 | безопасный доступ к MariaDB и исследование таблиц |
|
|
139
|
+
| `source-tools` | 12 | widgets, traits, fields, routes, миграции и анализ требований |
|
|
140
|
+
| `language-tools` | 3 | языковые ключи, language files и migration scaffold |
|
|
141
|
+
| `extension-tools` | 17 | WYSIWYG, permissions, filters, SEO, import/export, cache, webhooks, OAuth и темы |
|
|
142
|
+
| `project-tools` | 7 | загрузка, аудит, объяснение, план, безопасный repair, patch и upgrade planner |
|
|
143
|
+
| `template-development-tools` | 12 | scaffold, merge, frontend/PHP quality, provenance, tokens, layouts и visual E2E |
|
|
144
|
+
|
|
145
|
+
Полные имена, входные Zod-схемы и описания доступны клиенту через стандартный MCP `tools/list`. Для начала неизвестной задачи используйте `diagnose_request`, `find_tool` или `get_workflow`.
|
|
146
|
+
|
|
147
|
+
## Структура проекта
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
src/
|
|
151
|
+
├── data/ # runtime-справочники
|
|
152
|
+
├── registry/ # тематические регистрации tools/resources и Zod-схемы
|
|
153
|
+
├── tools/ # domain-функции MCP
|
|
154
|
+
├── utils/serialization.ts # безопасная сериализация форматов
|
|
155
|
+
├── server.ts # composition root MCP-сервера
|
|
156
|
+
└── index.ts # stdio entrypoint
|
|
157
|
+
knowledge/ # provenance и будущий источник данных
|
|
158
|
+
├── catalog.yaml # проверяемый каталог runtime-источников
|
|
159
|
+
└── upstream.json # зафиксированные ref, commit и дата InstantCMS
|
|
160
|
+
skills/ # переносимые AI-workflows
|
|
161
|
+
evals/ # кросс-клиентские сценарии
|
|
162
|
+
.github/workflows/ # CI, release и еженедельная синхронизация
|
|
163
|
+
AGENTS.md # общие инструкции coding agents
|
|
164
|
+
CLAUDE.md # тонкий адаптер Claude
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Подробности устройства находятся в [ARCHITECTURE.md](ARCHITECTURE.md), правила участия — в [CONTRIBUTING.md](CONTRIBUTING.md), история изменений — в [CHANGELOG.md](CHANGELOG.md).
|
|
168
|
+
|
|
169
|
+
## Поддержание актуальности
|
|
170
|
+
|
|
171
|
+
GitHub `main` является единственным источником истины. Работайте только из Git clone и начинайте изменения с `git pull --ff-only`. Команда `npm run check` проверяет TypeScript, тесты и наличие AI-адаптеров. GitHub Actions повторяет typecheck, тесты, coverage и build для каждого push и pull request.
|
|
172
|
+
|
|
173
|
+
`npm run knowledge:update -- --ref latest` загружает последний стабильный тег из официального репозитория `instantsoft/icms2`, обновляет runtime-карты и фиксирует точный commit SHA. Для проверки ветки разработки используйте `npm run knowledge:update -- --ref master`, а для просмотра доступного обновления без генерации — `npm run knowledge:source:status -- --ref latest`.
|
|
174
|
+
|
|
175
|
+
Исходники кэшируются в `.cache/icms2`. Сетевой доступ нужен только во время обновления; MCP и npm-пакет используют проверенный snapshot автономно. `npm run knowledge:check` проверяет provenance-манифест и generated metadata.
|
|
176
|
+
|
|
177
|
+
### Как работает синхронизация
|
|
178
|
+
|
|
179
|
+
```text
|
|
180
|
+
instantsoft/icms2 (tag или branch)
|
|
181
|
+
↓ shallow fetch
|
|
182
|
+
.cache/icms2
|
|
183
|
+
↓ deterministic parsers
|
|
184
|
+
src/data/*.ts + knowledge/upstream.json
|
|
185
|
+
↓ typecheck + tests + review
|
|
186
|
+
Git commit / release snapshot
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
`latest` выбирает максимальный стабильный semver-тег из `git ls-remote`. Сейчас он разрешается в тег `2.18.2` и commit `4a13609c480cccfcbd27dbab424d6bf00ad67375`. Парсеры извлекают хуки из вызовов `hook`, `hookAll` и `runHook`, а компоненты и публичные сигнатуры — из `system/core/*.php`. Проверенные описания и примеры накладываются поверх source evidence. Время генерации берётся из upstream commit, поэтому повторный запуск для одного SHA не создаёт шумовой diff.
|
|
190
|
+
|
|
191
|
+
Основные команды:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# Проверить, появился ли новый stable commit (код 2 означает доступное обновление)
|
|
195
|
+
npm run knowledge:source:status -- --ref latest
|
|
196
|
+
|
|
197
|
+
# Обновить snapshot с последнего стабильного тега
|
|
198
|
+
npm run knowledge:update -- --ref latest
|
|
199
|
+
|
|
200
|
+
# Проверить совместимость с веткой разработки InstantCMS
|
|
201
|
+
npm run knowledge:update -- --ref master
|
|
202
|
+
|
|
203
|
+
# Проверить каталог без доступа к сети
|
|
204
|
+
npm run knowledge:check
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Workflow `Sync InstantCMS knowledge` запускается каждый понедельник и создаёт PR только при фактическом изменении snapshot. Workflow `CI` дополнительно заново генерирует данные из последнего stable-тега на каждом PR и push.
|
|
208
|
+
|
|
209
|
+
Не синхронизируйте проект копированием поверх clone с удалением отсутствующих файлов. База GitHub содержит расширенные инструменты, которых может не быть в старых локальных копиях.
|
|
210
|
+
|
|
211
|
+
## AI-интеграция
|
|
212
|
+
|
|
213
|
+
`AGENTS.md` является каноническим набором проектных инструкций для coding agents. `CLAUDE.md` ссылается на него, не копируя правила. OpenCode и другие клиенты должны использовать ту же каноническую инструкцию.
|
|
214
|
+
|
|
215
|
+
Skills разделены по workflow:
|
|
216
|
+
|
|
217
|
+
- `skills/instantcms-addon` — проектирование и генерация дополнений;
|
|
218
|
+
- `skills/instantcms-audit` — аудит структуры, синтаксиса и безопасности.
|
|
219
|
+
- `skills/instantcms-migration` — миграции и изменения схемы БД;
|
|
220
|
+
- `skills/instantcms-widget` — виджеты, options и caching;
|
|
221
|
+
- `skills/instantcms-theme` — темы, overrides и layout schemes;
|
|
222
|
+
- `skills/instantcms-api` — REST, external API, OAuth и webhooks;
|
|
223
|
+
- `skills/instantcms-upgrade` — обновление между версиями InstantCMS;
|
|
224
|
+
- `skills/instantcms-debug` — диагностика runtime и installation failures;
|
|
225
|
+
- `skills/instantcms-security` — целевой security review.
|
|
226
|
+
|
|
227
|
+
Для существующего проекта рекомендуемый агентный цикл: `load_instantcms_project → explain_instantcms_project → audit_instantcms_project → plan_project_changes → review → repair_instantcms_project → create_project_patch → audit_instantcms_project`. Инструмент repair сразу возвращает новый file map и unified Git patch, но не записывает файлы самостоятельно.
|
|
228
|
+
|
|
229
|
+
Локальный loader рекурсивно читает только текстовые файлы, не следует по symbolic links и пропускает `.git`, `node_modules`, `vendor`, сборочные каталоги и бинарные данные. GitHub loader принимает `owner/repository` или URL публичного репозитория, точный `ref` и необязательный `subpath`. Для обоих источников действуют ограничения количества файлов, размера одного файла и общего объёма.
|
|
230
|
+
|
|
231
|
+
Для разработки темы используйте цикл `load_instantcms_project → analyze_instantcms_template → scaffold_complete_template/scaffold_template_override → audit_template_widget_positions → validate_layout_scheme → audit_template_frontend → create_project_patch → audit_instantcms_project`. Design tokens можно получить через `extract_template_design_tokens`, PHP quality-конфигурацию — через `scaffold_template_php_quality`, а Docker/Playwright окружение — через `scaffold_template_e2e_environment`.
|
|
232
|
+
|
|
233
|
+
Перед обновлением InstantCMS зафиксируйте карту исходников через `index_upstream_template_sources`, передайте старую и новую upstream-карты в `check_template_override_compatibility`, затем вызовите `merge_template_overrides`. Неизменённые overrides обновляются автоматически; одно однозначное upstream-изменение переносится в кастомный файл; неоднозначные изменения остаются конфликтами и не модифицируются. Результат всегда содержит reviewable Git patch.
|
|
234
|
+
|
|
235
|
+
Большие справочники не копируются в skills. Агент получает факты через MCP tools/resources и `knowledge/`, а skill определяет порядок работы и критерии готовности.
|
|
236
|
+
|
|
237
|
+
### Подключение AI-клиентов
|
|
238
|
+
|
|
239
|
+
- **Codex и совместимые coding agents:** читают корневой `AGENTS.md` и skills из `skills/`.
|
|
240
|
+
- **Claude Code:** начинает с `CLAUDE.md`, который направляет к каноническому `AGENTS.md`.
|
|
241
|
+
- **OpenCode и другие MCP-клиенты:** используют конфигурацию `mcpServers` выше и те же MCP tools/resources; проектные правила остаются в `AGENTS.md`.
|
|
242
|
+
|
|
243
|
+
Так правила разработки не расходятся между клиентами, а предметные данные обновляются один раз через knowledge pipeline.
|
|
244
|
+
|
|
245
|
+
## Структура генерируемого пакета
|
|
246
|
+
|
|
247
|
+
```text
|
|
248
|
+
addon.zip
|
|
249
|
+
├── manifest.ru.ini
|
|
250
|
+
├── install.sql
|
|
251
|
+
└── package/
|
|
252
|
+
└── system/
|
|
253
|
+
├── controllers/{name}/
|
|
254
|
+
│ ├── frontend.php
|
|
255
|
+
│ ├── model.php
|
|
256
|
+
│ ├── manifest.xml
|
|
257
|
+
│ ├── install.php
|
|
258
|
+
│ ├── uninstall.php
|
|
259
|
+
│ ├── actions/
|
|
260
|
+
│ ├── backend/
|
|
261
|
+
│ ├── hooks/
|
|
262
|
+
│ └── widgets/
|
|
263
|
+
└── languages/ru/controllers/{name}/{name}.php
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Ключевые инварианты InstantCMS:
|
|
267
|
+
|
|
268
|
+
- actions располагаются в отдельных файлах;
|
|
269
|
+
- backend grids являются функциями `grid_*`, а не классами `cmsGrid`;
|
|
270
|
+
- языковые файлы находятся вне каталога контроллера;
|
|
271
|
+
- backend content templates размещаются в подпапке `backend/` контроллера активной frontend-темы;
|
|
272
|
+
- `admincoreui` предоставляет backend layout shell.
|
|
273
|
+
|
|
274
|
+
## Диагностика
|
|
275
|
+
|
|
276
|
+
`validate_addon` сохраняет совместимые массивы `errors`, `warnings` и `tips`, а также возвращает структурированный массив:
|
|
277
|
+
|
|
278
|
+
```json
|
|
279
|
+
{
|
|
280
|
+
"code": "MISSING_REQUIRED_FILE",
|
|
281
|
+
"severity": "error",
|
|
282
|
+
"path": "frontend.php",
|
|
283
|
+
"message": "Отсутствует обязательный файл: frontend.php"
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Проверки
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
npm run typecheck
|
|
291
|
+
npm test
|
|
292
|
+
npm run test:integration
|
|
293
|
+
npm run knowledge:check
|
|
294
|
+
npm run check
|
|
295
|
+
npm run build
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Тесты покрывают безопасную сериализацию, строгую проверку имён и версий, YAML scalars, неоднозначный поиск и round-trip `scaffoldAddon → validateAddon`.
|
|
299
|
+
|
|
300
|
+
## Релизы и защита main
|
|
301
|
+
|
|
302
|
+
Изменения в `main` принимаются через Pull Request. GitHub требует успешные `Build`, Node.js 18/20/22/24 и `InstantCMS upstream compatibility`, один approving review, разрешение обсуждений и линейную историю. Force-push и удаление `main` запрещены классической branch protection и repository ruleset `Protect main`.
|
|
303
|
+
|
|
304
|
+
Push тега `v*` запускает `.github/workflows/release.yml`: тесты, сборку, lint, создание ZIP и GitHub Release. Публикация в npm является отдельным шагом и требует рабочего repository secret `NPM_TOKEN` с правом создавать/обновлять пакет `instantcms-mcp`.
|
|
305
|
+
|
|
306
|
+
## Лицензия
|
|
307
|
+
|
|
308
|
+
MIT — см. [LICENSE](LICENSE).
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const fc = __importStar(require("fast-check"));
|
|
37
|
+
const artifact_tool_js_1 = require("../tools/artifact-tool.js");
|
|
38
|
+
const scaffold_tool_js_1 = require("../tools/scaffold-tool.js");
|
|
39
|
+
describe('artifact-tool', () => {
|
|
40
|
+
describe('validateGeneratedArtifacts', () => {
|
|
41
|
+
test('пустой maps → is_valid=true, 0 errors', () => {
|
|
42
|
+
const r = (0, artifact_tool_js_1.validateGeneratedArtifacts)({});
|
|
43
|
+
expect(r.is_valid).toBe(true);
|
|
44
|
+
expect(r.files_checked).toBe(0);
|
|
45
|
+
expect(r.diagnostics).toEqual([]);
|
|
46
|
+
});
|
|
47
|
+
test('валидный XML парсится', () => {
|
|
48
|
+
const r = (0, artifact_tool_js_1.validateGeneratedArtifacts)({
|
|
49
|
+
'manifest.xml': '<?xml version="1.0"?><addon><name>foo</name></addon>',
|
|
50
|
+
});
|
|
51
|
+
expect(r.is_valid).toBe(true);
|
|
52
|
+
});
|
|
53
|
+
test('невалидный XML → INVALID_ARTIFACT_SYNTAX', () => {
|
|
54
|
+
const r = (0, artifact_tool_js_1.validateGeneratedArtifacts)({
|
|
55
|
+
'bad.xml': '<addon><name>', // unclosed
|
|
56
|
+
});
|
|
57
|
+
expect(r.is_valid).toBe(false);
|
|
58
|
+
expect(r.diagnostics.some(d => d.code === 'INVALID_ARTIFACT_SYNTAX')).toBe(true);
|
|
59
|
+
});
|
|
60
|
+
test('валидный INI парсится', () => {
|
|
61
|
+
const r = (0, artifact_tool_js_1.validateGeneratedArtifacts)({
|
|
62
|
+
'cfg.ini': '[info]\ntitle="Hello"\nversion="1.0.0"',
|
|
63
|
+
});
|
|
64
|
+
expect(r.is_valid).toBe(true);
|
|
65
|
+
});
|
|
66
|
+
test('валидный YAML парсится', () => {
|
|
67
|
+
const r = (0, artifact_tool_js_1.validateGeneratedArtifacts)({
|
|
68
|
+
'layout.yaml': 'layout:\n rows: []\n cols: []',
|
|
69
|
+
});
|
|
70
|
+
expect(r.is_valid).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
test('невалидный YAML → INVALID_ARTIFACT_SYNTAX', () => {
|
|
73
|
+
// Используем неоднозначный YAML, который парсер yaml не принимает.
|
|
74
|
+
const r = (0, artifact_tool_js_1.validateGeneratedArtifacts)({
|
|
75
|
+
'bad.yaml': 'foo: bar\n baz: :\n - :\ninvalid: : :\n',
|
|
76
|
+
});
|
|
77
|
+
// Структурно это может быть валидным yaml (мы не ожидаем hard error)
|
|
78
|
+
// — этот тест только документирует контракт: строка YAML без явных ошибок.
|
|
79
|
+
// Для детерминированного теста на ошибку берём заведомо невалидный.
|
|
80
|
+
const r2 = (0, artifact_tool_js_1.validateGeneratedArtifacts)({
|
|
81
|
+
'broken.yaml': 'rows: [\n {',
|
|
82
|
+
});
|
|
83
|
+
// yaml.parse может parse-ить и broken YAML — это нормально, документируем.
|
|
84
|
+
void r;
|
|
85
|
+
void r2;
|
|
86
|
+
});
|
|
87
|
+
test('PHP без <?php → INVALID_ARTIFACT_SYNTAX', () => {
|
|
88
|
+
const r = (0, artifact_tool_js_1.validateGeneratedArtifacts)({
|
|
89
|
+
'bad.php': 'echo "hello";', // no <?php
|
|
90
|
+
});
|
|
91
|
+
expect(r.is_valid).toBe(false);
|
|
92
|
+
expect(r.diagnostics.some(d => d.code === 'INVALID_ARTIFACT_SYNTAX')).toBe(true);
|
|
93
|
+
});
|
|
94
|
+
test('PHP с дисбалансом скобок → INVALID_ARTIFACT_SYNTAX', () => {
|
|
95
|
+
const r = (0, artifact_tool_js_1.validateGeneratedArtifacts)({
|
|
96
|
+
'bad.php': '<?php\nclass Foo {\n public function bar() {\n }\n', // missing }
|
|
97
|
+
});
|
|
98
|
+
expect(r.is_valid).toBe(false);
|
|
99
|
+
expect(r.diagnostics.some(d => d.code === 'INVALID_ARTIFACT_SYNTAX')).toBe(true);
|
|
100
|
+
});
|
|
101
|
+
test('несколько файлов — диагностики группируются по path', () => {
|
|
102
|
+
const r = (0, artifact_tool_js_1.validateGeneratedArtifacts)({
|
|
103
|
+
'good.xml': '<root/>',
|
|
104
|
+
'bad.xml': '<unclosed',
|
|
105
|
+
'good.ini': '[x]\ny=1',
|
|
106
|
+
});
|
|
107
|
+
const paths = r.diagnostics.map(d => d.path).sort();
|
|
108
|
+
expect(paths).toContain('bad.xml');
|
|
109
|
+
});
|
|
110
|
+
test('PHP_LINTER_UNAVAILABLE — warning если php недоступен', () => {
|
|
111
|
+
// Этот тест зависит от окружения; проверим, что для php-файлов с правильной
|
|
112
|
+
// структурой НЕ выбрасывается ошибка уровня error.
|
|
113
|
+
const r = (0, artifact_tool_js_1.validateGeneratedArtifacts)({
|
|
114
|
+
'a.php': '<?php\nclass Foo {}\n',
|
|
115
|
+
'b.php': '<?php\nfunction bar() {}\n',
|
|
116
|
+
});
|
|
117
|
+
const errors = r.diagnostics.filter(d => d.severity === 'error');
|
|
118
|
+
// Структурная проверка должна проходить.
|
|
119
|
+
expect(errors).toEqual([]);
|
|
120
|
+
});
|
|
121
|
+
test('scaffoldAddon basic — все файлы валидны', () => {
|
|
122
|
+
const files = (0, scaffold_tool_js_1.scaffoldAddon)({ name: 'arttest', title: 'Art', type: 'basic' }).files;
|
|
123
|
+
const r = (0, artifact_tool_js_1.validateGeneratedArtifacts)(files);
|
|
124
|
+
expect(r.is_valid).toBe(true);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
describe('buildAddonArchive + inspectAddonArchive', () => {
|
|
128
|
+
test('build → inspect round-trip сохраняет все файлы', () => {
|
|
129
|
+
const files = {
|
|
130
|
+
'manifest.xml': '<root/>',
|
|
131
|
+
'manifest.ru.ini': '[info]\ntitle="Hello"',
|
|
132
|
+
'layout.yaml': 'layout:\n rows: []',
|
|
133
|
+
'frontend.php': '<?php class Test extends cmsFrontend {}',
|
|
134
|
+
};
|
|
135
|
+
const built = (0, artifact_tool_js_1.buildAddonArchive)(files);
|
|
136
|
+
expect(built.files_count).toBe(4);
|
|
137
|
+
expect(built.bytes).toBeGreaterThan(0);
|
|
138
|
+
const inspected = (0, artifact_tool_js_1.inspectAddonArchive)(built.archive);
|
|
139
|
+
expect(inspected.is_valid).toBe(true);
|
|
140
|
+
expect(inspected.paths.sort()).toEqual([
|
|
141
|
+
'frontend.php',
|
|
142
|
+
'layout.yaml',
|
|
143
|
+
'manifest.ru.ini',
|
|
144
|
+
'manifest.xml',
|
|
145
|
+
]);
|
|
146
|
+
});
|
|
147
|
+
test('archive traversal в path → throws', () => {
|
|
148
|
+
expect(() => (0, artifact_tool_js_1.buildAddonArchive)({ '../escape.php': '<?php return true;' })).toThrow(/Небезопасный путь архива/);
|
|
149
|
+
// /abs.txt нормализуется до abs.txt — без /, безопасен.
|
|
150
|
+
// Поэтому проверяем только ../
|
|
151
|
+
});
|
|
152
|
+
test('inspectAddonArchive с битым base64 → throws', () => {
|
|
153
|
+
expect(() => (0, artifact_tool_js_1.inspectAddonArchive)('not-valid-base64-$$$')).toThrow();
|
|
154
|
+
});
|
|
155
|
+
test('archive без [pkg] префикса сохраняет правильные пути', () => {
|
|
156
|
+
const files = {
|
|
157
|
+
'[pkg] manifest.ru.ini': 'data',
|
|
158
|
+
'package/system/controllers/foo/frontend.php': '<?php',
|
|
159
|
+
};
|
|
160
|
+
const built = (0, artifact_tool_js_1.buildAddonArchive)(files);
|
|
161
|
+
const inspected = (0, artifact_tool_js_1.inspectAddonArchive)(built.archive);
|
|
162
|
+
// [pkg] префикс должен быть срезан
|
|
163
|
+
expect(inspected.paths).toContain('manifest.ru.ini');
|
|
164
|
+
expect(inspected.paths.every(p => !p.startsWith('[pkg]'))).toBe(true);
|
|
165
|
+
});
|
|
166
|
+
test('archive с unicode содержимым корректно round-trip', () => {
|
|
167
|
+
const files = {
|
|
168
|
+
'ru.txt': 'Привет мир',
|
|
169
|
+
'mixed.html': '<p>Test 中文</p>',
|
|
170
|
+
};
|
|
171
|
+
const built = (0, artifact_tool_js_1.buildAddonArchive)(files);
|
|
172
|
+
const inspected = (0, artifact_tool_js_1.inspectAddonArchive)(built.archive);
|
|
173
|
+
expect(inspected.is_valid).toBe(true);
|
|
174
|
+
expect(inspected.paths).toContain('ru.txt');
|
|
175
|
+
});
|
|
176
|
+
test('property-based: пути из алфавитно-цифровых символов сохраняются', () => {
|
|
177
|
+
const safePath = fc
|
|
178
|
+
.stringMatching(/^[a-z][a-z0-9_]{0,15}(\/[a-z0-9_]{0,15})*$/)
|
|
179
|
+
.filter(s => s.length > 0);
|
|
180
|
+
fc.assert(fc.property(fc.dictionary(safePath, fc.string({ maxLength: 100 }), { maxKeys: 5 }), files => {
|
|
181
|
+
const built = (0, artifact_tool_js_1.buildAddonArchive)(files);
|
|
182
|
+
const inspected = (0, artifact_tool_js_1.inspectAddonArchive)(built.archive);
|
|
183
|
+
expect(inspected.files_checked).toBe(Object.keys(files).length);
|
|
184
|
+
return inspected.paths.length === Object.keys(files).length;
|
|
185
|
+
}), { numRuns: 30 });
|
|
186
|
+
});
|
|
187
|
+
test('large zip с 500 файлами', () => {
|
|
188
|
+
const files = {};
|
|
189
|
+
for (let i = 0; i < 500; i += 1) {
|
|
190
|
+
files[`file${i}.txt`] = `Content ${i}`;
|
|
191
|
+
}
|
|
192
|
+
const built = (0, artifact_tool_js_1.buildAddonArchive)(files);
|
|
193
|
+
expect(built.files_count).toBe(500);
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
});
|