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

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

## Мета

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

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

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

## Workflow

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

> **Не парси `package.json`/glob вручну.** Розгортання воркспейсів і класифікацію `start` несе CLI.

```bash
n-cursor start-check scan
```

Друкує JSON `[{ workspace, name, hasStart, startCmd, type }]` для root + усіх воркспейсів. `type` — `server` (dev-сервер/демон) чи `cli` (разова дія). Воркспейси з `hasStart:false` — `SKIP (немає start)` у звіті; решту прогоняй послідовно (крок 2).

### 2. Прогнати `start` кожного воркспейсу — по черзі

> **Не запускай `perl alarm` і не інтерпретуй exit-коди вручну.** CLI запускає процес із grace-таймаутом (крос-платформно через `spawnSync`), класифікує OK/FAIL за типом і парсить лог.

Для кожного воркспейсу з `hasStart:true` (**по одному, НЕ паралельно** — dev-сервери конфліктують за портами):

```bash
n-cursor start-check run <workspace>   # напр. demo  (--grace <ms>, дефолт 12000)
```

Друкує JSON:

```
{ workspace, type, exitCode, timedOut, status, ready, firstError, logTail, sideEffects }
```

- `status: "OK"` — server дожив до кінця grace (`timedOut`) або встиг віддати рядок готовності; cli вийшов із кодом `0`.
- `status: "FAIL"` — крах/ненульовий код до grace. `firstError` + `logTail` — для діагностики.
- `sideEffects: { newFiles, changedTracked }` — read-only git-diff проти стану до запуску (для кроку 3).

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

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

CLI **не** мутує дерево сам (відкат — деструктивний, лишається явним). Якщо `run` повернув непорожній `sideEffects`, відкоти **лише те, що зʼявилося через прогін**, перш ніж запускати наступний воркспейс:

- `sideEffects.newFiles` — нові невідстежувані файли/директорії → видали (`rm`);
- `sideEffects.changedTracked` — відстежувані файли, що стали зміненими → `git checkout -- <path>`.

Усе, що було брудним **до** прогону, у `sideEffects` не потрапляє (CLI рахує лише різницю) — зміни користувача не чіпай. Gitignored-артефакти (кеші, `node_modules`) у git-diff не зʼявляються.

### 4. Звіт

Підсумкова таблиця: `воркспейс | статус | примітка`, з даних `scan` + `run`:

- `OK` — `status:"OK"` (живий dev-сервер або вихід `0`).
- `FAIL` — `status:"FAIL"`; додай `firstError` / `logTail`.
- `SKIP` — `hasStart:false`.

Якщо `run` повернув непорожній `sideEffects` — познач у примітці: проєкт стартує, але `start` не є чистим запуском (мутує репо). Якщо є хоч один `FAIL` — винеси його окремо з повною помилкою.

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