Стабилизация, итерация 8: конвертер — block-escape, атрибутный contract-тест, дедуп зеркал (один PR, 7 коммитов) #493
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Один PR. Зависимостей от других итераций нет. Связано с #347 (клиентские markdown-пути — отдельная работа, там же browser-entry). Координаты — develop@363f20ab.
Коммит 1 — fix(converter): block-escape параграфа — незакрытый класс потерь данных
packages/prosemirror-markdown/src/markdown-converter.ts:414-430: строка параграфа, начинающаяся с#/-/>/1./|/фенса/---, на round-trip превращается в другой блок или теряет текст. Класс известен и ОБХОДИТСЯ, а не чинится: генератор property-тестов сознательно не выдаёт такие строки (text-arbitraries.ts), bridge вставляет ZWSP-хак (gitmost-recording.ts:292-296) — workaround расползается по потребителям.Правка: экранировать блочные триггеры в начале каждой строки параграфа при сериализации (
\\#,\\-,\\>,1\\.— стандартный приём CommonMark-сериализаторов). Затем: удалить ZWSP-хак, снять самоцензуру в text-arbitraries — генеративный suite сам докажет закрытие класса. Пины на каждый триггер.Коммит 2 — test(converter): атрибутный contract-тест схем
schema-editor-ext-contract.test.ts:19-25сравнивает только ИМЕНА нод — дрейф атрибутов (класс, породивший потерюsubpages.recursive) CI не ловит. Правка: сравниватьspec.attrs(имена + дефолты) каждой ноды/марки обеих схем (~30 строк).Коммит 3 — fix(converter): warnings вместо тихой потери
markdown-converter.ts:520-596: незнакомые марки/ноды теряются молча. Default-ветка → накапливать warnings (паттернfootnoteWarningsуже есть) и отдавать наружу; в git-sync и тестах — strict-режим (warning = ошибка).Коммит 4 — refactor(converter): normalizeForeignMarkdown → в пакет
Нормализация GFM-сносок
[^id]/front-matter живёт только в apps/server → MCPupdatePageMarkdownтот же ввод обрабатывает иначе, чем серверный импорт. Перенести в@docmost/prosemirror-markdown, вызывать вmarkdownToProseMirrorCanonical.Коммит 5 — refactor(converter): дедуп зеркал footnote/stripInlineMarkdown/glyph
footnote-canonicalize.ts×2 (+1255-строчный корпус-зеркало),text-normalize.ts:95×2, glyph-карты ×2. Перенести canonicalizeFootnotes и stripInlineMarkdown в канонический пакет; editor-ext и mcp импортируют; корпус остаётся один.Коммит 6 — fix(mcp): resolved-якоря переживают полный write
Read-путь прячет resolved-спаны (#337), write-путь (
updatePageMarkdown) верит markdown агента дословно → full-write стирает resolved-марки. Правка: пере-прививать resolved-марки из старого дока на совпадающие текстовые диапазоны (механика анкоринга уже есть в comment-anchor). Альтернатива «отдавать resolved-спаны в get_page» отвергнута — ломает чистоту read-пути.Коммит 7 — refactor(import): унификация путей импорта .md
file-import-task.service.ts:477-480: zip-путь идёт через PM→HTML→PM-хоп, API-путь — прямой (import.service.ts:148). Унифицировать на прямой («architecture B» уже помечена в коде как план).