---
name: n-start-check
description: >-
  Smoke-перевірка bun-монорепо: зайти в кожен воркспейс зі `start`-скриптом, прогнати
  `start` і зафіксувати, чи проєкт взагалі запускається без негайного краху
---

<!-- n-cursor:root:start -->
> [!IMPORTANT]
> **Root-only skill.** Скіл мутує проєкт у поточному каталозі й має запускатися **з кореня репозиторію**.

**Крок 0 — preflight (обовʼязковий, перед будь-якими іншими діями).**

```bash
pwd
git rev-parse --show-toplevel
```

Якщо `pwd` **не** збігається з виводом `git rev-parse --show-toplevel` — ти в **піддиректорії**. **STOP**: перейди в корінь (`cd <toplevel>`, literal-шлях із виводу) і лише тоді виконуй наступні кроки скіла. Поза git-репо (команда без виводу) — продовжуй (корінь визначити неможливо).
<!-- n-cursor:root:end -->

# n-start-check — чи запускається кожен воркспейс

## Мета

Прогнати `start`-скрипт у кожному воркспейсі bun-монорепо й зафіксувати, чи проєкт **взагалі стартує**. Це smoke-перевірка: ціль — спіймати негайний крах (синтаксична помилка, відсутній модуль, падіння на старті), а не протестувати поведінку.

## Передумови

- Bun-монорепо: кореневий `package.json` має поле `workspaces`.
- Залежності встановлені (`bun i`) — інакше `start` упаде на відсутньому модулі, а не на реальній проблемі.
- Запуск з кореня репозиторію (де лежить кореневий `package.json` / `bun.lock`).

## Workflow

### 1. Зібрати список воркспейсів

Прочитай поле `workspaces` з кореневого `package.json`. Воно може містити glob-патерни (`packages/*`, `apps/*`) — розгорни кожен у конкретні директорії. Для кожної директорії прочитай її `package.json`.

### 2. Відфільтрувати воркспейси зі `start`-скриптом

Воркспейс перевіряється, лише якщо в його `package.json` є `scripts.start`. Решту — пропусти й познач у звіті як `SKIP (немає start)`.

### 3. Класифікувати `start` і зафіксувати стан репо

Скіл прогоняє **кожен** воркспейс зі `start` — запуск не пропускається. Але `start` буває двох типів, і це впливає і на трактування коду виходу, і на ризик побічних ефектів:

- **Запуск сервера/застосунку** (`vite`, `next dev`, `nuxt dev`, `node`/`bun <server>`, `nodemon` тощо) — успіх визначається за живучістю процесу.
- **CLI/разова дія** (зокрема ті, що мутують репо — sync, генерація коду, міграції, розгортання, перезапис конфігів) — успіх визначається за кодом виходу; такий `start` може **виконати реальну роботу** й лишити зміни в репозиторії.

Щоб прогін мутаційного `start` не лишив сміття, зафіксуй стан робочого дерева **перед** запусками:

```bash
git status --porcelain > /tmp/n-start-check.before
```

Цей знімок — база, щоб відкотити побічні ефекти (крок 5).

### 4. Прогнати `start` послідовно

Запускай воркспейси **по черзі, НЕ паралельно**: dev-сервери конфліктують за портами, а послідовний прогон дає однозначну причину краху.

`start` буває двох типів — скіл має їх розрізняти:

- **Довгий процес** (dev-сервер, демон): успіх = процес живий через grace-період без краху. Бажано дочекатися рядка готовності в логу (`ready`, `listening`, `Local:`, `started` тощо).
- **Короткий процес** (CLI, разова дія): успіх = вихід із кодом `0`.

macOS не має `timeout` як стандартної утиліти. Обмеж час через `perl` + `alarm`: `alarm` зводить SIGALRM, а `exec` зберігає той самий PID, тож таймер спрацьовує на справжньому процесі й знімає його після grace-періоду:

```bash
cd <workspace-dir>
perl -e 'alarm shift; exec @ARGV' 12 bun run start > /tmp/n-start-check.log 2>&1
CODE=$?
```

Інтерпретація `CODE`:

- `142` — процес дожив до кінця grace-періоду й був знятий SIGALRM (`128 + 14`). Для **довгого процесу** (dev-сервер) це **успіх** — стартував і не впав.
- `0` — процес завершився сам без помилки. Для **короткого процесу** (CLI, разова дія) це **успіх**.
- будь-що інше — **FAIL**: крах або ненульовий вихід ще до кінця grace-періоду.

Звір також лог: для dev-сервера — рядок готовності (`ready`, `listening`, `Local:`); для CLI — відсутність трас помилок.

Альтернатива `cd` — `bun run --filter '<package-name>' start` (запуск за іменем пакета).

`bun run start` прибирає свій дочірній процес при завершенні; якщо `start` у репо форкає демонів окремо — переконайся, що після перевірки нічого не лишилось висіти.

### 5. Відкотити побічні ефекти прогону

Після кожного запуску звір поточний `git status --porcelain` зі знімком `/tmp/n-start-check.before` і відкоти **лише те, що з'явилося через прогін**:

- нові невідстежувані файли/директорії (яких не було у знімку) — видали;
- відстежувані файли, що стали зміненими, а у знімку були чисті — `git checkout -- <path>`;
- усе, що було брудним **до** прогону, — НЕ чіпай: це зміни користувача, не пов'язані з прогоном.

Gitignored-артефакти (кеші, `node_modules`, логи) у `git status` не з'являються — їх чіпати не треба. Коли побічні ефекти прибрано, дерево повертається до стану знімка, тож наступний воркспейс стартує з чистої бази.

### 6. Зафіксувати результат

Для кожного воркспейсу — статус і примітка:

- `OK` — стартував (живий dev-сервер або вихід `0`).
- `FAIL` — крах або ненульовий код. Додай витяг із логу: останні значущі рядки з помилкою.
- `SKIP` — у воркспейсі немає `start`-скрипта (крок 2). Сам запуск `start` не пропускається.

Якщо мутаційний `start` лишив побічні ефекти (крок 5) — познач це в примітці: проєкт стартує, але `start` не є чистим запуском сервера.

Розрізняй у звіті **помилку коду** (синтаксис, відсутній імпорт, падіння при ініціалізації) і **середовищний збій** (немає `.env`, недоступна БД/сервіс, зайнятий порт) — останній не означає, що проєкт зламаний.

### 7. Звіт

Підсумкова таблиця: `воркспейс | статус | примітка`. Якщо є хоч один `FAIL` — винеси його окремо й покажи помилку повністю.

Скіл лише **діагностує** запуск. Виправлення коду — поза скоупом; якщо причина FAIL очевидна, познач її у звіті, але не правь, поки про це не попросять окремо.
