2a660687a0
canUndo/canRedo в use-toolbar-state читали приватные внутренности y-undo (undoManager.undoStack.length / redoStack.length). Апгрейд yjs / y-undo, переименовавший или перестроивший эти поля, тихо сломал бы состояние кнопок undo/redo (или упал бы на .length у undefined) без единой ошибки. Оставляем дешёвое чтение длины стеков (сознательно не используем дорогой editor.can().undo()/.redo(), который делает dry-run на каждый keystroke, см. комментарий в файле), но теперь feature-detect: доверяем стекам только если это реально массивы, иначе откатываемся на безопасный дефолт (prosemirror-history undoDepth/redoDepth -> 0). Логика вынесена в чистую функцию yHistoryAvailability. Добавлен pin-test, фиксирующий текущую форму библиотеки: реальный Y.UndoManager по-прежнему отдаёт undoStack/redoStack массивами. Апгрейд, меняющий контракт, упадёт громко в тесте, а не тихо в UI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>