Журнал змін
GitHubКожна значуща зміна, реліз за релізом. Той самий файл постачається в репозиторії та перекладений усіма 19 мовами.
[1.115.0] — 2026-07-06
Шліфування дизайну (консервативне, кораловий бренд збережено). Легкий прохід удосконалення спільної дизайн-системи — без перебудови, без зміни палітри. Картки метрик на дашборді тепер трохи піднімаються та отримують коралову рамку при наведенні (як плитки швидких дій); картки контенту піднімаються ледь-ледь; кнопки primary / dark / danger отримують тінь у спокої та м’яке підняття при наведенні для глибини; великі числа вирівнюються через tabular-nums; а інтерактивні елементи отримують м’який кораловий ореол за чітким 2px-кільцем клавіатури. Уся анімація поважає prefers-reduced-motion, а ореол обмежено елементами керування — ніколи не глобальний *:focus-visible.
- Лише CSS (
public/css/app.css); без змін розмітки, i18n, маршрутів чи CSP. Тести:tests/design-polish-v1115.test.mjs(5). Перевірено вживу через Playwright.
Нове: немає.
[1.114.0] — 2026-07-06
Лічильник використання та вартості ШІ в бічній панелі (лівий нижній кут). Компактний розділ ВИКОРИСТАННЯ тепер розташований унизу бічної панелі (фіксована картка в лівому нижньому куті, якщо панелі немає; у правому нижньому для RTL) на кожній сторінці. Він показує використання токенів LLM за вікнами 24г / 7д / 30д — кожне як <токени> · <частка%> із зеленою смугою (частка від усього часу) — плюс підвал з оцінкою вартості за 24г. Дані — доступний лише для читання звід GET /api/usage із data/llm-usage.jsonl (лише локально), те саме джерело, що й сторінка #/usage; вартість оцінна, а запуски в ручному режимі безкоштовні й не враховуються. Згортається — заголовок перемикає, стан зберігається.
- Новий клієнтський віджет
public/js/lib/usage-hud.js, завантажується зindex.html, монтується в бічну панель над підвалом версії (запасний варіант — фіксований кут). Безпечний для CSP; з урахуванням теми та дзеркалом RTL. Без нового маршруту сервера. Тести:tests/usage-hud.test.mjs(8). 3 нові ключі i18n ×16.
Нове: немає.
[1.113.0] — 2026-07-06
Плаваючий помічник «Запитати довідку» на кожній сторінці. Градієнтна кнопка-робот із чатом тепер плаває в правому нижньому куті (у лівому нижньому для RTL) кожної сторінки. Натисніть, щоб відкрити компактний чат, який відповідає на питання щодо використання, спираючись ЛИШЕ на вбудовану довідку вашою мовою — той самий ендпоінт, що й сторінка #/docs-assistant (POST /api/docs-assistant/ask), тож він ніколи не читає ваше резюме, профіль чи трекер. Наживо з ключем LLM; без ключа → готовий промпт. У шапці — аватар-робот і статус онлайн; чипи підставляють часті питання; Escape або клік ззовні закриває; на сторінці #/docs-assistant кнопка прихована.
- Новий клієнтський віджет
public/js/lib/docs-fab.js, монтується глобально зindex.html; безпечний для CSP; стилі з урахуванням теми та дзеркалом RTL уapp.css. Без нового маршруту сервера. Тести:tests/docs-fab.test.mjs(8). 6 нових ключів i18n ×16. Довідка §1 розширена на місці.
Нове: немає.
[1.112.0] — 2026-07-06
Консолідація документації та QA. Без видимих користувачу змін коду. Документ угод SDD (docs/sdd/CONVENTIONS.md) оновлено до поточних 30 модулів маршрутів (було 24) та поточної базової лінії тестів; визначальний загальнопроєктний QA-промпт (qa/QA-REGRESSION-PROMPT.md) консолідовано — механіку релізу актуалізовано (v1.111, parentVersion 1.17.0, публікація за подією релізу), таблицю доповнень §14 виправлено («Виключити» в Scan перепозначено як v1.109.0) і доповнено закриттям CodeQL з v1.111 — тож він самодостатній як єдиний регресійний промпт для всієї функціональності. Додано один тест покриття для гілки завеликого завантаження.
Нове: немає.
[1.111.0] — 2026-07-06
Безпека — закриття беклогу CodeQL. Три посилення ешелонованого захисту, що закривають решту зауважень статичного аналізу в першопричині, а не через dismiss. stripDangerousMarkdown тепер екранує < у будь-якому усіченому відкритті небезпечного тега (навантаження, що закінчується на <script/<iframe/…), тож у виводі доказово не лишається живого небезпечного тега. Імпорт CV читає розмір завантаженого буфера через явне приведення Number() — бар’єр проти плутанини типів. Рядки ролі режимів тепер є шаблонними рядками, інтерпольованими через String.replace, а не збереженими функціями, що повністю прибирає виклик динамічної диспетчеризації. Видимої для користувача зміни поведінки немає.
server/lib/security.mjs,server/lib/cv-import.mjs,server/lib/prompts.mjs. Тести:tests/security-hardening-v1111.test.mjs(7) + оновлений тест-страж v1108. Без змін i18n/довідки/маршрутів.
Нове: немає.
[1.110.0] — 2026-07-06
Оновлення документації та QA (усі мови). Без змін коду. Повнопроєктний QA-промпт оновлено до v1.109.0 з новим §14 (v1.98→v1.109), а вічнозелені промпти UX-аудиту та design-export отримали поточний набір екранів. Кожен абзац довідки, доданий у v1.100–v1.109, тепер перекладено всіма 16 мовами.
Нове: немає.
[1.109.0] — 2026-07-06
Фільтр «Виключити» в Scan + огляд пайплайна (паритет з веб-версією). На #/scan поле Пошук тепер трактує коми як АБО («ролі для пошуку»), а нове поле Виключити ховає рядки, де компанія/роль/локація містить будь-яке слово через кому (напр. senior, staff); обидва запам’ятовуються у збережених пошуках. На #/pipeline компактна смуга огляду показує пайплайн з одного погляду — N у вхідних, N відстежується та лічильники Applied / Responded / Interview / Offer з трекера, кожен чип веде до #/tracker.
- Лише клієнт (без нового маршруту/записів).
public/js/views/scan.js+public/js/views/pipeline.js. Тести:tests/scan-pipeline-ui-v1109.test.mjs(2). 4 нові ключі i18n ×16. Довідка §7 + §8 розширені на місці.
Нове: немає.
[1.108.0] — 2026-07-06
Посилення безпеки (розбір CodeQL, раунд 2). Виправлено ще три знахідки низької серйозності: збирач промптів розв’язує рядок ролі локалі за власним ключем + typeof === function, щоб підроблена локаль не могла викликати метод прототипу (unvalidated-dynamic-method-call); slug імені PDF-файлу обмежено 200 символами до регулярки, щоб вхід з самих дефісів не відкочувався (поліноміальний ReDoS); а імпорт документа приводить масивний filename (повторний заголовок) до рядка (type-confusion). Без зміни поведінки для коректного вводу.
server/lib/prompts.mjs,server/lib/routes/runners.mjs,server/lib/cv-import.mjs+tests/security-hardening-v1108.test.mjs(3). За v1.106–v1.108 беклог статичного аналізу скоротився зі 167 до ~14: усі справді значущі для безпеки знахідки виправлено, решту (захищені/санітизовані хибні спрацювання + lint рівня note) відхилено з обґрунтуванням.
Нове: немає.
[1.107.0] — 2026-07-06
Посилення санітайзера (ешелонований захист від XSS у стані спокою). stripDangerousMarkdown — нейтралізує небезпечний HTML у збереженому markdown резюме/вакансії, щоб будь-який споживач, що оминає клієнт з екрануванням-при-рендері, лишався безпечним — тепер виконує видалення тегів до нерухомої точки (повторювати до стабілізації), щоб видалення, що переформовує корисне навантаження (напр. <scr<script></script>ipt>), було впіймано, збігається із закривними тегами script/style тощо зі сміттям у кінці (</script foo>) і видаляє незакритий виконуваний відкривний тег (<script …>). Поведінка для коректного markdown не змінюється — лише видаляє більше.
server/lib/security.mjs: цикл нерухомої точки (обмеження 8 проходів) + шаблони закривних тегів[^>]*>+ видалення незакритого відкривного тега. +3 регресійні випадки вtests/cv-xss-bypasses.test.mjs. Авторитетна межа XSS лишається екрануванням на виводі (UI.md); це посилює гарантію в спокої й закриває відповідні знахідки CodeQL.
Нове: немає.
[1.106.0] — 2026-07-06
Посилення безпеки (розбір CodeQL). Виправлено три реальні (хай і низької серйозності) знахідки після проходу беклогу статичного аналізу: шлях помилки рендера маршруту тепер екранує повідомлення про помилку до потрапляння в DOM (помилка сервера може відобразити введення користувача, тож вважається недовіреною — межа XSS), а записи властивостей профілю/конфігу відхиляють ключі __proto__ / constructor / prototype (захист від забруднення прототипу про всяк випадок — ключі беруться з фіксованих специфікацій полів, а не з сирого введення). Більшість решти попереджень — хибні спрацювання на легітимних читаннях/записах сканера в data/* та на маршрутах, що вже мають власний обмежувач; відхилено з обґрунтуванням.
public/js/router.jsекрануєerr.messageчерезUI.escapeHtmlпередinnerHTML;server/lib/routes/content.mjsіserver/lib/routes/config.mjsзахищають ключі прототипу. Без зміни поведінки для коректного введення. Тести:tests/security-hardening-v1106.test.mjs(3). Нових ключів i18n немає.
Нове: немає.
[1.105.0] — 2026-07-06
Сторінка витрат і вартості ШІ. Нова сторінка Витрати ШІ (бічна панель, поруч зі «Здоров’ям») показує, скільки токенів ви витратили на живі генерації ШІ — оцінки, звіти, чати — з розбивкою за провайдерами за останні 24 години, 7 днів, 30 днів і весь час, з оцінкою вартості в USD. Кожен живий виклик додає невеликий запис {provider, in, out} до data/llm-usage.jsonl (нікуди нічого не надсилається); запуски без ключа (ручний режим) нічого не коштують і не записуються.
- Новий модуль маршруту (30-й)
server/lib/routes/usage.mjs—GET /api/usage(агрегати лише для читання) +server/lib/llm-usage.mjs(recordUsageнормалізує формати usage Anthropic/OpenAI/Gemini і додає best-effort;readUsage/aggregateагрегують за вікнами 24г/7д/30д/усе × провайдер) +server/lib/llm-pricing.mjs(редагована таблиця цін за провайдерами$/1Mтокенів — токени точні, долари — приблизні прайс-ціни, які можна виправити; не виставляються до оплати). Запис підключено в точках диспетчеризації (runActiveProvider+routes/llm.mjs). - Нове представлення
public/js/views/usage.js(#/usage, вкладки вікон). Тести:tests/usage-routes.test.mjs. 17 нових ключів i18n ×16 (usage.*+nav.usage). Довідка §6 розширена на місці.
Нове: server/lib/routes/usage.mjs; server/lib/llm-usage.mjs; server/lib/llm-pricing.mjs; public/js/views/usage.js.
[1.104.0] — 2026-07-06
Логотипи компаній у таблиці сканування (без витоку приватності). Новий перемикач Вигляд у Налаштуваннях — Показувати логотипи компаній у таблиці сканування (типово вимкнено) — малює логотип кожної компанії поруч із назвою на #/scan. Логотип — це favicon компанії, узятий з її власного домену та проксі на сервері (GET /api/logo), тож жоден сторонній сервіс логотипів не дізнається, яких роботодавців ви переглядаєте. Вакансії на спільному порталі (Greenhouse, Lever, Ashby, …) показують кольоровий літерний значок замість іконки порталу, і будь-який логотип, що не завантажився, відкочується на той самий значок.
- Новий модуль маршруту (29-й)
server/lib/routes/logos.mjs—GET /api/logo?domain=. Він валідує домен (без схеми/шляху/loopback), бере/favicon.icoчерез SSRF-безпечнийsafeGet(новий режимbinaryповертає сирі байти + content-type; DNS-піннінг, перевірка редиректів і ліміт розміру не змінені), виконує сніфінг сигнатури зображення, щоб ніколи не віддати HTML-сторінку помилки як картинку, кешує влучення і промахи в LRU у пам’яті та нічого не пише на диск. - Нова клієнтська бібліотека
public/js/lib/company-logo.js(window.CompanyLogo): типово вимкнена через прапорець у localStorage; пропускає спільні ATS-хости на користь детермінованого літерного аватара; CSP-безпечний відкатimg.onerror. Тести:tests/logo-routes.test.mjs. 5 нових ключів i18n ×16 (appear.*). Довідка §2 розширена на місці.
Нове: server/lib/routes/logos.mjs; public/js/lib/company-logo.js.
[1.103.0] — 2026-07-06
Налаштування: «Інструменти CLI для ШІ» — які встановлені. career-ops працює на Claude Code, але сумісний із будь-яким агентським CLI відкритого стандарту skills. Нова вкладка Інструменти CLI для ШІ у Налаштуваннях (#/config) показує, які з них — Claude Code, Codex, Gemini CLI, OpenCode, GitHub Copilot CLI, Qwen, Antigravity — встановлені на машині, де запущено сервер, і їхні шляхи. Це сканування PATH лише для читання: перевіряється лише наявність кожного бінарника, і він ніколи не запускається (без --version, без виконання), нічого не пишеться і дані користувача не зачіпаються.
- Новий модуль маршруту (28-й)
server/lib/routes/cli-detect.mjs—GET /api/cli-detect. Визначення резолвить шлях бінарника з фіксованого списку з 7 записів заprocess.env.PATH(шими.cmd/.exe/.batу Windows; біт виконання в POSIX); ворожий файл на PATH ніколи не буде виконано цим маршрутом. - Нова вкладка «Інструменти CLI для ШІ» у
public/js/views/config.js(лінива загрузка, діплінк через#/config?tab=cli). Тести:tests/cli-detect-routes.test.mjs. 8 нових ключів i18n ×16 (cli.*+config.tabCli). Довідка §2 розширена на місці.
Нове: server/lib/routes/cli-detect.mjs.
[1.102.0] — 2026-07-05
«Запитати довідку» — чат з опорою на вбудовану довідку. Нова сторінка Запитати довідку 💬 (бічна панель, під «Довідкою»): введіть запитання на кшталт «Як сканувати портали вакансій?» і отримайте відповідь лише зі вбудованої довідки застосунку вашою мовою — показує використані розділи й ніколи не читає ваше резюме, профіль чи пошук роботи. Це про те, як користуватися застосунком, а не про вас. З ключем LLM відповідає наживо; без ключа видає готовий промпт, уже заповнений потрібними розділами довідки.
- Новий модуль маршруту (27-й)
server/lib/routes/docs-assistant.mjs—POST /api/docs-assistant/ask. Пошук без залежностей: довідка вашою мовою розбивається на розділи##й оцінюється за збігом ключових слів із запитанням; найкращі включаються, і модель має відповідати з них або сказати, що довідка це не охоплює (без вигаданих функцій/маршрутів). Спільний каскад провайдерів, ручний відкат, обмеження частоти, без записів, не читає дані користувача. - Нове представлення
public/js/views/docs-assistant.js. Тести:tests/docs-assistant-routes.test.mjs. 14 нових ключів i18n ×16 (docs.*+nav.docsAssistant). Довідка §1 розширена на місці.
Нове: server/lib/routes/docs-assistant.mjs; public/js/views/docs-assistant.js.
[1.101.0] — 2026-07-05
CV Studio: адаптуйте резюме + напишіть супровідний лист під конкретну вакансію, з рекрутерським чек-лістом. Нова картка Адаптувати під вакансію на #/cv-studio: вставте опис вакансії (і, за бажанням, цільову роль/заголовок), і CV Studio створює адаптоване під цю вакансію резюме та відповідний супровідний лист, а потім проганяє обидва через чек-лист-гейт перед видачею — error блокує (виправляється до того, як ви побачите результат), warn радить. Механіка — витяжка з практики кар’єрного консультування в загальні правила: рекрутер читає за секунди, тож релевантне йде вгору, заголовок збігається з роллю вакансії, у результатах — конкретні цифри, а лист лишається коротким тизером з єдиною «смичкою» «вимога ↔ ваш відповідний факт». Ґрунтується лише на вашому резюме, профілі та two-pager і нічого не вигадує — без зашитих компаній, ролей чи історії.
- Новий ендпоінт
POST /api/cv-studio/tailor(розширює наявний модуль cv-studio — без 27-го модуля):buildTailorPrompt+ загальний гейтTAILOR_INSTRUCTIONS, на основіbundleProjectContext, спільний каскад провайдерів, ручний промпт без ключа, з обмеженням частоти, без записів. Результат експортується у Markdown / PDF / DOCX через спільну панельreport-export.js. - Тести: +3 у
tests/cv-studio-routes.test.mjs. 10 нових ключів i18n ×16 (cvs.tailor*). Загальний референсdocs/prompts/resume-cover.md. Довідка §24 розширена на місці.
Нове: docs/prompts/resume-cover.md.
[1.100.0] — 2026-07-05
Two-pager: ШІ-автозаповнення з вашого резюме + Перегляд + експорт у PDF/DOCX/Markdown. Two-pager (#/two-pager) фіксує те, чого ви насправді хочете від наступної ролі, але раніше кожне поле доводилося писати вручну або копіювати промпт в інший інструмент. Тепер ✨ ШІ-помічник заповнення працює наживо з налаштованим провайдером — читає лише ваше резюме + профіль (через bundleProjectContext, нічого не вигадуючи), складає всі поля (хто я / що подобається / обов’язкове / що ненавиджу / стоп-фактори / непорушне / цільове середовище) і заповнює форму, щоб ви перевірили, відредагували та зберегли. Без API-ключа повертається до модалки «скопіювати промпт», як раніше. Нова кнопка 👁 Перегляд і експорт відображає two-pager як форматований документ із панеллю Завантажити .md / Зберегти як PDF / Зберегти як DOCX / Копіювати.
- Експорт
.docxбез залежностей. Новийserver/lib/docx.mjsформує мінімальний, але валідний Office Open XML.docx(ZIP із DEFLATE із чотирьох частин OOXML, CRC-32 на запис) — без нової залежності (залежності лишаютьсяexpress+js-yaml). Новий маршрутPOST /api/export/docx(server/lib/routes/export.mjs, 26-й модуль маршрутів; без стану, ліміт 200 КБ, без записів / без LLM / без fetch за URL). Під’єднано до спільногоpublic/js/lib/report-export.js, тож звіт по ринку, кар’єрний план і профорієнтація теж отримують експорт у DOCX. - Живе автозаповнення використовує спільний каскад провайдерів (
runActiveProvider/providerAvailable); повернутий YAML парситься й приводиться назад до обмеженої форми two-pager (parseYamlFields+normalizeTwoPager) — невідомі ключі відкидаються, масиви/рядки обмежуються. Ручний режим збережено. - Тести:
tests/export-routes.test.mjs. 4 нові ключі i18n ×16 (export.saveDocx,twoPager.preview,twoPager.aiFilling,twoPager.aiFilled).
Нове: server/lib/docx.mjs; server/lib/routes/export.mjs.
[1.99.0] — 2026-07-05
Сторінка здоров’я порталів (#/portals). Сканер стежить за набором компаній у portals.yml; slug ATS може тихо зламатися, і цей роботодавець зникає з усіх майбутніх сканувань. Нова сторінка Portals перелічує кожну відстежувану компанію і за кнопкою Check portal health перевіряє кожен careers_url через safeGet із закріпленим DNS (захист від SSRF), позначаючи мертві (404 = тихо відкинута) — лише читання. Також посилює репортер багів v1.98.0 за підсумками ревʼю: кільцевий буфер помилок тепер ловить мережеві збої fetch, а скрабер вичищає непозначені ключі провайдерів.
Нове: server/lib/routes/portals.mjs; public/js/views/portals.js.
[1.98.0] — 2026-07-05
Вбудований репортер багів (паритет із веб-частиною web-v0.2.0 батьківського проєкту). Кнопка 🐞 Report a bug у панелі сповіщень збирає діагностичний знімок із пріоритетом приватності — версії, ваш екран, браузер, зведення перевірок /api/health і останні 20 помилок із нового клієнтського кільцевого буфера — плюс детермінований відбиток для дедуплікації (co-web-<base36>), дає переглянути точний Markdown і потім відкриває попередньо заповнений issue на GitHub. Нічого не надсилається автоматично; він ніколи не несе ваше CV, профіль, відповіді, URL вакансій чи ключі. Нові бібліотеки logbuf.js + bug-report.js; 11 ключів i18n ×16; tests/bug-report.test.mjs.
Нове: public/js/lib/logbuf.js; public/js/lib/bug-report.js.
[1.97.1] — 2026-07-05
Посилення за підсумками рев’ю та паритет документації (продовження v1.97.0). Розбір логів AI-рев’ю виявив реальні виправлення:
fit-score.js(значок відповідності◎під час сканування).salaryFloor()більше не перетворює ставку, меншу за річну, на фіктивний річний мінімум — «at least 500 EUR/day», «$80/hr», «6000 monthly» тепер повертаютьnullзамість дилбрейкера у 500k/80k. Зіставлення країн тепер іде за цілим словом (\b…\b), тож «Germany» більше не збігається з прикметником «German» (як і «Nigeria» всередині «Nigerian») і не спрацьовує хибним порушенням «обов’язково-деінде». +3 тести уtests/fit-score.test.mjs.- Паритет документації. Кожен локалізований README тепер однаково заявляє 16 локалей — лічильник/список у рядку Help (×13) та текст розділу локалізації плюс примітка «додайте ключ до всіх N файлів» (×8) усе ще трималися на лічильниках до v1.85 (8/9). Лічильник адаптерів §17 у вбудованій довідці виправлено на 46 адаптерів — 41 англійський + 5 російських в усіх 16 бандлах.
Жодних змін поведінки, окрім евристики значка відповідності; ні нових маршрутів, ні ключів, ні додавань i18n.
[1.97.0] — 2026-07-05
Джерело сканера Dassault Systèmes + фронт покращень якості за трьома напрямами.
- Нове джерело сканування — Dassault Systèmes (паритет із батьківським career-ops, #1498).
server/lib/sources/dassault.mjs+server/lib/portals/adapters/dassault.mjsвідтворюють zero-token-провайдер «карткового пошуку» Exalead із батьківського проєкту (публічна стрічка за3ds.com/careers/jobs). Це єдина глобальна кінцева точка, тож вона обирається за провайдером (provider: dassault) або автоматично визначається за хостом3ds.com, із захистом від SSRF, прив’язкою хоста доwww.3ds.comтаredirect:'error'. XML розбирається без DOM (карти<Meta>для кожного<Hit>), місто/країна беруться з локалізованого рядка категорії, а вакансії зберігаються лише тоді, коли їхній публічний URL перебуває на*.3ds.com. Реєстр тепер постачає 46 адаптерів (41 EN + 5 RU); лічильникALL_ADAPTERS, перевірки відсортованих id та EN-набору/api/scan/sourcesпідняті з 40 → 41. Набірtests/sources-dassault.test.mjs(10 випадків). - Перенесені з батьківського проєкту виправлення надійності. Парсер Avature тепер допускає два живі варіанти розмітки орендарів (
article--resultіз суфіксом позиційного індексу + безкласовий якір заголовка JobDetail, #1541); Get on Board захищається від0/від’ємногоpublished_at(більше жодних хибних дат 1970 року); SuccessFactors обмежує останню сторінку, щоб вона не могла перевищитиMAX_JOBS(#1528). - Виправлення серверного аудиту.
safe-fetchбільше не зависає на відповіді, що перевищує ліміт розміру — шлях обмеження розміру тепер напряму завершує проміс замість очікування події'end', яку зруйнований потік ніколи не випустить (виправляє запити/api/pipeline/previewта авто-пайплайну для великих сторінок). Логування активності SSEstream.*знову досяжне (перевірку/api/stream/переміщено вище загального захисту «пропускати GET»). - Виправлення аудиту SPA. Перемикач вкладок
#/statsзахищений від гонки під час асинхронного рендерингу — результат повільної вкладки більше не може затерти новішу вкладку, на яку користувач уже перемкнувся. Підтвердження видалення у mock interview та нетворкінгу тепер передають коректні заголовок + тіло (більше жодних діалогів із порожнім тілом). - Виправлення перекладу. Виправлено неперекладені значення словника — українські
config.modes*(Adaptive Framing / Exit Narrative / Location Policy), російськийeval.jdLbl(«Job Description»), італійськийdash.quick.contactoSub(«referral» → «segnalazione») — а також англійську заготовку 16 локалей локалізовано в CHANGELOG для ru/uk/ja/ko/zh-CN/zh-TW.
Нове: server/lib/sources/dassault.mjs; server/lib/portals/adapters/dassault.mjs.
[1.96.0] — 2026-07-04
Кар’єрна орієнтація (Epic 27). Нова сторінка #/orientation відповідає на питання «які напрями мені насправді підходять?» — така оцінка, яку дав би профорієнтаційний тест, але виведена з вашого власного резюме та профілю замість опитувальника. Натисніть Згенерувати профіль, і модель поверне ваші найкращі кар’єрні вектори (які з восьми архетипів — Функціоналіст, Адміністратор, Комунікатор, Спеціаліст, Аналітик, Новатор, Менеджер, Підприємець — підходять, з доказами), схильність до кар’єрного типу, рекомендовані ролі, професійні сильні сторони, прив’язані до вашого резюме, тенденції робочого стилю та рекомендації щодо розвитку. Це ШІ-рефлексія того, як читається ваше резюме, — а не психометричний тест: воно ніколи не вигадує досягнень і ніколи не подає числових результатів так, ніби їх виміряли. Експортуйте його в Markdown або PDF; нічого не записується на диск.
- Новий маршрут
server/lib/routes/orientation.mjs(24-й модуль маршрутів) —POST /api/orientation/generateбудує промпт профілю з CV+профілю+two-pager+пам’яті через спільну каскаду провайдерів, із ручним відкатом для копіювання-вставлення та без запису файлів. - Повторно використовує
report-export.jsдля Markdown/PDF/копіювання, у навігаційній групі Зростання. - Тести:
tests/orientation-routes.test.mjs(рамка рефлексії / без вигаданих оцінок, ручний режим із засівом із CV/профілю). 7 нових ключів i18n ×16 локалей, довідка §28 ×16.
Нове: #/orientation; server/lib/routes/orientation.mjs.
[1.95.0] — 2026-07-04
План кар’єри (Epic 26). Нова сторінка #/career-plan перетворює ваше резюме та профіль на конкретний, персоналізований план розвитку. Виберіть горизонт (6/12/24 місяці) та, за бажанням, фокус, і модель — читаючи ваше CV, профіль, two-pager і нотатку пам’яті — пише знімок відправної точки, SWOT сильних сторін і зростання, цілі у форматі SMART / OKR / WOOP, альтернативні траєкторії, план hard/soft-навичок, помісячну дорожню карту, методи відстеження прогресу, підводні камені та підтримувальні кроки. Вона планує вперед від того, що дійсно показують ваші матеріали, і ніколи не вигадує факти про вашу історію. Редагуйте її на місці, Збережіть її в користувацький шар (config/career-plan.md) та експортуйте її у Markdown або PDF.
- Новий маршрут
server/lib/routes/career-plan.mjs(23-й модуль маршрутів) —GET/PUT /api/career-plan(пишеconfig/career-plan.md) +POST /api/career-plan/generate(спільна каскада провайдерів, ручний відкат, без фабрикації).PATHS.careerPlan. - Повторно використовує спільний
report-export.js(v1.94.0) для Markdown/PDF/копіювання та нову навігаційну групу Зростання. - Тести:
tests/career-plan-routes.test.mjs(обмеження, круговий обхід GET/PUT, промпт із урахуванням горизонту, засіяний із CV/профілю). 20 нових ключів i18n в усіх 16 локалей, довідка §27 ×16.
Нове: #/career-plan; server/lib/routes/career-plan.mjs; PATHS.careerPlan.
[1.94.0] — 2026-07-04
Статистика, перероблена (Epic 25). Сторінка #/stats тепер є розділом Статистика з трьома вкладками, зі справжніми графіками та значно більшою кількістю даних. Нова вкладка Звіт про ринок просить модель проаналізувати зарплати та ринок праці для ваших цільових ролей у вибраному регіоні та валюті — стисле резюме, зарплати за рівнем із перцентилями P10/P25/P75/P90, провідні роботодавці, таблиця затребуваних навичок, частота пільг, розподіл офіс/гібрид/віддалено, тренди на 12–24 місяці та поради щодо перемовин. Кожна цифра позначена як орієнтовна оцінка зі знань моделі, і ніколи не подається як зібрані дані. Нова вкладка Мій пайплайн будує графіки за вашим власним трекером: розподіл оцінок, воронка статусів, провідні компанії та ролі, заявки в часі та коефіцієнти конверсії. Початковий вигляд цільових ролей (вакансії/зарплати за країнами + тренд збережених знімків) переходить у третю вкладку, тепер із вибором валюти та оглядом вакансій за роллю.
- Експортуйте будь-який звіт у Markdown або PDF чи скопіюйте його — через спільний помічник
report-export.js(завантаження Markdown як blob; PDF через наявний вбудований PDF-раннер). - Новий маршрут
server/lib/routes/market.mjs(22-й модуль маршрутів) —POST /api/stats/marketбудує промпт аналізу ринку на основі вашого CV/профілю (щоб знати ваші цільові ролі), регіону та валюти, запускає його через спільну каскаду провайдерів і відкочується до промпту для копіювання за відсутності ключа. Без запису файлів. - Тести:
tests/market-routes.test.mjs(обмеження регіону/валюти, промпт із чесним маркуванням, ручний режим із передзаповненням із CV/профілю). 36 нових ключів i18n в усіх 16 локалей, довідка §26 ×16.
Нове: #/stats перероблено на вкладки; server/lib/routes/market.mjs; public/js/lib/report-export.js.
[1.93.0] — 2026-07-04
Шар пам’яті (Epic 24). Нова сторінка #/memory містить коротку редаговану нотатку «запам’ятай це про мене», яку асистент тримає в голові на кожному завданні:
- Одна нотатка, всюди — оскільки вона вбудована в
bundleProjectContext, нотатка автоматично доходить до кожного AI-запиту (оцінка, пробна співбесіда, нетворкінг, CV Studio) в усіх провайдерах. Напишіть її раз — вона керує всім. - Керування, а не факти — вона фіксує ваші вподобання й те, як вам зручно працювати (тон, формат, стоп-фактори, ритм), і ніколи не нові фактичні твердження про ваш досвід — ті й далі живуть лише у вашому резюме, профілі та two-pager. Зберігається в користувацький шар за адресою
config/memory.mdі ніколи не перезаписується оновленнями. - Підказки з ваших даних —
POST /api/memory/suggestаналізує ваш власний трекер заявок на поведінкові патерни й готує пункти для перегляду й редагування. Він читає ваш трекер; ніколи не вигадує фактів і не робить жодного онлайн-виклику.
Нове: server/lib/routes/memory.mjs (21-й модуль маршрутів — GET/PUT /api/memory + POST /api/memory/suggest), public/js/views/memory.js, PATHS.memory та блок config/memory.md, доданий до bundleProjectContext. 11 нових ключів i18n в усіх 16 локалей. Тести: tests/memory-routes.test.mjs.
[1.92.0] — 2026-07-04
CV Studio (Epic 21). Нова сторінка #/cv-studio дає вашому резюме три чесні, здебільшого локальні інструменти:
- Діагностика резюме — детермінована оцінка 0–100 із поясненнями за кожною перевіркою (кількісно виміряний вплив, слабкі дієслова, штампи, обсяг, ключові розділи, контактні дані). Повністю на боці клієнта (
window.CvDiagnostics) — без LLM, нічого вигаданого, кожен висновок пояснено, тож ви вирішуєте, що змінювати. - Маска приватності — вилучення PII (email, телефон, посилання/нікнейми, поштова адреса й за бажанням ваше ім’я → ініціали) перед тим, як поділитися резюме як зразком чи скриншотом. Виконується цілком у браузері (
window.CvPrivacy); повідомляє, що саме було вилучено, і ніколи не зберігає оригінал. - Make it human / збіг голосу — вставте суху фразу чи абзац і перепишіть її вашим голосом, обґрунтованим на боці сервера через
voice-dna.mdіwriting-samples/. Жорсткий запобіжник: воно може переставляти, стискати й переголошувати, але ніколи не додає факту, метрики чи досягнення, якого ще немає в тексті. Виконується наживо через спільний каскад провайдерів або повертає готовий до копіювання промпт без ключа.
Нове: server/lib/routes/cv-studio.mjs (20-й модуль маршрутів — POST /api/cv-studio/humanize), public/js/views/cv-studio.js, public/js/lib/cv-diagnostics.js, public/js/lib/cv-privacy.js, PATHS.voiceDna + PATHS.writingSamplesDir. 29 нових ключів i18n в усіх 16 локалей. Тести: tests/cv-diagnostics.test.mjs, tests/cv-studio-routes.test.mjs. (Галерея шаблонів, експорт у Word та архів PDF-оголошень відстежуються як подальша робота над CV Studio.)
[1.91.0] — 2026-07-04
Нетворкінг і глибоке дослідження компаній (Epic 16). Нова сторінка #/networking перетворює компанію на дієвий план отримання співбесіди, обґрунтований вашим резюме, профілем і two-pager:
- Досьє компанії — стислий бриф про те, чим займається компанія, нещодавні сигнали, варті згадування, і зачіпки «чому я підходжу», взяті з вашого реального досвіду.
- З ким зв’язатися — 3–5 цільових персон (наймальний менеджер, внутрішній рекрутер, старший IC з команди, теплий контакт/випускник того самого вишу) з конкретним пошуковим рядком LinkedIn для пошуку кожного. Реальні імена ніколи не вигадуються.
- Найтепліший шлях для представлення — найреалістичніший теплий вхід саме для вашого досвіду (спільний роботодавець/навчальний заклад/спільнота, шлях другого рівня або сильний за сигналом холодний DM) і чому.
- Чернетки для контакту — короткі, конкретні повідомлення для головних персон, обґрунтовані вашими реальними точками доказу.
- Наживо або вручну — виконується наживо через спільний каскад провайдерів із будь-яким ключем або повертає готовий до копіювання промпт (чесний fallback, нічого вигаданого). Зберегти план зберігає готовий план у користувацький шар (
networking/net-{company}-{role}-{date}.md); сторінка показує список, відкриває й видаляє збережені плани.
Нове: server/lib/routes/networking.mjs (19-й модуль маршрутів), public/js/views/networking.js, PATHS.networkingDir. Повторно використовує каскад server/lib/llm-dispatch.mjs з v1.90.0. 24 нові ключі i18n в усіх 16 локалей. Тести: tests/networking-routes.test.mjs.
[1.90.0] — 2026-07-04
Mock Interview 2.0 (Epic 15). Нова сторінка #/mock-interview перетворює ваше резюме, профіль, two-pager і банк історій на покрокову репетицію співбесіди:
- Діалогова практика — задайте цільову роль (+ за бажанням компанію / JD), і інтерв’юер починає з точкового запитання. На кожну надіслану відповідь ви отримуєте структуровану репліку: Feedback (сильні сторони + прогалина за STAR+R), Score (
N/5) та Next question, яке промацує найслабше місце вашої останньої відповіді. Обґрунтовано на боці сервера вашими реальними матеріалами — воно ніколи не вигадує досвід, якого у вас немає. - Враховує банк історій —
interview-prep/story-bank.mdвбудовується в промпт (той самий рівень довіри, що йcv.md), тож зворотний зв’язок може вказати вам на ваші ж найкращі історії. - Наживо або вручну — за наявності ключа провайдера хід виконується наживо через спільний каскад провайдерів (Anthropic → Gemini → OpenAI → Qwen → OpenRouter → GitHub Models); без ключа ви отримуєте готовий до запуску промпт для копіювання та вставлення (чесний fallback, без вигаданих відповідей).
- Збережені сесії — натисніть Save transcript, щоб зберегти завершену співбесіду в шар користувача (
interview-prep/mock-{company}-{role}-{date}.md); сторінка показує список, відкриває та видаляє збережені сесії.
Нове: server/lib/routes/interview.mjs (18-й модуль маршрутів), public/js/views/mock-interview.js, server/lib/llm-dispatch.mjs (спільний каскад провайдерів), PATHS.storyBank, bundleProjectContext({ extraFiles }). 30 нових ключів i18n в усіх 16 локалей. Тести: tests/interview-routes.test.mjs.
[1.89.0] — 2026-07-04
Відповідність кандидата й ринку — two-pager (Epic 14). Нова сторінка #/two-pager дозволяє зафіксувати те, чого ви насправді хочете від наступної ролі, за зразком «Mnookin two-pager» із книги Never Search Alone:
- Покроковий конструктор — оповідь від першої особи «Хто я», нотатка «Цільове середовище» та п’ять редакторів списків-чипів: loves, must-haves, hates, deal-breakers і non-negotiables. Зберігається в користувацький шар батьківського проєкту (
config/two-pager.yml) черезPUT /api/two-pager— ніколи не перезаписується системними оновленнями. - ШІ-помічник заповнення (
POST /api/two-pager/draft) — збирає готовий до запуску Mnookin-промпт із вбудованими вашими CV + профілем, щоб ви запустили його в будь-якому LLM і вставили результат назад. Він використовує лише ваші власні матеріали; нічого не вигадується. - Бейдж відповідності-тому-що-ви-хочете — кожна вакансія на
#/scanтепер показує оцінку відповідності◎ N(на боці клієнта, черезwindow.FitScore), що зіставляє формат роботи, країну, мінімальну зарплату та релокацію вакансії з вашим two-pager. Чесний за задумом: якщо вакансія не дає зіставного сигналу, бейдж не показується (ніколи не вигадане число). Порушення deal-breakers важать більше, ніж легкі неприязні. - Живить кожну оцінку — збережений two-pager вбудовується в
bundleProjectContext, тож усі подальші оцінки LLM поєднують заявлені вами вподобання з відповідністю CV-проти-JD.
Нове: server/lib/routes/two-pager.mjs, public/js/views/two-pager.js, public/js/lib/fit-score.js, PATHS.twoPager. 27 нових ключів i18n в усіх 16 локалях. Тести: tests/two-pager-routes.test.mjs, tests/fit-score.test.mjs.
[1.88.0] — 2026-07-04
Доопрацювання issue #29 — прогалини i18n у Скануванні + гігієна API.
- Локалізовано останні захардкоджені рядки Сканування (дорожня карта v1.69.4): плашки зведення за джерелом (
N нових / M збігів), тостиN нових вакансійта бейджrelocтепер проходять черезt()— 4 нові ключі (scan.pillNew,scan.pillMatching,scan.newOffers,scan.relocBadge) в усіх 16 локалях. Неангломовні користувачі більше не бачать випадкової англійської в основному потоці сканування. - Вимкнено заголовок
X-Powered-By(дорожня карта v1.69.5):app.disable('x-powered-by')уcreateApp()— сервер більше не повідомляє, що працює на Express. (Решту цього епіку вже було випущено:parentVersionвирізає свій коментар release-please, перемикач світлої теми, закриття модальних вікон під час зміни маршруту та локалізація «Score» (rep.score) у Звітах.)
Тести: tests/scan-i18n-gaps.test.mjs + перевірка відсутності X-Powered-By у tests/security-headers.test.mjs.
[1.87.0] — 2026-07-04
4 нові провайдери сканування без автентифікації (паритет із батьківським career-ops v1.16.0). Реєстр сканера зростає з 41 → 45 адаптерів (40 EN + 5 RU) — усі публічні, без автентифікації, із закріпленим хостом, redirect:'error' (захист від SSRF), кожен з ізольованим для CI тестом:
- Get on Board (
getonbrd) — публічний JSON:API по всьому порталу (LATAM/віддалені технічні ролі), обирається за провайдером, із пагінацією.server/lib/sources/getonbrd.mjs. - Amazon (
amazon) — публічний JSON пошукуamazon.jobs, визначається за хостом абоprovider: amazon, пагінація за зміщенням.server/lib/sources/amazon.mjs. - Avature (
avature) — ATS*.avature.netдля кожного орендаря, парсинг HTML, визначається за хостом абоprovider: avature.server/lib/sources/avature.mjs. - SAP SuccessFactors (
successfactors) — список плиток RMK для кожного орендаря (*.successfactors.eu/.com,jobs2web.com), парсинг HTML.server/lib/sources/successfactors.mjs.
Кожен постачає sources/<slug>.mjs (автовиявлюваний meta → випадний список #/scan) та portals/adapters/<slug>.mjs у ALL_ADAPTERS (правило двох реєстрів) + tests/sources-<slug>.test.mjs. Лічильник ALL_ADAPTERS, а також перевірки відсортованих id та EN-набору /api/scan/sources зросли з 36→40; GET /api/scan/sources тепер перелічує 45.
[1.86.0] — 2026-07-03
Статистика за цільовими ролями (#/stats) — ринкова статистика вакансій і зарплат за ВАШИМИ цільовими ролями. Нова сторінка Аналітики читає ваші цільові ролі з профілю (config/profile.yml → не захардкоджені) та вакансії з останнього сканування, а потім показує для кожної ролі й країни:
- Вакансії за країнами та медіанну зарплату за країнами (USD) — агрегуються на боці клієнта (
public/js/lib/role-stats.js, повторно використовуючиwindow.Countries) з розріджених даних, які сканери вже збирають. Зарплати в будь-якій валюті нормалізуються до USD через явно приблизну таблицю FX, із застереженням щодо розміру вибірки — ніколи не вигадуються. - Фільтри ролі та країни й саморобні вбудовані SVG-графіки: стовпчикові та трендові (без нових залежностей, безпечно для CSP — лише
addEventListener). - Зберегти знімок (
POST /api/stats/snapshot) зберігає поточний агрегат уdata/role-stats.jsonl; графік тренду (GET /api/stats/trend) відстежує кількість вакансій у часі — подання «динаміки». Чесний гібрид: знімки формуються з локальних даних сканування й оновлюються за запитом. - Повністю локалізовано в усіх 16 локалях (26 нових ключів i18n).
Нове: server/lib/routes/stats.mjs (16-й модуль маршрутів), public/js/lib/role-stats.js, public/js/views/stats.js, PATHS.roleStats; тести role-stats.test.mjs (7) + stats-routes.test.mjs (5).
[1.85.0] — 2026-07-03
Локалі німецької, італійської та турецької (паритет локалей із батьківським career-ops v1.16.0). Інтерфейс тепер постачається 16 мовами — de 🇩🇪, it 🇮🇹 і tr 🇹🇷 додаються до наявних 13.
- Повний переклад інтерфейсу — усі 730 ключів i18n перекладено в
public/js/lib/locales/i18n-dict.{de,it,tr}.js; перемикач мов показує Deutsch / Italiano / Türkçe, а автовизначення мови браузера розпізнаєde/it/tr(public/js/lib/i18n.js). - Вбудований довідковий посібник —
docs/help/{de,it,tr}.mdперекладено (повна структура з 19 H2 / 75 H3), надаються черезGET /api/help/:lang. - Документація — додано
README.{de,it,tr}.mdіCHANGELOG.{de,it,tr}.md; перевірка паритету локалей CHANGELOG тепер охоплює 15 не-EN локалей. - Каркас промптів —
server/lib/prompts.mjs(LOCALE_NAMES+SCAFFOLD_STRINGS) локалізовано для трьох нових локалей, тож вивід LLM дотримується мови інтерфейсу.
Усі перевірки паритету (i18n-locale-files, i18n-coverage, check-changelog-parity, lang-switcher-rtl) розширено на набір із 16 локалей.
[1.84.0] — 2026-06-30
Кулдаун повторних заявок + компенсація в pipeline.md (паритет із батьківським career-ops v1.15.0). Два покращення сканера:
- Кулдаун повторних заявок (#1201): EN-скан тепер пропускає ролі в компаніях, до яких ви нещодавно вже подавали заявку, — результати лишаються зосередженими на НОВИХ вакансіях. Налаштуйте часові вікна на рівні компанії в
config/profile.ymlу секціїre_apply_windows:(last_apply_date,same_role_days,applied_to: [roles], необов’язковийcross_role_bucket); порівняння компаній нечутливе до пунктуації й працює за межами слів (server/lib/cooldown.mjs). Не діє, якщо ключ відсутній; до журналу сканування виводитьсяCooldown skipped: N. - Компенсація в pipeline.md (#1017): знайдені під час сканування вакансії тепер зберігають зарплату у вигляді необов’язкового кінцевого стовпця (
url | <salary>) уdata/pipeline.md. URL залишається ключем дедуплікації (стовпець| compприбирається під час читання), значення комірки санується (без ін’єкції рядка/стовпця, формульний префікс нейтралізується), а pipeline у форматі «лише URL» зберігає зворотну сумісність.
Постачається з tests/cooldown.test.mjs і тестами компенсації для pipeline. Кількість джерел не змінилась — 41 (обидва покращення стосуються логіки сканування, а не нових дошок).
[1.83.0] — 2026-06-30
Детектор повторних публікацій / фантомних вакансій (паритет із батьківським career-ops v1.15.0). На сторінці #/scan з’явилася панель 🔁 Повторні публікації / фантомні вакансії, яка позначає кластери «компанія + посада», повторно розміщені під різними URL у ковзному 90-денному вікні — сигнал застарілих конвеєрів і фантомних оголошень. Базується на нечіткому порівнянні заголовків (server/lib/role-matcher.mjs) та read-only детекторі (server/lib/detect-reposts.mjs) по data/scan-history.tsv, надається через GET /api/scan/reposts. Також: parentVersion у /api/health тепер повертає лише semver (коментар # x-release-please-version від release-please прибирається). Постачається з tests/detect-reposts.test.mjs. Кількість джерел не змінилась — 41: повторні публікації — аналітична функція, а не нова дошка.
[1.82.0] — 2026-06-30
Джерело сканування NoDesk (паритет із батьківським career-ops v1.15.0). Загальнодошкова RSS-стрічка віддаленої роботи NoDesk тепер повноцінне джерело — додайте запис provider: nodesk, і воно з’явиться у списку Source на #/scan (загалом 41 адаптер: 36 EN + 5 RU). Хост закріплено за nodesk.co із redirect:'error' (захист від SSRF); заголовки діляться за Role at Company (NoDesk не має тегу локації, поле місцеположення залишається порожнім); усі вакансії — віддалені. Постачається з CI-ізольованим набором тестів tests/sources-nodesk.test.mjs; повний набір юніт-тестів зелений, 1523.
[1.81.0] — 2026-06-29
Паритет із батьківським career-ops — 13 нових джерел сканування вакансій. Переносить останній пакет провайдерів із main Fighter90/career-ops у вбудований сканер. Загальнодоступні API дошок (вибір за provider:): Arbeitnow, Himalayas, Jobicy, Landing.jobs, 4 Day Week, The Muse, The Hub, Jobspresso (RSS) і Hacker News “Who is hiring?” (Algolia, два кроки). Польські дошки (визначаються за хостом або provider:): JustJoin.it і NoFluffJobs (POST-пошук). Per-tenant ATS (автовизначення за careers_url): Pinpoint (<slug>.pinpointhq.com/postings.json) і Rippling (ats.rippling.com/<slug> → api.rippling.com board). Кожне джерело закріплено за хостом із redirect:'error' (захист від SSRF) і доступне у списку Source на #/scan — реєстр тепер налічує 40 адаптерів сканера (35 EN + 5 RU). Додано 13 CI-ізольованих наборів тестів на джерело; повний набір юніт-тестів зелений, 1513.
[1.80.0] — 2026-06-28
П’ять покращень сканера (ідеї з job-crawler, переписані). (1) Джерело Teamtailor — сайти <slug>.teamtailor.com через публічну стрічку /jobs.rss, автовизначення за careers_url (хост закріплено + redirect:'error'); у реєстрі тепер 27 адаптерів. (2) Карантин джерел — джерело зі сталим 404/410 записується в data/scan-quarantine.json і пропускається в наступних сканах (самовідновлення: повтор через 14 днів). (3) Макс. на джерело — необов’язкове поле на #/scan, що обмежує кількість вакансій з борду (∞ за замовчуванням). (4) Опубліковано за — клієнтський фільтр за віком (24г / 7д / 30д). (5) Збережені пошуки + ★ обране — називайте й повторно використовуйте набори фільтрів і позначайте вакансії, у localStorage із захисною валідацією (пошкоджений кеш скидається чисто); кеш результатів скидається перед скануванням і наповнюється наживо.
[1.79.0] — 2026-06-28
Джерело сканування WeWorkRemotely (паритет із career-ops v1.14.0). Загальнодошкова RSS-стрічка віддаленої роботи We Work Remotely тепер повноцінне джерело — додайте запис provider: weworkremotely, і воно з’явиться у списку Source на #/scan (26 адаптерів загалом). Хост закріплено за weworkremotely.com із redirect:'error' (захист від SSRF); заголовки діляться за Company: Role. Також: ключові слова title_filter тепер обрізаються перед перевіркою довжини (parent #1261).
[1.78.2] — 2026-06-27
Зміцнення i18n та UX (виправлення після v1.78.1). Доступна назва логотипа тепер локалізована всіма 13 мовами (nav.logoHome). Enter у глобальному пошуку, коли ви вже на #/scan, примусово ре-рендерить, щоб не втратити введений термін (guard тієї ж маршрутизації). health.title тепер перекладено польською (Kondycja) та данською (Systemtilstand) — раніше англійською. Тести 1235 → 1238.
[1.78.1] — 2026-06-27
Виправлення UX на Scan. Таблиця результатів #/scan тепер автоматично оновлюється під час сканування та ще раз після завершення — без перезавантаження. Глобальний пошук у шапці показує підказку Enter і за не-URL-запитом переходить на #/scan із заповненим полем (раніше #/tracker). Логотип тепер веде на дашборд (головну).
[1.78.0] — 2026-06-27
Гео-фільтр на сторінці Scan — фільтр вакансій за країною, з прапорцями. Новий список Країна у #/scan показує кожну країну, виявлену в результатах (емодзі-прапор + лічильник), щоб лишити лише ролі, прив’язані до країни — поряд із фільтром Remote/Hybrid/Onsite, тож можна шукати як прив’язану до країни, так і віддалену роботу. На основі нового помічника countries.js, що зіставляє вільний текст локації (назви країн, аліаси та ~100 великих міст) з країною ISO + прапором; детекція консервативна й ніколи не вгадує.
[1.77.0] — 2026-06-27
Додано данську (Dansk) — 13-ту мову інтерфейсу. Повний переклад UI, вбудованого довідника Help (19 H2 / 75 H3), README та CHANGELOG. Данська додана до перемикача мов із прапорцями; механіка i18n (асемблер, аудит, перевірки паритету, знімок) тепер охоплює 13 локалей.
[1.76.0] — 2026-06-26
Паритет із career-ops v1.13.0 — шість нових джерел, зміцнення сканера та таблиця результатів без ліміту.
Додано
- Шість ATS-джерел на тенант — BambooHR, Breezy HR, Comeet, Personio, Recruitee, SolidJobs. Визначаються за хостом
careers_url(Comeet потребує повногоapi:); кожен хост закріплено якірним regex +redirect:'error'(захист від SSRF). Доступні у списку Source на#/scan— реєстр тепер має 25 адаптерів (20 EN + 5 RU). Додано помічникfetchTextдля XML-стрічки Personio. trust_filter— необов’язкова оцінка довіри (0–100, рівень high/medium/low, прапорці), лише анотує. Рядки нижчеhighотримують нейтральний значок ⚠ на#/scan; нічого не відкидається.- Arbeitsagentur
remoteMatch+remoteMaxPages— визначення віддаленої роботи з конфігу:title,filter(homeoffice=nv_trueна сервері + пагінація) абоoff.
Змінено
- Немає ліміту результатів.
MAX_STORED_RESULTS(2000) прибрано — зберігаються всі збіги, таблиця#/scanгортає їх (200/стор.). - Надійність фільтра заголовків — короткі абревіатури (COO, SDR…) збігаються за межами слів; некоректний
title_filterбільше не ламає скан. Обидва сканери.
Тести
- +32 кейси (1190 → 1222):
sources-ats-providers,title-filter,arbeitsagentur-remote,trust-validatorі переписаний стражscan-result-cap(«без ліміту»).
[1.75.2] — 2026-06-19
docs: повний паритет документації для агрегаторів сканера з v1.75.0 в усіх 12 локалях. Без зміни коду — приводить документацію для користувача у відповідність до семи джерел, що з’явилися в v1.75.0:
- Довідковий посібник (12 локалей). §5 отримує блок
content_filter(гейтинг за ключовими словами опису/сніпета, аналогlocation_filter) та примітку про агрегатори; §7 перелічує сім нових джерел у проході сканування в один клік та в повному переліку випадного списку Source; лічильник адаптерів у §17 виправлено зі застарілого «11 adapters» на «19 adapters — 14 English + 5 Russian». Заголовків##/###не додавалося, тож закріплена структура 19 H2 / 75 H3 залишається незмінною. - README (9 повних локалей). Новий пункт «Aggregator boards (v1.75.0)» під джерелами сканування, плюс значок релізу, оновлений до v1.75.2. (Скорочені README pl/uk/ar не мають списку за джерелами, і там вони навмисно не зачеплені.)
- Довідкові документи.
docs/portals-examples.mdотримує готовий до копіювання розділ «Aggregator boards» з точними блоками конфігураціїprovider:/<provider>:для всіх семи;docs/PROJECT.mdоновлено до 19 adapters;docs/sdd/CONVENTIONS.mdдокументує розрізнення двох реєстрів (sources/registry.mjsдля випадного списку протиportals/registry.mjsдля вибірки), вибір агрегатора на основіprovider:, що передається якopts.company, санітайзер запису сканування (scan-sanitize.mjs) та кількість тестів v1.75.1 (1190). - QA. Додано
qa/QA-REGRESSION-PROMPT-v1.75.2-FULL.md— драйвер релізного шлюзу за повною поверхнею, оновлений під цикл агрегаторів сканування v1.75.x.
[1.75.1] — 2026-06-19
fix(scan): доопрацювання надійності джерел на основі конфігурації з v1.75.0. Три невеликі зміцнювальні виправлення за підсумками післярелізного розбору (без зміни поведінки за штатного сканування):
- Паузи пагінації з урахуванням скасування. Міжсторінкові ввічливі паузи Glints (300 мс) та Jobstreet/SEEK (200 мс) тепер негайно завершуються, коли спрацьовує
AbortSignalсканування — через новий помічникdelay(ms, signal)уserver/lib/http-json.mjs, тож від’єднаний клієнт не може утримувати пагіноване сканування відкритим ще на одну паузу. - Описова помилка для не-JSON відповіді.
fetchJsonтепер загортає не-JSON тіло з кодом2xx(наприклад, HTML-сторінку обслуговування, віддану зі статусом 200) якnon-JSON 2xx response from <url>, замість того щоб видавати голийSyntaxError, тож журнал помилок сканера за кожним джерелом називає некоректно поводжуваний ендпоінт. - Посилена нормалізація запису сканування.
normalizeScanScalarтепер згортає вертикальну табуляцію, переведення сторінки та розділювачі рядка/абзацу Unicode (\v \f U+2028 U+2029) на додачу до\r \n \t— суворий надмножина, тож жоден розділювач запису/рядка, який могли б врахувати таблиця чи переглядач, не потрапляє доscan-history.tsv.
[1.75.0] — 2026-06-19
feat(scan): переносить паритет з батьківським career-ops v1.12.0 — сім нових джерел вакансій, фільтрація контенту та виправлення безпеки/якості. web-ui запускає власні внутрішньопроцесні сканери (він не викликає shell out до батьківського scan.mjs), тож зміни провайдерів і сканування з батьківської v1.12.0 не надходять автоматично — цей реліз переносить застосовні з них згідно з контрактом адаптерів web-ui.
- Сім нових джерел сканера. Три глобальні агрегатори віддалених вакансій — RemoteOK, Remotive, Working Nomads — вписуються в автоматично виявлюваний патерн
server/lib/sources/*.mjs(обираються черезprovider: remoteok/remotive/workingnomads). Чотири керовані конфігурацією регіональні агрегатори — careers IBM, Arbeitsagentur (німецьке Федеральне агентство зайнятості), Glints (Південно-Східна Азія), Jobstreet / SEEK — читають поелементний конфігураційний блок<provider>:; en-scanner тепер прокидає розв’язаний запис компанії аж до кожного фетчера, щоб вони могли його прочитати. Усі сім автоматично з’являються у випадному списку джерел#/scan. content_filter(батьківський #974). Необов’язковий блокportals.yml(списки ключових слівpositive/negative), що фільтрує вакансію за текстом її опису/сніпета — повторює семантикуlocation_filter; вакансії без опису завжди проходять. Підключений до обох сканерів — EN і RU.- Посилення запису під час сканування (батьківський #1098). Метадані зовнішніх стрічок тепер санітизуються перед потраплянням у
data/scan-history.tsvтаdata/pipeline.md: керівні символи згортаються (перенесення рядка в назві компанії/посади більше не може ін’єктувати рядок TSV), а провідні= + - @нейтралізуються проти ін’єкції формул електронних таблиць. secondaryLocationsAshby (батьківський #1073). Джерело Ashby тепер згортає мітку регіону кожної вторинної локації разом із поштовимиaddressLocality/addressCountryу рядок локації (з дедуплікацією), тож роль із правом працювати в ЄС, чия основна мітка читається, наприклад, як “Canada”, спливає дляlocation_filter.- Валідація форми звіту про оцінку (батьківський #819). Внутрішньопроцесні провайдери
/api/evaluate(Anthropic / OpenAI / Qwen / OpenRouter / GitHub Models) тепер позначають некоректний звіт A–G /SCORE_SUMMARYяк нефатальний масивwarnings; шлях оцінки Gemini вже успадковує цей захист від батьківськогоgemini-eval.mjs. - docs: Antigravity CLI додано до списків підтримуваних асистентів у всіх 12 README (зіставляється з провайдером Gemini).
Успадковано безкоштовно з git pull батьківського проєкту (web-ui викликає їх через shell out): резервні шрифти CJK для японського PDF (#1053), ATS-сумісні шрифти PDF (#1074), захист CJK для LaTeX (#1054), виправлення tracker/merge/followup/dashboard і китайські режими modes/zh (web-ui перелічує режими динамічно).
[1.74.3] — 2026-06-18
docs(parent-source): спрямовує батьківський репозиторій career-ops на форк Fighter90/career-ops. web-ui тепер посилається на форк супровідника як на батьківський проєкт усюди, де це реальне джерело: типове значення CAREER_OPS_REPO в інсталяторі bin/setup.sh, кожне посилання git clone / «побудовано на основі» / онбординг у всіх 12 README, а також документація агентів (CLAUDE.md, AGENTS.md, GEMINI.md, .github/copilot-instructions.md, docs/). Зазначення авторства santifer (та застереження про неофіційний інтерфейс) не змінилося — перемістилися лише URL джерела/клонування. tests/sh-files.test.mjs тепер перевіряє, що інсталятор клонує форк.
[1.74.2] — 2026-06-17
fix(health): відображення GITHUB_MODELS_API_KEY як необов’язкової перевірки на #/health та в /api/status/providers. Провайдер GitHub Models із v1.74.0 налаштовувався в #/config, але не мав рядка на сторінці Health і був відсутній у провайдерській поверхні keysConfigured. Додано необов’язкову перевірку (з тим самим формулюванням “set / unset (manual mode)”, що й у решти п’яти провайдерів живого оцінювання) та github (+ його GITHUB_MODELS_MODEL) до /api/status/providers, тож маршрутизація активного провайдера й сторінка Health тепер відображають усі шість. Тест рядка health у tests/api.test.mjs розширено на всі шість провайдерів.
[1.74.1] — 2026-06-17
docs + test: розділ README «Встановлення ШІ-асистента»; повне покриття гілок для конектора Gemini. До README додано таблицю встановлення/входу — посилання для встановлення Claude Code / Gemini CLI / Codex / Qwen Code / OpenCode / GitHub Copilot CLI + відповідність постачальника #/config для кожного + «увійдіть перед продовженням» (відповідає розділу швидкого старту career-ops.org/docs; пояснює, що web-ui є автономною альтернативою, яка не потребує CLI). Новий tests/gemini-connector.test.mjs (8 сценаріїв) охоплює кожну гілку runGemini — без ключа, успіх, помилка API, порожнє/заблоковане завершення, некоректне тіло відповіді, тайм-аут, мережева помилка, hasGeminiKey — доводячи server/lib/gemini.mjs до 100% за інструкціями. Загальне покриття: 96% рядків / 88% гілок / 96% функцій. Набір тестів 1126 → 1134.
[1.74.0] — 2026-06-17
feat(llm): GitHub Models (Copilot) як 6-й провайдер + канонічне вирівнювання 6 асистентів. career-ops.org/docs перераховує шість ІІ-асистентів для написання коду — Claude Code, Gemini CLI, Codex, Qwen Code, OpenCode, GitHub Copilot CLI. Тепер web-ui підтримує всі шість: п’ять відповідають наявним активним провайдерам (Anthropic / Gemini / OpenAI / Qwen / OpenRouter), а GitHub Copilot CLI отримує виділений конектор GitHub Models — runGitHubModels (OpenAI-compatible; PAT GitHub з областю models), що налаштовується в #/config (GITHUB_MODELS_API_KEY + GITHUB_MODELS_MODEL) і вибирається через LLM_PROVIDER=github; 6-й у порядку auto. Пакети довідки та README тепер перераховують канонічні шість (перейменовано Qwen CLI→Qwen Code; додано Gemini CLI + GitHub Copilot CLI), а README додає повну таблицю посилань на режими та адаптери порталів на career-ops.org/docs, щоб кожна функція відстежувалась до батьківського проекту. tests/llm-provider-context.test.mjs розширює матрицю меж отримання до всіх шести провайдерів (cv.md + profile.yml вбудовані + повернутий артефакт); нові ключі GITHUB_MODELS_* додані до всіх 12 словників локалей. Набір тестів 1125 → 1126.
[1.73.0] — 2026-06-17
feat(llm): універсальний конектор Gemini + верифікований контекст CV/профілю для всіх провайдерів. Додано server/lib/gemini.mjs (runGemini) — клієнт Gemini generateContent без зовнішніх залежностей, що повертає ту саму форму {markdown, usage, error}, що й клієнти, сумісні з Anthropic / OpenAI. Виправлення: /api/mode/:slug і /api/deep раніше спрямовували промпти через gemini-eval.mjs, призначений виключно для оцінювання вакансій, через що Gemini Run live повертав оцінку замість запитаного артефакту (супровідний лист, аутрич, бриф). Тепер вони викликають runGemini з bundleProjectContext, тому cv.md + config/profile.yml вбудовуються інлайн для Gemini так само, як і для всіх інших провайдерів — листи та брифи є детальними й персоналізованими. Новий tests/llm-provider-context.test.mjs імітує HTTP-межу кожного провайдера та перевіряє, що всі п’ять (Anthropic / Gemini / OpenAI / Qwen / OpenRouter) вбудовують cv.md + profile.yml інлайн і повертають артефакт (матриця mode + deep + evaluate, 9 випадків). /api/evaluate зберігає свій gemini-eval.mjs, налаштований під вакансії. Suite 1116 → 1125.
[1.72.0] — 2026-06-17
feat(modes): Run live тепер повертає підсумковий артефакт безпосередньо (контракт виведення за один запит). Батьківські шаблони modes/<slug>.md написані для інтерактивних сесій Claude Code — деякі з них (cover, contacto та інші) роблять паузу, щоб задати уточнювальні запитання перед формуванням результату, через що Run live у вебінтерфейсі видавав анкету замість артефакту. buildModePrompt тепер огортає кожен режим у неінтерактивний контракт виведення: виконує аналіз (розбір вакансії, нотатки про компанію, ключові слова ATS, розбіжності профілю↔вакансії, вибір тону/подачі) у фоновому режимі, обирає розумні значення за замовчуванням із cv.md / config/profile.yml для всього, про що шаблон зазвичай питав, і виводить лише підсумковий артефакт — із завершальним нагадуванням для кожного режиму «output ONLY {the cover letter / outreach message / …}». Тепер клік на Run live у #/cover повертає саме супровідний лист; те саме виправлення застосовується до всіх загальних режимів (cover, contacto, interview-prep, project, training, followup, patterns) у всіх 12 локалях (артефакт створюється мовою інтерфейсу через директиву локалі). Suite 1103 → 1116.
[1.71.2] — 2026-06-17
docs(i18n): публікує прохід з узгодженості документації. Блок “Translations of this guide” у кожному README тепер містить усі 11 мов-«сестер» (раніше деякі пропускали English/Français або мали посилання на самих себе), а порожній рядок перед роздільником розділу відновлено. Повний QA-запит регресійного тестування перейменовано на поточну версію, а документацію (CLAUDE.md, CONVENTIONS, LOCALIZATION, PROJECT-CONTEXT) синхронізовано з поточною версією та кількістю тестів (1103). Жодних змін у коді чи поведінці — лише документація, тому переклади довідки/UI та всі функції версій 1.70.0–1.71.1 залишаються без змін.
[1.71.1] — 2026-06-17
fix(i18n): вбудований посібник із довідки тепер повністю перекладено всіма 12 мовами. Додано docs/help/{pl,uk,ar}.md (кожен містить перевірену структуру 19 H2 / 75 H3), завдяки чому #/help надає нативний пакет польською, українською та арабською мовами замість переходу на англійську — GET /api/help/{pl,uk,ar} тепер повертають власну локаль. Підключено до всіх перевірок довідки (help-ui, help.test, help-ru-config-section, canonical-docs-coverage). Також завершено всі списки перекладів на 12 мов: блок «Translations of this guide» у README (9 файлів README), заголовки «Translations:» у локалізованих CHANGELOG (8 файлів) та оновлено застарілі лічильники документації. Suite 1100 → 1103.
[1.71.0] — 2026-06-16
feat(cover): генерація PDF супровідного листа безпосередньо з #/cover. Режим cover (доданий у v1.70.0) формує текст листа; тепер у результаті з’являється кнопка Generate PDF, яка рендерить його через спільний вбудований конвеєр markdown→PDF (POST /api/stream/pdf/inline → generate-pdf.mjs) — той самий шлях, що використовує interview-prep. Тепер можна створити лист і надіслати PDF, не залишаючи SPA.
test/docs: посилення перевірки v1.70.0. Додано CI-ізольоване покриття для режиму cover (список дозволів + збірка промпту), перемикача <select> прапорів + арабського RTL (dirFor/<html dir>), top.langLabel у кожній локалі, підключення PDF супровідного листа, а також директиви локалі prompts.mjs + скаффолдингу для fr/pl/uk/ar. Оновлено застарілі посилання «всі 8» → 12 локалей у docs/sdd/CONVENTIONS.md і в промпті регресійного QA всього проєкту.
career-ops-ui v1.267.1 · page 7/12 · mirror of the project changelog for cvstart.org