Resume Matcher 1.3 — Crescendolls
Crescendolls brings resume creation, tailoring, application tracking, and interview preparation into one workflow. It also strengthens the steps you depend on most: uploading a resume, saving your work, applying AI suggestions, and exporting a PDF.
Named after Crescendolls from Daft Punk’s Discovery, this release continues the v1 series after 1.2 Nightvision.
What’s new
Build a resume from the beginning
The guided resume wizard helps you turn your experience into a resume through an adaptive conversation. Save a draft, return to it later, and continue refining the result in the builder.
Follow the application through
The application tracker gives you a board for organizing jobs, recording notes, and keeping applications connected to tailored resumes. Interview preparation helps you prepare for the next step using your resume and the job description.
More control over your resume and AI
- Three new templates: LaTeX, Clean, and Vivid.
- More language support: French and Korean interfaces and improved Chinese, Japanese, and Korean PDF rendering.
- More AI options: Groq, Azure AI Foundry, and OpenAI-compatible servers, reasoning controls, and custom prompts for cover letters and outreach messages.
- Clearer tailoring feedback: expanded score breakdowns and improved job-description skill alignment across more resume sections.
More dependable, from upload to export
This release includes a reviewed reliability update spanning 17 pull requests and 44 tracked issues.
- Recover interrupted uploads. Retain the identity of a saved resume when its response is interrupted, and handle empty or invalid documents more clearly.
- Keep useful work. Improve draft recovery, save behavior, preview confirmation, and handling of partial AI results.
- Handle failures consistently. Bound AI operation times and retries, improve malformed-response handling, and provide clearer error messages.
- Preserve resume content. Strengthen checks around original information and recognize Latin skill names beside Chinese, Japanese, and Korean text.
- Improve PDF reliability. Handle concurrent exports, cancellation, and browser shutdown while retaining ownership of resources still in use.
The reliability stack preserves 124 individual commits. Its review evidence and file map are included in the repository.
Security update
This release includes the security bump merged in PR #993: NanoID 3.3.16 → 3.3.18.
The update addresses CVE-2026-67213, where a custom ID generator could loop indefinitely when asked for a zero-length ID.
Upgrading from 1.2
Stop the application and back up the complete persistent data directory before upgrading. This release moves storage to SQLite and stores provider API keys encrypted at rest. On startup, it imports a legacy TinyDB database when SQLite is empty and migrates legacy saved keys.
Keep the database, config.json, uploaded files, and the hidden .secret_key together. Existing encrypted keys need their original secret to be decrypted. Retain your pre-upgrade backup if you need to return to 1.2; the migrated SQLite database cannot replace the old version’s database.
For source installs, use Node.js 22+ and Python 3.13+, then reinstall dependencies following the README. For Docker upgrades, preserve your existing data volume when recreating the container.
Docker images
Release tag: v1.3.0. Versioned images are available for Linux amd64 and arm64 on GHCR and Docker Hub:
docker pull ghcr.io/srbhr/resume-matcher:1.3.0
# or
docker pull srbhr/resume-matcher:1.3.0
The image tags are 1.3.0 and 1.3. Release-tag publication succeeded, and both tags were verified publicly on both registries.
Verification
The release preparation passed 1,067 backend tests and 500 frontend tests, plus lint, type checking, and a production build. The suite includes real Chromium controls. Two optional paid-provider evaluations were excluded.
Thank you
Thank you to everyone who contributed code, reported bugs, tested fixes, and reviewed this release. The complete contribution history and first-time contributors are listed below.
Contributors to this release: @AbdullahFageeh, @chadidi, @Dessalines39394, @Frankli9986, @gingeekrishna, @godson-plt, @GwIhViEte, @icemc, @lbagnascom, @LongD1stanceRunner, @luochen211, @moduvoice, @mohdazmi03, @MRDGH2821, @NightingaleCen, @RedMoonnn, @sahayagodson, @spsilu, @srbhr, @thmsmtylr, @wwlwgo.
Automation contributions are credited to @dependabot and @oz-agent.
All changes and first-time contributors
What's Changed
- chore(deps): bump litellm from 1.81.8 to 1.83.0 in /apps/backend by @dependabot[bot] in #735
- chore(deps): bump vite from 7.3.1 to 7.3.2 in /apps/frontend by @dependabot[bot] in #738
- chore: extract portable docs and remove unused AI tooling by @srbhr in #741
- chore(deps-dev): bump brace-expansion transitive deps by @srbhr in #744
- frontend ui audit follow-up: perf, a11y, tokens, copy, polish by @srbhr in #742
- fix(docker): make frontend accessible for PDF generation by @chadidi in #724
- chore(deps): bump next from 16.1.7 to 16.2.3 in /apps/frontend by @dependabot[bot] in #748
- chore(deps): bump python-multipart from 0.0.22 to 0.0.26 in /apps/backend by @dependabot[bot] in #752
- chore(deps): bump dompurify from 3.3.3 to 3.4.0 in /apps/frontend by @dependabot[bot] in #753
- Bun compatibility + PyProject script by @MRDGH2821 in #755
- Bun compat +
uv run app script + LiteLLM reasoning hardening (#747, #751 partial) by @srbhr in #756
- Dev fixes: Settings error overflow, openai_compatible provider, custom feature prompts (#754, #751, #749) by @srbhr in #757
- fix(frontend): remove invalid turbopackUseSystemTlsCerts flag to unblock Docker Publish by @srbhr in #758
- fix(llm): conditionally pass temperature based on model capability by @Frankli9986 in #773
- test(backend): cover config settings flows by @AbdullahFageeh in #771
- fix(parser): prevent JSON truncation by clamping tokens to model limit by @mohdazmi03 in #770
- chore(deps): bump litellm from 1.83.0 to 1.83.7 in /apps/backend by @dependabot[bot] in #764
- chore(deps): bump python-dotenv from 1.2.1 to 1.2.2 in /apps/backend by @dependabot[bot] in #761
- fix(llm): resolve DeepSeek 500 / Failed to analyze resume by @Frankli9986 in #775
- fix(deps): pin python-dotenv to 1.0.1 to satisfy litellm (#779) by @NightingaleCen in #780
- Remove repeated def for _appears_truncated by @lbagnascom in #787
- [codex] Add verifier-led resume tailoring loop by @srbhr in #789
- fix(frontend): show timeout-specific error instead of misleading API key message by @Frankli9986 in #795
- feat: Add Groq LLM provider support by @Frankli9986 in #774
- fix(upload): reject resumes with empty extracted text by @Frankli9986 in #794
- chore(deps): bump next from 16.2.3 to 16.2.6 in /apps/frontend by @dependabot[bot] in #802
- chore(deps): bump litellm from 1.83.7 to 1.83.10 in /apps/backend by @dependabot[bot] in #801
- fix(deps): patch 5 security advisories (python-multipart, python-dotenv, postcss, brace-expansion) by @srbhr in #816
- fix(i18n): add missing tailor.errors.timeout translation (es, ja, pt-BR) — fixes Docker build by @srbhr in #817
- docs(claude): add app-level CLAUDE.md context files (backend + frontend) by @srbhr in #818
- docs(i18n): document Portuguese (pt) locale in i18n.md by @srbhr in #819
- test: testing initiative — backend (pytest+evals) & frontend (vitest) coverage, local pre-push gate, context docs by @srbhr in #820
- fix(resumes): improve/confirm rejects valid tailorings for non-schema-complete resumes (preview/confirm hash mismatch) by @srbhr in #824
- feat(e2e-monitor): agentic end-to-end monitor — drive the real app, judge output/render/provider vs a golden baseline (report, never a gate) by @srbhr in #823
- fix(improver): reorder skill changes silently dropped — accept list 'original' by @srbhr in #825
- feat(e2e-monitor): narrate the full loop + AI-agent handoff in the CLI by @srbhr in #826
- fix(tailor): expand diff scope + preserve casing (#805); e2e-monitor JD-keyword tolerance by @srbhr in #827
- fix(config): clearing Base URL persists null, not a stale value (#760) by @srbhr in #829
- fix(pdf): deterministic render wait + generic error; contain error modal (#799 #808 #811) by @srbhr in #828
- fix(improver): salvage skill reorder instead of dropping it wholesale (#736) by @srbhr in #830
- feat(prompts): JD-keyword incorporation as the default across all sections (truthful reframing) by @srbhr in #831
- fix(builder): preserve Enter newlines in Additional Info textareas (#763) by @srbhr in #834
- feat(timeout): configurable improve/request timeout across all 3 layers (#776) by @srbhr in #833
- fix(deps): bump vitest 4.0.18 → 4.1.8 (CVE-2026-47429, Dependabot #224) by @srbhr in #835
- fix(editor): stop duplicate tiptap link/underline extension warnings by @srbhr in #837
- test(backend): green the suite + cover the untested I/O surface by @srbhr in #839
- feat(templates): add LaTeX, Clean, and Vivid résumé templates by @srbhr in #840
- feat: SQLite data layer, encrypted multi-provider API keys & Kanban application tracker by @srbhr in #841
- chore(deps): bump cryptography from 46.0.3 to 46.0.7 in /apps/backend by @dependabot[bot] in #842
- fix(status): graceful degradation for the /status endpoint by @srbhr in #843
- docs: sync agent context for SQLite, encrypted keys & application tracker by @srbhr in #844
- feat: AI-led guided resume wizard (redesign) by @srbhr in #846
- chore(deps): batch security bumps (7 Dependabot PRs + cryptography HIGH) → main by @srbhr in #867
- fix(llm): graceful fallback when provider rejects response_format json_object (#857) by @srbhr in #868
- fix(resumes): make "Delete & Start Over" work when a resume fails processing by @srbhr in #871
- docs(readme): optimize sponsor conversion (top CTA, merged section, link fix) by @srbhr in #872
- feat(i18n): add French (fr) language support for UI and AI content ge… by @icemc in #869
- feat: add ATS score breakdown to resume improvement response by @gingeekrishna in #813
- feat: add interview prep workflow by @GwIhViEte in #873
- fix(i18n): add missing interviewPrep keys to fr.json (unblocks Docker publish) by @srbhr in #895
- chore(deps): consolidate frontend dependency updates (supersedes #888, #889, #893, #894) by @srbhr in #896
- chore(deps): land consolidated dependency updates on main (re-target of #896) by @srbhr in #897
- fix: contain long dialog descriptions by @luochen211 in #885
- Stabilize DnD context ids to avoid hydration mismatch by @RedMoonnn in #881
- fix(docker): add CJK fonts for Chinese/Japanese/Korean PDF rendering (#777) by @Frankli9986 in #785
- fix(builder): persist Compact Mode and Contact Icons toggles across sessions by @gingeekrishna in #874
- feat(i18n): add Korean (ko) language support by @moduvoice in #876
- Batch 2: Azure AI Foundry provider (#892) + plain description points (#882) by @srbhr in #898
- Release: Korean support, Azure AI Foundry, plain description points, CJK PDF fonts by @srbhr in #899
- Batch 3: resume autosave & draft recovery (#883) + CJK font fallback (#884) by @srbhr in #900
- Batch 4: reject empty resume uploads (#793) + tailor timeout feedback (#792) by @srbhr in #901
- Code review remediation: 4 blockers, 9 high, 8 medium, 6 test gaps by @srbhr in #902
- Harden normalization and draft comparison (#903 review findings) by @srbhr in #906
- Fix cubic findings on #907 (1 P0, 6 P1) by @srbhr in #908
- Release: autosave, CJK fonts, tailor feedback + full code-review remediation by @srbhr in #907
- fix: restore broken star history chart in READMEs by @Dessalines39394 in #919
- fix: preserve structured resume output for compatible LLMs by @wwlwgo in #924
- fix: preserve structured resume output for compatible LLMs (#924) + review follow-ups by @srbhr in #927
- feat: add tracker status visibility management by @LongD1stanceRunner in #920
- feat: tracker column visibility management (#920) + review follow-ups by @srbhr in #928
- fix(llm): skip temperature for OpenAI GPT-5 family by @thmsmtylr in #929
- [17/17] Complete cross-flow recovery and verified reliability fixes by @srbhr in #992
- [5/17] Protect attachment edits and surface operation failures by @srbhr in #980
- [07/17] Reject stale dashboard requests and serialize processing polls by @srbhr in #982
- [10/17] Make preview confirmation atomic and idempotent by @srbhr in #985
- [11/17] Validate LLM outputs and bound retry attempts by @srbhr in #986
- [12/17] Preserve source content through AI refinement by @srbhr in #987
- [13/17] Keep wizard entry identity stable during corrections by @srbhr in #988
- [14/17] Bound complete AI operations and input sizes by @srbhr in #989
- [16/17] Bound PDF rendering and recover Chromium safely by @srbhr in #991
- [Stack 01/17] Isolate configuration storage and atomically save settings by @srbhr in #976
- [Stack 02/17] Preserve supported GPT-5 sampling parameters by @srbhr in #977
- [Stack 03/17] Make uploads cancellable and bound HTTP response bodies by @srbhr in #978
- [Stack 04/17] Isolate resume editor state and guard draft recovery by @srbhr in #979
- [06/17] Validate wizard drafts and report storage failures accurately by @srbhr in #981
- [08/17] Bound document ingestion and enforce processing ownership by @srbhr in #983
- [09/17] Make master, job and tracker writes atomic by @srbhr in #984
- [15/17] Repair isolated monitoring and generated-result evaluations by @srbhr in #990
- build(deps): bump nanoid from 3.3.16 to 3.3.18 in /apps/frontend by @dependabot[bot] in #993
- Release 1.3 Crescendolls by @srbhr in #994
New Contributors
Full Changelog: 1.2.0...v1.3.0