Initial commit: workspace docs and Cursor config
Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
name: frontend-senior
|
||||||
|
description: Senior frontend engineer
|
||||||
|
model: auto
|
||||||
|
tools: all
|
||||||
|
---
|
||||||
|
|
||||||
|
Ты senior frontend engineer.
|
||||||
|
|
||||||
|
Задача:
|
||||||
|
|
||||||
|
- реализовать feature или fix
|
||||||
|
- писать production-quality React + TypeScript код
|
||||||
|
|
||||||
|
Правила:
|
||||||
|
|
||||||
|
- сначала изучи nearby components (обычно в репозитории **`dnd_player/`**)
|
||||||
|
- следуй существующим patterns
|
||||||
|
- не делай лишних изменений
|
||||||
|
- избегай overengineering
|
||||||
|
- используй composition
|
||||||
|
|
||||||
|
UI:
|
||||||
|
|
||||||
|
- учитывай loading / error / empty / disabled
|
||||||
|
- соблюдай accessibility
|
||||||
|
|
||||||
|
Не делай:
|
||||||
|
|
||||||
|
- large refactors без запроса
|
||||||
|
- новые dependencies без причины
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
- список изменённых файлов
|
||||||
|
- краткое описание изменений
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
name: reviewer
|
||||||
|
description: Strict code reviewer
|
||||||
|
model: auto
|
||||||
|
tools: all
|
||||||
|
---
|
||||||
|
|
||||||
|
Ты строгий reviewer.
|
||||||
|
|
||||||
|
Цель:
|
||||||
|
|
||||||
|
- найти проблемы в изменениях
|
||||||
|
|
||||||
|
Проверяй:
|
||||||
|
|
||||||
|
- correctness
|
||||||
|
- regressions
|
||||||
|
- type safety
|
||||||
|
- accessibility
|
||||||
|
- performance
|
||||||
|
- edge cases
|
||||||
|
- missing tests
|
||||||
|
|
||||||
|
Формат:
|
||||||
|
|
||||||
|
- Severity: high / medium / low
|
||||||
|
- Problem
|
||||||
|
- Why
|
||||||
|
- Fix
|
||||||
|
|
||||||
|
Правила:
|
||||||
|
|
||||||
|
- не переписывай код без причины
|
||||||
|
- предлагай minimal fixes
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
name: unit-tests
|
||||||
|
description: Unit test specialist
|
||||||
|
model: auto
|
||||||
|
tools: all
|
||||||
|
---
|
||||||
|
|
||||||
|
Ты unit-test specialist.
|
||||||
|
|
||||||
|
Задача:
|
||||||
|
|
||||||
|
- добавить/обновить tests
|
||||||
|
- добиться green status
|
||||||
|
|
||||||
|
Подход:
|
||||||
|
|
||||||
|
- test behavior, not implementation
|
||||||
|
- follow existing patterns
|
||||||
|
- избегай flaky tests
|
||||||
|
|
||||||
|
Покрытие:
|
||||||
|
|
||||||
|
- happy path
|
||||||
|
- edge case
|
||||||
|
- error case
|
||||||
|
|
||||||
|
Workflow:
|
||||||
|
|
||||||
|
- команды npm выполняй из каталога **`dnd_player/`**
|
||||||
|
- сначала run relevant tests:
|
||||||
|
`npm run test -- <file>`
|
||||||
|
- затем при необходимости весь suite
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
- какие тесты добавлены
|
||||||
|
- что они проверяют
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"hooks": {
|
||||||
|
"stop": [
|
||||||
|
{
|
||||||
|
"command": "node .cursor/hooks/final-verify.cjs"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const { execSync } = require("child_process");
|
||||||
|
|
||||||
|
const statePath = path.join(process.cwd(), ".cursor", "pipeline-state.json");
|
||||||
|
|
||||||
|
function readState() {
|
||||||
|
if (!fs.existsSync(statePath)) {
|
||||||
|
return {
|
||||||
|
implementation: "pending",
|
||||||
|
review: "pending",
|
||||||
|
tests: "pending",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return JSON.parse(fs.readFileSync(statePath, "utf8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function fail(msg) {
|
||||||
|
process.stdout.write(JSON.stringify({ followup_message: msg }));
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDndPlayerRoot() {
|
||||||
|
if (process.env.DND_PLAYER_ROOT) {
|
||||||
|
const r = path.resolve(process.env.DND_PLAYER_ROOT);
|
||||||
|
if (fs.existsSync(path.join(r, "package.json"))) return r;
|
||||||
|
}
|
||||||
|
const cwd = process.cwd();
|
||||||
|
const candidates = [
|
||||||
|
path.join(cwd, "..", "dnd_player"),
|
||||||
|
path.join(cwd, "dnd_player"),
|
||||||
|
cwd,
|
||||||
|
];
|
||||||
|
for (const root of candidates) {
|
||||||
|
const pkgPath = path.join(root, "package.json");
|
||||||
|
if (!fs.existsSync(pkgPath)) continue;
|
||||||
|
try {
|
||||||
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
||||||
|
if (
|
||||||
|
pkg.scripts?.lint &&
|
||||||
|
pkg.scripts?.typecheck &&
|
||||||
|
pkg.scripts?.test
|
||||||
|
) {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const state = readState();
|
||||||
|
|
||||||
|
if (state.implementation !== "done") {
|
||||||
|
fail("Run frontend-senior stage");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.review !== "done") {
|
||||||
|
fail("Run reviewer stage");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.tests !== "done") {
|
||||||
|
fail("Run unit-tests stage");
|
||||||
|
}
|
||||||
|
|
||||||
|
const dndPlayerRoot = getDndPlayerRoot();
|
||||||
|
if (!dndPlayerRoot) {
|
||||||
|
fail(
|
||||||
|
"Cannot find dnd_player (expected sibling ../dnd_player or env DND_PLAYER_ROOT)",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const opts = { stdio: "pipe", cwd: dndPlayerRoot };
|
||||||
|
|
||||||
|
try {
|
||||||
|
execSync("npm run lint", opts);
|
||||||
|
} catch {
|
||||||
|
fail("Lint failed (run from dnd_player root)");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
execSync("npm run typecheck", opts);
|
||||||
|
} catch {
|
||||||
|
fail("Typecheck failed (run from dnd_player root)");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
execSync("npm run test", opts);
|
||||||
|
} catch {
|
||||||
|
fail("Tests failed (run from dnd_player root)");
|
||||||
|
}
|
||||||
|
|
||||||
|
process.exit(0);
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"hooks": {
|
||||||
|
"stop": [
|
||||||
|
{
|
||||||
|
"command": "node .cursor/hooks/final-verify.cjs"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"implementation": "done",
|
||||||
|
"review": "done",
|
||||||
|
"tests": "done",
|
||||||
|
"verify": "done"
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
# PR: UI — выравнивание под макеты (редактор + пульт)
|
||||||
|
|
||||||
|
**База путей:** репозиторий **`dnd_player/`** (не каталог `cursorAi`).
|
||||||
|
|
||||||
|
Связь с **feature-pipeline** (`.cursor/skills/feature-pipeline/SKILL.md`): критерии ниже сгруппированы по стадиям; после merge обновляют `.cursor/pipeline-state.json` по мере прохождения стадий.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Мета PR
|
||||||
|
|
||||||
|
| Поле | Значение |
|
||||||
|
|------|----------|
|
||||||
|
| **Цель** | Визуальная и UX-полировка существующих экранов без новых продуктовых фич из макета |
|
||||||
|
| **Область** | `EditorApp`, `SceneGraph`, `ControlApp`, общие токены/мелкие UI-баги |
|
||||||
|
| **Вне скоупа** | Новые пункты меню, новые типы сцен, новые каналы микшера, если их нет в коде |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stage 1 — Implementation (subagent: `frontend-senior`)
|
||||||
|
|
||||||
|
### Чеклист PR
|
||||||
|
|
||||||
|
- [ ] **P0-A** Карточка узла графа: статусы «Авто / Цикл / Аудио» отражают **реальные** поля сцены (`previewVideoAutostart`, `settings.loopVideo`, наличие `media.audios`), а не статичный текст.
|
||||||
|
- [ ] **P0-B** Пульт: для сцены с видео-превью явно подписано, что **кисть эффектов** недоступна (согласовано с `PresentationView`: эффекты только для image).
|
||||||
|
- [ ] **P1-A** Пульт: порядок секций **Предпросмотр → Варианты ветвления → Музыка сцены → Быстрый микшер** (вертикальный поток как в референсе).
|
||||||
|
- [ ] **P1-B** Сетка «Варианты ветвления» без «дыр»: `repeat(auto-fit, minmax(...))` **или** фиксированные слоты с disabled/placeholder **без новых сценариев** — только визуальная сетка.
|
||||||
|
- [ ] **P2-A** Редактор: меню «Файл» — цвет текста пункта на валидном токене (`--text0` / `--text1`), без несуществующего `--text`.
|
||||||
|
- [ ] **P2-B** Список сцен: убрать пустой статус-ряд у неактивных карточек (без лишнего вертикального зазора).
|
||||||
|
|
||||||
|
### Критерии приёмки (Stage 1)
|
||||||
|
|
||||||
|
1. На графе для сцены **без видео-превью** не отображаются вводящие в заблуждение чипы «Авто/Цикл» видео-превью; при наличии аудио — корректный индикатор аудио.
|
||||||
|
2. Для сцены с **видео-превью** чипы «Авто»/«Цикл» совпадают с `previewVideoAutostart` и `scene.settings.loopVideo`.
|
||||||
|
3. В пульте при `previewAssetType === 'video'` пользователь видит **одну строку-пояснение** (вторичный текст), почему нет панели эффектов.
|
||||||
|
4. Визуальный порядок блоков пульта соответствует чеклисту P1-A; отступы между `Surface` единообразны (`gap` 16).
|
||||||
|
5. Нет регрессий drag-and-drop сцен на граф и переключения веток.
|
||||||
|
|
||||||
|
**Definition of Done (Stage 1):** все пункты чеклиста Stage 1 отмечены; из **`dnd_player/`**: `npm run build` успешен.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stage 2 — Review (subagent: `reviewer`)
|
||||||
|
|
||||||
|
### Чеклист PR
|
||||||
|
|
||||||
|
- [ ] Нет «мёртвых» веток UI и ложных состояний (чипы/подписи соответствуют данным).
|
||||||
|
- [ ] a11y: фокус/клавиатура на интерактивах не сломаны; `aria-*` не ухудшены.
|
||||||
|
- [ ] Нет лишнего diff вне файлов задачи.
|
||||||
|
|
||||||
|
### Критерии приёмки (Stage 2)
|
||||||
|
|
||||||
|
1. Reviewer фиксирует замечания с **Severity**; все **high** устранены или явно отклонены с причиной в PR.
|
||||||
|
2. После правок по review снова выполняется из **`dnd_player/`**: `npm run build`.
|
||||||
|
|
||||||
|
**Definition of Done (Stage 2):** review-замечания закрыты; state `review: done`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stage 3 — Tests (subagent: `unit-tests`)
|
||||||
|
|
||||||
|
### Чеклист PR
|
||||||
|
|
||||||
|
- [ ] Добавлены или обновлены тесты на **чистую логику** (например, хелпер разметки чипов по `Scene`, если вынесен в `app/shared`).
|
||||||
|
- [ ] Либо задокументировано в PR, что изменения только презентационные и покрыты smoke-тестом пайплайна.
|
||||||
|
|
||||||
|
### Критерии приёмки (Stage 3)
|
||||||
|
|
||||||
|
1. Из **`dnd_player/`**: `npm run test` завершается с кодом 0.
|
||||||
|
2. Новые тесты не flaky, не зависят от Electron UI.
|
||||||
|
|
||||||
|
**Definition of Done (Stage 3):** `tests: done` в `.cursor/pipeline-state.json`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stage 4 — Verify (локально / hook `final-verify.cjs`)
|
||||||
|
|
||||||
|
Выполнить подряд из **`dnd_player/`**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run lint
|
||||||
|
npm run typecheck
|
||||||
|
npm run test
|
||||||
|
```
|
||||||
|
|
||||||
|
**Если `npm run lint` падает на массовых `Delete ␍` (CRLF/LF) в файлах вне PR** — до отдельного chore-PR с нормализацией строк для этого чеклиста достаточно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx eslint app/renderer/control/ControlApp.tsx app/renderer/editor/graph/SceneGraph.tsx app/renderer/shared/ui/sceneGraphChips.ts app/renderer/shared/ui/sceneGraphChips.test.ts --max-warnings 0
|
||||||
|
npm run typecheck
|
||||||
|
npm run test
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Критерии приёмки (Stage 4)
|
||||||
|
|
||||||
|
1. Из **`dnd_player/`**: `npm run typecheck`, `npm run test`, `npm run build` — **exit 0**.
|
||||||
|
2. Линт: либо полный `npm run lint` — **exit 0**, либо (при известном eol-долге репозитория) scoped-ESLint по файлам PR — **exit 0**, как в блоке выше.
|
||||||
|
3. Из корня воркспейса (`cursorAi`): `node .cursor/hooks/final-verify.cjs` — успешное завершение пайплайна только когда полный `npm run lint` в **`dnd_player/`** зелёный (хук вызывает полный lint; при падении lint хук пишет `followup_message` в stdout).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Синхронизация с `.cursor/pipeline-state.json`
|
||||||
|
|
||||||
|
После каждой стадии обновлять файл в **корне воркспейса Cursor** (каталог с `.cursor/`):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"implementation": "done",
|
||||||
|
"review": "done",
|
||||||
|
"tests": "done"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
До начала работы — все `"pending"`.
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
description: Workspace-wide workflow and conventions (dnd_project)
|
||||||
|
alwaysApply: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# DNDGamePlayer / `dnd_project` — правила работы над задачами (future-pipeline)
|
||||||
|
|
||||||
|
Эти правила применяются **только** когда запрос пользователя требует **изменений в репозитории** (код/конфиги/тесты). Для чисто текстовых задач (описания, маркетинг, переписка) pipeline не запускаем.
|
||||||
|
|
||||||
|
**Корень воркспейса Cursor** — обычно каталог `cursorAi` с единым `.cursor/`. Исходники плеера — в соседнем репозитории **`dnd_player/`** (см. `WORKSPACE.md`).
|
||||||
|
|
||||||
|
## future-pipeline (обязательный порядок)
|
||||||
|
|
||||||
|
### 1) Implementation
|
||||||
|
- Прочитать релевантный код (минимум 1 файл), найти реальную причину бага/задачи.
|
||||||
|
- Делать **minimal, review-friendly diff** и следовать текущим паттернам проекта.
|
||||||
|
- Не добавлять зависимости без явной причины.
|
||||||
|
|
||||||
|
### 2) Review
|
||||||
|
- Самопроверка изменений: edge-cases, состояние UI (loading/error/empty/disabled), a11y, регрессии.
|
||||||
|
- Если задача нетривиальная: запустить внутренний «строгий ревью» (под-агент reviewer).
|
||||||
|
|
||||||
|
### 3) Tests
|
||||||
|
- Обновить/добавить тест(ы), если поведение изменилось или был баг.
|
||||||
|
- Для мелких правок допускается «облегчённый режим» без под-агентов, но тесты всё равно должны проходить там, где они есть.
|
||||||
|
|
||||||
|
### 4) Verify (всегда, перед ответом — для **`dnd_player`**)
|
||||||
|
|
||||||
|
Из каталога **`dnd_player/`** (или через хук из корня воркспейса, см. `.cursor/hooks/final-verify.cjs`):
|
||||||
|
|
||||||
|
- `npm run lint`
|
||||||
|
- `npm run typecheck`
|
||||||
|
- `npm run test`
|
||||||
|
|
||||||
|
Если задача касалась **только** `project-converter` или **DndGamePlayerLicenseServer** — выполни адекватную проверку для этого репозитория (`node --check`, локальный прогон) и явно укажи в ответе, что полный набор команд плеера не запускался (если он не нужен по смыслу).
|
||||||
|
|
||||||
|
Если что-то упало — исправить и повторить до green.
|
||||||
|
|
||||||
|
## Команды **`dnd_player`** (справка)
|
||||||
|
|
||||||
|
Выполнять из **`../dnd_player`** относительно `cursorAi`, либо из корня клонированного `dnd_player`:
|
||||||
|
|
||||||
|
- install: `npm install`
|
||||||
|
- dev: `npm run dev`
|
||||||
|
- build: `npm run build`
|
||||||
|
- lint: `npm run lint`
|
||||||
|
- typecheck: `npm run typecheck`
|
||||||
|
- test: `npm run test`
|
||||||
|
|
||||||
|
Полная карта воркспейса: **`WORKSPACE.md`**.
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
---
|
||||||
|
name: feature-pipeline
|
||||||
|
description: Implementation → Review → Tests → Verify
|
||||||
|
---
|
||||||
|
|
||||||
|
# Workflow
|
||||||
|
|
||||||
|
Контекст воркспейса: **`WORKSPACE.md`**. Основной код плеера — репозиторий **`dnd_player/`** (рядом с корнем воркспейса `cursorAi`).
|
||||||
|
|
||||||
|
## Stage 1 — Implementation
|
||||||
|
|
||||||
|
Используй subagent: frontend-senior
|
||||||
|
|
||||||
|
- реализуй задачу
|
||||||
|
- сделай minimal diff
|
||||||
|
|
||||||
|
Обнови state:
|
||||||
|
|
||||||
|
{
|
||||||
|
"implementation": "done"
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stage 2 — Review
|
||||||
|
|
||||||
|
Используй subagent: reviewer
|
||||||
|
|
||||||
|
- проверь изменения
|
||||||
|
- найди проблемы
|
||||||
|
- исправь минимально
|
||||||
|
|
||||||
|
Обнови state:
|
||||||
|
|
||||||
|
{
|
||||||
|
"implementation": "done",
|
||||||
|
"review": "done"
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stage 3 — Tests
|
||||||
|
|
||||||
|
Используй subagent: unit-tests
|
||||||
|
|
||||||
|
- добавь/обнови tests
|
||||||
|
- добейся green status
|
||||||
|
|
||||||
|
Обнови state:
|
||||||
|
|
||||||
|
{
|
||||||
|
"implementation": "done",
|
||||||
|
"review": "done",
|
||||||
|
"tests": "done"
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stage 4 — Verify
|
||||||
|
|
||||||
|
Выполни из каталога **`dnd_player/`** (см. также хук `.cursor/hooks/final-verify.cjs`):
|
||||||
|
|
||||||
|
- `npm run lint`
|
||||||
|
- `npm run typecheck`
|
||||||
|
- `npm run test`
|
||||||
|
|
||||||
|
Если ошибка:
|
||||||
|
|
||||||
|
- исправь
|
||||||
|
- повтори
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Final Output
|
||||||
|
|
||||||
|
- implementation summary
|
||||||
|
- review summary
|
||||||
|
- test summary
|
||||||
|
- verification status
|
||||||
|
|
||||||
|
## PR-чеклисты (приёмка по задаче)
|
||||||
|
|
||||||
|
Готовые чеклисты с критериями по стадиям лежат в `.cursor/pr-checklists/`. Для UI-выравнивания под макеты: `ui-mock-alignment.md`. Пути к файлам в чеклистах — относительно **`dnd_player/`**.
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# Воркспейс `dnd_project` (корень: `cursorAi`)
|
||||||
|
|
||||||
|
Этот каталог — **единая точка входа** в Cursor для всей экосистемы DNDGamePlayer: общие правила, агенты, пайплайн и чеклисты лежат в **`.cursor/`** здесь, а не в отдельных репозиториях.
|
||||||
|
|
||||||
|
Родительская папка на диске: **`D:\Work\my_projects\dnd_project`** (рядом с `cursorAi` лежат остальные репозитории).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Репозитории
|
||||||
|
|
||||||
|
| Каталог | Репозиторий | Назначение |
|
||||||
|
|---------|-------------|------------|
|
||||||
|
| **`cursorAi`** | воркспейс Cursor | Документация (этот файл), единые настройки `.cursor/`. Отдельного приложения нет. |
|
||||||
|
| **`../dnd_player`** | DNDGamePlayer | Electron: редактор и проигрыватель игр (React, Pixi.js, `.dnd.zip`, лицензирование). **Основной** код и полный CI-набор: `lint`, `typecheck`, `test`, `build`. |
|
||||||
|
| **`../project-converter`** | dnd-project-converter | Утилита: конвертация `.dnd.zip`, добавление превью сцен (WebP). Свой `package.json`, отдельный Electron-пакет. |
|
||||||
|
| **`../DndGamePlayerLicenseServer`** | dndgameplayer-license-server | HTTP-сервис лицензий (Ed25519, активация, отзыв). Node ≥20, без npm-зависимостей в манифесте. |
|
||||||
|
|
||||||
|
Связь клиента и сервера лицензий описана в README сервера и в коде плеера (`bundledPublicKey` и переменные окружения).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Сборка и проверки
|
||||||
|
|
||||||
|
- **`dnd_player`**: из каталога репозитория — `npm install`, `npm run dev`, `npm run build`, `npm run lint`, `npm run typecheck`, `npm run test`.
|
||||||
|
- **`project-converter`**: отдельного `build` нет; `npm install`, `npm run dev`. Синтаксис: `node --check` по файлам в `src/`.
|
||||||
|
- **`DndGamePlayerLicenseServer`**: `npm start` (или `node src/server.mjs`); синтаксис: `node --check` для `src/` и `lib/`.
|
||||||
|
|
||||||
|
Хук **`stop`** в Cursor (см. `.cursor/hooks.json`) запускает финальную проверку: стадии в `.cursor/pipeline-state.json` и команды **`lint` / `typecheck` / `test`** выполняются в каталоге **`dnd_player`**, если воркспейс открыт из `cursorAi` (см. логику в `.cursor/hooks/final-verify.cjs`). Переопределение пути: переменная окружения **`DND_PLAYER_ROOT`**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Пайплайн и правила
|
||||||
|
|
||||||
|
- Правила агента по умолчанию: **`.cursor/rules/project.mdc`** (future-pipeline: implementation → review → tests → verify).
|
||||||
|
- Пошаговый сценарий с под-агентами: **`.cursor/skills/feature-pipeline/SKILL.md`**.
|
||||||
|
- Под-агенты: **`.cursor/agents/`** (`frontend-senior`, `reviewer`, `unit-tests`).
|
||||||
|
- PR-чеклисты: **`.cursor/pr-checklists/`** (пути к файлам в чеклистах заданы относительно репозитория **`dnd_player/`**).
|
||||||
|
|
||||||
|
При работе **только** в `project-converter` или `DndGamePlayerLicenseServer` соблюдай смысл пайплайна (минимальный diff, тесты по возможности), а формальные команды `npm run lint` и т.д. из плеера запускай, когда менялся общий контракт или есть смысл прогнать регрессию всего монорепо по смыслу (или по требованию задачи).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Multi-root в Cursor (по желанию)
|
||||||
|
|
||||||
|
Чтобы видеть все папки в одном окне, можно добавить в файл `*.code-workspace` блок `folders` с путями к `cursorAi`, `dnd_player`, `project-converter`, `DndGamePlayerLicenseServer`. Корнем с правилами остаётся папка, где лежит актуальный **`.cursor/`** (рекомендуется **`cursorAi`**).
|
||||||
Reference in New Issue
Block a user