chore: cursor agents, rules, hooks and workspace docs
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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`.
|
||||
@@ -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"`.
|
||||
@@ -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:
|
||||
|
||||
- список изменённых файлов
|
||||
- краткое описание изменений
|
||||
@@ -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
|
||||
@@ -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`.
|
||||
@@ -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-верификации сервера — то же имя ключа: сценарная проверка завершена).
|
||||
@@ -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 -- <file>`
|
||||
- затем при необходимости весь suite
|
||||
|
||||
Output:
|
||||
|
||||
- какие тесты добавлены
|
||||
- что они проверяют
|
||||
+167
-58
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -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).
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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`) есть проверки там, где они затронуты.
|
||||
|
||||
Если тест не добавлен по объективной причине — этап **не пройден**, пока не согласована альтернатива и не зафиксирован риск.
|
||||
@@ -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 и повтор пайплайна по порядку.
|
||||
@@ -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) Запрет бездумного переноса паттернов
|
||||
|
||||
- Перенос примера/паттерна из другого места допустим только после проверки совместимости:
|
||||
- контракты,
|
||||
- ожидания типов,
|
||||
- окружение/инициализации,
|
||||
- интеграционный сценарий.
|
||||
@@ -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 и результат.
|
||||
@@ -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`**.
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
description: Базовые стандарты для агентной frontend-разработки
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Базовые правила frontend-агента
|
||||
|
||||
## Миссия
|
||||
|
||||
Создавать поддерживаемые frontend-функции с предсказуемым поведением, явными предположениями и проверяемым результатом.
|
||||
|
||||
## Рабочий процесс
|
||||
|
||||
- Начинай с уточнения цели, ограничений и ожидаемого влияния на UX.
|
||||
- Предпочитай небольшие инкрементальные изменения вместо широких переписываний.
|
||||
- Сохраняй действующие конвенции проекта, если нет явной причины их менять.
|
||||
- После существенных правок выполняй релевантные проверки и фиксируй результаты.
|
||||
|
||||
## Качество кода
|
||||
|
||||
- Ставь читаемость и явные имена выше «умных» сокращений.
|
||||
- Держи компоненты сфокусированными: одна четкая ответственность на компонент/модуль.
|
||||
- Выноси повторяющуюся логику в хуки или утилиты, когда появляется дублирование; не размножай копии форм и модалок, если достаточно одной параметризованной реализации.
|
||||
- Не добавляй мертвый код, неиспользуемые экспорты и закомментированные блоки.
|
||||
|
||||
## Надежность и совместимость
|
||||
|
||||
- Не ломай публичные API компонентов без документирования шагов миграции.
|
||||
- Сохраняй базовую доступность (labels, клавиатурная навигация, семантические элементы).
|
||||
- Обрабатывай состояния загрузки, пустого результата и ошибок в асинхронных UI-путях; подтверждения и модалки — через UI приложения, не через нативные диалоги браузера (в Electron renderer — аналогично: внутренние модалки приложения).
|
||||
- Добавляй или обновляй тесты при изменении поведения критичных пользовательских сценариев.
|
||||
|
||||
## Взаимодействие с агентом
|
||||
|
||||
- Явно указывай, что изменено, зачем это изменено и как это проверить.
|
||||
- Прямо фиксируй риски и компромиссы при нетривиальных решениях.
|
||||
- Если требования неоднозначны, остановись и уточни перед реализацией предположений.
|
||||
@@ -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, если включен) соблюдаются как в репозитории; если скрипта ещё нет — не ослаблять дисциплину «отмазкой репозитория», а фиксировать проверки в задаче (**одинаковая жёсткость** ожиданий по всем проектам воркспейса).
|
||||
- Запрещено ослаблять правила только ради быстрого прохождения проверок.
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
description: Единый короткий шаблон отчета для этапов пайплайна
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Шаблон отчета по этапу пайплайна
|
||||
|
||||
Использовать этот формат на каждом этапе:
|
||||
|
||||
1. Фронтэнд разработчик
|
||||
2. Разработчик UI-автотестов
|
||||
3. Ревьювер кода
|
||||
4. UI-тестировщик
|
||||
|
||||
## Формат
|
||||
|
||||
- Этап: `<название роли>`
|
||||
- Статус: `пройдено | пройдено с замечаниями | не пройдено`
|
||||
- Что проверено: `<3-6 кратких пунктов>`
|
||||
- Найдено: `<нет | список замечаний/дефектов>`
|
||||
- Решение по этапу: `<передать дальше | вернуть на этап 1>`
|
||||
- Следующее действие: `<кто и что делает дальше>`
|
||||
|
||||
## Правила заполнения
|
||||
|
||||
- Формулировки краткие и проверяемые.
|
||||
- Для замечаний указывать критичность: `блокирующий | важный | минорный`.
|
||||
- Если этап не пройден, обязательно указывать условие повторной проверки.
|
||||
+54
-20
@@ -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.
|
||||
|
||||
|
||||
@@ -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/`**.
|
||||
|
||||
@@ -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** и существующие паттерны репозитория.
|
||||
|
||||
+6
-6
@@ -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 целевого репозитория.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user