easyvibegate 0.4.4
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/LICENSE +21 -0
- package/README.en.md +123 -0
- package/README.md +144 -0
- package/dist/cli/index.js +402 -0
- package/dist/cli/wizard.js +196 -0
- package/dist/engine/aifix.js +65 -0
- package/dist/engine/checkers/backend/firebase.js +146 -0
- package/dist/engine/checkers/backend/supabase.js +249 -0
- package/dist/engine/checkers/deep/deps.js +118 -0
- package/dist/engine/checkers/index.js +15 -0
- package/dist/engine/checkers/live/endpoint-probe.js +72 -0
- package/dist/engine/checkers/live/http-checks.js +123 -0
- package/dist/engine/checkers/live/idor.js +101 -0
- package/dist/engine/checkers/static/client-exposure.js +34 -0
- package/dist/engine/checkers/static/config-risks.js +89 -0
- package/dist/engine/checkers/static/env-git.js +70 -0
- package/dist/engine/checkers/static/rls-migrations.js +324 -0
- package/dist/engine/checkers/static/route-inventory.js +31 -0
- package/dist/engine/checkers/static/secrets.js +262 -0
- package/dist/engine/config.js +54 -0
- package/dist/engine/detect.js +110 -0
- package/dist/engine/endpoints.js +65 -0
- package/dist/engine/i18n.js +189 -0
- package/dist/engine/net/http.js +108 -0
- package/dist/engine/report.js +219 -0
- package/dist/engine/scan.js +53 -0
- package/dist/engine/types.js +1 -0
- package/dist/engine/util/color.js +17 -0
- package/dist/engine/util/mask.js +66 -0
- package/dist/engine/util/text.js +50 -0
- package/dist/engine/version.js +12 -0
- package/dist/engine/walk.js +86 -0
- package/dist/orchestrator/flow.js +116 -0
- package/package.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 VibeGate contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.en.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# 🛡 EasyVibeGate
|
|
2
|
+
|
|
3
|
+
  
