career-ops: v1.10.0
career-ops v1.10.0 — the community week
This release is different from any before it.
In the span of a few days, this project merged work from more than 20 different contributors — including a dozen first-timers. Career-ops now speaks its first right-to-left language, interviews you instead of asking you to write config files, writes your cover letters, runs inside Docker on locked-down machines, and recovers gracefully when your AI session hits its limits mid-batch. Almost none of it was written by me. That's the whole point of this project.
✨ Highlights
New capabilities
- 🇸🇦 Full Arabic support — career-ops's first RTL language, with real right-to-left engineering in the PDF template (mirrored layout, Arabic-capable font stack), not just translated strings (#764)
- 🎤 Interactive interview onboarding —
career-ops interviewbuilds your profile and CV by asking you questions, instead of requiring you to writecv.mdfirst (#909) - ✉️ Cover letter mode — the most-requested missing piece, rendered through the existing PDF pipeline with zero new dependencies (#807)
- 🐳 Docker support — run the full pipeline (Playwright included) on hosts where native installs are blocked (#625)
- 💰 Salary filtering in the zero-token scanner — conservative by design: jobs without salary data always pass (#677)
- 🔭 Reverse ATS discovery —
scan:fullsweeps public ATS APIs (Greenhouse, Lever, Ashby, and now Workday) to find matching roles across companies you haven't configured (#746) - 🛡️ Apply preflight gate — before drafting any application answer, career-ops verifies the posting is still live and matches your report. On any mismatch it asks you — it never guesses (#887)
- ⏸️ Batch pause on session limits — hitting your AI plan's limit now pauses the batch (keeping retry budgets) instead of burning every remaining offer to
failed. Resume with--resume-paused(#874) - Plus: SolidJobs provider + generic
job_boardsconfig (#853), scan-history TTL (#895),--rediscover-404for moved postings (#808), LaTeX CV renderer (#905), configurable follow-up cadence (#889), portals.yml validator (#886),doctor --jsonas the single onboarding source of truth (#888)
Important fixes
- 🔐 Security: SSRF guard hardening in the liveness checker — bracketed IPv6 literals, mapped IPv4,
0.0.0.0and trailing-dot hostnames could bypass the private-host guard (#917) - 🩹 v1.8.x upgrades repaired — updating from 1.8.x no longer leaves the install broken (
tracker-links.mjsmissing). If you're on 1.8.x: this release fixes the path forward — see the note below (#921) - 🧯 Batch workers no longer deadlock fighting over a shared browser in parallel runs (#809), and min-score skips no longer fall through to "completed" (#873)
- 📒 Two tracker data-loss fixes: number collisions can no longer overwrite an unrelated company's row (#867, #793)
- 🧾 PDF generation now validates section order against your
cv.md, not a hardcoded convention (#817) - Liveness checking no longer false-expires postings hiding behind anti-bot walls (#783)
i18n — 🇫🇷 French README (#906) · 🇵🇱 Polish README (#837) · 🇸🇦 Arabic README + modes (#764) · last root-level modes translated to English (#903)
⬆️ Upgrading from 1.8.x
The 1.8.x updater has a known gap (#920): run node update-system.mjs apply twice (the first run updates the updater itself), or check the issue for a one-line manual fix. From 1.9.0 onward this class of bug is covered by an automated migration test (#833 — thanks @ncoprod).
📈 And the project itself?
Growing faster than we can triage it, honestly:
live star telemetry by warpchart.dev
To everyone who opened an issue before a PR, rebased twice without complaining, or translated a README into their language: thank you. Every one of those stars is someone's job search getting a little less lonely.
— Santiago
📋 Full changelog
1.10.0 (2026-06-11)
Features
- apply: add preflight liveness and role-match gate (#887) (42bb9ab)
- batch: pause batch runner on Claude session limits (#874) (ae6beec)
- cover: add cover letter generation mode (#807) (493f822)
- cv: add build-cv-latex.mjs structured JSON to LaTeX renderer (#905) (b4af01f)
- dashboard: keep discard reason visible in pipeline preview (#914) (3200dfe)
- dashboard: sortable Location, Pay, and Last-contact columns in pipeline view (#798) (265a95b)
- dockerize project for hosts blocked from native Playwright install (#625) (66404a8)
- doctor: adopt doctor --json as the single onboarding state source (#888) (35e2124)
- followup: read cadence settings from profile.yml (#889) (8050c37)
- i18n: add full Arabic language support and modes (#764) (333bb81)
- modes: add interactive interview onboarding subcommand (#909) (46a5c59)
- scan: add --rediscover-404 fallback for moved tracked postings (#808) (7096dbc)
- scan: add configurable salary filtering to the zero-token scanner (#677) (a6ea02e)
- scan: add portals.yml schema validator (#886) (3340695)
- scan: add scan-ats-full.mjs — reverse-discover jobs from public ATS APIs (#746) (7801dc7)
- scan: add scan-history TTL and recheck policy (#895) (1db4cf2)
- scan: add SolidJobs provider and job_boards support (#853) (79862a9)
Bug Fixes
- apply: preserve form field contracts (#821) (2b38fd0)
- batch: append profile context to worker prompts (#815) (4989afc)
- batch: isolate workers from inherited MCP to prevent parallel deadlock (#809) (c8c0dbd)
- batch: stop after min-score skip instead of falling through to completed (#873) (888ca31)
- dashboard: resolve tracker-relative report links against the tracker directory (#780) (858fc93), closes #779
- doctor: single source of truth for onboarding state via doctor --json (#765) (eb536c4)
- flake: declare systems so the devShell resolves on macOS (#848) (e5f0903), closes #334
- liveness: stop false-expiring postings behind anti-bot walls (#783) (a667c33)
- merge-tracker: require company match on exact entry-number dedup (#867) (10ad2de)
- merge-tracker: use token-union ratio in roleFuzzyMatch to stop cross-role dedup (#793) (cfa7505), closes #751
- patterns: parse header-style and Detected-archetype formats in analyze-patterns (#723) (abf603c)
- pdf: reject CV section ordering that diverges from cv.md source (#817) (9f6acc2)
- pipeline: atomic report-number reservation for parallel workers (#803) (c42368c)
- release: auto-sync VERSION via release-please generic extra-file (214f5f8)
- release: sync VERSION file to 1.9.0 (461e3d9)
- security: close SSRF guard bypasses in liveness-browser (#917) (1f525c4)
- update: bootstrap tracker-links.mjs and scaffolder/ for v1.8.x to v1.9.0 upgrades (#921) (1d3a18b)
- update: run curl version checks concurrently in check() (#896) (8f0ed38)
- update: use curl in check() so updates work inside the Claude Code sandbox (#802) (8cac7f3), closes #754