diff --git a/.cursor/rules/engineering.mdc b/.cursor/rules/engineering.mdc index 68100ec..a365508 100644 --- a/.cursor/rules/engineering.mdc +++ b/.cursor/rules/engineering.mdc @@ -123,8 +123,8 @@ alwaysApply: true **TEST-03** | MUST | Новые BIRD-сценарии в `internal/birdfmt/testdata/scenarios/*/bird.conf` + `bird -p`. *Проверка:* CI job `bird2`. -**TEST-04** | MUST | Изменения `web/` — локально `npm run check` и `npm run lint`; CI job `web` в `.gitea/workflows/ci.yaml`. -*Проверка:* локальные команды. +**TEST-04** | MUST | Изменения `web/` — локально **`npm run check` и `npm run lint`** (обе команды, exit 0); CI job `web` в `.gitea/workflows/ci.yaml`. Агент: при fail lint — `npx prettier --write` затем повтор. Только `check` не заменяет `lint`. +*Проверка:* CI job `web`; `.cursor/rules/web-shadcn.mdc` WEB-19. **TEST-05** | MUST | Изменения OpenAPI — `npx @redocly/cli lint docs/openapi.yaml`. *Проверка:* CI job `openapi`. diff --git a/.cursor/rules/web-shadcn.mdc b/.cursor/rules/web-shadcn.mdc index bdab97c..f8c7ddb 100644 --- a/.cursor/rules/web-shadcn.mdc +++ b/.cursor/rules/web-shadcn.mdc @@ -73,6 +73,15 @@ alwaysApply: false **WEB-15** | MUST | Сомнения — https://shadcn-svelte.com/llms.txt , Svelte MCP, `npm run check`. *Проверка:* локально. +**WEB-19** | MUST | **После любого изменения `web/**`** — перед завершением задачи агент **обязан** выполнить в `web/`: +```powershell +npm run check +npm run lint +``` +Если `npm run lint` падает (Prettier) — **сначала** `npx prettier --write <изменённые файлы>` или `npx prettier --write .`, затем снова `npm run check` и `npm run lint`. Не сдавать PR/ответ, пока обе команды не exit 0. +*Rationale:* CI job `web` = `check` + `prettier --check`; `svelte-check` не ловит форматирование. +*Проверка:* CI job `web`; pre-commit hook `prettier-web`. + **WEB-16** | MUST | Подтверждение удаления — `ConfirmDialog` из patterns, не `window.confirm`. *Проверка:* review. @@ -95,15 +104,23 @@ Tailwind v4: https://shadcn-svelte.com/docs/migration/tailwind-v4 ## Enforcement +**Обязательный финальный шаг агента при правках `web/**`:** `npm run check` **и** `npm run lint` (см. **WEB-19**). Только `check` недостаточно. + ```powershell cd web npm run check npm run lint +# при warn/fail lint: +npx prettier --write . +npm run check +npm run lint ``` **PR checklist `web/**`:** +- [ ] `npm run check` — exit 0 +- [ ] `npm run lint` (prettier --check) — exit 0 - [ ] `ui/core` / `ui/patterns`, не дубли примитивов - [ ] Новые примитивы через shadcn CLI - [ ] Ссылка на docs компонента (если новый паттерн) -**CI:** job `web` рекомендован; пока обязательно локально. +**CI:** job `web` — `npm run check` + `npm run lint`. diff --git a/AGENTS.md b/AGENTS.md index 7412b9f..afee1dd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -58,4 +58,12 @@ ## Svelte / фронтенд -При правках `web/**/*.svelte` или Svelte-модулей следуйте навыкам/инструментам проекта (официальный Svelte MCP и скиллы Cursor, если подключены). +При правках `web/**/*.svelte` или Svelte-модулей следуйте [.cursor/rules/web-shadcn.mdc](.cursor/rules/web-shadcn.mdc) (**WEB-19**): перед завершением задачи **обязательно**: + +```powershell +cd web +npm run check +npm run lint +``` + +Если `lint` падает — `npx prettier --write .` и повторить обе команды. CI job `web` не пропускает без этого. diff --git a/scripts/lint-web.ps1 b/scripts/lint-web.ps1 new file mode 100644 index 0000000..775d51e --- /dev/null +++ b/scripts/lint-web.ps1 @@ -0,0 +1,5 @@ +# Same gates as CI job web (.gitea/workflows/ci.yaml). +$ErrorActionPreference = 'Stop' +Set-Location (Join-Path $PSScriptRoot '..' 'web') +npm run check +npm run lint diff --git a/scripts/lint-web.sh b/scripts/lint-web.sh new file mode 100644 index 0000000..9f64451 --- /dev/null +++ b/scripts/lint-web.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# Same gates as CI job web (.gitea/workflows/ci.yaml). +set -euxo pipefail +cd "$(dirname "$0")/../web" +npm run check +npm run lint diff --git a/web/README.md b/web/README.md index 306da05..cccd220 100644 --- a/web/README.md +++ b/web/README.md @@ -21,8 +21,21 @@ SvelteKit-приложение панели управления EvoBGP. Зап npm install npm run dev npm run check +npm run lint # prettier --check; обязательно перед PR (CI job web) ``` +Из корня репозитория (обе проверки как в CI): + +```powershell +powershell -NoProfile -File scripts/lint-web.ps1 +``` + +```sh +sh scripts/lint-web.sh +``` + +При падении `lint`: `npx prettier --write .` в каталоге `web/`, затем снова `check` + `lint`. + Добавление компонентов shadcn (из каталога `web/`): ```sh diff --git a/web/src/lib/components/network/NetworkSpeakersCard.svelte b/web/src/lib/components/network/NetworkSpeakersCard.svelte index 590cead..41ee610 100644 --- a/web/src/lib/components/network/NetworkSpeakersCard.svelte +++ b/web/src/lib/components/network/NetworkSpeakersCard.svelte @@ -125,7 +125,9 @@ agent_domain: s.agent_domain ?? '', node_ipv4: s.node_ipv4 ?? '', bird_bgp_source_ipv4: s.bird_bgp_source_ipv4 ?? s.node_ipv4 ?? '', - bgpSourceManual: Boolean(s.bird_bgp_source_ipv4 && s.node_ipv4 && s.bird_bgp_source_ipv4 !== s.node_ipv4) + bgpSourceManual: Boolean( + s.bird_bgp_source_ipv4 && s.node_ipv4 && s.bird_bgp_source_ipv4 !== s.node_ipv4 + ) }; } @@ -139,8 +141,7 @@ function buildApiBody(f: SpeakerForm): BgpSpeakerCreate { const ep = - f.endpoint.trim() || - (f.agent_domain.trim() ? `https://${f.agent_domain.trim()}` : ''); + f.endpoint.trim() || (f.agent_domain.trim() ? `https://${f.agent_domain.trim()}` : ''); return { endpoint: ep, role: f.role.trim() || 'replica', @@ -294,7 +295,9 @@ CF_DNS_API_TOKEN= >
Спикеры - Удалённые BIRD-ноды (Remnawave-style Panel→Node + signed bundle) + Удалённые BIRD-ноды (Remnawave-style Panel→Node + signed bundle)
@@ -352,11 +355,7 @@ CF_DNS_API_TOKEN=
- + {#if createdSpeaker?.agent_secret}
- +
@@ -449,7 +453,9 @@ CF_DNS_API_TOKEN= Copy docker-compose - Спикер {composeTarget?.agent_domain ?? composeTarget?.id} + Спикер {composeTarget?.agent_domain ?? composeTarget?.id}