Dziennik zmian

GitHub

Każda istotna zmiana, wydanie po wydaniu. Ten sam plik jest dostępny w repozytorium i przetłumaczony na wszystkie 19 języków.

[1.198.0] — 2026-08-15

Dodano — ponowne próby skanowania używają teraz wykładniczego wycofywania, jittera i respektują Retry-After od ogranicznika tempa.

Dodano

  • Gdy tablica ofert na chwilę ogranicza tempo lub zwraca błąd (HTTP 429 / 5xx) w trakcie skanu, ponowna próba czeka teraz z wykładniczym wycofywaniem + jitterem zamiast stałego krótkiego opóźnienia — zajęta tablica nie jest młócona w tym samym rytmie, a równoległe próby nie zderzają się znów synchronicznie. Retry-After od tablicy jest respektowany (ale ograniczony, by wrogi Retry-After: 86400 nie zablokował całego skanu). Błędy trwałe (404, odrzucone przekierowania) nadal zawodzą natychmiast — bez zmian.

Uwagi

  • Nowe parseRetryAfterMs() i czysta computeRetryDelayMs() w server/lib/http-json.mjs; fetchJson przechwytuje teraz .retryAfter na odpowiedzi nie-ok, a fetchJsonWithRetry przyjmuje opcjonalny maxDelayMs (domyślnie 8000). tests/http-json.test.mjs (+9). Zestaw: 2536.

[1.197.0] — 2026-08-14

Dodano — śledź tablicę ofert funduszu Getro wyłącznie po jej careers_url; id kolekcji rozwiązuje się samo.

Dodano

  • Śledzona tablica Getro (b2venture, Earlybird, Point Nine, …) nie potrzebuje już ręcznie wyszukanego liczbowego getro_collection. Podaj własny careers_url tablicy, a id rozwiąże się automatycznie z tej strony przy pierwszym skanowaniu — pojedynczy bezpieczny wobec SSRF GET czyta liczbowy network.id prosto z osadzonych danych strony. Jawny getro_collection nadal ma pierwszeństwo i całkowicie pomija pobieranie.

Uwagi

  • Nowe httpsCareersUrl(), extractCollectionId() oraz asynchroniczny resolveCollectionId() w server/lib/sources/getro.mjs; strona tablicy jest pobierana przez safeGet (przypięty DNS, ograniczony rozmiar), a rozwiązany id nadal jest przypięty do hosta api.getro.com przez assertGetroUrl. Adapter dopasowuje teraz wpis provider: getro z careers_url https nawet bez id. tests/sources-getro.test.mjs (+8). Zestaw: 2527.

[1.196.0] — 2026-08-14

Naprawiono (bezpieczeństwo) — adapter Workday waliduje endpoint api po nazwie hosta, nie po podciągu.

Naprawiono

  • Wartość api: Workday w portals.yml jest teraz akceptowana tylko, gdy jej nazwa hosta to myworkdayjobs.com (lub subdomena .myworkdayjobs.com). Stare sprawdzenie było dopasowaniem podciągu, więc dowolny URL, który jedynie zawierał ten ciąg — np. https://example.com/?x=myworkdayjobs.com — przechodził i mógł zostać użyty jako endpoint. Prawdziwe endpointy Workday bez zmian. (Zgłoszone przez CodeQL, #443.)

Uwagi

  • Nowy isWorkdayApi() parsuje URL i sprawdza host (server/lib/portals/adapters/workday.mjs). tests/workday-adapter-endpoint.test.mjs (+1). Zestaw: 2522.

[1.195.0] — 2026-08-14

Wydajność (skaner) — wykrywanie repostów pozostaje szybkie przy dużych historiach skanów.

Wydajność

  • Wykrywanie duplikatów ofert nie degraduje się już do O(N²) na dużym scan-history.tsv. Grupowanie tytułów per firma było zagnieżdżoną pętlą płacącą pełny roleFuzzyMatch na każdą parę; teraz to indeks odwrócony — grupowanie wierszy po dokładnym tytule w jednym przebiegu, a potem dopasowanie rozmyte tylko między RÓŻNYMI kubełkami dzielącymi token dyskryminujący (niebazowy). Wyjście jest identyczne — te same klastry repostów — udowodnione testem różnicowym wobec starego algorytmu na 200+ losowych historiach.

Uwagi

  • groupRowsByTitle w server/lib/detect-reposts.mjs (wyeksportowane dla testu różnicowego). tests/detect-reposts-grouping.test.mjs (+2). Zestaw: 2521.

[1.194.0] — 2026-08-14

Naprawiono (skaner) — strony karier Workday z URL o jednym segmencie są teraz poprawnie skanowane.

Naprawiono

  • Adapter Workday analizuje teraz URL-e karier, których ścieżka to jeden segment — np. https://parsons.wd5.myworkdayjobs.com/Search, .../KBR_Careers, .../Careers. Wcześniej witryna spadała do External, adapter trafiał w zły endpoint CXS, a sonda mogła wyglądać zdrowo, nic nie zwracając. Teraz bierze pierwszy niepusty segment ścieżki jako witrynę (odrzucając prefiks języka jak en-US); udokumentowany przypadek /en-US/External bez zmian. (Zgłoszone w #255.)

Uwagi

  • Strukturalne parsowanie ścieżki w server/lib/portals/adapters/workday.mjs. tests/workday-adapter-endpoint.test.mjs (+7). Zestaw: 2519.

[1.193.0] — 2026-08-14

Dodano (statystyki) — zakładka „Cisza po rozmowie”, która pokazuje rozmowy warte przypomnienia.

Dodano

  • Zakładka Cisza po rozmowie w #/stats: rozmowy, które ucichły po oknie grzecznościowym (domyślnie 30 dni), łącząc aktywne rozmowy i tracker — z tym, jak długo każda milczy, datą ostatniej rozmowy i powodem. Łagodna lista przypomnień/domknięć; tylko sugestie, nigdy twierdzenie o odmowie. Bez tokenów.

Uwagi

  • Nowa trasa GET /api/stats/rejection-latency (fail-soft {available:false}). tests/stats-rejection-latency-route.test.mjs (+2). +10 kluczy i18n ×17; help-hint #/stats z 7→8 zakładek. Zestaw: 2510.

[1.192.0] — 2026-08-14

Dodano (cv-studio) — zabezpieczenie „Sprawdź fakty w swoim CV”, które wychwytuje liczby, których nigdy nie miałeś.

Dodano

  • Karta Sprawdź fakty w swoim CV w #/cv-studio: wklej dopasowane CV lub list i sprawdź każdą metrykę i fakt względem prawdziwego CV, profilu i two-pagera. Otrzymujesz werdykt pass / warn / block plus dokładne wymyślone metryki, niepoparte fakty oraz zabronione / ostrzegawcze frazy. Bez LLM; nic nie jest zapisywane.

Uwagi

  • Nowa trasa POST /api/cv-studio/verify-facts: zapisuje tekst do jednorazowego pliku tymczasowego i uruchamia verify-cv-facts.mjs, ufając werdyktowi JSON, mimo że skrypt kończy się kodem 1 przy block. tests/cv-studio-verify-facts-route.test.mjs (+4). +15 kluczy i18n ×17. Zestaw: 2508.

[1.191.0] — 2026-08-14

Dodano (statystyki) — zakładka „Czego się dalej uczyć” porządkująca umiejętności do nauki.

Dodano

  • Zakładka Czego się dalej uczyć w #/stats: zestawienie z całego trackera — brakujące umiejętności, które najczęściej topiły niskie dopasowanie, ważone (przez 5−wynik dopasowania w każdym raporcie) i w poziomach Critical / High / Medium — plus te już pokryte przez Twoje CV/profil. Tylko do odczytu, tylko sugestie, bez tokenów.

Uwagi

  • Nowa trasa GET /api/stats/upskill (pole { error } przy zbyt małej ilości danych; fail-soft {available:false}). tests/stats-upskill-route.test.mjs (+3). +15 kluczy i18n ×17. Zestaw: 2504.

[1.190.0] — 2026-08-14

Dodano (tracker) — panel „Historia firmy”, który pokazuje, które firmy naprawdę Ci odpowiadają.

Dodano

  • Karta Historia firmy na #/tracker: wybierz firmę i zobacz dowody tylko do odczytu — jak bardzo Ci odpowiadała (milczy wobec Ciebie / mieszane / odpowiedziała wcześniej) i czy to samo stanowisko jest publikowane ponownie — łącząc tracker, follow-upy i historię skanów. Bez tokenów; skaner nie jest wywoływany.

Uwagi

  • Nowa trasa GET /api/stats/company-history[?company=] (fail-soft {available:false}). tests/stats-company-history-route.test.mjs (+3). +18 kluczy i18n ×17. Zestaw: 2501.

[1.189.0] — 2026-08-14

Naprawiono (skaner) — poziomy stażu zapisane cyframi rzymskimi liczą się teraz także w tytułach niełacińskich.

Naprawiono

  • Klasyfikator poziomu za skip_tiers czyta teraz przyrostek poziomu cyframi rzymskimi (I / II / III / IV / V) po słowie stanowiska w dowolnym piśmie — „Инженер III”, „エンジニア I”, „Ingénieur IV” — nie tylko po słowach ASCII. Wcześniej cyfra poziomu po słowie niełacińskim była ignorowana, a oferta spadała do mid, więc skip_tiers: [senior] lub [entry] je pomijał.

Uwagi

  • Niezależny od pisma lookbehind w server/lib/classify-tier.mjs; usunięto martwy zdublowany matcher Sr.. tests/classify-tier.test.mjs (+1). Zestaw: 2498.

[1.188.0] — 2026-08-14

Naprawiono (UI) — główne przyciski akcji nie przylegają już do podtytułu strony.

Naprawiono

  • Wiersz głównej akcji / sterowania na stronach Tygodniowy przegląd rozmów, Finansowane firmy, Portale, Plan kariery i Orientacja zawodowa ma teraz odpowiedni górny margines, więc przycisk oddycha pod podtytułem zamiast się o niego opierać.

Uwagi

  • Zabezpieczenie regresji tests/lead-row-top-margin.test.mjs (+5). Zestaw: 2497.

[1.187.0] — 2026-08-14

Poprawiono (skaner) — ustawienie skip_tiers znów działa: oferty, które kazałeś pominąć według stażu, są odrzucane.

Poprawiono

  • Lista skip_tiers: w portals.yml (np. skip_tiers: [intern, entry]) jest teraz uwzględniana przez skan. Tytuł każdej oferty jest klasyfikowany do poziomu (intern / entry / mid / senior) i odrzucany, jeśli jego poziom jest na liście. Wcześniej skan stosował filtry tytułu / lokalizacji / treści / zaufania, ale bez filtra poziomu, więc skip_tiers był po cichu ignorowany. Tytuły bez słowa poziomu trafiają do mid (więc skip_tiers: [mid] odrzuca też większość zwykłych ofert), a klasyfikator czyta słowo poziomu NAJBARDZIEJ NA LEWO.

Uwagi

  • Nowy czysty moduł server/lib/classify-tier.mjs (classifyTier + buildTierFilter), podłączony do łańcuchów filtrów skanerów EN i RU. tests/classify-tier.test.mjs (+7). Zestaw: 2492.

[1.186.0] — 2026-08-14

Dodano (CV Studio) — panel „Luka kompetencji”: które z wymaganych umiejętności oferty twoje CV wymienia, sugeruje lub których brakuje.

Dodano

  • Nowy panel Luka kompetencji w CV Studio. Wybierz zapisany opis stanowiska, a on posortuje każdą wymaganą umiejętność na wymienioną w CV, sugerowaną w CV lub brakującą — porównanie słów bez LLM, nic nie jest zapisywane. Gdy oferta nie miała wyraźnej sekcji wymagań, pojawia się notka o niskiej pewności.

Uwagi

  • Nowy GET /api/jds/:name/skill-gap (nazwa oferty jest sanityzowana i potwierdzana pod jds/, zanim stanie się argumentem; miękki fallback do {available:false} bez skryptu). +13 kluczy i18n ×17. Testy: tests/jds-skill-gap-route.test.mjs (+4, w tym odrzucenie path-traversal). Zestaw: 2485.

[1.185.0] — 2026-08-14

Dodano (statystyki) — zakładka „Lejek i tempo”: jak twój lejek wypada na tle rynku i jak szybko przechodzisz między etapami.

Dodano

  • Nowa zakładka Lejek i tempo w Statystykach pokazuje twoje wskaźniki odpowiedzi i rozmów obok rynkowych zakresów odniesienia (z zastrzeżeniami o małej próbie i błędzie selekcji), listę oczekujących aplikacji w toku poza typowym oknem pierwszej odpowiedzi oraz mediana dni na etap (Zaaplikowano → Odpowiedź → Rozmowa → Oferta) — wolne wiersze są cenzurowane prawostronnie, by nie zaburzały median. Tylko do odczytu i bez tokenów; czyta wyłącznie twój tracker.

