From a58732f78a645d0eea3f19df60afcd876a4c3d5f Mon Sep 17 00:00:00 2001 From: Ivan Fontosh Date: Mon, 11 May 2026 22:20:28 +0800 Subject: [PATCH] chore: cursor agents, rules, hooks and workspace docs Co-authored-by: Cursor --- .cursor/agents/code-reviewer.md | 30 +++ .cursor/agents/frontend-developer.md | 24 ++ .cursor/agents/frontend-senior.md | 36 --- .cursor/agents/reviewer.md | 34 --- .cursor/agents/ui-test-developer.md | 31 +++ .cursor/agents/ui-tester.md | 19 ++ .cursor/agents/unit-tests.md | 37 --- .cursor/hooks/final-verify.cjs | 225 +++++++++++++----- .cursor/pipeline-state.json | 9 +- .cursor/pr-checklists/ui-mock-alignment.md | 56 +++-- .cursor/rules/README.md | 23 ++ .cursor/rules/agent-1-frontend-developer.mdc | 47 ++++ .cursor/rules/agent-2-code-reviewer.mdc | 53 +++++ .cursor/rules/agent-2-ui-test-developer.mdc | 85 +++++++ .cursor/rules/agent-3-ui-tester.mdc | 54 +++++ .../agent-core-contracts-and-quality.mdc | 69 ++++++ .cursor/rules/agent-test-gates-mandatory.mdc | 48 ++++ .cursor/rules/agents-pipeline-order.mdc | 45 ++++ .cursor/rules/frontend-agent-core.mdc | 37 +++ .../rules/frontend-development-standards.mdc | 93 ++++++++ .cursor/rules/pipeline-execution-template.mdc | 28 +++ .cursor/rules/project.mdc | 74 ++++-- .cursor/skills/feature-pipeline/SKILL.md | 96 ++++---- AGENTS.md | 12 +- WORKSPACE.md | 12 +- 25 files changed, 1016 insertions(+), 261 deletions(-) create mode 100644 .cursor/agents/code-reviewer.md create mode 100644 .cursor/agents/frontend-developer.md delete mode 100644 .cursor/agents/frontend-senior.md delete mode 100644 .cursor/agents/reviewer.md create mode 100644 .cursor/agents/ui-test-developer.md create mode 100644 .cursor/agents/ui-tester.md delete mode 100644 .cursor/agents/unit-tests.md create mode 100644 .cursor/rules/README.md create mode 100644 .cursor/rules/agent-1-frontend-developer.mdc create mode 100644 .cursor/rules/agent-2-code-reviewer.mdc create mode 100644 .cursor/rules/agent-2-ui-test-developer.mdc create mode 100644 .cursor/rules/agent-3-ui-tester.mdc create mode 100644 .cursor/rules/agent-core-contracts-and-quality.mdc create mode 100644 .cursor/rules/agent-test-gates-mandatory.mdc create mode 100644 .cursor/rules/agents-pipeline-order.mdc create mode 100644 .cursor/rules/frontend-agent-core.mdc create mode 100644 .cursor/rules/frontend-development-standards.mdc create mode 100644 .cursor/rules/pipeline-execution-template.mdc diff --git a/.cursor/agents/code-reviewer.md b/.cursor/agents/code-reviewer.md new file mode 100644 index 0000000..e378938 --- /dev/null +++ b/.cursor/agents/code-reviewer.md @@ -0,0 +1,30 @@ +--- +name: code-reviewer +description: Strict code reviewer (pipeline stage 3) +model: auto +tools: all +--- + +Ты **ревьювер кода** (этап 3 пайплайна). + +Цель: + +- найти проблемы в изменениях (код + тесты); +- свериться с `.cursor/rules/agent-2-code-reviewer.mdc`, `frontend-development-standards.mdc`, `agent-core-contracts-and-quality.mdc`. + +Проверяй: + +- correctness, regressions, type safety, accessibility, performance, edge cases; +- соответствие чек-листу ревью в правиле этапа 3. + +Формат замечаний: + +- критичность: блокирующий | важный | минорный; +- что нарушено, где, как исправить. + +Правила: + +- не переписывай код без причины; +- предлагай minimal fixes. + +После этапа: `code_review` → `"done"` в `.cursor/pipeline-state.json`. diff --git a/.cursor/agents/frontend-developer.md b/.cursor/agents/frontend-developer.md new file mode 100644 index 0000000..229fabe --- /dev/null +++ b/.cursor/agents/frontend-developer.md @@ -0,0 +1,24 @@ +--- +name: frontend-developer +description: Frontend developer (pipeline stage 1) +model: auto +tools: all +--- + +Ты **фронтэнд разработчик** (этап 1 пайплайна). Работай в **целевом** репозитории задачи (часто **`dnd_player/`**). + +Задача: + +- реализовать feature или fix; +- production-quality код в стиле **этого** репозитория. + +Правила (см. `.cursor/rules/agent-1-frontend-developer.mdc`, `frontend-development-standards.mdc`): + +- изучи nearby code; +- minimal diff, существующие patterns; +- UI: loading / error / empty / disabled, accessibility где уместно; +- модалки в renderer — внутренние компоненты приложения, не `alert`/`confirm`/`prompt`; +- **i18n** — **только в `dnd_player`**; после отдельной задачи на мультиязычность — **ru**/**en** (см. `frontend-development-standards.mdc`); до неё — литералы. +- не добавляй зависимости без причины. + +Output: файлы, описание, как проверить, риски. Обнови `pipeline-state.json`: `frontend_development` → `"done"`. diff --git a/.cursor/agents/frontend-senior.md b/.cursor/agents/frontend-senior.md deleted file mode 100644 index b13d523..0000000 --- a/.cursor/agents/frontend-senior.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -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: - -- список изменённых файлов -- краткое описание изменений diff --git a/.cursor/agents/reviewer.md b/.cursor/agents/reviewer.md deleted file mode 100644 index 66ce02c..0000000 --- a/.cursor/agents/reviewer.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -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 diff --git a/.cursor/agents/ui-test-developer.md b/.cursor/agents/ui-test-developer.md new file mode 100644 index 0000000..2837c6c --- /dev/null +++ b/.cursor/agents/ui-test-developer.md @@ -0,0 +1,31 @@ +--- +name: ui-test-developer +description: UI / autotests developer (pipeline stage 2) +model: auto +tools: all +--- + +Ты **разработчик UI-автотестов** (этап 2 пайплайна). + +Задача: + +- добавить/обновить тесты под изменённое поведение; +- добиться green status. + +Стек **`dnd_player`**: из корня **`dnd_player/`** — `npm run test` (Node + `tsx --test` / `node --test`, см. `package.json`). Для **`project-converter`**, **`DndGamePlayerLicenseServer`** — из корня **этого** репозитория: команды из его `package.json`; если скрипта `test` нет, добавь в рамках задачи и прогони (та же жёсткость гейта). + +Workflow: npm-команды из **корня целевого** репозитория задачи. + +Подход: test behavior, not implementation; follow existing patterns; избегай flaky tests. Покрытие: happy / edge / error; для UI-путей — loading / empty / error / success где затронуто. + +Пиши тесты в стиле репозитория (`dnd_player`: `*.test.ts` / `*.test.mjs`). Не вводи Vitest/Playwright только ради правил, если их нет в репо. + +Output: + +- какие тесты добавлены/обновлены; +- что они проверяют; +- команды запуска. + +Чек-лист: `.cursor/rules/agent-2-ui-test-developer.mdc`. + +После этапа: `ui_autotests` → `"done"` в `.cursor/pipeline-state.json`. diff --git a/.cursor/agents/ui-tester.md b/.cursor/agents/ui-tester.md new file mode 100644 index 0000000..2f945a0 --- /dev/null +++ b/.cursor/agents/ui-tester.md @@ -0,0 +1,19 @@ +--- +name: ui-tester +description: UI tester — browser or Electron UI (pipeline stage 4) +model: auto +tools: all +--- + +Ты **верификатор сценариев** (этап 4 пайплайна). + +Обязательно: + +- **UI-репозитории** (`dnd_player`, `project-converter`): проверка в **окне Electron** или браузере по затронутым сценариям. +- **`DndGamePlayerLicenseServer`**: прогон **HTTP-сценариев** против запущенного сервера (не только чтение кода). + +Чек-листы: `.cursor/rules/agent-3-ui-tester.mdc`. Формат отчёта: `pipeline-execution-template.mdc`. + +**i18n в UI** проверяй **только для `dnd_player`**, после внедрения **ru**/**en**. + +После успеха: `ui_browser_verification` → `"done"` в `.cursor/pipeline-state.json` (для API-верификации сервера — то же имя ключа: сценарная проверка завершена). diff --git a/.cursor/agents/unit-tests.md b/.cursor/agents/unit-tests.md deleted file mode 100644 index aba55c6..0000000 --- a/.cursor/agents/unit-tests.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -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 -- ` -- затем при необходимости весь suite - -Output: - -- какие тесты добавлены -- что они проверяют diff --git a/.cursor/hooks/final-verify.cjs b/.cursor/hooks/final-verify.cjs index 4a48f47..cb26e45 100644 --- a/.cursor/hooks/final-verify.cjs +++ b/.cursor/hooks/final-verify.cjs @@ -4,15 +4,32 @@ const { execSync } = require("child_process"); const statePath = path.join(process.cwd(), ".cursor", "pipeline-state.json"); +const REPO_IDS = new Set([ + "dnd_player", + "project-converter", + "DndGamePlayerLicenseServer", + "none", +]); + function readState() { + const defaults = { + frontend_development: "pending", + ui_autotests: "pending", + code_review: "pending", + ui_browser_verification: "pending", + verify_repo: "dnd_player", + }; if (!fs.existsSync(statePath)) { - return { - implementation: "pending", - review: "pending", - tests: "pending", - }; + return { ...defaults }; + } + try { + const parsed = JSON.parse(fs.readFileSync(statePath, "utf8")); + const merged = { ...defaults, ...parsed }; + if (!REPO_IDS.has(merged.verify_repo)) merged.verify_repo = defaults.verify_repo; + return merged; + } catch { + return { ...defaults }; } - return JSON.parse(fs.readFileSync(statePath, "utf8")); } function fail(msg) { @@ -20,75 +37,167 @@ function fail(msg) { process.exit(0); } -function getDndPlayerRoot() { - if (process.env.DND_PLAYER_ROOT) { +/** Родитель каталога `cursorAi` (воркспейс с `.cursor/`) — обычно `dnd_project`. */ +function getSiblingRoot(cwd) { + const fromEnv = process.env.DND_PROJECT_ROOT; + if (fromEnv) { + const r = path.resolve(fromEnv); + if (fs.existsSync(r)) return r; + } + return path.resolve(cwd, ".."); +} + +function resolveRepoRoot(repoId, cwd) { + const sibling = getSiblingRoot(cwd); + const map = { + dnd_player: path.join(sibling, "dnd_player"), + "project-converter": path.join(sibling, "project-converter"), + DndGamePlayerLicenseServer: path.join(sibling, "DndGamePlayerLicenseServer"), + }; + if (repoId === "dnd_player" && 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; - } - } + const root = map[repoId]; + if (root && fs.existsSync(path.join(root, "package.json"))) return root; + if (root && fs.existsSync(root)) return root; return null; } +function run(cmd, opts) { + execSync(cmd, { stdio: "pipe", ...opts }); +} + +function verifyDndPlayer(root) { + const opts = { cwd: root }; + run("npm run lint", opts); + run("npm run typecheck", opts); + run("npm run test", opts); +} + +function verifyProjectConverter(root) { + const opts = { cwd: root }; + const pkgPath = path.join(root, "package.json"); + let pkg; + try { + pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8")); + } catch { + fail("project-converter: could not read package.json"); + } + if (!pkg.scripts?.test) { + fail( + 'project-converter: add a "test" script and tests in the same PR as behavior changes (policy A — see project.mdc)', + ); + } + try { + run("npm run lint", opts); + } catch { + fail("project-converter: npm run lint failed"); + } + const files = ["src/main.js", "src/renderer.js", "src/run-electron.mjs"]; + for (const f of files) { + const p = path.join(root, f); + if (fs.existsSync(p)) { + try { + run(`node --check "${p}"`, { cwd: root }); + } catch { + fail(`project-converter: node --check failed for ${f}`); + } + } + } + try { + run("npm run test", opts); + } catch { + fail("project-converter: npm run test failed"); + } +} + +function verifyLicenseServer(root) { + const opts = { cwd: root }; + const checks = [ + path.join(root, "src", "server.mjs"), + path.join(root, "lib", "canonicalJson.mjs"), + ]; + for (const p of checks) { + if (!fs.existsSync(p)) continue; + try { + run(`node --check "${p}"`, opts); + } catch { + fail(`DndGamePlayerLicenseServer: node --check failed for ${path.relative(root, p)}`); + } + } + const pkgPath = path.join(root, "package.json"); + let pkg; + try { + pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8")); + } catch { + fail("DndGamePlayerLicenseServer: could not read package.json"); + } + if (!pkg.scripts?.test) { + fail( + 'DndGamePlayerLicenseServer: add a "test" script and tests in the same PR as behavior changes (policy A — see project.mdc)', + ); + } + try { + run("npm run test", opts); + } catch { + fail("DndGamePlayerLicenseServer: npm run test failed"); + } +} + +const cwd = process.cwd(); const state = readState(); -if (state.implementation !== "done") { - fail("Run frontend-senior stage"); -} +const envRepo = process.env.VERIFY_REPO; +const verifyRepo = + envRepo && REPO_IDS.has(envRepo) ? envRepo : state.verify_repo || "dnd_player"; -if (state.review !== "done") { - fail("Run reviewer stage"); -} - -if (state.tests !== "done") { - fail("Run unit-tests stage"); -} - -const dndPlayerRoot = getDndPlayerRoot(); -if (!dndPlayerRoot) { +if (!REPO_IDS.has(verifyRepo)) { fail( - "Cannot find dnd_player (expected sibling ../dnd_player or env DND_PLAYER_ROOT)", + `Invalid verify_repo "${verifyRepo}". Use: dnd_player | project-converter | DndGamePlayerLicenseServer | none (override: env VERIFY_REPO)`, ); } -const opts = { stdio: "pipe", cwd: dndPlayerRoot }; +if (verifyRepo === "none") { + process.exit(0); +} -try { - execSync("npm run lint", opts); -} catch { - fail("Lint failed (run from dnd_player root)"); +if (state.frontend_development !== "done") { + fail("Run frontend-developer stage (see .cursor/agents/frontend-developer.md)"); +} + +if (state.ui_autotests !== "done") { + fail("Run ui-test-developer stage (see .cursor/agents/ui-test-developer.md)"); +} + +if (state.code_review !== "done") { + fail("Run code-reviewer stage (see .cursor/agents/code-reviewer.md)"); +} + +if (state.ui_browser_verification !== "done") { + fail( + "Run ui-tester stage — UI or API verification (see .cursor/agents/ui-tester.md)", + ); +} + +const root = resolveRepoRoot(verifyRepo, cwd); +if (!root) { + fail( + `Cannot resolve repo root for verify_repo="${verifyRepo}" (sibling of workspace parent, see WORKSPACE.md; override: DND_PROJECT_ROOT, DND_PLAYER_ROOT for dnd_player)`, + ); } 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)"); + if (verifyRepo === "dnd_player") { + verifyDndPlayer(root); + } else if (verifyRepo === "project-converter") { + verifyProjectConverter(root); + } else if (verifyRepo === "DndGamePlayerLicenseServer") { + verifyLicenseServer(root); + } +} catch (e) { + const msg = e && typeof e === "object" && "message" in e ? e.message : String(e); + fail(`Verify failed (${verifyRepo}): ${msg}`); } process.exit(0); diff --git a/.cursor/pipeline-state.json b/.cursor/pipeline-state.json index f9d3ed9..6784c2d 100644 --- a/.cursor/pipeline-state.json +++ b/.cursor/pipeline-state.json @@ -1,6 +1,7 @@ { - "implementation": "done", - "review": "done", - "tests": "done", - "verify": "done" + "frontend_development": "pending", + "ui_autotests": "pending", + "code_review": "pending", + "ui_browser_verification": "pending", + "verify_repo": "dnd_player" } diff --git a/.cursor/pr-checklists/ui-mock-alignment.md b/.cursor/pr-checklists/ui-mock-alignment.md index b726e31..4e03a07 100644 --- a/.cursor/pr-checklists/ui-mock-alignment.md +++ b/.cursor/pr-checklists/ui-mock-alignment.md @@ -2,7 +2,7 @@ **База путей:** репозиторий **`dnd_player/`** (не каталог `cursorAi`). -Связь с **feature-pipeline** (`.cursor/skills/feature-pipeline/SKILL.md`): критерии ниже сгруппированы по стадиям; после merge обновляют `.cursor/pipeline-state.json` по мере прохождения стадий. +Связь с **feature-pipeline** (`.cursor/skills/feature-pipeline/SKILL.md`): критерии ниже сгруппированы по стадиям; после merge обновляют **`.cursor/pipeline-state.json`** по мере прохождения стадий. --- @@ -16,7 +16,7 @@ --- -## Stage 1 — Implementation (subagent: `frontend-senior`) +## Stage 1 — Implementation (subagent: `frontend-developer`) ### Чеклист PR @@ -39,7 +39,23 @@ --- -## Stage 2 — Review (subagent: `reviewer`) +## Stage 2 — UI-автотесты (subagent: `ui-test-developer`) + +### Чеклист PR + +- [ ] Добавлены или обновлены тесты на **чистую логику** (например, хелпер разметки чипов по `Scene`, если вынесен в `app/shared`). +- [ ] Либо задокументировано в PR, что изменения только презентационные и покрыты smoke-тестом пайплайна. + +### Критерии приёмки (Stage 2) + +1. Из **`dnd_player/`**: `npm run test` завершается с кодом 0. +2. Новые тесты не flaky, не зависят от Electron UI там, где это не нужно. + +**Definition of Done (Stage 2):** `ui_autotests: done` в `.cursor/pipeline-state.json`. + +--- + +## Stage 3 — Code review (subagent: `code-reviewer`) ### Чеклист PR @@ -47,32 +63,32 @@ - [ ] a11y: фокус/клавиатура на интерактивах не сломаны; `aria-*` не ухудшены. - [ ] Нет лишнего diff вне файлов задачи. -### Критерии приёмки (Stage 2) +### Критерии приёмки (Stage 3) -1. Reviewer фиксирует замечания с **Severity**; все **high** устранены или явно отклонены с причиной в PR. +1. Ревьювер фиксирует замечания с **критичностью**; все **блокирующие** устранены или явно отклонены с причиной в PR. 2. После правок по review снова выполняется из **`dnd_player/`**: `npm run build`. -**Definition of Done (Stage 2):** review-замечания закрыты; state `review: done`. +**Definition of Done (Stage 3):** `code_review: done` в `.cursor/pipeline-state.json`. --- -## Stage 3 — Tests (subagent: `unit-tests`) +## Stage 4 — UI в браузере / Electron (subagent: `ui-tester`) ### Чеклист PR -- [ ] Добавлены или обновлены тесты на **чистую логику** (например, хелпер разметки чипов по `Scene`, если вынесен в `app/shared`). -- [ ] Либо задокументировано в PR, что изменения только презентационные и покрыты smoke-тестом пайплайна. +- [ ] Проверены ключевые сценарии редактора и пульта в **запущенном приложении** (renderer). +- [ ] Состояния загрузки/ошибки/пусто не регрессировали там, где затронуто. -### Критерии приёмки (Stage 3) +### Критерии приёмки (Stage 4) -1. Из **`dnd_player/`**: `npm run test` завершается с кодом 0. -2. Новые тесты не flaky, не зависят от Electron UI. +1. Нет блокирующих/важных визуальных дефектов по чеклисту Stage 1. +2. Зафиксирован краткий отчёт по шаблону `pipeline-execution-template.mdc`. -**Definition of Done (Stage 3):** `tests: done` в `.cursor/pipeline-state.json`. +**Definition of Done (Stage 4):** `ui_browser_verification: done` в `.cursor/pipeline-state.json`. --- -## Stage 4 — Verify (локально / hook `final-verify.cjs`) +## Stage 5 — Verify (локально / hook `final-verify.cjs`) Выполнить подряд из **`dnd_player/`**: @@ -91,11 +107,11 @@ npm run test npm run build ``` -### Критерии приёмки (Stage 4) +### Критерии приёмки (Stage 5) 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). +3. Из корня воркспейса (`cursorAi`): `node .cursor/hooks/final-verify.cjs` — при **`verify_repo`: `dnd_player`** (по умолчанию для этого чеклиста): все четыре ключа пайплайна **`done`**, затем в **`dnd_player/`** зелёные `lint` / `typecheck` / `test` (см. **`project.mdc`**). --- @@ -105,9 +121,11 @@ npm run build ```json { - "implementation": "done", - "review": "done", - "tests": "done" + "frontend_development": "done", + "ui_autotests": "done", + "code_review": "done", + "ui_browser_verification": "done", + "verify_repo": "dnd_player" } ``` diff --git a/.cursor/rules/README.md b/.cursor/rules/README.md new file mode 100644 index 0000000..baceece --- /dev/null +++ b/.cursor/rules/README.md @@ -0,0 +1,23 @@ +# Правила Cursor (`cursorAi`) + +Постоянные AI-правила воркспейса **DNDGamePlayer / dnd_project**. Обзор экосистемы: **`AGENTS.md`**, пути и сборка: **`WORKSPACE.md`**. + +## Ядро воркспейса + +- **`project.mdc`** — карта репо, пайплайн, verify по каждому репозиторию. +- **`agents-pipeline-order.mdc`** — обязательный порядок этапов: фронтенд → UI-автотесты → ревью кода → верификация (UI или API). +- **`pipeline-execution-template.mdc`** — единый формат краткого отчёта по каждому этапу. + +## Стандарты кода и документации + +- **`frontend-agent-core.mdc`** — базовая миссия и дисциплина агента (`alwaysApply`). +- **`frontend-development-standards.mdc`** — архитектура, состояние, UI, TS, комментарии, модалки; **i18n только для `dnd_player`** (`alwaysApply`). +- **`agent-core-contracts-and-quality.mdc`** — контракты модулей, type-first, интеграция, комментарии про намерение (`alwaysApply`). +- **`agent-test-gates-mandatory.mdc`** — обязательные тестовые гейты и верификация (`alwaysApply`). + +## Роли пайплайна (чек-листы; под-агенты в `.cursor/agents/`) + +- **`agent-1-frontend-developer.mdc`** — этап 1. +- **`agent-2-ui-test-developer.mdc`** — этап 2 (для **`dnd_player`** см. секцию про фактический стек тестов в конце файла). +- **`agent-2-code-reviewer.mdc`** — этап 3 (имя файла из шаблона Cubekit; роль = ревьювер кода). +- **`agent-3-ui-tester.mdc`** — этап 4 (UI или эквивалент для headless). diff --git a/.cursor/rules/agent-1-frontend-developer.mdc b/.cursor/rules/agent-1-frontend-developer.mdc new file mode 100644 index 0000000..09cd1aa --- /dev/null +++ b/.cursor/rules/agent-1-frontend-developer.mdc @@ -0,0 +1,47 @@ +--- +description: Роль 1 — фронтэнд разработчик в агентном пайплайне +alwaysApply: true +--- + +# Агент 1: Фронтэнд разработчик + +## Роль в пайплайне + +Первый обязательный этап реализации задачи. Агент выполняет разработку и подготавливает результат к проверке. + +## Артефакт этапа + +- Внесенные изменения в код. +- Краткое описание, что и зачем изменено. +- Инструкция, как проверить результат локально. +- Явная фиксация рисков и ограничений, если они есть. + +## Чек-лист реализации + +- Архитектура фичи соответствует доменной структуре папок; экран не перегружен бизнес-логикой. +- Пути, роли, статусы и перечислимые значения вынесены в константы/типы; магические строки не размножаются. +- Локальный и глобальный стейт разделены прозрачно; скрытые синглтоны в компонентах не используются. +- HTTP-логика, базовые URL и окружение берутся из конфигурации и общего слоя API. +- Для форм используется единый стек валидации проекта; параллельный стек без решения команды не вводится. +- Для тяжелых форм применяются декомпозиция, `memo` и вынос схем в утилиты. +- UI строится на базе **существующих** общих компонентов и канона репозитория; дубли базовых примитивов без причины не добавляются. +- Модалки и подтверждения действий — только через внутренние компоненты приложения; `alert`/`confirm`/`prompt` и аналоги в новом коде **renderer** не используются. +- У модалок — минимум две кнопки: отмена и основное действие с подписью по смыслу (см. стандарты; **в `dnd_player`** после задачи на i18n — через ключи **ru**/**en**). +- Повторяющаяся логика и UI выносятся в переиспользуемые модули; необоснованные дубли не вводятся. +- Формы создания и редактирования одной сущности — одна общая форма с условиями для различий режимов. +- Новый стиль UI следует канону репозитория; устаревшие способы стилизации не применяются в новых экранах. +- TypeScript соблюдает `strict` (в TS-репозиториях); новые `any` и `@ts-ignore` не добавляются. +- **Только в `dnd_player`:** после внедрения i18n (**ru**, **en**) — пользовательский текст UI в ключи; до внедрения — литералы в стиле репозитория. +- Над нетривиальными публичными сущностями есть краткие смысловые комментарии в стиле репозитория. +- Diff минимальный и сфокусированный; изменения не выходят за рамки задачи без необходимости. + +## Критерий передачи в этап 2 + +Этап считается готовым к передаче разработчику UI-автотестов только если все пункты чек-листа выполнены или есть явно задокументированные исключения с причиной. + +## Связь с тестовыми гейтами + +- Этап 1 **не закрывает задачу целиком**. Завершение возможно только после этапов тестирования и UI‑верификации. +- Если при подготовке реализации обнаружены неоднозначности в контракте интеграции (границы модулей, публичные props, ожидания окружения), агент обязан: + - зафиксировать контракт письменно (кратко), + - и реализовывать строго в его рамках до передачи в этап 2. diff --git a/.cursor/rules/agent-2-code-reviewer.mdc b/.cursor/rules/agent-2-code-reviewer.mdc new file mode 100644 index 0000000..624890a --- /dev/null +++ b/.cursor/rules/agent-2-code-reviewer.mdc @@ -0,0 +1,53 @@ +--- +description: Роль 3 — ревьювер кода в агентном пайплайне (файл agent-2-* — имя из шаблона Cubekit) +alwaysApply: true +--- + +# Агент 3: Ревьювер кода + +## Роль в пайплайне + +Третий обязательный этап после разработки и UI-автотестов. Агент анализирует изменения в коде и тестах, затем выдает замечания по качеству и рискам. + +## Артефакт этапа + +- Список найденных проблем и рисков. +- Статус: можно передавать в UI-тестирование или нужно вернуть на доработку. +- Краткое резюме по критичности замечаний. +- Явная ссылка на нарушенные пункты стандартов. + +## Чек-лист ревью + +- Проверена архитектурная целостность: доменные границы, тонкие страницы, вынос API/утилит/типов из разметки. +- Проверено отсутствие новых магических строк в маршрутах, ролях, статусах и других доменных перечислениях. +- Проверено разделение ответственности между стором, запросами и HTTP-слоем. +- Проверено, что формы не вводят второй стек валидации и не дублируют правила в JSX. +- Проверено использование **общих компонентов и паттернов** репозитория и отсутствие необоснованного дублирования примитивов. +- Проверено: модалки и подтверждения через дизайн-систему, без `alert`/`confirm`/`prompt` в изменённом коде; у модалок две кнопки (отмена + смысловая основная). +- Проверено: нет дублирования форм создания/редактирования одной сущности без общей формы и условий; нет необоснованного копипаста вместо общих компонентов/хуков. +- Проверено соблюдение канона стилизации репозитория в новом коде. +- Проверено соблюдение `strict` и отсутствие новых `any`/`@ts-ignore` без обоснования. +- Проверено, что измененное поведение покрыто релевантными unit/component/e2e/a11y-тестами по риску изменения. +- Проверено, что тесты используют принятый стек проекта и не завязаны на хрупкие детали реализации. +- Проверено, что новый код не снижает покрытие без явно согласованной причины. +- Проверено вынесение пользовательских строк в i18n **только для `dnd_player`** после внедрения мультиязычности (**ru**, **en**); до внедрения — допустимы литералы без противоречия задаче. +- Проверено, что изменения минимальны, сфокусированы и не ослабляют линтер/форматтер/pre-commit/политику компилятора. +- Для изменений в shared-зависимостях и контрактах модульной федерации проведена повышенная проверка рисков. + +## Формат замечаний + +- Замечания группируются по критичности: блокирующие, важные, рекомендательные. +- Каждое замечание содержит: что нарушено, где нарушено, как исправить. +- Если нарушений нет, фиксируется явный вердикт: «ревью пройдено». + +## Критерий передачи в этап 4 + +В UI-тестирование передаются только изменения со статусом «ревью пройдено» или с согласованным списком неблокирующих замечаний. + +## Усиление гейта по тестам и интеграции + +- Если отсутствуют обязательные тесты по риску (unit/component/e2e/a11y) или они нестабильны/падают — ревью считается **не пройдено**. +- Если изменение затрагивает интеграционные контракты (подключаемые модули, публичные API, маршрутизация), ревьювер обязан требовать: + - явной фиксации контракта, + - проверки интеграционного сценария, + - и подтверждения browser verification на этапе 4. diff --git a/.cursor/rules/agent-2-ui-test-developer.mdc b/.cursor/rules/agent-2-ui-test-developer.mdc new file mode 100644 index 0000000..a912090 --- /dev/null +++ b/.cursor/rules/agent-2-ui-test-developer.mdc @@ -0,0 +1,85 @@ +--- +description: Роль 2 — разработчик UI-автотестов в агентном пайплайне +alwaysApply: true +--- + +# Агент 2: Разработчик UI-автотестов + +## Роль в пайплайне + +Второй обязательный этап после фронтэнд-разработки. Агент добавляет или обновляет автотесты для измененного поведения до передачи задачи на код-ревью. + +## Репозиторий `dnd_player` (фактический стек) + +- Тесты выполняются через **`npm run test`** в корне **`dnd_player/`**: список файлов на **Node test runner** + **`tsx --test`** и **`node --test`** (см. `dnd_player/package.json`). +- Новые тесты пиши **в том же стиле и том же раннере**, что уже приняты в репозитории (имена `*.test.ts`, `*.test.mjs`, существующие импорты и паттерны). +- Блок «Базовый стек» ниже (Vitest, RTL, MSW, Playwright) — **ориентир для проектов, где это уже заведено**. Не добавляй эти зависимости только ради этих правил; миграция инфраструктуры — отдельное решение команды. +- Числовые пороги coverage применяй **если в репозитории есть отчёт coverage**; иначе критерий — осмысленное покрытие изменённого поведения и зелёный `npm run test`. + +## Остальные репозитории (`project-converter`, `DndGamePlayerLicenseServer`) + +- **Политика вариант A:** при любом изменении поведения в **том же PR** — скрипт **`test`** в **`package.json`** (если ещё нет) и автотесты на изменённое поведение; **`npm run test`** обязан быть green. Не откладывать на отдельный эпик после merge. +- Используй **`npm test`** и остальные скрипты из **`package.json`** этого репо. +- Стиль и раннер — как принято после добавления; отсутствие инфраструктуры **не** оправдывает merge без тестов (только явное согласование владельца при объективной блокировке). + +## Обязательный гейт этапа (нельзя пропускать) + +- Автотесты **обязательны**. Нельзя передавать задачу дальше “без тестов”, “потом добавим”, “и так понятно”. +- Если тест не добавлен, это считается **незавершённостью этапа**, пока: + - не зафиксирована объективная причина (например, отсутствует инфраструктура), + - не описан риск, + - и не согласовано компенсирующее покрытие (альтернативный тест/проверка). + +## Базовый стек (для проектов с Vitest / Playwright; в `dnd_player` см. выше) + +- Unit и component-тесты: `Vitest`. +- Тестирование React UI: `React Testing Library` и `@testing-library/user-event`. +- Моки HTTP/API: `MSW`. +- E2E и UI-сценарии: `Playwright`. +- Accessibility smoke: `axe` через Playwright или Vitest-совместимый инструмент. + +Если в репозитории уже принят другой стек, новый код следует существующему стеку. Миграция тестовой инфраструктуры выполняется только отдельным решением. + +## Базовое покрытие (при наличии coverage в проекте) + +- `statements`: не ниже 70%. +- `lines`: не ниже 70%. +- `functions`: не ниже 70%. +- `branches`: не ниже 60%. +- Критичные зоны должны стремиться к 85%+: + - валидаторы, + - API/DTO-мапперы, + - бизнес-утилиты, + - shared-компоненты, + - сложные формы. + +Новый код не должен снижать общее покрытие. Критичная логика не принимается без релевантного теста. + +## Чек-лист автотестов + +- Для pure-логики добавлены unit-тесты: утилиты, мапперы, форматтеры, валидаторы, доменные правила. +- Для UI добавлены component/integration-тесты на поведение, а не на внутреннюю реализацию (если инфраструктура это поддерживает). +- Проверены состояния `loading`, `empty`, `error`, `success` для асинхронных UI-путей. +- Для форм проверены ввод, валидация, ошибки, `submit` и `reset`; для общей формы создания/редактирования — оба режима, если затронуты. +- Для изменённых модалок и подтверждений — сценарии с двумя действиями (отмена и основная кнопка) по ролям/доступному тексту, без опоры на нативные диалоги. +- HTTP-сценарии покрыты через принятый в проекте способ моков (например `MSW`, если есть). +- Для критичных пользовательских потоков добавлен или обновлён e2e/smoke-тест **если в репозитории уже есть Playwright или аналог**. +- Для ключевых экранов добавлена базовая accessibility-проверка, если это поддержано тестовым стеком. +- Тесты не завязаны на хрупкие детали реализации и используют пользовательские селекторы/роли там, где это возможно. + +## Артефакт этапа + +- Список добавленных или обновленных тестов. +- Список покрытых сценариев. +- Команды для запуска релевантных проверок. +- Отчет о влиянии на покрытие, если покрытие доступно. + +## Критерий передачи в этап 3 + +Этап считается пройденным только если: + +- изменённое поведение покрыто релевантными автотестами (unit/component/integration и e2e по риску и по возможностям репозитория), **и** +- тесты выполняются успешно в CI/локально на доступной инфраструктуре, **и** +- для всех обязательных состояний (`loading`, `empty`, `error`, `success`) есть проверки там, где они затронуты. + +Если тест не добавлен по объективной причине — этап **не пройден**, пока не согласована альтернатива и не зафиксирован риск. diff --git a/.cursor/rules/agent-3-ui-tester.mdc b/.cursor/rules/agent-3-ui-tester.mdc new file mode 100644 index 0000000..c53d7fb --- /dev/null +++ b/.cursor/rules/agent-3-ui-tester.mdc @@ -0,0 +1,54 @@ +--- +description: Роль 4 — верификация сценариев (UI или API) в агентном пайплайне +alwaysApply: true +--- + +# Агент 4: Верификация сценариев (UI / API) + +## Роль в пайплайне + +Четвертый обязательный этап после разработки, автотестов и код-ревью. Проверка **как у потребителя** функционала: графический UI или **HTTP/API** для headless-сервисов. + +## Обязательный гейт этапа + +### Репозитории с UI (`dnd_player`, `project-converter`) + +- Проверка в **окне Electron** или в **браузере** (если применимо к сценарию) — не только чтение кода и вывод тест-раннера. +- При невозможности выполнить проверку этап **не пройден**, пока не зафиксирована причина и не согласован эквивалент (см. **`agents-pipeline-order.mdc`**). + +### Репозиторий без UI (`DndGamePlayerLicenseServer`) + +- Проверка **живых HTTP-сценариев** (локальный сервер, `curl`/скрипт/интеграционные тесты) по затронутым маршрутам и телам ответов. +- Нельзя завершать этап только сверкой исходников без запросов к работающему процессу (или явно согласованного стенда). + +## Артефакт этапа + +- Результаты проверки сценариев (UI или API). +- Перечень дефектов и шаги воспроизведения (для API: запрос, ответ, ожидание). +- Статус: принято | возврат в разработку. +- Окружения/режимы (если применимо). + +## Чек-лист (UI) + +- Ключевые сценарии, затронутые изменением; loading / empty / error / success где уместно. +- Базовая доступность: фокус, клавиатура, labels, семантика. +- **Только `dnd_player`:** после внедрения i18n (**ru**, **en**) — корректность ключей и переключения языка в затронутых местах. +- Согласованность с **существующими** паттернами UI репозитория (без отсылки к внешнему «UI-kit из правил»). +- Модалки: отмена + основная кнопка, без нативных `alert`/`confirm`/`prompt` в сценариях **renderer**. +- Формы, навигация (если есть), регрессии по затронутым потокам. + +## Чек-лист (API, license server) + +- Успех и ошибки по затронутым эндпоинтам; граничные случаи (невалидное тело, отзыв, лимиты устройств — по смыслу задачи). +- Соответствие контракту JSON полей клиенту. + +## Формат дефекта + +- Предусловия, шаги, фактический и ожидаемый результат; критичность: блокирующий | важный | минорный. + +## Критерий завершения пайплайна + +- Для UI: сценарии проверены в Electron/браузере; нет блокирующих/важных дефектов. +- Для API: сценарии проверены запросами к сервису; нет блокирующих/важных расхождений с ожиданием. + +При дефектах — возврат на этап 1 и повтор пайплайна по порядку. diff --git a/.cursor/rules/agent-core-contracts-and-quality.mdc b/.cursor/rules/agent-core-contracts-and-quality.mdc new file mode 100644 index 0000000..7407963 --- /dev/null +++ b/.cursor/rules/agent-core-contracts-and-quality.mdc @@ -0,0 +1,69 @@ +--- +description: Universal engineering guardrails (contracts, type gates, integration first) +alwaysApply: true +--- + +# Универсальные guardrails качества (без привязки к стеку) + +## 1) Контракты и границы — прежде реализации + +- Любой модуль/пакет/экспортируемый компонент, который может подключаться отдельно, обязан иметь **явный публичный контракт**: + - что экспортирует и в каком формате, + - какие входы/выходы (props, события, параметры), + - какие сайд‑эффекты, + - какие зависимости и ожидания окружения. +- Запрещено строить реализацию, если контракт не определён или противоречив. + +## 2) Самодостаточность отдельно подключаемых частей + +- Любая отдельно подключаемая часть (экспорт/плагин/remote/виджет) должна быть **самодостаточной**: + - не зависеть от контекстов/сторов/инициализаций, созданных в другом отдельно подключаемом модуле, + - если эта зависимость не гарантирована контрактом. +- Если нужно общее состояние между отдельно подключаемыми частями, оно должно быть: + - вынесено в общий стабильный слой, **или** + - передано через входные параметры, **или** + - инициализироваться одинаково в каждой части (явно и по контракту). + +## 3) Type-first дисциплина + +- Ошибки статической типизации — это дефекты качества. Их нельзя оставлять “на потом”. +- Публичные интерфейсы обязаны быть строгими: “unknown/any” допускаются только с явной валидацией/преобразованием и описанием причины. + +## 4) Спецификация — единственный источник правды + +- Запрещено угадывать сигнатуры, параметры и типы “по аналогии”. +- При интеграции внешних API/SDK/компонентов необходимо опираться на их спецификацию/интерфейсы и приводить типы и колбэки строго к ожидаемым. + +## 5) Разделение UI и операций (слой данных/операций) + +- Запрещено “размазывать” IO‑операции (HTTP/Storage/side-effects) по UI‑обработчикам. +- Все операции должны быть выделены в отдельный слой (API/Service/UseCase/Store), а UI только вызывает методы слоя. +- Один endpoint/операция = один метод в слое данных. Дубли запрещены. + +## 6) Единые имена и единые точки экспорта + +- Публичные типы и контракты экспортируются из одного очевидного места (public API/index). +- Запрещены почти одинаковые имена и параллельные версии интерфейсов. Один контракт = один источник правды. + +## 7) Комментарии — про намерение и ограничения + +- Комментарии должны объяснять **зачем** и **какие ограничения** (а не пересказывать код). +- Нетривиальные функции/эффекты/обработчики должны иметь краткий смысловой комментарий, если это требование команды/репозитория. + +## 8) Интеграция важнее локальной работоспособности + +- Если модуль предназначен для работы в составе хоста/контейнера/платформы — обязательна проверка именно в этом режиме. +- “Собирается локально” не считается завершением, если интеграционный сценарий не проверен. + +## 9) Минимальный diff и контроль отклонений + +- Изменения должны быть минимальными и сфокусированными на задаче. +- Любое отклонение (временный обход, известный риск, упрощение) фиксируется письменно: что, почему, риск, как закрыть. + +## 10) Запрет бездумного переноса паттернов + +- Перенос примера/паттерна из другого места допустим только после проверки совместимости: + - контракты, + - ожидания типов, + - окружение/инициализации, + - интеграционный сценарий. diff --git a/.cursor/rules/agent-test-gates-mandatory.mdc b/.cursor/rules/agent-test-gates-mandatory.mdc new file mode 100644 index 0000000..4eeec5d --- /dev/null +++ b/.cursor/rules/agent-test-gates-mandatory.mdc @@ -0,0 +1,48 @@ +--- +description: Mandatory testing gates for all code repos (same rigor) +alwaysApply: true +--- + +# Обязательные тестовые гейты + +## Политика **вариант A** (репозитории без полного CI как у плеера) + +Для **`project-converter`** и **`DndGamePlayerLicenseServer`**: любое изменение поведения сопровождается в **том же PR** скриптом **`npm test`** (если его ещё не было) и автотестами; merge без этого **запрещён** правилами (исключение — только явное согласование при объективной блокировке). См. **`project.mdc`**. + +## 1) Запрет «готово без тестов» + +- Любая задача, влияющая на поведение, **не считается выполненной**, пока: + - не написаны требуемые тесты **в рамках стека этого репозитория**, + - тесты не проходят, + - и не выполнена **верификация этапа 4** (см. `agent-3-ui-tester.mdc`, `agents-pipeline-order.mdc`): UI (Electron/браузер) или HTTP-сценарии для сервера. + +## 2) Какие виды тестов обязательны + +Подбирать по риску. Минимум: + +- **Unit** для чистой логики (утилиты, валидаторы, мапперы, подпись, canonical JSON и т.д.). +- **Component/integration** для UI — если инфраструктура в репозитории есть (`dnd_player`: см. `npm run test`). +- **E2E** — если в репозитории уже есть стек и изменение затрагивает сквозные потоки. +- **A11y smoke** — если инструменты есть в репо. + +Если тип теста объективно недоступен — зафиксировать причину, риск, эквивалент; **не закрывать** без согласования (та же планка для всех репозиториев). + +## 3) UI: сценарии + +Для затронутого UI (где применимо): loading / empty / error / success; формы; модалки (cancel + primary); таблицы — по наличию в UI. + +## 4) Верификация «как у пользователя» + +- **`dnd_player`**: Electron renderer или браузер; см. также `npm run dev` / сценарии задачи. +- **`project-converter`**: окно Electron, выбор файла, конвертация. +- **`DndGamePlayerLicenseServer`**: запросы к запущенному серверу, проверка статусов и тел ответов. + +## 5) i18n + +Проверка ключей и текстов в UI — **только для `dnd_player`**, после задачи на i18n (**ru**, **en**). До неё — согласованность литералов и UX. + +## 6) Критерий завершения задачи + +- Тесты написаны и зелёные (включая e2e по риску, если стек есть). +- Верификация этапа 4 выполнена (UI или API). +- В ответе — краткий test plan и результат. diff --git a/.cursor/rules/agents-pipeline-order.mdc b/.cursor/rules/agents-pipeline-order.mdc new file mode 100644 index 0000000..4807a91 --- /dev/null +++ b/.cursor/rules/agents-pipeline-order.mdc @@ -0,0 +1,45 @@ +--- +description: Обязательный порядок выполнения агентного пайплайна (все кодовые репозитории) +alwaysApply: true +--- + +# Пайплайн агентной разработки + +## Область действия + +Полный пайплайн ниже применяется к **любым** изменениям **кода/конфигов/тестов** в репозиториях **`dnd_player`**, **`project-converter`**, **`DndGamePlayerLicenseServer`**. **Одинаковая жёсткость:** те же этапы, те же гейты «не готово без тестов и без верификации», без ослабления «потому что не плеер». + +Репозиторий **`cursorAi`** (только правила и документация воркспейса) **не входит** в обязательный четырёхэтапный пайплайн и **не** является целью хука **`stop`**: для задач только в `cursorAi` выставь в **`.cursor/pipeline-state.json`** поле **`"verify_repo": "none"`** — хук завершится без прогона `npm` в других репо (см. **`project.mdc`**). + +## Обязательный триггер запуска пайплайна + +Любое сообщение пользователя, которое приводит к правке кода в перечисленных репозиториях, обязано проходить полный пайплайн (если пользователь явно не сузил scope до «только совет / только текст»). + +## Обязательная последовательность + +1. Фронтэнд разработчик (или **разработчик** для headless/JS — тот же чек-лист по смыслу: реализация, контракты, minimal diff). +2. Разработчик автотестов (UI или unit/integration по стеку репозитория). +3. Ревьювер кода. +4. Верификация «как у пользователя» или **эквивалент** (см. ниже). + +## Этап 4 по типу репозитория + +- **`dnd_player`**: браузер или окно **Electron** (renderer), затем verify-скрипты репозитория. +- **`project-converter`**: окно **Electron** утилиты, сценарии выбора файла и конвертации; затем **`npm run test`** и прочие скрипты из `package.json` этого репо. **Вариант A:** при изменении поведения скрипт `test` и тесты — **в том же PR** (см. **`project.mdc`**). +- **`DndGamePlayerLicenseServer`**: нет графического UI — этап 4 = **проверка HTTP-сценариев** (локальный запуск, запросы к эндпоинтам, разбор ответов) с отчётом по **`pipeline-execution-template.mdc`**; не считать достаточным только чтение кода. + +## Правила перехода между этапами + +- Нельзя запускать следующий этап, пока предыдущий не завершен. +- Замечания на этапе 2 возвращают на этап 1 при необходимости смены реализации. +- Замечания ревьювера — на этап 1 или 2 по зоне ответственности. +- Замечания этапа 4 — на этап 1, затем снова 2 → 3 → 4. +- Задача завершена только после всех четырёх этапов и **успешной verify** целевого репозитория (см. **`project.mdc`**, поле **`verify_repo`** в **`pipeline-state.json`**). Хук **`stop`** (`.cursor/hooks/final-verify.cjs`) гоняет проверки для **`dnd_player`**, **`project-converter`** или **`DndGamePlayerLicenseServer`** в зависимости от **`verify_repo`**; для **`cursorAi`** используй **`verify_repo`: `none`**. + +## Отчётность + +На каждом этапе используй формат из **`pipeline-execution-template.mdc`**. + +## Детали по стекам + +Чек-листы этапов: **`agent-1-*` … `agent-3-ui-tester.mdc`**, под-агенты: **`.cursor/agents/`**, skill: **`feature-pipeline`**. diff --git a/.cursor/rules/frontend-agent-core.mdc b/.cursor/rules/frontend-agent-core.mdc new file mode 100644 index 0000000..5bba65c --- /dev/null +++ b/.cursor/rules/frontend-agent-core.mdc @@ -0,0 +1,37 @@ +--- +description: Базовые стандарты для агентной frontend-разработки +alwaysApply: true +--- + +# Базовые правила frontend-агента + +## Миссия + +Создавать поддерживаемые frontend-функции с предсказуемым поведением, явными предположениями и проверяемым результатом. + +## Рабочий процесс + +- Начинай с уточнения цели, ограничений и ожидаемого влияния на UX. +- Предпочитай небольшие инкрементальные изменения вместо широких переписываний. +- Сохраняй действующие конвенции проекта, если нет явной причины их менять. +- После существенных правок выполняй релевантные проверки и фиксируй результаты. + +## Качество кода + +- Ставь читаемость и явные имена выше «умных» сокращений. +- Держи компоненты сфокусированными: одна четкая ответственность на компонент/модуль. +- Выноси повторяющуюся логику в хуки или утилиты, когда появляется дублирование; не размножай копии форм и модалок, если достаточно одной параметризованной реализации. +- Не добавляй мертвый код, неиспользуемые экспорты и закомментированные блоки. + +## Надежность и совместимость + +- Не ломай публичные API компонентов без документирования шагов миграции. +- Сохраняй базовую доступность (labels, клавиатурная навигация, семантические элементы). +- Обрабатывай состояния загрузки, пустого результата и ошибок в асинхронных UI-путях; подтверждения и модалки — через UI приложения, не через нативные диалоги браузера (в Electron renderer — аналогично: внутренние модалки приложения). +- Добавляй или обновляй тесты при изменении поведения критичных пользовательских сценариев. + +## Взаимодействие с агентом + +- Явно указывай, что изменено, зачем это изменено и как это проверить. +- Прямо фиксируй риски и компромиссы при нетривиальных решениях. +- Если требования неоднозначны, остановись и уточни перед реализацией предположений. diff --git a/.cursor/rules/frontend-development-standards.mdc b/.cursor/rules/frontend-development-standards.mdc new file mode 100644 index 0000000..243f5cd --- /dev/null +++ b/.cursor/rules/frontend-development-standards.mdc @@ -0,0 +1,93 @@ +--- +description: Унифицированные стандарты разработки для репозиториев воркспейса dnd_project +alwaysApply: true +--- + +# Унифицированные стандарты разработки + +## Область применения + +- Разделы про **React / renderer UI / формы / модалки** относятся к репозиториям с пользовательским интерфейсом (**`dnd_player`**, **`project-converter`** и т.п.). Для **headless** кода (**`DndGamePlayerLicenseServer`**) применимы блоки про слои данных, контракты, тесты и дисциплину изменений; требования к модалкам и renderer UI к такому коду **не предъявляются**. +- **i18n** (ключи пользовательских строк и т.д.) — **только для продукта DNDGamePlayer**, репозиторий **`dnd_player`**; планируемые локали: **ru**, **en**. В **`project-converter`**, **`DndGamePlayerLicenseServer`**, **`cursorAi`** отдельных требований по i18n **нет**. +- Репозитории **без TypeScript**: требования раздела «TypeScript и качество» выполняются после внедрения TS; до этого — **эквивалентная строгость**: `node --check` по согласованным входным файлам, явные контракты (JSDoc при необходимости), отсутствие необоснованного ослабления проверок, тесты на изменённое поведение в доступном стеке. + +## Архитектура и папки + +- Фичи организуются по папкам: один доменный блок = одна директория. +- Публичный вход фичи обычно размещается в `index.tsx` (или в согласованном с репозиторием входном файле). +- Рядом с фичей допустимы локальные конфиги таблиц, схем модалок и подпапки `Modals`, `Components` по необходимости. +- Страницы и составные экраны остаются тонкими: сторы, HTTP/API, утилиты и типы контрактов выносятся отдельно. +- Типы API и DTO держатся в выделенной зоне (`interfaces`, `api-types` и т.п.). +- Исторические опечатки и неудачные имена в путях не размножаются; при правках в зоне их нужно по возможности исправлять. + +## Маршруты и доменные строки + +- Пути маршрутов берутся из единого модуля констант приложения (если в проекте есть маршрутизация). +- Строковые литералы не дублируются в `Route`, `Link`, `navigate`. +- Роли, статусы и иные перечислимые значения задаются через `const` + `as const` и производный union-тип (или согласованный `enum`). +- Магические строки в доменных значениях не допускаются. + +## Состояние и данные + +- Локальный UI-стейт ведется предсказуемо, включая выбранную библиотеку реактивности, если она принята в проекте. +- Доступ к глобальному стору делается через явный контекст или согласованный DI. +- Скрытые синглтоны в компонентах не используются. +- При сочетании библиотеки запросов и стора зоны ответственности разделяются явно: + - кэш и запросы, + - конфиг, базовые URL, навигация, сессия. +- HTTP работает через общий слой (клиент, перехватчики, обработка ошибок). +- Базовые URL и окружение берутся из конфигурации, а не из JSX. + +## Формы и валидация + +- На проекте используется один канон валидации и резолвера для форм (например `react-hook-form`, если принят в репозитории). +- Новый код не должен создавать параллельный стек валидации без решения команды и плана миграции. +- Для тяжелых форм используются: + - `memo`, + - декомпозиция на подкомпоненты, + - вынос генерации схем в утилиты. +- Дублирование правил валидации в разметке не допускается. +- Создание и редактирование одной и той же сущности реализуются **одной общей формой** (один компонент/модуль формы, общая схема по возможности). Отдельные «форма создания» и «форма редактирования» как копии друг друга не допускаются. +- Если поведение полей отличается между режимами создания и редактирования, различия задаются условно: условный рендеринг блоков полей, условная обязательность и правила в схеме валидации, различие дефолтов и `defaultValues`, флаги режима (`mode`, `isEdit` и т.п.) — без дублирования разметки и правил там, где достаточно параметризации. + +## UI и стили + +- **Единый источник** визуальных примитивов и отступов — **существующие общие компоненты и соглашения этого репозитория** (не внешняя «дизайн-система из правил»). Перед добавлением нового примитива ищи аналог в кодовой базе; дубли без причины не вводятся. +- Новый UI создаётся по **канону репозитория** (например CSS Modules или другой зафиксированный способ). +- Токены темы хранятся в согласованном месте проекта (если принято). +- Устаревший подход стилизации допускается только в наследуемых зонах; новые экраны на нем не строятся без решения команды. + +## Модальные окна и подтверждения действий + +- Любые модальные окна и запросы подтверждения в **renderer** реализуются **только** через **внутренние** компоненты приложения и паттерны **этого** репозитория (не нативные блокирующие диалоги ОС в зоне UI продукта). +- Использование **`alert` / `confirm` / `prompt`** в новом и изменяемом коде **renderer** запрещено (исключения — только явно зафиксированные в самом репозитории, например отдельный отладочный путь). +- **Продукт DNDGamePlayer** (`dnd_player`): после внедрения i18n (план: **ru**, **en**) подписи модалок и UI — через **ключи**; до внедрения — литералы в стиле репо. +- Повторяющаяся разметка и логика модалок выносится в переиспользуемые обёртки/конфиги, а не копируется между фичами. + +## Переиспользование кода и дублирование + +- Новый код проектируется с максимальным переиспользованием: общие компоненты, хуки, утилиты, схемы валидации и типы — единственный источник правды для повторяющегося поведения. +- Необоснованное дублирование блоков UI и бизнес-логики в новом коде не допускается: при появлении второго такого же фрагмента выносится общий модуль; при правках смежных дублей по возможности консолидируют реализацию. +- Наследуемый дублирующийся код при точечных задачах не обязан переписываться целиком, но расширять дубли вместо выноса общего решения не следует без явной причины (объём/риск миграции фиксируется в задаче или ревью). + +## TypeScript и качество + +- В репозиториях на TypeScript обязателен **`strict`**; новые `any` и `@ts-ignore` не добавляются. +- Ослабления возможны только точечно, с комментарием причины и ссылкой на задачу. +- Границы модулей (роутинг, внешние библиотеки) типизируются осмысленно. +- Практика «везде any» как норма запрещена. + +## Локализация (только **`dnd_player`**) и комментарии + +- **Продукт DNDGamePlayer** (`dnd_player`): планируется отдельная задача на **мультиязычность** — языки **русский (ru)** и **английский (en)**. После внедрения i18n пользовательские строки интерфейса выносятся в **ключи**; префиксы и соглашения по ключам — единые для приложения; новые строки без ключей не добавляются. До внедрения стека i18n действуют литералы в текущем стиле репозитория. +- **Вне `dnd_player`:** отдельных требований к i18n нет; строки — в принятом для репозитория виде. +- Над нетривиальными функциями, эффектами и публичными сущностями добавляется краткий смысловой комментарий там, где это принято в репозитории. +- Стиль комментариев и кодировка файлов соответствуют стандарту репозитория (UTF-8, читаемый язык команды). + +## Инженерная дисциплина + +- Изменения должны быть минимальными и сфокусированными (`minimal diff`). +- Предсказуемость решения приоритетнее «хитрости». +- Изменения контрактов модульной федерации и shared-зависимостей проходят с повышенным вниманием на ревью. +- Линтер, форматтер, pre-commit и политика компилятора (включая React Compiler, если включен) соблюдаются как в репозитории; если скрипта ещё нет — не ослаблять дисциплину «отмазкой репозитория», а фиксировать проверки в задаче (**одинаковая жёсткость** ожиданий по всем проектам воркспейса). +- Запрещено ослаблять правила только ради быстрого прохождения проверок. diff --git a/.cursor/rules/pipeline-execution-template.mdc b/.cursor/rules/pipeline-execution-template.mdc new file mode 100644 index 0000000..226c0c2 --- /dev/null +++ b/.cursor/rules/pipeline-execution-template.mdc @@ -0,0 +1,28 @@ +--- +description: Единый короткий шаблон отчета для этапов пайплайна +alwaysApply: true +--- + +# Шаблон отчета по этапу пайплайна + +Использовать этот формат на каждом этапе: + +1. Фронтэнд разработчик +2. Разработчик UI-автотестов +3. Ревьювер кода +4. UI-тестировщик + +## Формат + +- Этап: `<название роли>` +- Статус: `пройдено | пройдено с замечаниями | не пройдено` +- Что проверено: `<3-6 кратких пунктов>` +- Найдено: `<нет | список замечаний/дефектов>` +- Решение по этапу: `<передать дальше | вернуть на этап 1>` +- Следующее действие: `<кто и что делает дальше>` + +## Правила заполнения + +- Формулировки краткие и проверяемые. +- Для замечаний указывать критичность: `блокирующий | важный | минорный`. +- Если этап не пройден, обязательно указывать условие повторной проверки. diff --git a/.cursor/rules/project.mdc b/.cursor/rules/project.mdc index 97aa829..b3838e6 100644 --- a/.cursor/rules/project.mdc +++ b/.cursor/rules/project.mdc @@ -3,38 +3,72 @@ description: Workspace-wide workflow and conventions (dnd_project) alwaysApply: true --- -# DNDGamePlayer / `dnd_project` — правила работы над задачами (future-pipeline) +# DNDGamePlayer / `dnd_project` — правила работы над задачами -**Перед первой задачей в сессии по коду, архитектуре или продукту** открой и учти **`AGENTS.md`** в корне репозитория **`cursorAi`** — там обязательный обзор экосистемы и карта репозиториев. Детали путей и сборки: **`WORKSPACE.md`**. +**Перед первой задачей в сессии по коду, архитектуре или продукту** открой и учти **`AGENTS.md`** в корне репозитория **`cursorAi`** — там обзор экосистемы и карта репозиториев. Детали путей и сборки: **`WORKSPACE.md`**. -Эти правила применяются **только** когда запрос пользователя требует **изменений в репозитории** (код/конфиги/тесты). Для чисто текстовых задач (описания, маркетинг, переписка) 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). +- **`frontend-agent-core.mdc`**, **`frontend-development-standards.mdc`** — стиль кода, UI, формы, модалки, TS, комментарии; **i18n — только в `dnd_player`** (планируются языки **ru** и **en** — см. `frontend-development-standards.mdc`). +- **`agent-core-contracts-and-quality.mdc`**, **`agent-test-gates-mandatory.mdc`** — контракты, тестовые гейты, верификация. -### 3) Tests -- Обновить/добавить тест(ы), если поведение изменилось или был баг. -- Для мелких правок допускается «облегчённый режим» без под-агентов, но тесты всё равно должны проходить там, где они есть. +## Пайплайн (кодовые репозитории) -### 4) Verify (всегда, перед ответом — для **`dnd_player`**) +Порядок этапов: **`agents-pipeline-order.mdc`**. Отчёт по этапу: **`pipeline-execution-template.mdc`**. Чек-листы: **`agent-1-frontend-developer.mdc`** … **`agent-3-ui-tester.mdc`**. Под-агенты: **`.cursor/skills/feature-pipeline/SKILL.md`**. -Из каталога **`dnd_player/`** (или через хук из корня воркспейса, см. `.cursor/hooks/final-verify.cjs`): +**Не входит в обязательный пайплайн:** репозиторий **`cursorAi`** (только `.md` / `.mdc` правил и описаний). Для таких правок полный цикл из четырёх этапов **не требуется**; хук **`stop`**: **`verify_repo`: `none`**. -- `npm run lint` -- `npm run typecheck` -- `npm run test` +Последовательность для **`dnd_player`**, **`project-converter`**, **`DndGamePlayerLicenseServer`**: -Если задача касалась **только** `project-converter` или **DndGamePlayerLicenseServer** — выполни адекватную проверку для этого репозитория (`node --check`, локальный прогон) и явно укажи в ответе, что полный набор команд плеера не запускался (если он не нужен по смыслу). +1. Реализация (minimal diff, паттерны **целевого** репозитория). +2. Автотесты на изменённое поведение (стек репозитория). +3. Ревью кода. +4. Верификация: UI (Electron/браузер) или HTTP-сценарии для сервера. + +### `.cursor/pipeline-state.json` + +Обязательные ключи: `frontend_development`, `ui_autotests`, `code_review`, `ui_browser_verification` — все **`"done"`** перед успешным хуком (кроме режима **`verify_repo`: `none`**). + +Поле **`verify_repo`** (цель хука **`stop`** и автоматической verify): + +| Значение | Когда ставить | Что делает хук `final-verify.cjs` | +|----------|----------------|-----------------------------------| +| **`dnd_player`** | Задача по плееру (по умолчанию) | `npm run lint`, `typecheck`, `test` в **`dnd_player/`** | +| **`project-converter`** | Задача по конвертеру | `npm run lint`, `node --check` по `src/`, обязательный **`npm run test`** (скрипт и тесты — по политике A в том же PR, что и правки поведения) | +| **`DndGamePlayerLicenseServer`** | Задача по серверу лицензий | `node --check` по `src/`, `lib/`, обязательный **`npm run test`** | +| **`none`** | Только правки в **`cursorAi`** | Сразу **exit 0**, четыре ключа пайплайна **не проверяются** | + +Переопределение без правки файла: переменная окружения **`VERIFY_REPO`** (те же значения). Корни соседних репо: родитель каталога `cursorAi` (см. **`WORKSPACE.md`**); для плеера дополнительно **`DND_PLAYER_ROOT`**; для всех соседей — **`DND_PROJECT_ROOT`** (абсолютный путь к папке `dnd_project`). + +## Verify перед ответом (по репозиторию задачи) + +Перед ответом пользователю все проверки **целевого** репозитория должны быть **зелёными**; не подменять verify другим репо. + +### Политика тестов **вариант A** (`project-converter`, `DndGamePlayerLicenseServer`) + +Любая задача, которая **меняет поведение** этих репозиториев, в **том же PR** обязана: добавить или расширить **`npm test`** в **`package.json`**, добавить автотесты на затронутое поведение и довести **`npm run test`** до green. Откладывать появление скрипта `test` или тестов «отдельным эпиком» после merge **нельзя**. Исключение только при объективной блокировке (тогда — запись в задаче, риск, согласование с владельцем процесса), а не «пока не дошли руки». + +### `dnd_player` + +`npm run lint`, `npm run typecheck`, `npm run test` из корня репозитория. + +### `project-converter` + +`npm run lint`, **`node --check`** по entrypoints в `src/`, **`npm run test`** (обязателен — политика **вариант A**). Реальные lint/typecheck — по мере появления скриптов; до этого не ослаблять требование **тестов в том же PR**, что и изменение поведения. + +### `DndGamePlayerLicenseServer` + +**`node --check`** по модулям, **`npm run test`** (обязателен — политика **вариант A**). Скрипт `start` для ручного запуска сервера не заменяет автотесты. + +### `cursorAi` + +Обязательный 4-этапный пайплайн **не применяется**. Согласованность ссылок и имён файлов — по усмотрению задачи; для хука **`stop`** выставь **`verify_repo`: `none`**. Если что-то упало — исправить и повторить до green. diff --git a/.cursor/skills/feature-pipeline/SKILL.md b/.cursor/skills/feature-pipeline/SKILL.md index 1cb9465..92e0772 100644 --- a/.cursor/skills/feature-pipeline/SKILL.md +++ b/.cursor/skills/feature-pipeline/SKILL.md @@ -1,83 +1,97 @@ --- name: feature-pipeline -description: Implementation → Review → Tests → Verify +description: Dev → autotests → code review → scenario verify → repo verify (все кодовые репо) --- # Workflow -Контекст воркспейса: **`AGENTS.md`** (обзор продукта), затем **`WORKSPACE.md`** (пути, сборка, junction). Основной код плеера — репозиторий **`dnd_player/`** (рядом с корнем воркспейса `cursorAi`). +Контекст: **`AGENTS.md`**, **`WORKSPACE.md`**. Целевой репозиторий задачи: **`dnd_player/`**, **`project-converter/`** или **`DndGamePlayerLicenseServer/`**. В **`pipeline-state.json`** задай **`verify_repo`** под хук **`stop`** (см. **`project.mdc`**); для правок только в **`cursorAi`** — **`verify_repo`: `none`** (пайплайн 4 этапов не обязателен). -## Stage 1 — Implementation +Порядок этапов: **`agents-pipeline-order.mdc`**, отчёт: **`pipeline-execution-template.mdc`**, чек-листы: **`.cursor/rules/agent-*.mdc`**. -Используй subagent: frontend-senior +## Stage 1 — Разработчик -- реализуй задачу -- сделай minimal diff +Subagent: **frontend-developer** (`.cursor/agents/frontend-developer.md`) -Обнови state: +- реализация, **minimal diff**, паттерны **целевого** репозитория; +- **i18n** — только при работе в **`dnd_player`**; после внедрения — **ru**/**en** (см. `frontend-development-standards.mdc`). +```json { - "implementation": "done" + "frontend_development": "done", + "ui_autotests": "pending", + "code_review": "pending", + "ui_browser_verification": "pending" } +``` --- -## Stage 2 — Review +## Stage 2 — Автотесты -Используй subagent: reviewer +Subagent: **ui-test-developer** (`.cursor/agents/ui-test-developer.md`) -- проверь изменения -- найди проблемы -- исправь минимально - -Обнови state: +- тесты под изменённое поведение, стек **этого** репозитория (`dnd_player`: `npm run test`; остальные — по `package.json` или добавить в задаче). +```json { - "implementation": "done", - "review": "done" + "frontend_development": "done", + "ui_autotests": "done", + "code_review": "pending", + "ui_browser_verification": "pending" } +``` --- -## Stage 3 — Tests +## Stage 3 — Ревью кода -Используй subagent: unit-tests - -- добавь/обнови tests -- добейся green status - -Обнови state: +Subagent: **code-reviewer** (`.cursor/agents/code-reviewer.md`) +```json { - "implementation": "done", - "review": "done", - "tests": "done" + "frontend_development": "done", + "ui_autotests": "done", + "code_review": "done", + "ui_browser_verification": "pending" } +``` --- -## Stage 4 — Verify +## Stage 4 — Верификация сценариев -Выполни из каталога **`dnd_player/`** (см. также хук `.cursor/hooks/final-verify.cjs`): +Subagent: **ui-tester** (`.cursor/agents/ui-tester.md`) -- `npm run lint` -- `npm run typecheck` -- `npm run test` +- **`dnd_player`**, **`project-converter`**: Electron / браузер по сценарию; +- **`DndGamePlayerLicenseServer`**: HTTP-сценарии к запущенному сервису; +- отчёт: **`pipeline-execution-template.mdc`**. -Если ошибка: +```json +{ + "frontend_development": "done", + "ui_autotests": "done", + "code_review": "done", + "ui_browser_verification": "done" +} +``` -- исправь -- повтори +--- + +## Stage 5 — Verify (команды целевого репо) + +Выполни **все** проверки из **`package.json`** репозитория задачи до **green**. Для **`dnd_player`** после четырёх `"done"` в `pipeline-state.json` хук **`stop`** запускает `lint` / `typecheck` / `test`. Для **`project-converter`** и **`DndGamePlayerLicenseServer`** — в том числе обязательный **`npm run test`** (**вариант A**: тесты и скрипт `test` в том же PR, что и изменение поведения). Не подменять verify другим репозиторием. --- ## Final Output -- implementation summary -- review summary -- test summary -- verification status +- implementation summary +- autotests summary +- code review summary +- scenario verification (UI или API) +- verify status по **целевому** репо -## PR-чеклисты (приёмка по задаче) +## PR-чеклисты -Готовые чеклисты с критериями по стадиям лежат в `.cursor/pr-checklists/`. Для UI-выравнивания под макеты: `ui-mock-alignment.md`. Пути к файлам в чеклистах — относительно **`dnd_player/`**. +`.cursor/pr-checklists/`; пути в `ui-mock-alignment.md` — относительно **`dnd_player/`**. diff --git a/AGENTS.md b/AGENTS.md index 0186250..1cc1d6d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -31,15 +31,15 @@ - **Конвертер проектов** → **`project-converter`**: `npm run dev` и т.д. (отдельного production `build` в `package.json` может не быть). - **Лицензии** → **`DndGamePlayerLicenseServer`**: `npm start`, переменные окружения см. README там и в клиенте. -Хук Cursor **`stop`** (`.cursor/hooks/final-verify.cjs`) при полном пайплайне гоняет **lint / typecheck / test** в каталоге **`dnd_player`** (поиск корня: `DND_PLAYER_ROOT` или соседний `../dnd_player`). +Хук Cursor **`stop`** (`.cursor/hooks/final-verify.cjs`) после четырёх этапов в **`pipeline-state.json`** гоняет **lint / typecheck / test** в каталоге **`dnd_player`** (поиск корня: `DND_PLAYER_ROOT` или соседний `../dnd_player`). --- ## Как мы работаем (кратко) -1. **Правила по умолчанию:** `.cursor/rules/project.mdc` (**alwaysApply**) — future-pipeline: implementation → review → tests → verify для изменений в коде. +1. **Правила по умолчанию:** `.cursor/rules/project.mdc` (**alwaysApply**) — пайплайн и verify для изменений в коде; детали этапов: `agents-pipeline-order.mdc`, стандарты в `frontend-*.mdc` и `agent-*.mdc`. 2. **Сценарий по шагам:** `.cursor/skills/feature-pipeline/SKILL.md`. -3. **Под-агенты:** `.cursor/agents/` (`frontend-senior`, `reviewer`, `unit-tests`). +3. **Под-агенты:** `.cursor/agents/` (`frontend-developer`, `ui-test-developer`, `code-reviewer`, `ui-tester`). 4. **Чеклисты под тип задач:** `.cursor/pr-checklists/` (пути к файлам кода — от **`dnd_player/`**). Подробности путей на диске, сборки и junction: **`WORKSPACE.md`**. @@ -48,7 +48,7 @@ ## Что не путать -- **`cursorAi`** — не приложение; это **точка сборки правил и документации** для всей «песочницы» репозиториев. +- **`cursorAi`** — не приложение; это **точка сборки правил и документации** для всей «песочницы» репозиториев. Обязательный 4-этапный пайплайн к нему **не применяется**; для хука **`stop`** при работе только здесь — **`verify_repo`: `none`**. - **`project-converter`** — не часть `npm run build` основного плеера; отдельный продукт/утилита. - Контракт **лицензии**: публичный ключ в клиенте и приватный/сервер в **`DndGamePlayerLicenseServer`** должны соответствовать друг другу (см. README сервера). @@ -57,6 +57,6 @@ ## Итог для новой сессии 1. Прочитай **`AGENTS.md`** (этот файл) и при необходимости **`WORKSPACE.md`**. -2. Определи, в каком из четырёх репозиториев живёт задача. -3. Для **`dnd_player`** после существенных правок прогоняй **lint, typecheck, test** (и учитывай хук **`stop`**). +2. Определи, в каком из репозиториев живёт задача (**`dnd_player`**, **`project-converter`**, **`DndGamePlayerLicenseServer`**, **`cursorAi`**). +3. Для кода приложений: полный пайплайн и хук **`stop`**; в **`pipeline-state.json`** выставь **`verify_repo`** на целевой репо (**`none`** — только правки в **`cursorAi`**, тогда хук не гоняет `npm` в других репо). Для **`dnd_player`** — также **lint, typecheck, test**; планируется i18n **ru**/**en** (отдельная задача). 4. Соблюдай **минимальный diff** и существующие паттерны репозитория. diff --git a/WORKSPACE.md b/WORKSPACE.md index 6ab438d..26a7e45 100644 --- a/WORKSPACE.md +++ b/WORKSPACE.md @@ -24,21 +24,21 @@ ## Сборка и проверки - **`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/`. +- **`project-converter`**: отдельного `build` нет; `npm install`, `npm run dev`. Синтаксис: `node --check` по файлам в `src/`. **`npm run test`** — обязателен после появления скрипта `test` (**вариант A**, см. **`project.mdc`**). +- **`DndGamePlayerLicenseServer`**: `npm start` (или `node src/server.mjs`); `node --check` для `src/` и `lib/`. **`npm run test`** — обязателен после появления скрипта `test` (**вариант A**). -Хук **`stop`** в Cursor (см. `.cursor/hooks.json`) запускает финальную проверку: стадии в `.cursor/pipeline-state.json` и команды **`lint` / `typecheck` / `test`** выполняются в каталоге **`dnd_player`**, если воркспейс открыт из `cursorAi` (см. логику в `.cursor/hooks/final-verify.cjs`). Переопределение пути: переменная окружения **`DND_PLAYER_ROOT`**. +Хук **`stop`** (`.cursor/hooks/final-verify.cjs`): читает **`.cursor/pipeline-state.json`**. Если **`verify_repo`** = **`none`** (правки только в **`cursorAi`**), хук **сразу** завершается успехом. Иначе при четырёх **`done`** пайплайна запускает проверки **целевого** репо: **`dnd_player`** — `lint` / `typecheck` / `test`; **`project-converter`** — `npm run lint`, `node --check` по `src/`, обязательный **`npm run test`** (скрипт `test` должен быть в `package.json`); **`DndGamePlayerLicenseServer`** — `node --check` по `src/` и `lib/`, обязательный **`npm run test`**. Переопределение репо для хука: **`VERIFY_REPO`**; корень соседних репозиториев: **`DND_PROJECT_ROOT`**; для плеера: **`DND_PLAYER_ROOT`**. --- ## Пайплайн и правила -- Правила агента по умолчанию: **`.cursor/rules/project.mdc`** (future-pipeline: implementation → review → tests → verify). +- Правила агента по умолчанию: **`.cursor/rules/project.mdc`**, порядок этапов: **`agents-pipeline-order.mdc`**, стандарты: **`frontend-agent-core.mdc`**, **`frontend-development-standards.mdc`**, гейты: **`agent-test-gates-mandatory.mdc`**. - Пошаговый сценарий с под-агентами: **`.cursor/skills/feature-pipeline/SKILL.md`**. -- Под-агенты: **`.cursor/agents/`** (`frontend-senior`, `reviewer`, `unit-tests`). +- Под-агенты: **`.cursor/agents/`** (`frontend-developer`, `ui-test-developer`, `code-reviewer`, `ui-tester`). - PR-чеклисты: **`.cursor/pr-checklists/`** (пути к файлам в чеклистах заданы относительно репозитория **`dnd_player/`**). -При работе **только** в `project-converter` или `DndGamePlayerLicenseServer` соблюдай смысл пайплайна (минимальный diff, тесты по возможности), а формальные команды `npm run lint` и т.д. из плеера запускай, когда менялся общий контракт или есть смысл прогнать регрессию всего монорепо по смыслу (или по требованию задачи). +Для **`project-converter`** и **`DndGamePlayerLicenseServer`** действуют те же требования пайплайна и гейтов, что и для **`dnd_player`** (см. **`project.mdc`**, **`agents-pipeline-order.mdc`**). **Политика тестов — вариант A:** любое изменение поведения в **том же PR** добавляет/обновляет **`npm test`** и сами тесты; откладывать на отдельный эпик нельзя. Запуск проверок из **`dnd_player`** при задаче только в другом репо **не заменяет** verify целевого репозитория. ---