@nitra/cursor 1.13.74 → 1.13.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/package.json +2 -1
- package/scripts/auto-skills.mjs +1 -1
- package/skills/start-check/SKILL.md +100 -0
- package/skills/start-check/auto.md +1 -0
- package/skills/abie-clean/SKILL.md +0 -216
- package/skills/abie-clean/auto.md +0 -1
- package/skills/abie-kustomize/SKILL.md +0 -75
- package/skills/abie-kustomize/auto.md +0 -1
- package/skills/efes-create-env/SKILL.md +0 -185
- package/skills/efes-create-env/auto.md +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
Формат — [Keep a Changelog](https://keepachangelog.com/uk/1.1.0/), нумерація — [SemVer](https://semver.org/lang/uk/).
|
|
6
6
|
|
|
7
|
+
## [1.13.75] - 2026-05-22
|
|
8
|
+
|
|
9
|
+
### Removed
|
|
10
|
+
|
|
11
|
+
- **Скіли `abie-clean` та `abie-kustomize`** прибрано з пакета — abie-специфічні скіли перенесено до `@nitra/abie-docs` і перейменовано на `clean` / `kustomize` (запуск через `npx @nitra/abie-docs skill <id>`). Автоактивація цих скілів за правилом `abie` більше не діє. Зачеплено: [auto-skills.mjs](scripts/auto-skills.mjs), [auto-skills.test.mjs](scripts/auto-skills.test.mjs), `skills/abie-clean/`, `skills/abie-kustomize/`.
|
|
12
|
+
- **Скіл `efes-create-env`** прибрано з пакета — efes-специфічний скіл перенесено до `@nitra/efes-docs` і перейменовано на `create-env` (запуск через `npx @nitra/efes-docs skill create-env`). Автоактивація за правилом `efes` більше не діє. Зачеплено: [auto-skills.test.mjs](scripts/auto-skills.test.mjs), `skills/efes-create-env/`.
|
|
13
|
+
|
|
7
14
|
## [1.13.73] - 2026-05-21
|
|
8
15
|
|
|
9
16
|
### Fixed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nitra/cursor",
|
|
3
|
-
"version": "1.13.
|
|
3
|
+
"version": "1.13.75",
|
|
4
4
|
"description": "CLI для завантаження cursor-правил (префікс n-) у локальний репозиторій",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"types": "./types/bin/n-cursor.d.ts",
|
|
44
44
|
"scripts": {
|
|
45
45
|
"test": "bun test",
|
|
46
|
+
"start": "bun ./bin/n-cursor.js",
|
|
46
47
|
"rename-yaml-extensions": "bun ./bin/n-cursor.js rename-yaml-extensions"
|
|
47
48
|
},
|
|
48
49
|
"dependencies": {
|
package/scripts/auto-skills.mjs
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - `завжди` — скіл активується незалежно від інших правил
|
|
7
7
|
* (приклади: `fix`, `lint`, `llm-patch`, `publish-telegram`).
|
|
8
8
|
* - `[rule, rule, …]` — скіл активується, якщо ВСІ перелічені правила вже виявлені
|
|
9
|
-
* auto-rules (приклади: `
|
|
9
|
+
* auto-rules (приклади: `adr-normalize - [adr]`, `taze - [bun]`).
|
|
10
10
|
* - файл відсутній або формат не розпізнано — скіл opt-in лише через `.n-cursor.json:skills`.
|
|
11
11
|
*
|
|
12
12
|
* Сканування `npm/skills/` — sync під час завантаження модуля (детермінізм + sync API
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: n-start-check
|
|
3
|
+
description: >-
|
|
4
|
+
Smoke-перевірка bun-монорепо: зайти в кожен воркспейс зі `start`-скриптом, прогнати
|
|
5
|
+
`start` і зафіксувати, чи проєкт взагалі запускається без негайного краху
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# n-start-check — чи запускається кожен воркспейс
|
|
9
|
+
|
|
10
|
+
## Мета
|
|
11
|
+
|
|
12
|
+
Прогнати `start`-скрипт у кожному воркспейсі bun-монорепо й зафіксувати, чи проєкт **взагалі стартує**. Це smoke-перевірка: ціль — спіймати негайний крах (синтаксична помилка, відсутній модуль, падіння на старті), а не протестувати поведінку.
|
|
13
|
+
|
|
14
|
+
## Передумови
|
|
15
|
+
|
|
16
|
+
- Bun-монорепо: кореневий `package.json` має поле `workspaces`.
|
|
17
|
+
- Залежності встановлені (`bun i`) — інакше `start` упаде на відсутньому модулі, а не на реальній проблемі.
|
|
18
|
+
- Запуск з кореня репозиторію (де лежить кореневий `package.json` / `bun.lock`).
|
|
19
|
+
|
|
20
|
+
## Workflow
|
|
21
|
+
|
|
22
|
+
### 1. Зібрати список воркспейсів
|
|
23
|
+
|
|
24
|
+
Прочитай поле `workspaces` з кореневого `package.json`. Воно може містити glob-патерни (`packages/*`, `apps/*`) — розгорни кожен у конкретні директорії. Для кожної директорії прочитай її `package.json`.
|
|
25
|
+
|
|
26
|
+
### 2. Відфільтрувати воркспейси зі `start`-скриптом
|
|
27
|
+
|
|
28
|
+
Воркспейс перевіряється, лише якщо в його `package.json` є `scripts.start`. Решту — пропусти й познач у звіті як `SKIP (немає start)`.
|
|
29
|
+
|
|
30
|
+
### 3. Класифікувати `start` і зафіксувати стан репо
|
|
31
|
+
|
|
32
|
+
Скіл прогоняє **кожен** воркспейс зі `start` — запуск не пропускається. Але `start` буває двох типів, і це впливає і на трактування коду виходу, і на ризик побічних ефектів:
|
|
33
|
+
|
|
34
|
+
- **Запуск сервера/застосунку** (`vite`, `next dev`, `nuxt dev`, `node`/`bun <server>`, `nodemon` тощо) — успіх визначається за живучістю процесу.
|
|
35
|
+
- **CLI/разова дія** (зокрема ті, що мутують репо — sync, генерація коду, міграції, розгортання, перезапис конфігів) — успіх визначається за кодом виходу; такий `start` може **виконати реальну роботу** й лишити зміни в репозиторії.
|
|
36
|
+
|
|
37
|
+
Щоб прогін мутаційного `start` не лишив сміття, зафіксуй стан робочого дерева **перед** запусками:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
git status --porcelain > /tmp/n-start-check.before
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Цей знімок — база, щоб відкотити побічні ефекти (крок 5).
|
|
44
|
+
|
|
45
|
+
### 4. Прогнати `start` послідовно
|
|
46
|
+
|
|
47
|
+
Запускай воркспейси **по черзі, НЕ паралельно**: dev-сервери конфліктують за портами, а послідовний прогон дає однозначну причину краху.
|
|
48
|
+
|
|
49
|
+
`start` буває двох типів — скіл має їх розрізняти:
|
|
50
|
+
|
|
51
|
+
- **Довгий процес** (dev-сервер, демон): успіх = процес живий через grace-період без краху. Бажано дочекатися рядка готовності в логу (`ready`, `listening`, `Local:`, `started` тощо).
|
|
52
|
+
- **Короткий процес** (CLI, разова дія): успіх = вихід із кодом `0`.
|
|
53
|
+
|
|
54
|
+
macOS не має `timeout` як стандартної утиліти. Обмеж час через `perl` + `alarm`: `alarm` зводить SIGALRM, а `exec` зберігає той самий PID, тож таймер спрацьовує на справжньому процесі й знімає його після grace-періоду:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
cd <workspace-dir>
|
|
58
|
+
perl -e 'alarm shift; exec @ARGV' 12 bun run start > /tmp/n-start-check.log 2>&1
|
|
59
|
+
CODE=$?
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Інтерпретація `CODE`:
|
|
63
|
+
|
|
64
|
+
- `142` — процес дожив до кінця grace-періоду й був знятий SIGALRM (`128 + 14`). Для **довгого процесу** (dev-сервер) це **успіх** — стартував і не впав.
|
|
65
|
+
- `0` — процес завершився сам без помилки. Для **короткого процесу** (CLI, разова дія) це **успіх**.
|
|
66
|
+
- будь-що інше — **FAIL**: крах або ненульовий вихід ще до кінця grace-періоду.
|
|
67
|
+
|
|
68
|
+
Звір також лог: для dev-сервера — рядок готовності (`ready`, `listening`, `Local:`); для CLI — відсутність трас помилок.
|
|
69
|
+
|
|
70
|
+
Альтернатива `cd` — `bun run --filter '<package-name>' start` (запуск за іменем пакета).
|
|
71
|
+
|
|
72
|
+
`bun run start` прибирає свій дочірній процес при завершенні; якщо `start` у репо форкає демонів окремо — переконайся, що після перевірки нічого не лишилось висіти.
|
|
73
|
+
|
|
74
|
+
### 5. Відкотити побічні ефекти прогону
|
|
75
|
+
|
|
76
|
+
Після кожного запуску звір поточний `git status --porcelain` зі знімком `/tmp/n-start-check.before` і відкоти **лише те, що з'явилося через прогін**:
|
|
77
|
+
|
|
78
|
+
- нові невідстежувані файли/директорії (яких не було у знімку) — видали;
|
|
79
|
+
- відстежувані файли, що стали зміненими, а у знімку були чисті — `git checkout -- <path>`;
|
|
80
|
+
- усе, що було брудним **до** прогону, — НЕ чіпай: це зміни користувача, не пов'язані з прогоном.
|
|
81
|
+
|
|
82
|
+
Gitignored-артефакти (кеші, `node_modules`, логи) у `git status` не з'являються — їх чіпати не треба. Коли побічні ефекти прибрано, дерево повертається до стану знімка, тож наступний воркспейс стартує з чистої бази.
|
|
83
|
+
|
|
84
|
+
### 6. Зафіксувати результат
|
|
85
|
+
|
|
86
|
+
Для кожного воркспейсу — статус і примітка:
|
|
87
|
+
|
|
88
|
+
- `OK` — стартував (живий dev-сервер або вихід `0`).
|
|
89
|
+
- `FAIL` — крах або ненульовий код. Додай витяг із логу: останні значущі рядки з помилкою.
|
|
90
|
+
- `SKIP` — у воркспейсі немає `start`-скрипта (крок 2). Сам запуск `start` не пропускається.
|
|
91
|
+
|
|
92
|
+
Якщо мутаційний `start` лишив побічні ефекти (крок 5) — познач це в примітці: проєкт стартує, але `start` не є чистим запуском сервера.
|
|
93
|
+
|
|
94
|
+
Розрізняй у звіті **помилку коду** (синтаксис, відсутній імпорт, падіння при ініціалізації) і **середовищний збій** (немає `.env`, недоступна БД/сервіс, зайнятий порт) — останній не означає, що проєкт зламаний.
|
|
95
|
+
|
|
96
|
+
### 7. Звіт
|
|
97
|
+
|
|
98
|
+
Підсумкова таблиця: `воркспейс | статус | примітка`. Якщо є хоч один `FAIL` — винеси його окремо й покажи помилку повністю.
|
|
99
|
+
|
|
100
|
+
Скіл лише **діагностує** запуск. Виправлення коду — поза скоупом; якщо причина FAIL очевидна, познач її у звіті, але не правь, поки про це не попросять окремо.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[bun]
|
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: n-abie-clean
|
|
3
|
-
description: >-
|
|
4
|
-
Очистка проєкту від ru-середовища: гілка `ru`, директорії `ru/`, файли з суфіксом
|
|
5
|
-
`-ru`/`values-ru.*`, гілки `endsWith(...'ru')` у GitHub Actions, ru-умови у
|
|
6
|
-
Dockerfile/nginx, посилання на `cr.yandex` та раннер `ya`
|
|
7
|
-
version: '1.1'
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
Скіл прибирає з проєкту все, що належить **ru-середовищу**. Залишаються тільки `dev` (як база) та `ua` як активне продакшн-середовище. Працюй послідовно по секціях нижче — після кожної секції перевіряй, що проєкт лишається консистентним (`kustomization.yaml` посилається лише на наявні файли, GitHub Actions-вирази синтаксично коректні).
|
|
11
|
-
|
|
12
|
-
## 0. Що НЕ чіпати
|
|
13
|
-
|
|
14
|
-
**`node_modules/`** (і будь-які `**/node_modules/`) — повністю виключаються з аналізу й модифікацій. Це згенеровані залежності: збіги на `ru`, `values-ru.*`, `cr.yandex` тощо там нерелевантні і відновляться при наступному `install`. Усі `find` / `git grep` / автозаміни мають пропускати ці шляхи. Аналогічно не чіпай `.git/`, `dist/`, `build/`, `.next/`, `.nuxt/`, `.output/`, `coverage/`.
|
|
15
|
-
|
|
16
|
-
## 1. Директорії з назвою `ru`
|
|
17
|
-
|
|
18
|
-
Видали всі директорії з назвою `ru` у проєкті (крім тих, що всередині `node_modules`):
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
find . -type d \( -name node_modules -o -name .git \) -prune -o -type d -name "ru" -print -exec rm -rf {} +
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
Це чистить як `country/ru/`, так і `k8s/<...>/ru/` (overlay у kustomize). Після видалення overlay `ru/` обов’язково прибери відповідний запис у `resources:` у батьківському `kustomization.yaml`, якщо він там лишився.
|
|
25
|
-
|
|
26
|
-
## 2. Файли з ru-суфіксом
|
|
27
|
-
|
|
28
|
-
Видали файли, у назві яких є явний ru-маркер:
|
|
29
|
-
|
|
30
|
-
- `values-ru.ini`, `values-ru.yaml`, `values-ru.*` (Helm/абстракції values на середовище)
|
|
31
|
-
- будь-які файли, що закінчуються на `-ru` або `-ru.<ext>`, наприклад `site/.env.prod-ru`, `*.env.prod-ru`, `*.prod-ru.conf`
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
find . -type d \( -name node_modules -o -name .git \) -prune -o \
|
|
35
|
-
-type f \( -name "values-ru.*" -o -name "*-ru" -o -name "*.prod-ru" -o -name "*.prod-ru.*" \) -print -delete
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## 3. `.github/workflows/*.yml`
|
|
39
|
-
|
|
40
|
-
### 3.1. Тригери `on.push.branches`
|
|
41
|
-
|
|
42
|
-
Прибирай `ru` зі списку гілок.
|
|
43
|
-
|
|
44
|
-
Було:
|
|
45
|
-
|
|
46
|
-
```yaml
|
|
47
|
-
on:
|
|
48
|
-
push:
|
|
49
|
-
branches: [dev, ru, ua]
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Стало:
|
|
53
|
-
|
|
54
|
-
```yaml
|
|
55
|
-
on:
|
|
56
|
-
push:
|
|
57
|
-
branches: [dev, ua]
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### 3.2. Тернарні вирази `endsWith(github.ref_name, …)`
|
|
61
|
-
|
|
62
|
-
У ланцюжках `endsWith(...)` залишай тільки гілки `dev` та `ua`. Гілку `ru` (а також пов’язаний з нею fallback на раннер `ya`, реєстр `cr.yandex/...`, NATS `cluster.local` тощо) — прибирай. Останнє значення в ланцюжку стає fallback’ом для всього, що не `dev`.
|
|
63
|
-
|
|
64
|
-
`runs-on` — було:
|
|
65
|
-
|
|
66
|
-
```yaml
|
|
67
|
-
runs-on: ${{ endsWith(github.ref_name, 'dev') && 'dev' || ( endsWith(github.ref_name, 'ua') && 'ua' || 'ya' ) }}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Стало:
|
|
71
|
-
|
|
72
|
-
```yaml
|
|
73
|
-
runs-on: ${{ endsWith(github.ref_name, 'dev') && 'dev' || 'ua' }}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
`NATS_URL` — було:
|
|
77
|
-
|
|
78
|
-
```yaml
|
|
79
|
-
NATS_URL: ${{ endsWith(github.ref_name, 'dev') && 'nats.nats.svc.abie-dev.internal:4222' || ( endsWith(github.ref_name, 'ua') && 'nats.nats.svc.abie-ua.internal:4222' || 'nats.nats.svc.cluster.local:4222' ) }}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
Стало:
|
|
83
|
-
|
|
84
|
-
```yaml
|
|
85
|
-
NATS_URL: ${{ endsWith(github.ref_name, 'dev') && 'nats.nats.svc.abie-dev.internal:4222' || 'nats.nats.svc.abie-ua.internal:4222' }}
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
`NATS_STREAM` — було:
|
|
89
|
-
|
|
90
|
-
```yaml
|
|
91
|
-
NATS_STREAM: ${{ endsWith(github.ref_name, 'dev') && 'dev' || ( endsWith(github.ref_name, 'ua') && 'ua' || 'ru' ) }}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
Стало:
|
|
95
|
-
|
|
96
|
-
```yaml
|
|
97
|
-
NATS_STREAM: ${{ endsWith(github.ref_name, 'dev') && 'dev' || 'ua' }}
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
`REGISTRY` — було:
|
|
101
|
-
|
|
102
|
-
```yaml
|
|
103
|
-
REGISTRY: ${{ endsWith(github.ref_name, 'ru') && 'cr.yandex/crpaerfcq9t16fse5onm' || ( endsWith(github.ref_name, 'ua') && 'europe-west4-docker.pkg.dev/abie-ua/c' || 'europe-north1-docker.pkg.dev/abie-dev/c' ) }}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
Стало:
|
|
107
|
-
|
|
108
|
-
```yaml
|
|
109
|
-
REGISTRY: ${{ endsWith(github.ref_name, 'ua') && 'europe-west4-docker.pkg.dev/abie-ua/c' || 'europe-north1-docker.pkg.dev/abie-dev/c' }}
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
Загальне правило: у фінальному виразі мають лишитися лише `endsWith(github.ref_name, 'dev')` та `endsWith(github.ref_name, 'ua')` (або лише один із них, якщо середовище одне). Будь-яка згадка `'ru'`, `'ya'`, `cr.yandex`, `cluster.local`-fallback для ru — прибирається.
|
|
113
|
-
|
|
114
|
-
### 3.3. `ignore_branches` / `branches-ignore`
|
|
115
|
-
|
|
116
|
-
У всіх workflow-файлах та конфігах (включно з тими, що використовуються правилом **abie** `clean_merged_ignore_branches`) прибирай `ru` зі списків ignore-гілок.
|
|
117
|
-
|
|
118
|
-
## 4. Dockerfile / nginx / build-скрипти
|
|
119
|
-
|
|
120
|
-
Прибирай умовні гілки `if [ "$BRANCH" = "ru" ]; then …` та копіювання `country/ru/*`. Лишається лише той код, що працює для `dev`/`ua`.
|
|
121
|
-
|
|
122
|
-
Було:
|
|
123
|
-
|
|
124
|
-
```dockerfile
|
|
125
|
-
RUN if [ "$BRANCH" = "ru" ]; then cp -r country/ru/* public/ || true; fi && \
|
|
126
|
-
bun install && \
|
|
127
|
-
if [ "$BRANCH" = "ru" ]; then BASE="/itool/"; else BASE="/contract/"; fi && \
|
|
128
|
-
bun vite build --mode "prod-$BRANCH" --base="$BASE"
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
Стало:
|
|
132
|
-
|
|
133
|
-
```dockerfile
|
|
134
|
-
RUN bun install && bun vite build --mode "prod-$BRANCH" --base="$BASE"
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
Те саме стосується `nginx`-конфігів (`server_name`, `proxy_pass` з ru-доменами), `*.sh`-скриптів та `package.json` scripts (`build:ru`, `deploy:ru`, `prod-ru` тощо).
|
|
138
|
-
|
|
139
|
-
## 5. Переклади
|
|
140
|
-
|
|
141
|
-
Замінити переклад з російської на англійську в @nitra/tfm, @nitra/tf та @nitra/tfm-node. Якщо англійська вже є, то прибираємо російську:
|
|
142
|
-
|
|
143
|
-
Приклад БУЛО:
|
|
144
|
-
|
|
145
|
-
```vue
|
|
146
|
-
<template>
|
|
147
|
-
<h5>{{ t`Привіт` }}</h5>
|
|
148
|
-
</template>
|
|
149
|
-
|
|
150
|
-
<script setup>
|
|
151
|
-
import tf from '@nitra/tf/webpack'
|
|
152
|
-
|
|
153
|
-
// Translate
|
|
154
|
-
const tr = {
|
|
155
|
-
Привіт: 'Привет'
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const t = tf.bind({ tr })
|
|
159
|
-
</script>
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
СТАЛО:
|
|
163
|
-
|
|
164
|
-
```vue
|
|
165
|
-
<template>
|
|
166
|
-
<h5>{{ t`Привіт` }}</h5>
|
|
167
|
-
</template>
|
|
168
|
-
|
|
169
|
-
<script setup>
|
|
170
|
-
import tf from '@nitra/tf/webpack'
|
|
171
|
-
|
|
172
|
-
// Translate
|
|
173
|
-
const tr = {
|
|
174
|
-
Привіт: 'Hello'
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const t = tf.bind({ tr })
|
|
178
|
-
</script>
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
або
|
|
182
|
-
|
|
183
|
-
import { tf } from '@nitra/tfm'
|
|
184
|
-
|
|
185
|
-
const tr = {
|
|
186
|
-
Так: { ru: 'Да' },
|
|
187
|
-
Ні: { ru: 'Нет' }
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
на
|
|
191
|
-
|
|
192
|
-
import { tf } from '@nitra/tfm'
|
|
193
|
-
|
|
194
|
-
const tr = {
|
|
195
|
-
Так: { ru: 'Yes' },
|
|
196
|
-
Ні: { ru: 'No' }
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
### 5.1. Апострофи та спецсимволи в рядках перекладу
|
|
200
|
-
|
|
201
|
-
Український текст рідко містить апостроф у сенсі JS-рядка; у **англійських** перекладах часті скорочення з `'` (`today's`, `can't`, `don't`, `you're` тощо). Після кожної зміни `tr` переглянь результат на символи `'`, `"` та `\` і переконайся, що **роздільники рядка** парсяться коректно.
|
|
202
|
-
|
|
203
|
-
**Одинарні лапки.** Якщо англійський переклад містить апостроф і рядок обгорнуто в `'…'`:
|
|
204
|
-
|
|
205
|
-
- **Неправильно:** `'today\\'s route'` — подвійний backslash + кінець рядка, синтаксична помилка.
|
|
206
|
-
- **Правильно:** `'today\'s route'` — один backslash екранує апостроф.
|
|
207
|
-
- **Краще:** `"today's route"` — подвійні лапки, екранування не потрібне.
|
|
208
|
-
|
|
209
|
-
**Безпечне правило:** якщо в англійському перекладі є апостроф — переходь на **подвійні** лапки як роздільник рядка.
|
|
210
|
-
|
|
211
|
-
## 6. Після очистки
|
|
212
|
-
|
|
213
|
-
- Переконайся, що `kustomization.yaml` у кожній директорії `k8s/` не посилається на видалені overlay або файли.
|
|
214
|
-
- Пройдись `git grep` по репозиторію на залишки: `git grep -n -i -e '\bru\b' -e cr\.yandex -e country/ru -e prod-ru -e values-ru -e "'ya'"` — переглянь усі знахідки вручну, бо `ru` як слово може траплятися в легітимних контекстах (наприклад, `truncate`, `Aurum`, `cruft`). Видаляй лише ті входження, що належать ru-середовищу. `git grep` за замовчуванням пропускає невідстежувані шляхи, тож `node_modules/` у вихід не потрапить, поки воно у `.gitignore`.
|
|
215
|
-
- Перевір CI локально: `npx @nitra/cursor check abie` (якщо правило **abie** ввімкнене у проєкті).
|
|
216
|
-
- Після змін у вихідних файлах (особливо рядках перекладу) переконайся, що збірка **компілюється**: `bun vite build` у корені відповідного пакета (або там, де в проєкті налаштований Vite). Синтаксична помилка в об’єкті `tr` ламає всі три CI-пайплайни (android, ios, site) — локальний build ловить її до коміту.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[abie]
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: n-abie-kustomize
|
|
3
|
-
description: >-
|
|
4
|
-
Трансформація дерев k8s у Kustomize (base + overlays): dev → base, без окремої dev/; директорія
|
|
5
|
-
users/ у середовищах не входить у kustomization (окремі маніфести між середовищами); дерево з
|
|
6
|
-
CNPG Cluster (postgresql.cnpg.io/v1) не трансформувати
|
|
7
|
-
version: '1.2'
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
Спочатку знайди всі директорії `k8s/` у проєкті. Виконуй трансформацію лише для тих, у яких **немає** директорії `base/`. Якщо `base/` вже існує — пропускай цю директорію і рухайся далі.
|
|
11
|
-
|
|
12
|
-
Якщо в дереві тієї директорії `k8s/`, яку збираєшся трансформувати (рекурсивно по `*.yaml`), є маніфест з **`apiVersion: postgresql.cnpg.io/v1`** і **`kind: Cluster`** (CloudNativePG) — **не застосовуй** до цього дерева описану трансформацію base/overlays: залиш структуру як є і переходь до наступної директорії `k8s/`.
|
|
13
|
-
|
|
14
|
-
Трансформуй директорії, щоб виділити спільне за допомогою kustomize. За основу беремо все, що в середовищі dev, і саме в такому вигляді з dev воно має стати **base**; якщо вже є base і немає dev — це нормально, рухайся далі.
|
|
15
|
-
|
|
16
|
-
У інших середовищах має бути лише `kustomization.yaml` і зміни через оверрайди.
|
|
17
|
-
|
|
18
|
-
У **base** у всіх ресурсів (окрім `base/kustomization.yaml`) має бути namespace **dev**.
|
|
19
|
-
|
|
20
|
-
Окремої директорії **dev** не має бути — за середовище dev відповідає **base**.
|
|
21
|
-
|
|
22
|
-
README має бути в директорії **k8s**.
|
|
23
|
-
|
|
24
|
-
Рядки в маніфестах у **base**, які змінюватимуться в інших середовищах, позначай коментарем на тому самому рядку: `# буде замінено через kustomize`.
|
|
25
|
-
|
|
26
|
-
Патчів лише на namespace не роби — namespace задається в `kustomization.yaml`.
|
|
27
|
-
|
|
28
|
-
Застарілі файли прибирай.
|
|
29
|
-
|
|
30
|
-
Для overlay **ua** `namespace` задавай у `kustomization.yaml` (без окремих patch лише на зміну namespace). Деталі — **n-k8s** / **abie** у `.cursor/rules/`, якщо ці правила увімкнені в проєкті.
|
|
31
|
-
|
|
32
|
-
## Виключення: CNPG `Cluster`
|
|
33
|
-
|
|
34
|
-
Ресурс **`Cluster`** оператора CloudNativePG (`postgresql.cnpg.io/v1`) має власні правила життєвого циклу та іменування; шаблон «dev → base + overlays» для нього не застосовується.
|
|
35
|
-
|
|
36
|
-
## Виключення: директорії `users/`
|
|
37
|
-
|
|
38
|
-
Директорія `users/` у кожному середовищі — **окремий шар маніфестів**, який **не входить у Kustomize**. Так зроблено навмисно: вміст часто **різний між середовищами**, тож немає сенсу виносити його в `base` чи патчити через overlays.
|
|
39
|
-
|
|
40
|
-
Правила:
|
|
41
|
-
|
|
42
|
-
- Файли з `users/` **не додавай** до жодного `kustomization.yaml` (ні `base`, ні overlay) — вони **не підключаються** до kustomize.
|
|
43
|
-
- Директорію `users/` **не переміщуй** у `base` — вона **залишається** в своєму середовищі (`dev`, `ua`, інше overlay тощо), поруч з `kustomization.yaml` цього середовища (або після рефакторингу — поруч з overlay, де вона була логічно прив’язана).
|
|
44
|
-
- У файлах у `users/` **може не бути** `metadata.namespace` — це нормально, **не нав’язуй** namespace лише заради kustomize.
|
|
45
|
-
- Якщо `users/` є в кількох середовищах з різним набором файлів (наприклад, 29 yaml у одному й інша кількість в іншому) — **залишай незалежними**, не намагайся уніфікувати через base.
|
|
46
|
-
|
|
47
|
-
Приклад **до** трансформації (фрагмент):
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
k8s/db/
|
|
51
|
-
├── dev/ # namespace: dev
|
|
52
|
-
│ ├── kustomization.yaml
|
|
53
|
-
│ ├── cluster-db.yaml # instances: 1, поля з # буде замінено через kustomize
|
|
54
|
-
│ ├── secret-auth.yaml
|
|
55
|
-
│ └── secret-source-db.yaml
|
|
56
|
-
└── ua/ # або інше середовище
|
|
57
|
-
├── kustomization.yaml
|
|
58
|
-
└── users/
|
|
59
|
-
└── *.yaml # без metadata.namespace; не в kustomization.resources
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Приклад **після** трансформації (той самий принцип для `users/`):
|
|
63
|
-
|
|
64
|
-
```
|
|
65
|
-
k8s/db/
|
|
66
|
-
├── base/
|
|
67
|
-
│ ├── kustomization.yaml
|
|
68
|
-
│ ├── cluster-db.yaml # namespace: dev, поля з # буде замінено через kustomize
|
|
69
|
-
│ ├── secret-auth.yaml
|
|
70
|
-
│ └── secret-source-db.yaml
|
|
71
|
-
└── ua/
|
|
72
|
-
├── kustomization.yaml # namespace, patches — без users/
|
|
73
|
-
└── users/ # лишається тут; kustomize їх не бачить
|
|
74
|
-
└── *.yaml
|
|
75
|
-
```
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[abie]
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: n-efes-create-env
|
|
3
|
-
description: >-
|
|
4
|
-
Створення нового середовища (env) в репозиторії efes/manager — приймає назву
|
|
5
|
-
середовища як аргумент (наприклад `kz`, `kz-qa`, `tr-stage`, `ua-dev`).
|
|
6
|
-
Генерує .env.prod-<env>, .env.remote-<env>, оверлей site/k8s/<env>/,
|
|
7
|
-
додає скрипт start-remote-<env> у site/package.json і реєструє <env> у
|
|
8
|
-
списках branches GitHub Actions та Azure Pipelines. Якщо назва закінчується
|
|
9
|
-
на dev або -qa — non-production (база: md-qa); інакше — production (база: md).
|
|
10
|
-
Тригери: «створи середовище», «новий env», «add environment», «n-efes-create-env».
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
# n-efes-create-env — створення нового середовища
|
|
14
|
-
|
|
15
|
-
Скіл генерує всі конфіги для нового середовища `manager`, спираючись на існуюче як шаблон. Запуск: `/n-efes-create-env <env>` або «створи середовище `<env>`».
|
|
16
|
-
|
|
17
|
-
## Існуючі середовища (станом на створення скіла)
|
|
18
|
-
|
|
19
|
-
`dev` · `md` · `md-qa` · `tr` · `tr-qa`
|
|
20
|
-
|
|
21
|
-
## Аргумент
|
|
22
|
-
|
|
23
|
-
Назва середовища — `$ARGUMENTS` (kebab-case, без пробілів). Якщо аргументу немає — спитай користувача.
|
|
24
|
-
|
|
25
|
-
## Класифікація та джерело
|
|
26
|
-
|
|
27
|
-
| Закінчення | Тип | Базове середовище | Базовий домен |
|
|
28
|
-
| --------------- | -------------- | ----------------- | --------------------------- |
|
|
29
|
-
| `dev` або `-qa` | non-production | `md-qa` | `mayamd-qa.anadoluefes.com` |
|
|
30
|
-
| інше | production | `md` | `mayamd.anadoluefes.com` |
|
|
31
|
-
|
|
32
|
-
Перед роботою зафіксуй у себе:
|
|
33
|
-
|
|
34
|
-
- `ENV` — `$ARGUMENTS`
|
|
35
|
-
- `BASE` — `md-qa` або `md` згідно з таблицею вище
|
|
36
|
-
- `BASE_DOMAIN` — домен бази
|
|
37
|
-
- `DOMAIN` — `maya${ENV}.anadoluefes.com` (шаблон: префікс `maya` + env). Якщо ENV вже містить країну з дефісом (наприклад `kz-qa`) — домен буде `mayakz-qa.anadoluefes.com`. Якщо користувач хоче інший домен — підтверди.
|
|
38
|
-
- `COUNTRY` — країна без суфіксу `-qa`/`-dev`/`-stage` (наприклад `kz-qa` → `kz`). Потрібно для ACR-шляхів.
|
|
39
|
-
|
|
40
|
-
## Кроки
|
|
41
|
-
|
|
42
|
-
### 0. Перевірити, що середовище ще не існує
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
test ! -f site/.env.prod-$ENV \
|
|
46
|
-
&& test ! -f site/.env.remote-$ENV \
|
|
47
|
-
&& test ! -d site/k8s/$ENV \
|
|
48
|
-
|| { echo "Середовище $ENV вже існує — припини"; exit 1; }
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### 1. Інтерактивне опитування — зібрати country-specific дані
|
|
52
|
-
|
|
53
|
-
**ОБОВ'ЯЗКОВО** перед будь-якими `cp`/`sed` запитай користувача через `AskUserQuestion` (у Cursor — звичайним повідомленням з варіантами). Не виконуй кроки 2–5, поки не отримав усі відповіді.
|
|
54
|
-
|
|
55
|
-
Запитай **одним викликом** `AskUserQuestion` із кількома запитаннями:
|
|
56
|
-
|
|
57
|
-
1. **Тип середовища** — заголовок «Тип env»:
|
|
58
|
-
- «Нова країна» — env вводить нову країну (новий VITE_COUNTRY, своя SAP-tenant, свій бакет)
|
|
59
|
-
- «Новий етап існуючої країни» — env є додатковим етапом md/tr (інший суфікс, але та сама країна та tenant)
|
|
60
|
-
|
|
61
|
-
2. **Домен** — заголовок «Domain»:
|
|
62
|
-
- `maya${ENV}.anadoluefes.com` (default, рекомендований)
|
|
63
|
-
- «Інший» — користувач введе власний
|
|
64
|
-
|
|
65
|
-
3. **SAP-credentials** — заголовок «SAP auth»:
|
|
66
|
-
- «Залишити як у бази (`$BASE`)» — для нових етапів існуючої країни
|
|
67
|
-
- «Заглушки `TODO_SAP_*`» — для нової країни, реальні значення додасть devops/security окремим commit
|
|
68
|
-
- «Введу зараз» — користувач передасть значення в `Other` (формат: `ENDPOINT=…; CLIENT_ID=…; CLIENT_SECRET=…`)
|
|
69
|
-
|
|
70
|
-
4. **Storage account (`VITE_BUCKET`)** — заголовок «Bucket»:
|
|
71
|
-
- «Залишити як у бази» — той самий storage account (`stmdmayasfaprod001`/`stmdmayasfadev001`)
|
|
72
|
-
- «Власний для нової країни» — користувач введе ім'я storage account в `Other` (наприклад `stkzmayasfaprod001`)
|
|
73
|
-
|
|
74
|
-
Якщо «Нова країна» — окремо (у тому ж або наступному виклику) запитай:
|
|
75
|
-
|
|
76
|
-
5. **VITE_COUNTRY** — заголовок «Country»: `md`, `tr`, інше (через `Other`)
|
|
77
|
-
6. **VITE_TFM_DEFAULT** — заголовок «TFM default»: `ru`, `en`, `tr`, `ro`, інше
|
|
78
|
-
7. **VITE_TFM_LIST** — заголовок «TFM list»: набір популярних варіантів (`ru,en,ro,tr`, `en,tr`, `ru,en`) + `Other`
|
|
79
|
-
|
|
80
|
-
Збережи відповіді у змінні `DOMAIN`, `COUNTRY`, `TFM_DEFAULT`, `TFM_LIST`, `BUCKET_ACCOUNT`, `SAP_MODE` (`keep`/`stub`/`custom`), `SAP_VALUES` (якщо `custom`).
|
|
81
|
-
|
|
82
|
-
### 2. Створити `.env.prod-$ENV` та `.env.remote-$ENV`
|
|
83
|
-
|
|
84
|
-
Скопіюй файли бази:
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
cp site/.env.prod-$BASE site/.env.prod-$ENV
|
|
88
|
-
cp site/.env.remote-$BASE site/.env.remote-$ENV
|
|
89
|
-
|
|
90
|
-
# домен
|
|
91
|
-
sed -i '' "s|$BASE_DOMAIN|$DOMAIN|g" site/.env.prod-$ENV site/.env.remote-$ENV
|
|
92
|
-
|
|
93
|
-
# bucket path (maya-files-<base> → maya-files-$ENV)
|
|
94
|
-
sed -i '' "s|maya-files-$BASE|maya-files-$ENV|g" site/.env.prod-$ENV site/.env.remote-$ENV
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
Далі **застосуй відповіді з кроку 1** (через `Edit`):
|
|
98
|
-
|
|
99
|
-
- Якщо `BUCKET_ACCOUNT` != base — заміни storage account host у `VITE_BUCKET`.
|
|
100
|
-
- Якщо тип = «Нова країна»:
|
|
101
|
-
- `VITE_COUNTRY=$COUNTRY`
|
|
102
|
-
- `VITE_TFM_DEFAULT=$TFM_DEFAULT`
|
|
103
|
-
- `VITE_TFM_LIST=$TFM_LIST`
|
|
104
|
-
- Якщо `SAP_MODE=stub` — заміни значення на:
|
|
105
|
-
- `VITE_SAP_AUTH_ENDPOINT=TODO_SAP_ENDPOINT`
|
|
106
|
-
- `VITE_SAP_AUTH_CLIENT_ID='TODO_SAP_CLIENT_ID'`
|
|
107
|
-
- `VITE_SAP_AUTH_CLIENT_SECRET=TODO_SAP_CLIENT_SECRET`
|
|
108
|
-
- Якщо `SAP_MODE=custom` — підстав `SAP_VALUES`.
|
|
109
|
-
|
|
110
|
-
Інваріанти, які мають лишитися після всіх правок:
|
|
111
|
-
|
|
112
|
-
- У `.env.remote-$ENV` — `VITE_DOMAIN=localhost`, `VITE_UPLOADER=/file-link/`, `VITE_EXPORT_EXCEL=/export-table/`.
|
|
113
|
-
- У `.env.prod-$ENV` — `VITE_DOMAIN=$DOMAIN`, `VITE_UPLOADER=https://$DOMAIN/file-link/`, `VITE_EXPORT_EXCEL=https://$DOMAIN/export-table/`.
|
|
114
|
-
|
|
115
|
-
### 2. Створити `site/k8s/$ENV/kustomization.yaml`
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
mkdir -p site/k8s/$ENV
|
|
119
|
-
cp site/k8s/$BASE/kustomization.yaml site/k8s/$ENV/kustomization.yaml
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Відредагуй новий файл:
|
|
123
|
-
|
|
124
|
-
- `namespace: $ENV`
|
|
125
|
-
- `images[].newName`:
|
|
126
|
-
- **production** → `aefes.azurecr.io/mayasfa-$ENV/$ENV/manager-site`
|
|
127
|
-
- **non-production** → `aefes.azurecr.io/mayasfa-$COUNTRY-dev/$ENV/manager-site`
|
|
128
|
-
- `HTTPRoute` патч → `hostnames: ["$DOMAIN"]`
|
|
129
|
-
- Для **production** залиш блок `components: [../components]` (HPA/PDB).
|
|
130
|
-
- Для **non-production** видали `components` блок і HPA/PDB-патчі (як у `md-qa`).
|
|
131
|
-
|
|
132
|
-
Перевір: запусти `kubectl kustomize site/k8s/$ENV --output /dev/null` (якщо `kubectl` доступний) — має пройти без помилок.
|
|
133
|
-
|
|
134
|
-
### 3. Додати `start-remote-$ENV` у `site/package.json`
|
|
135
|
-
|
|
136
|
-
У секцію `"scripts"` додай рядок (зберігай порядок поряд із сусідніми `start-remote-*`):
|
|
137
|
-
|
|
138
|
-
```json
|
|
139
|
-
{ "scripts": { "start-remote-$ENV": "vite dev --mode remote-$ENV" } }
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### 4. Зареєструвати `$ENV` у CI/CD branch-списках
|
|
143
|
-
|
|
144
|
-
Додай `$ENV` у такі місця (зберігай існуючий порядок: dev → md-qa → md → tr → tr-qa → нові):
|
|
145
|
-
|
|
146
|
-
| Файл | Поле |
|
|
147
|
-
| ------------------------------------------- | ------------------------------ |
|
|
148
|
-
| `.github/workflows/sync-to-azure.yml` | `on.push.branches` |
|
|
149
|
-
| `.github/workflows/clean-merged-branch.yml` | `ignore_branches` (через кому) |
|
|
150
|
-
| `.azurepipelines/apply-k8s.yml` | `trigger.branches.include` |
|
|
151
|
-
| `.azurepipelines/site.yml` | `trigger.branches.include` |
|
|
152
|
-
|
|
153
|
-
Якщо існують інші `**/k8s/`-проекти у репозиторії — переконайся, що `$ENV` потрібен і там (на момент створення скіла є тільки `site/k8s/`).
|
|
154
|
-
|
|
155
|
-
### 5. Попередження користувачу про зовнішні залежності
|
|
156
|
-
|
|
157
|
-
Скіл **не** створює ці артефакти — повідом про них користувача:
|
|
158
|
-
|
|
159
|
-
- У repo `MayaSFA/k8s` має існувати шаблон `.azurepipelines/azure-pipeline-templates/$ENV.yml` (його використовує `apply-k8s.yml` і `site.yml`).
|
|
160
|
-
- Гілка `$ENV` має бути створена в обох remote (GitHub + Azure DevOps).
|
|
161
|
-
- DNS-запис для `$DOMAIN` та health-check у gateway мають бути налаштовані відповідною командою.
|
|
162
|
-
- Якщо ENV — нова країна: ACR-репозиторій `mayasfa-$ENV` (для prod) або `mayasfa-$COUNTRY-dev` (для non-prod) має бути створений.
|
|
163
|
-
|
|
164
|
-
### 6. Перевірка результату
|
|
165
|
-
|
|
166
|
-
```bash
|
|
167
|
-
ls site/.env.prod-$ENV site/.env.remote-$ENV site/k8s/$ENV/kustomization.yaml
|
|
168
|
-
grep -n "$ENV" \
|
|
169
|
-
.github/workflows/sync-to-azure.yml \
|
|
170
|
-
.github/workflows/clean-merged-branch.yml \
|
|
171
|
-
.azurepipelines/apply-k8s.yml \
|
|
172
|
-
.azurepipelines/site.yml \
|
|
173
|
-
site/package.json
|
|
174
|
-
git status
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
Виведи користувачу короткий звіт: що створено, що змінено, які зовнішні дії потрібні (з кроку 5). **Не комітити автоматично** — користувач сам перегляне через `git diff` і закомітить.
|
|
178
|
-
|
|
179
|
-
## Нюанси та пастки
|
|
180
|
-
|
|
181
|
-
- **Доменний шаблон `maya${ENV}.anadoluefes.com`** працює для існуючих країн (md/tr). Якщо нова країна має інший публічний URL — підтверди в користувача _до_ запуску `sed`.
|
|
182
|
-
- **ACR-шлях суворо за шаблоном**: prod → `mayasfa-$ENV/$ENV/manager-site`, non-prod → `mayasfa-$COUNTRY-dev/$ENV/manager-site`. Жодних додаткових сегментів між ACR-namespace та `$ENV` бути не повинно.
|
|
183
|
-
- **`ENV=dev`**: гілка `dev` — спеціальний випадок (вживає `base/`, без оверлею). Скіл не призначений для перестворення `dev`.
|
|
184
|
-
- **`.env.development`** — лише для локального запуску без бекенду; скіл його не чіпає.
|
|
185
|
-
- **Не запускай `bun run lint` / `lint-ga`** в один потік з іншими — дивись CLAUDE.md «Лінт і ESLint». Перевір лише потрібний файл (`bunx eslint <path>` або точково).
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[efes]
|