|
|
4
|
+
|
|
5
|
+
🇷🇺 Русская версия: [README.md](README.md)
|
|
6
|
+
|
|
7
|
+
**A security scanner for vibe-coded apps. It checks common risks and shows evidence where it can get it.**
|
|
8
|
+
|
|
9
|
+
Most scanners grep your code and say *"you might have leaked a key."* EasyVibeGate also goes to the running backend: for **Supabase/Firebase** it walks in with the public key and shows which tables are readable by anyone, with the exact `curl` — plus SQL to close it. It is honest about coverage: every check reports whether it actually ran, so a failed or skipped check is never shown as a green "all clear".
|
|
10
|
+
|
|
11
|
+
> ⚠️ **Not published to npm yet** — `npx easyvibegate` will work after publishing.
|
|
12
|
+
> Today, install straight from GitHub: `npx github:valedol190387/easyvibegate`
|
|
13
|
+
> (it fetches the repo and builds itself).
|
|
14
|
+
>
|
|
15
|
+
> Status: **v0.4, early.** Best-supported stack: **Next.js + Supabase**. Code review runs on any stack; the live backend probe is read-only and Supabase/Firebase-focused. Not a penetration test.
|
|
16
|
+
|
|
17
|
+
## How to run
|
|
18
|
+
|
|
19
|
+
Three ways — pick whichever suits you.
|
|
20
|
+
|
|
21
|
+
### Option 1. Via an AI agent (easiest)
|
|
22
|
+
|
|
23
|
+
If you use **Cursor, Claude Code, or Codex**, you don't need to type anything in a terminal. Open the project in your agent and paste this prompt:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
Check this project's security with EasyVibeGate and explain the result in plain language.
|
|
27
|
+
|
|
28
|
+
1. Run at the project root: npx github:valedol190387/easyvibegate . --no-wizard --deps
|
|
29
|
+
(After the npm release the short form is: npx easyvibegate . --no-wizard --deps)
|
|
30
|
+
(Add --url <my-app-url> --i-own-this only if this is my project
|
|
31
|
+
and I allow the live backend probe.)
|
|
32
|
+
2. Open and read the file: easyvibegate-report/ai-fix-prompt.md
|
|
33
|
+
3. Explain in plain language: what was found, how serious it is, most urgent first.
|
|
34
|
+
4. Propose concrete fixes, but do NOT change code without my confirmation.
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The agent runs it, reads the report, and explains the findings. You can also just say: "run EasyVibeGate and tell me what's wrong."
|
|
38
|
+
|
|
39
|
+
### Option 2. One command in the terminal
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx github:valedol190387/easyvibegate
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Run it inside your project. (After the npm release: `npx easyvibegate`.) A friendly wizard asks a few plain yes/no questions, tells you what's wrong in plain language, and writes a ready-to-use fix plan. No install, no config, no runtime deps.
|
|
46
|
+
|
|
47
|
+
### Option 3. In CI (GitHub Actions)
|
|
48
|
+
|
|
49
|
+
Add `.github/workflows/easyvibegate.yml`:
|
|
50
|
+
|
|
51
|
+
```yaml
|
|
52
|
+
name: EasyVibeGate
|
|
53
|
+
on: [push, pull_request]
|
|
54
|
+
jobs:
|
|
55
|
+
security:
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
steps:
|
|
58
|
+
- uses: actions/checkout@v4
|
|
59
|
+
- uses: actions/setup-node@v4
|
|
60
|
+
with: { node-version: 20 }
|
|
61
|
+
- run: npx github:valedol190387/easyvibegate . --ci
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Exit codes: `2` = critical, `1` = warnings, `3` = a check failed to run, `0` = clean.
|
|
65
|
+
|
|
66
|
+
## What to do with the result
|
|
67
|
+
|
|
68
|
+
Open `easyvibegate-report/ai-fix-prompt.md` and paste it into your AI assistant (Cursor, Claude Code, Windsurf). For security fixes, pick a **strong model — Claude Fable or Opus**, not a small "fast" one. Rotate any leaked key immediately.
|
|
69
|
+
|
|
70
|
+
## What it checks
|
|
71
|
+
|
|
72
|
+
### Level 0 — code review (any stack, read-only, zero install)
|
|
73
|
+
- **Hardcoded secrets** — OpenAI / Anthropic / AWS / Stripe / GitHub / Google keys, private keys, Supabase `service_role`/secret keys.
|
|
74
|
+
- **Secrets shipped to the browser** — real secrets behind `NEXT_PUBLIC_` / `VITE_` / `REACT_APP_`.
|
|
75
|
+
- **Dangerous config** — open CORS, debug mode, `eval`, string-interpolated SQL, JWT `alg:none`.
|
|
76
|
+
- **Missing RLS** — migrations that create tables but never `ENABLE ROW LEVEL SECURITY` (per-table analysis).
|
|
77
|
+
- **.env / git hygiene** — via real git semantics: a committed `.env` is critical.
|
|
78
|
+
- **Endpoint inventory** — routes listed as live-probe targets (no false "no auth" claims).
|
|
79
|
+
|
|
80
|
+
### Level 1 — dependency audit
|
|
81
|
+
npm / pnpm / yarn audit. A registry error is reported as "failed", never "clean".
|
|
82
|
+
|
|
83
|
+
### Level 2 — live probe (read-only, own apps only, with your confirmation)
|
|
84
|
+
- **Supabase / Firebase** — walk in with the public key and list which tables/buckets are readable by anyone, with a reproducing `curl`. Sensitive-looking table names (users, payments…) are critical; public content is flagged "confirm intent".
|
|
85
|
+
- **Any backend, best-effort** — hit discovered endpoints with no login; with two test accounts (`--idor-tokens a,b`), diff responses to spot candidate cross-user access (IDOR). Warnings to verify, not proof — the tool never writes.
|
|
86
|
+
|
|
87
|
+
## Scoring & coverage
|
|
88
|
+
|
|
89
|
+
- **One gate policy everywhere** (CI, JSON, badge, console): `fail` — a critical finding; `incomplete` — nothing critical, but a check failed / ran partially / is unsupported; `pass` — everything ran and is clean.
|
|
90
|
+
- **Score:** 0–100. An `incomplete` run is **never a green badge**.
|
|
91
|
+
- **Coverage line:** "Checks: N ok · M failed · K skipped".
|
|
92
|
+
- **Exit codes (every mode, not just `--ci`):** `2` critical, `1` warnings, `3` a check did not complete, `0` clean.
|
|
93
|
+
- Reports record the scanned path, version and timestamp, so reports from different projects never get mixed up.
|
|
94
|
+
|
|
95
|
+
## Suppressing noise
|
|
96
|
+
|
|
97
|
+
`easyvibegate.config.json`:
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{ "ignore": ["generic_secret:src/fixtures/sample.ts"], "ignorePaths": ["tests/", "docs/"] }
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Or inline, on or above the flagged line: `// easyvibegate-ignore`.
|
|
104
|
+
|
|
105
|
+
## As an AI-agent skill
|
|
106
|
+
|
|
107
|
+
`skills/easyvibegate/SKILL.md` makes EasyVibeGate a skill your agent can run and reason about. Copy it into your agent's skills dir, e.g. `cp -r skills/easyvibegate ~/.claude/skills/easyvibegate`.
|
|
108
|
+
|
|
109
|
+
## Honest limitations
|
|
110
|
+
|
|
111
|
+
EasyVibeGate is a **linter for common vibe-coding holes, not a penetration test.** Zero findings does not mean you are safe. The static layer cannot know whether an endpoint enforces access control — only the live probe can, and only against a running app you own. Never point the live probe at systems you do not own.
|
|
112
|
+
|
|
113
|
+
## Language
|
|
114
|
+
|
|
115
|
+
Interface is **Russian by default**; use `--lang en` for English. Security findings themselves stay in technical English so they hand off cleanly to your AI agent.
|
|
116
|
+
|
|
117
|
+
## Contributing
|
|
118
|
+
|
|
119
|
+
Issues and PRs welcome. Build with `pnpm install && pnpm build`; CLI entry is `dist/cli/index.js`; tests: `pnpm test`. New checks live under `src/engine/checkers/`; UI strings under `src/engine/i18n.ts`.
|
|
120
|
+
|
|
121
|
+
## License
|
|
122
|
+
|
|
123
|
+
MIT — see [LICENSE](LICENSE).
|
package/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# 🛡 EasyVibeGate
|
|
2
|
+
|
|
3
|
+
  