Uwagi

  • Nowy GET /api/stats/funnel (miękki fallback do {available:false} bez skryptu). +18 kluczy i18n ×17. Testy: tests/stats-funnel-route.test.mjs (+2). Zestaw: 2481.

[1.184.0] — 2026-08-14

Poprawiono (UI) — kafelki szybkich akcji na Pulpicie układają się teraz w równą siatkę.

Poprawiono

  • Na Pulpicie (Centrum dowodzenia) grupa 3 kafelków renderowała się szerzej niż grupa 4, przez co sekcje miały nierówną prawą krawędź. Każda grupa używa teraz kolumn o równej szerokości (4 na szerokim ekranie, schodząc do 3 / 2 / 1 przy zwężaniu okna), więc wszystkie kafelki są tej samej wielkości, a ich prawe krawędzie się wyrównują.

Uwagi

  • Tylko CSS (.qa-grid: stałe repeat(N, minmax(0,1fr)) zamiast auto-fill). Chronione przez tests/dashboard-grid-align.test.mjs (+2). Zestaw: 2479.

[1.183.0] — 2026-08-14

Dodano (skaner) — sprytniejsze wykrywanie duplikatów: ta sama oferta ponownie wystawiona z linkiem śledzącym nie pojawia się już dwa razy.

Dodano

  • Skaner rozpoznaje teraz ofertę po kanonicznym kluczu URL, więc ta sama oferta ponownie wystawiona z parametrem śledzącym (?utm_…, gclid, …), przez http vs https, albo z końcowym ukośnikiem / #fragmentem jest traktowana jako jedna oferta — bez zduplikowanego wiersza w wynikach czy pipeline i bez zmarnowanej oceny już widzianej oferty. Naprawdę różne oferty (zachowany funkcjonalny id jak gh_jid) nadal liczą się osobno.

Uwagi

  • Nowy server/lib/url-key.mjs, podłączony do deduplikacji obu skanerów i zapisu pipeline. Celowo słabo normalizuje — nigdy nie łączy dwóch różnych ofert. Testy: tests/url-key.test.mjs (+5), tests/parsers.test.mjs (+1). Zestaw: 2477 (+6).

[1.182.0] — 2026-08-14

Poprawiono (skaner) — przedziały wynagrodzeń wyglądają teraz tak samo w każdym języku.

Poprawiono

  • Kwoty wynagrodzeń w wierszach skanu i śledzenia używają neutralnych symboli ≥ i ≤ (np. ≥ 120000 EUR, ≤ 90000) zamiast angielskich słów „from” / „up to”, które przenikały nieprzetłumaczone do nieangielskich interfejsów. Dotyczy każdej tablicy z jednostronnym przedziałem (Getro, Remotli, Manfred, Agentic Jobs, JustJoin, Jobicy); przedziały dwustronne (100000–150000 USD) już były neutralne.

Uwagi

  • Tylko wyświetlanie — filtr wynagrodzeń klienta parsuje liczby niezależnie od prefiksu, więc filtrowanie się nie zmienia. Zestaw: 2471.

[1.181.0] — 2026-08-14

Dodano (skaner) — tablice Getro pokazują teraz wynagrodzenie, wszystkie lokalizacje i oferty zdalne.

Dodano

  • Skaner Getro (tablice sieci talentów funduszy) pokazuje teraz wynagrodzenie przy każdej ofercie (roczny przedział + waluta), wypisuje wszystkie lokalizacje zamiast tylko pierwszej i oznacza oferty zdalne. Oferta Getro w skanie i śledzeniu ma teraz te same dane o wynagrodzeniu i lokalizacji co pozostałe tablice.

Uwagi

  • Tylko skaner; bez nowej zależności, bez zmian tras / CSP / SSRF. Testy: tests/sources-getro.test.mjs (+5). Zestaw: 2470 (+5).

[1.180.0] — 2026-08-14

Poprawiono (ŚREDNIE, raporty) — lista #/reports jest teraz tabelą, a odzyskano prawdziwy wynik, który ukrywał symbol zastępczy Machine Summary.

Poprawiono

  • Lista #/reports to tabela (Raport · Data · Wiarygodność · Wynik), a nie siatka 4 kart. Długi chip „Nie wykryto wyniku” ściskał kolumnę tytułu niemal do zera, a overflow-wrap: anywhere w tytule karty łamał nazwę raportu po jednym znaku. Teraz każde pole ma własną kolumnę, komórka nazwy zawija się po słowach, a na wąskim ekranie tabela przewija się w poziomie (nowy kontener .reports-scroll). Nowy klucz i18n rep.colReport ×17.
  • Prawdziwy wynik w treści (**Итоговый балл:** 1.8 / 5) nie jest już ukrywany przez symbol zastępczy Machine Summary (score: —). Gdy blok ## Machine Summary zawierał wynik nieliczbowy lub spoza zakresu, zajmował miejsce sparsowanego wyniku i blokował rezerwowe parsowanie formy-wartości w pogrubieniu, więc raport pokazywał „Nie wykryto wyniku” mimo prawdziwego X / 5 w treści. parseReportHeader odzyskuje teraz formę-wartość z treści, gdy nie pozostał żaden użyteczny numer (krok 4.5).

Uwagi

  • Tylko klient + parser; bez zmian tras / CSP / SSRF / zapisu do rodzica. Testy: tests/reports-table.test.mjs (+5), tests/report-header-locale.test.mjs (+2). Zestaw: 2465 (+7).

[1.179.0] — 2026-08-13

Zmieniono (LOW, skaner) — 20 zduplikowanych dekoderów encji HTML scalono w jeden wspólny moduł (kontynuacja parytetu, zamyka worklist).

