Skip to content

Latest commit

 

History

History
72 lines (54 loc) · 14.1 KB

File metadata and controls

72 lines (54 loc) · 14.1 KB

Diode — терминальный текстовый редактор (клон VS Code) на TypeScript/Node.js. Цели и неизменяемые ограничения — в GOAL.md, не забывай его читать.

Карта документации

  • GOAL.md — цели проекта и non-negotiable constraints
  • docs/VISION.md — позиционирование: активы, ограничения реальности, направления, текущая ставка
  • docs/ARCHITECTURE.md — концептуальная карта: обзор слоёв + правила зависимостей (единственный источник правды по слоям)
  • docs/arch/ — детальный per-layer справочник (по файлу на слой: Common.md, Editor.md, Extensions.md, …)
  • docs/DI.md — справочник по DI-контейнеру (токены, модули, профили)
  • docs/arch/State.md — машинное состояние UI/сессии (StateService, аналог IStorageService/Memento)
  • TUIDom (движок TUI) — отдельный репозиторий github.com/tuidom/tuidom, пакеты @tuidom/* (core, elements, terminal-backend, headless-backend, inspector, testing); его доки (LAYOUT.md, STYLES.md, arch/) живут там
  • docs/TESTING.md — как тестировать каждый слой; скриншот-демо для визуальных фич
  • docs/COMMITS.md — правила коммитов (Conventional Commits, changelog)
  • docs/PR.md — скриншот-демо для визуальных фич и как приложить PNG к PR
  • docs/TODO/ — трекер задач (индекс — README.md)

Трекер задач

Текущие задачи и планы ведём в docs/TODO/. Индекс — docs/TODO/README.md, крупные задачи — в отдельных файлах. Когда берёшь задачу в работу, поменяй статус на [~]. Когда закончил — на [x].

Worktree

Любую задачу, которую мы начинаем с этапа планирования, ведём в отдельном git worktree — заходи в него через инструмент EnterWorktree до начала работы. Исключение одно: если пользователь явно сказал не использовать worktree для этой задачи.

Все worktree живут только в .claude/worktrees/<имя> (дефолтная раскладка EnterWorktree). Не создавай их где-либо ещё — ни в соседнем ../<repo>.worktrees/, ни в произвольном каталоге. Каталог .claude/worktrees/ в .gitignore, поэтому рабочее дерево репозитория не засоряется.

В итоге по задаче всегда указывай полный путь к worktree, где она сделана — пользователь оттуда запускает и проверяет.

Архитектура

Перед началом работы прочитай docs/ARCHITECTURE.md — там описана структура каталогов, слои и правила зависимостей. Если ты перемещаешь файлы, добавляешь новые каталоги или меняешь зависимости между слоями — обнови docs/ARCHITECTURE.md.

Style

Не запускай и не исправляй ошибки линтера. Просто не забывай использовать расширения в имени файла при импорте Приватные переменные давай не будем писать с подчеркиванием. Используй просто название и модификатор

Коммиты и PR

  • Правила коммитов (Conventional Commits, что попадает в changelog) — docs/COMMITS.md.
  • Скриншот-демо для визуальных фич и как приложить PNG к PR — docs/PR.md. Любая фича с видимой/внешней составляющей обязана принести сценарий-демо и скриншот в PR. Это не формальность: в #194 пропущенный сценарий стоил бага, который виден на первом же кадре. Сценарию, которому нужно стоковое расширение, отдай installVsix (см. e2e/scenarios/regionFolding.scenario.ts).

Что считать «готово»

Урок #194/#195: фича может быть зелёной по тестам и по покрытию, и при этом не работать в приложении совсем. Гейты ниже — про то, чтобы тест смотрел туда же, куда смотрит пользователь.

  • Покрытие — не сигнал DoD. Храповик 100% в vitest.config.ts ловит регрессии в написанном коде и по устройству слеп к ненаписанному. Пропущенный продюсер события и недостающее условие в отрисовке дают 100% покрытия и нерабочую фичу. «Добил покрытие» ≠ «фича работает».
  • Перед сдачей фичи — npm run test:mutation. Вторая половина храповика: покрытие говорит «строка исполнилась», мутационный балл — «кто-то её проверил». Тест без осмысленного ассерта даёт 100% покрытия и 11% мутационного балла (замерено). Выжившего мутанта либо убиваем тестом, либо гасим // Stryker disable next-line <мутатор>: причина — но не ассертом ради балла. Детали → docs/TESTING.md.
  • Тестируй наблюдаемый результат, а не шов, который только что написал. Ассерт на структуру, в которую фича пишет (viewState.foldedRegions), не видит бага в том, кто её читает (рендер). Если у фичи есть видимая часть — тест обязан дойти до кадра.
  • На каждое новое RPC-сообщение — тест продюсера. «Субпроцесс умеет разобрать сообщение» покрывает половину контракта. Вторая половина — «кто и по какому событию его шлёт»; именно она отсутствовала, и activeTextEditor.selection навсегда залипал на (0,0).
  • Фича поверх стокового расширения закрывается стоковым расширением. Поднять настоящий .vsix мало — надо дёрнуть его настоящую функциональность (команду, провайдер) из пользовательского состояния (курсор подвинут, текст выделен) и проверить результат. Фикстура, выведенная из своей же реализации, проверяет ровно то, что и так работает.
  • Запусти приложение. Харнесс фейкает рендер и ввод — то есть ровно те две области, где баги и живут. Перед «готово» — реальный запуск (npx tsx src/vs/diode/main.ts --user-data-dir=<tmp> --headless=WxH --inspect-tui=…) и взгляд на кадр.

Правила разработки

Сквозные конвенции, которые надо держать в голове. Полные формулировки — в детальных arch-доках по ссылкам.

  • Ограничения tuidom НЕ обходим — останавливаемся. Движок приходит пакетами @tuidom/* из npm; если фиче не хватает возможности движка или виджета (нет API/хука, поведение не параметризуется, виджет не расширяется штатным наследованием с нашей стороны) — это стоп-сигнал: разработку фичи в diode приостановить и поднять вопрос пользователю; недостающее делается в репозитории tuidom (/workspaces/tuidom/tuidom, github.com/tuidom/tuidom) и приезжает новой версией пакета. Запрещённые обходы: копировать куски движка в diode, monkey-patching и лазанье в приватные поля (as any, @ts-expect-error), дубликат виджета у нас ради недостающего хука, пост-обработка отрендеренного grid'а в обход каскада. Тест-обходы — тоже обходы.
  • Цвета — виджеты и компоненты ссылаются на ИМЕНА токенов темы в style/styleVar (палитру кладёт в корневой var-scope WorkbenchComponent); прямые чтения theme.getColor/getRequiredColor — только для не-виджетных потребителей (токен-темы синтаксиса, декорации). Никаких RGB-литералов и инлайн-фоллбэков; дефолты токенов tuidom — единственно в dom/styles/styleTokens.ts пакета @tuidom/core (репозиторий tuidom). Новый цвет — определение { defaults: { dark, light }, description } в группе своей области в src/vs/platform/theme/common/colors/. Детали → STYLES.md (tuidom), docs/arch/Theme.md.
  • Рост vscode.d.ts — файл запиннен к тегу upstream (шапка + extensions/VSCODE_VERSION, держи в лок-степе). Активная поверхность — это дословно раскомментированные строки нижней (закомментированной) копии; единственная ручная правка файла — снятие // , ничего не сужать/переписывать/переоформлять. Тянет незакомментированный тип — раскомментируй и его, либо отложи блок; для «тяжёлых» блоков допускается bounded member-level uncommenting (раскомментировать подмножество членов). Дормантную часть регенерирует scripts/import-vscode-dts.mjs; апдейт upstream — ручной трёхсторонний merge против запинненной базы. Детали → docs/arch/Extensions.md.
  • Перенесённый diff-движокsrc/vs/editor/common/diff/, часть src/vs/editor/common/core/ и src/vs/base/common/charCode.ts — это дословная копия upstream vscode, а не наш код. Правится только через scripts/import-vscode-diff.mjs (сменой пина или объявленной там трансформации), ручные правки запрещены — их снесёт ближайшая регенерация, а --check покажет дрейф. Шимы в base/common (arrays, assert, errors, map, strings, …) — наоборот, наш код: расширяются руками по мере надобности и покрываются тестами. Детали → docs/ARCHITECTURE.md, план фичи → docs/TODO/Diff.md.
  • DI — токены именуются *DIToken; токен объявляется рядом со своим типом (слой токена = слой типа, проверяет valid-layers-check); tuidom/ токенов не объявляет и diContainer не импортирует. Детали → docs/ARCHITECTURE.md.
  • Система команд — ID команд, отражающих VS Code Workbench/Editor, именуются в стиле VS Code; доступность — через typed when-контексты из ContextKeys.ts. Детали → docs/arch/Workbench.md.

Файловая структура

Раскладка — vscode-канон src/vs/* (две оси: слои base→tui→base/browser→platform→editor→workbench→diode и окружения common/browser/node; карта — docs/ARCHITECTURE.md, проверка — npm run valid-layers-check). Имена файлов — camelCase, как у vscode: tuiElement.ts, menuRegistry.ts; файл называется по главному экспорту.

Файлы с тестами не должны быть слишком большими — у нас может быть много кейсов, поэтому тесты пишем не в одном файле, колокацией рядом с кодом:

Если файл один, то структура такая:

tuiElement.ts tuiElement.test.ts

А если больше, то можно делать подразделы

tuiElement.ts tuiElement.events.test.ts