|
|
4
|
+
|
|
5
|
+
🇬🇧 English version: [README.en.md](README.en.md)
|
|
6
|
+
|
|
7
|
+
**Проверка безопасности для приложений, собранных «на вайбе». Находит частые дыры и показывает доказательства там, где может.**
|
|
8
|
+
|
|
9
|
+
Большинство сканеров просто грепают код и говорят «возможно, ты слил ключ». EasyVibeGate идёт дальше: для **Supabase/Firebase** заходит публичным ключом и показывает, какие таблицы читаются кем угодно, с готовым `curl` и SQL для починки. И он честен про покрытие: каждая проверка сообщает, реально ли она выполнилась, поэтому упавшая или пропущенная проверка **никогда не выдаётся за зелёное «всё чисто»**.
|
|
10
|
+
|
|
11
|
+
> ⚠️ **Пакет ещё не опубликован в npm.** Команда `npx easyvibegate` заработает после публикации.
|
|
12
|
+
> Сейчас рабочий способ — установка прямо из GitHub: `npx github:valedol190387/easyvibegate`
|
|
13
|
+
> (скачает репозиторий и соберёт его сам).
|
|
14
|
+
>
|
|
15
|
+
> Статус: **v0.4, ранняя версия.** Лучше всего поддержан стек **Next.js + Supabase**. Осмотр кода работает на любом стеке; живой пробинг бэкенда — только чтение и заточен под Supabase/Firebase. Это не пентест.
|
|
16
|
+
|
|
17
|
+
## 🇷🇺 Простыми словами
|
|
18
|
+
|
|
19
|
+
**Что это.** Проверка безопасности для приложений, собранных «на вайбе» с помощью ИИ (Cursor, Lovable, Bolt, Replit и т.п.). ИИ пишет код, который работает, но часто оставляет дыры: ключи прямо в коде, открытую всем базу данных, доступ к чужим данным. EasyVibeGate их находит и подсказывает, что чинить.
|
|
20
|
+
|
|
21
|
+
**Зачем.** Чтобы никто не скачал твою базу пользователей и не подделал данные через консоль браузера (F12).
|
|
22
|
+
|
|
23
|
+
**Как пользоваться — 3 шага:**
|
|
24
|
+
1. В папке своего проекта запусти одну команду (или попроси ИИ-агента — см. ниже).
|
|
25
|
+
2. Ответь на пару вопросов «да / нет».
|
|
26
|
+
3. Получишь понятный отчёт и готовый план починки — вставь его в свой ИИ (Cursor/Claude), и он всё исправит.
|
|
27
|
+
|
|
28
|
+
Разбираться в том, что внутри, не нужно: сложное — под капотом, снаружи одна команда и вопросы «да / нет».
|
|
29
|
+
|
|
30
|
+
## Как запустить
|
|
31
|
+
|
|
32
|
+
Три способа — выбери удобный.
|
|
33
|
+
|
|
34
|
+
### Способ 1. Через ИИ-агента (самый простой)
|
|
35
|
+
|
|
36
|
+
Если ты пользуешься **Cursor, Claude Code или Codex** — руками в терминал вводить ничего не надо. Открой проект в агенте и вставь ему такой промт:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
Проверь безопасность этого проекта с помощью EasyVibeGate и объясни результат простыми словами.
|
|
40
|
+
|
|
41
|
+
1. Запусти в корне проекта: npx github:valedol190387/easyvibegate . --no-wizard --deps
|
|
42
|
+
(После публикации в npm короткая форма: npx easyvibegate . --no-wizard --deps)
|
|
43
|
+
(Добавь --url <адрес-моего-приложения> --i-own-this только если это мой проект
|
|
44
|
+
и я разрешаю живую проверку бэкенда.)
|
|
45
|
+
2. Открой и изучи файл: easyvibegate-report/ai-fix-prompt.md
|
|
46
|
+
3. Объясни простыми словами: что нашлось, насколько это опасно, самое срочное — первым.
|
|
47
|
+
4. Предложи конкретные исправления, но НЕ меняй код без моего подтверждения.
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Агент сам всё запустит, прочитает отчёт и объяснит выводы. Можно так же просто сказать: «запусти EasyVibeGate и скажи, что не так».
|
|
51
|
+
|
|
52
|
+
### Способ 2. Одной командой в терминале
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx github:valedol190387/easyvibegate
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Запусти внутри своего проекта. (После публикации в npm будет короче: `npx easyvibegate`.) Дружелюбный мастер задаст пару вопросов «да/нет», понятным языком расскажет, что не так, и создаст готовый план починки. Ни установки, ни настройки, ни зависимостей.
|
|
59
|
+
|
|
60
|
+
### Способ 3. В CI (GitHub Actions)
|
|
61
|
+
|
|
62
|
+
Добавь `.github/workflows/easyvibegate.yml`:
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
65
|
+
name: EasyVibeGate
|
|
66
|
+
on: [push, pull_request]
|
|
67
|
+
jobs:
|
|
68
|
+
security:
|
|
69
|
+
runs-on: ubuntu-latest
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/checkout@v4
|
|
72
|
+
- uses: actions/setup-node@v4
|
|
73
|
+
with: { node-version: 20 }
|
|
74
|
+
- run: npx github:valedol190387/easyvibegate . --ci
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Коды выхода: `2` — есть критичное, `1` — предупреждения, `3` — проверка не завершилась, `0` — чисто.
|
|
78
|
+
|
|
79
|
+
## Что делать с результатом
|
|
80
|
+
|
|
81
|
+
Открой `easyvibegate-report/ai-fix-prompt.md` и вставь его в свой ИИ-помощник (Cursor, Claude Code, Windsurf). Для починки безопасности бери **сильную модель — Claude Fable или Opus**, а не маленькую «быструю»: иначе что-то пропустит. Любой утёкший ключ — сразу меняй (rotate).
|
|
82
|
+
|
|
83
|
+
## Что проверяет
|
|
84
|
+
|
|
85
|
+
### Уровень 0 — осмотр кода (любой стек, только чтение, без установки)
|
|
86
|
+
- **Секреты в коде** — ключи OpenAI / Anthropic / AWS / Stripe / GitHub / Google, приватные ключи, `service_role` и секретные ключи Supabase.
|
|
87
|
+
- **Секреты во фронте** — настоящие секреты за префиксами `NEXT_PUBLIC_` / `VITE_` / `REACT_APP_`.
|
|
88
|
+
- **Опасные конфиги** — открытый CORS, включённый debug, `eval`, сборка SQL строками, JWT `alg:none`.
|
|
89
|
+
- **Таблицы без RLS** — миграции создают таблицы, но не включают `ENABLE ROW LEVEL SECURITY` (анализ по каждой таблице).
|
|
90
|
+
- **Гигиена .env / git** — через настоящую семантику git: закоммиченный `.env` — критично.
|
|
91
|
+
- **Инвентарь эндпоинтов** — список маршрутов как цели для живой проверки (без ложных обвинений).
|
|
92
|
+
|
|
93
|
+
### Уровень 1 — зависимости
|
|
94
|
+
Аудит пакетов через npm / pnpm / yarn. Ошибка реестра честно помечается как «не удалось», а не «чисто».
|
|
95
|
+
|
|
96
|
+
### Уровень 2 — живой пробинг (только чтение, только твои приложения, с подтверждением)
|
|
97
|
+
- **Supabase / Firebase** — заходим публичным ключом и показываем, какие таблицы/бакеты читаются кем угодно, с воспроизводящим `curl`. Таблицы с «чувствительными» именами (users, payments…) — критично; публичный контент — «подтверди намеренность».
|
|
98
|
+
- **Любой бэкенд, best-effort** — дёргаем найденные эндпоинты без входа; с двумя тест-аккаунтами (`--idor-tokens a,b`) сравниваем ответы на предмет доступа к чужому (IDOR). Это подсказки для проверки, а не доказательство; инструмент никогда не пишет.
|
|
99
|
+
|
|
100
|
+
## Оценка и статусы
|
|
101
|
+
|
|
102
|
+
- **Итог — одна политика для всего** (CI, JSON, бейдж, консоль): `fail` — есть критичное; `incomplete` — критичного нет, но какая-то проверка упала / выполнилась частично / не поддержана; `pass` — всё проверено и чисто.
|
|
103
|
+
- **Балл:** 0–100. При `incomplete` бейдж **никогда не зелёный**.
|
|
104
|
+
- **Покрытие:** строка «Проверки: N выполнено · M с ошибкой · K пропущено».
|
|
105
|
+
- **Коды выхода (всегда, не только с `--ci`):** `2` критичное, `1` предупреждения, `3` проверка не завершилась, `0` чисто.
|
|
106
|
+
- Отчёт записывает проверенный путь, версию и время, поэтому отчёты разных проектов не путаются.
|
|
107
|
+
|
|
108
|
+
## Подавление ложных срабатываний
|
|
109
|
+
|
|
110
|
+
Файл `easyvibegate.config.json`:
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"ignore": ["generic_secret:src/fixtures/sample.ts"],
|
|
115
|
+
"ignorePaths": ["tests/", "docs/"]
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Или прямо в строке (на самой строке или над ней): `// easyvibegate-ignore`.
|
|
120
|
+
|
|
121
|
+
## Как запустить как skill (Cursor / Claude Code / Windsurf)
|
|
122
|
+
|
|
123
|
+
Файл `skills/easyvibegate/SKILL.md` делает EasyVibeGate навыком для ИИ-агента. Скопируй папку в каталог навыков агента, например: `cp -r skills/easyvibegate ~/.claude/skills/easyvibegate`.
|
|
124
|
+
|
|
125
|
+
## Честные ограничения
|
|
126
|
+
|
|
127
|
+
EasyVibeGate — **линтер частых дыр вайб-кодинга, а не пентест.** Ноль находок не значит «безопасно». Статический слой не знает, проверяет ли эндпоинт доступ — это может подтвердить только живая проверка на запущенном приложении, которым ты владеешь. Никогда не направляй живую проверку на чужие системы.
|
|
128
|
+
|
|
129
|
+
Что именно анализатор SQL знает про себя:
|
|
130
|
+
|
|
131
|
+
- **Порядок миграций внутри одной папки — настоящий**, и `DISABLE ROW LEVEL SECURITY` в более поздней миграции даёт критичную находку. **Порядок между разными папками — догадка**: если противоречащие друг другу команды лежат в разных каталогах, находка выдаётся как предупреждение «порядок неясен» — независимо от того, какая папка оказалась последней при сортировке.
|
|
132
|
+
- **DDL внутри `DO $$ … $$` считается выполненным**, если он безусловный. Любая команда под `IF … THEN` (`ENABLE`, `DISABLE`, `CREATE`, `DROP`) даёт предупреждение «состояние RLS не подтверждено»: выполнится ли ветка, статически не узнать, и утверждать обратное — в любую сторону — значит врать. Вложенные `IF` учитываются, `-- end if` в комментарии условие не закрывает. Если у тебя идемпотентная обёртка `IF NOT EXISTS`, проверь состояние в базе и при желании подави находку через `easyvibegate.config.json`.
|
|
133
|
+
|
|
134
|
+
## Язык
|
|
135
|
+
|
|
136
|
+
Интерфейс по умолчанию **русский**; английский — флагом `--lang en`. Сами находки остаются на техническом английском, чтобы их удобно было передать ИИ-агенту.
|
|
137
|
+
|
|
138
|
+
## Участие
|
|
139
|
+
|
|
140
|
+
Issues и PR приветствуются. Сборка: `pnpm install && pnpm build`; точка входа CLI — `dist/cli/index.js`; тесты — `pnpm test`. Новые проверки лежат в `src/engine/checkers/`, строки интерфейса — в `src/engine/i18n.ts`.
|
|
141
|
+
|
|
142
|
+
## Лицензия
|
|
143
|
+
|
|
144
|
+
MIT — см. [LICENSE](LICENSE).
|