Как я сделал расширение для навигации по длинным AI-чатам
Я часто использую AI-чаты для ресёрча: в транспорте, перед сном, чтобы набросать идеи. Проходит время — и я уже не помню, где именно в длинном чате задавал нужный вопрос. Начинается бесконечный скролл. Это раздражало меня достаточно долго, чтобы в итоге я решил это починить.
Проблема
Если вы активно пользуетесь ChatGPT, Claude или Perplexity, то наверняка сталкивались с этим: длинный чат превращается в бесконечную простыню. Вы помните, что где-то в начале задавали важный вопрос — но чтобы найти его, нужно скроллить минуту-две. Браузерный Ctrl+F ищет по всему тексту, включая ответы ИИ, и не очень помогает когда нужно найти именно ваше сообщение.
Нативной навигации по сообщениям ни в одной из платформ нет. Мне хотелось простую вещь: список моих сообщений сбоку, клик — и страница прыгает к нужному месту.
Решение: AI Chat Messages Toolkit
Я сделал Chrome-расширение, которое решает именно эту задачу. Оно добавляет боковую панель и кнопку в тулбаре браузера. В них отображается список всех ваших сообщений в текущем чате — первые 10 слов каждого, чтобы было понятно, о чём речь. Кликаете на любое — страница плавно скроллится к нему и на секунду подсвечивает нужный блок.
Поддерживаются пять платформ: ChatGPT, Claude, Perplexity, Gemini и Microsoft Copilot.
Никаких серверов, никакой аналитики, ничего никуда не отправляется — всё работает локально прямо в браузере.
Технические детали
Manifest V3 и контентные скрипты
Расширение построено на Manifest V3 — актуальном стандарте Chrome-расширений. Пять скриптов инжектируются на страницу в строгом порядке:
config.js → utils.js → messages.js → panel.js → content.js
Порядок важен: каждый следующий файл использует функции из предыдущих. Поскольку модули ES в контентных скриптах не поддерживаются в полной мере, все утилиты живут в глобальном скоупе и доступны между файлами без импортов.
Адаптация под каждую платформу
Главная техническая сложность — у каждой AI-платформы своя DOM-структура, и она периодически меняется. Для каждого сайта в config.js описан конфиг с CSS-селекторами:
'chatgpt.com': {
messageContainerSelector: '[data-turn="user"]',
textSelector: '.whitespace-pre-wrap',
editCounterSelector: '[aria-label="Previous response"] + div',
extractText: (el) => el.textContent
}
Когда платформа обновляет вёрстку, достаточно поправить один селектор в конфиге — остальная логика остаётся нетронутой. Это позволяет поддерживать пять совершенно разных сайтов, не дублируя код.
Отслеживание изменений через MutationObserver
AI-чаты — это SPA (Single Page Application). Новые сообщения появляются без перезагрузки страницы, а переходы между чатами не вызывают навигацию в классическом смысле. Чтобы список сообщений всегда был актуальным, используется два механизма.
MutationObserver следит за DOM и реагирует только на появление элементов, соответствующих messageContainerSelector. Мутации внутри самой панели расширения игнорируются, чтобы не создавать бесконечный цикл обновлений.
Перехват history API — для отслеживания SPA-навигации оборачиваются нативные методы history.pushState и history.replaceState:
const originalPushState = history.pushState;
history.pushState = function(...args) {
originalPushState.apply(history, args);
setTimeout(() => {
if (detectChatChange()) {
scheduleUpdate();
setupMessageObserver();
}
}, 500);
};
Обновления дебаунсятся с задержкой 300 мс, чтобы не перегружать браузер при быстром изменении DOM.
Попап и контентный скрипт: общение через сообщения
Попап тулбара и контентный скрипт живут в разных контекстах и не имеют прямого доступа к переменным друг друга. Они общаются через chrome.runtime.sendMessage / chrome.tabs.sendMessage:
- Попап отправляет
getUserMessages→ контентный скрипт возвращает массив сообщений - Попап отправляет
scrollToMessageс индексом → контентный скрипт скроллит страницу - Контентный скрипт отправляет
messagesChanged→ попап обновляет список
Это стандартная модель общения в Chrome-расширениях, но важно правильно обрабатывать случаи, когда вкладка ещё не инициализировала контентный скрипт — иначе попап будет крашиться при первом открытии.
Локализация на 18 языков
Все строки интерфейса хранятся в _locales/<lang>/messages.json и загружаются через chrome.i18n.getMessage(). Расширение доступно на 18 языках: английский, русский, украинский, немецкий, французский, испанский, польский, итальянский и другие. Chrome подхватывает нужный язык автоматически по настройкам браузера.
Лендинг и продвижение
Параллельно я сделал лендинг с описанием основных фич. Это было нужно по нескольким причинам: при регистрации в Chrome Web Store требуется указать сайт, политику приватности и контакт для обратной связи. Плюс хотелось попробовать как-то продвинуть расширение.
Добавил страницу поддержки проекта — но пока туда особо никто не заходит. Это честно.
Где взять
Расширение доступно в Chrome Web Store и работает во всех Chromium-браузерах: Chrome, Edge, Brave.
Подробнее о функциях можно почитать на лендинге расширения.
Если вы тоже тонете в длинных AI-чатах — попробуйте. Мне самому оно реально помогает каждый день.