Zmieniono

  • 20 źródeł skanowania miało własne decodeEntities/decodeXmlEntities (+ pomocnik fromCodePoint) — kopie, które się rozjechały (trzy mogły zgłosić RangeError, naprawione w v1.172.0; inne dopuszczały NUL/C0 lub błędnie parsowały &#1a2;). Teraz wszystkie przechodzą przez jeden server/lib/html-entities.mjs (dekoder zgodny z XML 1.0 Char), usuwając ~237 linii duplikacji. 8 źródeł typu RSS zyskało dekodowanie   (wcześniej obsługiwały tylko 5 encji); celowe podwójne dekodowanie cryptocurrencyjobs zachowano przez alias. hh zachowuje własny dekoder (obsługuje —/–, poza wspólną szóstką). Nowy test-strażnik zawodzi, jeśli jakieś źródło znów utworzy lokalny dekoder.

Uwagi

  • Refaktoryzacja zachowująca zachowanie; bez zmian tras / CSP / SSRF / zapisu do rodzica. Testy: tests/decoder-consolidation.test.mjs (+2). Zestaw: 2458 (+2).

[1.178.0] — 2026-08-13

Naprawiono (LOW, parytet z rodzicem) — dwie przestarzałe stałe dopasowano do rodzica (PARENT-SYNC GAP #4 + #5).

Naprawiono

  • User-Agent przeglądarki (GAP #4) — BROWSER_LIKE_USER_AGENT (wysyłany przez workable/workday/oraclecloud/a16z/eightfold do przejścia bramek WAF/bot) podniesiony z Chrome 131 do 151, zgodnie z user-agent.mjs rodzica; stara wersja jest częściej blokowana. Chroniony testem Chrome major ≥ 151.
  • FALLBACK stanów trackera (GAP #5) — ostateczny FALLBACK w states.mjs (używany tylko gdy żywy templates/states.yml jest nieczytelny — świeży klon / izolowany katalog CI) zyskał tureckie aliasy stanów rodzica (#2615): değerlendirildi, başvuruldu, yanıt verildi, mülakat, teklif, reddedildi, iptal edildi, uygun değil, kabul edildi/işe alındı. W produkcji żywy plik już je dostarczał.

Uwagi

  • Tylko dwie stałe; bez zmian tras / CSP / SSRF / zapisu do rodzica. Testy: tests/http-json.test.mjs (+1) + tests/states.test.mjs (+1). Zestaw: 2456 (+2).

[1.177.0] — 2026-08-13

Naprawiono (MEDIUM, skaner) — csod (Cornerstone) zwracał 0 ofert u najemców chroniących API wyszukiwania ciasteczkami sesji (parent #2769, PARENT-SYNC GAP #1).

Naprawiono

  • Niektórzy najemcy Cornerstone ustawiają ciasteczka sesji na stronie startowej witryny kariery i odpowiadają 401 CSOD Unauthorized na API wyszukiwania, o ile te ciasteczka nie wrócą razem z anonimowym tokenem bearer. sources/csod.mjs czyta teraz bootstrap przez nowego helpera fetchResponse, buduje nagłówek Cookie z wartości Set-Cookie (cookieHeaderFrom — tylko name=value, semantyka jar) i odtwarza go w POST wyszukiwania. Tylko to samo pochodzenie (przypięty host + redirect:'error'), więc ciasteczka sesji nigdy nie trafią do strony trzeciej; najemca bez ciasteczek działa jak wcześniej.

Uwagi

  • Nowy server/lib/http-json.mjs::fetchResponse (dodatkowy; istniejące źródła bez zmian). Bez zmian tras / CSP / SSRF / zapisu do rodzica. Testy: tests/sources-parity-v1118a.test.mjs (+1). Zestaw: 2454 (+1).

[1.176.0] — 2026-08-13

Naprawiono (MEDIUM, raporty) — wynik pod pogrubioną etykietą, której nie ma w tabeli RU, wciąż pokazywał “Score not detected” (FIND-5).

Naprawiono

  • Dwa raporty RU zapisywały wynik jako **Итоговый балл:** 1.8 / 5 / **Скор:** 1.8 / 5 — pogrubione etykiety, których REPORT_LABELS.ru nie wylicza (zna tylko „Оценка”/„Балл”), więc wynik nie był parsowany. Zamiast rozbudowywać listę synonimów, parseReportHeader sięga teraz po formę wartości: ułamek według rubryki /5 pod DOWOLNĄ pogrubioną etykietą. Jest niezależny od języka, odporny na nagłówek (brak **, brak wartości /5) i odrzuca datę taką jak 5/5/2026 (negatywny lookahead na mianowniku).

Uwagi

  • Tylko parser serwera; bez zmian tras / CSP / SSRF / zapisu do rodzica. Testy: tests/report-header-locale.test.mjs (+2). Zestaw: 2453 (+2).

[1.175.0] — 2026-08-13

Naprawiono (LOW, utwardzanie) — strażnik regresji dla opisu SEO z FIND-3 + odporny na nulle strip wiarygodności (kontynuacja AI-review).

Naprawiono

  • Strażnik parytetu opisu SEO — poprawka v1.174.0, która zamieniła zakodowane na sztywno “~55” w meta.desc każdego języka na placeholder {adapters} z rejestru, nie miała testu i mogła po cichu się cofnąć przy następnej edycji locale. Nowy, izolowany od CI tests/site-meta-desc-parity.test.mjs zawodzi, jeśli którykolwiek z 17 site/src/i18n/*.json utraci placeholder lub ponownie zakoduje liczbę, albo jeśli Landing.astro przestanie go wstawiać do trzech meta-opisów.
  • Odporny na nulle strip wiarygodności — stripEmphasis zwraca '' dla wejścia nullish zamiast napisu “undefined” (pola są inicjalizowane jako napis, więc to obrona w głąb).

Uwagi

  • Test + jednoliniowy strażnik w parserze; bez zmian tras / CSP / SSRF / zapisu do rodzica. Testy: tests/site-meta-desc-parity.test.mjs (+3). Zestaw: 2451 (+3).

[1.174.0] — 2026-08-13

Naprawiono (HIGH, raporty) — zlokalizowane raporty pokazywały „Score not detected”; opis SEO był nieaktualny.

Naprawiono

  • Parsowanie oceny (FIND-1) — raport nieanglojęzyczny, którego H1 zawiera słowo etykiety oceny (# Оценка вакансии: <tytuł>), nie myli już tego tytułu z oceną. parseReportHeader kotwiczy teraz na zlokalizowanej pogrubionej etykiecie (**Оценка:** 1.5 / 5), pomija wiersze nagłówków i wymaga, by etykieta sąsiadowała z dwukropkiem — więc raporty RU pokazujące „Score not detected” wyświetlają prawdziwą ocenę.
  • Odznaka wiarygodności (FIND-2) — z wartości usuwane jest wyróżnienie Markdown, więc odznaka pokazuje „High Confidence”, a nie „** High Confidence”.
  • Przepełnienie oceny — wiersz oceny z doczepionym tekstem statusu („1.8, Status: Evaluated, …“) jest skracany do samej oceny; .score-pill zyskuje limit bez zawijania/overflow, a kolumna tytułu może się kurczyć, więc kolorowa odznaka nigdy nie wychodzi poza kartę.
  • Opis SEO (FIND-3) — opisy meta / OG / Twitter cvstart.org (wszystkie 17 języków) miały na sztywno „Scan ~55 job boards”, podczas gdy treść liczyła realny rejestr („~75”). Opis wstawia teraz liczbę z rejestru, więc już się nie rozjedzie.

Uwagi

  • Parser serwera + render/CSS klienta + i18n witryny; bez zmian tras / CSP / SSRF / zapisu do rodzica. Testy: tests/report-header-locale.test.mjs (+4). Zestaw: 2448 (+4).

[1.173.0] — 2026-08-13

Dodano (LOW, konfiguracja) — Hermes dołącza do wykrywanej listy CLI AI (parytet z career-ops).

Dodano

  • Karta #/config → „Narzędzia CLI AI” wykrywa teraz Hermes (Nous Research), nowo obsługiwane środowisko agenta projektu nadrzędnego (plik hermes). Stała lista dozwolonych w server/lib/routes/cli-detect.mjs rośnie z 10 do 11 narzędzi; wykrywanie pozostaje skanowaniem PATH tylko do odczytu (żaden plik binarny nie jest uruchamiany).

Uwagi

  • Bez zmian i18n / tras / CSP / SSRF / zapisu do rodzica; lista jest stała, nigdy nie jest wejściem. Zestaw: 2444 (kanarek cli-detect zaktualizowany 10 → 11).

[1.172.0] — 2026-08-13

Naprawiono (MEDIUM, skaner) — zniekształcona encja HTML mogła zawiesić źródło skanowania (parytet z career-ops #2150).

Naprawiono

  • Źródła oraclecloud, gem i dassault dekodowały numeryczne encje HTML ze słabym sprawdzeniem Number.isFinite przed String.fromCodePoint — odwołanie powyżej 0x10FFFF (np. &#99999999; ze zniekształconego lub złośliwego kanału) zgłaszało nieprzechwycony RangeError i przerywało całe parsowanie tego źródła. Wspólny moduł server/lib/html-entities.mjs (odzwierciedlający _html-entities.mjs projektu nadrzędnego) ogranicza teraz odwołania numeryczne do zbioru Char XML 1.0 §2.2, więc String.fromCodePoint nigdy nie zgłosi wyjątku, i osobno dopasowuje szesnastkowe i dziesiętne, dzięki czemu &#1a2; nie jest już błędnie parsowane. Trzy źródła go importują.

Uwagi

  • Bez zmian dla poprawnych kanałów; bez zmian JS / i18n / tras / CSP / SSRF / zapisu do rodzica. Konsolidacja pozostałych ~20 kopii dekodera w źródłach jest śledzona w qa/PARENT-SYNC-WORKLIST-v1.26.0.md.
  • Testy: tests/html-entities.test.mjs (+7). Zestaw: 2444 (+7).

[1.171.0] — 2026-08-13

Zmieniono (NISKIE, design-system) — tokeny skali typograficznej + warstwy z-index (D-4, pierwszy krok). Rozmiary i nakładanie były literałami per komponent.

Zmieniono

  • Warstwy z-index — wprowadzono tokeny --z-* (--z-topbar … --z-skiplink) i zmigrowano każdy literał z-index. Wartości zachowane, nakładanie identyczne; nowy kanarek zakazuje nowych magicznych liczb.
  • Skala typograficzna — rampa --font-size-* (xs 11 … 2xl 28, base = Inter 15px); zmigrowano główne rozmiary (bez zmian wizualnych). Wartości spoza rampy migrują stopniowo (docs/UX-ROADMAP.md).

Uwagi

  • Tylko token CSS; bez zmian zachowania/JS/i18n/trasy/CSP/SSRF/zapisu. Bez zmian pikseli. tests/design-tokens-scale.test.mjs (+3). Zestaw: 2437 (+3).

[1.170.0] — 2026-08-13

Dodano (NISKIE) — uczciwe wskazówki ETA przy długich generacjach AI (P4-ETA). Ciężkie generacje (plan kariery ~40 s, orientacja / rynek / networking ~30 s, two-pager ~20 s) pokazywały tylko „Generowanie…” bez informacji o czasie.

Dodano

  • Obok każdego przycisku długiej generacji pojawia się teraz wyciszona wskazówka ⏱ ~Ns (jak ETA na #/auto). Wspólny styl .eta-hint + dwa ogólne klucze (common.eta ~{n}s, common.etaTitle).

Uwagi

  • Tylko klient; bez zmian trasy/CSP/SSRF/zapisu. +2 klucze i18n ×17 (migawka 1219 → 1221). tests/generation-eta-hint.test.mjs (+2). Zestaw: 2434 (+2).

[1.169.0] — 2026-08-13

Dodano (NISKIE) — podgląd PDF w przeglądarce (D-5). GET /api/output/pdfs/:name wymuszał Content-Disposition: attachment, więc nawet przycisk „Otwórz” na #/cv pobierał zamiast wyświetlać.

Dodano

  • ?inline=1 serwuje TEN SAM zweryfikowany plik z Content-Disposition: inline, do 👁 Podglądu w nowej karcie; domyślnie nadal pobieranie. Bez nowej trasy; te same zabezpieczenia nazwy.
  • Pierwszy przycisk listy PDF na #/cv to teraz 👁 Podgląd obok ⬇ Pobierz. cv.openPdf „Otwórz” → „Podgląd” ×17.

Uwagi

  • Bez zmian CSP/SSRF — ten sam sanitizePathName. Jeden istniejący klucz i18n przeredagowany ×17 (migawka 1219). tests/output-pdfs.test.mjs (+3). Zestaw: 2432 (+3).

[1.168.0] — 2026-08-13

Naprawiono (NISKIE, a11y) — wiersze pól wyboru spełniają teraz minimum 24×24 WCAG 2.5.8 (D-2). Etykiety pól wyboru/radio na #/scan, #/config, #/evaluate i #/cv-studio mieściły się w paśmie ~22 px.

Naprawiono

  • Ograniczona reguła label:has(> input[type="checkbox"/"radio"]) { min-height: 24px } gwarantuje pasmo ≥24 px. Tylko min-height — etykiety są już flex, nic się nie przesuwa; .apply-checklist (32 px) już był zgodny.

Uwagi

  • Tylko CSS; bez zmian zachowania/JS/i18n/trasy/CSP/SSRF/zapisu. tests/checkbox-target-size.test.mjs (+1). Zestaw: 2429 (+1).

[1.167.0] — 2026-08-13

Naprawiono (NISKIE, design-system) — powierzchnie wypukłe oddzielają się teraz od linii (D-3). Tokeny --panel-2 / --surface-elev1 rozwiązywały się do --slate, tej samej wartości co linie --line / --border, bez separacji wizualnej.

Naprawiono

  • Dedykowany, świadomy motywu token --elev (#eef1f6 jasny / #1e232e ciemny, różny od --slate w obu motywach) stoi teraz za powierzchniami wypukłymi; linie pozostają na --slate. Pozostałe ustalenia (D-2, D-4, D-5, P4-ETA) w backlogu docs/UX-ROADMAP.md.

Uwagi

  • Tylko token CSS; bez zmian zachowania/JS/i18n/trasy/CSP/SSRF/zapisu. tests/elevation-token.test.mjs (+2). Zestaw: 2428 (+2).

[1.166.0] — 2026-08-13

Naprawiono (NISKIE) — terminologia rubryki odzwierciedla teraz kanoniczne docs. career-ops.org/docs opisuje „pięć wymiarów plus całościowa ocena globalna”, ale web-ui, cvstart.org i wiki mówiły „rubryka o sześciu wymiarach” (5 + 1 = 6, lecz słownictwo się różniło).

Naprawiono

  • Przyjęto sformułowanie z docs — „pięć wymiarów plus całościowa ocena globalna” — spójnie w README ×17, na stronie cvstart.org ×17, w przewodniku pomocy ×17, w docs/career-ops-canonical.md i w wiki (Home ×17 + Features).

Uwagi

  • Tylko docs/marketing; bez zmian kodu/klucza i18n/trasy/CSP/SSRF/zapisu. tests/rubric-terminology.test.mjs (+2). Zestaw: 2426 (+2).

[1.165.0] — 2026-08-13

Naprawiono (NISKIE) — termin “Two-pager” jest teraz spójny w obrębie każdego języka. W arabskim pasek boczny pokazywał łacińskie “Two-pager”, podczas gdy <h1> był w pełni zlokalizowany — jedyny łaciński ciąg w skądinąd lustrzanej nawigacji RTL.

Naprawiono

  • Decyzja wdrożona: w każdym języku nav.twoPager i twoPager.title używają zgodnego terminu (oba po łacinie albo oba zlokalizowane). Tylko arabski był rozdzielony; jego etykieta nawigacji jest teraz zlokalizowana (“الصفحتان”). Nowy test-kanarek zawodzi, jeśli któryś język znów je rozdzieli.

Uwagi

  • Tylko tekst; bez zmian trasy/CSP/SSRF/zapisu. Zmieniono 1 wartość i18n (ar); bez nowych kluczy (migawka 1219). tests/two-pager-term-consistency.test.mjs (+2). Zestaw: 2424 (+2).

[1.164.0] — 2026-08-13

Naprawiono (NISKIE) — placeholder wyszukiwania nie przelewa się już w żadnym języku. “Find a company, role or URL…” był ucinany (nowrap), gdy pasek się kurczył; połowa “…or URL” nigdy nie była widoczna.

Naprawiono

  • top.search (×17) to teraz krótkie “Szukaj lub wklej URL” (≤24 znaki w każdym języku), mieści się nawet w wąskim pasku i zachowuje wskazówkę URL. Fallback w index.html pasuje; aria-label zachowuje pełny opis.

Uwagi

  • Tylko tekst; bez zmian trasy/CSP/SSRF/zapisu. Jeden istniejący klucz i18n przeredagowany ×17 (bez nowych; migawka 1219). tests/search-placeholder-fit.test.mjs (+2). Zestaw: 2422 (+2).

[1.163.0] — 2026-08-13

Naprawiono (NISKIE) — asystent “Zapytaj dokumentację” obejmuje teraz eksport raportu do PDF. Odpowiadał, że przewodnik tego nie obejmuje, choć #/reports/:slug ma działający przycisk 📄 Generate PDF.

Naprawiono

  • Dodano H3 “Eksport raportu do PDF” w §10 Raporty we wszystkich 17 pakietach pomocy (gdzie jest przycisk, plik trafia do output/*.pdf, wymaga Playwrighta, sprawdź przed wysłaniem). Wyszukiwanie asystenta pokazuje teraz sekcję Raporty.

Uwagi

  • Tylko dokumentacja/pomoc; bez zmian kodu/trasy/CSP/SSRF/zapisu. Próg pomocy 112 → 113 H3 (31 H2 bez zmian). tests/help-reports-pdf-section.test.mjs (+2). Zestaw: 2420 (+2).

[1.162.0] — 2026-08-13

Naprawiono (ŚREDNIE) — “?” pomocy jest teraz celem ≥24×24 (WCAG 2.5.8). .help-hint miał 18×18 px z padding:0, poniżej minimum, na każdym nagłówku.

Naprawiono

  • Pole .help-hint ma teraz 24×24 (mierzalny cel), a widoczny pierścień pozostaje 18px — rysowany wyśrodkowanym ::before, więc glif i linia bazowa <h1> bez zmian. Stany hover/aktywny/fokus podążają za pierścieniem; margines 6→3px zachowuje odstęp.

Uwagi

  • Tylko CSS; bez zmian JS/i18n/trasy/CSP/SSRF/zapisu. tests/help-hint-target-size.test.mjs (+2). Zestaw: 2418 (+2).

[1.161.0] — 2026-08-13

Naprawiono (ŚREDNIE) — #/reports pokazuje chip “Nie wykryto wyniku” zamiast pustego miejsca. Po parserze wielojęzycznym z v1.159.0 raport bez możliwego do odczytania wyniku pokazywał pusty obszar, nieodróżnialny od błędu.

Naprawiono

  • Komórka wyniku się rozgałęzia: jest wynik → pigułka tonu; brak wyniku → wyciszony chip .score-muted (“Nie wykryto wyniku”, ×17) z podpowiedzią “Otwórz raport…”. Karta pozostaje role="link" obsługiwanym z klawiatury, data się wyświetla.
  • Ponownie używa istniejącego neutralnego tokenu; bez nowego koloru.

Uwagi

  • Tylko klient; bez zmian trasy/CSP/SSRF/zapisu. +2 klucze i18n ×17 (migawka 1217 → 1219). Zestaw: 2416 (+3).

[1.160.0] — 2026-08-13

Naprawiono (WYSOKIE) — tekst o dostawcach nie zaprzecza już obietnicy 7 dostawców. #/config mówił, że ocena na żywo “używa klucza Anthropic lub Gemini”, a klucz OpenAI “nie jest używany przez web UI”; pulpit pokazywał “Anthropic-first scoring” — fałsz od kaskady 7 dostawców (v1.157.0).

Naprawiono

  • config.providerModelNote (×17): teraz mówi, że ⚡ ocena na żywo działa bezgłowo na dowolnym z siedmiu kluczy (Anthropic · Gemini · OpenAI · Qwen · OpenRouter · GitHub Models · Hermes), uporządkowanych automatycznie z rezerwą. Usunięto fałszywe zdanie o OpenAI.
  • dash.quick.evaluateSub (×17): neutralny (“Ocena dopasowania 0–5”). Keys: N / 5 → N / 7.

Uwagi

  • Tylko tekst; bez zmian trasy/CSP/SSRF/zapisu. Bez nowych kluczy i18n (migawka 1217). Zestaw: 2413 (+3).

[1.159.0] — 2026-08-13

Naprawiono (WYSOKIE) — metadane raportu nie są już powiązane z językiem. Raporty generowane w języku innym niż angielski pokazywały pusty pasek metadanych na #/reports, ponieważ parseReportHeader rozpoznawał tylko angielskie etykiety pogrubione.

Naprawiono

  • parseReportHeader analizuje teraz niezależny od języka blok YAML ## Machine Summary (score: / legitimacy: / date: — to samo źródło, które już czyta auto-pipeline): etykiety angielskie → blok Machine Summary → etykiety lokalne (REPORT_LABELS, 17 języków). Raporty angielskie pozostają identyczne bajt po bajcie.
  • Tolerancyjne parsowanie liczby (1.5/5, 1,5/5, 1.5 из 5, 4.5 out of 5); data przechodzi na mtime pliku, gdy jej brak.

Uwagi

  • Tylko odczyt/analiza; bez zmian trasy, CSP, SSRF ani zapisu do rodzica. Bez nowych kluczy i18n. Zestaw: 2410 (+8).

[1.158.0] — 2026-08-12

Naprawiono — dwa kosmetyczne błędy wyświetlania (przeciekające «?» w tytule karty oraz błędna liczba dostawców na landingu). Tylko wyświetlanie; bez zmian zachowania, bezpieczeństwa ani przepływu danych.

Naprawiono

  • «?» z HelpHint nie przecieka już do document.title. Router wyprowadzał tytuł karty z surowego h1.textContent, więc karta pokazywała «Vacancy search?» zamiast «Vacancy search». router.js::focusNewView klonuje teraz nagłówek, usuwa .help-hint, a dopiero potem czyta tekst; widoczne «?» pozostaje nietknięte.
  • cvstart.org pokazywał «17 AI providers» zamiast «7». Helper sub() w Features.astro zamieniał wszystkie {n} na liczbę języków (17) przed podstawieniem per-karta; teraz {n} jest rozwiązywane per-karta (dostawcy → 7, języki → 17).

Uwagi

  • Bez zmian serwera, trasy, CSP, SSRF ani kluczy i18n; forma facts.json bez zmian. Zestaw: 2402 testy (+1).

[1.157.0] — 2026-08-12

Naprawiono — ewaluacje na żywo działają teraz z DOWOLNYM skonfigurowanym dostawcą, nie tylko Anthropic/Gemini. Użytkownik mający tylko OPENROUTER_API_KEY był błędnie zmuszany do trybu ręcznego.

Naprawiono

  • Przyczyna źródłowa: pin LLM_PROVIDER bez klucza (np. LLM_PROVIDER=claude z init) kończył ślepo; teraz następuje przełączenie na kolejność auto wśród skonfigurowanych dostawców (w selectActiveProvider + obu kaskadach dispatch).
  • Gating po stronie klienta (#/deep + widoki mode-page) używa teraz window.ProviderStatus (/api/status/providers, wszystkie 7) zamiast przestarzałej sondy Anthropic/Gemini; przepisane teksty (deep/eval × 17) + odznaka „Ewaluacje na żywo” na dashboardzie + config.llmProviderHint.

Uwagi

  • Bez zmian bezpieczeństwa. Zestaw: 2401 testów (+5).

[1.156.0] — 2026-08-12

Refaktor — podzielić scan.js poniżej limitu rozmiaru (P-16) + poprawka CodeQL. scan.js miał 906 linii; wyodrębniono dwie fabryki zachowujące zachowanie → 648. Kończy parę podziałów widoków P-15/P-16.

Zmieniono

  • Nowe scan/runner.js (silnik wykonania skanu) i scan/filters.js (maszyna stanów filtrów) przez worki ctx/refs; scan.js łączy oba.

Naprawiono

  • CodeQL js/useless-assignment-to-local (#428) w config/tab-controller.js: let n = i; → let n;.

Uwagi

  • Czysty refaktor, bez zmiany zachowania; 4 testy czytające źródło przekierowano. Oba duże widoki poniżej 800 (P-15/P-16 gotowe). Zestaw: 2396 testów.

[1.155.0] — 2026-08-12

Refaktor — podzielić config.js poniżej limitu rozmiaru (P-15). config.js miał 1030 linii (ponad limit 800); wyodrębniono dwa moduły zachowujące zachowanie, do 783.

Zmieniono

  • Nowe config/field-specs.js (dane pól + listy modeli) i config/tab-controller.js (fabryka paska zakładek); config.js je referencuje, logika renderu bez zmian.

Uwagi

  • Czysty refaktor, bez zmiany zachowania; 6 testów czytających źródło przekierowano. scan.js (906) bez zmian (już częściowo podzielony; rdzeń zbyt sprzężony na czysty podział mechaniczny). Zestaw: 2396 testów.

[1.154.0] — 2026-08-12

Nowy przewodnik — „Uruchom cały stack w chmurze”. career-ops nie ma własnej historii chmury/serwera, więc ją dodajemy: przepis krok po kroku, jak umieścić nadrzędny pipeline career-ops, tę przeglądarkę career-ops-ui i silnik AI (subskrypcja Claude przez Claude Code, lokalny Hermes, lub klucze API) na małym, zawsze włączonym serwerze. Dostarczane jako Pomoc §31 w 17 językach, sekcja README i strona wiki.

Dodano

  • Pomoc §31 „Uruchom cały stack w chmurze” (× 17) — trzy części, provisioning + instalacja, wybór silnika, bezpieczne wystawienie (odwrotne proxy HTTPS + auth + niezmienniki CSP/SSRF/XSS/bez-sekretów). Bundle pomocy rośnie do 31 H2 / 112 H3.
  • README — sekcja „Uruchom cały stack w chmurze” (× 17) + strona Cloud-Deployment w wiki.

Uwagi

  • Tylko docs — bez trasy, serwera i zmian klienta; bez nowego klucza i18n. 4 testy pomocy przechodzą na kontrakt 31 H2 / 112 H3. Zestaw: 2396 testów (bez zmian).

[1.153.0] — 2026-08-12

Skaner Jobvite przeniesiony na publiczny kanał XML (sync z rodzicem). Rodzic wycofał API JSON Jobvite (zwraca zero ofert); source w web-ui używał tego samego martwego endpointu, więc każda śledzona firma Jobvite skanowała się po cichu pusto. Port poprawki rodzica (#2623): source czyta teraz publiczny kanał XML per-tenant, kluczowany przez companyEId.

Naprawiono

  • Source wołał wycofane API JSON i zwracał zero ofert; teraz woła https://app.jobvite.com/CompanyJobs/Xml.aspx?c={companyEId} i parsuje XML <result><job>… (CDATA + encje, detail-url przed apply-url).

Zmieniono

  • Rozwiązywanie companyEId: (1) company_eid: w portalu, (2) parametr c= jawnego api:, (3) odkrywanie ze strony boardu. fetchText (http-json.mjs) dołącza .location/.retryAfter do błędu non-ok (tylko odczyt, wstecznie zgodne).

Uwagi

  • Bezpieczeństwo — dwa hosty (jobs.jobvite.com, app.jobvite.com) przypięte przez assertJobviteUrl: tylko https, ścisła allowlista, żadne przekierowanie nie jest śledzone. companyEId to tylko wartość ?c=; liczba sources bez zmian.
  • Zestaw: 2396 testów (+4).

[1.152.0] — 2026-08-12

Dostawca Hermes — okablowanie ukończone + aktualizacja dokumentacji. Przegląd kodu integracji Hermes z v1.151.0 wykrył dwie realne luki i cztery elementy kompletności; wszystkie naprawiono tutaj, a lista dostawców LLM w całej aplikacji została doprowadzona do pełnej siódemki na wszystkich powierzchniach dokumentacji i w 17 językach.

Naprawiono

  • #/config nie mógł wymusić Hermesa — lista LLM_PROVIDER pokazywała tylko sześciu dostawców, więc HERMES_API_KEY dało się ustawić, ale nie wymusić Hermesa z UI. Teraz hermes to 8. opcja, a nowy test parzystości nie pozwoli liście znów rozejść się z LLM_PROVIDERS.
  • Krótkie klucze self-hosted były po cichu odrzucane — próg 20 znaków w isUsableKey był dobrany do kluczy chmurowych; hasHermesKey używa teraz złagodzonego progu 8 (przykład z dokumentacji Hermes ma 19 znaków).

Zmieniono

  • Listę dostawców znormalizowano do pełnej siódemki w README (× 17), pomocy w aplikacji (× 17), słowniku config.llmProviderHint (× 17) i docs/sdd; hermesChatUrl uzupełnia host bez ścieżki; tekst ręcznego fallbacku wymienia Hermesa.

Uwagi

  • Bezpieczeństwo bez zmian — brak nowej trasy i zmian SSRF/CSP; health/doctor zyskuje wiersz HERMES_API_KEY.
  • Zestaw: 2392 testów (+2).

[1.151.0] — 2026-08-12

Hermes jest teraz podłączonym dostawcą LLM (Phase 5) — spike zakresu Phase 5 potwierdził, że Hermes od Nous Research ma API Server zgodny z OpenAI (hermes gateway → POST /v1/chat/completions), więc career-ops-ui uruchamia teraz ewaluacje na żywo przez lokalnego Hermesa tak jak OpenAI/Qwen. Ustaw HERMES_API_KEY w Ustawieniach aplikacji, a dołączy do kolejności auto (ostatni). Zamyka ostatni otwarty punkt roadmapy — Phase 5, Shape A.

Dodano

  • Dostawca LLM Hermes (Shape A) — runHermes na współdzielonym kliencie runOpenAICompatible (server/lib/openai.mjs), w obu kaskadach (llm-dispatch.mjs + routes/llm.mjs), na końcu kolejności auto + pin LLM_PROVIDER=hermes, /api/status/providers i llm-pricing.mjs. Sięga do konfigurowalnego lokalnego base URL (domyślnie http://127.0.0.1:8642/v1) z auth Bearer — to SKONFIGUROWANY endpoint dostawcy (jak OpenRouter/Qwen), a nie URL oferty od użytkownika, więc nie przechodzi przez guard SSRF.
  • Pola #/config — HERMES_API_KEY (sekret) + HERMES_BASE_URL + HERMES_MODEL (domyślnie hermes-agent), 6 nowych kluczy i18n × 17 języków (snapshot 1208 → 1214).

Zmieniono

  • Spike zakresu rozwiązany: docs/integrations/HERMES.md, pomoc w aplikacji §30 (× 17), zapowiedź README (× 14), skill hermes-bridge i roadmapa przechodzą z „zaplanowane / jeszcze niepodłączone” na podłączone (Shape A). Shape B (dedykowany relay runtime agenta) nie był potrzebny.

Uwagi

  • Bezpieczeństwo: fetch dostawcy to skonfigurowany endpoint, tej samej kategorii co inni dostawcy zgodni z OpenAI — brak nowej powierzchni SSRF, brak zmian CSP/sanitizera. HERMES_API_KEY to SECRET_KEY (nigdy nie wyświetlany).
  • Testy (izolowane w CI, zaślepka transportu): tests/hermes-provider.test.mjs (+5); kanarek „brak gałęzi Hermes” z v1.146.0 jest odwrócony, by potwierdzać, że JEST podłączona; testy powierzchni dostawców zaktualizowane do kolejności 7 dostawców.
  • Zestaw: 2390 testów (+5).

[1.150.0] — 2026-08-12

Spójne stany puste (dopracowanie Phase 4) — każdy panel „jeszcze nic tu nie ma” renderuje się teraz przez jeden wspólny styl .empty, zamiast by kilka widoków redeklarowało wygląd inline z magicznym 40px. Drobna poprawka spójności wizualnej; puste stany #/activity, #/cv-studio, #/stats i #/usage pasują teraz do wszystkich innych (tokenizowany padding 48px + przerywana ramka).

Zmieniono

  • #/activity, #/cv-studio, #/stats, #/usage usunęły swój inline style: { padding: '40px', textAlign: 'center', color: 'var(--foggy)' } na pustych panelach — wszystkie trzy właściwości zapewnia już wspólna klasa .empty (--space-7 = 48px, wyśrodkowane, przygaszone, przerywana ramka). Dzięki temu te cztery renderują się identycznie jak ~25 innych paneli .empty.
  • Uzasadnione nadpisania per-widok (#/dashboard width:100%, #/pipeline border:none) pozostają — usunięto tylko czysto redundantne redeklaracje.

Uwagi

  • Tylko porządki użycia CSS po stronie klienta — bez zmiany trasy, serwera, klucza i18n czy reguł CSS (klasa .empty bez zmian); snapshot słownika 1208. Zweryfikowane w przeglądarce (pusty panel #/usage wylicza 48px paddingu + przerywaną ramkę, 0 błędów konsoli).
  • Nowy test kanarkowy tests/empty-state-consistency.test.mjs utrzymuje .empty jako jedyne źródło prawdy. Phase 5 (dostawca Hermes) pozostaje zablokowana.
  • Zestaw: 2385 testów (+2: tests/empty-state-consistency.test.mjs).

[1.149.0] — 2026-08-12

Portale przeniesione do Ustawień (Phase 4) — #/portals znajduje się teraz w grupie nawigacji Setup, obok Ustawień aplikacji, zamiast pod Sourcing. Od v1.144.0 to powierzchnia ustawień (włączanie/wyłączanie śledzonych firm + sonda stanu ATS), a nie akcja sourcingu — więc tam jest jego miejsce. Tylko zmiana nawigacji; strona i jej trasa bez zmian.

Zmieniono

  • Element nawigacji #/portals → grupa Setup (w public/index.html), umieszczony tuż za Ustawieniami aplikacji. Usunięty z grupy Sourcing (która zachowuje Scan / Pipeline / Auto-pipeline / Firmy z finansowaniem). Trasa #/portals, widok i etykieta nav.portals bez zmian — przesunęła się tylko pozycja na pasku bocznym.

Uwagi

  • Tylko znaczniki nawigacji — bez zmiany trasy, widoku, klucza i18n czy serwera. Zweryfikowane w przeglądarce (0 błędów konsoli); chronione przez tests/portals-nav-placement.test.mjs.
  • Zestaw: 2383 testów (+2: tests/portals-nav-placement.test.mjs).

[1.148.0] — 2026-08-12

Czytelniejsze filtry skanowania (Phase 4) — panel filtrów jest teraz uporządkowaną siatką — panel filtrów #/scan przeszedł z poszarpanego flex-wrap sztywnych pól o zmiennej szerokości na responsywną siatkę, a akcje Zastosuj / Wyczyść zajmują teraz własny, oddzielony i wyrównany do prawej wiersz. Te same filtry, to samo zachowanie — po prostu czytelniej. Szlif projektowy (bez parent-sync).

Zmieniono

  • Panel filtrów #/scan → responsywna siatka — .scan-filters to teraz display: grid z kolumnami repeat(auto-fill, minmax(180px, 1fr)) i równymi odstępami, więc 11 opisanych filtrów układa się w schludne kolumny przy każdej szerokości zamiast zawijać się w nierówny wiersz.
  • Akcje Zastosuj / Wyczyść obejmują całą siatkę we własnym wierszu, oddzielone cienką linią i wyrównane do prawej. Usunięto stary trik z ukrytą etykietą + wewnętrzny wrapper flex w scan.js.

Uwagi

  • Tylko CSS + drobne porządki w DOM — każdy id filtra (#scan-filter-*, #scan-apply) i podłączenie SR.render() są bez zmian, więc przepływ Playwright pozostaje nietknięty. Bez nowych kluczy i18n.
  • Zweryfikowane w przeglądarce (0 błędów konsoli); chronione przez tests/scan-filters-grid.test.mjs.
  • Zestaw: 2381 testów (+3: tests/scan-filters-grid.test.mjs).

[1.147.0] — 2026-08-12

Hermes & Telegram — sekcja pomocy w aplikacji + powierzchnia cvstart.org (Phase 5b, część 2) — druga i ostatnia część prac nad dokumentacją Hermesa: instrukcja mieszka teraz wewnątrz własnego przewodnika pomocy aplikacji, we wszystkich 17 językach, a wbudowany asystent dokumentacji odpowiada na jej podstawie na pytania o Hermes. Nadal wyłącznie dokumentacja — ścieżka dostawcy LLM Hermes pozostaje zaplanowana / jeszcze niepodłączona (Phase 5).

Dodano

  • Pomoc w aplikacji §30 „Hermes & Telegram” × 17 języków — nowa sekcja przewodnika (czym jest Hermes + dwie formy integracji; uruchamianie na serwerze w chmurze; Telegram przez Hermes + reguła „czego NIE ujawniać”), dostępna z #/help. Grounding docs-assistant / DocsFab pobiera ją automatycznie, ponieważ oba czytają docs/help/<lang>.md.
  • cvstart.org — link do przewodnika Hermes kierujący do dokumentu na GitHub.

Zmieniono

  • Próg pakietu pomocy podniesiony 29 → 30 H2 / 105 → 108 H3 (canonical-docs-coverage, help-ui, help-ru-config-section); §30 dodaje 3 H3.

Uwagi

  • Wciąż nic nie wywołuje Hermesa. Nowy test kanarkowy tests/help-hermes-section.test.mjs sprawdza, że każdy język zawiera §30 z jej niezależnymi od języka kotwicami (docs/integrations/HERMES.md, hermes-bridge, #/help, 127.0.0.1, Telegram). Dostawca pozostaje zablokowany do czasu kontraktu API z Phase 5.
  • To zamyka produkt dokumentacja + skill dla Phase 5b; integracja dostawcy (Phase 5) pozostaje osobnym, zablokowanym elementem.
  • Zestaw: 2378 testów (+2: tests/help-hermes-section.test.mjs).

[1.146.0] — 2026-08-12

Agent Hermes + Telegram — przewodnik integracyjny + skill (Phase 5b, część 1) — możesz uruchomić career-ops-ui na serwerze w chmurze i przekazywać jego zdarzenia (zakończony skan, nowy raport, pilny follow-up) do Telegrama za pomocą agenta Hermes od Nous Research. To wydanie dostarcza dokumentację projektową + wdrożeniową oraz skill hermes-bridge; ścieżka dostawcy LLM Hermes wciąż jest zaplanowana / jeszcze niepodłączona (zablokowana przez spike dotyczący kontraktu API w Phase 5). Dokumentacja z wyprzedzeniem względem kodu — celowo.

Dodano

  • docs/integrations/HERMES.md — dogłębna analiza: dwie formy integracji (endpoint kompatybilny z OpenAI vs. runtime agenta), wdrożenie na serwerze w chmurze (reverse proxy + HTTPS + systemd, kontrakt tylko do odczytu z parentem na maszynie headless), Telegram przez Hermes oraz lista modelu zagrożeń „czego NIE ujawniać” (żadnego CV / wynagrodzenia / treści raportów / kluczy na kanał).
  • Zapowiedź ## Hermes agent + Telegram w README — krótkie wskazanie + link, w angielskim README i odzwierciedlone w przetłumaczonych README każdego języka.
  • Skill hermes-bridge (.claude/skills/hermes-bridge/), która operacjonalizuje przewodnik — sprawdzenia wymagań wstępnych i zakresu (Node ≥ 18, obecność kluczy, dostępność endpointu przez ścieżkę bezpieczną wobec SSRF), nigdy nie zapisuje sekretów na dysku/w logach i odmawia wymyślania endpointu Hermes lub twierdzenia, że dostawca jest podłączony.
  • Sekcja Integrations w docs/architecture/OVERVIEW.md linkuje do przewodnika.

Uwagi

  • Nic jeszcze nie wywołuje Hermesa. Test kanarkowy (tests/hermes-docs.test.mjs) sprawdza znaczniki uczciwości „zaplanowane / jeszcze niepodłączone” oraz to, że llm-dispatch.mjs nie ma żadnej gałęzi Hermes/Nous — więc podłączenie dostawcy później musi zaktualizować dokumentację + roadmapę w tej samej zmianie.
  • Odłożone do v1.147.0 (Phase 5b, część 2): sekcja H2 „Hermes & Telegram” w pomocy w aplikacji × 17 języków oraz powierzchnia marketingowa cvstart.org.
  • Zestaw: 2376 testów (+4: tests/hermes-docs.test.mjs).

[1.145.0] — 2026-08-12

Wnikliwe statystyki (cd.): przebudowywalny wykres — karta „Trend ról docelowych” na #/stats ma teraz widżet Zbuduj wykres: wybierz metrykę × wymiar, a on odrysuje się na żywo. Prośba UX od użytkownika (bez parent-sync).

Dodano

  • Przebudowywalny wykres metryka × wymiar — wybierz metrykę (Oferty / Mediana wynagrodzenia / Średnie wynagrodzenie) i wymiar (Wg kraju / Wg roli), a wykres słupkowy odrysuje się natychmiast. Metryki wynagrodzeń respektują walutę + przełącznik rocznie ⇄ miesięcznie; oferty to zwykłe zliczenie.
  • 8 nowych kluczy i18n × 17 języków; snapshot 1200 → 1208.

Uwagi

  • Zweryfikowano w przeglądarce (0 błędów konsoli). Zestaw: 2372 testów (+2).

[1.144.0] — 2026-08-12

Ustawienia i filtry (Faza 4, część 1): włączanie/wyłączanie śledzonych portali — możesz teraz włączyć lub wyłączyć obserwowaną firmę z #/portals, a skaner to respektuje. Prośba UX od użytkownika (bez parent-sync).

Dodano

  • Przełącznik Włącz/Wyłącz dla firmy na #/portals — jedno kliknięcie wyłącza portal (skaner EN już pomija firmy enabled: false, więc wyłączony portal wypada ze wszystkich przyszłych skanów) lub włącza go z powrotem, z optymistycznym powiadomieniem.
  • POST /api/portals/toggle — jawny zapis użytkownika, który chirurgicznie i z walidacją parsowania przełącza flagę enabled firmy w portals.yml (komentarze, kolejność i pozostałe pola zachowane). 5 nowych kluczy i18n × 17 języków; snapshot 1195 → 1200.

Uwagi

  • Zmiana w skanerze wyniosła zero — en-scanner.mjs już filtruje enabled !== false. Zestaw: 2370 testów (+3).

[1.143.0] — 2026-08-12

Zrozumiałość (cd.): podpowiedzi ? na głównych widokach roboczych — pomocnicze ? obejmuje teraz dziewięć głównych stron akcji, we wszystkich językach. Poprawka UX zgłoszona przez użytkownika (bez parent-sync).

Dodano

  • Podpowiedź ? na kolejnych 9 tytułach widoków — #/scan, #/evaluate, #/cv-studio, #/tracker, #/config, #/deep, #/batch, #/auto, #/apply otrzymują wbudowane ? (przez HelpHint.title), które otwiera zlokalizowany dymek „co to robi / jak używać / czego oczekiwać” — ten sam bezpieczny dla CSP komponent z v1.139.0.
  • 9 nowych kluczy i18n × 17 języków (help.hint.scan/…/apply); snapshot 1186 → 1195.

Uwagi

  • Zweryfikowano w przeglądarce (0 błędów konsoli). Zestaw: 2365 testów (+1).

[1.142.0] — 2026-08-12

Poprawka: koniec z archetypem kariery „Unknown” — #/orientation zawsze klasyfikuje teraz spośród ośmiu nazwanych wektorów kariery, zamiast czasem odpowiadać „Unknown” i doradzać „postawienie na niego”. Poprawka zgłoszona przez użytkownika (bez parent-sync).

Naprawiono

  • #/orientation — prompt AI zabrania teraz archetypu spoza zbioru. Model MUSI uszeregować top 3 spośród dokładnie ośmiu nazwanych wektorów i nigdy nie odpowiadać „Unknown”/„N/A”/„za mało danych” ani wymyślać etykiety. Przy ubogim CV i tak nazywa trzy najbliższe z niższą pewnością i mówi, jakich dowodów brakuje.

Uwagi

  • Tylko zmiana promptu serwera (buildOrientationPrompt); bez zmian i18n/schematu. Zestaw: 2364 testów (+1).

[1.141.0] — 2026-08-12

Wnikliwe statystyki (cd.): wzbogacenie firm z finansowaniem — #/funded jest teraz bardziej wizualne: logotypy firm, wykres wg kwoty finansowania i karty z rundą / kwotą / oceną odkrycia / sugerowanym działaniem. Poprawka UX zgłoszona przez użytkownika (bez parent-sync).

Zmieniono

  • #/funded — płaska tabela → siatka kart. Każda niedawno dofinansowana firma to teraz karta z logo (wyprowadzonym z nazwy przez CompanyLogo, awatar literowy w razie niepowodzenia), chipami rundy + kwoty, oceną odkrycia i sugerowanym działaniem z projektu nadrzędnego oraz linkiem i datą newsa.
  • Wizualizacja kwoty finansowania — poziomy wykres słupkowy największych firm wg ujawnionej kwoty; wolny tekst kwot (“$120M”/“€1.5B”) jest parsowany do wielkości przez nowy parseAmount. 3 nowe klucze i18n × 17 języków.

Uwagi

  • Nadal tylko do odczytu przez GET /api/company-funded; opis i widełki płacowe nie występują w źródle finansowania. Zestaw: 2363 testów (+2).

[1.140.0] — 2026-08-12

Wnikliwe statystyki: bogatsze dane o wynagrodzeniach — rozbicie wynagrodzeń w „Mój pipeline” na #/stats pokazuje teraz średnią (nie tylko medianę), przełącznik rocznie ⇄ miesięcznie i tabelę min · śr · mediana · maks wg kraju. Pierwsza część Fazy 3. Poprawka UX zgłoszona przez użytkownika (bez parent-sync).

Dodano

  • Średnie wynagrodzenie — RoleStats.salaryStats zwraca teraz avgUsd obok minUsd/medianUsd/maxUsd. Mediana jest odporna na wartości odstające, średnia ujawnia skośność — razem czytają się jak rozkład.
  • Przełącznik rocznie ⇄ miesięcznie i tabela min · śr · mediana · maks wg kraju w sekcji wynagrodzeń, sterowane selektorami waluty i okresu. 8 nowych kluczy i18n × 17 języków.

Uwagi

  • Liczby wciąż pochodzą tylko z ofert z czytelnym wynagrodzeniem i są normalizowane do USD (orientacyjne). Zestaw: 2361 testów (+1).

[1.139.0] — 2026-08-12

Zrozumiałość: podpowiedzi ? — wielokrotnego użytku, bezpieczny dla CSP przycisk ?, który po kliknięciu wyjaśnia „co to robi / jak działa / czego oczekiwać” w Twoim języku. Poprawka UX zgłoszona przez użytkownika (bez parent-sync).

Dodano

  • Dymek podpowiedzi ? (window.HelpHint) — okrągły ? obok nagłówka otwiera lekki, zależny od motywu i lustrzany w RTL dymek, który renderuje zlokalizowane wyjaśnienie przez UI.md(); dostępny (role="tooltip", aria-expanded, zamykanie Escape/kliknięciem poza, przywracanie fokusu) i bezpieczny dla CSP.
  • ? na 5 kartach #/stats oraz na 8 tytułach widoków AI/analitycznych (career-plan, orientacja, two-pager, networking, próbna rozmowa, pamięć, funded, tygodniowe podsumowanie) — 14 nowych kluczy i18n × 17 języków.

Uwagi

  • Wszystkie widoki miały już jednoliniowy podtytuł; ? dodaje głębsze wyjaśnienie na żądanie i sprawia, że puste stany same się tłumaczą. Zestaw: 2360 testów (+4).

[1.138.0] — 2026-08-12

Generowanie w języku interfejsu — każda generacja AI odpowiada teraz w języku wybranym w UI, plus wzmocnienia testów z przeglądu. Poprawka UX zgłoszona przez użytkownika (bez parent-sync).

Zmieniono

  • Generacje AI respektują teraz język interfejsu. Gdy interfejs jest po rosyjsku, hiszpańsku, japońsku, … wygenerowany tekst wraca w tym języku zamiast zawsze po angielsku. Dyrektywa języka wyjścia jest przekazywana przez wszystkie endpointy generowania — plan kariery, orientację, raport rynkowy, próbną rozmowę, plan networkingu, „zapytaj dokumentację”, sugestię notatki pamięci i szkic two-pager. Kod i identyfikatory pozostają po angielsku (np. klucze YAML w two-pager); lokalizowane są tylko proza, nagłówki i punkty.

Naprawiono

  • Strażnik ról kolorów CSS (tests/css-role-tokens.test.mjs) — statyczny kanarek sprawdzający, że tokeny-aliasy trybu ciemnego z v1.137.0 nigdy nie odwracają roli: tokeny tekstowe (--fg/--danger/--ok/…) nigdy jako background, a tokeny powierzchni (--card/--panel/--line/…) nigdy jako tekstowy color, w całym CSS i stylach inline SPA.
  • Autosonda ładowarki XSS UI.md() — test ładujący md() z api.js sonduje teraz md('<script>…') tuż po ekstrakcji i rzuca błąd, gdy brak escapowania, więc przyszłe błędne cięcie zawodzi głośno, zamiast zazieleniać zestaw bezpieczeństwa na uciętej funkcji.
  • Strażnik przewijania na #/career-plan — scrollIntoView po generacji uruchamia się tylko, gdy podgląd jest wciąż połączony z dokumentem.

Uwagi

  • docs/UX-ROADMAP.md zaktualizowany: podpowiedzi ? + opisy stron + stany puste przechodzą do v1.139.0; dostawca Nous Research / Hermes — z przewodnikiem wdrożenia na serwerze chmurowym + Telegram i skillem Hermes — jest śledzony jako Faza 5 / 5b.
  • Zestaw: 2356 testów (+5).

[1.137.0] — 2026-08-11

Poprawki czytelności i renderowania — kontrast w trybie ciemnym, etykiety wykresów oraz plan kariery. Przegląd UX zgłoszony przez użytkownika (bez synchronizacji z rodzicem).

Naprawiono

  • Trwałe „białe na białym” / „czarne na czarnym” w trybie ciemnym na wielu ekranach — piętnaście własnych właściwości CSS, do których odwoływało się kilka widoków (--fg, --panel, --panel-2, --ok, --danger, --card, …), nigdy nie zostało zadeklarowanych, więc spadały do zakodowanych na stałe wartości jasnych/czarnych: w porządku w trybie jasnym, nieczytelne w trybie ciemnym (chipy przeglądu na #/pipeline, aktywna karta na #/stats, „Aktywne / Klucze” + „✓ ustawiono” na #/config, sekcje #/two-pager, bąbelek pytania na #/mock-interview, tekst błędów). Teraz są aliasowane do rzeczywistych tokenów świadomych motywu, dzięki czemu automatycznie podążają za motywem — 0 błędów kontrastu WCAG-AA we wszystkich 29 widokach, zweryfikowane przez automatyczny audytor; aktywna karta na #/config przeszła na czytelny, podbarwiony styl. Strażnik regresji (tests/dark-theme-tokens.test.mjs) utrzymuje ich aliasowanie.
  • Etykiety wykresów na #/stats były przycinane w połowie słowa („Senior Backend Engineer” → „…Enginee”) — teraz są skracane wielokropkiem, a pełna etykieta pojawia się jako podpowiedź (tooltip) po najechaniu kursorem.
  • #/career-plan wyświetlał wygenerowany plan jako surowy Markdown — teraz jest automatycznie renderowany jako sformatowany, czytelny tekst (edytowalny Markdown pozostaje w polu tekstowym; przełącznik Podgląd go przełącza).

Uwagi

  • #/career-plan, #/two-pager, #/stats oraz tygodniowe podsumowanie rozmów kwalifikacyjnych nie są uszkodzone — pokazują stany puste, dopóki nie wygenerujesz planu / nie będziesz mieć danych. Jaśniejsze wskazówki na stronie oraz podpowiedzi pomocy ? są planowane jako następny krok (docs/UX-ROADMAP.md).

[1.136.0] — 2026-08-11

Parytet z rodzicem career-ops v1.26.x (po głównej linii v1.26.0) — jedno nowe źródło bez autoryzacji oraz fala poprawek jakości i odporności dla kodu odzwierciedlanego w web-ui. Rejestr liczy teraz 79 źródeł = 74 angielskie + 5 rosyjskich (ALL_ADAPTERS 74).

Dodano

  • eightfold (Eightfold AI, #2684) — tablice rekrutacyjne poprzez bezautoryzacyjne API https://<tenant>.eightfold.ai/api/apply/v2/jobs, przypięte do hosta *.eightfold.ai (markowy CNAME careers.<company>.com jest celowo odrzucany); stronicowane z limitem bezpieczeństwa, zgłasza błąd dla martwej tablicy, deduplikacja adresów URL. Źródło + adapter oraz izolowany dla CI zestaw testów; pojawia się w filtrze Source na #/scan oraz na landingu.

Naprawiono

  • Deduplikacja i klucze ról świadome Unicode (#2569 / #2587 / #2667) — nowa współdzielona normalizeTextKey (NFKC, zachowuje litery/znaki diakrytyczne/cyfry z każdego alfabetu) zastępuje klucze ograniczone do ASCII: detect-reposts teraz grupuje warianty firm różniące się szerokością znaków/interpunkcją (“Acme, Inc.” ≡ “Acme Inc”) i nigdy nie zlewa odrębnych pracodawców spoza alfabetu łacińskiego, a role-matcher składa tytuły o pełnej szerokości i zachowuje tokeny ról spoza alfabetu łacińskiego, zamiast je wymazywać.
  • fetchJsonWithRetry nie ponawia już odrzuconego przekierowania (#2657) — zabezpieczenie redirect:'error' napotykające 3xx jest deterministyczne, więc jest teraz nieponawialne i zawodzi szybko, zamiast zużywać budżet ponowień.
  • Grupy AND w title_filter.positive (#2552) — rozdzielony spacjami + wewnątrz wpisu pozytywnego wymaga teraz, aby każdy termin wystąpił w tytule, w dowolnym porządku.
  • oraclecloud akceptuje numerowane domeny najemcy oraclecloud1.com … oraclecloud99.com (#2683) — ograniczona rodzina (bez wiodącego zera, ≤ 2 cyfry), nigdy dowolna domena wieloznaczna.
  • workable wzmocniony (#2675) — ponowienia, nagłówki przypominające przeglądarkę oraz serializacja żądań wobec hosta osłanianego przez Cloudflare.
  • personio przechodzi na zeskrobywanie HTML, gdy kanał XML jest wyłączony, zamiast zwracać brak wyników.
  • Aliasy FALLBACK dla states ponownie zsynchronizowane z rodzicem (#2615).

Uwagi

  • Nieprzeniesione (nie odzwierciedlone przez web-ui lub tylko CLI): reply-matcher (#2672), jd-similarity (#2661), jd-skill-gap (#2686), parsowanie ścieżki środowiskowej skanowania (#2568) / --flag=value (#2589) oraz zmiany dla listu motywacyjnego / szablonu CV / doctor / ollama / generate-pdf. Zagrożenia HIGH dla webowych js-yaml/nanoid zostały już naprawione w web-ui v1.135.0.

[1.135.0] — 2026-08-11

Parytet z rodzicem career-ops v1.26.0 — pięć nowych źródeł skanowania bez autoryzacji oraz poprawki poprawności dla czterech tablic, które web-ui już obsługuje. Rejestr liczy teraz 78 źródeł = 73 angielskie + 5 rosyjskich (ALL_ADAPTERS 73).

Dodano

  • Pięć nowych źródeł skanowania (każde to źródło + adapter + izolowany dla CI zestaw testów; pojawiają się w filtrze Source na #/scan oraz na landingu cvstart.org):
    • join (JOIN) — tablica JOIN danej firmy z Next.js __NEXT_DATA__ na join.com/companies/<slug> (przypięty do hosta, z limitem stron).
    • getro (Getro) — tablice ofert portfolio VC „sieci talentów” poprzez publiczne API POST api.getro.com, stronicowane od najnowszych; każda oferta jest przypisana do pracodawcy z portfolio, nie do funduszu.
    • consider (Consider) — tablice ofert portfolio VC na getconsider.com poprzez żądanie POST do tego samego źródła; host sterowany konfiguracją jest przypięty przez strukturalne zabezpieczenie SSRF (tylko publiczny host HTTPS).
    • joinup (JOINUP) — szwajcarska tablica ofert joinup.ch, odczytująca renderowaną po stronie serwera najnowszą stronę; zamyka się bezpiecznie (fail-closed) przy awarii scrapera.
    • remotli (Remotli) — remotli.ch, stanowiska zdalne w szwajcarskich firmach (wynagrodzenia w CHF); emituje własny adres aplikacyjny ATS pracodawcy, dzięki czemu duplikaty ogłoszeń między portalami są deduplikowane.

Naprawiono

  • a16z Speedrun nie przerywa już całej tablicy przy przejściowym zakłóceniu — pobieranie stron przechodzi teraz przez współdzielone fetchJsonWithRetry (ograniczone ponowienia tylko przy przejściowych błędach 429/5xx/timeout, nigdy przy trwałym 4xx), a budżet stron został dostosowany do strony liczącej 50 ofert.
  • arbeitsagentur przeniesiono na API Jobsuche v6 (/pc/v6/jobs) — stary punkt końcowy v4 zwraca teraz 404; kształt odpowiedzi zmienił nazwę, a filtrowanie pracy zdalnej zawęża się teraz po stronie serwera.
  • thehub przeniesiono na API v2 jobsandfeatured — wiersze nie mają daty publikacji i są zwolnione z filtra wieku ogłoszenia.
  • hackernews niezawodnie znajduje comiesięczny wątek „Who is hiring?”, filtrując wyszukiwanie Algolia po tagu konta author_whoishiring zamiast po zapytaniu tekstowym.

Uwagi

  • Nieprzeniesione (web-ui jest już bezpieczne, pochłonięte przez przekaźnik lub dotyczy tylko CLI): klucze deduplikacji ofert/dopasowywania firm dla Unicode (grupowanie powtórzeń w web-ui już kluczuje firmę po zwykłych małych literach, więc odrębni pracodawcy spoza alfabetu łacińskiego nigdy się nie zlewają); sygnał opóźnienia odrzuceń follow-up oraz poprawki company-funded (przekazywane tylko do odczytu, fail-soft); ścieżki skanowania nadpisywalne przez zmienne środowiskowe oraz parsowanie --flag=value (web-ui uruchamia skanery w procesie); refaktoryzacja ujednolicająca User-Agent (web-ui już to centralizuje); oraz elementy dotyczące wyłącznie CLI (rejestr niezaufanej treści, oferta/offer-prep, doctor, zmiany szablonu CV/listu motywacyjnego).

[1.134.1] — 2026-08-05

Wzmocnienie walidacji — poprawki wykryte podczas pełnego audytu projektu.

Naprawiono

  • successfactors nie odrzuca już zebranych ofert przy błędzie w połowie skanowania (regresja we wdrożeniu „dead-board-throw” z v1.134.0) — jego pętla paginacji nie miała try/catch, więc błąd na stronie 2 lub kolejnej (po sukcesie strony 1) zgłaszał wyjątek i odrzucał wszystko, co już zebrano; a jeśli tym błędem był 404 (nieprawidłowy zakres startrow), en-scanner kwarantannował aktywnego najemcę jako martwego na wiele dni. Teraz zachowuje się jak phenom/radancy: błąd na stronie 0 wciąż zgłasza wyjątek (martwa tablica), ale błąd na kolejnej stronie zachowuje częściowe wyniki.
  • Chipy filtrów na #/scan są teraz obsługiwane z klawiatury (WCAG 2.1.1) — chipy fasetowe (oraz chip „wyczyść”) były elementami <span> z obsługą kliknięcia, ale bez tabindex/role, więc użytkownicy klawiatury i czytników ekranu nie mogli do nich dotrzeć ani ich przełączać. Teraz mają role="button", tabindex="0", aria-pressed oraz aktywację klawiszami Enter/Spacja.
  • Trzy zakodowane na stałe angielskie ciągi są teraz zlokalizowane — podpowiedź (tooltip) plakietki zaufania na #/scan, nagłówek kolumny relokacji na #/scan oraz nagłówek wyniku (score) na #/dashboard były gołymi literałami, których nie widział mechanizm kontroli parytetu i18n (nigdy nie były kluczami), więc pozostawały w języku angielskim we wszystkich lokalizacjach innych niż angielska. Teraz to scan.trustTip + scan.col.reloc (2 nowe klucze) oraz ponowne użycie track.col.score, wraz ze statyczną strażą źródłową (source-static guard).

[1.134.0] — 2026-08-05

Parytet z rodzicem career-ops v1.25.0.

Dodano

  • Nowe źródło skanowania: getManfred (manfred) — ogólny kanał hiszpańsko-unijnych ofert pracy w branży tech z podanymi wynagrodzeniami, z www.getmanfred.com/api/v2/public/offers (bez autoryzacji, przypięty do hosta + tylko HTTPS, pełny katalog w jednym żądaniu). Źródło + adapter oraz izolowany dla CI zestaw testów (tests/sources-manfred.test.mjs); rejestr liczy teraz 73 źródła = 68 angielskich + 5 rosyjskich (ALL_ADAPTERS 68). Widoczne w filtrze Source na #/scan oraz na landingu cvstart.org.

Naprawiono

  • Kanał a16z Speedrun po cichu obcinał wynik do 50 ofert (#2404) — kanał ogranicza stronę do 50 pozycji, ale źródło żądało PER_PAGE = 100, więc paginacja zatrzymywała się po pierwszej stronie. Poprawiono na 50.
  • Martwe portale teraz zgłaszają błąd zamiast być odczytywane jako „działające, ale puste” (#2379) — cryptocurrencyjobs, phenom, radancy, successfactors: nieudane pobranie, w którym żadne żądanie nigdy się nie rozstrzygnęło, teraz zgłasza błąd (dzięki czemu stan #/portals i skan odnotowują rzeczywistą awarię), zamiast wyciszać go do pustej listy; awaria w połowie skanowania po co najmniej jednym sukcesie zachowuje wyniki częściowe.
  • workable korzysta teraz z publicznego API widżetu (#5ab8425) — przełączono na apply.workable.com/api/v1/widget/accounts/<slug>, który zwraca pełną listę ofert dużego konta w jednym żądaniu, więc duże konta nie są już obcinane.

Uwagi

  • Nieprzeniesione (tylko CLI lub nie odzwierciedlone przez web-ui): przepisanie wydajnościowe grupowania tytułów w detect-reposts #2389; poprawki kluczy firm dla Unicode (własna deduplikacja trackera w web-ui jest już bezpieczna dla znaków innych niż łacińskie); scan --since; cv-facts; przegląd szablonu CV / PDF; doctor; dyrektywa o niezaufanej treści w trybach.

[1.133.1] — 2026-08-02

Naprawiono

  • #/funded (Sfinansowane firmy) teraz renderuje wyniki — dwa błędy sprawiały, że tabela zawsze pokazywała „brak sfinansowanych firm”, nawet gdy skrypt rodzica company-funded.mjs zwracał pełną listę. (1) Widok odczytywał wyniki spod klucza res.candidates, podczas gdy rodzic emituje je pod companies (każdy element ma postać { company, amount, round, funding: { sources: [{ source, url, observed_date }] } }); klient teraz odczytuje właściwy klucz i mapuje rzeczywisty kształt dowodów. (2) Tabela wyników przekazywała swoje komórki do UI.el('tr', {}, …) jako argumenty zmiennej długości (varargs), podczas gdy UI.el(tag, attrs, children) przyjmuje children jako pojedynczy węzeł lub tablicę, więc renderowała się tylko pierwsza kolumna (Firma) — komórki są teraz przekazywane jako tablica. Zweryfikowano w prawdziwej przeglądarce: 11 firm z czterech kanałów renderuje się z kolumnami Firma / Sygnał finansowania / Źródło / Data oraz działającymi linkami do dowodów, zero błędów w konsoli. Pusty wynik ujawnia teraz również diagnostykę per źródło, dzięki czemu spokojny dzień bez wiadomości można odróżnić od zablokowanego kanału.
  • Zabezpieczenia regresji w tests/parity-routes-v1133.test.mjs: fałszywy skrypt rodzica emituje teraz prawdziwy kształt wyjścia companies (oryginalna fixtura odzwierciedlała błędny kształt candidates — co jest dokładnie powodem, dla którego ten błąd trafił do produkcji z zielonymi testami), a także statyczne kanarki źródłowe sprawdzające, że funded.js odczytuje res.companies (nigdy res.candidates) i buduje wiersze tabeli z komórkami jako tablicą (+1 → 2144).

[1.133.0] — 2026-08-01

Dodano

  • Wykrywanie sfinansowanych firm (#/funded, parytet z rodzicem #2117) — nowy widok tylko do odczytu, przekazujący skrypt company-funded.mjs rodzica career-ops przez GET /api/company-funded: lista firm niedawno sfinansowanych, przeznaczona najpierw do przejrzenia (review-first), wykrytych z publicznych, przypiętych do hosta kanałów o finansowaniu (TechCrunch, PR Newswire, The Guardian, Hacker News). Przekaźnik uruchamia skrypt z --json --dry-run (JSON na stdout, bez zapisu plików), nigdy nie przekazuje danych wejściowych użytkownika do --sources, ma ograniczanie liczby żądań i jest wyzwalany przez użytkownika (przycisk Discover, nigdy przy montowaniu). Nowy moduł trasy server/lib/routes/funded.mjs + public/js/views/funded.js, w grupie Pozyskiwanie.
  • Cotygodniowe podsumowanie rozmów kwalifikacyjnych (#/interview-digest, parytet z rodzicem #2129/#2130) — nowy widok tylko do odczytu, przekazujący skrypt rodzica weekly-digest.mjs (bez LLM) przez GET /api/interview/weekly-digest: mechaniczne zestawienie notatek z sesji rozmów kwalifikacyjnych — z jakimi firmami i na jakich rundach rozmawiałeś w tym tygodniu, powtarzające się kompetencje oraz szacunkowe (best-effort) otwarte luki. Opcjonalny zakres ?from=&to= jest przekazywany tylko wtedy, gdy OBIE wartości są poprawnymi datami YYYY-MM-DD; pusty zakres to prawidłowe podsumowanie available:true. Dodano do server/lib/routes/interview.mjs + public/js/views/interview-digest.js, w grupie Analityka.
  • Oba przekaźniki stosują się do ustalonego kontraktu fail-soft available:false, gdy skrypt rodzica jest niedostępny (CI, samodzielne instalacje). 26 nowych kluczy i18n ×17 lokalizacji; izolowany dla CI zestaw testów tests/parity-routes-v1133.test.mjs (+5 → 2143).

Uwagi

  • Rodzic career-ops posunął się dalej niż v1.24.0 dzięki stronie Follow-up Tracker w aplikacji Next.js web/ (#1422) oraz renderowaniu PDF po stronie backendu (#2182) — nieprzeniesione: web-ui ma już własny przekaźnik follow-up oraz uruchamiacze PDF, a leżące u podstaw utwardzenie followup-cadence.mjs trafia tu za darmo przez przekaźnik typu shell-out. Zmiany w set-status.mjs / tracker-utils.mjs są wewnętrzne dla CLI i nie zostały odzwierciedlone.

[1.132.0] — 2026-07-31

Zmieniono

  • Podsystem renderowania wyników #/scan wyodrębniono do public/js/lib/scan-results.js (dług kontraktu rozmiaru pliku — public/js/views/scan.js urósł do ~1254 LOC). Podsystem (renderResults, buildChipRow, getRows, generatory wierszy/fasetek, funkcje renderujące opcje oraz lustrzane odbicie rejestru FALLBACK_SOURCES) przeniesiono do fabryki window.ScanResults.create(ctx), domykającej się nad obiektem kontekstu dostarczanym przez widok. Bez zmiany zachowania — funkcje przeniesiono dosłownie, a zmienne domknięcia mechanicznie przełączono na ctx.*; scan.js ma teraz ~906 LOC (planowany jest drugi etap wyodrębniania w kierunku celu 800 LOC).
  • Testy statyczne źródła czytają oba pliki przez tests/helpers/scan-src.mjs::loadScanSrc(); tests/scan-fallback-sources.test.mjs czyta teraz lustrzane odbicie rejestru z scan-results.js.
  • Nowa bramka regresji w przeglądarce — tests/playwright-scan-filters.mjs zasiewa gotowy plik data/last-scan.json i przechodzi przez każdy filtr #/scan, sprawdzając dokładne liczby wierszy (npm run test:e2e:browser); dodano stabilne identyfikatory kontrolek filtra (#scan-filter-*, #scan-apply).
  • Baner „Najnowsze wydanie” w README uproszczono do jednowierszowego podsumowania z linkiem do pełnego dziennika zmian (długa, wielowersyjna ściana narracji została wycofana). Zastosowano we wszystkich 17 lokalizacjach.

[1.131.2] — 2026-07-31

Zmieniono

  • Podział app.css na trzy uporządkowane arkusze stylów (dług kontraktu rozmiaru pliku — pojedynczy plik urósł do ~1990 LOC, znacznie ponad twardy cel 800 LOC). Teraz jest to app.css (~672 — a11y, tokeny projektowe/motyw, pasek boczny, główna treść, przyciski, powłoka treści), components.css (~595 — karty, siatki, paginator, odznaki, tabele, formularze, log/konsola, markdown, przełącznik języka, filtr chipów, baner połączenia) oraz overlays.css (~737 — toast, szuflada powiadomień, modal, różne/responsywność, lustrzane odbicie [dir="rtl"], docs-fab, usage-hud), każdy w granicach twardego limitu.
    • Podział jest ciągły i zachowuje kolejność, więc kaskada jest identyczna co do bajtu z plikiem sprzed podziału; index.html ładuje trzy pliki jako uporządkowane <link>. Bez zmiany zachowania, znaczników czy i18n.
    • Testy odwołujące się do CSS czytają teraz połączenie plików przez współdzielony pomocnik tests/helpers/css.mjs::loadAppCss(). Nowy plik tests/css-modularization.test.mjs zabezpiecza podział (pliki istnieją · każdy ≤ 800 LOC · kolejność linków w index.html) → zestaw 2138. Zweryfikowano w przeglądarce: wszystkie trzy arkusze stylów parsują się poprawnie, a ich reguły są stosowane.

[1.131.1] — 2026-07-31

Naprawiono

  • Spójność przypinania hosta adaptera dla dwóch źródeł z v1.130.0 (następstwa przeglądu kodu, obrona w głąb; brak zmiany zachowania dla poprawnych danych wejściowych):
    • Adapter a16z-speedrun-talent teraz ponownie waliduje nadpisanie api: / a16z-speedrun-talent: w buildEndpoint (HTTPS + dokładny host speedrun-talent-network.com) i wraca do kanonicznego kanału, gdy walidacja zawiedzie — parytet z adapterem cryptocurrencyjobs, dzięki czemu wartość spoza hosta nigdy nie trafia do gniazda pobierania (wcześniej polegał wyłącznie na strażniku assertSpeedrunUrl w momencie pobierania). Dokładne sprawdzenie hosta to teraz pojedynczy eksportowany SPEEDRUN_TALENT_HOST_RE współdzielony przez strażnika i adapter.
    • Parser cryptocurrencyjobs — cleanUrl używa teraz tego samego dokładnego strażnika hosta co assertCryptocurrencyJobsUrl i nadpisanie adaptera (było endsWith, które akceptowało subdomeny). Parser nigdy nie jest bardziej permisywny niż strażnik SSRF: link do pozycji z sub.cryptocurrencyjobs.co jest odrzucany.
    • +2 testy → zestaw 2135.

[1.131.0] — 2026-07-31

Dodano

  • Tablica CRM z zakładkami etapów na #/tracker (przeniesiona z widoku /pipeline aplikacji webowej rodzica). Pasek chipów lejka + rozwijane menu statusu w trackerze zastępuje pasek zakładek etapów: zakładka Wszystkie plus jedna zakładka na każdy kanoniczny status — Evaluated · Applied · Responded · Interview · Offer · Rejected · Discarded · SKIP · Hired — każda pokazuje na żywo liczbę z całej historii, w tym etapy z zerową liczbą, dzięki czemu cały lejek jest zawsze widoczny (wygląd CRM). Aktywna zakładka steruje filtrem; kliknięcie jej ponownie czyści z powrotem do Wszystkie. Wiersze zachowują ton oceny, legalność, funkcje PDF i raportu, a komórka firmy pokazuje teraz logo marki, jeśli włączono pokazywanie logo firm (domyślnie wyłączone → zero dodatkowych zapytań).
    • Nowa trasa tylko do odczytu GET /api/tracker/stages zwraca kanoniczny lejek (etykiety w kolejności) + mapę składania aliasów, pochodzącą z server/lib/states.mjs (templates/states.yml, z wbudowanym fallbackiem) — dzięki czemu klient nigdy nie zakodowuje na sztywno białej listy statusów. Odpowiedź starszego GET /api/tracker bez parametrów jest niezmieniona (tylko { rows }).
    • Nowa czysta, pokryta testami jednostkowymi biblioteka kliencka public/js/lib/tracker-stages.js grupuje wiersze według etapów zwróconych przez serwer, tolerując przypadkowe pogrubienia markdown i zlokalizowane aliasy (np. aplicado → Applied). Zakładki są dostępne (rola tablist/tab, aria-selected, obszar dotykowy ≥44 px, liczby w dostępnej nazwie każdej zakładki). Bez nowych kluczy i18n. Zestaw testów 2133.

[1.130.0] — 2026-07-31

Dodano

  • Dwa nowe źródła skanowania przeniesione z rodzica career-ops v1.24.0 (w procesie, bez nowych zależności; oba pojawiają się w filtrze Source na #/scan i na landingu cvstart.org):
    • a16z Speedrun (a16z-speedrun-talent, #2231) — kanał JSON całej tablicy talent-network a16z Speedrun. Przypięty do hosta speedrun-talent-network.com, tylko HTTPS, paginacja indeksowana od 0 z limitem stron, przekazywanie q/konfiguracji per firma, fail-soft.
    • Cryptocurrency Jobs (cryptocurrencyjobs) — portal Web3 cryptocurrencyjobs.co, pobierany przez jego publiczny kanał RSS 2.0 (bez autoryzacji). Dwuprzebiegowe dekodowanie encji XML, wyłącznie oferty zdalne, pracodawca odczytywany z końcówki tytułu "… at <Company>".
    • Rejestr liczy teraz 72 źródła = 67 angielskich + 5 rosyjskich (ALL_ADAPTERS = 67 angielskich adapterów portali).

Naprawiono

  • echojobs — role hybrydowe pozostają odróżnialne od zdalnych (odzwierciedla rodzica #2258). Znacznik hybrid (bez rozróżniania wielkości liter) daje teraz "<Miasto> · Hybrydowo" (lub samo Hybrydowo, gdy brak miasta) oraz workplaceType: 'Hybrid', zamiast zostać zwiniętym do Remote.
  • radancy — przestarzały znacznik TalentBrew + transport fragmentu wyników JSON (odzwierciedla rodzica a3e6df9), włączany przez wstrzykiwalny opts.fetchJson.

Uwagi

  • Nie przeniesiono — funkcje rodzica tylko dla CLI. Duża powierzchnia CLI/trybów z career-ops v1.24.0 pozostaje poza web-ui, który jest przeglądarką + cienkim zapisem, a nie hostem trybów: tabele zgodności/jurysdykcji, książka kontaktów + vCard, debrief transkryptu rozmowy kwalifikacyjnej / wykrywanie platformy rozmów, ustawianie statusu w rejestrze, zapis wyniku, dwuprzebiegowa triage, podobieństwo JD, wersjonowany schemat artefaktu CV zgłoszenia, wykrywanie Playwright-MCP przez doctor oraz portals/fix-slugs.mjs. Zmiany orkiestracji skanowania żyjące w rodzicielskim scan.mjs — skaner Interamt.de oparty na Playwright, pełne przeczesanie odwróconego ATS iCIMS, filtr zdalnej kwalifikowalności krajowej, tempo zapytań DNS, deduplikacja rltr StepStone oraz znormalizowana kolumna firmy w historii skanów — nie mają zastosowania: web-ui uruchamia skanery EN/RU w procesie i nie wywołuje scan.mjs.
  • Już pokryte. Poprawka składania akcentów w role-matcher (#2209) została przeniesiona w v1.127.0, więc tutaj jest no-op.

[1.129.1] — 2026-07-29

Naprawiono

  • Następstwa przeglądu AI portów web z v1.128/v1.129 (wszystkie doradcze, naprawione u źródła): precedencja poziomu w job-facets.js (jawny modyfikator wygrywa teraz ze słowem menedżerskim — Senior Engineering Manager → senior, było lead); fallback w states.mjs nie jest już przypięty (udany odczyt jest memoizowany, fallback zwracany bez cache — chwilowo niedostępny rodzic przy starcie jest odczytany ponownie) + console.warn przy obecnym, lecz uszkodzonym pliku; score-tone.js — wiersz bez oceny jest neutralny (muted), nie czerwony; domainFromName() pomija sluggi nie-ASCII przed /api/logo; +strażnik izolacji w tests/states.test.mjs. +4 testy → 2073.

[1.129.0] — 2026-07-29

Dodano

  • Faseta poziomu + kolumna wieku w #/scan — biblioteka job-facets.js z v1.128.0 jest teraz wpięta w UI skanowania (wcześniej tylko logika). Nowa lista Poziom klasyfikuje tytuł każdej oferty na lead/staff/senior/mid/junior/stażysta (JobFacets.seniorityFromTitle) i wypełnia się tym, co faktycznie jest w wynikach (jak faseta Kraj); tytuły bez słowa poziomu zawsze przechodzą. Utrzymywana w zapisanych wyszukiwaniach, Resecie i Zastosuj. Tabela zyskuje kolumnę Poziom (badge) i beztokenową kolumnę Wiek (dziś / Nd, z JobFacets.daysSince). 12 kluczy i18n ×17, +3 testy → 2069.

[1.128.0] — 2026-07-29

Dodano

  • Cztery rozwiązania przeniesione z własnej aplikacji web rodzica (../web/, Next.js), przepisane w czystym JS/ESM, bez nowych zależności: (1) server/lib/states.mjs czyta templates/states.yml na żywo jako kanoniczny słownik statusów trackera (fallback dla CI) — usuwa ręczny re-sync whitelisty co wydanie; POST składa aliasy (hiszpańskie/legacy) do kanonicznej etykiety, funnel w GET grupuje wg statusu kanonicznego; (2) loga firm w wierszach na hoście ATS przez domainFromName() (~90 marka→domena); (3) score-tone.js — 4-poziomowy ton oceny (≥4.2/3.8/3.0 + fallback literowy); (4) job-facets.js — fasety seniority/source/days. +21 testów.

Uwagi

  • Nie przeniesiono (tylko koncept): warstwa akcji agentowych rodzica (actions/registry.ts + api/assistant/route.ts) — plan na wypadek, gdy docs-fab stanie się copilotem. Bez nowych źródeł (rejestr 70), bez zmian i18n/help.

[1.127.0] — 2026-07-29

Dodano

  • Trzy nowe źródła skanowania (parytet career-ops v1.23.0) — rejestr ma teraz 70 adapterów (65 EN + 5 RU): Flowxtra (globalny agregator bez auth), VDAB (API po słowach kluczowych flamandzkiego urzędu pracy) i iCIMS (portale careers-<tenant>.icims.com, odrębnie od jibeapply). Ponadto Cursor wraca do rosteru CLI (parent #2115): cli-detect wykrywa teraz cursor (10 narzędzi), roster przywrócony w help/README/config ×17.

Naprawiono

  • agenticjobs przeszedł ze scrapingu HTML na API REST (#2167); Greenhouse odzyskuje miasto z /offices, gdy location.name to tylko model pracy (#2104); parytet role-matcher (#1933/#2164/#2009: prefiks MTS, bazowy product, składanie akcentów, niezgodność sub-baseline).

Uwagi

  • Nie przeniesiono. Większość v1.23.0 to powierzchnia CLI/dashboard nieużywana przez web-ui (batch-tailor, discover-ats, tryby NL/PT, motywy PDF, dashboard Go, updater/doctor); skrypty przekazujące bez zmian. VERSION rodzica → 1.23.0.

[1.126.1] — 2026-07-25

Naprawiono

  • Dwa miejsca dryfu rosteru CLI, które resync v1.126.0 pominął — (1) intro zakładki API keys w #/config (config.providerModelNote, i18n ×17) wymieniało tylko 7 CLI — teraz Antigravity i Grok Build są wstawione po OpenCode; (2) drugi wiersz tabeli porównawczej w przewodniku pomocy (×17) oraz budowany w CI help strony wciąż zawierały Inside Claude Code / Codex / Cursor / Gemini CLI — przestarzały zestaw z Cursor — teraz pełny roster. Oba używały separatorów ukośnik/kropka środkowa, których wzorce zamiatania v1.126.0 nie obejmowały. Snapshot i18n zregenerowany; zestaw pozostaje 1969.

[1.126.0] — 2026-07-25

Dodano

  • Zakładka narzędzi AI CLI wykrywa teraz wszystkie 8 pierwszoklasowych CLI career-ops — roster #/config zsynchronizowano z rodzicielskim docs/SUPPORTED_CLIS.md: server/lib/routes/cli-detect.mjs zyskuje Grok Build CLI (grok) i Kimi CLI (kimi), a Antigravity sonduje teraz najpierw swój kanoniczny binarny agy. Skan PATH tylko-do-odczytu raportuje teraz 9 narzędzi; nadal nigdy nie uruchamia znalezionego binarnego.

Zmieniono

  • Resynchronizacja dokumentacji z career-ops.org/docs — każdą powierzchnię dokumentacji uzgodniono z żywymi stronami rodzica (przeczytano wszystkie 31). Kanoniczny roster asystentów AI (help ×17 + README ×17) wymienia teraz 8 pierwszoklasowych CLI — Claude Code, Codex, OpenCode, Antigravity CLI, Grok Build CLI, Qwen Code, Kimi, GitHub Copilot CLI — plus Gemini CLI (starszy wrapper). Pakiety pomocy zachowują strukturę 29 H2 / 105 H3.

[1.125.4] — 2026-07-23

Zmieniono

  • zależności 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 w site/; build Astro zielony, bez wpływu na SPA/serwer.

Uwagi

  • Przegląd parzystości z projektem nadrzędnym (career-ops 37d17ec..254764a, po v1.22.0) — nic do portowania: guard błędnego wiersza w set-status (#2108) dotyczy tylko CLI (w web-ui wiersze trackera wybiera się jawnie w UI i żadna trasa nie wywołuje set-status.mjs), Risk Summary zlokalizowanych trybów (#2109) dotyczy plików modes/<lang>/, których web-ui nigdy nie czyta (tylko modes/*.md najwyższego poziomu), weryfikacja manifestu update-system (#2111) dotyczy tylko aktualizatora, a reszta to dokumentacja rodzica (turecki README, SIGNATURES ×4, SCRIPTS.md, akcenty es). VERSION rodzica pozostaje 1.22.0 — parentVersion bez zmian.

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