Журнал змін

GitHub

Кожна значуща зміна, реліз за релізом. Той самий файл постачається в репозиторії та перекладений усіма 19 мовами.

[1.150.0] — 2026-08-12

Узгоджені порожні стани (шліфування Phase 4) — кожна панель «поки нічого немає» тепер малюється єдиним спільним стилем .empty, замість того щоб деякі подання переоголошували вигляд інлайн із магічним 40px. Невелике виправлення візуальної узгодженості; порожні стани #/activity, #/cv-studio, #/stats і #/usage тепер збігаються з усіма іншими (токенізований відступ 48px + пунктирна рамка).

Змінено

  • #/activity, #/cv-studio, #/stats, #/usage прибрали свій інлайн style: { padding: '40px', textAlign: 'center', color: 'var(--foggy)' } на порожніх панелях — усі три властивості вже дає спільний клас .empty (--space-7 = 48px, по центру, приглушено, пунктирна рамка). Тож ці чотири малюються ідентично до ~25 інших панелей .empty.
  • Правомірні перевизначення по поданню (#/dashboard width:100%, #/pipeline border:none) не чіпали — прибрано лише суто надлишкові переоголошення.

Примітки

  • Лише чистка використання CSS на клієнті — без зміни маршруту, сервера, ключа i18n чи правил CSS (сам клас .empty без змін); snapshot словника 1208. Перевірено в браузері (порожня панель #/usage обчислює 48px відступу + пунктирну рамку, 0 помилок консолі).
  • Новий канарковий тест tests/empty-state-consistency.test.mjs тримає .empty єдиним джерелом істини. Phase 5 (провайдер Hermes) лишається заблокованою.
  • Набір: 2385 тестів (+2: tests/empty-state-consistency.test.mjs).

[1.149.0] — 2026-08-12

Портали перенесено до Налаштувань (Phase 4) — #/portals тепер у групі навігації Setup, поруч із Налаштуваннями застосунку, а не під Sourcing. Із v1.144.0 це екран налаштувань (увімкнення/вимкнення відстежуваних компаній + перевірка стану ATS), а не дія сорсингу — тож саме тут його місце. Зміна лише навігації; сторінка та її маршрут без змін.

Змінено

  • Елемент навігації #/portals → група Setup (у public/index.html), розміщено одразу після Налаштувань застосунку. Прибрано з групи Sourcing (у ній лишаються Scan / Pipeline / Auto-pipeline / Профінансовані компанії). Маршрут #/portals, подання та підпис nav.portals без змін — зсунулася лише позиція на бічній панелі.

Примітки

  • Лише розмітка навігації — без зміни маршруту, подання, ключа i18n чи сервера. Перевірено в браузері (0 помилок консолі); захищено tests/portals-nav-placement.test.mjs.
  • Набір: 2383 тестів (+2: tests/portals-nav-placement.test.mjs).

[1.148.0] — 2026-08-12

Охайніші фільтри сканування (Phase 4) — панель фільтрів тепер акуратна сітка — панель фільтрів #/scan перейшла з рваного flex-wrap із жорстких блоків змінної ширини на адаптивну сітку, а дії «Застосувати / Скинути» тепер займають власний окремий рядок із вирівнюванням праворуч. Фільтри ті самі, поведінка та сама — просто читати зручніше. Дизайнерське шліфування (без parent-sync).

Змінено

  • Панель фільтрів #/scan → адаптивна сітка — .scan-filters тепер display: grid зі стовпцями repeat(auto-fill, minmax(180px, 1fr)) та рівномірними проміжками, тож 11 підписаних фільтрів вишиковуються в охайні колонки за будь-якої ширини, а не рвано переносяться в рядок.
  • Дії «Застосувати / Скинути» охоплюють усю сітку у власному рядку, відокремлені тонкою лінією та вирівняні праворуч. Прибрано старий трюк із прихованою міткою + внутрішній flex-обгортку в scan.js.

Примітки

  • Лише CSS + невелике прибирання DOM — усі id фільтрів (#scan-filter-*, #scan-apply) та зв’язку SR.render() не змінено, тож потік Playwright не зачеплено. Нових ключів i18n немає.
  • Перевірено в браузері (0 помилок консолі); захищено tests/scan-filters-grid.test.mjs.
  • Набір: 2381 тестів (+3: tests/scan-filters-grid.test.mjs).

[1.147.0] — 2026-08-12

Hermes & Telegram — розділ вбудованої довідки + поверхня на cvstart.org (Phase 5b, частина 2) — друга й остання частина роботи над документацією Hermes: інструкція тепер живе всередині власної довідки застосунку всіма 17 мовами, а вбудований асистент документації відповідає на її основі на запитання про Hermes. Це й досі лише документація — шлях LLM-провайдера Hermes залишається запланованим / ще не підключеним (Phase 5).

Додано

  • Вбудована довідка §30 «Hermes & Telegram» × 17 мов — новий розділ (що таке Hermes + дві форми інтеграції; запуск на хмарному сервері; Telegram через Hermes + правило «що НЕ показувати»), доступний з #/help. Grounding у docs-assistant / DocsFab підхоплює його автоматично, оскільки обидва читають docs/help/<lang>.md.
  • cvstart.org — посилання на посібник з Hermes з переходом на документ у GitHub.

Змінено

  • Поріг пакета довідки піднято 29 → 30 H2 / 105 → 108 H3 (canonical-docs-coverage, help-ui, help-ru-config-section); §30 додає 3 H3.

Примітки

  • Hermes і досі ніщо не викликає. Новий канарковий тест tests/help-hermes-section.test.mjs перевіряє, що всі мови містять §30 з її незалежними від мови якорями (docs/integrations/HERMES.md, hermes-bridge, #/help, 127.0.0.1, Telegram). Провайдер залишається заблокованим до контракту API з Phase 5.
  • Це завершує постачання документація + skill для Phase 5b; інтеграція провайдера (Phase 5) залишається окремим заблокованим пунктом.
  • Набір: 2378 тестів (+2: tests/help-hermes-section.test.mjs).

[1.146.0] — 2026-08-12

Агент Hermes + Telegram — посібник з інтеграції + skill (Phase 5b, частина 1) — можна запустити career-ops-ui на хмарному сервері та передавати його події (завершений скан, новий звіт, термінове нагадування) у Telegram через агента Hermes від Nous Research. Цей реліз додає документацію з дизайну + розгортання та skill hermes-bridge; шлях провайдера LLM Hermes залишається запланованим / ще не підключеним (заблокований спайком щодо контракту API Phase 5). Документація свідомо йде попереду коду.

Додано

  • docs/integrations/HERMES.md — докладний розбір: дві форми інтеграції (endpoint, сумісний з OpenAI, проти агентного runtime), розгортання на хмарному сервері (reverse proxy + HTTPS + systemd, контракт «лише читання» з parent на headless-машині), Telegram через Hermes, і список моделі загроз «що НЕ можна показувати» (жодних CV / зарплат / тіл звітів / ключів у канал).
  • Тизер ## Hermes agent + Telegram у README — короткий вказівник-посилання в англійському README, відображений у всіх повністю перекладених локалізованих README.
  • Skill hermes-bridge (.claude/skills/hermes-bridge/), що реалізує посібник на практиці — перевірки передумов і межі охоплення (Node ≥ 18, наявність ключів, доступність endpoint через безпечний щодо SSRF шлях), ніколи не записує секрети на диск/у логи й відмовляється вигадувати endpoint Hermes або стверджувати, що провайдер підключений.
  • Розділ Integrations у docs/architecture/OVERVIEW.md посилається на посібник.

Примітки

  • Наразі ніщо не викликає Hermes. Канарковий тест (tests/hermes-docs.test.mjs) перевіряє маркери чесності «заплановано / ще не підключено» і те, що в llm-dispatch.mjs немає жодної гілки Hermes/Nous — тож підключення провайдера пізніше має оновити документацію + roadmap в тій самій зміні.
  • Відкладено до v1.147.0 (Phase 5b, частина 2): розділ довідки в застосунку «Hermes & Telegram» H2 × 17 мов та маркетингова сторінка cvstart.org.
  • Набір: 2376 тестів (+4: tests/hermes-docs.test.mjs).

[1.145.0] — 2026-08-12

Проникливі статистики (продовження): перебудовуваний графік — вкладка «Тренд цільових ролей» на #/stats тепер має віджет Побудувати графік: виберіть метрику × вимір, і він перемальовується наживо. Запит UX від користувача (без parent-sync).

Додано

  • Перебудовуваний графік метрика × вимір — виберіть метрику (Вакансії / Медіанна зарплата / Середня зарплата) і вимір (За країнами / За ролями), і стовпчиковий графік миттєво перемальовується. Зарплатні метрики враховують валюту + перемикач рік ⇄ місяць; вакансії — простий підрахунок.
  • 8 нових ключів i18n × 17 локалей; snapshot 1200 → 1208.

Примітки

  • Перевірено в браузері (0 помилок консолі). Набір: 2372 тестів (+2).

[1.144.0] — 2026-08-12

Налаштування та фільтри (Фаза 4, частина 1): увімкнення/вимкнення відстежуваних порталів — тепер можна вмикати чи вимикати відстежувану компанію на #/portals, і сканер це враховує. Запит UX від користувача (без parent-sync).

Додано

  • Перемикач Увімкнути/Вимкнути для компанії на #/portals — один клік вимикає портал (EN-сканер уже пропускає компанії enabled: false, тож вимкнений портал випадає з усіх майбутніх сканів) або вмикає назад, з оптимістичним тостом.
  • POST /api/portals/toggle — явний запис користувача, який хірургічно та з перевіркою парсингу перемикає прапорець enabled компанії в portals.yml (коментарі, порядок та інші поля збережено). 5 нових ключів i18n × 17 локалей; snapshot 1195 → 1200.

Примітки

  • Зміна сканера — нуль: en-scanner.mjs уже фільтрує enabled !== false. Набір: 2370 тестів (+3).

[1.143.0] — 2026-08-12

Зрозумілість (продовження): підказки ? на основних робочих сторінках — довідкове ? тепер охоплює дев’ять головних сторінок дій, усіма мовами. Правка UX за репортом користувача (без parent-sync).

Додано

  • Підказка ? ще на 9 заголовках — #/scan, #/evaluate, #/cv-studio, #/tracker, #/config, #/deep, #/batch, #/auto, #/apply отримали вбудоване ? (через HelpHint.title), що відкриває локалізоване «що це / як використовувати / який результат» — той самий CSP-безпечний компонент із v1.139.0.
  • 9 нових ключів i18n × 17 локалей (help.hint.scan/…/apply); snapshot 1186 → 1195.

Примітки

  • Перевірено в браузері (0 помилок консолі). Набір: 2365 тестів (+1).

[1.142.0] — 2026-08-12

Виправлення: більше немає «Unknown» кар’єрного архетипу — #/orientation тепер завжди ранжує з восьми названих кар’єрних векторів, а не відповідає інколи «Unknown» і не радить «подвоїти ставку» на ньому. Правка за репортом користувача (без parent-sync).

Виправлено

  • #/orientation — промпт ШІ тепер забороняє архетип поза набором. Модель МУСИТЬ ранжувати топ-3 рівно з восьми названих векторів і ніколи не відповідати «Unknown»/«N/A»/«недостатньо даних» та не вигадувати мітку. За бідного резюме вона все одно називає три найближчі з меншою впевненістю і вказує, яких доказів бракує.

Примітки

  • Лише зміна серверного промпту (buildOrientationPrompt); без змін i18n/схеми. Набір: 2364 тестів (+1).

[1.141.0] — 2026-08-12

Проникливі статистики (продовження): збагачення профінансованих компаній — #/funded став наочнішим: логотипи компаній, графік за сумою фінансування та картки з раундом / сумою / оцінкою знахідки / рекомендованою дією. Правка UX за репортом користувача (без parent-sync).

Змінено

  • #/funded — плоска таблиця → сітка карток. Кожна нещодавно профінансована компанія тепер картка з логотипом (з назви через CompanyLogo, запасний варіант — літерний аватар), чипами раунду + суми, оцінкою знахідки та рекомендованою дією від батьківського проєкту, а також посиланням на новину і датою.
  • Візуалізація суми фінансування — горизонтальний стовпчиковий графік найбільших компаній за розкритою сумою; вільний текст сум (“$120M”/“€1.5B”) парситься у величину новим parseAmount. 3 нових ключі i18n × 17 локалей.

Примітки

  • Досі лише для читання через GET /api/company-funded; опису й вилки зарплат у стрічці фінансування немає. Набір: 2363 тестів (+2).

[1.140.0] — 2026-08-12

Проникливі статистики: багатші дані про зарплати — розбивка зарплат у «Мій пайплайн» на #/stats тепер показує середнє (не лише медіану), перемикач на рік ⇄ на місяць і таблицю мін · сер · медіана · макс за країнами. Перша частина Фази 3. Правка UX за репортом користувача (без parent-sync).

Додано

  • Середня зарплата — RoleStats.salaryStats тепер повертає avgUsd поряд із minUsd/medianUsd/maxUsd. Медіана стійка до викидів, середнє показує перекіс — разом вони читаються як розподіл.
  • Перемикач на рік ⇄ на місяць і таблиця мін · сер · медіана · макс за країнами в розділі зарплат, з урахуванням валюти й періоду. 8 нових ключів i18n × 17 локалей.

Примітки

  • Цифри й далі беруться лише з вакансій із розпізнаваною зарплатою і нормалізуються до USD (орієнтовно). Набір: 2361 тестів (+1).

[1.139.0] — 2026-08-12

Зрозумілість: підказки ? — багаторазова, безпечна для CSP кнопка ?, яка за кліком пояснює «що це / як працює / чого очікувати» вашою мовою. Правка UX за репортом користувача (без parent-sync).

Додано

  • Спливна підказка ? (window.HelpHint) — кругла ? біля заголовка відкриває легке, залежне від теми та дзеркалене в RTL спливне вікно, що відображає локалізоване пояснення через UI.md(); доступно (role="tooltip", aria-expanded, закриття Escape/кліком поза, повернення фокуса) та безпечно для CSP.
  • ? на 5 вкладках #/stats і на 8 заголовках ШІ/аналітичних екранів (career-plan, орієнтація, two-pager, нетворкінг, мок-інтерв’ю, пам’ять, funded, щотижневий підсумок) — 14 нових ключів i18n × 17 локалей.

Примітки

  • Усі екрани вже мали однорядковий підзаголовок; ? додає глибше пояснення на вимогу й робить порожні стани самоочевидними. Набір: 2360 тестів (+4).

[1.138.0] — 2026-08-12

Генерація мовою інтерфейсу — кожна AI-генерація тепер відповідає мовою, обраною в інтерфейсі, плюс посилення тестів за підсумками рев’ю. Правка UX за репортом користувача (без parent-sync).

Змінено

  • AI-генерації тепер враховують мову інтерфейсу. Якщо інтерфейс російською, іспанською, японською тощо — згенерований текст повертається цією мовою, а не завжди англійською. Директиву мови виводу проброшено в усі ендпоінти генерації — кар’єрний план, орієнтацію, звіт по ринку, мок-інтерв’ю, план нетворкінгу, «запитати документацію», пропозицію нотатки пам’яті та чернетку two-pager. Код та ідентифікатори лишаються англійською (напр., ключі YAML у two-pager); локалізуються лише проза, заголовки та пункти.

Виправлено

  • Вартовий CSS-ролей кольору (tests/css-role-tokens.test.mjs) — статичний канарок, що аліас-токени темної теми з v1.137.0 ніколи не змінюють роль: текстові токени (--fg/--danger/--ok/…) ніколи як background, а токени поверхонь (--card/--panel/--line/…) — як текстовий color, у всьому CSS та inline-стилях SPA.
  • Самоперевірка XSS-завантажувача UI.md() — тест, що через vm вантажить md() з api.js, тепер одразу після витягання перевіряє md('<script>…') і кидає помилку, якщо екранування зникло, — тож майбутній збій нарізки падає гучно, а не лишає security-набір зеленим на усіченій функції.
  • Вартовий прокрутки на #/career-plan — scrollIntoView після генерації виконується лише якщо прев’ю ще приєднане до документа.

Примітки

  • docs/UX-ROADMAP.md оновлено: підказки ? + описи сторінок + порожні стани тепер v1.139.0; провайдер Nous Research / Hermes — з гайдом розгортання на хмарному сервері + Telegram і скілом Hermes — відстежується як Фаза 5 / 5b.
  • Набір: 2356 тестів (+5).

[1.137.0] — 2026-08-11

Виправлення читабельності та рендерингу — контраст темної теми, підписи графіків та кар’єрний план. UX-правка за повідомленням користувача (без parent-sync).

Виправлено

  • Білий на білому / чорний на чорному в темній темі на багатьох екранах — п’ятнадцять кастомних властивостей CSS, на які посилалися кілька вкладок (--fg, --panel, --panel-2, --ok, --danger, --card, …), ніколи не були оголошені, тож вони відкочувалися до захардкоджених світлих/чорних значень: у світлій темі це не заважало, але в темній робило текст нечитабельним (чіпи огляду #/pipeline, активна вкладка #/stats, «Активний / Ключі» + «✓ встановлено» на #/config, розділи #/two-pager, бульбашка питання #/mock-interview, текст помилок). Тепер вони прив’язані псевдонімами до справжніх токенів, що враховують тему, тож автоматично слідують за нею — 0 порушень контрасту WCAG-AA на всіх 29 вкладках, підтверджено автоматизованим аудитором; активна вкладка #/config отримала читабельний тонований стиль. Регресійний бар’єр (tests/dark-theme-tokens.test.mjs) утримує цю прив’язку псевдонімами.
  • Підписи графіків #/stats обрізалися посередині слова («Senior Backend Engineer» → «…Enginee») — тепер вони скорочуються трьома крапками, а повний підпис зберігається як підказка при наведенні.
  • #/career-plan показував згенерований план як необроблений Markdown — тепер він автоматично рендериться як форматований, читабельний текст (редагований Markdown залишається в текстовому полі; кнопка «Перегляд» перемикає режим).

Примітки

  • #/career-plan, #/two-pager, #/stats та щотижневий дайджест інтерв’ю не зламані — вони показують порожні стани, доки ви не згенеруєте план / не матимете даних. Наступним кроком запланована зрозуміліша підказка на сторінці та довідкові підказки ? (docs/UX-ROADMAP.md).

[1.136.0] — 2026-08-11

Паритет із батьківським career-ops v1.26.x (після мейнлайну v1.26.0) — одне нове джерело без авторизації плюс хвиля портів якості та надійності для дзеркал web-ui. Реєстр тепер налічує 79 джерел = 74 англомовних + 5 російськомовних (ALL_ADAPTERS 74).

Додано

  • eightfold (Eightfold AI, #2684) — дошки з підбору персоналу через API без авторизації https://<tenant>.eightfold.ai/api/apply/v2/jobs, прив’язане до хоста *.eightfold.ai (брендований CNAME careers.<company>.com свідомо відхиляється); пагіноване з обмеженням безпеки, відмовою для неактивної дошки, дедуплікацією URL. Джерело + адаптер + CI-ізольований набір тестів; з’являється у фільтрі джерел #/scan та на лендінгу.

Виправлено

  • Unicode-орієнтована дедуплікація та ключі ролей (#2569 / #2587 / #2667) — нова спільна normalizeTextKey (NFKC, зберігає літери/знаки/цифри будь-якого письма) замінює ASCII-лише ключі: detect-reposts тепер групує варіанти назв компаній з різною шириною символів/пунктуацією («Acme, Inc.» ≡ «Acme Inc») і ніколи не зливає різних неЛатинських роботодавців, а role-matcher згортає повноширинні назви посад і зберігає неЛатинські токени ролей, а не стирає їх.
  • fetchJsonWithRetry більше не повторює відхилене перенаправлення (#2657) — захист redirect:'error', що натрапляє на 3xx, є детермінованим, тож тепер він неповторюваний і завершується швидким провалом, замість витрачання бюджету повторних спроб.
  • AND-групи title_filter.positive (#2552) — розділений пробілами + усередині позитивного запису тепер вимагає, щоб усі терміни зустрічалися в назві, у будь-якому порядку.
  • oraclecloud приймає нумеровані апекси орендаря oraclecloud1.com … oraclecloud99.com (#2683) — обмежене сімейство (без провідного нуля, ≤ 2 цифри), ніколи не символ підстановки апекса.
  • workable посилено (#2675) — повторні спроби, схожі на браузерні заголовки та серіалізація запитів проти хоста за Cloudflare.
  • personio переходить на HTML-скрейп, коли XML-стрічка вимкнена, замість повернення нічого.
  • Резервні псевдоніми states FALLBACK ресинхронізовано з батьком (#2615).

Примітки

  • Не портовано (не дзеркалюється web-ui, або лише для CLI): reply-matcher (#2672), jd-similarity (#2661), jd-skill-gap (#2686), розбір env-шляху сканування (#2568) / --flag=value (#2589), а також зміни cover-letter / шаблону CV / doctor / ollama / generate-pdf. HIGH-рекомендації web js-yaml/nanoid уже виправлено в web-ui v1.135.0.

[1.135.0] — 2026-08-11

Паритет із батьківським career-ops v1.26.0 — п’ять нових джерел сканування без авторизації плюс виправлення коректності для чотирьох дощок, які web-ui вже підтримує. Реєстр тепер налічує 78 джерел = 73 англомовних + 5 російськомовних (ALL_ADAPTERS 73).

Додано

  • П’ять нових джерел сканування (кожне — джерело + адаптер + CI-ізольований набір тестів; з’являються у фільтрі джерел #/scan та на лендінгу cvstart.org):
    • join (JOIN) — дошка вакансій компанії JOIN зі сторінки join.com/companies/<slug>, зчитана з Next.js __NEXT_DATA__ (прив’язка до хоста, обмеження за кількістю сторінок).
    • getro (Getro) — портфельні дошки «talent-network» венчурних фондів через публічний POST API api.getro.com, з пагінацією від найновіших; кожна вакансія приписується компанії-портфелю, а не самому фонду.
    • consider (Consider) — портфельні дошки венчурних фондів getconsider.com через POST-запит того ж походження; конфігурований хост прив’язаний структурним захистом від SSRF (лише публічний HTTPS-хост).
    • joinup (JOINUP) — швейцарська дошка joinup.ch, зчитування SSR-рендерованої найновішої сторінки; при поломці скрапера — відмова закритого типу (fail-closed).
    • remotli (Remotli) — remotli.ch, віддалені ролі у швейцарських компаніях (зарплати в CHF); видає власне посилання подання (apply URL) ATS роботодавця, тож перехресні лістинги дедуплікуються.

Виправлено

  • a16z Speedrun більше не переривав весь борд через тимчасовий збій — запити сторінок тепер проходять через спільну fetchJsonWithRetry (обмежені повторні спроби лише на тимчасових 429/5xx/таймаут, ніколи на постійних 4xx), а бюджет сторінки перерахований під сторінку з 50 вакансіями.
  • arbeitsagentur перенесено на API Jobsuche v6 (/pc/v6/jobs) — старий v4-ендпоінт видає 404; форму відповіді перейменовано, а фільтрація «remote» тепер звужується на боці сервера.
  • thehub перенесено на API v2 jobsandfeatured; рядки не містять дати публікації і звільнені від фільтра за віком.
  • hackernews тепер надійно знаходить щомісячну гілку «Who is hiring?», фільтруючи пошук у Algolia за тегом облікового запису author_whoishiring замість довільнотекстового запиту.

Примітки

  • Не портовано (web-ui вже безпечний, поглинутий через relay, або лише для CLI): ключі Unicode-дедуплікації ролей / зіставлення компаній (групування репостів у web-ui вже ключує компанію за простим нижнім регістром, тож різні неЛатинські роботодавці ніколи не зливаються); сигнал затримки відмов followup + доопрацювання company-funded (реле лише для читання, з м’яким відмовленням); середовищно-перевизначувані шляхи сканування та розбір --flag=value (web-ui запускає сканери in-process); рефакторинг консолідації User-Agent (web-ui вже централізує його); а також елементи лише для CLI (реєстр недовіреного вмісту, oferta/offer-prep, doctor, зміни шаблонів супровідного листа/резюме).

[1.134.1] — 2026-08-05

Посилення валідації — виправлення, виявлені під час повного аудиту проєкту.

Виправлено

  • successfactors більше не відкидає зібрані вакансії при збої в середині сканування (регресія в портуванні «неактивна дошка = помилка» з v1.134.0) — цикл пагінації не мав try/catch, тож збій на сторінці 2+ (після успішної сторінки 1) призводив до винятку й губив усе вже зібране; а якщо цей збій був 404 (вихід startrow за межі діапазону), en-scanner міг на кілька днів помилково позначити живого орендаря як неактивного. Тепер дзеркалює phenom/radancy: збій на сторінці 0 досі видає помилку (неактивна дошка), а збій на пізнішій сторінці зберігає часткові результати.
  • Фільтр-чипи #/scan тепер керуються з клавіатури (WCAG 2.1.1) — чипи фасетів (і чип «очистити») були елементами span з обробником кліку, але без tabindex/ролі, тож користувачі клавіатури та програм читання з екрана не могли до них дістатися чи перемикати їх. Тепер вони мають role="button", tabindex="0", aria-pressed і активацію по Enter/Space.
  • Три захардкоджені англійські рядки тепер локалізовано — підказка бейджа довіри #/scan, заголовок колонки релокації #/scan та заголовок колонки балу #/dashboard були голими літералами, яких не бачив паритет-контроль i18n (вони ніколи не були ключами), тож вони залишалися англійськими в кожній неанглійській локалі. Тепер scan.trustTip + scan.col.reloc (2 нових ключі) + повторне використання track.col.score, зі статичною перевіркою на рівні коду.

[1.134.0] — 2026-08-05

Паритет із батьківським career-ops v1.25.0.

Додано

  • Нове джерело сканування: getManfred (manfred) — стрічка вакансій в іспанських/європейських технологічних компаніях по всьому борду з опублікованими зарплатами, з www.getmanfred.com/api/v2/public/offers (без авторизації, прив’язка до хоста + лише HTTPS, повний каталог одним запитом). Джерело + адаптер + CI-ізольований набір тестів (tests/sources-manfred.test.mjs); реєстр тепер налічує 73 джерела = 68 англомовних + 5 російськомовних (ALL_ADAPTERS 68). З’являється у фільтрі джерел #/scan та на лендінгу cvstart.org.

Виправлено

  • Стрічка a16z Speedrun тихо обрізалася до 50 вакансій (#2404) — стрічка обмежує сторінку 50 елементами, але джерело запитувало PER_PAGE = 100, тож пагінація зупинялася після першої сторінки. Виправлено на 50.
  • Неактивні дошки тепер видають помилку, замість того щоб читатися як «живі, але порожні» (#2379) — cryptocurrencyjobs, phenom, radancy, successfactors: збій запиту, коли жоден запит так і не завершився успіхом, тепер видає помилку (тож перевірка стану #/portals та сканування фіксують реальний збій), замість того щоб приховувати його за порожнім списком; збій у середині сканування після хоча б одного успіху зберігає часткові результати.
  • workable тепер використовує публічний widget API (#5ab8425) — перехід на apply.workable.com/api/v1/widget/accounts/<slug>, який повертає повний список вакансій великого акаунту за один запит, тож великі акаунти більше не обрізаються.

Примітки

  • Не портовано (лише для CLI або не дзеркалюється в web-ui): переробка продуктивності групування заголовків для виявлення репостів #2389; виправлення Unicode-ключів компаній (власна дедуплікація трекера web-ui вже безпечна для не-латиниці); scan --since; cv-facts; аудит-прохід шаблону CV / PDF; doctor; директива щодо недовіреного вмісту в режимах.

[1.133.1] — 2026-08-02

Виправлено

  • #/funded (Профінансовані компанії) тепер відображає результати — через два баги таблиця завжди показувала «немає профінансованих компаній», навіть коли батьківський company-funded.mjs повертав повний список. (1) Вигляд читав результати з res.candidates, а батьківський скрипт видає їх під ключем companies (кожен елемент — { company, amount, round, funding: { sources: [{ source, url, observed_date }] } }); клієнт тепер читає правильний ключ і мапить реальну форму доказів. (2) Таблиця результатів передавала свої комірки в UI.el('tr', {}, …) як varargs, але UI.el(tag, attrs, children) приймає children як один вузол або масив, тож рендерилась лише перша колонка (Компанія) — тепер комірки передаються як масив. Перевірено в реальному браузері: 11 компаній із чотирьох стрічок відображаються з колонками Компанія / Сигнал фінансування / Джерело / Дата та робочими посиланнями на докази, нуль помилок у консолі. Порожній прохід тепер також показує діагностику по кожному джерелу, щоб тихий новинний день можна було відрізнити від заблокованої стрічки.
  • Регресійні бар’єри в tests/parity-routes-v1133.test.mjs: фейковий батьківський скрипт тепер видає реальну форму виводу companies (початкова заготовка дзеркалила неправильну форму candidates — саме тому баг і потрапив у реліз із зеленими тестами), плюс статичні канарки джерела, що funded.js читає res.companies (ніколи не res.candidates) і будує рядки таблиці з дочірніми елементами-масивом (+1 → 2144).

[1.133.0] — 2026-08-01

Додано

  • Виявлення профінансованих компаній (#/funded, паритет із батьком #2117) — новий тільки-для-читання вигляд, що ретранслює батьківський company-funded.mjs career-ops через GET /api/company-funded: список нещодавно профінансованих компаній «спершу на перегляд», знайдених у публічних стрічках про фінансування з прив’язкою до хоста (TechCrunch, PR Newswire, The Guardian, Hacker News). Ретрансляція запускає скрипт з --json --dry-run (JSON у stdout, без запису файлів), ніколи не передає користувацький ввід у --sources, має обмеження частоти запитів і запускається лише користувачем (кнопка «Знайти», ніколи при монтуванні). Новий модуль маршруту server/lib/routes/funded.mjs + public/js/views/funded.js, у розділі «Пошук».
  • Щотижневий дайджест співбесід (#/interview-digest, паритет із батьком #2129/#2130) — новий тільки-для-читання вигляд, що ретранслює батьківський weekly-digest.mjs (без ШІ) через GET /api/interview/weekly-digest: механічне зведення нотаток сесій співбесід — з якими компаніями та на яких раундах ви проходили співбесіди цього тижня, повторювані компетенції та відкриті прогалини за принципом «найкраще зусилля». Необов’язковий діапазон ?from=&to= передається, лише якщо ОБИДВА параметри — валідні YYYY-MM-DD; порожній діапазон — це коректний дайджест available:true. Додано до server/lib/routes/interview.mjs + public/js/views/interview-digest.js, у розділі «Аналітика».
  • Обидві ретрансляції дотримуються усталеного контракту fail-soft available:false, коли батьківський скрипт відсутній (CI, автономні інсталяції). 26 нових i18n-ключів ×17 локалей; CI-ізольований набір tests/parity-routes-v1133.test.mjs (+5 → 2143).

Примітки

  • Батьківський career-ops просунувся далі за v1.24.0 зі сторінкою «Follow-up Tracker» застосунку Next.js web/ (#1422) та бекенд-рендером PDF (#2182) — не портовано: web-ui вже має власну ретрансляцію нагадувань і власні PDF-раннери, а посилення followup-cadence.mjs надходить безкоштовно через shell-out ретрансляцію. Зміни set-status.mjs / tracker-utils.mjs — внутрішні для CLI і не дзеркалюються.

[1.132.0] — 2026-07-31

Змінено

  • Підсистему рендерингу результатів #/scan винесено в public/js/lib/scan-results.js (борг за контрактом розміру файлу — public/js/views/scan.js розрісся приблизно до ~1254 рядків). Підсистема (renderResults, buildChipRow, getRows, конструктори рядків/фасетів, малювальники опцій і дзеркало реєстру FALLBACK_SOURCES) перенесена у фабрику window.ScanResults.create(ctx), що замикається на об’єкт контексту, який надає вигляд. Без зміни поведінки — функції перенесено дослівно, змінні замикання переприв’язано до ctx.*; scan.js тепер має ~906 рядків (другий прохід виділення до цілі в 800 рядків заплановано).
  • Тести, що читають вихідний код статично, тепер читають обидва файли через tests/helpers/scan-src.mjs::loadScanSrc(); tests/scan-fallback-sources.test.mjs тепер читає дзеркало реєстру з scan-results.js.
  • Новий регресійний бар’єр у браузері — tests/playwright-scan-filters.mjs засіває заготовлений data/last-scan.json і проганяє кожен фільтр #/scan, перевіряючи точну кількість рядків (npm run test:e2e:browser); для цього додано стабільні ідентифікатори фільтрів (#scan-filter-*, #scan-apply).
  • Банер «Останній реліз» у README скорочено до однорядкового підсумку + посилання на повний журнал змін (довгу багатоверсійну стіну опису прибрано). Застосовано в усіх 17 локалях.

[1.131.2] — 2026-07-31

Змінено

  • Поділ app.css на три впорядковані таблиці стилів (борг за контрактом розміру файлу — єдиний файл розрісся приблизно до 1990 рядків, значно перевищивши жорсткий ліміт у 800 рядків). Тепер це app.css (~672 — a11y, дизайн-токени/тема, бічна панель, основний контент, кнопки, оболонка вмісту), components.css (~595 — картки, сітки, пагінатор, бейджі, таблиці, форми, лог/консоль, markdown, перемикач мов, фільтр-чіпи, банер з’єднання) і overlays.css (~737 — тост, шухляда сповіщень, модальне вікно, різне/адаптивність, дзеркало [dir="rtl"], docs-fab, usage-hud) — кожен у межах жорсткого ліміту.
    • Розріз суцільний і в тому ж порядку, тож каскад побайтово ідентичний файлу до поділу; index.html завантажує всі три як впорядковані <link>. Без зміни поведінки, розмітки чи i18n.
    • Тести, що перевіряють CSS, тепер читають конкатенацію через спільний хелпер tests/helpers/css.mjs::loadAppCss(). Новий tests/css-modularization.test.mjs фіксує поділ (файли існують · кожен ≤ 800 рядків · порядок <link> в index.html) → набір 2138. Перевірено в браузері: усі три таблиці стилів парсяться і їхні правила застосовуються.

[1.131.1] — 2026-07-31

Виправлено

  • Узгодженість прив’язки хоста в адаптерах для двох джерел v1.130.0 (доопрацювання за код-рев’ю, багаторівневий захист; без зміни поведінки для коректних вхідних даних):
    • Адаптер a16z-speedrun-talent тепер повторно перевіряє перевизначення api: / a16z-speedrun-talent: у buildEndpoint (HTTPS + точний хост speedrun-talent-network.com) і в разі невдачі відкочується до канонічної стрічки — паритет з адаптером cryptocurrencyjobs, тож значення з іншим хостом ніколи не потрапляє у слот запиту (раніше це покладалося виключно на перевірку assertSpeedrunUrl під час запиту). Перевірка точного хоста тепер — єдиний експортований SPEEDRUN_TALENT_HOST_RE, спільний для перевірки й адаптера.
    • Парсер cryptocurrencyjobs — cleanUrl тепер використовує ту саму перевірку точної відповідності хоста, що й assertCryptocurrencyJobsUrl та перевизначення адаптера (було endsWith, яке приймало субдомени). Парсер ніколи не є поблажливішим за SSRF-перевірку: посилання елемента sub.cryptocurrencyjobs.co відкидається.
    • +2 тести → 2135.

[1.131.0] — 2026-07-31

Додано

  • Дошка стадій-вкладок CRM #/tracker (портовано з вигляду /pipeline батьківського веб-застосунку). Панель чіпів воронки трекера + випадний список статусу замінено на смугу вкладок стадій: вкладка Усі плюс по одній вкладці на кожен канонічний статус — Evaluated · Applied · Responded · Interview · Offer · Rejected · Discarded · SKIP · Hired — кожна показує живий лічильник за всю історію, включно зі стадіями з нульовим лічильником, тож уся воронка завжди видима (вигляд CRM). Активна вкладка керує фільтром; повторний клік на неї скидає назад до «Усі». Рядки зберігають тональність оцінки, легітимність, можливості PDF і звіту, а комірка компанії тепер показує бренд-логотип, коли логотипи увімкнено (вимкнено за замовчуванням → без додаткових запитів).
    • Новий тільки-для-читання маршрут GET /api/tracker/stages повертає канонічну воронку (мітки за порядком) + карту згортання псевдонімів, отримані з server/lib/states.mjs (templates/states.yml, із вбудованим фолбеком) — тож клієнт ніколи не хардкодить whitelist статусів. Застаріла відповідь GET /api/tracker без параметрів лишається незмінною (лише { rows }).
    • Нова чиста, покрита юніт-тестами клієнтська бібліотека public/js/lib/tracker-stages.js розкладає рядки за стадіями сервера, толеруючи випадковий markdown bold і локалізовані псевдоніми (наприклад, aplicado → Applied). Вкладки доступні (role tablist/tab, aria-selected, зона кліку ≥44 px, лічильники в доступному імені кожної вкладки). Нових i18n-ключів немає. Набір тестів 2133.

[1.130.0] — 2026-07-31

Додано

  • Два нові джерела сканування, портовані з батьківського career-ops v1.24.0 (in-process, без нових залежностей; обидва з’являються у фільтрі джерел #/scan і на лендінгу cvstart.org):
    • a16z Speedrun (a16z-speedrun-talent, #2231) — стрічка JSON усього борду talent-network a16z Speedrun. Прив’язана до хоста speedrun-talent-network.com, лише HTTPS, 0-індексована пагінація з обмеженням сторінок, наскрізне передавання q/конфігурації по компанії, fail-soft.
    • Cryptocurrency Jobs (cryptocurrencyjobs) — дошка вакансій Web3 cryptocurrencyjobs.co, отримується через публічну стрічку RSS 2.0 (без авторизації). Дворазове декодування XML-сутностей, лише віддалені вакансії, роботодавець розбирається з хвоста заголовка "… at <Company>".
    • Загальна кількість у реєстрі тепер 72 джерела = 67 англомовних + 5 російськомовних (ALL_ADAPTERS = 67 англомовних адаптерів порталів).

Виправлено

  • echojobs — гібридні ролі лишаються відмінними від віддалених (віддзеркалює батьківський #2258). Регістронезалежний маркер hybrid тепер дає "<Місто> · Гібрид" (або просто Гібрид, якщо міста немає) і workplaceType: 'Hybrid', замість згортання в Remote.
  • radancy — застаріла розмітка TalentBrew + транспорт JSON-фрагмента результатів (віддзеркалює батьківський a3e6df9), під контролем ін’єктованого opts.fetchJson.

Примітки

  • Не портовано — CLI-специфічні можливості батька. Великий CLI/режимний шар career-ops v1.24.0 лишається поза web-ui, який є переглядачем + тонким наскрізним записом, а не хостом режимів: таблиці комплаєнсу/юрисдикції, телефонна книга контактів + vCard, транскрипт-дебриф інтерв’ю / визначення платформи дзвінків, встановлення статусу в реєстрі, запис результату, двопрохідний трайдж, jd-подібність, версійована схема артефакту CV заявки, виявлення Playwright-MCP у doctor та portals/fix-slugs.mjs. Зміни оркестрації сканування, що живуть у батьківському scan.mjs — сканер Interamt.de на Playwright, повне сканування iCIMS зворотним ATS, фільтр віддаленості за прийнятністю країни, темп DNS-пошуку, дедуп StepStone rltr і нормалізована колонка компанії в історії сканування — не застосовуються: web-ui запускає сканери EN/RU in-process і не викликає scan.mjs.
  • Вже покрито. Фікс згортання діакритики в role-matcher (#2209) було портовано в v1.127.0, тож тут це no-op.

[1.129.1] — 2026-07-29

Виправлено

  • Доопрацювання за AI-рев’ю портів web з v1.128/v1.129 (усі дорадчі, виправлено в корені): порядок рівня в job-facets.js (явний модифікатор тепер перемагає управлінське слово — Senior Engineering Manager → senior, було lead); fallback у states.mjs більше не пінниться (успішне читання мемоїзується, fallback повертається без кешу — тимчасово недоступний батько на старті перечитується наступним викликом) + console.warn за присутнього, але пошкодженого файлу; score-tone.js — рядок без оцінки нейтральний (muted), не червоний; domainFromName() пропускає не-ASCII slug до /api/logo; +sanity-гард ізоляції в tests/states.test.mjs. +4 тести → 2073.

[1.129.0] — 2026-07-29

Додано

  • Фасет «Рівень» + колонка «Свіжість» у #/scan — бібліотека job-facets.js з v1.128.0 тепер вплетена в UI сканування (раніше лише логіка). Новий дропдаун Рівень розкладає заголовок кожної вакансії на lead/staff/senior/mid/junior/intern (JobFacets.seniorityFromTitle) і автозаповнюється тим, що реально є в результатах (як фасет «Країна»); заголовки без слова-рівня завжди проходять. Зберігається у збережених пошуках, Скиданні та Застосувати. У таблиці з’являються колонка Рівень (бейдж) і zero-token колонка Свіжість (сьогодні / Nдн, з JobFacets.daysSince). 12 i18n-ключів ×17, +3 тести → 2069.

[1.128.0] — 2026-07-29

Додано

  • Чотири рішення, портовані з власного веб-застосунку батька (../web/, Next.js) — переписані на ванільному JS/ESM, без нових залежностей: (1) server/lib/states.mjs читає templates/states.yml наживо як канонічний словник статусів трекера (з CI-fallback) — усуває ручний ре-синк whitelist щорелізу; POST згортає аліаси (іспанські/legacy) до канонічної мітки, funnel у GET групує за канонічним статусом; (2) логотипи компаній у ATS-хостованих рядках через domainFromName() (~90 бренд→домен); (3) score-tone.js — 4-рівневий тон оцінки (≥4.2/3.8/3.0 + літерний fallback); (4) job-facets.js — фасети seniority/source/days. +21 тест.

Примітки

  • Не портовано (лише концепт): агентський шар дій батька (actions/registry.ts + api/assistant/route.ts) — креслення на випадок, коли docs-fab стане копайлотом. Нових джерел немає (реєстр 70), змін i18n/help немає.

[1.127.0] — 2026-07-29

Додано

  • Три нові джерела сканування (паритет career-ops v1.23.0) — у реєстрі тепер 70 адаптерів (65 EN + 5 RU): Flowxtra (глобальний агрегатор без авторизації), VDAB (keyword-API фламандської служби зайнятості) та iCIMS (портали careers-<tenant>.icims.com, окремо від jibeapply). Крім того Cursor повертається до ростера CLI (parent #2115): cli-detect тепер виявляє cursor (10 інструментів), ростер відновлено в help/README/config ×17.

Виправлено

  • agenticjobs переведено зі скрейпінгу HTML на REST API (#2167); Greenhouse відновлює місто з /offices, коли location.name — лише модель роботи (#2104); паритет role-matcher (#1933/#2164/#2009: префікс MTS, базовий product, згортання акцентів, незгода sub-baseline).

Примітки

  • Не портовано. Більшість v1.23.0 — CLI/dashboard-поверхня, яку web-ui не викликає (batch-tailor, discover-ats, режими NL/PT, теми PDF, Go-дашборд, updater/doctor); релейні скрипти без змін. VERSION батька → 1.23.0.

[1.126.1] — 2026-07-25

Виправлено

  • Дві точки дрейфу ростера CLI, які пропустив ресинк v1.126.0 — (1) інтро вкладки API keys у #/config (config.providerModelNote, i18n ×17) перелічувало лише 7 CLI — тепер Antigravity і Grok Build вставлені після OpenCode; (2) другий рядок порівняльної таблиці в довідці (×17) і зібраний у CI help сайту все ще містили Inside Claude Code / Codex / Cursor / Gemini CLI — застарілий набір із Cursor — тепер повний ростер. Обидва рядки використовували роздільники слеш/середня крапка, які патерни свіпу v1.126.0 не покривали. i18n-снапшот перегенеровано; сьют лишається 1969.

[1.126.0] — 2026-07-25

Додано

  • Вкладка інструментів AI CLI тепер виявляє всі 8 першокласних CLI career-ops — ростер #/config синхронізовано з батьківським docs/SUPPORTED_CLIS.md: у server/lib/routes/cli-detect.mjs додано Grok Build CLI (grok) і Kimi CLI (kimi), а Antigravity тепер спершу шукає канонічний бінарник agy. Скан PATH лише-для-читання тепер повідомляє 9 інструментів; знайдений бінарник, як і раніше, ніколи не запускається.

Змінено

  • Ресинк документації з career-ops.org/docs — звірив кожну поверхню докумен­тації з живими сторінками батька (прочитано всі 31). Канонічний ростер AI-асистентів (help ×17 + README ×17) тепер перелічує 8 першокласних CLI — Claude Code, Codex, OpenCode, Antigravity CLI, Grok Build CLI, Qwen Code, Kimi, GitHub Copilot CLI — плюс Gemini CLI (застаріла обгортка). Help-бандли зберігають структуру 29 H2 / 105 H3.

[1.125.4] — 2026-07-23

Змінено

  • залежності site (dependabot #151–#153) — sharp 0.34.5→0.35.3, svgo 4.0.1→4.0.2, fast-uri (dev) 3.1.3→3.1.4 у site/; збірка Astro зелена, SPA/сервер не зачеплені.

Примітки

  • Паріті-свіп батьківського проєкту (career-ops 37d17ec..254764a, після v1.22.0) — портувати нічого: guard неправильного рядка в set-status (#2108) — лише CLI (у web-ui рядок трекера обирається явно в UI, і жоден маршрут не викликає set-status.mjs); Risk Summary локалізованих режимів (#2109) — файли modes/<lang>/, які web-ui не читає (лише верхньорівневі modes/*.md); перевірка маніфесту update-system (#2111) — лише апдейтер; решта — документація батька (турецький README, SIGNATURES ×4, SCRIPTS.md, акценти es). VERSION батька лишається 1.22.0 — parentVersion без змін.

[1.125.3] — 2026-07-23

Виправлено

  • LLM-промпти данською та гінді відповідали англійською (повідомив користувач) — LOCALE_NAMES і всі п’ять наборів SCAFFOLD_STRINGS у server/lib/prompts.mjs так і не були розширені для da та hi, тож resolveLocale() відкочувався до en, і кожен AI-промпт — deep research (живий і ручний), режими, оцінювання, інтерв’ю, нетворкінг, CV Studio — втрачав директиву # Output language у цих двох локалях. Тепер обидві — повноправні: мовна директива + локалізоване обрамлення. Регресійний гейт у tests/locale-scaffold.test.mjs тепер обходить канонічний список із 17 локалей замість захардкоджених 12, а новий структурний гейт валить будь-який ключ обрамлення, що падає в англійську — локаль, яка пропустить prompts.mjs, більше не вийде (+12 тестів, разом 1969).

[1.125.2] — 2026-07-22

Виправлено

  • Deep research через Gemini: HTTP 502 (MALFORMED_FUNCTION_CALL) (#145, внесок @Alien10140) — живий промпт /api/deep наказував моделі «Use WebFetch / WebSearch» і зберегти бриф у файл, але безінструментальні API-провайдери не мають каналу інструментів; Gemini відповідав викликом функції замість тексту, що проявлялося як порожній HTTP 502. buildDeepPrompt і bundleProjectContext отримали прапорець headless: живі запуски (Anthropic/Gemini/каскад резервів) отримують промпт без інструментів, який пише бриф із вбудованого контексту, а copy-paste-промпт для Claude Code зберігає інструкції щодо інструментів. +1 тест у tests/critical-fixes.test.mjs.

Змінено

  • Типові моделі Gemini оновлено з застарілої gemini-2.0-flash (#144, внесок @Alien10140) — випадний список у Конфігурації, серверний резерв у gemini.mjs (що мовчки розходився з підказкою), ланцюжок резервів OpenRouter, config.geminiModelHint ×17 та довідка ×17 тепер одностайно вказують gemini-3.6-flash. Новий анти-дрейф ґейт tests/gemini-default-model.test.mjs (+5 тестів) фіксує всі поверхні на одному літералі — у сьюті тепер 1957 тестів.

[1.125.1] — 2026-07-21

Виправлено

  • SuccessFactors: мультибрендові тенанти RMK зберігають свій шлях бренду (батьківський #2099, після v1.22.0) — холдингові компанії, які ведуть кілька придбаних брендів на одному спільному інстансі RMK, розрізняють їх за сегментом шляху (careers.nemetschek.com/Bluebeam/ проти …/Vectorworks/); адаптер раніше згортав налаштований URL до його origin, непомітно скануючи вакансії батьківського бренду. Тепер ендпоінт зберігає префікс бренду, відкидаючи лише кінцевий сегмент /search/ або /tile-search-results/, тож ніщо ніколи не дублюється саме на себе; тенанти з одним доменом лишаються побайтово незмінними. Новий експортований хелпер resolveTenantBase + 1 перенесений тестовий блок у tests/sources-successfactors.test.mjs.

[1.125.0] — 2026-07-21

Додано

  • cvstart.org: розділ лендінгу «Джерела вакансій» — новий розділ між скриншотами та порівнянням, який перелічує всі 67 джерел сканування у вигляді клікабельних чіпів (62 англомовні дошки/ATS + 5 російських дощок під власним підзаголовком), кожне з яких веде на публічний сайт джерела. Список синхронізується з живим реєстром адаптерів під час збірки (sync-assets.mjs → facts.sources), тож він ніколи не може розійтися із застосунком; курований довідник посилань у Sources.astro захищений новим тестом tests/site-sources.test.mjs. У навігації шапки з’явився якір Sources; додано 4 нові ключі i18n сайту ×17. Також виправлено список inLanguage у JSON-LD лендінгу, в якому досі бракувало hi.

[1.124.0] — 2026-07-21

Додано

  • П’ять джерел сканування (паритет із батьківським v1.22.0, #1808/#1572/#2024/#2055) — Welcome to the Jungle (JSON API для всієї дошки), Agentic Engineering Jobs (дошка агентного/AI-інжинірингу), Jobvite (ATS на тенант без автентифікації), Gem (ATS на тенант) і Alibaba Group (JSON API кар’єрної сторінки, шаблон Meituan/Tencent). Кожне джерело — прив’язана до хоста, CI-ізольована пара джерело + адаптер; реєстр тепер постачається з 67 адаптерами (62 англомовних + 5 російськомовних); резервний список випадаючого списку Source на #/scan та його дрейф-гейт оновлено; п’ять нових наборів тестів tests/sources-{wttj,agenticjobs,jobvite,gem,alibaba}.test.mjs.

Виправлено

  • Arbeitsagentur: загальнонаціональна віддалена робота лише коли homeofficetyp дорівнює VOLLSTAENDIG (батьківський #1981) — запит homeoffice=nv_true також повертає гібридні вакансії, тож перевірка на віддаленість тепер підтверджує кожен збіг через ендпоінт деталей вакансії невеликими партіями і безвідмовно закривається (помилка пошуку зберігає справжнє місто вакансії, тож фільтри локації все одно застосовуються).
  • SmartRecruiters: публічні URL вакансій формувалися без /postings/ (батьківський #2047) — посилання тепер ведуть на публічну сторінку вакансії замість 404 для тенантів, чий публічний сайт відкидає цей сегмент.

Примітки

  • Батьківський v1.22.0 також містив зміни на боці CLI, у які веб-інтерфейс не заходить через shell або які вже покриває: шаблон CV zh-CN + типографіка PDF, режим /expand, налаштування кешування промптів провайдерів (Gemini/OpenAI/Ollama), розбивка токенів за кроками (у веб-інтерфейсі є власний лічильник використання), серіалізація блокування запису трекера (веб-інтерфейс скеровує записи через withFileLock ще з v1.21), прапорці CLI visa_filter та абсолютної дати публікації для сканування (у веб-інтерфейсі є власний фільтр віку «Опубліковано протягом») та посів дедуплікації відомих джерел (сканер веб-інтерфейсу веде власну дедуплікацію історії сканування).

[1.123.0] — 2026-07-17

Додано

  • Джерело сканування Oracle Recruiting Cloud (паритет із батьківським v1.21.0, #1929) — REST API recruitingCEJobRequisitions без автентифікації для кар’єрних сайтів Oracle Fusion/ORC (JPMorgan Chase, Oracle, BNY Mellon, American Express, Honeywell, …): прив’язка до хоста *.fa[.<region>][.ocs].oraclecloud.com, номер сайту визначається з careers_url кожної відстежуваної компанії, пагінація за зсувом із жорсткою межею кількості сторінок і WAF-обізнані заголовки на кшталт браузерних. Реєстр тепер постачається з 62 адаптерами (57 англомовних + 5 російськомовних); резервний список випадаючого списку Source на #/scan та його дрейф-гейт оновлено; новий CI-ізольований набір тестів tests/sources-oraclecloud.test.mjs.

Виправлено

  • Детектор репостів: базові назви залишаються окремо від сиблінгів зі спеціалізованим суфіксом (батьківський #1922) — «Senior Analytics Engineer» більше не групується із «Senior Analytics Engineer, People Analytics»: якщо токени однієї назви є строгою підмножиною токенів іншої, а додатковий токен є справжньою спеціалізацією (а не базовим словом), обидві вакансії вважаються окремими відкритими позиціями. Позначки репосту («(Repost)», «relisted») тепер трактуються як стоп-слова інформаційного шуму. +2 перевірки в tests/detect-reposts.test.mjs.

Примітки

  • Батьківський v1.21.0 також містив зміни на боці CLI, у які веб-інтерфейс не заходить через shell або які вже покриває: попередження про повторну подачу заявки до тієї самої компанії (у веб-інтерфейсі є пауза для повторної подачі ще з v1.84.0), прапорці --format/--report супровідного листа, режими промпту співбесіди для red-flag / панельної розвідки / no-show листа, персистентність довіри до джерел сканування та здоров’я порталів (веб-інтерфейс запускає власний внутрішньопроцесний сканер із trust-validator і сторінкою здоров’я порталів) і розширення статистики/розриву в зарплаті (транслюються лише для читання та безвідмовно).

[1.122.0] — 2026-07-16

Додано

  • Гінді (हिन्दी) — 17-та мова — повний словник інтерфейсу (~1 110 ключів), повний вбудований посібник довідки (паритет 29 H2 / 105 H3), README.hi.md, новий CHANGELOG.hi.md (починається з v1.122.0, за прецедентом de/it/tr), лендинг cvstart.org + сторінки Методологія/Ліцензія/Журнал змін/Довідка, перемикач мов (🇮🇳), автовизначення мови браузера та локалізований знімок дашборда. Кожен гейт паритету ×16 тепер працює ×17: паритет словника i18n + знімок, гейти H2/H3 довідки, паритет CHANGELOG, check-i18n сайту та перевірка локалей Playwright.

[1.121.0] — 2026-07-16

Додано

  • Сторінки Methodology, License і Changelog на cvstart.org — лендинг отримав три нові розділи всіма 16 мовами, поруч із наявним блоком Порівняння: /methodology/ (шкала оцінювання за шістьма вимірами 0.0–5.0, поріг подання заявки 4.0 і правила «ніколи не робимо» — локалізований стислий виклад career-ops.org/methodology), /license/ (канонічний текст ліцензії MIT із посиланням на NOTICE.md) і /changelog/ (цей файл, відображений для кожної локалі з 16 перекладених CHANGELOG репозиторію). Новий пункт Methodology у шапці та посилання в блоці ресурсів футера; sync-assets.mjs тепер синхронізує CHANGELOG ×16 та LICENSE у білд сайту, тож сторінки більше не можуть розійтися з репозиторієм.
  • Посилання на методологію в документації — README (усіма 16 мовами), канонічний список §1 вбудованого посібника довідки (усіма 16 мовами) та вікі тепер посилаються на career-ops.org/methodology (а також FAQ і глосарій) поруч із наявними посібниками career-ops.org/docs.

Змінено

  • Оновлено банер релізу та бейджі в README (1850 тестів, реліз v1.121.0) — банер досі анонсував v1.119.5.

[1.120.0] — 2026-07-16

Додано

  • Маніфест CareerOps (паритет із батьком v1.20.0) — батьківський проєкт випустив Маніфест CareerOps (MANIFESTO.md · career-ops.org/manifesto) і тепер показує його у своєму README, апдейтері та Go-дашборді. Веб-інтерфейс наслідує це: нове посилання у футері бічної панелі відкриває сторінку маніфесту (новий ключ i18n footer.manifesto у всіх 16 локалях), вбудований посібник довідки отримав §29 «Маніфест CareerOps» усіма 16 мовами, README пояснює, що таке маніфест і як його підписати, а футер лендингу cvstart.org теж посилається на нього.

Примітки

  • Батько v1.20.0 також виправив придушення відомих навичок у цільовому режимі upskill, приглушив dotenv, щоб stdout scan --json залишався придатним для парсингу, і виправив HTML-шаблон CV, щоб заголовок ролі не відривався від своїх пунктів — це поверхні на боці CLI, у які веб-інтерфейс не заходить через shell; змін коду веб-інтерфейсу не знадобилося.

[1.119.5] — 2026-07-13

Виправлено

  • Кнопка мови на лендінгу більше не переноситься — після появи прапорів у v1.119.2 підпис перемикача в шапці (наприклад «🇷🇺 Русский») міг розбиватися до трьох рядків на вузьких десктопних ширинах; підпис перемикача та всі пункти випадного списку тепер whitespace-nowrap — прапор + ендонім завжди в один рядок. Список мов у футері переведено з жорсткої двоколонкової сітки на рядок однорядкових пунктів із переносом — «🇧🇷 Português (Brasil)» теж більше не рветься посеред назви.

[1.119.4] — 2026-07-13

Змінено

  • LICENSE називає автора — рядок копірайту тепер: Sergei Emelianov (Fighter90) https://sergey-cv.com and career-ops-ui contributors (канонічний текст MIT не змінено). Новий NOTICE.md детально розписує ліцензування: хто власник копірайту, що саме покриває грант MIT (код, доки, переклади, лендінг, вікі), чого НЕ покриває (ваші дані в рантаймі, батьківський проєкт, контент джоб-бордів, торговельні марки), таблицю сторонніх компонентів (express/js-yaml — MIT; Astro/Tailwind — MIT; шрифти Figtree та JetBrains Mono — SIL OFL 1.1; sharp — Apache-2.0) і необов’язковий рядок атрибуції.

[1.119.3] — 2026-07-13

Додано

  • SECURITY.md — політика безпеки, на яку посилався CONTRIBUTING, тепер існує: підтримувані версії, приватний процес репортів (у репозиторії ввімкнено private vulnerability reporting GitHub — вкладка Security → «Report a vulnerability»), модель загроз для localhost-застосунку одного користувача (у скоупі: XSS через ворожі вакансії / SSRF / path traversal / витоки секретів / послаблення CSP; поза скоупом: DoS власного localhost і проблеми батьківського проєкту) та базова лінія хардинінгу для рев’юерів.

[1.119.2] — 2026-07-13

Додано

  • CONTRIBUTING.md — гід контриб’ютора, на який лендінг і README посилалися весь цей час, тепер існує: встановлення, карта проєкту, жорсткі правила безпеки/no-build, рівні тестування, walkthrough «двох реєстрів» для додавання скан-джерела, контракт i18n ×16, конвенції комітів/PR і процес релізу.
  • Прапори мов на лендінгу — перемикач мов cvstart.org, сітка мов у футері та банер «читайте своєю мовою» тепер показують прапор кожної локалі поруч з її ендонімом (той самий набір регіональних індикаторів, що й у мовному <select> застосунку; деградує до літер регіону там, де немає гліфів прапорів).
  • Правки футера лендінгу — неробоче посилання Discussions (функцію не ввімкнено в репозиторії) тепер веде на вікі проєкту, а у футері вказано автора: Sergei Emelianov (sergey-cv.com · LinkedIn).

[1.119.1] — 2026-07-13

Виправлено

  • Фільтр джерел на #/scan наздогнав реєстр — статичний список FALLBACK_SOURCES за випадним списком Source (використовується лише коли GET /api/scan/sources недоступний) мовчки відставав із v1.87.0: в офлайн-фолбеку бракувало 20 провайдерів (Amazon, Avature, SAP SuccessFactors, Get on Board, Dassault Systèmes, beesite, HigherEdJobs, JibeApply (iCIMS), softgarden, Cornerstone, Phenom, Radancy, Deutsche Bahn, EchoJobs, TKMS, Heckler & Koch, Rheinmetall, LaraJobs і нові Meituan / Tencent). Синхронізовано з усіма 61 і тепер закрито дрейф-тестом, що валить CI при розходженні клієнтського списку з серверним реєстром (значення І лейбли). +1 тест (1845).

[1.119.0] — 2026-07-13

Паритет із батьківським career-ops v1.19.0 + оновлення лендінгу cvstart.org.

Додано

  • 2 нові сканер-провайдери — Meituan (zhaopin.meituan.com) і Tencent (careers.tencent.com): публічні JSON-API китайських тех-дощок без авторизації, визначаються за хостом або явним provider:, серверний пошук за ключовими словами з пагінацією та дедуплікацією за URL — тепер 61 адаптер (56 EN + 5 RU). +20 тестів (1844).
  • Блок контриб’юторів на лендінгу — cvstart.org показує аватари всіх, хто долучився кодом (GitHub API /contributors на етапі збірки, боти відфільтровані), локалізовано всіма 16 мовами, з посиланням на повний граф контриб’юторів.
  • Живий лічильник зірок GitHub на лендінгу — бейдж у шапці тепер оновлюється на клієнті з GitHub API при кожному візиті (знімок збірки — як fallback), а щотижнева перезбірка Pages за розкладом не дає застаріти знімку та списку контриб’юторів; API-виклики в CI автентифіковані токеном.

Виправлено

  • Запити Workday CXS несуть браузерні заголовки (батьківський #1813) — тенанти за Cloudflare (спостерігалося наживо: geico) відповідають 500 на запити без звичайних UA/accept-language/origin/referer; фетчер тепер виводить origin і слаг сайту з самого CXS-URL. Запити Glints отримали той самий браузерний UA + origin/referer — обидва з спільної константи BROWSER_LIKE_USER_AGENT в http-json.mjs.

[1.118.4] — 2026-07-10

Виправлено

  • Скан hh.ru давав 0 вакансій з російського IP (посилання на регіональному піддомені) — з російського резидентного IP hh.ru редиректить пошук на регіональний піддомен (sochi.hh.ru, spb.hh.ru, …) і віддає посилання на вакансії на цьому піддомені. Парсер шукав посилання заголовка за жорстким хостом https://hh.ru/vacancy/ і не знаходив жодного регіонального — цілком робочий скан мовчки записував 0. Тепер приймається будь-який хост *.hh.ru (реклама adsrv.hh.ru/click?… так само відсікається — у неї немає шляху /vacancy/<id>), а URL результату канонізується в https://hh.ru/vacancy/<id>. Перевірено наживо: 17 реальних вакансій парсяться зі сторінки sochi.hh.ru, де раніше було 0. +1 тест (1824).

[1.118.3] — 2026-07-10

Виправлено

  • hh.ru мовчки повертав 0 вакансій (заглушка VPN-перевірки) — hh.ru тепер відповідає 302-редиректом на заглушку /vpncheeck («VPN мешает работе сайта») мережам, які вважає VPN/проксі (датацентрові IP); заглушка віддає HTTP 200 без жодної картки вакансії, тож скан звітував 0 без помилки. Сканер тепер розпізнає редирект за фінальним URL відповіді, вимикає hh.ru до кінця прогону й пише чесну підказку: трафік має справді виходити через резидентний IP — системний VPN/проксі може лишатися ввімкненим, навіть коли перемикач у браузері вимкнено. +1 тест (1823).

[1.118.2] — 2026-07-10

Обслуговування

  • Доопрацювання лендінгу (#118) — site/README.md приведено до Astro 7 (security-апгрейд з #116), прибрано невикористаний імпорт, додано 4 виконувані гарди для білд-скриптів лендінгу: гейт i18n-паритету доказово падає на зламаному словнику, а sync-assets ніколи не пише поза site/ — набір 1822. Розібрано два алерти CodeQL (один виправлено в коді, один відхилено як навмисну поведінку білда).

[1.118.1] — 2026-07-10

Виправлено

  • Сканування hh.ru з-поза меж Росії — hh.ru тепер віддає HTTP 451 (регіональне юридичне блокування) неросійським IP на публічних сторінках пошуку. Сканер обробляє 451 як 403: після першого блокування hh.ru вимикається до кінця прогону з чесним рядком у лозі про російську IP / VPN-вихід, тож решта запитів та інші RU-джерела не витрачаються марно. Довідку §7 оновлено всіма 16 мовами. +1 тест (1818).

[1.118.0] — 2026-07-09

Пакет паритету з батьківським career-ops v1.18.0.

Додано

  • 9 нових сканер-провайдерів — Cornerstone OnDemand (csod), Phenom (phenom), Radancy (radancy), Deutsche Bahn (deutschebahn), EchoJobs (echojobs), TKMS (tkms), Heckler & Koch (hecklerkoch), Rheinmetall (rheinmetall), LaraJobs (larajobs) — тепер 54 адаптери. Адаптер Lever додатково розпізнає дошки EU-тенанта (jobs.eu.lever.co).
  • Статус Hired у трекері (паритет зі states.yml батька): прийняті офери отримують власний канонічний статус, святковий бейдж і банер «роботу знайдено» на #/tracker; воронка та конверсії рахують його як такий, що пройшов усі етапи.
  • Вкладка «За весь час» у #/stats — ретрансляція лише для читання батьківського stats.mjs (зведення трекера за весь час, накопичені частки воронки, підсумки сканера, покриття порталів) плюс спостереження щодо компенсації з salary-gap.mjs (бажана vs заявлена vs фактична, за кожною заявкою). Нові маршрути GET /api/stats/lifetime і GET /api/stats/salary-gap — shell-out з нульовою вартістю токенів, м’яка деградація {available:false} без батьківського проєкту.
  • 28 нових i18n-ключів у всіх 16 локалях; довідку §14/§26 оновлено всіма мовами.

Тести

  • +38 юніт-тестів (три сьюти паритету провайдерів + маршрути релея/статусу) — разом 1817.

[1.117.2] — 2026-07-06

Фікс порожнього трекера для shell-out паритету. Батьківські скрипти виходять із кодом 1 і структурованим {error}-JSON, коли в трекері ще немає заявок; дошка фоллоу-апів і вкладка патернів показували це як «script-error». Обидва маршрути тепер передають це як здоровий порожній стан (available:true, empty:true), і UI показує чесне «поки порожньо». Перевірено наживо на реальному батькові.

Нове: немає.

[1.117.1] — 2026-07-06

Доналаштування v1.117.0 (розбір CodeQL). Три shell-out ендпоінти (GET /api/followup, POST /api/followup/seed, GET /api/stats/patterns) тепер несуть спільний per-IP лімітер (кожен запит породжує дочірній процес; на loopback — no-op). Витяг тексту за URL у «Додати в CV» вичищає теги до нерухомої точки й потім видаляє всі залишкові </> — доказово повне очищення для тексту LLM-промпту. Поведінка на коректному вводі незмінна.

Нове: немає.

[1.117.0] — 2026-07-06

Пакет паритету з батьком — шість можливостей батьківського career-ops тепер в UI. (1) Дошка каденції на #/followup: терміновість за кожною заявкою (🔴/🟠/🟡/🔵) з followup-cadence.mjs, плюс кнопка «Проставити дати» (followup-seed.mjs --backfill). (2) Патерни відмов: четверта вкладка Статистики запускає analyze-patterns.mjs (лише читання) — розподіл результатів, рекомендації, частка просування за ATS-вендорами. (3) Додати в CV: картка CV Studio перетворює URL чи вставлений текст на ATS-пункти, засновані ЛИШЕ на цьому джерелі (лише пропозиції, без записів; завантаження URL захищене від SSRF). (4) 4 нові сканер-провайдери — beesite, HigherEdJobs (RSS), JibeApply (iCIMS), softgarden — реєстр тепер налічує 50 адаптерів (45 EN + 5 RU), усі в списку Scan. (5) Крок передперевірки нокаут-питань у чек-листі Apply. (6) Раннер reconcile (/api/run/reconcile). Shell-out-маршрути чесно деградують без батьківських скриптів.

  • Новий модуль server/lib/routes/followup.mjs (31-й) + нові маршрути + 8 файлів source/adapter. Тести: 6 + 7 нових; сьют 1737 → 1750. 41 новий ключ i18n ×16. Довідка §13/§17/§24/§26 розширена ×16.

Нове: GET /api/followup, POST /api/followup/seed, GET /api/stats/patterns, POST /api/cv-studio/add-entry, POST /api/run/reconcile.

[1.116.0] — 2026-07-06

Перероблено лічильник витрат + перший наскрізний тест віджетів. Лічильник витрат ШІ (v1.114.0) виправлено й правильно закріплено: тепер він прикріплений унизу лівої бічної панелі (на всю ширину, та сама поверхня) й резервує внизу місце, що дорівнює його висоті, аби меню ніколи не перекривалося — навігація та підвал версії завжди прокручуються вільно над ним. Він оновлюється наживо (кожні 15 с, при фокусі вкладки та зміні маршруту), а кожен рядок вікна тепер показує реальні <токени> · <оцінка вартості> (смуги масштабуються відносно 30-денного вікна) замість завжди-100% «частки». Крім того: стійкий бар’єр typeof в імпортері CV закриває в першопричині повторюваний хибнопозитивний type-confusion CodeQL, а новий наскрізний тест Playwright проганяє обидва постійні віджети в реальному браузері.

  • public/js/lib/usage-hud.js + app.css, server/lib/cv-import.mjs. Тести: tests/playwright-widgets.mjs (2 E2E) + tests/usage-hud.test.mjs (10). Довідка §6 розширена ×16.

Нове: немає.


career-ops-ui v1.267.1 · page 6/12 · mirror of the project changelog for cvstart.org