Журнал изменений
GitHubКаждое значимое изменение, релиз за релизом. Тот же файл публикуется в репозитории и переведён на все 19 языков.
[1.135.0] — 2026-08-11
Паритет с родительским career-ops v1.26.0 — пять новых источников сканирования без авторизации, а также исправления корректности для четырёх досок, уже реализованных в web-ui. Реестр теперь насчитывает 78 источников = 73 EN + 5 RU (ALL_ADAPTERS 73).
Добавлено
- Пять новых источников сканирования (каждый — источник + адаптер + CI-изолированный сьют; они появляются в фильтре Source на
#/scanи на лендинге cvstart.org):join(JOIN) — доска JOIN компании из встроенного в Next.js__NEXT_DATA__наjoin.com/companies/<slug>(закреплён по хосту, с лимитом страниц).getro(Getro) — портфельные доски венчурных «talent-network» через публичный POST APIapi.getro.com, постранично от новых к старым; каждая вакансия приписывается портфельному работодателю, а не фонду.consider(Consider) — портфельные доски венчурных фондов на getconsider.com через POST на том же источнике (origin); конфигурируемый хост закреплён структурным SSRF-guard’ом (только публичный 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; форма ответа была переименована, а фильтрация по удалёнке теперь сужается на стороне сервера. - thehub переведён на API v2
jobsandfeatured; строки не содержат даты публикации и исключены из фильтра по возрасту. - hackernews теперь надёжно находит ежемесячный тред «Who is hiring?», фильтруя поиск через Algolia по тегу учётной записи
author_whoishiringвместо текстового запроса.
Примечания
- Не портировано (web-ui уже безопасен, поглощается relay’ем или относится только к CLI): Unicode-совместимые ключи дедупликации ролей / сопоставления компаний (группировка повторов в web-ui уже ключуется по компании в обычном нижнем регистре, поэтому разные не-латинские работодатели никогда не схлопываются в один ключ); сигнал задержки отказов followup + доработки company-funded (проксируются только на чтение, fail-soft); переопределяемые через env пути скана и разбор
--flag=value(web-ui запускает сканеры в процессе); рефакторинг унификации User-Agent (web-ui уже централизует его); а также пункты, относящиеся только к CLI (реестр недоверенного контента, oferta/offer-prep, doctor, изменения шаблонов сопроводительного письма/резюме).
[1.134.1] — 2026-08-05
Усиление валидации — исправления, выявленные полным аудитом проекта.
Исправлено
successfactorsбольше не отбрасывает уже собранные вакансии при сбое в середине скана (регрессия из портирования dead-board-throw в v1.134.0) — в цикле его пагинации не былоtry/catch, поэтому сбой на странице 2 и далее (после успешной первой страницы) выбрасывал ошибку и терял всё уже собранное; а если этим сбоем был404(вышедший за диапазонstartrow),en-scannerна несколько дней помечал живого тенанта как мёртвого. Теперь поведение зеркалируетphenom/radancy: сбой на странице 0 всё ещё выбрасывает ошибку (мёртвая доска), но сбой на более поздней странице сохраняет частичные результаты.- Фильтр-чипы
#/scanтеперь управляются с клавиатуры (WCAG 2.1.1) — чипы фасетов (и чип «очистить») были элементамиspanс обработчиком клика, но безtabindex/роли, поэтому пользователи клавиатуры и скринридеров не могли до них добраться или переключить их. Теперь у них естьrole="button",tabindex="0",aria-pressedи активация по Enter/пробелу. - Три хардкоженные англоязычные строки теперь локализованы — подсказка бейджа доверия на
#/scan, заголовок столбца релокации на#/scanи заголовок столбца оценки на#/dashboardбыли обычными строковыми литералами, которые гейт паритета i18n не мог увидеть (они никогда не были ключами), поэтому во всех неанглийских локалях они оставались на английском. Теперь этоscan.trustTip+scan.col.reloc(2 новых ключа) и повторное использованиеtrack.col.score, со статической source-гардой.
[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 EN + 5 RU (ALL_ADAPTERS68). Появляется в фильтре Source на#/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): перф-переписывание группировки заголовков в detect-reposts #2389; исправления Unicode-ключей компаний (собственная дедупликация трекера web-ui уже безопасна для не-латиницы);
scan --since;cv-facts; проход аудита шаблона CV / PDF;doctor; директива о недоверенном контенте в modes.
[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— именно поэтому баг и прошёл в релиз), плюс статические source-канарейки, проверяющие, чтоfunded.jsчитаетres.companies(никогдаres.candidates) и строит строки таблицы с дочерними элементами-массивом (+1 → 2144).
[1.133.0] — 2026-08-01
Добавлено
- Обнаружение профинансированных компаний (
#/funded, паритет с родителем #2117) — новый read-only вид, транслирующий родительский career-opscompany-funded.mjsчерезGET /api/company-funded: предварительно проверяемый (review-first) список недавно профинансированных компаний, обнаруженных из публичных, закреплённых по хосту фидов о финансировании (TechCrunch, PR Newswire, The Guardian, Hacker News). Релей запускает скрипт с--json --dry-run(JSON в stdout, без записи файлов), никогда не прокидывает пользовательский ввод в--sources(нет SSRF-поверхности сверх собственных фиксированных фидов родителя), несётllmRateLimitи запускается пользователем (кнопка Discover, никогда при монтировании). Новый модуль маршрутаserver/lib/routes/funded.mjs(32-й) +public/js/views/funded.js, в разделе Sourcing. - Еженедельный дайджест интервью (
#/interview-digest, паритет с родителем #2129/#2130) — новый read-only вид, транслирующий родительский zero-LLMweekly-digest.mjsчерезGET /api/interview/weekly-digest: механическая сводкаinterview-prep/sessions/*.md— с какими компаниями и на каких раундах вы проходили интервью на этой неделе, повторяющиеся компетенции и оценочные (best-effort) открытые пробелы. Опциональный диапазон?from=&to=прокидывается ТОЛЬКО если ОБА значения — валидныеYYYY-MM-DD; пустой диапазон — валидный дайджестavailable:true(не сбой). Добавлено вserver/lib/routes/interview.mjs+public/js/views/interview-digest.js, в разделе Analytics. - Оба релея следуют устоявшемуся fail-soft-контракту
{ available:false }(как/api/stats/lifetime), когда родительский скрипт отсутствует (CI, автономные установки), так что каждый вид показывает честную заметку. 26 новых i18n-ключей ×17 локалей; CI-изолированный сьютtests/parity-routes-v1133.test.mjs(+5 → 2143: успешный passthrough, прокидывание--from/--to, гарантия read-only--dry-runи путь fail-soft при ошибке скрипта).
Примечания
- Родительский career-ops продвинулся дальше v1.24.0: страница Follow-up Tracker Next.js-приложения web/ (#1422) и бэкенд-рендер PDF (#2182) — не портированы: у web-ui уже есть собственный релей follow-up (v1.117.0) и раннеры PDF, а лежащее в основе укрепление
followup-cadence.mjs(отклонение невозможных дат, null-safeaddDays, разбор legacy-буллетов) достаётся бесплатно через 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, билдеры строк/фасетов, отрисовщики опций и зеркало реестраFALLBACK_SOURCES— переезжает в фабрикуwindow.ScanResults.create(ctx), замыкающуюся на объект контекста, который передаёт вид. Без изменений поведения — функции перенесены дословно, а их переменные замыкания перепривязаны наctx.*;scan.jsтеперь ~906 строк (запланирован второй проход извлечения к цели в 800 строк). - Новый браузерный регрессионный гейт —
tests/playwright-scan-filters.mjsзасевает эталонныйdata/last-scan.jsonи прогоняет каждый фильтр#/scan, проверяя точные счётчики строк, так что извлечение верифицировано на реальном поведении браузера. - Баннер README облегчён — длинная построчная narrative-стена «Последний релиз» по версиям упраздняется в пользу однострочного резюме + ссылки на полный журнал изменений (
CHANGELOG.ru.md).
[1.131.2] — 2026-07-31
Изменено
app.cssразделён на три упорядоченных таблицы стилей (техдолг по контракту размера файла — единый файл разросся до ~1990 строк, далеко за жёсткий лимит в 800 строк). Теперь этоapp.css(~672 — a11y, дизайн-токены/тема, sidebar, main, кнопки, content-shell),components.css(~595 — карточки, гриды, пагинатор, бейджи, таблицы, формы, лог/консоль, markdown, переключатель языка, chip-фильтр, баннер соединения) иoverlays.css(~737 — toast, шторка уведомлений, модалка, разное/адаптивность, RTL-зеркалирование[dir="rtl"], docs-fab, usage-hud), каждый в пределах жёсткого лимита.- Разрез непрерывный и в исходном порядке, поэтому каскад побайтово идентичен файлу до разделения;
index.htmlподключает все три как упорядоченные<link>. Без изменений поведения, разметки или i18n. - Тесты, проверяющие CSS, теперь читают конкатенацию через общий хелпер
tests/helpers/css.mjs::loadAppCss(). Новыйtests/css-modularization.test.mjsфиксирует разделение (файлы существуют · каждый ≤ 800 строк · порядок ссылок в index.html) → сьют 2138. Проверено вживую в браузере: все три таблицы стилей парсятся и их правила применяются.
- Разрез непрерывный и в исходном порядке, поэтому каскад побайтово идентичен файлу до разделения;
[1.131.1] — 2026-07-31
Исправлено
- Согласованность host-pinning адаптеров на двух источниках v1.130.0 (доработки по code-review, defense-in-depth; поведение для валидных входных данных не меняется):
- Адаптер
a16z-speedrun-talentтеперь повторно валидирует overrideapi:/a16z-speedrun-talent:вbuildEndpoint(HTTPS + точное совпадение хостаspeedrun-talent-network.com) и откатывается на канонический фид при сбое проверки — паритет с адаптеромcryptocurrencyjobs, так что значение с чужим хостом никогда не попадает в слот запроса (ранее полагался исключительно на гардassertSpeedrunUrlна момент запроса). Проверка точного хоста теперь единый экспортируемыйSPEEDRUN_TALENT_HOST_RE, общий для гарда и адаптера. - Парсер
cryptocurrencyjobs—cleanUrlтеперь использует тот же гард точного совпадения хоста, что иassertCryptocurrencyJobsUrlи override адаптера (былоendsWith, который принимал поддомены). Парсер никогда не более permissive, чем SSRF-гард: ссылка на элемент сsub.cryptocurrencyjobs.coотбрасывается. - +2 теста → сьют 2135.
- Адаптер
[1.131.0] — 2026-07-31
Добавлено
- CRM-доска со вкладками стадий на
#/tracker(портировано из вида/pipelineвеб-приложения родителя). Полоска funnel-чипов трекера и дропдаун статуса заменены на полосу вкладок стадий: вкладка All плюс по одной вкладке на каждый канонический статус — Evaluated · Applied · Responded · Interview · Offer · Rejected · Discarded · SKIP · Hired — каждая показывает живой счётчик за всю историю, включая стадии с нулевым счётчиком, чтобы всегда была видна вся воронка (вид CRM). Активная вкладка управляет фильтром; повторный клик по ней сбрасывает обратно на All. Строки сохраняют тон оценки, легитимность, возможности PDF и отчёта, а ячейка компании теперь показывает брендовый логотип, если логотипы включены (по умолчанию выключены → ноль дополнительных запросов).- Новый read-only маршрут
GET /api/tracker/stagesвозвращает канонический перечень стадий воронки (метки по порядку) + карту свёртки алиасов, источник —server/lib/states.mjs(templates/states.yml, со встроенным fallback) — так что клиент никогда не хардкодит whitelist статусов. Легаси-ответGET /api/trackerбез параметров не изменился (только{ rows }). - Новая чистая, покрытая юнит-тестами клиентская библиотека
public/js/lib/tracker-stages.jsраскладывает строки по стадиям сервера, устойчива к случайному markdown-жирному начертанию и локализованным алиасам (например,aplicado→Applied). Вкладки доступны (role tablist/tab, aria-selected, зона клика ≥44 px, счётчики в accessible name каждой вкладки). Новых i18n-ключей нет. Сьют — 2133 теста.
- Новый read-only маршрут
[1.130.0] — 2026-07-31
Добавлено
- Два новых источника сканирования, портированных из родительского career-ops v1.24.0 (in-process, без новых зависимостей; оба появляются в фильтре Source на
#/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) — доска вакансий Web3cryptocurrencyjobs.co, забираемая через её публичный RSS 2.0-фид (без авторизации). Двухпроходное декодирование XML-сущностей, только удалённые вакансии, работодатель извлекается из хвоста заголовка"… at <Компания>". - Реестр теперь поставляется с 72 источниками = 67 английских + 5 русских (
ALL_ADAPTERS= 67 адаптеров англоязычных порталов).
- a16z Speedrun (
Исправлено
echojobs— гибридные вакансии остаются отличимы от удалённых (зеркалит родительский #2258). Регистронезависимый маркерhybridтеперь даёт"<Город> · Hybrid"(или простоHybrid, если города нет) иworkplaceType: 'Hybrid', вместо схлопывания вRemote.radancy— устаревшая разметка TalentBrew + транспорт JSON results-фрагмента (зеркалит родительский a3e6df9), под инжектируемымopts.fetchJson.
Примечания
- Не портировано — CLI-специфичные функции родителя. Обширная CLI/mode-поверхность career-ops v1.24.0 остаётся вне web-ui, который является вьюером + тонким write-through, а не хостом режимов: таблицы соответствия/юрисдикции, телефонная книга контактов + vCard, транскрипт-дебриф интервью / определение платформы звонка, установка статуса в ledger, запись исхода, двухпроходный триаж, jd-similarity, версионированная схема артефакта CV заявки, детектирование Playwright-MCP в doctor и
portals/fix-slugs.mjs. Изменения оркестрации скана, которые живут в родительскомscan.mjs— Playwright-сканер Interamt.de, полный проход iCIMS в режиме reverse-ATS, фильтр допустимости страны для удалённых вакансий, троттлинг DNS-lookup, дедупликация StepStonerltrи нормализованная колонка компании в истории сканирований — не применяются: 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 + letter-fallback); (4)job-facets.js— фасеты seniority/source/days. +21 тест.
Примечания
- Не портировано (только концепт): агентский слой действий родителя (
actions/registry.ts+api/assistant/route.ts) — чертёж на случай, когдаdocs-fabвырастет из help-чата в копайлот. Новых источников нет (реестр 70), изменений i18n/help нет.
[1.127.0] — 2026-07-29
Добавлено
- Три новых источника сканирования (паритет career-ops v1.23.0) — в реестре теперь 70 адаптеров (65 EN + 5 RU): Flowxtra (board-wide агрегатор без авторизации), 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) вторая строка сравнительной таблицы в help-гайде (×17) и собираемый в CI help сайта всё ещё содержалиInside Claude Code / Codex / Cursor / Gemini CLI— устаревший набор с Cursor — теперь полный ростер. Обе строки использовали разделители слэш/средняя точка, которые паттерны свипа v1.126.0 не покрывали. i18n-снапшот перегенерирован; сьют остаётся 1969.
[1.126.0] — 2026-07-25
Добавлено
- Вкладка AI CLI tools теперь детектит все 8 первоклассных CLI career-ops — ростер
#/configсинхронизирован с родительскимdocs/SUPPORTED_CLIS.md: вserver/lib/routes/cli-detect.mjsдобавлены Grok Build CLI (grok) и Kimi CLI (kimi), а Antigravity теперь сначала ищет канонический бинарникagy. Read-only-скан 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 (legacy-обёртка). Help-бандлы сохраняют структуру 29 H2 / 105 H3.
[1.125.4] — 2026-07-23
Изменено
- зависимости site (dependabot #151–#153) —
sharp0.34.5→0.35.3,svgo4.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
Добавлено
- Пять источников сканирования (паритет с родительским career-ops v1.22.0, #1808/#1572/#2024/#2055) — Welcome to the Jungle (JSON API по всей доске вакансий), Agentic Engineering Jobs (доска вакансий по agentic/AI-инженерии), Jobvite (ATS без авторизации, на тенант), Gem (ATS на тенант) и Alibaba Group (JSON API карьерной страницы, паттерн Meituan/Tencent). Каждый источник — это закреплённая по хосту, CI-изолированная пара «источник + адаптер»; реестр теперь поставляется с 67 адаптерами (62 EN + 5 RU); фолбэк выпадающего списка 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), пошаговая разбивка токенов (у веб-интерфейса свой счётчик использования), сериализация записи трекера через writer-lock (веб-интерфейс проводит записи черезwithFileLockс версии v1.21), флаги CLIvisa_filterи абсолютной даты публикации для скана (у веб-интерфейса свой фильтр «Опубликовано за» по возрасту), а также посев дедупликации по увиденным источникам (сканер веб-интерфейса ведёт собственную дедупликацию истории сканирований).
[1.123.0] — 2026-07-17
Добавлено
- Источник сканирования Oracle Recruiting Cloud (паритет с родительским career-ops 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каждой отслеживаемой компании, постраничная выборка по offset с жёстким лимитом числа страниц и WAF-совместимые «браузерные» заголовки. Реестр теперь поставляется с 62 адаптерами (57 EN + 5 RU); фолбэк выпадающего списка 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 / panel-intel / письмо о неявке), сохранение trust-сигналов сканирования и здоровья порталов (веб-интерфейс использует собственный in-process сканер сtrust-validatorи страницу здоровья порталов), а также расширения статистики/salary-gap (транслируются только для чтения, в fail-soft режиме).
[1.122.0] — 2026-07-16
Добавлено
- Хинди (हिन्दी) — 17-й язык — полный словарь интерфейса (~1110 ключей), полное встроенное руководство справки (паритет 29 H2 / 105 H3),
README.hi.md, новыйCHANGELOG.hi.md(начинается с v1.122.0, по образцу de/it/tr), лендинг cvstart.org и страницы Methodology/License/Changelog/Help, переключатель языка (🇮🇳), автоопределение языка браузера и локализованный скриншот дашборда. Теперь каждый паритетный гейт «×16» проверяется как «×17»: паритет словаря i18n и снапшот, гейты H2/H3 справки, паритет CHANGELOG,check-i18nсайта и локальный прогон Playwright.
[1.121.0] — 2026-07-16
Добавлено
- cvstart.org: страницы Methodology, License и Changelog — лендинг получил три новых раздела на всех 16 языках рядом с существующим блоком Compare: /methodology/ (шкала оценки из шести параметров 0.0–5.0, порог отклика 4.0 и правила «никогда не делает» — локализованное резюме career-ops.org/methodology), /license/ (канонический текст MIT со ссылкой на NOTICE.md) и /changelog/ (этот файл, отрисованный по локали из 16 переведённых CHANGELOG репозитория). Новый пункт «Методология» в шапке и ссылки в футере «Ресурсы»;
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-дашборде. Веб-интерфейс следует за ним: новая ссылка в футере боковой панели открывает страницу манифеста (новый ключ i18nfooter.manifestoво всех 16 локалях), встроенный гид справки получил §29 «Манифест CareerOps» на всех 16 языках, README объясняет, что такое манифест и как его подписать, а футер лендинга cvstart.org тоже ссылается на него.
Примечания
- Родитель v1.20.0 также исправил подавление известных навыков в целевом режиме
upskill, заглушил dotenv, чтобы stdoutscan --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 (бэкенд jobs.mercedes-benz.com), HigherEdJobs (RSS), JibeApply (iCIMS), softgarden — реестр теперь насчитывает 50 адаптеров (45 EN + 5 RU), все в выпадающем списке Scan. (5) Шаг предпроверки нокаут-вопросов в чек-листе Apply (виза/степень/зарплатные пороги — до заполнения формы). (6) Раннер reconcile (/api/run/reconcile → reconcile-pipeline.mjs). Shell-out-маршруты деградируют честно: без родительских скриптов UI показывает «недоступно».
- Новый модуль маршрутов
server/lib/routes/followup.mjs(31-й) +GET /api/stats/patterns+POST /api/cv-studio/add-entry+ 8 файлов source/adapter + счётчики реестра 41→45 EN. Тесты:tests/sources-parity-v1117.test.mjs(6) +tests/parity-routes-v1117.test.mjs(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.
Новое: нет.
[1.115.0] — 2026-07-06
Шлифовка дизайна (консервативная, коралловый бренд сохранён). Лёгкий проход по общей дизайн-системе — без перестройки, без смены палитры. Карточки метрик на дашборде теперь слегка приподнимаются и получают коралловую рамку при наведении (как плитки быстрых действий); карточки контента приподнимаются чуть-чуть; кнопки primary / dark / danger получают тень в покое и мягкий подъём при наведении для глубины; крупные числа выравниваются через tabular-nums; интерактивные элементы получают мягкий коралловый ореол за чётким 2px-кольцом клавиатуры. Вся анимация уважает prefers-reduced-motion, а ореол намеренно ограничен элементами управления — не глобальный *:focus-visible (иначе он перерисовал бы кольцо на заголовках маршрутов; урок v1.58.x).
- Только 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(window.UsageHud), загружается из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(window.DocsFab), монтируется глобально изindex.html; безопасен для CSP; стили с учётом темы и зеркалом RTL вapp.css. Без нового маршрута сервера — переиспользует эндпоинт справки. Тесты:tests/docs-fab.test.mjs(8). 6 новых ключей i18n ×16 (fab.*+docs.err). Справка §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(резюме + профиль + two-pager), общий каскад провайдеров, ручной промпт без ключа, с ограничением частоты, без записей. Результат экспортируется в 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.
career-ops-ui v1.267.1 · page 7/13 · mirror of the project changelog for cvstart.org