- text-normalize.ts: closestBlockHint был вставлен между docstring'ом
stripInlineMarkdown и его определением -> docstring осиротел. closestBlockHint
перенесён ПОСЛЕ stripInlineMarkdown, каждый docstring снова примыкает к своей
функции. Поведение не менялось (только порядок объявлений).
- comment-anchor.ts: header-коммент завышал маршрутизацию — countAnchorMatches НЕ
зовёт resolveAnchorSelection, у него своя параллельная реализация exact-wins.
Коммент уточнён: can/get/apply идут через resolveAnchorSelection, count держит
свой счётчик-примитив, синхронный с ним; обе реализации exact-wins должны
держаться в синхроне при правках.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
createComment — топ-хотспот ошибок агента (промахи по якорю, слепые ретраи).
Портированы аффордансы самокоррекции из editPageText:
- Closest-block hint: общий хелпер closestBlockHint вынесен в text-normalize.ts
(json-edit.ts теперь тоже его зовёт), подключён во все 3 throw-а createComment.
- Markdown-strip fallback в comment-anchor.ts согласованно по всем 4 функциям
(can/count/apply/get) через единый resolveAnchorSelection: exact-verbatim wins
глобально, stripped — только если raw не якорится нигде; soft warning как в
editPageText. Инвариант уникальности suggestion (0/1/>=2) сохранён: raw-unique
никогда не запускает fallback -> не может стать ambiguous. Хранимый selection
остаётся СЫРОЙ подстрокой документа (strip только для поиска).
- Multi-block detection: явное сообщение 'selection spans multiple blocks' когда
per-block поиск провалился, но выделение есть в объединённом тексте блоков.
- tool-spec createComment: копировать selection дословно из getPage/searchInPage.
Известное мелкое ограничение (нит внутреннего ревью): детектор multi-block
использует raw selection, поэтому markdown-стилизованное выделение через границу
блоков получит generic-подсказку вместо spans-multiple-blocks (редко, guidance
всё равно корректный).
closes#408
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>