openjutsu
One-click character swap for videos: an open-source, local Higgsfield Genjutsu alternative built on ComfyUI and MiniMax H3, with FLUX.3 Klein relighting.
Свежие новости без повторов, в двух предложениях
Translation pending
MediaTypeScript · CSSGitHub @disbagOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
AI-агрегатор новостей: RSS с 30+ изданий → саммари на русском через Gemini/Groq → дедупликация одинаковых новостей по эмбеддингам, Next.js фронтенд
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗Агрегатор: RSS 63 изданий → пересказ на русском → одна карточка на новость, сколько бы изданий о ней ни писали → треды для продолжающихся историй. Лента одной колонкой в духе редакторских журналов.
Продакшен: сайт на Vercel (dub1), база Supabase Postgres с pgvector (eu-west-1), сбор в GitHub Actions. Состояние каждого издания — в ../issues.md.
npm install
cp .env.example .env # заполнить переменные из таблицы ниже
npm run db:init # схема БД и издания из конфига
npm run fetch # собрать новости за последние сутки
npm run dev # http://localhost:3000
| Переменная | Где | Что |
|---|---|---|
DATABASE_URL | сайт, сбор | Postgres с pgvector |
RP_ORIGIN | сайт | адрес сайта для ссылок в превью |
SESSION_SECRET | сайт | проверка старых кук входа — до 24 января 2027 (см. src/lib/viewer.ts) |
THREADS_VIEW | сайт | 1 — лента с тредами (включено на проде; на preview-выкладках всегда) |
GEMINI_API_KEYS | сбор | ключи Google AI Studio через запятую, у каждого своя бесплатная квота |
GEMINI_MODELS | сбор | модели через запятую, в порядке перебора |
GROQ_API_KEY | сбор | запасная модель |
RETENTION_DAYS | сбор | сколько дней хранить статьи (7) |
DEDUPE_THRESHOLD | сбор | порог склейки по тексту (0.75) |
Для ручных прогонов: FETCH_SOURCES="Dezeen,Esquire" — только эти издания, FETCH_SINCE_DAYS=1 — окно на сутки шире, FETCH_LIMIT=N — не больше N статей, THREADS_SHADOW=0 — без раскладки по тредам.
После первого прогона с диагностикой сбор автоматически проверяет неизвестные ссылки за последние 72 часа, чтобы подхватывать запоздалые элементы RSS. Внутри каждого фида сначала идут статьи за последние сутки; догрузка ограничена 10 попытками на издание (суммарно для всех его фидов) и 50 на прогон. Лимиты применяются и к неудачным попыткам, чтобы не расходовать квоту на бесконечные повторы. Уже известные и окончательно отклонённые ссылки пропускаются. Ручной FETCH_SINCE_DAYS сохраняет прежнее поведение и не ограничивается бюджетом автоматической догрузки. Для Fast Company исходные ISO-даты без зоны явно трактуются как UTC через feedDateOffset в конфиге.
Каждый обработанный фид оставляет строку SOURCE_DIAGNOSTIC в логе: HTTP-статус, тип ответа, возраст CDN-кэша, SHA-256 RSS, свежесть элементов, число известных/сохранённых/отложенных ссылок, причины исключения и ошибки. При аномалии сохраняется снимок до 10 элементов с заголовками, ссылками, исходными датами и решениями — без полного текста RSS или дополнительных запросов к изданию. В GitHub запись содержит workflowRunId. Диагностика сохраняется одной пачкой за прогон в source_fetch_diagnostics; суточные счётчики по Москве — в source_volume_daily. Обе истории живут 56 дней независимо от очистки статей. Новые таблицы создаются db:init или автоматически при первом сборе из db/fetch-diagnostics.sql; ошибка диагностики выводится в лог и не останавливает сбор.
src/jobs/fetchAndProcess.ts)Запуск — каждые 30 минут через cron-job.org, который вызывает workflow_dispatch у .github/workflows/fetch-cron.yml; расписание в самом workflow — запасное. Прогон идёт 1–10 минут.
src/lib/adFilter.ts и правила издания), лайв-блоги и виды материалов, заданные в конфиге издания (src/config/sources.ts).src/lib/ogTags.ts). Текст — селектор издания, JSON-LD или абзацы страницы; у части изданий — сразу из RSS. Галерея — по правилам GALLERY_SITES для движка издания. Страницы NYT, WSJ и Bloomberg закрыты всегда и не запрашиваются; если страница закрыта, карточка строится по RSS.src/lib/embeddings.ts) — локально, Xenova/all-MiniLM-L6-v2: вектор заголовка с текстом и отдельно заголовка. Считаются от оригинала: пересказ стирает различия между похожими новостями.src/lib/grouping.ts). Статья сравнивается с первыми статьями карточек за 24 часа: первые 12 часов — по тексту или заголовку, дальше — только другие издания и строже. Запасные правила: парный материал издания, одновременные новости, общее имя в заголовке, одна и та же обложка.src/lib/summarizer.ts, промпты — src/lib/prompt.ts). Один запрос: главное, продолжение под «Читать» (если текста хватает) и до двух тем. Спорт и shopping в ленту не идут. Статья, приклеенная к готовой карточке, к модели не идёт.visible_at); статьи старше RETENTION_DAYS удаляются вместе с карточкой.src/lib/threads.ts). Новые карточки сравниваются с карточками за 72 часа (похожий заголовок или редкое имя в пересказе); модель решает, продолжение ли это той же истории, и пишет, что нового. Тред — одно событие и его прямые последствия, не больше 6 карточек; похожие треды модель сверяет и сливает. Ручные решения «не в этот тред» хранятся в thread_exclusions.Модели. Gemini (src/lib/gemini.ts) перебирает пары модель+ключ: при 429 — следующий ключ, при перегрузке — другая модель; последняя удачная пара запоминается в .gemini-state.json. Если Gemini недоступен везде — минута паузы, затем 3 минуты на Groq (суточный лимит 200 тыс. токенов, общий для всех прогонов). Кончились оба — прогон останавливается.
Отчёт о состоянии (src/jobs/healthReport.ts, DIS-81) — каждый день в Telegram: его отправляет первый прогон сбора после 10:00 по Москве (шаг в fetch-cron.yml, метка в кэше — раз в сутки; расписание GitHub пропускало запуски), вручную — health-report.yml (TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID в секретах GitHub). Ошибки сбора, RSS и обработки проверяются за последние сутки; объём статей, обложки, галереи и «Читать» — за предыдущий полный день по Москве. Для объёма используются два и более предыдущих таких же дня недели либо минимум три сопоставимых будних/выходных дня; пока истории недостаточно, отчёт это указывает. Отсутствие свежих публикаций в RSS само по себе не считается технической ошибкой: такие наблюдения перечисляются отдельно. Повторный отказ RSS, пустой фид, нераспознанные даты и сбой обработки различаются. Длинный отчёт разделяется на сообщения по границам строк. --dry не отправляет Telegram-сообщения и не изменяет БД.
app/)app/page.tsx, FeedList.tsx, FeedCard.tsx; данные — src/lib/feed.ts, JSON — GET /api/feed. Рубрики, вкладки «Новые» и «Прочитанные», плашка «N Новых», открытие с места, где читатель остановился. Карточка становится прочитанной через 2,5 секунды на экране.src/lib/imageHash.ts)./post/<номер статьи> с превью для мессенджеров./source/<слаг> (DIS-80): все карточки, где есть его статья, без вкладок и тредов; открывается по иконке издания в карточке.--chrome-offset, MobileChrome.tsx).app/manifest.ts) — с экрана «Домой» открывается на весь экран; viewport-fit=cover и отступы env(safe-area-inset-*); цвет статус-бара по теме (theme-color, theme.ts); без серой вспышки при тапе, :hover только при мыши, отклик на нажатие и запрет выделения у кнопок (globals.css)./api/image-proxy (только адреса из базы, до 15 МБ); если прокси не справился, браузер грузит напрямую.middleware.ts выдаёт куку yoten_browser со случайным номером на 400 дней, прочитанное и выключенные издания хранятся в базе под его хешем (src/lib/viewer.ts). Строка в users заводится при первой отметке или переключателе; браузеры, не заходившие год, удаляются при сборе./settings), тема и размер текста (/settings/display).| Команда | Что делает |
|---|---|
npm run fetch | сбор |
npm run threads | разложить по тредам непроверенные карточки (THREADS_SINCE_HOURS, по умолчанию 24) |
npm run db:init | применить db/schema.sql и добавить издания из конфига |
npm run favicons | скачать иконки новых изданий (-- --force — все заново) |
npm run feed | вывести ленту в консоль |
npm run health | отчёт о состоянии в Telegram (-- --dry — только напечатать) |
npm run dev / build / start | сайт |