diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6bd8f81 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +# Принудительно LF для всех текстовых файлов — навсегда, на всех платформах. +# +# Причина (сага 2026-06-17): CRLF в .mjs ломает transform vitest@4 — фантомный +# «SyntaxError: Invalid or unexpected token» (node/esbuild CRLF терпят, vite — нет). +# Windows git autocrlf при КАЖДОМ касании файла делал тронутые .mjs в рабочем дереве +# CRLF → полный свод краснел 19 файлами без видимой причины. eol=lf снимает это насовсем: +# git хранит и выдаёт LF независимо от core.autocrlf. +* text=auto eol=lf diff --git a/docs/superpowers/router-mentor-wall-GUIDE.md b/docs/superpowers/router-mentor-wall-GUIDE.md index f287d8e..e40176b 100644 --- a/docs/superpowers/router-mentor-wall-GUIDE.md +++ b/docs/superpowers/router-mentor-wall-GUIDE.md @@ -322,3 +322,32 @@ Verify-шаги под стеной сдвигают указатель, но GR **Мета-урок.** При «застряло» — сначала прочитать код пути (средства под рукой в разговорном режиме), потом действовать. НЕ скатываться в «ждать или спросить владельца», когда можешь сам диагностировать чтением. Owner видит вердикты в логах — но это не повод не открыть код самому. + +## Уроки сессии №8 (2026-06-17) — CRLF ломает vitest@4 (фантомный SyntaxError) + +**Симптом.** Полный свод краснеет N файлами с `SyntaxError: Invalid or unexpected token` БЕЗ позиции, +а `node --check`, `esbuild` (даже `--bundle` со всеми импортами) и прямой `node import()` те же файлы +парсят ЧИСТО. Под Claude те же файлы дают `Cannot read properties of undefined (reading 'config')`. +Статикой не воспроизводится — кажется, что «код валиден, а vitest врёт». + +**Причина.** Windows git `core.autocrlf` при КАЖДОМ касании файла (merge/checkout) делает тронутые +`.mjs` в рабочем дереве **CRLF**. vitest@4 (vite-transform) давится на `.mjs` с CRLF + шебангом +(`#!/usr/bin/env node`) → `SyntaxError`. node/esbuild CRLF терпят — поэтому ВСЕ статические проверки +молчат. Падают ровно «тронутые git» файлы; нетронутые (LF) проходят. Закоммиченный код при этом LF +и корректен — CRLF живёт только в рабочем дереве (артефакт autocrlf). + +**Диагностика (чтобы не потерять часы):** + +1. `node --check` / `esbuild` / `node -e "import('./f.mjs')"` зелёные, а vitest красный → подозревай + НЕ синтаксис, а кодировку/переносы. +2. Читай СЫРЬЁ как Buffer (utf8-чтение СРЕЗАЕТ ведущий BOM и не видит CRLF через `charCodeAt`): + `node -e "const b=require('fs').readFileSync('tools/f.mjs'); console.log(b.includes('\r\n'), b.slice(0,3).toString('hex'))"`. +3. Подтверди: конвертни файл CRLF→LF и перепрогони — зелёный = это оно. + +**Лечение (насовсем).** `.gitattributes` в корне: `* text=auto eol=lf` (git хранит и выдаёт LF +независимо от `core.autocrlf`). Разовая нормализация рабочего дерева — `node`-скрипт +`...replace(/\r\n/g,'\n')...` по всем `.mjs`, либо `git add --renormalize <безопасные-пути>` (НЕ всё: +`.claude/settings.json` под стеной-off трогать нельзя). + +**Мета-урок.** «SyntaxError без позиции» + «статика чистая, vitest красный» = почти всегда +CRLF/кодировка, а не логика. Проверь байты и переносы ПЕРВЫМ делом, а не последним.