Context7: свежайшая документация оказалась… устаревшей?

—

от автора

Или, как один простой вопрос неожиданно превратился в микро-расследование.

Познакомиться с новым сервисом или инструментом разработки можно многими путями, от рассказа знакомого до оплаченного разработчиком рекламного блока. Впечатлившись предлагаемыми возможностями, вы, конечно же, захотите протестировать новинку, прежде чем встраивать ее в ваши привычные процессы. Тут-то и может подстерегать сюрприз.

Опуская неинтересную предысторию, нынешнее утро застало меня на сайте Context7 — MCP-сервера, обещающего всегда актуальную документацию для огромного количества фреймворков, языков и библиотек.

Image description

Image description

Впечатляет и вдохновляет. Введенное “wordpress” в поле поиска показало вполне приемлемую картину обновлений. Обратите внимание на третью строку, где мы видим, собственно, официальный репозиторий WordPress (точнее, его зеркало с subversion).

Image description

Image description

Руки уже потянулись к клавиатуре для установки, как вдруг внимание привлек скромный пункт “Try live” в меню. Что ж, а почему бы и нет? Открываем чат и задаем простейший вопрос: “Последний известный релиз WordPress”.

Image description

Image description

ИИ последовательно просмотрел несколько пакетов документации (причем /wordpress/wordpress среди них не было) и… сообщил, что последняя известная ему версия WordPress — это 6.7 “Rollins”, вышедшая в ноябре 2024. Эй, а как же “up-to-date” и “version-specific”?! Впрочем, в чате заботливо рассказывают, как узнать версию самостоятельно, но, согласитесь, это несколько не то.

Что ж, возможно, вопрос и в самом деле был некорректен. Попробуем конкретизировать. Спросим об основных отличиях между 6.9 и 7.0, там как раз было одно маленькое, но очень важное изменение, детали которого потребовались мне в проекте. Спрашиваем.

Image description

Image description

Хм… Кажется, и этот вопрос останется без ответа. Хотя, казалось бы, именно на подобные вопросы должна отвечать “version-specific” документация. Теперь мне уже стало интересно: продолжим конкретизировать.

Image description

Image description

Что ж, ИИ прав: вопрос был с подвохом, такой функции в WordPress действительно нет, это метод класса. Ложноположительного срабатывания я не получила. Спросим сразу об интересующем нас filter.

Image description

Image description

Хорошо, мы получили информацию о filter. Единственный момент, который настораживает: доступность фильтра указана с версии 5.6. Впрочем, вернемся к этому немного позже, сначала хорошо бы уточнить информацию о методе, где применяется этот filter. Здесь начинается самое интересное, привожу конкретный код, показанный в ответе:

public function get_page_cache_headers(): array {    $cache_hit_callback = static function ( $header_value ) {        return 1 === preg_match( '/(^| |,)HIT(,| |$)/i', $header_value );    };    $cache_headers = array(        // Standard HTTP caching headers.        'cache-control'     => static function ( $header_value ) {            return (bool) preg_match( '/max-age=[1-9]/', $header_value );        },        'expires'           => static function ( $header_value ) {            return strtotime( $header_value ) > time();        },        'age'               => static function ( $header_value ) {            return is_numeric( $header_value ) && $header_value > 0;        },        'last-modified'     => null,        'etag'              => null,        'via'               => null,        // Vendor/custom headers (ported from AMP plugin → Performance Lab → core).        'x-cache-enabled'   => static function ( $header_value ) {            return ( 'true' === strtolower( $header_value ) );        },        'x-cache-disabled'  => static function ( $header_value ) {            return ( 'on' !== strtolower( $header_value ) );        },        // Cloudflare.        'cf-cache-status'   => $cache_hit_callback,        // Fastly.        'x-cache'           => $cache_hit_callback,        // LiteSpeed.        'x-litespeed-cache' => $cache_hit_callback,    );    return $cache_headers;}

На первый взгляд, выглядит достоверно. Но только на первый. Вернемся к основному вопросу — об отличиях версий 6.9 и 7.0 и вспомним про декларируемую доступность фильтра с версии 5.6. Зайдем в релизы репозитория /wordpress/wordpress на Github и выберем сравнение двух веток: 6.9.7 и 7.0.4. Нас интересует коммит, затрагивающий метод get_page_cache_headers. Для наглядности приведем код метода целиком, включая аннотации:

/** * Returns a list of headers and its verification callback to verify if page cache is enabled or not. * * Note: key is header name and value could be callable function to verify header value. * Empty value mean existence of header detect page cache is enabled. * * @since 6.1.0 * * @return array List of client caching headers and their (optional) verification callbacks. */public function get_page_cache_headers() {$cache_hit_callback = static function ( $header_value ) {return str_contains( strtolower( $header_value ), 'hit' );};$cache_headers = array('cache-control'          => static function ( $header_value ) {return (bool) preg_match( '/max-age=[1-9]/', $header_value );},'expires'                => static function ( $header_value ) {return strtotime( $header_value ) > time();},'age'                    => static function ( $header_value ) {return is_numeric( $header_value ) && $header_value > 0;},'last-modified'          => '','etag'                   => '','x-cache-enabled'        => static function ( $header_value ) {return 'true' === strtolower( $header_value );},'x-cache-disabled'       => static function ( $header_value ) {return ( 'on' !== strtolower( $header_value ) );},'x-srcache-store-status' => $cache_hit_callback,'x-srcache-fetch-status' => $cache_hit_callback,// Generic caching proxies (Nginx, Varnish, etc.)'x-cache'           => $cache_hit_callback,'x-cache-status'    => $cache_hit_callback,'x-litespeed-cache' => $cache_hit_callback,'x-proxy-cache'     => $cache_hit_callback,'via'               => '',// Cloudflare'cf-cache-status' => $cache_hit_callback,);/** * Filters the list of cache headers supported by core. * * @since 6.1.0 * * @param array $cache_headers Array of supported cache headers. */return apply_filters( 'site_status_page_cache_supported_cache_headers', $cache_headers );}

Кое-что удивляет, не правда ли? @since в аннотациях указывают на доступность и фильтра, и функции с версии 6.1.0, а вовсе не 5.6. Также определение $cache_hit_callback выглядит намного проще показанного в Context7 и массив $cache_headers отличается как по группировке, так и по составу. Давайте-ка скачаем архив релиза 5.6.19!

Поиск по содержимому файлов релиза 5.6.19 показывает отсутствие и метода get_page_cache_headers, и фильтра site_status_page_cache_supported_cache_headers где бы то ни было в коде. Идем в репозиторий, находим файл wp-admin/includes/class-wp-health.php и смотрим его историю редактирования. Находим коммит, добавивший функцию get_page_cache_headers. Убеждаемся, что никакого preg_match( '/(^| |,)HIT(,| |$)/i', $header_value ) там нет.

Немного позже находим и коммит, где false !== strpos( ... ) заменяется на str_contains() и далее никаких изменений с этим блоком кода не происходит.

Проделав аналогичные манипуляции с кодом, можно также убедиться, что и написание массива заголовков в любой версии реального файла отличается от показанного в чате Context7. Более того, ИИ не знает о наличии в этом массиве таких заголовков как x-srcache-store-status, x-srcache-fetch-status и x-proxy-cache, а вместо заголовка x-cache-status предлагает использовать x-cache-enabled и x-cache-disabled.

Можно возвразить, что это очень узкоспециализированный вопрос, крайне редко используемые данные и так далее. Однако люди создают не только темы, но и плагины для экосистемы WordPress, в том числе расширяющие штатный функционал. И кэш-решения занимают отнюдь не последнее место по популярности.

Не оспариваю полезность Context7, для этого у меня слишком мало опыта работы с ИИ. Но, надеюсь, получилось подсветить в статье потенциальные проблемные места этого решения, как минимум для WordPress-разработчиков.

ссылка на оригинал статьи https://habr.com/ru/articles/1071634/